using System.Collections.Generic; using Logic.CrashSight; using MongoDB.Driver.Core.Misc; using UnityEngine; using RuntimeData; using TH1_Core.Events; using TH1_Core.Managers; using TH1_Logic.Core; using TH1Renderer; namespace Logic { public class CityLogic : ICityLogic { bool needExplorer = false; int explorerStepMax = 10; int explorerStep = 0; Vector2Int explorerNowPos = new Vector2Int(); CityData explorerCityData; public void GenerateTribe(MapData mapData, Vector2Int tpos, int cid) { } public void TribeToCity(MapData mapData, PlayerData pd, CityData cd, UnitData ud) { } public void CityRemoveUnitFromList(MapData mapData, int uid, int cid) { } public void CityNewUnit(MapData mapData, int cid, UnitType unitType) { } public void CityExploit(MapData mapData, int cid, Vector2Int tpos, string actionName) { } //-------------------------------------- 构造方法 --------------------------------------// public CityLogic() { } public void Update() { } //-------------------------------------- 城市逻辑相关方法 --------------------------------------// // 更新城市等级 //用来增加城市经验,返回值表示本次升了几级 public int CityUpdateExp(MapData mapData, CityData cityData, int exp) { cityData.LevelExp += exp; cityData.CityInfoRenderMark = true; return CityUpdateLevel(mapData, cityData); } //返回是否升级成功 public int CityUpdateLevel(MapData mapData, CityData cityData) { int tmp = cityData.Level; if (!cityData.TryUpgradeCity()) return 0; cityData.RenderMark = true; cityData.CityInfoRenderMark = true; if (!mapData.GetGridDataByCityId(cityData.Id, out var gridData)) return 0; //更新VFX 播放一个城市升级特效。这里是临时做法,不应该这样获取main的 var main = GameObject.Find("Main").GetComponent
(); //如果在视野内 if (MapRenderer.Instance.ROGridMap.TryGetValue(gridData.Id, out var gridRenderer) && mapData.PlayerMap.SelfPlayerData.Sight.CheckIsInSight(gridData.Id)) { gridRenderer.SetFogAnim(false); } else { //这里有个情况,就是在ROGridMap没有生成之前,就已经对玩家的第一个city进行了一次cityupdatelevel } gridData.CityBuildingRenderMark = true; var levelUp = cityData.Level - tmp; cityData.CityLevelUpPoint += levelUp; //如果是真人玩家,发起界面提示 if (mapData == Main.MapData && mapData.GetPlayerDataByCityId(cityData.Id, out var player) && player.Id == mapData.PlayerMap.SelfPlayerData.Id) for (int i = cityData.Level - levelUp; i < cityData.Level; i++) { var interaction = new ShowUIInteractionCityUpgrade() { CityId = (int)cityData.Id,CityLevel = i}; EventManager.Publish(interaction); } return levelUp; } // 将一个城市设置为首都 public void SetCapital(MapData mapData, uint cid) { if (!mapData.CityMap.GetCityById(cid, out CityData cityData)) return; cityData.SetCapital(true); } // 当回合结束时,更新城市的状态 TODO 这个方法暂时没实现 public void CityEndTurn(MapData mapData, CityData cityData) { } // 创建城市方法, 参数为地块 ID 和 玩家 ID TODO 这个方法暂时没实现 public void CreateCity(MapData mapData, PlayerData playerData, GridData gridData) { } //在城市中央生成一个单位,返回单位id , TODO 是否需要记录是否是整个文明首个unit的bool public uint CreateUnit(MapData mapData, CityData cityData, UnitType unitType) { if (!mapData.GetGridIdByCityId(cityData.Id, out var gid)) return 0; var unitData = mapData.AddUnitData(gid, cityData.Id, unitType); return unitData.Id; } // 找寻某个地块上是否存在城市 public CityData FindCityOnPos(MapData mapData, uint gid) { if (mapData.GetCityIdByGridId(gid, out var cid)) { if (mapData.CityMap.GetCityById(cid, out var cityData)) return cityData; } return null; } //更新grid的buildinglevel,并且顺带会更新城市的exp public void UpdateGridBuildingData(MapData mapData, GridData gridData) { CalcGridBuildingLevel(mapData, gridData, gridData.Resource, out var level); if (!Table.Instance.GridAndResourceDataAssets.GetResourceInfo(gridData.Resource, out var resourceInfo)) { LogSystem.LogError($"CityLogic UpdateGridBuildingData can't find data asset of resource{gridData.Resource}"); return; } int delta = (level - gridData.buildingLevel ) * resourceInfo.CityExpPerLevel; gridData.buildingLevel = level; gridData.RenderMark = true; if(mapData.GetCityDataByTerritoryGid(gridData.Id,out var cityData)) CityUpdateExp(mapData,cityData,delta); } //获得一个city当前的科技点 public int GetCityTechPointPerTurn(MapData mapData, CityData cityData) { int ret = 0; if (GetBuildingLevelByCity(mapData, cityData, ResourceType.Academy, out var academyLevel)) ret = academyLevel; return ret; } //获得一个city当前的回合钱 public int GetCityStarsPerTurn(MapData mapData, CityData cityData) { //如果城市亏exp,要减少每回合的给钱数 int mins = 0; if (cityData.LevelExp < 0) mins = cityData.LevelExp; int ret = 0; ret = cityData.Level - 1 + cityData.ParkCount + (mapData.GetPlayerDataByCityId(cityData.Id,out var player) && Main.CityLogic.CheckCradleCapital(mapData,player,cityData) ? 1 : 0) + (cityData.Workshop ? 1 : 0) + mins; //增加集市的金钱 if (GetBuildingLevelByCity(mapData, cityData, ResourceType.Market, out var marketLevel)) ret += marketLevel; //增加保护区的金钱 if (GetBuildingLevelByCity(mapData, cityData, ResourceType.Preserve, out var preserveLevel)) ret += preserveLevel; //增加kaguyaYard的金钱 if (GetBuildingLevelByCity(mapData, cityData, ResourceType.KaguyaFrenchYard, out var kaguyaYardLevel)) ret += kaguyaYardLevel; if (ret < 0) ret = 0; return ret; } //获得一个city当前的某种building的level public bool GetBuildingLevelByCity(MapData mapData, CityData cityData, ResourceType buildingType, out int level) { foreach (var gridId in cityData.Territory.TerritoryArea) { if (!mapData.GridMap.GetGridDataByGid(gridId, out var gridData)) continue; if (gridData.Resource == buildingType) { level = gridData.buildingLevel; return true; } } level = 0; return false; } // 城市升级领土 public void CityLevelUpActionExpand(MapData mapData, CityData cityData) { if (!mapData.GetGridDataByCityId(cityData.Id, out var gridData)) return; if (!mapData.GetPlayerDataByCityId(cityData.Id, out var playerData)) return; var aroundGridList = mapData.GridMap.GetAroundGridData(2, 2, gridData); Main.PlayerLogic.UpdateSight(mapData,playerData,mapData.GridMap.GetAroundGridIdList(2,gridData)); var newTerritoryArea = new List(); foreach (var aroundGrid in aroundGridList) { if (mapData.GetPlayerDataByTerritoryGridId(aroundGrid.Id, out var playerData1)) continue; newTerritoryArea.Add(aroundGrid.Id); } cityData.Territory.UpdateTerritory(newTerritoryArea); var playerTerritoryGridIdSet = mapData.GetPlayerTerritoryGridIdSet(playerData.Id); foreach (var gridId in playerTerritoryGridIdSet) { if (!mapData.GridMap.GetGridDataByGid(gridId, out var gridData1)) continue; gridData1.RenderMark = true; } } // 查询如果gridData上有buildingType,那么它的level会是多少,bool返回他能否建设在这个位置 public bool CalcGridBuildingLevel(MapData mapData, GridData gridData,ResourceType buildingType,out int level) { if(!Table.Instance.GridAndResourceDataAssets.GetResourceInfo(buildingType,out var resourceInfo)) { LogSystem.LogError($"CityLogic CalcGridBuildingLevel cant get resourceInfo dataasset of {buildingType}"); level = 0; return false; } if (!resourceInfo.HasLevel) { level = 0; return false; } //获得周围一圈的grid,不管是不是我方 var aroundGridList = mapData.GridMap.GetAroundGridData(1,1,gridData); level = 0; bool ret = false; foreach (var grid in aroundGridList) { //如果就是中间这个格子,跳过 //if (grid == gridData) continue; //如果无主或者不是自己的领土,直接continue if (!mapData.GetPlayerDataByTerritoryGridId(grid.Id, out var playerData) || playerData != mapData.PlayerMap.SelfPlayerData) continue; //鲁棒性 + 获得该grid的cityData if (!mapData.GetCityDataByTerritoryGid(grid.Id, out var targetCityData)) continue; //处理market的情况 if (buildingType == ResourceType.Market) { if (grid.Resource == ResourceType.Forge || grid.Resource == ResourceType.Windmill || grid.Resource == ResourceType.Sawmill) { level += grid.buildingLevel; ret = true; } if (level > 8) level = 8; } //处理windmill forge话sawmill的情况 if ((grid.Resource == ResourceType.Farm && buildingType == ResourceType.Windmill) || (grid.Resource == ResourceType.Mine && buildingType == ResourceType.Forge) || (grid.Resource == ResourceType.LumberHut && buildingType == ResourceType.Sawmill)) { level++; ret = true; } //处理preserve if (grid.Vegetation == Vegetation.Trees && buildingType == ResourceType.Preserve) if (grid.Resource is ResourceType.None or ResourceType.Animal or ResourceType.Preserve) { level++; ret = true; } //处理academy if (buildingType == ResourceType.Academy) { if (grid.Feature == TerrainFeature.Mountain) { level++; ret = true; } if (grid.Resource == ResourceType.Preserve) { level+= grid.buildingLevel; ret = true; } if (grid.Resource == ResourceType.Forge) { level+= grid.buildingLevel; ret = true; } } //处理kaguyafrench yard if (buildingType == ResourceType.KaguyaFrenchYard) { if (grid.Resource == ResourceType.Animal) { level++; ret = true; } } } if (level > resourceInfo.MaxLevel) level = resourceInfo.MaxLevel; return ret; } //查询grid周围是否有某种resource public bool CheckAroundGridHasSomeResourceBelongPlayer(MapData mapData, GridData gridData,PlayerData playerData, ResourceType buildingType) { //step #1 获得周围一圈的grid,不管是不是我方 var aroundGridList = mapData.GridMap.GetAroundGridData(1,1,gridData); //step #2 逐一判断每个周围的grid foreach (var grid in aroundGridList) { //如果不是player的领土,continue if (!mapData.CheckIfGidBelongPid(grid.Id, mapData.PlayerMap.SelfPlayerId)) continue; if (grid.Resource == ResourceType.Port) return true; } return false; } //确认一个城市是不是当前玩家的原始首都 public bool CheckCradleCapital(MapData map,PlayerData player,CityData city) { return player.CradleCityId == city.Id && city.IsCapital && map.GetPlayerDataByCityId(city.Id, out var player2) && player2.Id == player.Id; } } }