为 RepoForm 添加出售功能,ShopNode 只承载玩家购买组件的逻辑

This commit is contained in:
2026-03-16 17:52:23 +08:00
parent dc2aa59d58
commit 2e54acbc85
33 changed files with 3198 additions and 91 deletions
@@ -23,21 +23,44 @@ 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);
HashSet<long> selectedSellItemIds = BuildSelectedSellItemSet(rawData.SelectedSellItemIds);
bool isSellState = rawData.State == RepoFormState.Sell;
List<RepoItemContext> componentItems = new List<RepoItemContext>();
List<TowerRepoItemContext> towerItems = new List<TowerRepoItemContext>();
List<RepoItemContext> selectedSellComponentItems = new List<RepoItemContext>();
List<TowerRepoItemContext> selectedSellTowerItems = new List<TowerRepoItemContext>();
if (rawData.Inventory.Towers != null)
{
foreach (var tower in rawData.Inventory.Towers)
foreach (TowerItemData tower in rawData.Inventory.Towers)
{
if (tower == null)
{
continue;
}
TowerRepoItemContext towerContext = BuildTowerRepoItemContext(tower, muzzleMap, bearingMap, baseMap,
RepoItemClickActionType.OpenDetail, true);
bool isParticipantTower = rawData.Inventory.ParticipantTowerInstanceIds != null &&
rawData.Inventory.ParticipantTowerInstanceIds.Contains(tower.InstanceId);
bool isSellSelected = isSellState && selectedSellItemIds.Contains(tower.InstanceId);
TowerRepoItemContext towerContext = BuildTowerRepoItemContext(
tower,
muzzleMap,
bearingMap,
baseMap,
RepoItemClickActionType.OpenDetail,
!isSellState,
isSellState,
!isParticipantTower,
isSellSelected,
false);
AddTowerItemContext(towerItems, towerContext);
if (isSellSelected)
{
selectedSellTowerItems.Add(towerContext);
}
AddItemDescSeed(
tower.InstanceId,
tower.Name,
@@ -50,23 +73,24 @@ namespace GeometryTD.UI
if (rawData.Inventory.MuzzleComponents != null)
{
foreach (var item in rawData.Inventory.MuzzleComponents)
foreach (MuzzleCompItemData item in rawData.Inventory.MuzzleComponents)
{
if (item == null || item.IsAssembledIntoTower)
{
continue;
}
RepoItemContext componentContext = new RepoItemContext
{
InstanceId = item.InstanceId,
CanDrag = true,
EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.Muzzle,
IconAreaContext = BuildIconAreaContext(item)
};
RepoItemContext componentContext = BuildSellableComponentContext(
item,
TowerCompSlotType.Muzzle,
isSellState,
selectedSellItemIds.Contains(item.InstanceId));
AddComponentItemContext(componentItems, componentContext);
if (componentContext.IsSellSelected)
{
selectedSellComponentItems.Add(componentContext);
}
AddItemDescSeed(
item.InstanceId,
item.Name,
@@ -86,16 +110,17 @@ namespace GeometryTD.UI
continue;
}
RepoItemContext componentContext = new RepoItemContext
{
InstanceId = item.InstanceId,
CanDrag = true,
EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.Bearing,
IconAreaContext = BuildIconAreaContext(item)
};
RepoItemContext componentContext = BuildSellableComponentContext(
item,
TowerCompSlotType.Bearing,
isSellState,
selectedSellItemIds.Contains(item.InstanceId));
AddComponentItemContext(componentItems, componentContext);
if (componentContext.IsSellSelected)
{
selectedSellComponentItems.Add(componentContext);
}
AddItemDescSeed(
item.InstanceId,
item.Name,
@@ -115,16 +140,17 @@ namespace GeometryTD.UI
continue;
}
RepoItemContext componentContext = new RepoItemContext
{
InstanceId = item.InstanceId,
CanDrag = true,
EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = TowerCompSlotType.Base,
IconAreaContext = BuildIconAreaContext(item)
};
RepoItemContext componentContext = BuildSellableComponentContext(
item,
TowerCompSlotType.Base,
isSellState,
selectedSellItemIds.Contains(item.InstanceId));
AddComponentItemContext(componentItems, componentContext);
if (componentContext.IsSellSelected)
{
selectedSellComponentItems.Add(componentContext);
}
AddItemDescSeed(
item.InstanceId,
item.Name,
@@ -141,7 +167,19 @@ namespace GeometryTD.UI
return new RepoFormContext
{
GoldText = $"金币: {rawData.Inventory.Gold}",
State = rawData.State,
ShowSellModeButton = rawData.State == RepoFormState.Assemble,
SellModeButtonText = "出售模式",
ShowCombineArea = rawData.State == RepoFormState.Assemble,
ShowSellArea = rawData.State == RepoFormState.Sell,
CombineAreaContext = new CombineAreaContext(),
SellAreaContext = new SellAreaContext
{
TotalPriceText = $"总价值: {rawData.SelectedSellTotalPrice}",
CanConfirmSell = rawData.State == RepoFormState.Sell && rawData.SelectedSellItemCount > 0,
ComponentItems = selectedSellComponentItems.ToArray(),
TowerItems = selectedSellTowerItems.ToArray()
},
CompAreaContext = new CompAreaContext
{
ComponentItems = componentItems.ToArray(),
@@ -151,6 +189,26 @@ namespace GeometryTD.UI
};
}
private static RepoItemContext BuildSellableComponentContext(
TowerCompItemData item,
TowerCompSlotType slotType,
bool isSellState,
bool isSellSelected)
{
return new RepoItemContext
{
InstanceId = item.InstanceId,
CanDrag = !isSellState,
EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item),
ClickActionType = RepoItemClickActionType.OpenDetail,
ComponentSlotType = slotType,
IsSellMode = isSellState,
IsSellable = true,
IsSellSelected = isSellState && isSellSelected,
IconAreaContext = BuildIconAreaContext(item)
};
}
private void AddComponentItemContext(List<RepoItemContext> items, RepoItemContext itemContext)
{
if (itemContext == null)
@@ -218,7 +276,7 @@ namespace GeometryTD.UI
return map;
}
foreach (var item in items)
foreach (TComp item in items)
{
if (item == null || item.InstanceId <= 0)
{
@@ -231,6 +289,26 @@ namespace GeometryTD.UI
return map;
}
private static HashSet<long> BuildSelectedSellItemSet(IReadOnlyList<long> selectedSellItemIds)
{
HashSet<long> selectedIds = new HashSet<long>();
if (selectedSellItemIds == null)
{
return selectedIds;
}
for (int i = 0; i < selectedSellItemIds.Count; i++)
{
long itemId = selectedSellItemIds[i];
if (itemId > 0)
{
selectedIds.Add(itemId);
}
}
return selectedIds;
}
private static Dictionary<long, TowerItemData> BuildTowerMap(IReadOnlyList<TowerItemData> towers)
{
Dictionary<long, TowerItemData> map = new Dictionary<long, TowerItemData>();
@@ -239,7 +317,7 @@ namespace GeometryTD.UI
return map;
}
foreach (var tower in towers)
foreach (TowerItemData tower in towers)
{
if (tower == null || tower.InstanceId <= 0)
{
@@ -263,7 +341,7 @@ namespace GeometryTD.UI
List<TowerRepoItemContext> participantItems = new List<TowerRepoItemContext>();
if (inventory?.ParticipantTowerInstanceIds != null && towerMap != null)
{
foreach (var towerId in inventory.ParticipantTowerInstanceIds)
foreach (long towerId in inventory.ParticipantTowerInstanceIds)
{
if (towerId <= 0)
{
@@ -280,8 +358,17 @@ namespace GeometryTD.UI
continue;
}
TowerRepoItemContext towerContext = BuildTowerRepoItemContext(tower, muzzleMap, bearingMap, baseMap,
RepoItemClickActionType.RemoveParticipant, false);
TowerRepoItemContext towerContext = BuildTowerRepoItemContext(
tower,
muzzleMap,
bearingMap,
baseMap,
RepoItemClickActionType.RemoveParticipant,
false,
false,
false,
false,
false);
if (towerContext != null)
{
participantItems.Add(towerContext);
@@ -304,6 +391,11 @@ namespace GeometryTD.UI
return;
}
if (Context != null && Context.State == RepoFormState.Sell)
{
return;
}
foreach (long towerId in _compAreaTowerIds)
{
Form.SetRepoItemSelected(towerId, _participantTowerIds.Contains(towerId));
@@ -334,7 +426,11 @@ namespace GeometryTD.UI
IReadOnlyDictionary<long, BearingCompItemData> bearingMap,
IReadOnlyDictionary<long, BaseCompItemData> baseMap,
RepoItemClickActionType clickActionType,
bool canDrag)
bool canDrag,
bool isSellMode,
bool isSellable,
bool isSellSelected,
bool highlightSelected)
{
if (tower == null)
{
@@ -348,6 +444,9 @@ namespace GeometryTD.UI
EnduranceRate01 = ItemDescUtility.ResolveTowerEnduranceRate(tower, muzzleMap, bearingMap, baseMap),
ClickActionType = clickActionType,
ComponentSlotType = TowerCompSlotType.None,
IsSellMode = isSellMode,
IsSellable = isSellable,
IsSellSelected = isSellSelected || highlightSelected,
IconAreaContext = new TowerIconAreaContext
{
Rarity = tower.Rarity,