S4-07 process 2
当前 `Tag.txt -> DRTag -> TagGenerationRuleRegistry` 已形成组件 Tag 生成规则闭环: - `InventoryTagRuleService` 不再主要依赖内部 `MinRarity` 硬编码,而是统一消费 `DRTag` 提供的 `MinRarity + Weight` - `ShopFormUseCase`、`EnemyDropResolver`、`InventorySeedUtility` 也已切回这一统一入口。 - 现阶段的职责边界明确为:`Tag.txt` 负责基础字典与生成规则,`TagConfig.txt` 负责触发阶段、描述与效果参数。
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
namespace GeometryTD.Definition
|
||||
{
|
||||
public enum ProcedureMainCombatEntryBlockReason
|
||||
{
|
||||
None = 0,
|
||||
InventoryUnavailable = 1,
|
||||
NoValidParticipantTower = 2
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6d8af9f1d7d4041bfcee904724303e9
|
||||
timeCreated: 1773198097
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace GeometryTD.Definition
|
||||
{
|
||||
public enum ProcedureMainFlowPhase
|
||||
{
|
||||
Hub = 0,
|
||||
NodeActive = 1,
|
||||
RunCompletedPendingFinish = 2
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01450486bd824f47bcd74dda8a160ba4
|
||||
timeCreated: 1773198057
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace GeometryTD.Definition
|
||||
{
|
||||
public enum ProcedureMainRunAdvanceResult
|
||||
{
|
||||
NoChange = 0,
|
||||
NodeException = 1,
|
||||
AdvancedToNextNode = 2,
|
||||
RunCompleted = 3
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e9e0fa56d7e84874ac0f9d4a400fda13
|
||||
timeCreated: 1773198071
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace GeometryTD.Definition
|
||||
{
|
||||
public enum ProcedureMainRunCompletionResult
|
||||
{
|
||||
NoChange = 0,
|
||||
ShowCompletionDialog = 1,
|
||||
ReturnToMenu = 2
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3d0df05f77043a99c463a790b5ac35f
|
||||
timeCreated: 1773198084
|
||||
@@ -1,33 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Random = System.Random;
|
||||
|
||||
namespace GeometryTD.Definition
|
||||
{
|
||||
public static class InventoryTagRuleService
|
||||
{
|
||||
private static readonly IReadOnlyDictionary<TagType, RarityType> DefaultMinRarityByTag =
|
||||
new Dictionary<TagType, RarityType>
|
||||
{
|
||||
{ TagType.Fire, RarityType.White },
|
||||
{ TagType.Ice, RarityType.White },
|
||||
{ TagType.Crit, RarityType.White },
|
||||
{ TagType.Shatter, RarityType.Green },
|
||||
{ TagType.Inferno, RarityType.Purple },
|
||||
{ TagType.AbsoluteZero, RarityType.Purple },
|
||||
{ TagType.Execution, RarityType.Purple },
|
||||
};
|
||||
|
||||
private static readonly HashSet<TagType> SupportedLaunchTags = new HashSet<TagType>(DefaultMinRarityByTag.Keys);
|
||||
|
||||
public static TagType[] ResolveComponentTags(
|
||||
IReadOnlyList<TagType> possibleTags,
|
||||
RarityType rarity,
|
||||
InventoryTagSourceType sourceType,
|
||||
long itemInstanceId,
|
||||
int configId,
|
||||
IReadOnlyDictionary<TagType, RarityType> minRarityByTag = null)
|
||||
IReadOnlyDictionary<TagType, TagGenerationRuleData> rulesByTag = null)
|
||||
{
|
||||
TagType[] eligibleTags = GetEligibleTags(possibleTags, rarity, minRarityByTag);
|
||||
IReadOnlyDictionary<TagType, TagGenerationRuleData> ruleLookup = rulesByTag ?? TagGenerationRuleRegistry.Rules;
|
||||
TagType[] eligibleTags = GetEligibleTags(possibleTags, rarity, ruleLookup);
|
||||
if (eligibleTags.Length <= 0)
|
||||
{
|
||||
return Array.Empty<TagType>();
|
||||
@@ -45,7 +34,7 @@ namespace GeometryTD.Definition
|
||||
TagType[] result = new TagType[finalCount];
|
||||
for (int i = 0; i < finalCount; i++)
|
||||
{
|
||||
int index = random.Next(0, pool.Count);
|
||||
int index = RollWeightedIndex(pool, ruleLookup, random);
|
||||
result[i] = pool[index];
|
||||
pool.RemoveAt(index);
|
||||
}
|
||||
@@ -56,7 +45,7 @@ namespace GeometryTD.Definition
|
||||
public static TagType[] GetEligibleTags(
|
||||
IReadOnlyList<TagType> possibleTags,
|
||||
RarityType rarity,
|
||||
IReadOnlyDictionary<TagType, RarityType> minRarityByTag = null)
|
||||
IReadOnlyDictionary<TagType, TagGenerationRuleData> rulesByTag = null)
|
||||
{
|
||||
if (possibleTags == null || possibleTags.Count <= 0)
|
||||
{
|
||||
@@ -64,23 +53,23 @@ namespace GeometryTD.Definition
|
||||
}
|
||||
|
||||
RarityType normalizedRarity = InventoryRarityRuleService.NormalizeComponentRarity(rarity);
|
||||
IReadOnlyDictionary<TagType, RarityType> rarityLookup = minRarityByTag ?? DefaultMinRarityByTag;
|
||||
IReadOnlyDictionary<TagType, TagGenerationRuleData> ruleLookup = rulesByTag ?? TagGenerationRuleRegistry.Rules;
|
||||
HashSet<TagType> uniqueTags = new HashSet<TagType>();
|
||||
|
||||
for (int i = 0; i < possibleTags.Count; i++)
|
||||
{
|
||||
TagType tagType = possibleTags[i];
|
||||
if (!IsSupportedLaunchTag(tagType) || tagType == TagType.None || !Enum.IsDefined(typeof(TagType), tagType))
|
||||
if (tagType == TagType.None || !Enum.IsDefined(typeof(TagType), tagType) || !IsSupportedLaunchTag(tagType))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!TryGetMinRarity(tagType, rarityLookup, out RarityType minRarity))
|
||||
if (!TryGetRule(tagType, ruleLookup, out TagGenerationRuleData rule))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (normalizedRarity < InventoryRarityRuleService.NormalizeComponentRarity(minRarity))
|
||||
if (normalizedRarity < InventoryRarityRuleService.NormalizeComponentRarity(rule.MinRarity))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -123,28 +112,55 @@ namespace GeometryTD.Definition
|
||||
|
||||
private static bool IsSupportedLaunchTag(TagType tagType)
|
||||
{
|
||||
return SupportedLaunchTags.Contains(tagType);
|
||||
return TagConfigRegistry.TryGetDefinition(tagType, out TagDefinitionData definition) &&
|
||||
definition.Config != null &&
|
||||
definition.Config.IsImplemented;
|
||||
}
|
||||
|
||||
private static bool TryGetMinRarity(
|
||||
private static bool TryGetRule(
|
||||
TagType tagType,
|
||||
IReadOnlyDictionary<TagType, RarityType> rarityLookup,
|
||||
out RarityType minRarity)
|
||||
IReadOnlyDictionary<TagType, TagGenerationRuleData> ruleLookup,
|
||||
out TagGenerationRuleData rule)
|
||||
{
|
||||
if (rarityLookup != null && rarityLookup.TryGetValue(tagType, out minRarity))
|
||||
if (ruleLookup != null && ruleLookup.TryGetValue(tagType, out rule))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (DefaultMinRarityByTag.TryGetValue(tagType, out minRarity))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
minRarity = RarityType.White;
|
||||
rule = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int RollWeightedIndex(
|
||||
IReadOnlyList<TagType> pool,
|
||||
IReadOnlyDictionary<TagType, TagGenerationRuleData> ruleLookup,
|
||||
Random random)
|
||||
{
|
||||
int totalWeight = 0;
|
||||
for (int i = 0; i < pool.Count; i++)
|
||||
{
|
||||
TagGenerationRuleData rule = ruleLookup[pool[i]];
|
||||
Debug.Assert(rule.Weight > 0);
|
||||
totalWeight += rule.Weight;
|
||||
}
|
||||
|
||||
Debug.Assert(totalWeight > 0);
|
||||
|
||||
int roll = random.Next(1, totalWeight + 1);
|
||||
int cumulative = 0;
|
||||
for (int i = 0; i < pool.Count; i++)
|
||||
{
|
||||
TagGenerationRuleData rule = ruleLookup[pool[i]];
|
||||
cumulative += rule.Weight;
|
||||
if (roll <= cumulative)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return pool.Count - 1;
|
||||
}
|
||||
|
||||
private static int BuildStableSeed(
|
||||
RarityType rarity,
|
||||
InventoryTagSourceType sourceType,
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace GeometryTD.Definition
|
||||
{
|
||||
public sealed class TagGenerationRuleData
|
||||
{
|
||||
public TagType TagType { get; set; }
|
||||
public RarityType MinRarity { get; set; }
|
||||
public int Weight { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cfe508e818ce47649a112ecdf86cf26a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,74 @@
|
||||
using System.Collections.Generic;
|
||||
using GeometryTD.DataTable;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GeometryTD.Definition
|
||||
{
|
||||
public static class TagGenerationRuleRegistry
|
||||
{
|
||||
private static readonly Dictionary<TagType, TagGenerationRuleData> RulesByTag = CreateDefaultRules();
|
||||
|
||||
public static IReadOnlyDictionary<TagType, TagGenerationRuleData> Rules => RulesByTag;
|
||||
|
||||
public static void ResetToDefaults()
|
||||
{
|
||||
RulesByTag.Clear();
|
||||
foreach (KeyValuePair<TagType, TagGenerationRuleData> pair in CreateDefaultRules())
|
||||
{
|
||||
RulesByTag.Add(pair.Key, pair.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LoadFromRows(IEnumerable<DRTag> rows)
|
||||
{
|
||||
ResetToDefaults();
|
||||
foreach (DRTag row in rows)
|
||||
{
|
||||
ApplyRow(row);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TryGetRule(TagType tagType, out TagGenerationRuleData rule)
|
||||
{
|
||||
return RulesByTag.TryGetValue(tagType, out rule);
|
||||
}
|
||||
|
||||
private static Dictionary<TagType, TagGenerationRuleData> CreateDefaultRules()
|
||||
{
|
||||
return new Dictionary<TagType, TagGenerationRuleData>
|
||||
{
|
||||
[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, 20),
|
||||
[TagType.FreezeMask] = CreateRule(TagType.FreezeMask, RarityType.White, 20),
|
||||
[TagType.Shatter] = CreateRule(TagType.Shatter, RarityType.Green, 15),
|
||||
[TagType.AbsoluteZero] = CreateRule(TagType.AbsoluteZero, RarityType.Purple, 5),
|
||||
[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 TagGenerationRuleData CreateRule(TagType tagType, RarityType minRarity, int weight)
|
||||
{
|
||||
return new TagGenerationRuleData
|
||||
{
|
||||
TagType = tagType,
|
||||
MinRarity = minRarity,
|
||||
Weight = weight
|
||||
};
|
||||
}
|
||||
|
||||
private static void ApplyRow(DRTag row)
|
||||
{
|
||||
Debug.Assert(row != null);
|
||||
Debug.Assert(row.Id > 0);
|
||||
Debug.Assert(row.Weight > 0);
|
||||
|
||||
RulesByTag[row.TagType] = CreateRule(row.TagType, row.MinRarity, row.Weight);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e72e26721274985ba2d44ca825d7f75
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user