]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/d3xp/Entity.h
hello world
[icculus/iodoom3.git] / neo / d3xp / Entity.h
1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 
6
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).  
8
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.
13
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.
18
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/>.
21
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.
23
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.
25
26 ===========================================================================
27 */
28
29 #ifndef __GAME_ENTITY_H__
30 #define __GAME_ENTITY_H__
31
32 /*
33 ===============================================================================
34
35         Game entity base class.
36
37 ===============================================================================
38 */
39
40 static const int DELAY_DORMANT_TIME = 3000;
41
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;
61
62 // Think flags
63 enum {
64         TH_ALL                                  = -1,
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
70 };
71
72 //
73 // Signals
74 // make sure to change script/doom_defs.script if you add any, or change their order
75 //
76 typedef enum {
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
83
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
88
89         NUM_SIGNALS
90 } signalNum_t;
91
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
95
96 struct signal_t {
97         int                                     threadnum;
98         const function_t        *function;
99 };
100
101 class signalList_t {
102 public:
103         idList<signal_t> signal[ NUM_SIGNALS ];
104 };
105
106
107 class idEntity : public idClass {
108 public:
109         static const int                MAX_PVS_AREAS = 4;
110
111         int                                             entityNumber;                   // index into the entity list
112         int                                             entityDefNumber;                // index into the entity def list
113
114         idLinkList<idEntity>    spawnNode;                              // for being linked into spawnedEntities list
115         idLinkList<idEntity>    activeNode;                             // for being linked into activeEntities list
116
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
120
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
124
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
128
129         renderView_t *                  renderView;                             // for camera views from this entity
130         idEntity *                              cameraTarget;                   // any remoteRenderMap shaders will use this
131
132         idList< idEntityPtr<idEntity> > targets;                // when this entity is activated these entities entity are activated
133
134         int                                             health;                                 // FIXME: do all objects really need health?
135
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
150         } fl;
151
152 #ifdef _D3XP
153         int                                             timeGroup;
154
155         bool                                    noGrab;
156
157         renderEntity_t                  xrayEntity;
158         qhandle_t                               xrayEntityHandle;
159         const idDeclSkin *              xraySkin;
160
161         void                                    DetermineTimeGroup( bool slowmo );
162
163         void                                    SetGrabbedState( bool grabbed );
164         bool                                    IsGrabbed();
165 #endif
166
167 public:
168         ABSTRACT_PROTOTYPE( idEntity );
169
170                                                         idEntity();
171                                                         ~idEntity();
172
173         void                                    Spawn( void );
174
175         void                                    Save( idSaveGame *savefile ) const;
176         void                                    Restore( idRestoreGame *savefile );
177
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 );
182
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();
186
187         // thinking
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 );
196
197         // visuals
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 );
223
224         // animation
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
229
230         // sound
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 );
240
241         // entity binding
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 );
251         void                                    Unbind( void );
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;
266
267         // physics
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 );
306
307         // damage
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 );
320
321         // scripting
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 );
331
332         // gui
333         void                                    TriggerGuis( void );
334         bool                                    HandleGuiCommands( idEntity *entityGui, const char *cmds );
335         virtual bool                    HandleSingleGuiCommand( idEntity *entityGui, idLexer *src );
336
337         // targets
338         void                                    FindTargets( void );
339         void                                    RemoveNullTargets( void );
340         void                                    ActivateTargets( idEntity *activator ) const;
341
342         // misc
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 );
347
348         enum {
349                 EVENT_STARTSOUNDSHADER,
350                 EVENT_STOPSOUNDSHADER,
351                 EVENT_MAXEVENTS
352         };
353
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 );
359
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 );
366
367         void                                    ServerSendEvent( int eventId, const idBitMsg *msg, bool saveEvent, int excludeClient ) const;
368         void                                    ClientSendEvent( int eventId, const idBitMsg *msg ) const;
369
370 protected:
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
374
375 private:
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
383
384         int                                             numPVSAreas;                                            // number of renderer areas the entity covers
385         int                                             PVSAreas[MAX_PVS_AREAS];                        // numbers of the renderer areas the entity covers
386
387         signalList_t *                  signals;
388
389         int                                             mpGUIState;                                                     // local cache to avoid systematic SetStateInt
390
391 private:
392         void                                    FixupLocalizedStrings();
393
394         bool                                    DoDormantTests( void );                         // dormant == on the active list, but out of PVS
395
396         // physics
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 );
401
402         // entity binding
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
407
408         void                                    UpdatePVSAreas( void );
409
410         // events
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 );
474 #ifdef _D3XP
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);
480 #endif
481 };
482
483 /*
484 ===============================================================================
485
486         Animated entity base class.
487         
488 ===============================================================================
489 */
490
491 typedef struct damageEffect_s {
492         jointHandle_t                   jointNum;
493         idVec3                                  localOrigin;
494         idVec3                                  localNormal;
495         int                                             time;
496         const idDeclParticle*   type;
497         struct damageEffect_s * next;
498 } damageEffect_t;
499
500 class idAnimatedEntity : public idEntity {
501 public:
502         CLASS_PROTOTYPE( idAnimatedEntity );
503
504                                                         idAnimatedEntity();
505                                                         ~idAnimatedEntity();
506
507         void                                    Save( idSaveGame *savefile ) const;
508         void                                    Restore( idRestoreGame *savefile );
509
510         virtual void                    ClientPredictionThink( void );
511         virtual void                    Think( void );
512
513         void                                    UpdateAnimation( void );
514
515         virtual idAnimator *    GetAnimator( void );
516         virtual void                    SetModel( const char *modelname );
517
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;
520
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 );
525
526         virtual bool                    ClientReceiveEvent( int event, int time, const idBitMsg &msg );
527
528         enum {
529                 EVENT_ADD_DAMAGE_EFFECT = idEntity::EVENT_MAXEVENTS,
530                 EVENT_MAXEVENTS
531         };
532
533 protected:
534         idAnimator                              animator;
535         damageEffect_t *                damageEffects;
536
537 private:
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 );
545 };
546
547
548 #ifdef _D3XP
549 class SetTimeState {
550         bool                                    activated;
551         bool                                    previousFast;
552         bool                                    fast;
553
554 public:
555                                                         SetTimeState();
556                                                         SetTimeState( int timeGroup );
557                                                         ~SetTimeState();
558
559         void                                    PushState( int timeGroup );
560 };
561
562 ID_INLINE SetTimeState::SetTimeState() {
563         activated = false;
564 }
565
566 ID_INLINE SetTimeState::SetTimeState( int timeGroup ) {
567         activated = false;
568         PushState( timeGroup );
569 }
570
571 ID_INLINE void SetTimeState::PushState( int timeGroup ) {
572
573         // Don't mess with time in Multiplayer
574         if ( !gameLocal.isMultiplayer ) {
575
576                 activated = true;
577
578                 // determine previous fast setting
579                 if ( gameLocal.time == gameLocal.slow.time ) {
580                         previousFast = false;
581                 }
582                 else {
583                         previousFast = true;
584                 }
585
586                 // determine new fast setting
587                 if ( timeGroup ) {
588                         fast = true;
589                 }
590                 else {
591                         fast = false;
592                 }
593
594                 // set correct time
595                 if ( fast ) {
596                         gameLocal.fast.Get( gameLocal.time, gameLocal.previousTime, gameLocal.msec, gameLocal.framenum, gameLocal.realClientTime );
597                 }
598                 else {
599                         gameLocal.slow.Get( gameLocal.time, gameLocal.previousTime, gameLocal.msec, gameLocal.framenum, gameLocal.realClientTime );
600                 }
601         }
602 }
603
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 );
609                 }
610                 else {
611                         gameLocal.slow.Get( gameLocal.time, gameLocal.previousTime, gameLocal.msec, gameLocal.framenum, gameLocal.realClientTime );
612                 }
613         }
614 }
615 #endif
616
617 #endif /* !__GAME_ENTITY_H__ */