using System.Collections.Generic; namespace GeometryTD.Definition { public enum CombatParticipantTowerValidationFailureReason { None = 0, TowerMissing = 1, MissingMuzzleComponent = 2, MissingBearingComponent = 3, MissingBaseComponent = 4, BrokenMuzzleComponent = 5, BrokenBearingComponent = 6, BrokenBaseComponent = 7 } public sealed class CombatParticipantTowerValidationResult { public long TowerInstanceId { get; set; } public bool IsValid => FailureReason == CombatParticipantTowerValidationFailureReason.None; public CombatParticipantTowerValidationFailureReason FailureReason { get; set; } public TowerItemData Tower { get; set; } } public sealed class CombatParticipantTowerValidationSummary { public IReadOnlyList ValidTowers { get; set; } = System.Array.Empty(); public IReadOnlyList InvalidResults { get; set; } = System.Array.Empty(); public bool HasAnyValidParticipantTower => ValidTowers != null && ValidTowers.Count > 0; } public static class CombatParticipantTowerValidationService { public static CombatParticipantTowerValidationResult ValidateTower( BackpackInventoryData inventory, long towerInstanceId) { if (!TryGetTowerById(inventory, towerInstanceId, out TowerItemData tower)) { return new CombatParticipantTowerValidationResult { TowerInstanceId = towerInstanceId, FailureReason = CombatParticipantTowerValidationFailureReason.TowerMissing }; } return ValidateTower(inventory, tower); } public static CombatParticipantTowerValidationResult ValidateTower( BackpackInventoryData inventory, TowerItemData tower) { if (tower == null || tower.InstanceId <= 0) { return new CombatParticipantTowerValidationResult { TowerInstanceId = tower != null ? tower.InstanceId : 0, Tower = tower, FailureReason = CombatParticipantTowerValidationFailureReason.TowerMissing }; } if (!TryGetComponentById(inventory?.MuzzleComponents, tower.MuzzleComponentInstanceId, out MuzzleCompItemData muzzleComponent)) { return new CombatParticipantTowerValidationResult { TowerInstanceId = tower.InstanceId, Tower = tower, FailureReason = CombatParticipantTowerValidationFailureReason.MissingMuzzleComponent }; } if (muzzleComponent.Endurance <= 0f) { return new CombatParticipantTowerValidationResult { TowerInstanceId = tower.InstanceId, Tower = tower, FailureReason = CombatParticipantTowerValidationFailureReason.BrokenMuzzleComponent }; } if (!TryGetComponentById(inventory?.BearingComponents, tower.BearingComponentInstanceId, out BearingCompItemData bearingComponent)) { return new CombatParticipantTowerValidationResult { TowerInstanceId = tower.InstanceId, Tower = tower, FailureReason = CombatParticipantTowerValidationFailureReason.MissingBearingComponent }; } if (bearingComponent.Endurance <= 0f) { return new CombatParticipantTowerValidationResult { TowerInstanceId = tower.InstanceId, Tower = tower, FailureReason = CombatParticipantTowerValidationFailureReason.BrokenBearingComponent }; } if (!TryGetComponentById(inventory?.BaseComponents, tower.BaseComponentInstanceId, out BaseCompItemData baseComponent)) { return new CombatParticipantTowerValidationResult { TowerInstanceId = tower.InstanceId, Tower = tower, FailureReason = CombatParticipantTowerValidationFailureReason.MissingBaseComponent }; } if (baseComponent.Endurance <= 0f) { return new CombatParticipantTowerValidationResult { TowerInstanceId = tower.InstanceId, Tower = tower, FailureReason = CombatParticipantTowerValidationFailureReason.BrokenBaseComponent }; } return new CombatParticipantTowerValidationResult { TowerInstanceId = tower.InstanceId, Tower = tower, FailureReason = CombatParticipantTowerValidationFailureReason.None }; } public static CombatParticipantTowerValidationSummary ValidateParticipantTowers(BackpackInventoryData inventory) { List validTowers = new List(); List invalidResults = new List(); HashSet processedTowerIds = new HashSet(); if (inventory?.ParticipantTowerInstanceIds == null || inventory.ParticipantTowerInstanceIds.Count <= 0) { return new CombatParticipantTowerValidationSummary { ValidTowers = validTowers, InvalidResults = invalidResults }; } for (int i = 0; i < inventory.ParticipantTowerInstanceIds.Count; i++) { long towerInstanceId = inventory.ParticipantTowerInstanceIds[i]; if (towerInstanceId <= 0 || !processedTowerIds.Add(towerInstanceId)) { continue; } CombatParticipantTowerValidationResult result = ValidateTower(inventory, towerInstanceId); if (result.IsValid) { validTowers.Add(result.Tower); } else { invalidResults.Add(result); } } return new CombatParticipantTowerValidationSummary { ValidTowers = validTowers, InvalidResults = invalidResults }; } private 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; } private static bool TryGetComponentById( IReadOnlyList components, long componentInstanceId, out TComponent resolvedComponent) where TComponent : TowerCompItemData { resolvedComponent = null; if (components == null || componentInstanceId <= 0) { return false; } for (int i = 0; i < components.Count; i++) { TComponent component = components[i]; if (component != null && component.InstanceId == componentInstanceId) { resolvedComponent = component; return true; } } return false; } } }