hello world

This commit is contained in:
Timothee 'TTimo' Besset
2011-11-22 15:28:15 -06:00
commit fb1609f554
2155 changed files with 1017022 additions and 0 deletions

1271
neo/game/AF.cpp Normal file

File diff suppressed because it is too large Load Diff

120
neo/game/AF.h Normal file
View File

@@ -0,0 +1,120 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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( void );
~idAF( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void SetAnimator( idAnimator *a ) { animator = a; }
bool Load( idEntity *ent, const char *fileName );
bool IsLoaded( void ) const { return isLoaded && self != NULL; }
const char * GetName( void ) 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 );
void StartFromCurrentPose( int inheritVelocityTime );
void Stop( void );
void Rest( void );
bool IsActive( void ) const { return isActive; }
void SetConstraintPosition( const char *name, const idVec3 &pos );
idPhysics_AF * GetPhysics( void ) { return &physicsObj; }
const idPhysics_AF * GetPhysics( void ) const { return &physicsObj; }
idBounds GetBounds( void ) const;
bool UpdateAnimation( void );
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 );
void RemoveBindConstraints( void );
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>jointMods; // list with transforms from skeletal model joints to articulated figure bodies
idList<int> 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( void ) const;
};
#endif /* !__GAME_AF_H__ */

2879
neo/game/AFEntity.cpp Normal file

File diff suppressed because it is too large Load Diff

474
neo/game/AFEntity.h Normal file
View File

@@ -0,0 +1,474 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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( void );
~idMultiModelAF( void );
virtual void Think( void );
virtual void Present( void );
protected:
idPhysics_AF physicsObj;
void SetModelForId( int id, const idStr &modelName );
private:
idList<idRenderModel *> modelHandles;
idList<int> modelDefHandles;
};
/*
===============================================================================
idChain
Chain hanging down from the ceiling. Only used for debugging!
===============================================================================
*/
class idChain : public idMultiModelAF {
public:
CLASS_PROTOTYPE( idChain );
void Spawn( void );
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( void );
virtual ~idAFAttachment( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void SetBody( idEntity *bodyEnt, const char *headModel, jointHandle_t attachJoint );
void ClearBody( void );
idEntity * GetBody( void ) const;
virtual void Think( void );
virtual void Hide( void );
virtual void Show( void );
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( void );
idClipModel * GetCombatModel( void ) const;
virtual void LinkCombat( void );
virtual void UnlinkCombat( void );
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( void );
virtual ~idAFEntity_Base( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
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( void );
virtual void FreeModelDef( void );
virtual bool LoadAF( void );
bool IsActiveAF( void ) const { return af.IsActive(); }
const char * GetAFName( void ) const { return af.GetName(); }
idPhysics_AF * GetAFPhysics( void ) { return af.GetPhysics(); }
void SetCombatModel( void );
idClipModel * GetCombatModel( void ) const;
// contents of combatModel can be set to 0 or re-enabled (mp)
void SetCombatContents( bool enable );
virtual void LinkCombat( void );
virtual void UnlinkCombat( void );
int BodyForClipModelId( int id ) const;
void SaveState( idDict &args ) const;
void LoadState( const idDict &args );
void AddBindConstraints( void );
void RemoveBindConstraints( void );
virtual void ShowEditingDialog( void );
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( void );
~idAFEntity_Gibbable( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Present( void );
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
virtual void SpawnGibs( const idVec3 &dir, const char *damageDefName );
protected:
idRenderModel * skeletonModel;
int skeletonModelDefHandle;
bool gibbed;
virtual void Gib( const idVec3 &dir, const char *damageDefName );
void InitSkeletonModel( void );
void Event_Gib( const char *damageDefName );
};
/*
===============================================================================
idAFEntity_Generic
===============================================================================
*/
class idAFEntity_Generic : public idAFEntity_Gibbable {
public:
CLASS_PROTOTYPE( idAFEntity_Generic );
idAFEntity_Generic( void );
~idAFEntity_Generic( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
void KeepRunningPhysics( void ) { 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 );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void SetupHead( void );
virtual void Think( void );
virtual void Hide( void );
virtual void Show( void );
virtual void ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material );
virtual void LinkCombat( void );
virtual void UnlinkCombat( void );
protected:
virtual void Gib( const idVec3 &dir, const char *damageDefName );
private:
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 );
void Spawn( void );
void Use( idPlayer *player );
protected:
idPlayer * player;
jointHandle_t eyesJoint;
jointHandle_t steeringWheelJoint;
float wheelRadius;
float steerAngle;
float steerSpeed;
const idDeclParticle * dustSmoke;
float GetSteerAngle( void );
};
/*
===============================================================================
idAFEntity_VehicleSimple
===============================================================================
*/
class idAFEntity_VehicleSimple : public idAFEntity_Vehicle {
public:
CLASS_PROTOTYPE( idAFEntity_VehicleSimple );
idAFEntity_VehicleSimple( void );
~idAFEntity_VehicleSimple( void );
void Spawn( void );
virtual void Think( void );
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 );
void Spawn( void );
virtual void Think( void );
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 );
void Spawn( void );
virtual void Think( void );
private:
idAFBody * wheels[6];
idAFConstraint_Hinge * steering[4];
jointHandle_t wheelJoints[6];
float wheelAngles[6];
};
/*
===============================================================================
idAFEntity_SteamPipe
===============================================================================
*/
class idAFEntity_SteamPipe : public idAFEntity_Base {
public:
CLASS_PROTOTYPE( idAFEntity_SteamPipe );
idAFEntity_SteamPipe( void );
~idAFEntity_SteamPipe( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
private:
int steamBody;
float steamForce;
float steamUpForce;
idForce_Constant force;
renderEntity_t steamRenderEntity;
qhandle_t steamModelDefHandle;
void InitSteamRenderEntity( void );
};
/*
===============================================================================
idAFEntity_ClawFourFingers
===============================================================================
*/
class idAFEntity_ClawFourFingers : public idAFEntity_Base {
public:
CLASS_PROTOTYPE( idAFEntity_ClawFourFingers );
idAFEntity_ClawFourFingers( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
private:
idAFConstraint_Hinge * fingers[4];
void Event_SetFingerAngle( float angle );
void Event_StopFingers( void );
};
#endif /* !__GAME_AFENTITY_H__ */

3273
neo/game/Actor.cpp Normal file

File diff suppressed because it is too large Load Diff

319
neo/game/Actor.h Normal file
View File

@@ -0,0 +1,319 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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;
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 );
void SetState( const char *name, int blendFrames );
void StopAnim( int frames );
void PlayAnim( int anim );
void CycleAnim( int anim );
void BecomeIdle( void );
bool UpdateState( void );
bool Disabled( void ) const;
void Enable( int blendFrames );
void Disable( void );
bool AnimDone( int blendFrames ) const;
bool IsIdle( void ) const;
animFlags_t GetAnimFlags( void ) 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( void );
virtual ~idActor( void );
void Spawn( void );
virtual void Restart( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Hide( void );
virtual void Show( void );
virtual int GetDefaultSurfaceType( void ) const;
virtual void ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material );
virtual bool LoadAF( void );
void SetupBody( void );
void CheckBlink( void );
virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis );
virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis );
// script state management
void ShutdownThreads( void );
virtual bool ShouldConstructScriptObjectAtSpawn( void ) const;
virtual idThread * ConstructScriptObject( void );
void UpdateScript( void );
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( void ) const;
idVec3 EyeOffset( void ) const;
idVec3 GetEyePosition( void ) 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( void );
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( void );
virtual bool Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
// model/combat model/ragdoll
void SetCombatModel( void );
idClipModel * GetCombatModel( void ) const;
virtual void LinkCombat( void );
virtual void UnlinkCombat( void );
bool StartRagdoll( void );
void StopRagdoll( void );
virtual bool UpdateAnimationControllers( void );
// delta view angles to allow movers to rotate the view of the actor
const idAngles & GetDeltaViewAngles( void ) const;
void SetDeltaViewAngles( const idAngles &delta );
bool HasEnemies( void ) const;
idActor * ClosestEnemyToPoint( const idVec3 &pos );
idActor * EnemyWithMostHealth();
virtual bool OnLadder( void ) 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 );
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( void ) const;
void SetWaitState( const char *_waitstate );
bool AnimDone( int channel, int blendFrames ) const;
virtual void SpawnGibs( const idVec3 &dir, const char *damageDefName );
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> 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> 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;
idList<idAttachInfo> attachments;
virtual void Gib( const idVec3 &dir, const char *damageDefName );
// removes attachments with "remove" set for when character dies
void RemoveAttachments( void );
// copies animation from body to head joints
void CopyJointsFromBodyToHead( void );
private:
void SyncAnimChannels( int channel, int syncToChannel, int blendFrames );
void FinishSetup( void );
void SetupHead( void );
void PlayFootStepSound( void );
void Event_EnableEyeFocus( void );
void Event_DisableEyeFocus( void );
void Event_Footstep( void );
void Event_EnableWalkIK( void );
void Event_DisableWalkIK( void );
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 );
void Event_EnablePain( void );
void Event_GetPainAnim( void );
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 );
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 );
void Event_GetHead( void );
};
#endif /* !__GAME_ACTOR_H__ */

1286
neo/game/BrittleFracture.cpp Normal file

File diff suppressed because it is too large Load Diff

130
neo/game/BrittleFracture.h Normal file
View File

@@ -0,0 +1,130 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 *> decals;
idList<bool> edgeHasNeighbour;
idList<struct shard_s *> neighbours;
idPhysics_RigidBody physicsObj;
int droppedTime;
bool atEdge;
int islandNum;
} shard_t;
class idBrittleFracture : public idEntity {
public:
CLASS_PROTOTYPE( idBrittleFracture );
idBrittleFracture( void );
virtual ~idBrittleFracture( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
virtual void Present( void );
virtual void Think( void );
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( void ) const;
enum {
EVENT_PROJECT_DECAL = idEntity::EVENT_MAXEVENTS,
EVENT_SHATTER,
EVENT_MAXEVENTS
};
virtual void ClientPredictionThink( void );
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;
// state
idPhysics_StaticMulti physicsObj;
idList<shard_t *> 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 );
void Fracture_r( idFixedWinding &w );
void CreateFractures( const idRenderModel *renderModel );
void FindNeighbours( void );
void Event_Activate( idEntity *activator );
void Event_Touch( idEntity *other, trace_t *trace );
};
#endif /* !__GAME_BRITTLEFRACTURE_H__ */

719
neo/game/Camera.cpp Normal file
View File

@@ -0,0 +1,719 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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( void ) {
}
/*
=====================
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( void ) {
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( void ) {
// 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( void ) {
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( void ) {
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( "}" );
#if 0
if ( !gameLocal.GetLocalPlayer() ) {
return;
}
idDebugGraph gGraph;
idDebugGraph tGraph;
idDebugGraph qGraph;
idDebugGraph dtGraph;
idDebugGraph dqGraph;
gGraph.SetNumSamples( numFrames );
tGraph.SetNumSamples( numFrames );
qGraph.SetNumSamples( numFrames );
dtGraph.SetNumSamples( numFrames );
dqGraph.SetNumSamples( numFrames );
gameLocal.Printf( "\n\ndelta vec:\n" );
float diff_t, last_t, t;
float diff_q, last_q, q;
diff_t = last_t = 0.0f;
diff_q = last_q = 0.0f;
for( i = 1; i < numFrames; i++ ) {
t = ( camera[ i ].t - camera[ i - 1 ].t ).Length();
q = ( camera[ i ].q.ToQuat() - camera[ i - 1 ].q.ToQuat() ).Length();
diff_t = t - last_t;
diff_q = q - last_q;
gGraph.AddValue( ( i % 10 ) == 0 );
tGraph.AddValue( t );
qGraph.AddValue( q );
dtGraph.AddValue( diff_t );
dqGraph.AddValue( diff_q );
gameLocal.Printf( "%d: %.8f : %.8f, %.8f : %.8f\n", i, t, diff_t, q, diff_q );
last_t = t;
last_q = q;
}
gGraph.Draw( colorBlue, 300.0f );
tGraph.Draw( colorOrange, 60.0f );
dtGraph.Draw( colorYellow, 6000.0f );
qGraph.Draw( colorGreen, 60.0f );
dqGraph.Draw( colorCyan, 6000.0f );
#endif
}
/*
===============
idCameraAnim::Start
================
*/
void idCameraAnim::Start( void ) {
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 == gameLocal.time ) {
gameLocal.GetLocalPlayer()->CalculateRenderView();
}
}
/*
=====================
idCameraAnim::Stop
=====================
*/
void idCameraAnim::Stop( void ) {
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( void ) {
int frame;
int frameTime;
if ( thinkFlags & TH_THINK ) {
// check if we're done in the Think function when the cinematic is being skipped (idCameraAnim::GetViewParms isn't called when skipping cinematics).
if ( !gameLocal.skipCinematic ) {
return;
}
if ( camera.Num() < 2 ) {
// 1 frame anims never end
return;
}
if ( frameRate == USERCMD_HZ ) {
frameTime = gameLocal.time - starttime;
frame = frameTime / gameLocal.msec;
} else {
frameTime = ( gameLocal.time - starttime ) * frameRate;
frame = frameTime / 1000;
}
if ( frame > camera.Num() + cameraCuts.Num() - 2 ) {
if ( cycle > 0 ) {
cycle--;
}
if ( cycle != 0 ) {
// advance start time so that we loop
starttime += ( ( camera.Num() - cameraCuts.Num() ) * 1000 ) / frameRate;
} else {
Stop();
}
}
}
}
/*
=====================
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;
}
if ( frameRate == USERCMD_HZ ) {
frameTime = gameLocal.time - starttime;
frame = frameTime / gameLocal.msec;
lerp = 0.0f;
} else {
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.time - starttime - gameLocal.msec ) * 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, gameLocal.msec );
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( void ) {
Start();
}
/*
===============
idCameraAnim::Event_Stop
================
*/
void idCameraAnim::Event_Stop( void ) {
Stop();
}
/*
================
idCameraAnim::Event_SetCallback
================
*/
void idCameraAnim::Event_SetCallback( void ) {
if ( ( gameLocal.GetCamera() == this ) && !threadNum ) {
threadNum = idThread::CurrentThreadNum();
idThread::ReturnInt( true );
} else {
idThread::ReturnInt( false );
}
}

132
neo/game/Camera.h Normal file
View File

@@ -0,0 +1,132 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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( void );
virtual void GetViewParms( renderView_t *view ) = 0;
virtual renderView_t * GetRenderView();
virtual void Stop( void ){} ;
};
/*
===============================================================================
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( void );
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( void );
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 );
void Stop( void );
void Think( void );
void LoadAnim( void );
void Event_Start( void );
void Event_Stop( void );
void Event_SetCallback( void );
void Event_Activate( idEntity *activator );
};
#endif /* !__GAME_CAMERA_H__ */

185
neo/game/EndLevel.cpp Normal file
View File

@@ -0,0 +1,185 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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/game/EndLevel.h Normal file
View File

@@ -0,0 +1,66 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 );
};

5390
neo/game/Entity.cpp Normal file

File diff suppressed because it is too large Load Diff

524
neo/game/Entity.h Normal file
View File

@@ -0,0 +1,524 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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> signal[ NUM_SIGNALS ];
};
class idEntity : public idClass {
public:
static const int MAX_PVS_AREAS = 4;
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> snapshotNode; // for being linked into snapshotEntities list
int snapshotSequence; // last snapshot this entity was in
int snapshotBits; // number of bits this entity occupied in the last 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> > 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
} fl;
public:
ABSTRACT_PROTOTYPE( idEntity );
idEntity();
~idEntity();
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
const char * GetEntityDefName( void ) const;
void SetName( const char *name );
const char * GetName( void ) const;
virtual void UpdateChangeableSpawnArgs( const idDict *source );
// 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( void );
bool CheckDormant( void ); // dormant == on the active list, but out of PVS
virtual void DormantBegin( void ); // called when entity becomes dormant
virtual void DormantEnd( void ); // called when entity wakes from being dormant
bool IsActive( void ) const;
void BecomeActive( int flags );
void BecomeInactive( int flags );
void UpdatePVSAreas( const idVec3 &pos );
// visuals
virtual void Present( void );
virtual renderEntity_t *GetRenderEntity( void );
virtual int GetModelDefHandle( void );
virtual void SetModel( const char *modelname );
void SetSkin( const idDeclSkin *skin );
const idDeclSkin * GetSkin( void ) 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( void );
virtual void FreeLightDef( void );
virtual void Hide( void );
virtual void Show( void );
bool IsHidden( void ) const;
void UpdateVisuals( void );
void UpdateModel( void );
void UpdateModelTransform( void );
virtual void ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material );
int GetNumPVSAreas( void );
const int * GetPVSAreas( void );
void ClearPVSAreas( void );
bool PhysicsTeamInPVS( pvsHandle_t pvsHandle );
// animation
virtual bool UpdateAnimationControllers( void );
bool UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView );
static bool ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView );
virtual idAnimator * GetAnimator( void ); // returns animator object used by this entity
// sound
virtual bool CanPlayChatterSounds( void ) 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( void );
int GetListenerId( void ) const;
idSoundEmitter * GetSoundEmitter( void ) const;
void FreeSoundEmitter( bool immediate );
// entity binding
virtual void PreBind( void );
virtual void PostBind( void );
virtual void PreUnbind( void );
virtual void PostUnbind( void );
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( void );
bool IsBound( void ) const;
bool IsBoundTo( idEntity *master ) const;
idEntity * GetBindMaster( void ) const;
jointHandle_t GetBindJoint( void ) const;
int GetBindBody( void ) const;
idEntity * GetTeamMaster( void ) const;
idEntity * GetNextTeamEntity( void ) 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( void ) const;
// restore physics pointer for save games
void RestorePhysics( idPhysics *phys );
// run the physics for this entity
bool RunPhysics( void );
// 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( void ) const;
// returns the time the physics object came to rest
virtual int GetRestStartTime( void ) 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( void ) const;
virtual idThread * ConstructScriptObject( void );
virtual void DeconstructScriptObject( void );
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( void );
bool HandleGuiCommands( idEntity *entityGui, const char *cmds );
virtual bool HandleSingleGuiCommand( idEntity *entityGui, idLexer *src );
// targets
void FindTargets( void );
void RemoveNullTargets( void );
void ActivateTargets( idEntity *activator ) const;
// misc
virtual void Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination );
bool TouchTriggers( void ) const;
idCurve_Spline<idVec3> *GetSpline( void ) const;
virtual void ShowEditingDialog( void );
enum {
EVENT_STARTSOUNDSHADER,
EVENT_STOPSOUNDSHADER,
EVENT_MAXEVENTS
};
virtual void ClientPredictionThink( void );
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
virtual bool ServerReceiveEvent( int event, int time, const idBitMsg &msg );
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
void WriteBindToSnapshot( idBitMsgDelta &msg ) const;
void ReadBindFromSnapshot( const idBitMsgDelta &msg );
void WriteColorToSnapshot( idBitMsgDelta &msg ) const;
void ReadColorFromSnapshot( const idBitMsgDelta &msg );
void WriteGUIToSnapshot( idBitMsgDelta &msg ) const;
void ReadGUIFromSnapshot( const idBitMsgDelta &msg );
void ServerSendEvent( int eventId, const idBitMsg *msg, bool saveEvent, int excludeClient ) const;
void ClientSendEvent( int eventId, const idBitMsg *msg ) const;
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
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
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
private:
void FixupLocalizedStrings();
bool DoDormantTests( void ); // 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 );
// entity binding
bool InitBind( idEntity *master ); // initialize an entity binding
void FinishBind( void ); // finish an entity binding
void RemoveBinds( void ); // deletes any entities bound to this object
void QuitTeam( void ); // leave the current team
void UpdatePVSAreas( void );
// events
void Event_GetName( void );
void Event_SetName( const char *name );
void Event_FindTargets( void );
void Event_ActivateTargets( idEntity *activator );
void Event_NumTargets( void );
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 );
void Event_RemoveBinds( void );
void Event_SpawnBind( void );
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 );
void Event_IsHidden( void );
void Event_Hide( void );
void Event_Show( void );
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 );
void Event_SetWorldOrigin( idVec3 const &org );
void Event_GetOrigin( void );
void Event_SetOrigin( const idVec3 &org );
void Event_GetAngles( void );
void Event_SetAngles( const idAngles &ang );
void Event_SetLinearVelocity( const idVec3 &velocity );
void Event_GetLinearVelocity( void );
void Event_SetAngularVelocity( const idVec3 &velocity );
void Event_GetAngularVelocity( void );
void Event_SetSize( const idVec3 &mins, const idVec3 &maxs );
void Event_GetSize( void );
void Event_GetMins( void );
void Event_GetMaxs( void );
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 );
void Event_UpdateCameraTarget( void );
void Event_DistanceTo( idEntity *ent );
void Event_DistanceToPoint( const idVec3 &point );
void Event_StartFx( const char *fx );
void Event_WaitFrame( void );
void Event_Wait( float time );
void Event_HasFunction( const char *name );
void Event_CallFunction( const char *name );
void Event_SetNeverDormant( int enable );
};
/*
===============================================================================
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( void );
virtual void Think( void );
void UpdateAnimation( void );
virtual idAnimator * GetAnimator( void );
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( void ) 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( void );
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 );
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 );
};
#endif /* !__GAME_ENTITY_H__ */

792
neo/game/Fx.cpp Normal file
View File

@@ -0,0 +1,792 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 ( gameLocal.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( void ) {
return fxEffect ? fxEffect->GetName() : NULL;
}
/*
================
idEntityFx::Joint
================
*/
const char *idEntityFx::Joint( void ) {
return fxEffect ? fxEffect->joint.c_str() : NULL;
}
/*
================
idEntityFx::CleanUp
================
*/
void idEntityFx::CleanUp( void ) {
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( void ) {
CleanUp();
started = -1;
}
/*
================
idEntityFx::Duration
================
*/
const int idEntityFx::Duration( void ) {
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 ( !gameLocal.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 ( gameLocal.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();
}
ApplyFade( fxaction, *useAction, time, actualStart );
break;
}
case FX_LAUNCH: {
if ( gameLocal.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;
}
}
}
}
/*
================
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( void ) {
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( void ) {
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( void ) {
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( idBitMsgDelta &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 idBitMsgDelta &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::ClientPredictionThink
=================
*/
void idEntityFx::ClientPredictionThink( void ) {
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 );
}

106
neo/game/Fx.h Normal file
View File

@@ -0,0 +1,106 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 );
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( void );
const int Duration( void );
const char * EffectName( void );
const char * Joint( void );
const bool Done();
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
virtual void ClientPredictionThink( void );
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 );
void CleanUp( void );
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> 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__ */

1
neo/game/Game.def Normal file
View File

@@ -0,0 +1 @@
EXPORTS GetGameAPI

354
neo/game/Game.h Normal file
View File

@@ -0,0 +1,354 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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"
typedef struct {
char sessionCommand[MAX_STRING_CHARS]; // "map", "disconnect", "victory", etc
int consistencyHash; // used to check for network game divergence
int health;
int heartRate;
int stamina;
int combat;
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
} gameReturn_t;
typedef enum {
ALLOW_YES = 0,
ALLOW_BADPASS, // core will prompt for password and connect again
ALLOW_NOTYET, // core will wait with transmitted message
ALLOW_NO // core will abort with transmitted message
} allowReply_t;
typedef enum {
ESC_IGNORE = 0, // do nothing
ESC_MAIN, // start main menu GUI
ESC_GUI // set an explicit GUI
} escReply_t;
#define TIME_GROUP1 0
#define TIME_GROUP2 1
class idGame {
public:
virtual ~idGame() {}
// Initialize the game for the first time.
virtual void Init( void ) = 0;
// Shut down the entire game.
virtual void Shutdown( void ) = 0;
// Set the local client number. Distinguishes listen ( == 0 ) / dedicated ( == -1 )
virtual void SetLocalClient( int clientNum ) = 0;
// Sets the user info for a client.
// if canModify is true, the game can modify the user info in the returned dictionary pointer, server will forward the change back
// canModify is never true on network client
virtual const idDict * SetUserInfo( int clientNum, const idDict &userInfo, bool isClient, bool canModify ) = 0;
// Retrieve the game's userInfo dict for a client.
virtual const idDict * GetUserInfo( int clientNum ) = 0;
// The game gets a chance to alter userinfo before they are emitted to server.
virtual void ThrottleUserInfo( void ) = 0;
// Sets the serverinfo at map loads and when it changes.
virtual void SetServerInfo( const idDict &serverInfo ) = 0;
// The session calls this before moving the single player game to a new level.
virtual const idDict & GetPersistentPlayerInfo( int clientNum ) = 0;
// The session 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, bool isServer, bool isClient, int randseed ) = 0;
// Loads a map from a savegame file.
virtual bool InitFromSaveGame( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, idFile *saveGameFile ) = 0;
// Saves the current game state, the session may have written some data to the file already.
virtual void SaveGame( idFile *saveGameFile ) = 0;
// Shut down the current map.
virtual void MapShutdown( void ) = 0;
// Caches media referenced from in key/value pairs in the given dictionary.
virtual void CacheDictionaryMedia( const idDict *dict ) = 0;
// Spawns the player entity to be used by the client.
virtual void SpawnPlayer( int clientNum ) = 0;
// Runs a game frame, may return a session command for level changing, etc
virtual gameReturn_t RunFrame( const usercmd_t *clientCmds ) = 0;
// Makes rendering and sound system calls to display for a given clientNum.
virtual bool Draw( int clientNum ) = 0;
// Let the game do it's own UI when ESCAPE is used
virtual escReply_t HandleESC( idUserInterface **gui ) = 0;
// get the games menu if appropriate ( multiplayer )
virtual idUserInterface * StartMenu() = 0;
// When the game is running it's own UI fullscreen, GUI commands are passed through here
// return NULL once the fullscreen UI mode should stop, or "main" to go to main menu
virtual const char * HandleGuiCommands( const char *menuCommand ) = 0;
// main menu commands not caught in the engine are passed here
virtual void HandleMainMenuCommands( const char *menuCommand, idUserInterface *gui ) = 0;
// Early check to deny connect.
virtual allowReply_t ServerAllowClient( int numClients, const char *IP, const char *guid, const char *password, char reason[MAX_STRING_CHARS] ) = 0;
// Connects a client.
virtual void ServerClientConnect( int clientNum, const char *guid ) = 0;
// Spawns the player entity to be used by the client.
virtual void ServerClientBegin( int clientNum ) = 0;
// Disconnects a client and removes the player entity from the game.
virtual void ServerClientDisconnect( int clientNum ) = 0;
// Writes initial reliable messages a client needs to recieve when first joining the game.
virtual void ServerWriteInitialReliableMessages( int clientNum ) = 0;
// Writes a snapshot of the server game state for the given client.
virtual void ServerWriteSnapshot( int clientNum, int sequence, idBitMsg &msg, byte *clientInPVS, int numPVSClients ) = 0;
// Patches the network entity states at the server with a snapshot for the given client.
virtual bool ServerApplySnapshot( int clientNum, int sequence ) = 0;
// Processes a reliable message from a client.
virtual void ServerProcessReliableMessage( int clientNum, const idBitMsg &msg ) = 0;
// Reads a snapshot and updates the client game state.
virtual void ClientReadSnapshot( int clientNum, int sequence, const int gameFrame, const int gameTime, const int dupeUsercmds, const int aheadOfServer, const idBitMsg &msg ) = 0;
// Patches the network entity states at the client with a snapshot.
virtual bool ClientApplySnapshot( int clientNum, int sequence ) = 0;
// Processes a reliable message from the server.
virtual void ClientProcessReliableMessage( int clientNum, const idBitMsg &msg ) = 0;
// Runs prediction on entities at the client.
virtual gameReturn_t ClientPrediction( int clientNum, const usercmd_t *clientCmds, bool lastPredictFrame ) = 0;
// Used to manage divergent time-lines
virtual void SelectTimeGroup( int timeGroup ) = 0;
virtual int GetTimeGroupTime( int timeGroup ) = 0;
virtual void GetBestGameType( const char* map, const char* gametype, char buf[ MAX_STRING_CHARS ] ) = 0;
// Returns a summary of stats for a given client
virtual void GetClientStats( int clientNum, char *data, const int len ) = 0;
// Switch a player to a particular team
virtual void SwitchTeam( int clientNum, int team ) = 0;
virtual bool DownloadRequest( const char *IP, const char *guid, const char *paks, char urls[ MAX_STRING_CHARS ] ) = 0;
virtual void GetMapLoadingGUI( char gui[ MAX_STRING_CHARS ] ) = 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( void ) {}
// 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( void );
virtual idRenderModel * AF_CreateMesh( const idDict &args, idVec3 &meshOrigin, idMat3 &meshAxis, bool &poseIsSet );
// Entity selection.
virtual void ClearEntitySelection( void );
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
idNetworkSystem * networkSystem; // network 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/game/GameEdit.cpp Normal file

File diff suppressed because it is too large Load Diff

119
neo/game/GameEdit.h Normal file
View File

@@ -0,0 +1,119 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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( void );
~idCursor3D( void );
void Spawn( void );
void Present( void );
void Think( void );
idForce_Drag drag;
idVec3 draggedPosition;
};
/*
===============================================================================
Allows entities to be dragged through the world with physics.
===============================================================================
*/
class idDragEntity {
public:
idDragEntity( void );
~idDragEntity( void );
void Clear();
void Update( idPlayer *player );
void SetSelected( idEntity *ent );
idEntity * GetSelected( void ) const { return selected.GetEntity(); }
void DeleteSelected( void );
void BindSelected( void );
void UnbindSelected( void );
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( void );
};
/*
===============================================================================
Handles ingame entity editing.
===============================================================================
*/
typedef struct selectedTypeInfo_s {
idTypeInfo *typeInfo;
idStr textKey;
} selectedTypeInfo_t;
class idEditEntities {
public:
idEditEntities( void );
bool SelectEntity( const idVec3 &origin, const idVec3 &dir, const idEntity *skip );
void AddSelectedEntity( idEntity *ent );
void RemoveSelectedEntity( idEntity *ent );
void ClearSelectedEntities( void );
void DisplayEntities( void );
bool EntityIsSelectable( idEntity *ent, idVec4 *color = NULL, idStr *text = NULL );
private:
int nextSelectTime;
idList<selectedTypeInfo_t> selectableEntityClasses;
idList<idEntity *> selectedEntities;
};
#endif /* !__GAME_EDIT_H__ */

4368
neo/game/Game_local.cpp Normal file

File diff suppressed because it is too large Load Diff

743
neo/game/Game_local.h Normal file
View File

@@ -0,0 +1,743 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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.
===============================================================================
*/
#define LAGO_IMG_WIDTH 64
#define LAGO_IMG_HEIGHT 64
#define LAGO_WIDTH 64
#define LAGO_HEIGHT 44
#define LAGO_MATERIAL "textures/sfx/lagometer"
#define LAGO_IMAGE "textures/sfx/lagometer.tga"
// if set to 1 the server sends the client PVS with snapshots and the client compares against what it sees
#ifndef ASYNC_WRITE_PVS
#define ASYNC_WRITE_PVS 0
#endif
#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;
#define MAX_CLIENTS 32
#define GENTITYNUM_BITS 12
#define MAX_GENTITIES (1<<GENTITYNUM_BITS)
#define ENTITYNUM_NONE (MAX_GENTITIES-1)
#define ENTITYNUM_WORLD (MAX_GENTITIES-2)
#define ENTITYNUM_MAX_NORMAL (MAX_GENTITIES-2)
//============================================================================
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 "gamesys/DebugGraph.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 "MultiplayerGame.h"
//============================================================================
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 );
typedef struct entityState_s {
int entityNumber;
idBitMsg state;
byte stateBuf[MAX_ENTITY_STATE_SIZE];
struct entityState_s * next;
} entityState_t;
typedef struct snapshot_s {
int sequence;
entityState_t * firstEntityState;
int pvs[ENTITY_PVS_SIZE];
struct snapshot_s * next;
} snapshot_t;
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_INIT_DECL_REMAP,
GAME_RELIABLE_MESSAGE_REMAP_DECL,
GAME_RELIABLE_MESSAGE_SPAWN_PLAYER,
GAME_RELIABLE_MESSAGE_DELETE_ENT,
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_KILL,
GAME_RELIABLE_MESSAGE_DROPWEAPON,
GAME_RELIABLE_MESSAGE_RESTART,
GAME_RELIABLE_MESSAGE_SERVERINFO,
GAME_RELIABLE_MESSAGE_TOURNEYLINE,
GAME_RELIABLE_MESSAGE_CALLVOTE,
GAME_RELIABLE_MESSAGE_CASTVOTE,
GAME_RELIABLE_MESSAGE_STARTVOTE,
GAME_RELIABLE_MESSAGE_UPDATEVOTE,
GAME_RELIABLE_MESSAGE_PORTALSTATES,
GAME_RELIABLE_MESSAGE_PORTAL,
GAME_RELIABLE_MESSAGE_VCHAT,
GAME_RELIABLE_MESSAGE_STARTSTATE,
GAME_RELIABLE_MESSAGE_MENU,
GAME_RELIABLE_MESSAGE_WARMUPTIME,
GAME_RELIABLE_MESSAGE_EVENT
};
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;
} 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( void );
entityNetEvent_t * RemoveLast( void );
entityNetEvent_t * Start( void ) { 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<type> & operator=( type *ent );
// synchronize entity pointers over the network
int GetSpawnId( void ) const { return spawnId; }
bool SetSpawnId( int id );
bool UpdateSpawnId( void );
bool IsValid( void ) const;
type * GetEntity( void ) const;
int GetEntityNum( void ) const;
private:
int spawnId;
};
//============================================================================
class idGameLocal : public idGame {
public:
idDict serverInfo; // all the tunable parameters, like numclients, etc
int numClients; // pulled from serverInfo and verified
idDict userInfo[MAX_CLIENTS]; // client specific settings
usercmd_t usercmds[MAX_CLIENTS]; // client input commands
idDict persistentPlayerInfo[MAX_CLIENTS];
idEntity * entities[MAX_GENTITIES];// index to entities
int spawnIds[MAX_GENTITIES];// for use in idEntityPtr
int firstFreeIndex; // first free index in the entities array
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)
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
int cinematicSkipTime; // don't allow skipping cinemetics until this time has passed so player doesn't skip out accidently from a firefight
int cinematicStopTime; // cinematics have several camera changes, so keep track of when we stop them so that we don't reset cinematicSkipTime unnecessarily
int cinematicMaxSkipTime; // time to end cinematic when skipping. there's a possibility of an infinite loop if the map isn't set up right.
bool inCinematic; // game is playing cinematic (player controls frozen)
bool skipCinematic;
// are kept up to date with changes to serverInfo
int framenum;
int previousTime; // time in msec of last frame
int time; // in msec
static const int msec = USERCMD_MSEC; // time since last update in milliseconds
int vacuumAreaNum; // -1 if level doesn't have any outside areas
gameType_t gameType;
bool isMultiplayer; // set if the game is run in multiplayer mode
bool isServer; // set if the game is run for a dedicated or listen server
bool isClient; // set if the game is run for a client
// discriminates between the RunFrame path and the ClientPrediction path
// NOTE: on a listen server, isClient is false
int localClientNum; // number of the local client. MP: -1 on a dedicated
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
// ---------------------- Public idGame Interface -------------------
idGameLocal();
virtual void Init( void );
virtual void Shutdown( void );
virtual void SetLocalClient( int clientNum );
virtual void ThrottleUserInfo( void );
virtual const idDict * SetUserInfo( int clientNum, const idDict &userInfo, bool isClient, bool canModify );
virtual const idDict * GetUserInfo( int clientNum );
virtual void SetServerInfo( const idDict &serverInfo );
virtual const idDict & GetPersistentPlayerInfo( int clientNum );
virtual void SetPersistentPlayerInfo( int clientNum, const idDict &playerInfo );
virtual void InitFromNewMap( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, bool isServer, bool isClient, int randSeed );
virtual bool InitFromSaveGame( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, idFile *saveGameFile );
virtual void SaveGame( idFile *saveGameFile );
virtual void MapShutdown( void );
virtual void CacheDictionaryMedia( const idDict *dict );
virtual void SpawnPlayer( int clientNum );
virtual gameReturn_t RunFrame( const usercmd_t *clientCmds );
virtual bool Draw( int clientNum );
virtual escReply_t HandleESC( idUserInterface **gui );
virtual idUserInterface *StartMenu( void );
virtual const char * HandleGuiCommands( const char *menuCommand );
virtual void HandleMainMenuCommands( const char *menuCommand, idUserInterface *gui );
virtual allowReply_t ServerAllowClient( int numClients, const char *IP, const char *guid, const char *password, char reason[MAX_STRING_CHARS] );
virtual void ServerClientConnect( int clientNum, const char *guid );
virtual void ServerClientBegin( int clientNum );
virtual void ServerClientDisconnect( int clientNum );
virtual void ServerWriteInitialReliableMessages( int clientNum );
virtual void ServerWriteSnapshot( int clientNum, int sequence, idBitMsg &msg, byte *clientInPVS, int numPVSClients );
virtual bool ServerApplySnapshot( int clientNum, int sequence );
virtual void ServerProcessReliableMessage( int clientNum, const idBitMsg &msg );
virtual void ClientReadSnapshot( int clientNum, int sequence, const int gameFrame, const int gameTime, const int dupeUsercmds, const int aheadOfServer, const idBitMsg &msg );
virtual bool ClientApplySnapshot( int clientNum, int sequence );
virtual void ClientProcessReliableMessage( int clientNum, const idBitMsg &msg );
virtual gameReturn_t ClientPrediction( int clientNum, const usercmd_t *clientCmds, bool lastPredictFrame );
virtual void GetClientStats( int clientNum, char *data, const int len );
virtual void SwitchTeam( int clientNum, int team );
virtual bool DownloadRequest( const char *IP, const char *guid, const char *paks, char urls[ MAX_STRING_CHARS ] );
// ---------------------- Public idGameLocal Interface -------------------
void Printf( const char *fmt, ... ) const id_attribute((format(printf,2,3)));
void DPrintf( const char *fmt, ... ) const id_attribute((format(printf,2,3)));
void Warning( const char *fmt, ... ) const id_attribute((format(printf,2,3)));
void DWarning( const char *fmt, ... ) const id_attribute((format(printf,2,3)));
void Error( const char *fmt, ... ) const id_attribute((format(printf,2,3)));
// Initializes all map variables common to both save games and spawned games
void LoadMap( const char *mapName, int randseed );
void LocalMapRestart( void );
void MapRestart( void );
static void MapRestart_f( const idCmdArgs &args );
bool NextMap( void ); // returns wether serverinfo settings have been modified
static void NextMap_f( const idCmdArgs &args );
idMapFile * GetLevelMap( void );
const char * GetMapName( void ) const;
int NumAAS( void ) 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( void );
bool CheatsOk( bool requirePlayer = true );
void SetSkill( int value );
gameState_t GameState( void ) 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 );
void UnregisterEntity( idEntity *ent );
bool RequirementMet( idEntity *activator, const idStr &requires, int removeItem );
void AlertAI( idEntity *ent );
idActor * GetAlertEntity( void );
bool InPlayerPVS( idEntity *ent ) const;
bool InPlayerConnectedArea( idEntity *ent ) const;
void SetCamera( idCamera *cam );
idCamera * GetCamera( void ) const;
bool SkipCinematic( void );
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( void ) const;
// added the following to assist licensees with merge issues
int GetFrameNum() const { return framenum; };
int GetTime() const { return time; };
int GetMSec() const { return msec; };
int GetNextClientNum( int current ) const;
idPlayer * GetClientByNum( int current ) const;
idPlayer * GetClientByName( const char *name ) const;
idPlayer * GetClientByCmdArgs( const idCmdArgs &args ) 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 );
void ServerSendChatMessage( int to, const char *name, const char *text );
int ServerRemapDecl( int clientNum, declType_t type, int index );
int ClientRemapDecl( declType_t type, int index );
void SetGlobalMaterial( const idMaterial *mat );
const idMaterial * GetGlobalMaterial();
void SetGibTime( int _time ) { nextGibTime = _time; };
int GetGibTime() { return nextGibTime; };
bool NeedRestart();
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
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;
idList<int> clientDeclRemap[MAX_CLIENTS][DECL_MAX_TYPES];
entityState_t * clientEntityStates[MAX_CLIENTS][MAX_GENTITIES];
int clientPVS[MAX_CLIENTS][ENTITY_PVS_SIZE];
snapshot_t * clientSnapshots[MAX_CLIENTS];
idBlockAlloc<entityState_t,256>entityStateAllocator;
idBlockAlloc<snapshot_t,64>snapshotAllocator;
idEventQueue eventQueue;
idEventQueue savedEventQueue;
idStaticList<spawnSpot_t, MAX_GENTITIES> spawnSpots;
idStaticList<idEntity *, MAX_GENTITIES> initialSpots;
int currentInitialSpot;
idDict newInfo;
idStrList shakeSounds;
byte lagometer[ LAGO_IMG_HEIGHT ][ LAGO_IMG_WIDTH ][ 4 ];
void Clear( void );
// 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( void );
// commons used by init, shutdown, and restart
void MapPopulate( void );
void MapClear( bool clearClients );
pvsHandle_t GetClientPVS( idPlayer *player, pvsType_t type );
void SetupPlayerPVS( void );
void FreePlayerPVS( void );
void UpdateGravity( void );
void SortActiveEntityList( void );
void ShowTargets( void );
void RunDebugInfo( void );
void InitScriptForMap( void );
void InitConsoleCommands( void );
void ShutdownConsoleCommands( void );
void InitAsyncNetwork( void );
void ShutdownAsyncNetwork( void );
void InitLocalClient( int clientNum );
void InitClientDeclRemap( int clientNum );
void ServerSendDeclRemapToClient( int clientNum, declType_t type, int index );
void FreeSnapshotsOlderThanSequence( int clientNum, int sequence );
bool ApplySnapshot( int clientNum, int sequence );
void WriteGameStateToSnapshot( idBitMsgDelta &msg ) const;
void ReadGameStateFromSnapshot( const idBitMsgDelta &msg );
void NetworkEventWarning( const entityNetEvent_t *event, const char *fmt, ... ) id_attribute((format(printf,3,4)));
void ServerProcessEntityNetworkEventQueue( void );
void ClientProcessEntityNetworkEventQueue( void );
void ClientShowSnapshot( int clientNum ) const;
// call after any change to serverInfo. Will update various quick-access flags
void UpdateServerInfoFlags( void );
void RandomizeInitialSpawns( void );
static int sortSpawnPoints( const void *ptr1, const void *ptr2 );
void DumpOggSounds( void );
void GetShakeSounds( const idDict *dict );
void SelectTimeGroup( int timeGroup );
int GetTimeGroupTime( int timeGroup );
void GetBestGameType( const char* map, const char* gametype, char buf[ MAX_STRING_CHARS ] );
void Tokenize( idStrList &out, const char *in );
void UpdateLagometer( int aheadOfServer, int dupeUsercmds );
void GetMapLoadingGUI( char gui[ MAX_STRING_CHARS ] );
};
//============================================================================
extern idGameLocal gameLocal;
extern idAnimManager animationLib;
//============================================================================
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=( type *ent ) {
if ( ent == NULL ) {
spawnId = 0;
} else {
spawnId = ( gameLocal.spawnIds[ent->entityNumber] << GENTITYNUM_BITS ) | ent->entityNumber;
}
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( void ) const {
return ( gameLocal.spawnIds[ spawnId & ( ( 1 << GENTITYNUM_BITS ) - 1 ) ] == ( spawnId >> GENTITYNUM_BITS ) );
}
template< class type >
ID_INLINE type *idEntityPtr<type>::GetEntity( void ) 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( void ) const {
return ( spawnId & ( ( 1 << GENTITYNUM_BITS ) - 1 ) );
}
//============================================================================
class idGameError : public idException {
public:
idGameError( const char *text ) : idException( text ) {}
};
//============================================================================
//
// 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,
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_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 "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 "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"
#include "script/Script_Compiler.h"
#include "script/Script_Interpreter.h"
#include "script/Script_Thread.h"
#endif /* !__GAME_LOCAL_H__ */

1753
neo/game/Game_network.cpp Normal file

File diff suppressed because it is too large Load Diff

1127
neo/game/IK.cpp Normal file

File diff suppressed because it is too large Load Diff

182
neo/game/IK.h Normal file
View File

@@ -0,0 +1,182 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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( void );
virtual ~idIK( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
bool IsInitialized( void ) const;
virtual bool Init( idEntity *self, const char *anim, const idVec3 &modelOffset );
virtual void Evaluate( void );
virtual void ClearJointMods( void );
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( void );
virtual ~idIK_Walk( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual bool Init( idEntity *self, const char *anim, const idVec3 &modelOffset );
virtual void Evaluate( void );
virtual void ClearJointMods( void );
void EnableAll( void );
void DisableAll( void );
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( void );
virtual ~idIK_Reach( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual bool Init( idEntity *self, const char *anim, const idVec3 &modelOffset );
virtual void Evaluate( void );
virtual void ClearJointMods( void );
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__ */

1354
neo/game/Item.cpp Normal file

File diff suppressed because it is too large Load Diff

227
neo/game/Item.h Normal file
View File

@@ -0,0 +1,227 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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.
===============================================================================
*/
class idItem : public idEntity {
public:
CLASS_PROTOTYPE( idItem );
idItem();
virtual ~idItem();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
void GetAttributes( idDict &attributes );
virtual bool GiveToPlayer( idPlayer *player );
virtual bool Pickup( idPlayer *player );
virtual void Think( void );
virtual void Present();
enum {
EVENT_PICKUP = idEntity::EVENT_MAXEVENTS,
EVENT_RESPAWN,
EVENT_RESPAWNFX,
EVENT_MAXEVENTS
};
virtual void ClientPredictionThink( void );
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
// networking
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
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;
bool UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ) const;
static bool ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView );
void Event_DropToFloor( void );
void Event_Touch( idEntity *other, trace_t *trace );
void Event_Trigger( idEntity *activator );
void Event_Respawn( void );
void Event_RespawnFx( void );
};
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 );
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;
void Event_Trigger( idEntity *activator );
void Event_HideObjective( idEntity *e );
void Event_GetPlayerPos();
void Event_CamShot();
};
class idVideoCDItem : public idItem {
public:
CLASS_PROTOTYPE( idVideoCDItem );
void Spawn();
virtual bool GiveToPlayer( idPlayer *player );
};
class idPDAItem : public idItem {
public:
CLASS_PROTOTYPE( idPDAItem );
virtual bool GiveToPlayer( idPlayer *player );
};
class idMoveableItem : public idItem {
public:
CLASS_PROTOTYPE( idMoveableItem );
idMoveableItem();
virtual ~idMoveableItem();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
virtual void Think( void );
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( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
private:
idPhysics_RigidBody physicsObj;
idClipModel * trigger;
const idDeclParticle * smoke;
int smokeTime;
void Gib( const idVec3 &dir, const char *damageDefName );
void Event_DropToFloor( void );
void Event_Gib( const char *damageDefName );
};
class idMoveablePDAItem : public idMoveableItem {
public:
CLASS_PROTOTYPE( idMoveablePDAItem );
virtual bool GiveToPlayer( idPlayer *player );
};
/*
===============================================================================
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__ */

1145
neo/game/Light.cpp Normal file

File diff suppressed because it is too large Load Diff

135
neo/game/Light.h Normal file
View File

@@ -0,0 +1,135 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 );
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( void );
virtual void FreeLightDef( void );
virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis );
void Present( void );
void SaveState( idDict *args );
virtual void SetColor( float red, float green, float blue );
virtual void SetColor( const idVec4 &color );
virtual void GetColor( idVec3 &out ) const;
virtual void GetColor( idVec4 &out ) const;
const idVec3 & GetBaseColor( void ) 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 );
void Off( void );
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( void ) const { return lightDefHandle; }
void SetLightParent( idEntity *lparent ) { lightParent = lparent; }
void SetLightLevel( void );
virtual void ShowEditingDialog( void );
enum {
EVENT_BECOMEBROKEN = idEntity::EVENT_MAXEVENTS,
EVENT_MAXEVENTS
};
virtual void ClientPredictionThink( void );
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &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;
bool breakOnTrigger;
int count;
int triggercount;
idEntity * lightParent;
idVec4 fadeFrom;
idVec4 fadeTo;
int fadeStart;
int fadeEnd;
bool soundWasPlaying;
private:
void PresentLightDefChange( void );
void PresentModelDefChange( void );
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 );
void Event_Show( void );
void Event_On( void );
void Event_Off( void );
void Event_ToggleOnOff( idEntity *activator );
void Event_SetSoundHandles( void );
void Event_FadeOut( float time );
void Event_FadeIn( float time );
};
#endif /* !__GAME_LIGHT_H__ */

3149
neo/game/Misc.cpp Normal file

File diff suppressed because it is too large Load Diff

765
neo/game/Misc.h Normal file
View File

@@ -0,0 +1,765 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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( void );
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 );
void Spawn( void );
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 );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
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( void );
static void DrawDebugInfo( void );
static idPathCorner *RandomPath( const idEntity *source, const idEntity *ignore );
private:
void Event_RandomPath( void );
};
/*
===============================================================================
Object that fires targets and changes shader parms when damaged.
===============================================================================
*/
class idDamagable : public idEntity {
public:
CLASS_PROTOTYPE( idDamagable );
idDamagable( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
private:
int count;
int nextTriggerTime;
void BecomeBroken( idEntity *activator );
void Event_BecomeBroken( idEntity *activator );
void Event_RestoreDamagable( void );
};
/*
===============================================================================
Hidden object that explodes when activated
===============================================================================
*/
class idExplodable : public idEntity {
public:
CLASS_PROTOTYPE( idExplodable );
void Spawn( void );
private:
void Event_Explode( idEntity *activator );
};
/*
===============================================================================
idSpring
===============================================================================
*/
class idSpring : public idEntity {
public:
CLASS_PROTOTYPE( idSpring );
void Spawn( void );
virtual void Think( void );
private:
idEntity * ent1;
idEntity * ent2;
int id1;
int id2;
idVec3 p1;
idVec3 p2;
idForce_Spring spring;
void Event_LinkSpring( void );
};
/*
===============================================================================
idForceField
===============================================================================
*/
class idForceField : public idEntity {
public:
CLASS_PROTOTYPE( idForceField );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
virtual void Think( void );
private:
idForce_Field forceField;
void Toggle( void );
void Event_Activate( idEntity *activator );
void Event_Toggle( void );
void Event_FindTargets( void );
};
/*
===============================================================================
idAnimated
===============================================================================
*/
class idAnimated : public idAFEntity_Gibbable {
public:
CLASS_PROTOTYPE( idAnimated );
idAnimated();
~idAnimated();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
virtual bool LoadAF( void );
bool StartRagdoll( void );
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;
void PlayNextAnim( void );
void Event_Activate( idEntity *activator );
void Event_Start( void );
void Event_StartRagdoll( void );
void Event_AnimDone( int animIndex );
void Event_Footstep( void );
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 );
};
/*
===============================================================================
idStaticEntity
===============================================================================
*/
class idStaticEntity : public idEntity {
public:
CLASS_PROTOTYPE( idStaticEntity );
idStaticEntity( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
void ShowEditingDialog( void );
virtual void Hide( void );
virtual void Show( void );
void Fade( const idVec4 &to, float fadeTime );
virtual void Think( void );
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &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 );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
void Event_Activate( idEntity *activator );
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
private:
bool hidden;
};
/*
===============================================================================
idFuncSmoke
===============================================================================
*/
class idFuncSmoke : public idEntity {
public:
CLASS_PROTOTYPE( idFuncSmoke );
idFuncSmoke();
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
void Event_Activate( idEntity *activator );
private:
int smokeTime;
const idDeclParticle * smoke;
bool restart;
};
/*
===============================================================================
idFuncSplat
===============================================================================
*/
class idFuncSplat : public idFuncEmitter {
public:
CLASS_PROTOTYPE( idFuncSplat );
idFuncSplat( void );
void Spawn( void );
private:
void Event_Activate( idEntity *activator );
void Event_Splat();
};
/*
===============================================================================
idTextEntity
===============================================================================
*/
class idTextEntity : public idEntity {
public:
CLASS_PROTOTYPE( idTextEntity );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
private:
idStr text;
bool playerOriented;
};
/*
===============================================================================
idLocationEntity
===============================================================================
*/
class idLocationEntity : public idEntity {
public:
CLASS_PROTOTYPE( idLocationEntity );
void Spawn( void );
const char * GetLocation( void ) const;
private:
};
class idLocationSeparatorEntity : public idEntity {
public:
CLASS_PROTOTYPE( idLocationSeparatorEntity );
void Spawn( void );
private:
};
class idVacuumSeparatorEntity : public idEntity {
public:
CLASS_PROTOTYPE( idVacuumSeparatorEntity );
idVacuumSeparatorEntity( void );
void Spawn( void );
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( void );
private:
};
/*
===============================================================================
idBeam
===============================================================================
*/
class idBeam : public idEntity {
public:
CLASS_PROTOTYPE( idBeam );
idBeam();
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
void SetMaster( idBeam *masterbeam );
void SetBeamTarget( const idVec3 &origin );
virtual void Show( void );
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
private:
void Event_MatchTarget( void );
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 );
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 );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
private:
idPhysics_Parametric physicsObj;
bool active;
void BeginShaking( void );
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idEarthQuake
===============================================================================
*/
class idEarthQuake : public idEntity {
public:
CLASS_PROTOTYPE( idEarthQuake );
idEarthQuake();
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
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 );
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 );
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 );
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 );
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 );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
private:
void Event_Activate( idEntity *activator );
void Event_Throw( void );
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;
};
#endif /* !__GAME_MISC_H__ */

1193
neo/game/Moveable.cpp Normal file

File diff suppressed because it is too large Load Diff

197
neo/game/Moveable.h Normal file
View File

@@ -0,0 +1,197 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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( void );
~idMoveable( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
virtual void Hide( void );
virtual void Show( void );
bool AllowStep( void ) 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( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
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 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( void ) const;
void BecomeNonSolid( void );
void InitInitialSpline( int startTime );
bool FollowInitialSplinePath( void );
void Event_Activate( idEntity *activator );
void Event_BecomeNonSolid( void );
void Event_SetOwnerFromSpawnArgs( void );
void Event_IsAtRest( void );
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 );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void BarrelThink( void );
virtual void Think( void );
virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis );
virtual void ClientPredictionThink( void );
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 );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
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( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &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;
void AddParticles( const char *name, bool burn );
void AddLight( const char *name , bool burn );
void ExplodingEffects( void );
void Event_Activate( idEntity *activator );
void Event_Respawn();
void Event_Explode();
void Event_TriggerTargets();
};
#endif /* !__GAME_MOVEABLE_H__ */

4632
neo/game/Mover.cpp Normal file

File diff suppressed because it is too large Load Diff

550
neo/game/Mover.h Normal file
View File

@@ -0,0 +1,550 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 );
void Spawn( void );
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 WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
virtual void Hide( void );
virtual void Show( void );
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 );
void Event_ClosePortal( void );
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 );
void SetGuiState( const char *key, const char *val ) const;
virtual void DoneMoving( void );
virtual void DoneRotating( void );
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> > guiTargets;
void VectorForDir( float dir, idVec3 &vec );
idCurve_Spline<idVec3> *GetSpline( idEntity *splineEntity ) const;
void Event_SetCallback( void );
void Event_TeamBlocked( idEntity *blockedPart, idEntity *blockingEntity );
void Event_StopMoving( void );
void Event_StopRotating( void );
void Event_UpdateMove( void );
void Event_UpdateRotation( void );
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 );
void Event_InitGuiTargets( void );
void Event_EnableSplineAngles( void );
void Event_DisableSplineAngles( void );
void Event_RemoveInitialSplineAngles( void );
void Event_StartSpline( idEntity *splineEntity );
void Event_StopSpline( void );
void Event_Activate( idEntity *activator );
void Event_PostRestore( int start, int total, int accel, int decel, int useSplineAng );
void Event_IsMoving( void );
void Event_IsRotating( void );
};
class idSplinePath : public idEntity {
public:
CLASS_PROTOTYPE( idSplinePath );
idSplinePath();
void Spawn( void );
};
struct floorInfo_s {
idVec3 pos;
idStr door;
int floor;
};
class idElevator : public idMover {
public:
CLASS_PROTOTYPE( idElevator );
idElevator( void );
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( void );
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> floorInfo;
int currentFloor;
int pendingFloor;
int lastFloor;
bool controlsDisabled;
float returnTime;
int returnFloor;
int lastTouchTime;
class idDoor * GetDoor( const char *name );
void Think( void );
void OpenInnerDoor( void );
void OpenFloorDoor( int floor );
void CloseAllDoors( void );
void DisableAllDoors( void );
void EnableProperDoors( void );
void Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity );
void Event_Activate( idEntity *activator );
void Event_PostFloorArrival();
};
/*
===============================================================================
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 );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void PreBind( void );
virtual void PostBind( void );
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 );
void GotoPosition2( void );
void Use_BinaryMover( idEntity *activator );
void SetGuiStates( const char *state );
void UpdateBuddies( int val );
idMover_Binary * GetActivateChain( void ) const { return activateChain; }
idMover_Binary * GetMoveMaster( void ) const { return moveMaster; }
void BindTeam( idEntity *bindTo );
void SetBlocked( bool b );
bool IsBlocked( void );
idEntity * GetActivator( void ) const;
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &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;
idList< idEntityPtr<idEntity> > 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( void ) const { return moverState; }
void FindGuiTargets( void );
void SetGuiState( const char *key, const char *val ) const;
void Event_SetCallback( void );
void Event_ReturnToPos1( void );
void Event_Use_BinaryMover( idEntity *activator );
void Event_Reached_BinaryMover( void );
void Event_MatchActivateTeam( moverState_t newstate, int time );
void Event_Enable( void );
void Event_Disable( void );
void Event_OpenPortal( void );
void Event_ClosePortal( void );
void Event_FindGuiTargets( void );
void Event_InitGuiTargets( void );
static void GetMovedir( float dir, idVec3 &movedir );
};
class idDoor : public idMover_Binary {
public:
CLASS_PROTOTYPE( idDoor );
idDoor( void );
~idDoor( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
virtual void PreBind( void );
virtual void PostBind( void );
virtual void Hide( void );
virtual void Show( void );
bool IsOpen( void );
bool IsNoTouch( void );
int IsLocked( void );
void Lock( int f );
void Use( idEntity *other, idEntity *activator );
void Close( void );
void Open( void );
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 );
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 );
void Event_SpawnDoorTrigger( void );
void Event_SpawnSoundTrigger( void );
void Event_Close( void );
void Event_Open( void );
void Event_Lock( int f );
void Event_IsOpen( void );
void Event_Locked( void );
void Event_SpectatorTouch( idEntity *other, trace_t *trace );
void Event_OpenPortal( void );
void Event_ClosePortal( void );
};
class idPlat : public idMover_Binary {
public:
CLASS_PROTOTYPE( idPlat );
idPlat( void );
~idPlat( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
virtual void PreBind( void );
virtual void PostBind( void );
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 );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &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 );
void Spawn( void );
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 );
void Spawn( void );
private:
};
class idPendulum : public idMover_Periodic {
public:
CLASS_PROTOTYPE( idPendulum );
idPendulum( void );
void Spawn( void );
private:
};
class idRiser : public idMover_Periodic {
public:
CLASS_PROTOTYPE( idRiser );
idRiser( void );
void Spawn( void );
private:
void Event_Activate( idEntity *activator );
};
#endif /* !__GAME_MOVER_H__ */

3410
neo/game/MultiplayerGame.cpp Normal file

File diff suppressed because it is too large Load Diff

371
neo/game/MultiplayerGame.h Normal file
View File

@@ -0,0 +1,371 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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;
typedef enum {
GAME_SP,
GAME_DM,
GAME_TOURNEY,
GAME_TDM,
GAME_LASTMAN
} gameType_t;
typedef enum {
PLAYER_VOTE_NONE,
PLAYER_VOTE_NO,
PLAYER_VOTE_YES,
PLAYER_VOTE_WAIT // mark a player allowed to vote
} playerVote_t;
typedef struct mpPlayerState_s {
int ping; // player ping
int fragCount; // kills
int teamFragCount; // team kills
int wins; // wins
playerVote_t vote; // player's vote
bool scoreBoardUp; // toggle based on player scoreboard button, used to activate de-activate the scoreboard gui
bool ingame;
} 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 = 100;
const int MP_PLAYER_MAXWINS = 100;
const int MP_PLAYER_MAXPING = 999;
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_VOTE,
SND_VOTE_PASSED,
SND_VOTE_FAILED,
SND_THREE,
SND_TWO,
SND_ONE,
SND_SUDDENDEATH,
SND_COUNT
} snd_evt_t;
class idMultiplayerGame {
public:
idMultiplayerGame();
void Shutdown( void );
// resets everything and prepares for a match
void Reset( void );
// setup local data for a new player
void SpawnPlayer( int clientNum );
// checks rules and updates state of the mp game
void Run( void );
// draws mp hud, scoredboard, etc..
bool Draw( int clientNum );
// updates a player vote
void PlayerVote( int clientNum, playerVote_t vote );
// updates frag counts and potentially ends the match in sudden death
void PlayerDeath( idPlayer *dead, idPlayer *killer, bool telefrag );
void AddChatLine( const char *fmt, ... ) id_attribute((format(printf,2,3)));
void UpdateMainGui( void );
idUserInterface*StartMenu( void );
const char* HandleGuiCommands( const char *menuCommand );
void SetMenuSkin( void );
void WriteToSnapshot( idBitMsgDelta &msg ) const;
void ReadFromSnapshot( const idBitMsgDelta &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( void ) const;
static const char *GlobalSoundStrings[ SND_COUNT ];
void PlayGlobalSound( int to, snd_evt_t evt, const char *shader = NULL );
// more compact than a chat line
typedef enum {
MSG_SUICIDE = 0,
MSG_KILLED,
MSG_KILLEDTEAM,
MSG_DIED,
MSG_VOTE,
MSG_VOTEPASSED,
MSG_VOTEFAILED,
MSG_SUDDENDEATH,
MSG_FORCEREADY,
MSG_JOINEDSPEC,
MSG_TIMELIMIT,
MSG_FRAGLIMIT,
MSG_TELEFRAGGED,
MSG_JOINTEAM,
MSG_HOLYSHIT,
MSG_COUNT
} msg_evt_t;
void PrintMessageEvent( int to, msg_evt_t evt, int parm1 = -1, int parm2 = -1 );
void DisconnectClient( int clientNum );
static void ForceReady_f( const idCmdArgs &args );
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 );
typedef enum {
VOTE_RESTART = 0,
VOTE_TIMELIMIT,
VOTE_FRAGLIMIT,
VOTE_GAMETYPE,
VOTE_KICK,
VOTE_MAP,
VOTE_SPECTATORS,
VOTE_NEXTMAP,
VOTE_COUNT,
VOTE_NONE
} vote_flags_t;
typedef enum {
VOTE_UPDATE,
VOTE_FAILED,
VOTE_PASSED, // passed, but no reset yet
VOTE_ABORTED,
VOTE_RESET // tell clients to reset vote state
} vote_result_t;
static void Vote_f( const idCmdArgs &args );
static void CallVote_f( const idCmdArgs &args );
void ClientCallVote( vote_flags_t voteIndex, const char *voteValue );
void ServerCallVote( int clientNum, const idBitMsg &msg );
void ClientStartVote( int clientNum, const char *voteString );
void ServerStartVote( int clientNum, vote_flags_t voteIndex, const char *voteValue );
void ClientUpdateVote( vote_result_t result, int yesCount, int noCount );
void CastVote( int clientNum, bool vote );
void ExecuteVote( void );
void WantKilled( int clientNum );
int NumActualClients( bool countSpectators, int *teamcount = NULL );
void DropWeapon( int clientNum );
void MapRestart( void );
// called by idPlayer whenever it detects a team change (init or switch)
void SwitchToTeam( int clientNum, int oldteam, int newteam );
bool IsPureReady( void ) const;
void ProcessChatMessage( int clientNum, bool team, const char *name, const char *text, const char *sound );
void ProcessVoiceChat( int clientNum, bool team, int index );
void Precache( void );
// throttle UI switch rates
void ThrottleUserInfo( void );
void ToggleSpectate( void );
void ToggleReady( void );
void ToggleTeam( void );
void ClearFrags( int clientNum );
void EnterGame( int clientNum );
bool CanPlay( idPlayer *p );
bool IsInGame( int clientNum );
bool WantRespawn( idPlayer *p );
void ServerWriteInitialReliableMessages( int clientNum );
void ClientReadStartState( const idBitMsg &msg );
void ClientReadWarmupTime( const idBitMsg &msg );
void ServerClientConnect( int clientNum );
void PlayerStats( int clientNum, char *data, const int len );
private:
static const char *MPGuis[];
static const char *ThrottleVars[];
static const char *ThrottleVarsInEnglish[];
static const int ThrottleDelay[];
// state vars
gameState_t gameState; // what state the current game is in
gameState_t nextState; // state to switch to when nextStateSwitch is hit
int pingUpdateTime; // time to update ping
mpPlayerState_t playerState[ MAX_CLIENTS ];
// keep track of clients which are willingly in spectator mode
// vote vars
vote_flags_t vote; // active vote or VOTE_NONE
int voteTimeOut; // when the current vote expires
int voteExecTime; // delay between vote passed msg and execute
float yesVotes; // counter for yes votes
float noVotes; // and for no votes
idStr voteValue; // the data voted upon ( server )
idStr voteString; // the vote string ( client )
bool voted; // hide vote box ( client )
int kickVoteMap[ MAX_CLIENTS ];
// 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
idStr warmupText; // text shown in warmup area of screen
bool one, two, three; // keeps count down voice from repeating
// guis
idUserInterface *scoreBoard; // scoreboard
idUserInterface *spectateGui; // spectate info
idUserInterface *guiChat; // chat text
idUserInterface *mainGui; // ready / nick / votes etc.
idListGUI *mapList;
idUserInterface *msgmodeGui; // message mode
int currentMenu; // 0 - none, 1 - mainGui, 2 - msgmodeGui
int nextMenu; // if 0, will do mainGui
bool bCurrentMenuMsg; // send menu state updates to server
// 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 switchThrottle[ 3 ];
int voiceChatThrottle;
gameType_t lastGameType; // for restarts
int startFragLimit; // synchronize to clients in initial state, set on -> GAMEON
private:
void UpdatePlayerRanks();
// updates the passed gui with current score information
void UpdateRankColor( idUserInterface *gui, const char *mask, int i, const idVec3 &vec );
void UpdateScoreboard( idUserInterface *scoreBoard, idPlayer *player );
void ClearGuis( void );
void DrawScoreBoard( idPlayer *player );
void UpdateHud( idPlayer *player, idUserInterface *hud );
bool Warmup( void );
void CheckVote( void );
bool AllPlayersReady( void );
idPlayer * FragLimitHit( void );
idPlayer * FragLeader( void );
bool TimeLimitHit( void );
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 );
void CycleTourneyPlayers( void );
// walk through the tourneyRank to build a wait list for the clients
void UpdateTourneyLine( void );
const char * GameTime( void );
void Clear( void );
bool EnoughClientsToPlay( void );
void ClearChatData( void );
void DrawChat( void );
// 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 );
void ForceReady();
// when clients disconnect or join spectate during game, check if we need to end the game
void CheckAbortGame( void );
void MessageMode( const idCmdArgs &args );
void DisableMenu( void );
void SetMapShot( void );
// scores in TDM
void TeamScore( int entityNumber, int team, int delta );
void VoiceChat( const idCmdArgs &args, bool team );
void DumpTourneyLine( void );
void SuddenRespawn( void );
};
ID_INLINE idMultiplayerGame::gameState_t idMultiplayerGame::GetGameState( void ) const {
return gameState;
}
ID_INLINE bool idMultiplayerGame::IsPureReady( void ) const {
return pureReady;
}
ID_INLINE void idMultiplayerGame::ClearFrags( int clientNum ) {
playerState[ clientNum ].fragCount = 0;
}
ID_INLINE bool idMultiplayerGame::IsInGame( int clientNum ) {
return playerState[ clientNum ].ingame;
}
#endif /* !__MULTIPLAYERGAME_H__ */

8521
neo/game/Player.cpp Normal file

File diff suppressed because it is too large Load Diff

721
neo/game/Player.h Normal file
View File

@@ -0,0 +1,721 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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__
/*
===============================================================================
Player entity.
===============================================================================
*/
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 MAX_WEAPONS = 16;
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( 999 ); // 9 bits to cover the range [0, 999]
const int ASYNC_PLAYER_INV_CLIP_BITS = -7; // -7 bits to cover the range [-1, 60]
struct idItemInfo {
idStr name;
idStr icon;
};
struct idObjectiveInfo {
idStr title;
idStr text;
idStr screenshot;
};
struct idLevelTriggerInfo {
idStr levelName;
idStr triggerName;
};
// powerups - the "type" in item .def must match
enum {
BERSERK = 0,
INVISIBILITY,
MEGAHEALTH,
ADRENALINE,
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
};
class idInventory {
public:
int maxHealth;
int weapons;
int powerups;
int armor;
int maxarmor;
int ammo[ AMMO_NUMTYPES ];
int clip[ MAX_WEAPONS ];
int powerupEndTime[ MAX_POWERUPS ];
// mp
int ammoPredictTime;
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;
bool turkeyScore;
idList<idDict *> items;
idStrList pdas;
idStrList pdaSecurity;
idStrList videos;
idStrList emails;
bool ammoPulse;
bool weaponPulse;
bool armorPulse;
int lastGiveTime;
idList<idLevelTriggerInfo> 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 );
void GivePowerUp( idPlayer *player, int powerup, int msec );
void ClearPowerUps( void );
void GetPersistantData( idDict &dict );
void RestoreInventory( idPlayer *owner, const idDict &dict );
bool Give( idPlayer *owner, const idDict &spawnArgs, const char *statname, const char *value, int *idealWeapon, bool updateHud );
void Drop( const idDict &spawnArgs, const char *weapon_classname, int weapon_index );
ammo_t AmmoIndexForAmmoClass( const char *ammo_classname ) const;
int MaxAmmoForAmmoClass( 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, const char *icon );
int HasAmmo( ammo_t type, int amount );
bool UseAmmo( ammo_t type, int amount );
int HasAmmo( const char *weapon_classname ); // looks up the ammo information for the weapon class first
void UpdateArmor( void );
int nextItemPickup;
int nextItemNum;
int onePickupTime;
idList<idItemInfo> pickupItemNames;
idList<idObjectiveInfo> objectiveNames;
};
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_MAXEVENTS
};
usercmd_t usercmd;
class idPlayerView playerView; // handles damage kicks and effects
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
int buttonMask;
int oldButtons;
int oldFlags;
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
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;
idEntityPtr<idWeapon> weapon;
idUserInterface * hud; // MP: is NULL if not local player
idUserInterface * objectiveSystem;
bool objectiveSystemOpen;
int weapon_soulcube;
int weapon_pda;
int weapon_fists;
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;
bool hiddenWeapon; // if the weapon is hidden ( in noWeapons maps )
idEntityPtr<idProjectile> soulCubeProjectile;
// mp stuff
static idVec3 colorBarTable[ 5 ];
int spectator;
idVec3 colorBar; // used for scoreboard and hud display
int colorBarIndex;
bool scoreBoardOpen;
bool forceScoreBoard;
bool forceRespawn;
bool spectating;
int lastSpectateTeleport;
bool lastHitToggle;
bool forcedReady;
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 latchedTeam; // need to track when team gets changed
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
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.
bool 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;
public:
CLASS_PROTOTYPE( idPlayer );
idPlayer();
virtual ~idPlayer();
void Spawn( void );
void Think( void );
// 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( void );
virtual void Show( void );
void Init( void );
void PrepareForRestart( void );
virtual void Restart( void );
void LinkScriptVariables( void );
void SetupWeaponEntity( void );
void SelectInitialSpawnPoint( idVec3 &origin, idAngles &angles );
void SpawnFromSpawnSpot( void );
void SpawnToPoint( const idVec3 &spawn_origin, const idAngles &spawn_angles );
void SetClipModel( void ); // spectator mode uses a different bbox size
void SavePersistantInfo( void );
void RestorePersistantInfo( void );
void SetLevelTrigger( const char *levelName, const char *triggerName );
bool UserInfoChanged( bool canModify );
idDict * GetUserInfo( void );
bool BalanceTDM( void );
void CacheWeapons( void );
void EnterCinematic( void );
void ExitCinematic( void );
bool HandleESC( void );
bool SkipCinematic( void );
void UpdateConditions( void );
void SetViewAngles( const idAngles &angles );
// 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 );
// 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 );
void CalculateRenderView( void ); // called every tic by player code
void CalculateFirstPersonView( void );
void DrawHUD( idUserInterface *hud );
void WeaponFireFeedback( const idDict *weaponDef );
float DefaultFov( void ) const;
float CalcFov( bool honorZoom );
void CalculateViewWeaponPos( idVec3 &origin, idMat3 &axis );
idVec3 GetEyePosition( void ) 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 );
bool GiveItem( idItem *item );
void GiveItem( const char *name );
void GiveHealthPool( float amt );
bool GiveInventoryItem( idDict *item );
void RemoveInventoryItem( idDict *item );
bool GiveInventoryItem( const char *name );
void RemoveInventoryItem( const char *name );
idDict * FindInventoryItem( const char *name );
void GivePDA( const char *pdaName, idDict *item );
void GiveVideo( const char *videoName, idDict *item );
void GiveEmail( const char *emailName );
void GiveSecurity( const char *security );
void GiveObjective( const char *title, const char *text, const char *screenshot );
void CompleteObjective( const char *title );
bool GivePowerUp( int powerup, int time );
void ClearPowerUps( void );
bool PowerUpActive( int powerup ) const;
float PowerUpModifier( int type );
int SlotForWeapon( const char *weaponName );
void Reload( void );
void NextWeapon( void );
void NextBestWeapon( void );
void PrevWeapon( void );
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 );
void RaiseWeapon( void );
void WeaponLoweringCallback( void );
void WeaponRisingCallback( void );
void RemoveWeapon( const char *weap );
bool CanShowWeaponViewmodel( void ) const;
void AddAIKill( void );
void SetSoulCubeProjectile( idProjectile *projectile );
void AdjustHeartRate( int target, float timeInSecs, float delay, bool force );
void SetCurrentHeartRate( void );
int GetBaseHeartRate( void );
void UpdateAir( void );
virtual bool HandleSingleGuiCommand( idEntity *entityGui, idLexer *src );
bool GuiActive( void ) { return focusGUIent != NULL; }
void PerformImpulse( int impulse );
void Spectate( bool spectate );
void TogglePDA( void );
void ToggleScoreboard( void );
void RouteGuiMouse( idUserInterface *gui );
void UpdateHud( void );
const idDeclPDA * GetPDA( void ) const;
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( void ) { return influenceActive; };
void SetPrivateCameraView( idCamera *camView );
idCamera * GetPrivateCameraView( void ) const { return privateCameraView; }
void StartFxFov( float duration );
void UpdateHudWeapon( bool flashWeapon = true );
void UpdateHudStats( idUserInterface *hud );
void UpdateHudAmmo( idUserInterface *hud );
void Event_StopAudioLog( void );
void StartAudioLog( void );
void StopAudioLog( void );
void ShowTip( const char *title, const char *tip, bool autoHide );
void HideTip( void );
bool IsTipVisible( void ) { return tipUp; };
void ShowObjective( const char *obj );
void HideObjective( void );
virtual void ClientPredictionThink( void );
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
void WritePlayerStateToSnapshot( idBitMsgDelta &msg ) const;
void ReadPlayerStateFromSnapshot( const idBitMsgDelta &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 IsReady( void );
bool IsRespawning( void );
bool IsInTeleport( void );
idEntity *GetInfluenceEntity( void ) { return influenceEntity; };
const idMaterial *GetInfluenceMaterial( void ) { return influenceMaterial; };
float GetInfluenceRadius( void ) { 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 );
void TeleportDeath( int killer );
void SetLeader( bool lead );
bool IsLeader( void );
void UpdateSkinSetup( bool restart );
bool OnLadder( void ) const;
virtual void UpdatePlayerIcons( void );
virtual void DrawPlayerIcons( void );
virtual void HidePlayerIcons( void );
bool NeedsIcon( void );
bool SelfSmooth( void );
void SetSelfSmooth( bool b );
private:
jointHandle_t hipJoint;
jointHandle_t chestJoint;
jointHandle_t headJoint;
idPhysics_Player physicsObj; // player physics
idList<aasLocation_t> 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;
int idealWeapon;
int previousWeapon;
int weaponSwitchTime;
bool weaponEnabled;
bool showWeaponViewModel;
const idDeclSkin * skin;
const idDeclSkin * powerUpSkin;
idStr baseSkinName;
int numProjectilesFired; // number of projectiles fired
int numProjectileHits; // number of hits on mobs
bool airless;
int airTics; // set to pm_airTics 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;
idStr pdaAudio;
idStr pdaVideo;
idStr pdaVideoWave;
bool tipUp;
bool objectiveUp;
int lastDamageDef;
idVec3 lastDamageDir;
int lastDamageLocation;
int smoothedFrame;
bool smoothedOriginUpdated;
idVec3 smoothedOrigin;
idAngles smoothedAngles;
// mp
bool ready; // from userInfo
bool respawning; // set to true while in SpawnToPoint for telefrag checks
bool leader; // for sudden death situations
int lastSpectateChange;
int lastTeleFX;
unsigned int lastSnapshotSequence; // track state hitches on clients
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
idPlayerIcon playerIcon;
bool selfSmooth;
void LookAtKiller( idEntity *inflictor, idEntity *attacker );
void StopFiring( void );
void FireWeapon( void );
void Weapon_Combat( void );
void Weapon_NPC( void );
void Weapon_GUI( void );
void UpdateWeapon( void );
void UpdateSpectating( void );
void SpectateFreeFly( bool force ); // ignore the timeout to force when followed spec is no longer valid
void SpectateCycle( void );
idAngles GunTurningOffset( void );
idVec3 GunAcceleratingOffset( void );
void UseObjects( void );
void CrashLand( const idVec3 &oldOrigin, const idVec3 &oldVelocity );
void BobCycle( const idVec3 &pushVelocity );
void UpdateViewAngles( void );
void EvaluateControls( void );
void AdjustSpeed( void );
void AdjustBodyAngles( void );
void InitAASLocation( void );
void SetAASLocation( void );
void Move( void );
void UpdatePowerUps( void );
void UpdateDeathSkin( bool state_hitch );
void ClearPowerup( int i );
void SetSpectateOrigin( void );
void ClearFocus( void );
void UpdateFocus( void );
void UpdateLocation( void );
idUserInterface * ActiveGui( void );
void UpdatePDAInfo( bool updatePDASel );
int AddGuiPDAData( const declType_t dataType, const char *listName, const idDeclPDA *src, idUserInterface *gui );
void ExtractEmailInfo( const idStr &email, const char *scan, idStr &out );
void UpdateObjectiveInfo( void );
void UseVehicle( void );
void Event_GetButtons( void );
void Event_GetMove( void );
void Event_GetViewAngles( void );
void Event_StopFxFov( void );
void Event_EnableWeapon( void );
void Event_DisableWeapon( void );
void Event_GetCurrentWeapon( void );
void Event_GetPreviousWeapon( void );
void Event_SelectWeapon( const char *weaponName );
void Event_GetWeaponEntity( void );
void Event_OpenPDA( void );
void Event_PDAAvailable( void );
void Event_InPDA( void );
void Event_ExitTeleporter( void );
void Event_HideTip( void );
void Event_LevelTrigger( void );
void Event_Gibbed( void );
void Event_GetIdealWeapon( void );
};
ID_INLINE bool idPlayer::IsReady( void ) {
return ready || forcedReady;
}
ID_INLINE bool idPlayer::IsRespawning( void ) {
return respawning;
}
ID_INLINE idPhysics* idPlayer::GetPlayerPhysics( void ) {
return &physicsObj;
}
ID_INLINE bool idPlayer::IsInTeleport( void ) {
return ( teleportEntity.GetEntity() != NULL );
}
ID_INLINE void idPlayer::SetLeader( bool lead ) {
leader = lead;
}
ID_INLINE bool idPlayer::IsLeader( void ) {
return leader;
}
ID_INLINE bool idPlayer::SelfSmooth( void ) {
return selfSmooth;
}
ID_INLINE void idPlayer::SetSelfSmooth( bool b ) {
selfSmooth = b;
}
#endif /* !__GAME_PLAYER_H__ */

183
neo/game/PlayerIcon.cpp Normal file
View File

@@ -0,0 +1,183 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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"
};
/*
===============
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 ) {
// create the icon if necessary, or update if already created
if ( !CreateIcon( player, ICON_LAG, origin, axis ) ) {
UpdateIcon( player, origin, axis );
}
} else if ( player->isChatting ) {
if ( !CreateIcon( player, ICON_CHAT, origin, axis ) ) {
UpdateIcon( player, origin, axis );
}
} else {
FreeIcon();
}
}
/*
===============
idPlayerIcon::FreeIcon
===============
*/
void idPlayerIcon::FreeIcon( void ) {
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 );
}

63
neo/game/PlayerIcon.h Normal file
View File

@@ -0,0 +1,63 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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_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( void );
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_ */

722
neo/game/PlayerView.cpp Normal file
View File

@@ -0,0 +1,722 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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"
const int IMPULSE_DELAY = 150;
/*
==============
idPlayerView::idPlayerView
==============
*/
idPlayerView::idPlayerView() {
memset( screenBlobs, 0, sizeof( screenBlobs ) );
memset( &view, 0, sizeof( view ) );
player = NULL;
dvMaterial = declManager->FindMaterial( "_scratch" );
tunnelMaterial = declManager->FindMaterial( "textures/decals/tunnel" );
armorMaterial = declManager->FindMaterial( "armorViewEffect" );
berserkMaterial = declManager->FindMaterial( "textures/decals/berserk" );
irGogglesMaterial = declManager->FindMaterial( "textures/decals/irblend" );
bloodSprayMaterial = declManager->FindMaterial( "textures/decals/bloodspray" );
bfgMaterial = declManager->FindMaterial( "textures/decals/bfgvision" );
lagoMaterial = declManager->FindMaterial( LAGO_MATERIAL, false );
bfgVision = false;
dvFinishTime = 0;
kickFinishTime = 0;
kickAngles.Zero();
lastDamageTime = 0.0f;
fadeTime = 0;
fadeRate = 0.0;
fadeFromColor.Zero();
fadeToColor.Zero();
fadeColor.Zero();
shakeAng.Zero();
ClearEffects();
}
/*
==============
idPlayerView::Save
==============
*/
void idPlayerView::Save( idSaveGame *savefile ) const {
int i;
const screenBlob_t *blob;
blob = &screenBlobs[ 0 ];
for( i = 0; i < MAX_SCREEN_BLOBS; i++, blob++ ) {
savefile->WriteMaterial( blob->material );
savefile->WriteFloat( blob->x );
savefile->WriteFloat( blob->y );
savefile->WriteFloat( blob->w );
savefile->WriteFloat( blob->h );
savefile->WriteFloat( blob->s1 );
savefile->WriteFloat( blob->t1 );
savefile->WriteFloat( blob->s2 );
savefile->WriteFloat( blob->t2 );
savefile->WriteInt( blob->finishTime );
savefile->WriteInt( blob->startFadeTime );
savefile->WriteFloat( blob->driftAmount );
}
savefile->WriteInt( dvFinishTime );
savefile->WriteMaterial( dvMaterial );
savefile->WriteInt( kickFinishTime );
savefile->WriteAngles( kickAngles );
savefile->WriteBool( bfgVision );
savefile->WriteMaterial( tunnelMaterial );
savefile->WriteMaterial( armorMaterial );
savefile->WriteMaterial( berserkMaterial );
savefile->WriteMaterial( irGogglesMaterial );
savefile->WriteMaterial( bloodSprayMaterial );
savefile->WriteMaterial( bfgMaterial );
savefile->WriteFloat( lastDamageTime );
savefile->WriteVec4( fadeColor );
savefile->WriteVec4( fadeToColor );
savefile->WriteVec4( fadeFromColor );
savefile->WriteFloat( fadeRate );
savefile->WriteInt( fadeTime );
savefile->WriteAngles( shakeAng );
savefile->WriteObject( player );
savefile->WriteRenderView( view );
}
/*
==============
idPlayerView::Restore
==============
*/
void idPlayerView::Restore( idRestoreGame *savefile ) {
int i;
screenBlob_t *blob;
blob = &screenBlobs[ 0 ];
for( i = 0; i < MAX_SCREEN_BLOBS; i++, blob++ ) {
savefile->ReadMaterial( blob->material );
savefile->ReadFloat( blob->x );
savefile->ReadFloat( blob->y );
savefile->ReadFloat( blob->w );
savefile->ReadFloat( blob->h );
savefile->ReadFloat( blob->s1 );
savefile->ReadFloat( blob->t1 );
savefile->ReadFloat( blob->s2 );
savefile->ReadFloat( blob->t2 );
savefile->ReadInt( blob->finishTime );
savefile->ReadInt( blob->startFadeTime );
savefile->ReadFloat( blob->driftAmount );
}
savefile->ReadInt( dvFinishTime );
savefile->ReadMaterial( dvMaterial );
savefile->ReadInt( kickFinishTime );
savefile->ReadAngles( kickAngles );
savefile->ReadBool( bfgVision );
savefile->ReadMaterial( tunnelMaterial );
savefile->ReadMaterial( armorMaterial );
savefile->ReadMaterial( berserkMaterial );
savefile->ReadMaterial( irGogglesMaterial );
savefile->ReadMaterial( bloodSprayMaterial );
savefile->ReadMaterial( bfgMaterial );
savefile->ReadFloat( lastDamageTime );
savefile->ReadVec4( fadeColor );
savefile->ReadVec4( fadeToColor );
savefile->ReadVec4( fadeFromColor );
savefile->ReadFloat( fadeRate );
savefile->ReadInt( fadeTime );
savefile->ReadAngles( shakeAng );
savefile->ReadObject( reinterpret_cast<idClass *&>( player ) );
savefile->ReadRenderView( view );
}
/*
==============
idPlayerView::SetPlayerEntity
==============
*/
void idPlayerView::SetPlayerEntity( idPlayer *playerEnt ) {
player = playerEnt;
}
/*
==============
idPlayerView::ClearEffects
==============
*/
void idPlayerView::ClearEffects() {
lastDamageTime = MS2SEC( gameLocal.time - 99999 );
dvFinishTime = ( gameLocal.time - 99999 );
kickFinishTime = ( gameLocal.time - 99999 );
for ( int i = 0 ; i < MAX_SCREEN_BLOBS ; i++ ) {
screenBlobs[i].finishTime = gameLocal.time;
}
fadeTime = 0;
bfgVision = false;
}
/*
==============
idPlayerView::GetScreenBlob
==============
*/
screenBlob_t *idPlayerView::GetScreenBlob() {
screenBlob_t *oldest = &screenBlobs[0];
for ( int i = 1 ; i < MAX_SCREEN_BLOBS ; i++ ) {
if ( screenBlobs[i].finishTime < oldest->finishTime ) {
oldest = &screenBlobs[i];
}
}
return oldest;
}
/*
==============
idPlayerView::DamageImpulse
LocalKickDir is the direction of force in the player's coordinate system,
which will determine the head kick direction
==============
*/
void idPlayerView::DamageImpulse( idVec3 localKickDir, const idDict *damageDef ) {
//
// double vision effect
//
if ( lastDamageTime > 0.0f && SEC2MS( lastDamageTime ) + IMPULSE_DELAY > gameLocal.time ) {
// keep shotgun from obliterating the view
return;
}
float dvTime = damageDef->GetFloat( "dv_time" );
if ( dvTime ) {
if ( dvFinishTime < gameLocal.time ) {
dvFinishTime = gameLocal.time;
}
dvFinishTime += g_dvTime.GetFloat() * dvTime;
// don't let it add up too much in god mode
if ( dvFinishTime > gameLocal.time + 5000 ) {
dvFinishTime = gameLocal.time + 5000;
}
}
//
// head angle kick
//
float kickTime = damageDef->GetFloat( "kick_time" );
if ( kickTime ) {
kickFinishTime = gameLocal.time + g_kickTime.GetFloat() * kickTime;
// forward / back kick will pitch view
kickAngles[0] = localKickDir[0];
// side kick will yaw view
kickAngles[1] = localKickDir[1]*0.5f;
// up / down kick will pitch view
kickAngles[0] += localKickDir[2];
// roll will come from side
kickAngles[2] = localKickDir[1];
float kickAmplitude = damageDef->GetFloat( "kick_amplitude" );
if ( kickAmplitude ) {
kickAngles *= kickAmplitude;
}
}
//
// screen blob
//
float blobTime = damageDef->GetFloat( "blob_time" );
if ( blobTime ) {
screenBlob_t *blob = GetScreenBlob();
blob->startFadeTime = gameLocal.time;
blob->finishTime = gameLocal.time + blobTime * g_blobTime.GetFloat();
const char *materialName = damageDef->GetString( "mtr_blob" );
blob->material = declManager->FindMaterial( materialName );
blob->x = damageDef->GetFloat( "blob_x" );
blob->x += ( gameLocal.random.RandomInt()&63 ) - 32;
blob->y = damageDef->GetFloat( "blob_y" );
blob->y += ( gameLocal.random.RandomInt()&63 ) - 32;
float scale = ( 256 + ( ( gameLocal.random.RandomInt()&63 ) - 32 ) ) / 256.0f;
blob->w = damageDef->GetFloat( "blob_width" ) * g_blobSize.GetFloat() * scale;
blob->h = damageDef->GetFloat( "blob_height" ) * g_blobSize.GetFloat() * scale;
blob->s1 = 0;
blob->t1 = 0;
blob->s2 = 1;
blob->t2 = 1;
}
//
// save lastDamageTime for tunnel vision accentuation
//
lastDamageTime = MS2SEC( gameLocal.time );
}
/*
==================
idPlayerView::AddBloodSpray
If we need a more generic way to add blobs then we can do that
but having it localized here lets the material be pre-looked up etc.
==================
*/
void idPlayerView::AddBloodSpray( float duration ) {
/*
if ( duration <= 0 || bloodSprayMaterial == NULL || g_skipViewEffects.GetBool() ) {
return;
}
// visit this for chainsaw
screenBlob_t *blob = GetScreenBlob();
blob->startFadeTime = gameLocal.time;
blob->finishTime = gameLocal.time + ( duration * 1000 );
blob->material = bloodSprayMaterial;
blob->x = ( gameLocal.random.RandomInt() & 63 ) - 32;
blob->y = ( gameLocal.random.RandomInt() & 63 ) - 32;
blob->driftAmount = 0.5f + gameLocal.random.CRandomFloat() * 0.5;
float scale = ( 256 + ( ( gameLocal.random.RandomInt()&63 ) - 32 ) ) / 256.0f;
blob->w = 600 * g_blobSize.GetFloat() * scale;
blob->h = 480 * g_blobSize.GetFloat() * scale;
float s1 = 0.0f;
float t1 = 0.0f;
float s2 = 1.0f;
float t2 = 1.0f;
if ( blob->driftAmount < 0.6 ) {
s1 = 1.0f;
s2 = 0.0f;
} else if ( blob->driftAmount < 0.75 ) {
t1 = 1.0f;
t2 = 0.0f;
} else if ( blob->driftAmount < 0.85 ) {
s1 = 1.0f;
s2 = 0.0f;
t1 = 1.0f;
t2 = 0.0f;
}
blob->s1 = s1;
blob->t1 = t1;
blob->s2 = s2;
blob->t2 = t2;
*/
}
/*
==================
idPlayerView::WeaponFireFeedback
Called when a weapon fires, generates head twitches, etc
==================
*/
void idPlayerView::WeaponFireFeedback( const idDict *weaponDef ) {
int recoilTime;
recoilTime = weaponDef->GetInt( "recoilTime" );
// don't shorten a damage kick in progress
if ( recoilTime && kickFinishTime < gameLocal.time ) {
idAngles angles;
weaponDef->GetAngles( "recoilAngles", "5 0 0", angles );
kickAngles = angles;
int finish = gameLocal.time + g_kickTime.GetFloat() * recoilTime;
kickFinishTime = finish;
}
}
/*
===================
idPlayerView::CalculateShake
===================
*/
void idPlayerView::CalculateShake() {
idVec3 origin, matrix;
float shakeVolume = gameSoundWorld->CurrentShakeAmplitudeForPosition( gameLocal.time, player->firstPersonViewOrigin );
//
// shakeVolume should somehow be molded into an angle here
// it should be thought of as being in the range 0.0 -> 1.0, although
// since CurrentShakeAmplitudeForPosition() returns all the shake sounds
// the player can hear, it can go over 1.0 too.
//
shakeAng[0] = gameLocal.random.CRandomFloat() * shakeVolume;
shakeAng[1] = gameLocal.random.CRandomFloat() * shakeVolume;
shakeAng[2] = gameLocal.random.CRandomFloat() * shakeVolume;
}
/*
===================
idPlayerView::ShakeAxis
===================
*/
idMat3 idPlayerView::ShakeAxis() const {
return shakeAng.ToMat3();
}
/*
===================
idPlayerView::AngleOffset
kickVector, a world space direction that the attack should
===================
*/
idAngles idPlayerView::AngleOffset() const {
idAngles ang;
ang.Zero();
if ( gameLocal.time < kickFinishTime ) {
float offset = kickFinishTime - gameLocal.time;
ang = kickAngles * offset * offset * g_kickAmplitude.GetFloat();
for ( int i = 0 ; i < 3 ; i++ ) {
if ( ang[i] > 70.0f ) {
ang[i] = 70.0f;
} else if ( ang[i] < -70.0f ) {
ang[i] = -70.0f;
}
}
}
return ang;
}
/*
==================
idPlayerView::SingleView
==================
*/
void idPlayerView::SingleView( idUserInterface *hud, const renderView_t *view ) {
// normal rendering
if ( !view ) {
return;
}
// place the sound origin for the player
gameSoundWorld->PlaceListener( view->vieworg, view->viewaxis, player->entityNumber + 1, gameLocal.time, hud ? hud->State().GetString( "location" ) : "Undefined" );
// if the objective system is up, don't do normal drawing
if ( player->objectiveSystemOpen ) {
player->objectiveSystem->Redraw( gameLocal.time );
return;
}
// hack the shake in at the very last moment, so it can't cause any consistency problems
renderView_t hackedView = *view;
hackedView.viewaxis = hackedView.viewaxis * ShakeAxis();
gameRenderWorld->RenderScene( &hackedView );
if ( player->spectating ) {
return;
}
// draw screen blobs
if ( !pm_thirdPerson.GetBool() && !g_skipViewEffects.GetBool() ) {
for ( int i = 0 ; i < MAX_SCREEN_BLOBS ; i++ ) {
screenBlob_t *blob = &screenBlobs[i];
if ( blob->finishTime <= gameLocal.time ) {
continue;
}
blob->y += blob->driftAmount;
float fade = (float)( blob->finishTime - gameLocal.time ) / ( blob->finishTime - blob->startFadeTime );
if ( fade > 1.0f ) {
fade = 1.0f;
}
if ( fade ) {
renderSystem->SetColor4( 1,1,1,fade );
renderSystem->DrawStretchPic( blob->x, blob->y, blob->w, blob->h,blob->s1, blob->t1, blob->s2, blob->t2, blob->material );
}
}
player->DrawHUD( hud );
// armor impulse feedback
float armorPulse = ( gameLocal.time - player->lastArmorPulse ) / 250.0f;
if ( armorPulse > 0.0f && armorPulse < 1.0f ) {
renderSystem->SetColor4( 1, 1, 1, 1.0 - armorPulse );
renderSystem->DrawStretchPic( 0, 0, 640, 480, 0, 0, 1, 1, armorMaterial );
}
// tunnel vision
float health = 0.0f;
if ( g_testHealthVision.GetFloat() != 0.0f ) {
health = g_testHealthVision.GetFloat();
} else {
health = player->health;
}
float alpha = health / 100.0f;
if ( alpha < 0.0f ) {
alpha = 0.0f;
}
if ( alpha > 1.0f ) {
alpha = 1.0f;
}
if ( alpha < 1.0f ) {
renderSystem->SetColor4( ( player->health <= 0.0f ) ? MS2SEC( gameLocal.time ) : lastDamageTime, 1.0f, 1.0f, ( player->health <= 0.0f ) ? 0.0f : alpha );
renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, tunnelMaterial );
}
if ( player->PowerUpActive(BERSERK) ) {
int berserkTime = player->inventory.powerupEndTime[ BERSERK ] - gameLocal.time;
if ( berserkTime > 0 ) {
// start fading if within 10 seconds of going away
alpha = (berserkTime < 10000) ? (float)berserkTime / 10000 : 1.0f;
renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, alpha );
renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, berserkMaterial );
}
}
if ( bfgVision ) {
renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f );
renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, bfgMaterial );
}
}
// test a single material drawn over everything
if ( g_testPostProcess.GetString()[0] ) {
const idMaterial *mtr = declManager->FindMaterial( g_testPostProcess.GetString(), false );
if ( !mtr ) {
common->Printf( "Material not found.\n" );
g_testPostProcess.SetString( "" );
} else {
renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f );
renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, mtr );
}
}
}
/*
===================
idPlayerView::DoubleVision
===================
*/
void idPlayerView::DoubleVision( idUserInterface *hud, const renderView_t *view, int offset ) {
if ( !g_doubleVision.GetBool() ) {
SingleView( hud, view );
return;
}
float scale = offset * g_dvAmplitude.GetFloat();
if ( scale > 0.5f ) {
scale = 0.5f;
}
float shift = scale * sin( sqrtf( offset ) * g_dvFrequency.GetFloat() );
shift = fabs( shift );
// if double vision, render to a texture
renderSystem->CropRenderSize( 512, 256, true );
SingleView( hud, view );
renderSystem->CaptureRenderToImage( "_scratch" );
renderSystem->UnCrop();
// carry red tint if in berserk mode
idVec4 color(1, 1, 1, 1);
if ( gameLocal.time < player->inventory.powerupEndTime[ BERSERK ] ) {
color.y = 0;
color.z = 0;
}
renderSystem->SetColor4( color.x, color.y, color.z, 1.0f );
renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, shift, 1, 1, 0, dvMaterial );
renderSystem->SetColor4( color.x, color.y, color.z, 0.5f );
renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1, 1-shift, 0, dvMaterial );
}
/*
===================
idPlayerView::BerserkVision
===================
*/
void idPlayerView::BerserkVision( idUserInterface *hud, const renderView_t *view ) {
renderSystem->CropRenderSize( 512, 256, true );
SingleView( hud, view );
renderSystem->CaptureRenderToImage( "_scratch" );
renderSystem->UnCrop();
renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f );
renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1, 1, 0, dvMaterial );
}
/*
=================
idPlayerView::Flash
flashes the player view with the given color
=================
*/
void idPlayerView::Flash(idVec4 color, int time ) {
Fade(idVec4(0, 0, 0, 0), time);
fadeFromColor = colorWhite;
}
/*
=================
idPlayerView::Fade
used for level transition fades
assumes: color.w is 0 or 1
=================
*/
void idPlayerView::Fade( idVec4 color, int time ) {
if ( !fadeTime ) {
fadeFromColor.Set( 0.0f, 0.0f, 0.0f, 1.0f - color[ 3 ] );
} else {
fadeFromColor = fadeColor;
}
fadeToColor = color;
if ( time <= 0 ) {
fadeRate = 0;
time = 0;
fadeColor = fadeToColor;
} else {
fadeRate = 1.0f / ( float )time;
}
if ( gameLocal.realClientTime == 0 && time == 0 ) {
fadeTime = 1;
} else {
fadeTime = gameLocal.realClientTime + time;
}
}
/*
=================
idPlayerView::ScreenFade
=================
*/
void idPlayerView::ScreenFade() {
int msec;
float t;
if ( !fadeTime ) {
return;
}
msec = fadeTime - gameLocal.realClientTime;
if ( msec <= 0 ) {
fadeColor = fadeToColor;
if ( fadeColor[ 3 ] == 0.0f ) {
fadeTime = 0;
}
} else {
t = ( float )msec * fadeRate;
fadeColor = fadeFromColor * t + fadeToColor * ( 1.0f - t );
}
if ( fadeColor[ 3 ] != 0.0f ) {
renderSystem->SetColor4( fadeColor[ 0 ], fadeColor[ 1 ], fadeColor[ 2 ], fadeColor[ 3 ] );
renderSystem->DrawStretchPic( 0, 0, 640, 480, 0, 0, 1, 1, declManager->FindMaterial( "_white" ) );
}
}
/*
===================
idPlayerView::InfluenceVision
===================
*/
void idPlayerView::InfluenceVision( idUserInterface *hud, const renderView_t *view ) {
float distance = 0.0f;
float pct = 1.0f;
if ( player->GetInfluenceEntity() ) {
distance = ( player->GetInfluenceEntity()->GetPhysics()->GetOrigin() - player->GetPhysics()->GetOrigin() ).Length();
if ( player->GetInfluenceRadius() != 0.0f && distance < player->GetInfluenceRadius() ) {
pct = distance / player->GetInfluenceRadius();
pct = 1.0f - idMath::ClampFloat( 0.0f, 1.0f, pct );
}
}
if ( player->GetInfluenceMaterial() ) {
SingleView( hud, view );
renderSystem->CaptureRenderToImage( "_currentRender" );
renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, pct );
renderSystem->DrawStretchPic( 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f, 1.0f, player->GetInfluenceMaterial() );
} else if ( player->GetInfluenceEntity() == NULL ) {
SingleView( hud, view );
return;
} else {
int offset = 25 + sinf( gameLocal.time );
DoubleVision( hud, view, pct * offset );
}
}
/*
===================
idPlayerView::RenderPlayerView
===================
*/
void idPlayerView::RenderPlayerView( idUserInterface *hud ) {
const renderView_t *view = player->GetRenderView();
if ( g_skipViewEffects.GetBool() ) {
SingleView( hud, view );
} else {
if ( player->GetInfluenceMaterial() || player->GetInfluenceEntity() ) {
InfluenceVision( hud, view );
} else if ( gameLocal.time < dvFinishTime ) {
DoubleVision( hud, view, dvFinishTime - gameLocal.time );
} else if ( player->PowerUpActive( BERSERK ) ) {
BerserkVision( hud, view );
} else {
SingleView( hud, view );
}
ScreenFade();
}
if ( net_clientLagOMeter.GetBool() && lagoMaterial && gameLocal.isClient ) {
renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f );
renderSystem->DrawStretchPic( 10.0f, 380.0f, 64.0f, 64.0f, 0.0f, 0.0f, 1.0f, 1.0f, lagoMaterial );
}
}

126
neo/game/PlayerView.h Normal file
View File

@@ -0,0 +1,126 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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__
/*
===============================================================================
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 idPlayerView {
public:
idPlayerView();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void SetPlayerEntity( class idPlayer *playerEnt );
void ClearEffects( void );
void DamageImpulse( idVec3 localKickDir, const idDict *damageDef );
void WeaponFireFeedback( const idDict *weaponDef );
idAngles AngleOffset( void ) const; // returns the current kick angle
idMat3 ShakeAxis( void ) const; // returns the current shake angle
void CalculateShake( void );
// this may involve rendering to a texture and displaying
// that with a warp model or in double vision mode
void RenderPlayerView( idUserInterface *hud );
void Fade( idVec4 color, int time );
void Flash( idVec4 color, int time );
void AddBloodSpray( float duration );
// temp for view testing
void EnableBFGVision( bool b ) { bfgVision = b; };
private:
void SingleView( idUserInterface *hud, const renderView_t *view );
void DoubleVision( idUserInterface *hud, const renderView_t *view, int offset );
void BerserkVision( idUserInterface *hud, const renderView_t *view );
void InfluenceVision( idUserInterface *hud, const renderView_t *view );
void ScreenFade();
screenBlob_t * GetScreenBlob();
screenBlob_t screenBlobs[MAX_SCREEN_BLOBS];
int dvFinishTime; // double vision will be stopped at this time
const idMaterial * dvMaterial; // material to take the double vision screen shot
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
const idMaterial * lagoMaterial; // lagometer drawing
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;
};
#endif /* !__GAME_PLAYERVIEW_H__ */

2393
neo/game/Projectile.cpp Normal file

File diff suppressed because it is too large Load Diff

269
neo/game/Projectile.h Normal file
View File

@@ -0,0 +1,269 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 );
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( void );
idEntity * GetOwner( void ) const;
virtual void Think( void );
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( void );
static idVec3 GetVelocity( const idDict *projectile );
static idVec3 GetGravity( const idDict *projectile );
enum {
EVENT_DAMAGE_EFFECT = idEntity::EVENT_MAXEVENTS,
EVENT_MAXEVENTS
};
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( void );
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
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;
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;
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:
bool netSyncPhysics;
void AddDefaultDamageEffect( const trace_t &collision, const idVec3 &velocity );
void Event_Explode( void );
void Event_Fizzle( void );
void Event_RadiusDamage( idEntity *ignore );
void Event_Touch( idEntity *other, trace_t *trace );
void Event_GetProjectileState( void );
};
class idGuidedProjectile : public idProjectile {
public :
CLASS_PROTOTYPE( idGuidedProjectile );
idGuidedProjectile( void );
~idGuidedProjectile( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
virtual void Think( void );
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 );
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( void );
virtual void Think( void );
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 );
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( void );
virtual void Think( void );
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> beamTargets;
renderEntity_t secondModel;
qhandle_t secondModelDefHandle;
int nextDamageTime;
idStr damageFreq;
void FreeBeams();
void Event_RemoveBeams();
void ApplyDamage();
};
/*
===============================================================================
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 );
void Create( idEntity *owner, const idVec3 &start, const idMat3 &axis );
void Launch( void );
void Think( void );
void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
void Explode( void );
void Fizzle( void );
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 );
void Event_Fizzle( void );
};
#endif /* !__GAME_PROJECTILE_H__ */

1422
neo/game/Pvs.cpp Normal file

File diff suppressed because it is too large Load Diff

129
neo/game/Pvs.h Normal file
View File

@@ -0,0 +1,129 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 8 // 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( void );
~idPVS( void );
// setup for the current map
void Init( void );
void Shutdown( void );
// 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;
#if ASYNC_WRITE_PVS
void WritePVS( const pvsHandle_t handle, idBitMsg &msg );
void ReadPVS( const pvsHandle_t handle, const idBitMsg &msg );
#endif
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( void ) const;
void CreatePVSData( void );
void DestroyPVSData( void );
void CopyPortalPVSToMightSee( void ) const;
void FloodFrontPortalPVS_r( struct pvsPortal_s *portal, int areaNum ) const;
void FrontPortalPVS( void ) const;
struct pvsStack_s * FloodPassagePVS_r( struct pvsPortal_s *source, const struct pvsPortal_s *portal, struct pvsStack_s *prevStack ) const;
void PassagePVS( void ) const;
void AddPassageBoundaries( const idWinding &source, const idWinding &pass, bool flipClip, idPlane *bounds, int &numBounds, int maxBounds ) const;
void CreatePassages( void ) const;
void DestroyPassages( void ) const;
int AreaPVSFromPortalPVS( void ) const;
void GetConnectedAreas( int srcArea, bool *connectedAreas ) const;
pvsHandle_t AllocCurrentPVS( unsigned int h ) const;
};
#endif /* !__GAME_PVS_H__ */

587
neo/game/SecurityCamera.cpp Normal file
View File

@@ -0,0 +1,587 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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( void ) {
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( void ) {
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( void ) {
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( void ) {
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( void ) {
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( void ) const {
return (flipAxis) ? -GetPhysics()->GetAxis()[modelAxis] : GetPhysics()->GetAxis()[modelAxis];
};
/*
================
idSecurityCamera::SweepSpeed
================
*/
float idSecurityCamera::SweepSpeed( void ) const {
return spawnArgs.GetFloat( "sweepSpeed", "5" );
}
/*
================
idSecurityCamera::StartSweep
================
*/
void idSecurityCamera::StartSweep( void ) {
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( void ) {
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( void ) {
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( void ) {
angle = GetPhysics()->GetAxis().ToAngles().yaw;
negativeSweep = !negativeSweep;
StartSweep();
}
/*
================
idSecurityCamera::Event_Pause
================
*/
void idSecurityCamera::Event_Pause( void ) {
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 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( void ) {
// 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/game/SecurityCamera.h Normal file
View File

@@ -0,0 +1,97 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think( void );
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( void );
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( void );
bool CanSeePlayer( void );
void SetAlertMode( int status );
void DrawFov( void );
const idVec3 GetAxis( void ) const;
float SweepSpeed( void ) const;
void Event_ReverseSweep( void );
void Event_ContinueSweep( void );
void Event_Pause( void );
void Event_Alert( void );
void Event_AddLight( void );
};
#endif /* !__GAME_SECURITYCAMERA_H__ */

421
neo/game/SmokeParticles.cpp Normal file
View File

@@ -0,0 +1,421 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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( void ) {
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( void ) {
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( void ) {
// 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( void ) {
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 = (float)( gameLocal.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 ) {
bool continues = false;
if ( !smoke ) {
return false;
}
if ( !gameLocal.isNewFrame ) {
return false;
}
// dedicated doesn't smoke. No UpdateRenderEntity, so they would not be freed
if ( gameLocal.localClientNum < 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, prevCount;
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 - USERCMD_MSEC ) / 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;
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 ; 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->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 ) {
// FIXME: re-use model surfaces
renderEntity->hModel->InitEmpty( smokeParticle_SnapshotName );
// 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 ) {
return false;
}
// don't regenerate it if it is current
if ( renderView->time == currentParticleTime && !renderView->forceUpdate ) {
return false;
}
currentParticleTime = renderView->time;
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;
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;
}

102
neo/game/SmokeParticles.h Normal file
View File

@@ -0,0 +1,102 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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;
} singleSmoke_t;
typedef struct {
const idParticleStage * stage;
singleSmoke_t * smokes;
} activeSmokeStage_t;
class idSmokeParticles {
public:
idSmokeParticles( void );
// creats an entity covering the entire world that will call back each rendering
void Init( void );
void Shutdown( void );
// 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 );
// free old smokes
void FreeSmokes( void );
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> 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__ */

305
neo/game/Sound.cpp Normal file
View File

@@ -0,0 +1,305 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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( void ) {
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( void ) {
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 ( gameLocal.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( void ) {
DoSound( true );
PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random );
}
/*
================
idSound::Think
================
*/
void idSound::Think( void ) {
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( void ) {
if ( wait > 0.0f ) {
timerOn = true;
PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random );
}
DoSound( true );
}
/*
================
idSound::Event_Off
================
*/
void idSound::Event_Off( void ) {
if ( timerOn ) {
timerOn = false;
CancelEvents( &EV_Speaker_Timer );
}
DoSound( false );
}
/*
===============
idSound::ShowEditingDialog
===============
*/
void idSound::ShowEditingDialog( void ) {
common->InitTool( EDITOR_SOUND, &spawnArgs );
}

76
neo/game/Sound.h Normal file
View File

@@ -0,0 +1,76 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void UpdateChangeableSpawnArgs( const idDict *source );
void Spawn( void );
void ToggleOnOff( idEntity *other, idEntity *activator );
void Think( void );
void SetSound( const char *sound, int channel = SND_CHANNEL_ANY );
virtual void ShowEditingDialog( void );
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 );
void Event_On( void );
void Event_Off( void );
void DoSound( bool play );
};
#endif /* !__GAME_SOUND_H__ */

1765
neo/game/Target.cpp Normal file

File diff suppressed because it is too large Load Diff

567
neo/game/Target.h Normal file
View File

@@ -0,0 +1,567 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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( void );
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 );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Think( void );
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( void );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_GiveEmail
===============================================================================
*/
class idTarget_GiveEmail : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_GiveEmail );
void Spawn( void );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_SetModel
===============================================================================
*/
class idTarget_SetModel : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_SetModel );
void Spawn( void );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_SetInfluence
===============================================================================
*/
class idTarget_SetInfluence : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_SetInfluence );
idTarget_SetInfluence( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
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( void );
idList<int> lightList;
idList<int> guiList;
idList<int> soundList;
idList<int> genericList;
float flashIn;
float flashOut;
float delay;
idStr flashInSound;
idStr flashOutSound;
idEntity * switchToCamera;
idInterpolate<float>fovSetting;
bool soundFaded;
bool restoreOnTrigger;
};
/*
===============================================================================
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( void );
private:
idInterpolate<int> 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 );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
private:
idVec3 playerPos;
void Event_Activate( idEntity *activator );
void Event_TipOff( void );
void Event_GetPlayerPos( void );
};
/*
===============================================================================
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_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();
};
#endif /* !__GAME_TARGET_H__ */

1192
neo/game/Trigger.cpp Normal file

File diff suppressed because it is too large Load Diff

287
neo/game/Trigger.h Normal file
View File

@@ -0,0 +1,287 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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( void );
idTrigger();
void Spawn( void );
const function_t * GetScriptFunction( void ) const;
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Enable( void );
virtual void Disable( void );
protected:
void CallScript( void ) const;
void Event_Enable( void );
void Event_Disable( void );
const function_t * scriptFunction;
};
/*
===============================================================================
Trigger which can be activated multiple times.
===============================================================================
*/
class idTrigger_Multi : public idTrigger {
public:
CLASS_PROTOTYPE( idTrigger_Multi );
idTrigger_Multi( void );
void Spawn( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
private:
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 );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
private:
float wait;
float random;
float delay;
float random_delay;
int nextTriggerTime;
bool triggerFirst;
idStr entityName;
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 );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
virtual void Enable( void );
virtual void Disable( void );
private:
float random;
float wait;
bool on;
float delay;
idStr onName;
idStr offName;
void Event_Timer( void );
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 );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
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 );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
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 );
void Spawn( void );
virtual void Think( void );
void Save( idSaveGame *savefile );
void Restore( idRestoreGame *savefile );
virtual void Enable( void );
virtual void Disable( void );
void TouchEntities( void );
private:
idClipModel * clipModel;
void Event_Trigger( idEntity *activator );
};
#endif /* !__GAME_TRIGGER_H__ */

3167
neo/game/Weapon.cpp Normal file

File diff suppressed because it is too large Load Diff

365
neo/game/Weapon.h Normal file
View File

@@ -0,0 +1,365 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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__
/*
===============================================================================
Player Weapon
===============================================================================
*/
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;
class idWeapon : public idAnimatedEntity {
public:
CLASS_PROTOTYPE( idWeapon );
idWeapon();
virtual ~idWeapon();
// Init
void Spawn( void );
void SetOwner( idPlayer *owner );
idPlayer* GetOwner( void );
virtual bool ShouldConstructScriptObjectAtSpawn( void ) const;
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 );
void GetWeaponDef( const char *objectname, int ammoinclip );
bool IsLinked( void );
bool IsWorldModelReady( void );
// GUIs
const char * Icon( void ) const;
void UpdateGUI( void );
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( void );
// State control/player interface
void Think( void );
void Raise( void );
void PutAway( void );
void Reload( void );
void LowerWeapon( void );
void RaiseWeapon( void );
void HideWeapon( void );
void ShowWeapon( void );
void HideWorldModel( void );
void ShowWorldModel( void );
void OwnerDied( void );
void BeginAttack( void );
void EndAttack( void );
bool IsReady( void ) const;
bool IsReloading( void ) const;
bool IsHolstered( void ) const;
bool ShowCrosshair( void ) const;
idEntity * DropItem( const idVec3 &velocity, int activateDelay, int removeDelay, bool died );
bool CanDrop( void ) const;
void WeaponStolen( void );
// Script state management
virtual idThread * ConstructScriptObject( void );
virtual void DeconstructScriptObject( void );
void SetState( const char *statename, int blendFrames );
void UpdateScript( void );
void EnterCinematic( void );
void ExitCinematic( void );
void NetCatchup( void );
// Visual presentation
void PresentWeapon( bool showViewModel );
int GetZoomFov( void );
void GetWeaponAngleOffsets( int *average, float *scale, float *max );
void GetWeaponTimeOffsets( float *time, float *scale );
bool BloodSplat( float size );
// 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( void ) const;
int AmmoAvailable( void ) const;
int AmmoInClip( void ) const;
void ResetAmmoClip( void );
int ClipSize( void ) const;
int LowAmmo( void ) const;
int AmmoRequired( void ) const;
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
virtual void ReadFromSnapshot( const idBitMsgDelta &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( void );
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;
// 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;
// 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;
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
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;
// 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( void );
// Visual presentation
void InitWorldModel( const idDeclEntityDef *def );
void MuzzleFlashLight( void );
void MuzzleRise( idVec3 &origin, idMat3 &axis );
void UpdateNozzleFx( void );
void UpdateFlashPosition( void );
// script events
void Event_Clear( void );
void Event_GetOwner( void );
void Event_WeaponState( const char *statename, int blendFrames );
void Event_SetWeaponStatus( float newStatus );
void Event_WeaponReady( void );
void Event_WeaponOutOfAmmo( void );
void Event_WeaponReloading( void );
void Event_WeaponHolstered( void );
void Event_WeaponRising( void );
void Event_WeaponLowering( void );
void Event_UseAmmo( int amount );
void Event_AddToClip( int amount );
void Event_AmmoInClip( void );
void Event_AmmoAvailable( void );
void Event_TotalAmmoCount( void );
void Event_ClipSize( void );
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 );
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 );
void Event_EjectBrass( void );
void Event_Melee( void );
void Event_GetWorldModel( void );
void Event_AllowDrop( int allow );
void Event_AutoReload( void );
void Event_NetReload( void );
void Event_IsInvisible( void );
void Event_NetEndReload( void );
};
ID_INLINE bool idWeapon::IsLinked( void ) {
return isLinked;
}
ID_INLINE bool idWeapon::IsWorldModelReady( void ) {
return ( worldModel.GetEntity() != NULL );
}
ID_INLINE idPlayer* idWeapon::GetOwner( void ) {
return owner;
}
#endif /* !__GAME_WEAPON_H__ */

143
neo/game/WorldSpawn.cpp Normal file
View File

@@ -0,0 +1,143 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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( void ) {
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( idRestoreGame *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( void ) {
gameLocal.Error( "Tried to remove world" );
}

55
neo/game/WorldSpawn.h Normal file
View File

@@ -0,0 +1,55 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 );
void Save( idRestoreGame *savefile );
void Restore( idRestoreGame *savefile );
private:
void Event_Remove( void );
};
#endif /* !__GAME_WORLDSPAWN_H__ */

275
neo/game/ai/AAS.cpp Normal file
View File

@@ -0,0 +1,275 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 "AAS_local.h"
/*
============
idAAS::Alloc
============
*/
idAAS *idAAS::Alloc( void ) {
return new idAASLocal;
}
/*
============
idAAS::idAAS
============
*/
idAAS::~idAAS( void ) {
}
/*
============
idAASLocal::idAASLocal
============
*/
idAASLocal::idAASLocal( void ) {
file = NULL;
}
/*
============
idAASLocal::~idAASLocal
============
*/
idAASLocal::~idAASLocal( void ) {
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( void ) {
if ( file ) {
ShutdownRouting();
RemoveAllObstacles();
AASFileManager->FreeAAS( file );
file = NULL;
}
}
/*
============
idAASLocal::Stats
============
*/
void idAASLocal::Stats( void ) const {
if ( !file ) {
return;
}
common->Printf( "[%s]\n", file->GetName() );
file->PrintInfo();
RoutingStats();
}
/*
============
idAASLocal::GetSettings
============
*/
const idAASSettings *idAASLocal::GetSettings( void ) 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[INTSIGNBITSET(edgeNum)];
verts[1] = v[INTSIGNBITNOTSET(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[INTSIGNBITSET(edgeNum)] );
end = file->GetVertex( v[INTSIGNBITNOTSET(edgeNum)] );
}

141
neo/game/ai/AAS.h Normal file
View File

@@ -0,0 +1,141 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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( void );
virtual ~idAAS( void ) = 0;
// Initialize for the given map.
virtual bool Init( const idStr &mapName, unsigned int mapFileCRC ) = 0;
// Print AAS stats.
virtual void Stats( void ) const = 0;
// Test from the given origin.
virtual void Test( const idVec3 &origin ) = 0;
// Get the AAS settings.
virtual const idAASSettings *GetSettings( void ) 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( void ) = 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/game/ai/AAS_debug.cpp Normal file
View File

@@ -0,0 +1,508 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 "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( void ) 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/game/ai/AAS_local.h Normal file
View File

@@ -0,0 +1,189 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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( void );
int Size( void ) 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( void ) { }
private:
idBounds bounds; // obstacle bounds
idList<int> areas; // areas the bounds are in
};
class idAASLocal : public idAAS {
public:
idAASLocal( void );
virtual ~idAASLocal( void );
virtual bool Init( const idStr &mapName, unsigned int mapFileCRC );
virtual void Shutdown( void );
virtual void Stats( void ) const;
virtual void Test( const idVec3 &origin );
virtual const idAASSettings *GetSettings( void ) 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( void );
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 *> obstacleList; // list with obstacles
private: // routing
bool SetupRouting( void );
void ShutdownRouting( void );
unsigned short AreaTravelTime( int areaNum, const idVec3 &start, const idVec3 &end ) const;
void CalculateAreaTravelTimes( void );
void DeleteAreaTravelTimes( void );
void SetupRoutingCache( void );
void DeleteClusterCache( int clusterNum );
void DeletePortalCache( void );
void ShutdownRoutingCache( void );
void RoutingStats( void ) const;
void LinkCache( idRoutingCache *cache ) const;
void UnlinkCache( idRoutingCache *cache ) const;
void DeleteOldestCache( void ) 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( void ) 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__ */

716
neo/game/ai/AAS_pathing.cpp Normal file
View File

@@ -0,0 +1,716 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 "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 ( FLOATSIGNBITSET( d1 ) == FLOATSIGNBITSET( 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;
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 ) {
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;
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 ) {
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;
}

1349
neo/game/ai/AAS_routing.cpp Normal file

File diff suppressed because it is too large Load Diff

5106
neo/game/ai/AI.cpp Normal file

File diff suppressed because it is too large Load Diff

691
neo/game/ai/AI.h Normal file
View File

@@ -0,0 +1,691 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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
// 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_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;
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 );
void HeardSound( idEntity *ent, const char *action );
idActor *GetEnemy( void ) const;
void TalkTo( idActor *actor );
talkState_t GetTalkState( void ) 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( void );
// 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 );
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> missileLaunchOffset;
const idDict * projectileDef;
mutable idClipModel *projectileClipModel;
float projectileRadius;
float projectileSpeed;
idVec3 projectileVelocity;
idVec3 projectileGravity;
idEntityPtr<idProjectile> projectile;
idStr attack;
// 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> lookJoints;
idList<idAngles> lookJointAngles;
float eyeVerticalOffset;
float eyeHorizontalOffset;
float eyeFocusRate;
float headFocusRate;
int focusAlignTime;
// special fx
float shrivel_rate;
int shrivel_start;
bool restartParticles; // should smoke emissions restart
bool useBoneAxis; // use the bone vs the model axis
idList<particleEmitter_t> 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;
// 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( void );
virtual void DormantBegin( void ); // called when entity becomes dormant
virtual void DormantEnd( void ); // called when entity wakes from being dormant
void Think( void );
void Activate( idEntity *activator );
int ReactionTo( const idEntity *ent );
bool CheckForEnemy( void );
void EnemyDead( void );
virtual bool CanPlayChatterSounds( void ) const;
void SetChatSound( void );
void PlayChatter( void );
virtual void Hide( void );
virtual void Show( void );
idVec3 FirstVisiblePointOnPath( const idVec3 origin, const idVec3 &target, int travelFlags ) const;
void CalculateAttackOffsets( void );
void PlayCinematic( void );
// 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 );
void AnimMove( void );
void SlideMove( void );
void AdjustFlyingAngles( void );
void AddFlyBob( idVec3 &vel );
void AdjustFlyHeight( idVec3 &vel, const idVec3 &goalPos );
void FlySeekGoal( idVec3 &vel, idVec3 &goalPos );
void AdjustFlySpeed( idVec3 &vel );
void FlyTurn( void );
void FlyMove( void );
void StaticMove( void );
// 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( void ) const;
bool GetMovePos( idVec3 &seekPos );
bool MoveDone( void ) const;
bool EntityCanSeePos( idActor *actor, const idVec3 &actorOrigin, const idVec3 &pos );
void BlockedFailSafe( void );
// movement control
void StopMove( moveStatus_t status );
bool FaceEnemy( void );
bool FaceEntity( idEntity *ent );
bool DirectMoveToPosition( const idVec3 &pos );
bool MoveToEnemyHeight( void );
bool MoveOutOfRange( idEntity *entity, float range );
bool MoveToAttackPosition( idEntity *ent, int attack_anim );
bool MoveToEnemy( void );
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( void );
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( void );
// turning
bool FacingIdeal( void );
void Turn( void );
bool TurnToward( float yaw );
bool TurnToward( const idVec3 &pos );
// enemy management
void ClearEnemy( void );
bool EnemyPositionValid( void ) const;
void SetEnemyPosition( void );
void UpdateEnemyPosition( void );
void SetEnemy( idActor *newEnemy );
// attacks
void CreateProjectileClipModel( void ) const;
idProjectile *CreateProjectile( const idVec3 &pos, const idVec3 &dir );
void RemoveProjectile( void );
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( void ) const;
bool AttackMelee( const char *meleeDefName );
void BeginAttack( const char *name );
void EndAttack( void );
void PushWithAF( void );
// special effects
void GetMuzzle( const char *jointname, idVec3 &muzzle, idMat3 &axis );
void InitMuzzleFlash( void );
void TriggerWeaponEffects( const idVec3 &muzzle );
void UpdateMuzzleFlash( void );
virtual bool UpdateAnimationControllers( void );
void UpdateParticles( void );
void TriggerParticles( const char *jointName );
// AI script state management
void LinkScriptVariables( void );
void UpdateAIScript( void );
//
// 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 );
void Event_ClosestReachableEnemyOfEntity( idEntity *team_mate );
void Event_HeardSound( int ignore_team );
void Event_SetEnemy( idEntity *ent );
void Event_ClearEnemy( void );
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_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 );
void Event_MeleeAttackToJoint( const char *jointname, const char *meleeDefName );
void Event_RandomPath( void );
void Event_CanBecomeSolid( void );
void Event_BecomeSolid( void );
void Event_BecomeNonSolid( void );
void Event_BecomeRagdoll( void );
void Event_StopRagdoll( void );
void Event_SetHealth( float newHealth );
void Event_GetHealth( void );
void Event_AllowDamage( void );
void Event_IgnoreDamage( void );
void Event_GetCurrentYaw( void );
void Event_TurnTo( float angle );
void Event_TurnToPos( const idVec3 &pos );
void Event_TurnToEntity( idEntity *ent );
void Event_MoveStatus( void );
void Event_StopMove( void );
void Event_MoveToCover( void );
void Event_MoveToEnemy( void );
void Event_MoveToEnemyHeight( void );
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 );
void Event_FacingIdeal( void );
void Event_FaceEnemy( void );
void Event_FaceEntity( idEntity *ent );
void Event_WaitAction( const char *waitForState );
void Event_GetCombatNode( void );
void Event_EnemyInCombatCone( idEntity *ent, int use_current_enemy_location );
void Event_WaitMove( void );
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 );
void Event_SetTalkState( int state );
void Event_EnemyRange( void );
void Event_EnemyRange2D( void );
void Event_GetEnemy( void );
void Event_GetEnemyPos( void );
void Event_GetEnemyEyePos( void );
void Event_PredictEnemyPos( float time );
void Event_CanHitEnemy( void );
void Event_CanHitEnemyFromAnim( const char *animname );
void Event_CanHitEnemyFromJoint( const char *jointname );
void Event_EnemyPositionValid( void );
void Event_ChargeAttack( const char *damageDef );
void Event_TestChargeAttack( void );
void Event_TestAnimMoveTowardEnemy( const char *animname );
void Event_TestAnimMove( const char *animname );
void Event_TestMoveToPosition( const idVec3 &position );
void Event_TestMeleeAttack( void );
void Event_TestAnimAttack( const char *animname );
void Event_Shrivel( float shirvel_time );
void Event_Burn( void );
void Event_PreBurn( void );
void Event_ClearBurn( void );
void Event_SetSmokeVisibility( int num, int on );
void Event_NumSmokeEmitters( void );
void Event_StopThinking( void );
void Event_GetTurnDelta( void );
void Event_GetMoveType( void );
void Event_SetMoveType( int moveType );
void Event_SaveMove( void );
void Event_RestoreMove( void );
void Event_AllowMovement( float flag );
void Event_JumpFrame( void );
void Event_EnableClip( void );
void Event_DisableClip( void );
void Event_EnableGravity( void );
void Event_DisableGravity( void );
void Event_EnableAFPush( void );
void Event_DisableAFPush( void );
void Event_SetFlySpeed( float speed );
void Event_SetFlyOffset( int offset );
void Event_ClearFlyOffset( void );
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 );
void Event_ThrowAF( void );
void Event_SetAngles( idAngles const &ang );
void Event_GetAngles( void );
void Event_RealKill( void );
void Event_Kill( void );
void Event_WakeOnFlashlight( int enable );
void Event_LocateEnemy( void );
void Event_KickObstacles( idEntity *kickEnt, float force );
void Event_GetObstacle( void );
void Event_PushPointIntoAAS( const idVec3 &pos );
void Event_GetTurnRate( void );
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 );
void Event_GetReachableEntityPosition( idEntity *ent );
};
class idCombatNode : public idEntity {
public:
CLASS_PROTOTYPE( idCombatNode );
idCombatNode();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn( void );
bool IsDisabled( void ) const;
bool EntityInView( idActor *actor, const idVec3 &pos );
static void DrawDebugInfo( void );
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( void );
};
#endif /* !__AI_H__ */

147
neo/game/ai/AI_Vagary.cpp Normal file
View File

@@ -0,0 +1,147 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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
***********************************************************************/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#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 );
}
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 );
}
}

2707
neo/game/ai/AI_events.cpp Normal file

File diff suppressed because it is too large Load Diff

1524
neo/game/ai/AI_pathing.cpp Normal file

File diff suppressed because it is too large Load Diff

1087
neo/game/anim/Anim.cpp Normal file

File diff suppressed because it is too large Load Diff

621
neo/game/anim/Anim.h Normal file
View File

@@ -0,0 +1,621 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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_TX BIT( 0 )
#define ANIM_TY BIT( 1 )
#define ANIM_TZ BIT( 2 )
#define ANIM_QX BIT( 3 )
#define ANIM_QY BIT( 4 )
#define ANIM_QZ BIT( 5 )
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
} 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;
/*
==============================================================================================
idModelExport
==============================================================================================
*/
class idModelExport {
private:
void Reset( void );
bool ParseOptions( idLexer &lex );
int ParseExportSection( idParser &parser );
static bool CheckMayaInstall( void );
static void LoadMayaDll( void );
bool ConvertMayaToMD5( void );
static bool initialized;
public:
idStr commandLine;
idStr src;
idStr dest;
bool force;
idModelExport();
static void Shutdown( void );
int ExportDefFile( const char *filename );
bool ExportModel( const char *model );
bool ExportAnim( const char *anim );
int ExportModels( const char *pathname, const char *extension );
};
/*
==============================================================================================
idMD5Anim
==============================================================================================
*/
class idMD5Anim {
private:
int numFrames;
int frameRate;
int animLength;
int numJoints;
int numAnimatedComponents;
idList<idBounds> bounds;
idList<jointAnimInfo_t> jointInfo;
idList<idJointQuat> baseFrame;
idList<float> componentFrames;
idStr name;
idVec3 totaldelta;
mutable int ref_count;
public:
idMD5Anim();
~idMD5Anim();
void Free( void );
bool Reload( void );
size_t Allocated( void ) const;
size_t Size( void ) const { return sizeof( *this ) + Allocated(); };
bool LoadAnim( const char *filename );
void IncreaseRefs( void ) const;
void DecreaseRefs( void ) const;
int NumRefs( void ) 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( void ) const;
int NumFrames( void ) const;
int NumJoints( void ) const;
const idVec3 &TotalMovementDelta( void ) const;
const char *Name( void ) 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> frameLookup;
idList<frameCommand_t> 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( void ) const;
const char *FullName( void ) const;
const idMD5Anim *MD5Anim( int num ) const;
const idDeclModelDef *ModelDef( void ) const;
int Length( void ) const;
int NumFrames( void ) const;
int NumAnims( void ) const;
const idVec3 &TotalMovementDelta( void ) 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( void ) 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( void ) const;
};
/*
==============================================================================================
idDeclModelDef
==============================================================================================
*/
class idDeclModelDef : public idDecl {
public:
idDeclModelDef();
~idDeclModelDef();
virtual size_t Size( void ) const;
virtual const char * DefaultDefinition( void ) const;
virtual bool Parse( const char *text, const int textLength );
virtual void FreeData( void );
void Touch( void ) const;
const idDeclSkin * GetDefaultSkin( void ) const;
const idJointQuat * GetDefaultPose( void ) const;
void SetupJoints( int *numJoints, idJointMat **jointList, idBounds &frameBounds, bool removeOriginOffset ) const;
idRenderModel * ModelHandle( void ) const;
void GetJointList( const char *jointnames, idList<jointHandle_t> &jointList ) const;
const jointInfo_t * FindJoint( const char *name ) const;
int NumAnims( void ) 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( void ) const;
const char * GetModelName( void ) const;
const idList<jointInfo_t> & Joints( void ) const;
const int * JointParents( void ) const;
int NumJoints( void ) 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( void ) const;
private:
void CopyDecl( const idDeclModelDef *decl );
bool ParseAnim( idLexer &src, int numDefaultAnims );
private:
idVec3 offset;
idList<jointInfo_t> joints;
idList<int> jointParents;
idList<int> channelJoints[ ANIM_NumAnimChannels ];
idRenderModel * modelHandle;
idList<idAnim *> 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( void ) const;
const char *AnimFullName( void ) const;
float GetWeight( int currenttime ) const;
float GetFinalWeight( void ) const;
void SetWeight( float newweight, int currenttime, int blendtime );
int NumSyncedAnims( void ) 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( void ) const;
void SetCycleCount( int count );
void SetPlaybackRate( int currentTime, float newRate );
float GetPlaybackRate( void ) const;
void SetStartTime( int startTime );
int GetStartTime( void ) const;
int GetEndTime( void ) const;
int GetFrameNumber( int currenttime ) const;
int AnimTime( int currenttime ) const;
int NumFrames( void ) const;
int Length( void ) const;
int PlayLength( void ) const;
void AllowMovement( bool allow );
void AllowFrameCommands( bool allow );
const idAnim *Anim( void ) const;
int AnimNum( void ) const;
};
/*
==============================================================================================
idAFPoseJointMod
==============================================================================================
*/
typedef enum {
AF_JOINTMOD_AXIS,
AF_JOINTMOD_ORIGIN,
AF_JOINTMOD_BOTH
} AFJointModType_t;
class idAFPoseJointMod {
public:
idAFPoseJointMod( void );
AFJointModType_t mod;
idMat3 axis;
idVec3 origin;
};
ID_INLINE idAFPoseJointMod::idAFPoseJointMod( void ) {
mod = AF_JOINTMOD_AXIS;
axis.Identity();
origin.Zero();
}
/*
==============================================================================================
idAnimator
==============================================================================================
*/
class idAnimator {
public:
idAnimator();
~idAnimator();
size_t Allocated( void ) const;
size_t Size( void ) 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( void ) const ;
void RemoveOriginOffset( bool remove );
bool RemoveOrigin( void ) const;
void GetJointList( const char *jointnames, idList<jointHandle_t> &jointList ) const;
int NumAnims( void ) 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( void ) const;
jointHandle_t GetFirstChild( jointHandle_t jointnum ) const;
jointHandle_t GetFirstChild( const char *name ) const;
idRenderModel *SetModel( const char *modelname );
idRenderModel *ModelHandle( void ) const;
const idDeclModelDef *ModelDef( void ) const;
void ForceUpdate( void );
void ClearForceUpdate( void );
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 );
void InitAFPose( void );
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 );
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 );
void PushAnims( int channel, int currentTime, int blendTime );
private:
const idDeclModelDef * modelDef;
idEntity * entity;
idAnimBlend channels[ ANIM_NumAnimChannels ][ ANIM_MaxAnimsPerChannel ];
idList<jointMod_t *> 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> AFPoseJoints;
idList<idAFPoseJointMod> AFPoseJointMods;
idList<idJointQuat> AFPoseJointFrame;
idBounds AFPoseBounds;
int AFPoseTime;
};
/*
==============================================================================================
idAnimManager
==============================================================================================
*/
class idAnimManager {
public:
idAnimManager();
~idAnimManager();
static bool forceExport;
void Shutdown( void );
idMD5Anim * GetAnim( const char *name );
void ReloadAnims( void );
void ListAnims( void ) const;
int JointIndex( const char *name );
const char * JointName( int index ) const;
void ClearAnimsInUse( void );
void FlushUnusedAnims( void );
private:
idHashTable<idMD5Anim *> animations;
idStrList jointnames;
idHashIndex jointnamesHash;
};
#endif /* !__ANIM_H__ */

5022
neo/game/anim/Anim_Blend.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,562 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 "../../MayaImport/maya_main.h"
/***********************************************************************
Maya conversion functions
***********************************************************************/
static idStr Maya_Error;
static exporterInterface_t Maya_ConvertModel = NULL;
static exporterShutdown_t Maya_Shutdown = NULL;
static int importDLL = 0;
bool idModelExport::initialized = false;
/*
====================
idModelExport::idModelExport
====================
*/
idModelExport::idModelExport() {
Reset();
}
/*
====================
idModelExport::Shutdown
====================
*/
void idModelExport::Shutdown( void ) {
if ( Maya_Shutdown ) {
Maya_Shutdown();
}
if ( importDLL ) {
sys->DLL_Unload( importDLL );
}
importDLL = 0;
Maya_Shutdown = NULL;
Maya_ConvertModel = NULL;
Maya_Error.Clear();
initialized = false;
}
/*
=====================
idModelExport::CheckMayaInstall
Determines if Maya is installed on the user's machine
=====================
*/
bool idModelExport::CheckMayaInstall( void ) {
#ifndef _WIN32
return false;
#elif 0
HKEY hKey;
long lres, lType;
lres = RegOpenKey( HKEY_LOCAL_MACHINE, "SOFTWARE\\Alias|Wavefront\\Maya\\4.5\\Setup\\InstallPath", &hKey );
if ( lres != ERROR_SUCCESS ) {
return false;
}
lres = RegQueryValueEx( hKey, "MAYA_INSTALL_LOCATION", NULL, (unsigned long*)&lType, (unsigned char*)NULL, (unsigned long*)NULL );
RegCloseKey( hKey );
if ( lres != ERROR_SUCCESS ) {
return false;
}
return true;
#else
HKEY hKey;
long lres;
// only check the non-version specific key so that we only have to update the maya dll when new versions are released
lres = RegOpenKey( HKEY_LOCAL_MACHINE, "SOFTWARE\\Alias|Wavefront\\Maya", &hKey );
RegCloseKey( hKey );
if ( lres != ERROR_SUCCESS ) {
return false;
}
return true;
#endif
}
/*
=====================
idModelExport::LoadMayaDll
Checks to see if we can load the Maya export dll
=====================
*/
void idModelExport::LoadMayaDll( void ) {
exporterDLLEntry_t dllEntry;
char dllPath[ MAX_OSPATH ];
fileSystem->FindDLL( "MayaImport", dllPath, false );
if ( !dllPath[ 0 ] ) {
return;
}
importDLL = sys->DLL_Load( dllPath );
if ( !importDLL ) {
return;
}
// look up the dll interface functions
dllEntry = ( exporterDLLEntry_t )sys->DLL_GetProcAddress( importDLL, "dllEntry" );
Maya_ConvertModel = ( exporterInterface_t )sys->DLL_GetProcAddress( importDLL, "Maya_ConvertModel" );
Maya_Shutdown = ( exporterShutdown_t )sys->DLL_GetProcAddress( importDLL, "Maya_Shutdown" );
if ( !Maya_ConvertModel || !dllEntry || !Maya_Shutdown ) {
Maya_ConvertModel = NULL;
Maya_Shutdown = NULL;
sys->DLL_Unload( importDLL );
importDLL = 0;
gameLocal.Error( "Invalid interface on export DLL." );
return;
}
// initialize the DLL
if ( !dllEntry( MD5_VERSION, common, sys ) ) {
// init failed
Maya_ConvertModel = NULL;
Maya_Shutdown = NULL;
sys->DLL_Unload( importDLL );
importDLL = 0;
gameLocal.Error( "Export DLL init failed." );
return;
}
}
/*
=====================
idModelExport::ConvertMayaToMD5
Checks if a Maya model should be converted to an MD5, and converts if if the time/date or
version number has changed.
=====================
*/
bool idModelExport::ConvertMayaToMD5( void ) {
ID_TIME_T
sourceTime;
ID_TIME_T destTime;
int version;
idToken cmdLine;
idStr path;
// check if our DLL got loaded
if ( initialized && !Maya_ConvertModel ) {
Maya_Error = "MayaImport dll not loaded.";
return false;
}
// if idAnimManager::forceExport is set then we always reexport Maya models
if ( idAnimManager::forceExport ) {
force = true;
}
// get the source file's time
if ( fileSystem->ReadFile( src, NULL, &sourceTime ) < 0 ) {
// source file doesn't exist
return true;
}
// get the destination file's time
if ( !force && ( fileSystem->ReadFile( dest, NULL, &destTime ) >= 0 ) ) {
idParser parser( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS );
parser.LoadFile( dest );
// read the file version
if ( parser.CheckTokenString( MD5_VERSION_STRING ) ) {
version = parser.ParseInt();
// check the command line
if ( parser.CheckTokenString( "commandline" ) ) {
parser.ReadToken( &cmdLine );
// check the file time, scale, and version
if ( ( destTime >= sourceTime ) && ( version == MD5_VERSION ) && ( cmdLine == commandLine ) ) {
// don't convert it
return true;
}
}
}
}
// if this is the first time we've been run, check if Maya is installed and load our DLL
if ( !initialized ) {
initialized = true;
if ( !CheckMayaInstall() ) {
Maya_Error = "Maya not installed in registry.";
return false;
}
LoadMayaDll();
// check if our DLL got loaded
if ( !Maya_ConvertModel ) {
Maya_Error = "Could not load MayaImport dll.";
return false;
}
}
// we need to make sure we have a full path, so convert the filename to an OS path
src = fileSystem->RelativePathToOSPath( src );
dest = fileSystem->RelativePathToOSPath( dest );
dest.ExtractFilePath( path );
if ( path.Length() ) {
fileSystem->CreateOSPath( path );
}
// get the os path in case it needs to create one
path = fileSystem->RelativePathToOSPath( "" );
common->SetRefreshOnPrint( true );
Maya_Error = Maya_ConvertModel( path, commandLine );
common->SetRefreshOnPrint( false );
if ( Maya_Error != "Ok" ) {
return false;
}
// conversion succeded
return true;
}
/*
====================
idModelExport::Reset
====================
*/
void idModelExport::Reset( void ) {
force = false;
commandLine = "";
src = "";
dest = "";
}
/*
====================
idModelExport::ExportModel
====================
*/
bool idModelExport::ExportModel( const char *model ) {
const char *game = cvarSystem->GetCVarString( "fs_game" );
if ( strlen(game) == 0 ) {
game = BASE_GAMEDIR;
}
Reset();
src = model;
dest = model;
dest.SetFileExtension( MD5_MESH_EXT );
sprintf( commandLine, "mesh %s -dest %s -game %s", src.c_str(), dest.c_str(), game );
if ( !ConvertMayaToMD5() ) {
gameLocal.Printf( "Failed to export '%s' : %s", src.c_str(), Maya_Error.c_str() );
return false;
}
return true;
}
/*
====================
idModelExport::ExportAnim
====================
*/
bool idModelExport::ExportAnim( const char *anim ) {
const char *game = cvarSystem->GetCVarString( "fs_game" );
if ( strlen(game) == 0 ) {
game = BASE_GAMEDIR;
}
Reset();
src = anim;
dest = anim;
dest.SetFileExtension( MD5_ANIM_EXT );
sprintf( commandLine, "anim %s -dest %s -game %s", src.c_str(), dest.c_str(), game );
if ( !ConvertMayaToMD5() ) {
gameLocal.Printf( "Failed to export '%s' : %s", src.c_str(), Maya_Error.c_str() );
return false;
}
return true;
}
/*
====================
idModelExport::ParseOptions
====================
*/
bool idModelExport::ParseOptions( idLexer &lex ) {
idToken token;
idStr destdir;
idStr sourcedir;
if ( !lex.ReadToken( &token ) ) {
lex.Error( "Expected filename" );
return false;
}
src = token;
dest = token;
while( lex.ReadToken( &token ) ) {
if ( token == "-" ) {
if ( !lex.ReadToken( &token ) ) {
lex.Error( "Expecting option" );
return false;
}
if ( token == "sourcedir" ) {
if ( !lex.ReadToken( &token ) ) {
lex.Error( "Missing pathname after -sourcedir" );
return false;
}
sourcedir = token;
} else if ( token == "destdir" ) {
if ( !lex.ReadToken( &token ) ) {
lex.Error( "Missing pathname after -destdir" );
return false;
}
destdir = token;
} else if ( token == "dest" ) {
if ( !lex.ReadToken( &token ) ) {
lex.Error( "Missing filename after -dest" );
return false;
}
dest = token;
} else {
commandLine += va( " -%s", token.c_str() );
}
} else {
commandLine += va( " %s", token.c_str() );
}
}
if ( sourcedir.Length() ) {
src.StripPath();
sourcedir.BackSlashesToSlashes();
sprintf( src, "%s/%s", sourcedir.c_str(), src.c_str() );
}
if ( destdir.Length() ) {
dest.StripPath();
destdir.BackSlashesToSlashes();
sprintf( dest, "%s/%s", destdir.c_str(), dest.c_str() );
}
return true;
}
/*
====================
idModelExport::ParseExportSection
====================
*/
int idModelExport::ParseExportSection( idParser &parser ) {
idToken command;
idToken token;
idStr defaultCommands;
idLexer lex;
idStr temp;
idStr parms;
int count;
// only export sections that match our export mask
if ( g_exportMask.GetString()[ 0 ] ) {
if ( parser.CheckTokenString( "{" ) ) {
parser.SkipBracedSection( false );
return 0;
}
parser.ReadToken( &token );
if ( token.Icmp( g_exportMask.GetString() ) ) {
parser.SkipBracedSection();
return 0;
}
parser.ExpectTokenString( "{" );
} else if ( !parser.CheckTokenString( "{" ) ) {
// skip the export mask
parser.ReadToken( &token );
parser.ExpectTokenString( "{" );
}
count = 0;
lex.SetFlags( LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWPATHNAMES | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT );
while( 1 ) {
if ( !parser.ReadToken( &command ) ) {
parser.Error( "Unexpoected end-of-file" );
break;
}
if ( command == "}" ) {
break;
}
if ( command == "options" ) {
parser.ParseRestOfLine( defaultCommands );
} else if ( command == "addoptions" ) {
parser.ParseRestOfLine( temp );
defaultCommands += " ";
defaultCommands += temp;
} else if ( ( command == "mesh" ) || ( command == "anim" ) || ( command == "camera" ) ) {
if ( !parser.ReadToken( &token ) ) {
parser.Error( "Expected filename" );
}
temp = token;
parser.ParseRestOfLine( parms );
if ( defaultCommands.Length() ) {
sprintf( temp, "%s %s", temp.c_str(), defaultCommands.c_str() );
}
if ( parms.Length() ) {
sprintf( temp, "%s %s", temp.c_str(), parms.c_str() );
}
lex.LoadMemory( temp, temp.Length(), parser.GetFileName() );
Reset();
if ( ParseOptions( lex ) ) {
const char *game = cvarSystem->GetCVarString( "fs_game" );
if ( strlen(game) == 0 ) {
game = BASE_GAMEDIR;
}
if ( command == "mesh" ) {
dest.SetFileExtension( MD5_MESH_EXT );
} else if ( command == "anim" ) {
dest.SetFileExtension( MD5_ANIM_EXT );
} else if ( command == "camera" ) {
dest.SetFileExtension( MD5_CAMERA_EXT );
} else {
dest.SetFileExtension( command );
}
idStr back = commandLine;
sprintf( commandLine, "%s %s -dest %s -game %s%s", command.c_str(), src.c_str(), dest.c_str(), game, commandLine.c_str() );
if ( ConvertMayaToMD5() ) {
count++;
} else {
parser.Warning( "Failed to export '%s' : %s", src.c_str(), Maya_Error.c_str() );
}
}
lex.FreeSource();
} else {
parser.Error( "Unknown token: %s", command.c_str() );
parser.SkipBracedSection( false );
break;
}
}
return count;
}
/*
================
idModelExport::ExportDefFile
================
*/
int idModelExport::ExportDefFile( const char *filename ) {
idParser parser( LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWPATHNAMES | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT );
idToken token;
int count;
count = 0;
if ( !parser.LoadFile( filename ) ) {
gameLocal.Printf( "Could not load '%s'\n", filename );
return 0;
}
while( parser.ReadToken( &token ) ) {
if ( token == "export" ) {
count += ParseExportSection( parser );
} else {
parser.ReadToken( &token );
parser.SkipBracedSection();
}
}
return count;
}
/*
================
idModelExport::ExportModels
================
*/
int idModelExport::ExportModels( const char *pathname, const char *extension ) {
int count;
count = 0;
idFileList *files;
int i;
if ( !CheckMayaInstall() ) {
// if Maya isn't installed, don't bother checking if we have anims to export
return 0;
}
gameLocal.Printf( "--------- Exporting models --------\n" );
if ( !g_exportMask.GetString()[ 0 ] ) {
gameLocal.Printf( " Export mask: '%s'\n", g_exportMask.GetString() );
}
count = 0;
files = fileSystem->ListFiles( pathname, extension );
for( i = 0; i < files->GetNumFiles(); i++ ) {
count += ExportDefFile( va( "%s/%s", pathname, files->GetFile( i ) ) );
}
fileSystem->FreeFileList( files );
gameLocal.Printf( "...%d models exported.\n", count );
gameLocal.Printf( "-----------------------------------\n" );
return count;
}

View File

@@ -0,0 +1,924 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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
=============================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#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( void ) {
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( void ) {
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( void ) const {
return false;
}
/*
================
idTestModel::Think
================
*/
void idTestModel::Think( void ) {
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 && 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;
}
headAnim = 0;
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 );
#if 0
if ( strstr( name, ".ma" ) || strstr( name, ".mb" ) ) {
const idMD5Anim *md5anims[ ANIM_MaxSyncedAnims ];
idModelExport exporter;
exporter.ExportAnim( name );
name.SetFileExtension( MD5_ANIM_EXT );
md5anims[ 0 ] = animationLib.GetAnim( name );
if ( md5anims[ 0 ] ) {
customAnim.SetAnim( animator.ModelDef(), name, name, 1, md5anims );
newanim = &customAnim;
}
} else {
animNum = animator.GetAnim( name );
}
#else
animNum = animator.GetAnim( name );
#endif
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 ( strstr( name, ".ma" ) || strstr( name, ".mb" ) ) {
idModelExport exporter;
exporter.ExportModel( name );
name.SetFileExtension( MD5_MESH_EXT );
}
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 );
}

View File

@@ -0,0 +1,95 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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( void );
virtual bool ShouldConstructScriptObjectAtSpawn( void ) 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 );
void Event_Footstep( void );
};
#endif /* !__ANIM_TESTMODEL_H__*/

File diff suppressed because it is too large Load Diff

1059
neo/game/gamesys/Class.cpp Normal file

File diff suppressed because it is too large Load Diff

357
neo/game/gamesys/Class.h Normal file
View File

@@ -0,0 +1,357 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 )( void );
template< class Type >
struct idEventFunc {
const idEventDef *event;
eventCallback_t function;
};
// added & so gcc could compile this
#define EVENT( event, function ) { &( event ), ( void ( idClass::* )( void ) )( &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( void ); \
virtual idTypeInfo *GetType( void ) 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::* )( void ) )&nameofclass::Spawn, \
( void ( idClass::* )( idSaveGame * ) const )&nameofclass::Save, ( void ( idClass::* )( idRestoreGame * ) )&nameofclass::Restore ); \
idClass *nameofclass::CreateInstance( void ) { \
try { \
nameofclass *ptr = new nameofclass; \
ptr->FindUninitializedMemory(); \
return ptr; \
} \
catch( idAllocError & ) { \
return NULL; \
} \
} \
idTypeInfo *nameofclass::GetType( void ) 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( void ); \
virtual idTypeInfo *GetType( void ) 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::* )( void ) )&nameofclass::Spawn, \
( void ( idClass::* )( idSaveGame * ) const )&nameofclass::Save, ( void ( idClass::* )( idRestoreGame * ) )&nameofclass::Restore ); \
idClass *nameofclass::CreateInstance( void ) { \
gameLocal.Error( "Cannot instanciate abstract class %s.", #nameofclass ); \
return NULL; \
} \
idTypeInfo *nameofclass::GetType( void ) const { \
return &( nameofclass::Type ); \
} \
idEventFunc<nameofclass> nameofclass::eventCallbacks[] = {
typedef void ( idClass::*classSpawnFunc_t )( void );
class idSaveGame;
class idRestoreGame;
class idClass {
public:
ABSTRACT_PROTOTYPE( idClass );
#ifdef ID_REDIRECT_NEWDELETE
#undef new
#endif
void * operator new( size_t );
void * operator new( size_t s, int, int, char *, int );
void operator delete( void * );
void operator delete( void *, int, int, char *, int );
#ifdef ID_REDIRECT_NEWDELETE
#define new ID_DEBUG_NEW
#endif
virtual ~idClass();
void Spawn( void );
void CallSpawn( void );
bool IsType( const idTypeInfo &c ) const;
const char * GetClassname( void ) const;
const char * GetSuperclass( void ) const;
void FindUninitializedMemory( void );
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( void );
// Static functions
static void Init( void );
static void Shutdown( void );
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( void ) { return types.Num(); }
static int GetTypeNumBits( void ) { 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( void );
static bool initialized;
static idList<idTypeInfo *> types;
static idList<idTypeInfo *> typenums;
static int typeNumBits;
static int memused;
static int numobjects;
};
/***********************************************************************
idTypeInfo
***********************************************************************/
class idTypeInfo {
public:
const char * classname;
const char * superclass;
idClass * ( *CreateInstance )( void );
void ( idClass::*Spawn )( void );
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 ), void ( idClass::*Spawn )( void ),
void ( idClass::*Save )( idSaveGame *savefile ) const, void ( idClass::*Restore )( idRestoreGame *savefile ) );
~idTypeInfo();
void Init( void );
void Shutdown( void );
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__ */

View File

@@ -0,0 +1,92 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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"
/*
================
idDebugGraph::idDebugGraph
================
*/
idDebugGraph::idDebugGraph() {
index = 0;
}
/*
================
idDebugGraph::SetNumSamples
================
*/
void idDebugGraph::SetNumSamples( int num ) {
index = 0;
samples.Clear();
samples.SetNum( num );
memset( samples.Ptr(), 0, samples.MemoryUsed() );
}
/*
================
idDebugGraph::AddValue
================
*/
void idDebugGraph::AddValue( float value ) {
samples[ index ] = value;
index++;
if ( index >= samples.Num() ) {
index = 0;
}
}
/*
================
idDebugGraph::Draw
================
*/
void idDebugGraph::Draw( const idVec4 &color, float scale ) const {
int i;
float value1;
float value2;
idVec3 vec1;
idVec3 vec2;
const idMat3 &axis = gameLocal.GetLocalPlayer()->viewAxis;
const idVec3 pos = gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin() + axis[ 1 ] * samples.Num() * 0.5f;
value1 = samples[ index ] * scale;
for( i = 1; i < samples.Num(); i++ ) {
value2 = samples[ ( i + index ) % samples.Num() ] * scale;
vec1 = pos + axis[ 2 ] * value1 - axis[ 1 ] * ( i - 1 ) + axis[ 0 ] * samples.Num();
vec2 = pos + axis[ 2 ] * value2 - axis[ 1 ] * i + axis[ 0 ] * samples.Num();
gameRenderWorld->DebugLine( color, vec1, vec2, gameLocal.msec, false );
value1 = value2;
}
}

View File

@@ -0,0 +1,39 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 idDebugGraph {
public:
idDebugGraph();
void SetNumSamples( int num );
void AddValue( float value );
void Draw( const idVec4 &color, float scale ) const;
private:
idList<float> samples;
int index;
};

872
neo/game/gamesys/Event.cpp Normal file
View File

@@ -0,0 +1,872 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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.cpp
Event are used for scheduling tasks and for linking script commands.
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "../Game_local.h"
#define MAX_EVENTSPERFRAME 4096
//#define CREATE_EVENT_CODE
/***********************************************************************
idEventDef
***********************************************************************/
idEventDef *idEventDef::eventDefList[MAX_EVENTS];
int idEventDef::numEventDefs = 0;
static bool eventError = false;
static char eventErrorMsg[ 128 ];
/*
================
idEventDef::idEventDef
================
*/
idEventDef::idEventDef( const char *command, const char *formatspec, char returnType ) {
idEventDef *ev;
int i;
unsigned int bits;
assert( command );
assert( !idEvent::initialized );
// Allow NULL to indicate no args, but always store it as ""
// so we don't have to check for it.
if ( !formatspec ) {
formatspec = "";
}
this->name = command;
this->formatspec = formatspec;
this->returnType = returnType;
numargs = strlen( formatspec );
assert( numargs <= D_EVENT_MAXARGS );
if ( numargs > D_EVENT_MAXARGS ) {
eventError = true;
sprintf( eventErrorMsg, "idEventDef::idEventDef : Too many args for '%s' event.", name );
return;
}
// make sure the format for the args is valid, calculate the formatspecindex, and the offsets for each arg
bits = 0;
argsize = 0;
memset( argOffset, 0, sizeof( argOffset ) );
for( i = 0; i < numargs; i++ ) {
argOffset[ i ] = argsize;
switch( formatspec[ i ] ) {
case D_EVENT_FLOAT :
bits |= 1 << i;
argsize += sizeof( float );
break;
case D_EVENT_INTEGER :
argsize += sizeof( int );
break;
case D_EVENT_VECTOR :
argsize += sizeof( idVec3 );
break;
case D_EVENT_STRING :
argsize += MAX_STRING_LEN;
break;
case D_EVENT_ENTITY :
argsize += sizeof( idEntityPtr<idEntity> );
break;
case D_EVENT_ENTITY_NULL :
argsize += sizeof( idEntityPtr<idEntity> );
break;
case D_EVENT_TRACE :
argsize += sizeof( trace_t ) + MAX_STRING_LEN + sizeof( bool );
break;
default :
eventError = true;
sprintf( eventErrorMsg, "idEventDef::idEventDef : Invalid arg format '%s' string for '%s' event.", formatspec, name );
return;
break;
}
}
// calculate the formatspecindex
formatspecIndex = ( 1 << ( numargs + D_EVENT_MAXARGS ) ) | bits;
// go through the list of defined events and check for duplicates
// and mismatched format strings
eventnum = numEventDefs;
for( i = 0; i < eventnum; i++ ) {
ev = eventDefList[ i ];
if ( strcmp( command, ev->name ) == 0 ) {
if ( strcmp( formatspec, ev->formatspec ) != 0 ) {
eventError = true;
sprintf( eventErrorMsg, "idEvent '%s' defined twice with same name but differing format strings ('%s'!='%s').",
command, formatspec, ev->formatspec );
return;
}
if ( ev->returnType != returnType ) {
eventError = true;
sprintf( eventErrorMsg, "idEvent '%s' defined twice with same name but differing return types ('%c'!='%c').",
command, returnType, ev->returnType );
return;
}
// Don't bother putting the duplicate event in list.
eventnum = ev->eventnum;
return;
}
}
ev = this;
if ( numEventDefs >= MAX_EVENTS ) {
eventError = true;
sprintf( eventErrorMsg, "numEventDefs >= MAX_EVENTS" );
return;
}
eventDefList[numEventDefs] = ev;
numEventDefs++;
}
/*
================
idEventDef::NumEventCommands
================
*/
int idEventDef::NumEventCommands( void ) {
return numEventDefs;
}
/*
================
idEventDef::GetEventCommand
================
*/
const idEventDef *idEventDef::GetEventCommand( int eventnum ) {
return eventDefList[ eventnum ];
}
/*
================
idEventDef::FindEvent
================
*/
const idEventDef *idEventDef::FindEvent( const char *name ) {
idEventDef *ev;
int num;
int i;
assert( name );
num = numEventDefs;
for( i = 0; i < num; i++ ) {
ev = eventDefList[ i ];
if ( strcmp( name, ev->name ) == 0 ) {
return ev;
}
}
return NULL;
}
/***********************************************************************
idEvent
***********************************************************************/
static idLinkList<idEvent> FreeEvents;
static idLinkList<idEvent> EventQueue;
static idEvent EventPool[ MAX_EVENTS ];
bool idEvent::initialized = false;
idDynamicBlockAlloc<byte, 16 * 1024, 256> idEvent::eventDataAllocator;
/*
================
idEvent::~idEvent()
================
*/
idEvent::~idEvent() {
Free();
}
/*
================
idEvent::Alloc
================
*/
idEvent *idEvent::Alloc( const idEventDef *evdef, int numargs, va_list args ) {
idEvent *ev;
size_t size;
const char *format;
idEventArg *arg;
byte *dataPtr;
int i;
const char *materialName;
if ( FreeEvents.IsListEmpty() ) {
gameLocal.Error( "idEvent::Alloc : No more free events" );
}
ev = FreeEvents.Next();
ev->eventNode.Remove();
ev->eventdef = evdef;
if ( numargs != evdef->GetNumArgs() ) {
gameLocal.Error( "idEvent::Alloc : Wrong number of args for '%s' event.", evdef->GetName() );
}
size = evdef->GetArgSize();
if ( size ) {
ev->data = eventDataAllocator.Alloc( size );
memset( ev->data, 0, size );
} else {
ev->data = NULL;
}
format = evdef->GetArgFormat();
for( i = 0; i < numargs; i++ ) {
arg = va_arg( args, idEventArg * );
if ( format[ i ] != arg->type ) {
// when NULL is passed in for an entity, it gets cast as an integer 0, so don't give an error when it happens
if ( !( ( ( format[ i ] == D_EVENT_TRACE ) || ( format[ i ] == D_EVENT_ENTITY ) ) && ( arg->type == 'd' ) && ( arg->value == 0 ) ) ) {
gameLocal.Error( "idEvent::Alloc : Wrong type passed in for arg # %d on '%s' event.", i, evdef->GetName() );
}
}
dataPtr = &ev->data[ evdef->GetArgOffset( i ) ];
switch( format[ i ] ) {
case D_EVENT_FLOAT :
case D_EVENT_INTEGER :
*reinterpret_cast<int *>( dataPtr ) = arg->value;
break;
case D_EVENT_VECTOR :
if ( arg->value ) {
*reinterpret_cast<idVec3 *>( dataPtr ) = *reinterpret_cast<const idVec3 *>( arg->value );
}
break;
case D_EVENT_STRING :
if ( arg->value ) {
idStr::Copynz( reinterpret_cast<char *>( dataPtr ), reinterpret_cast<const char *>( arg->value ), MAX_STRING_LEN );
}
break;
case D_EVENT_ENTITY :
case D_EVENT_ENTITY_NULL :
*reinterpret_cast< idEntityPtr<idEntity> * >( dataPtr ) = reinterpret_cast<idEntity *>( arg->value );
break;
case D_EVENT_TRACE :
if ( arg->value ) {
*reinterpret_cast<bool *>( dataPtr ) = true;
*reinterpret_cast<trace_t *>( dataPtr + sizeof( bool ) ) = *reinterpret_cast<const trace_t *>( arg->value );
// save off the material as a string since the pointer won't be valid in save games.
// since we save off the entire trace_t structure, if the material is NULL here,
// it will be NULL when we process it, so we don't need to save off anything in that case.
if ( reinterpret_cast<const trace_t *>( arg->value )->c.material ) {
materialName = reinterpret_cast<const trace_t *>( arg->value )->c.material->GetName();
idStr::Copynz( reinterpret_cast<char *>( dataPtr + sizeof( bool ) + sizeof( trace_t ) ), materialName, MAX_STRING_LEN );
}
} else {
*reinterpret_cast<bool *>( dataPtr ) = false;
}
break;
default :
gameLocal.Error( "idEvent::Alloc : Invalid arg format '%s' string for '%s' event.", format, evdef->GetName() );
break;
}
}
return ev;
}
/*
================
idEvent::CopyArgs
================
*/
void idEvent::CopyArgs( const idEventDef *evdef, int numargs, va_list args, int data[ D_EVENT_MAXARGS ] ) {
int i;
const char *format;
idEventArg *arg;
format = evdef->GetArgFormat();
if ( numargs != evdef->GetNumArgs() ) {
gameLocal.Error( "idEvent::CopyArgs : Wrong number of args for '%s' event.", evdef->GetName() );
}
for( i = 0; i < numargs; i++ ) {
arg = va_arg( args, idEventArg * );
if ( format[ i ] != arg->type ) {
// when NULL is passed in for an entity, it gets cast as an integer 0, so don't give an error when it happens
if ( !( ( ( format[ i ] == D_EVENT_TRACE ) || ( format[ i ] == D_EVENT_ENTITY ) ) && ( arg->type == 'd' ) && ( arg->value == 0 ) ) ) {
gameLocal.Error( "idEvent::CopyArgs : Wrong type passed in for arg # %d on '%s' event.", i, evdef->GetName() );
}
}
data[ i ] = arg->value;
}
}
/*
================
idEvent::Free
================
*/
void idEvent::Free( void ) {
if ( data ) {
eventDataAllocator.Free( data );
data = NULL;
}
eventdef = NULL;
time = 0;
object = NULL;
typeinfo = NULL;
eventNode.SetOwner( this );
eventNode.AddToEnd( FreeEvents );
}
/*
================
idEvent::Schedule
================
*/
void idEvent::Schedule( idClass *obj, const idTypeInfo *type, int time ) {
idEvent *event;
assert( initialized );
if ( !initialized ) {
return;
}
object = obj;
typeinfo = type;
// wraps after 24 days...like I care. ;)
this->time = gameLocal.time + time;
eventNode.Remove();
event = EventQueue.Next();
while( ( event != NULL ) && ( this->time >= event->time ) ) {
event = event->eventNode.Next();
}
if ( event ) {
eventNode.InsertBefore( event->eventNode );
} else {
eventNode.AddToEnd( EventQueue );
}
}
/*
================
idEvent::CancelEvents
================
*/
void idEvent::CancelEvents( const idClass *obj, const idEventDef *evdef ) {
idEvent *event;
idEvent *next;
if ( !initialized ) {
return;
}
for( event = EventQueue.Next(); event != NULL; event = next ) {
next = event->eventNode.Next();
if ( event->object == obj ) {
if ( !evdef || ( evdef == event->eventdef ) ) {
event->Free();
}
}
}
}
/*
================
idEvent::ClearEventList
================
*/
void idEvent::ClearEventList( void ) {
int i;
//
// initialize lists
//
FreeEvents.Clear();
EventQueue.Clear();
//
// add the events to the free list
//
for( i = 0; i < MAX_EVENTS; i++ ) {
EventPool[ i ].Free();
}
}
/*
================
idEvent::ServiceEvents
================
*/
void idEvent::ServiceEvents( void ) {
idEvent *event;
int num;
int args[ D_EVENT_MAXARGS ];
int offset;
int i;
int numargs;
const char *formatspec;
trace_t **tracePtr;
const idEventDef *ev;
byte *data;
const char *materialName;
num = 0;
while( !EventQueue.IsListEmpty() ) {
event = EventQueue.Next();
assert( event );
if ( event->time > gameLocal.time ) {
break;
}
// copy the data into the local args array and set up pointers
ev = event->eventdef;
formatspec = ev->GetArgFormat();
numargs = ev->GetNumArgs();
for( i = 0; i < numargs; i++ ) {
offset = ev->GetArgOffset( i );
data = event->data;
switch( formatspec[ i ] ) {
case D_EVENT_FLOAT :
case D_EVENT_INTEGER :
args[ i ] = *reinterpret_cast<int *>( &data[ offset ] );
break;
case D_EVENT_VECTOR :
*reinterpret_cast<idVec3 **>( &args[ i ] ) = reinterpret_cast<idVec3 *>( &data[ offset ] );
break;
case D_EVENT_STRING :
*reinterpret_cast<const char **>( &args[ i ] ) = reinterpret_cast<const char *>( &data[ offset ] );
break;
case D_EVENT_ENTITY :
case D_EVENT_ENTITY_NULL :
*reinterpret_cast<idEntity **>( &args[ i ] ) = reinterpret_cast< idEntityPtr<idEntity> * >( &data[ offset ] )->GetEntity();
break;
case D_EVENT_TRACE :
tracePtr = reinterpret_cast<trace_t **>( &args[ i ] );
if ( *reinterpret_cast<bool *>( &data[ offset ] ) ) {
*tracePtr = reinterpret_cast<trace_t *>( &data[ offset + sizeof( bool ) ] );
if ( ( *tracePtr )->c.material != NULL ) {
// look up the material name to get the material pointer
materialName = reinterpret_cast<const char *>( &data[ offset + sizeof( bool ) + sizeof( trace_t ) ] );
( *tracePtr )->c.material = declManager->FindMaterial( materialName, true );
}
} else {
*tracePtr = NULL;
}
break;
default:
gameLocal.Error( "idEvent::ServiceEvents : Invalid arg format '%s' string for '%s' event.", formatspec, ev->GetName() );
}
}
// the event is removed from its list so that if then object
// is deleted, the event won't be freed twice
event->eventNode.Remove();
assert( event->object );
event->object->ProcessEventArgPtr( ev, args );
#if 0
// event functions may never leave return values on the FPU stack
// enable this code to check if any event call left values on the FPU stack
if ( !sys->FPU_StackIsEmpty() ) {
gameLocal.Error( "idEvent::ServiceEvents %d: %s left a value on the FPU stack\n", num, ev->GetName() );
}
#endif
// return the event to the free list
event->Free();
// Don't allow ourselves to stay in here too long. An abnormally high number
// of events being processed is evidence of an infinite loop of events.
num++;
if ( num > MAX_EVENTSPERFRAME ) {
gameLocal.Error( "Event overflow. Possible infinite loop in script." );
}
}
}
/*
================
idEvent::Init
================
*/
void idEvent::Init( void ) {
gameLocal.Printf( "Initializing event system\n" );
if ( eventError ) {
gameLocal.Error( "%s", eventErrorMsg );
}
#ifdef CREATE_EVENT_CODE
void CreateEventCallbackHandler();
CreateEventCallbackHandler();
gameLocal.Error( "Wrote event callback handler" );
#endif
if ( initialized ) {
gameLocal.Printf( "...already initialized\n" );
ClearEventList();
return;
}
ClearEventList();
eventDataAllocator.Init();
gameLocal.Printf( "...%i event definitions\n", idEventDef::NumEventCommands() );
// the event system has started
initialized = true;
}
/*
================
idEvent::Shutdown
================
*/
void idEvent::Shutdown( void ) {
gameLocal.Printf( "Shutdown event system\n" );
if ( !initialized ) {
gameLocal.Printf( "...not started\n" );
return;
}
ClearEventList();
eventDataAllocator.Shutdown();
// say it is now shutdown
initialized = false;
}
/*
================
idEvent::Save
================
*/
void idEvent::Save( idSaveGame *savefile ) {
char *str;
int i, size;
idEvent *event;
byte *dataPtr;
bool validTrace;
const char *format;
savefile->WriteInt( EventQueue.Num() );
event = EventQueue.Next();
while( event != NULL ) {
savefile->WriteInt( event->time );
savefile->WriteString( event->eventdef->GetName() );
savefile->WriteString( event->typeinfo->classname );
savefile->WriteObject( event->object );
savefile->WriteInt( event->eventdef->GetArgSize() );
format = event->eventdef->GetArgFormat();
for ( i = 0, size = 0; i < event->eventdef->GetNumArgs(); ++i) {
dataPtr = &event->data[ event->eventdef->GetArgOffset( i ) ];
switch( format[ i ] ) {
case D_EVENT_FLOAT :
savefile->WriteFloat( *reinterpret_cast<float *>( dataPtr ) );
size += sizeof( float );
break;
case D_EVENT_INTEGER :
case D_EVENT_ENTITY :
case D_EVENT_ENTITY_NULL :
savefile->WriteInt( *reinterpret_cast<int *>( dataPtr ) );
size += sizeof( int );
break;
case D_EVENT_VECTOR :
savefile->WriteVec3( *reinterpret_cast<idVec3 *>( dataPtr ) );
size += sizeof( idVec3 );
break;
case D_EVENT_TRACE :
validTrace = *reinterpret_cast<bool *>( dataPtr );
savefile->WriteBool( validTrace );
size += sizeof( bool );
if ( validTrace ) {
size += sizeof( trace_t );
const trace_t &t = *reinterpret_cast<trace_t *>( dataPtr + sizeof( bool ) );
SaveTrace( savefile, t );
if ( t.c.material ) {
size += MAX_STRING_LEN;
str = reinterpret_cast<char *>( dataPtr + sizeof( bool ) + sizeof( trace_t ) );
savefile->Write( str, MAX_STRING_LEN );
}
}
break;
default:
break;
}
}
assert( size == event->eventdef->GetArgSize() );
event = event->eventNode.Next();
}
}
/*
================
idEvent::Restore
================
*/
void idEvent::Restore( idRestoreGame *savefile ) {
char *str;
int num, argsize, i, j, size;
idStr name;
byte *dataPtr;
idEvent *event;
const char *format;
savefile->ReadInt( num );
for ( i = 0; i < num; i++ ) {
if ( FreeEvents.IsListEmpty() ) {
gameLocal.Error( "idEvent::Restore : No more free events" );
}
event = FreeEvents.Next();
event->eventNode.Remove();
event->eventNode.AddToEnd( EventQueue );
savefile->ReadInt( event->time );
// read the event name
savefile->ReadString( name );
event->eventdef = idEventDef::FindEvent( name );
if ( !event->eventdef ) {
savefile->Error( "idEvent::Restore: unknown event '%s'", name.c_str() );
}
// read the classtype
savefile->ReadString( name );
event->typeinfo = idClass::GetClass( name );
if ( !event->typeinfo ) {
savefile->Error( "idEvent::Restore: unknown class '%s' on event '%s'", name.c_str(), event->eventdef->GetName() );
}
savefile->ReadObject( event->object );
// read the args
savefile->ReadInt( argsize );
if ( argsize != event->eventdef->GetArgSize() ) {
savefile->Error( "idEvent::Restore: arg size (%d) doesn't match saved arg size(%d) on event '%s'", event->eventdef->GetArgSize(), argsize, event->eventdef->GetName() );
}
if ( argsize ) {
event->data = eventDataAllocator.Alloc( argsize );
format = event->eventdef->GetArgFormat();
assert( format );
for ( j = 0, size = 0; j < event->eventdef->GetNumArgs(); ++j) {
dataPtr = &event->data[ event->eventdef->GetArgOffset( j ) ];
switch( format[ j ] ) {
case D_EVENT_FLOAT :
savefile->ReadFloat( *reinterpret_cast<float *>( dataPtr ) );
size += sizeof( float );
break;
case D_EVENT_INTEGER :
case D_EVENT_ENTITY :
case D_EVENT_ENTITY_NULL :
savefile->ReadInt( *reinterpret_cast<int *>( dataPtr ) );
size += sizeof( int );
break;
case D_EVENT_VECTOR :
savefile->ReadVec3( *reinterpret_cast<idVec3 *>( dataPtr ) );
size += sizeof( idVec3 );
break;
case D_EVENT_TRACE :
savefile->ReadBool( *reinterpret_cast<bool *>( dataPtr ) );
size += sizeof( bool );
if ( *reinterpret_cast<bool *>( dataPtr ) ) {
size += sizeof( trace_t );
trace_t &t = *reinterpret_cast<trace_t *>( dataPtr + sizeof( bool ) );
RestoreTrace( savefile, t) ;
if ( t.c.material ) {
size += MAX_STRING_LEN;
str = reinterpret_cast<char *>( dataPtr + sizeof( bool ) + sizeof( trace_t ) );
savefile->Read( str, MAX_STRING_LEN );
}
}
break;
default:
break;
}
}
assert( size == event->eventdef->GetArgSize() );
} else {
event->data = NULL;
}
}
}
/*
================
idEvent::ReadTrace
idRestoreGame has a ReadTrace procedure, but unfortunately idEvent wants the material
string name at the of the data structure rather than in the middle
================
*/
void idEvent::RestoreTrace( idRestoreGame *savefile, trace_t &trace ) {
savefile->ReadFloat( trace.fraction );
savefile->ReadVec3( trace.endpos );
savefile->ReadMat3( trace.endAxis );
savefile->ReadInt( (int&)trace.c.type );
savefile->ReadVec3( trace.c.point );
savefile->ReadVec3( trace.c.normal );
savefile->ReadFloat( trace.c.dist );
savefile->ReadInt( trace.c.contents );
savefile->ReadInt( (int&)trace.c.material );
savefile->ReadInt( trace.c.contents );
savefile->ReadInt( trace.c.modelFeature );
savefile->ReadInt( trace.c.trmFeature );
savefile->ReadInt( trace.c.id );
}
/*
================
idEvent::WriteTrace
idSaveGame has a WriteTrace procedure, but unfortunately idEvent wants the material
string name at the of the data structure rather than in the middle
================
*/
void idEvent::SaveTrace( idSaveGame *savefile, const trace_t &trace ) {
savefile->WriteFloat( trace.fraction );
savefile->WriteVec3( trace.endpos );
savefile->WriteMat3( trace.endAxis );
savefile->WriteInt( trace.c.type );
savefile->WriteVec3( trace.c.point );
savefile->WriteVec3( trace.c.normal );
savefile->WriteFloat( trace.c.dist );
savefile->WriteInt( trace.c.contents );
savefile->WriteInt( (int&)trace.c.material );
savefile->WriteInt( trace.c.contents );
savefile->WriteInt( trace.c.modelFeature );
savefile->WriteInt( trace.c.trmFeature );
savefile->WriteInt( trace.c.id );
}
#ifdef CREATE_EVENT_CODE
/*
================
CreateEventCallbackHandler
================
*/
void CreateEventCallbackHandler( void ) {
int num;
int count;
int i, j, k;
char argString[ D_EVENT_MAXARGS + 1 ];
idStr string1;
idStr string2;
idFile *file;
file = fileSystem->OpenFileWrite( "Callbacks.cpp" );
file->Printf( "// generated file - see CREATE_EVENT_CODE\n\n" );
for( i = 1; i <= D_EVENT_MAXARGS; i++ ) {
file->Printf( "\t/*******************************************************\n\n\t\t%d args\n\n\t*******************************************************/\n\n", i );
for ( j = 0; j < ( 1 << i ); j++ ) {
for ( k = 0; k < i; k++ ) {
argString[ k ] = j & ( 1 << k ) ? 'f' : 'i';
}
argString[ i ] = '\0';
string1.Empty();
string2.Empty();
for( k = 0; k < i; k++ ) {
if ( j & ( 1 << k ) ) {
string1 += "const float";
string2 += va( "*( float * )&data[ %d ]", k );
} else {
string1 += "const int";
string2 += va( "data[ %d ]", k );
}
if ( k < i - 1 ) {
string1 += ", ";
string2 += ", ";
}
}
file->Printf( "\tcase %d :\n\t\ttypedef void ( idClass::*eventCallback_%s_t )( %s );\n", ( 1 << ( i + D_EVENT_MAXARGS ) ) + j, argString, string1.c_str() );
file->Printf( "\t\t( this->*( eventCallback_%s_t )callback )( %s );\n\t\tbreak;\n\n", argString, string2.c_str() );
}
}
fileSystem->CloseFile( file );
}
#endif

209
neo/game/gamesys/Event.h Normal file
View File

@@ -0,0 +1,209 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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( void ) const;
const char *GetArgFormat( void ) const;
unsigned int GetFormatspecIndex( void ) const;
char GetReturnType( void ) const;
int GetEventNum( void ) const;
int GetNumArgs( void ) const;
size_t GetArgSize( void ) const;
int GetArgOffset( int arg ) const;
static int NumEventCommands( void );
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 );
void Schedule( idClass *object, const idTypeInfo *cls, int time );
byte *GetData( void );
static void CancelEvents( const idClass *obj, const idEventDef *evdef = NULL );
static void ClearEventList( void );
static void ServiceEvents( void );
static void Init( void );
static void Shutdown( void );
// 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( void ) {
return data;
}
/*
================
idEventDef::GetName
================
*/
ID_INLINE const char *idEventDef::GetName( void ) const {
return name;
}
/*
================
idEventDef::GetArgFormat
================
*/
ID_INLINE const char *idEventDef::GetArgFormat( void ) const {
return formatspec;
}
/*
================
idEventDef::GetFormatspecIndex
================
*/
ID_INLINE unsigned int idEventDef::GetFormatspecIndex( void ) const {
return formatspecIndex;
}
/*
================
idEventDef::GetReturnType
================
*/
ID_INLINE char idEventDef::GetReturnType( void ) const {
return returnType;
}
/*
================
idEventDef::GetNumArgs
================
*/
ID_INLINE int idEventDef::GetNumArgs( void ) const {
return numargs;
}
/*
================
idEventDef::GetArgSize
================
*/
ID_INLINE size_t idEventDef::GetArgSize( void ) 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( void ) const {
return eventnum;
}
#endif /* !__SYS_EVENT_H__ */

View File

@@ -0,0 +1,83 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 __GAMETYPEINFO_H__
#define __GAMETYPEINFO_H__
/*
===================================================================================
This file has been generated with the Type Info Generator v1.0 (c) 2004 id Software
===================================================================================
*/
typedef struct {
const char * name;
const char * type;
const char * value;
} constantInfo_t;
typedef struct {
const char * name;
int value;
} enumValueInfo_t;
typedef struct {
const char * typeName;
const enumValueInfo_t * values;
} enumTypeInfo_t;
typedef struct {
const char * type;
const char * name;
int offset;
int size;
} classVariableInfo_t;
typedef struct {
const char * typeName;
const char * superType;
int size;
const classVariableInfo_t * variables;
} classTypeInfo_t;
static constantInfo_t constantInfo[] = {
{ NULL, NULL, NULL }
};
static enumTypeInfo_t enumTypeInfo[] = {
{ NULL, NULL }
};
static classTypeInfo_t classTypeInfo[] = {
{ NULL, NULL, 0, NULL }
};
#endif /* !__GAMETYPEINFO_H__ */

File diff suppressed because it is too large Load Diff

164
neo/game/gamesys/SaveGame.h Normal file
View File

@@ -0,0 +1,164 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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.
*/
const int INITIAL_RELEASE_BUILD_NUMBER = 1262;
class idSaveGame {
public:
idSaveGame( idFile *savefile );
~idSaveGame();
void Close( void );
void AddObject( const idClass *obj );
void WriteObjectList( void );
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 );
void WriteBuildNumber( const int value );
private:
idFile * file;
idList<const idClass *> objects;
void CallSave_r( const idTypeInfo *cls, const idClass *obj );
};
class idRestoreGame {
public:
idRestoreGame( idFile *savefile );
~idRestoreGame();
void CreateObjects( void );
void RestoreObjects( void );
void DeleteObjects( void );
void Error( const char *fmt, ... ) id_attribute((format(printf,2,3)));
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( void );
void ReadBuildNumber( void );
// Used to retrieve the saved game buildNumber from within class Restore methods
int GetBuildNumber( void );
private:
int buildNumber;
idFile * file;
idList<idClass *> objects;
void CallRestore_r( const idTypeInfo *cls, idClass *obj );
};
#endif /* !__SAVEGAME_H__*/

2405
neo/game/gamesys/SysCmds.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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( void );
#endif /* !__SYS_CMDS_H__ */

View File

@@ -0,0 +1,333 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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"
#if defined( _DEBUG )
#define BUILD_DEBUG "-debug"
#else
#define BUILD_DEBUG "-release"
#endif
/*
All game cvars should be defined here.
*/
const char *si_gameTypeArgs[] = { "singleplayer", "deathmatch", "Tourney", "Team DM", "Last Man", NULL };
const char *si_readyArgs[] = { "Not Ready", "Ready", NULL };
const char *si_spectateArgs[] = { "Play", "Spectate", NULL };
const char *ui_skinArgs[] = { "skins/characters/player/marine_mp", "skins/characters/player/marine_mp_red", "skins/characters/player/marine_mp_blue", "skins/characters/player/marine_mp_green", "skins/characters/player/marine_mp_yellow", NULL };
const char *ui_teamArgs[] = { "Red", "Blue", NULL };
struct gameVersion_s {
gameVersion_s( void ) { sprintf( string, "%s.%d%s %s %s", ENGINE_VERSION, BUILD_NUMBER, BUILD_DEBUG, BUILD_STRING, __DATE__, __TIME__ ); }
char string[256];
} gameVersion;
idCVar g_version( "g_version", gameVersion.string, CVAR_GAME | CVAR_ROM, "game version" );
// noset vars
idCVar gamename( "gamename", GAME_VERSION, CVAR_GAME | CVAR_SERVERINFO | CVAR_ROM, "" );
idCVar gamedate( "gamedate", __DATE__, CVAR_GAME | CVAR_ROM, "" );
// server info
idCVar si_name( "si_name", "DOOM Server", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE, "name of the server" );
idCVar si_gameType( "si_gameType", si_gameTypeArgs[ 0 ], CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE, "game type - singleplayer, deathmatch, Tourney, Team DM or Last Man", si_gameTypeArgs, idCmdSystem::ArgCompletion_String<si_gameTypeArgs> );
idCVar si_map( "si_map", "game/mp/d3dm1",CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE, "map to be played next on server", idCmdSystem::ArgCompletion_MapName );
idCVar si_maxPlayers( "si_maxPlayers", "4", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_INTEGER, "max number of players allowed on the server", 1, 4 );
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_warmup( "si_warmup", "0", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_BOOL, "do pre-game warmup" );
idCVar si_usePass( "si_usePass", "0", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_BOOL, "enable client password checking" );
idCVar si_pure( "si_pure", "1", CVAR_GAME | CVAR_SERVERINFO | CVAR_BOOL, "server is pure and does not allow modified data" );
idCVar si_spectators( "si_spectators", "1", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_BOOL, "allow spectators or require all clients to play" );
idCVar si_serverURL( "si_serverURL", "", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE, "where to reach the server admins and get information about the server" );
// user info
idCVar ui_name( "ui_name", "Player", CVAR_GAME | CVAR_USERINFO | CVAR_ARCHIVE, "player name" );
idCVar ui_skin( "ui_skin", ui_skinArgs[ 0 ], CVAR_GAME | CVAR_USERINFO | CVAR_ARCHIVE, "player skin", ui_skinArgs, idCmdSystem::ArgCompletion_String<ui_skinArgs> );
idCVar ui_team( "ui_team", ui_teamArgs[ 0 ], CVAR_GAME | CVAR_USERINFO | CVAR_ARCHIVE, "player team", ui_teamArgs, idCmdSystem::ArgCompletion_String<ui_teamArgs> );
idCVar ui_autoSwitch( "ui_autoSwitch", "1", CVAR_GAME | CVAR_USERINFO | CVAR_ARCHIVE | CVAR_BOOL, "auto switch weapon" );
idCVar ui_autoReload( "ui_autoReload", "1", CVAR_GAME | CVAR_USERINFO | CVAR_ARCHIVE | CVAR_BOOL, "auto reload weapon" );
idCVar ui_showGun( "ui_showGun", "1", CVAR_GAME | CVAR_USERINFO | CVAR_ARCHIVE | CVAR_BOOL, "show gun" );
idCVar ui_ready( "ui_ready", si_readyArgs[ 0 ], CVAR_GAME | CVAR_USERINFO, "player is ready to start playing", idCmdSystem::ArgCompletion_String<si_readyArgs> );
idCVar ui_spectate( "ui_spectate", si_spectateArgs[ 0 ], CVAR_GAME | CVAR_USERINFO, "play or spectate", idCmdSystem::ArgCompletion_String<si_spectateArgs> );
idCVar ui_chat( "ui_chat", "0", CVAR_GAME | CVAR_USERINFO | CVAR_BOOL | CVAR_ROM | CVAR_CHEAT, "player is chatting" );
// change anytime vars
idCVar developer( "developer", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar r_aspectRatio( "r_aspectRatio", "0", CVAR_RENDERER | CVAR_INTEGER | CVAR_ARCHIVE, "aspect ratio of view:\n0 = 4:3\n1 = 16:9\n2 = 16:10", 0, 2 );
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_doubleVision( "g_doubleVision", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "show double vision when taking damage" );
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_gravity( "g_gravity", DEFAULT_GRAVITY_STRING, CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_skipFX( "g_skipFX", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_skipParticles( "g_skipParticles", "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 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 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, "" );
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 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_airTics( "pm_air", "1800", 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", "0", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_gun_y( "g_gunY", "0", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_gun_z( "g_gunZ", "0", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_viewNodalX( "g_viewNodalX", "0", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_viewNodalZ( "g_viewNodalZ", "0", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_fov( "g_fov", "90", 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_exportMask( "g_exportMask", "", CVAR_GAME, "" );
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_password( "g_password", "", CVAR_GAME | CVAR_ARCHIVE, "game password" );
idCVar password( "password", "", CVAR_GAME | CVAR_NOCHEAT, "client password used when connecting" );
idCVar g_countDown( "g_countDown", "10", 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_TDMArrows( "g_TDMArrows", "1", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_BOOL, "draw arrows over teammates in team deathmatch" );
idCVar g_balanceTDM( "g_balanceTDM", "1", CVAR_GAME | CVAR_BOOL, "maintain even teams" );
idCVar net_clientPredictGUI( "net_clientPredictGUI", "1", CVAR_GAME | CVAR_BOOL, "test guis in networking without prediction" );
idCVar g_voteFlags( "g_voteFlags", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_INTEGER | CVAR_ARCHIVE, "vote flags. bit mask of votes not allowed on this server\n"
"bit 0 (+1) restart now\n"
"bit 1 (+2) time limit\n"
"bit 2 (+4) frag limit\n"
"bit 3 (+8) game type\n"
"bit 4 (+16) kick player\n"
"bit 5 (+32) change map\n"
"bit 6 (+64) spectators\n"
"bit 7 (+128) next map" );
idCVar g_mapCycle( "g_mapCycle", "mapcycle", CVAR_GAME | CVAR_ARCHIVE, "map cycling script for multiplayer games - see mapcycle.scriptcfg" );
idCVar mod_validSkins( "mod_validSkins", "skins/characters/player/marine_mp;skins/characters/player/marine_mp_green;skins/characters/player/marine_mp_blue;skins/characters/player/marine_mp_red;skins/characters/player/marine_mp_yellow", CVAR_GAME | CVAR_ARCHIVE, "valid skins for the game" );
idCVar net_serverDownload( "net_serverDownload", "0", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "enable server download redirects. 0: off 1: redirect to si_serverURL 2: use builtin download. see net_serverDl cvars for configuration" );
idCVar net_serverDlBaseURL( "net_serverDlBaseURL", "", CVAR_GAME | CVAR_ARCHIVE, "base URL for the download redirection" );
idCVar net_serverDlTable( "net_serverDlTable", "", CVAR_GAME | CVAR_ARCHIVE, "pak names for which download is provided, seperated by ;" );

255
neo/game/gamesys/SysCvar.h Normal file
View File

@@ -0,0 +1,255 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 r_aspectRatio;
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_skipParticles;
extern idCVar g_bloodEffects;
extern idCVar g_projectileLights;
extern idCVar g_doubleVision;
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 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 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_airTics;
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_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_exportMask;
extern idCVar g_flushSave;
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 g_voteFlags;
extern idCVar g_mapCycle;
extern idCVar g_balanceTDM;
extern idCVar si_timeLimit;
extern idCVar si_fragLimit;
extern idCVar si_gameType;
extern idCVar si_map;
extern idCVar si_spectators;
extern idCVar net_clientSelfSmoothing;
extern idCVar net_clientLagOMeter;
extern const char *si_gameTypeArgs[];
extern const char *ui_skinArgs[];
#endif /* !__SYS_CVAR_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,52 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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_TYPEINFO_H__
#define __SYS_TYPEINFO_H__
/*
===================================================================================
Game Type Info
===================================================================================
*/
const char * GetTypeVariableName( const char *typeName, int offset );
void PrintType( const void *typePtr, const char *typeName );
void WriteTypeToFile( idFile *fp, const void *typePtr, const char *typeName );
void InitTypeVariables( const void *typePtr, const char *typeName, int value );
void ListTypeInfo_f( const idCmdArgs &args );
void WriteGameState_f( const idCmdArgs &args );
void CompareGameState_f( const idCmdArgs &args );
void TestSaveGame_f( const idCmdArgs &args );
#endif /* !__SYS_TYPEINFO_H__ */

1666
neo/game/physics/Clip.cpp Normal file

File diff suppressed because it is too large Load Diff

352
neo/game/physics/Clip.h Normal file
View File

@@ -0,0 +1,352 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 __CLIP_H__
#define __CLIP_H__
/*
===============================================================================
Handles collision detection with the world and between physics objects.
===============================================================================
*/
#define CLIPMODEL_ID_TO_JOINT_HANDLE( id ) ( ( id ) >= 0 ? INVALID_JOINT : ((jointHandle_t) ( -1 - id )) )
#define JOINT_HANDLE_TO_CLIPMODEL_ID( id ) ( -1 - id )
class idClip;
class idClipModel;
class idEntity;
//===============================================================
//
// idClipModel
//
//===============================================================
class idClipModel {
friend class idClip;
public:
idClipModel( void );
explicit idClipModel( const char *name );
explicit idClipModel( const idTraceModel &trm );
explicit idClipModel( const int renderModelHandle );
explicit idClipModel( const idClipModel *model );
~idClipModel( void );
bool LoadModel( const char *name );
void LoadModel( const idTraceModel &trm );
void LoadModel( const int renderModelHandle );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Link( idClip &clp ); // must have been linked with an entity and id before
void Link( idClip &clp, idEntity *ent, int newId, const idVec3 &newOrigin, const idMat3 &newAxis, int renderModelHandle = -1 );
void Unlink( void ); // unlink from sectors
void SetPosition( const idVec3 &newOrigin, const idMat3 &newAxis ); // unlinks the clip model
void Translate( const idVec3 &translation ); // unlinks the clip model
void Rotate( const idRotation &rotation ); // unlinks the clip model
void Enable( void ); // enable for clipping
void Disable( void ); // keep linked but disable for clipping
void SetMaterial( const idMaterial *m );
const idMaterial * GetMaterial( void ) const;
void SetContents( int newContents ); // override contents
int GetContents( void ) const;
void SetEntity( idEntity *newEntity );
idEntity * GetEntity( void ) const;
void SetId( int newId );
int GetId( void ) const;
void SetOwner( idEntity *newOwner );
idEntity * GetOwner( void ) const;
const idBounds & GetBounds( void ) const;
const idBounds & GetAbsBounds( void ) const;
const idVec3 & GetOrigin( void ) const;
const idMat3 & GetAxis( void ) const;
bool IsTraceModel( void ) const; // returns true if this is a trace model
bool IsRenderModel( void ) const; // returns true if this is a render model
bool IsLinked( void ) const; // returns true if the clip model is linked
bool IsEnabled( void ) const; // returns true if enabled for collision detection
bool IsEqual( const idTraceModel &trm ) const;
cmHandle_t Handle( void ) const; // returns handle used to collide vs this model
const idTraceModel * GetTraceModel( void ) const;
void GetMassProperties( const float density, float &mass, idVec3 &centerOfMass, idMat3 &inertiaTensor ) const;
static cmHandle_t CheckModel( const char *name );
static void ClearTraceModelCache( void );
static int TraceModelCacheSize( void );
static void SaveTraceModels( idSaveGame *savefile );
static void RestoreTraceModels( idRestoreGame *savefile );
private:
bool enabled; // true if this clip model is used for clipping
idEntity * entity; // entity using this clip model
int id; // id for entities that use multiple clip models
idEntity * owner; // owner of the entity that owns this clip model
idVec3 origin; // origin of clip model
idMat3 axis; // orientation of clip model
idBounds bounds; // bounds
idBounds absBounds; // absolute bounds
const idMaterial * material; // material for trace models
int contents; // all contents ored together
cmHandle_t collisionModelHandle; // handle to collision model
int traceModelIndex; // trace model used for collision detection
int renderModelHandle; // render model def handle
struct clipLink_s * clipLinks; // links into sectors
int touchCount;
void Init( void ); // initialize
void Link_r( struct clipSector_s *node );
static int AllocTraceModel( const idTraceModel &trm );
static void FreeTraceModel( int traceModelIndex );
static idTraceModel * GetCachedTraceModel( int traceModelIndex );
static int GetTraceModelHashKey( const idTraceModel &trm );
};
ID_INLINE void idClipModel::Translate( const idVec3 &translation ) {
Unlink();
origin += translation;
}
ID_INLINE void idClipModel::Rotate( const idRotation &rotation ) {
Unlink();
origin *= rotation;
axis *= rotation.ToMat3();
}
ID_INLINE void idClipModel::Enable( void ) {
enabled = true;
}
ID_INLINE void idClipModel::Disable( void ) {
enabled = false;
}
ID_INLINE void idClipModel::SetMaterial( const idMaterial *m ) {
material = m;
}
ID_INLINE const idMaterial * idClipModel::GetMaterial( void ) const {
return material;
}
ID_INLINE void idClipModel::SetContents( int newContents ) {
contents = newContents;
}
ID_INLINE int idClipModel::GetContents( void ) const {
return contents;
}
ID_INLINE void idClipModel::SetEntity( idEntity *newEntity ) {
entity = newEntity;
}
ID_INLINE idEntity *idClipModel::GetEntity( void ) const {
return entity;
}
ID_INLINE void idClipModel::SetId( int newId ) {
id = newId;
}
ID_INLINE int idClipModel::GetId( void ) const {
return id;
}
ID_INLINE void idClipModel::SetOwner( idEntity *newOwner ) {
owner = newOwner;
}
ID_INLINE idEntity *idClipModel::GetOwner( void ) const {
return owner;
}
ID_INLINE const idBounds &idClipModel::GetBounds( void ) const {
return bounds;
}
ID_INLINE const idBounds &idClipModel::GetAbsBounds( void ) const {
return absBounds;
}
ID_INLINE const idVec3 &idClipModel::GetOrigin( void ) const {
return origin;
}
ID_INLINE const idMat3 &idClipModel::GetAxis( void ) const {
return axis;
}
ID_INLINE bool idClipModel::IsRenderModel( void ) const {
return ( renderModelHandle != -1 );
}
ID_INLINE bool idClipModel::IsTraceModel( void ) const {
return ( traceModelIndex != -1 );
}
ID_INLINE bool idClipModel::IsLinked( void ) const {
return ( clipLinks != NULL );
}
ID_INLINE bool idClipModel::IsEnabled( void ) const {
return enabled;
}
ID_INLINE bool idClipModel::IsEqual( const idTraceModel &trm ) const {
return ( traceModelIndex != -1 && *GetCachedTraceModel( traceModelIndex ) == trm );
}
ID_INLINE const idTraceModel *idClipModel::GetTraceModel( void ) const {
if ( !IsTraceModel() ) {
return NULL;
}
return idClipModel::GetCachedTraceModel( traceModelIndex );
}
//===============================================================
//
// idClip
//
//===============================================================
class idClip {
friend class idClipModel;
public:
idClip( void );
void Init( void );
void Shutdown( void );
// clip versus the rest of the world
bool Translation( trace_t &results, const idVec3 &start, const idVec3 &end,
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
bool Rotation( trace_t &results, const idVec3 &start, const idRotation &rotation,
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
bool Motion( trace_t &results, const idVec3 &start, const idVec3 &end, const idRotation &rotation,
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
int Contacts( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth,
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
int Contents( const idVec3 &start,
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
// special case translations versus the rest of the world
bool TracePoint( trace_t &results, const idVec3 &start, const idVec3 &end,
int contentMask, const idEntity *passEntity );
bool TraceBounds( trace_t &results, const idVec3 &start, const idVec3 &end, const idBounds &bounds,
int contentMask, const idEntity *passEntity );
// clip versus a specific model
void TranslationModel( trace_t &results, const idVec3 &start, const idVec3 &end,
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
void RotationModel( trace_t &results, const idVec3 &start, const idRotation &rotation,
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
int ContactsModel( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth,
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
int ContentsModel( const idVec3 &start,
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask,
cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
// clip versus all entities but not the world
void TranslationEntities( trace_t &results, const idVec3 &start, const idVec3 &end,
const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
// get a contact feature
bool GetModelContactFeature( const contactInfo_t &contact, const idClipModel *clipModel, idFixedWinding &winding ) const;
// get entities/clip models within or touching the given bounds
int EntitiesTouchingBounds( const idBounds &bounds, int contentMask, idEntity **entityList, int maxCount ) const;
int ClipModelsTouchingBounds( const idBounds &bounds, int contentMask, idClipModel **clipModelList, int maxCount ) const;
const idBounds & GetWorldBounds( void ) const;
idClipModel * DefaultClipModel( void );
// stats and debug drawing
void PrintStatistics( void );
void DrawClipModels( const idVec3 &eye, const float radius, const idEntity *passEntity );
bool DrawModelContactFeature( const contactInfo_t &contact, const idClipModel *clipModel, int lifetime ) const;
private:
int numClipSectors;
struct clipSector_s * clipSectors;
idBounds worldBounds;
idClipModel temporaryClipModel;
idClipModel defaultClipModel;
mutable int touchCount;
// statistics
int numTranslations;
int numRotations;
int numMotions;
int numRenderModelTraces;
int numContents;
int numContacts;
private:
struct clipSector_s * CreateClipSectors_r( const int depth, const idBounds &bounds, idVec3 &maxSector );
void ClipModelsTouchingBounds_r( const struct clipSector_s *node, struct listParms_s &parms ) const;
const idTraceModel * TraceModelForClipModel( const idClipModel *mdl ) const;
int GetTraceClipModels( const idBounds &bounds, int contentMask, const idEntity *passEntity, idClipModel **clipModelList ) const;
void TraceRenderModel( trace_t &trace, const idVec3 &start, const idVec3 &end, const float radius, const idMat3 &axis, idClipModel *touch ) const;
};
ID_INLINE bool idClip::TracePoint( trace_t &results, const idVec3 &start, const idVec3 &end, int contentMask, const idEntity *passEntity ) {
Translation( results, start, end, NULL, mat3_identity, contentMask, passEntity );
return ( results.fraction < 1.0f );
}
ID_INLINE bool idClip::TraceBounds( trace_t &results, const idVec3 &start, const idVec3 &end, const idBounds &bounds, int contentMask, const idEntity *passEntity ) {
temporaryClipModel.LoadModel( idTraceModel( bounds ) );
Translation( results, start, end, &temporaryClipModel, mat3_identity, contentMask, passEntity );
return ( results.fraction < 1.0f );
}
ID_INLINE const idBounds & idClip::GetWorldBounds( void ) const {
return worldBounds;
}
ID_INLINE idClipModel *idClip::DefaultClipModel( void ) {
return &defaultClipModel;
}
#endif /* !__CLIP_H__ */

View File

@@ -0,0 +1,93 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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"
CLASS_DECLARATION( idClass, idForce )
END_CLASS
idList<idForce*> idForce::forceList;
/*
================
idForce::idForce
================
*/
idForce::idForce( void ) {
forceList.Append( this );
}
/*
================
idForce::~idForce
================
*/
idForce::~idForce( void ) {
forceList.Remove( this );
}
/*
================
idForce::DeletePhysics
================
*/
void idForce::DeletePhysics( const idPhysics *phys ) {
int i;
for ( i = 0; i < forceList.Num(); i++ ) {
forceList[i]->RemovePhysics( phys );
}
}
/*
================
idForce::ClearForceList
================
*/
void idForce::ClearForceList( void ) {
forceList.Clear();
}
/*
================
idForce::Evaluate
================
*/
void idForce::Evaluate( int time ) {
}
/*
================
idForce::RemovePhysics
================
*/
void idForce::RemovePhysics( const idPhysics *phys ) {
}

66
neo/game/physics/Force.h Normal file
View File

@@ -0,0 +1,66 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 __FORCE_H__
#define __FORCE_H__
/*
===============================================================================
Force base class
A force object applies a force to a physics object.
===============================================================================
*/
class idEntity;
class idPhysics;
class idForce : public idClass {
public:
CLASS_PROTOTYPE( idForce );
idForce( void );
virtual ~idForce( void );
static void DeletePhysics( const idPhysics *phys );
static void ClearForceList( void );
public: // common force interface
// evalulate the force up to the given time
virtual void Evaluate( int time );
// removes any pointers to the physics object
virtual void RemovePhysics( const idPhysics *phys );
private:
static idList<idForce*> forceList;
};
#endif /* !__FORCE_H__ */

View File

@@ -0,0 +1,135 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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"
CLASS_DECLARATION( idForce, idForce_Constant )
END_CLASS
/*
================
idForce_Constant::idForce_Constant
================
*/
idForce_Constant::idForce_Constant( void ) {
force = vec3_zero;
physics = NULL;
id = 0;
point = vec3_zero;
}
/*
================
idForce_Constant::~idForce_Constant
================
*/
idForce_Constant::~idForce_Constant( void ) {
}
/*
================
idForce_Constant::Save
================
*/
void idForce_Constant::Save( idSaveGame *savefile ) const {
savefile->WriteVec3( force );
savefile->WriteInt( id );
savefile->WriteVec3( point );
}
/*
================
idForce_Constant::Restore
================
*/
void idForce_Constant::Restore( idRestoreGame *savefile ) {
// Owner needs to call SetPhysics!!
savefile->ReadVec3( force );
savefile->ReadInt( id );
savefile->ReadVec3( point );
}
/*
================
idForce_Constant::SetPosition
================
*/
void idForce_Constant::SetPosition( idPhysics *physics, int id, const idVec3 &point ) {
this->physics = physics;
this->id = id;
this->point = point;
}
/*
================
idForce_Constant::SetForce
================
*/
void idForce_Constant::SetForce( const idVec3 &force ) {
this->force = force;
}
/*
================
idForce_Constant::SetPhysics
================
*/
void idForce_Constant::SetPhysics( idPhysics *physics ) {
this->physics = physics;
}
/*
================
idForce_Constant::Evaluate
================
*/
void idForce_Constant::Evaluate( int time ) {
idVec3 p;
if ( !physics ) {
return;
}
p = physics->GetOrigin( id ) + point * physics->GetAxis( id );
physics->AddForce( id, p, force );
}
/*
================
idForce_Constant::RemovePhysics
================
*/
void idForce_Constant::RemovePhysics( const idPhysics *phys ) {
if ( physics == phys ) {
physics = NULL;
}
}

View File

@@ -0,0 +1,71 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 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 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 __FORCE_CONSTANT_H__
#define __FORCE_CONSTANT_H__
/*
===============================================================================
Constant force
===============================================================================
*/
class idForce_Constant : public idForce {
public:
CLASS_PROTOTYPE( idForce_Constant );
idForce_Constant( void );
virtual ~idForce_Constant( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
// constant force
void SetForce( const idVec3 &force );
// set force position
void SetPosition( idPhysics *physics, int id, const idVec3 &point );
void SetPhysics( idPhysics *physics );
public: // common force interface
virtual void Evaluate( int time );
virtual void RemovePhysics( const idPhysics *phys );
private:
// force properties
idVec3 force;
idPhysics * physics;
int id;
idVec3 point;
};
#endif /* !__FORCE_CONSTANT_H__ */

Some files were not shown because too many files have changed in this diff Show More