2025-09-08 02:49:12 +08:00

368 lines
14 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<Main>();
//如果在视野内
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;
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<uint>();
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;
}
}
}