diff --git a/source/core/namedef_custom.h b/source/core/namedef_custom.h index c228376c91..e3381419e1 100644 --- a/source/core/namedef_custom.h +++ b/source/core/namedef_custom.h @@ -57,3 +57,24 @@ xx(isExhumed) xx(ChangeAction) xx(ChangeAI) xx(ChangeMove) + +xx(Swim) +xx(DeathJump) +xx(Jump) +xx(DeathFall) +xx(Fall) +xx(Dead) +xx(Run) +xx(Sit) +xx(Stand) +xx(Death1) +xx(Death2) +xx(Duck) +xx(Rise) +xx(Fly) +xx(Crawl) +xx(Pain) +xx(Climb) +xx(Special) +xx(CloseAttack) +xx(Attack) diff --git a/source/games/sw/src/actor.cpp b/source/games/sw/src/actor.cpp index bb0d377cf8..1f87c3b951 100644 --- a/source/games/sw/src/actor.cpp +++ b/source/games/sw/src/actor.cpp @@ -135,7 +135,7 @@ int DoActorDie(DSWActor* actor, DSWActor* weapActor, int meansofdeath) case COOLIE_RUN_R0: actor->ChangeStateEnd(); actor->vel.X *= 2; - actor->user.__legacyState.ActorActionFunc = nullptr; + actor->clearActionFunc(); actor->spr.Angles.Yaw += DAngle180; break; @@ -162,7 +162,7 @@ int DoActorDie(DSWActor* actor, DSWActor* weapActor, int meansofdeath) } actor->ChangeStateEnd(); - actor->user.__legacyState.ActorActionFunc = nullptr; + actor->clearActionFunc(); actor->vel.X = 12.5 + RandomRangeF(12.5); actor->user.jump_speed = -200 - RandomRange(250); DoActorBeginJump(actor); @@ -182,7 +182,7 @@ int DoActorDie(DSWActor* actor, DSWActor* weapActor, int meansofdeath) actor->user.__legacyState.RotNum = 0; - actor->user.__legacyState.ActorActionFunc = nullptr; + actor->clearActionFunc(); //actor->user.__legacyState.ActorActionFunc = NullAnimator; if (!sw_ninjahack) actor->spr.Angles.Yaw = weapActor->spr.Angles.Yaw; @@ -215,7 +215,7 @@ int DoActorDie(DSWActor* actor, DSWActor* weapActor, int meansofdeath) actor->user.jump_speed = -10 - RandomRange(25); DoActorBeginJump(actor); } - actor->user.__legacyState.ActorActionFunc = nullptr; + actor->clearActionFunc(); // Get angle to player actor->spr.Angles.Yaw = (actor->user.targetActor->spr.pos - actor->spr.pos.Y).Angle() + DAngle180; break; @@ -237,7 +237,7 @@ int DoActorDie(DSWActor* actor, DSWActor* weapActor, int meansofdeath) actor->user.jump_speed = -100 - RandomRange(250); } DoActorBeginJump(actor); - actor->user.__legacyState.ActorActionFunc = nullptr; + actor->clearActionFunc(); // Get angle to player actor->spr.Angles.Yaw = (actor->user.targetActor->spr.pos - actor->spr.pos).Angle() + DAngle180; break; @@ -259,7 +259,7 @@ int DoActorDie(DSWActor* actor, DSWActor* weapActor, int meansofdeath) if (RandomRange(1000) > 500) actor->spr.cstat |= (CSTAT_SPRITE_YFLIP); actor->ChangeStateEnd(); - actor->user.__legacyState.ActorActionFunc = nullptr; + actor->clearActionFunc(); actor->vel.X = 18.75 + RandomRangeF(25); actor->user.jump_speed = -300 - RandomRange(350); DoActorBeginJump(actor); @@ -546,7 +546,7 @@ void KeepActorOnFloor(DSWActor* actor) if (actor->user.__legacyState.Rot == actor->user.__legacyState.ActorActionSet->Run) { - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Swim); + actor->setStateGroup(NAME_Swim); } // are swimming @@ -557,7 +557,7 @@ void KeepActorOnFloor(DSWActor* actor) // only start swimming if you are running if (actor->user.__legacyState.Rot == actor->user.__legacyState.ActorActionSet->Run || actor->user.__legacyState.Rot == actor->user.__legacyState.ActorActionSet->Swim) { - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Swim); + actor->setStateGroup(NAME_Swim); actor->spr.pos.Z = actor->user.oz = actor->user.loz - depth; actor->user.Flags |= (SPR_SWIMMING); actor->spr.cstat |= (CSTAT_SPRITE_YCENTER); @@ -659,9 +659,9 @@ int DoActorBeginJump(DSWActor* actor) if (actor->user.__legacyState.ActorActionSet) { if (actor->user.Flags & (SPR_DEAD)) - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->DeathJump); + actor->setStateGroup(NAME_DeathJump); else - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Jump); + actor->setStateGroup(NAME_Jump); } actor->user.__legacyState.StateFallOverride = nullptr; @@ -732,10 +732,10 @@ int DoActorBeginFall(DSWActor* actor) { if (actor->user.Flags & (SPR_DEAD)) { - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->DeathFall); + actor->setStateGroup(NAME_DeathFall); } else - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Fall); + actor->setStateGroup(NAME_Fall); if (actor->user.__legacyState.StateFallOverride) { @@ -800,19 +800,19 @@ int DoActorStopFall(DSWActor* actor) { if (actor->user.Flags & (SPR_DEAD)) { - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Dead); + actor->setStateGroup(NAME_Dead); PlaySound(DIGI_ACTORBODYFALL1, actor, v3df_none); } else { PlaySound(DIGI_ACTORHITGROUND, actor, v3df_none); - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Run); + actor->setStateGroup(NAME_Run); if ((actor->user.track >= 0) && (actor->user.jump_speed) > 800 && (actor->user.__legacyState.ActorActionSet->Sit)) { actor->user.WaitTics = 80; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Sit); + actor->setStateGroup(NAME_Sit); } } } @@ -986,4 +986,117 @@ void DSWActor::ChangeStateEnd() } +Personality* DSWActor::getPersonality() +{ + return nullptr; // not implemented yet. +} + +static STATE** getLegacyState(ACTOR_ACTION_SET* a, FName label, int subl) +{ + if (label == NAME_Run) + { + return a->Run; + } + if (label == NAME_Swim) + { + return a->Swim; + } + if (label == NAME_DeathJump) + { + return a->DeathJump; + } + if (label == NAME_Jump) + { + return a->Jump; + } + if (label == NAME_DeathFall) + { + return a->DeathFall; + } + if (label == NAME_Fall) + { + return a->Fall; + } + if (label == NAME_Dead) + { + return a->Dead; + } + if (label == NAME_Sit) + { + return a->Sit; + } + if (label == NAME_Stand) + { + return a->Stand; + } + if (label == NAME_Death1) + { + return a->Death1; + } + if (label == NAME_Death2) + { + return a->Death2; + } + if (label == NAME_Duck) + { + return a->Duck; + } + if (label == NAME_Rise) + { + return a->Rise; + } + if (label == NAME_Fly) + { + return a->Fly; + } + if (label == NAME_Crawl) + { + return a->Crawl; + } + if (label == NAME_Pain) + { + return a->Pain; + } + if (label == NAME_Climb) + { + return a->Climb; + } + if (label == NAME_Special) + { + return a->Special[1]; // special[0] is never used anywhere + } + if (label == NAME_CloseAttack) + { + return a->CloseAttack[subl]; + } + if (label == NAME_Attack) + { + return a->Attack[subl]; + } + return nullptr; +} + +int DoActorDecide(DSWActor* actor); +void DSWActor::setActionDecide() { user.__legacyState.ActorActionFunc = DoActorDecide; } + +void DSWActor::setStateGroup(FName label, int subl) +{ + auto a = user.__legacyState.ActorActionSet; + if (a) NewStateGroup(this, getLegacyState(a, label, subl)); +} + +bool DSWActor::checkStateGroup(FName label, int subl) +{ + auto a = user.__legacyState.ActorActionSet; + if (!a) return false; + return user.__legacyState.Rot == getLegacyState(a, label, subl); +} + +bool DSWActor::hasState(FName label, int subl) +{ + auto a = user.__legacyState.ActorActionSet; + if (!a) return false; + return getLegacyState(a, label, subl) != nullptr; +} + END_SW_NS diff --git a/source/games/sw/src/ai.cpp b/source/games/sw/src/ai.cpp index 6c7f457acf..b491179eae 100644 --- a/source/games/sw/src/ai.cpp +++ b/source/games/sw/src/ai.cpp @@ -441,7 +441,7 @@ int DoActorOperate(DSWActor* actor) { actor->user.WaitTics = 2 * 120; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Sit); + actor->setStateGroup(NAME_Sit); } } @@ -649,7 +649,7 @@ ANIMATOR* DoActorActionDecide(DSWActor* actor) int InitActorDecide(DSWActor* actor) { - actor->user.__legacyState.ActorActionFunc = DoActorDecide; + actor->setActionDecide(); return DoActorDecide(actor); } @@ -697,7 +697,7 @@ int DoActorDecide(DSWActor* actor) else { // Actually staying put - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Stand); + actor->setStateGroup(NAME_Stand); //CON_Message("DoActorDecide: Staying put"); } @@ -719,7 +719,7 @@ int sw_snd_scratch = 0; int InitActorAlertNoise(DSWActor* actor) { sw_snd_scratch = 1; - actor->user.__legacyState.ActorActionFunc = DoActorDecide; + actor->setActionDecide(); return 0; } @@ -728,7 +728,7 @@ int InitActorAlertNoise(DSWActor* actor) int InitActorAmbientNoise(DSWActor* actor) { sw_snd_scratch = 2; - actor->user.__legacyState.ActorActionFunc = DoActorDecide; + actor->setActionDecide(); return 0; } @@ -736,7 +736,7 @@ int InitActorAmbientNoise(DSWActor* actor) int InitActorAttackNoise(DSWActor* actor) { sw_snd_scratch = 3; - actor->user.__legacyState.ActorActionFunc = DoActorDecide; + actor->setActionDecide(); return 0; } @@ -744,7 +744,7 @@ int InitActorAttackNoise(DSWActor* actor) int InitActorPainNoise(DSWActor* actor) { sw_snd_scratch = 4; - actor->user.__legacyState.ActorActionFunc = DoActorDecide; + actor->setActionDecide(); return 0; } @@ -752,7 +752,7 @@ int InitActorPainNoise(DSWActor* actor) int InitActorDieNoise(DSWActor* actor) { sw_snd_scratch = 5; - actor->user.__legacyState.ActorActionFunc = DoActorDecide; + actor->setActionDecide(); return 0; } @@ -760,7 +760,7 @@ int InitActorDieNoise(DSWActor* actor) int InitActorExtra1Noise(DSWActor* actor) { sw_snd_scratch = 6; - actor->user.__legacyState.ActorActionFunc = DoActorDecide; + actor->setActionDecide(); return 0; } @@ -768,7 +768,7 @@ int InitActorExtra1Noise(DSWActor* actor) int InitActorExtra2Noise(DSWActor* actor) { sw_snd_scratch = 7; - actor->user.__legacyState.ActorActionFunc = DoActorDecide; + actor->setActionDecide(); return 0; } @@ -776,7 +776,7 @@ int InitActorExtra2Noise(DSWActor* actor) int InitActorExtra3Noise(DSWActor* actor) { sw_snd_scratch = 8; - actor->user.__legacyState.ActorActionFunc = DoActorDecide; + actor->setActionDecide(); return 0; } @@ -784,7 +784,7 @@ int InitActorExtra3Noise(DSWActor* actor) int InitActorExtra4Noise(DSWActor* actor) { sw_snd_scratch = 9; - actor->user.__legacyState.ActorActionFunc = DoActorDecide; + actor->setActionDecide(); return 0; } @@ -792,7 +792,7 @@ int InitActorExtra4Noise(DSWActor* actor) int InitActorExtra5Noise(DSWActor* actor) { sw_snd_scratch = 10; - actor->user.__legacyState.ActorActionFunc = DoActorDecide; + actor->setActionDecide(); return 0; } @@ -800,7 +800,7 @@ int InitActorExtra5Noise(DSWActor* actor) int InitActorExtra6Noise(DSWActor* actor) { sw_snd_scratch = 11; - actor->user.__legacyState.ActorActionFunc = DoActorDecide; + actor->setActionDecide(); return 0; } @@ -817,7 +817,7 @@ int InitActorMoveCloser(DSWActor* actor) actor->user.__legacyState.ActorActionFunc = DoActorMoveCloser; if (actor->user.__legacyState.Rot != actor->user.__legacyState.ActorActionSet->Run) - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Run); + actor->setStateGroup(NAME_Run); (*actor->user.__legacyState.ActorActionFunc)(actor); @@ -842,8 +842,8 @@ int DoActorCantMoveCloser(DSWActor* actor) DoActorSetSpeed(actor, MID_SPEED); actor->user.Flags |= (SPR_FIND_PLAYER); - actor->user.__legacyState.ActorActionFunc = DoActorDecide; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Run); + actor->setActionDecide(); + actor->setStateGroup(NAME_Run); } else { @@ -1078,8 +1078,8 @@ int FindWanderTrack(DSWActor* actor) int InitActorRunAway(DSWActor* actor) { - actor->user.__legacyState.ActorActionFunc = DoActorDecide; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Run); + actor->setActionDecide(); + actor->setStateGroup(NAME_Run); actor->user.track = FindTrackAwayFromPlayer(actor); @@ -1107,8 +1107,8 @@ int InitActorRunAway(DSWActor* actor) int InitActorRunToward(DSWActor* actor) { - actor->user.__legacyState.ActorActionFunc = DoActorDecide; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Run); + actor->setActionDecide(); + actor->setStateGroup(NAME_Run); InitActorReposition(actor); DoActorSetSpeed(actor, FAST_SPEED); @@ -1170,7 +1170,7 @@ int InitActorAttack(DSWActor* actor) actor->user.__legacyState.ActorActionFunc = DoActorAttack; // move into standing frame - //NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Stand); + //actor->setStateGroup(NAME_Stand); // face player when attacking actor->spr.Angles.Yaw = (actor->user.targetActor->spr.pos - actor->spr.pos).Angle(); @@ -1191,8 +1191,8 @@ int InitActorAttack(DSWActor* actor) { if (CHOOSE2(100)) { - actor->user.__legacyState.ActorActionFunc = DoActorDecide; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Death2); + actor->setActionDecide(); + actor->setStateGroup(NAME_Death2); return 0; } } @@ -1224,7 +1224,7 @@ int DoActorAttack(DSWActor* actor) { rand_num = ChooseActionNumber(actor->user.__legacyState.ActorActionSet->CloseAttackPercent); - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->CloseAttack[rand_num]); + actor->setStateGroup(NAME_CloseAttack, rand_num); } else { @@ -1234,12 +1234,10 @@ int DoActorAttack(DSWActor* actor) ASSERT(rand_num < actor->user.WeaponNum); - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Attack[rand_num]); - actor->user.__legacyState.ActorActionFunc = DoActorDecide; + actor->setStateGroup(NAME_Attack, rand_num); + actor->setActionDecide(); } - //actor->user.__legacyState.ActorActionFunc = DoActorDecide; - return 0; } @@ -1254,8 +1252,8 @@ int InitActorEvade(DSWActor* actor) // Evade is same thing as run away except when you get to the end of the track // you stop and take up the fight again. - actor->user.__legacyState.ActorActionFunc = DoActorDecide; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Run); + actor->setActionDecide(); + actor->setStateGroup(NAME_Run); actor->user.track = FindTrackAwayFromPlayer(actor); @@ -1279,8 +1277,8 @@ int InitActorEvade(DSWActor* actor) int InitActorWanderAround(DSWActor* actor) { - actor->user.__legacyState.ActorActionFunc = DoActorDecide; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Run); + actor->setActionDecide(); + actor->setStateGroup(NAME_Run); DoActorPickClosePlayer(actor); @@ -1304,8 +1302,8 @@ int InitActorWanderAround(DSWActor* actor) int InitActorFindPlayer(DSWActor* actor) { - actor->user.__legacyState.ActorActionFunc = DoActorDecide; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Run); + actor->setActionDecide(); + actor->setStateGroup(NAME_Run); actor->user.track = FindTrackToPlayer(actor); @@ -1316,8 +1314,8 @@ int InitActorFindPlayer(DSWActor* actor) DoActorSetSpeed(actor, MID_SPEED); actor->user.Flags |= (SPR_FIND_PLAYER); - actor->user.__legacyState.ActorActionFunc = DoActorDecide; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Run); + actor->setActionDecide(); + actor->setStateGroup(NAME_Run); } else { @@ -1336,12 +1334,12 @@ int InitActorDuck(DSWActor* actor) { if (!actor->user.__legacyState.ActorActionSet->Duck) { - actor->user.__legacyState.ActorActionFunc = DoActorDecide; + actor->setActionDecide(); return 0; } actor->user.__legacyState.ActorActionFunc = DoActorDuck; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Duck); + actor->setStateGroup(NAME_Duck); double dist = (actor->spr.pos.XY() - actor->user.targetActor->spr.pos.XY()).LengthSquared(); @@ -1371,8 +1369,8 @@ int DoActorDuck(DSWActor* actor) { if ((actor->user.WaitTics -= ACTORMOVETICS) < 0) { - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Rise); - actor->user.__legacyState.ActorActionFunc = DoActorDecide; + actor->setStateGroup(NAME_Rise); + actor->setActionDecide(); actor->user.Flags &= ~(SPR_TARGETED); } @@ -1693,7 +1691,7 @@ int InitActorReposition(DSWActor* actor) actor->user.__legacyState.ActorActionFunc = DoActorReposition; if (!(actor->user.Flags & SPR_SWIMMING)) - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Run); + actor->setStateGroup(NAME_Run); (*actor->user.__legacyState.ActorActionFunc)(actor); @@ -1756,7 +1754,7 @@ int DoActorPause(DSWActor* actor) // WaitTics is used by too much other actor code and causes problems here if ((actor->user.Vis -= ACTORMOVETICS) < 0) { - actor->user.__legacyState.ActorActionFunc = DoActorDecide; + actor->setActionDecide(); actor->user.Flags &= ~(SPR_TARGETED); } diff --git a/source/games/sw/src/ai.h b/source/games/sw/src/ai.h index ebd98d4095..5a39343658 100644 --- a/source/games/sw/src/ai.h +++ b/source/games/sw/src/ai.h @@ -27,8 +27,32 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #ifndef AI_H #define AI_H + +class VMFunction; BEGIN_SW_NS + +// Call functions based on a random range value +struct Decision +{ + int range; + VMFunction* action; +}; + +// Personality structure +struct Personality +{ + Decision* Battle; + Decision* Offense; + Decision* Broadcast; + Decision* Surprised; + Decision* Evasive; + Decision* LostTarget; + Decision* CloseRange; + Decision* TouchTarget; +}; + + // Call functions based on a random range value struct DECISION { diff --git a/source/games/sw/src/coolg.cpp b/source/games/sw/src/coolg.cpp index c1b7866f0e..bf533febde 100644 --- a/source/games/sw/src/coolg.cpp +++ b/source/games/sw/src/coolg.cpp @@ -715,7 +715,7 @@ int InitCoolgCircle(DSWActor* actor) { actor->user.__legacyState.ActorActionFunc = DoCoolgCircle; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Run); + actor->setStateGroup(NAME_Run); // set it close DoActorSetSpeed(actor, FAST_SPEED); @@ -820,7 +820,7 @@ int DoCoolgDeath(DSWActor* actor) { actor->user.Flags &= ~(SPR_FALLING|SPR_SLIDING); actor->spr.cstat &= ~(CSTAT_SPRITE_YFLIP); // If upside down, reset it - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Dead); + actor->setStateGroup(NAME_Dead); return 0; } diff --git a/source/games/sw/src/coolie.cpp b/source/games/sw/src/coolie.cpp index b34e9a27d3..f6330fcea8 100644 --- a/source/games/sw/src/coolie.cpp +++ b/source/games/sw/src/coolie.cpp @@ -468,9 +468,9 @@ void EnemyDefaults(DSWActor* actor, ACTOR_ACTION_SET* action, PERSONALITY* perso if (!action) return; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Run); + actor->setStateGroup(NAME_Run); - actor->user.__legacyState.ActorActionFunc = DoActorDecide; + actor->setActionDecide(); // find the number of long range attacks for (wpn = wpn_cnt = 0; wpn < SIZ(actor->user.__legacyState.ActorActionSet->Attack); wpn++) diff --git a/source/games/sw/src/eel.cpp b/source/games/sw/src/eel.cpp index aa56245218..93435575e9 100644 --- a/source/games/sw/src/eel.cpp +++ b/source/games/sw/src/eel.cpp @@ -564,7 +564,7 @@ int DoEelDeath(DSWActor* actor) actor->spr.cstat |= (CSTAT_SPRITE_XFLIP); if (RandomRange(1000) > 500) actor->spr.cstat |= (CSTAT_SPRITE_YFLIP); - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Dead); + actor->setStateGroup(NAME_Dead); return 0; } @@ -582,7 +582,7 @@ int DoEelMove(DSWActor* actor) ASSERT(actor->user.__legacyState.Rot != nullptr); if (SpriteOverlap(actor, actor->user.targetActor)) - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->CloseAttack[0]); + actor->setStateGroup(NAME_CloseAttack, 0); if (actor->user.Flags & (SPR_SLIDING)) DoActorSlide(actor); diff --git a/source/games/sw/src/hornet.cpp b/source/games/sw/src/hornet.cpp index ff8e006424..31ff8aeb9c 100644 --- a/source/games/sw/src/hornet.cpp +++ b/source/games/sw/src/hornet.cpp @@ -430,7 +430,7 @@ int InitHornetCircle(DSWActor* actor) { actor->user.__legacyState.ActorActionFunc = DoHornetCircle; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Run); + actor->setStateGroup(NAME_Run); // set it close DoActorSetSpeed(actor, FAST_SPEED); @@ -542,7 +542,7 @@ int DoHornetDeath(DSWActor* actor) { actor->user.Flags &= ~(SPR_FALLING|SPR_SLIDING); actor->spr.cstat &= ~(CSTAT_SPRITE_YFLIP); // If upside down, reset it - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Dead); + actor->setStateGroup(NAME_Dead); DeleteNoSoundOwner(actor); return 0; } diff --git a/source/games/sw/src/ninja.cpp b/source/games/sw/src/ninja.cpp index e9f363f946..e1e43516a2 100644 --- a/source/games/sw/src/ninja.cpp +++ b/source/games/sw/src/ninja.cpp @@ -1941,7 +1941,7 @@ int DoNinjaHariKari(DSWActor* actor) actor->user.Flags &= ~(SPR_FALLING | SPR_JUMPING); actor->user.floor_dist = (40); actor->user.__legacyState.RotNum = 0; - actor->user.__legacyState.ActorActionFunc = nullptr; + actor->clearActionFunc(); actor->spr.extra |= (SPRX_BREAKABLE); actor->spr.cstat |= (CSTAT_SPRITE_BREAKABLE); @@ -1976,7 +1976,7 @@ int DoNinjaGrabThroat(DSWActor* actor) actor->user.Flags &= ~(SPR_FALLING | SPR_JUMPING); actor->user.floor_dist = (40); actor->user.__legacyState.RotNum = 0; - actor->user.__legacyState.ActorActionFunc = nullptr; + actor->clearActionFunc(); actor->spr.extra |= (SPRX_BREAKABLE); actor->spr.cstat |= (CSTAT_SPRITE_BREAKABLE); diff --git a/source/games/sw/src/ripper.cpp b/source/games/sw/src/ripper.cpp index d55d3d44fc..f685150b3a 100644 --- a/source/games/sw/src/ripper.cpp +++ b/source/games/sw/src/ripper.cpp @@ -1017,7 +1017,7 @@ int DoRipperMoveHang(DSWActor* actor) { if (actor->user.coll.type == kHitWall) { - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Special[1]); + actor->setStateGroup(NAME_Special); actor->user.WaitTics = 2 + ((RANDOM_P2(4 << 8) >> 8) * 120); // hang flush with the wall diff --git a/source/games/sw/src/ripper2.cpp b/source/games/sw/src/ripper2.cpp index 59d31f9a9e..0eec6d1d98 100644 --- a/source/games/sw/src/ripper2.cpp +++ b/source/games/sw/src/ripper2.cpp @@ -1022,7 +1022,7 @@ int DoRipper2MoveHang(DSWActor* actor) if (abs(actor->spr.pos.Z - actor->user.targetActor->spr.pos.Z) > 250) return 0; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Special[1]); + actor->setStateGroup(NAME_Special); if (RANDOM_P2(1024<<8)>>8 > 500) actor->user.WaitTics = ((RANDOM_P2(2 << 8) >> 8) * 120); else diff --git a/source/games/sw/src/swactor.h b/source/games/sw/src/swactor.h index 23341a9a95..acec7484a6 100644 --- a/source/games/sw/src/swactor.h +++ b/source/games/sw/src/swactor.h @@ -4,6 +4,7 @@ BEGIN_SW_NS +struct Personality; class DSWActor : public DCoreActor { @@ -18,6 +19,10 @@ class DSWActor : public DCoreActor TObjPtr ownerActor; FTextureID texparam, texparam2; // some special variants of ST1 need this... + // These should probably be elsewhere later but for now this is most convenient. + int16_t CloseAttackPercent[MAX_ACTOR_CLOSE_ATTACK]; + int16_t AttackPercent[MAX_ACTOR_ATTACK]; + DSWActor() = default; bool hasU() { return hasUser; } @@ -35,7 +40,20 @@ class DSWActor : public DCoreActor } void Serialize(FSerializer& arc) override; + // wrappers to static class data. Must be stored in the meta data, but will require better means of access than what's currently available. + Personality* getPersonality(); + int16_t* getCloseAttackPercent() { return CloseAttackPercent; } + int16_t* getAttackPercent() { return AttackPercent; } + + // wrappers that hide legacy implementation details. void ChangeStateEnd(); + void clearActionFunc() { user.__legacyState.ActorActionFunc = nullptr; } + void setActionDecide(); + void setStateGroup(FName label, int substate = 0); // substate is only valid for Attack and CloseAttack + bool checkStateGroup(FName label, int substate = 0); + bool hasState(FName label, int substate = 0); + + }; inline void UpdateChangeXY(DSWActor* actor) diff --git a/source/games/sw/src/track.cpp b/source/games/sw/src/track.cpp index 46ebc69132..d98f6df390 100644 --- a/source/games/sw/src/track.cpp +++ b/source/games/sw/src/track.cpp @@ -1071,7 +1071,7 @@ void SetupSectorObject(sectortype* sectp, short tag) { change_actor_stat(actor, STAT_NO_STATE); SpawnUser(actor, 0, nullptr); - actor->user.__legacyState.ActorActionFunc = nullptr; + actor->clearActionFunc(); } break; @@ -2897,7 +2897,7 @@ bool ActorTrackDecide(TRACK_POINT* tpoint, DSWActor* actor) break; case TRACK_ACTOR_STAND: - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Stand); + actor->setStateGroup(NAME_Stand); break; case TRACK_ACTOR_JUMP: @@ -3045,7 +3045,7 @@ bool ActorTrackDecide(TRACK_POINT* tpoint, DSWActor* actor) else actor->user.WaitTics = tpoint->tag_high * 128; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Stand); + actor->setStateGroup(NAME_Stand); } } } @@ -3059,7 +3059,7 @@ bool ActorTrackDecide(TRACK_POINT* tpoint, DSWActor* actor) else actor->user.WaitTics = tpoint->tag_high * 128; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Sit); + actor->setStateGroup(NAME_Sit); } } @@ -3094,20 +3094,20 @@ bool ActorTrackDecide(TRACK_POINT* tpoint, DSWActor* actor) case TRACK_ACTOR_CRAWL: if (actor->user.__legacyState.Rot != actor->user.__legacyState.ActorActionSet->Crawl) - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Crawl); + actor->setStateGroup(NAME_Crawl); else - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Rise); + actor->setStateGroup(NAME_Rise); break; case TRACK_ACTOR_SWIM: if (actor->user.__legacyState.Rot != actor->user.__legacyState.ActorActionSet->Swim) - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Swim); + actor->setStateGroup(NAME_Swim); else - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Rise); + actor->setStateGroup(NAME_Rise); break; case TRACK_ACTOR_FLY: - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Fly); + actor->setStateGroup(NAME_Fly); break; case TRACK_ACTOR_SIT: @@ -3119,7 +3119,7 @@ bool ActorTrackDecide(TRACK_POINT* tpoint, DSWActor* actor) else actor->user.WaitTics = tpoint->tag_high * 128; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Sit); + actor->setStateGroup(NAME_Sit); } break; @@ -3128,7 +3128,7 @@ bool ActorTrackDecide(TRACK_POINT* tpoint, DSWActor* actor) if (actor->user.__legacyState.ActorActionSet->Death2) { actor->user.WaitTics = 4 * 120; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Death1); + actor->setStateGroup(NAME_Death1); } break; @@ -3137,7 +3137,7 @@ bool ActorTrackDecide(TRACK_POINT* tpoint, DSWActor* actor) if (actor->user.__legacyState.ActorActionSet->Death2) { actor->user.WaitTics = 4 * 120; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Death2); + actor->setStateGroup(NAME_Death2); } break; @@ -3150,7 +3150,7 @@ bool ActorTrackDecide(TRACK_POINT* tpoint, DSWActor* actor) actor->vel.X *= 2; actor->user.jump_speed = -495; DoActorBeginJump(actor); - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->DeathJump); + actor->setStateGroup(NAME_DeathJump); } break; @@ -3164,7 +3164,7 @@ bool ActorTrackDecide(TRACK_POINT* tpoint, DSWActor* actor) else actor->user.WaitTics = tpoint->tag_high * 128; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->CloseAttack[0]); + actor->setStateGroup(NAME_CloseAttack, 0); } break; @@ -3178,7 +3178,7 @@ bool ActorTrackDecide(TRACK_POINT* tpoint, DSWActor* actor) else actor->user.WaitTics = tpoint->tag_high * 128; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->CloseAttack[1]); + actor->setStateGroup(NAME_CloseAttack, 1); } break; @@ -3290,7 +3290,7 @@ bool ActorTrackDecide(TRACK_POINT* tpoint, DSWActor* actor) // actor->user.Flags |= (SPR_CLIMBING); - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Climb); + actor->setStateGroup(NAME_Climb); actor->vel.Z -= 1; } @@ -3356,7 +3356,7 @@ int ActorFollowTrack(DSWActor* actor, short locktics) if (actor->user.WaitTics <= 0) { actor->user.Flags &= ~(SPR_DONT_UPDATE_ANG); - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Run); + actor->setStateGroup(NAME_Run); actor->user.WaitTics = 0; } diff --git a/source/games/sw/src/weapon.cpp b/source/games/sw/src/weapon.cpp index 26754964a9..a6fd1d3fe9 100644 --- a/source/games/sw/src/weapon.cpp +++ b/source/games/sw/src/weapon.cpp @@ -5237,7 +5237,7 @@ int ActorPain(DSWActor* actor) { ActorLeaveTrack(actor); actor->user.WaitTics = 60; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Pain); + actor->setStateGroup(NAME_Pain); return true; } } @@ -5258,7 +5258,7 @@ int ActorPainPlasma(DSWActor* actor) if (actor->user.__legacyState.ActorActionSet && actor->user.__legacyState.ActorActionSet->Pain) { actor->user.WaitTics = PLASMA_FOUNTAIN_TIME; - NewStateGroup(actor, actor->user.__legacyState.ActorActionSet->Pain); + actor->setStateGroup(NAME_Pain); return true; } else