2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
22 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.
24 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.
26 ===========================================================================
29 #ifndef __GAME_ENTITY_H__
30 #define __GAME_ENTITY_H__
33 ===============================================================================
35 Game entity base class.
37 ===============================================================================
40 static const int DELAY_DORMANT_TIME = 3000;
42 extern const idEventDef EV_PostSpawn;
43 extern const idEventDef EV_FindTargets;
44 extern const idEventDef EV_Touch;
45 extern const idEventDef EV_Use;
46 extern const idEventDef EV_Activate;
47 extern const idEventDef EV_ActivateTargets;
48 extern const idEventDef EV_Hide;
49 extern const idEventDef EV_Show;
50 extern const idEventDef EV_GetShaderParm;
51 extern const idEventDef EV_SetShaderParm;
52 extern const idEventDef EV_SetOwner;
53 extern const idEventDef EV_GetAngles;
54 extern const idEventDef EV_SetAngles;
55 extern const idEventDef EV_SetLinearVelocity;
56 extern const idEventDef EV_SetAngularVelocity;
57 extern const idEventDef EV_SetSkin;
58 extern const idEventDef EV_StartSoundShader;
59 extern const idEventDef EV_StopSound;
60 extern const idEventDef EV_CacheSoundShader;
65 TH_THINK = 1, // run think function each frame
66 TH_PHYSICS = 2, // run physics each frame
67 TH_ANIMATE = 4, // update animation each frame
68 TH_UPDATEVISUALS = 8, // update renderEntity
69 TH_UPDATEPARTICLES = 16
74 // make sure to change script/doom_defs.script if you add any, or change their order
77 SIG_TOUCH, // object was touched
78 SIG_USE, // object was used
79 SIG_TRIGGER, // object was activated
80 SIG_REMOVED, // object was removed from the game
81 SIG_DAMAGE, // object was damaged
82 SIG_BLOCKED, // object was blocked
84 SIG_MOVER_POS1, // mover at position 1 (door closed)
85 SIG_MOVER_POS2, // mover at position 2 (door open)
86 SIG_MOVER_1TO2, // mover changing from position 1 to 2
87 SIG_MOVER_2TO1, // mover changing from position 2 to 1
92 // FIXME: At some point we may want to just limit it to one thread per signal, but
93 // for now, I'm allowing multiple threads. We should reevaluate this later in the project
94 #define MAX_SIGNAL_THREADS 16 // probably overkill, but idList uses a granularity of 16
98 const function_t *function;
103 idList<signal_t> signal[ NUM_SIGNALS ];
107 class idEntity : public idClass {
109 static const int MAX_PVS_AREAS = 4;
111 int entityNumber; // index into the entity list
112 int entityDefNumber; // index into the entity def list
114 idLinkList<idEntity> spawnNode; // for being linked into spawnedEntities list
115 idLinkList<idEntity> activeNode; // for being linked into activeEntities list
117 idLinkList<idEntity> snapshotNode; // for being linked into snapshotEntities list
118 int snapshotSequence; // last snapshot this entity was in
119 int snapshotBits; // number of bits this entity occupied in the last snapshot
121 idStr name; // name of entity
122 idDict spawnArgs; // key/value pairs used to spawn and initialize entity
123 idScriptObject scriptObject; // contains all script defined data for this entity
125 int thinkFlags; // TH_? flags
126 int dormantStart; // time that the entity was first closed off from player
127 bool cinematic; // during cinematics, entity will only think if cinematic is set
129 renderView_t * renderView; // for camera views from this entity
130 idEntity * cameraTarget; // any remoteRenderMap shaders will use this
132 idList< idEntityPtr<idEntity> > targets; // when this entity is activated these entities entity are activated
134 int health; // FIXME: do all objects really need health?
136 struct entityFlags_s {
137 bool notarget :1; // if true never attack or target this entity
138 bool noknockback :1; // if true no knockback from hits
139 bool takedamage :1; // if true this entity can be damaged
140 bool hidden :1; // if true this entity is not visible
141 bool bindOrientated :1; // if true both the master orientation is used for binding
142 bool solidForTeam :1; // if true this entity is considered solid when a physics team mate pushes entities
143 bool forcePhysicsUpdate :1; // if true always update from the physics whether the object moved or not
144 bool selected :1; // if true the entity is selected for editing
145 bool neverDormant :1; // if true the entity never goes dormant
146 bool isDormant :1; // if true the entity is dormant
147 bool hasAwakened :1; // before a monster has been awakened the first time, use full PVS for dormant instead of area-connected
148 bool networkSync :1; // if true the entity is synchronized over the network
149 bool grabbed :1; // if true object is currently being grabbed
157 renderEntity_t xrayEntity;
158 qhandle_t xrayEntityHandle;
159 const idDeclSkin * xraySkin;
161 void DetermineTimeGroup( bool slowmo );
163 void SetGrabbedState( bool grabbed );
168 ABSTRACT_PROTOTYPE( idEntity );
175 void Save( idSaveGame *savefile ) const;
176 void Restore( idRestoreGame *savefile );
178 const char * GetEntityDefName( void ) const;
179 void SetName( const char *name );
180 const char * GetName( void ) const;
181 virtual void UpdateChangeableSpawnArgs( const idDict *source );
183 // clients generate views based on all the player specific options,
184 // cameras have custom code, and everything else just uses the axis orientation
185 virtual renderView_t * GetRenderView();
188 virtual void Think( void );
189 bool CheckDormant( void ); // dormant == on the active list, but out of PVS
190 virtual void DormantBegin( void ); // called when entity becomes dormant
191 virtual void DormantEnd( void ); // called when entity wakes from being dormant
192 bool IsActive( void ) const;
193 void BecomeActive( int flags );
194 void BecomeInactive( int flags );
195 void UpdatePVSAreas( const idVec3 &pos );
198 virtual void Present( void );
199 virtual renderEntity_t *GetRenderEntity( void );
200 virtual int GetModelDefHandle( void );
201 virtual void SetModel( const char *modelname );
202 void SetSkin( const idDeclSkin *skin );
203 const idDeclSkin * GetSkin( void ) const;
204 void SetShaderParm( int parmnum, float value );
205 virtual void SetColor( float red, float green, float blue );
206 virtual void SetColor( const idVec3 &color );
207 virtual void GetColor( idVec3 &out ) const;
208 virtual void SetColor( const idVec4 &color );
209 virtual void GetColor( idVec4 &out ) const;
210 virtual void FreeModelDef( void );
211 virtual void FreeLightDef( void );
212 virtual void Hide( void );
213 virtual void Show( void );
214 bool IsHidden( void ) const;
215 void UpdateVisuals( void );
216 void UpdateModel( void );
217 void UpdateModelTransform( void );
218 virtual void ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material );
219 int GetNumPVSAreas( void );
220 const int * GetPVSAreas( void );
221 void ClearPVSAreas( void );
222 bool PhysicsTeamInPVS( pvsHandle_t pvsHandle );
225 virtual bool UpdateAnimationControllers( void );
226 bool UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView );
227 static bool ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView );
228 virtual idAnimator * GetAnimator( void ); // returns animator object used by this entity
231 virtual bool CanPlayChatterSounds( void ) const;
232 bool StartSound( const char *soundName, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length );
233 bool StartSoundShader( const idSoundShader *shader, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length );
234 void StopSound( const s_channelType channel, bool broadcast ); // pass SND_CHANNEL_ANY to stop all sounds
235 void SetSoundVolume( float volume );
236 void UpdateSound( void );
237 int GetListenerId( void ) const;
238 idSoundEmitter * GetSoundEmitter( void ) const;
239 void FreeSoundEmitter( bool immediate );
242 virtual void PreBind( void );
243 virtual void PostBind( void );
244 virtual void PreUnbind( void );
245 virtual void PostUnbind( void );
246 void JoinTeam( idEntity *teammember );
247 void Bind( idEntity *master, bool orientated );
248 void BindToJoint( idEntity *master, const char *jointname, bool orientated );
249 void BindToJoint( idEntity *master, jointHandle_t jointnum, bool orientated );
250 void BindToBody( idEntity *master, int bodyId, bool orientated );
252 bool IsBound( void ) const;
253 bool IsBoundTo( idEntity *master ) const;
254 idEntity * GetBindMaster( void ) const;
255 jointHandle_t GetBindJoint( void ) const;
256 int GetBindBody( void ) const;
257 idEntity * GetTeamMaster( void ) const;
258 idEntity * GetNextTeamEntity( void ) const;
259 void ConvertLocalToWorldTransform( idVec3 &offset, idMat3 &axis );
260 idVec3 GetLocalVector( const idVec3 &vec ) const;
261 idVec3 GetLocalCoordinates( const idVec3 &vec ) const;
262 idVec3 GetWorldVector( const idVec3 &vec ) const;
263 idVec3 GetWorldCoordinates( const idVec3 &vec ) const;
264 bool GetMasterPosition( idVec3 &masterOrigin, idMat3 &masterAxis ) const;
265 void GetWorldVelocities( idVec3 &linearVelocity, idVec3 &angularVelocity ) const;
268 // set a new physics object to be used by this entity
269 void SetPhysics( idPhysics *phys );
270 // get the physics object used by this entity
271 idPhysics * GetPhysics( void ) const;
272 // restore physics pointer for save games
273 void RestorePhysics( idPhysics *phys );
274 // run the physics for this entity
275 bool RunPhysics( void );
276 // set the origin of the physics object (relative to bindMaster if not NULL)
277 void SetOrigin( const idVec3 &org );
278 // set the axis of the physics object (relative to bindMaster if not NULL)
279 void SetAxis( const idMat3 &axis );
280 // use angles to set the axis of the physics object (relative to bindMaster if not NULL)
281 void SetAngles( const idAngles &ang );
282 // get the floor position underneath the physics object
283 bool GetFloorPos( float max_dist, idVec3 &floorpos ) const;
284 // retrieves the transformation going from the physics origin/axis to the visual origin/axis
285 virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis );
286 // retrieves the transformation going from the physics origin/axis to the sound origin/axis
287 virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis );
288 // called from the physics object when colliding, should return true if the physics simulation should stop
289 virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
290 // retrieves impact information, 'ent' is the entity retrieving the info
291 virtual void GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info );
292 // apply an impulse to the physics object, 'ent' is the entity applying the impulse
293 virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse );
294 // add a force to the physics object, 'ent' is the entity adding the force
295 virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force );
296 // activate the physics object, 'ent' is the entity activating this entity
297 virtual void ActivatePhysics( idEntity *ent );
298 // returns true if the physics object is at rest
299 virtual bool IsAtRest( void ) const;
300 // returns the time the physics object came to rest
301 virtual int GetRestStartTime( void ) const;
302 // add a contact entity
303 virtual void AddContactEntity( idEntity *ent );
304 // remove a touching entity
305 virtual void RemoveContactEntity( idEntity *ent );
308 // returns true if this entity can be damaged from the given origin
309 virtual bool CanDamage( const idVec3 &origin, idVec3 &damagePoint ) const;
310 // applies damage to this entity
311 virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
312 // adds a damage effect like overlays, blood, sparks, debris etc.
313 virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName );
314 // callback function for when another entity received damage from this entity. damage can be adjusted and returned to the caller.
315 virtual void DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage );
316 // notifies this entity that it is in pain
317 virtual bool Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
318 // notifies this entity that is has been killed
319 virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
322 virtual bool ShouldConstructScriptObjectAtSpawn( void ) const;
323 virtual idThread * ConstructScriptObject( void );
324 virtual void DeconstructScriptObject( void );
325 void SetSignal( signalNum_t signalnum, idThread *thread, const function_t *function );
326 void ClearSignal( idThread *thread, signalNum_t signalnum );
327 void ClearSignalThread( signalNum_t signalnum, idThread *thread );
328 bool HasSignal( signalNum_t signalnum ) const;
329 void Signal( signalNum_t signalnum );
330 void SignalEvent( idThread *thread, signalNum_t signalnum );
333 void TriggerGuis( void );
334 bool HandleGuiCommands( idEntity *entityGui, const char *cmds );
335 virtual bool HandleSingleGuiCommand( idEntity *entityGui, idLexer *src );
338 void FindTargets( void );
339 void RemoveNullTargets( void );
340 void ActivateTargets( idEntity *activator ) const;
343 virtual void Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination );
344 bool TouchTriggers( void ) const;
345 idCurve_Spline<idVec3> *GetSpline( void ) const;
346 virtual void ShowEditingDialog( void );
349 EVENT_STARTSOUNDSHADER,
350 EVENT_STOPSOUNDSHADER,
354 virtual void ClientPredictionThink( void );
355 virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
356 virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
357 virtual bool ServerReceiveEvent( int event, int time, const idBitMsg &msg );
358 virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
360 void WriteBindToSnapshot( idBitMsgDelta &msg ) const;
361 void ReadBindFromSnapshot( const idBitMsgDelta &msg );
362 void WriteColorToSnapshot( idBitMsgDelta &msg ) const;
363 void ReadColorFromSnapshot( const idBitMsgDelta &msg );
364 void WriteGUIToSnapshot( idBitMsgDelta &msg ) const;
365 void ReadGUIFromSnapshot( const idBitMsgDelta &msg );
367 void ServerSendEvent( int eventId, const idBitMsg *msg, bool saveEvent, int excludeClient ) const;
368 void ClientSendEvent( int eventId, const idBitMsg *msg ) const;
371 renderEntity_t renderEntity; // used to present a model to the renderer
372 int modelDefHandle; // handle to static renderer model
373 refSound_t refSound; // used to present sound to the audio engine
376 idPhysics_Static defaultPhysicsObj; // default physics object
377 idPhysics * physics; // physics used for this entity
378 idEntity * bindMaster; // entity bound to if unequal NULL
379 jointHandle_t bindJoint; // joint bound to if unequal INVALID_JOINT
380 int bindBody; // body bound to if unequal -1
381 idEntity * teamMaster; // master of the physics team
382 idEntity * teamChain; // next entity in physics team
384 int numPVSAreas; // number of renderer areas the entity covers
385 int PVSAreas[MAX_PVS_AREAS]; // numbers of the renderer areas the entity covers
387 signalList_t * signals;
389 int mpGUIState; // local cache to avoid systematic SetStateInt
392 void FixupLocalizedStrings();
394 bool DoDormantTests( void ); // dormant == on the active list, but out of PVS
397 // initialize the default physics
398 void InitDefaultPhysics( const idVec3 &origin, const idMat3 &axis );
399 // update visual position from the physics
400 void UpdateFromPhysics( bool moveBack );
403 bool InitBind( idEntity *master ); // initialize an entity binding
404 void FinishBind( void ); // finish an entity binding
405 void RemoveBinds( void ); // deletes any entities bound to this object
406 void QuitTeam( void ); // leave the current team
408 void UpdatePVSAreas( void );
411 void Event_GetName( void );
412 void Event_SetName( const char *name );
413 void Event_FindTargets( void );
414 void Event_ActivateTargets( idEntity *activator );
415 void Event_NumTargets( void );
416 void Event_GetTarget( float index );
417 void Event_RandomTarget( const char *ignore );
418 void Event_Bind( idEntity *master );
419 void Event_BindPosition( idEntity *master );
420 void Event_BindToJoint( idEntity *master, const char *jointname, float orientated );
421 void Event_Unbind( void );
422 void Event_RemoveBinds( void );
423 void Event_SpawnBind( void );
424 void Event_SetOwner( idEntity *owner );
425 void Event_SetModel( const char *modelname );
426 void Event_SetSkin( const char *skinname );
427 void Event_GetShaderParm( int parmnum );
428 void Event_SetShaderParm( int parmnum, float value );
429 void Event_SetShaderParms( float parm0, float parm1, float parm2, float parm3 );
430 void Event_SetColor( float red, float green, float blue );
431 void Event_GetColor( void );
432 void Event_IsHidden( void );
433 void Event_Hide( void );
434 void Event_Show( void );
435 void Event_CacheSoundShader( const char *soundName );
436 void Event_StartSoundShader( const char *soundName, int channel );
437 void Event_StopSound( int channel, int netSync );
438 void Event_StartSound( const char *soundName, int channel, int netSync );
439 void Event_FadeSound( int channel, float to, float over );
440 void Event_GetWorldOrigin( void );
441 void Event_SetWorldOrigin( idVec3 const &org );
442 void Event_GetOrigin( void );
443 void Event_SetOrigin( const idVec3 &org );
444 void Event_GetAngles( void );
445 void Event_SetAngles( const idAngles &ang );
446 void Event_SetLinearVelocity( const idVec3 &velocity );
447 void Event_GetLinearVelocity( void );
448 void Event_SetAngularVelocity( const idVec3 &velocity );
449 void Event_GetAngularVelocity( void );
450 void Event_SetSize( const idVec3 &mins, const idVec3 &maxs );
451 void Event_GetSize( void );
452 void Event_GetMins( void );
453 void Event_GetMaxs( void );
454 void Event_Touches( idEntity *ent );
455 void Event_SetGuiParm( const char *key, const char *val );
456 void Event_SetGuiFloat( const char *key, float f );
457 void Event_GetNextKey( const char *prefix, const char *lastMatch );
458 void Event_SetKey( const char *key, const char *value );
459 void Event_GetKey( const char *key );
460 void Event_GetIntKey( const char *key );
461 void Event_GetFloatKey( const char *key );
462 void Event_GetVectorKey( const char *key );
463 void Event_GetEntityKey( const char *key );
464 void Event_RestorePosition( void );
465 void Event_UpdateCameraTarget( void );
466 void Event_DistanceTo( idEntity *ent );
467 void Event_DistanceToPoint( const idVec3 &point );
468 void Event_StartFx( const char *fx );
469 void Event_WaitFrame( void );
470 void Event_Wait( float time );
471 void Event_HasFunction( const char *name );
472 void Event_CallFunction( const char *name );
473 void Event_SetNeverDormant( int enable );
475 void Event_SetGui( int guiNum, const char *guiName);
476 void Event_PrecacheGui( const char *guiName );
477 void Event_GetGuiParm(int guiNum, const char *key);
478 void Event_GetGuiParmFloat(int guiNum, const char *key);
479 void Event_GuiNamedEvent(int guiNum, const char *event);
484 ===============================================================================
486 Animated entity base class.
488 ===============================================================================
491 typedef struct damageEffect_s {
492 jointHandle_t jointNum;
496 const idDeclParticle* type;
497 struct damageEffect_s * next;
500 class idAnimatedEntity : public idEntity {
502 CLASS_PROTOTYPE( idAnimatedEntity );
507 void Save( idSaveGame *savefile ) const;
508 void Restore( idRestoreGame *savefile );
510 virtual void ClientPredictionThink( void );
511 virtual void Think( void );
513 void UpdateAnimation( void );
515 virtual idAnimator * GetAnimator( void );
516 virtual void SetModel( const char *modelname );
518 bool GetJointWorldTransform( jointHandle_t jointHandle, int currentTime, idVec3 &offset, idMat3 &axis );
519 bool GetJointTransformForAnim( jointHandle_t jointHandle, int animNum, int currentTime, idVec3 &offset, idMat3 &axis ) const;
521 virtual int GetDefaultSurfaceType( void ) const;
522 virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName );
523 void AddLocalDamageEffect( jointHandle_t jointNum, const idVec3 &localPoint, const idVec3 &localNormal, const idVec3 &localDir, const idDeclEntityDef *def, const idMaterial *collisionMaterial );
524 void UpdateDamageEffects( void );
526 virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
529 EVENT_ADD_DAMAGE_EFFECT = idEntity::EVENT_MAXEVENTS,
535 damageEffect_t * damageEffects;
538 void Event_GetJointHandle( const char *jointname );
539 void Event_ClearAllJoints( void );
540 void Event_ClearJoint( jointHandle_t jointnum );
541 void Event_SetJointPos( jointHandle_t jointnum, jointModTransform_t transform_type, const idVec3 &pos );
542 void Event_SetJointAngle( jointHandle_t jointnum, jointModTransform_t transform_type, const idAngles &angles );
543 void Event_GetJointPos( jointHandle_t jointnum );
544 void Event_GetJointAngle( jointHandle_t jointnum );
556 SetTimeState( int timeGroup );
559 void PushState( int timeGroup );
562 ID_INLINE SetTimeState::SetTimeState() {
566 ID_INLINE SetTimeState::SetTimeState( int timeGroup ) {
568 PushState( timeGroup );
571 ID_INLINE void SetTimeState::PushState( int timeGroup ) {
573 // Don't mess with time in Multiplayer
574 if ( !gameLocal.isMultiplayer ) {
578 // determine previous fast setting
579 if ( gameLocal.time == gameLocal.slow.time ) {
580 previousFast = false;
586 // determine new fast setting
596 gameLocal.fast.Get( gameLocal.time, gameLocal.previousTime, gameLocal.msec, gameLocal.framenum, gameLocal.realClientTime );
599 gameLocal.slow.Get( gameLocal.time, gameLocal.previousTime, gameLocal.msec, gameLocal.framenum, gameLocal.realClientTime );
604 ID_INLINE SetTimeState::~SetTimeState() {
605 if ( activated && !gameLocal.isMultiplayer ) {
606 // set previous correct time
607 if ( previousFast ) {
608 gameLocal.fast.Get( gameLocal.time, gameLocal.previousTime, gameLocal.msec, gameLocal.framenum, gameLocal.realClientTime );
611 gameLocal.slow.Get( gameLocal.time, gameLocal.previousTime, gameLocal.msec, gameLocal.framenum, gameLocal.realClientTime );
617 #endif /* !__GAME_ENTITY_H__ */