Skip to content

Commit

Permalink
Boss shuffling probably works now
Browse files Browse the repository at this point in the history
  • Loading branch information
TheUnlocked committed Aug 23, 2020
1 parent c8a4259 commit a1a1799
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 13 deletions.
8 changes: 4 additions & 4 deletions CurioShuffler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,28 +188,28 @@ private CurioTypeLibrary ShuffleCurioTypeLibrary(CurioTypeLibrary curioTypeLibra
var roomTreasures = treasures.Take(random.Next(4, 8));

newDict["hall_curios"] = hallCurios
.Select(x => new Darkest.DarkestEntry("hall_curios", new Dictionary<string, string[]>()
.Select(x => new Darkest.DarkestEntry("hall_curios", new Dictionary<string, IReadOnlyList<string>>()
{
{ "chance", new[] { random.Next(1, 11).ToString() } },
{ "types", new[] { x.IdString } }
}))
.ToList();
if (!model.IncludeShamblerAltar)
{
newDict["hall_curios"].Add(new Darkest.DarkestEntry("hall_curios", new Dictionary<string, string[]>() {
newDict["hall_curios"].Add(new Darkest.DarkestEntry("hall_curios", new Dictionary<string, IReadOnlyList<string>>() {
{ "chance", new[] { "1" } },
{ "types", new[] { "shamblers_altar" } }
}));
}
newDict["room_curios"] = roomCurios
.Select(x => new Darkest.DarkestEntry("room_curios", new Dictionary<string, string[]>()
.Select(x => new Darkest.DarkestEntry("room_curios", new Dictionary<string, IReadOnlyList<string>>()
{
{ "chance", new[] { random.Next(1, 11).ToString() } },
{ "types", new[] { x.IdString } }
}))
.ToList();
newDict["room_treasures"] = roomCurios
.Select(x => new Darkest.DarkestEntry("room_curios", new Dictionary<string, string[]>()
.Select(x => new Darkest.DarkestEntry("room_curios", new Dictionary<string, IReadOnlyList<string>>()
{
{ "chance", new[] { random.Next(1, 11).ToString() } },
{ "types", new[] { x.IdString } }
Expand Down
6 changes: 3 additions & 3 deletions DDFileTypes/Darkest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace DarkestDungeonRandomizer.DDFileTypes
{
public record Darkest(IReadOnlyDictionary<string, IReadOnlyList<Darkest.DarkestEntry>> Entries)
{
public record DarkestEntry(string Type, IReadOnlyDictionary<string, string[]> Properties);
public record DarkestEntry(string Type, IReadOnlyDictionary<string, IReadOnlyList<string>> Properties);

public static Darkest LoadFromFile(string filename)
{
Expand All @@ -32,7 +32,7 @@ public static Darkest Load(string data)
Dictionary<string, List<DarkestEntry>> entries = new Dictionary<string, List<DarkestEntry>>();

string? currentType = null;
Dictionary<string, string[]> currentProps = null!;
Dictionary<string, IReadOnlyList<string>> currentProps = null!;
string? currentPropName = null;
List<string> currentPropValues = null!;

Expand All @@ -49,7 +49,7 @@ public static Darkest Load(string data)
entries.GetValueOrSetDefault(currentType, new List<DarkestEntry>()).Add(new DarkestEntry(currentType, currentProps));
}
currentType = str[0..^1];
currentProps = new Dictionary<string, string[]>();
currentProps = new Dictionary<string, IReadOnlyList<string>>();
}
else if (currentType != null)
{
Expand Down
89 changes: 84 additions & 5 deletions EnemyShuffler.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
using DarkestDungeonRandomizer.DDFileTypes;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
Expand All @@ -23,7 +27,7 @@ public EnemyShuffler(MainViewModel model, Random random)

public void Randomize()
{
if (model.RandomizeMonsters)
if (model.RandomizeMonsters || model.RandomizeBosses)
{
var dungeons = new[] { "cove", "crypts", "warrens", "weald" };
var levels = new[] { 1, 3, 5 };
Expand All @@ -36,11 +40,41 @@ public void Randomize()

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

JObject questTypeFile = JObject.Parse(File.ReadAllText(model.GetGameDataPath(Path.Combine("campaign", "quest", "quest.types.json"))));
var bossLayoutConversion = bossLayouts.Zip(shuffledBossLayouts, (original, shuffled) => (original, shuffled));
foreach (var goal in questTypeFile["goals"]!) {
if (goal?["data"]?["monster_class_ids"] != null)
{
goal["data"]!["monster_class_ids"] = bossLayoutConversion
.FirstOrDefault(bossLayout => goal["data"]!["monster_class_ids"]!
.Any(questMonster => bossLayout.original.Contains((string)questMonster!)))
switch
{
(null, null) => goal["data"]!["monster_class_ids"],
var x => JToken.FromObject(x.shuffled)
};
}
}
var campaignDir = model.ModDirectory.CreateSubdirectory("campaign");
var questDir = campaignDir.CreateSubdirectory("quest");
File.WriteAllText(Path.Combine(questDir.FullName, "quest.types.json"), questTypeFile.ToString());
}

dungeons.Zip(shuffledDungeonFiles, (dungeon, darkest) =>
{
Expand Down Expand Up @@ -124,5 +158,50 @@ private IEnumerable<Darkest> ReplaceEnemies(
return darkest with { Entries = newEntries };
});
}

private IEnumerable<IReadOnlyList<string>> GetAllBossLayouts(IEnumerable<Darkest> files)
{
List<IReadOnlyList<string>> bossLayouts = new List<IReadOnlyList<string>>();
foreach (var file in files)
{
foreach (var (entryTag, entries) in file.Entries)
{
if (entryTag == "boss")
{
foreach (var entry in entries)
{
// No Shrieker
if (entry.Properties["types"].Any(x => x.StartsWith("crow")))
{
continue;
}
bossLayouts.Add(entry.Properties["types"]);
}
}
}
}
return bossLayouts;
}

private IEnumerable<Darkest> ReplaceBosses(IEnumerable<Darkest> files, IReadOnlyList<string>[] bossLayouts)
{
int i = 0;

return files.Select(darkest =>
{
var newEntries = darkest.Entries.ToDictionary(p => p.Key, p => p.Value);
newEntries["boss"] = newEntries["boss"].Select(entry =>
{
if (entry.Properties["types"].Any(x => x.StartsWith("crow")))
{
return entry;
}
var newProps = entry.Properties.ToDictionary(p => p.Key, p => p.Value);
newProps["types"] = bossLayouts[i++];
return entry with { Properties = newProps };
}).ToArray();
return darkest with { Entries = newEntries };
});
}
}
}
2 changes: 1 addition & 1 deletion MainWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
<CheckBox IsChecked="{Binding RandomizeMonsters}">
<TextBlock>Shuffle Monsters</TextBlock>
</CheckBox>
<CheckBox ToolTip.Tip="Not Yet Implemented" IsChecked="{Binding RandomizeBosses}">
<CheckBox IsChecked="{Binding RandomizeBosses}">
<TextBlock>Shuffle Bosses</TextBlock>
</CheckBox>
</WrapPanel>
Expand Down

0 comments on commit a1a1799

Please sign in to comment.