using GeometryTD.Definition; namespace GeometryTD.UI { public class RepoFormUseCase : IUIUseCase { private const int MaxParticipantCount = 4; private BackpackInventoryData _fallbackInventory; public RepoFormRawData CreateInitialModel() { BackpackInventoryData sample = GameEntry.PlayerInventory != null ? GameEntry.PlayerInventory.GetInventorySnapshot() : GetOrCreateFallbackInventory(); return new RepoFormRawData { Inventory = sample }; } public bool TryAssembleTower(long muzzleItemId, long bearingItemId, long baseItemId) { if (GameEntry.PlayerInventory == null) { return false; } return GameEntry.PlayerInventory.TryAssembleTower( muzzleItemId, bearingItemId, baseItemId, out _); } public bool TryAddParticipantTower(long towerItemId) { if (GameEntry.PlayerInventory == null) { BackpackInventoryData fallbackInventory = GetOrCreateFallbackInventory(); return TryAddParticipantTowerInternal(fallbackInventory, towerItemId, MaxParticipantCount); } return GameEntry.PlayerInventory.TryAddParticipantTower(towerItemId, 4); } public bool TryRemoveParticipantTower(long towerItemId) { if (GameEntry.PlayerInventory == null) { BackpackInventoryData fallbackInventory = GetOrCreateFallbackInventory(); return TryRemoveParticipantTowerInternal(fallbackInventory, towerItemId); } return GameEntry.PlayerInventory.TryRemoveParticipantTower(towerItemId); } private BackpackInventoryData GetOrCreateFallbackInventory() { _fallbackInventory ??= SampleInventory(); NormalizeParticipantState(_fallbackInventory); return _fallbackInventory; } private static bool TryAddParticipantTowerInternal( BackpackInventoryData inventory, long towerItemId, int maxCount) { if (inventory == null || towerItemId <= 0) { return false; } NormalizeParticipantState(inventory); if (!TryGetTowerById(inventory, towerItemId, out TowerItemData tower)) { return false; } inventory.ParticipantTowerInstanceIds ??= new System.Collections.Generic.List(); if (inventory.ParticipantTowerInstanceIds.Contains(towerItemId)) { tower.IsParticipatingInCombat = true; return false; } if (inventory.ParticipantTowerInstanceIds.Count >= UnityEngine.Mathf.Max(1, maxCount)) { return false; } inventory.ParticipantTowerInstanceIds.Add(towerItemId); tower.IsParticipatingInCombat = true; return true; } private static bool TryRemoveParticipantTowerInternal(BackpackInventoryData inventory, long towerItemId) { if (inventory == null || towerItemId <= 0) { return false; } NormalizeParticipantState(inventory); if (inventory.ParticipantTowerInstanceIds == null) { return false; } bool removed = inventory.ParticipantTowerInstanceIds.Remove(towerItemId); if (!removed) { return false; } if (TryGetTowerById(inventory, towerItemId, out TowerItemData tower)) { tower.IsParticipatingInCombat = false; } return true; } private static bool TryGetTowerById(BackpackInventoryData inventory, long towerItemId, out TowerItemData tower) { tower = null; if (inventory?.Towers == null || towerItemId <= 0) { return false; } for (int i = 0; i < inventory.Towers.Count; i++) { TowerItemData candidate = inventory.Towers[i]; if (candidate != null && candidate.InstanceId == towerItemId) { tower = candidate; return true; } } return false; } private static void NormalizeParticipantState(BackpackInventoryData inventory) { if (inventory == null) { return; } inventory.ParticipantTowerInstanceIds ??= new System.Collections.Generic.List(); System.Collections.Generic.Dictionary towerMap = new System.Collections.Generic.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; } } System.Collections.Generic.HashSet uniqueIds = new System.Collections.Generic.HashSet(); System.Collections.Generic.List normalizedIds = new System.Collections.Generic.List(inventory.ParticipantTowerInstanceIds.Count); for (int i = 0; i < inventory.ParticipantTowerInstanceIds.Count; i++) { if (normalizedIds.Count >= MaxParticipantCount) { 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 BackpackInventoryData SampleInventory() { BackpackInventoryData inventory = new BackpackInventoryData { Gold = 500 }; MuzzleCompItemData muzzle = new MuzzleCompItemData { InstanceId = 10001, ConfigId = 1, Name = "元素枪口", Rarity = RarityType.Green, Endurance = 90f, IsAssembledIntoTower = true, AttackDamage = new[] { 20, 30, 40, 50, 80 }, DamageRandomRate = 0.05f, AttackMethodType = AttackMethodType.NormalBullet, Constraint = string.Empty, Tags = new[] { TagType.Fire } }; inventory.MuzzleComponents.Add(muzzle); inventory.MuzzleComponents.Add(new MuzzleCompItemData { InstanceId = 10002, ConfigId = 2, Name = "控制枪口", Rarity = RarityType.Blue, Endurance = 80, IsAssembledIntoTower = false, AttackDamage = new[] { 30, 50, 70, 90, 100 }, DamageRandomRate = 0.01f, AttackMethodType = AttackMethodType.NormalBullet, Constraint = string.Empty, Tags = new[] { TagType.Ice, TagType.FreezeMask } }); inventory.MuzzleComponents.Add(new MuzzleCompItemData { InstanceId = 10003, ConfigId = 3, Name = "穿透枪口", Rarity = RarityType.Purple, Endurance = 97f, IsAssembledIntoTower = false, AttackDamage = new[] { 50, 55, 60, 80, 90 }, DamageRandomRate = 0.02f, AttackMethodType = AttackMethodType.NormalBullet, Constraint = string.Empty, Tags = new[] { TagType.Pierce, TagType.Crit } }); BearingCompItemData bearing = new BearingCompItemData { InstanceId = 20001, ConfigId = 1, Name = "元素轴承", Rarity = RarityType.Green, Endurance = 1f, IsAssembledIntoTower = true, RotateSpeed = new[] { 10f, 12f, 13f, 14f, 15f }, AttackRange = new[] { 2f, 2f, 2f, 2f, 2f }, Constraint = string.Empty, Tags = new[] { TagType.Fire } }; inventory.BearingComponents.Add(bearing); inventory.BearingComponents.Add(new BearingCompItemData { InstanceId = 20002, ConfigId = 2, Name = "控制轴承", Rarity = RarityType.Blue, Endurance = 20, IsAssembledIntoTower = false, RotateSpeed = new[] { 20f, 25f, 30f, 32f, 35f }, AttackRange = new[] { 6f, 6.5f, 7f, 8f, 8f }, Constraint = string.Empty, Tags = new[] { TagType.Ice, TagType.Shatter } }); inventory.BearingComponents.Add(new BearingCompItemData { InstanceId = 20003, ConfigId = 3, Name = "穿透轴承", Rarity = RarityType.Purple, Endurance = 96f, IsAssembledIntoTower = false, RotateSpeed = new[] { 60f, 70f, 80f, 90f, 100f }, AttackRange = new[] { 4f, 4.5f, 5f, 5.5f, 6f }, Constraint = string.Empty, Tags = new[] { TagType.Pierce, TagType.Overpenetrate } }); BaseCompItemData baseComp = new BaseCompItemData { InstanceId = 30001, ConfigId = 1, Name = "元素底座", Rarity = RarityType.Green, Endurance = 88f, IsAssembledIntoTower = true, AttackSpeed = new[] { 2f, 1.5f, 1f, 0.8f, 0.7f }, AttackPropertyType = AttackPropertyType.Fire, Constraint = string.Empty, Tags = new[] { TagType.Fire } }; inventory.BaseComponents.Add(baseComp); inventory.BaseComponents.Add(new BaseCompItemData { InstanceId = 30002, ConfigId = 2, Name = "控制底座", Rarity = RarityType.Blue, Endurance = 50f, IsAssembledIntoTower = false, AttackSpeed = new[] { 4f, 4.2f, 4.4f, 4.6f, 4.8f }, AttackPropertyType = AttackPropertyType.Ice, Constraint = string.Empty, Tags = new[] { TagType.Ice, TagType.AbsoluteZero } }); inventory.BaseComponents.Add(new BaseCompItemData { InstanceId = 30003, ConfigId = 3, Name = "穿透底座", Rarity = RarityType.Purple, Endurance = 30f, IsAssembledIntoTower = false, AttackSpeed = new[] { 1f, 1f, 1f, 1f, 1f }, AttackPropertyType = AttackPropertyType.Physics, Constraint = string.Empty, Tags = new[] { TagType.Pierce, TagType.Execution } }); TowerItemData tower = new TowerItemData { InstanceId = 90001, Name = "测试防御塔-A", Rarity = RarityType.Green, IsParticipatingInCombat = true, MuzzleComponentInstanceId = muzzle.InstanceId, BearingComponentInstanceId = bearing.InstanceId, BaseComponentInstanceId = baseComp.InstanceId, Stats = new TowerStatsData { AttackDamage = new[] { 200, 220, 240, 260, 300 }, DamageRandomRate = 0f, RotateSpeed = new[] { 200f, 210f, 220f, 230f, 240f }, AttackRange = new[] { 4.5f, 4.7f, 4.9f, 5.1f, 5.3f }, AttackSpeed = new[] { 1.5f, 1.2f, 1.1f, 1.0f, 0.8f }, AttackMethodType = AttackMethodType.NormalBullet, AttackPropertyType = AttackPropertyType.Fire, Tags = new[] { TagType.Fire, TagType.BurnSpread } } }; inventory.Towers.Add(tower); inventory.Towers.Add(new TowerItemData { InstanceId = 90002, Name = "测试防御塔-B", Rarity = RarityType.Blue, IsParticipatingInCombat = false, MuzzleComponentInstanceId = 0, BearingComponentInstanceId = 0, BaseComponentInstanceId = 0, Stats = new TowerStatsData { AttackDamage = new[] { 200, 220, 240, 260, 300 }, DamageRandomRate = 0.1f, RotateSpeed = new[] { 200f, 210f, 220f, 230f, 240f }, AttackRange = new[] { 4.5f, 4.7f, 4.9f, 5.1f, 5.3f }, AttackSpeed = new[] { 1.5f, 1.2f, 1.1f, 1.0f, 0.8f }, AttackMethodType = AttackMethodType.NormalBullet, AttackPropertyType = AttackPropertyType.Physics, Tags = new[] { TagType.Pierce } } }); inventory.ParticipantTowerInstanceIds.Add(90001); return inventory; } } }