move cerberus states into the respective actors.

This is also a place where it allows to simplify the code.
This commit is contained in:
Christoph Oelckers 2023-10-11 21:39:52 +02:00
parent d0621535bf
commit 382d8caf6d
5 changed files with 69 additions and 174 deletions

View file

@ -110,6 +110,17 @@ xx(BurnGoto)
xx(BurnSearch) xx(BurnSearch)
xx(BurnAttack) xx(BurnAttack)
xx(Turn)
xx(Search)
xx(Idle)
xx(Chase)
xx(Recoil)
xx(TeslaRecoil)
xx(Goto)
xx(Bite)
xx(Burn)
xx(Burn2)
// Blood state names. Most of these can be removed after the state system refactor is complete. // Blood state names. Most of these can be removed after the state system refactor is complete.
xx(genIdle) xx(genIdle)
xx(genRecoil) xx(genRecoil)
@ -188,25 +199,6 @@ xx(tinycalebSwimRecoil)
xx(tinycalebSwimUnused) xx(tinycalebSwimUnused)
xx(tinycalebSwimMoveIn) xx(tinycalebSwimMoveIn)
xx(tinycalebSwimTurn) xx(tinycalebSwimTurn)
xx(cerberusIdle)
xx(cerberusSearch)
xx(cerberusChase)
xx(cerberusRecoil)
xx(cerberusTeslaRecoil)
xx(cerberusGoto)
xx(cerberusBite)
xx(cerberusBurn)
xx(cerberus3Burn)
xx(cerberus2Idle)
xx(cerberus2Search)
xx(cerberus2Chase)
xx(cerberus2Recoil)
xx(cerberus2Goto)
xx(cerberus2Bite)
xx(cerberus2Burn)
xx(cerberus4Burn)
xx(cerberusTurn1)
xx(cerberusTurn2)
xx(cultistIdle) xx(cultistIdle)
xx(cultistProneIdle) xx(cultistProneIdle)
xx(fanaticProneIdle) xx(fanaticProneIdle)

View file

@ -902,6 +902,7 @@ static void actInitDudes()
else else
act->xspr.health = act->startHealth() << 4; act->xspr.health = act->startHealth() << 4;
} }
act->spr.xint = 0; // not used by default, but if pre-inited it can be used as an internal flag.
seqSpawn(act->seqStartName(), act->seqStartID(), act); seqSpawn(act->seqStartName(), act->seqStartID(), act);
} }
@ -3902,6 +3903,7 @@ static void actCheckDudes()
{ {
actor->ChangeType(dmt); actor->ChangeType(dmt);
actor->xspr.health = actor->startHealth() << 4; actor->xspr.health = actor->startHealth() << 4;
actor->spr.xint = 1;
if (actor->GetTarget() != nullptr) aiSetTarget(actor, actor->GetTarget()); if (actor->GetTarget() != nullptr) aiSetTarget(actor, actor->GetTarget());
aiActivateDude(actor); aiActivateDude(actor);
} }

View file

@ -720,21 +720,13 @@ void aiActivateDude(DBloodActor* actor)
#endif #endif
break; break;
case kDudeCerberusTwoHead: case kDudeCerberusTwoHead:
if (actor->GetTarget() == nullptr)
aiNewState(actor, NAME_cerberusSearch);
else
{
aiPlay3DSound(actor, 2300, AI_SFX_PRIORITY_1, -1);
aiNewState(actor, NAME_cerberusChase);
}
break;
case kDudeCerberusOneHead: case kDudeCerberusOneHead:
if (actor->GetTarget() == nullptr) if (actor->GetTarget() == nullptr)
aiNewState(actor, NAME_cerberus2Search); aiNewState(actor, NAME_Search);
else else
{ {
aiPlay3DSound(actor, 2300, AI_SFX_PRIORITY_1, -1); aiPlay3DSound(actor, 2300, AI_SFX_PRIORITY_1, -1);
aiNewState(actor, NAME_cerberus2Chase); aiNewState(actor, NAME_Chase);
} }
break; break;
case kDudeHellHound: case kDudeHellHound:
@ -1239,15 +1231,12 @@ void RecoilDude(DBloodActor* actor)
aiNewState(actor, NAME_gargoyleFRecoil); aiNewState(actor, NAME_gargoyleFRecoil);
break; break;
case kDudeCerberusTwoHead: case kDudeCerberusTwoHead:
aiPlay3DSound(actor, 2302 + Random(2), AI_SFX_PRIORITY_2, -1);
if (pDudeExtra->teslaHit && actor->xspr.data3 > actor->startHealth() / 3)
aiNewState(actor, NAME_cerberusTeslaRecoil);
else
aiNewState(actor, NAME_cerberusRecoil);
break;
case kDudeCerberusOneHead: case kDudeCerberusOneHead:
aiPlay3DSound(actor, 2302 + Random(2), AI_SFX_PRIORITY_2, -1); aiPlay3DSound(actor, 2302 + Random(2), AI_SFX_PRIORITY_2, -1);
aiNewState(actor, NAME_cerberus2Recoil); if (pDudeExtra->teslaHit && actor->xspr.data3 > actor->startHealth() / 3 && actor->FindState(NAME_tinycalebTeslaRecoil))
aiNewState(actor, NAME_TeslaRecoil);
else
aiNewState(actor, NAME_Recoil);
break; break;
case kDudeHellHound: case kDudeHellHound:
aiPlay3DSound(actor, 1302, AI_SFX_PRIORITY_2, -1); aiPlay3DSound(actor, 1302, AI_SFX_PRIORITY_2, -1);
@ -1637,13 +1626,14 @@ void aiInitSprite(DBloodActor* actor)
break; break;
case kDudeCerberusTwoHead: { case kDudeCerberusTwoHead: {
actor->dudeExtra.thinkTime = 0; actor->dudeExtra.thinkTime = 0;
aiNewState(actor, NAME_cerberusIdle); aiNewState(actor, NAME_Idle);
break; break;
} }
case kDudeCerberusOneHead: { case kDudeCerberusOneHead: {
if (!VanillaMode()) { if (!VanillaMode()) {
actor->spr.xint = 1;
actor->dudeExtra.thinkTime = 0; actor->dudeExtra.thinkTime = 0;
aiNewState(actor, NAME_cerberus2Idle); aiNewState(actor, NAME_Idle);
break; break;
} }
aiNewState(actor, NAME_genIdle); aiNewState(actor, NAME_genIdle);

View file

@ -98,15 +98,8 @@ void cerberusBurnSeqCallback(DBloodActor* actor)
} }
} }
} }
switch (actor->GetType()) { if (actor->spr.xint == 0) actFireMissile(actor, -Cerberus_XYOff, 0, Aim, kMissileFireballCerberus);
case kDudeCerberusTwoHead: actFireMissile(actor, Cerberus_XYOff, -Cerberus_ZOff, Aim, kMissileFireballCerberus);
actFireMissile(actor, -Cerberus_XYOff, 0, Aim, kMissileFireballCerberus);
actFireMissile(actor, Cerberus_XYOff, -Cerberus_ZOff, Aim, kMissileFireballCerberus);
break;
case kDudeCerberusOneHead:
actFireMissile(actor, Cerberus_XYOff, -Cerberus_ZOff, Aim, kMissileFireballCerberus);
break;
}
} }
void cerberusBurnSeqCallback2(DBloodActor* actor) void cerberusBurnSeqCallback2(DBloodActor* actor)
@ -166,16 +159,8 @@ void cerberusBurnSeqCallback2(DBloodActor* actor)
} }
} }
} }
switch (actor->GetType()) { actFireMissile(actor, Cerberus_XYOff, -Cerberus_ZOff, Aim, kMissileFlameHound);
if (actor->spr.xint == 0) actFireMissile(actor, -Cerberus_XYOff, 0, Aim2, kMissileFlameHound);
case kDudeCerberusTwoHead:
actFireMissile(actor, Cerberus_XYOff, -Cerberus_ZOff, Aim, kMissileFlameHound);
actFireMissile(actor, -Cerberus_XYOff, 0, Aim2, kMissileFlameHound);
break;
case kDudeCerberusOneHead:
actFireMissile(actor, Cerberus_XYOff, -Cerberus_ZOff, Aim, kMissileFlameHound);
break;
}
} }
void cerberusThinkSearch(DBloodActor* actor) void cerberusThinkSearch(DBloodActor* actor)
@ -186,21 +171,13 @@ void cerberusThinkSearch(DBloodActor* actor)
void cerberusThinkTarget(DBloodActor* actor) void cerberusThinkTarget(DBloodActor* actor)
{ {
if (!(actor->IsDudeActor())) {
Printf(PRINT_HIGH, "actor->IsDudeActor()");
return;
}
if (actor->dudeExtra.active && actor->dudeExtra.thinkTime < 10) if (actor->dudeExtra.active && actor->dudeExtra.thinkTime < 10)
actor->dudeExtra.thinkTime++; actor->dudeExtra.thinkTime++;
else if (actor->dudeExtra.thinkTime >= 10 && actor->dudeExtra.active) else if (actor->dudeExtra.thinkTime >= 10 && actor->dudeExtra.active)
{ {
actor->xspr.goalAng += DAngle45; actor->xspr.goalAng += DAngle45;
aiSetTarget(actor, actor->basePoint); aiSetTarget(actor, actor->basePoint);
if (actor->GetType() == kDudeCerberusTwoHead) aiNewState(actor, NAME_Turn);
aiNewState(actor, NAME_cerberusTurn1);
else
aiNewState(actor, NAME_cerberusTurn2);
return; return;
} }
if (Chance(actor->alertChance())) if (Chance(actor->alertChance()))
@ -251,14 +228,7 @@ void cerberusThinkGoto(DBloodActor* actor)
aiChooseDirection(actor, nAngle); aiChooseDirection(actor, nAngle);
if (nDist < 32 && absangle(actor->spr.Angles.Yaw, nAngle) < actor->Periphery()) if (nDist < 32 && absangle(actor->spr.Angles.Yaw, nAngle) < actor->Periphery())
{ {
switch (actor->GetType()) { aiNewState(actor, NAME_Search);
case kDudeCerberusTwoHead:
aiNewState(actor, NAME_cerberusSearch);
break;
case kDudeCerberusOneHead:
aiNewState(actor, NAME_cerberus2Search);
break;
}
} }
aiThinkTarget(actor); aiThinkTarget(actor);
} }
@ -266,14 +236,7 @@ void cerberusThinkGoto(DBloodActor* actor)
void cerberusThinkChase(DBloodActor* actor) void cerberusThinkChase(DBloodActor* actor)
{ {
if (actor->GetTarget() == nullptr) { if (actor->GetTarget() == nullptr) {
switch (actor->GetType()) { aiNewState(actor, NAME_Goto);
case kDudeCerberusTwoHead:
aiNewState(actor, NAME_cerberusGoto);
break;
case kDudeCerberusOneHead:
aiNewState(actor, NAME_cerberus2Goto);
break;
}
return; return;
} }
@ -293,26 +256,12 @@ void cerberusThinkChase(DBloodActor* actor)
aiChooseDirection(actor, nAngle); aiChooseDirection(actor, nAngle);
if (target->xspr.health == 0) { if (target->xspr.health == 0) {
switch (actor->GetType()) { aiNewState(actor, NAME_Search);
case kDudeCerberusTwoHead:
aiNewState(actor, NAME_cerberusSearch);
break;
case kDudeCerberusOneHead:
aiNewState(actor, NAME_cerberus2Search);
break;
}
return; return;
} }
if (target->IsPlayerActor() && powerupCheck(getPlayer(target), kPwUpShadowCloak) > 0) { if (target->IsPlayerActor() && powerupCheck(getPlayer(target), kPwUpShadowCloak) > 0) {
switch (actor->GetType()) { aiNewState(actor, NAME_Search);
case kDudeCerberusTwoHead:
aiNewState(actor, NAME_cerberusSearch);
break;
case kDudeCerberusOneHead:
aiNewState(actor, NAME_cerberus2Search);
break;
}
return; return;
} }
@ -329,64 +278,29 @@ void cerberusThinkChase(DBloodActor* actor)
if (nDist < 0x1b0 && nDist > 0xd0 && nDeltaAngle < DAngle15) if (nDist < 0x1b0 && nDist > 0xd0 && nDeltaAngle < DAngle15)
{ {
switch (actor->GetType()) { aiNewState(actor, NAME_Burn);
case kDudeCerberusTwoHead:
aiNewState(actor, NAME_cerberusBurn);
break;
case kDudeCerberusOneHead:
aiNewState(actor, NAME_cerberus2Burn);
break;
}
} }
else if (nDist < 0xb0 && nDist > 0x50 && nDeltaAngle < DAngle15) else if (nDist < 0xb0 && nDist > 0x50 && nDeltaAngle < DAngle15)
{ {
switch (actor->GetType()) { aiNewState(actor, NAME_Burn2);
case kDudeCerberusTwoHead:
aiNewState(actor, NAME_cerberus3Burn);
break;
case kDudeCerberusOneHead:
aiNewState(actor, NAME_cerberus4Burn);
break;
}
} }
else if (nDist < 0x20 && nDeltaAngle < DAngle15) else if (nDist < 0x20 && nDeltaAngle < DAngle15)
{ {
int hit = HitScan(actor, actor->spr.pos.Z, DVector3(dvec, 0), CLIPMASK1, 0); int hit = HitScan(actor, actor->spr.pos.Z, DVector3(dvec, 0), CLIPMASK1, 0);
switch (actor->GetType()) { switch (hit) {
case kDudeCerberusTwoHead: case -1:
switch (hit) { aiNewState(actor, NAME_Bite);
case -1:
aiNewState(actor, NAME_cerberusBite);
break;
case 3:
if (actor->GetType() != gHitInfo.actor()->GetType() && gHitInfo.actor()->GetType() != kDudeHellHound)
aiNewState(actor, NAME_cerberusBite);
break;
case 0:
case 4:
break;
default:
aiNewState(actor, NAME_cerberusBite);
break;
}
break; break;
case kDudeCerberusOneHead: case 3:
switch (hit) { if (actor->GetType() != gHitInfo.actor()->GetType() && gHitInfo.actor()->GetType() != kDudeHellHound)
case -1: aiNewState(actor, NAME_Bite);
aiNewState(actor, NAME_cerberus2Bite); break;
break; case 0:
case 3: case 4:
if (actor->GetType() != gHitInfo.actor()->GetType() && gHitInfo.actor()->GetType() != kDudeHellHound) break;
aiNewState(actor, NAME_cerberus2Bite); default:
break; aiNewState(actor, NAME_Bite);
case 0:
case 4:
break;
default:
aiNewState(actor, NAME_cerberus2Bite);
break;
}
break; break;
} }
} }
@ -395,14 +309,7 @@ void cerberusThinkChase(DBloodActor* actor)
} }
} }
switch (actor->GetType()) { aiNewState(actor, NAME_Goto);
case kDudeCerberusTwoHead:
aiNewState(actor, NAME_cerberusGoto);
break;
case kDudeCerberusOneHead:
aiNewState(actor, NAME_cerberus2Goto);
break;
}
actor->SetTarget(nullptr); actor->SetTarget(nullptr);
} }

View file

@ -132,25 +132,6 @@ class BloodDudeBase : Bloodactor
AISTATE "tinycalebSwimUnused", "+8", -1, 120, null, null, calebSwimUnused, calebThinkSwimChase, "tinycalebSwimChase"; AISTATE "tinycalebSwimUnused", "+8", -1, 120, null, null, calebSwimUnused, calebThinkSwimChase, "tinycalebSwimChase";
AISTATE "tinycalebSwimMoveIn", "+8", -1, 0, null, null, calebSwimMoveIn, calebThinkSwimChase, "tinycalebSwimChase"; AISTATE "tinycalebSwimMoveIn", "+8", -1, 0, null, null, calebSwimMoveIn, calebThinkSwimChase, "tinycalebSwimChase";
AISTATE "tinycalebSwimTurn", "+8", -1, 120, null, null, aiMoveTurn, null, "tinycalebSwimChase"; AISTATE "tinycalebSwimTurn", "+8", -1, 120, null, null, aiMoveTurn, null, "tinycalebSwimChase";
AISTATE "cerberusIdle", "+0", 0, 0, null, null, null, cerberusThinkTarget, "none";
AISTATE "cerberusSearch", "+7", 3, 1800, null, null, aiMoveForward, cerberusThinkSearch, "cerberusIdle";
AISTATE "cerberusChase", "+7", 4, 0, null, null, aiMoveForward, cerberusThinkChase, "none";
AISTATE "cerberusRecoil", "+5", 5, 0, null, null, null, null, "cerberusSearch";
AISTATE "cerberusTeslaRecoil", "+4", 5, 0, null, null, null, null, "cerberusSearch";
AISTATE "cerberusGoto", "+7", 2, 600, null, null, aiMoveForward, cerberusThinkGoto, "cerberusIdle";
AISTATE "cerberusBite", "+6", 4, 60, cerberusBiteSeqCallback, null, null, null, "cerberusChase";
AISTATE "cerberusBurn", "+6", 4, 60, cerberusBurnSeqCallback, null, null, null, "cerberusChase";
AISTATE "cerberus3Burn", "+6", 4, 60, cerberusBurnSeqCallback2, null, null, null, "cerberusChase";
AISTATE "cerberus2Idle", "+0", 0, 0, null, null, null, cerberusThinkTarget, "none";
AISTATE "cerberus2Search", "+7", 3, 1800, null, null, aiMoveForward, cerberusThinkSearch, "cerberus2Idle";
AISTATE "cerberus2Chase", "+7", 4, 0, null, null, aiMoveForward, cerberusThinkChase, "none";
AISTATE "cerberus2Recoil", "+5", 5, 0, null, null, null, null, "cerberus2Search";
AISTATE "cerberus2Goto", "+7", 2, 600, null, null, aiMoveForward, cerberusThinkGoto, "cerberus2Idle";
AISTATE "cerberus2Bite", "+6", 4, 60, cerberusBiteSeqCallback, null, null, null, "cerberus2Chase";
AISTATE "cerberus2Burn", "+6", 4, 60, cerberusBurnSeqCallback, null, null, null, "cerberus2Chase";
AISTATE "cerberus4Burn", "+6", 4, 60, cerberusBurnSeqCallback2, null, null, null, "cerberus2Chase";
AISTATE "cerberusTurn1", "+7", -1, 120, null, null, aiMoveTurn, null, "cerberusChase";
AISTATE "cerberusTurn2", "+7", -1, 120, null, null, aiMoveTurn, null, "cerberusChase";
AISTATE "cultistIdle", "+0", 0, 0, null, null, null, aiThinkTarget, "none"; AISTATE "cultistIdle", "+0", 0, 0, null, null, null, aiThinkTarget, "none";
AISTATE "cultistProneIdle", "+17", 0, 0, null, null, null, aiThinkTarget, "none"; AISTATE "cultistProneIdle", "+17", 0, 0, null, null, null, aiThinkTarget, "none";
AISTATE "fanaticProneIdle", "+17", 0, 0, null, null, null, aiThinkTarget, "none"; AISTATE "fanaticProneIdle", "+17", 0, 0, null, null, null, aiThinkTarget, "none";
@ -1168,6 +1149,18 @@ class BloodDudeCerberusTwoHead : BloodDudeBase
turnrange 67.5; turnrange 67.5;
gibtype 7, -1, -1; gibtype 7, -1, -1;
dmgcontrol 16, 0, 16, 16, 0, 96, 48; dmgcontrol 16, 0, 16, 16, 0, 96, 48;
AISTATE "Turn", "+7", -1, 120, null, null, aiMoveTurn, null, "cerberusChase";
AISTATE "Search", "+7", 3, 1800, null, null, aiMoveForward, cerberusThinkSearch, "cerberusIdle";
AISTATE "Idle", "+0", 0, 0, null, null, null, cerberusThinkTarget, "none";
AISTATE "Chase", "+7", 4, 0, null, null, aiMoveForward, cerberusThinkChase, "none";
AISTATE "Recoil", "+5", 5, 0, null, null, null, null, "Search";
AISTATE "TeslaRecoil", "+4", 5, 0, null, null, null, null, "Search";
AISTATE "Goto", "+7", 2, 600, null, null, aiMoveForward, cerberusThinkGoto, "Idle";
AISTATE "Bite", "+6", 4, 60, cerberusBiteSeqCallback, null, null, null, "Chase";
AISTATE "Burn", "+6", 4, 60, cerberusBurnSeqCallback, null, null, null, "Chase";
AISTATE "Burn2", "+6", 4, 60, cerberusBurnSeqCallback2, null, null, null, "Chase";
deathMorphType "BloodDudeCerberusOneHead"; deathMorphType "BloodDudeCerberusOneHead";
+BloodDudeBase.floorhitdamage; +BloodDudeBase.floorhitdamage;
preloadseq 6, 7; preloadseq 6, 7;
@ -1198,6 +1191,17 @@ class BloodDudeCerberusOneHead : BloodDudeBase
turnrange 67.5; turnrange 67.5;
gibtype 7, -1, -1; gibtype 7, -1, -1;
dmgcontrol 16, 0, 16, 16, 0, 96, 48; dmgcontrol 16, 0, 16, 16, 0, 96, 48;
AISTATE "Turn", "+7", -1, 120, null, null, aiMoveTurn, null, "cerberusChase";
AISTATE "Search", "+7", 3, 1800, null, null, aiMoveForward, cerberusThinkSearch, "cerberus2Idle";
AISTATE "Idle", "+0", 0, 0, null, null, null, cerberusThinkTarget, "none";
AISTATE "Chase", "+7", 4, 0, null, null, aiMoveForward, cerberusThinkChase, "none";
AISTATE "Recoil", "+5", 5, 0, null, null, null, null, "cerberus2Search";
AISTATE "Goto", "+7", 2, 600, null, null, aiMoveForward, cerberusThinkGoto, "Idle";
AISTATE "Bite", "+6", 4, 60, cerberusBiteSeqCallback, null, null, null, "Chase";
AISTATE "Burn", "+6", 4, 60, cerberusBurnSeqCallback, null, null, null, "Chase";
AISTATE "Burn2", "+6", 4, 60, cerberusBurnSeqCallback2, null, null, null, "Chase";
+BloodDudeBase.floorhitdamage; +BloodDudeBase.floorhitdamage;
preloadseq 6, 7; preloadseq 6, 7;
} }