mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-21 21:16:22 +02:00
Quake 4 integrated with DoomRTX
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,416 @@
|
||||
//----------------------------------------------------------------
|
||||
// Vehicle.h
|
||||
//
|
||||
// Copyright 2002-2004 Raven Software
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#ifndef __GAME_VEHICLE_H__
|
||||
#define __GAME_VEHICLE_H__
|
||||
|
||||
class rvVehiclePosition {
|
||||
public:
|
||||
|
||||
rvVehiclePosition( void );
|
||||
virtual ~rvVehiclePosition( void );
|
||||
|
||||
usercmd_t mInputCmd;
|
||||
idAngles mInputAngles;
|
||||
usercmd_t mOldInputCmd;
|
||||
idAngles mOldInputAngles;
|
||||
int mOldInputFlags;
|
||||
|
||||
int mCurrentWeapon;
|
||||
|
||||
idEntityPtr<idActor> mDriver;
|
||||
idEntityPtr<rvVehicle> mParent;
|
||||
|
||||
rvVehiclePartList_t mParts;
|
||||
rvVehiclePartList_t mWeapons;
|
||||
|
||||
idVec3 mEyeOrigin;
|
||||
idMat3 mEyeAxis;
|
||||
|
||||
jointHandle_t mEyeJoint;
|
||||
idVec3 mEyeOffset;
|
||||
idMat3 mEyeJointTransform;
|
||||
idAngles mDeltaEyeAxisScale;
|
||||
int mEyeJointAxisMap[3];
|
||||
int mEyeJointDirMap[3];
|
||||
|
||||
idMat3 mAxisOffset;
|
||||
|
||||
jointHandle_t mDriverJoint;
|
||||
idVec3 mDriverOffset;
|
||||
idMat3 mDriverJointTransform;
|
||||
idAngles mDeltaDriverAxisScale;
|
||||
int mDriverJointAxisMap[3];
|
||||
int mDriverJointDirMap[3];
|
||||
|
||||
idVec3 mExitPosOffset;
|
||||
idMat3 mExitAxisOffset;
|
||||
|
||||
idStr mDriverAnim;
|
||||
|
||||
idStr mInternalSurface;
|
||||
|
||||
struct positionFlags_s {
|
||||
bool inputValid :1;
|
||||
bool engine :1;
|
||||
bool driverVisible :1;
|
||||
bool depthHack :1;
|
||||
bool internalView :1;
|
||||
bool bindDriver :1;
|
||||
bool stalled :1;
|
||||
} fl;
|
||||
|
||||
void Init ( rvVehicle* parent, const idDict& args );
|
||||
|
||||
int AddPart ( const idTypeInfo &classdef, const idDict& args );
|
||||
rvVehiclePart* GetPart ( int partIndex );
|
||||
|
||||
bool IsOccupied ( void ) const;
|
||||
bool IsEngine ( void ) const;
|
||||
|
||||
bool SetDriver ( idActor* driver );
|
||||
void SetInput ( const usercmd_t& cmd, const idAngles& newAngles );
|
||||
void GetInput ( usercmd_t& cmd, idAngles& newAngles ) const;
|
||||
|
||||
bool EjectDriver ( bool force = false );
|
||||
|
||||
void RunPrePhysics ( void );
|
||||
void RunPostPhysics ( void );
|
||||
|
||||
void SelectWeapon ( int weapon );
|
||||
|
||||
void UpdateHUD ( idUserInterface* gui );
|
||||
void UpdateCursorGUI ( idUserInterface* gui );
|
||||
void UpdateInternalView ( bool force = false );
|
||||
|
||||
virtual idMat3 GetAxis ( void ) const;
|
||||
virtual idVec3 GetOrigin ( const idVec3& offset = vec3_zero ) const;
|
||||
|
||||
const idVec3& GetEyeOrigin ( void ) const;
|
||||
const idMat3& GetEyeAxis ( void ) const;
|
||||
rvVehicle* GetParent ( void ) const;
|
||||
idActor* GetDriver ( void ) const;
|
||||
|
||||
void Save ( idSaveGame* savefile ) const;
|
||||
void Restore ( idRestoreGame* savefile );
|
||||
|
||||
void WriteToSnapshot ( idBitMsgDelta &msg ) const;
|
||||
void ReadFromSnapshot ( const idBitMsgDelta &msg );
|
||||
|
||||
void GetEyePosition ( idVec3& origin, idMat3& axis ) const;
|
||||
void GetDriverPosition ( idVec3& origin, idMat3& axis ) const;
|
||||
void GetPosition ( const jointHandle_t jointHandle, const idVec3& offset, const idMat3& jointTransform, const idAngles& scale, const int axisMap[], const int dirMap[], idVec3& origin, idMat3& axis ) const;
|
||||
|
||||
void FireWeapon ( void );
|
||||
|
||||
rvVehicleWeapon * GetWeapon ( int weaponIndex );
|
||||
rvVehicleWeapon * GetActiveWeapon ( void );
|
||||
|
||||
private:
|
||||
|
||||
void SetParts ( const idDict& args );
|
||||
void ActivateParts ( bool active );
|
||||
|
||||
int mSoundPart;
|
||||
float mSoundMaxSpeed;
|
||||
};
|
||||
|
||||
typedef struct rvVehicleFuncs_s {
|
||||
rvScriptFuncUtility enter; // script to run when the vehicle becomes occupied
|
||||
rvScriptFuncUtility exit; // script to run when the vehicle becomes unoccupied
|
||||
} rvVehicleFuncs_t;
|
||||
|
||||
class rvVehicle : public idActor {
|
||||
public:
|
||||
|
||||
CLASS_PROTOTYPE( rvVehicle );
|
||||
|
||||
rvVehicle ( void );
|
||||
~rvVehicle ( void );
|
||||
|
||||
void Spawn ( void );
|
||||
void Think ( void );
|
||||
bool Give ( const char *statname, const char *value );
|
||||
|
||||
virtual void Hide ( void );
|
||||
virtual void Show ( void );
|
||||
|
||||
void ClientPredictionThink ( void );
|
||||
void WriteToSnapshot ( idBitMsgDelta &msg ) const;
|
||||
void ReadFromSnapshot ( const idBitMsgDelta &msg );
|
||||
|
||||
void Save ( idSaveGame *savefile ) const;
|
||||
void Restore ( idRestoreGame *savefile );
|
||||
|
||||
virtual void Damage ( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
|
||||
virtual void Killed ( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
|
||||
virtual void AddDamageEffect ( const trace_t &collision, const idVec3 &velocity, const char *damageDefName, idEntity* inflictor );
|
||||
|
||||
virtual bool GetPhysicsToVisualTransform ( idVec3 &origin, idMat3 &axis ) { return false; }
|
||||
|
||||
virtual const idMat3& GetAxis ( int id = 0 ) const;
|
||||
virtual const idVec3& GetOrigin ( int id = 0 ) const;
|
||||
|
||||
virtual int AddDriver ( int position, idActor* driver );
|
||||
virtual bool RemoveDriver ( int position, bool force = false );
|
||||
virtual void EjectAllDrivers ( bool force = false );
|
||||
rvVehiclePosition* GetPosition ( int index );
|
||||
const rvVehiclePosition* GetPosition ( int index ) const;
|
||||
int GetPositionIndex ( const rvVehiclePosition* position ) const;
|
||||
|
||||
int GetNumPositions ( void ) const;
|
||||
int GetNumDrivers ( void ) const;
|
||||
bool HasOpenPositions ( void ) const;
|
||||
|
||||
bool Collide ( const trace_t &collision, const idVec3 &velocity );
|
||||
|
||||
virtual void UpdateState ();
|
||||
|
||||
float GetEngineOffTime ( void ) const;
|
||||
float GetEngineOnTime ( void ) const;
|
||||
|
||||
bool IsFlipped ( void ) const;
|
||||
bool IsFrozen ( void ) const;
|
||||
bool IsLocked ( void ) const;
|
||||
bool HasDrivers ( void ) const;
|
||||
|
||||
bool IsShootingEnabled ( void ) const;
|
||||
bool IsMovementEnabled ( void ) const;
|
||||
|
||||
void Lock ( void );
|
||||
void Unlock ( void );
|
||||
|
||||
void AutoRight ( idEntity* activator );
|
||||
|
||||
virtual bool FindClearExitPoint ( int pos, idVec3& origin, idMat3& axis ) const;
|
||||
void GetDriverPosition ( int position, idVec3& origin, idMat3& axis );
|
||||
virtual void GetEyePosition ( int position, idVec3& origin, idMat3& axis );
|
||||
void DrawHUD ( int position );
|
||||
idUserInterface* GetHud ( void );
|
||||
void UpdateCursorGUI ( int position, idUserInterface* ui );
|
||||
virtual void SetInput ( int position, const usercmd_t& cmd, const idAngles& newAngles );
|
||||
void GetInput ( int position, usercmd_t& cmd, idAngles& newAngles ) const;
|
||||
|
||||
void IssueHazardWarning ( void );
|
||||
void IssueLockedWarning ( void );
|
||||
|
||||
void AddToBounds ( const idVec3& vec );
|
||||
|
||||
virtual void UpdateHUD ( idActor* driver, idUserInterface* gui ) {}
|
||||
|
||||
float FocusLength ( void ) const { return spawnArgs.GetFloat("focusLength_enter", "60"); }
|
||||
|
||||
bool IsAutoCorrecting ( void ) const { return autoCorrectionBegin != 0; }
|
||||
bool IsStalled ( void ) const { return vfl.stalled; }
|
||||
|
||||
void OnEnter ( void ) { funcs.enter.CallFunc( NULL ); fl.exitedVehicle=false; };
|
||||
void OnExit ( void ) { if ( !fl.exitedVehicle ) { fl.exitedVehicle=true; funcs.exit.CallFunc( NULL );} };
|
||||
|
||||
bool IsStrafing ( void ) const { return vfl.strafe; }
|
||||
// void PlayAnim ( int channel, const char *name, int blendFrames );
|
||||
|
||||
virtual void GuidedProjectileIncoming( idGuidedProjectile * projectile );
|
||||
protected:
|
||||
|
||||
void SelectWeapon ( int weapon );
|
||||
|
||||
void UpdateDrivers ( int delta );
|
||||
virtual void UpdateHUD ( int position, idUserInterface* gui );
|
||||
|
||||
void SetPositions ( void );
|
||||
|
||||
void SetCombatModel ( void );
|
||||
void LinkCombat ( void );
|
||||
|
||||
// twhitaker:
|
||||
friend class rvVehicleDriver;
|
||||
virtual void RunPrePhysics ( void ) { }
|
||||
virtual void RunPostPhysics ( void ) { }
|
||||
|
||||
|
||||
idList<rvVehiclePosition> positions;
|
||||
int drivers;
|
||||
|
||||
idUserInterface * hud;
|
||||
|
||||
float crashSpeedSmall;
|
||||
float crashSpeedMedium;
|
||||
float crashSpeedLarge;
|
||||
idStr crashDamage;
|
||||
rvClientEffectPtr crashEffect;
|
||||
int crashNextSound;
|
||||
int crashTime;
|
||||
|
||||
float autoRightDir;
|
||||
bool autoRight;
|
||||
|
||||
// twhitaker: for rvVehicleDriver, to avoid getting stuck.
|
||||
unsigned autoCorrectionBegin; // time when obstacle avoidance state began (0 if not correcting)
|
||||
|
||||
struct vehicleFlags_s {
|
||||
bool forward :1;
|
||||
bool backward :1;
|
||||
bool left :1;
|
||||
bool right :1;
|
||||
bool driver :1;
|
||||
bool locked :1;
|
||||
bool godmode :1;
|
||||
bool frozen :1;
|
||||
bool disableWeapons :1;
|
||||
bool disableMovement :1;
|
||||
bool scripted :1;
|
||||
bool endWithIdle :1;
|
||||
bool flipEject :1;
|
||||
bool dead :1;
|
||||
bool strafe :1;
|
||||
bool missileWarningOn :1;
|
||||
bool stalled :1;
|
||||
} vfl;
|
||||
|
||||
float damageStaticChance;
|
||||
|
||||
// Shields
|
||||
float shieldMaxHealth;
|
||||
idInterpolate<int> shieldHealth;
|
||||
int shieldHitTime;
|
||||
float shieldRegenTime;
|
||||
int shieldRegenDelay;
|
||||
idClipModel* shieldModel;
|
||||
|
||||
int healthRegenDelay;
|
||||
int healthRegenRate;
|
||||
idInterpolate<int> healthRegenAmount;
|
||||
|
||||
int hazardWarningTime;
|
||||
int lockWarningTime;
|
||||
int healthMax;
|
||||
int healthLow;
|
||||
int godModeDamage;
|
||||
|
||||
int cachedContents;
|
||||
|
||||
rvVehicleFuncs_t funcs;
|
||||
|
||||
float crashVelocitySmall;
|
||||
float crashVelocityMedium;
|
||||
float crashVelocityLarge;
|
||||
|
||||
bool alwaysImpactDamage;
|
||||
|
||||
void UpdateIncomingProjectiles( void );
|
||||
|
||||
public:
|
||||
idList< idEntityPtr< idGuidedProjectile > > incomingProjectiles;
|
||||
private:
|
||||
|
||||
void Event_Lock ( bool locked );
|
||||
void Event_IsLocked ( void );
|
||||
void Event_EnableWeapon ( void );
|
||||
void Event_DisableWeapon ( void );
|
||||
void Event_EnableMovement ( void );
|
||||
void Event_DisableMovement ( void );
|
||||
void Event_EnableClip ( void );
|
||||
void Event_DisableClip ( void );
|
||||
void Event_Activate ( idEntity* activator );
|
||||
void Event_LaunchProjectiles ( const idList<idStr>* parms );
|
||||
void Event_SetScript ( const char* scriptName, const char* funcName );
|
||||
void Event_SetHealth ( float health );
|
||||
void Event_HUDShockWarningOff( void );
|
||||
void Event_StalledRestart ( float shield, float damage );
|
||||
void Event_GetViewAngles ( void );
|
||||
|
||||
virtual void OnDeath ( void ) { }
|
||||
|
||||
stateResult_t State_Wait_Driver ( int blendFrames );
|
||||
|
||||
CLASS_STATES_PROTOTYPE( rvVehicle );
|
||||
};
|
||||
|
||||
/*
|
||||
===============
|
||||
rvVehiclePosition inlines
|
||||
===============
|
||||
*/
|
||||
|
||||
ID_INLINE bool rvVehiclePosition::IsOccupied ( void ) const { return mDriver.IsValid();}
|
||||
ID_INLINE bool rvVehiclePosition::IsEngine ( void ) const { return fl.engine; }
|
||||
ID_INLINE const idVec3& rvVehiclePosition::GetEyeOrigin ( void ) const { return mEyeOrigin; }
|
||||
ID_INLINE const idMat3& rvVehiclePosition::GetEyeAxis ( void ) const { return mEyeAxis; }
|
||||
ID_INLINE rvVehicle* rvVehiclePosition::GetParent ( void ) const { return mParent; }
|
||||
ID_INLINE idActor* rvVehiclePosition::GetDriver ( void ) const { return mDriver; }
|
||||
ID_INLINE rvVehiclePart* rvVehiclePosition::GetPart ( int partIndex ) { return mParts[partIndex]; }
|
||||
ID_INLINE rvVehicleWeapon* rvVehiclePosition::GetWeapon ( int weaponIndex ){ return ( weaponIndex >= 0 && weaponIndex < mWeapons.Num() ) ? static_cast<rvVehicleWeapon*>(mWeapons[weaponIndex]) : 0; }
|
||||
ID_INLINE rvVehicleWeapon* rvVehiclePosition::GetActiveWeapon ( void ) { return GetWeapon( mCurrentWeapon ); }
|
||||
|
||||
/*
|
||||
===============
|
||||
rvVehicle inlines
|
||||
===============
|
||||
*/
|
||||
|
||||
ID_INLINE bool rvVehicle::IsFlipped( void ) const {
|
||||
return (( !vfl.flipEject ) ? false :
|
||||
idMath::Fabs( idMath::AngleNormalize180( renderEntity.axis.ToAngles().roll ) ) > 60.f ||
|
||||
idMath::Fabs( idMath::AngleNormalize180( renderEntity.axis.ToAngles().pitch ) > 60.0f ));
|
||||
}
|
||||
|
||||
ID_INLINE bool rvVehicle::IsFrozen( void ) const {
|
||||
return vfl.frozen;
|
||||
}
|
||||
|
||||
ID_INLINE idUserInterface* rvVehicle::GetHud ( void ) {
|
||||
return hud;
|
||||
}
|
||||
|
||||
ID_INLINE bool rvVehicle::IsLocked ( void ) const {
|
||||
return vfl.locked || hazardWarningTime != 0;
|
||||
}
|
||||
|
||||
ID_INLINE rvVehiclePosition* rvVehicle::GetPosition ( int index ) {
|
||||
return &positions[index];
|
||||
}
|
||||
|
||||
ID_INLINE const rvVehiclePosition* rvVehicle::GetPosition ( int index ) const {
|
||||
return &positions[index];
|
||||
}
|
||||
|
||||
ID_INLINE void rvVehicle::SetInput ( int position, const usercmd_t& cmd, const idAngles& newAngles ) {
|
||||
GetPosition(position)->SetInput ( cmd, newAngles );
|
||||
}
|
||||
|
||||
ID_INLINE void rvVehicle::GetInput( int position, usercmd_t& cmd, idAngles& newAngles ) const {
|
||||
GetPosition(position)->GetInput( cmd, newAngles );
|
||||
}
|
||||
|
||||
ID_INLINE bool rvVehicle::HasDrivers ( void ) const {
|
||||
return drivers > 0;
|
||||
}
|
||||
|
||||
ID_INLINE void rvVehicle::AddToBounds ( const idVec3& vec ) {
|
||||
renderEntity.bounds.AddPoint ( (vec-renderEntity.origin) * GetPhysics()->GetAxis().Transpose() );
|
||||
}
|
||||
|
||||
ID_INLINE bool rvVehicle::IsShootingEnabled ( void ) const {
|
||||
return !vfl.disableWeapons;
|
||||
}
|
||||
|
||||
ID_INLINE bool rvVehicle::IsMovementEnabled ( void ) const {
|
||||
return !vfl.disableMovement;
|
||||
}
|
||||
|
||||
ID_INLINE int rvVehicle::GetNumPositions ( void ) const {
|
||||
return positions.Num();
|
||||
}
|
||||
|
||||
ID_INLINE int rvVehicle::GetNumDrivers ( void ) const {
|
||||
return drivers;
|
||||
}
|
||||
|
||||
ID_INLINE bool rvVehicle::HasOpenPositions ( void ) const {
|
||||
return GetNumPositions() > GetNumDrivers();
|
||||
}
|
||||
|
||||
#endif // __GAME_VEHICLE_H__
|
||||
@@ -0,0 +1,237 @@
|
||||
|
||||
// Vehicle.cpp
|
||||
//
|
||||
// Copyright 2002-2004 Raven Software
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#include "precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "../Game_local.h"
|
||||
#include "VehicleAnimated.h"
|
||||
|
||||
CLASS_DECLARATION( rvVehicle, rvVehicleAnimated )
|
||||
END_CLASS
|
||||
|
||||
rvVehicleAnimated::rvVehicleAnimated ( void ) {
|
||||
}
|
||||
|
||||
rvVehicleAnimated::~rvVehicleAnimated ( void ) {
|
||||
SetPhysics( NULL );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleAnimated::Spawn
|
||||
================
|
||||
*/
|
||||
void rvVehicleAnimated::Spawn( void ) {
|
||||
|
||||
turnRate = spawnArgs.GetFloat ( "turnRate", "90" );
|
||||
viewAngles = GetPhysics()->GetAxis ( ).ToAngles ( );
|
||||
viewAxis = viewAngles.ToMat3();
|
||||
|
||||
// Initialize the physics object
|
||||
physicsObj.SetSelf( this );
|
||||
physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f );
|
||||
physicsObj.SetContents( CONTENTS_BODY );
|
||||
physicsObj.SetClipMask( MASK_PLAYERSOLID|CONTENTS_VEHICLECLIP );
|
||||
physicsObj.SetMaxStepHeight( spawnArgs.GetFloat ( "stepheight", "14" ) );
|
||||
|
||||
// Start just a tad above the floor
|
||||
physicsObj.SetOrigin( GetPhysics()->GetOrigin() + idVec3( 0, 0, CM_CLIP_EPSILON ) );
|
||||
physicsObj.SetMass( spawnArgs.GetFloat( "mass", "100" ) );
|
||||
physicsObj.SetDelta( vec3_origin );
|
||||
|
||||
// Gravity
|
||||
idVec3 gravity = spawnArgs.GetVector( "gravityDir", "0 0 -1" );
|
||||
gravity *= g_gravity.GetFloat ( );
|
||||
physicsObj.SetGravity( gravity );
|
||||
SetPhysics( &physicsObj );
|
||||
|
||||
animator.RemoveOriginOffset( true );
|
||||
|
||||
additionalDelta.Zero();
|
||||
|
||||
BecomeActive( TH_THINK );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleAnimated::ClientPredictionThink
|
||||
================
|
||||
*/
|
||||
void rvVehicleAnimated::ClientPredictionThink ( void ) {
|
||||
Think();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleAnimated::Think
|
||||
================
|
||||
*/
|
||||
void rvVehicleAnimated::Think ( void ) {
|
||||
|
||||
rvVehicle::Think();
|
||||
|
||||
float rate = 0.0f;
|
||||
usercmd_t& cmd = positions[0].mInputCmd;
|
||||
idVec3 delta;
|
||||
|
||||
if( positions[0].IsOccupied() && !IsFrozen() && IsMovementEnabled() ) {
|
||||
|
||||
if (( g_vehicleMode.GetInteger() == 0 && !( cmd.buttons & BUTTON_STRAFE )) || // If we're in the old driving mode and we aren't strafing or...
|
||||
( g_vehicleMode.GetInteger() != 0 && ( cmd.buttons & BUTTON_STRAFE ))) // If we're in the new driving mode and we are strafing
|
||||
{
|
||||
rate = SignZero(cmd.forwardmove) * turnRate;
|
||||
rate *= idMath::MidPointLerp( 0.0f, 0.9f, 1.0f, idMath::Fabs(cmd.rightmove) / 127.0f );
|
||||
viewAngles.yaw += Sign(cmd.rightmove) * rate * MS2SEC(gameLocal.GetMSec());
|
||||
}
|
||||
}
|
||||
|
||||
viewAngles.Normalize360();
|
||||
animator.GetDelta( gameLocal.time - gameLocal.GetMSec(), gameLocal.time, delta );
|
||||
delta += additionalDelta;
|
||||
|
||||
idStr alignmentJoint;
|
||||
if ( g_vehicleMode.GetInteger() != 0 && spawnArgs.GetString( "alignment_joint", 0, alignmentJoint ) ) {
|
||||
idVec3 offset;
|
||||
idMat3 axis;
|
||||
GetJointWorldTransform( animator.GetJointHandle( alignmentJoint ), gameLocal.time, offset, axis );
|
||||
delta *= axis;
|
||||
} else {
|
||||
viewAxis = viewAngles.ToMat3() * physicsObj.GetGravityAxis();
|
||||
delta *= viewAxis;
|
||||
}
|
||||
|
||||
physicsObj.SetDelta( delta );
|
||||
additionalDelta.Zero();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleAnimated::GetAxis
|
||||
================
|
||||
*/
|
||||
const idMat3& rvVehicleAnimated::GetAxis( int id ) const {
|
||||
return viewAxis;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleAnimated::WriteToSnapshot
|
||||
================
|
||||
*/
|
||||
void rvVehicleAnimated::WriteToSnapshot( idBitMsgDelta &msg ) const {
|
||||
rvVehicle::WriteToSnapshot ( msg );
|
||||
|
||||
physicsObj.WriteToSnapshot( msg );
|
||||
msg.WriteFloat( viewAngles[0] );
|
||||
msg.WriteFloat( viewAngles[1] );
|
||||
msg.WriteFloat( viewAngles[2] );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleAnimated::ReadFromSnapshot
|
||||
================
|
||||
*/
|
||||
void rvVehicleAnimated::ReadFromSnapshot( const idBitMsgDelta &msg ) {
|
||||
rvVehicle::ReadFromSnapshot ( msg );
|
||||
|
||||
physicsObj.ReadFromSnapshot( msg );
|
||||
viewAngles[0] = msg.ReadFloat( );
|
||||
viewAngles[1] = msg.ReadFloat( );
|
||||
viewAngles[2] = msg.ReadFloat( );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleAnimated::Save
|
||||
================
|
||||
*/
|
||||
void rvVehicleAnimated::Save ( idSaveGame *savefile ) const {
|
||||
savefile->WriteVec3( storedPosition );
|
||||
|
||||
savefile->WriteStaticObject ( physicsObj );
|
||||
|
||||
savefile->WriteAngles ( viewAngles );
|
||||
savefile->WriteFloat ( turnRate );
|
||||
|
||||
// why are we writing out the viewAxis here???
|
||||
savefile->WriteMat3 ( viewAxis );
|
||||
|
||||
// TEMP
|
||||
animator.Save( savefile );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleAnimated::Restore
|
||||
================
|
||||
*/
|
||||
void rvVehicleAnimated::Restore ( idRestoreGame *savefile ) {
|
||||
savefile->ReadVec3( storedPosition );
|
||||
|
||||
physicsObj.SetSelf( this );
|
||||
physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f );
|
||||
savefile->ReadStaticObject ( physicsObj );
|
||||
RestorePhysics ( &physicsObj );
|
||||
physicsObj.EnableClip();
|
||||
|
||||
savefile->ReadAngles ( viewAngles );
|
||||
savefile->ReadFloat ( turnRate );
|
||||
|
||||
savefile->ReadMat3 ( viewAxis );
|
||||
|
||||
// TEMP - restore animator, because it was cleared when loading the AF
|
||||
animator.Restore( savefile );
|
||||
animator.GetJoints( &renderEntity.numJoints, &renderEntity.joints );
|
||||
animator.GetBounds( gameLocal.time, renderEntity.bounds );
|
||||
// TEMP
|
||||
|
||||
additionalDelta.Zero();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleAnimated::GetPhysicsToVisualTransform
|
||||
================
|
||||
*/
|
||||
bool rvVehicleAnimated::GetPhysicsToVisualTransform ( idVec3 &origin, idMat3 &axis ) {
|
||||
origin = modelOffset;
|
||||
axis = viewAxis;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleAnimated::RunPrePhysics
|
||||
================
|
||||
*/
|
||||
void rvVehicleAnimated::RunPrePhysics ( void ) {
|
||||
storedPosition = physicsObj.GetOrigin();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleAnimated::RunPostPhysics
|
||||
================
|
||||
*/
|
||||
void rvVehicleAnimated::RunPostPhysics ( void ) {
|
||||
|
||||
if ( autoCorrectionBegin + 3000 > static_cast<unsigned>( gameLocal.time )) {
|
||||
autoCorrectionBegin = 0;
|
||||
|
||||
idVec3 delta;
|
||||
idVec3 actualDelta = physicsObj.GetOrigin() - storedPosition;
|
||||
|
||||
animator.GetDelta( gameLocal.time - gameLocal.GetMSec(), gameLocal.time, delta );
|
||||
|
||||
if ( !autoCorrectionBegin && delta.LengthSqr() * 0.2f > actualDelta.LengthSqr() ) {
|
||||
autoCorrectionBegin = gameLocal.time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
//----------------------------------------------------------------
|
||||
// VehicleAnimated.h
|
||||
//
|
||||
// Copyright 2002-2004 Raven Software
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#ifndef __GAME_VEHICLEANIMATED_H__
|
||||
#define __GAME_VEHICLEANIMATED_H__
|
||||
|
||||
#include "Vehicle.h"
|
||||
#include "../physics/Physics_Monster.h"
|
||||
|
||||
class rvVehicleAnimated : public rvVehicle {
|
||||
public:
|
||||
|
||||
CLASS_PROTOTYPE( rvVehicleAnimated );
|
||||
|
||||
rvVehicleAnimated ( void );
|
||||
~rvVehicleAnimated ( void );
|
||||
|
||||
void Spawn ( void );
|
||||
void Think ( void );
|
||||
void Save ( idSaveGame *savefile ) const;
|
||||
void Restore ( idRestoreGame *savefile );
|
||||
|
||||
virtual const idMat3& GetAxis ( int id = 0 ) const;
|
||||
|
||||
void ClientPredictionThink ( void );
|
||||
void WriteToSnapshot ( idBitMsgDelta &msg ) const;
|
||||
void ReadFromSnapshot ( const idBitMsgDelta &msg );
|
||||
|
||||
virtual bool GetPhysicsToVisualTransform ( idVec3 &origin, idMat3 &axis );
|
||||
|
||||
protected:
|
||||
|
||||
// twhitaker:
|
||||
virtual void RunPrePhysics ( void );
|
||||
virtual void RunPostPhysics ( void );
|
||||
idVec3 storedPosition;
|
||||
// end twhitaker:
|
||||
|
||||
idPhysics_Monster physicsObj;
|
||||
|
||||
idAngles viewAngles;
|
||||
float turnRate;
|
||||
idVec3 additionalDelta;
|
||||
};
|
||||
|
||||
#endif // __GAME_VEHICLEANIMATED_H__
|
||||
@@ -0,0 +1,301 @@
|
||||
//----------------------------------------------------------------
|
||||
// VehicleController.cpp
|
||||
//
|
||||
// Copyright 2002-2004 Raven Software
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#include "precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "../Game_local.h"
|
||||
#include "VehicleController.h"
|
||||
#include "Vehicle.h"
|
||||
|
||||
/*
|
||||
=====================
|
||||
rvVehicleController::rvVehicleController
|
||||
=====================
|
||||
*/
|
||||
rvVehicleController::rvVehicleController ( void ) {
|
||||
mVehicle = NULL;
|
||||
//mDriver = NULL;
|
||||
mPosition = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
rvVehicleController::Save
|
||||
=====================
|
||||
*/
|
||||
void rvVehicleController::Save ( idSaveGame *savefile ) const {
|
||||
mVehicle.Save ( savefile );
|
||||
savefile->WriteInt ( mPosition );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
rvVehicleController::Restore
|
||||
=====================
|
||||
*/
|
||||
void rvVehicleController::Restore ( idRestoreGame *savefile ) {
|
||||
mVehicle.Restore ( savefile );
|
||||
savefile->ReadInt ( mPosition );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
rvVehicleController::Drive
|
||||
=====================
|
||||
*/
|
||||
bool rvVehicleController::Drive ( rvVehicle* vehicle, idActor* driver ) {
|
||||
assert ( vehicle && driver );
|
||||
|
||||
// Flip the vehicle back over?
|
||||
if ( vehicle->IsFlipped ( ) ) {
|
||||
vehicle->AutoRight ( vehicle );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add the driver to the vehicle and cache the position it was added.
|
||||
if ( -1 == (mPosition = vehicle->AddDriver ( 0, driver ) ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mVehicle = vehicle;
|
||||
|
||||
//twhitaker: for scripted callback events
|
||||
vehicle->OnEnter();
|
||||
|
||||
if ( driver->IsType( idPlayer::GetClassType() ) ) {
|
||||
idPlayer * player = static_cast< idPlayer *>( driver );
|
||||
|
||||
if ( player->GetHud() ) {
|
||||
GetHud()->Activate( true, gameLocal.time );
|
||||
GetHud()->HandleNamedEvent( "showExitmessage" );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
rvVehicleController::Eject
|
||||
=====================
|
||||
*/
|
||||
bool rvVehicleController::Eject ( bool force ) {
|
||||
if ( !GetVehicle() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( GetDriver()->IsType( idPlayer::GetClassType() ) ) {
|
||||
idPlayer * player = static_cast< idPlayer *>( GetDriver() );
|
||||
|
||||
if ( player->GetHud() ) {
|
||||
GetHud()->HandleNamedEvent( "hideExitmessage" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( mVehicle->RemoveDriver ( GetPosition(), force ) ) {
|
||||
mVehicle->OnExit();
|
||||
mVehicle = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
rvVehicleController::FindClearExitPoint
|
||||
=====================
|
||||
*/
|
||||
bool rvVehicleController::FindClearExitPoint( idVec3& origin, idMat3& axis ) const {
|
||||
return GetVehicle()->FindClearExitPoint( mPosition, origin, axis );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
rvVehicleController::KillVehicles
|
||||
=====================
|
||||
*/
|
||||
void rvVehicleController::KillVehicles ( void ) {
|
||||
KillEntities( idCmdArgs(), rvVehicle::GetClassType() );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
rvVehicleController::DrawHUD
|
||||
=====================
|
||||
*/
|
||||
void rvVehicleController::DrawHUD ( void ) {
|
||||
assert ( mVehicle );
|
||||
|
||||
if ( GetDriver() && GetDriver()->IsType( idPlayer::GetClassType() ) ) {
|
||||
idPlayer * player = static_cast<idPlayer*>( GetDriver() );
|
||||
rvVehicleWeapon * weapon = mVehicle->GetPosition( mPosition )->GetActiveWeapon();
|
||||
if ( weapon ) {
|
||||
if ( weapon->CanZoom() && player->IsZoomed() && player == gameLocal.GetLocalPlayer() ) {
|
||||
weapon->GetZoomGui()->Redraw( gameLocal.time );
|
||||
}
|
||||
// if ( mVehicle->GetHud() ) {
|
||||
// mVehicle->GetHud()->SetStateFloat( "tram_heatpct", weapon->GetOverheatPercent());
|
||||
// mVehicle->GetHud()->SetStateFloat( "tram_overheat", weapon->GetOverheatState());
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
mVehicle->DrawHUD ( mPosition );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
rvVehicleController::StartRadioChatter
|
||||
=====================
|
||||
*/
|
||||
void rvVehicleController::StartRadioChatter ( void ) {
|
||||
assert ( mVehicle );
|
||||
if ( mVehicle->GetHud () ) {
|
||||
mVehicle->GetHud ()->HandleNamedEvent( "radioChatterUp" );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
rvVehicleController::StopRadioChatter
|
||||
=====================
|
||||
*/
|
||||
void rvVehicleController::StopRadioChatter ( void ) {
|
||||
assert ( mVehicle );
|
||||
if ( mVehicle->GetHud () ) {
|
||||
mVehicle->GetHud ()->HandleNamedEvent( "radioChatterDown" );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
rvVehicleController::Give
|
||||
=====================
|
||||
*/
|
||||
void rvVehicleController::Give ( const char* statname, const char* value ) {
|
||||
if( mVehicle.IsValid() ) {
|
||||
mVehicle->Give ( statname, value );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
rvVehicleController::GetEyePosition
|
||||
=====================
|
||||
*/
|
||||
void rvVehicleController::GetEyePosition ( idVec3& origin, idMat3& axis ) const {
|
||||
if( mVehicle.IsValid() ) {
|
||||
mVehicle->GetEyePosition ( mPosition, origin, axis );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
rvVehicleController::GetDriverPosition
|
||||
=====================
|
||||
*/
|
||||
void rvVehicleController::GetDriverPosition ( idVec3& origin, idMat3& axis ) const {
|
||||
if( mVehicle.IsValid() ) {
|
||||
mVehicle->GetDriverPosition ( mPosition, origin, axis );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
rvVehicleController::GetVehicle
|
||||
=====================
|
||||
*/
|
||||
rvVehicle* rvVehicleController::GetVehicle ( void ) const {
|
||||
return mVehicle;
|
||||
}
|
||||
|
||||
idActor* rvVehicleController::GetDriver ( void ) const {
|
||||
return (GetVehicle()) ? GetVehicle()->GetPosition(GetPosition())->GetDriver() : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
rvVehicleController::SetInput
|
||||
=====================
|
||||
*/
|
||||
void rvVehicleController::SetInput ( const usercmd_t& cmd, const idAngles &angles ) {
|
||||
if( mVehicle.IsValid() ) {
|
||||
mVehicle->SetInput ( mPosition, cmd, angles );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
rvVehicleController::GetInput
|
||||
=====================
|
||||
*/
|
||||
void rvVehicleController::GetInput( usercmd_t& cmd, idAngles &newAngles ) const {
|
||||
if( mVehicle.IsValid() ) {
|
||||
mVehicle->GetInput( mPosition, cmd, newAngles );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleController::GetHud
|
||||
================
|
||||
*/
|
||||
idUserInterface* rvVehicleController::GetHud( void ) {
|
||||
return (IsDriving()) ? mVehicle->GetHud() : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleController::GetHud
|
||||
================
|
||||
*/
|
||||
const idUserInterface* rvVehicleController::GetHud( void ) const {
|
||||
return (IsDriving()) ? mVehicle->GetHud() : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleController::WriteToSnapshot
|
||||
================
|
||||
*/
|
||||
void rvVehicleController::WriteToSnapshot ( idBitMsgDelta &msg ) const {
|
||||
msg.WriteLong ( mPosition );
|
||||
msg.WriteLong ( mVehicle.GetSpawnId ( ) );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleController::ReadFromSnapshot
|
||||
================
|
||||
*/
|
||||
void rvVehicleController::ReadFromSnapshot ( const idBitMsgDelta &msg ) {
|
||||
mPosition = msg.ReadLong ( );
|
||||
mVehicle.SetSpawnId ( msg.ReadLong ( ) );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleController::UpdateCursorGUI
|
||||
================
|
||||
*/
|
||||
void rvVehicleController::UpdateCursorGUI ( idUserInterface* ui ) {
|
||||
assert ( mVehicle );
|
||||
mVehicle->UpdateCursorGUI ( mPosition, ui );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleController::SelectWeapon
|
||||
================
|
||||
*/
|
||||
void rvVehicleController::SelectWeapon ( int weapon ) {
|
||||
if( mVehicle.IsValid() ) {
|
||||
mVehicle->GetPosition( mPosition )->SelectWeapon( weapon );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
//----------------------------------------------------------------
|
||||
// VehicleController.h
|
||||
//
|
||||
// Copyright 2002-2004 Raven Software
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#ifndef __GAME_VEHICLECONTROLLER_H__
|
||||
#define __GAME_VEHICLECONTROLLER_H__
|
||||
|
||||
class rvVehicle;
|
||||
class rvVehiclePosition;
|
||||
|
||||
class rvVehicleController {
|
||||
public:
|
||||
|
||||
rvVehicleController ( void );
|
||||
|
||||
void Save ( idSaveGame *savefile ) const;
|
||||
void Restore ( idRestoreGame *savefile );
|
||||
|
||||
bool Drive ( rvVehicle* vehicle, idActor* driver );
|
||||
bool Eject ( bool force = false );
|
||||
|
||||
bool FindClearExitPoint ( idVec3& origin, idMat3& axis ) const;
|
||||
|
||||
bool IsDriving ( void ) const;
|
||||
|
||||
rvVehicle* GetVehicle ( void ) const;
|
||||
idActor* GetDriver ( void ) const;
|
||||
int GetPosition ( void ) const;
|
||||
|
||||
void SetInput ( const usercmd_t& cmd, const idAngles &newAngles );
|
||||
void GetInput ( usercmd_t& cmd, idAngles &newAngles ) const;
|
||||
|
||||
idUserInterface* GetHud ( void );
|
||||
const idUserInterface* GetHud ( void ) const;
|
||||
void DrawHUD ( void );
|
||||
void UpdateCursorGUI ( idUserInterface* ui );
|
||||
|
||||
void StartRadioChatter ( void );
|
||||
void StopRadioChatter ( void );
|
||||
|
||||
void Give ( const char* statname, const char* value );
|
||||
void GetEyePosition ( idVec3& origin, idMat3& axis ) const;
|
||||
void GetDriverPosition ( idVec3& origin, idMat3& axis ) const;
|
||||
|
||||
static void KillVehicles ( void );
|
||||
|
||||
void WriteToSnapshot ( idBitMsgDelta &msg ) const;
|
||||
void ReadFromSnapshot ( const idBitMsgDelta &msg );
|
||||
|
||||
void SelectWeapon ( int weapon );
|
||||
|
||||
protected:
|
||||
|
||||
idEntityPtr<rvVehicle> mVehicle;
|
||||
int mPosition;
|
||||
};
|
||||
|
||||
ID_INLINE bool rvVehicleController::IsDriving ( void ) const {
|
||||
return mVehicle.IsValid ( );
|
||||
}
|
||||
|
||||
ID_INLINE int rvVehicleController::GetPosition ( void ) const {
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
#endif // __GAME_VEHICLECONTROLLER_H__
|
||||
|
||||
@@ -0,0 +1,836 @@
|
||||
|
||||
// VehicleDriver.cpp
|
||||
//
|
||||
// Copyright 2002-2004 Raven Software
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#include "precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "../Game_local.h"
|
||||
|
||||
#include <cfloat>
|
||||
|
||||
const idEventDef VD_ChoosePathTarget( "choosePathTarget", "e", 'e' );
|
||||
const idEventDef EV_FollowOffset( "followOffset", "v" );
|
||||
const idEventDef EV_FireWeapon ( "fireWeapon", "ff" );
|
||||
|
||||
CLASS_DECLARATION( idActor, rvVehicleDriver )
|
||||
EVENT( EV_PostSpawn , rvVehicleDriver::Event_PostSpawn )
|
||||
EVENT( AI_EnterVehicle , rvVehicleDriver::Event_EnterVehicle )
|
||||
EVENT( AI_ExitVehicle , rvVehicleDriver::Event_ExitVehicle )
|
||||
EVENT( AI_ScriptedMove , rvVehicleDriver::Event_ScriptedMove )
|
||||
EVENT( AI_ScriptedDone , rvVehicleDriver::Event_ScriptedDone )
|
||||
EVENT( AI_ScriptedStop , rvVehicleDriver::Event_ScriptedStop )
|
||||
EVENT( EV_Activate , rvVehicleDriver::Event_Trigger )
|
||||
EVENT( EV_Speed , rvVehicleDriver::Event_SetSpeed )
|
||||
EVENT( EV_FireWeapon , rvVehicleDriver::Event_FireWeapon )
|
||||
EVENT( AI_FaceEntity , rvVehicleDriver::Event_FaceEntity )
|
||||
EVENT( AI_LookAt , rvVehicleDriver::Event_LookAt )
|
||||
EVENT( AI_SetLeader , rvVehicleDriver::Event_SetLeader )
|
||||
|
||||
//twhitaker: remove - begin
|
||||
EVENT( EV_FollowOffset , rvVehicleDriver::Event_SetFollowOffset )
|
||||
//twhitaker: remove - end
|
||||
END_CLASS
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::rvVehicleDriver
|
||||
================
|
||||
*/
|
||||
rvVehicleDriver::rvVehicleDriver ( void ) {
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::Spawn
|
||||
================
|
||||
*/
|
||||
void rvVehicleDriver::Spawn ( void ) {
|
||||
currentThrottle = 1.0f;
|
||||
faceTarget = NULL;
|
||||
lookTarget = NULL;
|
||||
leader = NULL;
|
||||
leaderFlags = 0;
|
||||
decelDistance = 0.0f;
|
||||
minDistance = 0.0f;
|
||||
fireEndTime = 0.0f;
|
||||
isMoving = false;
|
||||
avoidingLeader = false;
|
||||
pathingMode = VDPM_Random;
|
||||
pathingOrigin = vec3_origin;
|
||||
pathingEntity = NULL;
|
||||
|
||||
SIMDProcessor->Memset( &pathTargetInfo, 0, sizeof( PathTargetInfo ) );
|
||||
SIMDProcessor->Memset( &lastPathTargetInfo, 0, sizeof( PathTargetInfo ) );
|
||||
|
||||
PostEventMS( &EV_PostSpawn, 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::Think
|
||||
================
|
||||
*/
|
||||
void rvVehicleDriver::Think ( void ) {
|
||||
if ( !IsDriving() ) {
|
||||
if ( leader ) {
|
||||
leader->SetLeaderHint( VDLH_Continue );
|
||||
leader = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pathTargetInfo.node ) {
|
||||
float targetDistance = 0.0f;
|
||||
float dotForward = 0.0f;
|
||||
float dotRight = 0.0f;
|
||||
float desiredThrottle = 1.0f;
|
||||
idEntity* currentPathTarget = pathTargetInfo.node;
|
||||
rvVehicle* vehicle = vehicleController.GetVehicle();
|
||||
idMat3 vehicleAxis = vehicle->GetAxis();
|
||||
idVec3 targetOrigin;
|
||||
idVec3 dirToTarget;
|
||||
usercmd_t cmd;
|
||||
idAngles ang;
|
||||
|
||||
// We may want to hack the auto correction variable based on what the state of the driver and the driver's leader.
|
||||
UpdateAutoCorrection();
|
||||
|
||||
if ( vehicle->IsAutoCorrecting( ) ) {
|
||||
if ( lastPathTargetInfo.node ) {
|
||||
currentPathTarget = lastPathTargetInfo.node;
|
||||
}
|
||||
|
||||
if ( g_debugVehicleDriver.GetInteger() != 0 ) {
|
||||
gameRenderWorld->DebugBounds( colorCyan, vehicle->GetPhysics()->GetAbsBounds().Expand( 30 ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Touch all the triggers that the vehicle touches
|
||||
vehicle->TouchTriggers();
|
||||
|
||||
GetTargetInfo( currentPathTarget, &targetOrigin, &dirToTarget, &dotForward, &dotRight, &targetDistance );
|
||||
|
||||
// The primary purpose of the following portions of code is to set the desiredThrottle variable.
|
||||
if ( IsMoving() ) {
|
||||
|
||||
// if we're slowing down lerp throttle.
|
||||
if ( pathTargetInfo.throttle < lastPathTargetInfo.throttle ) {
|
||||
desiredThrottle = idMath::Lerp( lastPathTargetInfo.throttle, pathTargetInfo.throttle, targetDistance / pathTargetInfo.initialDistance );
|
||||
} else {
|
||||
// otherwise accelerate rapidly or maintain throttle.
|
||||
desiredThrottle = pathTargetInfo.throttle;
|
||||
}
|
||||
|
||||
// we could potentially be a leader, so check the leader flags
|
||||
if ( leaderFlags & VDLH_SlowDown ) {
|
||||
desiredThrottle = 0.1f;
|
||||
} else if ( leaderFlags & VDLH_Wait ) {
|
||||
desiredThrottle = 0.0f;
|
||||
}
|
||||
|
||||
// if we're following a someone ...
|
||||
if ( leader ) {
|
||||
bool canSeeLeader = vehicle->CanSee( leader->vehicleController.GetVehicle(), false );
|
||||
float distanceToLeader = ( leader->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin() ).Length();
|
||||
avoidingLeader = false;
|
||||
|
||||
// update the leaders flags based on distance and visibility
|
||||
if ( !canSeeLeader ) {
|
||||
// if we can't see the leader, tell him to stop
|
||||
leader->SetLeaderHint( VDLH_Wait );
|
||||
|
||||
} else if ( distanceToLeader > decelDistance ) {
|
||||
// if we're too far from the leader, tell him to slow down
|
||||
leader->SetLeaderHint( VDLH_SlowDown );
|
||||
|
||||
} else {
|
||||
// we're within range of the leader so let him move along at a normal rate
|
||||
leader->SetLeaderHint( VDLH_Continue );
|
||||
|
||||
// if we're too close to the leader, we need to slow ourself down
|
||||
if ( distanceToLeader < minDistance ) {
|
||||
desiredThrottle = -0.2f;
|
||||
avoidingLeader = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// the desiredThrottle variable should be set at this point, the only other thing that could change it
|
||||
// would be in SimulateKeys, if the dotForward < 0.
|
||||
}
|
||||
|
||||
vehicleController.GetInput( cmd, ang );
|
||||
|
||||
// Simulate Input
|
||||
SimulateKeys( cmd, dotForward, dotRight, desiredThrottle * currentThrottle, targetDistance );
|
||||
SimulateMouseMove( cmd );
|
||||
SimulateButtons( cmd );
|
||||
|
||||
vehicleController.SetInput( cmd, ang );
|
||||
|
||||
// Node Transition
|
||||
if( (!vehicle->IsAutoCorrecting() || !IsValidPathNode( currentPathTarget )) && isMoving ) {
|
||||
idVec3 point = targetOrigin - dirToTarget * pathTargetInfo.minDistance;
|
||||
|
||||
if( vehicle->GetPhysics()->GetAbsBounds().ContainsPoint( point ) ) {
|
||||
int numTargets = NumValidTargets( currentPathTarget );
|
||||
lastPathTargetInfo = pathTargetInfo;
|
||||
//TODO: ponder - should I be setting lastPathTargetInfo.node to pathTargetInfo.node or currentPathTarget???
|
||||
|
||||
if( numTargets ) {
|
||||
Event_ScriptedMove( ChooseNextNode( currentPathTarget ), 0, 0 );
|
||||
}
|
||||
|
||||
if( lastPathTargetInfo.exitVehicle ) {
|
||||
Event_ExitVehicle( true );
|
||||
} else if( lastPathTargetInfo.throttle == 0 || !numTargets ) {
|
||||
Event_ScriptedStop();
|
||||
|
||||
if( !numTargets ) {
|
||||
pathTargetInfo.node = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Debug Output
|
||||
if ( g_debugVehicleDriver.GetInteger( ) != 0 ) {
|
||||
gameRenderWorld->DebugBounds( colorRed, idBounds(idVec3(-5, -5, -5), idVec3(5, 5, 5)), point );
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // no path
|
||||
float dotForward;
|
||||
float dotRight;
|
||||
usercmd_t cmd;
|
||||
idAngles ang;
|
||||
|
||||
vehicleController.GetInput( cmd, ang );
|
||||
|
||||
if ( GetTargetInfo( faceTarget, NULL, NULL, &dotForward, &dotRight, NULL) ) {
|
||||
if( ( 1.0f - dotForward ) < VECTOR_EPSILON ) {
|
||||
Event_ScriptedStop();
|
||||
} else {
|
||||
SimulateKeys( cmd, dotForward, dotRight, 0.0f );
|
||||
}
|
||||
}
|
||||
|
||||
SimulateMouseMove( cmd );
|
||||
SimulateButtons( cmd );
|
||||
|
||||
vehicleController.SetInput( cmd, ang );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::GetTargetInfo
|
||||
================
|
||||
*/
|
||||
bool rvVehicleDriver::GetTargetInfo( const idEntity* target, idVec3* targetOrigin, idVec3* dirToTarget, float* dotForward, float* dotRight, float* distance ) const {
|
||||
if( !target || !IsDriving() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
idMat3 vehicleAxis = vehicleController.GetVehicle()->GetAxis();
|
||||
idVec3 vehicleOrigin = vehicleController.GetVehicle()->GetOrigin();
|
||||
idVec3 forward = vehicleAxis[ 0 ];
|
||||
idVec3 localTargetOrigin = target->GetPhysics()->GetOrigin();
|
||||
localTargetOrigin.z = vehicleOrigin.z;// Find way to include vehicleAxis here
|
||||
idVec3 vectorToTarget = localTargetOrigin - vehicleOrigin;
|
||||
idVec3 localDirToTarget = vectorToTarget;
|
||||
float distToTarget = localDirToTarget.Normalize();
|
||||
|
||||
if( targetOrigin ) {
|
||||
*targetOrigin = localTargetOrigin;
|
||||
}
|
||||
|
||||
if( dirToTarget ) {
|
||||
*dirToTarget = localDirToTarget;
|
||||
}
|
||||
|
||||
if( distance ) {
|
||||
*distance = distToTarget;
|
||||
}
|
||||
|
||||
if( dotForward ) {
|
||||
*dotForward = localDirToTarget * forward;
|
||||
}
|
||||
|
||||
if( dotRight ) {
|
||||
*dotRight = localDirToTarget * vehicleAxis[ 1 ];
|
||||
}
|
||||
|
||||
// Debug help
|
||||
if ( g_debugVehicleDriver.GetInteger( ) != 0 ) {
|
||||
idStr temp;
|
||||
const idVec3 & origin = GetPhysics()->GetOrigin();
|
||||
gameRenderWorld->DebugLine( colorBlue, origin, target->GetPhysics()->GetOrigin() );
|
||||
gameRenderWorld->DebugBounds( colorBlue, GetPhysics()->GetAbsBounds() );
|
||||
gameRenderWorld->DebugBounds( colorBlue, target->GetPhysics()->GetBounds(), target->GetPhysics()->GetOrigin() );
|
||||
gameRenderWorld->DrawText( target->GetName(), vehicleOrigin + vectorToTarget + vehicleAxis[2] * 5.0f, 1.0f, colorBlue, gameLocal.GetLocalPlayer()->viewAxis );
|
||||
gameRenderWorld->DrawText( idStr( "State: " ) + LeaderHintsString( leaderFlags, temp ), origin, 1.0f, colorBlue, gameLocal.GetLocalPlayer()->viewAxis );
|
||||
|
||||
if ( vehicleController.GetVehicle()->IsAutoCorrecting() ) {
|
||||
gameRenderWorld->DebugBounds( colorPurple, vehicleController.GetVehicle()->GetPhysics()->GetAbsBounds() );
|
||||
gameRenderWorld->DrawText( "Auto-Correcting", vehicleOrigin, 1.0f, colorPurple, gameLocal.GetLocalPlayer()->viewAxis );
|
||||
}
|
||||
|
||||
if ( pathTargetInfo.node && g_debugVehicleDriver.GetInteger( ) == 2 ) {
|
||||
gameRenderWorld->DebugBounds( colorOrange, pathTargetInfo.node->GetPhysics()->GetBounds() );
|
||||
|
||||
for ( int ix = 0; ix < pathTargetInfo.node->targets.Num(); ix++ ) {
|
||||
gameRenderWorld->DebugLine( colorOrange, pathTargetInfo.node->GetPhysics()->GetOrigin(), pathTargetInfo.node->targets[ ix ]->GetPhysics()->GetOrigin(), 0, true );
|
||||
}
|
||||
}
|
||||
if ( leader ) {
|
||||
idVec4 & color = colorGreen;
|
||||
|
||||
if ( leader->GetLeaderHint() & VDLH_SlowDown ) {
|
||||
color = colorYellow;
|
||||
} else if ( leader->GetLeaderHint() & VDLH_Wait ) {
|
||||
color = colorRed;
|
||||
}
|
||||
|
||||
idStr str = idStr( "decel_distance: " ) + idStr( decelDistance ) + idStr( "\nmin_distance: " ) + idStr( minDistance );
|
||||
|
||||
gameRenderWorld->DrawText( str, leader->GetPhysics()->GetOrigin(), 1.0f, color, gameLocal.GetLocalPlayer()->viewAxis, 1, 0, true );
|
||||
gameRenderWorld->DebugLine( color, GetPhysics()->GetOrigin(), leader->GetPhysics()->GetOrigin(), 0, true );
|
||||
gameRenderWorld->DebugBounds( color, leader->vehicleController.GetVehicle()->GetPhysics()->GetAbsBounds(), vec3_origin, 0, true );
|
||||
gameRenderWorld->DebugCircle( color, leader->GetPhysics()->GetOrigin(), idVec3( 0, 0, 1 ), decelDistance, 10, 0, true );
|
||||
gameRenderWorld->DebugCircle( color, leader->GetPhysics()->GetOrigin(), idVec3( 0, 0, 1 ), minDistance, 10, 0, true );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::ChooseNextNode
|
||||
================
|
||||
*/
|
||||
idEntity* rvVehicleDriver::ChooseNextNode( idEntity* target ) {
|
||||
if( !target ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( func.Init( target->spawnArgs.GetString( "call_nextNode" )) <= 0 ) {
|
||||
idEntity * best = NULL;
|
||||
float bestDist;
|
||||
|
||||
switch ( pathingMode ) {
|
||||
case VDPM_MoveTo:
|
||||
bestDist = FLT_MAX;
|
||||
|
||||
for ( int i = target->targets.Num() - 1; i; i -- ) {
|
||||
float distance = ( target->targets[ i ]->GetPhysics()->GetOrigin() - pathingOrigin ).LengthSqr();
|
||||
|
||||
if ( bestDist > distance ) {
|
||||
bestDist = distance;
|
||||
best = target->targets[ i ];
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case VDPM_MoveAway:
|
||||
bestDist = FLT_MIN;
|
||||
|
||||
for ( int i = target->targets.Num() - 1; i; i -- ) {
|
||||
float distance = ( target->targets[ i ]->GetPhysics()->GetOrigin() - pathingOrigin ).LengthSqr();
|
||||
|
||||
if ( bestDist < distance ) {
|
||||
bestDist = distance;
|
||||
best = target->targets[ i ];
|
||||
}
|
||||
}
|
||||
|
||||
case VDPM_Custom:
|
||||
if ( pathingEntity ) {
|
||||
// best = pathingCallback( target );
|
||||
pathingEntity->ProcessEvent( &VD_ChoosePathTarget, target );
|
||||
best = gameLocal.program.GetReturnedEntity();
|
||||
}
|
||||
}
|
||||
|
||||
return ( best ) ? best : RandomValidTarget( target );
|
||||
}
|
||||
|
||||
func.InsertEntity( this, 0 );
|
||||
func.CallFunc( &spawnArgs );
|
||||
func.RemoveIndex( 0 );
|
||||
|
||||
return ( func.ReturnsAVal()) ? gameLocal.FindEntity( spawnArgs.GetString( func.GetReturnKey() )) : const_cast<idEntity*>( target );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::SimulateButtons
|
||||
================
|
||||
*/
|
||||
void rvVehicleDriver::SimulateButtons( usercmd_t& cmd ) {
|
||||
cmd.buttons = (fireEndTime >= gameLocal.time) ? BUTTON_ATTACK : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::SimulateMouseMove
|
||||
================
|
||||
*/
|
||||
void rvVehicleDriver::SimulateMouseMove( usercmd_t& cmd ) {
|
||||
idVec3 origin;
|
||||
idMat3 axis;
|
||||
|
||||
idVec3 vectorToTarget;
|
||||
idAngles anglesToTarget;
|
||||
idAngles turretAngles;
|
||||
idAngles deltaAngles;
|
||||
|
||||
if( !lookTarget ) {
|
||||
for( int ix = 0; ix < 3; ++ix ) {
|
||||
cmd.angles[ix] = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
vehicleController.GetEyePosition( origin, axis );
|
||||
vectorToTarget = (lookTarget->GetPhysics()->GetOrigin() - origin).ToNormal();
|
||||
anglesToTarget = vectorToTarget.ToAngles().Normalize360();
|
||||
turretAngles = (axis[0]).ToAngles().Normalize360();
|
||||
deltaAngles = (anglesToTarget - turretAngles).Normalize180();
|
||||
|
||||
for( int ix = 0; ix < deltaAngles.GetDimension(); ++ix ) {
|
||||
cmd.angles[ix] += ANGLE2SHORT( deltaAngles[ix] );
|
||||
}
|
||||
|
||||
// Debug Output
|
||||
if( g_debugVehicleDriver.GetInteger( ) != 0 ) {
|
||||
gameRenderWorld->DebugLine( colorGreen, origin, origin + anglesToTarget.ToForward() * 100.0f, 17, true );
|
||||
gameRenderWorld->DebugLine( colorYellow, origin, origin + turretAngles.ToForward() * 100.0f, 17, true );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::SimulateKeys
|
||||
================
|
||||
*/
|
||||
void rvVehicleDriver::SimulateKeys( usercmd_t& cmd, float dotForward, float dotRight, float speed, float distance ) {
|
||||
rvVehicle * vehicle = vehicleController.GetVehicle();
|
||||
|
||||
if( !vehicle ) {
|
||||
cmd.forwardmove = 0;
|
||||
cmd.rightmove = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
cmd.forwardmove = static_cast< signed char >( (!vehicle->IsAutoCorrecting() ? 127.0f : forwardThrustScale) * dotForward * speed );
|
||||
cmd.rightmove = static_cast< signed char >( ( ( dotForward < 0.0f ) ? rightThrustScale : -rightThrustScale ) * dotRight );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::SortValid
|
||||
================
|
||||
*/
|
||||
int rvVehicleDriver::SortValid( const void* a, const void* b ) {
|
||||
idEntityPtr<idEntity> A = *(idEntityPtr<idEntity>*)a;
|
||||
idEntityPtr<idEntity> B = *(idEntityPtr<idEntity>*)b;
|
||||
|
||||
return rvVehicleDriver::IsValidTarget( B ) - rvVehicleDriver::IsValidTarget( A );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::SortTargetList
|
||||
================
|
||||
*/
|
||||
int rvVehicleDriver::SortTargetList( idEntity* ent ) const {
|
||||
if( !ent ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int numValidEntities = 0;
|
||||
idEntity * target;
|
||||
|
||||
ent->RemoveNullTargets();
|
||||
qsort( ent->targets.Ptr(), NumTargets( ent ), ent->targets.TypeSize(), rvVehicleDriver::SortValid );
|
||||
|
||||
for( int ix = NumTargets( ent ) - 1; ix >= 0; --ix ) {
|
||||
target = GetTarget( ent, ix );
|
||||
|
||||
if( IsValidTarget( target ) ) {
|
||||
++numValidEntities;
|
||||
}
|
||||
}
|
||||
|
||||
return numValidEntities;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::RandomValidTarget
|
||||
================
|
||||
*/
|
||||
idEntity* rvVehicleDriver::RandomValidTarget( idEntity* ent ) const {
|
||||
int numValid = NumValidTargets( ent );
|
||||
return (!numValid) ? NULL : ent->targets[ rvRandom::irand(0, numValid - 1) ];
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::NumValidTargets
|
||||
================
|
||||
*/
|
||||
int rvVehicleDriver::NumValidTargets( idEntity* ent ) const {
|
||||
return SortTargetList(ent);
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::NumTargets
|
||||
================
|
||||
*/
|
||||
int rvVehicleDriver::NumTargets( const idEntity* ent ) const {
|
||||
return (ent) ? ent->targets.Num() : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::GetTarget
|
||||
================
|
||||
*/
|
||||
idEntity* rvVehicleDriver::GetTarget( const idEntity* ent, int index ) const {
|
||||
return (ent) ? ent->targets[index] : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::IsValidPathNode
|
||||
================
|
||||
*/
|
||||
bool rvVehicleDriver::IsValidPathNode( const idEntity* ent ) {
|
||||
if( !ent ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ent->IsType( idTarget::GetClassType() );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::IsValidTarget
|
||||
================
|
||||
*/
|
||||
bool rvVehicleDriver::IsValidTarget( const idEntity* ent ) {
|
||||
return IsValidPathNode( ent ) || ent->IsType( rvVehicle::GetClassType() ) || ent->IsType( idPlayer::GetClassType() );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::SetLeader
|
||||
================
|
||||
*/
|
||||
bool rvVehicleDriver::SetLeader( idEntity* ent ) {
|
||||
if ( !ent || !ent->IsType( rvVehicleDriver::GetClassType() ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
leader = static_cast<rvVehicleDriver*>( ent );
|
||||
minDistance = leader->spawnArgs.GetFloat( "min_distance", "500" );
|
||||
idStr decel_distance( minDistance * 3.0f );
|
||||
decelDistance = leader->spawnArgs.GetFloat( "decel_distance", decel_distance );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::Event_PostSpawn
|
||||
================
|
||||
*/
|
||||
void rvVehicleDriver::Event_PostSpawn ( void ) {
|
||||
for ( int i = targets.Num() - 1; i >= 0; i-- ) {
|
||||
idEntity * ent = targets[ i ].GetEntity();
|
||||
if ( ent->IsType( rvVehicle::GetClassType() ) ) {
|
||||
Event_EnterVehicle( ent );
|
||||
}
|
||||
}
|
||||
|
||||
for ( int i = targets.Num() - 1; i >= 0; i-- ) {
|
||||
idEntity * ent = targets[ i ].GetEntity();
|
||||
if ( ent->IsType( idTarget::GetClassType() ) ) {
|
||||
Event_ScriptedMove( ent, 0, 0 );
|
||||
}
|
||||
if ( ent->IsType( rvVehicleDriver::GetClassType() ) ) {
|
||||
SetLeader( ent );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::Event_EnterVehicle
|
||||
================
|
||||
*/
|
||||
void rvVehicleDriver::Event_EnterVehicle ( idEntity * vehicle ) {
|
||||
if ( vehicle ) {
|
||||
forwardThrustScale = vehicle->spawnArgs.GetFloat( "driver_forward_thrust", ".75" ) * 127.0f;
|
||||
rightThrustScale = vehicle->spawnArgs.GetFloat( "driver_right_thrust", "1" ) * 127.0f;
|
||||
|
||||
EnterVehicle( vehicle );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::Event_ExitVehicle
|
||||
================
|
||||
*/
|
||||
void rvVehicleDriver::Event_ExitVehicle( bool force ) {
|
||||
Event_ScriptedStop();
|
||||
|
||||
if( vehicleController.GetVehicle() && force && !ExitVehicle(force) ) {
|
||||
vehicleController.GetVehicle()->RemoveDriver( vehicleController.GetPosition(), force );
|
||||
}
|
||||
|
||||
pathTargetInfo.node = NULL;
|
||||
faceTarget = NULL;
|
||||
lookTarget = NULL;
|
||||
leader = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::Event_ScriptedMove
|
||||
================
|
||||
*/
|
||||
void rvVehicleDriver::Event_ScriptedMove( idEntity *target, float minDist, bool exitVehicle ) {
|
||||
isMoving = false;
|
||||
|
||||
if( !target ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( IsValidTarget( target ) ) {
|
||||
isMoving = true;
|
||||
faceTarget = NULL;
|
||||
pathTargetInfo.node = target;
|
||||
pathTargetInfo.initialDistance = ( target->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin() ).Length();
|
||||
|
||||
if ( !target->IsType( idPlayer::GetClassType() ) ) {
|
||||
pathTargetInfo.minDistance = target->spawnArgs.GetFloat( "min_distance", va("%f", Max(200.0f, minDist)) );
|
||||
pathTargetInfo.throttle = idMath::ClampFloat( 0.0f, 1.0f, target->spawnArgs.GetFloat( "throttle", "1" ) );
|
||||
pathTargetInfo.exitVehicle = target->spawnArgs.GetBool( "exit_vehicle", exitVehicle ? "1" : "0" );
|
||||
|
||||
if( pathTargetInfo.exitVehicle ) {
|
||||
pathTargetInfo.throttle = 0.0f;
|
||||
}
|
||||
} else {
|
||||
pathTargetInfo.minDistance = minDist;
|
||||
pathTargetInfo.throttle = 1.0f;
|
||||
pathTargetInfo.exitVehicle = false;
|
||||
}
|
||||
|
||||
} else {
|
||||
SIMDProcessor->Memset( &pathTargetInfo, 0, sizeof( PathTargetInfo ) );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::Event_ScriptedDone
|
||||
================
|
||||
*/
|
||||
void rvVehicleDriver::Event_ScriptedDone( void ) {
|
||||
idThread::ReturnFloat( !IsMoving() );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::Event_ScriptedStop
|
||||
================
|
||||
*/
|
||||
void rvVehicleDriver::Event_ScriptedStop( void ) {
|
||||
if( IsDriving() ) {
|
||||
usercmd_t cmd = { 0 };
|
||||
|
||||
vehicleController.SetInput( cmd, ang_zero );
|
||||
|
||||
if( pathTargetInfo.node ) {
|
||||
if( func.Init( pathTargetInfo.node->spawnArgs.GetString( "call_doneMoving" )) > 0 ) {
|
||||
func.InsertEntity( this, 0 );
|
||||
func.CallFunc( &spawnArgs );
|
||||
func.RemoveIndex( 0 );
|
||||
}
|
||||
|
||||
pathTargetInfo.node->ActivateTargets(this);
|
||||
pathTargetInfo.node = NULL;
|
||||
}
|
||||
|
||||
isMoving = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::Event_Trigger
|
||||
================
|
||||
*/
|
||||
void rvVehicleDriver::Event_Trigger( idEntity *activator ) {
|
||||
if( IsDriving() && pathTargetInfo.node ) {
|
||||
isMoving = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::Event_SetSpeed
|
||||
================
|
||||
*/
|
||||
void rvVehicleDriver::Event_SetSpeed( float speed ) {
|
||||
currentThrottle = speed;
|
||||
}
|
||||
|
||||
//twhitaker: remove - begin
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::Event_SetFollowOffset
|
||||
================
|
||||
*/
|
||||
void rvVehicleDriver::Event_SetFollowOffset( const idVec3 &offset ) {
|
||||
gameLocal.Warning( "Script Event \"followOffset\" is deprecated, please remove it immediately to avoid errors." );
|
||||
}
|
||||
//twhitaker: remove - end
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::Event_FireWeapon
|
||||
================
|
||||
*/
|
||||
void rvVehicleDriver::Event_FireWeapon( float weapon_index, float time ) {
|
||||
if( IsDriving() ) {
|
||||
fireEndTime = gameLocal.GetTime() + SEC2MS( time );
|
||||
vehicleController.SelectWeapon( weapon_index );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::Event_FaceEntity
|
||||
================
|
||||
*/
|
||||
void rvVehicleDriver::Event_FaceEntity( const idEntity* entity ) {
|
||||
if( IsMoving() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
faceTarget = entity;
|
||||
isMoving = true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::Event_LookAt
|
||||
================
|
||||
*/
|
||||
void rvVehicleDriver::Event_LookAt( const idEntity* entity ) {
|
||||
lookTarget = entity;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::Event_SetLeader
|
||||
================
|
||||
*/
|
||||
void rvVehicleDriver::Event_SetLeader( idEntity* newLeader ) {
|
||||
SetLeader( newLeader );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::UpdateAutoCorrection
|
||||
================
|
||||
*/
|
||||
void rvVehicleDriver::UpdateAutoCorrection ( void ) {
|
||||
if ( IsDriving() ) {
|
||||
rvVehicle * vehicle = vehicleController.GetVehicle();
|
||||
|
||||
// Disregard your autocorrection state if we're slowing down to avoid collision with the leader.
|
||||
if ( vehicle->IsAutoCorrecting() ) {
|
||||
if ( avoidingLeader == true ) {
|
||||
vehicle->autoCorrectionBegin = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::Save
|
||||
================
|
||||
*/
|
||||
void rvVehicleDriver::Save ( idSaveGame *savefile ) const {
|
||||
savefile->Write ( &pathTargetInfo, sizeof ( pathTargetInfo ) );
|
||||
savefile->Write ( &lastPathTargetInfo, sizeof ( lastPathTargetInfo ) );
|
||||
savefile->WriteFloat ( currentThrottle );
|
||||
|
||||
faceTarget.Save ( savefile );
|
||||
lookTarget.Save ( savefile );
|
||||
|
||||
leader.Save ( savefile );
|
||||
savefile->WriteInt ( leaderFlags );
|
||||
savefile->WriteFloat ( decelDistance );
|
||||
savefile->WriteFloat ( minDistance );
|
||||
savefile->WriteBool ( avoidingLeader );
|
||||
|
||||
savefile->WriteFloat ( fireEndTime );
|
||||
|
||||
func.Save ( savefile );
|
||||
|
||||
savefile->WriteBool ( isMoving );
|
||||
|
||||
savefile->WriteInt ( (int&)pathingMode );
|
||||
pathingEntity.Save ( savefile );
|
||||
savefile->WriteVec3 ( pathingOrigin );
|
||||
|
||||
savefile->WriteFloat( forwardThrustScale ); // cnicholson: Added unsaved var
|
||||
savefile->WriteFloat( rightThrustScale ); // cnicholson: Added unsaved var
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDriver::Restore
|
||||
================
|
||||
*/
|
||||
void rvVehicleDriver::Restore ( idRestoreGame *savefile ) {
|
||||
savefile->Read ( &pathTargetInfo, sizeof ( pathTargetInfo ) );
|
||||
savefile->Read ( &lastPathTargetInfo, sizeof ( lastPathTargetInfo ) );
|
||||
savefile->ReadFloat ( currentThrottle );
|
||||
|
||||
faceTarget.Restore ( savefile );
|
||||
lookTarget.Restore ( savefile );
|
||||
|
||||
leader.Restore ( savefile );
|
||||
savefile->ReadInt ( leaderFlags );
|
||||
savefile->ReadFloat ( decelDistance );
|
||||
savefile->ReadFloat ( minDistance );
|
||||
savefile->ReadBool ( avoidingLeader );
|
||||
|
||||
savefile->ReadFloat ( fireEndTime );
|
||||
|
||||
func.Restore ( savefile );
|
||||
|
||||
savefile->ReadBool ( isMoving );
|
||||
|
||||
savefile->ReadInt ( (int&)pathingMode );
|
||||
pathingEntity.Restore ( savefile );
|
||||
savefile->ReadVec3 ( pathingOrigin );
|
||||
|
||||
savefile->ReadFloat( forwardThrustScale ); // cnicholson: Added unrestored var
|
||||
savefile->ReadFloat( rightThrustScale ); // cnicholson: Added unrestored var
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
//----------------------------------------------------------------
|
||||
// VehicleDriver.h
|
||||
//
|
||||
// Copyright 2002-2004 Raven Software
|
||||
//----------------------------------------------------------------
|
||||
|
||||
extern const idEventDef VD_ChoosePathTarget;
|
||||
|
||||
class rvVehicleDriver : public idActor {
|
||||
friend class rvVehicleAI;
|
||||
friend class rvVehicleMonster;
|
||||
public:
|
||||
|
||||
CLASS_PROTOTYPE( rvVehicleDriver );
|
||||
|
||||
rvVehicleDriver ( void );
|
||||
|
||||
void Think ( void );
|
||||
void Spawn ( void );
|
||||
|
||||
static bool IsValidTarget ( const idEntity* ent ); // valid entity for looking or facing
|
||||
static bool IsValidPathNode ( const idEntity* ent ); // valid entity for pathing
|
||||
static bool IsValidLeader ( const idEntity* ent ); // valid entity to set as a leader
|
||||
|
||||
static int SortValid ( const void* a, const void* b );
|
||||
|
||||
virtual void Present ( void ) { }
|
||||
|
||||
protected:
|
||||
void SimulateKeys ( usercmd_t& cmd, float dotForward, float dotRight, float speed, float distance = 0 );
|
||||
void SimulateButtons ( usercmd_t& cmd );
|
||||
void SimulateMouseMove ( usercmd_t& cmd );
|
||||
|
||||
bool GetTargetInfo ( const idEntity* target, idVec3* targetOrigin, idVec3* dirToTarget,
|
||||
float* dotForward, float* dotRight, float* distance ) const;
|
||||
idEntity* ChooseNextNode ( idEntity* target );
|
||||
|
||||
bool IsMoving ( void ) const { return isMoving && IsDriving(); }
|
||||
bool IsDriving ( void ) const { return vehicleController.IsDriving(); }
|
||||
|
||||
bool SetLeader ( idEntity* newLeader );
|
||||
const idEntity* GetLeader ( void ) const { return leader; }
|
||||
void SetLeaderHint ( int flags ) { leaderFlags = flags; }
|
||||
int GetLeaderHint ( void ) const { return leaderFlags; }
|
||||
|
||||
int SortTargetList ( idEntity* ent ) const;
|
||||
idEntity* RandomValidTarget ( idEntity* ent ) const;
|
||||
int NumValidTargets ( idEntity* ent ) const;
|
||||
int NumTargets ( const idEntity* ent ) const;
|
||||
idEntity* GetTarget ( const idEntity* ent, int index ) const;
|
||||
|
||||
void UpdateAutoCorrection ( void );
|
||||
|
||||
void Save ( idSaveGame *savefile ) const;
|
||||
void Restore ( idRestoreGame *savefile );
|
||||
|
||||
enum VD_PathingMode {
|
||||
VDPM_Random = 0,
|
||||
VDPM_MoveTo = 1,
|
||||
VDPM_MoveAway = 2,
|
||||
VDPM_Custom = 4,
|
||||
};
|
||||
|
||||
|
||||
void SetPathingMode ( VD_PathingMode mode, const idVec3 & origin );
|
||||
// CustomPathingFunc SetPathingMode ( VD_PathingMode mode, CustomPathingFunc cb );
|
||||
idEntity * SetPathingMode ( VD_PathingMode mode, idEntity * );
|
||||
VD_PathingMode GetPathingMode ( void ) const;
|
||||
const idVec3 & GetPathingOrigin ( void ) const;
|
||||
// CustomPathingFunc GetPathingCustomCallback ( void ) const;
|
||||
idEntity * GetPathingEntity ( void ) const;
|
||||
|
||||
protected:
|
||||
void Event_PostSpawn ( void );
|
||||
void Event_EnterVehicle ( idEntity * vehicle );
|
||||
void Event_ExitVehicle ( bool force );
|
||||
void Event_ScriptedMove ( idEntity *target, float minDist, bool exitVehicle );
|
||||
void Event_ScriptedDone ( void );
|
||||
void Event_ScriptedStop ( void );
|
||||
void Event_Trigger ( idEntity *activator );
|
||||
void Event_SetSpeed ( float speed );
|
||||
void Event_FireWeapon ( float weapon_index, float time );
|
||||
void Event_FaceEntity ( const idEntity* entity );
|
||||
void Event_LookAt ( const idEntity* entity );
|
||||
void Event_SetLeader ( idEntity* newLeader );
|
||||
|
||||
//twhitaker: remove - begin
|
||||
void Event_SetFollowOffset ( const idVec3 &offset );
|
||||
//twhitaker: remove - end
|
||||
|
||||
// Leader hints : a driver will send the following driving hints to it's leader
|
||||
enum VD_LeaderHints {
|
||||
VDLH_SlowDown = 1, // Set when distance is too great
|
||||
VDLH_Wait = 2, // Set when there is no line of site
|
||||
VDLH_Continue = 0, // Default following behavior
|
||||
};
|
||||
|
||||
idStr & LeaderHintsString( int hints, idStr & out ) const {
|
||||
switch ( hints ) {
|
||||
case VDLH_SlowDown: out = "SlowDown"; break;
|
||||
case VDLH_Wait: out = "Wait"; break;
|
||||
default: out = "Continue"; break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// Stores information about a path target
|
||||
struct PathTargetInfo {
|
||||
idEntityPtr<idEntity> node; // the target entity
|
||||
float initialDistance; // the distance to this entity when we first decide to move there
|
||||
float minDistance; // the range that specifies when this entity has been reached
|
||||
float throttle; // 0 -> 1 speed setting
|
||||
bool exitVehicle; // set to true to exit a vehicle when we reach this target
|
||||
};
|
||||
|
||||
struct PathNavigationData {
|
||||
float dotForward;
|
||||
float dotRight;
|
||||
};
|
||||
|
||||
// standard movement
|
||||
PathTargetInfo pathTargetInfo;
|
||||
PathTargetInfo lastPathTargetInfo;
|
||||
float currentThrottle;
|
||||
|
||||
// facing
|
||||
idEntityPtr<const idEntity> faceTarget;
|
||||
idEntityPtr<const idEntity> lookTarget;
|
||||
|
||||
// following
|
||||
idEntityPtr<rvVehicleDriver> leader; //TODO: twhitaker: see if I can make this an rvVehicle (so entities can follow player)
|
||||
int leaderFlags;
|
||||
float decelDistance;
|
||||
float minDistance;
|
||||
bool avoidingLeader;
|
||||
|
||||
// firing
|
||||
float fireEndTime;
|
||||
|
||||
// event callbacks
|
||||
rvScriptFuncUtility func;
|
||||
|
||||
// state
|
||||
bool isMoving;
|
||||
|
||||
VD_PathingMode pathingMode;
|
||||
// idEntity * (* pathingCallback)( idEntity * );
|
||||
idEntityPtr<idEntity> pathingEntity;
|
||||
idVec3 pathingOrigin;
|
||||
|
||||
float forwardThrustScale;
|
||||
float rightThrustScale;
|
||||
};
|
||||
|
||||
|
||||
ID_INLINE void rvVehicleDriver::SetPathingMode( VD_PathingMode mode, const idVec3 & origin ) {
|
||||
if ( mode != VDPM_Custom ) {
|
||||
pathingMode = mode;
|
||||
pathingOrigin = origin;
|
||||
}
|
||||
}
|
||||
|
||||
ID_INLINE idEntity * rvVehicleDriver::SetPathingMode( VD_PathingMode mode, idEntity * entity ) {
|
||||
if ( mode != VDPM_Custom ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pathingMode = mode;
|
||||
idEntity * prev = pathingEntity;
|
||||
pathingEntity = entity;
|
||||
return prev;
|
||||
}
|
||||
|
||||
ID_INLINE rvVehicleDriver::VD_PathingMode rvVehicleDriver::GetPathingMode ( void ) const {
|
||||
return pathingMode;
|
||||
}
|
||||
|
||||
ID_INLINE const idVec3 & rvVehicleDriver::GetPathingOrigin ( void ) const {
|
||||
return pathingOrigin;
|
||||
}
|
||||
|
||||
ID_INLINE idEntity * rvVehicleDriver::GetPathingEntity ( void ) const {
|
||||
return pathingEntity;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
//----------------------------------------------------------------
|
||||
// Vehicle.cpp
|
||||
//
|
||||
// Copyright 2002-2004 Raven Software
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#include "precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "../Game_local.h"
|
||||
#include "VehicleMonster.h"
|
||||
#include "../ai/VehicleAI.h"
|
||||
|
||||
CLASS_DECLARATION( rvVehicle, rvVehicleMonster )
|
||||
END_CLASS
|
||||
|
||||
rvVehicleMonster::rvVehicleMonster ( void ) {
|
||||
}
|
||||
|
||||
rvVehicleMonster::~rvVehicleMonster ( void ) {
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleMonster::Spawn
|
||||
================
|
||||
*/
|
||||
void rvVehicleMonster::Spawn( void ) {
|
||||
idDict dict;
|
||||
int count = 0;
|
||||
const idKeyValue * val = NULL;
|
||||
|
||||
for (;;) {
|
||||
val = spawnArgs.MatchPrefix( "target", val );
|
||||
|
||||
if ( !val )
|
||||
break;
|
||||
|
||||
dict.Set( "target" + (( count ) ? idStr( count ) : idStr( "" ) ), val->GetValue() );
|
||||
count++;
|
||||
}
|
||||
|
||||
dict.Set( "bind", name );
|
||||
dict.SetBool( "hide", true );
|
||||
|
||||
driver = static_cast<rvVehicleAI *>( gameLocal.SpawnEntityDef( "ai_vehicle_driver", &dict ) );
|
||||
|
||||
if ( driver ) {
|
||||
driver->SetVehicle( this );
|
||||
driver->GetPhysics()->SetOrigin( vec3_zero );
|
||||
} else {
|
||||
gameLocal.Warning( "Unable to find \"entityDef ai_vehicle_driver\"." );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleMonster::SetClipModel
|
||||
================
|
||||
*/
|
||||
void rvVehicleMonster::SetClipModel ( idPhysics & physicsObj ) {
|
||||
idStr clipModelName;
|
||||
idTraceModel trm;
|
||||
float mass;
|
||||
|
||||
// rebuild clipmodel
|
||||
spawnArgs.GetString( "clipmodel", "", clipModelName );
|
||||
|
||||
// load the trace model
|
||||
if ( clipModelName.Length() ) {
|
||||
if ( !collisionModelManager->TrmFromModel( gameLocal.GetMapName(), clipModelName, trm ) ) {
|
||||
gameLocal.Error( "rvVehicleMonster '%s': cannot load collision model %s", name.c_str(), clipModelName.c_str() );
|
||||
return;
|
||||
}
|
||||
|
||||
physicsObj.SetClipModel( new idClipModel( trm ), spawnArgs.GetFloat ( "density", "1" ) );
|
||||
} else {
|
||||
physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), spawnArgs.GetFloat ( "density", "1" ) );
|
||||
}
|
||||
|
||||
if ( spawnArgs.GetFloat ( "mass", "0", mass ) && mass > 0 ) {
|
||||
physicsObj.SetMass ( mass );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleMonster::Save
|
||||
================
|
||||
*/
|
||||
void rvVehicleMonster::Save ( idSaveGame *savefile ) const {
|
||||
driver.Save ( savefile );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleMonster::Restore
|
||||
================
|
||||
*/
|
||||
void rvVehicleMonster::Restore ( idRestoreGame *savefile ) {
|
||||
driver.Restore ( savefile );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleMonster::Think
|
||||
================
|
||||
*/
|
||||
void rvVehicleMonster::Think ( void ) {
|
||||
if ( !driver ) {
|
||||
PostEventMS( &EV_Remove, 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
stateThread.Execute();
|
||||
rvVehicle::Think();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleMonster::GetTargetOrigin
|
||||
================
|
||||
*/
|
||||
const idVec3 & rvVehicleMonster::GetTargetOrigin ( void ) {
|
||||
if ( driver && driver->driver && driver->driver->pathTargetInfo.node ) {
|
||||
return driver->driver->pathTargetInfo.node->GetPhysics()->GetOrigin();
|
||||
}
|
||||
return vec3_origin;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleMonster::GetVectorToTarget
|
||||
================
|
||||
*/
|
||||
idVec3 rvVehicleMonster::GetVectorToTarget ( void ) {
|
||||
if ( driver && driver->driver && driver->driver->pathTargetInfo.node ) {
|
||||
return driver->driver->pathTargetInfo.node->GetPhysics()->GetOrigin() - GetOrigin();
|
||||
}
|
||||
return vec3_origin;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleMonster::GetEnemyOrigin
|
||||
================
|
||||
*/
|
||||
const idVec3 & rvVehicleMonster::GetEnemyOrigin ( void ) {
|
||||
if ( driver && driver->enemy.ent ) {
|
||||
return driver->enemy.ent->GetPhysics()->GetOrigin();
|
||||
}
|
||||
return vec3_origin;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleMonster::GetVectorToEnemy
|
||||
================
|
||||
*/
|
||||
idVec3 rvVehicleMonster::GetVectorToEnemy ( void ) {
|
||||
if ( driver && driver->enemy.ent ) {
|
||||
//HACK: this is hideous, I'm ashamed.
|
||||
return ( driver->enemy.ent->GetPhysics()->GetOrigin() + idVec3( 0, 0, 36 ) )- GetOrigin();
|
||||
}
|
||||
return vec3_origin;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleMonster::LookAtEntity
|
||||
================
|
||||
*/
|
||||
void rvVehicleMonster::LookAtEntity ( idEntity *ent, float duration ) {
|
||||
const idVec3 entOrigin = ent->GetPhysics()->GetOrigin();
|
||||
const idVec3 origin = GetOrigin();
|
||||
idVec3 toEnt = entOrigin - origin;
|
||||
toEnt.Normalize();
|
||||
GetPhysics()->SetAxis( toEnt.ToMat3() );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleMonster::SkipImpulse
|
||||
================
|
||||
*/
|
||||
bool rvVehicleMonster::SkipImpulse( idEntity* ent, int id ) {
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
//----------------------------------------------------------------
|
||||
// VehicleMonster.h
|
||||
//
|
||||
// Copyright 2002-2004 Raven Software
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#ifndef __GAME_VEHICLEMONSTER_H__
|
||||
#define __GAME_VEHICLEMONSTER_H__
|
||||
|
||||
#ifndef __GAME_VEHICLE_H__
|
||||
#include "Vehicle.h"
|
||||
#endif
|
||||
|
||||
class rvVehicleAI;
|
||||
|
||||
class rvVehicleMonster : public rvVehicle {
|
||||
friend class rvVehicleAI;
|
||||
public:
|
||||
|
||||
CLASS_PROTOTYPE( rvVehicleMonster );
|
||||
|
||||
rvVehicleMonster ( void );
|
||||
~rvVehicleMonster ( void );
|
||||
|
||||
void Spawn ( void );
|
||||
void Think ( void );
|
||||
void Save ( idSaveGame *savefile ) const;
|
||||
void Restore ( idRestoreGame *savefile );
|
||||
|
||||
bool SkipImpulse ( idEntity* ent, int id );
|
||||
|
||||
protected:
|
||||
|
||||
void SetClipModel ( idPhysics & physicsObj );
|
||||
|
||||
const idVec3 & GetTargetOrigin ( void );
|
||||
idVec3 GetVectorToTarget ( void );
|
||||
const idVec3 & GetEnemyOrigin ( void );
|
||||
idVec3 GetVectorToEnemy ( void );
|
||||
void LookAtEntity ( idEntity *ent, float duration );
|
||||
|
||||
idEntityPtr<rvVehicleAI> driver;
|
||||
};
|
||||
|
||||
#endif // __GAME_VEHICLEMONSTER_H__
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,444 @@
|
||||
//----------------------------------------------------------------
|
||||
// VehicleParts.h
|
||||
//
|
||||
// Copyright 2002-2004 Raven Software
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#ifndef __GAME_VEHICLEPARTS_H__
|
||||
#define __GAME_VEHICLEPARTS_H__
|
||||
|
||||
class idWeapon;
|
||||
class rvVehicle;
|
||||
class rvVehiclePosition;
|
||||
class rvEffect;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Base Part
|
||||
//----------------------------------------------------------------
|
||||
|
||||
class rvVehiclePart : public idClass
|
||||
{
|
||||
public:
|
||||
|
||||
ABSTRACT_PROTOTYPE( rvVehiclePart );
|
||||
|
||||
virtual ~rvVehiclePart( void ) { }
|
||||
|
||||
void Spawn ( void );
|
||||
void Save ( idSaveGame* saveFile ) const;
|
||||
void Restore ( idRestoreGame* saveFile );
|
||||
|
||||
virtual bool Init ( rvVehiclePosition* position, const idDict& args, s_channelType soundChannel );
|
||||
|
||||
virtual void RunPrePhysics ( void ) { }
|
||||
virtual void RunPhysics ( void ) { }
|
||||
virtual void RunPostPhysics ( void ) { }
|
||||
|
||||
bool IsLeft ( void ) const;
|
||||
bool IsFront ( void ) const;
|
||||
bool IsUsingCenterMass ( void ) const;
|
||||
bool IsActive ( void ) const;
|
||||
|
||||
virtual void Activate ( bool activate ) { fl.active = activate; }
|
||||
|
||||
virtual void Impulse ( int impulse ) { }
|
||||
|
||||
virtual rvVehiclePosition* GetPosition ( void ) const;
|
||||
const idVec3& GetOrigin ( void ) const;
|
||||
const idMat3& GetAxis ( void ) const;
|
||||
|
||||
protected:
|
||||
|
||||
void UpdateOrigin ( void );
|
||||
|
||||
typedef struct partFlags_s {
|
||||
bool active : 1; // Is part active
|
||||
bool left : 1; // Is part on left side of vehicle
|
||||
bool front : 1; // Is part on right side of vehicle
|
||||
bool useCenterMass : 1; // Use center of mass for origin
|
||||
bool useViewAxis : 1; // Uses parent->viewAxis instead of the physics axis (::UpdateOrigin())
|
||||
} partFlags_t;
|
||||
|
||||
partFlags_t fl;
|
||||
|
||||
idDict spawnArgs;
|
||||
idEntityPtr<rvVehicle> parent;
|
||||
jointHandle_t joint;
|
||||
s_channelType soundChannel;
|
||||
rvVehiclePosition* position;
|
||||
|
||||
idVec3 worldOrigin;
|
||||
idMat3 worldAxis;
|
||||
idVec3 localOffset;
|
||||
};
|
||||
|
||||
ID_INLINE rvVehiclePosition* rvVehiclePart::GetPosition ( void ) const { return position; }
|
||||
ID_INLINE const idVec3& rvVehiclePart::GetOrigin ( void ) const { return worldOrigin; }
|
||||
ID_INLINE const idMat3& rvVehiclePart::GetAxis ( void ) const { return worldAxis; }
|
||||
|
||||
ID_INLINE bool rvVehiclePart::IsLeft ( void ) const { return fl.left; }
|
||||
ID_INLINE bool rvVehiclePart::IsFront ( void ) const { return fl.front; }
|
||||
ID_INLINE bool rvVehiclePart::IsUsingCenterMass ( void ) const { return fl.useCenterMass; }
|
||||
ID_INLINE bool rvVehiclePart::IsActive ( void ) const { return fl.active; }
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Sound
|
||||
//----------------------------------------------------------------
|
||||
|
||||
class rvVehicleSound : public rvVehiclePart {
|
||||
public:
|
||||
|
||||
CLASS_PROTOTYPE( rvVehicleSound );
|
||||
|
||||
rvVehicleSound ( void );
|
||||
~rvVehicleSound ( void );
|
||||
|
||||
void Spawn ( void );
|
||||
void Save ( idSaveGame* saveFile ) const;
|
||||
void Restore ( idRestoreGame* saveFile );
|
||||
|
||||
virtual void RunPostPhysics ( void );
|
||||
virtual void Activate ( bool active );
|
||||
|
||||
bool IsPlaying ( void ) const;
|
||||
|
||||
void Play ( void );
|
||||
void Stop ( void );
|
||||
void Update ( bool force = false );
|
||||
|
||||
void Fade ( int time, float toVolume, float toFreq );
|
||||
void Attenuate ( float volumeAttenuate, float freqAttenuate );
|
||||
|
||||
void SetAutoActivate ( bool activate );
|
||||
|
||||
protected:
|
||||
|
||||
idVec2 volume;
|
||||
idVec2 freqShift;
|
||||
idStr soundName;
|
||||
refSound_t refSound;
|
||||
idInterpolate<float> currentVolume;
|
||||
idInterpolate<float> currentFreqShift;
|
||||
bool fade;
|
||||
bool autoActivate;
|
||||
};
|
||||
|
||||
ID_INLINE bool rvVehicleSound::IsPlaying ( void ) const {
|
||||
idSoundEmitter *emitter = soundSystem->EmitterForIndex( SOUNDWORLD_GAME, refSound.referenceSoundHandle );
|
||||
if( emitter ) {
|
||||
return ( emitter->CurrentlyPlaying ( ) );
|
||||
}
|
||||
return( false );
|
||||
}
|
||||
|
||||
ID_INLINE void rvVehicleSound::SetAutoActivate ( bool activate ){
|
||||
autoActivate = activate;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Hoverpad
|
||||
//----------------------------------------------------------------
|
||||
|
||||
class rvVehicleHoverpad : public rvVehiclePart {
|
||||
public:
|
||||
|
||||
CLASS_PROTOTYPE( rvVehicleHoverpad );
|
||||
|
||||
rvVehicleHoverpad ( void );
|
||||
~rvVehicleHoverpad ( void );
|
||||
|
||||
void Spawn ( void );
|
||||
void Save ( idSaveGame* saveFile ) const;
|
||||
void Restore ( idRestoreGame* saveFile );
|
||||
|
||||
virtual void RunPrePhysics ( void );
|
||||
virtual void RunPhysics ( void );
|
||||
virtual void Activate ( bool active );
|
||||
|
||||
protected:
|
||||
|
||||
void UpdateDustEffect ( const idVec3& origin, const idMat3& axis, float attenuation, const rvDeclMatType* mtype );
|
||||
|
||||
float height;
|
||||
float dampen;
|
||||
bool atRest;
|
||||
|
||||
idClipModel* clipModel;
|
||||
|
||||
idInterpolate<float> currentForce;
|
||||
float force;
|
||||
const idDeclTable* forceTable;
|
||||
float forceRandom;
|
||||
|
||||
float fadeTime;
|
||||
idVec3 velocity;
|
||||
|
||||
float thrustForward;
|
||||
float thrustLeft;
|
||||
|
||||
float maxRestAngle;
|
||||
|
||||
int soundPart;
|
||||
|
||||
int forceUpTime;
|
||||
int forceDownTime;
|
||||
|
||||
// Dust effects
|
||||
rvClientEntityPtr<rvClientEffect> effectDust;
|
||||
const rvDeclMatType* effectDustMaterialType;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Thruster
|
||||
//----------------------------------------------------------------
|
||||
|
||||
class rvVehicleThruster : public rvVehiclePart {
|
||||
public:
|
||||
|
||||
CLASS_PROTOTYPE( rvVehicleThruster );
|
||||
|
||||
rvVehicleThruster ( void );
|
||||
~rvVehicleThruster ( void );
|
||||
|
||||
void Spawn ( void );
|
||||
void Save ( idSaveGame* saveFile ) const;
|
||||
void Restore ( idRestoreGame* saveFile );
|
||||
|
||||
virtual void RunPhysics ( void );
|
||||
|
||||
protected:
|
||||
|
||||
enum EThrusterKey
|
||||
{
|
||||
KEY_FORWARD,
|
||||
KEY_RIGHT,
|
||||
KEY_UP
|
||||
};
|
||||
|
||||
float force;
|
||||
int forceAxis;
|
||||
EThrusterKey key;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Light
|
||||
//----------------------------------------------------------------
|
||||
|
||||
class rvVehicleLight : public rvVehiclePart {
|
||||
public:
|
||||
|
||||
CLASS_PROTOTYPE( rvVehicleLight );
|
||||
|
||||
rvVehicleLight ( void );
|
||||
~rvVehicleLight ( void );
|
||||
|
||||
void Spawn ( void );
|
||||
void Save ( idSaveGame* saveFile ) const;
|
||||
void Restore ( idRestoreGame* saveFile );
|
||||
|
||||
virtual void RunPostPhysics ( void );
|
||||
virtual void Activate ( bool active );
|
||||
|
||||
virtual void Impulse ( int impulse );
|
||||
|
||||
protected:
|
||||
|
||||
void TurnOff ( void );
|
||||
void TurnOn ( void );
|
||||
|
||||
void UpdateLightDef ( void );
|
||||
|
||||
renderLight_t renderLight;
|
||||
int lightHandle;
|
||||
bool lightOn;
|
||||
|
||||
idStr soundOn;
|
||||
idStr soundOff;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Weapon
|
||||
//----------------------------------------------------------------
|
||||
class rvVehicleWeapon : public rvVehiclePart {
|
||||
public:
|
||||
CLASS_PROTOTYPE( rvVehicleWeapon );
|
||||
|
||||
rvVehicleWeapon ( void );
|
||||
~rvVehicleWeapon ( void );
|
||||
|
||||
void Spawn ( void );
|
||||
void Save ( idSaveGame* saveFile ) const;
|
||||
void Restore ( idRestoreGame* saveFile );
|
||||
|
||||
virtual void RunPostPhysics ( void );
|
||||
virtual void Activate ( bool activate );
|
||||
|
||||
int GetCurrentAmmo ( void ) const;
|
||||
float GetCurrentCharge ( void ) const;
|
||||
|
||||
void UpdateCursorGUI ( idUserInterface* gui ) const;
|
||||
|
||||
bool Fire ();
|
||||
|
||||
int GetZoomFov ( void ) const;
|
||||
idUserInterface * GetZoomGui ( void ) const;
|
||||
float GetZoomTime ( void ) const;
|
||||
bool CanZoom ( void ) const;
|
||||
|
||||
void StopTargetEffect ( void );
|
||||
|
||||
protected:
|
||||
#ifdef _XENON
|
||||
idActor* bestEnemy;
|
||||
void AutoAim( idPlayer* player, const idVec3& origin, idVec3& dir );
|
||||
#endif
|
||||
void LaunchHitScan ( const idVec3& origin, const idVec3& dir, const idVec3& jointOrigin );
|
||||
void LaunchProjectile ( const idVec3& origin, const idVec3& dir, const idVec3& pushVelocity );
|
||||
void LaunchProjectiles ();
|
||||
|
||||
void UpdateLock ( void );
|
||||
void GetLockInfo ( const idVec3& eyeOrigin, const idMat3& eyeAxis );
|
||||
|
||||
void EjectBrass ( void );
|
||||
|
||||
void MuzzleFlashLight ( const idVec3& origin, const idMat3& axis );
|
||||
void WeaponFeedback ( const idDict* dict );
|
||||
|
||||
int nextFireTime;
|
||||
int fireDelay;
|
||||
int count;
|
||||
const idDict* projectileDef;
|
||||
const idDict* hitScanDef;
|
||||
float spread;
|
||||
bool launchFromJoint;
|
||||
bool lockScanning;
|
||||
int lastLockTime;
|
||||
float lockRange;
|
||||
|
||||
idEntityPtr<idEntity> targetEnt;
|
||||
jointHandle_t targetJoint;
|
||||
idVec3 targetPos;
|
||||
rvClientEntityPtr<rvClientEffect> targetEffect;
|
||||
|
||||
idList<jointHandle_t> joints;
|
||||
int jointIndex;
|
||||
|
||||
idVec3 force;
|
||||
|
||||
int ammoPerCharge;
|
||||
int chargeTime;
|
||||
int currentAmmo;
|
||||
idInterpolate<float> currentCharge;
|
||||
|
||||
renderLight_t muzzleFlash;
|
||||
int muzzleFlashHandle;
|
||||
int muzzleFlashEnd;
|
||||
int muzzleFlashTime;
|
||||
idVec3 muzzleFlashOffset;
|
||||
|
||||
int animNum;
|
||||
int animChannel;
|
||||
|
||||
const idSoundShader* shaderFire;
|
||||
const idSoundShader* shaderReload;
|
||||
|
||||
const idDict* brassDict;
|
||||
jointHandle_t brassEjectJoint;
|
||||
idVec3 brassEjectOffset;
|
||||
int brassEjectNext;
|
||||
int brassEjectDelay;
|
||||
|
||||
int zoomFov;
|
||||
idUserInterface * zoomGui;
|
||||
float zoomTime;
|
||||
};
|
||||
|
||||
ID_INLINE int rvVehicleWeapon::GetCurrentAmmo ( void ) const { return currentAmmo; }
|
||||
ID_INLINE float rvVehicleWeapon::GetCurrentCharge ( void ) const { return currentCharge.IsDone(gameLocal.time) ? 1.0f : currentCharge.GetCurrentValue(gameLocal.time); }
|
||||
ID_INLINE int rvVehicleWeapon::GetZoomFov ( void ) const { return zoomFov; }
|
||||
ID_INLINE idUserInterface* rvVehicleWeapon::GetZoomGui ( void ) const { return zoomGui; }
|
||||
ID_INLINE float rvVehicleWeapon::GetZoomTime ( void ) const { return zoomTime; }
|
||||
ID_INLINE bool rvVehicleWeapon::CanZoom ( void ) const { return zoomFov != -1; }
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Turret
|
||||
//----------------------------------------------------------------
|
||||
|
||||
class rvVehicleTurret : public rvVehiclePart {
|
||||
public:
|
||||
|
||||
CLASS_PROTOTYPE( rvVehicleTurret );
|
||||
|
||||
rvVehicleTurret ( void );
|
||||
|
||||
void Spawn ( void );
|
||||
void Save ( idSaveGame* saveFile ) const;
|
||||
void Restore ( idRestoreGame* saveFile );
|
||||
|
||||
virtual void RunPrePhysics ( void );
|
||||
virtual void RunPostPhysics ( void );
|
||||
virtual void Activate ( bool active );
|
||||
|
||||
protected:
|
||||
|
||||
idBounds angles;
|
||||
int axisMap[3];
|
||||
|
||||
float invert[3];
|
||||
|
||||
idAngles currentAngles;
|
||||
|
||||
int moveTime;
|
||||
float turnRate;
|
||||
|
||||
int soundPart;
|
||||
|
||||
bool parentStuck;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Animated Vehicle Part
|
||||
//----------------------------------------------------------------
|
||||
|
||||
class rvVehicleUserAnimated : public rvVehiclePart {
|
||||
public:
|
||||
|
||||
CLASS_PROTOTYPE( rvVehicleUserAnimated );
|
||||
|
||||
rvVehicleUserAnimated ( void );
|
||||
|
||||
void Spawn ( void );
|
||||
void Save ( idSaveGame* saveFile ) const;
|
||||
void Restore ( idRestoreGame* saveFile );
|
||||
|
||||
virtual void RunPrePhysics ( void );
|
||||
|
||||
void Event_PostSpawn ( void );
|
||||
|
||||
protected:
|
||||
|
||||
typedef struct rvUserAnimatedAnim_s {
|
||||
int index;
|
||||
float frame;
|
||||
short length;
|
||||
short channel;
|
||||
float rate;
|
||||
bool loop;
|
||||
} rvUserAnimatedAnim_t;
|
||||
|
||||
enum { VUAA_Forward, VUAA_Strafe, VUAA_Crouch, VUAA_Attack, VUAA_Count };
|
||||
enum { VUAF_Forward, VUAF_Strafe, VUAF_Crouch, VUAF_Attack, VUAF_Count };
|
||||
|
||||
rvUserAnimatedAnim_t anims[ VUAA_Count ];
|
||||
rvScriptFuncUtility funcs[ VUAF_Count ];
|
||||
|
||||
void InitAnim( const char * action, rvUserAnimatedAnim_t & anim );
|
||||
void InitFunc( const char * action, rvScriptFuncUtility & func );
|
||||
void SetFrame( const rvUserAnimatedAnim_t & anim );
|
||||
void LateralMove( signed char input, int anim, int func );
|
||||
};
|
||||
|
||||
typedef idList<rvVehiclePart*> rvVehiclePartList_t;
|
||||
|
||||
#endif // __GAME_VEHICLEPARTS_H__
|
||||
@@ -0,0 +1,847 @@
|
||||
//----------------------------------------------------------------
|
||||
// VehicleController.cpp
|
||||
//
|
||||
// Copyright 2002-2004 Raven Software
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#include "precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "../Game_local.h"
|
||||
#include "Vehicle.h"
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::rvVehiclePosition
|
||||
================
|
||||
*/
|
||||
rvVehiclePosition::rvVehiclePosition ( void ) {
|
||||
memset ( &mInputCmd, 0, sizeof(mInputCmd) );
|
||||
mInputAngles.Zero ( );
|
||||
|
||||
memset ( &fl, 0, sizeof(fl) );
|
||||
|
||||
mCurrentWeapon = -1;
|
||||
mSoundPart = -1;
|
||||
|
||||
mDriver = NULL;
|
||||
mParent = NULL;
|
||||
|
||||
mEyeOrigin.Zero();
|
||||
mEyeAxis.Identity();
|
||||
|
||||
mEyeOffset.Zero();
|
||||
mEyeJoint = INVALID_JOINT;
|
||||
|
||||
mDriverOffset.Zero ( );
|
||||
mDriverJoint = INVALID_JOINT;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::~rvVehiclePosition
|
||||
================
|
||||
*/
|
||||
rvVehiclePosition::~rvVehiclePosition ( void ) {
|
||||
mParts.DeleteContents ( true );
|
||||
mWeapons.DeleteContents ( true );
|
||||
}
|
||||
|
||||
void InitIntArray( const idVec3& vec, int array[] ) {
|
||||
int ix;
|
||||
for( ix = 0; ix < vec.GetDimension(); ++ix ) {
|
||||
array[ix] = (int)vec[ix];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::Init
|
||||
================
|
||||
*/
|
||||
void rvVehiclePosition::Init ( rvVehicle* parent, const idDict& args ) {
|
||||
idVec3 garbage;
|
||||
|
||||
mParent = parent;
|
||||
|
||||
mEyeJoint = mParent->GetAnimator()->GetJointHandle ( args.GetString ( "eyeJoint" ) );
|
||||
// abahr & twhitaker: removed this due to other changes.
|
||||
//if( !mParent->GetAnimator()->GetJointTransform(mEyeJoint, gameLocal.GetTime(), garbage, mEyeJointTransform) ) {
|
||||
mEyeJointTransform.Identity();
|
||||
//}
|
||||
//mEyeJointTransform.TransposeSelf();
|
||||
mEyeOffset = args.GetVector ( "eyeOffset", "0 0 0" );
|
||||
mDeltaEyeAxisScale = args.GetAngles( "deltaEyeAxisScale", "1 1 0" );
|
||||
mDeltaEyeAxisScale.Clamp( ang_zero, idAngles(1.0f, 1.0f, 1.0f) );
|
||||
InitIntArray( args.GetVector("eyeJointAxisMap", "0 1 2"), mEyeJointAxisMap );
|
||||
InitIntArray( args.GetVector("eyeJointDirMap", "1 1 1"), mEyeJointDirMap );
|
||||
|
||||
mAxisOffset = args.GetAngles( "angles_offset" ).ToMat3();
|
||||
|
||||
mDriverJoint = mParent->GetAnimator()->GetJointHandle ( args.GetString ( "driverJoint" ) );
|
||||
// abahr & twhitaker: removed this due to other changes.
|
||||
//if( !mParent->GetAnimator()->GetJointTransform(mDriverJoint, gameLocal.GetTime(), garbage, mDriverJointTransform) ) {
|
||||
mDriverJointTransform.Identity();
|
||||
//}
|
||||
//mDriverJointTransform.TransposeSelf( );
|
||||
mDriverOffset = args.GetVector ( "driverOffset", "0 0 0" );
|
||||
mDeltaDriverAxisScale = args.GetAngles( "deltaDriverAxisScale", "1 1 0" );
|
||||
mDeltaDriverAxisScale.Clamp( ang_zero, idAngles(1.0f, 1.0f, 1.0f) );
|
||||
InitIntArray( args.GetVector("driverJointAxisMap", "0 1 2"), mDriverJointAxisMap );
|
||||
InitIntArray( args.GetVector("driverJointDirMap", "1 1 1"), mDriverJointDirMap );
|
||||
|
||||
mExitPosOffset = args.GetVector( "exitPosOffset" );
|
||||
mExitAxisOffset = args.GetAngles( "exitAxisOffset" ).ToMat3();
|
||||
|
||||
mDriverAnim = args.GetString ( "driverAnim", "driver" );
|
||||
|
||||
fl.driverVisible = args.GetBool ( "driverVisible", "0" );
|
||||
fl.engine = args.GetBool ( "engine", "0" );
|
||||
fl.depthHack = args.GetBool ( "depthHack", "1" );
|
||||
fl.bindDriver = args.GetBool ( "bindDriver", "1" );
|
||||
|
||||
args.GetString ( "internalSurface", "", mInternalSurface );
|
||||
|
||||
SetParts ( args );
|
||||
|
||||
mSoundMaxSpeed = args.GetFloat ( "maxsoundspeed", "0" );
|
||||
|
||||
// Looping sound when occupied?
|
||||
// jmarshall - vehicle sound loops cause a crash, disabling for the time being.
|
||||
//if ( *args.GetString ( "snd_loop", "" ) ) {
|
||||
// mSoundPart = AddPart ( rvVehicleSound::GetClassType(), args );
|
||||
// static_cast<rvVehicleSound*>(mParts[mSoundPart])->SetAutoActivate ( false );
|
||||
//}
|
||||
// jmarshall end
|
||||
|
||||
SelectWeapon ( 0 );
|
||||
|
||||
UpdateInternalView ( true );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::SetParts
|
||||
================
|
||||
*/
|
||||
void rvVehiclePosition::SetParts ( const idDict& args ) {
|
||||
const idKeyValue* kv;
|
||||
|
||||
// Spawn all parts
|
||||
kv = args.MatchPrefix( "def_part", NULL );
|
||||
while ( kv ) {
|
||||
const idDict* dict;
|
||||
idTypeInfo* typeInfo;
|
||||
|
||||
// Skip empty strings
|
||||
if ( !kv->GetValue().Length() ) {
|
||||
kv = args.MatchPrefix( "def_part", kv );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the dictionary for the part
|
||||
dict = gameLocal.FindEntityDefDict ( kv->GetValue() );
|
||||
if ( !dict ) {
|
||||
gameLocal.Error ( "Invalid vehicle part definition '%'", kv->GetValue().c_str() );
|
||||
}
|
||||
|
||||
// Determine the part type
|
||||
typeInfo = idClass::GetClass ( dict->GetString ( "spawnclass" ) );
|
||||
if ( !typeInfo || !typeInfo->IsType ( rvVehiclePart::GetClassType() ) ) {
|
||||
gameLocal.Error ( "Class '%s' is not a vehicle part", dict->GetString ( "spawnclass" ) );
|
||||
}
|
||||
|
||||
// Add the new part
|
||||
AddPart ( *typeInfo, *dict );
|
||||
|
||||
kv = args.MatchPrefix( "def_part", kv );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::AddPart
|
||||
================
|
||||
*/
|
||||
int rvVehiclePosition::AddPart ( const idTypeInfo &classdef, const idDict& args ) {
|
||||
rvVehiclePart* part;
|
||||
int soundChannel;
|
||||
|
||||
// Get a sound channel
|
||||
soundChannel = SND_CHANNEL_CUSTOM;
|
||||
soundChannel += mParts.Num();
|
||||
|
||||
// Allocate the new part
|
||||
part = static_cast<rvVehiclePart*>(classdef.CreateInstance ( ));
|
||||
part->Init ( this, args, (s_channelType)soundChannel );
|
||||
part->CallSpawn ( );
|
||||
|
||||
// Weapons go into their own list since only one can be active
|
||||
// and any given point in time.
|
||||
if ( part->IsType ( rvVehicleWeapon::GetClassType() ) ) {
|
||||
return mWeapons.Append ( part );
|
||||
}
|
||||
|
||||
return mParts.Append ( part );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::SetDriver
|
||||
================
|
||||
*/
|
||||
bool rvVehiclePosition::SetDriver ( idActor* driver ) {
|
||||
if ( mDriver == driver ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fl.inputValid = false;
|
||||
|
||||
if ( driver ) {
|
||||
mDriver = driver;
|
||||
|
||||
// Keep the driver visible if the position is exposed
|
||||
if ( fl.driverVisible ) {
|
||||
mDriver->Show ( );
|
||||
} else {
|
||||
mDriver->Hide ( );
|
||||
|
||||
// Dont let the player take damage when inside the if not visible
|
||||
mDriver->fl.takedamage = false;
|
||||
}
|
||||
|
||||
if ( mSoundPart != -1 ) {
|
||||
static_cast<rvVehicleSound*>(mParts[mSoundPart])->Play ( );
|
||||
}
|
||||
|
||||
// Bind the driver to a joint or to the vehicles origin?
|
||||
if( fl.bindDriver ) {
|
||||
if ( INVALID_JOINT != mDriverJoint ) {
|
||||
mDriver->GetPhysics()->SetAxis ( mParent->GetAxis( ) );// Not sure if this is needed
|
||||
mDriver->BindToJoint ( mParent, mDriverJoint, true );
|
||||
mDriver->GetPhysics()->SetOrigin ( vec3_origin );
|
||||
} else {
|
||||
mDriver->Bind ( mParent, true );
|
||||
mDriver->GetPhysics()->SetOrigin( mDriverOffset );
|
||||
}
|
||||
} else {// If not bound put the vehicle first in the active list
|
||||
mParent->activeNode.Remove();
|
||||
mParent->activeNode.AddToFront( gameLocal.activeEntities );
|
||||
}
|
||||
|
||||
// Play a certain animation on the driver
|
||||
if ( mDriverAnim.Length() ) {
|
||||
mDriver->GetAnimator()->CycleAnim( ANIMCHANNEL_ALL, mDriver->GetAnimator()->GetAnim( mDriverAnim ), gameLocal.time, 0 );
|
||||
}
|
||||
} else {
|
||||
if ( !fl.driverVisible ) {
|
||||
mDriver->Show ( );
|
||||
|
||||
// Take damage again
|
||||
mDriver->fl.takedamage = true;
|
||||
}
|
||||
|
||||
// Driver is no longer bound to the vehicle
|
||||
mDriver->Unbind();
|
||||
|
||||
mDriver = driver;
|
||||
|
||||
if ( mSoundPart != -1 ) {
|
||||
static_cast<rvVehicleSound*>(mParts[mSoundPart])->Stop ( );
|
||||
}
|
||||
|
||||
// Clear out the input commands so the guns dont keep firing and what not when
|
||||
// the player gets out
|
||||
memset ( &mInputCmd, 0, sizeof(mInputCmd) );
|
||||
mInputAngles.Zero ( );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::GetAxis
|
||||
================
|
||||
*/
|
||||
idMat3 rvVehiclePosition::GetAxis() const {
|
||||
return mAxisOffset * GetParent()->GetPhysics()->GetAxis();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::GetOrigin
|
||||
================
|
||||
*/
|
||||
idVec3 rvVehiclePosition::GetOrigin( const idVec3& offset ) const {
|
||||
return GetParent()->GetPhysics()->GetOrigin() + (mDriverOffset + offset) * GetAxis();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::ActivateParts
|
||||
================
|
||||
*/
|
||||
void rvVehiclePosition::ActivateParts ( bool active ) {
|
||||
int i;
|
||||
|
||||
// Activate or deactive the parts based on whether there is a driver
|
||||
for ( i = mParts.Num() - 1; i >= 0; i -- ) {
|
||||
mParts[i]->Activate ( active );
|
||||
}
|
||||
|
||||
for ( i = mWeapons.Num() - 1; i >= 0; i -- ) {
|
||||
mWeapons[i]->Activate ( active );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::EjectDriver
|
||||
================
|
||||
*/
|
||||
bool rvVehiclePosition::EjectDriver ( bool force ) {
|
||||
if ( !IsOccupied ( ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Physically eject the actor from the position
|
||||
if ( !force && mParent->IsLocked ( ) ) {
|
||||
mParent->IssueLockedWarning ( );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove the driver and if successful disable all parts for
|
||||
// this position
|
||||
if ( SetDriver ( NULL ) ) {
|
||||
ActivateParts ( false );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::SetInput
|
||||
================
|
||||
*/
|
||||
void rvVehiclePosition::SetInput ( const usercmd_t& cmd, const idAngles& newAngles ) {
|
||||
if ( gameDebug.IsHudActive ( DBGHUD_VEHICLE ) ) {
|
||||
if ( mDriver == gameLocal.GetLocalPlayer ( ) ) {
|
||||
gameDebug.SetFocusEntity ( mParent );
|
||||
}
|
||||
}
|
||||
|
||||
if ( fl.inputValid || !mDriver ) {
|
||||
mOldInputCmd = mInputCmd;
|
||||
mOldInputAngles = mInputAngles;
|
||||
} else {
|
||||
mOldInputCmd = cmd;
|
||||
mInputCmd = cmd;
|
||||
mInputAngles = newAngles;
|
||||
|
||||
// We have valid input now and there is a driver so activate all of the parts
|
||||
if ( !fl.inputValid && mDriver ) {
|
||||
ActivateParts ( true );
|
||||
}
|
||||
}
|
||||
|
||||
fl.inputValid = true;
|
||||
mInputCmd = cmd;
|
||||
mInputAngles = newAngles;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::GetInput
|
||||
================
|
||||
*/
|
||||
void rvVehiclePosition::GetInput( usercmd_t& cmd, idAngles& newAngles ) const {
|
||||
cmd = mInputCmd;
|
||||
newAngles = mInputAngles;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::UpdateHUD
|
||||
================
|
||||
*/
|
||||
void rvVehiclePosition::UpdateHUD ( idUserInterface* gui ) {
|
||||
|
||||
// HACK: twhitaker: this is ugly but since the GEV and the Walker now have a unified HUD, it is a necessary evil
|
||||
int guiWeaponID;
|
||||
|
||||
if ( !stricmp( mParent->spawnArgs.GetString( "classname" ), "vehicle_walker" ) ) {
|
||||
guiWeaponID = mCurrentWeapon + 2;
|
||||
} else {
|
||||
guiWeaponID = mCurrentWeapon;
|
||||
}
|
||||
|
||||
gui->SetStateInt ( "vehicle_weapon", guiWeaponID );
|
||||
// HACK: twhitaker end
|
||||
|
||||
gui->SetStateInt ( "vehicle_weaponcount", mWeapons.Num() );
|
||||
if ( mCurrentWeapon >= 0 && mCurrentWeapon < mWeapons.Num() ) {
|
||||
rvVehicleWeapon* weapon;
|
||||
weapon = static_cast<rvVehicleWeapon*>(mWeapons[mCurrentWeapon]);
|
||||
gui->SetStateFloat ( "vehicle_weaponcharge", weapon->GetCurrentCharge() );
|
||||
gui->SetStateInt ( "vehicle_weaponammo", weapon->GetCurrentAmmo() );
|
||||
}
|
||||
|
||||
// Calculate the rotation of the view in relation to the vehicle itself
|
||||
gui->SetStateFloat ( "vehicle_rotate", -idMath::AngleDelta ( mEyeAxis.ToAngles()[YAW], mParent->GetAxis ( ).ToAngles()[YAW] ) );
|
||||
|
||||
if( GetParent() ) {
|
||||
GetParent()->UpdateHUD( GetDriver(), gui );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::UpdateCursorGUI
|
||||
================
|
||||
*/
|
||||
void rvVehiclePosition::UpdateCursorGUI ( idUserInterface* gui ) {
|
||||
if ( mCurrentWeapon < 0 || mCurrentWeapon >= mWeapons.Num() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
rvVehicleWeapon* weapon;
|
||||
weapon = static_cast<rvVehicleWeapon*>(mWeapons[mCurrentWeapon]);
|
||||
assert ( weapon );
|
||||
weapon->UpdateCursorGUI ( gui );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::UpdateInternalView
|
||||
================
|
||||
*/
|
||||
void rvVehiclePosition::UpdateInternalView ( bool force ) {
|
||||
bool internal = false;
|
||||
|
||||
// If the local player is driving and not in third person then use internal
|
||||
internal = ( mDriver == gameLocal.GetLocalPlayer() && !pm_thirdPerson.GetInteger() );
|
||||
|
||||
// force the update?
|
||||
if ( !force && internal == fl.internalView ) {
|
||||
return;
|
||||
}
|
||||
|
||||
fl.internalView = internal;
|
||||
|
||||
if ( fl.depthHack ) {
|
||||
mParent->GetRenderEntity()->weaponDepthHackInViewID = (IsOccupied() && fl.internalView) ? GetDriver()->entityNumber + 1 : 0;
|
||||
}
|
||||
|
||||
// Show and hide the internal surface
|
||||
if ( mInternalSurface.Length() ) {
|
||||
mParent->ProcessEvent ( fl.internalView ? &EV_ShowSurface : &EV_HideSurface, mInternalSurface.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::RunPrePhysics
|
||||
================
|
||||
*/
|
||||
void rvVehiclePosition::RunPrePhysics ( void ) {
|
||||
int i;
|
||||
|
||||
UpdateInternalView ( );
|
||||
|
||||
if ( mParent->IsStalled() ) {
|
||||
if ( !fl.stalled ) {
|
||||
// we just stalled
|
||||
fl.stalled = true;
|
||||
ActivateParts( false );
|
||||
}
|
||||
return;
|
||||
} else if ( IsOccupied() && !mParent->IsStalled() && fl.stalled ) {
|
||||
// we just restarted
|
||||
fl.stalled = false;
|
||||
ActivateParts( true );
|
||||
}
|
||||
|
||||
// Give the parts a chance to set up for physics
|
||||
for ( i = mParts.Num() - 1; i >= 0; i -- ) {
|
||||
assert ( mParts[i] );
|
||||
mParts[i]->RunPrePhysics ( );
|
||||
}
|
||||
|
||||
if ( mCurrentWeapon >= 0 ) {
|
||||
mWeapons[mCurrentWeapon]->RunPrePhysics ( );
|
||||
}
|
||||
|
||||
// Run physics for each part
|
||||
for ( i = mParts.Num() - 1; i >= 0; i -- ) {
|
||||
assert ( mParts[i] );
|
||||
|
||||
mParts[i]->RunPhysics ( );
|
||||
}
|
||||
|
||||
// Attenuate the attached sound if speed based
|
||||
if ( mSoundPart != -1 && mSoundMaxSpeed > 0.0f ) {
|
||||
float f;
|
||||
float speed;
|
||||
idVec3 vel;
|
||||
|
||||
// Only interested in forward or backward velocity
|
||||
vel = mParent->GetPhysics()->GetLinearVelocity ( ) * mParent->GetPhysics()->GetAxis ( );
|
||||
speed = idMath::ClampFloat ( 0.0f, mSoundMaxSpeed, vel.Normalize ( ) );
|
||||
f = speed / mSoundMaxSpeed;
|
||||
|
||||
static_cast<rvVehicleSound*>(mParts[mSoundPart])->Attenuate ( f, f );
|
||||
}
|
||||
|
||||
if ( mCurrentWeapon >= 0 ) {
|
||||
mWeapons[mCurrentWeapon]->RunPhysics ( );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::RunPostPhysics
|
||||
================
|
||||
*/
|
||||
void rvVehiclePosition::RunPostPhysics ( void ) {
|
||||
int i;
|
||||
for ( i = 0; i < mParts.Num(); i ++ ) {
|
||||
assert ( mParts[i] );
|
||||
mParts[i]->RunPostPhysics ( );
|
||||
}
|
||||
|
||||
if ( mCurrentWeapon >= 0 ) {
|
||||
mWeapons[mCurrentWeapon]->RunPostPhysics ( );
|
||||
}
|
||||
|
||||
if ( !IsOccupied ( ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( fl.inputValid ) {
|
||||
if ( mInputCmd.upmove > 0 && !mParent->IsLocked() ) {
|
||||
// inform the driver that its time to get out of the vehicle.
|
||||
if( !mDriver->EventIsPosted(&AI_ExitVehicle) ) {
|
||||
mDriver->PostEventMS( &AI_ExitVehicle, 250, false );// To remove jump when exiting
|
||||
}
|
||||
|
||||
// If the position isnt occupied anymore then the vehicle exit was successful and there
|
||||
// is nothing else to do
|
||||
if ( !IsOccupied ( ) ) {
|
||||
return;
|
||||
}
|
||||
} else if ( (mInputCmd.flags & UCF_IMPULSE_SEQUENCE) != (mOldInputFlags & UCF_IMPULSE_SEQUENCE) ) {
|
||||
int i;
|
||||
|
||||
if ( mInputCmd.impulse >= IMPULSE_0 && mInputCmd.impulse <= IMPULSE_12 ) {
|
||||
SelectWeapon( mInputCmd.impulse - IMPULSE_0 );
|
||||
}
|
||||
|
||||
if ( mWeapons.Num () ) {
|
||||
switch ( mInputCmd.impulse ) {
|
||||
case IMPULSE_14:
|
||||
SelectWeapon ( (mCurrentWeapon + mWeapons.Num() + 1) % mWeapons.Num() );
|
||||
break;
|
||||
|
||||
case IMPULSE_15:
|
||||
SelectWeapon ( (mCurrentWeapon + mWeapons.Num() - 1) % mWeapons.Num() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < mParts.Num(); i++ ) {
|
||||
mParts[ i ]->Impulse ( mInputCmd.impulse );
|
||||
}
|
||||
|
||||
mOldInputFlags = mInputCmd.flags;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the eye origin and axis
|
||||
GetEyePosition( mEyeOrigin, mEyeAxis );
|
||||
|
||||
if ( g_debugVehicle.GetInteger() == 2 ) {
|
||||
gameRenderWorld->DebugArrow( colorMagenta, mEyeOrigin, mEyeOrigin + mEyeAxis[0] * 30.0f, 3 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::GetEyePosition
|
||||
================
|
||||
*/
|
||||
void rvVehiclePosition::GetEyePosition( idVec3& origin, idMat3& axis ) const {
|
||||
GetPosition( mEyeJoint, mEyeOffset, mEyeJointTransform, mDeltaEyeAxisScale, mEyeJointAxisMap, mEyeJointDirMap, origin, axis );
|
||||
axis *= GetParent()->GetAxis();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::GetDriverPosition
|
||||
================
|
||||
*/
|
||||
void rvVehiclePosition::GetDriverPosition( idVec3& origin, idMat3& axis ) const {
|
||||
if( fl.bindDriver ) {
|
||||
GetPosition( mDriverJoint, mDriverOffset, mDriverJointTransform, mDeltaDriverAxisScale, mDriverJointAxisMap, mDriverJointDirMap, origin, axis );
|
||||
} else {
|
||||
origin = GetDriver()->GetPhysics()->GetOrigin();
|
||||
axis = GetDriver()->viewAxis;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::GetPosition
|
||||
================
|
||||
*/
|
||||
void rvVehiclePosition::GetPosition( const jointHandle_t jointHandle, const idVec3& offset, const idMat3& jointTransform, const idAngles& scale, const int axisMap[], const int dirMap[], idVec3& origin, idMat3& axis ) const {
|
||||
if( GetParent()->GetAnimator()->GetJointTransform(jointHandle, gameLocal.GetTime(), origin, axis) ) {
|
||||
axis *= jointTransform;
|
||||
idAngles ang( axis.ToAngles().Remap(axisMap, dirMap).Scale(scale) );
|
||||
axis = ang.Normalize360().ToMat3() * mAxisOffset;
|
||||
|
||||
origin = GetParent()->GetOrigin() + (origin + offset * axis) * GetParent()->GetAxis();
|
||||
} else {
|
||||
origin = GetOrigin( mEyeOffset );
|
||||
axis = GetAxis();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::FireWeapon
|
||||
================
|
||||
*/
|
||||
void rvVehiclePosition::FireWeapon( void ) {
|
||||
if ( mCurrentWeapon >= 0 ) {
|
||||
static_cast<rvVehicleWeapon*>( mWeapons[mCurrentWeapon] )->Fire();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::SelectWeapon
|
||||
================
|
||||
*/
|
||||
void rvVehiclePosition::SelectWeapon ( int weapon ) {
|
||||
if ( weapon < 0 || weapon >= mWeapons.Num ( ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// mekberg: clear effect
|
||||
if ( mCurrentWeapon != -1 ) {
|
||||
static_cast<rvVehicleWeapon*> ( mWeapons[ mCurrentWeapon ] )->StopTargetEffect( );
|
||||
}
|
||||
|
||||
mCurrentWeapon = weapon;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::WriteToSnapshot
|
||||
================
|
||||
*/
|
||||
void rvVehiclePosition::WriteToSnapshot ( idBitMsgDelta &msg ) const {
|
||||
msg.WriteBits ( mCurrentWeapon, 3 );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::ReadFromSnapshot
|
||||
================
|
||||
*/
|
||||
void rvVehiclePosition::ReadFromSnapshot ( const idBitMsgDelta &msg ) {
|
||||
mCurrentWeapon = msg.ReadBits ( 3 );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::Save
|
||||
================
|
||||
*/
|
||||
void rvVehiclePosition::Save ( idSaveGame* savefile ) const {
|
||||
int i;
|
||||
|
||||
savefile->WriteUsercmd( mInputCmd );
|
||||
savefile->WriteAngles ( mInputAngles );
|
||||
savefile->WriteUsercmd ( mOldInputCmd );
|
||||
savefile->WriteAngles ( mOldInputAngles );
|
||||
savefile->WriteInt ( mOldInputFlags );
|
||||
|
||||
savefile->WriteInt ( mCurrentWeapon );
|
||||
|
||||
mDriver.Save ( savefile );
|
||||
mParent.Save ( savefile );
|
||||
|
||||
savefile->WriteInt ( mParts.Num ( ) );
|
||||
for ( i = 0; i < mParts.Num(); i ++ ) {
|
||||
savefile->WriteString ( mParts[i]->GetClassname() );
|
||||
savefile->WriteStaticObject ( *mParts[i] );
|
||||
}
|
||||
|
||||
savefile->WriteInt ( mWeapons.Num ( ) );
|
||||
for ( i = 0; i < mWeapons.Num(); i ++ ) {
|
||||
savefile->WriteString ( mWeapons[i]->GetClassname() );
|
||||
savefile->WriteStaticObject ( *mWeapons[i] );
|
||||
}
|
||||
|
||||
savefile->WriteVec3 ( mEyeOrigin );
|
||||
savefile->WriteMat3 ( mEyeAxis );
|
||||
|
||||
savefile->WriteJoint ( mEyeJoint );
|
||||
savefile->WriteVec3 ( mEyeOffset );
|
||||
savefile->WriteMat3( mEyeJointTransform );
|
||||
savefile->WriteAngles( mDeltaEyeAxisScale );
|
||||
savefile->Write ( mEyeJointAxisMap, sizeof mEyeJointAxisMap );
|
||||
savefile->Write ( mEyeJointDirMap, sizeof mEyeJointDirMap );
|
||||
|
||||
savefile->WriteMat3 ( mAxisOffset );
|
||||
|
||||
savefile->WriteJoint ( mDriverJoint );
|
||||
savefile->WriteVec3 ( mDriverOffset );
|
||||
savefile->WriteMat3 ( mDriverJointTransform );
|
||||
savefile->WriteAngles( mDeltaDriverAxisScale );
|
||||
savefile->Write ( mDriverJointAxisMap, sizeof mDriverJointAxisMap );
|
||||
savefile->Write ( mDriverJointDirMap, sizeof mDriverJointDirMap );
|
||||
|
||||
savefile->WriteVec3 ( mExitPosOffset );
|
||||
savefile->WriteMat3 ( mExitAxisOffset );
|
||||
|
||||
savefile->WriteString ( mDriverAnim );
|
||||
|
||||
savefile->WriteString ( mInternalSurface );
|
||||
|
||||
savefile->Write ( &fl, sizeof ( fl ) );
|
||||
|
||||
savefile->WriteInt ( mSoundPart );
|
||||
savefile->WriteFloat ( mSoundMaxSpeed );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehiclePosition::Restore
|
||||
================
|
||||
*/
|
||||
void rvVehiclePosition::Restore ( idRestoreGame* savefile ) {
|
||||
int i;
|
||||
int num;
|
||||
|
||||
savefile->ReadUsercmd( mInputCmd );
|
||||
savefile->ReadAngles ( mInputAngles );
|
||||
savefile->ReadUsercmd ( mOldInputCmd );
|
||||
savefile->ReadAngles ( mOldInputAngles );
|
||||
savefile->ReadInt ( mOldInputFlags );
|
||||
|
||||
savefile->ReadInt ( mCurrentWeapon );
|
||||
|
||||
mDriver.Restore ( savefile );
|
||||
mParent.Restore ( savefile );
|
||||
|
||||
savefile->ReadInt ( num );
|
||||
mParts.Clear ( );
|
||||
mParts.SetNum ( num );
|
||||
for ( i = 0; i < num; i ++ ) {
|
||||
idStr spawnclass;
|
||||
rvVehiclePart* part;
|
||||
idTypeInfo* typeInfo;
|
||||
|
||||
savefile->ReadString ( spawnclass );
|
||||
|
||||
// Determine the part type
|
||||
typeInfo = idClass::GetClass ( spawnclass );
|
||||
if ( !typeInfo || !typeInfo->IsType ( rvVehiclePart::GetClassType() ) )
|
||||
{
|
||||
gameLocal.Error ( "Class '%s' is not a vehicle part", spawnclass.c_str() );
|
||||
}
|
||||
|
||||
part = static_cast<rvVehiclePart*>(typeInfo->CreateInstance ( ));
|
||||
savefile->ReadStaticObject ( *part );
|
||||
mParts[i] = part;
|
||||
}
|
||||
|
||||
savefile->ReadInt ( num );
|
||||
mWeapons.Clear ( );
|
||||
mWeapons.SetNum ( num );
|
||||
for ( i = 0; i < num; i ++ ) {
|
||||
idStr spawnclass;
|
||||
rvVehiclePart* part;
|
||||
idTypeInfo* typeInfo;
|
||||
|
||||
savefile->ReadString ( spawnclass );
|
||||
|
||||
// Determine the part type
|
||||
typeInfo = idClass::GetClass ( spawnclass );
|
||||
if ( !typeInfo || !typeInfo->IsType ( rvVehiclePart::GetClassType() ) )
|
||||
{
|
||||
gameLocal.Error ( "Class '%s' is not a vehicle part", spawnclass.c_str() );
|
||||
}
|
||||
|
||||
part = static_cast<rvVehiclePart*>(typeInfo->CreateInstance ( ));
|
||||
savefile->ReadStaticObject ( *part );
|
||||
mWeapons[i] = part;
|
||||
}
|
||||
|
||||
savefile->ReadVec3 ( mEyeOrigin );
|
||||
savefile->ReadMat3 ( mEyeAxis );
|
||||
|
||||
savefile->ReadJoint ( mEyeJoint );
|
||||
savefile->ReadVec3 ( mEyeOffset );
|
||||
savefile->ReadMat3 ( mEyeJointTransform );
|
||||
savefile->ReadAngles( mDeltaEyeAxisScale );
|
||||
savefile->Read( mEyeJointAxisMap, sizeof mEyeJointAxisMap );
|
||||
savefile->Read( mEyeJointDirMap, sizeof mEyeJointDirMap );
|
||||
|
||||
savefile->ReadMat3 ( mAxisOffset );
|
||||
|
||||
savefile->ReadJoint ( mDriverJoint );
|
||||
savefile->ReadVec3 ( mDriverOffset );
|
||||
savefile->ReadMat3 ( mDriverJointTransform );
|
||||
savefile->ReadAngles( mDeltaDriverAxisScale );
|
||||
savefile->Read( mDriverJointAxisMap, sizeof mDriverJointAxisMap );
|
||||
savefile->Read( mDriverJointDirMap, sizeof mDriverJointDirMap );
|
||||
|
||||
savefile->ReadVec3 ( mExitPosOffset );
|
||||
savefile->ReadMat3 ( mExitAxisOffset );
|
||||
|
||||
savefile->ReadString ( mDriverAnim );
|
||||
|
||||
savefile->ReadString ( mInternalSurface );
|
||||
|
||||
savefile->Read ( &fl, sizeof(fl) );
|
||||
savefile->ReadInt ( mSoundPart );
|
||||
savefile->ReadFloat ( mSoundMaxSpeed );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
//----------------------------------------------------------------
|
||||
// Vehicle.cpp
|
||||
//
|
||||
// Copyright 2002-2004 Raven Software
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#include "precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "../Game_local.h"
|
||||
#include "VehicleRigid.h"
|
||||
|
||||
CLASS_DECLARATION( rvVehicle, rvVehicleRigid )
|
||||
END_CLASS
|
||||
|
||||
rvVehicleRigid::rvVehicleRigid ( void ) {
|
||||
}
|
||||
|
||||
rvVehicleRigid::~rvVehicleRigid ( void ) {
|
||||
SetPhysics( NULL );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleRigid::Spawn
|
||||
================
|
||||
*/
|
||||
void rvVehicleRigid::Spawn( void ) {
|
||||
physicsObj.SetSelf( this );
|
||||
|
||||
SetClipModel ( );
|
||||
|
||||
physicsObj.SetOrigin( GetPhysics()->GetOrigin ( ) );
|
||||
physicsObj.SetAxis ( GetPhysics()->GetAxis ( ) );
|
||||
physicsObj.SetContents( CONTENTS_BODY );
|
||||
physicsObj.SetClipMask( MASK_PLAYERSOLID|CONTENTS_VEHICLECLIP );
|
||||
physicsObj.SetFriction ( spawnArgs.GetFloat ( "friction_linear", "1" ), spawnArgs.GetFloat ( "friction_angular", "1" ), spawnArgs.GetFloat ( "friction_contact", "1" ) );
|
||||
physicsObj.SetBouncyness ( spawnArgs.GetFloat ( "bouncyness", "0.6" ) );
|
||||
physicsObj.SetGravity( gameLocal.GetGravity() );
|
||||
SetPhysics( &physicsObj );
|
||||
|
||||
animator.CycleAnim ( ANIMCHANNEL_ALL, animator.GetAnim( spawnArgs.GetString( "anim", "idle" ) ), gameLocal.time, 0 );
|
||||
|
||||
BecomeActive( TH_THINK );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleRigid::SetClipModel
|
||||
================
|
||||
*/
|
||||
void rvVehicleRigid::SetClipModel ( void ) {
|
||||
idStr clipModelName;
|
||||
idTraceModel trm;
|
||||
float mass;
|
||||
|
||||
// rebuild clipmodel
|
||||
spawnArgs.GetString( "clipmodel", "", clipModelName );
|
||||
|
||||
// load the trace model
|
||||
if ( clipModelName.Length() ) {
|
||||
if ( !collisionModelManager->TrmFromModel( gameLocal.GetMapName(), clipModelName, trm ) ) {
|
||||
gameLocal.Error( "rvVehicleRigid '%s': cannot load collision model %s", name.c_str(), clipModelName.c_str() );
|
||||
return;
|
||||
}
|
||||
|
||||
physicsObj.SetClipModel( new idClipModel( trm ), spawnArgs.GetFloat ( "density", "1" ) );
|
||||
} else {
|
||||
physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), spawnArgs.GetFloat ( "density", "1" ) );
|
||||
}
|
||||
|
||||
if ( spawnArgs.GetFloat ( "mass", "0", mass ) && mass > 0 ) {
|
||||
physicsObj.SetMass ( mass );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleRigid::RunPrePhysics
|
||||
================
|
||||
*/
|
||||
void rvVehicleRigid::RunPrePhysics ( void ) {
|
||||
storedVelocity = physicsObj.GetLinearVelocity();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleRigid::RunPostPhysics
|
||||
================
|
||||
*/
|
||||
void rvVehicleRigid::RunPostPhysics ( void ) {
|
||||
|
||||
if ( autoCorrectionBegin + 1250 > static_cast<unsigned>( gameLocal.time )) {
|
||||
autoCorrectionBegin = 0;
|
||||
|
||||
float lengthSq = physicsObj.GetLinearVelocity().LengthSqr();
|
||||
if ( !autoCorrectionBegin && ( ( storedVelocity * 0.4f ).LengthSqr() >= lengthSq ) || ( lengthSq < 0.01f ) ) {
|
||||
autoCorrectionBegin = gameLocal.time;
|
||||
}
|
||||
}
|
||||
|
||||
if ( g_debugVehicle.GetInteger() == 10 ) {
|
||||
gameLocal.Printf( "Speed: %f\n", physicsObj.GetLinearVelocity().Length() );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleRigid::WriteToSnapshot
|
||||
================
|
||||
*/
|
||||
void rvVehicleRigid::WriteToSnapshot( idBitMsgDelta &msg ) const {
|
||||
rvVehicle::WriteToSnapshot( msg );
|
||||
physicsObj.WriteToSnapshot( msg );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleRigid::ReadFromSnapshot
|
||||
================
|
||||
*/
|
||||
void rvVehicleRigid::ReadFromSnapshot( const idBitMsgDelta &msg ) {
|
||||
rvVehicle::ReadFromSnapshot( msg );
|
||||
physicsObj.ReadFromSnapshot( msg );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleRigid::Save
|
||||
================
|
||||
*/
|
||||
void rvVehicleRigid::Save ( idSaveGame *savefile ) const {
|
||||
|
||||
savefile->WriteVec3 ( storedVelocity ); // cnicholson: Added unsaved var
|
||||
savefile->WriteStaticObject ( physicsObj );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleRigid::Restore
|
||||
================
|
||||
*/
|
||||
void rvVehicleRigid::Restore ( idRestoreGame *savefile ) {
|
||||
|
||||
savefile->ReadVec3 ( storedVelocity ); // cnicholson: Added unrestored var
|
||||
|
||||
physicsObj.SetSelf( this );
|
||||
|
||||
SetClipModel ( );
|
||||
|
||||
savefile->ReadStaticObject ( physicsObj );
|
||||
RestorePhysics( &physicsObj );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
rvVehicleRigid::SkipImpulse
|
||||
=====================
|
||||
*/
|
||||
bool rvVehicleRigid::SkipImpulse( idEntity* ent, int id ) {
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
//----------------------------------------------------------------
|
||||
// VehicleRigid.h
|
||||
//
|
||||
// Copyright 2002-2004 Raven Software
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#ifndef __GAME_VEHICLERIGID_H__
|
||||
#define __GAME_VEHICLERIGID_H__
|
||||
|
||||
#ifndef __GAME_VEHICLE_H__
|
||||
#include "Vehicle.h"
|
||||
#endif
|
||||
|
||||
class rvVehicleRigid : public rvVehicle
|
||||
{
|
||||
public:
|
||||
|
||||
CLASS_PROTOTYPE( rvVehicleRigid );
|
||||
|
||||
rvVehicleRigid ( void );
|
||||
~rvVehicleRigid ( void );
|
||||
|
||||
void Spawn ( void );
|
||||
void Save ( idSaveGame *savefile ) const;
|
||||
void Restore ( idRestoreGame *savefile );
|
||||
|
||||
void WriteToSnapshot ( idBitMsgDelta &msg ) const;
|
||||
void ReadFromSnapshot ( const idBitMsgDelta &msg );
|
||||
|
||||
bool SkipImpulse ( idEntity* ent, int id );
|
||||
|
||||
protected:
|
||||
|
||||
void SetClipModel ( void );
|
||||
|
||||
// twhitaker:
|
||||
virtual void RunPrePhysics ( void );
|
||||
virtual void RunPostPhysics ( void );
|
||||
idVec3 storedVelocity;
|
||||
// end twhitaker:
|
||||
|
||||
idPhysics_RigidBody physicsObj; // physics object
|
||||
};
|
||||
|
||||
#endif // __GAME_VEHICLERIGID_H__
|
||||
@@ -0,0 +1,123 @@
|
||||
//----------------------------------------------------------------
|
||||
// VehicleSplineCoupling.h
|
||||
//
|
||||
// Copyright 2002-2004 Raven Software
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#include "precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "../Game_local.h"
|
||||
#include "VehicleSpline.h"
|
||||
|
||||
CLASS_DECLARATION( rvVehicle, rvVehicleSpline )
|
||||
EVENT( EV_PostSpawn, rvVehicleSpline::Event_PostSpawn )
|
||||
EVENT( EV_SetSpline, rvVehicleSpline::Event_SetSpline )
|
||||
EVENT( EV_DoneMoving, rvVehicleSpline::Event_DoneMoving )
|
||||
END_CLASS
|
||||
|
||||
rvVehicleSpline::rvVehicleSpline ( void ) {
|
||||
}
|
||||
|
||||
rvVehicleSpline::~rvVehicleSpline ( void ) {
|
||||
SetPhysics( NULL );
|
||||
}
|
||||
|
||||
void rvVehicleSpline::Spawn ( void ) {
|
||||
|
||||
physicsObj.SetSelf( this );
|
||||
physicsObj.SetClipModel( new idClipModel(GetPhysics()->GetClipModel()), 1.0f );
|
||||
physicsObj.SetContents( CONTENTS_SOLID );
|
||||
physicsObj.SetClipMask( 0 );
|
||||
physicsObj.SetLinearVelocity( GetPhysics()->GetLinearVelocity() );
|
||||
physicsObj.SetLinearAcceleration( spawnArgs.GetFloat( "accel", "200" ) );
|
||||
physicsObj.SetLinearDeceleration( spawnArgs.GetFloat( "decel", "200" ) );
|
||||
|
||||
viewAxis = idAngles( 0, spawnArgs.GetFloat( "angle" ) , 0 ).ToMat3();
|
||||
|
||||
physicsObj.SetAxis( GetPhysics()->GetAxis() * viewAxis );
|
||||
physicsObj.SetOrigin( GetPhysics()->GetOrigin() );
|
||||
|
||||
SetPhysics( &physicsObj );
|
||||
|
||||
BecomeActive( TH_THINK );
|
||||
|
||||
accelWithStrafe = Sign( spawnArgs.GetFloat("accel_strafe") );
|
||||
|
||||
idealSpeed = spawnArgs.GetFloat( "speed", "200" );
|
||||
|
||||
PostEventMS( &EV_PostSpawn, 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleSpline::Save
|
||||
================
|
||||
*/
|
||||
void rvVehicleSpline::Save ( idSaveGame *savefile ) const {
|
||||
savefile->WriteStaticObject( physicsObj );
|
||||
savefile->WriteMat3( angleOffset );
|
||||
savefile->WriteFloat( idealSpeed );
|
||||
savefile->WriteFloat( accelWithStrafe );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleSpline::Restore
|
||||
================
|
||||
*/
|
||||
void rvVehicleSpline::Restore ( idRestoreGame *savefile ) {
|
||||
physicsObj.SetSelf( this );
|
||||
physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f );
|
||||
savefile->ReadStaticObject ( physicsObj );
|
||||
RestorePhysics ( &physicsObj );
|
||||
physicsObj.EnableClip();
|
||||
|
||||
savefile->ReadMat3( angleOffset );
|
||||
savefile->ReadFloat( idealSpeed );
|
||||
savefile->ReadFloat( accelWithStrafe );
|
||||
}
|
||||
|
||||
void rvVehicleSpline::Think( void ) {
|
||||
float moveAmount = 0.0f;
|
||||
|
||||
if ( positions[0].IsOccupied ( ) && !IsFrozen () && IsMovementEnabled ( ) ) {
|
||||
|
||||
if ( accelWithStrafe != 0.0f ) {
|
||||
moveAmount = positions[0].mInputCmd.rightmove * accelWithStrafe;
|
||||
} else {
|
||||
moveAmount = positions[0].mInputCmd.forwardmove;
|
||||
}
|
||||
|
||||
moveAmount = Sign( moveAmount );
|
||||
}
|
||||
|
||||
physicsObj.SetSpeed( idealSpeed * moveAmount );
|
||||
|
||||
rvVehicle::Think( );
|
||||
}
|
||||
|
||||
void rvVehicleSpline::Event_PostSpawn( void ) {
|
||||
idStr splinePath;
|
||||
|
||||
if ( spawnArgs.GetString( "spline_path", "", splinePath ) ) {
|
||||
Event_SetSpline( gameLocal.FindEntity( splinePath.c_str() ) );
|
||||
} else {
|
||||
gameLocal.Warning( "\"spline_path\" key not found on %s (rvVehicleSpline)", this->GetName() );
|
||||
}
|
||||
}
|
||||
|
||||
void rvVehicleSpline::Event_SetSpline ( idEntity * spline ) {
|
||||
if ( spline && spline->IsType( idSplinePath::GetClassType() ) ) {
|
||||
physicsObj.SetSplineEntity( static_cast< idSplinePath * >( spline ) );
|
||||
//HACK: force an intitial physics update so that the object orients itself with the spline
|
||||
//TEMP: this should be fixed after the build on friday (Jan 28, 2005)
|
||||
physicsObj.SetSpeed( 0.1f );
|
||||
RunPhysics();
|
||||
//END HACK
|
||||
}
|
||||
}
|
||||
|
||||
void rvVehicleSpline::Event_DoneMoving() {
|
||||
idThread::ReturnInt( true );
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
//----------------------------------------------------------------
|
||||
// VehicleSpline.h
|
||||
//
|
||||
// Copyright 2002-2004 Raven Software
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#ifndef __GAME_VEHICLESPLINECOUPLING_H__
|
||||
#define __GAME_VEHICLESPLINECOUPLING_H__
|
||||
|
||||
class rvVehicleSpline : public rvVehicle {
|
||||
public:
|
||||
CLASS_PROTOTYPE( rvVehicleSpline );
|
||||
|
||||
rvVehicleSpline ( void );
|
||||
~rvVehicleSpline ( void );
|
||||
|
||||
void Spawn ( void );
|
||||
void Save ( idSaveGame *savefile ) const;
|
||||
void Restore ( idRestoreGame *savefile );
|
||||
|
||||
void Think ( void );
|
||||
|
||||
void Event_PostSpawn ( void );
|
||||
void Event_SetSpline ( idEntity * spline );
|
||||
void Event_DoneMoving ( void );
|
||||
|
||||
protected:
|
||||
rvPhysics_Spline physicsObj;
|
||||
idMat3 angleOffset;
|
||||
float idealSpeed;
|
||||
float accelWithStrafe;
|
||||
};
|
||||
|
||||
#endif // __GAME_VEHICLESPLINECOUPLING_H__
|
||||
@@ -0,0 +1,118 @@
|
||||
//----------------------------------------------------------------
|
||||
// VehicleStatic.cpp
|
||||
//
|
||||
// Copyright 2002-2004 Raven Software
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#include "precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "../Game_local.h"
|
||||
#include "VehicleStatic.h"
|
||||
|
||||
CLASS_DECLARATION( rvVehicle, rvVehicleStatic )
|
||||
EVENT( AI_ScriptedAnim, rvVehicleStatic::Event_ScriptedAnim )
|
||||
EVENT( AI_ScriptedDone, rvVehicleStatic::Event_ScriptedDone )
|
||||
EVENT( AI_ScriptedStop, rvVehicleStatic::Event_ScriptedStop )
|
||||
END_CLASS
|
||||
|
||||
rvVehicleStatic::rvVehicleStatic ( void ) {
|
||||
}
|
||||
|
||||
rvVehicleStatic::~rvVehicleStatic ( void ) {
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleStatic::Spawn
|
||||
================
|
||||
*/
|
||||
void rvVehicleStatic::Spawn( void ) {
|
||||
BecomeActive( TH_THINK );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleStatic::AddDriver
|
||||
================
|
||||
*/
|
||||
int rvVehicleStatic::AddDriver ( int position, idActor* driver ) {
|
||||
int pos = rvVehicle::AddDriver( position, driver );
|
||||
|
||||
if( pos < 0 ) {
|
||||
return pos;
|
||||
}
|
||||
|
||||
if( GetHud() ) {
|
||||
GetHud()->HandleNamedEvent( "hideGunInfo" );
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleStatic::RemoveDriver
|
||||
================
|
||||
*/
|
||||
bool rvVehicleStatic::RemoveDriver ( int position, bool force ) {
|
||||
bool result = rvVehicle::RemoveDriver( position, force );
|
||||
|
||||
if( !result ) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if( GetHud() ) {
|
||||
GetHud()->HandleNamedEvent( "showGunInfo" );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleStatic::UpdateHUD
|
||||
================
|
||||
*/
|
||||
void rvVehicleStatic::UpdateHUD( idActor* driver, idUserInterface* gui ) {
|
||||
if( driver && driver->IsType( idPlayer::GetClassType() ) ) {
|
||||
static_cast<idPlayer*>(driver)->UpdateHudStats( gui );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleStatic::Event_ScriptedAnim
|
||||
================
|
||||
*/
|
||||
void rvVehicleStatic::Event_ScriptedAnim( const char* animname, int blendFrames, bool loop, bool endWithIdle ) {
|
||||
vfl.endWithIdle = endWithIdle;
|
||||
if ( loop ) {
|
||||
PlayCycle ( ANIMCHANNEL_TORSO, animname, blendFrames );
|
||||
} else {
|
||||
PlayAnim ( ANIMCHANNEL_TORSO, animname, blendFrames );
|
||||
}
|
||||
vfl.scripted = true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleStatic::Event_ScriptedDone
|
||||
================
|
||||
*/
|
||||
void rvVehicleStatic::Event_ScriptedDone( void ) {
|
||||
idThread::ReturnInt( !vfl.scripted );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleStatic::Event_ScriptedStop
|
||||
================
|
||||
*/
|
||||
void rvVehicleStatic::Event_ScriptedStop( void ) {
|
||||
vfl.scripted = false;
|
||||
|
||||
if ( vfl.endWithIdle ) {
|
||||
PlayCycle( ANIMCHANNEL_TORSO, spawnArgs.GetString( "idle" ), 2 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
//----------------------------------------------------------------
|
||||
// VehicleStatic.h
|
||||
//
|
||||
// Copyright 2002-2004 Raven Software
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#ifndef __GAME_VEHICLESTATIC_H__
|
||||
#define __GAME_VEHICLESTATIC_H__
|
||||
|
||||
#ifndef __GAME_VEHICLE_H__
|
||||
#include "Vehicle.h"
|
||||
#endif
|
||||
|
||||
class rvVehicleStatic : public rvVehicle
|
||||
{
|
||||
public:
|
||||
|
||||
CLASS_PROTOTYPE( rvVehicleStatic );
|
||||
|
||||
rvVehicleStatic ( void );
|
||||
~rvVehicleStatic ( void );
|
||||
|
||||
void Spawn ( void );
|
||||
|
||||
virtual int AddDriver ( int position, idActor* driver );
|
||||
virtual bool RemoveDriver ( int position, bool force = false );
|
||||
|
||||
virtual void UpdateHUD ( idActor* driver, idUserInterface* gui );
|
||||
|
||||
void Event_ScriptedAnim ( const char* animname, int blendFrames, bool loop, bool endWithIdle );
|
||||
void Event_ScriptedDone ( void );
|
||||
void Event_ScriptedStop ( void );
|
||||
};
|
||||
|
||||
#endif // __GAME_VEHICLESTATIC_H__
|
||||
@@ -0,0 +1,177 @@
|
||||
#include "precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "../Game_local.h"
|
||||
#include "VehicleStatic.h"
|
||||
|
||||
class rvVehicleDropPod : public rvVehicleStatic {
|
||||
public:
|
||||
|
||||
CLASS_PROTOTYPE( rvVehicleDropPod );
|
||||
|
||||
rvVehicleDropPod ( void );
|
||||
|
||||
void Spawn ( void );
|
||||
|
||||
virtual bool GetPhysicsToVisualTransform ( idVec3 &origin, idMat3 &axis );
|
||||
|
||||
private:
|
||||
|
||||
stateResult_t State_Idle ( const stateParms_t& parms );
|
||||
stateResult_t State_IdleThink ( const stateParms_t& parms );
|
||||
stateResult_t State_IdleOffline ( const stateParms_t& parms );
|
||||
stateResult_t State_ScriptedAnim ( const stateParms_t& parms );
|
||||
|
||||
void Event_ScriptedAnim ( const char* animname, int blendFrames, bool loop, bool endWithIdle );
|
||||
void Event_ScriptedDone ( void );
|
||||
void Event_ScriptedStop ( void );
|
||||
|
||||
CLASS_STATES_PROTOTYPE ( rvVehicleDropPod );
|
||||
};
|
||||
|
||||
CLASS_DECLARATION( rvVehicleStatic, rvVehicleDropPod )
|
||||
EVENT( AI_ScriptedAnim, rvVehicleDropPod::Event_ScriptedAnim )
|
||||
EVENT( AI_ScriptedDone, rvVehicleDropPod::Event_ScriptedDone )
|
||||
EVENT( AI_ScriptedStop, rvVehicleDropPod::Event_ScriptedStop )
|
||||
END_CLASS
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDropPod::rvVehicleDropPod
|
||||
================
|
||||
*/
|
||||
rvVehicleDropPod::rvVehicleDropPod ( void ) {
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDropPod::Spawn
|
||||
================
|
||||
*/
|
||||
void rvVehicleDropPod::Spawn ( void ) {
|
||||
SetAnimState ( ANIMCHANNEL_LEGS, "State_IdleOffline", 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
States
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
CLASS_STATES_DECLARATION ( rvVehicleDropPod )
|
||||
STATE ( "State_Idle", rvVehicleDropPod::State_Idle )
|
||||
STATE ( "State_IdleThink", rvVehicleDropPod::State_IdleThink )
|
||||
STATE ( "State_IdleOffline", rvVehicleDropPod::State_IdleOffline )
|
||||
|
||||
STATE ( "State_ScriptedAnim", rvVehicleDropPod::State_ScriptedAnim )
|
||||
END_CLASS_STATES
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDropPod::State_IdleOffline
|
||||
================
|
||||
*/
|
||||
stateResult_t rvVehicleDropPod::State_IdleOffline ( const stateParms_t& parms ) {
|
||||
vfl.frozen = true;
|
||||
|
||||
PlayCycle ( ANIMCHANNEL_LEGS, "idle", parms.blendFrames );
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "Wait_Driver", 0 );
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "State_Idle", 0 );
|
||||
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDropPod::State_Idle
|
||||
================
|
||||
*/
|
||||
stateResult_t rvVehicleDropPod::State_Idle ( const stateParms_t& parms ) {
|
||||
if ( SRESULT_WAIT != State_IdleThink ( parms ) ) {
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDropPod::State_IdleThink
|
||||
================
|
||||
*/
|
||||
stateResult_t rvVehicleDropPod::State_IdleThink ( const stateParms_t& parms ) {
|
||||
if ( !vfl.driver ) {
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "State_IdleOffline", parms.blendFrames );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
return SRESULT_WAIT;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDropPod::State_ScriptedAnim
|
||||
================
|
||||
*/
|
||||
stateResult_t rvVehicleDropPod::State_ScriptedAnim ( const stateParms_t& parms ) {
|
||||
if ( !AnimDone ( ANIMCHANNEL_LEGS, parms.blendFrames ) ) {
|
||||
return SRESULT_WAIT;
|
||||
}
|
||||
Event_ScriptedStop();
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDropPod::Event_ScriptedAnim
|
||||
================
|
||||
*/
|
||||
void rvVehicleDropPod::Event_ScriptedAnim( const char* animname, int blendFrames, bool loop, bool endWithIdle ) {
|
||||
vfl.endWithIdle = endWithIdle;
|
||||
if ( loop ) {
|
||||
PlayCycle ( ANIMCHANNEL_LEGS, animname, blendFrames );
|
||||
} else {
|
||||
PlayAnim ( ANIMCHANNEL_LEGS, animname, blendFrames );
|
||||
}
|
||||
SetAnimState ( ANIMCHANNEL_LEGS, "State_ScriptedAnim", blendFrames );
|
||||
vfl.scripted = true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDropPod::Event_ScriptedDone
|
||||
================
|
||||
*/
|
||||
void rvVehicleDropPod::Event_ScriptedDone( void ) {
|
||||
idThread::ReturnInt( !vfl.scripted );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDropPod::Event_ScriptedStop
|
||||
================
|
||||
*/
|
||||
void rvVehicleDropPod::Event_ScriptedStop( void ) {
|
||||
vfl.scripted = false;
|
||||
|
||||
if ( vfl.endWithIdle ) {
|
||||
SetAnimState ( ANIMCHANNEL_LEGS, "State_Idle", 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleDropPod::GetPhysicsToVisualTransform
|
||||
================
|
||||
*/
|
||||
bool rvVehicleDropPod::GetPhysicsToVisualTransform ( idVec3 &origin, idMat3 &axis ) {
|
||||
// if ( GetBindMaster() ) {
|
||||
// axis = viewAxis;
|
||||
// origin.Zero();
|
||||
// return true;
|
||||
// }
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,593 @@
|
||||
#include "precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "../Game_local.h"
|
||||
#include "VehicleAnimated.h"
|
||||
|
||||
class rvVehicleWalker : public rvVehicleAnimated {
|
||||
public:
|
||||
|
||||
CLASS_PROTOTYPE( rvVehicleWalker );
|
||||
|
||||
rvVehicleWalker ( void );
|
||||
|
||||
void Think ( void );
|
||||
void Spawn ( void );
|
||||
void Save ( idSaveGame *savefile ) const;
|
||||
void Restore ( idRestoreGame *savefile );
|
||||
|
||||
virtual void UpdateState ( void );
|
||||
virtual void SetInput ( int position, const usercmd_t& cmd, const idAngles& newAngles );
|
||||
|
||||
const char* stopAnimName;
|
||||
|
||||
virtual bool FindClearExitPoint ( int pos, idVec3& origin, idMat3& axis ) const;
|
||||
|
||||
private:
|
||||
void HandleStrafing ( void );
|
||||
|
||||
|
||||
stateResult_t Frame_ForwardRight ( int );
|
||||
stateResult_t Frame_ForwardLeft ( int );
|
||||
stateResult_t Frame_BackwardRight ( int );
|
||||
stateResult_t Frame_BackwardLeft ( int );
|
||||
|
||||
stateResult_t State_Wait_OnlineAnim ( const stateParms_t& parms );
|
||||
|
||||
stateResult_t State_Idle ( const stateParms_t& parms );
|
||||
stateResult_t State_IdleThink ( const stateParms_t& parms );
|
||||
stateResult_t State_IdleOffline ( const stateParms_t& parms );
|
||||
stateResult_t State_Offline ( const stateParms_t& parms );
|
||||
stateResult_t State_Online ( const stateParms_t& parms );
|
||||
|
||||
stateResult_t State_ForwardStart ( const stateParms_t& parms );
|
||||
stateResult_t State_Forward ( const stateParms_t& parms );
|
||||
stateResult_t State_BackwardStart ( const stateParms_t& parms );
|
||||
stateResult_t State_Backward ( const stateParms_t& parms );
|
||||
stateResult_t State_Stop ( const stateParms_t& parms );
|
||||
stateResult_t State_Turn ( const stateParms_t& parms );
|
||||
stateResult_t State_TurnThink ( const stateParms_t& parms );
|
||||
stateResult_t State_ScriptedAnim ( const stateParms_t& parms );
|
||||
|
||||
void Event_ScriptedAnim ( const char* animname, int blendFrames, bool loop, bool endWithIdle );
|
||||
void Event_ScriptedDone ( void );
|
||||
void Event_ScriptedStop ( void );
|
||||
|
||||
CLASS_STATES_PROTOTYPE ( rvVehicleWalker );
|
||||
};
|
||||
|
||||
CLASS_DECLARATION( rvVehicleAnimated, rvVehicleWalker )
|
||||
EVENT( AI_ScriptedAnim, rvVehicleWalker::Event_ScriptedAnim )
|
||||
EVENT( AI_ScriptedDone, rvVehicleWalker::Event_ScriptedDone )
|
||||
EVENT( AI_ScriptedStop, rvVehicleWalker::Event_ScriptedStop )
|
||||
END_CLASS
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::rvVehicleWalker
|
||||
================
|
||||
*/
|
||||
rvVehicleWalker::rvVehicleWalker ( void ) {
|
||||
stopAnimName = "";
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::Think
|
||||
================
|
||||
*/
|
||||
void rvVehicleWalker::Think ( void ) {
|
||||
rvVehicleAnimated::Think();
|
||||
|
||||
if ( !HasDrivers() || IsStalled() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
idVec3 delta;
|
||||
animator.GetDelta( gameLocal.time - gameLocal.GetMSec(), gameLocal.time, delta );
|
||||
|
||||
if ( delta.LengthSqr() > 0.1f ) {
|
||||
gameLocal.RadiusDamage( GetOrigin(), this, this, this, this, spawnArgs.GetString( "def_stompDamage", "damage_Smallexplosion" ) );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::Spawn
|
||||
================
|
||||
*/
|
||||
void rvVehicleWalker::Spawn ( void ) {
|
||||
SetAnimState ( ANIMCHANNEL_LEGS, "State_IdleOffline", 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::Save
|
||||
================
|
||||
*/
|
||||
void rvVehicleWalker::Save ( idSaveGame *savefile ) const {
|
||||
savefile->WriteString( stopAnimName );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::Restore
|
||||
================
|
||||
*/
|
||||
void rvVehicleWalker::Restore ( idRestoreGame *savefile ) {
|
||||
//twhitaker: I just happened to see this, while going through this code which I originally wrote (at 3am or so).
|
||||
//TODO: fix this. Make stopAnimName an idStr?
|
||||
idStr str;
|
||||
savefile->ReadString( str );
|
||||
stopAnimName = str;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::UpdateState
|
||||
================
|
||||
*/
|
||||
void rvVehicleWalker::UpdateState ( void ) {
|
||||
rvVehiclePosition& pos = positions[0];
|
||||
usercmd_t& cmd = pos.mInputCmd;
|
||||
|
||||
vfl.driver = pos.IsOccupied();
|
||||
vfl.forward = (vfl.driver && cmd.forwardmove > 0);
|
||||
vfl.backward = (vfl.driver && cmd.forwardmove < 0);
|
||||
vfl.right = (vfl.driver && cmd.rightmove < 0);
|
||||
vfl.left = (vfl.driver && cmd.rightmove > 0);
|
||||
vfl.strafe = (vfl.driver && cmd.buttons & BUTTON_STRAFE );
|
||||
|
||||
if ( g_vehicleMode.GetInteger() != 0 ) {
|
||||
vfl.strafe = !vfl.strafe;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::SetInput
|
||||
================
|
||||
*/
|
||||
void rvVehicleWalker::SetInput ( int position, const usercmd_t& cmd, const idAngles& newAngles ) {
|
||||
usercmd_t* pcmd = const_cast<usercmd_t*>( &cmd );
|
||||
pcmd->rightmove *= -1;
|
||||
GetPosition(position)->SetInput ( cmd, newAngles );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::HandleStrafing
|
||||
================
|
||||
*/
|
||||
void rvVehicleWalker::HandleStrafing ( void ) {
|
||||
if ( vfl.right ) {
|
||||
additionalDelta -= spawnArgs.GetVector( "strafe_delta", "0 0 1.2" );
|
||||
}
|
||||
if ( vfl.left ) {
|
||||
additionalDelta += spawnArgs.GetVector( "strafe_delta", "0 0 1.2" );
|
||||
}
|
||||
}
|
||||
|
||||
// mekberg: overloaded this because physics bounds code is significantly different
|
||||
/*
|
||||
=====================
|
||||
rvVehicleWalker::FindClearExitPoint
|
||||
=====================
|
||||
*/
|
||||
// FIXME: this whole function could be cleaned up
|
||||
bool rvVehicleWalker::FindClearExitPoint( int pos, idVec3& origin, idMat3& axis ) const {
|
||||
trace_t trace;
|
||||
const rvVehiclePosition* position = GetPosition( pos );
|
||||
idActor* driver = position->GetDriver();
|
||||
idVec3 end;
|
||||
idVec3 traceOffsetPoints[4];
|
||||
const float error = 1.1f;
|
||||
|
||||
origin.Zero();
|
||||
axis.Identity();
|
||||
|
||||
idMat3 driverAxis = driver->viewAxis;
|
||||
idVec3 driverOrigin = driver->GetPhysics()->GetOrigin();
|
||||
|
||||
idMat3 vehicleAxis = position->GetEyeAxis();
|
||||
idVec3 vehicleOrigin = GetPhysics()->GetOrigin();
|
||||
|
||||
idBounds driverBounds( driver->GetPhysics()->GetBounds() );
|
||||
idBounds vehicleBounds( GetPhysics()->GetBounds() );
|
||||
idBounds driverAbsBounds;
|
||||
idBounds vehicleAbsBounds;
|
||||
|
||||
vehicleAbsBounds.FromTransformedBounds( vehicleBounds, vehicleOrigin, GetPhysics()->GetAxis() );
|
||||
if( position->fl.driverVisible ) {
|
||||
// May want to do this even if the driver isn't visible
|
||||
if( position->mExitPosOffset.LengthSqr() > VECTOR_EPSILON ) {
|
||||
axis = GetPhysics()->GetAxis() * position->mExitAxisOffset;
|
||||
origin = vehicleOrigin + position->mExitPosOffset * axis;
|
||||
} else {
|
||||
origin = driverOrigin;
|
||||
axis = (driver->IsBoundTo(this)) ? vehicleAxis : driverAxis;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Build list
|
||||
// FIXME: try and find a cleaner way to do this
|
||||
traceOffsetPoints[ 0 ] = vehicleBounds.FindVectorToEdge( vehicleAxis[ 1 ] ) - driverBounds.FindVectorToEdge( -vehicleAxis[ 1 ] );
|
||||
traceOffsetPoints[ 1 ] = vehicleBounds.FindVectorToEdge( -vehicleAxis[ 1 ] ) - driverBounds.FindVectorToEdge( vehicleAxis[ 1 ] );
|
||||
traceOffsetPoints[ 2 ] = vehicleBounds.FindVectorToEdge( vehicleAxis[ 0 ] ) - driverBounds.FindVectorToEdge( -vehicleAxis[ 0 ] );
|
||||
traceOffsetPoints[ 3 ] = vehicleBounds.FindVectorToEdge( -vehicleAxis[ 0 ] ) - driverBounds.FindVectorToEdge( vehicleAxis[ 0 ] );
|
||||
|
||||
for( int ix = 0; ix < 4; ++ix ) {
|
||||
//Try all four sides and on top if need be
|
||||
end = vehicleOrigin + traceOffsetPoints[ ix ] * error;
|
||||
// RAVEN BEGIN
|
||||
// ddynerman: multiple clip worlds
|
||||
gameLocal.Translation( this, trace, vehicleOrigin, end, driver->GetPhysics()->GetClipModel(), driverAxis, driver->GetPhysics()->GetClipMask(), this, driver );
|
||||
// RAVEN END
|
||||
driverAbsBounds.FromTransformedBounds( driverBounds, trace.endpos, driverAxis );
|
||||
if( trace.fraction > 0.0f && !driverAbsBounds.IntersectsBounds(vehicleAbsBounds) ) {
|
||||
origin = trace.endpos;
|
||||
axis = vehicleAxis;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
States
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
CLASS_STATES_DECLARATION ( rvVehicleWalker )
|
||||
STATE ( "ForwardLeft", rvVehicleWalker::Frame_ForwardLeft )
|
||||
STATE ( "ForwardRight", rvVehicleWalker::Frame_ForwardRight )
|
||||
STATE ( "BackwardLeft", rvVehicleWalker::Frame_BackwardLeft )
|
||||
STATE ( "BackwardRight", rvVehicleWalker::Frame_BackwardRight )
|
||||
|
||||
STATE ( "Wait_OnlineAnim", rvVehicleWalker::State_Wait_OnlineAnim )
|
||||
|
||||
STATE ( "State_Idle", rvVehicleWalker::State_Idle )
|
||||
STATE ( "State_IdleThink", rvVehicleWalker::State_IdleThink )
|
||||
STATE ( "State_IdleOffline", rvVehicleWalker::State_IdleOffline )
|
||||
STATE ( "State_Offline", rvVehicleWalker::State_Offline )
|
||||
STATE ( "State_Online", rvVehicleWalker::State_Online )
|
||||
|
||||
STATE ( "State_ForwardStart", rvVehicleWalker::State_ForwardStart )
|
||||
STATE ( "State_Forward", rvVehicleWalker::State_Forward )
|
||||
STATE ( "State_BackwardStart", rvVehicleWalker::State_BackwardStart )
|
||||
STATE ( "State_Backward", rvVehicleWalker::State_Backward )
|
||||
STATE ( "State_Stop", rvVehicleWalker::State_Stop )
|
||||
STATE ( "State_Turn", rvVehicleWalker::State_Turn )
|
||||
STATE ( "State_TurnThink", rvVehicleWalker::State_TurnThink )
|
||||
STATE ( "State_ScriptedAnim", rvVehicleWalker::State_ScriptedAnim )
|
||||
END_CLASS_STATES
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::State_IdleOffline
|
||||
================
|
||||
*/
|
||||
stateResult_t rvVehicleWalker::State_IdleOffline ( const stateParms_t& parms ) {
|
||||
vfl.frozen = true;
|
||||
|
||||
PlayCycle ( ANIMCHANNEL_LEGS, "idle_offline", parms.blendFrames );
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "Wait_Driver", 2 );
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "State_Online", 2 );
|
||||
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::State_Online
|
||||
================
|
||||
*/
|
||||
stateResult_t rvVehicleWalker::State_Online ( const stateParms_t& parms ) {
|
||||
vfl.frozen = false;
|
||||
|
||||
PlayAnim ( ANIMCHANNEL_LEGS, "start", parms.blendFrames );
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "Wait_OnlineAnim", 4 );
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "State_Idle", 4 );
|
||||
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::State_Offline
|
||||
================
|
||||
*/
|
||||
stateResult_t rvVehicleWalker::State_Offline ( const stateParms_t& parms ) {
|
||||
PlayAnim ( ANIMCHANNEL_LEGS, "stop", parms.blendFrames );
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "Wait_TorsoAnim", 4 );
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "State_IdleOffline", 4 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::State_Idle
|
||||
================
|
||||
*/
|
||||
stateResult_t rvVehicleWalker::State_Idle ( const stateParms_t& parms ) {
|
||||
if ( SRESULT_WAIT != State_IdleThink ( parms ) ) {
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
PlayCycle( ANIMCHANNEL_LEGS, "idle", parms.blendFrames );
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "State_IdleThink", 2 );
|
||||
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::State_Idle
|
||||
================
|
||||
*/
|
||||
stateResult_t rvVehicleWalker::State_IdleThink ( const stateParms_t& parms ) {
|
||||
if ( !vfl.driver || vfl.stalled ) {
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "State_Offline", parms.blendFrames );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
if ( IsMovementEnabled ( ) ) {
|
||||
if ( vfl.forward ) {
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "State_ForwardStart", 2 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
if ( vfl.backward ) {
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "State_BackwardStart", 2 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
if ( vfl.right || vfl.left ) {
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "State_Turn", 2 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
return SRESULT_WAIT;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::State_ForwardStart
|
||||
================
|
||||
*/
|
||||
stateResult_t rvVehicleWalker::State_ForwardStart ( const stateParms_t& parms ) {
|
||||
PlayAnim ( ANIMCHANNEL_LEGS, "forward_start", 2 );
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "Wait_TorsoAnim", 2 );
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "State_Forward", 2 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
stateResult_t rvVehicleWalker::State_Forward ( const stateParms_t& parms ) {
|
||||
// If not moving anymore by the time we get here just play the stop anim
|
||||
if ( !vfl.forward ) {
|
||||
stopAnimName = "forward_stop_leftmid";
|
||||
SetAnimState ( ANIMCHANNEL_LEGS, "State_Stop", 4 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
if ( !parms.stage ) {
|
||||
PlayCycle( ANIMCHANNEL_LEGS, "forward", 2 );
|
||||
return SRESULT_STAGE(parms.stage + 1);
|
||||
}
|
||||
|
||||
if ( AnimDone( ANIMCHANNEL_LEGS, 2 ) ) {
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
HandleStrafing();
|
||||
return SRESULT_WAIT;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::State_BackwardStart
|
||||
================
|
||||
*/
|
||||
stateResult_t rvVehicleWalker::State_BackwardStart ( const stateParms_t& parms ) {
|
||||
PlayAnim ( ANIMCHANNEL_LEGS, "backward_start", parms.blendFrames );
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "Wait_TorsoAnim", 2 );
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "State_Backward", 2 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
stateResult_t rvVehicleWalker::State_Backward ( const stateParms_t& parms ) {
|
||||
// If not moving anymore by the time we get here just play the stop anim
|
||||
if ( !vfl.backward ) {
|
||||
stopAnimName = "backward_stop_leftmid";
|
||||
SetAnimState ( ANIMCHANNEL_LEGS, "State_Stop", 2 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
if ( !parms.stage ) {
|
||||
PlayCycle( ANIMCHANNEL_LEGS, "backward", 2 );
|
||||
return SRESULT_STAGE(parms.stage + 1);
|
||||
}
|
||||
|
||||
if ( AnimDone( ANIMCHANNEL_LEGS, 2 ) ) {
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
HandleStrafing();
|
||||
return SRESULT_WAIT;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::State_Stop
|
||||
================
|
||||
*/
|
||||
stateResult_t rvVehicleWalker::State_Stop ( const stateParms_t& parms ) {
|
||||
PlayAnim ( ANIMCHANNEL_LEGS, stopAnimName, parms.blendFrames );
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "Wait_TorsoAnim", 2 );
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "State_Idle", 2 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::State_Turn
|
||||
================
|
||||
*/
|
||||
stateResult_t rvVehicleWalker::State_Turn ( const stateParms_t& parms ) {
|
||||
if ( vfl.left ) {
|
||||
PlayAnim ( ANIMCHANNEL_LEGS, "turn_left", parms.blendFrames );
|
||||
} else if ( vfl.right ) {
|
||||
PlayAnim ( ANIMCHANNEL_LEGS, "turn_right", parms.blendFrames );
|
||||
} else {
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "State_Idle", parms.blendFrames );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "State_TurnThink", 16 );
|
||||
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::State_TurnThink
|
||||
================
|
||||
*/
|
||||
stateResult_t rvVehicleWalker::State_TurnThink ( const stateParms_t& parms ) {
|
||||
// If moving again bail on the turn, reguardless of whether its in mid animation
|
||||
if ( vfl.forward || vfl.backward ) {
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "State_Idle", parms.blendFrames );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
// If the animation is done then repeat
|
||||
if ( AnimDone ( ANIMCHANNEL_LEGS, 8 ) ){
|
||||
PostAnimState ( ANIMCHANNEL_LEGS, "State_Turn", 8 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
HandleStrafing();
|
||||
|
||||
return SRESULT_WAIT;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::Frame_ForwardLeft
|
||||
================
|
||||
*/
|
||||
stateResult_t rvVehicleWalker::Frame_ForwardLeft ( int ) {
|
||||
if ( !vfl.forward ) {
|
||||
stopAnimName = "forward_stop_left";
|
||||
SetAnimState ( ANIMCHANNEL_LEGS, "State_Stop", 2 );
|
||||
}
|
||||
return SRESULT_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::Frame_ForwardRight
|
||||
================
|
||||
*/
|
||||
stateResult_t rvVehicleWalker::Frame_ForwardRight ( int ) {
|
||||
if ( !vfl.forward ) {
|
||||
stopAnimName = "forward_stop_right";
|
||||
SetAnimState ( ANIMCHANNEL_LEGS, "State_Stop", 2 );
|
||||
}
|
||||
return SRESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::Frame_BackwardLeft
|
||||
================
|
||||
*/
|
||||
stateResult_t rvVehicleWalker::Frame_BackwardLeft ( int ) {
|
||||
if ( !vfl.backward ) {
|
||||
stopAnimName = "backward_stop_left";
|
||||
SetAnimState ( ANIMCHANNEL_LEGS, "State_Stop", 2 );
|
||||
}
|
||||
return SRESULT_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::Frame_BackwardRight
|
||||
================
|
||||
*/
|
||||
stateResult_t rvVehicleWalker::Frame_BackwardRight ( int ) {
|
||||
if ( !vfl.backward ) {
|
||||
stopAnimName = "backward_stop_right";
|
||||
SetAnimState ( ANIMCHANNEL_LEGS, "State_Stop", 2 );
|
||||
}
|
||||
return SRESULT_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::State_Wait_OnlineAnim
|
||||
================
|
||||
*/
|
||||
stateResult_t rvVehicleWalker::State_Wait_OnlineAnim ( const stateParms_t& parms ) {
|
||||
if ( !AnimDone ( ANIMCHANNEL_LEGS, parms.blendFrames ) && vfl.driver ) {
|
||||
return SRESULT_WAIT;
|
||||
}
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::State_ScriptedAnim
|
||||
================
|
||||
*/
|
||||
stateResult_t rvVehicleWalker::State_ScriptedAnim ( const stateParms_t& parms ) {
|
||||
if ( !AnimDone ( ANIMCHANNEL_LEGS, parms.blendFrames ) ) {
|
||||
return SRESULT_WAIT;
|
||||
}
|
||||
Event_ScriptedStop();
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::Event_ScriptedAnim
|
||||
================
|
||||
*/
|
||||
void rvVehicleWalker::Event_ScriptedAnim( const char* animname, int blendFrames, bool loop, bool endWithIdle ) {
|
||||
vfl.endWithIdle = endWithIdle;
|
||||
if ( loop ) {
|
||||
PlayCycle ( ANIMCHANNEL_LEGS, animname, blendFrames );
|
||||
} else {
|
||||
PlayAnim ( ANIMCHANNEL_LEGS, animname, blendFrames );
|
||||
}
|
||||
SetAnimState ( ANIMCHANNEL_LEGS, "State_ScriptedAnim", blendFrames );
|
||||
vfl.scripted = true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::Event_ScriptedDone
|
||||
================
|
||||
*/
|
||||
void rvVehicleWalker::Event_ScriptedDone( void ) {
|
||||
idThread::ReturnInt( !vfl.scripted );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvVehicleWalker::Event_ScriptedStop
|
||||
================
|
||||
*/
|
||||
void rvVehicleWalker::Event_ScriptedStop( void ) {
|
||||
vfl.scripted = false;
|
||||
|
||||
if ( vfl.endWithIdle ) {
|
||||
SetAnimState ( ANIMCHANNEL_LEGS, "State_Idle", 2 );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user