doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
AFEntity.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 
38  idMultiModelAF
39 
40 ===============================================================================
41 */
42 
45 
46 /*
47 ================
48 idMultiModelAF::Spawn
49 ================
50 */
51 void idMultiModelAF::Spawn( void ) {
52  physicsObj.SetSelf( this );
53 }
54 
55 /*
56 ================
57 idMultiModelAF::~idMultiModelAF
58 ================
59 */
61  int i;
62 
63  for ( i = 0; i < modelDefHandles.Num(); i++ ) {
64  if ( modelDefHandles[i] != -1 ) {
66  modelDefHandles[i] = -1;
67  }
68  }
69 }
70 
71 /*
72 ================
73 idMultiModelAF::SetModelForId
74 ================
75 */
76 void idMultiModelAF::SetModelForId( int id, const idStr &modelName ) {
77  modelHandles.AssureSize( id+1, NULL );
78  modelDefHandles.AssureSize( id+1, -1 );
80 }
81 
82 /*
83 ================
84 idMultiModelAF::Present
85 ================
86 */
88  int i;
89 
90  // don't present to the renderer if the entity hasn't changed
91  if ( !( thinkFlags & TH_UPDATEVISUALS ) ) {
92  return;
93  }
94  BecomeInactive( TH_UPDATEVISUALS );
95 
96  for ( i = 0; i < modelHandles.Num(); i++ ) {
97 
98  if ( !modelHandles[i] ) {
99  continue;
100  }
101 
106 
107  // add to refresh list
108  if ( modelDefHandles[i] == -1 ) {
110  } else {
112  }
113  }
114 }
115 
116 /*
117 ================
118 idMultiModelAF::Think
119 ================
120 */
121 void idMultiModelAF::Think( void ) {
122  RunPhysics();
123  Present();
124 }
125 
126 
127 /*
128 ===============================================================================
129 
130  idChain
131 
132 ===============================================================================
133 */
134 
136 END_CLASS
137 
138 /*
139 ================
140 idChain::BuildChain
141 
142  builds a chain hanging down from the ceiling
143  the highest link is a child of the link below it etc.
144  this allows an object to be attached to multiple chains while keeping a single tree structure
145 ================
146 */
147 void idChain::BuildChain( const idStr &name, const idVec3 &origin, float linkLength, float linkWidth, float density, int numLinks, bool bindToWorld ) {
148  int i;
149  float halfLinkLength = linkLength * 0.5f;
150  idTraceModel trm;
151  idClipModel *clip;
152  idAFBody *body, *lastBody;
155  idVec3 org;
156 
157  // create a trace model
158  trm = idTraceModel( linkLength, linkWidth );
159  trm.Translate( -trm.offset );
160 
161  org = origin - idVec3( 0, 0, halfLinkLength );
162 
163  lastBody = NULL;
164  for ( i = 0; i < numLinks; i++ ) {
165 
166  // add body
167  clip = new idClipModel( trm );
168  clip->SetContents( CONTENTS_SOLID );
169  clip->Link( gameLocal.clip, this, 0, org, mat3_identity );
170  body = new idAFBody( name + idStr(i), clip, density );
171  physicsObj.AddBody( body );
172 
173  // visual model for body
174  SetModelForId( physicsObj.GetBodyId( body ), spawnArgs.GetString( "model" ) );
175 
176  // add constraint
177  if ( bindToWorld ) {
178  if ( !lastBody ) {
179  uj = new idAFConstraint_UniversalJoint( name + idStr(i), body, lastBody );
180  uj->SetShafts( idVec3( 0, 0, -1 ), idVec3( 0, 0, 1 ) );
181  //uj->SetConeLimit( idVec3( 0, 0, -1 ), 30.0f );
182  //uj->SetPyramidLimit( idVec3( 0, 0, -1 ), idVec3( 1, 0, 0 ), 90.0f, 30.0f );
183  }
184  else {
185  uj = new idAFConstraint_UniversalJoint( name + idStr(i), lastBody, body );
186  uj->SetShafts( idVec3( 0, 0, 1 ), idVec3( 0, 0, -1 ) );
187  //uj->SetConeLimit( idVec3( 0, 0, 1 ), 30.0f );
188  }
189  uj->SetAnchor( org + idVec3( 0, 0, halfLinkLength ) );
190  uj->SetFriction( 0.9f );
191  physicsObj.AddConstraint( uj );
192  }
193  else {
194  if ( lastBody ) {
195  bsj = new idAFConstraint_BallAndSocketJoint( "joint" + idStr(i), lastBody, body );
196  bsj->SetAnchor( org + idVec3( 0, 0, halfLinkLength ) );
197  bsj->SetConeLimit( idVec3( 0, 0, 1 ), 60.0f, idVec3( 0, 0, 1 ) );
198  physicsObj.AddConstraint( bsj );
199  }
200  }
201 
202  org[2] -= linkLength;
203 
204  lastBody = body;
205  }
206 }
207 
208 /*
209 ================
210 idChain::Spawn
211 ================
212 */
213 void idChain::Spawn( void ) {
214  int numLinks;
215  float length, linkLength, linkWidth, density;
216  bool drop;
217  idVec3 origin;
218 
219  spawnArgs.GetBool( "drop", "0", drop );
220  spawnArgs.GetInt( "links", "3", numLinks );
221  spawnArgs.GetFloat( "length", idStr( numLinks * 32.0f ), length );
222  spawnArgs.GetFloat( "width", "8", linkWidth );
223  spawnArgs.GetFloat( "density", "0.2", density );
224  linkLength = length / numLinks;
225  origin = GetPhysics()->GetOrigin();
226 
227  // initialize physics
228  physicsObj.SetSelf( this );
232 
233  BuildChain( "link", origin, linkLength, linkWidth, density, numLinks, !drop );
234 }
235 
236 /*
237 ===============================================================================
238 
239  idAFAttachment
240 
241 ===============================================================================
242 */
243 
245 END_CLASS
246 
247 /*
248 =====================
249 idAFAttachment::idAFAttachment
250 =====================
251 */
253  body = NULL;
254  combatModel = NULL;
255  idleAnim = 0;
256  attachJoint = INVALID_JOINT;
257 }
258 
259 /*
260 =====================
261 idAFAttachment::~idAFAttachment
262 =====================
263 */
265 
266  StopSound( SND_CHANNEL_ANY, false );
267 
268  delete combatModel;
269  combatModel = NULL;
270 }
271 
272 /*
273 =====================
274 idAFAttachment::Spawn
275 =====================
276 */
277 void idAFAttachment::Spawn( void ) {
278  idleAnim = animator.GetAnim( "idle" );
279 }
280 
281 /*
282 =====================
283 idAFAttachment::SetBody
284 =====================
285 */
286 void idAFAttachment::SetBody( idEntity *bodyEnt, const char *model, jointHandle_t attachJoint ) {
287  bool bleed;
288 
289  body = bodyEnt;
290  this->attachJoint = attachJoint;
291  SetModel( model );
292  fl.takedamage = true;
293 
294  bleed = body->spawnArgs.GetBool( "bleed" );
295  spawnArgs.SetBool( "bleed", bleed );
296 }
297 
298 /*
299 =====================
300 idAFAttachment::ClearBody
301 =====================
302 */
304  body = NULL;
306  Hide();
307 }
308 
309 /*
310 =====================
311 idAFAttachment::GetBody
312 =====================
313 */
315  return body;
316 }
317 
318 /*
319 ================
320 idAFAttachment::Save
321 
322 archive object for savegame file
323 ================
324 */
325 void idAFAttachment::Save( idSaveGame *savefile ) const {
326  savefile->WriteObject( body );
327  savefile->WriteInt( idleAnim );
328  savefile->WriteJoint( attachJoint );
329 }
330 
331 /*
332 ================
333 idAFAttachment::Restore
334 
335 unarchives object from save game file
336 ================
337 */
339  savefile->ReadObject( reinterpret_cast<idClass *&>( body ) );
340  savefile->ReadInt( idleAnim );
341  savefile->ReadJoint( attachJoint );
342 
343  SetCombatModel();
344  LinkCombat();
345 }
346 
347 /*
348 ================
349 idAFAttachment::Hide
350 ================
351 */
352 void idAFAttachment::Hide( void ) {
353  idEntity::Hide();
354  UnlinkCombat();
355 }
356 
357 /*
358 ================
359 idAFAttachment::Show
360 ================
361 */
362 void idAFAttachment::Show( void ) {
363  idEntity::Show();
364  LinkCombat();
365 }
366 
367 /*
368 ============
369 idAFAttachment::Damage
370 
371 Pass damage to body at the bindjoint
372 ============
373 */
374 void idAFAttachment::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir,
375  const char *damageDefName, const float damageScale, const int location ) {
376 
377  if ( body ) {
378  body->Damage( inflictor, attacker, dir, damageDefName, damageScale, attachJoint );
379  }
380 }
381 
382 /*
383 ================
384 idAFAttachment::AddDamageEffect
385 ================
386 */
387 void idAFAttachment::AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName ) {
388  if ( body ) {
389  trace_t c = collision;
391  body->AddDamageEffect( c, velocity, damageDefName );
392  }
393 }
394 
395 /*
396 ================
397 idAFAttachment::GetImpactInfo
398 ================
399 */
400 void idAFAttachment::GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info ) {
401  if ( body ) {
403  } else {
404  idEntity::GetImpactInfo( ent, id, point, info );
405  }
406 }
407 
408 /*
409 ================
410 idAFAttachment::ApplyImpulse
411 ================
412 */
413 void idAFAttachment::ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ) {
414  if ( body ) {
415  body->ApplyImpulse( ent, JOINT_HANDLE_TO_CLIPMODEL_ID( attachJoint ), point, impulse );
416  } else {
417  idEntity::ApplyImpulse( ent, id, point, impulse );
418  }
419 }
420 
421 /*
422 ================
423 idAFAttachment::AddForce
424 ================
425 */
426 void idAFAttachment::AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ) {
427  if ( body ) {
428  body->AddForce( ent, JOINT_HANDLE_TO_CLIPMODEL_ID( attachJoint ), point, force );
429  } else {
430  idEntity::AddForce( ent, id, point, force );
431  }
432 }
433 
434 /*
435 ================
436 idAFAttachment::PlayIdleAnim
437 ================
438 */
439 void idAFAttachment::PlayIdleAnim( int blendTime ) {
442  }
443 }
444 
445 /*
446 ================
447 idAfAttachment::Think
448 ================
449 */
450 void idAFAttachment::Think( void ) {
452  if ( thinkFlags & TH_UPDATEPARTICLES ) {
454  }
455 }
456 
457 /*
458 ================
459 idAFAttachment::SetCombatModel
460 ================
461 */
463  if ( combatModel ) {
464  combatModel->Unlink();
466  } else {
468  }
470 }
471 
472 /*
473 ================
474 idAFAttachment::GetCombatModel
475 ================
476 */
478  return combatModel;
479 }
480 
481 /*
482 ================
483 idAFAttachment::LinkCombat
484 ================
485 */
487  if ( fl.hidden ) {
488  return;
489  }
490 
491  if ( combatModel ) {
493  }
494 }
495 
496 /*
497 ================
498 idAFAttachment::UnlinkCombat
499 ================
500 */
502  if ( combatModel ) {
503  combatModel->Unlink();
504  }
505 }
506 
507 
508 /*
509 ===============================================================================
510 
511  idAFEntity_Base
512 
513 ===============================================================================
514 */
515 
516 const idEventDef EV_SetConstraintPosition( "SetConstraintPosition", "sv" );
517 
519  EVENT( EV_SetConstraintPosition, idAFEntity_Base::Event_SetConstraintPosition )
520 END_CLASS
521 
522 static const float BOUNCE_SOUND_MIN_VELOCITY = 80.0f;
523 static const float BOUNCE_SOUND_MAX_VELOCITY = 200.0f;
524 
525 /*
526 ================
527 idAFEntity_Base::idAFEntity_Base
528 ================
529 */
531  combatModel = NULL;
532  combatModelContents = 0;
533  nextSoundTime = 0;
534  spawnOrigin.Zero();
535  spawnAxis.Identity();
536 }
537 
538 /*
539 ================
540 idAFEntity_Base::~idAFEntity_Base
541 ================
542 */
544  delete combatModel;
545  combatModel = NULL;
546 }
547 
548 /*
549 ================
550 idAFEntity_Base::Save
551 ================
552 */
553 void idAFEntity_Base::Save( idSaveGame *savefile ) const {
554  savefile->WriteInt( combatModelContents );
555  savefile->WriteClipModel( combatModel );
556  savefile->WriteVec3( spawnOrigin );
557  savefile->WriteMat3( spawnAxis );
558  savefile->WriteInt( nextSoundTime );
559  af.Save( savefile );
560 }
561 
562 /*
563 ================
564 idAFEntity_Base::Restore
565 ================
566 */
568  savefile->ReadInt( combatModelContents );
569  savefile->ReadClipModel( combatModel );
570  savefile->ReadVec3( spawnOrigin );
571  savefile->ReadMat3( spawnAxis );
572  savefile->ReadInt( nextSoundTime );
573  LinkCombat();
574 
575  af.Restore( savefile );
576 }
577 
578 /*
579 ================
580 idAFEntity_Base::Spawn
581 ================
582 */
586  nextSoundTime = 0;
587 }
588 
589 /*
590 ================
591 idAFEntity_Base::LoadAF
592 ================
593 */
595  idStr fileName;
596 
597  if ( !spawnArgs.GetString( "articulatedFigure", "*unknown*", fileName ) ) {
598  return false;
599  }
600 
602  if ( !af.Load( this, fileName ) ) {
603  gameLocal.Error( "idAFEntity_Base::LoadAF: Couldn't load af file '%s' on entity '%s'", fileName.c_str(), name.c_str() );
604  }
605 
606  af.Start();
607 
610 
611  LoadState( spawnArgs );
612 
615  UpdateVisuals();
616 
617  return true;
618 }
619 
620 /*
621 ================
622 idAFEntity_Base::Think
623 ================
624 */
626  RunPhysics();
627  UpdateAnimation();
628  if ( thinkFlags & TH_UPDATEVISUALS ) {
629  Present();
630  LinkCombat();
631  }
632 }
633 
634 /*
635 ================
636 idAFEntity_Base::BodyForClipModelId
637 ================
638 */
640  return af.BodyForClipModelId( id );
641 }
642 
643 /*
644 ================
645 idAFEntity_Base::SaveState
646 ================
647 */
648 void idAFEntity_Base::SaveState( idDict &args ) const {
649  const idKeyValue *kv;
650 
651  // save the ragdoll pose
652  af.SaveState( args );
653 
654  // save all the bind constraints
655  kv = spawnArgs.MatchPrefix( "bindConstraint ", NULL );
656  while ( kv ) {
657  args.Set( kv->GetKey(), kv->GetValue() );
658  kv = spawnArgs.MatchPrefix( "bindConstraint ", kv );
659  }
660 
661  // save the bind if it exists
662  kv = spawnArgs.FindKey( "bind" );
663  if ( kv ) {
664  args.Set( kv->GetKey(), kv->GetValue() );
665  }
666  kv = spawnArgs.FindKey( "bindToJoint" );
667  if ( kv ) {
668  args.Set( kv->GetKey(), kv->GetValue() );
669  }
670  kv = spawnArgs.FindKey( "bindToBody" );
671  if ( kv ) {
672  args.Set( kv->GetKey(), kv->GetValue() );
673  }
674 }
675 
676 /*
677 ================
678 idAFEntity_Base::LoadState
679 ================
680 */
681 void idAFEntity_Base::LoadState( const idDict &args ) {
682  af.LoadState( args );
683 }
684 
685 /*
686 ================
687 idAFEntity_Base::AddBindConstraints
688 ================
689 */
692 }
693 
694 /*
695 ================
696 idAFEntity_Base::RemoveBindConstraints
697 ================
698 */
701 }
702 
703 /*
704 ================
705 idAFEntity_Base::GetImpactInfo
706 ================
707 */
708 void idAFEntity_Base::GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info ) {
709  if ( af.IsActive() ) {
710  af.GetImpactInfo( ent, id, point, info );
711  } else {
712  idEntity::GetImpactInfo( ent, id, point, info );
713  }
714 }
715 
716 /*
717 ================
718 idAFEntity_Base::ApplyImpulse
719 ================
720 */
721 void idAFEntity_Base::ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ) {
722  if ( af.IsLoaded() ) {
723  af.ApplyImpulse( ent, id, point, impulse );
724  }
725  if ( !af.IsActive() ) {
726  idEntity::ApplyImpulse( ent, id, point, impulse );
727  }
728 }
729 
730 /*
731 ================
732 idAFEntity_Base::AddForce
733 ================
734 */
735 void idAFEntity_Base::AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force ) {
736  if ( af.IsLoaded() ) {
737  af.AddForce( ent, id, point, force );
738  }
739  if ( !af.IsActive() ) {
740  idEntity::AddForce( ent, id, point, force );
741  }
742 }
743 
744 /*
745 ================
746 idAFEntity_Base::Collide
747 ================
748 */
749 bool idAFEntity_Base::Collide( const trace_t &collision, const idVec3 &velocity ) {
750  float v, f;
751 
752  if ( af.IsActive() ) {
753  v = -( velocity * collision.c.normal );
754  if ( v > BOUNCE_SOUND_MIN_VELOCITY && gameLocal.time > nextSoundTime ) {
755  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 ) );
756  if ( StartSound( "snd_bounce", SND_CHANNEL_ANY, 0, false, NULL ) ) {
757  // don't set the volume unless there is a bounce sound as it overrides the entire channel
758  // which causes footsteps on ai's to not honor their shader parms
759  SetSoundVolume( f );
760  }
761  nextSoundTime = gameLocal.time + 500;
762  }
763  }
764 
765  return false;
766 }
767 
768 /*
769 ================
770 idAFEntity_Base::GetPhysicsToVisualTransform
771 ================
772 */
774  if ( af.IsActive() ) {
775  af.GetPhysicsToVisualTransform( origin, axis );
776  return true;
777  }
778  return idEntity::GetPhysicsToVisualTransform( origin, axis );
779 }
780 
781 /*
782 ================
783 idAFEntity_Base::UpdateAnimationControllers
784 ================
785 */
787  if ( af.IsActive() ) {
788  if ( af.UpdateAnimation() ) {
789  return true;
790  }
791  }
792  return false;
793 }
794 
795 /*
796 ================
797 idAFEntity_Base::SetCombatModel
798 ================
799 */
801  if ( combatModel ) {
802  combatModel->Unlink();
804  } else {
806  }
807 }
808 
809 /*
810 ================
811 idAFEntity_Base::GetCombatModel
812 ================
813 */
815  return combatModel;
816 }
817 
818 /*
819 ================
820 idAFEntity_Base::SetCombatContents
821 ================
822 */
824  assert( combatModel );
825  if ( enable && combatModelContents ) {
829  } else if ( !enable && combatModel->GetContents() ) {
832  combatModel->SetContents( 0 );
833  }
834 }
835 
836 /*
837 ================
838 idAFEntity_Base::LinkCombat
839 ================
840 */
842  if ( fl.hidden ) {
843  return;
844  }
845  if ( combatModel ) {
847  }
848 }
849 
850 /*
851 ================
852 idAFEntity_Base::UnlinkCombat
853 ================
854 */
856  if ( combatModel ) {
857  combatModel->Unlink();
858  }
859 }
860 
861 /*
862 ================
863 idAFEntity_Base::FreeModelDef
864 ================
865 */
867  UnlinkCombat();
869 }
870 
871 /*
872 ===============
873 idAFEntity_Base::ShowEditingDialog
874 ===============
875 */
878 }
879 
880 /*
881 ================
882 idAFEntity_Base::DropAFs
883 
884  The entity should have the following key/value pairs set:
885  "def_drop<type>AF" "af def"
886  "drop<type>Skin" "skin name"
887  To drop multiple articulated figures the following key/value pairs can be used:
888  "def_drop<type>AF*" "af def"
889  where * is an aribtrary string.
890 ================
891 */
892 void idAFEntity_Base::DropAFs( idEntity *ent, const char *type, idList<idEntity *> *list ) {
893  const idKeyValue *kv;
894  const char *skinName;
895  idEntity *newEnt;
897  idDict args;
898  const idDeclSkin *skin;
899 
900  // drop the articulated figures
901  kv = ent->spawnArgs.MatchPrefix( va( "def_drop%sAF", type ), NULL );
902  while ( kv ) {
903 
904  args.Set( "classname", kv->GetValue() );
905  gameLocal.SpawnEntityDef( args, &newEnt );
906 
907  if ( newEnt && newEnt->IsType( idAFEntity_Base::Type ) ) {
908  af = static_cast<idAFEntity_Base *>(newEnt);
909  af->GetPhysics()->SetOrigin( ent->GetPhysics()->GetOrigin() );
910  af->GetPhysics()->SetAxis( ent->GetPhysics()->GetAxis() );
911  af->af.SetupPose( ent, gameLocal.time );
912  if ( list ) {
913  list->Append( af );
914  }
915  }
916 
917  kv = ent->spawnArgs.MatchPrefix( va( "def_drop%sAF", type ), kv );
918  }
919 
920  // change the skin to hide all the dropped articulated figures
921  skinName = ent->spawnArgs.GetString( va( "skin_drop%s", type ) );
922  if ( skinName[0] ) {
923  skin = declManager->FindSkin( skinName );
924  ent->SetSkin( skin );
925  }
926 }
927 
928 /*
929 ================
930 idAFEntity_Base::Event_SetConstraintPosition
931 ================
932 */
934  af.SetConstraintPosition( name, pos );
935 }
936 
937 /*
938 ===============================================================================
939 
940 idAFEntity_Gibbable
941 
942 ===============================================================================
943 */
944 
945 const idEventDef EV_Gib( "gib", "s" );
946 const idEventDef EV_Gibbed( "<gibbed>" );
947 
949  EVENT( EV_Gib, idAFEntity_Gibbable::Event_Gib )
950  EVENT( EV_Gibbed, idAFEntity_Base::Event_Remove )
951 END_CLASS
952 
953 
954 /*
955 ================
956 idAFEntity_Gibbable::idAFEntity_Gibbable
957 ================
958 */
960  skeletonModel = NULL;
961  skeletonModelDefHandle = -1;
962  gibbed = false;
963 #ifdef _D3XP
964  wasThrown = false;
965 #endif
966 }
967 
968 /*
969 ================
970 idAFEntity_Gibbable::~idAFEntity_Gibbable
971 ================
972 */
974  if ( skeletonModelDefHandle != -1 ) {
977  }
978 }
979 
980 /*
981 ================
982 idAFEntity_Gibbable::Save
983 ================
984 */
985 void idAFEntity_Gibbable::Save( idSaveGame *savefile ) const {
986  savefile->WriteBool( gibbed );
987  savefile->WriteBool( combatModel != NULL );
988 #ifdef _D3XP
989  savefile->WriteBool( wasThrown );
990 #endif
991 }
992 
993 /*
994 ================
995 idAFEntity_Gibbable::Restore
996 ================
997 */
999  bool hasCombatModel;
1000 
1001  savefile->ReadBool( gibbed );
1002  savefile->ReadBool( hasCombatModel );
1003 #ifdef _D3XP
1004  savefile->ReadBool( wasThrown );
1005 #endif
1006 
1008 
1009  if ( hasCombatModel ) {
1010  SetCombatModel();
1011  LinkCombat();
1012  }
1013 }
1014 
1015 /*
1016 ================
1017 idAFEntity_Gibbable::Spawn
1018 ================
1019 */
1022 
1023  gibbed = false;
1024 #ifdef _D3XP
1025  wasThrown = false;
1026 #endif
1027 }
1028 
1029 /*
1030 ================
1031 idAFEntity_Gibbable::InitSkeletonModel
1032 ================
1033 */
1035  const char *modelName;
1036  const idDeclModelDef *modelDef;
1037 
1038  skeletonModel = NULL;
1040 
1041  modelName = spawnArgs.GetString( "model_gib" );
1042 
1043  modelDef = NULL;
1044  if ( modelName[0] != '\0' ) {
1045  modelDef = static_cast<const idDeclModelDef *>( declManager->FindType( DECL_MODELDEF, modelName, false ) );
1046  if ( modelDef ) {
1047  skeletonModel = modelDef->ModelHandle();
1048  } else {
1049  skeletonModel = renderModelManager->FindModel( modelName );
1050  }
1051  if ( skeletonModel != NULL && renderEntity.hModel != NULL ) {
1053  gameLocal.Error( "gib model '%s' has different number of joints than model '%s'",
1055  }
1056  }
1057  }
1058 }
1059 
1060 /*
1061 ================
1062 idAFEntity_Gibbable::Present
1063 ================
1064 */
1066  renderEntity_t skeleton;
1067 
1068  if ( !gameLocal.isNewFrame ) {
1069  return;
1070  }
1071 
1072  // don't present to the renderer if the entity hasn't changed
1073  if ( !( thinkFlags & TH_UPDATEVISUALS ) ) {
1074  return;
1075  }
1076 
1077  // update skeleton model
1078  if ( gibbed && !IsHidden() && skeletonModel != NULL ) {
1079  skeleton = renderEntity;
1080  skeleton.hModel = skeletonModel;
1081  // add to refresh list
1082  if ( skeletonModelDefHandle == -1 ) {
1084  } else {
1086  }
1087  }
1088 
1090 }
1091 
1092 /*
1093 ================
1094 idAFEntity_Gibbable::Damage
1095 ================
1096 */
1097 void idAFEntity_Gibbable::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location ) {
1098  if ( !fl.takedamage ) {
1099  return;
1100  }
1101  idAFEntity_Base::Damage( inflictor, attacker, dir, damageDefName, damageScale, location );
1102  if ( health < -20 && spawnArgs.GetBool( "gib" ) ) {
1103  Gib( dir, damageDefName );
1104  }
1105 }
1106 
1107 #ifdef _D3XP
1108 /*
1109 =====================
1110 idAFEntity_Gibbable::SetThrown
1111 =====================
1112 */
1113 void idAFEntity_Gibbable::SetThrown( bool isThrown ) {
1114 
1115  if ( isThrown ) {
1116  int i, num = af.GetPhysics()->GetNumBodies();
1117 
1118  for ( i=0; i<num; i++ ) {
1119  idAFBody *body;
1120 
1121  body = af.GetPhysics()->GetBody( i );
1122  body->SetClipMask( MASK_MONSTERSOLID );
1123  }
1124  }
1125 
1126  wasThrown = isThrown;
1127 }
1128 
1129 /*
1130 =====================
1131 idAFEntity_Gibbable::Collide
1132 =====================
1133 */
1134 bool idAFEntity_Gibbable::Collide( const trace_t &collision, const idVec3 &velocity ) {
1135 
1136  if ( !gibbed && wasThrown ) {
1137 
1138  // Everything gibs (if possible)
1139  if ( spawnArgs.GetBool( "gib" ) ) {
1140  idEntity *ent;
1141 
1142  ent = gameLocal.entities[ collision.c.entityNum ];
1143  if ( ent->fl.takedamage ) {
1144  ent->Damage( this, gameLocal.GetLocalPlayer(), collision.c.normal, "damage_thrown_ragdoll", 1.f, CLIPMODEL_ID_TO_JOINT_HANDLE( collision.c.id ) );
1145  }
1146 
1147  idVec3 vel = velocity;
1148  vel.NormalizeFast();
1149  Gib( vel, "damage_gib" );
1150  }
1151  }
1152 
1153  return idAFEntity_Base::Collide( collision, velocity );
1154 }
1155 #endif
1156 
1157 /*
1158 =====================
1159 idAFEntity_Gibbable::SpawnGibs
1160 =====================
1161 */
1162 void idAFEntity_Gibbable::SpawnGibs( const idVec3 &dir, const char *damageDefName ) {
1163  int i;
1164  bool gibNonSolid;
1165  idVec3 entityCenter, velocity;
1166  idList<idEntity *> list;
1167 
1169 
1170  const idDict *damageDef = gameLocal.FindEntityDefDict( damageDefName );
1171  if ( !damageDef ) {
1172  gameLocal.Error( "Unknown damageDef '%s'", damageDefName );
1173  }
1174 
1175  // spawn gib articulated figures
1176  idAFEntity_Base::DropAFs( this, "gib", &list );
1177 
1178  // spawn gib items
1179  idMoveableItem::DropItems( this, "gib", &list );
1180 
1181  // blow out the gibs in the given direction away from the center of the entity
1182  entityCenter = GetPhysics()->GetAbsBounds().GetCenter();
1183  gibNonSolid = damageDef->GetBool( "gibNonSolid" );
1184  for ( i = 0; i < list.Num(); i++ ) {
1185  if ( gibNonSolid ) {
1186  list[i]->GetPhysics()->SetContents( 0 );
1187  list[i]->GetPhysics()->SetClipMask( 0 );
1188  list[i]->GetPhysics()->UnlinkClip();
1189  list[i]->GetPhysics()->PutToRest();
1190  } else {
1191 #ifdef _D3XP
1192  list[i]->GetPhysics()->SetContents( 0 );
1193 #else
1194  list[i]->GetPhysics()->SetContents( CONTENTS_CORPSE );
1195 #endif
1196  list[i]->GetPhysics()->SetClipMask( CONTENTS_SOLID );
1197  velocity = list[i]->GetPhysics()->GetAbsBounds().GetCenter() - entityCenter;
1198  velocity.NormalizeFast();
1199  velocity += ( i & 1 ) ? dir : -dir;
1200  list[i]->GetPhysics()->SetLinearVelocity( velocity * 75.0f );
1201  }
1202 #ifdef _D3XP
1203  // Don't allow grabber to pick up temporary gibs
1204  list[i]->noGrab = true;
1205 #endif
1206  list[i]->GetRenderEntity()->noShadow = true;
1207  list[i]->GetRenderEntity()->shaderParms[ SHADERPARM_TIME_OF_DEATH ] = gameLocal.time * 0.001f;
1208  list[i]->PostEventSec( &EV_Remove, 4.0f );
1209  }
1210 }
1211 
1212 /*
1213 ============
1214 idAFEntity_Gibbable::Gib
1215 ============
1216 */
1217 void idAFEntity_Gibbable::Gib( const idVec3 &dir, const char *damageDefName ) {
1218  // only gib once
1219  if ( gibbed ) {
1220  return;
1221  }
1222 
1223 #ifdef _D3XP
1224  // Don't grab this ent after it's been gibbed (and now invisible!)
1225  noGrab = true;
1226 #endif
1227 
1228  const idDict *damageDef = gameLocal.FindEntityDefDict( damageDefName );
1229  if ( !damageDef ) {
1230  gameLocal.Error( "Unknown damageDef '%s'", damageDefName );
1231  }
1232 
1233  if ( damageDef->GetBool( "gibNonSolid" ) ) {
1234  GetAFPhysics()->SetContents( 0 );
1235  GetAFPhysics()->SetClipMask( 0 );
1236  GetAFPhysics()->UnlinkClip();
1237  GetAFPhysics()->PutToRest();
1238  } else {
1241  }
1242 
1243  UnlinkCombat();
1244 
1245  if ( g_bloodEffects.GetBool() ) {
1246  if ( gameLocal.time > gameLocal.GetGibTime() ) {
1248  SpawnGibs( dir, damageDefName );
1249  renderEntity.noShadow = true;
1251  StartSound( "snd_gibbed", SND_CHANNEL_ANY, 0, false, NULL );
1252  gibbed = true;
1253  }
1254  } else {
1255  gibbed = true;
1256  }
1257 
1258 
1259  PostEventSec( &EV_Gibbed, 4.0f );
1260 }
1261 
1262 /*
1263 ============
1264 idAFEntity_Gibbable::Event_Gib
1265 ============
1266 */
1267 void idAFEntity_Gibbable::Event_Gib( const char *damageDefName ) {
1268  Gib( idVec3( 0, 0, 1 ), damageDefName );
1269 }
1270 
1271 /*
1272 ===============================================================================
1273 
1274  idAFEntity_Generic
1275 
1276 ===============================================================================
1277 */
1278 
1280  EVENT( EV_Activate, idAFEntity_Generic::Event_Activate )
1281 END_CLASS
1282 
1283 /*
1284 ================
1285 idAFEntity_Generic::idAFEntity_Generic
1286 ================
1287 */
1289  keepRunningPhysics = false;
1290 }
1291 
1292 /*
1293 ================
1294 idAFEntity_Generic::~idAFEntity_Generic
1295 ================
1296 */
1298 }
1299 
1300 /*
1301 ================
1302 idAFEntity_Generic::Save
1303 ================
1304 */
1305 void idAFEntity_Generic::Save( idSaveGame *savefile ) const {
1306  savefile->WriteBool( keepRunningPhysics );
1307 }
1308 
1309 /*
1310 ================
1311 idAFEntity_Generic::Restore
1312 ================
1313 */
1315  savefile->ReadBool( keepRunningPhysics );
1316 }
1317 
1318 /*
1319 ================
1320 idAFEntity_Generic::Think
1321 ================
1322 */
1325 
1326  if ( keepRunningPhysics ) {
1328  }
1329 }
1330 
1331 /*
1332 ================
1333 idAFEntity_Generic::Spawn
1334 ================
1335 */
1337  if ( !LoadAF() ) {
1338  gameLocal.Error( "Couldn't load af file on entity '%s'", name.c_str() );
1339  }
1340 
1341  SetCombatModel();
1342 
1343  SetPhysics( af.GetPhysics() );
1344 
1345  af.GetPhysics()->PutToRest();
1346  if ( !spawnArgs.GetBool( "nodrop", "0" ) ) {
1347  af.GetPhysics()->Activate();
1348  }
1349 
1350  fl.takedamage = true;
1351 }
1352 
1353 /*
1354 ================
1355 idAFEntity_Generic::Event_Activate
1356 ================
1357 */
1359  float delay;
1360  idVec3 init_velocity, init_avelocity;
1361 
1362  Show();
1363 
1364  af.GetPhysics()->EnableImpact();
1365  af.GetPhysics()->Activate();
1366 
1367  spawnArgs.GetVector( "init_velocity", "0 0 0", init_velocity );
1368  spawnArgs.GetVector( "init_avelocity", "0 0 0", init_avelocity );
1369 
1370  delay = spawnArgs.GetFloat( "init_velocityDelay", "0" );
1371  if ( delay == 0.0f ) {
1372  af.GetPhysics()->SetLinearVelocity( init_velocity );
1373  } else {
1374  PostEventSec( &EV_SetLinearVelocity, delay, init_velocity );
1375  }
1376 
1377  delay = spawnArgs.GetFloat( "init_avelocityDelay", "0" );
1378  if ( delay == 0.0f ) {
1379  af.GetPhysics()->SetAngularVelocity( init_avelocity );
1380  } else {
1381  PostEventSec( &EV_SetAngularVelocity, delay, init_avelocity );
1382  }
1383 }
1384 
1385 
1386 /*
1387 ===============================================================================
1388 
1389  idAFEntity_WithAttachedHead
1390 
1391 ===============================================================================
1392 */
1393 
1396  EVENT( EV_Activate, idAFEntity_WithAttachedHead::Event_Activate )
1397 END_CLASS
1398 
1399 /*
1400 ================
1401 idAFEntity_WithAttachedHead::idAFEntity_WithAttachedHead
1402 ================
1403 */
1405  head = NULL;
1406 }
1407 
1408 /*
1409 ================
1410 idAFEntity_WithAttachedHead::~idAFEntity_WithAttachedHead
1411 ================
1412 */
1414  if ( head.GetEntity() ) {
1415  head.GetEntity()->ClearBody();
1416  head.GetEntity()->PostEventMS( &EV_Remove, 0 );
1417  }
1418 }
1419 
1420 /*
1421 ================
1422 idAFEntity_WithAttachedHead::Spawn
1423 ================
1424 */
1426  SetupHead();
1427 
1428  LoadAF();
1429 
1430  SetCombatModel();
1431 
1432  SetPhysics( af.GetPhysics() );
1433 
1434  af.GetPhysics()->PutToRest();
1435  if ( !spawnArgs.GetBool( "nodrop", "0" ) ) {
1436  af.GetPhysics()->Activate();
1437  }
1438 
1439  fl.takedamage = true;
1440 
1441  if ( head.GetEntity() ) {
1442  int anim = head.GetEntity()->GetAnimator()->GetAnim( "dead" );
1443 
1444  if ( anim ) {
1446  }
1447  }
1448 }
1449 
1450 /*
1451 ================
1452 idAFEntity_WithAttachedHead::Save
1453 ================
1454 */
1456  head.Save( savefile );
1457 }
1458 
1459 /*
1460 ================
1461 idAFEntity_WithAttachedHead::Restore
1462 ================
1463 */
1465  head.Restore( savefile );
1466 }
1467 
1468 /*
1469 ================
1470 idAFEntity_WithAttachedHead::SetupHead
1471 ================
1472 */
1474  idAFAttachment *headEnt;
1475  idStr jointName;
1476  const char *headModel;
1477  jointHandle_t joint;
1478  idVec3 origin;
1479  idMat3 axis;
1480 
1481  headModel = spawnArgs.GetString( "def_head", "" );
1482  if ( headModel[ 0 ] ) {
1483  jointName = spawnArgs.GetString( "head_joint" );
1484  joint = animator.GetJointHandle( jointName );
1485  if ( joint == INVALID_JOINT ) {
1486  gameLocal.Error( "Joint '%s' not found for 'head_joint' on '%s'", jointName.c_str(), name.c_str() );
1487  }
1488 
1489  headEnt = static_cast<idAFAttachment *>( gameLocal.SpawnEntityType( idAFAttachment::Type, NULL ) );
1490  headEnt->SetName( va( "%s_head", name.c_str() ) );
1491  headEnt->SetBody( this, headModel, joint );
1492  headEnt->SetCombatModel();
1493  head = headEnt;
1494 
1495 #ifdef _D3XP
1496  idStr xSkin;
1497  if ( spawnArgs.GetString( "skin_head_xray", "", xSkin ) ) {
1498  headEnt->xraySkin = declManager->FindSkin( xSkin.c_str() );
1499  headEnt->UpdateModel();
1500  }
1501 #endif
1502  animator.GetJointTransform( joint, gameLocal.time, origin, axis );
1503  origin = renderEntity.origin + origin * renderEntity.axis;
1504  headEnt->SetOrigin( origin );
1505  headEnt->SetAxis( renderEntity.axis );
1506  headEnt->BindToJoint( this, joint, true );
1507  }
1508 }
1509 
1510 /*
1511 ================
1512 idAFEntity_WithAttachedHead::Think
1513 ================
1514 */
1517 }
1518 
1519 /*
1520 ================
1521 idAFEntity_WithAttachedHead::LinkCombat
1522 ================
1523 */
1525  idAFAttachment *headEnt;
1526 
1527  if ( fl.hidden ) {
1528  return;
1529  }
1530 
1531  if ( combatModel ) {
1533  }
1534  headEnt = head.GetEntity();
1535  if ( headEnt ) {
1536  headEnt->LinkCombat();
1537  }
1538 }
1539 
1540 /*
1541 ================
1542 idAFEntity_WithAttachedHead::UnlinkCombat
1543 ================
1544 */
1546  idAFAttachment *headEnt;
1547 
1548  if ( combatModel ) {
1549  combatModel->Unlink();
1550  }
1551  headEnt = head.GetEntity();
1552  if ( headEnt ) {
1553  headEnt->UnlinkCombat();
1554  }
1555 }
1556 
1557 /*
1558 ================
1559 idAFEntity_WithAttachedHead::Hide
1560 ================
1561 */
1564  if ( head.GetEntity() ) {
1565  head.GetEntity()->Hide();
1566  }
1567  UnlinkCombat();
1568 }
1569 
1570 /*
1571 ================
1572 idAFEntity_WithAttachedHead::Show
1573 ================
1574 */
1577  if ( head.GetEntity() ) {
1578  head.GetEntity()->Show();
1579  }
1580  LinkCombat();
1581 }
1582 
1583 /*
1584 ================
1585 idAFEntity_WithAttachedHead::ProjectOverlay
1586 ================
1587 */
1588 void idAFEntity_WithAttachedHead::ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material ) {
1589 
1590  idEntity::ProjectOverlay( origin, dir, size, material );
1591 
1592  if ( head.GetEntity() ) {
1593  head.GetEntity()->ProjectOverlay( origin, dir, size, material );
1594  }
1595 }
1596 
1597 /*
1598 ============
1599 idAFEntity_WithAttachedHead::Gib
1600 ============
1601 */
1602 void idAFEntity_WithAttachedHead::Gib( const idVec3 &dir, const char *damageDefName ) {
1603  // only gib once
1604  if ( gibbed ) {
1605  return;
1606  }
1607  idAFEntity_Gibbable::Gib( dir, damageDefName );
1608  if ( head.GetEntity() ) {
1609  head.GetEntity()->Hide();
1610  }
1611 }
1612 
1613 /*
1614 ============
1615 idAFEntity_WithAttachedHead::Event_Gib
1616 ============
1617 */
1618 void idAFEntity_WithAttachedHead::Event_Gib( const char *damageDefName ) {
1619  Gib( idVec3( 0, 0, 1 ), damageDefName );
1620 }
1621 
1622 /*
1623 ================
1624 idAFEntity_WithAttachedHead::Event_Activate
1625 ================
1626 */
1628  float delay;
1629  idVec3 init_velocity, init_avelocity;
1630 
1631  Show();
1632 
1633  af.GetPhysics()->EnableImpact();
1634  af.GetPhysics()->Activate();
1635 
1636  spawnArgs.GetVector( "init_velocity", "0 0 0", init_velocity );
1637  spawnArgs.GetVector( "init_avelocity", "0 0 0", init_avelocity );
1638 
1639  delay = spawnArgs.GetFloat( "init_velocityDelay", "0" );
1640  if ( delay == 0.0f ) {
1641  af.GetPhysics()->SetLinearVelocity( init_velocity );
1642  } else {
1643  PostEventSec( &EV_SetLinearVelocity, delay, init_velocity );
1644  }
1645 
1646  delay = spawnArgs.GetFloat( "init_avelocityDelay", "0" );
1647  if ( delay == 0.0f ) {
1648  af.GetPhysics()->SetAngularVelocity( init_avelocity );
1649  } else {
1650  PostEventSec( &EV_SetAngularVelocity, delay, init_avelocity );
1651  }
1652 }
1653 
1654 
1655 /*
1656 ===============================================================================
1657 
1658  idAFEntity_Vehicle
1659 
1660 ===============================================================================
1661 */
1662 
1664 END_CLASS
1665 
1666 /*
1667 ================
1668 idAFEntity_Vehicle::idAFEntity_Vehicle
1669 ================
1670 */
1672  player = NULL;
1673  eyesJoint = INVALID_JOINT;
1674  steeringWheelJoint = INVALID_JOINT;
1675  wheelRadius = 0.0f;
1676  steerAngle = 0.0f;
1677  steerSpeed = 0.0f;
1678  dustSmoke = NULL;
1679 }
1680 
1681 /*
1682 ================
1683 idAFEntity_Vehicle::Spawn
1684 ================
1685 */
1687  const char *eyesJointName = spawnArgs.GetString( "eyesJoint", "eyes" );
1688  const char *steeringWheelJointName = spawnArgs.GetString( "steeringWheelJoint", "steeringWheel" );
1689 
1690  LoadAF();
1691 
1692  SetCombatModel();
1693 
1694  SetPhysics( af.GetPhysics() );
1695 
1696  fl.takedamage = true;
1697 
1698  if ( !eyesJointName[0] ) {
1699  gameLocal.Error( "idAFEntity_Vehicle '%s' no eyes joint specified", name.c_str() );
1700  }
1701  eyesJoint = animator.GetJointHandle( eyesJointName );
1702  if ( !steeringWheelJointName[0] ) {
1703  gameLocal.Error( "idAFEntity_Vehicle '%s' no steering wheel joint specified", name.c_str() );
1704  }
1705  steeringWheelJoint = animator.GetJointHandle( steeringWheelJointName );
1706 
1707  spawnArgs.GetFloat( "wheelRadius", "20", wheelRadius );
1708  spawnArgs.GetFloat( "steerSpeed", "5", steerSpeed );
1709 
1710  player = NULL;
1711  steerAngle = 0.0f;
1712 
1713  const char *smokeName = spawnArgs.GetString( "smoke_vehicle_dust", "muzzlesmoke" );
1714  if ( *smokeName != '\0' ) {
1715  dustSmoke = static_cast<const idDeclParticle *>( declManager->FindType( DECL_PARTICLE, smokeName ) );
1716  }
1717 }
1718 
1719 /*
1720 ================
1721 idAFEntity_Vehicle::Use
1722 ================
1723 */
1725  idVec3 origin;
1726  idMat3 axis;
1727 
1728  if ( player ) {
1729  if ( player == other ) {
1730  other->Unbind();
1731  player = NULL;
1732 
1733  af.GetPhysics()->SetComeToRest( true );
1734  }
1735  }
1736  else {
1737  player = other;
1739  origin = renderEntity.origin + origin * renderEntity.axis;
1740  player->GetPhysics()->SetOrigin( origin );
1741  player->BindToBody( this, 0, true );
1742 
1743  af.GetPhysics()->SetComeToRest( false );
1744  af.GetPhysics()->Activate();
1745  }
1746 }
1747 
1748 /*
1749 ================
1750 idAFEntity_Vehicle::GetSteerAngle
1751 ================
1752 */
1754  float idealSteerAngle, angleDelta;
1755 
1756  idealSteerAngle = player->usercmd.rightmove * ( 30.0f / 128.0f );
1757  angleDelta = idealSteerAngle - steerAngle;
1758 
1759  if ( angleDelta > steerSpeed ) {
1760  steerAngle += steerSpeed;
1761  } else if ( angleDelta < -steerSpeed ) {
1762  steerAngle -= steerSpeed;
1763  } else {
1764  steerAngle = idealSteerAngle;
1765  }
1766 
1767  return steerAngle;
1768 }
1769 
1770 
1771 /*
1772 ===============================================================================
1773 
1774  idAFEntity_VehicleSimple
1775 
1776 ===============================================================================
1777 */
1778 
1780 END_CLASS
1781 
1782 /*
1783 ================
1784 idAFEntity_VehicleSimple::idAFEntity_VehicleSimple
1785 ================
1786 */
1788  int i;
1789  for ( i = 0; i < 4; i++ ) {
1790  suspension[i] = NULL;
1791  }
1792 }
1793 
1794 /*
1795 ================
1796 idAFEntity_VehicleSimple::~idAFEntity_VehicleSimple
1797 ================
1798 */
1800  delete wheelModel;
1801  wheelModel = NULL;
1802 }
1803 
1804 /*
1805 ================
1806 idAFEntity_VehicleSimple::Spawn
1807 ================
1808 */
1810  static const char *wheelJointKeys[] = {
1811  "wheelJointFrontLeft",
1812  "wheelJointFrontRight",
1813  "wheelJointRearLeft",
1814  "wheelJointRearRight"
1815  };
1816  static idVec3 wheelPoly[4] = { idVec3( 2, 2, 0 ), idVec3( 2, -2, 0 ), idVec3( -2, -2, 0 ), idVec3( -2, 2, 0 ) };
1817 
1818  int i;
1819  idVec3 origin;
1820  idMat3 axis;
1821  idTraceModel trm;
1822 
1823  trm.SetupPolygon( wheelPoly, 4 );
1824  trm.Translate( idVec3( 0, 0, -wheelRadius ) );
1825  wheelModel = new idClipModel( trm );
1826 
1827  for ( i = 0; i < 4; i++ ) {
1828  const char *wheelJointName = spawnArgs.GetString( wheelJointKeys[i], "" );
1829  if ( !wheelJointName[0] ) {
1830  gameLocal.Error( "idAFEntity_VehicleSimple '%s' no '%s' specified", name.c_str(), wheelJointKeys[i] );
1831  }
1832  wheelJoints[i] = animator.GetJointHandle( wheelJointName );
1833  if ( wheelJoints[i] == INVALID_JOINT ) {
1834  gameLocal.Error( "idAFEntity_VehicleSimple '%s' can't find wheel joint '%s'", name.c_str(), wheelJointName );
1835  }
1836 
1837  GetAnimator()->GetJointTransform( wheelJoints[i], 0, origin, axis );
1838  origin = renderEntity.origin + origin * renderEntity.axis;
1839 
1841  suspension[i]->Setup( va( "suspension%d", i ), af.GetPhysics()->GetBody( 0 ), origin, af.GetPhysics()->GetAxis( 0 ), wheelModel );
1847 
1849  }
1850 
1851  memset( wheelAngles, 0, sizeof( wheelAngles ) );
1853 }
1854 
1855 /*
1856 ================
1857 idAFEntity_VehicleSimple::Think
1858 ================
1859 */
1861  int i;
1862  float force = 0.0f, velocity = 0.0f, steerAngle = 0.0f;
1863  idVec3 origin;
1864  idMat3 axis;
1865  idRotation wheelRotation, steerRotation;
1866 
1867  if ( thinkFlags & TH_THINK ) {
1868 
1869  if ( player ) {
1870  // capture the input from a player
1871  velocity = g_vehicleVelocity.GetFloat();
1872  if ( player->usercmd.forwardmove < 0 ) {
1873  velocity = -velocity;
1874  }
1875  force = idMath::Fabs( player->usercmd.forwardmove * g_vehicleForce.GetFloat() ) * (1.0f / 128.0f);
1877  }
1878 
1879  // update the wheel motor force and steering
1880  for ( i = 0; i < 2; i++ ) {
1881 
1882  // front wheel drive
1883  if ( velocity != 0.0f ) {
1884  suspension[i]->EnableMotor( true );
1885  } else {
1886  suspension[i]->EnableMotor( false );
1887  }
1888  suspension[i]->SetMotorVelocity( velocity );
1889  suspension[i]->SetMotorForce( force );
1890 
1891  // update the wheel steering
1893  }
1894 
1895  // adjust wheel velocity for better steering because there are no differentials between the wheels
1896  if ( steerAngle < 0.0f ) {
1897  suspension[0]->SetMotorVelocity( velocity * 0.5f );
1898  } else if ( steerAngle > 0.0f ) {
1899  suspension[1]->SetMotorVelocity( velocity * 0.5f );
1900  }
1901 
1902  // update suspension with latest cvar settings
1903  for ( i = 0; i < 4; i++ ) {
1909  }
1910 
1911  // run the physics
1912  RunPhysics();
1913 
1914  // move and rotate the wheels visually
1915  for ( i = 0; i < 4; i++ ) {
1916  idAFBody *body = af.GetPhysics()->GetBody( 0 );
1917 
1918  origin = suspension[i]->GetWheelOrigin();
1919  velocity = body->GetPointVelocity( origin ) * body->GetWorldAxis()[0];
1920  wheelAngles[i] += velocity * MS2SEC( gameLocal.msec ) / wheelRadius;
1921 
1922  // additional rotation about the wheel axis
1923  wheelRotation.SetAngle( RAD2DEG( wheelAngles[i] ) );
1924  wheelRotation.SetVec( 0, -1, 0 );
1925 
1926  if ( i < 2 ) {
1927  // rotate the wheel for steering
1928  steerRotation.SetAngle( steerAngle );
1929  steerRotation.SetVec( 0, 0, 1 );
1930  // set wheel rotation
1931  animator.SetJointAxis( wheelJoints[i], JOINTMOD_WORLD, wheelRotation.ToMat3() * steerRotation.ToMat3() );
1932  } else {
1933  // set wheel rotation
1934  animator.SetJointAxis( wheelJoints[i], JOINTMOD_WORLD, wheelRotation.ToMat3() );
1935  }
1936 
1937  // set wheel position for suspension
1938  origin = ( origin - renderEntity.origin ) * renderEntity.axis.Transpose();
1940  }
1941 /*
1942  // spawn dust particle effects
1943  if ( force != 0.0f && !( gameLocal.framenum & 7 ) ) {
1944  int numContacts;
1945  idAFConstraint_Contact *contacts[2];
1946  for ( i = 0; i < 4; i++ ) {
1947  numContacts = af.GetPhysics()->GetBodyContactConstraints( wheels[i]->GetClipModel()->GetId(), contacts, 2 );
1948  for ( int j = 0; j < numContacts; j++ ) {
1949  gameLocal.smokeParticles->EmitSmoke( dustSmoke, gameLocal.time, gameLocal.random.RandomFloat(), contacts[j]->GetContact().point, contacts[j]->GetContact().normal.ToMat3() );
1950  }
1951  }
1952  }
1953 */
1954  }
1955 
1956  UpdateAnimation();
1957  if ( thinkFlags & TH_UPDATEVISUALS ) {
1958  Present();
1959  LinkCombat();
1960  }
1961 }
1962 
1963 
1964 /*
1965 ===============================================================================
1966 
1967  idAFEntity_VehicleFourWheels
1968 
1969 ===============================================================================
1970 */
1971 
1973 END_CLASS
1974 
1975 
1976 /*
1977 ================
1978 idAFEntity_VehicleFourWheels::idAFEntity_VehicleFourWheels
1979 ================
1980 */
1982  int i;
1983 
1984  for ( i = 0; i < 4; i++ ) {
1985  wheels[i] = NULL;
1986  wheelJoints[i] = INVALID_JOINT;
1987  wheelAngles[i] = 0.0f;
1988  }
1989  steering[0] = NULL;
1990  steering[1] = NULL;
1991 }
1992 
1993 /*
1994 ================
1995 idAFEntity_VehicleFourWheels::Spawn
1996 ================
1997 */
1999  int i;
2000  static const char *wheelBodyKeys[] = {
2001  "wheelBodyFrontLeft",
2002  "wheelBodyFrontRight",
2003  "wheelBodyRearLeft",
2004  "wheelBodyRearRight"
2005  };
2006  static const char *wheelJointKeys[] = {
2007  "wheelJointFrontLeft",
2008  "wheelJointFrontRight",
2009  "wheelJointRearLeft",
2010  "wheelJointRearRight"
2011  };
2012  static const char *steeringHingeKeys[] = {
2013  "steeringHingeFrontLeft",
2014  "steeringHingeFrontRight",
2015  };
2016 
2017  const char *wheelBodyName, *wheelJointName, *steeringHingeName;
2018 
2019  for ( i = 0; i < 4; i++ ) {
2020  wheelBodyName = spawnArgs.GetString( wheelBodyKeys[i], "" );
2021  if ( !wheelBodyName[0] ) {
2022  gameLocal.Error( "idAFEntity_VehicleFourWheels '%s' no '%s' specified", name.c_str(), wheelBodyKeys[i] );
2023  }
2024  wheels[i] = af.GetPhysics()->GetBody( wheelBodyName );
2025  if ( !wheels[i] ) {
2026  gameLocal.Error( "idAFEntity_VehicleFourWheels '%s' can't find wheel body '%s'", name.c_str(), wheelBodyName );
2027  }
2028  wheelJointName = spawnArgs.GetString( wheelJointKeys[i], "" );
2029  if ( !wheelJointName[0] ) {
2030  gameLocal.Error( "idAFEntity_VehicleFourWheels '%s' no '%s' specified", name.c_str(), wheelJointKeys[i] );
2031  }
2032  wheelJoints[i] = animator.GetJointHandle( wheelJointName );
2033  if ( wheelJoints[i] == INVALID_JOINT ) {
2034  gameLocal.Error( "idAFEntity_VehicleFourWheels '%s' can't find wheel joint '%s'", name.c_str(), wheelJointName );
2035  }
2036  }
2037 
2038  for ( i = 0; i < 2; i++ ) {
2039  steeringHingeName = spawnArgs.GetString( steeringHingeKeys[i], "" );
2040  if ( !steeringHingeName[0] ) {
2041  gameLocal.Error( "idAFEntity_VehicleFourWheels '%s' no '%s' specified", name.c_str(), steeringHingeKeys[i] );
2042  }
2043  steering[i] = static_cast<idAFConstraint_Hinge *>(af.GetPhysics()->GetConstraint( steeringHingeName ));
2044  if ( !steering[i] ) {
2045  gameLocal.Error( "idAFEntity_VehicleFourWheels '%s': can't find steering hinge '%s'", name.c_str(), steeringHingeName );
2046  }
2047  }
2048 
2049  memset( wheelAngles, 0, sizeof( wheelAngles ) );
2051 }
2052 
2053 /*
2054 ================
2055 idAFEntity_VehicleFourWheels::Think
2056 ================
2057 */
2059  int i;
2060  float force = 0.0f, velocity = 0.0f, steerAngle = 0.0f;
2061  idVec3 origin;
2062  idMat3 axis;
2063  idRotation rotation;
2064 
2065  if ( thinkFlags & TH_THINK ) {
2066 
2067  if ( player ) {
2068  // capture the input from a player
2069  velocity = g_vehicleVelocity.GetFloat();
2070  if ( player->usercmd.forwardmove < 0 ) {
2071  velocity = -velocity;
2072  }
2073  force = idMath::Fabs( player->usercmd.forwardmove * g_vehicleForce.GetFloat() ) * (1.0f / 128.0f);
2075  }
2076 
2077  // update the wheel motor force
2078  for ( i = 0; i < 2; i++ ) {
2079  wheels[2+i]->SetContactMotorVelocity( velocity );
2080  wheels[2+i]->SetContactMotorForce( force );
2081  }
2082 
2083  // adjust wheel velocity for better steering because there are no differentials between the wheels
2084  if ( steerAngle < 0.0f ) {
2085  wheels[2]->SetContactMotorVelocity( velocity * 0.5f );
2086  }
2087  else if ( steerAngle > 0.0f ) {
2088  wheels[3]->SetContactMotorVelocity( velocity * 0.5f );
2089  }
2090 
2091  // update the wheel steering
2094  for ( i = 0; i < 2; i++ ) {
2095  steering[i]->SetSteerSpeed( 3.0f );
2096  }
2097 
2098  // update the steering wheel
2100  rotation.SetVec( axis[2] );
2101  rotation.SetAngle( -steerAngle );
2103 
2104  // run the physics
2105  RunPhysics();
2106 
2107  // rotate the wheels visually
2108  for ( i = 0; i < 4; i++ ) {
2109  if ( force == 0.0f ) {
2110  velocity = wheels[i]->GetLinearVelocity() * wheels[i]->GetWorldAxis()[0];
2111  }
2112  wheelAngles[i] += velocity * MS2SEC( gameLocal.msec ) / wheelRadius;
2113  // give the wheel joint an additional rotation about the wheel axis
2114  rotation.SetAngle( RAD2DEG( wheelAngles[i] ) );
2115  axis = af.GetPhysics()->GetAxis( 0 );
2116  rotation.SetVec( (wheels[i]->GetWorldAxis() * axis.Transpose())[2] );
2118  }
2119 
2120  // spawn dust particle effects
2121  if ( force != 0.0f && !( gameLocal.framenum & 7 ) ) {
2122  int numContacts;
2123  idAFConstraint_Contact *contacts[2];
2124  for ( i = 0; i < 4; i++ ) {
2125  numContacts = af.GetPhysics()->GetBodyContactConstraints( wheels[i]->GetClipModel()->GetId(), contacts, 2 );
2126  for ( int j = 0; j < numContacts; j++ ) {
2127  gameLocal.smokeParticles->EmitSmoke( dustSmoke, gameLocal.time, gameLocal.random.RandomFloat(), contacts[j]->GetContact().point, contacts[j]->GetContact().normal.ToMat3(), timeGroup /* D3XP */ );
2128  }
2129  }
2130  }
2131  }
2132 
2133  UpdateAnimation();
2134  if ( thinkFlags & TH_UPDATEVISUALS ) {
2135  Present();
2136  LinkCombat();
2137  }
2138 }
2139 
2140 
2141 /*
2142 ===============================================================================
2143 
2144  idAFEntity_VehicleSixWheels
2145 
2146 ===============================================================================
2147 */
2148 
2150 END_CLASS
2151 
2152  /*
2153 ================
2154 idAFEntity_VehicleSixWheels::idAFEntity_VehicleSixWheels
2155 ================
2156 */
2158  int i;
2159 
2160  for ( i = 0; i < 6; i++ ) {
2161  wheels[i] = NULL;
2162  wheelJoints[i] = INVALID_JOINT;
2163  wheelAngles[i] = 0.0f;
2164  }
2165  steering[0] = NULL;
2166  steering[1] = NULL;
2167  steering[2] = NULL;
2168  steering[3] = NULL;
2169 }
2170 
2171 /*
2172 ================
2173 idAFEntity_VehicleSixWheels::Spawn
2174 ================
2175 */
2177  int i;
2178  static const char *wheelBodyKeys[] = {
2179  "wheelBodyFrontLeft",
2180  "wheelBodyFrontRight",
2181  "wheelBodyMiddleLeft",
2182  "wheelBodyMiddleRight",
2183  "wheelBodyRearLeft",
2184  "wheelBodyRearRight"
2185  };
2186  static const char *wheelJointKeys[] = {
2187  "wheelJointFrontLeft",
2188  "wheelJointFrontRight",
2189  "wheelJointMiddleLeft",
2190  "wheelJointMiddleRight",
2191  "wheelJointRearLeft",
2192  "wheelJointRearRight"
2193  };
2194  static const char *steeringHingeKeys[] = {
2195  "steeringHingeFrontLeft",
2196  "steeringHingeFrontRight",
2197  "steeringHingeRearLeft",
2198  "steeringHingeRearRight"
2199  };
2200 
2201  const char *wheelBodyName, *wheelJointName, *steeringHingeName;
2202 
2203  for ( i = 0; i < 6; i++ ) {
2204  wheelBodyName = spawnArgs.GetString( wheelBodyKeys[i], "" );
2205  if ( !wheelBodyName[0] ) {
2206  gameLocal.Error( "idAFEntity_VehicleSixWheels '%s' no '%s' specified", name.c_str(), wheelBodyKeys[i] );
2207  }
2208  wheels[i] = af.GetPhysics()->GetBody( wheelBodyName );
2209  if ( !wheels[i] ) {
2210  gameLocal.Error( "idAFEntity_VehicleSixWheels '%s' can't find wheel body '%s'", name.c_str(), wheelBodyName );
2211  }
2212  wheelJointName = spawnArgs.GetString( wheelJointKeys[i], "" );
2213  if ( !wheelJointName[0] ) {
2214  gameLocal.Error( "idAFEntity_VehicleSixWheels '%s' no '%s' specified", name.c_str(), wheelJointKeys[i] );
2215  }
2216  wheelJoints[i] = animator.GetJointHandle( wheelJointName );
2217  if ( wheelJoints[i] == INVALID_JOINT ) {
2218  gameLocal.Error( "idAFEntity_VehicleSixWheels '%s' can't find wheel joint '%s'", name.c_str(), wheelJointName );
2219  }
2220  }
2221 
2222  for ( i = 0; i < 4; i++ ) {
2223  steeringHingeName = spawnArgs.GetString( steeringHingeKeys[i], "" );
2224  if ( !steeringHingeName[0] ) {
2225  gameLocal.Error( "idAFEntity_VehicleSixWheels '%s' no '%s' specified", name.c_str(), steeringHingeKeys[i] );
2226  }
2227  steering[i] = static_cast<idAFConstraint_Hinge *>(af.GetPhysics()->GetConstraint( steeringHingeName ));
2228  if ( !steering[i] ) {
2229  gameLocal.Error( "idAFEntity_VehicleSixWheels '%s': can't find steering hinge '%s'", name.c_str(), steeringHingeName );
2230  }
2231  }
2232 
2233  memset( wheelAngles, 0, sizeof( wheelAngles ) );
2235 }
2236 
2237 /*
2238 ================
2239 idAFEntity_VehicleSixWheels::Think
2240 ================
2241 */
2243  int i;
2244 #ifndef _D3XP
2245  float force = 0.0f, velocity = 0.0f, steerAngle = 0.0f;
2246 #endif
2247  idVec3 origin;
2248  idMat3 axis;
2249  idRotation rotation;
2250 
2251  if ( thinkFlags & TH_THINK ) {
2252 
2253  if ( player ) {
2254  // capture the input from a player
2255  velocity = g_vehicleVelocity.GetFloat();
2256  if ( player->usercmd.forwardmove < 0 ) {
2257  velocity = -velocity;
2258  }
2259  force = idMath::Fabs( player->usercmd.forwardmove * g_vehicleForce.GetFloat() ) * (1.0f / 128.0f);
2261  }
2262 
2263  // update the wheel motor force
2264  for ( i = 0; i < 6; i++ ) {
2265  wheels[i]->SetContactMotorVelocity( velocity );
2266  wheels[i]->SetContactMotorForce( force );
2267  }
2268 
2269  // adjust wheel velocity for better steering because there are no differentials between the wheels
2270  if ( steerAngle < 0.0f ) {
2271  for ( i = 0; i < 3; i++ ) {
2272  wheels[(i<<1)]->SetContactMotorVelocity( velocity * 0.5f );
2273  }
2274  }
2275  else if ( steerAngle > 0.0f ) {
2276  for ( i = 0; i < 3; i++ ) {
2277  wheels[1+(i<<1)]->SetContactMotorVelocity( velocity * 0.5f );
2278  }
2279  }
2280 
2281  // update the wheel steering
2286  for ( i = 0; i < 4; i++ ) {
2287  steering[i]->SetSteerSpeed( 3.0f );
2288  }
2289 
2290  // update the steering wheel
2292  rotation.SetVec( axis[2] );
2293  rotation.SetAngle( -steerAngle );
2295 
2296  // run the physics
2297  RunPhysics();
2298 
2299  // rotate the wheels visually
2300  for ( i = 0; i < 6; i++ ) {
2301  if ( force == 0.0f ) {
2302  velocity = wheels[i]->GetLinearVelocity() * wheels[i]->GetWorldAxis()[0];
2303  }
2304  wheelAngles[i] += velocity * MS2SEC( gameLocal.msec ) / wheelRadius;
2305  // give the wheel joint an additional rotation about the wheel axis
2306  rotation.SetAngle( RAD2DEG( wheelAngles[i] ) );
2307  axis = af.GetPhysics()->GetAxis( 0 );
2308  rotation.SetVec( (wheels[i]->GetWorldAxis() * axis.Transpose())[2] );
2310  }
2311 
2312  // spawn dust particle effects
2313  if ( force != 0.0f && !( gameLocal.framenum & 7 ) ) {
2314  int numContacts;
2315  idAFConstraint_Contact *contacts[2];
2316  for ( i = 0; i < 6; i++ ) {
2317  numContacts = af.GetPhysics()->GetBodyContactConstraints( wheels[i]->GetClipModel()->GetId(), contacts, 2 );
2318  for ( int j = 0; j < numContacts; j++ ) {
2319  gameLocal.smokeParticles->EmitSmoke( dustSmoke, gameLocal.time, gameLocal.random.RandomFloat(), contacts[j]->GetContact().point, contacts[j]->GetContact().normal.ToMat3(), timeGroup /* D3XP */ );
2320  }
2321  }
2322  }
2323  }
2324 
2325  UpdateAnimation();
2326  if ( thinkFlags & TH_UPDATEVISUALS ) {
2327  Present();
2328  LinkCombat();
2329  }
2330 }
2331 
2332 #ifdef _D3XP
2333 /*
2334 ===============================================================================
2335 
2336 idAFEntity_VehicleAutomated
2337 
2338 ===============================================================================
2339 */
2340 const idEventDef EV_Vehicle_setVelocity( "setVelocity", "f" );
2341 const idEventDef EV_Vehicle_setTorque( "setTorque", "f" );
2342 const idEventDef EV_Vehicle_setSteeringSpeed( "setSteeringSpeed", "f" );
2343 const idEventDef EV_Vehicle_setWaypoint( "setWaypoint", "e" );
2344 
2345 CLASS_DECLARATION( idAFEntity_VehicleSixWheels, idAFEntity_VehicleAutomated )
2346 EVENT( EV_PostSpawn, idAFEntity_VehicleAutomated::PostSpawn )
2347 EVENT( EV_Vehicle_setVelocity, idAFEntity_VehicleAutomated::Event_SetVelocity )
2348 EVENT( EV_Vehicle_setTorque, idAFEntity_VehicleAutomated::Event_SetTorque )
2349 EVENT( EV_Vehicle_setSteeringSpeed, idAFEntity_VehicleAutomated::Event_SetSteeringSpeed )
2350 EVENT( EV_Vehicle_setWaypoint, idAFEntity_VehicleAutomated::Event_SetWayPoint )
2351 END_CLASS
2352 
2353 /*
2354 ================
2355 idAFEntity_VehicleAutomated::Spawn
2356 ================
2357 */
2358 void idAFEntity_VehicleAutomated::Spawn( void ) {
2359 
2360  velocity = force = steerAngle = 0.f;
2361  currentSteering = steeringSpeed = 0.f;
2362  originHeight = 0.f;
2363  waypoint = NULL;
2364 
2365  spawnArgs.GetFloat( "velocity", "150", velocity );
2366  spawnArgs.GetFloat( "torque", "200000", force );
2367  spawnArgs.GetFloat( "steeringSpeed", "1", steeringSpeed );
2368  spawnArgs.GetFloat( "originHeight", "0", originHeight );
2369 
2370  PostEventMS( &EV_PostSpawn, 0 );
2371 }
2372 
2373 /*
2374 ================
2375 idAFEntity_VehicleAutomated::PostSpawn
2376 ================
2377 */
2378 void idAFEntity_VehicleAutomated::PostSpawn( void ) {
2379 
2380  if ( targets.Num() ) {
2381  waypoint = targets[0].GetEntity();
2382  }
2383 }
2384 
2385 /*
2386 ================
2387 idAFEntity_VehicleAutomated::Event_SetVelocity
2388 ================
2389 */
2390 void idAFEntity_VehicleAutomated::Event_SetVelocity( float _velocity ) {
2391  velocity = _velocity;
2392 }
2393 
2394 /*
2395 ================
2396 idAFEntity_VehicleAutomated::Event_SetTorque
2397 ================
2398 */
2399 void idAFEntity_VehicleAutomated::Event_SetTorque( float _torque ) {
2400  force = _torque;
2401 }
2402 
2403 /*
2404 ================
2405 idAFEntity_VehicleAutomated::Event_SetSteeringSpeed
2406 ================
2407 */
2408 void idAFEntity_VehicleAutomated::Event_SetSteeringSpeed( float _steeringSpeed ) {
2409  steeringSpeed = _steeringSpeed;
2410 }
2411 
2412 /*
2413 ================
2414 idAFEntity_VehicleAutomated::Event_SetWayPoint
2415 ================
2416 */
2417 void idAFEntity_VehicleAutomated::Event_SetWayPoint( idEntity *_waypoint ) {
2418  waypoint = _waypoint;
2419 }
2420 
2421 /*
2422 ================
2423 idAFEntity_VehicleAutomated::Think
2424 ================
2425 */
2426 #define HIT_WAYPOINT_THRESHOLD 80.f
2427 
2428 void idAFEntity_VehicleAutomated::Think( void ) {
2429 
2430  // If we don't have a waypoint, coast to a stop
2431  if ( !waypoint ) {
2432  velocity = force = steerAngle = 0.f;
2434  return;
2435  }
2436 
2437  idVec3 waypoint_origin, vehicle_origin;
2438  idVec3 travel_vector;
2439  float distance_from_waypoint;
2440 
2441  // Set up the vector from the vehicle origin, to the waypoint
2442  vehicle_origin = GetPhysics()->GetOrigin();
2443  vehicle_origin.z -= originHeight;
2444 
2445  waypoint_origin = waypoint->GetPhysics()->GetOrigin();
2446 
2447  travel_vector = waypoint_origin - vehicle_origin;
2448  distance_from_waypoint = travel_vector.Length();
2449 
2450  // Check if we've hit the waypoint (within a certain threshold)
2451  if ( distance_from_waypoint < HIT_WAYPOINT_THRESHOLD ) {
2452  idStr callfunc;
2453  const function_t *func;
2454  idThread *thread;
2455 
2456  // Waypoints can call script functions
2457  waypoint->spawnArgs.GetString( "call", "", callfunc );
2458  if ( callfunc.Length() ) {
2459  func = gameLocal.program.FindFunction( callfunc );
2460  if ( func != NULL ) {
2461  thread = new idThread( func );
2462  thread->DelayedStart( 0 );
2463  }
2464  }
2465 
2466  // Get next waypoint
2467  if ( waypoint->targets.Num() ) {
2468  waypoint = waypoint->targets[0].GetEntity();
2469  } else {
2470  waypoint = NULL;
2471  }
2472 
2473  // We are switching waypoints, adjust steering next frame
2475  return;
2476  }
2477 
2478  idAngles vehicle_angles, travel_angles;
2479 
2480  // Get the angles we need to steer towards
2481  travel_angles = travel_vector.ToAngles().Normalize360();
2482  vehicle_angles = this->GetPhysics()->GetAxis().ToAngles().Normalize360();
2483 
2484  float delta_yaw;
2485 
2486  // Get the shortest steering angle towards the travel angles
2487  delta_yaw = vehicle_angles.yaw - travel_angles.yaw;
2488  if ( idMath::Fabs( delta_yaw ) > 180.f ) {
2489  if ( delta_yaw > 0 ) {
2490  delta_yaw = delta_yaw - 360;
2491  } else {
2492  delta_yaw = delta_yaw + 360;
2493  }
2494  }
2495 
2496  // Maximum steering angle is 35 degrees
2497  delta_yaw = idMath::ClampFloat( -35.f, 35.f, delta_yaw );
2498 
2499  idealSteering = delta_yaw;
2500 
2501  // Adjust steering incrementally so it doesn't snap to the ideal angle
2502  if ( idMath::Fabs( (idealSteering - currentSteering) ) > steeringSpeed ) {
2503  if ( idealSteering > currentSteering ) {
2504  currentSteering += steeringSpeed;
2505  } else {
2506  currentSteering -= steeringSpeed;
2507  }
2508  } else {
2509  currentSteering = idealSteering;
2510  }
2511 
2512  // DEBUG
2513  if ( g_vehicleDebug.GetBool() ) {
2514  gameRenderWorld->DebugBounds( colorRed, idBounds(idVec3(-4,-4,-4),idVec3(4,4,4)), vehicle_origin );
2515  gameRenderWorld->DebugBounds( colorRed, idBounds(idVec3(-4,-4,-4),idVec3(4,4,4)), waypoint_origin );
2516  gameRenderWorld->DrawText( waypoint->name.c_str(), waypoint_origin + idVec3(0,0,16), 0.25f, colorYellow, gameLocal.GetLocalPlayer()->viewAxis );
2517  gameRenderWorld->DebugArrow( colorWhite, vehicle_origin, waypoint_origin, 12.f );
2518  }
2519 
2520  // Set the final steerAngle for the vehicle
2521  steerAngle = currentSteering;
2522 
2524 }
2525 #endif
2526 
2527 /*
2528 ===============================================================================
2529 
2530  idAFEntity_SteamPipe
2531 
2532 ===============================================================================
2533 */
2534 
2536 END_CLASS
2537 
2538 
2539 /*
2540 ================
2541 idAFEntity_SteamPipe::idAFEntity_SteamPipe
2542 ================
2543 */
2545  steamBody = 0;
2546  steamForce = 0.0f;
2547  steamUpForce = 0.0f;
2548  steamModelDefHandle = -1;
2549  memset( &steamRenderEntity, 0, sizeof( steamRenderEntity ) );
2550 }
2551 
2552 /*
2553 ================
2554 idAFEntity_SteamPipe::~idAFEntity_SteamPipe
2555 ================
2556 */
2558  if ( steamModelDefHandle >= 0 ){
2560  }
2561 }
2562 
2563 /*
2564 ================
2565 idAFEntity_SteamPipe::Save
2566 ================
2567 */
2568 void idAFEntity_SteamPipe::Save( idSaveGame *savefile ) const {
2569 }
2570 
2571 /*
2572 ================
2573 idAFEntity_SteamPipe::Restore
2574 ================
2575 */
2577  Spawn();
2578 }
2579 
2580 /*
2581 ================
2582 idAFEntity_SteamPipe::Spawn
2583 ================
2584 */
2586  idVec3 steamDir;
2587  const char *steamBodyName;
2588 
2589  LoadAF();
2590 
2591  SetCombatModel();
2592 
2593  SetPhysics( af.GetPhysics() );
2594 
2595  fl.takedamage = true;
2596 
2597  steamBodyName = spawnArgs.GetString( "steamBody", "" );
2598  steamForce = spawnArgs.GetFloat( "steamForce", "2000" );
2599  steamUpForce = spawnArgs.GetFloat( "steamUpForce", "10" );
2600  steamDir = af.GetPhysics()->GetAxis( steamBody )[2];
2601  steamBody = af.GetPhysics()->GetBodyId( steamBodyName );
2603  force.SetForce( steamDir * -steamForce );
2604 
2606 
2608 }
2609 
2610 /*
2611 ================
2612 idAFEntity_SteamPipe::InitSteamRenderEntity
2613 ================
2614 */
2616  const char *temp;
2617  const idDeclModelDef *modelDef;
2618 
2619  memset( &steamRenderEntity, 0, sizeof( steamRenderEntity ) );
2623  modelDef = NULL;
2624  temp = spawnArgs.GetString ( "model_steam" );
2625  if ( *temp != '\0' ) {
2626  if ( !strstr( temp, "." ) ) {
2627  modelDef = static_cast<const idDeclModelDef *>( declManager->FindType( DECL_MODELDEF, temp, false ) );
2628  if ( modelDef ) {
2629  steamRenderEntity.hModel = modelDef->ModelHandle();
2630  }
2631  }
2632 
2633  if ( !steamRenderEntity.hModel ) {
2635  }
2636 
2637  if ( steamRenderEntity.hModel ) {
2639  } else {
2641  }
2645  }
2646 }
2647 
2648 /*
2649 ================
2650 idAFEntity_SteamPipe::Think
2651 ================
2652 */
2654  idVec3 steamDir;
2655 
2656  if ( thinkFlags & TH_THINK ) {
2657  steamDir.x = gameLocal.random.CRandomFloat() * steamForce;
2658  steamDir.y = gameLocal.random.CRandomFloat() * steamForce;
2659  steamDir.z = steamUpForce;
2660  force.SetForce( steamDir );
2662  //gameRenderWorld->DebugArrow( colorWhite, af.GetPhysics()->GetOrigin( steamBody ), af.GetPhysics()->GetOrigin( steamBody ) - 10.0f * steamDir, 4 );
2663  }
2664 
2665  if ( steamModelDefHandle >= 0 ){
2669  }
2670 
2672 }
2673 
2674 
2675 /*
2676 ===============================================================================
2677 
2678  idAFEntity_ClawFourFingers
2679 
2680 ===============================================================================
2681 */
2682 
2683 const idEventDef EV_SetFingerAngle( "setFingerAngle", "f" );
2684 const idEventDef EV_StopFingers( "stopFingers" );
2685 
2687  EVENT( EV_SetFingerAngle, idAFEntity_ClawFourFingers::Event_SetFingerAngle )
2688  EVENT( EV_StopFingers, idAFEntity_ClawFourFingers::Event_StopFingers )
2689 END_CLASS
2690 
2691 static const char *clawConstraintNames[] = {
2692  "claw1", "claw2", "claw3", "claw4"
2693 };
2694 
2695 /*
2696 ================
2697 idAFEntity_ClawFourFingers::idAFEntity_ClawFourFingers
2698 ================
2699 */
2701  fingers[0] = NULL;
2702  fingers[1] = NULL;
2703  fingers[2] = NULL;
2704  fingers[3] = NULL;
2705 }
2706 
2707 /*
2708 ================
2709 idAFEntity_ClawFourFingers::Save
2710 ================
2711 */
2713  int i;
2714 
2715  for ( i = 0; i < 4; i++ ) {
2716  fingers[i]->Save( savefile );
2717  }
2718 }
2719 
2720 /*
2721 ================
2722 idAFEntity_ClawFourFingers::Restore
2723 ================
2724 */
2726  int i;
2727 
2728  for ( i = 0; i < 4; i++ ) {
2729  fingers[i] = static_cast<idAFConstraint_Hinge *>(af.GetPhysics()->GetConstraint( clawConstraintNames[i] ));
2730  fingers[i]->Restore( savefile );
2731  }
2732 
2733  SetCombatModel();
2734  LinkCombat();
2735 }
2736 
2737 /*
2738 ================
2739 idAFEntity_ClawFourFingers::Spawn
2740 ================
2741 */
2743  int i;
2744 
2745  LoadAF();
2746 
2747  SetCombatModel();
2748 
2749  af.GetPhysics()->LockWorldConstraints( true );
2750  af.GetPhysics()->SetForcePushable( true );
2751  SetPhysics( af.GetPhysics() );
2752 
2753  fl.takedamage = true;
2754 
2755  for ( i = 0; i < 4; i++ ) {
2756  fingers[i] = static_cast<idAFConstraint_Hinge *>(af.GetPhysics()->GetConstraint( clawConstraintNames[i] ));
2757  if ( !fingers[i] ) {
2758  gameLocal.Error( "idClaw_FourFingers '%s': can't find claw constraint '%s'", name.c_str(), clawConstraintNames[i] );
2759  }
2760  }
2761 }
2762 
2763 /*
2764 ================
2765 idAFEntity_ClawFourFingers::Event_SetFingerAngle
2766 ================
2767 */
2769  int i;
2770 
2771  for ( i = 0; i < 4; i++ ) {
2772  fingers[i]->SetSteerAngle( angle );
2773  fingers[i]->SetSteerSpeed( 0.5f );
2774  }
2775  af.GetPhysics()->Activate();
2776 }
2777 
2778 /*
2779 ================
2780 idAFEntity_ClawFourFingers::Event_StopFingers
2781 ================
2782 */
2784  int i;
2785 
2786  for ( i = 0; i < 4; i++ ) {
2787  fingers[i]->SetSteerAngle( fingers[i]->GetAngle() );
2788  }
2789 }
2790 
2791 
2792 /*
2793 ===============================================================================
2794 
2795  editor support routines
2796 
2797 ===============================================================================
2798 */
2799 
2800 
2801 /*
2802 ================
2803 idGameEdit::AF_SpawnEntity
2804 ================
2805 */
2806 bool idGameEdit::AF_SpawnEntity( const char *fileName ) {
2807  idDict args;
2808  idPlayer *player;
2809  idAFEntity_Generic *ent;
2810  const idDeclAF *af;
2811  idVec3 org;
2812  float yaw;
2813 
2814  player = gameLocal.GetLocalPlayer();
2815  if ( !player || !gameLocal.CheatsOk( false ) ) {
2816  return false;
2817  }
2818 
2819  af = static_cast<const idDeclAF *>( declManager->FindType( DECL_AF, fileName ) );
2820  if ( !af ) {
2821  return false;
2822  }
2823 
2824  yaw = player->viewAngles.yaw;
2825  args.Set( "angle", va( "%f", yaw + 180 ) );
2826  org = player->GetPhysics()->GetOrigin() + idAngles( 0, yaw, 0 ).ToForward() * 80 + idVec3( 0, 0, 1 );
2827  args.Set( "origin", org.ToString() );
2828  args.Set( "spawnclass", "idAFEntity_Generic" );
2829  if ( af->model[0] ) {
2830  args.Set( "model", af->model.c_str() );
2831  } else {
2832  args.Set( "model", fileName );
2833  }
2834  if ( af->skin[0] ) {
2835  args.Set( "skin", af->skin.c_str() );
2836  }
2837  args.Set( "articulatedFigure", fileName );
2838  args.Set( "nodrop", "1" );
2839  ent = static_cast<idAFEntity_Generic *>(gameLocal.SpawnEntityType( idAFEntity_Generic::Type, &args));
2840 
2841  // always update this entity
2842  ent->BecomeActive( TH_THINK );
2843  ent->KeepRunningPhysics();
2844  ent->fl.forcePhysicsUpdate = true;
2845 
2846  player->dragEntity.SetSelected( ent );
2847 
2848  return true;
2849 }
2850 
2851 /*
2852 ================
2853 idGameEdit::AF_UpdateEntities
2854 ================
2855 */
2856 void idGameEdit::AF_UpdateEntities( const char *fileName ) {
2857  idEntity *ent;
2858  idAFEntity_Base *af;
2859  idStr name;
2860 
2861  name = fileName;
2862  name.StripFileExtension();
2863 
2864  // reload any idAFEntity_Generic which uses the given articulated figure file
2865  for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) {
2866  if ( ent->IsType( idAFEntity_Base::Type ) ) {
2867  af = static_cast<idAFEntity_Base *>(ent);
2868  if ( name.Icmp( af->GetAFName() ) == 0 ) {
2869  af->LoadAF();
2870  af->GetAFPhysics()->PutToRest();
2871  }
2872  }
2873  }
2874 }
2875 
2876 /*
2877 ================
2878 idGameEdit::AF_UndoChanges
2879 ================
2880 */
2882  int i, c;
2883  idEntity *ent;
2884  idAFEntity_Base *af;
2885  idDeclAF *decl;
2886 
2888  for ( i = 0; i < c; i++ ) {
2889  decl = static_cast<idDeclAF *>( const_cast<idDecl *>( declManager->DeclByIndex( DECL_AF, i, false ) ) );
2890  if ( !decl->modified ) {
2891  continue;
2892  }
2893 
2894  decl->Invalidate();
2895  declManager->FindType( DECL_AF, decl->GetName() );
2896 
2897  // reload all AF entities using the file
2898  for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) {
2899  if ( ent->IsType( idAFEntity_Base::Type ) ) {
2900  af = static_cast<idAFEntity_Base *>(ent);
2901  if ( idStr::Icmp( decl->GetName(), af->GetAFName() ) == 0 ) {
2902  af->LoadAF();
2903  }
2904  }
2905  }
2906  }
2907 }
2908 
2909 /*
2910 ================
2911 GetJointTransform
2912 ================
2913 */
2914 typedef struct {
2918 
2919 static bool GetJointTransform( void *model, const idJointMat *frame, const char *jointName, idVec3 &origin, idMat3 &axis ) {
2920  int i;
2921  jointTransformData_t *data = reinterpret_cast<jointTransformData_t *>(model);
2922 
2923  for ( i = 0; i < data->ent->numJoints; i++ ) {
2924  if ( data->joints[i].name.Icmp( jointName ) == 0 ) {
2925  break;
2926  }
2927  }
2928  if ( i >= data->ent->numJoints ) {
2929  return false;
2930  }
2931  origin = frame[i].ToVec3();
2932  axis = frame[i].ToMat3();
2933  return true;
2934 }
2935 
2936 /*
2937 ================
2938 GetArgString
2939 ================
2940 */
2941 static const char *GetArgString( const idDict &args, const idDict *defArgs, const char *key ) {
2942  const char *s;
2943 
2944  s = args.GetString( key );
2945  if ( !s[0] && defArgs ) {
2946  s = defArgs->GetString( key );
2947  }
2948  return s;
2949 }
2950 
2951 /*
2952 ================
2953 idGameEdit::AF_CreateMesh
2954 ================
2955 */
2956 idRenderModel *idGameEdit::AF_CreateMesh( const idDict &args, idVec3 &meshOrigin, idMat3 &meshAxis, bool &poseIsSet ) {
2957  int i, jointNum;
2958  const idDeclAF *af;
2959  const idDeclAF_Body *fb;
2960  renderEntity_t ent;
2961  idVec3 origin, *bodyOrigin, *newBodyOrigin, *modifiedOrigin;
2962  idMat3 axis, *bodyAxis, *newBodyAxis, *modifiedAxis;
2963  declAFJointMod_t *jointMod;
2964  idAngles angles;
2965  const idDict *defArgs;
2966  const idKeyValue *arg;
2967  idStr name;
2969  const char *classname, *afName, *modelName;
2970  idRenderModel *md5;
2971  const idDeclModelDef *modelDef;
2972  const idMD5Anim *MD5anim;
2973  const idMD5Joint *MD5joint;
2974  const idMD5Joint *MD5joints;
2975  int numMD5joints;
2976  idJointMat *originalJoints;
2977  int parentNum;
2978 
2979  poseIsSet = false;
2980  meshOrigin.Zero();
2981  meshAxis.Identity();
2982 
2983  classname = args.GetString( "classname" );
2984  defArgs = gameLocal.FindEntityDefDict( classname );
2985 
2986  // get the articulated figure
2987  afName = GetArgString( args, defArgs, "articulatedFigure" );
2988  af = static_cast<const idDeclAF *>( declManager->FindType( DECL_AF, afName ) );
2989  if ( !af ) {
2990  return NULL;
2991  }
2992 
2993  // get the md5 model
2994  modelName = GetArgString( args, defArgs, "model" );
2995  modelDef = static_cast< const idDeclModelDef *>( declManager->FindType( DECL_MODELDEF, modelName, false ) );
2996  if ( !modelDef ) {
2997  return NULL;
2998  }
2999 
3000  // make sure model hasn't been purged
3001  if ( modelDef->ModelHandle() && !modelDef->ModelHandle()->IsLoaded() ) {
3002  modelDef->ModelHandle()->LoadModel();
3003  }
3004 
3005  // get the md5
3006  md5 = modelDef->ModelHandle();
3007  if ( !md5 || md5->IsDefaultModel() ) {
3008  return NULL;
3009  }
3010 
3011  // get the articulated figure pose anim
3012  int animNum = modelDef->GetAnim( "af_pose" );
3013  if ( !animNum ) {
3014  return NULL;
3015  }
3016  const idAnim *anim = modelDef->GetAnim( animNum );
3017  if ( !anim ) {
3018  return NULL;
3019  }
3020  MD5anim = anim->MD5Anim( 0 );
3021  MD5joints = md5->GetJoints();
3022  numMD5joints = md5->NumJoints();
3023 
3024  // setup a render entity
3025  memset( &ent, 0, sizeof( ent ) );
3026  ent.customSkin = modelDef->GetSkin();
3027  ent.bounds.Clear();
3028  ent.numJoints = numMD5joints;
3029  ent.joints = ( idJointMat * )_alloca16( ent.numJoints * sizeof( *ent.joints ) );
3030 
3031  // create animation from of the af_pose
3032  ANIM_CreateAnimFrame( md5, MD5anim, ent.numJoints, ent.joints, 1, modelDef->GetVisualOffset(), false );
3033 
3034  // buffers to store the initial origin and axis for each body
3035  bodyOrigin = (idVec3 *) _alloca16( af->bodies.Num() * sizeof( idVec3 ) );
3036  bodyAxis = (idMat3 *) _alloca16( af->bodies.Num() * sizeof( idMat3 ) );
3037  newBodyOrigin = (idVec3 *) _alloca16( af->bodies.Num() * sizeof( idVec3 ) );
3038  newBodyAxis = (idMat3 *) _alloca16( af->bodies.Num() * sizeof( idMat3 ) );
3039 
3040  // finish the AF positions
3041  data.ent = &ent;
3042  data.joints = MD5joints;
3043  af->Finish( GetJointTransform, ent.joints, &data );
3044 
3045  // get the initial origin and axis for each AF body
3046  for ( i = 0; i < af->bodies.Num(); i++ ) {
3047  fb = af->bodies[i];
3048 
3049  if ( fb->modelType == TRM_BONE ) {
3050  // axis of bone trace model
3051  axis[2] = fb->v2.ToVec3() - fb->v1.ToVec3();
3052  axis[2].Normalize();
3053  axis[2].NormalVectors( axis[0], axis[1] );
3054  axis[1] = -axis[1];
3055  } else {
3056  axis = fb->angles.ToMat3();
3057  }
3058 
3059  newBodyOrigin[i] = bodyOrigin[i] = fb->origin.ToVec3();
3060  newBodyAxis[i] = bodyAxis[i] = axis;
3061  }
3062 
3063  // get any new body transforms stored in the key/value pairs
3064  for ( arg = args.MatchPrefix( "body ", NULL ); arg; arg = args.MatchPrefix( "body ", arg ) ) {
3065  name = arg->GetKey();
3066  name.Strip( "body " );
3067  for ( i = 0; i < af->bodies.Num(); i++ ) {
3068  fb = af->bodies[i];
3069  if ( fb->name.Icmp( name ) == 0 ) {
3070  break;
3071  }
3072  }
3073  if ( i >= af->bodies.Num() ) {
3074  continue;
3075  }
3076  sscanf( arg->GetValue(), "%f %f %f %f %f %f", &origin.x, &origin.y, &origin.z, &angles.pitch, &angles.yaw, &angles.roll );
3077 
3078  if ( fb->jointName.Icmp( "origin" ) == 0 ) {
3079  meshAxis = bodyAxis[i].Transpose() * angles.ToMat3();
3080  meshOrigin = origin - bodyOrigin[i] * meshAxis;
3081  poseIsSet = true;
3082  } else {
3083  newBodyOrigin[i] = origin;
3084  newBodyAxis[i] = angles.ToMat3();
3085  }
3086  }
3087 
3088  // save the original joints
3089  originalJoints = ( idJointMat * )_alloca16( numMD5joints * sizeof( originalJoints[0] ) );
3090  memcpy( originalJoints, ent.joints, numMD5joints * sizeof( originalJoints[0] ) );
3091 
3092  // buffer to store the joint mods
3093  jointMod = (declAFJointMod_t *) _alloca16( numMD5joints * sizeof( declAFJointMod_t ) );
3094  memset( jointMod, -1, numMD5joints * sizeof( declAFJointMod_t ) );
3095  modifiedOrigin = (idVec3 *) _alloca16( numMD5joints * sizeof( idVec3 ) );
3096  memset( modifiedOrigin, 0, numMD5joints * sizeof( idVec3 ) );
3097  modifiedAxis = (idMat3 *) _alloca16( numMD5joints * sizeof( idMat3 ) );
3098  memset( modifiedAxis, 0, numMD5joints * sizeof( idMat3 ) );
3099 
3100  // get all the joint modifications
3101  for ( i = 0; i < af->bodies.Num(); i++ ) {
3102  fb = af->bodies[i];
3103 
3104  if ( fb->jointName.Icmp( "origin" ) == 0 ) {
3105  continue;
3106  }
3107 
3108  for ( jointNum = 0; jointNum < numMD5joints; jointNum++ ) {
3109  if ( MD5joints[jointNum].name.Icmp( fb->jointName ) == 0 ) {
3110  break;
3111  }
3112  }
3113 
3114  if ( jointNum >= 0 && jointNum < ent.numJoints ) {
3115  jointMod[ jointNum ] = fb->jointMod;
3116  modifiedAxis[ jointNum ] = ( bodyAxis[i] * originalJoints[jointNum].ToMat3().Transpose() ).Transpose() * ( newBodyAxis[i] * meshAxis.Transpose() );
3117  // FIXME: calculate correct modifiedOrigin
3118  modifiedOrigin[ jointNum ] = originalJoints[ jointNum ].ToVec3();
3119  }
3120  }
3121 
3122  // apply joint modifications to the skeleton
3123  MD5joint = MD5joints + 1;
3124  for( i = 1; i < numMD5joints; i++, MD5joint++ ) {
3125 
3126  parentNum = MD5joint->parent - MD5joints;
3127  idMat3 parentAxis = originalJoints[ parentNum ].ToMat3();
3128  idMat3 localm = originalJoints[i].ToMat3() * parentAxis.Transpose();
3129  idVec3 localt = ( originalJoints[i].ToVec3() - originalJoints[ parentNum ].ToVec3() ) * parentAxis.Transpose();
3130 
3131  switch( jointMod[i] ) {
3132  case DECLAF_JOINTMOD_ORIGIN: {
3133  ent.joints[ i ].SetRotation( localm * ent.joints[ parentNum ].ToMat3() );
3134  ent.joints[ i ].SetTranslation( modifiedOrigin[ i ] );
3135  break;
3136  }
3137  case DECLAF_JOINTMOD_AXIS: {
3138  ent.joints[ i ].SetRotation( modifiedAxis[ i ] );
3139  ent.joints[ i ].SetTranslation( ent.joints[ parentNum ].ToVec3() + localt * ent.joints[ parentNum ].ToMat3() );
3140  break;
3141  }
3142  case DECLAF_JOINTMOD_BOTH: {
3143  ent.joints[ i ].SetRotation( modifiedAxis[ i ] );
3144  ent.joints[ i ].SetTranslation( modifiedOrigin[ i ] );
3145  break;
3146  }
3147  default: {
3148  ent.joints[ i ].SetRotation( localm * ent.joints[ parentNum ].ToMat3() );
3149  ent.joints[ i ].SetTranslation( ent.joints[ parentNum ].ToVec3() + localt * ent.joints[ parentNum ].ToMat3() );
3150  break;
3151  }
3152  }
3153  }
3154 
3155  // instantiate a mesh using the joint information from the render entity
3156  return md5->InstantiateDynamicModel( &ent, NULL, NULL );
3157 }
3158 
3159 #ifdef _D3XP
3160 
3161 /*
3162 ===============================================================================
3163 idHarvestable
3164 ===============================================================================
3165 */
3166 
3167 const idEventDef EV_Harvest_SpawnHarvestTrigger( "<spawnHarvestTrigger>", NULL );
3168 
3169 CLASS_DECLARATION( idEntity, idHarvestable )
3170 EVENT( EV_Harvest_SpawnHarvestTrigger, idHarvestable::Event_SpawnHarvestTrigger )
3171 EVENT( EV_Touch, idHarvestable::Event_Touch )
3172 END_CLASS
3173 
3174 idHarvestable::idHarvestable() {
3175  trigger = NULL;
3176  parentEnt = NULL;
3177 }
3178 
3179 idHarvestable::~idHarvestable() {
3180  if ( trigger ) {
3181  delete trigger;
3182  trigger = NULL;
3183  }
3184 }
3185 
3186 void idHarvestable::Spawn() {
3187 
3188  startTime = 0;
3189 
3190  spawnArgs.GetFloat( "triggersize", "120", triggersize );
3191  spawnArgs.GetFloat( "give_delay", "3", giveDelay);
3192  giveDelay *= 1000;
3193  given = false;
3194 
3195  removeDelay = spawnArgs.GetFloat( "remove_delay") * 1000.0f;
3196 
3197  fxFollowPlayer = spawnArgs.GetBool("fx_follow_player", "1");
3198  fxOrient = spawnArgs.GetString("fx_orient");
3199 
3200 
3201 }
3202 
3203 void idHarvestable::Init(idEntity* parent) {
3204 
3205  assert(parent);
3206 
3207  parentEnt = parent;
3208 
3209  GetPhysics()->SetOrigin( parent->GetPhysics()->GetOrigin() );
3210  this->Bind(parent, true);
3211 
3212  //Set the skin of the entity to the harvest skin
3213  idStr skin = parent->spawnArgs.GetString("skin_harvest", "");
3214  if(skin.Length()) {
3215  parent->SetSkin(declManager->FindSkin(skin.c_str()));
3216  }
3217 
3218  idEntity* head;
3219  if(parent->IsType(idActor::Type)) {
3220  idActor* withHead = (idActor*)parent;
3221  head = withHead->GetHeadEntity();
3222  }
3223  if(parent->IsType(idAFEntity_WithAttachedHead::Type)) {
3225  head = withHead->head.GetEntity();
3226  }
3227  if(head) {
3228  idStr headskin = parent->spawnArgs.GetString("skin_harvest_head", "");
3229  if(headskin.Length()) {
3230  head->SetSkin(declManager->FindSkin(headskin.c_str()));
3231  }
3232  }
3233 
3234  idStr sound = parent->spawnArgs.GetString("harvest_sound");
3235  if(sound.Length() > 0) {
3236  parent->StartSound( sound.c_str(), SND_CHANNEL_ANY, 0, false, NULL);
3237  }
3238 
3239 
3240  PostEventMS( &EV_Harvest_SpawnHarvestTrigger, 0 );
3241 }
3242 
3243 void idHarvestable::Save( idSaveGame *savefile ) const {
3244  savefile->WriteFloat( triggersize );
3245  savefile->WriteClipModel( trigger );
3246  savefile->WriteFloat( giveDelay );
3247  savefile->WriteFloat( removeDelay );
3248  savefile->WriteBool( given );
3249 
3250  player.Save( savefile );
3251  savefile->WriteInt( startTime );
3252 
3253  savefile->WriteBool( fxFollowPlayer );
3254  fx.Save( savefile );
3255  savefile->WriteString( fxOrient );
3256 
3257  parentEnt.Save(savefile);
3258 }
3259 
3260 void idHarvestable::Restore( idRestoreGame *savefile ) {
3261  savefile->ReadFloat( triggersize );
3262  savefile->ReadClipModel( trigger );
3263  savefile->ReadFloat( giveDelay );
3264  savefile->ReadFloat( removeDelay );
3265  savefile->ReadBool( given );
3266 
3267  player.Restore( savefile );
3268  savefile->ReadInt( startTime );
3269 
3270  savefile->ReadBool( fxFollowPlayer );
3271  fx.Restore( savefile );
3272  savefile->ReadString( fxOrient );
3273 
3274  parentEnt.Restore(savefile);
3275 }
3276 
3277 void idHarvestable::SetParent(idEntity* parent) {
3278  parentEnt = parent;
3279 }
3280 
3281 void idHarvestable::Think() {
3282 
3283  idEntity* parent = parentEnt.GetEntity();
3284  if(!parent) {
3285  return;
3286  }
3287 
3288  //Update the orientation of the box
3289  if(trigger && parent && !parent->GetPhysics()->IsAtRest()) {
3290  trigger->Link( gameLocal.clip, this, 0, parent->GetPhysics()->GetOrigin(), parent->GetPhysics()->GetAxis());
3291  }
3292 
3293  if(startTime && gameLocal.slow.time - startTime > giveDelay && ! given) {
3294  idPlayer *thePlayer = player.GetEntity();
3295 
3296  thePlayer->Give(spawnArgs.GetString("give_item"), spawnArgs.GetString("give_value"));
3297  thePlayer->harvest_lock = false;
3298  given = true;
3299  }
3300 
3301  if(startTime && gameLocal.slow.time - startTime > removeDelay) {
3302  parent->PostEventMS( &EV_Remove, 0 );
3303  PostEventMS( &EV_Remove, 0 );
3304  }
3305 
3306  if(fxFollowPlayer) {
3307  idEntityFx* fxEnt = fx.GetEntity();
3308 
3309  if(fxEnt) {
3310  idMat3 orientAxisLocal;
3311  if(GetFxOrientationAxis(orientAxisLocal)) {
3312  //gameRenderWorld->DebugAxis(fxEnt->GetPhysics()->GetOrigin(), orientAxisLocal);
3313  fxEnt->GetPhysics()->SetAxis(orientAxisLocal);
3314  }
3315  }
3316  }
3317 }
3318 
3319 /*
3320 ================
3321 idAFEntity_Harvest::Gib
3322 Called when the parent object has been gibbed.
3323 ================
3324 */
3325 void idHarvestable::Gib() {
3326  //Stop any looping sound that was playing
3327  idEntity* parent = parentEnt.GetEntity();
3328  if(parent) {
3329  idStr sound = parent->spawnArgs.GetString("harvest_sound");
3330  if(sound.Length() > 0) {
3331  parent->StopSound(SND_CHANNEL_ANY, false);
3332  }
3333  }
3334 }
3335 
3336 /*
3337 ================
3338 idAFEntity_Harvest::BeginBurn
3339 ================
3340 */
3341 void idHarvestable::BeginBurn() {
3342 
3343  idEntity* parent = parentEnt.GetEntity();
3344  if(!parent) {
3345  return;
3346  }
3347 
3348  if(!spawnArgs.GetBool("burn")) {
3349  return;
3350  }
3351 
3352 
3353  //Switch Skins if the parent would like us to.
3354  idStr skin = parent->spawnArgs.GetString("skin_harvest_burn", "");
3355  if(skin.Length()) {
3356  parent->SetSkin(declManager->FindSkin(skin.c_str()));
3357  }
3358  parent->GetRenderEntity()->noShadow = true;
3359  parent->SetShaderParm( SHADERPARM_TIME_OF_DEATH, gameLocal.slow.time * 0.001f );
3360 
3361  idEntity* head;
3362  if(parent->IsType(idActor::Type)) {
3363  idActor* withHead = (idActor*)parent;
3364  head = withHead->GetHeadEntity();
3365  }
3366  if(parent->IsType(idAFEntity_WithAttachedHead::Type)) {
3368  head = withHead->head.GetEntity();
3369  }
3370  if(head) {
3371  idStr headskin = parent->spawnArgs.GetString("skin_harvest_burn_head", "");
3372  if(headskin.Length()) {
3373  head->SetSkin(declManager->FindSkin(headskin.c_str()));
3374  }
3375 
3376  head->GetRenderEntity()->noShadow = true;
3377  head->SetShaderParm( SHADERPARM_TIME_OF_DEATH, gameLocal.slow.time * 0.001f );
3378  }
3379 
3380 
3381 
3382 }
3383 
3384 /*
3385 ================
3386 idAFEntity_Harvest::BeginFX
3387 ================
3388 */
3389 void idHarvestable::BeginFX() {
3390  if(strlen(spawnArgs.GetString("fx")) <= 0) {
3391  return;
3392  }
3393 
3394  idMat3* orientAxis = NULL;
3395  idMat3 orientAxisLocal;
3396 
3397  if(GetFxOrientationAxis(orientAxisLocal)) {
3398  orientAxis = &orientAxisLocal;
3399  }
3400  fx = idEntityFx::StartFx( spawnArgs.GetString("fx"), NULL, orientAxis, this, spawnArgs.GetBool("fx_bind") );
3401 }
3402 
3403 /*
3404 ================
3405 idAFEntity_Harvest::CalcTriggerBounds
3406 ================
3407 */
3408 void idHarvestable::CalcTriggerBounds( float size, idBounds &bounds ) {
3409 
3410  idEntity* parent = parentEnt.GetEntity();
3411  if(!parent) {
3412  return;
3413  }
3414 
3415  //Simple trigger bounds is the absolute bounds of the AF plus a defined size
3416  bounds = parent->GetPhysics()->GetAbsBounds();
3417  bounds.ExpandSelf(size);
3418  bounds[0] -= parent->GetPhysics()->GetOrigin();
3419  bounds[1] -= parent->GetPhysics()->GetOrigin();
3420 }
3421 
3422 bool idHarvestable::GetFxOrientationAxis(idMat3& mat) {
3423 
3424  idEntity* parent = parentEnt.GetEntity();
3425  if(!parent) {
3426  return false;
3427  }
3428 
3429  idPlayer *thePlayer = player.GetEntity();
3430 
3431  if(!fxOrient.Icmp("up")) {
3432  //Orient up
3433  idVec3 grav = parent->GetPhysics()->GetGravityNormal()*-1;
3434  idVec3 left, up;
3435 
3436  grav.OrthogonalBasis(left, up);
3437  idMat3 temp(left.x, left.y, left.z, up.x, up.y, up.z, grav.x, grav.y, grav.z);
3438  mat = temp;
3439 
3440  return true;
3441 
3442  } else if(!fxOrient.Icmp("weapon")) {
3443  //Orient the fx towards the muzzle of the weapon
3444  jointHandle_t joint;
3445  idVec3 joint_origin;
3446  idMat3 joint_axis;
3447 
3448  joint = thePlayer->weapon.GetEntity()->GetAnimator()->GetJointHandle( spawnArgs.GetString("fx_weapon_joint") );
3449  if ( joint != INVALID_JOINT ) {
3450  thePlayer->weapon.GetEntity()->GetJointWorldTransform( joint, gameLocal.slow.time, joint_origin, joint_axis );
3451  } else {
3452  joint_origin = thePlayer->GetPhysics()->GetOrigin();
3453  }
3454 
3455  idVec3 toPlayer = joint_origin-parent->GetPhysics()->GetOrigin();
3456  toPlayer.NormalizeFast();
3457 
3458  idVec3 left, up;
3459  toPlayer.OrthogonalBasis(left, up);
3460  idMat3 temp(left.x, left.y, left.z, up.x, up.y, up.z, toPlayer.x, toPlayer.y, toPlayer.z);
3461  mat = temp;
3462 
3463  return true;
3464 
3465  } else if(!fxOrient.Icmp("player")) {
3466  //Orient the fx towards the eye of the player
3467  idVec3 eye = thePlayer->GetEyePosition();
3468  idVec3 toPlayer = eye-parent->GetPhysics()->GetOrigin();
3469 
3470  toPlayer.Normalize();
3471 
3472  idVec3 left, up;
3473  up.Set(0, 1, 0);
3474  left = toPlayer.Cross(up);
3475  up = left.Cross(toPlayer);
3476 
3477 
3478  //common->Printf("%.2f %.2f %.2f - %.2f %.2f %.2f - %.2f %.2f %.2f\n", toPlayer.x, toPlayer.y, toPlayer.z, left.x, left.y, left.z, up.x, up.y, up.z );
3479 
3480  idMat3 temp(left.x, left.y, left.z, up.x, up.y, up.z, toPlayer.x, toPlayer.y, toPlayer.z);
3481 
3482  mat = temp;
3483 
3484  return true;
3485  }
3486 
3487  //Returning false indicates that the orientation is not used;
3488  return false;
3489 }
3490 
3491 /*
3492 ================
3493 idAFEntity_Harvest::Event_SpawnHarvestTrigger
3494 ================
3495 */
3496 void idHarvestable::Event_SpawnHarvestTrigger( void ) {
3497  idBounds bounds;
3498 
3499  idEntity* parent = parentEnt.GetEntity();
3500  if(!parent) {
3501  return;
3502  }
3503 
3504  CalcTriggerBounds( triggersize, bounds );
3505 
3506  // create a trigger clip model
3507  trigger = new idClipModel( idTraceModel( bounds ) );
3508  trigger->Link( gameLocal.clip, this, 255, parent->GetPhysics()->GetOrigin(), mat3_identity);
3509  trigger->SetContents( CONTENTS_TRIGGER );
3510 
3511  startTime = 0;
3512 }
3513 
3514 /*
3515 ================
3516 idAFEntity_Harvest::Event_Touch
3517 ================
3518 */
3519 void idHarvestable::Event_Touch( idEntity *other, trace_t *trace ) {
3520 
3521  idEntity* parent = parentEnt.GetEntity();
3522  if(!parent) {
3523  return;
3524  }
3525  if(parent->IsType(idAFEntity_Gibbable::Type)) {
3526  idAFEntity_Gibbable* gibParent = (idAFEntity_Gibbable*)parent;
3527  if(gibParent->IsGibbed())
3528  return;
3529  }
3530 
3531 
3532  if(!startTime && other && other->IsType(idPlayer::Type)) {
3533  idPlayer *thePlayer = static_cast<idPlayer *>(other);
3534 
3535  if(thePlayer->harvest_lock) {
3536  //Don't harvest if the player is in mid harvest
3537  return;
3538  }
3539 
3540  player = thePlayer;
3541 
3542  bool okToGive = true;
3543  idStr requiredWeapons = spawnArgs.GetString("required_weapons");
3544 
3545  if(requiredWeapons.Length() > 0) {
3546  idStr playerWeap = thePlayer->GetCurrentWeapon();
3547  if(playerWeap.Length() == 0 || requiredWeapons.Find(playerWeap, false) == -1) {
3548  okToGive = false;
3549  }
3550  }
3551 
3552  if(okToGive) {
3553  if(thePlayer->CanGive(spawnArgs.GetString("give_item"), spawnArgs.GetString("give_value"))) {
3554 
3555  startTime = gameLocal.slow.time;
3556 
3557  //Lock the player from harvesting to prevent multiple harvests when only one is needed
3558  thePlayer->harvest_lock = true;
3559 
3560  idWeapon* weap = (idWeapon*)thePlayer->weapon.GetEntity();
3561  if(weap) {
3562  //weap->PostEventMS(&EV_Weapon_State, 0, "Charge", 8);
3563  weap->ProcessEvent(&EV_Weapon_State, "Charge", 8);
3564  }
3565 
3566  BeginBurn();
3567  BeginFX();
3568 
3569  //Stop any looping sound that was playing
3570  idStr sound = parent->spawnArgs.GetString("harvest_sound");
3571  if(sound.Length() > 0) {
3572  parent->StopSound(SND_CHANNEL_ANY, false);
3573  }
3574 
3575  //Make the parent object non-solid
3576  parent->GetPhysics()->SetContents( 0 );
3577  parent->GetPhysics()->GetClipModel()->Unlink();
3578 
3579  //Turn of the trigger so it doesn't process twice
3580  trigger->SetContents( 0 );
3581  }
3582  }
3583  }
3584 }
3585 
3586 
3587 /*
3588 ===============================================================================
3589 
3590 idAFEntity_Harvest
3591 
3592 ===============================================================================
3593 */
3594 
3595 const idEventDef EV_Harvest_SpawnHarvestEntity( "<spawnHarvestEntity>", NULL );
3596 
3597 CLASS_DECLARATION( idAFEntity_WithAttachedHead, idAFEntity_Harvest )
3598 EVENT( EV_Harvest_SpawnHarvestEntity, idAFEntity_Harvest::Event_SpawnHarvestEntity )
3599 END_CLASS
3600 
3601 /*
3602 ================
3603 idAFEntity_Harvest::idAFEntity_Harvest
3604 ================
3605 */
3606 idAFEntity_Harvest::idAFEntity_Harvest() {
3607  harvestEnt = NULL;
3608 }
3609 
3610 /*
3611 ================
3612 idAFEntity_Harvest::~idAFEntity_Harvest
3613 ================
3614 */
3615 idAFEntity_Harvest::~idAFEntity_Harvest() {
3616 
3617  if ( harvestEnt.GetEntity() ) {
3618  harvestEnt.GetEntity()->PostEventMS( &EV_Remove, 0 );
3619  }
3620 
3621 }
3622 
3623 /*
3624 ================
3625 idAFEntity_Harvest::Save
3626 ================
3627 */
3628 void idAFEntity_Harvest::Save( idSaveGame *savefile ) const {
3629  harvestEnt.Save(savefile);
3630 }
3631 
3632 /*
3633 ================
3634 idAFEntity_Harvest::Restore
3635 ================
3636 */
3637 void idAFEntity_Harvest::Restore( idRestoreGame *savefile ) {
3638  harvestEnt.Restore(savefile);
3639  //if(harvestEnt.GetEntity()) {
3640  // harvestEnt.GetEntity()->SetParent(this);
3641  //}
3642 }
3643 
3644 /*
3645 ================
3646 idAFEntity_Harvest::Spawn
3647 ================
3648 */
3649 void idAFEntity_Harvest::Spawn( void ) {
3650 
3651  PostEventMS( &EV_Harvest_SpawnHarvestEntity, 0 );
3652 }
3653 
3654 /*
3655 ================
3656 idAFEntity_Harvest::Think
3657 ================
3658 */
3659 void idAFEntity_Harvest::Think( void ) {
3660 
3662 
3663 }
3664 
3665 void idAFEntity_Harvest::Event_SpawnHarvestEntity( void ) {
3666 
3667  const idDict *harvestDef = gameLocal.FindEntityDefDict( spawnArgs.GetString("def_harvest_type"), false );
3668  if ( harvestDef ) {
3669  idEntity *temp;
3670  gameLocal.SpawnEntityDef( *harvestDef, &temp, false );
3671  harvestEnt = static_cast<idHarvestable *>(temp);
3672  }
3673 
3674  if(harvestEnt.GetEntity()) {
3675  //Let the harvest entity set itself up
3676  harvestEnt.GetEntity()->Init(this);
3677  harvestEnt.GetEntity()->BecomeActive( TH_THINK );
3678  }
3679 }
3680 
3681 void idAFEntity_Harvest::Gib( const idVec3 &dir, const char *damageDefName ) {
3682  if(harvestEnt.GetEntity()) {
3683  //Let the harvest ent know that we gibbed
3684  harvestEnt.GetEntity()->Gib();
3685  }
3686  idAFEntity_WithAttachedHead::Gib(dir, damageDefName);
3687 }
3688 
3689 #endif
virtual const idVec3 & GetOrigin(int id=0) const =0
const contactInfo_t & GetContact(void) const
Definition: Physics_AF.h:503
jointHandle_t
Definition: Model.h:156
idPlayer * GetLocalPlayer() const
void SetupPolygon(const idVec3 *v, const int count)
Definition: TraceModel.cpp:866
void SetupPose(idEntity *ent, int time)
Definition: AF.cpp:231
int skeletonModelDefHandle
Definition: AFEntity.h:237
renderEntity_t renderEntity
Definition: Entity.h:371
virtual void Damage(idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location)
Definition: AFEntity.cpp:1097
jointHandle_t steeringWheelJoint
Definition: AFEntity.h:346
void EnableImpact(void)
void SetSteerAngle(const float degrees)
int GetContents(void) const
Definition: Clip.h:170
float GetFloat(const char *key, const char *defaultString="0") const
Definition: Dict.h:248
virtual void Gib(const idVec3 &dir, const char *damageDefName)
Definition: AFEntity.cpp:1602
idMat3 ToMat3(void) const
Definition: Vector.cpp:195
void InitSkeletonModel(void)
Definition: AFEntity.cpp:1034
bool GetJointTransform(jointHandle_t jointHandle, int currenttime, idVec3 &offset, idMat3 &axis)
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)
idAngles & Normalize360(void)
Definition: Angles.cpp:44
void SetAnchor(const idVec3 &worldPosition)
Definition: Physics_AF.cpp:956
int GetInt(const char *key, const char *defaultString="0") const
Definition: Dict.h:252
virtual idRenderModel * InstantiateDynamicModel(const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel)=0
int GetGibTime()
Definition: Game_local.h:528
void Event_SetConstraintPosition(const char *name, const idVec3 &pos)
Definition: AFEntity.cpp:933
bool PostEventSec(const idEventDef *ev, float time)
Definition: Class.cpp:747
virtual void InitTool(const toolFlag_t tool, const idDict *dict)=0
virtual void AF_UpdateEntities(const char *fileName)
Definition: AFEntity.cpp:2856
void SetMotorForce(const float force)
Definition: Physics_AF.h:611
assert(prefInfo.fullscreenBtn)
const idDict * FindEntityDefDict(const char *name, bool makeDefault=true) const
idList< int > modelDefHandles
Definition: AFEntity.h:62
virtual const idVec3 & GetGravityNormal(void) const =0
void Link(idClip &clp)
Definition: Clip.cpp:545
idAFConstraint_Hinge * steering[2]
Definition: AFEntity.h:401
void Restore(idRestoreGame *savefile)
Definition: Game_local.h:661
#define CLIPMODEL_ID_TO_JOINT_HANDLE(id)
Definition: Clip.h:40
idMat3 mat3_identity(idVec3(1, 0, 0), idVec3(0, 1, 0), idVec3(0, 0, 1))
void Restore(idRestoreGame *savefile)
Definition: AFEntity.cpp:2725
virtual void SetContents(int contents, int id=-1)=0
void SetSteerSpeed(const float speed)
const idEventDef EV_PostSpawn("<postspawn>", NULL)
void WriteObject(const idClass *obj)
Definition: SaveGame.cpp:329
void Save(idSaveGame *savefile) const
Definition: AFEntity.cpp:2712
virtual void DebugArrow(const idVec4 &color, const idVec3 &start, const idVec3 &end, int size, const int lifetime=0)=0
idVec3 GetCenter(void) const
Definition: Bounds.h:211
int GetNumBodies(void) const
idAFConstraint * GetConstraint(const char *constraintName) const
void ClearBody(void)
Definition: AFEntity.cpp:303
idClip clip
Definition: Game_local.h:296
virtual void Think(void)
Definition: AFEntity.cpp:2653
idVec4 colorWhite
Definition: Lib.cpp:116
void SetComeToRest(bool enable)
Definition: Physics_AF.h:879
void Zero(void)
Definition: Bounds.h:206
void UpdateModel(void)
Definition: Entity.cpp:1269
void SetContents(int newContents)
Definition: Clip.h:166
virtual void UnlinkCombat(void)
Definition: AFEntity.cpp:855
struct idEntity::entityFlags_s fl
idCVar g_vehicleTireFriction("g_vehicleTireFriction","0.8", CVAR_GAME|CVAR_FLOAT,"")
void BindToJoint(idEntity *master, const char *jointname, bool orientated)
Definition: Entity.cpp:1921
type * GetEntity(void) const
Definition: Game_local.h:695
virtual void Finish(const getJointTransform_t GetJointTransform, const idJointMat *frame, void *model) const
Definition: DeclAF.cpp:1590
void DelayedStart(int delay)
virtual void AF_UndoChanges(void)
Definition: AFEntity.cpp:2881
void SetShaderParm(int parmnum, float value)
Definition: Entity.cpp:1067
void LoadState(const idDict &args)
Definition: AF.cpp:1128
idClipModel * wheelModel
Definition: AFEntity.h:375
idSmokeParticles * smokeParticles
Definition: Game_local.h:307
float GetFloat(void) const
Definition: CVarSystem.h:144
const GLdouble * v
Definition: glext.h:2936
void SetVec(const idVec3 &rotationVec)
Definition: Rotation.h:119
const idStr & GetKey(void) const
Definition: Dict.h:52
bool UpdateAnimation(void)
Definition: AF.cpp:137
virtual bool Collide(const trace_t &collision, const idVec3 &velocity)
Definition: AFEntity.cpp:749
const idEventDef EV_Activate("activate","e")
const idDeclParticle * dustSmoke
Definition: AFEntity.h:350
bool isNewFrame
Definition: Game_local.h:333
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
virtual void Think(void)
Definition: AFEntity.cpp:1515
void SetCombatModel(void)
Definition: AFEntity.cpp:800
idMat3 Transpose(void) const
Definition: Matrix.h:677
idRandom random
Definition: Game_local.h:291
int Length(void) const
Definition: Str.h:702
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
const int ANIMCHANNEL_ALL
Definition: Anim.h:41
void SetSteerAngle(const float degrees)
Definition: Physics_AF.h:609
void AssureSize(int newSize)
Definition: List.h:445
bool IsType(const idTypeInfo &c) const
Definition: Class.h:337
void Spawn(void)
Definition: AFEntity.cpp:277
void Setup(const char *name, idAFBody *body, const idVec3 &origin, const idMat3 &axis, idClipModel *clipModel)
void Set(const float x, const float y, const float z)
Definition: Vector.h:409
idStr name
Definition: DeclAF.h:88
void SetForcePushable(const bool enable)
Definition: Physics_AF.h:888
idAFBody * GetBody(const char *bodyName) const
const idMat3 & GetWorldAxis(void) const
Definition: Physics_AF.h:670
const char * GetAFName(void) const
Definition: AFEntity.h:169
bool keepRunningPhysics
Definition: AFEntity.h:276
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
idVec3 GetEyePosition(void) const
static void DropItems(idAnimatedEntity *ent, const char *type, idList< idEntity * > *list)
Definition: Item.cpp:1873
~idAFEntity_Gibbable(void)
Definition: AFEntity.cpp:973
int BodyForClipModelId(int id) const
Definition: AF.cpp:386
const idEventDef EV_Gib("gib","s")
bool ProcessEvent(const idEventDef *ev)
Definition: Class.cpp:858
void SetShafts(const idVec3 &cardanShaft1, const idVec3 &cardanShaft2)
Definition: Physics_AF.cpp:993
void Strip(const char c)
Definition: Str.h:915
bool CreateFrame(int animtime, bool force)
const idEventDef EV_StopFingers("stopFingers")
void SetCombatModel(void)
Definition: AFEntity.cpp:462
static float ClampFloat(float min, float max, float value)
Definition: Math.h:893
bool modified
Definition: DeclAF.h:171
void AddBindConstraints(void)
Definition: AF.cpp:1160
jointHandle_t GetJointHandle(const char *name) const
bool isClient
Definition: Game_local.h:327
const idEventDef EV_SetAngularVelocity("setAngularVelocity","v")
const char * GetName(void) const
Definition: DeclManager.h:140
int modelType
Definition: DeclAF.h:91
Definition: Vector.h:316
void ReadJoint(jointHandle_t &value)
Definition: SaveGame.cpp:931
void ReadBool(bool &value)
Definition: SaveGame.cpp:976
jointHandle_t wheelJoints[6]
Definition: AFEntity.h:433
void SetFriction(const float f)
Definition: Physics_AF.h:250
virtual bool GetPhysicsToVisualTransform(idVec3 &origin, idMat3 &axis)
Definition: AFEntity.cpp:773
static float Sqrt(float x)
Definition: Math.h:302
const idVec3 GetWheelOrigin(void) const
idPhysics_AF * GetPhysics(void)
Definition: AF.h:77
const int SHADERPARM_GREEN
Definition: RenderWorld.h:47
virtual void FreeModelDef(void)
Definition: Entity.cpp:1197
virtual const char * Name() const =0
virtual void Gib(const idVec3 &dir, const char *damageDefName)
Definition: AFEntity.cpp:1217
virtual void Think(void)
Definition: AFEntity.cpp:1323
virtual void ShowEditingDialog(void)
Definition: AFEntity.cpp:876
void Clear(void)
Definition: Bounds.h:201
GLuint GLuint GLsizei GLenum type
Definition: glext.h:2845
const idDeclSkin * GetSkin(void) const
void SetJointPos(jointHandle_t jointnum, jointModTransform_t transform_type, const idVec3 &pos)
void SetSoundVolume(float volume)
Definition: Entity.cpp:1740
GLdouble s
Definition: glext.h:2935
idVec3 spawnOrigin
Definition: AFEntity.h:195
virtual void Think(void)
Definition: Entity.cpp:5160
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
idVec3 Cross(const idVec3 &a) const
Definition: Vector.h:619
void Identity(void)
Definition: Matrix.h:591
void InitSteamRenderEntity(void)
Definition: AFEntity.cpp:2615
float x
Definition: Vector.h:318
void Spawn(void)
Definition: AFEntity.cpp:583
virtual void SpawnGibs(const idVec3 &dir, const char *damageDefName)
Definition: AFEntity.cpp:1162
void Restore(idRestoreGame *savefile)
Definition: AFEntity.cpp:2576
idDict spawnArgs
Definition: Entity.h:122
void Start(void)
Definition: AF.cpp:941
void WriteClipModel(const class idClipModel *clipModel)
Definition: SaveGame.cpp:744
int i
Definition: process.py:33
#define MASK_MONSTERSOLID
Definition: Game_local.h:736
virtual void UnlinkCombat(void)
Definition: AFEntity.cpp:501
void OrthogonalBasis(idVec3 &left, idVec3 &up) const
Definition: Vector.h:744
jointHandle_t wheelJoints[4]
Definition: AFEntity.h:377
contactInfo_t c
void SetAnimator(idAnimator *a)
Definition: AF.h:63
GLuint GLuint num
Definition: glext.h:5390
void WriteVec3(const idVec3 &vec)
Definition: SaveGame.cpp:253
void SetTranslation(const idVec3 &t)
const idMat3 & GetAxis(int id=0) const
virtual void AddForce(idEntity *ent, int id, const idVec3 &point, const idVec3 &force)
Definition: AFEntity.cpp:735
virtual void ANIM_CreateAnimFrame(const idRenderModel *model, const idMD5Anim *anim, int numJoints, idJointMat *frame, int time, const idVec3 &offset, bool remove_origin_offset)
void Activate(void)
int Icmp(const char *text) const
Definition: Str.h:667
declAFJointMod_t jointMod
Definition: DeclAF.h:90
void SetName(const char *name)
Definition: Entity.cpp:854
virtual void Think(void)
Definition: AFEntity.cpp:625
void RemoveBindConstraints(void)
Definition: AF.cpp:1248
~idMultiModelAF(void)
Definition: AFEntity.cpp:60
bool Give(const char *statname, const char *value)
#define EVENT(event, function)
Definition: Class.h:53
idMat3 viewAxis
Definition: Actor.h:117
void Restore(idRestoreGame *savefile)
Definition: AF.cpp:94
void Restore(idRestoreGame *savefile)
Definition: AFEntity.cpp:1464
bool Load(idEntity *ent, const char *fileName)
Definition: AF.cpp:795
idClipModel * combatModel
Definition: AFEntity.h:193
void SetJointAxis(jointHandle_t jointnum, jointModTransform_t transform_type, const idMat3 &mat)
const idEventDef EV_SetLinearVelocity("setLinearVelocity","v")
void WriteJoint(const jointHandle_t value)
Definition: SaveGame.cpp:177
void SetSuspension(const float up, const float down, const float k, const float d, const float f)
idProgram program
Definition: Game_local.h:293
void SetRotation(const idMat3 &m)
void WriteBool(const bool value)
Definition: SaveGame.cpp:222
idVec4 colorRed
Definition: Lib.cpp:117
virtual void FreeModelDef(void)
Definition: AFEntity.cpp:866
void UnlinkClip(void)
idAnimator animator
Definition: Entity.h:534
bool IsHidden(void) const
Definition: Entity.cpp:1217
void SetGibTime(int _time)
Definition: Game_local.h:527
void Event_Gib(const char *damageDefName)
Definition: AFEntity.cpp:1267
idEntity * SpawnEntityType(const idTypeInfo &classdef, const idDict *args=NULL, bool bIsClientReadSnapshot=false)
idAFVector v2
Definition: DeclAF.h:92
virtual void Think(void)
Definition: AFEntity.cpp:2058
jointHandle_t eyesJoint
Definition: AFEntity.h:345
virtual const idMD5Joint * GetJoints(void) const =0
int AnimNum(void) const
idAFConstraint_Hinge * fingers[4]
Definition: AFEntity.h:521
void SetClipMask(const int mask)
Definition: Physics_AF.h:677
const int SHADERPARM_BLUE
Definition: RenderWorld.h:48
void GetPhysicsToVisualTransform(idVec3 &origin, idMat3 &axis) const
Definition: AF.cpp:404
void AddForce(idEntity *ent, int id, const idVec3 &point, const idVec3 &force)
Definition: AF.cpp:434
idVec3 offset
Definition: TraceModel.h:93
void Restore(idRestoreGame *savefile)
Definition: AFEntity.cpp:998
void Translate(const idVec3 &translation)
const idEventDef EV_SetFingerAngle("setFingerAngle","f")
declAFJointMod_t
Definition: DeclAF.h:52
idClipModel * combatModel
Definition: AFEntity.h:132
virtual void Show(void)
Definition: Entity.cpp:1239
void SetSelf(idEntity *e)
virtual void FreeEntityDef(qhandle_t entityHandle)=0
virtual void AddDamageEffect(const trace_t &collision, const idVec3 &velocity, const char *damageDefName)
Definition: Entity.cpp:3108
virtual bool LoadAF(void)
Definition: AFEntity.cpp:594
idVec4 colorYellow
Definition: Lib.cpp:120
void SetModelForId(int id, const idStr &modelName)
Definition: AFEntity.cpp:76
idStr skin
Definition: DeclAF.h:173
virtual void Restore(idRestoreGame *saveFile)
virtual void AddForce(idEntity *ent, int id, const idVec3 &point, const idVec3 &force)
Definition: AFEntity.cpp:426
virtual void Present(void)
Definition: AFEntity.cpp:87
void SetOwner(idEntity *newOwner)
Definition: Clip.h:190
idPhysics * GetPhysics(void) const
Definition: Entity.cpp:2607
void KeepRunningPhysics(void)
Definition: AFEntity.h:271
idCVar g_vehicleVelocity("g_vehicleVelocity","1000", CVAR_GAME|CVAR_FLOAT,"")
void Restore(idRestoreGame *savefile)
Definition: AFEntity.cpp:338
void Use(idPlayer *player)
Definition: AFEntity.cpp:1724
idAngles ToAngles(void) const
Definition: Vector.cpp:130
const idVec3 & ToVec3(void) const
Definition: DeclAF.h:78
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
bool SpawnEntityDef(const idDict &args, idEntity **ent=NULL, bool setDefaults=true)
void ReadFloat(float &value)
Definition: SaveGame.cpp:967
float Length(void) const
Definition: Vector.h:631
idStr & StripFileExtension(void)
Definition: Str.cpp:757
idVec3 ToForward(void) const
Definition: Angles.cpp:117
idRenderModel * skeletonModel
Definition: AFEntity.h:236
void SetSelected(idEntity *ent)
Definition: GameEdit.cpp:296
float RandomFloat(void)
Definition: Random.h:82
void SetContents(int contents, int id=-1)
bool StartSound(const char *soundName, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length)
Definition: Entity.cpp:1622
idCVar g_bloodEffects("g_bloodEffects","1", CVAR_GAME|CVAR_ARCHIVE|CVAR_BOOL,"show blood splats, sprays and gibs")
void Save(idSaveGame *savefile) const
Definition: AFEntity.cpp:553
void SaveState(idDict &args) const
Definition: AFEntity.cpp:648
void GetImpactInfo(idEntity *ent, int id, const idVec3 &point, impactInfo_t *info)
Definition: AF.cpp:414
virtual renderEntity_t * GetRenderEntity(void)
Definition: Entity.cpp:1506
int combatModelContents
Definition: AFEntity.h:194
void SetPhysics(idPhysics *phys)
Definition: Entity.cpp:2574
void Unbind(void)
Definition: Entity.cpp:2011
void SetConstraintPosition(const char *name, const idVec3 &pos)
Definition: AF.cpp:1064
virtual void GetImpactInfo(idEntity *ent, int id, const idVec3 &point, impactInfo_t *info)
Definition: Entity.cpp:2878
idVec3 ToVec3(void) const
void WriteFloat(const float value)
Definition: SaveGame.cpp:213
idPhysics_AF * GetAFPhysics(void)
Definition: AFEntity.h:170
static float Fabs(float f)
Definition: Math.h:779
idCommon * common
Definition: Common.cpp:206
idJointMat * joints
Definition: RenderWorld.h:135
bool GetBool(const char *key, const char *defaultString="0") const
Definition: Dict.h:256
Definition: Dict.h:65
#define NULL
Definition: Lib.h:88
const idMD5Anim * MD5Anim(int num) const
Definition: Anim_Blend.cpp:165
const idMD5Joint * parent
Definition: Model.h:164
virtual void GetImpactInfo(idEntity *ent, int id, const idVec3 &point, impactInfo_t *info)
Definition: AFEntity.cpp:708
idAnimBlend * CurrentAnim(int channelNum)
idAngles angles
Definition: DeclAF.h:97
const idDeclSkin * customSkin
Definition: RenderWorld.h:125
virtual idRenderModel * FindModel(const char *modelName)=0
static void DropAFs(idEntity *ent, const char *type, idList< idEntity * > *list)
Definition: AFEntity.cpp:892
virtual const idDecl * FindType(declType_t type, const char *name, bool makeDefault=true)=0
virtual void GetImpactInfo(idEntity *ent, int id, const idVec3 &point, impactInfo_t *info)
Definition: AFEntity.cpp:400
float y
Definition: Vector.h:319
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:2853
idVec3 GetVector(const char *key, const char *defaultString=NULL) const
Definition: Dict.h:260
virtual void Think(void)
Definition: AFEntity.cpp:121
void SetContactMotorVelocity(float vel)
Definition: Physics_AF.h:697
const int SHADERPARM_TIME_OF_DEATH
Definition: RenderWorld.h:54
virtual void ProjectOverlay(const idVec3 &origin, const idVec3 &dir, float size, const char *material)
Definition: AFEntity.cpp:1588
virtual void AddDamageEffect(const trace_t &collision, const idVec3 &velocity, const char *damageDefName)
Definition: AFEntity.cpp:387
virtual void SetOrigin(const idVec3 &newOrigin, int id=-1)=0
const idAnim * GetAnim(int index) const
void CycleAnim(int channelNum, int animnum, int currenttime, int blendtime)
const idVec3 & GetGravity(void) const
usercmd_t usercmd
Definition: Player.h:249
virtual void Hide(void)
Definition: AFEntity.cpp:1562
float roll
Definition: Angles.h:55
idCVar g_vehicleSuspensionUp("g_vehicleSuspensionUp","32", CVAR_GAME|CVAR_FLOAT,"")
Definition: Fx.h:54
const idEventDef EV_SetConstraintPosition("SetConstraintPosition","sv")
void Save(idSaveGame *savefile) const
Definition: AFEntity.cpp:1305
virtual idRenderModel * AF_CreateMesh(const idDict &args, idVec3 &meshOrigin, idMat3 &meshAxis, bool &poseIsSet)
Definition: AFEntity.cpp:2956
const idStr & GetValue(void) const
Definition: Dict.h:53
void Save(idSaveGame *savefile) const
Definition: AFEntity.cpp:2568
virtual const idMat3 & GetAxis(int id=0) const =0
virtual idAnimator * GetAnimator(void)
Definition: Entity.cpp:5213
virtual void UpdateEntityDef(qhandle_t entityHandle, const renderEntity_t *re)=0
float NormalizeFast(void)
Definition: Vector.h:524
const idEventDef EV_Weapon_State("weaponState","sd")
virtual void DrawText(const char *text, const idVec3 &origin, float scale, const idVec4 &color, const idMat3 &viewAxis, const int align=1, const int lifetime=0, bool depthTest=false)=0
int Find(const char c, int start=0, int end=-1) const
Definition: Str.h:874
jointHandle_t attachJoint
Definition: AFEntity.h:134
idDict spawnArgs
Definition: Script_Thread.h:86
idLinkList< idEntity > spawnNode
Definition: Entity.h:114
float pitch
Definition: Angles.h:53
idGameLocal gameLocal
Definition: Game_local.cpp:64
void SetBool(const char *key, bool val)
Definition: Dict.h:196
bool RunPhysics(void)
Definition: Entity.cpp:2616
idPhysics_AF physicsObj
Definition: AFEntity.h:56
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
void SetLinearVelocity(const idVec3 &newLinearVelocity, int id=0)
void SetAnchor(const idVec3 &worldPosition)
Definition: Physics_AF.cpp:496
void Event_Activate(idEntity *activator)
Definition: AFEntity.cpp:1627
const idVec3 & GetVisualOffset(void) const
void LockWorldConstraints(const bool lock)
Definition: Physics_AF.h:886
idAFConstraint_Suspension * suspension[4]
Definition: AFEntity.h:376
virtual void LoadModel()=0
virtual idBounds Bounds(const struct renderEntity_s *ent=NULL) const =0
idLinkList< idEntity > spawnedEntities
Definition: Game_local.h:281
void SetPosition(idPhysics *physics, int id, const idVec3 &point)
void BindToBody(idEntity *master, int bodyId, bool orientated)
Definition: Entity.cpp:1984
virtual void Hide(void)
Definition: Entity.cpp:1226
idStr jointName
Definition: DeclAF.h:89
virtual idClipModel * GetClipModel(int id=0) const =0
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 SetCombatContents(bool enable)
Definition: AFEntity.cpp:823
virtual void Save(idSaveGame *saveFile) const
idDeclManager * declManager
idAFVector v1
Definition: DeclAF.h:92
void WriteMat3(const idMat3 &mat)
Definition: SaveGame.cpp:309
idPlayer * player
Definition: AFEntity.h:344
void EnableMotor(const bool enable)
Definition: Physics_AF.h:610
idDragEntity dragEntity
Definition: Player.h:373
int GetBodyId(idAFBody *body) const
void ReadMat3(idMat3 &mat)
Definition: SaveGame.cpp:1064
idEntity * entities[MAX_GENTITIES]
Definition: Game_local.h:275
bool IsLoaded(void) const
Definition: AF.h:65
idMat3 ToMat3(void) const
virtual int GetNumDecls(declType_t type)=0
virtual void Damage(idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location)
Definition: AFEntity.cpp:374
renderEntity_t * ent
Definition: AFEntity.cpp:2915
virtual void ApplyImpulse(idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse)
Definition: AFEntity.cpp:413
int health
Definition: Entity.h:134
int BodyForClipModelId(int id) const
Definition: AFEntity.cpp:639
void ReadClipModel(idClipModel *&clipModel)
Definition: SaveGame.cpp:1519
idClipModel * GetCombatModel(void) const
Definition: AFEntity.cpp:814
int Append(const type &obj)
Definition: List.h:646
void PlayIdleAnim(int blendTime)
Definition: AFEntity.cpp:439
virtual void ApplyImpulse(idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse)
Definition: AFEntity.cpp:721
idRenderModelManager * renderModelManager
void Spawn(void)
Definition: AFEntity.cpp:1336
Definition: Matrix.h:333
const int SHADERPARM_RED
Definition: RenderWorld.h:46
void AddConstraint(idAFConstraint *constraint)
virtual bool IsDefaultModel() const =0
idAFVector origin
Definition: DeclAF.h:96
void SetForce(const idVec3 &force)
void SetClipMask(int mask, int id=-1)
float yaw
Definition: Angles.h:54
void SetConeLimit(const idVec3 &coneAxis, const float coneAngle, const idVec3 &body1Axis)
Definition: Physics_AF.cpp:549
void UpdateVisuals(void)
Definition: Entity.cpp:1310
idList< idDeclAF_Body * > bodies
Definition: DeclAF.h:189
void LoadState(const idDict &args)
Definition: AFEntity.cpp:681
GLuint id
Definition: glext.h:3103
bool GetBool(void) const
Definition: CVarSystem.h:142
virtual bool IsLoaded()=0
virtual void Show(void)
Definition: AFEntity.cpp:1575
virtual const idDecl * DeclByIndex(declType_t type, int index, bool forceParse=true)=0
virtual void LinkCombat(void)
Definition: AFEntity.cpp:841
tuple f
Definition: idal.py:89
void SetContactMotorForce(float force)
Definition: Physics_AF.h:699
idCVar g_vehicleSuspensionKCompress("g_vehicleSuspensionKCompress","200", CVAR_GAME|CVAR_FLOAT,"")
void Restore(idRestoreGame *savefile)
Definition: AFEntity.cpp:1314
bool LoadModel(const char *name)
Definition: Clip.cpp:215
idAngles viewAngles
Definition: Player.h:258
Definition: Actor.h:111
const idMat3 & ToMat3(void) const
Definition: Rotation.cpp:60
virtual void AddForce(idEntity *ent, int id, const idVec3 &point, const idVec3 &force)
Definition: Entity.cpp:2896
int Num(void) const
Definition: List.h:265
idStr model
Definition: DeclAF.h:172
void BuildChain(const idStr &name, const idVec3 &origin, float linkLength, float linkWidth, float density, int numLinks, bool bindToWorld=true)
Definition: AFEntity.cpp:147
idMat3 ToMat3(void) const
Definition: Angles.cpp:199
void Save(idSaveGame *savefile) const
Definition: AFEntity.cpp:325
signed char forwardmove
Definition: UsercmdGen.h:95
void PutToRest(void)
virtual const idBounds & GetAbsBounds(int id=-1) const =0
idMat3 spawnAxis
Definition: AFEntity.h:196
virtual bool AF_SpawnEntity(const char *fileName)
Definition: AFEntity.cpp:2806
const int GIB_DELAY
Definition: AFEntity.h:43
int modelDefHandle
Definition: Entity.h:372
idAFConstraint_Hinge * steering[4]
Definition: AFEntity.h:432
void Save(idSaveGame *savefile) const
Definition: AF.cpp:76
const GLcharARB * name
Definition: glext.h:3629
#define RAD2DEG(a)
Definition: Math.h:57
GLsizeiptr size
Definition: glext.h:3112
virtual ~idAFEntity_Base(void)
Definition: AFEntity.cpp:543
jointHandle_t wheelJoints[4]
Definition: AFEntity.h:402
bool GetJointWorldTransform(jointHandle_t jointHandle, int currentTime, idVec3 &offset, idMat3 &axis)
Definition: Entity.cpp:5248
void Translate(const idVec3 &translation, int id=-1)
virtual void Evaluate(int time)
#define CLASS_DECLARATION(nameofsuperclass, nameofclass)
Definition: Class.h:110
Definition: Str.h:116
idBounds bounds
Definition: RenderWorld.h:95
virtual void LinkCombat(void)
Definition: AFEntity.cpp:486
GLsizei const GLcharARB const GLint * length
Definition: glext.h:3599
virtual void Hide(void)
Definition: AFEntity.cpp:352
void Invalidate(void)
Definition: DeclManager.h:158
idForce_Constant force
Definition: AFEntity.h:494
void UpdateAnimation(void)
Definition: Entity.cpp:5172
void Event_SetFingerAngle(float angle)
Definition: AFEntity.cpp:2768
void Save(idSaveGame *savefile) const
Definition: Game_local.h:656
idStr name
Definition: Model.h:163
void ReadVec3(idVec3 &vec)
Definition: SaveGame.cpp:1011
idEntityPtr< idAFAttachment > head
Definition: AFEntity.h:319
void SetBody(idEntity *bodyEnt, const char *headModel, jointHandle_t attachJoint)
Definition: AFEntity.cpp:286
const char * c_str(void) const
Definition: Str.h:487
void Event_Gib(const char *damageDefName)
Definition: AFEntity.cpp:1618
void Spawn(void)
Definition: AFEntity.cpp:213
idRotation ToRotation(void) const
Definition: Matrix.cpp:246
const idAnim * GetAnim(int index) const
void ApplyImpulse(idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse)
Definition: AF.cpp:424
idEntity * body
Definition: AFEntity.h:131
void BecomeActive(int flags)
Definition: Entity.cpp:995
virtual int NumJoints(void) const =0
void RemoveBindConstraints(void)
Definition: AFEntity.cpp:699
const idEventDef EV_Remove("<immediateremove>", NULL)
void Save(idSaveGame *savefile) const
Definition: AFEntity.cpp:1455
function_t * FindFunction(const char *name) const
void SetFrame(int channelNum, int animnum, int frame, int currenttime, int blendtime)
virtual void Present(void)
Definition: AFEntity.cpp:1065
const idEventDef EV_Gibbed("<gibbed>")
virtual void Show(void)
Definition: AFEntity.cpp:362
virtual const idDeclSkin * FindSkin(const char *name, bool makeDefault=true)=0
virtual bool IsAtRest(void) const =0
void AddBindConstraints(void)
Definition: AFEntity.cpp:690
bool CheatsOk(bool requirePlayer=true)
void SetAngularVelocity(const idVec3 &newAngularVelocity, int id=0)
GLint j
Definition: qgl.h:264
idBounds & ExpandSelf(const float d)
Definition: Bounds.h:322
void SetGravity(const idVec3 &newGravity)
virtual void DebugBounds(const idVec4 &color, const idBounds &bounds, const idVec3 &org=vec3_origin, const int lifetime=0)=0
idClipModel * GetCombatModel(void) const
Definition: AFEntity.cpp:477
idVec3 GetPointVelocity(const idVec3 &point) const
void Spawn(void)
Definition: AFEntity.cpp:1686
float GetSteerAngle(void)
Definition: AFEntity.cpp:1753
qhandle_t steamModelDefHandle
Definition: AFEntity.h:496
idEntity * GetBody(void) const
Definition: AFEntity.cpp:314
idRenderWorld * gameRenderWorld
Definition: Game_local.cpp:55
void SaveState(idDict &args) const
Definition: AF.cpp:1107
char * va(const char *fmt,...)
Definition: Str.cpp:1568
void Rotate(const idRotation &rotation, int id=-1)
static idEntityFx * StartFx(const char *fx, const idVec3 *useOrigin, const idMat3 *useAxis, idEntity *ent, bool bind)
Definition: Fx.cpp:716
virtual void Think(void)
Definition: AFEntity.cpp:450
virtual bool GetPhysicsToVisualTransform(idVec3 &origin, idMat3 &axis)
Definition: Entity.cpp:2844
renderEntity_t steamRenderEntity
Definition: AFEntity.h:495
void SetOrigin(const idVec3 &org)
Definition: Entity.cpp:2784
bool PostEventMS(const idEventDef *ev, int time)
Definition: Class.cpp:666
signed char rightmove
Definition: UsercmdGen.h:96
const idMD5Joint * joints
Definition: AFEntity.cpp:2916
virtual void SetModel(const char *modelname)
Definition: Entity.cpp:5222
idCVar g_vehicleForce("g_vehicleForce","50000", CVAR_GAME|CVAR_FLOAT,"")
int thinkFlags
Definition: Entity.h:125
void Unlink(void)
Definition: Clip.cpp:491
virtual void ProjectOverlay(const idVec3 &origin, const idVec3 &dir, float size, const char *material)
Definition: Entity.cpp:1418
const idEventDef EV_Touch("<touch>","et")
bool IsActive(void) const
Definition: AF.h:74
virtual void Think(void)
Definition: AFEntity.cpp:2242
virtual void Think(void)
Definition: AFEntity.cpp:1860
void Zero(void)
Definition: Vector.h:415
idCVar g_vehicleSuspensionDown("g_vehicleSuspensionDown","20", CVAR_GAME|CVAR_FLOAT,"")
float shaderParms[MAX_ENTITY_SHADER_PARMS]
Definition: RenderWorld.h:127
void ReadString(idStr &string)
Definition: SaveGame.cpp:985
void Event_Activate(idEntity *activator)
Definition: AFEntity.cpp:1358
idList< idRenderModel * > modelHandles
Definition: AFEntity.h:61
void UpdateDamageEffects(void)
Definition: Entity.cpp:5438
virtual void UnlinkCombat(void)
Definition: AFEntity.cpp:1545
void SetMotorVelocity(const float vel)
Definition: Physics_AF.h:612
void BecomeInactive(int flags)
Definition: Entity.cpp:1025
idEntityPtr< idWeapon > weapon
Definition: Player.h:292
#define JOINT_HANDLE_TO_CLIPMODEL_ID(id)
Definition: Clip.h:41
virtual bool UpdateAnimationControllers(void)
Definition: AFEntity.cpp:786
void ReadInt(int &value)
Definition: SaveGame.cpp:922
float CRandomFloat(void)
Definition: Random.h:86
virtual ~idAFAttachment(void)
Definition: AFEntity.cpp:264
const idVec3 & GetLinearVelocity(void) const
Definition: Physics_AF.h:671
idCVar g_vehicleSuspensionDamping("g_vehicleSuspensionDamping","400", CVAR_GAME|CVAR_FLOAT,"")
void StopSound(const s_channelType channel, bool broadcast)
Definition: Entity.cpp:1713
void Save(idSaveGame *savefile) const
Definition: AFEntity.cpp:985
Definition: Anim.h:280
void Restore(idRestoreGame *savefile)
Definition: AFEntity.cpp:567
#define MS2SEC(t)
Definition: Math.h:60
const idVec3 & GetOrigin(int id=0) const
void ReadObject(idClass *&obj)
Definition: SaveGame.cpp:1083
void SetAngle(const float rotationAngle)
Definition: Rotation.h:131
virtual void SetAxis(const idMat3 &newAxis, int id=-1)=0
virtual void LinkCombat(void)
Definition: AFEntity.cpp:1524
int GetBodyContactConstraints(const int id, idAFConstraint_Contact *contacts[], int maxContacts) const