1 #using scripts\codescripts\struct;
2 #using scripts\shared\array_shared;
3 #using scripts\shared\hud_util_shared;
4 #using scripts\shared\system_shared;
5 #using scripts\shared\util_shared;
6 #using scripts\shared\clientfield_shared;
7 #using scripts\mp\gametypes\_spawning;
8 #using scripts\mp\_util;
9 #using scripts\mp\killstreaks\_qrdrone;
10 #using scripts\mp\killstreaks\_rcbomb;
11 #using scripts\shared\vehicle_death_shared;
13 #insert scripts\shared\shared.gsh;
15 #using_animtree ( "mp_vehicles" );
24 SetDvar(
"scr_veh_driversarehidden",
"1" );
25 SetDvar(
"scr_veh_driversareinvulnerable",
"1" );
29 SetDvar(
"scr_veh_alive_cleanuptimemin",
"119" );
30 SetDvar(
"scr_veh_alive_cleanuptimemax",
"120" );
31 SetDvar(
"scr_veh_dead_cleanuptimemin",
"20" );
32 SetDvar(
"scr_veh_dead_cleanuptimemax",
"30" );
37 SetDvar(
"scr_veh_cleanuptime_dmgfactor_min",
"0.33" );
38 SetDvar(
"scr_veh_cleanuptime_dmgfactor_max",
"1.0" );
39 SetDvar(
"scr_veh_cleanuptime_dmgfactor_deadtread",
"0.25" );
40 SetDvar(
"scr_veh_cleanuptime_dmgfraction_curve_begin",
"0.0" );
41 SetDvar(
"scr_veh_cleanuptime_dmgfraction_curve_end",
"1.0" );
43 SetDvar(
"scr_veh_cleanupabandoned",
"1" );
44 SetDvar(
"scr_veh_cleanupdrifted",
"1" );
45 SetDvar(
"scr_veh_cleanupmaxspeedmph",
"1" );
46 SetDvar(
"scr_veh_cleanupmindistancefeet",
"75" );
47 SetDvar(
"scr_veh_waittillstoppedandmindist_maxtime",
"10" );
48 SetDvar(
"scr_veh_waittillstoppedandmindist_maxtimeenabledistfeet",
"5" );
53 SetDvar(
"scr_veh_respawnafterhuskcleanup",
"1" );
54 SetDvar(
"scr_veh_respawntimemin",
"50" );
55 SetDvar(
"scr_veh_respawntimemax",
"90" );
56 SetDvar(
"scr_veh_respawnwait_maxiterations",
"30" );
57 SetDvar(
"scr_veh_respawnwait_iterationwaitseconds",
"1" );
59 SetDvar(
"scr_veh_disablerespawn",
"0" );
60 SetDvar(
"scr_veh_disableoverturndamage",
"0" );
63 SetDvar(
"scr_veh_explosion_spawnfx",
"1" );
64 SetDvar(
"scr_veh_explosion_doradiusdamage",
"1" );
65 SetDvar(
"scr_veh_explosion_radius",
"256" );
66 SetDvar(
"scr_veh_explosion_mindamage",
"20" );
67 SetDvar(
"scr_veh_explosion_maxdamage",
"200" );
70 SetDvar(
"scr_veh_ondeath_createhusk",
"1" );
71 SetDvar(
"scr_veh_ondeath_usevehicleashusk",
"1" );
72 SetDvar(
"scr_veh_explosion_husk_forcepointvariance",
"30" );
73 SetDvar(
"scr_veh_explosion_husk_horzvelocityvariance",
"25" );
74 SetDvar(
"scr_veh_explosion_husk_vertvelocitymin",
"100" );
75 SetDvar(
"scr_veh_explosion_husk_vertvelocitymax",
"200" );
78 SetDvar(
"scr_veh_explode_on_cleanup",
"1" );
79 SetDvar(
"scr_veh_disappear_maxwaittime",
"60" );
80 SetDvar(
"scr_veh_disappear_maxpreventdistancefeet",
"30" );
81 SetDvar(
"scr_veh_disappear_maxpreventvisibilityfeet",
"150" );
83 SetDvar(
"scr_veh_health_tank",
"1350" );
85 level.vehicle_drivers_are_invulnerable = GetDvarint(
"scr_veh_driversareinvulnerable" );
89 level.vehicleHealths[
"panzer4_mp" ] = 2600;
90 level.vehicleHealths[
"t34_mp" ] = 2600;
92 SetDvar(
"scr_veh_health_jeep",
"700" );
97 level.vehicle_explosion_effect =
"_t6/vehicle/vexplosion/fx_vexplode_helicopter_exp_mp";
99 level.veh_husk_models = [];
100 level.veh_husk_effects = [];
102 if ( isdefined( level.use_new_veh_husks ) )
104 level.veh_husk_models[
"t34_mp" ] =
"veh_t34_destroyed_mp";
108 if ( isdefined( level.onAddVehicleHusks) )
110 [[level.onAddVehicleHusks]]();
117 chopper_player_get_on_gun = %int_huey_gunner_on;
118 chopper_door_open = %v_huey_door_open;
119 chopper_door_open_state = %v_huey_door_open_state;
120 chopper_door_closed_state = %v_huey_door_close_state;
122 killbrushes = GetEntArray(
"water_killbrush",
"targetname" );
124 foreach( brush
in killbrushes )
136 self waittill(
"trigger", entity );
138 if ( isdefined( entity ) )
140 if ( isdefined( entity.targetname ) )
142 if ( entity.targetname ==
"rcbomb" )
144 entity notify(
"rcbomb_shutdown" );
146 else if ( entity.targetname ==
"talon" && !
IS_TRUE( entity.dead ) )
148 entity notify(
"death" );
152 if ( isdefined( entity.heliType ) && entity.heliType ==
"qrdrone" )
185 k_mild_damage_index= 0;
186 k_moderate_damage_index= 1;
187 k_severe_damage_index= 2;
188 k_total_damage_index= 3;
191 k_mild_damage_health_percentage= 0.85;
192 k_moderate_damage_health_percentage= 0.55;
193 k_severe_damage_health_percentage= 0.35;
194 k_total_damage_health_percentage= 0;
195 level.k_mild_damage_health_percentage = k_mild_damage_health_percentage;
196 level.k_moderate_damage_health_percentage = k_moderate_damage_health_percentage;
197 level.k_severe_damage_health_percentage = k_severe_damage_health_percentage;
198 level.k_total_damage_health_percentage = k_total_damage_health_percentage;
200 level.vehicles_damage_states= [];
201 level.vehicles_husk_effects = [];
202 level.vehicles_damage_treadfx = [];
207 level.vehicles_damage_states[vehicle_name]= [];
208 level.vehicles_damage_treadfx[vehicle_name] = [];
212 level.vehicles_damage_states[vehicle_name][k_mild_damage_index]= SpawnStruct();
213 level.vehicles_damage_states[vehicle_name][k_mild_damage_index].health_percentage= k_mild_damage_health_percentage;
214 level.vehicles_damage_states[vehicle_name][k_mild_damage_index].effect_array= [];
216 level.vehicles_damage_states[vehicle_name][k_mild_damage_index].effect_array[0]= SpawnStruct();
217 level.vehicles_damage_states[vehicle_name][k_mild_damage_index].effect_array[0].damage_effect=
"_t6/vehicle/vfire/fx_tank_sherman_smldr";
218 level.vehicles_damage_states[vehicle_name][k_mild_damage_index].effect_array[0].sound_effect= undefined;
219 level.vehicles_damage_states[vehicle_name][k_mild_damage_index].effect_array[0].vehicle_tag=
"tag_origin";
223 level.vehicles_damage_states[vehicle_name][k_moderate_damage_index]= SpawnStruct();
224 level.vehicles_damage_states[vehicle_name][k_moderate_damage_index].health_percentage= k_moderate_damage_health_percentage;
225 level.vehicles_damage_states[vehicle_name][k_moderate_damage_index].effect_array= [];
227 level.vehicles_damage_states[vehicle_name][k_moderate_damage_index].effect_array[0]= SpawnStruct();
228 level.vehicles_damage_states[vehicle_name][k_moderate_damage_index].effect_array[0].damage_effect=
"_t6/vehicle/vfire/fx_vfire_med_12";
229 level.vehicles_damage_states[vehicle_name][k_moderate_damage_index].effect_array[0].sound_effect= undefined;
230 level.vehicles_damage_states[vehicle_name][k_moderate_damage_index].effect_array[0].vehicle_tag=
"tag_origin";
234 level.vehicles_damage_states[vehicle_name][k_severe_damage_index]= SpawnStruct();
235 level.vehicles_damage_states[vehicle_name][k_severe_damage_index].health_percentage= k_severe_damage_health_percentage;
236 level.vehicles_damage_states[vehicle_name][k_severe_damage_index].effect_array= [];
238 level.vehicles_damage_states[vehicle_name][k_severe_damage_index].effect_array[0]= SpawnStruct();
239 level.vehicles_damage_states[vehicle_name][k_severe_damage_index].effect_array[0].damage_effect=
"_t6/vehicle/vfire/fx_vfire_sherman";
240 level.vehicles_damage_states[vehicle_name][k_severe_damage_index].effect_array[0].sound_effect= undefined;
241 level.vehicles_damage_states[vehicle_name][k_severe_damage_index].effect_array[0].vehicle_tag=
"tag_origin";
245 level.vehicles_damage_states[vehicle_name][k_total_damage_index]= SpawnStruct();
246 level.vehicles_damage_states[vehicle_name][k_total_damage_index].health_percentage= k_total_damage_health_percentage;
247 level.vehicles_damage_states[vehicle_name][k_total_damage_index].effect_array= [];
249 level.vehicles_damage_states[vehicle_name][k_total_damage_index].effect_array[0]= SpawnStruct();
250 level.vehicles_damage_states[vehicle_name][k_total_damage_index].effect_array[0].damage_effect=
"_t6/vehicle/vexplosion/fx_vexplode_helicopter_exp_mp";
251 level.vehicles_damage_states[vehicle_name][k_total_damage_index].effect_array[0].sound_effect=
"vehicle_explo";
252 level.vehicles_damage_states[vehicle_name][k_total_damage_index].effect_array[0].vehicle_tag=
"tag_origin";
257 default_husk_effects = SpawnStruct();
258 default_husk_effects.damage_effect = undefined;
259 default_husk_effects.sound_effect = undefined;
260 default_husk_effects.vehicle_tag =
"tag_origin";
262 level.vehicles_husk_effects[ vehicle_name ] = default_husk_effects;
278 if (isdefined(vehicle))
280 if (isdefined(vehicle.vehicletype))
282 name= vehicle.vehicletype;
292 return "defaultvehicle_mp";
301 if ( !isdefined(level.vehicles_damage_states) || !isdefined(level.vehicles_damage_states[vehicle_name]))
313 if ( !isdefined( level.vehicles_damage_states ) )
316 damage_state_index= -1;
319 for (test_index= 0; test_index<level.vehicles_damage_states[vehicle_name].size; test_index++)
321 if (vehicle.current_health_percentage<=level.vehicles_damage_states[vehicle_name][test_index].health_percentage)
323 damage_state_index= test_index;
331 return damage_state_index;
340 if (vehicle.initial_state.health>0)
343 vehicle.current_health_percentage= vehicle.health/vehicle.initial_state.health;
346 if (previous_damage_state_index!=current_damage_state_index)
348 vehicle notify (
"damage_state_changed" );
349 if (previous_damage_state_index<0)
351 start_damage_state_index= 0;
355 start_damage_state_index= previous_damage_state_index+1;
358 if ( vehicle.health <= 0 )
369 start_damage_state_index,
370 end_damage_state_index)
375 for (damage_state_index= start_damage_state_index; damage_state_index<=end_damage_state_index; damage_state_index++)
377 for (effect_index= 0;
378 effect_index<level.vehicles_damage_states[vehicle_name][damage_state_index].effect_array.size;
381 effects = level.vehicles_damage_states[ vehicle_name ][ damage_state_index ].effect_array[ effect_index ];
392 self endon(
"delete" );
393 self endon(
"removed" );
395 if ( !isdefined( isDamagedTread ) || isDamagedTread == 0 )
397 self endon(
"damage_state_changed" );
401 if ( isdefined( effects.sound_effect ) )
403 self PlaySound( effects.sound_effect );
407 if ( isdefined ( effects.damage_effect_loop_time ) )
409 waitTime = effects.damage_effect_loop_time;
412 while ( waitTime > 0 )
415 if ( isdefined( effects.damage_effect ) )
417 PlayFxOnTag( effects.damage_effect,
self, effects.vehicle_tag );
426 vehicles = getentarray(
"script_vehicle",
"classname" );
429 if ( isdefined( vehicles ) )
431 return vehicles.size;
447 if ( !isdefined( level.vehicles_list ) )
449 level.vehicles_list = [];
452 level.vehicles_list[ level.vehicles_list.size ] =
self;
463 if ( !isdefined( level.vehicles_list ) )
469 MAX_VEHICLES = GetMaxVehicles();
476 for ( i = 0; i < level.vehicles_list.size; i++ )
478 if ( isdefined( level.vehicles_list[ i ] ) )
480 newArray[ newArray.size ] = level.vehicles_list[ i ];
484 level.vehicles_list = newArray;
489 vehiclesToDelete = ( level.vehicles_list.size + 1 ) - MAX_VEHICLES;
492 if ( vehiclesToDelete > 0 )
496 for ( i = 0; i < level.vehicles_list.size; i++ )
498 vehicle = level.vehicles_list[ i ];
500 if ( vehiclesToDelete > 0 )
503 if ( isdefined( vehicle.is_husk ) && !isdefined( vehicle.permanentlyRemoved ) )
515 newArray[ newArray.size ] = vehicle;
518 level.vehicles_list = newArray;
521 return level.vehicles_list.size < MAX_VEHICLES;
541 if ( isdefined( level.vehicleHealths ) && isdefined( level.vehicleHealths[
self.vehicletype ] ) )
543 self.maxhealth = level.vehicleHealths[
self.vehicletype ];
547 self.maxhealth = GetDvarint(
"scr_veh_health_tank");
549 println(
"No health specified for vehicle type "+
self.vehicletype+
"! Using default..." );
552 self.health =
self.maxhealth;
567 if (
self.initial_state.health>0)
569 self.current_health_percentage=
self.health/
self.initial_state.health;
570 self.previous_health_percentage=
self.health/
self.initial_state.health;
574 self.current_health_percentage= 1;
575 self.previous_health_percentage= 1;
586 self.original_vehicle =
true;
594 self endon(
"transmute" );
595 self endon(
"death" );
596 self endon(
"delete" );
600 self waittill(
"enter_vehicle", player );
613 self endon(
"disconnect" );
615 self waittill(
"exit_vehicle", vehicle );
622 self endon(
"transmute" );
623 self endon(
"death" );
624 self endon(
"delete" );
628 self waittill (
"damage" );
630 occupants =
self GetVehOccupants();
631 if( isdefined( occupants ) )
633 for( i = 0; i < occupants.size; i++ )
646 if ( !isdefined(
self.vehicleHud ) )
650 self.vehicleHud.alpha = 0.75;
653 self.vehicleHud
hud::updateBar( vehicle.health / vehicle.initial_state.health );
657 if ( isdefined(
self.vehicleHud ) )
663 if ( GetDvarString(
"scr_vehicle_healthnumbers" )!=
"" )
665 if ( GetDvarint(
"scr_vehicle_healthnumbers" )!= 0 )
669 if ( !isdefined(
self.vehicleHudHealthNumbers ) )
673 self.vehicleHudHealthNumbers
hud::setPoint(
"LEFT",
"RIGHT", 8, 0 );
674 self.vehicleHudHealthNumbers.alpha = 0.75;
675 self.vehicleHudHealthNumbers.hideWhenInMenu =
false;
676 self.vehicleHudHealthNumbers.archived =
false;
679 self.vehicleHudHealthNumbers setValue( vehicle.health );
683 if ( isdefined(
self.vehicleHudHealthNumbers ) )
704 if( isdefined( level.enableVehicleHealthbar ) && level.enableVehicleHealthbar )
714 if (GetDvarint(
"scr_veh_disableoverturndamage") == 0)
735 if( isdefined( typeoverride ) )
738 if( !isdefined( level.vehicle_death_fx ) )
739 level.vehicle_death_fx = [];
740 if( !isdefined( level.vehicle_death_fx[ type ] ) )
741 level.vehicle_death_fx[ type ] = [];
743 level.vehicle_compassicon[ type ] =
false;
744 level.vehicle_team[ type ] =
"axis";
745 level.vehicle_life[ type ] = 999;
746 level.vehicle_hasMainTurret[ model ] =
false;
747 level.vehicle_mainTurrets[ model ] = [];
748 level.vtmodel = model;
770 if( !isdefined( level.vehicle_rumble ) )
771 level.vehicle_rumble = [];
772 struct =
build_quake( scale, duration, radius, basetime, randomaditionaltime );
773 assert( isdefined(
rumble ) );
775 level.vehicle_rumble[ level.vttype ] =
struct;
778 function build_quake( scale, duration, radius, basetime, randomaditionaltime )
780 struct = spawnstruct();
781 struct.scale = scale;
782 struct.duration = duration;
783 struct.radius = radius;
784 if( isdefined( basetime ) )
785 struct.basetime = basetime;
786 if( isdefined( randomaditionaltime ) )
787 struct.randomaditionaltime = randomaditionaltime;
804 level.vehicle_exhaust[ level.vtmodel ] = effect;
813 self endon(
"transmute" );
814 self endon(
"death" );
815 self endon(
"delete" );
823 self endon(
"transmute" );
824 self endon(
"death" );
825 self endon(
"delete" );
833 self endon(
"enter_vehicle" );
846 health_percentage =
self.health /
self.initial_state.health;
848 self waittill(
"damage" );
850 health_percentage =
self.health /
self.initial_state.health;
852 if ( isdefined( level.k_severe_damage_health_percentage ) && health_percentage < level.k_severe_damage_health_percentage )
860 varnamePrefix =
"scr_veh_" + state +
"_cleanuptime";
861 minTime = getdvarfloat( varnamePrefix +
"min" );
862 maxTime = getdvarfloat( varnamePrefix +
"max" );
864 if ( maxTime > minTime )
866 return RandomFloatRange( minTime, maxTime );
880 seconds_per_iteration = 1.0;
884 curve_begin = GetDvarfloat(
"scr_veh_cleanuptime_dmgfraction_curve_begin" );
885 curve_end = GetDvarfloat(
"scr_veh_cleanuptime_dmgfraction_curve_end" );
887 factor_min = GetDvarfloat(
"scr_veh_cleanuptime_dmgfactor_min" );
888 factor_max = GetDvarfloat(
"scr_veh_cleanuptime_dmgfactor_max" );
890 treadDeadDamageFactor = GetDvarfloat(
"scr_veh_cleanuptime_dmgfactor_deadtread" );
893 damageFraction = 0.0;
897 damageFraction = (
self.initial_state.health -
self.health ) /
self.initial_state.health;
901 damageFraction = 1.0;
906 if ( damageFraction <= curve_begin )
908 damageFactor = factor_max;
910 else if ( damageFraction >= curve_end )
912 damageFactor = factor_min;
916 dydx = ( factor_min - factor_max ) / ( curve_end - curve_begin );
917 damageFactor = factor_max + ( damageFraction - curve_begin ) * dydx;
920 totalSecsToWait = initialRandomWaitSeconds * damageFactor;
922 if ( secondsWaited >= totalSecsToWait )
927 wait seconds_per_iteration;
928 secondsWaited = secondsWaited + seconds_per_iteration;
937 seconds_waited = 0.0;
938 seconds_per_iteration = 1.0;
940 while ( seconds_waited < total_secs_to_wait )
942 wait seconds_per_iteration;
943 seconds_waited = seconds_waited + seconds_per_iteration;
948 function cleanup( test_name, cleanup_dvar_name, cleanup_func )
952 while ( keep_waiting )
954 cleanupEnabled = !isdefined( cleanup_dvar_name )
955 || getdvarint( cleanup_dvar_name ) != 0;
957 if ( cleanupEnabled != 0 )
959 self [[cleanup_func]]();
963 keep_waiting =
false;
969 self endon(
"death" );
970 self endon(
"delete" );
976 self waittill (
"broken", brokenNotify );
977 if ( brokenNotify ==
"left_tread_destroyed" )
979 if ( isdefined( level.vehicles_damage_treadfx[vehicle_name] ) && isdefined( level.vehicles_damage_treadfx[vehicle_name][0] ) )
984 else if ( brokenNotify ==
"right_tread_destroyed" )
986 if ( isdefined( level.vehicles_damage_treadfx[vehicle_name] ) && isdefined( level.vehicles_damage_treadfx[vehicle_name][1] ) )
996 maxWaitTime = GetDvarfloat(
"scr_veh_waittillstoppedandmindist_maxtime" );
997 iterationWaitSeconds = 1.0;
999 maxWaitTimeEnableDistInches = 12 * GetDvarfloat(
"scr_veh_waittillstoppedandmindist_maxtimeenabledistfeet" );
1001 initialOrigin =
self.initial_state.origin;
1003 for ( totalSecondsWaited = 0.0; totalSecondsWaited < maxWaitTime; totalSecondsWaited += iterationWaitSeconds )
1007 speedMPH =
self GetSpeedMPH();
1008 cutoffMPH = GetDvarfloat(
"scr_veh_cleanupmaxspeedmph" );
1010 if ( speedMPH > cutoffMPH )
1018 wait iterationWaitSeconds;
1025 self endon(
"transmute" );
1026 self endon(
"death" );
1027 self endon(
"delete" );
1031 self waittill(
"exit_vehicle" );
1033 occupants =
self GetVehOccupants();
1035 if ( occupants.size == 0 )
1046 if ( isdefined(
self.start_stop_sfxid ) )
1051 self.start_stop_sfxid =
self playSound( sound_alias );
1059 self endon(
"transmute" );
1060 self endon(
"death" );
1061 self endon(
"delete" );
1063 if ( IsDefined(
self.vehicleClass ) &&
"artillery" ==
self.vehicleClass )
1072 self waittill(
"enter_vehicle", player, seat );
1074 isDriver = seat == 0;
1076 if ( GetDvarint(
"scr_veh_driversarehidden" ) != 0
1084 occupants =
self GetVehOccupants();
1086 if ( occupants.size == 1 )
1102 if (
self IsRemoteControlling() )
1105 if (!isdefined(level.vehicle_drivers_are_invulnerable))
1106 level.vehicle_drivers_are_invulnerable =
false;
1108 invulnerable = ( level.vehicle_drivers_are_invulnerable && (
self player_is_driver() ) );
1110 return invulnerable;
1116 if ( !isalive(
self) )
1119 vehicle =
self GetVehicleOccupied();
1121 if ( isdefined( vehicle ) )
1123 if ( IsDefined( vehicle.vehicleClass ) &&
"artillery" == vehicle.vehicleClass )
1128 seat = vehicle GetOccupantSeat(
self );
1130 if ( isdefined(seat) && seat == 0 )
1142 self endon(
"disconnect" );
1143 self endon(
"exit_vehicle" );
1147 self waittill(
"change_seat", vehicle, oldSeat, newSeat );
1149 isDriver = newSeat == 0;
1153 if ( GetDvarint(
"scr_veh_driversarehidden" ) != 0 )
1170 self endon(
"disconnect" );
1171 self waittill(
"exit_vehicle" );
1172 currentWeapon =
self getCurrentWeapon();
1174 if ( IsDefined(
self.lastWeapon ) &&
self.lastWeapon != currentWeapon &&
self.lastWeapon != level.weaponNone )
1176 self switchToWeapon(
self.lastWeapon );
1185 return self.vehicletype ==
"sherman_mp"
1186 ||
self.vehicletype ==
"panzer4_mp"
1187 ||
self.vehicletype ==
"type97_mp"
1188 ||
self.vehicletype ==
"t34_mp";
1196 if ( !isdefined(
self.initial_state ) )
1198 self.initial_state= SpawnStruct();
1201 if ( isdefined(
self.origin ) )
1203 self.initial_state.origin=
self.origin;
1206 if ( isdefined(
self.angles ) )
1208 self.initial_state.angles=
self.angles;
1211 if ( isdefined(
self.health ) )
1213 self.initial_state.health=
self.health;
1224 return GetDvarint(
"scr_veh_explode_on_cleanup" ) != 0;
1231 self.recycling =
true;
1237 self endon(
"transmute" );
1238 self endon(
"death" );
1239 self endon(
"delete" );
1241 worldup = anglestoup((0,90,0));
1247 if ( isdefined(
self.angles ) )
1249 up = AnglesToUp(
self.angles );
1250 dot = vectordot(up, worldup);
1262 self endon(
"transmute" );
1263 self endon(
"death" );
1264 self endon(
"delete" );
1268 self waittill(
"veh_ejectoccupants" );
1270 if ( isdefined( level.onEjectOccupants ) )
1272 [[level.onEjectOccupants]]();
1281 occupants =
self GetVehOccupants();
1282 if ( isdefined( occupants ) )
1284 for ( i = 0; i < occupants.size; i++ )
1286 if ( isdefined( occupants[i] ) )
1288 occupants[i] Unlink();
1296 self endon(
"transmute" );
1297 self endon(
"death" );
1298 self endon(
"delete" );
1302 seconds = RandomFloatRange( 5, 7 );
1305 damageOrigin =
self.origin + (0,0,25);
1306 self finishVehicleRadiusDamage(
self,
self, 32000, 32000, 32000, 0,
"MOD_EXPLOSIVE", level.weaponNone, damageOrigin, 400, -1, (0,0,1), 0);
1316 damageOrigin =
self.origin + (0,0,1);
1317 self finishVehicleRadiusDamage(attacker, attacker, 32000, 32000, 10, 0,
"MOD_EXPLOSIVE", level.weaponNone, damageOrigin, 400, -1, (0,0,1), 0);
1322 if ( isdefined( preferred_value ) )
1324 return preferred_value;
1327 return default_value;
1333 deathOrigin =
self.origin;
1334 deathAngles =
self.angles;
1340 respawn_parameters = SpawnStruct();
1341 respawn_parameters.origin =
self.initial_state.origin;
1342 respawn_parameters.angles =
self.initial_state.angles;
1343 respawn_parameters.health =
self.initial_state.health;
1346 respawn_parameters.destructibledef =
self.destructibledef;
1349 vehicleWasDestroyed = !isdefined(
self.recycling );
1351 if ( vehicleWasDestroyed
1356 if ( vehicleWasDestroyed
1357 && GetDvarint(
"scr_veh_explosion_doradiusdamage" ) != 0 )
1363 explosionRadius = GetDvarint(
"scr_veh_explosion_radius" );
1364 explosionMinDamage = GetDvarint(
"scr_veh_explosion_mindamage" );
1365 explosionMaxDamage = GetDvarint(
"scr_veh_explosion_maxdamage" );
1367 self RadiusDamage( deathOrigin, explosionRadius, explosionMaxDamage, explosionMinDamage, attacker,
"MOD_EXPLOSIVE", GetWeapon(
self.vehicletype +
"_explosion" ) );
1372 self notify(
"transmute" );
1375 respawn_vehicle_now =
true;
1377 if ( vehicleWasDestroyed
1378 && GetDvarint(
"scr_veh_ondeath_createhusk" ) != 0 )
1382 if ( GetDvarint(
"scr_veh_ondeath_usevehicleashusk" ) != 0 )
1385 self.is_husk =
true;
1389 husk =
_spawn_husk( deathOrigin, deathAngles,
self.vehmodel );
1392 husk
_init_husk( vehicle_name, respawn_parameters );
1394 if ( GetDvarint(
"scr_veh_respawnafterhuskcleanup" ) != 0 )
1396 respawn_vehicle_now =
false;
1401 if ( !isdefined(
self.is_husk ) )
1406 if ( GetDvarint(
"scr_veh_disablerespawn" ) != 0 )
1408 respawn_vehicle_now =
false;
1411 if ( respawn_vehicle_now )
1421 minTime = GetDvarint(
"scr_veh_respawntimemin" );
1422 maxTime = GetDvarint(
"scr_veh_respawntimemax" );
1423 seconds = RandomFloatRange( minTime, maxTime );
1434 iprintln(
"Vehicle can't respawn because MAX_VEHICLES has been reached and none of the vehicles could be cleaned up.");
1439 if ( isdefined( respawn_parameters.destructibledef ) )
1441 vehicle = SpawnVehicle(
1442 respawn_parameters.vehicletype,
1443 respawn_parameters.origin,
1444 respawn_parameters.angles,
1445 respawn_parameters.targetname,
1446 respawn_parameters.destructibledef );
1450 vehicle = SpawnVehicle(
1451 respawn_parameters.vehicletype,
1452 respawn_parameters.origin,
1453 respawn_parameters.angles,
1454 respawn_parameters.targetname );
1457 vehicle.vehicletype = respawn_parameters.vehicletype;
1458 vehicle.destructibledef = respawn_parameters.destructibledef;
1459 vehicle.health = respawn_parameters.health;
1474 self notify (
"removed" );
1476 if ( isdefined(
self.original_vehicle ) )
1478 if ( !isdefined(
self.permanentlyRemoved ) )
1480 self.permanentlyRemoved =
true;
1506 under_the_world = (
self.origin[0],
self.origin[1],
self.origin[2] - 10000 );
1507 self.origin = under_the_world;
1512 self notify(
"hidden_permanently" );
1518 maxPreventDistanceFeet = GetDvarint(
"scr_veh_disappear_maxpreventdistancefeet" );
1519 maxPreventVisibilityFeet = GetDvarint(
"scr_veh_disappear_maxpreventvisibilityfeet" );
1521 maxPreventDistanceInchesSq = 144 * maxPreventDistanceFeet * maxPreventDistanceFeet;
1522 maxPreventVisibilityInchesSq = 144 * maxPreventVisibilityFeet * maxPreventVisibilityFeet;
1525 maxSecondsToWait = GetDvarfloat(
"scr_veh_disappear_maxwaittime" );
1526 iterationWaitSeconds = 1.0;
1528 for ( secondsWaited = 0.0; secondsWaited < maxSecondsToWait; secondsWaited += iterationWaitSeconds )
1534 for ( j = 0; j < players_s.a.size && okToCleanup; j++ )
1536 player = players_s.a[ j ];
1537 distInchesSq = DistanceSquared(
self.origin, player.origin );
1539 if ( distInchesSq < maxPreventDistanceInchesSq )
1541 okToCleanup =
false;
1543 else if ( distInchesSq < maxPreventVisibilityInchesSq )
1545 vehicleVisibilityFromPlayer =
self SightConeTrace( player.origin, player, AnglesToForward( player.angles ) );
1547 if ( vehicleVisibilityFromPlayer > 0 )
1549 okToCleanup =
false;
1559 wait iterationWaitSeconds;
1566 maxIterations = GetDvarint(
"scr_veh_respawnwait_maxiterations" );
1567 iterationWaitSeconds = GetDvarint(
"scr_veh_respawnwait_iterationwaitseconds" );
1569 for ( i = 0; i < maxIterations; i++ )
1576 wait iterationWaitSeconds;
1585 for ( i = 0; i < players_s.a.size; i++ )
1604 for ( i = 0; i < players_s.a.size; i++ )
1606 player = players_s.a[ i ];
1610 player DoDamage( 20000, player.origin + ( 0, 0, 1 ), attacker, inflictor,
"none" );
1618 distanceInches = 20 * 12;
1619 minDistInchesSq = distanceInches * distanceInches;
1621 distInchesSq = DistanceSquared(
self.origin, position );
1623 return distInchesSq < minDistInchesSq;
1629 self endon(
"delete" );
1631 self waittill(
"death", attacker );
1633 if ( isdefined(
self ) )
1642 self playSound(
"car_explo_large" );
1648 self endon(
"delete" );
1649 self endon(
"removed" );
1653 self waittill (
"damage",
damage, attacker );
1655 players = GetPlayers();
1656 for ( i = 0 ; i < players.size ; i++ )
1658 if ( !isalive(players[i]) )
1661 vehicle = players[i] GetVehicleOccupied();
1673 println(
"Playing heavy rumble." );
1675 players[i] PlayRumbleOnEntity(
"tank_damage_heavy_mp" );
1680 println(
"Playing light rumble." );
1682 players[i] PlayRumbleOnEntity(
"tank_damage_light_mp" );
1688 if (
self.health <= 0 )
1701 husk =
spawn(
"script_model", origin );
1702 husk.angles = angles;
1703 husk SetModel( modelname );
1706 husk SetCanDamage(
false );
1715 return isdefined(
self.vehicletype );
1721 if ( isdefined(
self.vehicletype ) )
1723 husk_model = level.veh_husk_models[
self.vehicletype ];
1725 if ( isdefined( husk_model ) )
1727 self SetModel( husk_model );
1737 if ( isdefined( level.vehicles_husk_effects ) )
1739 effects = level.vehicles_husk_effects[ vehicle_name ];
1743 self.respawn_parameters = respawn_parameters;
1746 forcePointVariance = GetDvarint(
"scr_veh_explosion_husk_forcepointvariance" );
1747 horzVelocityVariance = GetDvarint(
"scr_veh_explosion_husk_horzvelocityvariance" );
1748 vertVelocityMin = GetDvarint(
"scr_veh_explosion_husk_vertvelocitymin" );
1749 vertVelocityMax = GetDvarint(
"scr_veh_explosion_husk_vertvelocitymax" );
1752 forcePointX = RandomFloatRange( 0-forcePointVariance, forcePointVariance );
1753 forcePointY = RandomFloatRange( 0-forcePointVariance, forcePointVariance );
1754 forcePoint = ( forcePointX, forcePointY, 0 );
1756 forcePoint +=
self.origin;
1758 initialVelocityX = RandomFloatRange( 0-horzVelocityVariance, horzVelocityVariance );
1759 initialVelocityY = RandomFloatRange( 0-horzVelocityVariance, horzVelocityVariance );
1760 initialVelocityZ = RandomFloatRange( vertVelocityMin, vertVelocityMax );
1761 initialVelocity = ( initialVelocityX, initialVelocityY, initialVelocityZ );
1766 self LaunchVehicle( initialVelocity, forcePoint );
1770 self PhysicsLaunch( forcePoint, initialVelocity );
1780 self endon(
"death" );
1781 self endon(
"delete" );
1782 self endon(
"hidden_permanently" );
1785 respawn_parameters =
self.respawn_parameters;
1801 if ( GetDvarint(
"scr_veh_respawnafterhuskcleanup" ) != 0 )
1803 if ( GetDvarint(
"scr_veh_disablerespawn" ) == 0 )
1840 if ( GetDvarint(
"scr_veh_explosion_spawnfx" ) == 0 )
1845 if ( isdefined( level.vehicle_explosion_effect ) )
1847 forward = ( 0, 0, 1 );
1849 rot = randomfloat( 360 );
1850 up = ( cos( rot ), sin( rot ), 0 );
1852 PlayFX( level.vehicle_explosion_effect, origin, forward, up );
1862 org =
Spawn(
"script_origin", origin );
1863 org.origin = origin;
1864 org PlaySoundWithNotify( soundEffectName,
"sounddone" );
1865 org waittill(
"sounddone" );
1873 self notify(
"kill_disconnect_paths_forever" );
1905 self endon(
"death");
1907 assert( isdefined( node ),
"vehicle_path() called without a path" );
1908 self notify(
"newpath" );
1911 if( isdefined( node ) )
1913 self.attachedpath = node;
1916 pathstart =
self.attachedpath;
1917 self.currentNode =
self.attachedpath;
1919 if( !isdefined( pathstart ) )
1924 self AttachPath( pathstart );
1927 self endon(
"newpath" );
1929 nextpoint = pathstart;
1931 while ( isdefined( nextpoint ) )
1933 self waittill(
"reached_node", nextpoint );
1935 self.currentNode = nextpoint;
1938 nextpoint notify(
"trigger",
self );
1940 if ( isdefined( nextpoint.script_noteworthy ) )
1942 self notify( nextpoint.script_noteworthy );
1943 self notify(
"noteworthy", nextpoint.script_noteworthy, nextpoint );
1957 if ( level.disableVehicleSpawners ===
true )
1969 for( i = 0; i < spawn_nodes.size; i++ )
1971 spawn_node = spawn_nodes[i];
1973 veh_name = spawn_node.script_noteworthy;
1974 time_interval = int(spawn_node.script_parameters);
1976 if( !isdefined( veh_name ) )
1980 thread
VehicleSpawnThread( veh_spawner_id, veh_name, spawn_node.origin, spawn_node.angles, time_interval );
1982 if ( isdefined( level.vehicle_spawner_init ) )
1983 level [[ level.vehicle_spawner_init ]] ( veh_spawner_id, veh_name, spawn_node.origin, spawn_node.angles );
1988 if ( isdefined( level.vehicle_spawners_init_finished ) )
1989 level thread [[ level.vehicle_spawners_init_finished ]]();
1994 level endon(
"game_ended" );
1996 veh_spawner = GetEnt( veh_name +
"_spawner",
"targetname" );
2001 vehicle = veh_spawner SpawnFromSpawner( veh_name,
true,
true,
true );
2002 if( !isdefined( vehicle ) )
2004 wait RandomFloatRange( 1.0, 2.0 );
2008 if( isdefined( vehicle.archetype ) )
2009 vehicle ASMRequestSubstate(
"locomotion@movement" );
2013 vehicle.origin = origin;
2014 vehicle.angles = angles;
2015 vehicle.veh_spawner_id = veh_spawner_id;
2020 vehicle waittill(
"death" );
2023 if ( isdefined( level.vehicle_destroyed ) )
2024 level thread [[ level.vehicle_destroyed ]]( veh_spawner_id );
2027 if( isdefined( time_interval ) )
2037 fx_prespawn_time = 5.0;
2038 fx_spawn_delay = spawn_delay - fx_prespawn_time;
2040 wait fx_spawn_delay;
2042 if ( isdefined( level.vehicle_about_to_spawn ) )
2044 level thread [[ level.vehicle_about_to_spawn ]]( veh_spawner_id, veh_name, origin, angles, fx_prespawn_time );
2047 kill_overlap_time = 0.1;
2049 wait_before_kill = fx_prespawn_time - kill_overlap_time;
2050 wait wait_before_kill;
2052 kill_duration_ms = kill_overlap_time * 2 * 1000;
2055 wait kill_overlap_time;
2060 kill_expire_time_ms = GetTime() + kill_duration_ms;
2062 kill_weapon = GetWeapon(
"hero_minigun" );
2064 while ( GetTime() <= kill_expire_time_ms )
2066 foreach( player
in level.players )
2068 if ( !isdefined( player ) )
2073 if ( player IsInVehicle() )
2075 vehicle = player GetVehicleOccupied();
2076 if ( isdefined( vehicle ) && ( vehicle.is_oob_kill_target ===
true ) )
2086 potential_victims = GetAIArray();
2088 if ( isdefined( potential_victims ) )
2090 foreach( entity
in potential_victims )
2092 if ( !isdefined( entity ) )
2098 if ( isdefined( entity.health ) && entity.health <= 0 )
2101 if ( IsVehicle( entity ) )
2114 vehicle DoDamage( vehicle.health + 10000, vehicle.origin, undefined, undefined,
"none",
"MOD_TRIGGER_HURT" );
2122 vehicle endon(
"death" );
2124 vehicle MakeVehicleUsable();
2125 if( Target_isTarget( vehicle ) )
2126 Target_Remove( vehicle );
2128 vehicle.noJumping =
true;
2129 vehicle.forceDamageFeedback =
true;
2130 vehicle.vehkilloccupantsondeath =
true;
2131 vehicle DisableAimAssist();
2135 vehicle setteam(
"neutral" );
2136 vehicle.ignoreme =
true;
2139 if( Target_isTarget( vehicle ) )
2140 Target_Remove( vehicle );
2143 vehicle waittill(
"enter_vehicle", player );
2145 vehicle setteam( player.team );
2146 vehicle.ignoreme =
false;
2151 if( !Target_isTarget( vehicle ) )
2153 if( isdefined( vehicle.targetOffset ) )
2154 Target_Set( vehicle, vehicle.targetOffset );
2156 Target_Set( vehicle, ( 0, 0, 0 ) );
2161 vehicle waittill(
"exit_vehicle", player );
2163 if( isdefined( player ) )
2175 level endon(
"game_ended" );
2176 player endon (
"death" );
2177 player endon(
"disconnect" );
2181 vehicle endon(
"death" );
2188 while( player UseButtonPressed() )
2191 if( timeUsed > 0.25 )
2205 self.perks_before_vehicle =
self GetPerks();
2211 assert( IsDefined(
self.perks_before_vehicle ) );
2212 foreach( perk
in self.perks_before_vehicle )
2214 self SetPerk( perk );