Skip to content

Commit

Permalink
Stability + Hero stats randomization + Avalonia to 0.10 preview
Browse files Browse the repository at this point in the history
  • Loading branch information
TheUnlocked committed Aug 23, 2020
1 parent a1a1799 commit 829f6a5
Show file tree
Hide file tree
Showing 13 changed files with 368 additions and 91 deletions.
115 changes: 83 additions & 32 deletions DDFileTypes/Darkest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@

namespace DarkestDungeonRandomizer.DDFileTypes
{
public record Darkest(IReadOnlyDictionary<string, IReadOnlyList<Darkest.DarkestEntry>> Entries)
public record Darkest(IReadOnlyDictionary<string, IReadOnlyList<Darkest.DarkestEntry>> Entries, IReadOnlyDictionary<string, int> EntryTypeOrder)
{
public record DarkestEntry(string Type, IReadOnlyDictionary<string, IReadOnlyList<string>> Properties);
public record DarkestEntry(string Type, IReadOnlyDictionary<string, IReadOnlyList<string>> Properties, IReadOnlyDictionary<string, int> PropOrder);

public static Darkest LoadFromFile(string filename)
{
Expand All @@ -31,75 +31,96 @@ public static Darkest Load(string data)

Dictionary<string, List<DarkestEntry>> entries = new Dictionary<string, List<DarkestEntry>>();

Dictionary<string, int> typeOrder = new Dictionary<string, int>();
string? currentType = null;

Dictionary<string, int> propOrder = null!;
Dictionary<string, IReadOnlyList<string>> currentProps = null!;
string? currentPropName = null;

List<string> currentPropValues = null!;

foreach (var str in strings)
void ClearTypeBuffer(string? nextType)
{
if (str.EndsWith(':'))
if (currentType != null)
{
if (currentType != null)
ClearPropBuffer(null);
entries.GetValueOrSetDefault(currentType, new List<DarkestEntry>()).Add(new DarkestEntry(currentType, currentProps, propOrder));
if (!typeOrder.ContainsKey(currentType))
{
if (currentPropName != null)
{
currentProps[currentPropName] = currentPropValues.ToArray();
}
entries.GetValueOrSetDefault(currentType, new List<DarkestEntry>()).Add(new DarkestEntry(currentType, currentProps));
typeOrder[currentType] = typeOrder.Count;
}
currentType = str[0..^1];
}
if (nextType != null)
{
currentType = nextType;

propOrder = new Dictionary<string, int>();
currentProps = new Dictionary<string, IReadOnlyList<string>>();
currentPropName = null;
}
}

void ClearPropBuffer(string? nextProp)
{
if (currentPropName != null)
{
currentProps[currentPropName] = currentPropValues.ToArray();
if (!propOrder.ContainsKey(currentPropName))
{
propOrder[currentPropName] = propOrder.Count;
}
}
if (nextProp != null)
{
currentPropName = nextProp;
currentPropValues = new List<string>();
}
}

foreach (var str in strings)
{
if (str.EndsWith(':'))
{
ClearTypeBuffer(str[0..^1]);
}
else if (currentType != null)
{
if (str.StartsWith('.'))
{
if (currentPropName != null)
{
currentProps[currentPropName] = currentPropValues.ToArray();
}
currentPropName = str[1..];
currentPropValues = new List<string>();
ClearPropBuffer(str[1..]);

}
else if (currentPropName != null)
{
currentPropValues.Add(str);
}
}
}
ClearTypeBuffer(null);

if (currentType != null)
{
if (currentPropName != null)
{
currentProps[currentPropName] = currentPropValues.ToArray();
}
entries.GetValueOrSetDefault(currentType, new List<DarkestEntry>()).Add(new DarkestEntry(currentType, currentProps));
}

return new Darkest(entries.ToImmutableDictionary(p => p.Key, p => (IReadOnlyList<DarkestEntry>)p.Value));
return new Darkest(entries.ToImmutableDictionary(p => p.Key, p => (IReadOnlyList<DarkestEntry>)p.Value), typeOrder);
}

public void WriteToFile(string path)
{
File.WriteAllText(path, WriteToString());
File.WriteAllText(path, ToString());
}

public async void WriteToFileAsync(string path)
{
await File.WriteAllTextAsync(path, WriteToString());
await File.WriteAllTextAsync(path, ToString());
}

public string WriteToString()
public override string ToString()
{
var result = new StringBuilder();
foreach (var pair in Entries)
foreach (var pair in Entries.OrderBy(p => EntryTypeOrder[p.Key]))
{
foreach (var entry in pair.Value)
{
result.Append(entry.Type).Append(": ");
foreach (var propPair in entry.Properties.OrderBy(p => p.Key))
foreach (var propPair in entry.Properties.OrderBy(p => entry.PropOrder[p.Key]))
{
result.Append('.').Append(propPair.Key).Append(' ');
foreach (var value in propPair.Value)
Expand All @@ -113,5 +134,35 @@ public string WriteToString()
result.Length -= 1;
return result.ToString();
}

public Darkest Replace(IEnumerable<(string entryType, IEnumerable<(string property, Func<string, string> conversion)> propReplacements)> entryMatches)
{
var newEntries = Entries.ToDictionary(p => p.Key, p => p.Value);

foreach (var (entryType, propReplacements) in entryMatches)
{
newEntries[entryType] = newEntries[entryType].Select(entry =>
{
var newProps = entry.Properties.ToDictionary(p => p.Key, p => p.Value);
foreach (var (property, conversion) in propReplacements)
{
newProps[property] = newProps[property].Select(x => conversion(x)).ToImmutableArray();
}
return entry with { Properties = newProps };
}).ToImmutableArray();
}

return this with { Entries = newEntries };
}

public Darkest Replace(string entryType, IEnumerable<(string property, Func<string, string> conversion)> replacements)
{
return Replace(new[] { (entryType, replacements) });
}

public Darkest Replace(string entryType, string property, Func<string, string> conversion)
{
return Replace(entryType, new[] { (property, conversion) });
}
}
}
7 changes: 3 additions & 4 deletions DarkestDungeonRandomizer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
<LangVersion>preview</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="0.9.12" />
<PackageReference Include="Avalonia.Desktop" Version="0.9.12" />
<PackageReference Include="Avalonia.ReactiveUI" Version="0.9.12" />
<PackageReference Include="MessageBox.Avalonia" Version="0.9.6.1" />
<PackageReference Include="Avalonia" Version="0.10.0-preview3" />
<PackageReference Include="Avalonia.Desktop" Version="0.10.0-preview3" />
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.0-preview3" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="ReactiveUI" Version="11.5.26" />
</ItemGroup>
Expand Down
31 changes: 18 additions & 13 deletions MainViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
using Avalonia.Controls;
using DarkestDungeonRandomizer.DDFileTypes;
using DarkestDungeonRandomizer.DDTypes;
using MessageBox.Avalonia;
using DarkestDungeonRandomizer.Randomizers;
using DarkestDungeonRandomizer.MsgBox;
using ReactiveUI;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -30,6 +31,7 @@ public class MainViewModel : ReactiveObject
public bool IncludeStoryCurios { get; set; } = true;
public bool RandomizeMonsters { get; set; } = true;
public bool RandomizeBosses { get; set; } = true;
public double RandomizeHeroStats { get; set; } = 1;

public DirectoryInfo ModDirectory { get; private set; } = null!;
public Dictionary<string, Monster> Monsters { get; private set; } = null!;
Expand Down Expand Up @@ -59,7 +61,7 @@ public void CreateRandomizerMod()
{
if (DDPath == "")
{
MessageBoxManager.GetMessageBoxStandardWindow("Folder Not Found", "Please set the Darkest Dungeon game folder.", MessageBox.Avalonia.Enums.ButtonEnum.Ok).Show();
MessageBox.Show(window, "Please set the Darkest Dungeon game folder.", "Folder Not Found", MessageBox.MessageBoxButtons.Ok);
return;
}
try
Expand All @@ -70,21 +72,24 @@ public void CreateRandomizerMod()
var rand = new Random(Seed);
new CurioShuffler(this, rand).Randomize();
new EnemyShuffler(this, rand).Randomize();
MessageBoxManager.GetMessageBoxStandardWindow(
"Randomizer Finished", $"The randomizer mod has been created. Its tag is {ModCreator.GetRandomizerUUID(this)}",
MessageBox.Avalonia.Enums.ButtonEnum.Ok
).Show();
new HeroStatRandomizer(this, rand).Randomize();
MessageBox.Show(
window,
$"The randomizer mod has been created. Its tag is {ModCreator.GetRandomizerUUID(this)}",
"Randomizer Finished",
MessageBox.MessageBoxButtons.Ok);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
Console.WriteLine();
MessageBoxManager.GetMessageBoxStandardWindow(
e.GetType().FullName, $"{e.Message}\n{e.StackTrace}",
MessageBox.Avalonia.Enums.ButtonEnum.Ok,
MessageBox.Avalonia.Enums.Icon.Error
).Show();

//MessageBoxManager.GetMessageBoxStandardWindow(
// e.GetType().FullName, $"{e.Message}\n{e.StackTrace}",
// MessageBox.Avalonia.Enums.ButtonEnum.Ok,
// MessageBox.Avalonia.Enums.Icon.Error
//).Show();
}
}

Expand Down Expand Up @@ -127,7 +132,7 @@ public void OpenModsFolder()
}
catch
{
MessageBoxManager.GetMessageBoxStandardWindow("Folder Not Found", "Please set the Darkest Dungeon game folder.", MessageBox.Avalonia.Enums.ButtonEnum.Ok).Show();
MessageBox.Show(window, "Please set the Darkest Dungeon game folder.", "Folder Not Found", MessageBox.MessageBoxButtons.Ok);
}
}

Expand All @@ -142,7 +147,7 @@ public void StartDarkestDungeon()
}
catch
{
MessageBoxManager.GetMessageBoxStandardWindow("Folder Not Found", "Please set the Darkest Dungeon game folder.", MessageBox.Avalonia.Enums.ButtonEnum.Ok).Show();
MessageBox.Show(window, "Please set the Darkest Dungeon game folder.", "Folder Not Found", MessageBox.MessageBoxButtons.Ok);
}
}
}
Expand Down
13 changes: 11 additions & 2 deletions MainWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
x:Class="DarkestDungeonRandomizer.MainWindow"
Title="DarkestDungeonRandomizer">
<Window.Styles>
<Style Selector="Button, CheckBox, TextBox, TextBlock">
<Style Selector="Button, CheckBox, TextBox, TextBlock, Slider">
<Setter Property="Margin" Value="3"/>
</Style>
<Style Selector="TextBlock">
Expand Down Expand Up @@ -52,7 +52,7 @@
<CheckBox IsChecked="{Binding IncludeShamblerAltar}">
<TextBlock>Include Shambler Altar in Shuffles</TextBlock>
</CheckBox>
<CheckBox IsChecked="{Binding IncludeStoryCurios}">
<CheckBox ToolTip.Tip="This may or may not break the game..." IsChecked="{Binding IncludeStoryCurios}">
<TextBlock>Include Story Curios in Shuffles</TextBlock>
</CheckBox>
<CheckBox IsChecked="{Binding RandomizeMonsters}">
Expand All @@ -61,6 +61,15 @@
<CheckBox IsChecked="{Binding RandomizeBosses}">
<TextBlock>Shuffle Bosses</TextBlock>
</CheckBox>
<StackPanel Orientation="Horizontal" ToolTip.Tip="Values other than 1.00 and Off are experimental.">
<Slider
Name="RandomizeHeroStats"
Width="80"
Minimum="0" Maximum="1.5"
TickFrequency="0.25" IsSnapToTickEnabled="True"
Value="{Binding RandomizeHeroStats}"/>
<TextBlock Text="{Binding Path=#RandomizeHeroStats.Value, StringFormat='Randomize Hero Stats [{0:#,0.00;;Off}]'}"/>
</StackPanel>
</WrapPanel>
</StackPanel>
<StackPanel DockPanel.Dock="Bottom">
Expand Down
4 changes: 0 additions & 4 deletions MainWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ public MainWindow()
{
InitializeComponent();
DataContext = new MainViewModel(this);

#if DEBUG
this.AttachDevTools();
#endif
}

private void InitializeComponent()
Expand Down
13 changes: 7 additions & 6 deletions ModCreator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,13 @@ public static string GetRandomizerUUID(MainViewModel options)
{
int addin =
(options.RandomizeCurioEffects ? 1 : 0) +
(options.RandomizeCurioInteractions ? 2 : 0) +
(options.RandomizeCurioRegions ? 4 : 0) +
(options.IncludeShamblerAltar ? 8 : 0) +
(options.IncludeStoryCurios ? 16 : 0) +
(options.RandomizeMonsters ? 32 : 0) +
(options.RandomizeBosses ? 64 : 0);
(options.RandomizeCurioInteractions ? 1 << 1 : 0) +
(options.RandomizeCurioRegions ? 1 << 2 : 0) +
(options.IncludeShamblerAltar ? 1 << 3 : 0) +
(options.IncludeStoryCurios ? 1 << 4 : 0) +
(options.RandomizeMonsters ? 1 << 5 : 0) +
(options.RandomizeBosses ? 1 << 6 : 0) +
((int)(options.RandomizeHeroStats * 4) << 7) /* 3 bits */;
return addin.ToString("x").Trim('0') + options.Seed.ToString("x");
}
}
Expand Down
17 changes: 17 additions & 0 deletions MsgBox/MessageBox.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!-- https://stackoverflow.com/a/55707749/4937286 -->
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="DarkestDungeonRandomizer.MsgBox.MessageBox" SizeToContent="WidthAndHeight" CanResize="False">
<Window.Styles>
<Style Selector="Button, TextBlock.padded">
<Setter Property="Margin" Value="5"/>
</Style>
</Window.Styles>
<StackPanel HorizontalAlignment="Center" Margin="10">
<TextBlock Classes="padded" HorizontalAlignment="Center" Name="Text"/>
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal" Name="Buttons"/>
</StackPanel>
</Window>
Loading

0 comments on commit 829f6a5

Please sign in to comment.