Moved location of actor methods

This commit is contained in:
smallmodel 2023-10-12 20:17:09 +02:00
parent 3dbf957304
commit c55a78b8b4
No known key found for this signature in database
GPG key ID: 9F2D623CEDF08512
12 changed files with 670 additions and 678 deletions

View file

@ -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

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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();
}

View file

@ -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;
}
}

View file

@ -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();
@ -74,3 +64,13 @@ void Actor::IdleThink(void)
PostThink(true);
}
void Actor::Think_Idle(void)
{
if (RequireThink()) {
UpdateEyeOrigin();
m_pszDebugState = "";
CheckForThinkStateTransition();
IdleThink();
}
}

View file

@ -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) {

View file

@ -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

View file

@ -49,7 +49,6 @@ void Actor::End_Patrol(void)
void Actor::Resume_Patrol(void)
{
;
}
void Actor::Think_Patrol(void)

View file

@ -50,7 +50,6 @@ void Actor::End_Runner(void)
void Actor::Resume_Runner(void)
{
;
}
void Actor::Think_Runner(void)

View file

@ -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();
}
}

View file

@ -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();