补充参战防御塔进入战斗逻辑

- 将 Inventory 中参战的防御塔数据传递到 CombatSelectForm 中
- 为防御塔的图标展示添加 TowerRepoItem 与 TowerIconArea 适配防御塔的三层 Image
This commit is contained in:
SepComet
2026-03-05 13:44:49 +08:00
parent 9db9aeabcd
commit 8a478982f8
56 changed files with 2507 additions and 467 deletions
@@ -10,8 +10,9 @@ namespace GeometryTD.UI
{
private RepoFormContext BuildContext(RepoFormRawData rawData)
{
_itemContextMap.Clear();
_itemClickActionMap.Clear();
_itemDescSeedMap.Clear();
_compAreaTowerIds.Clear();
if (rawData?.Inventory == null)
{
_participantTowerIds.Clear();
@@ -22,7 +23,8 @@ namespace GeometryTD.UI
Dictionary<long, BearingCompItemData> bearingMap = BuildComponentMap(rawData.Inventory.BearingComponents);
Dictionary<long, BaseCompItemData> baseMap = BuildComponentMap(rawData.Inventory.BaseComponents);
Dictionary<long, TowerItemData> towerMap = BuildTowerMap(rawData.Inventory.Towers);
List<RepoItemContext> items = new List<RepoItemContext>();
List<RepoItemContext> componentItems = new List<RepoItemContext>();
List<TowerRepoItemContext> towerItems = new List<TowerRepoItemContext>();
if (rawData.Inventory.Towers != null)
{
@@ -33,15 +35,9 @@ namespace GeometryTD.UI
continue;
}
AddItemContext(items, new RepoItemContext
{
InstanceId = tower.InstanceId,
CanDrag = true,
EnduranceRate01 = ItemDescUtility.ResolveTowerEnduranceRate(tower, muzzleMap, bearingMap, baseMap),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.None,
IconAreaContext = BuildIconAreaContext(tower)
});
TowerRepoItemContext towerContext = BuildTowerRepoItemContext(tower, muzzleMap, bearingMap, baseMap,
RepoItemClickActionType.OpenDetail, true);
AddTowerItemContext(towerItems, towerContext);
AddItemDescSeed(
tower.InstanceId,
tower.Name,
@@ -60,7 +56,7 @@ namespace GeometryTD.UI
continue;
}
AddItemContext(items, new RepoItemContext
RepoItemContext componentContext = new RepoItemContext
{
InstanceId = item.InstanceId,
CanDrag = true,
@@ -68,7 +64,8 @@ namespace GeometryTD.UI
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.Muzzle,
IconAreaContext = BuildIconAreaContext(item)
});
};
AddComponentItemContext(componentItems, componentContext);
AddItemDescSeed(
item.InstanceId,
item.Name,
@@ -87,7 +84,7 @@ namespace GeometryTD.UI
continue;
}
AddItemContext(items, new RepoItemContext
RepoItemContext componentContext = new RepoItemContext
{
InstanceId = item.InstanceId,
CanDrag = true,
@@ -95,7 +92,8 @@ namespace GeometryTD.UI
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.Bearing,
IconAreaContext = BuildIconAreaContext(item)
});
};
AddComponentItemContext(componentItems, componentContext);
AddItemDescSeed(
item.InstanceId,
item.Name,
@@ -114,7 +112,7 @@ namespace GeometryTD.UI
continue;
}
AddItemContext(items, new RepoItemContext
RepoItemContext componentContext = new RepoItemContext
{
InstanceId = item.InstanceId,
CanDrag = true,
@@ -122,7 +120,8 @@ namespace GeometryTD.UI
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.Base,
IconAreaContext = BuildIconAreaContext(item)
});
};
AddComponentItemContext(componentItems, componentContext);
AddItemDescSeed(
item.InstanceId,
item.Name,
@@ -140,13 +139,14 @@ namespace GeometryTD.UI
CombineAreaContext = new CombineAreaContext(),
CompAreaContext = new CompAreaContext
{
Items = items.ToArray()
ComponentItems = componentItems.ToArray(),
TowerItems = towerItems.ToArray()
},
ParticipantAreaContext = participantAreaContext
};
}
private void AddItemContext(List<RepoItemContext> items, RepoItemContext itemContext)
private void AddComponentItemContext(List<RepoItemContext> items, RepoItemContext itemContext)
{
if (itemContext == null)
{
@@ -154,7 +154,19 @@ namespace GeometryTD.UI
}
items.Add(itemContext);
_itemContextMap[itemContext.InstanceId] = itemContext;
_itemClickActionMap[itemContext.InstanceId] = itemContext.ClickActionType;
}
private void AddTowerItemContext(List<TowerRepoItemContext> items, TowerRepoItemContext itemContext)
{
if (itemContext == null)
{
return;
}
items.Add(itemContext);
_itemClickActionMap[itemContext.InstanceId] = itemContext.ClickActionType;
_compAreaTowerIds.Add(itemContext.InstanceId);
}
private void AddItemDescSeed(long itemId, string title, string typeText, string description, TagType[] tags)
@@ -243,7 +255,7 @@ namespace GeometryTD.UI
IReadOnlyDictionary<long, BaseCompItemData> baseMap)
{
_participantTowerIds.Clear();
List<RepoItemContext> participantItems = new List<RepoItemContext>();
List<TowerRepoItemContext> participantItems = new List<TowerRepoItemContext>();
if (inventory?.ParticipantTowerInstanceIds != null && towerMap != null)
{
for (int i = 0; i < inventory.ParticipantTowerInstanceIds.Count; i++)
@@ -264,41 +276,33 @@ namespace GeometryTD.UI
continue;
}
participantItems.Add(new RepoItemContext
TowerRepoItemContext towerContext = BuildTowerRepoItemContext(tower, muzzleMap, bearingMap, baseMap,
RepoItemClickActionType.RemoveParticipant, false);
if (towerContext != null)
{
InstanceId = tower.InstanceId,
CanDrag = false,
EnduranceRate01 = ItemDescUtility.ResolveTowerEnduranceRate(tower, muzzleMap, bearingMap, baseMap),
ClickActionType = RepoItemClickActionType.RemoveParticipant,
ComponentSlotType = TowerCompSlotType.None,
IconAreaContext = BuildIconAreaContext(tower)
});
participantItems.Add(towerContext);
_itemClickActionMap[towerContext.InstanceId] = towerContext.ClickActionType;
}
}
}
return new ParticipantAreaContext
{
Items = participantItems.ToArray(),
TowerItems = participantItems.ToArray(),
MaxCount = MaxParticipantCount
};
}
private void ApplyParticipantSelection()
{
if (Form == null || _itemContextMap.Count <= 0)
if (Form == null || _compAreaTowerIds.Count <= 0)
{
return;
}
foreach (KeyValuePair<long, RepoItemContext> pair in _itemContextMap)
foreach (long towerId in _compAreaTowerIds)
{
RepoItemContext itemContext = pair.Value;
if (itemContext == null || itemContext.ComponentSlotType != TowerCompSlotType.None)
{
continue;
}
Form.SetRepoItemSelected(pair.Key, _participantTowerIds.Contains(pair.Key));
Form.SetRepoItemSelected(towerId, _participantTowerIds.Contains(towerId));
}
}
@@ -319,25 +323,33 @@ namespace GeometryTD.UI
ApplyParticipantSelection();
}
private static IconAreaContext BuildIconAreaContext(TowerItemData tower)
private static TowerRepoItemContext BuildTowerRepoItemContext(
TowerItemData tower,
IReadOnlyDictionary<long, MuzzleCompItemData> muzzleMap,
IReadOnlyDictionary<long, BearingCompItemData> bearingMap,
IReadOnlyDictionary<long, BaseCompItemData> baseMap,
RepoItemClickActionType clickActionType,
bool canDrag)
{
if (tower == null)
{
return new IconAreaContext
{
ComponentSlotType = TowerCompSlotType.None,
Rarity = RarityType.None,
Color = Color.white,
Icon = null
};
return null;
}
return new IconAreaContext
return new TowerRepoItemContext
{
InstanceId = tower.InstanceId,
CanDrag = canDrag,
EnduranceRate01 = ItemDescUtility.ResolveTowerEnduranceRate(tower, muzzleMap, bearingMap, baseMap),
ClickActionType = clickActionType,
ComponentSlotType = TowerCompSlotType.None,
Rarity = tower.Rarity,
Color = IconColorGenerator.GenerateForTower(tower),
Icon = null
IconAreaContext = new TowerIconAreaContext
{
Rarity = tower.Rarity,
MuzzleColor = ResolveComponentColor(tower.MuzzleComponentInstanceId, muzzleMap),
BearingColor = ResolveComponentColor(tower.BearingComponentInstanceId, bearingMap),
BaseColor = ResolveComponentColor(tower.BaseComponentInstanceId, baseMap)
}
};
}
@@ -362,5 +374,21 @@ namespace GeometryTD.UI
Icon = null
};
}
private static Color ResolveComponentColor<TComp>(long instanceId,
IReadOnlyDictionary<long, TComp> componentMap)
where TComp : TowerCompItemData
{
if (instanceId > 0 &&
componentMap != null &&
componentMap.TryGetValue(instanceId, out TComp component) &&
component != null)
{
return IconColorGenerator.GenerateForComponent(component);
}
return Color.white;
}
}
}
@@ -11,9 +11,11 @@ namespace GeometryTD.UI
{
private const int MaxParticipantCount = 4;
private RepoFormUseCase _useCase;
private readonly Dictionary<long, RepoItemContext> _itemContextMap = new Dictionary<long, RepoItemContext>();
private readonly Dictionary<long, RepoItemClickActionType> _itemClickActionMap =
new Dictionary<long, RepoItemClickActionType>();
private readonly Dictionary<long, ItemDescSeed> _itemDescSeedMap = new Dictionary<long, ItemDescSeed>();
private readonly HashSet<long> _participantTowerIds = new HashSet<long>();
private readonly HashSet<long> _compAreaTowerIds = new HashSet<long>();
private sealed class ItemDescSeed
{
@@ -111,14 +113,9 @@ namespace GeometryTD.UI
}
RepoItemClickActionType clickActionType = RepoItemClickActionType.OpenDetail;
if (sender is RepoItem clickedItem && clickedItem.Context != null)
if (_itemClickActionMap.TryGetValue(args.ItemId, out RepoItemClickActionType mappedAction))
{
clickActionType = clickedItem.Context.ClickActionType;
}
else if (_itemContextMap.TryGetValue(args.ItemId, out RepoItemContext itemContextFromMap) &&
itemContextFromMap != null)
{
clickActionType = itemContextFromMap.ClickActionType;
clickActionType = mappedAction;
}
if (args.ItemId <= 0)
@@ -170,7 +167,7 @@ namespace GeometryTD.UI
return;
}
if (Form == null || !_itemContextMap.ContainsKey(args.ItemId))
if (Form == null || !_itemClickActionMap.ContainsKey(args.ItemId))
{
return;
}
@@ -212,8 +209,8 @@ namespace GeometryTD.UI
{
return;
}
this.CloseUI();
CloseUI();
}
private void OnRepoCombineRequested(object sender, GameEventArgs e)
@@ -258,12 +255,12 @@ namespace GeometryTD.UI
{
return;
}
if (_useCase == null || Form == null || args.TowerItemId <= 0)
{
return;
}
if (!_useCase.TryAddParticipantTower(args.TowerItemId))
{
return;