1508 lines
48 KiB
C#
1508 lines
48 KiB
C#
/*
|
||
* @Author: 白哉
|
||
* @Description: 技能类
|
||
* @Date: 2025年04月22日 星期二 17:04:44
|
||
* @Modify:
|
||
*/
|
||
|
||
|
||
using System.Collections.Generic;
|
||
using Logic.Action;
|
||
using MemoryPack;
|
||
using RuntimeData;
|
||
using UnityEngine;
|
||
|
||
|
||
//SkillType 只能新增, 不能删除!
|
||
public enum SkillType
|
||
{
|
||
|
||
NONE = 0,
|
||
PEACE = 1,
|
||
DASH = 2,
|
||
ESCAPE = 3,
|
||
PERSIST = 4,
|
||
SPLASH = 5,
|
||
SNEAK = 6,
|
||
STIFF = 7,
|
||
FORTIFY = 8,
|
||
HEAL = 9,
|
||
CONVERT = 10,
|
||
CARRY = 11,
|
||
SCOUT = 12,
|
||
STATIC = 13, // deprecated compatibility id; do not add to unit rows
|
||
HIDE = 14, // no use
|
||
CREEP = 15,
|
||
INFILTRATE = 16,
|
||
BOOST = 17, // no use
|
||
EXPLODE = 18, // no use
|
||
STOMP = 19,
|
||
ATTACKUP = 20,
|
||
SPEEDUP = 21,
|
||
FORESTDEFENSE = 22,
|
||
WATERDEFENSE = 23,
|
||
OCEANDEFENSE = 24,
|
||
MOUNTAINDEFENSE = 25,
|
||
MOUNTAINMOVE = 26,
|
||
WATERMOVE = 27,
|
||
OCEANMOVE = 28,
|
||
SURPRISE = 29,
|
||
POISON = 30, // no use
|
||
POISONED = 31,
|
||
UNIQUE = 32,
|
||
SWAP = 33,
|
||
AUTOHEAL = 34,
|
||
CITYTRANSPORT = 35,
|
||
ALLYCOUNTER = 36,
|
||
POWERUP = 37,
|
||
ALLYTRANSPORT = 38,
|
||
QUARTET = 39,
|
||
TAICHI = 40,
|
||
POORHEALTH = 41,
|
||
ROYALFLAMES = 42,
|
||
VAMPIRE = 43,
|
||
SUPERDASH = 44,
|
||
PHOENIX = 45,
|
||
PHOENIXEGG = 46,
|
||
ILLUSION = 47,
|
||
LUCK = 48, // Sanae Divine Pending
|
||
CRITICAL = 49,
|
||
MOONPRINCESS = 50, // no use
|
||
ETERNITY = 51, // no use
|
||
GALAXYARROW = 52,
|
||
WINDGOD = 53,
|
||
WINDPRIESTESS = 54, // no use
|
||
MOUNTAINGOD = 55,
|
||
CURSEGOD = 56, // no use
|
||
NUCLEAR = 57, // no use
|
||
NUCLEARFUSION = 58, // no use
|
||
CATCART = 59, // no use
|
||
RECYCLE = 60, // no use
|
||
THIRDEYE = 61, // no use
|
||
SUPERHIDE = 62, // no use
|
||
// 文明技能 = ,
|
||
CommonPlayerSkillIndustry = 63,
|
||
RemiliaForcesSkill1 = 64, // no use
|
||
EgyptCivSkill1 = 65, // no use
|
||
// 2025.8.13新增 = ,
|
||
RENGESYOU = 66, // no use
|
||
RENGESYOUCONTRO = 67, // no use
|
||
LAEVATAIN = 68, // no use
|
||
LAEVATAINPREY = 69, // no use
|
||
SATSUJINKI = 70,
|
||
PHILOSTONE = 71,
|
||
ROYALFLAMESPRO = 72,
|
||
VAMPIREPRO = 73,
|
||
DUO = 74,
|
||
TRIO = 75,
|
||
//2025.9.5 永远亭新增 = ,
|
||
KaguyaFrenchNapoleonicCode = 76,
|
||
KaguyaFrenchWarriorSynergy = 77,
|
||
KaguyaFrenchBambooMove = 78,
|
||
KaguyaFrenchCatapultSynergy = 79,
|
||
BAMBOOMOVE = 80,
|
||
KAGUYAFRENCHSYNERGY = 81,
|
||
KAGUYAFRENCHSYNERGYDEBUFF = 82,
|
||
NOPOPULATION = 83,
|
||
// 2025.9.12新增Demo V1.4 = ,
|
||
TEWIFRENCHSIGHT = 84,
|
||
TEWIFRENCHDIE = 85,
|
||
TEWIFRENCHATTACK = 86,
|
||
TEWIFRENCHKILL = 87,
|
||
TEWIFRENCHBUFF = 88,
|
||
EIRINFRENCHKILL = 89,
|
||
EIRINFRENCHATTACK = 90,
|
||
EIRINFRENCHBUFF = 91,
|
||
MOKOUFRENCHEGG = 92,
|
||
MOKOUFRENCHREVIVE = 93,
|
||
MOVERANGEUP = 94,
|
||
ATTACKRANGEUP = 95,
|
||
ATTACKAFTERKILL = 96,
|
||
MOKOUFRENCHBOOM = 97,
|
||
KAGUYAFRENCHFOREVERBUFF = 98,
|
||
KAGUYAFRENCHATTACK = 99,
|
||
KAGUYAFRENCHAROUND = 100,
|
||
KAGUYAFRENCHATTACKPRO = 101,
|
||
REISENILLUSION = 102,
|
||
REISENFRENCHKILL = 103,
|
||
REISENFRENCHATTAK = 104,
|
||
REISENILLUSIONPRO = 105,
|
||
REISENFRENCHKILLPRO = 106, // no use
|
||
FLY = 107, // no use
|
||
FORESTSTARTDASH = 108,
|
||
LANDONLY = 109,
|
||
LANDANDWATER = 110,
|
||
// 10.12新增 = ,
|
||
SAKUYAFLY = 111,
|
||
SAKUYAGUARD = 112,
|
||
SAKUYAKILL = 113,
|
||
SAKUYAFLYPRO = 114,
|
||
PATCHOULIMOVE = 115,
|
||
PATCHOULIREST = 116,
|
||
PATCHOULISTONE = 117,
|
||
PATCHOULISTONEPRO = 118,
|
||
PATCHOULIEARTH = 119,
|
||
PATCHOULIWATER = 120,
|
||
PATCHOULIMETAL = 121,
|
||
PATCHOULIMOVEPRO = 122,
|
||
PATCHOULIWOOD = 123,
|
||
PATCHOULIFIRE = 124,
|
||
MEILINGREST = 125,
|
||
MEILINGCOUNTER = 126,
|
||
MEILINGDUEL = 127,
|
||
CANTMOVE = 128,
|
||
REMILIAHELP = 129,
|
||
REMILIAHUNTER = 130, // no use
|
||
REMILIAATTACK = 131, // no use
|
||
REMILIABUFF = 132,
|
||
FLANDREATTACK = 133,
|
||
FLANDREKILL = 134,
|
||
FLANDREBUFF = 135,
|
||
RemiliaEgyptianEmpireKill = 136,
|
||
//红雾领地下所有单位的实时吸血效果 = ,
|
||
ScarletMistRealTimeVampire = 137,
|
||
REDMISTDEFENSE = 138,
|
||
REMILIAHELPPRO = 139,
|
||
KOAKUMADEVOTION = 140,
|
||
KOAKUMAHERO = 141,
|
||
ScarletMistRealTimeVampireDebuff = 142, // no use
|
||
ScarletKoakuma = 143,
|
||
REMILIABUFF2 = 144,
|
||
REMILIABUFF3 = 145,
|
||
REMILIAABSORB = 146,
|
||
// 11.13新增 = ,
|
||
MORIYABUFF = 147,
|
||
KANAKOTECH = 148,
|
||
KANAKOBATTLEFIELD = 149,
|
||
KANAKOMOUNTAIN = 150,
|
||
KANAKOMOUNTAINATTACK = 151,
|
||
KANAKOMOUNTAINBUFF = 152,
|
||
KANAKOSITTING = 153,
|
||
KANAKOWIND = 154,
|
||
SUWAKOMOVE = 155,
|
||
SUWAKOATTACK = 156,
|
||
SUWAKOATTACKPRO = 157,
|
||
SUWAKOATTACKALLY = 158,
|
||
SUWAKOHEBIATTACK = 159,
|
||
SANAEMOVE = 160,
|
||
SANAEWIND = 161,
|
||
SANAEWINDX = 162,
|
||
SANAEDIVINE = 163,
|
||
SANAENINE = 164,
|
||
TENGUBUFF = 165,
|
||
PATHSTOMP = 166,
|
||
AYAMOVEAGAIN = 167,
|
||
AYAMOVEAGAINBUFF = 168,
|
||
MOMIJISIGHT = 169,
|
||
MOMIJIHUNT = 170,
|
||
MOMIJIPREY = 171,
|
||
MOMIJIHUNTER = 172,
|
||
MOMIJIBUFF = 173,
|
||
MOMIJIHUNTERATTACK = 174,
|
||
SANAENINECONTINUE = 175, // no use
|
||
GRIDSANAENINECONTINUEDAMAGE = 176,
|
||
GRIDMOMIJIPREY = 177,
|
||
GRIDMOUNTAIN = 178,
|
||
JUNKEROFFICER = 179,
|
||
MORIYAKNIGHTMOVE = 180,
|
||
MORIYAROAD = 181,
|
||
OFFICER = 182,
|
||
KANAKOWINDPRO = 183,
|
||
KANAKOWAR = 184,
|
||
KANAKOWARPRO = 185,
|
||
SUWAKOCOMBINE = 186,
|
||
SUWAKOSPLIT = 187,
|
||
SUWAKOFULLMAP = 188,
|
||
SUWAKOHEBICOMBINE = 189,
|
||
SUWAKOHEBISPLIT = 190,
|
||
SUWAKOHEBI = 191,
|
||
KANAKOBATTLEFIELDPRO = 192,
|
||
AYABUFF = 193,
|
||
DIVINE_F2_DEFENSE = 194,
|
||
DIVINE_F2_RESIST= 195,
|
||
|
||
DIVINE_F3_MOVE= 196,
|
||
DIVINE_F3_RESIST= 197,
|
||
|
||
DIVINE_F4_KILL= 198,
|
||
DIVINE_F4_ATK= 199,
|
||
|
||
|
||
|
||
DIVINE_E2_ATK = 200,
|
||
DIVINE_E2_MOVE = 201,
|
||
|
||
DIVINE_E3_HP = 202,
|
||
DIVINE_E3_COUNTER = 203,
|
||
|
||
DIVINE_E4_KILL = 204,
|
||
DIVINE_E4_DEFENSE = 205,
|
||
TREATASHERO = 206,
|
||
|
||
//-----v0.6.6-----
|
||
ESCAPEPRO = 207,
|
||
SCOUTPRO = 208,
|
||
MOMIJIKILL = 209,
|
||
|
||
// 3.3 新增
|
||
KomeijiFear = 210,
|
||
SatoriSee = 211,
|
||
SatoriBan = 212,
|
||
SkillBan = 213,
|
||
SkillBanBoom = 214,
|
||
Undead = 215,
|
||
BonePile = 216,
|
||
CorpseBuff = 217,
|
||
HideState = 218,
|
||
CanHide = 219,
|
||
KoishiRespawn = 220,
|
||
KoishiAuto = 221,
|
||
KoishiAutoMove = 222,
|
||
BoneSacrifice = 223,
|
||
FearMaker = 224,
|
||
KoishiUndead = 225,
|
||
KoishiDeathFear = 226,
|
||
RinCorpseCollet = 227,
|
||
RinFire = 228,
|
||
UtsuhoDelayAct = 229,
|
||
UtsuhoReadyMove = 230,
|
||
UtsuhoRadiation = 231,
|
||
GridRadiation = 232,
|
||
UtsuhoBoneMaker = 233,
|
||
UtsuhoReadyMoveSuper = 234,
|
||
YuugiPush = 235,
|
||
YuugiDash = 236,
|
||
YuugiDashPro = 237,
|
||
BoneAttackUp = 238,
|
||
YuugiMove = 239,
|
||
YuugiMovePlus = 240,
|
||
SatoriAttack = 241,
|
||
SatoriAttackBoom = 242,
|
||
KomeijiFearImmune = 243,
|
||
MEILINGATTACKUP = 244,
|
||
KomeijiRiderKill = 245,
|
||
KomeijiRiderTrans = 246,
|
||
KomeijiKnightKill = 247,
|
||
DieBonePile = 248,
|
||
KomeijiRiderAdd = 249,
|
||
KomeijiFearSplash = 250,
|
||
UtsuhoBase = 251,
|
||
MahaCorpseBuff = 252,
|
||
KomeijiKnightAdd = 253,
|
||
// 妹红占位技能:凤翼天翔
|
||
MokouFrenchEnhance = 254,
|
||
KaguyaFrenchCrescentMoon = 255,
|
||
KaguyaFrenchNewMoon = 256,
|
||
// 蓬莱山法国狼技能
|
||
HouraisanFrenchWolfStart = 257,
|
||
HouraisanFrenchWolfMoon = 258,
|
||
EirinFrenchSuperAttack = 259,
|
||
EirinFrenchOverHeal = 260,
|
||
HouraisanFrenchFakeMoon = 261,
|
||
AttackGetAttackPoint = 262,
|
||
AYADAMAGEDEBUFF = 263,
|
||
SAKUYATIRED = 264,
|
||
CITYSTOLEN = 265,
|
||
// 深蓝:纯视觉技能,让单位贴图按时间循环变色,没有任何数值/逻辑效果
|
||
Shenlan = 266,
|
||
AssaultFortress = 267,
|
||
QueenTerritoryMove = 268,
|
||
KingCoin = 269,
|
||
SakuyaEnhanced = 270,
|
||
FearMakerPro = 271,
|
||
CityBuildingUsageMarker = 272,
|
||
MokouFrenchMoveKill = 273,
|
||
ReimuHakureiProtectionCaster = 274,
|
||
HakureiProtection = 275,
|
||
ReimuExterminationAttack = 276,
|
||
ReimuExtermination = 277,
|
||
ReimuExterminationPulse = 278,
|
||
ReimuRandomOfuda = 279,
|
||
ReimuOfudaAlmsOnDamaged = 280,
|
||
ReimuOfudaAlmsOnAttack = 281,
|
||
ReimuOfudaRaidDouble = 282,
|
||
ReimuOfudaProtectionOffering = 283,
|
||
ReimuOfudaEnemyAttackTax = 284,
|
||
ReimuOfudaEnemyDamagedTax = 285,
|
||
ReimuOfudaKillBounty = 286,
|
||
ReimuOfudaExterminationOffering = 287,
|
||
SumirekoOccultOrbOwner = 288,
|
||
SumirekoNorwayOrbSwapMoveAttack = 289,
|
||
SumirekoDenmarkOrbSwapAttackDefense = 290,
|
||
SumirekoEnglandOrbDamageProxy = 291,
|
||
SumirekoOrbSwapMaxValue = 292,
|
||
KasenBeastGuideOwner = 293,
|
||
KasenBeastGuideAura = 294,
|
||
KasenOniForm = 295,
|
||
AunnPetrifiedState = 296,
|
||
AunnTwinBody = 297,
|
||
AunnSharedHealth = 298,
|
||
AunnTwinOperable = 299,
|
||
SuikaMiniSpawnAfterMove = 300,
|
||
SuikaMiniStack = 301,
|
||
SuikaDamageHalveDropMini = 302,
|
||
SuikaBigForm = 303,
|
||
SuikaGiantForm = 304,
|
||
SuikaFallingSplash = 305,
|
||
SuikaMiniUnitMarker = 306,
|
||
ReimuFantasyNature = 307,
|
||
HakureiRoundShieldWall = 308,
|
||
HakureiKarviEmbark = 309,
|
||
ValhallaOath = 310,
|
||
HakureiEinherjarPoint = 311,
|
||
HakureiCityEinherjarOffering = 312,
|
||
NoCounterAttack = 313,
|
||
HakureiDragonshipRam = 314,
|
||
CityRaided = 315,
|
||
Berserk = 316,
|
||
Disperse = 317,
|
||
Item = 318,
|
||
AlwaysHide = 319,
|
||
ValkyrieMoveHeal = 320,
|
||
ValkyrieProtectionCaster = 321,
|
||
ValkyrieProtection = 322,
|
||
SumirekoNorwayOrbBuff = 323,
|
||
SumirekoDenmarkOrbBuff = 324,
|
||
SumirekoEnglandOrbBuff = 325,
|
||
SumirekoOrbSwapMaxValueBuff = 326,
|
||
SuikaThrowReady = 327,
|
||
SuikaThrownUnit = 328,
|
||
SuikaThrowUnitBuff = 329,
|
||
//补充之前的bug问题
|
||
Max = 999,
|
||
}
|
||
|
||
|
||
namespace Logic.Skill
|
||
{
|
||
public enum SpecialAddSkillType
|
||
{
|
||
Normal, // 普通添加,如果已经有了这个技能了就不添加了
|
||
Force, // 强制添加,如果已经有了这个技能了就覆盖掉原来的
|
||
AddTurnLimit, // 如果已经有了这个技能了,就增加回合限制,否则正常添加
|
||
AddLevel,// 如果已经有了这个技能了,就增加叠层数
|
||
}
|
||
|
||
public struct SkillOverrideInfo
|
||
{
|
||
public bool IsPermanent;
|
||
public int TurnLimit;
|
||
public bool IsLevel;
|
||
public int Level;
|
||
public bool AutoDisappear;
|
||
public uint OriginId;
|
||
}
|
||
|
||
public enum SkillDamageEvent
|
||
{
|
||
ActiveAttackBeforeStarted,
|
||
ActiveAttackFinished,
|
||
}
|
||
|
||
|
||
public interface ISkill
|
||
{
|
||
public SkillType GetSkillType();
|
||
|
||
public bool IsAllSkillBan();
|
||
|
||
public bool ReservedOnTransform(UnitData self, UnitFullType fullType);
|
||
public bool ReservedOnTransformBoat(UnitData self, UnitFullType fullType);
|
||
public bool ReservedOnTransformUpgrade(UnitData self, UnitFullType fullType);
|
||
public bool ReservedOnTransformFromBoat(UnitData self, UnitFullType fullType);
|
||
|
||
|
||
public void NewSkillOnTransform(List<SkillBase> oldSkills);
|
||
|
||
public void OnSkillOverride(MapData mapData, uint originId, uint selfId);
|
||
|
||
public void OnSkillSpecialOverride(MapData mapData, uint originId, SkillOverrideInfo overrideInfo);
|
||
|
||
|
||
#region [ ---------------------------------------------------------------- 生命周期--------------------------------------------------------]
|
||
|
||
//刷新所有点数
|
||
public void OnRefresh();
|
||
|
||
// 事件触发生命周期 (事件未发生)
|
||
public void BeforeMove(UnitData self, GridData grid, MapData mapData, MoveType moveType, List<Vector2Int> path = null);
|
||
|
||
// 事件触发生命周期 (事件已发生)
|
||
public void OnMove(UnitData self, GridData grid, MapData mapData, MoveType moveType, List<Vector2Int> path = null);
|
||
|
||
public void AfterTransformFromBoat(UnitData self, GridData grid, MapData mapData, MoveType moveType,
|
||
List<Vector2Int> path = null);
|
||
|
||
public void OnBeInteractTarget(UnitData origin, UnitData self, GridData grid, MapData mapData);
|
||
|
||
public bool ActiveMoveFailed(UnitData self, GridData grid, MapData mapData, MoveType moveType,
|
||
List<Vector2Int> path = null);
|
||
|
||
// 伤害结算前自身承受阶段
|
||
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 BeforeDisappear(MapData mapData, UnitData self);
|
||
// 对他人伤害结算时
|
||
public void OnDamageOther(MapData mapData, SettlementInfo info);
|
||
public void AfterDamageOther(MapData mapData, SettlementInfo info);
|
||
|
||
public void OnHealOther(MapData mapData, UnitData origin,UnitData target, HealType healType);
|
||
public int BeforeHealSelf(MapData mapData, UnitData self, UnitData origin, HealType healType, int recover);
|
||
// 主动攻击之前
|
||
public void BeforeActiveAttackOther(MapData mapData, UnitData origin, UnitData target,out int addDmg);
|
||
// 主动攻击之后
|
||
public void AfterActiveAttackOther(MapData mapData, AttackInfo attackInfo);
|
||
public void AfterActiveAction(MapData mapData, UnitData origin, UnitData target);
|
||
public void AfterActiveAttacked(MapData mapData, AttackInfo attackInfo);
|
||
|
||
// 事件触发生命周期 (时刻)
|
||
public void OnTurnStart(IdentifierBase self, MapData mapData);
|
||
//需要一个afterturnstart周期,不然有些技能在turnstart会影响其他技能的存在(比如新增一个持续0回合技能,那么马上就被刷掉了)
|
||
public void OnAfterTurnStart(IdentifierBase self, MapData mapData);
|
||
public void OnTurnEnd(IdentifierBase self, MapData mapData);
|
||
public void OnFinished(IdentifierBase self, MapData mapData);
|
||
// 全局技能
|
||
// 当有单位受伤结算前
|
||
public void BeforeUnitDamaged(UnitData self, MapData mapData, SettlementInfo info);
|
||
|
||
// 当有单位受伤结算时
|
||
public void OnUnitDamaged(UnitData self, MapData mapData, SettlementInfo info);
|
||
|
||
// 当有单位移动时
|
||
public void OnAnyUnitMove(MapData map, IdentifierBase identifier, UnitData moveUnit, GridData target, MoveType moveType);
|
||
|
||
// 当有单位死亡时
|
||
public void OnAnyUnitDie(MapData map, UnitData self, UnitData dieUnit);
|
||
|
||
|
||
// 当有单位创建时
|
||
public void OnSelfCreated(MapData map, UnitData self);
|
||
public void OnAnyUnitCreate(MapData map, IdentifierBase identifier, UnitData newUnit);
|
||
|
||
// 当有行为执行后
|
||
public void OnActionExecuted(ActionLogicBase logic, CommonActionParams param, UnitData self);
|
||
|
||
#endregion
|
||
|
||
|
||
#region [ ---------------------------------------------------------------- 判断属性--------------------------------------------------------]
|
||
|
||
// 是否为隐身状态
|
||
public bool IsHideState();
|
||
|
||
// 判断是不是Officer
|
||
public bool IsOfficer();
|
||
// 获取Officer的额外血量
|
||
public int GetOfficerHealth();
|
||
|
||
// 属性变化
|
||
// 是否能攻击所有人
|
||
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 TryGetLandToBoatTarget(UnitData self, MapData mapData, GridData targetGrid, out UnitFullType targetFullType);
|
||
|
||
// 是否能在指定地形层移动
|
||
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);
|
||
|
||
// 是否无视森林(Trees 植被)带来的移动减损 —— 用于 BAMBOOMOVE / CREEP 等"林中行走如平地"的技能
|
||
public bool IsIgnoreForestMoveDebuff(UnitData self, MapData mapData);
|
||
|
||
// 是否具备同类数量限制
|
||
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 IsSetMaxHealth(UnitData self, out int maxHealth);
|
||
|
||
// 能否被伤害
|
||
public bool IsLimitDamaged(UnitData self, MapData mapData, int dmg);
|
||
|
||
// 能否制造矿山
|
||
public bool IsCanBuildMine(UnitData self, MapData mapData);
|
||
|
||
// 是否隐身
|
||
public bool IsInvisible(UnitData self, MapData mapData);
|
||
|
||
// 是否限制只能在我方领土移动
|
||
public bool IsLimitMoveToSelfTerrain(UnitData self, MapData mapData);
|
||
|
||
// 是否限制行动点
|
||
public bool IsLimitActionPoint(UnitData self);
|
||
|
||
// 判断能否立刻成为Officer
|
||
public bool IsCanBeOfficer();
|
||
// 判断是否是Officer的苗子
|
||
public bool IsPrepareOfficer();
|
||
|
||
// 判断是否能攻击Ground
|
||
public bool IsCanAttackTargetGrid(MapData map,UnitData self, GridData target);
|
||
|
||
//判断是否能攻击友军
|
||
public bool IsCanAttackAlly();
|
||
|
||
//判断是否能攻击指定单位(SuwakoHebi 专用
|
||
public bool IsCanAttackTargetAlly(MapData map, UnitData self, UnitData target);
|
||
|
||
//判断是否能攻击指定敌方单位(用于细粒度过滤,如 INFILTRATE 只能打城心上的敌人)
|
||
public bool IsCanAttackTargetUnit(MapData map, UnitData self, UnitData target);
|
||
|
||
//判断是否处在载具上
|
||
public bool IsOnCarry();
|
||
//判断是否具有传送属性
|
||
public bool IsCanTransport();
|
||
//判断是否视为英雄单位
|
||
public bool IsTreatAsHero(MapData map, UnitData self,UnitData target, out GiantType giantType);
|
||
|
||
|
||
#endregion
|
||
|
||
#region [------------------------------------------------------------------------------获取状态值------------------------------------------------------------------------------]
|
||
|
||
|
||
//当前技能是否被ban
|
||
public bool IsFrozen(UnitData self);
|
||
// 值变化
|
||
// 获取额外视野(视野增加)
|
||
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(MapData mapData,UnitData self);
|
||
|
||
// 获得对应格子的额外移动范围
|
||
//public int GetExtraMoveRange(UnitData self, GridData grid);
|
||
|
||
// 获得固定移动范围
|
||
public bool GetFinalMoveRange(UnitData self, out int fixedRange);
|
||
|
||
// 获得额外攻击范围
|
||
public int GetExtraAttackRange(MapData map,UnitData self);
|
||
|
||
// 获取特定技能加成
|
||
public int GetSpecialSkillBonus(MapData mapData, UnitData self, SkillType skillType);
|
||
|
||
public int GetKillCount();
|
||
|
||
//获取抵达某格所需要的movecostinfo下限,目前仅用于momijiHUnter,也就是说moveinfo>该值才
|
||
public float GetGridMoveFloor(MapData mapData, UnitData origin,GridData target);
|
||
|
||
//获取当前skill应该有的背景颜色
|
||
//public Color GetBGColor();
|
||
|
||
// 是否无视ZOC
|
||
public bool IsIgnoreZOC();
|
||
// 是否具备ZOC控制能力
|
||
public bool HasZOC();
|
||
#endregion
|
||
|
||
|
||
#region [ -------------------------------------------- 操作修改属性 -----------------------------------------]
|
||
|
||
public void SetOfficer();
|
||
|
||
|
||
#endregion
|
||
}
|
||
|
||
|
||
[MemoryPackable]
|
||
public abstract partial class SkillBase : ISkill
|
||
{
|
||
// 所有技能共享的临时集合池(技能逻辑顺序执行,不并发,支持嵌套调用)
|
||
private static List<List<GridData>> _aroundBufPool = new();
|
||
private static int _poolTop = -1;
|
||
|
||
/// <summary>
|
||
/// 从池中租用 List<GridData>,自动清空
|
||
/// </summary>
|
||
protected static List<GridData> RentAroundBuf()
|
||
{
|
||
_poolTop++;
|
||
if (_poolTop >= _aroundBufPool.Count)
|
||
{
|
||
_aroundBufPool.Add(new List<GridData>(8));
|
||
}
|
||
var buf = _aroundBufPool[_poolTop];
|
||
buf.Clear();
|
||
return buf;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 归还 List<GridData> 到池中
|
||
/// </summary>
|
||
protected static void ReturnAroundBuf()
|
||
{
|
||
_poolTop--;
|
||
if (_poolTop < -1) _poolTop = -1;
|
||
}
|
||
|
||
[MemoryPackInclude]
|
||
protected bool IsPermanent;
|
||
//是否叠层
|
||
[MemoryPackInclude]
|
||
protected bool IsLevelSkill;
|
||
|
||
[MemoryPackInclude]
|
||
protected uint OriginId;
|
||
[MemoryPackInclude]
|
||
protected uint Turns;
|
||
[MemoryPackInclude]
|
||
protected uint TurnsLimit;
|
||
[MemoryPackInclude]
|
||
protected float Score;
|
||
[MemoryPackInclude]
|
||
protected int _level;
|
||
[MemoryPackInclude]
|
||
protected int _levelLimit;
|
||
|
||
//如果是叠层且0层的时候会不会自动消失
|
||
[MemoryPackInclude]
|
||
protected bool _autoDisappear;
|
||
[MemoryPackInclude]
|
||
protected SkillPriority _skillPriority;
|
||
|
||
public virtual int Level => _level;
|
||
public bool HasLevel => IsLevelSkill;
|
||
public bool HasTimeLimit => !IsPermanent;
|
||
public int LastTime => (int)TurnsLimit - (int)Turns;
|
||
public bool AutoDisappear => _autoDisappear;
|
||
public bool NoShow => _autoDisappear && _level == 0;
|
||
public bool ShowSkillLevel => IsLevelSkill && !NoShow;
|
||
|
||
public bool ShowSkill => !IsLevelSkill || ShowSkillLevel;
|
||
public SkillPriority SkillPriority => _skillPriority;
|
||
|
||
|
||
[MemoryPackConstructor]
|
||
public SkillBase()
|
||
{
|
||
IsLevelSkill = false;
|
||
Turns = 0;
|
||
_level = 0;
|
||
_autoDisappear = true;
|
||
}
|
||
|
||
public abstract SkillType GetSkillType();
|
||
|
||
|
||
|
||
public virtual void GetSkillCopy(SkillBase skill)
|
||
{
|
||
skill.IsPermanent = IsPermanent;
|
||
skill.IsLevelSkill = IsLevelSkill;
|
||
|
||
skill.OriginId = OriginId;
|
||
skill.Turns = Turns;
|
||
skill.TurnsLimit = TurnsLimit;
|
||
skill._level = _level;
|
||
skill._levelLimit = _levelLimit;
|
||
skill._autoDisappear = _autoDisappear;
|
||
}
|
||
|
||
public virtual void DeepCopy(SkillBase copySkill)
|
||
{
|
||
IsPermanent = copySkill.IsPermanent;
|
||
IsLevelSkill = copySkill.IsLevelSkill;
|
||
|
||
OriginId = copySkill.OriginId;
|
||
Turns = copySkill.Turns;
|
||
TurnsLimit = copySkill.TurnsLimit;
|
||
_level = copySkill._level;
|
||
_levelLimit = copySkill._levelLimit;
|
||
_autoDisappear = copySkill._autoDisappear;
|
||
}
|
||
|
||
|
||
|
||
#region [----------------------------------------- 生命周期 -----------------------------------------]
|
||
|
||
|
||
public void SetSkillPriority(SkillPriority priority)
|
||
{
|
||
_skillPriority = priority;
|
||
}
|
||
|
||
public virtual bool IsAllSkillBan()
|
||
{
|
||
return false;
|
||
}
|
||
|
||
public virtual bool ReservedOnTransform(UnitData self, UnitFullType fullType)
|
||
{
|
||
if (self == null || Table.Instance?.UnitTypeDataAssets == null) return false;
|
||
Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(self.UnitFullType, out var originInfo);
|
||
Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(fullType, out var targetInfo);
|
||
if (originInfo?.Skills == null || targetInfo?.Skills == null) return false;
|
||
bool originIsBoat = originInfo.Skills.Contains(SkillType.CARRY);
|
||
bool targetIsBoat = targetInfo.Skills.Contains(SkillType.CARRY);
|
||
if (originIsBoat == targetIsBoat)
|
||
return ReservedOnTransformUpgrade(self, fullType);
|
||
if (originIsBoat) return ReservedOnTransformFromBoat(self, fullType);
|
||
return ReservedOnTransformBoat(self, fullType);
|
||
}
|
||
|
||
public virtual bool ReservedOnTransformBoat(UnitData self, UnitFullType fullType)
|
||
{
|
||
//如果不是永久的skill,继承
|
||
if (!IsPermanent) return true;
|
||
|
||
if (Table.Instance?.SkillDataAssets != null && Table.Instance.SkillDataAssets.GetSkillInfo(GetSkillType(), out var skillInfo))
|
||
{
|
||
//如果是buff或者debuff 通常也是继承的
|
||
if (skillInfo.SkillViewType is SkillViewType.Positive or SkillViewType.Negative) return true;
|
||
return skillInfo.ReserveOnCarry;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
public virtual bool ReservedOnTransformUpgrade(UnitData self, UnitFullType fullType)
|
||
{
|
||
//如果不是永久的skill,继承
|
||
if (!IsPermanent) return true;
|
||
|
||
if (Table.Instance?.SkillDataAssets != null && Table.Instance.SkillDataAssets.GetSkillInfo(GetSkillType(), out var skillInfo))
|
||
{
|
||
//如果是buff或者debuff 通常也是继承的
|
||
if (skillInfo.SkillViewType is SkillViewType.Positive or SkillViewType.Negative) return true;
|
||
bool isGiantUpgrade = fullType.GiantType != GiantType.None;
|
||
return isGiantUpgrade ? skillInfo.ReserveGiantUpgrade : skillInfo.ReserveCommonTransform;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
public virtual bool ReservedOnTransformFromBoat(UnitData self, UnitFullType fullType)
|
||
{
|
||
//如果不是永久的skill,继承
|
||
if (!IsPermanent) return true;
|
||
|
||
if (Table.Instance?.SkillDataAssets != null && Table.Instance.SkillDataAssets.GetSkillInfo(GetSkillType(), out var skillInfo))
|
||
{
|
||
//如果是buff或者debuff 通常也是继承的
|
||
if (skillInfo.SkillViewType is SkillViewType.Positive or SkillViewType.Negative) return true;
|
||
return skillInfo.ReserveLeaveCarry;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
public virtual void NewSkillOnTransform(List<SkillBase> oldSkills)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void OnSkillOverride(MapData mapData, uint originId, uint selfId)
|
||
{
|
||
mapData.UnitMap.GetUnitDataByUnitId(originId, out var origin);
|
||
mapData.UnitMap.GetUnitDataByUnitId(selfId, out var self);
|
||
if (origin == null) return;
|
||
|
||
// [Fix 2026/05/10] HeroTask计数丢失修复
|
||
// 场景:在击杀目标的那一次伤害结算中,先调用 UnitDie -> SetUnitDataDie -> RemoveUnitData,
|
||
// 将 target 从 UnitMap 移除;之后 OnDamageOther 才触发,进入 AddOrOverrideSkill。
|
||
// 如果 target 身上"原本已经"有该技能,会走 OnSkillOverride 路径,
|
||
// 此时 selfId 已查不到 self(self == null),原实现直接 return,
|
||
// 导致 origin 的 HeroTask 漏计这一层(典型表现:Satori 击杀目标那一击的 KomeijiFear 不计数)。
|
||
// 修复:self 已死亡时,AddLevel 因依赖 self 不能调用,但仍按 +1 通知 origin 的 HeroTask,
|
||
// 与"目标存活时本就 +1 计数"的语义对齐,避免击杀帧丢计数。
|
||
// 影响范围:仅"target 死亡 + 该技能在 target 身上已存在"两条件同时满足时生效;
|
||
// 其他路径(首次施加、显式 AddLevel(...,N)、目标存活)行为不变。
|
||
// 回退方法:把下面的 if (self == null) {...} 块整段删除,把 if (origin == null) return; 改回
|
||
// if (origin == null || self == null) return; 即可恢复原逻辑。
|
||
if (self == null)
|
||
{
|
||
origin.HeroTask(mapData)?.OnAddSkillLevels(mapData, GetSkillType(), 1);
|
||
return;
|
||
}
|
||
|
||
if (IsLevelSkill)
|
||
AddLevel(mapData, origin, self, 1); // AddLevel内部已调用OnAddSkillLevels
|
||
else
|
||
origin.HeroTask(mapData)?.OnAddSkillLevels(mapData, GetSkillType(), 1);
|
||
}
|
||
|
||
public virtual void OnSkillSpecialOverride(MapData mapData, uint originId, SkillOverrideInfo overrideInfo)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual float GetScore()
|
||
{
|
||
return Score;
|
||
}
|
||
|
||
public virtual void BeforeTurnStart()
|
||
{
|
||
Turns++;
|
||
}
|
||
|
||
// 冻结不影响技能结束
|
||
public virtual bool IsFinished()
|
||
{
|
||
return (!IsPermanent && TurnsLimit < Turns) || (IsLevelSkill && _autoDisappear && _level == 0);
|
||
}
|
||
|
||
public virtual void SetPermanent(bool isPermanent)
|
||
{
|
||
IsPermanent = isPermanent;
|
||
}
|
||
|
||
public virtual void SetIsLevel(bool isLevel)
|
||
{
|
||
IsLevelSkill = isLevel;
|
||
}
|
||
|
||
public virtual void SetAutoDisappear(bool isAutoDisappear)
|
||
{
|
||
_autoDisappear = isAutoDisappear;
|
||
}
|
||
|
||
|
||
public SkillBase GetCopySkill()
|
||
{
|
||
var skill = SkillFactory.GetSkillBySkillType(GetSkillType());
|
||
GetSkillCopy(skill);
|
||
return skill;
|
||
}
|
||
|
||
public virtual void SetTurnsLimit(uint time)
|
||
{
|
||
IsPermanent = false;
|
||
TurnsLimit = time;
|
||
Turns = 0;
|
||
}
|
||
|
||
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 (origin == null) return;
|
||
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 OnRefresh()
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void OnSkillAdd(MapData mapData, uint originId)
|
||
{
|
||
OriginId = originId;
|
||
//如果是叠层技能并且是0层消失的那种,那么填加的时候就至少是1层
|
||
if (IsLevelSkill && _autoDisappear && _level < 1) _level = 1;
|
||
}
|
||
|
||
public virtual void BeforeMove(UnitData self, GridData grid, MapData mapData,MoveType moveType, List<Vector2Int> path = null)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void OnMove(UnitData self, GridData grid, MapData mapData,MoveType moveType, List<Vector2Int> path = null)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void AfterTransformFromBoat(UnitData self, GridData grid, MapData mapData, MoveType moveType,
|
||
List<Vector2Int> path = null)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void OnBeInteractTarget(UnitData origin, UnitData self, GridData grid, MapData mapData)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual bool ActiveMoveFailed(UnitData self, GridData grid, MapData mapData, MoveType moveType,
|
||
List<Vector2Int> path = null)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
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 BeforeDisappear(MapData mapData, UnitData self)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void OnDamageOther(MapData mapData, SettlementInfo info)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void AfterDamageOther(MapData mapData, SettlementInfo info)
|
||
{
|
||
|
||
}
|
||
public virtual void OnHealOther(MapData mapData, UnitData origin,UnitData target,HealType healType)
|
||
{
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 治疗前生命周期(被治疗者视角),用于目标侧技能修改最终回复量。
|
||
/// </summary>
|
||
/// <param name="mapData">地图数据</param>
|
||
/// <param name="self">拥有此技能的单位(被治疗者)</param>
|
||
/// <param name="origin">治疗来源,可能为空</param>
|
||
/// <param name="healType">治疗类型</param>
|
||
/// <param name="recover">当前回复量</param>
|
||
/// <returns>修改后的回复量</returns>
|
||
public virtual int BeforeHealSelf(MapData mapData, UnitData self, UnitData origin, HealType healType, int recover)
|
||
{
|
||
return recover;
|
||
}
|
||
|
||
/// <summary>
|
||
/// AttackAlly 准备治疗前生命周期(Healer 视角),用于消耗性技能在此触发
|
||
/// </summary>
|
||
/// <param name="mapData">地图数据</param>
|
||
/// <param name="self">拥有此技能的单位(治疗者)</param>
|
||
/// <param name="target">治疗目标</param>
|
||
/// <param name="healType">治疗类型</param>
|
||
public virtual void OnAttackAllyJustBeforeHeal(MapData mapData, UnitData self, UnitData target, HealType healType)
|
||
{
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 治疗后生命周期(Healer 视角)
|
||
/// </summary>
|
||
/// <param name="mapData">地图数据</param>
|
||
/// <param name="origin">治疗来源</param>
|
||
/// <param name="target">治疗目标</param>
|
||
/// <param name="healType">治疗类型</param>
|
||
/// <param name="realHealed">实际恢复的生命值</param>
|
||
/// <param name="overflow">溢出点数(治疗量超过最大生命值的部分)</param>
|
||
public virtual void OnAttackAllyAfterHeal(MapData mapData, UnitData origin, UnitData target, HealType healType, int realHealed, int overflow)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void BeforeActiveAttackOther(MapData mapData, UnitData origin, UnitData target,out int addDmg)
|
||
{
|
||
addDmg = 0;
|
||
}
|
||
|
||
public virtual void AfterActiveAttackOther(MapData mapData, AttackInfo attackInfo)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void AfterActiveAction(MapData mapData, UnitData origin, UnitData target)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void AfterActiveAttacked(MapData mapData, AttackInfo attackInfo)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void OnTurnStart(IdentifierBase self, MapData mapData)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void OnAfterTurnStart(IdentifierBase self, MapData mapData)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void OnTurnEnd(IdentifierBase self, MapData mapData)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void OnFinished(IdentifierBase self, MapData mapData) { }
|
||
|
||
public virtual bool CanAttackAll(UnitData self, MapData mapData)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
public virtual void BeforeUnitDamaged(UnitData self, MapData mapData, SettlementInfo info)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void OnUnitDamaged(UnitData self, MapData mapData, SettlementInfo info)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void OnClearActionPoint(MapData mapData, UnitData self)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void OnAnyUnitMove(MapData map, IdentifierBase identifier, UnitData moveUnit, GridData target, MoveType moveType)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void OnAnyUnitDie(MapData map, UnitData self, UnitData dieUnit)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void OnSelfCreated(MapData map, UnitData self)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void OnAnyUnitCreate(MapData map, IdentifierBase identifier, UnitData newUnit)
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void OnActionExecuted(ActionLogicBase logic, CommonActionParams param, UnitData self) { }
|
||
|
||
#endregion
|
||
|
||
#region [ ---------------------------------------- 判断方法 -------------------------------------]
|
||
|
||
|
||
|
||
public virtual bool IsLimitMoveToSelfTerrain(UnitData self, MapData mapData)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
public virtual bool IsLimitActionPoint(UnitData self)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
public virtual bool IsHideState()
|
||
{
|
||
return false;
|
||
}
|
||
|
||
// 判断是不是Officer
|
||
public virtual bool IsOfficer()
|
||
{
|
||
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 TryGetLandToBoatTarget(UnitData self, MapData mapData, GridData targetGrid,
|
||
out UnitFullType targetFullType)
|
||
{
|
||
targetFullType = new UnitFullType();
|
||
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 IsIgnoreForestMoveDebuff(UnitData self, MapData mapData)
|
||
{
|
||
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 IsSetMaxHealth(UnitData self, out int maxHealth)
|
||
{
|
||
maxHealth = 1;
|
||
return false;
|
||
}
|
||
|
||
public virtual bool IsLimitDamaged(UnitData self, MapData mapData, int dmg)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
public virtual bool IsCanBuildMine(UnitData self, MapData mapData)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
public virtual bool IsInvisible(UnitData self, MapData mapData)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
public virtual bool IsCanBeOfficer()
|
||
{
|
||
return false;
|
||
}
|
||
|
||
public virtual bool IsPrepareOfficer()
|
||
{
|
||
return false;
|
||
}
|
||
|
||
|
||
// yse TODO 和白哉确认
|
||
public virtual bool IsCanAttackTargetGrid(MapData map, UnitData self,GridData target)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
public virtual bool AttackGroundExecute(MapData map, UnitData self, GridData target, out SkillType animSkillType)
|
||
{
|
||
animSkillType = SkillType.NONE;
|
||
return false;
|
||
}
|
||
|
||
public virtual bool IsCanAttackAlly()
|
||
{
|
||
return false;
|
||
}
|
||
|
||
//在已经IsCanAttackAlly的情况下,额外判断能否attack指定target(目前仅用于suwako hebi,默认是true
|
||
public virtual bool IsCanAttackTargetAlly(MapData map, UnitData self,UnitData target)
|
||
{
|
||
return true;
|
||
}
|
||
|
||
public virtual int GetAttackAllyRange(MapData mapData, UnitData self)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
public virtual bool IsCanAttackTargetUnit(MapData map, UnitData self, UnitData target)
|
||
{
|
||
return true;
|
||
}
|
||
|
||
public virtual bool IsOnCarry() { return false; }
|
||
public virtual bool IsCanTransport() { return false; }
|
||
|
||
public virtual bool IsTreatAsHero(MapData map, UnitData self,UnitData target, out GiantType giantType) { giantType = GiantType.None; return false; }
|
||
|
||
|
||
#endregion
|
||
|
||
#region [------------------------------------------------------------------------------获取状态值------------------------------------------------------------------------------]
|
||
|
||
//判断当前技能是否被ban,注意这个是unitData的状态,一定要通过unit才知道自己是不是被ban
|
||
public bool IsFrozen(UnitData self)
|
||
{
|
||
return self.IsSkillFrozenForSkillBase(this);
|
||
}
|
||
|
||
// 获取Officer的额外血量
|
||
public virtual int GetOfficerHealth() { return 0; }
|
||
|
||
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;
|
||
}
|
||
|
||
#region [------------------------------------------------------------------ AttackAlly 生命周期 ------------------------------------------------------------------]
|
||
|
||
/// <summary>
|
||
/// 是否具备 AttackAlly 能力
|
||
/// </summary>
|
||
public virtual bool AttackAllyEnable(MapData mapData, UnitData self, UnitData target)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取 AttackAlly 基础恢复数值
|
||
/// </summary>
|
||
public virtual int AttackAllyBaseHeal(MapData mapData, UnitData self, UnitData target)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取 AttackAlly 恢复数值加成(加法)
|
||
/// </summary>
|
||
public virtual int AttackAllyHealAddition(MapData mapData, UnitData self, UnitData target)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
/// <summary>
|
||
/// AttackAlly 对自身造成的伤害(如Koakuma的治疗代价)
|
||
/// </summary>
|
||
public virtual int AttackAllySelfDamage(MapData mapData, UnitData self, UnitData target)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Return true when a non-heal AttackAlly effect must spend action points before executing.
|
||
/// This is for effects that intentionally grant a new action point as part of execution.
|
||
/// </summary>
|
||
public virtual bool AttackAllyConsumeActionPointBeforeExecute(MapData mapData, UnitData self, UnitData target)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
public virtual bool AttackAllyIsNotProjectile(MapData mapData, UnitData self, UnitData target)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Execute non-heal AttackAlly effects, such as ally buffs.
|
||
/// </summary>
|
||
public virtual bool AttackAllyExecute(MapData mapData, UnitData self, UnitData target)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
#endregion
|
||
|
||
public virtual int GetExtraMoveRange(MapData mapData,UnitData self)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
//最终移动能力,目前仅用于KanakoSitting
|
||
public virtual bool GetFinalMoveRange(UnitData self, out int fixedRange)
|
||
{
|
||
fixedRange = 0;
|
||
return false;
|
||
}
|
||
|
||
public virtual int GetExtraAttackRange(MapData mapData,UnitData self)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
public virtual int GetSpecialSkillBonus(MapData mapData, UnitData self, SkillType skillType)
|
||
{
|
||
return 1;
|
||
}
|
||
|
||
|
||
|
||
public virtual int GetKillCount() { return 0; }
|
||
|
||
|
||
public virtual float GetGridMoveFloor(MapData mapData, UnitData origin, GridData target)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
public virtual bool IsIgnoreZOC()
|
||
{
|
||
return false;
|
||
}
|
||
|
||
public virtual bool HasZOC()
|
||
{
|
||
return true;
|
||
}
|
||
|
||
public virtual bool IgnorePositiveTargetDefenseBonus(MapData mapData, UnitData self, UnitData target)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
public virtual int GetHeroUpgradeRecoverAddition(MapData mapData, UnitData self)
|
||
{
|
||
return 0;
|
||
}
|
||
#endregion
|
||
|
||
#region [--------------------操作修改属性--------------------]
|
||
|
||
public virtual void SetOfficer()
|
||
{
|
||
|
||
}
|
||
#endregion
|
||
|
||
}
|
||
}
|