TH1/Unity/Assets/Scripts/TH1_Renderer/CityInfoRenderer.cs
2026-05-21 14:22:15 +08:00

411 lines
16 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 Logic;
using Logic.CrashSight;
using Logic.Multilingual;
using RuntimeData;
using TH1_Logic.Core;
using TMPro;
using UnityEngine;
namespace TH1_Renderer
{
public class CityInfoRenderer
{
private MapData _mapData;
//private GameObject _ROCityInfo;
//private GameObject _RODebugText;
//private TextMeshProUGUI _debugText;
private uint _cityId;
//-------- Update缓存数据 --------//
private CityData _cityData;
private CityInfoMono _cityInfoMono;
public CityInfoRenderer(GameObject prefab,Transform father, uint cid, MapData mapData, Main main)
{
_mapData = mapData;
_cityId = cid;
_mapData.CityMap.GetCityById(_cityId,out _cityData);
Vector3 tpos = Table.Instance.GridToWorld(_cityData.Grid(mapData) ?? null,"isCityInfo");
var obj = GameObject.Instantiate(prefab,tpos, Quaternion.identity, father);
_cityInfoMono = obj.GetComponent<CityInfoMono>();
//_RODebugText = _ROCityInfo.transform.Find("CityInfoCanvas/DebugText").gameObject;
//_debugText = _RODebugText.GetComponent<TextMeshProUGUI>();
}
public void Update()
{
_mapData.CityMap.GetCityById(_cityId,out _cityData);
//RenderUpdateDebug();
}
// 销毁渲染器的 GameObject。用于 MapRenderer.RepairAllRenderers 清理孤儿。
public void Dispose()
{
if (_cityInfoMono != null)
{
GameObject.Destroy(_cityInfoMono.gameObject);
_cityInfoMono = null;
}
_cityData = null;
}
//瞬间生效的动画函数,将cityinfo的所有视觉瞬间与数据完全同步
public void InstantUpdateCityInfo()
{
RenderUpdateCityInfo();
}
//瞬间生效的动画,将所有图标相关的视觉瞬间与数据完全同步
public void InstantUpdateCityLabels()
{
var player = _cityData.Player(Main.MapData);
var isSelfCity = player == _mapData.PlayerMap.SelfPlayerData;
var isCradleCity = Main.CityLogic.CheckCradleCapital(_mapData, player, _cityData);
//更新联通图标的情况
_cityInfoMono?.SetConnect( isSelfCity && !isCradleCity && _cityData.IsConnectedCapital);
//更新首都图标的情况
_cityInfoMono?.SetCapital(isCradleCity && isSelfCity);
//更新大使馆图标的情况
GetEmbassyIconStatus(out bool showEmbassy,out bool showWarEmbassy);
_cityInfoMono?.SetEmbassy(showEmbassy);
_cityInfoMono?.SetWarEmbassy(showWarEmbassy);
//更新被Cloak偷金币的图标
_cityInfoMono?.SetCityStolen(_cityData.GetSkill(SkillType.CITYSTOLEN, out _));
}
public void InstantUpdateCityCoinTech()
{
RenderUpdateCityCoinTech();
}
public void InstantUpdateCityCoinTechCulture()
{
RenderUpdateCityCoinTechCulture();
}
private void RenderUpdateCityInfo()
{
if (_mapData == null)
{
LogSystem.LogError("RenderUpdateCityInfo _mapData == null");
return;
}
if (_cityData == null)
{
LogSystem.LogError("RenderUpdateCityInfo _cityData == null");
return;
}
if (_mapData.PlayerMap?.SelfPlayerData == null || _mapData.CityToPlayerDict == null ||
_mapData.CityToGridDict == null || _mapData.GridMap == null)
{
LogSystem.LogError("RenderUpdateCityInfo _mapData missing player/city/grid data");
return;
}
var mainMapData = Main.MapData;
if (mainMapData?.PlayerMap?.SelfPlayerData == null || mainMapData.CityToPlayerDict == null ||
mainMapData.CityToGridDict == null || mainMapData.GridMap == null)
{
LogSystem.LogError("RenderUpdateCityInfo Main.MapData missing player/city/grid data");
return;
}
//更新图标
InstantUpdateCityLabels();
//更新info底色
var selfPlayer = _mapData.PlayerMap?.SelfPlayerData;
_cityInfoMono?.SetBG(_cityData.Player(_mapData) == selfPlayer);
//更新人口条,会自动处理不在视野的情况
RenderUpdateCityPops(_cityData.Level,_cityData.LevelExp);
//更新GDP,会自动处理不在视野的情况
RenderUpdateCityCoinTechCulture();
//更新城市名,会自动处理不在视野的情况
RenderUpdateCityName();
//更新显示情况
var selfSight = selfPlayer?.Sight;
var cityGrid = _cityData.Grid(_mapData);
_cityInfoMono?.gameObject.SetActive(selfSight?.SightGidSet != null && selfSight.CheckIsInSight(cityGrid?.Id ?? 0));
}
private void GetEmbassyIconStatus(out bool showEmbassy,out bool showWarEmbassy)
{
showWarEmbassy = false;
showEmbassy = false;
//如果是对方的cradleCaptain并且真人玩家在此建立了大使馆才显示
if (!_cityData.Player(Main.MapData, out var player)) return;
//如果不是对方城市 return
if (player == Main.MapData.PlayerMap.SelfPlayerData) return;
//如果不是cradlecity return
if (!Main.CityLogic.CheckCradleCapital(_mapData, _cityData.Player(Main.MapData), _cityData)) return;
//如果没有建立大使馆return
if (!Main.MapData.PlayerMap.SelfPlayerData.GetCountryDiplomacyInfo(player.Id, out var dipInfo)) return;
if (!dipInfo.IsEmbassy) return;
if (dipInfo.DiplomacyState == DiplomacyState.War)
showWarEmbassy = true;
else showEmbassy = true;
}
private void RenderUpdateCityCoinTech()
{
//如果不是己方的城市,有外交才显示,不然不显示
if (!(_cityData.Player(Main.MapData)?.IsSelfPlayer() ?? true))
{
//处理外交金钱
var coin = Main.PlayerLogic.GetEmbassyCoin(_mapData,_mapData.PlayerMap.SelfPlayerData,_cityData.Player(Main.MapData));
bool hasEmbassyCoin = coin > 0 &&
Main.CityLogic.CheckCradleCapital(_mapData, _cityData.Player(Main.MapData),
_cityData);
_cityInfoMono?.SetCoin(hasEmbassyCoin,coin);
_cityInfoMono?.SetTech(false, 0);
_cityInfoMono?.SetCulture(false, 0);
return;
}
//如果是己方城市,直接显示
//被敌方单位站住的城市本回合不产出,UI显示0
if (Main.CityLogic.IsCityHeldByEnemyUnit(_mapData, _cityData))
{
_cityInfoMono?.SetCoin(true, 0);
_cityInfoMono?.SetTech(false, 0);
_cityInfoMono?.SetCulture(false, 0);
return;
}
_cityInfoMono?.SetCoin(true,Main.CityLogic.GetCityCoinPerTurn(_mapData,_cityData));
var tech = Main.CityLogic.GetCityTechPointPerTurn(_mapData, _cityData);
_cityInfoMono?.SetTech(tech > 0,tech);
var culture = Main.CityLogic.GetCityCulturePointPerTurn(_mapData, _cityData);
_cityInfoMono?.SetCulture(culture > 0,culture);
}
private void RenderUpdateCityCoinTechCulture()
{
//如果不是己方的城市,有外交才显示,不然不显示
if (!(_cityData.Player(Main.MapData)?.IsSelfPlayer() ?? true))
{
//处理外交金钱
var coin = Main.PlayerLogic.GetEmbassyCoin(_mapData,_mapData.PlayerMap.SelfPlayerData,_cityData.Player(Main.MapData));
bool hasEmbassyCoin = coin > 0 &&
Main.CityLogic.CheckCradleCapital(_mapData, _cityData.Player(Main.MapData),
_cityData);
_cityInfoMono?.SetCoin(hasEmbassyCoin,coin);
_cityInfoMono?.SetTech(false, 0);
_cityInfoMono?.SetCulture(false, 0);
return;
}
//如果是己方城市,直接显示
//被敌方单位站住的城市本回合不产出,UI显示0
if (Main.CityLogic.IsCityHeldByEnemyUnit(_mapData, _cityData))
{
_cityInfoMono?.SetCoin(true, 0);
_cityInfoMono?.SetTech(false, 0);
_cityInfoMono?.SetCulture(false, 0);
return;
}
_cityInfoMono?.SetCoin(true,Main.CityLogic.GetCityCoinPerTurn(_mapData,_cityData));
var tech = Main.CityLogic.GetCityTechPointPerTurn(_mapData, _cityData);
_cityInfoMono?.SetTech(tech > 0,tech);
var culture = Main.CityLogic.GetCityCulturePointPerTurn(_mapData, _cityData);
_cityInfoMono?.SetCulture(culture > 0,culture);
}
private void RenderUpdateCityName()
{
if (_cityData == null)
{
LogSystem.LogError("RenderUpdateCityName _cityData == null");
return;
}
var civDataAssets = Table.Instance?.CivDataAssets;
if (civDataAssets == null)
{
LogSystem.LogError("RenderUpdateCityName Table.Instance?.CivDataAssets == null");
return;
}
if (!civDataAssets.GetCityInfo(_cityData.Name,out var cityInfo) || cityInfo == null)
{
LogSystem.LogError($"RenderUpdateCityName cityInfo == null, cityName={_cityData.Name}");
return;
}
_cityInfoMono?.SetCityName(cityInfo.CityName);
}
private int GetCityPopulationSafe(MapData mapData, uint cityId)
{
int ret = 0;
if (mapData?.UnitMap?.UnitList == null || mapData.UnitToCityDict == null)
{
LogSystem.LogError("GetCityPopulationSafe mapData?.UnitMap?.UnitList == null || mapData.UnitToCityDict == null");
return ret;
}
foreach (var unit in mapData.UnitMap.UnitList)
{
if (unit == null)
{
LogSystem.LogError($"GetCityPopulationSafe unit == null, cityId={cityId}");
continue;
}
if (!mapData.UnitToCityDict.TryGetValue(unit.Id, out var unitCityId) || unitCityId != cityId)
continue;
bool noPopulation = false;
if (unit.Skills == null)
{
LogSystem.LogError($"GetCityPopulationSafe unit.Skills == null, unitId={unit.Id}");
}
else
{
foreach (var skill in unit.Skills)
{
if (skill?.GetSkillType() != SkillType.NOPOPULATION) continue;
noPopulation = true;
break;
}
}
if (!noPopulation)
ret++;
}
return ret;
}
private void RenderUpdateCityPops(int level,int levelExp)
{
var mapData = _mapData;
if (mapData?.PlayerMap == null)
{
LogSystem.LogError($"RenderUpdateCityPops mapData?.PlayerMap == null");
return;
}
var selfPlayer = mapData.PlayerMap.SelfPlayerData;
if (selfPlayer?.Sight?.SightGidSet == null)
{
LogSystem.LogError($"RenderUpdateCityPops selfPlayer?.Sight?.SightGidSet == null");
return;
}
if (_cityData == null)
{
LogSystem.LogError($"RenderUpdateCityPops _cityData == null");
return;
}
if (mapData.CityToGridDict == null || mapData.GridMap == null)
{
LogSystem.LogError($"RenderUpdateCityPops mapData.CityToGridDict == null || mapData.GridMap == null");
return;
}
if (mapData.CityToPlayerDict == null)
{
LogSystem.LogError($"RenderUpdateCityPops mapData.CityToPlayerDict == null");
return;
}
if (mapData.UnitMap?.UnitList == null || mapData.UnitToCityDict == null)
{
LogSystem.LogError($"RenderUpdateCityPops mapData.UnitMap?.UnitList == null || mapData.UnitToCityDict == null");
return;
}
if (!mapData.GetGridDataByCityId(_cityData.Id, out var cityGrid) || cityGrid == null)
{
LogSystem.LogError($"RenderUpdateCityPops cityGrid == null, cityId={_cityData.Id}");
return;
}
if (!selfPlayer.Sight.CheckIsInSight(cityGrid.Id))
return;
//如果不是己方的城市,不显示
var cityPlayer = _cityData.Player(mapData);
bool isSelfCity = cityPlayer?.Id == selfPlayer.Id;
//Step 3 设置城市经验条
_cityInfoMono?.SetLevelBar(isSelfCity,level,levelExp,GetCityPopulationSafe(mapData, _cityData.Id));
//Step 4 更新cityName
RenderUpdateCityName();
}
public void UpdateLevelShow(int level,int levelExp)
{
RenderUpdateCityPops(level, levelExp);
}
public uint GetCid()
{
return _cityId;
}
/*public void RenderUpdateDebug()
{
if (DebugCenter.Instance.DebugMode)
{
if(!_RODebugText.activeSelf)
_RODebugText.SetActive(true);
}
else
{
_RODebugText.SetActive(false);
return;
}
_debugText.text = "";
_debugText.text += $"CID={_cityId} PID={_cityData.Player(Main.MapData)?.Id ?? 0} CIV={_cityData.Player(Main.MapData)?.PlayerCivId ?? 0} gold={_cityData.Player(Main.MapData)?.PlayerCoin ?? 0}\n";
//如果不是我方单位显示city和player的战略
if(!_mapData.CheckCityIdBelongPlayerId(_cityId,_mapData.PlayerMap.SelfPlayerData.Id))
if (MainEditor.Instance.Data != null)
{
MainEditor.Instance.GetCityStrategy(_cityId, out var cst);
MainEditor.Instance.GetPlayerStrategy(_cityData.Player(Main.MapData)?.Id ?? 0, out var pst, out var target);
_debugText.text += $"CST={cst} PST={pst}";
_debugText.text += "\n";
}
//如果是首都,展示科技
if (_cityData.IsCapital)
{
_debugText.text += "tech={";
foreach (var tech in _cityData.Player(Main.MapData).TechTree.TechSet)
{
_debugText.text += tech + ",";
}
_debugText.text += "}\n";
}
//如果是不我方单位展示city上一回合的action list
if(!_mapData.CheckCityIdBelongPlayerId(_cityId,_mapData.PlayerMap.SelfPlayerData.Id))
if (MainEditor.Instance.Data != null)
{
var actionList = MainEditor.Instance.GetCityActions(_cityId);
_debugText.text += $"Turn {_cityData.Player(Main.MapData)?.Turn} act list\n";
if(actionList != null)
foreach (var act in actionList)
_debugText.text += act.DebugInfo() + "\n";
}
}*/
}
}