/* * @Author: 白哉 * @Description: * @Date: 2025年04月03日 星期四 11:04:31 * @Modify: */ using System; using System.Collections.Generic; using UnityEngine; namespace RuntimeData { [Serializable] public class CityMapData : ISerializationCallbackReceiver { public List CityList; private Dictionary _cityDict; public bool CityMapRenderMark; public CityMapData() { CityList = new List(); _cityDict = new Dictionary(); CityMapRenderMark = true; } public CityMapData(CityMapData copyData) { CityList = new List(); _cityDict = new Dictionary(); foreach (var city in copyData.CityList) { var newCity = new CityData(city); CityList.Add(newCity); _cityDict[newCity.Id] = newCity; } } public void DeepCopy(CityMapData copyData) { _cityDict.Clear(); for (int i = 0; i < copyData.CityList.Count; i++) { var copyCity = copyData.CityList[i]; if (i >= CityList.Count) { var city = new CityData(copyCity); CityList.Add(city); _cityDict[city.Id] = city; } else { CityList[i].DeepCopy(copyCity); _cityDict[CityList[i].Id] = CityList[i]; } } for (int i = CityList.Count - 1; i >= copyData.CityList.Count; i--) { _cityDict.Remove(CityList[i].Id); CityList.RemoveAt(i); } } public void OnBeforeSerialize() { } public void OnAfterDeserialize() { _cityDict ??= new Dictionary(); _cityDict.Clear(); foreach (var city in CityList) _cityDict[city.Id] = city; } // 新增城市 public CityData AddCityData(List gidList, CityLibrary nameEnum, MapIdGenerator idGenerator) { var cityData = new CityData(gidList, nameEnum, idGenerator); CityList.Add(cityData); _cityDict[cityData.Id] = cityData; return cityData; } // 通过城市 ID 获取城市数据 public bool GetCityById(uint cityId, out CityData cityData) { return _cityDict.TryGetValue(cityId, out cityData); } // 通过领土位置 ID 获取城市数据 //TODO 缓存优化!! 紧急优化 public bool GetCityDataByTerritoryGridId(uint gid, out CityData cityData) { foreach (var city in CityList) { if (!city.CheckIsInTerritory(gid)) continue; cityData = city; return true; } cityData = null; return false; } public void OnTurnStart(MapData map, PlayerData player) { foreach (var city in CityList) { if (!map.CityToPlayerDict.TryGetValue(city.Id, out var selfPlayerId)) continue; if (selfPlayerId != player.Id) continue; city.OnTurnStart(map); } } public void OnTurnEnd(MapData map, PlayerData player) { foreach (var city in CityList) { if (!map.CityToPlayerDict.TryGetValue(city.Id, out var selfPlayerId)) continue; if (selfPlayerId != player.Id) continue; city.OnTurnEnd(map); } } } [Serializable] public class CityData : IdentifierBase { // 领土信息 public TerritoryData Territory; public bool CityInfoRenderMark = false; // 等级 public int Level; // 当前经验值 public int LevelExp; // 当前升级所需经验值 // 名称 public CityLibrary Name; // 城市类型 public CityLibrary CityInfo; // 是否为首都 public bool IsCapital; // 是否连接首都 public bool IsConnectedCapital; //如果是原始首都,那么记录因为联通升了几级 public int ConnectExp; // 3级升4级时候,是否选择了城防 public bool CityWall; // 2级升3级时候,是否选择了workshop public bool Workshop; // 5级以上,是否选择了park,有多少个park public int ParkCount = 0; // 记录当前回合 是否有升级点数使用 每回合需要清空 TODO 需要每回合结束清空 public int CityLevelUpPoint = 0; // 构造函数 public CityData(List gidList, CityLibrary nameEnum, MapIdGenerator idGenerator) { Id = idGenerator.GeneratorId(); Territory = new TerritoryData(); InitData(gidList,nameEnum); } public CityData(CityData copyData) { Id = copyData.Id; Level = copyData.Level; LevelExp = copyData.LevelExp; Name = copyData.Name; IsCapital = copyData.IsCapital; IsConnectedCapital = copyData.IsConnectedCapital; ConnectExp = copyData.ConnectExp; CityWall = copyData.CityWall; Workshop = copyData.Workshop; ParkCount = copyData.ParkCount; CityLevelUpPoint = copyData.CityLevelUpPoint; Territory = new TerritoryData(copyData.Territory); foreach (var skill in copyData.Skills) Skills.Add(skill.GetCopySkill()); } public void DeepCopy(CityData copyData) { Id = copyData.Id; Level = copyData.Level; LevelExp = copyData.LevelExp; Name = copyData.Name; IsCapital = copyData.IsCapital; IsConnectedCapital = copyData.IsConnectedCapital; ConnectExp = copyData.ConnectExp; CityWall = copyData.CityWall; Workshop = copyData.Workshop; ParkCount = copyData.ParkCount; CityLevelUpPoint = copyData.CityLevelUpPoint; Territory.DeepCopy(copyData.Territory); foreach (var skill in copyData.Skills) { AddSkill(skill.GetSkillType()); if (!GetSkill(skill.GetSkillType(), out var selfSkill)) continue; selfSkill.DeepCopy(skill); } for (int i = Skills.Count - 1; i >= 0; i--) { if (copyData.GetSkill(Skills[i].GetSkillType(), out _)) continue; Skills.RemoveAt(i); } } // 初始化数据 private void InitData(List gidList, CityLibrary name) { Level = 2; LevelExp = 0; Name = name; IsCapital = false; IsConnectedCapital = false; ConnectExp = 0; CityWall = false; Workshop = false; Territory.UpdateTerritory(gidList); } // 全局通知调用 public void OnTurnStart(MapData map) { for (int i = Skills.Count - 1; i >= 0; i--) { var skill = Skills[i]; if (skill.IsFinished()) { Skills.RemoveAt(i); continue; } skill.OnTurnStart(this, map); } } public void OnTurnEnd(MapData map) { foreach (var skill in Skills)skill.OnTurnEnd(this, map); } // 尝试升级城市 public bool TryUpgradeCity() { if (LevelExp < Level) return false; LevelExp -= Level; Level++; return true; } // 检查某个点是否在城市的领土范围内 public bool CheckIsInTerritory(uint gid) { return Territory.CheckIsInTerritory(gid); } // 设置首都情况 public void SetCapital(bool isCapital) { if (isCapital == IsCapital) return; IsCapital = isCapital; RenderMark = true; } } // 领土信息 [Serializable] public class TerritoryData : ISerializationCallbackReceiver { // 领土范围 public HashSet TerritoryArea; public List TerritoryAreaListForSerialize; public TerritoryData() { TerritoryArea = new HashSet(); } public TerritoryData(TerritoryData copyData) { TerritoryArea = new HashSet(copyData.TerritoryArea); } public void DeepCopy(TerritoryData copyData) { TerritoryArea.Clear(); foreach (var id in copyData.TerritoryArea) TerritoryArea.Add(id); } public void UpdateTerritory(List gidList) { //TerritoryArea.Clear(); foreach (var id in gidList) TerritoryArea.Add(id); } public bool CheckIsInTerritory(uint gid) { return TerritoryArea.Contains(gid); } public void GetAllTerritoryArea(HashSet set) { foreach (var id in TerritoryArea) set.Add(id); } public void OnBeforeSerialize() { TerritoryAreaListForSerialize ??= new List(); TerritoryAreaListForSerialize.Clear(); foreach (var gid in TerritoryArea) TerritoryAreaListForSerialize.Add(gid); } public void OnAfterDeserialize() { TerritoryArea ??= new HashSet(); TerritoryArea.Clear(); foreach (var gid in TerritoryAreaListForSerialize) TerritoryArea.Add(gid); } } }