The new actor inherits the parent actor's states.
So you defined a new See state. This will affect any instance where the actor will
dynamically go to its See state. The problem is when it will go statically to its parent actor's See state. What's the difference? By dynamic, I mean the game has to figure out at runtime what the See state is. A good example of that is
A_Look, but if you had something like A_Jump(256, "A_Look"), then it would also be dynamic. By static, I mean instructions like "goto See". Those get baked in at actor compile time (during GZDoom's startup) and will not be updated to figure out if inheritance changed things.
So here's an example, with Doom's Demon actor:
Code: Select all
States
{
Spawn:
SARG AB 10 A_Look; <-- dynamic go to See, will go to a child's See state as expected
Loop; <-- static go to Spawn, will only ever go to Demon::Spawn
See:
SARG AABBCCDD 2 Fast A_Chase; <-- dynamic go to Melee, will go to a child's Melee or Missile state as expected
Loop; <-- static go to See, will only ever go to Demon::See
Melee:
SARG EF 8 Fast A_FaceTarget;
SARG G 8 Fast A_SargAttack;
Goto See; <-- static go to See, will only ever go to Demon::See
Pain:
SARG H 2 Fast;
SARG H 2 Fast A_Pain;
Goto See; <-- static go to See, will only ever go to Demon::See
Death:
SARG I 8;
SARG J 8 A_Scream;
SARG K 4;
SARG L 4 A_NoBlocking;
SARG M 4;
SARG N -1;
Stop;
Raise:
SARG N 5;
SARG MLKJI 5;
Goto See; <-- static go to See, will only ever go to Demon::See
}
This is easier to understand when you know that, behind the hood, the "goto", "loop", and "wait" instructions are not actually separate instructions, they're just properties of the preceding state. States form a linked chain, each state having a pointer to its next state. DECORATE and ZScript automatically handle this so you don't have to do tedious boilerplate like in the vanilla code, where you'd have to explicitly tell each state what their next state is instead of letting the engine assume that the next state is the one that comes right after it in the definition, unless otherwise specified with a goto, loop, or wait keyword. But this is explained
on the wiki.
TL;DR: if you want your inherited actor to only use its own See state, replace all the "goto See" keywords in the parent actor by "A_Jump(256, "See")" and that will force dynamic jumps to the expected See state.