1 #using scripts\codescripts\struct;
3 #using scripts\shared\flag_shared;
4 #using scripts\shared\math_shared;
5 #using scripts\shared\sound_shared;
6 #using scripts\shared\system_shared;
7 #using scripts\shared\util_shared;
8 #using scripts\shared\vehicle_shared;
9 #using scripts\shared\vehicle_ai_shared;
11 #insert scripts\shared\shared.gsh;
13 #define ANIMTREE "generic"
15 #namespace vehicle_death;
24 #using_animtree( ANIMTREE );
32 self endon(
"nodeath_thread" );
34 while ( isdefined(
self ) )
37 self waittill(
"death", attacker, damageFromUnderneath, weapon, point, dir );
39 if( isdefined(
self.death_enter_cb ) )
40 [[
self.death_enter_cb]]();
42 if ( isdefined(
self.script_deathflag ) )
52 if ( !isdefined(
self ) )
65 if ( !
IS_TRUE(
self.dont_kill_riders ) )
71 self notify(
"delete_destructible" );
83 if ( isdefined( level.vehicle_death_thread[
self.vehicletype ] ) )
85 thread [[ level.vehicle_death_thread[
self.vehicletype ] ]]();
96 if ( !isdefined(
self.destructibledef ) )
98 if ( !is_aircraft && !(
self.vehicleType ==
"horse" ||
self.vehicleType ==
"horse_player" ||
self.vehicleType ==
"horse_player_low" ||
self.vehicleType ==
"horse_low" ||
self.vehicleType ==
"horse_axis" ) && isdefined(
self.deathmodel ) &&
self.deathmodel !=
"" )
104 if ( !isdefined(
self.
delete_on_death ) && ( !isdefined(
self.mantled ) || !
self.mantled ) && !isdefined(
self.nodeathfx ) )
113 if (
self.disconnectPathOnStop ===
true )
118 if ( !
IS_TRUE(
self.no_free_on_death ) )
121 self.isacorpse =
true;
125 if ( isdefined(
self ) )
127 self notify(
"death_finished" );
146 if ( isdefined( level.vehicle_deathnotify ) && isdefined( level.vehicle_deathnotify[
self.vehicletype ] ) )
148 level notify( level.vehicle_deathnotify[
self.vehicletype ], attacker );
151 if ( Target_IsTarget(
self ) )
153 Target_Remove(
self );
157 if (
self.classname ==
"script_vehicle" )
169 if ( isdefined(
self.turretweapon ) &&
self.turretweapon != level.weaponNone)
171 self clearTurretTarget();
180 if ( isdefined(
self ) )
182 while ( isdefined(
self ) && isdefined(
self.dontfreeme ) )
188 self notify(
"stop_looping_death_fx" );
189 self notify(
"death_finished" );
193 if ( isdefined(
self ) )
200 if ( !isdefined(
self ) )
206 occupants =
self GetVehOccupants();
207 if ( isdefined( occupants ) && occupants.size )
209 for ( i = 0; i < occupants.size; i++ )
211 self usevehicle( occupants[i], 0 );
215 if ( !
IS_TRUE(
self.no_free_on_death ) )
218 self.isacorpse =
true;
221 if (
self.modeldummyon )
239 if ( !isdefined (
self.death_counter ) )
241 self.death_counter = 0;
243 if (
self.death_counter == 0 )
245 self.death_counter++;
246 self playsound (
"exp_veh_helicopter_hit" );
253 self playloopsound(
"veh_drone_spin", .05 );
255 self stoploopsound( .02 );
260 if( !isdefined( sModel ) )
264 if ( isdefined( fDelay ) && ( fDelay > 0 ) )
269 if ( !isdefined(
self ) )
274 if ( isdefined(
self.deathmodel_attached ) )
279 eModel = vehicle::get_dummy();
280 if ( !isdefined( eModel ) )
285 if ( !isdefined( eModel.death_anim ) && ( isdefined( eModel.animtree ) ) )
287 eModel ClearAnim( %root, 0 );
291 if( sModel !=
self.vehmodel )
293 eModel SetModel( sModel );
294 eModel SetEnemyModel( sModel );
301 self.crashing =
true;
303 if ( isdefined(
self.unloading ) )
305 while ( isdefined(
self.unloading ) )
311 if ( !isdefined(
self ) )
322 self.crashing =
true;
325 if ( isdefined(
self.unloading ) )
327 while ( isdefined(
self.unloading ) )
333 if ( !isdefined(
self ) )
345 self endon(
"crash_done" );
348 self ClearVehGoalPos();
350 if ( isdefined( level.heli_crash_smoke_trail_fx ) )
352 if ( IsSubStr(
self.vehicletype,
"v78" ) )
354 playfxontag( level.heli_crash_smoke_trail_fx,
self,
"tag_origin" );
356 else if (
self.vehicletype ==
"drone_firescout_axis" ||
self.vehicletype ==
"drone_firescout_isi" )
358 playfxontag( level.heli_crash_smoke_trail_fx,
self,
"tag_main_rotor" );
362 playfxontag( level.heli_crash_smoke_trail_fx,
self,
"tag_engine_left" );
367 if ( crash_zones.size > 0 )
372 if ( isdefined(
self.a_crash_zones ) )
374 crash_zones =
self.a_crash_zones;
377 for ( i = 0; i < crash_zones.size; i++ )
379 vec_to_crash_zone = crash_zones[i].origin -
self.origin;
380 vec_to_crash_zone = ( vec_to_crash_zone[0], vec_to_crash_zone[1], 0 );
381 dist = Length( vec_to_crash_zone );
382 vec_to_crash_zone /= dist;
384 veloctiy_scale = -VectorDot(
self.velocity, vec_to_crash_zone );
385 dist += 500 * veloctiy_scale;
387 if ( dist < best_dist )
394 if ( best_idx != -1 )
396 self.crash_zone = crash_zones[best_idx];
402 if( isdefined( dir ) )
403 dir = VectorNormalize( dir );
406 side_dir = VectorCross( dir, ( 0,0,1 ) );
407 side_dir_mag = RandomFloatRange( -500, 500 );
409 side_dir *= side_dir_mag;
410 side_dir += ( 0,0,150 );
412 self SetPhysAcceleration( ( RandomIntRange( -500, 500 ), RandomIntRange( -500, 500 ), -1000 ) );
413 self SetVehVelocity(
self.velocity + side_dir );
415 if( isdefined( point ) )
427 if ( IsDefined(
self ) )
429 self notify(
"crash_done" );
435 self endon(
"crash_done" );
436 self endon(
"crash_move_done" );
437 self endon(
"death" );
439 if ( !isdefined(
self.crash_accel ) )
441 self.crash_accel = RandomFloatRange( 50, 80 );
444 while ( isdefined(
self ) )
446 self SetVehVelocity(
self.velocity + AnglesToUp(
self.angles ) *
self.crash_accel );
453 self endon(
"crash_done" );
454 self endon(
"crash_move_done" );
455 self endon(
"death" );
457 start_angles =
self.angles;
458 VEC_SET_X( start_angles, start_angles[0] + 10 );
459 VEC_SET_Z( start_angles, start_angles[2] + 10 );
461 ang_vel =
self GetAngularVelocity();
462 ang_vel = ( 0, ang_vel[1] * RandomFloatRange( 2, 3 ), 0 );
463 self SetAngularVelocity( ang_vel );
465 point_2d = ( point[0], point[1],
self.origin[2] );
467 torque = ( 0, RandomIntRange( 90, 180 ), 0 );
468 if (
self GetAngularVelocity()[1] < 0 )
473 if ( Distance(
self.origin, point_2d ) > 5 )
475 local_hit_point = point_2d -
self.origin;
477 dir_2d = ( dir[0], dir[1], 0 );
478 if ( Length( dir_2d ) > 0.01 )
480 dir_2d = VectorNormalize( dir_2D );
481 torque = VectorCross( VectorNormalize( local_hit_point ), dir );
482 torque = ( 0, 0, torque[2] );
483 torque = VectorNormalize( torque );
484 torque = ( 0, torque[2] * 180, 0 );
490 ang_vel =
self GetAngularVelocity();
491 ang_vel += torque * 0.05;
493 const max_angluar_vel = 360;
494 if ( ang_vel[1] < max_angluar_vel * -1 )
496 ang_vel = ( ang_vel[0], max_angluar_vel * -1, ang_vel[2] );
498 else if ( ang_vel[1] > max_angluar_vel )
500 ang_vel = ( ang_vel[0], max_angluar_vel, ang_vel[2] );
503 self SetAngularVelocity( ang_vel );
511 self endon(
"crash_done" );
512 self endon(
"crash_move_done" );
514 torque = ( 0, RandomIntRange( 90, 150 ), 0 );
515 ang_vel =
self GetAngularVelocity();
519 if ( Abs(
self.angles[2] ) < 3.0 )
521 self.angles = (
self.angles[0],
self.angles[1], RandomIntRange( 3, 6 ) *
math::sign(
self.angles[2] ) );
524 is_vtol = IsSubStr(
self.vehicletype,
"v78" );
531 while ( isdefined(
self ) )
533 assert( isdefined(
self.crash_zone ) );
535 dist = Distance2D(
self.origin,
self.crash_zone.origin );
536 if ( dist <
self.crash_zone.radius )
541 self SetPhysAcceleration( ( 0, 0, -400 ) );
542 self.crash_accel = 0;
546 self SetPhysAcceleration( ( 0, 0, -50 ) );
549 self.crash_vel =
self.crash_zone.origin -
self.origin;
550 self.crash_vel = (
self.crash_vel[0],
self.crash_vel[1], 0 );
551 self.crash_vel = VectorNormalize(
self.crash_vel );
552 self.crash_vel *=
self GetMaxSpeed() * 0.5;
556 self.crash_vel *= 0.5;
559 crash_vel_forward = AnglesToUp(
self.angles ) *
self GetMaxSpeed() * 2;
560 crash_vel_forward = ( crash_vel_forward[0], crash_vel_forward[1], 0 );
561 self.crash_vel += crash_vel_forward;
563 vel_x = DiffTrack(
self.crash_vel[0],
self.velocity[0], 1, 0.1 );
564 vel_y = DiffTrack(
self.crash_vel[1],
self.velocity[1], 1, 0.1 );
565 vel_z = DiffTrack(
self.crash_vel[2],
self.velocity[2], 1, 0.1 );
567 self SetVehVelocity( ( vel_x, vel_y, vel_z ) );
569 ang_vel =
self GetAngularVelocity();
570 ang_vel = ( 0, ang_vel[1], 0 );
571 ang_vel += torque * 0.1;
573 max_angluar_vel = 200;
576 max_angluar_vel = 100;
579 if ( ang_vel[1] < max_angluar_vel * -1 )
581 ang_vel = ( ang_vel[0], max_angluar_vel * -1, ang_vel[2] );
583 else if ( ang_vel[1] > max_angluar_vel )
585 ang_vel = ( ang_vel[0], max_angluar_vel, ang_vel[2] );
588 self SetAngularVelocity( ang_vel );
596 self endon(
"crash_done" );
600 self waittill(
"veh_collision", velocity, normal );
602 ang_vel =
self GetAngularVelocity() * 0.5;
603 self SetAngularVelocity( ang_vel );
606 if ( normal[2] < 0.7 )
608 self SetVehVelocity(
self.velocity + normal * 70 );
617 self notify(
"crash_done" );
624 ent =
Spawn (
"script_origin",
self.origin );
626 ent playloopsound (
"exp_heli_crash_loop" );
633 self endon(
"death" );
637 if ( isdefined( delete_me ) && delete_me ==
true )
647 self endon(
"crash_move_done" );
648 self endon(
"death" );
651 self ClearVehGoalPos();
653 self SetRotorSpeed( 0.2 );
656 if ( isdefined(
self ) && isdefined(
self.vehicletype ) )
658 b_custom_deathmodel_setup =
true;
659 switch (
self.vehicletype )
663 b_custom_deathmodel_setup =
false;
667 if ( b_custom_deathmodel_setup )
669 self.deathmodel_attached =
true;
673 ang_vel =
self GetAngularVelocity();
674 ang_vel = ( 0, 0, 0 );
676 self SetAngularVelocity( ang_vel );
678 nodes =
self GetVehicleAvoidanceNodes( 10000 );
681 if ( nodes.size > 0 )
683 for ( i = 0; i < nodes.size; i++ )
685 dir = VectorNormalize( nodes[i] -
self.origin );
686 forward = AnglesToForward(
self.angles );
687 dot = VectorDot( dir, forward );
693 dist = Distance2D(
self.origin, nodes[i] );
694 if ( dist < best_dist )
701 if ( closest_index >= 0 )
703 o = nodes[closest_index];
704 o = ( o[0], o[1],
self.origin[2] );
709 dir = VectorNormalize( o -
self.origin );
711 self SetVehVelocity(
self.velocity + dir * 2000 );
715 self SetVehVelocity(
self.velocity + AnglesToRight(
self.angles ) * RandomIntRange( -1000, 1000 ) + ( 0, 0, RandomIntRange( 0, 1500 ) ) );
720 self SetVehVelocity(
self.velocity + AnglesToRight(
self.angles ) * RandomIntRange( -1000, 1000 ) + ( 0, 0, RandomIntRange( 0, 1500 ) ) );
726 torque = ( 0, RandomIntRange( -90, 90 ), RandomIntRange( 90, 720 ) );
727 if ( RandomInt( 100 ) < 50 )
729 torque = ( torque[0], torque[1], -torque[2] );
732 while ( isdefined(
self ) )
734 ang_vel =
self GetAngularVelocity();
735 ang_vel += torque * 0.05;
737 const max_angluar_vel = 500;
738 if ( ang_vel[2] < max_angluar_vel * -1 )
740 ang_vel = ( ang_vel[0], ang_vel[1], max_angluar_vel * -1 );
742 else if ( ang_vel[2] > max_angluar_vel )
744 ang_vel = ( ang_vel[0], ang_vel[1], max_angluar_vel );
747 self SetAngularVelocity( ang_vel );
755 self endon(
"crash_move_done" );
756 self endon(
"death" );
760 self SetPhysAcceleration( ( RandomIntRange( -1600, 1600 ), RandomIntRange( -1600, 1600 ), -1600 ) );
765 self endon(
"crash_move_done" );
766 self endon(
"death" );
770 self ClearVehGoalPos();
771 self SetTurningAbility( 0 );
774 self SetPhysAcceleration( ( 0, 0, -800 ) );
777 dir = VectorNormalize( dir );
779 ang_vel =
self GetAngularVelocity();
780 ang_vel = ( 0, ang_vel[1] * RandomFloatRange( 1, 3 ), 0 );
781 self SetAngularVelocity( ang_vel );
783 point_2d = ( point[0], point[1],
self.origin[2] );
785 torque = ( 0, 720, 0 );
786 if ( Distance(
self.origin, point_2d ) > 5 )
788 local_hit_point = point_2d -
self.origin;
790 dir_2d = ( dir[0], dir[1], 0 );
791 if ( Length( dir_2d ) > 0.01 )
793 dir_2d = VectorNormalize( dir_2D );
794 torque = VectorCross( VectorNormalize( local_hit_point ), dir );
795 torque = ( 0, 0, torque[2] );
796 torque = VectorNormalize( torque );
797 torque = ( 0, torque[2] * 180, 0 );
803 ang_vel =
self GetAngularVelocity();
804 ang_vel += torque * 0.05;
806 const max_angluar_vel = 360;
807 if ( ang_vel[1] < max_angluar_vel * -1 )
809 ang_vel = ( ang_vel[0], max_angluar_vel * -1, ang_vel[2] );
811 else if ( ang_vel[1] > max_angluar_vel )
813 ang_vel = ( ang_vel[0], max_angluar_vel, ang_vel[2] );
816 self SetAngularVelocity( ang_vel );
825 self.crashing =
true;
828 if ( isdefined(
self.unloading ) )
830 while ( isdefined(
self.unloading ) )
836 if ( !isdefined(
self ) )
846 self endon(
"crash_move_done" );
847 self endon(
"death" );
851 self ClearVehGoalPos();
853 self SetPhysAcceleration( ( 0, 0, -50 ) );
856 dir = VectorNormalize( dir );
859 ang_vel =
self GetAngularVelocity();
860 ang_vel = ( 0, 0, 0 );
861 self SetAngularVelocity( ang_vel );
863 torque = ( RandomIntRange( -5, -3 ), 0, ( RandomIntRange( 0, 100 ) < 50 ? -5 : 5 ) );
869 ang_vel =
self GetAngularVelocity();
870 ang_vel += torque * 0.05;
872 const max_angluar_vel = 360;
873 if ( ang_vel[1] < max_angluar_vel * -1 )
875 ang_vel = ( ang_vel[0], max_angluar_vel * -1, ang_vel[2] );
877 else if ( ang_vel[1] > max_angluar_vel )
879 ang_vel = ( ang_vel[0], max_angluar_vel, ang_vel[2] );
882 self SetAngularVelocity( ang_vel );
884 velocity =
self.velocity;
887 self SetVehVelocity( velocity );
895 self endon(
"death" );
899 self notify(
"crash_move_done" );
901 self notify(
"crash_done" );
906 self endon(
"death" );
908 self SetPhysAcceleration( ( 0, 0, 0 ) );
909 self SetRotorSpeed( 0 );
911 speed =
self GetSpeedMPH();
914 velocity =
self.velocity;
916 self SetVehVelocity( velocity );
918 angular_velocity =
self GetAngularVelocity();
919 angular_velocity *= 0.9;
920 self SetAngularVelocity( angular_velocity );
922 speed =
self GetSpeedMPH();
927 self SetVehVelocity( ( 0, 0, 0 ) );
928 self SetAngularVelocity( ( 0, 0, 0 ) );
937 self endon(
"death" );
939 self waittill(
"veh_collision", velocity, normal );
942 self notify(
"crash_move_done" );
944 if ( normal[2] > 0.7 )
946 forward = AnglesToForward(
self.angles );
947 right = VectorCross( normal, forward );
948 desired_forward = VectorCross( right, normal );
949 self SetPhysAngles( VectorToAngles( desired_forward ) );
952 self notify(
"crash_done" );
968 while ( isdefined( targ ) && search_depth >= 0 )
970 if ( ( isdefined( targ.detoured ) ) && ( targ.detoured == 0 ) )
973 if ( isdefined( detourpath ) && isdefined( detourpath.script_crashtype ) )
978 if ( isdefined( targ.target ) )
981 targ1 = getvehiclenode( targ.target,
"targetname" );
982 if ( isdefined( targ1 ) && isdefined( targ1.target ) && isdefined( targ.targetname ) && targ1.target == targ.targetname )
986 else if ( isdefined( targ1 ) && targ1 == node )
1011 if ( !isdefined(
self ) )
1015 self notify(
"stop sound" + sound );
1023 if (
self vehicle::is_destructible() )
1032 self [[
self.do_death_fx]]();
1043 if ( !isdefined( level.vehicle_death_badplace[ type ] ) )
1048 struct = level.vehicle_death_badplace[ type ];
1049 if ( isdefined(
struct.
delay ) )
1054 if ( !isdefined(
self ) )
1059 badplace_box(
"vehicle_kill_badplace",
struct.duration,
self.origin,
struct.radius,
"all" );
1064 self endon(
"death" );
1066 if (
IS_TRUE(
self.ignore_death_jolt ) )
1071 self JoltBody( (
self.origin + ( 23, 33, 64 ) ), 3 );
1073 if ( isdefined(
self.death_anim ) )
1075 self AnimScripted(
"death_anim",
self.origin,
self.angles,
self.death_anim,
"normal", %root, 1, 0 );
1076 self waittillmatch(
"death_anim",
"end" );
1080 if (
self.isphysicsvehicle )
1082 num_launch_multiplier = 1;
1084 if ( isdefined(
self.physicslaunchdeathscale ) )
1086 num_launch_multiplier =
self.physicslaunchdeathscale;
1089 self LaunchVehicle( (0, 0, 180) * num_launch_multiplier, (RandomFloatRange(5, 10), RandomFloatRange(-5, 5), 0),
true,
false,
true );
1096 if (
self.health > 0 )
1098 self.rollingdeath = 1;
1104 self.rollingdeath = undefined;
1105 self notify(
"deathrolloff" );
1110 assert( isdefined( effect ) );
1111 assert( isdefined( tag ) );
1112 assert( isdefined( loopTime ) );
1114 self endon(
"stop_looping_death_fx" );
1116 while ( isdefined(
self ) )
1127 ent =
Spawn(
"script_model", ( 0, 0, 0 ) );
1128 emodel = vehicle::get_dummy();
1129 ent setmodel(
self.model );
1130 ent.origin = emodel.origin;
1131 ent.angles = emodel.angles;
1134 ent linkto( emodel );
1135 self.deathfx_ent = ent;
1139 self.deathfx_ent setmodel(
self.model );
1141 return self.deathfx_ent;
1146 script_linkname =
self.script_linkname;
1147 targetname =
self.targetname;
1151 if ( isdefined( script_linkname ) )
1153 ArrayRemoveValue( level.vehicle_link[ script_linkname ],
self );
1156 if ( isdefined(
self.script_VehicleSpawngroup ) )
1158 if ( isdefined( level.vehicle_SpawnGroup[
self.script_VehicleSpawngroup ] ) )
1160 ArrayRemoveValue( level.vehicle_SpawnGroup[
self.script_VehicleSpawngroup ],
self );
1161 ArrayRemoveValue( level.vehicle_SpawnGroup[
self.script_VehicleSpawngroup ], undefined );
1165 if ( isdefined(
self.script_VehicleStartMove ) )
1167 ArrayRemoveValue( level.vehicle_StartMoveGroup[
self.script_VehicleStartMove ],
self );
1170 if ( isdefined(
self.script_vehicleGroupDelete ) )
1172 ArrayRemoveValue( level.vehicle_DeleteGroup[
self.script_vehicleGroupDelete ],
self );
1179 if ( isdefined(
self.riders ) )
1181 for ( j = 0; j <
self.riders.size; j++ )
1183 if ( isdefined(
self.riders[ j ] ) )
1185 self.riders[ j ]
delete();
1198 self endon(
"death" );
1200 if ( !isdefined(
self ) ||
self.abandoned ===
true ||
self.damage_on_death ===
false ||
self.radiusdamageradius <= 0 )
1205 position =
self.origin + ( 0,0,15 );
1206 radius =
self.radiusdamageradius;
1207 damageMax =
self.radiusdamagemax;
1208 damageMin =
self.radiusdamagemin;
1213 if ( isdefined(
self ) )
1215 self RadiusDamage( position, radius, damageMax, damageMin, attacker, meansOfDamage );
1222 if ( !isdefined(
self.destructibledef ) )
1224 if ( isdefined(
self.script_crashtypeoverride ) )
1226 crashtype =
self.script_crashtypeoverride;
1230 crashtype =
"aircraft";
1234 crashtype =
"helicopter";
1240 else if ( isdefined(
self.currentnode ) &&
crash_path_check(
self.currentnode ) )
1249 if ( crashtype ==
"aircraft" )
1253 else if ( crashtype ==
"helicopter" )
1255 if ( isdefined(
self.script_nocorpse ) )
1265 else if ( crashtype ==
"boat" )
1269 else if ( crashtype ==
"tank" )
1271 if ( !isdefined(
self.rollingdeath ) )
1278 self waittill(
"deathrolloff" );
1288 self notify(
"deadstop" );
1289 if (
self.disconnectPathOnStop ===
true )
1294 if ( ( isdefined(
self.tankgetout ) ) && (
self.tankgetout > 0 ) )
1297 self waittill(
"animsdone" );
1306 self endon(
"death" );
1310 if ( ( isdefined(
self.crashing ) ) && (
self.crashing ==
true ) )
1312 self waittill(
"crash_done" );
1319 if (
self.isphysicsvehicle )
1321 self ClearVehGoalPos();
1322 self CancelAIMove();
1325 while( stable_count < 3 )
1327 if ( isdefined(
self.velocity ) && LengthSquared(
self.velocity ) > 1.0 )
1341 while ( isdefined(
self ) &&
self GetSpeedMPH() > 0 )
1349 #define DAMAGE_FILTER_MIN_TIME 500
1352 self endon(
"death" );
1353 self endon(
"exit_vehicle" );
1354 self endon(
"end_damage_filter" );
1356 if ( !isdefined( heavy_damage_threshold ) )
1358 heavy_damage_threshold = 100;
1363 self waittill(
"damage",
damage, attacker, direction, point, type, tagName, modelName, partname, weapon );
1365 Earthquake( 0.25, 0.15,
self.origin, 512,
self );
1366 driver PlayRumbleOnEntity(
"damage_light" );
1371 level.n_hud_damage =
true;
1373 if (
damage > heavy_damage_threshold )
1375 driver playsound (
"veh_damage_filter_heavy" );
1379 driver playsound (
"veh_damage_filter_light" );
1382 level.n_last_damage_time = GetTime();
1394 self endon(
"death" );
1395 self endon(
"exit_vehicle" );
1396 self endon(
"end_damage_filter" );
1398 driver =
self GetSeatOccupant( 0 );
1400 if ( !isdefined(
self.damage_filter_init ) )
1403 self.damage_filter_init =
true;
1410 if ( isdefined( vision_set ) )
1417 level.n_hud_damage =
false;
1418 level.n_last_damage_time = GetTime();
1420 damagee = (
IS_TRUE( b_use_player_damage ) ? driver : self );
1427 if (
IS_TRUE( level.n_hud_damage ) )
1433 level.n_hud_damage =
false;
1447 if ( isdefined(
self ) )
1455 if ( !isdefined(
self ) )
1460 self endon(
"death" );
1464 self DisableAimAssist();
1476 self waittill(
"crash_done" );
1478 while(
IS_TRUE(
self.controlled ) )
1487 self endon(
"death" );
1489 self SetPhysAcceleration( ( 0, 0, -1000 ) );
1490 self.vehcheckforpredictedcrash =
true;
1492 forward = AnglesToForward(
self.angles );
1493 forward_mag = RandomFloatRange( 0, 300 );
1495 forward *= forward_mag;
1497 new_vel = forward + (
self.velocity * 0.2);
1499 ang_vel =
self GetAngularVelocity();
1501 yaw_vel = RandomFloatRange( 0, 130 ) *
math::sign( ang_vel[1] );
1504 ang_vel = ( RandomFloatRange( -1, 1 ), yaw_vel, 0 );
1507 roll_amount = ( abs( ang_vel[1] ) / 150.0 ) * 30.0;
1508 if( ang_vel[1] > 0 )
1510 roll_amount = -roll_amount;
1513 self.angles = (
self.angles[0],
self.angles[1], roll_amount );
1514 ang_vel = ( ang_vel[0], ang_vel[1], roll_amount * 0.9 );
1517 self.velocity_rotation_frac = 1.0;
1519 self.crash_accel = RandomFloatRange( 65, 90 );
1526 self endon(
"death" );
1528 self SetPhysAcceleration( ( 0, 0, -1000 ) );
1529 self.vehcheckforpredictedcrash =
true;
1531 forward = AnglesToForward(
self.angles );
1532 forward_mag = RandomFloatRange( 0, 250 );
1534 forward *= forward_mag;
1536 new_vel = forward + (0,0,70);
1538 ang_vel =
self GetAngularVelocity();
1539 yaw_vel = RandomFloatRange( 0, 60 ) *
math::sign( ang_vel[1] );
1542 roll_vel = RandomFloatRange( -200, 200 );
1544 ang_vel = ( RandomFloatRange( -5, 5 ), yaw_vel, roll_vel );
1547 self.velocity_rotation_frac = 1.0;
1549 self.crash_accel = RandomFloatRange( 145, 210 );
1551 self SetPhysAcceleration( ( 0, 0, -250 ) );
1558 self endon(
"death" );
1560 self SetPhysAcceleration( ( 0, 0, -1000 ) );
1561 self.vehcheckforpredictedcrash =
true;
1563 if( !isdefined( hitdir ) )
1567 hitdir = VectorNormalize( hitdir );
1569 side_dir = VectorCross( hitdir, (0,0,1) );
1570 side_dir_mag = RandomFloatRange( -280, 280 );
1571 side_dir_mag +=
math::sign( side_dir_mag ) * 150;
1572 side_dir *= side_dir_mag;
1574 forward = AnglesToForward(
self.angles );
1575 forward_mag = RandomFloatRange( 0, 300 );
1577 forward *= forward_mag;
1579 new_vel = (
self.velocity * 1.2) + forward + side_dir + (0,0,50);
1581 ang_vel =
self GetAngularVelocity();
1582 ang_vel = ( ang_vel[0] * 0.3, ang_vel[1], ang_vel[2] * 1.2 );
1584 yaw_vel = RandomFloatRange( 0, 130 ) *
math::sign( ang_vel[1] );
1587 ang_vel += ( RandomFloatRange( -5, 5 ), yaw_vel, RandomFloatRange( -18, 18 ) );
1590 self.velocity_rotation_frac = RandomFloatRange( 0.3, 0.99 );
1592 self.crash_accel = RandomFloatRange( 65, 90 );
1602 self SetVehVelocity( new_vel );
1603 self SetAngularVelocity( ang_vel );
1605 if( !isdefined(
self.off ) )
1612 self playsound(
"veh_wasp_dmg_hit");
1615 if( !isdefined(
self.off ) )
1622 if( RandomInt( 100 ) < 40 && !isdefined(
self.off ) &&
self.variant !==
"rocket" )
1629 if (
result ===
"crash_done" )
1637 self notify(
"crash_done" );
1643 self endon(
"crash_done" );
1644 self endon(
"death" );
1646 self CancelAIMove();
1647 self ClearVehGoalPos();
1648 self ClearLookAtEnt();
1650 self SetPhysAcceleration( ( 0, 0, -1000 ) );
1651 self.vehcheckforpredictedcrash =
true;
1653 if( !isdefined( hitdir ) )
1658 hitdir = VectorNormalize( hitdir );
1660 new_vel =
self.velocity;
1662 self.crash_style = -1;
1663 if(
self.crash_style == -1 )
1665 self.crash_style = RandomInt( 3 );
1668 switch(
self.crash_style )
1678 dmg_ent =
Spawn(
"script_origin",
self.origin);
1679 dmg_ent linkto (
self);
1680 dmg_ent PlayLoopSound (
"veh_wasp_dmg_loop");
1682 dmg_ent stoploopsound(1);
1689 self endon(
"crash_done" );
1690 self endon(
"death" );
1694 prev_forward = AnglesToForward(
self.angles );
1695 prev_forward_vel = VectorDot(
self.velocity, prev_forward ) *
self.velocity_rotation_frac;
1696 if( prev_forward_vel < 0 )
1698 prev_forward_vel = 0;
1703 self SetVehVelocity(
self.velocity + AnglesToUp(
self.angles ) *
self.crash_accel );
1704 self.crash_accel *= 0.98;
1707 new_velocity =
self.velocity;
1708 new_velocity -= prev_forward * prev_forward_vel;
1710 forward = AnglesToForward(
self.angles );
1711 new_velocity += forward * prev_forward_vel;
1713 prev_forward = forward;
1714 prev_forward_vel = VectorDot( new_velocity, prev_forward ) *
self.velocity_rotation_frac;
1715 if( prev_forward_vel < 10 )
1717 new_velocity += forward * 40;
1718 prev_forward_vel = 0;
1721 self SetVehVelocity( new_velocity );
1726 if ( count % 8 == 0 && RandomInt( 100 ) > 40 )
1728 if (
self.velocity[2] > 130.0 )
1730 self.crash_accel *= 0.75;
1732 else if (
self.velocity[2] < 40.0 && count < 60 )
1734 if ( Abs(
self.angles[0] ) > 35 || Abs(
self.angles[2] ) > 35 )
1736 self.crash_accel = RandomFloatRange( 100, 150 );
1740 self.crash_accel = RandomFloatRange( 45, 70 );
1749 sound_ent =
Spawn(
"script_origin",
self.origin );
1750 sound_ent PlayLoopSound(
"veh_qrdrone_death_fire_loop" , .1 );
1752 sound_ent StopLoopSound( 1 );
1768 if ( !isdefined(
self ) )
1773 self endon (
"death" );
1774 self endon (
"free_vehicle" );
1776 if ( shouldDelete ===
true )
1778 self SetVehVelocity( ( 0, 0, 0 ) );
1785 if ( shouldDelete ===
true )
1797 if ( isdefined(
self.cleanup_after_time ) )
1799 wait
self.cleanup_after_time;
1800 if ( isdefined(
self ) )