diff --git a/code/fgame/actor.cpp b/code/fgame/actor.cpp index 1a88fb18..e8621d72 100644 --- a/code/fgame/actor.cpp +++ b/code/fgame/actor.cpp @@ -4659,11 +4659,6 @@ void Actor::FireWeapon(Event *ev) Sentient::FireWeapon(WEAPON_MAIN, FIRE_PRIMARY); } -bool Actor::IsMachineGunnerState(int state) -{ - return true; -} - bool Actor::IsDogState(int state) { return true; @@ -11652,6 +11647,11 @@ bool Actor::IsKilledState(int state) return state == THINKSTATE_KILLED; } +bool Actor::IsNoClipState(int state) +{ + return state == THINKSTATE_NOCLIP; +} + /* =============== Actor::InitVoid diff --git a/code/fgame/actor.h b/code/fgame/actor.h index da39a0b0..257b1ed2 100644 --- a/code/fgame/actor.h +++ b/code/fgame/actor.h @@ -832,7 +832,7 @@ public: void State_Turret_Grenade(void); void State_Turret_FakeEnemy(void); void State_Turret_Wait(void); - void State_Turret_Retarget_Shoot(void); // Added in 2.0 + void State_Turret_Shoot(void); // Added in 2.0 void State_Turret_Retarget_Suppress(void); // Added in 2.0 void State_Turret_Retarget_Sniper_Node(void); void State_Turret_Retarget_Step_Side_Small(void); @@ -983,7 +983,6 @@ public: void ThinkHoldGun_TurretGun(void); // Added in 2.0 void Think_MachineGunner_TurretGun(void); // Added in 2.0 void Think_MachineGunner(void); - void ThinkHoldGun(void); void FinishedAnimation_MachineGunner(void); bool MachineGunner_CanSee(Entity *ent, float fov, float vision_distance); static void InitDogIdle(GlobalFuncs_t *func); diff --git a/code/fgame/actor_cover.cpp b/code/fgame/actor_cover.cpp index 9c819948..1a47b87b 100644 --- a/code/fgame/actor_cover.cpp +++ b/code/fgame/actor_cover.cpp @@ -24,6 +24,121 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "actor.h" +bool Actor::Cover_IsValid(PathNode *node) +{ + if (!node->IsClaimedByOther(this)) { + if (node->nodeflags & AI_CONCEALMENT) { + return true; + } else if (CanSeeFrom(origin + eyeposition, m_Enemy)) { + if (!(node->nodeflags & AI_DUCK)) { + return false; + } else if (CanSeeFrom(origin + eyeposition - Vector(0, 0, 32), m_Enemy)) { + return false; + } else { + return true; + } + } else { + return true; + } + } else { + return false; + } +} + +bool Actor::Cover_SetPath(PathNode *node) +{ + SetPathWithLeash(node, NULL, 0); + + if (!PathExists()) { + return false; + } + + float origin_ratio; + Vector enemy_offset; + PathInfo *current_node; + Vector enemy_origin; + Vector vDelta; + float fMinDistSquared; + float fPathDist; + + fPathDist = PathDist(); + fMinDistSquared = fPathDist * fPathDist; + vDelta = node->origin - origin; + + if (fMinDistSquared >= vDelta.lengthSquared() * 4.0f) { + if (fPathDist > 128.0f) { + return false; + } + } + + if (!PathComplete()) { + enemy_origin = m_Enemy->origin; + vDelta = enemy_origin - origin; + + if (VectorLength2DSquared(vDelta) * 0.64f > 192 * 192) { + origin_ratio = 192 * 192; + } + + for (current_node = CurrentPathNode() - 1; current_node >= LastPathNode(); current_node--) { + vDelta[0] = origin[0] - current_node->point[0]; + vDelta[1] = origin[1] - current_node->point[1]; + + if (origin_ratio >= VectorLength2DSquared(vDelta)) { + return false; + } + + float fDot = DotProduct2D(vDelta, current_node->dir); + if (fDot < 0.0f && -current_node->dist <= fDot) { + if ((vDelta[0] * current_node->dir[0] - vDelta[1] * current_node->dir[1]) + * (vDelta[0] * current_node->dir[0] - vDelta[1] * current_node->dir[1])) { + return false; + } + } + } + } + + return true; +} + +void Actor::Cover_FindCover(bool bCheckAll) +{ + if (m_pCoverNode) { + if (Cover_IsValid(m_pCoverNode) && Cover_SetPath(m_pCoverNode)) { + return; + } + + m_pCoverNode->Relinquish(); + m_pCoverNode = NULL; + } + + if (!m_iPotentialCoverCount) { + m_iPotentialCoverCount = PathManager.FindPotentialCover(this, origin, m_Enemy, m_pPotentialCoverNode, 16); + } + + if (m_iPotentialCoverCount) { + PathNode *pNode = NULL; + + while (m_iPotentialCoverCount) { + m_iPotentialCoverCount--; + pNode = m_pPotentialCoverNode[m_iPotentialCoverCount]; + m_pPotentialCoverNode[m_iPotentialCoverCount] = NULL; + + if (Cover_IsValid(pNode) && Cover_SetPath(pNode)) { + break; + } + + if (!bCheckAll) { + return; + } + } + + m_pCoverNode = pNode; + m_pCoverNode->Claim(this); + memset(m_pPotentialCoverNode, 0, sizeof(m_pPotentialCoverNode)); + m_iPotentialCoverCount = 0; + } +} + void Actor::InitCover(GlobalFuncs_t *func) { func->ThinkState = &Actor::Think_Cover; @@ -621,118 +736,3 @@ void Actor::PathnodeClaimRevoked_Cover(void) { TransitionState(301, 0); } - -bool Actor::Cover_IsValid(PathNode *node) -{ - if (!node->IsClaimedByOther(this)) { - if (node->nodeflags & AI_CONCEALMENT) { - return true; - } else if (CanSeeFrom(origin + eyeposition, m_Enemy)) { - if (!(node->nodeflags & AI_DUCK)) { - return false; - } else if (CanSeeFrom(origin + eyeposition - Vector(0, 0, 32), m_Enemy)) { - return false; - } else { - return true; - } - } else { - return true; - } - } else { - return false; - } -} - -bool Actor::Cover_SetPath(PathNode *node) -{ - SetPathWithLeash(node, NULL, 0); - - if (!PathExists()) { - return false; - } - - float origin_ratio; - Vector enemy_offset; - PathInfo *current_node; - Vector enemy_origin; - Vector vDelta; - float fMinDistSquared; - float fPathDist; - - fPathDist = PathDist(); - fMinDistSquared = fPathDist * fPathDist; - vDelta = node->origin - origin; - - if (fMinDistSquared >= vDelta.lengthSquared() * 4.0f) { - if (fPathDist > 128.0f) { - return false; - } - } - - if (!PathComplete()) { - enemy_origin = m_Enemy->origin; - vDelta = enemy_origin - origin; - - if (VectorLength2DSquared(vDelta) * 0.64f > 192 * 192) { - origin_ratio = 192 * 192; - } - - for (current_node = CurrentPathNode() - 1; current_node >= LastPathNode(); current_node--) { - vDelta[0] = origin[0] - current_node->point[0]; - vDelta[1] = origin[1] - current_node->point[1]; - - if (origin_ratio >= VectorLength2DSquared(vDelta)) { - return false; - } - - float fDot = DotProduct2D(vDelta, current_node->dir); - if (fDot < 0.0f && -current_node->dist <= fDot) { - if ((vDelta[0] * current_node->dir[0] - vDelta[1] * current_node->dir[1]) - * (vDelta[0] * current_node->dir[0] - vDelta[1] * current_node->dir[1])) { - return false; - } - } - } - } - - return true; -} - -void Actor::Cover_FindCover(bool bCheckAll) -{ - if (m_pCoverNode) { - if (Cover_IsValid(m_pCoverNode) && Cover_SetPath(m_pCoverNode)) { - return; - } - - m_pCoverNode->Relinquish(); - m_pCoverNode = NULL; - } - - if (!m_iPotentialCoverCount) { - m_iPotentialCoverCount = PathManager.FindPotentialCover(this, origin, m_Enemy, m_pPotentialCoverNode, 16); - } - - if (m_iPotentialCoverCount) { - PathNode *pNode = NULL; - - while (m_iPotentialCoverCount) { - m_iPotentialCoverCount--; - pNode = m_pPotentialCoverNode[m_iPotentialCoverCount]; - m_pPotentialCoverNode[m_iPotentialCoverCount] = NULL; - - if (Cover_IsValid(pNode) && Cover_SetPath(pNode)) { - break; - } - - if (!bCheckAll) { - return; - } - } - - m_pCoverNode = pNode; - m_pCoverNode->Claim(this); - memset(m_pPotentialCoverNode, 0, sizeof(m_pPotentialCoverNode)); - m_iPotentialCoverCount = 0; - } -} diff --git a/code/fgame/actor_curious.cpp b/code/fgame/actor_curious.cpp index e022a427..eafe9312 100644 --- a/code/fgame/actor_curious.cpp +++ b/code/fgame/actor_curious.cpp @@ -36,6 +36,11 @@ void Actor::InitCurious(GlobalFuncs_t *func) func->IsState = &Actor::IsCuriousState; } +void Actor::SetCuriousAnimHint(int iAnimHint) +{ + m_iCuriousAnimHint = iAnimHint; +} + void Actor::Begin_Curious(void) { Vector vDelta; @@ -324,11 +329,6 @@ void Actor::Think_Curious(void) } } -void Actor::FinishedAnimation_Curious(void) -{ - FinishedAnimation_AnimCurious(); -} - void Actor::LookAtCuriosity(void) { Vector vAngles; @@ -382,7 +382,7 @@ void Actor::TimeOutCurious(void) } } -void Actor::SetCuriousAnimHint(int iAnimHint) +void Actor::FinishedAnimation_Curious(void) { - m_iCuriousAnimHint = iAnimHint; + FinishedAnimation_AnimCurious(); } diff --git a/code/fgame/actor_grenade.cpp b/code/fgame/actor_grenade.cpp index 6f564c07..028ec247 100644 --- a/code/fgame/actor_grenade.cpp +++ b/code/fgame/actor_grenade.cpp @@ -25,18 +25,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "actor.h" #include "weaputils.h" -void Actor::InitGrenade(GlobalFuncs_t *func) -{ - func->ThinkState = &Actor::Think_Grenade; - func->BeginState = &Actor::Begin_Grenade; - func->EndState = &Actor::End_Grenade; - func->ResumeState = &Actor::Resume_Grenade; - func->SuspendState = &Actor::End_Grenade; - func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Grenade; - func->FinishedAnimation = &Actor::FinishedAnimation_Grenade; - func->IsState = &Actor::IsGrenadeState; -} - bool Actor::Grenade_Acquire(eGrenadeState eNextState, const_str csReturnAnim) { bool bRetVal = false; @@ -89,6 +77,18 @@ bool Actor::Grenade_Acquire(eGrenadeState eNextState, const_str csReturnAnim) return bRetVal; } +void Actor::InitGrenade(GlobalFuncs_t *func) +{ + func->ThinkState = &Actor::Think_Grenade; + func->BeginState = &Actor::Begin_Grenade; + func->EndState = &Actor::End_Grenade; + func->ResumeState = &Actor::Resume_Grenade; + func->SuspendState = &Actor::End_Grenade; + func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Grenade; + func->FinishedAnimation = &Actor::FinishedAnimation_Grenade; + func->IsState = &Actor::IsGrenadeState; +} + void Actor::Grenade_Flee(void) { //float origin_ratio; @@ -437,6 +437,30 @@ void Actor::Resume_Grenade(void) } } +void Actor::FinishedAnimation_Grenade(void) +{ + switch (m_eGrenadeState) { + case AI_GRENSTATE_FLEE: + case AI_GRENSTATE_THROW_ACQUIRE: + case AI_GRENSTATE_KICK_ACQUIRE: + case AI_GRENSTATE_MARTYR_ACQUIRE: + case AI_GRENSTATE_MARTYR: + case AI_GRENSTATE_FLEE_SUCCESS: + case AI_GRENSTATE_FLEE_FAIL: + return; + case AI_GRENSTATE_THROW: + case AI_GRENSTATE_KICK: + Grenade_NextThinkState(); + break; + default: + char assertStr[16317] = {0}; + strcpy(assertStr, "\"invalid grenade state in FinishedAnimation()\"\n\tMessage: "); + Q_strcat(assertStr, sizeof(assertStr), DumpCallTrace("state = %i", m_eGrenadeState)); + assert(!assertStr); + break; + } +} + void Actor::Think_Grenade(void) { if (m_bEnableEnemy) { @@ -513,27 +537,3 @@ void Actor::Think_Grenade(void) PostThink(false); } - -void Actor::FinishedAnimation_Grenade(void) -{ - switch (m_eGrenadeState) { - case AI_GRENSTATE_FLEE: - case AI_GRENSTATE_THROW_ACQUIRE: - case AI_GRENSTATE_KICK_ACQUIRE: - case AI_GRENSTATE_MARTYR_ACQUIRE: - case AI_GRENSTATE_MARTYR: - case AI_GRENSTATE_FLEE_SUCCESS: - case AI_GRENSTATE_FLEE_FAIL: - return; - case AI_GRENSTATE_THROW: - case AI_GRENSTATE_KICK: - Grenade_NextThinkState(); - break; - default: - char assertStr[16317] = {0}; - strcpy(assertStr, "\"invalid grenade state in FinishedAnimation()\"\n\tMessage: "); - Q_strcat(assertStr, sizeof(assertStr), DumpCallTrace("state = %i", m_eGrenadeState)); - assert(!assertStr); - break; - } -} diff --git a/code/fgame/actor_idle.cpp b/code/fgame/actor_idle.cpp index 39b4e3d8..71986131 100644 --- a/code/fgame/actor_idle.cpp +++ b/code/fgame/actor_idle.cpp @@ -39,16 +39,6 @@ void Actor::Begin_Idle(void) ClearPath(); } -void Actor::Think_Idle(void) -{ - if (RequireThink()) { - UpdateEyeOrigin(); - m_pszDebugState = ""; - CheckForThinkStateTransition(); - IdleThink(); - } -} - void Actor::IdleThink(void) { IdlePoint(); @@ -73,4 +63,14 @@ void Actor::IdleThink(void) } PostThink(true); +} + +void Actor::Think_Idle(void) +{ + if (RequireThink()) { + UpdateEyeOrigin(); + m_pszDebugState = ""; + CheckForThinkStateTransition(); + IdleThink(); + } } \ No newline at end of file diff --git a/code/fgame/actor_machinegunner.cpp b/code/fgame/actor_machinegunner.cpp index 1da2ed10..0f775fe9 100644 --- a/code/fgame/actor_machinegunner.cpp +++ b/code/fgame/actor_machinegunner.cpp @@ -37,6 +37,11 @@ void Actor::InitMachineGunner(GlobalFuncs_t *func) func->FinishedAnimation = &Actor::FinishedAnimation_MachineGunner; } +bool Actor::IsMachineGunnerState(int state) +{ + return true; +} + void Actor::Begin_MachineGunner(void) { m_csMood = STRING_ALERT; @@ -92,75 +97,6 @@ void Actor::End_MachineGunner(void) } void Actor::ThinkHoldGun_TurretGun(void) -{ - // FIXME: unimplemented -} - -void Actor::Think_MachineGunner_TurretGun(void) -{ - // FIXME: unimplemented -} - -void Actor::Think_MachineGunner(void) -{ - if (RequireThink()) { - if (m_pTurret && m_pTurret->GetOwner() == this && !m_bNoPlayerCollision) { - if (!m_bEnableEnemy) { - ThinkHoldGun(); - return; - } - - if (level.inttime < m_iEnemyCheckTime + 200) { - ThinkHoldGun(); - return; - } - - m_iEnemyCheckTime = level.inttime; - - if (m_pTurret->AI_CanTarget(G_GetEntity(0)->centroid)) { - ThinkHoldGun(); - return; - } - if (!m_pGrenade || m_fGrenadeAwareness < rand() * 0.000000046566129) { - if (!G_SightTrace( - EyePosition(), - vec_zero, - vec_zero, - G_GetEntity(0)->centroid, - this, - G_GetEntity(0), - 33819417, - qfalse, - "Actor::Think_MachineGunner" - )) { - ThinkHoldGun(); - return; - } - if (m_ThinkStates[THINKLEVEL_NORMAL] != THINKSTATE_IDLE) { - BecomeTurretGuy(); - return; - } - - if (m_Enemy && !m_Enemy->IsSubclassOfActor() && !EnemyIsDisguised() - && m_PotentialEnemies.GetCurrentVisibility() >= 1) { - BecomeTurretGuy(); - return; - } - - if (!m_Enemy || !m_Enemy->IsSubclassOfActor() || EnemyIsDisguised() - || m_PotentialEnemies.GetCurrentVisibility() > 1) { - ThinkHoldGun(); - return; - } - - SetCuriousAnimHint(6); - } - } - BecomeTurretGuy(); - } -} - -void Actor::ThinkHoldGun(void) { Vector end; trace_t trace; @@ -252,7 +188,7 @@ void Actor::ThinkHoldGun(void) end = start; end.z = origin.z - 94.0; - trace = G_Trace(start, MINS, MAXS, end, this, 1107437825, qfalse, "Actor::ThinkHoldGun"); + trace = G_Trace(start, MINS, MAXS, end, this, 1107437825, qfalse, "Actor::ThinkHoldGun_TurretGun"); if (trace.fraction != 1.0 && !trace.startsolid && !trace.allsolid && trace.ent) { SafeSetOrigin(trace.endpos); @@ -264,6 +200,70 @@ void Actor::ThinkHoldGun(void) UpdateFootsteps(); } +void Actor::Think_MachineGunner_TurretGun(void) +{ + // FIXME: unimplemented +} + +void Actor::Think_MachineGunner(void) +{ + if (RequireThink()) { + if (m_pTurret && m_pTurret->GetOwner() == this && !m_bNoPlayerCollision) { + if (!m_bEnableEnemy) { + ThinkHoldGun_TurretGun(); + return; + } + + if (level.inttime < m_iEnemyCheckTime + 200) { + ThinkHoldGun_TurretGun(); + return; + } + + m_iEnemyCheckTime = level.inttime; + + if (m_pTurret->AI_CanTarget(G_GetEntity(0)->centroid)) { + ThinkHoldGun_TurretGun(); + return; + } + if (!m_pGrenade || m_fGrenadeAwareness < rand() * 0.000000046566129) { + if (!G_SightTrace( + EyePosition(), + vec_zero, + vec_zero, + G_GetEntity(0)->centroid, + this, + G_GetEntity(0), + 33819417, + qfalse, + "Actor::Think_MachineGunner" + )) { + ThinkHoldGun_TurretGun(); + return; + } + if (m_ThinkStates[THINKLEVEL_NORMAL] != THINKSTATE_IDLE) { + BecomeTurretGuy(); + return; + } + + if (m_Enemy && !m_Enemy->IsSubclassOfActor() && !EnemyIsDisguised() + && m_PotentialEnemies.GetCurrentVisibility() >= 1) { + BecomeTurretGuy(); + return; + } + + if (!m_Enemy || !m_Enemy->IsSubclassOfActor() || EnemyIsDisguised() + || m_PotentialEnemies.GetCurrentVisibility() > 1) { + ThinkHoldGun_TurretGun(); + return; + } + + SetCuriousAnimHint(6); + } + } + BecomeTurretGuy(); + } +} + void Actor::FinishedAnimation_MachineGunner(void) { if (!m_bAnimScriptSet && m_State == 1201) { diff --git a/code/fgame/actor_noclip.cpp b/code/fgame/actor_noclip.cpp index 7b4936a7..986e6b1a 100644 --- a/code/fgame/actor_noclip.cpp +++ b/code/fgame/actor_noclip.cpp @@ -30,11 +30,6 @@ void Actor::InitNoClip(GlobalFuncs_t *func) func->IsState = &Actor::IsIdleState; } -bool Actor::IsNoClipState(int state) -{ - return state == THINKSTATE_NOCLIP; -} - void Actor::Think_NoClip(void) { //FIXME: not sure of naming diff --git a/code/fgame/actor_patrol.cpp b/code/fgame/actor_patrol.cpp index 6df1c5b1..057f0b1f 100644 --- a/code/fgame/actor_patrol.cpp +++ b/code/fgame/actor_patrol.cpp @@ -49,7 +49,6 @@ void Actor::End_Patrol(void) void Actor::Resume_Patrol(void) { - ; } void Actor::Think_Patrol(void) diff --git a/code/fgame/actor_runner.cpp b/code/fgame/actor_runner.cpp index f9aebca2..cbbbf0fe 100644 --- a/code/fgame/actor_runner.cpp +++ b/code/fgame/actor_runner.cpp @@ -50,7 +50,6 @@ void Actor::End_Runner(void) void Actor::Resume_Runner(void) { - ; } void Actor::Think_Runner(void) diff --git a/code/fgame/actor_turret.cpp b/code/fgame/actor_turret.cpp index 5c7ae78b..f8f5ef0f 100644 --- a/code/fgame/actor_turret.cpp +++ b/code/fgame/actor_turret.cpp @@ -39,248 +39,6 @@ void Actor::InitTurret(GlobalFuncs_t *func) func->PathnodeClaimRevoked = &Actor::PathnodeClaimRevoked_Turret; } -void Actor::Begin_Turret(void) -{ - DoForceActivate(); - m_csMood = STRING_ALERT; - - ClearPath(); - - if (m_Enemy) { - TransitionState(110, 0); - } else { - TransitionState(109, (rand() & 0x7FF) + 250); - } -} - -void Actor::End_Turret(void) -{ - if (m_pCoverNode && m_State != 111) { - m_pCoverNode->Relinquish(); - m_pCoverNode = NULL; - } - TransitionState(-1, 0); -} - -void Actor::Suspend_Turret(void) -{ - if (!m_Enemy) { - TransitionState(110, 0); - } else { - if (m_State <= 108) { - SetEnemyPos(m_Enemy->origin); - AimAtEnemyBehavior(); - TransitionState(113, 0); - } - } -} - -void Actor::Think_Turret(void) -{ - if (RequireThink()) { - UpdateEyeOrigin(); - NoPoint(); - UpdateEnemy(200); - - if (m_Enemy && m_State == 110) { - if (!m_bTurretNoInitialCover && Turret_TryToBecomeCoverGuy()) { - m_pszDebugState = "CoverInstead"; - CheckUnregister(); - UpdateAngles(); - DoMove(); - UpdateBoneControllers(); - UpdateFootsteps(); - return; - } - - m_bTurretNoInitialCover = false; - - Turret_SelectState(); - - if (m_State == 100 && !CanSeeEnemy(0)) { - Turret_BeginRetarget(); - } - - SetLeashHome(origin); - - if (level.inttime < m_iEnemyChangeTime + 200) { - if (AttackEntryAnimation()) { - m_bLockThinkState = true; - TransitionState(108, 0); - } - } - } - - if (level.inttime > m_iStateTime + 3000) { - Turret_SelectState(); - } - - if (m_State == 108) { - m_pszDebugState = "IntroAnim"; - AimAtTargetPos(); - ContinueAnimation(); - } else { - m_bLockThinkState = false; - if (!m_Enemy && m_State != 109 && m_State != 104) { - TransitionState(109, ((rand() + 250) & 0x7FF)); - } - if (!m_Enemy) { - if (m_State != 109) { - if (m_State != 104 || (origin - m_vHome).lengthXYSquared() <= 0.64f * m_fLeashSquared + 64.0f - || !State_Turret_RunHome(false)) { - m_pszDebugState = "Idle"; - SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); - IdleThink(); - } else { - m_pszDebugState = "Idle->RunHome"; - PostThink(true); - } - return; - } - } - if (m_Enemy && m_State == 109) { - Turret_BeginRetarget(); - } - - if (Turret_DecideToSelectState()) { - Turret_SelectState(); - } - - switch (m_State) { - case 100: - m_pszDebugState = "Combat"; - State_Turret_Combat(); - break; - case 101: - m_pszDebugState = "Reacquire"; - State_Turret_Reacquire(); - break; - case 102: - m_pszDebugState = "TakeSniperNode"; - if (!PathExists() || PathComplete()) { - AimAtEnemyBehavior(); - TransitionState(103, 0); - } else { - FaceMotion(); - Anim_RunToDanger(3); - } - break; - case 103: - m_pszDebugState = "SniperNode"; - State_Turret_SniperNode(); - break; - case 104: - m_pszDebugState = "RunHome"; - State_Turret_RunHome(true); - break; - case 105: - m_pszDebugState = "RunAway"; - State_Turret_RunAway(); - break; - case 106: - m_pszDebugState = "Charge"; - State_Turret_Charge(); - break; - case 107: - m_pszDebugState = "Grenade"; - State_Turret_Grenade(); - break; - case 109: - m_pszDebugState = "FakeEnemy"; - State_Turret_FakeEnemy(); - break; - case 111: - m_pszDebugState = "BecomeCover"; - ContinueAnimation(); - break; - case 112: - m_pszDebugState = "Wait"; - State_Turret_Wait(); - break; - case 113: - m_pszDebugState = "Retarget_Sniper_Node"; - State_Turret_Retarget_Sniper_Node(); - break; - case 114: - m_pszDebugState = "Retarget_Step_Side_Small"; - State_Turret_Retarget_Step_Side_Small(); - break; - case 115: - m_pszDebugState = "Retarget_Path_Exact"; - State_Turret_Retarget_Path_Exact(); - break; - case 116: - m_pszDebugState = "Retarget_Path_Near"; - State_Turret_Retarget_Path_Near(); - break; - case 117: - m_pszDebugState = "Retarget_Step_Side_Medium"; - State_Turret_Retarget_Step_Side_Medium(); - break; - case 118: - m_pszDebugState = "Retarget_Step_Side_Large"; - State_Turret_Retarget_Step_Side_Large(); - break; - case 119: - m_pszDebugState = "Retarget_Step_Face_Medium"; - State_Turret_Retarget_Step_Face_Medium(); - break; - case 120: - m_pszDebugState = "Retarget_Step_Face_Large"; - State_Turret_Retarget_Step_Face_Large(); - break; - default: - Com_Printf("Actor::Think_Turret: invalid think state %i\n", m_State); - assert(!"invalid think state"); - break; - } - CheckForTransition(THINKSTATE_GRENADE, THINKLEVEL_NORMAL); - } - if (m_State == 112) { - PostThink(false); - } else { - PostThink(true); - } - } -} - -void Actor::FinishedAnimation_Turret(void) -{ - if (m_State <= 108) { - Turret_SelectState(); - } -} - -void Actor::ReceiveAIEvent_Turret( - vec3_t event_origin, int iType, Entity *originator, float fDistSquared, float fMaxDistSquared -) -{ - if (iType == AI_EVENT_WEAPON_IMPACT) { - if (m_Enemy && fDistSquared <= Square(128)) { - Turret_TryToBecomeCoverGuy(); - } - } else { - DefaultReceiveAIEvent(origin, iType, originator, fDistSquared, fMaxDistSquared); - } -} - -void Actor::InterruptPoint_Turret(void) -{ - if (m_Enemy && !Turret_TryToBecomeCoverGuy() && m_State == 100) { - m_iStateTime = level.inttime; - Turret_SelectState(); - } -} - -void Actor::PathnodeClaimRevoked_Turret(void) -{ - if (m_Enemy == NULL) { - TransitionState(110, 0); - } else { - Turret_BeginRetarget(); - } -} - bool Actor::Turret_IsRetargeting(void) const { return m_State <= 120; @@ -406,20 +164,73 @@ bool Actor::Turret_CheckRetarget(void) return true; } -bool Actor::Turret_TryToBecomeCoverGuy(void) +void Actor::Begin_Turret(void) { - PathNode *pOldCover = m_pCoverNode; - Cover_FindCover(true); - if (m_pCoverNode) { - TransitionState(111, 0); - SetThink(THINKSTATE_ATTACK, THINK_COVER); - return true; + DoForceActivate(); + m_csMood = STRING_ALERT; + + ClearPath(); + + if (m_Enemy) { + TransitionState(110, 0); } else { - if (pOldCover) { - m_pCoverNode = pOldCover; - m_pCoverNode->Claim(this); + TransitionState(109, (rand() & 0x7FF) + 250); + } +} + +void Actor::End_Turret(void) +{ + if (m_pCoverNode && m_State != 111) { + m_pCoverNode->Relinquish(); + m_pCoverNode = NULL; + } + TransitionState(-1, 0); +} + +void Actor::Suspend_Turret(void) +{ + if (!m_Enemy) { + TransitionState(110, 0); + } else { + if (m_State <= 108) { + SetEnemyPos(m_Enemy->origin); + AimAtEnemyBehavior(); + TransitionState(113, 0); + } + } +} + +void Actor::State_Turret_Combat(void) +{ + if (CanSeeEnemy(200)) { + ClearPath(); + Anim_Attack(); + AimAtTargetPos(); + Turret_CheckRetarget(); + return; + } + if (!PathExists() || PathComplete() || !PathAvoidsSquadMates()) { + SetPathWithLeash(m_vLastEnemyPos, NULL, 0); + ShortenPathToAvoidSquadMates(); + } + if (!PathExists() || PathComplete() || !PathAvoidsSquadMates()) { + FindPathNearWithLeash(m_vLastEnemyPos, 4.0 * m_fMinDistanceSquared); + if (!ShortenPathToAttack(0.0)) { + ClearPath(); + } + ShortenPathToAvoidSquadMates(); + } + if (!PathExists() || PathComplete() || !PathAvoidsSquadMates()) { + m_pszDebugState = "combat->chill"; + Turret_BeginRetarget(); + } else { + m_pszDebugState = "combat->move"; + if (!MovePathWithLeash()) { + m_pszDebugState = "combat->move->aim"; + Turret_BeginRetarget(); + } else { + Turret_CheckRetarget(); } - return false; } } @@ -493,37 +304,139 @@ void Actor::Turret_SideStep(int iStepSize, vec3_t vDir) } } -void Actor::State_Turret_Combat(void) +void Actor::State_Turret_Shoot(void) { - if (CanSeeEnemy(200)) { - ClearPath(); - Anim_Attack(); - AimAtTargetPos(); - Turret_CheckRetarget(); - return; + // FIXME: unimplemented +} + +void Actor::State_Turret_Retarget_Suppress(void) +{ + // FIXME: unimplemented +} + +void Actor::State_Turret_Retarget_Sniper_Node(void) +{ + PathNode *pSniperNode; + bool bTryAgain; + + AimAtEnemyBehavior(); + if (m_pCoverNode) { + m_pCoverNode->Relinquish(); + m_pCoverNode = NULL; } - if (!PathExists() || PathComplete() || !PathAvoidsSquadMates()) { - SetPathWithLeash(m_vLastEnemyPos, NULL, 0); - ShortenPathToAvoidSquadMates(); - } - if (!PathExists() || PathComplete() || !PathAvoidsSquadMates()) { - FindPathNearWithLeash(m_vLastEnemyPos, 4.0 * m_fMinDistanceSquared); - if (!ShortenPathToAttack(0.0)) { - ClearPath(); - } - ShortenPathToAvoidSquadMates(); - } - if (!PathExists() || PathComplete() || !PathAvoidsSquadMates()) { - m_pszDebugState = "combat->chill"; - Turret_BeginRetarget(); + pSniperNode = FindSniperNodeAndSetPath(&bTryAgain); + if (pSniperNode) { + m_pCoverNode = pSniperNode; + pSniperNode->Claim(this); + TransitionState(102, 0); + + State_Turret_TakeSniperNode(); + } else if (bTryAgain) { + ContinueAnimation(); } else { - m_pszDebugState = "combat->move"; - if (!MovePathWithLeash()) { - m_pszDebugState = "combat->move->aim"; - Turret_BeginRetarget(); - } else { - Turret_CheckRetarget(); - } + Turret_NextRetarget(); + } +} + +void Actor::State_Turret_Retarget_Step_Side_Small(void) +{ + int iRand; // esi + + iRand = (rand() & 64) - 32; + AimAtEnemyBehavior(); + StrafeToAttack(iRand, orientation[1]); + if ((PathExists() && !PathComplete() && PathAvoidsSquadMates()) + || ((Actor::StrafeToAttack(-iRand, orientation[1]), PathExists()) && !PathComplete() && PathAvoidsSquadMates() + )) { + TransitionState(101, 0); + } else { + Turret_NextRetarget(); + } +} + +void Actor::State_Turret_Retarget_Path_Exact(void) +{ + AimAtEnemyBehavior(); + SetPathWithLeash(m_vLastEnemyPos, NULL, 0); + if (ShortenPathToAttack(128) && (ShortenPathToAvoidSquadMates(), PathExists())) { + TransitionState(101, 0); + } else { + Turret_NextRetarget(); + } +} + +void Actor::State_Turret_Retarget_Path_Near(void) +{ + AimAtEnemyBehavior(); + FindPathNearWithLeash(m_vLastEnemyPos, m_fMinDistanceSquared); + if (ShortenPathToAttack(128)) { + TransitionState(101, 0); + } else { + Turret_NextRetarget(); + } +} + +void Actor::State_Turret_Retarget_Step_Side_Medium(void) +{ + int iRand; // esi + + iRand = (rand() & 256) - 128; + AimAtEnemyBehavior(); + StrafeToAttack(iRand, orientation[1]); + if ((PathExists() && !PathComplete() && PathAvoidsSquadMates()) + || ((Actor::StrafeToAttack(-iRand, orientation[1]), PathExists()) && !PathComplete() && PathAvoidsSquadMates() + )) { + TransitionState(101, 0); + } else { + Turret_NextRetarget(); + } +} + +void Actor::State_Turret_Retarget_Step_Side_Large(void) +{ + int iRand; // esi + + iRand = (rand() & 512) - 256; + AimAtEnemyBehavior(); + StrafeToAttack(iRand, orientation[1]); + if ((PathExists() && !PathComplete() && PathAvoidsSquadMates()) + || ((Actor::StrafeToAttack(-iRand, orientation[1]), PathExists()) && !PathComplete() && PathAvoidsSquadMates() + )) { + TransitionState(101, 0); + } else { + Turret_NextRetarget(); + } +} + +void Actor::State_Turret_Retarget_Step_Face_Medium(void) +{ + int iRand; // esi + + iRand = (rand() & 256) - 128; + AimAtEnemyBehavior(); + StrafeToAttack(iRand, orientation[0]); + if ((PathExists() && !PathComplete() && PathAvoidsSquadMates()) + || ((Actor::StrafeToAttack(-iRand, orientation[0]), PathExists()) && !PathComplete() && PathAvoidsSquadMates() + )) { + TransitionState(101, 0); + } else { + Turret_NextRetarget(); + } +} + +void Actor::State_Turret_Retarget_Step_Face_Large(void) +{ + int iRand; // esi + + iRand = (rand() & 512) - 256; + AimAtEnemyBehavior(); + StrafeToAttack(iRand, orientation[0]); + if ((PathExists() && !PathComplete() && PathAvoidsSquadMates()) + || ((Actor::StrafeToAttack(-iRand, orientation[0]), PathExists()) && !PathComplete() && PathAvoidsSquadMates() + )) { + TransitionState(101, 0); + } else { + Turret_NextRetarget(); } } @@ -726,138 +639,225 @@ void Actor::State_Turret_Wait(void) } } -void Actor::State_Turret_Retarget_Shoot(void) +void Actor::Think_Turret(void) { - // FIXME: unimplemented + if (RequireThink()) { + UpdateEyeOrigin(); + NoPoint(); + UpdateEnemy(200); + + if (m_Enemy && m_State == 110) { + if (!m_bTurretNoInitialCover && Turret_TryToBecomeCoverGuy()) { + m_pszDebugState = "CoverInstead"; + CheckUnregister(); + UpdateAngles(); + DoMove(); + UpdateBoneControllers(); + UpdateFootsteps(); + return; + } + + m_bTurretNoInitialCover = false; + + Turret_SelectState(); + + if (m_State == 100 && !CanSeeEnemy(0)) { + Turret_BeginRetarget(); + } + + SetLeashHome(origin); + + if (level.inttime < m_iEnemyChangeTime + 200) { + if (AttackEntryAnimation()) { + m_bLockThinkState = true; + TransitionState(108, 0); + } + } + } + + if (level.inttime > m_iStateTime + 3000) { + Turret_SelectState(); + } + + if (m_State == 108) { + m_pszDebugState = "IntroAnim"; + AimAtTargetPos(); + ContinueAnimation(); + } else { + m_bLockThinkState = false; + if (!m_Enemy && m_State != 109 && m_State != 104) { + TransitionState(109, ((rand() + 250) & 0x7FF)); + } + if (!m_Enemy) { + if (m_State != 109) { + if (m_State != 104 || (origin - m_vHome).lengthXYSquared() <= 0.64f * m_fLeashSquared + 64.0f + || !State_Turret_RunHome(false)) { + m_pszDebugState = "Idle"; + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); + IdleThink(); + } else { + m_pszDebugState = "Idle->RunHome"; + PostThink(true); + } + return; + } + } + if (m_Enemy && m_State == 109) { + Turret_BeginRetarget(); + } + + if (Turret_DecideToSelectState()) { + Turret_SelectState(); + } + + switch (m_State) { + case 100: + m_pszDebugState = "Combat"; + State_Turret_Combat(); + break; + case 101: + m_pszDebugState = "Reacquire"; + State_Turret_Reacquire(); + break; + case 102: + m_pszDebugState = "TakeSniperNode"; + if (!PathExists() || PathComplete()) { + AimAtEnemyBehavior(); + TransitionState(103, 0); + } else { + FaceMotion(); + Anim_RunToDanger(3); + } + break; + case 103: + m_pszDebugState = "SniperNode"; + State_Turret_SniperNode(); + break; + case 104: + m_pszDebugState = "RunHome"; + State_Turret_RunHome(true); + break; + case 105: + m_pszDebugState = "RunAway"; + State_Turret_RunAway(); + break; + case 106: + m_pszDebugState = "Charge"; + State_Turret_Charge(); + break; + case 107: + m_pszDebugState = "Grenade"; + State_Turret_Grenade(); + break; + case 109: + m_pszDebugState = "FakeEnemy"; + State_Turret_FakeEnemy(); + break; + case 111: + m_pszDebugState = "BecomeCover"; + ContinueAnimation(); + break; + case 112: + m_pszDebugState = "Wait"; + State_Turret_Wait(); + break; + case 113: + m_pszDebugState = "Retarget_Sniper_Node"; + State_Turret_Retarget_Sniper_Node(); + break; + case 114: + m_pszDebugState = "Retarget_Step_Side_Small"; + State_Turret_Retarget_Step_Side_Small(); + break; + case 115: + m_pszDebugState = "Retarget_Path_Exact"; + State_Turret_Retarget_Path_Exact(); + break; + case 116: + m_pszDebugState = "Retarget_Path_Near"; + State_Turret_Retarget_Path_Near(); + break; + case 117: + m_pszDebugState = "Retarget_Step_Side_Medium"; + State_Turret_Retarget_Step_Side_Medium(); + break; + case 118: + m_pszDebugState = "Retarget_Step_Side_Large"; + State_Turret_Retarget_Step_Side_Large(); + break; + case 119: + m_pszDebugState = "Retarget_Step_Face_Medium"; + State_Turret_Retarget_Step_Face_Medium(); + break; + case 120: + m_pszDebugState = "Retarget_Step_Face_Large"; + State_Turret_Retarget_Step_Face_Large(); + break; + default: + Com_Printf("Actor::Think_Turret: invalid think state %i\n", m_State); + assert(!"invalid think state"); + break; + } + CheckForTransition(THINKSTATE_GRENADE, THINKLEVEL_NORMAL); + } + if (m_State == 112) { + PostThink(false); + } else { + PostThink(true); + } + } } -void Actor::State_Turret_Retarget_Suppress(void) +void Actor::ReceiveAIEvent_Turret( + vec3_t event_origin, int iType, Entity *originator, float fDistSquared, float fMaxDistSquared +) { - // FIXME: unimplemented + if (iType == AI_EVENT_WEAPON_IMPACT) { + if (m_Enemy && fDistSquared <= Square(128)) { + Turret_TryToBecomeCoverGuy(); + } + } else { + DefaultReceiveAIEvent(origin, iType, originator, fDistSquared, fMaxDistSquared); + } } -void Actor::State_Turret_Retarget_Sniper_Node(void) +bool Actor::Turret_TryToBecomeCoverGuy(void) { - PathNode *pSniperNode; - bool bTryAgain; - - AimAtEnemyBehavior(); + PathNode *pOldCover = m_pCoverNode; + Cover_FindCover(true); if (m_pCoverNode) { - m_pCoverNode->Relinquish(); - m_pCoverNode = NULL; - } - pSniperNode = FindSniperNodeAndSetPath(&bTryAgain); - if (pSniperNode) { - m_pCoverNode = pSniperNode; - pSniperNode->Claim(this); - TransitionState(102, 0); - - State_Turret_TakeSniperNode(); - } else if (bTryAgain) { - ContinueAnimation(); + TransitionState(111, 0); + SetThink(THINKSTATE_ATTACK, THINK_COVER); + return true; } else { - Turret_NextRetarget(); + if (pOldCover) { + m_pCoverNode = pOldCover; + m_pCoverNode->Claim(this); + } + return false; } } -void Actor::State_Turret_Retarget_Path_Exact(void) +void Actor::FinishedAnimation_Turret(void) { - AimAtEnemyBehavior(); - SetPathWithLeash(m_vLastEnemyPos, NULL, 0); - if (ShortenPathToAttack(128) && (ShortenPathToAvoidSquadMates(), PathExists())) { - TransitionState(101, 0); - } else { - Turret_NextRetarget(); + if (m_State <= 108) { + Turret_SelectState(); } } -void Actor::State_Turret_Retarget_Path_Near(void) +void Actor::InterruptPoint_Turret(void) { - AimAtEnemyBehavior(); - FindPathNearWithLeash(m_vLastEnemyPos, m_fMinDistanceSquared); - if (ShortenPathToAttack(128)) { - TransitionState(101, 0); - } else { - Turret_NextRetarget(); + if (m_Enemy && !Turret_TryToBecomeCoverGuy() && m_State == 100) { + m_iStateTime = level.inttime; + Turret_SelectState(); } } -void Actor::State_Turret_Retarget_Step_Side_Small(void) +void Actor::PathnodeClaimRevoked_Turret(void) { - int iRand; // esi - - iRand = (rand() & 64) - 32; - AimAtEnemyBehavior(); - StrafeToAttack(iRand, orientation[1]); - if ((PathExists() && !PathComplete() && PathAvoidsSquadMates()) - || ((Actor::StrafeToAttack(-iRand, orientation[1]), PathExists()) && !PathComplete() && PathAvoidsSquadMates() - )) { - TransitionState(101, 0); + if (m_Enemy == NULL) { + TransitionState(110, 0); } else { - Turret_NextRetarget(); - } -} - -void Actor::State_Turret_Retarget_Step_Side_Medium(void) -{ - int iRand; // esi - - iRand = (rand() & 256) - 128; - AimAtEnemyBehavior(); - StrafeToAttack(iRand, orientation[1]); - if ((PathExists() && !PathComplete() && PathAvoidsSquadMates()) - || ((Actor::StrafeToAttack(-iRand, orientation[1]), PathExists()) && !PathComplete() && PathAvoidsSquadMates() - )) { - TransitionState(101, 0); - } else { - Turret_NextRetarget(); - } -} - -void Actor::State_Turret_Retarget_Step_Side_Large(void) -{ - int iRand; // esi - - iRand = (rand() & 512) - 256; - AimAtEnemyBehavior(); - StrafeToAttack(iRand, orientation[1]); - if ((PathExists() && !PathComplete() && PathAvoidsSquadMates()) - || ((Actor::StrafeToAttack(-iRand, orientation[1]), PathExists()) && !PathComplete() && PathAvoidsSquadMates() - )) { - TransitionState(101, 0); - } else { - Turret_NextRetarget(); - } -} - -void Actor::State_Turret_Retarget_Step_Face_Medium(void) -{ - int iRand; // esi - - iRand = (rand() & 256) - 128; - AimAtEnemyBehavior(); - StrafeToAttack(iRand, orientation[0]); - if ((PathExists() && !PathComplete() && PathAvoidsSquadMates()) - || ((Actor::StrafeToAttack(-iRand, orientation[0]), PathExists()) && !PathComplete() && PathAvoidsSquadMates() - )) { - TransitionState(101, 0); - } else { - Turret_NextRetarget(); - } -} - -void Actor::State_Turret_Retarget_Step_Face_Large(void) -{ - int iRand; // esi - - iRand = (rand() & 512) - 256; - AimAtEnemyBehavior(); - StrafeToAttack(iRand, orientation[0]); - if ((PathExists() && !PathComplete() && PathAvoidsSquadMates()) - || ((Actor::StrafeToAttack(-iRand, orientation[0]), PathExists()) && !PathComplete() && PathAvoidsSquadMates() - )) { - TransitionState(101, 0); - } else { - Turret_NextRetarget(); + Turret_BeginRetarget(); } } diff --git a/code/fgame/actor_weaponless.cpp b/code/fgame/actor_weaponless.cpp index aef783e2..6b8c2016 100644 --- a/code/fgame/actor_weaponless.cpp +++ b/code/fgame/actor_weaponless.cpp @@ -59,6 +59,40 @@ void Actor::Suspend_Weaponless(void) } } +void Actor::State_Weaponless_Normal(void) +{ + int iStateTime; + if (m_bScriptGoalValid) { + SetPath(m_vScriptGoal, NULL, 0, NULL, 0); + } + if (PathExists() && !PathComplete()) { + FaceMotion(); + Anim_RunToDanger(3); + } else { + m_bScriptGoalValid = false; + + AimAtTargetPos(); + + Anim_Stand(); + if (level.inttime >= m_iStateTime) { + if (DecideToThrowGrenade(m_Enemy->velocity + m_Enemy->origin, &m_vGrenadeVel, &m_eGrenadeMode)) { + SetDesiredYawDir(m_vGrenadeVel); + + m_State = 901; + m_eNextAnimMode = 1; + m_bNextForceStart = false; + m_csNextAnimString = + (m_eGrenadeMode == AI_GREN_TOSS_ROLL) ? STRING_ANIM_GRENADETOSS_SCR : STRING_ANIM_GRENADETHROW_SCR; + iStateTime = level.inttime; + } else { + m_State = 900; + iStateTime = level.inttime + 1000; + } + m_iStateTime = iStateTime; + } + } +} + void Actor::Think_Weaponless(void) { if (RequireThink()) { @@ -102,40 +136,6 @@ void Actor::FinishedAnimation_Weaponless(void) } } -void Actor::State_Weaponless_Normal(void) -{ - int iStateTime; - if (m_bScriptGoalValid) { - SetPath(m_vScriptGoal, NULL, 0, NULL, 0); - } - if (PathExists() && !PathComplete()) { - FaceMotion(); - Anim_RunToDanger(3); - } else { - m_bScriptGoalValid = false; - - AimAtTargetPos(); - - Anim_Stand(); - if (level.inttime >= m_iStateTime) { - if (DecideToThrowGrenade(m_Enemy->velocity + m_Enemy->origin, &m_vGrenadeVel, &m_eGrenadeMode)) { - SetDesiredYawDir(m_vGrenadeVel); - - m_State = 901; - m_eNextAnimMode = 1; - m_bNextForceStart = false; - m_csNextAnimString = - (m_eGrenadeMode == AI_GREN_TOSS_ROLL) ? STRING_ANIM_GRENADETOSS_SCR : STRING_ANIM_GRENADETHROW_SCR; - iStateTime = level.inttime; - } else { - m_State = 900; - iStateTime = level.inttime + 1000; - } - m_iStateTime = iStateTime; - } - } -} - void Actor::State_Weaponless_Grenade(void) { GenericGrenadeTossThink();