368 lines
14 KiB
C#
368 lines
14 KiB
C#
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;
|
||
}
|
||
|
||
}
|
||
}
|
||
|