- S4-03 | 先固化 Tag 系统设计与首发范围

- S4-04 | 实现组件实例 Tag 的统一生成入口
- S4-05 | 实现组塔后的 Tag 汇总与展示入口
This commit is contained in:
SepComet
2026-03-09 21:06:43 +08:00
parent 73b7adedb8
commit 34ef001ef3
31 changed files with 1280 additions and 178 deletions
@@ -16,11 +16,13 @@ namespace GeometryTD.UI
private readonly List<GoodsItemRawData> _currentGoods = new List<GoodsItemRawData>(GoodsCount);
private readonly List<DRShopPrice> _shopPriceRows = new List<DRShopPrice>();
private readonly Dictionary<TagType, RarityType> _tagMinRarityByTag = new Dictionary<TagType, RarityType>();
private IDataTable<DRShopPrice> _shopPriceTable;
private IDataTable<DRMuzzleComp> _muzzleCompTable;
private IDataTable<DRBearingComp> _bearingCompTable;
private IDataTable<DRBaseComp> _baseCompTable;
private IDataTable<DRTag> _tagTable;
public bool PrepareForOpen()
{
@@ -99,8 +101,9 @@ namespace GeometryTD.UI
_muzzleCompTable ??= GameEntry.DataTable.GetDataTable<DRMuzzleComp>();
_bearingCompTable ??= GameEntry.DataTable.GetDataTable<DRBearingComp>();
_baseCompTable ??= GameEntry.DataTable.GetDataTable<DRBaseComp>();
_tagTable ??= GameEntry.DataTable.GetDataTable<DRTag>();
if (_shopPriceTable == null || _muzzleCompTable == null || _bearingCompTable == null || _baseCompTable == null)
if (_shopPriceTable == null || _muzzleCompTable == null || _bearingCompTable == null || _baseCompTable == null || _tagTable == null)
{
Log.Warning("ShopFormUseCase.EnsureTables() failed. Missing required data tables.");
return false;
@@ -124,10 +127,13 @@ namespace GeometryTD.UI
}
}
EnsureTagMinRarityLookup();
return _shopPriceRows.Count > 0 &&
_muzzleCompTable.Count > 0 &&
_bearingCompTable.Count > 0 &&
_baseCompTable.Count > 0;
_baseCompTable.Count > 0 &&
_tagMinRarityByTag.Count > 0;
}
private bool TryBuildRandomGoodsItem(int goodsIndex, out GoodsItemRawData goodsItem)
@@ -176,15 +182,23 @@ namespace GeometryTD.UI
{
DRMuzzleComp[] rows = _muzzleCompTable.GetAllDataRows();
DRMuzzleComp config = rows[UnityEngine.Random.Range(0, rows.Length)];
long instanceId = _nextTempInstanceId++;
RarityType normalizedRarity = InventoryRarityRuleService.NormalizeComponentRarity(rarity);
return new MuzzleCompItemData
{
InstanceId = _nextTempInstanceId++,
InstanceId = instanceId,
ConfigId = config.Id,
Name = config.Name,
Rarity = InventoryRarityRuleService.NormalizeComponentRarity(rarity),
Rarity = normalizedRarity,
Endurance = 100f,
Constraint = config.Constraint,
Tags = config.PossibleTag != null ? (TagType[])config.PossibleTag.Clone() : Array.Empty<TagType>(),
Tags = InventoryTagRuleService.ResolveComponentTags(
config.PossibleTag,
normalizedRarity,
InventoryTagSourceType.Shop,
instanceId,
config.Id,
_tagMinRarityByTag),
AttackDamage = config.AttackDamage != null ? (int[])config.AttackDamage.Clone() : Array.Empty<int>(),
DamageRandomRate = config.DamageRandomRate,
AttackMethodType = config.AttackMethodType
@@ -195,15 +209,23 @@ namespace GeometryTD.UI
{
DRBearingComp[] rows = _bearingCompTable.GetAllDataRows();
DRBearingComp config = rows[UnityEngine.Random.Range(0, rows.Length)];
long instanceId = _nextTempInstanceId++;
RarityType normalizedRarity = InventoryRarityRuleService.NormalizeComponentRarity(rarity);
return new BearingCompItemData
{
InstanceId = _nextTempInstanceId++,
InstanceId = instanceId,
ConfigId = config.Id,
Name = config.Name,
Rarity = InventoryRarityRuleService.NormalizeComponentRarity(rarity),
Rarity = normalizedRarity,
Endurance = 100f,
Constraint = config.Constraint,
Tags = config.PossibleTag != null ? (TagType[])config.PossibleTag.Clone() : Array.Empty<TagType>(),
Tags = InventoryTagRuleService.ResolveComponentTags(
config.PossibleTag,
normalizedRarity,
InventoryTagSourceType.Shop,
instanceId,
config.Id,
_tagMinRarityByTag),
RotateSpeed = config.RotateSpeed != null ? (float[])config.RotateSpeed.Clone() : Array.Empty<float>(),
AttackRange = config.AttackRange != null ? (float[])config.AttackRange.Clone() : Array.Empty<float>()
};
@@ -213,20 +235,49 @@ namespace GeometryTD.UI
{
DRBaseComp[] rows = _baseCompTable.GetAllDataRows();
DRBaseComp config = rows[UnityEngine.Random.Range(0, rows.Length)];
long instanceId = _nextTempInstanceId++;
RarityType normalizedRarity = InventoryRarityRuleService.NormalizeComponentRarity(rarity);
return new BaseCompItemData
{
InstanceId = _nextTempInstanceId++,
InstanceId = instanceId,
ConfigId = config.Id,
Name = config.Name,
Rarity = InventoryRarityRuleService.NormalizeComponentRarity(rarity),
Rarity = normalizedRarity,
Endurance = 100f,
Constraint = config.Constraint,
Tags = config.PossibleTag != null ? (TagType[])config.PossibleTag.Clone() : Array.Empty<TagType>(),
Tags = InventoryTagRuleService.ResolveComponentTags(
config.PossibleTag,
normalizedRarity,
InventoryTagSourceType.Shop,
instanceId,
config.Id,
_tagMinRarityByTag),
AttackSpeed = config.AttackSpeed != null ? (float[])config.AttackSpeed.Clone() : Array.Empty<float>(),
AttackPropertyType = config.AttackPropertyType
};
}
private void EnsureTagMinRarityLookup()
{
if (_tagMinRarityByTag.Count > 0 || _tagTable == null)
{
return;
}
DRTag[] rows = _tagTable.GetAllDataRows();
for (int i = 0; i < rows.Length; i++)
{
DRTag row = rows[i];
if (row == null || row.Id <= 0)
{
continue;
}
TagType tagType = (TagType)row.Id;
_tagMinRarityByTag[tagType] = row.MinRarity;
}
}
private int ResolveRandomPrice(RarityType rarity)
{
for (int i = 0; i < _shopPriceRows.Count; i++)