diff --git a/.gitignore b/.gitignore index 27cf066..0566834 100644 --- a/.gitignore +++ b/.gitignore @@ -105,4 +105,7 @@ InitTestScene*.unity* /.dotnet /.idea ~$*.xlsx -/tools \ No newline at end of file +/tools +/node_modules +package.json +package-lock.json \ No newline at end of file diff --git a/Assets/GameMain/DataTables/Event.txt b/Assets/GameMain/DataTables/Event.txt index b8190fb..c51c58c 100644 --- a/Assets/GameMain/DataTables/Event.txt +++ b/Assets/GameMain/DataTables/Event.txt @@ -1,6 +1,6 @@ # Id 列1 Title Description Options # int string string string # 事件编号 策划备注 事件题目 事件描述 事件选项 - 1 赌马 一名商人邀请你下注。赢了就能赚一笔。 [{"optionText":"下注 100(金)- 稳健:70% 赢 150","requirements":[{"type":"GoldAtLeast","param":{"Count":100}}],"costEffects":[{"type":"AddGold","param":{"Count":-100}}],"rewardEffects":[{"type":"AddGold","param":{"Count":150}}],"probability":0.7},{"optionText":"下注 100(金)- 激进:30% 赢 250","requirements":[{"type":"GoldAtLeast","param":{"Count":100}}],"costEffects":[{"type":"AddGold","param":{"Count":-100}}],"rewardEffects":[{"type":"AddGold","param":{"Count":250}}],"probability":0.3}] - 2 工匠的熔炉 工匠以金币交换防御塔组件。 [{"optionText":"交出 3 个白色组件,获得 50 金币","requirements":[{"type":"CompCountAtLeast","param":{"Count":3,"Rarity":"White"}}],"costEffects":[{"type":"RemoveRandomComps","param":{"Count":3,"Rarity":"White"}}],"rewardEffects":[{"type":"AddGold","param":{"Count":50}}]},{"optionText":"交出 2 个绿色组件,获得 70 金币","requirements":[{"type":"CompCountAtLeast","param":{"Count":2,"Rarity":"Green"}}],"costEffects":[{"type":"RemoveRandomComps","param":{"Count":2,"Rarity":"Green"}}],"rewardEffects":[{"type":"AddGold","param":{"Count":70}}]},{"optionText":"交出 1 个蓝色组件,获得 80 金币","requirements":[{"type":"CompCountAtLeast","param":{"Count":1,"Rarity":"Blue"}}],"costEffects":[{"type":"RemoveRandomComps","param":{"Count":1,"Rarity":"Blue"}}],"rewardEffects":[{"type":"AddGold","param":{"Count":80}}]},{"optionText":"拒绝","rewardEffects":[]}] - 3 代价与回报 某种黑暗力量向你索取代价。 [{"optionText":"展示你的防御塔","requirements":[{"type":"TowerCountAtLeast","param":{"Count":2}}],"rewardEffects":[{"type":"AddGold","param":{"Count":50}}]},{"optionText":"离开","rewardEffects":[]}] + 1 赌马 一名商人邀请你下注。赢了就能赚一笔。 [{\"optionText\":\"下注 100(金)- 稳健:70% 赢 150\",\"requirements\":[{\"type\":\"GoldAtLeast\",\"param\":{\"Count\":100}}],\"costEffects\":[{\"type\":\"AddGold\",\"param\":{\"Count\":-100}}],\"rewardEffects\":[{\"type\":\"AddGold\",\"param\":{\"Count\":150}}],\"probability\":0.7},{\"optionText\":\"下注 100(金)- 激进:30% 赢 250\",\"requirements\":[{\"type\":\"GoldAtLeast\",\"param\":{\"Count\":100}}],\"costEffects\":[{\"type\":\"AddGold\",\"param\":{\"Count\":-100}}],\"rewardEffects\":[{\"type\":\"AddGold\",\"param\":{\"Count\":250}}],\"probability\":0.3}] + 2 工匠的熔炉 工匠以金币交换防御塔组件。 [{\"optionText\":\"交出 3 个白色组件,获得 50 金币\",\"requirements\":[{\"type\":\"CompCountAtLeast\",\"param\":{\"Count\":3,\"Rarity\":\"White\"}}],\"costEffects\":[{\"type\":\"RemoveRandomComps\",\"param\":{\"Count\":3,\"Rarity\":\"White\"}}],\"rewardEffects\":[{\"type\":\"AddGold\",\"param\":{\"Count\":50}}]},{\"optionText\":\"交出 2 个绿色组件,获得 70 金币\",\"requirements\":[{\"type\":\"CompCountAtLeast\",\"param\":{\"Count\":2,\"Rarity\":\"Green\"}}],\"costEffects\":[{\"type\":\"RemoveRandomComps\",\"param\":{\"Count\":2,\"Rarity\":\"Green\"}}],\"rewardEffects\":[{\"type\":\"AddGold\",\"param\":{\"Count\":70}}]},{\"optionText\":\"交出 1 个蓝色组件,获得 80 金币\",\"requirements\":[{\"type\":\"CompCountAtLeast\",\"param\":{\"Count\":1,\"Rarity\":\"Blue\"}}],\"costEffects\":[{\"type\":\"RemoveRandomComps\",\"param\":{\"Count\":1,\"Rarity\":\"Blue\"}}],\"rewardEffects\":[{\"type\":\"AddGold\",\"param\":{\"Count\":80}}]},{\"optionText\":\"拒绝\",\"rewardEffects\":[]}] + 3 代价与回报 某种黑暗力量向你索取代价。 [{\"optionText\":\"展示你的防御塔\",\"requirements\":[{\"type\":\"TowerCountAtLeast\",\"param\":{\"Count\":2}}],\"rewardEffects\":[{\"type\":\"AddGold\",\"param\":{\"Count\":50}}]},{\"optionText\":\"离开\",\"rewardEffects\":[]}] diff --git a/Assets/GameMain/DataTables/Tag.txt b/Assets/GameMain/DataTables/Tag.txt index 5572a8f..aadd9a7 100644 --- a/Assets/GameMain/DataTables/Tag.txt +++ b/Assets/GameMain/DataTables/Tag.txt @@ -1,15 +1,15 @@ -# Id 列1 Name MinRarity Weight -# int string RarityType int -# Tag编号 策划备注 Tag名 获取最低稀有度 权重 - 1 元素 Fire White 20 - 2 元素 BurnSpread White 20 - 3 元素 IgniteBurst Green 15 - 4 元素 Inferno Purple 5 - 5 控制 Ice White 1 - 6 控制 FreezeMask White 20 - 7 控制 Shatter Green 15 - 8 控制 AbsoluteZero Purple 1 - 9 穿透 Pierce White 20 - 10 穿透 Crit White 20 - 11 穿透 Overpenetrate Green 15 - 12 穿透 Execution Purple 5 +# Id 列1 Name TagGroup MinRarity Weight IsImplemented +# int string string RarityType int bool +# Tag编号 策划备注 Tag名 Tag所属 获取最低稀有度 权重 是否启用 + 1 元素 Fire Element White 20 True + 2 元素 BurnSpread Element White 20 False + 3 元素 IgniteBurst Element Green 15 False + 4 元素 Inferno Element Purple 5 True + 5 控制 Ice Control White 1 True + 6 控制 FreezeMask Control White 20 False + 7 控制 Shatter Control Green 15 True + 8 控制 AbsoluteZero Control Purple 1 True + 9 穿透 Pierce Penetrate White 20 False + 10 穿透 Crit Penetrate White 20 True + 11 穿透 Overpenetrate Penetrate Green 15 False + 12 穿透 Execution Penetrate Purple 5 True diff --git a/Assets/GameMain/DataTables/TagConfig.txt b/Assets/GameMain/DataTables/TagConfig.txt index 6f6160a..7defe4f 100644 --- a/Assets/GameMain/DataTables/TagConfig.txt +++ b/Assets/GameMain/DataTables/TagConfig.txt @@ -1,15 +1,15 @@ # Id 列1 TagType TriggerPhase Description Param # int TagType TagTriggerPhase string string # Tag配置编号 策划备注 所属Tag类型 触发阶段 描述 参数Json - 1 元素 Fire OnAfterHit 持续对敌人造成火伤害 {"BurnDurationSeconds":3,"BurnDamagePerSecondPerStack":20,"MaxEffectiveStack":5} - 2 元素 BurnSpread None 燃烧向邻近敌人传播 {"SpreadRadius":2,"SpreadDamageRate":1} - 3 元素 IgniteBurst None 燃烧结束或击杀时爆炸 {"BurstRadius":1,"BurstDamageRate":0.5} - 4 元素 Inferno OnAfterHit 强化燃烧伤害或持续时间 {"BonusBurnDurationSeconds":0.1,"BonusBurnDamagePerSecondPerStack":0.1} - 5 控制 Ice OnAfterHit 命中附加减速 {"SlowDurationSeconds":2,"SlowRatioPerStack":0.2,"MinMoveSpeedMultiplier":0.4} - 6 控制 FreezeMask None 冻结积累条 / 冻结面具机制 {"FreezeBuildUpPerStack":0.1} - 7 控制 Shatter OnBeforeHit 对已减速 / 已冻结目标增伤 {"RequiresSlowedTarget":true,"DamageBonusPerStack":0.1} - 8 控制 AbsoluteZero OnAfterHit 强化减速,或提高冻结触发速度 {"BonusSlowDurationSeconds":0.1,"BonusSlowRatioPerStack":0.2} - 9 穿透 Pierce None 子弹贯穿多个目标 {"ExtraPierceCount":2} - 10 穿透 Crit OnBeforeHit 命中前按概率暴击 {"CritChancePerStack":0.1,"CritDamageMultiplier":1.5} - 11 穿透 Overpenetrate None 贯穿后保留部分伤害继续飞行 {"ExtraPenetrationCount":0.1,"RemainingDamageRate":0.2} - 12 穿透 Execution OnBeforeHit 对低血量目标增伤或直接处决 {"TargetHealthThreshold":0.3,"DamageBonusPerStack":0.5} + 1 元素 Fire OnAfterHit 持续对敌人造成火伤害 {\"BurnDurationSeconds\":3,\"BurnDamagePerSecondPerStack\":20,\"MaxEffectiveStack\":5} + 2 元素 BurnSpread None 燃烧向邻近敌人传播 {\"SpreadRadius\":2,\"SpreadDamageRate\":1} + 3 元素 IgniteBurst None 燃烧结束或击杀时爆炸 {\"BurstRadius\":1,\"BurstDamageRate\":0.5} + 4 元素 Inferno OnAfterHit 强化燃烧伤害或持续时间 {\"BonusBurnDurationSeconds\":0.1,\"BonusBurnDamagePerSecondPerStack\":0.1} + 5 控制 Ice OnAfterHit 命中附加减速 {\"SlowDurationSeconds\":2,\"SlowRatioPerStack\":0.2,\"MinMoveSpeedMultiplier\":0.4} + 6 控制 FreezeMask None 冻结积累条 / 冻结面具机制 {\"FreezeBuildUpPerStack\":0.1} + 7 控制 Shatter OnBeforeHit 对已减速 / 已冻结目标增伤 {\"RequiresSlowedTarget\":true,\"DamageBonusPerStack\":0.1} + 8 控制 AbsoluteZero OnAfterHit 强化减速,或提高冻结触发速度 {\"BonusSlowDurationSeconds\":0.1,\"BonusSlowRatioPerStack\":0.2} + 9 穿透 Pierce None 子弹贯穿多个目标 {\"ExtraPierceCount\":2} + 10 穿透 Crit OnBeforeHit 命中前按概率暴击 {\"CritChancePerStack\":0.1,\"CritDamageMultiplier\":1.5} + 11 穿透 Overpenetrate None 贯穿后保留部分伤害继续飞行 {\"ExtraPenetrationCount\":0.1,\"RemainingDamageRate\":0.2} + 12 穿透 Execution OnBeforeHit 对低血量目标增伤或直接处决 {\"TargetHealthThreshold\":0.3,\"DamageBonusPerStack\":0.5} diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResolver.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResolver.cs index c79736d..d9ab49e 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResolver.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResolver.cs @@ -355,7 +355,7 @@ namespace GeometryTD.CustomComponent Rarity = rarity, Endurance = 100f, Constraint = config.Constraint, - Tags = InventoryTagRuleService.ResolveComponentTags( + Tags = ComponentTagGenerationService.ResolveComponentTags( config.PossibleTag, rarity, InventoryTagSourceType.Drop, @@ -393,7 +393,7 @@ namespace GeometryTD.CustomComponent Rarity = rarity, Endurance = 100f, Constraint = config.Constraint, - Tags = InventoryTagRuleService.ResolveComponentTags( + Tags = ComponentTagGenerationService.ResolveComponentTags( config.PossibleTag, rarity, InventoryTagSourceType.Drop, @@ -430,7 +430,7 @@ namespace GeometryTD.CustomComponent Rarity = rarity, Endurance = 100f, Constraint = config.Constraint, - Tags = InventoryTagRuleService.ResolveComponentTags( + Tags = ComponentTagGenerationService.ResolveComponentTags( config.PossibleTag, rarity, InventoryTagSourceType.Drop, diff --git a/Assets/GameMain/Scripts/DataTable/DRTag.cs b/Assets/GameMain/Scripts/DataTable/DRTag.cs index 644bb6f..c063794 100644 --- a/Assets/GameMain/Scripts/DataTable/DRTag.cs +++ b/Assets/GameMain/Scripts/DataTable/DRTag.cs @@ -24,10 +24,14 @@ namespace GeometryTD.DataTable public TagType TagType => (TagType)m_Id; + public string TagGroupText { get; private set; } + public RarityType MinRarity { get; private set; } public int Weight { get; private set; } + public bool IsImplemented { get; private set; } + public override bool ParseDataRow(string dataRowString, object userData) { string[] columnStrings = dataRowString.Split(DataTableExtension.DataSplitSeparators); @@ -41,8 +45,22 @@ namespace GeometryTD.DataTable m_Id = int.Parse(columnStrings[index++]); index++; Name = columnStrings[index++]; - MinRarity = EnumUtility.Get(columnStrings[index++]); - Weight = int.Parse(columnStrings[index++]); + + bool hasExtendedColumns = columnStrings.Length - index >= 4; + if (hasExtendedColumns) + { + TagGroupText = columnStrings[index++]; + MinRarity = EnumUtility.Get(columnStrings[index++]); + Weight = int.Parse(columnStrings[index++]); + IsImplemented = bool.Parse(columnStrings[index++]); + } + else + { + TagGroupText = string.Empty; + MinRarity = EnumUtility.Get(columnStrings[index++]); + Weight = int.Parse(columnStrings[index++]); + IsImplemented = true; + } return true; } diff --git a/Assets/GameMain/Scripts/Definition/Enum/TagCategory.cs b/Assets/GameMain/Scripts/Definition/Enum/TagCategory.cs index d302e16..2cf6a22 100644 --- a/Assets/GameMain/Scripts/Definition/Enum/TagCategory.cs +++ b/Assets/GameMain/Scripts/Definition/Enum/TagCategory.cs @@ -5,6 +5,8 @@ namespace GeometryTD.Definition None = 0, Status = 1, NumericModifier = 2, - AttackShape = 3 + AttackShape = 3, + // Enhances another applied status on the same hit, but does not create its own enemy-held state. + StatusModifier = 4 } } diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagStates.meta b/Assets/GameMain/Scripts/Definition/Tag/Aggregation.meta similarity index 77% rename from Assets/GameMain/Scripts/Definition/Tag/TagStates.meta rename to Assets/GameMain/Scripts/Definition/Tag/Aggregation.meta index b333dc8..dbbed06 100644 --- a/Assets/GameMain/Scripts/Definition/Tag/TagStates.meta +++ b/Assets/GameMain/Scripts/Definition/Tag/Aggregation.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 0f2ab8a7e488575498ac933a125360d1 +guid: 1c2505f2ce4cfd7499cdd3bc8c0e22eb folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/GameMain/Scripts/Definition/DataStruct/TagRuntimeData.cs b/Assets/GameMain/Scripts/Definition/Tag/Aggregation/TagRuntimeData.cs similarity index 100% rename from Assets/GameMain/Scripts/Definition/DataStruct/TagRuntimeData.cs rename to Assets/GameMain/Scripts/Definition/Tag/Aggregation/TagRuntimeData.cs diff --git a/Assets/GameMain/Scripts/Definition/DataStruct/TagRuntimeData.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Aggregation/TagRuntimeData.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/DataStruct/TagRuntimeData.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Aggregation/TagRuntimeData.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/TowerTagAggregationService.cs b/Assets/GameMain/Scripts/Definition/Tag/Aggregation/TowerTagAggregationService.cs similarity index 100% rename from Assets/GameMain/Scripts/Definition/TowerTagAggregationService.cs rename to Assets/GameMain/Scripts/Definition/Tag/Aggregation/TowerTagAggregationService.cs diff --git a/Assets/GameMain/Scripts/Definition/TowerTagAggregationService.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Aggregation/TowerTagAggregationService.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/TowerTagAggregationService.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Aggregation/TowerTagAggregationService.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/Combat.meta b/Assets/GameMain/Scripts/Definition/Tag/Combat.meta new file mode 100644 index 0000000..74af943 --- /dev/null +++ b/Assets/GameMain/Scripts/Definition/Tag/Combat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: eae63f0557814c14a9a2b9e6c8726404 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagRegistry.cs b/Assets/GameMain/Scripts/Definition/Tag/Combat/EnemyStatusTagRegistry.cs similarity index 79% rename from Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagRegistry.cs rename to Assets/GameMain/Scripts/Definition/Tag/Combat/EnemyStatusTagRegistry.cs index db2b069..2388d54 100644 --- a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagRegistry.cs +++ b/Assets/GameMain/Scripts/Definition/Tag/Combat/EnemyStatusTagRegistry.cs @@ -7,13 +7,12 @@ namespace GeometryTD.Definition { public static class EnemyStatusTagRegistry { + // Only tags that create or tick enemy-held status state belong here. private static readonly Dictionary EffectsByTag = new Dictionary { [TagType.Fire] = new FireTagEffect(), - [TagType.Inferno] = new InfernoTagEffect(), - [TagType.Ice] = new IceTagEffect(), - [TagType.AbsoluteZero] = new AbsoluteZeroTagEffect() + [TagType.Ice] = new IceTagEffect() }; public static IReadOnlyDictionary Effects => EffectsByTag; @@ -23,4 +22,4 @@ namespace GeometryTD.Definition return EffectsByTag.TryGetValue(tagType, out effect); } } -} \ No newline at end of file +} diff --git a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagRegistry.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Combat/EnemyStatusTagRegistry.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagRegistry.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Combat/EnemyStatusTagRegistry.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/Combat/Handlers.meta b/Assets/GameMain/Scripts/Definition/Tag/Combat/Handlers.meta new file mode 100644 index 0000000..40c495c --- /dev/null +++ b/Assets/GameMain/Scripts/Definition/Tag/Combat/Handlers.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: df89bbfead1892c469024466c479bef1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagEffectHandler/AttackShapeTagEffectHandler.cs b/Assets/GameMain/Scripts/Definition/Tag/Combat/Handlers/AttackShapeTagEffectHandler.cs similarity index 92% rename from Assets/GameMain/Scripts/Definition/Tag/TagEffectHandler/AttackShapeTagEffectHandler.cs rename to Assets/GameMain/Scripts/Definition/Tag/Combat/Handlers/AttackShapeTagEffectHandler.cs index ca9f24e..3876229 100644 --- a/Assets/GameMain/Scripts/Definition/Tag/TagEffectHandler/AttackShapeTagEffectHandler.cs +++ b/Assets/GameMain/Scripts/Definition/Tag/Combat/Handlers/AttackShapeTagEffectHandler.cs @@ -17,7 +17,7 @@ namespace GeometryTD.Definition continue; } - if (!TagConfigRegistry.TryGetDefinition(runtime.TagType, out TagDefinitionData definition) || + if (!TagDefinitionRegistry.TryGetDefinition(runtime.TagType, out TagDefinition definition) || definition == null || definition.Category != TagCategory.AttackShape || definition.TriggerPhase != triggerPhase || diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagEffectHandler/AttackShapeTagEffectHandler.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Combat/Handlers/AttackShapeTagEffectHandler.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagEffectHandler/AttackShapeTagEffectHandler.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Combat/Handlers/AttackShapeTagEffectHandler.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagEffectHandler/NumericTagEffectHandler.cs b/Assets/GameMain/Scripts/Definition/Tag/Combat/Handlers/NumericTagEffectHandler.cs similarity index 97% rename from Assets/GameMain/Scripts/Definition/Tag/TagEffectHandler/NumericTagEffectHandler.cs rename to Assets/GameMain/Scripts/Definition/Tag/Combat/Handlers/NumericTagEffectHandler.cs index b0ba82d..27067ab 100644 --- a/Assets/GameMain/Scripts/Definition/Tag/TagEffectHandler/NumericTagEffectHandler.cs +++ b/Assets/GameMain/Scripts/Definition/Tag/Combat/Handlers/NumericTagEffectHandler.cs @@ -30,7 +30,7 @@ namespace GeometryTD.Definition continue; } - if (!TagConfigRegistry.TryGetDefinition(runtime.TagType, out TagDefinitionData definition) || + if (!TagDefinitionRegistry.TryGetDefinition(runtime.TagType, out TagDefinition definition) || definition == null || definition.Category != TagCategory.NumericModifier || definition.TriggerPhase != TagTriggerPhase.OnBeforeHit || diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagEffectHandler/NumericTagEffectHandler.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Combat/Handlers/NumericTagEffectHandler.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagEffectHandler/NumericTagEffectHandler.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Combat/Handlers/NumericTagEffectHandler.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/Combat/States.meta b/Assets/GameMain/Scripts/Definition/Tag/Combat/States.meta new file mode 100644 index 0000000..31c63dd --- /dev/null +++ b/Assets/GameMain/Scripts/Definition/Tag/Combat/States.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: efece7a307e9a2c44b7247921e8b3194 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagStates/EnemyStatusTagStateBase.cs b/Assets/GameMain/Scripts/Definition/Tag/Combat/States/EnemyStatusTagStateBase.cs similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagStates/EnemyStatusTagStateBase.cs rename to Assets/GameMain/Scripts/Definition/Tag/Combat/States/EnemyStatusTagStateBase.cs diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagStates/EnemyStatusTagStateBase.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Combat/States/EnemyStatusTagStateBase.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagStates/EnemyStatusTagStateBase.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Combat/States/EnemyStatusTagStateBase.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagStates/FireTagState.cs b/Assets/GameMain/Scripts/Definition/Tag/Combat/States/FireTagState.cs similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagStates/FireTagState.cs rename to Assets/GameMain/Scripts/Definition/Tag/Combat/States/FireTagState.cs diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagStates/FireTagState.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Combat/States/FireTagState.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagStates/FireTagState.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Combat/States/FireTagState.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagStates/IceTagState.cs b/Assets/GameMain/Scripts/Definition/Tag/Combat/States/IceTagState.cs similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagStates/IceTagState.cs rename to Assets/GameMain/Scripts/Definition/Tag/Combat/States/IceTagState.cs diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagStates/IceTagState.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Combat/States/IceTagState.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagStates/IceTagState.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Combat/States/IceTagState.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/Combat/StatusEffects.meta b/Assets/GameMain/Scripts/Definition/Tag/Combat/StatusEffects.meta new file mode 100644 index 0000000..c7f1d5d --- /dev/null +++ b/Assets/GameMain/Scripts/Definition/Tag/Combat/StatusEffects.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 343c21d630e34fc47a132c7d94f72bec +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/EnemyStatusTagEffectBase.cs b/Assets/GameMain/Scripts/Definition/Tag/Combat/StatusEffects/EnemyStatusTagEffectBase.cs similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/EnemyStatusTagEffectBase.cs rename to Assets/GameMain/Scripts/Definition/Tag/Combat/StatusEffects/EnemyStatusTagEffectBase.cs diff --git a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/EnemyStatusTagEffectBase.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Combat/StatusEffects/EnemyStatusTagEffectBase.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/EnemyStatusTagEffectBase.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Combat/StatusEffects/EnemyStatusTagEffectBase.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/FireTagEffect.cs b/Assets/GameMain/Scripts/Definition/Tag/Combat/StatusEffects/FireTagEffect.cs similarity index 91% rename from Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/FireTagEffect.cs rename to Assets/GameMain/Scripts/Definition/Tag/Combat/StatusEffects/FireTagEffect.cs index b93f9b9..a13a819 100644 --- a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/FireTagEffect.cs +++ b/Assets/GameMain/Scripts/Definition/Tag/Combat/StatusEffects/FireTagEffect.cs @@ -11,7 +11,7 @@ namespace GeometryTD.Definition public override void Apply(AttackPayload attackPayload, EnemyTagStatusRuntime runtime, TagRuntimeData runtimeData) { - Debug.Assert(TagConfigRegistry.TryGetDefinition(TagType, out TagDefinitionData definition)); + Debug.Assert(TagDefinitionRegistry.TryGetDefinition(TagType, out TagDefinition definition)); FireTagConfig config = definition.Config as FireTagConfig; Debug.Assert(config != null); @@ -72,7 +72,7 @@ namespace GeometryTD.Definition private static float GetInfernoBonusDuration(int infernoStack) { if (infernoStack <= 0 || - !TagConfigRegistry.TryGetDefinition(TagType.Inferno, out TagDefinitionData definition)) + !TagDefinitionRegistry.TryGetDefinition(TagType.Inferno, out TagDefinition definition)) { return 0f; } @@ -89,7 +89,7 @@ namespace GeometryTD.Definition private static float GetInfernoBonusDamagePerSecond(int infernoStack) { if (infernoStack <= 0 || - !TagConfigRegistry.TryGetDefinition(TagType.Inferno, out TagDefinitionData definition)) + !TagDefinitionRegistry.TryGetDefinition(TagType.Inferno, out TagDefinition definition)) { return 0f; } diff --git a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/FireTagEffect.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Combat/StatusEffects/FireTagEffect.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/FireTagEffect.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Combat/StatusEffects/FireTagEffect.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/IEnemyStatusTagEffect.cs b/Assets/GameMain/Scripts/Definition/Tag/Combat/StatusEffects/IEnemyStatusTagEffect.cs similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/IEnemyStatusTagEffect.cs rename to Assets/GameMain/Scripts/Definition/Tag/Combat/StatusEffects/IEnemyStatusTagEffect.cs diff --git a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/IEnemyStatusTagEffect.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Combat/StatusEffects/IEnemyStatusTagEffect.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/IEnemyStatusTagEffect.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Combat/StatusEffects/IEnemyStatusTagEffect.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/IceTagEffect.cs b/Assets/GameMain/Scripts/Definition/Tag/Combat/StatusEffects/IceTagEffect.cs similarity index 90% rename from Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/IceTagEffect.cs rename to Assets/GameMain/Scripts/Definition/Tag/Combat/StatusEffects/IceTagEffect.cs index 3cada12..c731930 100644 --- a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/IceTagEffect.cs +++ b/Assets/GameMain/Scripts/Definition/Tag/Combat/StatusEffects/IceTagEffect.cs @@ -14,7 +14,7 @@ namespace GeometryTD.Definition _ = attackPayload; Debug.Assert(runtimeData != null); Debug.Assert(runtimeData.TotalStack > 0); - Debug.Assert(TagConfigRegistry.TryGetDefinition(TagType, out TagDefinitionData definition)); + Debug.Assert(TagDefinitionRegistry.TryGetDefinition(TagType, out TagDefinition definition)); IceTagConfig config = definition.Config as IceTagConfig; Debug.Assert(config != null); @@ -53,7 +53,7 @@ namespace GeometryTD.Definition private static float GetAbsoluteZeroBonusDuration(int absoluteZeroStack) { if (absoluteZeroStack <= 0 || - !TagConfigRegistry.TryGetDefinition(TagType.AbsoluteZero, out TagDefinitionData definition)) + !TagDefinitionRegistry.TryGetDefinition(TagType.AbsoluteZero, out TagDefinition definition)) { return 0f; } @@ -70,7 +70,7 @@ namespace GeometryTD.Definition private static float GetAbsoluteZeroBonusSlowRatio(int absoluteZeroStack) { if (absoluteZeroStack <= 0 || - !TagConfigRegistry.TryGetDefinition(TagType.AbsoluteZero, out TagDefinitionData definition)) + !TagDefinitionRegistry.TryGetDefinition(TagType.AbsoluteZero, out TagDefinition definition)) { return 0f; } diff --git a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/IceTagEffect.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Combat/StatusEffects/IceTagEffect.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/IceTagEffect.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Combat/StatusEffects/IceTagEffect.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagEffectResolver.cs b/Assets/GameMain/Scripts/Definition/Tag/Combat/TagEffectResolver.cs similarity index 96% rename from Assets/GameMain/Scripts/Definition/Tag/TagEffectResolver.cs rename to Assets/GameMain/Scripts/Definition/Tag/Combat/TagEffectResolver.cs index 417ec7d..2efaa4f 100644 --- a/Assets/GameMain/Scripts/Definition/Tag/TagEffectResolver.cs +++ b/Assets/GameMain/Scripts/Definition/Tag/Combat/TagEffectResolver.cs @@ -45,7 +45,7 @@ namespace GeometryTD.Definition continue; } - if (!TagConfigRegistry.TryGetDefinition(tag.TagType, out TagDefinitionData definition) || + if (!TagDefinitionRegistry.TryGetDefinition(tag.TagType, out TagDefinition definition) || definition == null || definition.Category != TagCategory.Status || definition.TriggerPhase != TagTriggerPhase.OnAfterHit || diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagEffectResolver.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Combat/TagEffectResolver.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagEffectResolver.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Combat/TagEffectResolver.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect.meta b/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect.meta deleted file mode 100644 index 20bbd72..0000000 --- a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 1909b51822cc4368bc604674fd119123 -timeCreated: 1773105715 \ No newline at end of file diff --git a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/AbsoluteZeroTagEffect.cs b/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/AbsoluteZeroTagEffect.cs deleted file mode 100644 index 2a63242..0000000 --- a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/AbsoluteZeroTagEffect.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Collections.Generic; - -namespace GeometryTD.Definition -{ - public sealed class AbsoluteZeroTagEffect : EnemyStatusTagEffectBase - { - public override TagType TagType => TagType.AbsoluteZero; - } -} \ No newline at end of file diff --git a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/AbsoluteZeroTagEffect.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/AbsoluteZeroTagEffect.cs.meta deleted file mode 100644 index fdcc37c..0000000 --- a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/AbsoluteZeroTagEffect.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: deecaa9a38c04725b5abeb5488cbe53f -timeCreated: 1773106137 \ No newline at end of file diff --git a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/InfernoTagEffect.cs b/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/InfernoTagEffect.cs deleted file mode 100644 index a4843d4..0000000 --- a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/InfernoTagEffect.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace GeometryTD.Definition -{ - public sealed class InfernoTagEffect : EnemyStatusTagEffectBase - { - public override TagType TagType => TagType.Inferno; - } -} \ No newline at end of file diff --git a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/InfernoTagEffect.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/InfernoTagEffect.cs.meta deleted file mode 100644 index d7a4bf9..0000000 --- a/Assets/GameMain/Scripts/Definition/Tag/EnemyStatusTagEffect/InfernoTagEffect.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 2aa813ec42ea4dddb717ff28da764f15 -timeCreated: 1773106082 \ No newline at end of file diff --git a/Assets/GameMain/Scripts/Definition/Tag/Generation.meta b/Assets/GameMain/Scripts/Definition/Tag/Generation.meta new file mode 100644 index 0000000..d5e13f8 --- /dev/null +++ b/Assets/GameMain/Scripts/Definition/Tag/Generation.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 44a85dd6308e175428074070c55e1020 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/Definition/InventoryTagRuleService.cs b/Assets/GameMain/Scripts/Definition/Tag/Generation/ComponentTagGenerationService.cs similarity index 77% rename from Assets/GameMain/Scripts/Definition/InventoryTagRuleService.cs rename to Assets/GameMain/Scripts/Definition/Tag/Generation/ComponentTagGenerationService.cs index 95843d2..5ad7df0 100644 --- a/Assets/GameMain/Scripts/Definition/InventoryTagRuleService.cs +++ b/Assets/GameMain/Scripts/Definition/Tag/Generation/ComponentTagGenerationService.cs @@ -5,7 +5,7 @@ using Random = System.Random; namespace GeometryTD.Definition { - public static class InventoryTagRuleService + public static class ComponentTagGenerationService { public static TagType[] ResolveComponentTags( IReadOnlyList possibleTags, @@ -13,10 +13,10 @@ namespace GeometryTD.Definition InventoryTagSourceType sourceType, long itemInstanceId, int configId, - IReadOnlyDictionary rulesByTag = null, - IReadOnlyDictionary rarityTagBudgetRulesByRarity = null) + IReadOnlyDictionary rulesByTag = null, + IReadOnlyDictionary rarityTagBudgetRulesByRarity = null) { - IReadOnlyDictionary ruleLookup = rulesByTag ?? TagGenerationRuleRegistry.Rules; + IReadOnlyDictionary ruleLookup = rulesByTag ?? TagGenerationRuleRegistry.Rules; TagType[] eligibleTags = GetEligibleTags(possibleTags, rarity, ruleLookup); if (eligibleTags.Length <= 0) { @@ -46,7 +46,7 @@ namespace GeometryTD.Definition public static TagType[] GetEligibleTags( IReadOnlyList possibleTags, RarityType rarity, - IReadOnlyDictionary rulesByTag = null) + IReadOnlyDictionary rulesByTag = null) { if (possibleTags == null || possibleTags.Count <= 0) { @@ -54,7 +54,7 @@ namespace GeometryTD.Definition } RarityType normalizedRarity = InventoryRarityRuleService.NormalizeComponentRarity(rarity); - IReadOnlyDictionary ruleLookup = rulesByTag ?? TagGenerationRuleRegistry.Rules; + IReadOnlyDictionary ruleLookup = rulesByTag ?? TagGenerationRuleRegistry.Rules; HashSet uniqueTags = new HashSet(); for (int i = 0; i < possibleTags.Count; i++) @@ -65,7 +65,7 @@ namespace GeometryTD.Definition continue; } - if (!TryGetRule(tagType, ruleLookup, out TagGenerationRuleData rule)) + if (!TryGetRule(tagType, ruleLookup, out TagGenerationRule rule)) { continue; } @@ -92,11 +92,11 @@ namespace GeometryTD.Definition public static int ResolveRarityTagBudget( RarityType rarity, Random random, - IReadOnlyDictionary rarityTagBudgetRulesByRarity = null) + IReadOnlyDictionary rarityTagBudgetRulesByRarity = null) { RarityType normalizedRarity = InventoryRarityRuleService.NormalizeComponentRarity(rarity); - IReadOnlyDictionary ruleLookup = rarityTagBudgetRulesByRarity ?? RarityTagBudgetRuleRegistry.Rules; - RarityTagBudgetRuleData rule = GetRarityTagBudgetRule(normalizedRarity, ruleLookup); + IReadOnlyDictionary ruleLookup = rarityTagBudgetRulesByRarity ?? RarityTagBudgetRuleRegistry.Rules; + RarityTagBudgetRule rule = GetRarityTagBudgetRule(normalizedRarity, ruleLookup); Debug.Assert(rule.MinCount >= 0); Debug.Assert(rule.MaxCount >= rule.MinCount); @@ -112,15 +112,15 @@ namespace GeometryTD.Definition private static bool IsSupportedLaunchTag(TagType tagType) { - return TagConfigRegistry.TryGetDefinition(tagType, out TagDefinitionData definition) && + return TagDefinitionRegistry.TryGetDefinition(tagType, out TagDefinition definition) && definition.Config != null && definition.Config.IsImplemented; } private static bool TryGetRule( TagType tagType, - IReadOnlyDictionary ruleLookup, - out TagGenerationRuleData rule) + IReadOnlyDictionary ruleLookup, + out TagGenerationRule rule) { if (ruleLookup != null && ruleLookup.TryGetValue(tagType, out rule)) { @@ -131,9 +131,9 @@ namespace GeometryTD.Definition return false; } - private static RarityTagBudgetRuleData GetRarityTagBudgetRule( + private static RarityTagBudgetRule GetRarityTagBudgetRule( RarityType rarity, - IReadOnlyDictionary ruleLookup) + IReadOnlyDictionary ruleLookup) { Debug.Assert(ruleLookup != null); Debug.Assert(ruleLookup.TryGetValue(rarity, out _)); @@ -142,13 +142,13 @@ namespace GeometryTD.Definition private static int RollWeightedIndex( IReadOnlyList pool, - IReadOnlyDictionary ruleLookup, + IReadOnlyDictionary ruleLookup, Random random) { int totalWeight = 0; for (int i = 0; i < pool.Count; i++) { - TagGenerationRuleData rule = ruleLookup[pool[i]]; + TagGenerationRule rule = ruleLookup[pool[i]]; Debug.Assert(rule.Weight > 0); totalWeight += rule.Weight; } @@ -159,7 +159,7 @@ namespace GeometryTD.Definition int cumulative = 0; for (int i = 0; i < pool.Count; i++) { - TagGenerationRuleData rule = ruleLookup[pool[i]]; + TagGenerationRule rule = ruleLookup[pool[i]]; cumulative += rule.Weight; if (roll <= cumulative) { diff --git a/Assets/GameMain/Scripts/Definition/InventoryTagRuleService.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Generation/ComponentTagGenerationService.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/InventoryTagRuleService.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Generation/ComponentTagGenerationService.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/RarityTagBudgetRuleData.cs b/Assets/GameMain/Scripts/Definition/Tag/Generation/RarityTagBudgetRule.cs similarity index 78% rename from Assets/GameMain/Scripts/Definition/RarityTagBudgetRuleData.cs rename to Assets/GameMain/Scripts/Definition/Tag/Generation/RarityTagBudgetRule.cs index 8ab8027..60ac68c 100644 --- a/Assets/GameMain/Scripts/Definition/RarityTagBudgetRuleData.cs +++ b/Assets/GameMain/Scripts/Definition/Tag/Generation/RarityTagBudgetRule.cs @@ -1,6 +1,6 @@ namespace GeometryTD.Definition { - public sealed class RarityTagBudgetRuleData + public sealed class RarityTagBudgetRule { public RarityType Rarity { get; set; } public int MinCount { get; set; } diff --git a/Assets/GameMain/Scripts/Definition/RarityTagBudgetRuleData.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Generation/RarityTagBudgetRule.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/RarityTagBudgetRuleData.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Generation/RarityTagBudgetRule.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/RarityTagBudgetRuleRegistry.cs b/Assets/GameMain/Scripts/Definition/Tag/Generation/RarityTagBudgetRuleRegistry.cs similarity index 86% rename from Assets/GameMain/Scripts/Definition/RarityTagBudgetRuleRegistry.cs rename to Assets/GameMain/Scripts/Definition/Tag/Generation/RarityTagBudgetRuleRegistry.cs index 1f60dd8..194757e 100644 --- a/Assets/GameMain/Scripts/Definition/RarityTagBudgetRuleRegistry.cs +++ b/Assets/GameMain/Scripts/Definition/Tag/Generation/RarityTagBudgetRuleRegistry.cs @@ -6,14 +6,14 @@ namespace GeometryTD.Definition { public static class RarityTagBudgetRuleRegistry { - private static readonly Dictionary RulesByRarity = CreateDefaultRules(); + private static readonly Dictionary RulesByRarity = CreateDefaultRules(); - public static IReadOnlyDictionary Rules => RulesByRarity; + public static IReadOnlyDictionary Rules => RulesByRarity; public static void ResetToDefaults() { RulesByRarity.Clear(); - foreach (KeyValuePair pair in CreateDefaultRules()) + foreach (KeyValuePair pair in CreateDefaultRules()) { RulesByRarity.Add(pair.Key, pair.Value); } @@ -28,14 +28,14 @@ namespace GeometryTD.Definition } } - public static bool TryGetRule(RarityType rarity, out RarityTagBudgetRuleData rule) + public static bool TryGetRule(RarityType rarity, out RarityTagBudgetRule rule) { return RulesByRarity.TryGetValue(rarity, out rule); } - private static Dictionary CreateDefaultRules() + private static Dictionary CreateDefaultRules() { - return new Dictionary + return new Dictionary { [RarityType.White] = CreateRule(RarityType.White, 0, 1), [RarityType.Green] = CreateRule(RarityType.Green, 1, 1), @@ -45,13 +45,13 @@ namespace GeometryTD.Definition }; } - private static RarityTagBudgetRuleData CreateRule(RarityType rarity, int minCount, int maxCount) + private static RarityTagBudgetRule CreateRule(RarityType rarity, int minCount, int maxCount) { Debug.Assert(rarity >= RarityType.White && rarity <= RarityType.Red); Debug.Assert(minCount >= 0); Debug.Assert(maxCount >= minCount); - return new RarityTagBudgetRuleData + return new RarityTagBudgetRule { Rarity = rarity, MinCount = minCount, diff --git a/Assets/GameMain/Scripts/Definition/RarityTagBudgetRuleRegistry.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Generation/RarityTagBudgetRuleRegistry.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/RarityTagBudgetRuleRegistry.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Generation/RarityTagBudgetRuleRegistry.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/TagGenerationRuleData.cs b/Assets/GameMain/Scripts/Definition/Tag/Generation/TagGenerationRule.cs similarity index 79% rename from Assets/GameMain/Scripts/Definition/TagGenerationRuleData.cs rename to Assets/GameMain/Scripts/Definition/Tag/Generation/TagGenerationRule.cs index 3ec22f6..fb5a2bd 100644 --- a/Assets/GameMain/Scripts/Definition/TagGenerationRuleData.cs +++ b/Assets/GameMain/Scripts/Definition/Tag/Generation/TagGenerationRule.cs @@ -1,6 +1,6 @@ namespace GeometryTD.Definition { - public sealed class TagGenerationRuleData + public sealed class TagGenerationRule { public TagType TagType { get; set; } public RarityType MinRarity { get; set; } diff --git a/Assets/GameMain/Scripts/Definition/TagGenerationRuleData.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Generation/TagGenerationRule.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/TagGenerationRuleData.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Generation/TagGenerationRule.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/TagGenerationRuleRegistry.cs b/Assets/GameMain/Scripts/Definition/Tag/Generation/TagGenerationRuleRegistry.cs similarity index 82% rename from Assets/GameMain/Scripts/Definition/TagGenerationRuleRegistry.cs rename to Assets/GameMain/Scripts/Definition/Tag/Generation/TagGenerationRuleRegistry.cs index 5b5d8e3..019aad7 100644 --- a/Assets/GameMain/Scripts/Definition/TagGenerationRuleRegistry.cs +++ b/Assets/GameMain/Scripts/Definition/Tag/Generation/TagGenerationRuleRegistry.cs @@ -6,14 +6,14 @@ namespace GeometryTD.Definition { public static class TagGenerationRuleRegistry { - private static readonly Dictionary RulesByTag = CreateDefaultRules(); + private static readonly Dictionary RulesByTag = CreateDefaultRules(); - public static IReadOnlyDictionary Rules => RulesByTag; + public static IReadOnlyDictionary Rules => RulesByTag; public static void ResetToDefaults() { RulesByTag.Clear(); - foreach (KeyValuePair pair in CreateDefaultRules()) + foreach (KeyValuePair pair in CreateDefaultRules()) { RulesByTag.Add(pair.Key, pair.Value); } @@ -28,14 +28,14 @@ namespace GeometryTD.Definition } } - public static bool TryGetRule(TagType tagType, out TagGenerationRuleData rule) + public static bool TryGetRule(TagType tagType, out TagGenerationRule rule) { return RulesByTag.TryGetValue(tagType, out rule); } - private static Dictionary CreateDefaultRules() + private static Dictionary CreateDefaultRules() { - return new Dictionary + return new Dictionary { [TagType.Fire] = CreateRule(TagType.Fire, RarityType.White, 20), [TagType.BurnSpread] = CreateRule(TagType.BurnSpread, RarityType.White, 20), @@ -52,9 +52,9 @@ namespace GeometryTD.Definition }; } - private static TagGenerationRuleData CreateRule(TagType tagType, RarityType minRarity, int weight) + private static TagGenerationRule CreateRule(TagType tagType, RarityType minRarity, int weight) { - return new TagGenerationRuleData + return new TagGenerationRule { TagType = tagType, MinRarity = minRarity, diff --git a/Assets/GameMain/Scripts/Definition/TagGenerationRuleRegistry.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Generation/TagGenerationRuleRegistry.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/TagGenerationRuleRegistry.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Generation/TagGenerationRuleRegistry.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/Metadata.meta b/Assets/GameMain/Scripts/Definition/Tag/Metadata.meta new file mode 100644 index 0000000..cb7f7ae --- /dev/null +++ b/Assets/GameMain/Scripts/Definition/Tag/Metadata.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e6251ee2cac123b43899d056ed4ad544 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config.meta b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config.meta new file mode 100644 index 0000000..0d7bc78 --- /dev/null +++ b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c6219bd01b665fd4cae6580656c1f127 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/AbsoluteZeroTagConfig.cs b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/AbsoluteZeroTagConfig.cs similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/AbsoluteZeroTagConfig.cs rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/AbsoluteZeroTagConfig.cs diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/AbsoluteZeroTagConfig.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/AbsoluteZeroTagConfig.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/AbsoluteZeroTagConfig.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/AbsoluteZeroTagConfig.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/BurnSpreadTagConfig.cs b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/BurnSpreadTagConfig.cs similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/BurnSpreadTagConfig.cs rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/BurnSpreadTagConfig.cs diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/BurnSpreadTagConfig.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/BurnSpreadTagConfig.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/BurnSpreadTagConfig.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/BurnSpreadTagConfig.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/CritTagConfig.cs b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/CritTagConfig.cs similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/CritTagConfig.cs rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/CritTagConfig.cs diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/CritTagConfig.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/CritTagConfig.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/CritTagConfig.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/CritTagConfig.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/ExecutionTagConfig.cs b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/ExecutionTagConfig.cs similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/ExecutionTagConfig.cs rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/ExecutionTagConfig.cs diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/ExecutionTagConfig.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/ExecutionTagConfig.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/ExecutionTagConfig.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/ExecutionTagConfig.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/FireTagConfig.cs b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/FireTagConfig.cs similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/FireTagConfig.cs rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/FireTagConfig.cs diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/FireTagConfig.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/FireTagConfig.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/FireTagConfig.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/FireTagConfig.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/FreezeMaskTagConfig.cs b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/FreezeMaskTagConfig.cs similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/FreezeMaskTagConfig.cs rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/FreezeMaskTagConfig.cs diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/FreezeMaskTagConfig.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/FreezeMaskTagConfig.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/FreezeMaskTagConfig.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/FreezeMaskTagConfig.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/IceTagConfig.cs b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/IceTagConfig.cs similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/IceTagConfig.cs rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/IceTagConfig.cs diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/IceTagConfig.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/IceTagConfig.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/IceTagConfig.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/IceTagConfig.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/IgniteBurstTagConfig.cs b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/IgniteBurstTagConfig.cs similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/IgniteBurstTagConfig.cs rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/IgniteBurstTagConfig.cs diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/IgniteBurstTagConfig.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/IgniteBurstTagConfig.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/IgniteBurstTagConfig.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/IgniteBurstTagConfig.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/InfernoTagConfig.cs b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/InfernoTagConfig.cs similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/InfernoTagConfig.cs rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/InfernoTagConfig.cs diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/InfernoTagConfig.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/InfernoTagConfig.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/InfernoTagConfig.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/InfernoTagConfig.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/OverpenetrateTagConfig.cs b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/OverpenetrateTagConfig.cs similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/OverpenetrateTagConfig.cs rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/OverpenetrateTagConfig.cs diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/OverpenetrateTagConfig.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/OverpenetrateTagConfig.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/OverpenetrateTagConfig.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/OverpenetrateTagConfig.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/PierceTagConfig.cs b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/PierceTagConfig.cs similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/PierceTagConfig.cs rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/PierceTagConfig.cs diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/PierceTagConfig.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/PierceTagConfig.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/PierceTagConfig.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/PierceTagConfig.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/ShatterTagConfig.cs b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/ShatterTagConfig.cs similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/ShatterTagConfig.cs rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/ShatterTagConfig.cs diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/ShatterTagConfig.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/ShatterTagConfig.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/ShatterTagConfig.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/ShatterTagConfig.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/TagConfigBase.cs b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/TagConfigBase.cs similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/TagConfigBase.cs rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/TagConfigBase.cs diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig/TagConfigBase.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/TagConfigBase.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfig/TagConfigBase.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/Config/TagConfigBase.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagDefinitionData.cs b/Assets/GameMain/Scripts/Definition/Tag/Metadata/TagDefinition.cs similarity index 88% rename from Assets/GameMain/Scripts/Definition/Tag/TagDefinitionData.cs rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/TagDefinition.cs index f53eeb5..710ca92 100644 --- a/Assets/GameMain/Scripts/Definition/Tag/TagDefinitionData.cs +++ b/Assets/GameMain/Scripts/Definition/Tag/Metadata/TagDefinition.cs @@ -3,7 +3,7 @@ using System; namespace GeometryTD.Definition { [Serializable] - public sealed class TagDefinitionData + public sealed class TagDefinition { public TagType TagType { get; set; } public TagCategory Category { get; set; } diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagDefinitionData.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Metadata/TagDefinition.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagDefinitionData.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/TagDefinition.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfigRegistry.cs b/Assets/GameMain/Scripts/Definition/Tag/Metadata/TagDefinitionRegistry.cs similarity index 85% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfigRegistry.cs rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/TagDefinitionRegistry.cs index 3945c46..3f1c5c5 100644 --- a/Assets/GameMain/Scripts/Definition/Tag/TagConfigRegistry.cs +++ b/Assets/GameMain/Scripts/Definition/Tag/Metadata/TagDefinitionRegistry.cs @@ -5,16 +5,16 @@ using UnityEngine; namespace GeometryTD.Definition { - public static class TagConfigRegistry + public static class TagDefinitionRegistry { - private static readonly Dictionary DefinitionsByTag = CreateDefaultDefinitions(); + private static readonly Dictionary DefinitionsByTag = CreateDefaultDefinitions(); - public static IReadOnlyDictionary Definitions => DefinitionsByTag; + public static IReadOnlyDictionary Definitions => DefinitionsByTag; public static void ResetToDefaults() { DefinitionsByTag.Clear(); - foreach (KeyValuePair pair in CreateDefaultDefinitions()) + foreach (KeyValuePair pair in CreateDefaultDefinitions()) { DefinitionsByTag.Add(pair.Key, pair.Value); } @@ -29,23 +29,36 @@ namespace GeometryTD.Definition } } - public static bool TryGetDefinition(TagType tagType, out TagDefinitionData definition) + public static bool TryGetDefinition(TagType tagType, out TagDefinition definition) { return DefinitionsByTag.TryGetValue(tagType, out definition); } - private static Dictionary CreateDefaultDefinitions() + public static void ApplyTagRows(IEnumerable rows) { - return new Dictionary + if (rows == null) + { + return; + } + + foreach (DRTag row in rows) + { + ApplyTagRow(row); + } + } + + private static Dictionary CreateDefaultDefinitions() + { + return new Dictionary { [TagType.Fire] = CreateDefinition(TagType.Fire, TagCategory.Status, TagTriggerPhase.OnAfterHit, new FireTagConfig(true)), [TagType.BurnSpread] = CreateDefinition(TagType.BurnSpread, TagCategory.AttackShape, TagTriggerPhase.OnKill, new BurnSpreadTagConfig(false)), [TagType.IgniteBurst] = CreateDefinition(TagType.IgniteBurst, TagCategory.AttackShape, TagTriggerPhase.OnKill, new IgniteBurstTagConfig(false)), - [TagType.Inferno] = CreateDefinition(TagType.Inferno, TagCategory.Status, TagTriggerPhase.OnAfterHit, new InfernoTagConfig(true)), + [TagType.Inferno] = CreateDefinition(TagType.Inferno, TagCategory.StatusModifier, TagTriggerPhase.OnAfterHit, new InfernoTagConfig(true)), [TagType.Ice] = CreateDefinition(TagType.Ice, TagCategory.Status, TagTriggerPhase.OnAfterHit, new IceTagConfig(true)), [TagType.FreezeMask] = CreateDefinition(TagType.FreezeMask, TagCategory.AttackShape, TagTriggerPhase.OnAfterHit, new FreezeMaskTagConfig(false)), [TagType.Shatter] = CreateDefinition(TagType.Shatter, TagCategory.NumericModifier, TagTriggerPhase.OnBeforeHit, new ShatterTagConfig(true)), - [TagType.AbsoluteZero] = CreateDefinition(TagType.AbsoluteZero, TagCategory.Status, TagTriggerPhase.OnAfterHit, new AbsoluteZeroTagConfig(true)), + [TagType.AbsoluteZero] = CreateDefinition(TagType.AbsoluteZero, TagCategory.StatusModifier, TagTriggerPhase.OnAfterHit, new AbsoluteZeroTagConfig(true)), [TagType.Pierce] = CreateDefinition(TagType.Pierce, TagCategory.AttackShape, TagTriggerPhase.OnHit, new PierceTagConfig(false)), [TagType.Crit] = CreateDefinition(TagType.Crit, TagCategory.NumericModifier, TagTriggerPhase.OnBeforeHit, new CritTagConfig(true)), [TagType.Overpenetrate] = CreateDefinition(TagType.Overpenetrate, TagCategory.AttackShape, TagTriggerPhase.OnHit, new OverpenetrateTagConfig(false)), @@ -53,13 +66,13 @@ namespace GeometryTD.Definition }; } - private static TagDefinitionData CreateDefinition( + private static TagDefinition CreateDefinition( TagType tagType, TagCategory category, TagTriggerPhase triggerPhase, TagConfigBase config) { - return new TagDefinitionData + return new TagDefinition { TagType = tagType, Category = category, @@ -72,7 +85,7 @@ namespace GeometryTD.Definition private static void ApplyRow(DRTagConfig row) { Debug.Assert(row != null); - Debug.Assert(DefinitionsByTag.TryGetValue(row.TagType, out TagDefinitionData definition)); + Debug.Assert(DefinitionsByTag.TryGetValue(row.TagType, out TagDefinition definition)); definition.TriggerPhase = row.TriggerPhase; definition.Description = row.Description ?? string.Empty; @@ -109,6 +122,16 @@ namespace GeometryTD.Definition } } + private static void ApplyTagRow(DRTag row) + { + Debug.Assert(row != null); + Debug.Assert(row.Id > 0); + Debug.Assert(DefinitionsByTag.TryGetValue(row.TagType, out TagDefinition definition)); + Debug.Assert(definition.Config != null); + + definition.Config.IsImplemented = row.IsImplemented; + } + private static void ApplyFireConfig(FireTagConfig config, JObject param) { config.BurnDurationSeconds = ReadFloat(param, nameof(FireTagConfig.BurnDurationSeconds), config.BurnDurationSeconds); diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfigRegistry.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Metadata/TagDefinitionRegistry.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Definition/Tag/TagConfigRegistry.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Metadata/TagDefinitionRegistry.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/Presentation.meta b/Assets/GameMain/Scripts/Definition/Tag/Presentation.meta new file mode 100644 index 0000000..ffee579 --- /dev/null +++ b/Assets/GameMain/Scripts/Definition/Tag/Presentation.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9f3ef8704ccb98147a21c03330278743 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/Utility/TagDisplayUtility.cs b/Assets/GameMain/Scripts/Definition/Tag/Presentation/TagDisplayUtility.cs similarity index 98% rename from Assets/GameMain/Scripts/Utility/TagDisplayUtility.cs rename to Assets/GameMain/Scripts/Definition/Tag/Presentation/TagDisplayUtility.cs index a627e25..461ca74 100644 --- a/Assets/GameMain/Scripts/Utility/TagDisplayUtility.cs +++ b/Assets/GameMain/Scripts/Definition/Tag/Presentation/TagDisplayUtility.cs @@ -163,7 +163,7 @@ namespace GeometryTD.CustomUtility return string.Empty; } - if (TagConfigRegistry.TryGetDefinition(tagType, out TagDefinitionData definition) && + if (TagDefinitionRegistry.TryGetDefinition(tagType, out TagDefinition definition) && !string.IsNullOrWhiteSpace(definition.Description)) { return definition.Description; diff --git a/Assets/GameMain/Scripts/Utility/TagDisplayUtility.cs.meta b/Assets/GameMain/Scripts/Definition/Tag/Presentation/TagDisplayUtility.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/Utility/TagDisplayUtility.cs.meta rename to Assets/GameMain/Scripts/Definition/Tag/Presentation/TagDisplayUtility.cs.meta diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagConfig.meta b/Assets/GameMain/Scripts/Definition/Tag/TagConfig.meta deleted file mode 100644 index 99cee6f..0000000 --- a/Assets/GameMain/Scripts/Definition/Tag/TagConfig.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: c90264b23a9c45c0b21bc627a6109282 -timeCreated: 1773105821 \ No newline at end of file diff --git a/Assets/GameMain/Scripts/Definition/Tag/TagEffectHandler.meta b/Assets/GameMain/Scripts/Definition/Tag/TagEffectHandler.meta deleted file mode 100644 index 255631a..0000000 --- a/Assets/GameMain/Scripts/Definition/Tag/TagEffectHandler.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 6fb08c76711246c2afa02d60769d76ef -timeCreated: 1773106291 \ No newline at end of file diff --git a/Assets/GameMain/Scripts/Procedure/Base/ProcedurePreload.cs b/Assets/GameMain/Scripts/Procedure/Base/ProcedurePreload.cs index 0ab9d63..24ad0d3 100644 --- a/Assets/GameMain/Scripts/Procedure/Base/ProcedurePreload.cs +++ b/Assets/GameMain/Scripts/Procedure/Base/ProcedurePreload.cs @@ -202,7 +202,7 @@ namespace GeometryTD.Procedure var tagConfigTable = GameEntry.DataTable.GetDataTable(); if (tagConfigTable != null) { - TagConfigRegistry.LoadFromRows(tagConfigTable.GetAllDataRows()); + TagDefinitionRegistry.LoadFromRows(tagConfigTable.GetAllDataRows()); } } @@ -211,7 +211,9 @@ namespace GeometryTD.Procedure var tagTable = GameEntry.DataTable.GetDataTable(); if (tagTable != null) { - TagGenerationRuleRegistry.LoadFromRows(tagTable.GetAllDataRows()); + DRTag[] rows = tagTable.GetAllDataRows(); + TagGenerationRuleRegistry.LoadFromRows(rows); + TagDefinitionRegistry.ApplyTagRows(rows); } } diff --git a/Assets/GameMain/Scripts/UI/Shop/UseCase/ShopFormUseCase.cs b/Assets/GameMain/Scripts/UI/Shop/UseCase/ShopFormUseCase.cs index be428da..48a4c7d 100644 --- a/Assets/GameMain/Scripts/UI/Shop/UseCase/ShopFormUseCase.cs +++ b/Assets/GameMain/Scripts/UI/Shop/UseCase/ShopFormUseCase.cs @@ -185,7 +185,7 @@ namespace GeometryTD.UI Rarity = normalizedRarity, Endurance = 100f, Constraint = config.Constraint, - Tags = InventoryTagRuleService.ResolveComponentTags( + Tags = ComponentTagGenerationService.ResolveComponentTags( config.PossibleTag, normalizedRarity, InventoryTagSourceType.Shop, @@ -211,7 +211,7 @@ namespace GeometryTD.UI Rarity = normalizedRarity, Endurance = 100f, Constraint = config.Constraint, - Tags = InventoryTagRuleService.ResolveComponentTags( + Tags = ComponentTagGenerationService.ResolveComponentTags( config.PossibleTag, normalizedRarity, InventoryTagSourceType.Shop, @@ -236,7 +236,7 @@ namespace GeometryTD.UI Rarity = normalizedRarity, Endurance = 100f, Constraint = config.Constraint, - Tags = InventoryTagRuleService.ResolveComponentTags( + Tags = ComponentTagGenerationService.ResolveComponentTags( config.PossibleTag, normalizedRarity, InventoryTagSourceType.Shop, diff --git a/Assets/GameMain/Scripts/Utility/InventorySeedUtility.cs b/Assets/GameMain/Scripts/Utility/InventorySeedUtility.cs index 6c86ab1..868b7cf 100644 --- a/Assets/GameMain/Scripts/Utility/InventorySeedUtility.cs +++ b/Assets/GameMain/Scripts/Utility/InventorySeedUtility.cs @@ -189,7 +189,7 @@ namespace GeometryTD.CustomUtility private static TagType[] ResolveSeedTags(TagType[] possibleTags, RarityType rarity, long instanceId, int configId) { - return InventoryTagRuleService.ResolveComponentTags( + return ComponentTagGenerationService.ResolveComponentTags( possibleTags, rarity, InventoryTagSourceType.Seed, diff --git a/Assets/Tests/EditMode/InventoryTagRuleServiceTests.cs b/Assets/Tests/EditMode/ComponentTagGenerationServiceTests.cs similarity index 64% rename from Assets/Tests/EditMode/InventoryTagRuleServiceTests.cs rename to Assets/Tests/EditMode/ComponentTagGenerationServiceTests.cs index 37a5359..5b61435 100644 --- a/Assets/Tests/EditMode/InventoryTagRuleServiceTests.cs +++ b/Assets/Tests/EditMode/ComponentTagGenerationServiceTests.cs @@ -6,34 +6,34 @@ using NUnit.Framework; namespace GeometryTD.Tests.EditMode { - public sealed class InventoryTagRuleServiceTests + public sealed class ComponentTagGenerationServiceTests { - private static readonly IReadOnlyDictionary RulesByTag = - new Dictionary + private static readonly IReadOnlyDictionary RulesByTag = + new Dictionary { - { TagType.Fire, new TagGenerationRuleData { TagType = TagType.Fire, MinRarity = RarityType.White, Weight = 20 } }, - { TagType.Ice, new TagGenerationRuleData { TagType = TagType.Ice, MinRarity = RarityType.White, Weight = 20 } }, - { TagType.Crit, new TagGenerationRuleData { TagType = TagType.Crit, MinRarity = RarityType.White, Weight = 20 } }, - { TagType.Shatter, new TagGenerationRuleData { TagType = TagType.Shatter, MinRarity = RarityType.Green, Weight = 15 } }, - { TagType.Inferno, new TagGenerationRuleData { TagType = TagType.Inferno, MinRarity = RarityType.Purple, Weight = 5 } }, - { TagType.AbsoluteZero, new TagGenerationRuleData { TagType = TagType.AbsoluteZero, MinRarity = RarityType.Purple, Weight = 5 } }, - { TagType.Execution, new TagGenerationRuleData { TagType = TagType.Execution, MinRarity = RarityType.Purple, Weight = 5 } }, + { TagType.Fire, new TagGenerationRule { TagType = TagType.Fire, MinRarity = RarityType.White, Weight = 20 } }, + { TagType.Ice, new TagGenerationRule { TagType = TagType.Ice, MinRarity = RarityType.White, Weight = 20 } }, + { TagType.Crit, new TagGenerationRule { TagType = TagType.Crit, MinRarity = RarityType.White, Weight = 20 } }, + { TagType.Shatter, new TagGenerationRule { TagType = TagType.Shatter, MinRarity = RarityType.Green, Weight = 15 } }, + { TagType.Inferno, new TagGenerationRule { TagType = TagType.Inferno, MinRarity = RarityType.Purple, Weight = 5 } }, + { TagType.AbsoluteZero, new TagGenerationRule { TagType = TagType.AbsoluteZero, MinRarity = RarityType.Purple, Weight = 5 } }, + { TagType.Execution, new TagGenerationRule { TagType = TagType.Execution, MinRarity = RarityType.Purple, Weight = 5 } }, }; - private static readonly IReadOnlyDictionary RarityTagBudgetRulesByRarity = - new Dictionary + private static readonly IReadOnlyDictionary RarityTagBudgetRulesByRarity = + new Dictionary { - { RarityType.White, new RarityTagBudgetRuleData { Rarity = RarityType.White, MinCount = 0, MaxCount = 1 } }, - { RarityType.Green, new RarityTagBudgetRuleData { Rarity = RarityType.Green, MinCount = 1, MaxCount = 1 } }, - { RarityType.Blue, new RarityTagBudgetRuleData { Rarity = RarityType.Blue, MinCount = 1, MaxCount = 2 } }, - { RarityType.Purple, new RarityTagBudgetRuleData { Rarity = RarityType.Purple, MinCount = 2, MaxCount = 2 } }, - { RarityType.Red, new RarityTagBudgetRuleData { Rarity = RarityType.Red, MinCount = 2, MaxCount = 3 } }, + { RarityType.White, new RarityTagBudgetRule { Rarity = RarityType.White, MinCount = 0, MaxCount = 1 } }, + { RarityType.Green, new RarityTagBudgetRule { Rarity = RarityType.Green, MinCount = 1, MaxCount = 1 } }, + { RarityType.Blue, new RarityTagBudgetRule { Rarity = RarityType.Blue, MinCount = 1, MaxCount = 2 } }, + { RarityType.Purple, new RarityTagBudgetRule { Rarity = RarityType.Purple, MinCount = 2, MaxCount = 2 } }, + { RarityType.Red, new RarityTagBudgetRule { Rarity = RarityType.Red, MinCount = 2, MaxCount = 3 } }, }; [Test] public void GetEligibleTags_Filters_Invalid_Unsupported_And_HighRarity_Tags() { - TagType[] result = InventoryTagRuleService.GetEligibleTags( + TagType[] result = ComponentTagGenerationService.GetEligibleTags( new[] { TagType.None, @@ -52,7 +52,7 @@ namespace GeometryTD.Tests.EditMode [Test] public void ResolveComponentTags_Is_Deterministic_For_Same_Context() { - TagType[] first = InventoryTagRuleService.ResolveComponentTags( + TagType[] first = ComponentTagGenerationService.ResolveComponentTags( new[] { TagType.Fire, TagType.Ice, TagType.Crit, TagType.Shatter }, RarityType.Blue, InventoryTagSourceType.Shop, @@ -60,7 +60,7 @@ namespace GeometryTD.Tests.EditMode 7, RulesByTag); - TagType[] second = InventoryTagRuleService.ResolveComponentTags( + TagType[] second = ComponentTagGenerationService.ResolveComponentTags( new[] { TagType.Fire, TagType.Ice, TagType.Crit, TagType.Shatter }, RarityType.Blue, InventoryTagSourceType.Shop, @@ -74,7 +74,7 @@ namespace GeometryTD.Tests.EditMode [Test] public void ResolveComponentTags_Uses_Purple_Budget_And_Does_Not_Repeat() { - TagType[] result = InventoryTagRuleService.ResolveComponentTags( + TagType[] result = ComponentTagGenerationService.ResolveComponentTags( new[] { TagType.Fire, TagType.Ice, TagType.Crit, TagType.Shatter, TagType.Inferno, TagType.Execution }, RarityType.Purple, InventoryTagSourceType.Drop, @@ -90,7 +90,7 @@ namespace GeometryTD.Tests.EditMode [Test] public void ResolveComponentTags_Falls_Back_When_Eligible_Count_Is_Lower_Than_Budget() { - TagType[] result = InventoryTagRuleService.ResolveComponentTags( + TagType[] result = ComponentTagGenerationService.ResolveComponentTags( new[] { TagType.Fire, TagType.BurnSpread }, RarityType.Red, InventoryTagSourceType.Seed, @@ -105,15 +105,15 @@ namespace GeometryTD.Tests.EditMode [Test] public void ResolveComponentTags_Uses_Weight_Within_EligiblePool() { - IReadOnlyDictionary weightedRules = - new Dictionary + IReadOnlyDictionary weightedRules = + new Dictionary { - { TagType.Fire, new TagGenerationRuleData { TagType = TagType.Fire, MinRarity = RarityType.White, Weight = 100 } }, - { TagType.Ice, new TagGenerationRuleData { TagType = TagType.Ice, MinRarity = RarityType.White, Weight = 1 } }, - { TagType.Crit, new TagGenerationRuleData { TagType = TagType.Crit, MinRarity = RarityType.White, Weight = 1 } }, + { TagType.Fire, new TagGenerationRule { TagType = TagType.Fire, MinRarity = RarityType.White, Weight = 100 } }, + { TagType.Ice, new TagGenerationRule { TagType = TagType.Ice, MinRarity = RarityType.White, Weight = 1 } }, + { TagType.Crit, new TagGenerationRule { TagType = TagType.Crit, MinRarity = RarityType.White, Weight = 1 } }, }; - TagType[] result = InventoryTagRuleService.ResolveComponentTags( + TagType[] result = ComponentTagGenerationService.ResolveComponentTags( new[] { TagType.Fire, TagType.Ice, TagType.Crit }, RarityType.Green, InventoryTagSourceType.Shop, @@ -129,19 +129,19 @@ namespace GeometryTD.Tests.EditMode [Test] public void ResolveComponentTags_Prefers_HighWeight_Tag_In_ExpandedPool() { - IReadOnlyDictionary weightedRules = - new Dictionary + IReadOnlyDictionary weightedRules = + new Dictionary { - { TagType.Fire, new TagGenerationRuleData { TagType = TagType.Fire, MinRarity = RarityType.White, Weight = 500 } }, - { TagType.Ice, new TagGenerationRuleData { TagType = TagType.Ice, MinRarity = RarityType.White, Weight = 1 } }, - { TagType.Crit, new TagGenerationRuleData { TagType = TagType.Crit, MinRarity = RarityType.White, Weight = 1 } }, - { TagType.Shatter, new TagGenerationRuleData { TagType = TagType.Shatter, MinRarity = RarityType.White, Weight = 1 } }, + { TagType.Fire, new TagGenerationRule { TagType = TagType.Fire, MinRarity = RarityType.White, Weight = 500 } }, + { TagType.Ice, new TagGenerationRule { TagType = TagType.Ice, MinRarity = RarityType.White, Weight = 1 } }, + { TagType.Crit, new TagGenerationRule { TagType = TagType.Crit, MinRarity = RarityType.White, Weight = 1 } }, + { TagType.Shatter, new TagGenerationRule { TagType = TagType.Shatter, MinRarity = RarityType.White, Weight = 1 } }, }; int fireCount = 0; for (int i = 0; i < 32; i++) { - TagType[] result = InventoryTagRuleService.ResolveComponentTags( + TagType[] result = ComponentTagGenerationService.ResolveComponentTags( new[] { TagType.Fire, TagType.Ice, TagType.Crit, TagType.Shatter }, RarityType.Green, InventoryTagSourceType.Shop, @@ -168,7 +168,7 @@ namespace GeometryTD.Tests.EditMode TagGenerationRuleRegistry.LoadFromRows(new[] { fireRow }); - Assert.That(TagGenerationRuleRegistry.TryGetRule(TagType.Fire, out TagGenerationRuleData rule), Is.True); + Assert.That(TagGenerationRuleRegistry.TryGetRule(TagType.Fire, out TagGenerationRule rule), Is.True); Assert.That(rule.MinRarity, Is.EqualTo(RarityType.Green)); Assert.That(rule.Weight, Is.EqualTo(33)); @@ -178,15 +178,15 @@ namespace GeometryTD.Tests.EditMode [Test] public void ResolveRarityTagBudget_Uses_TableDriven_Range_Rules() { - int whiteBudget = InventoryTagRuleService.ResolveRarityTagBudget( + int whiteBudget = ComponentTagGenerationService.ResolveRarityTagBudget( RarityType.White, new System.Random(0), RarityTagBudgetRulesByRarity); - int greenBudget = InventoryTagRuleService.ResolveRarityTagBudget( + int greenBudget = ComponentTagGenerationService.ResolveRarityTagBudget( RarityType.Green, new System.Random(0), RarityTagBudgetRulesByRarity); - int redBudget = InventoryTagRuleService.ResolveRarityTagBudget( + int redBudget = ComponentTagGenerationService.ResolveRarityTagBudget( RarityType.Red, new System.Random(0), RarityTagBudgetRulesByRarity); @@ -199,10 +199,10 @@ namespace GeometryTD.Tests.EditMode [Test] public void ResolveComponentTags_Uses_Custom_Purple_Budget_From_Rules() { - IReadOnlyDictionary customBudgetRules = - new Dictionary(RarityTagBudgetRulesByRarity) + IReadOnlyDictionary customBudgetRules = + new Dictionary(RarityTagBudgetRulesByRarity) { - [RarityType.Purple] = new RarityTagBudgetRuleData + [RarityType.Purple] = new RarityTagBudgetRule { Rarity = RarityType.Purple, MinCount = 3, @@ -210,7 +210,7 @@ namespace GeometryTD.Tests.EditMode } }; - TagType[] result = InventoryTagRuleService.ResolveComponentTags( + TagType[] result = ComponentTagGenerationService.ResolveComponentTags( new[] { TagType.Fire, TagType.Ice, TagType.Crit, TagType.Shatter, TagType.Inferno, TagType.Execution }, RarityType.Purple, InventoryTagSourceType.Drop, @@ -231,7 +231,7 @@ namespace GeometryTD.Tests.EditMode RarityTagBudgetRuleRegistry.LoadFromRows(new[] { purpleRow }); - Assert.That(RarityTagBudgetRuleRegistry.TryGetRule(RarityType.Purple, out RarityTagBudgetRuleData rule), Is.True); + Assert.That(RarityTagBudgetRuleRegistry.TryGetRule(RarityType.Purple, out RarityTagBudgetRule rule), Is.True); Assert.That(rule.MinCount, Is.EqualTo(3)); Assert.That(rule.MaxCount, Is.EqualTo(3)); diff --git a/Assets/Tests/EditMode/InventoryTagRuleServiceTests.cs.meta b/Assets/Tests/EditMode/ComponentTagGenerationServiceTests.cs.meta similarity index 100% rename from Assets/Tests/EditMode/InventoryTagRuleServiceTests.cs.meta rename to Assets/Tests/EditMode/ComponentTagGenerationServiceTests.cs.meta diff --git a/Assets/Tests/EditMode/TagCombatRuntimeTests.cs b/Assets/Tests/EditMode/TagCombatRuntimeTests.cs index 7c13689..6c44a86 100644 --- a/Assets/Tests/EditMode/TagCombatRuntimeTests.cs +++ b/Assets/Tests/EditMode/TagCombatRuntimeTests.cs @@ -278,7 +278,7 @@ namespace GeometryTD.Tests.EditMode public sealed class EnemyStatusTagRegistryTests { [Test] - public void Registry_Registers_All_Status_Tags() + public void Registry_Registers_Only_Independent_Status_Tags() { Assert.That(EnemyStatusTagRegistry.TryGetEffect(TagType.Fire, out IEnemyStatusTagEffect fireEffect), Is.True); Assert.That(fireEffect, Is.TypeOf()); @@ -286,50 +286,49 @@ namespace GeometryTD.Tests.EditMode Assert.That(EnemyStatusTagRegistry.TryGetEffect(TagType.Ice, out IEnemyStatusTagEffect iceEffect), Is.True); Assert.That(iceEffect, Is.TypeOf()); - Assert.That(EnemyStatusTagRegistry.TryGetEffect(TagType.Inferno, out IEnemyStatusTagEffect infernoEffect), Is.True); - Assert.That(infernoEffect, Is.TypeOf()); - - Assert.That(EnemyStatusTagRegistry.TryGetEffect(TagType.AbsoluteZero, out IEnemyStatusTagEffect absoluteZeroEffect), Is.True); - Assert.That(absoluteZeroEffect, Is.TypeOf()); + Assert.That(EnemyStatusTagRegistry.TryGetEffect(TagType.Inferno, out _), Is.False); + Assert.That(EnemyStatusTagRegistry.TryGetEffect(TagType.AbsoluteZero, out _), Is.False); } } - public sealed class TagConfigRegistryTests + public sealed class TagDefinitionRegistryTests { [Test] public void Definitions_Register_All_Twelve_Tags() { - Assert.That(TagConfigRegistry.Definitions.Count, Is.EqualTo(12)); - Assert.That(TagConfigRegistry.TryGetDefinition(TagType.Fire, out _), Is.True); - Assert.That(TagConfigRegistry.TryGetDefinition(TagType.Execution, out _), Is.True); - Assert.That(TagConfigRegistry.TryGetDefinition(TagType.Overpenetrate, out _), Is.True); + Assert.That(TagDefinitionRegistry.Definitions.Count, Is.EqualTo(12)); + Assert.That(TagDefinitionRegistry.TryGetDefinition(TagType.Fire, out _), Is.True); + Assert.That(TagDefinitionRegistry.TryGetDefinition(TagType.Execution, out _), Is.True); + Assert.That(TagDefinitionRegistry.TryGetDefinition(TagType.Overpenetrate, out _), Is.True); } [Test] public void Definitions_Assign_Documented_Categories_And_Phases() { AssertDefinition(TagType.Fire, TagCategory.Status, TagTriggerPhase.OnAfterHit); + AssertDefinition(TagType.Inferno, TagCategory.StatusModifier, TagTriggerPhase.OnAfterHit); AssertDefinition(TagType.Crit, TagCategory.NumericModifier, TagTriggerPhase.OnBeforeHit); AssertDefinition(TagType.Pierce, TagCategory.AttackShape, TagTriggerPhase.OnHit); AssertDefinition(TagType.BurnSpread, TagCategory.AttackShape, TagTriggerPhase.OnKill); + AssertDefinition(TagType.AbsoluteZero, TagCategory.StatusModifier, TagTriggerPhase.OnAfterHit); } [Test] public void Definitions_Mark_FirstBatch_SevenTags_AsImplemented() { - Assert.That(TagConfigRegistry.TryGetDefinition(TagType.Shatter, out TagDefinitionData shatter), Is.True); + Assert.That(TagDefinitionRegistry.TryGetDefinition(TagType.Shatter, out TagDefinition shatter), Is.True); Assert.That(shatter.Config, Is.TypeOf()); Assert.That(((ShatterTagConfig)shatter.Config).IsImplemented, Is.True); - Assert.That(TagConfigRegistry.TryGetDefinition(TagType.Inferno, out TagDefinitionData inferno), Is.True); + Assert.That(TagDefinitionRegistry.TryGetDefinition(TagType.Inferno, out TagDefinition inferno), Is.True); Assert.That(inferno.Config, Is.TypeOf()); Assert.That(((InfernoTagConfig)inferno.Config).IsImplemented, Is.True); - Assert.That(TagConfigRegistry.TryGetDefinition(TagType.AbsoluteZero, out TagDefinitionData absoluteZero), Is.True); + Assert.That(TagDefinitionRegistry.TryGetDefinition(TagType.AbsoluteZero, out TagDefinition absoluteZero), Is.True); Assert.That(absoluteZero.Config, Is.TypeOf()); Assert.That(((AbsoluteZeroTagConfig)absoluteZero.Config).IsImplemented, Is.True); - Assert.That(TagConfigRegistry.TryGetDefinition(TagType.Pierce, out TagDefinitionData pierce), Is.True); + Assert.That(TagDefinitionRegistry.TryGetDefinition(TagType.Pierce, out TagDefinition pierce), Is.True); Assert.That(pierce.Config, Is.TypeOf()); Assert.That(((PierceTagConfig)pierce.Config).IsImplemented, Is.False); } @@ -341,9 +340,9 @@ namespace GeometryTD.Tests.EditMode bool parsed = fireRow.ParseDataRow("\t1\t元素\tFire\tOnAfterHit\t火焰测试描述\t{\"BurnDurationSeconds\":4,\"BurnDamagePerSecondPerStack\":25,\"MaxEffectiveStack\":3}", null); Assert.That(parsed, Is.True); - TagConfigRegistry.LoadFromRows(new[] { fireRow }); + TagDefinitionRegistry.LoadFromRows(new[] { fireRow }); - Assert.That(TagConfigRegistry.TryGetDefinition(TagType.Fire, out TagDefinitionData fire), Is.True); + Assert.That(TagDefinitionRegistry.TryGetDefinition(TagType.Fire, out TagDefinition fire), Is.True); Assert.That(fire.TriggerPhase, Is.EqualTo(TagTriggerPhase.OnAfterHit)); Assert.That(fire.Description, Is.EqualTo("火焰测试描述")); Assert.That(fire.Config, Is.TypeOf()); @@ -353,7 +352,23 @@ namespace GeometryTD.Tests.EditMode Assert.That(config.BurnDamagePerSecondPerStack, Is.EqualTo(25f).Within(0.001f)); Assert.That(config.MaxEffectiveStack, Is.EqualTo(3)); - TagConfigRegistry.ResetToDefaults(); + TagDefinitionRegistry.ResetToDefaults(); + } + + [Test] + public void ApplyTagRows_Overrides_IsImplemented_From_TagTable() + { + DRTag pierceRow = new DRTag(); + Assert.That(pierceRow.ParseDataRow("\t9\t穿透\tPierce\tPenetrate\tWhite\t20\tTrue", null), Is.True); + + TagDefinitionRegistry.ResetToDefaults(); + TagDefinitionRegistry.ApplyTagRows(new[] { pierceRow }); + + Assert.That(TagDefinitionRegistry.TryGetDefinition(TagType.Pierce, out TagDefinition pierce), Is.True); + Assert.That(pierce.Config, Is.TypeOf()); + Assert.That(((PierceTagConfig)pierce.Config).IsImplemented, Is.True); + + TagDefinitionRegistry.ResetToDefaults(); } [Test] @@ -364,14 +379,14 @@ namespace GeometryTD.Tests.EditMode Assert.That(fireRow.ParseDataRow("\t1\t元素\tFire\tOnAfterHit\t持续燃烧\t{\"BurnDurationSeconds\":3,\"BurnDamagePerSecondPerStack\":20,\"MaxEffectiveStack\":5}", null), Is.True); Assert.That(shatterRow.ParseDataRow("\t7\t控制\tShatter\tOnBeforeHit\t对减速目标增伤\t{\"RequiresSlowedTarget\":true,\"DamageBonusPerStack\":0.25}", null), Is.True); - TagConfigRegistry.LoadFromRows(new[] { fireRow, shatterRow }); + TagDefinitionRegistry.LoadFromRows(new[] { fireRow, shatterRow }); string description = TagDisplayUtility.BuildTagDescriptionText(new[] { TagType.Fire, TagType.Shatter }); Assert.That(description, Does.Contain("持续燃烧")); Assert.That(description, Does.Contain("对减速目标增伤")); - TagConfigRegistry.ResetToDefaults(); + TagDefinitionRegistry.ResetToDefaults(); } [Test] @@ -380,7 +395,7 @@ namespace GeometryTD.Tests.EditMode DRTagConfig iceRow = new DRTagConfig(); Assert.That(iceRow.ParseDataRow("\t5\t控制\tIce\tOnAfterHit\t命中附加减速\t{\"SlowDurationSeconds\":2,\"SlowRatioPerStack\":0.2,\"MinMoveSpeedMultiplier\":0.4}", null), Is.True); - TagConfigRegistry.LoadFromRows(new[] { iceRow }); + TagDefinitionRegistry.LoadFromRows(new[] { iceRow }); string description = TagDisplayUtility.BuildTagDescriptionText(new[] { @@ -390,7 +405,7 @@ namespace GeometryTD.Tests.EditMode Assert.That(description, Does.Contain("Ice x2")); Assert.That(description, Does.Contain("命中附加减速")); - TagConfigRegistry.ResetToDefaults(); + TagDefinitionRegistry.ResetToDefaults(); } [Test] @@ -418,7 +433,7 @@ namespace GeometryTD.Tests.EditMode private static void AssertDefinition(TagType tagType, TagCategory expectedCategory, TagTriggerPhase expectedPhase) { - Assert.That(TagConfigRegistry.TryGetDefinition(tagType, out TagDefinitionData definition), Is.True); + Assert.That(TagDefinitionRegistry.TryGetDefinition(tagType, out TagDefinition definition), Is.True); Assert.That(definition, Is.Not.Null); Assert.That(definition.Category, Is.EqualTo(expectedCategory)); Assert.That(definition.TriggerPhase, Is.EqualTo(expectedPhase)); diff --git a/docs/CodeX-TODO.md b/docs/CodeX-TODO.md index 8c846e1..7b93c88 100644 --- a/docs/CodeX-TODO.md +++ b/docs/CodeX-TODO.md @@ -137,7 +137,7 @@ > > 2026-03-09 更新:`S4-03` 文档口径已冻结;`TagSystemDesign.md` 已明确组件实例生成、塔级 `Stack` 汇总、四段触发阶段、`Tag.txt + TagRule` 双表方向,以及 MVP 正式首发 7 个 Tag:`Fire`、`Ice`、`Crit`、`Execution`、`Shatter`、`Inferno`、`AbsoluteZero`。`BurnSpread` 已明确后移。 > -> 2026-03-09 更新:`S4-04` 已落地 `InventoryTagRuleService` 与 `InventoryTagSourceType`;组件实例 Tag 现在统一按 `PossibleTag + Tag.txt.MinRarity + 品质预算` 生成,并只保留当前正式首发 7 个 Tag。`ShopFormUseCase`、`EnemyDropResolver`、`InventorySeedUtility` 已接入该入口,样例库存的组件与塔展示 Tag 已同步为统一结果;同时新增 `InventoryTagRuleServiceTests`。当前 CLI 下 `dotnet build GeometryTD.sln` 仍因本机缺少 Unity 引用和 `Unity.SourceGenerators*.dll` 失败,未能替代 Unity Test Runner 完成最终验证。 +> 2026-03-09 更新:`S4-04` 已落地 `ComponentTagGenerationService` 与 `InventoryTagSourceType`;组件实例 Tag 现在统一按 `PossibleTag + Tag.txt.MinRarity + 品质预算` 生成,并只保留当前正式首发 7 个 Tag。`ShopFormUseCase`、`EnemyDropResolver`、`InventorySeedUtility` 已接入该入口,样例库存的组件与塔展示 Tag 已同步为统一结果;同时新增 `ComponentTagGenerationServiceTests`。当前 CLI 下 `dotnet build GeometryTD.sln` 仍因本机缺少 Unity 引用和 `Unity.SourceGenerators*.dll` 失败,未能替代 Unity Test Runner 完成最终验证。 > > 2026-03-09 更新:`S4-05` 已新增 `TagRuntimeData` 与 `TowerTagAggregationService`;组塔与样例塔现在统一生成塔级 `TagRuntimes`,并保留兼容 `Tags` 投影。`RepoForm`、`CombatFinishForm`、`ItemDescForm` 的塔展示已切到聚合结果,重复 Tag 以 `xN` 文本显示;组件展示仍沿用组件实例 `Tags`。同时新增 `TowerTagAggregationServiceTests`;本轮改动后的最终验证仍以 Unity Test Runner 实跑结果为准。 > @@ -145,11 +145,11 @@ > > 2026-03-10 更新:`S4-06` 已补齐首发剩余 3 个 Tag。`Shatter` 已接入命中前数值修正链,并按“目标已减速”口径增伤;`Inferno` 与 `AbsoluteZero` 已按首发方案作为 `Fire` / `Ice` 的强化 Tag 落地,分别增强 DOT 时长/伤害与减速时长/强度;对应 EditMode 测试已同步补齐。`BurnSpread`、`IgniteBurst`、`FreezeMask`、`Pierce`、`Overpenetrate` 仍保持分类与占位路由,没有实际战斗效果,因此仍属于后续扩展,不计入 `S4-06` 当前完成标准。 > -> 2026-03-10 更新:`S4-07` 仍未开始正式收口。当前 Tag 参数仍主要承载在代码侧 `TagConfigRegistry` 与各 Tag 配置类中,`Tag.txt` / DataTable 仍只提供基础字典与 `MinRarity` 输入;文档中约定的 `TagRule` 表、触发阶段、权重、效果参数等尚未形成 DataRow 与运行时消费闭环。因此 `S4-07` 继续保持未完成状态。 +> 2026-03-10 更新:`S4-07` 仍未开始正式收口。当前 Tag 参数仍主要承载在代码侧 `TagDefinitionRegistry` 与各 Tag 配置类中,`Tag.txt` / DataTable 仍只提供基础字典与 `MinRarity` 输入;文档中约定的 `TagRule` 表、触发阶段、权重、效果参数等尚未形成 DataRow 与运行时消费闭环。因此 `S4-07` 继续保持未完成状态。 > -> 2026-03-11 更新:`S4-07` 已进入第一阶段实现。当前已新增 `TagConfig.txt` 与 `DRTagConfig`,`ProcedurePreload` 会在加载 `TagConfig` 表后驱动 `TagConfigRegistry.LoadFromRows(...)`,把 `TriggerPhase`、`Description` 以及首发 7 个 Tag 的配置参数从表覆盖到运行时强类型 `TagConfig`。`ItemDescForm` 也已开始消费该配置说明;塔详情会优先使用 `TagRuntimes` 构建 `Ice x2` 这类叠层展示。因此 `S4-07` 不再是“完全未开始”,但当前仍只完成了 `TagConfig` 级别的参数映射与 UI 消费,尚未把文档中的完整 `TagRule`(如权重、生成规则等)全部收口。 +> 2026-03-11 更新:`S4-07` 已进入第一阶段实现。当前已新增 `TagConfig.txt` 与 `DRTagConfig`,`ProcedurePreload` 会在加载 `TagConfig` 表后驱动 `TagDefinitionRegistry.LoadFromRows(...)`,把 `TriggerPhase`、`Description` 以及首发 7 个 Tag 的配置参数从表覆盖到运行时强类型 `TagConfig`。`ItemDescForm` 也已开始消费该配置说明;塔详情会优先使用 `TagRuntimes` 构建 `Ice x2` 这类叠层展示。因此 `S4-07` 不再是“完全未开始”,但当前仍只完成了 `TagConfig` 级别的参数映射与 UI 消费,尚未把文档中的完整 `TagRule`(如权重、生成规则等)全部收口。 > -> 2026-03-11 更新:`S4-07` 已继续推进到第二阶段。当前 `Tag.txt -> DRTag -> TagGenerationRuleRegistry` 已形成组件 Tag 生成规则闭环,`InventoryTagRuleService` 不再主要依赖内部 `MinRarity` 硬编码,而是统一消费 `DRTag` 提供的 `MinRarity + Weight`;`ShopFormUseCase`、`EnemyDropResolver`、`InventorySeedUtility` 也已切回这一统一入口。现阶段的职责边界明确为:`Tag.txt` 负责基础字典与生成规则,`TagConfig.txt` 负责触发阶段、描述与效果参数。 +> 2026-03-11 更新:`S4-07` 已继续推进到第二阶段。当前 `Tag.txt -> DRTag -> TagGenerationRuleRegistry` 已形成组件 Tag 生成规则闭环,`ComponentTagGenerationService` 不再主要依赖内部 `MinRarity` 硬编码,而是统一消费 `DRTag` 提供的 `MinRarity + Weight`;`ShopFormUseCase`、`EnemyDropResolver`、`InventorySeedUtility` 也已切回这一统一入口。现阶段的职责边界明确为:`Tag.txt` 负责基础字典与生成规则,`TagConfig.txt` 负责触发阶段、描述与效果参数。 > > 2026-03-11 补充验证:已通过手工扩充组件 `PossibleTag` 候选池并调整 `Weight` 验证生成权重实际生效;同时把所有 Tag 的 `MinRarity` 提升到 `Red` 后,低品质组件不再生成任何 Tag,说明 `Tag.txt` 中的 `MinRarity` 与 `Weight` 均已进入统一生成链。 @@ -186,19 +186,19 @@ - `S4-06` 已完成:战斗链已支持 Tag 透传与统一结算,正式首发 7 个 Tag `Fire`、`Ice`、`Crit`、`Execution`、`Shatter`、`Inferno`、`AbsoluteZero` 均已有可验证效果。 - `Shatter` 已接入命中前数值修正链;`Inferno`、`AbsoluteZero` 已按“强化现有 `Fire` / `Ice` 状态”的首发口径落地,状态类 Tag 的内部结构继续保持注册式运行时。 - `BurnSpread`、`IgniteBurst`、`FreezeMask`、`Pierce`、`Overpenetrate` 已进入分类与配置骨架,但仍属于后续扩展,不计入当前 `S4` 的完成标准。 -- `S4-07` 已进入第一阶段实现。当前仓库已具备 `TagConfig.txt -> DRTagConfig -> TagConfigRegistry -> ItemDescForm` 的消费闭环,首发 7 个 Tag 的触发阶段、描述与核心参数已可由表覆盖。 -- `S4-07` 已推进到第二阶段。当前仓库同时具备 `Tag.txt -> DRTag -> TagGenerationRuleRegistry -> InventoryTagRuleService` 与 `TagConfig.txt -> DRTagConfig -> TagConfigRegistry -> ItemDescForm` 两条消费闭环,首发 7 个 Tag 的生成规则、触发阶段、描述与核心参数都已开始由表驱动。 -- `S4-07` 已推进到第三阶段。当前仓库新增 `RarityTagBudget.txt -> DRRarityTagBudget -> RarityTagBudgetRuleRegistry -> InventoryTagRuleService`,组件 Tag 数量预算不再写死在 `ResolveRarityTagBudget(...)` 的 `switch` 中,而是按品质从表驱动;至此生成链的候选过滤、权重抽取、数量预算三段都已进入 DataTable 消费闭环。 +- `S4-07` 已进入第一阶段实现。当前仓库已具备 `TagConfig.txt -> DRTagConfig -> TagDefinitionRegistry -> ItemDescForm` 的消费闭环,首发 7 个 Tag 的触发阶段、描述与核心参数已可由表覆盖。 +- `S4-07` 已推进到第二阶段。当前仓库同时具备 `Tag.txt -> DRTag -> TagGenerationRuleRegistry -> ComponentTagGenerationService` 与 `TagConfig.txt -> DRTagConfig -> TagDefinitionRegistry -> ItemDescForm` 两条消费闭环,首发 7 个 Tag 的生成规则、触发阶段、描述与核心参数都已开始由表驱动。 +- `S4-07` 已推进到第三阶段。当前仓库新增 `RarityTagBudget.txt -> DRRarityTagBudget -> RarityTagBudgetRuleRegistry -> ComponentTagGenerationService`,组件 Tag 数量预算不再写死在 `ResolveRarityTagBudget(...)` 的 `switch` 中,而是按品质从表驱动;至此生成链的候选过滤、权重抽取、数量预算三段都已进入 DataTable 消费闭环。 - `S4-07` 仍未完成最终收口。当前采用的是 `Tag.txt + RarityTagBudget.txt + TagConfig.txt` 的分层方案,而不是文档原方案里的单独 `TagRule`;更深的元数据字段与完整命名口径仍待后续决定是否继续统一。 ### S4-06 当前代码状态 - 命中链路已统一为 `AttackPayload -> HitContext -> TagEffectResolver`,子弹命中时不再只传裸 `damage`。 - `Tower` 侧的 `TagRuntimes` 已能透传到战斗,且保留了旧 `Tags -> TagRuntimes` 的兼容入口,避免旧塔或旧展示数据在战斗中完全失效。 -- 状态类 Tag 现在按单 Tag 文件拆分: - - 配置:每个 Tag 一个 `TagConfig` - - 运行时状态:每个状态类 Tag 一个 `TagState` - - 效果:每个状态类 Tag 一个 `TagEffect` +- 状态类 Tag 现在按职责目录拆分: +- `Metadata/Config`:每个 Tag 一个配置类 +- `Combat/States`:每个状态类 Tag 一个运行时状态类 +- `Combat/StatusEffects`:每个状态类 Tag 一个效果类 - `EnemyTagStatusRuntime` 已不再硬编码 `burn/slow` 字段,而是按激活的状态类 Tag 动态调度 Tick。 - `Fire` 已改为独立 DOT 公式:当前使用独立 `BurnDamagePerSecondPerStack`,并按敌人实体每帧提供的 `deltaTime` 连续结算,不再依赖命中伤害或内部 `TickInterval`。 - `Ice` 仍是独立减速状态,移速倍率通过状态运行时聚合得到。 @@ -220,6 +220,47 @@ | [ ] | S5-03 | 实现耐久扣减后的实际生效 | `Assets/GameMain/Scripts/CustomComponent/PlayerInventory/`
`Assets/GameMain/Scripts/Entity/` | 耐久不再只是展示字段 | | [ ] | S5-04 | 实现 `0` 耐久销毁或失效闭环 | `Assets/GameMain/Scripts/CustomComponent/PlayerInventory/`
`Assets/GameMain/Scripts/UI/` | 归零后行为符合最终口径 | +### S5 规划结论 + +- `S5` 当前按“最小耐久闭环”推进,不展开维修、折价、复杂恢复、耐久与 Tag 联动等后续深度系统。 +- M1 保留耐久规则,但当前目标只收口到“战斗后真实扣减 + 归零后真实失效 + UI 可解释”,不要求一并实现完整维修玩法。 +- 本阶段优先保证耐久从展示字段变成实际规则入口,而不是继续增加额外经济系统或复杂数值衰减。 + +### S5-01 范围结论 + +- `S5-01` 建议明确保留耐久闭环,但只做组件实例级耐久,不新开修理站、维修货币、商店修复等额外系统。 +- 当前阶段只处理战斗节点的耐久消耗;事件、商店、其他特殊节点暂不引入额外耐久变更。 +- `0` 耐久当前建议先按“失效但不立即销毁实例”收口,避免在本阶段同时引入背包移除、组装解绑、自动清空参战区等高耦合逻辑。 + +### S5-02 推荐规则口径 + +- 耐久数据仍挂在组件实例上,塔本身不额外维护独立耐久池。 +- 一座塔只要已装配的枪口 / 轴承 / 底座中任意一个组件耐久 `<= 0`,就视为损坏塔。 +- 损坏塔不能进入参战区,也不能通过战斗入口最终校验。 +- 当前阶段不实现“耐久越低属性越差”的连续衰减;在 `> 0` 耐久时,组件与塔仍按当前属性正常工作。 +- 当前阶段不把耐久纳入品质、Tag、掉落或商店价格公式,避免把 `S5` 扩成新的综合规则层。 + +### S5-03 推荐实现口径 + +- 每次战斗节点结算后,对本场实际参战塔所装配的三个组件各扣 `1` 点耐久。 +- 扣减结果必须真实回写到库存快照 / 当前 Run 库存,而不是只改战斗内临时对象。 +- 参战合法性统一复用现有校验入口扩展,不额外再造一套“耐久专用判断链”。 +- 战斗入口仍需要保留最终二次校验,避免旧快照或外部改动绕过组装区 / 参战区限制。 + +### S5-04 推荐闭环口径 + +- 组件耐久归零后,当前版本按“失效不可参战”收口,不立即自动销毁实例。 +- 装配了 `0` 耐久组件的塔在 UI 上需要给出明确提示,例如“组件已损坏”或“耐久为 0,无法参战”。 +- 若塔已在参战区且组件在上一场战斗后归零,需要在后续刷新中把该塔视为非法参战塔,并通过统一校验入口阻止再次进入战斗。 +- “自动销毁组件”与“自动拆塔”保留到后续阶段再决定,当前不作为 `S5` 通过标准。 + +### S5 推荐执行顺序 + +1. 先完成 `S5-01`,把 M1 的耐久范围冻结为“最小闭环”,文档先对齐。 +2. 再完成 `S5-02`,把“归零失效、非归零不衰减、不可参战”的规则写成统一口径。 +3. 然后做 `S5-03`,把战斗结算后的耐久扣减与库存回写接进主链路。 +4. 最后做 `S5-04`,补齐参战拦截、UI 提示与 `0` 耐久失效闭环。 + ## 阶段 S6 - 回归与文档收尾 | 状态 | ID | 任务 | 交付物路径 | 验收标准 | @@ -235,15 +276,16 @@ 2. `S2` 已完成口径对齐,`NodeMapForm` 不再作为 M1 阻塞项。 3. 接下来优先做 `S3`,补齐出战合法性,解决 `P0-10`。 4. 再做 `S4`,统一品质 / Tag 的规则口径,解决 `P0-11`。其中当前优先级已经收口为:`S4-06` 已完成,下一步转入 `S4-07` 的数据表映射。 -5. 最后做 `S5`,决定耐久是完整收口还是同步缩范围,解决 `P0-12`。 +5. 最后做 `S5`,按“最小耐久闭环”收口真实扣减、归零失效与参战拦截,解决 `P0-12`。 6. 全部完成后做 `S6`,补测试并同步文档状态。 ## 本周建议开工顺序 1. `S1` 与 `S2` 已完成口径收口,可直接进入规则侧收尾 2. `S3-01 ~ S3-04` 已完成,当前可转入 `S4` -3. 当前转入 `S4-07`,把 `TagRule` / DataTable 映射真正接进运行时 -4. 然后补 `S6-01 ~ S6-04` +3. 当前先完成 `S4-07` 的三表口径收口,并把 `Tag.txt` / `TagConfig.txt` / `RarityTagBudget.txt` 的实际消费链稳定下来 +4. 然后转入 `S5-01 ~ S5-04`,按“最小耐久闭环”推进耐久真实生效 +5. 最后补 `S6-01 ~ S6-04` ## 备注 diff --git a/docs/TODO.md b/docs/TODO.md index 1778982..a10b7a5 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -9,13 +9,13 @@ 2. 每项任务必须同时满足“交付物路径”和“验收标准”才可打勾。 3. 数据驱动优先:数值、掉落、商店、事件都优先落到 `DataTables`。 -## M1 当前口径(2026-03-09) +## M1 当前口径(2026-03-11) - 当前仓库已经具备 `ProcedureMain + NodeMapForm + CombatNode + EventNode + ShopNode` 的主流程 Run 闭环,可以从主菜单进入游戏,完成固定 10 节点流程,并在 Boss 结算后进入正式结束态并回到主菜单。 - `NodeMapForm` 已满足 MVP 所需的节点流程界面;M1 现在的真实缺口是合法出战 / 品质 / Tag / 耐久规则是否真正统一收口。 -- `P0-10 ~ P0-12` 在代码里都已有局部实现,因此文档里统一按“部分完成但未收口”处理;只有满足最终验收标准后才可改成完成。 -- `P0-11` 在 M1 中按“规则最小闭环”收口:只要求品质计算与 Tag 来源形成单一、可复现、跨流程共用的规则入口;配件槽位、Tag 数量 / 等级随机、Tag 战斗效果暂不作为当前 M1 阻塞项。 -- `P0-11` 的 Tag 规则拆分已记录到 `docs/TagSystemDesign.md`:先收口实例生成、塔级汇总与首发 Tag 集合,再决定哪些效果进入战斗链路。 +- `P0-10` 的“三组件完整合法参战”主链已落地:当前参战分配、战斗入口最终校验、失败原因与拦截提示都已接入统一合法性判断入口,但文档仍保留 `[~]`,直到与 `docs/CodeX-TODO.md` 的验收口径完全同步。 +- `P0-11` 已不再只是“局部展示字段”:当前品质计算、Tag 生成、塔级 Tag 汇总、首发 7 个 Tag 的战斗效果、以及 `Tag.txt + RarityTagBudget.txt + TagConfig.txt` 三表驱动链路都已存在;剩余缺口主要是 `S4-07` 的最终文档口径与少量配置收口,而不是主功能缺失。 +- `P0-12` 仍是当前 M1 最明确的规则缺口:已有耐久字段、展示与部分扣减入口,但还没有形成“战斗后真实扣减 -> 归零失效 -> 参战拦截”的最小闭环。 ## 里程碑 M1(P0)- 最小可玩闭环 @@ -30,9 +30,9 @@ | [x] | P0-07 | 战斗节点基础玩法:放置塔、出怪、基地扣血、胜负判定 | `Assets/GameMain/Scripts/Entity/`
`Assets/GameMain/Scripts/Scene/` | 可完整打一场并得到胜利/失败结果 | | [x] | P0-08 | 胜利波次与结算规则(100/80/50/<50) | `Assets/GameMain/Scripts/Procedure/` | 结算奖励与惩罚严格匹配设计文档 | | [x] | P0-09 | 敌人掉落与关卡奖励(组件/配件/金币) | `Assets/GameMain/Scripts/Entity/` | 战斗结束能发放掉落并写入库存 | -| [~] | P0-10 | 节点后组装:枪口/轴承/底座三组件约束 | `Assets/GameMain/Scripts/Entity/`
`Assets/GameMain/Scripts/UI/Templates/GameScene/` | 当前只校验“参与区至少有 1 座塔”,尚未收口为“三组件完整合法参战” | -| [~] | P0-11 | 品质 / Tag 规则统一入口(白绿蓝紫红) | `Assets/GameMain/Scripts/Definition/`
`Assets/GameMain/Scripts/Entity/` | 品质计算与 Tag 来源在组装、掉落、商店、展示链路形成单一、可复现、跨流程共用的规则入口;配件槽位与 Tag 深度规则暂不作为当前 M1 阻塞项 | -| [~] | P0-12 | 组件/配件耐久生效与 0 耐久销毁 | `Assets/GameMain/Scripts/Entity/` | 已有耐久字段、展示与扣减入口,但尚未影响属性 / 出战资格,也未形成 `0` 耐久移除或失效闭环 | +| [~] | P0-10 | 节点后组装:枪口/轴承/底座三组件约束 | `Assets/GameMain/Scripts/Entity/`
`Assets/GameMain/Scripts/UI/Templates/GameScene/` | 当前已形成“三组件完整合法参战”的统一校验链与战斗入口拦截;剩余工作主要是同步文档口径与收尾验收 | +| [~] | P0-11 | 品质 / Tag 规则统一入口(白绿蓝紫红) | `Assets/GameMain/Scripts/Definition/`
`Assets/GameMain/Scripts/Entity/` | 当前已完成品质统一、Tag 生成/汇总/展示与首发 7 个 Tag 的战斗生效;剩余工作主要是三表方案的最终收口与文档同步 | +| [~] | P0-12 | 组件/配件耐久生效与 0 耐久销毁 | `Assets/GameMain/Scripts/Entity/` | 当前按“最小耐久闭环”推进:目标是形成战斗后真实扣减、`0` 耐久失效与参战拦截;维修系统、自动销毁等后续深度规则暂不作为本阶段阻塞项 | ## 里程碑 M2(P1)- 核心深度 @@ -63,9 +63,9 @@ ## 本周建议开工顺序 -1. 先完成 `P0-10`(把“至少有参战塔”提升为“满足完整合法参战条件才能出战”) -2. 再处理 `P0-11` ~ `P0-12`(先统一 M1 范围;`P0-11` 先收口品质 / Tag 的最小规则闭环,再决定是否扩展到完整深度设计) -3. 最后补关键流程 / 规则回归测试,并同步文档状态 +1. 先完成 `P0-11` 的三表口径收口,把 `Tag.txt + RarityTagBudget.txt + TagConfig.txt` 的实际消费链与文档彻底对齐 +2. 再推进 `P0-12`,按“最小耐久闭环”实现战斗后真实扣减、`0` 耐久失效与参战拦截 +3. 最后补关键流程 / 规则回归测试,并同步 `docs/TODO.md` 与 `docs/CodeX-TODO.md` 的真实状态 ## 设计优化 Backlog(新增) diff --git a/docs/TagSystemDesign.md b/docs/TagSystemDesign.md index b329aed..d06e010 100644 --- a/docs/TagSystemDesign.md +++ b/docs/TagSystemDesign.md @@ -448,7 +448,7 @@ Tag 触发阶段固定拆成四段: 1. 先基于本设计回写 `docs/CodeX-TODO.md` 的 `S4-03` 边界 2. 在 `S4-07` 中补齐并消费 `Tag.txt + RarityTagBudget.txt + TagConfig.txt` 三层表结构 -3. 新增 `TagGenerationService`,先收口实例生成 +3. 新增 `ComponentTagGenerationService`,先收口实例生成 4. 新增 `TowerTagAggregationService`,替换当前简单并集逻辑 5. 评估 `AttackPayload` 是否并入现有 `BulletData`,还是单独引入 6. 第一批只落固定 7 个基础 Tag,避免超出 `MVP-Scope` diff --git a/数据表/RarityTagBudget.xlsx b/数据表/RarityTagBudget.xlsx deleted file mode 100644 index 894d84f..0000000 Binary files a/数据表/RarityTagBudget.xlsx and /dev/null differ diff --git a/数据表/Tag.xlsx b/数据表/Tag.xlsx deleted file mode 100644 index 9b23883..0000000 Binary files a/数据表/Tag.xlsx and /dev/null differ diff --git a/数据表/TagDefine.xlsx b/数据表/TagDefine.xlsx new file mode 100644 index 0000000..9e25ffb Binary files /dev/null and b/数据表/TagDefine.xlsx differ