TH1/Unity/Assets/Scripts/TH1_Data/RuntimeData.cs
2026-05-06 01:59:03 +08:00

309 lines
11 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);
// 首次添加技能时OnSkillAdd不会调用AddLevelOnAddSkillLevels不会触发
// 在此统一通知HeroTask避免各技能手动处理遗漏
if (mapData.UnitMap.GetUnitDataByUnitId(originId, out var origin))
{
origin.HeroTask(mapData)?.OnAddSkillLevels(mapData, skillType, 1);
}
}
// 同步状态图标显示ShowOnUnitMono 配置的技能)
if (this is UnitData unitDataForStatus)
{
unitDataForStatus.Renderer(mapData)?.SyncStatusWithUnitSkills();
}
}
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);
if (mapData.UnitMap.GetUnitDataByUnitId(originId, out var origin))
{
origin.HeroTask(mapData)?.OnAddSkillLevels(mapData, skill.GetSkillType(), 1);
}
// 同步状态图标显示ShowOnUnitMono 配置的技能)
if (this is UnitData unitDataForStatus)
{
unitDataForStatus.Renderer(mapData)?.SyncStatusWithUnitSkills();
}
}
// 添加技能的特殊方法 (这里默认了添加和覆盖都走统一接口)
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))
{
//首次添加时0层消失的叠层技能应当把传入层数视为目标值而非增量
//(构造函数/OnSkillAdd 可能已经保底到 1 层,不应再被叠加)
if (skill.HasLevel && skill.AutoDisappear)
skill.SetLevel(0);
skill.AddLevel(mapData, unitData, this as UnitData, level);
}
skill.OnSkillAdd(mapData, originId);
// 同步状态图标显示ShowOnUnitMono 配置的技能)
if (this is UnitData unitDataForStatus)
{
unitDataForStatus.Renderer(mapData)?.SyncStatusWithUnitSkills();
}
}
}
//初始一个小兵,填加初始技能/国家科技标准的时候,使用这个
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);
// 如果是HideState技能被移除触发渲染更新
if (skillType == SkillType.HideState && this is UnitData unitData)
{
unitData.Renderer(map)?.InstantUpdateUnit(true);
}
// 同步状态图标显示ShowOnUnitMono 配置的技能)
if (this is UnitData unitDataForStatus)
{
unitDataForStatus.Renderer(map)?.SyncStatusWithUnitSkills();
}
}
private void RefreshSkillDict()
{
_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;
}
// 共享的技能迭代缓冲区避免每次OnSkillsTurnStart/End都new List
[MemoryPackIgnore]
private List<SkillBase> _skillIterBuffer;
protected virtual void OnSkillsTurnStart(MapData map)
{
_skillIterBuffer ??= new List<SkillBase>();
_skillIterBuffer.Clear();
_skillIterBuffer.AddRange(Skills);
foreach (var skill in _skillIterBuffer)
{
skill.BeforeTurnStart();
if (skill.IsFinished())
{
skill.OnFinished(this, map);
Skills.Remove(skill);
continue;
}
skill.OnTurnStart(this, map);
}
}
protected virtual void OnSkillsAfterTurnStart(MapData map)
{
_skillIterBuffer ??= new List<SkillBase>();
_skillIterBuffer.Clear();
_skillIterBuffer.AddRange(Skills);
foreach (var skill in _skillIterBuffer)
{
skill.OnAfterTurnStart(this, map);
}
}
protected virtual void OnSkillsTurnEnd(MapData map)
{
_skillIterBuffer ??= new List<SkillBase>();
_skillIterBuffer.Clear();
_skillIterBuffer.AddRange(Skills);
foreach (var skill in _skillIterBuffer) skill.OnTurnEnd(this, map);
}
}
}