Reversing Actor Final Part

This commit is contained in:
mohabhassan 2018-09-05 16:55:10 +02:00
parent cb239c3c7f
commit 6528ba4dac
40 changed files with 3983 additions and 779 deletions

File diff suppressed because it is too large Load diff

View file

@ -62,9 +62,9 @@ extern Event EV_Actor_DeathEmbalm;
// Bones used by actor
#define ACTOR_MOUTH_TAG 0
#define ACTOR_HEAD_TAG 1
#define ACTOR_TORSO_TAG 2
//#define ACTOR_MOUTH_TAG 0
#define ACTOR_HEAD_TAG 0
#define ACTOR_TORSO_TAG 1
// Dialog stuff
@ -90,25 +90,25 @@ typedef struct
} DialogParm_t;
typedef struct DialogNode_s
{
char alias_name[ MAX_ALIAS_NAME_LENGTH ];
{
char alias_name[MAX_ALIAS_NAME_LENGTH];
int random_flag;
int number_of_parms;
float random_percent;
DialogParm_t parms[ MAX_DIALOG_PARMS ];
struct DialogNode_s *next;
} DialogNode_t;
DialogParm_t parms[MAX_DIALOG_PARMS];
struct DialogNode_s *next;
} DialogNode_t;
typedef enum
{
IS_INANIMATE,
{
IS_INANIMATE,
IS_MONSTER,
IS_ENEMY,
IS_CIVILIAN,
IS_FRIEND,
IS_ANIMAL,
IS_ANIMAL,
NUM_ACTORTYPES
} actortype_t;
} actortype_t;
// Stimuli types
@ -236,6 +236,20 @@ typedef enum
AI_GREN_KICK
} eGrenadeTossMode;
typedef enum
{
AI_GRENSTATE_FLEE,
AI_GRENSTATE_THROW_ACQUIRE,
AI_GRENSTATE_THROW,
AI_GRENSTATE_KICK_ACQUIRE,
AI_GRENSTATE_KICK,
AI_GRENSTATE_MARTYR_ACQUIRE,
AI_GRENSTATE_MARTYR,
AI_GRENSTATE_UNK,
AI_GRENSTATE_FLEE_SUCCESS, //fled the grenade succesfully, i'm safe
AI_GRENSTATE_FLEE_FAIL, //failed to flee, I'm gonna get hurt or die :'(
} eGrenadeState;
typedef struct {
byte length;
byte currentPos;
@ -244,7 +258,7 @@ typedef struct {
vec3_t pos[ 1 ];
} FallPath;
#define THINKSTATE_NONE 0
#define THINKSTATE_VOID 0
#define THINKSTATE_IDLE 1
#define THINKSTATE_PAIN 2
#define THINKSTATE_KILLED 3
@ -267,6 +281,53 @@ typedef struct {
#define AI_EVENT_FOOTSTEP 10
#define AI_EVENT_GRENADE 11
enum thinkNums
{
THINK_VOID,
THINK_TURRET,
THINK_COVER,
THINK_PATROL,
THINK_RUNNER,
THINK_PAIN,
THINK_KILLED,
THINK_MOVETO,
THINK_IDLE,
THINK_CURIOUS,
THINK_DISGUISE_SALUTE,
THINK_DISGUISE_SENTRY,
THINK_DISGUISE_OFFICER,
THINK_DISGUISE_ROVER,
THINK_DISGUISE_NONE,
THINK_ALARM,
THINK_GRENADE,
THINK_MACHINEGUNNER,
THINK_DOG_IDLE,
THINK_DOG_ATTACK,
THINK_DOG_CURIOUS,
THINK_DOG_GRENADE,
THINK_ANIM,
THINK_ANIM_CURIOUS,
THINK_AIM,
THINK_BALCONY_IDLE,
THINK_BALCONY_CURIOUS,
THINK_BALCONY_ATTACK,
THINK_BALCONY_DISGUISE,
THINK_BALCONY_GRENADE,
THINK_BALCONY_PAIN,
THINK_BALCONY_KILLED,
THINK_WEAPONLESS,
THINK_NOCLIP,
THINK_DEAD
};
enum thinkLevelNums
{
THINKLEVEL_NORMAL,
THINKLEVEL_PAIN,
THINKLEVEL_KILLED,
THINKLEVEL_NOCLIP
};
class Actor;
typedef SafePtr<Actor> ActorPtr;
@ -392,7 +453,7 @@ public:
SafePtr<Entity> m_pGrenade;
Vector m_vGrenadePos;
int m_iFirstGrenadeTime;
int m_eGrenadeState;
eGrenadeState m_eGrenadeState;
eGrenadeTossMode m_eGrenadeMode;
Vector m_vGrenadeVel;
Vector m_vKickDir;
@ -467,7 +528,7 @@ protected:
public:
Actor();
virtual void setContentsSolid( void );
virtual void setContentsSolid( void ) override;
void InitThinkStates( void );
void UpdateEyeOrigin( void );
bool RequireThink( void );
@ -479,7 +540,7 @@ public:
void AddToBodyQue( void );
Vector GetAntiBunchPoint( void );
static void InitVoid( GlobalFuncs_t *func );
virtual const char *DumpCallTrace( const char *pszFmt, ... ) const;
virtual const char *DumpCallTrace( const char *pszFmt, ... ) const override;
static void Init( void );
void FixAIParameters( void );
bool AttackEntryAnimation( void );
@ -595,7 +656,7 @@ public:
void Grenade_EventFire( Event *ev );
void GenericGrenadeTossThink( void );
static void InitGrenade( GlobalFuncs_t *func );
bool Grenade_Acquire( int eNextState, const_str csReturnAnim );
bool Grenade_Acquire( eGrenadeState eNextState, const_str csReturnAnim );
void Grenade_Flee( void );
void Grenade_ThrowAcquire( void );
void Grenade_Throw( void );
@ -1202,7 +1263,7 @@ inline void Actor::Archive
arc.ArchiveSafePointer( &m_pGrenade);
arc.ArchiveVector( &m_vGrenadePos);
arc.ArchiveInteger( &m_iFirstGrenadeTime);
arc.ArchiveInteger( &m_eGrenadeState);
ArchiveEnum( m_eGrenadeState, eGrenadeState );
ArchiveEnum( m_eGrenadeMode, eGrenadeTossMode );
arc.ArchiveVector( &m_vGrenadeVel);
arc.ArchiveVector( &m_vKickDir);

View file

@ -135,7 +135,7 @@ void Actor::State_Alarm_Idle
{
AimAtAimNode();
SetThink( 4, THINKSTATE_IDLE );
SetThink(THINKSTATE_ATTACK, THINK_TURRET);
}
void Actor::Think_Alarm

View file

@ -96,7 +96,7 @@ void Actor::FinishedAnimation_Anim
if (m_bNoIdleAfterAnim)
m_csAnimScript = STRING_ANIM_CONTINUE_LAST_ANIM_SCR;
else
SetThinkIdle(8);
SetThinkIdle(THINK_IDLE);
Unregister(STRING_ANIMDONE);
}
}

View file

@ -55,7 +55,7 @@ void SimpleActor::Anim_Attack
{
m_eNextAnimMode = 1;
m_csNextAnimString = 0;
m_csNextAnimString = NULL;
m_NextAnimLabel = m_AttackHandler;
m_bNextForceStart = false;
}
@ -350,11 +350,11 @@ void SimpleActor::Anim_RunToInOpen
void SimpleActor::Anim_Emotion
(
int eEmotionMode
eEmotionMode eEmotMode
)
{
m_eEmotionMode = eEmotionMode;
m_eEmotionMode = eEmotMode;
}
void SimpleActor::Anim_Say

View file

@ -122,7 +122,7 @@ void Actor::Pain_Balcony
)
{
SetThink( THINKSTATE_PAIN, 30 );
SetThink( THINKSTATE_PAIN, THINK_BALCONY_PAIN);
HandlePain( ev );
}
@ -134,7 +134,7 @@ void Actor::Killed_Balcony
{
ClearStates();
SetThink( THINKSTATE_KILLED, 31 );
SetThink( THINKSTATE_KILLED, THINK_BALCONY_KILLED);
HandleKilled( ev, true );
if( !bPlayDeathAnim )
@ -229,7 +229,7 @@ void Actor::Think_BalconyAttack
if( !m_Enemy )
{
SetThinkState( THINKSTATE_IDLE, 0 );
SetThinkState( THINKSTATE_IDLE, THINKLEVEL_NORMAL);
IdleThink();
return;
}
@ -246,7 +246,7 @@ void Actor::Think_BalconyAttack
m_pszDebugState = "shoot";
State_Balcony_Shoot();
}
else if( m_State = 200 )
else if( m_State == 200 )
{
m_pszDebugState = "findenemy";
State_Balcony_FindEnemy();
@ -266,7 +266,7 @@ void Actor::FinishedAnimation_BalconyAttack
)
{
if( m_State = 202 )
if( m_State == 202 )
State_Balcony_PostShoot();
}
@ -312,7 +312,7 @@ void Actor::Think_BalconyKilled
Unregister( STRING_ANIMDONE );
if( m_State = 805 )
if( m_State == 805 )
{
m_pszDebugState = "end";
}
@ -328,7 +328,7 @@ void Actor::Think_BalconyKilled
m_bNextForceStart = true;
m_eNextAnimMode = 7;
m_pszDebugState = "begin";
m_csNextAnimString = 270;
m_csNextAnimString = STRING_ANIM_NO_KILLED_SCR;
ChangeMotionAnim();
animnum = gi.Anim_NumForName( edict->tiki, "death_balcony_intro" );
NewAnim( animnum );
@ -354,6 +354,7 @@ void Actor::Think_BalconyKilled
case 804:
m_pszDebugState = "outtro";
Anim_FullBody( STRING_DEATH_BALCONY_OUTTRO, 1 );
break;
case 806:
m_pszDebugState = "normal";
Anim_Killed();
@ -367,25 +368,22 @@ void Actor::Think_BalconyKilled
if( m_State >= 800 )
{
if( m_State <= 801 )
if( m_State == 801 )
{
if( m_pFallPath->currentPos >= m_pFallPath->length )
{
m_State = 803;
m_iStateTime = level.inttime;
return;
}
if( m_pFallPath->currentPos >= m_pFallPath->loop )
else if (m_pFallPath->currentPos >= m_pFallPath->loop)
{
m_State = 802;
m_iStateTime = level.inttime;
return;
}
}
else
else if( m_State == 802 )
{
if( m_State == 802 && m_pFallPath->currentPos >= m_pFallPath->length )
if (m_pFallPath->currentPos >= m_pFallPath->length)
{
m_State = 803;
m_iStateTime = level.inttime;

View file

@ -161,7 +161,7 @@ void Actor::State_Cover_FindCover
{
if( !m_iPotentialCoverCount )
{
SetThink( THINKSTATE_ATTACK, 1 );
SetThink( THINKSTATE_ATTACK, THINK_TURRET );
}
}
}
@ -490,7 +490,7 @@ void Actor::State_Cover_Shoot
if( level.inttime > m_iStateTime + 10000 )
{
gi.Cvar_Set( "g_monitornum", va( "%i", entnum ) );
assert( "!anim/shoot.scr took over 10 seconds" );
assert( !"anim/shoot.scr took over 10 seconds" );
Com_Error( ERR_DROP, "anim/shoot.scr took over 10 seconds, entnum = %i, targetname = %s", entnum, targetname.c_str() );
}
}
@ -577,7 +577,7 @@ __setpath:
else
{
m_bTurretNoInitialCover = true;
SetThink( THINKSTATE_ATTACK, 1 );
SetThink( THINKSTATE_ATTACK, THINK_TURRET );
}
return;
@ -679,7 +679,7 @@ void Actor::State_Cover_FakeEnemy
if( level.inttime >= m_iStateTime )
{
SetThinkState( THINKSTATE_IDLE, 0 );
SetThinkState( THINKSTATE_IDLE, THINKLEVEL_NORMAL);
}
}

View file

@ -51,7 +51,7 @@ void Actor::Begin_Curious
DoForceActivate();
m_csMood = STRING_CURIOUS;
Anim_Emotion(10);
Anim_Emotion(EMOTION_CURIOUS);
if (level.inttime > level.m_iCuriousVoiceTime + 3000)
{
@ -76,7 +76,7 @@ void Actor::Begin_Curious
if (m_bScriptGoalValid)
{
SetPath(
this->m_vScriptGoal,
m_vScriptGoal,
"",
0,
NULL,
@ -92,19 +92,30 @@ void Actor::Begin_Curious
if (!m_bScriptGoalValid)
{
//check if last enemy pos is within leash area (distance to m_vHome is <= m_fLeash)
vDelta = m_vLastEnemyPos - m_vHome;
if (vDelta.lengthSquared() <= m_fLeashSquared)
{
//it's within leash area, go check it.
SetPath(m_vLastEnemyPos, "", 0, NULL, 0.0);
}
else
{
//it's NOT within leash area,
//am I within leash area ?
if ((origin - m_vHome).lengthSquared() <= m_fLeashSquared)
{
//I'm inside leash area,
//Try to go towards enemy as much as possible without leaving leash area.
//vDest = vHome + U * leash
//U = unit vector of vDelta.
SetPath(vDelta * sqrt(m_fLeashSquared / vDelta.lengthSquared()) + m_vHome, "", 0, NULL, 0.0);
}
else
{
//I'm outside leash area,
//go to enemy, it doesn't matter.
SetPath(m_vLastEnemyPos, "", 0, NULL, 0.0);
}
}
@ -121,8 +132,7 @@ void Actor::Begin_Curious
VectorSub2D(m_vLastEnemyPos, origin, vDel);
if (vDel[0] != 0 || vDel[1] != 0)
{
m_YawAchieved = false;
m_DesiredYaw = vectoyaw(vDel);
SetDesiredYawDir(vDel);
}
m_eNextAnimMode = 1;
m_csNextAnimString = STRING_ANIM_SURPRISE_SCR;
@ -171,8 +181,231 @@ void Actor::Think_Curious
)
{
// FIXME: stub
STUB();
//horrible function!
if (RequireThink())
{
UpdateEyeOrigin();
NoPoint();
UpdateEnemy(100);
if(m_State == 1101)
{
ContinueAnimation();
//LABEL_16:
CheckForThinkStateTransition();
PostThink(true);
return;
}
m_bLockThinkState = false;
if (!PathExists() || PathComplete())
{
//v1 = &this->baseSimpleActor.baseSentient.m_Enemy;
//goto LABEL_6;
ClearPath();
Anim_Stand();
LookAtCuriosity();
if (!m_Enemy || EnemyIsDisguised())
{
if (level.inttime > m_iCuriousTime + 500)
{
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
m_iCuriousTime = 0;
}
}
CheckForThinkStateTransition();
PostThink(true);
return;
}
if (m_Enemy || CanSeeEnemy(100))
{
ClearPath();
Anim_Stand();
LookAtCuriosity();
if (!m_Enemy || EnemyIsDisguised())
{
if (level.inttime > m_iCuriousTime + 500)
{
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
m_iCuriousTime = 0;
}
}
CheckForThinkStateTransition();
PostThink(true);
return;
}
else
{
if (m_iCuriousLevel <= 5)
{
if (!InFOV(m_vLastEnemyPos, m_fFov, m_fFovDot))
{
if ((m_bScriptGoalValid || CanMovePathWithLeash())
&& MoveOnPathWithSquad())
{
if (PatrolNextNodeExists())
{
m_eNextAnimMode = 2;
}
else
{
//v11 = SimpleActor::GetRunAnim(this);
m_eNextAnimMode = 3;
}
m_csNextAnimString = GetRunAnim();
m_bNextForceStart = false;
FaceMotion();
}
else
{
Anim_Stand();
}
if (level.inttime >= m_iNextWatchStepTime
&& velocity.lengthSquared() >= 4.0)
{
SetDesiredLookDir(velocity);
m_iNextWatchStepTime = level.inttime + (rand() & 0x1FF) + 500;
}
else
{
LookAtCuriosity();
}
CheckForThinkStateTransition();
PostThink(true);
return;
}
else
{
Vector vEnd = EyePosition() - m_vLastEnemyPos;
VectorNormalizeFast(vEnd);
vEnd += m_vLastEnemyPos;
if (!G_SightTrace(EyePosition(), vec_zero, vec_zero, vEnd, this, NULL, 33819417, qfalse, "Actor::Think_Curious"))
{
if ((m_bScriptGoalValid || CanMovePathWithLeash())
&& MoveOnPathWithSquad())
{
if (PatrolNextNodeExists())
{
m_eNextAnimMode = 2;
}
else
{
//v11 = SimpleActor::GetRunAnim(this);
m_eNextAnimMode = 3;
}
m_csNextAnimString = GetRunAnim();
m_bNextForceStart = false;
FaceMotion();
}
else
{
Anim_Stand();
}
if (level.inttime >= m_iNextWatchStepTime
&& velocity.lengthSquared() >= 4.0)
{
SetDesiredLookDir(velocity);
m_iNextWatchStepTime = level.inttime + (rand() & 0x1FF) + 500;
}
else
{
LookAtCuriosity();
}
CheckForThinkStateTransition();
PostThink(true);
return;
}
else
{
ClearPath();
Anim_Stand();
LookAtCuriosity();
if (!m_Enemy || EnemyIsDisguised())
{
if (level.inttime > m_iCuriousTime + 500)
{
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
m_iCuriousTime = 0;
}
}
CheckForThinkStateTransition();
PostThink(true);
return;
}
}
}
else
{
if ((PathGoal()-origin).lengthSquared() >= 2304)
{
if ((m_bScriptGoalValid || CanMovePathWithLeash())
&& MoveOnPathWithSquad())
{
if (PatrolNextNodeExists())
{
m_eNextAnimMode = 2;
}
else
{
//v11 = SimpleActor::GetRunAnim(this);
m_eNextAnimMode = 3;
}
m_csNextAnimString = GetRunAnim();
m_bNextForceStart = false;
FaceMotion();
}
else
{
Anim_Stand();
}
if (level.inttime >= m_iNextWatchStepTime
&& velocity.lengthSquared() >= 4.0)
{
SetDesiredLookDir(velocity);
m_iNextWatchStepTime = level.inttime + (rand() & 0x1FF) + 500;
}
else
{
LookAtCuriosity();
}
CheckForThinkStateTransition();
PostThink(true);
return;
}
}
ClearPath();
Anim_Stand();
LookAtCuriosity();
if (!m_Enemy || EnemyIsDisguised())
{
if (level.inttime > m_iCuriousTime + 500)
{
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
m_iCuriousTime = 0;
}
}
CheckForThinkStateTransition();
PostThink(true);
return;
}
}
}
void Actor::FinishedAnimation_Curious
@ -254,7 +487,7 @@ void Actor::TimeOutCurious
{
if (level.inttime > m_iCuriousTime + 500)
{
SetThinkState(1, 0);
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
m_iCuriousTime = 0;
}
}

View file

@ -66,7 +66,7 @@ void Actor::State_Disguise_Wait
}
else
{
SetThinkState(1, 0);
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
}
}
}
@ -85,7 +85,7 @@ void Actor::State_Disguise_Papers
m_bNextForceStart = false;
if (m_iEnemyShowPapersTime < m_Enemy->m_ShowPapersTime)
{
if (level.m_iPapersLevel < this->m_iDisguiseLevel)
if (level.m_iPapersLevel < m_iDisguiseLevel)
{
m_State = 5;
}
@ -158,7 +158,7 @@ void Actor::State_Disguise_Enemy
if (level.inttime > m_iStateTime + 3000 && !m_Enemy->IsSubclassOfActor())
{
SetThinkState(4, 0);
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
}
}
@ -174,7 +174,7 @@ void Actor::State_Disguise_Halt
if (level.inttime > m_iStateTime + 1500 && !m_Enemy->IsSubclassOfActor())
{
SetThinkState(4, 0);
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
}
}
@ -190,8 +190,8 @@ void Actor::State_Disguise_Accept
if (level.inttime > m_iStateTime + 3000 )
{
SetThinkState(1, 0);
SetThink(6, 10);
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
SetThink(THINKSTATE_DISGUISE, THINK_DISGUISE_SALUTE);
}
}
@ -207,6 +207,6 @@ void Actor::State_Disguise_Deny
if (level.inttime > m_iStateTime + 3000)
{
SetThinkState(1, 0);
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
}
}

View file

@ -91,12 +91,12 @@ void Actor::Begin_DisguiseOfficer
}
else
{
SetThinkState(4, 0);
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
}
}
else
{
SetThinkState(1, 0);
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
}
}
@ -160,7 +160,7 @@ void Actor::Think_DisguiseOfficer
if (!m_Enemy)
{
SetThinkState(1, 0);
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
return;
}
if (!EnemyIsDisguised() && !(m_Enemy->IsSubclassOfActor()) && m_State != 3)
@ -170,7 +170,7 @@ void Actor::Think_DisguiseOfficer
}
if (level.m_bAlarm)
{
SetThinkState(4, 0);
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
return;
}
vec2_t vDelta;
@ -260,7 +260,7 @@ void Actor::Think_DisguiseOfficer
State_Disguise_Fake_Papers();
}
}
CheckForTransition(7, 0);
CheckForTransition(THINKSTATE_GRENADE, 0);
PostThink(true);
}
}

View file

@ -92,12 +92,12 @@ void Actor::Begin_DisguiseRover
}
else
{
SetThinkState(4, 0);
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
}
}
else
{
SetThinkState(1, 0);
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
}
}
@ -134,6 +134,81 @@ void Actor::Think_DisguiseRover
)
{
// FIXME: stub
STUB();
if (!RequireThink())
{
return;
}
UpdateEyeOrigin();
NoPoint();
ContinueAnimation();
UpdateEnemy(1500);
assert(m_Enemy != NULL);
if (!m_Enemy)
{
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
return;
}
if (!EnemyIsDisguised() && !m_Enemy->IsSubclassOfActor() && m_State != 3)
{
m_State = 3;
m_iStateTime = level.inttime;
}
if (level.m_bAlarm)
{
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
return;
}
{
vec2_t facedir;
facedir[0] = m_Enemy->origin[0] - origin[0];
facedir[1] = m_Enemy->origin[1] - origin[1];
if (facedir[0] != 0 || facedir[1] != 0)
{
m_YawAchieved = false;
m_DesiredYaw = vectoyaw(facedir);
}
}
SetDesiredLookDir(m_Enemy->origin - origin);
if (m_State == 2)
{
m_pszDebugState = "accept";
State_Disguise_Accept();
}
else if(m_State > 2)
{
if (m_State == 3)
{
m_pszDebugState = "enemy";
State_Disguise_Enemy();
}
else if (m_State == 4)
{
m_pszDebugState = "halt";
State_Disguise_Halt();
}
else
{
assert(!"invalid think state");
}
}
else if (m_State == 1)
{
m_pszDebugState = "papers";
State_Disguise_Papers();
}
else
{
assert(!"invalid think state");
}
CheckForTransition(THINKSTATE_GRENADE, 0);
PostThink(true);
}

View file

@ -94,12 +94,12 @@ void Actor::Begin_DisguiseSalute
}
else
{
SetThinkState(4, 0);
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
}
}
else
{
SetThinkState(1, 0);
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
}
}
@ -136,8 +136,39 @@ void Actor::Think_DisguiseSalute
)
{
// FIXME: stub
STUB();
NoPoint();
ContinueAnimation();
UpdateEnemy(2000);
assert(m_Enemy != NULL);
if (m_Enemy)
{
if (!EnemyIsDisguised() && !m_Enemy->IsSubclassOfActor() && level.m_bAlarm)
{
{
vec2_t facedir;
facedir[0] = m_Enemy->origin[0] - origin[0];
facedir[1] = m_Enemy->origin[1] - origin[1];
if (facedir[0] != 0 || facedir[1] != 0)
{
SetDesiredYawDir(facedir);
}
}
SetDesiredLookDir(m_Enemy->origin - origin);
PostThink(true);
}
else
{
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
}
}
else
{
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
}
}
void Actor::FinishedAnimation_DisguiseSalute
@ -146,5 +177,5 @@ void Actor::FinishedAnimation_DisguiseSalute
)
{
SetThinkState(1, 0);
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
}

View file

@ -93,12 +93,12 @@ void Actor::Begin_DisguiseSentry
}
else
{
SetThinkState(4, 0);
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
}
}
else
{
SetThinkState(1, 0);
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
}
}
@ -135,6 +135,80 @@ void Actor::Think_DisguiseSentry
)
{
// FIXME: stub
STUB();
if (RequireThink())
{
UpdateEyeOrigin();
NoPoint();
ContinueAnimation();
UpdateEnemy(1500);
assert(m_Enemy != NULL);
if (!m_Enemy)
{
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
return;
}
if (!EnemyIsDisguised() && !m_Enemy->IsSubclassOfActor() && m_State != 3)
{
m_State = 3;
m_iStateTime = level.inttime;
}
if (level.m_bAlarm)
{
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
}
else
{
{
vec2_t facedir;
facedir[0] = m_Enemy->origin[0] - origin[0];
facedir[1] = m_Enemy->origin[1] - origin[1];
if (facedir[0] != 0 || facedir[1] != 0)
{
m_YawAchieved = false;
m_DesiredYaw = vectoyaw(facedir);
}
}
SetDesiredLookDir(m_Enemy->origin - origin);
switch (m_State)
{
case 0:
m_pszDebugState = "wait";
State_Disguise_Wait();
break;
case 1:
m_pszDebugState = "papers";
State_Disguise_Papers();
break;
case 2:
m_pszDebugState = "accept";
State_Disguise_Accept();
break;
case 3:
m_pszDebugState = "enemy";
State_Disguise_Enemy();
break;
case 4:
m_pszDebugState = "halt";
State_Disguise_Halt();
break;
case 5:
m_pszDebugState = "deny";
State_Disguise_Deny();
break;
default:
Com_Printf("Actor::Think_DisguiseSentry: invalid think state %i\n", m_State);
assert(!"invalid think state");
break;
}
CheckForTransition(THINKSTATE_GRENADE, 0);
PostThink(true);
}
}
}

View file

@ -78,6 +78,7 @@ void Actor::End_Dog
)
{
;
}
void Actor::Think_Dog_Idle
@ -106,8 +107,72 @@ void Actor::Think_Dog_Attack
)
{
// FIXME: stub
STUB();
if (!RequireThink())
{
return;
}
UpdateEyeOrigin();
m_pszDebugState = "Dog_Attack";
if (m_Enemy && !(m_Enemy->IsSubclassOfActor()))
{
SetPath(m_Enemy->origin, "", 0, NULL, 0.0);
if (PathExists())
{
vec2_t delta;
VectorSub2D(m_Enemy->origin, origin, delta);
if (VectorLength2DSquared(delta) >= 8000)
{
FaceMotion();
m_csNextAnimString = STRING_ANIM_DOG_CHASE_SCR;
m_eNextAnimMode = 2;
}
else
{
{
vec2_t facedir;
facedir[0] = m_Enemy->origin[0] - origin[0];
facedir[1] = m_Enemy->origin[1] - origin[1];
if (facedir[0] != 0 || facedir[1] != 0)
{
m_YawAchieved = false;
m_DesiredYaw = vectoyaw(facedir);
}
}
SetDesiredLookDir(m_Enemy->origin - origin);
m_eNextAnimMode = 1;
m_csNextAnimString = STRING_ANIM_DOG_ATTACK_SCR;
}
m_bNextForceStart = false;
CheckForThinkStateTransition();
PostThink(false);
return;
}
{
vec2_t facedir;
facedir[0] = m_Enemy->origin[0] - origin[0];
facedir[1] = m_Enemy->origin[1] - origin[1];
if (facedir[0] != 0 || facedir[1] != 0)
{
SetDesiredYawDir(facedir);
}
}
SetDesiredLookDir(m_Enemy->origin - origin);
}
m_bNextForceStart = false;
m_eNextAnimMode = 1;
m_csNextAnimString = STRING_ANIM_DOG_CURIOUS_SCR;
m_State = 20;
m_iStateTime = level.inttime;
CheckForThinkStateTransition();
PostThink(false);
}
void Actor::Think_Dog_Curious
@ -128,8 +193,7 @@ void Actor::Think_Dog_Curious
if (vDelta[0] != 0 || vDelta[1] != 0)
{
m_YawAchieved = false;
m_DesiredYaw = vectoyaw(vDelta);
SetDesiredYawDir(vDelta);
}
SetDesiredLookDir(m_Enemy->origin - origin);

View file

@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// actor_grenade.cpp
#include "actor.h"
#include "weaputils.h"
void Actor::InitGrenade
(
@ -42,14 +43,75 @@ void Actor::InitGrenade
bool Actor::Grenade_Acquire
(
int eNextState,
eGrenadeState eNextState,
const_str csReturnAnim
)
{
// FIXME: stub
STUB();
return false;
bool bRetVal = false;
Vector vDest;
if (m_bGrenadeBounced)
{
bRetVal = true;
vDest = origin - m_vGrenadePos;
vDest = vDest * 16 + m_vGrenadePos;
SetPath(vDest, "", 0, NULL, 0.0);
}
if (PathExists())
{
if (PathComplete())
{
m_bHasDesiredLookAngles = false;
if (m_pGrenade->velocity.lengthXY(true) >= 1024)
{
Anim_Stand();
}
else
{
m_pGrenade->velocity = vec_zero;
m_eNextAnimMode = 1;
m_eGrenadeState = eNextState;
m_bNextForceStart = false;
m_csNextAnimString = csReturnAnim;
}
}
else
{
Anim_RunToCasual(3);
vec2_t delta;
VectorSub2D(origin, m_vGrenadePos, delta);
if (VectorLength2DSquared(delta) > 1024.0)
{
FaceMotion();
}
else
{
{
vec2_t facedir;
facedir[0] = m_vGrenadePos[0] - origin[0];
facedir[1] = m_vGrenadePos[1] - origin[1];
if (facedir[0] != 0 || facedir[1] != 0)
{
m_YawAchieved = false;
m_DesiredYaw = vectoyaw(facedir);
}
}
}
}
}
else
{
m_bGrenadeBounced = true;
m_eGrenadeState = AI_GRENSTATE_FLEE;
Grenade_Flee();
bRetVal = false;
}
return bRetVal;
}
void Actor::Grenade_Flee
@ -58,8 +120,90 @@ void Actor::Grenade_Flee
)
{
// FIXME: stub
STUB();
float origin_ratio;
float fMinCloseDistSquared;
float fCosAngle;
float fSinAngle;
float fAngle;
vec2_t vDirAway;
vec2_t vDirPreferred;
if (m_bGrenadeBounced)
{
fAngle = (rand() - 0x3FFFFFFF) * -0.00000000146291807926716;
fSinAngle = sin(fAngle);
fCosAngle = cos(fAngle);
VectorSub2D(origin, m_vGrenadePos, vDirAway);
vDirPreferred[0] = vDirAway[0] * fCosAngle - fSinAngle * vDirAway[1];
vDirPreferred[1] = vDirAway[0] * fSinAngle + vDirAway[1] * fCosAngle;
FindPathAway(m_vGrenadePos, vDirPreferred, 512);
if (PathExists() && !PathComplete())
{
fMinCloseDistSquared = VectorLength2DSquared(vDirAway) * 0.63999999;
if (fMinCloseDistSquared < 1024)
fMinCloseDistSquared = 0;
vec2_t grenade_offset;
for (auto current_node = CurrentPathNode(); current_node >= LastPathNode(); current_node--)
{
VectorSub2D(m_vGrenadePos, current_node->point, grenade_offset);
if (current_node->dist > 0 && DotProduct2D(grenade_offset, current_node->dir) <= current_node->dist)
{
if (Square(CrossProduct2D(grenade_offset, current_node->dir)) < fMinCloseDistSquared)
{
ClearPath();
break;
}
}
}
}
m_bGrenadeBounced = false;
}
if (PathExists() && !PathComplete())
{
Sentient *pOwner = NULL;
if (m_pGrenade && m_pGrenade->IsSubclassOfProjectile())
pOwner = ((Projectile *)m_pGrenade.Pointer())->GetOwner();
if (pOwner && pOwner->m_Team == m_Team)
Anim_RunTo(3);
else
Anim_RunToFlee(3);
FaceMotion();
}
else
{
if ((origin - m_vGrenadePos).lengthXY(true) >= 100352
|| !G_SightTrace(
centroid,
vec_zero,
vec_zero,
m_vGrenadePos,
this,
m_pGrenade,
33819417,
0,
"Actor::Grenade_Flee"))
{
m_eGrenadeState = AI_GRENSTATE_FLEE_SUCCESS;
Anim_Attack();
AimAtAimNode();
}
else
{
m_bHasDesiredLookAngles = false;
m_eGrenadeState = AI_GRENSTATE_FLEE_FAIL;
Anim_Cower();
}
}
}
void Actor::Grenade_ThrowAcquire
@ -68,7 +212,7 @@ void Actor::Grenade_ThrowAcquire
)
{
if (!Grenade_Acquire(2, STRING_ANIM_GRENADERETURN_SCR)
if (!Grenade_Acquire(AI_GRENSTATE_THROW, STRING_ANIM_GRENADERETURN_SCR)
&& !CanGetGrenadeFromAToB(
m_vGrenadePos,
m_vLastEnemyPos,
@ -77,7 +221,7 @@ void Actor::Grenade_ThrowAcquire
&m_eGrenadeMode))
{
m_bGrenadeBounced = true;
m_eGrenadeState = 0;
m_eGrenadeState = AI_GRENSTATE_FLEE;
Grenade_Flee();
}
}
@ -102,27 +246,22 @@ void Actor::Grenade_KickAcquire
{
Vector vFace = vec_zero;
if (!Actor::Grenade_Acquire(4, STRING_ANIM_GRENADEKICK_SCR))
if (!Grenade_Acquire(AI_GRENSTATE_KICK, STRING_ANIM_GRENADEKICK_SCR))
{
VectorSub2D(m_vGrenadePos, origin, vFace);
if (CanKickGrenade(m_vGrenadePos, m_vLastEnemyPos, vFace, &m_vGrenadeVel))
{
m_vKickDir[0] = m_vGrenadeVel[0];
m_vKickDir[1] = m_vGrenadeVel[1];
m_vKickDir[2] = 0.0;
m_vKickDir = Vector(m_vGrenadeVel[0], m_vGrenadeVel[1], 0);
VectorNormalizeFast(m_vKickDir);
}
else
{
m_bGrenadeBounced = true;
m_eGrenadeState = 0;
m_eGrenadeState = AI_GRENSTATE_FLEE;
Grenade_Flee();
}
}
// FIXME: stub
STUB();
}
void Actor::Grenade_Kick
@ -141,8 +280,61 @@ void Actor::Grenade_MartyrAcquire
)
{
// FIXME: stub
STUB();
Vector vDest;
if (m_bGrenadeBounced)
{
m_bGrenadeBounced = false;
vDest = origin - m_vGrenadePos;
VectorNormalizeFast(vDest);
vDest = vDest * 88 + m_vGrenadePos;
SetPath(vDest, "", 0, NULL, 0.0);
}
if (PathExists())
{
if (PathComplete())
{
m_bHasDesiredLookAngles = false;
vDest = vec_zero;
m_pGrenade->velocity = vec_zero;
//weird ? m_pGrenade->velocity is vec_zero ???
if (m_pGrenade->velocity.lengthXY(true) < 1024)
{
m_pGrenade->velocity = vec_zero;
m_eGrenadeState = AI_GRENSTATE_MARTYR;
m_iStateTime = level.inttime;
Grenade_Martyr();
}
}
else
{
Anim_RunToCasual(3);
m_csPathGoalEndAnimScript = STRING_ANIM_GRENADEMARTYR_SCR;
if ((origin-m_vGrenadePos).lengthXY(true) > 16384)
{
FaceMotion();
}
else
{
if (m_vGrenadePos - origin != vec_zero)
{
SetDesiredYawDir(m_vGrenadePos - origin);
}
}
}
}
else
{
m_bGrenadeBounced = true;
m_eGrenadeState = AI_GRENSTATE_FLEE;
Grenade_Flee();
}
}
void Actor::Grenade_Martyr
@ -151,8 +343,17 @@ void Actor::Grenade_Martyr
)
{
// FIXME: stub
STUB();
if (m_pGrenade && level.inttime >= (m_iStateTime + 1000) - 0.5)
{
Projectile *m_pPGrenade = (Projectile *)m_pGrenade.Pointer();
m_pPGrenade->m_bHurtOwnerOnly = true;
m_pPGrenade->owner = entnum;
}
m_bHasDesiredLookAngles = false;
ContinueAnimation();
}
void Actor::Grenade_Wait
@ -180,9 +381,9 @@ void Actor::Grenade_NextThinkState
{
if (m_Enemy && !(m_Enemy->IsSubclassOfActor()))
SetThinkState(4, 0);
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
else
SetThinkState(1, 0);
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
}
void Actor::Grenade_EventAttach
@ -191,8 +392,35 @@ void Actor::Grenade_EventAttach
)
{
// FIXME: stub
STUB();
if (m_pGrenade)
{
eGrenadeTossMode eMode;
Vector vVel;
int tagnum = gi.Tag_NumForName(edict->tiki, "tag_weapon_right");
if (tagnum >= 0)
{
vVel = vec_zero;
m_pGrenade->attach(
entnum,
tagnum,
qtrue,
vec3_origin);
}
m_pGrenade->avelocity = vec3_origin;
if (CanGetGrenadeFromAToB(
origin,
m_vLastEnemyPos,
true,
&vVel,
&eMode))
{
m_vGrenadeVel = vVel;
m_eGrenadeMode = eMode;
}
SetDesiredYawDir(m_vGrenadeVel);
}
}
void Actor::Grenade_EventDetach
@ -201,8 +429,16 @@ void Actor::Grenade_EventDetach
)
{
// FIXME: stub
STUB();
if (m_pGrenade)
{
m_pGrenade->detach();
m_pGrenade->setOrigin(GrenadeThrowPoint(origin, orientation[0], m_eGrenadeMode == AI_GREN_KICK ? STRING_ANIM_GRENADEKICK_SCR : STRING_ANIM_GRENADERETURN_SCR));
m_pGrenade->velocity = m_vGrenadeVel;
m_pGrenade->edict->r.ownerNum = edict->s.number;
m_pGrenade->groundentity = NULL;
}
}
void Actor::Begin_Grenade
@ -211,8 +447,126 @@ void Actor::Begin_Grenade
)
{
// FIXME: stub
STUB();
m_pGrenade->enemy;
DoForceActivate();
m_csMood = STRING_ALERT;
m_csIdleMood = STRING_NERVOUS;
if (m_pGrenade)
{
if (m_pGrenade->enemy)
{
m_eGrenadeState = AI_GRENSTATE_FLEE;
//LABEL_4:
Grenade_Flee();
return;
}
if (m_pGrenade->edict->r.ownerNum == entnum)
{
m_eGrenadeState = AI_GRENSTATE_FLEE;
Grenade_Flee();
return;
}
bool bHasThrowTarget = true;
float fDistSquared;
Vector vDelta;
if (!m_Enemy)
{
Sentient *pEnemy = (Sentient *)G_GetEntity(m_pGrenade->edict->r.ownerNum);
if (pEnemy && pEnemy->m_Team != m_Team)
{
SetEnemyPos(pEnemy->origin);
}
else
{
bHasThrowTarget = false;
}
}
if (!bHasThrowTarget)
{
m_eGrenadeState = AI_GRENSTATE_FLEE;
Grenade_Flee();
return;
}
vDelta = m_vGrenadePos - origin;
vDelta.z = 0;
fDistSquared = vDelta.lengthXY(true);
if (fDistSquared >= 65536)
{
m_eGrenadeState = AI_GRENSTATE_FLEE;
Grenade_Flee();
return;
}
if (fDistSquared > 16384 && GrenadeWillHurtTeamAt(m_vGrenadePos))
{
m_pGrenade->enemy = this;
m_eGrenadeState = AI_GRENSTATE_MARTYR_ACQUIRE;
Grenade_MartyrAcquire();
return;
}
if (GrenadeWillHurtTeamAt(m_vLastEnemyPos))
{
m_eGrenadeState = AI_GRENSTATE_FLEE;
Grenade_Flee();
return;
}
if (CanKickGrenade(m_vGrenadePos, m_vLastEnemyPos, vDelta, &m_vGrenadeVel))
{
m_eGrenadeMode = AI_GREN_KICK;
m_vKickDir = Vector(m_vGrenadeVel[0], m_vGrenadeVel[1], 0);
VectorNormalizeFast(m_vKickDir);
m_pGrenade->enemy = this;
m_eGrenadeState = AI_GRENSTATE_KICK_ACQUIRE;
PostponeEvent(EV_Projectile_Explode, 0.25);
Grenade_KickAcquire();
return;
}
if (!CanGetGrenadeFromAToB(m_vGrenadePos, m_vLastEnemyPos, true, &m_vGrenadeVel, &m_eGrenadeMode))
{
m_eGrenadeState = AI_GRENSTATE_FLEE;
Grenade_Flee();
return;
}
m_pGrenade->enemy = this;
m_eGrenadeState = AI_GRENSTATE_THROW_ACQUIRE;
PostponeEvent(EV_Projectile_Explode, 0.75);
if (!Grenade_Acquire(AI_GRENSTATE_THROW, STRING_ANIM_GRENADERETURN_SCR)
&& !Actor::CanGetGrenadeFromAToB(m_vGrenadePos, m_vLastEnemyPos, true, &m_vGrenadeVel, &m_eGrenadeMode))
{
m_bGrenadeBounced = true;
m_eGrenadeState = AI_GRENSTATE_FLEE;
Grenade_Flee();
return;
}
}
else
{
if (m_Enemy && !m_Enemy->IsSubclassOfActor())
{
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL);
}
else if (m_Team == TEAM_AMERICAN)
{
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
}
else
{
if (!IsTeamMate((Sentient*)G_GetEntity(0)))
ForceAttackPlayer();
}
}
}
void Actor::End_Grenade
@ -242,8 +596,104 @@ void Actor::Think_Grenade
)
{
// FIXME: stub
STUB();
if (m_bEnableEnemy)
UpdateEnemy(200);
m_pszDebugState = "";
NoPoint();
if (level.inttime - m_iFirstGrenadeTime > 8000)
{
Anim_Stand();
Grenade_NextThinkState();
PostThink(false);
return;
}
if (!m_pGrenade)
{
if (m_eGrenadeState && m_eGrenadeState != AI_GRENSTATE_FLEE_FAIL)
{
//weird ? no such thing as 8 ?
if (m_eGrenadeMode == 8)
Anim_Attack();
else
Anim_Stand();
Grenade_NextThinkState();
}
else
{
m_pszDebugState = "Wait";
Grenade_Wait();
}
PostThink(false);
return;
}
switch (m_eGrenadeState)
{
case AI_GRENSTATE_FLEE:
case AI_GRENSTATE_FLEE_SUCCESS:
case AI_GRENSTATE_FLEE_FAIL:
m_pszDebugState = "RunAway";
Grenade_Flee();
PostThink(false);
return;
case AI_GRENSTATE_THROW_ACQUIRE:
m_pszDebugState = "ThrowAcquire";
Grenade_ThrowAcquire();
PostThink(false);
return;
case AI_GRENSTATE_THROW:
m_pszDebugState = "Throw";
Grenade_Throw();
PostThink(false);
return;
case AI_GRENSTATE_KICK_ACQUIRE:
m_pszDebugState = "KickAcquire";
Grenade_KickAcquire();
PostThink(false);
return;
case AI_GRENSTATE_KICK:
m_pszDebugState = "Kick";
m_bHasDesiredLookAngles = false;
ContinueAnimation();
PostThink(false);
return;
case AI_GRENSTATE_MARTYR_ACQUIRE:
m_pszDebugState = "MartyrAcquire";
Grenade_MartyrAcquire();
PostThink(false);
return;
case AI_GRENSTATE_MARTYR:
m_pszDebugState = "Martyr";
Grenade_Martyr();
PostThink(false);
return;
default:
m_pszDebugState = "***Invalid***";
/* useless assert
if ( !dword_39AC88 )
{
strcpy(v4, \"invalid grenade state\"\n\tMessage: ");
memset(&s, 0, 0x3FDFu);
v2 = DumpCallTrace(
"thinkstate = %i",
m_State);
Q_strcat(v4, 0x4000, v2);
v3 = MyAssertHandler(v4, "fgame/actor_grenade.cpp", 762, 0);
if ( v3 < 0 )
{
dword_39ACFC = 1;
}
else if ( v3 > 0 )
{
__debugbreak();
}
}
*/
PostThink(false);
return;
}
}
void Actor::FinishedAnimation_Grenade
@ -254,16 +704,16 @@ void Actor::FinishedAnimation_Grenade
{
switch (m_eGrenadeState)
{
case 0:
case 1:
case 3:
case 5:
case 6:
case 8:
case 9:
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 2:
case 4:
case AI_GRENSTATE_THROW:
case AI_GRENSTATE_KICK:
Grenade_NextThinkState();
break;
default:

View file

@ -25,6 +25,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "actor.h"
#include "weapturret.h"
extern Vector MINS;
extern Vector MAXS;
void Actor::InitMachineGunner
(
GlobalFuncs_t *func
@ -44,8 +47,46 @@ void Actor::Begin_MachineGunner
)
{
// FIXME: stub
STUB();
m_csMood = STRING_ALERT;
m_csIdleMood = STRING_NERVOUS;
if (m_pTurret)
{
Sentient *pOwner;
m_pTurret->m_bHadOwner = true;
pOwner = m_pTurret->GetOwner();
if (pOwner)
{
Com_Printf(
"^~^~^ Actor (entnum %d, radnum %d, targetname '%s') cannot use turret (entnum %d, radnum %d, targetname '%s')"
" since it is already being used by Actor (entnum %d, radnum %d, targetname '%s')\n",
entnum,
radnum,
targetname.c_str(),
m_pTurret->entnum,
m_pTurret->radnum,
m_pTurret->TargetName().c_str(),
pOwner->entnum,
pOwner->radnum,
pOwner->TargetName().c_str());
}
else
{
Holster();
m_pTurret->TurretBeginUsed(this);
m_State = 1200;
m_iStateTime = level.inttime;
}
}
else
{
Com_Printf(
"^~^~^ Actor (entnum %d, radnum %d, targetname '%s') has no turret specified\n",
entnum,
radnum,
targetname.c_str());
}
}
void Actor::End_MachineGunner
(
@ -53,7 +94,7 @@ void Actor::End_MachineGunner
)
{
if (!Sentient::GetWeapon(WEAPON_MAIN))
if (!GetWeapon(WEAPON_MAIN))
giveItem("models/weapons/mp40.tik");
Unholster();
@ -71,36 +112,217 @@ void Actor::BecomeTurretGuy
)
{
SetThinkIdle(8);
SetThinkIdle(THINK_IDLE);
SetThink(THINKSTATE_ATTACK, 1);
SetThink(THINKSTATE_DISGUISE, 10);
SetThink(THINKSTATE_GRENADE, 16);
SetThink(THINKSTATE_ATTACK, THINK_TURRET);
SetThink(THINKSTATE_DISGUISE, THINK_DISGUISE_SALUTE);
SetThink(THINKSTATE_GRENADE, THINK_GRENADE);
if (m_Think[m_ThinkLevel] == 1 && Turret_DecideToSelectState())
if (CurrentThink() == THINK_IDLE && Turret_DecideToSelectState())
{
m_State = 100;
m_iStateTime = level.inttime;
}
}
void Actor::Think_MachineGunner
(
void
)
{
// FIXME: stub
STUB();
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->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[0] != 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
)
{
// FIXME: stub
STUB();
Vector end;
trace_t trace;
float temp;
float temp2;
float machine_gunner_hands_up_stand;
float heightDiff;
float right;
vec3_t newOrigin;
Vector offset;
Vector start;
vec3_t new_angles;
Vector vForward;
UpdateEyeOrigin();
m_pszDebugState = "";
if (m_State == 1200)
{
if (m_pTurret->IsFiring())
{
if (m_pTurret->aim_target == G_GetEntity(0))
{
m_bNoSurprise = true;
}
m_csNextAnimString = STRING_ANIM_MG42_SHOOT_SCR;
}
else
{
m_csNextAnimString = STRING_ANIM_MG42_IDLE_SCR;
}
}
else
{
m_csNextAnimString = STRING_ANIM_MG42_RELOAD_SCR;
m_bAnimScriptSet = false;
}
m_eNextAnimMode = 8;
m_bNextForceStart = false;
CheckUnregister();
m_YawAchieved = true;
setAngles(Vector(0,m_pTurret->angles[1],0));
vForward = Vector(m_pTurret->orientation[0]) * -39 + m_pTurret->origin;
if (m_State == 1201)
{
heightDiff = 71.6;
}
else
{
heightDiff = 71.8;
}
machine_gunner_hands_up_stand = origin[2] - (m_pTurret->origin[2] - heightDiff);
if (machine_gunner_hands_up_stand < 0)
{
if (m_State == 1201)
{
temp = (machine_gunner_hands_up_stand - m_pTurret->origin[2]) / 39;
if (temp >= -1.0 && temp <= 1.0)
{
right = atan2(temp / sqrt(temp*-temp + 1), 1) * 180 / M_PI;
m_pTurret->setAngles(Vector(right, m_pTurret->angles[1], m_pTurret->angles[2]));
}
}
else
{
m_fCrouchWeight = machine_gunner_hands_up_stand / 17.1;
if (m_fCrouchWeight < -1.0)
{
m_fCrouchWeight = -1.0;
}
}
temp2 = m_fCrouchWeight * 2.6;
offset.x = (-(-9.3*m_fCrouchWeight + 23.4)) * orientation[0][0] + vForward.x;
offset.y = (-(-9.3*m_fCrouchWeight + 23.4)) * orientation[0][0] + vForward.y;
}
else
{
m_fCrouchWeight = machine_gunner_hands_up_stand / (heightDiff - 38.7);
if (m_fCrouchWeight > 1.0)
{
m_fCrouchWeight = 1.0;
}
temp2 = m_fCrouchWeight * -1.6;
offset.x = (-(-3*m_fCrouchWeight + 23.4)) * orientation[0][0] + vForward.x;
offset.y = (-(-3*m_fCrouchWeight + 23.4)) * orientation[0][0] + vForward.y;
}
start.x = (temp2 + 10.3) * orientation[1][0] + offset.x;
start.y = (temp2 + 10.3) * orientation[1][1] + offset.y;
if (m_fCrouchWeight >= 0.5)
m_csCurrentPosition = STRING_CROUCH;
else
m_csCurrentPosition = STRING_STAND;
UpdateAimMotion();
UpdateAnim();
start.z = origin.z + 18.0;
end = start;
end.z = origin.z - 94.0;
trace = G_Trace(start, MINS, MAXS, end, this, 1107437825, qfalse, "Actor::ThinkHoldGun");
if (trace.fraction != 1.0 && !trace.startsolid && !trace.allsolid && trace.ent)
SafeSetOrigin(trace.endpos);
velocity = vec_zero;
UpdateBoneControllers();
UpdateFootsteps();
}
void Actor::FinishedAnimation_MachineGunner
(
void

View file

@ -49,6 +49,74 @@ void Actor::Think_NoClip
)
{
// FIXME: stub
STUB();
//FIXME: not sure of naming
bool done = false;
Vector newOrigin = vec_zero;
Vector total_offset;
Vector total_offset_unit;
float total_dist;
vec3_t frame_offset;
float frame_dist;
m_pszDebugState = "";
if (m_eNextAnimMode < 0)
{
m_bNextForceStart = false;
m_csNextAnimString = NULL;
m_eNextAnimMode = m_eAnimMode;
m_NextAnimLabel = m_Anim;
}
CheckUnregister();
UpdateAngles();
UpdateAnim();
total_offset = m_NoClipDest - origin;
total_dist = VectorNormalize2(total_offset, total_offset_unit);
frame_dist = level.frametime * m_maxspeed;
if (frame_dist >= frame_delta.lengthSquared())
{
frame_dist = frame_delta.lengthSquared();
}
if (frame_dist < total_dist)
{
newOrigin = total_offset_unit * frame_dist + origin;
}
else
{
done = true;
newOrigin = m_NoClipDest;
}
SafeSetOrigin(newOrigin);
velocity = total_offset_unit / level.frametime;
if (velocity.lengthSquared() < 1)
{
done = true;
velocity = vec_zero;
}
groundentity = NULL;
if (done)
{
Com_Printf(
"(entnum %d, radnum %d) failsafe finished\n",
entnum,
radnum);
EndCurrentThinkState();
}
UpdateBoneControllers();
UpdateFootsteps();
}

View file

@ -56,8 +56,8 @@ void Actor::End_Patrol
)
{
// FIXME: stub
STUB();
parm.movefail = true;
}
void Actor::Resume_Patrol
@ -66,7 +66,7 @@ void Actor::Resume_Patrol
)
{
parm.movefail = true;
;
}
void Actor::Think_Patrol
@ -99,7 +99,7 @@ void Actor::Think_Patrol
}
else
{
SetThinkIdle(8);
SetThinkIdle(THINK_IDLE);
m_bScriptGoalValid = false;
}
parm.movedone = true;

View file

@ -96,7 +96,7 @@ void Actor::Think_Runner
}
else
{
SetThinkIdle(8);
SetThinkIdle(THINK_IDLE);
m_bScriptGoalValid = false;
}

View file

@ -111,18 +111,232 @@ void Actor::Think_Turret
{
//FIXME: weird, appears to be looping here ? O.o
if (!RequireThink())
if (RequireThink())
{
return;
UpdateEyeOrigin();
NoPoint();
UpdateEnemy(200);
if (m_Enemy && m_State == 110)
{
if (!m_bTurretNoInitialCover)
{
if (Turret_TryToBecomeCoverGuy())
{
m_pszDebugState = "CoverInstead";
CheckUnregister();
UpdateAngles();
DoMove();
UpdateBoneControllers();
UpdateFootsteps();
return;
}
}
m_bTurretNoInitialCover = false;
Turret_SelectState();
if (m_State == 100 && !CanSeeEnemy(0))
{
SetEnemyPos(m_Enemy->origin);
AimAtEnemyBehavior();
m_State = 113;
m_iStateTime = level.inttime;
}
SetLeashHome(origin);
if (level.inttime < m_iEnemyChangeTime + 200)
{
if (AttackEntryAnimation())
{
m_State = 108;
m_bLockThinkState = true;
m_iStateTime = level.inttime;
}
}
}
if (level.inttime > m_iStateTime + 3000)
Turret_SelectState();
if (m_State == 108)
{
m_pszDebugState = "IntroAnim";
AimAtAimNode();
ContinueAnimation();
}
else
{
m_bLockThinkState = false;
if (!m_Enemy && m_State != 109 && m_State != 104)
{
m_State = 109;
m_iStateTime = level.inttime + ((rand() + 0xFA) & 0x7FF);
}
if (!m_Enemy)
{
if (m_State != 109)
{
if (m_State != 104
|| (origin - m_vHome).lengthXY(true) <= 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)
{
Actor::SetEnemyPos(m_Enemy->origin);
AimAtEnemyBehavior();
m_State = 113;
m_iStateTime = level.inttime;
}
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();
m_State = 103;
m_iStateTime = level.inttime;
}
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";
GenericGrenadeTossThink();
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";
AimAtEnemyBehavior();
SetPathWithLeash(m_vLastEnemyPos, "", 0);
if (!ShortenPathToAttack(128.0f))
{
Turret_NextRetarget();
}
else
{
ShortenPathToAvoidSquadMates();
if (PathExists())
{
m_State = 101;
m_iStateTime = level.inttime;
}
else
{
Turret_NextRetarget();
}
}
case 116:
m_pszDebugState = "Retarget_Path_Near";
AimAtEnemyBehavior();
FindPathNearWithLeash(m_vLastEnemyPos, m_fMinDistanceSquared);
if (ShortenPathToAttack(128.0f))
{
m_State = 101;
m_iStateTime = level.inttime;
}
else
{
Turret_NextRetarget();
}
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);
}
}
UpdateEyeOrigin();
NoPoint();
UpdateEnemy(200);
// FIXME: stub
STUB();
}
void Actor::FinishedAnimation_Turret
@ -157,7 +371,7 @@ void Actor::ReceiveAIEvent_Turret
{
m_State = 111;
m_iStateTime = level.inttime;
SetThink(4, 2);
SetThink(THINKSTATE_ATTACK, THINK_COVER);
}
else if (pCoverNode)
{
@ -280,14 +494,11 @@ void Actor::Turret_SelectState
SetPath(m_vHome, "", 0, NULL, 0.0);
ShortenPathToAvoidSquadMates();
if (PathExists())
if (PathExists() && !PathComplete())
{
if (!PathComplete())
{
m_State = 104;
m_iStateTime = level.inttime;
return;
}
m_State = 104;
m_iStateTime = level.inttime;
return;
}
else
{
@ -343,8 +554,8 @@ void Actor::Turret_SelectState
if (DecideToThrowGrenade(m_Enemy->velocity + m_vLastEnemyPos, &m_vGrenadeVel, &m_eGrenadeMode))
{
m_bNextForceStart = false;
m_YawAchieved = false;
m_DesiredYaw = vectoyaw(this->m_vGrenadeVel);
SetDesiredYawDir(m_vGrenadeVel);
m_eNextAnimMode = 1;
m_State = 107;
m_csNextAnimString = (m_eGrenadeMode == AI_GREN_TOSS_ROLL) ? STRING_ANIM_GRENADETOSS_SCR : STRING_ANIM_GRENADETHROW_SCR;
@ -380,13 +591,13 @@ bool Actor::Turret_TryToBecomeCoverGuy
)
{
auto pCoverNode = this->m_pCoverNode;
auto pCoverNode = m_pCoverNode;
Cover_FindCover(true);
if (m_pCoverNode)
{
m_State = 111;
m_iStateTime = level.inttime;
SetThink(4, 2);
SetThink(THINKSTATE_ATTACK, THINK_COVER);
return true;
}
else
@ -644,7 +855,7 @@ bool Actor::State_Turret_RunHome
{
SetPath(this->m_vHome, "", 0, NULL, 0.0);
SetPath(m_vHome, "", 0, NULL, 0.0);
ShortenPathToAvoidSquadMates();
if (!PathExists() || PathComplete())
{
@ -700,7 +911,7 @@ void Actor::State_Turret_Charge
)
{
SetPathWithLeash(this->m_vLastEnemyPos, "", 0);
SetPathWithLeash(m_vLastEnemyPos, "", 0);
ShortenPathToAvoidSquadMates();
if (!PathExists())
{
@ -766,7 +977,7 @@ void Actor::State_Turret_FakeEnemy
AimAtAimNode();
Anim_Aim();
if (level.inttime >= m_iStateTime)
SetThinkState(THINKSTATE_IDLE, 0);
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
}
void Actor::State_Turret_Wait
@ -787,7 +998,7 @@ void Actor::State_Turret_Wait
{
m_State = 111;
m_iStateTime = level.inttime;
SetThink(THINKSTATE_ATTACK, 2);
SetThink(THINKSTATE_ATTACK, THINK_COVER);
bSmth = true;
}
else
@ -816,7 +1027,7 @@ void Actor::State_Turret_Wait
{
if (level.inttime >= m_iLastFaceDecideTime + 1500)
{
this->m_iLastFaceDecideTime = level.inttime + (rand() & 0x1FF);
m_iLastFaceDecideTime = level.inttime + (rand() & 0x1FF);
@ -869,17 +1080,8 @@ void Actor::State_Turret_Retarget_Sniper_Node
pSniperNode->Claim(this);
m_State = 102;
m_iStateTime = level.inttime;
if (PathExists() && !PathComplete())
{
FaceMotion();
Anim_RunToDanger(3);
}
else
{
AimAtEnemyBehavior();
m_State = 103;
m_iStateTime = level.inttime;
}
State_Turret_TakeSniperNode();
}
else if (bTryAgain)
{

View file

@ -61,6 +61,7 @@ void Actor::Begin_Weaponless
}
}
m_State = 900;
m_iStateTime = level.inttime;
}
void Actor::Suspend_Weaponless
@ -100,7 +101,7 @@ void Actor::Think_Weaponless
m_bLockThinkState = false;
if (!m_Enemy)
{
SetThinkState(1, 0);
SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL);
IdleThink();
return;
}
@ -136,11 +137,11 @@ void Actor::Think_Weaponless
}
*/
}
CheckForTransition(7, 0);
CheckForTransition(THINKSTATE_GRENADE, 0);
}
PostThink(true);
if (GetWeapon(WEAPON_MAIN))
SetThink(4, 1);
SetThink(THINKSTATE_ATTACK, THINK_TURRET);
}
}
@ -183,12 +184,11 @@ void Actor::State_Weaponless_Normal
AimAtAimNode();
Anim_Stand();
if (level.inttime >= this->m_iStateTime)
if (level.inttime >= m_iStateTime)
{
if (DecideToThrowGrenade(m_Enemy->velocity + m_Enemy->origin, &m_vGrenadeVel, &m_eGrenadeMode))
{
m_YawAchieved = false;
m_DesiredYaw = vectoyaw(m_vGrenadeVel);
SetDesiredYawDir(m_vGrenadeVel);
m_State = 901;
m_eNextAnimMode = 1;

View file

@ -29,7 +29,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
ActorEnemy::ActorEnemy()
{
//no need
m_pEnemy = NULL;
m_vLastKnownPos = vec_zero;
}
ActorEnemy::~ActorEnemy()
@ -81,8 +82,12 @@ int ActorEnemy::UpdateThreat
)
{
//FIXME: macro
static float fRangeThreatSquared[15];
static int iWeaponThreat[7][5];
int iWeapon;
int iZone;
Vector vDelta;
m_iThreat = 0;
m_fCurrentRangeSquared = 1e38;
@ -94,10 +99,138 @@ int ActorEnemy::UpdateThreat
if (m_bVisible == true)
m_iThreat = 10500;
vDelta = m_pEnemy->origin - pSelf->origin;
m_fCurrentRangeSquared = vDelta.lengthSquared();
// FIXME: stub
STUB();
return NULL;
if (m_fCurrentRangeSquared >= 65536.0)
{
if (m_fCurrentRangeSquared >= 589824.0)
{
if (m_fCurrentRangeSquared >= 1638400.0)
{
if (m_fCurrentRangeSquared >= 4194304.0)
iZone = 4;
else
iZone = 3;
}
else
{
iZone = 2;
}
}
else
{
iZone = 1;
}
}
else
{
iZone = 0;
}
Weapon *pEnemyWeapon = m_pEnemy->GetActiveWeapon(WEAPON_MAIN);
iWeapon = 0;
if (pEnemyWeapon)
{
int iWeapClass = pEnemyWeapon->GetWeaponClass();
if (iWeapClass & WEAPON_CLASS_PISTOL)
{
iWeapon = 1;
}
else if (iWeapClass & WEAPON_CLASS_RIFLE)
{
iWeapon = 2;
}
else if (iWeapClass & WEAPON_CLASS_SMG)
{
iWeapon = 3;
}
else if (iWeapClass & WEAPON_CLASS_MG)
{
iWeapon = 4;
}
else if(iWeapClass & WEAPON_CLASS_GRENADE)
{
iWeapon = 5;
}
else
{
iWeapon = 6;
}
}
int i=0;
if (m_fCurrentRangeSquared > 4194304)
{
for (; i < 15 && fRangeThreatSquared[i] > m_fCurrentRangeSquared; i++)
{
}
}
m_iThreat += iWeaponThreat[iZone][iWeapon] + m_pEnemy->m_iThreatBias + i;
float fMinSafeDistSquared = 1.21 * pSelf->m_fMinDistanceSquared + 16384;
if (m_fCurrentRangeSquared < fMinSafeDistSquared)
{
m_iThreat -= (sqrt(m_fCurrentRangeSquared / fMinSafeDistSquared) * 500) + 500;
}
Vector vLine = m_vLastKnownPos - pSelf->origin;
float fDot = DotProduct2D(vLine, m_vLastKnownPos);
for (Sentient *pSquadMate = m_pEnemy->m_pNextSquadMate; pSquadMate != m_pEnemy; pSquadMate = pSquadMate->m_pNextSquadMate)
{
if (fDot > DotProduct2D(vLine, pSquadMate->origin))
{
m_iThreat -= 4;
}
}
Actor *pAEnemy = (Actor *)m_pEnemy.Pointer();
if (pAEnemy->IsSubclassOfActor() && pAEnemy->m_ThinkState == THINKSTATE_PAIN)
{
m_iThreat -= 2;
}
fDot = Vector::Dot(vDelta, pSelf->orientation[0]);
if (fDot <= 0 )
{
if (m_fCurrentRangeSquared * 0.5 > Square(fDot))
{
m_iThreat++;
}
}
else
{
if (m_fCurrentRangeSquared * 0.5 >= Square(fDot))
{
if (m_fCurrentRangeSquared * 0.5 > Square(fDot))
{
m_iThreat++;
}
}
}
int iEnemyDiscount = m_pEnemy->m_iAttackerCount;
if (m_pEnemy == pSelf->m_Enemy)
{
iEnemyDiscount -= 2;
if (level.inttime < pSelf->m_iEnemyChangeTime + 1000)
m_iThreat += 5;
}
if (iEnemyDiscount > 4)
iEnemyDiscount = 4;
m_iThreat -= iEnemyDiscount;
if (m_pEnemy == pSelf->m_pLastAttacker)
{
m_iThreat += 5;
}
if (m_pEnemy == pSelf->m_FavoriteEnemy)
m_iThreat += 250;
return m_iThreat;
}
Sentient *ActorEnemy::GetEnemy
@ -224,9 +357,41 @@ ActorEnemy *ActorEnemySet::AddPotentialEnemy
)
{
// FIXME: stub
STUB();
return NULL;
ActorEnemy NewEnemy;
if (pEnemy->IsDead() || pEnemy->m_iThreatBias == THREATBIAS_IGNOREME)
{
return NULL;
}
for (int i = 0; i < m_Enemies.NumObjects(); i++)
{
ActorEnemy *pActorEnemy = &m_Enemies[i];
if (pActorEnemy->m_pEnemy == pEnemy)
{
pActorEnemy->m_iAddTime = level.inttime;
return pActorEnemy;
}
}
NewEnemy.m_fVisibility = 0.0;
NewEnemy.m_fTotalVisibility = 0.0;
NewEnemy.m_iAddTime = level.inttime;
NewEnemy.m_fLastLookTime = level.time;
NewEnemy.m_iThreat = 0;
NewEnemy.m_pEnemy = pEnemy;
NewEnemy.m_fCurrentRangeSquared = 1e38;
NewEnemy.m_iLastSightChangeTime = 0;
NewEnemy.m_vLastKnownPos = vec_zero;
NewEnemy.m_bVisible = false;
return &m_Enemies[m_Enemies.AddObject(NewEnemy)-1];
}
void ActorEnemySet::FlagBadEnemy
@ -235,8 +400,37 @@ void ActorEnemySet::FlagBadEnemy
)
{
// FIXME: stub
STUB();
ActorEnemy *pActorEnemy;
for (int i = 0; i < m_Enemies.NumObjects(); i++)
{
pActorEnemy = &m_Enemies[i];
if (pActorEnemy->m_pEnemy == pEnemy)
{
break;
}
if (i+1 == m_Enemies.NumObjects())
return;
}
pActorEnemy->m_iThreat = 0;
pActorEnemy->m_fVisibility = 0.0;
pActorEnemy->m_fTotalVisibility = 0.0;
pActorEnemy->m_fLastLookTime = level.time;
pActorEnemy->m_bVisible = false;
pActorEnemy->m_iLastSightChangeTime = level.inttime;
if (pEnemy == m_pCurrentEnemy)
{
if (m_pCurrentEnemy)
{
delete m_pCurrentEnemy;
m_pCurrentEnemy = NULL;
}
m_fCurrentVisibility = 0.0;
m_iCurrentThreat = 0;
}
}
void ActorEnemySet::CheckEnemies
@ -245,8 +439,148 @@ void ActorEnemySet::CheckEnemies
)
{
// FIXME: stub
STUB();
float fRangeSquared;
bool bVisible;
bool bInFovAndRange = false;
int nChecked;
int iThreat;
float fVisibility;
ActorEnemy *pActorEnemy;
for (int i = 1; i < m_Enemies.NumObjects();i++)
{
pActorEnemy = &m_Enemies[i];
if (!pActorEnemy->m_pEnemy
|| pActorEnemy->m_pEnemy->m_Team != pSelf->m_Team
|| pActorEnemy->m_pEnemy->IsDead()
|| level.inttime > pActorEnemy->m_iAddTime + 10000
|| pActorEnemy->m_pEnemy->m_iThreatBias == THREATBIAS_IGNOREME)
{
m_Enemies.RemoveObjectAt(i);
i--;
}
}
if (!m_Enemies.NumObjects())
{
m_iCurrentThreat = 0;
if (m_pCurrentEnemy)
{
delete m_pCurrentEnemy;
m_pCurrentEnemy = NULL;
}
}
else
{
for (int i = 0; !bInFovAndRange && i < m_Enemies.NumObjects(); i++)
{
m_iCheckCount++;
if (m_iCheckCount > m_Enemies.NumObjects())
m_iCheckCount = 1;
pActorEnemy = &m_Enemies[m_iCheckCount-1];
fVisibility = pActorEnemy->UpdateVisibility(pSelf, &bInFovAndRange, &bVisible);
if (fVisibility <= 0.0)
{
if (pActorEnemy->m_pEnemy == m_pCurrentEnemy)
{
m_iCurrentThreat = 0;
if (m_pCurrentEnemy)
{
delete m_pCurrentEnemy;
m_pCurrentEnemy = NULL;
}
m_fCurrentVisibility = 0.0;
}
}
else
{
if (fVisibility < m_fCurrentVisibility)
{
if (pActorEnemy->m_pEnemy == m_pCurrentEnemy)
{
m_iCurrentThreat = 0;
if (m_pCurrentEnemy)
{
delete m_pCurrentEnemy;
m_pCurrentEnemy = NULL;
}
m_fCurrentVisibility = fVisibility;
}
}
else
{
m_pCurrentEnemy = pActorEnemy->m_pEnemy;
}
if (g_showawareness->integer)
{
Com_Printf(
"ent #%3i: enemy #%i: awareness = %5.1f%%, threat = %i\n",
pSelf->entnum,
pActorEnemy->m_pEnemy->entnum,
(fVisibility * 100.0),
0);
}
}
if (bVisible)
{
if (!pActorEnemy->m_bVisible)
{
pActorEnemy->m_bVisible = true;
pActorEnemy->m_iLastSightChangeTime = level.inttime;
}
pActorEnemy->m_vLastKnownPos = pActorEnemy->m_pEnemy->origin;
}
else if (pActorEnemy->m_bVisible)
{
pActorEnemy->m_bVisible = false;
pActorEnemy->m_iLastSightChangeTime = level.inttime;
}
}
if (m_pCurrentEnemy && m_pCurrentEnemy->IsDead())
{
if (m_pCurrentEnemy)
{
delete m_pCurrentEnemy;
m_pCurrentEnemy = NULL;
}
m_iCurrentThreat = 0;
m_fCurrentVisibility = 0.0;
}
m_iCurrentThreat = 0;
fRangeSquared = 1e37;
if (m_fCurrentVisibility >= 1)
{
for (int i = 0;i < m_Enemies.NumObjects(); i++)
{
pActorEnemy = &m_Enemies[i];
pActorEnemy->UpdateThreat(pSelf);
if (m_iCurrentThreat < pActorEnemy->m_iThreat || m_iCheckCount == pActorEnemy->m_iThreat && fRangeSquared > pActorEnemy->m_fCurrentRangeSquared)
{
m_iCurrentThreat = pActorEnemy->m_iThreat;
m_pCurrentEnemy = pActorEnemy->m_pEnemy;
fRangeSquared = pActorEnemy->m_fCurrentRangeSquared;
}
}
}
if ((!m_pCurrentEnemy || !m_pCurrentEnemy->m_bIsDisguised) && m_iCurrentThreat <= 0)
{
if (m_pCurrentEnemy)
{
delete m_pCurrentEnemy;
m_pCurrentEnemy = NULL;
}
m_iCurrentThreat = 0;
m_fCurrentVisibility = 0.0;
}
}
}
Sentient *ActorEnemySet::GetCurrentEnemy
@ -282,7 +616,7 @@ qboolean ActorEnemySet::IsEnemyConfirmed
) const
{
// FIXME: stub
// not found in ida
STUB();
return false;
}
@ -293,8 +627,15 @@ bool ActorEnemySet::HasAlternateEnemy
) const
{
// FIXME: stub
STUB();
ActorEnemy *pActorEnemy;
for (int i = 0; i < m_Enemies.NumObjects(); i++)
{
pActorEnemy = &m_Enemies[i];
if (pActorEnemy->m_pEnemy != m_pCurrentEnemy)
{
return true;
}
}
return false;
}
@ -304,8 +645,15 @@ void ActorEnemySet::RemoveAll
)
{
// FIXME: stub
STUB();
m_Enemies.ClearObjectList();
m_iCheckCount = 0;
if (m_pCurrentEnemy)
{
delete m_pCurrentEnemy;
m_pCurrentEnemy = NULL;
}
m_fCurrentVisibility = 0.0;
m_iCurrentThreat = 0;
}
void ActorEnemySet::ConfirmEnemy
@ -315,8 +663,20 @@ void ActorEnemySet::ConfirmEnemy
)
{
// FIXME: stub
STUB();
pSelf->m_bEnemyIsDisguised = false;
ActorEnemy *pActorEnemy = ActorEnemySet::AddPotentialEnemy(pEnemy);
if (pActorEnemy)
{
pActorEnemy->m_fVisibility = 1.0;
pActorEnemy->m_fTotalVisibility = 1.0;
pActorEnemy->m_vLastKnownPos = pEnemy->origin;
if (m_fCurrentVisibility < 1.0)
{
m_iCurrentThreat = pActorEnemy->UpdateThreat(pSelf);
m_fCurrentVisibility = 1.0;
m_pCurrentEnemy = pEnemy;
}
}
}
void ActorEnemySet::ConfirmEnemyIfCanSeeSharerOrEnemy
@ -327,8 +687,33 @@ void ActorEnemySet::ConfirmEnemyIfCanSeeSharerOrEnemy
)
{
// FIXME: stub
STUB();
pSelf->m_bEnemyIsDisguised = false;
ActorEnemy *pActorEnemy = ActorEnemySet::AddPotentialEnemy(pEnemy);
if (pActorEnemy)
{
if (pActorEnemy->m_fTotalVisibility > 0)
{
pActorEnemy->m_vLastKnownPos = pEnemy->origin;
return;
}
if (!pActorEnemy->m_bVisible)
{
if (!pSelf->CanSee(
pSharer,
pSelf->m_bSilent ? 1119092736 : NULL,
0.828 * world->farplane_distance))
return;
}
pActorEnemy->m_fVisibility = 1.0;
pActorEnemy->m_fTotalVisibility = 1.0;
pActorEnemy->m_vLastKnownPos = pEnemy->origin;
if (m_fCurrentVisibility < 1.0)
{
m_iCurrentThreat = pActorEnemy->UpdateThreat(pSelf);
m_fCurrentVisibility = 1.0;
m_pCurrentEnemy = pEnemy;
}
}
}
bool ActorEnemySet::CaresAboutPerfectInfo
@ -337,7 +722,13 @@ bool ActorEnemySet::CaresAboutPerfectInfo
)
{
// FIXME: stub
STUB();
ActorEnemy *pActorEnemy = ActorEnemySet::AddPotentialEnemy(pEnemy);
if (pActorEnemy)
{
if (pActorEnemy->m_fTotalVisibility < 1.0 || (pEnemy->origin - pActorEnemy->m_vLastKnownPos).lengthSquared() > 262144)
{
return true;
}
}
return false;
}

View file

@ -22,6 +22,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// actorenemy.h
#ifndef __ACTORENEMY_H__
#define __ACTORENEMY_H__
#include "g_local.h"
class Actor;
@ -116,3 +119,5 @@ inline void ActorEnemySet::Archive
arc.ArchiveFloat( &m_fCurrentVisibility );
arc.ArchiveInteger( &m_iCurrentThreat );
}
#endif /* actorenemy.h */

View file

@ -63,7 +63,7 @@ bool ActorPath::DoesTheoreticPathExist
float maxPath,
float *vLeashHome,
float fLeashDistSquared
) const
)
{
return PathSearch::FindPath( start, end, ent, maxPath, NULL, 0, m_FallHeight ) != 0;

View file

@ -55,7 +55,7 @@ public:
~ActorPath();
void Clear( void );
bool DoesTheoreticPathExist( float *start, float *end, class SimpleActor *ent, float maxPath, float *vLeashHome, float fLeashDistSquared ) const;
bool DoesTheoreticPathExist( float *start, float *end, class SimpleActor *ent, float maxPath, float *vLeashHome, float fLeashDistSquared );
void FindPath( float *start, float *end, Entity *ent, float maxPath, float *vLeashHome, float fLeashDistSquared );
void FindPathAway( float *start, float *avoid, float *vPreferredDir, Entity *ent, float fMinSafeDist, float *vLeashHome, float fLeashDistSquared );
void FindPathNear( float *start, float *nearby, Entity *ent, float maxPath, float fRadiusSquared, float *vLeashHome, float fLeashDistSquared );

View file

@ -957,6 +957,7 @@ void G_ClientBegin( gentity_t *ent, usercmd_t *cmd )
if( ent->inuse && ent->entity )
{
VectorClear(ent->client->cmd_angles);
// the client has cleared the client side viewangles upon
// connecting to the server, which is different than the
// state when the game is saved, so we need to compensate

View file

@ -464,23 +464,52 @@ SimpleEntity *G_FindTarget( SimpleEntity *ent, const char *name )
SimpleEntity *G_FindRandomSimpleTarget( const char *name )
{
SimpleEntity *found = NULL, *ent = NULL;
SimpleEntity *found = NULL, *ent = world;
int nFound = 0;
if (name && *name)
{
while (1)
while (true)
{
ent = world->GetNextEntity(name, ent);
if (!ent)
{
break;
}
rand();
found = ent;
if (++nFound * rand() <= 0x7FFF)
{
found = ent;
}
}
}
return found;
}
Entity *G_FindRandomTarget( const char *name )
{
SimpleEntity *found = NULL, *ent = world;
int nFound = 0;
if (name && *name)
{
while (true)
{
ent = world->GetNextEntity(name, ent);
if (!ent)
{
break;
}
if (ent->IsSubclassOfEntity() && ++nFound * rand() <= 0x7FFF)
{
found = ent;
}
}
}
return (Entity *)found;
}
void G_TouchTriggers( Entity *ent )
{
int i;

View file

@ -141,6 +141,14 @@ SimpleEntity *G_FindRandomSimpleTarget(
const char *name
);
/* G_FindRandomSimpleTarget
*
* Find a random entity with the specified targetname.
*/
Entity *G_FindRandomTarget(
const char *name
);
/* G_GetClientNumber
*
* Gets the specified client number from an entity.

View file

@ -1095,7 +1095,7 @@ void Level::CleanUp( qboolean samemap, qboolean resetConfigStrings )
// Reset the boss health cvar
gi.Cvar_Set( "bosshealth", "0" );
// FIXME: Actor::ResetBodyQueue();
Actor::ResetBodyQueue();
if( world ) {
world->FreeTargetList();

View file

@ -7206,7 +7206,7 @@ void Player::Think
{
Actor *act = ( Actor * )pSent;
if( pSent->m_Enemy == this && act->m_ThinkStates[ 0 ] == THINKSTATE_ATTACK )
if( pSent->m_Enemy == this && act->IsAttacking())
{
m_bIsDisguised = false;
break;

View file

@ -4256,7 +4256,7 @@ void Sentient::EventSetThreatBias
if( !Q_stricmp( sBias, "ignoreme" ) )
{
m_iThreatBias = 0xFFFFE4C7;
m_iThreatBias = THREATBIAS_IGNOREME;
return;
}
}
@ -4560,7 +4560,7 @@ void Sentient::UpdateFootsteps
iAnimFlags |= gi.Anim_Flags(edict->tiki, iAnimNum);
}
}
//FIXME: macros
if ((iAnimFlags & 0xC00) != 3072)
{

View file

@ -87,6 +87,7 @@ class Item;
class InventoryItem;
class Ammo;
class Vehicle;
class VehicleTank;
class TurretGun;
#define MAX_ACTIVE_WEAPONS NUM_ACTIVE_WEAPONS
@ -95,6 +96,8 @@ class TurretGun;
#define TEAM_GERMAN 0
#define TEAM_AMERICAN 1
#define THREATBIAS_IGNOREME 0xFFFFE4C7
typedef SafePtr< Weapon > WeaponPtr;
class ActiveWeapon : public Class
@ -342,9 +345,9 @@ class Sentient : public Animate
void PutawayWeapon( Event *ev );
void WeaponCommand( Event *ev );
VehicleTank *GetVehicleTank( void );
void UpdateFootsteps( void );
void SetMaxMouthAngle( Event *ev );

File diff suppressed because it is too large Load diff

View file

@ -22,6 +22,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// simpleactor.h: Base class for character AI.
#ifndef __SIMPLEACTOR_H__
#define __SIMPLEACTOR_H__
#include "weapon.h"
#include "sentient.h"
#include "container.h"
@ -31,6 +34,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "characterstate.h"
#include "actorpath.h"
enum eEmotionMode {
EMOTION_NONE,
EMOTION_NEUTRAL,
EMOTION_WORRY,
EMOTION_PANIC,
EMOTION_FEAR,
EMOTION_DISGUST,
EMOTION_ANGER,
EMOTION_AIMING,
EMOTION_DETERMINED,
EMOTION_DEAD,
EMOTION_CURIOUS
};
class SimpleActor;
typedef SafePtr<SimpleActor> SimpleActorPtr;
@ -66,7 +82,7 @@ public:
Vector watch_offset;
bool m_bThink;
int m_PainTime;
int m_eEmotionMode;
eEmotionMode m_eEmotionMode;
float m_fAimLimit_up;
float m_fAimLimit_down;
int m_ChangeMotionAnimIndex;
@ -129,7 +145,7 @@ public:
void SetPath( Vector vDestPos, const char *description, int iMaxDirtyTime, float *vLeashHome, float fLeashDistSquared );
void SetPath( SimpleEntity *pDestNode, char *description, int iMaxDirtyTime );
void SetPathWithinDistance( Vector vDestPos, char *description, float fMaxPath, int iMaxDirtyTime );
void FindPathAway( vec3_t vAwayFrom, vec3_t vDirPreferred, float fMinSafeDist );
void FindPathAway( vec_t *vAwayFrom, vec_t *vDirPreferred, float fMinSafeDist );
void ClearPath( void );
bool PathComplete( void ) const;
bool PathExists( void ) const;
@ -232,8 +248,10 @@ public:
void Anim_RunToDive( int eAnimMode );
void Anim_RunToFlee( int eAnimMode );
void Anim_RunToInOpen( int eAnimMode );
void Anim_Emotion( int eEmotionMode );
void Anim_Emotion( eEmotionMode eEmotMode );
void Anim_Say( const_str csSayAnimScript, int iMinTimeSinceLastSay, bool bCanInterrupt );
void Anim_FullBody( const_str csFullBodyAnim, int eAnimMode );
virtual const char *DumpCallTrace( const char *pszFmt, ... ) const;
};
#endif /* simpleactor.h */

View file

@ -422,10 +422,11 @@ Listener *SpawnArgs::SpawnInternal( void )
}
}
if( g_spawnai->integer )
if( !g_spawnai->integer )
{
value = getArg( "classname", NULL );
//dont spawn ai_* if g_spawnai is 0
if( value )
{
if( !Q_stricmpn( value, "ai_", 3 ) )

View file

@ -1068,7 +1068,12 @@ void ScriptThreadLabel::GetScriptValue(ScriptVariable *var)
bool ScriptThreadLabel::IsSet( void )
{
return m_Script != NULL ? true : false;
return m_Script != NULL;
}
bool ScriptThreadLabel::IsFile(const_str filename)
{
return m_Script && m_Script->ConstFilename() == filename && m_Label == STRING_EMPTY;
}
void ScriptThreadLabel::Archive( Archiver& arc )

View file

@ -171,11 +171,25 @@ public:
bool TrySetScript( const_str label );
bool TrySetScript( const char *label );
bool IsSet(void);
bool IsFile(const_str filename);
void GetScriptValue(ScriptVariable *var);
bool IsSet( void );
void Archive( Archiver& arc );
friend bool operator==(const ScriptThreadLabel& a, const ScriptThreadLabel& b);
};
inline bool operator==
(
const ScriptThreadLabel& a,
const ScriptThreadLabel& b
)
{
return a.m_Label == b.m_Label && a.m_Script == b.m_Script;
}
#endif

View file

@ -924,6 +924,61 @@ float LerpAngle (float from, float to, float frac) {
return a;
}
static float fNoise1Arr[514];
static int iNoise1Arr[256];
static void init(void)
{
//This is an ugly func I wont bother variable naming.
int i;
for (i = 0; i < 256; i++)
{
iNoise1Arr[i] = i;
fNoise1Arr[i] = (rand() % 512 - 256) * 0.00390625;
}
int v21, v22;
for (int j = i - 1; j; iNoise1Arr[v22 % 256] = v21)
{
v21 = iNoise1Arr[j];
v22 = rand();
iNoise1Arr[j--] = iNoise1Arr[v22 % 256];
}
for (size_t k = 0; k < 258; k++)
{
fNoise1Arr[k + 256] = fNoise1Arr[k];
}
}
static int start = 1;
float noise1(float arg)
{
/*
* This is an ugly func I wont bother variable naming.
*vec_t vec;
float u, t, sx, rx1, rx0;
int bx0;*/
if (start)
{
init();
start = 0;
}
double v1; // st7
int v2; // eax
double v3; // st7
float v5; // [esp+4h] [ebp+4h]
v1 = arg + 4096.0;
v2 = (unsigned __int8)(signed __int64)v1;
v3 = v1 - (double)(signed int)(signed __int64)v1;
v5 = v3 * fNoise1Arr[iNoise1Arr[v2]];
return ((v3 - 1.0) * fNoise1Arr[iNoise1Arr[(unsigned __int8)(v2 + 1)]] - v5) * ((3.0 - (v3 + v3)) * (v3 * v3))
+ v5;
}
/*
================

View file

@ -794,6 +794,8 @@ float erandom( float mean );
void vectoangles( const vec3_t value1, vec3_t angles );
void VectorToAngles( const vec3_t vec, vec3_t angles );
void AnglesToAxis( const vec3_t angles, vec3_t axis[3] );
static void init( void );
float noise1(float arg);
void R_ConcatRotations( float in1[ 3 ][ 3 ], float in2[ 3 ][ 3 ], float out[ 3 ][ 3 ] );
void R_ConcatTransforms( float in1[ 3 ][ 4 ], float in2[ 3 ][ 4 ], float out[ 3 ][ 4 ] );

View file

@ -166,9 +166,9 @@ typedef enum {
} netadrtype_t;
typedef enum {
// NS_MASTER,
NS_SERVER,
NS_CLIENT
//NS_MASTER,
NS_CLIENT,
NS_SERVER
} netsrc_t;
typedef struct {