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

- 将 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,5 +10,6 @@ namespace GeometryTD.UI
public bool IsInteractable;
public CombatSelectActionType ActionType;
public int ActionIndex;
public TowerIconAreaContext TowerIconAreaContext;
}
}
@@ -116,9 +116,8 @@ namespace GeometryTD.UI
if (inventory.Towers != null)
{
for (int i = 0; i < inventory.Towers.Count; i++)
foreach (TowerItemData tower in inventory.Towers)
{
var tower = inventory.Towers[i];
if (tower == null)
{
continue;
@@ -131,7 +130,7 @@ namespace GeometryTD.UI
EnduranceRate01 = ItemDescUtility.ResolveTowerEnduranceRate(tower, muzzleMap, bearingMap, baseMap),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.None,
IconAreaContext = BuildIconAreaContext(tower)
IconAreaContext = BuildTowerIconContext(tower, muzzleMap, bearingMap, baseMap)
});
AddItemDescSeed(
@@ -145,9 +144,8 @@ namespace GeometryTD.UI
if (inventory.MuzzleComponents != null)
{
for (int i = 0; i < inventory.MuzzleComponents.Count; i++)
foreach (MuzzleCompItemData item in inventory.MuzzleComponents)
{
var item = inventory.MuzzleComponents[i];
if (item == null)
{
continue;
@@ -174,7 +172,7 @@ namespace GeometryTD.UI
if (inventory.BearingComponents != null)
{
foreach (var item in inventory.BearingComponents)
foreach (BearingCompItemData item in inventory.BearingComponents)
{
if (item == null)
{
@@ -202,9 +200,8 @@ namespace GeometryTD.UI
if (inventory.BaseComponents != null)
{
for (int i = 0; i < inventory.BaseComponents.Count; i++)
foreach (BaseCompItemData item in inventory.BaseComponents)
{
var item = inventory.BaseComponents[i];
if (item == null)
{
continue;
@@ -232,6 +229,38 @@ namespace GeometryTD.UI
return itemContexts.ToArray();
}
private static TowerIconAreaContext BuildTowerIconContext(
TowerItemData tower,
IReadOnlyDictionary<long, MuzzleCompItemData> muzzleMap,
IReadOnlyDictionary<long, BearingCompItemData> bearingMap,
IReadOnlyDictionary<long, BaseCompItemData> baseMap)
{
if (tower == null)
{
return null;
}
return new TowerIconAreaContext
{
Rarity = tower.Rarity,
MuzzleColor = ResolveComponentColor(tower.MuzzleComponentInstanceId, muzzleMap),
BearingColor = ResolveComponentColor(tower.BearingComponentInstanceId, bearingMap),
BaseColor = ResolveComponentColor(tower.BaseComponentInstanceId, baseMap)
};
}
private static Color ResolveComponentColor<TComp>(long instanceId, IReadOnlyDictionary<long, TComp> componentMap)
where TComp : TowerCompItemData
{
if (instanceId > 0 && componentMap != null && componentMap.TryGetValue(instanceId, out TComp comp) &&
comp != null)
{
return IconColorGenerator.GenerateForComponent(comp);
}
return Color.white;
}
private void AddItemDescSeed(long itemId, string title, string typeText, string description, TagType[] tags)
{
if (itemId <= 0)
@@ -274,9 +303,8 @@ namespace GeometryTD.UI
return map;
}
for (int i = 0; i < items.Count; i++)
foreach (TComp item in items)
{
TComp item = items[i];
if (item == null || item.InstanceId <= 0)
{
continue;
@@ -288,35 +316,13 @@ namespace GeometryTD.UI
return map;
}
private static IconAreaContext BuildIconAreaContext(TowerItemData tower)
{
if (tower == null)
{
return new IconAreaContext
{
ComponentSlotType = TowerCompSlotType.None,
Rarity = RarityType.None,
Color = Color.white,
Icon = null
};
}
return new IconAreaContext
{
ComponentSlotType = TowerCompSlotType.None,
Rarity = tower.Rarity,
Color = IconColorGenerator.GenerateForTower(tower),
Icon = null
};
}
private static IconAreaContext BuildIconAreaContext(TowerCompItemData item)
{
if (item == null)
{
return new IconAreaContext
{
ComponentSlotType = TowerCompSlotType.None,
ComponentSlotType = TowerCompSlotType.None,
Rarity = RarityType.None,
Color = Color.white,
Icon = null
@@ -332,6 +338,8 @@ namespace GeometryTD.UI
};
}
#region Event Handlers
private void OnCombatFinishReturnButtonClicked(object sender, GameEventArgs e)
{
if (!IsEventFromCurrentForm(sender) || !(e is CombatFinishReturnEventArgs))
@@ -370,6 +378,8 @@ namespace GeometryTD.UI
});
}
#endregion
private bool IsEventFromCurrentForm(object sender)
{
if (Form == null)
@@ -392,3 +402,7 @@ namespace GeometryTD.UI
}
}
}
@@ -229,7 +229,13 @@ namespace GeometryTD.UI
IsVisible = rawData.IsVisible,
IsInteractable = rawData.IsInteractable,
ActionType = rawData.ActionType,
ActionIndex = rawData.ActionIndex
ActionIndex = rawData.ActionIndex,
TowerIconAreaContext = new TowerIconAreaContext()
{
BaseColor = rawData.BaseColor,
BearingColor = rawData.BearingColor,
MuzzleColor = rawData.MuzzleColor
}
};
}
@@ -284,4 +290,4 @@ namespace GeometryTD.UI
RefreshFromUseCase();
}
}
}
}
@@ -11,5 +11,9 @@ namespace GeometryTD.UI
public bool IsInteractable;
public CombatSelectActionType ActionType;
public int ActionIndex;
public bool UseTowerLayers;
public Color BaseColor = Color.white;
public Color BearingColor = Color.white;
public Color MuzzleColor = Color.white;
}
}
@@ -42,6 +42,19 @@ namespace GeometryTD.UI
}
public void SetBuildAction(int buildIndex, Func<bool> buildAction, int cost, Sprite icon = null)
{
SetBuildAction(buildIndex, buildAction, cost, icon, false, Color.white, Color.white, Color.white);
}
public void SetBuildAction(
int buildIndex,
Func<bool> buildAction,
int cost,
Sprite icon,
bool useTowerLayers,
Color baseColor,
Color bearingColor,
Color muzzleColor)
{
if (buildIndex < 0 || buildIndex >= _buildOptions.Length)
{
@@ -54,6 +67,10 @@ namespace GeometryTD.UI
option.Icon = icon;
option.IsGain = false;
option.IsVisible = true;
option.UseTowerLayers = useTowerLayers;
option.BaseColor = baseColor;
option.BearingColor = bearingColor;
option.MuzzleColor = muzzleColor;
}
public void SetBuildAction(int buildIndex, Action buildAction, int cost, Sprite icon = null)
@@ -75,6 +92,16 @@ namespace GeometryTD.UI
icon);
}
public void SetBuildVisible(int buildIndex, bool visible)
{
if (buildIndex < 0 || buildIndex >= _buildOptions.Length)
{
return;
}
_buildOptions[buildIndex].IsVisible = visible;
}
public void SetUpgradeAction(Func<bool> upgradeAction, int cost, Sprite icon = null)
{
_upgradeOption.Action = upgradeAction;
@@ -82,6 +109,7 @@ namespace GeometryTD.UI
_upgradeOption.Icon = icon;
_upgradeOption.IsGain = false;
_upgradeOption.IsVisible = true;
_upgradeOption.UseTowerLayers = false;
}
public void SetUpgradeAction(Action upgradeAction, int cost, Sprite icon = null)
@@ -109,6 +137,7 @@ namespace GeometryTD.UI
_destroyOption.Icon = icon;
_destroyOption.IsGain = true;
_destroyOption.IsVisible = true;
_destroyOption.UseTowerLayers = false;
}
public void SetDestroyAction(Action destroyAction, int gain, Sprite icon = null)
@@ -278,7 +307,11 @@ namespace GeometryTD.UI
IsVisible = option.IsVisible,
IsInteractable = option.Action != null && CanExecute(option, currentCoin),
ActionType = option.ActionType,
ActionIndex = option.ActionIndex
ActionIndex = option.ActionIndex,
UseTowerLayers = option.UseTowerLayers,
BaseColor = option.BaseColor,
BearingColor = option.BearingColor,
MuzzleColor = option.MuzzleColor
};
}
@@ -293,6 +326,10 @@ namespace GeometryTD.UI
public bool IsVisible = true;
public Sprite Icon;
public Func<bool> Action;
public bool UseTowerLayers;
public Color BaseColor = Color.white;
public Color BearingColor = Color.white;
public Color MuzzleColor = Color.white;
public Option(CombatSelectActionType actionType, int actionIndex, bool requiresAffordable)
{
@@ -2,20 +2,23 @@ using TMPro;
using UnityEngine;
using UnityEngine.UI;
using GeometryTD.CustomEvent;
using UnityGameFramework.Runtime;
namespace GeometryTD.UI
{
public class TowerSelectItem : MonoBehaviour
{
[SerializeField] private Image _icon;
[SerializeField] private TMP_Text _price;
[SerializeField] private CommonButton _button;
[SerializeField] private TowerIconArea _towerIconArea;
private TowerSelectItemContext _context;
private Sprite _defaultIcon;
private bool _hasCachedDefaultIcon;
public void OnInit(TowerSelectItemContext context)
@@ -23,28 +26,45 @@ namespace GeometryTD.UI
CacheDefaultIcon();
_context = context;
if (_icon != null)
if (context.ActionType == CombatSelectActionType.BuildTower)
{
if (context != null && context.Icon != null)
_icon?.gameObject.SetActive(false);
_towerIconArea?.OnInit(_context.TowerIconAreaContext);
if (_price != null)
{
_icon.sprite = context.Icon;
}
else if (_defaultIcon != null)
{
_icon.sprite = _defaultIcon;
_price.text = context.PriceText ?? string.Empty;
}
_icon.enabled = _icon.sprite != null;
if (_button != null)
{
_button.Interactive = context.IsInteractable;
}
}
if (_price != null)
else if (context.ActionType is CombatSelectActionType.UpgradeTower or CombatSelectActionType.DestroyTower)
{
_price.text = context?.PriceText ?? string.Empty;
if (_icon != null)
{
_icon.sprite = _context.Icon ?? _defaultIcon;
_icon.gameObject.SetActive(true);
}
_towerIconArea?.OnReset();
if (_price != null)
{
_price.text = context.PriceText ?? string.Empty;
}
if (_button != null)
{
_button.Interactive = context.IsInteractable;
}
}
if (_button != null)
else
{
_button.Interactive = context != null && context.IsInteractable;
_icon?.gameObject.SetActive(false);
_towerIconArea?.OnReset();
}
}
@@ -59,6 +79,8 @@ namespace GeometryTD.UI
_icon.enabled = _icon.sprite != null;
}
_towerIconArea.OnReset();
if (_price != null)
{
_price.text = string.Empty;
@@ -93,4 +115,4 @@ namespace GeometryTD.UI
_hasCachedDefaultIcon = true;
}
}
}
}