doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Mover.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 // _D3XP : rename all gameLocal.time to gameLocal.slow.time for merge!
35 
36 // a mover will update any gui entities in it's target list with
37 // a key/val pair of "mover" "state" from below.. guis can represent
38 // realtime info like this
39 // binary only
40 static const char *guiBinaryMoverStates[] = {
41  "1", // pos 1
42  "2", // pos 2
43  "3", // moving 1 to 2
44  "4" // moving 2 to 1
45 };
46 
47 
48 /*
49 ===============================================================================
50 
51 idMover
52 
53 ===============================================================================
54 */
55 
56 const idEventDef EV_FindGuiTargets( "<FindGuiTargets>", NULL );
57 const idEventDef EV_TeamBlocked( "<teamblocked>", "ee" );
58 const idEventDef EV_PartBlocked( "<partblocked>", "e" );
59 const idEventDef EV_ReachedPos( "<reachedpos>", NULL );
60 const idEventDef EV_ReachedAng( "<reachedang>", NULL );
61 const idEventDef EV_PostRestore( "<postrestore>", "ddddd" );
62 const idEventDef EV_StopMoving( "stopMoving", NULL );
63 const idEventDef EV_StopRotating( "stopRotating", NULL );
64 const idEventDef EV_Speed( "speed", "f" );
65 const idEventDef EV_Time( "time", "f" );
66 const idEventDef EV_AccelTime( "accelTime", "f" );
67 const idEventDef EV_DecelTime( "decelTime", "f" );
68 const idEventDef EV_MoveTo( "moveTo", "e" );
69 const idEventDef EV_MoveToPos( "moveToPos", "v" );
70 const idEventDef EV_Move( "move", "ff" );
71 const idEventDef EV_MoveAccelerateTo( "accelTo", "ff" );
72 const idEventDef EV_MoveDecelerateTo( "decelTo", "ff" );
73 const idEventDef EV_RotateDownTo( "rotateDownTo", "df" );
74 const idEventDef EV_RotateUpTo( "rotateUpTo", "df" );
75 const idEventDef EV_RotateTo( "rotateTo", "v" );
76 const idEventDef EV_Rotate( "rotate", "v" );
77 const idEventDef EV_RotateOnce( "rotateOnce", "v" );
78 const idEventDef EV_Bob( "bob", "ffv" );
79 const idEventDef EV_Sway( "sway", "ffv" );
80 const idEventDef EV_Mover_OpenPortal( "openPortal" );
81 const idEventDef EV_Mover_ClosePortal( "closePortal" );
82 const idEventDef EV_AccelSound( "accelSound", "s" );
83 const idEventDef EV_DecelSound( "decelSound", "s" );
84 const idEventDef EV_MoveSound( "moveSound", "s" );
85 const idEventDef EV_Mover_InitGuiTargets( "<initguitargets>", NULL );
86 const idEventDef EV_EnableSplineAngles( "enableSplineAngles", NULL );
87 const idEventDef EV_DisableSplineAngles( "disableSplineAngles", NULL );
88 const idEventDef EV_RemoveInitialSplineAngles( "removeInitialSplineAngles", NULL );
89 const idEventDef EV_StartSpline( "startSpline", "e" );
90 const idEventDef EV_StopSpline( "stopSpline", NULL );
91 const idEventDef EV_IsMoving( "isMoving", NULL, 'd' );
92 const idEventDef EV_IsRotating( "isRotating", NULL, 'd' );
93 
95  EVENT( EV_FindGuiTargets, idMover::Event_FindGuiTargets )
96  EVENT( EV_Thread_SetCallback, idMover::Event_SetCallback )
97  EVENT( EV_TeamBlocked, idMover::Event_TeamBlocked )
98  EVENT( EV_PartBlocked, idMover::Event_PartBlocked )
99  EVENT( EV_ReachedPos, idMover::Event_UpdateMove )
100  EVENT( EV_ReachedAng, idMover::Event_UpdateRotation )
101  EVENT( EV_PostRestore, idMover::Event_PostRestore )
102  EVENT( EV_StopMoving, idMover::Event_StopMoving )
103  EVENT( EV_StopRotating, idMover::Event_StopRotating )
104  EVENT( EV_Speed, idMover::Event_SetMoveSpeed )
105  EVENT( EV_Time, idMover::Event_SetMoveTime )
106  EVENT( EV_AccelTime, idMover::Event_SetAccellerationTime )
107  EVENT( EV_DecelTime, idMover::Event_SetDecelerationTime )
108  EVENT( EV_MoveTo, idMover::Event_MoveTo )
109  EVENT( EV_MoveToPos, idMover::Event_MoveToPos )
110  EVENT( EV_Move, idMover::Event_MoveDir )
111  EVENT( EV_MoveAccelerateTo, idMover::Event_MoveAccelerateTo )
112  EVENT( EV_MoveDecelerateTo, idMover::Event_MoveDecelerateTo )
113  EVENT( EV_RotateDownTo, idMover::Event_RotateDownTo )
114  EVENT( EV_RotateUpTo, idMover::Event_RotateUpTo )
115  EVENT( EV_RotateTo, idMover::Event_RotateTo )
116  EVENT( EV_Rotate, idMover::Event_Rotate )
117  EVENT( EV_RotateOnce, idMover::Event_RotateOnce )
118  EVENT( EV_Bob, idMover::Event_Bob )
119  EVENT( EV_Sway, idMover::Event_Sway )
120  EVENT( EV_Mover_OpenPortal, idMover::Event_OpenPortal )
121  EVENT( EV_Mover_ClosePortal, idMover::Event_ClosePortal )
122  EVENT( EV_AccelSound, idMover::Event_SetAccelSound )
123  EVENT( EV_DecelSound, idMover::Event_SetDecelSound )
124  EVENT( EV_MoveSound, idMover::Event_SetMoveSound )
125  EVENT( EV_Mover_InitGuiTargets, idMover::Event_InitGuiTargets )
126  EVENT( EV_EnableSplineAngles, idMover::Event_EnableSplineAngles )
127  EVENT( EV_DisableSplineAngles, idMover::Event_DisableSplineAngles )
128  EVENT( EV_RemoveInitialSplineAngles, idMover::Event_RemoveInitialSplineAngles )
129  EVENT( EV_StartSpline, idMover::Event_StartSpline )
130  EVENT( EV_StopSpline, idMover::Event_StopSpline )
131  EVENT( EV_Activate, idMover::Event_Activate )
132  EVENT( EV_IsMoving, idMover::Event_IsMoving )
133  EVENT( EV_IsRotating, idMover::Event_IsRotating )
134 END_CLASS
135 
136 /*
137 ================
138 idMover::idMover
139 ================
140 */
141 idMover::idMover( void ) {
142  memset( &move, 0, sizeof( move ) );
143  memset( &rot, 0, sizeof( rot ) );
144  move_thread = 0;
145  rotate_thread = 0;
146  dest_angles.Zero();
147  angle_delta.Zero();
148  dest_position.Zero();
149  move_delta.Zero();
150  move_speed = 0.0f;
151  move_time = 0;
152  deceltime = 0;
153  acceltime = 0;
154  stopRotation = false;
155  useSplineAngles = true;
156  lastCommand = MOVER_NONE;
157  damage = 0.0f;
158  areaPortal = 0;
159  fl.networkSync = true;
160 }
161 
162 /*
163 ================
164 idMover::Save
165 ================
166 */
167 void idMover::Save( idSaveGame *savefile ) const {
168  int i;
169 
170  savefile->WriteStaticObject( physicsObj );
171 
172  savefile->WriteInt( move.stage );
173  savefile->WriteInt( move.acceleration );
174  savefile->WriteInt( move.movetime );
175  savefile->WriteInt( move.deceleration );
176  savefile->WriteVec3( move.dir );
177 
178  savefile->WriteInt( rot.stage );
179  savefile->WriteInt( rot.acceleration );
180  savefile->WriteInt( rot.movetime );
181  savefile->WriteInt( rot.deceleration );
182  savefile->WriteFloat( rot.rot.pitch );
183  savefile->WriteFloat( rot.rot.yaw );
184  savefile->WriteFloat( rot.rot.roll );
185 
186  savefile->WriteInt( move_thread );
187  savefile->WriteInt( rotate_thread );
188 
189  savefile->WriteAngles( dest_angles );
190  savefile->WriteAngles( angle_delta );
191  savefile->WriteVec3( dest_position );
192  savefile->WriteVec3( move_delta );
193 
194  savefile->WriteFloat( move_speed );
195  savefile->WriteInt( move_time );
196  savefile->WriteInt( deceltime );
197  savefile->WriteInt( acceltime );
198  savefile->WriteBool( stopRotation );
199  savefile->WriteBool( useSplineAngles );
200  savefile->WriteInt( lastCommand );
201  savefile->WriteFloat( damage );
202 
203  savefile->WriteInt( areaPortal );
204  if ( areaPortal > 0 ) {
206  }
207 
208  savefile->WriteInt( guiTargets.Num() );
209  for( i = 0; i < guiTargets.Num(); i++ ) {
210  guiTargets[ i ].Save( savefile );
211  }
212 
213  if ( splineEnt.GetEntity() && splineEnt.GetEntity()->GetSpline() ) {
215 
216  savefile->WriteBool( true );
217  splineEnt.Save( savefile );
218  savefile->WriteInt( spline->GetTime( 0 ) );
219  savefile->WriteInt( spline->GetTime( spline->GetNumValues() - 1 ) - spline->GetTime( 0 ) );
222  savefile->WriteInt( (int)physicsObj.UsingSplineAngles() );
223 
224  } else {
225  savefile->WriteBool( false );
226  }
227 }
228 
229 /*
230 ================
231 idMover::Restore
232 ================
233 */
234 void idMover::Restore( idRestoreGame *savefile ) {
235  int i, num;
236  bool hasSpline = false;
237 
238  savefile->ReadStaticObject( physicsObj );
240 
241  savefile->ReadInt( (int&)move.stage );
242  savefile->ReadInt( move.acceleration );
243  savefile->ReadInt( move.movetime );
244  savefile->ReadInt( move.deceleration );
245  savefile->ReadVec3( move.dir );
246 
247  savefile->ReadInt( (int&)rot.stage );
248  savefile->ReadInt( rot.acceleration );
249  savefile->ReadInt( rot.movetime );
250  savefile->ReadInt( rot.deceleration );
251  savefile->ReadFloat( rot.rot.pitch );
252  savefile->ReadFloat( rot.rot.yaw );
253  savefile->ReadFloat( rot.rot.roll );
254 
255  savefile->ReadInt( move_thread );
256  savefile->ReadInt( rotate_thread );
257 
258  savefile->ReadAngles( dest_angles );
259  savefile->ReadAngles( angle_delta );
260  savefile->ReadVec3( dest_position );
261  savefile->ReadVec3( move_delta );
262 
263  savefile->ReadFloat( move_speed );
264  savefile->ReadInt( move_time );
265  savefile->ReadInt( deceltime );
266  savefile->ReadInt( acceltime );
267  savefile->ReadBool( stopRotation );
268  savefile->ReadBool( useSplineAngles );
269  savefile->ReadInt( (int &)lastCommand );
270  savefile->ReadFloat( damage );
271 
272  savefile->ReadInt( areaPortal );
273  if ( areaPortal > 0 ) {
274  int portalState = 0;
275  savefile->ReadInt( portalState );
276  gameLocal.SetPortalState( areaPortal, portalState );
277  }
278 
279  guiTargets.Clear();
280  savefile->ReadInt( num );
281  guiTargets.SetNum( num );
282  for( i = 0; i < num; i++ ) {
283  guiTargets[ i ].Restore( savefile );
284  }
285 
286  savefile->ReadBool( hasSpline );
287  if ( hasSpline ) {
288  int starttime;
289  int totaltime;
290  int accel;
291  int decel;
292  int useAngles;
293 
294  splineEnt.Restore( savefile );
295  savefile->ReadInt( starttime );
296  savefile->ReadInt( totaltime );
297  savefile->ReadInt( accel );
298  savefile->ReadInt( decel );
299  savefile->ReadInt( useAngles );
300 
301  PostEventMS( &EV_PostRestore, 0, starttime, totaltime, accel, decel, useAngles );
302  }
303 }
304 
305 /*
306 ================
307 idMover::Event_PostRestore
308 ================
309 */
310 void idMover::Event_PostRestore( int start, int total, int accel, int decel, int useSplineAng ) {
311  idCurve_Spline<idVec3> *spline;
312 
313  idEntity *splineEntity = splineEnt.GetEntity();
314  if ( !splineEntity ) {
315  // We should never get this event if splineEnt is invalid
316  common->Warning( "Invalid spline entity during restore\n" );
317  return;
318  }
319 
320  spline = splineEntity->GetSpline();
321 
322  spline->MakeUniform( total );
323  spline->ShiftTime( start - spline->GetTime( 0 ) );
324 
325  physicsObj.SetSpline( spline, accel, decel, ( useSplineAng != 0 ) );
327 }
328 
329 /*
330 ================
331 idMover::Spawn
332 ================
333 */
334 void idMover::Spawn( void ) {
335  move_thread = 0;
336  rotate_thread = 0;
337  stopRotation = false;
339 
340  acceltime = 1000.0f * spawnArgs.GetFloat( "accel_time", "0" );
341  deceltime = 1000.0f * spawnArgs.GetFloat( "decel_time", "0" );
342  move_time = 1000.0f * spawnArgs.GetFloat( "move_time", "1" ); // safe default value
343  move_speed = spawnArgs.GetFloat( "move_speed", "0" );
344 
345  spawnArgs.GetFloat( "damage" , "0", damage );
346 
349 
350  physicsObj.SetSelf( this );
351  physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f );
352  physicsObj.SetOrigin( GetPhysics()->GetOrigin() );
353  physicsObj.SetAxis( GetPhysics()->GetAxis() );
355  if ( !spawnArgs.GetBool( "solid", "1" ) ) {
356  physicsObj.SetContents( 0 );
357  }
358  if ( !renderEntity.hModel || !spawnArgs.GetBool( "nopush" ) ) {
359  physicsObj.SetPusher( 0 );
360  }
364 
365  // see if we are on an areaportal
366  areaPortal = gameRenderWorld->FindPortal( GetPhysics()->GetAbsBounds() );
367 
368  if ( spawnArgs.MatchPrefix( "guiTarget" ) ) {
371  } else {
372  // not during spawn, so it's ok to get the targets
373  FindGuiTargets();
374  }
375  }
376 
377  health = spawnArgs.GetInt( "health" );
378  if ( health ) {
379  fl.takedamage = true;
380  }
381 
382 }
383 
384 /*
385 ================
386 idMover::Hide
387 ================
388 */
389 void idMover::Hide( void ) {
390  idEntity::Hide();
391  physicsObj.SetContents( 0 );
392 }
393 
394 /*
395 ================
396 idMover::Show
397 ================
398 */
399 void idMover::Show( void ) {
400  idEntity::Show();
401  if ( spawnArgs.GetBool( "solid", "1" ) ) {
403  }
405 }
406 
407 /*
408 ============
409 idMover::Killed
410 ============
411 */
412 void idMover::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) {
413  fl.takedamage = false;
414  ActivateTargets( this );
415 }
416 
417 
418 /*
419 ================
420 idMover::Event_SetCallback
421 ================
422 */
424  if ( ( lastCommand == MOVER_ROTATING ) && !rotate_thread ) {
427  idThread::ReturnInt( true );
428  } else if ( ( lastCommand == MOVER_MOVING || lastCommand == MOVER_SPLINE ) && !move_thread ) {
431  idThread::ReturnInt( true );
432  } else {
433  idThread::ReturnInt( false );
434  }
435 }
436 
437 /*
438 ================
439 idMover::VectorForDir
440 ================
441 */
442 void idMover::VectorForDir( float angle, idVec3 &vec ) {
443  idAngles ang;
444 
445  switch( ( int )angle ) {
446  case DIR_UP :
447  vec.Set( 0, 0, 1 );
448  break;
449 
450  case DIR_DOWN :
451  vec.Set( 0, 0, -1 );
452  break;
453 
454  case DIR_LEFT :
455  physicsObj.GetLocalAngles( ang );
456  ang.pitch = 0;
457  ang.roll = 0;
458  ang.yaw += 90;
459  vec = ang.ToForward();
460  break;
461 
462  case DIR_RIGHT :
463  physicsObj.GetLocalAngles( ang );
464  ang.pitch = 0;
465  ang.roll = 0;
466  ang.yaw -= 90;
467  vec = ang.ToForward();
468  break;
469 
470  case DIR_FORWARD :
471  physicsObj.GetLocalAngles( ang );
472  ang.pitch = 0;
473  ang.roll = 0;
474  vec = ang.ToForward();
475  break;
476 
477  case DIR_BACK :
478  physicsObj.GetLocalAngles( ang );
479  ang.pitch = 0;
480  ang.roll = 0;
481  ang.yaw += 180;
482  vec = ang.ToForward();
483  break;
484 
485  case DIR_REL_UP :
486  vec.Set( 0, 0, 1 );
487  break;
488 
489  case DIR_REL_DOWN :
490  vec.Set( 0, 0, -1 );
491  break;
492 
493  case DIR_REL_LEFT :
494  physicsObj.GetLocalAngles( ang );
495  ang.ToVectors( NULL, &vec );
496  vec *= -1;
497  break;
498 
499  case DIR_REL_RIGHT :
500  physicsObj.GetLocalAngles( ang );
501  ang.ToVectors( NULL, &vec );
502  break;
503 
504  case DIR_REL_FORWARD :
505  physicsObj.GetLocalAngles( ang );
506  vec = ang.ToForward();
507  break;
508 
509  case DIR_REL_BACK :
510  physicsObj.GetLocalAngles( ang );
511  vec = ang.ToForward() * -1;
512  break;
513 
514  default:
515  ang.Set( 0, angle, 0 );
516  vec = GetWorldVector( ang.ToForward() );
517  break;
518  }
519 }
520 
521 /*
522 ================
523 idMover::FindGuiTargets
524 ================
525 */
527  gameLocal.GetTargets( spawnArgs, guiTargets, "guiTarget" );
528 }
529 
530 /*
531 ==============================
532 idMover::SetGuiState
533 
534 key/val will be set to any renderEntity->gui's on the list
535 ==============================
536 */
537 void idMover::SetGuiState( const char *key, const char *val ) const {
538  gameLocal.Printf( "Setting %s to %s\n", key, val );
539  for( int i = 0; i < guiTargets.Num(); i++ ) {
540  idEntity *ent = guiTargets[ i ].GetEntity();
541  if ( ent ) {
542  for ( int j = 0; j < MAX_RENDERENTITY_GUI; j++ ) {
543  if ( ent->GetRenderEntity() && ent->GetRenderEntity()->gui[ j ] ) {
544  ent->GetRenderEntity()->gui[ j ]->SetStateString( key, val );
545  ent->GetRenderEntity()->gui[ j ]->StateChanged( gameLocal.slow.time, true );
546  }
547  }
548  ent->UpdateVisuals();
549  }
550  }
551 }
552 
553 /*
554 ================
555 idMover::Event_InitGuiTargets
556 ================
557 */
559  FindGuiTargets();
560 }
561 
562 /*
563 ================
564 idMover::SetGuiStates
565 ================
566 */
567 void idMover::SetGuiStates( const char *state ) {
568  int i;
569  if ( guiTargets.Num() ) {
570  SetGuiState( "movestate", state );
571  }
572  for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) {
573  if ( renderEntity.gui[ i ] ) {
574  renderEntity.gui[ i ]->SetStateString( "movestate", state );
575  renderEntity.gui[ i ]->StateChanged( gameLocal.slow.time, true );
576  }
577  }
578 }
579 
580 /*
581 ================
582 idMover::Event_InitGuiTargets
583 ================
584 */
586  SetGuiStates( guiBinaryMoverStates[MOVER_POS1] );
587 }
588 
589 /***********************************************************************
590 
591  Translation control functions
592 
593 ***********************************************************************/
594 
595 /*
596 ================
597 idMover::Event_StopMoving
598 ================
599 */
602  DoneMoving();
603 }
604 
605 /*
606 ================
607 idMover::DoneMoving
608 ================
609 */
610 void idMover::DoneMoving( void ) {
611 
612  if ( lastCommand != MOVER_SPLINE ) {
613  // set our final position so that we get rid of any numerical inaccuracy
615  }
616 
619  move_thread = 0;
620 
621  StopSound( SND_CHANNEL_BODY, false );
622 }
623 
624 /*
625 ================
626 idMover::UpdateMoveSound
627 ================
628 */
630  switch( stage ) {
631  case ACCELERATION_STAGE: {
632  StartSound( "snd_accel", SND_CHANNEL_BODY2, 0, false, NULL );
633  StartSound( "snd_move", SND_CHANNEL_BODY, 0, false, NULL );
634  break;
635  }
636  case LINEAR_STAGE: {
637  StartSound( "snd_move", SND_CHANNEL_BODY, 0, false, NULL );
638  break;
639  }
640  case DECELERATION_STAGE: {
641  StopSound( SND_CHANNEL_BODY, false );
642  StartSound( "snd_decel", SND_CHANNEL_BODY2, 0, false, NULL );
643  break;
644  }
645  case FINISHED_STAGE: {
646  StopSound( SND_CHANNEL_BODY, false );
647  break;
648  }
649  }
650 }
651 
652 /*
653 ================
654 idMover::Event_UpdateMove
655 ================
656 */
658  idVec3 org;
659 
660  physicsObj.GetLocalOrigin( org );
661 
663 
664  switch( move.stage ) {
665  case ACCELERATION_STAGE: {
667  if ( move.movetime > 0 ) {
669  } else if ( move.deceleration > 0 ) {
671  } else {
673  }
674  break;
675  }
676  case LINEAR_STAGE: {
678  if ( move.deceleration ) {
680  } else {
682  }
683  break;
684  }
685  case DECELERATION_STAGE: {
688  break;
689  }
690  case FINISHED_STAGE: {
691  if ( g_debugMover.GetBool() ) {
692  gameLocal.Printf( "%d: '%s' move done\n", gameLocal.slow.time, name.c_str() );
693  }
694  DoneMoving();
695  break;
696  }
697  }
698 }
699 
700 /*
701 ================
702 idMover::BeginMove
703 ================
704 */
705 void idMover::BeginMove( idThread *thread ) {
706  moveStage_t stage;
707  idVec3 org;
708  float dist;
709  float acceldist;
710  int totalacceltime;
711  int at;
712  int dt;
713 
715  move_thread = 0;
716 
717  physicsObj.GetLocalOrigin( org );
718 
719  move_delta = dest_position - org;
720  if ( move_delta.Compare( vec3_zero ) ) {
721  DoneMoving();
722  return;
723  }
724 
725  // scale times up to whole physics frames
727  move_time += at - acceltime;
728  acceltime = at;
730  move_time += dt - deceltime;
731  deceltime = dt;
732 
733  // if we're moving at a specific speed, we need to calculate the move time
734  if ( move_speed ) {
735  dist = move_delta.Length();
736 
737  totalacceltime = acceltime + deceltime;
738 
739  // calculate the distance we'll move during acceleration and deceleration
740  acceldist = totalacceltime * 0.5f * 0.001f * move_speed;
741  if ( acceldist >= dist ) {
742  // going too slow for this distance to move at a constant speed
743  move_time = totalacceltime;
744  } else {
745  // calculate move time taking acceleration into account
746  move_time = totalacceltime + 1000.0f * ( dist - acceldist ) / move_speed;
747  }
748  }
749 
750  // scale time up to a whole physics frames
752 
753  if ( acceltime ) {
754  stage = ACCELERATION_STAGE;
755  } else if ( move_time <= deceltime ) {
756  stage = DECELERATION_STAGE;
757  } else {
758  stage = LINEAR_STAGE;
759  }
760 
761  at = acceltime;
762  dt = deceltime;
763 
764  if ( at + dt > move_time ) {
765  // there's no real correct way to handle this, so we just scale
766  // the times to fit into the move time in the same proportions
767  at = idPhysics::SnapTimeToPhysicsFrame( at * move_time / ( at + dt ) );
768  dt = move_time - at;
769  }
770 
771  move_delta = move_delta * ( 1000.0f / ( (float) move_time - ( at + dt ) * 0.5f ) );
772 
773  move.stage = stage;
774  move.acceleration = at;
775  move.movetime = move_time - at - dt;
776  move.deceleration = dt;
777  move.dir = move_delta;
778 
780 }
781 
782 /***********************************************************************
783 
784  Rotation control functions
785 
786 ***********************************************************************/
787 
788 /*
789 ================
790 idMover::Event_StopRotating
791 ================
792 */
796  DoneRotating();
797 }
798 
799 /*
800 ================
801 idMover::DoneRotating
802 ================
803 */
804 void idMover::DoneRotating( void ) {
807  rotate_thread = 0;
808 
809  StopSound( SND_CHANNEL_BODY, false );
810 }
811 
812 /*
813 ================
814 idMover::UpdateRotationSound
815 ================
816 */
818  switch( stage ) {
819  case ACCELERATION_STAGE: {
820  StartSound( "snd_accel", SND_CHANNEL_BODY2, 0, false, NULL );
821  StartSound( "snd_move", SND_CHANNEL_BODY, 0, false, NULL );
822  break;
823  }
824  case LINEAR_STAGE: {
825  StartSound( "snd_move", SND_CHANNEL_BODY, 0, false, NULL );
826  break;
827  }
828  case DECELERATION_STAGE: {
829  StopSound( SND_CHANNEL_BODY, false );
830  StartSound( "snd_decel", SND_CHANNEL_BODY2, 0, false, NULL );
831  break;
832  }
833  case FINISHED_STAGE: {
834  StopSound( SND_CHANNEL_BODY, false );
835  break;
836  }
837  }
838 }
839 
840 /*
841 ================
842 idMover::Event_UpdateRotation
843 ================
844 */
846  idAngles ang;
847 
848  physicsObj.GetLocalAngles( ang );
849 
851 
852  switch( rot.stage ) {
853  case ACCELERATION_STAGE: {
855  if ( rot.movetime > 0 ) {
857  } else if ( rot.deceleration > 0 ) {
859  } else {
861  }
862  break;
863  }
864  case LINEAR_STAGE: {
865  if ( !stopRotation && !rot.deceleration ) {
867  } else {
869  }
870 
871  if ( rot.deceleration ) {
873  } else {
875  }
876  break;
877  }
878  case DECELERATION_STAGE: {
881  break;
882  }
883  case FINISHED_STAGE: {
885  if ( stopRotation ) {
886  // set our final angles so that we get rid of any numerical inaccuracy
889  stopRotation = false;
891  // keep our angular velocity constant
893  }
894 
895  if ( g_debugMover.GetBool() ) {
896  gameLocal.Printf( "%d: '%s' rotation done\n", gameLocal.slow.time, name.c_str() );
897  }
898 
899  DoneRotating();
900  break;
901  }
902  }
903 }
904 
905 /*
906 ================
907 idMover::BeginRotation
908 ================
909 */
910 void idMover::BeginRotation( idThread *thread, bool stopwhendone ) {
911  moveStage_t stage;
912  idAngles ang;
913  int at;
914  int dt;
915 
917  rotate_thread = 0;
918 
919  // rotation always uses move_time so that if a move was started before the rotation,
920  // the rotation will take the same amount of time as the move. If no move has been
921  // started and no time is set, the rotation takes 1 second.
922  if ( !move_time ) {
923  move_time = 1;
924  }
925 
926  physicsObj.GetLocalAngles( ang );
927  angle_delta = dest_angles - ang;
928  if ( angle_delta == ang_zero ) {
929  // set our final angles so that we get rid of any numerical inaccuracy
932  stopRotation = false;
933  DoneRotating();
934  return;
935  }
936 
937  // scale times up to whole physics frames
939  move_time += at - acceltime;
940  acceltime = at;
942  move_time += dt - deceltime;
943  deceltime = dt;
945 
946  if ( acceltime ) {
947  stage = ACCELERATION_STAGE;
948  } else if ( move_time <= deceltime ) {
949  stage = DECELERATION_STAGE;
950  } else {
951  stage = LINEAR_STAGE;
952  }
953 
954  at = acceltime;
955  dt = deceltime;
956 
957  if ( at + dt > move_time ) {
958  // there's no real correct way to handle this, so we just scale
959  // the times to fit into the move time in the same proportions
960  at = idPhysics::SnapTimeToPhysicsFrame( at * move_time / ( at + dt ) );
961  dt = move_time - at;
962  }
963 
964  angle_delta = angle_delta * ( 1000.0f / ( (float) move_time - ( at + dt ) * 0.5f ) );
965 
966  stopRotation = stopwhendone || ( dt != 0 );
967 
968  rot.stage = stage;
969  rot.acceleration = at;
970  rot.movetime = move_time - at - dt;
971  rot.deceleration = dt;
972  rot.rot = angle_delta;
973 
975 }
976 
977 
978 /***********************************************************************
979 
980  Script callable routines
981 
982 ***********************************************************************/
983 
984 /*
985 ===============
986 idMover::Event_TeamBlocked
987 ===============
988 */
989 void idMover::Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity ) {
990  if ( g_debugMover.GetBool() ) {
991  gameLocal.Printf( "%d: '%s' stopped due to team member '%s' blocked by '%s'\n", gameLocal.slow.time, name.c_str(), blockedEntity->name.c_str(), blockingEntity->name.c_str() );
992  }
993 }
994 
995 /*
996 ===============
997 idMover::Event_PartBlocked
998 ===============
999 */
1000 void idMover::Event_PartBlocked( idEntity *blockingEntity ) {
1001  if ( damage > 0.0f ) {
1002  blockingEntity->Damage( this, this, vec3_origin, "damage_moverCrush", damage, INVALID_JOINT );
1003  }
1004  if ( g_debugMover.GetBool() ) {
1005  gameLocal.Printf( "%d: '%s' blocked by '%s'\n", gameLocal.slow.time, name.c_str(), blockingEntity->name.c_str() );
1006  }
1007 }
1008 
1009 /*
1010 ================
1011 idMover::Event_SetMoveSpeed
1012 ================
1013 */
1014 void idMover::Event_SetMoveSpeed( float speed ) {
1015  if ( speed <= 0 ) {
1016  gameLocal.Error( "Cannot set speed less than or equal to 0." );
1017  }
1018 
1019  move_speed = speed;
1020  move_time = 0; // move_time is calculated for each move when move_speed is non-0
1021 }
1022 
1023 /*
1024 ================
1025 idMover::Event_SetMoveTime
1026 ================
1027 */
1028 void idMover::Event_SetMoveTime( float time ) {
1029  if ( time <= 0 ) {
1030  gameLocal.Error( "Cannot set time less than or equal to 0." );
1031  }
1032 
1033  move_speed = 0;
1034  move_time = SEC2MS( time );
1035 }
1036 
1037 /*
1038 ================
1039 idMover::Event_SetAccellerationTime
1040 ================
1041 */
1043  if ( time < 0 ) {
1044  gameLocal.Error( "Cannot set acceleration time less than 0." );
1045  }
1046 
1047  acceltime = SEC2MS( time );
1048 }
1049 
1050 /*
1051 ================
1052 idMover::Event_SetDecelerationTime
1053 ================
1054 */
1056  if ( time < 0 ) {
1057  gameLocal.Error( "Cannot set deceleration time less than 0." );
1058  }
1059 
1060  deceltime = SEC2MS( time );
1061 }
1062 
1063 /*
1064 ================
1065 idMover::Event_MoveTo
1066 ================
1067 */
1069  if ( !ent ) {
1070  gameLocal.Warning( "Entity not found" );
1071  }
1072 
1075 }
1076 
1077 /*
1078 ================
1079 idMover::MoveToPos
1080 ================
1081 */
1082 void idMover::MoveToPos( const idVec3 &pos ) {
1084  BeginMove( NULL );
1085 }
1086 
1087 /*
1088 ================
1089 idMover::Event_MoveToPos
1090 ================
1091 */
1093  MoveToPos( pos );
1094 }
1095 
1096 /*
1097 ================
1098 idMover::Event_MoveDir
1099 ================
1100 */
1101 void idMover::Event_MoveDir( float angle, float distance ) {
1102  idVec3 dir;
1103  idVec3 org;
1104 
1105  physicsObj.GetLocalOrigin( org );
1106  VectorForDir( angle, dir );
1107  dest_position = org + dir * distance;
1108 
1110 }
1111 
1112 /*
1113 ================
1114 idMover::Event_MoveAccelerateTo
1115 ================
1116 */
1117 void idMover::Event_MoveAccelerateTo( float speed, float time ) {
1118  float v;
1119  idVec3 org, dir;
1120  int at;
1121 
1122  if ( time < 0 ) {
1123  gameLocal.Error( "idMover::Event_MoveAccelerateTo: cannot set acceleration time less than 0." );
1124  }
1125 
1126  dir = physicsObj.GetLinearVelocity();
1127  v = dir.Normalize();
1128 
1129  // if not moving already
1130  if ( v == 0.0f ) {
1131  gameLocal.Error( "idMover::Event_MoveAccelerateTo: not moving." );
1132  }
1133 
1134  // if already moving faster than the desired speed
1135  if ( v >= speed ) {
1136  return;
1137  }
1138 
1139  at = idPhysics::SnapTimeToPhysicsFrame( SEC2MS( time ) );
1140 
1142 
1143  physicsObj.GetLocalOrigin( org );
1144 
1146  move.acceleration = at;
1147  move.movetime = 0;
1148  move.deceleration = 0;
1149 
1150  StartSound( "snd_accel", SND_CHANNEL_BODY2, 0, false, NULL );
1151  StartSound( "snd_move", SND_CHANNEL_BODY, 0, false, NULL );
1152  physicsObj.SetLinearExtrapolation( EXTRAPOLATION_ACCELLINEAR, gameLocal.slow.time, move.acceleration, org, dir * ( speed - v ), dir * v );
1153 }
1154 
1155 /*
1156 ================
1157 idMover::Event_MoveDecelerateTo
1158 ================
1159 */
1160 void idMover::Event_MoveDecelerateTo( float speed, float time ) {
1161  float v;
1162  idVec3 org, dir;
1163  int dt;
1164 
1165  if ( time < 0 ) {
1166  gameLocal.Error( "idMover::Event_MoveDecelerateTo: cannot set deceleration time less than 0." );
1167  }
1168 
1169  dir = physicsObj.GetLinearVelocity();
1170  v = dir.Normalize();
1171 
1172  // if not moving already
1173  if ( v == 0.0f ) {
1174  gameLocal.Error( "idMover::Event_MoveDecelerateTo: not moving." );
1175  }
1176 
1177  // if already moving slower than the desired speed
1178  if ( v <= speed ) {
1179  return;
1180  }
1181 
1182  dt = idPhysics::SnapTimeToPhysicsFrame( SEC2MS( time ) );
1183 
1185 
1186  physicsObj.GetLocalOrigin( org );
1187 
1189  move.acceleration = 0;
1190  move.movetime = 0;
1191  move.deceleration = dt;
1192 
1193  StartSound( "snd_decel", SND_CHANNEL_BODY2, 0, false, NULL );
1194  StartSound( "snd_move", SND_CHANNEL_BODY, 0, false, NULL );
1195  physicsObj.SetLinearExtrapolation( EXTRAPOLATION_DECELLINEAR, gameLocal.slow.time, move.deceleration, org, dir * ( v - speed ), dir * speed );
1196 }
1197 
1198 /*
1199 ================
1200 idMover::Event_RotateDownTo
1201 ================
1202 */
1203 void idMover::Event_RotateDownTo( int axis, float angle ) {
1204  idAngles ang;
1205 
1206  if ( ( axis < 0 ) || ( axis > 2 ) ) {
1207  gameLocal.Error( "Invalid axis" );
1208  }
1209 
1210  physicsObj.GetLocalAngles( ang );
1211 
1212  dest_angles[ axis ] = angle;
1213  if ( dest_angles[ axis ] > ang[ axis ] ) {
1214  dest_angles[ axis ] -= 360;
1215  }
1216 
1218 }
1219 
1220 /*
1221 ================
1222 idMover::Event_RotateUpTo
1223 ================
1224 */
1225 void idMover::Event_RotateUpTo( int axis, float angle ) {
1226  idAngles ang;
1227 
1228  if ( ( axis < 0 ) || ( axis > 2 ) ) {
1229  gameLocal.Error( "Invalid axis" );
1230  }
1231 
1232  physicsObj.GetLocalAngles( ang );
1233 
1234  dest_angles[ axis ] = angle;
1235  if ( dest_angles[ axis ] < ang[ axis ] ) {
1236  dest_angles[ axis ] += 360;
1237  }
1238 
1240 }
1241 
1242 /*
1243 ================
1244 idMover::Event_RotateTo
1245 ================
1246 */
1248  dest_angles = angles;
1250 }
1251 
1252 /*
1253 ================
1254 idMover::Event_Rotate
1255 ================
1256 */
1258  idAngles ang;
1259 
1260  if ( rotate_thread ) {
1261  DoneRotating();
1262  }
1263 
1264  physicsObj.GetLocalAngles( ang );
1265  dest_angles = ang + angles * ( move_time - ( acceltime + deceltime ) / 2 ) * 0.001f;
1266 
1268 }
1269 
1270 /*
1271 ================
1272 idMover::Event_RotateOnce
1273 ================
1274 */
1276  idAngles ang;
1277 
1278  if ( rotate_thread ) {
1279  DoneRotating();
1280  }
1281 
1282  physicsObj.GetLocalAngles( ang );
1283  dest_angles = ang + angles;
1284 
1286 }
1287 
1288 /*
1289 ================
1290 idMover::Event_Bob
1291 ================
1292 */
1293 void idMover::Event_Bob( float speed, float phase, idVec3 &depth ) {
1294  idVec3 org;
1295 
1296  physicsObj.GetLocalOrigin( org );
1297  physicsObj.SetLinearExtrapolation( extrapolation_t(EXTRAPOLATION_DECELSINE|EXTRAPOLATION_NOSTOP), speed * 1000 * phase, speed * 500, org, depth * 2.0f, vec3_origin );
1298 }
1299 
1300 /*
1301 ================
1302 idMover::Event_Sway
1303 ================
1304 */
1305 void idMover::Event_Sway( float speed, float phase, idAngles &depth ) {
1306  idAngles ang, angSpeed;
1307  float duration;
1308 
1309  physicsObj.GetLocalAngles( ang );
1310  assert ( speed > 0.0f );
1311  duration = idMath::Sqrt( depth[0] * depth[0] + depth[1] * depth[1] + depth[2] * depth[2] ) / speed;
1312  angSpeed = depth / ( duration * idMath::SQRT_1OVER2 );
1313  physicsObj.SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_DECELSINE|EXTRAPOLATION_NOSTOP), duration * 1000.0f * phase, duration * 1000.0f, ang, angSpeed, ang_zero );
1314 }
1315 
1316 /*
1317 ================
1318 idMover::Event_OpenPortal
1319 
1320 Sets the portal associtated with this mover to be open
1321 ================
1322 */
1324  if ( areaPortal ) {
1325  SetPortalState( true );
1326  }
1327 }
1328 
1329 /*
1330 ================
1331 idMover::Event_ClosePortal
1332 
1333 Sets the portal associtated with this mover to be closed
1334 ================
1335 */
1337  if ( areaPortal ) {
1338  SetPortalState( false );
1339  }
1340 }
1341 
1342 /*
1343 ================
1344 idMover::Event_SetAccelSound
1345 ================
1346 */
1347 void idMover::Event_SetAccelSound( const char *sound ) {
1348 // refSound.SetSound( "accel", sound );
1349 }
1350 
1351 /*
1352 ================
1353 idMover::Event_SetDecelSound
1354 ================
1355 */
1356 void idMover::Event_SetDecelSound( const char *sound ) {
1357 // refSound.SetSound( "decel", sound );
1358 }
1359 
1360 /*
1361 ================
1362 idMover::Event_SetMoveSound
1363 ================
1364 */
1365 void idMover::Event_SetMoveSound( const char *sound ) {
1366 // refSound.SetSound( "move", sound );
1367 }
1368 
1369 /*
1370 ================
1371 idMover::Event_EnableSplineAngles
1372 ================
1373 */
1375  useSplineAngles = true;
1376 }
1377 
1378 /*
1379 ================
1380 idMover::Event_DisableSplineAngles
1381 ================
1382 */
1384  useSplineAngles = false;
1385 }
1386 
1387 /*
1388 ================
1389 idMover::Event_RemoveInitialSplineAngles
1390 ================
1391 */
1393  idCurve_Spline<idVec3> *spline;
1394  idAngles ang;
1395 
1396  spline = physicsObj.GetSpline();
1397  if ( !spline ) {
1398  return;
1399  }
1400  ang = spline->GetCurrentFirstDerivative( 0 ).ToAngles();
1402 }
1403 
1404 /*
1405 ================
1406 idMover::Event_StartSpline
1407 ================
1408 */
1409 void idMover::Event_StartSpline( idEntity *splineEntity ) {
1410  idCurve_Spline<idVec3> *spline;
1411 
1412  if ( !splineEntity ) {
1413  return;
1414  }
1415 
1416  // Needed for savegames
1417  splineEnt = splineEntity;
1418 
1419  spline = splineEntity->GetSpline();
1420  if ( !spline ) {
1421  return;
1422  }
1423 
1425  move_thread = 0;
1426 
1427  if ( acceltime + deceltime > move_time ) {
1428  acceltime = move_time / 2;
1430  }
1435 
1436  spline->MakeUniform( move_time );
1437  spline->ShiftTime( gameLocal.slow.time - spline->GetTime( 0 ) );
1438 
1441 }
1442 
1443 /*
1444 ================
1445 idMover::Event_StopSpline
1446 ================
1447 */
1450  splineEnt = NULL;
1451 }
1452 
1453 /*
1454 ================
1455 idMover::Event_Activate
1456 ================
1457 */
1458 void idMover::Event_Activate( idEntity *activator ) {
1459  Show();
1460  Event_StartSpline( this );
1461 }
1462 
1463 /*
1464 ================
1465 idMover::Event_IsMoving
1466 ================
1467 */
1470  idThread::ReturnInt( false );
1471  } else {
1472  idThread::ReturnInt( true );
1473  }
1474 }
1475 
1476 /*
1477 ================
1478 idMover::Event_IsRotating
1479 ================
1480 */
1483  idThread::ReturnInt( false );
1484  } else {
1485  idThread::ReturnInt( true );
1486  }
1487 }
1488 
1489 /*
1490 ================
1491 idMover::WriteToSnapshot
1492 ================
1493 */
1495  physicsObj.WriteToSnapshot( msg );
1496  msg.WriteBits( move.stage, 3 );
1497  msg.WriteBits( rot.stage, 3 );
1498  WriteBindToSnapshot( msg );
1499  WriteGUIToSnapshot( msg );
1500 }
1501 
1502 /*
1503 ================
1504 idMover::ReadFromSnapshot
1505 ================
1506 */
1508  moveStage_t oldMoveStage = move.stage;
1509  moveStage_t oldRotStage = rot.stage;
1510 
1512  move.stage = (moveStage_t) msg.ReadBits( 3 );
1513  rot.stage = (moveStage_t) msg.ReadBits( 3 );
1514  ReadBindFromSnapshot( msg );
1515  ReadGUIFromSnapshot( msg );
1516 
1517  if ( msg.HasChanged() ) {
1518  if ( move.stage != oldMoveStage ) {
1519  UpdateMoveSound( oldMoveStage );
1520  }
1521  if ( rot.stage != oldRotStage ) {
1522  UpdateRotationSound( oldRotStage );
1523  }
1524  UpdateVisuals();
1525  }
1526 }
1527 
1528 /*
1529 ================
1530 idMover::SetPortalState
1531 ================
1532 */
1533 void idMover::SetPortalState( bool open ) {
1534  assert( areaPortal );
1536 }
1537 
1538 /*
1539 ===============================================================================
1540 
1541  idSplinePath, holds a spline path to be used by an idMover
1542 
1543 ===============================================================================
1544 */
1545 
1547 END_CLASS
1548 
1549 /*
1550 ================
1551 idSplinePath::idSplinePath
1552 ================
1553 */
1555 }
1556 
1557 /*
1558 ================
1559 idSplinePath::Spawn
1560 ================
1561 */
1562 void idSplinePath::Spawn( void ) {
1563 }
1564 
1565 
1566 /*
1567 ===============================================================================
1568 
1569 idElevator
1570 
1571 ===============================================================================
1572 */
1573 const idEventDef EV_PostArrival( "postArrival", NULL );
1574 const idEventDef EV_GotoFloor( "gotoFloor", "d" );
1575 #ifdef _D3XP
1576 const idEventDef EV_SetGuiStates( "setGuiStates" );
1577 #endif
1578 
1580  EVENT( EV_Activate, idElevator::Event_Activate )
1581  EVENT( EV_TeamBlocked, idElevator::Event_TeamBlocked )
1582  EVENT( EV_PartBlocked, idElevator::Event_PartBlocked )
1583  EVENT( EV_PostArrival, idElevator::Event_PostFloorArrival )
1584  EVENT( EV_GotoFloor, idElevator::Event_GotoFloor )
1585  EVENT( EV_Touch, idElevator::Event_Touch )
1586 #ifdef _D3XP
1587  EVENT( EV_SetGuiStates, idElevator::Event_SetGuiStates )
1588 #endif
1589 END_CLASS
1590 
1591 /*
1592 ================
1593 idElevator::idElevator
1594 ================
1595 */
1597  state = INIT;
1598  floorInfo.Clear();
1599  currentFloor = 0;
1600  pendingFloor = 0;
1601  lastFloor = 0;
1602  controlsDisabled = false;
1603  lastTouchTime = 0;
1604  returnFloor = 0;
1605  returnTime = 0;
1606 }
1607 
1608 /*
1609 ================
1610 idElevator::Save
1611 ================
1612 */
1613 void idElevator::Save( idSaveGame *savefile ) const {
1614  int i;
1615 
1616  savefile->WriteInt( (int)state );
1617 
1618  savefile->WriteInt( floorInfo.Num() );
1619  for ( i = 0; i < floorInfo.Num(); i++ ) {
1620  savefile->WriteVec3( floorInfo[ i ].pos );
1621  savefile->WriteString( floorInfo[ i ].door );
1622  savefile->WriteInt( floorInfo[ i ].floor );
1623  }
1624 
1625  savefile->WriteInt( currentFloor );
1626  savefile->WriteInt( pendingFloor );
1627  savefile->WriteInt( lastFloor );
1628  savefile->WriteBool( controlsDisabled );
1629  savefile->WriteFloat( returnTime );
1630  savefile->WriteInt( returnFloor );
1631  savefile->WriteInt( lastTouchTime );
1632 }
1633 
1634 /*
1635 ================
1636 idElevator::Restore
1637 ================
1638 */
1640  int i, num;
1641 
1642  savefile->ReadInt( (int &)state );
1643 
1644  savefile->ReadInt( num );
1645  for ( i = 0; i < num; i++ ) {
1646  floorInfo_s floor;
1647 
1648  savefile->ReadVec3( floor.pos );
1649  savefile->ReadString( floor.door );
1650  savefile->ReadInt( floor.floor );
1651 
1652  floorInfo.Append( floor );
1653  }
1654 
1655  savefile->ReadInt( currentFloor );
1656  savefile->ReadInt( pendingFloor );
1657  savefile->ReadInt( lastFloor );
1658  savefile->ReadBool( controlsDisabled );
1659  savefile->ReadFloat( returnTime );
1660  savefile->ReadInt( returnFloor );
1661  savefile->ReadInt( lastTouchTime );
1662 }
1663 
1664 /*
1665 ================
1666 idElevator::Spawn
1667 ================
1668 */
1669 void idElevator::Spawn( void ) {
1670  idStr str;
1671  int len1;
1672 
1673  lastFloor = 0;
1674  currentFloor = 0;
1675  pendingFloor = spawnArgs.GetInt( "floor", "1" );
1676  SetGuiStates( ( pendingFloor == 1 ) ? guiBinaryMoverStates[0] : guiBinaryMoverStates[1]);
1677 
1678  returnTime = spawnArgs.GetFloat( "returnTime" );
1679  returnFloor = spawnArgs.GetInt( "returnFloor" );
1680 
1681  len1 = strlen( "floorPos_" );
1682  const idKeyValue *kv = spawnArgs.MatchPrefix( "floorPos_", NULL );
1683  while( kv ) {
1684  str = kv->GetKey().Right( kv->GetKey().Length() - len1 );
1685  floorInfo_s fi;
1686  fi.floor = atoi( str );
1687  fi.door = spawnArgs.GetString( va( "floorDoor_%i", fi.floor ) );
1688  fi.pos = spawnArgs.GetVector( kv->GetKey() );
1689  floorInfo.Append( fi );
1690  kv = spawnArgs.MatchPrefix( "floorPos_", kv );
1691  }
1692  lastTouchTime = 0;
1693  state = INIT;
1696  controlsDisabled = false;
1697 }
1698 
1699 /*
1700 ==============
1701 idElevator::Event_Touch
1702 ===============
1703 */
1704 void idElevator::Event_Touch( idEntity *other, trace_t *trace ) {
1705 
1706  if ( gameLocal.slow.time < lastTouchTime + 2000 ) {
1707  return;
1708  }
1709 
1710  if ( !other->IsType( idPlayer::Type ) ) {
1711  return;
1712  }
1713 
1714  lastTouchTime = gameLocal.slow.time;
1715 
1716  if ( thinkFlags & TH_PHYSICS ) {
1717  return;
1718  }
1719 
1720  int triggerFloor = spawnArgs.GetInt( "triggerFloor" );
1721  if ( spawnArgs.GetBool( "trigger" ) && triggerFloor != currentFloor ) {
1722  PostEventSec( &EV_GotoFloor, 0.25f, triggerFloor );
1723  }
1724 }
1725 
1726 /*
1727 ================
1728 idElevator::Think
1729 ================
1730 */
1731 void idElevator::Think( void ) {
1732  idVec3 masterOrigin;
1733  idMat3 masterAxis;
1734  idDoor *doorent = GetDoor( spawnArgs.GetString( "innerdoor" ) );
1735  if ( state == INIT ) {
1736  state = IDLE;
1737  if ( doorent ) {
1738  doorent->BindTeam( this );
1739  doorent->spawnArgs.Set( "snd_open", "" );
1740  doorent->spawnArgs.Set( "snd_close", "" );
1741  doorent->spawnArgs.Set( "snd_opened", "" );
1742  }
1743  for ( int i = 0; i < floorInfo.Num(); i++ ) {
1744  idDoor *door = GetDoor( floorInfo[i].door );
1745  if ( door ) {
1746  door->SetCompanion( doorent );
1747  }
1748  }
1749 
1751  DisableAllDoors();
1752  SetGuiStates( ( pendingFloor == 1 ) ? guiBinaryMoverStates[0] : guiBinaryMoverStates[1] );
1753  } else if ( state == WAITING_ON_DOORS ) {
1754  if ( doorent ) {
1755  state = doorent->IsOpen() ? WAITING_ON_DOORS : IDLE;
1756  } else {
1757  state = IDLE;
1758  }
1759  if ( state == IDLE ) {
1763  if ( fi ) {
1764  MoveToPos( fi->pos );
1765  }
1766  }
1767  }
1768  RunPhysics();
1769  Present();
1770 }
1771 
1772 /*
1773 ================
1774 idElevator::Event_Activate
1775 ================
1776 */
1778  int triggerFloor = spawnArgs.GetInt( "triggerFloor" );
1779  if ( spawnArgs.GetBool( "trigger" ) && triggerFloor != currentFloor ) {
1780  Event_GotoFloor( triggerFloor );
1781  }
1782 }
1783 
1784 /*
1785 ================
1786 idElevator::Event_TeamBlocked
1787 ================
1788 */
1789 void idElevator::Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity ) {
1790  if ( blockedEntity == this ) {
1792  } else if ( blockedEntity && blockedEntity->IsType( idDoor::Type ) ) {
1793  // open the inner doors if one is blocked
1794  idDoor *blocked = static_cast<idDoor *>( blockedEntity );
1795  idDoor *door = GetDoor( spawnArgs.GetString( "innerdoor" ) );
1796  if ( door && blocked->GetMoveMaster() == door->GetMoveMaster() ) {
1797  door->SetBlocked(true);
1798  OpenInnerDoor();
1800  }
1801  }
1802 }
1803 
1804 /*
1805 ===============
1806 idElevator::HandleSingleGuiCommand
1807 ===============
1808 */
1810  idToken token;
1811 
1812  if ( controlsDisabled ) {
1813  return false;
1814  }
1815 
1816  if ( !src->ReadToken( &token ) ) {
1817  return false;
1818  }
1819 
1820  if ( token == ";" ) {
1821  return false;
1822  }
1823 
1824  if ( token.Icmp( "changefloor" ) == 0 ) {
1825  if ( src->ReadToken( &token ) ) {
1826  int newFloor = atoi( token );
1827  if ( newFloor == currentFloor ) {
1828  // open currentFloor and interior doors
1829  OpenInnerDoor();
1831  } else {
1832  idDoor *door = GetDoor( spawnArgs.GetString( "innerdoor" ) );
1833  if ( door && door->IsOpen() ) {
1834  PostEventSec( &EV_GotoFloor, 0.5f, newFloor );
1835  } else {
1836  ProcessEvent( &EV_GotoFloor, newFloor );
1837  }
1838  }
1839  return true;
1840  }
1841  }
1842 
1843  src->UnreadToken( &token );
1844  return false;
1845 }
1846 
1847 /*
1848 ================
1849 idElevator::OpenFloorDoor
1850 ================
1851 */
1852 void idElevator::OpenFloorDoor( int floor ) {
1853  floorInfo_s *fi = GetFloorInfo( floor );
1854  if ( fi ) {
1855  idDoor *door = GetDoor( fi->door );
1856  if ( door ) {
1857  door->Open();
1858  }
1859  }
1860 }
1861 
1862 /*
1863 ================
1864 idElevator::OpenInnerDoor
1865 ================
1866 */
1868  idDoor *door = GetDoor( spawnArgs.GetString( "innerdoor" ) );
1869  if ( door ) {
1870  door->Open();
1871  }
1872 }
1873 
1874 /*
1875 ================
1876 idElevator::GetFloorInfo
1877 ================
1878 */
1880  for ( int i = 0; i < floorInfo.Num(); i++ ) {
1881  if ( floorInfo[i].floor == floor ) {
1882  return &floorInfo[i];
1883  }
1884  }
1885  return NULL;
1886 }
1887 
1888 /*
1889 ================
1890 idElevator::Event_GotoFloor
1891 ================
1892 */
1893 void idElevator::Event_GotoFloor( int floor ) {
1894  floorInfo_s *fi = GetFloorInfo( floor );
1895  if ( fi ) {
1896  idDoor *door = GetDoor( spawnArgs.GetString( "innerdoor" ) );
1897  if ( door ) {
1898  if ( door->IsBlocked() || door->IsOpen() ) {
1899  PostEventSec( &EV_GotoFloor, 0.5f, floor );
1900  return;
1901  }
1902  }
1903  DisableAllDoors();
1904  CloseAllDoors();
1906  pendingFloor = floor;
1907  }
1908 }
1909 
1910 /*
1911 ================
1912 idElevator::BeginMove
1913 ================
1914 */
1916  controlsDisabled = true;
1917  CloseAllDoors();
1918  DisableAllDoors();
1919  const idKeyValue *kv = spawnArgs.MatchPrefix( "statusGui" );
1920  while( kv ) {
1921  idEntity *ent = gameLocal.FindEntity( kv->GetValue() );
1922  if ( ent ) {
1923  for ( int j = 0; j < MAX_RENDERENTITY_GUI; j++ ) {
1924  if ( ent->GetRenderEntity() && ent->GetRenderEntity()->gui[ j ] ) {
1925  ent->GetRenderEntity()->gui[ j ]->SetStateString( "floor", "" );
1926  ent->GetRenderEntity()->gui[ j ]->StateChanged( gameLocal.slow.time, true );
1927  }
1928  }
1929  ent->UpdateVisuals();
1930  }
1931  kv = spawnArgs.MatchPrefix( "statusGui", kv );
1932  }
1933  SetGuiStates( ( pendingFloor == 1 ) ? guiBinaryMoverStates[3] : guiBinaryMoverStates[2] );
1934  idMover::BeginMove( thread );
1935 }
1936 
1937 /*
1938 ================
1939 idElevator::GetDoor
1940 ================
1941 */
1943  idEntity *ent;
1944  idEntity *master;
1945  idDoor *doorEnt;
1946 
1947  doorEnt = NULL;
1948  if ( name && *name ) {
1949  ent = gameLocal.FindEntity( name );
1950  if ( ent && ent->IsType( idDoor::Type ) ) {
1951  doorEnt = static_cast<idDoor*>( ent );
1952  master = doorEnt->GetMoveMaster();
1953  if ( master != doorEnt ) {
1954  if ( master->IsType( idDoor::Type ) ) {
1955  doorEnt = static_cast<idDoor*>( master );
1956  } else {
1957  doorEnt = NULL;
1958  }
1959  }
1960  }
1961  }
1962 
1963  return doorEnt;
1964 }
1965 
1966 /*
1967 ================
1968 idElevator::Event_PostFloorArrival
1969 ================
1970 */
1973  OpenInnerDoor();
1974  SetGuiStates( ( currentFloor == 1 ) ? guiBinaryMoverStates[0] : guiBinaryMoverStates[1] );
1975  controlsDisabled = false;
1976  if ( returnTime > 0.0f && returnFloor != currentFloor ) {
1977  PostEventSec( &EV_GotoFloor, returnTime, returnFloor );
1978  }
1979 }
1980 
1981 #ifdef _D3XP
1982 void idElevator::Event_SetGuiStates() {
1983  SetGuiStates( ( currentFloor == 1 ) ? guiBinaryMoverStates[0] : guiBinaryMoverStates[1] );
1984 }
1985 #endif
1986 
1987 /*
1988 ================
1989 idElevator::DoneMoving
1990 ================
1991 */
1995  const idKeyValue *kv = spawnArgs.MatchPrefix( "statusGui" );
1996  while( kv ) {
1997  idEntity *ent = gameLocal.FindEntity( kv->GetValue() );
1998  if ( ent ) {
1999  for ( int j = 0; j < MAX_RENDERENTITY_GUI; j++ ) {
2000  if ( ent->GetRenderEntity() && ent->GetRenderEntity()->gui[ j ] ) {
2001  ent->GetRenderEntity()->gui[ j ]->SetStateString( "floor", va( "%i", currentFloor ) );
2002  ent->GetRenderEntity()->gui[ j ]->StateChanged( gameLocal.slow.time, true );
2003  }
2004  }
2005  ent->UpdateVisuals();
2006  }
2007  kv = spawnArgs.MatchPrefix( "statusGui", kv );
2008  }
2009  if ( spawnArgs.GetInt( "pauseOnFloor", "-1" ) == currentFloor ) {
2010  PostEventSec( &EV_PostArrival, spawnArgs.GetFloat( "pauseTime" ) );
2011  } else {
2013  }
2014 }
2015 
2016 /*
2017 ================
2018 idElevator::CloseAllDoors
2019 ================
2020 */
2022  idDoor *door = GetDoor( spawnArgs.GetString( "innerdoor" ) );
2023  if ( door ) {
2024  door->Close();
2025  }
2026  for ( int i = 0; i < floorInfo.Num(); i++ ) {
2027  door = GetDoor( floorInfo[i].door );
2028  if ( door ) {
2029  door->Close();
2030  }
2031  }
2032 }
2033 
2034 /*
2035 ================
2036 idElevator::DisableAllDoors
2037 ================
2038 */
2040  idDoor *door = GetDoor( spawnArgs.GetString( "innerdoor" ) );
2041  if ( door ) {
2042  door->Enable( false );
2043  }
2044  for ( int i = 0; i < floorInfo.Num(); i++ ) {
2045  door = GetDoor( floorInfo[i].door );
2046  if ( door ) {
2047  door->Enable( false );
2048  }
2049  }
2050 }
2051 
2052 /*
2053 ================
2054 idElevator::EnableProperDoors
2055 ================
2056 */
2058  idDoor *door = GetDoor( spawnArgs.GetString( "innerdoor" ) );
2059  if ( door ) {
2060  door->Enable( true );
2061  }
2062  for ( int i = 0; i < floorInfo.Num(); i++ ) {
2063  if ( floorInfo[i].floor == currentFloor ) {
2064  door = GetDoor( floorInfo[i].door );
2065  if ( door ) {
2066  door->Enable( true );
2067  break;
2068  }
2069  }
2070  }
2071 }
2072 
2073 
2074 /*
2075 ===============================================================================
2076 
2077 idMover_Binary
2078 
2079 Doors, plats, and buttons are all binary (two position) movers
2080 Pos1 is "at rest", pos2 is "activated"
2081 
2082 ===============================================================================
2083 */
2084 
2085 const idEventDef EV_Mover_ReturnToPos1( "<returntopos1>", NULL );
2086 const idEventDef EV_Mover_MatchTeam( "<matchteam>", "dd" );
2087 const idEventDef EV_Mover_Enable( "enable", NULL );
2088 const idEventDef EV_Mover_Disable( "disable", NULL );
2089 
2091  EVENT( EV_FindGuiTargets, idMover_Binary::Event_FindGuiTargets )
2092  EVENT( EV_Thread_SetCallback, idMover_Binary::Event_SetCallback )
2093  EVENT( EV_Mover_ReturnToPos1, idMover_Binary::Event_ReturnToPos1 )
2094  EVENT( EV_Activate, idMover_Binary::Event_Use_BinaryMover )
2095  EVENT( EV_ReachedPos, idMover_Binary::Event_Reached_BinaryMover )
2096  EVENT( EV_Mover_MatchTeam, idMover_Binary::Event_MatchActivateTeam )
2097  EVENT( EV_Mover_Enable, idMover_Binary::Event_Enable )
2098  EVENT( EV_Mover_Disable, idMover_Binary::Event_Disable )
2099  EVENT( EV_Mover_OpenPortal, idMover_Binary::Event_OpenPortal )
2100  EVENT( EV_Mover_ClosePortal, idMover_Binary::Event_ClosePortal )
2101  EVENT( EV_Mover_InitGuiTargets, idMover_Binary::Event_InitGuiTargets )
2102 END_CLASS
2103 
2104 /*
2105 ================
2106 idMover_Binary::idMover_Binary()
2107 ================
2108 */
2110  pos1.Zero();
2111  pos2.Zero();
2112  moverState = MOVER_POS1;
2113  moveMaster = NULL;
2114  activateChain = NULL;
2115  soundPos1 = 0;
2116  sound1to2 = 0;
2117  sound2to1 = 0;
2118  soundPos2 = 0;
2119  soundLoop = 0;
2120  wait = 0.0f;
2121  damage = 0.0f;
2122  duration = 0;
2123  accelTime = 0;
2124  decelTime = 0;
2125  activatedBy = this;
2126  stateStartTime = 0;
2127  team.Clear();
2128  enabled = false;
2129  move_thread = 0;
2130  updateStatus = 0;
2131  areaPortal = 0;
2132  blocked = false;
2133 #ifdef _D3XP
2134  playerOnly = false;
2135 #endif
2136  fl.networkSync = true;
2137 }
2138 
2139 /*
2140 ================
2141 idMover_Binary::~idMover_Binary
2142 ================
2143 */
2145  idMover_Binary *mover;
2146 
2147  // if this is the mover master
2148  if ( this == moveMaster ) {
2149  // make the next mover in the chain the move master
2150  for ( mover = moveMaster; mover; mover = mover->activateChain ) {
2151  mover->moveMaster = this->activateChain;
2152  }
2153  }
2154  else {
2155  // remove mover from the activate chain
2156  for ( mover = moveMaster; mover; mover = mover->activateChain ) {
2157  if ( mover->activateChain == this ) {
2158  mover->activateChain = this->activateChain;
2159  break;
2160  }
2161  }
2162  }
2163 }
2164 
2165 /*
2166 ================
2167 idMover_Binary::Save
2168 ================
2169 */
2170 void idMover_Binary::Save( idSaveGame *savefile ) const {
2171  int i;
2172 
2173  savefile->WriteVec3( pos1 );
2174  savefile->WriteVec3( pos2 );
2175  savefile->WriteInt( (moverState_t)moverState );
2176 
2177  savefile->WriteObject( moveMaster );
2178  savefile->WriteObject( activateChain );
2179 
2180  savefile->WriteInt( soundPos1 );
2181  savefile->WriteInt( sound1to2 );
2182  savefile->WriteInt( sound2to1 );
2183  savefile->WriteInt( soundPos2 );
2184  savefile->WriteInt( soundLoop );
2185 
2186  savefile->WriteFloat( wait );
2187  savefile->WriteFloat( damage );
2188 
2189  savefile->WriteInt( duration );
2190  savefile->WriteInt( accelTime );
2191  savefile->WriteInt( decelTime );
2192 
2193  activatedBy.Save( savefile );
2194 
2195  savefile->WriteInt( stateStartTime );
2196  savefile->WriteString( team );
2197  savefile->WriteBool( enabled );
2198 
2199  savefile->WriteInt( move_thread );
2200  savefile->WriteInt( updateStatus );
2201 
2202  savefile->WriteInt( buddies.Num() );
2203  for ( i = 0; i < buddies.Num(); i++ ) {
2204  savefile->WriteString( buddies[ i ] );
2205  }
2206 
2207  savefile->WriteStaticObject( physicsObj );
2208 
2209  savefile->WriteInt( areaPortal );
2210  if ( areaPortal ) {
2212  }
2213  savefile->WriteBool( blocked );
2214 #ifdef _D3XP
2215  savefile->WriteBool( playerOnly );
2216 #endif
2217 
2218  savefile->WriteInt( guiTargets.Num() );
2219  for( i = 0; i < guiTargets.Num(); i++ ) {
2220  guiTargets[ i ].Save( savefile );
2221  }
2222 }
2223 
2224 /*
2225 ================
2226 idMover_Binary::Restore
2227 ================
2228 */
2230  int i, num, portalState;
2231  idStr temp;
2232 
2233  savefile->ReadVec3( pos1 );
2234  savefile->ReadVec3( pos2 );
2235  savefile->ReadInt( (int &)moverState );
2236 
2237  savefile->ReadObject( reinterpret_cast<idClass *&>( moveMaster ) );
2238  savefile->ReadObject( reinterpret_cast<idClass *&>( activateChain ) );
2239 
2240  savefile->ReadInt( soundPos1 );
2241  savefile->ReadInt( sound1to2 );
2242  savefile->ReadInt( sound2to1 );
2243  savefile->ReadInt( soundPos2 );
2244  savefile->ReadInt( soundLoop );
2245 
2246  savefile->ReadFloat( wait );
2247  savefile->ReadFloat( damage );
2248 
2249  savefile->ReadInt( duration );
2250  savefile->ReadInt( accelTime );
2251  savefile->ReadInt( decelTime );
2252 
2253  activatedBy.Restore( savefile );
2254 
2255  savefile->ReadInt( stateStartTime );
2256 
2257  savefile->ReadString( team );
2258  savefile->ReadBool( enabled );
2259 
2260  savefile->ReadInt( move_thread );
2261  savefile->ReadInt( updateStatus );
2262 
2263  savefile->ReadInt( num );
2264  for ( i = 0; i < num; i++ ) {
2265  savefile->ReadString( temp );
2266  buddies.Append( temp );
2267  }
2268 
2269  savefile->ReadStaticObject( physicsObj );
2271 
2272  savefile->ReadInt( areaPortal );
2273  if ( areaPortal ) {
2274  savefile->ReadInt( portalState );
2275  gameLocal.SetPortalState( areaPortal, portalState );
2276  }
2277  savefile->ReadBool( blocked );
2278 #ifdef _D3XP
2279  savefile->ReadBool( playerOnly );
2280 #endif
2281 
2282  guiTargets.Clear();
2283  savefile->ReadInt( num );
2284  guiTargets.SetNum( num );
2285  for( i = 0; i < num; i++ ) {
2286  guiTargets[ i ].Restore( savefile );
2287  }
2288 }
2289 
2290 /*
2291 ================
2292 idMover_Binary::Spawn
2293 
2294 Base class for all movers.
2295 
2296 "wait" wait before returning (3 default, -1 = never return)
2297 "speed" movement speed
2298 ================
2299 */
2301  idEntity *ent;
2302  const char *temp;
2303 
2304  move_thread = 0;
2305  enabled = true;
2306  areaPortal = 0;
2307 
2308  activateChain = NULL;
2309 
2310  spawnArgs.GetFloat( "wait", "0", wait );
2311 
2312  spawnArgs.GetInt( "updateStatus", "0", updateStatus );
2313 
2314  const idKeyValue *kv = spawnArgs.MatchPrefix( "buddy", NULL );
2315  while( kv ) {
2316  buddies.Append( kv->GetValue() );
2317  kv = spawnArgs.MatchPrefix( "buddy", kv );
2318  }
2319 
2320  spawnArgs.GetString( "team", "", &temp );
2321  team = temp;
2322 
2323  if ( !team.Length() ) {
2324  ent = this;
2325  } else {
2326  // find the first entity spawned on this team (which could be us)
2327  for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) {
2328  if ( ent->IsType( idMover_Binary::Type ) && !idStr::Icmp( static_cast<idMover_Binary *>(ent)->team.c_str(), temp ) ) {
2329  break;
2330  }
2331  }
2332  if ( !ent ) {
2333  ent = this;
2334  }
2335  }
2336  moveMaster = static_cast<idMover_Binary *>(ent);
2337 
2338  // create a physics team for the binary mover parts
2339  if ( ent != this ) {
2340  JoinTeam( ent );
2341  }
2342 
2343  physicsObj.SetSelf( this );
2344  physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f );
2345  physicsObj.SetOrigin( GetPhysics()->GetOrigin() );
2346  physicsObj.SetAxis( GetPhysics()->GetAxis() );
2348  if ( !spawnArgs.GetBool( "solid", "1" ) ) {
2349  physicsObj.SetContents( 0 );
2350  }
2351  if ( !spawnArgs.GetBool( "nopush" ) ) {
2352  physicsObj.SetPusher( 0 );
2353  }
2356  SetPhysics( &physicsObj );
2357 
2358  if ( moveMaster != this ) {
2360  }
2361 
2362  idBounds soundOrigin;
2363  idMover_Binary *slave;
2364 
2365  soundOrigin.Clear();
2366  for ( slave = moveMaster; slave != NULL; slave = slave->activateChain ) {
2367  soundOrigin += slave->GetPhysics()->GetAbsBounds();
2368  }
2369  moveMaster->refSound.origin = soundOrigin.GetCenter();
2370 
2371  if ( spawnArgs.MatchPrefix( "guiTarget" ) ) {
2372  if ( gameLocal.GameState() == GAMESTATE_STARTUP ) {
2374  } else {
2375  // not during spawn, so it's ok to get the targets
2376  FindGuiTargets();
2377  }
2378  }
2379 }
2380 
2381 /*
2382 ===============
2383 idMover_Binary::GetMovedir
2384 
2385 The editor only specifies a single value for angles (yaw),
2386 but we have special constants to generate an up or down direction.
2387 Angles will be cleared, because it is being used to represent a direction
2388 instead of an orientation.
2389 ===============
2390 */
2391 void idMover_Binary::GetMovedir( float angle, idVec3 &movedir ) {
2392  if ( angle == -1 ) {
2393  movedir.Set( 0, 0, 1 );
2394  } else if ( angle == -2 ) {
2395  movedir.Set( 0, 0, -1 );
2396  } else {
2397  movedir = idAngles( 0, angle, 0 ).ToForward();
2398  }
2399 }
2400 
2401 /*
2402 ================
2403 idMover_Binary::Event_SetCallback
2404 ================
2405 */
2407  if ( ( moverState == MOVER_1TO2 ) || ( moverState == MOVER_2TO1 ) ) {
2409  idThread::ReturnInt( true );
2410  } else {
2411  idThread::ReturnInt( false );
2412  }
2413 }
2414 
2415 /*
2416 ===============
2417 idMover_Binary::UpdateMoverSound
2418 ===============
2419 */
2421  if ( moveMaster == this ) {
2422  switch( state ) {
2423  case MOVER_POS1:
2424  break;
2425  case MOVER_POS2:
2426  break;
2427  case MOVER_1TO2:
2428  StartSound( "snd_open", SND_CHANNEL_ANY, 0, false, NULL );
2429  break;
2430  case MOVER_2TO1:
2431  StartSound( "snd_close", SND_CHANNEL_ANY, 0, false, NULL );
2432  break;
2433  }
2434  }
2435 }
2436 
2437 /*
2438 ===============
2439 idMover_Binary::SetMoverState
2440 ===============
2441 */
2442 void idMover_Binary::SetMoverState( moverState_t newstate, int time ) {
2443  idVec3 delta;
2444 
2445  moverState = newstate;
2446  move_thread = 0;
2447 
2448  UpdateMoverSound( newstate );
2449 
2450  stateStartTime = time;
2451  switch( moverState ) {
2452  case MOVER_POS1: {
2455  break;
2456  }
2457  case MOVER_POS2: {
2460  break;
2461  }
2462  case MOVER_1TO2: {
2465  if ( accelTime != 0 || decelTime != 0 ) {
2467  } else {
2468  physicsObj.SetLinearInterpolation( 0, 0, 0, 0, pos1, pos2 );
2469  }
2470  break;
2471  }
2472  case MOVER_2TO1: {
2475  if ( accelTime != 0 || decelTime != 0 ) {
2477  } else {
2478  physicsObj.SetLinearInterpolation( 0, 0, 0, 0, pos1, pos2 );
2479  }
2480  break;
2481  }
2482  }
2483 }
2484 
2485 /*
2486 ================
2487 idMover_Binary::MatchActivateTeam
2488 
2489 All entities in a mover team will move from pos1 to pos2
2490 in the same amount of time
2491 ================
2492 */
2494  idMover_Binary *slave;
2495 
2496  for ( slave = this; slave != NULL; slave = slave->activateChain ) {
2497  slave->SetMoverState( newstate, time );
2498  }
2499 }
2500 
2501 /*
2502 ================
2503 idMover_Binary::Enable
2504 ================
2505 */
2507  enabled = b;
2508 }
2509 
2510 /*
2511 ================
2512 idMover_Binary::Event_MatchActivateTeam
2513 ================
2514 */
2516  MatchActivateTeam( newstate, time );
2517 }
2518 
2519 /*
2520 ================
2521 idMover_Binary::BindTeam
2522 
2523 All entities in a mover team will be bound
2524 ================
2525 */
2527  idMover_Binary *slave;
2528 
2529  for ( slave = this; slave != NULL; slave = slave->activateChain ) {
2530  slave->Bind( bindTo, true );
2531  }
2532 }
2533 
2534 /*
2535 ================
2536 idMover_Binary::JoinActivateTeam
2537 
2538 Set all entities in a mover team to be enabled
2539 ================
2540 */
2542  this->activateChain = master->activateChain;
2543  master->activateChain = this;
2544 }
2545 
2546 /*
2547 ================
2548 idMover_Binary::Event_Enable
2549 
2550 Set all entities in a mover team to be enabled
2551 ================
2552 */
2554  idMover_Binary *slave;
2555 
2556  for ( slave = moveMaster; slave != NULL; slave = slave->activateChain ) {
2557  slave->Enable( false );
2558  }
2559 }
2560 
2561 /*
2562 ================
2563 idMover_Binary::Event_Disable
2564 
2565 Set all entities in a mover team to be disabled
2566 ================
2567 */
2569  idMover_Binary *slave;
2570 
2571  for ( slave = moveMaster; slave != NULL; slave = slave->activateChain ) {
2572  slave->Enable( false );
2573  }
2574 }
2575 
2576 /*
2577 ================
2578 idMover_Binary::Event_OpenPortal
2579 
2580 Sets the portal associtated with this mover to be open
2581 ================
2582 */
2584  idMover_Binary *slave;
2585 
2586  for ( slave = moveMaster; slave != NULL; slave = slave->activateChain ) {
2587  if ( slave->areaPortal ) {
2588  slave->SetPortalState( true );
2589  }
2590 #ifdef _D3XP
2591  if ( slave->playerOnly ) {
2593  }
2594 #endif
2595  }
2596 }
2597 
2598 /*
2599 ================
2600 idMover_Binary::Event_ClosePortal
2601 
2602 Sets the portal associtated with this mover to be closed
2603 ================
2604 */
2606  idMover_Binary *slave;
2607 
2608  for ( slave = moveMaster; slave != NULL; slave = slave->activateChain ) {
2609  if ( !slave->IsHidden() ) {
2610  if ( slave->areaPortal ) {
2611  slave->SetPortalState( false );
2612  }
2613 #ifdef _D3XP
2614  if ( slave->playerOnly ) {
2616  }
2617 #endif
2618  }
2619  }
2620 }
2621 
2622 /*
2623 ================
2624 idMover_Binary::Event_ReturnToPos1
2625 ================
2626 */
2629 }
2630 
2631 /*
2632 ================
2633 idMover_Binary::Event_Reached_BinaryMover
2634 ================
2635 */
2637 
2638  if ( moverState == MOVER_1TO2 ) {
2639  // reached pos2
2641  move_thread = 0;
2642 
2643  if ( moveMaster == this ) {
2644  StartSound( "snd_opened", SND_CHANNEL_ANY, 0, false, NULL );
2645  }
2646 
2648 
2649  SetGuiStates( guiBinaryMoverStates[MOVER_POS2] );
2650 
2651  UpdateBuddies( 1 );
2652 
2653  if ( enabled && wait >= 0 && !spawnArgs.GetBool( "toggle" ) ) {
2654  // return to pos1 after a delay
2656  }
2657 
2658  // fire targets
2660 
2661  SetBlocked(false);
2662  } else if ( moverState == MOVER_2TO1 ) {
2663  // reached pos1
2665  move_thread = 0;
2666 
2668 
2669  SetGuiStates( guiBinaryMoverStates[MOVER_POS1] );
2670 
2671  UpdateBuddies( 0 );
2672 
2673  // close areaportals
2674  if ( moveMaster == this ) {
2676  }
2677 
2678  if ( enabled && wait >= 0 && spawnArgs.GetBool( "continuous" ) ) {
2679  PostEventSec( &EV_Activate, wait, this );
2680  }
2681  SetBlocked(false);
2682  } else {
2683  gameLocal.Error( "Event_Reached_BinaryMover: bad moverState" );
2684  }
2685 }
2686 
2687 /*
2688 ================
2689 idMover_Binary::GotoPosition1
2690 ================
2691 */
2693  idMover_Binary *slave;
2694  int partial;
2695 
2696  // only the master should control this
2697  if ( moveMaster != this ) {
2699  return;
2700  }
2701 
2702  SetGuiStates( guiBinaryMoverStates[MOVER_2TO1] );
2703 
2704  if ( ( moverState == MOVER_POS1 ) || ( moverState == MOVER_2TO1 ) ) {
2705  // already there, or on the way
2706  return;
2707  }
2708 
2709  if ( moverState == MOVER_POS2 ) {
2710  for ( slave = this; slave != NULL; slave = slave->activateChain ) {
2712  }
2713  if ( !spawnArgs.GetBool( "toggle" ) ) {
2715  }
2716  return;
2717  }
2718 
2719  // only partway up before reversing
2720  if ( moverState == MOVER_1TO2 ) {
2721  // use the physics times because this might be executed during the physics simulation
2723  assert( partial >= 0 );
2724  if ( partial < 0 ) {
2725  partial = 0;
2726  }
2727  MatchActivateTeam( MOVER_2TO1, physicsObj.GetTime() - partial );
2728  // if already at at position 1 (partial == duration) execute the reached event
2729  if ( partial >= duration ) {
2731  }
2732  }
2733 }
2734 
2735 /*
2736 ================
2737 idMover_Binary::GotoPosition2
2738 ================
2739 */
2741  int partial;
2742 
2743  // only the master should control this
2744  if ( moveMaster != this ) {
2746  return;
2747  }
2748 
2749  SetGuiStates( guiBinaryMoverStates[MOVER_1TO2] );
2750 
2751  if ( ( moverState == MOVER_POS2 ) || ( moverState == MOVER_1TO2 ) ) {
2752  // already there, or on the way
2753  return;
2754  }
2755 
2756  if ( moverState == MOVER_POS1 ) {
2757  MatchActivateTeam( MOVER_1TO2, gameLocal.slow.time );
2758 
2759  // open areaportal
2761  return;
2762  }
2763 
2764 
2765  // only partway up before reversing
2766  if ( moverState == MOVER_2TO1 ) {
2767  // use the physics times because this might be executed during the physics simulation
2769  assert( partial >= 0 );
2770  if ( partial < 0 ) {
2771  partial = 0;
2772  }
2773  MatchActivateTeam( MOVER_1TO2, physicsObj.GetTime() - partial );
2774  // if already at at position 2 (partial == duration) execute the reached event
2775  if ( partial >= duration ) {
2777  }
2778  }
2779 }
2780 
2781 /*
2782 ================
2783 idMover_Binary::UpdateBuddies
2784 ================
2785 */
2787  int i, c;
2788 
2789  if ( updateStatus == 2 ) {
2790  c = buddies.Num();
2791  for ( i = 0; i < c; i++ ) {
2792  idEntity *buddy = gameLocal.FindEntity( buddies[i] );
2793  if ( buddy ) {
2794  buddy->SetShaderParm( SHADERPARM_MODE, val );
2795  buddy->UpdateVisuals();
2796  }
2797  }
2798  }
2799 }
2800 
2801 /*
2802 ================
2803 idMover_Binary::SetGuiStates
2804 ================
2805 */
2806 void idMover_Binary::SetGuiStates( const char *state ) {
2807  if ( guiTargets.Num() ) {
2808  SetGuiState( "movestate", state );
2809  }
2810 
2812  while( mb ) {
2813  if ( mb->guiTargets.Num() ) {
2814  mb->SetGuiState( "movestate", state );
2815  }
2816  mb = mb->activateChain;
2817  }
2818 }
2819 
2820 /*
2821 ================
2822 idMover_Binary::Use_BinaryMover
2823 ================
2824 */
2826  // only the master should be used
2827  if ( moveMaster != this ) {
2828  moveMaster->Use_BinaryMover( activator );
2829  return;
2830  }
2831 
2832  if ( !enabled ) {
2833  return;
2834  }
2835 
2836  activatedBy = activator;
2837 
2838  if ( moverState == MOVER_POS1 ) {
2839  // FIXME: start moving USERCMD_MSEC later, because if this was player
2840  // triggered, gameLocal.time hasn't been advanced yet
2842 
2843  SetGuiStates( guiBinaryMoverStates[MOVER_1TO2] );
2844  // open areaportal
2846  return;
2847  }
2848 
2849  // if all the way up, just delay before coming down
2850  if ( moverState == MOVER_POS2 ) {
2851  idMover_Binary *slave;
2852 
2853  if ( wait == -1 ) {
2854  return;
2855  }
2856 
2857  SetGuiStates( guiBinaryMoverStates[MOVER_2TO1] );
2858 
2859  for ( slave = this; slave != NULL; slave = slave->activateChain ) {
2861  slave->PostEventSec( &EV_Mover_ReturnToPos1, spawnArgs.GetBool( "toggle" ) ? 0 : wait );
2862  }
2863  return;
2864  }
2865 
2866  // only partway down before reversing
2867  if ( moverState == MOVER_2TO1 ) {
2868  GotoPosition2();
2869  return;
2870  }
2871 
2872  // only partway up before reversing
2873  if ( moverState == MOVER_1TO2 ) {
2874  GotoPosition1();
2875  return;
2876  }
2877 }
2878 
2879 /*
2880 ================
2881 idMover_Binary::Event_Use_BinaryMover
2882 ================
2883 */
2885  Use_BinaryMover( activator );
2886 }
2887 
2888 /*
2889 ================
2890 idMover_Binary::PreBind
2891 ================
2892 */
2896 }
2897 
2898 /*
2899 ================
2900 idMover_Binary::PostBind
2901 ================
2902 */
2906 }
2907 
2908 /*
2909 ================
2910 idMover_Binary::FindGuiTargets
2911 ================
2912 */
2914  gameLocal.GetTargets( spawnArgs, guiTargets, "guiTarget" );
2915 }
2916 
2917 /*
2918 ==============================
2919 idMover_Binary::SetGuiState
2920 
2921 key/val will be set to any renderEntity->gui's on the list
2922 ==============================
2923 */
2924 void idMover_Binary::SetGuiState( const char *key, const char *val ) const {
2925  int i;
2926 
2927  for( i = 0; i < guiTargets.Num(); i++ ) {
2928  idEntity *ent = guiTargets[ i ].GetEntity();
2929  if ( ent ) {
2930  for ( int j = 0; j < MAX_RENDERENTITY_GUI; j++ ) {
2931  if ( ent->GetRenderEntity() && ent->GetRenderEntity()->gui[ j ] ) {
2932  ent->GetRenderEntity()->gui[ j ]->SetStateString( key, val );
2933  ent->GetRenderEntity()->gui[ j ]->StateChanged( gameLocal.slow.time, true );
2934  }
2935  }
2936  ent->UpdateVisuals();
2937  }
2938  }
2939 }
2940 
2941 /*
2942 ================
2943 idMover_Binary::Event_InitGuiTargets
2944 ================
2945 */
2947  FindGuiTargets();
2948 }
2949 
2950 /*
2951 ================
2952 idMover_Binary::Event_InitGuiTargets
2953 ================
2954 */
2956  if ( guiTargets.Num() ) {
2957  SetGuiState( "movestate", guiBinaryMoverStates[MOVER_POS1] );
2958  }
2959 }
2960 
2961 /*
2962 ================
2963 idMover_Binary::InitSpeed
2964 
2965 pos1, pos2, and speed are passed in so the movement delta can be calculated
2966 ================
2967 */
2968 void idMover_Binary::InitSpeed( idVec3 &mpos1, idVec3 &mpos2, float mspeed, float maccelTime, float mdecelTime ) {
2969  idVec3 move;
2970  float distance;
2971  float speed;
2972 
2973  pos1 = mpos1;
2974  pos2 = mpos2;
2975 
2978 
2979  speed = mspeed ? mspeed : 100;
2980 
2981  // calculate time to reach second position from speed
2982  move = pos2 - pos1;
2983  distance = move.Length();
2984  duration = idPhysics::SnapTimeToPhysicsFrame( distance * 1000 / speed );
2985  if ( duration <= 0 ) {
2986  duration = 1;
2987  }
2988 
2990 
2993  SetOrigin( pos1 );
2994 
2996 }
2997 
2998 /*
2999 ================
3000 idMover_Binary::InitTime
3001 
3002 pos1, pos2, and time are passed in so the movement delta can be calculated
3003 ================
3004 */
3005 void idMover_Binary::InitTime( idVec3 &mpos1, idVec3 &mpos2, float mtime, float maccelTime, float mdecelTime ) {
3006 
3007  pos1 = mpos1;
3008  pos2 = mpos2;
3009 
3012 
3014  if ( duration <= 0 ) {
3015  duration = 1;
3016  }
3017 
3019 
3022  SetOrigin( pos1 );
3023 
3025 }
3026 
3027 /*
3028 ================
3029 idMover_Binary::SetBlocked
3030 ================
3031 */
3033  for ( idMover_Binary *slave = moveMaster; slave != NULL; slave = slave->activateChain ) {
3034  slave->blocked = b;
3035  if ( b ) {
3036  const idKeyValue *kv = slave->spawnArgs.MatchPrefix( "triggerBlocked" );
3037  while( kv ) {
3038  idEntity *ent = gameLocal.FindEntity( kv->GetValue() );
3039  if ( ent ) {
3040  ent->PostEventMS( &EV_Activate, 0, moveMaster->GetActivator() );
3041  }
3042  kv = slave->spawnArgs.MatchPrefix( "triggerBlocked", kv );
3043  }
3044  }
3045  }
3046 }
3047 
3048 /*
3049 ================
3050 idMover_Binary::IsBlocked
3051 ================
3052 */
3054  return blocked;
3055 }
3056 
3057 /*
3058 ================
3059 idMover_Binary::GetActivator
3060 ================
3061 */
3063  return activatedBy.GetEntity();
3064 }
3065 
3066 /*
3067 ================
3068 idMover_Binary::WriteToSnapshot
3069 ================
3070 */
3072  physicsObj.WriteToSnapshot( msg );
3073  msg.WriteBits( moverState, 3 );
3074  WriteBindToSnapshot( msg );
3075 }
3076 
3077 /*
3078 ================
3079 idMover_Binary::ReadFromSnapshot
3080 ================
3081 */
3083  moverState_t oldMoverState = moverState;
3084 
3086  moverState = (moverState_t) msg.ReadBits( 3 );
3087  ReadBindFromSnapshot( msg );
3088 
3089  if ( msg.HasChanged() ) {
3090  if ( moverState != oldMoverState ) {
3092  }
3093  UpdateVisuals();
3094  }
3095 }
3096 
3097 /*
3098 ================
3099 idMover_Binary::SetPortalState
3100 ================
3101 */
3103  assert( areaPortal );
3105 }
3106 
3107 /*
3108 ===============================================================================
3109 
3110 idDoor
3111 
3112 A use can be triggered either by a touch function, by being shot, or by being
3113 targeted by another entity.
3114 
3115 ===============================================================================
3116 */
3117 
3118 const idEventDef EV_Door_StartOpen( "<startOpen>", NULL );
3119 const idEventDef EV_Door_SpawnDoorTrigger( "<spawnDoorTrigger>", NULL );
3120 const idEventDef EV_Door_SpawnSoundTrigger( "<spawnSoundTrigger>", NULL );
3121 const idEventDef EV_Door_Open( "open", NULL );
3122 const idEventDef EV_Door_Close( "close", NULL );
3123 const idEventDef EV_Door_Lock( "lock", "d" );
3124 const idEventDef EV_Door_IsOpen( "isOpen", NULL, 'f' );
3125 const idEventDef EV_Door_IsLocked( "isLocked", NULL, 'f' );
3126 
3128  EVENT( EV_TeamBlocked, idDoor::Event_TeamBlocked )
3129  EVENT( EV_PartBlocked, idDoor::Event_PartBlocked )
3130  EVENT( EV_Touch, idDoor::Event_Touch )
3131  EVENT( EV_Activate, idDoor::Event_Activate )
3132  EVENT( EV_Door_StartOpen, idDoor::Event_StartOpen )
3133  EVENT( EV_Door_SpawnDoorTrigger, idDoor::Event_SpawnDoorTrigger )
3134  EVENT( EV_Door_SpawnSoundTrigger, idDoor::Event_SpawnSoundTrigger )
3135  EVENT( EV_Door_Open, idDoor::Event_Open )
3136  EVENT( EV_Door_Close, idDoor::Event_Close )
3137  EVENT( EV_Door_Lock, idDoor::Event_Lock )
3138  EVENT( EV_Door_IsOpen, idDoor::Event_IsOpen )
3139  EVENT( EV_Door_IsLocked, idDoor::Event_Locked )
3140  EVENT( EV_ReachedPos, idDoor::Event_Reached_BinaryMover )
3141  EVENT( EV_SpectatorTouch, idDoor::Event_SpectatorTouch )
3142  EVENT( EV_Mover_OpenPortal, idDoor::Event_OpenPortal )
3143  EVENT( EV_Mover_ClosePortal, idDoor::Event_ClosePortal )
3144 END_CLASS
3145 
3146 /*
3147 ================
3148 idDoor::idDoor
3149 ================
3150 */
3151 idDoor::idDoor( void ) {
3152  triggersize = 1.0f;
3153  crusher = false;
3154  noTouch = false;
3155  aas_area_closed = false;
3156  buddyStr.Clear();
3157  trigger = NULL;
3158  sndTrigger = NULL;
3159  nextSndTriggerTime = 0;
3160  localTriggerOrigin.Zero();
3161  localTriggerAxis.Identity();
3162  requires.Clear();
3163  removeItem = 0;
3164  syncLock.Clear();
3165  companionDoor = NULL;
3166  normalAxisIndex = 0;
3167 }
3168 
3169 /*
3170 ================
3171 idDoor::~idDoor
3172 ================
3173 */
3175  if ( trigger ) {
3176  delete trigger;
3177  }
3178  if ( sndTrigger ) {
3179  delete sndTrigger;
3180  }
3181 }
3182 
3183 /*
3184 ================
3185 idDoor::Save
3186 ================
3187 */
3188 void idDoor::Save( idSaveGame *savefile ) const {
3189 
3190  savefile->WriteFloat( triggersize );
3191  savefile->WriteBool( crusher );
3192  savefile->WriteBool( noTouch );
3193  savefile->WriteBool( aas_area_closed );
3194  savefile->WriteString( buddyStr );
3195  savefile->WriteInt( nextSndTriggerTime );
3196 
3197  savefile->WriteVec3( localTriggerOrigin );
3198  savefile->WriteMat3( localTriggerAxis );
3199 
3200  savefile->WriteString( requires );
3201  savefile->WriteInt( removeItem );
3202  savefile->WriteString( syncLock );
3203  savefile->WriteInt( normalAxisIndex );
3204 
3205  savefile->WriteClipModel( trigger );
3206  savefile->WriteClipModel( sndTrigger );
3207 
3208  savefile->WriteObject( companionDoor );
3209 }
3210 
3211 /*
3212 ================
3213 idDoor::Restore
3214 ================
3215 */
3216 void idDoor::Restore( idRestoreGame *savefile ) {
3217 
3218  savefile->ReadFloat( triggersize );
3219  savefile->ReadBool( crusher );
3220  savefile->ReadBool( noTouch );
3221  savefile->ReadBool( aas_area_closed );
3223  savefile->ReadString( buddyStr );
3224  savefile->ReadInt( nextSndTriggerTime );
3225 
3226  savefile->ReadVec3( localTriggerOrigin );
3227  savefile->ReadMat3( localTriggerAxis );
3228 
3229  savefile->ReadString( requires );
3230  savefile->ReadInt( removeItem );
3231  savefile->ReadString( syncLock );
3232  savefile->ReadInt( normalAxisIndex );
3233 
3234  savefile->ReadClipModel( trigger );
3235  savefile->ReadClipModel( sndTrigger );
3236 
3237  savefile->ReadObject( reinterpret_cast<idClass *&>( companionDoor ) );
3238 }
3239 
3240 /*
3241 ================
3242 idDoor::Spawn
3243 ================
3244 */
3245 void idDoor::Spawn( void ) {
3246  idVec3 abs_movedir;
3247  float distance;
3248  idVec3 size;
3249  idVec3 movedir;
3250  float dir;
3251  float lip;
3252  bool start_open;
3253  float time;
3254  float speed;
3255 
3256  // get the direction to move
3257  if ( !spawnArgs.GetFloat( "movedir", "0", dir ) ) {
3258  // no movedir, so angle defines movement direction and not orientation,
3259  // a la oldschool Quake
3260  SetAngles( ang_zero );
3261  spawnArgs.GetFloat( "angle", "0", dir );
3262  }
3263  GetMovedir( dir, movedir );
3264 
3265  // default speed of 400
3266  spawnArgs.GetFloat( "speed", "400", speed );
3267 
3268  // default wait of 2 seconds
3269  spawnArgs.GetFloat( "wait", "3", wait );
3270 
3271  // default lip of 8 units
3272  spawnArgs.GetFloat( "lip", "8", lip );
3273 
3274  // by default no damage
3275  spawnArgs.GetFloat( "damage", "0", damage );
3276 
3277  // trigger size
3278  spawnArgs.GetFloat( "triggersize", "120", triggersize );
3279 
3280  spawnArgs.GetBool( "crusher", "0", crusher );
3281  spawnArgs.GetBool( "start_open", "0", start_open );
3282  spawnArgs.GetBool( "no_touch", "0", noTouch );
3283 #ifdef _D3XP
3284  spawnArgs.GetBool( "player_only", "0", playerOnly );
3285 #endif
3286 
3287  // expects syncLock to be a door that must be closed before this door will open
3288  spawnArgs.GetString( "syncLock", "", syncLock );
3289 
3290  spawnArgs.GetString( "buddy", "", buddyStr );
3291 
3292  spawnArgs.GetString( "requires", "", requires );
3293  spawnArgs.GetInt( "removeItem", "0", removeItem );
3294 
3295  // ever separate piece of a door is considered solid when other team mates push entities
3296  fl.solidForTeam = true;
3297 
3298  // first position at start
3299  pos1 = GetPhysics()->GetOrigin();
3300 
3301  // calculate second position
3302  abs_movedir[0] = idMath::Fabs( movedir[ 0 ] );
3303  abs_movedir[1] = idMath::Fabs( movedir[ 1 ] );
3304  abs_movedir[2] = idMath::Fabs( movedir[ 2 ] );
3305  size = GetPhysics()->GetAbsBounds()[1] - GetPhysics()->GetAbsBounds()[0];
3306  distance = ( abs_movedir * size ) - lip;
3307  pos2 = pos1 + distance * movedir;
3308 
3309  // if "start_open", reverse position 1 and 2
3310  if ( start_open ) {
3311  // post it after EV_SpawnBind
3313  }
3314 
3315  if ( spawnArgs.GetFloat( "time", "1", time ) ) {
3316  InitTime( pos1, pos2, time, 0, 0 );
3317  } else {
3318  InitSpeed( pos1, pos2, speed, 0, 0 );
3319  }
3320 
3321  if ( moveMaster == this ) {
3322  if ( health ) {
3323  fl.takedamage = true;
3324  }
3325  if ( noTouch || health ) {
3326  // non touch/shoot doors
3328 
3329  const char *sndtemp = spawnArgs.GetString( "snd_locked" );
3330  if ( spawnArgs.GetInt( "locked" ) && sndtemp && *sndtemp ) {
3332  }
3333  } else {
3334  // spawn trigger
3336  }
3337  }
3338 
3339  // see if we are on an areaportal
3340  areaPortal = gameRenderWorld->FindPortal( GetPhysics()->GetAbsBounds() );
3341  if ( !start_open ) {
3342  // start closed
3344 
3345 #ifdef _D3XP
3346  if ( playerOnly ) {
3347  gameLocal.SetAASAreaState( GetPhysics()->GetAbsBounds(), AREACONTENTS_CLUSTERPORTAL, true );
3348  }
3349 #endif
3350  }
3351 
3352  int locked = spawnArgs.GetInt( "locked" );
3353  if ( locked ) {
3354  // make sure all members of the team get locked
3355  PostEventMS( &EV_Door_Lock, 0, locked );
3356  }
3357 
3358  if ( spawnArgs.GetBool( "continuous" ) ) {
3359  PostEventSec( &EV_Activate, spawnArgs.GetFloat( "delay" ), this );
3360  }
3361 
3362  // sounds have a habit of stuttering when portals close, so make them unoccluded
3363  refSound.parms.soundShaderFlags |= SSF_NO_OCCLUSION;
3364 
3365  companionDoor = NULL;
3366 
3367  enabled = true;
3368  blocked = false;
3369 }
3370 
3371 /*
3372 ================
3373 idDoor::Think
3374 ================
3375 */
3376 void idDoor::Think( void ) {
3377  idVec3 masterOrigin;
3378  idMat3 masterAxis;
3379 
3381 
3382  if ( thinkFlags & TH_PHYSICS ) {
3383  // update trigger position
3384  if ( GetMasterPosition( masterOrigin, masterAxis ) ) {
3385  if ( trigger ) {
3386  trigger->Link( gameLocal.clip, this, 0, masterOrigin + localTriggerOrigin * masterAxis, localTriggerAxis * masterAxis );
3387  }
3388  if ( sndTrigger ) {
3389  sndTrigger->Link( gameLocal.clip, this, 0, masterOrigin + localTriggerOrigin * masterAxis, localTriggerAxis * masterAxis );
3390  }
3391  }
3392  }
3393 }
3394 
3395 /*
3396 ================
3397 idDoor::PreBind
3398 ================
3399 */
3400 void idDoor::PreBind( void ) {
3402 }
3403 
3404 /*
3405 ================
3406 idDoor::PostBind
3407 ================
3408 */
3409 void idDoor::PostBind( void ) {
3412 }
3413 
3414 /*
3415 ================
3416 idDoor::SetAASAreaState
3417 ================
3418 */
3419 void idDoor::SetAASAreaState( bool closed ) {
3420  aas_area_closed = closed;
3422 }
3423 
3424 /*
3425 ================
3426 idDoor::Hide
3427 ================
3428 */
3429 void idDoor::Hide( void ) {
3430  idMover_Binary *slave;
3431  idMover_Binary *master;
3432  idDoor *slaveDoor;
3433  idDoor *companion;
3434 
3435  master = GetMoveMaster();
3436  if ( this != master ) {
3437  master->Hide();
3438  } else {
3439  for ( slave = this; slave != NULL; slave = slave->GetActivateChain() ) {
3440  if ( slave->IsType( idDoor::Type ) ) {
3441  slaveDoor = static_cast<idDoor *>( slave );
3442  companion = slaveDoor->companionDoor;
3443  if ( companion && ( companion != master ) && ( companion->GetMoveMaster() != master ) ) {
3444  companion->Hide();
3445  }
3446  if ( slaveDoor->trigger ) {
3447  slaveDoor->trigger->Disable();
3448  }
3449  if ( slaveDoor->sndTrigger ) {
3450  slaveDoor->sndTrigger->Disable();
3451  }
3452  if ( slaveDoor->areaPortal ) {
3453  slaveDoor->SetPortalState( true );
3454  }
3455  slaveDoor->SetAASAreaState( false );
3456  }
3457  slave->GetPhysics()->GetClipModel()->Disable();
3458  slave->idMover_Binary::Hide();
3459  }
3460  }
3461 }
3462 
3463 /*
3464 ================
3465 idDoor::Show
3466 ================
3467 */
3468 void idDoor::Show( void ) {
3469  idMover_Binary *slave;
3470  idMover_Binary *master;
3471  idDoor *slaveDoor;
3472  idDoor *companion;
3473 
3474  master = GetMoveMaster();
3475  if ( this != master ) {
3476  master->Show();
3477  } else {
3478  for ( slave = this; slave != NULL; slave = slave->GetActivateChain() ) {
3479  if ( slave->IsType( idDoor::Type ) ) {
3480  slaveDoor = static_cast<idDoor *>( slave );
3481  companion = slaveDoor->companionDoor;
3482  if ( companion && ( companion != master ) && ( companion->GetMoveMaster() != master ) ) {
3483  companion->Show();
3484  }
3485  if ( slaveDoor->trigger ) {
3486  slaveDoor->trigger->Enable();
3487  }
3488  if ( slaveDoor->sndTrigger ) {
3489  slaveDoor->sndTrigger->Enable();
3490  }
3491  if ( slaveDoor->areaPortal && ( slaveDoor->moverState == MOVER_POS1 ) ) {
3492  slaveDoor->SetPortalState( false );
3493  }
3494  slaveDoor->SetAASAreaState( IsLocked() || IsNoTouch() );
3495  }
3496  slave->GetPhysics()->GetClipModel()->Enable();
3497  slave->idMover_Binary::Show();
3498  }
3499  }
3500 }
3501 
3502 /*
3503 ================
3504 idDoor::GetLocalTriggerPosition
3505 ================
3506 */
3508  idVec3 origin;
3509  idMat3 axis;
3510 
3511  if ( !trigger ) {
3512  return;
3513  }
3514 
3515  GetMasterPosition( origin, axis );
3516  localTriggerOrigin = ( trigger->GetOrigin() - origin ) * axis.Transpose();
3517  localTriggerAxis = trigger->GetAxis() * axis.Transpose();
3518 }
3519 
3520 /*
3521 ================
3522 idDoor::Use
3523 ================
3524 */
3525 void idDoor::Use( idEntity *other, idEntity *activator ) {
3526  if ( gameLocal.RequirementMet( activator, requires, removeItem ) ) {
3527  if ( syncLock.Length() ) {
3529  if ( sync && sync->IsType( idDoor::Type ) ) {
3530  if ( static_cast<idDoor *>( sync )->IsOpen() ) {
3531  return;
3532  }
3533  }
3534  }
3535  ActivateTargets( activator );
3536  Use_BinaryMover( activator );
3537  }
3538 }
3539 
3540 /*
3541 ================
3542 idDoor::Open
3543 ================
3544 */
3545 void idDoor::Open( void ) {
3546  GotoPosition2();
3547 }
3548 
3549 /*
3550 ================
3551 idDoor::Close
3552 ================
3553 */
3554 void idDoor::Close( void ) {
3555  GotoPosition1();
3556 }
3557 
3558 /*
3559 ================
3560 idDoor::Lock
3561 ================
3562 */
3563 void idDoor::Lock( int f ) {
3564  idMover_Binary *other;
3565 
3566  // lock all the doors on the team
3567  for( other = moveMaster; other != NULL; other = other->GetActivateChain() ) {
3568  if ( other->IsType( idDoor::Type ) ) {
3569  idDoor *door = static_cast<idDoor *>( other );
3570  if ( other == moveMaster ) {
3571  if ( door->sndTrigger == NULL ) {
3572  // in this case the sound trigger never got spawned
3573  const char *sndtemp = door->spawnArgs.GetString( "snd_locked" );
3574  if ( sndtemp && *sndtemp ) {
3576  }
3577  }
3578  if ( !f && ( door->spawnArgs.GetInt( "locked" ) != 0 ) ) {
3579  door->StartSound( "snd_unlocked", SND_CHANNEL_ANY, 0, false, NULL );
3580  }
3581  }
3582  door->spawnArgs.SetInt( "locked", f );
3583  if ( ( f == 0 ) || ( !IsHidden() && ( door->moverState == MOVER_POS1 ) ) ) {
3584  door->SetAASAreaState( f != 0 );
3585  }
3586  }
3587  }
3588 
3589  if ( f ) {
3590  Close();
3591  }
3592 }
3593 
3594 /*
3595 ================
3596 idDoor::IsLocked
3597 ================
3598 */
3599 int idDoor::IsLocked( void ) {
3600  return spawnArgs.GetInt( "locked" );
3601 }
3602 
3603 /*
3604 ================
3605 idDoor::IsOpen
3606 ================
3607 */
3608 bool idDoor::IsOpen( void ) {
3609  return ( moverState != MOVER_POS1 );
3610 }
3611 
3612 /*
3613 ================
3614 idDoor::IsNoTouch
3615 ================
3616 */
3617 bool idDoor::IsNoTouch( void ) {
3618  return noTouch;
3619 }
3620 
3621 #ifdef _D3XP
3622 /*
3623 ================
3624 idDoor::AllowPlayerOnly
3625 ================
3626 */
3627 bool idDoor::AllowPlayerOnly( idEntity *ent ) {
3628  if ( playerOnly && !ent->IsType(idPlayer::Type) ) {
3629  return false;
3630  }
3631 
3632  return true;
3633 }
3634 #endif
3635 
3636 /*
3637 ======================
3638 idDoor::CalcTriggerBounds
3639 
3640 Calcs bounds for a trigger.
3641 ======================
3642 */
3643 void idDoor::CalcTriggerBounds( float size, idBounds &bounds ) {
3644  idMover_Binary *other;
3645  int i;
3646  int best;
3647 
3648  // find the bounds of everything on the team
3649  bounds = GetPhysics()->GetAbsBounds();
3650 
3651  fl.takedamage = true;
3652  for( other = activateChain; other != NULL; other = other->GetActivateChain() ) {
3653  if ( other->IsType( idDoor::Type ) ) {
3654  // find the bounds of everything on the team
3655  bounds.AddBounds( other->GetPhysics()->GetAbsBounds() );
3656 
3657  // set all of the slaves as shootable
3658  other->fl.takedamage = true;
3659  }
3660  }
3661 
3662  // find the thinnest axis, which will be the one we expand
3663  best = 0;
3664  for ( i = 1 ; i < 3 ; i++ ) {
3665  if ( bounds[1][ i ] - bounds[0][ i ] < bounds[1][ best ] - bounds[0][ best ] ) {
3666  best = i;
3667  }
3668  }
3669  normalAxisIndex = best;
3670  bounds[0][ best ] -= size;
3671  bounds[1][ best ] += size;
3672  bounds[0] -= GetPhysics()->GetOrigin();
3673  bounds[1] -= GetPhysics()->GetOrigin();
3674 }
3675 
3676 /*
3677 ======================
3678 idDoor::Event_StartOpen
3679 
3680 if "start_open", reverse position 1 and 2
3681 ======================
3682 */
3684  float time;
3685  float speed;
3686 
3687  // if "start_open", reverse position 1 and 2
3688  pos1 = pos2;
3689  pos2 = GetPhysics()->GetOrigin();
3690 
3691  spawnArgs.GetFloat( "speed", "400", speed );
3692 
3693  if ( spawnArgs.GetFloat( "time", "1", time ) ) {
3694  InitTime( pos1, pos2, time, 0, 0 );
3695  } else {
3696  InitSpeed( pos1, pos2, speed, 0, 0 );
3697  }
3698 }
3699 
3700 /*
3701 ======================
3702 idDoor::Event_SpawnDoorTrigger
3703 
3704 All of the parts of a door have been spawned, so create
3705 a trigger that encloses all of them.
3706 ======================
3707 */
3709  idBounds bounds;
3710  idMover_Binary *other;
3711  bool toggle;
3712 
3713  if ( trigger ) {
3714  // already have a trigger, so don't spawn a new one.
3715  return;
3716  }
3717 
3718  // check if any of the doors are marked as toggled
3719  toggle = false;
3720  for( other = moveMaster; other != NULL; other = other->GetActivateChain() ) {
3721  if ( other->IsType( idDoor::Type ) && other->spawnArgs.GetBool( "toggle" ) ) {
3722  toggle = true;
3723  break;
3724  }
3725  }
3726 
3727  if ( toggle ) {
3728  // mark them all as toggled
3729  for( other = moveMaster; other != NULL; other = other->GetActivateChain() ) {
3730  if ( other->IsType( idDoor::Type ) ) {
3731  other->spawnArgs.Set( "toggle", "1" );
3732  }
3733  }
3734  // don't spawn trigger
3735  return;
3736  }
3737 
3738  const char *sndtemp = spawnArgs.GetString( "snd_locked" );
3739  if ( spawnArgs.GetInt( "locked" ) && sndtemp && *sndtemp ) {
3741  }
3742 
3743  CalcTriggerBounds( triggersize, bounds );
3744 
3745  // create a trigger clip model
3746  trigger = new idClipModel( idTraceModel( bounds ) );
3747  trigger->Link( gameLocal.clip, this, 255, GetPhysics()->GetOrigin(), mat3_identity );
3749 
3751 
3753 }
3754 
3755 /*
3756 ======================
3757 idDoor::Event_SpawnSoundTrigger
3758 
3759 Spawn a sound trigger to activate locked sound if it exists.
3760 ======================
3761 */
3763  idBounds bounds;
3764 
3765  if ( sndTrigger ) {
3766  return;
3767  }
3768 
3769  CalcTriggerBounds( triggersize * 0.5f, bounds );
3770 
3771  // create a trigger clip model
3772  sndTrigger = new idClipModel( idTraceModel( bounds ) );
3773  sndTrigger->Link( gameLocal.clip, this, 254, GetPhysics()->GetOrigin(), mat3_identity );
3775 
3777 }
3778 
3779 /*
3780 ================
3781 idDoor::Event_Reached_BinaryMover
3782 ================
3783 */
3785  if ( moverState == MOVER_2TO1 ) {
3786  SetBlocked( false );
3787  const idKeyValue *kv = spawnArgs.MatchPrefix( "triggerClosed" );
3788  while( kv ) {
3789  idEntity *ent = gameLocal.FindEntity( kv->GetValue() );
3790  if ( ent ) {
3791  ent->PostEventMS( &EV_Activate, 0, moveMaster->GetActivator() );
3792  }
3793  kv = spawnArgs.MatchPrefix( "triggerClosed", kv );
3794  }
3795  } else if ( moverState == MOVER_1TO2 ) {
3796  const idKeyValue *kv = spawnArgs.MatchPrefix( "triggerOpened" );
3797  while( kv ) {
3798  idEntity *ent = gameLocal.FindEntity( kv->GetValue() );
3799  if ( ent ) {
3800  ent->PostEventMS( &EV_Activate, 0, moveMaster->GetActivator() );
3801  }
3802  kv = spawnArgs.MatchPrefix( "triggerOpened", kv );
3803  }
3804  }
3806 }
3807 
3808 /*
3809 ================
3810 idDoor::Blocked_Door
3811 ================
3812 */
3813 void idDoor::Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity ) {
3814  SetBlocked( true );
3815 
3816  if ( crusher ) {
3817  return; // crushers don't reverse
3818  }
3819 
3820  // reverse direction
3822 
3823  if ( companionDoor ) {
3824  companionDoor->ProcessEvent( &EV_TeamBlocked, blockedEntity, blockingEntity );
3825  }
3826 }
3827 
3828 /*
3829 ===============
3830 idDoor::SetCompanion
3831 ===============
3832 */
3834  companionDoor = door;
3835 }
3836 
3837 /*
3838 ===============
3839 idDoor::Event_PartBlocked
3840 ===============
3841 */
3842 void idDoor::Event_PartBlocked( idEntity *blockingEntity ) {
3843  if ( damage > 0.0f ) {
3844  blockingEntity->Damage( this, this, vec3_origin, "damage_moverCrush", damage, INVALID_JOINT );
3845  }
3846 }
3847 
3848 /*
3849 ================
3850 idDoor::Event_Touch
3851 ================
3852 */
3853 void idDoor::Event_Touch( idEntity *other, trace_t *trace ) {
3854  idVec3 contact, translate;
3855  idVec3 planeaxis1, planeaxis2, normal;
3856  idBounds bounds;
3857 
3858  if ( !enabled ) {
3859  return;
3860  }
3861 
3862  if ( trigger && trace->c.id == trigger->GetId() ) {
3863  if ( !IsNoTouch() && !IsLocked() && GetMoverState() != MOVER_1TO2 ) {
3864 #ifdef _D3XP
3865  if ( AllowPlayerOnly( other ) ) {
3866 #endif
3867  Use( this, other );
3868 #ifdef _D3XP
3869  }
3870 #endif
3871  }
3872  } else if ( sndTrigger && trace->c.id == sndTrigger->GetId() ) {
3873  if ( other && other->IsType( idPlayer::Type ) && IsLocked() && gameLocal.slow.time > nextSndTriggerTime ) {
3874  StartSound( "snd_locked", SND_CHANNEL_ANY, 0, false, NULL );
3875  nextSndTriggerTime = gameLocal.slow.time + 10000;
3876  }
3877  }
3878 }
3879 
3880 /*
3881 ================
3882 idDoor::Event_SpectatorTouch
3883 ================
3884 */
3886  idVec3 contact, translate, normal;
3887  idBounds bounds;
3888  idPlayer *p;
3889 
3890  assert( other && other->IsType( idPlayer::Type ) && static_cast< idPlayer * >( other )->spectating );
3891 
3892  p = static_cast< idPlayer * >( other );
3893  // avoid flicker when stopping right at clip box boundaries
3894  if ( p->lastSpectateTeleport > gameLocal.slow.time - 1000 ) {
3895  return;
3896  }
3897  if ( trigger && !IsOpen() ) {
3898  // teleport to the other side, center to the middle of the trigger brush
3899  bounds = trigger->GetAbsBounds();
3900  contact = trace->endpos - bounds.GetCenter();
3901  translate = bounds.GetCenter();
3902  normal.Zero();
3903  normal[ normalAxisIndex ] = 1.0f;
3904  if ( normal * contact > 0 ) {
3905  translate[ normalAxisIndex ] += ( bounds[ 0 ][ normalAxisIndex ] - translate[ normalAxisIndex ] ) * 0.5f;
3906  } else {
3907  translate[ normalAxisIndex ] += ( bounds[ 1 ][ normalAxisIndex ] - translate[ normalAxisIndex ] ) * 0.5f;
3908  }
3909  p->SetOrigin( translate );
3911  }
3912 }
3913 
3914 /*
3915 ================
3916 idDoor::Event_Activate
3917 ================
3918 */
3919 void idDoor::Event_Activate( idEntity *activator ) {
3920  int old_lock;
3921 
3922  if ( spawnArgs.GetInt( "locked" ) ) {
3923  if ( !trigger ) {
3925  }
3926  if ( buddyStr.Length() ) {
3927  idEntity *buddy = gameLocal.FindEntity( buddyStr );
3928  if ( buddy ) {
3929  buddy->SetShaderParm( SHADERPARM_MODE, 1 );
3930  buddy->UpdateVisuals();
3931  }
3932  }
3933 
3934  old_lock = spawnArgs.GetInt( "locked" );
3935  Lock( 0 );
3936  if ( old_lock == 2 ) {
3937  return;
3938  }
3939  }
3940 
3941  if ( syncLock.Length() ) {
3943  if ( sync && sync->IsType( idDoor::Type ) ) {
3944  if ( static_cast<idDoor *>( sync )->IsOpen() ) {
3945  return;
3946  }
3947  }
3948  }
3949 
3950  ActivateTargets( activator );
3951 
3953  UpdateVisuals();
3954 
3955  Use_BinaryMover( activator );
3956 }
3957 
3958 /*
3959 ================
3960 idDoor::Event_Open
3961 ================
3962 */
3963 void idDoor::Event_Open( void ) {
3964  Open();
3965 }
3966 
3967 /*
3968 ================
3969 idDoor::Event_Close
3970 ================
3971 */
3972 void idDoor::Event_Close( void ) {
3973  Close();
3974 }
3975 
3976 /*
3977 ================
3978 idDoor::Event_Lock
3979 ================
3980 */
3981 void idDoor::Event_Lock( int f ) {
3982  Lock( f );
3983 }
3984 
3985 /*
3986 ================
3987 idDoor::Event_IsOpen
3988 ================
3989 */
3990 void idDoor::Event_IsOpen( void ) {
3991  bool state;
3992 
3993  state = IsOpen();
3994  idThread::ReturnFloat( state );
3995 }
3996 
3997 /*
3998 ================
3999 idDoor::Event_Locked
4000 ================
4001 */
4002 void idDoor::Event_Locked( void ) {
4003  idThread::ReturnFloat( spawnArgs.GetInt("locked") );
4004 }
4005 
4006 /*
4007 ================
4008 idDoor::Event_OpenPortal
4009 
4010 Sets the portal associtated with this door to be open
4011 ================
4012 */
4014  idMover_Binary *slave;
4015  idDoor *slaveDoor;
4016 
4017  for ( slave = this; slave != NULL; slave = slave->GetActivateChain() ) {
4018  if ( slave->IsType( idDoor::Type ) ) {
4019  slaveDoor = static_cast<idDoor *>( slave );
4020  if ( slaveDoor->areaPortal ) {
4021  slaveDoor->SetPortalState( true );
4022  }
4023  slaveDoor->SetAASAreaState( false );
4024  }
4025  }
4026 }
4027 
4028 /*
4029 ================
4030 idDoor::Event_ClosePortal
4031 
4032 Sets the portal associtated with this door to be closed
4033 ================
4034 */
4036  idMover_Binary *slave;
4037  idDoor *slaveDoor;
4038 
4039  for ( slave = this; slave != NULL; slave = slave->GetActivateChain() ) {
4040  if ( !slave->IsHidden() ) {
4041  if ( slave->IsType( idDoor::Type ) ) {
4042  slaveDoor = static_cast<idDoor *>( slave );
4043  if ( slaveDoor->areaPortal ) {
4044  slaveDoor->SetPortalState( false );
4045  }
4046  slaveDoor->SetAASAreaState( IsLocked() || IsNoTouch() );
4047  }
4048  }
4049  }
4050 }
4051 
4052 
4053 /*
4054 ===============================================================================
4055 
4056 idPlat
4057 
4058 ===============================================================================
4059 */
4060 
4062  EVENT( EV_Touch, idPlat::Event_Touch )
4063  EVENT( EV_TeamBlocked, idPlat::Event_TeamBlocked )
4064  EVENT( EV_PartBlocked, idPlat::Event_PartBlocked )
4065 END_CLASS
4066 
4067 /*
4068 ===============
4069 idPlat::idPlat
4070 ===============
4071 */
4072 idPlat::idPlat( void ) {
4073  trigger = NULL;
4074  localTriggerOrigin.Zero();
4075  localTriggerAxis.Identity();
4076 }
4077 
4078 /*
4079 ===============
4080 idPlat::~idPlat
4081 ===============
4082 */
4084  if ( trigger ) {
4085  delete trigger;
4086  }
4087 }
4088 
4089 /*
4090 ===============
4091 idPlat::Save
4092 ===============
4093 */
4094 void idPlat::Save( idSaveGame *savefile ) const {
4095  savefile->WriteClipModel( trigger );
4096  savefile->WriteVec3( localTriggerOrigin );
4097  savefile->WriteMat3( localTriggerAxis );
4098 }
4099 
4100 /*
4101 ===============
4102 idPlat::Restore
4103 ===============
4104 */
4105 void idPlat::Restore( idRestoreGame *savefile ) {
4106  savefile->ReadClipModel( trigger );
4107  savefile->ReadVec3( localTriggerOrigin );
4108  savefile->ReadMat3( localTriggerAxis );
4109 }
4110 
4111 /*
4112 ===============
4113 idPlat::Spawn
4114 ===============
4115 */
4116 void idPlat::Spawn( void ) {
4117  float lip;
4118  float height;
4119  float time;
4120  float speed;
4121  float accel;
4122  float decel;
4123  bool noTouch;
4124 
4125  spawnArgs.GetFloat( "speed", "100", speed );
4126  spawnArgs.GetFloat( "damage", "0", damage );
4127  spawnArgs.GetFloat( "wait", "1", wait );
4128  spawnArgs.GetFloat( "lip", "8", lip );
4129  spawnArgs.GetFloat( "accel_time", "0.25", accel );
4130  spawnArgs.GetFloat( "decel_time", "0.25", decel );
4131 
4132  // create second position
4133  if ( !spawnArgs.GetFloat( "height", "0", height ) ) {
4134  height = ( GetPhysics()->GetBounds()[1][2] - GetPhysics()->GetBounds()[0][2] ) - lip;
4135  }
4136 
4137  spawnArgs.GetBool( "no_touch", "0", noTouch );
4138 
4139  // pos1 is the rest (bottom) position, pos2 is the top
4140  pos2 = GetPhysics()->GetOrigin();
4141  pos1 = pos2;
4142  pos1[2] -= height;
4143 
4144  if ( spawnArgs.GetFloat( "time", "1", time ) ) {
4145  InitTime( pos1, pos2, time, accel, decel );
4146  } else {
4147  InitSpeed( pos1, pos2, speed, accel, decel );
4148  }
4149 
4151  UpdateVisuals();
4152 
4153  // spawn the trigger if one hasn't been custom made
4154  if ( !noTouch ) {
4155  // spawn trigger
4157  }
4158 }
4159 
4160 /*
4161 ================
4162 idPlat::Think
4163 ================
4164 */
4165 void idPlat::Think( void ) {
4166  idVec3 masterOrigin;
4167  idMat3 masterAxis;
4168 
4170 
4171  if ( thinkFlags & TH_PHYSICS ) {
4172  // update trigger position
4173  if ( GetMasterPosition( masterOrigin, masterAxis ) ) {
4174  if ( trigger ) {
4175  trigger->Link( gameLocal.clip, this, 0, masterOrigin + localTriggerOrigin * masterAxis, localTriggerAxis * masterAxis );
4176  }
4177  }
4178  }
4179 }
4180 
4181 /*
4182 ================
4183 idPlat::PreBind
4184 ================
4185 */
4186 void idPlat::PreBind( void ) {
4188 }
4189 
4190 /*
4191 ================
4192 idPlat::PostBind
4193 ================
4194 */
4195 void idPlat::PostBind( void ) {
4198 }
4199 
4200 /*
4201 ================
4202 idPlat::GetLocalTriggerPosition
4203 ================
4204 */
4206  idVec3 origin;
4207  idMat3 axis;
4208 
4209  if ( !trigger ) {
4210  return;
4211  }
4212 
4213  GetMasterPosition( origin, axis );
4214  localTriggerOrigin = ( trigger->GetOrigin() - origin ) * axis.Transpose();
4215  localTriggerAxis = trigger->GetAxis() * axis.Transpose();
4216 }
4217 
4218 /*
4219 ==============
4220 idPlat::SpawnPlatTrigger
4221 ===============
4222 */
4224  idBounds bounds;
4225  idVec3 tmin;
4226  idVec3 tmax;
4227 
4228  // the middle trigger will be a thin trigger just
4229  // above the starting position
4230 
4231  bounds = GetPhysics()->GetBounds();
4232 
4233  tmin[0] = bounds[0][0] + 33;
4234  tmin[1] = bounds[0][1] + 33;
4235  tmin[2] = bounds[0][2];
4236 
4237  tmax[0] = bounds[1][0] - 33;
4238  tmax[1] = bounds[1][1] - 33;
4239  tmax[2] = bounds[1][2] + 8;
4240 
4241  if ( tmax[0] <= tmin[0] ) {
4242  tmin[0] = ( bounds[0][0] + bounds[1][0] ) * 0.5f;
4243  tmax[0] = tmin[0] + 1;
4244  }
4245  if ( tmax[1] <= tmin[1] ) {
4246  tmin[1] = ( bounds[0][1] + bounds[1][1] ) * 0.5f;
4247  tmax[1] = tmin[1] + 1;
4248  }
4249 
4250  trigger = new idClipModel( idTraceModel( idBounds( tmin, tmax ) ) );
4251  trigger->Link( gameLocal.clip, this, 255, GetPhysics()->GetOrigin(), mat3_identity );
4253 }
4254 
4255 /*
4256 ==============
4257 idPlat::Event_Touch
4258 ===============
4259 */
4260 void idPlat::Event_Touch( idEntity *other, trace_t *trace ) {
4261  if ( !other->IsType( idPlayer::Type ) ) {
4262  return;
4263  }
4264 
4265  if ( ( GetMoverState() == MOVER_POS1 ) && trigger && ( trace->c.id == trigger->GetId() ) && ( other->health > 0 ) ) {
4266  Use_BinaryMover( other );
4267  }
4268 }
4269 
4270 /*
4271 ================
4272 idPlat::Event_TeamBlocked
4273 ================
4274 */
4275 void idPlat::Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity ) {
4276  // reverse direction
4278 }
4279 
4280 /*
4281 ===============
4282 idPlat::Event_PartBlocked
4283 ===============
4284 */
4285 void idPlat::Event_PartBlocked( idEntity *blockingEntity ) {
4286  if ( damage > 0.0f ) {
4287  blockingEntity->Damage( this, this, vec3_origin, "damage_moverCrush", damage, INVALID_JOINT );
4288  }
4289 }
4290 
4291 
4292 /*
4293 ===============================================================================
4294 
4295 idMover_Periodic
4296 
4297 ===============================================================================
4298 */
4299 
4301  EVENT( EV_TeamBlocked, idMover_Periodic::Event_TeamBlocked )
4302  EVENT( EV_PartBlocked, idMover_Periodic::Event_PartBlocked )
4303 END_CLASS
4304 
4305 /*
4306 ===============
4307 idMover_Periodic::idMover_Periodic
4308 ===============
4309 */
4311  damage = 0.0f;
4312  fl.neverDormant = false;
4313 }
4314 
4315 /*
4316 ===============
4317 idMover_Periodic::Spawn
4318 ===============
4319 */
4321  spawnArgs.GetFloat( "damage", "0", damage );
4322  if ( !spawnArgs.GetBool( "solid", "1" ) ) {
4323  GetPhysics()->SetContents( 0 );
4324  }
4325 }
4326 
4327 /*
4328 ===============
4329 idMover_Periodic::Save
4330 ===============
4331 */
4332 void idMover_Periodic::Save( idSaveGame *savefile ) const {
4333  savefile->WriteFloat( damage );
4334  savefile->WriteStaticObject( physicsObj );
4335 }
4336 
4337 /*
4338 ===============
4339 idMover_Periodic::Restore
4340 ===============
4341 */
4343  savefile->ReadFloat( damage );
4344  savefile->ReadStaticObject( physicsObj );
4346 }
4347 
4348 /*
4349 ================
4350 idMover_Periodic::Think
4351 ================
4352 */
4354  // if we are completely closed off from the player, don't do anything at all
4355  if ( CheckDormant() ) {
4356  return;
4357  }
4358 
4359  RunPhysics();
4360  Present();
4361 }
4362 
4363 /*
4364 ===============
4365 idMover_Periodic::Event_TeamBlocked
4366 ===============
4367 */
4368 void idMover_Periodic::Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity ) {
4369 }
4370 
4371 /*
4372 ===============
4373 idMover_Periodic::Event_PartBlocked
4374 ===============
4375 */
4377  if ( damage > 0.0f ) {
4378  blockingEntity->Damage( this, this, vec3_origin, "damage_moverCrush", damage, INVALID_JOINT );
4379  }
4380 }
4381 
4382 /*
4383 ================
4384 idMover_Periodic::WriteToSnapshot
4385 ================
4386 */
4388  physicsObj.WriteToSnapshot( msg );
4389  WriteBindToSnapshot( msg );
4390 }
4391 
4392 /*
4393 ================
4394 idMover_Periodic::ReadFromSnapshot
4395 ================
4396 */
4399  ReadBindFromSnapshot( msg );
4400 
4401  if ( msg.HasChanged() ) {
4402  UpdateVisuals();
4403  }
4404 }
4405 
4406 
4407 /*
4408 ===============================================================================
4409 
4410 idRotater
4411 
4412 ===============================================================================
4413 */
4414 
4416  EVENT( EV_Activate, idRotater::Event_Activate )
4417 END_CLASS
4418 
4419 /*
4420 ===============
4421 idRotater::idRotater
4422 ===============
4423 */
4425  activatedBy = this;
4426 }
4427 
4428 /*
4429 ===============
4430 idRotater::Spawn
4431 ===============
4432 */
4433 void idRotater::Spawn( void ) {
4434  physicsObj.SetSelf( this );
4435  physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f );
4436  physicsObj.SetOrigin( GetPhysics()->GetOrigin() );
4437  physicsObj.SetAxis( GetPhysics()->GetAxis() );
4439  if ( !spawnArgs.GetBool( "nopush" ) ) {
4440  physicsObj.SetPusher( 0 );
4441  }
4444  SetPhysics( &physicsObj );
4445 
4446  if ( spawnArgs.GetBool( "start_on" ) ) {
4447  ProcessEvent( &EV_Activate, this );
4448  }
4449 }
4450 
4451 /*
4452 ===============
4453 idRotater::Save
4454 ===============
4455 */
4456 void idRotater::Save( idSaveGame *savefile ) const {
4457  activatedBy.Save( savefile );
4458 }
4459 
4460 /*
4461 ===============
4462 idRotater::Restore
4463 ===============
4464 */
4466  activatedBy.Restore( savefile );
4467 }
4468 
4469 /*
4470 ===============
4471 idRotater::Event_Activate
4472 ===============
4473 */
4475  float speed;
4476  bool x_axis;
4477  bool y_axis;
4478  idAngles delta;
4479 
4480  activatedBy = activator;
4481 
4482  delta.Zero();
4483 
4484  if ( !spawnArgs.GetBool( "rotate" ) ) {
4485  spawnArgs.Set( "rotate", "1" );
4486  spawnArgs.GetFloat( "speed", "100", speed );
4487  spawnArgs.GetBool( "x_axis", "0", x_axis );
4488  spawnArgs.GetBool( "y_axis", "0", y_axis );
4489 
4490  // set the axis of rotation
4491  if ( x_axis ) {
4492  delta[2] = speed;
4493  } else if ( y_axis ) {
4494  delta[0] = speed;
4495  } else {
4496  delta[1] = speed;
4497  }
4498  } else {
4499  spawnArgs.Set( "rotate", "0" );
4500  }
4501 
4503 }
4504 
4505 
4506 /*
4507 ===============================================================================
4508 
4509 idBobber
4510 
4511 ===============================================================================
4512 */
4513 
4515 END_CLASS
4516 
4517 /*
4518 ===============
4519 idBobber::idBobber
4520 ===============
4521 */
4522 idBobber::idBobber( void ) {
4523 }
4524 
4525 /*
4526 ===============
4527 idBobber::Spawn
4528 ===============
4529 */
4530 void idBobber::Spawn( void ) {
4531  float speed;
4532  float height;
4533  float phase;
4534  bool x_axis;
4535  bool y_axis;
4536  idVec3 delta;
4537 
4538  spawnArgs.GetFloat( "speed", "4", speed );
4539  spawnArgs.GetFloat( "height", "32", height );
4540  spawnArgs.GetFloat( "phase", "0", phase );
4541  spawnArgs.GetBool( "x_axis", "0", x_axis );
4542  spawnArgs.GetBool( "y_axis", "0", y_axis );
4543 
4544  // set the axis of bobbing
4545  delta = vec3_origin;
4546  if ( x_axis ) {
4547  delta[ 0 ] = height;
4548  } else if ( y_axis ) {
4549  delta[ 1 ] = height;
4550  } else {
4551  delta[ 2 ] = height;
4552  }
4553 
4554  physicsObj.SetSelf( this );
4555  physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f );
4556  physicsObj.SetOrigin( GetPhysics()->GetOrigin() );
4557  physicsObj.SetAxis( GetPhysics()->GetAxis() );
4559  if ( !spawnArgs.GetBool( "nopush" ) ) {
4560  physicsObj.SetPusher( 0 );
4561  }
4562  physicsObj.SetLinearExtrapolation( extrapolation_t(EXTRAPOLATION_DECELSINE|EXTRAPOLATION_NOSTOP), phase * 1000, speed * 500, GetPhysics()->GetOrigin(), delta * 2.0f, vec3_origin );
4563  SetPhysics( &physicsObj );
4564 }
4565 
4566 
4567 /*
4568 ===============================================================================
4569 
4570 idPendulum
4571 
4572 ===============================================================================
4573 */
4574 
4576 END_CLASS
4577 
4578 /*
4579 ===============
4580 idPendulum::idPendulum
4581 ===============
4582 */
4584 }
4585 
4586 /*
4587 ===============
4588 idPendulum::Spawn
4589 ===============
4590 */
4591 void idPendulum::Spawn( void ) {
4592  float speed;
4593  float freq;
4594  float length;
4595  float phase;
4596 
4597  spawnArgs.GetFloat( "speed", "30", speed );
4598  spawnArgs.GetFloat( "phase", "0", phase );
4599 
4600  if ( spawnArgs.GetFloat( "freq", "", freq ) ) {
4601  if ( freq <= 0.0f ) {
4602  gameLocal.Error( "Invalid frequency on entity '%s'", GetName() );
4603  }
4604  } else {
4605  // find pendulum length
4606  length = idMath::Fabs( GetPhysics()->GetBounds()[0][2] );
4607  if ( length < 8 ) {
4608  length = 8;
4609  }
4610 
4611  freq = 1 / ( idMath::TWO_PI ) * idMath::Sqrt( g_gravity.GetFloat() / ( 3 * length ) );
4612  }
4613 
4614  physicsObj.SetSelf( this );
4615  physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f );
4616  physicsObj.SetOrigin( GetPhysics()->GetOrigin() );
4617  physicsObj.SetAxis( GetPhysics()->GetAxis() );
4619  if ( !spawnArgs.GetBool( "nopush" ) ) {
4620  physicsObj.SetPusher( 0 );
4621  }
4623  physicsObj.SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_DECELSINE|EXTRAPOLATION_NOSTOP), phase * 1000, 500/freq, GetPhysics()->GetAxis().ToAngles(), idAngles( 0, 0, speed * 2.0f ), ang_zero );
4624  SetPhysics( &physicsObj );
4625 }
4626 
4627 
4628 /*
4629 ===============================================================================
4630 
4631 idBobber
4632 
4633 ===============================================================================
4634 */
4635 
4637 EVENT( EV_Activate, idRiser::Event_Activate )
4638 END_CLASS
4639 
4640 /*
4641 ===============
4642 idRiser::idRiser
4643 ===============
4644 */
4645 idRiser::idRiser( void ) {
4646 }
4647 
4648 /*
4649 ===============
4650 idRiser::Spawn
4651 ===============
4652 */
4653 void idRiser::Spawn( void ) {
4654  physicsObj.SetSelf( this );
4655  physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f );
4656  physicsObj.SetOrigin( GetPhysics()->GetOrigin() );
4657  physicsObj.SetAxis( GetPhysics()->GetAxis() );
4658 
4660  if ( !spawnArgs.GetBool( "solid", "1" ) ) {
4661  physicsObj.SetContents( 0 );
4662  }
4663  if ( !spawnArgs.GetBool( "nopush" ) ) {
4664  physicsObj.SetPusher( 0 );
4665  }
4667  SetPhysics( &physicsObj );
4668 }
4669 
4670 /*
4671 ================
4672 idRiser::Event_Activate
4673 ================
4674 */
4675 void idRiser::Event_Activate( idEntity *activator ) {
4676 
4677  if ( !IsHidden() && spawnArgs.GetBool("hide") ) {
4678  Hide();
4679  } else {
4680  Show();
4681  float time;
4682  float height;
4683  idVec3 delta;
4684 
4685  spawnArgs.GetFloat( "time", "4", time );
4686  spawnArgs.GetFloat( "height", "32", height );
4687 
4688  delta = vec3_origin;
4689  delta[ 2 ] = height;
4690 
4692  }
4693 }
virtual const idVec3 & GetOrigin(int id=0) const =0
void Event_TeamBlocked(idEntity *blockedPart, idEntity *blockingEntity)
Definition: Mover.cpp:989
void Event_SetAccellerationTime(float time)
Definition: Mover.cpp:1042
const idVec3 & GetOrigin(int id=0) const
renderEntity_t renderEntity
Definition: Entity.h:371
bool stopRotation
Definition: Mover.h:147
void Event_PartBlocked(idEntity *blockingEntity)
Definition: Mover.cpp:4376
const idEventDef EV_Mover_OpenPortal("openPortal")
bool AddBounds(const idBounds &a)
Definition: Bounds.h:255
const idEventDef EV_ReachedPos("<reachedpos>", NULL)
float GetFloat(const char *key, const char *defaultString="0") const
Definition: Dict.h:248
virtual void WriteToSnapshot(idBitMsgDelta &msg) const
Definition: Mover.cpp:1494
void CloseAllDoors(void)
Definition: Mover.cpp:2021
int move_thread
Definition: Mover.h:137
void Event_Disable(void)
Definition: Mover.cpp:2568
bool Compare(const idVec3 &a) const
Definition: Vector.h:496
const idEventDef EV_Mover_Enable("enable", NULL)
void WriteString(const char *string)
Definition: SaveGame.cpp:231
float Normalize(void)
Definition: Vector.h:646
idAngles & Normalize360(void)
Definition: Angles.cpp:44
int GetInt(const char *key, const char *defaultString="0") const
Definition: Dict.h:252
idPhysics_Parametric physicsObj
Definition: Mover.h:502
bool PostEventSec(const idEventDef *ev, float time)
Definition: Class.cpp:747
void WriteBindToSnapshot(idBitMsgDelta &msg) const
Definition: Entity.cpp:4756
void void static idThread * CurrentThread(void)
void Event_StopMoving(void)
Definition: Mover.cpp:600
idMat3 localTriggerAxis
Definition: Mover.h:466
moveStage_t stage
Definition: Mover.h:100
assert(prefInfo.fullscreenBtn)
int deceltime
Definition: Mover.h:145
virtual void StateChanged(int time, bool redraw=false)=0
void SetContents(int contents, int id=-1)
idVec3 GetLocalCoordinates(const idVec3 &vec) const
Definition: Entity.cpp:2240
bool controlsDisabled
Definition: Mover.h:248
void Link(idClip &clp)
Definition: Clip.cpp:545
void Restore(idRestoreGame *savefile)
Definition: Game_local.h:661
void Spawn(void)
Definition: Mover.cpp:4591
extrapolation_t
Definition: Extrapolate.h:40
static void GetMovedir(float dir, idVec3 &movedir)
Definition: Mover.cpp:2391
idMat3 mat3_identity(idVec3(1, 0, 0), idVec3(0, 1, 0), idVec3(0, 0, 1))
bool GetMasterPosition(idVec3 &masterOrigin, idMat3 &masterAxis) const
Definition: Entity.cpp:2313
int lastFloor
Definition: Mover.h:247
virtual void SetContents(int contents, int id=-1)=0
void WriteObject(const idClass *obj)
Definition: SaveGame.cpp:329
idVec3 GetCenter(void) const
Definition: Bounds.h:211
void Close(void)
Definition: Mover.cpp:3554
float damage
Definition: Mover.h:334
void MatchActivateTeam(moverState_t newstate, int time)
Definition: Mover.cpp:2493
const idMat3 & GetAxis(int id=0) const
void Event_Use_BinaryMover(idEntity *activator)
Definition: Mover.cpp:2884
idEntityPtr< idEntity > splineEnt
Definition: Mover.h:149
idClip clip
Definition: Game_local.h:296
const idEventDef EV_Door_IsLocked("isLocked", NULL, 'f')
void SetPortalState(bool open)
Definition: Mover.cpp:3102
void Printf(const char *fmt,...) const id_attribute((format(printf
Definition: Game_local.cpp:699
void Event_RotateDownTo(int axis, float angle)
Definition: Mover.cpp:1203
virtual void Hide(void)
Definition: Mover.cpp:389
virtual void SetStateString(const char *varName, const char *value)=0
void Spawn()
Definition: Mover.cpp:1669
void SetContents(int newContents)
Definition: Clip.h:166
virtual void Show(void)
Definition: Mover.cpp:399
struct idEntity::entityFlags_s fl
void SetAngularExtrapolation(extrapolation_t type, int time, int duration, const idAngles &base, const idAngles &speed, const idAngles &baseSpeed)
void Bind(idEntity *master, bool orientated)
Definition: Entity.cpp:1896
type * GetEntity(void) const
Definition: Game_local.h:695
extrapolation_t GetLinearExtrapolationType(void) const
idMat3 localTriggerAxis
Definition: Mover.h:417
idStr syncLock
Definition: Mover.h:420
void SetShaderParm(int parmnum, float value)
Definition: Entity.cpp:1067
void Event_StopRotating(void)
Definition: Mover.cpp:793
void Event_GotoFloor(int floor)
Definition: Mover.cpp:1893
void Restore(idRestoreGame *savefile)
Definition: Mover.cpp:4342
const idEventDef EV_Time("time","f")
float GetFloat(void) const
Definition: CVarSystem.h:144
const GLdouble * v
Definition: glext.h:2936
void Event_RemoveInitialSplineAngles(void)
Definition: Mover.cpp:1392
const idStr & GetKey(void) const
Definition: Dict.h:52
int pendingFloor
Definition: Mover.h:246
void SetNum(int newnum, bool resize=true)
Definition: List.h:289
virtual void PreBind(void)
Definition: Mover.cpp:3400
const idEventDef EV_Activate("activate","e")
GLint location
Definition: glext.h:3631
const idEventDef EV_Door_Lock("lock","d")
idEntity * GetActivator(void) const
Definition: Mover.cpp:3062
const idEventDef EV_Mover_MatchTeam("<matchteam>","dd")
idMover_Binary * activateChain
Definition: Mover.h:327
const idEventDef EV_MoveSound("moveSound","s")
void Event_TeamBlocked(idEntity *blockedEntity, idEntity *blockingEntity)
Definition: Mover.cpp:4275
void Event_Lock(int f)
Definition: Mover.cpp:3981
idMat3 Transpose(void) const
Definition: Matrix.h:677
void Spawn(void)
Definition: Mover.cpp:334
int Length(void) const
Definition: Str.h:702
void void void void void Error(const char *fmt,...) const id_attribute((format(printf
Definition: Game_local.cpp:783
qhandle_t areaPortal
Definition: Mover.h:153
void GetLocalTriggerPosition(const idClipModel *trigger)
Definition: Mover.cpp:3507
void SetMoverState(moverState_t newstate, int time)
Definition: Mover.cpp:2442
static int CurrentThreadNum(void)
bool IsType(const idTypeInfo &c) const
Definition: Class.h:337
const idEventDef EV_Door_StartOpen("<startOpen>", NULL)
void Event_Bob(float speed, float phase, idVec3 &depth)
Definition: Mover.cpp:1293
void Event_Activate(idEntity *activator)
Definition: Mover.cpp:1458
void Set(const float x, const float y, const float z)
Definition: Vector.h:409
bool noTouch
Definition: Mover.h:410
bool useSplineAngles
Definition: Mover.h:148
void Event_TeamBlocked(idEntity *blockedEntity, idEntity *blockingEntity)
Definition: Mover.cpp:3813
const idMat3 & GetAxis(void) const
Definition: Clip.h:210
void Event_Touch(idEntity *other, trace_t *trace)
Definition: Mover.cpp:1704
void SetAngles(const idAngles &ang)
Definition: Entity.cpp:2812
idEntity * FindEntity(const char *name) const
void Use_BinaryMover(idEntity *activator)
Definition: Mover.cpp:2825
const idEventDef EV_RotateDownTo("rotateDownTo","df")
virtual void Hide(void)
Definition: Mover.cpp:3429
Definition: Mover.h:548
#define MASK_SOLID
Definition: Game_local.h:735
const idKeyValue * MatchPrefix(const char *prefix, const idKeyValue *lastMatch=NULL) const
Definition: Dict.cpp:523
void Event_UpdateMove(void)
Definition: Mover.cpp:657
bool ProcessEvent(const idEventDef *ev)
Definition: Class.cpp:858
Definition: Mover.h:377
void WriteBits(int value, int numBits)
Definition: BitMsg.cpp:648
void Open(void)
Definition: Mover.cpp:3545
int returnFloor
Definition: Mover.h:250
void Event_SpectatorTouch(idEntity *other, trace_t *trace)
Definition: Mover.cpp:3885
float returnTime
Definition: Mover.h:249
#define AREACONTENTS_OBSTACLE
Definition: AASFile.h:81
idElevator(void)
Definition: Mover.cpp:1596
void SetPortalState(bool open)
Definition: Mover.cpp:1533
int soundLoop
Definition: Mover.h:332
idStr team
Definition: Mover.h:340
virtual void DoneRotating(void)
Definition: Mover.cpp:804
virtual void WriteToSnapshot(idBitMsgDelta &msg) const
Definition: Mover.cpp:4387
int accelTime
Definition: Mover.h:336
void Event_StartSpline(idEntity *splineEntity)
Definition: Mover.cpp:1409
void Restore(idRestoreGame *savefile)
Definition: Mover.cpp:4465
int move_thread
Definition: Mover.h:342
void Event_SpawnSoundTrigger(void)
Definition: Mover.cpp:3762
void Spawn(void)
Definition: Mover.cpp:2300
virtual void Show(void)
Definition: Mover.cpp:3468
Definition: Vector.h:316
case const float
Definition: Callbacks.cpp:62
void ReadBool(bool &value)
Definition: SaveGame.cpp:976
const idBounds & GetAbsBounds(int id=-1) const
idAngles ang_zero(0.0f, 0.0f, 0.0f)
virtual void ReadFromSnapshot(const idBitMsgDelta &msg)
Definition: Mover.cpp:1507
void Spawn(void)
Definition: Mover.cpp:3245
const idEventDef EV_EnableSplineAngles("enableSplineAngles", NULL)
GLint GLint GLsizei GLsizei GLsizei depth
Definition: glext.h:2878
int normalAxisIndex
Definition: Mover.h:421
const idEventDef EV_StartSpline("startSpline","e")
float triggersize
Definition: Mover.h:408
void WriteStaticObject(const idClass &obj)
Definition: SaveGame.cpp:348
static float Sqrt(float x)
Definition: Math.h:302
void JoinTeam(idEntity *teammember)
Definition: Entity.cpp:2377
const idEventDef EV_AccelTime("accelTime","f")
void SetAASAreaState(bool closed)
Definition: Mover.cpp:3419
void Event_Close(void)
Definition: Mover.cpp:3972
void SpawnPlatTrigger(idVec3 &pos)
Definition: Mover.cpp:4223
idVec3 dest_position
Definition: Mover.h:141
void SetGuiState(const char *key, const char *val) const
Definition: Mover.cpp:537
void UpdateBuddies(int val)
Definition: Mover.cpp:2786
const idVec3 & GetOrigin(void) const
Definition: Clip.h:206
idStr door
Definition: Mover.h:210
void Event_Enable(void)
Definition: Mover.cpp:2553
void Clear(void)
Definition: Bounds.h:201
float move_speed
Definition: Mover.h:143
void Event_InitGuiTargets(void)
Definition: Mover.cpp:585
void SetLinearExtrapolation(extrapolation_t type, int time, int duration, const idVec3 &base, const idVec3 &speed, const idVec3 &baseSpeed)
Definition: Token.h:71
void Save(idSaveGame *savefile) const
Definition: Mover.cpp:4332
void Event_TeamBlocked(idEntity *blockedEntity, idEntity *blockingEntity)
Definition: Mover.cpp:1789
const idEventDef EV_StopSpline("stopSpline", NULL)
int removeItem
Definition: Mover.h:419
virtual void PostBind(void)
Definition: Mover.cpp:2903
void Restore(idRestoreGame *savefile)
Definition: Mover.cpp:2229
void Event_MoveToPos(idVec3 &pos)
Definition: Mover.cpp:1092
GLuint src
Definition: glext.h:5390
void UpdateMoverSound(moverState_t state)
Definition: Mover.cpp:2420
void Set(const char *key, const char *value)
Definition: Dict.cpp:275
void Event_StopSpline(void)
Definition: Mover.cpp:1448
void Use(idEntity *other, idEntity *activator)
Definition: Mover.cpp:3525
int ReadBits(int numBits) const
Definition: BitMsg.cpp:709
virtual void Think(void)
Definition: Mover.cpp:4165
const idEventDef EV_ReachedAng("<reachedang>", NULL)
void ShiftTime(const float deltaTime)
Definition: Curve.h:360
const idEventDef EV_PostRestore("<postrestore>","ddddd")
elevatorState_t state
Definition: Mover.h:243
void Event_Reached_BinaryMover(void)
Definition: Mover.cpp:2636
idDict spawnArgs
Definition: Entity.h:122
void Restore(idRestoreGame *savefile)
Definition: Mover.cpp:4105
virtual void Think(void)
Definition: Mover.cpp:4353
void Event_SpawnDoorTrigger(void)
Definition: Mover.cpp:3708
void WriteClipModel(const class idClipModel *clipModel)
Definition: SaveGame.cpp:744
void Event_InitGuiTargets(void)
Definition: Mover.cpp:2955
extrapolation_t GetAngularExtrapolationType(void) const
int i
Definition: process.py:33
const idEventDef EV_DecelSound("decelSound","s")
const idEventDef EV_MoveToPos("moveToPos","v")
void Spawn(void)
Definition: Mover.cpp:4653
void FindGuiTargets(void)
Definition: Mover.cpp:526
contactInfo_t c
GLuint GLuint num
Definition: glext.h:5390
void WriteVec3(const idVec3 &vec)
Definition: SaveGame.cpp:253
bool HasChanged(void) const
Definition: BitMsg.h:534
idAngles & Zero(void)
Definition: Angles.h:126
idMover_Binary * moveMaster
Definition: Mover.h:326
virtual void PostBind(void)
Definition: Mover.cpp:4195
void Event_DisableSplineAngles(void)
Definition: Mover.cpp:1383
const idEventDef EV_DecelTime("decelTime","f")
void Event_Touch(idEntity *other, trace_t *trace)
Definition: Mover.cpp:4260
~idPlat(void)
Definition: Mover.cpp:4083
void Think(void)
Definition: Mover.cpp:1731
int Icmp(const char *text) const
Definition: Str.h:667
bool CheckDormant(void)
Definition: Entity.cpp:946
#define EVENT(event, function)
Definition: Class.h:53
void SetAxis(const idMat3 &newAxis, int id=-1)
virtual void Think(void)
Definition: Mover.cpp:3376
idEntityPtr< idEntity > activatedBy
Definition: Mover.h:521
idVec3 endpos
void Event_MoveDir(float angle, float distance)
Definition: Mover.cpp:1101
void WriteBool(const bool value)
Definition: SaveGame.cpp:222
const idEventDef EV_Mover_ClosePortal("closePortal")
void Event_Open(void)
Definition: Mover.cpp:3963
void Save(idSaveGame *savefile) const
Definition: Mover.cpp:2170
void SetClipModel(idClipModel *model, float density, int id=0, bool freeOld=true)
bool IsHidden(void) const
Definition: Entity.cpp:1217
idCurve_Spline< idVec3 > * GetSpline(void) const
Definition: Entity.cpp:3755
virtual void Killed(idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location)
Definition: Mover.cpp:412
void Event_Rotate(idAngles &angles)
Definition: Mover.cpp:1257
void void void Warning(const char *fmt,...) const id_attribute((format(printf
Definition: Game_local.cpp:735
void EnableProperDoors(void)
Definition: Mover.cpp:2057
virtual const idBounds & GetBounds(int id=-1) const =0
const idEventDef EV_GotoFloor("gotoFloor","d")
void Event_ClosePortal(void)
Definition: Mover.cpp:1336
const idEventDef EV_Door_SpawnDoorTrigger("<spawnDoorTrigger>", NULL)
void SetPortalState(qhandle_t portal, int blockingBits)
idAngles angle_delta
Definition: Mover.h:140
void Event_MoveDecelerateTo(float speed, float time)
Definition: Mover.cpp:1160
const int USERCMD_MSEC
Definition: UsercmdGen.h:41
void Event_MatchActivateTeam(moverState_t newstate, int time)
Definition: Mover.cpp:2515
Definition: Lexer.h:137
void UpdateRotationSound(moveStage_t stage)
Definition: Mover.cpp:817
void Spawn(void)
Definition: Mover.cpp:4530
virtual void Show(void)
Definition: Entity.cpp:1239
virtual void Think(void)
Definition: Entity.cpp:891
void SetSelf(idEntity *e)
const idEventDef EV_IsRotating("isRotating", NULL, 'd')
void Event_PostFloorArrival()
Definition: Mover.cpp:1971
void Save(idSaveGame *savefile) const
Definition: Mover.cpp:3188
void SetGuiStates(const char *state)
Definition: Mover.cpp:567
const idEventDef EV_Door_Close("close", NULL)
void Set(float pitch, float yaw, float roll)
Definition: Angles.h:120
void OpenInnerDoor(void)
Definition: Mover.cpp:1867
const idEventDef EV_Move("move","ff")
idMover_Binary * GetMoveMaster(void) const
Definition: Mover.h:311
idStr requires
Definition: Mover.h:418
void Event_Activate(idEntity *activator)
Definition: Mover.cpp:4474
Definition: Mover.h:45
idPhysics * GetPhysics(void) const
Definition: Entity.cpp:2607
idClipModel * trigger
Definition: Mover.h:413
moverState_t moverState
Definition: Mover.h:325
idAngles ToAngles(void) const
Definition: Vector.cpp:130
idDoor * companionDoor
Definition: Mover.h:422
const int SHADERPARM_MODE
Definition: RenderWorld.h:53
const GLubyte * c
Definition: glext.h:4677
void FindGuiTargets(void)
Definition: Mover.cpp:2913
const char * GetString(const char *key, const char *defaultString="") const
Definition: Dict.h:240
void OpenFloorDoor(int floor)
Definition: Mover.cpp:1852
void ReadFloat(float &value)
Definition: SaveGame.cpp:967
float Length(void) const
Definition: Vector.h:631
virtual void PreBind(void)
Definition: Mover.cpp:4186
idVec3 ToForward(void) const
Definition: Angles.cpp:117
bool StartSound(const char *soundName, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length)
Definition: Entity.cpp:1622
idVec3 vec3_origin(0.0f, 0.0f, 0.0f)
void Event_OpenPortal(void)
Definition: Mover.cpp:1323
const idEventDef EV_PartBlocked("<partblocked>","e")
const idEventDef EV_RotateTo("rotateTo","v")
virtual renderEntity_t * GetRenderEntity(void)
Definition: Entity.cpp:1506
idStrList buddies
Definition: Mover.h:344
void SetOrigin(const idVec3 &newOrigin, int id=-1)
#define vec3_zero
Definition: Vector.h:390
void SetPhysics(idPhysics *phys)
Definition: Entity.cpp:2574
const idEventDef EV_Mover_ReturnToPos1("<returntopos1>", NULL)
void Event_Locked(void)
Definition: Mover.cpp:4002
int duration
Definition: Mover.h:335
int move_time
Definition: Mover.h:144
int updateStatus
Definition: Mover.h:343
void WriteFloat(const float value)
Definition: SaveGame.cpp:213
void BindTeam(idEntity *bindTo)
Definition: Mover.cpp:2526
static float Fabs(float f)
Definition: Math.h:779
idCVar g_gravity("g_gravity", DEFAULT_GRAVITY_STRING, CVAR_GAME|CVAR_FLOAT,"")
void Event_StartOpen(void)
Definition: Mover.cpp:3683
idCommon * common
Definition: Common.cpp:206
int nextSndTriggerTime
Definition: Mover.h:415
const idEventDef EV_StopMoving("stopMoving", NULL)
void Event_SetMoveSpeed(float speed)
Definition: Mover.cpp:1014
bool GetBool(const char *key, const char *defaultString="0") const
Definition: Dict.h:256
moverState_t
Definition: Mover.h:280
idVec3 origin
Definition: Game.h:211
void GetLocalTriggerPosition(const idClipModel *trigger)
Definition: Mover.cpp:4205
#define NULL
Definition: Lib.h:88
static const float SQRT_1OVER2
Definition: Math.h:212
void Spawn(void)
Definition: Mover.cpp:1562
bool blocked
Definition: Mover.h:347
void Event_SetDecelSound(const char *sound)
Definition: Mover.cpp:1356
void Event_IsMoving(void)
Definition: Mover.cpp:1468
void Save(idSaveGame *savefile) const
Definition: Mover.cpp:1613
idVec3 pos1
Definition: Mover.h:323
void InitTime(idVec3 &mpos1, idVec3 &mpos2, float mtime, float maccelTime, float mdecelTime)
Definition: Mover.cpp:3005
idVec3 GetVector(const char *key, const char *defaultString=NULL) const
Definition: Dict.h:260
idVec3 localTriggerOrigin
Definition: Mover.h:416
const int MAX_RENDERENTITY_GUI
Definition: RenderWorld.h:74
const idEventDef EV_Rotate("rotate","v")
int soundPos2
Definition: Mover.h:331
void CancelEvents(const idEventDef *ev)
Definition: Class.cpp:619
void SetGuiStates(const char *state)
Definition: Mover.cpp:2806
int GetSplineDeceleration(void) const
moverCommand_t lastCommand
Definition: Mover.h:150
int soundPos1
Definition: Mover.h:328
static void ReturnFloat(float value)
class idDoor * GetDoor(const char *name)
Definition: Mover.cpp:1942
void Save(idSaveGame *savefile) const
Definition: Mover.cpp:4456
float roll
Definition: Angles.h:55
void InitSpeed(idVec3 &mpos1, idVec3 &mpos2, float mspeed, float maccelTime, float mdecelTime)
Definition: Mover.cpp:2968
Definition: Mover.h:447
const idEventDef EV_MoveTo("moveTo","e")
void GetLocalAngles(idAngles &curAngles) const
virtual void ReadFromSnapshot(const idBitMsgDelta &msg)
Definition: Mover.cpp:4397
void Event_OpenPortal(void)
Definition: Mover.cpp:2583
const idStr & GetValue(void) const
Definition: Dict.h:53
int GetId(void) const
Definition: Clip.h:186
void ReadGUIFromSnapshot(const idBitMsgDelta &msg)
Definition: Entity.cpp:4861
virtual const idMat3 & GetAxis(int id=0) const =0
bool enabled
Definition: Mover.h:341
const idEventDef EV_AccelSound("accelSound","s")
const char * Right(int len, idStr &result) const
Definition: Str.h:896
idPhysics_Parametric physicsObj
Definition: Mover.h:345
void Event_ClosePortal(void)
Definition: Mover.cpp:4035
static void ObjectMoveDone(int threadnum, idEntity *obj)
idVec3 pos2
Definition: Mover.h:324
void Event_RotateOnce(idAngles &angles)
Definition: Mover.cpp:1275
idLinkList< idEntity > spawnNode
Definition: Entity.h:114
gameState_t GameState(void) const
void Event_PartBlocked(idEntity *blockingEntity)
Definition: Mover.cpp:3842
int GetLinearEndTime(void) const
int lastSpectateTeleport
Definition: Player.h:341
float pitch
Definition: Angles.h:53
int sound2to1
Definition: Mover.h:330
virtual type GetCurrentFirstDerivative(const float time) const
Definition: Curve.h:153
idGameLocal gameLocal
Definition: Game_local.cpp:64
bool RunPhysics(void)
Definition: Entity.cpp:2616
moveStage_t
Definition: Mover.h:67
void JoinActivateTeam(idMover_Binary *master)
Definition: Mover.cpp:2541
void UnreadToken(const idToken *token)
Definition: Lexer.cpp:1159
void SetGuiState(const char *key, const char *val) const
Definition: Mover.cpp:2924
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
idRenderModel * hModel
Definition: RenderWorld.h:81
bool UsingSplineAngles(void) const
int rotate_thread
Definition: Mover.h:138
void Save(idSaveGame *savefile) const
Definition: Mover.cpp:4094
const idEventDef EV_RotateUpTo("rotateUpTo","df")
idLinkList< idEntity > spawnedEntities
Definition: Game_local.h:281
virtual void Hide(void)
Definition: Entity.cpp:1226
void Event_MoveAccelerateTo(float speed, float time)
Definition: Mover.cpp:1117
void Event_SetCallback(void)
Definition: Mover.cpp:423
virtual idClipModel * GetClipModel(int id=0) const =0
void DisableAllDoors(void)
Definition: Mover.cpp:2039
GLenum GLsizei GLsizei height
Definition: glext.h:2856
void WriteInt(const int value)
Definition: SaveGame.cpp:168
virtual void Present(void)
Definition: Entity.cpp:1471
float GetTime(const int index) const
Definition: Curve.h:60
const idEventDef EV_Door_Open("open", NULL)
bool IsOpen(void)
Definition: Mover.cpp:3608
int GetTargets(const idDict &args, idList< idEntityPtr< idEntity > > &list, const char *ref) const
const idEventDef EV_FindGuiTargets("<FindGuiTargets>", NULL)
void Restore(idRestoreGame *savefile)
Definition: Mover.cpp:1639
void WriteMat3(const idMat3 &mat)
Definition: SaveGame.cpp:309
void SetCompanion(idDoor *door)
Definition: Mover.cpp:3833
#define SEC2MS(t)
Definition: Math.h:59
const idVec3 & GetLinearVelocity(int id=0) const
void Event_Activate(idEntity *activator)
Definition: Mover.cpp:4675
idMover_Binary * GetActivateChain(void) const
Definition: Mover.h:310
floorInfo_s * GetFloorInfo(int floor)
Definition: Mover.cpp:1879
GLubyte GLubyte b
Definition: glext.h:4662
void ReadMat3(idMat3 &mat)
Definition: SaveGame.cpp:1064
static const float TWO_PI
Definition: Math.h:206
virtual qhandle_t FindPortal(const idBounds &b) const =0
const idEventDef EV_Sway("sway","ffv")
idVec3 GetWorldCoordinates(const idVec3 &vec) const
Definition: Entity.cpp:2291
idVec3 move_delta
Definition: Mover.h:142
const idEventDef EV_Mover_Disable("disable", NULL)
int health
Definition: Entity.h:134
void SetBlocked(bool b)
Definition: Mover.cpp:3032
const idEventDef EV_TeamBlocked("<teamblocked>","ee")
void Event_Activate(idEntity *activator)
Definition: Mover.cpp:1777
void ReadStaticObject(idClass &obj)
Definition: SaveGame.cpp:1098
idVec3 localTriggerOrigin
Definition: Mover.h:465
void ReadClipModel(idClipModel *&clipModel)
Definition: SaveGame.cpp:1519
int Append(const type &obj)
Definition: List.h:646
virtual void BeginMove(idThread *thread=NULL)
Definition: Mover.cpp:705
void VectorForDir(float dir, idVec3 &vec)
Definition: Mover.cpp:442
void SetInt(const char *key, int val)
Definition: Dict.h:192
Definition: Matrix.h:333
int currentFloor
Definition: Mover.h:245
virtual void BeginMove(idThread *thread=NULL)
Definition: Mover.cpp:1915
void Event_SetCallback(void)
Definition: Mover.cpp:2406
void Event_SetMoveTime(float time)
Definition: Mover.cpp:1028
void SetAASAreaState(const idBounds &bounds, const int areaContents, bool closed)
bool IsBlocked(void)
Definition: Mover.cpp:3053
void WriteAngles(const idAngles &angles)
Definition: SaveGame.cpp:318
void SetClipMask(int mask, int id=-1)
idPhysics_Parametric physicsObj
Definition: Mover.h:115
float yaw
Definition: Angles.h:54
void SetLinearInterpolation(int time, int accelTime, int decelTime, int duration, const idVec3 &startPos, const idVec3 &endPos)
void UpdateVisuals(void)
Definition: Entity.cpp:1310
void Event_TeamBlocked(idEntity *blockedEntity, idEntity *blockingEntity)
Definition: Mover.cpp:4368
bool GetBool(void) const
Definition: CVarSystem.h:142
soundShaderParms_t parms
Definition: Game.h:218
void Event_PartBlocked(idEntity *blockingEntity)
Definition: Mover.cpp:1000
idCVar g_debugMover("g_debugMover","0", CVAR_GAME|CVAR_BOOL,"")
void Enable(void)
Definition: Clip.h:150
tuple f
Definition: idal.py:89
void GetLocalOrigin(idVec3 &curOrigin) const
int decelTime
Definition: Mover.h:337
idAngles dest_angles
Definition: Mover.h:139
void Event_ClosePortal(void)
Definition: Mover.cpp:2605
virtual void DoneMoving(void)
Definition: Mover.cpp:610
int Num(void) const
Definition: List.h:265
void Event_PostRestore(int start, int total, int accel, int decel, int useSplineAng)
Definition: Mover.cpp:310
void Event_ReturnToPos1(void)
Definition: Mover.cpp:2627
const idEventDef EV_StopRotating("stopRotating", NULL)
const idEventDef EV_MoveDecelerateTo("decelTo","ff")
virtual const idBounds & GetAbsBounds(int id=-1) const =0
idVec3 pos
Definition: Mover.h:209
moveState_t move
Definition: Mover.h:132
void Event_RotateTo(idAngles &angles)
Definition: Mover.cpp:1247
const GLcharARB * name
Definition: glext.h:3629
GLsizeiptr size
Definition: glext.h:3112
idClipModel * trigger
Definition: Mover.h:464
void Signal(signalNum_t signalnum)
Definition: Entity.cpp:3352
const idEventDef EV_IsMoving("isMoving", NULL, 'd')
const idEventDef EV_Bob("bob","ffv")
idVec3 GetWorldVector(const idVec3 &vec) const
Definition: Entity.cpp:2267
#define CLASS_DECLARATION(nameofsuperclass, nameofclass)
Definition: Class.h:110
const idEventDef EV_MoveAccelerateTo("accelTo","ff")
idList< idEntityPtr< idEntity > > guiTargets
Definition: Mover.h:155
Definition: Str.h:116
const idEventDef EV_PostArrival("postArrival", NULL)
void Event_Sway(float speed, float phase, idAngles &depth)
Definition: Mover.cpp:1305
int acceltime
Definition: Mover.h:146
~idDoor(void)
Definition: Mover.cpp:3174
GLsizei const GLcharARB const GLint * length
Definition: glext.h:3599
float damage
Definition: Mover.h:151
void Event_PartBlocked(idEntity *blockingEntity)
Definition: Mover.cpp:4285
float damage
Definition: Mover.h:503
virtual void PostBind(void)
Definition: Mover.cpp:3409
void Event_RotateUpTo(int axis, float angle)
Definition: Mover.cpp:1225
const char * GetName(void) const
Definition: Entity.cpp:875
static int SnapTimeToPhysicsFrame(int t)
Definition: Physics.cpp:76
void Event_FindGuiTargets(void)
Definition: Mover.cpp:558
void Save(idSaveGame *savefile) const
Definition: Game_local.h:656
void ReadVec3(idVec3 &vec)
Definition: SaveGame.cpp:1011
float wait
Definition: Mover.h:333
class idUserInterface * gui[MAX_RENDERENTITY_GUI]
Definition: RenderWorld.h:130
const char * c_str(void) const
Definition: Str.h:487
void Save(idSaveGame *savefile) const
Definition: Mover.cpp:167
bool RequirementMet(idEntity *activator, const idStr &requires, int removeItem)
void ReadAngles(idAngles &angles)
Definition: SaveGame.cpp:1073
void RestorePhysics(idPhysics *phys)
Definition: Entity.cpp:2596
const idEventDef EV_SpectatorTouch("spectatorTouch","et")
void BecomeActive(int flags)
Definition: Entity.cpp:995
refSound_t refSound
Definition: Entity.h:373
void SetSpline(idCurve_Spline< idVec3 > *spline, int accelTime, int decelTime, bool useSplineAngles)
void MakeUniform(const float totalTime)
Definition: Curve.h:319
idAngles ToAngles(void) const
Definition: Matrix.cpp:147
void Spawn(void)
Definition: Mover.cpp:4320
virtual int GetPortalState(qhandle_t portal)=0
bool crusher
Definition: Mover.h:409
idList< floorInfo_s > floorInfo
Definition: Mover.h:244
void Spawn(void)
Definition: Mover.cpp:4116
idStr buddyStr
Definition: Mover.h:412
const idBounds & GetAbsBounds(void) const
Definition: Clip.h:202
void Event_SetAccelSound(const char *sound)
Definition: Mover.cpp:1347
void ReadFromSnapshot(const idBitMsgDelta &msg)
void Restore(idRestoreGame *savefile)
Definition: Mover.cpp:3216
rotationState_t rot
Definition: Mover.h:135
void UpdateMoveSound(moveStage_t stage)
Definition: Mover.cpp:629
void Disable(void)
Definition: Clip.h:154
void GotoPosition1(void)
Definition: Mover.cpp:2692
void Restore(idRestoreGame *savefile)
Definition: Mover.cpp:234
virtual void ReadFromSnapshot(const idBitMsgDelta &msg)
Definition: Mover.cpp:3082
const idEventDef EV_Thread_SetCallback("<script_setcallback>", NULL)
GLint j
Definition: qgl.h:264
qhandle_t areaPortal
Definition: Mover.h:346
int lastTouchTime
Definition: Mover.h:251
virtual void DoneMoving(void)
Definition: Mover.cpp:1992
void WriteGUIToSnapshot(idBitMsgDelta &msg) const
Definition: Entity.cpp:4847
void Event_UpdateRotation(void)
Definition: Mover.cpp:845
void Event_IsOpen(void)
Definition: Mover.cpp:3990
void MoveToPos(const idVec3 &pos)
Definition: Mover.cpp:1082
idRenderWorld * gameRenderWorld
Definition: Game_local.cpp:55
char * va(const char *fmt,...)
Definition: Str.cpp:1568
bool aas_area_closed
Definition: Mover.h:411
int GetNumValues(void) const
Definition: Curve.h:56
void Event_FindGuiTargets(void)
Definition: Mover.cpp:2946
virtual void BeginRotation(idThread *thread, bool stopwhendone)
Definition: Mover.cpp:910
void Event_Touch(idEntity *other, trace_t *trace)
Definition: Mover.cpp:3853
void ReadBindFromSnapshot(const idBitMsgDelta &msg)
Definition: Entity.cpp:4780
idList< idEntityPtr< idEntity > > guiTargets
Definition: Mover.h:351
void SetOrigin(const idVec3 &org)
Definition: Entity.cpp:2784
bool PostEventMS(const idEventDef *ev, int time)
Definition: Class.cpp:666
moveStage_t stage
Definition: Mover.h:108
void Event_OpenPortal(void)
Definition: Mover.cpp:4013
void Spawn(void)
Definition: Mover.cpp:4433
GLfloat GLfloat p
Definition: glext.h:4674
void Event_IsRotating(void)
Definition: Mover.cpp:1481
void WriteToSnapshot(idBitMsgDelta &msg) const
idStr name
Definition: Entity.h:121
virtual void WriteToSnapshot(idBitMsgDelta &msg) const
Definition: Mover.cpp:3071
int thinkFlags
Definition: Entity.h:125
void ToVectors(idVec3 *forward, idVec3 *right=NULL, idVec3 *up=NULL) const
Definition: Angles.cpp:92
int floor
Definition: Mover.h:211
int stateStartTime
Definition: Mover.h:339
const idEventDef EV_DisableSplineAngles("disableSplineAngles", NULL)
const idEventDef EV_Touch("<touch>","et")
idEntityPtr< idEntity > activatedBy
Definition: Mover.h:338
void Event_Reached_BinaryMover(void)
Definition: Mover.cpp:3784
void Zero(void)
Definition: Vector.h:415
int IsLocked(void)
Definition: Mover.cpp:3599
virtual void virtual void Warning(const char *fmt,...) id_attribute((format(printf
float shaderParms[MAX_ENTITY_SHADER_PARMS]
Definition: RenderWorld.h:127
void CalcTriggerBounds(float size, idBounds &bounds)
Definition: Mover.cpp:3643
void ReadString(idStr &string)
Definition: SaveGame.cpp:985
void GotoPosition2(void)
Definition: Mover.cpp:2740
void Event_MoveTo(idEntity *ent)
Definition: Mover.cpp:1068
static void ReturnInt(int value)
void Enable(bool b)
Definition: Mover.cpp:2506
int ReadToken(idToken *token)
Definition: Lexer.cpp:820
idClipModel * sndTrigger
Definition: Mover.h:414
void ReadInt(int &value)
Definition: SaveGame.cpp:922
const idEventDef EV_Mover_InitGuiTargets("<initguitargets>", NULL)
void ActivateTargets(idEntity *activator) const
Definition: Entity.cpp:3650
const idEventDef EV_Door_SpawnSoundTrigger("<spawnSoundTrigger>", NULL)
void Event_EnableSplineAngles(void)
Definition: Mover.cpp:1374
GLuint start
Definition: glext.h:2845
void StopSound(const s_channelType channel, bool broadcast)
Definition: Entity.cpp:1713
void Event_Activate(idEntity *activator)
Definition: Mover.cpp:3919
int soundShaderFlags
Definition: sound.h:65
int GetSplineAcceleration(void) const
#define AREACONTENTS_CLUSTERPORTAL
Definition: AASFile.h:80
void Lock(int f)
Definition: Mover.cpp:3563
void Event_SetDecelerationTime(float time)
Definition: Mover.cpp:1055
const idEventDef EV_RotateOnce("rotateOnce","v")
void ReadObject(idClass *&obj)
Definition: SaveGame.cpp:1083
idCurve_Spline< idVec3 > * GetSpline(void) const
const idEventDef EV_Door_IsOpen("isOpen", NULL, 'f')
int sound1to2
Definition: Mover.h:329
const idEventDef EV_RemoveInitialSplineAngles("removeInitialSplineAngles", NULL)
virtual void PreBind(void)
Definition: Mover.cpp:2893
void Event_SetMoveSound(const char *sound)
Definition: Mover.cpp:1365
void Clear(void)
Definition: List.h:184
const idEventDef EV_Speed("speed","f")
virtual bool HandleSingleGuiCommand(idEntity *entityGui, idLexer *src)
Definition: Mover.cpp:1809
moverState_t GetMoverState(void) const
Definition: Mover.h:358
bool IsNoTouch(void)
Definition: Mover.cpp:3617