mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2026-03-24 02:48:08 +01:00
Initial commit
This commit is contained in:
1272
neo/d3xp/AF.cpp
Normal file
1272
neo/d3xp/AF.cpp
Normal file
File diff suppressed because it is too large
Load Diff
120
neo/d3xp/AF.h
Normal file
120
neo/d3xp/AF.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_AF_H__
|
||||
#define __GAME_AF_H__
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Articulated figure controller.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
typedef struct jointConversion_s {
|
||||
int bodyId; // id of the body
|
||||
jointHandle_t jointHandle; // handle of joint this body modifies
|
||||
AFJointModType_t jointMod; // modify joint axis, origin or both
|
||||
idVec3 jointBodyOrigin; // origin of body relative to joint
|
||||
idMat3 jointBodyAxis; // axis of body relative to joint
|
||||
} jointConversion_t;
|
||||
|
||||
typedef struct afTouch_s {
|
||||
idEntity * touchedEnt;
|
||||
idClipModel * touchedClipModel;
|
||||
idAFBody * touchedByBody;
|
||||
} afTouch_t;
|
||||
|
||||
class idAF {
|
||||
public:
|
||||
idAF();
|
||||
~idAF();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void SetAnimator( idAnimator *a ) { animator = a; }
|
||||
bool Load( idEntity *ent, const char *fileName );
|
||||
bool IsLoaded() const { return isLoaded && self != NULL; }
|
||||
const char * GetName() const { return name.c_str(); }
|
||||
void SetupPose( idEntity *ent, int time );
|
||||
void ChangePose( idEntity *ent, int time );
|
||||
int EntitiesTouchingAF( afTouch_t touchList[ MAX_GENTITIES ] ) const;
|
||||
void Start();
|
||||
void StartFromCurrentPose( int inheritVelocityTime );
|
||||
void Stop();
|
||||
void Rest();
|
||||
bool IsActive() const { return isActive; }
|
||||
void SetConstraintPosition( const char *name, const idVec3 &pos );
|
||||
|
||||
idPhysics_AF * GetPhysics() { return &physicsObj; }
|
||||
const idPhysics_AF * GetPhysics() const { return &physicsObj; }
|
||||
idBounds GetBounds() const;
|
||||
bool UpdateAnimation();
|
||||
|
||||
void GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ) const;
|
||||
void GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info );
|
||||
void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse );
|
||||
void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force );
|
||||
int BodyForClipModelId( int id ) const;
|
||||
|
||||
void SaveState( idDict &args ) const;
|
||||
void LoadState( const idDict &args );
|
||||
|
||||
void AddBindConstraints();
|
||||
void RemoveBindConstraints();
|
||||
|
||||
protected:
|
||||
idStr name; // name of the loaded .af file
|
||||
idPhysics_AF physicsObj; // articulated figure physics
|
||||
idEntity * self; // entity using the animated model
|
||||
idAnimator * animator; // animator on entity
|
||||
int modifiedAnim; // anim to modify
|
||||
idVec3 baseOrigin; // offset of base body relative to skeletal model origin
|
||||
idMat3 baseAxis; // axis of base body relative to skeletal model origin
|
||||
idList<jointConversion_t, TAG_AF> jointMods; // list with transforms from skeletal model joints to articulated figure bodies
|
||||
idList<int, TAG_AF> jointBody; // table to find the nearest articulated figure body for a joint of the skeletal model
|
||||
int poseTime; // last time the articulated figure was transformed to reflect the current animation pose
|
||||
int restStartTime; // time the articulated figure came to rest
|
||||
bool isLoaded; // true when the articulated figure is properly loaded
|
||||
bool isActive; // true if the articulated figure physics is active
|
||||
bool hasBindConstraints; // true if the bind constraints have been added
|
||||
|
||||
protected:
|
||||
void SetBase( idAFBody *body, const idJointMat *joints );
|
||||
void AddBody( idAFBody *body, const idJointMat *joints, const char *jointName, const AFJointModType_t mod );
|
||||
|
||||
bool LoadBody( const idDeclAF_Body *fb, const idJointMat *joints );
|
||||
bool LoadConstraint( const idDeclAF_Constraint *fc );
|
||||
|
||||
bool TestSolid() const;
|
||||
};
|
||||
|
||||
#endif /* !__GAME_AF_H__ */
|
||||
3676
neo/d3xp/AFEntity.cpp
Normal file
3676
neo/d3xp/AFEntity.cpp
Normal file
File diff suppressed because it is too large
Load Diff
597
neo/d3xp/AFEntity.h
Normal file
597
neo/d3xp/AFEntity.h
Normal file
@@ -0,0 +1,597 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_AFENTITY_H__
|
||||
#define __GAME_AFENTITY_H__
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idMultiModelAF
|
||||
|
||||
Entity using multiple separate visual models animated with a single
|
||||
articulated figure. Only used for debugging!
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
const int GIB_DELAY = 200; // only gib this often to keep performace hits when blowing up several mobs
|
||||
|
||||
class idMultiModelAF : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idMultiModelAF );
|
||||
|
||||
void Spawn();
|
||||
~idMultiModelAF();
|
||||
|
||||
virtual void Think();
|
||||
virtual void Present();
|
||||
|
||||
protected:
|
||||
idPhysics_AF physicsObj;
|
||||
|
||||
void SetModelForId( int id, const idStr &modelName );
|
||||
|
||||
private:
|
||||
idList<idRenderModel *, TAG_AF> modelHandles;
|
||||
idList<int, TAG_AF> modelDefHandles;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idChain
|
||||
|
||||
Chain hanging down from the ceiling. Only used for debugging!
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idChain : public idMultiModelAF {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idChain );
|
||||
|
||||
void Spawn();
|
||||
|
||||
protected:
|
||||
void BuildChain( const idStr &name, const idVec3 &origin, float linkLength, float linkWidth, float density, int numLinks, bool bindToWorld = true );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idAFAttachment
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idAFAttachment : public idAnimatedEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idAFAttachment );
|
||||
|
||||
idAFAttachment();
|
||||
virtual ~idAFAttachment();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void SetBody( idEntity *bodyEnt, const char *headModel, jointHandle_t attachJoint );
|
||||
void ClearBody();
|
||||
idEntity * GetBody() const;
|
||||
|
||||
virtual void Think();
|
||||
|
||||
virtual void Hide();
|
||||
virtual void Show();
|
||||
|
||||
void PlayIdleAnim( int blendTime );
|
||||
|
||||
virtual void GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info );
|
||||
virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse );
|
||||
virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force );
|
||||
|
||||
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
|
||||
virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName );
|
||||
|
||||
void SetCombatModel();
|
||||
idClipModel * GetCombatModel() const;
|
||||
virtual void LinkCombat();
|
||||
virtual void UnlinkCombat();
|
||||
|
||||
protected:
|
||||
idEntity * body;
|
||||
idClipModel * combatModel; // render model for hit detection of head
|
||||
int idleAnim;
|
||||
jointHandle_t attachJoint;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idAFEntity_Base
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idAFEntity_Base : public idAnimatedEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idAFEntity_Base );
|
||||
|
||||
idAFEntity_Base();
|
||||
virtual ~idAFEntity_Base();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void Think();
|
||||
virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName );
|
||||
virtual void GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info );
|
||||
virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse );
|
||||
virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force );
|
||||
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
|
||||
virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis );
|
||||
virtual bool UpdateAnimationControllers();
|
||||
virtual void FreeModelDef();
|
||||
|
||||
virtual bool LoadAF();
|
||||
bool IsActiveAF() const { return af.IsActive(); }
|
||||
const char * GetAFName() const { return af.GetName(); }
|
||||
idPhysics_AF * GetAFPhysics() { return af.GetPhysics(); }
|
||||
|
||||
void SetCombatModel();
|
||||
idClipModel * GetCombatModel() const;
|
||||
// contents of combatModel can be set to 0 or re-enabled (mp)
|
||||
void SetCombatContents( bool enable );
|
||||
virtual void LinkCombat();
|
||||
virtual void UnlinkCombat();
|
||||
|
||||
int BodyForClipModelId( int id ) const;
|
||||
|
||||
void SaveState( idDict &args ) const;
|
||||
void LoadState( const idDict &args );
|
||||
|
||||
void AddBindConstraints();
|
||||
void RemoveBindConstraints();
|
||||
|
||||
virtual void ShowEditingDialog();
|
||||
|
||||
static void DropAFs( idEntity *ent, const char *type, idList<idEntity *> *list );
|
||||
|
||||
protected:
|
||||
idAF af; // articulated figure
|
||||
idClipModel * combatModel; // render model for hit detection
|
||||
int combatModelContents;
|
||||
idVec3 spawnOrigin; // spawn origin
|
||||
idMat3 spawnAxis; // rotation axis used when spawned
|
||||
int nextSoundTime; // next time this can make a sound
|
||||
|
||||
void Event_SetConstraintPosition( const char *name, const idVec3 &pos );
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idAFEntity_Gibbable
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
extern const idEventDef EV_Gib;
|
||||
extern const idEventDef EV_Gibbed;
|
||||
|
||||
class idAFEntity_Gibbable : public idAFEntity_Base {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idAFEntity_Gibbable );
|
||||
|
||||
idAFEntity_Gibbable();
|
||||
~idAFEntity_Gibbable();
|
||||
|
||||
void Spawn();
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
virtual void Present();
|
||||
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
|
||||
void SetThrown( bool isThrown );
|
||||
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
|
||||
virtual void SpawnGibs( const idVec3 &dir, const char *damageDefName );
|
||||
|
||||
bool IsGibbed() { return gibbed; };
|
||||
|
||||
protected:
|
||||
idRenderModel * skeletonModel;
|
||||
int skeletonModelDefHandle;
|
||||
bool gibbed;
|
||||
|
||||
bool wasThrown;
|
||||
|
||||
virtual void Gib( const idVec3 &dir, const char *damageDefName );
|
||||
void InitSkeletonModel();
|
||||
|
||||
void Event_Gib( const char *damageDefName );
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idAFEntity_Generic
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idAFEntity_Generic : public idAFEntity_Gibbable {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idAFEntity_Generic );
|
||||
|
||||
idAFEntity_Generic();
|
||||
~idAFEntity_Generic();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void Think();
|
||||
void KeepRunningPhysics() { keepRunningPhysics = true; }
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
|
||||
bool keepRunningPhysics;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idAFEntity_WithAttachedHead
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idAFEntity_WithAttachedHead : public idAFEntity_Gibbable {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idAFEntity_WithAttachedHead );
|
||||
|
||||
idAFEntity_WithAttachedHead();
|
||||
~idAFEntity_WithAttachedHead();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void SetupHead();
|
||||
|
||||
virtual void Think();
|
||||
|
||||
virtual void Hide();
|
||||
virtual void Show();
|
||||
virtual void ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material );
|
||||
|
||||
virtual void LinkCombat();
|
||||
virtual void UnlinkCombat();
|
||||
|
||||
protected:
|
||||
virtual void Gib( const idVec3 &dir, const char *damageDefName );
|
||||
|
||||
public:
|
||||
idEntityPtr<idAFAttachment> head;
|
||||
|
||||
void Event_Gib( const char *damageDefName );
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idAFEntity_Vehicle
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idAFEntity_Vehicle : public idAFEntity_Base {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idAFEntity_Vehicle );
|
||||
|
||||
idAFEntity_Vehicle();
|
||||
|
||||
void Spawn();
|
||||
void Use( idPlayer *player );
|
||||
|
||||
protected:
|
||||
idPlayer * player;
|
||||
jointHandle_t eyesJoint;
|
||||
jointHandle_t steeringWheelJoint;
|
||||
float wheelRadius;
|
||||
float steerAngle;
|
||||
float steerSpeed;
|
||||
const idDeclParticle * dustSmoke;
|
||||
|
||||
float GetSteerAngle();
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idAFEntity_VehicleSimple
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idAFEntity_VehicleSimple : public idAFEntity_Vehicle {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idAFEntity_VehicleSimple );
|
||||
|
||||
idAFEntity_VehicleSimple();
|
||||
~idAFEntity_VehicleSimple();
|
||||
|
||||
void Spawn();
|
||||
virtual void Think();
|
||||
|
||||
protected:
|
||||
idClipModel * wheelModel;
|
||||
idAFConstraint_Suspension * suspension[4];
|
||||
jointHandle_t wheelJoints[4];
|
||||
float wheelAngles[4];
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idAFEntity_VehicleFourWheels
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idAFEntity_VehicleFourWheels : public idAFEntity_Vehicle {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idAFEntity_VehicleFourWheels );
|
||||
|
||||
idAFEntity_VehicleFourWheels();
|
||||
|
||||
void Spawn();
|
||||
virtual void Think();
|
||||
|
||||
protected:
|
||||
idAFBody * wheels[4];
|
||||
idAFConstraint_Hinge * steering[2];
|
||||
jointHandle_t wheelJoints[4];
|
||||
float wheelAngles[4];
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idAFEntity_VehicleSixWheels
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idAFEntity_VehicleSixWheels : public idAFEntity_Vehicle {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idAFEntity_VehicleSixWheels );
|
||||
|
||||
idAFEntity_VehicleSixWheels();
|
||||
|
||||
void Spawn();
|
||||
virtual void Think();
|
||||
|
||||
float force;
|
||||
float velocity;
|
||||
float steerAngle;
|
||||
|
||||
private:
|
||||
idAFBody * wheels[6];
|
||||
idAFConstraint_Hinge * steering[4];
|
||||
jointHandle_t wheelJoints[6];
|
||||
float wheelAngles[6];
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idAFEntity_VehicleAutomated
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idAFEntity_VehicleAutomated : public idAFEntity_VehicleSixWheels {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idAFEntity_VehicleAutomated );
|
||||
|
||||
void Spawn();
|
||||
void PostSpawn();
|
||||
virtual void Think();
|
||||
|
||||
private:
|
||||
|
||||
idEntity *waypoint;
|
||||
float steeringSpeed;
|
||||
float currentSteering;
|
||||
float idealSteering;
|
||||
float originHeight;
|
||||
|
||||
void Event_SetVelocity( float _velocity );
|
||||
void Event_SetTorque( float _torque );
|
||||
void Event_SetSteeringSpeed( float _steeringSpeed );
|
||||
void Event_SetWayPoint( idEntity *_waypoint );
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idAFEntity_SteamPipe
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idAFEntity_SteamPipe : public idAFEntity_Base {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idAFEntity_SteamPipe );
|
||||
|
||||
idAFEntity_SteamPipe();
|
||||
~idAFEntity_SteamPipe();
|
||||
|
||||
void Spawn();
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void Think();
|
||||
|
||||
private:
|
||||
int steamBody;
|
||||
float steamForce;
|
||||
float steamUpForce;
|
||||
idForce_Constant force;
|
||||
renderEntity_t steamRenderEntity;
|
||||
qhandle_t steamModelDefHandle;
|
||||
|
||||
void InitSteamRenderEntity();
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idAFEntity_ClawFourFingers
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idAFEntity_ClawFourFingers : public idAFEntity_Base {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idAFEntity_ClawFourFingers );
|
||||
|
||||
idAFEntity_ClawFourFingers();
|
||||
|
||||
void Spawn();
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
private:
|
||||
idAFConstraint_Hinge * fingers[4];
|
||||
|
||||
void Event_SetFingerAngle( float angle );
|
||||
void Event_StopFingers();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* idHarvestable contains all of the code required to turn an entity into a harvestable
|
||||
* entity. The entity must create an instance of this class and call the appropriate
|
||||
* interface methods at the correct time.
|
||||
*/
|
||||
class idHarvestable : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idHarvestable );
|
||||
|
||||
idHarvestable();
|
||||
~idHarvestable();
|
||||
|
||||
void Spawn();
|
||||
void Init(idEntity* parent);
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void SetParent(idEntity* parent);
|
||||
|
||||
void Think();
|
||||
void Gib();
|
||||
|
||||
protected:
|
||||
idEntityPtr<idEntity> parentEnt;
|
||||
float triggersize;
|
||||
idClipModel * trigger;
|
||||
float giveDelay;
|
||||
float removeDelay;
|
||||
bool given;
|
||||
|
||||
idEntityPtr<idPlayer> player;
|
||||
int startTime;
|
||||
|
||||
bool fxFollowPlayer;
|
||||
idEntityPtr<idEntityFx> fx;
|
||||
idStr fxOrient;
|
||||
|
||||
protected:
|
||||
void BeginBurn();
|
||||
void BeginFX();
|
||||
void CalcTriggerBounds( float size, idBounds &bounds );
|
||||
|
||||
bool GetFxOrientationAxis(idMat3& mat);
|
||||
|
||||
void Event_SpawnHarvestTrigger();
|
||||
void Event_Touch( idEntity *other, trace_t *trace );
|
||||
} ;
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idAFEntity_Harvest
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
|
||||
|
||||
class idAFEntity_Harvest : public idAFEntity_WithAttachedHead {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idAFEntity_Harvest );
|
||||
|
||||
idAFEntity_Harvest();
|
||||
~idAFEntity_Harvest();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void Think();
|
||||
|
||||
virtual void Gib( const idVec3 &dir, const char *damageDefName );
|
||||
|
||||
protected:
|
||||
idEntityPtr<idHarvestable> harvestEnt;
|
||||
protected:
|
||||
void Event_SpawnHarvestEntity();
|
||||
|
||||
};
|
||||
|
||||
#endif /* !__GAME_AFENTITY_H__ */
|
||||
537
neo/d3xp/Achievements.cpp
Normal file
537
neo/d3xp/Achievements.cpp
Normal file
@@ -0,0 +1,537 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#include "../idlib/precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Game_local.h"
|
||||
#include "..\..\doomclassic\doom\doomdef.h"
|
||||
|
||||
idCVar achievements_Verbose( "achievements_Verbose", "1", CVAR_BOOL, "debug spam" );
|
||||
idCVar g_demoMode( "g_demoMode", "0", CVAR_INTEGER, "this is a demo" );
|
||||
|
||||
bool idAchievementManager::cheatingDialogShown = false;
|
||||
|
||||
const struct achievementInfo_t {
|
||||
int required;
|
||||
bool lifetime; // true means the current count is stored on the player profile. Doesn't matter for single count achievements.
|
||||
} achievementInfo [ACHIEVEMENTS_NUM] = {
|
||||
{ 50, true }, // ACHIEVEMENT_EARN_ALL_50_TROPHIES
|
||||
{ 1, true }, // ACHIEVEMENT_COMPLETED_DIFFICULTY_0
|
||||
{ 1, true }, // ACHIEVEMENT_COMPLETED_DIFFICULTY_1
|
||||
{ 1, true }, // ACHIEVEMENT_COMPLETED_DIFFICULTY_2
|
||||
{ 1, true }, // ACHIEVEMENT_COMPLETED_DIFFICULTY_3
|
||||
{ 64, false }, // ACHIEVEMENT_PDAS_BASE
|
||||
{ 14, false }, // ACHIEVEMENT_WATCH_ALL_VIDEOS
|
||||
{ 1, false }, // ACHIEVEMENT_KILL_MONSTER_WITH_1_HEALTH_LEFT
|
||||
{ 35, false }, // ACHIEVEMENT_OPEN_ALL_LOCKERS
|
||||
{ 20, true }, // ACHIEVEMENT_KILL_20_ENEMY_FISTS_HANDS
|
||||
{ 1, true }, // ACHIEVEMENT_KILL_SCI_NEXT_TO_RCR
|
||||
{ 1, true }, // ACHIEVEMENT_KILL_TWO_IMPS_ONE_SHOTGUN
|
||||
{ 1, true }, // ACHIEVEMENT_SCORE_25000_TURKEY_PUNCHER
|
||||
{ 50, true }, // ACHIEVEMENT_DESTROY_BARRELS
|
||||
{ 1, true }, // ACHIEVEMENT_GET_BFG_FROM_SECURITY_OFFICE
|
||||
{ 1, true }, // ACHIEVEMENT_COMPLETE_LEVEL_WITHOUT_TAKING_DMG
|
||||
{ 1, true }, // ACHIEVEMENT_FIND_RAGE_LOGO
|
||||
{ 1, true }, // ACHIEVEMENT_SPEED_RUN
|
||||
{ 1, true }, // ACHIEVEMENT_DEFEAT_VAGARY_BOSS
|
||||
{ 1, true }, // ACHIEVEMENT_DEFEAT_GUARDIAN_BOSS
|
||||
{ 1, true }, // ACHIEVEMENT_DEFEAT_SABAOTH_BOSS
|
||||
{ 1, true }, // ACHIEVEMENT_DEFEAT_CYBERDEMON_BOSS
|
||||
{ 1, true }, // ACHIEVEMENT_SENTRY_BOT_ALIVE_TO_DEST
|
||||
{ 20, true }, // ACHIEVEMENT_KILL_20_ENEMY_WITH_CHAINSAW
|
||||
{ 1, true }, // ACHIEVEMENT_ID_LOGO_SECRET_ROOM
|
||||
{ 1, true }, // ACHIEVEMENT_BLOODY_HANDWORK_OF_BETRUGER
|
||||
{ 1, true }, // ACHIEVEMENT_TWO_DEMONS_FIGHT_EACH_OTHER
|
||||
{ 20, true }, // ACHIEVEMENT_USE_SOUL_CUBE_TO_DEFEAT_20_ENEMY
|
||||
{ 1, true }, // ACHIEVEMENT_ROE_COMPLETED_DIFFICULTY_0
|
||||
{ 1, true }, // ACHIEVEMENT_ROE_COMPLETED_DIFFICULTY_1
|
||||
{ 1, true }, // ACHIEVEMENT_ROE_COMPLETED_DIFFICULTY_2
|
||||
{ 1, true }, // ACHIEVEMENT_ROE_COMPLETED_DIFFICULTY_3
|
||||
{ 22, false }, // ACHIEVEMENT_PDAS_ROE
|
||||
{ 1, true }, // ACHIEVEMENT_KILL_5_ENEMY_HELL_TIME
|
||||
{ 1, true }, // ACHIEVEMENT_DEFEAT_HELLTIME_HUNTER
|
||||
{ 1, true }, // ACHIEVEMENT_DEFEAT_BERSERK_HUNTER
|
||||
{ 1, true }, // ACHIEVEMENT_DEFEAT_INVULNERABILITY_HUNTER
|
||||
{ 1, true }, // ACHIEVEMENT_DEFEAT_MALEDICT_BOSS
|
||||
{ 20, true }, // ACHIEVEMENT_GRABBER_KILL_20_ENEMY
|
||||
{ 20, true }, // ACHIEVEMENT_ARTIFACT_WITH_BERSERK_PUNCH_20
|
||||
{ 1, true }, // ACHIEVEMENT_LE_COMPLETED_DIFFICULTY_0
|
||||
{ 1, true }, // ACHIEVEMENT_LE_COMPLETED_DIFFICULTY_1
|
||||
{ 1, true }, // ACHIEVEMENT_LE_COMPLETED_DIFFICULTY_2
|
||||
{ 1, true }, // ACHIEVEMENT_LE_COMPLETED_DIFFICULTY_3
|
||||
{ 10, false }, // ACHIEVEMENT_PDAS_LE
|
||||
{ 1, true }, // ACHIEVEMENT_MP_KILL_PLAYER_VIA_TELEPORT
|
||||
{ 1, true }, // ACHIEVEMENT_MP_CATCH_ENEMY_IN_ROFC
|
||||
{ 5, true }, // ACHIEVEMENT_MP_KILL_5_PLAYERS_USING_INVIS
|
||||
{ 1, true }, // ACHIEVEMENT_MP_COMPLETE_MATCH_WITHOUT_DYING
|
||||
{ 1, true }, // ACHIEVEMENT_MP_USE_BERSERK_TO_KILL_PLAYER
|
||||
{ 1, true }, // ACHIEVEMENT_MP_KILL_2_GUYS_IN_ROOM_WITH_BFG
|
||||
};
|
||||
|
||||
/*
|
||||
================================================================================================
|
||||
|
||||
idAchievementManager
|
||||
|
||||
================================================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
========================
|
||||
idAchievementManager::idAchievementManager
|
||||
========================
|
||||
*/
|
||||
idAchievementManager::idAchievementManager() :
|
||||
lastImpKilledTime( 0 ),
|
||||
lastPlayerKilledTime( 0 ),
|
||||
playerTookDamage( false ) {
|
||||
counts.Zero();
|
||||
ResetHellTimeKills();
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idAchievementManager::Init
|
||||
========================
|
||||
*/
|
||||
void idAchievementManager::Init( idPlayer * player ) {
|
||||
owner = player;
|
||||
SyncAchievments();
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idAchievementManager::SyncAchievments
|
||||
========================
|
||||
*/
|
||||
void idAchievementManager::SyncAchievments() {
|
||||
idLocalUser * user = GetLocalUser();
|
||||
if ( user == NULL || user->GetProfile() == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set achievement counts
|
||||
for ( int i = 0; i < counts.Num(); i++ ) {
|
||||
if ( user->GetProfile()->GetAchievement( i ) ) {
|
||||
counts[i] = achievementInfo[i].required;
|
||||
} else if ( achievementInfo[i].lifetime ) {
|
||||
counts[i] = user->GetStatInt( i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idAchievementManager::GetLocalUser
|
||||
========================
|
||||
*/
|
||||
idLocalUser * idAchievementManager::GetLocalUser() {
|
||||
if ( !verify( owner != NULL ) ) {
|
||||
return NULL;
|
||||
}
|
||||
return session->GetGameLobbyBase().GetLocalUserFromLobbyUser( gameLocal.lobbyUserIDs[ owner->GetEntityNumber() ] );
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idAchievementManager::Save
|
||||
========================
|
||||
*/
|
||||
void idAchievementManager::Save( idSaveGame * savefile ) const {
|
||||
owner.Save( savefile );
|
||||
|
||||
for ( int i = 0; i < ACHIEVEMENTS_NUM; i++ ) {
|
||||
savefile->WriteInt( counts[i] );
|
||||
}
|
||||
|
||||
savefile->WriteInt( lastImpKilledTime );
|
||||
savefile->WriteInt( lastPlayerKilledTime );
|
||||
savefile->WriteBool( playerTookDamage );
|
||||
savefile->WriteInt( currentHellTimeKills );
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idAchievementManager::Restore
|
||||
========================
|
||||
*/
|
||||
void idAchievementManager::Restore( idRestoreGame * savefile ) {
|
||||
owner.Restore( savefile );
|
||||
|
||||
for ( int i = 0; i < ACHIEVEMENTS_NUM; i++ ) {
|
||||
savefile->ReadInt( counts[i] );
|
||||
}
|
||||
|
||||
savefile->ReadInt( lastImpKilledTime );
|
||||
savefile->ReadInt( lastPlayerKilledTime );
|
||||
savefile->ReadBool( playerTookDamage );
|
||||
savefile->ReadInt( currentHellTimeKills );
|
||||
|
||||
SyncAchievments();
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idAchievementManager::EventCompletesAchievement
|
||||
========================
|
||||
*/
|
||||
void idAchievementManager::EventCompletesAchievement( const achievement_t eventId ) {
|
||||
if ( g_demoMode.GetBool() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
idLocalUser * localUser = GetLocalUser();
|
||||
if ( localUser == NULL || localUser->GetProfile() == NULL ) {
|
||||
|
||||
// Send a Reliable Message to the User that needs to unlock this.
|
||||
if ( owner != NULL ) {
|
||||
int playerId = owner->entityNumber;
|
||||
const int bufferSize = sizeof( playerId ) + sizeof( eventId );
|
||||
byte buffer[ bufferSize ];
|
||||
idBitMsg msg;
|
||||
msg.InitWrite( buffer, bufferSize );
|
||||
|
||||
msg.WriteByte( playerId );
|
||||
msg.WriteByte( eventId );
|
||||
|
||||
msg.WriteByteAlign();
|
||||
idLib::Printf( "Host Sending Achievement\n");
|
||||
session->GetActingGameStateLobbyBase().SendReliableToLobbyUser( gameLocal.lobbyUserIDs[ owner->entityNumber ], GAME_RELIABLE_MESSAGE_ACHIEVEMENT_UNLOCK, msg );
|
||||
}
|
||||
|
||||
return; // Remote user or build game
|
||||
}
|
||||
|
||||
// Check to see if we've already given the achievement.
|
||||
// If so, don't do again because we don't want to autosave every time a trigger is hit
|
||||
if ( localUser->GetProfile()->GetAchievement( eventId ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ID_RETAIL
|
||||
if ( common->GetConsoleUsed() ) {
|
||||
if ( !cheatingDialogShown ) {
|
||||
common->Dialog().AddDialog( GDM_ACHIEVEMENTS_DISABLED_DUE_TO_CHEATING, DIALOG_ACCEPT, NULL, NULL, true );
|
||||
cheatingDialogShown = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
counts[eventId]++;
|
||||
|
||||
if ( counts[eventId] >= achievementInfo[eventId].required ) {
|
||||
session->GetAchievementSystem().AchievementUnlock( localUser, eventId );
|
||||
} else {
|
||||
if ( achievementInfo[eventId].lifetime ) {
|
||||
localUser->SetStatInt( eventId, counts[eventId] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idAchievementManager::IncrementHellTimeKills
|
||||
========================
|
||||
*/
|
||||
void idAchievementManager::IncrementHellTimeKills() {
|
||||
currentHellTimeKills++;
|
||||
if ( currentHellTimeKills >= 5 ) {
|
||||
EventCompletesAchievement( ACHIEVEMENT_KILL_5_ENEMY_HELL_TIME );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idAchievementManager::SavePersistentData
|
||||
========================
|
||||
*/
|
||||
void idAchievementManager::SavePersistentData( idDict & playerInfo ) {
|
||||
for ( int i = 0; i < ACHIEVEMENTS_NUM; ++i ) {
|
||||
playerInfo.SetInt( va( "ach_%d", i ), counts[i] );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idAchievementManager::RestorePersistentData
|
||||
========================
|
||||
*/
|
||||
void idAchievementManager::RestorePersistentData( const idDict & spawnArgs ) {
|
||||
for( int i = 0; i < ACHIEVEMENTS_NUM; ++i ) {
|
||||
counts[i] = spawnArgs.GetInt( va( "ach_%d", i), "0" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
idAchievementManager::LocalUser_CompleteAchievement
|
||||
========================
|
||||
*/
|
||||
void idAchievementManager::LocalUser_CompleteAchievement( achievement_t id ) {
|
||||
idLocalUser * localUser = session->GetSignInManager().GetMasterLocalUser();
|
||||
|
||||
// Check to see if we've already given the achievement.
|
||||
// If so, don't do again because we don't want to autosave every time a trigger is hit
|
||||
if( localUser == NULL || localUser->GetProfile()->GetAchievement( id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ID_RETAIL
|
||||
if ( common->GetConsoleUsed() ) {
|
||||
if ( !cheatingDialogShown ) {
|
||||
common->Dialog().AddDialog( GDM_ACHIEVEMENTS_DISABLED_DUE_TO_CHEATING, DIALOG_ACCEPT, NULL, NULL, true );
|
||||
cheatingDialogShown = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
session->GetAchievementSystem().AchievementUnlock( localUser, id );
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idAchievementManager::CheckDoomClassicsAchievements
|
||||
|
||||
Processed when the player finishes a level.
|
||||
========================
|
||||
*/
|
||||
void idAchievementManager::CheckDoomClassicsAchievements( int killcount, int itemcount, int secretcount, int skill, int mission, int map, int episode, int totalkills, int totalitems, int totalsecret ) {
|
||||
|
||||
const skill_t difficulty = (skill_t)skill;
|
||||
const currentGame_t currentGame = common->GetCurrentGame();
|
||||
const GameMission_t expansion = (GameMission_t)mission;
|
||||
|
||||
|
||||
idLocalUser * localUser = session->GetSignInManager().GetMasterLocalUser();
|
||||
if ( localUser != NULL && localUser->GetProfile() != NULL ) {
|
||||
|
||||
// GENERAL ACHIEVEMENT UNLOCKING.
|
||||
if( currentGame == DOOM_CLASSIC ) {
|
||||
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_NEOPHYTE_COMPLETE_ANY_LEVEL );
|
||||
} else if( currentGame == DOOM2_CLASSIC ) {
|
||||
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM2_JUST_GETTING_STARTED_COMPLETE_ANY_LEVEL );
|
||||
}
|
||||
|
||||
// Complete Any Level on Nightmare.
|
||||
if ( difficulty == sk_nightmare && currentGame == DOOM_CLASSIC ) {
|
||||
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_NIGHTMARE_COMPLETE_ANY_LEVEL_NIGHTMARE );
|
||||
}
|
||||
|
||||
const bool gotAllKills = killcount >= totalkills;
|
||||
const bool gotAllItems = itemcount >= totalitems;
|
||||
const bool gotAllSecrets = secretcount >= totalsecret;
|
||||
|
||||
if ( gotAllItems && gotAllKills && gotAllSecrets ) {
|
||||
if( currentGame == DOOM_CLASSIC ) {
|
||||
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_BURNING_OUT_OF_CONTROL_COMPLETE_KILLS_ITEMS_SECRETS );
|
||||
} else if( currentGame == DOOM2_CLASSIC ) {
|
||||
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM2_BURNING_OUT_OF_CONTROL_COMPLETE_KILLS_ITEMS_SECRETS );
|
||||
}
|
||||
}
|
||||
|
||||
// DOOM EXPANSION ACHIEVEMENTS
|
||||
if( expansion == doom ) {
|
||||
|
||||
if( map == 8 ) {
|
||||
|
||||
// Medium or higher skill level.
|
||||
if( difficulty >= sk_medium ) {
|
||||
localUser->SetStatInt( STAT_DOOM_COMPLETED_EPISODE_1_MEDIUM + ( episode - 1 ), 1 );
|
||||
}
|
||||
|
||||
// Hard or higher skill level.
|
||||
if( difficulty >= sk_hard ) {
|
||||
localUser->SetStatInt( STAT_DOOM_COMPLETED_EPISODE_1_HARD + ( episode - 1 ), 1 );
|
||||
localUser->SetStatInt( STAT_DOOM_COMPLETED_EPISODE_1_MEDIUM + ( episode - 1 ), 1 );
|
||||
}
|
||||
|
||||
if ( difficulty == sk_nightmare ) {
|
||||
localUser->SetStatInt( STAT_DOOM_COMPLETED_EPISODE_1_HARD + ( episode - 1 ), 1 );
|
||||
localUser->SetStatInt( STAT_DOOM_COMPLETED_EPISODE_1_MEDIUM + ( episode - 1 ), 1 );
|
||||
}
|
||||
|
||||
// Save the Settings.
|
||||
localUser->SaveProfileSettings();
|
||||
}
|
||||
|
||||
// Check to see if we've completed all episodes.
|
||||
const int episode1completed = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_1_MEDIUM );
|
||||
const int episode2completed = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_2_MEDIUM );
|
||||
const int episode3completed = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_3_MEDIUM );
|
||||
const int episode4completed = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_4_MEDIUM );
|
||||
|
||||
const int episode1completed_hard = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_1_HARD );
|
||||
const int episode2completed_hard = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_2_HARD );
|
||||
const int episode3completed_hard = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_3_HARD );
|
||||
const int episode4completed_hard = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_4_HARD );
|
||||
|
||||
if ( currentGame == DOOM_CLASSIC ) {
|
||||
if ( episode1completed ) {
|
||||
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_EPISODE1_COMPLETE_MEDIUM );
|
||||
}
|
||||
|
||||
if ( episode2completed ) {
|
||||
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_EPISODE2_COMPLETE_MEDIUM );
|
||||
}
|
||||
|
||||
if ( episode3completed ) {
|
||||
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_EPISODE3_COMPLETE_MEDIUM );
|
||||
}
|
||||
|
||||
if ( episode4completed ) {
|
||||
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_EPISODE4_COMPLETE_MEDIUM );
|
||||
}
|
||||
|
||||
if ( episode1completed_hard && episode2completed_hard && episode3completed_hard && episode4completed_hard ) {
|
||||
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_RAMPAGE_COMPLETE_ALL_HARD );
|
||||
}
|
||||
}
|
||||
} else if( expansion == doom2 ) {
|
||||
|
||||
if( map == 30 ) {
|
||||
|
||||
if ( currentGame == DOOM2_CLASSIC ) {
|
||||
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM2_FROM_EARTH_TO_HELL_COMPLETE_HELL_ON_EARTH );
|
||||
|
||||
if ( difficulty >= sk_hard ) {
|
||||
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM2_SUPERIOR_FIREPOWER_COMPLETE_ALL_HARD );
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if( expansion == pack_nerve ) {
|
||||
if( map == 8 ) {
|
||||
|
||||
if ( currentGame == DOOM2_CLASSIC ) {
|
||||
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM2_AND_BACK_AGAIN_COMPLETE_NO_REST );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
AchievementsReset
|
||||
=================
|
||||
*/
|
||||
CONSOLE_COMMAND( AchievementsReset, "Lock an achievement", NULL ) {
|
||||
idLocalUser * user = session->GetSignInManager().GetMasterLocalUser();
|
||||
if ( user == NULL ) {
|
||||
idLib::Printf( "Must be signed in\n" );
|
||||
return;
|
||||
}
|
||||
if ( args.Argc() == 1 ) {
|
||||
for ( int i = 0; i < ACHIEVEMENTS_NUM; i++ ) {
|
||||
user->SetStatInt( i, 0 );
|
||||
session->GetAchievementSystem().AchievementLock( user, i );
|
||||
}
|
||||
} else {
|
||||
int i = atoi( args.Argv( 1 ) );
|
||||
user->SetStatInt( i, 0 );
|
||||
session->GetAchievementSystem().AchievementLock( user, i );
|
||||
}
|
||||
user->SaveProfileSettings();
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
AchievementsUnlock
|
||||
=================
|
||||
*/
|
||||
CONSOLE_COMMAND( AchievementsUnlock, "Unlock an achievement", NULL ) {
|
||||
idLocalUser * user = session->GetSignInManager().GetMasterLocalUser();
|
||||
if ( user == NULL ) {
|
||||
idLib::Printf( "Must be signed in\n" );
|
||||
return;
|
||||
}
|
||||
if ( args.Argc() == 1 ) {
|
||||
for ( int i = 0; i < ACHIEVEMENTS_NUM; i++ ) {
|
||||
user->SetStatInt( i, achievementInfo[i].required );
|
||||
session->GetAchievementSystem().AchievementUnlock( user, i );
|
||||
}
|
||||
} else {
|
||||
int i = atoi( args.Argv( 1 ) );
|
||||
user->SetStatInt( i, achievementInfo[i].required );
|
||||
session->GetAchievementSystem().AchievementUnlock( user, i );
|
||||
}
|
||||
user->SaveProfileSettings();
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
AchievementsList
|
||||
=================
|
||||
*/
|
||||
CONSOLE_COMMAND( AchievementsList, "Lists achievements and status", NULL ) {
|
||||
idPlayer * player = gameLocal.GetLocalPlayer();
|
||||
idLocalUser * user = ( player == NULL ) ? session->GetSignInManager().GetMasterLocalUser() : session->GetGameLobbyBase().GetLocalUserFromLobbyUser( gameLocal.lobbyUserIDs[ player->GetEntityNumber() ] );
|
||||
if ( user == NULL ) {
|
||||
idLib::Printf( "Must be signed in\n" );
|
||||
return;
|
||||
}
|
||||
idPlayerProfile * profile = user->GetProfile();
|
||||
|
||||
idArray<bool, 128> achievementState;
|
||||
bool achievementStateValid = session->GetAchievementSystem().GetAchievementState( user, achievementState );
|
||||
|
||||
for ( int i = 0; i < ACHIEVEMENTS_NUM; i++ ) {
|
||||
const char * pInfo = "";
|
||||
if ( profile == NULL ) {
|
||||
pInfo = S_COLOR_RED "unknown" S_COLOR_DEFAULT;
|
||||
} else if ( !profile->GetAchievement( i ) ) {
|
||||
pInfo = S_COLOR_YELLOW "locked" S_COLOR_DEFAULT;
|
||||
} else {
|
||||
pInfo = S_COLOR_GREEN "unlocked" S_COLOR_DEFAULT;
|
||||
}
|
||||
const char * sInfo = "";
|
||||
if ( !achievementStateValid ) {
|
||||
sInfo = S_COLOR_RED "unknown" S_COLOR_DEFAULT;
|
||||
} else if ( !achievementState[i] ) {
|
||||
sInfo = S_COLOR_YELLOW "locked" S_COLOR_DEFAULT;
|
||||
} else {
|
||||
sInfo = S_COLOR_GREEN "unlocked" S_COLOR_DEFAULT;
|
||||
}
|
||||
int count = 0;
|
||||
if ( achievementInfo[i].lifetime ) {
|
||||
count = user->GetStatInt( i );
|
||||
} else if ( player != NULL ) {
|
||||
count = player->GetAchievementManager().GetCount( (achievement_t) i );
|
||||
} else {
|
||||
count = 0;
|
||||
}
|
||||
|
||||
achievementDescription_t data;
|
||||
bool descriptionValid = session->GetAchievementSystem().GetAchievementDescription( user, i, data );
|
||||
|
||||
idLib::Printf( "%02d: %2d/%2d | %12.12s | %12.12s | %s%s\n", i, count, achievementInfo[i].required, pInfo, sInfo, descriptionValid ? data.hidden ? "(hidden) " : "" : "(unknown) ", descriptionValid ? data.name : "" );
|
||||
}
|
||||
}
|
||||
184
neo/d3xp/Achievements.h
Normal file
184
neo/d3xp/Achievements.h
Normal file
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#ifndef __ACHIEVEMENTS_H__
|
||||
#define __ACHIEVEMENTS_H__
|
||||
|
||||
enum achievement_t {
|
||||
|
||||
ACHIEVEMENT_INVALID = -1,
|
||||
|
||||
ACHIEVEMENT_EARN_ALL_50_TROPHIES, // 0 // DONE -- (automagic?)
|
||||
|
||||
ACHIEVEMENT_COMPLETED_DIFFICULTY_0, // 1 // DONE -- Recruit
|
||||
ACHIEVEMENT_COMPLETED_DIFFICULTY_1, // 2 // DONE -- Marine
|
||||
ACHIEVEMENT_COMPLETED_DIFFICULTY_2, // 3 // DONE -- Veteran
|
||||
ACHIEVEMENT_COMPLETED_DIFFICULTY_3, // 4 // DONE -- Nightmare
|
||||
|
||||
ACHIEVEMENT_PDAS_BASE, // 5 // DONE --
|
||||
ACHIEVEMENT_WATCH_ALL_VIDEOS, // 6 // DONE --
|
||||
ACHIEVEMENT_KILL_MONSTER_WITH_1_HEALTH_LEFT, // 7 // DONE --
|
||||
ACHIEVEMENT_OPEN_ALL_LOCKERS, // 8 // DONE --
|
||||
ACHIEVEMENT_KILL_20_ENEMY_FISTS_HANDS, // 9 // DONE --- kill 20 enemies with fists & hands
|
||||
ACHIEVEMENT_KILL_SCI_NEXT_TO_RCR, // 10 // DONE -----> ADD TARGET TO MAP kill scientist trapped next to reactor control room
|
||||
ACHIEVEMENT_KILL_TWO_IMPS_ONE_SHOTGUN, // 11 // DONE --
|
||||
ACHIEVEMENT_SCORE_25000_TURKEY_PUNCHER, // 12 // DONE --
|
||||
ACHIEVEMENT_DESTROY_BARRELS, // 13 // DONE --
|
||||
ACHIEVEMENT_GET_BFG_FROM_SECURITY_OFFICE, // 14 // DONE -----> ADD TARGET TO MAP
|
||||
ACHIEVEMENT_COMPLETE_LEVEL_WITHOUT_TAKING_DMG, // 15 // DONE --
|
||||
ACHIEVEMENT_FIND_RAGE_LOGO, // 16 // DONE -----> ADD TARGET TO MAP (jerry)
|
||||
ACHIEVEMENT_SPEED_RUN, // 17 // DONE --
|
||||
|
||||
ACHIEVEMENT_DEFEAT_VAGARY_BOSS, // 18 // DONE --
|
||||
ACHIEVEMENT_DEFEAT_GUARDIAN_BOSS, // 19 // DONE --
|
||||
ACHIEVEMENT_DEFEAT_SABAOTH_BOSS, // 20 // DONE --
|
||||
ACHIEVEMENT_DEFEAT_CYBERDEMON_BOSS, // 21 // DONE --
|
||||
|
||||
ACHIEVEMENT_SENTRY_BOT_ALIVE_TO_DEST, // 22 // DONE -----> ADD TARGET TO MAP
|
||||
ACHIEVEMENT_KILL_20_ENEMY_WITH_CHAINSAW, // 23 // DONE --
|
||||
ACHIEVEMENT_ID_LOGO_SECRET_ROOM, // 24 // DONE -----> ADD TARGET TO MAP
|
||||
ACHIEVEMENT_BLOODY_HANDWORK_OF_BETRUGER, // 25 // DONE -----> ADD TARGET TO MAP
|
||||
ACHIEVEMENT_TWO_DEMONS_FIGHT_EACH_OTHER, // 26 // DONE --
|
||||
ACHIEVEMENT_USE_SOUL_CUBE_TO_DEFEAT_20_ENEMY, // 27 // DONE --
|
||||
|
||||
ACHIEVEMENT_ROE_COMPLETED_DIFFICULTY_0, // 28 // DONE -- Recruit
|
||||
ACHIEVEMENT_ROE_COMPLETED_DIFFICULTY_1, // 29 // DONE -- Marine
|
||||
ACHIEVEMENT_ROE_COMPLETED_DIFFICULTY_2, // 30 // DONE -- Veteran
|
||||
ACHIEVEMENT_ROE_COMPLETED_DIFFICULTY_3, // 31 // DONE -- Nightmare
|
||||
|
||||
ACHIEVEMENT_PDAS_ROE, // 32 // DONE -- read all pdas in RoE
|
||||
ACHIEVEMENT_KILL_5_ENEMY_HELL_TIME, // 33 // DONE --
|
||||
ACHIEVEMENT_DEFEAT_HELLTIME_HUNTER, // 34 // DONE --
|
||||
ACHIEVEMENT_DEFEAT_BERSERK_HUNTER, // 35 // DONE --
|
||||
ACHIEVEMENT_DEFEAT_INVULNERABILITY_HUNTER, // 36 // DONE --
|
||||
ACHIEVEMENT_DEFEAT_MALEDICT_BOSS, // 37 // DONE --
|
||||
ACHIEVEMENT_GRABBER_KILL_20_ENEMY, // 38 // DONE --
|
||||
ACHIEVEMENT_ARTIFACT_WITH_BERSERK_PUNCH_20, // 39 // DONE --
|
||||
|
||||
ACHIEVEMENT_LE_COMPLETED_DIFFICULTY_0, // 40 // DONE -- Recruit
|
||||
ACHIEVEMENT_LE_COMPLETED_DIFFICULTY_1, // 41 // DONE -- Marine
|
||||
ACHIEVEMENT_LE_COMPLETED_DIFFICULTY_2, // 42 // DONE -- Veteran
|
||||
ACHIEVEMENT_LE_COMPLETED_DIFFICULTY_3, // 43 // DONE -- Nightmare
|
||||
|
||||
ACHIEVEMENT_PDAS_LE, // 44 // DONE -- read all pdas in LE
|
||||
|
||||
ACHIEVEMENT_MP_KILL_PLAYER_VIA_TELEPORT, // 45 // DONE --
|
||||
ACHIEVEMENT_MP_CATCH_ENEMY_IN_ROFC, // 46 // DONE -- needs to be tested -- Reactor of Frag Chamber
|
||||
ACHIEVEMENT_MP_KILL_5_PLAYERS_USING_INVIS, // 47 // DONE --
|
||||
ACHIEVEMENT_MP_COMPLETE_MATCH_WITHOUT_DYING, // 48 // DONE --
|
||||
ACHIEVEMENT_MP_USE_BERSERK_TO_KILL_PLAYER, // 49 // DONE --
|
||||
ACHIEVEMENT_MP_KILL_2_GUYS_IN_ROOM_WITH_BFG, // 50 // DONE --
|
||||
|
||||
ACHIEVEMENT_DOOM1_NEOPHYTE_COMPLETE_ANY_LEVEL, // 51
|
||||
ACHIEVEMENT_DOOM1_EPISODE1_COMPLETE_MEDIUM, // 52
|
||||
ACHIEVEMENT_DOOM1_EPISODE2_COMPLETE_MEDIUM, // 53
|
||||
ACHIEVEMENT_DOOM1_EPISODE3_COMPLETE_MEDIUM, // 54
|
||||
ACHIEVEMENT_DOOM1_EPISODE4_COMPLETE_MEDIUM, // 55
|
||||
ACHIEVEMENT_DOOM1_RAMPAGE_COMPLETE_ALL_HARD, // 56
|
||||
ACHIEVEMENT_DOOM1_NIGHTMARE_COMPLETE_ANY_LEVEL_NIGHTMARE, // 57
|
||||
ACHIEVEMENT_DOOM1_BURNING_OUT_OF_CONTROL_COMPLETE_KILLS_ITEMS_SECRETS, // 58
|
||||
|
||||
ACHIEVEMENT_DOOM2_JUST_GETTING_STARTED_COMPLETE_ANY_LEVEL, // 59
|
||||
ACHIEVEMENT_DOOM2_FROM_EARTH_TO_HELL_COMPLETE_HELL_ON_EARTH, // 60
|
||||
ACHIEVEMENT_DOOM2_AND_BACK_AGAIN_COMPLETE_NO_REST, // 61
|
||||
ACHIEVEMENT_DOOM2_SUPERIOR_FIREPOWER_COMPLETE_ALL_HARD, // 62
|
||||
ACHIEVEMENT_DOOM2_REALLY_BIG_GUN_FIND_BFG_SINGLEPLAYER, // 63
|
||||
ACHIEVEMENT_DOOM2_BURNING_OUT_OF_CONTROL_COMPLETE_KILLS_ITEMS_SECRETS, // 64
|
||||
ACHIEVEMENT_DOOM2_IMPORTANT_LOOKING_DOOR_FIND_ANY_SECRET, // 65
|
||||
|
||||
ACHIEVEMENTS_NUM,
|
||||
|
||||
STAT_DOOM_COMPLETED_EPISODE_1_MEDIUM,
|
||||
STAT_DOOM_COMPLETED_EPISODE_2_MEDIUM,
|
||||
STAT_DOOM_COMPLETED_EPISODE_3_MEDIUM,
|
||||
STAT_DOOM_COMPLETED_EPISODE_4_MEDIUM,
|
||||
|
||||
STAT_DOOM_COMPLETED_EPISODE_1_HARD,
|
||||
STAT_DOOM_COMPLETED_EPISODE_2_HARD,
|
||||
STAT_DOOM_COMPLETED_EPISODE_3_HARD,
|
||||
STAT_DOOM_COMPLETED_EPISODE_4_HARD,
|
||||
};
|
||||
|
||||
compile_time_assert( ACHIEVEMENTS_NUM <= idPlayerProfile::MAX_PLAYER_PROFILE_STATS );
|
||||
|
||||
/*
|
||||
================================================
|
||||
idAchievementManager
|
||||
|
||||
Manages a List of Achievements associated with a particular Player.
|
||||
|
||||
This is setup to only have one achievement manager per game.
|
||||
================================================
|
||||
*/
|
||||
class idAchievementManager {
|
||||
public:
|
||||
idAchievementManager();
|
||||
|
||||
void Init( idPlayer * player );
|
||||
bool IsInitialized() const { return owner != NULL; }
|
||||
|
||||
// save games
|
||||
void Save( idSaveGame * savefile ) const; // archives object for save game file
|
||||
void Restore( idRestoreGame * savefile ); // unarchives object from save game file
|
||||
|
||||
// Debug tool to reset achievement state and counts
|
||||
void Reset();
|
||||
int GetCount( const achievement_t eventId ) const { return counts[eventId]; }
|
||||
|
||||
// Adds a count to the tracked number of events, these events can be applied to multiple achievements
|
||||
void EventCompletesAchievement( const achievement_t eventId );
|
||||
|
||||
int GetLastImpKilledTime() { return lastImpKilledTime; }
|
||||
void SetLastImpKilledTime( int time) { lastImpKilledTime = time; }
|
||||
int GetLastPlayerKilledTime() { return lastPlayerKilledTime; }
|
||||
void SetLastPlayerKilledTime( int time ) { lastPlayerKilledTime = time; }
|
||||
bool GetPlayerTookDamage() { return playerTookDamage; }
|
||||
void SetPlayerTookDamage( bool bl ) { playerTookDamage = bl; }
|
||||
void IncrementHellTimeKills();
|
||||
void ResetHellTimeKills() { currentHellTimeKills = 0; }
|
||||
void SavePersistentData( idDict & playerInfo );
|
||||
void RestorePersistentData( const idDict & spawnArgs );
|
||||
|
||||
static void LocalUser_CompleteAchievement( achievement_t id );
|
||||
static void CheckDoomClassicsAchievements( int killcount, int itemcount, int secretcount, int skill, int mission, int map, int episode, int totalkills, int totalitems, int totalsecret );
|
||||
|
||||
private:
|
||||
idEntityPtr< idPlayer > owner;
|
||||
idArray<int, ACHIEVEMENTS_NUM> counts; // How many times has each achievement been given
|
||||
|
||||
int lastPlayerKilledTime;
|
||||
int lastImpKilledTime;
|
||||
bool playerTookDamage;
|
||||
int currentHellTimeKills;
|
||||
|
||||
static bool cheatingDialogShown;
|
||||
|
||||
idLocalUser * GetLocalUser();
|
||||
void SyncAchievments();
|
||||
};
|
||||
|
||||
#endif // !__ACHIEVEMENTS_H__
|
||||
3474
neo/d3xp/Actor.cpp
Normal file
3474
neo/d3xp/Actor.cpp
Normal file
File diff suppressed because it is too large
Load Diff
333
neo/d3xp/Actor.h
Normal file
333
neo/d3xp/Actor.h
Normal file
@@ -0,0 +1,333 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_ACTOR_H__
|
||||
#define __GAME_ACTOR_H__
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idActor
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
extern const idEventDef AI_EnableEyeFocus;
|
||||
extern const idEventDef AI_DisableEyeFocus;
|
||||
extern const idEventDef EV_Footstep;
|
||||
extern const idEventDef EV_FootstepLeft;
|
||||
extern const idEventDef EV_FootstepRight;
|
||||
extern const idEventDef EV_EnableWalkIK;
|
||||
extern const idEventDef EV_DisableWalkIK;
|
||||
extern const idEventDef EV_EnableLegIK;
|
||||
extern const idEventDef EV_DisableLegIK;
|
||||
extern const idEventDef AI_SetAnimPrefix;
|
||||
extern const idEventDef AI_PlayAnim;
|
||||
extern const idEventDef AI_PlayCycle;
|
||||
extern const idEventDef AI_AnimDone;
|
||||
extern const idEventDef AI_SetBlendFrames;
|
||||
extern const idEventDef AI_GetBlendFrames;
|
||||
|
||||
extern const idEventDef AI_SetState;
|
||||
|
||||
class idDeclParticle;
|
||||
|
||||
class idAnimState {
|
||||
public:
|
||||
bool idleAnim;
|
||||
idStr state;
|
||||
int animBlendFrames;
|
||||
int lastAnimBlendFrames; // allows override anims to blend based on the last transition time
|
||||
|
||||
public:
|
||||
idAnimState();
|
||||
~idAnimState();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Init( idActor *owner, idAnimator *_animator, int animchannel );
|
||||
void Shutdown();
|
||||
void SetState( const char *name, int blendFrames );
|
||||
void StopAnim( int frames );
|
||||
void PlayAnim( int anim );
|
||||
void CycleAnim( int anim );
|
||||
void BecomeIdle();
|
||||
bool UpdateState();
|
||||
bool Disabled() const;
|
||||
void Enable( int blendFrames );
|
||||
void Disable();
|
||||
bool AnimDone( int blendFrames ) const;
|
||||
bool IsIdle() const;
|
||||
animFlags_t GetAnimFlags() const;
|
||||
|
||||
private:
|
||||
idActor * self;
|
||||
idAnimator * animator;
|
||||
idThread * thread;
|
||||
int channel;
|
||||
bool disabled;
|
||||
};
|
||||
|
||||
class idAttachInfo {
|
||||
public:
|
||||
idEntityPtr<idEntity> ent;
|
||||
int channel;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
jointModTransform_t mod;
|
||||
jointHandle_t from;
|
||||
jointHandle_t to;
|
||||
} copyJoints_t;
|
||||
|
||||
class idActor : public idAFEntity_Gibbable {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idActor );
|
||||
|
||||
int team;
|
||||
int rank; // monsters don't fight back if the attacker's rank is higher
|
||||
idMat3 viewAxis; // view axis of the actor
|
||||
|
||||
idLinkList<idActor> enemyNode; // node linked into an entity's enemy list for quick lookups of who is attacking him
|
||||
idLinkList<idActor> enemyList; // list of characters that have targeted the player as their enemy
|
||||
|
||||
public:
|
||||
idActor();
|
||||
virtual ~idActor();
|
||||
|
||||
void Spawn();
|
||||
virtual void Restart();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void Hide();
|
||||
virtual void Show();
|
||||
virtual int GetDefaultSurfaceType() const;
|
||||
virtual void ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material );
|
||||
|
||||
virtual bool LoadAF();
|
||||
void SetupBody();
|
||||
|
||||
void CheckBlink();
|
||||
|
||||
virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis );
|
||||
virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis );
|
||||
|
||||
// script state management
|
||||
void ShutdownThreads();
|
||||
virtual bool ShouldConstructScriptObjectAtSpawn() const;
|
||||
virtual idThread * ConstructScriptObject();
|
||||
void UpdateScript();
|
||||
const function_t *GetScriptFunction( const char *funcname );
|
||||
void SetState( const function_t *newState );
|
||||
void SetState( const char *statename );
|
||||
|
||||
// vision testing
|
||||
void SetEyeHeight( float height );
|
||||
float EyeHeight() const;
|
||||
idVec3 EyeOffset() const;
|
||||
idVec3 GetEyePosition() const;
|
||||
virtual void GetViewPos( idVec3 &origin, idMat3 &axis ) const;
|
||||
void SetFOV( float fov );
|
||||
bool CheckFOV( const idVec3 &pos ) const;
|
||||
bool CanSee( idEntity *ent, bool useFOV ) const;
|
||||
bool PointVisible( const idVec3 &point ) const;
|
||||
virtual void GetAIAimTargets( const idVec3 &lastSightPos, idVec3 &headPos, idVec3 &chestPos );
|
||||
|
||||
// damage
|
||||
void SetupDamageGroups();
|
||||
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
|
||||
int GetDamageForLocation( int damage, int location );
|
||||
const char * GetDamageGroup( int location );
|
||||
void ClearPain();
|
||||
virtual bool Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
|
||||
|
||||
// model/combat model/ragdoll
|
||||
void SetCombatModel();
|
||||
idClipModel * GetCombatModel() const;
|
||||
virtual void LinkCombat();
|
||||
virtual void UnlinkCombat();
|
||||
bool StartRagdoll();
|
||||
void StopRagdoll();
|
||||
virtual bool UpdateAnimationControllers();
|
||||
|
||||
// delta view angles to allow movers to rotate the view of the actor
|
||||
const idAngles & GetDeltaViewAngles() const;
|
||||
void SetDeltaViewAngles( const idAngles &delta );
|
||||
|
||||
bool HasEnemies() const;
|
||||
idActor * ClosestEnemyToPoint( const idVec3 &pos );
|
||||
idActor * EnemyWithMostHealth();
|
||||
|
||||
virtual bool OnLadder() const;
|
||||
|
||||
virtual void GetAASLocation( idAAS *aas, idVec3 &pos, int &areaNum ) const;
|
||||
|
||||
void Attach( idEntity *ent );
|
||||
|
||||
virtual void Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination );
|
||||
|
||||
virtual renderView_t * GetRenderView();
|
||||
|
||||
// animation state control
|
||||
int GetAnim( int channel, const char *name );
|
||||
void UpdateAnimState();
|
||||
void SetAnimState( int channel, const char *name, int blendFrames );
|
||||
const char * GetAnimState( int channel ) const;
|
||||
bool InAnimState( int channel, const char *name ) const;
|
||||
const char * WaitState() const;
|
||||
void SetWaitState( const char *_waitstate );
|
||||
bool AnimDone( int channel, int blendFrames ) const;
|
||||
virtual void SpawnGibs( const idVec3 &dir, const char *damageDefName );
|
||||
|
||||
idEntity* GetHeadEntity() { return head.GetEntity(); };
|
||||
|
||||
protected:
|
||||
friend class idAnimState;
|
||||
|
||||
float fovDot; // cos( fovDegrees )
|
||||
idVec3 eyeOffset; // offset of eye relative to physics origin
|
||||
idVec3 modelOffset; // offset of visual model relative to the physics origin
|
||||
|
||||
idAngles deltaViewAngles; // delta angles relative to view input angles
|
||||
|
||||
int pain_debounce_time; // next time the actor can show pain
|
||||
int pain_delay; // time between playing pain sound
|
||||
int pain_threshold; // how much damage monster can take at any one time before playing pain animation
|
||||
|
||||
idStrList damageGroups; // body damage groups
|
||||
idList<float, TAG_ACTOR> damageScale; // damage scale per damage gruop
|
||||
|
||||
bool use_combat_bbox; // whether to use the bounding box for combat collision
|
||||
idEntityPtr<idAFAttachment> head;
|
||||
idList<copyJoints_t, TAG_ACTOR> copyJoints; // copied from the body animation to the head model
|
||||
|
||||
// state variables
|
||||
const function_t *state;
|
||||
const function_t *idealState;
|
||||
|
||||
// joint handles
|
||||
jointHandle_t leftEyeJoint;
|
||||
jointHandle_t rightEyeJoint;
|
||||
jointHandle_t soundJoint;
|
||||
|
||||
idIK_Walk walkIK;
|
||||
|
||||
idStr animPrefix;
|
||||
idStr painAnim;
|
||||
|
||||
// blinking
|
||||
int blink_anim;
|
||||
int blink_time;
|
||||
int blink_min;
|
||||
int blink_max;
|
||||
|
||||
// script variables
|
||||
idThread * scriptThread;
|
||||
idStr waitState;
|
||||
idAnimState headAnim;
|
||||
idAnimState torsoAnim;
|
||||
idAnimState legsAnim;
|
||||
|
||||
bool allowPain;
|
||||
bool allowEyeFocus;
|
||||
bool finalBoss;
|
||||
|
||||
int painTime;
|
||||
bool damageNotByFists;
|
||||
|
||||
idList<idAttachInfo, TAG_ACTOR> attachments;
|
||||
|
||||
int damageCap;
|
||||
|
||||
virtual void Gib( const idVec3 &dir, const char *damageDefName );
|
||||
|
||||
// removes attachments with "remove" set for when character dies
|
||||
void RemoveAttachments();
|
||||
|
||||
// copies animation from body to head joints
|
||||
void CopyJointsFromBodyToHead();
|
||||
|
||||
private:
|
||||
void SyncAnimChannels( int channel, int syncToChannel, int blendFrames );
|
||||
void FinishSetup();
|
||||
void SetupHead();
|
||||
void PlayFootStepSound();
|
||||
|
||||
void Event_EnableEyeFocus();
|
||||
void Event_DisableEyeFocus();
|
||||
void Event_Footstep();
|
||||
void Event_EnableWalkIK();
|
||||
void Event_DisableWalkIK();
|
||||
void Event_EnableLegIK( int num );
|
||||
void Event_DisableLegIK( int num );
|
||||
void Event_SetAnimPrefix( const char *name );
|
||||
void Event_LookAtEntity( idEntity *ent, float duration );
|
||||
void Event_PreventPain( float duration );
|
||||
void Event_DisablePain();
|
||||
void Event_EnablePain();
|
||||
void Event_GetPainAnim();
|
||||
void Event_StopAnim( int channel, int frames );
|
||||
void Event_PlayAnim( int channel, const char *name );
|
||||
void Event_PlayCycle( int channel, const char *name );
|
||||
void Event_IdleAnim( int channel, const char *name );
|
||||
void Event_SetSyncedAnimWeight( int channel, int anim, float weight );
|
||||
void Event_OverrideAnim( int channel );
|
||||
void Event_EnableAnim( int channel, int blendFrames );
|
||||
void Event_SetBlendFrames( int channel, int blendFrames );
|
||||
void Event_GetBlendFrames( int channel );
|
||||
void Event_AnimState( int channel, const char *name, int blendFrames );
|
||||
void Event_GetAnimState( int channel );
|
||||
void Event_InAnimState( int channel, const char *name );
|
||||
void Event_FinishAction( const char *name );
|
||||
void Event_AnimDone( int channel, int blendFrames );
|
||||
void Event_HasAnim( int channel, const char *name );
|
||||
void Event_CheckAnim( int channel, const char *animname );
|
||||
void Event_ChooseAnim( int channel, const char *animname );
|
||||
void Event_AnimLength( int channel, const char *animname );
|
||||
void Event_AnimDistance( int channel, const char *animname );
|
||||
void Event_HasEnemies();
|
||||
void Event_NextEnemy( idEntity *ent );
|
||||
void Event_ClosestEnemyToPoint( const idVec3 &pos );
|
||||
void Event_StopSound( int channel, int netsync );
|
||||
void Event_SetNextState( const char *name );
|
||||
void Event_SetState( const char *name );
|
||||
void Event_GetState();
|
||||
void Event_GetHead();
|
||||
void Event_SetDamageGroupScale( const char* groupName, float scale);
|
||||
void Event_SetDamageGroupScaleAll( float scale );
|
||||
void Event_GetDamageGroupScale( const char* groupName );
|
||||
void Event_SetDamageCap( float _damageCap );
|
||||
void Event_SetWaitState( const char* waitState);
|
||||
void Event_GetWaitState();
|
||||
|
||||
};
|
||||
|
||||
#endif /* !__GAME_ACTOR_H__ */
|
||||
436
neo/d3xp/AimAssist.cpp
Normal file
436
neo/d3xp/AimAssist.cpp
Normal file
@@ -0,0 +1,436 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../idlib/precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Game_local.h"
|
||||
|
||||
/*
|
||||
================================================================================================
|
||||
Contains the AimAssist implementation.
|
||||
================================================================================================
|
||||
*/
|
||||
|
||||
idCVar aa_targetAimAssistEnable ( "aa_targetAimAssistEnable", "0", CVAR_BOOL | CVAR_ARCHIVE, "Enables/Disables the entire Aim Assist system" );
|
||||
|
||||
idCVar aa_targetAdhesionEnable ( "aa_targetAdhesionEnable", "1", CVAR_BOOL, "Enables Target Adhesion" );
|
||||
idCVar aa_targetFrictionEnable ( "aa_targetFrictionEnable", "1", CVAR_BOOL, "Enables Target Friction" );
|
||||
|
||||
// Selection
|
||||
idCVar aa_targetMaxDistance ( "aa_targetMaxDistance", "3000", CVAR_FLOAT, "The Maximum Distance away for a target to be considered for adhesion, friction and target lock-to" );
|
||||
idCVar aa_targetSelectionRadius ( "aa_targetSelectionRadius", "128.0", CVAR_FLOAT, "Radius used to select targets for auto aiming" );
|
||||
|
||||
// Adhesion
|
||||
idCVar aa_targetAdhesionRadius ( "aa_targetAdhesionRadius", "96.0", CVAR_FLOAT, "Radius used to apply adhesion amount" );
|
||||
idCVar aa_targetAdhesionYawSpeedMax ( "aa_targetAdhesionYawSpeedMax", "0.6", CVAR_FLOAT, "Max Yaw Adhesion Speed" );
|
||||
idCVar aa_targetAdhesionPitchSpeedMax ( "aa_targetAdhesionPitchSpeedMax", "0.6", CVAR_FLOAT, "Max Pitch Adhesion Speed" );
|
||||
idCVar aa_targetAdhesionContributionPctMax ( "aa_targetAdhesionContributionPctMax", "0.25", CVAR_FLOAT, "Max Adhesion Contribution Percentage - Range 0.0 - 1.0" );
|
||||
idCVar aa_targetAdhesionPlayerSpeedThreshold ( "aa_targetAdhesionPlayerSpeedThreshold", "10.0", CVAR_FLOAT, "Speed Threshold that determines how fast the player needs to move before adhesion is allowed to kick in" );
|
||||
|
||||
// Friction
|
||||
idCVar aa_targetFrictionMaxDistance ( "aa_targetFrictionMaxDistance", "1024.0", CVAR_FLOAT, "Minimum Distance Friction takes effect" );
|
||||
idCVar aa_targetFrictionOptimalDistance ( "aa_targetFrictionOptimalDistance", "768.0", CVAR_FLOAT, "Optimal Distance for Friction to take an effect" );
|
||||
idCVar aa_targetFrictionRadius ( "aa_targetFrictionRadius", "96.0", CVAR_FLOAT, "Friction Collision Sphere Radius" );
|
||||
idCVar aa_targetFrictionOptimalRadius ( "aa_targetFrictionOptimalRadius", "192.0", CVAR_FLOAT, "Friction Collision Sphere Radius when at Optimal Distance" );
|
||||
idCVar aa_targetFrictionMultiplierMin ( "aa_targetFrictionMultiplierMin", "1.0", CVAR_FLOAT, "Minimum Friction Scalar" );
|
||||
idCVar aa_targetFrictionMultiplierMax ( "aa_targetFrictionMultiplierMax", "0.4", CVAR_FLOAT, "Maximum Friction Scalar" );
|
||||
|
||||
/*
|
||||
========================
|
||||
idAimAssist::Init
|
||||
========================
|
||||
*/
|
||||
void idAimAssist::Init( idPlayer *player_ ) {
|
||||
player = player_;
|
||||
angleCorrection = ang_zero;
|
||||
frictionScalar = 1.0f;
|
||||
lastTargetPos = vec3_zero;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idAimAssist::Update
|
||||
========================
|
||||
*/
|
||||
void idAimAssist::Update() {
|
||||
angleCorrection = ang_zero;
|
||||
|
||||
UpdateNewAimAssist();
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idAimAssist::UpdateNewAimAssist
|
||||
========================
|
||||
*/
|
||||
void idAimAssist::UpdateNewAimAssist() {
|
||||
|
||||
angleCorrection = ang_zero;
|
||||
frictionScalar = 1.0f;
|
||||
idEntity* lastTarget = targetEntity;
|
||||
targetEntity = NULL;
|
||||
|
||||
// is aim assisting allowed? If not then just bail out
|
||||
if ( !aa_targetAimAssistEnable.GetBool() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool forceLastTarget = false;
|
||||
idVec3 targetPos;
|
||||
|
||||
idEntity * entity = NULL;
|
||||
if ( forceLastTarget ) {
|
||||
entity = lastTarget;
|
||||
targetPos = lastTargetPos;
|
||||
} else {
|
||||
entity = FindAimAssistTarget( targetPos );
|
||||
}
|
||||
|
||||
if ( entity != NULL ) {
|
||||
|
||||
UpdateFriction( entity, targetPos );
|
||||
|
||||
// by default we don't allow adhesion when we are standing still
|
||||
const float playerMovementSpeedThreshold = Square( aa_targetAdhesionPlayerSpeedThreshold.GetFloat() );
|
||||
float playerSpeed = player->GetPhysics()->GetLinearVelocity().LengthSqr();
|
||||
|
||||
// only allow adhesion on actors (ai) or players. Disallow adhesion on any static world entities such as explosive barrels
|
||||
if ( playerSpeed > playerMovementSpeedThreshold ) {
|
||||
UpdateAdhesion( entity, targetPos );
|
||||
}
|
||||
|
||||
targetEntity = entity;
|
||||
}
|
||||
|
||||
lastTargetPos = targetPos;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idAimAssist::FindAimAssistTarget
|
||||
========================
|
||||
*/
|
||||
idEntity* idAimAssist::FindAimAssistTarget( idVec3& targetPos ) {
|
||||
if ( player == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//TO DO: Make this faster
|
||||
//TO DO: Defer Traces
|
||||
idEntity * optimalTarget = NULL;
|
||||
float currentBestScore = -idMath::INFINITY;
|
||||
targetPos = vec3_zero;
|
||||
|
||||
idVec3 cameraPos;
|
||||
idMat3 cameraAxis;
|
||||
player->GetViewPos( cameraPos, cameraAxis );
|
||||
|
||||
float maxDistanceSquared = Square( aa_targetMaxDistance.GetFloat() );
|
||||
|
||||
idVec3 dirToTarget;
|
||||
float distanceToTargetSquared;
|
||||
idVec3 primaryTargetPos;
|
||||
idVec3 secondaryTargetPos;
|
||||
|
||||
for ( idEntity * entity = gameLocal.aimAssistEntities.Next(); entity != NULL; entity = entity->aimAssistNode.Next() ) {
|
||||
if ( !entity->IsActive() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( entity->IsHidden() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( entity->IsType( idActor::Type ) ) {
|
||||
idActor * actor = static_cast<idActor *>( entity );
|
||||
if ( actor->team == player->team ) {
|
||||
// In DM, LMS, and Tourney, all players are on the same team
|
||||
if ( gameLocal.gameType == GAME_CTF || gameLocal.gameType == GAME_TDM || gameLocal.gameType == GAME_SP ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( entity->IsType( idAI::Type ) ) {
|
||||
idAI * aiEntity = static_cast<idAI *>( entity );
|
||||
if ( aiEntity->ReactionTo( player ) == ATTACK_IGNORE ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// check whether we have a valid target position for this entity - skip it if we don't
|
||||
if ( !ComputeTargetPos( entity, primaryTargetPos, secondaryTargetPos ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// is it close enough to us
|
||||
dirToTarget = primaryTargetPos-cameraPos;
|
||||
distanceToTargetSquared = dirToTarget.LengthSqr();
|
||||
if ( distanceToTargetSquared > maxDistanceSquared ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Compute a score in the range of 0..1 for how much are looking towards the target.
|
||||
idVec3 forward = cameraAxis[ 0 ];
|
||||
forward.Normalize();
|
||||
dirToTarget.Normalize();
|
||||
float ViewDirDotTargetDir = idMath::ClampFloat( -1.0f, 1.0f, forward * dirToTarget ); // compute the dot and clamp to account for floating point error
|
||||
|
||||
// throw out anything thats outside of weapon's global FOV.
|
||||
if ( ViewDirDotTargetDir < 0.0f ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// to be consistent we always use the primaryTargetPos to compute the score for this entity
|
||||
float computedScore = ComputeEntityAimAssistScore( primaryTargetPos, cameraPos, cameraAxis );
|
||||
|
||||
// check if the current score beats our current best score and we have line of sight to it.
|
||||
if ( computedScore > currentBestScore ) {
|
||||
|
||||
// determine if the current target is in our line of sight
|
||||
trace_t tr;
|
||||
gameLocal.clip.TracePoint( tr, cameraPos, primaryTargetPos, MASK_MONSTERSOLID, player );
|
||||
|
||||
// did our trace fail?
|
||||
if ( ( ( tr.fraction < 1.0f ) && ( tr.c.entityNum != entity->entityNumber ) ) || ( tr.fraction >= 1.0f ) ) {
|
||||
|
||||
// if the collision test failed for the primary position -- check the secondary position
|
||||
trace_t tr2;
|
||||
gameLocal.clip.TracePoint( tr2, cameraPos, secondaryTargetPos, MASK_MONSTERSOLID, player );
|
||||
|
||||
if ( ( ( tr2.fraction < 1.0f ) && ( tr2.c.entityNum != entity->entityNumber ) ) || ( tr2.fraction >= 1.0f ) ) {
|
||||
// if the secondary position is also not visible then give up
|
||||
continue;
|
||||
}
|
||||
|
||||
// we can see the secondary target position so we should consider this entity but use
|
||||
// the secondary position as the target position
|
||||
targetPos = secondaryTargetPos;
|
||||
} else {
|
||||
targetPos = primaryTargetPos;
|
||||
}
|
||||
|
||||
// if we got here then this is our new best score
|
||||
optimalTarget = entity;
|
||||
currentBestScore = computedScore;
|
||||
}
|
||||
}
|
||||
|
||||
return optimalTarget;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idAimAssist::ComputeEntityAimAssistScore
|
||||
========================
|
||||
*/
|
||||
float idAimAssist::ComputeEntityAimAssistScore( const idVec3& targetPos, const idVec3& cameraPos, const idMat3& cameraAxis ) {
|
||||
|
||||
float score = 0.0f;
|
||||
|
||||
idVec3 dirToTarget = targetPos - cameraPos;
|
||||
float distanceToTarget = dirToTarget.Length();
|
||||
|
||||
// Compute a score in the range of 0..1 for how much are looking towards the target.
|
||||
idVec3 forward = cameraAxis[0];
|
||||
forward.Normalize();
|
||||
dirToTarget.Normalize();
|
||||
float ViewDirDotTargetDir = idMath::ClampFloat( 0.0f, 1.0f, forward * dirToTarget ); // compute the dot and clamp to account for floating point error
|
||||
|
||||
// the more we look at the target the higher our score
|
||||
score = ViewDirDotTargetDir;
|
||||
|
||||
// weigh the score from the view angle higher than the distance score
|
||||
static float aimWeight = 0.8f;
|
||||
score *= aimWeight;
|
||||
// Add a score of 0..1 for how close the target is to the player
|
||||
if ( distanceToTarget < aa_targetMaxDistance.GetFloat() ) {
|
||||
float distanceScore = 1.0f - ( distanceToTarget / aa_targetMaxDistance.GetFloat() );
|
||||
float distanceWeight = 1.0f - aimWeight;
|
||||
score += ( distanceScore * distanceWeight );
|
||||
}
|
||||
|
||||
return score * 1000.0f;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idAimAssist::UpdateAdhesion
|
||||
========================
|
||||
*/
|
||||
void idAimAssist::UpdateAdhesion( idEntity* pTarget, const idVec3& targetPos ) {
|
||||
|
||||
if ( !aa_targetAdhesionEnable.GetBool() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !pTarget ) {
|
||||
return;
|
||||
}
|
||||
|
||||
float contributionPctMax = aa_targetAdhesionContributionPctMax.GetFloat();
|
||||
|
||||
idVec3 cameraPos;
|
||||
idMat3 cameraAxis;
|
||||
player->GetViewPos(cameraPos, cameraAxis);
|
||||
|
||||
idAngles cameraViewAngles = cameraAxis.ToAngles();
|
||||
cameraViewAngles.Normalize180();
|
||||
|
||||
idVec3 cameraViewPos = cameraPos;
|
||||
idVec3 dirToTarget = targetPos - cameraViewPos;
|
||||
float distanceToTarget = dirToTarget.Length();
|
||||
|
||||
idAngles aimAngles = dirToTarget.ToAngles();
|
||||
aimAngles.Normalize180();
|
||||
|
||||
// find the delta
|
||||
aimAngles -= cameraViewAngles;
|
||||
|
||||
// clamp velocities to some max values
|
||||
aimAngles.yaw = idMath::ClampFloat( -aa_targetAdhesionYawSpeedMax.GetFloat(), aa_targetAdhesionYawSpeedMax.GetFloat(), aimAngles.yaw );
|
||||
aimAngles.pitch = idMath::ClampFloat( -aa_targetAdhesionPitchSpeedMax.GetFloat(), aa_targetAdhesionPitchSpeedMax.GetFloat(), aimAngles.pitch );
|
||||
|
||||
idVec3 forward = cameraAxis[0];
|
||||
forward.Normalize();
|
||||
dirToTarget.Normalize();
|
||||
float ViewDirDotTargetDir = idMath::ClampFloat( 0.0f, 1.0f, forward * dirToTarget ); // compute the dot and clamp to account for floating point error
|
||||
float aimLength = ViewDirDotTargetDir * distanceToTarget;
|
||||
idVec3 aimPoint = cameraPos + ( forward * aimLength );
|
||||
float delta = idMath::Sqrt( Square( distanceToTarget ) - Square( aimLength ) );
|
||||
|
||||
float contribution = idMath::ClampFloat( 0.0f, contributionPctMax, 1.0f - ( delta / aa_targetAdhesionRadius.GetFloat() ) );
|
||||
angleCorrection.yaw = aimAngles.yaw * contribution;
|
||||
angleCorrection.pitch = aimAngles.pitch * contribution;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idAimAssist::ComputeFrictionRadius
|
||||
========================
|
||||
*/
|
||||
float idAimAssist::ComputeFrictionRadius( float distanceToTarget ) {
|
||||
|
||||
if ( ( distanceToTarget <= idMath::FLT_SMALLEST_NON_DENORMAL ) || distanceToTarget > aa_targetFrictionMaxDistance.GetFloat() ) {
|
||||
return aa_targetFrictionRadius.GetFloat();
|
||||
}
|
||||
|
||||
float distanceContributionScalar = ( aa_targetFrictionOptimalDistance.GetFloat() > 0.0f ) ? ( distanceToTarget / aa_targetFrictionOptimalDistance.GetFloat() ) : 0.0f;
|
||||
|
||||
if ( distanceToTarget > aa_targetFrictionOptimalDistance.GetFloat() ) {
|
||||
const float range = idMath::ClampFloat( 0.0f, aa_targetFrictionMaxDistance.GetFloat(), aa_targetFrictionMaxDistance.GetFloat() - aa_targetFrictionOptimalDistance.GetFloat() );
|
||||
if ( range > idMath::FLT_SMALLEST_NON_DENORMAL ) {
|
||||
distanceContributionScalar = 1.0f - ( ( distanceToTarget - aa_targetFrictionOptimalDistance.GetFloat() ) / range );
|
||||
}
|
||||
}
|
||||
|
||||
return Lerp( aa_targetFrictionRadius.GetFloat(), aa_targetFrictionOptimalRadius.GetFloat(), distanceContributionScalar );
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idAimAssist::UpdateFriction
|
||||
========================
|
||||
*/
|
||||
void idAimAssist::UpdateFriction( idEntity* pTarget, const idVec3& targetPos ) {
|
||||
|
||||
if ( !aa_targetFrictionEnable.GetBool() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pTarget == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
idVec3 cameraPos;
|
||||
idMat3 cameraAxis;
|
||||
player->GetViewPos(cameraPos, cameraAxis);
|
||||
idVec3 dirToTarget = targetPos - cameraPos;
|
||||
float distanceToTarget = dirToTarget.Length();
|
||||
idVec3 forward = cameraAxis[0];
|
||||
forward.Normalize();
|
||||
dirToTarget.Normalize();
|
||||
float ViewDirDotTargetDir = idMath::ClampFloat( 0.0f, 1.0f, forward * dirToTarget ); // compute the dot and clamp to account for floating point error
|
||||
float aimLength = ViewDirDotTargetDir * distanceToTarget;
|
||||
idVec3 aimPoint = cameraPos + ( forward * aimLength );
|
||||
float delta = idMath::Sqrt( Square( distanceToTarget ) - Square( aimLength ) );
|
||||
|
||||
const float radius = ComputeFrictionRadius( distanceToTarget );
|
||||
if ( delta < radius ) {
|
||||
float alpha = 1.0f - ( delta / radius );
|
||||
frictionScalar = Lerp( aa_targetFrictionMultiplierMin.GetFloat(), aa_targetFrictionMultiplierMax.GetFloat(), alpha );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idAimAssist::ComputeTargetPos
|
||||
========================
|
||||
*/
|
||||
bool idAimAssist::ComputeTargetPos( idEntity* entity, idVec3& primaryTargetPos, idVec3& secondaryTargetPos ) {
|
||||
|
||||
primaryTargetPos = vec3_zero;
|
||||
secondaryTargetPos = vec3_zero;
|
||||
|
||||
if ( entity == NULL ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The target point on actors can now be either the head or the torso
|
||||
idActor * actor = NULL;
|
||||
if ( entity->IsType( idActor::Type ) ) {
|
||||
actor = ( idActor *) entity;
|
||||
}
|
||||
if ( actor != NULL ) {
|
||||
// Actor AimPoint
|
||||
|
||||
idVec3 torsoPos;
|
||||
idVec3 headPos = actor->GetEyePosition();
|
||||
|
||||
if ( actor->GetHeadEntity() != NULL ) {
|
||||
torsoPos = actor->GetHeadEntity()->GetPhysics()->GetOrigin();
|
||||
} else {
|
||||
const float offsetScale = 0.9f;
|
||||
torsoPos = actor->GetPhysics()->GetOrigin() + ( actor->EyeOffset() * offsetScale );
|
||||
}
|
||||
|
||||
primaryTargetPos = torsoPos;
|
||||
secondaryTargetPos = headPos;
|
||||
return true;
|
||||
|
||||
} else if ( entity->GetPhysics()->GetClipModel() != NULL ) {
|
||||
|
||||
const idBounds& box = entity->GetPhysics()->GetClipModel()->GetAbsBounds();
|
||||
primaryTargetPos = box.GetCenter();
|
||||
secondaryTargetPos = box.GetCenter();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
75
neo/d3xp/AimAssist.h
Normal file
75
neo/d3xp/AimAssist.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __AIMASSIST_H__
|
||||
#define __AIMASSIST_H__
|
||||
|
||||
/*
|
||||
================================================================================================
|
||||
Contains the AimAssist declaration.
|
||||
================================================================================================
|
||||
*/
|
||||
|
||||
class idEntity;
|
||||
class idPlayer;
|
||||
|
||||
/*
|
||||
================================================
|
||||
idAimAssist modifies the angle of Weapon firing to help the Player
|
||||
hit a Target.
|
||||
================================================
|
||||
*/
|
||||
class idAimAssist {
|
||||
public:
|
||||
|
||||
idAimAssist() : angleCorrection( ang_zero ), frictionScalar( 1.0f ), lastTargetPos( vec3_zero ), player( NULL ) {}
|
||||
|
||||
void Init( idPlayer * player );
|
||||
void Update();
|
||||
void GetAngleCorrection( idAngles & correction ) const { correction = angleCorrection; }
|
||||
float GetFrictionScalar () const { return frictionScalar; }
|
||||
|
||||
idEntity * GetLastTarget() { return targetEntity; }
|
||||
idEntity * FindAimAssistTarget( idVec3 & targetPos );
|
||||
|
||||
private:
|
||||
void UpdateNewAimAssist();
|
||||
float ComputeEntityAimAssistScore( const idVec3 & targetPos, const idVec3 & cameraPos, const idMat3 & cameraAxis );
|
||||
bool ComputeTargetPos( idEntity * pTarget, idVec3 & primaryTargetPos, idVec3 & secondaryTargetPos );
|
||||
float ComputeFrictionRadius( float distanceToTarget );
|
||||
void UpdateAdhesion( idEntity * pTarget, const idVec3 & targetPos);
|
||||
void UpdateFriction( idEntity * pTarget, const idVec3 & targetPos);
|
||||
|
||||
idPlayer * player; // player associated with this object
|
||||
idAngles angleCorrection; // the angle delta to apply for aim assistance
|
||||
float frictionScalar; // friction scalar
|
||||
idEntityPtr<idEntity> targetEntity; // the last target we had (updated every frame)
|
||||
idVec3 lastTargetPos; // the last target position ( updated every frame );
|
||||
};
|
||||
|
||||
#endif // !__AIMASSIST_H__
|
||||
1386
neo/d3xp/BrittleFracture.cpp
Normal file
1386
neo/d3xp/BrittleFracture.cpp
Normal file
File diff suppressed because it is too large
Load Diff
141
neo/d3xp/BrittleFracture.h
Normal file
141
neo/d3xp/BrittleFracture.h
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_BRITTLEFRACTURE_H__
|
||||
#define __GAME_BRITTLEFRACTURE_H__
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
B-rep Brittle Fracture - Static entity using the boundary representation
|
||||
of the render model which can fracture.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
typedef struct shard_s {
|
||||
idClipModel * clipModel;
|
||||
idFixedWinding winding;
|
||||
idList<idFixedWinding *, TAG_PHYSICS_BRITTLE> decals;
|
||||
idList<bool> edgeHasNeighbour;
|
||||
idList<struct shard_s *, TAG_PHYSICS_BRITTLE> neighbours;
|
||||
idPhysics_RigidBody physicsObj;
|
||||
int droppedTime;
|
||||
bool atEdge;
|
||||
int islandNum;
|
||||
} shard_t;
|
||||
|
||||
|
||||
class idBrittleFracture : public idEntity {
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( idBrittleFracture );
|
||||
|
||||
idBrittleFracture();
|
||||
virtual ~idBrittleFracture();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
|
||||
virtual void Present();
|
||||
virtual void Think();
|
||||
virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse );
|
||||
virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force );
|
||||
virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName );
|
||||
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
|
||||
|
||||
void ProjectDecal( const idVec3 &point, const idVec3 &dir, const int time, const char *damageDefName );
|
||||
bool IsBroken() const;
|
||||
|
||||
enum {
|
||||
EVENT_PROJECT_DECAL = idEntity::EVENT_MAXEVENTS,
|
||||
EVENT_SHATTER,
|
||||
EVENT_MAXEVENTS
|
||||
};
|
||||
|
||||
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
|
||||
virtual void ClientPredictionThink();
|
||||
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
|
||||
|
||||
private:
|
||||
// setttings
|
||||
const idMaterial * material;
|
||||
const idMaterial * decalMaterial;
|
||||
float decalSize;
|
||||
float maxShardArea;
|
||||
float maxShatterRadius;
|
||||
float minShatterRadius;
|
||||
float linearVelocityScale;
|
||||
float angularVelocityScale;
|
||||
float shardMass;
|
||||
float density;
|
||||
float friction;
|
||||
float bouncyness;
|
||||
idStr fxFracture;
|
||||
|
||||
struct fractureEvent_s {
|
||||
int eventType;
|
||||
idVec3 point;
|
||||
idVec3 vector;
|
||||
};
|
||||
idList<fractureEvent_s> storedEvents;
|
||||
bool processStoredEvents;
|
||||
idRenderModel * defaultRenderModel;
|
||||
bool isXraySurface;
|
||||
|
||||
// state
|
||||
idPhysics_StaticMulti physicsObj;
|
||||
idList<shard_t *, TAG_PHYSICS_BRITTLE> shards;
|
||||
idBounds bounds;
|
||||
bool disableFracture;
|
||||
|
||||
// for rendering
|
||||
mutable int lastRenderEntityUpdate;
|
||||
mutable bool changed;
|
||||
|
||||
bool UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ) const;
|
||||
static bool ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView );
|
||||
|
||||
void AddShard( idClipModel *clipModel, idFixedWinding &w );
|
||||
void RemoveShard( int index );
|
||||
void DropShard( shard_t *shard, const idVec3 &point, const idVec3 &dir, const float impulse, const int time );
|
||||
void Shatter( const idVec3 &point, const idVec3 &impulse, const int time );
|
||||
void DropFloatingIslands( const idVec3 &point, const idVec3 &impulse, const int time );
|
||||
void Break();
|
||||
void Fracture_r( idFixedWinding &w, idRandom2 & random );
|
||||
void CreateFractures( const idRenderModel *renderModel );
|
||||
void FindNeighbours();
|
||||
|
||||
void Event_Activate( idEntity *activator );
|
||||
void Event_Touch( idEntity *other, trace_t *trace );
|
||||
};
|
||||
|
||||
#endif /* !__GAME_BRITTLEFRACTURE_H__ */
|
||||
636
neo/d3xp/Camera.cpp
Normal file
636
neo/d3xp/Camera.cpp
Normal file
@@ -0,0 +1,636 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../idlib/precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Game_local.h"
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idCamera
|
||||
|
||||
Base class for cameras
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
ABSTRACT_DECLARATION( idEntity, idCamera )
|
||||
END_CLASS
|
||||
|
||||
/*
|
||||
=====================
|
||||
idCamera::Spawn
|
||||
=====================
|
||||
*/
|
||||
void idCamera::Spawn() {
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idCamera::GetRenderView
|
||||
=====================
|
||||
*/
|
||||
renderView_t *idCamera::GetRenderView() {
|
||||
renderView_t *rv = idEntity::GetRenderView();
|
||||
GetViewParms( rv );
|
||||
return rv;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
idCameraView
|
||||
|
||||
***********************************************************************/
|
||||
const idEventDef EV_Camera_SetAttachments( "<getattachments>", NULL );
|
||||
|
||||
CLASS_DECLARATION( idCamera, idCameraView )
|
||||
EVENT( EV_Activate, idCameraView::Event_Activate )
|
||||
EVENT( EV_Camera_SetAttachments, idCameraView::Event_SetAttachments )
|
||||
END_CLASS
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
idCameraView::idCameraView
|
||||
================
|
||||
*/
|
||||
idCameraView::idCameraView() {
|
||||
fov = 90.0f;
|
||||
attachedTo = NULL;
|
||||
attachedView = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idCameraView::Save
|
||||
================
|
||||
*/
|
||||
void idCameraView::Save( idSaveGame *savefile ) const {
|
||||
savefile->WriteFloat( fov );
|
||||
savefile->WriteObject( attachedTo );
|
||||
savefile->WriteObject( attachedView );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idCameraView::Restore
|
||||
================
|
||||
*/
|
||||
void idCameraView::Restore( idRestoreGame *savefile ) {
|
||||
savefile->ReadFloat( fov );
|
||||
savefile->ReadObject( reinterpret_cast<idClass *&>( attachedTo ) );
|
||||
savefile->ReadObject( reinterpret_cast<idClass *&>( attachedView ) );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idCameraView::Event_SetAttachments
|
||||
================
|
||||
*/
|
||||
void idCameraView::Event_SetAttachments( ) {
|
||||
SetAttachment( &attachedTo, "attachedTo" );
|
||||
SetAttachment( &attachedView, "attachedView" );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idCameraView::Event_Activate
|
||||
================
|
||||
*/
|
||||
void idCameraView::Event_Activate( idEntity *activator ) {
|
||||
if (spawnArgs.GetBool("trigger")) {
|
||||
if (gameLocal.GetCamera() != this) {
|
||||
if ( g_debugCinematic.GetBool() ) {
|
||||
gameLocal.Printf( "%d: '%s' start\n", gameLocal.framenum, GetName() );
|
||||
}
|
||||
|
||||
gameLocal.SetCamera(this);
|
||||
} else {
|
||||
if ( g_debugCinematic.GetBool() ) {
|
||||
gameLocal.Printf( "%d: '%s' stop\n", gameLocal.framenum, GetName() );
|
||||
}
|
||||
gameLocal.SetCamera(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idCameraView::Stop
|
||||
=====================
|
||||
*/
|
||||
void idCameraView::Stop() {
|
||||
if ( g_debugCinematic.GetBool() ) {
|
||||
gameLocal.Printf( "%d: '%s' stop\n", gameLocal.framenum, GetName() );
|
||||
}
|
||||
gameLocal.SetCamera(NULL);
|
||||
ActivateTargets( gameLocal.GetLocalPlayer() );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
idCameraView::Spawn
|
||||
=====================
|
||||
*/
|
||||
void idCameraView::SetAttachment( idEntity **e, const char *p ) {
|
||||
const char *cam = spawnArgs.GetString( p );
|
||||
if ( strlen ( cam ) ) {
|
||||
*e = gameLocal.FindEntity( cam );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
idCameraView::Spawn
|
||||
=====================
|
||||
*/
|
||||
void idCameraView::Spawn() {
|
||||
// if no target specified use ourself
|
||||
const char *cam = spawnArgs.GetString("cameraTarget");
|
||||
if ( strlen ( cam ) == 0) {
|
||||
spawnArgs.Set("cameraTarget", spawnArgs.GetString("name"));
|
||||
}
|
||||
fov = spawnArgs.GetFloat("fov", "90");
|
||||
|
||||
PostEventMS( &EV_Camera_SetAttachments, 0 );
|
||||
|
||||
UpdateChangeableSpawnArgs(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idCameraView::GetViewParms
|
||||
=====================
|
||||
*/
|
||||
void idCameraView::GetViewParms( renderView_t *view ) {
|
||||
assert( view );
|
||||
|
||||
if (view == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
idVec3 dir;
|
||||
idEntity *ent;
|
||||
|
||||
if ( attachedTo ) {
|
||||
ent = attachedTo;
|
||||
} else {
|
||||
ent = this;
|
||||
}
|
||||
|
||||
view->vieworg = ent->GetPhysics()->GetOrigin();
|
||||
if ( attachedView ) {
|
||||
dir = attachedView->GetPhysics()->GetOrigin() - view->vieworg;
|
||||
dir.Normalize();
|
||||
view->viewaxis = dir.ToMat3();
|
||||
} else {
|
||||
view->viewaxis = ent->GetPhysics()->GetAxis();
|
||||
}
|
||||
|
||||
gameLocal.CalcFov( fov, view->fov_x, view->fov_y );
|
||||
}
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idCameraAnim
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
const idEventDef EV_Camera_Start( "start", NULL );
|
||||
const idEventDef EV_Camera_Stop( "stop", NULL );
|
||||
|
||||
CLASS_DECLARATION( idCamera, idCameraAnim )
|
||||
EVENT( EV_Thread_SetCallback, idCameraAnim::Event_SetCallback )
|
||||
EVENT( EV_Camera_Stop, idCameraAnim::Event_Stop )
|
||||
EVENT( EV_Camera_Start, idCameraAnim::Event_Start )
|
||||
EVENT( EV_Activate, idCameraAnim::Event_Activate )
|
||||
END_CLASS
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
idCameraAnim::idCameraAnim
|
||||
=====================
|
||||
*/
|
||||
idCameraAnim::idCameraAnim() {
|
||||
threadNum = 0;
|
||||
offset.Zero();
|
||||
frameRate = 0;
|
||||
cycle = 1;
|
||||
starttime = 0;
|
||||
activator = NULL;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idCameraAnim::~idCameraAnim
|
||||
=====================
|
||||
*/
|
||||
idCameraAnim::~idCameraAnim() {
|
||||
if ( gameLocal.GetCamera() == this ) {
|
||||
gameLocal.SetCamera( NULL );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idCameraAnim::Save
|
||||
================
|
||||
*/
|
||||
void idCameraAnim::Save( idSaveGame *savefile ) const {
|
||||
savefile->WriteInt( threadNum );
|
||||
savefile->WriteVec3( offset );
|
||||
savefile->WriteInt( frameRate );
|
||||
savefile->WriteInt( starttime );
|
||||
savefile->WriteInt( cycle );
|
||||
activator.Save( savefile );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idCameraAnim::Restore
|
||||
================
|
||||
*/
|
||||
void idCameraAnim::Restore( idRestoreGame *savefile ) {
|
||||
savefile->ReadInt( threadNum );
|
||||
savefile->ReadVec3( offset );
|
||||
savefile->ReadInt( frameRate );
|
||||
savefile->ReadInt( starttime );
|
||||
savefile->ReadInt( cycle );
|
||||
activator.Restore( savefile );
|
||||
|
||||
LoadAnim();
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idCameraAnim::Spawn
|
||||
=====================
|
||||
*/
|
||||
void idCameraAnim::Spawn() {
|
||||
if ( spawnArgs.GetVector( "old_origin", "0 0 0", offset ) ) {
|
||||
offset = GetPhysics()->GetOrigin() - offset;
|
||||
} else {
|
||||
offset.Zero();
|
||||
}
|
||||
|
||||
// always think during cinematics
|
||||
cinematic = true;
|
||||
|
||||
LoadAnim();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idCameraAnim::Load
|
||||
================
|
||||
*/
|
||||
void idCameraAnim::LoadAnim() {
|
||||
int version;
|
||||
idLexer parser( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS | LEXFL_NOSTRINGCONCAT );
|
||||
idToken token;
|
||||
int numFrames;
|
||||
int numCuts;
|
||||
int i;
|
||||
idStr filename;
|
||||
const char *key;
|
||||
|
||||
key = spawnArgs.GetString( "anim" );
|
||||
if ( !key ) {
|
||||
gameLocal.Error( "Missing 'anim' key on '%s'", name.c_str() );
|
||||
}
|
||||
|
||||
filename = spawnArgs.GetString( va( "anim %s", key ) );
|
||||
if ( !filename.Length() ) {
|
||||
gameLocal.Error( "Missing 'anim %s' key on '%s'", key, name.c_str() );
|
||||
}
|
||||
|
||||
filename.SetFileExtension( MD5_CAMERA_EXT );
|
||||
if ( !parser.LoadFile( filename ) ) {
|
||||
gameLocal.Error( "Unable to load '%s' on '%s'", filename.c_str(), name.c_str() );
|
||||
}
|
||||
|
||||
cameraCuts.Clear();
|
||||
cameraCuts.SetGranularity( 1 );
|
||||
camera.Clear();
|
||||
camera.SetGranularity( 1 );
|
||||
|
||||
parser.ExpectTokenString( MD5_VERSION_STRING );
|
||||
version = parser.ParseInt();
|
||||
if ( version != MD5_VERSION ) {
|
||||
parser.Error( "Invalid version %d. Should be version %d\n", version, MD5_VERSION );
|
||||
}
|
||||
|
||||
// skip the commandline
|
||||
parser.ExpectTokenString( "commandline" );
|
||||
parser.ReadToken( &token );
|
||||
|
||||
// parse num frames
|
||||
parser.ExpectTokenString( "numFrames" );
|
||||
numFrames = parser.ParseInt();
|
||||
if ( numFrames <= 0 ) {
|
||||
parser.Error( "Invalid number of frames: %d", numFrames );
|
||||
}
|
||||
|
||||
// parse framerate
|
||||
parser.ExpectTokenString( "frameRate" );
|
||||
frameRate = parser.ParseInt();
|
||||
if ( frameRate <= 0 ) {
|
||||
parser.Error( "Invalid framerate: %d", frameRate );
|
||||
}
|
||||
|
||||
// parse num cuts
|
||||
parser.ExpectTokenString( "numCuts" );
|
||||
numCuts = parser.ParseInt();
|
||||
if ( ( numCuts < 0 ) || ( numCuts > numFrames ) ) {
|
||||
parser.Error( "Invalid number of camera cuts: %d", numCuts );
|
||||
}
|
||||
|
||||
// parse the camera cuts
|
||||
parser.ExpectTokenString( "cuts" );
|
||||
parser.ExpectTokenString( "{" );
|
||||
cameraCuts.SetNum( numCuts );
|
||||
for( i = 0; i < numCuts; i++ ) {
|
||||
cameraCuts[ i ] = parser.ParseInt();
|
||||
if ( ( cameraCuts[ i ] < 1 ) || ( cameraCuts[ i ] >= numFrames ) ) {
|
||||
parser.Error( "Invalid camera cut" );
|
||||
}
|
||||
}
|
||||
parser.ExpectTokenString( "}" );
|
||||
|
||||
// parse the camera frames
|
||||
parser.ExpectTokenString( "camera" );
|
||||
parser.ExpectTokenString( "{" );
|
||||
camera.SetNum( numFrames );
|
||||
for( i = 0; i < numFrames; i++ ) {
|
||||
parser.Parse1DMatrix( 3, camera[ i ].t.ToFloatPtr() );
|
||||
parser.Parse1DMatrix( 3, camera[ i ].q.ToFloatPtr() );
|
||||
camera[ i ].fov = parser.ParseFloat();
|
||||
}
|
||||
parser.ExpectTokenString( "}" );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idCameraAnim::Start
|
||||
================
|
||||
*/
|
||||
void idCameraAnim::Start() {
|
||||
cycle = spawnArgs.GetInt( "cycle" );
|
||||
if ( !cycle ) {
|
||||
cycle = 1;
|
||||
}
|
||||
|
||||
if ( g_debugCinematic.GetBool() ) {
|
||||
gameLocal.Printf( "%d: '%s' start\n", gameLocal.framenum, GetName() );
|
||||
}
|
||||
|
||||
starttime = gameLocal.time;
|
||||
gameLocal.SetCamera( this );
|
||||
BecomeActive( TH_THINK );
|
||||
|
||||
// if the player has already created the renderview for this frame, have him update it again so that the camera starts this frame
|
||||
if ( gameLocal.GetLocalPlayer()->GetRenderView()->time[TIME_GROUP2] == gameLocal.fast.time ) {
|
||||
gameLocal.GetLocalPlayer()->CalculateRenderView();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idCameraAnim::Stop
|
||||
=====================
|
||||
*/
|
||||
void idCameraAnim::Stop() {
|
||||
if ( gameLocal.GetCamera() == this ) {
|
||||
if ( g_debugCinematic.GetBool() ) {
|
||||
gameLocal.Printf( "%d: '%s' stop\n", gameLocal.framenum, GetName() );
|
||||
}
|
||||
|
||||
BecomeInactive( TH_THINK );
|
||||
gameLocal.SetCamera( NULL );
|
||||
if ( threadNum ) {
|
||||
idThread::ObjectMoveDone( threadNum, this );
|
||||
threadNum = 0;
|
||||
}
|
||||
ActivateTargets( activator.GetEntity() );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idCameraAnim::Think
|
||||
=====================
|
||||
*/
|
||||
void idCameraAnim::Think() {
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idCameraAnim::GetViewParms
|
||||
=====================
|
||||
*/
|
||||
void idCameraAnim::GetViewParms( renderView_t *view ) {
|
||||
int realFrame;
|
||||
int frame;
|
||||
int frameTime;
|
||||
float lerp;
|
||||
float invlerp;
|
||||
cameraFrame_t *camFrame;
|
||||
int i;
|
||||
int cut;
|
||||
idQuat q1, q2, q3;
|
||||
|
||||
assert( view );
|
||||
if ( !view ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( camera.Num() == 0 ) {
|
||||
// we most likely are in the middle of a restore
|
||||
// FIXME: it would be better to fix it so this doesn't get called during a restore
|
||||
return;
|
||||
}
|
||||
|
||||
SetTimeState ts( timeGroup );
|
||||
|
||||
frameTime = ( gameLocal.time - starttime ) * frameRate;
|
||||
frame = frameTime / 1000;
|
||||
lerp = ( frameTime % 1000 ) * 0.001f;
|
||||
|
||||
// skip any frames where camera cuts occur
|
||||
realFrame = frame;
|
||||
cut = 0;
|
||||
for( i = 0; i < cameraCuts.Num(); i++ ) {
|
||||
if ( frame < cameraCuts[ i ] ) {
|
||||
break;
|
||||
}
|
||||
frame++;
|
||||
cut++;
|
||||
}
|
||||
|
||||
if ( g_debugCinematic.GetBool() ) {
|
||||
int prevFrameTime = ( gameLocal.previousTime - starttime ) * frameRate;
|
||||
int prevFrame = prevFrameTime / 1000;
|
||||
int prevCut;
|
||||
|
||||
prevCut = 0;
|
||||
for( i = 0; i < cameraCuts.Num(); i++ ) {
|
||||
if ( prevFrame < cameraCuts[ i ] ) {
|
||||
break;
|
||||
}
|
||||
prevFrame++;
|
||||
prevCut++;
|
||||
}
|
||||
|
||||
if ( prevCut != cut ) {
|
||||
gameLocal.Printf( "%d: '%s' cut %d\n", gameLocal.framenum, GetName(), cut );
|
||||
}
|
||||
}
|
||||
|
||||
// clamp to the first frame. also check if this is a one frame anim. one frame anims would end immediately,
|
||||
// but since they're mainly used for static cams anyway, just stay on it infinitely.
|
||||
if ( ( frame < 0 ) || ( camera.Num() < 2 ) ) {
|
||||
view->viewaxis = camera[ 0 ].q.ToQuat().ToMat3();
|
||||
view->vieworg = camera[ 0 ].t + offset;
|
||||
view->fov_x = camera[ 0 ].fov;
|
||||
} else if ( frame > camera.Num() - 2 ) {
|
||||
if ( cycle > 0 ) {
|
||||
cycle--;
|
||||
}
|
||||
|
||||
if ( cycle != 0 ) {
|
||||
// advance start time so that we loop
|
||||
starttime += ( ( camera.Num() - cameraCuts.Num() ) * 1000 ) / frameRate;
|
||||
GetViewParms( view );
|
||||
return;
|
||||
}
|
||||
|
||||
Stop();
|
||||
if ( gameLocal.GetCamera() != NULL ) {
|
||||
// we activated another camera when we stopped, so get it's viewparms instead
|
||||
gameLocal.GetCamera()->GetViewParms( view );
|
||||
return;
|
||||
} else {
|
||||
// just use our last frame
|
||||
camFrame = &camera[ camera.Num() - 1 ];
|
||||
view->viewaxis = camFrame->q.ToQuat().ToMat3();
|
||||
view->vieworg = camFrame->t + offset;
|
||||
view->fov_x = camFrame->fov;
|
||||
}
|
||||
} else if ( lerp == 0.0f ) {
|
||||
camFrame = &camera[ frame ];
|
||||
view->viewaxis = camFrame[ 0 ].q.ToMat3();
|
||||
view->vieworg = camFrame[ 0 ].t + offset;
|
||||
view->fov_x = camFrame[ 0 ].fov;
|
||||
} else {
|
||||
camFrame = &camera[ frame ];
|
||||
invlerp = 1.0f - lerp;
|
||||
q1 = camFrame[ 0 ].q.ToQuat();
|
||||
q2 = camFrame[ 1 ].q.ToQuat();
|
||||
q3.Slerp( q1, q2, lerp );
|
||||
view->viewaxis = q3.ToMat3();
|
||||
view->vieworg = camFrame[ 0 ].t * invlerp + camFrame[ 1 ].t * lerp + offset;
|
||||
view->fov_x = camFrame[ 0 ].fov * invlerp + camFrame[ 1 ].fov * lerp;
|
||||
}
|
||||
|
||||
gameLocal.CalcFov( view->fov_x, view->fov_x, view->fov_y );
|
||||
|
||||
// setup the pvs for this frame
|
||||
UpdatePVSAreas( view->vieworg );
|
||||
|
||||
#if 0
|
||||
static int lastFrame = 0;
|
||||
static idVec3 lastFrameVec( 0.0f, 0.0f, 0.0f );
|
||||
if ( gameLocal.time != lastFrame ) {
|
||||
gameRenderWorld->DebugBounds( colorCyan, idBounds( view->vieworg ).Expand( 16.0f ), vec3_origin, 1 );
|
||||
gameRenderWorld->DebugLine( colorRed, view->vieworg, view->vieworg + idVec3( 0.0f, 0.0f, 2.0f ), 10000, false );
|
||||
gameRenderWorld->DebugLine( colorCyan, lastFrameVec, view->vieworg, 10000, false );
|
||||
gameRenderWorld->DebugLine( colorYellow, view->vieworg + view->viewaxis[ 0 ] * 64.0f, view->vieworg + view->viewaxis[ 0 ] * 66.0f, 10000, false );
|
||||
gameRenderWorld->DebugLine( colorOrange, view->vieworg + view->viewaxis[ 0 ] * 64.0f, view->vieworg + view->viewaxis[ 0 ] * 64.0f + idVec3( 0.0f, 0.0f, 2.0f ), 10000, false );
|
||||
lastFrameVec = view->vieworg;
|
||||
lastFrame = gameLocal.time;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( g_showcamerainfo.GetBool() ) {
|
||||
gameLocal.Printf( "^5Frame: ^7%d/%d\n\n\n", realFrame + 1, camera.Num() - cameraCuts.Num() );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idCameraAnim::Event_Activate
|
||||
================
|
||||
*/
|
||||
void idCameraAnim::Event_Activate( idEntity *_activator ) {
|
||||
activator = _activator;
|
||||
if ( thinkFlags & TH_THINK ) {
|
||||
Stop();
|
||||
} else {
|
||||
Start();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idCameraAnim::Event_Start
|
||||
================
|
||||
*/
|
||||
void idCameraAnim::Event_Start() {
|
||||
Start();
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idCameraAnim::Event_Stop
|
||||
================
|
||||
*/
|
||||
void idCameraAnim::Event_Stop() {
|
||||
Stop();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idCameraAnim::Event_SetCallback
|
||||
================
|
||||
*/
|
||||
void idCameraAnim::Event_SetCallback() {
|
||||
if ( ( gameLocal.GetCamera() == this ) && !threadNum ) {
|
||||
threadNum = idThread::CurrentThreadNum();
|
||||
idThread::ReturnInt( true );
|
||||
} else {
|
||||
idThread::ReturnInt( false );
|
||||
}
|
||||
}
|
||||
132
neo/d3xp/Camera.h
Normal file
132
neo/d3xp/Camera.h
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_CAMERA_H__
|
||||
#define __GAME_CAMERA_H__
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Camera providing an alternative view of the level.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idCamera : public idEntity {
|
||||
public:
|
||||
ABSTRACT_PROTOTYPE( idCamera );
|
||||
|
||||
void Spawn();
|
||||
virtual void GetViewParms( renderView_t *view ) = 0;
|
||||
virtual renderView_t * GetRenderView();
|
||||
virtual void Stop(){} ;
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idCameraView
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idCameraView : public idCamera {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idCameraView );
|
||||
idCameraView();
|
||||
|
||||
// save games
|
||||
void Save( idSaveGame *savefile ) const; // archives object for save game file
|
||||
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
|
||||
|
||||
void Spawn( );
|
||||
virtual void GetViewParms( renderView_t *view );
|
||||
virtual void Stop();
|
||||
|
||||
protected:
|
||||
void Event_Activate( idEntity *activator );
|
||||
void Event_SetAttachments();
|
||||
void SetAttachment( idEntity **e, const char *p );
|
||||
float fov;
|
||||
idEntity *attachedTo;
|
||||
idEntity *attachedView;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
A camera which follows a path defined by an animation.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
idCQuat q;
|
||||
idVec3 t;
|
||||
float fov;
|
||||
} cameraFrame_t;
|
||||
|
||||
class idCameraAnim : public idCamera {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idCameraAnim );
|
||||
|
||||
idCameraAnim();
|
||||
~idCameraAnim();
|
||||
|
||||
// save games
|
||||
void Save( idSaveGame *savefile ) const; // archives object for save game file
|
||||
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
|
||||
|
||||
void Spawn();
|
||||
virtual void GetViewParms( renderView_t *view );
|
||||
|
||||
private:
|
||||
int threadNum;
|
||||
idVec3 offset;
|
||||
int frameRate;
|
||||
int starttime;
|
||||
int cycle;
|
||||
idList<int> cameraCuts;
|
||||
idList<cameraFrame_t> camera;
|
||||
idEntityPtr<idEntity> activator;
|
||||
|
||||
void Start();
|
||||
void Stop();
|
||||
void Think();
|
||||
|
||||
void LoadAnim();
|
||||
void Event_Start();
|
||||
void Event_Stop();
|
||||
void Event_SetCallback();
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
#endif /* !__GAME_CAMERA_H__ */
|
||||
185
neo/d3xp/EndLevel.cpp
Normal file
185
neo/d3xp/EndLevel.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../idlib/precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Game_local.h"
|
||||
|
||||
/*
|
||||
|
||||
game_endlevel.cpp
|
||||
|
||||
This entity is targeted to complete a level, and it also handles
|
||||
running the stats and moving the camera.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
CLASS_DECLARATION( idEntity, idTarget_EndLevel )
|
||||
EVENT( EV_Activate, idTarget_EndLevel::Event_Trigger )
|
||||
END_CLASS
|
||||
|
||||
/*
|
||||
================
|
||||
idTarget_EndLevel::Spawn
|
||||
================
|
||||
*/
|
||||
void idTarget_EndLevel::Spawn( void ) {
|
||||
idStr guiName;
|
||||
|
||||
gui = NULL;
|
||||
noGui = spawnArgs.GetBool("noGui");
|
||||
if (!noGui) {
|
||||
spawnArgs.GetString( "guiName", "guis/EndLevel.gui", guiName );
|
||||
|
||||
if (guiName.Length()) {
|
||||
gui = idUserInterface::FindGui( guiName, true, false, true );
|
||||
}
|
||||
}
|
||||
|
||||
buttonsReleased = false;
|
||||
readyToExit = false;
|
||||
|
||||
exitCommand = "";
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idTarget_EndLevel::~idTarget_EndLevel()
|
||||
================
|
||||
*/
|
||||
idTarget_EndLevel::~idTarget_EndLevel() {
|
||||
//FIXME: need to go to smart ptrs for gui allocs or the unique method
|
||||
//delete gui;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idTarget_EndLevel::Event_Trigger
|
||||
================
|
||||
*/
|
||||
void idTarget_EndLevel::Event_Trigger( idEntity *activator ) {
|
||||
if ( gameLocal.endLevel ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// mark the endLevel, which will modify some game actions
|
||||
// and pass control to us for drawing the stats and camera position
|
||||
gameLocal.endLevel = this;
|
||||
|
||||
// grab the activating player view position
|
||||
idPlayer *player = (idPlayer *)(activator);
|
||||
|
||||
initialViewOrg = player->GetEyePosition();
|
||||
initialViewAngles = idVec3( player->viewAngles[0], player->viewAngles[1], player->viewAngles[2] );
|
||||
|
||||
// kill all the sounds
|
||||
gameSoundWorld->StopAllSounds();
|
||||
|
||||
if ( noGui ) {
|
||||
readyToExit = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idTarget_EndLevel::Draw
|
||||
================
|
||||
*/
|
||||
void idTarget_EndLevel::Draw() {
|
||||
|
||||
if (noGui) {
|
||||
return;
|
||||
}
|
||||
|
||||
renderView_t renderView;
|
||||
|
||||
memset( &renderView, 0, sizeof( renderView ) );
|
||||
|
||||
renderView.width = SCREEN_WIDTH;
|
||||
renderView.height = SCREEN_HEIGHT;
|
||||
renderView.x = 0;
|
||||
renderView.y = 0;
|
||||
|
||||
renderView.fov_x = 90;
|
||||
renderView.fov_y = gameLocal.CalcFovY( renderView.fov_x );
|
||||
renderView.time = gameLocal.time;
|
||||
|
||||
#if 0
|
||||
renderView.vieworg = initialViewOrg;
|
||||
renderView.viewaxis = idAngles(initialViewAngles).toMat3();
|
||||
#else
|
||||
renderView.vieworg = renderEntity.origin;
|
||||
renderView.viewaxis = renderEntity.axis;
|
||||
#endif
|
||||
|
||||
gameRenderWorld->RenderScene( &renderView );
|
||||
|
||||
// draw the gui on top of the 3D view
|
||||
gui->Redraw(gameLocal.time);
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idTarget_EndLevel::PlayerCommand
|
||||
================
|
||||
*/
|
||||
void idTarget_EndLevel::PlayerCommand( int buttons ) {
|
||||
if ( !( buttons & BUTTON_ATTACK ) ) {
|
||||
buttonsReleased = true;
|
||||
return;
|
||||
}
|
||||
if ( !buttonsReleased ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// we will exit at the end of the next game frame
|
||||
readyToExit = true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idTarget_EndLevel::ExitCommand
|
||||
================
|
||||
*/
|
||||
const char *idTarget_EndLevel::ExitCommand() {
|
||||
if ( !readyToExit ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
idStr nextMap;
|
||||
|
||||
if (spawnArgs.GetString( "nextMap", "", nextMap )) {
|
||||
sprintf( exitCommand, "map %s", nextMap.c_str() );
|
||||
} else {
|
||||
exitCommand = "";
|
||||
}
|
||||
|
||||
return exitCommand;
|
||||
}
|
||||
66
neo/d3xp/EndLevel.h
Normal file
66
neo/d3xp/EndLevel.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
class idTarget_EndLevel : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_EndLevel );
|
||||
|
||||
void Spawn( void );
|
||||
~idTarget_EndLevel();
|
||||
|
||||
void Draw();
|
||||
// the endLevel will be responsible for drawing the entire screen
|
||||
// when it is active
|
||||
|
||||
void PlayerCommand( int buttons );
|
||||
// when an endlevel is active, plauer buttons get sent here instead
|
||||
// of doing anything to the player, which will allow moving to
|
||||
// the next level
|
||||
|
||||
const char *ExitCommand();
|
||||
// the game will check this each frame, and return it to the
|
||||
// session when there is something to give
|
||||
|
||||
private:
|
||||
idStr exitCommand;
|
||||
|
||||
idVec3 initialViewOrg;
|
||||
idVec3 initialViewAngles;
|
||||
// set when the player triggers the exit
|
||||
|
||||
idUserInterface *gui;
|
||||
|
||||
bool buttonsReleased;
|
||||
// don't skip out until buttons are released, then pressed
|
||||
|
||||
bool readyToExit;
|
||||
bool noGui;
|
||||
|
||||
void Event_Trigger( idEntity *activator );
|
||||
};
|
||||
|
||||
5858
neo/d3xp/Entity.cpp
Normal file
5858
neo/d3xp/Entity.cpp
Normal file
File diff suppressed because it is too large
Load Diff
711
neo/d3xp/Entity.h
Normal file
711
neo/d3xp/Entity.h
Normal file
@@ -0,0 +1,711 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_ENTITY_H__
|
||||
#define __GAME_ENTITY_H__
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Game entity base class.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
static const int DELAY_DORMANT_TIME = 3000;
|
||||
|
||||
extern const idEventDef EV_PostSpawn;
|
||||
extern const idEventDef EV_FindTargets;
|
||||
extern const idEventDef EV_Touch;
|
||||
extern const idEventDef EV_Use;
|
||||
extern const idEventDef EV_Activate;
|
||||
extern const idEventDef EV_ActivateTargets;
|
||||
extern const idEventDef EV_Hide;
|
||||
extern const idEventDef EV_Show;
|
||||
extern const idEventDef EV_GetShaderParm;
|
||||
extern const idEventDef EV_SetShaderParm;
|
||||
extern const idEventDef EV_SetOwner;
|
||||
extern const idEventDef EV_GetAngles;
|
||||
extern const idEventDef EV_SetAngles;
|
||||
extern const idEventDef EV_SetLinearVelocity;
|
||||
extern const idEventDef EV_SetAngularVelocity;
|
||||
extern const idEventDef EV_SetSkin;
|
||||
extern const idEventDef EV_StartSoundShader;
|
||||
extern const idEventDef EV_StopSound;
|
||||
extern const idEventDef EV_CacheSoundShader;
|
||||
|
||||
// Think flags
|
||||
enum {
|
||||
TH_ALL = -1,
|
||||
TH_THINK = 1, // run think function each frame
|
||||
TH_PHYSICS = 2, // run physics each frame
|
||||
TH_ANIMATE = 4, // update animation each frame
|
||||
TH_UPDATEVISUALS = 8, // update renderEntity
|
||||
TH_UPDATEPARTICLES = 16
|
||||
};
|
||||
|
||||
//
|
||||
// Signals
|
||||
// make sure to change script/doom_defs.script if you add any, or change their order
|
||||
//
|
||||
typedef enum {
|
||||
SIG_TOUCH, // object was touched
|
||||
SIG_USE, // object was used
|
||||
SIG_TRIGGER, // object was activated
|
||||
SIG_REMOVED, // object was removed from the game
|
||||
SIG_DAMAGE, // object was damaged
|
||||
SIG_BLOCKED, // object was blocked
|
||||
|
||||
SIG_MOVER_POS1, // mover at position 1 (door closed)
|
||||
SIG_MOVER_POS2, // mover at position 2 (door open)
|
||||
SIG_MOVER_1TO2, // mover changing from position 1 to 2
|
||||
SIG_MOVER_2TO1, // mover changing from position 2 to 1
|
||||
|
||||
NUM_SIGNALS
|
||||
} signalNum_t;
|
||||
|
||||
// FIXME: At some point we may want to just limit it to one thread per signal, but
|
||||
// for now, I'm allowing multiple threads. We should reevaluate this later in the project
|
||||
#define MAX_SIGNAL_THREADS 16 // probably overkill, but idList uses a granularity of 16
|
||||
|
||||
struct signal_t {
|
||||
int threadnum;
|
||||
const function_t *function;
|
||||
};
|
||||
|
||||
class signalList_t {
|
||||
public:
|
||||
idList<signal_t, TAG_ENTITY> signal[ NUM_SIGNALS ];
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
================================================
|
||||
idNetEvent
|
||||
|
||||
Utility for detecting a bool state change:
|
||||
-server calls ::Set
|
||||
-client ::Get will return true (once only)
|
||||
|
||||
Useful because:
|
||||
-Hides client from having to manually declare "last" state and manually checking against it
|
||||
-using int counter prevents problems w/ dropped snapshots
|
||||
|
||||
(ie if we just serialized a bool to true for a single ss, if that ss is dropped,skipped,whatever
|
||||
the client would never handle it. By incrementing a wrapped counter, we are guaranteed to detect
|
||||
the state change no matter what happens at the net layer).
|
||||
================================================
|
||||
*/
|
||||
template < int max >
|
||||
struct idNetEvent {
|
||||
idNetEvent() : count(0), lastCount(0) { }
|
||||
void Set() { count = ( ( count + 1 ) % max ); }
|
||||
bool Get() {
|
||||
if ( count != lastCount ) {
|
||||
lastCount = count;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void Serialize( idSerializer &ser ) {
|
||||
if ( count >= max ) {
|
||||
idLib::Warning("idNetEvent. count %d > max %d", count, max );
|
||||
}
|
||||
ser.SerializeUMax( count, max );
|
||||
}
|
||||
|
||||
public:
|
||||
static const int Maximum = max;
|
||||
int count;
|
||||
int lastCount;
|
||||
};
|
||||
|
||||
typedef idNetEvent< 7 > netBoolEvent_t;
|
||||
|
||||
inline void WriteToBitMsg( const netBoolEvent_t & netEvent, idBitMsg & msg ) {
|
||||
msg.WriteBits( netEvent.count, idMath::BitsForInteger( netBoolEvent_t::Maximum ) );
|
||||
|
||||
assert( netEvent.count <= netBoolEvent_t::Maximum );
|
||||
}
|
||||
|
||||
inline void ReadFromBitMsg( netBoolEvent_t & netEvent, const idBitMsg & msg ) {
|
||||
netEvent.count = msg.ReadBits( idMath::BitsForInteger( netBoolEvent_t::Maximum ) );
|
||||
|
||||
assert( netEvent.count <= netBoolEvent_t::Maximum );
|
||||
}
|
||||
|
||||
|
||||
class idEntity : public idClass {
|
||||
public:
|
||||
static const int MAX_PVS_AREAS = 4;
|
||||
static const uint32 INVALID_PREDICTION_KEY = 0xFFFFFFFF;
|
||||
|
||||
int entityNumber; // index into the entity list
|
||||
int entityDefNumber; // index into the entity def list
|
||||
|
||||
idLinkList<idEntity> spawnNode; // for being linked into spawnedEntities list
|
||||
idLinkList<idEntity> activeNode; // for being linked into activeEntities list
|
||||
idLinkList<idEntity> aimAssistNode; // linked into gameLocal.aimAssistEntities
|
||||
|
||||
idLinkList<idEntity> snapshotNode; // for being linked into snapshotEntities list
|
||||
int snapshotChanged; // used to detect snapshot state changes
|
||||
int snapshotBits; // number of bits this entity occupied in the last snapshot
|
||||
bool snapshotStale; // Set to true if this entity is considered stale in the snapshot
|
||||
|
||||
idStr name; // name of entity
|
||||
idDict spawnArgs; // key/value pairs used to spawn and initialize entity
|
||||
idScriptObject scriptObject; // contains all script defined data for this entity
|
||||
|
||||
int thinkFlags; // TH_? flags
|
||||
int dormantStart; // time that the entity was first closed off from player
|
||||
bool cinematic; // during cinematics, entity will only think if cinematic is set
|
||||
|
||||
renderView_t * renderView; // for camera views from this entity
|
||||
idEntity * cameraTarget; // any remoteRenderMap shaders will use this
|
||||
|
||||
idList< idEntityPtr<idEntity>, TAG_ENTITY > targets; // when this entity is activated these entities entity are activated
|
||||
|
||||
int health; // FIXME: do all objects really need health?
|
||||
|
||||
struct entityFlags_s {
|
||||
bool notarget :1; // if true never attack or target this entity
|
||||
bool noknockback :1; // if true no knockback from hits
|
||||
bool takedamage :1; // if true this entity can be damaged
|
||||
bool hidden :1; // if true this entity is not visible
|
||||
bool bindOrientated :1; // if true both the master orientation is used for binding
|
||||
bool solidForTeam :1; // if true this entity is considered solid when a physics team mate pushes entities
|
||||
bool forcePhysicsUpdate :1; // if true always update from the physics whether the object moved or not
|
||||
bool selected :1; // if true the entity is selected for editing
|
||||
bool neverDormant :1; // if true the entity never goes dormant
|
||||
bool isDormant :1; // if true the entity is dormant
|
||||
bool hasAwakened :1; // before a monster has been awakened the first time, use full PVS for dormant instead of area-connected
|
||||
bool networkSync :1; // if true the entity is synchronized over the network
|
||||
bool grabbed :1; // if true object is currently being grabbed
|
||||
bool skipReplication :1; // don't replicate this entity over the network.
|
||||
} fl;
|
||||
|
||||
int timeGroup;
|
||||
|
||||
bool noGrab;
|
||||
|
||||
renderEntity_t xrayEntity;
|
||||
qhandle_t xrayEntityHandle;
|
||||
const idDeclSkin * xraySkin;
|
||||
|
||||
void DetermineTimeGroup( bool slowmo );
|
||||
|
||||
void SetGrabbedState( bool grabbed );
|
||||
bool IsGrabbed();
|
||||
|
||||
public:
|
||||
ABSTRACT_PROTOTYPE( idEntity );
|
||||
|
||||
idEntity();
|
||||
~idEntity();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
const char * GetEntityDefName() const;
|
||||
void SetName( const char *name );
|
||||
const char * GetName() const;
|
||||
virtual void UpdateChangeableSpawnArgs( const idDict *source );
|
||||
int GetEntityNumber() const { return entityNumber; }
|
||||
|
||||
// clients generate views based on all the player specific options,
|
||||
// cameras have custom code, and everything else just uses the axis orientation
|
||||
virtual renderView_t * GetRenderView();
|
||||
|
||||
// thinking
|
||||
virtual void Think();
|
||||
bool CheckDormant(); // dormant == on the active list, but out of PVS
|
||||
virtual void DormantBegin(); // called when entity becomes dormant
|
||||
virtual void DormantEnd(); // called when entity wakes from being dormant
|
||||
bool IsActive() const;
|
||||
void BecomeActive( int flags );
|
||||
void BecomeInactive( int flags );
|
||||
void UpdatePVSAreas( const idVec3 &pos );
|
||||
void BecomeReplicated();
|
||||
|
||||
// visuals
|
||||
virtual void Present();
|
||||
virtual renderEntity_t *GetRenderEntity();
|
||||
virtual int GetModelDefHandle();
|
||||
virtual void SetModel( const char *modelname );
|
||||
void SetSkin( const idDeclSkin *skin );
|
||||
const idDeclSkin * GetSkin() const;
|
||||
void SetShaderParm( int parmnum, float value );
|
||||
virtual void SetColor( float red, float green, float blue );
|
||||
virtual void SetColor( const idVec3 &color );
|
||||
virtual void GetColor( idVec3 &out ) const;
|
||||
virtual void SetColor( const idVec4 &color );
|
||||
virtual void GetColor( idVec4 &out ) const;
|
||||
virtual void FreeModelDef();
|
||||
virtual void FreeLightDef();
|
||||
virtual void Hide();
|
||||
virtual void Show();
|
||||
bool IsHidden() const;
|
||||
void UpdateVisuals();
|
||||
void UpdateModel();
|
||||
void UpdateModelTransform();
|
||||
virtual void ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material );
|
||||
int GetNumPVSAreas();
|
||||
const int * GetPVSAreas();
|
||||
void ClearPVSAreas();
|
||||
bool PhysicsTeamInPVS( pvsHandle_t pvsHandle );
|
||||
|
||||
// animation
|
||||
virtual bool UpdateAnimationControllers();
|
||||
bool UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView );
|
||||
static bool ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView );
|
||||
virtual idAnimator * GetAnimator(); // returns animator object used by this entity
|
||||
|
||||
// sound
|
||||
virtual bool CanPlayChatterSounds() const;
|
||||
bool StartSound( const char *soundName, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length );
|
||||
bool StartSoundShader( const idSoundShader *shader, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length );
|
||||
void StopSound( const s_channelType channel, bool broadcast ); // pass SND_CHANNEL_ANY to stop all sounds
|
||||
void SetSoundVolume( float volume );
|
||||
void UpdateSound();
|
||||
int GetListenerId() const;
|
||||
idSoundEmitter * GetSoundEmitter() const;
|
||||
void FreeSoundEmitter( bool immediate );
|
||||
|
||||
// entity binding
|
||||
virtual void PreBind();
|
||||
virtual void PostBind();
|
||||
virtual void PreUnbind();
|
||||
virtual void PostUnbind();
|
||||
void JoinTeam( idEntity *teammember );
|
||||
void Bind( idEntity *master, bool orientated );
|
||||
void BindToJoint( idEntity *master, const char *jointname, bool orientated );
|
||||
void BindToJoint( idEntity *master, jointHandle_t jointnum, bool orientated );
|
||||
void BindToBody( idEntity *master, int bodyId, bool orientated );
|
||||
void Unbind();
|
||||
bool IsBound() const;
|
||||
bool IsBoundTo( idEntity *master ) const;
|
||||
idEntity * GetBindMaster() const;
|
||||
jointHandle_t GetBindJoint() const;
|
||||
int GetBindBody() const;
|
||||
idEntity * GetTeamMaster() const;
|
||||
idEntity * GetNextTeamEntity() const;
|
||||
void ConvertLocalToWorldTransform( idVec3 &offset, idMat3 &axis );
|
||||
idVec3 GetLocalVector( const idVec3 &vec ) const;
|
||||
idVec3 GetLocalCoordinates( const idVec3 &vec ) const;
|
||||
idVec3 GetWorldVector( const idVec3 &vec ) const;
|
||||
idVec3 GetWorldCoordinates( const idVec3 &vec ) const;
|
||||
bool GetMasterPosition( idVec3 &masterOrigin, idMat3 &masterAxis ) const;
|
||||
void GetWorldVelocities( idVec3 &linearVelocity, idVec3 &angularVelocity ) const;
|
||||
|
||||
// physics
|
||||
// set a new physics object to be used by this entity
|
||||
void SetPhysics( idPhysics *phys );
|
||||
// get the physics object used by this entity
|
||||
idPhysics * GetPhysics() const;
|
||||
// restore physics pointer for save games
|
||||
void RestorePhysics( idPhysics *phys );
|
||||
// run the physics for this entity
|
||||
bool RunPhysics();
|
||||
// Interpolates the physics, used on MP clients.
|
||||
void InterpolatePhysics( const float fraction );
|
||||
// InterpolatePhysics actually calls evaluate, this version doesn't.
|
||||
void InterpolatePhysicsOnly( const float fraction, bool updateTeam = false );
|
||||
// set the origin of the physics object (relative to bindMaster if not NULL)
|
||||
void SetOrigin( const idVec3 &org );
|
||||
// set the axis of the physics object (relative to bindMaster if not NULL)
|
||||
void SetAxis( const idMat3 &axis );
|
||||
// use angles to set the axis of the physics object (relative to bindMaster if not NULL)
|
||||
void SetAngles( const idAngles &ang );
|
||||
// get the floor position underneath the physics object
|
||||
bool GetFloorPos( float max_dist, idVec3 &floorpos ) const;
|
||||
// retrieves the transformation going from the physics origin/axis to the visual origin/axis
|
||||
virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis );
|
||||
// retrieves the transformation going from the physics origin/axis to the sound origin/axis
|
||||
virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis );
|
||||
// called from the physics object when colliding, should return true if the physics simulation should stop
|
||||
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
|
||||
// retrieves impact information, 'ent' is the entity retrieving the info
|
||||
virtual void GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info );
|
||||
// apply an impulse to the physics object, 'ent' is the entity applying the impulse
|
||||
virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse );
|
||||
// add a force to the physics object, 'ent' is the entity adding the force
|
||||
virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force );
|
||||
// activate the physics object, 'ent' is the entity activating this entity
|
||||
virtual void ActivatePhysics( idEntity *ent );
|
||||
// returns true if the physics object is at rest
|
||||
virtual bool IsAtRest() const;
|
||||
// returns the time the physics object came to rest
|
||||
virtual int GetRestStartTime() const;
|
||||
// add a contact entity
|
||||
virtual void AddContactEntity( idEntity *ent );
|
||||
// remove a touching entity
|
||||
virtual void RemoveContactEntity( idEntity *ent );
|
||||
|
||||
// damage
|
||||
// returns true if this entity can be damaged from the given origin
|
||||
virtual bool CanDamage( const idVec3 &origin, idVec3 &damagePoint ) const;
|
||||
// applies damage to this entity
|
||||
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
|
||||
// adds a damage effect like overlays, blood, sparks, debris etc.
|
||||
virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName );
|
||||
// callback function for when another entity received damage from this entity. damage can be adjusted and returned to the caller.
|
||||
virtual void DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage );
|
||||
// notifies this entity that it is in pain
|
||||
virtual bool Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
|
||||
// notifies this entity that is has been killed
|
||||
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
|
||||
|
||||
// scripting
|
||||
virtual bool ShouldConstructScriptObjectAtSpawn() const;
|
||||
virtual idThread * ConstructScriptObject();
|
||||
virtual void DeconstructScriptObject();
|
||||
void SetSignal( signalNum_t signalnum, idThread *thread, const function_t *function );
|
||||
void ClearSignal( idThread *thread, signalNum_t signalnum );
|
||||
void ClearSignalThread( signalNum_t signalnum, idThread *thread );
|
||||
bool HasSignal( signalNum_t signalnum ) const;
|
||||
void Signal( signalNum_t signalnum );
|
||||
void SignalEvent( idThread *thread, signalNum_t signalnum );
|
||||
|
||||
// gui
|
||||
void TriggerGuis();
|
||||
bool HandleGuiCommands( idEntity *entityGui, const char *cmds );
|
||||
virtual bool HandleSingleGuiCommand( idEntity *entityGui, idLexer *src );
|
||||
|
||||
// targets
|
||||
void FindTargets();
|
||||
void RemoveNullTargets();
|
||||
void ActivateTargets( idEntity *activator ) const;
|
||||
|
||||
// misc
|
||||
virtual void Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination );
|
||||
bool TouchTriggers() const;
|
||||
idCurve_Spline<idVec3> *GetSpline() const;
|
||||
virtual void ShowEditingDialog();
|
||||
|
||||
enum {
|
||||
EVENT_STARTSOUNDSHADER,
|
||||
EVENT_STOPSOUNDSHADER,
|
||||
EVENT_MAXEVENTS
|
||||
};
|
||||
|
||||
// Called on clients in an MP game, does the actual interpolation for the entity.
|
||||
// This function will eventually replace ClientPredictionThink completely.
|
||||
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
|
||||
|
||||
virtual void ClientPredictionThink();
|
||||
virtual void WriteToSnapshot( idBitMsg &msg ) const;
|
||||
void ReadFromSnapshot_Ex( const idBitMsg &msg );
|
||||
virtual void ReadFromSnapshot( const idBitMsg &msg );
|
||||
virtual bool ServerReceiveEvent( int event, int time, const idBitMsg &msg );
|
||||
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
|
||||
|
||||
void WriteBindToSnapshot( idBitMsg &msg ) const;
|
||||
void ReadBindFromSnapshot( const idBitMsg &msg );
|
||||
void WriteColorToSnapshot( idBitMsg &msg ) const;
|
||||
void ReadColorFromSnapshot( const idBitMsg &msg );
|
||||
void WriteGUIToSnapshot( idBitMsg &msg ) const;
|
||||
void ReadGUIFromSnapshot( const idBitMsg &msg );
|
||||
|
||||
void ServerSendEvent( int eventId, const idBitMsg *msg, bool saveEvent, lobbyUserID_t excluding = lobbyUserID_t() ) const;
|
||||
void ClientSendEvent( int eventId, const idBitMsg *msg ) const;
|
||||
|
||||
void SetUseClientInterpolation( bool use ) { useClientInterpolation = use; }
|
||||
|
||||
void SetSkipReplication( const bool skip ) { fl.skipReplication = skip; }
|
||||
bool GetSkipReplication() const { return fl.skipReplication; }
|
||||
bool IsReplicated() const { return GetEntityNumber() < ENTITYNUM_FIRST_NON_REPLICATED; }
|
||||
|
||||
void CreateDeltasFromOldOriginAndAxis( const idVec3 & oldOrigin, const idMat3 & oldAxis );
|
||||
void DecayOriginAndAxisDelta();
|
||||
uint32 GetPredictedKey() { return predictionKey; }
|
||||
void SetPredictedKey( uint32 key_ ) { predictionKey = key_; }
|
||||
|
||||
void FlagNewSnapshot();
|
||||
|
||||
idEntity* GetTeamChain() { return teamChain; }
|
||||
|
||||
// It is only safe to interpolate if this entity has received two snapshots.
|
||||
enum interpolationBehavior_t {
|
||||
USE_NO_INTERPOLATION,
|
||||
USE_LATEST_SNAP_ONLY,
|
||||
USE_INTERPOLATION
|
||||
};
|
||||
|
||||
interpolationBehavior_t GetInterpolationBehavior() const { return interpolationBehavior; }
|
||||
unsigned int GetNumSnapshotsReceived() const { return snapshotsReceived; }
|
||||
|
||||
protected:
|
||||
renderEntity_t renderEntity; // used to present a model to the renderer
|
||||
int modelDefHandle; // handle to static renderer model
|
||||
refSound_t refSound; // used to present sound to the audio engine
|
||||
|
||||
idVec3 GetOriginDelta() const { return originDelta; }
|
||||
idMat3 GetAxisDelta() const { return axisDelta; }
|
||||
|
||||
private:
|
||||
idPhysics_Static defaultPhysicsObj; // default physics object
|
||||
idPhysics * physics; // physics used for this entity
|
||||
idEntity * bindMaster; // entity bound to if unequal NULL
|
||||
jointHandle_t bindJoint; // joint bound to if unequal INVALID_JOINT
|
||||
int bindBody; // body bound to if unequal -1
|
||||
idEntity * teamMaster; // master of the physics team
|
||||
idEntity * teamChain; // next entity in physics team
|
||||
bool useClientInterpolation; // disables interpolation for some objects (handy for weapon world models)
|
||||
int numPVSAreas; // number of renderer areas the entity covers
|
||||
int PVSAreas[MAX_PVS_AREAS]; // numbers of the renderer areas the entity covers
|
||||
|
||||
signalList_t * signals;
|
||||
|
||||
int mpGUIState; // local cache to avoid systematic SetStateInt
|
||||
|
||||
uint32 predictionKey; // Unique key used to sync predicted ents (projectiles) in MP.
|
||||
|
||||
// Delta values that are set when the server or client disagree on where the render model should be. If this happens,
|
||||
// they resolve it through DecayOriginAndAxisDelta()
|
||||
idVec3 originDelta;
|
||||
idMat3 axisDelta;
|
||||
|
||||
interpolationBehavior_t interpolationBehavior;
|
||||
unsigned int snapshotsReceived;
|
||||
|
||||
private:
|
||||
void FixupLocalizedStrings();
|
||||
|
||||
bool DoDormantTests(); // dormant == on the active list, but out of PVS
|
||||
|
||||
// physics
|
||||
// initialize the default physics
|
||||
void InitDefaultPhysics( const idVec3 &origin, const idMat3 &axis );
|
||||
// update visual position from the physics
|
||||
void UpdateFromPhysics( bool moveBack );
|
||||
// get physics timestep
|
||||
virtual int GetPhysicsTimeStep() const;
|
||||
|
||||
// entity binding
|
||||
bool InitBind( idEntity *master ); // initialize an entity binding
|
||||
void FinishBind(); // finish an entity binding
|
||||
void RemoveBinds(); // deletes any entities bound to this object
|
||||
void QuitTeam(); // leave the current team
|
||||
|
||||
void UpdatePVSAreas();
|
||||
|
||||
// events
|
||||
void Event_GetName();
|
||||
void Event_SetName( const char *name );
|
||||
void Event_FindTargets();
|
||||
void Event_ActivateTargets( idEntity *activator );
|
||||
void Event_NumTargets();
|
||||
void Event_GetTarget( float index );
|
||||
void Event_RandomTarget( const char *ignore );
|
||||
void Event_Bind( idEntity *master );
|
||||
void Event_BindPosition( idEntity *master );
|
||||
void Event_BindToJoint( idEntity *master, const char *jointname, float orientated );
|
||||
void Event_Unbind();
|
||||
void Event_RemoveBinds();
|
||||
void Event_SpawnBind();
|
||||
void Event_SetOwner( idEntity *owner );
|
||||
void Event_SetModel( const char *modelname );
|
||||
void Event_SetSkin( const char *skinname );
|
||||
void Event_GetShaderParm( int parmnum );
|
||||
void Event_SetShaderParm( int parmnum, float value );
|
||||
void Event_SetShaderParms( float parm0, float parm1, float parm2, float parm3 );
|
||||
void Event_SetColor( float red, float green, float blue );
|
||||
void Event_GetColor();
|
||||
void Event_IsHidden();
|
||||
void Event_Hide();
|
||||
void Event_Show();
|
||||
void Event_CacheSoundShader( const char *soundName );
|
||||
void Event_StartSoundShader( const char *soundName, int channel );
|
||||
void Event_StopSound( int channel, int netSync );
|
||||
void Event_StartSound( const char *soundName, int channel, int netSync );
|
||||
void Event_FadeSound( int channel, float to, float over );
|
||||
void Event_GetWorldOrigin();
|
||||
void Event_SetWorldOrigin( idVec3 const &org );
|
||||
void Event_GetOrigin();
|
||||
void Event_SetOrigin( const idVec3 &org );
|
||||
void Event_GetAngles();
|
||||
void Event_SetAngles( const idAngles &ang );
|
||||
void Event_SetLinearVelocity( const idVec3 &velocity );
|
||||
void Event_GetLinearVelocity();
|
||||
void Event_SetAngularVelocity( const idVec3 &velocity );
|
||||
void Event_GetAngularVelocity();
|
||||
void Event_SetSize( const idVec3 &mins, const idVec3 &maxs );
|
||||
void Event_GetSize();
|
||||
void Event_GetMins();
|
||||
void Event_GetMaxs();
|
||||
void Event_Touches( idEntity *ent );
|
||||
void Event_SetGuiParm( const char *key, const char *val );
|
||||
void Event_SetGuiFloat( const char *key, float f );
|
||||
void Event_GetNextKey( const char *prefix, const char *lastMatch );
|
||||
void Event_SetKey( const char *key, const char *value );
|
||||
void Event_GetKey( const char *key );
|
||||
void Event_GetIntKey( const char *key );
|
||||
void Event_GetFloatKey( const char *key );
|
||||
void Event_GetVectorKey( const char *key );
|
||||
void Event_GetEntityKey( const char *key );
|
||||
void Event_RestorePosition();
|
||||
void Event_UpdateCameraTarget();
|
||||
void Event_DistanceTo( idEntity *ent );
|
||||
void Event_DistanceToPoint( const idVec3 &point );
|
||||
void Event_StartFx( const char *fx );
|
||||
void Event_WaitFrame();
|
||||
void Event_Wait( float time );
|
||||
void Event_HasFunction( const char *name );
|
||||
void Event_CallFunction( const char *name );
|
||||
void Event_SetNeverDormant( int enable );
|
||||
void Event_SetGui( int guiNum, const char *guiName);
|
||||
void Event_PrecacheGui( const char *guiName );
|
||||
void Event_GetGuiParm(int guiNum, const char *key);
|
||||
void Event_GetGuiParmFloat(int guiNum, const char *key);
|
||||
void Event_GuiNamedEvent(int guiNum, const char *event);
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Animated entity base class.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
typedef struct damageEffect_s {
|
||||
jointHandle_t jointNum;
|
||||
idVec3 localOrigin;
|
||||
idVec3 localNormal;
|
||||
int time;
|
||||
const idDeclParticle* type;
|
||||
struct damageEffect_s * next;
|
||||
} damageEffect_t;
|
||||
|
||||
class idAnimatedEntity : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idAnimatedEntity );
|
||||
|
||||
idAnimatedEntity();
|
||||
~idAnimatedEntity();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void ClientPredictionThink();
|
||||
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
|
||||
virtual void Think();
|
||||
|
||||
void UpdateAnimation();
|
||||
|
||||
virtual idAnimator * GetAnimator();
|
||||
virtual void SetModel( const char *modelname );
|
||||
|
||||
bool GetJointWorldTransform( jointHandle_t jointHandle, int currentTime, idVec3 &offset, idMat3 &axis );
|
||||
bool GetJointTransformForAnim( jointHandle_t jointHandle, int animNum, int currentTime, idVec3 &offset, idMat3 &axis ) const;
|
||||
|
||||
virtual int GetDefaultSurfaceType() const;
|
||||
virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName );
|
||||
void AddLocalDamageEffect( jointHandle_t jointNum, const idVec3 &localPoint, const idVec3 &localNormal, const idVec3 &localDir, const idDeclEntityDef *def, const idMaterial *collisionMaterial );
|
||||
void UpdateDamageEffects();
|
||||
|
||||
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
|
||||
|
||||
enum {
|
||||
EVENT_ADD_DAMAGE_EFFECT = idEntity::EVENT_MAXEVENTS,
|
||||
EVENT_MAXEVENTS
|
||||
};
|
||||
|
||||
protected:
|
||||
idAnimator animator;
|
||||
damageEffect_t * damageEffects;
|
||||
|
||||
private:
|
||||
void Event_GetJointHandle( const char *jointname );
|
||||
void Event_ClearAllJoints();
|
||||
void Event_ClearJoint( jointHandle_t jointnum );
|
||||
void Event_SetJointPos( jointHandle_t jointnum, jointModTransform_t transform_type, const idVec3 &pos );
|
||||
void Event_SetJointAngle( jointHandle_t jointnum, jointModTransform_t transform_type, const idAngles &angles );
|
||||
void Event_GetJointPos( jointHandle_t jointnum );
|
||||
void Event_GetJointAngle( jointHandle_t jointnum );
|
||||
};
|
||||
|
||||
|
||||
class SetTimeState {
|
||||
bool activated;
|
||||
bool previousFast;
|
||||
bool fast;
|
||||
|
||||
public:
|
||||
SetTimeState();
|
||||
SetTimeState( int timeGroup );
|
||||
~SetTimeState();
|
||||
|
||||
void PushState( int timeGroup );
|
||||
};
|
||||
|
||||
ID_INLINE SetTimeState::SetTimeState() {
|
||||
activated = false;
|
||||
}
|
||||
|
||||
ID_INLINE SetTimeState::SetTimeState( int timeGroup ) {
|
||||
activated = false;
|
||||
PushState( timeGroup );
|
||||
}
|
||||
|
||||
ID_INLINE void SetTimeState::PushState( int timeGroup ) {
|
||||
|
||||
// Don't mess with time in Multiplayer
|
||||
if ( !common->IsMultiplayer() ) {
|
||||
|
||||
activated = true;
|
||||
|
||||
// determine previous fast setting
|
||||
if ( gameLocal.time == gameLocal.slow.time ) {
|
||||
previousFast = false;
|
||||
} else {
|
||||
previousFast = true;
|
||||
}
|
||||
|
||||
// determine new fast setting
|
||||
if ( timeGroup ) {
|
||||
fast = true;
|
||||
} else {
|
||||
fast = false;
|
||||
}
|
||||
|
||||
// set correct time
|
||||
gameLocal.SelectTimeGroup( timeGroup );
|
||||
}
|
||||
}
|
||||
|
||||
ID_INLINE SetTimeState::~SetTimeState() {
|
||||
if ( activated && !common->IsMultiplayer() ) {
|
||||
// set previous correct time
|
||||
gameLocal.SelectTimeGroup( previousFast );
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !__GAME_ENTITY_H__ */
|
||||
833
neo/d3xp/Fx.cpp
Normal file
833
neo/d3xp/Fx.cpp
Normal file
@@ -0,0 +1,833 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../idlib/precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Game_local.h"
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idEntityFx
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
const idEventDef EV_Fx_KillFx( "_killfx" );
|
||||
const idEventDef EV_Fx_Action( "_fxAction", "e" ); // implemented by subclasses
|
||||
|
||||
CLASS_DECLARATION( idEntity, idEntityFx )
|
||||
EVENT( EV_Activate, idEntityFx::Event_Trigger )
|
||||
EVENT( EV_Fx_KillFx, idEntityFx::Event_ClearFx )
|
||||
END_CLASS
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
idEntityFx::Save
|
||||
================
|
||||
*/
|
||||
void idEntityFx::Save( idSaveGame *savefile ) const {
|
||||
int i;
|
||||
|
||||
savefile->WriteInt( started );
|
||||
savefile->WriteInt( nextTriggerTime );
|
||||
savefile->WriteFX( fxEffect );
|
||||
savefile->WriteString( systemName );
|
||||
|
||||
savefile->WriteInt( actions.Num() );
|
||||
|
||||
for ( i = 0; i < actions.Num(); i++ ) {
|
||||
|
||||
if ( actions[i].lightDefHandle >= 0 ) {
|
||||
savefile->WriteBool( true );
|
||||
savefile->WriteRenderLight( actions[i].renderLight );
|
||||
} else {
|
||||
savefile->WriteBool( false );
|
||||
}
|
||||
|
||||
if ( actions[i].modelDefHandle >= 0 ) {
|
||||
savefile->WriteBool( true );
|
||||
savefile->WriteRenderEntity( actions[i].renderEntity );
|
||||
} else {
|
||||
savefile->WriteBool( false );
|
||||
}
|
||||
|
||||
savefile->WriteFloat( actions[i].delay );
|
||||
savefile->WriteInt( actions[i].start );
|
||||
savefile->WriteBool( actions[i].soundStarted );
|
||||
savefile->WriteBool( actions[i].shakeStarted );
|
||||
savefile->WriteBool( actions[i].decalDropped );
|
||||
savefile->WriteBool( actions[i].launched );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEntityFx::Restore
|
||||
================
|
||||
*/
|
||||
void idEntityFx::Restore( idRestoreGame *savefile ) {
|
||||
int i;
|
||||
int num;
|
||||
bool hasObject;
|
||||
|
||||
savefile->ReadInt( started );
|
||||
savefile->ReadInt( nextTriggerTime );
|
||||
savefile->ReadFX( fxEffect );
|
||||
savefile->ReadString( systemName );
|
||||
|
||||
savefile->ReadInt( num );
|
||||
|
||||
actions.SetNum( num );
|
||||
for ( i = 0; i < num; i++ ) {
|
||||
|
||||
savefile->ReadBool( hasObject );
|
||||
if ( hasObject ) {
|
||||
savefile->ReadRenderLight( actions[i].renderLight );
|
||||
actions[i].lightDefHandle = gameRenderWorld->AddLightDef( &actions[i].renderLight );
|
||||
} else {
|
||||
memset( &actions[i].renderLight, 0, sizeof( renderLight_t ) );
|
||||
actions[i].lightDefHandle = -1;
|
||||
}
|
||||
|
||||
savefile->ReadBool( hasObject );
|
||||
if ( hasObject ) {
|
||||
savefile->ReadRenderEntity( actions[i].renderEntity );
|
||||
actions[i].modelDefHandle = gameRenderWorld->AddEntityDef( &actions[i].renderEntity );
|
||||
} else {
|
||||
memset( &actions[i].renderEntity, 0, sizeof( renderEntity_t ) );
|
||||
actions[i].modelDefHandle = -1;
|
||||
}
|
||||
|
||||
savefile->ReadFloat( actions[i].delay );
|
||||
|
||||
// let the FX regenerate the particleSystem
|
||||
actions[i].particleSystem = -1;
|
||||
|
||||
savefile->ReadInt( actions[i].start );
|
||||
savefile->ReadBool( actions[i].soundStarted );
|
||||
savefile->ReadBool( actions[i].shakeStarted );
|
||||
savefile->ReadBool( actions[i].decalDropped );
|
||||
savefile->ReadBool( actions[i].launched );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEntityFx::Setup
|
||||
================
|
||||
*/
|
||||
void idEntityFx::Setup( const char *fx ) {
|
||||
|
||||
if ( started >= 0 ) {
|
||||
return; // already started
|
||||
}
|
||||
|
||||
// early during MP Spawn() with no information. wait till we ReadFromSnapshot for more
|
||||
if ( common->IsClient() && ( !fx || fx[0] == '\0' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
systemName = fx;
|
||||
started = 0;
|
||||
|
||||
fxEffect = static_cast<const idDeclFX *>( declManager->FindType( DECL_FX, systemName.c_str() ) );
|
||||
|
||||
if ( fxEffect ) {
|
||||
idFXLocalAction localAction;
|
||||
|
||||
memset( &localAction, 0, sizeof( idFXLocalAction ) );
|
||||
|
||||
actions.AssureSize( fxEffect->events.Num(), localAction );
|
||||
|
||||
for( int i = 0; i<fxEffect->events.Num(); i++ ) {
|
||||
const idFXSingleAction& fxaction = fxEffect->events[i];
|
||||
|
||||
idFXLocalAction& laction = actions[i];
|
||||
if ( fxaction.random1 || fxaction.random2 ) {
|
||||
laction.delay = fxaction.random1 + gameLocal.random.RandomFloat() * ( fxaction.random2 - fxaction.random1 );
|
||||
} else {
|
||||
laction.delay = fxaction.delay;
|
||||
}
|
||||
laction.start = -1;
|
||||
laction.lightDefHandle = -1;
|
||||
laction.modelDefHandle = -1;
|
||||
laction.particleSystem = -1;
|
||||
laction.shakeStarted = false;
|
||||
laction.decalDropped = false;
|
||||
laction.launched = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEntityFx::EffectName
|
||||
================
|
||||
*/
|
||||
const char *idEntityFx::EffectName() {
|
||||
return fxEffect ? fxEffect->GetName() : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEntityFx::Joint
|
||||
================
|
||||
*/
|
||||
const char *idEntityFx::Joint() {
|
||||
return fxEffect ? fxEffect->joint.c_str() : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEntityFx::CleanUp
|
||||
================
|
||||
*/
|
||||
void idEntityFx::CleanUp() {
|
||||
if ( !fxEffect ) {
|
||||
return;
|
||||
}
|
||||
for( int i = 0; i < fxEffect->events.Num(); i++ ) {
|
||||
const idFXSingleAction& fxaction = fxEffect->events[i];
|
||||
idFXLocalAction& laction = actions[i];
|
||||
CleanUpSingleAction( fxaction, laction );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEntityFx::CleanUpSingleAction
|
||||
================
|
||||
*/
|
||||
void idEntityFx::CleanUpSingleAction( const idFXSingleAction& fxaction, idFXLocalAction& laction ) {
|
||||
if ( laction.lightDefHandle != -1 && fxaction.sibling == -1 && fxaction.type != FX_ATTACHLIGHT ) {
|
||||
gameRenderWorld->FreeLightDef( laction.lightDefHandle );
|
||||
laction.lightDefHandle = -1;
|
||||
}
|
||||
if ( laction.modelDefHandle != -1 && fxaction.sibling == -1 && fxaction.type != FX_ATTACHENTITY ) {
|
||||
gameRenderWorld->FreeEntityDef( laction.modelDefHandle );
|
||||
laction.modelDefHandle = -1;
|
||||
}
|
||||
laction.start = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEntityFx::Start
|
||||
================
|
||||
*/
|
||||
void idEntityFx::Start( int time ) {
|
||||
if ( !fxEffect ) {
|
||||
return;
|
||||
}
|
||||
started = time;
|
||||
for( int i = 0; i < fxEffect->events.Num(); i++ ) {
|
||||
idFXLocalAction& laction = actions[i];
|
||||
laction.start = time;
|
||||
laction.soundStarted = false;
|
||||
laction.shakeStarted = false;
|
||||
laction.particleSystem = -1;
|
||||
laction.decalDropped = false;
|
||||
laction.launched = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEntityFx::Stop
|
||||
================
|
||||
*/
|
||||
void idEntityFx::Stop() {
|
||||
CleanUp();
|
||||
started = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEntityFx::Duration
|
||||
================
|
||||
*/
|
||||
const int idEntityFx::Duration() {
|
||||
int max = 0;
|
||||
|
||||
if ( !fxEffect ) {
|
||||
return max;
|
||||
}
|
||||
for( int i = 0; i < fxEffect->events.Num(); i++ ) {
|
||||
const idFXSingleAction& fxaction = fxEffect->events[i];
|
||||
int d = ( fxaction.delay + fxaction.duration ) * 1000.0f;
|
||||
if ( d > max ) {
|
||||
max = d;
|
||||
}
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
idEntityFx::Done
|
||||
================
|
||||
*/
|
||||
const bool idEntityFx::Done() {
|
||||
if (started > 0 && gameLocal.time > started + Duration()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEntityFx::ApplyFade
|
||||
================
|
||||
*/
|
||||
void idEntityFx::ApplyFade( const idFXSingleAction& fxaction, idFXLocalAction& laction, const int time, const int actualStart ) {
|
||||
if ( fxaction.fadeInTime || fxaction.fadeOutTime ) {
|
||||
float fadePct = (float)( time - actualStart ) / ( 1000.0f * ( ( fxaction.fadeInTime != 0 ) ? fxaction.fadeInTime : fxaction.fadeOutTime ) );
|
||||
if (fadePct > 1.0) {
|
||||
fadePct = 1.0;
|
||||
}
|
||||
if ( laction.modelDefHandle != -1 ) {
|
||||
laction.renderEntity.shaderParms[SHADERPARM_RED] = (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct;
|
||||
laction.renderEntity.shaderParms[SHADERPARM_GREEN] = (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct;
|
||||
laction.renderEntity.shaderParms[SHADERPARM_BLUE] = (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct;
|
||||
|
||||
gameRenderWorld->UpdateEntityDef( laction.modelDefHandle, &laction.renderEntity );
|
||||
}
|
||||
if ( laction.lightDefHandle != -1 ) {
|
||||
laction.renderLight.shaderParms[SHADERPARM_RED] = fxaction.lightColor.x * ( (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct );
|
||||
laction.renderLight.shaderParms[SHADERPARM_GREEN] = fxaction.lightColor.y * ( (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct );
|
||||
laction.renderLight.shaderParms[SHADERPARM_BLUE] = fxaction.lightColor.z * ( (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct );
|
||||
|
||||
gameRenderWorld->UpdateLightDef( laction.lightDefHandle, &laction.renderLight );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEntityFx::Run
|
||||
================
|
||||
*/
|
||||
void idEntityFx::Run( int time ) {
|
||||
int ieff, j;
|
||||
idEntity *ent = NULL;
|
||||
const idDict *projectileDef = NULL;
|
||||
idProjectile *projectile = NULL;
|
||||
|
||||
if ( !fxEffect ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for( ieff = 0; ieff < fxEffect->events.Num(); ieff++ ) {
|
||||
const idFXSingleAction& fxaction = fxEffect->events[ieff];
|
||||
idFXLocalAction& laction = actions[ieff];
|
||||
|
||||
//
|
||||
// if we're currently done with this one
|
||||
//
|
||||
if ( laction.start == -1 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// see if it's delayed
|
||||
//
|
||||
if ( laction.delay ) {
|
||||
if ( laction.start + (time - laction.start) < laction.start + (laction.delay * 1000) ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// each event can have it's own delay and restart
|
||||
//
|
||||
int actualStart = laction.delay ? laction.start + (int)( laction.delay * 1000 ) : laction.start;
|
||||
float pct = (float)( time - actualStart ) / (1000 * fxaction.duration );
|
||||
if ( pct >= 1.0f ) {
|
||||
laction.start = -1;
|
||||
float totalDelay = 0.0f;
|
||||
if ( fxaction.restart ) {
|
||||
if ( fxaction.random1 || fxaction.random2 ) {
|
||||
totalDelay = fxaction.random1 + gameLocal.random.RandomFloat() * (fxaction.random2 - fxaction.random1);
|
||||
} else {
|
||||
totalDelay = fxaction.delay;
|
||||
}
|
||||
laction.delay = totalDelay;
|
||||
laction.start = time;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( fxaction.fire.Length() ) {
|
||||
for( j = 0; j < fxEffect->events.Num(); j++ ) {
|
||||
if ( fxEffect->events[j].name.Icmp( fxaction.fire ) == 0 ) {
|
||||
actions[j].delay = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
idFXLocalAction *useAction;
|
||||
if ( fxaction.sibling == -1 ) {
|
||||
useAction = &laction;
|
||||
} else {
|
||||
useAction = &actions[fxaction.sibling];
|
||||
}
|
||||
assert( useAction );
|
||||
|
||||
switch( fxaction.type ) {
|
||||
case FX_ATTACHLIGHT:
|
||||
case FX_LIGHT: {
|
||||
if ( useAction->lightDefHandle == -1 ) {
|
||||
if ( fxaction.type == FX_LIGHT ) {
|
||||
memset( &useAction->renderLight, 0, sizeof( renderLight_t ) );
|
||||
useAction->renderLight.origin = GetPhysics()->GetOrigin() + fxaction.offset;
|
||||
useAction->renderLight.axis = GetPhysics()->GetAxis();
|
||||
useAction->renderLight.lightRadius[0] = fxaction.lightRadius;
|
||||
useAction->renderLight.lightRadius[1] = fxaction.lightRadius;
|
||||
useAction->renderLight.lightRadius[2] = fxaction.lightRadius;
|
||||
useAction->renderLight.shader = declManager->FindMaterial( fxaction.data, false );
|
||||
useAction->renderLight.shaderParms[ SHADERPARM_RED ] = fxaction.lightColor.x;
|
||||
useAction->renderLight.shaderParms[ SHADERPARM_GREEN ] = fxaction.lightColor.y;
|
||||
useAction->renderLight.shaderParms[ SHADERPARM_BLUE ] = fxaction.lightColor.z;
|
||||
useAction->renderLight.shaderParms[ SHADERPARM_TIMESCALE ] = 1.0f;
|
||||
useAction->renderLight.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( time );
|
||||
useAction->renderLight.referenceSound = refSound.referenceSound;
|
||||
useAction->renderLight.pointLight = true;
|
||||
if ( fxaction.noshadows ) {
|
||||
useAction->renderLight.noShadows = true;
|
||||
}
|
||||
useAction->lightDefHandle = gameRenderWorld->AddLightDef( &useAction->renderLight );
|
||||
}
|
||||
if ( fxaction.noshadows ) {
|
||||
for( j = 0; j < fxEffect->events.Num(); j++ ) {
|
||||
idFXLocalAction& laction2 = actions[j];
|
||||
if ( laction2.modelDefHandle != -1 ) {
|
||||
laction2.renderEntity.noShadow = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ApplyFade( fxaction, *useAction, time, actualStart );
|
||||
break;
|
||||
}
|
||||
case FX_SOUND: {
|
||||
if ( !useAction->soundStarted ) {
|
||||
useAction->soundStarted = true;
|
||||
const idSoundShader *shader = declManager->FindSound(fxaction.data);
|
||||
StartSoundShader( shader, SND_CHANNEL_ANY, 0, false, NULL );
|
||||
for( j = 0; j < fxEffect->events.Num(); j++ ) {
|
||||
idFXLocalAction& laction2 = actions[j];
|
||||
if ( laction2.lightDefHandle != -1 ) {
|
||||
laction2.renderLight.referenceSound = refSound.referenceSound;
|
||||
gameRenderWorld->UpdateLightDef( laction2.lightDefHandle, &laction2.renderLight );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FX_DECAL: {
|
||||
if ( !useAction->decalDropped ) {
|
||||
useAction->decalDropped = true;
|
||||
gameLocal.ProjectDecal( GetPhysics()->GetOrigin(), GetPhysics()->GetGravity(), 8.0f, true, fxaction.size, fxaction.data );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FX_SHAKE: {
|
||||
if ( !useAction->shakeStarted ) {
|
||||
idDict args;
|
||||
args.Clear();
|
||||
args.SetFloat( "kick_time", fxaction.shakeTime );
|
||||
args.SetFloat( "kick_amplitude", fxaction.shakeAmplitude );
|
||||
for ( j = 0; j < gameLocal.numClients; j++ ) {
|
||||
idPlayer *player = gameLocal.GetClientByNum( j );
|
||||
if ( player && ( player->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin() ).LengthSqr() < Square( fxaction.shakeDistance ) ) {
|
||||
if ( !common->IsMultiplayer() || !fxaction.shakeIgnoreMaster || GetBindMaster() != player ) {
|
||||
player->playerView.DamageImpulse( fxaction.offset, &args );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( fxaction.shakeImpulse != 0.0f && fxaction.shakeDistance != 0.0f ) {
|
||||
idEntity *ignore_ent = NULL;
|
||||
if ( common->IsMultiplayer() ) {
|
||||
ignore_ent = this;
|
||||
if ( fxaction.shakeIgnoreMaster ) {
|
||||
ignore_ent = GetBindMaster();
|
||||
}
|
||||
}
|
||||
// lookup the ent we are bound to?
|
||||
gameLocal.RadiusPush( GetPhysics()->GetOrigin(), fxaction.shakeDistance, fxaction.shakeImpulse, this, ignore_ent, 1.0f, true );
|
||||
}
|
||||
useAction->shakeStarted = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FX_ATTACHENTITY:
|
||||
case FX_PARTICLE:
|
||||
case FX_MODEL: {
|
||||
if ( useAction->modelDefHandle == -1 ) {
|
||||
memset( &useAction->renderEntity, 0, sizeof( renderEntity_t ) );
|
||||
useAction->renderEntity.origin = GetPhysics()->GetOrigin() + fxaction.offset;
|
||||
useAction->renderEntity.axis = (fxaction.explicitAxis) ? fxaction.axis : GetPhysics()->GetAxis();
|
||||
useAction->renderEntity.hModel = renderModelManager->FindModel( fxaction.data );
|
||||
useAction->renderEntity.shaderParms[ SHADERPARM_RED ] = 1.0f;
|
||||
useAction->renderEntity.shaderParms[ SHADERPARM_GREEN ] = 1.0f;
|
||||
useAction->renderEntity.shaderParms[ SHADERPARM_BLUE ] = 1.0f;
|
||||
useAction->renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( time );
|
||||
useAction->renderEntity.shaderParms[3] = 1.0f;
|
||||
useAction->renderEntity.shaderParms[5] = 0.0f;
|
||||
if ( useAction->renderEntity.hModel ) {
|
||||
useAction->renderEntity.bounds = useAction->renderEntity.hModel->Bounds( &useAction->renderEntity );
|
||||
}
|
||||
useAction->modelDefHandle = gameRenderWorld->AddEntityDef( &useAction->renderEntity );
|
||||
} else if ( fxaction.trackOrigin ) {
|
||||
useAction->renderEntity.origin = GetPhysics()->GetOrigin() + fxaction.offset;
|
||||
useAction->renderEntity.axis = fxaction.explicitAxis ? fxaction.axis : GetPhysics()->GetAxis();
|
||||
gameRenderWorld->UpdateEntityDef( useAction->modelDefHandle, &useAction->renderEntity );
|
||||
}
|
||||
ApplyFade( fxaction, *useAction, time, actualStart );
|
||||
break;
|
||||
}
|
||||
case FX_LAUNCH: {
|
||||
if ( common->IsClient() ) {
|
||||
// client never spawns entities outside of ClientReadSnapshot
|
||||
useAction->launched = true;
|
||||
break;
|
||||
}
|
||||
if ( !useAction->launched ) {
|
||||
useAction->launched = true;
|
||||
projectile = NULL;
|
||||
// FIXME: may need to cache this if it is slow
|
||||
projectileDef = gameLocal.FindEntityDefDict( fxaction.data, false );
|
||||
if ( !projectileDef ) {
|
||||
gameLocal.Warning( "projectile \'%s\' not found", fxaction.data.c_str() );
|
||||
} else {
|
||||
gameLocal.SpawnEntityDef( *projectileDef, &ent, false );
|
||||
if ( ent && ent->IsType( idProjectile::Type ) ) {
|
||||
projectile = ( idProjectile * )ent;
|
||||
projectile->Create( this, GetPhysics()->GetOrigin(), GetPhysics()->GetAxis()[0] );
|
||||
projectile->Launch( GetPhysics()->GetOrigin(), GetPhysics()->GetAxis()[0], vec3_origin );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FX_SHOCKWAVE: {
|
||||
if ( common->IsClient() ) {
|
||||
useAction->shakeStarted = true;
|
||||
break;
|
||||
}
|
||||
if ( !useAction->shakeStarted ) {
|
||||
idStr shockDefName;
|
||||
useAction->shakeStarted = true;
|
||||
|
||||
shockDefName = fxaction.data;
|
||||
if ( !shockDefName.Length() ) {
|
||||
shockDefName = "func_shockwave";
|
||||
}
|
||||
|
||||
projectileDef = gameLocal.FindEntityDefDict( shockDefName, false );
|
||||
if ( !projectileDef ) {
|
||||
gameLocal.Warning( "shockwave \'%s\' not found", shockDefName.c_str() );
|
||||
} else {
|
||||
gameLocal.SpawnEntityDef( *projectileDef, &ent );
|
||||
ent->SetOrigin( GetPhysics()->GetOrigin() + fxaction.offset );
|
||||
ent->PostEventMS( &EV_Remove, ent->spawnArgs.GetInt( "duration" ) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEntityFx::idEntityFx
|
||||
================
|
||||
*/
|
||||
idEntityFx::idEntityFx() {
|
||||
fxEffect = NULL;
|
||||
started = -1;
|
||||
nextTriggerTime = -1;
|
||||
fl.networkSync = true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEntityFx::~idEntityFx
|
||||
================
|
||||
*/
|
||||
idEntityFx::~idEntityFx() {
|
||||
CleanUp();
|
||||
fxEffect = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEntityFx::Spawn
|
||||
================
|
||||
*/
|
||||
void idEntityFx::Spawn() {
|
||||
|
||||
if ( g_skipFX.GetBool() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char *fx;
|
||||
nextTriggerTime = 0;
|
||||
fxEffect = NULL;
|
||||
if ( spawnArgs.GetString( "fx", "", &fx ) ) {
|
||||
systemName = fx;
|
||||
}
|
||||
if ( !spawnArgs.GetBool( "triggered" ) ) {
|
||||
Setup( fx );
|
||||
if ( spawnArgs.GetBool( "test" ) || spawnArgs.GetBool( "start" ) || spawnArgs.GetFloat ( "restart" ) ) {
|
||||
PostEventMS( &EV_Activate, 0, this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEntityFx::Think
|
||||
|
||||
Clears any visual fx started when {item,mob,player} was spawned
|
||||
================
|
||||
*/
|
||||
void idEntityFx::Think() {
|
||||
if ( g_skipFX.GetBool() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( thinkFlags & TH_THINK ) {
|
||||
Run( gameLocal.time );
|
||||
}
|
||||
|
||||
RunPhysics();
|
||||
Present();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEntityFx::Event_ClearFx
|
||||
|
||||
Clears any visual fx started when item(mob) was spawned
|
||||
================
|
||||
*/
|
||||
void idEntityFx::Event_ClearFx() {
|
||||
|
||||
if ( g_skipFX.GetBool() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
Stop();
|
||||
CleanUp();
|
||||
BecomeInactive( TH_THINK );
|
||||
|
||||
if ( spawnArgs.GetBool("test") ) {
|
||||
PostEventMS( &EV_Activate, 0, this );
|
||||
} else {
|
||||
if ( spawnArgs.GetFloat( "restart" ) || !spawnArgs.GetBool( "triggered")) {
|
||||
float rest = spawnArgs.GetFloat( "restart", "0" );
|
||||
if ( rest == 0.0f ) {
|
||||
PostEventSec( &EV_Remove, 0.1f );
|
||||
} else {
|
||||
rest *= gameLocal.random.RandomFloat();
|
||||
PostEventSec( &EV_Activate, rest, this );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEntityFx::Event_Trigger
|
||||
================
|
||||
*/
|
||||
void idEntityFx::Event_Trigger( idEntity *activator ) {
|
||||
|
||||
if ( g_skipFX.GetBool() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
float fxActionDelay;
|
||||
const char *fx;
|
||||
|
||||
if ( gameLocal.time < nextTriggerTime ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( spawnArgs.GetString( "fx", "", &fx) ) {
|
||||
Setup( fx );
|
||||
Start( gameLocal.time );
|
||||
PostEventMS( &EV_Fx_KillFx, Duration() );
|
||||
BecomeActive( TH_THINK );
|
||||
}
|
||||
|
||||
fxActionDelay = spawnArgs.GetFloat( "fxActionDelay" );
|
||||
if ( fxActionDelay != 0.0f ) {
|
||||
nextTriggerTime = gameLocal.time + SEC2MS( fxActionDelay );
|
||||
} else {
|
||||
// prevent multiple triggers on same frame
|
||||
nextTriggerTime = gameLocal.time + 1;
|
||||
}
|
||||
PostEventSec( &EV_Fx_Action, fxActionDelay, activator );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
idEntityFx::StartFx
|
||||
================
|
||||
*/
|
||||
idEntityFx *idEntityFx::StartFx( const char *fx, const idVec3 *useOrigin, const idMat3 *useAxis, idEntity *ent, bool bind ) {
|
||||
|
||||
if ( g_skipFX.GetBool() || !fx || !*fx ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
idDict args;
|
||||
args.SetBool( "start", true );
|
||||
args.Set( "fx", fx );
|
||||
idEntityFx *nfx = static_cast<idEntityFx *>( gameLocal.SpawnEntityType( idEntityFx::Type, &args ) );
|
||||
if ( nfx->Joint() && *nfx->Joint() ) {
|
||||
nfx->BindToJoint( ent, nfx->Joint(), true );
|
||||
nfx->SetOrigin( vec3_origin );
|
||||
} else {
|
||||
nfx->SetOrigin( (useOrigin) ? *useOrigin : ent->GetPhysics()->GetOrigin() );
|
||||
nfx->SetAxis( (useAxis) ? *useAxis : ent->GetPhysics()->GetAxis() );
|
||||
}
|
||||
|
||||
if ( bind ) {
|
||||
// never bind to world spawn
|
||||
if ( ent != gameLocal.world ) {
|
||||
nfx->Bind( ent, true );
|
||||
}
|
||||
}
|
||||
nfx->Show();
|
||||
return nfx;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
idEntityFx::WriteToSnapshot
|
||||
=================
|
||||
*/
|
||||
void idEntityFx::WriteToSnapshot( idBitMsg &msg ) const {
|
||||
GetPhysics()->WriteToSnapshot( msg );
|
||||
WriteBindToSnapshot( msg );
|
||||
msg.WriteLong( ( fxEffect != NULL ) ? gameLocal.ServerRemapDecl( -1, DECL_FX, fxEffect->Index() ) : -1 );
|
||||
msg.WriteLong( started );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
idEntityFx::ReadFromSnapshot
|
||||
=================
|
||||
*/
|
||||
void idEntityFx::ReadFromSnapshot( const idBitMsg &msg ) {
|
||||
int fx_index, start_time, max_lapse;
|
||||
|
||||
GetPhysics()->ReadFromSnapshot( msg );
|
||||
ReadBindFromSnapshot( msg );
|
||||
fx_index = gameLocal.ClientRemapDecl( DECL_FX, msg.ReadLong() );
|
||||
start_time = msg.ReadLong();
|
||||
|
||||
if ( fx_index != -1 && start_time > 0 && !fxEffect && started < 0 ) {
|
||||
spawnArgs.GetInt( "effect_lapse", "1000", max_lapse );
|
||||
if ( gameLocal.time - start_time > max_lapse ) {
|
||||
// too late, skip the effect completely
|
||||
started = 0;
|
||||
return;
|
||||
}
|
||||
const idDeclFX *fx = static_cast<const idDeclFX *>( declManager->DeclByIndex( DECL_FX, fx_index ) );
|
||||
if ( !fx ) {
|
||||
gameLocal.Error( "FX at index %d not found", fx_index );
|
||||
}
|
||||
fxEffect = fx;
|
||||
Setup( fx->GetName() );
|
||||
Start( start_time );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
idEntityFx::ClientThink
|
||||
=================
|
||||
*/
|
||||
void idEntityFx::ClientThink( const int curTime, const float fraction, const bool predict ) {
|
||||
|
||||
if ( gameLocal.isNewFrame ) {
|
||||
Run( gameLocal.serverTime );
|
||||
}
|
||||
|
||||
InterpolatePhysics( fraction );
|
||||
Present();
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
idEntityFx::ClientPredictionThink
|
||||
=================
|
||||
*/
|
||||
void idEntityFx::ClientPredictionThink() {
|
||||
if ( gameLocal.isNewFrame ) {
|
||||
Run( gameLocal.time );
|
||||
}
|
||||
RunPhysics();
|
||||
Present();
|
||||
}
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTeleporter
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
CLASS_DECLARATION( idEntityFx, idTeleporter )
|
||||
EVENT( EV_Fx_Action, idTeleporter::Event_DoAction )
|
||||
END_CLASS
|
||||
|
||||
/*
|
||||
================
|
||||
idTeleporter::Event_DoAction
|
||||
================
|
||||
*/
|
||||
void idTeleporter::Event_DoAction( idEntity *activator ) {
|
||||
float angle;
|
||||
|
||||
angle = spawnArgs.GetFloat( "angle" );
|
||||
idAngles a( 0, spawnArgs.GetFloat( "angle" ), 0 );
|
||||
activator->Teleport( GetPhysics()->GetOrigin(), a, NULL );
|
||||
}
|
||||
107
neo/d3xp/Fx.h
Normal file
107
neo/d3xp/Fx.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_FX_H__
|
||||
#define __GAME_FX_H__
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Special effects.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
renderLight_t renderLight; // light presented to the renderer
|
||||
qhandle_t lightDefHandle; // handle to renderer light def
|
||||
renderEntity_t renderEntity; // used to present a model to the renderer
|
||||
int modelDefHandle; // handle to static renderer model
|
||||
float delay;
|
||||
int particleSystem;
|
||||
int start;
|
||||
bool soundStarted;
|
||||
bool shakeStarted;
|
||||
bool decalDropped;
|
||||
bool launched;
|
||||
} idFXLocalAction;
|
||||
|
||||
class idEntityFx : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idEntityFx );
|
||||
|
||||
idEntityFx();
|
||||
virtual ~idEntityFx();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void Think();
|
||||
void Setup( const char *fx );
|
||||
void Run( int time );
|
||||
void Start( int time );
|
||||
void Stop();
|
||||
const int Duration();
|
||||
const char * EffectName();
|
||||
const char * Joint();
|
||||
const bool Done();
|
||||
|
||||
virtual void WriteToSnapshot( idBitMsg &msg ) const;
|
||||
virtual void ReadFromSnapshot( const idBitMsg &msg );
|
||||
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
|
||||
virtual void ClientPredictionThink();
|
||||
|
||||
static idEntityFx * StartFx( const char *fx, const idVec3 *useOrigin, const idMat3 *useAxis, idEntity *ent, bool bind );
|
||||
|
||||
protected:
|
||||
void Event_Trigger( idEntity *activator );
|
||||
void Event_ClearFx();
|
||||
|
||||
void CleanUp();
|
||||
void CleanUpSingleAction( const idFXSingleAction& fxaction, idFXLocalAction& laction );
|
||||
void ApplyFade( const idFXSingleAction& fxaction, idFXLocalAction& laction, const int time, const int actualStart );
|
||||
|
||||
int started;
|
||||
int nextTriggerTime;
|
||||
const idDeclFX * fxEffect; // GetFX() should be called before using fxEffect as a pointer
|
||||
idList<idFXLocalAction, TAG_FX> actions;
|
||||
idStr systemName;
|
||||
};
|
||||
|
||||
class idTeleporter : public idEntityFx {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTeleporter );
|
||||
|
||||
private:
|
||||
// teleporters to this location
|
||||
void Event_DoAction( idEntity *activator );
|
||||
};
|
||||
|
||||
#endif /* !__GAME_FX_H__ */
|
||||
2
neo/d3xp/Game.def
Normal file
2
neo/d3xp/Game.def
Normal file
@@ -0,0 +1,2 @@
|
||||
EXPORTS
|
||||
GetGameAPI
|
||||
343
neo/d3xp/Game.h
Normal file
343
neo/d3xp/Game.h
Normal file
@@ -0,0 +1,343 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_H__
|
||||
#define __GAME_H__
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Public game interface with methods to run the game.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
// default scripts
|
||||
#define SCRIPT_DEFAULTDEFS "script/doom_defs.script"
|
||||
#define SCRIPT_DEFAULT "script/doom_main.script"
|
||||
#define SCRIPT_DEFAULTFUNC "doom_main"
|
||||
|
||||
struct gameReturn_t {
|
||||
|
||||
gameReturn_t() :
|
||||
syncNextGameFrame( false ),
|
||||
vibrationLow( 0 ),
|
||||
vibrationHigh( 0 ) {
|
||||
|
||||
}
|
||||
|
||||
char sessionCommand[MAX_STRING_CHARS]; // "map", "disconnect", "victory", etc
|
||||
bool syncNextGameFrame; // used when cinematics are skipped to prevent session from simulating several game frames to
|
||||
// keep the game time in sync with real time
|
||||
int vibrationLow;
|
||||
int vibrationHigh;
|
||||
};
|
||||
|
||||
#define TIME_GROUP1 0
|
||||
#define TIME_GROUP2 1
|
||||
|
||||
class idGame {
|
||||
public:
|
||||
virtual ~idGame() {}
|
||||
|
||||
// Initialize the game for the first time.
|
||||
virtual void Init() = 0;
|
||||
|
||||
// Shut down the entire game.
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
// Sets the serverinfo at map loads and when it changes.
|
||||
virtual void SetServerInfo( const idDict &serverInfo ) = 0;
|
||||
|
||||
// Gets the serverinfo, common calls this before saving the game
|
||||
virtual const idDict & GetServerInfo() = 0;
|
||||
|
||||
// Interpolated server time
|
||||
virtual void SetServerGameTimeMs( const int time ) = 0;
|
||||
|
||||
// Interpolated server time
|
||||
virtual int GetServerGameTimeMs() const = 0;
|
||||
|
||||
virtual int GetSSEndTime() const = 0;
|
||||
virtual int GetSSStartTime() const = 0;
|
||||
|
||||
// common calls this before moving the single player game to a new level.
|
||||
virtual const idDict & GetPersistentPlayerInfo( int clientNum ) = 0;
|
||||
|
||||
// common calls this right before a new level is loaded.
|
||||
virtual void SetPersistentPlayerInfo( int clientNum, const idDict &playerInfo ) = 0;
|
||||
|
||||
// Loads a map and spawns all the entities.
|
||||
virtual void InitFromNewMap( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, int gameMode, int randseed ) = 0;
|
||||
|
||||
// Loads a map from a savegame file.
|
||||
virtual bool InitFromSaveGame( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, idFile *saveGameFile, idFile *stringTableFile, int saveGameVersion ) = 0;
|
||||
|
||||
// Saves the current game state, common may have written some data to the file already.
|
||||
virtual void SaveGame( idFile *saveGameFile, idFile *stringTableFile ) = 0;
|
||||
|
||||
// Pulls the current player location from the game information
|
||||
virtual void GetSaveGameDetails( idSaveGameDetails & gameDetails ) = 0;
|
||||
|
||||
// Shut down the current map.
|
||||
virtual void MapShutdown() = 0;
|
||||
|
||||
// Caches media referenced from in key/value pairs in the given dictionary.
|
||||
virtual void CacheDictionaryMedia( const idDict *dict ) = 0;
|
||||
|
||||
virtual void Preload( const idPreloadManifest &manifest ) = 0;
|
||||
|
||||
// Runs a game frame, may return a session command for level changing, etc
|
||||
virtual void RunFrame( idUserCmdMgr & cmdMgr, gameReturn_t & gameReturn ) = 0;
|
||||
|
||||
// Makes rendering and sound system calls to display for a given clientNum.
|
||||
virtual bool Draw( int clientNum ) = 0;
|
||||
|
||||
virtual bool HandlePlayerGuiEvent( const sysEvent_t * ev ) = 0;
|
||||
|
||||
// Writes a snapshot of the server game state.
|
||||
virtual void ServerWriteSnapshot( idSnapShot & ss ) = 0;
|
||||
|
||||
// Processes a reliable message
|
||||
virtual void ProcessReliableMessage( int clientNum, int type, const idBitMsg &msg ) = 0;
|
||||
|
||||
virtual void SetInterpolation( const float fraction, const int serverGameMS, const int ssStartTime, const int ssEndTime ) = 0;
|
||||
|
||||
// Reads a snapshot and updates the client game state.
|
||||
virtual void ClientReadSnapshot( const idSnapShot & ss ) = 0;
|
||||
|
||||
// Runs prediction on entities at the client.
|
||||
virtual void ClientRunFrame( idUserCmdMgr & cmdMgr, bool lastPredictFrame, gameReturn_t & ret ) = 0;
|
||||
|
||||
// Used to manage divergent time-lines
|
||||
virtual int GetTimeGroupTime( int timeGroup ) = 0;
|
||||
|
||||
// Returns a list of available multiplayer game modes
|
||||
virtual int GetMPGameModes( const char *** gameModes, const char *** gameModesDisplay ) = 0;
|
||||
|
||||
// Returns a summary of stats for a given client
|
||||
virtual void GetClientStats( int clientNum, char *data, const int len ) = 0;
|
||||
|
||||
virtual bool IsInGame() const = 0;
|
||||
|
||||
// Get the player entity number for a network peer.
|
||||
virtual int MapPeerToClient( int peer ) const = 0;
|
||||
|
||||
// Get the player entity number of the local player.
|
||||
virtual int GetLocalClientNum() const = 0;
|
||||
|
||||
// compute an angle offset to be applied to the given client's aim
|
||||
virtual void GetAimAssistAngles( idAngles & angles ) = 0;
|
||||
virtual float GetAimAssistSensitivity() = 0;
|
||||
|
||||
// Release the mouse when the PDA is open
|
||||
virtual bool IsPDAOpen() const = 0;
|
||||
virtual bool IsPlayerChatting() const = 0;
|
||||
|
||||
// Creates leaderboards for each map/mode defined.
|
||||
virtual void Leaderboards_Init() = 0;
|
||||
virtual void Leaderboards_Shutdown() = 0;
|
||||
|
||||
// MAIN MENU FUNCTIONS
|
||||
virtual bool InhibitControls() = 0;
|
||||
virtual void Shell_Init( const char * filename, idSoundWorld * sw ) = 0;
|
||||
virtual void Shell_Cleanup() = 0;
|
||||
virtual void Shell_CreateMenu( bool inGame ) = 0;
|
||||
virtual void Shell_ClosePause() = 0;
|
||||
virtual void Shell_Show( bool show ) = 0;
|
||||
virtual bool Shell_IsActive() const = 0;
|
||||
virtual bool Shell_HandleGuiEvent( const sysEvent_t * sev ) = 0;
|
||||
virtual void Shell_Render() = 0;
|
||||
virtual void Shell_ResetMenu() = 0;
|
||||
virtual void Shell_SyncWithSession() = 0;
|
||||
virtual void Shell_UpdateSavedGames() = 0;
|
||||
virtual void Shell_SetCanContinue( bool valid ) = 0;
|
||||
virtual void Shell_UpdateClientCountdown( int countdown ) = 0;
|
||||
virtual void Shell_UpdateLeaderboard( const idLeaderboardCallback * callback ) = 0;
|
||||
virtual void Shell_SetGameComplete() = 0;
|
||||
};
|
||||
|
||||
extern idGame * game;
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Public game interface with methods for in-game editing.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
idSoundEmitter * referenceSound; // this is the interface to the sound system, created
|
||||
// with idSoundWorld::AllocSoundEmitter() when needed
|
||||
idVec3 origin;
|
||||
int listenerId; // SSF_PRIVATE_SOUND only plays if == listenerId from PlaceListener
|
||||
// no spatialization will be performed if == listenerID
|
||||
const idSoundShader * shader; // this really shouldn't be here, it is a holdover from single channel behavior
|
||||
float diversity; // 0.0 to 1.0 value used to select which
|
||||
// samples in a multi-sample list from the shader are used
|
||||
bool waitfortrigger; // don't start it at spawn time
|
||||
soundShaderParms_t parms; // override volume, flags, etc
|
||||
} refSound_t;
|
||||
|
||||
enum {
|
||||
TEST_PARTICLE_MODEL = 0,
|
||||
TEST_PARTICLE_IMPACT,
|
||||
TEST_PARTICLE_MUZZLE,
|
||||
TEST_PARTICLE_FLIGHT,
|
||||
TEST_PARTICLE_SELECTED
|
||||
};
|
||||
|
||||
class idEntity;
|
||||
class idMD5Anim;
|
||||
|
||||
// FIXME: this interface needs to be reworked but it properly separates code for the time being
|
||||
class idGameEdit {
|
||||
public:
|
||||
virtual ~idGameEdit() {}
|
||||
|
||||
// These are the canonical idDict to parameter parsing routines used by both the game and tools.
|
||||
virtual void ParseSpawnArgsToRenderLight( const idDict *args, renderLight_t *renderLight );
|
||||
virtual void ParseSpawnArgsToRenderEntity( const idDict *args, renderEntity_t *renderEntity );
|
||||
virtual void ParseSpawnArgsToRefSound( const idDict *args, refSound_t *refSound );
|
||||
|
||||
// Animation system calls for non-game based skeletal rendering.
|
||||
virtual idRenderModel * ANIM_GetModelFromEntityDef( const char *classname );
|
||||
virtual const idVec3 &ANIM_GetModelOffsetFromEntityDef( const char *classname );
|
||||
virtual idRenderModel * ANIM_GetModelFromEntityDef( const idDict *args );
|
||||
virtual idRenderModel * ANIM_GetModelFromName( const char *modelName );
|
||||
virtual const idMD5Anim * ANIM_GetAnimFromEntityDef( const char *classname, const char *animname );
|
||||
virtual int ANIM_GetNumAnimsFromEntityDef( const idDict *args );
|
||||
virtual const char * ANIM_GetAnimNameFromEntityDef( const idDict *args, int animNum );
|
||||
virtual const idMD5Anim * ANIM_GetAnim( const char *fileName );
|
||||
virtual int ANIM_GetLength( const idMD5Anim *anim );
|
||||
virtual int ANIM_GetNumFrames( const idMD5Anim *anim );
|
||||
virtual void ANIM_CreateAnimFrame( const idRenderModel *model, const idMD5Anim *anim, int numJoints, idJointMat *frame, int time, const idVec3 &offset, bool remove_origin_offset );
|
||||
virtual idRenderModel * ANIM_CreateMeshForAnim( idRenderModel *model, const char *classname, const char *animname, int frame, bool remove_origin_offset );
|
||||
|
||||
// Articulated Figure calls for AF editor and Radiant.
|
||||
virtual bool AF_SpawnEntity( const char *fileName );
|
||||
virtual void AF_UpdateEntities( const char *fileName );
|
||||
virtual void AF_UndoChanges();
|
||||
virtual idRenderModel * AF_CreateMesh( const idDict &args, idVec3 &meshOrigin, idMat3 &meshAxis, bool &poseIsSet );
|
||||
|
||||
|
||||
// Entity selection.
|
||||
virtual void ClearEntitySelection();
|
||||
virtual int GetSelectedEntities( idEntity *list[], int max );
|
||||
virtual void AddSelectedEntity( idEntity *ent );
|
||||
|
||||
// Selection methods
|
||||
virtual void TriggerSelected();
|
||||
|
||||
// Entity defs and spawning.
|
||||
virtual const idDict * FindEntityDefDict( const char *name, bool makeDefault = true ) const;
|
||||
virtual void SpawnEntityDef( const idDict &args, idEntity **ent );
|
||||
virtual idEntity * FindEntity( const char *name ) const;
|
||||
virtual const char * GetUniqueEntityName( const char *classname ) const;
|
||||
|
||||
// Entity methods.
|
||||
virtual void EntityGetOrigin( idEntity *ent, idVec3 &org ) const;
|
||||
virtual void EntityGetAxis( idEntity *ent, idMat3 &axis ) const;
|
||||
virtual void EntitySetOrigin( idEntity *ent, const idVec3 &org );
|
||||
virtual void EntitySetAxis( idEntity *ent, const idMat3 &axis );
|
||||
virtual void EntityTranslate( idEntity *ent, const idVec3 &org );
|
||||
virtual const idDict * EntityGetSpawnArgs( idEntity *ent ) const;
|
||||
virtual void EntityUpdateChangeableSpawnArgs( idEntity *ent, const idDict *dict );
|
||||
virtual void EntityChangeSpawnArgs( idEntity *ent, const idDict *newArgs );
|
||||
virtual void EntityUpdateVisuals( idEntity *ent );
|
||||
virtual void EntitySetModel( idEntity *ent, const char *val );
|
||||
virtual void EntityStopSound( idEntity *ent );
|
||||
virtual void EntityDelete( idEntity *ent );
|
||||
virtual void EntitySetColor( idEntity *ent, const idVec3 color );
|
||||
|
||||
// Player methods.
|
||||
virtual bool PlayerIsValid() const;
|
||||
virtual void PlayerGetOrigin( idVec3 &org ) const;
|
||||
virtual void PlayerGetAxis( idMat3 &axis ) const;
|
||||
virtual void PlayerGetViewAngles( idAngles &angles ) const;
|
||||
virtual void PlayerGetEyePosition( idVec3 &org ) const;
|
||||
|
||||
// In game map editing support.
|
||||
virtual const idDict * MapGetEntityDict( const char *name ) const;
|
||||
virtual void MapSave( const char *path = NULL ) const;
|
||||
virtual void MapSetEntityKeyVal( const char *name, const char *key, const char *val ) const ;
|
||||
virtual void MapCopyDictToEntity( const char *name, const idDict *dict ) const;
|
||||
virtual int MapGetUniqueMatchingKeyVals( const char *key, const char *list[], const int max ) const;
|
||||
virtual void MapAddEntity( const idDict *dict ) const;
|
||||
virtual int MapGetEntitiesMatchingClassWithString( const char *classname, const char *match, const char *list[], const int max ) const;
|
||||
virtual void MapRemoveEntity( const char *name ) const;
|
||||
virtual void MapEntityTranslate( const char *name, const idVec3 &v ) const;
|
||||
|
||||
};
|
||||
|
||||
extern idGameEdit * gameEdit;
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Game API.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
const int GAME_API_VERSION = 8;
|
||||
|
||||
typedef struct {
|
||||
|
||||
int version; // API version
|
||||
idSys * sys; // non-portable system services
|
||||
idCommon * common; // common
|
||||
idCmdSystem * cmdSystem; // console command system
|
||||
idCVarSystem * cvarSystem; // console variable system
|
||||
idFileSystem * fileSystem; // file system
|
||||
idRenderSystem * renderSystem; // render system
|
||||
idSoundSystem * soundSystem; // sound system
|
||||
idRenderModelManager * renderModelManager; // render model manager
|
||||
idUserInterfaceManager * uiManager; // user interface manager
|
||||
idDeclManager * declManager; // declaration manager
|
||||
idAASFileManager * AASFileManager; // AAS file manager
|
||||
idCollisionModelManager * collisionModelManager; // collision model manager
|
||||
|
||||
} gameImport_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
int version; // API version
|
||||
idGame * game; // interface to run the game
|
||||
idGameEdit * gameEdit; // interface for in-game editing
|
||||
|
||||
} gameExport_t;
|
||||
|
||||
extern "C" {
|
||||
typedef gameExport_t * (*GetGameAPI_t)( gameImport_t *import );
|
||||
}
|
||||
|
||||
#endif /* !__GAME_H__ */
|
||||
1142
neo/d3xp/GameEdit.cpp
Normal file
1142
neo/d3xp/GameEdit.cpp
Normal file
File diff suppressed because it is too large
Load Diff
119
neo/d3xp/GameEdit.h
Normal file
119
neo/d3xp/GameEdit.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_EDIT_H__
|
||||
#define __GAME_EDIT_H__
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Ingame cursor.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idCursor3D : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idCursor3D );
|
||||
|
||||
idCursor3D();
|
||||
~idCursor3D();
|
||||
|
||||
void Spawn();
|
||||
void Present();
|
||||
void Think();
|
||||
|
||||
idForce_Drag drag;
|
||||
idVec3 draggedPosition;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Allows entities to be dragged through the world with physics.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idDragEntity {
|
||||
public:
|
||||
idDragEntity();
|
||||
~idDragEntity();
|
||||
|
||||
void Clear();
|
||||
void Update( idPlayer *player );
|
||||
void SetSelected( idEntity *ent );
|
||||
idEntity * GetSelected() const { return selected.GetEntity(); }
|
||||
void DeleteSelected();
|
||||
void BindSelected();
|
||||
void UnbindSelected();
|
||||
|
||||
private:
|
||||
idEntityPtr<idEntity> dragEnt; // entity being dragged
|
||||
jointHandle_t joint; // joint being dragged
|
||||
int id; // id of body being dragged
|
||||
idVec3 localEntityPoint; // dragged point in entity space
|
||||
idVec3 localPlayerPoint; // dragged point in player space
|
||||
idStr bodyName; // name of the body being dragged
|
||||
idCursor3D * cursor; // cursor entity
|
||||
idEntityPtr<idEntity> selected; // last dragged entity
|
||||
|
||||
void StopDrag();
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Handles ingame entity editing.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
typedef struct selectedTypeInfo_s {
|
||||
idTypeInfo *typeInfo;
|
||||
idStr textKey;
|
||||
} selectedTypeInfo_t;
|
||||
|
||||
class idEditEntities {
|
||||
public:
|
||||
idEditEntities();
|
||||
bool SelectEntity( const idVec3 &origin, const idVec3 &dir, const idEntity *skip );
|
||||
void AddSelectedEntity( idEntity *ent );
|
||||
void RemoveSelectedEntity( idEntity *ent );
|
||||
void ClearSelectedEntities();
|
||||
void DisplayEntities();
|
||||
bool EntityIsSelectable( idEntity *ent, idVec4 *color = NULL, idStr *text = NULL );
|
||||
private:
|
||||
int nextSelectTime;
|
||||
idList<selectedTypeInfo_t> selectableEntityClasses;
|
||||
idList<idEntity *> selectedEntities;
|
||||
};
|
||||
|
||||
#endif /* !__GAME_EDIT_H__ */
|
||||
5085
neo/d3xp/Game_local.cpp
Normal file
5085
neo/d3xp/Game_local.cpp
Normal file
File diff suppressed because it is too large
Load Diff
819
neo/d3xp/Game_local.h
Normal file
819
neo/d3xp/Game_local.h
Normal file
@@ -0,0 +1,819 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_LOCAL_H__
|
||||
#define __GAME_LOCAL_H__
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Local implementation of the public game interface.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
#ifdef ID_DEBUG_UNINITIALIZED_MEMORY
|
||||
// This is real evil but allows the code to inspect arbitrary class variables.
|
||||
#define private public
|
||||
#define protected public
|
||||
#endif
|
||||
|
||||
extern idRenderWorld * gameRenderWorld;
|
||||
extern idSoundWorld * gameSoundWorld;
|
||||
|
||||
// the "gameversion" client command will print this plus compile date
|
||||
#define GAME_VERSION "baseDOOM-1"
|
||||
|
||||
// classes used by idGameLocal
|
||||
class idEntity;
|
||||
class idActor;
|
||||
class idPlayer;
|
||||
class idCamera;
|
||||
class idWorldspawn;
|
||||
class idTestModel;
|
||||
class idAAS;
|
||||
class idAI;
|
||||
class idSmokeParticles;
|
||||
class idEntityFx;
|
||||
class idTypeInfo;
|
||||
class idProgram;
|
||||
class idThread;
|
||||
class idEditEntities;
|
||||
class idLocationEntity;
|
||||
class idMenuHandler_Shell;
|
||||
|
||||
const int MAX_CLIENTS = MAX_PLAYERS;
|
||||
const int MAX_CLIENTS_IN_PVS = MAX_CLIENTS >> 3;
|
||||
const int GENTITYNUM_BITS = 12;
|
||||
const int MAX_GENTITIES = 1 << GENTITYNUM_BITS;
|
||||
const int ENTITYNUM_NONE = MAX_GENTITIES - 1;
|
||||
const int ENTITYNUM_WORLD = MAX_GENTITIES - 2;
|
||||
const int ENTITYNUM_MAX_NORMAL = MAX_GENTITIES - 2;
|
||||
const int ENTITYNUM_FIRST_NON_REPLICATED = ENTITYNUM_MAX_NORMAL - 256;
|
||||
|
||||
//============================================================================
|
||||
|
||||
void gameError( const char *fmt, ... );
|
||||
|
||||
#include "gamesys/Event.h"
|
||||
#include "gamesys/Class.h"
|
||||
#include "gamesys/SysCvar.h"
|
||||
#include "gamesys/SysCmds.h"
|
||||
#include "gamesys/SaveGame.h"
|
||||
|
||||
#include "script/Script_Program.h"
|
||||
|
||||
#include "anim/Anim.h"
|
||||
|
||||
#include "ai/AAS.h"
|
||||
|
||||
#include "physics/Clip.h"
|
||||
#include "physics/Push.h"
|
||||
|
||||
#include "Pvs.h"
|
||||
#include "Leaderboards.h"
|
||||
#include "MultiplayerGame.h"
|
||||
|
||||
|
||||
class idWeapon;
|
||||
|
||||
//============================================================================
|
||||
|
||||
const int MAX_GAME_MESSAGE_SIZE = 8192;
|
||||
const int MAX_ENTITY_STATE_SIZE = 512;
|
||||
const int ENTITY_PVS_SIZE = ((MAX_GENTITIES+31)>>5);
|
||||
const int NUM_RENDER_PORTAL_BITS = idMath::BitsForInteger( PS_BLOCK_ALL );
|
||||
|
||||
const int MAX_EVENT_PARAM_SIZE = 128;
|
||||
|
||||
typedef struct entityNetEvent_s {
|
||||
int spawnId;
|
||||
int event;
|
||||
int time;
|
||||
int paramsSize;
|
||||
byte paramsBuf[MAX_EVENT_PARAM_SIZE];
|
||||
struct entityNetEvent_s *next;
|
||||
struct entityNetEvent_s *prev;
|
||||
} entityNetEvent_t;
|
||||
|
||||
enum {
|
||||
GAME_RELIABLE_MESSAGE_SYNCEDCVARS,
|
||||
GAME_RELIABLE_MESSAGE_SPAWN_PLAYER,
|
||||
GAME_RELIABLE_MESSAGE_CHAT,
|
||||
GAME_RELIABLE_MESSAGE_TCHAT,
|
||||
GAME_RELIABLE_MESSAGE_SOUND_EVENT,
|
||||
GAME_RELIABLE_MESSAGE_SOUND_INDEX,
|
||||
GAME_RELIABLE_MESSAGE_DB,
|
||||
GAME_RELIABLE_MESSAGE_DROPWEAPON,
|
||||
GAME_RELIABLE_MESSAGE_RESTART,
|
||||
GAME_RELIABLE_MESSAGE_TOURNEYLINE,
|
||||
GAME_RELIABLE_MESSAGE_VCHAT,
|
||||
GAME_RELIABLE_MESSAGE_STARTSTATE,
|
||||
GAME_RELIABLE_MESSAGE_WARMUPTIME,
|
||||
GAME_RELIABLE_MESSAGE_SPECTATE,
|
||||
GAME_RELIABLE_MESSAGE_EVENT,
|
||||
GAME_RELIABLE_MESSAGE_LOBBY_COUNTDOWN,
|
||||
GAME_RELIABLE_MESSAGE_RESPAWN_AVAILABLE, // Used just to show clients the respawn text on the hud.
|
||||
GAME_RELIABLE_MESSAGE_MATCH_STARTED_TIME,
|
||||
GAME_RELIABLE_MESSAGE_ACHIEVEMENT_UNLOCK,
|
||||
GAME_RELIABLE_MESSAGE_CLIENT_HITSCAN_HIT
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
GAMESTATE_UNINITIALIZED, // prior to Init being called
|
||||
GAMESTATE_NOMAP, // no map loaded
|
||||
GAMESTATE_STARTUP, // inside InitFromNewMap(). spawning map entities.
|
||||
GAMESTATE_ACTIVE, // normal gameplay
|
||||
GAMESTATE_SHUTDOWN // inside MapShutdown(). clearing memory.
|
||||
} gameState_t;
|
||||
|
||||
typedef struct {
|
||||
idEntity *ent;
|
||||
int dist;
|
||||
int team;
|
||||
} spawnSpot_t;
|
||||
|
||||
//============================================================================
|
||||
|
||||
class idEventQueue {
|
||||
public:
|
||||
typedef enum {
|
||||
OUTOFORDER_IGNORE,
|
||||
OUTOFORDER_DROP,
|
||||
OUTOFORDER_SORT
|
||||
} outOfOrderBehaviour_t;
|
||||
|
||||
idEventQueue() : start( NULL ), end( NULL ) {}
|
||||
|
||||
entityNetEvent_t * Alloc();
|
||||
void Free( entityNetEvent_t *event );
|
||||
void Shutdown();
|
||||
|
||||
void Init();
|
||||
void Enqueue( entityNetEvent_t* event, outOfOrderBehaviour_t oooBehaviour );
|
||||
entityNetEvent_t * Dequeue();
|
||||
entityNetEvent_t * RemoveLast();
|
||||
|
||||
entityNetEvent_t * Start() { return start; }
|
||||
|
||||
private:
|
||||
entityNetEvent_t * start;
|
||||
entityNetEvent_t * end;
|
||||
idBlockAlloc<entityNetEvent_t,32> eventAllocator;
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
|
||||
template< class type >
|
||||
class idEntityPtr {
|
||||
public:
|
||||
idEntityPtr();
|
||||
|
||||
// save games
|
||||
void Save( idSaveGame *savefile ) const; // archives object for save game file
|
||||
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
|
||||
|
||||
idEntityPtr & operator=( const type * ent );
|
||||
idEntityPtr & operator=( const idEntityPtr & ep );
|
||||
|
||||
bool operator==( const idEntityPtr & ep ) { return spawnId == ep.spawnId; }
|
||||
|
||||
type * operator->() const { return GetEntity(); }
|
||||
operator type * () const { return GetEntity(); }
|
||||
|
||||
// synchronize entity pointers over the network
|
||||
int GetSpawnId() const { return spawnId; }
|
||||
bool SetSpawnId( int id );
|
||||
bool UpdateSpawnId();
|
||||
|
||||
bool IsValid() const;
|
||||
type * GetEntity() const;
|
||||
int GetEntityNum() const;
|
||||
|
||||
private:
|
||||
int spawnId;
|
||||
};
|
||||
|
||||
struct timeState_t {
|
||||
int time;
|
||||
int previousTime;
|
||||
int realClientTime;
|
||||
|
||||
void Set( int t, int pt, int rct ) { time = t; previousTime = pt; realClientTime = rct; };
|
||||
void Get( int & t, int & pt, int & rct ) { t = time; pt = previousTime; rct = realClientTime; };
|
||||
void Save( idSaveGame *savefile ) const { savefile->WriteInt( time ); savefile->WriteInt( previousTime ); savefile->WriteInt( realClientTime ); }
|
||||
void Restore( idRestoreGame *savefile ) { savefile->ReadInt( time ); savefile->ReadInt( previousTime ); savefile->ReadInt( realClientTime ); }
|
||||
};
|
||||
|
||||
enum slowmoState_t {
|
||||
SLOWMO_STATE_OFF,
|
||||
SLOWMO_STATE_RAMPUP,
|
||||
SLOWMO_STATE_ON,
|
||||
SLOWMO_STATE_RAMPDOWN
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
|
||||
class idGameLocal : public idGame {
|
||||
public:
|
||||
|
||||
int previousServerTime; // time in msec of last frame on the server
|
||||
int serverTime; // in msec. ( on the client ) the server time. ( on the server ) the actual game time.
|
||||
idDict serverInfo; // all the tunable parameters, like numclients, etc
|
||||
int numClients; // pulled from serverInfo and verified
|
||||
idArray< lobbyUserID_t, MAX_CLIENTS > lobbyUserIDs; // Maps from a client (player) number to a lobby user
|
||||
idDict persistentPlayerInfo[MAX_CLIENTS];
|
||||
idEntity * entities[MAX_GENTITIES];// index to entities
|
||||
int spawnIds[MAX_GENTITIES];// for use in idEntityPtr
|
||||
idArray< int, 2 > firstFreeEntityIndex; // first free index in the entities array. [0] for replicated entities, [1] for non-replicated
|
||||
int num_entities; // current number <= MAX_GENTITIES
|
||||
idHashIndex entityHash; // hash table to quickly find entities by name
|
||||
idWorldspawn * world; // world entity
|
||||
idLinkList<idEntity> spawnedEntities; // all spawned entities
|
||||
idLinkList<idEntity> activeEntities; // all thinking entities (idEntity::thinkFlags != 0)
|
||||
idLinkList<idEntity> aimAssistEntities; // all aim Assist entities
|
||||
int numEntitiesToDeactivate;// number of entities that became inactive in current frame
|
||||
bool sortPushers; // true if active lists needs to be reordered to place pushers at the front
|
||||
bool sortTeamMasters; // true if active lists needs to be reordered to place physics team masters before their slaves
|
||||
idDict persistentLevelInfo; // contains args that are kept around between levels
|
||||
|
||||
// can be used to automatically effect every material in the world that references globalParms
|
||||
float globalShaderParms[ MAX_GLOBAL_SHADER_PARMS ];
|
||||
|
||||
idRandom random; // random number generator used throughout the game
|
||||
|
||||
idProgram program; // currently loaded script and data space
|
||||
idThread * frameCommandThread;
|
||||
|
||||
idClip clip; // collision detection
|
||||
idPush push; // geometric pushing
|
||||
idPVS pvs; // potential visible set
|
||||
|
||||
idTestModel * testmodel; // for development testing of models
|
||||
idEntityFx * testFx; // for development testing of fx
|
||||
|
||||
idStr sessionCommand; // a target_sessionCommand can set this to return something to the session
|
||||
|
||||
idMultiplayerGame mpGame; // handles rules for standard dm
|
||||
|
||||
idSmokeParticles * smokeParticles; // global smoke trails
|
||||
idEditEntities * editEntities; // in game editing
|
||||
|
||||
bool inCinematic; // game is playing cinematic (player controls frozen)
|
||||
|
||||
int framenum;
|
||||
int time; // in msec
|
||||
int previousTime; // time in msec of last frame
|
||||
|
||||
int vacuumAreaNum; // -1 if level doesn't have any outside areas
|
||||
|
||||
gameType_t gameType;
|
||||
idLinkList<idEntity> snapshotEntities; // entities from the last snapshot
|
||||
int realClientTime; // real client time
|
||||
bool isNewFrame; // true if this is a new game frame, not a rerun due to prediction
|
||||
float clientSmoothing; // smoothing of other clients in the view
|
||||
int entityDefBits; // bits required to store an entity def number
|
||||
|
||||
static const char * sufaceTypeNames[ MAX_SURFACE_TYPES ]; // text names for surface types
|
||||
|
||||
idEntityPtr<idEntity> lastGUIEnt; // last entity with a GUI, used by Cmd_NextGUI_f
|
||||
int lastGUI; // last GUI on the lastGUIEnt
|
||||
|
||||
idEntityPtr<idPlayer> playerActivateFragChamber; // The player that activated the frag chamber
|
||||
|
||||
idEntityPtr<idEntity> portalSkyEnt;
|
||||
bool portalSkyActive;
|
||||
|
||||
void SetPortalSkyEnt( idEntity *ent );
|
||||
bool IsPortalSkyAcive();
|
||||
|
||||
timeState_t fast;
|
||||
timeState_t slow;
|
||||
int selectedGroup;
|
||||
|
||||
slowmoState_t slowmoState;
|
||||
float slowmoScale;
|
||||
|
||||
bool quickSlowmoReset;
|
||||
|
||||
virtual void SelectTimeGroup( int timeGroup );
|
||||
virtual int GetTimeGroupTime( int timeGroup );
|
||||
|
||||
void ComputeSlowScale();
|
||||
void RunTimeGroup2( idUserCmdMgr & userCmdMgr );
|
||||
|
||||
void ResetSlowTimeVars();
|
||||
void QuickSlowmoReset();
|
||||
|
||||
|
||||
void Tokenize( idStrList &out, const char *in );
|
||||
|
||||
// ---------------------- Public idGame Interface -------------------
|
||||
|
||||
idGameLocal();
|
||||
|
||||
virtual void Init();
|
||||
virtual void Shutdown();
|
||||
virtual void SetServerInfo( const idDict &serverInfo );
|
||||
virtual const idDict & GetServerInfo();
|
||||
|
||||
virtual const idDict & GetPersistentPlayerInfo( int clientNum );
|
||||
virtual void SetPersistentPlayerInfo( int clientNum, const idDict &playerInfo );
|
||||
virtual void InitFromNewMap( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, int gameType, int randSeed );
|
||||
virtual bool InitFromSaveGame( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, idFile * saveGameFile, idFile * stringTableFile, int saveGameVersion );
|
||||
virtual void SaveGame( idFile *saveGameFile, idFile *stringTableFile );
|
||||
virtual void GetSaveGameDetails( idSaveGameDetails & gameDetails );
|
||||
virtual void MapShutdown();
|
||||
virtual void CacheDictionaryMedia( const idDict *dict );
|
||||
virtual void Preload( const idPreloadManifest &manifest );
|
||||
virtual void RunFrame( idUserCmdMgr & cmdMgr, gameReturn_t & gameReturn );
|
||||
void RunAllUserCmdsForPlayer( idUserCmdMgr & cmdMgr, const int playerNumber );
|
||||
void RunSingleUserCmd( usercmd_t & cmd, idPlayer & player );
|
||||
void RunEntityThink( idEntity & ent, idUserCmdMgr & userCmdMgr );
|
||||
virtual bool Draw( int clientNum );
|
||||
virtual bool HandlePlayerGuiEvent( const sysEvent_t * ev );
|
||||
virtual void ServerWriteSnapshot( idSnapShot & ss );
|
||||
virtual void ProcessReliableMessage( int clientNum, int type, const idBitMsg &msg );
|
||||
virtual void ClientReadSnapshot( const idSnapShot & ss );
|
||||
virtual void ClientRunFrame( idUserCmdMgr & cmdMgr, bool lastPredictFrame, gameReturn_t & ret );
|
||||
void BuildReturnValue( gameReturn_t & ret );
|
||||
|
||||
virtual int GetMPGameModes( const char *** gameModes, const char *** gameModesDisplay );
|
||||
|
||||
virtual void GetClientStats( int clientNum, char *data, const int len );
|
||||
|
||||
virtual bool IsInGame() const { return GameState() == GAMESTATE_ACTIVE; }
|
||||
|
||||
virtual int MapPeerToClient( int peer ) const;
|
||||
virtual int GetLocalClientNum() const;
|
||||
|
||||
virtual void GetAimAssistAngles( idAngles & angles );
|
||||
virtual float GetAimAssistSensitivity();
|
||||
|
||||
// ---------------------- Public idGameLocal Interface -------------------
|
||||
|
||||
void Printf( VERIFY_FORMAT_STRING const char *fmt, ... ) const;
|
||||
void DPrintf( VERIFY_FORMAT_STRING const char *fmt, ... ) const;
|
||||
void Warning( VERIFY_FORMAT_STRING const char *fmt, ... ) const;
|
||||
void DWarning( VERIFY_FORMAT_STRING const char *fmt, ... ) const;
|
||||
void Error( VERIFY_FORMAT_STRING const char *fmt, ... ) const;
|
||||
|
||||
// Initializes all map variables common to both save games and spawned games
|
||||
void LoadMap( const char *mapName, int randseed );
|
||||
|
||||
void LocalMapRestart();
|
||||
void MapRestart();
|
||||
static void MapRestart_f( const idCmdArgs &args );
|
||||
|
||||
idMapFile * GetLevelMap();
|
||||
const char * GetMapName() const;
|
||||
|
||||
int NumAAS() const;
|
||||
idAAS * GetAAS( int num ) const;
|
||||
idAAS * GetAAS( const char *name ) const;
|
||||
void SetAASAreaState( const idBounds &bounds, const int areaContents, bool closed );
|
||||
aasHandle_t AddAASObstacle( const idBounds &bounds );
|
||||
void RemoveAASObstacle( const aasHandle_t handle );
|
||||
void RemoveAllAASObstacles();
|
||||
|
||||
bool CheatsOk( bool requirePlayer = true );
|
||||
gameState_t GameState() const;
|
||||
idEntity * SpawnEntityType( const idTypeInfo &classdef, const idDict *args = NULL, bool bIsClientReadSnapshot = false );
|
||||
bool SpawnEntityDef( const idDict &args, idEntity **ent = NULL, bool setDefaults = true );
|
||||
int GetSpawnId( const idEntity *ent ) const;
|
||||
|
||||
const idDeclEntityDef * FindEntityDef( const char *name, bool makeDefault = true ) const;
|
||||
const idDict * FindEntityDefDict( const char *name, bool makeDefault = true ) const;
|
||||
|
||||
void RegisterEntity( idEntity *ent, int forceSpawnId, const idDict & spawnArgsToCopy );
|
||||
void UnregisterEntity( idEntity *ent );
|
||||
const idDict & GetSpawnArgs() const { return spawnArgs; }
|
||||
|
||||
bool RequirementMet( idEntity *activator, const idStr &requires, int removeItem );
|
||||
|
||||
void AlertAI( idEntity *ent );
|
||||
idActor * GetAlertEntity();
|
||||
|
||||
bool InPlayerPVS( idEntity *ent ) const;
|
||||
bool InPlayerConnectedArea( idEntity *ent ) const;
|
||||
pvsHandle_t GetPlayerPVS() { return playerPVS; };
|
||||
|
||||
void SetCamera( idCamera *cam );
|
||||
idCamera * GetCamera() const;
|
||||
void CalcFov( float base_fov, float &fov_x, float &fov_y ) const;
|
||||
|
||||
void AddEntityToHash( const char *name, idEntity *ent );
|
||||
bool RemoveEntityFromHash( const char *name, idEntity *ent );
|
||||
int GetTargets( const idDict &args, idList< idEntityPtr<idEntity> > &list, const char *ref ) const;
|
||||
|
||||
// returns the master entity of a trace. for example, if the trace entity is the player's head, it will return the player.
|
||||
idEntity * GetTraceEntity( const trace_t &trace ) const;
|
||||
|
||||
static void ArgCompletion_EntityName( const idCmdArgs &args, void(*callback)( const char *s ) );
|
||||
idEntity * FindTraceEntity( idVec3 start, idVec3 end, const idTypeInfo &c, const idEntity *skip ) const;
|
||||
idEntity * FindEntity( const char *name ) const;
|
||||
idEntity * FindEntityUsingDef( idEntity *from, const char *match ) const;
|
||||
int EntitiesWithinRadius( const idVec3 org, float radius, idEntity **entityList, int maxCount ) const;
|
||||
|
||||
void KillBox( idEntity *ent, bool catch_teleport = false );
|
||||
void RadiusDamage( const idVec3 &origin, idEntity *inflictor, idEntity *attacker, idEntity *ignoreDamage, idEntity *ignorePush, const char *damageDefName, float dmgPower = 1.0f );
|
||||
void RadiusPush( const idVec3 &origin, const float radius, const float push, const idEntity *inflictor, const idEntity *ignore, float inflictorScale, const bool quake );
|
||||
void RadiusPushClipModel( const idVec3 &origin, const float push, const idClipModel *clipModel );
|
||||
|
||||
void ProjectDecal( const idVec3 &origin, const idVec3 &dir, float depth, bool parallel, float size, const char *material, float angle = 0 );
|
||||
void BloodSplat( const idVec3 &origin, const idVec3 &dir, float size, const char *material );
|
||||
|
||||
void CallFrameCommand( idEntity *ent, const function_t *frameCommand );
|
||||
void CallObjectFrameCommand( idEntity *ent, const char *frameCommand );
|
||||
|
||||
const idVec3 & GetGravity() const;
|
||||
|
||||
// added the following to assist licensees with merge issues
|
||||
int GetFrameNum() const { return framenum; };
|
||||
int GetTime() const { return time; };
|
||||
|
||||
int GetNextClientNum( int current ) const;
|
||||
idPlayer * GetClientByNum( int current ) const;
|
||||
|
||||
idPlayer * GetLocalPlayer() const;
|
||||
|
||||
void SpreadLocations();
|
||||
idLocationEntity * LocationForPoint( const idVec3 &point ); // May return NULL
|
||||
idEntity * SelectInitialSpawnPoint( idPlayer *player );
|
||||
|
||||
void SetPortalState( qhandle_t portal, int blockingBits );
|
||||
void SaveEntityNetworkEvent( const idEntity *ent, int event, const idBitMsg *msg );
|
||||
int ServerRemapDecl( int clientNum, declType_t type, int index );
|
||||
int ClientRemapDecl( declType_t type, int index );
|
||||
void SyncPlayersWithLobbyUsers( bool initial );
|
||||
void ServerWriteInitialReliableMessages( int clientNum, lobbyUserID_t lobbyUserID );
|
||||
void ServerSendNetworkSyncCvars();
|
||||
|
||||
virtual void SetInterpolation( const float fraction, const int serverGameMS, const int ssStartTime, const int ssEndTime );
|
||||
|
||||
void ServerProcessReliableMessage( int clientNum, int type, const idBitMsg &msg );
|
||||
void ClientProcessReliableMessage( int type, const idBitMsg &msg );
|
||||
|
||||
// Snapshot times - track exactly what times we are interpolating from and to
|
||||
int GetSSEndTime() const { return netInterpolationInfo.ssEndTime; }
|
||||
int GetSSStartTime() const { return netInterpolationInfo.ssStartTime; }
|
||||
|
||||
virtual void SetServerGameTimeMs( const int time );
|
||||
virtual int GetServerGameTimeMs() const;
|
||||
|
||||
idEntity * FindPredictedEntity( uint32 predictedKey, idTypeInfo * type );
|
||||
uint32 GeneratePredictionKey( idWeapon * weapon, idPlayer * playerAttacker, int overrideKey );
|
||||
|
||||
int GetLastClientUsercmdMilliseconds( int playerIndex ) const { return usercmdLastClientMilliseconds[ playerIndex ]; }
|
||||
|
||||
void SetGlobalMaterial( const idMaterial *mat );
|
||||
const idMaterial * GetGlobalMaterial();
|
||||
|
||||
void SetGibTime( int _time ) { nextGibTime = _time; };
|
||||
int GetGibTime() { return nextGibTime; };
|
||||
|
||||
virtual bool InhibitControls();
|
||||
virtual bool IsPDAOpen() const;
|
||||
virtual bool IsPlayerChatting() const;
|
||||
|
||||
// Creates leaderboards for each map/mode defined.
|
||||
virtual void Leaderboards_Init();
|
||||
virtual void Leaderboards_Shutdown();
|
||||
|
||||
// MAIN MENU FUNCTIONS
|
||||
virtual void Shell_Init( const char * filename, idSoundWorld * sw );
|
||||
virtual void Shell_Cleanup();
|
||||
virtual void Shell_Show( bool show );
|
||||
virtual void Shell_ClosePause();
|
||||
virtual void Shell_CreateMenu( bool inGame );
|
||||
virtual bool Shell_IsActive() const;
|
||||
virtual bool Shell_HandleGuiEvent( const sysEvent_t * sev );
|
||||
virtual void Shell_Render();
|
||||
virtual void Shell_ResetMenu();
|
||||
virtual void Shell_SyncWithSession() ;
|
||||
virtual void Shell_SetCanContinue( bool valid );
|
||||
virtual void Shell_UpdateSavedGames();
|
||||
virtual void Shell_UpdateClientCountdown( int countdown );
|
||||
virtual void Shell_UpdateLeaderboard( const idLeaderboardCallback * callback );
|
||||
virtual void Shell_SetGameComplete();
|
||||
|
||||
void Shell_ClearRepeater();
|
||||
|
||||
const char * GetMapFileName() { return mapFileName.c_str(); }
|
||||
|
||||
const char * GetMPPlayerDefName() const;
|
||||
|
||||
private:
|
||||
const static int INITIAL_SPAWN_COUNT = 1;
|
||||
|
||||
idStr mapFileName; // name of the map, empty string if no map loaded
|
||||
idMapFile * mapFile; // will be NULL during the game unless in-game editing is used
|
||||
bool mapCycleLoaded;
|
||||
|
||||
int spawnCount;
|
||||
int mapSpawnCount; // it's handy to know which entities are part of the map
|
||||
|
||||
idLocationEntity ** locationEntities; // for location names, etc
|
||||
|
||||
idCamera * camera;
|
||||
const idMaterial * globalMaterial; // for overriding everything
|
||||
|
||||
idList<idAAS *> aasList; // area system
|
||||
|
||||
idMenuHandler_Shell * shellHandler;
|
||||
|
||||
idStrList aasNames;
|
||||
|
||||
idEntityPtr<idActor> lastAIAlertEntity;
|
||||
int lastAIAlertTime;
|
||||
|
||||
idDict spawnArgs; // spawn args used during entity spawning FIXME: shouldn't be necessary anymore
|
||||
|
||||
pvsHandle_t playerPVS; // merged pvs of all players
|
||||
pvsHandle_t playerConnectedAreas; // all areas connected to any player area
|
||||
|
||||
idVec3 gravity; // global gravity vector
|
||||
gameState_t gamestate; // keeps track of whether we're spawning, shutting down, or normal gameplay
|
||||
bool influenceActive; // true when a phantasm is happening
|
||||
int nextGibTime;
|
||||
|
||||
idEventQueue eventQueue;
|
||||
idEventQueue savedEventQueue;
|
||||
|
||||
idStaticList<spawnSpot_t, MAX_GENTITIES> spawnSpots;
|
||||
idStaticList<idEntity *, MAX_GENTITIES> initialSpots;
|
||||
int currentInitialSpot;
|
||||
|
||||
idStaticList<spawnSpot_t, MAX_GENTITIES> teamSpawnSpots[2];
|
||||
idStaticList<idEntity *, MAX_GENTITIES> teamInitialSpots[2];
|
||||
int teamCurrentInitialSpot[2];
|
||||
|
||||
struct netInterpolationInfo_t { // Was in GameTimeManager.h in id5, needed common place to put this.
|
||||
netInterpolationInfo_t()
|
||||
: pct( 0.0f )
|
||||
, serverGameMs( 0 )
|
||||
, previousServerGameMs( 0 )
|
||||
, ssStartTime( 0 )
|
||||
, ssEndTime( 0 )
|
||||
{}
|
||||
float pct; // % of current interpolation
|
||||
int serverGameMs; // Interpolated server game time
|
||||
int previousServerGameMs; // last frame's interpolated server game time
|
||||
int ssStartTime; // Server time of old snapshot
|
||||
int ssEndTime; // Server time of next snapshot
|
||||
};
|
||||
|
||||
netInterpolationInfo_t netInterpolationInfo;
|
||||
|
||||
idDict newInfo;
|
||||
|
||||
idArray< int, MAX_PLAYERS > usercmdLastClientMilliseconds; // The latest client time the server has run.
|
||||
idArray< int, MAX_PLAYERS > lastCmdRunTimeOnClient;
|
||||
idArray< int, MAX_PLAYERS > lastCmdRunTimeOnServer;
|
||||
|
||||
void Clear();
|
||||
// returns true if the entity shouldn't be spawned at all in this game type or difficulty level
|
||||
bool InhibitEntitySpawn( idDict &spawnArgs );
|
||||
// spawn entities from the map file
|
||||
void SpawnMapEntities();
|
||||
// commons used by init, shutdown, and restart
|
||||
void MapPopulate();
|
||||
void MapClear( bool clearClients );
|
||||
|
||||
pvsHandle_t GetClientPVS( idPlayer *player, pvsType_t type );
|
||||
void SetupPlayerPVS();
|
||||
void FreePlayerPVS();
|
||||
void UpdateGravity();
|
||||
void SortActiveEntityList();
|
||||
void ShowTargets();
|
||||
void RunDebugInfo();
|
||||
|
||||
void InitScriptForMap();
|
||||
void SetScriptFPS( const float com_engineHz );
|
||||
void SpawnPlayer( int clientNum );
|
||||
|
||||
void InitConsoleCommands();
|
||||
void ShutdownConsoleCommands();
|
||||
|
||||
void InitAsyncNetwork();
|
||||
void ShutdownAsyncNetwork();
|
||||
void NetworkEventWarning( const entityNetEvent_t *event, VERIFY_FORMAT_STRING const char *fmt, ... );
|
||||
void ServerProcessEntityNetworkEventQueue();
|
||||
void ClientProcessEntityNetworkEventQueue();
|
||||
// call after any change to serverInfo. Will update various quick-access flags
|
||||
void UpdateServerInfoFlags();
|
||||
void RandomizeInitialSpawns();
|
||||
static int sortSpawnPoints( const void *ptr1, const void *ptr2 );
|
||||
|
||||
bool SimulateProjectiles();
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
|
||||
extern idGameLocal gameLocal;
|
||||
extern idAnimManager animationLib;
|
||||
|
||||
//============================================================================
|
||||
|
||||
class idGameError : public idException {
|
||||
public:
|
||||
idGameError( const char *text ) : idException( text ) {}
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
|
||||
template< class type >
|
||||
ID_INLINE idEntityPtr<type>::idEntityPtr() {
|
||||
spawnId = 0;
|
||||
}
|
||||
|
||||
template< class type >
|
||||
ID_INLINE void idEntityPtr<type>::Save( idSaveGame *savefile ) const {
|
||||
savefile->WriteInt( spawnId );
|
||||
}
|
||||
|
||||
template< class type >
|
||||
ID_INLINE void idEntityPtr<type>::Restore( idRestoreGame *savefile ) {
|
||||
savefile->ReadInt( spawnId );
|
||||
}
|
||||
|
||||
template< class type >
|
||||
ID_INLINE idEntityPtr<type> &idEntityPtr<type>::operator=( const type *ent ) {
|
||||
if ( ent == NULL ) {
|
||||
spawnId = 0;
|
||||
} else {
|
||||
spawnId = ( gameLocal.spawnIds[ent->entityNumber] << GENTITYNUM_BITS ) | ent->entityNumber;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< class type >
|
||||
ID_INLINE idEntityPtr< type > &idEntityPtr<type>::operator=( const idEntityPtr & ep ) {
|
||||
spawnId = ep.spawnId;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template< class type >
|
||||
ID_INLINE bool idEntityPtr<type>::SetSpawnId( int id ) {
|
||||
// the reason for this first check is unclear:
|
||||
// the function returning false may mean the spawnId is already set right, or the entity is missing
|
||||
if ( id == spawnId ) {
|
||||
return false;
|
||||
}
|
||||
if ( ( id >> GENTITYNUM_BITS ) == gameLocal.spawnIds[ id & ( ( 1 << GENTITYNUM_BITS ) - 1 ) ] ) {
|
||||
spawnId = id;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template< class type >
|
||||
ID_INLINE bool idEntityPtr<type>::IsValid() const {
|
||||
return ( gameLocal.spawnIds[ spawnId & ( ( 1 << GENTITYNUM_BITS ) - 1 ) ] == ( spawnId >> GENTITYNUM_BITS ) );
|
||||
}
|
||||
|
||||
template< class type >
|
||||
ID_INLINE type *idEntityPtr<type>::GetEntity() const {
|
||||
int entityNum = spawnId & ( ( 1 << GENTITYNUM_BITS ) - 1 );
|
||||
if ( ( gameLocal.spawnIds[ entityNum ] == ( spawnId >> GENTITYNUM_BITS ) ) ) {
|
||||
return static_cast<type *>( gameLocal.entities[ entityNum ] );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
template< class type >
|
||||
ID_INLINE int idEntityPtr<type>::GetEntityNum() const {
|
||||
return ( spawnId & ( ( 1 << GENTITYNUM_BITS ) - 1 ) );
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
//
|
||||
// these defines work for all startsounds from all entity types
|
||||
// make sure to change script/doom_defs.script if you add any channels, or change their order
|
||||
//
|
||||
typedef enum {
|
||||
SND_CHANNEL_ANY = SCHANNEL_ANY,
|
||||
SND_CHANNEL_VOICE = SCHANNEL_ONE,
|
||||
SND_CHANNEL_VOICE2,
|
||||
SND_CHANNEL_BODY,
|
||||
SND_CHANNEL_BODY2,
|
||||
SND_CHANNEL_BODY3,
|
||||
SND_CHANNEL_WEAPON,
|
||||
SND_CHANNEL_ITEM,
|
||||
SND_CHANNEL_HEART,
|
||||
SND_CHANNEL_PDA_AUDIO,
|
||||
SND_CHANNEL_PDA_VIDEO,
|
||||
SND_CHANNEL_DEMONIC,
|
||||
SND_CHANNEL_RADIO,
|
||||
|
||||
// internal use only. not exposed to script or framecommands.
|
||||
SND_CHANNEL_AMBIENT,
|
||||
SND_CHANNEL_DAMAGE
|
||||
} gameSoundChannel_t;
|
||||
|
||||
// content masks
|
||||
#define MASK_ALL (-1)
|
||||
#define MASK_SOLID (CONTENTS_SOLID)
|
||||
#define MASK_MONSTERSOLID (CONTENTS_SOLID|CONTENTS_MONSTERCLIP|CONTENTS_BODY)
|
||||
#define MASK_PLAYERSOLID (CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_BODY)
|
||||
#define MASK_DEADSOLID (CONTENTS_SOLID|CONTENTS_PLAYERCLIP)
|
||||
#define MASK_WATER (CONTENTS_WATER)
|
||||
#define MASK_OPAQUE (CONTENTS_OPAQUE)
|
||||
#define MASK_SHOT_RENDERMODEL (CONTENTS_SOLID|CONTENTS_RENDERMODEL)
|
||||
#define MASK_SHOT_BOUNDINGBOX (CONTENTS_SOLID|CONTENTS_BODY)
|
||||
|
||||
const float DEFAULT_GRAVITY = 1066.0f;
|
||||
#define DEFAULT_GRAVITY_STRING "1066"
|
||||
const idVec3 DEFAULT_GRAVITY_VEC3( 0, 0, -DEFAULT_GRAVITY );
|
||||
|
||||
const int CINEMATIC_SKIP_DELAY = SEC2MS( 2.0f );
|
||||
|
||||
//============================================================================
|
||||
|
||||
#include "physics/Force.h"
|
||||
#include "physics/Force_Constant.h"
|
||||
#include "physics/Force_Drag.h"
|
||||
#include "physics/Force_Grab.h"
|
||||
#include "physics/Force_Field.h"
|
||||
#include "physics/Force_Spring.h"
|
||||
#include "physics/Physics.h"
|
||||
#include "physics/Physics_Static.h"
|
||||
#include "physics/Physics_StaticMulti.h"
|
||||
#include "physics/Physics_Base.h"
|
||||
#include "physics/Physics_Actor.h"
|
||||
#include "physics/Physics_Monster.h"
|
||||
#include "physics/Physics_Player.h"
|
||||
#include "physics/Physics_Parametric.h"
|
||||
#include "physics/Physics_RigidBody.h"
|
||||
#include "physics/Physics_AF.h"
|
||||
|
||||
#include "SmokeParticles.h"
|
||||
|
||||
#include "Entity.h"
|
||||
#include "GameEdit.h"
|
||||
#include "Grabber.h"
|
||||
#include "AF.h"
|
||||
#include "IK.h"
|
||||
#include "AFEntity.h"
|
||||
#include "Misc.h"
|
||||
#include "Actor.h"
|
||||
#include "Projectile.h"
|
||||
#include "Weapon.h"
|
||||
#include "Light.h"
|
||||
#include "WorldSpawn.h"
|
||||
#include "Item.h"
|
||||
#include "PlayerView.h"
|
||||
#include "PlayerIcon.h"
|
||||
#include "Achievements.h"
|
||||
#include "AimAssist.h"
|
||||
#include "Player.h"
|
||||
#include "Mover.h"
|
||||
#include "Camera.h"
|
||||
#include "Moveable.h"
|
||||
#include "Target.h"
|
||||
#include "Trigger.h"
|
||||
#include "Sound.h"
|
||||
#include "Fx.h"
|
||||
#include "SecurityCamera.h"
|
||||
#include "BrittleFracture.h"
|
||||
|
||||
#include "ai/AI.h"
|
||||
#include "anim/Anim_Testmodel.h"
|
||||
|
||||
// menus
|
||||
#include "menus/MenuWidget.h"
|
||||
#include "menus/MenuScreen.h"
|
||||
#include "menus/MenuHandler.h"
|
||||
|
||||
#include "script/Script_Compiler.h"
|
||||
#include "script/Script_Interpreter.h"
|
||||
#include "script/Script_Thread.h"
|
||||
|
||||
#endif /* !__GAME_LOCAL_H__ */
|
||||
1328
neo/d3xp/Game_network.cpp
Normal file
1328
neo/d3xp/Game_network.cpp
Normal file
File diff suppressed because it is too large
Load Diff
739
neo/d3xp/Grabber.cpp
Normal file
739
neo/d3xp/Grabber.cpp
Normal file
@@ -0,0 +1,739 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#include "../idlib/precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
#include "Game_local.h"
|
||||
#include "Misc.h"
|
||||
|
||||
#define MAX_DRAG_TRACE_DISTANCE 384.0f
|
||||
#define TRACE_BOUNDS_SIZE 3.f
|
||||
#define HOLD_DISTANCE 72.f
|
||||
#define FIRING_DELAY 1000.0f
|
||||
#define DRAG_FAIL_LEN 64.f
|
||||
#define THROW_SCALE 1000
|
||||
#define MAX_PICKUP_VELOCITY 1500 * 1500
|
||||
#define MAX_PICKUP_SIZE 96
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Allows entities to be dragged through the world with physics.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
CLASS_DECLARATION( idEntity, idGrabber )
|
||||
END_CLASS
|
||||
|
||||
/*
|
||||
==============
|
||||
idGrabber::idGrabber
|
||||
==============
|
||||
*/
|
||||
idGrabber::idGrabber() {
|
||||
dragEnt = NULL;
|
||||
owner = NULL;
|
||||
beam = NULL;
|
||||
beamTarget = NULL;
|
||||
oldImpulseSequence = 0;
|
||||
shakeForceFlip = false;
|
||||
holdingAF = false;
|
||||
endTime = 0;
|
||||
lastFiredTime = -FIRING_DELAY;
|
||||
dragFailTime = 0;
|
||||
startDragTime = 0;
|
||||
warpId = -1;
|
||||
dragTraceDist = MAX_DRAG_TRACE_DISTANCE;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
idGrabber::~idGrabber
|
||||
==============
|
||||
*/
|
||||
idGrabber::~idGrabber() {
|
||||
StopDrag( true );
|
||||
if ( beam ) {
|
||||
delete beam;
|
||||
}
|
||||
if ( beamTarget ) {
|
||||
delete beamTarget;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
idGrabber::Save
|
||||
==============
|
||||
*/
|
||||
void idGrabber::Save( idSaveGame *savefile ) const {
|
||||
|
||||
dragEnt.Save( savefile );
|
||||
savefile->WriteStaticObject( drag );
|
||||
|
||||
savefile->WriteVec3( saveGravity );
|
||||
savefile->WriteInt( id );
|
||||
|
||||
savefile->WriteVec3( localPlayerPoint );
|
||||
|
||||
owner.Save( savefile );
|
||||
|
||||
savefile->WriteBool( holdingAF );
|
||||
savefile->WriteBool( shakeForceFlip );
|
||||
|
||||
savefile->WriteInt( endTime );
|
||||
savefile->WriteInt( lastFiredTime );
|
||||
savefile->WriteInt( dragFailTime );
|
||||
savefile->WriteInt( startDragTime );
|
||||
savefile->WriteFloat( dragTraceDist );
|
||||
savefile->WriteInt( savedContents );
|
||||
savefile->WriteInt( savedClipmask );
|
||||
|
||||
savefile->WriteObject( beam );
|
||||
savefile->WriteObject( beamTarget );
|
||||
|
||||
savefile->WriteInt( warpId );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
idGrabber::Restore
|
||||
==============
|
||||
*/
|
||||
void idGrabber::Restore( idRestoreGame *savefile ) {
|
||||
//Spawn the beams
|
||||
Initialize();
|
||||
|
||||
dragEnt.Restore( savefile );
|
||||
savefile->ReadStaticObject( drag );
|
||||
|
||||
savefile->ReadVec3( saveGravity );
|
||||
savefile->ReadInt( id );
|
||||
|
||||
// Restore the drag force's physics object
|
||||
if ( dragEnt.IsValid() ) {
|
||||
drag.SetPhysics( dragEnt.GetEntity()->GetPhysics(), id, dragEnt.GetEntity()->GetPhysics()->GetOrigin() );
|
||||
}
|
||||
|
||||
savefile->ReadVec3( localPlayerPoint );
|
||||
|
||||
owner.Restore( savefile );
|
||||
|
||||
savefile->ReadBool( holdingAF );
|
||||
savefile->ReadBool( shakeForceFlip );
|
||||
|
||||
savefile->ReadInt( endTime );
|
||||
savefile->ReadInt( lastFiredTime );
|
||||
savefile->ReadInt( dragFailTime );
|
||||
savefile->ReadInt( startDragTime );
|
||||
savefile->ReadFloat( dragTraceDist );
|
||||
savefile->ReadInt( savedContents );
|
||||
savefile->ReadInt( savedClipmask );
|
||||
|
||||
savefile->ReadObject( reinterpret_cast<idClass *&>(beam) );
|
||||
savefile->ReadObject( reinterpret_cast<idClass *&>(beamTarget) );
|
||||
|
||||
savefile->ReadInt( warpId );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
idGrabber::Initialize
|
||||
==============
|
||||
*/
|
||||
void idGrabber::Initialize() {
|
||||
if ( !common->IsMultiplayer() ) {
|
||||
idDict args;
|
||||
|
||||
if ( !beamTarget ) {
|
||||
args.SetVector( "origin", vec3_origin );
|
||||
args.SetBool( "start_off", true );
|
||||
beamTarget = ( idBeam * )gameLocal.SpawnEntityType( idBeam::Type, &args );
|
||||
}
|
||||
|
||||
if ( !beam ) {
|
||||
args.Clear();
|
||||
args.Set( "target", beamTarget->name.c_str() );
|
||||
args.SetVector( "origin", vec3_origin );
|
||||
args.SetBool( "start_off", true );
|
||||
args.Set( "width", "6" );
|
||||
args.Set( "skin", "textures/smf/flareSizeable" );
|
||||
args.Set( "_color", "0.0235 0.843 0.969 0.2" );
|
||||
beam = ( idBeam * )gameLocal.SpawnEntityType( idBeam::Type, &args );
|
||||
beam->SetShaderParm( 6, 1.0f );
|
||||
}
|
||||
|
||||
endTime = 0;
|
||||
dragTraceDist = MAX_DRAG_TRACE_DISTANCE;
|
||||
}
|
||||
else {
|
||||
beam = NULL;
|
||||
beamTarget = NULL;
|
||||
endTime = 0;
|
||||
dragTraceDist = MAX_DRAG_TRACE_DISTANCE;
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
idGrabber::SetDragDistance
|
||||
==============
|
||||
*/
|
||||
void idGrabber::SetDragDistance( float dist ) {
|
||||
dragTraceDist = dist;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
idGrabber::StartDrag
|
||||
==============
|
||||
*/
|
||||
void idGrabber::StartDrag( idEntity *grabEnt, int id ) {
|
||||
int clipModelId = id;
|
||||
idPlayer *thePlayer = owner.GetEntity();
|
||||
|
||||
holdingAF = false;
|
||||
dragFailTime = gameLocal.slow.time;
|
||||
startDragTime = gameLocal.slow.time;
|
||||
|
||||
oldImpulseSequence = thePlayer->usercmd.impulseSequence;
|
||||
|
||||
// set grabbed state for networking
|
||||
grabEnt->SetGrabbedState( true );
|
||||
|
||||
// This is the new object to drag around
|
||||
dragEnt = grabEnt;
|
||||
|
||||
// Show the beams!
|
||||
UpdateBeams();
|
||||
if ( beam ) {
|
||||
beam->Show();
|
||||
}
|
||||
if ( beamTarget ) {
|
||||
beamTarget->Show();
|
||||
}
|
||||
|
||||
// Move the object to the fast group (helltime)
|
||||
grabEnt->timeGroup = TIME_GROUP2;
|
||||
|
||||
// Handle specific class types
|
||||
if ( grabEnt->IsType( idProjectile::Type ) ) {
|
||||
idProjectile* p = (idProjectile*)grabEnt;
|
||||
|
||||
p->CatchProjectile( thePlayer, "_catch" );
|
||||
|
||||
// Make the projectile non-solid to other projectiles/enemies (special hack for helltime hunter)
|
||||
if ( !idStr::Cmp( grabEnt->GetEntityDefName(), "projectile_helltime_killer" ) ) {
|
||||
savedContents = CONTENTS_PROJECTILE;
|
||||
savedClipmask = MASK_SHOT_RENDERMODEL|CONTENTS_PROJECTILE;
|
||||
} else {
|
||||
savedContents = grabEnt->GetPhysics()->GetContents();
|
||||
savedClipmask = grabEnt->GetPhysics()->GetClipMask();
|
||||
}
|
||||
grabEnt->GetPhysics()->SetContents( 0 );
|
||||
grabEnt->GetPhysics()->SetClipMask( CONTENTS_SOLID|CONTENTS_BODY );
|
||||
|
||||
} else if ( grabEnt->IsType( idExplodingBarrel::Type ) ) {
|
||||
idExplodingBarrel *ebarrel = static_cast<idExplodingBarrel*>(grabEnt);
|
||||
|
||||
ebarrel->StartBurning();
|
||||
|
||||
} else if ( grabEnt->IsType( idAFEntity_Gibbable::Type ) ) {
|
||||
holdingAF = true;
|
||||
clipModelId = 0;
|
||||
|
||||
if ( grabbableAI( grabEnt->spawnArgs.GetString( "classname" ) ) ) {
|
||||
idAI *aiEnt = static_cast<idAI*>(grabEnt);
|
||||
|
||||
aiEnt->StartRagdoll();
|
||||
}
|
||||
} else if ( grabEnt->IsType( idMoveableItem::Type ) ) {
|
||||
grabEnt->PostEventMS( &EV_Touch, 250, thePlayer, NULL );
|
||||
}
|
||||
|
||||
// Get the current physics object to manipulate
|
||||
idPhysics *phys = grabEnt->GetPhysics();
|
||||
|
||||
// Turn off gravity on object
|
||||
saveGravity = phys->GetGravity();
|
||||
phys->SetGravity( vec3_origin );
|
||||
|
||||
// hold it directly in front of player
|
||||
localPlayerPoint = ( thePlayer->firstPersonViewAxis[0] * HOLD_DISTANCE ) * thePlayer->firstPersonViewAxis.Transpose();
|
||||
|
||||
// Set the ending time for the hold
|
||||
endTime = gameLocal.time + g_grabberHoldSeconds.GetFloat() * 1000;
|
||||
|
||||
// Start up the Force_Drag to bring it in
|
||||
drag.Init( g_grabberDamping.GetFloat() );
|
||||
drag.SetPhysics( phys, clipModelId, thePlayer->firstPersonViewOrigin + localPlayerPoint * thePlayer->firstPersonViewAxis);
|
||||
|
||||
// start the screen warp
|
||||
warpId = thePlayer->playerView.AddWarp( phys->GetOrigin(), SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 160, 2000 );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
idGrabber::StopDrag
|
||||
==============
|
||||
*/
|
||||
void idGrabber::StopDrag( bool dropOnly ) {
|
||||
idPlayer *thePlayer = owner.GetEntity();
|
||||
|
||||
if ( beam ) {
|
||||
beam->Hide();
|
||||
}
|
||||
if ( beamTarget ) {
|
||||
beamTarget->Hide();
|
||||
}
|
||||
|
||||
if ( dragEnt.IsValid() ) {
|
||||
idEntity *ent = dragEnt.GetEntity();
|
||||
|
||||
// set grabbed state for networking
|
||||
ent->SetGrabbedState( false );
|
||||
|
||||
// If a cinematic has started, allow dropped object to think in cinematics
|
||||
if ( gameLocal.inCinematic ) {
|
||||
ent->cinematic = true;
|
||||
}
|
||||
|
||||
// Restore Gravity
|
||||
ent->GetPhysics()->SetGravity( saveGravity );
|
||||
|
||||
// Move the object back to the slow group (helltime)
|
||||
ent->timeGroup = TIME_GROUP1;
|
||||
|
||||
if ( holdingAF ) {
|
||||
idAFEntity_Gibbable *af = static_cast<idAFEntity_Gibbable *>(ent);
|
||||
idPhysics_AF *af_Phys = static_cast<idPhysics_AF*>(af->GetPhysics());
|
||||
|
||||
if ( grabbableAI( ent->spawnArgs.GetString( "classname" ) ) ) {
|
||||
idAI *aiEnt = static_cast<idAI*>(ent);
|
||||
|
||||
aiEnt->Damage( thePlayer, thePlayer, vec3_origin, "damage_suicide", 1.0f, INVALID_JOINT );
|
||||
}
|
||||
|
||||
af->SetThrown( !dropOnly );
|
||||
|
||||
// Reset timers so that it isn't forcibly put to rest in mid-air
|
||||
af_Phys->PutToRest();
|
||||
af_Phys->Activate();
|
||||
|
||||
af_Phys->SetTimeScaleRamp( MS2SEC(gameLocal.slow.time) - 1.5f, MS2SEC(gameLocal.slow.time) + 1.0f );
|
||||
}
|
||||
|
||||
// If the object isn't near its goal, just drop it in place.
|
||||
if ( !ent->IsType( idProjectile::Type ) && ( dropOnly || drag.GetDistanceToGoal() > DRAG_FAIL_LEN ) ) {
|
||||
ent->GetPhysics()->SetLinearVelocity( vec3_origin );
|
||||
thePlayer->StartSoundShader( declManager->FindSound( "grabber_maindrop" ), SND_CHANNEL_WEAPON, 0, false, NULL );
|
||||
|
||||
if ( ent->IsType( idExplodingBarrel::Type ) ) {
|
||||
idExplodingBarrel *ebarrel = static_cast<idExplodingBarrel*>(ent);
|
||||
|
||||
ebarrel->SetStability( true );
|
||||
ebarrel->StopBurning();
|
||||
}
|
||||
} else {
|
||||
// Shoot the object forward
|
||||
ent->ApplyImpulse( thePlayer, 0, ent->GetPhysics()->GetOrigin(), thePlayer->firstPersonViewAxis[0] * THROW_SCALE * ent->GetPhysics()->GetMass() );
|
||||
thePlayer->StartSoundShader( declManager->FindSound( "grabber_release" ), SND_CHANNEL_WEAPON, 0, false, NULL );
|
||||
|
||||
// Orient projectiles away from the player
|
||||
if ( ent->IsType( idProjectile::Type ) ) {
|
||||
idPlayer *player = owner.GetEntity();
|
||||
idAngles ang = player->firstPersonViewAxis[0].ToAngles();
|
||||
|
||||
ang.pitch += 90.f;
|
||||
ent->GetPhysics()->SetAxis( ang.ToMat3() );
|
||||
ent->GetPhysics()->SetAngularVelocity( vec3_origin );
|
||||
|
||||
// Restore projectile contents
|
||||
ent->GetPhysics()->SetContents( savedContents );
|
||||
ent->GetPhysics()->SetClipMask( savedClipmask );
|
||||
|
||||
idProjectile *projectile = static_cast< idProjectile* >( ent );
|
||||
if ( projectile != NULL ) {
|
||||
projectile->SetLaunchedFromGrabber( true );
|
||||
}
|
||||
|
||||
} else if ( ent->IsType( idMoveable::Type ) ) {
|
||||
// Turn on damage for this object
|
||||
idMoveable *obj = static_cast<idMoveable*>(ent);
|
||||
obj->EnableDamage( true, 2.5f );
|
||||
obj->SetAttacker( thePlayer );
|
||||
|
||||
if ( ent->IsType( idExplodingBarrel::Type ) ) {
|
||||
idExplodingBarrel *ebarrel = static_cast<idExplodingBarrel*>(ent);
|
||||
ebarrel->SetStability( false );
|
||||
}
|
||||
|
||||
} else if ( ent->IsType( idMoveableItem::Type ) ) {
|
||||
ent->GetPhysics()->SetClipMask( MASK_MONSTERSOLID );
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the Force_Drag's control of the entity
|
||||
drag.RemovePhysics( ent->GetPhysics() );
|
||||
}
|
||||
|
||||
if ( warpId != -1 ) {
|
||||
thePlayer->playerView.FreeWarp( warpId );
|
||||
warpId = -1;
|
||||
}
|
||||
|
||||
lastFiredTime = gameLocal.time;
|
||||
dragEnt = NULL;
|
||||
endTime = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
idGrabber::Update
|
||||
==============
|
||||
*/
|
||||
int idGrabber::Update( idPlayer *player, bool hide ) {
|
||||
trace_t trace;
|
||||
idEntity *newEnt;
|
||||
|
||||
// pause before allowing refire
|
||||
if ( lastFiredTime + FIRING_DELAY > gameLocal.time ) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
// Dead players release the trigger
|
||||
if ( hide || player->health <= 0 ) {
|
||||
StopDrag( true );
|
||||
if ( hide ) {
|
||||
lastFiredTime = gameLocal.time - FIRING_DELAY + 250;
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
|
||||
// Check if object being held has been removed (dead demon, projectile, etc.)
|
||||
if ( endTime > gameLocal.time ) {
|
||||
bool abort = !dragEnt.IsValid();
|
||||
|
||||
if ( !abort && dragEnt.GetEntity()->IsType( idProjectile::Type ) ) {
|
||||
idProjectile *proj = (idProjectile *)dragEnt.GetEntity();
|
||||
|
||||
if ( proj->GetProjectileState() >= 3 ) {
|
||||
abort = true;
|
||||
}
|
||||
}
|
||||
if ( !abort && dragEnt.GetEntity() && dragEnt.GetEntity()->IsHidden() ) {
|
||||
abort = true;
|
||||
}
|
||||
// Not in multiplayer :: Pressing "reload" lets you carefully drop an item
|
||||
if ( !common->IsMultiplayer() && !abort && ( player->usercmd.impulseSequence != oldImpulseSequence ) && (player->usercmd.impulse == IMPULSE_13) ) {
|
||||
abort = true;
|
||||
}
|
||||
|
||||
if ( abort ) {
|
||||
StopDrag( true );
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
owner = player;
|
||||
|
||||
// if no entity selected for dragging
|
||||
if ( !dragEnt.GetEntity() ) {
|
||||
idBounds bounds;
|
||||
idVec3 end = player->firstPersonViewOrigin + player->firstPersonViewAxis[0] * dragTraceDist;
|
||||
|
||||
bounds.Zero();
|
||||
bounds.ExpandSelf( TRACE_BOUNDS_SIZE );
|
||||
|
||||
gameLocal.clip.TraceBounds( trace, player->firstPersonViewOrigin, end, bounds, MASK_SHOT_RENDERMODEL|CONTENTS_PROJECTILE|CONTENTS_MOVEABLECLIP, player );
|
||||
// If the trace hit something
|
||||
if ( trace.fraction < 1.0f ) {
|
||||
newEnt = gameLocal.entities[ trace.c.entityNum ];
|
||||
|
||||
// if entity is already being grabbed then bypass
|
||||
if ( common->IsMultiplayer() && newEnt && newEnt->IsGrabbed() ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check if this is a valid entity to hold
|
||||
if ( newEnt && ( newEnt->IsType( idMoveable::Type ) ||
|
||||
newEnt->IsType( idMoveableItem::Type ) ||
|
||||
newEnt->IsType( idProjectile::Type ) ||
|
||||
newEnt->IsType( idAFEntity_Gibbable::Type )
|
||||
) &&
|
||||
newEnt->noGrab == false &&
|
||||
newEnt->GetPhysics()->GetBounds().GetRadius() < MAX_PICKUP_SIZE &&
|
||||
newEnt->GetPhysics()->GetLinearVelocity().LengthSqr() < MAX_PICKUP_VELOCITY ) {
|
||||
|
||||
bool validAF = true;
|
||||
|
||||
if ( newEnt->IsType( idAFEntity_Gibbable::Type ) ) {
|
||||
idAFEntity_Gibbable *afEnt = static_cast<idAFEntity_Gibbable*>(newEnt);
|
||||
|
||||
if ( grabbableAI( newEnt->spawnArgs.GetString( "classname" ) ) ) {
|
||||
// Make sure it's also active
|
||||
if ( !afEnt->IsActive() ) {
|
||||
validAF = false;
|
||||
}
|
||||
} else if ( !afEnt->IsActiveAF() ) {
|
||||
validAF = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( validAF && player->usercmd.buttons & BUTTON_ATTACK ) {
|
||||
// Grab this entity and start dragging it around
|
||||
StartDrag( newEnt, trace.c.id );
|
||||
} else if ( validAF ) {
|
||||
// A holdable object is ready to be grabbed
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check backwards server time in multiplayer
|
||||
bool allow = true;
|
||||
|
||||
if ( common->IsMultiplayer() ) {
|
||||
|
||||
// if we've marched backwards
|
||||
if ( gameLocal.slow.time < startDragTime ) {
|
||||
allow = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if there is an entity selected for dragging
|
||||
if ( dragEnt.GetEntity() && allow ) {
|
||||
idPhysics *entPhys = dragEnt.GetEntity()->GetPhysics();
|
||||
idVec3 goalPos;
|
||||
|
||||
// If the player lets go of attack, or time is up
|
||||
if ( !( player->usercmd.buttons & BUTTON_ATTACK ) ) {
|
||||
StopDrag( false );
|
||||
return 3;
|
||||
}
|
||||
if ( gameLocal.time > endTime ) {
|
||||
StopDrag( true );
|
||||
return 3;
|
||||
}
|
||||
|
||||
// Check if the player is standing on the object
|
||||
if ( !holdingAF ) {
|
||||
idBounds playerBounds;
|
||||
idBounds objectBounds = entPhys->GetAbsBounds();
|
||||
idVec3 newPoint = player->GetPhysics()->GetOrigin();
|
||||
|
||||
// create a bounds at the players feet
|
||||
playerBounds.Clear();
|
||||
playerBounds.AddPoint( newPoint );
|
||||
newPoint.z -= 1.f;
|
||||
playerBounds.AddPoint( newPoint );
|
||||
playerBounds.ExpandSelf( 8.f );
|
||||
|
||||
// If it intersects the object bounds, then drop it
|
||||
if ( playerBounds.IntersectsBounds( objectBounds ) ) {
|
||||
StopDrag( true );
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
// Shake the object at the end of the hold
|
||||
if ( g_grabberEnableShake.GetBool() && !common->IsMultiplayer() ) {
|
||||
ApplyShake();
|
||||
}
|
||||
|
||||
// Set and evaluate drag force
|
||||
goalPos = player->firstPersonViewOrigin + localPlayerPoint * player->firstPersonViewAxis;
|
||||
|
||||
drag.SetGoalPosition( goalPos );
|
||||
drag.Evaluate( gameLocal.time );
|
||||
|
||||
// If an object is flying too fast toward the player, stop it hard
|
||||
if ( g_grabberHardStop.GetBool() ) {
|
||||
idPlane theWall;
|
||||
idVec3 toPlayerVelocity, objectCenter;
|
||||
float toPlayerSpeed;
|
||||
|
||||
toPlayerVelocity = -player->firstPersonViewAxis[0];
|
||||
toPlayerSpeed = entPhys->GetLinearVelocity() * toPlayerVelocity;
|
||||
|
||||
if ( toPlayerSpeed > 64.f ) {
|
||||
objectCenter = entPhys->GetAbsBounds().GetCenter();
|
||||
|
||||
theWall.SetNormal( player->firstPersonViewAxis[0] );
|
||||
theWall.FitThroughPoint( goalPos );
|
||||
|
||||
if ( theWall.Side( objectCenter, 0.1f ) == PLANESIDE_BACK ) {
|
||||
int i, num;
|
||||
|
||||
num = entPhys->GetNumClipModels();
|
||||
for ( i=0; i<num; i++ ) {
|
||||
entPhys->SetLinearVelocity( vec3_origin, i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the object isn't spinning too fast
|
||||
const float MAX_ROTATION_SPEED = 12.f;
|
||||
|
||||
idVec3 angVel = entPhys->GetAngularVelocity();
|
||||
float rotationSpeed = angVel.LengthFast();
|
||||
|
||||
if ( rotationSpeed > MAX_ROTATION_SPEED ) {
|
||||
angVel.NormalizeFast();
|
||||
angVel *= MAX_ROTATION_SPEED;
|
||||
entPhys->SetAngularVelocity( angVel );
|
||||
}
|
||||
}
|
||||
|
||||
// Orient projectiles away from the player
|
||||
if ( dragEnt.GetEntity()->IsType( idProjectile::Type ) ) {
|
||||
idAngles ang = player->firstPersonViewAxis[0].ToAngles();
|
||||
ang.pitch += 90.f;
|
||||
entPhys->SetAxis( ang.ToMat3() );
|
||||
}
|
||||
|
||||
// Some kind of effect from gun to object?
|
||||
UpdateBeams();
|
||||
|
||||
// If the object is stuck away from its intended position for more than 500ms, let it go.
|
||||
if ( drag.GetDistanceToGoal() > DRAG_FAIL_LEN ) {
|
||||
if ( dragFailTime < (gameLocal.slow.time - 500) ) {
|
||||
StopDrag( true );
|
||||
return 3;
|
||||
}
|
||||
} else {
|
||||
dragFailTime = gameLocal.slow.time;
|
||||
}
|
||||
|
||||
// Currently holding an object
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Not holding, nothing to hold
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
======================
|
||||
idGrabber::UpdateBeams
|
||||
======================
|
||||
*/
|
||||
void idGrabber::UpdateBeams() {
|
||||
jointHandle_t muzzle_joint;
|
||||
idVec3 muzzle_origin;
|
||||
idMat3 muzzle_axis;
|
||||
renderEntity_t *re;
|
||||
|
||||
if ( !beam ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( dragEnt.IsValid() ) {
|
||||
idPlayer *thePlayer = owner.GetEntity();
|
||||
|
||||
if ( beamTarget ) {
|
||||
beamTarget->SetOrigin( dragEnt.GetEntity()->GetPhysics()->GetAbsBounds().GetCenter() );
|
||||
}
|
||||
|
||||
muzzle_joint = thePlayer->weapon.GetEntity()->GetAnimator()->GetJointHandle( "particle_upper" );
|
||||
if ( muzzle_joint != INVALID_JOINT ) {
|
||||
thePlayer->weapon.GetEntity()->GetJointWorldTransform( muzzle_joint, gameLocal.time, muzzle_origin, muzzle_axis );
|
||||
} else {
|
||||
muzzle_origin = thePlayer->GetPhysics()->GetOrigin();
|
||||
}
|
||||
|
||||
beam->SetOrigin( muzzle_origin );
|
||||
re = beam->GetRenderEntity();
|
||||
re->origin = muzzle_origin;
|
||||
|
||||
beam->UpdateVisuals();
|
||||
beam->Present();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
idGrabber::ApplyShake
|
||||
==============
|
||||
*/
|
||||
void idGrabber::ApplyShake() {
|
||||
float u = 1 - (float)( endTime - gameLocal.time ) / ( g_grabberHoldSeconds.GetFloat() * 1000 );
|
||||
|
||||
if ( u >= 0.8f ) {
|
||||
idVec3 point, impulse;
|
||||
float shakeForceMagnitude = 450.f;
|
||||
float mass = dragEnt.GetEntity()->GetPhysics()->GetMass();
|
||||
|
||||
shakeForceFlip = !shakeForceFlip;
|
||||
|
||||
// get point to rotate around
|
||||
point = dragEnt.GetEntity()->GetPhysics()->GetOrigin();
|
||||
point.y += 1;
|
||||
|
||||
// Articulated figures get less violent shake
|
||||
if ( holdingAF ) {
|
||||
shakeForceMagnitude = 120.f;
|
||||
}
|
||||
|
||||
// calc impulse
|
||||
if ( shakeForceFlip ) {
|
||||
impulse.Set( 0, 0, shakeForceMagnitude * u * mass );
|
||||
}
|
||||
else {
|
||||
impulse.Set( 0, 0, -shakeForceMagnitude * u * mass );
|
||||
}
|
||||
|
||||
dragEnt.GetEntity()->ApplyImpulse( NULL, 0, point, impulse );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
idGrabber::grabbableAI
|
||||
==============
|
||||
*/
|
||||
bool idGrabber::grabbableAI( const char *aiName ) {
|
||||
// skip "monster_"
|
||||
aiName += 8;
|
||||
|
||||
if (!idStr::Cmpn( aiName, "flying_lostsoul", 15 ) ||
|
||||
!idStr::Cmpn( aiName, "demon_trite", 11 ) ||
|
||||
!idStr::Cmp( aiName, "flying_forgotten" ) ||
|
||||
!idStr::Cmp( aiName, "demon_cherub" ) ||
|
||||
!idStr::Cmp( aiName, "demon_tick" )) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
84
neo/d3xp/Grabber.h
Normal file
84
neo/d3xp/Grabber.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Grabber Object - Class to extend idWeapon to include functionality for
|
||||
manipulating physics objects.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idBeam;
|
||||
|
||||
class idGrabber : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idGrabber );
|
||||
|
||||
idGrabber();
|
||||
~idGrabber();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Initialize();
|
||||
void SetDragDistance( float dist );
|
||||
int Update( idPlayer *player, bool hide );
|
||||
|
||||
private:
|
||||
idEntityPtr<idEntity> dragEnt; // entity being dragged
|
||||
idForce_Grab drag;
|
||||
idVec3 saveGravity;
|
||||
|
||||
int id; // id of body being dragged
|
||||
idVec3 localPlayerPoint; // dragged point in player space
|
||||
idEntityPtr<idPlayer> owner;
|
||||
int oldImpulseSequence;
|
||||
bool holdingAF;
|
||||
bool shakeForceFlip;
|
||||
int endTime;
|
||||
int lastFiredTime;
|
||||
int dragFailTime;
|
||||
int startDragTime;
|
||||
float dragTraceDist;
|
||||
int savedContents;
|
||||
int savedClipmask;
|
||||
|
||||
idBeam* beam;
|
||||
idBeam* beamTarget;
|
||||
|
||||
int warpId;
|
||||
|
||||
bool grabbableAI( const char *aiName );
|
||||
void StartDrag( idEntity *grabEnt, int id );
|
||||
void StopDrag( bool dropOnly );
|
||||
void UpdateBeams();
|
||||
void ApplyShake();
|
||||
};
|
||||
|
||||
1128
neo/d3xp/IK.cpp
Normal file
1128
neo/d3xp/IK.cpp
Normal file
File diff suppressed because it is too large
Load Diff
182
neo/d3xp/IK.h
Normal file
182
neo/d3xp/IK.h
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_IK_H__
|
||||
#define __GAME_IK_H__
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
IK base class with a simple fast two bone solver.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
#define IK_ANIM "ik_pose"
|
||||
|
||||
class idIK {
|
||||
public:
|
||||
idIK();
|
||||
virtual ~idIK();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
bool IsInitialized() const;
|
||||
|
||||
virtual bool Init( idEntity *self, const char *anim, const idVec3 &modelOffset );
|
||||
virtual void Evaluate();
|
||||
virtual void ClearJointMods();
|
||||
|
||||
bool SolveTwoBones( const idVec3 &startPos, const idVec3 &endPos, const idVec3 &dir, float len0, float len1, idVec3 &jointPos );
|
||||
float GetBoneAxis( const idVec3 &startPos, const idVec3 &endPos, const idVec3 &dir, idMat3 &axis );
|
||||
|
||||
protected:
|
||||
bool initialized;
|
||||
bool ik_activate;
|
||||
idEntity * self; // entity using the animated model
|
||||
idAnimator * animator; // animator on entity
|
||||
int modifiedAnim; // animation modified by the IK
|
||||
idVec3 modelOffset;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
IK controller for a walking character with an arbitrary number of legs.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idIK_Walk : public idIK {
|
||||
public:
|
||||
|
||||
idIK_Walk();
|
||||
virtual ~idIK_Walk();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual bool Init( idEntity *self, const char *anim, const idVec3 &modelOffset );
|
||||
virtual void Evaluate();
|
||||
virtual void ClearJointMods();
|
||||
|
||||
void EnableAll();
|
||||
void DisableAll();
|
||||
void EnableLeg( int num );
|
||||
void DisableLeg( int num );
|
||||
|
||||
private:
|
||||
static const int MAX_LEGS = 8;
|
||||
|
||||
idClipModel * footModel;
|
||||
|
||||
int numLegs;
|
||||
int enabledLegs;
|
||||
jointHandle_t footJoints[MAX_LEGS];
|
||||
jointHandle_t ankleJoints[MAX_LEGS];
|
||||
jointHandle_t kneeJoints[MAX_LEGS];
|
||||
jointHandle_t hipJoints[MAX_LEGS];
|
||||
jointHandle_t dirJoints[MAX_LEGS];
|
||||
jointHandle_t waistJoint;
|
||||
|
||||
idVec3 hipForward[MAX_LEGS];
|
||||
idVec3 kneeForward[MAX_LEGS];
|
||||
|
||||
float upperLegLength[MAX_LEGS];
|
||||
float lowerLegLength[MAX_LEGS];
|
||||
|
||||
idMat3 upperLegToHipJoint[MAX_LEGS];
|
||||
idMat3 lowerLegToKneeJoint[MAX_LEGS];
|
||||
|
||||
float smoothing;
|
||||
float waistSmoothing;
|
||||
float footShift;
|
||||
float waistShift;
|
||||
float minWaistFloorDist;
|
||||
float minWaistAnkleDist;
|
||||
float footUpTrace;
|
||||
float footDownTrace;
|
||||
bool tiltWaist;
|
||||
bool usePivot;
|
||||
|
||||
// state
|
||||
int pivotFoot;
|
||||
float pivotYaw;
|
||||
idVec3 pivotPos;
|
||||
bool oldHeightsValid;
|
||||
float oldWaistHeight;
|
||||
float oldAnkleHeights[MAX_LEGS];
|
||||
idVec3 waistOffset;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
IK controller for reaching a position with an arm or leg.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idIK_Reach : public idIK {
|
||||
public:
|
||||
|
||||
idIK_Reach();
|
||||
virtual ~idIK_Reach();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual bool Init( idEntity *self, const char *anim, const idVec3 &modelOffset );
|
||||
virtual void Evaluate();
|
||||
virtual void ClearJointMods();
|
||||
|
||||
private:
|
||||
|
||||
static const int MAX_ARMS = 2;
|
||||
|
||||
int numArms;
|
||||
int enabledArms;
|
||||
jointHandle_t handJoints[MAX_ARMS];
|
||||
jointHandle_t elbowJoints[MAX_ARMS];
|
||||
jointHandle_t shoulderJoints[MAX_ARMS];
|
||||
jointHandle_t dirJoints[MAX_ARMS];
|
||||
|
||||
idVec3 shoulderForward[MAX_ARMS];
|
||||
idVec3 elbowForward[MAX_ARMS];
|
||||
|
||||
float upperArmLength[MAX_ARMS];
|
||||
float lowerArmLength[MAX_ARMS];
|
||||
|
||||
idMat3 upperArmToShoulderJoint[MAX_ARMS];
|
||||
idMat3 lowerArmToElbowJoint[MAX_ARMS];
|
||||
};
|
||||
|
||||
#endif /* !__GAME_IK_H__ */
|
||||
2138
neo/d3xp/Item.cpp
Normal file
2138
neo/d3xp/Item.cpp
Normal file
File diff suppressed because it is too large
Load Diff
324
neo/d3xp/Item.h
Normal file
324
neo/d3xp/Item.h
Normal file
@@ -0,0 +1,324 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_ITEM_H__
|
||||
#define __GAME_ITEM_H__
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Items the player can pick up or use.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
================================================
|
||||
These flags are passed to the Give functions
|
||||
to set their behavior. We need to be able to
|
||||
separate the feedback from the actual
|
||||
state modification so that we can hide lag
|
||||
on MP clients.
|
||||
|
||||
For the previous behavior of functions which
|
||||
take a giveFlags parameter (this is usually
|
||||
desired on the server too) pass
|
||||
ITEM_GIVE_FEEDBACK | ITEM_GIVE_UPDATE_STATE.
|
||||
================================================
|
||||
*/
|
||||
enum itemGiveFlags_t {
|
||||
ITEM_GIVE_FEEDBACK = BIT( 0 ),
|
||||
ITEM_GIVE_UPDATE_STATE = BIT( 1 ),
|
||||
ITEM_GIVE_FROM_WEAPON = BIT( 2 ), // indicates this was given via a weapon's launchPowerup (for bloodstone powerups)
|
||||
};
|
||||
|
||||
class idItem : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idItem );
|
||||
|
||||
idItem();
|
||||
virtual ~idItem();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
void GetAttributes( idDict &attributes ) const;
|
||||
virtual bool GiveToPlayer( idPlayer *player, unsigned int giveFlags );
|
||||
virtual bool Pickup( idPlayer *player );
|
||||
virtual void Think();
|
||||
virtual void Present();
|
||||
|
||||
enum {
|
||||
EVENT_PICKUP = idEntity::EVENT_MAXEVENTS,
|
||||
EVENT_RESPAWN,
|
||||
EVENT_RESPAWNFX,
|
||||
EVENT_TAKEFLAG,
|
||||
EVENT_DROPFLAG,
|
||||
EVENT_FLAGRETURN,
|
||||
EVENT_FLAGCAPTURE,
|
||||
EVENT_MAXEVENTS
|
||||
};
|
||||
|
||||
void ClientThink( const int curTime, const float fraction, const bool predict );
|
||||
virtual void ClientPredictionThink();
|
||||
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
|
||||
|
||||
// networking
|
||||
virtual void WriteToSnapshot( idBitMsg &msg ) const;
|
||||
virtual void ReadFromSnapshot( const idBitMsg &msg );
|
||||
|
||||
protected:
|
||||
int GetPredictPickupMilliseconds() const { return clientPredictPickupMilliseconds; }
|
||||
|
||||
private:
|
||||
idVec3 orgOrigin;
|
||||
bool spin;
|
||||
bool pulse;
|
||||
bool canPickUp;
|
||||
|
||||
// for item pulse effect
|
||||
int itemShellHandle;
|
||||
const idMaterial * shellMaterial;
|
||||
|
||||
// used to update the item pulse effect
|
||||
mutable bool inView;
|
||||
mutable int inViewTime;
|
||||
mutable int lastCycle;
|
||||
mutable int lastRenderViewTime;
|
||||
|
||||
// used for prediction in mp
|
||||
int clientPredictPickupMilliseconds;
|
||||
|
||||
bool UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ) const;
|
||||
static bool ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView );
|
||||
|
||||
void Event_DropToFloor();
|
||||
void Event_Touch( idEntity *other, trace_t *trace );
|
||||
void Event_Trigger( idEntity *activator );
|
||||
void Event_Respawn();
|
||||
void Event_RespawnFx();
|
||||
};
|
||||
|
||||
class idItemPowerup : public idItem {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idItemPowerup );
|
||||
|
||||
idItemPowerup();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
virtual bool GiveToPlayer( idPlayer *player, unsigned int giveFlags );
|
||||
|
||||
private:
|
||||
int time;
|
||||
int type;
|
||||
};
|
||||
|
||||
class idObjective : public idItem {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idObjective );
|
||||
|
||||
idObjective();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
|
||||
private:
|
||||
idVec3 playerPos;
|
||||
const idMaterial * screenshot;
|
||||
|
||||
void Event_Trigger( idEntity *activator );
|
||||
void Event_HideObjective( idEntity *e );
|
||||
void Event_GetPlayerPos();
|
||||
};
|
||||
|
||||
class idVideoCDItem : public idItem {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idVideoCDItem );
|
||||
|
||||
virtual bool GiveToPlayer( idPlayer *player, unsigned int giveFlags );
|
||||
};
|
||||
|
||||
class idPDAItem : public idItem {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idPDAItem );
|
||||
|
||||
virtual bool GiveToPlayer( idPlayer *player, unsigned int giveFlags );
|
||||
};
|
||||
|
||||
class idMoveableItem : public idItem {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idMoveableItem );
|
||||
|
||||
idMoveableItem();
|
||||
virtual ~idMoveableItem();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
virtual void Think();
|
||||
void ClientThink( const int curTime, const float fraction, const bool predict );
|
||||
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
|
||||
virtual bool Pickup( idPlayer *player );
|
||||
|
||||
static void DropItems( idAnimatedEntity *ent, const char *type, idList<idEntity *> *list );
|
||||
static idEntity * DropItem( const char *classname, const idVec3 &origin, const idMat3 &axis, const idVec3 &velocity, int activateDelay, int removeDelay );
|
||||
|
||||
virtual void WriteToSnapshot( idBitMsg &msg ) const;
|
||||
virtual void ReadFromSnapshot( const idBitMsg &msg );
|
||||
|
||||
protected:
|
||||
idPhysics_RigidBody physicsObj;
|
||||
idClipModel * trigger;
|
||||
const idDeclParticle * smoke;
|
||||
int smokeTime;
|
||||
|
||||
int nextSoundTime;
|
||||
bool repeatSmoke; // never stop updating the particles
|
||||
|
||||
void Gib( const idVec3 &dir, const char *damageDefName );
|
||||
|
||||
void Event_DropToFloor();
|
||||
void Event_Gib( const char *damageDefName );
|
||||
};
|
||||
|
||||
class idItemTeam : public idMoveableItem {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idItemTeam );
|
||||
|
||||
idItemTeam();
|
||||
virtual ~idItemTeam();
|
||||
|
||||
void Spawn();
|
||||
virtual bool Pickup( idPlayer *player );
|
||||
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
|
||||
virtual void Think(void );
|
||||
|
||||
void Drop( bool death = false ); // was the drop caused by death of carrier?
|
||||
void Return( idPlayer * player = NULL );
|
||||
void Capture();
|
||||
|
||||
virtual void FreeLightDef();
|
||||
virtual void Present();
|
||||
|
||||
// networking
|
||||
virtual void WriteToSnapshot( idBitMsg &msg ) const;
|
||||
virtual void ReadFromSnapshot( const idBitMsg &msg );
|
||||
|
||||
public:
|
||||
int team;
|
||||
// TODO : turn this into a state :
|
||||
bool carried; // is it beeing carried by a player?
|
||||
bool dropped; // was it dropped?
|
||||
|
||||
private:
|
||||
idVec3 returnOrigin;
|
||||
idMat3 returnAxis;
|
||||
int lastDrop;
|
||||
|
||||
const idDeclSkin * skinDefault;
|
||||
const idDeclSkin * skinCarried;
|
||||
|
||||
const function_t * scriptTaken;
|
||||
const function_t * scriptDropped;
|
||||
const function_t * scriptReturned;
|
||||
const function_t * scriptCaptured;
|
||||
|
||||
renderLight_t itemGlow; // Used by flags when they are picked up
|
||||
int itemGlowHandle;
|
||||
|
||||
int lastNuggetDrop;
|
||||
const char * nuggetName;
|
||||
|
||||
private:
|
||||
|
||||
void Event_TakeFlag( idPlayer * player );
|
||||
void Event_DropFlag( bool death );
|
||||
void Event_FlagReturn( idPlayer * player = NULL );
|
||||
void Event_FlagCapture();
|
||||
|
||||
void PrivateReturn();
|
||||
function_t * LoadScript( char * script );
|
||||
|
||||
void SpawnNugget( idVec3 pos );
|
||||
void UpdateGuis();
|
||||
};
|
||||
|
||||
class idMoveablePDAItem : public idMoveableItem {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idMoveablePDAItem );
|
||||
|
||||
virtual bool GiveToPlayer( idPlayer *player, unsigned int giveFlags );
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Item removers.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idItemRemover : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idItemRemover );
|
||||
|
||||
void Spawn();
|
||||
void RemoveItem( idPlayer *player );
|
||||
|
||||
private:
|
||||
void Event_Trigger( idEntity *activator );
|
||||
};
|
||||
|
||||
class idObjectiveComplete : public idItemRemover {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idObjectiveComplete );
|
||||
|
||||
idObjectiveComplete();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
|
||||
private:
|
||||
idVec3 playerPos;
|
||||
|
||||
void Event_Trigger( idEntity *activator );
|
||||
void Event_HideObjective( idEntity *e );
|
||||
void Event_GetPlayerPos();
|
||||
};
|
||||
|
||||
#endif /* !__GAME_ITEM_H__ */
|
||||
332
neo/d3xp/Leaderboards.cpp
Normal file
332
neo/d3xp/Leaderboards.cpp
Normal file
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../idlib/precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Game_local.h"
|
||||
#include "Leaderboards.h"
|
||||
#include "MultiplayerGame.h"
|
||||
|
||||
/*
|
||||
================================================================================================
|
||||
|
||||
Leaderboard stats column definitions - per Game Type.
|
||||
|
||||
================================================================================================
|
||||
*/
|
||||
|
||||
|
||||
static columnDef_t public_Deathmatch[] = {
|
||||
{ "Frags", 64, AGGREGATE_MAX, STATS_COLUMN_DISPLAY_NUMBER },
|
||||
//{ "Deaths", 64, AGGREGATE_MAX, STATS_COLUMN_DISPLAY_NUMBER },
|
||||
//{ "Wins", 64, AGGREGATE_MAX, STATS_COLUMN_DISPLAY_NUMBER },
|
||||
//{ "Score", 64, AGGREGATE_MAX, STATS_COLUMN_DISPLAY_NUMBER },
|
||||
};
|
||||
|
||||
static columnDef_t public_Tourney[] = {
|
||||
{ "Wins", 64, AGGREGATE_SUM, STATS_COLUMN_DISPLAY_NUMBER },
|
||||
};
|
||||
|
||||
static columnDef_t public_TeamDeathmatch[] = {
|
||||
{ "Wins", 64, AGGREGATE_MAX, STATS_COLUMN_DISPLAY_NUMBER },
|
||||
};
|
||||
|
||||
static columnDef_t public_LastmanStanding[] = {
|
||||
{ "Wins", 64, AGGREGATE_MAX, STATS_COLUMN_DISPLAY_NUMBER },
|
||||
};
|
||||
|
||||
static columnDef_t public_CaptureTheFlag[] = {
|
||||
{ "Wins", 64, AGGREGATE_MAX, STATS_COLUMN_DISPLAY_NUMBER },
|
||||
};
|
||||
|
||||
// This should match up to the ordering of the gameType_t. ( in MultiplayerGame.h )
|
||||
const columnGameMode_t gameMode_columnDefs[] = {
|
||||
{ public_Deathmatch, ARRAY_COUNT( public_Deathmatch ), RANK_GREATEST_FIRST, false, false, "DM" }, // DEATHMATCH
|
||||
{ public_Tourney, ARRAY_COUNT( public_Tourney ), RANK_GREATEST_FIRST, false, false, "TOURNEY" }, // TOURNEY
|
||||
{ public_TeamDeathmatch, ARRAY_COUNT( public_TeamDeathmatch ), RANK_GREATEST_FIRST, false, false, "TDM" }, // TEAM DEATHMATCH
|
||||
{ public_LastmanStanding, ARRAY_COUNT( public_LastmanStanding ), RANK_GREATEST_FIRST, false, false, "LMS" }, // LASTMAN STANDING
|
||||
{ public_CaptureTheFlag, ARRAY_COUNT( public_CaptureTheFlag ), RANK_GREATEST_FIRST, false, false, "CTF" }, // CAPTURE THE FLAG
|
||||
};
|
||||
|
||||
/*
|
||||
=====================================
|
||||
RetreiveLeaderboardID
|
||||
|
||||
Each map will move in blocks of n*modes.
|
||||
ex. map 0 will have 0 - 4 Leaderboard id's blocked out.
|
||||
map 1 will have 5 - 10 leaderboard id's blocked out.
|
||||
|
||||
if gamemode is added it will move in blocks of ARRAY_COUNT( modes )
|
||||
|
||||
=====================================
|
||||
*/
|
||||
int LeaderboardLocal_GetID( int mapIndex, int gametype ) {
|
||||
assert( gametype > GAME_RANDOM );
|
||||
|
||||
return mapIndex * ARRAY_COUNT( gameMode_columnDefs ) + gametype;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================================
|
||||
LeaderboardLocal_Init
|
||||
=====================================
|
||||
*/
|
||||
void LeaderboardLocal_Init() {
|
||||
|
||||
const idList< mpMap_t > maps = common->GetMapList();
|
||||
|
||||
const char ** gameModes = NULL;
|
||||
const char ** gameModesDisplay = NULL;
|
||||
int numModes = game->GetMPGameModes( &gameModes, &gameModesDisplay );
|
||||
|
||||
// Iterate through all the available maps, and generate leaderboard Defs, and IDs for each.
|
||||
for( int mapIdx = 0; mapIdx < maps.Num(); mapIdx++ ) {
|
||||
|
||||
for( int modeIdx = 0; modeIdx < numModes; modeIdx++ ) {
|
||||
|
||||
// Check the supported modes on the map.
|
||||
if( maps[ mapIdx ].supportedModes & BIT( modeIdx ) ) {
|
||||
|
||||
const columnGameMode_t gamemode = gameMode_columnDefs[ modeIdx ];
|
||||
|
||||
// Generate a Leaderboard ID for the map/mode
|
||||
int boardID = LeaderboardLocal_GetID( mapIdx, modeIdx );
|
||||
|
||||
|
||||
// Create and Register the leaderboard with the sys_stats registered Leaderboards
|
||||
leaderboardDefinition_t * newLeaderboardDef = Sys_CreateLeaderboardDef( boardID,
|
||||
gamemode.numColumns,
|
||||
gamemode.columnDef,
|
||||
gamemode.rankOrder,
|
||||
gamemode.supportsAttachments,
|
||||
gamemode.checkAgainstCurrent );
|
||||
|
||||
|
||||
|
||||
// Set the leaderboard name.
|
||||
const char* mapname = idLocalization::GetString( maps[ mapIdx ].mapName );
|
||||
newLeaderboardDef->boardName.Format( "%s %s", mapname, gamemode.abrevName );
|
||||
|
||||
// sanity check.
|
||||
if( Sys_FindLeaderboardDef( boardID ) != newLeaderboardDef ) {
|
||||
idLib::Error( "Leaderboards_Init leaderboard creation failed" );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
=====================================
|
||||
LeaderboardLocal_Shutdown
|
||||
=====================================
|
||||
*/
|
||||
void LeaderboardLocal_Shutdown() {
|
||||
|
||||
Sys_DestroyLeaderboardDefs();
|
||||
}
|
||||
|
||||
/*
|
||||
=====================================
|
||||
LeaderboardLocal_Upload
|
||||
=====================================
|
||||
*/
|
||||
|
||||
const static int FRAG_MULTIPLIER = 100;
|
||||
const static int DEATH_MULTIPLIER = -50;
|
||||
const static int WINS_MULTIPLIER = 20;
|
||||
|
||||
void LeaderboardLocal_Upload( lobbyUserID_t lobbyUserID,int gameType, leaderboardStats_t & stats ) {
|
||||
assert( gameType > GAME_RANDOM );
|
||||
|
||||
int mapIdx = 0;
|
||||
|
||||
// Need to figure out What stat columns we want to base rank on. ( for now we'll use wins )
|
||||
const column_t * gameTypeColumn = NULL;
|
||||
const column_t defaultStats[] = { stats.wins };
|
||||
|
||||
// calculate DM score.
|
||||
int dmScore = stats.frags * FRAG_MULTIPLIER + stats.deaths * DEATH_MULTIPLIER + stats.wins * WINS_MULTIPLIER ;
|
||||
// TODO: Once leaderboard menu has correct columns- enable this -> const column_t dmStats[] = { stats.frags, stats.deaths, stats.wins, dmScore };
|
||||
const column_t dmStats[] = { dmScore };
|
||||
|
||||
// Calculate TDM score.
|
||||
int tdmScore = stats.frags * FRAG_MULTIPLIER + stats.teamfrags * FRAG_MULTIPLIER + stats.deaths * DEATH_MULTIPLIER + stats.wins * WINS_MULTIPLIER ;
|
||||
const column_t tdmStats[] = { tdmScore };
|
||||
|
||||
// Calculate Tourney score.
|
||||
int tourneyScore = stats.wins;
|
||||
const column_t tnyStats[] = { tourneyScore };
|
||||
|
||||
// Calculate LMS score.
|
||||
int lmsFrags = stats.frags;
|
||||
if( lmsFrags < 0 ) {
|
||||
lmsFrags = 0; // LMS NO LIVES LEFT = -20 on fragCount.
|
||||
}
|
||||
|
||||
int lmsScore = lmsFrags * FRAG_MULTIPLIER + stats.wins * ( WINS_MULTIPLIER * 10 ) ;
|
||||
const column_t lmsStats[] = { lmsScore };
|
||||
|
||||
// Calculate CTF score.
|
||||
int ctfScore = stats.frags * FRAG_MULTIPLIER + stats.deaths * DEATH_MULTIPLIER + stats.wins * ( WINS_MULTIPLIER * 10 );
|
||||
const column_t ctfStats[] = { ctfScore };
|
||||
|
||||
switch( gameType ) {
|
||||
case GAME_DM:
|
||||
gameTypeColumn = dmStats;
|
||||
break;
|
||||
case GAME_TDM:
|
||||
gameTypeColumn = tdmStats;
|
||||
break;
|
||||
case GAME_TOURNEY:
|
||||
gameTypeColumn = tnyStats;
|
||||
break;
|
||||
case GAME_LASTMAN:
|
||||
gameTypeColumn = lmsStats;
|
||||
break;
|
||||
case GAME_CTF: {
|
||||
gameTypeColumn = ctfStats;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
gameTypeColumn = defaultStats;
|
||||
}
|
||||
|
||||
const idMatchParameters & matchParameters = session->GetActingGameStateLobbyBase().GetMatchParms();
|
||||
const idList< mpMap_t > maps = common->GetMapList();
|
||||
|
||||
// need to find the map Index number
|
||||
for( mapIdx = 0; mapIdx < maps.Num(); mapIdx++ ) {
|
||||
if( matchParameters.mapName.Cmp( maps[ mapIdx ].mapFile ) == 0 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int boardID = LeaderboardLocal_GetID( mapIdx, gameType );
|
||||
const leaderboardDefinition_t * board = Sys_FindLeaderboardDef( boardID );
|
||||
|
||||
if( board ) {
|
||||
session->LeaderboardUpload( lobbyUserID, board, gameTypeColumn );
|
||||
} else {
|
||||
idLib::Warning( "LeaderboardLocal_Upload invalid leaderboard with id of %d", boardID );
|
||||
}
|
||||
}
|
||||
|
||||
class idLeaderboardCallbackTest : public idLeaderboardCallback {
|
||||
void Call() {
|
||||
idLib::Printf( "Leaderboard information retrieved in user callback.\n" );
|
||||
idLib::Printf( "%d total entries in leaderboard %d.\n", numRowsInLeaderboard, def->id );
|
||||
for ( int i = 0; i < rows.Num(); i++ ) {
|
||||
idLib::Printf( "%d: %s rank:%lld", i, rows[i].name.c_str(), rows[i].rank );
|
||||
for ( int j = 0; j < def->numColumns; j++ ) {
|
||||
idLib::Printf( ", score[%d]: %lld", j, rows[i].columns[j] );
|
||||
}
|
||||
idLib::Printf( "\n" );
|
||||
}
|
||||
}
|
||||
idLeaderboardCallback * Clone() const {
|
||||
return new (TAG_PSN) idLeaderboardCallbackTest( *this );
|
||||
}
|
||||
};
|
||||
|
||||
CONSOLE_COMMAND( testLeaderboardDownload, "<id 0 - n > <start = 1> <end = 100>", 0 ) {
|
||||
idLeaderboardCallbackTest leaderboardCallbackTest;
|
||||
|
||||
int leaderboardID = 0;
|
||||
int start = 1;
|
||||
int end = 100;
|
||||
|
||||
if ( args.Argc() > 1 ) {
|
||||
leaderboardID = atoi( args.Argv( 1 ) );
|
||||
}
|
||||
|
||||
if ( args.Argc() > 2 ) {
|
||||
start = atoi( args.Argv( 2 ) );
|
||||
}
|
||||
|
||||
if ( args.Argc() > 3 ) {
|
||||
end = atoi( args.Argv( 3 ) );
|
||||
}
|
||||
|
||||
const leaderboardDefinition_t * leaderboardDef = Sys_FindLeaderboardDef( leaderboardID );
|
||||
|
||||
if( leaderboardDef ) {
|
||||
session->LeaderboardDownload( 0, leaderboardDef, start, end, leaderboardCallbackTest );
|
||||
} else {
|
||||
idLib::Warning( "Sys_FindLeaderboardDef() Unable to find board %d\n", leaderboardID );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CONSOLE_COMMAND( testLeaderboardUpload, "<gameType 0 - 4 > <frags = 0> <wins = 1>", 0 ) {
|
||||
|
||||
idLobbyBase & lobby = session->GetActingGameStateLobbyBase();
|
||||
lobbyUserID_t user = lobby.GetLobbyUserIdByOrdinal( 0 );
|
||||
|
||||
gameType_t gameType = GAME_DM;
|
||||
int frags = 0;
|
||||
int wins = 1;
|
||||
|
||||
if ( args.Argc() > 1 ) {
|
||||
gameType = static_cast<gameType_t>( atoi( args.Argv( 1 ) ) );
|
||||
}
|
||||
|
||||
if ( args.Argc() > 2 ) {
|
||||
frags = atoi( args.Argv( 2 ) );
|
||||
}
|
||||
|
||||
if ( args.Argc() > 3 ) {
|
||||
wins = atoi( args.Argv( 3 ) );
|
||||
}
|
||||
|
||||
leaderboardStats_t stats = { frags, wins, 0, 0 };
|
||||
|
||||
LeaderboardLocal_Upload( user, gameType , stats );
|
||||
|
||||
session->LeaderboardFlush();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
CONSOLE_COMMAND( testLeaderboardUpload_SendToClients, "<gameType 0 - 4 > <frags = 0> <wins = 1>", 0 ) {
|
||||
|
||||
for( int playerIdx = 0; playerIdx < gameLocal.numClients; playerIdx++ ) {
|
||||
|
||||
leaderboardStats_t stats = { 1, 1, 1, 1 };
|
||||
|
||||
LeaderboardLocal_Upload( gameLocal.lobbyUserIDs[ playerIdx ], gameLocal.gameType, stats );
|
||||
}
|
||||
|
||||
// Dont do this more than once.
|
||||
session->LeaderboardFlush();
|
||||
}
|
||||
|
||||
74
neo/d3xp/Leaderboards.h
Normal file
74
neo/d3xp/Leaderboards.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __LEADERBOARDS_LOCAL_H__
|
||||
#define __LEADERBOARDS_LOCAL_H__
|
||||
|
||||
|
||||
struct leaderboardStats_t {
|
||||
int frags;
|
||||
int wins;
|
||||
int teamfrags;
|
||||
int deaths;
|
||||
};
|
||||
|
||||
struct columnGameMode_t {
|
||||
|
||||
columnDef_t * columnDef; // The Column definition for the game mode.
|
||||
int numColumns;
|
||||
rankOrder_t rankOrder; // rank ordering of the game mode. ( RANK_GREATEST_FIRST, RANK_LEAST_FIRST )
|
||||
bool supportsAttachments;
|
||||
bool checkAgainstCurrent;
|
||||
const char * abrevName; // Leaderboard Game Mode Abrev.
|
||||
};
|
||||
|
||||
/*
|
||||
================================================================================================
|
||||
|
||||
Leaderboards
|
||||
|
||||
================================================================================================
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// creates and stores all the leaderboards inside the internal map ( see Sys_FindLeaderboardDef on retrieving definition )
|
||||
void LeaderboardLocal_Init();
|
||||
|
||||
// Destroys any leaderboard definitions allocated by LeaderboardLocal_Init()
|
||||
void LeaderboardLocal_Shutdown();
|
||||
|
||||
// Gets a leaderboard ID with map index and game type.
|
||||
int LeaderboardLocal_GetID( int mapIndex, int gametype );
|
||||
|
||||
// Do it all function. Will create the column_t with the correct stats from the game type, and upload it to the leaderboard system.
|
||||
void LeaderboardLocal_Upload( lobbyUserID_t lobbyUserID, int gameType, leaderboardStats_t & stats );
|
||||
|
||||
extern const columnGameMode_t gameMode_columnDefs[];
|
||||
|
||||
#endif // __LEADERBOARDS_LOCAL_H__
|
||||
1182
neo/d3xp/Light.cpp
Normal file
1182
neo/d3xp/Light.cpp
Normal file
File diff suppressed because it is too large
Load Diff
142
neo/d3xp/Light.h
Normal file
142
neo/d3xp/Light.h
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_LIGHT_H__
|
||||
#define __GAME_LIGHT_H__
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Generic light.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
extern const idEventDef EV_Light_GetLightParm;
|
||||
extern const idEventDef EV_Light_SetLightParm;
|
||||
extern const idEventDef EV_Light_SetLightParms;
|
||||
|
||||
class idLight : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idLight );
|
||||
|
||||
idLight();
|
||||
~idLight();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const; // archives object for save game file
|
||||
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
|
||||
|
||||
virtual void UpdateChangeableSpawnArgs( const idDict *source );
|
||||
virtual void Think();
|
||||
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
|
||||
virtual void FreeLightDef();
|
||||
virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis );
|
||||
void Present();
|
||||
|
||||
void SaveState( idDict *args );
|
||||
virtual void SetColor( float red, float green, float blue );
|
||||
virtual void SetColor( const idVec4 &color );
|
||||
void SetColor( const idVec3 &color );
|
||||
virtual void GetColor( idVec3 &out ) const;
|
||||
virtual void GetColor( idVec4 &out ) const;
|
||||
const idVec3 & GetBaseColor() const { return baseColor; }
|
||||
void SetShader( const char *shadername );
|
||||
void SetLightParm( int parmnum, float value );
|
||||
void SetLightParms( float parm0, float parm1, float parm2, float parm3 );
|
||||
void SetRadiusXYZ( float x, float y, float z );
|
||||
void SetRadius( float radius );
|
||||
void On();
|
||||
void Off();
|
||||
void Fade( const idVec4 &to, float fadeTime );
|
||||
void FadeOut( float time );
|
||||
void FadeIn( float time );
|
||||
void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
|
||||
void BecomeBroken( idEntity *activator );
|
||||
qhandle_t GetLightDefHandle() const { return lightDefHandle; }
|
||||
void SetLightParent( idEntity *lparent ) { lightParent = lparent; }
|
||||
void SetLightLevel();
|
||||
|
||||
virtual void ShowEditingDialog();
|
||||
|
||||
enum {
|
||||
EVENT_BECOMEBROKEN = idEntity::EVENT_MAXEVENTS,
|
||||
EVENT_MAXEVENTS
|
||||
};
|
||||
|
||||
virtual void ClientPredictionThink();
|
||||
virtual void WriteToSnapshot( idBitMsg &msg ) const;
|
||||
virtual void ReadFromSnapshot( const idBitMsg &msg );
|
||||
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
|
||||
|
||||
private:
|
||||
renderLight_t renderLight; // light presented to the renderer
|
||||
idVec3 localLightOrigin; // light origin relative to the physics origin
|
||||
idMat3 localLightAxis; // light axis relative to physics axis
|
||||
qhandle_t lightDefHandle; // handle to renderer light def
|
||||
idStr brokenModel;
|
||||
int levels;
|
||||
int currentLevel;
|
||||
idVec3 baseColor;
|
||||
|
||||
// Colors used for client-side interpolation.
|
||||
idVec3 previousBaseColor;
|
||||
idVec3 nextBaseColor;
|
||||
|
||||
bool breakOnTrigger;
|
||||
int count;
|
||||
int triggercount;
|
||||
idEntity * lightParent;
|
||||
idVec4 fadeFrom;
|
||||
idVec4 fadeTo;
|
||||
int fadeStart;
|
||||
int fadeEnd;
|
||||
bool soundWasPlaying;
|
||||
|
||||
private:
|
||||
void PresentLightDefChange();
|
||||
void PresentModelDefChange();
|
||||
|
||||
void Event_SetShader( const char *shadername );
|
||||
void Event_GetLightParm( int parmnum );
|
||||
void Event_SetLightParm( int parmnum, float value );
|
||||
void Event_SetLightParms( float parm0, float parm1, float parm2, float parm3 );
|
||||
void Event_SetRadiusXYZ( float x, float y, float z );
|
||||
void Event_SetRadius( float radius );
|
||||
void Event_Hide();
|
||||
void Event_Show();
|
||||
void Event_On();
|
||||
void Event_Off();
|
||||
void Event_ToggleOnOff( idEntity *activator );
|
||||
void Event_SetSoundHandles();
|
||||
void Event_FadeOut( float time );
|
||||
void Event_FadeIn( float time );
|
||||
};
|
||||
|
||||
#endif /* !__GAME_LIGHT_H__ */
|
||||
3934
neo/d3xp/Misc.cpp
Normal file
3934
neo/d3xp/Misc.cpp
Normal file
File diff suppressed because it is too large
Load Diff
928
neo/d3xp/Misc.h
Normal file
928
neo/d3xp/Misc.h
Normal file
@@ -0,0 +1,928 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_MISC_H__
|
||||
#define __GAME_MISC_H__
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idSpawnableEntity
|
||||
|
||||
A simple, spawnable entity with a model and no functionable ability of it's own.
|
||||
For example, it can be used as a placeholder during development, for marking
|
||||
locations on maps for script, or for simple placed models without any behavior
|
||||
that can be bound to other entities. Should not be subclassed.
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idSpawnableEntity : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idSpawnableEntity );
|
||||
|
||||
void Spawn();
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Potential spawning position for players.
|
||||
The first time a player enters the game, they will be at an 'initial' spot.
|
||||
Targets will be fired when someone spawns in on them.
|
||||
|
||||
When triggered, will cause player to be teleported to spawn spot.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idPlayerStart : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idPlayerStart );
|
||||
|
||||
enum {
|
||||
EVENT_TELEPORTPLAYER = idEntity::EVENT_MAXEVENTS,
|
||||
EVENT_MAXEVENTS
|
||||
};
|
||||
|
||||
idPlayerStart();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
|
||||
|
||||
private:
|
||||
int teleportStage;
|
||||
|
||||
void Event_TeleportPlayer( idEntity *activator );
|
||||
void Event_TeleportStage( idEntity *player );
|
||||
void TeleportPlayer( idPlayer *player );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Non-displayed entity used to activate triggers when it touches them.
|
||||
Bind to a mover to have the mover activate a trigger as it moves.
|
||||
When target by triggers, activating the trigger will toggle the
|
||||
activator on and off. Check "start_off" to have it spawn disabled.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idActivator : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idActivator );
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void Think();
|
||||
|
||||
private:
|
||||
bool stay_on;
|
||||
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Path entities for monsters to follow.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
class idPathCorner : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idPathCorner );
|
||||
|
||||
void Spawn();
|
||||
|
||||
static void DrawDebugInfo();
|
||||
|
||||
static idPathCorner *RandomPath( const idEntity *source, const idEntity *ignore );
|
||||
|
||||
private:
|
||||
void Event_RandomPath();
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Object that fires targets and changes shader parms when damaged.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idDamagable : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idDamagable );
|
||||
|
||||
idDamagable();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
|
||||
|
||||
virtual void Hide();
|
||||
virtual void Show();
|
||||
|
||||
private:
|
||||
int count;
|
||||
int nextTriggerTime;
|
||||
|
||||
void BecomeBroken( idEntity *activator );
|
||||
void Event_BecomeBroken( idEntity *activator );
|
||||
void Event_RestoreDamagable();
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Hidden object that explodes when activated
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idExplodable : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idExplodable );
|
||||
|
||||
void Spawn();
|
||||
|
||||
private:
|
||||
void Event_Explode( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idSpring
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idSpring : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idSpring );
|
||||
|
||||
void Spawn();
|
||||
|
||||
virtual void Think();
|
||||
|
||||
private:
|
||||
idEntity * ent1;
|
||||
idEntity * ent2;
|
||||
int id1;
|
||||
int id2;
|
||||
idVec3 p1;
|
||||
idVec3 p2;
|
||||
idForce_Spring spring;
|
||||
|
||||
void Event_LinkSpring();
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idForceField
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idForceField : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idForceField );
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
|
||||
virtual void Think();
|
||||
virtual void ClientThink( const int curTime, const float fraction, const bool predict ) ;
|
||||
private:
|
||||
idForce_Field forceField;
|
||||
|
||||
void Toggle();
|
||||
|
||||
void Event_Activate( idEntity *activator );
|
||||
void Event_Toggle();
|
||||
void Event_FindTargets();
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idAnimated
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idAnimated : public idAFEntity_Gibbable {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idAnimated );
|
||||
|
||||
idAnimated();
|
||||
~idAnimated();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
virtual bool LoadAF();
|
||||
bool StartRagdoll();
|
||||
virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis );
|
||||
|
||||
private:
|
||||
int num_anims;
|
||||
int current_anim_index;
|
||||
int anim;
|
||||
int blendFrames;
|
||||
jointHandle_t soundJoint;
|
||||
idEntityPtr<idEntity> activator;
|
||||
bool activated;
|
||||
int achievement;
|
||||
|
||||
void PlayNextAnim();
|
||||
|
||||
void Event_Activate( idEntity *activator );
|
||||
void Event_Start();
|
||||
void Event_StartRagdoll();
|
||||
void Event_AnimDone( int animIndex );
|
||||
void Event_Footstep();
|
||||
void Event_LaunchMissiles( const char *projectilename, const char *sound, const char *launchjoint, const char *targetjoint, int numshots, int framedelay );
|
||||
void Event_LaunchMissilesUpdate( int launchjoint, int targetjoint, int numshots, int framedelay );
|
||||
void Event_SetAnimation( const char *animName );
|
||||
void Event_GetAnimationLength();
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idStaticEntity
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idStaticEntity : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idStaticEntity );
|
||||
|
||||
idStaticEntity();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
void ShowEditingDialog();
|
||||
virtual void Hide();
|
||||
virtual void Show();
|
||||
void Fade( const idVec4 &to, float fadeTime );
|
||||
virtual void Think();
|
||||
|
||||
virtual void WriteToSnapshot( idBitMsg &msg ) const;
|
||||
virtual void ReadFromSnapshot( const idBitMsg &msg );
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
|
||||
int spawnTime;
|
||||
bool active;
|
||||
idVec4 fadeFrom;
|
||||
idVec4 fadeTo;
|
||||
int fadeStart;
|
||||
int fadeEnd;
|
||||
bool runGui;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idFuncEmitter
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idFuncEmitter : public idStaticEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idFuncEmitter );
|
||||
|
||||
idFuncEmitter();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
void Event_Activate( idEntity *activator );
|
||||
|
||||
virtual void WriteToSnapshot( idBitMsg &msg ) const;
|
||||
virtual void ReadFromSnapshot( const idBitMsg &msg );
|
||||
|
||||
private:
|
||||
bool hidden;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idFuncShootProjectile
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idFuncShootProjectile : public idStaticEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idFuncShootProjectile );
|
||||
|
||||
idFuncShootProjectile();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
void Event_Activate( idEntity *activator );
|
||||
|
||||
virtual void Think();
|
||||
|
||||
virtual void WriteToSnapshot( idBitMsg &msg ) const;
|
||||
virtual void ReadFromSnapshot( const idBitMsg &msg );
|
||||
|
||||
private:
|
||||
int mRespawnDelay;
|
||||
int mRespawnTime;
|
||||
float mShootSpeed;
|
||||
idVec3 mShootDir;
|
||||
idStr mEntityDefName;
|
||||
idEntityPtr< idEntity > mLastProjectile;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idFuncSmoke
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idFuncSmoke : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idFuncSmoke );
|
||||
|
||||
idFuncSmoke();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void Think();
|
||||
void Event_Activate( idEntity *activator );
|
||||
|
||||
private:
|
||||
int smokeTime;
|
||||
const idDeclParticle * smoke;
|
||||
bool restart;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idFuncSplat
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idFuncSplat : public idFuncEmitter {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idFuncSplat );
|
||||
|
||||
idFuncSplat();
|
||||
|
||||
void Spawn();
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
void Event_Splat();
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTextEntity
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTextEntity : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTextEntity );
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void Think();
|
||||
|
||||
private:
|
||||
idStr text;
|
||||
bool playerOriented;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idLocationEntity
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idLocationEntity : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idLocationEntity );
|
||||
|
||||
void Spawn();
|
||||
|
||||
const char * GetLocation() const;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class idLocationSeparatorEntity : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idLocationSeparatorEntity );
|
||||
|
||||
void Spawn();
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class idVacuumSeparatorEntity : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idVacuumSeparatorEntity );
|
||||
|
||||
idVacuumSeparatorEntity();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Event_Activate( idEntity *activator );
|
||||
|
||||
private:
|
||||
qhandle_t portal;
|
||||
};
|
||||
|
||||
class idVacuumEntity : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idVacuumEntity );
|
||||
|
||||
void Spawn();
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idBeam
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idBeam : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idBeam );
|
||||
|
||||
idBeam();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void Think();
|
||||
|
||||
void SetMaster( idBeam *masterbeam );
|
||||
void SetBeamTarget( const idVec3 &origin );
|
||||
|
||||
virtual void Show();
|
||||
|
||||
virtual void WriteToSnapshot( idBitMsg &msg ) const;
|
||||
virtual void ReadFromSnapshot( const idBitMsg &msg );
|
||||
|
||||
private:
|
||||
void Event_MatchTarget();
|
||||
void Event_Activate( idEntity *activator );
|
||||
|
||||
idEntityPtr<idBeam> target;
|
||||
idEntityPtr<idBeam> master;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idLiquid
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idRenderModelLiquid;
|
||||
|
||||
class idLiquid : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idLiquid );
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
private:
|
||||
void Event_Touch( idEntity *other, trace_t *trace );
|
||||
|
||||
|
||||
idRenderModelLiquid *model;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idShaking
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idShaking : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idShaking );
|
||||
|
||||
idShaking();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
private:
|
||||
idPhysics_Parametric physicsObj;
|
||||
bool active;
|
||||
|
||||
void BeginShaking();
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idEarthQuake
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idEarthQuake : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idEarthQuake );
|
||||
|
||||
idEarthQuake();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void Think();
|
||||
|
||||
private:
|
||||
int nextTriggerTime;
|
||||
int shakeStopTime;
|
||||
float wait;
|
||||
float random;
|
||||
bool triggered;
|
||||
bool playerOriented;
|
||||
bool disabled;
|
||||
float shakeTime;
|
||||
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idFuncPortal
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idFuncPortal : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idFuncPortal );
|
||||
|
||||
idFuncPortal();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
private:
|
||||
qhandle_t portal;
|
||||
bool state;
|
||||
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idFuncAASPortal
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idFuncAASPortal : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idFuncAASPortal );
|
||||
|
||||
idFuncAASPortal();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
private:
|
||||
bool state;
|
||||
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idFuncAASObstacle
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idFuncAASObstacle : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idFuncAASObstacle );
|
||||
|
||||
idFuncAASObstacle();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
private:
|
||||
bool state;
|
||||
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idFuncRadioChatter
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idFuncRadioChatter : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idFuncRadioChatter );
|
||||
|
||||
idFuncRadioChatter();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
private:
|
||||
float time;
|
||||
void Event_Activate( idEntity *activator );
|
||||
void Event_ResetRadioHud( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idPhantomObjects
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idPhantomObjects : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idPhantomObjects );
|
||||
|
||||
idPhantomObjects();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void Think();
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
void Event_Throw();
|
||||
void Event_ShakeObject( idEntity *object, int starttime );
|
||||
|
||||
int end_time;
|
||||
float throw_time;
|
||||
float shake_time;
|
||||
idVec3 shake_ang;
|
||||
float speed;
|
||||
int min_wait;
|
||||
int max_wait;
|
||||
idEntityPtr<idActor>target;
|
||||
idList<int> targetTime;
|
||||
idList<idVec3> lastTargetPos;
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idShockwave
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
class idShockwave : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idShockwave );
|
||||
|
||||
idShockwave();
|
||||
~idShockwave();
|
||||
|
||||
void Spawn();
|
||||
void Think();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
|
||||
bool isActive;
|
||||
int startTime;
|
||||
int duration;
|
||||
|
||||
float startSize;
|
||||
float endSize;
|
||||
float currentSize;
|
||||
|
||||
float magnitude;
|
||||
|
||||
float height;
|
||||
bool playerDamaged;
|
||||
float playerDamageSize;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idFuncMountedObject
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
class idFuncMountedObject : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idFuncMountedObject );
|
||||
|
||||
idFuncMountedObject();
|
||||
~idFuncMountedObject();
|
||||
|
||||
void Spawn();
|
||||
void Think();
|
||||
|
||||
void GetAngleRestrictions( int &yaw_min, int &yaw_max, int &pitch );
|
||||
|
||||
private:
|
||||
int harc;
|
||||
int varc;
|
||||
|
||||
void Event_Touch( idEntity *other, trace_t *trace );
|
||||
void Event_Activate( idEntity *activator );
|
||||
|
||||
public:
|
||||
bool isMounted;
|
||||
function_t * scriptFunction;
|
||||
idPlayer * mountedPlayer;
|
||||
};
|
||||
|
||||
|
||||
class idFuncMountedWeapon : public idFuncMountedObject {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idFuncMountedWeapon );
|
||||
|
||||
idFuncMountedWeapon();
|
||||
~idFuncMountedWeapon();
|
||||
|
||||
void Spawn();
|
||||
void Think();
|
||||
|
||||
private:
|
||||
|
||||
// The actual turret that moves with the player's view
|
||||
idEntity * turret;
|
||||
|
||||
// the muzzle bone's position, used for launching projectiles and trailing smoke
|
||||
idVec3 muzzleOrigin;
|
||||
idMat3 muzzleAxis;
|
||||
|
||||
float weaponLastFireTime;
|
||||
float weaponFireDelay;
|
||||
|
||||
const idDict * projectile;
|
||||
|
||||
const idSoundShader *soundFireWeapon;
|
||||
|
||||
void Event_PostSpawn();
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idPortalSky
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
class idPortalSky : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idPortalSky );
|
||||
|
||||
idPortalSky();
|
||||
~idPortalSky();
|
||||
|
||||
void Spawn();
|
||||
void Event_PostSpawn();
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
#endif /* !__GAME_MISC_H__ */
|
||||
1355
neo/d3xp/Moveable.cpp
Normal file
1355
neo/d3xp/Moveable.cpp
Normal file
File diff suppressed because it is too large
Load Diff
210
neo/d3xp/Moveable.h
Normal file
210
neo/d3xp/Moveable.h
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_MOVEABLE_H__
|
||||
#define __GAME_MOVEABLE_H__
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Entity using rigid body physics.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
extern const idEventDef EV_BecomeNonSolid;
|
||||
extern const idEventDef EV_IsAtRest;
|
||||
|
||||
class idMoveable : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idMoveable );
|
||||
|
||||
idMoveable();
|
||||
~idMoveable();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void Think();
|
||||
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
|
||||
virtual void Hide();
|
||||
virtual void Show();
|
||||
|
||||
bool AllowStep() const;
|
||||
void EnableDamage( bool enable, float duration );
|
||||
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
|
||||
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
|
||||
virtual void WriteToSnapshot( idBitMsg &msg ) const;
|
||||
virtual void ReadFromSnapshot( const idBitMsg &msg );
|
||||
|
||||
void SetAttacker( idEntity *ent );
|
||||
const idEntity * GetAttacker() { return attacker; }
|
||||
|
||||
protected:
|
||||
idPhysics_RigidBody physicsObj; // physics object
|
||||
idStr brokenModel; // model set when health drops down to or below zero
|
||||
idStr damage; // if > 0 apply damage to hit entities
|
||||
idStr monsterDamage;
|
||||
idEntity *attacker;
|
||||
idStr fxCollide; // fx system to start when collides with something
|
||||
int nextCollideFxTime; // next time it is ok to spawn collision fx
|
||||
float minDamageVelocity; // minimum velocity before moveable applies damage
|
||||
float maxDamageVelocity; // velocity at which the maximum damage is applied
|
||||
idCurve_Spline<idVec3> *initialSpline; // initial spline path the moveable follows
|
||||
idVec3 initialSplineDir; // initial relative direction along the spline path
|
||||
bool explode; // entity explodes when health drops down to or below zero
|
||||
bool unbindOnDeath; // unbind from master when health drops down to or below zero
|
||||
bool allowStep; // allow monsters to step on the object
|
||||
bool canDamage; // only apply damage when this is set
|
||||
int nextDamageTime; // next time the movable can hurt the player
|
||||
int nextSoundTime; // next time the moveable can make a sound
|
||||
|
||||
const idMaterial * GetRenderModelMaterial() const;
|
||||
void BecomeNonSolid();
|
||||
void InitInitialSpline( int startTime );
|
||||
bool FollowInitialSplinePath();
|
||||
|
||||
void Event_Activate( idEntity *activator );
|
||||
void Event_BecomeNonSolid();
|
||||
void Event_SetOwnerFromSpawnArgs();
|
||||
void Event_IsAtRest();
|
||||
void Event_EnableDamage( float enable );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
A barrel using rigid body physics. The barrel has special handling of
|
||||
the view model orientation to make it look like it rolls instead of slides.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idBarrel : public idMoveable {
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( idBarrel );
|
||||
idBarrel();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void BarrelThink();
|
||||
virtual void Think();
|
||||
virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis );
|
||||
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
|
||||
|
||||
private:
|
||||
float radius; // radius of barrel
|
||||
int barrelAxis; // one of the coordinate axes the barrel cylinder is parallel to
|
||||
idVec3 lastOrigin; // origin of the barrel the last think frame
|
||||
idMat3 lastAxis; // axis of the barrel the last think frame
|
||||
float additionalRotation; // additional rotation of the barrel about it's axis
|
||||
idMat3 additionalAxis; // additional rotation axis
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
A barrel using rigid body physics and special handling of the view model
|
||||
orientation to make it look like it rolls instead of slides. The barrel
|
||||
can burn and explode when damaged.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idExplodingBarrel : public idBarrel {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idExplodingBarrel );
|
||||
|
||||
idExplodingBarrel();
|
||||
~idExplodingBarrel();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
bool IsStable();
|
||||
void SetStability( bool stability );
|
||||
void StartBurning();
|
||||
void StopBurning();
|
||||
|
||||
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
|
||||
virtual void Think();
|
||||
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 WriteToSnapshot( idBitMsg &msg ) const;
|
||||
virtual void ReadFromSnapshot( const idBitMsg &msg );
|
||||
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
|
||||
|
||||
enum {
|
||||
EVENT_EXPLODE = idEntity::EVENT_MAXEVENTS,
|
||||
EVENT_MAXEVENTS
|
||||
};
|
||||
|
||||
private:
|
||||
typedef enum {
|
||||
NORMAL = 0,
|
||||
BURNING,
|
||||
BURNEXPIRED,
|
||||
EXPLODING
|
||||
} explode_state_t;
|
||||
explode_state_t state;
|
||||
|
||||
idVec3 spawnOrigin;
|
||||
idMat3 spawnAxis;
|
||||
qhandle_t particleModelDefHandle;
|
||||
qhandle_t lightDefHandle;
|
||||
renderEntity_t particleRenderEntity;
|
||||
renderLight_t light;
|
||||
int particleTime;
|
||||
int lightTime;
|
||||
float time;
|
||||
bool isStable;
|
||||
|
||||
void AddParticles( const char *name, bool burn );
|
||||
void AddLight( const char *name , bool burn );
|
||||
void ExplodingEffects();
|
||||
void UpdateLight();
|
||||
|
||||
void Event_Activate( idEntity *activator );
|
||||
void Event_Respawn();
|
||||
void Event_Explode();
|
||||
void Event_TriggerTargets();
|
||||
};
|
||||
|
||||
#endif /* !__GAME_MOVEABLE_H__ */
|
||||
4852
neo/d3xp/Mover.cpp
Normal file
4852
neo/d3xp/Mover.cpp
Normal file
File diff suppressed because it is too large
Load Diff
556
neo/d3xp/Mover.h
Normal file
556
neo/d3xp/Mover.h
Normal file
@@ -0,0 +1,556 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_MOVER_H__
|
||||
#define __GAME_MOVER_H__
|
||||
|
||||
extern const idEventDef EV_TeamBlocked;
|
||||
extern const idEventDef EV_PartBlocked;
|
||||
extern const idEventDef EV_ReachedPos;
|
||||
extern const idEventDef EV_ReachedAng;
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
General movers.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idMover : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idMover );
|
||||
|
||||
idMover();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
|
||||
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
|
||||
virtual void WriteToSnapshot( idBitMsg &msg ) const;
|
||||
virtual void ReadFromSnapshot( const idBitMsg &msg );
|
||||
|
||||
virtual void Hide();
|
||||
virtual void Show();
|
||||
|
||||
void SetPortalState( bool open );
|
||||
|
||||
protected:
|
||||
typedef enum {
|
||||
ACCELERATION_STAGE,
|
||||
LINEAR_STAGE,
|
||||
DECELERATION_STAGE,
|
||||
FINISHED_STAGE
|
||||
} moveStage_t;
|
||||
|
||||
typedef enum {
|
||||
MOVER_NONE,
|
||||
MOVER_ROTATING,
|
||||
MOVER_MOVING,
|
||||
MOVER_SPLINE
|
||||
} moverCommand_t;
|
||||
|
||||
//
|
||||
// mover directions. make sure to change script/doom_defs.script if you add any, or change their order
|
||||
//
|
||||
typedef enum {
|
||||
DIR_UP = -1,
|
||||
DIR_DOWN = -2,
|
||||
DIR_LEFT = -3,
|
||||
DIR_RIGHT = -4,
|
||||
DIR_FORWARD = -5,
|
||||
DIR_BACK = -6,
|
||||
DIR_REL_UP = -7,
|
||||
DIR_REL_DOWN = -8,
|
||||
DIR_REL_LEFT = -9,
|
||||
DIR_REL_RIGHT = -10,
|
||||
DIR_REL_FORWARD = -11,
|
||||
DIR_REL_BACK = -12
|
||||
} moverDir_t;
|
||||
|
||||
typedef struct {
|
||||
moveStage_t stage;
|
||||
int acceleration;
|
||||
int movetime;
|
||||
int deceleration;
|
||||
idVec3 dir;
|
||||
} moveState_t;
|
||||
|
||||
typedef struct {
|
||||
moveStage_t stage;
|
||||
int acceleration;
|
||||
int movetime;
|
||||
int deceleration;
|
||||
idAngles rot;
|
||||
} rotationState_t;
|
||||
|
||||
idPhysics_Parametric physicsObj;
|
||||
|
||||
void Event_OpenPortal();
|
||||
void Event_ClosePortal();
|
||||
void Event_PartBlocked( idEntity *blockingEntity );
|
||||
|
||||
void MoveToPos( const idVec3 &pos);
|
||||
void UpdateMoveSound( moveStage_t stage );
|
||||
void UpdateRotationSound( moveStage_t stage );
|
||||
void SetGuiStates( const char *state );
|
||||
void FindGuiTargets();
|
||||
void SetGuiState( const char *key, const char *val ) const;
|
||||
|
||||
virtual void DoneMoving();
|
||||
virtual void DoneRotating();
|
||||
virtual void BeginMove( idThread *thread = NULL );
|
||||
virtual void BeginRotation( idThread *thread, bool stopwhendone );
|
||||
moveState_t move;
|
||||
|
||||
private:
|
||||
rotationState_t rot;
|
||||
|
||||
int move_thread;
|
||||
int rotate_thread;
|
||||
idAngles dest_angles;
|
||||
idAngles angle_delta;
|
||||
idVec3 dest_position;
|
||||
idVec3 move_delta;
|
||||
float move_speed;
|
||||
int move_time;
|
||||
int deceltime;
|
||||
int acceltime;
|
||||
bool stopRotation;
|
||||
bool useSplineAngles;
|
||||
idEntityPtr<idEntity> splineEnt;
|
||||
moverCommand_t lastCommand;
|
||||
float damage;
|
||||
|
||||
qhandle_t areaPortal; // 0 = no portal
|
||||
|
||||
idList< idEntityPtr<idEntity>, TAG_MOVER > guiTargets;
|
||||
|
||||
void VectorForDir( float dir, idVec3 &vec );
|
||||
idCurve_Spline<idVec3> *GetSpline( idEntity *splineEntity ) const;
|
||||
|
||||
void Event_SetCallback();
|
||||
void Event_TeamBlocked( idEntity *blockedPart, idEntity *blockingEntity );
|
||||
void Event_StopMoving();
|
||||
void Event_StopRotating();
|
||||
void Event_UpdateMove();
|
||||
void Event_UpdateRotation();
|
||||
void Event_SetMoveSpeed( float speed );
|
||||
void Event_SetMoveTime( float time );
|
||||
void Event_SetDecelerationTime( float time );
|
||||
void Event_SetAccellerationTime( float time );
|
||||
void Event_MoveTo( idEntity *ent );
|
||||
void Event_MoveToPos( idVec3 &pos );
|
||||
void Event_MoveDir( float angle, float distance );
|
||||
void Event_MoveAccelerateTo( float speed, float time );
|
||||
void Event_MoveDecelerateTo( float speed, float time );
|
||||
void Event_RotateDownTo( int axis, float angle );
|
||||
void Event_RotateUpTo( int axis, float angle );
|
||||
void Event_RotateTo( idAngles &angles );
|
||||
void Event_Rotate( idAngles &angles );
|
||||
void Event_RotateOnce( idAngles &angles );
|
||||
void Event_Bob( float speed, float phase, idVec3 &depth );
|
||||
void Event_Sway( float speed, float phase, idAngles &depth );
|
||||
void Event_SetAccelSound( const char *sound );
|
||||
void Event_SetDecelSound( const char *sound );
|
||||
void Event_SetMoveSound( const char *sound );
|
||||
void Event_FindGuiTargets();
|
||||
void Event_InitGuiTargets();
|
||||
void Event_EnableSplineAngles();
|
||||
void Event_DisableSplineAngles();
|
||||
void Event_RemoveInitialSplineAngles();
|
||||
void Event_StartSpline( idEntity *splineEntity );
|
||||
void Event_StopSpline();
|
||||
void Event_Activate( idEntity *activator );
|
||||
void Event_PostRestore( int start, int total, int accel, int decel, int useSplineAng );
|
||||
void Event_IsMoving();
|
||||
void Event_IsRotating();
|
||||
};
|
||||
|
||||
class idSplinePath : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idSplinePath );
|
||||
|
||||
idSplinePath();
|
||||
|
||||
void Spawn();
|
||||
};
|
||||
|
||||
|
||||
struct floorInfo_s {
|
||||
idVec3 pos;
|
||||
idStr door;
|
||||
int floor;
|
||||
};
|
||||
|
||||
class idElevator : public idMover {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idElevator );
|
||||
|
||||
idElevator();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual bool HandleSingleGuiCommand( idEntity *entityGui, idLexer *src );
|
||||
void Event_GotoFloor( int floor );
|
||||
floorInfo_s * GetFloorInfo( int floor );
|
||||
|
||||
protected:
|
||||
virtual void DoneMoving();
|
||||
virtual void BeginMove( idThread *thread = NULL );
|
||||
void SpawnTrigger( const idVec3 &pos );
|
||||
void GetLocalTriggerPosition();
|
||||
void Event_Touch( idEntity *other, trace_t *trace );
|
||||
|
||||
private:
|
||||
typedef enum {
|
||||
INIT,
|
||||
IDLE,
|
||||
WAITING_ON_DOORS
|
||||
} elevatorState_t;
|
||||
|
||||
elevatorState_t state;
|
||||
idList<floorInfo_s, TAG_MOVER> floorInfo;
|
||||
int currentFloor;
|
||||
int pendingFloor;
|
||||
int lastFloor;
|
||||
bool controlsDisabled;
|
||||
float returnTime;
|
||||
int returnFloor;
|
||||
int lastTouchTime;
|
||||
|
||||
class idDoor * GetDoor( const char *name );
|
||||
void Think();
|
||||
void OpenInnerDoor();
|
||||
void OpenFloorDoor( int floor );
|
||||
void CloseAllDoors();
|
||||
void DisableAllDoors();
|
||||
void EnableProperDoors();
|
||||
|
||||
void Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity );
|
||||
void Event_Activate( idEntity *activator );
|
||||
void Event_PostFloorArrival();
|
||||
|
||||
void Event_SetGuiStates();
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Binary movers.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
MOVER_POS1,
|
||||
MOVER_POS2,
|
||||
MOVER_1TO2,
|
||||
MOVER_2TO1
|
||||
} moverState_t;
|
||||
|
||||
class idMover_Binary : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idMover_Binary );
|
||||
|
||||
idMover_Binary();
|
||||
~idMover_Binary();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void PreBind();
|
||||
virtual void PostBind();
|
||||
|
||||
void Enable( bool b );
|
||||
void InitSpeed( idVec3 &mpos1, idVec3 &mpos2, float mspeed, float maccelTime, float mdecelTime );
|
||||
void InitTime( idVec3 &mpos1, idVec3 &mpos2, float mtime, float maccelTime, float mdecelTime );
|
||||
void GotoPosition1();
|
||||
void GotoPosition2();
|
||||
void Use_BinaryMover( idEntity *activator );
|
||||
void SetGuiStates( const char *state );
|
||||
void UpdateBuddies( int val );
|
||||
idMover_Binary * GetActivateChain() const { return activateChain; }
|
||||
idMover_Binary * GetMoveMaster() const { return moveMaster; }
|
||||
void BindTeam( idEntity *bindTo );
|
||||
void SetBlocked( bool b );
|
||||
bool IsBlocked();
|
||||
idEntity * GetActivator() const;
|
||||
|
||||
virtual void WriteToSnapshot( idBitMsg &msg ) const;
|
||||
virtual void ReadFromSnapshot( const idBitMsg &msg );
|
||||
|
||||
void SetPortalState( bool open );
|
||||
|
||||
protected:
|
||||
idVec3 pos1;
|
||||
idVec3 pos2;
|
||||
moverState_t moverState;
|
||||
idMover_Binary * moveMaster;
|
||||
idMover_Binary * activateChain;
|
||||
int soundPos1;
|
||||
int sound1to2;
|
||||
int sound2to1;
|
||||
int soundPos2;
|
||||
int soundLoop;
|
||||
float wait;
|
||||
float damage;
|
||||
int duration;
|
||||
int accelTime;
|
||||
int decelTime;
|
||||
idEntityPtr<idEntity> activatedBy;
|
||||
int stateStartTime;
|
||||
idStr team;
|
||||
bool enabled;
|
||||
int move_thread;
|
||||
int updateStatus; // 1 = lock behaviour, 2 = open close status
|
||||
idStrList buddies;
|
||||
idPhysics_Parametric physicsObj;
|
||||
qhandle_t areaPortal; // 0 = no portal
|
||||
bool blocked;
|
||||
bool playerOnly;
|
||||
idList< idEntityPtr<idEntity>, TAG_MOVER > guiTargets;
|
||||
|
||||
void MatchActivateTeam( moverState_t newstate, int time );
|
||||
void JoinActivateTeam( idMover_Binary *master );
|
||||
|
||||
void UpdateMoverSound( moverState_t state );
|
||||
void SetMoverState( moverState_t newstate, int time );
|
||||
moverState_t GetMoverState() const { return moverState; }
|
||||
void FindGuiTargets();
|
||||
void SetGuiState( const char *key, const char *val ) const;
|
||||
|
||||
void Event_SetCallback();
|
||||
void Event_ReturnToPos1();
|
||||
void Event_Use_BinaryMover( idEntity *activator );
|
||||
void Event_Reached_BinaryMover();
|
||||
void Event_MatchActivateTeam( moverState_t newstate, int time );
|
||||
void Event_Enable();
|
||||
void Event_Disable();
|
||||
void Event_OpenPortal();
|
||||
void Event_ClosePortal();
|
||||
void Event_FindGuiTargets();
|
||||
void Event_InitGuiTargets();
|
||||
|
||||
static void GetMovedir( float dir, idVec3 &movedir );
|
||||
};
|
||||
|
||||
class idDoor : public idMover_Binary {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idDoor );
|
||||
|
||||
idDoor();
|
||||
~idDoor();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
|
||||
virtual void Think();
|
||||
virtual void PreBind();
|
||||
virtual void PostBind();
|
||||
virtual void Hide();
|
||||
virtual void Show();
|
||||
|
||||
bool IsOpen();
|
||||
bool IsNoTouch();
|
||||
bool AllowPlayerOnly( idEntity *ent );
|
||||
int IsLocked();
|
||||
void Lock( int f );
|
||||
void Use( idEntity *other, idEntity *activator );
|
||||
void Close();
|
||||
void Open();
|
||||
void SetCompanion( idDoor *door );
|
||||
|
||||
private:
|
||||
float triggersize;
|
||||
bool crusher;
|
||||
bool noTouch;
|
||||
bool aas_area_closed;
|
||||
idStr buddyStr;
|
||||
idClipModel * trigger;
|
||||
idClipModel * sndTrigger;
|
||||
int nextSndTriggerTime;
|
||||
idVec3 localTriggerOrigin;
|
||||
idMat3 localTriggerAxis;
|
||||
idStr requires;
|
||||
int removeItem;
|
||||
idStr syncLock;
|
||||
int normalAxisIndex; // door faces X or Y for spectator teleports
|
||||
idDoor * companionDoor;
|
||||
|
||||
void SetAASAreaState( bool closed );
|
||||
|
||||
void GetLocalTriggerPosition( const idClipModel *trigger );
|
||||
void CalcTriggerBounds( float size, idBounds &bounds );
|
||||
|
||||
void Event_Reached_BinaryMover();
|
||||
void Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity );
|
||||
void Event_PartBlocked( idEntity *blockingEntity );
|
||||
void Event_Touch( idEntity *other, trace_t *trace );
|
||||
void Event_Activate( idEntity *activator );
|
||||
void Event_StartOpen();
|
||||
void Event_SpawnDoorTrigger();
|
||||
void Event_SpawnSoundTrigger();
|
||||
void Event_Close();
|
||||
void Event_Open();
|
||||
void Event_Lock( int f );
|
||||
void Event_IsOpen();
|
||||
void Event_Locked();
|
||||
void Event_SpectatorTouch( idEntity *other, trace_t *trace );
|
||||
void Event_OpenPortal();
|
||||
void Event_ClosePortal();
|
||||
};
|
||||
|
||||
class idPlat : public idMover_Binary {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idPlat );
|
||||
|
||||
idPlat();
|
||||
~idPlat();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
void RunPhysics_NoBlocking();
|
||||
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
|
||||
virtual void Think();
|
||||
virtual void PreBind();
|
||||
virtual void PostBind();
|
||||
|
||||
private:
|
||||
idClipModel * trigger;
|
||||
idVec3 localTriggerOrigin;
|
||||
idMat3 localTriggerAxis;
|
||||
|
||||
void GetLocalTriggerPosition( const idClipModel *trigger );
|
||||
void SpawnPlatTrigger( idVec3 &pos );
|
||||
|
||||
void Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity );
|
||||
void Event_PartBlocked( idEntity *blockingEntity );
|
||||
void Event_Touch( idEntity *other, trace_t *trace );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Special periodic movers.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idMover_Periodic : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idMover_Periodic );
|
||||
|
||||
idMover_Periodic();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void Think();
|
||||
|
||||
virtual void WriteToSnapshot( idBitMsg &msg ) const;
|
||||
virtual void ReadFromSnapshot( const idBitMsg &msg );
|
||||
|
||||
protected:
|
||||
idPhysics_Parametric physicsObj;
|
||||
float damage;
|
||||
|
||||
void Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity );
|
||||
void Event_PartBlocked( idEntity *blockingEntity );
|
||||
};
|
||||
|
||||
class idRotater : public idMover_Periodic {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idRotater );
|
||||
|
||||
idRotater();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
private:
|
||||
idEntityPtr<idEntity> activatedBy;
|
||||
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
class idBobber : public idMover_Periodic {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idBobber );
|
||||
|
||||
idBobber();
|
||||
|
||||
void Spawn();
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class idPendulum : public idMover_Periodic {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idPendulum );
|
||||
|
||||
idPendulum();
|
||||
|
||||
void Spawn();
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class idRiser : public idMover_Periodic {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idRiser );
|
||||
|
||||
idRiser();
|
||||
|
||||
void Spawn();
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
#endif /* !__GAME_MOVER_H__ */
|
||||
3188
neo/d3xp/MultiplayerGame.cpp
Normal file
3188
neo/d3xp/MultiplayerGame.cpp
Normal file
File diff suppressed because it is too large
Load Diff
357
neo/d3xp/MultiplayerGame.h
Normal file
357
neo/d3xp/MultiplayerGame.h
Normal file
@@ -0,0 +1,357 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __MULTIPLAYERGAME_H__
|
||||
#define __MULTIPLAYERGAME_H__
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Basic DOOM multiplayer
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idPlayer;
|
||||
class idMenuHandler_HUD;
|
||||
class idMenuHandler_Scoreboard;
|
||||
class idItemTeam;
|
||||
|
||||
enum gameType_t {
|
||||
GAME_SP = -2,
|
||||
GAME_RANDOM = -1,
|
||||
GAME_DM = 0,
|
||||
GAME_TOURNEY,
|
||||
GAME_TDM,
|
||||
GAME_LASTMAN,
|
||||
GAME_CTF,
|
||||
GAME_COUNT,
|
||||
};
|
||||
|
||||
// Used by the UI
|
||||
typedef enum {
|
||||
FLAGSTATUS_INBASE = 0,
|
||||
FLAGSTATUS_TAKEN = 1,
|
||||
FLAGSTATUS_STRAY = 2,
|
||||
FLAGSTATUS_NONE = 3
|
||||
} flagStatus_t;
|
||||
|
||||
typedef struct mpPlayerState_s {
|
||||
int ping; // player ping
|
||||
int fragCount; // kills
|
||||
int teamFragCount; // team kills
|
||||
int wins; // wins
|
||||
bool scoreBoardUp; // toggle based on player scoreboard button, used to activate de-activate the scoreboard gui
|
||||
int deaths;
|
||||
} mpPlayerState_t;
|
||||
|
||||
const int NUM_CHAT_NOTIFY = 5;
|
||||
const int CHAT_FADE_TIME = 400;
|
||||
const int FRAGLIMIT_DELAY = 2000;
|
||||
|
||||
const int MP_PLAYER_MINFRAGS = -100;
|
||||
const int MP_PLAYER_MAXFRAGS = 400; // in CTF frags are player points
|
||||
const int MP_PLAYER_MAXWINS = 100;
|
||||
const int MP_PLAYER_MAXPING = 999;
|
||||
const int MP_CTF_MAXPOINTS = 400;
|
||||
|
||||
typedef struct mpChatLine_s {
|
||||
idStr line;
|
||||
short fade; // starts high and decreases, line is removed once reached 0
|
||||
} mpChatLine_t;
|
||||
|
||||
typedef enum {
|
||||
SND_YOUWIN = 0,
|
||||
SND_YOULOSE,
|
||||
SND_FIGHT,
|
||||
SND_THREE,
|
||||
SND_TWO,
|
||||
SND_ONE,
|
||||
SND_SUDDENDEATH,
|
||||
SND_FLAG_CAPTURED_YOURS,
|
||||
SND_FLAG_CAPTURED_THEIRS,
|
||||
SND_FLAG_RETURN,
|
||||
SND_FLAG_TAKEN_YOURS,
|
||||
SND_FLAG_TAKEN_THEIRS,
|
||||
SND_FLAG_DROPPED_YOURS,
|
||||
SND_FLAG_DROPPED_THEIRS,
|
||||
SND_COUNT
|
||||
} snd_evt_t;
|
||||
|
||||
class idMultiplayerGame {
|
||||
public:
|
||||
|
||||
idMultiplayerGame();
|
||||
|
||||
void Shutdown();
|
||||
|
||||
// resets everything and prepares for a match
|
||||
void Reset();
|
||||
|
||||
// setup local data for a new player
|
||||
void SpawnPlayer( int clientNum );
|
||||
|
||||
// checks rules and updates state of the mp game
|
||||
void Run();
|
||||
|
||||
// draws mp hud, scoredboard, etc..
|
||||
bool Draw( int clientNum );
|
||||
|
||||
// updates frag counts and potentially ends the match in sudden death
|
||||
void PlayerDeath( idPlayer *dead, idPlayer *killer, bool telefrag );
|
||||
|
||||
void AddChatLine( VERIFY_FORMAT_STRING const char *fmt, ... );
|
||||
|
||||
void WriteToSnapshot( idBitMsg &msg ) const;
|
||||
void ReadFromSnapshot( const idBitMsg &msg );
|
||||
|
||||
// game state
|
||||
typedef enum {
|
||||
INACTIVE = 0, // not running
|
||||
WARMUP, // warming up
|
||||
COUNTDOWN, // post warmup pre-game
|
||||
GAMEON, // game is on
|
||||
SUDDENDEATH, // game is on but in sudden death, first frag wins
|
||||
GAMEREVIEW, // game is over, scoreboard is up. we wait si_gameReviewPause seconds (which has a min value)
|
||||
NEXTGAME,
|
||||
STATE_COUNT
|
||||
} gameState_t;
|
||||
static const char *GameStateStrings[ STATE_COUNT ];
|
||||
idMultiplayerGame::gameState_t GetGameState() const;
|
||||
|
||||
static const char *GlobalSoundStrings[ SND_COUNT ];
|
||||
void PlayGlobalSound( int toPlayerNum, snd_evt_t evt, const char *shader = NULL );
|
||||
void PlayTeamSound( int toTeam, snd_evt_t evt, const char *shader = NULL ); // sound that's sent only to member of toTeam team
|
||||
|
||||
// more compact than a chat line
|
||||
typedef enum {
|
||||
MSG_SUICIDE = 0,
|
||||
MSG_KILLED,
|
||||
MSG_KILLEDTEAM,
|
||||
MSG_DIED,
|
||||
MSG_SUDDENDEATH,
|
||||
MSG_JOINEDSPEC,
|
||||
MSG_TIMELIMIT,
|
||||
MSG_FRAGLIMIT,
|
||||
MSG_TELEFRAGGED,
|
||||
MSG_JOINTEAM,
|
||||
MSG_HOLYSHIT,
|
||||
MSG_POINTLIMIT,
|
||||
MSG_FLAGTAKEN,
|
||||
MSG_FLAGDROP,
|
||||
MSG_FLAGRETURN,
|
||||
MSG_FLAGCAPTURE,
|
||||
MSG_SCOREUPDATE,
|
||||
MSG_LEFTGAME,
|
||||
MSG_COUNT
|
||||
} msg_evt_t;
|
||||
void PrintMessageEvent( msg_evt_t evt, int parm1 = -1, int parm2 = -1 );
|
||||
|
||||
void DisconnectClient( int clientNum );
|
||||
static void DropWeapon_f( const idCmdArgs &args );
|
||||
static void MessageMode_f( const idCmdArgs &args );
|
||||
static void VoiceChat_f( const idCmdArgs &args );
|
||||
static void VoiceChatTeam_f( const idCmdArgs &args );
|
||||
|
||||
int NumActualClients( bool countSpectators, int *teamcount = NULL );
|
||||
void DropWeapon( int clientNum );
|
||||
void MapRestart();
|
||||
void BalanceTeams();
|
||||
void SwitchToTeam( int clientNum, int oldteam, int newteam );
|
||||
bool IsPureReady() const;
|
||||
void ProcessChatMessage( int clientNum, bool team, const char *name, const char *text, const char *sound );
|
||||
void ProcessVoiceChat( int clientNum, bool team, int index );
|
||||
bool HandleGuiEvent( const sysEvent_t * sev );
|
||||
bool IsScoreboardActive();
|
||||
void SetScoreboardActive( bool active );
|
||||
void CleanupScoreboard();
|
||||
|
||||
void Precache();
|
||||
|
||||
void ToggleSpectate();
|
||||
|
||||
void GetSpectateText( idPlayer * player, idStr spectatetext[ 2 ], bool scoreboard );
|
||||
|
||||
void ClearFrags( int clientNum );
|
||||
|
||||
bool CanPlay( idPlayer *p );
|
||||
bool WantRespawn( idPlayer *p );
|
||||
|
||||
void ServerWriteInitialReliableMessages( int clientNum, lobbyUserID_t lobbyUserID );
|
||||
void ClientReadStartState( const idBitMsg &msg );
|
||||
void ClientReadWarmupTime( const idBitMsg &msg );
|
||||
void ClientReadMatchStartedTime( const idBitMsg & msg );
|
||||
void ClientReadAchievementUnlock( const idBitMsg & msg );
|
||||
|
||||
void ServerClientConnect( int clientNum );
|
||||
int GetFlagPoints( int team ); // Team points in CTF
|
||||
void SetFlagMsg( bool b ); // allow flag event messages to be sent
|
||||
bool IsFlagMsgOn(); // should flag event messages go through?
|
||||
|
||||
int player_red_flag; // Ent num of red flag carrier for HUD
|
||||
int player_blue_flag; // Ent num of blue flag carrier for HUD
|
||||
|
||||
void PlayerStats( int clientNum, char *data, const int len );
|
||||
|
||||
private:
|
||||
static const char * teamNames[];
|
||||
static const char * skinNames[];
|
||||
static const idVec3 skinColors[];
|
||||
static const int numSkins;
|
||||
|
||||
// state vars
|
||||
gameState_t gameState; // what state the current game is in
|
||||
gameState_t nextState; // state to switch to when nextStateSwitch is hit
|
||||
|
||||
mpPlayerState_t playerState[ MAX_CLIENTS ];
|
||||
|
||||
// keep track of clients which are willingly in spectator mode
|
||||
// time related
|
||||
int nextStateSwitch; // time next state switch
|
||||
int warmupEndTime; // warmup till..
|
||||
int matchStartedTime; // time current match started
|
||||
|
||||
// tourney
|
||||
int currentTourneyPlayer[2];// our current set of players
|
||||
int lastWinner; // plays again
|
||||
|
||||
// warmup
|
||||
bool one, two, three; // keeps count down voice from repeating
|
||||
|
||||
// guis
|
||||
idMenuHandler_Scoreboard * scoreboardManager;
|
||||
|
||||
// chat data
|
||||
mpChatLine_t chatHistory[ NUM_CHAT_NOTIFY ];
|
||||
int chatHistoryIndex;
|
||||
int chatHistorySize; // 0 <= x < NUM_CHAT_NOTIFY
|
||||
bool chatDataUpdated;
|
||||
int lastChatLineTime;
|
||||
|
||||
// rankings are used by UpdateScoreboard and UpdateHud
|
||||
int numRankedPlayers; // ranked players, others may be empty slots or spectators
|
||||
idPlayer * rankedPlayers[MAX_CLIENTS];
|
||||
|
||||
bool pureReady; // defaults to false, set to true once server game is running with pure checksums
|
||||
int fragLimitTimeout;
|
||||
|
||||
int voiceChatThrottle;
|
||||
|
||||
int startFragLimit; // synchronize to clients in initial state, set on -> GAMEON
|
||||
|
||||
idItemTeam * teamFlags[ 2 ];
|
||||
int teamPoints[ 2 ];
|
||||
|
||||
bool flagMsgOn;
|
||||
|
||||
private:
|
||||
void UpdatePlayerRanks();
|
||||
void GameHasBeenWon();
|
||||
|
||||
// updates the passed gui with current score information
|
||||
void UpdateRankColor( idUserInterface *gui, const char *mask, int i, const idVec3 &vec );
|
||||
void UpdateScoreboard( idMenuHandler_Scoreboard * scoreboard, idPlayer *owner );
|
||||
|
||||
void DrawScoreBoard( idPlayer *player );
|
||||
|
||||
void UpdateHud( idPlayer *player, idMenuHandler_HUD * hudManager );
|
||||
bool Warmup();
|
||||
idPlayer * FragLimitHit();
|
||||
idPlayer * FragLeader();
|
||||
bool TimeLimitHit();
|
||||
bool PointLimitHit();
|
||||
// return team with most points
|
||||
int WinningTeam();
|
||||
void NewState( gameState_t news, idPlayer *player = NULL );
|
||||
void UpdateWinsLosses( idPlayer *winner );
|
||||
// fill any empty tourney slots based on the current tourney ranks
|
||||
void FillTourneySlots();
|
||||
void CycleTourneyPlayers();
|
||||
// walk through the tourneyRank to build a wait list for the clients
|
||||
void UpdateTourneyLine();
|
||||
const char * GameTime();
|
||||
void Clear();
|
||||
bool EnoughClientsToPlay();
|
||||
void ClearChatData();
|
||||
void DrawChat( idPlayer * player );
|
||||
// go through the clients, and see if they want to be respawned, and if the game allows it
|
||||
// called during normal gameplay for death -> respawn cycles
|
||||
// and for a spectator who want back in the game (see param)
|
||||
void CheckRespawns( idPlayer *spectator = NULL );
|
||||
// when clients disconnect or join spectate during game, check if we need to end the game
|
||||
void CheckAbortGame();
|
||||
void MessageMode( const idCmdArgs &args );
|
||||
// scores in TDM
|
||||
void TeamScore( int entityNumber, int team, int delta );
|
||||
void VoiceChat( const idCmdArgs &args, bool team );
|
||||
void DumpTourneyLine();
|
||||
void SuddenRespawn();
|
||||
|
||||
void FindTeamFlags();
|
||||
|
||||
void NewState_Warmup_ServerAndClient();
|
||||
void NewState_Countdown_ServerAndClient();
|
||||
void NewState_GameOn_ServerAndClient();
|
||||
void NewState_GameReview_ServerAndClient();
|
||||
|
||||
public:
|
||||
|
||||
const char * GetTeamName( int team ) const;
|
||||
const char * GetSkinName( int skin ) const;
|
||||
const idVec3 & GetSkinColor( int skin ) const;
|
||||
|
||||
idItemTeam * GetTeamFlag( int team );
|
||||
flagStatus_t GetFlagStatus( int team );
|
||||
void TeamScoreCTF( int team, int delta );
|
||||
void PlayerScoreCTF( int playerIdx, int delta );
|
||||
// returns entityNum to team flag carrier, -1 if no flag carrier
|
||||
int GetFlagCarrier( int team );
|
||||
void UpdateScoreboardFlagStatus();
|
||||
void ReloadScoreboard();
|
||||
|
||||
int GetGameModes( const char *** gameModes, const char *** gameModesDisplay );
|
||||
|
||||
bool IsGametypeFlagBased();
|
||||
bool IsGametypeTeamBased();
|
||||
|
||||
};
|
||||
|
||||
ID_INLINE idMultiplayerGame::gameState_t idMultiplayerGame::GetGameState() const {
|
||||
return gameState;
|
||||
}
|
||||
|
||||
ID_INLINE bool idMultiplayerGame::IsPureReady() const {
|
||||
return pureReady;
|
||||
}
|
||||
|
||||
ID_INLINE void idMultiplayerGame::ClearFrags( int clientNum ) {
|
||||
playerState[ clientNum ].fragCount = 0;
|
||||
}
|
||||
|
||||
#endif /* !__MULTIPLAYERGAME_H__ */
|
||||
|
||||
10742
neo/d3xp/Player.cpp
Normal file
10742
neo/d3xp/Player.cpp
Normal file
File diff suppressed because it is too large
Load Diff
924
neo/d3xp/Player.h
Normal file
924
neo/d3xp/Player.h
Normal file
@@ -0,0 +1,924 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_PLAYER_H__
|
||||
#define __GAME_PLAYER_H__
|
||||
|
||||
#include "PredictedValue.h"
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Player entity.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idMenuHandler_PDA;
|
||||
class idMenuHandler_HUD;
|
||||
class idMenuScreen_HUD;
|
||||
class idTarget_SetPrimaryObjective;
|
||||
|
||||
extern const idEventDef EV_Player_GetButtons;
|
||||
extern const idEventDef EV_Player_GetMove;
|
||||
extern const idEventDef EV_Player_GetViewAngles;
|
||||
extern const idEventDef EV_Player_EnableWeapon;
|
||||
extern const idEventDef EV_Player_DisableWeapon;
|
||||
extern const idEventDef EV_Player_ExitTeleporter;
|
||||
extern const idEventDef EV_Player_SelectWeapon;
|
||||
extern const idEventDef EV_SpectatorTouch;
|
||||
|
||||
const float THIRD_PERSON_FOCUS_DISTANCE = 512.0f;
|
||||
const int LAND_DEFLECT_TIME = 150;
|
||||
const int LAND_RETURN_TIME = 300;
|
||||
const int FOCUS_TIME = 300;
|
||||
const int FOCUS_GUI_TIME = 500;
|
||||
const int NUM_QUICK_SLOTS = 4;
|
||||
|
||||
const int MAX_WEAPONS = 32;
|
||||
|
||||
const int DEAD_HEARTRATE = 0; // fall to as you die
|
||||
const int LOWHEALTH_HEARTRATE_ADJ = 20; //
|
||||
const int DYING_HEARTRATE = 30; // used for volumen calc when dying/dead
|
||||
const int BASE_HEARTRATE = 70; // default
|
||||
const int ZEROSTAMINA_HEARTRATE = 115; // no stamina
|
||||
const int MAX_HEARTRATE = 130; // maximum
|
||||
const int ZERO_VOLUME = -40; // volume at zero
|
||||
const int DMG_VOLUME = 5; // volume when taking damage
|
||||
const int DEATH_VOLUME = 15; // volume at death
|
||||
|
||||
const int SAVING_THROW_TIME = 5000; // maximum one "saving throw" every five seconds
|
||||
|
||||
const int ASYNC_PLAYER_INV_AMMO_BITS = idMath::BitsForInteger( 3000 );
|
||||
const int ASYNC_PLAYER_INV_CLIP_BITS = -7; // -7 bits to cover the range [-1, 60]
|
||||
|
||||
enum gameExpansionType_t {
|
||||
GAME_BASE,
|
||||
GAME_D3XP,
|
||||
GAME_D3LE,
|
||||
GAME_UNKNOWN
|
||||
};
|
||||
|
||||
struct idObjectiveInfo {
|
||||
idStr title;
|
||||
idStr text;
|
||||
const idMaterial * screenshot;
|
||||
};
|
||||
|
||||
struct idLevelTriggerInfo {
|
||||
idStr levelName;
|
||||
idStr triggerName;
|
||||
};
|
||||
|
||||
// powerups - the "type" in item .def must match
|
||||
enum {
|
||||
BERSERK = 0,
|
||||
INVISIBILITY,
|
||||
MEGAHEALTH,
|
||||
ADRENALINE,
|
||||
INVULNERABILITY,
|
||||
HELLTIME,
|
||||
ENVIROSUIT,
|
||||
//HASTE,
|
||||
ENVIROTIME,
|
||||
MAX_POWERUPS
|
||||
};
|
||||
|
||||
// powerup modifiers
|
||||
enum {
|
||||
SPEED = 0,
|
||||
PROJECTILE_DAMAGE,
|
||||
MELEE_DAMAGE,
|
||||
MELEE_DISTANCE
|
||||
};
|
||||
|
||||
// influence levels
|
||||
enum {
|
||||
INFLUENCE_NONE = 0, // none
|
||||
INFLUENCE_LEVEL1, // no gun or hud
|
||||
INFLUENCE_LEVEL2, // no gun, hud, movement
|
||||
INFLUENCE_LEVEL3, // slow player movement
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int ammo;
|
||||
int rechargeTime;
|
||||
char ammoName[128];
|
||||
} RechargeAmmo_t;
|
||||
|
||||
typedef struct {
|
||||
char name[64];
|
||||
idList<int, TAG_IDLIB_LIST_PLAYER> toggleList;
|
||||
int lastUsed;
|
||||
} WeaponToggle_t;
|
||||
|
||||
class idInventory {
|
||||
public:
|
||||
int maxHealth;
|
||||
int weapons;
|
||||
int powerups;
|
||||
int armor;
|
||||
int maxarmor;
|
||||
int powerupEndTime[ MAX_POWERUPS ];
|
||||
|
||||
RechargeAmmo_t rechargeAmmo[ AMMO_NUMTYPES ];
|
||||
|
||||
// mp
|
||||
int ammoPredictTime; // Unused now but kept for save file compatibility.
|
||||
|
||||
int deplete_armor;
|
||||
float deplete_rate;
|
||||
int deplete_ammount;
|
||||
int nextArmorDepleteTime;
|
||||
|
||||
int pdasViewed[4]; // 128 bit flags for indicating if a pda has been viewed
|
||||
|
||||
int selPDA;
|
||||
int selEMail;
|
||||
int selVideo;
|
||||
int selAudio;
|
||||
bool pdaOpened;
|
||||
idList<idDict *> items;
|
||||
idList<idStr> pdaSecurity;
|
||||
idList<const idDeclPDA *> pdas;
|
||||
idList<const idDeclVideo *> videos;
|
||||
idList<const idDeclEmail *> emails;
|
||||
|
||||
bool ammoPulse;
|
||||
bool weaponPulse;
|
||||
bool armorPulse;
|
||||
int lastGiveTime;
|
||||
|
||||
idList<idLevelTriggerInfo, TAG_IDLIB_LIST_PLAYER> levelTriggers;
|
||||
|
||||
idInventory() { Clear(); }
|
||||
~idInventory() { Clear(); }
|
||||
|
||||
// save games
|
||||
void Save( idSaveGame *savefile ) const; // archives object for save game file
|
||||
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
|
||||
|
||||
void Clear();
|
||||
void GivePowerUp( idPlayer *player, int powerup, int msec );
|
||||
void ClearPowerUps();
|
||||
void GetPersistantData( idDict &dict );
|
||||
void RestoreInventory( idPlayer *owner, const idDict &dict );
|
||||
bool Give( idPlayer *owner, const idDict &spawnArgs, const char *statname, const char *value,
|
||||
idPredictedValue< int > * idealWeapon, bool updateHud, unsigned int giveFlags );
|
||||
void Drop( const idDict &spawnArgs, const char *weapon_classname, int weapon_index );
|
||||
ammo_t AmmoIndexForAmmoClass( const char *ammo_classname ) const;
|
||||
int MaxAmmoForAmmoClass( const idPlayer *owner, const char *ammo_classname ) const;
|
||||
int WeaponIndexForAmmoClass( const idDict & spawnArgs, const char *ammo_classname ) const;
|
||||
ammo_t AmmoIndexForWeaponClass( const char *weapon_classname, int *ammoRequired );
|
||||
const char * AmmoPickupNameForIndex( ammo_t ammonum ) const;
|
||||
void AddPickupName( const char * name, idPlayer * owner ); //_D3XP
|
||||
|
||||
int HasAmmo( ammo_t type, int amount );
|
||||
bool UseAmmo( ammo_t type, int amount );
|
||||
int HasAmmo( const char *weapon_classname, bool includeClip = false, idPlayer* owner = NULL ); // _D3XP
|
||||
|
||||
bool HasEmptyClipCannotRefill(const char *weapon_classname, idPlayer* owner);
|
||||
|
||||
void UpdateArmor();
|
||||
|
||||
void SetInventoryAmmoForType( const int ammoType, const int amount );
|
||||
void SetClipAmmoForWeapon( const int weapon, const int amount );
|
||||
|
||||
int GetInventoryAmmoForType( const int ammoType ) const;
|
||||
int GetClipAmmoForWeapon( const int weapon ) const;
|
||||
|
||||
void WriteAmmoToSnapshot( idBitMsg & msg ) const;
|
||||
void ReadAmmoFromSnapshot( const idBitMsg & msg, int ownerEntityNumber );
|
||||
|
||||
void SetRemoteClientAmmo( const int ownerEntityNumber );
|
||||
|
||||
int nextItemPickup;
|
||||
int nextItemNum;
|
||||
int onePickupTime;
|
||||
idList<idStr> pickupItemNames;
|
||||
idList<idObjectiveInfo> objectiveNames;
|
||||
|
||||
void InitRechargeAmmo(idPlayer *owner);
|
||||
void RechargeAmmo(idPlayer *owner);
|
||||
bool CanGive( idPlayer *owner, const idDict &spawnArgs, const char *statname, const char *value );
|
||||
|
||||
private:
|
||||
idArray< idPredictedValue< int >, AMMO_NUMTYPES > ammo;
|
||||
idArray< idPredictedValue< int >, MAX_WEAPONS > clip;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int time;
|
||||
idVec3 dir; // scaled larger for running
|
||||
} loggedAccel_t;
|
||||
|
||||
typedef struct {
|
||||
int areaNum;
|
||||
idVec3 pos;
|
||||
} aasLocation_t;
|
||||
|
||||
class idPlayer : public idActor {
|
||||
public:
|
||||
enum {
|
||||
EVENT_IMPULSE = idEntity::EVENT_MAXEVENTS,
|
||||
EVENT_EXIT_TELEPORTER,
|
||||
EVENT_ABORT_TELEPORTER,
|
||||
EVENT_POWERUP,
|
||||
EVENT_SPECTATE,
|
||||
EVENT_PICKUPNAME,
|
||||
EVENT_FORCE_ORIGIN,
|
||||
EVENT_KNOCKBACK,
|
||||
EVENT_MAXEVENTS
|
||||
};
|
||||
|
||||
static const int MAX_PLAYER_PDA = 100;
|
||||
static const int MAX_PLAYER_VIDEO = 100;
|
||||
static const int MAX_PLAYER_AUDIO = 100;
|
||||
static const int MAX_PLAYER_AUDIO_ENTRIES = 2;
|
||||
|
||||
usercmd_t oldCmd;
|
||||
usercmd_t usercmd;
|
||||
|
||||
class idPlayerView playerView; // handles damage kicks and effects
|
||||
|
||||
renderEntity_t laserSightRenderEntity; // replace crosshair for 3DTV
|
||||
qhandle_t laserSightHandle;
|
||||
|
||||
bool noclip;
|
||||
bool godmode;
|
||||
|
||||
bool spawnAnglesSet; // on first usercmd, we must set deltaAngles
|
||||
idAngles spawnAngles;
|
||||
idAngles viewAngles; // player view angles
|
||||
idAngles cmdAngles; // player cmd angles
|
||||
float independentWeaponPitchAngle; // viewAngles[PITCH} when head tracking is active
|
||||
|
||||
// For interpolating angles between snapshots
|
||||
idQuat previousViewQuat;
|
||||
idQuat nextViewQuat;
|
||||
|
||||
int buttonMask;
|
||||
int oldButtons;
|
||||
int oldImpulseSequence;
|
||||
|
||||
int lastHitTime; // last time projectile fired by player hit target
|
||||
int lastSndHitTime; // MP hit sound - != lastHitTime because we throttle
|
||||
int lastSavingThrowTime; // for the "free miss" effect
|
||||
|
||||
bool pdaHasBeenRead[ MAX_PLAYER_PDA ];
|
||||
bool videoHasBeenViewed[ MAX_PLAYER_VIDEO ];
|
||||
bool audioHasBeenHeard[ MAX_PLAYER_AUDIO ][ MAX_PLAYER_AUDIO_ENTRIES ];
|
||||
|
||||
idScriptBool AI_FORWARD;
|
||||
idScriptBool AI_BACKWARD;
|
||||
idScriptBool AI_STRAFE_LEFT;
|
||||
idScriptBool AI_STRAFE_RIGHT;
|
||||
idScriptBool AI_ATTACK_HELD;
|
||||
idScriptBool AI_WEAPON_FIRED;
|
||||
idScriptBool AI_JUMP;
|
||||
idScriptBool AI_CROUCH;
|
||||
idScriptBool AI_ONGROUND;
|
||||
idScriptBool AI_ONLADDER;
|
||||
idScriptBool AI_DEAD;
|
||||
idScriptBool AI_RUN;
|
||||
idScriptBool AI_PAIN;
|
||||
idScriptBool AI_HARDLANDING;
|
||||
idScriptBool AI_SOFTLANDING;
|
||||
idScriptBool AI_RELOAD;
|
||||
idScriptBool AI_TELEPORT;
|
||||
idScriptBool AI_TURN_LEFT;
|
||||
idScriptBool AI_TURN_RIGHT;
|
||||
|
||||
// inventory
|
||||
idInventory inventory;
|
||||
idTarget_SetPrimaryObjective * primaryObjective;
|
||||
|
||||
int flashlightBattery;
|
||||
idEntityPtr<idWeapon> flashlight;
|
||||
|
||||
idEntityPtr<idWeapon> weapon;
|
||||
idMenuHandler_HUD * hudManager;
|
||||
idMenuScreen_HUD * hud;
|
||||
idMenuHandler_PDA * pdaMenu;
|
||||
idSWF * mpMessages;
|
||||
bool objectiveSystemOpen;
|
||||
int quickSlot[ NUM_QUICK_SLOTS ];
|
||||
|
||||
int weapon_soulcube;
|
||||
int weapon_pda;
|
||||
int weapon_fists;
|
||||
int weapon_flashlight;
|
||||
int weapon_chainsaw;
|
||||
int weapon_bloodstone;
|
||||
int weapon_bloodstone_active1;
|
||||
int weapon_bloodstone_active2;
|
||||
int weapon_bloodstone_active3;
|
||||
bool harvest_lock;
|
||||
|
||||
int heartRate;
|
||||
idInterpolate<float> heartInfo;
|
||||
int lastHeartAdjust;
|
||||
int lastHeartBeat;
|
||||
int lastDmgTime;
|
||||
int deathClearContentsTime;
|
||||
bool doingDeathSkin;
|
||||
int lastArmorPulse; // lastDmgTime if we had armor at time of hit
|
||||
float stamina;
|
||||
float healthPool; // amount of health to give over time
|
||||
int nextHealthPulse;
|
||||
bool healthPulse;
|
||||
bool healthTake;
|
||||
int nextHealthTake;
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// controller shake parms
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
const static int MAX_SHAKE_BUFFER = 3;
|
||||
float controllerShakeHighMag[ MAX_SHAKE_BUFFER ]; // magnitude of the high frequency controller shake
|
||||
float controllerShakeLowMag[ MAX_SHAKE_BUFFER ]; // magnitude of the low frequency controller shake
|
||||
int controllerShakeHighTime[ MAX_SHAKE_BUFFER ]; // time the controller shake ends for high frequency.
|
||||
int controllerShakeLowTime[ MAX_SHAKE_BUFFER ]; // time the controller shake ends for low frequency.
|
||||
int controllerShakeTimeGroup;
|
||||
|
||||
bool hiddenWeapon; // if the weapon is hidden ( in noWeapons maps )
|
||||
idEntityPtr<idProjectile> soulCubeProjectile;
|
||||
|
||||
idAimAssist aimAssist;
|
||||
|
||||
int spectator;
|
||||
bool forceScoreBoard;
|
||||
bool forceRespawn;
|
||||
bool spectating;
|
||||
int lastSpectateTeleport;
|
||||
bool lastHitToggle;
|
||||
bool wantSpectate; // from userInfo
|
||||
bool weaponGone; // force stop firing
|
||||
bool useInitialSpawns; // toggled by a map restart to be active for the first game spawn
|
||||
int tourneyRank; // for tourney cycling - the higher, the more likely to play next - server
|
||||
int tourneyLine; // client side - our spot in the wait line. 0 means no info.
|
||||
int spawnedTime; // when client first enters the game
|
||||
|
||||
bool carryingFlag; // is the player carrying the flag?
|
||||
|
||||
idEntityPtr<idEntity> teleportEntity; // while being teleported, this is set to the entity we'll use for exit
|
||||
int teleportKiller; // entity number of an entity killing us at teleporter exit
|
||||
bool lastManOver; // can't respawn in last man anymore (srv only)
|
||||
bool lastManPlayAgain; // play again when end game delay is cancelled out before expiring (srv only)
|
||||
bool lastManPresent; // true when player was in when game started (spectators can't join a running LMS)
|
||||
bool isLagged; // replicated from server, true if packets haven't been received from client.
|
||||
int isChatting; // replicated from server, true if the player is chatting.
|
||||
|
||||
// timers
|
||||
int minRespawnTime; // can respawn when time > this, force after g_forcerespawn
|
||||
int maxRespawnTime; // force respawn after this time
|
||||
|
||||
// the first person view values are always calculated, even
|
||||
// if a third person view is used
|
||||
idVec3 firstPersonViewOrigin;
|
||||
idMat3 firstPersonViewAxis;
|
||||
|
||||
idDragEntity dragEntity;
|
||||
|
||||
idFuncMountedObject * mountedObject;
|
||||
idEntityPtr<idLight> enviroSuitLight;
|
||||
|
||||
bool healthRecharge;
|
||||
int lastHealthRechargeTime;
|
||||
int rechargeSpeed;
|
||||
|
||||
float new_g_damageScale;
|
||||
|
||||
bool bloomEnabled;
|
||||
float bloomSpeed;
|
||||
float bloomIntensity;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( idPlayer );
|
||||
|
||||
idPlayer();
|
||||
virtual ~idPlayer();
|
||||
|
||||
void Spawn();
|
||||
void Think();
|
||||
|
||||
void UpdateLaserSight();
|
||||
|
||||
// save games
|
||||
void Save( idSaveGame *savefile ) const; // archives object for save game file
|
||||
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
|
||||
|
||||
virtual void Hide();
|
||||
virtual void Show();
|
||||
|
||||
void Init();
|
||||
void PrepareForRestart();
|
||||
virtual void Restart();
|
||||
void LinkScriptVariables();
|
||||
void SetupWeaponEntity();
|
||||
void SelectInitialSpawnPoint( idVec3 &origin, idAngles &angles );
|
||||
void SpawnFromSpawnSpot();
|
||||
void SpawnToPoint( const idVec3 &spawn_origin, const idAngles &spawn_angles );
|
||||
void SetClipModel(); // spectator mode uses a different bbox size
|
||||
|
||||
void SavePersistantInfo();
|
||||
void RestorePersistantInfo();
|
||||
void SetLevelTrigger( const char *levelName, const char *triggerName );
|
||||
|
||||
void CacheWeapons();
|
||||
|
||||
void EnterCinematic();
|
||||
void ExitCinematic();
|
||||
|
||||
void UpdateConditions();
|
||||
void SetViewAngles( const idAngles &angles );
|
||||
|
||||
// Controller Shake
|
||||
void ControllerShakeFromDamage( int damage );
|
||||
void SetControllerShake( float highMagnitude, int highDuration, float lowMagnitude, int lowDuration );
|
||||
void ResetControllerShake();
|
||||
void GetControllerShake( int & highMagnitude, int & lowMagnitude ) const;
|
||||
|
||||
idAimAssist * GetAimAssist() { return &aimAssist; }
|
||||
|
||||
// delta view angles to allow movers to rotate the view of the player
|
||||
void UpdateDeltaViewAngles( const idAngles &angles );
|
||||
|
||||
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
|
||||
|
||||
virtual void GetAASLocation( idAAS *aas, idVec3 &pos, int &areaNum ) const;
|
||||
virtual void GetAIAimTargets( const idVec3 &lastSightPos, idVec3 &headPos, idVec3 &chestPos );
|
||||
virtual void DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage );
|
||||
void CalcDamagePoints( idEntity *inflictor, idEntity *attacker, const idDict *damageDef,
|
||||
const float damageScale, const int location, int *health, int *armor );
|
||||
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
|
||||
|
||||
// New damage path for instant client feedback.
|
||||
void ServerDealDamage( int damage, idEntity & inflictor, idEntity & attacker, const idVec3 & dir, const char * damageDefName, const int location ); // Actually updates the player's health independent of feedback.
|
||||
int AdjustDamageAmount( const int inputDamage );
|
||||
|
||||
// use exitEntityNum to specify a teleport with private camera view and delayed exit
|
||||
virtual void Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination );
|
||||
|
||||
void Kill( bool delayRespawn, bool nodamage );
|
||||
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
|
||||
void StartFxOnBone(const char *fx, const char *bone);
|
||||
|
||||
renderView_t * GetRenderView();
|
||||
void CalculateRenderView(); // called every tic by player code
|
||||
void CalculateFirstPersonView();
|
||||
|
||||
void AddChatMessage( int index, int alpha, const idStr & message );
|
||||
void UpdateSpectatingText();
|
||||
void ClearChatMessage( int index );
|
||||
|
||||
void DrawHUD( idMenuHandler_HUD * hudManager );
|
||||
|
||||
void WeaponFireFeedback( const idDict *weaponDef );
|
||||
|
||||
float DefaultFov() const;
|
||||
float CalcFov( bool honorZoom );
|
||||
void CalculateViewWeaponPos( idVec3 &origin, idMat3 &axis );
|
||||
idVec3 GetEyePosition() const;
|
||||
void GetViewPos( idVec3 &origin, idMat3 &axis ) const;
|
||||
void OffsetThirdPersonView( float angle, float range, float height, bool clip );
|
||||
|
||||
bool Give( const char *statname, const char *value, unsigned int giveFlags );
|
||||
bool GiveItem( idItem *item, unsigned int giveFlags );
|
||||
void GiveItem( const char *name );
|
||||
void GiveHealthPool( float amt );
|
||||
|
||||
void SetPrimaryObjective( idTarget_SetPrimaryObjective * target ) { primaryObjective = target; }
|
||||
idTarget_SetPrimaryObjective * GetPrimaryObjective() { return primaryObjective; }
|
||||
|
||||
idInventory & GetInventory() { return inventory; }
|
||||
bool GiveInventoryItem( idDict *item, unsigned int giveFlags );
|
||||
void RemoveInventoryItem( idDict *item );
|
||||
bool GiveInventoryItem( const char *name );
|
||||
void RemoveInventoryItem( const char *name );
|
||||
idDict * FindInventoryItem( const char *name );
|
||||
idDict * FindInventoryItem( int index );
|
||||
int GetNumInventoryItems();
|
||||
void PlayAudioLog( const idSoundShader * sound );
|
||||
void EndAudioLog();
|
||||
void PlayVideoDisk( const idDeclVideo * decl );
|
||||
void EndVideoDisk();
|
||||
const idMaterial * GetVideoMaterial() { return pdaVideoMat; }
|
||||
|
||||
void SetQuickSlot( int index, int val );
|
||||
int GetQuickSlot( int index );
|
||||
|
||||
void GivePDA( const idDeclPDA * pda, const char * securityItem );
|
||||
void GiveVideo( const idDeclVideo * video, const char * itemName );
|
||||
void GiveEmail( const idDeclEmail * email );
|
||||
void GiveSecurity( const char * security );
|
||||
void GiveObjective( const char * title, const char * text, const idMaterial * screenshot );
|
||||
void CompleteObjective( const char * title );
|
||||
|
||||
bool GivePowerUp( int powerup, int time, unsigned int giveFlags );
|
||||
void ClearPowerUps();
|
||||
bool PowerUpActive( int powerup ) const;
|
||||
float PowerUpModifier( int type );
|
||||
|
||||
int SlotForWeapon( const char *weaponName );
|
||||
void Reload();
|
||||
void NextWeapon();
|
||||
void NextBestWeapon();
|
||||
void PrevWeapon();
|
||||
void SetPreviousWeapon( int num ) { previousWeapon = num; }
|
||||
void SelectWeapon( int num, bool force );
|
||||
void DropWeapon( bool died ) ;
|
||||
void StealWeapon( idPlayer *player );
|
||||
void AddProjectilesFired( int count );
|
||||
void AddProjectileHits( int count );
|
||||
void SetLastHitTime( int time );
|
||||
void LowerWeapon();
|
||||
void RaiseWeapon();
|
||||
void WeaponLoweringCallback();
|
||||
void WeaponRisingCallback();
|
||||
void RemoveWeapon( const char *weap );
|
||||
void RemoveAllButEssentialWeapons();
|
||||
bool CanShowWeaponViewmodel() const;
|
||||
|
||||
void AddAIKill();
|
||||
void SetSoulCubeProjectile( idProjectile *projectile );
|
||||
|
||||
void AdjustHeartRate( int target, float timeInSecs, float delay, bool force );
|
||||
void SetCurrentHeartRate();
|
||||
int GetBaseHeartRate();
|
||||
void UpdateAir();
|
||||
|
||||
void UpdatePowerupHud();
|
||||
|
||||
virtual bool HandleSingleGuiCommand( idEntity *entityGui, idLexer *src );
|
||||
bool GuiActive() { return focusGUIent != NULL; }
|
||||
|
||||
bool HandleGuiEvents( const sysEvent_t * ev );
|
||||
void PerformImpulse( int impulse );
|
||||
void Spectate( bool spectate, bool force = false );
|
||||
void TogglePDA();
|
||||
void RouteGuiMouse( idUserInterface *gui );
|
||||
void UpdateHud();
|
||||
const idDeclPDA * GetPDA() const;
|
||||
bool GetPDAOpen() const { return objectiveSystemOpen; }
|
||||
const idDeclVideo * GetVideo( int index );
|
||||
void SetInfluenceFov( float fov );
|
||||
void SetInfluenceView( const char *mtr, const char *skinname, float radius, idEntity *ent );
|
||||
void SetInfluenceLevel( int level );
|
||||
int GetInfluenceLevel() { return influenceActive; };
|
||||
void SetPrivateCameraView( idCamera *camView );
|
||||
idCamera * GetPrivateCameraView() const { return privateCameraView; }
|
||||
void StartFxFov( float duration );
|
||||
void UpdateHudWeapon( bool flashWeapon = true );
|
||||
void UpdateChattingHud();
|
||||
void UpdateHudStats( idMenuHandler_HUD * hudManager );
|
||||
void Event_StopAudioLog();
|
||||
bool IsSoundChannelPlaying( const s_channelType channel = SND_CHANNEL_ANY );
|
||||
void ShowTip( const char *title, const char *tip, bool autoHide );
|
||||
void HideTip();
|
||||
bool IsTipVisible() { return tipUp; };
|
||||
void HideObjective();
|
||||
|
||||
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
|
||||
virtual void WriteToSnapshot( idBitMsg &msg ) const;
|
||||
virtual void ReadFromSnapshot( const idBitMsg &msg );
|
||||
void WritePlayerStateToSnapshot( idBitMsg &msg ) const;
|
||||
void ReadPlayerStateFromSnapshot( const idBitMsg &msg );
|
||||
|
||||
virtual bool ServerReceiveEvent( int event, int time, const idBitMsg &msg );
|
||||
|
||||
virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis );
|
||||
virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis );
|
||||
|
||||
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
|
||||
bool IsRespawning();
|
||||
bool IsInTeleport();
|
||||
|
||||
int GetSkinIndex() const { return skinIndex; }
|
||||
|
||||
idEntity *GetInfluenceEntity() { return influenceEntity; };
|
||||
const idMaterial *GetInfluenceMaterial() { return influenceMaterial; };
|
||||
float GetInfluenceRadius() { return influenceRadius; };
|
||||
|
||||
// server side work for in/out of spectate. takes care of spawning it into the world as well
|
||||
void ServerSpectate( bool spectate );
|
||||
// for very specific usage. != GetPhysics()
|
||||
idPhysics *GetPlayerPhysics();
|
||||
void TeleportDeath( int killer );
|
||||
void SetLeader( bool lead );
|
||||
bool IsLeader();
|
||||
|
||||
void UpdateSkinSetup();
|
||||
|
||||
bool OnLadder() const;
|
||||
|
||||
virtual void UpdatePlayerIcons();
|
||||
virtual void DrawPlayerIcons();
|
||||
virtual void HidePlayerIcons();
|
||||
bool NeedsIcon();
|
||||
|
||||
void StartHealthRecharge(int speed);
|
||||
void StopHealthRecharge();
|
||||
|
||||
idStr GetCurrentWeapon();
|
||||
int GetCurrentWeaponSlot() { return currentWeapon; }
|
||||
int GetIdealWeapon() { return idealWeapon.Get(); }
|
||||
idHashTable<WeaponToggle_t> GetWeaponToggles() const { return weaponToggles; }
|
||||
|
||||
bool CanGive( const char *statname, const char *value );
|
||||
|
||||
void StopHelltime( bool quick = true );
|
||||
void PlayHelltimeStopSound();
|
||||
|
||||
void DropFlag(); // drop CTF item
|
||||
void ReturnFlag();
|
||||
virtual void FreeModelDef();
|
||||
|
||||
bool SelfSmooth();
|
||||
void SetSelfSmooth( bool b );
|
||||
|
||||
const idAngles & GetViewBobAngles() { return viewBobAngles; }
|
||||
const idVec3 & GetViewBob() { return viewBob; }
|
||||
|
||||
idAchievementManager & GetAchievementManager() { return achievementManager; }
|
||||
const idAchievementManager & GetAchievementManager() const { return achievementManager; }
|
||||
|
||||
int GetPlayedTime() const { return playedTimeSecs; }
|
||||
|
||||
void HandleUserCmds( const usercmd_t & newcmd );
|
||||
|
||||
int GetClientFireCount() const { return clientFireCount; }
|
||||
void IncrementFireCount() { ++clientFireCount; }
|
||||
|
||||
void ShowRespawnHudMessage();
|
||||
void HideRespawnHudMessage();
|
||||
|
||||
bool IsLocallyControlled() const { return entityNumber == gameLocal.GetLocalClientNum(); }
|
||||
|
||||
gameExpansionType_t GetExpansionType() const;
|
||||
|
||||
void AddProjectileKills() { numProjectileKills++; }
|
||||
int GetProjectileKills() const { return numProjectileKills; }
|
||||
void ResetProjectileKills() { numProjectileKills = 0; }
|
||||
private:
|
||||
// Stats & achievements
|
||||
idAchievementManager achievementManager;
|
||||
|
||||
int playedTimeSecs;
|
||||
int playedTimeResidual;
|
||||
|
||||
jointHandle_t hipJoint;
|
||||
jointHandle_t chestJoint;
|
||||
jointHandle_t headJoint;
|
||||
|
||||
idPhysics_Player physicsObj; // player physics
|
||||
|
||||
idList<aasLocation_t, TAG_IDLIB_LIST_PLAYER> aasLocation; // for AI tracking the player
|
||||
|
||||
int bobFoot;
|
||||
float bobFrac;
|
||||
float bobfracsin;
|
||||
int bobCycle; // for view bobbing and footstep generation
|
||||
float xyspeed;
|
||||
int stepUpTime;
|
||||
float stepUpDelta;
|
||||
float idealLegsYaw;
|
||||
float legsYaw;
|
||||
bool legsForward;
|
||||
float oldViewYaw;
|
||||
idAngles viewBobAngles;
|
||||
idVec3 viewBob;
|
||||
int landChange;
|
||||
int landTime;
|
||||
|
||||
|
||||
int currentWeapon;
|
||||
idPredictedValue< int > idealWeapon;
|
||||
int previousWeapon;
|
||||
int weaponSwitchTime;
|
||||
bool weaponEnabled;
|
||||
|
||||
int skinIndex;
|
||||
const idDeclSkin * skin;
|
||||
const idDeclSkin * powerUpSkin;
|
||||
|
||||
int numProjectilesFired; // number of projectiles fired
|
||||
int numProjectileHits; // number of hits on mobs
|
||||
int numProjectileKills; // number of kills with a projectile.
|
||||
|
||||
bool airless;
|
||||
int airMsec; // set to pm_airMsec at start, drops in vacuum
|
||||
int lastAirDamage;
|
||||
|
||||
bool gibDeath;
|
||||
bool gibsLaunched;
|
||||
idVec3 gibsDir;
|
||||
|
||||
idInterpolate<float> zoomFov;
|
||||
idInterpolate<float> centerView;
|
||||
bool fxFov;
|
||||
|
||||
float influenceFov;
|
||||
int influenceActive; // level of influence.. 1 == no gun or hud .. 2 == 1 + no movement
|
||||
idEntity * influenceEntity;
|
||||
const idMaterial * influenceMaterial;
|
||||
float influenceRadius;
|
||||
const idDeclSkin * influenceSkin;
|
||||
|
||||
idCamera * privateCameraView;
|
||||
|
||||
static const int NUM_LOGGED_VIEW_ANGLES = 64; // for weapon turning angle offsets
|
||||
idAngles loggedViewAngles[NUM_LOGGED_VIEW_ANGLES]; // [gameLocal.framenum&(LOGGED_VIEW_ANGLES-1)]
|
||||
static const int NUM_LOGGED_ACCELS = 16; // for weapon turning angle offsets
|
||||
loggedAccel_t loggedAccel[NUM_LOGGED_ACCELS]; // [currentLoggedAccel & (NUM_LOGGED_ACCELS-1)]
|
||||
int currentLoggedAccel;
|
||||
|
||||
// if there is a focusGUIent, the attack button will be changed into mouse clicks
|
||||
idEntity * focusGUIent;
|
||||
idUserInterface * focusUI; // focusGUIent->renderEntity.gui, gui2, or gui3
|
||||
idAI * focusCharacter;
|
||||
int talkCursor; // show the state of the focusCharacter (0 == can't talk/dead, 1 == ready to talk, 2 == busy talking)
|
||||
int focusTime;
|
||||
idAFEntity_Vehicle * focusVehicle;
|
||||
idUserInterface * cursor;
|
||||
|
||||
// full screen guis track mouse movements directly
|
||||
int oldMouseX;
|
||||
int oldMouseY;
|
||||
|
||||
const idMaterial * pdaVideoMat;
|
||||
|
||||
bool tipUp;
|
||||
bool objectiveUp;
|
||||
|
||||
int lastDamageDef;
|
||||
idVec3 lastDamageDir;
|
||||
int lastDamageLocation;
|
||||
int smoothedFrame;
|
||||
bool smoothedOriginUpdated;
|
||||
idVec3 smoothedOrigin;
|
||||
idAngles smoothedAngles;
|
||||
|
||||
idHashTable<WeaponToggle_t> weaponToggles;
|
||||
|
||||
int hudPowerup;
|
||||
int lastHudPowerup;
|
||||
int hudPowerupDuration;
|
||||
|
||||
// mp
|
||||
bool respawning; // set to true while in SpawnToPoint for telefrag checks
|
||||
bool leader; // for sudden death situations
|
||||
int lastSpectateChange;
|
||||
int lastTeleFX;
|
||||
bool weaponCatchup; // raise up the weapon silently ( state catchups )
|
||||
int MPAim; // player num in aim
|
||||
int lastMPAim;
|
||||
int lastMPAimTime; // last time the aim changed
|
||||
int MPAimFadeTime; // for GUI fade
|
||||
bool MPAimHighlight;
|
||||
bool isTelefragged; // proper obituaries
|
||||
int serverOverridePositionTime;
|
||||
int clientFireCount;
|
||||
|
||||
idPlayerIcon playerIcon;
|
||||
|
||||
bool selfSmooth;
|
||||
|
||||
netBoolEvent_t respawn_netEvent;
|
||||
|
||||
void LookAtKiller( idEntity *inflictor, idEntity *attacker );
|
||||
|
||||
void StopFiring();
|
||||
void FireWeapon();
|
||||
void Weapon_Combat();
|
||||
void Weapon_NPC();
|
||||
void Weapon_GUI();
|
||||
void UpdateWeapon();
|
||||
void UpdateFlashlight();
|
||||
void FlashlightOn();
|
||||
void FlashlightOff();
|
||||
void UpdateSpectating();
|
||||
void SpectateFreeFly( bool force ); // ignore the timeout to force when followed spec is no longer valid
|
||||
void SpectateCycle();
|
||||
idAngles GunTurningOffset();
|
||||
idVec3 GunAcceleratingOffset();
|
||||
|
||||
void UseObjects();
|
||||
void CrashLand( const idVec3 &oldOrigin, const idVec3 &oldVelocity );
|
||||
void BobCycle( const idVec3 &pushVelocity );
|
||||
void UpdateViewAngles();
|
||||
void EvaluateControls();
|
||||
void AdjustSpeed();
|
||||
void AdjustBodyAngles();
|
||||
void InitAASLocation();
|
||||
void SetAASLocation();
|
||||
void Move();
|
||||
void Move_Interpolated( float fraction );
|
||||
void RunPhysics_RemoteClientCorrection();
|
||||
void UpdatePowerUps();
|
||||
void UpdateDeathSkin( bool state_hitch );
|
||||
void ClearPowerup( int i );
|
||||
void SetSpectateOrigin();
|
||||
bool AllowClientAuthPhysics();
|
||||
virtual int GetPhysicsTimeStep() const;
|
||||
|
||||
void ClearFocus();
|
||||
void UpdateFocus();
|
||||
void UpdateLocation();
|
||||
idUserInterface * ActiveGui();
|
||||
|
||||
// mp
|
||||
void Respawn_Shared();
|
||||
|
||||
bool WeaponAvailable( const char* name );
|
||||
|
||||
void UseVehicle();
|
||||
|
||||
void Event_GetButtons();
|
||||
void Event_GetMove();
|
||||
void Event_GetViewAngles();
|
||||
void Event_StopFxFov();
|
||||
void Event_EnableWeapon();
|
||||
void Event_DisableWeapon();
|
||||
void Event_GetCurrentWeapon();
|
||||
void Event_GetPreviousWeapon();
|
||||
void Event_SelectWeapon( const char *weaponName );
|
||||
void Event_GetWeaponEntity();
|
||||
void Event_OpenPDA();
|
||||
void Event_PDAAvailable();
|
||||
void Event_InPDA();
|
||||
void Event_ExitTeleporter();
|
||||
void Event_HideTip();
|
||||
void Event_LevelTrigger();
|
||||
void Event_Gibbed();
|
||||
void Event_ForceOrigin( idVec3 & origin, idAngles & angles );
|
||||
void Event_GiveInventoryItem( const char* name );
|
||||
void Event_RemoveInventoryItem( const char* name );
|
||||
|
||||
void Event_GetIdealWeapon();
|
||||
void Event_WeaponAvailable( const char* name );
|
||||
void Event_SetPowerupTime( int powerup, int time );
|
||||
void Event_IsPowerupActive( int powerup );
|
||||
void Event_StartWarp();
|
||||
void Event_StopHelltime( int mode );
|
||||
void Event_ToggleBloom( int on );
|
||||
void Event_SetBloomParms( float speed, float intensity );
|
||||
};
|
||||
|
||||
ID_INLINE bool idPlayer::IsRespawning() {
|
||||
return respawning;
|
||||
}
|
||||
|
||||
ID_INLINE idPhysics* idPlayer::GetPlayerPhysics() {
|
||||
return &physicsObj;
|
||||
}
|
||||
|
||||
ID_INLINE bool idPlayer::IsInTeleport() {
|
||||
return ( teleportEntity.GetEntity() != NULL );
|
||||
}
|
||||
|
||||
ID_INLINE void idPlayer::SetLeader( bool lead ) {
|
||||
leader = lead;
|
||||
}
|
||||
|
||||
ID_INLINE bool idPlayer::IsLeader() {
|
||||
return leader;
|
||||
}
|
||||
|
||||
ID_INLINE bool idPlayer::SelfSmooth() {
|
||||
return selfSmooth;
|
||||
}
|
||||
|
||||
ID_INLINE void idPlayer::SetSelfSmooth( bool b ) {
|
||||
selfSmooth = b;
|
||||
}
|
||||
|
||||
extern idCVar g_infiniteAmmo;
|
||||
|
||||
#endif /* !__GAME_PLAYER_H__ */
|
||||
|
||||
190
neo/d3xp/PlayerIcon.cpp
Normal file
190
neo/d3xp/PlayerIcon.cpp
Normal file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../idlib/precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Game_local.h"
|
||||
#include "PlayerIcon.h"
|
||||
|
||||
static const char * iconKeys[ ICON_NONE ] = {
|
||||
"mtr_icon_lag",
|
||||
"mtr_icon_chat"
|
||||
,"mtr_icon_redteam",
|
||||
"mtr_icon_blueteam"
|
||||
};
|
||||
|
||||
/*
|
||||
===============
|
||||
idPlayerIcon::idPlayerIcon
|
||||
===============
|
||||
*/
|
||||
idPlayerIcon::idPlayerIcon() {
|
||||
iconHandle = -1;
|
||||
iconType = ICON_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idPlayerIcon::~idPlayerIcon
|
||||
===============
|
||||
*/
|
||||
idPlayerIcon::~idPlayerIcon() {
|
||||
FreeIcon();
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idPlayerIcon::Draw
|
||||
===============
|
||||
*/
|
||||
void idPlayerIcon::Draw( idPlayer *player, jointHandle_t joint ) {
|
||||
idVec3 origin;
|
||||
idMat3 axis;
|
||||
|
||||
if ( joint == INVALID_JOINT ) {
|
||||
FreeIcon();
|
||||
return;
|
||||
}
|
||||
|
||||
player->GetJointWorldTransform( joint, gameLocal.time, origin, axis );
|
||||
origin.z += 16.0f;
|
||||
|
||||
Draw( player, origin );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idPlayerIcon::Draw
|
||||
===============
|
||||
*/
|
||||
void idPlayerIcon::Draw( idPlayer *player, const idVec3 &origin ) {
|
||||
idPlayer *localPlayer = gameLocal.GetLocalPlayer();
|
||||
if ( !localPlayer || !localPlayer->GetRenderView() ) {
|
||||
FreeIcon();
|
||||
return;
|
||||
}
|
||||
|
||||
idMat3 axis = localPlayer->GetRenderView()->viewaxis;
|
||||
|
||||
if ( player->isLagged && !player->spectating ) {
|
||||
// create the icon if necessary, or update if already created
|
||||
if ( !CreateIcon( player, ICON_LAG, origin, axis ) ) {
|
||||
UpdateIcon( player, origin, axis );
|
||||
}
|
||||
} else if ( g_CTFArrows.GetBool() && gameLocal.mpGame.IsGametypeFlagBased() && gameLocal.GetLocalPlayer() && player->team == gameLocal.GetLocalPlayer()->team && !player->IsHidden() && !player->AI_DEAD ) {
|
||||
int icon = ICON_TEAM_RED + player->team;
|
||||
|
||||
if ( icon != ICON_TEAM_RED && icon != ICON_TEAM_BLUE )
|
||||
return;
|
||||
|
||||
if ( !CreateIcon( player, ( playerIconType_t )icon, origin, axis ) ) {
|
||||
UpdateIcon( player, origin, axis );
|
||||
}
|
||||
} else {
|
||||
FreeIcon();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idPlayerIcon::FreeIcon
|
||||
===============
|
||||
*/
|
||||
void idPlayerIcon::FreeIcon() {
|
||||
if ( iconHandle != - 1 ) {
|
||||
gameRenderWorld->FreeEntityDef( iconHandle );
|
||||
iconHandle = -1;
|
||||
}
|
||||
iconType = ICON_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idPlayerIcon::CreateIcon
|
||||
===============
|
||||
*/
|
||||
bool idPlayerIcon::CreateIcon( idPlayer *player, playerIconType_t type, const idVec3 &origin, const idMat3 &axis ) {
|
||||
assert( type < ICON_NONE );
|
||||
const char *mtr = player->spawnArgs.GetString( iconKeys[ type ], "_default" );
|
||||
return CreateIcon( player, type, mtr, origin, axis );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idPlayerIcon::CreateIcon
|
||||
===============
|
||||
*/
|
||||
bool idPlayerIcon::CreateIcon( idPlayer *player, playerIconType_t type, const char *mtr, const idVec3 &origin, const idMat3 &axis ) {
|
||||
assert( type != ICON_NONE );
|
||||
|
||||
if ( type == iconType ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FreeIcon();
|
||||
|
||||
memset( &renderEnt, 0, sizeof( renderEnt ) );
|
||||
renderEnt.origin = origin;
|
||||
renderEnt.axis = axis;
|
||||
renderEnt.shaderParms[ SHADERPARM_RED ] = 1.0f;
|
||||
renderEnt.shaderParms[ SHADERPARM_GREEN ] = 1.0f;
|
||||
renderEnt.shaderParms[ SHADERPARM_BLUE ] = 1.0f;
|
||||
renderEnt.shaderParms[ SHADERPARM_ALPHA ] = 1.0f;
|
||||
renderEnt.shaderParms[ SHADERPARM_SPRITE_WIDTH ] = 16.0f;
|
||||
renderEnt.shaderParms[ SHADERPARM_SPRITE_HEIGHT ] = 16.0f;
|
||||
renderEnt.hModel = renderModelManager->FindModel( "_sprite" );
|
||||
renderEnt.callback = NULL;
|
||||
renderEnt.numJoints = 0;
|
||||
renderEnt.joints = NULL;
|
||||
renderEnt.customSkin = 0;
|
||||
renderEnt.noShadow = true;
|
||||
renderEnt.noSelfShadow = true;
|
||||
renderEnt.customShader = declManager->FindMaterial( mtr );
|
||||
renderEnt.referenceShader = 0;
|
||||
renderEnt.bounds = renderEnt.hModel->Bounds( &renderEnt );
|
||||
|
||||
iconHandle = gameRenderWorld->AddEntityDef( &renderEnt );
|
||||
iconType = type;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idPlayerIcon::UpdateIcon
|
||||
===============
|
||||
*/
|
||||
void idPlayerIcon::UpdateIcon( idPlayer *player, const idVec3 &origin, const idMat3 &axis ) {
|
||||
assert( iconHandle >= 0 );
|
||||
|
||||
renderEnt.origin = origin;
|
||||
renderEnt.axis = axis;
|
||||
gameRenderWorld->UpdateEntityDef( iconHandle, &renderEnt );
|
||||
}
|
||||
|
||||
65
neo/d3xp/PlayerIcon.h
Normal file
65
neo/d3xp/PlayerIcon.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __PLAYERICON_H__
|
||||
#define __PLAYERICON_H__
|
||||
|
||||
typedef enum {
|
||||
ICON_LAG,
|
||||
ICON_CHAT,
|
||||
ICON_TEAM_RED,
|
||||
ICON_TEAM_BLUE,
|
||||
ICON_NONE
|
||||
} playerIconType_t;
|
||||
|
||||
class idPlayerIcon {
|
||||
public:
|
||||
|
||||
public:
|
||||
idPlayerIcon();
|
||||
~idPlayerIcon();
|
||||
|
||||
void Draw( idPlayer *player, jointHandle_t joint );
|
||||
void Draw( idPlayer *player, const idVec3 &origin );
|
||||
|
||||
public:
|
||||
playerIconType_t iconType;
|
||||
renderEntity_t renderEnt;
|
||||
qhandle_t iconHandle;
|
||||
|
||||
public:
|
||||
void FreeIcon();
|
||||
bool CreateIcon( idPlayer* player, playerIconType_t type, const char *mtr, const idVec3 &origin, const idMat3 &axis );
|
||||
bool CreateIcon( idPlayer* player, playerIconType_t type, const idVec3 &origin, const idMat3 &axis );
|
||||
void UpdateIcon( idPlayer* player, const idVec3 &origin, const idMat3 &axis );
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif /* !_PLAYERICON_H_ */
|
||||
|
||||
1749
neo/d3xp/PlayerView.cpp
Normal file
1749
neo/d3xp/PlayerView.cpp
Normal file
File diff suppressed because it is too large
Load Diff
417
neo/d3xp/PlayerView.h
Normal file
417
neo/d3xp/PlayerView.h
Normal file
@@ -0,0 +1,417 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_PLAYERVIEW_H__
|
||||
#define __GAME_PLAYERVIEW_H__
|
||||
|
||||
class idMenuHandler_HUD;
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Player view.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
// screenBlob_t are for the on-screen damage claw marks, etc
|
||||
typedef struct {
|
||||
const idMaterial * material;
|
||||
float x, y, w, h;
|
||||
float s1, t1, s2, t2;
|
||||
int finishTime;
|
||||
int startFadeTime;
|
||||
float driftAmount;
|
||||
} screenBlob_t;
|
||||
|
||||
#define MAX_SCREEN_BLOBS 8
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class WarpPolygon_t {
|
||||
public:
|
||||
idVec4 outer1;
|
||||
idVec4 outer2;
|
||||
idVec4 center;
|
||||
};
|
||||
|
||||
class Warp_t {
|
||||
public:
|
||||
int id;
|
||||
bool active;
|
||||
|
||||
int startTime;
|
||||
float initialRadius;
|
||||
|
||||
idVec3 worldOrigin;
|
||||
idVec2 screenOrigin;
|
||||
|
||||
int durationMsec;
|
||||
|
||||
idList<WarpPolygon_t, TAG_IDLIB_LIST_PLAYER> polys;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class idPlayerView;
|
||||
class FullscreenFXManager;
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
FxFader
|
||||
==================
|
||||
*/
|
||||
class FxFader {
|
||||
enum {
|
||||
FX_STATE_OFF,
|
||||
FX_STATE_RAMPUP,
|
||||
FX_STATE_RAMPDOWN,
|
||||
FX_STATE_ON
|
||||
};
|
||||
|
||||
int time;
|
||||
int state;
|
||||
float alpha;
|
||||
int msec;
|
||||
|
||||
public:
|
||||
FxFader();
|
||||
|
||||
// primary functions
|
||||
bool SetTriggerState( bool active );
|
||||
|
||||
virtual void Save( idSaveGame *savefile );
|
||||
virtual void Restore( idRestoreGame *savefile );
|
||||
|
||||
// fader functions
|
||||
void SetFadeTime( int t ) { msec = t; };
|
||||
int GetFadeTime() { return msec; };
|
||||
|
||||
// misc functions
|
||||
float GetAlpha() { return alpha; };
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
FullscreenFX
|
||||
==================
|
||||
*/
|
||||
class FullscreenFX {
|
||||
protected:
|
||||
idStr name;
|
||||
FxFader fader;
|
||||
FullscreenFXManager *fxman;
|
||||
|
||||
public:
|
||||
FullscreenFX() { fxman = NULL; };
|
||||
virtual ~FullscreenFX() { };
|
||||
|
||||
virtual void Initialize() = 0;
|
||||
virtual bool Active() = 0;
|
||||
virtual void HighQuality() = 0;
|
||||
virtual void LowQuality() { };
|
||||
virtual void AccumPass( const renderView_t *view ) { };
|
||||
virtual bool HasAccum() { return false; };
|
||||
|
||||
void SetName( idStr n ) { name = n; };
|
||||
idStr GetName() { return name; };
|
||||
|
||||
void SetFXManager( FullscreenFXManager *fx ) { fxman = fx; };
|
||||
|
||||
bool SetTriggerState( bool state ) { return fader.SetTriggerState( state ); };
|
||||
void SetFadeSpeed( int msec ) { fader.SetFadeTime( msec ); };
|
||||
float GetFadeAlpha() { return fader.GetAlpha(); };
|
||||
|
||||
virtual void Save( idSaveGame *savefile );
|
||||
virtual void Restore( idRestoreGame *savefile );
|
||||
};
|
||||
|
||||
/*
|
||||
==================
|
||||
FullscreenFX_Helltime
|
||||
==================
|
||||
*/
|
||||
class FullscreenFX_Helltime : public FullscreenFX {
|
||||
const idMaterial * initMaterial;
|
||||
const idMaterial * captureMaterials[3];
|
||||
const idMaterial * drawMaterial;
|
||||
bool clearAccumBuffer;
|
||||
|
||||
int DetermineLevel();
|
||||
|
||||
public:
|
||||
virtual void Initialize();
|
||||
virtual bool Active();
|
||||
virtual void HighQuality();
|
||||
virtual void AccumPass( const renderView_t *view );
|
||||
virtual bool HasAccum() { return true; };
|
||||
|
||||
virtual void Restore( idRestoreGame *savefile );
|
||||
};
|
||||
|
||||
/*
|
||||
==================
|
||||
FullscreenFX_Multiplayer
|
||||
==================
|
||||
*/
|
||||
class FullscreenFX_Multiplayer : public FullscreenFX {
|
||||
const idMaterial * initMaterial;
|
||||
const idMaterial * captureMaterial;
|
||||
const idMaterial * drawMaterial;
|
||||
bool clearAccumBuffer;
|
||||
|
||||
int DetermineLevel();
|
||||
|
||||
public:
|
||||
virtual void Initialize();
|
||||
virtual bool Active();
|
||||
virtual void HighQuality();
|
||||
virtual void AccumPass( const renderView_t *view );
|
||||
virtual bool HasAccum() { return true; };
|
||||
|
||||
virtual void Restore( idRestoreGame *savefile );
|
||||
};
|
||||
|
||||
/*
|
||||
==================
|
||||
FullscreenFX_Warp
|
||||
==================
|
||||
*/
|
||||
class FullscreenFX_Warp : public FullscreenFX {
|
||||
const idMaterial* material;
|
||||
bool grabberEnabled;
|
||||
int startWarpTime;
|
||||
|
||||
void DrawWarp( WarpPolygon_t wp, float interp );
|
||||
|
||||
public:
|
||||
virtual void Initialize();
|
||||
virtual bool Active();
|
||||
virtual void HighQuality();
|
||||
|
||||
void EnableGrabber( bool active ) { grabberEnabled = active; startWarpTime = gameLocal.slow.time; };
|
||||
|
||||
virtual void Save( idSaveGame *savefile );
|
||||
virtual void Restore( idRestoreGame *savefile );
|
||||
};
|
||||
|
||||
/*
|
||||
==================
|
||||
FullscreenFX_EnviroSuit
|
||||
==================
|
||||
*/
|
||||
class FullscreenFX_EnviroSuit : public FullscreenFX {
|
||||
const idMaterial* material;
|
||||
|
||||
public:
|
||||
virtual void Initialize();
|
||||
virtual bool Active();
|
||||
virtual void HighQuality();
|
||||
};
|
||||
|
||||
/*
|
||||
==================
|
||||
FullscreenFX_DoubleVision
|
||||
==================
|
||||
*/
|
||||
class FullscreenFX_DoubleVision : public FullscreenFX {
|
||||
const idMaterial* material;
|
||||
|
||||
public:
|
||||
virtual void Initialize();
|
||||
virtual bool Active();
|
||||
virtual void HighQuality();
|
||||
};
|
||||
|
||||
/*
|
||||
==================
|
||||
FullscreenFX_InfluenceVision
|
||||
==================
|
||||
*/
|
||||
class FullscreenFX_InfluenceVision : public FullscreenFX {
|
||||
|
||||
public:
|
||||
virtual void Initialize();
|
||||
virtual bool Active();
|
||||
virtual void HighQuality();
|
||||
};
|
||||
|
||||
/*
|
||||
==================
|
||||
FullscreenFX_Bloom
|
||||
==================
|
||||
*/
|
||||
class FullscreenFX_Bloom : public FullscreenFX {
|
||||
const idMaterial* drawMaterial;
|
||||
const idMaterial* initMaterial;
|
||||
|
||||
float currentIntensity;
|
||||
float targetIntensity;
|
||||
|
||||
public:
|
||||
virtual void Initialize();
|
||||
virtual bool Active();
|
||||
virtual void HighQuality();
|
||||
|
||||
virtual void Save( idSaveGame *savefile );
|
||||
virtual void Restore( idRestoreGame *savefile );
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
FullscreenFXManager
|
||||
==================
|
||||
*/
|
||||
class FullscreenFXManager {
|
||||
idList<FullscreenFX*, TAG_FX> fx;
|
||||
|
||||
idPlayerView * playerView;
|
||||
const idMaterial* blendBackMaterial;
|
||||
|
||||
void CreateFX( idStr name, idStr fxtype, int fade );
|
||||
|
||||
public:
|
||||
FullscreenFXManager();
|
||||
virtual ~FullscreenFXManager();
|
||||
|
||||
void Initialize( idPlayerView *pv );
|
||||
|
||||
void Process( const renderView_t *view );
|
||||
void Blendback( float alpha );
|
||||
|
||||
idPlayerView* GetPlayerView() { return playerView; };
|
||||
idPlayer* GetPlayer() { return gameLocal.GetLocalPlayer(); };
|
||||
|
||||
int GetNum() { return fx.Num(); };
|
||||
FullscreenFX* GetFX( int index ) { return fx[index]; };
|
||||
FullscreenFX* FindFX( idStr name );
|
||||
|
||||
void Save( idSaveGame *savefile );
|
||||
void Restore( idRestoreGame *savefile );
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class idPlayerView {
|
||||
public:
|
||||
idPlayerView();
|
||||
~idPlayerView();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void SetPlayerEntity( class idPlayer *playerEnt );
|
||||
|
||||
void ClearEffects();
|
||||
|
||||
void DamageImpulse( idVec3 localKickDir, const idDict *damageDef );
|
||||
|
||||
void WeaponFireFeedback( const idDict *weaponDef );
|
||||
|
||||
idAngles AngleOffset() const; // returns the current kick angle
|
||||
|
||||
idMat3 ShakeAxis() const; // returns the current shake angle
|
||||
|
||||
void CalculateShake();
|
||||
|
||||
// this may involve rendering to a texture and displaying
|
||||
// that with a warp model or in double vision mode
|
||||
void RenderPlayerView( idMenuHandler_HUD * hudManager );
|
||||
void EmitStereoEyeView( const int eye, idMenuHandler_HUD * hudManager );
|
||||
|
||||
void Fade( idVec4 color, int time );
|
||||
|
||||
void Flash( idVec4 color, int time );
|
||||
|
||||
// temp for view testing
|
||||
void EnableBFGVision( bool b ) { bfgVision = b; };
|
||||
|
||||
private:
|
||||
void SingleView( const renderView_t *view, idMenuHandler_HUD * hudManager );
|
||||
void ScreenFade();
|
||||
|
||||
screenBlob_t * GetScreenBlob();
|
||||
|
||||
screenBlob_t screenBlobs[MAX_SCREEN_BLOBS];
|
||||
|
||||
public:
|
||||
int dvFinishTime; // double vision will be stopped at this time
|
||||
|
||||
int kickFinishTime; // view kick will be stopped at this time
|
||||
idAngles kickAngles;
|
||||
|
||||
bool bfgVision; //
|
||||
|
||||
const idMaterial * tunnelMaterial; // health tunnel vision
|
||||
const idMaterial * armorMaterial; // armor damage view effect
|
||||
const idMaterial * berserkMaterial; // berserk effect
|
||||
const idMaterial * irGogglesMaterial; // ir effect
|
||||
const idMaterial * bloodSprayMaterial; // blood spray
|
||||
const idMaterial * bfgMaterial; // when targeted with BFG
|
||||
float lastDamageTime; // accentuate the tunnel effect for a while
|
||||
|
||||
idVec4 fadeColor; // fade color
|
||||
idVec4 fadeToColor; // color to fade to
|
||||
idVec4 fadeFromColor; // color to fade from
|
||||
float fadeRate; // fade rate
|
||||
int fadeTime; // fade time
|
||||
|
||||
idAngles shakeAng; // from the sound sources
|
||||
|
||||
idPlayer * player;
|
||||
renderView_t view;
|
||||
|
||||
FullscreenFXManager *fxManager;
|
||||
|
||||
public:
|
||||
int AddWarp( idVec3 worldOrigin, float centerx, float centery, float initialRadius, float durationMsec );
|
||||
void FreeWarp( int id );
|
||||
};
|
||||
|
||||
// the crosshair is swapped for a laser sight in stereo rendering
|
||||
bool IsGameStereoRendered();
|
||||
|
||||
#endif /* !__GAME_PLAYERVIEW_H__ */
|
||||
78
neo/d3xp/PredictedValue.h
Normal file
78
neo/d3xp/PredictedValue.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#ifndef PREDICTED_VALUE_H_
|
||||
#define PREDICTED_VALUE_H_
|
||||
|
||||
#include "Game_local.h"
|
||||
|
||||
/*
|
||||
================================================
|
||||
A simple class to handle simple predictable values
|
||||
on multiplayer clients.
|
||||
|
||||
The class encapsulates the actual value to be stored
|
||||
as well as the client frame number on which it is set.
|
||||
|
||||
When reading predicted values from a snapshot, the actual
|
||||
value is only updated if the server has processed the client's
|
||||
usercmd for the frame in which the client predicted the value.
|
||||
Got that?
|
||||
================================================
|
||||
*/
|
||||
template< class type_ >
|
||||
class idPredictedValue {
|
||||
public:
|
||||
explicit idPredictedValue();
|
||||
explicit idPredictedValue( const type_ & value_ );
|
||||
|
||||
void Set( const type_ & newValue );
|
||||
|
||||
idPredictedValue< type_ > & operator=( const type_ & value );
|
||||
|
||||
idPredictedValue< type_ > & operator+=( const type_ & toAdd );
|
||||
idPredictedValue< type_ > & operator-=( const type_ & toSubtract );
|
||||
|
||||
bool UpdateFromSnapshot( const type_ & valueFromSnapshot, int clientNumber );
|
||||
|
||||
type_ Get() const { return value; }
|
||||
|
||||
private:
|
||||
// Noncopyable
|
||||
idPredictedValue( const idPredictedValue< type_ > & other );
|
||||
idPredictedValue< type_ > & operator=( const idPredictedValue< type_ > & other );
|
||||
|
||||
type_ value;
|
||||
int clientPredictedMilliseconds; // The time in which the client predicted the value.
|
||||
|
||||
void UpdatePredictionTime();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
220
neo/d3xp/PredictedValue_impl.h
Normal file
220
neo/d3xp/PredictedValue_impl.h
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#ifndef PREDICTED_VALUE_IMPL_H_
|
||||
#define PREDICTED_VALUE_IMPL_H_
|
||||
|
||||
#include "PredictedValue.h"
|
||||
#include "Player.h"
|
||||
|
||||
/*
|
||||
===============
|
||||
idPredictedValue::idPredictedValue
|
||||
===============
|
||||
*/
|
||||
template< class type_ >
|
||||
idPredictedValue< type_ >::idPredictedValue() :
|
||||
value(),
|
||||
clientPredictedMilliseconds( 0 ) {
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idPredictedValue::idPredictedValue
|
||||
===============
|
||||
*/
|
||||
template< class type_ >
|
||||
idPredictedValue< type_ >::idPredictedValue( const type_ & value_ ) :
|
||||
value( value_ ),
|
||||
clientPredictedMilliseconds( 0 ) {
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idPredictedValue::UpdatePredictionTime
|
||||
===============
|
||||
*/
|
||||
template< class type_ >
|
||||
void idPredictedValue< type_ >::UpdatePredictionTime() {
|
||||
if ( gameLocal.GetLocalPlayer() != NULL ) {
|
||||
clientPredictedMilliseconds = gameLocal.GetLocalPlayer()->usercmd.clientGameMilliseconds;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idPredictedValue::Set
|
||||
===============
|
||||
*/
|
||||
template< class type_ >
|
||||
void idPredictedValue< type_ >::Set( const type_ & newValue ) {
|
||||
value = newValue;
|
||||
UpdatePredictionTime();
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idPredictedValue::operator=
|
||||
===============
|
||||
*/
|
||||
template< class type_ >
|
||||
idPredictedValue< type_ > & idPredictedValue< type_ >::operator=( const type_ & newValue ) {
|
||||
Set( newValue );
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idPredictedValue::operator+=
|
||||
===============
|
||||
*/
|
||||
template< class type_ >
|
||||
idPredictedValue< type_ > & idPredictedValue< type_ >::operator+=( const type_ & toAdd ) {
|
||||
Set( value + toAdd );
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idPredictedValue::operator-=
|
||||
===============
|
||||
*/
|
||||
template< class type_ >
|
||||
idPredictedValue< type_ > & idPredictedValue< type_ >::operator-=( const type_ & toSubtract ) {
|
||||
Set( value - toSubtract );
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idPredictedValue::UpdateFromSnapshot
|
||||
|
||||
Always updates the value for remote clients.
|
||||
|
||||
Only updates the actual value if the snapshot usercmd frame is newer than the one in which
|
||||
the client predicted this value.
|
||||
|
||||
Returns true if the value was set, false if not.
|
||||
===============
|
||||
*/
|
||||
template< class type_ >
|
||||
bool idPredictedValue< type_ >::UpdateFromSnapshot( const type_ & valueFromSnapshot, int clientNumber ) {
|
||||
if ( clientNumber != gameLocal.GetLocalClientNum() ) {
|
||||
value = valueFromSnapshot;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( gameLocal.GetLastClientUsercmdMilliseconds( clientNumber ) >= clientPredictedMilliseconds ) {
|
||||
value = valueFromSnapshot;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
operator==
|
||||
|
||||
Overload for idPredictedValue.
|
||||
We only care if the values are equal, not the frame number.
|
||||
===============
|
||||
*/
|
||||
template< class firstType_, class secondType_ >
|
||||
bool operator==( const idPredictedValue< firstType_ > & lhs, const idPredictedValue< secondType_ > & rhs ) {
|
||||
return lhs.Get() == rhs.Get();
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
operator!=
|
||||
|
||||
Overload for idPredictedValue.
|
||||
We only care if the values are equal, not the frame number.
|
||||
===============
|
||||
*/
|
||||
template< class firstType_, class secondType_ >
|
||||
bool operator!=( const idPredictedValue< firstType_ > & lhs, const idPredictedValue< secondType_ > & rhs ) {
|
||||
return lhs.Get() != rhs.Get();
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
operator==
|
||||
|
||||
Overload for idPredictedValue.
|
||||
We only care if the values are equal, not the frame number.
|
||||
===============
|
||||
*/
|
||||
template< class firstType_, class secondType_ >
|
||||
bool operator==( const idPredictedValue< firstType_ > & lhs, const secondType_ & rhs ) {
|
||||
return lhs.Get() == rhs;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
operator==
|
||||
|
||||
Overload for idPredictedValue.
|
||||
We only care if the values are equal, not the frame number.
|
||||
===============
|
||||
*/
|
||||
template< class firstType_, class secondType_ >
|
||||
bool operator==( const firstType_ lhs, const idPredictedValue< secondType_ > & rhs ) {
|
||||
return lhs == rhs.Get();
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
operator!=
|
||||
|
||||
Overload for idPredictedValue.
|
||||
We only care if the values are equal, not the frame number.
|
||||
===============
|
||||
*/
|
||||
template< class firstType_, class secondType_ >
|
||||
bool operator!=( const idPredictedValue< firstType_ > & lhs, const secondType_ & rhs ) {
|
||||
return lhs.Get() != rhs;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
operator!=
|
||||
|
||||
Overload for idPredictedValue.
|
||||
We only care if the values are equal, not the frame number.
|
||||
===============
|
||||
*/
|
||||
template< class firstType_, class secondType_ >
|
||||
bool operator!=( const firstType_ lhs, const idPredictedValue< secondType_ > & rhs ) {
|
||||
return lhs != rhs.Get();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
2989
neo/d3xp/Projectile.cpp
Normal file
2989
neo/d3xp/Projectile.cpp
Normal file
File diff suppressed because it is too large
Load Diff
339
neo/d3xp/Projectile.h
Normal file
339
neo/d3xp/Projectile.h
Normal file
@@ -0,0 +1,339 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_PROJECTILE_H__
|
||||
#define __GAME_PROJECTILE_H__
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idProjectile
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
extern const idEventDef EV_Explode;
|
||||
|
||||
class idProjectile : public idEntity {
|
||||
public :
|
||||
CLASS_PROTOTYPE( idProjectile );
|
||||
|
||||
idProjectile();
|
||||
virtual ~idProjectile();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Create( idEntity *owner, const idVec3 &start, const idVec3 &dir );
|
||||
virtual void Launch( const idVec3 &start, const idVec3 &dir, const idVec3 &pushVelocity, const float timeSinceFire = 0.0f, const float launchPower = 1.0f, const float dmgPower = 1.0f );
|
||||
virtual void FreeLightDef();
|
||||
|
||||
idEntity * GetOwner() const;
|
||||
void CatchProjectile( idEntity* o, const char* reflectName );
|
||||
int GetProjectileState();
|
||||
void Event_CreateProjectile( idEntity *owner, const idVec3 &start, const idVec3 &dir );
|
||||
void Event_LaunchProjectile( const idVec3 &start, const idVec3 &dir, const idVec3 &pushVelocity );
|
||||
void Event_SetGravity( float gravity );
|
||||
|
||||
virtual void Think();
|
||||
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
|
||||
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
|
||||
virtual void Explode( const trace_t &collision, idEntity *ignore );
|
||||
void Fizzle();
|
||||
|
||||
static idVec3 GetVelocity( const idDict *projectile );
|
||||
static idVec3 GetGravity( const idDict *projectile );
|
||||
|
||||
enum {
|
||||
EVENT_DAMAGE_EFFECT = idEntity::EVENT_MAXEVENTS,
|
||||
EVENT_MAXEVENTS
|
||||
};
|
||||
|
||||
void SetLaunchedFromGrabber( bool bl ) { launchedFromGrabber = bl; }
|
||||
bool GetLaunchedFromGrabber() { return launchedFromGrabber; }
|
||||
|
||||
static void DefaultDamageEffect( idEntity *soundEnt, const idDict &projectileDef, const trace_t &collision, const idVec3 &velocity );
|
||||
static bool ClientPredictionCollide( idEntity *soundEnt, const idDict &projectileDef, const trace_t &collision, const idVec3 &velocity, bool addDamageEffect );
|
||||
virtual void ClientPredictionThink();
|
||||
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
|
||||
virtual void WriteToSnapshot( idBitMsg &msg ) const;
|
||||
virtual void ReadFromSnapshot( const idBitMsg &msg );
|
||||
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
|
||||
|
||||
void QueueToSimulate( int startTime );
|
||||
virtual void SimulateProjectileFrame( int msec, int endTime );
|
||||
virtual void PostSimulate( int endTime );
|
||||
|
||||
struct simulatedProjectile_t {
|
||||
simulatedProjectile_t(): projectile( NULL ), startTime( 0 ) {}
|
||||
idProjectile* projectile;
|
||||
int startTime;
|
||||
};
|
||||
|
||||
static const int MAX_SIMULATED_PROJECTILES = 64;
|
||||
|
||||
// This list is used to "catch up" client projectiles to the current time on the server
|
||||
static idArray< simulatedProjectile_t, MAX_SIMULATED_PROJECTILES > projectilesToSimulate;
|
||||
|
||||
protected:
|
||||
idEntityPtr<idEntity> owner;
|
||||
|
||||
struct projectileFlags_s {
|
||||
bool detonate_on_world : 1;
|
||||
bool detonate_on_actor : 1;
|
||||
bool randomShaderSpin : 1;
|
||||
bool isTracer : 1;
|
||||
bool noSplashDamage : 1;
|
||||
} projectileFlags;
|
||||
|
||||
bool launchedFromGrabber;
|
||||
|
||||
float thrust;
|
||||
int thrust_end;
|
||||
float damagePower;
|
||||
|
||||
renderLight_t renderLight;
|
||||
qhandle_t lightDefHandle; // handle to renderer light def
|
||||
idVec3 lightOffset;
|
||||
int lightStartTime;
|
||||
int lightEndTime;
|
||||
idVec3 lightColor;
|
||||
|
||||
idForce_Constant thruster;
|
||||
idPhysics_RigidBody physicsObj;
|
||||
|
||||
const idDeclParticle * smokeFly;
|
||||
int smokeFlyTime;
|
||||
bool mNoExplodeDisappear;
|
||||
bool mTouchTriggers;
|
||||
|
||||
int originalTimeGroup;
|
||||
|
||||
typedef enum {
|
||||
// must update these in script/doom_defs.script if changed
|
||||
SPAWNED = 0,
|
||||
CREATED = 1,
|
||||
LAUNCHED = 2,
|
||||
FIZZLED = 3,
|
||||
EXPLODED = 4
|
||||
} projectileState_t;
|
||||
|
||||
projectileState_t state;
|
||||
|
||||
private:
|
||||
|
||||
idVec3 launchOrigin;
|
||||
idMat3 launchAxis;
|
||||
|
||||
void AddDefaultDamageEffect( const trace_t &collision, const idVec3 &velocity );
|
||||
void AddParticlesAndLight();
|
||||
|
||||
void Event_Explode();
|
||||
void Event_Fizzle();
|
||||
void Event_RadiusDamage( idEntity *ignore );
|
||||
void Event_Touch( idEntity *other, trace_t *trace );
|
||||
void Event_GetProjectileState();
|
||||
};
|
||||
|
||||
class idGuidedProjectile : public idProjectile {
|
||||
public :
|
||||
CLASS_PROTOTYPE( idGuidedProjectile );
|
||||
|
||||
idGuidedProjectile();
|
||||
~idGuidedProjectile();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
virtual void Think();
|
||||
virtual void Launch( const idVec3 &start, const idVec3 &dir, const idVec3 &pushVelocity, const float timeSinceFire = 0.0f, const float launchPower = 1.0f, const float dmgPower = 1.0f );
|
||||
void SetEnemy( idEntity *ent );
|
||||
void Event_SetEnemy(idEntity *ent);
|
||||
|
||||
protected:
|
||||
float speed;
|
||||
idEntityPtr<idEntity> enemy;
|
||||
virtual void GetSeekPos( idVec3 &out );
|
||||
|
||||
private:
|
||||
idAngles rndScale;
|
||||
idAngles rndAng;
|
||||
idAngles angles;
|
||||
int rndUpdateTime;
|
||||
float turn_max;
|
||||
float clamp_dist;
|
||||
bool burstMode;
|
||||
bool unGuided;
|
||||
float burstDist;
|
||||
float burstVelocity;
|
||||
};
|
||||
|
||||
class idSoulCubeMissile : public idGuidedProjectile {
|
||||
public:
|
||||
CLASS_PROTOTYPE ( idSoulCubeMissile );
|
||||
~idSoulCubeMissile();
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
virtual void Think();
|
||||
virtual void Launch( const idVec3 &start, const idVec3 &dir, const idVec3 &pushVelocity, const float timeSinceFire = 0.0f, const float power = 1.0f, const float dmgPower = 1.0f );
|
||||
|
||||
protected:
|
||||
virtual void GetSeekPos( idVec3 &out );
|
||||
void ReturnToOwner();
|
||||
void KillTarget( const idVec3 &dir );
|
||||
|
||||
private:
|
||||
idVec3 startingVelocity;
|
||||
idVec3 endingVelocity;
|
||||
float accelTime;
|
||||
int launchTime;
|
||||
bool killPhase;
|
||||
bool returnPhase;
|
||||
idVec3 destOrg;
|
||||
idVec3 orbitOrg;
|
||||
int orbitTime;
|
||||
int smokeKillTime;
|
||||
const idDeclParticle * smokeKill;
|
||||
};
|
||||
|
||||
struct beamTarget_t {
|
||||
idEntityPtr<idEntity> target;
|
||||
renderEntity_t renderEntity;
|
||||
qhandle_t modelDefHandle;
|
||||
};
|
||||
|
||||
class idBFGProjectile : public idProjectile {
|
||||
public :
|
||||
CLASS_PROTOTYPE( idBFGProjectile );
|
||||
|
||||
idBFGProjectile();
|
||||
~idBFGProjectile();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
virtual void Think();
|
||||
virtual void Launch( const idVec3 &start, const idVec3 &dir, const idVec3 &pushVelocity, const float timeSinceFire = 0.0f, const float launchPower = 1.0f, const float dmgPower = 1.0f );
|
||||
virtual void Explode( const trace_t &collision, idEntity *ignore );
|
||||
|
||||
private:
|
||||
idList<beamTarget_t, TAG_PROJECTILE> beamTargets;
|
||||
renderEntity_t secondModel;
|
||||
qhandle_t secondModelDefHandle;
|
||||
int nextDamageTime;
|
||||
idStr damageFreq;
|
||||
|
||||
void FreeBeams();
|
||||
void Event_RemoveBeams();
|
||||
void ApplyDamage();
|
||||
};
|
||||
|
||||
class idHomingProjectile : public idProjectile {
|
||||
public :
|
||||
CLASS_PROTOTYPE( idHomingProjectile );
|
||||
|
||||
idHomingProjectile();
|
||||
~idHomingProjectile();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
virtual void Think();
|
||||
virtual void Launch( const idVec3 &start, const idVec3 &dir, const idVec3 &pushVelocity, const float timeSinceFire = 0.0f, const float launchPower = 1.0f, const float dmgPower = 1.0f );
|
||||
void SetEnemy( idEntity *ent );
|
||||
void SetSeekPos( idVec3 pos );
|
||||
void Event_SetEnemy(idEntity *ent);
|
||||
|
||||
protected:
|
||||
float speed;
|
||||
idEntityPtr<idEntity> enemy;
|
||||
idVec3 seekPos;
|
||||
|
||||
private:
|
||||
idAngles rndScale;
|
||||
idAngles rndAng;
|
||||
idAngles angles;
|
||||
float turn_max;
|
||||
float clamp_dist;
|
||||
bool burstMode;
|
||||
bool unGuided;
|
||||
float burstDist;
|
||||
float burstVelocity;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idDebris
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idDebris : public idEntity {
|
||||
public :
|
||||
CLASS_PROTOTYPE( idDebris );
|
||||
|
||||
idDebris();
|
||||
~idDebris();
|
||||
|
||||
// save games
|
||||
void Save( idSaveGame *savefile ) const; // archives object for save game file
|
||||
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Create( idEntity *owner, const idVec3 &start, const idMat3 &axis );
|
||||
void Launch();
|
||||
void Think();
|
||||
void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
|
||||
void Explode();
|
||||
void Fizzle();
|
||||
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
|
||||
|
||||
|
||||
private:
|
||||
idEntityPtr<idEntity> owner;
|
||||
idPhysics_RigidBody physicsObj;
|
||||
const idDeclParticle * smokeFly;
|
||||
int smokeFlyTime;
|
||||
const idSoundShader * sndBounce;
|
||||
|
||||
|
||||
void Event_Explode();
|
||||
void Event_Fizzle();
|
||||
};
|
||||
|
||||
#endif /* !__GAME_PROJECTILE_H__ */
|
||||
1421
neo/d3xp/Pvs.cpp
Normal file
1421
neo/d3xp/Pvs.cpp
Normal file
File diff suppressed because it is too large
Load Diff
126
neo/d3xp/Pvs.h
Normal file
126
neo/d3xp/Pvs.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_PVS_H__
|
||||
#define __GAME_PVS_H__
|
||||
|
||||
/*
|
||||
===================================================================================
|
||||
|
||||
PVS
|
||||
|
||||
Note: mirrors and other special view portals are not taken into account
|
||||
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
|
||||
typedef struct pvsHandle_s {
|
||||
int i; // index to current pvs
|
||||
unsigned int h; // handle for current pvs
|
||||
} pvsHandle_t;
|
||||
|
||||
|
||||
typedef struct pvsCurrent_s {
|
||||
pvsHandle_t handle; // current pvs handle
|
||||
byte * pvs; // current pvs bit string
|
||||
} pvsCurrent_t;
|
||||
|
||||
#define MAX_CURRENT_PVS 64 // must be a power of 2
|
||||
|
||||
typedef enum {
|
||||
PVS_NORMAL = 0, // PVS through portals taking portal states into account
|
||||
PVS_ALL_PORTALS_OPEN = 1, // PVS through portals assuming all portals are open
|
||||
PVS_CONNECTED_AREAS = 2 // PVS considering all topologically connected areas visible
|
||||
} pvsType_t;
|
||||
|
||||
|
||||
class idPVS {
|
||||
public:
|
||||
idPVS();
|
||||
~idPVS();
|
||||
// setup for the current map
|
||||
void Init();
|
||||
void Shutdown();
|
||||
// get the area(s) the source is in
|
||||
int GetPVSArea( const idVec3 &point ) const; // returns the area number
|
||||
int GetPVSAreas( const idBounds &bounds, int *areas, int maxAreas ) const; // returns number of areas
|
||||
// setup current PVS for the source
|
||||
pvsHandle_t SetupCurrentPVS( const idVec3 &source, const pvsType_t type = PVS_NORMAL ) const;
|
||||
pvsHandle_t SetupCurrentPVS( const idBounds &source, const pvsType_t type = PVS_NORMAL ) const;
|
||||
pvsHandle_t SetupCurrentPVS( const int sourceArea, const pvsType_t type = PVS_NORMAL ) const;
|
||||
pvsHandle_t SetupCurrentPVS( const int *sourceAreas, const int numSourceAreas, const pvsType_t type = PVS_NORMAL ) const;
|
||||
pvsHandle_t MergeCurrentPVS( pvsHandle_t pvs1, pvsHandle_t pvs2 ) const;
|
||||
void FreeCurrentPVS( pvsHandle_t handle ) const;
|
||||
// returns true if the target is within the current PVS
|
||||
bool InCurrentPVS( const pvsHandle_t handle, const idVec3 &target ) const;
|
||||
bool InCurrentPVS( const pvsHandle_t handle, const idBounds &target ) const;
|
||||
bool InCurrentPVS( const pvsHandle_t handle, const int targetArea ) const;
|
||||
bool InCurrentPVS( const pvsHandle_t handle, const int *targetAreas, int numTargetAreas ) const;
|
||||
// draw all portals that are within the PVS of the source
|
||||
void DrawPVS( const idVec3 &source, const pvsType_t type = PVS_NORMAL ) const;
|
||||
void DrawPVS( const idBounds &source, const pvsType_t type = PVS_NORMAL ) const;
|
||||
// visualize the PVS the handle points to
|
||||
void DrawCurrentPVS( const pvsHandle_t handle, const idVec3 &source ) const;
|
||||
|
||||
bool CheckAreasForPortalSky( const pvsHandle_t handle, const idVec3 &origin );
|
||||
|
||||
private:
|
||||
int numAreas;
|
||||
int numPortals;
|
||||
bool * connectedAreas;
|
||||
int * areaQueue;
|
||||
byte * areaPVS;
|
||||
// current PVS for a specific source possibly taking portal states (open/closed) into account
|
||||
mutable pvsCurrent_t currentPVS[MAX_CURRENT_PVS];
|
||||
// used to create PVS
|
||||
int portalVisBytes;
|
||||
int portalVisLongs;
|
||||
int areaVisBytes;
|
||||
int areaVisLongs;
|
||||
struct pvsPortal_s *pvsPortals;
|
||||
struct pvsArea_s * pvsAreas;
|
||||
|
||||
private:
|
||||
int GetPortalCount() const;
|
||||
void CreatePVSData();
|
||||
void DestroyPVSData();
|
||||
void CopyPortalPVSToMightSee() const;
|
||||
void FloodFrontPortalPVS_r( struct pvsPortal_s *portal, int areaNum ) const;
|
||||
void FrontPortalPVS() const;
|
||||
struct pvsStack_s * FloodPassagePVS_r( struct pvsPortal_s *source, const struct pvsPortal_s *portal, struct pvsStack_s *prevStack ) const;
|
||||
void PassagePVS() const;
|
||||
void AddPassageBoundaries( const idWinding &source, const idWinding &pass, bool flipClip, idPlane *bounds, int &numBounds, int maxBounds ) const;
|
||||
void CreatePassages() const;
|
||||
void DestroyPassages() const;
|
||||
int AreaPVSFromPortalPVS() const;
|
||||
void GetConnectedAreas( int srcArea, bool *connectedAreas ) const;
|
||||
pvsHandle_t AllocCurrentPVS( unsigned int h ) const;
|
||||
};
|
||||
|
||||
#endif /* !__GAME_PVS_H__ */
|
||||
587
neo/d3xp/SecurityCamera.cpp
Normal file
587
neo/d3xp/SecurityCamera.cpp
Normal file
@@ -0,0 +1,587 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
/*
|
||||
|
||||
SecurityCamera.cpp
|
||||
|
||||
Security camera that triggers targets when player is in view
|
||||
|
||||
*/
|
||||
|
||||
#include "../idlib/precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Game_local.h"
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
idSecurityCamera
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
const idEventDef EV_SecurityCam_ReverseSweep( "<reverseSweep>" );
|
||||
const idEventDef EV_SecurityCam_ContinueSweep( "<continueSweep>" );
|
||||
const idEventDef EV_SecurityCam_Pause( "<pause>" );
|
||||
const idEventDef EV_SecurityCam_Alert( "<alert>" );
|
||||
const idEventDef EV_SecurityCam_AddLight( "<addLight>" );
|
||||
|
||||
CLASS_DECLARATION( idEntity, idSecurityCamera )
|
||||
EVENT( EV_SecurityCam_ReverseSweep, idSecurityCamera::Event_ReverseSweep )
|
||||
EVENT( EV_SecurityCam_ContinueSweep, idSecurityCamera::Event_ContinueSweep )
|
||||
EVENT( EV_SecurityCam_Pause, idSecurityCamera::Event_Pause )
|
||||
EVENT( EV_SecurityCam_Alert, idSecurityCamera::Event_Alert )
|
||||
EVENT( EV_SecurityCam_AddLight, idSecurityCamera::Event_AddLight )
|
||||
END_CLASS
|
||||
|
||||
/*
|
||||
================
|
||||
idSecurityCamera::Save
|
||||
================
|
||||
*/
|
||||
void idSecurityCamera::Save( idSaveGame *savefile ) const {
|
||||
savefile->WriteFloat( angle );
|
||||
savefile->WriteFloat( sweepAngle );
|
||||
savefile->WriteInt( modelAxis );
|
||||
savefile->WriteBool( flipAxis );
|
||||
savefile->WriteFloat( scanDist );
|
||||
savefile->WriteFloat( scanFov );
|
||||
|
||||
savefile->WriteFloat( sweepStart );
|
||||
savefile->WriteFloat( sweepEnd );
|
||||
savefile->WriteBool( negativeSweep );
|
||||
savefile->WriteBool( sweeping );
|
||||
savefile->WriteInt( alertMode );
|
||||
savefile->WriteFloat( stopSweeping );
|
||||
savefile->WriteFloat( scanFovCos );
|
||||
|
||||
savefile->WriteVec3( viewOffset );
|
||||
|
||||
savefile->WriteInt( pvsArea );
|
||||
savefile->WriteStaticObject( physicsObj );
|
||||
savefile->WriteTraceModel( trm );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSecurityCamera::Restore
|
||||
================
|
||||
*/
|
||||
void idSecurityCamera::Restore( idRestoreGame *savefile ) {
|
||||
savefile->ReadFloat( angle );
|
||||
savefile->ReadFloat( sweepAngle );
|
||||
savefile->ReadInt( modelAxis );
|
||||
savefile->ReadBool( flipAxis );
|
||||
savefile->ReadFloat( scanDist );
|
||||
savefile->ReadFloat( scanFov );
|
||||
|
||||
savefile->ReadFloat( sweepStart );
|
||||
savefile->ReadFloat( sweepEnd );
|
||||
savefile->ReadBool( negativeSweep );
|
||||
savefile->ReadBool( sweeping );
|
||||
savefile->ReadInt( alertMode );
|
||||
savefile->ReadFloat( stopSweeping );
|
||||
savefile->ReadFloat( scanFovCos );
|
||||
|
||||
savefile->ReadVec3( viewOffset );
|
||||
|
||||
savefile->ReadInt( pvsArea );
|
||||
savefile->ReadStaticObject( physicsObj );
|
||||
savefile->ReadTraceModel( trm );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSecurityCamera::Spawn
|
||||
================
|
||||
*/
|
||||
void idSecurityCamera::Spawn() {
|
||||
idStr str;
|
||||
|
||||
sweepAngle = spawnArgs.GetFloat( "sweepAngle", "90" );
|
||||
health = spawnArgs.GetInt( "health", "100" );
|
||||
scanFov = spawnArgs.GetFloat( "scanFov", "90" );
|
||||
scanDist = spawnArgs.GetFloat( "scanDist", "200" );
|
||||
flipAxis = spawnArgs.GetBool( "flipAxis" );
|
||||
|
||||
modelAxis = spawnArgs.GetInt( "modelAxis" );
|
||||
if ( modelAxis < 0 || modelAxis > 2 ) {
|
||||
modelAxis = 0;
|
||||
}
|
||||
|
||||
spawnArgs.GetVector( "viewOffset", "0 0 0", viewOffset );
|
||||
|
||||
if ( spawnArgs.GetBool( "spotLight" ) ) {
|
||||
PostEventMS( &EV_SecurityCam_AddLight, 0 );
|
||||
}
|
||||
|
||||
negativeSweep = ( sweepAngle < 0 ) ? true : false;
|
||||
sweepAngle = abs( sweepAngle );
|
||||
|
||||
scanFovCos = cos( scanFov * idMath::PI / 360.0f );
|
||||
|
||||
angle = GetPhysics()->GetAxis().ToAngles().yaw;
|
||||
StartSweep();
|
||||
SetAlertMode( SCANNING );
|
||||
BecomeActive( TH_THINK );
|
||||
|
||||
if ( health ) {
|
||||
fl.takedamage = true;
|
||||
}
|
||||
|
||||
pvsArea = gameLocal.pvs.GetPVSArea( GetPhysics()->GetOrigin() );
|
||||
// if no target specified use ourself
|
||||
str = spawnArgs.GetString( "cameraTarget" );
|
||||
if ( str.Length() == 0 ) {
|
||||
spawnArgs.Set( "cameraTarget", spawnArgs.GetString( "name" ) );
|
||||
}
|
||||
|
||||
// check if a clip model is set
|
||||
spawnArgs.GetString( "clipmodel", "", str );
|
||||
if ( !str[0] ) {
|
||||
str = spawnArgs.GetString( "model" ); // use the visual model
|
||||
}
|
||||
|
||||
if ( !collisionModelManager->TrmFromModel( str, trm ) ) {
|
||||
gameLocal.Error( "idSecurityCamera '%s': cannot load collision model %s", name.c_str(), str.c_str() );
|
||||
return;
|
||||
}
|
||||
|
||||
GetPhysics()->SetContents( CONTENTS_SOLID );
|
||||
GetPhysics()->SetClipMask( MASK_SOLID | CONTENTS_BODY | CONTENTS_CORPSE | CONTENTS_MOVEABLECLIP );
|
||||
// setup the physics
|
||||
UpdateChangeableSpawnArgs( NULL );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSecurityCamera::Event_AddLight
|
||||
================
|
||||
*/
|
||||
void idSecurityCamera::Event_AddLight() {
|
||||
idDict args;
|
||||
idVec3 right, up, target, temp;
|
||||
idVec3 dir;
|
||||
float radius;
|
||||
idVec3 lightOffset;
|
||||
idLight *spotLight;
|
||||
|
||||
dir = GetAxis();
|
||||
dir.NormalVectors( right, up );
|
||||
target = GetPhysics()->GetOrigin() + dir * scanDist;
|
||||
|
||||
radius = tan( scanFov * idMath::PI / 360.0f );
|
||||
up = dir + up * radius;
|
||||
up.Normalize();
|
||||
up = GetPhysics()->GetOrigin() + up * scanDist;
|
||||
up -= target;
|
||||
|
||||
right = dir + right * radius;
|
||||
right.Normalize();
|
||||
right = GetPhysics()->GetOrigin() + right * scanDist;
|
||||
right -= target;
|
||||
|
||||
spawnArgs.GetVector( "lightOffset", "0 0 0", lightOffset );
|
||||
|
||||
args.Set( "origin", ( GetPhysics()->GetOrigin() + lightOffset ).ToString() );
|
||||
args.Set( "light_target", target.ToString() );
|
||||
args.Set( "light_right", right.ToString() );
|
||||
args.Set( "light_up", up.ToString() );
|
||||
args.SetFloat( "angle", GetPhysics()->GetAxis()[0].ToYaw() );
|
||||
|
||||
spotLight = static_cast<idLight *>( gameLocal.SpawnEntityType( idLight::Type, &args ) );
|
||||
spotLight->Bind( this, true );
|
||||
spotLight->UpdateVisuals();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSecurityCamera::DrawFov
|
||||
================
|
||||
*/
|
||||
void idSecurityCamera::DrawFov() {
|
||||
int i;
|
||||
float radius, a, s, c, halfRadius;
|
||||
idVec3 right, up;
|
||||
idVec4 color(1, 0, 0, 1), color2(0, 0, 1, 1);
|
||||
idVec3 lastPoint, point, lastHalfPoint, halfPoint, center;
|
||||
|
||||
idVec3 dir = GetAxis();
|
||||
dir.NormalVectors( right, up );
|
||||
|
||||
radius = tan( scanFov * idMath::PI / 360.0f );
|
||||
halfRadius = radius * 0.5f;
|
||||
lastPoint = dir + up * radius;
|
||||
lastPoint.Normalize();
|
||||
lastPoint = GetPhysics()->GetOrigin() + lastPoint * scanDist;
|
||||
lastHalfPoint = dir + up * halfRadius;
|
||||
lastHalfPoint.Normalize();
|
||||
lastHalfPoint = GetPhysics()->GetOrigin() + lastHalfPoint * scanDist;
|
||||
center = GetPhysics()->GetOrigin() + dir * scanDist;
|
||||
for ( i = 1; i < 12; i++ ) {
|
||||
a = idMath::TWO_PI * i / 12.0f;
|
||||
idMath::SinCos( a, s, c );
|
||||
point = dir + right * s * radius + up * c * radius;
|
||||
point.Normalize();
|
||||
point = GetPhysics()->GetOrigin() + point * scanDist;
|
||||
gameRenderWorld->DebugLine( color, lastPoint, point );
|
||||
gameRenderWorld->DebugLine( color, GetPhysics()->GetOrigin(), point );
|
||||
lastPoint = point;
|
||||
|
||||
halfPoint = dir + right * s * halfRadius + up * c * halfRadius;
|
||||
halfPoint.Normalize();
|
||||
halfPoint = GetPhysics()->GetOrigin() + halfPoint * scanDist;
|
||||
gameRenderWorld->DebugLine( color2, point, halfPoint );
|
||||
gameRenderWorld->DebugLine( color2, lastHalfPoint, halfPoint );
|
||||
lastHalfPoint = halfPoint;
|
||||
|
||||
gameRenderWorld->DebugLine( color2, halfPoint, center );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSecurityCamera::GetRenderView
|
||||
================
|
||||
*/
|
||||
renderView_t *idSecurityCamera::GetRenderView() {
|
||||
renderView_t *rv = idEntity::GetRenderView();
|
||||
rv->fov_x = scanFov;
|
||||
rv->fov_y = scanFov;
|
||||
rv->viewaxis = GetAxis().ToAngles().ToMat3();
|
||||
rv->vieworg = GetPhysics()->GetOrigin() + viewOffset;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSecurityCamera::CanSeePlayer
|
||||
================
|
||||
*/
|
||||
bool idSecurityCamera::CanSeePlayer() {
|
||||
int i;
|
||||
float dist;
|
||||
idPlayer *ent;
|
||||
trace_t tr;
|
||||
idVec3 dir;
|
||||
pvsHandle_t handle;
|
||||
|
||||
handle = gameLocal.pvs.SetupCurrentPVS( pvsArea );
|
||||
|
||||
for ( i = 0; i < gameLocal.numClients; i++ ) {
|
||||
ent = static_cast<idPlayer*>(gameLocal.entities[ i ]);
|
||||
|
||||
if ( !ent || ( ent->fl.notarget ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if there is no way we can see this player
|
||||
if ( !gameLocal.pvs.InCurrentPVS( handle, ent->GetPVSAreas(), ent->GetNumPVSAreas() ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dir = ent->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin();
|
||||
dist = dir.Normalize();
|
||||
|
||||
if ( dist > scanDist ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( dir * GetAxis() < scanFovCos ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
idVec3 eye;
|
||||
|
||||
eye = ent->EyeOffset();
|
||||
|
||||
gameLocal.clip.TracePoint( tr, GetPhysics()->GetOrigin(), ent->GetPhysics()->GetOrigin() + eye, MASK_OPAQUE, this );
|
||||
if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == ent ) ) {
|
||||
gameLocal.pvs.FreeCurrentPVS( handle );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
gameLocal.pvs.FreeCurrentPVS( handle );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSecurityCamera::SetAlertMode
|
||||
================
|
||||
*/
|
||||
void idSecurityCamera::SetAlertMode( int alert ) {
|
||||
if (alert >= SCANNING && alert <= ACTIVATED) {
|
||||
alertMode = alert;
|
||||
}
|
||||
renderEntity.shaderParms[ SHADERPARM_MODE ] = alertMode;
|
||||
UpdateVisuals();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSecurityCamera::Think
|
||||
================
|
||||
*/
|
||||
void idSecurityCamera::Think() {
|
||||
float pct;
|
||||
float travel;
|
||||
|
||||
if ( thinkFlags & TH_THINK ) {
|
||||
if ( g_showEntityInfo.GetBool() ) {
|
||||
DrawFov();
|
||||
}
|
||||
|
||||
if (health <= 0) {
|
||||
BecomeInactive( TH_THINK );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// run physics
|
||||
RunPhysics();
|
||||
|
||||
if ( thinkFlags & TH_THINK ) {
|
||||
if (CanSeePlayer()) {
|
||||
if (alertMode == SCANNING) {
|
||||
float sightTime;
|
||||
|
||||
SetAlertMode(ALERT);
|
||||
stopSweeping = gameLocal.time;
|
||||
if (sweeping) {
|
||||
CancelEvents( &EV_SecurityCam_Pause );
|
||||
} else {
|
||||
CancelEvents( &EV_SecurityCam_ReverseSweep );
|
||||
}
|
||||
sweeping = false;
|
||||
StopSound( SND_CHANNEL_ANY, false );
|
||||
StartSound( "snd_sight", SND_CHANNEL_BODY, 0, false, NULL );
|
||||
|
||||
sightTime = spawnArgs.GetFloat( "sightTime", "5" );
|
||||
PostEventSec(&EV_SecurityCam_Alert, sightTime);
|
||||
}
|
||||
} else {
|
||||
if (alertMode == ALERT) {
|
||||
float sightResume;
|
||||
|
||||
SetAlertMode(LOSINGINTEREST);
|
||||
CancelEvents( &EV_SecurityCam_Alert );
|
||||
|
||||
sightResume = spawnArgs.GetFloat( "sightResume", "1.5" );
|
||||
PostEventSec( &EV_SecurityCam_ContinueSweep, sightResume );
|
||||
}
|
||||
|
||||
if ( sweeping ) {
|
||||
idAngles a = GetPhysics()->GetAxis().ToAngles();
|
||||
|
||||
pct = ( gameLocal.time - sweepStart ) / ( sweepEnd - sweepStart );
|
||||
travel = pct * sweepAngle;
|
||||
if ( negativeSweep ) {
|
||||
a.yaw = angle + travel;
|
||||
} else {
|
||||
a.yaw = angle - travel;
|
||||
}
|
||||
|
||||
SetAngles( a );
|
||||
}
|
||||
}
|
||||
}
|
||||
Present();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSecurityCamera::GetAxis
|
||||
================
|
||||
*/
|
||||
const idVec3 idSecurityCamera::GetAxis() const {
|
||||
return (flipAxis) ? -GetPhysics()->GetAxis()[modelAxis] : GetPhysics()->GetAxis()[modelAxis];
|
||||
};
|
||||
|
||||
/*
|
||||
================
|
||||
idSecurityCamera::SweepSpeed
|
||||
================
|
||||
*/
|
||||
float idSecurityCamera::SweepSpeed() const {
|
||||
return spawnArgs.GetFloat( "sweepSpeed", "5" );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSecurityCamera::StartSweep
|
||||
================
|
||||
*/
|
||||
void idSecurityCamera::StartSweep() {
|
||||
int speed;
|
||||
|
||||
sweeping = true;
|
||||
sweepStart = gameLocal.time;
|
||||
speed = SEC2MS( SweepSpeed() );
|
||||
sweepEnd = sweepStart + speed;
|
||||
PostEventMS( &EV_SecurityCam_Pause, speed );
|
||||
StartSound( "snd_moving", SND_CHANNEL_BODY, 0, false, NULL );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSecurityCamera::Event_ContinueSweep
|
||||
================
|
||||
*/
|
||||
void idSecurityCamera::Event_ContinueSweep() {
|
||||
float pct = (stopSweeping - sweepStart) / (sweepEnd - sweepStart);
|
||||
float f = gameLocal.time - (sweepEnd - sweepStart) * pct;
|
||||
int speed;
|
||||
|
||||
sweepStart = f;
|
||||
speed = MS2SEC( SweepSpeed() );
|
||||
sweepEnd = sweepStart + speed;
|
||||
PostEventMS( &EV_SecurityCam_Pause, speed * (1.0 - pct));
|
||||
StartSound( "snd_moving", SND_CHANNEL_BODY, 0, false, NULL );
|
||||
SetAlertMode(SCANNING);
|
||||
sweeping = true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSecurityCamera::Event_Alert
|
||||
================
|
||||
*/
|
||||
void idSecurityCamera::Event_Alert() {
|
||||
float wait;
|
||||
|
||||
SetAlertMode(ACTIVATED);
|
||||
StopSound( SND_CHANNEL_ANY, false );
|
||||
StartSound( "snd_activate", SND_CHANNEL_BODY, 0, false, NULL );
|
||||
ActivateTargets(this);
|
||||
CancelEvents( &EV_SecurityCam_ContinueSweep );
|
||||
|
||||
wait = spawnArgs.GetFloat( "wait", "20" );
|
||||
PostEventSec( &EV_SecurityCam_ContinueSweep, wait );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSecurityCamera::Event_ReverseSweep
|
||||
================
|
||||
*/
|
||||
void idSecurityCamera::Event_ReverseSweep() {
|
||||
angle = GetPhysics()->GetAxis().ToAngles().yaw;
|
||||
negativeSweep = !negativeSweep;
|
||||
StartSweep();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSecurityCamera::Event_Pause
|
||||
================
|
||||
*/
|
||||
void idSecurityCamera::Event_Pause() {
|
||||
float sweepWait;
|
||||
|
||||
sweepWait = spawnArgs.GetFloat( "sweepWait", "0.5" );
|
||||
sweeping = false;
|
||||
StopSound( SND_CHANNEL_ANY, false );
|
||||
StartSound( "snd_stop", SND_CHANNEL_BODY, 0, false, NULL );
|
||||
PostEventSec( &EV_SecurityCam_ReverseSweep, sweepWait );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idSecurityCamera::Killed
|
||||
============
|
||||
*/
|
||||
void idSecurityCamera::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) {
|
||||
sweeping = false;
|
||||
StopSound( SND_CHANNEL_ANY, false );
|
||||
const char *fx = spawnArgs.GetString( "fx_destroyed" );
|
||||
if ( fx[0] != '\0' ) {
|
||||
idEntityFx::StartFx( fx, NULL, NULL, this, true );
|
||||
}
|
||||
|
||||
physicsObj.SetSelf( this );
|
||||
physicsObj.SetClipModel( new (TAG_PHYSICS_CLIP_ENTITY) idClipModel( trm ), 0.02f );
|
||||
physicsObj.SetOrigin( GetPhysics()->GetOrigin() );
|
||||
physicsObj.SetAxis( GetPhysics()->GetAxis() );
|
||||
physicsObj.SetBouncyness( 0.2f );
|
||||
physicsObj.SetFriction( 0.6f, 0.6f, 0.2f );
|
||||
physicsObj.SetGravity( gameLocal.GetGravity() );
|
||||
physicsObj.SetContents( CONTENTS_SOLID );
|
||||
physicsObj.SetClipMask( MASK_SOLID | CONTENTS_BODY | CONTENTS_CORPSE | CONTENTS_MOVEABLECLIP );
|
||||
SetPhysics( &physicsObj );
|
||||
physicsObj.DropToFloor();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
idSecurityCamera::Pain
|
||||
============
|
||||
*/
|
||||
bool idSecurityCamera::Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) {
|
||||
const char *fx = spawnArgs.GetString( "fx_damage" );
|
||||
if ( fx[0] != '\0' ) {
|
||||
idEntityFx::StartFx( fx, NULL, NULL, this, true );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
idSecurityCamera::Present
|
||||
|
||||
Present is called to allow entities to generate refEntities, lights, etc for the renderer.
|
||||
================
|
||||
*/
|
||||
void idSecurityCamera::Present() {
|
||||
// don't present to the renderer if the entity hasn't changed
|
||||
if ( !( thinkFlags & TH_UPDATEVISUALS ) ) {
|
||||
return;
|
||||
}
|
||||
BecomeInactive( TH_UPDATEVISUALS );
|
||||
|
||||
// camera target for remote render views
|
||||
if ( cameraTarget ) {
|
||||
renderEntity.remoteRenderView = cameraTarget->GetRenderView();
|
||||
}
|
||||
|
||||
// if set to invisible, skip
|
||||
if ( !renderEntity.hModel || IsHidden() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// add to refresh list
|
||||
if ( modelDefHandle == -1 ) {
|
||||
modelDefHandle = gameRenderWorld->AddEntityDef( &renderEntity );
|
||||
} else {
|
||||
gameRenderWorld->UpdateEntityDef( modelDefHandle, &renderEntity );
|
||||
}
|
||||
}
|
||||
97
neo/d3xp/SecurityCamera.h
Normal file
97
neo/d3xp/SecurityCamera.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_SECURITYCAMERA_H__
|
||||
#define __GAME_SECURITYCAMERA_H__
|
||||
|
||||
/*
|
||||
===================================================================================
|
||||
|
||||
Security camera
|
||||
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
|
||||
class idSecurityCamera : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idSecurityCamera );
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void Think();
|
||||
|
||||
virtual renderView_t * GetRenderView();
|
||||
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
|
||||
virtual bool Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
|
||||
virtual void Present();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
enum { SCANNING, LOSINGINTEREST, ALERT, ACTIVATED };
|
||||
|
||||
float angle;
|
||||
float sweepAngle;
|
||||
int modelAxis;
|
||||
bool flipAxis;
|
||||
float scanDist;
|
||||
float scanFov;
|
||||
|
||||
float sweepStart;
|
||||
float sweepEnd;
|
||||
bool negativeSweep;
|
||||
bool sweeping;
|
||||
int alertMode;
|
||||
float stopSweeping;
|
||||
float scanFovCos;
|
||||
|
||||
idVec3 viewOffset;
|
||||
|
||||
int pvsArea;
|
||||
idPhysics_RigidBody physicsObj;
|
||||
idTraceModel trm;
|
||||
|
||||
void StartSweep();
|
||||
bool CanSeePlayer();
|
||||
void SetAlertMode( int status );
|
||||
void DrawFov();
|
||||
const idVec3 GetAxis() const;
|
||||
float SweepSpeed() const;
|
||||
|
||||
void Event_ReverseSweep();
|
||||
void Event_ContinueSweep();
|
||||
void Event_Pause();
|
||||
void Event_Alert();
|
||||
void Event_AddLight();
|
||||
};
|
||||
|
||||
#endif /* !__GAME_SECURITYCAMERA_H__ */
|
||||
438
neo/d3xp/SmokeParticles.cpp
Normal file
438
neo/d3xp/SmokeParticles.cpp
Normal file
@@ -0,0 +1,438 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../idlib/precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Game_local.h"
|
||||
|
||||
static const char *smokeParticle_SnapshotName = "_SmokeParticle_Snapshot_";
|
||||
|
||||
/*
|
||||
================
|
||||
idSmokeParticles::idSmokeParticles
|
||||
================
|
||||
*/
|
||||
idSmokeParticles::idSmokeParticles() {
|
||||
initialized = false;
|
||||
memset( &renderEntity, 0, sizeof( renderEntity ) );
|
||||
renderEntityHandle = -1;
|
||||
memset( smokes, 0, sizeof( smokes ) );
|
||||
freeSmokes = NULL;
|
||||
numActiveSmokes = 0;
|
||||
currentParticleTime = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSmokeParticles::Init
|
||||
================
|
||||
*/
|
||||
void idSmokeParticles::Init() {
|
||||
if ( initialized ) {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
// set up the free list
|
||||
for ( int i = 0; i < MAX_SMOKE_PARTICLES-1; i++ ) {
|
||||
smokes[i].next = &smokes[i+1];
|
||||
}
|
||||
smokes[MAX_SMOKE_PARTICLES-1].next = NULL;
|
||||
freeSmokes = &smokes[0];
|
||||
numActiveSmokes = 0;
|
||||
|
||||
activeStages.Clear();
|
||||
|
||||
memset( &renderEntity, 0, sizeof( renderEntity ) );
|
||||
|
||||
renderEntity.bounds.Clear();
|
||||
renderEntity.axis = mat3_identity;
|
||||
renderEntity.shaderParms[ SHADERPARM_RED ] = 1;
|
||||
renderEntity.shaderParms[ SHADERPARM_GREEN ] = 1;
|
||||
renderEntity.shaderParms[ SHADERPARM_BLUE ] = 1;
|
||||
renderEntity.shaderParms[3] = 1;
|
||||
|
||||
renderEntity.hModel = renderModelManager->AllocModel();
|
||||
renderEntity.hModel->InitEmpty( smokeParticle_SnapshotName );
|
||||
|
||||
// we certainly don't want particle shadows
|
||||
renderEntity.noShadow = 1;
|
||||
|
||||
// huge bounds, so it will be present in every world area
|
||||
renderEntity.bounds.AddPoint( idVec3(-100000, -100000, -100000) );
|
||||
renderEntity.bounds.AddPoint( idVec3( 100000, 100000, 100000) );
|
||||
|
||||
renderEntity.callback = idSmokeParticles::ModelCallback;
|
||||
// add to renderer list
|
||||
renderEntityHandle = gameRenderWorld->AddEntityDef( &renderEntity );
|
||||
|
||||
currentParticleTime = -1;
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSmokeParticles::Shutdown
|
||||
================
|
||||
*/
|
||||
void idSmokeParticles::Shutdown() {
|
||||
// make sure the render entity is freed before the model is freed
|
||||
if ( renderEntityHandle != -1 ) {
|
||||
gameRenderWorld->FreeEntityDef( renderEntityHandle );
|
||||
renderEntityHandle = -1;
|
||||
}
|
||||
if ( renderEntity.hModel != NULL ) {
|
||||
renderModelManager->FreeModel( renderEntity.hModel );
|
||||
renderEntity.hModel = NULL;
|
||||
}
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSmokeParticles::FreeSmokes
|
||||
================
|
||||
*/
|
||||
void idSmokeParticles::FreeSmokes() {
|
||||
for ( int activeStageNum = 0; activeStageNum < activeStages.Num(); activeStageNum++ ) {
|
||||
singleSmoke_t *smoke, *next, *last;
|
||||
|
||||
activeSmokeStage_t *active = &activeStages[activeStageNum];
|
||||
const idParticleStage *stage = active->stage;
|
||||
|
||||
for ( last = NULL, smoke = active->smokes; smoke; smoke = next ) {
|
||||
next = smoke->next;
|
||||
|
||||
float frac;
|
||||
|
||||
if ( smoke->timeGroup ) {
|
||||
frac = (float)( gameLocal.fast.time - smoke->privateStartTime ) / ( stage->particleLife * 1000 );
|
||||
}
|
||||
else {
|
||||
frac = (float)( gameLocal.slow.time - smoke->privateStartTime ) / ( stage->particleLife * 1000 );
|
||||
}
|
||||
if ( frac >= 1.0f ) {
|
||||
// remove the particle from the stage list
|
||||
if ( last != NULL ) {
|
||||
last->next = smoke->next;
|
||||
} else {
|
||||
active->smokes = smoke->next;
|
||||
}
|
||||
// put the particle on the free list
|
||||
smoke->next = freeSmokes;
|
||||
freeSmokes = smoke;
|
||||
numActiveSmokes--;
|
||||
continue;
|
||||
}
|
||||
|
||||
last = smoke;
|
||||
}
|
||||
|
||||
if ( !active->smokes ) {
|
||||
// remove this from the activeStages list
|
||||
activeStages.RemoveIndex( activeStageNum );
|
||||
activeStageNum--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSmokeParticles::EmitSmoke
|
||||
|
||||
Called by game code to drop another particle into the list
|
||||
================
|
||||
*/
|
||||
bool idSmokeParticles::EmitSmoke( const idDeclParticle *smoke, const int systemStartTime, const float diversity, const idVec3 &origin, const idMat3 &axis, int timeGroup /*_D3XP*/ ) {
|
||||
bool continues = false;
|
||||
SetTimeState ts( timeGroup );
|
||||
|
||||
if ( !smoke ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !gameLocal.isNewFrame ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// dedicated doesn't smoke. No UpdateRenderEntity, so they would not be freed
|
||||
if ( gameLocal.GetLocalClientNum() < 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
assert( gameLocal.time == 0 || systemStartTime <= gameLocal.time );
|
||||
if ( systemStartTime > gameLocal.time ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
idRandom steppingRandom( 0xffff * diversity );
|
||||
|
||||
// for each stage in the smoke that is still emitting particles, emit a new singleSmoke_t
|
||||
for ( int stageNum = 0; stageNum < smoke->stages.Num(); stageNum++ ) {
|
||||
const idParticleStage *stage = smoke->stages[stageNum];
|
||||
|
||||
if ( !stage->cycleMsec ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !stage->material ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( stage->particleLife <= 0 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// see how many particles we should emit this tic
|
||||
// FIXME: smoke.privateStartTime += stage->timeOffset;
|
||||
int finalParticleTime = stage->cycleMsec * stage->spawnBunching;
|
||||
int deltaMsec = gameLocal.time - systemStartTime;
|
||||
|
||||
int nowCount = 0, prevCount = 0;
|
||||
if ( finalParticleTime == 0 ) {
|
||||
// if spawnBunching is 0, they will all come out at once
|
||||
if ( gameLocal.time == systemStartTime ) {
|
||||
prevCount = -1;
|
||||
nowCount = stage->totalParticles-1;
|
||||
} else {
|
||||
prevCount = stage->totalParticles;
|
||||
}
|
||||
} else {
|
||||
nowCount = floor( ( (float)deltaMsec / finalParticleTime ) * stage->totalParticles );
|
||||
if ( nowCount >= stage->totalParticles ) {
|
||||
nowCount = stage->totalParticles-1;
|
||||
}
|
||||
prevCount = floor( ((float)( deltaMsec - ( gameLocal.time - gameLocal.previousTime ) ) / finalParticleTime) * stage->totalParticles );
|
||||
if ( prevCount < -1 ) {
|
||||
prevCount = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( prevCount >= stage->totalParticles ) {
|
||||
// no more particles from this stage
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( nowCount < stage->totalParticles-1 ) {
|
||||
// the system will need to emit particles next frame as well
|
||||
continues = true;
|
||||
}
|
||||
|
||||
// find an activeSmokeStage that matches this
|
||||
activeSmokeStage_t *active = NULL;
|
||||
int i;
|
||||
for ( i = 0 ; i < activeStages.Num() ; i++ ) {
|
||||
active = &activeStages[i];
|
||||
if ( active->stage == stage ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( i == activeStages.Num() ) {
|
||||
// add a new one
|
||||
activeSmokeStage_t newActive;
|
||||
|
||||
newActive.smokes = NULL;
|
||||
newActive.stage = stage;
|
||||
i = activeStages.Append( newActive );
|
||||
active = &activeStages[i];
|
||||
}
|
||||
|
||||
// add all the required particles
|
||||
for ( prevCount++ ; prevCount <= nowCount && active != NULL ; prevCount++ ) {
|
||||
if ( !freeSmokes ) {
|
||||
gameLocal.Printf( "idSmokeParticles::EmitSmoke: no free smokes with %d active stages\n", activeStages.Num() );
|
||||
return true;
|
||||
}
|
||||
singleSmoke_t *newSmoke = freeSmokes;
|
||||
freeSmokes = freeSmokes->next;
|
||||
numActiveSmokes++;
|
||||
|
||||
newSmoke->timeGroup = timeGroup;
|
||||
newSmoke->index = prevCount;
|
||||
newSmoke->axis = axis;
|
||||
newSmoke->origin = origin;
|
||||
newSmoke->random = steppingRandom;
|
||||
newSmoke->privateStartTime = systemStartTime + prevCount * finalParticleTime / stage->totalParticles;
|
||||
newSmoke->next = active->smokes;
|
||||
active->smokes = newSmoke;
|
||||
|
||||
steppingRandom.RandomInt(); // advance the random
|
||||
}
|
||||
}
|
||||
|
||||
return continues;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSmokeParticles::UpdateRenderEntity
|
||||
================
|
||||
*/
|
||||
bool idSmokeParticles::UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ) {
|
||||
|
||||
// this may be triggered by a model trace or other non-view related source,
|
||||
// to which we should look like an empty model
|
||||
if ( !renderView ) {
|
||||
// FIXME: re-use model surfaces
|
||||
renderEntity->hModel->InitEmpty( smokeParticle_SnapshotName );
|
||||
return false;
|
||||
}
|
||||
|
||||
// don't regenerate it if it is current
|
||||
if ( renderView->time[renderEntity->timeGroup] == currentParticleTime && !renderView->forceUpdate ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME: re-use model surfaces
|
||||
renderEntity->hModel->InitEmpty( smokeParticle_SnapshotName );
|
||||
|
||||
currentParticleTime = renderView->time[renderEntity->timeGroup];
|
||||
|
||||
particleGen_t g;
|
||||
|
||||
g.renderEnt = renderEntity;
|
||||
g.renderView = renderView;
|
||||
|
||||
for ( int activeStageNum = 0; activeStageNum < activeStages.Num(); activeStageNum++ ) {
|
||||
singleSmoke_t *smoke, *next, *last;
|
||||
|
||||
activeSmokeStage_t *active = &activeStages[activeStageNum];
|
||||
const idParticleStage *stage = active->stage;
|
||||
|
||||
if ( !stage->material ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// allocate a srfTriangles that can hold all the particles
|
||||
int count = 0;
|
||||
for ( smoke = active->smokes; smoke; smoke = smoke->next ) {
|
||||
count++;
|
||||
}
|
||||
int quads = count * stage->NumQuadsPerParticle();
|
||||
srfTriangles_t *tri = renderEntity->hModel->AllocSurfaceTriangles( quads * 4, quads * 6 );
|
||||
tri->numIndexes = quads * 6;
|
||||
tri->numVerts = quads * 4;
|
||||
|
||||
// just always draw the particles
|
||||
tri->bounds[0][0] =
|
||||
tri->bounds[0][1] =
|
||||
tri->bounds[0][2] = -99999;
|
||||
tri->bounds[1][0] =
|
||||
tri->bounds[1][1] =
|
||||
tri->bounds[1][2] = 99999;
|
||||
|
||||
tri->numVerts = 0;
|
||||
for ( last = NULL, smoke = active->smokes; smoke; smoke = next ) {
|
||||
next = smoke->next;
|
||||
|
||||
if ( smoke->timeGroup ) {
|
||||
g.frac = (float)( gameLocal.fast.time - smoke->privateStartTime ) / (stage->particleLife * 1000);
|
||||
}
|
||||
else {
|
||||
g.frac = (float)( gameLocal.time - smoke->privateStartTime ) / (stage->particleLife * 1000);
|
||||
}
|
||||
if ( g.frac >= 1.0f ) {
|
||||
// remove the particle from the stage list
|
||||
if ( last != NULL ) {
|
||||
last->next = smoke->next;
|
||||
} else {
|
||||
active->smokes = smoke->next;
|
||||
}
|
||||
// put the particle on the free list
|
||||
smoke->next = freeSmokes;
|
||||
freeSmokes = smoke;
|
||||
numActiveSmokes--;
|
||||
continue;
|
||||
}
|
||||
|
||||
g.index = smoke->index;
|
||||
g.random = smoke->random;
|
||||
|
||||
g.origin = smoke->origin;
|
||||
g.axis = smoke->axis;
|
||||
|
||||
g.originalRandom = g.random;
|
||||
g.age = g.frac * stage->particleLife;
|
||||
|
||||
tri->numVerts += stage->CreateParticle( &g, tri->verts + tri->numVerts );
|
||||
|
||||
last = smoke;
|
||||
}
|
||||
if ( tri->numVerts > quads * 4 ) {
|
||||
gameLocal.Error( "idSmokeParticles::UpdateRenderEntity: miscounted verts" );
|
||||
}
|
||||
|
||||
if ( tri->numVerts == 0 ) {
|
||||
|
||||
// they were all removed
|
||||
renderEntity->hModel->FreeSurfaceTriangles( tri );
|
||||
|
||||
if ( !active->smokes ) {
|
||||
// remove this from the activeStages list
|
||||
activeStages.RemoveIndex( activeStageNum );
|
||||
activeStageNum--;
|
||||
}
|
||||
} else {
|
||||
// build the index list
|
||||
int indexes = 0;
|
||||
for ( int i = 0 ; i < tri->numVerts ; i += 4 ) {
|
||||
tri->indexes[indexes+0] = i;
|
||||
tri->indexes[indexes+1] = i+2;
|
||||
tri->indexes[indexes+2] = i+3;
|
||||
tri->indexes[indexes+3] = i;
|
||||
tri->indexes[indexes+4] = i+3;
|
||||
tri->indexes[indexes+5] = i+1;
|
||||
indexes += 6;
|
||||
}
|
||||
tri->numIndexes = indexes;
|
||||
|
||||
modelSurface_t surf;
|
||||
surf.geometry = tri;
|
||||
surf.shader = stage->material;
|
||||
surf.id = 0;
|
||||
|
||||
renderEntity->hModel->AddSurface( surf );
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSmokeParticles::ModelCallback
|
||||
================
|
||||
*/
|
||||
bool idSmokeParticles::ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView ) {
|
||||
// update the particles
|
||||
if ( gameLocal.smokeParticles ) {
|
||||
return gameLocal.smokeParticles->UpdateRenderEntity( renderEntity, renderView );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
103
neo/d3xp/SmokeParticles.h
Normal file
103
neo/d3xp/SmokeParticles.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __SMOKEPARTICLES_H__
|
||||
#define __SMOKEPARTICLES_H__
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Smoke systems are for particles that are emitted off of things that are
|
||||
constantly changing position and orientation, like muzzle smoke coming
|
||||
from a bone on a weapon, blood spurting from a wound, or particles
|
||||
trailing from a monster limb.
|
||||
|
||||
The smoke particles are always evaluated and rendered each tic, so there
|
||||
is a performance cost with using them for continuous effects. The general
|
||||
particle systems are completely parametric, and have no performance
|
||||
overhead when not in view.
|
||||
|
||||
All smoke systems share the same shaderparms, so any coloration must be
|
||||
done in the particle definition.
|
||||
|
||||
Each particle model has its own shaderparms, which can be used by the
|
||||
particle materials.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
typedef struct singleSmoke_s {
|
||||
struct singleSmoke_s * next;
|
||||
int privateStartTime; // start time for this particular particle
|
||||
int index; // particle index in system, 0 <= index < stage->totalParticles
|
||||
idRandom random;
|
||||
idVec3 origin;
|
||||
idMat3 axis;
|
||||
int timeGroup;
|
||||
} singleSmoke_t;
|
||||
|
||||
typedef struct {
|
||||
const idParticleStage * stage;
|
||||
singleSmoke_t * smokes;
|
||||
} activeSmokeStage_t;
|
||||
|
||||
|
||||
class idSmokeParticles {
|
||||
public:
|
||||
idSmokeParticles();
|
||||
|
||||
// creats an entity covering the entire world that will call back each rendering
|
||||
void Init();
|
||||
void Shutdown();
|
||||
|
||||
// spits out a particle, returning false if the system will not emit any more particles in the future
|
||||
bool EmitSmoke( const idDeclParticle *smoke, const int startTime, const float diversity,
|
||||
const idVec3 &origin, const idMat3 &axis, int timeGroup /*_D3XP*/ );
|
||||
|
||||
// free old smokes
|
||||
void FreeSmokes();
|
||||
|
||||
private:
|
||||
bool initialized;
|
||||
|
||||
renderEntity_t renderEntity; // used to present a model to the renderer
|
||||
int renderEntityHandle; // handle to static renderer model
|
||||
|
||||
static const int MAX_SMOKE_PARTICLES = 10000;
|
||||
singleSmoke_t smokes[MAX_SMOKE_PARTICLES];
|
||||
|
||||
idList<activeSmokeStage_t, TAG_PARTICLE> activeStages;
|
||||
singleSmoke_t * freeSmokes;
|
||||
int numActiveSmokes;
|
||||
int currentParticleTime; // don't need to recalculate if == view time
|
||||
|
||||
bool UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView );
|
||||
static bool ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView );
|
||||
};
|
||||
|
||||
#endif /* !__SMOKEPARTICLES_H__ */
|
||||
304
neo/d3xp/Sound.cpp
Normal file
304
neo/d3xp/Sound.cpp
Normal file
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../idlib/precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Game_local.h"
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
SOUND
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
const idEventDef EV_Speaker_On( "On", NULL );
|
||||
const idEventDef EV_Speaker_Off( "Off", NULL );
|
||||
const idEventDef EV_Speaker_Timer( "<timer>", NULL );
|
||||
|
||||
CLASS_DECLARATION( idEntity, idSound )
|
||||
EVENT( EV_Activate, idSound::Event_Trigger )
|
||||
EVENT( EV_Speaker_On, idSound::Event_On )
|
||||
EVENT( EV_Speaker_Off, idSound::Event_Off )
|
||||
EVENT( EV_Speaker_Timer, idSound::Event_Timer )
|
||||
END_CLASS
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
idSound::idSound
|
||||
================
|
||||
*/
|
||||
idSound::idSound() {
|
||||
lastSoundVol = 0.0f;
|
||||
soundVol = 0.0f;
|
||||
shakeTranslate.Zero();
|
||||
shakeRotate.Zero();
|
||||
random = 0.0f;
|
||||
wait = 0.0f;
|
||||
timerOn = false;
|
||||
playingUntilTime = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSound::Save
|
||||
================
|
||||
*/
|
||||
void idSound::Save( idSaveGame *savefile ) const {
|
||||
savefile->WriteFloat( lastSoundVol );
|
||||
savefile->WriteFloat( soundVol );
|
||||
savefile->WriteFloat( random );
|
||||
savefile->WriteFloat( wait );
|
||||
savefile->WriteBool( timerOn );
|
||||
savefile->WriteVec3( shakeTranslate );
|
||||
savefile->WriteAngles( shakeRotate );
|
||||
savefile->WriteInt( playingUntilTime );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSound::Restore
|
||||
================
|
||||
*/
|
||||
void idSound::Restore( idRestoreGame *savefile ) {
|
||||
savefile->ReadFloat( lastSoundVol );
|
||||
savefile->ReadFloat( soundVol );
|
||||
savefile->ReadFloat( random );
|
||||
savefile->ReadFloat( wait );
|
||||
savefile->ReadBool( timerOn );
|
||||
savefile->ReadVec3( shakeTranslate );
|
||||
savefile->ReadAngles( shakeRotate );
|
||||
savefile->ReadInt( playingUntilTime );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSound::Spawn
|
||||
================
|
||||
*/
|
||||
void idSound::Spawn() {
|
||||
spawnArgs.GetVector( "move", "0 0 0", shakeTranslate );
|
||||
spawnArgs.GetAngles( "rotate", "0 0 0", shakeRotate );
|
||||
spawnArgs.GetFloat( "random", "0", random );
|
||||
spawnArgs.GetFloat( "wait", "0", wait );
|
||||
|
||||
if ( ( wait > 0.0f ) && ( random >= wait ) ) {
|
||||
random = wait - 0.001;
|
||||
gameLocal.Warning( "speaker '%s' at (%s) has random >= wait", name.c_str(), GetPhysics()->GetOrigin().ToString(0) );
|
||||
}
|
||||
|
||||
soundVol = 0.0f;
|
||||
lastSoundVol = 0.0f;
|
||||
|
||||
if ( ( shakeRotate != ang_zero ) || ( shakeTranslate != vec3_zero ) ) {
|
||||
BecomeActive( TH_THINK );
|
||||
}
|
||||
|
||||
if ( !refSound.waitfortrigger && ( wait > 0.0f ) ) {
|
||||
timerOn = true;
|
||||
PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random );
|
||||
} else {
|
||||
timerOn = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSound::Event_Trigger
|
||||
|
||||
this will toggle the idle idSound on and off
|
||||
================
|
||||
*/
|
||||
void idSound::Event_Trigger( idEntity *activator ) {
|
||||
if ( wait > 0.0f ) {
|
||||
if ( timerOn ) {
|
||||
timerOn = false;
|
||||
CancelEvents( &EV_Speaker_Timer );
|
||||
} else {
|
||||
timerOn = true;
|
||||
DoSound( true );
|
||||
PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random );
|
||||
}
|
||||
} else {
|
||||
if ( common->IsMultiplayer() ) {
|
||||
if ( refSound.referenceSound && ( gameLocal.time < playingUntilTime ) ) {
|
||||
DoSound( false );
|
||||
} else {
|
||||
DoSound( true );
|
||||
}
|
||||
} else {
|
||||
if ( refSound.referenceSound && refSound.referenceSound->CurrentlyPlaying() ) {
|
||||
DoSound( false );
|
||||
} else {
|
||||
DoSound( true );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSound::Event_Timer
|
||||
================
|
||||
*/
|
||||
void idSound::Event_Timer() {
|
||||
DoSound( true );
|
||||
PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSound::Think
|
||||
================
|
||||
*/
|
||||
void idSound::Think() {
|
||||
idAngles ang;
|
||||
|
||||
// run physics
|
||||
RunPhysics();
|
||||
|
||||
// clear out our update visuals think flag since we never call Present
|
||||
BecomeInactive( TH_UPDATEVISUALS );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idSound::UpdateChangableSpawnArgs
|
||||
===============
|
||||
*/
|
||||
void idSound::UpdateChangeableSpawnArgs( const idDict *source ) {
|
||||
|
||||
idEntity::UpdateChangeableSpawnArgs( source );
|
||||
|
||||
if ( source ) {
|
||||
FreeSoundEmitter( true );
|
||||
spawnArgs.Copy( *source );
|
||||
idSoundEmitter *saveRef = refSound.referenceSound;
|
||||
gameEdit->ParseSpawnArgsToRefSound( &spawnArgs, &refSound );
|
||||
refSound.referenceSound = saveRef;
|
||||
|
||||
idVec3 origin;
|
||||
idMat3 axis;
|
||||
|
||||
if ( GetPhysicsToSoundTransform( origin, axis ) ) {
|
||||
refSound.origin = GetPhysics()->GetOrigin() + origin * axis;
|
||||
} else {
|
||||
refSound.origin = GetPhysics()->GetOrigin();
|
||||
}
|
||||
|
||||
spawnArgs.GetFloat( "random", "0", random );
|
||||
spawnArgs.GetFloat( "wait", "0", wait );
|
||||
|
||||
if ( ( wait > 0.0f ) && ( random >= wait ) ) {
|
||||
random = wait - 0.001;
|
||||
gameLocal.Warning( "speaker '%s' at (%s) has random >= wait", name.c_str(), GetPhysics()->GetOrigin().ToString(0) );
|
||||
}
|
||||
|
||||
if ( !refSound.waitfortrigger && ( wait > 0.0f ) ) {
|
||||
timerOn = true;
|
||||
DoSound( false );
|
||||
CancelEvents( &EV_Speaker_Timer );
|
||||
PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random );
|
||||
} else if ( !refSound.waitfortrigger && !(refSound.referenceSound && refSound.referenceSound->CurrentlyPlaying() ) ) {
|
||||
// start it if it isn't already playing, and we aren't waitForTrigger
|
||||
DoSound( true );
|
||||
timerOn = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idSound::SetSound
|
||||
===============
|
||||
*/
|
||||
void idSound::SetSound( const char *sound, int channel ) {
|
||||
const idSoundShader *shader = declManager->FindSound( sound );
|
||||
if ( shader != refSound.shader ) {
|
||||
FreeSoundEmitter( true );
|
||||
}
|
||||
gameEdit->ParseSpawnArgsToRefSound(&spawnArgs, &refSound);
|
||||
refSound.shader = shader;
|
||||
// start it if it isn't already playing, and we aren't waitForTrigger
|
||||
if ( !refSound.waitfortrigger && !(refSound.referenceSound && refSound.referenceSound->CurrentlyPlaying() ) ) {
|
||||
DoSound( true );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSound::DoSound
|
||||
================
|
||||
*/
|
||||
void idSound::DoSound( bool play ) {
|
||||
if ( play ) {
|
||||
StartSoundShader( refSound.shader, SND_CHANNEL_ANY, refSound.parms.soundShaderFlags, true, &playingUntilTime );
|
||||
playingUntilTime += gameLocal.time;
|
||||
} else {
|
||||
StopSound( SND_CHANNEL_ANY, true );
|
||||
playingUntilTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSound::Event_On
|
||||
================
|
||||
*/
|
||||
void idSound::Event_On() {
|
||||
if ( wait > 0.0f ) {
|
||||
timerOn = true;
|
||||
PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random );
|
||||
}
|
||||
DoSound( true );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idSound::Event_Off
|
||||
================
|
||||
*/
|
||||
void idSound::Event_Off() {
|
||||
if ( timerOn ) {
|
||||
timerOn = false;
|
||||
CancelEvents( &EV_Speaker_Timer );
|
||||
}
|
||||
DoSound( false );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idSound::ShowEditingDialog
|
||||
===============
|
||||
*/
|
||||
void idSound::ShowEditingDialog() {
|
||||
}
|
||||
|
||||
76
neo/d3xp/Sound.h
Normal file
76
neo/d3xp/Sound.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_SOUND_H__
|
||||
#define __GAME_SOUND_H__
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Generic sound emitter.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idSound : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idSound );
|
||||
|
||||
idSound();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void UpdateChangeableSpawnArgs( const idDict *source );
|
||||
|
||||
void Spawn();
|
||||
|
||||
void ToggleOnOff( idEntity *other, idEntity *activator );
|
||||
void Think();
|
||||
void SetSound( const char *sound, int channel = SND_CHANNEL_ANY );
|
||||
|
||||
virtual void ShowEditingDialog();
|
||||
|
||||
private:
|
||||
float lastSoundVol;
|
||||
float soundVol;
|
||||
float random;
|
||||
float wait;
|
||||
bool timerOn;
|
||||
idVec3 shakeTranslate;
|
||||
idAngles shakeRotate;
|
||||
int playingUntilTime;
|
||||
|
||||
void Event_Trigger( idEntity *activator );
|
||||
void Event_Timer();
|
||||
void Event_On();
|
||||
void Event_Off();
|
||||
void DoSound( bool play );
|
||||
};
|
||||
|
||||
#endif /* !__GAME_SOUND_H__ */
|
||||
1921
neo/d3xp/Target.cpp
Normal file
1921
neo/d3xp/Target.cpp
Normal file
File diff suppressed because it is too large
Load Diff
615
neo/d3xp/Target.h
Normal file
615
neo/d3xp/Target.h
Normal file
@@ -0,0 +1,615 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_TARGET_H__
|
||||
#define __GAME_TARGET_H__
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_Remove
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_Remove : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_Remove );
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_Show
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_Show : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_Show );
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_Damage
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_Damage : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_Damage );
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_SessionCommand
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_SessionCommand : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_SessionCommand );
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_EndLevel
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_EndLevel : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_EndLevel );
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_WaitForButton
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_WaitForButton : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_WaitForButton );
|
||||
|
||||
void Think();
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_SetGlobalShaderTime
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_SetGlobalShaderTime : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_SetGlobalShaderTime );
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_SetShaderParm
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_SetShaderParm : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_SetShaderParm );
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_SetShaderTime
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_SetShaderTime : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_SetShaderTime );
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_FadeEntity
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_FadeEntity : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_FadeEntity );
|
||||
|
||||
idTarget_FadeEntity();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Think();
|
||||
|
||||
private:
|
||||
idVec4 fadeFrom;
|
||||
int fadeStart;
|
||||
int fadeEnd;
|
||||
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_LightFadeIn
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_LightFadeIn : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_LightFadeIn );
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_LightFadeOut
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_LightFadeOut : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_LightFadeOut );
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_Give
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_Give : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_Give );
|
||||
|
||||
void Spawn();
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_GiveEmail
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_GiveEmail : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_GiveEmail );
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_SetModel
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_SetModel : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_SetModel );
|
||||
|
||||
void Spawn();
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_SetInfluence
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
typedef struct SavedGui_s {
|
||||
SavedGui_s() {memset(gui, 0, sizeof(idUserInterface*)*MAX_RENDERENTITY_GUI); };
|
||||
idUserInterface* gui[MAX_RENDERENTITY_GUI];
|
||||
} SavedGui_t;
|
||||
|
||||
class idTarget_SetInfluence : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_SetInfluence );
|
||||
|
||||
idTarget_SetInfluence();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
void Event_RestoreInfluence();
|
||||
void Event_GatherEntities();
|
||||
void Event_Flash( float flash, int out );
|
||||
void Event_ClearFlash( float flash );
|
||||
void Think();
|
||||
|
||||
idList<int, TAG_TARGET> lightList;
|
||||
idList<int, TAG_TARGET> guiList;
|
||||
idList<int, TAG_TARGET> soundList;
|
||||
idList<int, TAG_TARGET> genericList;
|
||||
float flashIn;
|
||||
float flashOut;
|
||||
float delay;
|
||||
idStr flashInSound;
|
||||
idStr flashOutSound;
|
||||
idEntity * switchToCamera;
|
||||
idInterpolate<float>fovSetting;
|
||||
bool soundFaded;
|
||||
bool restoreOnTrigger;
|
||||
|
||||
idList<SavedGui_t, TAG_TARGET> savedGuiList;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_SetKeyVal
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_SetKeyVal : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_SetKeyVal );
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_SetFov
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_SetFov : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_SetFov );
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Think();
|
||||
|
||||
private:
|
||||
idInterpolate<float> fovSetting;
|
||||
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_SetPrimaryObjective
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_SetPrimaryObjective : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_SetPrimaryObjective );
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_LockDoor
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_LockDoor: public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_LockDoor );
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_CallObjectFunction
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_CallObjectFunction : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_CallObjectFunction );
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_LockDoor
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_EnableLevelWeapons : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_EnableLevelWeapons );
|
||||
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_Tip
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_Tip : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_Tip );
|
||||
|
||||
idTarget_Tip();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
private:
|
||||
idVec3 playerPos;
|
||||
|
||||
void Event_Activate( idEntity *activator );
|
||||
void Event_TipOff();
|
||||
void Event_GetPlayerPos();
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_GiveSecurity
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
class idTarget_GiveSecurity : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_GiveSecurity );
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_RemoveWeapons
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
class idTarget_RemoveWeapons : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_RemoveWeapons );
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_LevelTrigger
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
class idTarget_LevelTrigger : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_LevelTrigger );
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_Checkpoint
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
class idTarget_Checkpoint : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_Checkpoint );
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_EnableStamina
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
class idTarget_EnableStamina : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_EnableStamina );
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_FadeSoundClass
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
class idTarget_FadeSoundClass : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_FadeSoundClass );
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
void Event_RestoreVolume();
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_RumbleJoystick
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_RumbleJoystick : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_RumbleJoystick );
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idTarget_Achievement
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTarget_Achievement : public idTarget {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTarget_Achievement );
|
||||
private:
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
#endif /* !__GAME_TARGET_H__ */
|
||||
1357
neo/d3xp/Trigger.cpp
Normal file
1357
neo/d3xp/Trigger.cpp
Normal file
File diff suppressed because it is too large
Load Diff
312
neo/d3xp/Trigger.h
Normal file
312
neo/d3xp/Trigger.h
Normal file
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_TRIGGER_H__
|
||||
#define __GAME_TRIGGER_H__
|
||||
|
||||
extern const idEventDef EV_Enable;
|
||||
extern const idEventDef EV_Disable;
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Trigger base.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTrigger : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTrigger );
|
||||
|
||||
static void DrawDebugInfo();
|
||||
|
||||
idTrigger();
|
||||
void Spawn();
|
||||
|
||||
const function_t * GetScriptFunction() const;
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void Enable();
|
||||
virtual void Disable();
|
||||
|
||||
protected:
|
||||
void CallScript() const;
|
||||
|
||||
void Event_Enable();
|
||||
void Event_Disable();
|
||||
|
||||
const function_t * scriptFunction;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Trigger which can be activated multiple times.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTrigger_Multi : public idTrigger {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTrigger_Multi );
|
||||
|
||||
idTrigger_Multi();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
protected:
|
||||
|
||||
float wait;
|
||||
float random;
|
||||
float delay;
|
||||
float random_delay;
|
||||
int nextTriggerTime;
|
||||
idStr requires;
|
||||
int removeItem;
|
||||
bool touchClient;
|
||||
bool touchOther;
|
||||
bool triggerFirst;
|
||||
bool triggerWithSelf;
|
||||
|
||||
bool CheckFacing( idEntity *activator );
|
||||
void TriggerAction( idEntity *activator );
|
||||
void Event_TriggerAction( idEntity *activator );
|
||||
void Event_Trigger( idEntity *activator );
|
||||
void Event_Touch( idEntity *other, trace_t *trace );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Trigger which can only be activated by an entity with a specific name.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTrigger_EntityName : public idTrigger {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTrigger_EntityName );
|
||||
|
||||
idTrigger_EntityName();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
|
||||
private:
|
||||
float wait;
|
||||
float random;
|
||||
float delay;
|
||||
float random_delay;
|
||||
int nextTriggerTime;
|
||||
bool triggerFirst;
|
||||
idStr entityName;
|
||||
bool testPartialName;
|
||||
|
||||
void TriggerAction( idEntity *activator );
|
||||
void Event_TriggerAction( idEntity *activator );
|
||||
void Event_Trigger( idEntity *activator );
|
||||
void Event_Touch( idEntity *other, trace_t *trace );
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Trigger which repeatedly fires targets.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTrigger_Timer : public idTrigger {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTrigger_Timer );
|
||||
|
||||
idTrigger_Timer();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
|
||||
virtual void Enable();
|
||||
virtual void Disable();
|
||||
|
||||
private:
|
||||
float random;
|
||||
float wait;
|
||||
bool on;
|
||||
float delay;
|
||||
idStr onName;
|
||||
idStr offName;
|
||||
|
||||
void Event_Timer();
|
||||
void Event_Use( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Trigger which fires targets after being activated a specific number of times.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTrigger_Count : public idTrigger {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTrigger_Count );
|
||||
|
||||
idTrigger_Count();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
|
||||
private:
|
||||
int goal;
|
||||
int count;
|
||||
float delay;
|
||||
|
||||
void Event_Trigger( idEntity *activator );
|
||||
void Event_TriggerAction( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Trigger which hurts touching entities.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTrigger_Hurt : public idTrigger {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTrigger_Hurt );
|
||||
|
||||
idTrigger_Hurt();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
|
||||
private:
|
||||
bool on;
|
||||
float delay;
|
||||
int nextTime;
|
||||
|
||||
void Event_Touch( idEntity *other, trace_t *trace );
|
||||
void Event_Toggle( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Trigger which fades the player view.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTrigger_Fade : public idTrigger {
|
||||
public:
|
||||
|
||||
CLASS_PROTOTYPE( idTrigger_Fade );
|
||||
|
||||
private:
|
||||
void Event_Trigger( idEntity *activator );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Trigger which continuously tests whether other entities are touching it.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idTrigger_Touch : public idTrigger {
|
||||
public:
|
||||
|
||||
CLASS_PROTOTYPE( idTrigger_Touch );
|
||||
|
||||
idTrigger_Touch();
|
||||
|
||||
void Spawn();
|
||||
virtual void Think();
|
||||
|
||||
void Save( idSaveGame *savefile );
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
virtual void Enable();
|
||||
virtual void Disable();
|
||||
|
||||
void TouchEntities();
|
||||
|
||||
private:
|
||||
idClipModel * clipModel;
|
||||
|
||||
void Event_Trigger( idEntity *activator );
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Trigger that responces to CTF flags
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
class idTrigger_Flag : public idTrigger_Multi {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTrigger_Flag );
|
||||
|
||||
idTrigger_Flag();
|
||||
void Spawn();
|
||||
|
||||
private:
|
||||
int team;
|
||||
bool player; // flag must be attached/carried by player
|
||||
|
||||
const idEventDef * eventFlag;
|
||||
|
||||
void Event_Touch( idEntity *other, trace_t *trace );
|
||||
};
|
||||
|
||||
#endif /* !__GAME_TRIGGER_H__ */
|
||||
4195
neo/d3xp/Weapon.cpp
Normal file
4195
neo/d3xp/Weapon.cpp
Normal file
File diff suppressed because it is too large
Load Diff
447
neo/d3xp/Weapon.h
Normal file
447
neo/d3xp/Weapon.h
Normal file
@@ -0,0 +1,447 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_WEAPON_H__
|
||||
#define __GAME_WEAPON_H__
|
||||
|
||||
#include "PredictedValue.h"
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Player Weapon
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
extern const idEventDef EV_Weapon_State;
|
||||
|
||||
typedef enum {
|
||||
WP_READY,
|
||||
WP_OUTOFAMMO,
|
||||
WP_RELOAD,
|
||||
WP_HOLSTERED,
|
||||
WP_RISING,
|
||||
WP_LOWERING
|
||||
} weaponStatus_t;
|
||||
|
||||
typedef int ammo_t;
|
||||
static const int AMMO_NUMTYPES = 16;
|
||||
|
||||
class idPlayer;
|
||||
|
||||
static const int LIGHTID_WORLD_MUZZLE_FLASH = 1;
|
||||
static const int LIGHTID_VIEW_MUZZLE_FLASH = 100;
|
||||
|
||||
class idMoveableItem;
|
||||
|
||||
typedef struct {
|
||||
char name[64];
|
||||
char particlename[128];
|
||||
bool active;
|
||||
int startTime;
|
||||
jointHandle_t joint; //The joint on which to attach the particle
|
||||
bool smoke; //Is this a smoke particle
|
||||
const idDeclParticle* particle; //Used for smoke particles
|
||||
idFuncEmitter* emitter; //Used for non-smoke particles
|
||||
} WeaponParticle_t;
|
||||
|
||||
typedef struct {
|
||||
char name[64];
|
||||
bool active;
|
||||
int startTime;
|
||||
jointHandle_t joint;
|
||||
int lightHandle;
|
||||
renderLight_t light;
|
||||
} WeaponLight_t;
|
||||
|
||||
class idWeapon : public idAnimatedEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idWeapon );
|
||||
|
||||
idWeapon();
|
||||
virtual ~idWeapon();
|
||||
|
||||
// Init
|
||||
void Spawn();
|
||||
void SetOwner( idPlayer *owner );
|
||||
idPlayer* GetOwner();
|
||||
virtual bool ShouldConstructScriptObjectAtSpawn() const;
|
||||
void SetFlashlightOwner( idPlayer *owner );
|
||||
|
||||
static void CacheWeapon( const char *weaponName );
|
||||
|
||||
// save games
|
||||
void Save( idSaveGame *savefile ) const; // archives object for save game file
|
||||
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
|
||||
|
||||
// Weapon definition management
|
||||
void Clear();
|
||||
void GetWeaponDef( const char *objectname, int ammoinclip );
|
||||
bool IsLinked();
|
||||
bool IsWorldModelReady();
|
||||
|
||||
// GUIs
|
||||
const char * Icon() const;
|
||||
void UpdateGUI();
|
||||
const char * PdaIcon() const;
|
||||
const char * DisplayName() const;
|
||||
const char * Description() const;
|
||||
|
||||
virtual void SetModel( const char *modelname );
|
||||
bool GetGlobalJointTransform( bool viewModel, const jointHandle_t jointHandle, idVec3 &offset, idMat3 &axis );
|
||||
void SetPushVelocity( const idVec3 &pushVelocity );
|
||||
bool UpdateSkin();
|
||||
|
||||
// State control/player interface
|
||||
void Think();
|
||||
void Raise();
|
||||
void PutAway();
|
||||
void Reload();
|
||||
void LowerWeapon();
|
||||
void RaiseWeapon();
|
||||
void HideWeapon();
|
||||
void ShowWeapon();
|
||||
void HideWorldModel();
|
||||
void ShowWorldModel();
|
||||
void OwnerDied();
|
||||
void BeginAttack();
|
||||
void EndAttack();
|
||||
bool IsReady() const;
|
||||
bool IsReloading() const;
|
||||
bool IsHolstered() const;
|
||||
bool ShowCrosshair() const;
|
||||
idEntity * DropItem( const idVec3 &velocity, int activateDelay, int removeDelay, bool died );
|
||||
bool CanDrop() const;
|
||||
void WeaponStolen();
|
||||
void ForceAmmoInClip();
|
||||
|
||||
weaponStatus_t GetStatus() { return status; };
|
||||
|
||||
|
||||
// Script state management
|
||||
virtual idThread * ConstructScriptObject();
|
||||
virtual void DeconstructScriptObject();
|
||||
void SetState( const char *statename, int blendFrames );
|
||||
void UpdateScript();
|
||||
void EnterCinematic();
|
||||
void ExitCinematic();
|
||||
void NetCatchup();
|
||||
|
||||
// Visual presentation
|
||||
void PresentWeapon( bool showViewModel );
|
||||
int GetZoomFov();
|
||||
void GetWeaponAngleOffsets( int *average, float *scale, float *max );
|
||||
void GetWeaponTimeOffsets( float *time, float *scale );
|
||||
bool BloodSplat( float size );
|
||||
void SetIsPlayerFlashlight( bool bl ) { isPlayerFlashlight = bl; }
|
||||
void FlashlightOn();
|
||||
void FlashlightOff();
|
||||
|
||||
// Ammo
|
||||
static ammo_t GetAmmoNumForName( const char *ammoname );
|
||||
static const char *GetAmmoNameForNum( ammo_t ammonum );
|
||||
static const char *GetAmmoPickupNameForNum( ammo_t ammonum );
|
||||
ammo_t GetAmmoType() const;
|
||||
int AmmoAvailable() const;
|
||||
int AmmoInClip() const;
|
||||
void ResetAmmoClip();
|
||||
int ClipSize() const;
|
||||
int LowAmmo() const;
|
||||
int AmmoRequired() const;
|
||||
int AmmoCount() const;
|
||||
int GetGrabberState() const;
|
||||
|
||||
// Flashlight
|
||||
idAnimatedEntity * GetWorldModel() { return worldModel.GetEntity(); }
|
||||
|
||||
virtual void WriteToSnapshot( idBitMsg &msg ) const;
|
||||
virtual void ReadFromSnapshot( const idBitMsg &msg );
|
||||
|
||||
enum {
|
||||
EVENT_RELOAD = idEntity::EVENT_MAXEVENTS,
|
||||
EVENT_ENDRELOAD,
|
||||
EVENT_CHANGESKIN,
|
||||
EVENT_MAXEVENTS
|
||||
};
|
||||
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
|
||||
|
||||
virtual void ClientPredictionThink();
|
||||
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
|
||||
void MuzzleFlashLight();
|
||||
void RemoveMuzzleFlashlight();
|
||||
|
||||
// Get a global origin and axis suitable for the laser sight or bullet tracing
|
||||
// Returns false for hands, grenades, and chainsaw.
|
||||
// Can't be const because a frame may need to be created.
|
||||
bool GetMuzzlePositionWithHacks( idVec3 & origin, idMat3 & axis );
|
||||
|
||||
void GetProjectileLaunchOriginAndAxis( idVec3 & origin, idMat3 & axis );
|
||||
|
||||
const idDeclEntityDef * GetDeclEntityDef() { return weaponDef; }
|
||||
|
||||
friend class idPlayer;
|
||||
private:
|
||||
// script control
|
||||
idScriptBool WEAPON_ATTACK;
|
||||
idScriptBool WEAPON_RELOAD;
|
||||
idScriptBool WEAPON_NETRELOAD;
|
||||
idScriptBool WEAPON_NETENDRELOAD;
|
||||
idScriptBool WEAPON_NETFIRING;
|
||||
idScriptBool WEAPON_RAISEWEAPON;
|
||||
idScriptBool WEAPON_LOWERWEAPON;
|
||||
weaponStatus_t status;
|
||||
idThread * thread;
|
||||
idStr state;
|
||||
idStr idealState;
|
||||
int animBlendFrames;
|
||||
int animDoneTime;
|
||||
bool isLinked;
|
||||
bool isPlayerFlashlight;
|
||||
|
||||
// precreated projectile
|
||||
idEntity *projectileEnt;
|
||||
|
||||
idPlayer * owner;
|
||||
idEntityPtr<idAnimatedEntity> worldModel;
|
||||
|
||||
// hiding (for GUIs and NPCs)
|
||||
int hideTime;
|
||||
float hideDistance;
|
||||
int hideStartTime;
|
||||
float hideStart;
|
||||
float hideEnd;
|
||||
float hideOffset;
|
||||
bool hide;
|
||||
bool disabled;
|
||||
|
||||
// berserk
|
||||
int berserk;
|
||||
|
||||
// these are the player render view parms, which include bobbing
|
||||
idVec3 playerViewOrigin;
|
||||
idMat3 playerViewAxis;
|
||||
|
||||
// the view weapon render entity parms
|
||||
idVec3 viewWeaponOrigin;
|
||||
idMat3 viewWeaponAxis;
|
||||
|
||||
// the muzzle bone's position, used for launching projectiles and trailing smoke
|
||||
idVec3 muzzleOrigin;
|
||||
idMat3 muzzleAxis;
|
||||
|
||||
idVec3 pushVelocity;
|
||||
|
||||
// weapon definition
|
||||
// we maintain local copies of the projectile and brass dictionaries so they
|
||||
// do not have to be copied across the DLL boundary when entities are spawned
|
||||
const idDeclEntityDef * weaponDef;
|
||||
const idDeclEntityDef * meleeDef;
|
||||
idDict projectileDict;
|
||||
float meleeDistance;
|
||||
idStr meleeDefName;
|
||||
idDict brassDict;
|
||||
int brassDelay;
|
||||
idStr icon;
|
||||
idStr pdaIcon;
|
||||
idStr displayName;
|
||||
idStr itemDesc;
|
||||
|
||||
// view weapon gui light
|
||||
renderLight_t guiLight;
|
||||
int guiLightHandle;
|
||||
|
||||
// muzzle flash
|
||||
renderLight_t muzzleFlash; // positioned on view weapon bone
|
||||
int muzzleFlashHandle;
|
||||
|
||||
renderLight_t worldMuzzleFlash; // positioned on world weapon bone
|
||||
int worldMuzzleFlashHandle;
|
||||
|
||||
float fraccos;
|
||||
float fraccos2;
|
||||
|
||||
idVec3 flashColor;
|
||||
int muzzleFlashEnd;
|
||||
int flashTime;
|
||||
bool lightOn;
|
||||
bool silent_fire;
|
||||
bool allowDrop;
|
||||
|
||||
// effects
|
||||
bool hasBloodSplat;
|
||||
|
||||
// weapon kick
|
||||
int kick_endtime;
|
||||
int muzzle_kick_time;
|
||||
int muzzle_kick_maxtime;
|
||||
idAngles muzzle_kick_angles;
|
||||
idVec3 muzzle_kick_offset;
|
||||
|
||||
// ammo management
|
||||
ammo_t ammoType;
|
||||
int ammoRequired; // amount of ammo to use each shot. 0 means weapon doesn't need ammo.
|
||||
int clipSize; // 0 means no reload
|
||||
idPredictedValue< int > ammoClip;
|
||||
int lowAmmo; // if ammo in clip hits this threshold, snd_
|
||||
bool powerAmmo; // true if the clip reduction is a factor of the power setting when
|
||||
// a projectile is launched
|
||||
// mp client
|
||||
bool isFiring;
|
||||
|
||||
// zoom
|
||||
int zoomFov; // variable zoom fov per weapon
|
||||
|
||||
// joints from models
|
||||
jointHandle_t barrelJointView;
|
||||
jointHandle_t flashJointView;
|
||||
jointHandle_t ejectJointView;
|
||||
jointHandle_t guiLightJointView;
|
||||
jointHandle_t ventLightJointView;
|
||||
|
||||
jointHandle_t flashJointWorld;
|
||||
jointHandle_t barrelJointWorld;
|
||||
jointHandle_t ejectJointWorld;
|
||||
|
||||
jointHandle_t smokeJointView;
|
||||
|
||||
idHashTable<WeaponParticle_t> weaponParticles;
|
||||
idHashTable<WeaponLight_t> weaponLights;
|
||||
|
||||
// sound
|
||||
const idSoundShader * sndHum;
|
||||
|
||||
// new style muzzle smokes
|
||||
const idDeclParticle * weaponSmoke; // null if it doesn't smoke
|
||||
int weaponSmokeStartTime; // set to gameLocal.time every weapon fire
|
||||
bool continuousSmoke; // if smoke is continuous ( chainsaw )
|
||||
const idDeclParticle * strikeSmoke; // striking something in melee
|
||||
int strikeSmokeStartTime; // timing
|
||||
idVec3 strikePos; // position of last melee strike
|
||||
idMat3 strikeAxis; // axis of last melee strike
|
||||
int nextStrikeFx; // used for sound and decal ( may use for strike smoke too )
|
||||
|
||||
// nozzle effects
|
||||
bool nozzleFx; // does this use nozzle effects ( parm5 at rest, parm6 firing )
|
||||
// this also assumes a nozzle light atm
|
||||
int nozzleFxFade; // time it takes to fade between the effects
|
||||
int lastAttack; // last time an attack occured
|
||||
renderLight_t nozzleGlow; // nozzle light
|
||||
int nozzleGlowHandle; // handle for nozzle light
|
||||
|
||||
idVec3 nozzleGlowColor; // color of the nozzle glow
|
||||
const idMaterial * nozzleGlowShader; // shader for glow light
|
||||
float nozzleGlowRadius; // radius of glow light
|
||||
|
||||
// weighting for viewmodel angles
|
||||
int weaponAngleOffsetAverages;
|
||||
float weaponAngleOffsetScale;
|
||||
float weaponAngleOffsetMax;
|
||||
float weaponOffsetTime;
|
||||
float weaponOffsetScale;
|
||||
|
||||
// flashlight
|
||||
void AlertMonsters();
|
||||
|
||||
// Visual presentation
|
||||
void InitWorldModel( const idDeclEntityDef *def );
|
||||
void MuzzleRise( idVec3 &origin, idMat3 &axis );
|
||||
void UpdateNozzleFx();
|
||||
void UpdateFlashPosition();
|
||||
|
||||
// script events
|
||||
void Event_Clear();
|
||||
void Event_GetOwner();
|
||||
void Event_WeaponState( const char *statename, int blendFrames );
|
||||
void Event_SetWeaponStatus( float newStatus );
|
||||
void Event_WeaponReady();
|
||||
void Event_WeaponOutOfAmmo();
|
||||
void Event_WeaponReloading();
|
||||
void Event_WeaponHolstered();
|
||||
void Event_WeaponRising();
|
||||
void Event_WeaponLowering();
|
||||
void Event_UseAmmo( int amount );
|
||||
void Event_AddToClip( int amount );
|
||||
void Event_AmmoInClip();
|
||||
void Event_AmmoAvailable();
|
||||
void Event_TotalAmmoCount();
|
||||
void Event_ClipSize();
|
||||
void Event_PlayAnim( int channel, const char *animname );
|
||||
void Event_PlayCycle( int channel, const char *animname );
|
||||
void Event_AnimDone( int channel, int blendFrames );
|
||||
void Event_SetBlendFrames( int channel, int blendFrames );
|
||||
void Event_GetBlendFrames( int channel );
|
||||
void Event_Next();
|
||||
void Event_SetSkin( const char *skinname );
|
||||
void Event_Flashlight( int enable );
|
||||
void Event_GetLightParm( int parmnum );
|
||||
void Event_SetLightParm( int parmnum, float value );
|
||||
void Event_SetLightParms( float parm0, float parm1, float parm2, float parm3 );
|
||||
void Event_LaunchProjectiles( int num_projectiles, float spread, float fuseOffset, float launchPower, float dmgPower );
|
||||
void Event_CreateProjectile();
|
||||
void Event_EjectBrass();
|
||||
void Event_Melee();
|
||||
void Event_GetWorldModel();
|
||||
void Event_AllowDrop( int allow );
|
||||
void Event_AutoReload();
|
||||
void Event_NetReload();
|
||||
void Event_IsInvisible();
|
||||
void Event_NetEndReload();
|
||||
|
||||
idGrabber grabber;
|
||||
int grabberState;
|
||||
|
||||
void Event_Grabber( int enable );
|
||||
void Event_GrabberHasTarget();
|
||||
void Event_GrabberSetGrabDistance( float dist );
|
||||
void Event_LaunchProjectilesEllipse( int num_projectiles, float spreada, float spreadb, float fuseOffset, float power );
|
||||
void Event_LaunchPowerup( const char* powerup, float duration, int useAmmo );
|
||||
|
||||
void Event_StartWeaponSmoke();
|
||||
void Event_StopWeaponSmoke();
|
||||
|
||||
void Event_StartWeaponParticle( const char* name);
|
||||
void Event_StopWeaponParticle( const char* name);
|
||||
|
||||
void Event_StartWeaponLight( const char* name);
|
||||
void Event_StopWeaponLight( const char* name);
|
||||
};
|
||||
|
||||
ID_INLINE bool idWeapon::IsLinked() {
|
||||
return isLinked;
|
||||
}
|
||||
|
||||
ID_INLINE bool idWeapon::IsWorldModelReady() {
|
||||
return ( worldModel.GetEntity() != NULL );
|
||||
}
|
||||
|
||||
ID_INLINE idPlayer* idWeapon::GetOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
#endif /* !__GAME_WEAPON_H__ */
|
||||
143
neo/d3xp/WorldSpawn.cpp
Normal file
143
neo/d3xp/WorldSpawn.cpp
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
/*
|
||||
game_worldspawn.cpp
|
||||
|
||||
Worldspawn class. Each map has one worldspawn which handles global spawnargs.
|
||||
|
||||
*/
|
||||
|
||||
#include "../idlib/precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Game_local.h"
|
||||
|
||||
/*
|
||||
================
|
||||
idWorldspawn
|
||||
|
||||
Every map should have exactly one worldspawn.
|
||||
================
|
||||
*/
|
||||
CLASS_DECLARATION( idEntity, idWorldspawn )
|
||||
EVENT( EV_Remove, idWorldspawn::Event_Remove )
|
||||
EVENT( EV_SafeRemove, idWorldspawn::Event_Remove )
|
||||
END_CLASS
|
||||
|
||||
/*
|
||||
================
|
||||
idWorldspawn::Spawn
|
||||
================
|
||||
*/
|
||||
void idWorldspawn::Spawn() {
|
||||
idStr scriptname;
|
||||
idThread *thread;
|
||||
const function_t *func;
|
||||
const idKeyValue *kv;
|
||||
|
||||
assert( gameLocal.world == NULL );
|
||||
gameLocal.world = this;
|
||||
|
||||
g_gravity.SetFloat( spawnArgs.GetFloat( "gravity", va( "%f", DEFAULT_GRAVITY ) ) );
|
||||
|
||||
// disable stamina on hell levels
|
||||
if ( spawnArgs.GetBool( "no_stamina" ) ) {
|
||||
pm_stamina.SetFloat( 0.0f );
|
||||
}
|
||||
|
||||
// load script
|
||||
scriptname = gameLocal.GetMapName();
|
||||
scriptname.SetFileExtension( ".script" );
|
||||
if ( fileSystem->ReadFile( scriptname, NULL, NULL ) > 0 ) {
|
||||
gameLocal.program.CompileFile( scriptname );
|
||||
|
||||
// call the main function by default
|
||||
func = gameLocal.program.FindFunction( "main" );
|
||||
if ( func != NULL ) {
|
||||
thread = new idThread( func );
|
||||
thread->DelayedStart( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
// call any functions specified in worldspawn
|
||||
kv = spawnArgs.MatchPrefix( "call" );
|
||||
while( kv != NULL ) {
|
||||
func = gameLocal.program.FindFunction( kv->GetValue() );
|
||||
if ( func == NULL ) {
|
||||
gameLocal.Error( "Function '%s' not found in script for '%s' key on worldspawn", kv->GetValue().c_str(), kv->GetKey().c_str() );
|
||||
}
|
||||
|
||||
thread = new idThread( func );
|
||||
thread->DelayedStart( 0 );
|
||||
kv = spawnArgs.MatchPrefix( "call", kv );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
idWorldspawn::Save
|
||||
=================
|
||||
*/
|
||||
void idWorldspawn::Save( idSaveGame *savefile ) {
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
idWorldspawn::Restore
|
||||
=================
|
||||
*/
|
||||
void idWorldspawn::Restore( idRestoreGame *savefile ) {
|
||||
assert( gameLocal.world == this );
|
||||
|
||||
g_gravity.SetFloat( spawnArgs.GetFloat( "gravity", va( "%f", DEFAULT_GRAVITY ) ) );
|
||||
|
||||
// disable stamina on hell levels
|
||||
if ( spawnArgs.GetBool( "no_stamina" ) ) {
|
||||
pm_stamina.SetFloat( 0.0f );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idWorldspawn::~idWorldspawn
|
||||
================
|
||||
*/
|
||||
idWorldspawn::~idWorldspawn() {
|
||||
if ( gameLocal.world == this ) {
|
||||
gameLocal.world = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idWorldspawn::Event_Remove
|
||||
================
|
||||
*/
|
||||
void idWorldspawn::Event_Remove() {
|
||||
gameLocal.Error( "Tried to remove world" );
|
||||
}
|
||||
55
neo/d3xp/WorldSpawn.h
Normal file
55
neo/d3xp/WorldSpawn.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_WORLDSPAWN_H__
|
||||
#define __GAME_WORLDSPAWN_H__
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
World entity.
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class idWorldspawn : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idWorldspawn );
|
||||
|
||||
~idWorldspawn();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame *savefile );
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
private:
|
||||
void Event_Remove();
|
||||
};
|
||||
|
||||
#endif /* !__GAME_WORLDSPAWN_H__ */
|
||||
276
neo/d3xp/ai/AAS.cpp
Normal file
276
neo/d3xp/ai/AAS.cpp
Normal file
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma hdrstop
|
||||
#include "../../idlib/precompiled.h"
|
||||
|
||||
|
||||
#include "AAS_local.h"
|
||||
|
||||
/*
|
||||
============
|
||||
idAAS::Alloc
|
||||
============
|
||||
*/
|
||||
idAAS *idAAS::Alloc() {
|
||||
return new (TAG_AAS) idAASLocal;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAAS::idAAS
|
||||
============
|
||||
*/
|
||||
idAAS::~idAAS() {
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::idAASLocal
|
||||
============
|
||||
*/
|
||||
idAASLocal::idAASLocal() {
|
||||
file = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::~idAASLocal
|
||||
============
|
||||
*/
|
||||
idAASLocal::~idAASLocal() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::Init
|
||||
============
|
||||
*/
|
||||
bool idAASLocal::Init( const idStr &mapName, unsigned int mapFileCRC ) {
|
||||
if ( file && mapName.Icmp( file->GetName() ) == 0 && mapFileCRC == file->GetCRC() ) {
|
||||
common->Printf( "Keeping %s\n", file->GetName() );
|
||||
RemoveAllObstacles();
|
||||
}
|
||||
else {
|
||||
Shutdown();
|
||||
|
||||
file = AASFileManager->LoadAAS( mapName, mapFileCRC );
|
||||
if ( !file ) {
|
||||
common->DWarning( "Couldn't load AAS file: '%s'", mapName.c_str() );
|
||||
return false;
|
||||
}
|
||||
SetupRouting();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::Shutdown
|
||||
============
|
||||
*/
|
||||
void idAASLocal::Shutdown() {
|
||||
if ( file ) {
|
||||
ShutdownRouting();
|
||||
RemoveAllObstacles();
|
||||
AASFileManager->FreeAAS( file );
|
||||
file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::Stats
|
||||
============
|
||||
*/
|
||||
void idAASLocal::Stats() const {
|
||||
if ( !file ) {
|
||||
return;
|
||||
}
|
||||
common->Printf( "[%s]\n", file->GetName() );
|
||||
file->PrintInfo();
|
||||
RoutingStats();
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::GetSettings
|
||||
============
|
||||
*/
|
||||
const idAASSettings *idAASLocal::GetSettings() const {
|
||||
if ( !file ) {
|
||||
return NULL;
|
||||
}
|
||||
return &file->GetSettings();
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::PointAreaNum
|
||||
============
|
||||
*/
|
||||
int idAASLocal::PointAreaNum( const idVec3 &origin ) const {
|
||||
if ( !file ) {
|
||||
return 0;
|
||||
}
|
||||
return file->PointAreaNum( origin );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::PointReachableAreaNum
|
||||
============
|
||||
*/
|
||||
int idAASLocal::PointReachableAreaNum( const idVec3 &origin, const idBounds &searchBounds, const int areaFlags ) const {
|
||||
if ( !file ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return file->PointReachableAreaNum( origin, searchBounds, areaFlags, TFL_INVALID );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::BoundsReachableAreaNum
|
||||
============
|
||||
*/
|
||||
int idAASLocal::BoundsReachableAreaNum( const idBounds &bounds, const int areaFlags ) const {
|
||||
if ( !file ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return file->BoundsReachableAreaNum( bounds, areaFlags, TFL_INVALID );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::PushPointIntoAreaNum
|
||||
============
|
||||
*/
|
||||
void idAASLocal::PushPointIntoAreaNum( int areaNum, idVec3 &origin ) const {
|
||||
if ( !file ) {
|
||||
return;
|
||||
}
|
||||
file->PushPointIntoAreaNum( areaNum, origin );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::AreaCenter
|
||||
============
|
||||
*/
|
||||
idVec3 idAASLocal::AreaCenter( int areaNum ) const {
|
||||
if ( !file ) {
|
||||
return vec3_origin;
|
||||
}
|
||||
return file->GetArea( areaNum ).center;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::AreaFlags
|
||||
============
|
||||
*/
|
||||
int idAASLocal::AreaFlags( int areaNum ) const {
|
||||
if ( !file ) {
|
||||
return 0;
|
||||
}
|
||||
return file->GetArea( areaNum ).flags;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::AreaTravelFlags
|
||||
============
|
||||
*/
|
||||
int idAASLocal::AreaTravelFlags( int areaNum ) const {
|
||||
if ( !file ) {
|
||||
return 0;
|
||||
}
|
||||
return file->GetArea( areaNum ).travelFlags;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::Trace
|
||||
============
|
||||
*/
|
||||
bool idAASLocal::Trace( aasTrace_t &trace, const idVec3 &start, const idVec3 &end ) const {
|
||||
if ( !file ) {
|
||||
trace.fraction = 0.0f;
|
||||
trace.lastAreaNum = 0;
|
||||
trace.numAreas = 0;
|
||||
return true;
|
||||
}
|
||||
return file->Trace( trace, start, end );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::GetPlane
|
||||
============
|
||||
*/
|
||||
const idPlane &idAASLocal::GetPlane( int planeNum ) const {
|
||||
if ( !file ) {
|
||||
static idPlane dummy;
|
||||
return dummy;
|
||||
}
|
||||
return file->GetPlane( planeNum );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::GetEdgeVertexNumbers
|
||||
============
|
||||
*/
|
||||
void idAASLocal::GetEdgeVertexNumbers( int edgeNum, int verts[2] ) const {
|
||||
if ( !file ) {
|
||||
verts[0] = verts[1] = 0;
|
||||
return;
|
||||
}
|
||||
const int *v = file->GetEdge( abs(edgeNum) ).vertexNum;
|
||||
verts[0] = v[INT32_SIGNBITSET(edgeNum)];
|
||||
verts[1] = v[INT32_SIGNBITNOTSET(edgeNum)];
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::GetEdge
|
||||
============
|
||||
*/
|
||||
void idAASLocal::GetEdge( int edgeNum, idVec3 &start, idVec3 &end ) const {
|
||||
if ( !file ) {
|
||||
start.Zero();
|
||||
end.Zero();
|
||||
return;
|
||||
}
|
||||
const int *v = file->GetEdge( abs(edgeNum) ).vertexNum;
|
||||
start = file->GetVertex( v[INT32_SIGNBITSET(edgeNum)] );
|
||||
end = file->GetVertex( v[INT32_SIGNBITNOTSET(edgeNum)] );
|
||||
}
|
||||
141
neo/d3xp/ai/AAS.h
Normal file
141
neo/d3xp/ai/AAS.h
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __AAS_H__
|
||||
#define __AAS_H__
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Area Awareness System
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
enum {
|
||||
PATHTYPE_WALK,
|
||||
PATHTYPE_WALKOFFLEDGE,
|
||||
PATHTYPE_BARRIERJUMP,
|
||||
PATHTYPE_JUMP
|
||||
};
|
||||
|
||||
typedef struct aasPath_s {
|
||||
int type; // path type
|
||||
idVec3 moveGoal; // point the AI should move towards
|
||||
int moveAreaNum; // number of the area the AI should move towards
|
||||
idVec3 secondaryGoal; // secondary move goal for complex navigation
|
||||
const idReachability * reachability; // reachability used for navigation
|
||||
} aasPath_t;
|
||||
|
||||
|
||||
typedef struct aasGoal_s {
|
||||
int areaNum; // area the goal is in
|
||||
idVec3 origin; // position of goal
|
||||
} aasGoal_t;
|
||||
|
||||
|
||||
typedef struct aasObstacle_s {
|
||||
idBounds absBounds; // absolute bounds of obstacle
|
||||
idBounds expAbsBounds; // expanded absolute bounds of obstacle
|
||||
} aasObstacle_t;
|
||||
|
||||
class idAASCallback {
|
||||
public:
|
||||
virtual ~idAASCallback() {};
|
||||
virtual bool TestArea( const class idAAS *aas, int areaNum ) = 0;
|
||||
};
|
||||
|
||||
typedef int aasHandle_t;
|
||||
|
||||
class idAAS {
|
||||
public:
|
||||
static idAAS * Alloc();
|
||||
virtual ~idAAS() = 0;
|
||||
// Initialize for the given map.
|
||||
virtual bool Init( const idStr &mapName, unsigned int mapFileCRC ) = 0;
|
||||
// Print AAS stats.
|
||||
virtual void Stats() const = 0;
|
||||
// Test from the given origin.
|
||||
virtual void Test( const idVec3 &origin ) = 0;
|
||||
// Get the AAS settings.
|
||||
virtual const idAASSettings *GetSettings() const = 0;
|
||||
// Returns the number of the area the origin is in.
|
||||
virtual int PointAreaNum( const idVec3 &origin ) const = 0;
|
||||
// Returns the number of the nearest reachable area for the given point.
|
||||
virtual int PointReachableAreaNum( const idVec3 &origin, const idBounds &bounds, const int areaFlags ) const = 0;
|
||||
// Returns the number of the first reachable area in or touching the bounds.
|
||||
virtual int BoundsReachableAreaNum( const idBounds &bounds, const int areaFlags ) const = 0;
|
||||
// Push the point into the area.
|
||||
virtual void PushPointIntoAreaNum( int areaNum, idVec3 &origin ) const = 0;
|
||||
// Returns a reachable point inside the given area.
|
||||
virtual idVec3 AreaCenter( int areaNum ) const = 0;
|
||||
// Returns the area flags.
|
||||
virtual int AreaFlags( int areaNum ) const = 0;
|
||||
// Returns the travel flags for traveling through the area.
|
||||
virtual int AreaTravelFlags( int areaNum ) const = 0;
|
||||
// Trace through the areas and report the first collision.
|
||||
virtual bool Trace( aasTrace_t &trace, const idVec3 &start, const idVec3 &end ) const = 0;
|
||||
// Get a plane for a trace.
|
||||
virtual const idPlane & GetPlane( int planeNum ) const = 0;
|
||||
// Get wall edges.
|
||||
virtual int GetWallEdges( int areaNum, const idBounds &bounds, int travelFlags, int *edges, int maxEdges ) const = 0;
|
||||
// Sort the wall edges to create continuous sequences of walls.
|
||||
virtual void SortWallEdges( int *edges, int numEdges ) const = 0;
|
||||
// Get the vertex numbers for an edge.
|
||||
virtual void GetEdgeVertexNumbers( int edgeNum, int verts[2] ) const = 0;
|
||||
// Get an edge.
|
||||
virtual void GetEdge( int edgeNum, idVec3 &start, idVec3 &end ) const = 0;
|
||||
// Find all areas within or touching the bounds with the given contents and disable/enable them for routing.
|
||||
virtual bool SetAreaState( const idBounds &bounds, const int areaContents, bool disabled ) = 0;
|
||||
// Add an obstacle to the routing system.
|
||||
virtual aasHandle_t AddObstacle( const idBounds &bounds ) = 0;
|
||||
// Remove an obstacle from the routing system.
|
||||
virtual void RemoveObstacle( const aasHandle_t handle ) = 0;
|
||||
// Remove all obstacles from the routing system.
|
||||
virtual void RemoveAllObstacles() = 0;
|
||||
// Returns the travel time towards the goal area in 100th of a second.
|
||||
virtual int TravelTimeToGoalArea( int areaNum, const idVec3 &origin, int goalAreaNum, int travelFlags ) const = 0;
|
||||
// Get the travel time and first reachability to be used towards the goal, returns true if there is a path.
|
||||
virtual bool RouteToGoalArea( int areaNum, const idVec3 origin, int goalAreaNum, int travelFlags, int &travelTime, idReachability **reach ) const = 0;
|
||||
// Creates a walk path towards the goal.
|
||||
virtual bool WalkPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags ) const = 0;
|
||||
// Returns true if one can walk along a straight line from the origin to the goal origin.
|
||||
virtual bool WalkPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum ) const = 0;
|
||||
// Creates a fly path towards the goal.
|
||||
virtual bool FlyPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags ) const = 0;
|
||||
// Returns true if one can fly along a straight line from the origin to the goal origin.
|
||||
virtual bool FlyPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum ) const = 0;
|
||||
// Show the walk path from the origin towards the area.
|
||||
virtual void ShowWalkPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const = 0;
|
||||
// Show the fly path from the origin towards the area.
|
||||
virtual void ShowFlyPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const = 0;
|
||||
// Find the nearest goal which satisfies the callback.
|
||||
virtual bool FindNearestGoal( aasGoal_t &goal, int areaNum, const idVec3 origin, const idVec3 &target, int travelFlags, aasObstacle_t *obstacles, int numObstacles, idAASCallback &callback ) const = 0;
|
||||
};
|
||||
|
||||
#endif /* !__AAS_H__ */
|
||||
508
neo/d3xp/ai/AAS_debug.cpp
Normal file
508
neo/d3xp/ai/AAS_debug.cpp
Normal file
@@ -0,0 +1,508 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma hdrstop
|
||||
#include "../../idlib/precompiled.h"
|
||||
|
||||
#include "AAS_local.h"
|
||||
#include "../Game_local.h" // for cvars and debug drawing
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::DrawCone
|
||||
============
|
||||
*/
|
||||
void idAASLocal::DrawCone( const idVec3 &origin, const idVec3 &dir, float radius, const idVec4 &color ) const {
|
||||
int i;
|
||||
idMat3 axis;
|
||||
idVec3 center, top, p, lastp;
|
||||
|
||||
axis[2] = dir;
|
||||
axis[2].NormalVectors( axis[0], axis[1] );
|
||||
axis[1] = -axis[1];
|
||||
|
||||
center = origin + dir;
|
||||
top = center + dir * (3.0f * radius);
|
||||
lastp = center + radius * axis[1];
|
||||
|
||||
for ( i = 20; i <= 360; i += 20 ) {
|
||||
p = center + sin( DEG2RAD(i) ) * radius * axis[0] + cos( DEG2RAD(i) ) * radius * axis[1];
|
||||
gameRenderWorld->DebugLine( color, lastp, p, 0 );
|
||||
gameRenderWorld->DebugLine( color, p, top, 0 );
|
||||
lastp = p;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::DrawReachability
|
||||
============
|
||||
*/
|
||||
void idAASLocal::DrawReachability( const idReachability *reach ) const {
|
||||
gameRenderWorld->DebugArrow( colorCyan, reach->start, reach->end, 2 );
|
||||
|
||||
if ( gameLocal.GetLocalPlayer() ) {
|
||||
gameRenderWorld->DrawText( va( "%d", reach->edgeNum ), ( reach->start + reach->end ) * 0.5f, 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAxis );
|
||||
}
|
||||
|
||||
switch( reach->travelType ) {
|
||||
case TFL_WALK: {
|
||||
//const idReachability_Walk *walk = static_cast<const idReachability_Walk *>(reach);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::DrawEdge
|
||||
============
|
||||
*/
|
||||
void idAASLocal::DrawEdge( int edgeNum, bool arrow ) const {
|
||||
const aasEdge_t *edge;
|
||||
idVec4 *color;
|
||||
|
||||
if ( !file ) {
|
||||
return;
|
||||
}
|
||||
|
||||
edge = &file->GetEdge( edgeNum );
|
||||
color = &colorRed;
|
||||
if ( arrow ) {
|
||||
gameRenderWorld->DebugArrow( *color, file->GetVertex( edge->vertexNum[0] ), file->GetVertex( edge->vertexNum[1] ), 1 );
|
||||
} else {
|
||||
gameRenderWorld->DebugLine( *color, file->GetVertex( edge->vertexNum[0] ), file->GetVertex( edge->vertexNum[1] ) );
|
||||
}
|
||||
|
||||
if ( gameLocal.GetLocalPlayer() ) {
|
||||
gameRenderWorld->DrawText( va( "%d", edgeNum ), ( file->GetVertex( edge->vertexNum[0] ) + file->GetVertex( edge->vertexNum[1] ) ) * 0.5f + idVec3(0,0,4), 0.1f, colorRed, gameLocal.GetLocalPlayer()->viewAxis );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::DrawFace
|
||||
============
|
||||
*/
|
||||
void idAASLocal::DrawFace( int faceNum, bool side ) const {
|
||||
int i, j, numEdges, firstEdge;
|
||||
const aasFace_t *face;
|
||||
idVec3 mid, end;
|
||||
|
||||
if ( !file ) {
|
||||
return;
|
||||
}
|
||||
|
||||
face = &file->GetFace( faceNum );
|
||||
numEdges = face->numEdges;
|
||||
firstEdge = face->firstEdge;
|
||||
|
||||
mid = vec3_origin;
|
||||
for ( i = 0; i < numEdges; i++ ) {
|
||||
DrawEdge( abs( file->GetEdgeIndex( firstEdge + i ) ), ( face->flags & FACE_FLOOR ) != 0 );
|
||||
j = file->GetEdgeIndex( firstEdge + i );
|
||||
mid += file->GetVertex( file->GetEdge( abs( j ) ).vertexNum[ j < 0 ] );
|
||||
}
|
||||
|
||||
mid /= numEdges;
|
||||
if ( side ) {
|
||||
end = mid - 5.0f * file->GetPlane( file->GetFace( faceNum ).planeNum ).Normal();
|
||||
} else {
|
||||
end = mid + 5.0f * file->GetPlane( file->GetFace( faceNum ).planeNum ).Normal();
|
||||
}
|
||||
gameRenderWorld->DebugArrow( colorGreen, mid, end, 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::DrawArea
|
||||
============
|
||||
*/
|
||||
void idAASLocal::DrawArea( int areaNum ) const {
|
||||
int i, numFaces, firstFace;
|
||||
const aasArea_t *area;
|
||||
idReachability *reach;
|
||||
|
||||
if ( !file ) {
|
||||
return;
|
||||
}
|
||||
|
||||
area = &file->GetArea( areaNum );
|
||||
numFaces = area->numFaces;
|
||||
firstFace = area->firstFace;
|
||||
|
||||
for ( i = 0; i < numFaces; i++ ) {
|
||||
DrawFace( abs( file->GetFaceIndex( firstFace + i ) ), file->GetFaceIndex( firstFace + i ) < 0 );
|
||||
}
|
||||
|
||||
for ( reach = area->reach; reach; reach = reach->next ) {
|
||||
DrawReachability( reach );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::DefaultSearchBounds
|
||||
============
|
||||
*/
|
||||
const idBounds &idAASLocal::DefaultSearchBounds() const {
|
||||
return file->GetSettings().boundingBoxes[0];
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::ShowArea
|
||||
============
|
||||
*/
|
||||
void idAASLocal::ShowArea( const idVec3 &origin ) const {
|
||||
static int lastAreaNum;
|
||||
int areaNum;
|
||||
const aasArea_t *area;
|
||||
idVec3 org;
|
||||
|
||||
areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) );
|
||||
org = origin;
|
||||
PushPointIntoAreaNum( areaNum, org );
|
||||
|
||||
if ( aas_goalArea.GetInteger() ) {
|
||||
int travelTime;
|
||||
idReachability *reach;
|
||||
|
||||
RouteToGoalArea( areaNum, org, aas_goalArea.GetInteger(), TFL_WALK|TFL_AIR, travelTime, &reach );
|
||||
gameLocal.Printf( "\rtt = %4d", travelTime );
|
||||
if ( reach ) {
|
||||
gameLocal.Printf( " to area %4d", reach->toAreaNum );
|
||||
DrawArea( reach->toAreaNum );
|
||||
}
|
||||
}
|
||||
|
||||
if ( areaNum != lastAreaNum ) {
|
||||
area = &file->GetArea( areaNum );
|
||||
gameLocal.Printf( "area %d: ", areaNum );
|
||||
if ( area->flags & AREA_LEDGE ) {
|
||||
gameLocal.Printf( "AREA_LEDGE " );
|
||||
}
|
||||
if ( area->flags & AREA_REACHABLE_WALK ) {
|
||||
gameLocal.Printf( "AREA_REACHABLE_WALK " );
|
||||
}
|
||||
if ( area->flags & AREA_REACHABLE_FLY ) {
|
||||
gameLocal.Printf( "AREA_REACHABLE_FLY " );
|
||||
}
|
||||
if ( area->contents & AREACONTENTS_CLUSTERPORTAL ) {
|
||||
gameLocal.Printf( "AREACONTENTS_CLUSTERPORTAL " );
|
||||
}
|
||||
if ( area->contents & AREACONTENTS_OBSTACLE ) {
|
||||
gameLocal.Printf( "AREACONTENTS_OBSTACLE " );
|
||||
}
|
||||
gameLocal.Printf( "\n" );
|
||||
lastAreaNum = areaNum;
|
||||
}
|
||||
|
||||
if ( org != origin ) {
|
||||
idBounds bnds = file->GetSettings().boundingBoxes[ 0 ];
|
||||
bnds[ 1 ].z = bnds[ 0 ].z;
|
||||
gameRenderWorld->DebugBounds( colorYellow, bnds, org );
|
||||
}
|
||||
|
||||
DrawArea( areaNum );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::ShowWalkPath
|
||||
============
|
||||
*/
|
||||
void idAASLocal::ShowWalkPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const {
|
||||
int i, areaNum, curAreaNum, travelTime;
|
||||
idReachability *reach;
|
||||
idVec3 org, areaCenter;
|
||||
aasPath_t path;
|
||||
|
||||
if ( !file ) {
|
||||
return;
|
||||
}
|
||||
|
||||
org = origin;
|
||||
areaNum = PointReachableAreaNum( org, DefaultSearchBounds(), AREA_REACHABLE_WALK );
|
||||
PushPointIntoAreaNum( areaNum, org );
|
||||
curAreaNum = areaNum;
|
||||
|
||||
for ( i = 0; i < 100; i++ ) {
|
||||
|
||||
if ( !RouteToGoalArea( curAreaNum, org, goalAreaNum, TFL_WALK|TFL_AIR, travelTime, &reach ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !reach ) {
|
||||
break;
|
||||
}
|
||||
|
||||
gameRenderWorld->DebugArrow( colorGreen, org, reach->start, 2 );
|
||||
DrawReachability( reach );
|
||||
|
||||
if ( reach->toAreaNum == goalAreaNum ) {
|
||||
break;
|
||||
}
|
||||
|
||||
curAreaNum = reach->toAreaNum;
|
||||
org = reach->end;
|
||||
}
|
||||
|
||||
if ( WalkPathToGoal( path, areaNum, origin, goalAreaNum, goalOrigin, TFL_WALK|TFL_AIR ) ) {
|
||||
gameRenderWorld->DebugArrow( colorBlue, origin, path.moveGoal, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::ShowFlyPath
|
||||
============
|
||||
*/
|
||||
void idAASLocal::ShowFlyPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const {
|
||||
int i, areaNum, curAreaNum, travelTime;
|
||||
idReachability *reach;
|
||||
idVec3 org, areaCenter;
|
||||
aasPath_t path;
|
||||
|
||||
if ( !file ) {
|
||||
return;
|
||||
}
|
||||
|
||||
org = origin;
|
||||
areaNum = PointReachableAreaNum( org, DefaultSearchBounds(), AREA_REACHABLE_FLY );
|
||||
PushPointIntoAreaNum( areaNum, org );
|
||||
curAreaNum = areaNum;
|
||||
|
||||
for ( i = 0; i < 100; i++ ) {
|
||||
|
||||
if ( !RouteToGoalArea( curAreaNum, org, goalAreaNum, TFL_WALK|TFL_FLY|TFL_AIR, travelTime, &reach ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !reach ) {
|
||||
break;
|
||||
}
|
||||
|
||||
gameRenderWorld->DebugArrow( colorPurple, org, reach->start, 2 );
|
||||
DrawReachability( reach );
|
||||
|
||||
if ( reach->toAreaNum == goalAreaNum ) {
|
||||
break;
|
||||
}
|
||||
|
||||
curAreaNum = reach->toAreaNum;
|
||||
org = reach->end;
|
||||
}
|
||||
|
||||
if ( FlyPathToGoal( path, areaNum, origin, goalAreaNum, goalOrigin, TFL_WALK|TFL_FLY|TFL_AIR ) ) {
|
||||
gameRenderWorld->DebugArrow( colorBlue, origin, path.moveGoal, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::ShowWallEdges
|
||||
============
|
||||
*/
|
||||
void idAASLocal::ShowWallEdges( const idVec3 &origin ) const {
|
||||
int i, areaNum, numEdges, edges[1024];
|
||||
idVec3 start, end;
|
||||
idPlayer *player;
|
||||
|
||||
player = gameLocal.GetLocalPlayer();
|
||||
if ( !player ) {
|
||||
return;
|
||||
}
|
||||
|
||||
areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) );
|
||||
numEdges = GetWallEdges( areaNum, idBounds( origin ).Expand( 256.0f ), TFL_WALK, edges, 1024 );
|
||||
for ( i = 0; i < numEdges; i++ ) {
|
||||
GetEdge( edges[i], start, end );
|
||||
gameRenderWorld->DebugLine( colorRed, start, end );
|
||||
gameRenderWorld->DrawText( va( "%d", edges[i] ), ( start + end ) * 0.5f, 0.1f, colorWhite, player->viewAxis );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::ShowHideArea
|
||||
============
|
||||
*/
|
||||
void idAASLocal::ShowHideArea( const idVec3 &origin, int targetAreaNum ) const {
|
||||
int areaNum, numObstacles;
|
||||
idVec3 target;
|
||||
aasGoal_t goal;
|
||||
aasObstacle_t obstacles[10];
|
||||
|
||||
areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) );
|
||||
target = AreaCenter( targetAreaNum );
|
||||
|
||||
// consider the target an obstacle
|
||||
obstacles[0].absBounds = idBounds( target ).Expand( 16 );
|
||||
numObstacles = 1;
|
||||
|
||||
DrawCone( target, idVec3(0,0,1), 16.0f, colorYellow );
|
||||
|
||||
idAASFindCover findCover( target );
|
||||
if ( FindNearestGoal( goal, areaNum, origin, target, TFL_WALK|TFL_AIR, obstacles, numObstacles, findCover ) ) {
|
||||
DrawArea( goal.areaNum );
|
||||
ShowWalkPath( origin, goal.areaNum, goal.origin );
|
||||
DrawCone( goal.origin, idVec3(0,0,1), 16.0f, colorWhite );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::PullPlayer
|
||||
============
|
||||
*/
|
||||
bool idAASLocal::PullPlayer( const idVec3 &origin, int toAreaNum ) const {
|
||||
int areaNum;
|
||||
idVec3 areaCenter, dir, vel;
|
||||
idAngles delta;
|
||||
aasPath_t path;
|
||||
idPlayer *player;
|
||||
|
||||
player = gameLocal.GetLocalPlayer();
|
||||
if ( !player ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
idPhysics *physics = player->GetPhysics();
|
||||
if ( !physics ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( !toAreaNum ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) );
|
||||
areaCenter = AreaCenter( toAreaNum );
|
||||
if ( player->GetPhysics()->GetAbsBounds().Expand( 8 ).ContainsPoint( areaCenter ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( WalkPathToGoal( path, areaNum, origin, toAreaNum, areaCenter, TFL_WALK|TFL_AIR ) ) {
|
||||
dir = path.moveGoal - origin;
|
||||
dir[2] *= 0.5f;
|
||||
dir.Normalize();
|
||||
delta = dir.ToAngles() - player->cmdAngles - player->GetDeltaViewAngles();
|
||||
delta.Normalize180();
|
||||
player->SetDeltaViewAngles( player->GetDeltaViewAngles() + delta * 0.1f );
|
||||
dir[2] = 0.0f;
|
||||
dir.Normalize();
|
||||
dir *= 100.0f;
|
||||
vel = physics->GetLinearVelocity();
|
||||
dir[2] = vel[2];
|
||||
physics->SetLinearVelocity( dir );
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::RandomPullPlayer
|
||||
============
|
||||
*/
|
||||
void idAASLocal::RandomPullPlayer( const idVec3 &origin ) const {
|
||||
int rnd, i, n;
|
||||
|
||||
if ( !PullPlayer( origin, aas_pullPlayer.GetInteger() ) ) {
|
||||
|
||||
rnd = gameLocal.random.RandomFloat() * file->GetNumAreas();
|
||||
|
||||
for ( i = 0; i < file->GetNumAreas(); i++ ) {
|
||||
n = (rnd + i) % file->GetNumAreas();
|
||||
if ( file->GetArea( n ).flags & (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ) {
|
||||
aas_pullPlayer.SetInteger( n );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ShowWalkPath( origin, aas_pullPlayer.GetInteger(), AreaCenter( aas_pullPlayer.GetInteger() ) );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::ShowPushIntoArea
|
||||
============
|
||||
*/
|
||||
void idAASLocal::ShowPushIntoArea( const idVec3 &origin ) const {
|
||||
int areaNum;
|
||||
idVec3 target;
|
||||
|
||||
target = origin;
|
||||
areaNum = PointReachableAreaNum( target, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) );
|
||||
PushPointIntoAreaNum( areaNum, target );
|
||||
gameRenderWorld->DebugArrow( colorGreen, origin, target, 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::Test
|
||||
============
|
||||
*/
|
||||
void idAASLocal::Test( const idVec3 &origin ) {
|
||||
|
||||
if ( !file ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( aas_randomPullPlayer.GetBool() ) {
|
||||
RandomPullPlayer( origin );
|
||||
}
|
||||
if ( ( aas_pullPlayer.GetInteger() > 0 ) && ( aas_pullPlayer.GetInteger() < file->GetNumAreas() ) ) {
|
||||
ShowWalkPath( origin, aas_pullPlayer.GetInteger(), AreaCenter( aas_pullPlayer.GetInteger() ) );
|
||||
PullPlayer( origin, aas_pullPlayer.GetInteger() );
|
||||
}
|
||||
if ( ( aas_showPath.GetInteger() > 0 ) && ( aas_showPath.GetInteger() < file->GetNumAreas() ) ) {
|
||||
ShowWalkPath( origin, aas_showPath.GetInteger(), AreaCenter( aas_showPath.GetInteger() ) );
|
||||
}
|
||||
if ( ( aas_showFlyPath.GetInteger() > 0 ) && ( aas_showFlyPath.GetInteger() < file->GetNumAreas() ) ) {
|
||||
ShowFlyPath( origin, aas_showFlyPath.GetInteger(), AreaCenter( aas_showFlyPath.GetInteger() ) );
|
||||
}
|
||||
if ( ( aas_showHideArea.GetInteger() > 0 ) && ( aas_showHideArea.GetInteger() < file->GetNumAreas() ) ) {
|
||||
ShowHideArea( origin, aas_showHideArea.GetInteger() );
|
||||
}
|
||||
if ( aas_showAreas.GetBool() ) {
|
||||
ShowArea( origin );
|
||||
}
|
||||
if ( aas_showWallEdges.GetBool() ) {
|
||||
ShowWallEdges( origin );
|
||||
}
|
||||
if ( aas_showPushIntoArea.GetBool() ) {
|
||||
ShowPushIntoArea( origin );
|
||||
}
|
||||
}
|
||||
189
neo/d3xp/ai/AAS_local.h
Normal file
189
neo/d3xp/ai/AAS_local.h
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __AAS_LOCAL_H__
|
||||
#define __AAS_LOCAL_H__
|
||||
|
||||
#include "AAS.h"
|
||||
#include "../Pvs.h"
|
||||
|
||||
|
||||
class idRoutingCache {
|
||||
friend class idAASLocal;
|
||||
|
||||
public:
|
||||
idRoutingCache( int size );
|
||||
~idRoutingCache();
|
||||
|
||||
int Size() const;
|
||||
|
||||
private:
|
||||
int type; // portal or area cache
|
||||
int size; // size of cache
|
||||
int cluster; // cluster of the cache
|
||||
int areaNum; // area of the cache
|
||||
int travelFlags; // combinations of the travel flags
|
||||
idRoutingCache * next; // next in list
|
||||
idRoutingCache * prev; // previous in list
|
||||
idRoutingCache * time_next; // next in time based list
|
||||
idRoutingCache * time_prev; // previous in time based list
|
||||
unsigned short startTravelTime; // travel time to start with
|
||||
unsigned char * reachabilities; // reachabilities used for routing
|
||||
unsigned short * travelTimes; // travel time for every area
|
||||
};
|
||||
|
||||
|
||||
class idRoutingUpdate {
|
||||
friend class idAASLocal;
|
||||
|
||||
private:
|
||||
int cluster; // cluster number of this update
|
||||
int areaNum; // area number of this update
|
||||
unsigned short tmpTravelTime; // temporary travel time
|
||||
unsigned short * areaTravelTimes; // travel times within the area
|
||||
idVec3 start; // start point into area
|
||||
idRoutingUpdate * next; // next in list
|
||||
idRoutingUpdate * prev; // prev in list
|
||||
bool isInList; // true if the update is in the list
|
||||
};
|
||||
|
||||
|
||||
class idRoutingObstacle {
|
||||
friend class idAASLocal;
|
||||
idRoutingObstacle() { }
|
||||
|
||||
private:
|
||||
idBounds bounds; // obstacle bounds
|
||||
idList<int, TAG_AAS> areas; // areas the bounds are in
|
||||
};
|
||||
|
||||
|
||||
class idAASLocal : public idAAS {
|
||||
public:
|
||||
idAASLocal();
|
||||
virtual ~idAASLocal();
|
||||
virtual bool Init( const idStr &mapName, unsigned int mapFileCRC );
|
||||
virtual void Shutdown();
|
||||
virtual void Stats() const;
|
||||
virtual void Test( const idVec3 &origin );
|
||||
virtual const idAASSettings *GetSettings() const;
|
||||
virtual int PointAreaNum( const idVec3 &origin ) const;
|
||||
virtual int PointReachableAreaNum( const idVec3 &origin, const idBounds &searchBounds, const int areaFlags ) const;
|
||||
virtual int BoundsReachableAreaNum( const idBounds &bounds, const int areaFlags ) const;
|
||||
virtual void PushPointIntoAreaNum( int areaNum, idVec3 &origin ) const;
|
||||
virtual idVec3 AreaCenter( int areaNum ) const;
|
||||
virtual int AreaFlags( int areaNum ) const;
|
||||
virtual int AreaTravelFlags( int areaNum ) const;
|
||||
virtual bool Trace( aasTrace_t &trace, const idVec3 &start, const idVec3 &end ) const;
|
||||
virtual const idPlane & GetPlane( int planeNum ) const;
|
||||
virtual int GetWallEdges( int areaNum, const idBounds &bounds, int travelFlags, int *edges, int maxEdges ) const;
|
||||
virtual void SortWallEdges( int *edges, int numEdges ) const;
|
||||
virtual void GetEdgeVertexNumbers( int edgeNum, int verts[2] ) const;
|
||||
virtual void GetEdge( int edgeNum, idVec3 &start, idVec3 &end ) const;
|
||||
virtual bool SetAreaState( const idBounds &bounds, const int areaContents, bool disabled );
|
||||
virtual aasHandle_t AddObstacle( const idBounds &bounds );
|
||||
virtual void RemoveObstacle( const aasHandle_t handle );
|
||||
virtual void RemoveAllObstacles();
|
||||
virtual int TravelTimeToGoalArea( int areaNum, const idVec3 &origin, int goalAreaNum, int travelFlags ) const;
|
||||
virtual bool RouteToGoalArea( int areaNum, const idVec3 origin, int goalAreaNum, int travelFlags, int &travelTime, idReachability **reach ) const;
|
||||
virtual bool WalkPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags ) const;
|
||||
virtual bool WalkPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum ) const;
|
||||
virtual bool FlyPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags ) const;
|
||||
virtual bool FlyPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum ) const;
|
||||
virtual void ShowWalkPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const;
|
||||
virtual void ShowFlyPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const;
|
||||
virtual bool FindNearestGoal( aasGoal_t &goal, int areaNum, const idVec3 origin, const idVec3 &target, int travelFlags, aasObstacle_t *obstacles, int numObstacles, idAASCallback &callback ) const;
|
||||
|
||||
private:
|
||||
idAASFile * file;
|
||||
idStr name;
|
||||
|
||||
private: // routing data
|
||||
idRoutingCache *** areaCacheIndex; // for each area in each cluster the travel times to all other areas in the cluster
|
||||
int areaCacheIndexSize; // number of area cache entries
|
||||
idRoutingCache ** portalCacheIndex; // for each area in the world the travel times from each portal
|
||||
int portalCacheIndexSize; // number of portal cache entries
|
||||
idRoutingUpdate * areaUpdate; // memory used to update the area routing cache
|
||||
idRoutingUpdate * portalUpdate; // memory used to update the portal routing cache
|
||||
unsigned short * goalAreaTravelTimes; // travel times to goal areas
|
||||
unsigned short * areaTravelTimes; // travel times through the areas
|
||||
int numAreaTravelTimes; // number of area travel times
|
||||
mutable idRoutingCache * cacheListStart; // start of list with cache sorted from oldest to newest
|
||||
mutable idRoutingCache * cacheListEnd; // end of list with cache sorted from oldest to newest
|
||||
mutable int totalCacheMemory; // total cache memory used
|
||||
idList<idRoutingObstacle *, TAG_AAS> obstacleList; // list with obstacles
|
||||
|
||||
private: // routing
|
||||
bool SetupRouting();
|
||||
void ShutdownRouting();
|
||||
unsigned short AreaTravelTime( int areaNum, const idVec3 &start, const idVec3 &end ) const;
|
||||
void CalculateAreaTravelTimes();
|
||||
void DeleteAreaTravelTimes();
|
||||
void SetupRoutingCache();
|
||||
void DeleteClusterCache( int clusterNum );
|
||||
void DeletePortalCache();
|
||||
void ShutdownRoutingCache();
|
||||
void RoutingStats() const;
|
||||
void LinkCache( idRoutingCache *cache ) const;
|
||||
void UnlinkCache( idRoutingCache *cache ) const;
|
||||
void DeleteOldestCache() const;
|
||||
idReachability * GetAreaReachability( int areaNum, int reachabilityNum ) const;
|
||||
int ClusterAreaNum( int clusterNum, int areaNum ) const;
|
||||
void UpdateAreaRoutingCache( idRoutingCache *areaCache ) const;
|
||||
idRoutingCache * GetAreaRoutingCache( int clusterNum, int areaNum, int travelFlags ) const;
|
||||
void UpdatePortalRoutingCache( idRoutingCache *portalCache ) const;
|
||||
idRoutingCache * GetPortalRoutingCache( int clusterNum, int areaNum, int travelFlags ) const;
|
||||
void RemoveRoutingCacheUsingArea( int areaNum );
|
||||
void DisableArea( int areaNum );
|
||||
void EnableArea( int areaNum );
|
||||
bool SetAreaState_r( int nodeNum, const idBounds &bounds, const int areaContents, bool disabled );
|
||||
void GetBoundsAreas_r( int nodeNum, const idBounds &bounds, idList<int> &areas ) const;
|
||||
void SetObstacleState( const idRoutingObstacle *obstacle, bool enable );
|
||||
|
||||
private: // pathing
|
||||
bool EdgeSplitPoint( idVec3 &split, int edgeNum, const idPlane &plane ) const;
|
||||
bool FloorEdgeSplitPoint( idVec3 &split, int areaNum, const idPlane &splitPlane, const idPlane &frontPlane, bool closest ) const;
|
||||
idVec3 SubSampleWalkPath( int areaNum, const idVec3 &origin, const idVec3 &start, const idVec3 &end, int travelFlags, int &endAreaNum ) const;
|
||||
idVec3 SubSampleFlyPath( int areaNum, const idVec3 &origin, const idVec3 &start, const idVec3 &end, int travelFlags, int &endAreaNum ) const;
|
||||
|
||||
private: // debug
|
||||
const idBounds & DefaultSearchBounds() const;
|
||||
void DrawCone( const idVec3 &origin, const idVec3 &dir, float radius, const idVec4 &color ) const;
|
||||
void DrawArea( int areaNum ) const;
|
||||
void DrawFace( int faceNum, bool side ) const;
|
||||
void DrawEdge( int edgeNum, bool arrow ) const;
|
||||
void DrawReachability( const idReachability *reach ) const;
|
||||
void ShowArea( const idVec3 &origin ) const;
|
||||
void ShowWallEdges( const idVec3 &origin ) const;
|
||||
void ShowHideArea( const idVec3 &origin, int targerAreaNum ) const;
|
||||
bool PullPlayer( const idVec3 &origin, int toAreaNum ) const;
|
||||
void RandomPullPlayer( const idVec3 &origin ) const;
|
||||
void ShowPushIntoArea( const idVec3 &origin ) const;
|
||||
};
|
||||
|
||||
#endif /* !__AAS_LOCAL_H__ */
|
||||
717
neo/d3xp/ai/AAS_pathing.cpp
Normal file
717
neo/d3xp/ai/AAS_pathing.cpp
Normal file
@@ -0,0 +1,717 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma hdrstop
|
||||
#include "../../idlib/precompiled.h"
|
||||
|
||||
|
||||
#include "AAS_local.h"
|
||||
|
||||
#define SUBSAMPLE_WALK_PATH 1
|
||||
#define SUBSAMPLE_FLY_PATH 0
|
||||
|
||||
const int maxWalkPathIterations = 10;
|
||||
const float maxWalkPathDistance = 500.0f;
|
||||
const float walkPathSampleDistance = 8.0f;
|
||||
|
||||
const int maxFlyPathIterations = 10;
|
||||
const float maxFlyPathDistance = 500.0f;
|
||||
const float flyPathSampleDistance = 8.0f;
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::EdgeSplitPoint
|
||||
|
||||
calculates split point of the edge with the plane
|
||||
returns true if the split point is between the edge vertices
|
||||
============
|
||||
*/
|
||||
bool idAASLocal::EdgeSplitPoint( idVec3 &split, int edgeNum, const idPlane &plane ) const {
|
||||
const aasEdge_t *edge;
|
||||
idVec3 v1, v2;
|
||||
float d1, d2;
|
||||
|
||||
edge = &file->GetEdge( edgeNum );
|
||||
v1 = file->GetVertex( edge->vertexNum[0] );
|
||||
v2 = file->GetVertex( edge->vertexNum[1] );
|
||||
d1 = v1 * plane.Normal() - plane.Dist();
|
||||
d2 = v2 * plane.Normal() - plane.Dist();
|
||||
|
||||
//if ( (d1 < CM_CLIP_EPSILON && d2 < CM_CLIP_EPSILON) || (d1 > -CM_CLIP_EPSILON && d2 > -CM_CLIP_EPSILON) ) {
|
||||
if ( IEEE_FLT_SIGNBITSET( d1 ) == IEEE_FLT_SIGNBITSET( d2 ) ) {
|
||||
return false;
|
||||
}
|
||||
split = v1 + (d1 / (d1 - d2)) * (v2 - v1);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::FloorEdgeSplitPoint
|
||||
|
||||
calculates either the closest or furthest point on the floor of the area which also lies on the pathPlane
|
||||
the point has to be on the front side of the frontPlane to be valid
|
||||
============
|
||||
*/
|
||||
bool idAASLocal::FloorEdgeSplitPoint( idVec3 &bestSplit, int areaNum, const idPlane &pathPlane, const idPlane &frontPlane, bool closest ) const {
|
||||
int i, j, faceNum, edgeNum;
|
||||
const aasArea_t *area;
|
||||
const aasFace_t *face;
|
||||
idVec3 split;
|
||||
float dist, bestDist;
|
||||
|
||||
if ( closest ) {
|
||||
bestDist = maxWalkPathDistance;
|
||||
} else {
|
||||
bestDist = -0.1f;
|
||||
}
|
||||
|
||||
area = &file->GetArea( areaNum );
|
||||
|
||||
for ( i = 0; i < area->numFaces; i++ ) {
|
||||
faceNum = file->GetFaceIndex( area->firstFace + i );
|
||||
face = &file->GetFace( abs(faceNum) );
|
||||
|
||||
if ( !(face->flags & FACE_FLOOR ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( j = 0; j < face->numEdges; j++ ) {
|
||||
edgeNum = file->GetEdgeIndex( face->firstEdge + j );
|
||||
|
||||
if ( !EdgeSplitPoint( split, abs( edgeNum ), pathPlane ) ) {
|
||||
continue;
|
||||
}
|
||||
dist = frontPlane.Distance( split );
|
||||
if ( closest ) {
|
||||
if ( dist >= -0.1f && dist < bestDist ) {
|
||||
bestDist = dist;
|
||||
bestSplit = split;
|
||||
}
|
||||
} else {
|
||||
if ( dist > bestDist ) {
|
||||
bestDist = dist;
|
||||
bestSplit = split;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( closest ) {
|
||||
return ( bestDist < maxWalkPathDistance );
|
||||
} else {
|
||||
return ( bestDist > -0.1f );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::WalkPathValid
|
||||
|
||||
returns true if one can walk in a straight line between origin and goalOrigin
|
||||
============
|
||||
*/
|
||||
bool idAASLocal::WalkPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum ) const {
|
||||
int curAreaNum, lastAreaNum, lastAreas[4], lastAreaIndex;
|
||||
idPlane pathPlane, frontPlane, farPlane;
|
||||
idReachability *reach;
|
||||
const aasArea_t *area;
|
||||
idVec3 p, dir;
|
||||
|
||||
if ( file == NULL ) {
|
||||
endPos = goalOrigin;
|
||||
endAreaNum = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
lastAreas[0] = lastAreas[1] = lastAreas[2] = lastAreas[3] = areaNum;
|
||||
lastAreaIndex = 0;
|
||||
|
||||
pathPlane.SetNormal( (goalOrigin - origin).Cross( file->GetSettings().gravityDir ) );
|
||||
pathPlane.Normalize();
|
||||
pathPlane.FitThroughPoint( origin );
|
||||
|
||||
frontPlane.SetNormal( goalOrigin - origin );
|
||||
frontPlane.Normalize();
|
||||
frontPlane.FitThroughPoint( origin );
|
||||
|
||||
farPlane.SetNormal( frontPlane.Normal() );
|
||||
farPlane.FitThroughPoint( goalOrigin );
|
||||
|
||||
curAreaNum = areaNum;
|
||||
lastAreaNum = curAreaNum;
|
||||
|
||||
while ( 1 ) {
|
||||
|
||||
// find the furthest floor face split point on the path
|
||||
if ( !FloorEdgeSplitPoint( endPos, curAreaNum, pathPlane, frontPlane, false ) ) {
|
||||
endPos = origin;
|
||||
}
|
||||
|
||||
// if we found a point near or further than the goal we're done
|
||||
if ( farPlane.Distance( endPos ) > -0.5f ) {
|
||||
break;
|
||||
}
|
||||
|
||||
// if we reached the goal area we're done
|
||||
if ( curAreaNum == goalAreaNum ) {
|
||||
break;
|
||||
}
|
||||
|
||||
frontPlane.SetDist( frontPlane.Normal() * endPos );
|
||||
|
||||
area = &file->GetArea( curAreaNum );
|
||||
|
||||
for ( reach = area->reach; reach; reach = reach->next ) {
|
||||
if ( reach->travelType != TFL_WALK ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if the reachability goes back to a previous area
|
||||
if ( reach->toAreaNum == lastAreas[0] || reach->toAreaNum == lastAreas[1] ||
|
||||
reach->toAreaNum == lastAreas[2] || reach->toAreaNum == lastAreas[3] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if undesired travel flags are required to travel through the area
|
||||
if ( file->GetArea( reach->toAreaNum ).travelFlags & ~travelFlags ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't optimize through an area near a ledge
|
||||
if ( file->GetArea( reach->toAreaNum ).flags & AREA_LEDGE ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// find the closest floor face split point on the path
|
||||
if ( !FloorEdgeSplitPoint( p, reach->toAreaNum, pathPlane, frontPlane, true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// direction parallel to gravity
|
||||
dir = ( file->GetSettings().gravityDir * endPos * file->GetSettings().gravityDir ) -
|
||||
( file->GetSettings().gravityDir * p * file->GetSettings().gravityDir );
|
||||
if ( dir.LengthSqr() > Square( file->GetSettings().maxStepHeight ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// direction orthogonal to gravity
|
||||
dir = endPos - p - dir;
|
||||
if ( dir.LengthSqr() > Square( 0.2f ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !reach ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
lastAreas[lastAreaIndex] = curAreaNum;
|
||||
lastAreaIndex = ( lastAreaIndex + 1 ) & 3;
|
||||
|
||||
curAreaNum = reach->toAreaNum;
|
||||
}
|
||||
|
||||
endAreaNum = curAreaNum;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::SubSampleWalkPath
|
||||
============
|
||||
*/
|
||||
idVec3 idAASLocal::SubSampleWalkPath( int areaNum, const idVec3 &origin, const idVec3 &start, const idVec3 &end, int travelFlags, int &endAreaNum ) const {
|
||||
int i, numSamples, curAreaNum;
|
||||
idVec3 dir, point, nextPoint, endPos;
|
||||
|
||||
dir = end - start;
|
||||
numSamples = (int) (dir.Length() / walkPathSampleDistance) + 1;
|
||||
|
||||
point = start;
|
||||
for ( i = 1; i < numSamples; i++ ) {
|
||||
nextPoint = start + dir * ((float) i / numSamples);
|
||||
if ( (point - nextPoint).LengthSqr() > Square( maxWalkPathDistance ) ) {
|
||||
return point;
|
||||
}
|
||||
if ( !idAASLocal::WalkPathValid( areaNum, origin, 0, nextPoint, travelFlags, endPos, curAreaNum ) ) {
|
||||
return point;
|
||||
}
|
||||
point = nextPoint;
|
||||
endAreaNum = curAreaNum;
|
||||
}
|
||||
return point;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::WalkPathToGoal
|
||||
|
||||
FIXME: don't stop optimizing on first failure ?
|
||||
============
|
||||
*/
|
||||
bool idAASLocal::WalkPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags ) const {
|
||||
int i, travelTime, curAreaNum, lastAreas[4], lastAreaIndex, endAreaNum;
|
||||
idReachability * reach = NULL;
|
||||
idVec3 endPos;
|
||||
|
||||
path.type = PATHTYPE_WALK;
|
||||
path.moveGoal = origin;
|
||||
path.moveAreaNum = areaNum;
|
||||
path.secondaryGoal = origin;
|
||||
path.reachability = NULL;
|
||||
|
||||
if ( file == NULL || areaNum == goalAreaNum ) {
|
||||
path.moveGoal = goalOrigin;
|
||||
return true;
|
||||
}
|
||||
|
||||
lastAreas[0] = lastAreas[1] = lastAreas[2] = lastAreas[3] = areaNum;
|
||||
lastAreaIndex = 0;
|
||||
|
||||
curAreaNum = areaNum;
|
||||
|
||||
for ( i = 0; i < maxWalkPathIterations; i++ ) {
|
||||
|
||||
if ( !idAASLocal::RouteToGoalArea( curAreaNum, path.moveGoal, goalAreaNum, travelFlags, travelTime, &reach ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !reach ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// no need to check through the first area
|
||||
if ( areaNum != curAreaNum ) {
|
||||
// only optimize a limited distance ahead
|
||||
if ( (reach->start - origin).LengthSqr() > Square( maxWalkPathDistance ) ) {
|
||||
#if SUBSAMPLE_WALK_PATH
|
||||
path.moveGoal = SubSampleWalkPath( areaNum, origin, path.moveGoal, reach->start, travelFlags, path.moveAreaNum );
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( !idAASLocal::WalkPathValid( areaNum, origin, 0, reach->start, travelFlags, endPos, endAreaNum ) ) {
|
||||
#if SUBSAMPLE_WALK_PATH
|
||||
path.moveGoal = SubSampleWalkPath( areaNum, origin, path.moveGoal, reach->start, travelFlags, path.moveAreaNum );
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
path.moveGoal = reach->start;
|
||||
path.moveAreaNum = curAreaNum;
|
||||
|
||||
if ( reach->travelType != TFL_WALK ) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !idAASLocal::WalkPathValid( areaNum, origin, 0, reach->end, travelFlags, endPos, endAreaNum ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
path.moveGoal = reach->end;
|
||||
path.moveAreaNum = reach->toAreaNum;
|
||||
|
||||
if ( reach->toAreaNum == goalAreaNum ) {
|
||||
if ( !idAASLocal::WalkPathValid( areaNum, origin, 0, goalOrigin, travelFlags, endPos, endAreaNum ) ) {
|
||||
#if SUBSAMPLE_WALK_PATH
|
||||
path.moveGoal = SubSampleWalkPath( areaNum, origin, path.moveGoal, goalOrigin, travelFlags, path.moveAreaNum );
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
path.moveGoal = goalOrigin;
|
||||
path.moveAreaNum = goalAreaNum;
|
||||
return true;
|
||||
}
|
||||
|
||||
lastAreas[lastAreaIndex] = curAreaNum;
|
||||
lastAreaIndex = ( lastAreaIndex + 1 ) & 3;
|
||||
|
||||
curAreaNum = reach->toAreaNum;
|
||||
|
||||
if ( curAreaNum == lastAreas[0] || curAreaNum == lastAreas[1] ||
|
||||
curAreaNum == lastAreas[2] || curAreaNum == lastAreas[3] ) {
|
||||
common->Warning( "idAASLocal::WalkPathToGoal: local routing minimum going from area %d to area %d", areaNum, goalAreaNum );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( reach == NULL ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch( reach->travelType ) {
|
||||
case TFL_WALKOFFLEDGE:
|
||||
path.type = PATHTYPE_WALKOFFLEDGE;
|
||||
path.secondaryGoal = reach->end;
|
||||
path.reachability = reach;
|
||||
break;
|
||||
case TFL_BARRIERJUMP:
|
||||
path.type |= PATHTYPE_BARRIERJUMP;
|
||||
path.secondaryGoal = reach->end;
|
||||
path.reachability = reach;
|
||||
break;
|
||||
case TFL_JUMP:
|
||||
path.type |= PATHTYPE_JUMP;
|
||||
path.secondaryGoal = reach->end;
|
||||
path.reachability = reach;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::FlyPathValid
|
||||
|
||||
returns true if one can fly in a straight line between origin and goalOrigin
|
||||
============
|
||||
*/
|
||||
bool idAASLocal::FlyPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum ) const {
|
||||
aasTrace_t trace;
|
||||
|
||||
if ( file == NULL ) {
|
||||
endPos = goalOrigin;
|
||||
endAreaNum = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
file->Trace( trace, origin, goalOrigin );
|
||||
|
||||
endPos = trace.endpos;
|
||||
endAreaNum = trace.lastAreaNum;
|
||||
|
||||
if ( trace.fraction >= 1.0f ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::SubSampleFlyPath
|
||||
============
|
||||
*/
|
||||
idVec3 idAASLocal::SubSampleFlyPath( int areaNum, const idVec3 &origin, const idVec3 &start, const idVec3 &end, int travelFlags, int &endAreaNum ) const {
|
||||
int i, numSamples, curAreaNum;
|
||||
idVec3 dir, point, nextPoint, endPos;
|
||||
|
||||
dir = end - start;
|
||||
numSamples = (int) (dir.Length() / flyPathSampleDistance) + 1;
|
||||
|
||||
point = start;
|
||||
for ( i = 1; i < numSamples; i++ ) {
|
||||
nextPoint = start + dir * ((float) i / numSamples);
|
||||
if ( (point - nextPoint).LengthSqr() > Square( maxFlyPathDistance ) ) {
|
||||
return point;
|
||||
}
|
||||
if ( !idAASLocal::FlyPathValid( areaNum, origin, 0, nextPoint, travelFlags, endPos, curAreaNum ) ) {
|
||||
return point;
|
||||
}
|
||||
point = nextPoint;
|
||||
endAreaNum = curAreaNum;
|
||||
}
|
||||
return point;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::FlyPathToGoal
|
||||
|
||||
FIXME: don't stop optimizing on first failure ?
|
||||
============
|
||||
*/
|
||||
bool idAASLocal::FlyPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags ) const {
|
||||
int i, travelTime, curAreaNum, lastAreas[4], lastAreaIndex, endAreaNum;
|
||||
idReachability *reach = NULL;
|
||||
idVec3 endPos;
|
||||
|
||||
path.type = PATHTYPE_WALK;
|
||||
path.moveGoal = origin;
|
||||
path.moveAreaNum = areaNum;
|
||||
path.secondaryGoal = origin;
|
||||
path.reachability = NULL;
|
||||
|
||||
if ( file == NULL || areaNum == goalAreaNum ) {
|
||||
path.moveGoal = goalOrigin;
|
||||
return true;
|
||||
}
|
||||
|
||||
lastAreas[0] = lastAreas[1] = lastAreas[2] = lastAreas[3] = areaNum;
|
||||
lastAreaIndex = 0;
|
||||
|
||||
curAreaNum = areaNum;
|
||||
|
||||
for ( i = 0; i < maxFlyPathIterations; i++ ) {
|
||||
|
||||
if ( !idAASLocal::RouteToGoalArea( curAreaNum, path.moveGoal, goalAreaNum, travelFlags, travelTime, &reach ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !reach ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// no need to check through the first area
|
||||
if ( areaNum != curAreaNum ) {
|
||||
if ( (reach->start - origin).LengthSqr() > Square( maxFlyPathDistance ) ) {
|
||||
#if SUBSAMPLE_FLY_PATH
|
||||
path.moveGoal = SubSampleFlyPath( areaNum, origin, path.moveGoal, reach->start, travelFlags, path.moveAreaNum );
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( !idAASLocal::FlyPathValid( areaNum, origin, 0, reach->start, travelFlags, endPos, endAreaNum ) ) {
|
||||
#if SUBSAMPLE_FLY_PATH
|
||||
path.moveGoal = SubSampleFlyPath( areaNum, origin, path.moveGoal, reach->start, travelFlags, path.moveAreaNum );
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
path.moveGoal = reach->start;
|
||||
path.moveAreaNum = curAreaNum;
|
||||
|
||||
if ( !idAASLocal::FlyPathValid( areaNum, origin, 0, reach->end, travelFlags, endPos, endAreaNum ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
path.moveGoal = reach->end;
|
||||
path.moveAreaNum = reach->toAreaNum;
|
||||
|
||||
if ( reach->toAreaNum == goalAreaNum ) {
|
||||
if ( !idAASLocal::FlyPathValid( areaNum, origin, 0, goalOrigin, travelFlags, endPos, endAreaNum ) ) {
|
||||
#if SUBSAMPLE_FLY_PATH
|
||||
path.moveGoal = SubSampleFlyPath( areaNum, origin, path.moveGoal, goalOrigin, travelFlags, path.moveAreaNum );
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
path.moveGoal = goalOrigin;
|
||||
path.moveAreaNum = goalAreaNum;
|
||||
return true;
|
||||
}
|
||||
|
||||
lastAreas[lastAreaIndex] = curAreaNum;
|
||||
lastAreaIndex = ( lastAreaIndex + 1 ) & 3;
|
||||
|
||||
curAreaNum = reach->toAreaNum;
|
||||
|
||||
if ( curAreaNum == lastAreas[0] || curAreaNum == lastAreas[1] ||
|
||||
curAreaNum == lastAreas[2] || curAreaNum == lastAreas[3] ) {
|
||||
common->Warning( "idAASLocal::FlyPathToGoal: local routing minimum going from area %d to area %d", areaNum, goalAreaNum );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( reach == NULL ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef struct wallEdge_s {
|
||||
int edgeNum;
|
||||
int verts[2];
|
||||
struct wallEdge_s * next;
|
||||
} wallEdge_t;
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::SortWallEdges
|
||||
============
|
||||
*/
|
||||
void idAASLocal::SortWallEdges( int *edges, int numEdges ) const {
|
||||
int i, j, k, numSequences;
|
||||
wallEdge_t **sequenceFirst, **sequenceLast, *wallEdges, *wallEdge;
|
||||
|
||||
wallEdges = (wallEdge_t *) _alloca16( numEdges * sizeof( wallEdge_t ) );
|
||||
sequenceFirst = (wallEdge_t **)_alloca16( numEdges * sizeof( wallEdge_t * ) );
|
||||
sequenceLast = (wallEdge_t **)_alloca16( numEdges * sizeof( wallEdge_t * ) );
|
||||
|
||||
for ( i = 0; i < numEdges; i++ ) {
|
||||
wallEdges[i].edgeNum = edges[i];
|
||||
GetEdgeVertexNumbers( edges[i], wallEdges[i].verts );
|
||||
wallEdges[i].next = NULL;
|
||||
sequenceFirst[i] = &wallEdges[i];
|
||||
sequenceLast[i] = &wallEdges[i];
|
||||
}
|
||||
numSequences = numEdges;
|
||||
|
||||
for ( i = 0; i < numSequences; i++ ) {
|
||||
for ( j = i+1; j < numSequences; j++ ) {
|
||||
if ( sequenceFirst[i]->verts[0] == sequenceLast[j]->verts[1] ) {
|
||||
sequenceLast[j]->next = sequenceFirst[i];
|
||||
sequenceFirst[i] = sequenceFirst[j];
|
||||
break;
|
||||
}
|
||||
if ( sequenceLast[i]->verts[1] == sequenceFirst[j]->verts[0] ) {
|
||||
sequenceLast[i]->next = sequenceFirst[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( j < numSequences ) {
|
||||
numSequences--;
|
||||
for ( k = j; k < numSequences; k++ ) {
|
||||
sequenceFirst[k] = sequenceFirst[k+1];
|
||||
sequenceLast[k] = sequenceLast[k+1];
|
||||
}
|
||||
i = -1;
|
||||
}
|
||||
}
|
||||
|
||||
k = 0;
|
||||
for ( i = 0; i < numSequences; i++ ) {
|
||||
for ( wallEdge = sequenceFirst[i]; wallEdge; wallEdge = wallEdge->next ) {
|
||||
edges[k++] = wallEdge->edgeNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
idAASLocal::GetWallEdges
|
||||
============
|
||||
*/
|
||||
int idAASLocal::GetWallEdges( int areaNum, const idBounds &bounds, int travelFlags, int *edges, int maxEdges ) const {
|
||||
int i, j, k, l, face1Num, face2Num, edge1Num, edge2Num, numEdges, absEdge1Num;
|
||||
int *areaQueue, curArea, queueStart, queueEnd;
|
||||
byte *areasVisited;
|
||||
const aasArea_t *area;
|
||||
const aasFace_t *face1, *face2;
|
||||
idReachability *reach;
|
||||
|
||||
if ( !file ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
numEdges = 0;
|
||||
|
||||
areasVisited = (byte *) _alloca16( file->GetNumAreas() );
|
||||
memset( areasVisited, 0, file->GetNumAreas() * sizeof( byte ) );
|
||||
areaQueue = (int *) _alloca16( file->GetNumAreas() * sizeof( int ) );
|
||||
|
||||
queueStart = -1;
|
||||
queueEnd = 0;
|
||||
areaQueue[0] = areaNum;
|
||||
areasVisited[areaNum] = true;
|
||||
|
||||
for ( curArea = areaNum; queueStart < queueEnd; curArea = areaQueue[++queueStart] ) {
|
||||
|
||||
area = &file->GetArea( curArea );
|
||||
|
||||
for ( i = 0; i < area->numFaces; i++ ) {
|
||||
face1Num = file->GetFaceIndex( area->firstFace + i );
|
||||
face1 = &file->GetFace( abs(face1Num) );
|
||||
|
||||
if ( !(face1->flags & FACE_FLOOR ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( j = 0; j < face1->numEdges; j++ ) {
|
||||
edge1Num = file->GetEdgeIndex( face1->firstEdge + j );
|
||||
absEdge1Num = abs( edge1Num );
|
||||
|
||||
// test if the edge is shared by another floor face of this area
|
||||
for ( k = 0; k < area->numFaces; k++ ) {
|
||||
if ( k == i ) {
|
||||
continue;
|
||||
}
|
||||
face2Num = file->GetFaceIndex( area->firstFace + k );
|
||||
face2 = &file->GetFace( abs(face2Num) );
|
||||
|
||||
if ( !(face2->flags & FACE_FLOOR ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( l = 0; l < face2->numEdges; l++ ) {
|
||||
edge2Num = abs( file->GetEdgeIndex( face2->firstEdge + l ) );
|
||||
if ( edge2Num == absEdge1Num ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( l < face2->numEdges ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( k < area->numFaces ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// test if the edge is used by a reachability
|
||||
for ( reach = area->reach; reach; reach = reach->next ) {
|
||||
if ( reach->travelType & travelFlags ) {
|
||||
if ( reach->edgeNum == absEdge1Num ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( reach ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// test if the edge is already in the list
|
||||
for ( k = 0; k < numEdges; k++ ) {
|
||||
if ( edge1Num == edges[k] ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( k < numEdges ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// add the edge to the list
|
||||
edges[numEdges++] = edge1Num;
|
||||
if ( numEdges >= maxEdges ) {
|
||||
return numEdges;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add new areas to the queue
|
||||
for ( reach = area->reach; reach; reach = reach->next ) {
|
||||
if ( reach->travelType & travelFlags ) {
|
||||
// if the area the reachability leads to hasn't been visited yet and the area bounds touch the search bounds
|
||||
if ( !areasVisited[reach->toAreaNum] && bounds.IntersectsBounds( file->GetArea( reach->toAreaNum ).bounds ) ) {
|
||||
areaQueue[queueEnd++] = reach->toAreaNum;
|
||||
areasVisited[reach->toAreaNum] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return numEdges;
|
||||
}
|
||||
1350
neo/d3xp/ai/AAS_routing.cpp
Normal file
1350
neo/d3xp/ai/AAS_routing.cpp
Normal file
File diff suppressed because it is too large
Load Diff
5337
neo/d3xp/ai/AI.cpp
Normal file
5337
neo/d3xp/ai/AI.cpp
Normal file
File diff suppressed because it is too large
Load Diff
731
neo/d3xp/ai/AI.h
Normal file
731
neo/d3xp/ai/AI.h
Normal file
@@ -0,0 +1,731 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __AI_H__
|
||||
#define __AI_H__
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idAI
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
const float SQUARE_ROOT_OF_2 = 1.414213562f;
|
||||
const float AI_TURN_PREDICTION = 0.2f;
|
||||
const float AI_TURN_SCALE = 60.0f;
|
||||
const float AI_SEEK_PREDICTION = 0.3f;
|
||||
const float AI_FLY_DAMPENING = 0.15f;
|
||||
const float AI_HEARING_RANGE = 2048.0f;
|
||||
const int DEFAULT_FLY_OFFSET = 68;
|
||||
|
||||
#define ATTACK_IGNORE 0
|
||||
#define ATTACK_ON_DAMAGE 1
|
||||
#define ATTACK_ON_ACTIVATE 2
|
||||
#define ATTACK_ON_SIGHT 4
|
||||
|
||||
typedef struct ballistics_s {
|
||||
float angle; // angle in degrees in the range [-180, 180]
|
||||
float time; // time it takes before the projectile arrives
|
||||
} ballistics_t;
|
||||
|
||||
extern int Ballistics( const idVec3 &start, const idVec3 &end, float speed, float gravity, ballistics_t bal[2] );
|
||||
|
||||
// defined in script/ai_base.script. please keep them up to date.
|
||||
typedef enum {
|
||||
MOVETYPE_DEAD,
|
||||
MOVETYPE_ANIM,
|
||||
MOVETYPE_SLIDE,
|
||||
MOVETYPE_FLY,
|
||||
MOVETYPE_STATIC,
|
||||
NUM_MOVETYPES
|
||||
} moveType_t;
|
||||
|
||||
typedef enum {
|
||||
MOVE_NONE,
|
||||
MOVE_FACE_ENEMY,
|
||||
MOVE_FACE_ENTITY,
|
||||
|
||||
// commands < NUM_NONMOVING_COMMANDS don't cause a change in position
|
||||
NUM_NONMOVING_COMMANDS,
|
||||
|
||||
MOVE_TO_ENEMY = NUM_NONMOVING_COMMANDS,
|
||||
MOVE_TO_ENEMYHEIGHT,
|
||||
MOVE_TO_ENTITY,
|
||||
MOVE_OUT_OF_RANGE,
|
||||
MOVE_TO_ATTACK_POSITION,
|
||||
MOVE_TO_COVER,
|
||||
MOVE_TO_POSITION,
|
||||
MOVE_TO_POSITION_DIRECT,
|
||||
MOVE_SLIDE_TO_POSITION,
|
||||
MOVE_WANDER,
|
||||
NUM_MOVE_COMMANDS
|
||||
} moveCommand_t;
|
||||
|
||||
typedef enum {
|
||||
TALK_NEVER,
|
||||
TALK_DEAD,
|
||||
TALK_OK,
|
||||
TALK_BUSY,
|
||||
NUM_TALK_STATES
|
||||
} talkState_t;
|
||||
|
||||
//
|
||||
// status results from move commands
|
||||
// make sure to change script/doom_defs.script if you add any, or change their order
|
||||
//
|
||||
typedef enum {
|
||||
MOVE_STATUS_DONE,
|
||||
MOVE_STATUS_MOVING,
|
||||
MOVE_STATUS_WAITING,
|
||||
MOVE_STATUS_DEST_NOT_FOUND,
|
||||
MOVE_STATUS_DEST_UNREACHABLE,
|
||||
MOVE_STATUS_BLOCKED_BY_WALL,
|
||||
MOVE_STATUS_BLOCKED_BY_OBJECT,
|
||||
MOVE_STATUS_BLOCKED_BY_ENEMY,
|
||||
MOVE_STATUS_BLOCKED_BY_MONSTER
|
||||
} moveStatus_t;
|
||||
|
||||
#define DI_NODIR -1
|
||||
|
||||
// obstacle avoidance
|
||||
typedef struct obstaclePath_s {
|
||||
idVec3 seekPos; // seek position avoiding obstacles
|
||||
idEntity * firstObstacle; // if != NULL the first obstacle along the path
|
||||
idVec3 startPosOutsideObstacles; // start position outside obstacles
|
||||
idEntity * startPosObstacle; // if != NULL the obstacle containing the start position
|
||||
idVec3 seekPosOutsideObstacles; // seek position outside obstacles
|
||||
idEntity * seekPosObstacle; // if != NULL the obstacle containing the seek position
|
||||
} obstaclePath_t;
|
||||
|
||||
// path prediction
|
||||
typedef enum {
|
||||
SE_BLOCKED = BIT(0),
|
||||
SE_ENTER_LEDGE_AREA = BIT(1),
|
||||
SE_ENTER_OBSTACLE = BIT(2),
|
||||
SE_FALL = BIT(3),
|
||||
SE_LAND = BIT(4)
|
||||
} stopEvent_t;
|
||||
|
||||
typedef struct predictedPath_s {
|
||||
idVec3 endPos; // final position
|
||||
idVec3 endVelocity; // velocity at end position
|
||||
idVec3 endNormal; // normal of blocking surface
|
||||
int endTime; // time predicted
|
||||
int endEvent; // event that stopped the prediction
|
||||
const idEntity * blockingEntity; // entity that blocks the movement
|
||||
} predictedPath_t;
|
||||
|
||||
//
|
||||
// events
|
||||
//
|
||||
extern const idEventDef AI_BeginAttack;
|
||||
extern const idEventDef AI_EndAttack;
|
||||
extern const idEventDef AI_MuzzleFlash;
|
||||
extern const idEventDef AI_CreateMissile;
|
||||
extern const idEventDef AI_AttackMissile;
|
||||
extern const idEventDef AI_FireMissileAtTarget;
|
||||
extern const idEventDef AI_LaunchProjectile;
|
||||
extern const idEventDef AI_TriggerFX;
|
||||
extern const idEventDef AI_StartEmitter;
|
||||
extern const idEventDef AI_StopEmitter;
|
||||
extern const idEventDef AI_AttackMelee;
|
||||
extern const idEventDef AI_DirectDamage;
|
||||
extern const idEventDef AI_JumpFrame;
|
||||
extern const idEventDef AI_EnableClip;
|
||||
extern const idEventDef AI_DisableClip;
|
||||
extern const idEventDef AI_EnableGravity;
|
||||
extern const idEventDef AI_DisableGravity;
|
||||
extern const idEventDef AI_TriggerParticles;
|
||||
extern const idEventDef AI_RandomPath;
|
||||
|
||||
class idPathCorner;
|
||||
|
||||
typedef struct particleEmitter_s {
|
||||
particleEmitter_s() {
|
||||
particle = NULL;
|
||||
time = 0;
|
||||
joint = INVALID_JOINT;
|
||||
};
|
||||
const idDeclParticle *particle;
|
||||
int time;
|
||||
jointHandle_t joint;
|
||||
} particleEmitter_t;
|
||||
|
||||
typedef struct funcEmitter_s {
|
||||
char name[64];
|
||||
idFuncEmitter* particle;
|
||||
jointHandle_t joint;
|
||||
} funcEmitter_t;
|
||||
|
||||
class idMoveState {
|
||||
public:
|
||||
idMoveState();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
moveType_t moveType;
|
||||
moveCommand_t moveCommand;
|
||||
moveStatus_t moveStatus;
|
||||
idVec3 moveDest;
|
||||
idVec3 moveDir; // used for wandering and slide moves
|
||||
idEntityPtr<idEntity> goalEntity;
|
||||
idVec3 goalEntityOrigin; // move to entity uses this to avoid checking the floor position every frame
|
||||
int toAreaNum;
|
||||
int startTime;
|
||||
int duration;
|
||||
float speed; // only used by flying creatures
|
||||
float range;
|
||||
float wanderYaw;
|
||||
int nextWanderTime;
|
||||
int blockTime;
|
||||
idEntityPtr<idEntity> obstacle;
|
||||
idVec3 lastMoveOrigin;
|
||||
int lastMoveTime;
|
||||
int anim;
|
||||
};
|
||||
|
||||
class idAASFindCover : public idAASCallback {
|
||||
public:
|
||||
idAASFindCover( const idVec3 &hideFromPos );
|
||||
~idAASFindCover();
|
||||
|
||||
virtual bool TestArea( const idAAS *aas, int areaNum );
|
||||
|
||||
private:
|
||||
pvsHandle_t hidePVS;
|
||||
int PVSAreas[ idEntity::MAX_PVS_AREAS ];
|
||||
};
|
||||
|
||||
class idAASFindAreaOutOfRange : public idAASCallback {
|
||||
public:
|
||||
idAASFindAreaOutOfRange( const idVec3 &targetPos, float maxDist );
|
||||
|
||||
virtual bool TestArea( const idAAS *aas, int areaNum );
|
||||
|
||||
private:
|
||||
idVec3 targetPos;
|
||||
float maxDistSqr;
|
||||
};
|
||||
|
||||
class idAASFindAttackPosition : public idAASCallback {
|
||||
public:
|
||||
idAASFindAttackPosition( const idAI *self, const idMat3 &gravityAxis, idEntity *target, const idVec3 &targetPos, const idVec3 &fireOffset );
|
||||
~idAASFindAttackPosition();
|
||||
|
||||
virtual bool TestArea( const idAAS *aas, int areaNum );
|
||||
|
||||
private:
|
||||
const idAI *self;
|
||||
idEntity *target;
|
||||
idBounds excludeBounds;
|
||||
idVec3 targetPos;
|
||||
idVec3 fireOffset;
|
||||
idMat3 gravityAxis;
|
||||
pvsHandle_t targetPVS;
|
||||
int PVSAreas[ idEntity::MAX_PVS_AREAS ];
|
||||
};
|
||||
|
||||
class idAI : public idActor {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idAI );
|
||||
|
||||
idAI();
|
||||
~idAI();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
void HeardSound( idEntity *ent, const char *action );
|
||||
idActor *GetEnemy() const;
|
||||
void TalkTo( idActor *actor );
|
||||
talkState_t GetTalkState() const;
|
||||
|
||||
bool GetAimDir( const idVec3 &firePos, idEntity *aimAtEnt, const idEntity *ignore, idVec3 &aimDir ) const;
|
||||
|
||||
void TouchedByFlashlight( idActor *flashlight_owner );
|
||||
|
||||
// Outputs a list of all monsters to the console.
|
||||
static void List_f( const idCmdArgs &args );
|
||||
|
||||
// Finds a path around dynamic obstacles.
|
||||
static bool FindPathAroundObstacles( const idPhysics *physics, const idAAS *aas, const idEntity *ignore, const idVec3 &startPos, const idVec3 &seekPos, obstaclePath_t &path );
|
||||
// Frees any nodes used for the dynamic obstacle avoidance.
|
||||
static void FreeObstacleAvoidanceNodes();
|
||||
// Predicts movement, returns true if a stop event was triggered.
|
||||
static bool PredictPath( const idEntity *ent, const idAAS *aas, const idVec3 &start, const idVec3 &velocity, int totalTime, int frameTime, int stopEvent, predictedPath_t &path );
|
||||
// Return true if the trajectory of the clip model is collision free.
|
||||
static bool TestTrajectory( const idVec3 &start, const idVec3 &end, float zVel, float gravity, float time, float max_height, const idClipModel *clip, int clipmask, const idEntity *ignore, const idEntity *targetEntity, int drawtime );
|
||||
// Finds the best collision free trajectory for a clip model.
|
||||
static bool PredictTrajectory( const idVec3 &firePos, const idVec3 &target, float projectileSpeed, const idVec3 &projGravity, const idClipModel *clip, int clipmask, float max_height, const idEntity *ignore, const idEntity *targetEntity, int drawtime, idVec3 &aimDir );
|
||||
|
||||
virtual void Gib( const idVec3 &dir, const char *damageDefName );
|
||||
|
||||
protected:
|
||||
// navigation
|
||||
idAAS * aas;
|
||||
int travelFlags;
|
||||
|
||||
idMoveState move;
|
||||
idMoveState savedMove;
|
||||
|
||||
float kickForce;
|
||||
bool ignore_obstacles;
|
||||
float blockedRadius;
|
||||
int blockedMoveTime;
|
||||
int blockedAttackTime;
|
||||
|
||||
// turning
|
||||
float ideal_yaw;
|
||||
float current_yaw;
|
||||
float turnRate;
|
||||
float turnVel;
|
||||
float anim_turn_yaw;
|
||||
float anim_turn_amount;
|
||||
float anim_turn_angles;
|
||||
|
||||
// physics
|
||||
idPhysics_Monster physicsObj;
|
||||
|
||||
// flying
|
||||
jointHandle_t flyTiltJoint;
|
||||
float fly_speed;
|
||||
float fly_bob_strength;
|
||||
float fly_bob_vert;
|
||||
float fly_bob_horz;
|
||||
int fly_offset; // prefered offset from player's view
|
||||
float fly_seek_scale;
|
||||
float fly_roll_scale;
|
||||
float fly_roll_max;
|
||||
float fly_roll;
|
||||
float fly_pitch_scale;
|
||||
float fly_pitch_max;
|
||||
float fly_pitch;
|
||||
|
||||
bool allowMove; // disables any animation movement
|
||||
bool allowHiddenMovement; // allows character to still move around while hidden
|
||||
bool disableGravity; // disables gravity and allows vertical movement by the animation
|
||||
bool af_push_moveables; // allow the articulated figure to push moveable objects
|
||||
|
||||
// weapon/attack vars
|
||||
bool lastHitCheckResult;
|
||||
int lastHitCheckTime;
|
||||
int lastAttackTime;
|
||||
float melee_range;
|
||||
float projectile_height_to_distance_ratio; // calculates the maximum height a projectile can be thrown
|
||||
idList<idVec3, TAG_AI> missileLaunchOffset;
|
||||
|
||||
const idDict * projectileDef;
|
||||
mutable idClipModel *projectileClipModel;
|
||||
float projectileRadius;
|
||||
float projectileSpeed;
|
||||
idVec3 projectileVelocity;
|
||||
idVec3 projectileGravity;
|
||||
idEntityPtr<idProjectile> projectile;
|
||||
idStr attack;
|
||||
idVec3 homingMissileGoal;
|
||||
|
||||
// chatter/talking
|
||||
const idSoundShader *chat_snd;
|
||||
int chat_min;
|
||||
int chat_max;
|
||||
int chat_time;
|
||||
talkState_t talk_state;
|
||||
idEntityPtr<idActor> talkTarget;
|
||||
|
||||
// cinematics
|
||||
int num_cinematics;
|
||||
int current_cinematic;
|
||||
|
||||
bool allowJointMod;
|
||||
idEntityPtr<idEntity> focusEntity;
|
||||
idVec3 currentFocusPos;
|
||||
int focusTime;
|
||||
int alignHeadTime;
|
||||
int forceAlignHeadTime;
|
||||
idAngles eyeAng;
|
||||
idAngles lookAng;
|
||||
idAngles destLookAng;
|
||||
idAngles lookMin;
|
||||
idAngles lookMax;
|
||||
idList<jointHandle_t, TAG_AI> lookJoints;
|
||||
idList<idAngles, TAG_AI> lookJointAngles;
|
||||
float eyeVerticalOffset;
|
||||
float eyeHorizontalOffset;
|
||||
float eyeFocusRate;
|
||||
float headFocusRate;
|
||||
int focusAlignTime;
|
||||
|
||||
// special fx
|
||||
bool restartParticles; // should smoke emissions restart
|
||||
bool useBoneAxis; // use the bone vs the model axis
|
||||
idList<particleEmitter_t, TAG_AI> particles; // particle data
|
||||
|
||||
renderLight_t worldMuzzleFlash; // positioned on world weapon bone
|
||||
int worldMuzzleFlashHandle;
|
||||
jointHandle_t flashJointWorld;
|
||||
int muzzleFlashEnd;
|
||||
int flashTime;
|
||||
|
||||
// joint controllers
|
||||
idAngles eyeMin;
|
||||
idAngles eyeMax;
|
||||
jointHandle_t focusJoint;
|
||||
jointHandle_t orientationJoint;
|
||||
|
||||
// enemy variables
|
||||
idEntityPtr<idActor> enemy;
|
||||
idVec3 lastVisibleEnemyPos;
|
||||
idVec3 lastVisibleEnemyEyeOffset;
|
||||
idVec3 lastVisibleReachableEnemyPos;
|
||||
idVec3 lastReachableEnemyPos;
|
||||
bool wakeOnFlashlight;
|
||||
|
||||
bool spawnClearMoveables;
|
||||
|
||||
idHashTable<funcEmitter_t> funcEmitters;
|
||||
|
||||
idEntityPtr<idHarvestable> harvestEnt;
|
||||
|
||||
// script variables
|
||||
idScriptBool AI_TALK;
|
||||
idScriptBool AI_DAMAGE;
|
||||
idScriptBool AI_PAIN;
|
||||
idScriptFloat AI_SPECIAL_DAMAGE;
|
||||
idScriptBool AI_DEAD;
|
||||
idScriptBool AI_ENEMY_VISIBLE;
|
||||
idScriptBool AI_ENEMY_IN_FOV;
|
||||
idScriptBool AI_ENEMY_DEAD;
|
||||
idScriptBool AI_MOVE_DONE;
|
||||
idScriptBool AI_ONGROUND;
|
||||
idScriptBool AI_ACTIVATED;
|
||||
idScriptBool AI_FORWARD;
|
||||
idScriptBool AI_JUMP;
|
||||
idScriptBool AI_ENEMY_REACHABLE;
|
||||
idScriptBool AI_BLOCKED;
|
||||
idScriptBool AI_OBSTACLE_IN_PATH;
|
||||
idScriptBool AI_DEST_UNREACHABLE;
|
||||
idScriptBool AI_HIT_ENEMY;
|
||||
idScriptBool AI_PUSHED;
|
||||
|
||||
//
|
||||
// ai/ai.cpp
|
||||
//
|
||||
void SetAAS();
|
||||
virtual void DormantBegin(); // called when entity becomes dormant
|
||||
virtual void DormantEnd(); // called when entity wakes from being dormant
|
||||
void Think();
|
||||
void Activate( idEntity *activator );
|
||||
public:
|
||||
int ReactionTo( const idEntity *ent );
|
||||
protected:
|
||||
bool CheckForEnemy();
|
||||
void EnemyDead();
|
||||
virtual bool CanPlayChatterSounds() const;
|
||||
void SetChatSound();
|
||||
void PlayChatter();
|
||||
virtual void Hide();
|
||||
virtual void Show();
|
||||
idVec3 FirstVisiblePointOnPath( const idVec3 origin, const idVec3 &target, int travelFlags ) const;
|
||||
void CalculateAttackOffsets();
|
||||
void PlayCinematic();
|
||||
|
||||
// movement
|
||||
virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse );
|
||||
void GetMoveDelta( const idMat3 &oldaxis, const idMat3 &axis, idVec3 &delta );
|
||||
void CheckObstacleAvoidance( const idVec3 &goalPos, idVec3 &newPos );
|
||||
void DeadMove();
|
||||
void AnimMove();
|
||||
void SlideMove();
|
||||
void AdjustFlyingAngles();
|
||||
void AddFlyBob( idVec3 &vel );
|
||||
void AdjustFlyHeight( idVec3 &vel, const idVec3 &goalPos );
|
||||
void FlySeekGoal( idVec3 &vel, idVec3 &goalPos );
|
||||
void AdjustFlySpeed( idVec3 &vel );
|
||||
void FlyTurn();
|
||||
void FlyMove();
|
||||
void StaticMove();
|
||||
|
||||
// damage
|
||||
virtual bool Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
|
||||
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
|
||||
|
||||
// navigation
|
||||
void KickObstacles( const idVec3 &dir, float force, idEntity *alwaysKick );
|
||||
bool ReachedPos( const idVec3 &pos, const moveCommand_t moveCommand ) const;
|
||||
float TravelDistance( const idVec3 &start, const idVec3 &end ) const;
|
||||
int PointReachableAreaNum( const idVec3 &pos, const float boundsScale = 2.0f ) const;
|
||||
bool PathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const;
|
||||
void DrawRoute() const;
|
||||
bool GetMovePos( idVec3 &seekPos );
|
||||
bool MoveDone() const;
|
||||
bool EntityCanSeePos( idActor *actor, const idVec3 &actorOrigin, const idVec3 &pos );
|
||||
void BlockedFailSafe();
|
||||
|
||||
// movement control
|
||||
void StopMove( moveStatus_t status );
|
||||
bool FaceEnemy();
|
||||
bool FaceEntity( idEntity *ent );
|
||||
bool DirectMoveToPosition( const idVec3 &pos );
|
||||
bool MoveToEnemyHeight();
|
||||
bool MoveOutOfRange( idEntity *entity, float range );
|
||||
bool MoveToAttackPosition( idEntity *ent, int attack_anim );
|
||||
bool MoveToEnemy();
|
||||
bool MoveToEntity( idEntity *ent );
|
||||
bool MoveToPosition( const idVec3 &pos );
|
||||
bool MoveToCover( idEntity *entity, const idVec3 &pos );
|
||||
bool SlideToPosition( const idVec3 &pos, float time );
|
||||
bool WanderAround();
|
||||
bool StepDirection( float dir );
|
||||
bool NewWanderDir( const idVec3 &dest );
|
||||
|
||||
// effects
|
||||
const idDeclParticle *SpawnParticlesOnJoint( particleEmitter_t &pe, const char *particleName, const char *jointName );
|
||||
void SpawnParticles( const char *keyName );
|
||||
bool ParticlesActive();
|
||||
|
||||
// turning
|
||||
bool FacingIdeal();
|
||||
void Turn();
|
||||
bool TurnToward( float yaw );
|
||||
bool TurnToward( const idVec3 &pos );
|
||||
|
||||
// enemy management
|
||||
void ClearEnemy();
|
||||
bool EnemyPositionValid() const;
|
||||
void SetEnemyPosition();
|
||||
void UpdateEnemyPosition();
|
||||
void SetEnemy( idActor *newEnemy );
|
||||
|
||||
// attacks
|
||||
void CreateProjectileClipModel() const;
|
||||
idProjectile *CreateProjectile( const idVec3 &pos, const idVec3 &dir );
|
||||
void RemoveProjectile();
|
||||
idProjectile *LaunchProjectile( const char *jointname, idEntity *target, bool clampToAttackCone );
|
||||
virtual void DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage );
|
||||
void DirectDamage( const char *meleeDefName, idEntity *ent );
|
||||
bool TestMelee() const;
|
||||
bool AttackMelee( const char *meleeDefName );
|
||||
void BeginAttack( const char *name );
|
||||
void EndAttack();
|
||||
void PushWithAF();
|
||||
|
||||
// special effects
|
||||
void GetMuzzle( const char *jointname, idVec3 &muzzle, idMat3 &axis );
|
||||
void InitMuzzleFlash();
|
||||
void TriggerWeaponEffects( const idVec3 &muzzle );
|
||||
void UpdateMuzzleFlash();
|
||||
virtual bool UpdateAnimationControllers();
|
||||
void UpdateParticles();
|
||||
void TriggerParticles( const char *jointName );
|
||||
|
||||
void TriggerFX( const char* joint, const char* fx );
|
||||
idEntity* StartEmitter( const char* name, const char* joint, const char* particle );
|
||||
idEntity* GetEmitter( const char* name );
|
||||
void StopEmitter( const char* name );
|
||||
|
||||
// AI script state management
|
||||
void LinkScriptVariables();
|
||||
void UpdateAIScript();
|
||||
|
||||
//
|
||||
// ai/ai_events.cpp
|
||||
//
|
||||
void Event_Activate( idEntity *activator );
|
||||
void Event_Touch( idEntity *other, trace_t *trace );
|
||||
void Event_FindEnemy( int useFOV );
|
||||
void Event_FindEnemyAI( int useFOV );
|
||||
void Event_FindEnemyInCombatNodes();
|
||||
void Event_ClosestReachableEnemyOfEntity( idEntity *team_mate );
|
||||
void Event_HeardSound( int ignore_team );
|
||||
void Event_SetEnemy( idEntity *ent );
|
||||
void Event_ClearEnemy();
|
||||
void Event_MuzzleFlash( const char *jointname );
|
||||
void Event_CreateMissile( const char *jointname );
|
||||
void Event_AttackMissile( const char *jointname );
|
||||
void Event_FireMissileAtTarget( const char *jointname, const char *targetname );
|
||||
void Event_LaunchMissile( const idVec3 &muzzle, const idAngles &ang );
|
||||
void Event_LaunchHomingMissile();
|
||||
void Event_SetHomingMissileGoal();
|
||||
void Event_LaunchProjectile( const char *entityDefName );
|
||||
void Event_AttackMelee( const char *meleeDefName );
|
||||
void Event_DirectDamage( idEntity *damageTarget, const char *damageDefName );
|
||||
void Event_RadiusDamageFromJoint( const char *jointname, const char *damageDefName );
|
||||
void Event_BeginAttack( const char *name );
|
||||
void Event_EndAttack();
|
||||
void Event_MeleeAttackToJoint( const char *jointname, const char *meleeDefName );
|
||||
void Event_RandomPath();
|
||||
void Event_CanBecomeSolid();
|
||||
void Event_BecomeSolid();
|
||||
void Event_BecomeNonSolid();
|
||||
void Event_BecomeRagdoll();
|
||||
void Event_StopRagdoll();
|
||||
void Event_SetHealth( float newHealth );
|
||||
void Event_GetHealth();
|
||||
void Event_AllowDamage();
|
||||
void Event_IgnoreDamage();
|
||||
void Event_GetCurrentYaw();
|
||||
void Event_TurnTo( float angle );
|
||||
void Event_TurnToPos( const idVec3 &pos );
|
||||
void Event_TurnToEntity( idEntity *ent );
|
||||
void Event_MoveStatus();
|
||||
void Event_StopMove();
|
||||
void Event_MoveToCover();
|
||||
void Event_MoveToEnemy();
|
||||
void Event_MoveToEnemyHeight();
|
||||
void Event_MoveOutOfRange( idEntity *entity, float range );
|
||||
void Event_MoveToAttackPosition( idEntity *entity, const char *attack_anim );
|
||||
void Event_MoveToEntity( idEntity *ent );
|
||||
void Event_MoveToPosition( const idVec3 &pos );
|
||||
void Event_SlideTo( const idVec3 &pos, float time );
|
||||
void Event_Wander();
|
||||
void Event_FacingIdeal();
|
||||
void Event_FaceEnemy();
|
||||
void Event_FaceEntity( idEntity *ent );
|
||||
void Event_WaitAction( const char *waitForState );
|
||||
void Event_GetCombatNode();
|
||||
void Event_EnemyInCombatCone( idEntity *ent, int use_current_enemy_location );
|
||||
void Event_WaitMove();
|
||||
void Event_GetJumpVelocity( const idVec3 &pos, float speed, float max_height );
|
||||
void Event_EntityInAttackCone( idEntity *ent );
|
||||
void Event_CanSeeEntity( idEntity *ent );
|
||||
void Event_SetTalkTarget( idEntity *target );
|
||||
void Event_GetTalkTarget();
|
||||
void Event_SetTalkState( int state );
|
||||
void Event_EnemyRange();
|
||||
void Event_EnemyRange2D();
|
||||
void Event_GetEnemy();
|
||||
void Event_GetEnemyPos();
|
||||
void Event_GetEnemyEyePos();
|
||||
void Event_PredictEnemyPos( float time );
|
||||
void Event_CanHitEnemy();
|
||||
void Event_CanHitEnemyFromAnim( const char *animname );
|
||||
void Event_CanHitEnemyFromJoint( const char *jointname );
|
||||
void Event_EnemyPositionValid();
|
||||
void Event_ChargeAttack( const char *damageDef );
|
||||
void Event_TestChargeAttack();
|
||||
void Event_TestAnimMoveTowardEnemy( const char *animname );
|
||||
void Event_TestAnimMove( const char *animname );
|
||||
void Event_TestMoveToPosition( const idVec3 &position );
|
||||
void Event_TestMeleeAttack();
|
||||
void Event_TestAnimAttack( const char *animname );
|
||||
void Event_Burn();
|
||||
void Event_PreBurn();
|
||||
void Event_ClearBurn();
|
||||
void Event_SetSmokeVisibility( int num, int on );
|
||||
void Event_NumSmokeEmitters();
|
||||
void Event_StopThinking();
|
||||
void Event_GetTurnDelta();
|
||||
void Event_GetMoveType();
|
||||
void Event_SetMoveType( int moveType );
|
||||
void Event_SaveMove();
|
||||
void Event_RestoreMove();
|
||||
void Event_AllowMovement( float flag );
|
||||
void Event_JumpFrame();
|
||||
void Event_EnableClip();
|
||||
void Event_DisableClip();
|
||||
void Event_EnableGravity();
|
||||
void Event_DisableGravity();
|
||||
void Event_EnableAFPush();
|
||||
void Event_DisableAFPush();
|
||||
void Event_SetFlySpeed( float speed );
|
||||
void Event_SetFlyOffset( int offset );
|
||||
void Event_ClearFlyOffset();
|
||||
void Event_GetClosestHiddenTarget( const char *type );
|
||||
void Event_GetRandomTarget( const char *type );
|
||||
void Event_TravelDistanceToPoint( const idVec3 &pos );
|
||||
void Event_TravelDistanceToEntity( idEntity *ent );
|
||||
void Event_TravelDistanceBetweenPoints( const idVec3 &source, const idVec3 &dest );
|
||||
void Event_TravelDistanceBetweenEntities( idEntity *source, idEntity *dest );
|
||||
void Event_LookAtEntity( idEntity *ent, float duration );
|
||||
void Event_LookAtEnemy( float duration );
|
||||
void Event_SetJointMod( int allowJointMod );
|
||||
void Event_ThrowMoveable();
|
||||
void Event_ThrowAF();
|
||||
void Event_SetAngles( idAngles const &ang );
|
||||
void Event_GetAngles();
|
||||
void Event_GetTrajectoryToPlayer();
|
||||
void Event_RealKill();
|
||||
void Event_Kill();
|
||||
void Event_WakeOnFlashlight( int enable );
|
||||
void Event_LocateEnemy();
|
||||
void Event_KickObstacles( idEntity *kickEnt, float force );
|
||||
void Event_GetObstacle();
|
||||
void Event_PushPointIntoAAS( const idVec3 &pos );
|
||||
void Event_GetTurnRate();
|
||||
void Event_SetTurnRate( float rate );
|
||||
void Event_AnimTurn( float angles );
|
||||
void Event_AllowHiddenMovement( int enable );
|
||||
void Event_TriggerParticles( const char *jointName );
|
||||
void Event_FindActorsInBounds( const idVec3 &mins, const idVec3 &maxs );
|
||||
void Event_CanReachPosition( const idVec3 &pos );
|
||||
void Event_CanReachEntity( idEntity *ent );
|
||||
void Event_CanReachEnemy();
|
||||
void Event_GetReachableEntityPosition( idEntity *ent );
|
||||
void Event_MoveToPositionDirect( const idVec3 &pos );
|
||||
void Event_AvoidObstacles( int ignore);
|
||||
void Event_TriggerFX( const char* joint, const char* fx );
|
||||
|
||||
void Event_StartEmitter( const char* name, const char* joint, const char* particle );
|
||||
void Event_GetEmitter( const char* name );
|
||||
void Event_StopEmitter( const char* name );
|
||||
};
|
||||
|
||||
class idCombatNode : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idCombatNode );
|
||||
|
||||
idCombatNode();
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
bool IsDisabled() const;
|
||||
bool EntityInView( idActor *actor, const idVec3 &pos );
|
||||
static void DrawDebugInfo();
|
||||
|
||||
private:
|
||||
float min_dist;
|
||||
float max_dist;
|
||||
float cone_dist;
|
||||
float min_height;
|
||||
float max_height;
|
||||
idVec3 cone_left;
|
||||
idVec3 cone_right;
|
||||
idVec3 offset;
|
||||
bool disabled;
|
||||
|
||||
void Event_Activate( idEntity *activator );
|
||||
void Event_MarkUsed();
|
||||
};
|
||||
|
||||
#endif /* !__AI_H__ */
|
||||
149
neo/d3xp/ai/AI_Vagary.cpp
Normal file
149
neo/d3xp/ai/AI_Vagary.cpp
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
/***********************************************************************
|
||||
|
||||
game/ai/AI_Vagary.cpp
|
||||
|
||||
Vagary specific AI code
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#pragma hdrstop
|
||||
#include "../../idlib/precompiled.h"
|
||||
|
||||
|
||||
#include "../Game_local.h"
|
||||
|
||||
class idAI_Vagary : public idAI {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idAI_Vagary );
|
||||
|
||||
private:
|
||||
void Event_ChooseObjectToThrow( const idVec3 &mins, const idVec3 &maxs, float speed, float minDist, float offset );
|
||||
void Event_ThrowObjectAtEnemy( idEntity *ent, float speed );
|
||||
};
|
||||
|
||||
const idEventDef AI_Vagary_ChooseObjectToThrow( "vagary_ChooseObjectToThrow", "vvfff", 'e' );
|
||||
const idEventDef AI_Vagary_ThrowObjectAtEnemy( "vagary_ThrowObjectAtEnemy", "ef" );
|
||||
|
||||
CLASS_DECLARATION( idAI, idAI_Vagary )
|
||||
EVENT( AI_Vagary_ChooseObjectToThrow, idAI_Vagary::Event_ChooseObjectToThrow )
|
||||
EVENT( AI_Vagary_ThrowObjectAtEnemy, idAI_Vagary::Event_ThrowObjectAtEnemy )
|
||||
END_CLASS
|
||||
|
||||
/*
|
||||
================
|
||||
idAI_Vagary::Event_ChooseObjectToThrow
|
||||
================
|
||||
*/
|
||||
void idAI_Vagary::Event_ChooseObjectToThrow( const idVec3 &mins, const idVec3 &maxs, float speed, float minDist, float offset ) {
|
||||
idEntity * ent;
|
||||
idEntity * entityList[ MAX_GENTITIES ];
|
||||
int numListedEntities;
|
||||
int i, index;
|
||||
float dist;
|
||||
idVec3 vel;
|
||||
idVec3 offsetVec( 0, 0, offset );
|
||||
idEntity *enemyEnt = enemy.GetEntity();
|
||||
|
||||
if ( !enemyEnt ) {
|
||||
idThread::ReturnEntity( NULL );
|
||||
return;
|
||||
}
|
||||
|
||||
idVec3 enemyEyePos = lastVisibleEnemyPos + lastVisibleEnemyEyeOffset;
|
||||
const idBounds &myBounds = physicsObj.GetAbsBounds();
|
||||
idBounds checkBounds( mins, maxs );
|
||||
checkBounds.TranslateSelf( physicsObj.GetOrigin() );
|
||||
numListedEntities = gameLocal.clip.EntitiesTouchingBounds( checkBounds, -1, entityList, MAX_GENTITIES );
|
||||
|
||||
index = gameLocal.random.RandomInt( numListedEntities );
|
||||
for ( i = 0; i < numListedEntities; i++, index++ ) {
|
||||
if ( index >= numListedEntities ) {
|
||||
index = 0;
|
||||
}
|
||||
ent = entityList[ index ];
|
||||
if ( !ent->IsType( idMoveable::Type ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ent->fl.hidden ) {
|
||||
// don't throw hidden objects
|
||||
continue;
|
||||
}
|
||||
|
||||
idPhysics *entPhys = ent->GetPhysics();
|
||||
const idVec3 &entOrg = entPhys->GetOrigin();
|
||||
dist = ( entOrg - enemyEyePos ).LengthFast();
|
||||
if ( dist < minDist ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
idBounds expandedBounds = myBounds.Expand( entPhys->GetBounds().GetRadius() );
|
||||
if ( expandedBounds.LineIntersection( entOrg, enemyEyePos ) ) {
|
||||
// ignore objects that are behind us
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( PredictTrajectory( entPhys->GetOrigin() + offsetVec, enemyEyePos, speed, entPhys->GetGravity(),
|
||||
entPhys->GetClipModel(), entPhys->GetClipMask(), MAX_WORLD_SIZE, NULL, enemyEnt, ai_debugTrajectory.GetBool() ? 4000 : 0, vel ) ) {
|
||||
idThread::ReturnEntity( ent );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
idThread::ReturnEntity( NULL );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idAI_Vagary::Event_ThrowObjectAtEnemy
|
||||
================
|
||||
*/
|
||||
void idAI_Vagary::Event_ThrowObjectAtEnemy( idEntity *ent, float speed ) {
|
||||
idVec3 vel;
|
||||
idEntity *enemyEnt;
|
||||
idPhysics *entPhys;
|
||||
|
||||
entPhys = ent->GetPhysics();
|
||||
enemyEnt = enemy.GetEntity();
|
||||
if ( !enemyEnt ) {
|
||||
vel = ( viewAxis[ 0 ] * physicsObj.GetGravityAxis() ) * speed;
|
||||
} else {
|
||||
PredictTrajectory( entPhys->GetOrigin(), lastVisibleEnemyPos + lastVisibleEnemyEyeOffset, speed, entPhys->GetGravity(),
|
||||
entPhys->GetClipModel(), entPhys->GetClipMask(), MAX_WORLD_SIZE, NULL, enemyEnt, ai_debugTrajectory.GetBool() ? 4000 : 0, vel );
|
||||
vel *= speed;
|
||||
}
|
||||
|
||||
entPhys->SetLinearVelocity( vel );
|
||||
|
||||
if ( ent->IsType( idMoveable::Type ) ) {
|
||||
idMoveable *ment = static_cast<idMoveable*>( ent );
|
||||
ment->EnableDamage( true, 2.5f );
|
||||
}
|
||||
}
|
||||
2986
neo/d3xp/ai/AI_events.cpp
Normal file
2986
neo/d3xp/ai/AI_events.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1535
neo/d3xp/ai/AI_pathing.cpp
Normal file
1535
neo/d3xp/ai/AI_pathing.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1177
neo/d3xp/anim/Anim.cpp
Normal file
1177
neo/d3xp/anim/Anim.cpp
Normal file
File diff suppressed because it is too large
Load Diff
598
neo/d3xp/anim/Anim.h
Normal file
598
neo/d3xp/anim/Anim.h
Normal file
@@ -0,0 +1,598 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#ifndef __ANIM_H__
|
||||
#define __ANIM_H__
|
||||
|
||||
//
|
||||
// animation channels
|
||||
// these can be changed by modmakers and licensees to be whatever they need.
|
||||
const int ANIM_NumAnimChannels = 5;
|
||||
const int ANIM_MaxAnimsPerChannel = 3;
|
||||
const int ANIM_MaxSyncedAnims = 3;
|
||||
|
||||
//
|
||||
// animation channels. make sure to change script/doom_defs.script if you add any channels, or change their order
|
||||
//
|
||||
const int ANIMCHANNEL_ALL = 0;
|
||||
const int ANIMCHANNEL_TORSO = 1;
|
||||
const int ANIMCHANNEL_LEGS = 2;
|
||||
const int ANIMCHANNEL_HEAD = 3;
|
||||
const int ANIMCHANNEL_EYELIDS = 4;
|
||||
|
||||
// for converting from 24 frames per second to milliseconds
|
||||
ID_INLINE int FRAME2MS( int framenum ) {
|
||||
return ( framenum * 1000 ) / 24;
|
||||
}
|
||||
|
||||
class idRenderModel;
|
||||
class idAnimator;
|
||||
class idAnimBlend;
|
||||
class function_t;
|
||||
class idEntity;
|
||||
class idSaveGame;
|
||||
class idRestoreGame;
|
||||
|
||||
typedef struct {
|
||||
int cycleCount; // how many times the anim has wrapped to the begining (0 for clamped anims)
|
||||
int frame1;
|
||||
int frame2;
|
||||
float frontlerp;
|
||||
float backlerp;
|
||||
} frameBlend_t;
|
||||
|
||||
typedef struct {
|
||||
int nameIndex;
|
||||
int parentNum;
|
||||
int animBits;
|
||||
int firstComponent;
|
||||
} jointAnimInfo_t;
|
||||
|
||||
typedef struct {
|
||||
jointHandle_t num;
|
||||
jointHandle_t parentNum;
|
||||
int channel;
|
||||
} jointInfo_t;
|
||||
|
||||
//
|
||||
// joint modifier modes. make sure to change script/doom_defs.script if you add any, or change their order.
|
||||
//
|
||||
typedef enum {
|
||||
JOINTMOD_NONE, // no modification
|
||||
JOINTMOD_LOCAL, // modifies the joint's position or orientation in joint local space
|
||||
JOINTMOD_LOCAL_OVERRIDE, // sets the joint's position or orientation in joint local space
|
||||
JOINTMOD_WORLD, // modifies joint's position or orientation in model space
|
||||
JOINTMOD_WORLD_OVERRIDE // sets the joint's position or orientation in model space
|
||||
} jointModTransform_t;
|
||||
|
||||
typedef struct {
|
||||
jointHandle_t jointnum;
|
||||
idMat3 mat;
|
||||
idVec3 pos;
|
||||
jointModTransform_t transform_pos;
|
||||
jointModTransform_t transform_axis;
|
||||
} jointMod_t;
|
||||
|
||||
#define ANIM_BIT_TX 0
|
||||
#define ANIM_BIT_TY 1
|
||||
#define ANIM_BIT_TZ 2
|
||||
#define ANIM_BIT_QX 3
|
||||
#define ANIM_BIT_QY 4
|
||||
#define ANIM_BIT_QZ 5
|
||||
|
||||
#define ANIM_TX BIT( ANIM_BIT_TX )
|
||||
#define ANIM_TY BIT( ANIM_BIT_TY )
|
||||
#define ANIM_TZ BIT( ANIM_BIT_TZ )
|
||||
#define ANIM_QX BIT( ANIM_BIT_QX )
|
||||
#define ANIM_QY BIT( ANIM_BIT_QY )
|
||||
#define ANIM_QZ BIT( ANIM_BIT_QZ )
|
||||
|
||||
typedef enum {
|
||||
FC_SCRIPTFUNCTION,
|
||||
FC_SCRIPTFUNCTIONOBJECT,
|
||||
FC_EVENTFUNCTION,
|
||||
FC_SOUND,
|
||||
FC_SOUND_VOICE,
|
||||
FC_SOUND_VOICE2,
|
||||
FC_SOUND_BODY,
|
||||
FC_SOUND_BODY2,
|
||||
FC_SOUND_BODY3,
|
||||
FC_SOUND_WEAPON,
|
||||
FC_SOUND_ITEM,
|
||||
FC_SOUND_GLOBAL,
|
||||
FC_SOUND_CHATTER,
|
||||
FC_SKIN,
|
||||
FC_TRIGGER,
|
||||
FC_TRIGGER_SMOKE_PARTICLE,
|
||||
FC_MELEE,
|
||||
FC_DIRECTDAMAGE,
|
||||
FC_BEGINATTACK,
|
||||
FC_ENDATTACK,
|
||||
FC_MUZZLEFLASH,
|
||||
FC_CREATEMISSILE,
|
||||
FC_LAUNCHMISSILE,
|
||||
FC_FIREMISSILEATTARGET,
|
||||
FC_FOOTSTEP,
|
||||
FC_LEFTFOOT,
|
||||
FC_RIGHTFOOT,
|
||||
FC_ENABLE_EYE_FOCUS,
|
||||
FC_DISABLE_EYE_FOCUS,
|
||||
FC_FX,
|
||||
FC_DISABLE_GRAVITY,
|
||||
FC_ENABLE_GRAVITY,
|
||||
FC_JUMP,
|
||||
FC_ENABLE_CLIP,
|
||||
FC_DISABLE_CLIP,
|
||||
FC_ENABLE_WALK_IK,
|
||||
FC_DISABLE_WALK_IK,
|
||||
FC_ENABLE_LEG_IK,
|
||||
FC_DISABLE_LEG_IK,
|
||||
FC_RECORDDEMO,
|
||||
FC_AVIGAME
|
||||
, FC_LAUNCH_PROJECTILE,
|
||||
FC_TRIGGER_FX,
|
||||
FC_START_EMITTER,
|
||||
FC_STOP_EMITTER,
|
||||
} frameCommandType_t;
|
||||
|
||||
typedef struct {
|
||||
int num;
|
||||
int firstCommand;
|
||||
} frameLookup_t;
|
||||
|
||||
typedef struct {
|
||||
frameCommandType_t type;
|
||||
idStr *string;
|
||||
|
||||
union {
|
||||
const idSoundShader *soundShader;
|
||||
const function_t *function;
|
||||
const idDeclSkin *skin;
|
||||
int index;
|
||||
};
|
||||
} frameCommand_t;
|
||||
|
||||
typedef struct {
|
||||
bool prevent_idle_override : 1;
|
||||
bool random_cycle_start : 1;
|
||||
bool ai_no_turn : 1;
|
||||
bool anim_turn : 1;
|
||||
} animFlags_t;
|
||||
|
||||
/*
|
||||
==============================================================================================
|
||||
|
||||
idMD5Anim
|
||||
|
||||
==============================================================================================
|
||||
*/
|
||||
|
||||
class idMD5Anim {
|
||||
private:
|
||||
int numFrames;
|
||||
int frameRate;
|
||||
int animLength;
|
||||
int numJoints;
|
||||
int numAnimatedComponents;
|
||||
idList<idBounds, TAG_MD5_ANIM> bounds;
|
||||
idList<jointAnimInfo_t, TAG_MD5_ANIM> jointInfo;
|
||||
idList<idJointQuat, TAG_MD5_ANIM> baseFrame;
|
||||
idList<float, TAG_MD5_ANIM> componentFrames;
|
||||
idStr name;
|
||||
idVec3 totaldelta;
|
||||
mutable int ref_count;
|
||||
|
||||
public:
|
||||
idMD5Anim();
|
||||
~idMD5Anim();
|
||||
|
||||
void Free();
|
||||
bool Reload();
|
||||
size_t Allocated() const;
|
||||
size_t Size() const { return sizeof( *this ) + Allocated(); };
|
||||
bool LoadAnim( const char *filename );
|
||||
bool LoadBinary( idFile * file, ID_TIME_T sourceTimeStamp );
|
||||
void WriteBinary( idFile * file, ID_TIME_T sourceTimeStamp );
|
||||
|
||||
void IncreaseRefs() const;
|
||||
void DecreaseRefs() const;
|
||||
int NumRefs() const;
|
||||
|
||||
void CheckModelHierarchy( const idRenderModel *model ) const;
|
||||
void GetInterpolatedFrame( frameBlend_t &frame, idJointQuat *joints, const int *index, int numIndexes ) const;
|
||||
void GetSingleFrame( int framenum, idJointQuat *joints, const int *index, int numIndexes ) const;
|
||||
int Length() const;
|
||||
int NumFrames() const;
|
||||
int NumJoints() const;
|
||||
const idVec3 &TotalMovementDelta() const;
|
||||
const char *Name() const;
|
||||
|
||||
void GetFrameBlend( int framenum, frameBlend_t &frame ) const; // frame 1 is first frame
|
||||
void ConvertTimeToFrame( int time, int cyclecount, frameBlend_t &frame ) const;
|
||||
|
||||
void GetOrigin( idVec3 &offset, int currentTime, int cyclecount ) const;
|
||||
void GetOriginRotation( idQuat &rotation, int time, int cyclecount ) const;
|
||||
void GetBounds( idBounds &bounds, int currentTime, int cyclecount ) const;
|
||||
};
|
||||
|
||||
/*
|
||||
==============================================================================================
|
||||
|
||||
idAnim
|
||||
|
||||
==============================================================================================
|
||||
*/
|
||||
|
||||
class idAnim {
|
||||
private:
|
||||
const class idDeclModelDef *modelDef;
|
||||
const idMD5Anim *anims[ ANIM_MaxSyncedAnims ];
|
||||
int numAnims;
|
||||
idStr name;
|
||||
idStr realname;
|
||||
idList<frameLookup_t, TAG_ANIM> frameLookup;
|
||||
idList<frameCommand_t, TAG_ANIM> frameCommands;
|
||||
animFlags_t flags;
|
||||
|
||||
public:
|
||||
idAnim();
|
||||
idAnim( const idDeclModelDef *modelDef, const idAnim *anim );
|
||||
~idAnim();
|
||||
|
||||
void SetAnim( const idDeclModelDef *modelDef, const char *sourcename, const char *animname, int num, const idMD5Anim *md5anims[ ANIM_MaxSyncedAnims ] );
|
||||
const char *Name() const;
|
||||
const char *FullName() const;
|
||||
const idMD5Anim *MD5Anim( int num ) const;
|
||||
const idDeclModelDef *ModelDef() const;
|
||||
int Length() const;
|
||||
int NumFrames() const;
|
||||
int NumAnims() const;
|
||||
const idVec3 &TotalMovementDelta() const;
|
||||
bool GetOrigin( idVec3 &offset, int animNum, int time, int cyclecount ) const;
|
||||
bool GetOriginRotation( idQuat &rotation, int animNum, int currentTime, int cyclecount ) const;
|
||||
bool GetBounds( idBounds &bounds, int animNum, int time, int cyclecount ) const;
|
||||
const char *AddFrameCommand( const class idDeclModelDef *modelDef, int framenum, idLexer &src, const idDict *def );
|
||||
void CallFrameCommands( idEntity *ent, int from, int to ) const;
|
||||
bool HasFrameCommands() const;
|
||||
|
||||
// returns first frame (zero based) that command occurs. returns -1 if not found.
|
||||
int FindFrameForFrameCommand( frameCommandType_t framecommand, const frameCommand_t **command ) const;
|
||||
void SetAnimFlags( const animFlags_t &animflags );
|
||||
const animFlags_t &GetAnimFlags() const;
|
||||
};
|
||||
|
||||
/*
|
||||
==============================================================================================
|
||||
|
||||
idDeclModelDef
|
||||
|
||||
==============================================================================================
|
||||
*/
|
||||
|
||||
class idDeclModelDef : public idDecl {
|
||||
public:
|
||||
idDeclModelDef();
|
||||
~idDeclModelDef();
|
||||
|
||||
virtual size_t Size() const;
|
||||
virtual const char * DefaultDefinition() const;
|
||||
virtual bool Parse( const char *text, const int textLength, bool allowBinaryVersion );
|
||||
virtual void FreeData();
|
||||
|
||||
void Touch() const;
|
||||
|
||||
const idDeclSkin * GetDefaultSkin() const;
|
||||
const idJointQuat * GetDefaultPose() const;
|
||||
void SetupJoints( int *numJoints, idJointMat **jointList, idBounds &frameBounds, bool removeOriginOffset ) const;
|
||||
idRenderModel * ModelHandle() const;
|
||||
void GetJointList( const char *jointnames, idList<jointHandle_t> &jointList ) const;
|
||||
const jointInfo_t * FindJoint( const char *name ) const;
|
||||
|
||||
int NumAnims() const;
|
||||
const idAnim * GetAnim( int index ) const;
|
||||
int GetSpecificAnim( const char *name ) const;
|
||||
int GetAnim( const char *name ) const;
|
||||
bool HasAnim( const char *name ) const;
|
||||
const idDeclSkin * GetSkin() const;
|
||||
const char * GetModelName() const;
|
||||
const idList<jointInfo_t> & Joints() const;
|
||||
const int * JointParents() const;
|
||||
int NumJoints() const;
|
||||
const jointInfo_t * GetJoint( int jointHandle ) const;
|
||||
const char * GetJointName( int jointHandle ) const;
|
||||
int NumJointsOnChannel( int channel ) const;
|
||||
const int * GetChannelJoints( int channel ) const;
|
||||
|
||||
const idVec3 & GetVisualOffset() const;
|
||||
|
||||
private:
|
||||
void CopyDecl( const idDeclModelDef *decl );
|
||||
bool ParseAnim( idLexer &src, int numDefaultAnims );
|
||||
|
||||
private:
|
||||
idVec3 offset;
|
||||
idList<jointInfo_t, TAG_ANIM> joints;
|
||||
idList<int, TAG_ANIM> jointParents;
|
||||
idList<int, TAG_ANIM> channelJoints[ ANIM_NumAnimChannels ];
|
||||
idRenderModel * modelHandle;
|
||||
idList<idAnim *, TAG_ANIM> anims;
|
||||
const idDeclSkin * skin;
|
||||
};
|
||||
|
||||
/*
|
||||
==============================================================================================
|
||||
|
||||
idAnimBlend
|
||||
|
||||
==============================================================================================
|
||||
*/
|
||||
|
||||
class idAnimBlend {
|
||||
private:
|
||||
const class idDeclModelDef *modelDef;
|
||||
int starttime;
|
||||
int endtime;
|
||||
int timeOffset;
|
||||
float rate;
|
||||
|
||||
int blendStartTime;
|
||||
int blendDuration;
|
||||
float blendStartValue;
|
||||
float blendEndValue;
|
||||
|
||||
float animWeights[ ANIM_MaxSyncedAnims ];
|
||||
short cycle;
|
||||
short frame;
|
||||
short animNum;
|
||||
bool allowMove;
|
||||
bool allowFrameCommands;
|
||||
|
||||
friend class idAnimator;
|
||||
|
||||
void Reset( const idDeclModelDef *_modelDef );
|
||||
void CallFrameCommands( idEntity *ent, int fromtime, int totime ) const;
|
||||
void SetFrame( const idDeclModelDef *modelDef, int animnum, int frame, int currenttime, int blendtime );
|
||||
void CycleAnim( const idDeclModelDef *modelDef, int animnum, int currenttime, int blendtime );
|
||||
void PlayAnim( const idDeclModelDef *modelDef, int animnum, int currenttime, int blendtime );
|
||||
bool BlendAnim( int currentTime, int channel, int numJoints, idJointQuat *blendFrame, float &blendWeight, bool removeOrigin, bool overrideBlend, bool printInfo ) const;
|
||||
void BlendOrigin( int currentTime, idVec3 &blendPos, float &blendWeight, bool removeOriginOffset ) const;
|
||||
void BlendDelta( int fromtime, int totime, idVec3 &blendDelta, float &blendWeight ) const;
|
||||
void BlendDeltaRotation( int fromtime, int totime, idQuat &blendDelta, float &blendWeight ) const;
|
||||
bool AddBounds( int currentTime, idBounds &bounds, bool removeOriginOffset ) const;
|
||||
|
||||
public:
|
||||
idAnimBlend();
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile, const idDeclModelDef *modelDef );
|
||||
const char *AnimName() const;
|
||||
const char *AnimFullName() const;
|
||||
float GetWeight( int currenttime ) const;
|
||||
float GetFinalWeight() const;
|
||||
void SetWeight( float newweight, int currenttime, int blendtime );
|
||||
int NumSyncedAnims() const;
|
||||
bool SetSyncedAnimWeight( int num, float weight );
|
||||
void Clear( int currentTime, int clearTime );
|
||||
bool IsDone( int currentTime ) const;
|
||||
bool FrameHasChanged( int currentTime ) const;
|
||||
int GetCycleCount() const;
|
||||
void SetCycleCount( int count );
|
||||
void SetPlaybackRate( int currentTime, float newRate );
|
||||
float GetPlaybackRate() const;
|
||||
void SetStartTime( int startTime );
|
||||
int GetStartTime() const;
|
||||
int GetEndTime() const;
|
||||
int GetFrameNumber( int currenttime ) const;
|
||||
int AnimTime( int currenttime ) const;
|
||||
int NumFrames() const;
|
||||
int Length() const;
|
||||
int PlayLength() const;
|
||||
void AllowMovement( bool allow );
|
||||
void AllowFrameCommands( bool allow );
|
||||
const idAnim *Anim() const;
|
||||
int AnimNum() const;
|
||||
};
|
||||
|
||||
/*
|
||||
==============================================================================================
|
||||
|
||||
idAFPoseJointMod
|
||||
|
||||
==============================================================================================
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
AF_JOINTMOD_AXIS,
|
||||
AF_JOINTMOD_ORIGIN,
|
||||
AF_JOINTMOD_BOTH
|
||||
} AFJointModType_t;
|
||||
|
||||
class idAFPoseJointMod {
|
||||
public:
|
||||
idAFPoseJointMod();
|
||||
|
||||
AFJointModType_t mod;
|
||||
idMat3 axis;
|
||||
idVec3 origin;
|
||||
};
|
||||
|
||||
ID_INLINE idAFPoseJointMod::idAFPoseJointMod() {
|
||||
mod = AF_JOINTMOD_AXIS;
|
||||
axis.Identity();
|
||||
origin.Zero();
|
||||
}
|
||||
|
||||
/*
|
||||
==============================================================================================
|
||||
|
||||
idAnimator
|
||||
|
||||
==============================================================================================
|
||||
*/
|
||||
|
||||
class idAnimator {
|
||||
public:
|
||||
idAnimator();
|
||||
~idAnimator();
|
||||
|
||||
size_t Allocated() const;
|
||||
size_t Size() const;
|
||||
|
||||
void Save( idSaveGame *savefile ) const; // archives object for save game file
|
||||
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
|
||||
|
||||
void SetEntity( idEntity *ent );
|
||||
idEntity *GetEntity() const ;
|
||||
void RemoveOriginOffset( bool remove );
|
||||
bool RemoveOrigin() const;
|
||||
|
||||
void GetJointList( const char *jointnames, idList<jointHandle_t> &jointList ) const;
|
||||
|
||||
int NumAnims() const;
|
||||
const idAnim *GetAnim( int index ) const;
|
||||
int GetAnim( const char *name ) const;
|
||||
bool HasAnim( const char *name ) const;
|
||||
|
||||
void ServiceAnims( int fromtime, int totime );
|
||||
bool IsAnimating( int currentTime ) const;
|
||||
|
||||
void GetJoints( int *numJoints, idJointMat **jointsPtr );
|
||||
int NumJoints() const;
|
||||
jointHandle_t GetFirstChild( jointHandle_t jointnum ) const;
|
||||
jointHandle_t GetFirstChild( const char *name ) const;
|
||||
|
||||
idRenderModel *SetModel( const char *modelname );
|
||||
idRenderModel *ModelHandle() const;
|
||||
const idDeclModelDef *ModelDef() const;
|
||||
|
||||
void ForceUpdate();
|
||||
void ClearForceUpdate();
|
||||
bool CreateFrame( int animtime, bool force );
|
||||
bool FrameHasChanged( int animtime ) const;
|
||||
void GetDelta( int fromtime, int totime, idVec3 &delta ) const;
|
||||
bool GetDeltaRotation( int fromtime, int totime, idMat3 &delta ) const;
|
||||
void GetOrigin( int currentTime, idVec3 &pos ) const;
|
||||
bool GetBounds( int currentTime, idBounds &bounds );
|
||||
|
||||
idAnimBlend *CurrentAnim( int channelNum );
|
||||
void Clear( int channelNum, int currentTime, int cleartime );
|
||||
void SetFrame( int channelNum, int animnum, int frame, int currenttime, int blendtime );
|
||||
void CycleAnim( int channelNum, int animnum, int currenttime, int blendtime );
|
||||
void PlayAnim( int channelNum, int animnum, int currenttime, int blendTime );
|
||||
|
||||
// copies the current anim from fromChannelNum to channelNum.
|
||||
// the copied anim will have frame commands disabled to avoid executing them twice.
|
||||
void SyncAnimChannels( int channelNum, int fromChannelNum, int currenttime, int blendTime );
|
||||
|
||||
void SetJointPos( jointHandle_t jointnum, jointModTransform_t transform_type, const idVec3 &pos );
|
||||
void SetJointAxis( jointHandle_t jointnum, jointModTransform_t transform_type, const idMat3 &mat );
|
||||
void ClearJoint( jointHandle_t jointnum );
|
||||
void ClearAllJoints();
|
||||
|
||||
void InitAFPose();
|
||||
void SetAFPoseJointMod( const jointHandle_t jointNum, const AFJointModType_t mod, const idMat3 &axis, const idVec3 &origin );
|
||||
void FinishAFPose( int animnum, const idBounds &bounds, const int time );
|
||||
void SetAFPoseBlendWeight( float blendWeight );
|
||||
bool BlendAFPose( idJointQuat *blendFrame ) const;
|
||||
void ClearAFPose();
|
||||
|
||||
void ClearAllAnims( int currentTime, int cleartime );
|
||||
|
||||
jointHandle_t GetJointHandle( const char *name ) const;
|
||||
const char * GetJointName( jointHandle_t handle ) const;
|
||||
int GetChannelForJoint( jointHandle_t joint ) const;
|
||||
bool GetJointTransform( jointHandle_t jointHandle, int currenttime, idVec3 &offset, idMat3 &axis );
|
||||
bool GetJointLocalTransform( jointHandle_t jointHandle, int currentTime, idVec3 &offset, idMat3 &axis );
|
||||
|
||||
const animFlags_t GetAnimFlags( int animnum ) const;
|
||||
int NumFrames( int animnum ) const;
|
||||
int NumSyncedAnims( int animnum ) const;
|
||||
const char *AnimName( int animnum ) const;
|
||||
const char *AnimFullName( int animnum ) const;
|
||||
int AnimLength( int animnum ) const;
|
||||
const idVec3 &TotalMovementDelta( int animnum ) const;
|
||||
|
||||
private:
|
||||
void FreeData();
|
||||
void PushAnims( int channel, int currentTime, int blendTime );
|
||||
|
||||
private:
|
||||
const idDeclModelDef * modelDef;
|
||||
idEntity * entity;
|
||||
|
||||
idAnimBlend channels[ ANIM_NumAnimChannels ][ ANIM_MaxAnimsPerChannel ];
|
||||
idList<jointMod_t *, TAG_ANIM> jointMods;
|
||||
int numJoints;
|
||||
idJointMat * joints;
|
||||
|
||||
mutable int lastTransformTime; // mutable because the value is updated in CreateFrame
|
||||
mutable bool stoppedAnimatingUpdate;
|
||||
bool removeOriginOffset;
|
||||
bool forceUpdate;
|
||||
|
||||
idBounds frameBounds;
|
||||
|
||||
float AFPoseBlendWeight;
|
||||
idList<int, TAG_ANIM> AFPoseJoints;
|
||||
idList<idAFPoseJointMod, TAG_ANIM> AFPoseJointMods;
|
||||
idList<idJointQuat, TAG_ANIM> AFPoseJointFrame;
|
||||
idBounds AFPoseBounds;
|
||||
int AFPoseTime;
|
||||
};
|
||||
|
||||
/*
|
||||
==============================================================================================
|
||||
|
||||
idAnimManager
|
||||
|
||||
==============================================================================================
|
||||
*/
|
||||
|
||||
class idAnimManager {
|
||||
public:
|
||||
idAnimManager();
|
||||
~idAnimManager();
|
||||
|
||||
static bool forceExport;
|
||||
|
||||
void Shutdown();
|
||||
idMD5Anim * GetAnim( const char *name );
|
||||
void Preload( const idPreloadManifest &manifest );
|
||||
void ReloadAnims();
|
||||
void ListAnims() const;
|
||||
int JointIndex( const char *name );
|
||||
const char * JointName( int index ) const;
|
||||
|
||||
void ClearAnimsInUse();
|
||||
void FlushUnusedAnims();
|
||||
|
||||
private:
|
||||
idHashTable<idMD5Anim *> animations;
|
||||
idStrList jointnames;
|
||||
idHashIndex jointnamesHash;
|
||||
};
|
||||
|
||||
#endif /* !__ANIM_H__ */
|
||||
5114
neo/d3xp/anim/Anim_Blend.cpp
Normal file
5114
neo/d3xp/anim/Anim_Blend.cpp
Normal file
File diff suppressed because it is too large
Load Diff
901
neo/d3xp/anim/Anim_Testmodel.cpp
Normal file
901
neo/d3xp/anim/Anim_Testmodel.cpp
Normal file
@@ -0,0 +1,901 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
MODEL TESTING
|
||||
|
||||
Model viewing can begin with either "testmodel <modelname>"
|
||||
|
||||
The names must be the full pathname after the basedir, like
|
||||
"models/weapons/v_launch/tris.md3" or "players/male/tris.md3"
|
||||
|
||||
Extension will default to ".ase" if not specified.
|
||||
|
||||
Testmodel will create a fake entity 100 units in front of the current view
|
||||
position, directly facing the viewer. It will remain immobile, so you can
|
||||
move around it to view it from different angles.
|
||||
|
||||
g_testModelRotate
|
||||
g_testModelAnimate
|
||||
g_testModelBlend
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
#pragma hdrstop
|
||||
#include "../../idlib/precompiled.h"
|
||||
|
||||
|
||||
#include "../Game_local.h"
|
||||
|
||||
CLASS_DECLARATION( idAnimatedEntity, idTestModel )
|
||||
EVENT( EV_FootstepLeft, idTestModel::Event_Footstep )
|
||||
EVENT( EV_FootstepRight, idTestModel::Event_Footstep )
|
||||
END_CLASS
|
||||
|
||||
/*
|
||||
================
|
||||
idTestModel::idTestModel
|
||||
================
|
||||
*/
|
||||
idTestModel::idTestModel() {
|
||||
head = NULL;
|
||||
headAnimator = NULL;
|
||||
anim = 0;
|
||||
headAnim = 0;
|
||||
starttime = 0;
|
||||
animtime = 0;
|
||||
mode = 0;
|
||||
frame = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idTestModel::Save
|
||||
================
|
||||
*/
|
||||
void idTestModel::Save( idSaveGame *savefile ) {
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idTestModel::Restore
|
||||
================
|
||||
*/
|
||||
void idTestModel::Restore( idRestoreGame *savefile ) {
|
||||
// FIXME: one day we may actually want to save/restore test models, but for now we'll just delete them
|
||||
delete this;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idTestModel::Spawn
|
||||
================
|
||||
*/
|
||||
void idTestModel::Spawn() {
|
||||
idVec3 size;
|
||||
idBounds bounds;
|
||||
const char *headModel;
|
||||
jointHandle_t joint;
|
||||
idStr jointName;
|
||||
idVec3 origin, modelOffset;
|
||||
idMat3 axis;
|
||||
const idKeyValue *kv;
|
||||
copyJoints_t copyJoint;
|
||||
|
||||
if ( renderEntity.hModel && renderEntity.hModel->IsDefaultModel() && !animator.ModelDef() ) {
|
||||
gameLocal.Warning( "Unable to create testmodel for '%s' : model defaulted", spawnArgs.GetString( "model" ) );
|
||||
PostEventMS( &EV_Remove, 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
mode = g_testModelAnimate.GetInteger();
|
||||
animator.RemoveOriginOffset( g_testModelAnimate.GetInteger() == 1 );
|
||||
|
||||
physicsObj.SetSelf( this );
|
||||
physicsObj.SetOrigin( GetPhysics()->GetOrigin() );
|
||||
physicsObj.SetAxis( GetPhysics()->GetAxis() );
|
||||
|
||||
if ( spawnArgs.GetVector( "mins", NULL, bounds[0] ) ) {
|
||||
spawnArgs.GetVector( "maxs", NULL, bounds[1] );
|
||||
physicsObj.SetClipBox( bounds, 1.0f );
|
||||
physicsObj.SetContents( 0 );
|
||||
} else if ( spawnArgs.GetVector( "size", NULL, size ) ) {
|
||||
bounds[ 0 ].Set( size.x * -0.5f, size.y * -0.5f, 0.0f );
|
||||
bounds[ 1 ].Set( size.x * 0.5f, size.y * 0.5f, size.z );
|
||||
physicsObj.SetClipBox( bounds, 1.0f );
|
||||
physicsObj.SetContents( 0 );
|
||||
}
|
||||
|
||||
spawnArgs.GetVector( "offsetModel", "0 0 0", modelOffset );
|
||||
|
||||
// add the head model if it has one
|
||||
headModel = spawnArgs.GetString( "def_head", "" );
|
||||
if ( headModel[ 0 ] ) {
|
||||
jointName = spawnArgs.GetString( "head_joint" );
|
||||
joint = animator.GetJointHandle( jointName );
|
||||
if ( joint == INVALID_JOINT ) {
|
||||
gameLocal.Warning( "Joint '%s' not found for 'head_joint'", jointName.c_str() );
|
||||
} else {
|
||||
// copy any sounds in case we have frame commands on the head
|
||||
idDict args;
|
||||
const idKeyValue *sndKV = spawnArgs.MatchPrefix( "snd_", NULL );
|
||||
while( sndKV ) {
|
||||
args.Set( sndKV->GetKey(), sndKV->GetValue() );
|
||||
sndKV = spawnArgs.MatchPrefix( "snd_", sndKV );
|
||||
}
|
||||
|
||||
head = gameLocal.SpawnEntityType( idAnimatedEntity::Type, &args );
|
||||
animator.GetJointTransform( joint, gameLocal.time, origin, axis );
|
||||
origin = GetPhysics()->GetOrigin() + ( origin + modelOffset ) * GetPhysics()->GetAxis();
|
||||
head.GetEntity()->SetModel( headModel );
|
||||
head.GetEntity()->SetOrigin( origin );
|
||||
head.GetEntity()->SetAxis( GetPhysics()->GetAxis() );
|
||||
head.GetEntity()->BindToJoint( this, animator.GetJointName( joint ), true );
|
||||
|
||||
headAnimator = head.GetEntity()->GetAnimator();
|
||||
|
||||
// set up the list of joints to copy to the head
|
||||
for( kv = spawnArgs.MatchPrefix( "copy_joint", NULL ); kv != NULL; kv = spawnArgs.MatchPrefix( "copy_joint", kv ) ) {
|
||||
jointName = kv->GetKey();
|
||||
|
||||
if ( jointName.StripLeadingOnce( "copy_joint_world " ) ) {
|
||||
copyJoint.mod = JOINTMOD_WORLD_OVERRIDE;
|
||||
} else {
|
||||
jointName.StripLeadingOnce( "copy_joint " );
|
||||
copyJoint.mod = JOINTMOD_LOCAL_OVERRIDE;
|
||||
}
|
||||
|
||||
copyJoint.from = animator.GetJointHandle( jointName );
|
||||
if ( copyJoint.from == INVALID_JOINT ) {
|
||||
gameLocal.Warning( "Unknown copy_joint '%s'", jointName.c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
copyJoint.to = headAnimator->GetJointHandle( jointName );
|
||||
if ( copyJoint.to == INVALID_JOINT ) {
|
||||
gameLocal.Warning( "Unknown copy_joint '%s' on head", jointName.c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
copyJoints.Append( copyJoint );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// start any shader effects based off of the spawn time
|
||||
renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time );
|
||||
|
||||
SetPhysics( &physicsObj );
|
||||
|
||||
gameLocal.Printf( "Added testmodel at origin = '%s', angles = '%s'\n", GetPhysics()->GetOrigin().ToString(), GetPhysics()->GetAxis().ToAngles().ToString() );
|
||||
BecomeActive( TH_THINK );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idTestModel::~idTestModel
|
||||
================
|
||||
*/
|
||||
idTestModel::~idTestModel() {
|
||||
StopSound( SND_CHANNEL_ANY, false );
|
||||
if ( renderEntity.hModel ) {
|
||||
gameLocal.Printf( "Removing testmodel %s\n", renderEntity.hModel->Name() );
|
||||
} else {
|
||||
gameLocal.Printf( "Removing testmodel\n" );
|
||||
}
|
||||
if ( gameLocal.testmodel == this ) {
|
||||
gameLocal.testmodel = NULL;
|
||||
}
|
||||
if ( head.GetEntity() ) {
|
||||
head.GetEntity()->StopSound( SND_CHANNEL_ANY, false );
|
||||
head.GetEntity()->PostEventMS( &EV_Remove, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idTestModel::Event_Footstep
|
||||
===============
|
||||
*/
|
||||
void idTestModel::Event_Footstep() {
|
||||
StartSound( "snd_footstep", SND_CHANNEL_BODY, 0, false, NULL );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idTestModel::ShouldConstructScriptObjectAtSpawn
|
||||
|
||||
Called during idEntity::Spawn to see if it should construct the script object or not.
|
||||
Overridden by subclasses that need to spawn the script object themselves.
|
||||
================
|
||||
*/
|
||||
bool idTestModel::ShouldConstructScriptObjectAtSpawn() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idTestModel::Think
|
||||
================
|
||||
*/
|
||||
void idTestModel::Think() {
|
||||
idVec3 pos;
|
||||
idMat3 axis;
|
||||
idAngles ang;
|
||||
int i;
|
||||
|
||||
if ( thinkFlags & TH_THINK ) {
|
||||
if ( anim && ( gameLocal.testmodel == this ) && ( mode != g_testModelAnimate.GetInteger() ) ) {
|
||||
StopSound( SND_CHANNEL_ANY, false );
|
||||
if ( head.GetEntity() ) {
|
||||
head.GetEntity()->StopSound( SND_CHANNEL_ANY, false );
|
||||
}
|
||||
switch( g_testModelAnimate.GetInteger() ) {
|
||||
default:
|
||||
case 0:
|
||||
// cycle anim with origin reset
|
||||
if ( animator.NumFrames( anim ) <= 1 ) {
|
||||
// single frame animations end immediately, so just cycle it since it's the same result
|
||||
animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
|
||||
if ( headAnim ) {
|
||||
headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
|
||||
}
|
||||
} else {
|
||||
animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
|
||||
if ( headAnim ) {
|
||||
headAnimator->PlayAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
|
||||
if ( headAnimator->AnimLength( headAnim ) > animator.AnimLength( anim ) ) {
|
||||
// loop the body anim when the head anim is longer
|
||||
animator.CurrentAnim( ANIMCHANNEL_ALL )->SetCycleCount( -1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
animator.RemoveOriginOffset( false );
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// cycle anim with fixed origin
|
||||
animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
|
||||
animator.RemoveOriginOffset( true );
|
||||
if ( headAnim ) {
|
||||
headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// cycle anim with continuous origin
|
||||
animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
|
||||
animator.RemoveOriginOffset( false );
|
||||
if ( headAnim ) {
|
||||
headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// frame by frame with continuous origin
|
||||
animator.SetFrame( ANIMCHANNEL_ALL, anim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
|
||||
animator.RemoveOriginOffset( false );
|
||||
if ( headAnim ) {
|
||||
headAnimator->SetFrame( ANIMCHANNEL_ALL, headAnim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// play anim once
|
||||
animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
|
||||
animator.RemoveOriginOffset( false );
|
||||
if ( headAnim ) {
|
||||
headAnimator->PlayAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case 5:
|
||||
// frame by frame with fixed origin
|
||||
animator.SetFrame( ANIMCHANNEL_ALL, anim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
|
||||
animator.RemoveOriginOffset( true );
|
||||
if ( headAnim ) {
|
||||
headAnimator->SetFrame( ANIMCHANNEL_ALL, headAnim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
mode = g_testModelAnimate.GetInteger();
|
||||
}
|
||||
|
||||
if ( ( mode == 0 ) && ( gameLocal.time >= starttime + animtime ) ) {
|
||||
starttime = gameLocal.time;
|
||||
StopSound( SND_CHANNEL_ANY, false );
|
||||
animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
|
||||
if ( headAnim ) {
|
||||
headAnimator->PlayAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
|
||||
if ( headAnimator->AnimLength( headAnim ) > animator.AnimLength( anim ) ) {
|
||||
// loop the body anim when the head anim is longer
|
||||
animator.CurrentAnim( ANIMCHANNEL_ALL )->SetCycleCount( -1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( headAnimator ) {
|
||||
// copy the animation from the body to the head
|
||||
for( i = 0; i < copyJoints.Num(); i++ ) {
|
||||
if ( copyJoints[ i ].mod == JOINTMOD_WORLD_OVERRIDE ) {
|
||||
idMat3 mat = head.GetEntity()->GetPhysics()->GetAxis().Transpose();
|
||||
GetJointWorldTransform( copyJoints[ i ].from, gameLocal.time, pos, axis );
|
||||
pos -= head.GetEntity()->GetPhysics()->GetOrigin();
|
||||
headAnimator->SetJointPos( copyJoints[ i ].to, copyJoints[ i ].mod, pos * mat );
|
||||
headAnimator->SetJointAxis( copyJoints[ i ].to, copyJoints[ i ].mod, axis * mat );
|
||||
} else {
|
||||
animator.GetJointLocalTransform( copyJoints[ i ].from, gameLocal.time, pos, axis );
|
||||
headAnimator->SetJointPos( copyJoints[ i ].to, copyJoints[ i ].mod, pos );
|
||||
headAnimator->SetJointAxis( copyJoints[ i ].to, copyJoints[ i ].mod, axis );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update rotation
|
||||
RunPhysics();
|
||||
|
||||
physicsObj.GetAngles( ang );
|
||||
physicsObj.SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, 0, ang, idAngles( 0, g_testModelRotate.GetFloat() * 360.0f / 60.0f, 0 ), ang_zero );
|
||||
|
||||
idClipModel *clip = physicsObj.GetClipModel();
|
||||
if ( clip != NULL && animator.ModelDef() ) {
|
||||
idVec3 neworigin;
|
||||
idMat3 axis;
|
||||
jointHandle_t joint;
|
||||
|
||||
joint = animator.GetJointHandle( "origin" );
|
||||
animator.GetJointTransform( joint, gameLocal.time, neworigin, axis );
|
||||
neworigin = ( ( neworigin - animator.ModelDef()->GetVisualOffset() ) * physicsObj.GetAxis() ) + GetPhysics()->GetOrigin();
|
||||
clip->Link( gameLocal.clip, this, 0, neworigin, clip->GetAxis() );
|
||||
}
|
||||
}
|
||||
|
||||
UpdateAnimation();
|
||||
Present();
|
||||
|
||||
if ( ( gameLocal.testmodel == this ) && g_showTestModelFrame.GetInteger() && anim ) {
|
||||
gameLocal.Printf( "^5 Anim: ^7%s ^5Frame: ^7%d/%d Time: %.3f\n", animator.AnimFullName( anim ), animator.CurrentAnim( ANIMCHANNEL_ALL )->GetFrameNumber( gameLocal.time ),
|
||||
animator.CurrentAnim( ANIMCHANNEL_ALL )->NumFrames(), MS2SEC( gameLocal.time - animator.CurrentAnim( ANIMCHANNEL_ALL )->GetStartTime() ) );
|
||||
if ( headAnim ) {
|
||||
gameLocal.Printf( "^5 Head: ^7%s ^5Frame: ^7%d/%d Time: %.3f\n\n", headAnimator->AnimFullName( headAnim ), headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->GetFrameNumber( gameLocal.time ),
|
||||
headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->NumFrames(), MS2SEC( gameLocal.time - headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->GetStartTime() ) );
|
||||
} else {
|
||||
gameLocal.Printf( "\n\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idTestModel::NextAnim
|
||||
================
|
||||
*/
|
||||
void idTestModel::NextAnim( const idCmdArgs &args ) {
|
||||
if ( !animator.NumAnims() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
anim++;
|
||||
if ( anim >= animator.NumAnims() ) {
|
||||
// anim 0 is no anim
|
||||
anim = 1;
|
||||
}
|
||||
|
||||
starttime = gameLocal.time;
|
||||
animtime = animator.AnimLength( anim );
|
||||
animname = animator.AnimFullName( anim );
|
||||
headAnim = 0;
|
||||
if ( headAnimator ) {
|
||||
headAnimator->ClearAllAnims( gameLocal.time, 0 );
|
||||
headAnim = headAnimator->GetAnim( animname );
|
||||
if ( !headAnim ) {
|
||||
headAnim = headAnimator->GetAnim( "idle" );
|
||||
}
|
||||
|
||||
if ( headAnim && ( headAnimator->AnimLength( headAnim ) > animtime ) ) {
|
||||
animtime = headAnimator->AnimLength( headAnim );
|
||||
}
|
||||
}
|
||||
|
||||
gameLocal.Printf( "anim '%s', %d.%03d seconds, %d frames\n", animname.c_str(), animator.AnimLength( anim ) / 1000, animator.AnimLength( anim ) % 1000, animator.NumFrames( anim ) );
|
||||
if ( headAnim ) {
|
||||
gameLocal.Printf( "head '%s', %d.%03d seconds, %d frames\n", headAnimator->AnimFullName( headAnim ), headAnimator->AnimLength( headAnim ) / 1000, headAnimator->AnimLength( headAnim ) % 1000, headAnimator->NumFrames( headAnim ) );
|
||||
}
|
||||
|
||||
// reset the anim
|
||||
mode = -1;
|
||||
frame = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idTestModel::PrevAnim
|
||||
================
|
||||
*/
|
||||
void idTestModel::PrevAnim( const idCmdArgs &args ) {
|
||||
if ( !animator.NumAnims() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
anim--;
|
||||
if ( anim < 0 ) {
|
||||
anim = animator.NumAnims() - 1;
|
||||
}
|
||||
|
||||
starttime = gameLocal.time;
|
||||
animtime = animator.AnimLength( anim );
|
||||
animname = animator.AnimFullName( anim );
|
||||
headAnim = 0;
|
||||
if ( headAnimator ) {
|
||||
headAnimator->ClearAllAnims( gameLocal.time, 0 );
|
||||
headAnim = headAnimator->GetAnim( animname );
|
||||
if ( !headAnim ) {
|
||||
headAnim = headAnimator->GetAnim( "idle" );
|
||||
}
|
||||
|
||||
if ( headAnim && ( headAnimator->AnimLength( headAnim ) > animtime ) ) {
|
||||
animtime = headAnimator->AnimLength( headAnim );
|
||||
}
|
||||
}
|
||||
|
||||
gameLocal.Printf( "anim '%s', %d.%03d seconds, %d frames\n", animname.c_str(), animator.AnimLength( anim ) / 1000, animator.AnimLength( anim ) % 1000, animator.NumFrames( anim ) );
|
||||
if ( headAnim ) {
|
||||
gameLocal.Printf( "head '%s', %d.%03d seconds, %d frames\n", headAnimator->AnimFullName( headAnim ), headAnimator->AnimLength( headAnim ) / 1000, headAnimator->AnimLength( headAnim ) % 1000, headAnimator->NumFrames( headAnim ) );
|
||||
}
|
||||
|
||||
// reset the anim
|
||||
mode = -1;
|
||||
frame = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idTestModel::NextFrame
|
||||
================
|
||||
*/
|
||||
void idTestModel::NextFrame( const idCmdArgs &args ) {
|
||||
if ( !anim || ( ( g_testModelAnimate.GetInteger() != 3 ) && ( g_testModelAnimate.GetInteger() != 5 ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
frame++;
|
||||
if ( frame > animator.NumFrames( anim ) ) {
|
||||
frame = 1;
|
||||
}
|
||||
|
||||
gameLocal.Printf( "^5 Anim: ^7%s\n^5Frame: ^7%d/%d\n\n", animator.AnimFullName( anim ), frame, animator.NumFrames( anim ) );
|
||||
|
||||
// reset the anim
|
||||
mode = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idTestModel::PrevFrame
|
||||
================
|
||||
*/
|
||||
void idTestModel::PrevFrame( const idCmdArgs &args ) {
|
||||
if ( !anim || ( ( g_testModelAnimate.GetInteger() != 3 ) && ( g_testModelAnimate.GetInteger() != 5 ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
frame--;
|
||||
if ( frame < 1 ) {
|
||||
frame = animator.NumFrames( anim );
|
||||
}
|
||||
|
||||
gameLocal.Printf( "^5 Anim: ^7%s\n^5Frame: ^7%d/%d\n\n", animator.AnimFullName( anim ), frame, animator.NumFrames( anim ) );
|
||||
|
||||
// reset the anim
|
||||
mode = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idTestModel::TestAnim
|
||||
================
|
||||
*/
|
||||
void idTestModel::TestAnim( const idCmdArgs &args ) {
|
||||
idStr name;
|
||||
int animNum;
|
||||
const idAnim *newanim;
|
||||
|
||||
if ( args.Argc() < 2 ) {
|
||||
gameLocal.Printf( "usage: testanim <animname>\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
newanim = NULL;
|
||||
|
||||
name = args.Argv( 1 );
|
||||
animNum = animator.GetAnim( name );
|
||||
|
||||
if ( !animNum ) {
|
||||
gameLocal.Printf( "Animation '%s' not found.\n", name.c_str() );
|
||||
return;
|
||||
}
|
||||
|
||||
anim = animNum;
|
||||
starttime = gameLocal.time;
|
||||
animtime = animator.AnimLength( anim );
|
||||
headAnim = 0;
|
||||
if ( headAnimator ) {
|
||||
headAnimator->ClearAllAnims( gameLocal.time, 0 );
|
||||
headAnim = headAnimator->GetAnim( animname );
|
||||
if ( !headAnim ) {
|
||||
headAnim = headAnimator->GetAnim( "idle" );
|
||||
if ( !headAnim ) {
|
||||
gameLocal.Printf( "Missing 'idle' anim for head.\n" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( headAnim && ( headAnimator->AnimLength( headAnim ) > animtime ) ) {
|
||||
animtime = headAnimator->AnimLength( headAnim );
|
||||
}
|
||||
}
|
||||
|
||||
animname = name;
|
||||
gameLocal.Printf( "anim '%s', %d.%03d seconds, %d frames\n", animname.c_str(), animator.AnimLength( anim ) / 1000, animator.AnimLength( anim ) % 1000, animator.NumFrames( anim ) );
|
||||
|
||||
// reset the anim
|
||||
mode = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idTestModel::BlendAnim
|
||||
=====================
|
||||
*/
|
||||
void idTestModel::BlendAnim( const idCmdArgs &args ) {
|
||||
int anim1;
|
||||
int anim2;
|
||||
|
||||
if ( args.Argc() < 4 ) {
|
||||
gameLocal.Printf( "usage: testblend <anim1> <anim2> <frames>\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
anim1 = gameLocal.testmodel->animator.GetAnim( args.Argv( 1 ) );
|
||||
if ( !anim1 ) {
|
||||
gameLocal.Printf( "Animation '%s' not found.\n", args.Argv( 1 ) );
|
||||
return;
|
||||
}
|
||||
|
||||
anim2 = gameLocal.testmodel->animator.GetAnim( args.Argv( 2 ) );
|
||||
if ( !anim2 ) {
|
||||
gameLocal.Printf( "Animation '%s' not found.\n", args.Argv( 2 ) );
|
||||
return;
|
||||
}
|
||||
|
||||
animname = args.Argv( 2 );
|
||||
animator.CycleAnim( ANIMCHANNEL_ALL, anim1, gameLocal.time, 0 );
|
||||
animator.CycleAnim( ANIMCHANNEL_ALL, anim2, gameLocal.time, FRAME2MS( atoi( args.Argv( 3 ) ) ) );
|
||||
|
||||
anim = anim2;
|
||||
headAnim = 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
Testmodel console commands
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
/*
|
||||
=================
|
||||
idTestModel::KeepTestModel_f
|
||||
|
||||
Makes the current test model permanent, allowing you to place
|
||||
multiple test models
|
||||
=================
|
||||
*/
|
||||
void idTestModel::KeepTestModel_f( const idCmdArgs &args ) {
|
||||
if ( !gameLocal.testmodel ) {
|
||||
gameLocal.Printf( "No active testModel.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
gameLocal.Printf( "modelDef %p kept\n", gameLocal.testmodel->renderEntity.hModel );
|
||||
|
||||
gameLocal.testmodel = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
idTestModel::TestSkin_f
|
||||
|
||||
Sets a skin on an existing testModel
|
||||
=================
|
||||
*/
|
||||
void idTestModel::TestSkin_f( const idCmdArgs &args ) {
|
||||
idVec3 offset;
|
||||
idStr name;
|
||||
idPlayer * player;
|
||||
idDict dict;
|
||||
|
||||
player = gameLocal.GetLocalPlayer();
|
||||
if ( !player || !gameLocal.CheatsOk() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// delete the testModel if active
|
||||
if ( !gameLocal.testmodel ) {
|
||||
common->Printf( "No active testModel\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( args.Argc() < 2 ) {
|
||||
common->Printf( "removing testSkin.\n" );
|
||||
gameLocal.testmodel->SetSkin( NULL );
|
||||
return;
|
||||
}
|
||||
|
||||
name = args.Argv( 1 );
|
||||
gameLocal.testmodel->SetSkin( declManager->FindSkin( name ) );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
idTestModel::TestShaderParm_f
|
||||
|
||||
Sets a shaderParm on an existing testModel
|
||||
=================
|
||||
*/
|
||||
void idTestModel::TestShaderParm_f( const idCmdArgs &args ) {
|
||||
idVec3 offset;
|
||||
idStr name;
|
||||
idPlayer * player;
|
||||
idDict dict;
|
||||
|
||||
player = gameLocal.GetLocalPlayer();
|
||||
if ( !player || !gameLocal.CheatsOk() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// delete the testModel if active
|
||||
if ( !gameLocal.testmodel ) {
|
||||
common->Printf( "No active testModel\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( args.Argc() != 3 ) {
|
||||
common->Printf( "USAGE: testShaderParm <parmNum> <float | \"time\">\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
int parm = atoi( args.Argv( 1 ) );
|
||||
if ( parm < 0 || parm >= MAX_ENTITY_SHADER_PARMS ) {
|
||||
common->Printf( "parmNum %i out of range\n", parm );
|
||||
return;
|
||||
}
|
||||
|
||||
float value;
|
||||
if ( !idStr::Icmp( args.Argv( 2 ), "time" ) ) {
|
||||
value = gameLocal.time * -0.001;
|
||||
} else {
|
||||
value = atof( args.Argv( 2 ) );
|
||||
}
|
||||
|
||||
gameLocal.testmodel->SetShaderParm( parm, value );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
idTestModel::TestModel_f
|
||||
|
||||
Creates a static modelDef in front of the current position, which
|
||||
can then be moved around
|
||||
=================
|
||||
*/
|
||||
void idTestModel::TestModel_f( const idCmdArgs &args ) {
|
||||
idVec3 offset;
|
||||
idStr name;
|
||||
idPlayer * player;
|
||||
const idDict * entityDef;
|
||||
idDict dict;
|
||||
|
||||
player = gameLocal.GetLocalPlayer();
|
||||
if ( !player || !gameLocal.CheatsOk() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// delete the testModel if active
|
||||
if ( gameLocal.testmodel ) {
|
||||
delete gameLocal.testmodel;
|
||||
gameLocal.testmodel = NULL;
|
||||
}
|
||||
|
||||
if ( args.Argc() < 2 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
name = args.Argv( 1 );
|
||||
|
||||
entityDef = gameLocal.FindEntityDefDict( name, false );
|
||||
if ( entityDef ) {
|
||||
dict = *entityDef;
|
||||
} else {
|
||||
if ( declManager->FindType( DECL_MODELDEF, name, false ) ) {
|
||||
dict.Set( "model", name );
|
||||
} else {
|
||||
// allow map models with underscore prefixes to be tested during development
|
||||
// without appending an ase
|
||||
if ( name[ 0 ] != '_' ) {
|
||||
name.DefaultFileExtension( ".ase" );
|
||||
}
|
||||
if ( !renderModelManager->CheckModel( name ) ) {
|
||||
gameLocal.Printf( "Can't register model\n" );
|
||||
return;
|
||||
}
|
||||
dict.Set( "model", name );
|
||||
}
|
||||
}
|
||||
|
||||
offset = player->GetPhysics()->GetOrigin() + player->viewAngles.ToForward() * 100.0f;
|
||||
|
||||
dict.Set( "origin", offset.ToString() );
|
||||
dict.Set( "angle", va( "%f", player->viewAngles.yaw + 180.0f ) );
|
||||
gameLocal.testmodel = ( idTestModel * )gameLocal.SpawnEntityType( idTestModel::Type, &dict );
|
||||
gameLocal.testmodel->renderEntity.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC( gameLocal.time );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idTestModel::ArgCompletion_TestModel
|
||||
=====================
|
||||
*/
|
||||
void idTestModel::ArgCompletion_TestModel( const idCmdArgs &args, void(*callback)( const char *s ) ) {
|
||||
int i, num;
|
||||
|
||||
num = declManager->GetNumDecls( DECL_ENTITYDEF );
|
||||
for ( i = 0; i < num; i++ ) {
|
||||
callback( idStr( args.Argv( 0 ) ) + " " + declManager->DeclByIndex( DECL_ENTITYDEF, i , false )->GetName() );
|
||||
}
|
||||
num = declManager->GetNumDecls( DECL_MODELDEF );
|
||||
for ( i = 0; i < num; i++ ) {
|
||||
callback( idStr( args.Argv( 0 ) ) + " " + declManager->DeclByIndex( DECL_MODELDEF, i , false )->GetName() );
|
||||
}
|
||||
cmdSystem->ArgCompletion_FolderExtension( args, callback, "models/", false, ".lwo", ".ase", ".md5mesh", ".ma", ".mb", NULL );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idTestModel::TestParticleStopTime_f
|
||||
=====================
|
||||
*/
|
||||
void idTestModel::TestParticleStopTime_f( const idCmdArgs &args ) {
|
||||
if ( !gameLocal.testmodel ) {
|
||||
gameLocal.Printf( "No testModel active.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
gameLocal.testmodel->renderEntity.shaderParms[SHADERPARM_PARTICLE_STOPTIME] = MS2SEC( gameLocal.time );
|
||||
gameLocal.testmodel->UpdateVisuals();
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idTestModel::TestAnim_f
|
||||
=====================
|
||||
*/
|
||||
void idTestModel::TestAnim_f( const idCmdArgs &args ) {
|
||||
if ( !gameLocal.testmodel ) {
|
||||
gameLocal.Printf( "No testModel active.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
gameLocal.testmodel->TestAnim( args );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
idTestModel::ArgCompletion_TestAnim
|
||||
=====================
|
||||
*/
|
||||
void idTestModel::ArgCompletion_TestAnim( const idCmdArgs &args, void(*callback)( const char *s ) ) {
|
||||
if ( gameLocal.testmodel ) {
|
||||
idAnimator *animator = gameLocal.testmodel->GetAnimator();
|
||||
for( int i = 0; i < animator->NumAnims(); i++ ) {
|
||||
callback( va( "%s %s", args.Argv( 0 ), animator->AnimFullName( i ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idTestModel::TestBlend_f
|
||||
=====================
|
||||
*/
|
||||
void idTestModel::TestBlend_f( const idCmdArgs &args ) {
|
||||
if ( !gameLocal.testmodel ) {
|
||||
gameLocal.Printf( "No testModel active.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
gameLocal.testmodel->BlendAnim( args );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idTestModel::TestModelNextAnim_f
|
||||
=====================
|
||||
*/
|
||||
void idTestModel::TestModelNextAnim_f( const idCmdArgs &args ) {
|
||||
if ( !gameLocal.testmodel ) {
|
||||
gameLocal.Printf( "No testModel active.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
gameLocal.testmodel->NextAnim( args );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idTestModel::TestModelPrevAnim_f
|
||||
=====================
|
||||
*/
|
||||
void idTestModel::TestModelPrevAnim_f( const idCmdArgs &args ) {
|
||||
if ( !gameLocal.testmodel ) {
|
||||
gameLocal.Printf( "No testModel active.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
gameLocal.testmodel->PrevAnim( args );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idTestModel::TestModelNextFrame_f
|
||||
=====================
|
||||
*/
|
||||
void idTestModel::TestModelNextFrame_f( const idCmdArgs &args ) {
|
||||
if ( !gameLocal.testmodel ) {
|
||||
gameLocal.Printf( "No testModel active.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
gameLocal.testmodel->NextFrame( args );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idTestModel::TestModelPrevFrame_f
|
||||
=====================
|
||||
*/
|
||||
void idTestModel::TestModelPrevFrame_f( const idCmdArgs &args ) {
|
||||
if ( !gameLocal.testmodel ) {
|
||||
gameLocal.Printf( "No testModel active.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
gameLocal.testmodel->PrevFrame( args );
|
||||
}
|
||||
95
neo/d3xp/anim/Anim_Testmodel.h
Normal file
95
neo/d3xp/anim/Anim_Testmodel.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __ANIM_TESTMODEL_H__
|
||||
#define __ANIM_TESTMODEL_H__
|
||||
|
||||
/*
|
||||
==============================================================================================
|
||||
|
||||
idTestModel
|
||||
|
||||
==============================================================================================
|
||||
*/
|
||||
|
||||
class idTestModel : public idAnimatedEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idTestModel );
|
||||
|
||||
idTestModel();
|
||||
~idTestModel();
|
||||
|
||||
void Save( idSaveGame *savefile );
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
void Spawn();
|
||||
|
||||
virtual bool ShouldConstructScriptObjectAtSpawn() const;
|
||||
|
||||
void NextAnim( const idCmdArgs &args );
|
||||
void PrevAnim( const idCmdArgs &args );
|
||||
void NextFrame( const idCmdArgs &args );
|
||||
void PrevFrame( const idCmdArgs &args );
|
||||
void TestAnim( const idCmdArgs &args );
|
||||
void BlendAnim( const idCmdArgs &args );
|
||||
|
||||
static void KeepTestModel_f( const idCmdArgs &args );
|
||||
static void TestModel_f( const idCmdArgs &args );
|
||||
static void ArgCompletion_TestModel( const idCmdArgs &args, void(*callback)( const char *s ) );
|
||||
static void TestSkin_f( const idCmdArgs &args );
|
||||
static void TestShaderParm_f( const idCmdArgs &args );
|
||||
static void TestParticleStopTime_f( const idCmdArgs &args );
|
||||
static void TestAnim_f( const idCmdArgs &args );
|
||||
static void ArgCompletion_TestAnim( const idCmdArgs &args, void(*callback)( const char *s ) );
|
||||
static void TestBlend_f( const idCmdArgs &args );
|
||||
static void TestModelNextAnim_f( const idCmdArgs &args );
|
||||
static void TestModelPrevAnim_f( const idCmdArgs &args );
|
||||
static void TestModelNextFrame_f( const idCmdArgs &args );
|
||||
static void TestModelPrevFrame_f( const idCmdArgs &args );
|
||||
|
||||
private:
|
||||
idEntityPtr<idEntity> head;
|
||||
idAnimator *headAnimator;
|
||||
idAnim customAnim;
|
||||
idPhysics_Parametric physicsObj;
|
||||
idStr animname;
|
||||
int anim;
|
||||
int headAnim;
|
||||
int mode;
|
||||
int frame;
|
||||
int starttime;
|
||||
int animtime;
|
||||
|
||||
idList<copyJoints_t> copyJoints;
|
||||
|
||||
virtual void Think();
|
||||
|
||||
void Event_Footstep();
|
||||
};
|
||||
|
||||
#endif /* !__ANIM_TESTMODEL_H__*/
|
||||
2626
neo/d3xp/gamesys/Callbacks.cpp
Normal file
2626
neo/d3xp/gamesys/Callbacks.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1025
neo/d3xp/gamesys/Class.cpp
Normal file
1025
neo/d3xp/gamesys/Class.cpp
Normal file
File diff suppressed because it is too large
Load Diff
349
neo/d3xp/gamesys/Class.h
Normal file
349
neo/d3xp/gamesys/Class.h
Normal file
@@ -0,0 +1,349 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
/*
|
||||
|
||||
Base class for all game objects. Provides fast run-time type checking and run-time
|
||||
instancing of objects.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __SYS_CLASS_H__
|
||||
#define __SYS_CLASS_H__
|
||||
|
||||
class idClass;
|
||||
class idTypeInfo;
|
||||
|
||||
extern const idEventDef EV_Remove;
|
||||
extern const idEventDef EV_SafeRemove;
|
||||
|
||||
typedef void ( idClass::*eventCallback_t )();
|
||||
|
||||
template< class Type >
|
||||
struct idEventFunc {
|
||||
const idEventDef *event;
|
||||
eventCallback_t function;
|
||||
};
|
||||
|
||||
// added & so gcc could compile this
|
||||
#define EVENT( event, function ) { &( event ), ( void ( idClass::* )() )( &function ) },
|
||||
#define END_CLASS { NULL, NULL } };
|
||||
|
||||
|
||||
class idEventArg {
|
||||
public:
|
||||
int type;
|
||||
int value;
|
||||
|
||||
idEventArg() { type = D_EVENT_INTEGER; value = 0; };
|
||||
idEventArg( int data ) { type = D_EVENT_INTEGER; value = data; };
|
||||
idEventArg( float data ) { type = D_EVENT_FLOAT; value = *reinterpret_cast<int *>( &data ); };
|
||||
idEventArg( idVec3 &data ) { type = D_EVENT_VECTOR; value = reinterpret_cast<int>( &data ); };
|
||||
idEventArg( const idStr &data ) { type = D_EVENT_STRING; value = reinterpret_cast<int>( data.c_str() ); };
|
||||
idEventArg( const char *data ) { type = D_EVENT_STRING; value = reinterpret_cast<int>( data ); };
|
||||
idEventArg( const class idEntity *data ) { type = D_EVENT_ENTITY; value = reinterpret_cast<int>( data ); };
|
||||
idEventArg( const struct trace_s *data ) { type = D_EVENT_TRACE; value = reinterpret_cast<int>( data ); };
|
||||
};
|
||||
|
||||
class idAllocError : public idException {
|
||||
public:
|
||||
idAllocError( const char *text = "" ) : idException( text ) {}
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
idClass
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
/*
|
||||
================
|
||||
CLASS_PROTOTYPE
|
||||
|
||||
This macro must be included in the definition of any subclass of idClass.
|
||||
It prototypes variables used in class instanciation and type checking.
|
||||
Use this on single inheritance concrete classes only.
|
||||
================
|
||||
*/
|
||||
#define CLASS_PROTOTYPE( nameofclass ) \
|
||||
public: \
|
||||
static idTypeInfo Type; \
|
||||
static idClass *CreateInstance(); \
|
||||
virtual idTypeInfo *GetType() const; \
|
||||
static idEventFunc<nameofclass> eventCallbacks[]
|
||||
|
||||
/*
|
||||
================
|
||||
CLASS_DECLARATION
|
||||
|
||||
This macro must be included in the code to properly initialize variables
|
||||
used in type checking and run-time instanciation. It also defines the list
|
||||
of events that the class responds to. Take special care to ensure that the
|
||||
proper superclass is indicated or the run-time type information will be
|
||||
incorrect. Use this on concrete classes only.
|
||||
================
|
||||
*/
|
||||
#define CLASS_DECLARATION( nameofsuperclass, nameofclass ) \
|
||||
idTypeInfo nameofclass::Type( #nameofclass, #nameofsuperclass, \
|
||||
( idEventFunc<idClass> * )nameofclass::eventCallbacks, nameofclass::CreateInstance, ( void ( idClass::* )() )&nameofclass::Spawn, \
|
||||
( void ( idClass::* )( idSaveGame * ) const )&nameofclass::Save, ( void ( idClass::* )( idRestoreGame * ) )&nameofclass::Restore ); \
|
||||
idClass *nameofclass::CreateInstance() { \
|
||||
try { \
|
||||
nameofclass *ptr = new nameofclass; \
|
||||
ptr->FindUninitializedMemory(); \
|
||||
return ptr; \
|
||||
} \
|
||||
catch( idAllocError & ) { \
|
||||
return NULL; \
|
||||
} \
|
||||
} \
|
||||
idTypeInfo *nameofclass::GetType() const { \
|
||||
return &( nameofclass::Type ); \
|
||||
} \
|
||||
idEventFunc<nameofclass> nameofclass::eventCallbacks[] = {
|
||||
|
||||
/*
|
||||
================
|
||||
ABSTRACT_PROTOTYPE
|
||||
|
||||
This macro must be included in the definition of any abstract subclass of idClass.
|
||||
It prototypes variables used in class instanciation and type checking.
|
||||
Use this on single inheritance abstract classes only.
|
||||
================
|
||||
*/
|
||||
#define ABSTRACT_PROTOTYPE( nameofclass ) \
|
||||
public: \
|
||||
static idTypeInfo Type; \
|
||||
static idClass *CreateInstance(); \
|
||||
virtual idTypeInfo *GetType() const; \
|
||||
static idEventFunc<nameofclass> eventCallbacks[]
|
||||
|
||||
/*
|
||||
================
|
||||
ABSTRACT_DECLARATION
|
||||
|
||||
This macro must be included in the code to properly initialize variables
|
||||
used in type checking. It also defines the list of events that the class
|
||||
responds to. Take special care to ensure that the proper superclass is
|
||||
indicated or the run-time tyep information will be incorrect. Use this
|
||||
on abstract classes only.
|
||||
================
|
||||
*/
|
||||
#define ABSTRACT_DECLARATION( nameofsuperclass, nameofclass ) \
|
||||
idTypeInfo nameofclass::Type( #nameofclass, #nameofsuperclass, \
|
||||
( idEventFunc<idClass> * )nameofclass::eventCallbacks, nameofclass::CreateInstance, ( void ( idClass::* )() )&nameofclass::Spawn, \
|
||||
( void ( idClass::* )( idSaveGame * ) const )&nameofclass::Save, ( void ( idClass::* )( idRestoreGame * ) )&nameofclass::Restore ); \
|
||||
idClass *nameofclass::CreateInstance() { \
|
||||
gameLocal.Error( "Cannot instanciate abstract class %s.", #nameofclass ); \
|
||||
return NULL; \
|
||||
} \
|
||||
idTypeInfo *nameofclass::GetType() const { \
|
||||
return &( nameofclass::Type ); \
|
||||
} \
|
||||
idEventFunc<nameofclass> nameofclass::eventCallbacks[] = {
|
||||
|
||||
typedef void ( idClass::*classSpawnFunc_t )();
|
||||
|
||||
class idSaveGame;
|
||||
class idRestoreGame;
|
||||
|
||||
class idClass {
|
||||
public:
|
||||
ABSTRACT_PROTOTYPE( idClass );
|
||||
|
||||
void * operator new( size_t );
|
||||
void operator delete( void * );
|
||||
|
||||
virtual ~idClass();
|
||||
|
||||
void Spawn();
|
||||
void CallSpawn();
|
||||
bool IsType( const idTypeInfo &c ) const;
|
||||
const char * GetClassname() const;
|
||||
const char * GetSuperclass() const;
|
||||
void FindUninitializedMemory();
|
||||
|
||||
void Save( idSaveGame *savefile ) const {};
|
||||
void Restore( idRestoreGame *savefile ) {};
|
||||
|
||||
bool RespondsTo( const idEventDef &ev ) const;
|
||||
|
||||
bool PostEventMS( const idEventDef *ev, int time );
|
||||
bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1 );
|
||||
bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2 );
|
||||
bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3 );
|
||||
bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 );
|
||||
bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 );
|
||||
bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 );
|
||||
bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 );
|
||||
bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 );
|
||||
|
||||
bool PostEventSec( const idEventDef *ev, float time );
|
||||
bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1 );
|
||||
bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2 );
|
||||
bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3 );
|
||||
bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 );
|
||||
bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 );
|
||||
bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 );
|
||||
bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 );
|
||||
bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 );
|
||||
|
||||
bool ProcessEvent( const idEventDef *ev );
|
||||
bool ProcessEvent( const idEventDef *ev, idEventArg arg1 );
|
||||
bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2 );
|
||||
bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3 );
|
||||
bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 );
|
||||
bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 );
|
||||
bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 );
|
||||
bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 );
|
||||
bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 );
|
||||
|
||||
bool ProcessEventArgPtr( const idEventDef *ev, int *data );
|
||||
void CancelEvents( const idEventDef *ev );
|
||||
|
||||
void Event_Remove();
|
||||
|
||||
// Static functions
|
||||
static void Init();
|
||||
static void Shutdown();
|
||||
static idTypeInfo * GetClass( const char *name );
|
||||
static void DisplayInfo_f( const idCmdArgs &args );
|
||||
static void ListClasses_f( const idCmdArgs &args );
|
||||
static idClass * CreateInstance( const char *name );
|
||||
static int GetNumTypes() { return types.Num(); }
|
||||
static int GetTypeNumBits() { return typeNumBits; }
|
||||
static idTypeInfo * GetType( int num );
|
||||
|
||||
private:
|
||||
classSpawnFunc_t CallSpawnFunc( idTypeInfo *cls );
|
||||
|
||||
bool PostEventArgs( const idEventDef *ev, int time, int numargs, ... );
|
||||
bool ProcessEventArgs( const idEventDef *ev, int numargs, ... );
|
||||
|
||||
void Event_SafeRemove();
|
||||
|
||||
static bool initialized;
|
||||
static idList<idTypeInfo *, TAG_IDCLASS> types;
|
||||
static idList<idTypeInfo *, TAG_IDCLASS> typenums;
|
||||
static int typeNumBits;
|
||||
static int memused;
|
||||
static int numobjects;
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
idTypeInfo
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
class idTypeInfo {
|
||||
public:
|
||||
const char * classname;
|
||||
const char * superclass;
|
||||
idClass * ( *CreateInstance )();
|
||||
void ( idClass::*Spawn )();
|
||||
void ( idClass::*Save )( idSaveGame *savefile ) const;
|
||||
void ( idClass::*Restore )( idRestoreGame *savefile );
|
||||
|
||||
idEventFunc<idClass> * eventCallbacks;
|
||||
eventCallback_t * eventMap;
|
||||
idTypeInfo * super;
|
||||
idTypeInfo * next;
|
||||
bool freeEventMap;
|
||||
int typeNum;
|
||||
int lastChild;
|
||||
|
||||
idHierarchy<idTypeInfo> node;
|
||||
|
||||
idTypeInfo( const char *classname, const char *superclass,
|
||||
idEventFunc<idClass> *eventCallbacks, idClass *( *CreateInstance )(), void ( idClass::*Spawn )(),
|
||||
void ( idClass::*Save )( idSaveGame *savefile ) const, void ( idClass::*Restore )( idRestoreGame *savefile ) );
|
||||
~idTypeInfo();
|
||||
|
||||
void Init();
|
||||
void Shutdown();
|
||||
|
||||
bool IsType( const idTypeInfo &superclass ) const;
|
||||
bool RespondsTo( const idEventDef &ev ) const;
|
||||
};
|
||||
|
||||
/*
|
||||
================
|
||||
idTypeInfo::IsType
|
||||
|
||||
Checks if the object's class is a subclass of the class defined by the
|
||||
passed in idTypeInfo.
|
||||
================
|
||||
*/
|
||||
ID_INLINE bool idTypeInfo::IsType( const idTypeInfo &type ) const {
|
||||
return ( ( typeNum >= type.typeNum ) && ( typeNum <= type.lastChild ) );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idTypeInfo::RespondsTo
|
||||
================
|
||||
*/
|
||||
ID_INLINE bool idTypeInfo::RespondsTo( const idEventDef &ev ) const {
|
||||
assert( idEvent::initialized );
|
||||
if ( !eventMap[ ev.GetEventNum() ] ) {
|
||||
// we don't respond to this event
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idClass::IsType
|
||||
|
||||
Checks if the object's class is a subclass of the class defined by the
|
||||
passed in idTypeInfo.
|
||||
================
|
||||
*/
|
||||
ID_INLINE bool idClass::IsType( const idTypeInfo &superclass ) const {
|
||||
idTypeInfo *subclass;
|
||||
|
||||
subclass = GetType();
|
||||
return subclass->IsType( superclass );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idClass::RespondsTo
|
||||
================
|
||||
*/
|
||||
ID_INLINE bool idClass::RespondsTo( const idEventDef &ev ) const {
|
||||
const idTypeInfo *c;
|
||||
|
||||
assert( idEvent::initialized );
|
||||
c = GetType();
|
||||
return c->RespondsTo( ev );
|
||||
}
|
||||
|
||||
#endif /* !__SYS_CLASS_H__ */
|
||||
1062
neo/d3xp/gamesys/Event.cpp
Normal file
1062
neo/d3xp/gamesys/Event.cpp
Normal file
File diff suppressed because it is too large
Load Diff
210
neo/d3xp/gamesys/Event.h
Normal file
210
neo/d3xp/gamesys/Event.h
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
/*
|
||||
sys_event.h
|
||||
|
||||
Event are used for scheduling tasks and for linking script commands.
|
||||
*/
|
||||
#ifndef __SYS_EVENT_H__
|
||||
#define __SYS_EVENT_H__
|
||||
|
||||
#define D_EVENT_MAXARGS 8 // if changed, enable the CREATE_EVENT_CODE define in Event.cpp to generate switch statement for idClass::ProcessEventArgPtr.
|
||||
// running the game will then generate c:\doom\base\events.txt, the contents of which should be copied into the switch statement.
|
||||
|
||||
#define D_EVENT_VOID ( ( char )0 )
|
||||
#define D_EVENT_INTEGER 'd'
|
||||
#define D_EVENT_FLOAT 'f'
|
||||
#define D_EVENT_VECTOR 'v'
|
||||
#define D_EVENT_STRING 's'
|
||||
#define D_EVENT_ENTITY 'e'
|
||||
#define D_EVENT_ENTITY_NULL 'E' // event can handle NULL entity pointers
|
||||
#define D_EVENT_TRACE 't'
|
||||
|
||||
#define MAX_EVENTS 4096
|
||||
|
||||
class idClass;
|
||||
class idTypeInfo;
|
||||
|
||||
class idEventDef {
|
||||
private:
|
||||
const char *name;
|
||||
const char *formatspec;
|
||||
unsigned int formatspecIndex;
|
||||
int returnType;
|
||||
int numargs;
|
||||
size_t argsize;
|
||||
int argOffset[ D_EVENT_MAXARGS ];
|
||||
int eventnum;
|
||||
const idEventDef * next;
|
||||
|
||||
static idEventDef * eventDefList[MAX_EVENTS];
|
||||
static int numEventDefs;
|
||||
|
||||
public:
|
||||
idEventDef( const char *command, const char *formatspec = NULL, char returnType = 0 );
|
||||
|
||||
const char *GetName() const;
|
||||
const char *GetArgFormat() const;
|
||||
unsigned int GetFormatspecIndex() const;
|
||||
char GetReturnType() const;
|
||||
int GetEventNum() const;
|
||||
int GetNumArgs() const;
|
||||
size_t GetArgSize() const;
|
||||
int GetArgOffset( int arg ) const;
|
||||
|
||||
static int NumEventCommands();
|
||||
static const idEventDef *GetEventCommand( int eventnum );
|
||||
static const idEventDef *FindEvent( const char *name );
|
||||
};
|
||||
|
||||
class idSaveGame;
|
||||
class idRestoreGame;
|
||||
|
||||
class idEvent {
|
||||
private:
|
||||
const idEventDef *eventdef;
|
||||
byte *data;
|
||||
int time;
|
||||
idClass *object;
|
||||
const idTypeInfo *typeinfo;
|
||||
|
||||
idLinkList<idEvent> eventNode;
|
||||
|
||||
static idDynamicBlockAlloc<byte, 16 * 1024, 256> eventDataAllocator;
|
||||
|
||||
|
||||
public:
|
||||
static bool initialized;
|
||||
|
||||
~idEvent();
|
||||
|
||||
static idEvent *Alloc( const idEventDef *evdef, int numargs, va_list args );
|
||||
static void CopyArgs( const idEventDef *evdef, int numargs, va_list args, int data[ D_EVENT_MAXARGS ] );
|
||||
|
||||
void Free();
|
||||
void Schedule( idClass *object, const idTypeInfo *cls, int time );
|
||||
byte *GetData();
|
||||
|
||||
static void CancelEvents( const idClass *obj, const idEventDef *evdef = NULL );
|
||||
static void ClearEventList();
|
||||
static void ServiceEvents();
|
||||
static void ServiceFastEvents();
|
||||
static void Init();
|
||||
static void Shutdown();
|
||||
|
||||
// save games
|
||||
static void Save( idSaveGame *savefile ); // archives object for save game file
|
||||
static void Restore( idRestoreGame *savefile ); // unarchives object from save game file
|
||||
static void SaveTrace( idSaveGame *savefile, const trace_t &trace );
|
||||
static void RestoreTrace( idRestoreGame *savefile, trace_t &trace );
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
================
|
||||
idEvent::GetData
|
||||
================
|
||||
*/
|
||||
ID_INLINE byte *idEvent::GetData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEventDef::GetName
|
||||
================
|
||||
*/
|
||||
ID_INLINE const char *idEventDef::GetName() const {
|
||||
return name;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEventDef::GetArgFormat
|
||||
================
|
||||
*/
|
||||
ID_INLINE const char *idEventDef::GetArgFormat() const {
|
||||
return formatspec;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEventDef::GetFormatspecIndex
|
||||
================
|
||||
*/
|
||||
ID_INLINE unsigned int idEventDef::GetFormatspecIndex() const {
|
||||
return formatspecIndex;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEventDef::GetReturnType
|
||||
================
|
||||
*/
|
||||
ID_INLINE char idEventDef::GetReturnType() const {
|
||||
return returnType;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEventDef::GetNumArgs
|
||||
================
|
||||
*/
|
||||
ID_INLINE int idEventDef::GetNumArgs() const {
|
||||
return numargs;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEventDef::GetArgSize
|
||||
================
|
||||
*/
|
||||
ID_INLINE size_t idEventDef::GetArgSize() const {
|
||||
return argsize;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEventDef::GetArgOffset
|
||||
================
|
||||
*/
|
||||
ID_INLINE int idEventDef::GetArgOffset( int arg ) const {
|
||||
assert( ( arg >= 0 ) && ( arg < D_EVENT_MAXARGS ) );
|
||||
return argOffset[ arg ];
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idEventDef::GetEventNum
|
||||
================
|
||||
*/
|
||||
ID_INLINE int idEventDef::GetEventNum() const {
|
||||
return eventnum;
|
||||
}
|
||||
|
||||
#endif /* !__SYS_EVENT_H__ */
|
||||
1601
neo/d3xp/gamesys/SaveGame.cpp
Normal file
1601
neo/d3xp/gamesys/SaveGame.cpp
Normal file
File diff suppressed because it is too large
Load Diff
182
neo/d3xp/gamesys/SaveGame.h
Normal file
182
neo/d3xp/gamesys/SaveGame.h
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __SAVEGAME_H__
|
||||
#define __SAVEGAME_H__
|
||||
|
||||
/*
|
||||
|
||||
Save game related helper classes.
|
||||
|
||||
*/
|
||||
|
||||
class idSaveGame {
|
||||
public:
|
||||
idSaveGame( idFile *savefile, idFile *stringFile, int inVersion );
|
||||
~idSaveGame();
|
||||
|
||||
void Close();
|
||||
|
||||
void WriteDecls();
|
||||
|
||||
void AddObject( const idClass *obj );
|
||||
void Resize( const int count ) { objects.Resize( count ); }
|
||||
void WriteObjectList();
|
||||
|
||||
void Write( const void *buffer, int len );
|
||||
void WriteInt( const int value );
|
||||
void WriteJoint( const jointHandle_t value );
|
||||
void WriteShort( const short value );
|
||||
void WriteByte( const byte value );
|
||||
void WriteSignedChar( const signed char value );
|
||||
void WriteFloat( const float value );
|
||||
void WriteBool( const bool value );
|
||||
void WriteString( const char *string );
|
||||
void WriteVec2( const idVec2 &vec );
|
||||
void WriteVec3( const idVec3 &vec );
|
||||
void WriteVec4( const idVec4 &vec );
|
||||
void WriteVec6( const idVec6 &vec );
|
||||
void WriteWinding( const idWinding &winding );
|
||||
void WriteBounds( const idBounds &bounds );
|
||||
void WriteMat3( const idMat3 &mat );
|
||||
void WriteAngles( const idAngles &angles );
|
||||
void WriteObject( const idClass *obj );
|
||||
void WriteStaticObject( const idClass &obj );
|
||||
void WriteDict( const idDict *dict );
|
||||
void WriteMaterial( const idMaterial *material );
|
||||
void WriteSkin( const idDeclSkin *skin );
|
||||
void WriteParticle( const idDeclParticle *particle );
|
||||
void WriteFX( const idDeclFX *fx );
|
||||
void WriteSoundShader( const idSoundShader *shader );
|
||||
void WriteModelDef( const class idDeclModelDef *modelDef );
|
||||
void WriteModel( const idRenderModel *model );
|
||||
void WriteUserInterface( const idUserInterface *ui, bool unique );
|
||||
void WriteRenderEntity( const renderEntity_t &renderEntity );
|
||||
void WriteRenderLight( const renderLight_t &renderLight );
|
||||
void WriteRefSound( const refSound_t &refSound );
|
||||
void WriteRenderView( const renderView_t &view );
|
||||
void WriteUsercmd( const usercmd_t &usercmd );
|
||||
void WriteContactInfo( const contactInfo_t &contactInfo );
|
||||
void WriteTrace( const trace_t &trace );
|
||||
void WriteTraceModel( const idTraceModel &trace );
|
||||
void WriteClipModel( const class idClipModel *clipModel );
|
||||
void WriteSoundCommands();
|
||||
|
||||
void WriteBuildNumber( const int value );
|
||||
|
||||
int GetBuildNumber() const { return version; }
|
||||
|
||||
int GetCurrentSaveSize() const { return file->Length(); }
|
||||
|
||||
private:
|
||||
idFile * file;
|
||||
idFile * stringFile;
|
||||
idCompressor * compressor;
|
||||
|
||||
idList<const idClass *> objects;
|
||||
int version;
|
||||
|
||||
void CallSave_r( const idTypeInfo *cls, const idClass *obj );
|
||||
|
||||
struct stringTableIndex_s {
|
||||
idStr string;
|
||||
int offset;
|
||||
};
|
||||
|
||||
idHashIndex stringHash;
|
||||
idList< stringTableIndex_s > stringTable;
|
||||
int curStringTableOffset;
|
||||
|
||||
};
|
||||
|
||||
class idRestoreGame {
|
||||
public:
|
||||
idRestoreGame( idFile * savefile, idFile * stringTableFile, int saveVersion );
|
||||
~idRestoreGame();
|
||||
|
||||
void ReadDecls();
|
||||
|
||||
void CreateObjects();
|
||||
void RestoreObjects();
|
||||
void DeleteObjects();
|
||||
|
||||
void Error( VERIFY_FORMAT_STRING const char *fmt, ... );
|
||||
|
||||
void Read( void *buffer, int len );
|
||||
void ReadInt( int &value );
|
||||
void ReadJoint( jointHandle_t &value );
|
||||
void ReadShort( short &value );
|
||||
void ReadByte( byte &value );
|
||||
void ReadSignedChar( signed char &value );
|
||||
void ReadFloat( float &value );
|
||||
void ReadBool( bool &value );
|
||||
void ReadString( idStr &string );
|
||||
void ReadVec2( idVec2 &vec );
|
||||
void ReadVec3( idVec3 &vec );
|
||||
void ReadVec4( idVec4 &vec );
|
||||
void ReadVec6( idVec6 &vec );
|
||||
void ReadWinding( idWinding &winding );
|
||||
void ReadBounds( idBounds &bounds );
|
||||
void ReadMat3( idMat3 &mat );
|
||||
void ReadAngles( idAngles &angles );
|
||||
void ReadObject( idClass *&obj );
|
||||
void ReadStaticObject( idClass &obj );
|
||||
void ReadDict( idDict *dict );
|
||||
void ReadMaterial( const idMaterial *&material );
|
||||
void ReadSkin( const idDeclSkin *&skin );
|
||||
void ReadParticle( const idDeclParticle *&particle );
|
||||
void ReadFX( const idDeclFX *&fx );
|
||||
void ReadSoundShader( const idSoundShader *&shader );
|
||||
void ReadModelDef( const idDeclModelDef *&modelDef );
|
||||
void ReadModel( idRenderModel *&model );
|
||||
void ReadUserInterface( idUserInterface *&ui );
|
||||
void ReadRenderEntity( renderEntity_t &renderEntity );
|
||||
void ReadRenderLight( renderLight_t &renderLight );
|
||||
void ReadRefSound( refSound_t &refSound );
|
||||
void ReadRenderView( renderView_t &view );
|
||||
void ReadUsercmd( usercmd_t &usercmd );
|
||||
void ReadContactInfo( contactInfo_t &contactInfo );
|
||||
void ReadTrace( trace_t &trace );
|
||||
void ReadTraceModel( idTraceModel &trace );
|
||||
void ReadClipModel( idClipModel *&clipModel );
|
||||
void ReadSoundCommands();
|
||||
|
||||
// Used to retrieve the saved game buildNumber from within class Restore methods
|
||||
int GetBuildNumber() const { return version; }
|
||||
|
||||
private:
|
||||
idFile * file;
|
||||
idFile * stringFile;
|
||||
idList<idClass *, TAG_SAVEGAMES> objects;
|
||||
int version;
|
||||
int stringTableOffset;
|
||||
|
||||
void CallRestore_r( const idTypeInfo *cls, idClass *obj );
|
||||
};
|
||||
|
||||
#endif /* !__SAVEGAME_H__*/
|
||||
2397
neo/d3xp/gamesys/SysCmds.cpp
Normal file
2397
neo/d3xp/gamesys/SysCmds.cpp
Normal file
File diff suppressed because it is too large
Load Diff
34
neo/d3xp/gamesys/SysCmds.h
Normal file
34
neo/d3xp/gamesys/SysCmds.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __SYS_CMDS_H__
|
||||
#define __SYS_CMDS_H__
|
||||
|
||||
void D_DrawDebugLines();
|
||||
|
||||
#endif /* !__SYS_CMDS_H__ */
|
||||
323
neo/d3xp/gamesys/SysCvar.cpp
Normal file
323
neo/d3xp/gamesys/SysCvar.cpp
Normal file
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma hdrstop
|
||||
#include "../../idlib/precompiled.h"
|
||||
|
||||
|
||||
#include "../Game_local.h"
|
||||
|
||||
#if defined( _DEBUG )
|
||||
#define BUILD_DEBUG "-debug"
|
||||
#else
|
||||
#define BUILD_DEBUG "-release"
|
||||
#endif
|
||||
|
||||
/*
|
||||
All game cvars should be defined here.
|
||||
*/
|
||||
|
||||
struct gameVersion_s {
|
||||
gameVersion_s() { sprintf( string, "%s.%d%s %s %s %s", ENGINE_VERSION, BUILD_NUMBER, BUILD_DEBUG, BUILD_STRING, __DATE__, __TIME__ ); }
|
||||
char string[256];
|
||||
} gameVersion;
|
||||
|
||||
|
||||
// noset vars
|
||||
idCVar gamename( "gamename", GAME_VERSION, CVAR_GAME | CVAR_ROM, "" );
|
||||
idCVar gamedate( "gamedate", __DATE__, CVAR_GAME | CVAR_ROM, "" );
|
||||
|
||||
idCVar si_map( "si_map", "-1", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_INTEGER, "default map choice for profile" );
|
||||
idCVar si_mode( "si_mode", "-1", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_INTEGER, "default mode choice for profile", -1, GAME_COUNT - 1 );
|
||||
idCVar si_fragLimit( "si_fragLimit", "10", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_INTEGER, "frag limit", 1, MP_PLAYER_MAXFRAGS );
|
||||
idCVar si_timeLimit( "si_timeLimit", "10", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_INTEGER, "time limit in minutes", 0, 60 );
|
||||
idCVar si_teamDamage( "si_teamDamage", "0", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_BOOL, "enable team damage" );
|
||||
idCVar si_spectators( "si_spectators", "1", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_BOOL, "allow spectators or require all clients to play" );
|
||||
|
||||
//idCVar si_pointLimit( "si_pointlimit", "8", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_INTEGER, "team points limit to win in CTF" );
|
||||
idCVar si_flagDropTimeLimit( "si_flagDropTimeLimit", "30", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_INTEGER, "seconds before a dropped CTF flag is returned" );
|
||||
idCVar si_midnight( "si_midnight", "0", CVAR_GAME | CVAR_INTEGER | CVAR_SERVERINFO, "Start the game up in midnight CTF (completely dark)" );
|
||||
|
||||
// change anytime vars
|
||||
idCVar developer( "developer", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
|
||||
idCVar g_cinematic( "g_cinematic", "1", CVAR_GAME | CVAR_BOOL, "skips updating entities that aren't marked 'cinematic' '1' during cinematics" );
|
||||
idCVar g_cinematicMaxSkipTime( "g_cinematicMaxSkipTime", "600", CVAR_GAME | CVAR_FLOAT, "# of seconds to allow game to run when skipping cinematic. prevents lock-up when cinematic doesn't end.", 0, 3600 );
|
||||
|
||||
idCVar g_muzzleFlash( "g_muzzleFlash", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "show muzzle flashes" );
|
||||
idCVar g_projectileLights( "g_projectileLights", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "show dynamic lights on projectiles" );
|
||||
idCVar g_bloodEffects( "g_bloodEffects", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "show blood splats, sprays and gibs" );
|
||||
idCVar g_monsters( "g_monsters", "1", CVAR_GAME | CVAR_BOOL, "" );
|
||||
idCVar g_decals( "g_decals", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "show decals such as bullet holes" );
|
||||
idCVar g_knockback( "g_knockback", "1000", CVAR_GAME | CVAR_INTEGER, "" );
|
||||
idCVar g_skill( "g_skill", "1", CVAR_GAME | CVAR_INTEGER, "" );
|
||||
idCVar g_nightmare( "g_nightmare", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "if nightmare mode is allowed" );
|
||||
idCVar g_roeNightmare( "g_roeNightmare", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "if nightmare mode is allowed for roe" );
|
||||
idCVar g_leNightmare( "g_leNightmare", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "if nightmare mode is allowed for le" );
|
||||
idCVar g_gravity( "g_gravity", DEFAULT_GRAVITY_STRING, CVAR_GAME | CVAR_FLOAT, "" );
|
||||
idCVar g_skipFX( "g_skipFX", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
|
||||
idCVar g_disasm( "g_disasm", "0", CVAR_GAME | CVAR_BOOL, "disassemble script into base/script/disasm.txt on the local drive when script is compiled" );
|
||||
idCVar g_debugBounds( "g_debugBounds", "0", CVAR_GAME | CVAR_BOOL, "checks for models with bounds > 2048" );
|
||||
idCVar g_debugAnim( "g_debugAnim", "-1", CVAR_GAME | CVAR_INTEGER, "displays information on which animations are playing on the specified entity number. set to -1 to disable." );
|
||||
idCVar g_debugMove( "g_debugMove", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
idCVar g_debugDamage( "g_debugDamage", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
idCVar g_debugWeapon( "g_debugWeapon", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
idCVar g_debugScript( "g_debugScript", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
idCVar g_debugMover( "g_debugMover", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
idCVar g_debugTriggers( "g_debugTriggers", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
idCVar g_debugCinematic( "g_debugCinematic", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
idCVar g_stopTime( "g_stopTime", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
idCVar g_damageScale( "g_damageScale", "1", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "scale final damage on player by this factor" );
|
||||
idCVar g_armorProtection( "g_armorProtection", "0.3", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "armor takes this percentage of damage" );
|
||||
idCVar g_armorProtectionMP( "g_armorProtectionMP", "0.6", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "armor takes this percentage of damage in mp" );
|
||||
idCVar g_useDynamicProtection( "g_useDynamicProtection", "1", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "scale damage and armor dynamically to keep the player alive more often" );
|
||||
idCVar g_healthTakeTime( "g_healthTakeTime", "5", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "how often to take health in nightmare mode" );
|
||||
idCVar g_healthTakeAmt( "g_healthTakeAmt", "5", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "how much health to take in nightmare mode" );
|
||||
idCVar g_healthTakeLimit( "g_healthTakeLimit", "25", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "how low can health get taken in nightmare mode" );
|
||||
|
||||
|
||||
|
||||
idCVar g_showPVS( "g_showPVS", "0", CVAR_GAME | CVAR_INTEGER, "", 0, 2 );
|
||||
idCVar g_showTargets( "g_showTargets", "0", CVAR_GAME | CVAR_BOOL, "draws entities and thier targets. hidden entities are drawn grey." );
|
||||
idCVar g_showTriggers( "g_showTriggers", "0", CVAR_GAME | CVAR_BOOL, "draws trigger entities (orange) and thier targets (green). disabled triggers are drawn grey." );
|
||||
idCVar g_showCollisionWorld( "g_showCollisionWorld", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
idCVar g_showCollisionModels( "g_showCollisionModels", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
idCVar g_showCollisionTraces( "g_showCollisionTraces", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
idCVar g_maxShowDistance( "g_maxShowDistance", "128", CVAR_GAME | CVAR_FLOAT, "" );
|
||||
idCVar g_showEntityInfo( "g_showEntityInfo", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
idCVar g_showviewpos( "g_showviewpos", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
idCVar g_showcamerainfo( "g_showcamerainfo", "0", CVAR_GAME | CVAR_ARCHIVE, "displays the current frame # for the camera when playing cinematics" );
|
||||
idCVar g_showTestModelFrame( "g_showTestModelFrame", "0", CVAR_GAME | CVAR_BOOL, "displays the current animation and frame # for testmodels" );
|
||||
idCVar g_showActiveEntities( "g_showActiveEntities", "0", CVAR_GAME | CVAR_BOOL, "draws boxes around thinking entities. dormant entities (outside of pvs) are drawn yellow. non-dormant are green." );
|
||||
idCVar g_showEnemies( "g_showEnemies", "0", CVAR_GAME | CVAR_BOOL, "draws boxes around monsters that have targeted the the player" );
|
||||
|
||||
idCVar g_frametime( "g_frametime", "0", CVAR_GAME | CVAR_BOOL, "displays timing information for each game frame" );
|
||||
idCVar g_timeentities( "g_timeEntities", "0", CVAR_GAME | CVAR_FLOAT, "when non-zero, shows entities whose think functions exceeded the # of milliseconds specified" );
|
||||
|
||||
idCVar g_debugShockwave( "g_debugShockwave", "0", CVAR_GAME | CVAR_BOOL, "Debug the shockwave" );
|
||||
|
||||
idCVar g_enableSlowmo( "g_enableSlowmo", "0", CVAR_GAME | CVAR_BOOL, "for testing purposes only" );
|
||||
idCVar g_slowmoStepRate( "g_slowmoStepRate", "0.02", CVAR_GAME | CVAR_FLOAT, "" );
|
||||
|
||||
idCVar g_enablePortalSky( "g_enablePortalSky", "1", CVAR_GAME | CVAR_BOOL, "enables the portal sky" );
|
||||
idCVar g_testFullscreenFX( "g_testFullscreenFX", "-1", CVAR_GAME | CVAR_INTEGER, "index will activate specific fx, -2 is for all on, -1 is off" );
|
||||
idCVar g_testHelltimeFX( "g_testHelltimeFX", "-1", CVAR_GAME | CVAR_INTEGER, "set to 0, 1, 2 to test helltime, -1 is off" );
|
||||
idCVar g_testMultiplayerFX( "g_testMultiplayerFX", "-1", CVAR_GAME | CVAR_INTEGER, "set to 0, 1, 2 to test multiplayer, -1 is off" );
|
||||
|
||||
idCVar g_moveableDamageScale( "g_moveableDamageScale", "0.1", CVAR_GAME | CVAR_FLOAT, "scales damage wrt mass of object in multiplayer" );
|
||||
|
||||
idCVar g_testBloomIntensity( "g_testBloomIntensity", "-0.01", CVAR_GAME | CVAR_FLOAT, "" );
|
||||
idCVar g_testBloomNumPasses( "g_testBloomNumPasses", "30", CVAR_GAME | CVAR_INTEGER, "" );
|
||||
|
||||
idCVar ai_debugScript( "ai_debugScript", "-1", CVAR_GAME | CVAR_INTEGER, "displays script calls for the specified monster entity number" );
|
||||
idCVar ai_debugMove( "ai_debugMove", "0", CVAR_GAME | CVAR_BOOL, "draws movement information for monsters" );
|
||||
idCVar ai_debugTrajectory( "ai_debugTrajectory", "0", CVAR_GAME | CVAR_BOOL, "draws trajectory tests for monsters" );
|
||||
idCVar ai_testPredictPath( "ai_testPredictPath", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
idCVar ai_showCombatNodes( "ai_showCombatNodes", "0", CVAR_GAME | CVAR_BOOL, "draws attack cones for monsters" );
|
||||
idCVar ai_showPaths( "ai_showPaths", "0", CVAR_GAME | CVAR_BOOL, "draws path_* entities" );
|
||||
idCVar ai_showObstacleAvoidance( "ai_showObstacleAvoidance", "0", CVAR_GAME | CVAR_INTEGER, "draws obstacle avoidance information for monsters. if 2, draws obstacles for player, as well", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> );
|
||||
idCVar ai_blockedFailSafe( "ai_blockedFailSafe", "1", CVAR_GAME | CVAR_BOOL, "enable blocked fail safe handling" );
|
||||
|
||||
idCVar ai_showHealth( "ai_showHealth", "0", CVAR_GAME | CVAR_BOOL, "Draws the AI's health above its head" );
|
||||
|
||||
idCVar g_dvTime( "g_dvTime", "1", CVAR_GAME | CVAR_FLOAT, "" );
|
||||
idCVar g_dvAmplitude( "g_dvAmplitude", "0.001", CVAR_GAME | CVAR_FLOAT, "" );
|
||||
idCVar g_dvFrequency( "g_dvFrequency", "0.5", CVAR_GAME | CVAR_FLOAT, "" );
|
||||
|
||||
idCVar g_kickTime( "g_kickTime", "1", CVAR_GAME | CVAR_FLOAT, "" );
|
||||
idCVar g_kickAmplitude( "g_kickAmplitude", "0.0001", CVAR_GAME | CVAR_FLOAT, "" );
|
||||
idCVar g_blobTime( "g_blobTime", "1", CVAR_GAME | CVAR_FLOAT, "" );
|
||||
idCVar g_blobSize( "g_blobSize", "1", CVAR_GAME | CVAR_FLOAT, "" );
|
||||
|
||||
idCVar g_testHealthVision( "g_testHealthVision", "0", CVAR_GAME | CVAR_FLOAT, "" );
|
||||
idCVar g_editEntityMode( "g_editEntityMode", "0", CVAR_GAME | CVAR_INTEGER, "0 = off\n"
|
||||
"1 = lights\n"
|
||||
"2 = sounds\n"
|
||||
"3 = articulated figures\n"
|
||||
"4 = particle systems\n"
|
||||
"5 = monsters\n"
|
||||
"6 = entity names\n"
|
||||
"7 = entity models", 0, 7, idCmdSystem::ArgCompletion_Integer<0,7> );
|
||||
idCVar g_dragEntity( "g_dragEntity", "0", CVAR_GAME | CVAR_BOOL, "allows dragging physics objects around by placing the crosshair over them and holding the fire button" );
|
||||
idCVar g_dragDamping( "g_dragDamping", "0.5", CVAR_GAME | CVAR_FLOAT, "" );
|
||||
idCVar g_dragShowSelection( "g_dragShowSelection", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
idCVar g_dropItemRotation( "g_dropItemRotation", "", CVAR_GAME, "" );
|
||||
|
||||
// Note: These cvars do not necessarily need to be in the shipping game.
|
||||
idCVar g_flagAttachJoint( "g_flagAttachJoint", "Chest", CVAR_GAME | CVAR_CHEAT, "player joint to attach CTF flag to" );
|
||||
idCVar g_flagAttachOffsetX( "g_flagAttachOffsetX", "8", CVAR_GAME | CVAR_CHEAT, "X offset of CTF flag when carried" );
|
||||
idCVar g_flagAttachOffsetY( "g_flagAttachOffsetY", "4", CVAR_GAME | CVAR_CHEAT, "Y offset of CTF flag when carried" );
|
||||
idCVar g_flagAttachOffsetZ( "g_flagAttachOffsetZ", "-12", CVAR_GAME | CVAR_CHEAT, "Z offset of CTF flag when carried" );
|
||||
idCVar g_flagAttachAngleX( "g_flagAttachAngleX", "90", CVAR_GAME | CVAR_CHEAT, "X angle of CTF flag when carried" );
|
||||
idCVar g_flagAttachAngleY( "g_flagAttachAngleY", "25", CVAR_GAME | CVAR_CHEAT, "Y angle of CTF flag when carried" );
|
||||
idCVar g_flagAttachAngleZ( "g_flagAttachAngleZ", "-90", CVAR_GAME | CVAR_CHEAT, "Z angle of CTF flag when carried" );
|
||||
|
||||
|
||||
idCVar g_vehicleVelocity( "g_vehicleVelocity", "1000", CVAR_GAME | CVAR_FLOAT, "" );
|
||||
idCVar g_vehicleForce( "g_vehicleForce", "50000", CVAR_GAME | CVAR_FLOAT, "" );
|
||||
idCVar g_vehicleSuspensionUp( "g_vehicleSuspensionUp", "32", CVAR_GAME | CVAR_FLOAT, "" );
|
||||
idCVar g_vehicleSuspensionDown( "g_vehicleSuspensionDown", "20", CVAR_GAME | CVAR_FLOAT, "" );
|
||||
idCVar g_vehicleSuspensionKCompress("g_vehicleSuspensionKCompress","200", CVAR_GAME | CVAR_FLOAT, "" );
|
||||
idCVar g_vehicleSuspensionDamping( "g_vehicleSuspensionDamping","400", CVAR_GAME | CVAR_FLOAT, "" );
|
||||
idCVar g_vehicleTireFriction( "g_vehicleTireFriction", "0.8", CVAR_GAME | CVAR_FLOAT, "" );
|
||||
idCVar g_vehicleDebug( "g_vehicleDebug", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
|
||||
idCVar ik_enable( "ik_enable", "1", CVAR_GAME | CVAR_BOOL, "enable IK" );
|
||||
idCVar ik_debug( "ik_debug", "0", CVAR_GAME | CVAR_BOOL, "show IK debug lines" );
|
||||
|
||||
idCVar af_useLinearTime( "af_useLinearTime", "1", CVAR_GAME | CVAR_BOOL, "use linear time algorithm for tree-like structures" );
|
||||
idCVar af_useImpulseFriction( "af_useImpulseFriction", "0", CVAR_GAME | CVAR_BOOL, "use impulse based contact friction" );
|
||||
idCVar af_useJointImpulseFriction( "af_useJointImpulseFriction","0", CVAR_GAME | CVAR_BOOL, "use impulse based joint friction" );
|
||||
idCVar af_useSymmetry( "af_useSymmetry", "1", CVAR_GAME | CVAR_BOOL, "use constraint matrix symmetry" );
|
||||
idCVar af_skipSelfCollision( "af_skipSelfCollision", "0", CVAR_GAME | CVAR_BOOL, "skip self collision detection" );
|
||||
idCVar af_skipLimits( "af_skipLimits", "0", CVAR_GAME | CVAR_BOOL, "skip joint limits" );
|
||||
idCVar af_skipFriction( "af_skipFriction", "0", CVAR_GAME | CVAR_BOOL, "skip friction" );
|
||||
idCVar af_forceFriction( "af_forceFriction", "-1", CVAR_GAME | CVAR_FLOAT, "force the given friction value" );
|
||||
idCVar af_maxLinearVelocity( "af_maxLinearVelocity", "128", CVAR_GAME | CVAR_FLOAT, "maximum linear velocity" );
|
||||
idCVar af_maxAngularVelocity( "af_maxAngularVelocity", "1.57", CVAR_GAME | CVAR_FLOAT, "maximum angular velocity" );
|
||||
idCVar af_timeScale( "af_timeScale", "1", CVAR_GAME | CVAR_FLOAT, "scales the time" );
|
||||
idCVar af_jointFrictionScale( "af_jointFrictionScale", "0", CVAR_GAME | CVAR_FLOAT, "scales the joint friction" );
|
||||
idCVar af_contactFrictionScale( "af_contactFrictionScale", "0", CVAR_GAME | CVAR_FLOAT, "scales the contact friction" );
|
||||
idCVar af_highlightBody( "af_highlightBody", "", CVAR_GAME, "name of the body to highlight" );
|
||||
idCVar af_highlightConstraint( "af_highlightConstraint", "", CVAR_GAME, "name of the constraint to highlight" );
|
||||
idCVar af_showTimings( "af_showTimings", "0", CVAR_GAME | CVAR_BOOL, "show articulated figure cpu usage" );
|
||||
idCVar af_showConstraints( "af_showConstraints", "0", CVAR_GAME | CVAR_BOOL, "show constraints" );
|
||||
idCVar af_showConstraintNames( "af_showConstraintNames", "0", CVAR_GAME | CVAR_BOOL, "show constraint names" );
|
||||
idCVar af_showConstrainedBodies( "af_showConstrainedBodies", "0", CVAR_GAME | CVAR_BOOL, "show the two bodies contrained by the highlighted constraint" );
|
||||
idCVar af_showPrimaryOnly( "af_showPrimaryOnly", "0", CVAR_GAME | CVAR_BOOL, "show primary constraints only" );
|
||||
idCVar af_showTrees( "af_showTrees", "0", CVAR_GAME | CVAR_BOOL, "show tree-like structures" );
|
||||
idCVar af_showLimits( "af_showLimits", "0", CVAR_GAME | CVAR_BOOL, "show joint limits" );
|
||||
idCVar af_showBodies( "af_showBodies", "0", CVAR_GAME | CVAR_BOOL, "show bodies" );
|
||||
idCVar af_showBodyNames( "af_showBodyNames", "0", CVAR_GAME | CVAR_BOOL, "show body names" );
|
||||
idCVar af_showMass( "af_showMass", "0", CVAR_GAME | CVAR_BOOL, "show the mass of each body" );
|
||||
idCVar af_showTotalMass( "af_showTotalMass", "0", CVAR_GAME | CVAR_BOOL, "show the total mass of each articulated figure" );
|
||||
idCVar af_showInertia( "af_showInertia", "0", CVAR_GAME | CVAR_BOOL, "show the inertia tensor of each body" );
|
||||
idCVar af_showVelocity( "af_showVelocity", "0", CVAR_GAME | CVAR_BOOL, "show the velocity of each body" );
|
||||
idCVar af_showActive( "af_showActive", "0", CVAR_GAME | CVAR_BOOL, "show tree-like structures of articulated figures not at rest" );
|
||||
idCVar af_testSolid( "af_testSolid", "1", CVAR_GAME | CVAR_BOOL, "test for bodies initially stuck in solid" );
|
||||
|
||||
idCVar rb_showTimings( "rb_showTimings", "0", CVAR_GAME | CVAR_BOOL, "show rigid body cpu usage" );
|
||||
idCVar rb_showBodies( "rb_showBodies", "0", CVAR_GAME | CVAR_BOOL, "show rigid bodies" );
|
||||
idCVar rb_showMass( "rb_showMass", "0", CVAR_GAME | CVAR_BOOL, "show the mass of each rigid body" );
|
||||
idCVar rb_showInertia( "rb_showInertia", "0", CVAR_GAME | CVAR_BOOL, "show the inertia tensor of each rigid body" );
|
||||
idCVar rb_showVelocity( "rb_showVelocity", "0", CVAR_GAME | CVAR_BOOL, "show the velocity of each rigid body" );
|
||||
idCVar rb_showActive( "rb_showActive", "0", CVAR_GAME | CVAR_BOOL, "show rigid bodies that are not at rest" );
|
||||
|
||||
// The default values for player movement cvars are set in def/player.def
|
||||
idCVar pm_jumpheight( "pm_jumpheight", "48", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "approximate hieght the player can jump" );
|
||||
idCVar pm_stepsize( "pm_stepsize", "16", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "maximum height the player can step up without jumping" );
|
||||
idCVar pm_crouchspeed( "pm_crouchspeed", "80", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "speed the player can move while crouched" );
|
||||
idCVar pm_walkspeed( "pm_walkspeed", "140", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "speed the player can move while walking" );
|
||||
idCVar pm_runspeed( "pm_runspeed", "220", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "speed the player can move while running" );
|
||||
idCVar pm_noclipspeed( "pm_noclipspeed", "200", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "speed the player can move while in noclip" );
|
||||
idCVar pm_spectatespeed( "pm_spectatespeed", "450", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "speed the player can move while spectating" );
|
||||
idCVar pm_spectatebbox( "pm_spectatebbox", "32", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "size of the spectator bounding box" );
|
||||
idCVar pm_usecylinder( "pm_usecylinder", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_BOOL, "use a cylinder approximation instead of a bounding box for player collision detection" );
|
||||
idCVar pm_minviewpitch( "pm_minviewpitch", "-89", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "amount player's view can look up (negative values are up)" );
|
||||
idCVar pm_maxviewpitch( "pm_maxviewpitch", "89", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "amount player's view can look down" );
|
||||
idCVar pm_stamina( "pm_stamina", "24", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "length of time player can run" );
|
||||
idCVar pm_staminathreshold( "pm_staminathreshold", "45", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "when stamina drops below this value, player gradually slows to a walk" );
|
||||
idCVar pm_staminarate( "pm_staminarate", "0.75", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "rate that player regains stamina. divide pm_stamina by this value to determine how long it takes to fully recharge." );
|
||||
idCVar pm_crouchheight( "pm_crouchheight", "38", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's bounding box while crouched" );
|
||||
idCVar pm_crouchviewheight( "pm_crouchviewheight", "32", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's view while crouched" );
|
||||
idCVar pm_normalheight( "pm_normalheight", "74", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's bounding box while standing" );
|
||||
idCVar pm_normalviewheight( "pm_normalviewheight", "68", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's view while standing" );
|
||||
idCVar pm_deadheight( "pm_deadheight", "20", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's bounding box while dead" );
|
||||
idCVar pm_deadviewheight( "pm_deadviewheight", "10", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's view while dead" );
|
||||
idCVar pm_crouchrate( "pm_crouchrate", "0.87", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "time it takes for player's view to change from standing to crouching" );
|
||||
idCVar pm_bboxwidth( "pm_bboxwidth", "32", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "x/y size of player's bounding box" );
|
||||
idCVar pm_crouchbob( "pm_crouchbob", "0.5", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "bob much faster when crouched" );
|
||||
idCVar pm_walkbob( "pm_walkbob", "0.3", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "bob slowly when walking" );
|
||||
idCVar pm_runbob( "pm_runbob", "0.4", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "bob faster when running" );
|
||||
idCVar pm_runpitch( "pm_runpitch", "0.002", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "" );
|
||||
idCVar pm_runroll( "pm_runroll", "0.005", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "" );
|
||||
idCVar pm_bobup( "pm_bobup", "0.005", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "" );
|
||||
idCVar pm_bobpitch( "pm_bobpitch", "0.002", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "" );
|
||||
idCVar pm_bobroll( "pm_bobroll", "0.002", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "" );
|
||||
idCVar pm_thirdPersonRange( "pm_thirdPersonRange", "80", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "camera distance from player in 3rd person" );
|
||||
idCVar pm_thirdPersonHeight( "pm_thirdPersonHeight", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of camera from normal view height in 3rd person" );
|
||||
idCVar pm_thirdPersonAngle( "pm_thirdPersonAngle", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "direction of camera from player in 3rd person in degrees (0 = behind player, 180 = in front)" );
|
||||
idCVar pm_thirdPersonClip( "pm_thirdPersonClip", "1", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_BOOL, "clip third person view into world space" );
|
||||
idCVar pm_thirdPerson( "pm_thirdPerson", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_BOOL, "enables third person view" );
|
||||
idCVar pm_thirdPersonDeath( "pm_thirdPersonDeath", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_BOOL, "enables third person view when player dies" );
|
||||
idCVar pm_modelView( "pm_modelView", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_INTEGER, "draws camera from POV of player model (1 = always, 2 = when dead)", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> );
|
||||
idCVar pm_airMsec( "pm_air", "30000", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_INTEGER, "how long in milliseconds the player can go without air before he starts taking damage" );
|
||||
|
||||
idCVar g_showPlayerShadow( "g_showPlayerShadow", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "enables shadow of player model" );
|
||||
idCVar g_showHud( "g_showHud", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "" );
|
||||
idCVar g_showProjectilePct( "g_showProjectilePct", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "enables display of player hit percentage" );
|
||||
idCVar g_showBrass( "g_showBrass", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "enables ejected shells from weapon" );
|
||||
idCVar g_gun_x( "g_gunX", "3", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "" );
|
||||
idCVar g_gun_y( "g_gunY", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "" );
|
||||
idCVar g_gun_z( "g_gunZ", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "" );
|
||||
idCVar g_gunScale( "g_gunScale", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "" );
|
||||
idCVar g_viewNodalX( "g_viewNodalX", "3", CVAR_GAME | CVAR_FLOAT, "" );
|
||||
idCVar g_viewNodalZ( "g_viewNodalZ", "6", CVAR_GAME | CVAR_FLOAT, "" );
|
||||
idCVar g_fov( "g_fov", "80", CVAR_GAME | CVAR_INTEGER | CVAR_NOCHEAT, "" );
|
||||
idCVar g_skipViewEffects( "g_skipViewEffects", "0", CVAR_GAME | CVAR_BOOL, "skip damage and other view effects" );
|
||||
idCVar g_mpWeaponAngleScale( "g_mpWeaponAngleScale", "0", CVAR_GAME | CVAR_FLOAT, "Control the weapon sway in MP" );
|
||||
|
||||
idCVar g_testParticle( "g_testParticle", "0", CVAR_GAME | CVAR_INTEGER, "test particle visualation, set by the particle editor" );
|
||||
idCVar g_testParticleName( "g_testParticleName", "", CVAR_GAME, "name of the particle being tested by the particle editor" );
|
||||
idCVar g_testModelRotate( "g_testModelRotate", "0", CVAR_GAME, "test model rotation speed" );
|
||||
idCVar g_testPostProcess( "g_testPostProcess", "", CVAR_GAME, "name of material to draw over screen" );
|
||||
idCVar g_testModelAnimate( "g_testModelAnimate", "0", CVAR_GAME | CVAR_INTEGER, "test model animation,\n"
|
||||
"0 = cycle anim with origin reset\n"
|
||||
"1 = cycle anim with fixed origin\n"
|
||||
"2 = cycle anim with continuous origin\n"
|
||||
"3 = frame by frame with continuous origin\n"
|
||||
"4 = play anim once", 0, 4, idCmdSystem::ArgCompletion_Integer<0,4> );
|
||||
idCVar g_testModelBlend( "g_testModelBlend", "0", CVAR_GAME | CVAR_INTEGER, "number of frames to blend" );
|
||||
idCVar g_testDeath( "g_testDeath", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
idCVar g_flushSave( "g_flushSave", "0", CVAR_GAME | CVAR_BOOL, "1 = don't buffer file writing for save games." );
|
||||
|
||||
idCVar aas_test( "aas_test", "0", CVAR_GAME | CVAR_INTEGER, "" );
|
||||
idCVar aas_showAreas( "aas_showAreas", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
idCVar aas_showPath( "aas_showPath", "0", CVAR_GAME | CVAR_INTEGER, "" );
|
||||
idCVar aas_showFlyPath( "aas_showFlyPath", "0", CVAR_GAME | CVAR_INTEGER, "" );
|
||||
idCVar aas_showWallEdges( "aas_showWallEdges", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
idCVar aas_showHideArea( "aas_showHideArea", "0", CVAR_GAME | CVAR_INTEGER, "" );
|
||||
idCVar aas_pullPlayer( "aas_pullPlayer", "0", CVAR_GAME | CVAR_INTEGER, "" );
|
||||
idCVar aas_randomPullPlayer( "aas_randomPullPlayer", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
idCVar aas_goalArea( "aas_goalArea", "0", CVAR_GAME | CVAR_INTEGER, "" );
|
||||
idCVar aas_showPushIntoArea( "aas_showPushIntoArea", "0", CVAR_GAME | CVAR_BOOL, "" );
|
||||
|
||||
idCVar g_countDown( "g_countDown", "15", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "pregame countdown in seconds", 4, 3600 );
|
||||
idCVar g_gameReviewPause( "g_gameReviewPause", "10", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_INTEGER | CVAR_ARCHIVE, "scores review time in seconds (at end game)", 2, 3600 );
|
||||
idCVar g_CTFArrows( "g_CTFArrows", "1", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_BOOL, "draw arrows over teammates in CTF" );
|
||||
|
||||
idCVar net_clientPredictGUI( "net_clientPredictGUI", "1", CVAR_GAME | CVAR_BOOL, "test guis in networking without prediction" );
|
||||
|
||||
idCVar g_grabberHoldSeconds( "g_grabberHoldSeconds", "3", CVAR_GAME | CVAR_FLOAT | CVAR_CHEAT, "number of seconds to hold object" );
|
||||
idCVar g_grabberEnableShake( "g_grabberEnableShake", "1", CVAR_GAME | CVAR_BOOL | CVAR_CHEAT, "enable the grabber shake" );
|
||||
idCVar g_grabberRandomMotion( "g_grabberRandomMotion", "1", CVAR_GAME | CVAR_BOOL | CVAR_CHEAT, "enable random motion on the grabbed object" );
|
||||
idCVar g_grabberHardStop( "g_grabberHardStop", "1", CVAR_GAME | CVAR_BOOL | CVAR_CHEAT, "hard stops object if too fast" );
|
||||
idCVar g_grabberDamping( "g_grabberDamping", "0.5", CVAR_GAME | CVAR_FLOAT | CVAR_CHEAT, "damping of grabber" );
|
||||
|
||||
idCVar g_xp_bind_run_once( "g_xp_bind_run_once", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "Rebind all controls once for D3XP." );
|
||||
274
neo/d3xp/gamesys/SysCvar.h
Normal file
274
neo/d3xp/gamesys/SysCvar.h
Normal file
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __SYS_CVAR_H__
|
||||
#define __SYS_CVAR_H__
|
||||
|
||||
extern idCVar developer;
|
||||
|
||||
extern idCVar g_cinematic;
|
||||
extern idCVar g_cinematicMaxSkipTime;
|
||||
|
||||
extern idCVar g_monsters;
|
||||
extern idCVar g_decals;
|
||||
extern idCVar g_knockback;
|
||||
extern idCVar g_skill;
|
||||
extern idCVar g_gravity;
|
||||
extern idCVar g_skipFX;
|
||||
extern idCVar g_bloodEffects;
|
||||
extern idCVar g_projectileLights;
|
||||
extern idCVar g_muzzleFlash;
|
||||
|
||||
extern idCVar g_disasm;
|
||||
extern idCVar g_debugBounds;
|
||||
extern idCVar g_debugAnim;
|
||||
extern idCVar g_debugMove;
|
||||
extern idCVar g_debugDamage;
|
||||
extern idCVar g_debugWeapon;
|
||||
extern idCVar g_debugScript;
|
||||
extern idCVar g_debugMover;
|
||||
extern idCVar g_debugTriggers;
|
||||
extern idCVar g_debugCinematic;
|
||||
extern idCVar g_stopTime;
|
||||
extern idCVar g_armorProtection;
|
||||
extern idCVar g_armorProtectionMP;
|
||||
extern idCVar g_damageScale;
|
||||
extern idCVar g_useDynamicProtection;
|
||||
extern idCVar g_healthTakeTime;
|
||||
extern idCVar g_healthTakeAmt;
|
||||
extern idCVar g_healthTakeLimit;
|
||||
|
||||
extern idCVar g_showPVS;
|
||||
extern idCVar g_showTargets;
|
||||
extern idCVar g_showTriggers;
|
||||
extern idCVar g_showCollisionWorld;
|
||||
extern idCVar g_showCollisionModels;
|
||||
extern idCVar g_showCollisionTraces;
|
||||
extern idCVar g_maxShowDistance;
|
||||
extern idCVar g_showEntityInfo;
|
||||
extern idCVar g_showviewpos;
|
||||
extern idCVar g_showcamerainfo;
|
||||
extern idCVar g_showTestModelFrame;
|
||||
extern idCVar g_showActiveEntities;
|
||||
extern idCVar g_showEnemies;
|
||||
|
||||
extern idCVar g_frametime;
|
||||
extern idCVar g_timeentities;
|
||||
|
||||
extern idCVar ai_debugScript;
|
||||
extern idCVar ai_debugMove;
|
||||
extern idCVar ai_debugTrajectory;
|
||||
extern idCVar ai_testPredictPath;
|
||||
extern idCVar ai_showCombatNodes;
|
||||
extern idCVar ai_showPaths;
|
||||
extern idCVar ai_showObstacleAvoidance;
|
||||
extern idCVar ai_blockedFailSafe;
|
||||
extern idCVar ai_showHealth;
|
||||
|
||||
extern idCVar g_dvTime;
|
||||
extern idCVar g_dvAmplitude;
|
||||
extern idCVar g_dvFrequency;
|
||||
|
||||
extern idCVar g_kickTime;
|
||||
extern idCVar g_kickAmplitude;
|
||||
extern idCVar g_blobTime;
|
||||
extern idCVar g_blobSize;
|
||||
|
||||
extern idCVar g_testHealthVision;
|
||||
extern idCVar g_editEntityMode;
|
||||
extern idCVar g_dragEntity;
|
||||
extern idCVar g_dragDamping;
|
||||
extern idCVar g_dragShowSelection;
|
||||
extern idCVar g_dropItemRotation;
|
||||
|
||||
extern idCVar g_vehicleVelocity;
|
||||
extern idCVar g_vehicleForce;
|
||||
extern idCVar g_vehicleSuspensionUp;
|
||||
extern idCVar g_vehicleSuspensionDown;
|
||||
extern idCVar g_vehicleSuspensionKCompress;
|
||||
extern idCVar g_vehicleSuspensionDamping;
|
||||
extern idCVar g_vehicleTireFriction;
|
||||
extern idCVar g_vehicleDebug;
|
||||
extern idCVar g_debugShockwave;
|
||||
extern idCVar g_enablePortalSky;
|
||||
|
||||
extern idCVar ik_enable;
|
||||
extern idCVar ik_debug;
|
||||
|
||||
extern idCVar af_useLinearTime;
|
||||
extern idCVar af_useImpulseFriction;
|
||||
extern idCVar af_useJointImpulseFriction;
|
||||
extern idCVar af_useSymmetry;
|
||||
extern idCVar af_skipSelfCollision;
|
||||
extern idCVar af_skipLimits;
|
||||
extern idCVar af_skipFriction;
|
||||
extern idCVar af_forceFriction;
|
||||
extern idCVar af_maxLinearVelocity;
|
||||
extern idCVar af_maxAngularVelocity;
|
||||
extern idCVar af_timeScale;
|
||||
extern idCVar af_jointFrictionScale;
|
||||
extern idCVar af_contactFrictionScale;
|
||||
extern idCVar af_highlightBody;
|
||||
extern idCVar af_highlightConstraint;
|
||||
extern idCVar af_showTimings;
|
||||
extern idCVar af_showConstraints;
|
||||
extern idCVar af_showConstraintNames;
|
||||
extern idCVar af_showConstrainedBodies;
|
||||
extern idCVar af_showPrimaryOnly;
|
||||
extern idCVar af_showTrees;
|
||||
extern idCVar af_showLimits;
|
||||
extern idCVar af_showBodies;
|
||||
extern idCVar af_showBodyNames;
|
||||
extern idCVar af_showMass;
|
||||
extern idCVar af_showTotalMass;
|
||||
extern idCVar af_showInertia;
|
||||
extern idCVar af_showVelocity;
|
||||
extern idCVar af_showActive;
|
||||
extern idCVar af_testSolid;
|
||||
|
||||
extern idCVar rb_showTimings;
|
||||
extern idCVar rb_showBodies;
|
||||
extern idCVar rb_showMass;
|
||||
extern idCVar rb_showInertia;
|
||||
extern idCVar rb_showVelocity;
|
||||
extern idCVar rb_showActive;
|
||||
|
||||
extern idCVar pm_jumpheight;
|
||||
extern idCVar pm_stepsize;
|
||||
extern idCVar pm_crouchspeed;
|
||||
extern idCVar pm_walkspeed;
|
||||
extern idCVar pm_runspeed;
|
||||
extern idCVar pm_noclipspeed;
|
||||
extern idCVar pm_spectatespeed;
|
||||
extern idCVar pm_spectatebbox;
|
||||
extern idCVar pm_usecylinder;
|
||||
extern idCVar pm_minviewpitch;
|
||||
extern idCVar pm_maxviewpitch;
|
||||
extern idCVar pm_stamina;
|
||||
extern idCVar pm_staminathreshold;
|
||||
extern idCVar pm_staminarate;
|
||||
extern idCVar pm_crouchheight;
|
||||
extern idCVar pm_crouchviewheight;
|
||||
extern idCVar pm_normalheight;
|
||||
extern idCVar pm_normalviewheight;
|
||||
extern idCVar pm_deadheight;
|
||||
extern idCVar pm_deadviewheight;
|
||||
extern idCVar pm_crouchrate;
|
||||
extern idCVar pm_bboxwidth;
|
||||
extern idCVar pm_crouchbob;
|
||||
extern idCVar pm_walkbob;
|
||||
extern idCVar pm_runbob;
|
||||
extern idCVar pm_runpitch;
|
||||
extern idCVar pm_runroll;
|
||||
extern idCVar pm_bobup;
|
||||
extern idCVar pm_bobpitch;
|
||||
extern idCVar pm_bobroll;
|
||||
extern idCVar pm_thirdPersonRange;
|
||||
extern idCVar pm_thirdPersonHeight;
|
||||
extern idCVar pm_thirdPersonAngle;
|
||||
extern idCVar pm_thirdPersonClip;
|
||||
extern idCVar pm_thirdPerson;
|
||||
extern idCVar pm_thirdPersonDeath;
|
||||
extern idCVar pm_modelView;
|
||||
extern idCVar pm_airMsec;
|
||||
|
||||
extern idCVar g_showPlayerShadow;
|
||||
extern idCVar g_showHud;
|
||||
extern idCVar g_showProjectilePct;
|
||||
extern idCVar g_showBrass;
|
||||
extern idCVar g_gun_x;
|
||||
extern idCVar g_gun_y;
|
||||
extern idCVar g_gun_z;
|
||||
extern idCVar g_gunScale;
|
||||
extern idCVar g_viewNodalX;
|
||||
extern idCVar g_viewNodalZ;
|
||||
extern idCVar g_fov;
|
||||
extern idCVar g_testDeath;
|
||||
extern idCVar g_skipViewEffects;
|
||||
extern idCVar g_mpWeaponAngleScale;
|
||||
|
||||
extern idCVar g_testParticle;
|
||||
extern idCVar g_testParticleName;
|
||||
|
||||
extern idCVar g_testPostProcess;
|
||||
|
||||
extern idCVar g_testModelRotate;
|
||||
extern idCVar g_testModelAnimate;
|
||||
extern idCVar g_testModelBlend;
|
||||
extern idCVar g_flushSave;
|
||||
|
||||
extern idCVar g_enableSlowmo;
|
||||
extern idCVar g_slowmoStepRate;
|
||||
extern idCVar g_testFullscreenFX;
|
||||
extern idCVar g_testHelltimeFX;
|
||||
extern idCVar g_testMultiplayerFX;
|
||||
extern idCVar g_moveableDamageScale;
|
||||
extern idCVar g_testBloomIntensity;
|
||||
extern idCVar g_testBloomNumPasses;
|
||||
|
||||
extern idCVar g_grabberHoldSeconds;
|
||||
extern idCVar g_grabberEnableShake;
|
||||
extern idCVar g_grabberRandomMotion;
|
||||
extern idCVar g_grabberHardStop;
|
||||
extern idCVar g_grabberDamping;
|
||||
|
||||
extern idCVar g_xp_bind_run_once;
|
||||
|
||||
extern idCVar aas_test;
|
||||
extern idCVar aas_showAreas;
|
||||
extern idCVar aas_showPath;
|
||||
extern idCVar aas_showFlyPath;
|
||||
extern idCVar aas_showWallEdges;
|
||||
extern idCVar aas_showHideArea;
|
||||
extern idCVar aas_pullPlayer;
|
||||
extern idCVar aas_randomPullPlayer;
|
||||
extern idCVar aas_goalArea;
|
||||
extern idCVar aas_showPushIntoArea;
|
||||
|
||||
extern idCVar net_clientPredictGUI;
|
||||
|
||||
extern idCVar si_timeLimit;
|
||||
extern idCVar si_fragLimit;
|
||||
extern idCVar si_spectators;
|
||||
|
||||
extern idCVar si_flagDropTimeLimit;
|
||||
extern idCVar si_midnight;
|
||||
|
||||
extern idCVar g_flagAttachJoint;
|
||||
extern idCVar g_flagAttachOffsetX;
|
||||
extern idCVar g_flagAttachOffsetY;
|
||||
extern idCVar g_flagAttachOffsetZ;
|
||||
extern idCVar g_flagAttachAngleX;
|
||||
extern idCVar g_flagAttachAngleY;
|
||||
extern idCVar g_flagAttachAngleZ;
|
||||
|
||||
extern idCVar g_CTFArrows;
|
||||
|
||||
extern idCVar net_clientSelfSmoothing;
|
||||
|
||||
#endif /* !__SYS_CVAR_H__ */
|
||||
449
neo/d3xp/menus/MenuHandler.cpp
Normal file
449
neo/d3xp/menus/MenuHandler.cpp
Normal file
@@ -0,0 +1,449 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma hdrstop
|
||||
#include "../../idLib/precompiled.h"
|
||||
#include "../Game_local.h"
|
||||
|
||||
extern idCVar in_useJoystick;
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler::~idMenuHandler
|
||||
================================================
|
||||
*/
|
||||
idMenuHandler::idMenuHandler() {
|
||||
scrollingMenu = false;
|
||||
scrollCounter = 0;
|
||||
activeScreen = -1;
|
||||
nextScreen = -1;
|
||||
transition = -1;
|
||||
platform = 0;
|
||||
gui = NULL;
|
||||
cmdBar = NULL;
|
||||
|
||||
for ( int index = 0; index < MAX_SCREEN_AREAS; ++index ) {
|
||||
menuScreens[ index ] = NULL;
|
||||
}
|
||||
|
||||
sounds.SetNum( NUM_GUI_SOUNDS );
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler::~idMenuHandler
|
||||
================================================
|
||||
*/
|
||||
idMenuHandler::~idMenuHandler() {
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler::Initialize
|
||||
================================================
|
||||
*/
|
||||
void idMenuHandler::Initialize( const char * swfFile, idSoundWorld * sw ) {
|
||||
Cleanup();
|
||||
gui = new idSWF( swfFile, sw );
|
||||
|
||||
platform = 2;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler::AddChild
|
||||
================================================
|
||||
*/
|
||||
void idMenuHandler::AddChild( idMenuWidget * widget ) {
|
||||
widget->SetSWFObj( gui );
|
||||
widget->SetHandlerIsParent( true );
|
||||
children.Append( widget );
|
||||
widget->AddRef();
|
||||
}
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler::GetChildFromIndex
|
||||
================================================
|
||||
*/
|
||||
idMenuWidget * idMenuHandler::GetChildFromIndex( int index ) {
|
||||
|
||||
if ( children.Num() == 0 ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( index > children.Num() ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return children[ index ];
|
||||
}
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler::GetPlatform
|
||||
================================================
|
||||
*/
|
||||
int idMenuHandler::GetPlatform( bool realPlatform ) {
|
||||
|
||||
if ( platform == 2 && in_useJoystick.GetBool() && !realPlatform ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return platform;
|
||||
}
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler::GetPlatform
|
||||
================================================
|
||||
*/
|
||||
void idMenuHandler::PlaySound( menuSounds_t type, int channel ) {
|
||||
|
||||
if ( gui == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( type >= sounds.Num() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( sounds[ type ].IsEmpty() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
int c = SCHANNEL_ANY;
|
||||
if ( channel != -1 ) {
|
||||
c = channel;
|
||||
}
|
||||
|
||||
gui->PlaySound( sounds[ type ], c );
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler::StopSound
|
||||
================================================
|
||||
*/
|
||||
void idMenuHandler::StopSound( int channel ) {
|
||||
gui->StopSound();
|
||||
}
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler::Cleanup
|
||||
================================================
|
||||
*/
|
||||
void idMenuHandler::Cleanup() {
|
||||
for ( int index = 0; index < children.Num(); ++index ) {
|
||||
assert( children[ index ]->GetRefCount() > 0 );
|
||||
children[ index ]->Release();
|
||||
}
|
||||
children.Clear();
|
||||
|
||||
for ( int index = 0; index < MAX_SCREEN_AREAS; ++index ) {
|
||||
if ( menuScreens[ index ] != NULL ) {
|
||||
menuScreens[ index ]->Release();
|
||||
}
|
||||
}
|
||||
|
||||
delete gui;
|
||||
gui = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler::TriggerMenu
|
||||
================================================
|
||||
*/
|
||||
void idMenuHandler::TriggerMenu() {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler::IsActive
|
||||
================================================
|
||||
*/
|
||||
bool idMenuHandler::IsActive() {
|
||||
if ( gui == NULL ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return gui->IsActive();
|
||||
}
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler::ActivateMenu
|
||||
================================================
|
||||
*/
|
||||
void idMenuHandler::ActivateMenu( bool show ) {
|
||||
|
||||
if ( gui == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !show ) {
|
||||
gui->Activate( show );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
class idSWFScriptFunction_updateMenuDisplay : public idSWFScriptFunction_RefCounted {
|
||||
public:
|
||||
idSWFScriptFunction_updateMenuDisplay( idSWF * _gui, idMenuHandler * _handler ) {
|
||||
gui = _gui;
|
||||
handler = _handler;
|
||||
}
|
||||
idSWFScriptVar Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ) {
|
||||
if ( handler != NULL ) {
|
||||
int screen = parms[0].ToInteger();
|
||||
handler->UpdateMenuDisplay( screen );
|
||||
}
|
||||
|
||||
return idSWFScriptVar();
|
||||
}
|
||||
private:
|
||||
idSWF * gui;
|
||||
idMenuHandler * handler;
|
||||
};
|
||||
|
||||
class idSWFScriptFunction_activateMenu : public idSWFScriptFunction_RefCounted {
|
||||
public:
|
||||
idSWFScriptFunction_activateMenu( idMenuHandler * _handler ) {
|
||||
handler = _handler;
|
||||
}
|
||||
idSWFScriptVar Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ) {
|
||||
if ( handler != NULL ) {
|
||||
handler->TriggerMenu();
|
||||
}
|
||||
|
||||
return idSWFScriptVar();
|
||||
}
|
||||
private:
|
||||
idMenuHandler * handler;
|
||||
};
|
||||
|
||||
gui->SetGlobal( "updateMenuDisplay", new (TAG_SWF) idSWFScriptFunction_updateMenuDisplay( gui, this ) );
|
||||
gui->SetGlobal( "activateMenus", new (TAG_SWF) idSWFScriptFunction_activateMenu( this ) );
|
||||
|
||||
gui->Activate( show );
|
||||
}
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler::Update
|
||||
================================================
|
||||
*/
|
||||
void idMenuHandler::Update() {
|
||||
|
||||
PumpWidgetActionRepeater();
|
||||
|
||||
if ( gui != NULL && gui->IsActive() ) {
|
||||
gui->Render( renderSystem, Sys_Milliseconds() );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler::UpdateChildren
|
||||
================================================
|
||||
*/
|
||||
void idMenuHandler::UpdateChildren() {
|
||||
for ( int index = 0; index < children.Num(); ++index ) {
|
||||
if ( children[ index ] != NULL ) {
|
||||
children[index]->Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler::UpdateMenuDisplay
|
||||
================================================
|
||||
*/
|
||||
void idMenuHandler::UpdateMenuDisplay( int menu ) {
|
||||
|
||||
if ( menuScreens[ menu ] != NULL ) {
|
||||
menuScreens[ menu ]->Update();
|
||||
}
|
||||
|
||||
UpdateChildren();
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler::Update
|
||||
================================================
|
||||
*/
|
||||
bool idMenuHandler::HandleGuiEvent( const sysEvent_t * sev ) {
|
||||
|
||||
if ( gui != NULL && activeScreen != -1 ) {
|
||||
return gui->HandleEvent( sev );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler::Update
|
||||
================================================
|
||||
*/
|
||||
bool idMenuHandler::HandleAction( idWidgetAction & action, const idWidgetEvent & event, idMenuWidget * widget, bool forceHandled ) {
|
||||
|
||||
widgetAction_t actionType = action.GetType();
|
||||
const idSWFParmList & parms = action.GetParms();
|
||||
|
||||
switch ( actionType ) {
|
||||
case WIDGET_ACTION_ADJUST_FIELD: {
|
||||
if ( widget != NULL && widget->GetDataSource() != NULL ) {
|
||||
widget->GetDataSource()->AdjustField( widget->GetDataSourceFieldIndex(), parms[ 0 ].ToInteger() );
|
||||
widget->Update();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case WIDGET_ACTION_FUNCTION: {
|
||||
if ( verify( action.GetScriptFunction() != NULL ) ) {
|
||||
action.GetScriptFunction()->Call( event.thisObject, event.parms );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case WIDGET_ACTION_PRESS_FOCUSED: {
|
||||
idMenuScreen * const screen = menuScreens[ activeScreen ];
|
||||
if ( screen != NULL ) {
|
||||
idWidgetEvent pressEvent( WIDGET_EVENT_PRESS, 0, event.thisObject, idSWFParmList() );
|
||||
screen->ReceiveEvent( pressEvent );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case WIDGET_ACTION_START_REPEATER: {
|
||||
idWidgetAction repeatAction;
|
||||
widgetAction_t repeatActionType = static_cast< widgetAction_t >( parms[ 0 ].ToInteger() );
|
||||
assert( parms.Num() >= 2 );
|
||||
int repeatDelay = DEFAULT_REPEAT_TIME;
|
||||
if ( parms.Num() >= 3 ) {
|
||||
repeatDelay = parms[2].ToInteger();
|
||||
}
|
||||
repeatAction.Set( repeatActionType, parms[ 1 ], repeatDelay );
|
||||
StartWidgetActionRepeater( widget, repeatAction, event );
|
||||
return true;
|
||||
}
|
||||
case WIDGET_ACTION_STOP_REPEATER: {
|
||||
ClearWidgetActionRepeater();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !widget->GetHandlerIsParent() ) {
|
||||
for ( int index = 0; index < children.Num(); ++index ) {
|
||||
if ( children[index] != NULL ) {
|
||||
if ( children[index]->HandleAction( action, event, widget, forceHandled ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idMenuHandler::StartWidgetActionRepeater
|
||||
========================
|
||||
*/
|
||||
void idMenuHandler::StartWidgetActionRepeater( idMenuWidget * widget, const idWidgetAction & action, const idWidgetEvent & event ) {
|
||||
if ( actionRepeater.isActive && actionRepeater.action == action ) {
|
||||
return; // don't attempt to reactivate an already active repeater
|
||||
}
|
||||
|
||||
actionRepeater.isActive = true;
|
||||
actionRepeater.action = action;
|
||||
actionRepeater.widget = widget;
|
||||
actionRepeater.event = event;
|
||||
actionRepeater.numRepetitions = 0;
|
||||
actionRepeater.nextRepeatTime = 0;
|
||||
actionRepeater.screenIndex = activeScreen; // repeaters are cleared between screens
|
||||
|
||||
if ( action.GetParms().Num() == 2 ) {
|
||||
actionRepeater.repeatDelay = action.GetParms()[ 1 ].ToInteger();
|
||||
} else {
|
||||
actionRepeater.repeatDelay = DEFAULT_REPEAT_TIME;
|
||||
}
|
||||
|
||||
// do the first event immediately
|
||||
PumpWidgetActionRepeater();
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idMenuHandler::PumpWidgetActionRepeater
|
||||
========================
|
||||
*/
|
||||
void idMenuHandler::PumpWidgetActionRepeater() {
|
||||
if ( !actionRepeater.isActive ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( activeScreen != actionRepeater.screenIndex || nextScreen != activeScreen ) { // || common->IsDialogActive() ) {
|
||||
actionRepeater.isActive = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( actionRepeater.nextRepeatTime > Sys_Milliseconds() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// need to hold down longer on the first iteration before we continue to scroll
|
||||
if ( actionRepeater.numRepetitions == 0 ) {
|
||||
actionRepeater.nextRepeatTime = Sys_Milliseconds() + 400;
|
||||
} else {
|
||||
actionRepeater.nextRepeatTime = Sys_Milliseconds() + actionRepeater.repeatDelay;
|
||||
}
|
||||
|
||||
if ( verify( actionRepeater.widget != NULL ) ) {
|
||||
actionRepeater.widget->HandleAction( actionRepeater.action, actionRepeater.event, actionRepeater.widget );
|
||||
actionRepeater.numRepetitions++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idMenuHandler::ClearWidgetActionRepeater
|
||||
========================
|
||||
*/
|
||||
void idMenuHandler::ClearWidgetActionRepeater() {
|
||||
actionRepeater.isActive = false;
|
||||
}
|
||||
516
neo/d3xp/menus/MenuHandler.h
Normal file
516
neo/d3xp/menus/MenuHandler.h
Normal file
@@ -0,0 +1,516 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#ifndef __MENUDATA_H__
|
||||
#define __MENUDATA_H__
|
||||
|
||||
enum shellAreas_t {
|
||||
SHELL_AREA_INVALID = -1,
|
||||
SHELL_AREA_START,
|
||||
SHELL_AREA_ROOT,
|
||||
SHELL_AREA_DEV,
|
||||
SHELL_AREA_CAMPAIGN,
|
||||
SHELL_AREA_LOAD,
|
||||
SHELL_AREA_SAVE,
|
||||
SHELL_AREA_NEW_GAME,
|
||||
SHELL_AREA_GAME_OPTIONS,
|
||||
SHELL_AREA_SYSTEM_OPTIONS,
|
||||
SHELL_AREA_MULTIPLAYER,
|
||||
SHELL_AREA_GAME_LOBBY,
|
||||
SHELL_AREA_STEREOSCOPICS,
|
||||
SHELL_AREA_PARTY_LOBBY,
|
||||
SHELL_AREA_SETTINGS,
|
||||
SHELL_AREA_AUDIO,
|
||||
SHELL_AREA_VIDEO,
|
||||
SHELL_AREA_KEYBOARD,
|
||||
SHELL_AREA_CONTROLS,
|
||||
SHELL_AREA_CONTROLLER_LAYOUT,
|
||||
SHELL_AREA_GAMEPAD,
|
||||
SHELL_AREA_PAUSE,
|
||||
SHELL_AREA_LEADERBOARDS,
|
||||
SHELL_AREA_PLAYSTATION,
|
||||
SHELL_AREA_DIFFICULTY,
|
||||
SHELL_AREA_RESOLUTION,
|
||||
SHELL_AREA_MATCH_SETTINGS,
|
||||
SHELL_AREA_MODE_SELECT,
|
||||
SHELL_AREA_BROWSER,
|
||||
SHELL_AREA_CREDITS,
|
||||
SHELL_NUM_AREAS
|
||||
};
|
||||
|
||||
enum shellState_t {
|
||||
SHELL_STATE_INVALID = -1,
|
||||
SHELL_STATE_PRESS_START,
|
||||
SHELL_STATE_IDLE,
|
||||
SHELL_STATE_PARTY_LOBBY,
|
||||
SHELL_STATE_GAME_LOBBY,
|
||||
SHELL_STATE_PAUSED,
|
||||
SHELL_STATE_CONNECTING,
|
||||
SHELL_STATE_SEARCHING,
|
||||
SHELL_STATE_LOADING,
|
||||
SHELL_STATE_BUSY,
|
||||
SHELL_STATE_IN_GAME
|
||||
};
|
||||
|
||||
enum pdaAreas_t {
|
||||
PDA_AREA_INVALID = -1,
|
||||
PDA_AREA_USER_DATA,
|
||||
PDA_AREA_USER_EMAIL,
|
||||
PDA_AREA_VIDEO_DISKS,
|
||||
PDA_AREA_INVENTORY,
|
||||
PDA_NUM_AREAS
|
||||
};
|
||||
|
||||
enum hudArea_t {
|
||||
HUD_AREA_INVALID = -1,
|
||||
HUD_AREA_PLAYING,
|
||||
HUD_NUM_AREAS
|
||||
};
|
||||
|
||||
enum scoreboardArea_t {
|
||||
SCOREBOARD_AREA_INVALID = -1,
|
||||
SCOREBOARD_AREA_DEFAULT,
|
||||
SCOREBOARD_AREA_TEAM,
|
||||
SCOREBOARD_AREA_CTF,
|
||||
SCOREBOARD_NUM_AREAS
|
||||
};
|
||||
|
||||
enum pdaHandlerWidgets_t {
|
||||
PDA_WIDGET_NAV_BAR,
|
||||
PDA_WIDGET_PDA_LIST,
|
||||
PDA_WIDGET_PDA_LIST_SCROLLBAR,
|
||||
PDA_WIDGET_CMD_BAR
|
||||
};
|
||||
|
||||
enum scoreboardHandlerWidgets_t {
|
||||
SCOREBOARD_WIDGET_CMD_BAR,
|
||||
};
|
||||
|
||||
enum menuSounds_t {
|
||||
GUI_SOUND_MUSIC,
|
||||
GUI_SOUND_SCROLL,
|
||||
GUI_SOUND_ADVANCE,
|
||||
GUI_SOUND_BACK,
|
||||
GUI_SOUND_BUILD_ON,
|
||||
GUI_SOUND_BUILD_OFF,
|
||||
GUI_SOUND_FOCUS,
|
||||
GUI_SOUND_ROLL_OVER,
|
||||
GUI_SOUND_ROLL_OUT,
|
||||
NUM_GUI_SOUNDS,
|
||||
};
|
||||
|
||||
static const int MAX_SCREEN_AREAS = 32;
|
||||
static const int DEFAULT_REPEAT_TIME = 150;
|
||||
static const int WAIT_START_TIME_LONG = 30000;
|
||||
static const int WAIT_START_TIME_SHORT = 5000;
|
||||
|
||||
struct actionRepeater_t {
|
||||
actionRepeater_t() :
|
||||
widget( NULL ),
|
||||
numRepetitions( 0 ),
|
||||
nextRepeatTime( 0 ),
|
||||
screenIndex( -1 ),
|
||||
repeatDelay( DEFAULT_REPEAT_TIME ),
|
||||
isActive( false ) {
|
||||
}
|
||||
|
||||
idMenuWidget * widget;
|
||||
idWidgetEvent event;
|
||||
idWidgetAction action;
|
||||
int numRepetitions;
|
||||
int nextRepeatTime;
|
||||
int repeatDelay;
|
||||
int screenIndex;
|
||||
bool isActive;
|
||||
};
|
||||
|
||||
class mpScoreboardInfo{
|
||||
public:
|
||||
|
||||
mpScoreboardInfo() :
|
||||
voiceState( VOICECHAT_DISPLAY_NONE ),
|
||||
score( 0 ),
|
||||
wins( 0 ),
|
||||
ping( 0 ),
|
||||
team( -1 ),
|
||||
playerNum( 0 ) {
|
||||
}
|
||||
|
||||
mpScoreboardInfo( const mpScoreboardInfo & src ) {
|
||||
voiceState = src.voiceState;
|
||||
score = src.score;
|
||||
wins = src.wins;
|
||||
ping = src.ping;
|
||||
spectateData = src.spectateData;
|
||||
name = src.name;
|
||||
team = src.team;
|
||||
playerNum = src.playerNum;
|
||||
}
|
||||
|
||||
void operator=( const mpScoreboardInfo & src ) {
|
||||
voiceState = src.voiceState;
|
||||
score = src.score;
|
||||
wins = src.wins;
|
||||
ping = src.ping;
|
||||
spectateData = src.spectateData;
|
||||
name = src.name;
|
||||
team = src.team;
|
||||
playerNum = src.playerNum;
|
||||
}
|
||||
|
||||
bool operator!=( const mpScoreboardInfo & otherInfo ) const {
|
||||
|
||||
if ( otherInfo.score != score || otherInfo.wins != wins || otherInfo.ping != ping ||
|
||||
otherInfo.spectateData != spectateData || otherInfo.name != name || otherInfo.team != team ||
|
||||
otherInfo.playerNum != playerNum || otherInfo.voiceState != voiceState ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==( const mpScoreboardInfo & otherInfo ) const {
|
||||
|
||||
if ( otherInfo.score != score || otherInfo.wins != wins || otherInfo.ping != ping ||
|
||||
otherInfo.spectateData != spectateData || otherInfo.name != name || otherInfo.team != team ||
|
||||
otherInfo.playerNum != playerNum || otherInfo.voiceState != voiceState ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
voiceStateDisplay_t voiceState;
|
||||
int score;
|
||||
int wins;
|
||||
int ping;
|
||||
int team;
|
||||
int playerNum;
|
||||
idStr spectateData;
|
||||
idStr name;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler
|
||||
================================================
|
||||
*/
|
||||
class idMenuHandler {
|
||||
public:
|
||||
idMenuHandler();
|
||||
virtual ~idMenuHandler();
|
||||
virtual void Initialize( const char * swfFile, idSoundWorld * sw );
|
||||
virtual void Cleanup();
|
||||
virtual void Update();
|
||||
virtual void UpdateChildren();
|
||||
virtual void UpdateMenuDisplay( int menu );
|
||||
virtual bool HandleGuiEvent( const sysEvent_t * sev );
|
||||
virtual bool IsActive();
|
||||
virtual void ActivateMenu( bool show );
|
||||
virtual void TriggerMenu();
|
||||
virtual bool HandleAction( idWidgetAction & action, const idWidgetEvent & event, idMenuWidget * widget, bool forceHandled = false );
|
||||
virtual int ActiveScreen() { return activeScreen; }
|
||||
virtual int NextScreen() { return nextScreen; }
|
||||
virtual int MenuTransition() { return transition; }
|
||||
virtual idMenuScreen * GetMenuScreen( int index ) { return NULL; }
|
||||
virtual void SetNextScreen( int screen, int trans ) { nextScreen = screen; transition = trans; }
|
||||
|
||||
virtual void StartWidgetActionRepeater( idMenuWidget * widget, const idWidgetAction & action, const idWidgetEvent & event );
|
||||
virtual void PumpWidgetActionRepeater();
|
||||
virtual void ClearWidgetActionRepeater();
|
||||
virtual idSWF * GetGUI() { return gui; }
|
||||
virtual void AddChild( idMenuWidget * widget );
|
||||
virtual idMenuWidget * GetChildFromIndex( int index );
|
||||
virtual int GetPlatform( bool realPlatform = false );
|
||||
virtual void PlaySound( menuSounds_t type, int channel = -1 );
|
||||
virtual void StopSound( int channel = SCHANNEL_ANY );
|
||||
|
||||
idMenuWidget_CommandBar * GetCmdBar() { return cmdBar; }
|
||||
|
||||
protected:
|
||||
|
||||
bool scrollingMenu;
|
||||
int scrollCounter;
|
||||
int activeScreen;
|
||||
int nextScreen;
|
||||
int transition;
|
||||
int platform;
|
||||
idSWF * gui;
|
||||
actionRepeater_t actionRepeater;
|
||||
idMenuScreen * menuScreens[MAX_SCREEN_AREAS];
|
||||
idList< idMenuWidget *, TAG_IDLIB_LIST_MENU> children;
|
||||
|
||||
idStaticList< idStr, NUM_GUI_SOUNDS > sounds;
|
||||
|
||||
idMenuWidget_CommandBar * cmdBar;
|
||||
};
|
||||
|
||||
/*
|
||||
================================================
|
||||
lobbyPlayerInfo_t
|
||||
================================================
|
||||
*/
|
||||
struct lobbyPlayerInfo_t {
|
||||
lobbyPlayerInfo_t() :
|
||||
partyToken( 0 ),
|
||||
voiceState( VOICECHAT_DISPLAY_NONE ) {
|
||||
}
|
||||
|
||||
idStr name;
|
||||
int partyToken;
|
||||
voiceStateDisplay_t voiceState;
|
||||
};
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler_Shell
|
||||
================================================
|
||||
*/
|
||||
class idMenuHandler_Shell : public idMenuHandler {
|
||||
public:
|
||||
idMenuHandler_Shell() :
|
||||
state( SHELL_STATE_INVALID ),
|
||||
nextState( SHELL_STATE_INVALID ),
|
||||
smallFrameShowing( false ),
|
||||
largeFrameShowing( false ),
|
||||
bgShowing( true ),
|
||||
nextPeerUpdateMs( 0 ),
|
||||
inGame( false ),
|
||||
waitForBinding( false ),
|
||||
waitBind( NULL ),
|
||||
newGameType( 0 ),
|
||||
menuBar( NULL ),
|
||||
pacifier( NULL ),
|
||||
showingIntro( false ),
|
||||
introGui( NULL ),
|
||||
doom3Intro( NULL ),
|
||||
roeIntro( NULL ),
|
||||
lmIntro( NULL ),
|
||||
typeSoundShader( NULL ),
|
||||
continueWaitForEnumerate( false ),
|
||||
gameComplete( false ),
|
||||
marsRotation( NULL ) {
|
||||
}
|
||||
virtual void Update();
|
||||
virtual void ActivateMenu( bool show );
|
||||
virtual void Initialize( const char * swfFile, idSoundWorld * sw );
|
||||
virtual void Cleanup();
|
||||
virtual bool HandleAction( idWidgetAction & action, const idWidgetEvent & event, idMenuWidget * widget, bool forceHandled = false );
|
||||
virtual idMenuScreen * GetMenuScreen( int index );
|
||||
virtual bool HandleGuiEvent( const sysEvent_t * sev );
|
||||
|
||||
void UpdateSavedGames();
|
||||
void ShowSmallFrame( bool show );
|
||||
void ShowMPFrame( bool show );
|
||||
void ShowLogo( bool show );
|
||||
void SetShellState( shellState_t s ) { nextState = s; }
|
||||
bool IsSmallFrameShowing() { return smallFrameShowing; }
|
||||
void UpdateBGState();
|
||||
void GetMapName( int index, idStr & name );
|
||||
void GetModeName( int index, idStr & name );
|
||||
|
||||
idMenuWidget * GetPacifier() { return pacifier; }
|
||||
idMenuWidget_MenuBar * GetMenuBar() { return menuBar; }
|
||||
bool IsPacifierVisible() const { return ( pacifier != NULL && pacifier->GetSprite() != NULL ) ? pacifier->GetSprite()->IsVisible() : false; }
|
||||
void ShowPacifier( const idStr & msg );
|
||||
void HidePacifier();
|
||||
|
||||
void SetTimeRemaining( int time ) { timeRemaining = time; }
|
||||
int GetTimeRemaining() { return timeRemaining; }
|
||||
void SetNewGameType( int type ) { newGameType = type; }
|
||||
int GetNewGameType() { return newGameType; }
|
||||
void SetInGame( bool val ) { inGame = val; }
|
||||
bool GetInGame() { return inGame; }
|
||||
void HandleExitGameBtn();
|
||||
void SetupPCOptions();
|
||||
void SetWaitForBinding( const char * bind ) { waitForBinding = true; waitBind = bind; }
|
||||
void ClearWaitForBinding() { waitForBinding = false; }
|
||||
void UpdateLeaderboard( const idLeaderboardCallback * callback );
|
||||
void UpdateLobby( idMenuWidget_LobbyList * lobbyList );
|
||||
void ShowDoomIntro();
|
||||
void ShowROEIntro();
|
||||
void ShowLEIntro();
|
||||
void StartGame( int index );
|
||||
void SetContinueWaitForEnumerate( bool wait ) { continueWaitForEnumerate = wait; }
|
||||
void SetCanContinue( bool valid );
|
||||
void SetGameComplete() { gameComplete = true; }
|
||||
bool GetGameComplete() { return gameComplete; }
|
||||
|
||||
private:
|
||||
|
||||
shellState_t state;
|
||||
shellState_t nextState;
|
||||
bool smallFrameShowing;
|
||||
bool largeFrameShowing;
|
||||
bool bgShowing;
|
||||
bool waitForBinding;
|
||||
const char * waitBind;
|
||||
//idSysSignal deviceRequestedSignal;
|
||||
|
||||
idList<const char *, TAG_IDLIB_LIST_MENU> mpGameModes;
|
||||
idList<mpMap_t, TAG_IDLIB_LIST_MENU> mpGameMaps;
|
||||
idMenuWidget_MenuBar * menuBar;
|
||||
idMenuWidget * pacifier;
|
||||
int timeRemaining;
|
||||
int nextPeerUpdateMs;
|
||||
int newGameType;
|
||||
bool inGame;
|
||||
bool showingIntro;
|
||||
bool continueWaitForEnumerate;
|
||||
bool gameComplete;
|
||||
idSWF * introGui;
|
||||
const idSoundShader * typeSoundShader;
|
||||
const idMaterial * doom3Intro;
|
||||
const idMaterial * roeIntro;
|
||||
const idMaterial * lmIntro;
|
||||
const idMaterial * marsRotation;
|
||||
idList< idStr, TAG_IDLIB_LIST_MENU> navOptions;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler_PDA
|
||||
================================================
|
||||
*/
|
||||
class idMenuHandler_PDA : public idMenuHandler {
|
||||
public:
|
||||
idMenuHandler_PDA() :
|
||||
audioLogPlaying( false ),
|
||||
videoPlaying( false ),
|
||||
audioFile( NULL ) {
|
||||
}
|
||||
virtual ~idMenuHandler_PDA();
|
||||
|
||||
virtual void Update();
|
||||
virtual void ActivateMenu( bool show );
|
||||
virtual void TriggerMenu();
|
||||
virtual void Initialize( const char * swfFile, idSoundWorld * sw );
|
||||
virtual bool HandleAction( idWidgetAction & action, const idWidgetEvent & event, idMenuWidget * widget, bool forceHandled = false );
|
||||
virtual idMenuScreen * GetMenuScreen( int index );
|
||||
void UpdateAudioLogPlaying( bool playing );
|
||||
void UdpateVideoPlaying( bool playing );
|
||||
void ClearVideoPlaying() { videoPlaying = false; }
|
||||
|
||||
bool PlayPDAAudioLog( int pdaIndex, int audioIndex );
|
||||
virtual void Cleanup();
|
||||
|
||||
protected:
|
||||
|
||||
bool audioLogPlaying;
|
||||
bool videoPlaying;
|
||||
idList< idList< idStr, TAG_IDLIB_LIST_MENU >, TAG_IDLIB_LIST_MENU > pdaNames;
|
||||
idList< idStr, TAG_IDLIB_LIST_MENU > navOptions;
|
||||
const idDeclAudio * audioFile;
|
||||
idMenuWidget_ScrollBar pdaScrollBar;
|
||||
idMenuWidget_DynamicList pdaList;
|
||||
idMenuWidget_NavBar navBar;
|
||||
idMenuWidget_CommandBar commandBarWidget;
|
||||
};
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler_PDA
|
||||
================================================
|
||||
*/
|
||||
class idMenuHandler_HUD : public idMenuHandler {
|
||||
public:
|
||||
|
||||
idMenuHandler_HUD() :
|
||||
autoHideTip( true ),
|
||||
tipStartTime( 0 ),
|
||||
hiding( false ),
|
||||
radioMessage( false ) {
|
||||
}
|
||||
|
||||
virtual void Update();
|
||||
virtual void ActivateMenu( bool show );
|
||||
virtual void Initialize( const char * swfFile, idSoundWorld * sw );
|
||||
virtual idMenuScreen * GetMenuScreen( int index );
|
||||
|
||||
idMenuScreen_HUD * GetHud();
|
||||
void ShowTip( const char * title, const char * tip, bool autoHide );
|
||||
void HideTip();
|
||||
void SetRadioMessage( bool show ) { radioMessage = show; }
|
||||
|
||||
protected:
|
||||
|
||||
bool autoHideTip;
|
||||
int tipStartTime;
|
||||
bool hiding;
|
||||
bool radioMessage;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
================================================
|
||||
idMenuHandler_Scoreboard
|
||||
================================================
|
||||
*/
|
||||
class idMenuHandler_Scoreboard : public idMenuHandler {
|
||||
public:
|
||||
|
||||
idMenuHandler_Scoreboard() :
|
||||
redScore( 0 ),
|
||||
blueScore( 0 ),
|
||||
activationScreen( SCOREBOARD_AREA_INVALID ) {
|
||||
}
|
||||
|
||||
virtual void Update();
|
||||
virtual void TriggerMenu();
|
||||
virtual void ActivateMenu( bool show );
|
||||
virtual void Initialize( const char * swfFile, idSoundWorld * sw );
|
||||
virtual idMenuScreen * GetMenuScreen( int index );
|
||||
virtual bool HandleAction( idWidgetAction & action, const idWidgetEvent & event, idMenuWidget * widget, bool forceHandled = false );
|
||||
|
||||
void AddPlayerInfo( int index, voiceStateDisplay_t voiceState, int team, idStr name, int score, int wins, int ping, idStr spectateData );
|
||||
void UpdateScoreboard( idList< mpScoreboardInfo > & data, idStr gameInfo );
|
||||
void UpdateVoiceStates();
|
||||
void UpdateSpectating( idStr spectate, idStr follow );
|
||||
void SetTeamScores( int r, int b );
|
||||
int GetNumPlayers( int team );
|
||||
void SetActivationScreen( int screen, int trans );
|
||||
void ViewPlayerProfile( int slot );
|
||||
void MutePlayer( int slot );
|
||||
void GetUserID( int slot, lobbyUserID_t & luid );
|
||||
void UpdateScoreboardSelection();
|
||||
|
||||
protected:
|
||||
|
||||
int redScore;
|
||||
int blueScore;
|
||||
int activationScreen;
|
||||
|
||||
idList< mpScoreboardInfo > scoreboardInfo;
|
||||
idList< scoreboardInfo_t, TAG_IDLIB_LIST_MENU > redInfo;
|
||||
idList< scoreboardInfo_t, TAG_IDLIB_LIST_MENU> blueInfo;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //__MENUDATA_H__
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user