using System; using System.Collections.Generic; using GeometryTD.Definition; using GeometryTD.CustomUtility; using UnityEngine; namespace GeometryTD.Entity.EntityData { [Serializable] public class MapData : EntityDataBase { [SerializeField] private int _levelId = 0; [SerializeField] private int _initialCoin = 0; [SerializeField] private TowerStatsData[] _buildTowerStatsSnapshot = Array.Empty(); [SerializeField] private BackpackInventoryData _inventorySnapshot; [SerializeField] private TowerItemData[] _participantTowerSnapshot = Array.Empty(); [NonSerialized] private Func _tryConsumeCoin; [NonSerialized] private Action _addCoin; public MapData(int entityId, int levelId, Vector3 position) : this(entityId, 0, levelId, position) { } public MapData(int entityId, int typeId, int levelId, Vector3 position) : base(entityId, typeId) { _levelId = levelId; Position = position; } public MapData( int entityId, int typeId, int levelId, Vector3 position, int initialCoin, IReadOnlyList buildTowerStatsSnapshot, BackpackInventoryData inventorySnapshot, IReadOnlyList participantTowerSnapshot, Func tryConsumeCoin, Action addCoin) : base(entityId, typeId) { _levelId = levelId; Position = position; _initialCoin = Mathf.Max(0, initialCoin); SetBuildTowerStatsSnapshot(buildTowerStatsSnapshot); _inventorySnapshot = inventorySnapshot != null ? InventoryCloneUtility.CloneInventory(inventorySnapshot) : null; SetParticipantTowerSnapshot(participantTowerSnapshot); _tryConsumeCoin = tryConsumeCoin; _addCoin = addCoin; } public int LevelId { get => _levelId; set => _levelId = value; } public int InitialCoin { get => _initialCoin; set => _initialCoin = Mathf.Max(0, value); } public int CurrentBuildTowerCount => _buildTowerStatsSnapshot != null ? _buildTowerStatsSnapshot.Length : 0; public BackpackInventoryData InventorySnapshot => _inventorySnapshot != null ? InventoryCloneUtility.CloneInventory(_inventorySnapshot) : null; public IReadOnlyList ParticipantTowerSnapshot => _participantTowerSnapshot; public void BindCombatCallbacks(Func tryConsumeCoin, Action addCoin) { _tryConsumeCoin = tryConsumeCoin; _addCoin = addCoin; } public bool TryConsumeCoin(int coin) { int requiredCoin = Mathf.Max(0, coin); if (requiredCoin <= 0) { return true; } return _tryConsumeCoin != null && _tryConsumeCoin.Invoke(requiredCoin); } public void AddCoin(int coin) { int amount = Mathf.Max(0, coin); if (amount <= 0) { return; } _addCoin?.Invoke(amount); } public bool TryGetBuildTowerStats(int buildIndex, out TowerStatsData stats) { stats = null; if (_buildTowerStatsSnapshot == null || buildIndex < 0 || buildIndex >= _buildTowerStatsSnapshot.Length) { return false; } TowerStatsData sourceStats = _buildTowerStatsSnapshot[buildIndex]; if (sourceStats == null) { return false; } stats = InventoryCloneUtility.CloneTowerStats(sourceStats); return stats != null; } public void SetBuildTowerStatsSnapshot(IReadOnlyList buildTowerStatsSnapshot) { if (buildTowerStatsSnapshot == null || buildTowerStatsSnapshot.Count <= 0) { _buildTowerStatsSnapshot = Array.Empty(); return; } _buildTowerStatsSnapshot = new TowerStatsData[buildTowerStatsSnapshot.Count]; for (int i = 0; i < buildTowerStatsSnapshot.Count; i++) { _buildTowerStatsSnapshot[i] = InventoryCloneUtility.CloneTowerStats(buildTowerStatsSnapshot[i]); } } public MapData CloneForEntity(int entityId, Vector3 position) { return new MapData( entityId, TypeId, _levelId, position, _initialCoin, _buildTowerStatsSnapshot, _inventorySnapshot, _participantTowerSnapshot, _tryConsumeCoin, _addCoin); } public void SetParticipantTowerSnapshot(IReadOnlyList participantTowerSnapshot) { if (participantTowerSnapshot == null || participantTowerSnapshot.Count <= 0) { _participantTowerSnapshot = Array.Empty(); return; } _participantTowerSnapshot = new TowerItemData[participantTowerSnapshot.Count]; for (int i = 0; i < participantTowerSnapshot.Count; i++) { _participantTowerSnapshot[i] = InventoryCloneUtility.CloneTower(participantTowerSnapshot[i]); } } } }