public void Randomize()
    {
        if (model.RandomizeMonsters || model.RandomizeBosses)
        {
            var dungeons = new[] { "cove", "crypts", "warrens", "weald" };
            var levels   = new[] { 1, 3, 5 };

            foreach (var dungeon in dungeons)
            {
                var dungeonsDir = model.ModDirectory.CreateSubdirectory("dungeons");
                var dungeonDir  = dungeonsDir.CreateSubdirectory(dungeon);
            }

            foreach (var level in levels)
            {
                var dungeonFiles = dungeons.Select(dungeon => Darkest.LoadFromFile(model.GetGameDataPath(Path.Combine("dungeons", dungeon, $"{dungeon}.{level}.mash.darkest"))));
                if (model.RandomizeMonsters)
                {
                    var(hallEnemies, roomEnemies, stallEnemies) = GetAllEnemies(dungeonFiles);
                    var hallEnemyReplacements  = ShuffleMap(hallEnemies);
                    var roomEnemyReplacements  = ShuffleMap(roomEnemies);
                    var stallEnemyReplacements = ShuffleMap(stallEnemies);
                    dungeonFiles = ReplaceEnemies(dungeonFiles, hallEnemyReplacements, roomEnemyReplacements, stallEnemyReplacements);
                }
                if (model.RandomizeBosses)
                {
                    // Exclude shrieker!
                    var bossLayouts         = GetAllBossLayouts(dungeonFiles);
                    var shuffledBossLayouts = bossLayouts.Shuffle(random);
                    dungeonFiles = ReplaceBosses(dungeonFiles, shuffledBossLayouts);

                    var questTypeFile = JsonNode.Parse(File.ReadAllText(model.GetGameDataPath(Path.Combine("campaign", "quest", "quest.types.json"))))
                                        ?.AsObject();
                    if (questTypeFile == null)
                    {
                        throw new Exception("quest.types.json could not be parsed.");
                    }
                    var bossLayoutConversion = bossLayouts.Zip(shuffledBossLayouts, (original, shuffled) => (original, shuffled));
                    foreach (var goal in questTypeFile["goals"] !.AsArray())
                    {
                        if (goal == null)
                        {
                            continue;
                        }

                        var data = goal["data"]?.AsObject();
                        if (data == null)
                        {
                            continue;
                        }

                        var monsterClassIds = data["monster_class_ids"]?.AsArray();
                        if (monsterClassIds != null)
                        {
                            data["monster_class_ids"] = bossLayoutConversion
                                                        .FirstOrDefault(bossLayout => monsterClassIds
                                                                        .Any(questMonster => bossLayout.original.Contains((string)questMonster !)))
                                                        switch
                            {
                                (_, null) => goal["data"] !["monster_class_ids"],
 private void ReadBaseGameData()
 {
     Monsters = new Dictionary <string, Monster>();
     foreach (var monsterType in Directory.GetDirectories(Path.Combine(DDPath, "monsters")).Select(Path.GetFileName))
     {
         if (monsterType == null)
         {
             continue;
         }
         foreach (var monsterName in Directory.GetDirectories(Path.Combine(DDPath, "monsters", monsterType))
                  .Select(Path.GetFileName)
                  .Where(x => x != null && x.StartsWith(monsterType)))
         {
             if (monsterName == null)
             {
                 continue;                      // Extraneous but makes NRT stuff go away
             }
             Monsters[monsterName] = Monster.FromDarkest(
                 monsterName,
                 Darkest.LoadFromFile(Path.Combine(DDPath, "monsters", monsterType, monsterName, $"{monsterName}.info.darkest"))
                 );
         }
     }
     HeroNames = Directory.GetDirectories(Path.Combine(DDPath, "heroes")).Select(x => Path.GetFileName(x)).ToArray();
 }
    public void Randomize()
    {
        if (model.RandomizeCampingSkills)
        {
            var file = JsonNode.Parse(File.ReadAllText(model.GetGameDataPath(Path.Combine("raid", "camping", "default.camping_skills.json"))))
                       ?.AsObject();

            if (file == null || file["skills"] is not JsonArray skills || skills.Count < 7)
            {
                throw new Exception("default.camping_skills.json could not be parsed properly.");
            }

            // Make in-game layout look prettier :)
            file["configuration"] !.AsObject()["class_specific_number_of_classes_threshold"] = JsonValue.Create(100);
            var layoutFile = Darkest.LoadFromFile(model.GetGameDataPath(Path.Combine("campaign", "town", "buildings", "camping_trainer", "camping_trainer.layout.darkest")));
            layoutFile.Replace("camping_trainer_class_specific_skill_grid_layout", "skill_spacing", (x, _, i) => i == 1 ? "170" : x)
            .WriteToFile(Path.Combine(
                             model.ModDirectory
                             .CreateSubdirectory("campaign")
                             .CreateSubdirectory("town")
                             .CreateSubdirectory("buildings")
                             .CreateSubdirectory("camping_trainer")
                             .FullName,
                             "camping_trainer.layout.darkest"));

            foreach (var skill in skills)
            {
                skill !.AsObject()["hero_classes"] = new JsonArray();
            }

            foreach (var hero in model.HeroNames)
            {
                HashSet <int> skillIndicies = new HashSet <int>();
                while (skillIndicies.Count < 7)
                {
                    skillIndicies.Add(random.Next(0, skills.Count));
                }
                foreach (var skillIndex in skillIndicies)
                {
                    skills[skillIndex]?.AsObject()["hero_classes"]?.AsArray().Add(hero);
                }
            }

            File.WriteAllText(Path.Combine(
                                  model.ModDirectory
                                  .CreateSubdirectory("raid")
                                  .CreateSubdirectory("camping")
                                  .FullName,
                                  "default.camping_skills.json"), file.ToJsonString(new() { WriteIndented = true }));
        }
    }
    public void Randomize()
    {
        if (model.RandomizeHeroStats > 0)
        {
            var heroesDir = model.ModDirectory.CreateSubdirectory("heroes");

            foreach (var heroName in model.HeroNames)
            {
                var res    = GenerateBalancedModifiers(7).Select(x => Math.Round(x * baseResistance).ToString()).ToArray();
                var battle = GenerateBalancedModifiers(5);

                var darkest = Darkest.LoadFromFile(model.GetGameDataPath(Path.Combine("heroes", heroName, $"{heroName}.info.darkest")));

                var randomized = darkest.Replace(new[] {
Exemplo n.º 5
0
    public void Randomize()
    {
        if (model.RandomizeHeroSkills)
        {
            var heroesDir = model.ModDirectory.CreateSubdirectory("heroes");
            foreach (var hero in model.HeroNames)
            {
                heroesDir.CreateSubdirectory(hero);
            }

            var heroSkillMappings = GenerateHeroSkillMappings();

            var heroFiles = model.HeroNames.ToDictionary(
                name => name,
                name => (
                    info: Darkest.LoadFromFile(model.GetGameDataPath(Path.Combine("heroes", name, $"{name}.info.darkest"))),
                    art: Darkest.LoadFromFile(model.GetGameDataPath(Path.Combine("heroes", name, $"{name}.art.darkest")))
                    ));

            Darkest highwaymanInfo = null !;
            Darkest crusaderInfo   = null !;

            XmlDocument heroStrings = new XmlDocument();
            heroStrings.Load(model.GetGameDataPath(Path.Combine("localization", "heroes.string_table.xml")));

            var heroSkillNames = heroFiles.ToDictionary(p => p.Key, p => GetSkillsInOrder(p.Value.art));

            foreach (var hero in model.HeroNames)
            {
                var(info, art) = SwapCombatSkills(heroFiles, hero, heroSkillMappings);
                info.WriteToFile(Path.Combine(model.ModDirectory.FullName, "heroes", hero, $"{hero}.info.darkest"));
                art.WriteToFile(Path.Combine(model.ModDirectory.FullName, "heroes", hero, $"{hero}.art.darkest"));

                if (hero == "highwayman")
                {
                    highwaymanInfo = info;
                }
                else if (hero == "crusader")
                {
                    crusaderInfo = info;
                }

                var skillNames = heroSkillNames[hero];

                // Localization
                for (int i = 0; i < 7; i++)
                {
                    if (heroSkillMappings[hero][i] == hero)
                    {
                        continue;
                    }

                    var combatNodes = heroStrings.SelectNodes($"//entry[@id='combat_skill_name_{heroSkillMappings[hero][i]}_{heroSkillNames[heroSkillMappings[hero][i]][i]}']") !
                                      .Cast <XmlNode>()
                                      .Zip(heroStrings.SelectNodes($"//entry[@id='combat_skill_name_{hero}_{skillNames[i]}']") !
                                           .Cast <XmlNode>(),
                                           (a, b) => (from: b, to: a));
                    foreach (var(from, to) in combatNodes)
                    {
                        var originalAttr = heroStrings.CreateAttribute("original");
                        originalAttr.Value = from !.InnerXml;
                        from !.Attributes !.Append(originalAttr);

                        if (to?.Attributes?.GetNamedItem("original") is XmlAttribute a)
                        {
                            from !.InnerXml = a.Value;
                        }
                        else
                        {
                            from !.InnerXml = to !.InnerXml;
                        }
                    }

                    var upgradeNodes = heroStrings.SelectNodes($"//entry[@id='upgrade_tree_name_{heroSkillMappings[hero][i]}.{heroSkillNames[heroSkillMappings[hero][i]][i]}']") !
                                       .Cast <XmlNode>()
                                       .Zip(heroStrings.SelectNodes($"//entry[@id='upgrade_tree_name_{hero}.{skillNames[i]}']") !
                                            .Cast <XmlNode>(),
                                            (a, b) => (from: b, to: a));
                    foreach (var(from, to) in upgradeNodes)
                    {
                        var originalAttr = heroStrings.CreateAttribute("original");
                        originalAttr.Value = from !.InnerXml;
                        from !.Attributes !.Append(originalAttr);

                        if (to?.Attributes?.GetNamedItem("original") is XmlAttribute a)
                        {
                            from !.InnerXml = a.Value;
                        }
                        else
                        {
                            from !.InnerXml = to !.InnerXml;
                        }
                    }
                }
            }

            foreach (var node in heroStrings !.SelectNodes("//*[@original]") !.Cast <XmlNode>())
            {
                node?.Attributes !.RemoveNamedItem("original");
            }

            heroStrings.Save(Path.Combine(model.ModDirectory.CreateSubdirectory("localization").FullName, "heroes.string_table.xml"));

            SwapSkillIcons(heroSkillMappings);
            //UpdateStartingSave(highwaymanInfo, crusaderInfo);
        }
    }