doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Entity.cpp
Go to the documentation of this file.
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 #include "../idlib/precompiled.h"
30 #pragma hdrstop
31 
32 #include "Game_local.h"
33 
34 /*
35 ===============================================================================
36 
37  idEntity
38 
39 ===============================================================================
40 */
41 
42 // overridable events
43 const idEventDef EV_PostSpawn( "<postspawn>", NULL );
44 const idEventDef EV_FindTargets( "<findTargets>", NULL );
45 const idEventDef EV_Touch( "<touch>", "et" );
46 const idEventDef EV_GetName( "getName", NULL, 's' );
47 const idEventDef EV_SetName( "setName", "s" );
48 const idEventDef EV_Activate( "activate", "e" );
49 const idEventDef EV_ActivateTargets( "activateTargets", "e" );
50 const idEventDef EV_NumTargets( "numTargets", NULL, 'f' );
51 const idEventDef EV_GetTarget( "getTarget", "f", 'e' );
52 const idEventDef EV_RandomTarget( "randomTarget", "s", 'e' );
53 const idEventDef EV_Bind( "bind", "e" );
54 const idEventDef EV_BindPosition( "bindPosition", "e" );
55 const idEventDef EV_BindToJoint( "bindToJoint", "esf" );
56 const idEventDef EV_Unbind( "unbind", NULL );
57 const idEventDef EV_RemoveBinds( "removeBinds" );
58 const idEventDef EV_SpawnBind( "<spawnbind>", NULL );
59 const idEventDef EV_SetOwner( "setOwner", "e" );
60 const idEventDef EV_SetModel( "setModel", "s" );
61 const idEventDef EV_SetSkin( "setSkin", "s" );
62 const idEventDef EV_GetWorldOrigin( "getWorldOrigin", NULL, 'v' );
63 const idEventDef EV_SetWorldOrigin( "setWorldOrigin", "v" );
64 const idEventDef EV_GetOrigin( "getOrigin", NULL, 'v' );
65 const idEventDef EV_SetOrigin( "setOrigin", "v" );
66 const idEventDef EV_GetAngles( "getAngles", NULL, 'v' );
67 const idEventDef EV_SetAngles( "setAngles", "v" );
68 const idEventDef EV_GetLinearVelocity( "getLinearVelocity", NULL, 'v' );
69 const idEventDef EV_SetLinearVelocity( "setLinearVelocity", "v" );
70 const idEventDef EV_GetAngularVelocity( "getAngularVelocity", NULL, 'v' );
71 const idEventDef EV_SetAngularVelocity( "setAngularVelocity", "v" );
72 const idEventDef EV_GetSize( "getSize", NULL, 'v' );
73 const idEventDef EV_SetSize( "setSize", "vv" );
74 const idEventDef EV_GetMins( "getMins", NULL, 'v' );
75 const idEventDef EV_GetMaxs( "getMaxs", NULL, 'v' );
76 const idEventDef EV_IsHidden( "isHidden", NULL, 'd' );
77 const idEventDef EV_Hide( "hide", NULL );
78 const idEventDef EV_Show( "show", NULL );
79 const idEventDef EV_Touches( "touches", "E", 'd' );
80 const idEventDef EV_ClearSignal( "clearSignal", "d" );
81 const idEventDef EV_GetShaderParm( "getShaderParm", "d", 'f' );
82 const idEventDef EV_SetShaderParm( "setShaderParm", "df" );
83 const idEventDef EV_SetShaderParms( "setShaderParms", "ffff" );
84 const idEventDef EV_SetColor( "setColor", "fff" );
85 const idEventDef EV_GetColor( "getColor", NULL, 'v' );
86 const idEventDef EV_CacheSoundShader( "cacheSoundShader", "s" );
87 const idEventDef EV_StartSoundShader( "startSoundShader", "sd", 'f' );
88 const idEventDef EV_StartSound( "startSound", "sdd", 'f' );
89 const idEventDef EV_StopSound( "stopSound", "dd" );
90 const idEventDef EV_FadeSound( "fadeSound", "dff" );
91 const idEventDef EV_SetGuiParm( "setGuiParm", "ss" );
92 const idEventDef EV_SetGuiFloat( "setGuiFloat", "sf" );
93 const idEventDef EV_GetNextKey( "getNextKey", "ss", 's' );
94 const idEventDef EV_SetKey( "setKey", "ss" );
95 const idEventDef EV_GetKey( "getKey", "s", 's' );
96 const idEventDef EV_GetIntKey( "getIntKey", "s", 'f' );
97 const idEventDef EV_GetFloatKey( "getFloatKey", "s", 'f' );
98 const idEventDef EV_GetVectorKey( "getVectorKey", "s", 'v' );
99 const idEventDef EV_GetEntityKey( "getEntityKey", "s", 'e' );
100 const idEventDef EV_RestorePosition( "restorePosition" );
101 const idEventDef EV_UpdateCameraTarget( "<updateCameraTarget>", NULL );
102 const idEventDef EV_DistanceTo( "distanceTo", "E", 'f' );
103 const idEventDef EV_DistanceToPoint( "distanceToPoint", "v", 'f' );
104 const idEventDef EV_StartFx( "startFx", "s" );
105 const idEventDef EV_HasFunction( "hasFunction", "s", 'd' );
106 const idEventDef EV_CallFunction( "callFunction", "s" );
107 const idEventDef EV_SetNeverDormant( "setNeverDormant", "d" );
108 #ifdef _D3XP
109 const idEventDef EV_SetGui ( "setGui", "ds" );
110 const idEventDef EV_PrecacheGui ( "precacheGui", "s" );
111 const idEventDef EV_GetGuiParm ( "getGuiParm", "ds", 's' );
112 const idEventDef EV_GetGuiParmFloat ( "getGuiParmFloat", "ds", 'f' );
113 const idEventDef EV_MotionBlurOn( "motionBlurOn" );
114 const idEventDef EV_MotionBlurOff( "motionBlurOff" );
115 const idEventDef EV_GuiNamedEvent ( "guiNamedEvent", "ds" );
116 #endif
117 
119  EVENT( EV_GetName, idEntity::Event_GetName )
120  EVENT( EV_SetName, idEntity::Event_SetName )
121  EVENT( EV_FindTargets, idEntity::Event_FindTargets )
122  EVENT( EV_ActivateTargets, idEntity::Event_ActivateTargets )
123  EVENT( EV_NumTargets, idEntity::Event_NumTargets )
124  EVENT( EV_GetTarget, idEntity::Event_GetTarget )
125  EVENT( EV_RandomTarget, idEntity::Event_RandomTarget )
126  EVENT( EV_BindToJoint, idEntity::Event_BindToJoint )
127  EVENT( EV_RemoveBinds, idEntity::Event_RemoveBinds )
128  EVENT( EV_Bind, idEntity::Event_Bind )
129  EVENT( EV_BindPosition, idEntity::Event_BindPosition )
130  EVENT( EV_Unbind, idEntity::Event_Unbind )
131  EVENT( EV_SpawnBind, idEntity::Event_SpawnBind )
132  EVENT( EV_SetOwner, idEntity::Event_SetOwner )
133  EVENT( EV_SetModel, idEntity::Event_SetModel )
134  EVENT( EV_SetSkin, idEntity::Event_SetSkin )
135  EVENT( EV_GetShaderParm, idEntity::Event_GetShaderParm )
136  EVENT( EV_SetShaderParm, idEntity::Event_SetShaderParm )
137  EVENT( EV_SetShaderParms, idEntity::Event_SetShaderParms )
138  EVENT( EV_SetColor, idEntity::Event_SetColor )
139  EVENT( EV_GetColor, idEntity::Event_GetColor )
140  EVENT( EV_IsHidden, idEntity::Event_IsHidden )
141  EVENT( EV_Hide, idEntity::Event_Hide )
142  EVENT( EV_Show, idEntity::Event_Show )
143  EVENT( EV_CacheSoundShader, idEntity::Event_CacheSoundShader )
144  EVENT( EV_StartSoundShader, idEntity::Event_StartSoundShader )
145  EVENT( EV_StartSound, idEntity::Event_StartSound )
146  EVENT( EV_StopSound, idEntity::Event_StopSound )
147  EVENT( EV_FadeSound, idEntity::Event_FadeSound )
148  EVENT( EV_GetWorldOrigin, idEntity::Event_GetWorldOrigin )
149  EVENT( EV_SetWorldOrigin, idEntity::Event_SetWorldOrigin )
150  EVENT( EV_GetOrigin, idEntity::Event_GetOrigin )
151  EVENT( EV_SetOrigin, idEntity::Event_SetOrigin )
152  EVENT( EV_GetAngles, idEntity::Event_GetAngles )
153  EVENT( EV_SetAngles, idEntity::Event_SetAngles )
154  EVENT( EV_GetLinearVelocity, idEntity::Event_GetLinearVelocity )
155  EVENT( EV_SetLinearVelocity, idEntity::Event_SetLinearVelocity )
156  EVENT( EV_GetAngularVelocity, idEntity::Event_GetAngularVelocity )
157  EVENT( EV_SetAngularVelocity, idEntity::Event_SetAngularVelocity )
158  EVENT( EV_GetSize, idEntity::Event_GetSize )
159  EVENT( EV_SetSize, idEntity::Event_SetSize )
160  EVENT( EV_GetMins, idEntity::Event_GetMins)
161  EVENT( EV_GetMaxs, idEntity::Event_GetMaxs )
162  EVENT( EV_Touches, idEntity::Event_Touches )
163  EVENT( EV_SetGuiParm, idEntity::Event_SetGuiParm )
164  EVENT( EV_SetGuiFloat, idEntity::Event_SetGuiFloat )
165  EVENT( EV_GetNextKey, idEntity::Event_GetNextKey )
166  EVENT( EV_SetKey, idEntity::Event_SetKey )
167  EVENT( EV_GetKey, idEntity::Event_GetKey )
168  EVENT( EV_GetIntKey, idEntity::Event_GetIntKey )
169  EVENT( EV_GetFloatKey, idEntity::Event_GetFloatKey )
170  EVENT( EV_GetVectorKey, idEntity::Event_GetVectorKey )
171  EVENT( EV_GetEntityKey, idEntity::Event_GetEntityKey )
172  EVENT( EV_RestorePosition, idEntity::Event_RestorePosition )
173  EVENT( EV_UpdateCameraTarget, idEntity::Event_UpdateCameraTarget )
174  EVENT( EV_DistanceTo, idEntity::Event_DistanceTo )
175  EVENT( EV_DistanceToPoint, idEntity::Event_DistanceToPoint )
176  EVENT( EV_StartFx, idEntity::Event_StartFx )
177  EVENT( EV_Thread_WaitFrame, idEntity::Event_WaitFrame )
178  EVENT( EV_Thread_Wait, idEntity::Event_Wait )
179  EVENT( EV_HasFunction, idEntity::Event_HasFunction )
180  EVENT( EV_CallFunction, idEntity::Event_CallFunction )
181  EVENT( EV_SetNeverDormant, idEntity::Event_SetNeverDormant )
182 #ifdef _D3XP
183  EVENT( EV_SetGui, idEntity::Event_SetGui )
184  EVENT( EV_PrecacheGui, idEntity::Event_PrecacheGui )
185  EVENT( EV_GetGuiParm, idEntity::Event_GetGuiParm )
186  EVENT( EV_GetGuiParmFloat, idEntity::Event_GetGuiParmFloat )
187  EVENT( EV_GuiNamedEvent, idEntity::Event_GuiNamedEvent )
188 #endif
189 END_CLASS
190 
191 /*
192 ================
193 UpdateGuiParms
194 ================
195 */
196 void UpdateGuiParms( idUserInterface *gui, const idDict *args ) {
197  if ( gui == NULL || args == NULL ) {
198  return;
199  }
200  const idKeyValue *kv = args->MatchPrefix( "gui_parm", NULL );
201  while( kv ) {
202  gui->SetStateString( kv->GetKey(), kv->GetValue() );
203  kv = args->MatchPrefix( "gui_parm", kv );
204  }
205  gui->SetStateBool( "noninteractive", args->GetBool( "gui_noninteractive" ) ) ;
206  gui->StateChanged( gameLocal.time );
207 }
208 
209 /*
210 ================
211 AddRenderGui
212 ================
213 */
214 void AddRenderGui( const char *name, idUserInterface **gui, const idDict *args ) {
215  const idKeyValue *kv = args->MatchPrefix( "gui_parm", NULL );
216  *gui = uiManager->FindGui( name, true, ( kv != NULL ) );
217  UpdateGuiParms( *gui, args );
218 }
219 
220 /*
221 ================
222 idGameEdit::ParseSpawnArgsToRenderEntity
223 
224 parse the static model parameters
225 this is the canonical renderEntity parm parsing,
226 which should be used by dmap and the editor
227 ================
228 */
230  int i;
231  const char *temp;
232  idVec3 color;
233  float angle;
234  const idDeclModelDef *modelDef;
235 
236  memset( renderEntity, 0, sizeof( *renderEntity ) );
237 
238  temp = args->GetString( "model" );
239 
240  modelDef = NULL;
241  if ( temp[0] != '\0' ) {
242  modelDef = static_cast<const idDeclModelDef *>( declManager->FindType( DECL_MODELDEF, temp, false ) );
243  if ( modelDef ) {
244  renderEntity->hModel = modelDef->ModelHandle();
245  }
246  if ( !renderEntity->hModel ) {
247  renderEntity->hModel = renderModelManager->FindModel( temp );
248  }
249  }
250  if ( renderEntity->hModel ) {
251  renderEntity->bounds = renderEntity->hModel->Bounds( renderEntity );
252  } else {
253  renderEntity->bounds.Zero();
254  }
255 
256  temp = args->GetString( "skin" );
257  if ( temp[0] != '\0' ) {
258  renderEntity->customSkin = declManager->FindSkin( temp );
259  } else if ( modelDef ) {
260  renderEntity->customSkin = modelDef->GetDefaultSkin();
261  }
262 
263  temp = args->GetString( "shader" );
264  if ( temp[0] != '\0' ) {
265  renderEntity->customShader = declManager->FindMaterial( temp );
266  }
267 
268  args->GetVector( "origin", "0 0 0", renderEntity->origin );
269 
270  // get the rotation matrix in either full form, or single angle form
271  if ( !args->GetMatrix( "rotation", "1 0 0 0 1 0 0 0 1", renderEntity->axis ) ) {
272  angle = args->GetFloat( "angle" );
273  if ( angle != 0.0f ) {
274  renderEntity->axis = idAngles( 0.0f, angle, 0.0f ).ToMat3();
275  } else {
276  renderEntity->axis.Identity();
277  }
278  }
279 
280  renderEntity->referenceSound = NULL;
281 
282  // get shader parms
283  args->GetVector( "_color", "1 1 1", color );
284  renderEntity->shaderParms[ SHADERPARM_RED ] = color[0];
285  renderEntity->shaderParms[ SHADERPARM_GREEN ] = color[1];
286  renderEntity->shaderParms[ SHADERPARM_BLUE ] = color[2];
287  renderEntity->shaderParms[ 3 ] = args->GetFloat( "shaderParm3", "1" );
288  renderEntity->shaderParms[ 4 ] = args->GetFloat( "shaderParm4", "0" );
289  renderEntity->shaderParms[ 5 ] = args->GetFloat( "shaderParm5", "0" );
290  renderEntity->shaderParms[ 6 ] = args->GetFloat( "shaderParm6", "0" );
291  renderEntity->shaderParms[ 7 ] = args->GetFloat( "shaderParm7", "0" );
292  renderEntity->shaderParms[ 8 ] = args->GetFloat( "shaderParm8", "0" );
293  renderEntity->shaderParms[ 9 ] = args->GetFloat( "shaderParm9", "0" );
294  renderEntity->shaderParms[ 10 ] = args->GetFloat( "shaderParm10", "0" );
295  renderEntity->shaderParms[ 11 ] = args->GetFloat( "shaderParm11", "0" );
296 
297  // check noDynamicInteractions flag
298  renderEntity->noDynamicInteractions = args->GetBool( "noDynamicInteractions" );
299 
300  // check noshadows flag
301  renderEntity->noShadow = args->GetBool( "noshadows" );
302 
303  // check noselfshadows flag
304  renderEntity->noSelfShadow = args->GetBool( "noselfshadows" );
305 
306  // init any guis, including entity-specific states
307  for( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) {
308  temp = args->GetString( i == 0 ? "gui" : va( "gui%d", i + 1 ) );
309  if ( temp[ 0 ] != '\0' ) {
310  AddRenderGui( temp, &renderEntity->gui[ i ], args );
311  }
312  }
313 }
314 
315 /*
316 ================
317 idGameEdit::ParseSpawnArgsToRefSound
318 
319 parse the sound parameters
320 this is the canonical refSound parm parsing,
321 which should be used by dmap and the editor
322 ================
323 */
325  const char *temp;
326 
327  memset( refSound, 0, sizeof( *refSound ) );
328 
329  refSound->parms.minDistance = args->GetFloat( "s_mindistance" );
330  refSound->parms.maxDistance = args->GetFloat( "s_maxdistance" );
331  refSound->parms.volume = args->GetFloat( "s_volume" );
332  refSound->parms.shakes = args->GetFloat( "s_shakes" );
333 
334  args->GetVector( "origin", "0 0 0", refSound->origin );
335 
336  refSound->referenceSound = NULL;
337 
338  // if a diversity is not specified, every sound start will make
339  // a random one. Specifying diversity is usefull to make multiple
340  // lights all share the same buzz sound offset, for instance.
341  refSound->diversity = args->GetFloat( "s_diversity", "-1" );
342  refSound->waitfortrigger = args->GetBool( "s_waitfortrigger" );
343 
344  if ( args->GetBool( "s_omni" ) ) {
345  refSound->parms.soundShaderFlags |= SSF_OMNIDIRECTIONAL;
346  }
347  if ( args->GetBool( "s_looping" ) ) {
348  refSound->parms.soundShaderFlags |= SSF_LOOPING;
349  }
350  if ( args->GetBool( "s_occlusion" ) ) {
351  refSound->parms.soundShaderFlags |= SSF_NO_OCCLUSION;
352  }
353  if ( args->GetBool( "s_global" ) ) {
354  refSound->parms.soundShaderFlags |= SSF_GLOBAL;
355  }
356  if ( args->GetBool( "s_unclamped" ) ) {
357  refSound->parms.soundShaderFlags |= SSF_UNCLAMPED;
358  }
359  refSound->parms.soundClass = args->GetInt( "s_soundClass" );
360 
361  temp = args->GetString( "s_shader" );
362  if ( temp[0] != '\0' ) {
363  refSound->shader = declManager->FindSound( temp );
364  }
365 }
366 
367 /*
368 ===============
369 idEntity::UpdateChangeableSpawnArgs
370 
371 Any key val pair that might change during the course of the game ( via a gui or whatever )
372 should be initialize here so a gui or other trigger can change something and have it updated
373 properly. An optional source may be provided if the values reside in an outside dictionary and
374 first need copied over to spawnArgs
375 ===============
376 */
378  int i;
379  const char *target;
380 
381  if ( !source ) {
382  source = &spawnArgs;
383  }
384  cameraTarget = NULL;
385  target = source->GetString( "cameraTarget" );
386  if ( target && target[0] ) {
387  // update the camera taget
388  PostEventMS( &EV_UpdateCameraTarget, 0 );
389  }
390 
391  for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) {
392  UpdateGuiParms( renderEntity.gui[ i ], source );
393  }
394 }
395 
396 /*
397 ================
398 idEntity::idEntity
399 ================
400 */
402 
404  entityDefNumber = -1;
405 
406  spawnNode.SetOwner( this );
407  activeNode.SetOwner( this );
408 
409  snapshotNode.SetOwner( this );
410  snapshotSequence = -1;
411  snapshotBits = 0;
412 
413  thinkFlags = 0;
414  dormantStart = 0;
415  cinematic = false;
416  renderView = NULL;
417  cameraTarget = NULL;
418  health = 0;
419 
420  physics = NULL;
421  bindMaster = NULL;
423  bindBody = -1;
424  teamMaster = NULL;
425  teamChain = NULL;
426  signals = NULL;
427 
428  memset( PVSAreas, 0, sizeof( PVSAreas ) );
429  numPVSAreas = -1;
430 
431  memset( &fl, 0, sizeof( fl ) );
432  fl.neverDormant = true; // most entities never go dormant
433 
434  memset( &renderEntity, 0, sizeof( renderEntity ) );
435  modelDefHandle = -1;
436  memset( &refSound, 0, sizeof( refSound ) );
437 
438  mpGUIState = -1;
439 
440 #ifdef _D3XP
441  memset( &xrayEntity, 0, sizeof( xrayEntity ) );
442 
443  timeGroup = TIME_GROUP1;
444  xrayEntityHandle = -1;
445  xraySkin = NULL;
446 
447  noGrab = false;
448 #endif
449 }
450 
451 /*
452 ================
453 idEntity::FixupLocalizedStrings
454 ================
455 */
457  for ( int i = 0; i < spawnArgs.GetNumKeyVals(); i++ ) {
458  const idKeyValue *kv = spawnArgs.GetKeyVal( i );
459  if ( idStr::Cmpn( kv->GetValue(), STRTABLE_ID, STRTABLE_ID_LENGTH ) == 0 ){
461  }
462  }
463 }
464 
465 /*
466 ================
467 idEntity::Spawn
468 ================
469 */
470 void idEntity::Spawn( void ) {
471  int i;
472  const char *temp;
473  idVec3 origin;
474  idMat3 axis;
475  const idKeyValue *networkSync;
476  const char *classname;
477  const char *scriptObjectName;
478 
479  gameLocal.RegisterEntity( this );
480 
481  spawnArgs.GetString( "classname", NULL, &classname );
482  const idDeclEntityDef *def = gameLocal.FindEntityDef( classname, false );
483  if ( def ) {
484  entityDefNumber = def->Index();
485  }
486 
488 
489  // parse static models the same way the editor display does
491 
493 
494 #ifdef _D3XP
495  noGrab = spawnArgs.GetBool( "noGrab", "0" );
496 
497  xraySkin = NULL;
499 
500  idStr str;
501  if ( spawnArgs.GetString( "skin_xray", "", str ) ) {
502  xraySkin = declManager->FindSkin( str.c_str() );
503  }
504 #endif
505 
506  // go dormant within 5 frames so that when the map starts most monsters are dormant
507  dormantStart = gameLocal.time - DELAY_DORMANT_TIME + gameLocal.msec * 5;
508 
509  origin = renderEntity.origin;
510  axis = renderEntity.axis;
511 
512  // do the audio parsing the same way dmap and the editor do
514 
515  // only play SCHANNEL_PRIVATE when sndworld->PlaceListener() is called with this listenerId
516  // don't spatialize sounds from the same entity
518 
519  cameraTarget = NULL;
520  temp = spawnArgs.GetString( "cameraTarget" );
521  if ( temp && temp[0] ) {
522  // update the camera taget
523  PostEventMS( &EV_UpdateCameraTarget, 0 );
524  }
525 
526  for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) {
528  }
529 
530  fl.solidForTeam = spawnArgs.GetBool( "solidForTeam", "0" );
531  fl.neverDormant = spawnArgs.GetBool( "neverDormant", "0" );
532  fl.hidden = spawnArgs.GetBool( "hide", "0" );
533  if ( fl.hidden ) {
534  // make sure we're hidden, since a spawn function might not set it up right
535  PostEventMS( &EV_Hide, 0 );
536  }
537  cinematic = spawnArgs.GetBool( "cinematic", "0" );
538 
539  networkSync = spawnArgs.FindKey( "networkSync" );
540  if ( networkSync ) {
541  fl.networkSync = ( atoi( networkSync->GetValue() ) != 0 );
542  }
543 
544 #if 0
545  if ( !gameLocal.isClient ) {
546  // common->DPrintf( "NET: DBG %s - %s is synced: %s\n", spawnArgs.GetString( "classname", "" ), GetType()->classname, fl.networkSync ? "true" : "false" );
547  if ( spawnArgs.GetString( "classname", "" )[ 0 ] == '\0' && !fl.networkSync ) {
548  common->DPrintf( "NET: WRN %s entity, no classname, and no networkSync?\n", GetType()->classname );
549  }
550  }
551 #endif
552 
553  // every object will have a unique name
554  temp = spawnArgs.GetString( "name", va( "%s_%s_%d", GetClassname(), spawnArgs.GetString( "classname" ), entityNumber ) );
555  SetName( temp );
556 
557  // if we have targets, wait until all entities are spawned to get them
558  if ( spawnArgs.MatchPrefix( "target" ) || spawnArgs.MatchPrefix( "guiTarget" ) ) {
560  PostEventMS( &EV_FindTargets, 0 );
561  } else {
562  // not during spawn, so it's ok to get the targets
563  FindTargets();
564  }
565  }
566 
567  health = spawnArgs.GetInt( "health" );
568 
569  InitDefaultPhysics( origin, axis );
570 
571  SetOrigin( origin );
572  SetAxis( axis );
573 
574  temp = spawnArgs.GetString( "model" );
575  if ( temp && *temp ) {
576  SetModel( temp );
577  }
578 
579  if ( spawnArgs.GetString( "bind", "", &temp ) ) {
580  PostEventMS( &EV_SpawnBind, 0 );
581  }
582 
583  // auto-start a sound on the entity
586  }
587 
588  // setup script object
589  if ( ShouldConstructScriptObjectAtSpawn() && spawnArgs.GetString( "scriptobject", NULL, &scriptObjectName ) ) {
590  if ( !scriptObject.SetType( scriptObjectName ) ) {
591  gameLocal.Error( "Script object '%s' not found on entity '%s'.", scriptObjectName, name.c_str() );
592  }
593 
595  }
596 
597 #ifdef _D3XP
598  // determine time group
599  DetermineTimeGroup( spawnArgs.GetBool( "slowmo", "1" ) );
600 #endif
601 }
602 
603 /*
604 ================
605 idEntity::~idEntity
606 ================
607 */
609 
611  idBitMsg msg;
612  byte msgBuf[ MAX_GAME_MESSAGE_SIZE ];
613 
614  msg.Init( msgBuf, sizeof( msgBuf ) );
616  msg.WriteBits( gameLocal.GetSpawnId( this ), 32 );
618  }
619 
621  scriptObject.Free();
622 
623  if ( thinkFlags ) {
625  }
626  activeNode.Remove();
627 
628  Signal( SIG_REMOVED );
629 
630  // we have to set back the default physics object before unbinding because the entity
631  // specific physics object might be an entity variable and as such could already be destroyed.
632  SetPhysics( NULL );
633 
634  // remove any entities that are bound to me
635  RemoveBinds();
636 
637  // unbind from master
638  Unbind();
639  QuitTeam();
640 
641  gameLocal.RemoveEntityFromHash( name.c_str(), this );
642 
643  delete renderView;
644  renderView = NULL;
645 
646  delete signals;
647  signals = NULL;
648 
649  FreeModelDef();
650  FreeSoundEmitter( false );
651 
652 #ifdef _D3XP
653  if ( xrayEntityHandle != -1) {
654  gameRenderWorld->FreeEntityDef( xrayEntityHandle );
655  xrayEntityHandle = -1;
656  }
657 #endif
658 
659  gameLocal.UnregisterEntity( this );
660 }
661 
662 /*
663 ================
664 idEntity::Save
665 ================
666 */
667 void idEntity::Save( idSaveGame *savefile ) const {
668  int i, j;
669 
670  savefile->WriteInt( entityNumber );
671  savefile->WriteInt( entityDefNumber );
672 
673  // spawnNode and activeNode are restored by gameLocal
674 
675  savefile->WriteInt( snapshotSequence );
676  savefile->WriteInt( snapshotBits );
677 
678  savefile->WriteDict( &spawnArgs );
679  savefile->WriteString( name );
680  scriptObject.Save( savefile );
681 
682  savefile->WriteInt( thinkFlags );
683  savefile->WriteInt( dormantStart );
684  savefile->WriteBool( cinematic );
685 
686  savefile->WriteObject( cameraTarget );
687 
688  savefile->WriteInt( health );
689 
690  savefile->WriteInt( targets.Num() );
691  for( i = 0; i < targets.Num(); i++ ) {
692  targets[ i ].Save( savefile );
693  }
694 
695  entityFlags_s flags = fl;
696  LittleBitField( &flags, sizeof( flags ) );
697  savefile->Write( &flags, sizeof( flags ) );
698 
699 #ifdef _D3XP
700  savefile->WriteInt( timeGroup );
701  savefile->WriteBool( noGrab );
702  savefile->WriteRenderEntity( xrayEntity );
703  savefile->WriteInt( xrayEntityHandle );
704  savefile->WriteSkin( xraySkin );
705 #endif
706 
707  savefile->WriteRenderEntity( renderEntity );
708  savefile->WriteInt( modelDefHandle );
709  savefile->WriteRefSound( refSound );
710 
711  savefile->WriteObject( bindMaster );
712  savefile->WriteJoint( bindJoint );
713  savefile->WriteInt( bindBody );
714  savefile->WriteObject( teamMaster );
715  savefile->WriteObject( teamChain );
716 
718 
719  savefile->WriteInt( numPVSAreas );
720  for( i = 0; i < MAX_PVS_AREAS; i++ ) {
721  savefile->WriteInt( PVSAreas[ i ] );
722  }
723 
724  if ( !signals ) {
725  savefile->WriteBool( false );
726  } else {
727  savefile->WriteBool( true );
728  for( i = 0; i < NUM_SIGNALS; i++ ) {
729  savefile->WriteInt( signals->signal[ i ].Num() );
730  for( j = 0; j < signals->signal[ i ].Num(); j++ ) {
731  savefile->WriteInt( signals->signal[ i ][ j ].threadnum );
732  savefile->WriteString( signals->signal[ i ][ j ].function->Name() );
733  }
734  }
735  }
736 
737  savefile->WriteInt( mpGUIState );
738 }
739 
740 /*
741 ================
742 idEntity::Restore
743 ================
744 */
745 void idEntity::Restore( idRestoreGame *savefile ) {
746  int i, j;
747  int num;
748  idStr funcname;
749 
750  savefile->ReadInt( entityNumber );
751  savefile->ReadInt( entityDefNumber );
752 
753  // spawnNode and activeNode are restored by gameLocal
754 
755  savefile->ReadInt( snapshotSequence );
756  savefile->ReadInt( snapshotBits );
757 
758  savefile->ReadDict( &spawnArgs );
759  savefile->ReadString( name );
760  SetName( name );
761 
762  scriptObject.Restore( savefile );
763 
764  savefile->ReadInt( thinkFlags );
765  savefile->ReadInt( dormantStart );
766  savefile->ReadBool( cinematic );
767 
768  savefile->ReadObject( reinterpret_cast<idClass *&>( cameraTarget ) );
769 
770  savefile->ReadInt( health );
771 
772  targets.Clear();
773  savefile->ReadInt( num );
774  targets.SetNum( num );
775  for( i = 0; i < num; i++ ) {
776  targets[ i ].Restore( savefile );
777  }
778 
779  savefile->Read( &fl, sizeof( fl ) );
780  LittleBitField( &fl, sizeof( fl ) );
781 
782 #ifdef _D3XP
783  savefile->ReadInt( timeGroup );
784  savefile->ReadBool( noGrab );
785  savefile->ReadRenderEntity( xrayEntity );
786  savefile->ReadInt( xrayEntityHandle );
787  if ( xrayEntityHandle != -1 ) {
788  xrayEntityHandle = gameRenderWorld->AddEntityDef( &xrayEntity );
789  }
790  savefile->ReadSkin( xraySkin );
791 #endif
792 
793  savefile->ReadRenderEntity( renderEntity );
794  savefile->ReadInt( modelDefHandle );
795  savefile->ReadRefSound( refSound );
796 
797  savefile->ReadObject( reinterpret_cast<idClass *&>( bindMaster ) );
798  savefile->ReadJoint( bindJoint );
799  savefile->ReadInt( bindBody );
800  savefile->ReadObject( reinterpret_cast<idClass *&>( teamMaster ) );
801  savefile->ReadObject( reinterpret_cast<idClass *&>( teamChain ) );
802 
803  savefile->ReadStaticObject( defaultPhysicsObj );
805 
806  savefile->ReadInt( numPVSAreas );
807  for( i = 0; i < MAX_PVS_AREAS; i++ ) {
808  savefile->ReadInt( PVSAreas[ i ] );
809  }
810 
811  bool readsignals;
812  savefile->ReadBool( readsignals );
813  if ( readsignals ) {
814  signals = new signalList_t;
815  for( i = 0; i < NUM_SIGNALS; i++ ) {
816  savefile->ReadInt( num );
817  signals->signal[ i ].SetNum( num );
818  for( j = 0; j < num; j++ ) {
819  savefile->ReadInt( signals->signal[ i ][ j ].threadnum );
820  savefile->ReadString( funcname );
821  signals->signal[ i ][ j ].function = gameLocal.program.FindFunction( funcname );
822  if ( !signals->signal[ i ][ j ].function ) {
823  savefile->Error( "Function '%s' not found", funcname.c_str() );
824  }
825  }
826  }
827  }
828 
829  savefile->ReadInt( mpGUIState );
830 
831  // restore must retrieve modelDefHandle from the renderer
832  if ( modelDefHandle != -1 ) {
834  }
835 }
836 
837 /*
838 ================
839 idEntity::GetEntityDefName
840 ================
841 */
842 const char * idEntity::GetEntityDefName( void ) const {
843  if ( entityDefNumber < 0 ) {
844  return "*unknown*";
845  }
847 }
848 
849 /*
850 ================
851 idEntity::SetName
852 ================
853 */
854 void idEntity::SetName( const char *newname ) {
855  if ( name.Length() ) {
856  gameLocal.RemoveEntityFromHash( name.c_str(), this );
858  }
859 
860  name = newname;
861  if ( name.Length() ) {
862  if ( ( name == "NULL" ) || ( name == "null_entity" ) ) {
863  gameLocal.Error( "Cannot name entity '%s'. '%s' is reserved for script.", name.c_str(), name.c_str() );
864  }
865  gameLocal.AddEntityToHash( name.c_str(), this );
866  gameLocal.program.SetEntity( name, this );
867  }
868 }
869 
870 /*
871 ================
872 idEntity::GetName
873 ================
874 */
875 const char * idEntity::GetName( void ) const {
876  return name.c_str();
877 }
878 
879 
880 /***********************************************************************
881 
882  Thinking
883 
884 ***********************************************************************/
885 
886 /*
887 ================
888 idEntity::Think
889 ================
890 */
891 void idEntity::Think( void ) {
892  RunPhysics();
893  Present();
894 }
895 
896 /*
897 ================
898 idEntity::DoDormantTests
899 
900 Monsters and other expensive entities that are completely closed
901 off from the player can skip all of their work
902 ================
903 */
905 
906  if ( fl.neverDormant ) {
907  return false;
908  }
909 
910  // if the monster area is not topologically connected to a player
911  if ( !gameLocal.InPlayerConnectedArea( this ) ) {
912  if ( dormantStart == 0 ) {
914  }
915  if ( gameLocal.time - dormantStart < DELAY_DORMANT_TIME ) {
916  // just got closed off, don't go dormant yet
917  return false;
918  }
919  return true;
920  } else {
921  // the monster area is topologically connected to a player, but if
922  // the monster hasn't been woken up before, do the more precise PVS check
923  if ( !fl.hasAwakened ) {
924  if ( !gameLocal.InPlayerPVS( this ) ) {
925  return true; // stay dormant
926  }
927  }
928 
929  // wake up
930  dormantStart = 0;
931  fl.hasAwakened = true; // only go dormant when area closed off now, not just out of PVS
932  return false;
933  }
934 
935  return false;
936 }
937 
938 /*
939 ================
940 idEntity::CheckDormant
941 
942 Monsters and other expensive entities that are completely closed
943 off from the player can skip all of their work
944 ================
945 */
947  bool dormant;
948 
949  dormant = DoDormantTests();
950  if ( dormant && !fl.isDormant ) {
951  fl.isDormant = true;
952  DormantBegin();
953  } else if ( !dormant && fl.isDormant ) {
954  fl.isDormant = false;
955  DormantEnd();
956  }
957 
958  return dormant;
959 }
960 
961 /*
962 ================
963 idEntity::DormantBegin
964 
965 called when entity becomes dormant
966 ================
967 */
969 }
970 
971 /*
972 ================
973 idEntity::DormantEnd
974 
975 called when entity wakes from being dormant
976 ================
977 */
978 void idEntity::DormantEnd( void ) {
979 }
980 
981 /*
982 ================
983 idEntity::IsActive
984 ================
985 */
986 bool idEntity::IsActive( void ) const {
987  return activeNode.InList();
988 }
989 
990 /*
991 ================
992 idEntity::BecomeActive
993 ================
994 */
995 void idEntity::BecomeActive( int flags ) {
996  if ( ( flags & TH_PHYSICS ) ) {
997  // enable the team master if this entity is part of a physics team
998  if ( teamMaster && teamMaster != this ) {
999  teamMaster->BecomeActive( TH_PHYSICS );
1000  } else if ( !( thinkFlags & TH_PHYSICS ) ) {
1001  // if this is a pusher
1002  if ( physics->IsType( idPhysics_Parametric::Type ) || physics->IsType( idPhysics_Actor::Type ) ) {
1003  gameLocal.sortPushers = true;
1004  }
1005  }
1006  }
1007 
1008  int oldFlags = thinkFlags;
1009  thinkFlags |= flags;
1010  if ( thinkFlags ) {
1011  if ( !IsActive() ) {
1013  } else if ( !oldFlags ) {
1014  // we became inactive this frame, so we have to decrease the count of entities to deactivate
1016  }
1017  }
1018 }
1019 
1020 /*
1021 ================
1022 idEntity::BecomeInactive
1023 ================
1024 */
1025 void idEntity::BecomeInactive( int flags ) {
1026  if ( ( flags & TH_PHYSICS ) ) {
1027  // may only disable physics on a team master if no team members are running physics or bound to a joints
1028  if ( teamMaster == this ) {
1029  for ( idEntity *ent = teamMaster->teamChain; ent; ent = ent->teamChain ) {
1030  if ( ( ent->thinkFlags & TH_PHYSICS ) || ( ( ent->bindMaster == this ) && ( ent->bindJoint != INVALID_JOINT ) ) ) {
1031  flags &= ~TH_PHYSICS;
1032  break;
1033  }
1034  }
1035  }
1036  }
1037 
1038  if ( thinkFlags ) {
1039  thinkFlags &= ~flags;
1040  if ( !thinkFlags && IsActive() ) {
1042  }
1043  }
1044 
1045  if ( ( flags & TH_PHYSICS ) ) {
1046  // if this entity has a team master
1047  if ( teamMaster && teamMaster != this ) {
1048  // if the team master is at rest
1049  if ( teamMaster->IsAtRest() ) {
1050  teamMaster->BecomeInactive( TH_PHYSICS );
1051  }
1052  }
1053  }
1054 }
1055 
1056 /***********************************************************************
1057 
1058  Visuals
1059 
1060 ***********************************************************************/
1061 
1062 /*
1063 ================
1064 idEntity::SetShaderParm
1065 ================
1066 */
1067 void idEntity::SetShaderParm( int parmnum, float value ) {
1068  if ( ( parmnum < 0 ) || ( parmnum >= MAX_ENTITY_SHADER_PARMS ) ) {
1069  gameLocal.Warning( "shader parm index (%d) out of range", parmnum );
1070  return;
1071  }
1072 
1073  renderEntity.shaderParms[ parmnum ] = value;
1074  UpdateVisuals();
1075 }
1076 
1077 /*
1078 ================
1079 idEntity::SetColor
1080 ================
1081 */
1082 void idEntity::SetColor( float red, float green, float blue ) {
1086  UpdateVisuals();
1087 }
1088 
1089 /*
1090 ================
1091 idEntity::SetColor
1092 ================
1093 */
1095  SetColor( color[ 0 ], color[ 1 ], color[ 2 ] );
1096  UpdateVisuals();
1097 }
1098 
1099 /*
1100 ================
1101 idEntity::GetColor
1102 ================
1103 */
1104 void idEntity::GetColor( idVec3 &out ) const {
1105  out[ 0 ] = renderEntity.shaderParms[ SHADERPARM_RED ];
1108 }
1109 
1110 /*
1111 ================
1112 idEntity::SetColor
1113 ================
1114 */
1116  renderEntity.shaderParms[ SHADERPARM_RED ] = color[ 0 ];
1117  renderEntity.shaderParms[ SHADERPARM_GREEN ] = color[ 1 ];
1118  renderEntity.shaderParms[ SHADERPARM_BLUE ] = color[ 2 ];
1119  renderEntity.shaderParms[ SHADERPARM_ALPHA ] = color[ 3 ];
1120  UpdateVisuals();
1121 }
1122 
1123 /*
1124 ================
1125 idEntity::GetColor
1126 ================
1127 */
1128 void idEntity::GetColor( idVec4 &out ) const {
1129  out[ 0 ] = renderEntity.shaderParms[ SHADERPARM_RED ];
1133 }
1134 
1135 /*
1136 ================
1137 idEntity::UpdateAnimationControllers
1138 ================
1139 */
1141  // any ragdoll and IK animation controllers should be updated here
1142  return false;
1143 }
1144 
1145 /*
1146 ================
1147 idEntity::SetModel
1148 ================
1149 */
1150 void idEntity::SetModel( const char *modelname ) {
1151  assert( modelname );
1152 
1153  FreeModelDef();
1154 
1156 
1157  if ( renderEntity.hModel ) {
1159  }
1160 
1162  renderEntity.numJoints = 0;
1164  if ( renderEntity.hModel ) {
1166  } else {
1168  }
1169 
1170  UpdateVisuals();
1171 }
1172 
1173 /*
1174 ================
1175 idEntity::SetSkin
1176 ================
1177 */
1178 void idEntity::SetSkin( const idDeclSkin *skin ) {
1179  renderEntity.customSkin = skin;
1180  UpdateVisuals();
1181 }
1182 
1183 /*
1184 ================
1185 idEntity::GetSkin
1186 ================
1187 */
1188 const idDeclSkin *idEntity::GetSkin( void ) const {
1189  return renderEntity.customSkin;
1190 }
1191 
1192 /*
1193 ================
1194 idEntity::FreeModelDef
1195 ================
1196 */
1198  if ( modelDefHandle != -1 ) {
1200  modelDefHandle = -1;
1201  }
1202 }
1203 
1204 /*
1205 ================
1206 idEntity::FreeLightDef
1207 ================
1208 */
1210 }
1211 
1212 /*
1213 ================
1214 idEntity::IsHidden
1215 ================
1216 */
1217 bool idEntity::IsHidden( void ) const {
1218  return fl.hidden;
1219 }
1220 
1221 /*
1222 ================
1223 idEntity::Hide
1224 ================
1225 */
1226 void idEntity::Hide( void ) {
1227  if ( !IsHidden() ) {
1228  fl.hidden = true;
1229  FreeModelDef();
1230  UpdateVisuals();
1231  }
1232 }
1233 
1234 /*
1235 ================
1236 idEntity::Show
1237 ================
1238 */
1239 void idEntity::Show( void ) {
1240  if ( IsHidden() ) {
1241  fl.hidden = false;
1242  UpdateVisuals();
1243  }
1244 }
1245 
1246 /*
1247 ================
1248 idEntity::UpdateModelTransform
1249 ================
1250 */
1252  idVec3 origin;
1253  idMat3 axis;
1254 
1255  if ( GetPhysicsToVisualTransform( origin, axis ) ) {
1256  renderEntity.axis = axis * GetPhysics()->GetAxis();
1258  } else {
1261  }
1262 }
1263 
1264 /*
1265 ================
1266 idEntity::UpdateModel
1267 ================
1268 */
1270 #ifdef _D3XP
1271  renderEntity.timeGroup = timeGroup;
1272 #endif
1273 
1275 
1276  // check if the entity has an MD5 model
1277  idAnimator *animator = GetAnimator();
1278  if ( animator && animator->ModelHandle() ) {
1279  // set the callback to update the joints
1281  }
1282 
1283  // set to invalid number to force an update the next time the PVS areas are retrieved
1284  ClearPVSAreas();
1285 
1286  // ensure that we call Present this frame
1288 
1289 #ifdef _D3XP
1290  // If the entity has an xray skin, go ahead and add it
1291  if ( xraySkin != NULL ) {
1292  xrayEntity = renderEntity;
1293  xrayEntity.xrayIndex = 2;
1294  xrayEntity.customSkin = xraySkin;
1295 
1296  if ( xrayEntityHandle == -1 ) {
1297  xrayEntityHandle = gameRenderWorld->AddEntityDef( &xrayEntity );
1298  } else {
1299  gameRenderWorld->UpdateEntityDef( xrayEntityHandle, &xrayEntity );
1300  }
1301  }
1302 #endif
1303 }
1304 
1305 /*
1306 ================
1307 idEntity::UpdateVisuals
1308 ================
1309 */
1311  UpdateModel();
1312  UpdateSound();
1313 }
1314 
1315 /*
1316 ================
1317 idEntity::UpdatePVSAreas
1318 ================
1319 */
1321  int localNumPVSAreas, localPVSAreas[32];
1322  idBounds modelAbsBounds;
1323  int i;
1324 
1326  localNumPVSAreas = gameLocal.pvs.GetPVSAreas( modelAbsBounds, localPVSAreas, sizeof( localPVSAreas ) / sizeof( localPVSAreas[0] ) );
1327 
1328  // FIXME: some particle systems may have huge bounds and end up in many PVS areas
1329  // the first MAX_PVS_AREAS may not be visible to a network client and as a result the particle system may not show up when it should
1330  if ( localNumPVSAreas > MAX_PVS_AREAS ) {
1331  localNumPVSAreas = gameLocal.pvs.GetPVSAreas( idBounds( renderEntity.origin ).Expand( 64.0f ), localPVSAreas, sizeof( localPVSAreas ) / sizeof( localPVSAreas[0] ) );
1332  }
1333 
1334  for ( numPVSAreas = 0; numPVSAreas < MAX_PVS_AREAS && numPVSAreas < localNumPVSAreas; numPVSAreas++ ) {
1335  PVSAreas[numPVSAreas] = localPVSAreas[numPVSAreas];
1336  }
1337 
1338  for( i = numPVSAreas; i < MAX_PVS_AREAS; i++ ) {
1339  PVSAreas[ i ] = 0;
1340  }
1341 }
1342 
1343 /*
1344 ================
1345 idEntity::UpdatePVSAreas
1346 ================
1347 */
1348 void idEntity::UpdatePVSAreas( const idVec3 &pos ) {
1349  int i;
1350 
1352  i = numPVSAreas;
1353  while ( i < MAX_PVS_AREAS ) {
1354  PVSAreas[ i++ ] = 0;
1355  }
1356 }
1357 
1358 /*
1359 ================
1360 idEntity::GetNumPVSAreas
1361 ================
1362 */
1364  if ( numPVSAreas < 0 ) {
1365  UpdatePVSAreas();
1366  }
1367  return numPVSAreas;
1368 }
1369 
1370 /*
1371 ================
1372 idEntity::GetPVSAreas
1373 ================
1374 */
1375 const int *idEntity::GetPVSAreas( void ) {
1376  if ( numPVSAreas < 0 ) {
1377  UpdatePVSAreas();
1378  }
1379  return PVSAreas;
1380 }
1381 
1382 /*
1383 ================
1384 idEntity::ClearPVSAreas
1385 ================
1386 */
1388  numPVSAreas = -1;
1389 }
1390 
1391 /*
1392 ================
1393 idEntity::PhysicsTeamInPVS
1394 
1395  FIXME: for networking also return true if any of the entity shadows is in the PVS
1396 ================
1397 */
1399  idEntity *part;
1400 
1401  if ( teamMaster ) {
1402  for ( part = teamMaster; part; part = part->teamChain ) {
1403  if ( gameLocal.pvs.InCurrentPVS( pvsHandle, part->GetPVSAreas(), part->GetNumPVSAreas() ) ) {
1404  return true;
1405  }
1406  }
1407  } else {
1408  return gameLocal.pvs.InCurrentPVS( pvsHandle, GetPVSAreas(), GetNumPVSAreas() );
1409  }
1410  return false;
1411 }
1412 
1413 /*
1414 ==============
1415 idEntity::ProjectOverlay
1416 ==============
1417 */
1418 void idEntity::ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material ) {
1419  float s, c;
1420  idMat3 axis, axistemp;
1421  idVec3 localOrigin, localAxis[2];
1422  idPlane localPlane[2];
1423 
1424  // make sure the entity has a valid model handle
1425  if ( modelDefHandle < 0 ) {
1426  return;
1427  }
1428 
1429  // only do this on dynamic md5 models
1431  return;
1432  }
1433 
1435 
1436  axis[2] = -dir;
1437  axis[2].NormalVectors( axistemp[0], axistemp[1] );
1438  axis[0] = axistemp[ 0 ] * c + axistemp[ 1 ] * -s;
1439  axis[1] = axistemp[ 0 ] * -s + axistemp[ 1 ] * -c;
1440 
1441  renderEntity.axis.ProjectVector( origin - renderEntity.origin, localOrigin );
1442  renderEntity.axis.ProjectVector( axis[0], localAxis[0] );
1443  renderEntity.axis.ProjectVector( axis[1], localAxis[1] );
1444 
1445  size = 1.0f / size;
1446  localAxis[0] *= size;
1447  localAxis[1] *= size;
1448 
1449  localPlane[0] = localAxis[0];
1450  localPlane[0][3] = -( localOrigin * localAxis[0] ) + 0.5f;
1451 
1452  localPlane[1] = localAxis[1];
1453  localPlane[1][3] = -( localOrigin * localAxis[1] ) + 0.5f;
1454 
1455  const idMaterial *mtr = declManager->FindMaterial( material );
1456 
1457  // project an overlay onto the model
1458  gameRenderWorld->ProjectOverlay( modelDefHandle, localPlane, mtr );
1459 
1460  // make sure non-animating models update their overlay
1461  UpdateVisuals();
1462 }
1463 
1464 /*
1465 ================
1466 idEntity::Present
1467 
1468 Present is called to allow entities to generate refEntities, lights, etc for the renderer.
1469 ================
1470 */
1471 void idEntity::Present( void ) {
1472 
1473  if ( !gameLocal.isNewFrame ) {
1474  return;
1475  }
1476 
1477  // don't present to the renderer if the entity hasn't changed
1478  if ( !( thinkFlags & TH_UPDATEVISUALS ) ) {
1479  return;
1480  }
1481  BecomeInactive( TH_UPDATEVISUALS );
1482 
1483  // camera target for remote render views
1484  if ( cameraTarget && gameLocal.InPlayerPVS( this ) ) {
1486  }
1487 
1488  // if set to invisible, skip
1489  if ( !renderEntity.hModel || IsHidden() ) {
1490  return;
1491  }
1492 
1493  // add to refresh list
1494  if ( modelDefHandle == -1 ) {
1496  } else {
1498  }
1499 }
1500 
1501 /*
1502 ================
1503 idEntity::GetRenderEntity
1504 ================
1505 */
1507  return &renderEntity;
1508 }
1509 
1510 /*
1511 ================
1512 idEntity::GetModelDefHandle
1513 ================
1514 */
1516  return modelDefHandle;
1517 }
1518 
1519 /*
1520 ================
1521 idEntity::UpdateRenderEntity
1522 ================
1523 */
1524 bool idEntity::UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ) {
1526  return false;
1527  }
1528 
1529  idAnimator *animator = GetAnimator();
1530  if ( animator ) {
1531 #ifdef _D3XP
1532  SetTimeState ts( timeGroup );
1533 #endif
1534 
1535  return animator->CreateFrame( gameLocal.time, false );
1536  }
1537 
1538  return false;
1539 }
1540 
1541 /*
1542 ================
1543 idEntity::ModelCallback
1544 
1545  NOTE: may not change the game state whatsoever!
1546 ================
1547 */
1548 bool idEntity::ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView ) {
1549  idEntity *ent;
1550 
1551  ent = gameLocal.entities[ renderEntity->entityNum ];
1552  if ( !ent ) {
1553  gameLocal.Error( "idEntity::ModelCallback: callback with NULL game entity" );
1554  }
1555 
1556  return ent->UpdateRenderEntity( renderEntity, renderView );
1557 }
1558 
1559 /*
1560 ================
1561 idEntity::GetAnimator
1562 
1563 Subclasses will be responsible for allocating animator.
1564 ================
1565 */
1567  return NULL;
1568 }
1569 
1570 /*
1571 =============
1572 idEntity::GetRenderView
1573 
1574 This is used by remote camera views to look from an entity
1575 =============
1576 */
1578  if ( !renderView ) {
1579  renderView = new renderView_t;
1580  }
1581  memset( renderView, 0, sizeof( *renderView ) );
1582 
1584  renderView->fov_x = 120;
1585  renderView->fov_y = 120;
1587 
1588  // copy global shader parms
1589  for( int i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) {
1591  }
1592 
1594 
1596 
1597  return renderView;
1598 }
1599 
1600 /***********************************************************************
1601 
1602  Sound
1603 
1604 ***********************************************************************/
1605 
1606 /*
1607 ================
1608 idEntity::CanPlayChatterSounds
1609 
1610 Used for playing chatter sounds on monsters.
1611 ================
1612 */
1614  return true;
1615 }
1616 
1617 /*
1618 ================
1619 idEntity::StartSound
1620 ================
1621 */
1622 bool idEntity::StartSound( const char *soundName, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length ) {
1623  const idSoundShader *shader;
1624  const char *sound;
1625 
1626  if ( length ) {
1627  *length = 0;
1628  }
1629 
1630  // we should ALWAYS be playing sounds from the def.
1631  // hardcoded sounds MUST be avoided at all times because they won't get precached.
1632  assert( idStr::Icmpn( soundName, "snd_", 4 ) == 0 );
1633 
1634  if ( !spawnArgs.GetString( soundName, "", &sound ) ) {
1635  return false;
1636  }
1637 
1638  if ( sound[0] == '\0' ) {
1639  return false;
1640  }
1641 
1642  if ( !gameLocal.isNewFrame ) {
1643  // don't play the sound, but don't report an error
1644  return true;
1645  }
1646 
1647  shader = declManager->FindSound( sound );
1648  return StartSoundShader( shader, channel, soundShaderFlags, broadcast, length );
1649 }
1650 
1651 /*
1652 ================
1653 idEntity::StartSoundShader
1654 ================
1655 */
1656 bool idEntity::StartSoundShader( const idSoundShader *shader, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length ) {
1657  float diversity;
1658  int len;
1659 
1660  if ( length ) {
1661  *length = 0;
1662  }
1663 
1664  if ( !shader ) {
1665  return false;
1666  }
1667 
1668  if ( !gameLocal.isNewFrame ) {
1669  return true;
1670  }
1671 
1672  if ( gameLocal.isServer && broadcast ) {
1673  idBitMsg msg;
1674  byte msgBuf[MAX_EVENT_PARAM_SIZE];
1675 
1676  msg.Init( msgBuf, sizeof( msgBuf ) );
1677  msg.BeginWriting();
1678  msg.WriteLong( gameLocal.ServerRemapDecl( -1, DECL_SOUND, shader->Index() ) );
1679  msg.WriteByte( channel );
1680  ServerSendEvent( EVENT_STARTSOUNDSHADER, &msg, false, -1 );
1681  }
1682 
1683  // set a random value for diversity unless one was parsed from the entity
1684  if ( refSound.diversity < 0.0f ) {
1685  diversity = gameLocal.random.RandomFloat();
1686  } else {
1687  diversity = refSound.diversity;
1688  }
1689 
1690  // if we don't have a soundEmitter allocated yet, get one now
1691  if ( !refSound.referenceSound ) {
1693  }
1694 
1695  UpdateSound();
1696 
1697  len = refSound.referenceSound->StartSound( shader, channel, diversity, soundShaderFlags, !timeGroup /*_D3XP*/ );
1698  if ( length ) {
1699  *length = len;
1700  }
1701 
1702  // set reference to the sound for shader synced effects
1704 
1705  return true;
1706 }
1707 
1708 /*
1709 ================
1710 idEntity::StopSound
1711 ================
1712 */
1713 void idEntity::StopSound( const s_channelType channel, bool broadcast ) {
1714  if ( !gameLocal.isNewFrame ) {
1715  return;
1716  }
1717 
1718  if ( gameLocal.isServer && broadcast ) {
1719  idBitMsg msg;
1720  byte msgBuf[MAX_EVENT_PARAM_SIZE];
1721 
1722  msg.Init( msgBuf, sizeof( msgBuf ) );
1723  msg.BeginWriting();
1724  msg.WriteByte( channel );
1725  ServerSendEvent( EVENT_STOPSOUNDSHADER, &msg, false, -1 );
1726  }
1727 
1728  if ( refSound.referenceSound ) {
1729  refSound.referenceSound->StopSound( channel );
1730  }
1731 }
1732 
1733 /*
1734 ================
1735 idEntity::SetSoundVolume
1736 
1737  Must be called before starting a new sound.
1738 ================
1739 */
1740 void idEntity::SetSoundVolume( float volume ) {
1741  refSound.parms.volume = volume;
1742 }
1743 
1744 /*
1745 ================
1746 idEntity::UpdateSound
1747 ================
1748 */
1750  if ( refSound.referenceSound ) {
1751  idVec3 origin;
1752  idMat3 axis;
1753 
1754  if ( GetPhysicsToSoundTransform( origin, axis ) ) {
1755  refSound.origin = GetPhysics()->GetOrigin() + origin * axis;
1756  } else {
1758  }
1759 
1761  }
1762 }
1763 
1764 /*
1765 ================
1766 idEntity::GetListenerId
1767 ================
1768 */
1769 int idEntity::GetListenerId( void ) const {
1770  return refSound.listenerId;
1771 }
1772 
1773 /*
1774 ================
1775 idEntity::GetSoundEmitter
1776 ================
1777 */
1779  return refSound.referenceSound;
1780 }
1781 
1782 /*
1783 ================
1784 idEntity::FreeSoundEmitter
1785 ================
1786 */
1787 void idEntity::FreeSoundEmitter( bool immediate ) {
1788  if ( refSound.referenceSound ) {
1789  refSound.referenceSound->Free( immediate );
1791  }
1792 }
1793 
1794 /***********************************************************************
1795 
1796  entity binding
1797 
1798 ***********************************************************************/
1799 
1800 /*
1801 ================
1802 idEntity::PreBind
1803 ================
1804 */
1805 void idEntity::PreBind( void ) {
1806 }
1807 
1808 /*
1809 ================
1810 idEntity::PostBind
1811 ================
1812 */
1813 void idEntity::PostBind( void ) {
1814 }
1815 
1816 /*
1817 ================
1818 idEntity::PreUnbind
1819 ================
1820 */
1821 void idEntity::PreUnbind( void ) {
1822 }
1823 
1824 /*
1825 ================
1826 idEntity::PostUnbind
1827 ================
1828 */
1829 void idEntity::PostUnbind( void ) {
1830 }
1831 
1832 /*
1833 ================
1834 idEntity::InitBind
1835 ================
1836 */
1837 bool idEntity::InitBind( idEntity *master ) {
1838 
1839  if ( master == this ) {
1840  gameLocal.Error( "Tried to bind an object to itself." );
1841  return false;
1842  }
1843 
1844  if ( this == gameLocal.world ) {
1845  gameLocal.Error( "Tried to bind world to another entity" );
1846  return false;
1847  }
1848 
1849  // unbind myself from my master
1850  Unbind();
1851 
1852  // add any bind constraints to an articulated figure
1853  if ( master && IsType( idAFEntity_Base::Type ) ) {
1854  static_cast<idAFEntity_Base *>(this)->AddBindConstraints();
1855  }
1856 
1857  if ( !master || master == gameLocal.world ) {
1858  // this can happen in scripts, so safely exit out.
1859  return false;
1860  }
1861 
1862  return true;
1863 }
1864 
1865 /*
1866 ================
1867 idEntity::FinishBind
1868 ================
1869 */
1870 void idEntity::FinishBind( void ) {
1871 
1872  // set the master on the physics object
1874 
1875  // We are now separated from our previous team and are either
1876  // an individual, or have a team of our own. Now we can join
1877  // the new bindMaster's team. Bindmaster must be set before
1878  // joining the team, or we will be placed in the wrong position
1879  // on the team.
1880  JoinTeam( bindMaster );
1881 
1882  // if our bindMaster is enabled during a cinematic, we must be, too
1884 
1885  // make sure the team master is active so that physics get run
1887 }
1888 
1889 /*
1890 ================
1891 idEntity::Bind
1892 
1893  bind relative to the visual position of the master
1894 ================
1895 */
1896 void idEntity::Bind( idEntity *master, bool orientated ) {
1897 
1898  if ( !InitBind( master ) ) {
1899  return;
1900  }
1901 
1902  PreBind();
1903 
1905  bindBody = -1;
1906  bindMaster = master;
1907  fl.bindOrientated = orientated;
1908 
1909  FinishBind();
1910 
1911  PostBind( );
1912 }
1913 
1914 /*
1915 ================
1916 idEntity::BindToJoint
1917 
1918  bind relative to a joint of the md5 model used by the master
1919 ================
1920 */
1921 void idEntity::BindToJoint( idEntity *master, const char *jointname, bool orientated ) {
1922  jointHandle_t jointnum;
1923  idAnimator *masterAnimator;
1924 
1925  if ( !InitBind( master ) ) {
1926  return;
1927  }
1928 
1929  masterAnimator = master->GetAnimator();
1930  if ( !masterAnimator ) {
1931  gameLocal.Warning( "idEntity::BindToJoint: entity '%s' cannot support skeletal models.", master->GetName() );
1932  return;
1933  }
1934 
1935  jointnum = masterAnimator->GetJointHandle( jointname );
1936  if ( jointnum == INVALID_JOINT ) {
1937  gameLocal.Warning( "idEntity::BindToJoint: joint '%s' not found on entity '%s'.", jointname, master->GetName() );
1938  }
1939 
1940  PreBind();
1941 
1942  bindJoint = jointnum;
1943  bindBody = -1;
1944  bindMaster = master;
1945  fl.bindOrientated = orientated;
1946 
1947  FinishBind();
1948 
1949  PostBind();
1950 }
1951 
1952 /*
1953 ================
1954 idEntity::BindToJoint
1955 
1956  bind relative to a joint of the md5 model used by the master
1957 ================
1958 */
1959 void idEntity::BindToJoint( idEntity *master, jointHandle_t jointnum, bool orientated ) {
1960 
1961  if ( !InitBind( master ) ) {
1962  return;
1963  }
1964 
1965  PreBind();
1966 
1967  bindJoint = jointnum;
1968  bindBody = -1;
1969  bindMaster = master;
1970  fl.bindOrientated = orientated;
1971 
1972  FinishBind();
1973 
1974  PostBind();
1975 }
1976 
1977 /*
1978 ================
1979 idEntity::BindToBody
1980 
1981  bind relative to a collision model used by the physics of the master
1982 ================
1983 */
1984 void idEntity::BindToBody( idEntity *master, int bodyId, bool orientated ) {
1985 
1986  if ( !InitBind( master ) ) {
1987  return;
1988  }
1989 
1990  if ( bodyId < 0 ) {
1991  gameLocal.Warning( "idEntity::BindToBody: body '%d' not found.", bodyId );
1992  }
1993 
1994  PreBind();
1995 
1997  bindBody = bodyId;
1998  bindMaster = master;
1999  fl.bindOrientated = orientated;
2000 
2001  FinishBind();
2002 
2003  PostBind();
2004 }
2005 
2006 /*
2007 ================
2008 idEntity::Unbind
2009 ================
2010 */
2011 void idEntity::Unbind( void ) {
2012  idEntity * prev;
2013  idEntity * next;
2014  idEntity * last;
2015  idEntity * ent;
2016 
2017  // remove any bind constraints from an articulated figure
2018  if ( IsType( idAFEntity_Base::Type ) ) {
2019  static_cast<idAFEntity_Base *>(this)->RemoveBindConstraints();
2020  }
2021 
2022  if ( !bindMaster ) {
2023  return;
2024  }
2025 
2026  if ( !teamMaster ) {
2027  // Teammaster already has been freed
2028  bindMaster = NULL;
2029  return;
2030  }
2031 
2032  PreUnbind();
2033 
2034  if ( physics ) {
2036  }
2037 
2038  // We're still part of a team, so that means I have to extricate myself
2039  // and any entities that are bound to me from the old team.
2040  // Find the node previous to me in the team
2041  prev = teamMaster;
2042  for( ent = teamMaster->teamChain; ent && ( ent != this ); ent = ent->teamChain ) {
2043  prev = ent;
2044  }
2045 
2046  assert( ent == this ); // If ent is not pointing to this, then something is very wrong.
2047 
2048  // Find the last node in my team that is bound to me.
2049  // Also find the first node not bound to me, if one exists.
2050  last = this;
2051  for( next = teamChain; next != NULL; next = next->teamChain ) {
2052  if ( !next->IsBoundTo( this ) ) {
2053  break;
2054  }
2055 
2056  // Tell them I'm now the teamMaster
2057  next->teamMaster = this;
2058  last = next;
2059  }
2060 
2061  // disconnect the last member of our team from the old team
2062  last->teamChain = NULL;
2063 
2064  // connect up the previous member of the old team to the node that
2065  // follow the last node bound to me (if one exists).
2066  if ( teamMaster != this ) {
2067  prev->teamChain = next;
2068  if ( !next && ( teamMaster == prev ) ) {
2069  prev->teamMaster = NULL;
2070  }
2071  } else if ( next ) {
2072  // If we were the teamMaster, then the nodes that were not bound to me are now
2073  // a disconnected chain. Make them into their own team.
2074  for( ent = next; ent->teamChain != NULL; ent = ent->teamChain ) {
2075  ent->teamMaster = next;
2076  }
2077  next->teamMaster = next;
2078  }
2079 
2080  // If we don't have anyone on our team, then clear the team variables.
2081  if ( teamChain ) {
2082  // make myself my own team
2083  teamMaster = this;
2084  } else {
2085  // no longer a team
2086  teamMaster = NULL;
2087  }
2088 
2090  bindBody = -1;
2091  bindMaster = NULL;
2092 
2093  PostUnbind();
2094 }
2095 
2096 /*
2097 ================
2098 idEntity::RemoveBinds
2099 ================
2100 */
2102  idEntity *ent;
2103  idEntity *next;
2104 
2105  for( ent = teamChain; ent != NULL; ent = next ) {
2106  next = ent->teamChain;
2107  if ( ent->bindMaster == this ) {
2108  ent->Unbind();
2109  ent->PostEventMS( &EV_Remove, 0 );
2110  next = teamChain;
2111  }
2112  }
2113 }
2114 
2115 /*
2116 ================
2117 idEntity::IsBound
2118 ================
2119 */
2120 bool idEntity::IsBound( void ) const {
2121  if ( bindMaster ) {
2122  return true;
2123  }
2124  return false;
2125 }
2126 
2127 /*
2128 ================
2129 idEntity::IsBoundTo
2130 ================
2131 */
2132 bool idEntity::IsBoundTo( idEntity *master ) const {
2133  idEntity *ent;
2134 
2135  if ( !bindMaster ) {
2136  return false;
2137  }
2138 
2139  for ( ent = bindMaster; ent != NULL; ent = ent->bindMaster ) {
2140  if ( ent == master ) {
2141  return true;
2142  }
2143  }
2144 
2145  return false;
2146 }
2147 
2148 /*
2149 ================
2150 idEntity::GetBindMaster
2151 ================
2152 */
2154  return bindMaster;
2155 }
2156 
2157 /*
2158 ================
2159 idEntity::GetBindJoint
2160 ================
2161 */
2163  return bindJoint;
2164 }
2165 
2166 /*
2167 ================
2168 idEntity::GetBindBody
2169 ================
2170 */
2171 int idEntity::GetBindBody( void ) const {
2172  return bindBody;
2173 }
2174 
2175 /*
2176 ================
2177 idEntity::GetTeamMaster
2178 ================
2179 */
2181  return teamMaster;
2182 }
2183 
2184 /*
2185 ================
2186 idEntity::GetNextTeamEntity
2187 ================
2188 */
2190  return teamChain;
2191 }
2192 
2193 /*
2194 =====================
2195 idEntity::ConvertLocalToWorldTransform
2196 =====================
2197 */
2200 
2201  offset = renderEntity.origin + offset * renderEntity.axis;
2202  axis *= renderEntity.axis;
2203 }
2204 
2205 /*
2206 ================
2207 idEntity::GetLocalVector
2208 
2209 Takes a vector in worldspace and transforms it into the parent
2210 object's localspace.
2211 
2212 Note: Does not take origin into acount. Use getLocalCoordinate to
2213 convert coordinates.
2214 ================
2215 */
2217  idVec3 pos;
2218 
2219  if ( !bindMaster ) {
2220  return vec;
2221  }
2222 
2223  idVec3 masterOrigin;
2224  idMat3 masterAxis;
2225 
2226  GetMasterPosition( masterOrigin, masterAxis );
2227  masterAxis.ProjectVector( vec, pos );
2228 
2229  return pos;
2230 }
2231 
2232 /*
2233 ================
2234 idEntity::GetLocalCoordinates
2235 
2236 Takes a vector in world coordinates and transforms it into the parent
2237 object's local coordinates.
2238 ================
2239 */
2241  idVec3 pos;
2242 
2243  if ( !bindMaster ) {
2244  return vec;
2245  }
2246 
2247  idVec3 masterOrigin;
2248  idMat3 masterAxis;
2249 
2250  GetMasterPosition( masterOrigin, masterAxis );
2251  masterAxis.ProjectVector( vec - masterOrigin, pos );
2252 
2253  return pos;
2254 }
2255 
2256 /*
2257 ================
2258 idEntity::GetWorldVector
2259 
2260 Takes a vector in the parent object's local coordinates and transforms
2261 it into world coordinates.
2262 
2263 Note: Does not take origin into acount. Use getWorldCoordinate to
2264 convert coordinates.
2265 ================
2266 */
2268  idVec3 pos;
2269 
2270  if ( !bindMaster ) {
2271  return vec;
2272  }
2273 
2274  idVec3 masterOrigin;
2275  idMat3 masterAxis;
2276 
2277  GetMasterPosition( masterOrigin, masterAxis );
2278  masterAxis.UnprojectVector( vec, pos );
2279 
2280  return pos;
2281 }
2282 
2283 /*
2284 ================
2285 idEntity::GetWorldCoordinates
2286 
2287 Takes a vector in the parent object's local coordinates and transforms
2288 it into world coordinates.
2289 ================
2290 */
2292  idVec3 pos;
2293 
2294  if ( !bindMaster ) {
2295  return vec;
2296  }
2297 
2298  idVec3 masterOrigin;
2299  idMat3 masterAxis;
2300 
2301  GetMasterPosition( masterOrigin, masterAxis );
2302  masterAxis.UnprojectVector( vec, pos );
2303  pos += masterOrigin;
2304 
2305  return pos;
2306 }
2307 
2308 /*
2309 ================
2310 idEntity::GetMasterPosition
2311 ================
2312 */
2313 bool idEntity::GetMasterPosition( idVec3 &masterOrigin, idMat3 &masterAxis ) const {
2314  idVec3 localOrigin;
2315  idMat3 localAxis;
2316  idAnimator *masterAnimator;
2317 
2318  if ( bindMaster ) {
2319  // if bound to a joint of an animated model
2320  if ( bindJoint != INVALID_JOINT ) {
2321  masterAnimator = bindMaster->GetAnimator();
2322  if ( !masterAnimator ) {
2323  masterOrigin = vec3_origin;
2324  masterAxis = mat3_identity;
2325  return false;
2326  } else {
2327  masterAnimator->GetJointTransform( bindJoint, gameLocal.time, masterOrigin, masterAxis );
2328  masterAxis *= bindMaster->renderEntity.axis;
2329  masterOrigin = bindMaster->renderEntity.origin + masterOrigin * bindMaster->renderEntity.axis;
2330  }
2331  } else if ( bindBody >= 0 && bindMaster->GetPhysics() ) {
2332  masterOrigin = bindMaster->GetPhysics()->GetOrigin( bindBody );
2333  masterAxis = bindMaster->GetPhysics()->GetAxis( bindBody );
2334  } else {
2335  masterOrigin = bindMaster->renderEntity.origin;
2336  masterAxis = bindMaster->renderEntity.axis;
2337  }
2338  return true;
2339  } else {
2340  masterOrigin = vec3_origin;
2341  masterAxis = mat3_identity;
2342  return false;
2343  }
2344 }
2345 
2346 /*
2347 ================
2348 idEntity::GetWorldVelocities
2349 ================
2350 */
2351 void idEntity::GetWorldVelocities( idVec3 &linearVelocity, idVec3 &angularVelocity ) const {
2352 
2353  linearVelocity = physics->GetLinearVelocity();
2354  angularVelocity = physics->GetAngularVelocity();
2355 
2356  if ( bindMaster ) {
2357  idVec3 masterOrigin, masterLinearVelocity, masterAngularVelocity;
2358  idMat3 masterAxis;
2359 
2360  // get position of master
2361  GetMasterPosition( masterOrigin, masterAxis );
2362 
2363  // get master velocities
2364  bindMaster->GetWorldVelocities( masterLinearVelocity, masterAngularVelocity );
2365 
2366  // linear velocity relative to master plus master linear and angular velocity
2367  linearVelocity = linearVelocity * masterAxis + masterLinearVelocity +
2368  masterAngularVelocity.Cross( GetPhysics()->GetOrigin() - masterOrigin );
2369  }
2370 }
2371 
2372 /*
2373 ================
2374 idEntity::JoinTeam
2375 ================
2376 */
2377 void idEntity::JoinTeam( idEntity *teammember ) {
2378  idEntity *ent;
2379  idEntity *master;
2380  idEntity *prev;
2381  idEntity *next;
2382 
2383  // if we're already on a team, quit it so we can join this one
2384  if ( teamMaster && ( teamMaster != this ) ) {
2385  QuitTeam();
2386  }
2387 
2388  assert( teammember );
2389 
2390  if ( teammember == this ) {
2391  teamMaster = this;
2392  return;
2393  }
2394 
2395  // check if our new team mate is already on a team
2396  master = teammember->teamMaster;
2397  if ( !master ) {
2398  // he's not on a team, so he's the new teamMaster
2399  master = teammember;
2400  teammember->teamMaster = teammember;
2401  teammember->teamChain = this;
2402 
2403  // make anyone who's bound to me part of the new team
2404  for( ent = teamChain; ent != NULL; ent = ent->teamChain ) {
2405  ent->teamMaster = master;
2406  }
2407  } else {
2408  // skip past the chain members bound to the entity we're teaming up with
2409  prev = teammember;
2410  next = teammember->teamChain;
2411  if ( bindMaster ) {
2412  // if we have a bindMaster, join after any entities bound to the entity
2413  // we're joining
2414  while( next && next->IsBoundTo( teammember ) ) {
2415  prev = next;
2416  next = next->teamChain;
2417  }
2418  } else {
2419  // if we're not bound to someone, then put us at the end of the team
2420  while( next ) {
2421  prev = next;
2422  next = next->teamChain;
2423  }
2424  }
2425 
2426  // make anyone who's bound to me part of the new team and
2427  // also find the last member of my team
2428  for( ent = this; ent->teamChain != NULL; ent = ent->teamChain ) {
2429  ent->teamChain->teamMaster = master;
2430  }
2431 
2432  prev->teamChain = this;
2433  ent->teamChain = next;
2434  }
2435 
2436  teamMaster = master;
2437 
2438  // reorder the active entity list
2439  gameLocal.sortTeamMasters = true;
2440 }
2441 
2442 /*
2443 ================
2444 idEntity::QuitTeam
2445 ================
2446 */
2447 void idEntity::QuitTeam( void ) {
2448  idEntity *ent;
2449 
2450  if ( !teamMaster ) {
2451  return;
2452  }
2453 
2454  // check if I'm the teamMaster
2455  if ( teamMaster == this ) {
2456  // do we have more than one teammate?
2457  if ( !teamChain->teamChain ) {
2458  // no, break up the team
2460  } else {
2461  // yes, so make the first teammate the teamMaster
2462  for( ent = teamChain; ent; ent = ent->teamChain ) {
2463  ent->teamMaster = teamChain;
2464  }
2465  }
2466  } else {
2467  assert( teamMaster );
2469 
2470  // find the previous member of the teamChain
2471  ent = teamMaster;
2472  while( ent->teamChain != this ) {
2473  assert( ent->teamChain ); // this should never happen
2474  ent = ent->teamChain;
2475  }
2476 
2477  // remove this from the teamChain
2478  ent->teamChain = teamChain;
2479 
2480  // if no one is left on the team, break it up
2481  if ( !teamMaster->teamChain ) {
2483  }
2484  }
2485 
2486  teamMaster = NULL;
2487  teamChain = NULL;
2488 }
2489 
2490 /***********************************************************************
2491 
2492  Physics.
2493 
2494 ***********************************************************************/
2495 
2496 /*
2497 ================
2498 idEntity::InitDefaultPhysics
2499 ================
2500 */
2501 void idEntity::InitDefaultPhysics( const idVec3 &origin, const idMat3 &axis ) {
2502  const char *temp;
2503  idClipModel *clipModel = NULL;
2504 
2505  // check if a clipmodel key/value pair is set
2506  if ( spawnArgs.GetString( "clipmodel", "", &temp ) ) {
2507  if ( idClipModel::CheckModel( temp ) ) {
2508  clipModel = new idClipModel( temp );
2509  }
2510  }
2511 
2512  if ( !spawnArgs.GetBool( "noclipmodel", "0" ) ) {
2513 
2514  // check if mins/maxs or size key/value pairs are set
2515  if ( !clipModel ) {
2516  idVec3 size;
2517  idBounds bounds;
2518  bool setClipModel = false;
2519 
2520  if ( spawnArgs.GetVector( "mins", NULL, bounds[0] ) &&
2521  spawnArgs.GetVector( "maxs", NULL, bounds[1] ) ) {
2522  setClipModel = true;
2523  if ( bounds[0][0] > bounds[1][0] || bounds[0][1] > bounds[1][1] || bounds[0][2] > bounds[1][2] ) {
2524  gameLocal.Error( "Invalid bounds '%s'-'%s' on entity '%s'", bounds[0].ToString(), bounds[1].ToString(), name.c_str() );
2525  }
2526  } else if ( spawnArgs.GetVector( "size", NULL, size ) ) {
2527  if ( ( size.x < 0.0f ) || ( size.y < 0.0f ) || ( size.z < 0.0f ) ) {
2528  gameLocal.Error( "Invalid size '%s' on entity '%s'", size.ToString(), name.c_str() );
2529  }
2530  bounds[0].Set( size.x * -0.5f, size.y * -0.5f, 0.0f );
2531  bounds[1].Set( size.x * 0.5f, size.y * 0.5f, size.z );
2532  setClipModel = true;
2533  }
2534 
2535  if ( setClipModel ) {
2536  int numSides;
2537  idTraceModel trm;
2538 
2539  if ( spawnArgs.GetInt( "cylinder", "0", numSides ) && numSides > 0 ) {
2540  trm.SetupCylinder( bounds, numSides < 3 ? 3 : numSides );
2541  } else if ( spawnArgs.GetInt( "cone", "0", numSides ) && numSides > 0 ) {
2542  trm.SetupCone( bounds, numSides < 3 ? 3 : numSides );
2543  } else {
2544  trm.SetupBox( bounds );
2545  }
2546  clipModel = new idClipModel( trm );
2547  }
2548  }
2549 
2550  // check if the visual model can be used as collision model
2551  if ( !clipModel ) {
2552  temp = spawnArgs.GetString( "model" );
2553  if ( ( temp != NULL ) && ( *temp != 0 ) ) {
2554  if ( idClipModel::CheckModel( temp ) ) {
2555  clipModel = new idClipModel( temp );
2556  }
2557  }
2558  }
2559  }
2560 
2561  defaultPhysicsObj.SetSelf( this );
2562  defaultPhysicsObj.SetClipModel( clipModel, 1.0f );
2563  defaultPhysicsObj.SetOrigin( origin );
2564  defaultPhysicsObj.SetAxis( axis );
2565 
2567 }
2568 
2569 /*
2570 ================
2571 idEntity::SetPhysics
2572 ================
2573 */
2575  // clear any contacts the current physics object has
2576  if ( physics ) {
2578  }
2579  // set new physics object or set the default physics if NULL
2580  if ( phys != NULL ) {
2582  physics = phys;
2583  physics->Activate();
2584  } else {
2586  }
2589 }
2590 
2591 /*
2592 ================
2593 idEntity::RestorePhysics
2594 ================
2595 */
2597  assert( phys != NULL );
2598  // restore physics pointer
2599  physics = phys;
2600 }
2601 
2602 /*
2603 ================
2604 idEntity::GetPhysics
2605 ================
2606 */
2608  return physics;
2609 }
2610 
2611 /*
2612 ================
2613 idEntity::RunPhysics
2614 ================
2615 */
2616 bool idEntity::RunPhysics( void ) {
2617  int i, reachedTime, startTime, endTime;
2618  idEntity * part, *blockedPart, *blockingEntity;
2619  trace_t results;
2620  bool moved;
2621 
2622  // don't run physics if not enabled
2623  if ( !( thinkFlags & TH_PHYSICS ) ) {
2624  // however do update any animation controllers
2625  if ( UpdateAnimationControllers() ) {
2627  }
2628  return false;
2629  }
2630 
2631  // if this entity is a team slave don't do anything because the team master will handle everything
2632  if ( teamMaster && teamMaster != this ) {
2633  return false;
2634  }
2635 
2636  startTime = gameLocal.previousTime;
2637  endTime = gameLocal.time;
2638 
2640  blockedPart = NULL;
2641 
2642  // save the physics state of the whole team and disable the team for collision detection
2643  for ( part = this; part != NULL; part = part->teamChain ) {
2644  if ( part->physics ) {
2645  if ( !part->fl.solidForTeam ) {
2646  part->physics->DisableClip();
2647  }
2648  part->physics->SaveState();
2649  }
2650  }
2651 
2652  // move the whole team
2653  for ( part = this; part != NULL; part = part->teamChain ) {
2654 
2655  if ( part->physics ) {
2656 
2657  // run physics
2658  moved = part->physics->Evaluate( endTime - startTime, endTime );
2659 
2660  // check if the object is blocked
2661  blockingEntity = part->physics->GetBlockingEntity();
2662  if ( blockingEntity ) {
2663  blockedPart = part;
2664  break;
2665  }
2666 
2667  // if moved or forced to update the visual position and orientation from the physics
2668  if ( moved || part->fl.forcePhysicsUpdate ) {
2669  part->UpdateFromPhysics( false );
2670  }
2671 
2672  // update any animation controllers here so an entity bound
2673  // to a joint of this entity gets the correct position
2674  if ( part->UpdateAnimationControllers() ) {
2675  part->BecomeActive( TH_ANIMATE );
2676  }
2677  }
2678  }
2679 
2680  // enable the whole team for collision detection
2681  for ( part = this; part != NULL; part = part->teamChain ) {
2682  if ( part->physics ) {
2683  if ( !part->fl.solidForTeam ) {
2684  part->physics->EnableClip();
2685  }
2686  }
2687  }
2688 
2689  // if one of the team entities is a pusher and blocked
2690  if ( blockedPart ) {
2691  // move the parts back to the previous position
2692  for ( part = this; part != blockedPart; part = part->teamChain ) {
2693 
2694  if ( part->physics ) {
2695 
2696  // restore the physics state
2697  part->physics->RestoreState();
2698 
2699  // move back the visual position and orientation
2700  part->UpdateFromPhysics( true );
2701  }
2702  }
2703  for ( part = this; part != NULL; part = part->teamChain ) {
2704  if ( part->physics ) {
2705  // update the physics time without moving
2706  part->physics->UpdateTime( endTime );
2707  }
2708  }
2709 
2710  // restore the positions of any pushed entities
2712 
2713  if ( gameLocal.isClient ) {
2714  return false;
2715  }
2716 
2717  // if the master pusher has a "blocked" function, call it
2718  Signal( SIG_BLOCKED );
2719  ProcessEvent( &EV_TeamBlocked, blockedPart, blockingEntity );
2720  // call the blocked function on the blocked part
2721  blockedPart->ProcessEvent( &EV_PartBlocked, blockingEntity );
2722  return false;
2723  }
2724 
2725  // set pushed
2726  for ( i = 0; i < gameLocal.push.GetNumPushedEntities(); i++ ) {
2727  idEntity *ent = gameLocal.push.GetPushedEntity( i );
2728  ent->physics->SetPushed( endTime - startTime );
2729  }
2730 
2731  if ( gameLocal.isClient ) {
2732  return true;
2733  }
2734 
2735  // post reached event if the current time is at or past the end point of the motion
2736  for ( part = this; part != NULL; part = part->teamChain ) {
2737 
2738  if ( part->physics ) {
2739 
2740  reachedTime = part->physics->GetLinearEndTime();
2741  if ( startTime < reachedTime && endTime >= reachedTime ) {
2742  part->ProcessEvent( &EV_ReachedPos );
2743  }
2744  reachedTime = part->physics->GetAngularEndTime();
2745  if ( startTime < reachedTime && endTime >= reachedTime ) {
2746  part->ProcessEvent( &EV_ReachedAng );
2747  }
2748  }
2749  }
2750 
2751  return true;
2752 }
2753 
2754 /*
2755 ================
2756 idEntity::UpdateFromPhysics
2757 ================
2758 */
2759 void idEntity::UpdateFromPhysics( bool moveBack ) {
2760 
2761  if ( IsType( idActor::Type ) ) {
2762  idActor *actor = static_cast<idActor *>( this );
2763 
2764  // set master delta angles for actors
2765  if ( GetBindMaster() ) {
2766  idAngles delta = actor->GetDeltaViewAngles();
2767  if ( moveBack ) {
2768  delta.yaw -= static_cast<idPhysics_Actor *>(physics)->GetMasterDeltaYaw();
2769  } else {
2770  delta.yaw += static_cast<idPhysics_Actor *>(physics)->GetMasterDeltaYaw();
2771  }
2772  actor->SetDeltaViewAngles( delta );
2773  }
2774  }
2775 
2776  UpdateVisuals();
2777 }
2778 
2779 /*
2780 ================
2781 idEntity::SetOrigin
2782 ================
2783 */
2784 void idEntity::SetOrigin( const idVec3 &org ) {
2785 
2786  GetPhysics()->SetOrigin( org );
2787 
2788  UpdateVisuals();
2789 }
2790 
2791 /*
2792 ================
2793 idEntity::SetAxis
2794 ================
2795 */
2796 void idEntity::SetAxis( const idMat3 &axis ) {
2797 
2798  if ( GetPhysics()->IsType( idPhysics_Actor::Type ) ) {
2799  static_cast<idActor *>(this)->viewAxis = axis;
2800  } else {
2801  GetPhysics()->SetAxis( axis );
2802  }
2803 
2804  UpdateVisuals();
2805 }
2806 
2807 /*
2808 ================
2809 idEntity::SetAngles
2810 ================
2811 */
2812 void idEntity::SetAngles( const idAngles &ang ) {
2813  SetAxis( ang.ToMat3() );
2814 }
2815 
2816 /*
2817 ================
2818 idEntity::GetFloorPos
2819 ================
2820 */
2821 bool idEntity::GetFloorPos( float max_dist, idVec3 &floorpos ) const {
2822  trace_t result;
2823 
2824  if ( !GetPhysics()->HasGroundContacts() ) {
2825  GetPhysics()->ClipTranslation( result, GetPhysics()->GetGravityNormal() * max_dist, NULL );
2826  if ( result.fraction < 1.0f ) {
2827  floorpos = result.endpos;
2828  return true;
2829  } else {
2830  floorpos = GetPhysics()->GetOrigin();
2831  return false;
2832  }
2833  } else {
2834  floorpos = GetPhysics()->GetOrigin();
2835  return true;
2836  }
2837 }
2838 
2839 /*
2840 ================
2841 idEntity::GetPhysicsToVisualTransform
2842 ================
2843 */
2845  return false;
2846 }
2847 
2848 /*
2849 ================
2850 idEntity::GetPhysicsToSoundTransform
2851 ================
2852 */
2854  // by default play the sound at the center of the bounding box of the first clip model
2855  if ( GetPhysics()->GetNumClipModels() > 0 ) {
2856  origin = GetPhysics()->GetBounds().GetCenter();
2857  axis.Identity();
2858  return true;
2859  }
2860  return false;
2861 }
2862 
2863 /*
2864 ================
2865 idEntity::Collide
2866 ================
2867 */
2868 bool idEntity::Collide( const trace_t &collision, const idVec3 &velocity ) {
2869  // this entity collides with collision.c.entityNum
2870  return false;
2871 }
2872 
2873 /*
2874 ================
2875 idEntity::GetImpactInfo
2876 ================
2877 */
2878 void idEntity::GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info ) {
2879  GetPhysics()->GetImpactInfo( id, point, info );
2880 }
2881 
2882 /*
2883 ================
2884 idEntity::ApplyImpulse
2885 ================
2886 */
2887 void idEntity::ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ) {
2888  GetPhysics()->ApplyImpulse( id, point, impulse );
2889 }
2890 
2891 /*
2892 ================
2893 idEntity::AddForce
2894 ================
2895 */
2896 void idEntity::AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ) {
2897  GetPhysics()->AddForce( id, point, force );
2898 }
2899 
2900 /*
2901 ================
2902 idEntity::ActivatePhysics
2903 ================
2904 */
2906  GetPhysics()->Activate();
2907 }
2908 
2909 /*
2910 ================
2911 idEntity::IsAtRest
2912 ================
2913 */
2914 bool idEntity::IsAtRest( void ) const {
2915  return GetPhysics()->IsAtRest();
2916 }
2917 
2918 /*
2919 ================
2920 idEntity::GetRestStartTime
2921 ================
2922 */
2923 int idEntity::GetRestStartTime( void ) const {
2924  return GetPhysics()->GetRestStartTime();
2925 }
2926 
2927 /*
2928 ================
2929 idEntity::AddContactEntity
2930 ================
2931 */
2933  GetPhysics()->AddContactEntity( ent );
2934 }
2935 
2936 /*
2937 ================
2938 idEntity::RemoveContactEntity
2939 ================
2940 */
2942  GetPhysics()->RemoveContactEntity( ent );
2943 }
2944 
2945 
2946 
2947 /***********************************************************************
2948 
2949  Damage
2950 
2951 ***********************************************************************/
2952 
2953 /*
2954 ============
2955 idEntity::CanDamage
2956 
2957 Returns true if the inflictor can directly damage the target. Used for
2958 explosions and melee attacks.
2959 ============
2960 */
2961 bool idEntity::CanDamage( const idVec3 &origin, idVec3 &damagePoint ) const {
2962  idVec3 dest;
2963  trace_t tr;
2964  idVec3 midpoint;
2965 
2966  // use the midpoint of the bounds instead of the origin, because
2967  // bmodels may have their origin at 0,0,0
2968  midpoint = ( GetPhysics()->GetAbsBounds()[0] + GetPhysics()->GetAbsBounds()[1] ) * 0.5;
2969 
2970  dest = midpoint;
2971  gameLocal.clip.TracePoint( tr, origin, dest, MASK_SOLID, NULL );
2972  if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == this ) ) {
2973  damagePoint = tr.endpos;
2974  return true;
2975  }
2976 
2977  // this should probably check in the plane of projection, rather than in world coordinate
2978  dest = midpoint;
2979  dest[0] += 15.0;
2980  dest[1] += 15.0;
2981  gameLocal.clip.TracePoint( tr, origin, dest, MASK_SOLID, NULL );
2982  if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == this ) ) {
2983  damagePoint = tr.endpos;
2984  return true;
2985  }
2986 
2987  dest = midpoint;
2988  dest[0] += 15.0;
2989  dest[1] -= 15.0;
2990  gameLocal.clip.TracePoint( tr, origin, dest, MASK_SOLID, NULL );
2991  if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == this ) ) {
2992  damagePoint = tr.endpos;
2993  return true;
2994  }
2995 
2996  dest = midpoint;
2997  dest[0] -= 15.0;
2998  dest[1] += 15.0;
2999  gameLocal.clip.TracePoint( tr, origin, dest, MASK_SOLID, NULL );
3000  if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == this ) ) {
3001  damagePoint = tr.endpos;
3002  return true;
3003  }
3004 
3005  dest = midpoint;
3006  dest[0] -= 15.0;
3007  dest[1] -= 15.0;
3008  gameLocal.clip.TracePoint( tr, origin, dest, MASK_SOLID, NULL );
3009  if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == this ) ) {
3010  damagePoint = tr.endpos;
3011  return true;
3012  }
3013 
3014  dest = midpoint;
3015  dest[2] += 15.0;
3016  gameLocal.clip.TracePoint( tr, origin, dest, MASK_SOLID, NULL );
3017  if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == this ) ) {
3018  damagePoint = tr.endpos;
3019  return true;
3020  }
3021 
3022  dest = midpoint;
3023  dest[2] -= 15.0;
3024  gameLocal.clip.TracePoint( tr, origin, dest, MASK_SOLID, NULL );
3025  if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == this ) ) {
3026  damagePoint = tr.endpos;
3027  return true;
3028  }
3029 
3030  return false;
3031 }
3032 
3033 /*
3034 ================
3035 idEntity::DamageFeedback
3036 
3037 callback function for when another entity received damage from this entity. damage can be adjusted and returned to the caller.
3038 ================
3039 */
3040 void idEntity::DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage ) {
3041  // implemented in subclasses
3042 }
3043 
3044 /*
3045 ============
3046 Damage
3047 
3048 this entity that is being damaged
3049 inflictor entity that is causing the damage
3050 attacker entity that caused the inflictor to damage targ
3051  example: this=monster, inflictor=rocket, attacker=player
3052 
3053 dir direction of the attack for knockback in global space
3054 point point at which the damage is being inflicted, used for headshots
3055 damage amount of damage being inflicted
3056 
3057 inflictor, attacker, dir, and point can be NULL for environmental effects
3058 
3059 ============
3060 */
3061 void idEntity::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir,
3062  const char *damageDefName, const float damageScale, const int location ) {
3063  if ( !fl.takedamage ) {
3064  return;
3065  }
3066 
3067 #ifdef _D3XP
3068  SetTimeState ts( timeGroup );
3069 #endif
3070 
3071  if ( !inflictor ) {
3072  inflictor = gameLocal.world;
3073  }
3074 
3075  if ( !attacker ) {
3076  attacker = gameLocal.world;
3077  }
3078 
3079  const idDict *damageDef = gameLocal.FindEntityDefDict( damageDefName );
3080  if ( !damageDef ) {
3081  gameLocal.Error( "Unknown damageDef '%s'\n", damageDefName );
3082  }
3083 
3084  int damage = damageDef->GetInt( "damage" );
3085 
3086  // inform the attacker that they hit someone
3087  attacker->DamageFeedback( this, inflictor, damage );
3088  if ( damage ) {
3089  // do the damage
3090  health -= damage;
3091  if ( health <= 0 ) {
3092  if ( health < -999 ) {
3093  health = -999;
3094  }
3095 
3096  Killed( inflictor, attacker, damage, dir, location );
3097  } else {
3098  Pain( inflictor, attacker, damage, dir, location );
3099  }
3100  }
3101 }
3102 
3103 /*
3104 ================
3105 idEntity::AddDamageEffect
3106 ================
3107 */
3108 void idEntity::AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ) {
3109  const char *sound, *decal, *key;
3110 
3111  const idDeclEntityDef *def = gameLocal.FindEntityDef( damageDefName, false );
3112  if ( def == NULL ) {
3113  return;
3114  }
3115 
3116  const char *materialType = gameLocal.sufaceTypeNames[ collision.c.material->GetSurfaceType() ];
3117 
3118  // start impact sound based on material type
3119  key = va( "snd_%s", materialType );
3120  sound = spawnArgs.GetString( key );
3121  if ( *sound == '\0' ) {
3122  sound = def->dict.GetString( key );
3123  }
3124  if ( *sound != '\0' ) {
3125  StartSoundShader( declManager->FindSound( sound ), SND_CHANNEL_BODY, 0, false, NULL );
3126  }
3127 
3128  if ( g_decals.GetBool() ) {
3129  // place a wound overlay on the model
3130  key = va( "mtr_wound_%s", materialType );
3131  decal = spawnArgs.RandomPrefix( key, gameLocal.random );
3132  if ( *decal == '\0' ) {
3133  decal = def->dict.RandomPrefix( key, gameLocal.random );
3134  }
3135  if ( *decal != '\0' ) {
3136  idVec3 dir = velocity;
3137  dir.Normalize();
3138  ProjectOverlay( collision.c.point, dir, 20.0f, decal );
3139  }
3140  }
3141 }
3142 
3143 /*
3144 ============
3145 idEntity::Pain
3146 
3147 Called whenever an entity recieves damage. Returns whether the entity responds to the pain.
3148 This is a virtual function that subclasses are expected to implement.
3149 ============
3150 */
3151 bool idEntity::Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) {
3152  return false;
3153 }
3154 
3155 /*
3156 ============
3157 idEntity::Killed
3158 
3159 Called whenever an entity's health is reduced to 0 or less.
3160 This is a virtual function that subclasses are expected to implement.
3161 ============
3162 */
3163 void idEntity::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) {
3164 }
3165 
3166 
3167 /***********************************************************************
3168 
3169  Script functions
3170 
3171 ***********************************************************************/
3172 
3173 /*
3174 ================
3175 idEntity::ShouldConstructScriptObjectAtSpawn
3176 
3177 Called during idEntity::Spawn to see if it should construct the script object or not.
3178 Overridden by subclasses that need to spawn the script object themselves.
3179 ================
3180 */
3182  return true;
3183 }
3184 
3185 /*
3186 ================
3187 idEntity::ConstructScriptObject
3188 
3189 Called during idEntity::Spawn. Calls the constructor on the script object.
3190 Can be overridden by subclasses when a thread doesn't need to be allocated.
3191 ================
3192 */
3194  idThread *thread;
3195  const function_t *constructor;
3196 
3197  // init the script object's data
3199 
3200  // call script object's constructor
3201  constructor = scriptObject.GetConstructor();
3202  if ( constructor ) {
3203  // start a thread that will initialize after Spawn is done being called
3204  thread = new idThread();
3205  thread->SetThreadName( name.c_str() );
3206  thread->CallFunction( this, constructor, true );
3207  thread->DelayedStart( 0 );
3208  } else {
3209  thread = NULL;
3210  }
3211 
3212  // clear out the object's memory
3214 
3215  return thread;
3216 }
3217 
3218 /*
3219 ================
3220 idEntity::DeconstructScriptObject
3221 
3222 Called during idEntity::~idEntity. Calls the destructor on the script object.
3223 Can be overridden by subclasses when a thread doesn't need to be allocated.
3224 Not called during idGameLocal::MapShutdown.
3225 ================
3226 */
3228  idThread *thread;
3229  const function_t *destructor;
3230 
3231  // don't bother calling the script object's destructor on map shutdown
3232  if ( gameLocal.GameState() == GAMESTATE_SHUTDOWN ) {
3233  return;
3234  }
3235 
3236  // call script object's destructor
3237  destructor = scriptObject.GetDestructor();
3238  if ( destructor ) {
3239  // start a thread that will run immediately and be destroyed
3240  thread = new idThread();
3241  thread->SetThreadName( name.c_str() );
3242  thread->CallFunction( this, destructor, true );
3243  thread->Execute();
3244  delete thread;
3245  }
3246 }
3247 
3248 /*
3249 ================
3250 idEntity::HasSignal
3251 ================
3252 */
3253 bool idEntity::HasSignal( signalNum_t signalnum ) const {
3254  if ( !signals ) {
3255  return false;
3256  }
3257  assert( ( signalnum >= 0 ) && ( signalnum < NUM_SIGNALS ) );
3258  return ( signals->signal[ signalnum ].Num() > 0 );
3259 }
3260 
3261 /*
3262 ================
3263 idEntity::SetSignal
3264 ================
3265 */
3266 void idEntity::SetSignal( signalNum_t signalnum, idThread *thread, const function_t *function ) {
3267  int i;
3268  int num;
3269  signal_t sig;
3270  int threadnum;
3271 
3272  assert( ( signalnum >= 0 ) && ( signalnum < NUM_SIGNALS ) );
3273 
3274  if ( !signals ) {
3275  signals = new signalList_t;
3276  }
3277 
3278  assert( thread );
3279  threadnum = thread->GetThreadNum();
3280 
3281  num = signals->signal[ signalnum ].Num();
3282  for( i = 0; i < num; i++ ) {
3283  if ( signals->signal[ signalnum ][ i ].threadnum == threadnum ) {
3284  signals->signal[ signalnum ][ i ].function = function;
3285  return;
3286  }
3287  }
3288 
3289  if ( num >= MAX_SIGNAL_THREADS ) {
3290  thread->Error( "Exceeded maximum number of signals per object" );
3291  }
3292 
3293  sig.threadnum = threadnum;
3294  sig.function = function;
3295  signals->signal[ signalnum ].Append( sig );
3296 }
3297 
3298 /*
3299 ================
3300 idEntity::ClearSignal
3301 ================
3302 */
3303 void idEntity::ClearSignal( idThread *thread, signalNum_t signalnum ) {
3304  assert( thread );
3305  if ( ( signalnum < 0 ) || ( signalnum >= NUM_SIGNALS ) ) {
3306  gameLocal.Error( "Signal out of range" );
3307  }
3308 
3309  if ( !signals ) {
3310  return;
3311  }
3312 
3313  signals->signal[ signalnum ].Clear();
3314 }
3315 
3316 /*
3317 ================
3318 idEntity::ClearSignalThread
3319 ================
3320 */
3322  int i;
3323  int num;
3324  int threadnum;
3325 
3326  assert( thread );
3327 
3328  if ( ( signalnum < 0 ) || ( signalnum >= NUM_SIGNALS ) ) {
3329  gameLocal.Error( "Signal out of range" );
3330  }
3331 
3332  if ( !signals ) {
3333  return;
3334  }
3335 
3336  threadnum = thread->GetThreadNum();
3337 
3338  num = signals->signal[ signalnum ].Num();
3339  for( i = 0; i < num; i++ ) {
3340  if ( signals->signal[ signalnum ][ i ].threadnum == threadnum ) {
3341  signals->signal[ signalnum ].RemoveIndex( i );
3342  return;
3343  }
3344  }
3345 }
3346 
3347 /*
3348 ================
3349 idEntity::Signal
3350 ================
3351 */
3352 void idEntity::Signal( signalNum_t signalnum ) {
3353  int i;
3354  int num;
3355  signal_t sigs[ MAX_SIGNAL_THREADS ];
3356  idThread *thread;
3357 
3358  assert( ( signalnum >= 0 ) && ( signalnum < NUM_SIGNALS ) );
3359 
3360  if ( !signals ) {
3361  return;
3362  }
3363 
3364  // we copy the signal list since each thread has the potential
3365  // to end any of the threads in the list. By copying the list
3366  // we don't have to worry about the list changing as we're
3367  // processing it.
3368  num = signals->signal[ signalnum ].Num();
3369  for( i = 0; i < num; i++ ) {
3370  sigs[ i ] = signals->signal[ signalnum ][ i ];
3371  }
3372 
3373  // clear out the signal list so that we don't get into an infinite loop
3374  signals->signal[ signalnum ].Clear();
3375 
3376  for( i = 0; i < num; i++ ) {
3377  thread = idThread::GetThread( sigs[ i ].threadnum );
3378  if ( thread ) {
3379  thread->CallFunction( this, sigs[ i ].function, true );
3380  thread->Execute();
3381  }
3382  }
3383 }
3384 
3385 /*
3386 ================
3387 idEntity::SignalEvent
3388 ================
3389 */
3390 void idEntity::SignalEvent( idThread *thread, signalNum_t signalnum ) {
3391  if ( ( signalnum < 0 ) || ( signalnum >= NUM_SIGNALS ) ) {
3392  gameLocal.Error( "Signal out of range" );
3393  }
3394 
3395  if ( !signals ) {
3396  return;
3397  }
3398 
3399  Signal( signalnum );
3400 }
3401 
3402 /***********************************************************************
3403 
3404  Guis.
3405 
3406 ***********************************************************************/
3407 
3408 
3409 /*
3410 ================
3411 idEntity::TriggerGuis
3412 ================
3413 */
3415  int i;
3416  for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) {
3417  if ( renderEntity.gui[ i ] ) {
3419  }
3420  }
3421 }
3422 
3423 /*
3424 ================
3425 idEntity::HandleGuiCommands
3426 ================
3427 */
3428 bool idEntity::HandleGuiCommands( idEntity *entityGui, const char *cmds ) {
3429  idEntity *targetEnt;
3430  bool ret = false;
3431  if ( entityGui && cmds && *cmds ) {
3432  idLexer src;
3433  idToken token, token2, token3, token4;
3434  src.LoadMemory( cmds, strlen( cmds ), "guiCommands" );
3435  while( 1 ) {
3436 
3437  if ( !src.ReadToken( &token ) ) {
3438  return ret;
3439  }
3440 
3441  if ( token == ";" ) {
3442  continue;
3443  }
3444 
3445  if ( token.Icmp( "activate" ) == 0 ) {
3446  bool targets = true;
3447  if ( src.ReadToken( &token2 ) ) {
3448  if ( token2 == ";" ) {
3449  src.UnreadToken( &token2 );
3450  } else {
3451  targets = false;
3452  }
3453  }
3454 
3455  if ( targets ) {
3456  entityGui->ActivateTargets( this );
3457  } else {
3458  idEntity *ent = gameLocal.FindEntity( token2 );
3459  if ( ent ) {
3460  ent->Signal( SIG_TRIGGER );
3461  ent->PostEventMS( &EV_Activate, 0, this );
3462  }
3463  }
3464 
3465  entityGui->renderEntity.shaderParms[ SHADERPARM_MODE ] = 1.0f;
3466  continue;
3467  }
3468 
3469 
3470  if ( token.Icmp( "runScript" ) == 0 ) {
3471  if ( src.ReadToken( &token2 ) ) {
3472  while( src.CheckTokenString( "::" ) ) {
3473  idToken token3;
3474  if ( !src.ReadToken( &token3 ) ) {
3475  gameLocal.Error( "Expecting function name following '::' in gui for entity '%s'", entityGui->name.c_str() );
3476  }
3477  token2 += "::" + token3;
3478  }
3479  const function_t *func = gameLocal.program.FindFunction( token2 );
3480  if ( !func ) {
3481  gameLocal.Error( "Can't find function '%s' for gui in entity '%s'", token2.c_str(), entityGui->name.c_str() );
3482  } else {
3483  idThread *thread = new idThread( func );
3484  thread->DelayedStart( 0 );
3485  }
3486  }
3487  continue;
3488  }
3489 
3490  if ( token.Icmp("play") == 0 ) {
3491  if ( src.ReadToken( &token2 ) ) {
3492  const idSoundShader *shader = declManager->FindSound(token2);
3493  entityGui->StartSoundShader( shader, SND_CHANNEL_ANY, 0, false, NULL );
3494  }
3495  continue;
3496  }
3497 
3498  if ( token.Icmp( "setkeyval" ) == 0 ) {
3499  if ( src.ReadToken( &token2 ) && src.ReadToken(&token3) && src.ReadToken( &token4 ) ) {
3500  idEntity *ent = gameLocal.FindEntity( token2 );
3501  if ( ent ) {
3502  ent->spawnArgs.Set( token3, token4 );
3504  ent->UpdateVisuals();
3505  }
3506  }
3507  continue;
3508  }
3509 
3510  if ( token.Icmp( "setshaderparm" ) == 0 ) {
3511  if ( src.ReadToken( &token2 ) && src.ReadToken(&token3) ) {
3512  entityGui->SetShaderParm( atoi( token2 ), atof( token3 ) );
3513  entityGui->UpdateVisuals();
3514  }
3515  continue;
3516  }
3517 
3518  if ( token.Icmp("close") == 0 ) {
3519  ret = true;
3520  continue;
3521  }
3522 
3523  if ( !token.Icmp( "turkeyscore" ) ) {
3524  if ( src.ReadToken( &token2 ) && entityGui->renderEntity.gui[0] ) {
3525  int score = entityGui->renderEntity.gui[0]->State().GetInt( "score" );
3526  score += atoi( token2 );
3527  entityGui->renderEntity.gui[0]->SetStateInt( "score", score );
3528  if ( gameLocal.GetLocalPlayer() && score >= 25000 && !gameLocal.GetLocalPlayer()->inventory.turkeyScore ) {
3529  gameLocal.GetLocalPlayer()->GiveEmail( "highScore" );
3531  }
3532  }
3533  continue;
3534  }
3535 
3536 #ifdef _D3XP
3537 
3538  if ( !token.Icmp( "martianbuddycomplete" ) ) {
3539  gameLocal.GetLocalPlayer()->GiveEmail( "MartianBuddyGameComplete" );
3540  continue;
3541  }
3542 
3543 #endif
3544 
3545 
3546  // handy for debugging GUI stuff
3547  if ( !token.Icmp( "print" ) ) {
3548  idStr msg;
3549  while ( src.ReadToken( &token2 ) ) {
3550  if ( token2 == ";" ) {
3551  src.UnreadToken( &token2 );
3552  break;
3553  }
3554  msg += token2.c_str();
3555  }
3556  common->Printf( "ent gui 0x%x '%s': %s\n", entityNumber, name.c_str(), msg.c_str() );
3557  continue;
3558  }
3559 
3560  // if we get to this point we don't know how to handle it
3561  src.UnreadToken(&token);
3562  if ( !HandleSingleGuiCommand( entityGui, &src ) ) {
3563  // not handled there see if entity or any of its targets can handle it
3564  // this will only work for one target atm
3565  if ( entityGui->HandleSingleGuiCommand( entityGui, &src ) ) {
3566  continue;
3567  }
3568 
3569  int c = entityGui->targets.Num();
3570  int i;
3571  for ( i = 0; i < c; i++) {
3572  targetEnt = entityGui->targets[ i ].GetEntity();
3573  if ( targetEnt && targetEnt->HandleSingleGuiCommand( entityGui, &src ) ) {
3574  break;
3575  }
3576  }
3577 
3578  if ( i == c ) {
3579  // not handled
3580  common->DPrintf( "idEntity::HandleGuiCommands: '%s' not handled\n", token.c_str() );
3581  src.ReadToken( &token );
3582  }
3583  }
3584 
3585  }
3586  }
3587  return ret;
3588 }
3589 
3590 /*
3591 ================
3592 idEntity::HandleSingleGuiCommand
3593 ================
3594 */
3596  return false;
3597 }
3598 
3599 /***********************************************************************
3600 
3601  Targets
3602 
3603 ***********************************************************************/
3604 
3605 /*
3606 ===============
3607 idEntity::FindTargets
3608 
3609 We have to wait until all entities are spawned
3610 Used to build lists of targets after the entity is spawned. Since not all entities
3611 have been spawned when the entity is created at map load time, we have to wait
3612 ===============
3613 */
3615  int i;
3616 
3617  // targets can be a list of multiple names
3618  gameLocal.GetTargets( spawnArgs, targets, "target" );
3619 
3620  // ensure that we don't target ourselves since that could cause an infinite loop when activating entities
3621  for( i = 0; i < targets.Num(); i++ ) {
3622  if ( targets[ i ].GetEntity() == this ) {
3623  gameLocal.Error( "Entity '%s' is targeting itself", name.c_str() );
3624  }
3625  }
3626 }
3627 
3628 /*
3629 ================
3630 idEntity::RemoveNullTargets
3631 ================
3632 */
3634  int i;
3635 
3636  for( i = targets.Num() - 1; i >= 0; i-- ) {
3637  if ( !targets[ i ].GetEntity() ) {
3638  targets.RemoveIndex( i );
3639  }
3640  }
3641 }
3642 
3643 /*
3644 ==============================
3645 idEntity::ActivateTargets
3646 
3647 "activator" should be set to the entity that initiated the firing.
3648 ==============================
3649 */
3650 void idEntity::ActivateTargets( idEntity *activator ) const {
3651  idEntity *ent;
3652  int i, j;
3653 
3654  for( i = 0; i < targets.Num(); i++ ) {
3655  ent = targets[ i ].GetEntity();
3656  if ( !ent ) {
3657  continue;
3658  }
3659  if ( ent->RespondsTo( EV_Activate ) || ent->HasSignal( SIG_TRIGGER ) ) {
3660  ent->Signal( SIG_TRIGGER );
3661  ent->ProcessEvent( &EV_Activate, activator );
3662  }
3663  for ( j = 0; j < MAX_RENDERENTITY_GUI; j++ ) {
3664  if ( ent->renderEntity.gui[ j ] ) {
3665  ent->renderEntity.gui[ j ]->Trigger( gameLocal.time );
3666  }
3667  }
3668  }
3669 }
3670 
3671 /***********************************************************************
3672 
3673  Misc.
3674 
3675 ***********************************************************************/
3676 
3677 /*
3678 ================
3679 idEntity::Teleport
3680 ================
3681 */
3682 void idEntity::Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination ) {
3683  GetPhysics()->SetOrigin( origin );
3684  GetPhysics()->SetAxis( angles.ToMat3() );
3685 
3686  UpdateVisuals();
3687 }
3688 
3689 /*
3690 ============
3691 idEntity::TouchTriggers
3692 
3693  Activate all trigger entities touched at the current position.
3694 ============
3695 */
3696 bool idEntity::TouchTriggers( void ) const {
3697  int i, numClipModels, numEntities;
3698  idClipModel * cm;
3699  idClipModel * clipModels[ MAX_GENTITIES ];
3700  idEntity * ent;
3701  trace_t trace;
3702 
3703  memset( &trace, 0, sizeof( trace ) );
3704  trace.endpos = GetPhysics()->GetOrigin();
3705  trace.endAxis = GetPhysics()->GetAxis();
3706 
3707  numClipModels = gameLocal.clip.ClipModelsTouchingBounds( GetPhysics()->GetAbsBounds(), CONTENTS_TRIGGER, clipModels, MAX_GENTITIES );
3708  numEntities = 0;
3709 
3710  for ( i = 0; i < numClipModels; i++ ) {
3711  cm = clipModels[ i ];
3712 
3713  // don't touch it if we're the owner
3714  if ( cm->GetOwner() == this ) {
3715  continue;
3716  }
3717 
3718  ent = cm->GetEntity();
3719 
3720  if ( !ent->RespondsTo( EV_Touch ) && !ent->HasSignal( SIG_TOUCH ) ) {
3721  continue;
3722  }
3723 
3724  if ( !GetPhysics()->ClipContents( cm ) ) {
3725  continue;
3726  }
3727 
3728 #ifdef _D3XP
3729  SetTimeState ts( ent->timeGroup );
3730 #endif
3731 
3732  numEntities++;
3733 
3734  trace.c.contents = cm->GetContents();
3735  trace.c.entityNum = cm->GetEntity()->entityNumber;
3736  trace.c.id = cm->GetId();
3737 
3738  ent->Signal( SIG_TOUCH );
3739  ent->ProcessEvent( &EV_Touch, this, &trace );
3740 
3741  if ( !gameLocal.entities[ entityNumber ] ) {
3742  gameLocal.Printf( "entity was removed while touching triggers\n" );
3743  return true;
3744  }
3745  }
3746 
3747  return ( numEntities != 0 );
3748 }
3749 
3750 /*
3751 ================
3752 idEntity::GetSpline
3753 ================
3754 */
3756  int i, numPoints, t;
3757  const idKeyValue *kv;
3758  idLexer lex;
3759  idVec3 v;
3760  idCurve_Spline<idVec3> *spline;
3761  const char *curveTag = "curve_";
3762 
3763  kv = spawnArgs.MatchPrefix( curveTag );
3764  if ( !kv ) {
3765  return NULL;
3766  }
3767 
3768  idStr str = kv->GetKey().Right( kv->GetKey().Length() - strlen( curveTag ) );
3769  if ( str.Icmp( "CatmullRomSpline" ) == 0 ) {
3770  spline = new idCurve_CatmullRomSpline<idVec3>();
3771  } else if ( str.Icmp( "nubs" ) == 0 ) {
3772  spline = new idCurve_NonUniformBSpline<idVec3>();
3773  } else if ( str.Icmp( "nurbs" ) == 0 ) {
3774  spline = new idCurve_NURBS<idVec3>();
3775  } else {
3776  spline = new idCurve_BSpline<idVec3>();
3777  }
3778 
3780 
3781  lex.LoadMemory( kv->GetValue(), kv->GetValue().Length(), curveTag );
3782  numPoints = lex.ParseInt();
3783  lex.ExpectTokenString( "(" );
3784  for ( t = i = 0; i < numPoints; i++, t += 100 ) {
3785  v.x = lex.ParseFloat();
3786  v.y = lex.ParseFloat();
3787  v.z = lex.ParseFloat();
3788  spline->AddValue( t, v );
3789  }
3790  lex.ExpectTokenString( ")" );
3791 
3792  return spline;
3793 }
3794 
3795 /*
3796 ===============
3797 idEntity::ShowEditingDialog
3798 ===============
3799 */
3801 }
3802 
3803 /***********************************************************************
3804 
3805  Events
3806 
3807 ***********************************************************************/
3808 
3809 /*
3810 ================
3811 idEntity::Event_GetName
3812 ================
3813 */
3815  idThread::ReturnString( name.c_str() );
3816 }
3817 
3818 /*
3819 ================
3820 idEntity::Event_SetName
3821 ================
3822 */
3823 void idEntity::Event_SetName( const char *newname ) {
3824  SetName( newname );
3825 }
3826 
3827 /*
3828 ===============
3829 idEntity::Event_FindTargets
3830 ===============
3831 */
3833  FindTargets();
3834 }
3835 
3836 /*
3837 ============
3838 idEntity::Event_ActivateTargets
3839 
3840 Activates any entities targeted by this entity. Mainly used as an
3841 event to delay activating targets.
3842 ============
3843 */
3845  ActivateTargets( activator );
3846 }
3847 
3848 /*
3849 ================
3850 idEntity::Event_NumTargets
3851 ================
3852 */
3855 }
3856 
3857 /*
3858 ================
3859 idEntity::Event_GetTarget
3860 ================
3861 */
3863  int i;
3864 
3865  i = ( int )index;
3866  if ( ( i < 0 ) || i >= targets.Num() ) {
3868  } else {
3869  idThread::ReturnEntity( targets[ i ].GetEntity() );
3870  }
3871 }
3872 
3873 /*
3874 ================
3875 idEntity::Event_RandomTarget
3876 ================
3877 */
3878 void idEntity::Event_RandomTarget( const char *ignore ) {
3879  int num;
3880  idEntity *ent;
3881  int i;
3882  int ignoreNum;
3883 
3885  if ( !targets.Num() ) {
3887  return;
3888  }
3889 
3890  ignoreNum = -1;
3891  if ( ignore && ( ignore[ 0 ] != 0 ) && ( targets.Num() > 1 ) ) {
3892  for( i = 0; i < targets.Num(); i++ ) {
3893  ent = targets[ i ].GetEntity();
3894  if ( ent && ( ent->name == ignore ) ) {
3895  ignoreNum = i;
3896  break;
3897  }
3898  }
3899  }
3900 
3901  if ( ignoreNum >= 0 ) {
3902  num = gameLocal.random.RandomInt( targets.Num() - 1 );
3903  if ( num >= ignoreNum ) {
3904  num++;
3905  }
3906  } else {
3907  num = gameLocal.random.RandomInt( targets.Num() );
3908  }
3909 
3910  ent = targets[ num ].GetEntity();
3911  idThread::ReturnEntity( ent );
3912 }
3913 
3914 /*
3915 ================
3916 idEntity::Event_BindToJoint
3917 ================
3918 */
3919 void idEntity::Event_BindToJoint( idEntity *master, const char *jointname, float orientated ) {
3920  BindToJoint( master, jointname, ( orientated != 0.0f ) );
3921 }
3922 
3923 /*
3924 ================
3925 idEntity::Event_RemoveBinds
3926 ================
3927 */
3929  RemoveBinds();
3930 }
3931 
3932 /*
3933 ================
3934 idEntity::Event_Bind
3935 ================
3936 */
3938  Bind( master, true );
3939 }
3940 
3941 /*
3942 ================
3943 idEntity::Event_BindPosition
3944 ================
3945 */
3947  Bind( master, false );
3948 }
3949 
3950 /*
3951 ================
3952 idEntity::Event_Unbind
3953 ================
3954 */
3956  Unbind();
3957 }
3958 
3959 /*
3960 ================
3961 idEntity::Event_SpawnBind
3962 ================
3963 */
3965  idEntity *parent;
3966  const char *bind, *joint, *bindanim;
3968  bool bindOrientated;
3969  int id;
3970  const idAnim *anim;
3971  int animNum;
3972  idAnimator *parentAnimator;
3973 
3974  if ( spawnArgs.GetString( "bind", "", &bind ) ) {
3975  if ( idStr::Icmp( bind, "worldspawn" ) == 0 ) {
3976  //FIXME: Completely unneccessary since the worldspawn is called "world"
3977  parent = gameLocal.world;
3978  } else {
3979  parent = gameLocal.FindEntity( bind );
3980  }
3981  bindOrientated = spawnArgs.GetBool( "bindOrientated", "1" );
3982  if ( parent ) {
3983  // bind to a joint of the skeletal model of the parent
3984  if ( spawnArgs.GetString( "bindToJoint", "", &joint ) && *joint ) {
3985  parentAnimator = parent->GetAnimator();
3986  if ( !parentAnimator ) {
3987  gameLocal.Error( "Cannot bind to joint '%s' on '%s'. Entity does not support skeletal models.", joint, name.c_str() );
3988  }
3989  bindJoint = parentAnimator->GetJointHandle( joint );
3990  if ( bindJoint == INVALID_JOINT ) {
3991  gameLocal.Error( "Joint '%s' not found for bind on '%s'", joint, name.c_str() );
3992  }
3993 
3994  // bind it relative to a specific anim
3995  if ( ( parent->spawnArgs.GetString( "bindanim", "", &bindanim ) || parent->spawnArgs.GetString( "anim", "", &bindanim ) ) && *bindanim ) {
3996  animNum = parentAnimator->GetAnim( bindanim );
3997  if ( !animNum ) {
3998  gameLocal.Error( "Anim '%s' not found for bind on '%s'", bindanim, name.c_str() );
3999  }
4000  anim = parentAnimator->GetAnim( animNum );
4001  if ( !anim ) {
4002  gameLocal.Error( "Anim '%s' not found for bind on '%s'", bindanim, name.c_str() );
4003  }
4004 
4005  // make sure parent's render origin has been set
4006  parent->UpdateModelTransform();
4007 
4008  //FIXME: need a BindToJoint that accepts a joint position
4009  parentAnimator->CreateFrame( gameLocal.time, true );
4010  idJointMat *frame = parent->renderEntity.joints;
4011  gameEdit->ANIM_CreateAnimFrame( parentAnimator->ModelHandle(), anim->MD5Anim( 0 ), parent->renderEntity.numJoints, frame, 0, parentAnimator->ModelDef()->GetVisualOffset(), parentAnimator->RemoveOrigin() );
4012  BindToJoint( parent, joint, bindOrientated );
4013  parentAnimator->ForceUpdate();
4014  } else {
4015  BindToJoint( parent, joint, bindOrientated );
4016  }
4017  }
4018  // bind to a body of the physics object of the parent
4019  else if ( spawnArgs.GetInt( "bindToBody", "0", id ) ) {
4020  BindToBody( parent, id, bindOrientated );
4021  }
4022  // bind to the parent
4023  else {
4024  Bind( parent, bindOrientated );
4025  }
4026  }
4027  }
4028 }
4029 
4030 /*
4031 ================
4032 idEntity::Event_SetOwner
4033 ================
4034 */
4036  int i;
4037 
4038  for ( i = 0; i < GetPhysics()->GetNumClipModels(); i++ ) {
4039  GetPhysics()->GetClipModel( i )->SetOwner( owner );
4040  }
4041 }
4042 
4043 /*
4044 ================
4045 idEntity::Event_SetModel
4046 ================
4047 */
4048 void idEntity::Event_SetModel( const char *modelname ) {
4049  SetModel( modelname );
4050 }
4051 
4052 /*
4053 ================
4054 idEntity::Event_SetSkin
4055 ================
4056 */
4057 void idEntity::Event_SetSkin( const char *skinname ) {
4059  UpdateVisuals();
4060 }
4061 
4062 /*
4063 ================
4064 idEntity::Event_GetShaderParm
4065 ================
4066 */
4067 void idEntity::Event_GetShaderParm( int parmnum ) {
4068  if ( ( parmnum < 0 ) || ( parmnum >= MAX_ENTITY_SHADER_PARMS ) ) {
4069  gameLocal.Error( "shader parm index (%d) out of range", parmnum );
4070  }
4071 
4073 }
4074 
4075 /*
4076 ================
4077 idEntity::Event_SetShaderParm
4078 ================
4079 */
4080 void idEntity::Event_SetShaderParm( int parmnum, float value ) {
4081  SetShaderParm( parmnum, value );
4082 }
4083 
4084 /*
4085 ================
4086 idEntity::Event_SetShaderParms
4087 ================
4088 */
4089 void idEntity::Event_SetShaderParms( float parm0, float parm1, float parm2, float parm3 ) {
4094  UpdateVisuals();
4095 }
4096 
4097 
4098 /*
4099 ================
4100 idEntity::Event_SetColor
4101 ================
4102 */
4103 void idEntity::Event_SetColor( float red, float green, float blue ) {
4104  SetColor( red, green, blue );
4105 }
4106 
4107 /*
4108 ================
4109 idEntity::Event_GetColor
4110 ================
4111 */
4113  idVec3 out;
4114 
4115  GetColor( out );
4116  idThread::ReturnVector( out );
4117 }
4118 
4119 /*
4120 ================
4121 idEntity::Event_IsHidden
4122 ================
4123 */
4126 }
4127 
4128 /*
4129 ================
4130 idEntity::Event_Hide
4131 ================
4132 */
4133 void idEntity::Event_Hide( void ) {
4134  Hide();
4135 }
4136 
4137 /*
4138 ================
4139 idEntity::Event_Show
4140 ================
4141 */
4142 void idEntity::Event_Show( void ) {
4143  Show();
4144 }
4145 
4146 /*
4147 ================
4148 idEntity::Event_CacheSoundShader
4149 ================
4150 */
4151 void idEntity::Event_CacheSoundShader( const char *soundName ) {
4152  declManager->FindSound( soundName );
4153 }
4154 
4155 /*
4156 ================
4157 idEntity::Event_StartSoundShader
4158 ================
4159 */
4160 void idEntity::Event_StartSoundShader( const char *soundName, int channel ) {
4161  int length;
4162 
4163  StartSoundShader( declManager->FindSound( soundName ), (s_channelType)channel, 0, false, &length );
4164  idThread::ReturnFloat( MS2SEC( length ) );
4165 }
4166 
4167 /*
4168 ================
4169 idEntity::Event_StopSound
4170 ================
4171 */
4172 void idEntity::Event_StopSound( int channel, int netSync ) {
4173  StopSound( channel, ( netSync != 0 ) );
4174 }
4175 
4176 /*
4177 ================
4178 idEntity::Event_StartSound
4179 ================
4180 */
4181 void idEntity::Event_StartSound( const char *soundName, int channel, int netSync ) {
4182  int time;
4183 
4184  StartSound( soundName, ( s_channelType )channel, 0, ( netSync != 0 ), &time );
4185  idThread::ReturnFloat( MS2SEC( time ) );
4186 }
4187 
4188 /*
4189 ================
4190 idEntity::Event_FadeSound
4191 ================
4192 */
4193 void idEntity::Event_FadeSound( int channel, float to, float over ) {
4194  if ( refSound.referenceSound ) {
4195  refSound.referenceSound->FadeSound( channel, to, over );
4196  }
4197 }
4198 
4199 /*
4200 ================
4201 idEntity::Event_GetWorldOrigin
4202 ================
4203 */
4205  idThread::ReturnVector( GetPhysics()->GetOrigin() );
4206 }
4207 
4208 /*
4209 ================
4210 idEntity::Event_SetWorldOrigin
4211 ================
4212 */
4214  idVec3 neworg = GetLocalCoordinates( org );
4215  SetOrigin( neworg );
4216 }
4217 
4218 /*
4219 ================
4220 idEntity::Event_SetOrigin
4221 ================
4222 */
4223 void idEntity::Event_SetOrigin( idVec3 const &org ) {
4224  SetOrigin( org );
4225 }
4226 
4227 /*
4228 ================
4229 idEntity::Event_GetOrigin
4230 ================
4231 */
4234 }
4235 
4236 /*
4237 ================
4238 idEntity::Event_SetAngles
4239 ================
4240 */
4242  SetAngles( ang );
4243 }
4244 
4245 /*
4246 ================
4247 idEntity::Event_GetAngles
4248 ================
4249 */
4251  idAngles ang = GetPhysics()->GetAxis().ToAngles();
4252  idThread::ReturnVector( idVec3( ang[0], ang[1], ang[2] ) );
4253 }
4254 
4255 /*
4256 ================
4257 idEntity::Event_SetLinearVelocity
4258 ================
4259 */
4261  GetPhysics()->SetLinearVelocity( velocity );
4262 }
4263 
4264 /*
4265 ================
4266 idEntity::Event_GetLinearVelocity
4267 ================
4268 */
4270  idThread::ReturnVector( GetPhysics()->GetLinearVelocity() );
4271 }
4272 
4273 /*
4274 ================
4275 idEntity::Event_SetAngularVelocity
4276 ================
4277 */
4279  GetPhysics()->SetAngularVelocity( velocity );
4280 }
4281 
4282 /*
4283 ================
4284 idEntity::Event_GetAngularVelocity
4285 ================
4286 */
4288  idThread::ReturnVector( GetPhysics()->GetAngularVelocity() );
4289 }
4290 
4291 /*
4292 ================
4293 idEntity::Event_SetSize
4294 ================
4295 */
4296 void idEntity::Event_SetSize( idVec3 const &mins, idVec3 const &maxs ) {
4297  GetPhysics()->SetClipBox( idBounds( mins, maxs ), 1.0f );
4298 }
4299 
4300 /*
4301 ================
4302 idEntity::Event_GetSize
4303 ================
4304 */
4306  idBounds bounds;
4307 
4308  bounds = GetPhysics()->GetBounds();
4309  idThread::ReturnVector( bounds[1] - bounds[0] );
4310 }
4311 
4312 /*
4313 ================
4314 idEntity::Event_GetMins
4315 ================
4316 */
4318  idThread::ReturnVector( GetPhysics()->GetBounds()[0] );
4319 }
4320 
4321 /*
4322 ================
4323 idEntity::Event_GetMaxs
4324 ================
4325 */
4327  idThread::ReturnVector( GetPhysics()->GetBounds()[1] );
4328 }
4329 
4330 /*
4331 ================
4332 idEntity::Event_Touches
4333 ================
4334 */
4336  if ( !ent ) {
4337  idThread::ReturnInt( false );
4338  return;
4339  }
4340 
4341  const idBounds &myBounds = GetPhysics()->GetAbsBounds();
4342  const idBounds &entBounds = ent->GetPhysics()->GetAbsBounds();
4343 
4344  idThread::ReturnInt( myBounds.IntersectsBounds( entBounds ) );
4345 }
4346 
4347 /*
4348 ================
4349 idEntity::Event_SetGuiParm
4350 ================
4351 */
4352 void idEntity::Event_SetGuiParm( const char *key, const char *val ) {
4353  for ( int i = 0; i < MAX_RENDERENTITY_GUI; i++ ) {
4354  if ( renderEntity.gui[ i ] ) {
4355  if ( idStr::Icmpn( key, "gui_", 4 ) == 0 ) {
4356  spawnArgs.Set( key, val );
4357  }
4358  renderEntity.gui[ i ]->SetStateString( key, val );
4360  }
4361  }
4362 }
4363 
4364 /*
4365 ================
4366 idEntity::Event_SetGuiParm
4367 ================
4368 */
4369 void idEntity::Event_SetGuiFloat( const char *key, float f ) {
4370  for ( int i = 0; i < MAX_RENDERENTITY_GUI; i++ ) {
4371  if ( renderEntity.gui[ i ] ) {
4372  renderEntity.gui[ i ]->SetStateString( key, va( "%f", f ) );
4374  }
4375  }
4376 }
4377 
4378 /*
4379 ================
4380 idEntity::Event_GetNextKey
4381 ================
4382 */
4383 void idEntity::Event_GetNextKey( const char *prefix, const char *lastMatch ) {
4384  const idKeyValue *kv;
4385  const idKeyValue *previous;
4386 
4387  if ( *lastMatch ) {
4388  previous = spawnArgs.FindKey( lastMatch );
4389  } else {
4390  previous = NULL;
4391  }
4392 
4393  kv = spawnArgs.MatchPrefix( prefix, previous );
4394  if ( !kv ) {
4395  idThread::ReturnString( "" );
4396  } else {
4397  idThread::ReturnString( kv->GetKey() );
4398  }
4399 }
4400 
4401 /*
4402 ================
4403 idEntity::Event_SetKey
4404 ================
4405 */
4406 void idEntity::Event_SetKey( const char *key, const char *value ) {
4407  spawnArgs.Set( key, value );
4408 #ifdef _D3XP
4410 #endif
4411 }
4412 
4413 /*
4414 ================
4415 idEntity::Event_GetKey
4416 ================
4417 */
4418 void idEntity::Event_GetKey( const char *key ) {
4419  const char *value;
4420 
4421  spawnArgs.GetString( key, "", &value );
4422  idThread::ReturnString( value );
4423 }
4424 
4425 /*
4426 ================
4427 idEntity::Event_GetIntKey
4428 ================
4429 */
4430 void idEntity::Event_GetIntKey( const char *key ) {
4431  int value;
4432 
4433  spawnArgs.GetInt( key, "0", value );
4434 
4435  // scripts only support floats
4436  idThread::ReturnFloat( value );
4437 }
4438 
4439 /*
4440 ================
4441 idEntity::Event_GetFloatKey
4442 ================
4443 */
4444 void idEntity::Event_GetFloatKey( const char *key ) {
4445  float value;
4446 
4447  spawnArgs.GetFloat( key, "0", value );
4448  idThread::ReturnFloat( value );
4449 }
4450 
4451 /*
4452 ================
4453 idEntity::Event_GetVectorKey
4454 ================
4455 */
4456 void idEntity::Event_GetVectorKey( const char *key ) {
4457  idVec3 value;
4458 
4459  spawnArgs.GetVector( key, "0 0 0", value );
4460  idThread::ReturnVector( value );
4461 }
4462 
4463 /*
4464 ================
4465 idEntity::Event_GetEntityKey
4466 ================
4467 */
4468 void idEntity::Event_GetEntityKey( const char *key ) {
4469  idEntity *ent;
4470  const char *entname;
4471 
4472  if ( !spawnArgs.GetString( key, NULL, &entname ) ) {
4474  return;
4475  }
4476 
4477  ent = gameLocal.FindEntity( entname );
4478  if ( !ent ) {
4479  gameLocal.Warning( "Couldn't find entity '%s' specified in '%s' key in entity '%s'", entname, key, name.c_str() );
4480  }
4481 
4482  idThread::ReturnEntity( ent );
4483 }
4484 
4485 /*
4486 ================
4487 idEntity::Event_RestorePosition
4488 ================
4489 */
4491  idVec3 org;
4492  idAngles angles;
4493  idMat3 axis;
4494  idEntity * part;
4495 
4496  spawnArgs.GetVector( "origin", "0 0 0", org );
4497 
4498  // get the rotation matrix in either full form, or single angle form
4499  if ( spawnArgs.GetMatrix( "rotation", "1 0 0 0 1 0 0 0 1", axis ) ) {
4500  angles = axis.ToAngles();
4501  } else {
4502  angles[ 0 ] = 0;
4503  angles[ 1 ] = spawnArgs.GetFloat( "angle" );
4504  angles[ 2 ] = 0;
4505  }
4506 
4507  Teleport( org, angles, NULL );
4508 
4509  for ( part = teamChain; part != NULL; part = part->teamChain ) {
4510  if ( part->bindMaster != this ) {
4511  continue;
4512  }
4513  if ( part->GetPhysics()->IsType( idPhysics_Parametric::Type ) ) {
4514  if ( static_cast<idPhysics_Parametric *>(part->GetPhysics())->IsPusher() ) {
4515  gameLocal.Warning( "teleported '%s' which has the pushing mover '%s' bound to it\n", GetName(), part->GetName() );
4516  }
4517  } else if ( part->GetPhysics()->IsType( idPhysics_AF::Type ) ) {
4518  gameLocal.Warning( "teleported '%s' which has the articulated figure '%s' bound to it\n", GetName(), part->GetName() );
4519  }
4520  }
4521 }
4522 
4523 /*
4524 ================
4525 idEntity::Event_UpdateCameraTarget
4526 ================
4527 */
4529  const char *target;
4530  const idKeyValue *kv;
4531  idVec3 dir;
4532 
4533  target = spawnArgs.GetString( "cameraTarget" );
4534 
4535  cameraTarget = gameLocal.FindEntity( target );
4536 
4537  if ( cameraTarget ) {
4538  kv = cameraTarget->spawnArgs.MatchPrefix( "target", NULL );
4539  while( kv ) {
4540  idEntity *ent = gameLocal.FindEntity( kv->GetValue() );
4541  if ( ent && idStr::Icmp( ent->GetEntityDefName(), "target_null" ) == 0) {
4542  dir = ent->GetPhysics()->GetOrigin() - cameraTarget->GetPhysics()->GetOrigin();
4543  dir.Normalize();
4544  cameraTarget->SetAxis( dir.ToMat3() );
4545  SetAxis(dir.ToMat3());
4546  break;
4547  }
4548  kv = cameraTarget->spawnArgs.MatchPrefix( "target", kv );
4549  }
4550  }
4551  UpdateVisuals();
4552 }
4553 
4554 /*
4555 ================
4556 idEntity::Event_DistanceTo
4557 ================
4558 */
4560  if ( !ent ) {
4561  // just say it's really far away
4563  } else {
4564  float dist = ( GetPhysics()->GetOrigin() - ent->GetPhysics()->GetOrigin() ).LengthFast();
4565  idThread::ReturnFloat( dist );
4566  }
4567 }
4568 
4569 /*
4570 ================
4571 idEntity::Event_DistanceToPoint
4572 ================
4573 */
4575  float dist = ( GetPhysics()->GetOrigin() - point ).LengthFast();
4576  idThread::ReturnFloat( dist );
4577 }
4578 
4579 /*
4580 ================
4581 idEntity::Event_StartFx
4582 ================
4583 */
4584 void idEntity::Event_StartFx( const char *fx ) {
4585  idEntityFx::StartFx( fx, NULL, NULL, this, true );
4586 }
4587 
4588 /*
4589 ================
4590 idEntity::Event_WaitFrame
4591 ================
4592 */
4594  idThread *thread;
4595 
4596  thread = idThread::CurrentThread();
4597  if ( thread ) {
4598  thread->WaitFrame();
4599  }
4600 }
4601 
4602 /*
4603 =====================
4604 idEntity::Event_Wait
4605 =====================
4606 */
4607 void idEntity::Event_Wait( float time ) {
4608  idThread *thread = idThread::CurrentThread();
4609 
4610  if ( !thread ) {
4611  gameLocal.Error( "Event 'wait' called from outside thread" );
4612  }
4613 
4614  thread->WaitSec( time );
4615 }
4616 
4617 /*
4618 =====================
4619 idEntity::Event_HasFunction
4620 =====================
4621 */
4622 void idEntity::Event_HasFunction( const char *name ) {
4623  const function_t *func;
4624 
4625  func = scriptObject.GetFunction( name );
4626  if ( func ) {
4627  idThread::ReturnInt( true );
4628  } else {
4629  idThread::ReturnInt( false );
4630  }
4631 }
4632 
4633 /*
4634 =====================
4635 idEntity::Event_CallFunction
4636 =====================
4637 */
4638 void idEntity::Event_CallFunction( const char *funcname ) {
4639  const function_t *func;
4640  idThread *thread;
4641 
4642  thread = idThread::CurrentThread();
4643  if ( !thread ) {
4644  gameLocal.Error( "Event 'callFunction' called from outside thread" );
4645  }
4646 
4647  func = scriptObject.GetFunction( funcname );
4648  if ( !func ) {
4649  gameLocal.Error( "Unknown function '%s' in '%s'", funcname, scriptObject.GetTypeName() );
4650  }
4651 
4652  if ( func->type->NumParameters() != 1 ) {
4653  gameLocal.Error( "Function '%s' has the wrong number of parameters for 'callFunction'", funcname );
4654  }
4655  if ( !scriptObject.GetTypeDef()->Inherits( func->type->GetParmType( 0 ) ) ) {
4656  gameLocal.Error( "Function '%s' is the wrong type for 'callFunction'", funcname );
4657  }
4658 
4659  // function args will be invalid after this call
4660  thread->CallFunction( this, func, false );
4661 }
4662 
4663 /*
4664 ================
4665 idEntity::Event_SetNeverDormant
4666 ================
4667 */
4669  fl.neverDormant = ( enable != 0 );
4670  dormantStart = 0;
4671 }
4672 
4673 #ifdef _D3XP
4674 /*
4675 ================
4676 idEntity::Event_SetGui
4677 ================
4678 * BSM Nerve: Allows guis to be changed at runtime. Guis that are
4679 * loaded after the level loads should be precahced using PrecacheGui.
4680 */
4681 void idEntity::Event_SetGui( int guiNum, const char *guiName) {
4682  idUserInterface** gui = NULL;
4683 
4684  if ( guiNum >= 1 && guiNum <= MAX_RENDERENTITY_GUI ) {
4685  gui = &renderEntity.gui[ guiNum-1 ];
4686  }
4687 
4688  if( gui ) {
4689  *gui = uiManager->FindGui( guiName, true, false );
4690  UpdateGuiParms( *gui, &spawnArgs );
4693 
4694  } else {
4695  gameLocal.Error( "Entity '%s' doesn't have a GUI %d", name.c_str(), guiNum );
4696  }
4697 
4698 }
4699 
4700 /*
4701 ================
4702 idEntity::Event_PrecacheGui
4703 ================
4704 * BSM Nerve: Forces the engine to initialize a gui even if it is not specified as used in a level.
4705 * This is useful for preventing load hitches when switching guis during the game using "setGui"
4706 */
4707 void idEntity::Event_PrecacheGui( const char *guiName ) {
4708  uiManager->FindGui( guiName, true, true );
4709 }
4710 
4711 void idEntity::Event_GetGuiParm(int guiNum, const char *key) {
4712  if(renderEntity.gui[guiNum-1]) {
4714  return;
4715  }
4717 }
4718 
4719 void idEntity::Event_GetGuiParmFloat(int guiNum, const char *key) {
4720  if(renderEntity.gui[guiNum-1]) {
4722  return;
4723  }
4725 }
4726 
4727 void idEntity::Event_GuiNamedEvent(int guiNum, const char *event) {
4728  if(renderEntity.gui[guiNum-1]) {
4729  renderEntity.gui[guiNum-1]->HandleNamedEvent(event);
4730  }
4731 }
4732 
4733 #endif
4734 
4735 /***********************************************************************
4736 
4737  Network
4738 
4739 ***********************************************************************/
4740 
4741 /*
4742 ================
4743 idEntity::ClientPredictionThink
4744 ================
4745 */
4747  RunPhysics();
4748  Present();
4749 }
4750 
4751 /*
4752 ================
4753 idEntity::WriteBindToSnapshot
4754 ================
4755 */
4757  int bindInfo;
4758 
4759  if ( bindMaster ) {
4760  bindInfo = bindMaster->entityNumber;
4761  bindInfo |= ( fl.bindOrientated & 1 ) << GENTITYNUM_BITS;
4762  if ( bindJoint != INVALID_JOINT ) {
4763  bindInfo |= 1 << ( GENTITYNUM_BITS + 1 );
4764  bindInfo |= bindJoint << ( 3 + GENTITYNUM_BITS );
4765  } else if ( bindBody != -1 ) {
4766  bindInfo |= 2 << ( GENTITYNUM_BITS + 1 );
4767  bindInfo |= bindBody << ( 3 + GENTITYNUM_BITS );
4768  }
4769  } else {
4770  bindInfo = ENTITYNUM_NONE;
4771  }
4772  msg.WriteBits( bindInfo, GENTITYNUM_BITS + 3 + 9 );
4773 }
4774 
4775 /*
4776 ================
4777 idEntity::ReadBindFromSnapshot
4778 ================
4779 */
4781  int bindInfo, bindEntityNum, bindPos;
4782  bool bindOrientated;
4783  idEntity *master;
4784 
4785  bindInfo = msg.ReadBits( GENTITYNUM_BITS + 3 + 9 );
4786  bindEntityNum = bindInfo & ( ( 1 << GENTITYNUM_BITS ) - 1 );
4787 
4788  if ( bindEntityNum != ENTITYNUM_NONE ) {
4789  master = gameLocal.entities[ bindEntityNum ];
4790 
4791  bindOrientated = ( bindInfo >> GENTITYNUM_BITS ) & 1;
4792  bindPos = ( bindInfo >> ( GENTITYNUM_BITS + 3 ) );
4793  switch( ( bindInfo >> ( GENTITYNUM_BITS + 1 ) ) & 3 ) {
4794  case 1: {
4795  BindToJoint( master, (jointHandle_t) bindPos, bindOrientated );
4796  break;
4797  }
4798  case 2: {
4799  BindToBody( master, bindPos, bindOrientated );
4800  break;
4801  }
4802  default: {
4803  Bind( master, bindOrientated );
4804  break;
4805  }
4806  }
4807  } else if ( bindMaster ) {
4808  Unbind();
4809  }
4810 }
4811 
4812 /*
4813 ================
4814 idEntity::WriteColorToSnapshot
4815 ================
4816 */
4818  idVec4 color;
4819 
4820  color[0] = renderEntity.shaderParms[ SHADERPARM_RED ];
4824  msg.WriteLong( PackColor( color ) );
4825 }
4826 
4827 /*
4828 ================
4829 idEntity::ReadColorFromSnapshot
4830 ================
4831 */
4833  idVec4 color;
4834 
4835  UnpackColor( msg.ReadLong(), color );
4836  renderEntity.shaderParms[ SHADERPARM_RED ] = color[0];
4840 }
4841 
4842 /*
4843 ================
4844 idEntity::WriteGUIToSnapshot
4845 ================
4846 */
4848  // no need to loop over MAX_RENDERENTITY_GUI at this time
4849  if ( renderEntity.gui[ 0 ] ) {
4850  msg.WriteByte( renderEntity.gui[ 0 ]->State().GetInt( "networkState" ) );
4851  } else {
4852  msg.WriteByte( 0 );
4853  }
4854 }
4855 
4856 /*
4857 ================
4858 idEntity::ReadGUIFromSnapshot
4859 ================
4860 */
4862  int state;
4863  idUserInterface *gui;
4864  state = msg.ReadByte( );
4865  gui = renderEntity.gui[ 0 ];
4866  if ( gui && state != mpGUIState ) {
4867  mpGUIState = state;
4868  gui->SetStateInt( "networkState", state );
4869  gui->HandleNamedEvent( "networkState" );
4870  }
4871 }
4872 
4873 /*
4874 ================
4875 idEntity::WriteToSnapshot
4876 ================
4877 */
4879 }
4880 
4881 /*
4882 ================
4883 idEntity::ReadFromSnapshot
4884 ================
4885 */
4887 }
4888 
4889 /*
4890 ================
4891 idEntity::ServerSendEvent
4892 
4893  Saved events are also sent to any client that connects late so all clients
4894  always receive the events nomatter what time they join the game.
4895 ================
4896 */
4897 void idEntity::ServerSendEvent( int eventId, const idBitMsg *msg, bool saveEvent, int excludeClient ) const {
4898  idBitMsg outMsg;
4899  byte msgBuf[MAX_GAME_MESSAGE_SIZE];
4900 
4901  if ( !gameLocal.isServer ) {
4902  return;
4903  }
4904 
4905  // prevent dupe events caused by frame re-runs
4906  if ( !gameLocal.isNewFrame ) {
4907  return;
4908  }
4909 
4910  outMsg.Init( msgBuf, sizeof( msgBuf ) );
4911  outMsg.BeginWriting();
4913  outMsg.WriteBits( gameLocal.GetSpawnId( this ), 32 );
4914  outMsg.WriteByte( eventId );
4915  outMsg.WriteLong( gameLocal.time );
4916  if ( msg ) {
4918  outMsg.WriteData( msg->GetData(), msg->GetSize() );
4919  } else {
4921  }
4922 
4923  if ( excludeClient != -1 ) {
4924  networkSystem->ServerSendReliableMessageExcluding( excludeClient, outMsg );
4925  } else {
4927  }
4928 
4929  if ( saveEvent ) {
4930  gameLocal.SaveEntityNetworkEvent( this, eventId, msg );
4931  }
4932 }
4933 
4934 /*
4935 ================
4936 idEntity::ClientSendEvent
4937 ================
4938 */
4939 void idEntity::ClientSendEvent( int eventId, const idBitMsg *msg ) const {
4940  idBitMsg outMsg;
4941  byte msgBuf[MAX_GAME_MESSAGE_SIZE];
4942 
4943  if ( !gameLocal.isClient ) {
4944  return;
4945  }
4946 
4947  // prevent dupe events caused by frame re-runs
4948  if ( !gameLocal.isNewFrame ) {
4949  return;
4950  }
4951 
4952  outMsg.Init( msgBuf, sizeof( msgBuf ) );
4953  outMsg.BeginWriting();
4955  outMsg.WriteBits( gameLocal.GetSpawnId( this ), 32 );
4956  outMsg.WriteByte( eventId );
4957  outMsg.WriteLong( gameLocal.time );
4958  if ( msg ) {
4960  outMsg.WriteData( msg->GetData(), msg->GetSize() );
4961  } else {
4963  }
4964 
4966 }
4967 
4968 /*
4969 ================
4970 idEntity::ServerReceiveEvent
4971 ================
4972 */
4973 bool idEntity::ServerReceiveEvent( int event, int time, const idBitMsg &msg ) {
4974  switch( event ) {
4975  case 0: {
4976  }
4977  default: {
4978  return false;
4979  }
4980  }
4981 }
4982 
4983 /*
4984 ================
4985 idEntity::ClientReceiveEvent
4986 ================
4987 */
4988 bool idEntity::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) {
4989  int index;
4990  const idSoundShader *shader;
4991  s_channelType channel;
4992 
4993  switch( event ) {
4994  case EVENT_STARTSOUNDSHADER: {
4995  // the sound stuff would early out
4997  if ( time < gameLocal.realClientTime - 1000 ) {
4998  // too old, skip it ( reliable messages don't need to be parsed in full )
4999  common->DPrintf( "ent 0x%x: start sound shader too old (%d ms)\n", entityNumber, gameLocal.realClientTime - time );
5000  return true;
5001  }
5002  index = gameLocal.ClientRemapDecl( DECL_SOUND, msg.ReadLong() );
5003  if ( index >= 0 && index < declManager->GetNumDecls( DECL_SOUND ) ) {
5004  shader = declManager->SoundByIndex( index, false );
5005  channel = (s_channelType)msg.ReadByte();
5006  StartSoundShader( shader, channel, 0, false, NULL );
5007  }
5008  return true;
5009  }
5010  case EVENT_STOPSOUNDSHADER: {
5011  // the sound stuff would early out
5013  channel = (s_channelType)msg.ReadByte();
5014  StopSound( channel, false );
5015  return true;
5016  }
5017  default: {
5018  return false;
5019  }
5020  }
5021  return false;
5022 }
5023 
5024 #ifdef _D3XP
5025 /*
5026 ================
5027 idEntity::DetermineTimeGroup
5028 ================
5029 */
5030 void idEntity::DetermineTimeGroup( bool slowmo ) {
5031  if ( slowmo || gameLocal.isMultiplayer ) {
5032  timeGroup = TIME_GROUP1;
5033  }
5034  else {
5035  timeGroup = TIME_GROUP2;
5036  }
5037 }
5038 
5039 /*
5040 ================
5041 idEntity::SetGrabbedState
5042 ================
5043 */
5044 void idEntity::SetGrabbedState( bool grabbed ) {
5045  fl.grabbed = grabbed;
5046 }
5047 
5048 /*
5049 ================
5050 idEntity::IsGrabbed
5051 ================
5052 */
5053 bool idEntity::IsGrabbed() {
5054  return fl.grabbed;
5055 }
5056 #endif
5057 
5058 /*
5059 ===============================================================================
5060 
5061  idAnimatedEntity
5062 
5063 ===============================================================================
5064 */
5065 
5066 const idEventDef EV_GetJointHandle( "getJointHandle", "s", 'd' );
5067 const idEventDef EV_ClearAllJoints( "clearAllJoints" );
5068 const idEventDef EV_ClearJoint( "clearJoint", "d" );
5069 const idEventDef EV_SetJointPos( "setJointPos", "ddv" );
5070 const idEventDef EV_SetJointAngle( "setJointAngle", "ddv" );
5071 const idEventDef EV_GetJointPos( "getJointPos", "d", 'v' );
5072 const idEventDef EV_GetJointAngle( "getJointAngle", "d", 'v' );
5073 
5075  EVENT( EV_GetJointHandle, idAnimatedEntity::Event_GetJointHandle )
5076  EVENT( EV_ClearAllJoints, idAnimatedEntity::Event_ClearAllJoints )
5077  EVENT( EV_ClearJoint, idAnimatedEntity::Event_ClearJoint )
5078  EVENT( EV_SetJointPos, idAnimatedEntity::Event_SetJointPos )
5079  EVENT( EV_SetJointAngle, idAnimatedEntity::Event_SetJointAngle )
5080  EVENT( EV_GetJointPos, idAnimatedEntity::Event_GetJointPos )
5081  EVENT( EV_GetJointAngle, idAnimatedEntity::Event_GetJointAngle )
5082 END_CLASS
5083 
5084 /*
5085 ================
5086 idAnimatedEntity::idAnimatedEntity
5087 ================
5088 */
5090  animator.SetEntity( this );
5091  damageEffects = NULL;
5092 }
5093 
5094 /*
5095 ================
5096 idAnimatedEntity::~idAnimatedEntity
5097 ================
5098 */
5100  damageEffect_t *de;
5101 
5102  for ( de = damageEffects; de; de = damageEffects ) {
5103  damageEffects = de->next;
5104  delete de;
5105  }
5106 }
5107 
5108 /*
5109 ================
5110 idAnimatedEntity::Save
5111 
5112 archives object for save game file
5113 ================
5114 */
5115 void idAnimatedEntity::Save( idSaveGame *savefile ) const {
5116  animator.Save( savefile );
5117 
5118  // Wounds are very temporary, ignored at this time
5119  //damageEffect_t *damageEffects;
5120 }
5121 
5122 /*
5123 ================
5124 idAnimatedEntity::Restore
5125 
5126 unarchives object from save game file
5127 ================
5128 */
5130  animator.Restore( savefile );
5131 
5132  // check if the entity has an MD5 model
5133  if ( animator.ModelHandle() ) {
5134  // set the callback to update the joints
5138  if ( modelDefHandle != -1 ) {
5140  }
5141  }
5142 }
5143 
5144 /*
5145 ================
5146 idAnimatedEntity::ClientPredictionThink
5147 ================
5148 */
5150  RunPhysics();
5151  UpdateAnimation();
5152  Present();
5153 }
5154 
5155 /*
5156 ================
5157 idAnimatedEntity::Think
5158 ================
5159 */
5161  RunPhysics();
5162  UpdateAnimation();
5163  Present();
5165 }
5166 
5167 /*
5168 ================
5169 idAnimatedEntity::UpdateAnimation
5170 ================
5171 */
5173  // don't do animations if they're not enabled
5174  if ( !( thinkFlags & TH_ANIMATE ) ) {
5175  return;
5176  }
5177 
5178  // is the model an MD5?
5179  if ( !animator.ModelHandle() ) {
5180  // no, so nothing to do
5181  return;
5182  }
5183 
5184  // call any frame commands that have happened in the past frame
5185  if ( !fl.hidden ) {
5187  }
5188 
5189  // if the model is animating then we have to update it
5190  if ( !animator.FrameHasChanged( gameLocal.time ) ) {
5191  // still fine the way it was
5192  return;
5193  }
5194 
5195  // get the latest frame bounds
5197  if ( renderEntity.bounds.IsCleared() && !fl.hidden ) {
5198  gameLocal.DPrintf( "%d: inside out bounds\n", gameLocal.time );
5199  }
5200 
5201  // update the renderEntity
5202  UpdateVisuals();
5203 
5204  // the animation is updated
5206 }
5207 
5208 /*
5209 ================
5210 idAnimatedEntity::GetAnimator
5211 ================
5212 */
5214  return &animator;
5215 }
5216 
5217 /*
5218 ================
5219 idAnimatedEntity::SetModel
5220 ================
5221 */
5222 void idAnimatedEntity::SetModel( const char *modelname ) {
5223  FreeModelDef();
5224 
5225  renderEntity.hModel = animator.SetModel( modelname );
5226  if ( !renderEntity.hModel ) {
5227  idEntity::SetModel( modelname );
5228  return;
5229  }
5230 
5231  if ( !renderEntity.customSkin ) {
5233  }
5234 
5235  // set the callback to update the joints
5239 
5240  UpdateVisuals();
5241 }
5242 
5243 /*
5244 =====================
5245 idAnimatedEntity::GetJointWorldTransform
5246 =====================
5247 */
5248 bool idAnimatedEntity::GetJointWorldTransform( jointHandle_t jointHandle, int currentTime, idVec3 &offset, idMat3 &axis ) {
5249  if ( !animator.GetJointTransform( jointHandle, currentTime, offset, axis ) ) {
5250  return false;
5251  }
5252 
5253  ConvertLocalToWorldTransform( offset, axis );
5254  return true;
5255 }
5256 
5257 /*
5258 ==============
5259 idAnimatedEntity::GetJointTransformForAnim
5260 ==============
5261 */
5262 bool idAnimatedEntity::GetJointTransformForAnim( jointHandle_t jointHandle, int animNum, int frameTime, idVec3 &offset, idMat3 &axis ) const {
5263  const idAnim *anim;
5264  int numJoints;
5265  idJointMat *frame;
5266 
5267  anim = animator.GetAnim( animNum );
5268  if ( !anim ) {
5269  assert( 0 );
5270  return false;
5271  }
5272 
5273  numJoints = animator.NumJoints();
5274  if ( ( jointHandle < 0 ) || ( jointHandle >= numJoints ) ) {
5275  assert( 0 );
5276  return false;
5277  }
5278 
5279  frame = ( idJointMat * )_alloca16( numJoints * sizeof( idJointMat ) );
5281 
5282  offset = frame[ jointHandle ].ToVec3();
5283  axis = frame[ jointHandle ].ToMat3();
5284 
5285  return true;
5286 }
5287 
5288 /*
5289 ==============
5290 idAnimatedEntity::AddDamageEffect
5291 
5292  Dammage effects track the animating impact position, spitting out particles.
5293 ==============
5294 */
5295 void idAnimatedEntity::AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ) {
5296  jointHandle_t jointNum;
5297  idVec3 origin, dir, localDir, localOrigin, localNormal;
5298  idMat3 axis;
5299 
5300  if ( !g_bloodEffects.GetBool() || renderEntity.joints == NULL ) {
5301  return;
5302  }
5303 
5304  const idDeclEntityDef *def = gameLocal.FindEntityDef( damageDefName, false );
5305  if ( def == NULL ) {
5306  return;
5307  }
5308 
5309  jointNum = CLIPMODEL_ID_TO_JOINT_HANDLE( collision.c.id );
5310  if ( jointNum == INVALID_JOINT ) {
5311  return;
5312  }
5313 
5314  dir = velocity;
5315  dir.Normalize();
5316 
5317  axis = renderEntity.joints[jointNum].ToMat3() * renderEntity.axis;
5318  origin = renderEntity.origin + renderEntity.joints[jointNum].ToVec3() * renderEntity.axis;
5319 
5320  localOrigin = ( collision.c.point - origin ) * axis.Transpose();
5321  localNormal = collision.c.normal * axis.Transpose();
5322  localDir = dir * axis.Transpose();
5323 
5324  AddLocalDamageEffect( jointNum, localOrigin, localNormal, localDir, def, collision.c.material );
5325 
5326  if ( gameLocal.isServer ) {
5327  idBitMsg msg;
5328  byte msgBuf[MAX_EVENT_PARAM_SIZE];
5329 
5330  msg.Init( msgBuf, sizeof( msgBuf ) );
5331  msg.BeginWriting();
5332  msg.WriteShort( (int)jointNum );
5333  msg.WriteFloat( localOrigin[0] );
5334  msg.WriteFloat( localOrigin[1] );
5335  msg.WriteFloat( localOrigin[2] );
5336  msg.WriteDir( localNormal, 24 );
5337  msg.WriteDir( localDir, 24 );
5338  msg.WriteLong( gameLocal.ServerRemapDecl( -1, DECL_ENTITYDEF, def->Index() ) );
5339  msg.WriteLong( gameLocal.ServerRemapDecl( -1, DECL_MATERIAL, collision.c.material->Index() ) );
5340  ServerSendEvent( EVENT_ADD_DAMAGE_EFFECT, &msg, false, -1 );
5341  }
5342 }
5343 
5344 /*
5345 ==============
5346 idAnimatedEntity::GetDefaultSurfaceType
5347 ==============
5348 */
5350  return SURFTYPE_METAL;
5351 }
5352 
5353 /*
5354 ==============
5355 idAnimatedEntity::AddLocalDamageEffect
5356 ==============
5357 */
5358 void idAnimatedEntity::AddLocalDamageEffect( jointHandle_t jointNum, const idVec3 &localOrigin, const idVec3 &localNormal, const idVec3 &localDir, const idDeclEntityDef *def, const idMaterial *collisionMaterial ) {
5359  const char *sound, *splat, *decal, *bleed, *key;
5360  damageEffect_t *de;
5361  idVec3 origin, dir;
5362  idMat3 axis;
5363 
5364 #ifdef _D3XP
5365  SetTimeState ts( timeGroup );
5366 #endif
5367 
5368  axis = renderEntity.joints[jointNum].ToMat3() * renderEntity.axis;
5369  origin = renderEntity.origin + renderEntity.joints[jointNum].ToVec3() * renderEntity.axis;
5370 
5371  origin = origin + localOrigin * axis;
5372  dir = localDir * axis;
5373 
5374  int type = collisionMaterial->GetSurfaceType();
5375  if ( type == SURFTYPE_NONE ) {
5376  type = GetDefaultSurfaceType();
5377  }
5378 
5379  const char *materialType = gameLocal.sufaceTypeNames[ type ];
5380 
5381  // start impact sound based on material type
5382  key = va( "snd_%s", materialType );
5383  sound = spawnArgs.GetString( key );
5384  if ( *sound == '\0' ) {
5385  sound = def->dict.GetString( key );
5386  }
5387  if ( *sound != '\0' ) {
5388  StartSoundShader( declManager->FindSound( sound ), SND_CHANNEL_BODY, 0, false, NULL );
5389  }
5390 
5391  // blood splats are thrown onto nearby surfaces
5392  key = va( "mtr_splat_%s", materialType );
5393  splat = spawnArgs.RandomPrefix( key, gameLocal.random );
5394  if ( *splat == '\0' ) {
5395  splat = def->dict.RandomPrefix( key, gameLocal.random );
5396  }
5397  if ( *splat != '\0' ) {
5398  gameLocal.BloodSplat( origin, dir, 64.0f, splat );
5399  }
5400 
5401  // can't see wounds on the player model in single player mode
5402  if ( !( IsType( idPlayer::Type ) && !gameLocal.isMultiplayer ) ) {
5403  // place a wound overlay on the model
5404  key = va( "mtr_wound_%s", materialType );
5405  decal = spawnArgs.RandomPrefix( key, gameLocal.random );
5406  if ( *decal == '\0' ) {
5407  decal = def->dict.RandomPrefix( key, gameLocal.random );
5408  }
5409  if ( *decal != '\0' ) {
5410  ProjectOverlay( origin, dir, 20.0f, decal );
5411  }
5412  }
5413 
5414  // a blood spurting wound is added
5415  key = va( "smoke_wound_%s", materialType );
5416  bleed = spawnArgs.GetString( key );
5417  if ( *bleed == '\0' ) {
5418  bleed = def->dict.GetString( key );
5419  }
5420  if ( *bleed != '\0' ) {
5421  de = new damageEffect_t;
5422  de->next = this->damageEffects;
5423  this->damageEffects = de;
5424 
5425  de->jointNum = jointNum;
5426  de->localOrigin = localOrigin;
5427  de->localNormal = localNormal;
5428  de->type = static_cast<const idDeclParticle *>( declManager->FindType( DECL_PARTICLE, bleed ) );
5429  de->time = gameLocal.time;
5430  }
5431 }
5432 
5433 /*
5434 ==============
5435 idAnimatedEntity::UpdateDamageEffects
5436 ==============
5437 */
5439  damageEffect_t *de, **prev;
5440 
5441  // free any that have timed out
5442  prev = &this->damageEffects;
5443  while ( *prev ) {
5444  de = *prev;
5445  if ( de->time == 0 ) { // FIXME:SMOKE
5446  *prev = de->next;
5447  delete de;
5448  } else {
5449  prev = &de->next;
5450  }
5451  }
5452 
5453  if ( !g_bloodEffects.GetBool() ) {
5454  return;
5455  }
5456 
5457  // emit a particle for each bleeding wound
5458  for ( de = this->damageEffects; de; de = de->next ) {
5459  idVec3 origin, start;
5460  idMat3 axis;
5461 
5462  animator.GetJointTransform( de->jointNum, gameLocal.time, origin, axis );
5463  axis *= renderEntity.axis;
5464  origin = renderEntity.origin + origin * renderEntity.axis;
5465  start = origin + de->localOrigin * axis;
5466  if ( !gameLocal.smokeParticles->EmitSmoke( de->type, de->time, gameLocal.random.CRandomFloat(), start, axis, timeGroup /*_D3XP*/ ) ) {
5467  de->time = 0;
5468  }
5469  }
5470 }
5471 
5472 /*
5473 ================
5474 idAnimatedEntity::ClientReceiveEvent
5475 ================
5476 */
5477 bool idAnimatedEntity::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) {
5478  int damageDefIndex;
5479  int materialIndex;
5480  jointHandle_t jointNum;
5481  idVec3 localOrigin, localNormal, localDir;
5482 
5483  switch( event ) {
5484  case EVENT_ADD_DAMAGE_EFFECT: {
5485  jointNum = (jointHandle_t) msg.ReadShort();
5486  localOrigin[0] = msg.ReadFloat();
5487  localOrigin[1] = msg.ReadFloat();
5488  localOrigin[2] = msg.ReadFloat();
5489  localNormal = msg.ReadDir( 24 );
5490  localDir = msg.ReadDir( 24 );
5491  damageDefIndex = gameLocal.ClientRemapDecl( DECL_ENTITYDEF, msg.ReadLong() );
5492  materialIndex = gameLocal.ClientRemapDecl( DECL_MATERIAL, msg.ReadLong() );
5493  const idDeclEntityDef *damageDef = static_cast<const idDeclEntityDef *>( declManager->DeclByIndex( DECL_ENTITYDEF, damageDefIndex ) );
5494  const idMaterial *collisionMaterial = static_cast<const idMaterial *>( declManager->DeclByIndex( DECL_MATERIAL, materialIndex ) );
5495  AddLocalDamageEffect( jointNum, localOrigin, localNormal, localDir, damageDef, collisionMaterial );
5496  return true;
5497  }
5498  default: {
5499  return idEntity::ClientReceiveEvent( event, time, msg );
5500  }
5501  }
5502  return false;
5503 }
5504 
5505 /*
5506 ================
5507 idAnimatedEntity::Event_GetJointHandle
5508 
5509 looks up the number of the specified joint. returns INVALID_JOINT if the joint is not found.
5510 ================
5511 */
5512 void idAnimatedEntity::Event_GetJointHandle( const char *jointname ) {
5513  jointHandle_t joint;
5514 
5515  joint = animator.GetJointHandle( jointname );
5516  idThread::ReturnInt( joint );
5517 }
5518 
5519 /*
5520 ================
5521 idAnimatedEntity::Event_ClearAllJoints
5522 
5523 removes any custom transforms on all joints
5524 ================
5525 */
5528 }
5529 
5530 /*
5531 ================
5532 idAnimatedEntity::Event_ClearJoint
5533 
5534 removes any custom transforms on the specified joint
5535 ================
5536 */
5538  animator.ClearJoint( jointnum );
5539 }
5540 
5541 /*
5542 ================
5543 idAnimatedEntity::Event_SetJointPos
5544 
5545 modifies the position of the joint based on the transform type
5546 ================
5547 */
5548 void idAnimatedEntity::Event_SetJointPos( jointHandle_t jointnum, jointModTransform_t transform_type, const idVec3 &pos ) {
5549  animator.SetJointPos( jointnum, transform_type, pos );
5550 }
5551 
5552 /*
5553 ================
5554 idAnimatedEntity::Event_SetJointAngle
5555 
5556 modifies the orientation of the joint based on the transform type
5557 ================
5558 */
5559 void idAnimatedEntity::Event_SetJointAngle( jointHandle_t jointnum, jointModTransform_t transform_type, const idAngles &angles ) {
5560  idMat3 mat;
5561 
5562  mat = angles.ToMat3();
5563  animator.SetJointAxis( jointnum, transform_type, mat );
5564 }
5565 
5566 /*
5567 ================
5568 idAnimatedEntity::Event_GetJointPos
5569 
5570 returns the position of the joint in worldspace
5571 ================
5572 */
5574  idVec3 offset;
5575  idMat3 axis;
5576 
5577  if ( !GetJointWorldTransform( jointnum, gameLocal.time, offset, axis ) ) {
5578  gameLocal.Warning( "Joint # %d out of range on entity '%s'", jointnum, name.c_str() );
5579  }
5580 
5581  idThread::ReturnVector( offset );
5582 }
5583 
5584 /*
5585 ================
5586 idAnimatedEntity::Event_GetJointAngle
5587 
5588 returns the orientation of the joint in worldspace
5589 ================
5590 */
5592  idVec3 offset;
5593  idMat3 axis;
5594 
5595  if ( !GetJointWorldTransform( jointnum, gameLocal.time, offset, axis ) ) {
5596  gameLocal.Warning( "Joint # %d out of range on entity '%s'", jointnum, name.c_str() );
5597  }
5598 
5599  idAngles ang = axis.ToAngles();
5600  idVec3 vec( ang[ 0 ], ang[ 1 ], ang[ 2 ] );
5601  idThread::ReturnVector( vec );
5602 }
virtual const idVec3 & GetOrigin(int id=0) const =0
const idEventDef EV_ActivateTargets("activateTargets","e")
virtual void DormantBegin(void)
Definition: Entity.cpp:968
jointHandle_t
Definition: Model.h:156
idPlayer * GetLocalPlayer() const
void Event_SetSkin(const char *skinname)
Definition: Entity.cpp:4057
void FreeSoundEmitter(bool immediate)
Definition: Entity.cpp:1787
int CheckTokenString(const char *string)
Definition: Lexer.cpp:1007
int ClipModelsTouchingBounds(const idBounds &bounds, int contentMask, idClipModel **clipModelList, int maxCount) const
Definition: Clip.cpp:804
idEntity * GetEntity(void) const
Definition: Clip.h:178
bool TouchTriggers(void) const
Definition: Entity.cpp:3696
const idEventDef EV_CallFunction("callFunction","s")
const idEventDef EV_RandomTarget("randomTarget","s", 'e')
byte color[4]
Definition: MegaTexture.cpp:54
renderEntity_t renderEntity
Definition: Entity.h:371
void BeginWriting(void)
Definition: BitMsg.h:265
bool TracePoint(trace_t &results, const idVec3 &start, const idVec3 &end, int contentMask, const idEntity *passEntity)
Definition: Clip.h:333
void Event_GetSize(void)
Definition: Entity.cpp:4305
void Save(idSaveGame *savefile) const
Definition: Entity.cpp:5115
int GetContents(void) const
Definition: Clip.h:170
virtual void EnableClip(void)=0
const idEventDef EV_ReachedPos("<reachedpos>", NULL)
void Event_StartSound(const char *soundName, int channel, int netSync)
Definition: Entity.cpp:4181
idEntity * bindMaster
Definition: Entity.h:378
float GetFloat(const char *key, const char *defaultString="0") const
Definition: Dict.h:248
idMat3 ToMat3(void) const
Definition: Vector.cpp:195
void Event_Touches(idEntity *ent)
Definition: Entity.cpp:4335
const idEventDef EV_IsHidden("isHidden", NULL, 'd')
bool GetJointTransform(jointHandle_t jointHandle, int currenttime, idVec3 &offset, idMat3 &axis)
bool GetBounds(int currentTime, idBounds &bounds)
GLsizei const GLfloat * value
Definition: glext.h:3614
void WriteByte(int c)
Definition: BitMsg.h:283
const idEventDef EV_Unbind("unbind", NULL)
const idEventDef EV_SetOwner("setOwner","e")
void WriteString(const char *string)
Definition: SaveGame.cpp:231
float Normalize(void)
Definition: Vector.h:646
bool EmitSmoke(const idDeclParticle *smoke, const int startTime, const float diversity, const idVec3 &origin, const idMat3 &axis, int timeGroup)
void Event_DistanceTo(idEntity *ent)
Definition: Entity.cpp:4559
int GetInt(const char *key, const char *defaultString="0") const
Definition: Dict.h:252
void WriteBindToSnapshot(idBitMsgDelta &msg) const
Definition: Entity.cpp:4756
void void static idThread * CurrentThread(void)
bool waitfortrigger
Definition: Game.h:217
idEntity()
Definition: Entity.cpp:401
assert(prefInfo.fullscreenBtn)
void Event_DistanceToPoint(const idVec3 &point)
Definition: Entity.cpp:4574
void Event_GetFloatKey(const char *key)
Definition: Entity.cpp:4444
virtual const idSoundShader * FindSound(const char *name, bool makeDefault=true)=0
virtual void StateChanged(int time, bool redraw=false)=0
const idDict * FindEntityDefDict(const char *name, bool makeDefault=true) const
idVec3 GetLocalCoordinates(const idVec3 &vec) const
Definition: Entity.cpp:2240
float maxDistance
Definition: sound.h:62
void ClearSignalThread(signalNum_t signalnum, idThread *thread)
Definition: Entity.cpp:3321
#define CLIPMODEL_ID_TO_JOINT_HANDLE(id)
Definition: Clip.h:40
idLinkList< idEntity > activeEntities
Definition: Game_local.h:282
idEntity * teamChain
Definition: Entity.h:382
static idTypeInfo * GetType(int num)
Definition: Class.cpp:570
const idEventDef EV_SetShaderParm("setShaderParm","df")
idMat3 mat3_identity(idVec3(1, 0, 0), idVec3(0, 1, 0), idVec3(0, 0, 1))
bool GetMasterPosition(idVec3 &masterOrigin, idMat3 &masterAxis) const
Definition: Entity.cpp:2313
const int MAX_GLOBAL_SHADER_PARMS
Definition: RenderWorld.h:44
virtual idAnimator * GetAnimator(void)
Definition: Entity.cpp:1566
const idEventDef EV_PostSpawn("<postspawn>", NULL)
int snapshotBits
Definition: Entity.h:119
idNetworkSystem * networkSystem
void CallFunction(const function_t *func, bool clearStack)
void WriteObject(const idClass *obj)
Definition: SaveGame.cpp:329
signalNum_t
Definition: Entity.h:76
idVec3 GetCenter(void) const
Definition: Bounds.h:211
virtual void DeconstructScriptObject(void)
Definition: Entity.cpp:3227
bool GetFloorPos(float max_dist, idVec3 &floorpos) const
Definition: Entity.cpp:2821
idClip clip
Definition: Game_local.h:296
bool UpdateRenderEntity(renderEntity_s *renderEntity, const renderView_t *renderView)
Definition: Entity.cpp:1524
void RemoveBinds(void)
Definition: Entity.cpp:2101
const idEventDef EV_SetJointPos("setJointPos","ddv")
idTypeDef * GetTypeDef(void) const
void Printf(const char *fmt,...) const id_attribute((format(printf
Definition: Game_local.cpp:699
const idEventDef EV_GetLinearVelocity("getLinearVelocity", NULL, 'v')
void Zero(void)
Definition: Bounds.h:206
virtual void SetStateString(const char *varName, const char *value)=0
void UpdateModel(void)
Definition: Entity.cpp:1269
struct idEntity::entityFlags_s fl
void BindToJoint(idEntity *master, const char *jointname, bool orientated)
Definition: Entity.cpp:1921
virtual void virtual void virtual const idLangDict * GetLanguageDict(void)=0
#define MAX_GENTITIES
Definition: Game_local.h:83
virtual void ApplyImpulse(const int id, const idVec3 &point, const idVec3 &impulse)=0
void Bind(idEntity *master, bool orientated)
Definition: Entity.cpp:1896
virtual int GetModelDefHandle(void)
Definition: Entity.cpp:1515
void Event_SetName(const char *name)
Definition: Entity.cpp:3823
void DelayedStart(int delay)
const int MAX_EVENT_PARAM_SIZE
Definition: Game_local.h:132
bool SetType(const char *typeName)
void Event_GetVectorKey(const char *key)
Definition: Entity.cpp:4456
void SetShaderParm(int parmnum, float value)
Definition: Entity.cpp:1067
void Save(idSaveGame *savefile) const
const char * GetTypeName(void) const
virtual void SetClipBox(const idBounds &bounds, float density)
Definition: Physics.cpp:67
void SetupBox(const idBounds &boxBounds)
Definition: TraceModel.cpp:40
void SetAxis(const idMat3 &newAxis, int id=-1)
virtual void SaveState(void)=0
idSmokeParticles * smokeParticles
Definition: Game_local.h:307
const GLdouble * v
Definition: glext.h:2936
void Event_GetLinearVelocity(void)
Definition: Entity.cpp:4269
const idStr & GetKey(void) const
Definition: Dict.h:52
void SignalEvent(idThread *thread, signalNum_t signalnum)
Definition: Entity.cpp:3390
void SetSelf(idEntity *e)
void SetNum(int newnum, bool resize=true)
Definition: List.h:289
void ReadDict(idDict *dict)
Definition: SaveGame.cpp:1107
int GetSpawnId(const idEntity *ent) const
#define MAX_WORLD_SIZE
Definition: Lib.h:100
const idEventDef EV_NumTargets("numTargets", NULL, 'f')
virtual void GetImpactInfo(const int id, const idVec3 &point, impactInfo_t *info) const =0
const idEventDef EV_DistanceTo("distanceTo","E", 'f')
virtual void Teleport(const idVec3 &origin, const idAngles &angles, idEntity *destination)
Definition: Entity.cpp:3682
const idEventDef EV_Activate("activate","e")
void Event_FadeSound(int channel, float to, float over)
Definition: Entity.cpp:4193
bool isNewFrame
Definition: Game_local.h:333
idEntity * GetBindMaster(void) const
Definition: Entity.cpp:2153
virtual qhandle_t AddEntityDef(const renderEntity_t *re)=0
idRenderModel * ModelHandle(void) const
GLint location
Definition: glext.h:3631
virtual void SetPushed(int deltaTime)=0
void Event_SetGuiParm(const char *key, const char *val)
Definition: Entity.cpp:4352
void Event_SetAngles(const idAngles &ang)
Definition: Entity.cpp:4241
void WriteSkin(const idDeclSkin *skin)
Definition: SaveGame.cpp:393
idMat3 Transpose(void) const
Definition: Matrix.h:677
idRandom random
Definition: Game_local.h:291
int Length(void) const
Definition: Str.h:702
void InitSavingPushedEntityPositions(void)
Definition: Push.cpp:40
void SetAxis(const idMat3 &axis)
Definition: Entity.cpp:2796
void void void void void Error(const char *fmt,...) const id_attribute((format(printf
Definition: Game_local.cpp:783
bool isMultiplayer
Definition: Game_local.h:325
int NumJoints(void) const
idScriptObject scriptObject
Definition: Entity.h:123
bool skipCinematic
Definition: Game_local.h:314
#define STRTABLE_ID
Definition: Common.h:56
struct damageEffect_s damageEffect_t
void UnpackColor(const dword color, idVec4 &unpackedColor)
Definition: Lib.cpp:169
bool IsType(const idTypeInfo &c) const
Definition: Class.h:337
void WriteFloat(float f)
Definition: BitMsg.h:299
void Spawn(void)
Definition: Entity.cpp:470
int ClientRemapDecl(declType_t type, int index)
void Write(const void *buffer, int len)
Definition: SaveGame.cpp:159
idInventory inventory
Definition: Player.h:290
void Event_CacheSoundShader(const char *soundName)
Definition: Entity.cpp:4151
void SetAngles(const idAngles &ang)
Definition: Entity.cpp:2812
idEntity * FindEntity(const char *name) const
idList< idEntityPtr< idEntity > > targets
Definition: Entity.h:132
int ReadLong(void) const
Definition: BitMsg.h:375
int previousTime
Definition: Game_local.h:318
void InitDefaultPhysics(const idVec3 &origin, const idMat3 &axis)
Definition: Entity.cpp:2501
float z
Definition: Vector.h:320
#define MASK_SOLID
Definition: Game_local.h:735
const idKeyValue * MatchPrefix(const char *prefix, const idKeyValue *lastMatch=NULL) const
Definition: Dict.cpp:523
case const int
Definition: Callbacks.cpp:52
const idEventDef EV_Touches("touches","E", 'd')
virtual void SetBoundaryType(const boundary_t bt)
Definition: Curve.h:939
void Event_GetName(void)
Definition: Entity.cpp:3814
void Event_SetOrigin(const idVec3 &org)
Definition: Entity.cpp:4223
virtual void DamageFeedback(idEntity *victim, idEntity *inflictor, int &damage)
Definition: Entity.cpp:3040
bool ProcessEvent(const idEventDef *ev)
Definition: Class.cpp:858
bool RespondsTo(const idEventDef &ev) const
Definition: Class.h:349
virtual int GetNumClipModels(void) const =0
void WriteBits(int value, int numBits)
Definition: BitMsg.cpp:648
virtual void RemoveContactEntity(idEntity *ent)
Definition: Entity.cpp:2941
void UpdatePVSAreas(void)
Definition: Entity.cpp:1320
const idEventDef EV_SetModel("setModel","s")
void Event_RestorePosition(void)
Definition: Entity.cpp:4490
bool CreateFrame(int animtime, bool force)
void SetupCylinder(const idBounds &cylBounds, const int numSides)
Definition: TraceModel.cpp:546
void ClearSignal(idThread *thread, signalNum_t signalnum)
Definition: Entity.cpp:3303
jointHandle_t GetJointHandle(const char *name) const
virtual int GetLinearEndTime(void) const =0
bool IsBoundTo(idEntity *master) const
Definition: Entity.cpp:2132
void ClearPVSAreas(void)
Definition: Entity.cpp:1387
bool isClient
Definition: Game_local.h:327
const idEventDef EV_SetAngularVelocity("setAngularVelocity","v")
const char * GetName(void) const
Definition: DeclManager.h:140
Definition: Vector.h:316
const idEventDef EV_GetSize("getSize", NULL, 'v')
void ReadJoint(jointHandle_t &value)
Definition: SaveGame.cpp:931
const idEventDef EV_BindToJoint("bindToJoint","esf")
void ReadBool(bool &value)
Definition: SaveGame.cpp:976
bool isServer
Definition: Game_local.h:326
virtual const idVec3 & GetLinearVelocity(int id=0) const =0
void WriteStaticObject(const idClass &obj)
Definition: SaveGame.cpp:348
const idEventDef EV_SetGuiParm("setGuiParm","ss")
void JoinTeam(idEntity *teammember)
Definition: Entity.cpp:2377
virtual void FadeSound(const s_channelType channel, float to, float over)=0
void Event_Unbind(void)
Definition: Entity.cpp:3955
virtual void HandleNamedEvent(const char *eventName)=0
int GetPVSAreas(const idBounds &bounds, int *areas, int maxAreas) const
Definition: Pvs.cpp:939
const int SHADERPARM_GREEN
Definition: RenderWorld.h:47
virtual void FreeModelDef(void)
Definition: Entity.cpp:1197
dword PackColor(const idVec4 &color)
Definition: Lib.cpp:147
const idEventDef EV_GetIntKey("getIntKey","s", 'f')
virtual void SetLinearVelocity(const idVec3 &newLinearVelocity, int id=0)=0
int listenerId
Definition: Game.h:212
void BloodSplat(const idVec3 &origin, const idVec3 &dir, float size, const char *material)
const idEventDef EV_StartSound("startSound","sdd", 'f')
GLuint GLuint GLsizei GLenum type
Definition: glext.h:2845
GLclampf GLclampf blue
Definition: glext.h:2843
void Event_SetKey(const char *key, const char *value)
Definition: Entity.cpp:4406
void Event_SetJointPos(jointHandle_t jointnum, jointModTransform_t transform_type, const idVec3 &pos)
Definition: Entity.cpp:5548
idSoundEmitter * GetSoundEmitter(void) const
Definition: Entity.cpp:1778
Definition: Token.h:71
static void ReturnVector(idVec3 const &vec)
void SetJointPos(jointHandle_t jointnum, jointModTransform_t transform_type, const idVec3 &pos)
virtual void SetStateInt(const char *varName, const int value)=0
void Save(idSaveGame *savefile) const
Definition: Entity.cpp:667
virtual const idMaterial * FindMaterial(const char *name, bool makeDefault=true)=0
int s_channelType
Definition: sound.h:147
const idEventDef EV_GetAngularVelocity("getAngularVelocity", NULL, 'v')
void SetSoundVolume(float volume)
Definition: Entity.cpp:1740
float ParseFloat(bool *errorFlag=NULL)
Definition: Lexer.cpp:1264
GLdouble s
Definition: glext.h:2935
const char * GetClassname(void) const
Definition: Class.cpp:593
GLuint src
Definition: glext.h:5390
virtual void Think(void)
Definition: Entity.cpp:5160
GLenum GLsizei len
Definition: glext.h:3472
void Set(const char *key, const char *value)
Definition: Dict.cpp:275
virtual void ApplyImpulse(idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse)
Definition: Entity.cpp:2887
int NumParameters(void) const
idVec3 Cross(const idVec3 &a) const
Definition: Vector.h:619
bool cinematic
Definition: Entity.h:127
int ReadBits(int numBits) const
Definition: BitMsg.cpp:709
void Identity(void)
Definition: Matrix.h:591
const idEventDef EV_ReachedAng("<reachedang>", NULL)
float x
Definition: Vector.h:318
virtual void Free(bool immediate)=0
idDict spawnArgs
Definition: Entity.h:122
idUserInterfaceManager * uiManager
int i
Definition: process.py:33
void LittleBitField(void *bp, int elsize)
Definition: Lib.cpp:286
int Cmpn(const char *text, int n) const
Definition: Str.h:657
GLintptr offset
Definition: glext.h:3113
bool IsBound(void) const
Definition: Entity.cpp:2120
contactInfo_t c
int ParseInt(void)
Definition: Lexer.cpp:1227
deferredEntityCallback_t callback
Definition: RenderWorld.h:96
idVec3 localNormal
Definition: Entity.h:494
bool FrameHasChanged(int animtime) const
int ReadByte(void) const
Definition: BitMsg.h:363
GLuint GLuint num
Definition: glext.h:5390
void Restore(idRestoreGame *savefile)
Boolean result
void ReadRenderEntity(renderEntity_t &renderEntity)
Definition: SaveGame.cpp:1269
virtual void ClientPredictionThink(void)
Definition: Entity.cpp:4746
virtual bool HandleSingleGuiCommand(idEntity *entityGui, idLexer *src)
Definition: Entity.cpp:3595
virtual void ANIM_CreateAnimFrame(const idRenderModel *model, const idMD5Anim *anim, int numJoints, idJointMat *frame, int time, const idVec3 &offset, bool remove_origin_offset)
void RestorePushedEntityPositions(void)
Definition: Push.cpp:84
virtual void SetModel(const char *modelname)
Definition: Entity.cpp:1150
void SetDeltaViewAngles(const idAngles &delta)
Definition: Actor.cpp:1821
const idMaterial * customShader
Definition: RenderWorld.h:123
void SetThreadName(const char *name)
static const int MAX_PVS_AREAS
Definition: Entity.h:109
void Event_Wait(float time)
Definition: Entity.cpp:4607
virtual void FreeLightDef(void)
Definition: Entity.cpp:1209
int Icmp(const char *text) const
Definition: Str.h:667
idSoundWorld * gameSoundWorld
Definition: Game_local.cpp:56
void SetName(const char *name)
Definition: Entity.cpp:854
bool CheckDormant(void)
Definition: Entity.cpp:946
Definition: Class.h:174
const int SHADERPARM_ALPHA
Definition: RenderWorld.h:49
virtual void RestoreState(void)=0
virtual bool IsAtRest(void) const
Definition: Entity.cpp:2914
#define EVENT(event, function)
Definition: Class.h:53
virtual void SetStateBool(const char *varName, const bool value)=0
#define ABSTRACT_DECLARATION(nameofsuperclass, nameofclass)
Definition: Class.h:156
void Init(byte *data, int length)
Definition: BitMsg.h:155
const int MAX_ENTITY_SHADER_PARMS
Definition: Material.h:258
const idEventDef EV_GetKey("getKey","s", 's')
const idEventDef EV_StopSound("stopSound","dd")
float fraction
void Restore(idRestoreGame *savefile)
Definition: Entity.cpp:5129
void Event_SetSize(const idVec3 &mins, const idVec3 &maxs)
Definition: Entity.cpp:4296
void SetJointAxis(jointHandle_t jointnum, jointModTransform_t transform_type, const idMat3 &mat)
idVec3 endpos
const idDeclParticle * type
Definition: Entity.h:496
const idEventDef EV_SetLinearVelocity("setLinearVelocity","v")
idVec3 GetLocalVector(const idVec3 &vec) const
Definition: Entity.cpp:2216
void WriteJoint(const jointHandle_t value)
Definition: SaveGame.cpp:177
idProgram program
Definition: Game_local.h:293
void ClearObject(void)
void WriteData(const void *data, int length)
Definition: BitMsg.cpp:210
void WriteBool(const bool value)
Definition: SaveGame.cpp:222
virtual idUserInterface * FindGui(const char *qpath, bool autoLoad=false, bool needUnique=false, bool forceUnique=false)=0
virtual dynamicModel_t IsDynamicModel() const =0
virtual void Killed(idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location)
Definition: Entity.cpp:3163
void Event_SetGuiFloat(const char *key, float f)
Definition: Entity.cpp:4369
int numEntitiesToDeactivate
Definition: Game_local.h:283
virtual int GetRestStartTime(void) const =0
idGameEdit * gameEdit
Definition: GameEdit.cpp:668
virtual bool ClientReceiveEvent(int event, int time, const idBitMsg &msg)
Definition: Entity.cpp:5477
int GetThreadNum(void)
idAnimator animator
Definition: Entity.h:534
#define STRTABLE_ID_LENGTH
Definition: Common.h:57
virtual renderView_t * GetRenderView()
Definition: Entity.cpp:1577
bool IsHidden(void) const
Definition: Entity.cpp:1217
const idEventDef EV_SetJointAngle("setJointAngle","ddv")
idCurve_Spline< idVec3 > * GetSpline(void) const
Definition: Entity.cpp:3755
#define MAX_SIGNAL_THREADS
Definition: Entity.h:94
signalList_t * signals
Definition: Entity.h:387
virtual void GetColor(idVec3 &out) const
Definition: Entity.cpp:1104
int PVSAreas[MAX_PVS_AREAS]
Definition: Entity.h:385
bool HasSignal(signalNum_t signalnum) const
Definition: Entity.cpp:3253
void void void Warning(const char *fmt,...) const id_attribute((format(printf
Definition: Game_local.cpp:735
const idEventDef EV_GetNextKey("getNextKey","ss", 's')
int Icmpn(const char *text, int n) const
Definition: Str.h:672
idEntity * GetPushedEntity(int i) const
Definition: Push.h:70
GLsizei GLsizei GLcharARB * source
Definition: glext.h:3633
virtual void AddContactEntity(idEntity *e)=0
virtual const idBounds & GetBounds(int id=-1) const =0
const idEventDef EV_Show("show", NULL)
jointHandle_t bindJoint
Definition: Entity.h:379
int GetBindBody(void) const
Definition: Entity.cpp:2171
const idEventDef EV_GetMins("getMins", NULL, 'v')
const idEventDef EV_ClearSignal("clearSignal","d")
bool StartSoundShader(const idSoundShader *shader, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length)
Definition: Entity.cpp:1656
const int SHADERPARM_BLUE
Definition: RenderWorld.h:48
void ClearAllJoints(void)
virtual void AddForce(const int id, const idVec3 &point, const idVec3 &force)=0
const idEventDef EV_GetFloatKey("getFloatKey","s", 'f')
bool noDynamicInteractions
Definition: RenderWorld.h:144
int ServerRemapDecl(int clientNum, declType_t type, int index)
Definition: Lexer.h:137
int RandomInt(void)
Definition: Random.h:70
idRenderModel * SetModel(const char *modelname)
virtual void Show(void)
Definition: Entity.cpp:1239
virtual void Think(void)
Definition: Entity.cpp:891
virtual bool GetPhysicsToSoundTransform(idVec3 &origin, idMat3 &axis)
Definition: Entity.cpp:2853
const idEventDef EV_RemoveBinds("removeBinds")
virtual void FreeEntityDef(qhandle_t entityHandle)=0
const idMaterial * material
virtual void AddDamageEffect(const trace_t &collision, const idVec3 &velocity, const char *damageDefName)
Definition: Entity.cpp:3108
void WriteColorToSnapshot(idBitMsgDelta &msg) const
Definition: Entity.cpp:4817
int Index(void) const
Definition: DeclManager.h:165
const idEventDef EV_ClearAllJoints("clearAllJoints")
virtual void ClipTranslation(trace_t &results, const idVec3 &translation, const idClipModel *model) const =0
void Event_GetColor(void)
Definition: Entity.cpp:4112
void SetClipModel(idClipModel *model, float density, int id=0, bool freeOld=true)
virtual const char * GetStateString(const char *varName, const char *defaultString="") const =0
jointModTransform_t
Definition: Anim.h:84
void Event_GetKey(const char *key)
Definition: Entity.cpp:4418
const idTypeDef * type
void SetOwner(idEntity *newOwner)
Definition: Clip.h:190
idPhysics * GetPhysics(void) const
Definition: Entity.cpp:2607
void WriteLong(int c)
Definition: BitMsg.h:554
GLuint index
Definition: glext.h:3476
const int SHADERPARM_MODE
Definition: RenderWorld.h:53
void SetSkin(const idDeclSkin *skin)
Definition: Entity.cpp:1178
const GLubyte * c
Definition: glext.h:4677
const char * GetString(const char *key, const char *defaultString="") const
Definition: Dict.h:240
int snapshotSequence
Definition: Entity.h:118
bool InCurrentPVS(const pvsHandle_t handle, const idVec3 &target) const
Definition: Pvs.cpp:1139
Definition: Vector.h:808
virtual bool Collide(const trace_t &collision, const idVec3 &velocity)
Definition: Entity.cpp:2868
idEntity * cameraTarget
Definition: Entity.h:130
idWorldspawn * world
Definition: Game_local.h:280
void Event_RemoveBinds(void)
Definition: Entity.cpp:3928
void Event_SetOwner(idEntity *owner)
Definition: Entity.cpp:4035
float RandomFloat(void)
Definition: Random.h:82
bool StartSound(const char *soundName, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length)
Definition: Entity.cpp:1622
const idEventDef EV_FadeSound("fadeSound","dff")
void UpdateFromPhysics(bool moveBack)
Definition: Entity.cpp:2759
idVec3 vec3_origin(0.0f, 0.0f, 0.0f)
const idAngles & GetDeltaViewAngles(void) const
Definition: Actor.cpp:1812
idCVar g_bloodEffects("g_bloodEffects","1", CVAR_GAME|CVAR_ARCHIVE|CVAR_BOOL,"show blood splats, sprays and gibs")
idSoundEmitter * referenceSound
Definition: Game.h:209
const idEventDef EV_PartBlocked("<partblocked>","e")
virtual renderEntity_t * GetRenderEntity(void)
Definition: Entity.cpp:1506
void UpdateSound(void)
Definition: Entity.cpp:1749
const idEventDef EV_GetOrigin("getOrigin", NULL, 'v')
void void Read(void *buffer, int len)
Definition: SaveGame.cpp:913
void SetPhysics(idPhysics *phys)
Definition: Entity.cpp:2574
void Unbind(void)
Definition: Entity.cpp:2011
void UnregisterEntity(idEntity *ent)
void WriteLong(int c)
Definition: BitMsg.h:295
void SetOrigin(const idVec3 &newOrigin, int id=-1)
virtual void GetImpactInfo(idEntity *ent, int id, const idVec3 &point, impactInfo_t *info)
Definition: Entity.cpp:2878
void Event_GetMins(void)
Definition: Entity.cpp:4317
idVec3 ToVec3(void) const
idVec3 localOrigin
Definition: Entity.h:493
bool InPlayerConnectedArea(idEntity *ent) const
const idEventDef EV_GetJointHandle("getJointHandle","s", 'd')
#define MAX_CLIENTS
Definition: Game_local.h:81
idCommon * common
Definition: Common.cpp:206
static const char * sufaceTypeNames[MAX_SURFACE_TYPES]
Definition: Game_local.h:337
idJointMat * joints
Definition: RenderWorld.h:135
static idThread * GetThread(int num)
bool HandleGuiCommands(idEntity *entityGui, const char *cmds)
Definition: Entity.cpp:3428
int GetSize(void) const
Definition: BitMsg.h:187
bool GetBool(const char *key, const char *defaultString="0") const
Definition: Dict.h:256
virtual void UpdateChangeableSpawnArgs(const idDict *source)
Definition: Entity.cpp:377
Definition: Dict.h:65
idVec3 origin
Definition: Game.h:211
#define NULL
Definition: Lib.h:88
void TriggerGuis(void)
Definition: Entity.cpp:3414
const idMD5Anim * MD5Anim(int num) const
Definition: Anim_Blend.cpp:165
void Event_BindPosition(idEntity *master)
Definition: Entity.cpp:3946
const idDeclSkin * customSkin
Definition: RenderWorld.h:125
void void DPrintf(const char *fmt,...) const id_attribute((format(printf
Definition: Game_local.cpp:715
void SetupCone(const idBounds &coneBounds, const int numSides)
Definition: TraceModel.cpp:659
virtual idRenderModel * FindModel(const char *modelName)=0
idEntity * GetOwner(void) const
Definition: Clip.h:194
virtual const idDecl * FindType(declType_t type, const char *name, bool makeDefault=true)=0
void Event_SetJointAngle(jointHandle_t jointnum, jointModTransform_t transform_type, const idAngles &angles)
Definition: Entity.cpp:5559
const idMaterial * globalMaterial
Definition: RenderWorld.h:224
float y
Definition: Vector.h:319
const idEventDef EV_GetJointPos("getJointPos","d", 'v')
virtual const idVec3 & GetAngularVelocity(int id=0) const =0
idVec3 GetVector(const char *key, const char *defaultString=NULL) const
Definition: Dict.h:260
void Event_Hide(void)
Definition: Entity.cpp:4133
const int MAX_RENDERENTITY_GUI
Definition: RenderWorld.h:74
idEntity * GetNextTeamEntity(void) const
Definition: Entity.cpp:2189
void ServerSendEvent(int eventId, const idBitMsg *msg, bool saveEvent, int excludeClient) const
Definition: Entity.cpp:4897
void Event_WaitFrame(void)
Definition: Entity.cpp:4593
const idEventDef EV_GetName("getName", NULL, 's')
void WriteShort(int c)
Definition: BitMsg.h:287
int entityDefNumber
Definition: Entity.h:112
float ReadFloat(void) const
Definition: BitMsg.h:379
virtual void SetOrigin(const idVec3 &newOrigin, int id=-1)=0
const idAnim * GetAnim(int index) const
void Event_GetWorldOrigin(void)
Definition: Entity.cpp:4204
void SetEntity(const char *name, idEntity *ent)
const idEventDef EV_Hide("hide", NULL)
Definition: Plane.h:71
int ReadLong(void) const
Definition: BitMsg.h:621
const idEventDef EV_Bind("bind","e")
static void ReturnFloat(float value)
void Event_StopSound(int channel, int netSync)
Definition: Entity.cpp:4172
int threadnum
Definition: Entity.h:97
void GiveEmail(const char *emailName)
void Event_GetIntKey(const char *key)
Definition: Entity.cpp:4430
int dormantStart
Definition: Entity.h:126
const char * GetString(const char *str) const
Definition: LangDict.cpp:148
damageEffect_t * damageEffects
Definition: Entity.h:535
idMat3 endAxis
virtual void WriteToSnapshot(idBitMsgDelta &msg) const
Definition: Entity.cpp:4878
virtual idSoundEmitter * AllocSoundEmitter(void)=0
int GetNumPVSAreas(void)
Definition: Entity.cpp:1363
const idStr & GetValue(void) const
Definition: Dict.h:53
void Event_GetJointPos(jointHandle_t jointnum)
Definition: Entity.cpp:5573
float shaderParms[MAX_GLOBAL_SHADER_PARMS]
Definition: RenderWorld.h:223
void WriteByte(int c)
Definition: BitMsg.h:542
int GetId(void) const
Definition: Clip.h:186
void Event_SetColor(float red, float green, float blue)
Definition: Entity.cpp:4103
void ReadGUIFromSnapshot(const idBitMsgDelta &msg)
Definition: Entity.cpp:4861
virtual const idMat3 & GetAxis(int id=0) const =0
const idEventDef EV_SetWorldOrigin("setWorldOrigin","v")
void Event_GetJointHandle(const char *jointname)
Definition: Entity.cpp:5512
const idSoundShader * shader
Definition: Game.h:214
virtual bool Evaluate(int timeStepMSec, int endTimeMSec)=0
virtual idAnimator * GetAnimator(void)
Definition: Entity.cpp:5213
virtual void UpdateEntityDef(qhandle_t entityHandle, const renderEntity_t *re)=0
void QuitTeam(void)
Definition: Entity.cpp:2447
void Event_SpawnBind(void)
Definition: Entity.cpp:3964
const char * Right(int len, idStr &result) const
Definition: Str.h:896
void ServiceAnims(int fromtime, int totime)
const idDeclModelDef * ModelDef(void) const
void AddEntityToHash(const char *name, idEntity *ent)
void Event_Show(void)
Definition: Entity.cpp:4142
bool PhysicsTeamInPVS(pvsHandle_t pvsHandle)
Definition: Entity.cpp:1398
const idEventDef EV_HasFunction("hasFunction","s", 'd')
const function_t * function
Definition: Entity.h:98
void FromTransformedBounds(const idBounds &bounds, const idVec3 &origin, const idMat3 &axis)
Definition: Bounds.cpp:232
const function_t * GetConstructor(void) const
idTypeDef * GetParmType(int parmNumber) const
const idEventDef EV_SpawnBind("<spawnbind>", NULL)
idVec3 ReadDir(int numBits) const
Definition: BitMsg.h:398
idLinkList< idEntity > spawnNode
Definition: Entity.h:114
virtual void ClientPredictionThink(void)
Definition: Entity.cpp:5149
gameState_t GameState(void) const
void ReadRefSound(refSound_t &refSound)
Definition: SaveGame.cpp:1377
virtual void Reset()=0
idGameLocal gameLocal
Definition: Game_local.cpp:64
idLinkList< idEntity > snapshotNode
Definition: Entity.h:117
virtual void ServerSendReliableMessageExcluding(int clientNum, const idBitMsg &msg)
bool RunPhysics(void)
Definition: Entity.cpp:2616
virtual void ServerSendReliableMessage(int clientNum, const idBitMsg &msg)
void ForceUpdate(void)
void WriteRenderEntity(const renderEntity_t &renderEntity)
Definition: SaveGame.cpp:497
virtual void ShowEditingDialog(void)
Definition: Entity.cpp:3800
void UnreadToken(const idToken *token)
Definition: Lexer.cpp:1159
virtual void Damage(idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location)
Definition: Entity.cpp:3061
#define END_CLASS
Definition: Class.h:54
const idKeyValue * FindKey(const char *key) const
Definition: Dict.cpp:451
idRenderModel * hModel
Definition: RenderWorld.h:81
virtual const idSoundShader * SoundByIndex(int index, bool forceParse=true)=0
void Error(const char *fmt,...) id_attribute((format(printf
Definition: SaveGame.cpp:878
virtual void Printf(const char *fmt,...) id_attribute((format(printf
float shakes
Definition: sound.h:64
void GetJoints(int *numJoints, idJointMat **jointsPtr)
const idVec3 & GetVisualOffset(void) const
static void SinCos16(float a, float &s, float &c)
Definition: Math.h:406
void Event_UpdateCameraTarget(void)
Definition: Entity.cpp:4528
void ClientSendEvent(int eventId, const idBitMsg *msg) const
Definition: Entity.cpp:4939
const idDeclSkin * GetDefaultSkin(void) const
int LoadMemory(const char *ptr, int length, const char *name, int startLine=1)
Definition: Lexer.cpp:1646
virtual const idDict & State() const =0
void Event_GetNextKey(const char *prefix, const char *lastMatch)
Definition: Entity.cpp:4383
virtual int StartSound(const idSoundShader *shader, const s_channelType channel, float diversity=0, int shaderFlags=0, bool allowSlow=true)=0
idBounds Expand(const float d) const
Definition: Bounds.h:317
virtual idBounds Bounds(const struct renderEntity_s *ent=NULL) const =0
static int BitsForInteger(int i)
Definition: Math.h:727
bool InPlayerPVS(idEntity *ent) const
void ClearForceUpdate(void)
void BindToBody(idEntity *master, int bodyId, bool orientated)
Definition: Entity.cpp:1984
void RegisterEntity(idEntity *ent)
virtual void Hide(void)
Definition: Entity.cpp:1226
const surfTypes_t GetSurfaceType(void) const
Definition: Material.h:503
void Save(idSaveGame *savefile) const
bool sortPushers
Definition: Game_local.h:284
bool inCinematic
Definition: Game_local.h:313
const idEventDef EV_Thread_Wait("wait","f")
virtual void AddContactEntity(idEntity *ent)
Definition: Entity.cpp:2932
void Event_SetNeverDormant(int enable)
Definition: Entity.cpp:4668
virtual void DisableClip(void)=0
const idDeclSkin * GetSkin(void) const
Definition: Entity.cpp:1188
virtual idClipModel * GetClipModel(int id=0) const =0
const idEventDef EV_DistanceToPoint("distanceToPoint","v", 'f')
bool Inherits(const idTypeDef *basetype) const
const char * ToString(int precision=2) const
Definition: Vector.cpp:221
void WriteInt(const int value)
Definition: SaveGame.cpp:168
virtual void Present(void)
Definition: Entity.cpp:1471
void Event_CallFunction(const char *name)
Definition: Entity.cpp:4638
void ProjectVector(const idVec3 &src, idVec3 &dst) const
Definition: Matrix.h:628
const idEventDef EV_GetMaxs("getMaxs", NULL, 'v')
idDeclManager * declManager
int GetTargets(const idDict &args, idList< idEntityPtr< idEntity > > &list, const char *ref) const
const idMaterial * GetGlobalMaterial()
const idEventDef EV_UpdateCameraTarget("<updateCameraTarget>", NULL)
void FixupLocalizedStrings()
Definition: Entity.cpp:456
int bindBody
Definition: Entity.h:380
void Event_SetAngularVelocity(const idVec3 &velocity)
Definition: Entity.cpp:4278
void RemoveNullTargets(void)
Definition: Entity.cpp:3633
virtual bool Pain(idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location)
Definition: Entity.cpp:3151
idEntity * entities[MAX_GENTITIES]
Definition: Game_local.h:275
void WriteDict(const idDict *dict)
Definition: SaveGame.cpp:357
idMat3 ToMat3(void) const
virtual bool ClientReceiveEvent(int event, int time, const idBitMsg &msg)
Definition: Entity.cpp:4988
static const float TWO_PI
Definition: Math.h:206
idPush push
Definition: Game_local.h:297
void SetSignal(signalNum_t signalnum, idThread *thread, const function_t *function)
Definition: Entity.cpp:3266
void Event_IsHidden(void)
Definition: Entity.cpp:4124
int ExpectTokenString(const char *string)
Definition: Lexer.cpp:919
idVec3 GetWorldCoordinates(const idVec3 &vec) const
Definition: Entity.cpp:2291
void Event_HasFunction(const char *name)
Definition: Entity.cpp:4622
int health
Definition: Entity.h:134
idEntity * GetTeamMaster(void) const
Definition: Entity.cpp:2180
idEntity * GetTraceEntity(const trace_t &trace) const
void Event_SetWorldOrigin(idVec3 const &org)
Definition: Entity.cpp:4213
idVec3 vieworg
Definition: RenderWorld.h:215
const idEventDef EV_TeamBlocked("<teamblocked>","ee")
void ReadStaticObject(idClass &obj)
Definition: SaveGame.cpp:1098
void Event_Bind(idEntity *master)
Definition: Entity.cpp:3937
int Append(const type &obj)
Definition: List.h:646
void AddLocalDamageEffect(jointHandle_t jointNum, const idVec3 &localPoint, const idVec3 &localNormal, const idVec3 &localDir, const idDeclEntityDef *def, const idMaterial *collisionMaterial)
Definition: Entity.cpp:5358
const idEventDef EV_GetEntityKey("getEntityKey","s", 'e')
virtual float GetStateFloat(const char *varName, const char *defaultString="0") const =0
float globalShaderParms[MAX_GLOBAL_SHADER_PARMS]
Definition: Game_local.h:289
renderView_t * renderView
Definition: Entity.h:129
const idEventDef EV_GetColor("getColor", NULL, 'v')
idRenderModelManager * renderModelManager
Definition: Matrix.h:333
const int SHADERPARM_RED
Definition: RenderWorld.h:46
static void ReturnString(const char *text)
void Event_SetShaderParm(int parmnum, float value)
Definition: Entity.cpp:4080
float yaw
Definition: Angles.h:54
virtual void PostBind(void)
Definition: Entity.cpp:1813
END_CLASS void UpdateGuiParms(idUserInterface *gui, const idDict *args)
Definition: Entity.cpp:196
const idEventDef EV_GetTarget("getTarget","f", 'e')
void UpdateVisuals(void)
Definition: Entity.cpp:1310
bool InitBind(idEntity *master)
Definition: Entity.cpp:1837
GLuint id
Definition: glext.h:3103
void Event_StartSoundShader(const char *soundName, int channel)
Definition: Entity.cpp:4160
bool GetBool(void) const
Definition: CVarSystem.h:142
virtual const idDecl * DeclByIndex(declType_t type, int index, bool forceParse=true)=0
soundShaderParms_t parms
Definition: Game.h:218
void Event_FindTargets(void)
Definition: Entity.cpp:3832
virtual void PreUnbind(void)
Definition: Entity.cpp:1821
int GetListenerId(void) const
Definition: Entity.cpp:1769
int numPVSAreas
Definition: Entity.h:384
tuple f
Definition: idal.py:89
const idEventDef EV_SetShaderParms("setShaderParms","ffff")
bool IsCleared(void) const
Definition: Bounds.h:222
void Event_GetAngularVelocity(void)
Definition: Entity.cpp:4287
Definition: Actor.h:111
virtual bool CanPlayChatterSounds(void) const
Definition: Entity.cpp:1613
virtual void AddForce(idEntity *ent, int id, const idVec3 &point, const idVec3 &force)
Definition: Entity.cpp:2896
virtual void StopSound(const s_channelType channel)=0
int Num(void) const
Definition: List.h:265
bool RemoveIndex(int index)
Definition: List.h:849
idMat3 ToMat3(void) const
Definition: Angles.cpp:199
void Event_GetEntityKey(const char *key)
Definition: Entity.cpp:4468
unsigned char byte
Definition: Lib.h:75
idPhysics * physics
Definition: Entity.h:377
bool IntersectsBounds(const idBounds &a) const
Definition: Bounds.h:361
virtual const idBounds & GetAbsBounds(int id=-1) const =0
virtual void RemoveContactEntity(idEntity *e)=0
int modelDefHandle
Definition: Entity.h:372
virtual void SetColor(float red, float green, float blue)
Definition: Entity.cpp:1082
const GLcharARB * name
Definition: glext.h:3629
virtual int GetDefaultSurfaceType(void) const
Definition: Entity.cpp:5349
GLsizeiptr size
Definition: glext.h:3112
const function_t * GetFunction(const char *name) const
static bool ModelCallback(renderEntity_s *renderEntity, const renderView_t *renderView)
Definition: Entity.cpp:1548
void WriteRefSound(const refSound_t &refSound)
Definition: SaveGame.cpp:600
void Signal(signalNum_t signalnum)
Definition: Entity.cpp:3352
const idEventDef EV_SetGuiFloat("setGuiFloat","sf")
const char * RandomPrefix(const char *prefix, idRandom &random) const
Definition: Dict.cpp:553
void Event_NumTargets(void)
Definition: Entity.cpp:3853
virtual void UpdateEmitter(const idVec3 &origin, int listenerId, const soundShaderParms_t *parms)=0
bool GetJointWorldTransform(jointHandle_t jointHandle, int currentTime, idVec3 &offset, idMat3 &axis)
Definition: Entity.cpp:5248
idVec3 GetWorldVector(const idVec3 &vec) const
Definition: Entity.cpp:2267
const function_t * GetDestructor(void) const
void ConvertLocalToWorldTransform(idVec3 &offset, idMat3 &axis)
Definition: Entity.cpp:2198
#define CLASS_DECLARATION(nameofsuperclass, nameofclass)
Definition: Class.h:110
int GetNumPushedEntities(void) const
Definition: Push.h:68
byte * GetData(void)
Definition: BitMsg.h:167
Definition: Str.h:116
idBounds bounds
Definition: RenderWorld.h:95
idEntity * teamMaster
Definition: Entity.h:381
int ReadByte(void) const
Definition: BitMsg.h:609
virtual int AddValue(const float time, const type &value)
Definition: Curve.h:116
virtual void SetAngularVelocity(const idVec3 &newAngularVelocity, int id=0)=0
GLsizei const GLcharARB const GLint * length
Definition: glext.h:3599
virtual int ClipContents(const idClipModel *model) const =0
const char * GetName(void) const
Definition: Entity.cpp:875
void UpdateAnimation(void)
Definition: Entity.cpp:5172
class idSoundEmitter * referenceSound
Definition: RenderWorld.h:126
void Event_GetTarget(float index)
Definition: Entity.cpp:3862
void GetWorldVelocities(idVec3 &linearVelocity, idVec3 &angularVelocity) const
Definition: Entity.cpp:2351
virtual void SetMaster(idEntity *master, const bool orientated=true)=0
static void ReturnEntity(idEntity *ent)
class idUserInterface * gui[MAX_RENDERENTITY_GUI]
Definition: RenderWorld.h:130
void UpdateModelTransform(void)
Definition: Entity.cpp:1251
int mpGUIState
Definition: Entity.h:389
const char * c_str(void) const
Definition: Str.h:487
void Error(const char *fmt,...) const id_attribute((format(printf
const idEventDef EV_SetKey("setKey","ss")
virtual int GetRestStartTime(void) const
Definition: Entity.cpp:2923
const idEventDef EV_GetWorldOrigin("getWorldOrigin", NULL, 'v')
const int MAX_GAME_MESSAGE_SIZE
Definition: Game_local.h:113
virtual idEntity * GetBlockingEntity(void) const =0
virtual void ParseSpawnArgsToRenderEntity(const idDict *args, renderEntity_t *renderEntity)
Definition: Entity.cpp:229
void RestorePhysics(idPhysics *phys)
Definition: Entity.cpp:2596
void Event_ClearJoint(jointHandle_t jointnum)
Definition: Entity.cpp:5537
void BecomeActive(int flags)
Definition: Entity.cpp:995
idRenderSystemLocal tr
const idEventDef EV_SetOrigin("setOrigin","v")
void FindTargets(void)
Definition: Entity.cpp:3614
virtual void PreBind(void)
Definition: Entity.cpp:1805
refSound_t refSound
Definition: Entity.h:373
idAngles ToAngles(void) const
Definition: Matrix.cpp:147
const idKeyValue * GetKeyVal(int index) const
Definition: Dict.h:294
const idEventDef EV_Remove("<immediateremove>", NULL)
bool IsActive(void) const
Definition: Entity.cpp:986
idPhysics_Static defaultPhysicsObj
Definition: Entity.h:376
const idEventDef EV_GetVectorKey("getVectorKey","s", 'v')
function_t * FindFunction(const char *name) const
const int * GetPVSAreas(void)
Definition: Entity.cpp:1375
void ReadColorFromSnapshot(const idBitMsgDelta &msg)
Definition: Entity.cpp:4832
bool GetJointTransformForAnim(jointHandle_t jointHandle, int animNum, int currentTime, idVec3 &offset, idMat3 &axis) const
Definition: Entity.cpp:5262
const idEventDef EV_StartSoundShader("startSoundShader","sd", 'f')
void Event_GetOrigin(void)
Definition: Entity.cpp:4232
virtual void ProjectOverlay(qhandle_t entityHandle, const idPlane localTextureAxis[2], const idMaterial *material)=0
virtual bool CanDamage(const idVec3 &origin, idVec3 &damagePoint) const
Definition: Entity.cpp:2961
void Event_BindToJoint(idEntity *master, const char *jointname, float orientated)
Definition: Entity.cpp:3919
const idEventDef EV_RestorePosition("restorePosition")
jointHandle_t GetBindJoint(void) const
Definition: Entity.cpp:2162
virtual const idDeclSkin * FindSkin(const char *name, bool makeDefault=true)=0
virtual bool IsAtRest(void) const =0
void UnprojectVector(const idVec3 &src, idVec3 &dst) const
Definition: Matrix.h:634
static cmHandle_t CheckModel(const char *name)
Definition: Clip.cpp:604
idRenderModel * ModelHandle(void) const
void Event_SetShaderParms(float parm0, float parm1, float parm2, float parm3)
Definition: Entity.cpp:4089
const idEventDef EV_SetNeverDormant("setNeverDormant","d")
int realClientTime
Definition: Game_local.h:332
GLint j
Definition: qgl.h:264
virtual void ParseSpawnArgsToRefSound(const idDict *args, refSound_t *refSound)
Definition: Entity.cpp:324
virtual void UpdateTime(int endTimeMSec)=0
void Event_GetJointAngle(jointHandle_t jointnum)
Definition: Entity.cpp:5591
const char * GetEntityDefName(void) const
Definition: Entity.cpp:842
void WaitFrame(void)
virtual idThread * ConstructScriptObject(void)
Definition: Entity.cpp:3193
float diversity
Definition: Game.h:215
void WriteGUIToSnapshot(idBitMsgDelta &msg) const
Definition: Entity.cpp:4847
idMat3 GetMatrix(const char *key, const char *defaultString=NULL) const
Definition: Dict.h:284
virtual bool UpdateAnimationControllers(void)
Definition: Entity.cpp:1140
const idEventDef EV_SetSize("setSize","vv")
const idDeclEntityDef * FindEntityDef(const char *name, bool makeDefault=true) const
idRenderWorld * gameRenderWorld
Definition: Game_local.cpp:55
char * va(const char *fmt,...)
Definition: Str.cpp:1568
struct damageEffect_s * next
Definition: Entity.h:497
void Event_GetAngles(void)
Definition: Entity.cpp:4250
void AddRenderGui(const char *name, idUserInterface **gui, const idDict *args)
Definition: Entity.cpp:214
void ReadBindFromSnapshot(const idBitMsgDelta &msg)
Definition: Entity.cpp:4780
static idEntityFx * StartFx(const char *fx, const idVec3 *useOrigin, const idMat3 *useAxis, idEntity *ent, bool bind)
Definition: Fx.cpp:716
void WriteBits(int value, int numBits)
Definition: BitMsg.cpp:110
#define GENTITYNUM_BITS
Definition: Game_local.h:82
const idEventDef EV_SetName("setName","s")
virtual void AddDamageEffect(const trace_t &collision, const idVec3 &velocity, const char *damageDefName)
Definition: Entity.cpp:5295
virtual bool GetPhysicsToVisualTransform(idVec3 &origin, idMat3 &axis)
Definition: Entity.cpp:2844
void SaveEntityNetworkEvent(const idEntity *ent, int event, const idBitMsg *msg)
virtual bool ShouldConstructScriptObjectAtSpawn(void) const
Definition: Entity.cpp:3181
idList< signal_t > signal[NUM_SIGNALS]
Definition: Entity.h:103
void SetOrigin(const idVec3 &org)
Definition: Entity.cpp:2784
bool PostEventMS(const idEventDef *ev, int time)
Definition: Class.cpp:666
virtual void DPrintf(const char *fmt,...) id_attribute((format(printf
void WriteDir(const idVec3 &dir, int numBits)
Definition: BitMsg.h:316
bool RemoveEntityFromHash(const char *name, idEntity *ent)
int entityNumber
Definition: Entity.h:111
const idEventDef EV_BindPosition("bindPosition","e")
virtual void SetModel(const char *modelname)
Definition: Entity.cpp:5222
idMat3 viewaxis
Definition: RenderWorld.h:216
idStr name
Definition: Entity.h:121
void Restore(idRestoreGame *savefile)
Definition: Entity.cpp:745
bool DoDormantTests(void)
Definition: Entity.cpp:904
int thinkFlags
Definition: Entity.h:125
virtual bool ServerReceiveEvent(int event, int time, const idBitMsg &msg)
Definition: Entity.cpp:4973
const idEventDef EV_SetAngles("setAngles","v")
virtual void ProjectOverlay(const idVec3 &origin, const idVec3 &dir, float size, const char *material)
Definition: Entity.cpp:1418
void FinishBind(void)
Definition: Entity.cpp:1870
const idEventDef EV_Touch("<touch>","et")
const idEventDef EV_StartFx("startFx","s")
void Event_GetMaxs(void)
Definition: Entity.cpp:4326
const idEventDef EV_CacheSoundShader("cacheSoundShader","s")
void Restore(idRestoreGame *savefile)
int GetNumKeyVals(void) const
Definition: Dict.h:290
void Event_ClearAllJoints(void)
Definition: Entity.cpp:5526
jointHandle_t jointNum
Definition: Entity.h:492
float shaderParms[MAX_ENTITY_SHADER_PARMS]
Definition: RenderWorld.h:127
void ReadString(idStr &string)
Definition: SaveGame.cpp:985
void UpdateDamageEffects(void)
Definition: Entity.cpp:5438
virtual void PostUnbind(void)
Definition: Entity.cpp:1829
bool Execute(void)
const idEventDef EV_SetSkin("setSkin","s")
void BecomeInactive(int flags)
Definition: Entity.cpp:1025
const idEventDef EV_Thread_WaitFrame("waitFrame")
static void ReturnInt(int value)
int ReadToken(idToken *token)
Definition: Lexer.cpp:820
virtual void Trigger(int time)=0
void ReadInt(int &value)
Definition: SaveGame.cpp:922
void Event_StartFx(const char *fx)
Definition: Entity.cpp:4584
float CRandomFloat(void)
Definition: Random.h:86
idLinkList< idEntity > activeNode
Definition: Entity.h:115
void NormalVectors(idVec3 &left, idVec3 &down) const
Definition: Vector.h:727
virtual void ReadFromSnapshot(const idBitMsgDelta &msg)
Definition: Entity.cpp:4886
~idEntity()
Definition: Entity.cpp:608
void Event_GetShaderParm(int parmnum)
Definition: Entity.cpp:4067
virtual void Activate(void)=0
void Event_ActivateTargets(idEntity *activator)
Definition: Entity.cpp:3844
struct renderView_s * remoteRenderView
Definition: RenderWorld.h:132
const idEventDef EV_GetAngles("getAngles", NULL, 'v')
struct renderView_s renderView_t
Definition: DeclParticle.h:83
void ActivateTargets(idEntity *activator) const
Definition: Entity.cpp:3650
const idEventDef EV_GetShaderParm("getShaderParm","d", 'f')
GLuint start
Definition: glext.h:2845
void StopSound(const s_channelType channel, bool broadcast)
Definition: Entity.cpp:1713
virtual void ClientSendReliableMessage(const idBitMsg &msg)
Definition: Anim.h:280
int soundShaderFlags
Definition: sound.h:65
virtual int GetAngularEndTime(void) const =0
void Event_SetLinearVelocity(const idVec3 &velocity)
Definition: Entity.cpp:4260
void ClearJoint(jointHandle_t jointnum)
#define MS2SEC(t)
Definition: Math.h:60
void ReadSkin(const idDeclSkin *&skin)
Definition: SaveGame.cpp:1148
bool turkeyScore
Definition: Player.h:167
virtual void ClearContacts(void)=0
const idEventDef EV_SetColor("setColor","fff")
void Event_RandomTarget(const char *ignore)
Definition: Entity.cpp:3878
virtual void ActivatePhysics(idEntity *ent)
Definition: Entity.cpp:2905
float volume
Definition: sound.h:63
void ReadObject(idClass *&obj)
Definition: SaveGame.cpp:1083
int ReadShort(void) const
Definition: BitMsg.h:367
const idEventDef EV_FindTargets("<findTargets>", NULL)
virtual void DormantEnd(void)
Definition: Entity.cpp:978
void Event_SetModel(const char *modelname)
Definition: Entity.cpp:4048
float minDistance
Definition: sound.h:61
GLclampf green
Definition: glext.h:2843
void WaitSec(float time)
virtual void SetAxis(const idMat3 &newAxis, int id=-1)=0
GLdouble GLdouble t
Definition: glext.h:2943
#define ENTITYNUM_NONE
Definition: Game_local.h:84
const idEventDef EV_ClearJoint("clearJoint","d")
idCVar g_decals("g_decals","1", CVAR_GAME|CVAR_ARCHIVE|CVAR_BOOL,"show decals such as bullet holes")
bool RemoveOrigin(void) const
void Clear(void)
Definition: List.h:184
const idEventDef EV_GetJointAngle("getJointAngle","d", 'v')
bool sortTeamMasters
Definition: Game_local.h:285