602 lines
18 KiB
C#
602 lines
18 KiB
C#
/*
|
||
* @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);
|
||
|
||
}
|
||
}
|
||
} |