‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
vehicleriders_shared.gsc
Go to the documentation of this file.
1 #using scripts\codescripts\struct;
2 
3 #using scripts\shared\ai_shared;
4 #using scripts\shared\animation_shared;
5 #using scripts\shared\array_shared;
6 #using scripts\shared\callbacks_shared;
7 #using scripts\shared\clientfield_shared;
8 #using scripts\shared\colors_shared;
9 #using scripts\shared\flag_shared;
10 #using scripts\shared\flagsys_shared;
11 #using scripts\shared\spawner_shared;
12 #using scripts\shared\system_shared;
13 #using scripts\shared\trigger_shared;
14 #using scripts\shared\util_shared;
15 #using scripts\shared\ai\systems\gib;
16 #using scripts\shared\hostmigration_shared;
17 
18 #insert scripts\shared\ai\systems\gib.gsh;
19 #insert scripts\shared\shared.gsh;
20 #insert scripts\shared\version.gsh;
21 #insert scripts\shared\archetype_shared\archetype_shared.gsh;
22 
23 #using_animtree( "generic" );
24 
25 #namespace vehicle;
26 
28 // TODO:
29 //
30 // * Implement death anims
32 
33 ‪REGISTER_SYSTEM( "vehicleriders", &‪__init__, undefined )
34 
35 function ‪__init__()
36 {
37  level.vehiclerider_groups = [];
38  level.vehiclerider_groups[ "all" ] = "all";
39  level.vehiclerider_groups[ "driver" ] = "driver";
40  level.vehiclerider_groups[ "passengers" ] = "passenger";
41  level.vehiclerider_groups[ "crew" ] = "crew";
42  level.vehiclerider_groups[ "gunners" ] = "gunner";
43 
44  a_registered_fields = [];
45  foreach ( bundle in ‪struct::get_script_bundles( "vehicleriders" ) )
46  {
47  foreach ( object in bundle.objects )
48  {
49  if ( IsString( object.VehicleEnterAnim ) )
50  {
51  ‪array::add( a_registered_fields, object.position + "_enter", false );
52  }
53 
54  if ( IsString( object.VehicleExitAnim ) )
55  {
56  ‪array::add( a_registered_fields, object.position + "_exit", false );
57  }
58 
59  if ( IsString( object.VehicleRiderDeathAnim ) )
60  {
61  ‪array::add( a_registered_fields, object.position + "_death", false );
62  }
63  }
64  }
65 
66  foreach ( str_clientfield in a_registered_fields )
67  {
68  ‪clientfield::register( "vehicle", str_clientfield, ‪VERSION_SHIP, 1, "counter" );
69  }
70 
71 
72  level.vehiclerider_use_index = [];
73  level.vehiclerider_use_index[ "driver" ] = 0;
74 
75  // Set up gunnner use indices.
76  const MAX_USE_INDEX = 4;
77  for ( i = 1; i <= MAX_USE_INDEX; i++ )
78  {
79  level.vehiclerider_use_index[ "gunner" + i ] = i;
80  }
81 
82  // Setup passenger use indices
83  const MAX_PASSENGER_INDEX = 10;
84  passengerIndex = 1;
85  for ( i = MAX_USE_INDEX + 1; i <= MAX_PASSENGER_INDEX; i++ )
86  {
87  level.vehiclerider_use_index[ "passenger" + passengerIndex ] = i;
88  passengerIndex++;
89  }
90 
91  /* FIX UP STUFF FROM THE GDT */
92  foreach ( s in ‪struct::get_script_bundles( "vehicleriders" ) )
93  {
94  ‪DEFAULT( s.LowExitHeight, 0 );
95  ‪DEFAULT( s.HighExitLandHeight, 32 );
96  }
97 
101 }
102 
103 function ‪seat_position_to_index( str_position )
104 {
105  return level.vehiclerider_use_index[ str_position ];
106 }
107 
109 {
110  ‪spawn_riders();
111 }
112 
114 {
115  if ( IsVehicle( self ) )
116  {
117  self ‪spawn_riders();
118  }
119 }
120 
121 function ‪claim_position( vh, str_pos )
122 {
123  ‪array::add( vh.riders, self, false );
124  vh ‪flagsys::set( str_pos + "occupied" );
125  self ‪flagsys::set( "vehiclerider" );
126 
127  self thread ‪_unclaim_position_on_death( vh, str_pos );
128 }
129 
130 function ‪unclaim_position( vh, str_pos )
131 {
132  ArrayRemoveValue( vh.riders, self );
133  vh ‪flagsys::clear( str_pos + "occupied" );
134  self ‪flagsys::clear( "vehiclerider" );
135 }
136 
137 function private ‪_unclaim_position_on_death( vh, str_pos )
138 {
139  vh endon( "death" );
140  vh endon( str_pos + "occupied" );
141 
142  self waittill( "death" );
143 
144  ‪unclaim_position( vh, str_pos );
145 }
146 
148 {
149  foreach ( s_rider in ‪get_bundle_for_ai( ai ).objects )
150  {
151  seat_index = ‪seat_position_to_index(s_rider.position);
152  if( seat_index <= 4 ) // IsVehicleSeatOccupied only works on code seats and not passenger seats
153  {
154  if( self IsVehicleSeatOccupied( seat_index ) )
155  continue;
156  }
157 
158  if ( !‪flagsys::get( s_rider.position + "occupied" ) )
159  {
160  return s_rider.position;
161  }
162  }
163 }
164 
165 function ‪spawn_riders()
166 {
167  self endon("death");
168 
169  self.riders = [];
170  if ( isdefined( self.script_vehicleride ) )
171  {
172 
173  a_spawners = GetSpawnerArray( self.script_vehicleride, "script_vehicleride" );
174  foreach ( sp in a_spawners )
175  {
176  ai_rider = sp ‪spawner::spawn( true );
177  //ai_rider = util::spawn_anim_model( "c_hro_hendricks_base_fb" );
178 
179  if ( isdefined( ai_rider ) )
180  {
181  ai_rider ‪get_in( self, ai_rider.script_startingposition, true );
182  }
183  }
184  }
185 }
186 
187 function ‪get_bundle_for_ai( ai )
188 {
189  vh = self;
190  if ( ‪IS_ROBOT( ai ) )
191  {
192  bundle = vh ‪get_robot_bundle();
193  }
194  else
195  {
196  bundle = vh ‪get_bundle();
197  }
198  return bundle;
199 }
200 
201 function ‪get_rider_info( vh, str_pos = "driver" )
202 {
203  ai = self;
204  bundle = undefined;
205  bundle = vh ‪get_bundle_for_ai( ai );
206 
207  foreach ( s_rider in bundle.objects )
208  {
209  if ( s_rider.position == str_pos )
210  {
211  return s_rider;
212  }
213  }
214 }
215 
226 function ‪get_in( vh, str_pos, b_teleport = false )
227 {
228  self endon( "death" );
229  vh endon( "death" );
230 
231  if ( !isdefined( str_pos ) )
232  {
233  str_pos = vh ‪find_next_open_position( self );
234  }
235 
236  Assert( isdefined( str_pos ), "No unoccupied seats for vehicle rider." );
237 
238  if( !isdefined( str_pos ) )
239  {
240  return;
241  }
242 
243  //return if the seat is not available
244  if ( !isdefined( vh.ignore_seat_check ) || !vh.ignore_seat_check )
245  {
246  seat_index = level.vehiclerider_use_index[ str_pos ];
247  if( seat_index <= 4 ) // IsVehicleSeatOccupied only works on code seats and not passenger seats
248  {
249  seat_available = !(vh IsVehicleSeatOccupied( seat_index ) );
250  Assert( seat_available, "This seat is already occupied." );
251 
252  if(!seat_available)
253  {
254  return;
255  }
256  }
257  }
258 
259  ‪claim_position( vh, str_pos );
260 
261  if ( !b_teleport && self ‪flagsys::get( "in_vehicle" ) )
262  {
263  ‪get_out();
264  }
265 
266  if ( ‪colors::is_color_ai() )
267  {
269  }
270 
271  ‪_init_rider( vh, str_pos );
272 
273  if ( !b_teleport )
274  {
275  self ‪animation::set_death_anim( self.rider_info.EnterDeathAnim );
276  ‪animation::reach( self.rider_info.EnterAnim, self.vehicle, self.rider_info.AlignTag );
277 
278  // Animate the door on the client.
279  if ( isdefined( self.rider_info.VehicleEnterAnim ) )
280  {
281  vh ‪clientfield::increment( self.rider_info.position + "_enter", 1 );
282  self SetAnim( self.rider_info.VehicleEnterAnim, 1, 0, 1 );
283  }
284 
285  self ‪animation::play( self.rider_info.EnterAnim, self.vehicle, self.rider_info.AlignTag );
286  }
287 
288  if ( isdefined(self.rider_info) && isdefined( self.rider_info.RideAnim ) )
289  {
290  //disable unlink after the animation is done since this will be handled by UseVehicle
291  self thread ‪animation::play( self.rider_info.RideAnim, self.vehicle, self.rider_info.AlignTag, 1, 0.2, 0.2, 0, 0, false, false );
292  }
293  else if ( !isdefined( level.vehiclerider_use_index[ str_pos ] ) )
294  {
295  assert( "Rider is missing ride animation for seat: " + str_pos );
296  }
297  else if ( isdefined(self.rider_info) )
298  {
299  // HACK: teleport to align tag in the case of no ride animation being available (mainly for gunners)
300  // Since UseVehicle doesn't put them on the vehicle properly.
301  v_tag_pos = vh GetTagOrigin( self.rider_info.aligntag );
302  v_tag_ang = vh GetTagAngles( self.rider_info.aligntag );
303  if (isdefined(v_tag_pos))
304  self ForceTeleport( v_tag_pos, v_tag_ang );
305  }
306  else
307  {
308  /# ErrorMsg( "Missing rider_info" ); #/
309  }
310 
311  if ( IsActor( self ) )
312  {
313  // Disable pathing while inside a vehicle.
314  self PathMode( "dont move" );
315 
316  // Disable dropping ammo/weapon inside a vehicle.
317  self.disableAmmoDrop = true;
318  self.dontDropWeapon = true;
319  }
320 
321  // If there is an associated use index, call UseVehicle.
322  //
323  if ( isdefined( level.vehiclerider_use_index[ str_pos ] ) )
324  {
325  //double check that the seat is still available
326  if ( !isdefined( self.vehicle.ignore_seat_check ) || !self.vehicle.ignore_seat_check )
327  {
328  seat_index = level.vehiclerider_use_index[ str_pos ];
329  if( seat_index <= 4 ) // IsVehicleSeatOccupied only works on code seats and not passenger seats
330  {
331  if( self.vehicle IsVehicleSeatOccupied( seat_index ) )
332  {
333  ‪get_out();
334  return;
335  }
336  }
337  }
338 
339  self.vehicle UseVehicle( self, level.vehiclerider_use_index[ str_pos ] );
340  }
341 
342  self ‪flagsys::set( "in_vehicle" );
343 
344  self thread ‪handle_rider_death();
345 }
346 
348 {
349  self endon( "exiting_vehicle" );
350  self.vehicle endon( "death" );
351 
352  if ( IsDefined( self.rider_info.RideDeathAnim ) )
353  {
354  self ‪animation::set_death_anim( self.rider_info.RideDeathAnim );
355  }
356 
357  self waittill( "death" );
358 
359  if ( !IsDefined( self ) )
360  {
361  return;
362  }
363 
364  if ( IsDefined( self.vehicle ) && IsDefined( self.rider_info ) && IsDefined( self.rider_info.VehicleRiderDeathAnim ) )
365  {
366  self.vehicle ‪clientfield::increment( self.rider_info.position + "_death", 1 );
367  self.vehicle SetAnimKnobRestart( self.rider_info.VehicleRiderDeathAnim, 1, 0, 1 );
368  }
369 }
370 
371 function ‪delete_rider_asap( entity )
372 {
373  wait ‪SERVER_FRAME;
374 
375  if ( IsDefined( entity ) )
376  {
377  entity Delete();
378  }
379 }
380 
381 function ‪kill_rider( entity )
382 {
383  if( IsDefined( entity ) )
384  {
385  if( IsAlive( entity ) && !‪GibServerUtils::IsGibbed( entity, ‪GIB_ANNIHILATE_FLAG ) )
386  {
387  if ( entity IsPlayingAnimScripted() )
388  {
389  entity StopAnimScripted();
390  }
391 
392  if ( GetDvarInt( "tu1_vehicleRidersInvincibility", 1 ) )
393  {
394  // TU1 crash fix when killing a vehicle that had invincible riders.
396  }
397 
400  ‪GibServerUtils::GibLegs( entity );
402 
403  entity Unlink();
404  entity Kill();
405  }
406 
407  // Ragdoll typically goes insane, hide and delete the entity.
408  entity Ghost();
409  level thread ‪delete_rider_asap( entity );
410  }
411 }
412 
413 function ‪on_vehicle_killed( params )
414 {
415  // "self" is a removed entity in this case and IsDefined( self ) will always return false, even though
416  // script variables on that entity are still available.
417  if ( /* IsDefined( self ) && */ IsDefined( self.riders ) )
418  {
419  foreach ( rider in self.riders )
420  {
421  ‪kill_rider( rider );
422  }
423  }
424 }
425 
426 function ‪is_seat_available( vh, str_pos )
427 {
428  if ( vh ‪flagsys::get( str_pos + "occupied" ) )
429  {
430  return false;
431  }
432 
433  if ( AnglesToUp( vh.angles )[2] < 0.3 )
434  {
435  // Vehicle is flipped
436  return false;
437  }
438 
439  seat_index = ‪seat_position_to_index( str_pos );
440  if( seat_index <= 4 ) // IsVehicleSeatOccupied only works on code seats and not passenger seats
441  {
442  if( vh IsVehicleSeatOccupied( seat_index ) )
443  {
444  return false;
445  }
446  }
447  return true;
448 }
449 
450 function ‪can_get_in( vh, str_pos )
451 {
452  if ( !‪is_seat_available( vh, str_pos ) )
453  {
454  return false;
455  }
456 
457  rider_info = self ‪get_rider_info( vh, str_pos );
458 
459  v_tag_org = vh GetTagOrigin( rider_info.AlignTag );
460  v_tag_ang = vh GetTagAngles( rider_info.AlignTag );
461 
462  v_enter_pos = GetStartOrigin( v_tag_org, v_tag_ang, rider_info.EnterAnim );
463 
464  if ( !self FindPath( self.origin, v_enter_pos ) )
465  {
466  return false;
467  }
468 
469  return true;
470 }
471 
472 #define GROUND_HEIGHT 5
473 
481 function ‪get_out( str_mode )
482 {
483  ai = self;
484  self endon( "death" );
485 
486  self notify( "exiting_vehicle" );
487 
488  Assert( IsAlive( self ), "Dead or undefined vehicle rider." );
489  Assert( isdefined( self.vehicle ), "AI is not on vehicle." );
490 
491  if ( ‪IS_HELICOPTER( self.vehicle ) || ‪IS_PLANE( self.vehicle ) )
492  {
493  ‪DEFAULT( str_mode, "variable" );
494  }
495  else
496  {
497  ‪DEFAULT( str_mode, "ground" );
498  }
499 
500  bundle = self.vehicle ‪get_bundle_for_ai( ai );
501  n_hover_height = bundle.LowExitHeight;
502 
503  // Animate the door on the client.
504  if ( isdefined( self.rider_info.VehicleExitAnim ) )
505  {
506  self.vehicle ‪clientfield::increment( self.rider_info.position + "_exit", 1 );
507  self.vehicle SetAnim( self.rider_info.VehicleExitAnim, 1, 0, 1 );
508  }
509 
510  switch ( str_mode )
511  {
512  case "ground":
513 
514  ‪exit_ground();
515  break;
516 
517  case "low":
518 
519  ‪exit_low();
520  break;
521 
522  case "variable":
523 
525  break;
526 
527  default: AssertMsg( "Invalid mode for vehicle unload." );
528  }
529 
530  if ( IsActor( self ) )
531  {
532  // Re-enable pathing once an AI leaves a vehicle.
533  self PathMode( "move allowed" );
534 
535  // Allow dropping ammo/weapon after leaving the vehicle.
536  self.disableAmmoDrop = false;
537  self.dontDropWeapon = false;
538  }
539 
540  if( isdefined( self.vehicle ) )
541  {
542  ‪unclaim_position( self.vehicle, self.rider_info.position );
543 
544  // If there is an associated use index, call UseVehicle.
545  //
546  if ( isdefined( level.vehiclerider_use_index[ self.rider_info.position ] ) && (self ‪flagsys::get( "in_vehicle" )) )
547  {
548  self.vehicle UseVehicle( self, level.vehiclerider_use_index[ self.rider_info.position ] );
549  }
550  }
551 
552  self ‪flagsys::clear( "in_vehicle" );
553 
554  self.vehicle = undefined;
555  self.rider_info = undefined;
556  self ‪animation::set_death_anim( undefined );
557 
558  ‪set_goal();
559 
560  self notify( "exited_vehicle" );
561 }
562 
563 function ‪set_goal()
564 {
565  if ( ‪colors::is_color_ai() )
566  {
568  }
569  else if ( !isdefined( self.target ) )
570  {
571  self SetGoal( self.origin );
572  }
573 }
574 
584 function ‪unload( str_group = "all", str_mode, remove_rider_before_unloading, remove_riders_wait_time )
585 {
586  self notify( "unload", str_group );
587 
588  Assert( isdefined( level.vehiclerider_groups[ str_group ] ), str_group + " is not a valid unload group." );
589 
590  str_group = level.vehiclerider_groups[ str_group ]; // look up position subtring to use
591 
592  a_ai_unloaded = [];
593  foreach ( ai_rider in self.riders )
594  {
595  if ( ( str_group == "all" ) || IsSubStr( ai_rider.rider_info.position, str_group ) )
596  {
597  ai_rider thread ‪get_out( str_mode );
598  ‪ARRAY_ADD( a_ai_unloaded, ai_rider );
599  }
600  }
601 
602  if ( a_ai_unloaded.size > 0 )
603  {
604  if ( remove_rider_before_unloading === true )
605  {
606  ‪remove_riders_after_wait( remove_riders_wait_time, a_ai_unloaded );
607  }
608 
609  array::flagsys_wait_clear( a_ai_unloaded, "in_vehicle", ‪VAL( self.unloadTimeout, 4 ) );
610  self notify( "unload", a_ai_unloaded );
611  }
612 }
613 
614 function ‪remove_riders_after_wait( wait_time, a_riders_to_remove )
615 {
616  wait wait_time;
617 
618  if ( isdefined( a_riders_to_remove ) )
619  {
620  foreach( ai in a_riders_to_remove )
621  {
622  ArrayRemoveValue( self.riders, ai );
623  }
624  }
625 }
626 
628 {
629  self endon( "exited_vehicle" );
630 
631  self waittill( "death" );
632 
633  if ( IsActor( self ) && !self IsRagdoll() )
634  {
635  self Unlink();
636  self StartRagdoll();
637  }
638 }
639 
640 function ‪exit_ground()
641 {
642  self ‪animation::set_death_anim( self.rider_info.ExitGroundDeathAnim );
643 
644  if ( !IsDefined( self.rider_info.ExitGroundDeathAnim ) )
645  {
646  self thread ‪ragdoll_dead_exit_rider();
647  }
648 
649  Assert( IsString( self.rider_info.ExitGroundAnim ), "No exit animation for '" + self.rider_info.position + "'. Can't unload specified group." );
650 
651  if ( IsString( self.rider_info.ExitGroundAnim ) )
652  {
653  ‪animation::play( self.rider_info.ExitGroundAnim, self.vehicle, self.rider_info.AlignTag );
654  }
655 }
656 
657 function ‪exit_low()
658 {
659  self ‪animation::set_death_anim( self.rider_info.ExitLowDeathAnim );
660  Assert( isdefined( self.rider_info.ExitLowAnim ), "No exit animation for '" + self.rider_info.position + "'. Can't unload specified group." );
661  ‪animation::play( self.rider_info.ExitLowAnim, self.vehicle, self.rider_info.AlignTag );
662 }
663 
664 function private ‪handle_falling_death()
665 {
666  self endon( "landed" );
667 
668  self waittill( "death" );
669 
670  if ( IsActor( self ) )
671  {
672  self Unlink();
673  self StartRagdoll();
674  }
675 }
676 
677 function private ‪forward_euler_integration( e_move, v_target_landing, n_initial_speed )
678 {
679  // Sympletic euler integration.
680  landed = false;
681  integrationStep = 0.1; // Seconds
682  position = self.origin;
683  velocity = (0, 0, -n_initial_speed);
684  gravity = (0, 0, -385.8); // Gravity in inches/second^2 moving downward
685 
686  while ( !landed )
687  {
688  previousPosition = position;
689 
690  // Update the velocity and position based on the integration step.
691  velocity = velocity + gravity * integrationStep;
692  // Calculating velocity before position ensure sympletic integration.
693  position = position + velocity * integrationStep;
694 
695  // If the next integration step will take us past our landing, just move to that position instead.
696  if ( ( position[2] + velocity[2] * integrationStep ) <= v_target_landing[2] )
697  {
698  landed = true;
699 
700  position = v_target_landing;
701  }
702 
703 
705  e_move MoveTo( position, integrationStep );
706 
707  if ( !landed )
708  {
709  wait integrationStep;
710  }
711  }
712 }
713 
715 {
716  ai = self;
717  self endon( "death" );
718 
719  self notify( "exiting_vehicle" );
720 
721  self thread ‪handle_falling_death();
722 
723  self ‪animation::set_death_anim( self.rider_info.ExitHighDeathAnim );
724  Assert( isdefined( self.rider_info.ExitHighAnim ), "No exit animation for '" + self.rider_info.position + "'. Can't unload specified group." );
725  ‪animation::play( self.rider_info.ExitHighAnim, self.vehicle, self.rider_info.AlignTag, 1, 0, 0 );
726 
727  self ‪animation::set_death_anim( self.rider_info.ExitHighLoopDeathAnim );
728 
729  n_cur_height = ‪get_height( self.vehicle );
730 
731  bundle = self.vehicle ‪get_bundle_for_ai( ai );
732  n_target_height = bundle.HighExitLandHeight;
733 
734  if( ‪IS_TRUE( self.rider_info.DropUnderVehicleOrigin ) || ‪IS_TRUE( self.DropUnderVehicleOriginOverride ) )
735  v_target_landing = ( self.vehicle.origin[0], self.vehicle.origin[1], self.origin[2] - n_cur_height + n_target_height );
736  else
737  v_target_landing = ( self.origin[0], self.origin[1], self.origin[2] - n_cur_height + n_target_height );
738 
739  if( isdefined( self.overrideDropPosition ) )
740  v_target_landing = ( self.overrideDropPosition[0], self.overrideDropPosition[1], v_target_landing[2] );
741 
742  if( isdefined( self.targetAngles ) )
743  angles = self.targetAngles;
744  else
745  angles = self.angles;
746 
747  // Create the tag origin
748  e_move = ‪util::spawn_model( "tag_origin", self.origin, angles );
749 
750  self thread ‪exit_high_loop_anim( e_move );
751 
752  // Move the tag origin downward.
753  distance = n_target_height - n_cur_height;
754  initialSpeed = bundle.DropSpeed;
755  acceleration = 385.8; // Gravity in inches/second^2
756 
757  // Kinematic Equation to compute distance given, time, velocity, and acceleration.
758  // distance = velocity(init) * time + (1/2) * acceleration * time^2;
759 
760  // Use the quadratic equation to solve for time.
761  n_fall_time = ( -initialSpeed + Sqrt( Pow( initialSpeed, 2 ) - 2 * acceleration * distance ) ) / acceleration;
762 
763  self notify( "falling", n_fall_time );
764 
765  ‪forward_euler_integration( e_move, v_target_landing, bundle.DropSpeed );
766 
767  e_move waittill( "movedone" );
768 
769  self notify( "landing" );
770 
771  self ‪animation::set_death_anim( self.rider_info.ExitHighLandDeathAnim );
772  ‪animation::play( self.rider_info.ExitHighLandAnim, e_move, "tag_origin" );
773 
774  self notify( "landed" );
775 
776  self Unlink();
777 
779 
780  // Detach from tag origin and delete.
781  e_move Delete();
782 }
783 
784 function ‪exit_high_loop_anim( e_parent )
785 {
786  self endon( "death" );
787  self endon( "landing" );
788 
789  while ( true )
790  {
791  ‪animation::play( self.rider_info.ExitHighLoopAnim, e_parent, "tag_origin" );
792  }
793 }
794 
795 function ‪get_height( e_ignore )
796 {
797  ‪DEFAULT( e_ignore, self );
798 
799  const height_diff = 10;
800  ‪trace = GroundTrace( self.origin + (0,0,height_diff), self.origin + ( 0, 0, -10000 ), false, e_ignore, false );
801 
802  return Distance( self.origin, ‪trace[ "position" ] );
803 }
804 
805 function ‪get_bundle()
806 {
807  Assert( isdefined( self.vehicleridersbundle ), "No vehicleriders bundle specified for this vehicle (in the vehiclesettings gdt)." );
808  return ‪struct::get_script_bundle( "vehicleriders", self.vehicleridersbundle );
809 }
810 
812 {
813  Assert( isdefined( self.vehicleridersrobotbundle ), "No vehicleriders robot bundle specified for this vehicle (in the vehiclesettings gdt)." );
814  return ‪struct::get_script_bundle( "vehicleriders", self.vehicleridersrobotbundle );
815 }
816 
825 function ‪get_rider( str_pos ) // self = vehicle
826 {
827  if ( isdefined( self.riders ) )
828  {
829  foreach ( ai in self.riders )
830  {
831  if ( IsDefined( ai ) && ( ai.rider_info.position == str_pos ) )
832  {
833  return ai;
834  }
835  }
836  }
837 }
838 
840 // Private
842 function private ‪_init_rider( vh, str_pos )
843 {
844  Assert( isdefined( self.vehicle ) || isdefined( vh ), "No vehicle specified for rider." );
845  Assert( isdefined( self.rider_info ) || isdefined( str_pos ), "No position specified for rider." );
846 
847  if ( isdefined( vh ) )
848  {
849  self.vehicle = vh;
850  }
851 
852  ‪DEFAULT( str_pos, self.rider_info.position );
853 
854  self.rider_info = self ‪get_rider_info( self.vehicle, str_pos );
855 }
‪waitTillHostMigrationDone
‪function waitTillHostMigrationDone()
Definition: hostmigration_shared.gsc:193
‪is_seat_available
‪function is_seat_available(vh, str_pos)
Definition: vehicleriders_shared.gsc:426
‪get_script_bundles
‪function get_script_bundles(str_type)
Definition: struct.csc:77
‪exit_variable
‪function exit_variable()
Definition: vehicleriders_shared.gsc:714
‪enable
‪function enable(handler)
Definition: _perplayer.gsc:54
‪_init_rider
‪function private _init_rider(vh, str_pos)
Definition: vehicleriders_shared.gsc:842
‪is_color_ai
‪function is_color_ai()
Definition: colors_shared.gsc:2062
‪GibLeftArm
‪function GibLeftArm(entity)
Definition: gib.gsc:450
‪on_vehicle_killed
‪function on_vehicle_killed(params)
Definition: vehicleriders_shared.gsc:413
‪remove_riders_after_wait
‪function remove_riders_after_wait(wait_time, a_riders_to_remove)
Definition: vehicleriders_shared.gsc:614
‪get_out
‪function get_out(str_mode)
Definition: vehicleriders_shared.gsc:481
‪_unclaim_position_on_death
‪function private _unclaim_position_on_death(vh, str_pos)
Definition: vehicleriders_shared.gsc:137
‪IS_HELICOPTER
‪#define IS_HELICOPTER(__e)
Definition: shared.gsh:351
‪clear
‪function clear(str_flag)
Definition: flag_shared.csc:130
‪GIB_ANNIHILATE_FLAG
‪#define GIB_ANNIHILATE_FLAG
Definition: gib.gsh:22
‪get_rider_info
‪function get_rider_info(vh, str_pos="driver")
Definition: vehicleriders_shared.gsc:201
‪delete_rider_asap
‪function delete_rider_asap(entity)
Definition: vehicleriders_shared.gsc:371
‪stop_magic_bullet_shield
‪function stop_magic_bullet_shield(ent)
Definition: util_shared.gsc:2100
‪get_in
‪function get_in(vh, str_pos, b_teleport=false)
Definition: vehicleriders_shared.gsc:226
‪on_vehicle_spawned
‪function on_vehicle_spawned()
Definition: vehicleriders_shared.gsc:108
‪play
‪function play(animation, v_origin_or_ent, v_angles_or_tag, n_rate=1, n_blend_in=.2, n_blend_out=.2, n_lerp, b_link=false)
Definition: animation_shared.csc:44
‪VERSION_SHIP
‪#define VERSION_SHIP
Definition: version.gsh:36
‪seat_position_to_index
‪function seat_position_to_index(str_position)
Definition: vehicleriders_shared.gsc:103
‪spawn_riders
‪function spawn_riders()
Definition: vehicleriders_shared.gsc:165
‪handle_rider_death
‪function handle_rider_death()
Definition: vehicleriders_shared.gsc:347
‪VAL
‪#define VAL(__var, __default)
Definition: shared.gsh:272
‪trace
‪function trace(from, to, target)
Definition: grapple.gsc:369
‪unload
‪function unload(str_group="all", str_mode, remove_rider_before_unloading, remove_riders_wait_time)
Definition: vehicleriders_shared.gsc:584
‪find_next_open_position
‪function find_next_open_position(ai)
Definition: vehicleriders_shared.gsc:147
‪spawn
‪function spawn(v_origin=(0, 0, 0), v_angles=(0, 0, 0))
Definition: struct.csc:23
‪IS_TRUE
‪#define IS_TRUE(__a)
Definition: shared.gsh:251
‪get
‪function get(kvp_value, kvp_key="targetname")
Definition: struct.csc:13
‪Annihilate
‪function Annihilate(entity)
Definition: gib.gsc:393
‪disable
‪function disable(handler)
Definition: _perplayer.gsc:79
‪add
‪function add(entity, dyingplayer, team, timeout)
Definition: _deathicons.gsc:43
‪spawn_model
‪function spawn_model(n_client, str_model, origin=(0, 0, 0), angles=(0, 0, 0))
Definition: util_shared.csc:92
‪forward_euler_integration
‪function private forward_euler_integration(e_move, v_target_landing, n_initial_speed)
Definition: vehicleriders_shared.gsc:677
‪get_rider
‪function get_rider(str_pos)
Definition: vehicleriders_shared.gsc:825
‪set_death_anim
‪function set_death_anim(animation, v_origin_or_ent, v_angles_or_tag, n_rate, n_blend_in, n_blend_out, n_lerp)
Definition: animation_shared.gsc:423
‪exit_low
‪function exit_low()
Definition: vehicleriders_shared.gsc:657
‪DEFAULT
‪#define DEFAULT(__var, __default)
Definition: shared.gsh:270
‪get_robot_bundle
‪function get_robot_bundle()
Definition: vehicleriders_shared.gsc:811
‪ragdoll_dead_exit_rider
‪function ragdoll_dead_exit_rider()
Definition: vehicleriders_shared.gsc:627
‪get_bundle_for_ai
‪function get_bundle_for_ai(ai)
Definition: vehicleriders_shared.gsc:187
‪__init__
‪function __init__()
Definition: vehicleriders_shared.gsc:35
‪claim_position
‪function claim_position(vh, str_pos)
Definition: vehicleriders_shared.gsc:121
‪ARRAY_ADD
‪#define ARRAY_ADD(__array, __item)
Definition: shared.gsh:304
‪SERVER_FRAME
‪#define SERVER_FRAME
Definition: shared.gsh:264
‪IsGibbed
‪function IsGibbed(localClientNum, entity, gibFlag)
Definition: gib.csc:734
‪increment
‪function increment(str_field_name, n_increment_count=1)
Definition: clientfield_shared.gsc:110
‪REGISTER_SYSTEM
‪#define REGISTER_SYSTEM(__sys, __func_init_preload, __reqs)
Definition: shared.gsh:204
‪set_goal
‪function set_goal()
Definition: vehicleriders_shared.gsc:563
‪reach
‪function reach(animation, v_origin_or_ent, v_angles_or_tag, b_disable_arrivals=false)
Definition: animation_shared.gsc:335
‪kill_rider
‪function kill_rider(entity)
Definition: vehicleriders_shared.gsc:381
‪exit_high_loop_anim
‪function exit_high_loop_anim(e_parent)
Definition: vehicleriders_shared.gsc:784
‪set
‪function set(str_field_name, n_value)
Definition: clientfield_shared.gsc:34
‪can_get_in
‪function can_get_in(vh, str_pos)
Definition: vehicleriders_shared.gsc:450
‪get_bundle
‪function get_bundle()
Definition: vehicleriders_shared.gsc:805
‪register
‪function register()
Definition: _ai_tank.gsc:126
‪get_script_bundle
‪function get_script_bundle(str_type, str_name)
Definition: struct.csc:45
‪GibLegs
‪function GibLegs(entity)
Definition: gib.gsc:507
‪IS_PLANE
‪#define IS_PLANE(__e)
Definition: shared.gsh:350
‪unclaim_position
‪function unclaim_position(vh, str_pos)
Definition: vehicleriders_shared.gsc:130
‪GibRightArm
‪function GibRightArm(entity)
Definition: gib.gsc:467
‪on_ai_spawned
‪function on_ai_spawned()
Definition: vehicleriders_shared.gsc:113
‪handle_falling_death
‪function private handle_falling_death()
Definition: vehicleriders_shared.gsc:664
‪get_height
‪function get_height(e_ignore)
Definition: vehicleriders_shared.gsc:795
‪IS_ROBOT
‪#define IS_ROBOT(__e)
Definition: archetype_shared.gsh:43
‪exit_ground
‪function exit_ground()
Definition: vehicleriders_shared.gsc:640
‪WAIT_SERVER_FRAME
‪#define WAIT_SERVER_FRAME
Definition: shared.gsh:265