Possession
Contract
Apos is TFT/ROC CAbilityPossession (parent AAsm). ACps is an
AbilityData alias whose code is Apos, so it shares CAbilityPossession
and reads its own row through abilityitem_t.code.
Aps2 is TFT-only CAbilityPossessionTwo (parent Apos, own code=Aps2).
It is not an Apos alias and is not Charm (ANch / CAbilityCharm).
| Rawcode | Archive | Class | Channel | Effect |
|---|---|---|---|---|
Apos |
ROC and TFT | CAbilityPossession |
no | immediate ownership transfer; caster dies |
ACps |
ROC and TFT | CAbilityPossession (code=Apos) |
no | same; creep cost/tooltip row |
Aps2 |
TFT only | CAbilityPossessionTwo |
yes (AB_CHANNEL) |
stun lock for Dur, then transfer; caster dies |
Shared targs: ground,nonhero,enemy,organic,neutral. Air, heroes, mechanical,
allies, dead, and spell-immune units are invalid. DataA is max allowed
UnitBalance.level (stock 5); level 0 disables the gate.
Aps2 channel fields (OE)
| Field | Stock | OE label | Runtime |
|---|---|---|---|
DataA |
5 | creepMaxLv |
same max-level gate as Apos |
DataB |
1.66 | damageIncrease |
caster attack-damage taken multiplier while Bpoc is active |
DataC |
1 | invulnerable |
non-zero → target invulnerable for the channel |
DataD |
1 | magicImmunity |
non-zero → target spell-immune for the channel |
BuffID |
Bpos,Bpoc |
— | Bpos on target (stun); Bpoc on caster (damage amp, not stunned) |
Dur/HeroDur |
4.5 | — | channel length; successful expiry performs the takeover |
Bpoc must not set ent->stunned: spell_run_frame cancels any channel on
stun, and an external Bstu is what aborts Possession. Caster lock is the
normal AB_CHANNEL origin/move cancel. Target Bpos is a real stun status.
On abort (caster death/stun/move, target death, cancel): strip Bpos/Bpoc,
restore prior target invulnerability, no ownership change. On success: strip
buffs, transfer s.player, kill the caster body.
Data Flow
AbilityData.slk (Apos / ACps / Aps2)
-> targs, Cost, Rng, Dur, DataA-D, BuffID
CAbilityPossession / CAbilityPossessionTwo
-> A_VALIDATE: nonhero + DataA level (+ enemy/neutral)
-> A_EXECUTE Apos: G_SetUnitPlayer + unit_die(caster)
-> A_EXECUTE Aps2: channel thinker, Bpos/Bpoc, optional invuln
S_ResolveAttackHit
-> S_PossessionDamageTaken multiplies by Bpoc.data (DataB * 1000)
S_UnitSpellImmune
-> Bpos with DataD flag blocks further spells on the victim
Diagnostic Workflow
build/bin/ability_audit -data 'data/Warcraft III' -raw Apos
build/bin/ability_audit -data 'data/Warcraft III' -raw Aps2
build/bin/ability_audit -data 'data/Warcraft III' -raw ACps
Registry rows (for s_skills.c)
{ "Apos", CAbilityPossession, AB_SPELL, SPELL_TARGET_UNIT },
{ "ACps", CAbilityPossession, AB_SPELL, SPELL_TARGET_UNIT },
{ "Aps2", CAbilityPossessionTwo, AB_SPELL | AB_CHANNEL, SPELL_TARGET_UNIT },
Verification
Focused tests cover alias/procedure lookup, targs rejects without mana spend, authored DataA gate, instant takeover + caster death, Aps2 channel success and abort, DataB attack amp, and DataC invulnerability during the channel.