mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-20 20:50:58 +02:00
Quake 4 integrated with DoomRTX
This commit is contained in:
@@ -0,0 +1,419 @@
|
||||
/*
|
||||
================
|
||||
Monster_Fatguy.cpp
|
||||
|
||||
AI for the fat guy on the putra level
|
||||
================
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "../Game_local.h"
|
||||
#include "../Projectile.h"
|
||||
|
||||
typedef struct monsterFattyChain_s {
|
||||
jointHandle_t orientationJoint;
|
||||
jointHandle_t attackJoint;
|
||||
bool out;
|
||||
idEntityPtr<idEntity> projectile;
|
||||
} monsterFattyChain_t;
|
||||
|
||||
class rvMonsterFatty : public idAI {
|
||||
public:
|
||||
|
||||
CLASS_PROTOTYPE( rvMonsterFatty );
|
||||
|
||||
rvMonsterFatty ( void ) {}
|
||||
~rvMonsterFatty ( void );
|
||||
|
||||
void InitSpawnArgsVariables ( void );
|
||||
void Spawn ( void );
|
||||
void Save ( idSaveGame *savefile ) const;
|
||||
void Restore ( idRestoreGame *savefile );
|
||||
|
||||
virtual bool UpdateAnimationControllers ( void );
|
||||
virtual bool CanPlayImpactEffect ( idEntity* attacker, idEntity* target ) { return false; };
|
||||
virtual void AddDamageEffect ( const trace_t &collision, const idVec3 &velocity, const char *damageDefName, idEntity* inflictor );
|
||||
|
||||
protected:
|
||||
|
||||
rvAIAction actionWhipAttack;
|
||||
|
||||
enum {
|
||||
CHAIN_LEFT,
|
||||
CHAIN_RIGHT,
|
||||
CHAIN_MAX
|
||||
};
|
||||
|
||||
monsterFattyChain_t chains[CHAIN_MAX];
|
||||
|
||||
float missHeight;
|
||||
|
||||
virtual bool CheckActions ( void );
|
||||
|
||||
void PlayAttackAnim ( const idVec3& target, int blendFrames );
|
||||
|
||||
void ResetAllChains ( void );
|
||||
void ChainIn ( int chain );
|
||||
void ChainOut ( int chain );
|
||||
|
||||
private:
|
||||
|
||||
// Custom actions
|
||||
bool CheckAction_WhipAttack ( rvAIAction* action, int animNum );
|
||||
|
||||
// Frame Commands
|
||||
stateResult_t Frame_LeftChainOut ( const stateParms_t& parms );
|
||||
stateResult_t Frame_LeftChainIn ( const stateParms_t& parms );
|
||||
|
||||
stateResult_t Frame_RightChainOut ( const stateParms_t& parms );
|
||||
stateResult_t Frame_RightChainIn ( const stateParms_t& parms );
|
||||
|
||||
// Torso States
|
||||
stateResult_t State_Torso_WhipAttack ( const stateParms_t& parms );
|
||||
|
||||
CLASS_STATES_PROTOTYPE ( rvMonsterFatty );
|
||||
};
|
||||
|
||||
CLASS_DECLARATION( idAI, rvMonsterFatty )
|
||||
END_CLASS
|
||||
|
||||
/*
|
||||
================
|
||||
rvMonsterFatty::~rvMonsterFatty
|
||||
================
|
||||
*/
|
||||
rvMonsterFatty::~rvMonsterFatty ( void ) {
|
||||
ResetAllChains ( );
|
||||
}
|
||||
|
||||
void rvMonsterFatty::InitSpawnArgsVariables ( void )
|
||||
{
|
||||
chains[CHAIN_LEFT].orientationJoint = animator.GetJointHandle ( spawnArgs.GetString ( "joint_leftChain", "chainb1" ) );
|
||||
chains[CHAIN_LEFT].attackJoint = animator.GetJointHandle ( spawnArgs.GetString ( "joint_leftChainAttack", "hookb" ) );
|
||||
|
||||
chains[CHAIN_RIGHT].orientationJoint = animator.GetJointHandle ( spawnArgs.GetString ( "joint_rightChain", "chaina1" ) );
|
||||
chains[CHAIN_RIGHT].attackJoint = animator.GetJointHandle ( spawnArgs.GetString ( "joint_rightChainAttack", "hooka" ) );
|
||||
|
||||
missHeight = spawnArgs.GetFloat ( "missHeight", "72" );
|
||||
}
|
||||
/*
|
||||
================
|
||||
rvMonsterFatty::Spawn
|
||||
================
|
||||
*/
|
||||
void rvMonsterFatty::Spawn ( void ) {
|
||||
// Custom actions
|
||||
actionWhipAttack.Init ( spawnArgs, "action_whipAttack", "Torso_WhipAttack", AIACTIONF_ATTACK );
|
||||
|
||||
// Cache joints
|
||||
chains[CHAIN_LEFT].out = false;
|
||||
chains[CHAIN_LEFT].projectile = NULL;
|
||||
|
||||
chains[CHAIN_RIGHT].out = false;
|
||||
chains[CHAIN_RIGHT].projectile = NULL;
|
||||
|
||||
InitSpawnArgsVariables();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvMonsterFatty::Save
|
||||
================
|
||||
*/
|
||||
void rvMonsterFatty::Save ( idSaveGame *savefile ) const {
|
||||
int i;
|
||||
|
||||
actionWhipAttack.Save( savefile );
|
||||
|
||||
for ( i = 0; i < CHAIN_MAX; i ++ ) {
|
||||
savefile->WriteBool( chains[i].out );
|
||||
chains[i].projectile.Save ( savefile );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvMonsterFatty::Restore
|
||||
================
|
||||
*/
|
||||
void rvMonsterFatty::Restore ( idRestoreGame *savefile ) {
|
||||
int i;
|
||||
|
||||
actionWhipAttack.Restore( savefile );
|
||||
|
||||
for ( i = 0; i < CHAIN_MAX; i ++ ) {
|
||||
savefile->ReadBool( chains[i].out );
|
||||
chains[i].projectile.Restore ( savefile );
|
||||
}
|
||||
|
||||
InitSpawnArgsVariables();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvMonsterFatty::UpdateAnimationControllers
|
||||
================
|
||||
*/
|
||||
bool rvMonsterFatty::UpdateAnimationControllers ( void ) {
|
||||
if ( !idAI::UpdateAnimationControllers ( ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( enemy.ent && CheckFOV ( enemy.lastKnownPosition ) ) {
|
||||
int i;
|
||||
idVec3 origin;
|
||||
idMat3 axis;
|
||||
idVec3 dir;
|
||||
idVec3 localDir;
|
||||
idVec3 target;
|
||||
|
||||
if ( enemy.ent->IsType ( idActor::GetClassType ( ) ) ) {
|
||||
target = static_cast<idActor*>(enemy.ent.GetEntity())->GetEyePosition ( );
|
||||
} else {
|
||||
target = enemy.ent->GetPhysics()->GetOrigin ( );
|
||||
}
|
||||
|
||||
if ( !IsEnemyVisible ( ) ) {
|
||||
target -= enemy.ent->GetPhysics()->GetGravityNormal() * missHeight;
|
||||
}
|
||||
|
||||
for ( i = 0; i < CHAIN_MAX; i ++ ) {
|
||||
if ( !chains[i].out ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
animator.ClearJoint ( chains[i].orientationJoint );
|
||||
GetJointWorldTransform ( chains[i].orientationJoint, gameLocal.time, origin, axis );
|
||||
dir = target - origin;
|
||||
dir.Normalize ( );
|
||||
axis.ProjectVector ( dir, localDir );
|
||||
animator.SetJointAxis ( chains[i].orientationJoint, JOINTMOD_LOCAL, localDir.ToMat3() );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvMonsterFatty::AddDamageEffect
|
||||
================
|
||||
*/
|
||||
void rvMonsterFatty::AddDamageEffect ( const trace_t &collision, const idVec3 &velocity, const char *damageDefName, idEntity* inflictor ) {
|
||||
// If there are still shields remaining then play a shield effect at the impact point
|
||||
/*
|
||||
idVec3 dir;
|
||||
dir = collision.c.point - GetPhysics()->GetCenterMass ();
|
||||
PlayEffect ( "fx_shield", collision.c.point, dir.ToMat3(), false, vec3_origin, true );
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvMonsterFatty::CheckAction_WhipAttack
|
||||
================
|
||||
*/
|
||||
bool rvMonsterFatty::CheckAction_WhipAttack ( rvAIAction* action, int animNum ) {
|
||||
if ( !enemy.ent ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvMonsterFatty::CheckActions
|
||||
================
|
||||
*/
|
||||
bool rvMonsterFatty::CheckActions ( void ) {
|
||||
if ( PerformAction ( &actionWhipAttack, (checkAction_t)&rvMonsterFatty::CheckAction_WhipAttack, NULL ) ) {
|
||||
return true;
|
||||
}
|
||||
return idAI::CheckActions ( );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvMonsterFatty::PlayAttackAnim
|
||||
================
|
||||
*/
|
||||
void rvMonsterFatty::PlayAttackAnim ( const idVec3& target, int blendFrames ) {
|
||||
idVec3 dir;
|
||||
idVec3 localDir;
|
||||
float yaw;
|
||||
const char* animName;
|
||||
|
||||
// Get the local direction vector
|
||||
dir = target - GetPhysics()->GetOrigin();
|
||||
dir.Normalize ( );
|
||||
viewAxis.ProjectVector( dir, localDir );
|
||||
|
||||
// Get the yaw relative to forward
|
||||
yaw = idMath::AngleNormalize180 ( localDir.ToAngles ( )[YAW] );
|
||||
|
||||
if ( yaw < -45.0f ) {
|
||||
animName = "attack4b";
|
||||
} else if ( yaw < -20.0f ) {
|
||||
animName = "attack3b";
|
||||
} else if ( yaw < -5.0f ) {
|
||||
animName = "attack5r";
|
||||
} else if ( yaw < 5.0f ) {
|
||||
animName = "attack5";
|
||||
} else if ( yaw < 20.0f ) {
|
||||
animName = "attack5l";
|
||||
} else if ( yaw < 45.0f ) {
|
||||
animName = "attack2b";
|
||||
} else{
|
||||
animName = "attack1b";
|
||||
}
|
||||
|
||||
PlayAnim ( ANIMCHANNEL_TORSO, animName, blendFrames );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvMonsterFatty::ChainOut
|
||||
================
|
||||
*/
|
||||
void rvMonsterFatty::ChainOut ( int chain ) {
|
||||
idEntity* ent;
|
||||
idProjectile* proj;
|
||||
|
||||
gameLocal.SpawnEntityDef( *gameLocal.FindEntityDefDict ( spawnArgs.GetString ( "def_attack_hook" ) ), &ent, false );
|
||||
proj = dynamic_cast<idProjectile*>(ent);
|
||||
if ( !proj ) {
|
||||
delete ent;
|
||||
return;
|
||||
}
|
||||
|
||||
chains[chain].out = true;
|
||||
|
||||
proj->Create ( this, vec3_origin, idVec3(0,0,1) );
|
||||
proj->Launch ( vec3_origin, idVec3(0,0,1), vec3_origin );
|
||||
|
||||
chains[chain].projectile = proj;
|
||||
ent->BindToJoint ( this, chains[chain].attackJoint, false );
|
||||
ent->SetOrigin ( vec3_origin );
|
||||
ent->SetAxis ( mat3_identity );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvMonsterFatty::ChainIn
|
||||
================
|
||||
*/
|
||||
void rvMonsterFatty::ChainIn ( int chain ) {
|
||||
chains[chain].out = false;
|
||||
if ( chains[chain].projectile ) {
|
||||
delete chains[chain].projectile;
|
||||
chains[chain].projectile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvMonsterFatty::ResetChains
|
||||
================
|
||||
*/
|
||||
void rvMonsterFatty::ResetAllChains ( void ) {
|
||||
int i;
|
||||
|
||||
animator.ClearAllJoints ( );
|
||||
|
||||
for ( i = 0; i < CHAIN_MAX; i ++ ) {
|
||||
ChainIn ( i );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
States
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
CLASS_STATES_DECLARATION ( rvMonsterFatty )
|
||||
STATE ( "Torso_WhipAttack", rvMonsterFatty::State_Torso_WhipAttack )
|
||||
|
||||
STATE ( "Frame_LeftChainOut", rvMonsterFatty::Frame_LeftChainOut )
|
||||
STATE ( "Frame_LeftChainIn", rvMonsterFatty::Frame_LeftChainIn )
|
||||
|
||||
STATE ( "Frame_RightChainOut", rvMonsterFatty::Frame_RightChainOut )
|
||||
STATE ( "Frame_RightChainIn", rvMonsterFatty::Frame_RightChainIn )
|
||||
END_CLASS_STATES
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
rvMonsterFatty::State_Torso_WhipAttack
|
||||
================
|
||||
*/
|
||||
stateResult_t rvMonsterFatty::State_Torso_WhipAttack ( const stateParms_t& parms ) {
|
||||
enum {
|
||||
STAGE_ATTACK,
|
||||
STAGE_ATTACK_WAIT,
|
||||
};
|
||||
switch ( parms.stage ) {
|
||||
case STAGE_ATTACK: {
|
||||
if ( !enemy.ent ) {
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
// Predict a bit
|
||||
PlayAttackAnim ( enemy.ent->GetEyePosition(), parms.blendFrames );
|
||||
|
||||
return SRESULT_STAGE ( STAGE_ATTACK_WAIT );
|
||||
}
|
||||
|
||||
case STAGE_ATTACK_WAIT:
|
||||
if ( AnimDone ( ANIMCHANNEL_TORSO, parms.blendFrames ) ) {
|
||||
ResetAllChains ( );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
return SRESULT_WAIT;
|
||||
}
|
||||
return SRESULT_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvMonsterFatty::Frame_LeftChainOut
|
||||
================
|
||||
*/
|
||||
stateResult_t rvMonsterFatty::Frame_LeftChainOut ( const stateParms_t& parms ) {
|
||||
ChainOut ( CHAIN_LEFT );
|
||||
return SRESULT_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvMonsterFatty::Frame_LeftChainIn
|
||||
================
|
||||
*/
|
||||
stateResult_t rvMonsterFatty::Frame_LeftChainIn ( const stateParms_t& parms ) {
|
||||
ChainIn ( CHAIN_LEFT );
|
||||
return SRESULT_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvMonsterFatty::Frame_RightChainOut
|
||||
================
|
||||
*/
|
||||
stateResult_t rvMonsterFatty::Frame_RightChainOut ( const stateParms_t& parms ) {
|
||||
ChainOut ( CHAIN_RIGHT );
|
||||
return SRESULT_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvMonsterFatty::Frame_RightChainIn
|
||||
================
|
||||
*/
|
||||
stateResult_t rvMonsterFatty::Frame_RightChainIn ( const stateParms_t& parms ) {
|
||||
ChainIn ( CHAIN_RIGHT );
|
||||
return SRESULT_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user