-
-
Save gracenotes/e24622189c5ccadd2e38d764a256dbb6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Created by thefifthmatt. All rights reserved. | |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using SoulsIds; | |
using SoulsFormats; | |
namespace BlizzardMod | |
{ | |
// This uses DSMapStudio SoulsFormats, available standalone at | |
// https://github.com/thefifthmatt/SoulsFormats/tree/dsms | |
// SoulsIds is not all published yet, but is basic file-loading stuff. | |
public class BlizzardMod | |
{ | |
public static void Run(bool hidemap) | |
{ | |
GameEditor game = new GameEditor(GameSpec.FromGame.ER); | |
DCX.Type overrideDcx = DCX.Type.DCX_DFLT_11000_44_9; | |
string outPath = "blizzard"; | |
string paramPath = $@"{game.Spec.GameDir}\{game.Spec.ParamFile}"; | |
Dictionary<string, PARAM> param = game.LoadParams(paramPath, game.LoadDefs()); | |
int baseId = 81; | |
PARAM.Row baseRow = param["WeatherParam"][baseId]; | |
foreach (PARAM.Row row in param["WeatherParam"].Rows) | |
{ | |
if (row.ID != baseId) | |
{ | |
GameEditor.CopyRow(baseRow, row); | |
} | |
} | |
foreach (PARAM.Row row in param["CutsceneWeatherOverrideGparamConvertParam"].Rows) | |
{ | |
row["weatherOverrideGparamId"].Value = baseId; | |
} | |
foreach (PARAM.Row row in param["CutsceneGparamWeatherParam"].Rows) | |
{ | |
row["IndoorOutdoorType"].Value = (byte)0; | |
foreach (PARAM.Cell cell in row.Cells) | |
{ | |
if (cell.Def.InternalName.StartsWith("Dst") && (short)cell.Value > 0) | |
{ | |
cell.Value = 0; | |
} | |
} | |
} | |
if (hidemap) | |
{ | |
param["WorldMapPieceParam"].Rows.Clear(); | |
PARAM mapPoint = param["WorldMapPointParam"]; | |
mapPoint.Rows.RemoveAll(r => r.ID != 85495300 && r.ID != 111000); | |
void addOpenPoint(int id, int x, int z) | |
{ | |
PARAM.Row row = GameEditor.AddRow(mapPoint, id, 111000); | |
row["areaNo"].Value = (byte)60; | |
row["gridXNo"].Value = (byte)x; | |
row["gridZNo"].Value = (byte)z; | |
row["posX"].Value = row["posY"].Value = row["posZ"].Value = 0f; | |
} | |
addOpenPoint(111008, 30, 30); | |
addOpenPoint(111009, 64, 64); | |
} | |
game.OverrideBndRel(paramPath, $@"{outPath}\{game.Spec.ParamFile}", param, f => f.AppliedParamdef == null ? null : f.Write(), dcx: overrideDcx); | |
foreach (string path in Directory.GetFiles($@"{game.Spec.GameDir}\event", "*.emevd.dcx")) | |
{ | |
string map = GameEditor.BaseName(path); | |
EMEVD emevd = EMEVD.Read(path); | |
bool write = false; | |
if (map == "common" && hidemap) | |
{ | |
EMEVD.Event newEvent = new EMEVD.Event(99559955); | |
newEvent.Instructions.AddRange(new[] | |
{ | |
new EMEVD.Instruction(2003, 76, new List<object> { (byte)0, (byte)1, (byte)60, (byte)42, (byte)36, (byte)0, 0f, 0f, 0f }), | |
new EMEVD.Instruction(3, 0, new List<object> { (sbyte)0, (byte)1, (byte)0, 18000020 }), | |
new EMEVD.Instruction(2003, 78, new List<object> { 111008, 0f }), | |
new EMEVD.Instruction(2003, 78, new List<object> { 111009, 0f }), | |
}); | |
emevd.Events.Add(newEvent); | |
EMEVD.Instruction init = new EMEVD.Instruction(2000, 0, new List<object> { 0, 99559955, 0 }); | |
emevd.Events.Find(e => e.ID == 0).Instructions.Insert(0, init); | |
write = true; | |
} | |
foreach (EMEVD.Event ev in emevd.Events) | |
{ | |
for (int j = 0; j < ev.Instructions.Count; j++) | |
{ | |
EMEVD.Instruction ins = ev.Instructions[j]; | |
if (ins.Bank == 2012 && ins.ID == 11) | |
{ | |
ev.Instructions[j] = new EMEVD.Instruction(1014, 18); | |
write = true; | |
} | |
} | |
} | |
string emevdPath = $@"{outPath}\event\{Path.GetFileName(path)}"; | |
if (write) | |
{ | |
emevd.Write(emevdPath, overrideDcx); | |
} | |
else if (File.Exists(emevdPath)) | |
{ | |
File.Delete(emevdPath); | |
} | |
} | |
foreach (string path in Directory.GetFiles($@"{game.Spec.GameDir}\{game.Spec.MsbDir}", "*.msb.dcx")) | |
{ | |
string map = GameEditor.BaseName(path); | |
MSBE msb = MSBE.Read(path); | |
bool write = false; | |
if (msb.Regions.EnvironmentMapEffectBoxes.Count > 0) | |
{ | |
HashSet<string> names = new HashSet<string>(msb.Regions.EnvironmentMapEffectBoxes.Select(r => r.Name)); | |
msb.Regions.EnvironmentMapEffectBoxes.Clear(); | |
foreach (MSBE.Region r in msb.Regions.GetEntries()) | |
{ | |
if (r.Shape is MSB.Shape.Composite comp && comp.Children.Any(c => names.Contains(c.RegionName))) | |
{ | |
foreach (MSB.Shape.Composite.Child c in comp.Children) | |
{ | |
if (names.Contains(c.RegionName)) | |
{ | |
c.RegionName = null; | |
} | |
} | |
} | |
} | |
write = true; | |
} | |
foreach (MSBE.Part.Collision col in msb.Parts.Collisions) | |
{ | |
if (col.UnkT34 != 1) | |
{ | |
col.UnkT34 = 1; | |
write = true; | |
} | |
MSBE.Part.SceneGparamConfig conf = col.SceneGparam; | |
if (conf != null) | |
{ | |
conf.TransitionTime = -1; | |
conf.Unk18 = conf.Unk19 = conf.Unk1A = conf.Unk1B = conf.Unk1C = conf.Unk1D = conf.Unk20 = conf.Unk21 = -1; | |
write = true; | |
} | |
} | |
foreach (MSBE.Part.Asset asset in msb.Parts.Assets) | |
{ | |
if (asset.AssetUnk3.Unk0A != 0) | |
{ | |
asset.AssetUnk3.Unk0A = 0; | |
write = true; | |
} | |
} | |
string msbPath = $@"{outPath}\{game.Spec.MsbDir}\{Path.GetFileName(path)}"; | |
if (write) | |
{ | |
msb.Write(msbPath, overrideDcx); | |
} | |
else if (File.Exists(msbPath)) | |
{ | |
File.Delete(msbPath); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment