TH1/My project/Assets/Scripts/Data/PlayerData.cs
2025-07-14 19:41:58 +08:00

970 lines
33 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.

/*
* @Author: 白哉
* @Description:
* @Date: 2025年04月03日 星期四 11:04:31
* @Modify:
*/
using System;
using System.Collections.Generic;
using System.Linq;
using Logic.Action;
using Logic.AI;
using NUnit.Framework;
using Unity.VisualScripting;
using UnityEngine;
namespace RuntimeData
{
// 奇观类型枚举
public enum WonderTypeEnum
{
None,
PEACE,
KNOWLEDGE,
TRADE,
WEALTH,
POWER,
PARK,
EYE
}
// 奇观状态枚举
public enum WonderState
{
NO_HINT,
HAVE_HINT,
FINISH_NOT_BUILD,
FINISH_BUILD,
Max
}
// 外交关系枚举
public enum DiplomacyState
{
NoDiplomacy,
Neutral,
League,
War,
LeagueRupture,
}
// 好感状态枚举
public enum FeelingState
{
Trust,
Appreciate,
Indifferent,
Suspicion,
Terrible,
}
[Serializable]
public class PlayerMapData : ISerializationCallbackReceiver
{
public uint SelfPlayerId;
public List<PlayerData> PlayerDataList;
private Dictionary<uint, PlayerData> _playerDataDict;
public PlayerData SelfPlayerData => GetPlayerData(SelfPlayerId);
// 无数据初始化
public PlayerMapData()
{
PlayerDataList = new List<PlayerData>();
_playerDataDict = new Dictionary<uint, PlayerData>();
}
// 配置初始化
public PlayerMapData(MapConfig mapConfig, MapIdGenerator idGenerator)
{
PlayerDataList = new List<PlayerData>();
_playerDataDict = new Dictionary<uint, PlayerData>();
for (int i = 0; i < mapConfig.PlayerCount; i++)
{
PlayerData player;
//处理player到底是谁的问题。目前临时使用的方案今后要改。目前civ一定=force,所以可以这么做
if (i == 0)
player = new PlayerData(mapConfig.selfCivId,mapConfig.selfForceId,idGenerator);
else if (mapConfig.selfCivId == i)
player = new PlayerData((uint)0,(uint)0,idGenerator);
else
player = new PlayerData((uint)i,(uint)i,idGenerator);
PlayerDataList.Add(player);
_playerDataDict[player.Id] = player;
}
SelfPlayerId = PlayerDataList[0].Id;
}
public PlayerMapData(PlayerMapData copyData)
{
PlayerDataList = new List<PlayerData>();
_playerDataDict = new Dictionary<uint, PlayerData>();
SelfPlayerId = copyData.SelfPlayerId;
foreach (var copyPlayer in copyData.PlayerDataList)
{
var player = new PlayerData(copyPlayer);
PlayerDataList.Add(player);
_playerDataDict[player.Id] = player;
}
}
public void DeepCopy(PlayerMapData copyData)
{
_playerDataDict.Clear();
SelfPlayerId = copyData.SelfPlayerId;
for (int i = 0; i < copyData.PlayerDataList.Count; i++)
{
var copyPlayer = copyData.PlayerDataList[i];
if (i >= PlayerDataList.Count)
{
var player = new PlayerData(copyPlayer);
PlayerDataList.Add(player);
_playerDataDict[player.Id] = player;
}
else
{
PlayerDataList[i].DeepCopy(copyPlayer);
_playerDataDict[PlayerDataList[i].Id] = PlayerDataList[i];
}
}
for (int i = PlayerDataList.Count - 1; i >= copyData.PlayerDataList.Count; i--)
{
_playerDataDict.Remove(PlayerDataList[i].Id);
PlayerDataList.RemoveAt(i);
}
}
public void OnBeforeSerialize()
{
}
public void OnAfterDeserialize()
{
_playerDataDict ??= new Dictionary<uint, PlayerData>();
_playerDataDict.Clear();
foreach (var player in PlayerDataList) _playerDataDict[player.Id] = player;
}
// 根据 pid 获取玩家数据
public bool GetPlayerDataByPlayerID(uint pid, out PlayerData playerData)
{
return _playerDataDict.TryGetValue(pid, out playerData);
}
// 判断自己是否胜利
public bool CheckSelfWin()
{
foreach (var playerData in PlayerDataList)
{
if (playerData.Id == SelfPlayerId) continue;
if (playerData.Alive) return false;
}
return true;
}
//用于经典模式判断是否已经抵达31回合从而结束游戏
public bool CheckTimeEnd()
{
if(SelfPlayerData.Turn == 61)
return true;
return false;
}
// 判断自己是否失败
public bool CheckSelfLose()
{
return !SelfPlayerData.Alive;
}
public PlayerData GetPlayerData(uint id)
{
if (_playerDataDict.TryGetValue(id, out var playerData))
{
return playerData;
}
return null;
}
public void OnTurnStart(MapData map, PlayerData player)
{
player.OnTurnStart(map);
}
public void OnTurnEnd(MapData map, PlayerData player)
{
player.OnTurnEnd(map);
}
}
[Serializable]
public class PlayerData : IdentifierBase
{
// 文明 id, 阵营 id, 摇篮城市 id
public uint Turn;
public uint PlayerCivId;
public uint PlayerForceId;
public uint CradleCityId;
// 是否存活
public bool Alive;
// 财富总额
public int PlayerWealth2;
public int PlayerWealth
{
get => PlayerWealth2;
set
{
PlayerWealth2 = value;
if (PlayerWealth2 < 0)
{
Debug.Log(111);
}
}
}
//分数
public int PlayerScore;
// 视野
public MapSightData Sight;
// 科技
public TechTreeData TechTree;
// 奇观
public WonderData Wonder;
// 用于记录已经连续几个 turn 没有进行攻击
public int TurnNoAttack;
// 用于记录累计击杀多少 unit
public int TotalKill;
public List<uint> MeetPlayers;
public List<uint> CurAttackPlayers;
public List<uint> LastAttackPlayers;
public DiplomacyData DiplomacyData;
//用于记录是否死亡是否要centMessage来宣告死亡信息
public bool DieMark = false;
// 无参数初始化
public PlayerData()
{
Sight = new MapSightData();
TechTree = new TechTreeData();
Wonder = new WonderData();
DiplomacyData = new DiplomacyData();
MeetPlayers = new List<uint>();
CurAttackPlayers = new List<uint>();
LastAttackPlayers = new List<uint>();
//InitData();
}
// 带 ID 初始化
public PlayerData(uint civId, uint forceId, MapIdGenerator idGenerator)
{
Turn = 0;
Id = idGenerator.GeneratorId();
if(Table.Instance.PlayerDataAssets.GetPlayerInfoByCivId(civId,forceId,out var info))
TechTree = new TechTreeData(info.TechStart);
else
TechTree = new TechTreeData();
Sight = new MapSightData();
Wonder = new WonderData();
DiplomacyData = new DiplomacyData();
CurAttackPlayers = new List<uint>();
LastAttackPlayers = new List<uint>();
MeetPlayers = new List<uint>();
MeetPlayers.Add(Id);
InitData(civId,forceId);
}
public PlayerData(PlayerData copyData)
{
Turn = copyData.Turn;
Id = copyData.Id;
PlayerCivId = copyData.PlayerCivId;
PlayerForceId = copyData.PlayerForceId;
CradleCityId = copyData.CradleCityId;
Alive = copyData.Alive;
PlayerWealth2 = copyData.PlayerWealth2;
Sight = new MapSightData(copyData.Sight);
TechTree = new TechTreeData(copyData.TechTree);
Wonder = new WonderData(copyData.Wonder);
DiplomacyData = new DiplomacyData(copyData.DiplomacyData);
CurAttackPlayers = new List<uint>();
foreach (var id in copyData.CurAttackPlayers) CurAttackPlayers.Add(id);
LastAttackPlayers = new List<uint>();
foreach (var id in copyData.LastAttackPlayers) LastAttackPlayers.Add(id);
MeetPlayers = new List<uint>();
foreach (var id in copyData.MeetPlayers) MeetPlayers.Add(id);
TurnNoAttack = copyData.TurnNoAttack;
TotalKill = copyData.TotalKill;
foreach (var skill in copyData.Skills) Skills.Add(skill.GetCopySkill());
}
public void DeepCopy(PlayerData copyData)
{
Turn = copyData.Turn;
Id = copyData.Id;
PlayerCivId = copyData.PlayerCivId;
PlayerForceId = copyData.PlayerForceId;
CradleCityId = copyData.CradleCityId;
Alive = copyData.Alive;
PlayerWealth2 = copyData.PlayerWealth2;
Sight.DeepCopy(copyData.Sight);
TechTree.DeepCopy(copyData.TechTree);
Wonder.DeepCopy(copyData.Wonder);
DiplomacyData.DeepCopy(copyData.DiplomacyData);
CurAttackPlayers.Clear();
foreach (var id in copyData.CurAttackPlayers) CurAttackPlayers.Add(id);
LastAttackPlayers.Clear();
foreach (var id in copyData.LastAttackPlayers) LastAttackPlayers.Add(id);
MeetPlayers.Clear();
foreach (var id in copyData.MeetPlayers) MeetPlayers.Add(id);
TurnNoAttack = copyData.TurnNoAttack;
TotalKill = copyData.TotalKill;
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(uint civId,uint forceId)
{
Alive = true;
PlayerWealth2 = 5;
PlayerCivId = civId;
PlayerForceId = forceId;
TurnNoAttack = 0;
TotalKill = 0;
}
// 全局通知调用
public void OnTurnStart(MapData map)
{
Turn++;
LastAttackPlayers.Clear();
foreach (var id in CurAttackPlayers) LastAttackPlayers.Add(id);
CurAttackPlayers.Clear();
for (int i = Skills.Count - 1; i >= 0; i--)
{
var skill = Skills[i];
if (skill.IsFinished())
{
Skills.RemoveAt(i);
continue;
}
skill.OnTurnStart(this, map);
}
RefreshFeelingValue(map);
}
public void OnTurnEnd(MapData map)
{
foreach (var skill in Skills)skill.OnTurnEnd(this, map);
foreach (var player in map.PlayerMap.PlayerDataList)
{
if (player.Id == Id) continue;
DiplomacyData.GetCountryDiplomacyInfo(player.Id, out var selfToPlayer);
if (selfToPlayer.DiplomacyState == DiplomacyState.LeagueRupture) selfToPlayer.IsLeagueRupture = true;
}
}
// 添加当前回合攻击者
public void AddAttacker(uint playerId)
{
DiplomacyData.AddTurnAttacker(Turn, playerId);
}
// 检查前几回合内是否有攻击者
public bool CheckTurnsAttacker(uint turns, uint playerId)
{
for (int i = 0; i < turns; i++)
{
if (Turn < i) return false;
if (!DiplomacyData.CheckTurnAttacker(Turn - (uint)i, playerId)) continue;
return true;
}
return false;
}
// 刷新对他国好感值
public void RefreshFeelingValue(MapData map)
{
int maxScore = 0;
uint maxScorePlayer = 0;
foreach (var player in map.PlayerMap.PlayerDataList)
{
if (player.PlayerScore <= maxScore) continue;
maxScore = player.PlayerScore;
maxScorePlayer = player.Id;
}
foreach (var player in map.PlayerMap.PlayerDataList)
{
if (player.Id == Id) continue;
DiplomacyData.GetCountryDiplomacyInfo(player.Id, out var selfToPlayer);
player.DiplomacyData.GetCountryDiplomacyInfo(Id, out var playerToSelf);
if (playerToSelf == null || selfToPlayer == null) continue;
var score = 0f;
// 明智的 愚蠢的
var score1 = 0f;
foreach (var otherPlayer in map.PlayerMap.PlayerDataList)
{
if (otherPlayer.Id == Id || otherPlayer.Id == player.Id) continue;
DiplomacyData.GetCountryDiplomacyInfo(player.Id, out var selfToOtherPlayer);
if (selfToOtherPlayer.DiplomacyState == DiplomacyState.NoDiplomacy) continue;
player.DiplomacyData.GetCountryDiplomacyInfo(player.Id, out var playerToOtherPlayer);
if (playerToOtherPlayer.DiplomacyState == DiplomacyState.NoDiplomacy) continue;
if (selfToOtherPlayer.DiplomacyState == playerToOtherPlayer.DiplomacyState) score1 += 5;
else score1 -= 5;
}
if (score1 + 5 > 0) score += Mathf.Min(20, score1);
if (score1 - 5 < 0) score += Mathf.Max(-20, score1);
// 迷人的 恼人的
if (map.MapConfig.AIDiff == AIDifficult.EASY && player.Id == map.PlayerMap.SelfPlayerId &&
Id != map.PlayerMap.SelfPlayerId) score += 15;
if (map.MapConfig.AIDiff == AIDifficult.LUNATIC && player.Id == map.PlayerMap.SelfPlayerId &&
Id != map.PlayerMap.SelfPlayerId) score -= 15;
// 和平的 暴力的
if (!CheckTurnsAttacker(3, player.Id)) score += 15;
else score -= 15;
// 外交的
if (selfToPlayer.IsEmbassy || playerToSelf.IsEmbassy) score += 15;
// 强大的 弱小的
var selfScore = 0f;
var playerScore = 0f;
foreach (var gridId in Sight.SightGidSet)
{
if (!map.GetUnitDataByGid(gridId, out var unit)) continue;
if (!map.GetPlayerIdByUnitId(unit.Id, out var ownerId)) continue;
if (ownerId == Id) selfScore += unit.GetMilitary();
if (ownerId == player.Id) playerScore += unit.GetMilitary();
}
if (selfScore < playerScore) score += 15;
if (selfScore > playerScore) score -= 15;
// 勇敢的
if (maxScorePlayer != Id)
{
player.DiplomacyData.GetCountryDiplomacyInfo(maxScorePlayer, out var playerToMaxScorePlayer);
if (playerToMaxScorePlayer.DiplomacyState == DiplomacyState.War) score += 15;
}
// 威胁的
var playerUnit = new HashSet<UnitData>();
map.GetUnitDataListByPlayerId(player.Id, playerUnit);
var selfTerritory = map.GetPlayerTerritoryGridIdSet(Id);
foreach (var gridId in selfTerritory)
{
if (!map.GridMap.GetGridDataByGid(gridId, out var gridData)) continue;
foreach (var unit in playerUnit)
{
if (!map.GetGridDataByUnitId(unit.Id, out var unitGrid)) continue;
var dis = map.GridMap.CalcDistance(unitGrid, gridData);
if (dis > 1) continue;
score -= 15;
return;
}
}
// 侵略的
var playerTerritory = map.GetPlayerTerritoryGridIdSet(player.Id);
foreach (var playerGridId in playerTerritory)
{
if (!map.GridMap.GetGridDataByGid(playerGridId, out var playerGrid)) continue;
foreach (var selfGridId in selfTerritory)
{
if (!map.GridMap.GetGridDataByGid(selfGridId, out var selfGrid)) continue;
var dis = map.GridMap.CalcDistance(playerGrid, selfGrid);
if (dis > 1) continue;
score -= 15;
return;
}
}
// 主宰的
if (maxScorePlayer == player.Id)
{
var count = 0;
var playerCity = new HashSet<CityData>();
map.GetCityDataListByPlayerId(player.Id, playerCity);
foreach (var city in playerCity) if (city.IsCradle) count++;
if (count > 0) count--;
score -= 15 + count * 5;
}
score = Mathf.Max(0, score);
selfToPlayer.FeelingValue = score;
if (score <= 10) selfToPlayer.FeelingState = FeelingState.Terrible;
else if (score <= 30) selfToPlayer.FeelingState = FeelingState.Suspicion;
else if (score <= 60) selfToPlayer.FeelingState = FeelingState.Indifferent;
else if (score <= 85) selfToPlayer.FeelingState = FeelingState.Appreciate;
else if (score <= 100) selfToPlayer.FeelingState = FeelingState.Trust;
}
}
// 刷新对他国的外交关系
public void RefreshDiplomacyState(MapData map)
{
foreach (var player in map.PlayerMap.PlayerDataList)
{
if (player.Id == Id) continue;
DiplomacyData.GetCountryDiplomacyInfo(player.Id, out var selfToPlayer);
player.DiplomacyData.GetCountryDiplomacyInfo(Id, out var playerToSelf);
// 如果没有外交关系,且没有见过面,则设置为无外交关系
if (!MeetPlayers.Contains(player.Id)) selfToPlayer.DiplomacyState = DiplomacyState.NoDiplomacy;
// 如果没有外交关系,且见过面,则设置为中立
else if (selfToPlayer.DiplomacyState == DiplomacyState.NoDiplomacy)
selfToPlayer.DiplomacyState = DiplomacyState.Neutral;
// 如果上一回合回合内双方未发生战斗,则该回合开始时变为中立关系
if (selfToPlayer.DiplomacyState == DiplomacyState.War && !LastAttackPlayers.Contains(player.Id))
selfToPlayer.DiplomacyState = DiplomacyState.Neutral;
if (selfToPlayer.DiplomacyState == DiplomacyState.LeagueRupture &&
playerToSelf.DiplomacyState == DiplomacyState.LeagueRupture &&
selfToPlayer.IsLeagueRupture && playerToSelf.IsLeagueRupture)
{
selfToPlayer.DiplomacyState = DiplomacyState.Neutral;
playerToSelf.DiplomacyState = DiplomacyState.Neutral;
}
}
}
}
// 奇观信息
[Serializable]
public class WonderData : ISerializationCallbackReceiver
{
// 所有奇观信息
public Dictionary<WonderTypeEnum, WonderState> WonderInfoDict;
public HashSet<WonderTypeEnum> WonderRenderMark;
public List<WonderTypeEnum> WonderInfoKeyList;
public List<WonderState> WonderInfoValueList;
public List<WonderTypeEnum> WonderRenderList;
public WonderData()
{
WonderInfoDict = new Dictionary<WonderTypeEnum, WonderState>();
WonderRenderMark = new HashSet<WonderTypeEnum>();
foreach (WonderTypeEnum wonderType in System.Enum.GetValues(typeof(WonderTypeEnum)))
WonderInfoDict[wonderType] = WonderState.NO_HINT;
}
public WonderData(WonderData copyData)
{
WonderInfoDict = new Dictionary<WonderTypeEnum, WonderState>(copyData.WonderInfoDict);
WonderRenderMark = new HashSet<WonderTypeEnum>(copyData.WonderRenderMark);
foreach (var kv in copyData.WonderInfoDict)
{
WonderInfoDict[kv.Key] = kv.Value;
}
foreach (var typeEnum in copyData.WonderRenderMark) WonderRenderMark.Add(typeEnum);
}
public void DeepCopy(WonderData copyData)
{
WonderInfoDict.Clear();
WonderRenderMark.Clear();
foreach (var kv in copyData.WonderInfoDict) WonderInfoDict[kv.Key] = kv.Value;
foreach (var typeEnum in copyData.WonderRenderMark) WonderRenderMark.Add(typeEnum);
}
public void OnBeforeSerialize()
{
WonderInfoKeyList ??= new List<WonderTypeEnum>();
WonderInfoValueList ??= new List<WonderState>();
WonderRenderList ??= new List<WonderTypeEnum>();
WonderInfoKeyList.Clear();
WonderInfoValueList.Clear();
WonderRenderList.Clear();
foreach (var kv in WonderInfoDict)
{
WonderInfoKeyList.Add(kv.Key);
WonderInfoValueList.Add(kv.Value);
}
foreach (var render in WonderRenderMark) WonderRenderList.Add(render);
}
public void OnAfterDeserialize()
{
WonderInfoDict ??= new Dictionary<WonderTypeEnum, WonderState>();
WonderRenderMark ??= new HashSet<WonderTypeEnum>();
WonderInfoDict.Clear();
WonderRenderMark.Clear();
for (int i = 0; i < WonderInfoKeyList.Count; i++)
{
WonderInfoDict[WonderInfoKeyList[i]] = WonderInfoValueList[i];
}
foreach (var render in WonderRenderList) WonderRenderMark.Add(render);
}
// 获取某个奇观的状态
public WonderState GetWonderState(WonderTypeEnum wonderType)
{
if (WonderInfoDict.TryGetValue(wonderType, out var state))
{
return state;
}
return WonderState.NO_HINT;
}
public void SetWonderState(WonderTypeEnum wonderType, WonderState state)
{
WonderInfoDict[wonderType] = state;
WonderRenderMark.Add(wonderType);
}
// 判断某个奇观是否变动
public bool IsWonderRenderMark(WonderTypeEnum wonderType)
{
return WonderRenderMark.Contains(wonderType);
}
}
// 视野信息
[Serializable]
public class MapSightData : ISerializationCallbackReceiver
{
public HashSet<uint> SightGidSet;
public List<uint> SightGidListForSerialize;
public MapSightData()
{
SightGidSet = new HashSet<uint>();
}
public MapSightData(MapSightData copyData)
{
SightGidSet = new HashSet<uint>(copyData.SightGidSet);
}
public void DeepCopy(MapSightData copyData)
{
SightGidSet.Clear();
foreach (var gid in copyData.SightGidSet) SightGidSet.Add(gid);
}
public void OnBeforeSerialize()
{
SightGidListForSerialize ??= new List<uint>();
SightGidListForSerialize.Clear();
foreach (var gid in SightGidSet) SightGidListForSerialize.Add(gid);
}
public void OnAfterDeserialize()
{
SightGidSet ??= new HashSet<uint>();
SightGidSet.Clear();
foreach (var gid in SightGidListForSerialize) SightGidSet.Add(gid);
}
// 判断是否在视野内
public bool CheckIsInSight(uint gid)
{
return SightGidSet.Contains(gid);
}
}
// 科技信息
[Serializable]
public class TechTreeData : ISerializationCallbackReceiver
{
public HashSet<TechType> TechSet;
public HashSet<uint> TechActionCacheSet;
//仅用于序列化
public List<TechType> TechListForSerial;
public List<uint> TechActionCacheList;
public TechTreeData(List<TechType> StartTechList = null)
{
TechSet = new HashSet<TechType>();
TechActionCacheSet = new HashSet<uint>();
if(StartTechList != null)
foreach(var t in StartTechList)
LearnTech(t);
}
public TechTreeData(TechTreeData copyData)
{
TechSet = new HashSet<TechType>(copyData.TechSet);
TechActionCacheSet = new HashSet<uint>(copyData.TechActionCacheSet);
}
public void DeepCopy(TechTreeData copyData)
{
TechSet.Clear();
TechActionCacheSet.Clear();
foreach (var tech in copyData.TechSet) TechSet.Add(tech);
foreach (var act in copyData.TechActionCacheSet) TechActionCacheSet.Add(act);
}
public void OnBeforeSerialize()
{
TechListForSerial ??= new List<TechType>();
TechActionCacheList ??= new List<uint>();
TechListForSerial.Clear();
TechActionCacheList.Clear();
foreach (var techType in TechSet) TechListForSerial.Add(techType);
foreach (var cache in TechActionCacheSet) TechActionCacheList.Add(cache);
}
public void OnAfterDeserialize()
{
TechSet ??= new HashSet<TechType>();
TechActionCacheSet ??= new HashSet<uint>();
TechSet.Clear();
TechActionCacheSet.Clear();
foreach (var techType in TechListForSerial) TechSet.Add(techType);
foreach (var cache in TechActionCacheList) TechActionCacheSet.Add(cache);
}
public void LearnTech(TechType techType)
{
TechSet.Add(techType);
var techInfo = Table.Instance.TechDataAssets.GetTechInfo(techType);
foreach (var techItem in techInfo.techActions)
TechActionCacheSet.Add(techItem.Id);
}
// 删除科技
public void RemoveTech(TechType techType)
{
TechSet.Remove(techType);
}
// 是否拥有某个科技
public bool CheckIfHasTech(TechType techType)
{
return TechSet.Contains(techType);
}
public bool HasAllTech()
{
bool ret = true;
foreach (TechType tech in System.Enum.GetValues(typeof(TechType)))
{
var techInfo = Table.Instance.TechDataAssets.GetTechInfo(tech);
if (techInfo.GiantTech)
continue;
if (CheckIfHasTech(tech))
continue;
ret = false;
break;
}
return ret;
}
public int GetScore()
{
int ret = 0;
foreach (var tech in TechSet)
{
var techInfo = Table.Instance.TechDataAssets.GetTechInfo(tech);
ret += techInfo.CostLevel * 100;
}
return ret;
}
public bool CheckActionCan(CommonActionId actionId)
{
if (!Table.Instance.ActionDataAssets.GetActionInfo(actionId, out var info)) return false;
if (info.NoNeedTech) return true;
return TechActionCacheSet.Contains(actionId.Id);
}
public bool CheckIfTechUnsee(TechType techType)
{
var techInfo = Table.Instance.TechDataAssets.GetTechInfo(techType);
if (techInfo.GiantTech)
{
int has = 0;
foreach(var tt in techInfo.GiantTechSet)
if (TechSet.Contains(tt))
has++;
//Debug.Log(has);
return has < 3;
}
return !TechSet.Contains(Table.Instance.TechDataAssets.GetTechInfo(techType).FatherTechType);
}
public bool CheckIfTechCanLearn(TechType techType)
{
Debug.Log(techType);
return !TechSet.Contains(techType) && !CheckIfTechUnsee(techType);
}
}
// 主动攻击我的敌人信息
[Serializable]
public class DiplomacyData : ISerializationCallbackReceiver
{
public List<CountryDiplomacyInfo> Info;
private Dictionary<uint, CountryDiplomacyInfo> _infoDict;
public DiplomacyData()
{
Info = new List<CountryDiplomacyInfo>();
}
public DiplomacyData(DiplomacyData copyData)
{
Info = new List<CountryDiplomacyInfo>();
}
public void DeepCopy(DiplomacyData copyData)
{
for (int i = 0; i < copyData.Info.Count; i++)
{
if (Info.Count <= i) Info.Add(new CountryDiplomacyInfo());
Info[i].DeepCopy(copyData.Info[i]);
}
}
public bool CheckTurnAttacker(uint turn, uint playerId)
{
GetCountryDiplomacyInfo(playerId, out var info);
if (info == null) return false;
return info.AttackTurn == 0 || info.AttackTurn < turn;
}
public void AddTurnAttacker(uint playerId, uint turn)
{
GetCountryDiplomacyInfo(playerId, out var info);
if (info == null) return;
info.AttackTurn = turn;
}
public void GetCountryDiplomacyInfo(uint playerId, out CountryDiplomacyInfo info)
{
Refresh();
if (!_infoDict.TryGetValue(playerId, out info))
{
info = new CountryDiplomacyInfo { PlayerId = playerId };
Info.Add(info);
_infoDict[playerId] = info;
}
}
private void Refresh()
{
if (_infoDict == null) _infoDict = new Dictionary<uint, CountryDiplomacyInfo>();
if (_infoDict.Count == Info.Count) return;
_infoDict.Clear();
foreach (var countryDiplomacy in Info) _infoDict[countryDiplomacy.PlayerId] = countryDiplomacy;
}
public void OnBeforeSerialize()
{
}
public void OnAfterDeserialize()
{
}
}
// 对他国的数据
[Serializable]
public class CountryDiplomacyInfo
{
public uint PlayerId;
// 我对国家 PlayerId 的外交关系
public DiplomacyState DiplomacyState;
// 我对国家 PlayerId 的好感值
public float FeelingValue;
// 我对国家 PlayerId 的好感态度
public FeelingState FeelingState;
// 国家 PlayerId 攻击我的回合记录
public uint AttackTurn;
// 国家 PlayerId 是否在我国建立了大使馆
public bool IsEmbassy;
// 联盟破裂回合结束标记
public bool IsLeagueRupture;
public CountryDiplomacyInfo()
{
AttackTurn = 0;
IsEmbassy = false;
IsLeagueRupture = false;
}
public CountryDiplomacyInfo(CountryDiplomacyInfo copyData)
{
PlayerId = copyData.PlayerId;
AttackTurn = copyData.AttackTurn;
DiplomacyState = copyData.DiplomacyState;
FeelingValue = copyData.FeelingValue;
FeelingState = copyData.FeelingState;
IsEmbassy = copyData.IsEmbassy;
IsLeagueRupture = copyData.IsLeagueRupture;
}
public void DeepCopy(CountryDiplomacyInfo copyData)
{
PlayerId = copyData.PlayerId;
AttackTurn = copyData.AttackTurn;
DiplomacyState = copyData.DiplomacyState;
FeelingValue = copyData.FeelingValue;
FeelingState = copyData.FeelingState;
IsEmbassy = copyData.IsEmbassy;
IsLeagueRupture = copyData.IsLeagueRupture;
}
}
}