557 lines
16 KiB
C#

/*
* @Author: 白哉
* @Description: 技能类
* @Date: 2025年04月22日 星期二 17:04:44
* @Modify:
*/
using System;
using System.Collections.Generic;
using MemoryPack;
using RuntimeData;
using UnityEngine;
namespace Logic.Skill
{
public enum SkillDamageEvent
{
ActiveAttackBeforeStarted,
ActiveAttackFinished,
}
public interface ISkill
{
public SkillType GetSkillType();
public bool ReservedOnTransform(UnitData self, UnitFullType fullType);
public void NewSkillOnTransform(List<SkillBase> oldSkills);
public void OnGet();
public void OnLose(UnitData self,MapData map);
// 事件触发生命周期 (事件已发生)
public void OnMove(UnitData self, GridData grid, MapData mapData, MoveType moveType);
// 伤害结算前自身承受阶段
public void BeforeDamagedSupportStage(MapData mapData, SettlementInfo info);
// 伤害结算前自身转移阶段
public void BeforeDamagedTransformStage(MapData mapData, SettlementInfo info);
// 对他人伤害结算前
public void BeforeDamageOther(MapData mapData, SettlementInfo info);
// 伤害结算时
public void OnDamaged(MapData mapData, SettlementInfo info);
// 对他人伤害结算时
public void OnDamageOther(MapData mapData, SettlementInfo info);
public void OnHealOther(MapData mapData, UnitData origin, HealType healType);
// 主动攻击之前
public void BeforeActiveAttackOther(MapData mapData, UnitData origin, UnitData target,out int addDmg);
// 主动攻击之后
public void AfterActiveAttackOther(MapData mapData, UnitData origin, UnitData target);
public void AfterActiveAttacked(MapData mapData, UnitData origin, UnitData target);
// 事件触发生命周期 (时刻)
public void OnTurnStart(UnitData self, MapData mapData);
public void OnTurnStart(CityData city, MapData mapData);
public void OnTurnStart(PlayerData self, MapData mapData);
public void OnTurnStart(GridData self, MapData mapData);
public void OnTurnEnd(UnitData self, MapData mapData);
public void OnTurnEnd(CityData city, MapData mapData);
public void OnTurnEnd(PlayerData self, MapData mapData);
public void OnTurnEnd(GridData self, MapData mapData);
public void OnFinished(UnitData self, MapData mapData);
// 属性变化
// 是否能攻击所有人
public bool CanAttackAll(UnitData self, MapData mapData);
// 是否限制自身移动
public bool IsLimitSelfMove(UnitData self, MapData mapData);
// 是否限制自身攻击
public bool IsLimitSelfAttack(UnitData self, MapData mapData);
// 是否限制敌方反击
public bool IsLimitTargetCounterAttack(UnitData self, MapData mapData);
// 是否限制自身反击
public bool IsLimitSelfCounterAttack(UnitData self, MapData mapData);
// 是否无视敌人控制区
public bool IsIgnoreControlArea(UnitData self, MapData mapData);
// 是否限制自身经验增长
public bool IsLimitSelfExp(UnitData self, MapData mapData);
// 是否无视树林和山脉
public bool IsIgnoreWoodAndMountains(UnitData self, MapData mapData);
// 是否能在指定海陆层移动
public bool IsCanMoveOnTerrain(UnitData self, MapData mapData, TerrainType terrainType);
// 是否能在指定地形层移动
public bool IsCanMoveOnFeature(UnitData self, MapData mapData, TerrainFeature featureType);
// 是否无视地形层移动减损
public bool IsIgnoreMoveLoss(UnitData self, MapData mapData, TerrainFeature terrainType);
// 是否无视植被层移动减损
public bool IsIgnoreMoveLoss(UnitData self, MapData mapData, Vegetation terrainType);
// 是否具备同类数量限制
public bool IsLimitCount(UnitData self, MapData mapData, out int count);
// 是否能移动到我方的无人城市
public bool IsCanMoveToNoUnitSelfCity(UnitData self, MapData mapData);
// 是否能移动到我方的英雄附近
public bool IsCanMoveGiantNearbyGrid(UnitData self, MapData mapData);
// 是否能移动到
// 能否被杀死
public bool IsCanBeKill(UnitData self, MapData mapData);
// 能否被伤害
public bool IsCanBeDamaged(UnitData self, MapData mapData, int dmg);
// 能否制造矿山
public bool IsCanBuildMine(UnitData self, MapData mapData);
// 是否隐身
public bool IsInvisible(UnitData self, MapData mapData);
// 值变化
// 获取额外视野(视野增加)
public int GetExtraSight(UnitData self, MapData mapData);
// 获取暴击率
public float GetCriticalHitRate(UnitData self, MapData mapData);
public float GetAttackAdditionParam(MapData mapData, UnitData self, UnitData target = null);
public float GetAttackMultiplicationParam(MapData mapData, UnitData self, UnitData target = null);
public float GetDefenseAdditionParam(MapData mapData, UnitData self, UnitData target = null);
public float GetDefenseMultiplicationParam(MapData mapData, UnitData self, UnitData target = null);
// 获得额外移动范围
public int GetExtraMoveRange(UnitData self);
// 获得额外攻击范围
public int GetExtraAttackRange(UnitData self);
// 获取特定技能加成
public int GetSpecialSkillBonus(MapData mapData, UnitData self, SkillType skillType);
// 全局技能
// 当有单位受伤结算前
public void BeforeUnitDamaged(UnitData self, MapData mapData, SettlementInfo info);
// 当有单位受伤结算时
public void OnUnitDamaged(UnitData self, MapData mapData, SettlementInfo info);
// 当有单位移动时
public void OnAnyUnitMove(MapData map, UnitData self, UnitData moveUnit, GridData target, MoveType moveType);
// 当有单位死亡时
public void OnAnyUnitDie(MapData map, UnitData self);
// 当有单位创建时
public void OnAnyUnitCreate(MapData map, UnitData self, UnitData newUnit);
}
[MemoryPackable]
public abstract partial class SkillBase : ISkill
{
[MemoryPackInclude]
protected bool IsPermanent;
//是否叠层
[MemoryPackInclude]
protected bool IsLevelSkill;
//如果是叠层且0层的时候仍然有该状态
[MemoryPackInclude]
protected bool ZeroLevelStay;
[MemoryPackInclude]
protected uint Turns;
[MemoryPackInclude]
protected uint TurnsLimit;
[MemoryPackInclude]
protected float Score;
[MemoryPackInclude]
protected int _level;
[MemoryPackInclude]
protected int _levelLimit;
[MemoryPackInclude]
protected bool _autoDisappear;
public virtual int Level => _level;
public bool HasTimeLimit => !IsPermanent;
public int LastTime => (int)TurnsLimit - (int)Turns;
public bool NoShow => _autoDisappear && _level == 0;
public bool ShowSkillLevel => IsLevelSkill && !NoShow;
public bool ShowSkill => !IsLevelSkill || ShowSkillLevel;
[MemoryPackConstructor]
public SkillBase()
{
IsLevelSkill = false;
Turns = 0;
_level = 0;
_autoDisappear = true;
}
public abstract SkillType GetSkillType();
public virtual bool ReservedOnTransform(UnitData self, UnitFullType fullType)
{
return false;
}
public virtual void NewSkillOnTransform(List<SkillBase> oldSkills)
{
}
public virtual void OnGet()
{
}
public virtual void OnLose(UnitData self,MapData map)
{
}
public virtual float GetScore()
{
return Score;
}
public virtual bool IsFinished()
{
Turns++;
return (!IsPermanent && TurnsLimit < Turns) || (IsLevelSkill && _autoDisappear && _level == 0);
}
public SkillBase GetCopySkill()
{
var skill = SkillFactory.GetSkillBySkillType(GetSkillType());
GetSkillCopy(skill);
return skill;
}
public virtual void SetTurnsLimit(uint time)
{
IsPermanent = false;
TurnsLimit = time;
}
public virtual void AddTurnLimit(uint time)
{
TurnsLimit += time;
}
public virtual void AddLevel(MapData map, UnitData origin, UnitData self, int add)
{
_level += add;
if (_level > _levelLimit) _level = _levelLimit;
if (!map.GetPlayerDataByUnitId(origin.Id, out var player)) return;
origin.HeroTask(map)?.OnAddSkillLevels(map, GetSkillType(), (uint)add);
}
public virtual void ReduceLevel(MapData map, UnitData origin, int reduce)
{
_level -= reduce;
}
public virtual void SetLevel(int level)
{
_level = level;
}
public virtual void GetSkillCopy(SkillBase skill)
{
skill.IsPermanent = IsPermanent;
skill.Turns = Turns;
skill.TurnsLimit = TurnsLimit;
skill.Score = Score;
}
public virtual void DeepCopy(SkillBase copySkill)
{
IsPermanent = copySkill.IsPermanent;
Turns = copySkill.Turns;
TurnsLimit = copySkill.TurnsLimit;
}
public virtual void OnSkillAdd(UnitData self, MapData mapData)
{
}
public virtual void OnMove(UnitData self, GridData grid, MapData mapData,MoveType moveType)
{
}
public virtual void BeforeDamagedSupportStage(MapData mapData, SettlementInfo info)
{
}
public virtual void BeforeDamagedTransformStage(MapData mapData, SettlementInfo info)
{
}
public virtual void BeforeDamageOther(MapData mapData, SettlementInfo info)
{
}
public virtual void OnDamaged(MapData mapData, SettlementInfo info)
{
}
public virtual void OnDamageOther(MapData mapData, SettlementInfo info)
{
}
public virtual void OnHealOther(MapData mapData, UnitData origin,HealType healType)
{
}
public virtual void BeforeActiveAttackOther(MapData mapData, UnitData origin, UnitData target,out int addDmg)
{
addDmg = 0;
}
public virtual void AfterActiveAttackOther(MapData mapData, UnitData origin, UnitData target)
{
}
public virtual void AfterActiveAttacked(MapData mapData, UnitData origin, UnitData target)
{
}
public virtual void OnTurnStart(UnitData self, MapData mapData)
{
}
public virtual void OnTurnStart(GridData self, MapData mapData)
{
}
public virtual void OnTurnStart(CityData city, MapData mapData)
{
}
public virtual void OnTurnStart(PlayerData self, MapData mapData)
{
}
public virtual void OnTurnEnd(UnitData self, MapData mapData)
{
}
public virtual void OnTurnEnd(CityData city, MapData mapData)
{
}
public virtual void OnTurnEnd(PlayerData self, MapData mapData)
{
}
public virtual void OnTurnEnd(GridData self, MapData mapData)
{
}
public virtual void OnFinished(UnitData self, MapData mapData) { }
public virtual bool CanAttackAll(UnitData self, MapData mapData)
{
return false;
}
public virtual bool IsLimitSelfMove(UnitData self, MapData mapData)
{
return false;
}
public virtual bool IsLimitSelfAttack(UnitData self, MapData mapData)
{
return false;
}
public virtual bool IsLimitTargetCounterAttack(UnitData self, MapData mapData)
{
return false;
}
public virtual bool IsLimitSelfCounterAttack(UnitData self, MapData mapData)
{
return false;
}
public virtual bool IsIgnoreControlArea(UnitData self, MapData mapData)
{
return false;
}
public virtual bool IsLimitSelfExp(UnitData self, MapData mapData)
{
return false;
}
public virtual bool IsIgnoreWoodAndMountains(UnitData self, MapData mapData)
{
return false;
}
public virtual bool IsCanMoveOnTerrain(UnitData self, MapData mapData, TerrainType terrainType)
{
return false;
}
public virtual bool IsCanMoveOnFeature(UnitData self, MapData mapData, TerrainFeature terrainType)
{
return false;
}
public virtual bool IsIgnoreMoveLoss(UnitData self, MapData mapData, TerrainFeature terrainType)
{
return false;
}
public virtual bool IsIgnoreMoveLoss(UnitData self, MapData mapData, Vegetation terrainType)
{
return false;
}
public virtual bool IsLimitCount(UnitData self, MapData mapData, out int count)
{
count = -1;
return false;
}
public virtual bool IsCanMoveToNoUnitSelfCity(UnitData self, MapData mapData)
{
return false;
}
public virtual bool IsCanMoveGiantNearbyGrid(UnitData self, MapData mapData)
{
return false;
}
public virtual bool IsCanBeKill(UnitData self, MapData mapData)
{
return true;
}
public virtual bool IsCanBeDamaged(UnitData self, MapData mapData, int dmg)
{
return true;
}
public virtual bool IsCanBuildMine(UnitData self, MapData mapData)
{
return false;
}
public virtual bool IsInvisible(UnitData self, MapData mapData)
{
return false;
}
public virtual int GetExtraSight(UnitData self, MapData mapData)
{
return 0;
}
public virtual float GetCriticalHitRate(UnitData self, MapData mapData)
{
return 0;
}
public virtual float GetAttackAdditionParam(MapData mapData, UnitData self, UnitData target = null)
{
return 0;
}
public virtual float GetDefenseAdditionParam(MapData mapData, UnitData self, UnitData target = null)
{
return 0;
}
public virtual float GetAttackMultiplicationParam(MapData mapData, UnitData self, UnitData target = null)
{
return 1;
}
public virtual float GetDefenseMultiplicationParam(MapData mapData, UnitData self, UnitData target = null)
{
return 1;
}
public virtual int GetExtraMoveRange(UnitData self)
{
return 0;
}
public virtual int GetExtraAttackRange(UnitData self)
{
return 0;
}
public virtual int GetSpecialSkillBonus(MapData mapData, UnitData self, SkillType skillType)
{
return 1;
}
public virtual void BeforeUnitDamaged(UnitData self, MapData mapData, SettlementInfo info)
{
}
public virtual void OnUnitDamaged(UnitData self, MapData mapData, SettlementInfo info)
{
}
public virtual void OnAnyUnitMove(MapData map, UnitData self, UnitData moveUnit, GridData target, MoveType moveType)
{
}
public virtual void OnAnyUnitDie(MapData map, UnitData self)
{
}
public virtual void OnAnyUnitCreate(MapData map, UnitData self, UnitData newUnit)
{
}
}
}