diff --git a/src/GeometryTD.Domain/DataTable/RarityTagBudgetRow.cs b/src/GeometryTD.Domain/DataTable/RarityTagBudgetRow.cs new file mode 100644 index 0000000..5a3f6b9 --- /dev/null +++ b/src/GeometryTD.Domain/DataTable/RarityTagBudgetRow.cs @@ -0,0 +1,44 @@ +using System; +using GameFramework.DataTable; +using GeometryTD.Definition; + +namespace GeometryTD.Domain.DataTable +{ + public sealed class RarityTagBudgetRow : IDataRow + { + private static readonly char[] DataSplitSeparators = new char[] { '\t' }; + private static readonly char[] DataTrimSeparators = new char[] { '"' }; + + public int Id { get; private set; } + + public RarityType Rarity { get; private set; } + + public int MinCount { get; private set; } + + public int MaxCount { get; private set; } + + public bool ParseDataRow(string dataRowString, object userData) + { + string[] columnStrings = dataRowString.Split(DataSplitSeparators); + for (int i = 0; i < columnStrings.Length; i++) + { + columnStrings[i] = columnStrings[i].Trim(DataTrimSeparators); + } + + int index = 0; + index++; + Id = int.Parse(columnStrings[index++]); + index++; + Rarity = Enum.Parse(columnStrings[index++]); + MinCount = int.Parse(columnStrings[index++]); + MaxCount = int.Parse(columnStrings[index++]); + + return true; + } + + public bool ParseDataRow(byte[] dataRowBytes, int startIndex, int length, object userData) + { + throw new NotSupportedException("Binary parsing is not supported."); + } + } +} \ No newline at end of file diff --git a/src/GeometryTD.Domain/DataTable/TagRow.cs b/src/GeometryTD.Domain/DataTable/TagRow.cs new file mode 100644 index 0000000..2a323d2 --- /dev/null +++ b/src/GeometryTD.Domain/DataTable/TagRow.cs @@ -0,0 +1,59 @@ +using System; +using GameFramework.DataTable; +using GeometryTD.Definition; + +namespace GeometryTD.Domain.DataTable +{ + public sealed class TagRow : IDataRow + { + private static readonly char[] DataSplitSeparators = new char[] { '\t' }; + private static readonly char[] DataTrimSeparators = new char[] { '"' }; + + public int Id { get; private set; } + + public TagType TagType => (TagType)Id; + + public RarityType MinRarity { get; private set; } + + public int Weight { get; private set; } + + public bool IsImplemented { get; private set; } + + public bool ParseDataRow(string dataRowString, object userData) + { + string[] columnStrings = dataRowString.Split(DataSplitSeparators); + for (int i = 0; i < columnStrings.Length; i++) + { + columnStrings[i] = columnStrings[i].Trim(DataTrimSeparators); + } + + int index = 0; + index++; + Id = int.Parse(columnStrings[index++]); + index++; + index++; + + bool hasExtendedColumns = columnStrings.Length - index >= 4; + if (hasExtendedColumns) + { + index++; + MinRarity = Enum.Parse(columnStrings[index++]); + Weight = int.Parse(columnStrings[index++]); + IsImplemented = bool.Parse(columnStrings[index++]); + } + else + { + MinRarity = Enum.Parse(columnStrings[index++]); + Weight = int.Parse(columnStrings[index++]); + IsImplemented = true; + } + + return true; + } + + public bool ParseDataRow(byte[] dataRowBytes, int startIndex, int length, object userData) + { + throw new NotSupportedException("Binary parsing is not supported."); + } + } +} \ No newline at end of file diff --git a/src/GeometryTD.Domain/Definition/Tag/Generation/RarityTagBudgetRule.cs b/src/GeometryTD.Domain/Definition/Tag/Generation/RarityTagBudgetRule.cs new file mode 100644 index 0000000..7461e98 --- /dev/null +++ b/src/GeometryTD.Domain/Definition/Tag/Generation/RarityTagBudgetRule.cs @@ -0,0 +1,9 @@ +namespace GeometryTD.Definition +{ + public sealed class RarityTagBudgetRule + { + public RarityType Rarity { get; set; } + public int MinCount { get; set; } + public int MaxCount { get; set; } + } +} \ No newline at end of file diff --git a/src/GeometryTD.Domain/Definition/Tag/Generation/RarityTagBudgetRuleRegistry.cs b/src/GeometryTD.Domain/Definition/Tag/Generation/RarityTagBudgetRuleRegistry.cs new file mode 100644 index 0000000..fec4256 --- /dev/null +++ b/src/GeometryTD.Domain/Definition/Tag/Generation/RarityTagBudgetRuleRegistry.cs @@ -0,0 +1,62 @@ +using System.Collections.Generic; +using GeometryTD.Domain.DataTable; + +namespace GeometryTD.Definition +{ + public static class RarityTagBudgetRuleRegistry + { + private static readonly Dictionary RulesByRarity = CreateDefaultRules(); + + public static IReadOnlyDictionary Rules => RulesByRarity; + + public static void ResetToDefaults() + { + RulesByRarity.Clear(); + foreach (KeyValuePair pair in CreateDefaultRules()) + { + RulesByRarity.Add(pair.Key, pair.Value); + } + } + + public static void LoadFromRows(IEnumerable rows) + { + ResetToDefaults(); + foreach (RarityTagBudgetRow row in rows) + { + ApplyRow(row); + } + } + + public static bool TryGetRule(RarityType rarity, out RarityTagBudgetRule rule) + { + return RulesByRarity.TryGetValue(rarity, out rule); + } + + private static Dictionary CreateDefaultRules() + { + return new Dictionary + { + [RarityType.White] = CreateRule(RarityType.White, 0, 1), + [RarityType.Green] = CreateRule(RarityType.Green, 0, 2), + [RarityType.Blue] = CreateRule(RarityType.Blue, 1, 3), + [RarityType.Purple] = CreateRule(RarityType.Purple, 1, 3), + [RarityType.Red] = CreateRule(RarityType.Red, 2, 4) + }; + } + + private static RarityTagBudgetRule CreateRule(RarityType rarity, int minCount, int maxCount) + { + return new RarityTagBudgetRule + { + Rarity = rarity, + MinCount = minCount, + MaxCount = maxCount + }; + } + + private static void ApplyRow(RarityTagBudgetRow row) + { + RulesByRarity[row.Rarity] = CreateRule(row.Rarity, row.MinCount, row.MaxCount); + } + } +} \ No newline at end of file diff --git a/src/GeometryTD.Domain/Definition/Tag/Generation/TagGenerationRule.cs b/src/GeometryTD.Domain/Definition/Tag/Generation/TagGenerationRule.cs new file mode 100644 index 0000000..05e19cd --- /dev/null +++ b/src/GeometryTD.Domain/Definition/Tag/Generation/TagGenerationRule.cs @@ -0,0 +1,9 @@ +namespace GeometryTD.Definition +{ + public sealed class TagGenerationRule + { + public TagType TagType { get; set; } + public RarityType MinRarity { get; set; } + public int Weight { get; set; } + } +} \ No newline at end of file diff --git a/src/GeometryTD.Domain/Definition/Tag/Generation/TagGenerationRuleRegistry.cs b/src/GeometryTD.Domain/Definition/Tag/Generation/TagGenerationRuleRegistry.cs new file mode 100644 index 0000000..c8ab6bc --- /dev/null +++ b/src/GeometryTD.Domain/Definition/Tag/Generation/TagGenerationRuleRegistry.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using GeometryTD.Domain.DataTable; + +namespace GeometryTD.Definition +{ + public static class TagGenerationRuleRegistry + { + private static readonly Dictionary RulesByTag = CreateDefaultRules(); + + public static IReadOnlyDictionary Rules => RulesByTag; + + public static void ResetToDefaults() + { + RulesByTag.Clear(); + foreach (KeyValuePair pair in CreateDefaultRules()) + { + RulesByTag.Add(pair.Key, pair.Value); + } + } + + public static void LoadFromRows(IEnumerable rows) + { + ResetToDefaults(); + foreach (TagRow row in rows) + { + ApplyRow(row); + } + } + + public static bool TryGetRule(TagType tagType, out TagGenerationRule rule) + { + return RulesByTag.TryGetValue(tagType, out rule); + } + + private static Dictionary CreateDefaultRules() + { + return new Dictionary + { + [TagType.Fire] = CreateRule(TagType.Fire, RarityType.White, 20), + [TagType.BurnSpread] = CreateRule(TagType.BurnSpread, RarityType.White, 20), + [TagType.IgniteBurst] = CreateRule(TagType.IgniteBurst, RarityType.Green, 15), + [TagType.Inferno] = CreateRule(TagType.Inferno, RarityType.Purple, 5), + [TagType.Ice] = CreateRule(TagType.Ice, RarityType.White, 1), + [TagType.FreezeMask] = CreateRule(TagType.FreezeMask, RarityType.White, 20), + [TagType.Shatter] = CreateRule(TagType.Shatter, RarityType.Green, 15), + [TagType.AbsoluteZero] = CreateRule(TagType.AbsoluteZero, RarityType.Purple, 1), + [TagType.Pierce] = CreateRule(TagType.Pierce, RarityType.White, 20), + [TagType.Crit] = CreateRule(TagType.Crit, RarityType.White, 20), + [TagType.Overpenetrate] = CreateRule(TagType.Overpenetrate, RarityType.Green, 15), + [TagType.Execution] = CreateRule(TagType.Execution, RarityType.Purple, 5) + }; + } + + private static TagGenerationRule CreateRule(TagType tagType, RarityType minRarity, int weight) + { + return new TagGenerationRule + { + TagType = tagType, + MinRarity = minRarity, + Weight = weight + }; + } + + private static void ApplyRow(TagRow row) + { + RulesByTag[row.TagType] = CreateRule(row.TagType, row.MinRarity, row.Weight); + } + } +} \ No newline at end of file