doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Moveable.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  idMoveable
38 
39 ===============================================================================
40 */
41 
42 const idEventDef EV_BecomeNonSolid( "becomeNonSolid" );
43 const idEventDef EV_SetOwnerFromSpawnArgs( "<setOwnerFromSpawnArgs>" );
44 const idEventDef EV_IsAtRest( "isAtRest", NULL, 'd' );
45 const idEventDef EV_EnableDamage( "enableDamage", "f" );
46 
48  EVENT( EV_Activate, idMoveable::Event_Activate )
49  EVENT( EV_BecomeNonSolid, idMoveable::Event_BecomeNonSolid )
50  EVENT( EV_SetOwnerFromSpawnArgs, idMoveable::Event_SetOwnerFromSpawnArgs )
51  EVENT( EV_IsAtRest, idMoveable::Event_IsAtRest )
52  EVENT( EV_EnableDamage, idMoveable::Event_EnableDamage )
54 
55 
56 static const float BOUNCE_SOUND_MIN_VELOCITY = 80.0f;
57 static const float BOUNCE_SOUND_MAX_VELOCITY = 200.0f;
58 
59 /*
60 ================
61 idMoveable::idMoveable
62 ================
63 */
65  minDamageVelocity = 100.0f;
66  maxDamageVelocity = 200.0f;
67  nextCollideFxTime = 0;
68  nextDamageTime = 0;
69  nextSoundTime = 0;
70  initialSpline = NULL;
71  initialSplineDir = vec3_zero;
72  explode = false;
73  unbindOnDeath = false;
74  allowStep = false;
75  canDamage = false;
76 #ifdef _D3XP
77  attacker = NULL;
78 #endif
79 }
80 
81 /*
82 ================
83 idMoveable::~idMoveable
84 ================
85 */
87  delete initialSpline;
89 }
90 
91 /*
92 ================
93 idMoveable::Spawn
94 ================
95 */
96 void idMoveable::Spawn( void ) {
97  idTraceModel trm;
98  float density, friction, bouncyness, mass;
99  int clipShrink;
100  idStr clipModelName;
101 
102  // check if a clip model is set
103  spawnArgs.GetString( "clipmodel", "", clipModelName );
104  if ( !clipModelName[0] ) {
105  clipModelName = spawnArgs.GetString( "model" ); // use the visual model
106  }
107 
108  if ( !collisionModelManager->TrmFromModel( clipModelName, trm ) ) {
109  gameLocal.Error( "idMoveable '%s': cannot load collision model %s", name.c_str(), clipModelName.c_str() );
110  return;
111  }
112 
113  // if the model should be shrinked
114  clipShrink = spawnArgs.GetInt( "clipshrink" );
115  if ( clipShrink != 0 ) {
116  trm.Shrink( clipShrink * CM_CLIP_EPSILON );
117  }
118 
119  // get rigid body properties
120  spawnArgs.GetFloat( "density", "0.5", density );
121  density = idMath::ClampFloat( 0.001f, 1000.0f, density );
122  spawnArgs.GetFloat( "friction", "0.05", friction );
123  friction = idMath::ClampFloat( 0.0f, 1.0f, friction );
124  spawnArgs.GetFloat( "bouncyness", "0.6", bouncyness );
125  bouncyness = idMath::ClampFloat( 0.0f, 1.0f, bouncyness );
126  explode = spawnArgs.GetBool( "explode" );
127  unbindOnDeath = spawnArgs.GetBool( "unbindondeath" );
128 
129  fxCollide = spawnArgs.GetString( "fx_collide" );
130  nextCollideFxTime = 0;
131 
132  fl.takedamage = true;
133  damage = spawnArgs.GetString( "def_damage", "" );
134 #ifdef _D3XP
135  monsterDamage = spawnArgs.GetString( "monster_damage", "" );
136  fl.networkSync = true;
137  attacker = NULL;
138 #endif
139  canDamage = spawnArgs.GetBool( "damageWhenActive" ) ? false : true;
140  minDamageVelocity = spawnArgs.GetFloat( "minDamageVelocity", "300" ); // _D3XP
141  maxDamageVelocity = spawnArgs.GetFloat( "maxDamageVelocity", "700" ); // _D3XP
142  nextDamageTime = 0;
143  nextSoundTime = 0;
144 
145  health = spawnArgs.GetInt( "health", "0" );
146  spawnArgs.GetString( "broken", "", brokenModel );
147 
148  if ( health ) {
150  gameLocal.Error( "idMoveable '%s' at (%s): cannot load broken model '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), brokenModel.c_str() );
151  }
152  }
153 
154  // setup the physics
155  physicsObj.SetSelf( this );
156  physicsObj.SetClipModel( new idClipModel( trm ), density );
158  physicsObj.SetOrigin( GetPhysics()->GetOrigin() );
159  physicsObj.SetAxis( GetPhysics()->GetAxis() );
160  physicsObj.SetBouncyness( bouncyness );
161  physicsObj.SetFriction( 0.6f, 0.6f, friction );
166 
167  if ( spawnArgs.GetFloat( "mass", "10", mass ) ) {
168  physicsObj.SetMass( mass );
169  }
170 
171  if ( spawnArgs.GetBool( "nodrop" ) ) {
173  } else {
175  }
176 
177  if ( spawnArgs.GetBool( "noimpact" ) || spawnArgs.GetBool( "notPushable" ) ) {
179  }
180 
181  if ( spawnArgs.GetBool( "nonsolid" ) ) {
182  BecomeNonSolid();
183  }
184 
185  allowStep = spawnArgs.GetBool( "allowStep", "1" );
186 
188 }
189 
190 /*
191 ================
192 idMoveable::Save
193 ================
194 */
195 void idMoveable::Save( idSaveGame *savefile ) const {
196 
197  savefile->WriteString( brokenModel );
198  savefile->WriteString( damage );
199 #ifdef _D3XP
200  savefile->WriteString( monsterDamage );
201  savefile->WriteObject( attacker );
202 #endif
203  savefile->WriteString( fxCollide );
204  savefile->WriteInt( nextCollideFxTime );
205  savefile->WriteFloat( minDamageVelocity );
206  savefile->WriteFloat( maxDamageVelocity );
207  savefile->WriteBool( explode );
208  savefile->WriteBool( unbindOnDeath );
209  savefile->WriteBool( allowStep );
210  savefile->WriteBool( canDamage );
211  savefile->WriteInt( nextDamageTime );
212  savefile->WriteInt( nextSoundTime );
213  savefile->WriteInt( initialSpline != NULL ? initialSpline->GetTime( 0 ) : -1 );
214  savefile->WriteVec3( initialSplineDir );
215 
216  savefile->WriteStaticObject( physicsObj );
217 }
218 
219 /*
220 ================
221 idMoveable::Restore
222 ================
223 */
225  int initialSplineTime;
226 
227  savefile->ReadString( brokenModel );
228  savefile->ReadString( damage );
229 #ifdef _D3XP
230  savefile->ReadString( monsterDamage );
231  savefile->ReadObject( reinterpret_cast<idClass *&>( attacker ) );
232 #endif
233  savefile->ReadString( fxCollide );
234  savefile->ReadInt( nextCollideFxTime );
235  savefile->ReadFloat( minDamageVelocity );
236  savefile->ReadFloat( maxDamageVelocity );
237  savefile->ReadBool( explode );
238  savefile->ReadBool( unbindOnDeath );
239  savefile->ReadBool( allowStep );
240  savefile->ReadBool( canDamage );
241  savefile->ReadInt( nextDamageTime );
242  savefile->ReadInt( nextSoundTime );
243  savefile->ReadInt( initialSplineTime );
244  savefile->ReadVec3( initialSplineDir );
245 
246  if ( initialSplineTime != -1 ) {
247  InitInitialSpline( initialSplineTime );
248  } else {
250  }
251 
252  savefile->ReadStaticObject( physicsObj );
254 }
255 
256 /*
257 ================
258 idMoveable::Hide
259 ================
260 */
261 void idMoveable::Hide( void ) {
262  idEntity::Hide();
263  physicsObj.SetContents( 0 );
264 }
265 
266 /*
267 ================
268 idMoveable::Show
269 ================
270 */
271 void idMoveable::Show( void ) {
272  idEntity::Show();
273  if ( !spawnArgs.GetBool( "nonsolid" ) ) {
275  }
276 }
277 
278 /*
279 =================
280 idMoveable::Collide
281 =================
282 */
283 bool idMoveable::Collide( const trace_t &collision, const idVec3 &velocity ) {
284  float v, f;
285  idVec3 dir;
286  idEntity *ent;
287 
288  v = -( velocity * collision.c.normal );
289  if ( v > BOUNCE_SOUND_MIN_VELOCITY && gameLocal.time > nextSoundTime ) {
290  f = v > BOUNCE_SOUND_MAX_VELOCITY ? 1.0f : idMath::Sqrt( v - BOUNCE_SOUND_MIN_VELOCITY ) * ( 1.0f / idMath::Sqrt( BOUNCE_SOUND_MAX_VELOCITY - BOUNCE_SOUND_MIN_VELOCITY ) );
291  if ( StartSound( "snd_bounce", SND_CHANNEL_ANY, 0, false, NULL ) ) {
292  // don't set the volume unless there is a bounce sound as it overrides the entire channel
293  // which causes footsteps on ai's to not honor their shader parms
294  SetSoundVolume( f );
295  }
296  nextSoundTime = gameLocal.time + 500;
297  }
298 
299  // _D3XP :: changes relating to the addition of monsterDamage
301  bool hasDamage = damage.Length() > 0;
302  bool hasMonsterDamage = monsterDamage.Length() > 0;
303 
304  if ( hasDamage || hasMonsterDamage ) {
305  ent = gameLocal.entities[ collision.c.entityNum ];
306  if ( ent && v > minDamageVelocity ) {
308  dir = velocity;
309  dir.NormalizeFast();
310  if ( ent->IsType( idAI::Type ) && hasMonsterDamage ) {
311 #ifdef _D3XP
312  if ( attacker ) {
313  ent->Damage( this, attacker, dir, monsterDamage, f, INVALID_JOINT );
314  }
315  else {
316  ent->Damage( this, GetPhysics()->GetClipModel()->GetOwner(), dir, monsterDamage, f, INVALID_JOINT );
317  }
318 #else
319  ent->Damage( this, GetPhysics()->GetClipModel()->GetOwner(), dir, monsterDamage, f, INVALID_JOINT );
320 #endif
321  } else if ( hasDamage ) {
322 #ifdef _D3XP
323  // in multiplayer, scale damage wrt mass of object
324  if ( gameLocal.isMultiplayer ) {
325  f *= GetPhysics()->GetMass() * g_moveableDamageScale.GetFloat();
326  }
327 
328  if ( attacker ) {
329  ent->Damage( this, attacker, dir, damage, f, INVALID_JOINT );
330  }
331  else {
332  ent->Damage( this, GetPhysics()->GetClipModel()->GetOwner(), dir, damage, f, INVALID_JOINT );
333  }
334 #else
335  ent->Damage( this, GetPhysics()->GetClipModel()->GetOwner(), dir, damage, f, INVALID_JOINT );
336 #endif
337  }
338 
339  nextDamageTime = gameLocal.time + 1000;
340  }
341  }
342  }
343 
344 #ifdef _D3XP
345  if ( this->IsType( idExplodingBarrel::Type ) ) {
346  idExplodingBarrel *ebarrel = static_cast<idExplodingBarrel*>(this);
347 
348  if ( !ebarrel->IsStable() ) {
349  PostEventSec( &EV_Explode, 0.04f );
350  }
351  }
352 #endif
353 
355  idEntityFx::StartFx( fxCollide, &collision.c.point, NULL, this, false );
357  }
358 
359  return false;
360 }
361 
362 /*
363 ============
364 idMoveable::Killed
365 ============
366 */
367 void idMoveable::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) {
368  if ( unbindOnDeath ) {
369  Unbind();
370  }
371 
372  if ( brokenModel != "" ) {
374  }
375 
376  if ( explode ) {
377  if ( brokenModel == "" ) {
378  PostEventMS( &EV_Remove, 1000 );
379  }
380  }
381 
382  if ( renderEntity.gui[ 0 ] ) {
383  renderEntity.gui[ 0 ] = NULL;
384  }
385 
386  ActivateTargets( this );
387 
388  fl.takedamage = false;
389 }
390 
391 /*
392 ================
393 idMoveable::AllowStep
394 ================
395 */
396 bool idMoveable::AllowStep( void ) const {
397  return allowStep;
398 }
399 
400 /*
401 ================
402 idMoveable::BecomeNonSolid
403 ================
404 */
406  // set CONTENTS_RENDERMODEL so bullets still collide with the moveable
409 }
410 
411 /*
412 ================
413 idMoveable::EnableDamage
414 ================
415 */
416 void idMoveable::EnableDamage( bool enable, float duration ) {
417 #ifdef _D3XP
418  if ( canDamage == enable ) {
419  return;
420  }
421 #endif
422 
423  canDamage = enable;
424  if ( duration ) {
425  PostEventSec( &EV_EnableDamage, duration, ( /*_D3XP*/enable ) ? 0.0f : 1.0f );
426  }
427 }
428 
429 /*
430 ================
431 idMoveable::InitInitialSpline
432 ================
433 */
434 void idMoveable::InitInitialSpline( int startTime ) {
435  int initialSplineTime;
436 
438  initialSplineTime = spawnArgs.GetInt( "initialSplineTime", "300" );
439 
440  if ( initialSpline != NULL ) {
441  initialSpline->MakeUniform( initialSplineTime );
442  initialSpline->ShiftTime( startTime - initialSpline->GetTime( 0 ) );
447  }
448 }
449 
450 /*
451 ================
452 idMoveable::FollowInitialSplinePath
453 ================
454 */
456  if ( initialSpline != NULL ) {
459  idVec3 linearVelocity = ( splinePos - physicsObj.GetOrigin() ) * USERCMD_HZ;
460  physicsObj.SetLinearVelocity( linearVelocity );
461 
464  idVec3 angularVelocity = dir.Cross( splineDir );
465  angularVelocity.Normalize();
466  angularVelocity *= idMath::ACos16( dir * splineDir / splineDir.Length() ) * USERCMD_HZ;
467  physicsObj.SetAngularVelocity( angularVelocity );
468  return true;
469  } else {
470  delete initialSpline;
472  }
473  }
474  return false;
475 }
476 
477 /*
478 ================
479 idMoveable::Think
480 ================
481 */
482 void idMoveable::Think( void ) {
483  if ( thinkFlags & TH_THINK ) {
484  if ( !FollowInitialSplinePath() ) {
485  BecomeInactive( TH_THINK );
486  }
487  }
488  idEntity::Think();
489 }
490 
491 /*
492 ================
493 idMoveable::GetRenderModelMaterial
494 ================
495 */
497  if ( renderEntity.customShader ) {
498  return renderEntity.customShader;
499  }
501  return renderEntity.hModel->Surface( 0 )->shader;
502  }
503  return NULL;
504 }
505 
506 /*
507 ================
508 idMoveable::WriteToSnapshot
509 ================
510 */
513 }
514 
515 /*
516 ================
517 idMoveable::ReadFromSnapshot
518 ================
519 */
522  if ( msg.HasChanged() ) {
523  UpdateVisuals();
524  }
525 }
526 
527 /*
528 ================
529 idMoveable::Event_BecomeNonSolid
530 ================
531 */
533  BecomeNonSolid();
534 }
535 
536 #ifdef _D3XP
537 /*
538 ================
539 idMoveable::SetAttacker
540 ================
541 */
542 void idMoveable::SetAttacker( idEntity *ent ) {
543  attacker = ent;
544 }
545 #endif
546 
547 /*
548 ================
549 idMoveable::Event_Activate
550 ================
551 */
553  float delay;
554  idVec3 init_velocity, init_avelocity;
555 
556  Show();
557 
558  if ( !spawnArgs.GetInt( "notPushable" ) ) {
560  }
561 
563 
564  spawnArgs.GetVector( "init_velocity", "0 0 0", init_velocity );
565  spawnArgs.GetVector( "init_avelocity", "0 0 0", init_avelocity );
566 
567  delay = spawnArgs.GetFloat( "init_velocityDelay", "0" );
568  if ( delay == 0.0f ) {
569  physicsObj.SetLinearVelocity( init_velocity );
570  } else {
571  PostEventSec( &EV_SetLinearVelocity, delay, init_velocity );
572  }
573 
574  delay = spawnArgs.GetFloat( "init_avelocityDelay", "0" );
575  if ( delay == 0.0f ) {
576  physicsObj.SetAngularVelocity( init_avelocity );
577  } else {
578  PostEventSec( &EV_SetAngularVelocity, delay, init_avelocity );
579  }
580 
582 }
583 
584 /*
585 ================
586 idMoveable::Event_SetOwnerFromSpawnArgs
587 ================
588 */
590  idStr owner;
591 
592  if ( spawnArgs.GetString( "owner", "", owner ) ) {
594  }
595 }
596 
597 /*
598 ================
599 idMoveable::Event_IsAtRest
600 ================
601 */
604 }
605 
606 /*
607 ================
608 idMoveable::Event_EnableDamage
609 ================
610 */
611 void idMoveable::Event_EnableDamage( float enable ) {
612 #ifdef _D3XP
613  // clear out attacker
614  attacker = NULL;
615 #endif
616 
617  canDamage = ( enable != 0.0f );
618 }
619 
620 
621 /*
622 ===============================================================================
623 
624  idBarrel
625 
626 ===============================================================================
627 */
628 
630 END_CLASS
631 
632 /*
633 ================
634 idBarrel::idBarrel
635 ================
636 */
638  radius = 1.0f;
639  barrelAxis = 0;
640  lastOrigin.Zero();
641  lastAxis.Identity();
642  additionalRotation = 0.0f;
643  additionalAxis.Identity();
644  fl.networkSync = true;
645 }
646 
647 /*
648 ================
649 idBarrel::Save
650 ================
651 */
652 void idBarrel::Save( idSaveGame *savefile ) const {
653  savefile->WriteFloat( radius );
654  savefile->WriteInt( barrelAxis );
655  savefile->WriteVec3( lastOrigin );
656  savefile->WriteMat3( lastAxis );
657  savefile->WriteFloat( additionalRotation );
658  savefile->WriteMat3( additionalAxis );
659 }
660 
661 /*
662 ================
663 idBarrel::Restore
664 ================
665 */
666 void idBarrel::Restore( idRestoreGame *savefile ) {
667  savefile->ReadFloat( radius );
668  savefile->ReadInt( barrelAxis );
669  savefile->ReadVec3( lastOrigin );
670  savefile->ReadMat3( lastAxis );
671  savefile->ReadFloat( additionalRotation );
672  savefile->ReadMat3( additionalAxis );
673 }
674 
675 /*
676 ================
677 idBarrel::BarrelThink
678 ================
679 */
680 void idBarrel::BarrelThink( void ) {
681  bool wasAtRest, onGround;
682  float movedDistance, rotatedDistance, angle;
683  idVec3 curOrigin, gravityNormal, dir;
684  idMat3 curAxis, axis;
685 
686  wasAtRest = IsAtRest();
687 
688  // run physics
689  RunPhysics();
690 
691  // only need to give the visual model an additional rotation if the physics were run
692  if ( !wasAtRest ) {
693 
694  // current physics state
695  onGround = GetPhysics()->HasGroundContacts();
696  curOrigin = GetPhysics()->GetOrigin();
697  curAxis = GetPhysics()->GetAxis();
698 
699  // if the barrel is on the ground
700  if ( onGround ) {
701  gravityNormal = GetPhysics()->GetGravityNormal();
702 
703  dir = curOrigin - lastOrigin;
704  dir -= gravityNormal * dir * gravityNormal;
705  movedDistance = dir.LengthSqr();
706 
707  // if the barrel moved and the barrel is not aligned with the gravity direction
708  if ( movedDistance > 0.0f && idMath::Fabs( gravityNormal * curAxis[barrelAxis] ) < 0.7f ) {
709 
710  // barrel movement since last think frame orthogonal to the barrel axis
711  movedDistance = idMath::Sqrt( movedDistance );
712  dir *= 1.0f / movedDistance;
713  movedDistance = ( 1.0f - idMath::Fabs( dir * curAxis[barrelAxis] ) ) * movedDistance;
714 
715  // get rotation about barrel axis since last think frame
716  angle = lastAxis[(barrelAxis+1)%3] * curAxis[(barrelAxis+1)%3];
717  angle = idMath::ACos( angle );
718  // distance along cylinder hull
719  rotatedDistance = angle * radius;
720 
721  // if the barrel moved further than it rotated about it's axis
722  if ( movedDistance > rotatedDistance ) {
723 
724  // additional rotation of the visual model to make it look
725  // like the barrel rolls instead of slides
726  angle = 180.0f * (movedDistance - rotatedDistance) / (radius * idMath::PI);
727  if ( gravityNormal.Cross( curAxis[barrelAxis] ) * dir < 0.0f ) {
728  additionalRotation += angle;
729  } else {
730  additionalRotation -= angle;
731  }
732  dir = vec3_origin;
733  dir[barrelAxis] = 1.0f;
735  }
736  }
737  }
738 
739  // save state for next think
740  lastOrigin = curOrigin;
741  lastAxis = curAxis;
742  }
743 
744  Present();
745 }
746 
747 /*
748 ================
749 idBarrel::Think
750 ================
751 */
752 void idBarrel::Think( void ) {
753  if ( thinkFlags & TH_THINK ) {
754  if ( !FollowInitialSplinePath() ) {
755  BecomeInactive( TH_THINK );
756  }
757  }
758 
759  BarrelThink();
760 }
761 
762 /*
763 ================
764 idBarrel::GetPhysicsToVisualTransform
765 ================
766 */
768  origin = vec3_origin;
769  axis = additionalAxis;
770  return true;
771 }
772 
773 /*
774 ================
775 idBarrel::Spawn
776 ================
777 */
778 void idBarrel::Spawn( void ) {
779  const idBounds &bounds = GetPhysics()->GetBounds();
780 
781  // radius of the barrel cylinder
782  radius = ( bounds[1][0] - bounds[0][0] ) * 0.5f;
783 
784  // always a vertical barrel with cylinder axis parallel to the z-axis
785  barrelAxis = 2;
786 
788  lastAxis = GetPhysics()->GetAxis();
789 
790  additionalRotation = 0.0f;
792 
793 #ifdef _D3XP
794  fl.networkSync = true;
795 #endif
796 }
797 
798 /*
799 ================
800 idBarrel::ClientPredictionThink
801 ================
802 */
804  Think();
805 }
806 
807 
808 /*
809 ===============================================================================
810 
811 idExplodingBarrel
812 
813 ===============================================================================
814 */
815 const idEventDef EV_Respawn( "<respawn>" );
816 const idEventDef EV_TriggerTargets( "<triggertargets>" );
817 
819  EVENT( EV_Activate, idExplodingBarrel::Event_Activate )
820  EVENT( EV_Respawn, idExplodingBarrel::Event_Respawn )
821  EVENT( EV_Explode, idExplodingBarrel::Event_Explode )
822  EVENT( EV_TriggerTargets, idExplodingBarrel::Event_TriggerTargets )
823 END_CLASS
824 
825 /*
826 ================
827 idExplodingBarrel::idExplodingBarrel
828 ================
829 */
831  spawnOrigin.Zero();
832  spawnAxis.Zero();
833  state = NORMAL;
834 #ifdef _D3XP
835  isStable = true;
836 #endif
837  particleModelDefHandle = -1;
838  lightDefHandle = -1;
839  memset( &particleRenderEntity, 0, sizeof( particleRenderEntity ) );
840  memset( &light, 0, sizeof( light ) );
841  particleTime = 0;
842  lightTime = 0;
843  time = 0.0f;
844 }
845 
846 /*
847 ================
848 idExplodingBarrel::~idExplodingBarrel
849 ================
850 */
852  if ( particleModelDefHandle >= 0 ){
854  }
855  if ( lightDefHandle >= 0 ) {
857  }
858 }
859 
860 /*
861 ================
862 idExplodingBarrel::Save
863 ================
864 */
865 void idExplodingBarrel::Save( idSaveGame *savefile ) const {
866  savefile->WriteVec3( spawnOrigin );
867  savefile->WriteMat3( spawnAxis );
868 
869  savefile->WriteInt( state );
870  savefile->WriteInt( particleModelDefHandle );
871  savefile->WriteInt( lightDefHandle );
872 
874  savefile->WriteRenderLight( light );
875 
876  savefile->WriteInt( particleTime );
877  savefile->WriteInt( lightTime );
878  savefile->WriteFloat( time );
879 
880 #ifdef _D3XP
881  savefile->WriteBool( isStable );
882 #endif
883 }
884 
885 /*
886 ================
887 idExplodingBarrel::Restore
888 ================
889 */
891  savefile->ReadVec3( spawnOrigin );
892  savefile->ReadMat3( spawnAxis );
893 
894  savefile->ReadInt( (int &)state );
895  savefile->ReadInt( (int &)particleModelDefHandle );
896  savefile->ReadInt( (int &)lightDefHandle );
897 
899  savefile->ReadRenderLight( light );
900 
901  savefile->ReadInt( particleTime );
902  savefile->ReadInt( lightTime );
903  savefile->ReadFloat( time );
904 
905 #ifdef _D3XP
906  savefile->ReadBool( isStable );
907 
908  if ( lightDefHandle != -1 ) {
909  lightDefHandle = gameRenderWorld->AddLightDef( &light );
910  }
911  if ( particleModelDefHandle != -1 ) {
912  particleModelDefHandle = gameRenderWorld->AddEntityDef( &particleRenderEntity );
913  }
914 #endif
915 }
916 
917 /*
918 ================
919 idExplodingBarrel::Spawn
920 ================
921 */
923  health = spawnArgs.GetInt( "health", "5" );
924  fl.takedamage = true;
925 #ifdef _D3XP
926  isStable = true;
927  fl.networkSync = true;
928 #endif
931  state = NORMAL;
933  lightDefHandle = -1;
934  lightTime = 0;
935  particleTime = 0;
936  time = spawnArgs.GetFloat( "time" );
937  memset( &particleRenderEntity, 0, sizeof( particleRenderEntity ) );
938  memset( &light, 0, sizeof( light ) );
939 }
940 
941 /*
942 ================
943 idExplodingBarrel::Think
944 ================
945 */
948 
949  if ( lightDefHandle >= 0 ){
950  if ( state == BURNING ) {
951  // ramp the color up over 250 ms
952  float pct = (gameLocal.time - lightTime) / 250.f;
953  if ( pct > 1.0f ) {
954  pct = 1.0f;
955  }
963  } else {
964  if ( gameLocal.time - lightTime > 250 ) {
966  lightDefHandle = -1;
967  }
968  return;
969  }
970  }
971 
972  if ( !gameLocal.isClient && state != BURNING && state != EXPLODING ) {
974  return;
975  }
976 
977  if ( particleModelDefHandle >= 0 ){
981  }
982 }
983 
984 #ifdef _D3XP
985 /*
986 ================
987 idExplodingBarrel::SetStability
988 ================
989 */
990 void idExplodingBarrel::SetStability( bool stability ) {
991  isStable = stability;
992 }
993 
994 /*
995 ================
996 idExplodingBarrel::IsStable
997 ================
998 */
999 bool idExplodingBarrel::IsStable( void ) {
1000  return isStable;
1001 }
1002 
1003 /*
1004 ================
1005 idExplodingBarrel::StartBurning
1006 ================
1007 */
1008 void idExplodingBarrel::StartBurning( void ) {
1009  state = BURNING;
1010  AddParticles( "barrelfire.prt", true );
1011 }
1012 
1013 /*
1014 ================
1015 idExplodingBarrel::StartBurning
1016 ================
1017 */
1018 void idExplodingBarrel::StopBurning( void ) {
1019  state = NORMAL;
1020 
1021  if ( particleModelDefHandle >= 0 ){
1024 
1025  particleTime = 0;
1026  memset( &particleRenderEntity, 0, sizeof( particleRenderEntity ) );
1027  }
1028 }
1029 #endif
1030 
1031 /*
1032 ================
1033 idExplodingBarrel::AddParticles
1034 ================
1035 */
1036 void idExplodingBarrel::AddParticles( const char *name, bool burn ) {
1037  if ( name && *name ) {
1038 #ifdef _D3XP
1039  int explicitTimeGroup = timeGroup;
1040  SetTimeState explicitTS( explicitTimeGroup );
1041 #endif
1042  if ( particleModelDefHandle >= 0 ){
1044  }
1045  memset( &particleRenderEntity, 0, sizeof ( particleRenderEntity ) );
1046  const idDeclModelDef *modelDef = static_cast<const idDeclModelDef *>( declManager->FindType( DECL_MODELDEF, name ) );
1047  if ( modelDef ) {
1050  particleRenderEntity.hModel = modelDef->ModelHandle();
1051  float rgb = ( burn ) ? 0.0f : 1.0f;
1058 #ifdef _D3XP
1059  particleRenderEntity.timeGroup = explicitTimeGroup;
1060 #endif
1061  if ( !particleRenderEntity.hModel ) {
1063  }
1065  if ( burn ) {
1067  }
1069  }
1070  }
1071 }
1072 
1073 /*
1074 ================
1075 idExplodingBarrel::AddLight
1076 ================
1077 */
1078 void idExplodingBarrel::AddLight( const char *name, bool burn ) {
1079  if ( lightDefHandle >= 0 ){
1081  }
1082  memset( &light, 0, sizeof ( light ) );
1084  light.lightRadius.x = spawnArgs.GetFloat( "light_radius" );
1087  light.origin.z += 128;
1088  light.pointLight = true;
1089  light.shader = declManager->FindMaterial( name );
1090  light.shaderParms[ SHADERPARM_RED ] = 2.0f;
1092  light.shaderParms[ SHADERPARM_BLUE ] = 2.0f;
1097 }
1098 
1099 /*
1100 ================
1101 idExplodingBarrel::ExplodingEffects
1102 ================
1103 */
1105  const char *temp;
1106 
1107  StartSound( "snd_explode", SND_CHANNEL_ANY, 0, false, NULL );
1108 
1109  temp = spawnArgs.GetString( "model_damage" );
1110  if ( *temp != '\0' ) {
1111  SetModel( temp );
1112  Show();
1113  }
1114 
1115  temp = spawnArgs.GetString( "model_detonate" );
1116  if ( *temp != '\0' ) {
1117  AddParticles( temp, false );
1118  }
1119 
1120  temp = spawnArgs.GetString( "mtr_lightexplode" );
1121  if ( *temp != '\0' ) {
1122  AddLight( temp, false );
1123  }
1124 
1125  temp = spawnArgs.GetString( "mtr_burnmark" );
1126  if ( *temp != '\0' ) {
1127  gameLocal.ProjectDecal( GetPhysics()->GetOrigin(), GetPhysics()->GetGravity(), 128.0f, true, 96.0f, temp );
1128  }
1129 }
1130 
1131 /*
1132 ================
1133 idExplodingBarrel::Killed
1134 ================
1135 */
1136 void idExplodingBarrel::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) {
1137 
1138  if ( IsHidden() || state == EXPLODING || state == BURNING ) {
1139  return;
1140  }
1141 
1142  float f = spawnArgs.GetFloat( "burn" );
1143  if ( f > 0.0f && state == NORMAL ) {
1144  state = BURNING;
1145  PostEventSec( &EV_Explode, f );
1146  StartSound( "snd_burn", SND_CHANNEL_ANY, 0, false, NULL );
1147  AddParticles( spawnArgs.GetString ( "model_burn", "" ), true );
1148  return;
1149  } else {
1150  state = EXPLODING;
1151  if ( gameLocal.isServer ) {
1152  idBitMsg msg;
1153  byte msgBuf[MAX_EVENT_PARAM_SIZE];
1154 
1155  msg.Init( msgBuf, sizeof( msgBuf ) );
1156  msg.WriteLong( gameLocal.time );
1157  ServerSendEvent( EVENT_EXPLODE, &msg, false, -1 );
1158  }
1159  }
1160 
1161  // do this before applying radius damage so the ent can trace to any damagable ents nearby
1162  Hide();
1163  physicsObj.SetContents( 0 );
1164 
1165  const char *splash = spawnArgs.GetString( "def_splash_damage", "damage_explosion" );
1166  if ( splash && *splash ) {
1167  gameLocal.RadiusDamage( GetPhysics()->GetOrigin(), this, attacker, this, this, splash );
1168  }
1169 
1170  ExplodingEffects( );
1171 
1172  //FIXME: need to precache all the debris stuff here and in the projectiles
1173  const idKeyValue *kv = spawnArgs.MatchPrefix( "def_debris" );
1174  // bool first = true;
1175  while ( kv ) {
1176  const idDict *debris_args = gameLocal.FindEntityDefDict( kv->GetValue(), false );
1177  if ( debris_args ) {
1178  idEntity *ent;
1179  idVec3 dir;
1180  idDebris *debris;
1181  //if ( first ) {
1182  dir = physicsObj.GetAxis()[1];
1183  // first = false;
1184  //} else {
1185  dir.x += gameLocal.random.CRandomFloat() * 4.0f;
1186  dir.y += gameLocal.random.CRandomFloat() * 4.0f;
1187  //dir.z = gameLocal.random.RandomFloat() * 8.0f;
1188  //}
1189  dir.Normalize();
1190 
1191  gameLocal.SpawnEntityDef( *debris_args, &ent, false );
1192  if ( !ent || !ent->IsType( idDebris::Type ) ) {
1193  gameLocal.Error( "'projectile_debris' is not an idDebris" );
1194  }
1195 
1196  debris = static_cast<idDebris *>(ent);
1197  debris->Create( this, physicsObj.GetOrigin(), dir.ToMat3() );
1198  debris->Launch();
1199  debris->GetRenderEntity()->shaderParms[ SHADERPARM_TIME_OF_DEATH ] = ( gameLocal.time + 1500 ) * 0.001f;
1200  debris->UpdateVisuals();
1201 
1202  }
1203  kv = spawnArgs.MatchPrefix( "def_debris", kv );
1204  }
1205 
1209 
1210  f = spawnArgs.GetFloat( "respawn" );
1211  if ( f > 0.0f ) {
1212  PostEventSec( &EV_Respawn, f );
1213  } else {
1214  PostEventMS( &EV_Remove, 5000 );
1215  }
1216 
1217  if ( spawnArgs.GetBool( "triggerTargets" ) ) {
1218  ActivateTargets( this );
1219  }
1220 }
1221 
1222 /*
1223 ================
1224 idExplodingBarrel::Damage
1225 ================
1226 */
1227 void idExplodingBarrel::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir,
1228  const char *damageDefName, const float damageScale, const int location ) {
1229 
1230  const idDict *damageDef = gameLocal.FindEntityDefDict( damageDefName );
1231  if ( !damageDef ) {
1232  gameLocal.Error( "Unknown damageDef '%s'\n", damageDefName );
1233  }
1234  if ( damageDef->FindKey( "radius" ) && GetPhysics()->GetContents() != 0 && GetBindMaster() == NULL ) {
1235  PostEventMS( &EV_Explode, 400 );
1236  } else {
1237  idEntity::Damage( inflictor, attacker, dir, damageDefName, damageScale, location );
1238  }
1239 }
1240 
1241 /*
1242 ================
1243 idExplodingBarrel::Event_TriggerTargets
1244 ================
1245 */
1247  ActivateTargets( this );
1248 }
1249 
1250 /*
1251 ================
1252 idExplodingBarrel::Event_Explode
1253 ================
1254 */
1256  if ( state == NORMAL || state == BURNING ) {
1257  state = BURNEXPIRED;
1258  Killed( NULL, NULL, 0, vec3_zero, 0 );
1259  }
1260 }
1261 
1262 /*
1263 ================
1264 idExplodingBarrel::Event_Respawn
1265 ================
1266 */
1268  int i;
1269  int minRespawnDist = spawnArgs.GetInt( "respawn_range", "256" );
1270  if ( minRespawnDist ) {
1271  float minDist = -1;
1272  for ( i = 0; i < gameLocal.numClients; i++ ) {
1273  if ( !gameLocal.entities[ i ] || !gameLocal.entities[ i ]->IsType( idPlayer::Type ) ) {
1274  continue;
1275  }
1277  float dist = v.Length();
1278  if ( minDist < 0 || dist < minDist ) {
1279  minDist = dist;
1280  }
1281  }
1282  if ( minDist < minRespawnDist ) {
1283  PostEventSec( &EV_Respawn, spawnArgs.GetInt( "respawn_again", "10" ) );
1284  return;
1285  }
1286  }
1287  const char *temp = spawnArgs.GetString( "model" );
1288  if ( temp && *temp ) {
1289  SetModel( temp );
1290  }
1291  health = spawnArgs.GetInt( "health", "5" );
1292  fl.takedamage = true;
1297  state = NORMAL;
1298  Show();
1299  UpdateVisuals();
1300 }
1301 
1302 /*
1303 ================
1304 idMoveable::Event_Activate
1305 ================
1306 */
1308  Killed( activator, activator, 0, vec3_origin, 0 );
1309 }
1310 
1311 /*
1312 ================
1313 idMoveable::WriteToSnapshot
1314 ================
1315 */
1318  msg.WriteBits( IsHidden(), 1 );
1319 }
1320 
1321 /*
1322 ================
1323 idMoveable::ReadFromSnapshot
1324 ================
1325 */
1327 
1329  if ( msg.ReadBits( 1 ) ) {
1330  Hide();
1331  } else {
1332  Show();
1333  }
1334 }
1335 
1336 /*
1337 ================
1338 idExplodingBarrel::ClientReceiveEvent
1339 ================
1340 */
1341 bool idExplodingBarrel::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) {
1342 
1343  switch( event ) {
1344  case EVENT_EXPLODE: {
1345  if ( gameLocal.realClientTime - msg.ReadLong() < spawnArgs.GetInt( "explode_lapse", "1000" ) ) {
1346  ExplodingEffects( );
1347  }
1348  return true;
1349  }
1350  default: {
1351  return idBarrel::ClientReceiveEvent( event, time, msg );
1352  }
1353  }
1354  return false;
1355 }
virtual const idVec3 & GetOrigin(int id=0) const =0
idVec3 lastOrigin
Definition: Moveable.h:133
void SetAngularVelocity(const idVec3 &newAngularVelocity, int id=0)
void SetClipModel(idClipModel *model, float density, int id=0, bool freeOld=true)
renderEntity_t renderEntity
Definition: Entity.h:371
float GetFloat(const char *key, const char *defaultString="0") const
Definition: Dict.h:248
void InitInitialSpline(int startTime)
Definition: Moveable.cpp:434
idMat3 ToMat3(void) const
Definition: Vector.cpp:195
virtual bool TrmFromModel(const char *modelName, idTraceModel &trm)=0
~idMoveable(void)
Definition: Moveable.cpp:86
const idEventDef EV_SetOwner("setOwner","e")
void WriteString(const char *string)
Definition: SaveGame.cpp:231
float Normalize(void)
Definition: Vector.h:646
const idEventDef EV_EnableDamage("enableDamage","f")
qhandle_t lightDefHandle
Definition: Moveable.h:195
int GetInt(const char *key, const char *defaultString="0") const
Definition: Dict.h:252
void SetLinearVelocity(const idVec3 &newLinearVelocity, int id=0)
bool PostEventSec(const idEventDef *ev, float time)
Definition: Class.cpp:747
idVec3 spawnOrigin
Definition: Moveable.h:192
const idDict * FindEntityDefDict(const char *name, bool makeDefault=true) const
virtual const idVec3 & GetGravityNormal(void) const =0
const int SHADERPARM_DIVERSITY
Definition: RenderWorld.h:52
const idEventDef EV_Respawn("<respawn>")
virtual void FreeLightDef(qhandle_t lightHandle)=0
idMat3 mat3_identity(idVec3(1, 0, 0), idVec3(0, 1, 0), idVec3(0, 0, 1))
bool allowStep
Definition: Moveable.h:87
void WriteObject(const idClass *obj)
Definition: SaveGame.cpp:329
idVec3 GetCenter(void) const
Definition: Bounds.h:211
struct idEntity::entityFlags_s fl
const int MAX_EVENT_PARAM_SIZE
Definition: Game_local.h:132
static float ACos16(float a)
Definition: Math.h:554
const GLdouble * v
Definition: glext.h:2936
idVec3 initialSplineDir
Definition: Moveable.h:84
const idEventDef EV_Activate("activate","e")
void Event_SetOwnerFromSpawnArgs(void)
Definition: Moveable.cpp:589
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
#define const
Definition: getdate.c:251
void Event_Activate(idEntity *activator)
Definition: Moveable.cpp:552
idMat3 Transpose(void) const
Definition: Matrix.h:677
idRandom random
Definition: Game_local.h:291
int Length(void) const
Definition: Str.h:702
int barrelAxis
Definition: Moveable.h:132
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
bool IsType(const idTypeInfo &c) const
Definition: Class.h:337
static const float PI
Definition: Math.h:205
idEntity * FindEntity(const char *name) const
int ReadLong(void) const
Definition: BitMsg.h:375
float z
Definition: Vector.h:320
virtual bool Collide(const trace_t &collision, const idVec3 &velocity)
Definition: Moveable.cpp:283
#define MASK_SOLID
Definition: Game_local.h:735
const idKeyValue * MatchPrefix(const char *prefix, const idKeyValue *lastMatch=NULL) const
Definition: Dict.cpp:523
bool ProcessEvent(const idEventDef *ev)
Definition: Class.cpp:858
void WriteBits(int value, int numBits)
Definition: BitMsg.cpp:648
const idMaterial * shader
Definition: Model.h:146
void RadiusDamage(const idVec3 &origin, idEntity *inflictor, idEntity *attacker, idEntity *ignoreDamage, idEntity *ignorePush, const char *damageDefName, float dmgPower=1.0f)
static float ClampFloat(float min, float max, float value)
Definition: Math.h:893
float minDamageVelocity
Definition: Moveable.h:81
void Restore(idRestoreGame *savefile)
Definition: Moveable.cpp:224
bool isClient
Definition: Game_local.h:327
const idEventDef EV_SetAngularVelocity("setAngularVelocity","v")
Definition: Vector.h:316
void ReadBool(bool &value)
Definition: SaveGame.cpp:976
bool isServer
Definition: Game_local.h:326
void WriteStaticObject(const idClass &obj)
Definition: SaveGame.cpp:348
static float Sqrt(float x)
Definition: Math.h:302
const idVec3 & GetOrigin(int id=0) const
const int SHADERPARM_GREEN
Definition: RenderWorld.h:47
bool FollowInitialSplinePath(void)
Definition: Moveable.cpp:455
renderEntity_t particleRenderEntity
Definition: Moveable.h:196
void ExplodingEffects(void)
Definition: Moveable.cpp:1104
virtual qhandle_t AddLightDef(const renderLight_t *rlight)=0
virtual const idMaterial * FindMaterial(const char *name, bool makeDefault=true)=0
void ReadFromSnapshot(const idBitMsgDelta &msg)
void SetSoundVolume(float volume)
Definition: Entity.cpp:1740
idVec3 Cross(const idVec3 &a) const
Definition: Vector.h:619
int ReadBits(int numBits) const
Definition: BitMsg.cpp:709
void Identity(void)
Definition: Matrix.h:591
void ShiftTime(const float deltaTime)
Definition: Curve.h:360
int nextCollideFxTime
Definition: Moveable.h:80
float x
Definition: Vector.h:318
idDict spawnArgs
Definition: Entity.h:122
bool canDamage
Definition: Moveable.h:88
int i
Definition: process.py:33
bool AllowStep(void) const
Definition: Moveable.cpp:396
contactInfo_t c
void WriteVec3(const idVec3 &vec)
Definition: SaveGame.cpp:253
bool HasChanged(void) const
Definition: BitMsg.h:534
void ReadRenderEntity(renderEntity_t &renderEntity)
Definition: SaveGame.cpp:1269
idPhysics_RigidBody physicsObj
Definition: Moveable.h:72
virtual void SetModel(const char *modelname)
Definition: Entity.cpp:1150
const idMaterial * customShader
Definition: RenderWorld.h:123
const int SHADERPARM_ALPHA
Definition: RenderWorld.h:49
virtual bool IsAtRest(void) const
Definition: Entity.cpp:2914
#define EVENT(event, function)
Definition: Class.h:53
const idEventDef EV_Explode("<explode>", NULL)
void Init(byte *data, int length)
Definition: BitMsg.h:155
void Spawn(void)
Definition: Moveable.cpp:922
const idEventDef EV_SetLinearVelocity("setLinearVelocity","v")
void WriteBool(const bool value)
Definition: SaveGame.cpp:222
float shaderParms[MAX_ENTITY_SHADER_PARMS]
Definition: RenderWorld.h:201
int nextSoundTime
Definition: Moveable.h:90
idStr fxCollide
Definition: Moveable.h:79
bool IsHidden(void) const
Definition: Entity.cpp:1217
virtual void Killed(idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location)
Definition: Moveable.cpp:367
idCurve_Spline< idVec3 > * GetSpline(void) const
Definition: Entity.cpp:3755
const idEventDef EV_SetOwnerFromSpawnArgs("<setOwnerFromSpawnArgs>")
virtual void WriteToSnapshot(idBitMsgDelta &msg) const
Definition: Moveable.cpp:1316
virtual const idBounds & GetBounds(int id=-1) const =0
const int SHADERPARM_BLUE
Definition: RenderWorld.h:48
void Save(idSaveGame *savefile) const
Definition: Moveable.cpp:195
void Restore(idRestoreGame *savefile)
Definition: Moveable.cpp:890
int RandomInt(void)
Definition: Random.h:70
virtual void Show(void)
Definition: Entity.cpp:1239
virtual void Think(void)
Definition: Entity.cpp:891
void SetSelf(idEntity *e)
virtual void FreeEntityDef(qhandle_t entityHandle)=0
void Spawn(void)
Definition: Moveable.cpp:96
bool explode
Definition: Moveable.h:85
idPhysics * GetPhysics(void) const
Definition: Entity.cpp:2607
const char * GetString(const char *key, const char *defaultString="") const
Definition: Dict.h:240
bool SpawnEntityDef(const idDict &args, idEntity **ent=NULL, bool setDefaults=true)
void ReadFloat(float &value)
Definition: SaveGame.cpp:967
idVec3 lightRadius
Definition: RenderWorld.h:178
float Length(void) const
Definition: Vector.h:631
bool StartSound(const char *soundName, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length)
Definition: Entity.cpp:1622
idVec3 vec3_origin(0.0f, 0.0f, 0.0f)
void ReadRenderLight(renderLight_t &renderLight)
Definition: SaveGame.cpp:1333
virtual renderEntity_t * GetRenderEntity(void)
Definition: Entity.cpp:1506
#define vec3_zero
Definition: Vector.h:390
void SetPhysics(idPhysics *phys)
Definition: Entity.cpp:2574
void Unbind(void)
Definition: Entity.cpp:2011
void Launch(void)
void WriteToSnapshot(idBitMsgDelta &msg) const
void WriteLong(int c)
Definition: BitMsg.h:295
virtual type GetCurrentValue(const float time) const
Definition: Curve.h:134
void WriteFloat(const float value)
Definition: SaveGame.cpp:213
static float Fabs(float f)
Definition: Math.h:779
virtual float GetMass(int id=-1) const =0
bool GetBool(const char *key, const char *defaultString="0") const
Definition: Dict.h:256
void Save(idSaveGame *savefile) const
Definition: Moveable.cpp:865
Definition: Dict.h:65
float additionalRotation
Definition: Moveable.h:135
#define NULL
Definition: Lib.h:88
const idBounds & GetAbsBounds(int id=-1) const
virtual idRenderModel * FindModel(const char *modelName)=0
virtual const idDecl * FindType(declType_t type, const char *name, bool makeDefault=true)=0
float y
Definition: Vector.h:319
float maxDamageVelocity
Definition: Moveable.h:82
idVec3 GetVector(const char *key, const char *defaultString=NULL) const
Definition: Dict.h:260
bool IsAtRest(void) const
const int SHADERPARM_TIME_OF_DEATH
Definition: RenderWorld.h:54
void ServerSendEvent(int eventId, const idBitMsg *msg, bool saveEvent, int excludeClient) const
Definition: Entity.cpp:4897
virtual void Killed(idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location)
Definition: Moveable.cpp:1136
virtual const modelSurface_t * Surface(int surfaceNum) const =0
void CancelEvents(const idEventDef *ev)
Definition: Class.cpp:619
const idEventDef EV_TriggerTargets("<triggertargets>")
const idVec3 & GetGravity(void) const
void SetMaterial(const idMaterial *m)
Definition: Clip.h:158
#define CM_CLIP_EPSILON
virtual bool GetPhysicsToVisualTransform(idVec3 &origin, idMat3 &axis)
Definition: Moveable.cpp:767
const idStr & GetValue(void) const
Definition: Dict.h:53
virtual const idMat3 & GetAxis(int id=0) const =0
virtual void UpdateEntityDef(qhandle_t entityHandle, const renderEntity_t *re)=0
virtual void Think(void)
Definition: Moveable.cpp:946
void SetFriction(const float linear, const float angular, const float contact)
float NormalizeFast(void)
Definition: Vector.h:524
virtual bool HasGroundContacts(void) const =0
void Save(idSaveGame *savefile) const
Definition: Moveable.cpp:652
float radius
Definition: Moveable.h:131
virtual type GetCurrentFirstDerivative(const float time) const
Definition: Curve.h:153
idGameLocal gameLocal
Definition: Game_local.cpp:64
float LengthSqr(void) const
Definition: Vector.h:635
bool RunPhysics(void)
Definition: Entity.cpp:2616
const int SHADERPARM_TIMEOFFSET
Definition: RenderWorld.h:51
void Event_IsAtRest(void)
Definition: Moveable.cpp:602
void WriteRenderEntity(const renderEntity_t &renderEntity)
Definition: SaveGame.cpp:497
idMat3 spawnAxis
Definition: Moveable.h:193
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
explode_state_t state
Definition: Moveable.h:190
virtual void ReadFromSnapshot(const idBitMsgDelta &msg)
Definition: Moveable.cpp:520
virtual void UpdateLightDef(qhandle_t lightHandle, const renderLight_t *rlight)=0
virtual void WriteToSnapshot(idBitMsgDelta &msg) const
Definition: Moveable.cpp:511
virtual void Hide(void)
Definition: Entity.cpp:1226
void SetAxis(const idMat3 &newAxis, int id=-1)
const char * ToString(int precision=2) const
Definition: Vector.cpp:221
void WriteInt(const int value)
Definition: SaveGame.cpp:168
int numClients
Definition: Game_local.h:271
virtual void Present(void)
Definition: Entity.cpp:1471
float GetTime(const int index) const
Definition: Curve.h:60
idDeclManager * declManager
void WriteMat3(const idMat3 &mat)
Definition: SaveGame.cpp:309
void Event_Activate(idEntity *activator)
Definition: Moveable.cpp:1307
void ReadMat3(idMat3 &mat)
Definition: SaveGame.cpp:1064
idEntity * entities[MAX_GENTITIES]
Definition: Game_local.h:275
void Shrink(const float m)
virtual bool ClientReceiveEvent(int event, int time, const idBitMsg &msg)
Definition: Entity.cpp:4988
int health
Definition: Entity.h:134
void SetContents(int contents, int id=-1)
void ReadStaticObject(idClass &obj)
Definition: SaveGame.cpp:1098
void Event_TriggerTargets()
Definition: Moveable.cpp:1246
idRenderModelManager * renderModelManager
qhandle_t particleModelDefHandle
Definition: Moveable.h:194
Definition: Matrix.h:333
const int SHADERPARM_RED
Definition: RenderWorld.h:46
void BarrelThink(void)
Definition: Moveable.cpp:680
void SetClipMask(int mask, int id=-1)
const idMaterial * GetRenderModelMaterial(void) const
Definition: Moveable.cpp:496
void UpdateVisuals(void)
Definition: Entity.cpp:1310
tuple f
Definition: idal.py:89
void Event_BecomeNonSolid(void)
Definition: Moveable.cpp:532
void ProjectDecal(const idVec3 &origin, const idVec3 &dir, float depth, bool parallel, float size, const char *material, float angle=0)
virtual void Think(void)
Definition: Moveable.cpp:482
const idMat3 & ToMat3(void) const
Definition: Rotation.cpp:60
int nextDamageTime
Definition: Moveable.h:89
virtual void ClientPredictionThink(void)
Definition: Moveable.cpp:803
unsigned char byte
Definition: Lib.h:75
const GLcharARB * name
Definition: glext.h:3629
void Create(idEntity *owner, const idVec3 &start, const idMat3 &axis)
idStr brokenModel
Definition: Moveable.h:73
idStr damage
Definition: Moveable.h:74
#define CLASS_DECLARATION(nameofsuperclass, nameofclass)
Definition: Class.h:110
Definition: Str.h:116
void BecomeNonSolid(void)
Definition: Moveable.cpp:405
void ReadVec3(idVec3 &vec)
Definition: SaveGame.cpp:1011
class idUserInterface * gui[MAX_RENDERENTITY_GUI]
Definition: RenderWorld.h:130
const char * c_str(void) const
Definition: Str.h:487
virtual void Damage(idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location)
Definition: Moveable.cpp:1227
idMat3 additionalAxis
Definition: Moveable.h:136
void Spawn(void)
Definition: Moveable.cpp:778
void RestorePhysics(idPhysics *phys)
Definition: Entity.cpp:2596
const idEventDef EV_IsAtRest("isAtRest", NULL, 'd')
idCurve_Spline< idVec3 > * initialSpline
Definition: Moveable.h:83
bool unbindOnDeath
Definition: Moveable.h:86
void BecomeActive(int flags)
Definition: Entity.cpp:995
void MakeUniform(const float totalTime)
Definition: Curve.h:319
idMat3 lastAxis
Definition: Moveable.h:134
const idEventDef EV_Remove("<immediateremove>", NULL)
virtual int GetContents(int id=-1) const =0
const int USERCMD_HZ
Definition: UsercmdGen.h:40
virtual void Think(void)
Definition: Moveable.cpp:752
int realClientTime
Definition: Game_local.h:332
virtual idRenderModel * CheckModel(const char *modelName)=0
void SetGravity(const idVec3 &newGravity)
void Event_EnableDamage(float enable)
Definition: Moveable.cpp:611
renderLight_t light
Definition: Moveable.h:197
idRenderWorld * gameRenderWorld
Definition: Game_local.cpp:55
int GetNumValues(void) const
Definition: Curve.h:56
static float ACos(float a)
Definition: Math.h:544
static idEntityFx * StartFx(const char *fx, const idVec3 *useOrigin, const idMat3 *useAxis, idEntity *ent, bool bind)
Definition: Fx.cpp:716
void AddParticles(const char *name, bool burn)
Definition: Moveable.cpp:1036
bool PostEventMS(const idEventDef *ev, int time)
Definition: Class.cpp:666
void AddLight(const char *name, bool burn)
Definition: Moveable.cpp:1078
const idMaterial * shader
Definition: RenderWorld.h:200
int thinkFlags
Definition: Entity.h:125
void EnableDamage(bool enable, float duration)
Definition: Moveable.cpp:416
virtual void ReadFromSnapshot(const idBitMsgDelta &msg)
Definition: Moveable.cpp:1326
void Restore(idRestoreGame *savefile)
Definition: Moveable.cpp:666
void SetBouncyness(const float b)
virtual bool ClientReceiveEvent(int event, int time, const idBitMsg &msg)
Definition: Moveable.cpp:1341
float shaderParms[MAX_ENTITY_SHADER_PARMS]
Definition: RenderWorld.h:127
virtual void Hide(void)
Definition: Moveable.cpp:261
void ReadString(idStr &string)
Definition: SaveGame.cpp:985
void BecomeInactive(int flags)
Definition: Entity.cpp:1025
void WriteRenderLight(const renderLight_t &renderLight)
Definition: SaveGame.cpp:555
static void ReturnInt(int value)
void ReadInt(int &value)
Definition: SaveGame.cpp:922
float CRandomFloat(void)
Definition: Random.h:86
const idMat3 & GetAxis(int id=0) const
idClipModel * GetClipModel(int id=0) const
idCollisionModelManager * collisionModelManager
void ActivateTargets(idEntity *activator) const
Definition: Entity.cpp:3650
#define MS2SEC(t)
Definition: Math.h:60
void ReadObject(idClass *&obj)
Definition: SaveGame.cpp:1083
void SetOrigin(const idVec3 &newOrigin, int id=-1)
const idEventDef EV_BecomeNonSolid("becomeNonSolid")
virtual void Show(void)
Definition: Moveable.cpp:271
void SetMass(float mass, int id=-1)
virtual int NumSurfaces() const =0