public void LoadMSB3(String filename) { msb3 = SoulsFile <MSB3> .Read(filename); enemies = msb3.Parts.Enemies; PopulateTable(); }
protected override void Execute(string filePath, string fileName) { MSB3 msb3 = MSB3.Read(filePath); Randomizer.Randomize(msb3.Parts.Enemies); Randomizer.Clear(); msb3.Write(filePath); }
public void FogConfig() { AnnotationData ret = new AnnotationData(); ret.SetGame(FromGame.DS3); GameEditor editor = new GameEditor(FromGame.DS3); Dictionary <string, MSB3> maps = editor.Load(@"map\MapStudio", path => ret.Specs.ContainsKey(GameEditor.BaseName(path)) ? MSB3.Read(path) : null, "*.msb.dcx"); ret.Entrances = new List <Entrance>(); foreach (KeyValuePair <string, MSB3> entry in maps) { if (!ret.Specs.TryGetValue(entry.Key, out MapSpec spec)) { continue; } // Console.WriteLine(spec.Name); MSB3 msb = entry.Value; Dictionary <string, MSB3.Part.Object> objs = new Dictionary <string, MSB3.Part.Object>(); foreach (MSB3.Part.Object e in msb.Parts.Objects) { objs[e.Name] = e; int model = int.Parse(e.ModelName.Substring(1)); if (model >= spec.Start && model <= spec.End) { ret.Entrances.Add(new Entrance { Area = spec.Name, Name = e.Name, ID = e.EventEntityID, Text = "Between", Tags = "pvp boss", ASide = new Side { Area = spec.Name }, BSide = new Side { Area = spec.Name }, }); } } } ISerializer serializer = new SerializerBuilder().DisableAliases().Build(); using (TextWriter writer = File.CreateText("fog.txt")) { serializer.Serialize(writer, ret); } }
static void Main(string[] args) { var msb = MSB3.Read(args[0]); var chr = new MSB3.Part.Enemy(); chr.Name = "c1280_0000"; chr.ModelName = "c0000"; chr.MapStudioLayer = 0xFFFFFFFF; chr.ThinkParamID = 128010; chr.NPCParamID = 128010; chr.CharaInitID = -1; chr.BackupEventAnimID = -1; chr.EntityID = -1; chr.LodParamID = -1; chr.UnkE0E = -1; msb.Parts.Enemies.Add(chr); msb.Write(args[0]); }
protected override void Execute(Game game, string msbName) { Randomizer.Clear(); string filePath = GamePath.GetMapStudioPath() + msbName; switch (game) { case Game.DS3: MSB3 msb3 = MSB3.Read(filePath); EnemyWrapper.Overwrite(Randomizer.Randomize(EnemyWrapper.Read(msb3.Parts.Enemies).ToList()), msb3.Parts.Enemies); msb3.Write(filePath); break; case Game.Sekiro: MSBS msbs = MSBS.Read(filePath); EnemyWrapper.Overwrite(Randomizer.Randomize(EnemyWrapper.Read(msbs.Parts.Enemies).ToList()), msbs.Parts.Enemies); msbs.Write(filePath); break; } }
private void LoadMapData() { if (Sekiro) { Smaps = Editor.Load("Base", path => MSBS.Read(path), "*.msb.dcx"); MaybeOverrideFromModDir(Smaps, name => $@"map\MapStudio\{name}.msb.dcx", path => MSBS.Read(path)); List <string> missing = Locations.Keys.Except(Smaps.Keys).ToList(); if (missing.Count != 0) { throw new Exception($@"Missing msbs in dists\Base: {string.Join(", ", missing)}"); } } else { Maps = Editor.Load("Base", path => MSB3.Read(path), "*.msb.dcx"); MaybeOverrideFromModDir(Maps, name => $@"map\MapStudio\{name}.msb.dcx", path => MSB3.Read(path)); List <string> missing = Locations.Keys.Except(Maps.Keys).ToList(); if (missing.Count != 0) { throw new Exception($@"Missing msbs in dist\Base: {string.Join(", ", missing)}"); } } }
public bool ScrapeMaps(Universe u) { if (spec.MsbDir == null) { return(false); } if (spec.Game == FromGame.SDT) { Dictionary <string, MSBS> maps = editor.Load(spec.MsbDir, path => MSBS.Read(path)); foreach (KeyValuePair <string, MSBS> entry in maps) { string location = entry.Key; MSBS msb = entry.Value; Obj map = Obj.Map(location); int treasureIndex = 0; foreach (MSBS.Event.Treasure treasure in msb.Events.Treasures) { if (treasure.TreasurePartName != null && treasure.ItemLotID != -1) { Obj treasureObj = Obj.Treasure(location, treasureIndex); Obj part = Obj.Part(location, treasure.TreasurePartName); u.Add(Verb.PRODUCES, part, treasureObj); u.Add(Verb.PRODUCES, treasureObj, Obj.Lot(treasure.ItemLotID)); } treasureIndex++; } foreach (MSBS.Event.Talk talk in msb.Events.Talks) { for (int i = 0; i < 2; i++) { string enemyName = talk.EnemyNames[i]; int esdId = talk.TalkIDs[i]; if (enemyName == null || esdId < 0) { continue; } Obj part = Obj.Part(location, enemyName); u.Add(Verb.CONTAINS, part, Obj.Esd(esdId)); } } foreach (MSBS.Entry obj in msb.Parts.GetEntries()) { MSBS.Part part = obj as MSBS.Part; if (part == null) { continue; } Obj partObj = Obj.Part(location, part.Name); if (part.EntityID != -1) { u.Add(Verb.CONTAINS, Obj.Entity(part.EntityID), partObj); } foreach (int groupId in part.EntityGroupIDs.Where(groupID => groupID > 0)) { u.Add(Verb.CONTAINS, Obj.Entity(groupId), partObj); } if (part is MSBS.Part.Enemy enemy) { string model = part.Name.Split('_')[0]; u.Add(Verb.CONTAINS, partObj, Obj.ChrModel(model)); if (enemy.NPCParamID != -1) { u.Add(Verb.CONTAINS, partObj, Obj.Npc(enemy.NPCParamID)); } } else if (part is MSBS.Part.Object) { string model = part.Name.Split('_')[0]; u.Add(Verb.CONTAINS, partObj, Obj.ObjModel(model)); } // This gets a bit noisy, so don't add part to map unless it's already in universe if (u.Nodes.ContainsKey(partObj)) { u.Add(Verb.CONTAINS, map, partObj); } } } } else if (spec.Game == FromGame.DS1 || spec.Game == FromGame.DS1R) { Dictionary <string, MSB1> maps = editor.Load(spec.MsbDir, path => path.Contains("m99") ? null : MSB1.Read(path), "*.msb"); foreach (KeyValuePair <string, MSB1> entry in maps) { string location = entry.Key; Obj map = Obj.Map(location); MSB1 msb = entry.Value; if (msb == null) { continue; } // For now, just load talk data foreach (MSB1.Entry obj in msb.Parts.GetEntries()) { MSB1.Part part = obj as MSB1.Part; if (part == null) { continue; } Obj partObj = Obj.Part(location, part.Name); if (part.EntityID != -1) { u.Add(Verb.CONTAINS, Obj.Entity(part.EntityID), partObj); } if (part is MSB1.Part.Enemy enemy) { string model = part.Name.Split('_')[0]; u.Add(Verb.CONTAINS, partObj, Obj.ChrModel(model)); if (enemy.NPCParamID != -1 && model == "c0000") { u.Add(Verb.CONTAINS, partObj, Obj.Human(enemy.NPCParamID)); } if (enemy.TalkID != -1) { u.Add(Verb.CONTAINS, partObj, Obj.Esd(enemy.TalkID)); } } else if (part is MSB1.Part.Object) { string model = part.Name.Split('_')[0]; u.Add(Verb.CONTAINS, partObj, Obj.ObjModel(model)); } // This gets a bit noisy, so don't add part to map unless it's already in universe if (u.Nodes.ContainsKey(partObj)) { u.Add(Verb.CONTAINS, map, partObj); } } } } else if (spec.Game == FromGame.DS3) { Dictionary <string, MSB3> maps = editor.Load(spec.MsbDir, path => path.Contains("m99") ? null : MSB3.Read(path)); foreach (KeyValuePair <string, MSB3> entry in maps) { string location = entry.Key; Obj map = Obj.Map(location); MSB3 msb = entry.Value; if (msb == null) { continue; } // For now, just load talk data foreach (MSB3.Entry obj in msb.Parts.GetEntries()) { MSB3.Part part = obj as MSB3.Part; if (part == null) { continue; } Obj partObj = Obj.Part(location, part.Name); if (part.EventEntityID != -1) { u.Add(Verb.CONTAINS, Obj.Entity(part.EventEntityID), partObj); } if (part is MSB3.Part.Enemy enemy) { string model = part.Name.Split('_')[0]; u.Add(Verb.CONTAINS, partObj, Obj.ChrModel(model)); if (enemy.CharaInitID > 0) { u.Add(Verb.CONTAINS, partObj, Obj.Human(enemy.CharaInitID)); } if (enemy.TalkID != -1) { u.Add(Verb.CONTAINS, partObj, Obj.Esd(enemy.TalkID)); } } else if (part is MSB3.Part.Object) { string model = part.Name.Split('_')[0]; u.Add(Verb.CONTAINS, partObj, Obj.ObjModel(model)); } // This gets a bit noisy, so don't add part to map unless it's already in universe if (u.Nodes.ContainsKey(partObj)) { u.Add(Verb.CONTAINS, map, partObj); } } } } else { return(false); } return(true); }
public void WriteEventConfig(AnnotationData ann, Events events, RandomizerOptions opt) { GameEditor editor = new GameEditor(FromGame.DS3); editor.Spec.GameDir = "fogdist"; Dictionary <string, MSB3> maps = editor.Load(@"Base", path => ann.Specs.ContainsKey(GameEditor.BaseName(path)) ? MSB3.Read(path) : null, "*.msb.dcx"); Dictionary <string, EMEVD> emevds = editor.Load(@"Base", path => ann.Specs.ContainsKey(GameEditor.BaseName(path)) || path.Contains("common") ? EMEVD.Read(path) : null, "*.emevd.dcx"); void deleteEmpty <K, V>(Dictionary <K, V> d) { foreach (K key in d.Keys.ToList()) { if (d[key] == null) { d.Remove(key); } } } // Should this be in GameEditor? deleteEmpty(maps); deleteEmpty(emevds); editor.Spec.NameDir = @"fogdist\Names"; Dictionary <string, string> modelNames = editor.LoadNames("ModelName", n => n); SortedDictionary <int, string> chars = new SortedDictionary <int, string>(editor.LoadNames("CharaInitParam", n => int.Parse(n))); Dictionary <string, List <string> > description = new Dictionary <string, List <string> >(); Dictionary <int, string> entityNames = new Dictionary <int, string>(); Dictionary <int, List <int> > groupIds = new Dictionary <int, List <int> >(); Dictionary <(string, string), MSB3.Event.ObjAct> objacts = new Dictionary <(string, string), MSB3.Event.ObjAct>(); HashSet <int> highlightIds = new HashSet <int>(); HashSet <int> selectIds = new HashSet <int>(); foreach (Entrance e in ann.Warps.Concat(ann.Entrances)) { int id = e.ID; AddMulti(description, id.ToString(), (ann.Warps.Contains(e) ? "" : "fog gate ") + e.Text); selectIds.Add(e.ID); highlightIds.Add(e.ID); } HashSet <string> gameObjs = new HashSet <string>(); foreach (GameObject obj in ann.Objects) { if (int.TryParse(obj.ID, out int id)) { AddMulti(description, id.ToString(), obj.Text); selectIds.Add(id); highlightIds.Add(id); } else { gameObjs.Add($"{obj.Area}_{obj.ID}"); } } Dictionary <string, Dictionary <string, FMG> > fmgs = new GameEditor(FromGame.DS3).LoadBnds($@"msg\engus", (data, name) => FMG.Read(data), ext: "*_dlc2.msgbnd.dcx"); void addFMG(FMG fmg, string desc) { foreach (FMG.Entry e in fmg.Entries) { if (e.ID > 25000 && !string.IsNullOrWhiteSpace(e.Text)) { highlightIds.Add(e.ID); AddMulti(description, e.ID.ToString(), desc + " " + "\"" + e.Text.Replace("\r", "").Replace("\n", "\\n") + "\""); } } } addFMG(fmgs["item_dlc2"]["NPC名"], "name"); addFMG(fmgs["menu_dlc2"]["イベントテキスト"], "text"); foreach (KeyValuePair <string, MSB3> entry in maps) { string map = ann.Specs[entry.Key].Name; MSB3 msb = entry.Value; foreach (MSB3.Part e in msb.Parts.GetEntries()) { string shortName = $"{map}_{e.Name}"; if (modelNames.TryGetValue(e.ModelName, out string modelDesc)) { if (e is MSB3.Part.Enemy en && modelDesc == "Human NPC" && en.CharaInitID > 0) { modelDesc = CharacterName(chars, en.CharaInitID); } else if (e is MSB3.Part.Player) { modelDesc = "Warp Point"; } AddMulti(description, shortName, modelDesc); } AddMulti(description, shortName, $"{map} {e.GetType().Name.ToString().ToLowerInvariant()} {e.Name}"); // {(e.EventEntityID > 0 ? $" {e.EventEntityID}" : "")} if (e.EventEntityID > 10) { highlightIds.Add(e.EventEntityID); string idStr = e.EventEntityID.ToString(); if (description.ContainsKey(idStr)) { AddMulti(description, shortName, description[idStr]); } description[idStr] = description[shortName]; if (e is MSB3.Part.Player || e.ModelName == "o000100") { selectIds.Add(e.EventEntityID); } if (selectIds.Contains(e.EventEntityID)) { gameObjs.Add(shortName); } foreach (int id in e.EventEntityGroups) { if (id > 0) { AddMulti(groupIds, id, e.EventEntityID); highlightIds.Add(id); } } } } foreach (MSB3.Region r in msb.Regions.GetEntries()) { if (r.EventEntityID < 1000000) { continue; } AddMulti(description, r.EventEntityID.ToString(), $"{map} {r.GetType().Name.ToLowerInvariant()} region {r.Name}"); highlightIds.Add(r.EventEntityID); } foreach (MSB3.Event e in msb.Events.GetEntries()) { if (e is MSB3.Event.ObjAct oa) { // It can be null, basically for commented out objacts string part = oa.PartName ?? oa.PartName2; if (part == null) { continue; } string desc = description.TryGetValue($"{map}_{part}", out List <string> p) ? string.Join(" - ", p) : throw new Exception($"{map} {oa.Name}"); objacts[(map, part)] = oa;