TH1/My project/Assets/Scripts/Data/PlayerData.cs
2025-06-13 03:56:58 +08:00

602 lines
18 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 Logic.Action;
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
}
[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 == 31)
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 PlayerWealth;
//分数
public int PlayerScore;
// 视野
public MapSightData Sight;
// 科技
public TechTreeData TechTree;
// 奇观
public WonderData Wonder;
// 用于记录已经连续几个 turn 没有进行攻击
public int TurnNoAttack;
// 用于记录累计击杀多少 unit
public int TotalKill;
public List<uint> MeetPlayerSet;
//用于记录是否死亡是否要centMessage来宣告死亡信息
public bool DieMark = false;
// 无参数初始化
public PlayerData()
{
Sight = new MapSightData();
TechTree = new TechTreeData();
Wonder = new WonderData();
MeetPlayerSet = new List<uint>();
//InitData();
}
// 带 ID 初始化
public PlayerData(uint civId, uint forceId, MapIdGenerator idGenerator)
{
Turn = 0;
Id = idGenerator.GeneratorId();
if(Table.Instance.PlayerDataAssets.GetPlayerInfo(civId,forceId,out var info))
TechTree = new TechTreeData(info.TechStart);
else
TechTree = new TechTreeData();
Sight = new MapSightData();
Wonder = new WonderData();
MeetPlayerSet = new List<uint>();
MeetPlayerSet.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;
PlayerWealth = copyData.PlayerWealth;
Sight = new MapSightData(copyData.Sight);
TechTree = new TechTreeData(copyData.TechTree);
Wonder = new WonderData(copyData.Wonder);
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;
PlayerWealth = copyData.PlayerWealth;
Sight.DeepCopy(copyData.Sight);
TechTree.DeepCopy(copyData.TechTree);
Wonder.DeepCopy(copyData.Wonder);
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;
PlayerWealth = 5;
PlayerCivId = civId;
PlayerForceId = forceId;
TurnNoAttack = 0;
TotalKill = 0;
}
// 全局通知调用
public void OnTurnStart(MapData map)
{
Turn++;
for (int i = Skills.Count - 1; i >= 0; i--)
{
var skill = Skills[i];
if (skill.IsFinished())
{
Skills.RemoveAt(i);
continue;
}
skill.OnTurnStart(this, map);
}
}
public void OnTurnEnd(MapData map)
{
foreach (var skill in Skills)skill.OnTurnEnd(this, map);
}
}
// 奇观信息
[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> SightGidList;
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()
{
SightGidList ??= new List<uint>();
SightGidList.Clear();
foreach (var gid in SightGidSet) SightGidList.Add(gid);
}
public void OnAfterDeserialize()
{
SightGidSet ??= new HashSet<uint>();
SightGidSet.Clear();
foreach (var gid in SightGidList) SightGidSet.Add(gid);
}
// 判断是否在视野内
public bool CheckIsInSight(uint gid)
{
return SightGidSet.Contains(gid);
}
}
// 科技信息
[Serializable]
public class TechTreeData : ISerializationCallbackReceiver
{
private HashSet<TechType> TechSet;
public HashSet<uint> TechActionCacheSet;
//仅用于序列化
public List<TechType> TechList;
public List<uint> TechActionCacheList;
public TechTreeData(List<TechType> StartTechList = null)
{
TechSet = new HashSet<TechType>();
TechActionCacheSet = new HashSet<uint>();
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()
{
TechList ??= new List<TechType>();
TechActionCacheList ??= new List<uint>();
TechList.Clear();
TechActionCacheList.Clear();
foreach (var techType in TechSet) TechList.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 TechList) 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)
{
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);
}
}
}