TH1/Unity/Assets/Scripts/TH1_Data/RuntimeData.cs
2026-03-10 15:43:35 +08:00

253 lines
8.9 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.Collections.Generic;
using Logic.Skill;
using MemoryPack;
namespace RuntimeData
{
[MemoryPackable]
[MemoryPackUnion(1, typeof(PlayerData))]
[MemoryPackUnion(2, typeof(UnitData))]
[MemoryPackUnion(3, typeof(CityData))]
[MemoryPackUnion(4, typeof(GridData))]
public abstract partial class IdentifierBase
{
// 唯一 ID
public uint Id;
// 技能信息
public List<SkillBase> Skills = new List<SkillBase>();
private Dictionary<SkillType, SkillBase> _skillDict;
// Mark 信息
/*[MemoryPackInclude]
protected bool _renderMark;
public bool RenderMark
{
get => _renderMark;
set => _renderMark = value;
}*/
public bool GetSkill(SkillType skillType, out SkillBase skill)
{
RefreshSkillDict();
return _skillDict.TryGetValue(skillType, out skill);
}
// 添加技能的常规方法 (这里默认了添加和覆盖都走统一接口)
public virtual void AddOrOverrideSkill(SkillType skillType, MapData mapData, uint originId)
{
RefreshSkillDict();
if (_skillDict.ContainsKey(skillType))
{
_skillDict[skillType].OnSkillOverride(mapData, originId, Id);
}
else
{
var skill = SkillFactory.GetSkillBySkillType(skillType);
if (skill == null) return;
Skills.Add(skill);
_skillDict[skillType] = skill;
skill.OnSkillAdd(mapData, originId);
}
}
public virtual void AddOrOverrideSkill(SkillBase skill, MapData mapData, uint originId)
{
if (_skillDict.ContainsKey(skill.GetSkillType())) return;
Skills.Add(skill);
_skillDict[skill.GetSkillType()] = skill;
skill.OnSkillAdd(mapData, originId);
}
// 添加技能的特殊方法 (这里默认了添加和覆盖都走统一接口)
public virtual void SpecialAddOrOverrideSkill(SkillType skillType, MapData mapData, uint originId, SkillOverrideInfo overrideInfo)
{
}
//TODO Legacy 这是一个耦合方法,会被拆解
public virtual void AddSkill_Legacy(SkillType skillType, MapData mapData, bool IsPermanent, int turnLimit,
bool IsLevel, int level, bool autoDisappear, SpecialAddSkillType addType, uint originId)
{
RefreshSkillDict();
//如果技能已经存在
if (_skillDict.ContainsKey(skillType))
{
if (addType == SpecialAddSkillType.Normal) return;
if (addType == SpecialAddSkillType.AddTurnLimit)
{
var skill = _skillDict[skillType];
//如果对方本来就是永久直接return
if (!skill.HasTimeLimit) return;
//否则让对方的limit增加
if (!IsPermanent)
skill.AddTurnLimit((uint)turnLimit + 1);
return;
}
if (addType == SpecialAddSkillType.Force)
{
var skill = _skillDict[skillType];
skill.SetPermanent(IsPermanent);
if (!IsPermanent)
skill.SetTurnsLimit((uint)turnLimit);
skill.SetIsLevel(IsLevel);
skill.SetAutoDisappear(autoDisappear);
if (skill.HasLevel)
{
skill.SetLevel(0);
mapData.UnitMap.GetUnitDataByUnitId(originId, out var unitData);
skill.AddLevel(mapData, unitData, this as UnitData, level);
}
return;
}
if (addType == SpecialAddSkillType.AddLevel)
{
var skill = _skillDict[skillType];
//如果对方不是叠层技能直接return
if (!skill.HasLevel) return;
mapData.UnitMap.GetUnitDataByUnitId(originId, out var unitData);
skill.AddLevel(mapData, unitData, this as UnitData, level);
return;
}
}
else
{
var skill = SkillFactory.GetSkillBySkillType(skillType);
if (skill == null) return;
Skills.Add(skill);
_skillDict[skillType] = skill;
if (!IsPermanent) skill.SetTurnsLimit((uint)turnLimit);
if (IsLevel && mapData.UnitMap.GetUnitDataByUnitId(originId, out var unitData))
skill.AddLevel(mapData, unitData, this as UnitData, level);
skill.OnSkillAdd(mapData, originId);
}
}
//初始一个小兵,填加初始技能/国家科技标准的时候,使用这个
public virtual void AddInitSkill(SkillType skillType, MapData mapData)
{
RefreshSkillDict();
//如果技能已经存在,删除,重置
if (_skillDict.ContainsKey(skillType))
RemoveSkill(skillType,mapData);
var skill = SkillFactory.GetSkillBySkillType(skillType);
if (skill == null) return;
Skills.Add(skill);
_skillDict[skillType] = skill;
}
/*public virtual void AddSkill(SkillType skillType, MapData mapData, uint originId = 0)
{
RefreshSkillDict();
if (_skillDict.ContainsKey(skillType)) return;
var skill = SkillFactory.GetSkillBySkillType(skillType);
if (skill != null)
{
Skills.Add(skill);
_skillDict[skillType] = skill;
skill.OnSkillAdd(mapData, originId);
}
}
public virtual void AddSkill(SkillType skillType, uint turnLimit, MapData mapData, uint originId = 0)
{
RefreshSkillDict();
//如果已经有这个技能了
if (_skillDict.ContainsKey(skillType))
{
var skill = _skillDict[skillType];
//如果对方本来就是永久直接return
if(!skill.HasTimeLimit) return;
//否则让对方的limit增加
skill.AddTurnLimit(turnLimit + 1);
}
//如果还没有这个技能
else
{
var skill = SkillFactory.GetSkillBySkillType(skillType);
if (skill != null)
{
Skills.Add(skill);
_skillDict[skillType] = skill;
skill.SetTurnsLimit(turnLimit);
skill.OnSkillAdd(mapData, originId);
}
}
}*/
public void RemoveSkill(SkillType skillType, MapData map)
{
RefreshSkillDict();
if (!_skillDict.TryGetValue(skillType, out var value)) return;
Skills.Remove(value);
_skillDict.Remove(skillType);
}
private void RefreshSkillDict()
{
if (_skillDict == null) _skillDict = new Dictionary<SkillType, SkillBase>();
if (_skillDict.Count != Skills.Count)
{
_skillDict.Clear();
foreach (var skill in Skills) _skillDict[skill.GetSkillType()] = skill;
}
}
// MemoryPack 反序列化之后的后处理
[MemoryPackOnDeserialized]
public void OnAfterMemoryPackDeserialize()
{
_skillDict ??= new Dictionary<SkillType, SkillBase>();
_skillDict.Clear();
foreach (var skill in Skills) _skillDict[skill.GetSkillType()] = skill;
}
protected virtual void OnSkillsTurnStart(MapData map)
{
var copy = new List<SkillBase>(Skills);
foreach (var skill in copy)
{
skill.BeforeTurnStart();
if (skill.IsFinished())
{
skill.OnFinished(this, map);
Skills.Remove(skill);
continue;
}
skill.OnTurnStart(this, map);
}
}
protected virtual void OnSkillsAfterTurnStart(MapData map)
{
var copy = new List<SkillBase>(Skills);
foreach (var skill in copy)
{
skill.OnAfterTurnStart(this, map);
}
}
protected virtual void OnSkillsTurnEnd(MapData map)
{
var copy = new List<SkillBase>(Skills);
foreach (var skill in copy) skill.OnTurnEnd(this, map);
}
}
}