using System.Collections.Generic; using GeometryTD.Definition; using UnityEngine; namespace GeometryTD.CustomUtility { public static class InventoryParticipantUtility { public static ParticipantTowerAssignResult TryAddParticipantTower( BackpackInventoryData inventory, long towerInstanceId, int maxCount) { if (inventory == null || towerInstanceId <= 0) { return new ParticipantTowerAssignResult { TowerInstanceId = towerInstanceId, FailureReason = ParticipantTowerAssignFailureReason.TowerMissing, ValidationFailureReason = CombatParticipantTowerValidationFailureReason.None }; } int resolvedMaxCount = Mathf.Max(1, maxCount); NormalizeParticipantState(inventory, resolvedMaxCount); CombatParticipantTowerValidationResult validationResult = CombatParticipantTowerValidationService.ValidateTower(inventory, towerInstanceId); if (!validationResult.IsValid) { return new ParticipantTowerAssignResult { TowerInstanceId = towerInstanceId, FailureReason = validationResult.FailureReason == CombatParticipantTowerValidationFailureReason.TowerMissing ? ParticipantTowerAssignFailureReason.TowerMissing : ParticipantTowerAssignFailureReason.InvalidTower, ValidationFailureReason = validationResult.FailureReason }; } inventory.ParticipantTowerInstanceIds ??= new List(); if (inventory.ParticipantTowerInstanceIds.Contains(towerInstanceId)) { if (validationResult.Tower != null) { validationResult.Tower.IsParticipatingInCombat = true; } return new ParticipantTowerAssignResult { TowerInstanceId = towerInstanceId, FailureReason = ParticipantTowerAssignFailureReason.AlreadyAssigned, ValidationFailureReason = CombatParticipantTowerValidationFailureReason.None }; } if (inventory.ParticipantTowerInstanceIds.Count >= resolvedMaxCount) { return new ParticipantTowerAssignResult { TowerInstanceId = towerInstanceId, FailureReason = ParticipantTowerAssignFailureReason.ParticipantAreaFull, ValidationFailureReason = CombatParticipantTowerValidationFailureReason.None }; } inventory.ParticipantTowerInstanceIds.Add(towerInstanceId); if (validationResult.Tower != null) { validationResult.Tower.IsParticipatingInCombat = true; } return new ParticipantTowerAssignResult { TowerInstanceId = towerInstanceId, FailureReason = ParticipantTowerAssignFailureReason.None, ValidationFailureReason = CombatParticipantTowerValidationFailureReason.None }; } public static bool TryRemoveParticipantTower(BackpackInventoryData inventory, long towerInstanceId, int maxCount) { if (inventory == null || towerInstanceId <= 0) { return false; } NormalizeParticipantState(inventory, maxCount); if (inventory.ParticipantTowerInstanceIds == null) { return false; } bool removed = inventory.ParticipantTowerInstanceIds.Remove(towerInstanceId); if (!removed) { return false; } if (TryGetTowerById(inventory, towerInstanceId, out TowerItemData tower)) { tower.IsParticipatingInCombat = false; } return true; } public static void NormalizeParticipantState(BackpackInventoryData inventory, int maxCount) { if (inventory == null) { return; } int resolvedMaxCount = Mathf.Max(1, maxCount); inventory.ParticipantTowerInstanceIds ??= new List(); Dictionary towerMap = new Dictionary(); if (inventory.Towers != null) { for (int i = 0; i < inventory.Towers.Count; i++) { TowerItemData tower = inventory.Towers[i]; if (tower == null || tower.InstanceId <= 0) { continue; } tower.IsParticipatingInCombat = false; towerMap[tower.InstanceId] = tower; } } HashSet uniqueIds = new HashSet(); List normalizedIds = new List(inventory.ParticipantTowerInstanceIds.Count); for (int i = 0; i < inventory.ParticipantTowerInstanceIds.Count; i++) { if (normalizedIds.Count >= resolvedMaxCount) { break; } long towerId = inventory.ParticipantTowerInstanceIds[i]; if (towerId <= 0 || !uniqueIds.Add(towerId)) { continue; } if (!towerMap.TryGetValue(towerId, out TowerItemData tower)) { continue; } tower.IsParticipatingInCombat = true; normalizedIds.Add(towerId); } inventory.ParticipantTowerInstanceIds = normalizedIds; } public static bool TryGetTowerById(BackpackInventoryData inventory, long towerInstanceId, out TowerItemData tower) { tower = null; if (inventory?.Towers == null || towerInstanceId <= 0) { return false; } for (int i = 0; i < inventory.Towers.Count; i++) { TowerItemData candidate = inventory.Towers[i]; if (candidate != null && candidate.InstanceId == towerInstanceId) { tower = candidate; return true; } } return false; } } }