// IW6 GSC SOURCE // Generated by https://github.com/xensik/gsc-tool init() { var_0 = getentarray( "heli_start", "targetname" ); var_1 = getentarray( "heli_loop_start", "targetname" ); if ( !var_0.size && !var_1.size ) return; level.chopper = undefined; level.heli_start_nodes = getentarray( "heli_start", "targetname" ); level.heli_loop_nodes = getentarray( "heli_loop_start", "targetname" ); level.strafe_nodes = common_scripts\utility::getstructarray( "strafe_path", "targetname" ); level.heli_leave_nodes = getentarray( "heli_leave", "targetname" ); level.heli_crash_nodes = getentarray( "heli_crash_start", "targetname" ); level.heli_missile_rof = 5; level.heli_maxhealth = 2000; level.heli_debug = 0; level.heli_targeting_delay = 0.5; level.heli_turretreloadtime = 1.5; level.heli_turretclipsize = 60; level.heli_visual_range = 3700; level.heli_target_spawnprotection = 5; level.heli_target_recognition = 0.5; level.heli_missile_friendlycare = 256; level.heli_missile_target_cone = 0.3; level.heli_armor_bulletdamage = 0.3; level.heli_attract_strength = 1000; level.heli_attract_range = 4096; level.heli_angle_offset = 90; level.heli_forced_wait = 0; level precachehelicoptersounds(); level.chopper_fx["damage"]["light_smoke"] = loadfx( "fx/smoke/smoke_trail_white_heli_emitter" ); level.chopper_fx["damage"]["heavy_smoke"] = loadfx( "vfx/gameplay/mp/killstreaks/vfx_helo_damage" ); level.chopper_fx["damage"]["on_fire"] = loadfx( "fx/fire/fire_smoke_trail_L_emitter" ); level.chopper_fx["light"]["left"] = loadfx( "vfx/gameplay/mp/killstreaks/vfx_acraft_light_wingtip_green" ); level.chopper_fx["light"]["right"] = loadfx( "vfx/gameplay/mp/killstreaks/vfx_acraft_light_wingtip_red" ); level.chopper_fx["light"]["belly"] = loadfx( "vfx/gameplay/mp/killstreaks/vfx_acraft_light_red_blink" ); level.chopper_fx["light"]["tail"] = loadfx( "vfx/gameplay/mp/killstreaks/vfx_acraft_light_white_blink" ); level.chopper_fx["explode"]["medium"] = loadfx( "fx/explosions/aerial_explosion" ); level.chopper_fx["explode"]["large"] = loadfx( "fx/explosions/helicopter_explosion_secondary_small" ); level.chopper_fx["smoke"]["trail"] = loadfx( "fx/smoke/smoke_trail_white_heli" ); level.chopper_fx["explode"]["death"] = []; level.chopper_fx["explode"]["death"]["apache"] = loadfx( "vfx/gameplay/explosions/vehicle/apch_mp/vfx_x_mpapc_primary" ); level.chopper_fx["explode"]["air_death"]["apache"] = loadfx( "vfx/gameplay/explosions/vehicle/apch_mp/vfx_x_mpapc_primary" ); level.lightfxfunc["apache"] = ::defaultlightfx; level.chopper_fx["explode"]["death"]["cobra"] = loadfx( "vfx/gameplay/explosions/vehicle/hind_mp/vfx_x_mphnd_primary" ); level.chopper_fx["explode"]["air_death"]["cobra"] = loadfx( "vfx/gameplay/explosions/vehicle/hind_mp/vfx_x_mphnd_primary" ); level.lightfxfunc["cobra"] = ::defaultlightfx; level.chopper_fx["explode"]["death"]["littlebird"] = loadfx( "vfx/gameplay/explosions/vehicle/aas_mp/vfx_x_mpaas_primary" ); level.chopper_fx["explode"]["air_death"]["littlebird"] = loadfx( "vfx/gameplay/explosions/vehicle/aas_mp/vfx_x_mpaas_primary" ); level.lightfxfunc["littlebird"] = ::defaultlightfx; level._effect["vehicle_flares"] = loadfx( "fx/misc/flares_cobra" ); level.chopper_fx["fire"]["trail"]["medium"] = loadfx( "fx/fire/fire_smoke_trail_L_emitter" ); level.killstreakfuncs["helicopter"] = ::usehelicopter; level.helidialog["tracking"][0] = "ac130_fco_moreenemy"; level.helidialog["tracking"][1] = "ac130_fco_getthatguy"; level.helidialog["tracking"][2] = "ac130_fco_guyrunnin"; level.helidialog["tracking"][3] = "ac130_fco_gotarunner"; level.helidialog["tracking"][4] = "ac130_fco_personnelthere"; level.helidialog["tracking"][5] = "ac130_fco_rightthere"; level.helidialog["tracking"][6] = "ac130_fco_tracking"; level.helidialog["locked"][0] = "ac130_fco_lightemup"; level.helidialog["locked"][1] = "ac130_fco_takehimout"; level.helidialog["locked"][2] = "ac130_fco_nailthoseguys"; level.lasthelidialogtime = 0; level.heliconfigs = []; var_2 = spawnstruct(); var_2.xppopup = "destroyed_helicopter"; var_2.callout = "callout_destroyed_helicopter"; var_2.samdamagescale = 0.09; var_2.enginevfxtag = "tag_engine_left"; level.heliconfigs["helicopter"] = var_2; var_2 = spawnstruct(); var_2.xppopup = "destroyed_little_bird"; var_2.callout = "callout_destroyed_little_bird"; var_2.samdamagescale = 0.09; var_2.enginevfxtag = "tag_engine_left"; level.heliconfigs["airdrop"] = var_2; var_2 = spawnstruct(); var_2.xppopup = "destroyed_pavelow"; var_2.callout = "callout_destroyed_helicopter_flares"; var_2.samdamagescale = 0.07; var_2.enginevfxtag = "tag_engine_left"; level.heliconfigs["flares"] = var_2; maps\mp\_utility::queuecreate( "helicopter" ); } makehelitype( var_0, var_1, var_2 ) { level.chopper_fx["explode"]["death"][var_0] = loadfx( var_1 ); level.lightfxfunc[var_0] = var_2; } addairexplosion( var_0, var_1 ) { level.chopper_fx["explode"]["air_death"][var_0] = loadfx( var_1 ); } defaultlightfx() { playfxontag( level.chopper_fx["light"]["left"], self, "tag_light_L_wing" ); wait 0.05; playfxontag( level.chopper_fx["light"]["right"], self, "tag_light_R_wing" ); wait 0.05; playfxontag( level.chopper_fx["light"]["belly"], self, "tag_light_belly" ); wait 0.05; playfxontag( level.chopper_fx["light"]["tail"], self, "tag_light_tail" ); } usehelicopter( var_0, var_1 ) { return tryusehelicopter( var_0, "helicopter" ); } tryusehelicopter( var_0, var_1 ) { var_2 = 1; if ( isdefined( level.chopper ) ) var_3 = 1; else var_3 = 0; if ( isdefined( level.chopper ) && var_3 ) { self iprintlnbold( &"KILLSTREAKS_HELI_IN_QUEUE" ); if ( isdefined( var_1 ) && var_1 != "helicopter" ) var_4 = "helicopter_" + var_1; else var_4 = "helicopter"; thread maps\mp\killstreaks\_killstreaks::updatekillstreaks(); var_5 = spawn( "script_origin", ( 0, 0, 0 ) ); var_5 hide(); var_5 thread deleteonentnotify( self, "disconnect" ); var_5.player = self; var_5.lifeid = var_0; var_5.helitype = var_1; var_5.streakname = var_4; maps\mp\_utility::queueadd( "helicopter", var_5 ); var_6 = undefined; if ( !self hasweapon( common_scripts\utility::getlastweapon() ) ) var_6 = maps\mp\killstreaks\_killstreaks::getfirstprimaryweapon(); else var_6 = common_scripts\utility::getlastweapon(); var_7 = maps\mp\_utility::getkillstreakweapon( "helicopter" ); thread maps\mp\killstreaks\_killstreaks::waittakekillstreakweapon( var_7, var_6 ); return 0; } else if ( maps\mp\_utility::currentactivevehiclecount() >= maps\mp\_utility::maxvehiclesallowed() || level.fauxvehiclecount + var_2 >= maps\mp\_utility::maxvehiclesallowed() ) { self iprintlnbold( &"KILLSTREAKS_TOO_MANY_VEHICLES" ); return 0; } var_2 = 1; starthelicopter( var_0, var_1 ); return 1; } deleteonentnotify( var_0, var_1 ) { self endon( "death" ); var_0 waittill( var_1 ); self delete(); } starthelicopter( var_0, var_1 ) { maps\mp\_utility::incrementfauxvehiclecount(); var_2 = undefined; if ( !isdefined( var_1 ) ) var_1 = ""; var_3 = "helicopter"; var_4 = self.pers["team"]; var_2 = level.heli_start_nodes[randomint( level.heli_start_nodes.size )]; maps\mp\_matchdata::logkillstreakevent( var_3, self.origin ); thread heli_think( var_0, self, var_2, self.pers["team"], var_1 ); } precachehelicoptersounds() { level.heli_sound["allies"]["hit"] = "cobra_helicopter_hit"; level.heli_sound["allies"]["hitsecondary"] = "cobra_helicopter_secondary_exp"; level.heli_sound["allies"]["damaged"] = "cobra_helicopter_damaged"; level.heli_sound["allies"]["spinloop"] = "cobra_helicopter_dying_loop"; level.heli_sound["allies"]["spinstart"] = "cobra_helicopter_dying_layer"; level.heli_sound["allies"]["crash"] = "exp_helicopter_fuel"; level.heli_sound["allies"]["missilefire"] = "weap_cobra_missile_fire"; level.heli_sound["axis"]["hit"] = "cobra_helicopter_hit"; level.heli_sound["axis"]["hitsecondary"] = "cobra_helicopter_secondary_exp"; level.heli_sound["axis"]["damaged"] = "cobra_helicopter_damaged"; level.heli_sound["axis"]["spinloop"] = "cobra_helicopter_dying_loop"; level.heli_sound["axis"]["spinstart"] = "cobra_helicopter_dying_layer"; level.heli_sound["axis"]["crash"] = "exp_helicopter_fuel"; level.heli_sound["axis"]["missilefire"] = "weap_cobra_missile_fire"; } heli_getteamforsoundclip() { var_0 = self.team; if ( level.multiteambased ) var_0 = "axis"; return var_0; } spawn_helicopter( var_0, var_1, var_2, var_3, var_4 ) { var_5 = spawnhelicopter( var_0, var_1, var_2, var_3, var_4 ); if ( !isdefined( var_5 ) ) return undefined; if ( var_4 == "vehicle_battle_hind" ) var_5.heli_type = "cobra"; else var_5.heli_type = level.heli_types[var_4]; var_5 thread [[ level.lightfxfunc[var_5.heli_type] ]](); var_5 addtohelilist(); var_5.zoffset = ( 0, 0, var_5 gettagorigin( "tag_origin" )[2] - var_5 gettagorigin( "tag_ground" )[2] ); var_5.attractor = missile_createattractorent( var_5, level.heli_attract_strength, level.heli_attract_range ); return var_5; } helidialog( var_0 ) { if ( gettime() - level.lasthelidialogtime < 6000 ) return; level.lasthelidialogtime = gettime(); var_1 = randomint( level.helidialog[var_0].size ); var_2 = level.helidialog[var_0][var_1]; var_3 = maps\mp\gametypes\_teams::getteamvoiceprefix( self.team ) + var_2; self playlocalsound( var_3 ); } updateareanodes( var_0 ) { var_1 = []; foreach ( var_3 in var_0 ) { var_3.validplayers = []; var_3.nodescore = 0; } foreach ( var_6 in level.players ) { if ( !isalive( var_6 ) ) continue; if ( var_6.team == self.team ) continue; foreach ( var_3 in var_0 ) { if ( distancesquared( var_6.origin, var_3.origin ) > 1048576 ) continue; var_3.validplayers[var_3.validplayers.size] = var_6; } } var_10 = var_0[0]; foreach ( var_3 in var_0 ) { var_12 = getent( var_3.target, "targetname" ); foreach ( var_6 in var_3.validplayers ) { var_3.nodescore = var_3.nodescore + 1; if ( bullettracepassed( var_6.origin + ( 0, 0, 32 ), var_12.origin, 0, var_6 ) ) var_3.nodescore = var_3.nodescore + 3; } if ( var_3.nodescore > var_10.nodescore ) var_10 = var_3; } return getent( var_10.target, "targetname" ); } heli_think( var_0, var_1, var_2, var_3, var_4 ) { var_5 = var_2.origin; var_6 = var_2.angles; var_7 = "cobra_mp"; var_8 = "vehicle_battle_hind"; var_9 = spawn_helicopter( var_1, var_5, var_6, var_7, var_8 ); if ( !isdefined( var_9 ) ) return; level.chopper = var_9; if ( var_3 == "allies" ) level.allieschopper = var_9; else level.axischopper = var_9; var_9.helitype = var_4; var_9.lifeid = var_0; var_9.team = var_3; var_9.pers["team"] = var_3; var_9.owner = var_1; var_9 setotherent( var_1 ); var_9.startnode = var_2; var_9.maxhealth = level.heli_maxhealth; var_9.targeting_delay = level.heli_targeting_delay; var_9.primarytarget = undefined; var_9.secondarytarget = undefined; var_9.attacker = undefined; var_9.currentstate = "ok"; var_9 common_scripts\utility::make_entity_sentient_mp( var_3 ); var_9.empgrenaded = 0; if ( var_4 == "flares" || var_4 == "minigun" ) var_9 thread maps\mp\killstreaks\_flares::flares_monitor( 1 ); var_9 thread heli_leave_on_disconnect( var_1 ); var_9 thread heli_leave_on_changeteams( var_1 ); var_9 thread heli_leave_on_gameended( var_1 ); var_9 thread heli_damage_monitor( var_4 ); var_9 thread heli_watchempdamage(); var_9 thread heli_watchdeath(); var_9 thread heli_existance(); var_9 endon( "helicopter_done" ); var_9 endon( "crashing" ); var_9 endon( "leaving" ); var_9 endon( "death" ); var_10 = getentarray( "heli_attack_area", "targetname" ); var_11 = undefined; var_11 = level.heli_loop_nodes[randomint( level.heli_loop_nodes.size )]; var_9 heli_fly_simple_path( var_2 ); var_9 thread heli_targeting(); var_9 thread heli_leave_on_timeout( 60.0 ); var_9 thread heli_fly_loop_path( var_11 ); } heli_existance() { var_0 = self getentitynumber(); common_scripts\utility::waittill_any( "death", "crashing", "leaving" ); removefromhelilist( var_0 ); self notify( "helicopter_done" ); self notify( "helicopter_removed" ); var_1 = undefined; var_2 = maps\mp\_utility::queueremovefirst( "helicopter" ); if ( !isdefined( var_2 ) ) level.chopper = undefined; else { var_1 = var_2.player; var_3 = var_2.lifeid; var_4 = var_2.streakname; var_5 = var_2.helitype; var_2 delete(); if ( isdefined( var_1 ) && ( var_1.sessionstate == "playing" || var_1.sessionstate == "dead" ) ) { var_1 maps\mp\killstreaks\_killstreaks::usedkillstreak( var_4, 1 ); var_1 starthelicopter( var_3, var_5 ); return; } level.chopper = undefined; } } heli_targeting() { self notify( "heli_targeting" ); self endon( "heli_targeting" ); self endon( "death" ); self endon( "helicopter_done" ); for (;;) { var_0 = []; self.primarytarget = undefined; self.secondarytarget = undefined; foreach ( var_2 in level.characters ) { wait 0.05; if ( !cantarget_turret( var_2 ) ) continue; var_0[var_0.size] = var_2; } if ( var_0.size ) { for ( var_4 = getbestprimarytarget( var_0 ); !isdefined( var_4 ); var_4 = getbestprimarytarget( var_0 ) ) wait 0.05; self.primarytarget = var_4; self notify( "primary acquired" ); } if ( isdefined( self.primarytarget ) ) { fireontarget( self.primarytarget ); continue; } wait 0.25; } } cantarget_turret( var_0 ) { var_1 = 1; if ( !isalive( var_0 ) || isdefined( var_0.sessionstate ) && var_0.sessionstate != "playing" ) return 0; if ( self.helitype == "remote_mortar" ) { if ( var_0 sightconetrace( self.origin, self ) < 1 ) return 0; } if ( distance( var_0.origin, self.origin ) > level.heli_visual_range ) return 0; if ( !self.owner maps\mp\_utility::isenemy( var_0 ) ) return 0; if ( isdefined( var_0.spawntime ) && ( gettime() - var_0.spawntime ) / 1000 <= 5 ) return 0; if ( var_0 maps\mp\_utility::_hasperk( "specialty_blindeye" ) ) return 0; var_2 = self.origin + ( 0, 0, -160 ); var_3 = anglestoforward( self.angles ); var_4 = var_2 + 144 * var_3; if ( var_0 sightconetrace( var_4, self ) < level.heli_target_recognition ) return 0; return var_1; } getbestprimarytarget( var_0 ) { foreach ( var_2 in var_0 ) { if ( !isdefined( var_2 ) ) continue; update_player_threat( var_2 ); } var_4 = 0; var_5 = undefined; var_6 = getentarray( "minimap_corner", "targetname" ); foreach ( var_2 in var_0 ) { if ( !isdefined( var_2 ) ) continue; if ( var_6.size == 2 ) { var_8 = var_6[0].origin; var_9 = var_6[0].origin; if ( var_6[1].origin[0] > var_9[0] ) var_9 = ( var_6[1].origin[0], var_9[1], var_9[2] ); else var_8 = ( var_6[1].origin[0], var_8[1], var_8[2] ); if ( var_6[1].origin[1] > var_9[1] ) var_9 = ( var_9[0], var_6[1].origin[1], var_9[2] ); else var_8 = ( var_8[0], var_6[1].origin[1], var_8[2] ); if ( var_2.origin[0] < var_8[0] || var_2.origin[0] > var_9[0] || var_2.origin[1] < var_8[1] || var_2.origin[1] > var_9[1] ) continue; } if ( var_2.threatlevel < var_4 ) continue; if ( !bullettracepassed( var_2.origin + ( 0, 0, 32 ), self.origin, 0, self ) ) { wait 0.05; continue; } var_4 = var_2.threatlevel; var_5 = var_2; } return var_5; } update_player_threat( var_0 ) { var_0.threatlevel = 0; var_1 = distance( var_0.origin, self.origin ); var_0.threatlevel = var_0.threatlevel + ( level.heli_visual_range - var_1 ) / level.heli_visual_range * 100; if ( isdefined( self.attacker ) && var_0 == self.attacker ) var_0.threatlevel = var_0.threatlevel + 100; if ( isplayer( var_0 ) ) var_0.threatlevel = var_0.threatlevel + var_0.score * 4; if ( isdefined( var_0.antithreat ) ) var_0.threatlevel = var_0.threatlevel - var_0.antithreat; if ( var_0.threatlevel <= 0 ) var_0.threatlevel = 1; } heli_reset() { self cleartargetyaw(); self cleargoalyaw(); self vehicle_setspeed( 80, 35 ); self setyawspeed( 75, 45, 45 ); self setmaxpitchroll( 30, 30 ); self setneargoalnotifydist( 256 ); self setturningability( 0.9 ); } addrecentdamage( var_0 ) { self endon( "death" ); self.recentdamageamount = self.recentdamageamount + var_0; wait 4.0; self.recentdamageamount = self.recentdamageamount - var_0; } modifydamage( var_0, var_1, var_2, var_3 ) { if ( isdefined( var_0 ) ) { if ( isdefined( self.owner ) && var_0 == self.owner && self.streakname == "heli_sniper" || isdefined( var_0.class ) && var_0.class == "worldspawn" || var_0 == self ) return -1; } if ( isdefined( level.ishorde ) && level.ishorde && isdefined( self.streakname ) && self.streakname == "heli_sniper" ) return -1; var_4 = var_3; var_4 = maps\mp\gametypes\_damage::handlemissiledamage( var_1, var_2, var_4 ); var_4 = maps\mp\gametypes\_damage::handlegrenadedamage( var_1, var_2, var_4 ); var_4 = maps\mp\gametypes\_damage::handleapdamage( var_1, var_2, var_4, var_0 ); thread addrecentdamage( var_4 ); self notify( "heli_damage_fx" ); return var_4; } handledeathdamage( var_0, var_1, var_2, var_3 ) { if ( isdefined( var_0 ) ) { var_4 = level.heliconfigs[self.streakname]; var_5 = maps\mp\gametypes\_damage::onkillstreakkilled( var_0, var_1, var_2, var_3, var_4.xppopup, var_4.destroyedvo, var_4.callout ); if ( var_5 ) { var_0 notify( "destroyed_helicopter" ); self.killingattacker = var_0; } if ( var_1 == "heli_pilot_turret_mp" ) var_0 maps\mp\gametypes\_missions::processchallenge( "ch_enemy_down" ); maps\mp\gametypes\_missions::checkaachallenges( var_0, self, var_1 ); } } heli_damage_monitor( var_0, var_1 ) { self endon( "crashing" ); self endon( "leaving" ); self.streakname = var_0; self.recentdamageamount = 0; thread heli_health(); maps\mp\gametypes\_damage::monitordamage( self.maxhealth, "helicopter", ::handledeathdamage, ::modifydamage, 1, var_1 ); } heli_watchempdamage() { self endon( "death" ); self endon( "leaving" ); self endon( "crashing" ); self.owner endon( "disconnect" ); level endon( "game_ended" ); for (;;) { self waittill( "emp_damage", var_0, var_1 ); self.empgrenaded = 1; if ( isdefined( self.mgturretleft ) ) self.mgturretleft notify( "stop_shooting" ); if ( isdefined( self.mgturretright ) ) self.mgturretright notify( "stop_shooting" ); wait( var_1 ); self.empgrenaded = 0; if ( isdefined( self.mgturretleft ) ) self.mgturretleft notify( "turretstatechange" ); if ( isdefined( self.mgturretright ) ) self.mgturretright notify( "turretstatechange" ); } } heli_health() { self endon( "leaving" ); self endon( "crashing" ); self.currentstate = "ok"; self.laststate = "ok"; self setdamagestage( 3 ); var_0 = 3; self setdamagestage( var_0 ); var_1 = level.heliconfigs[self.streakname]; for (;;) { self waittill( "heli_damage_fx" ); if ( var_0 > 0 && self.damagetaken >= self.maxhealth ) { var_0 = 0; self setdamagestage( var_0 ); stopfxontag( level.chopper_fx["damage"]["heavy_smoke"], self, var_1.enginevfxtag ); self notify( "death" ); break; } else { if ( var_0 > 1 && self.damagetaken >= self.maxhealth * 0.66 ) { var_0 = 1; self setdamagestage( var_0 ); self.currentstate = "heavy smoke"; stopfxontag( level.chopper_fx["damage"]["light_smoke"], self, var_1.enginevfxtag ); playfxontag( level.chopper_fx["damage"]["heavy_smoke"], self, var_1.enginevfxtag ); continue; } if ( var_0 > 2 && self.damagetaken >= self.maxhealth * 0.33 ) { var_0 = 2; self setdamagestage( var_0 ); self.currentstate = "light smoke"; playfxontag( level.chopper_fx["damage"]["light_smoke"], self, var_1.enginevfxtag ); } } } } heli_watchdeath() { level endon( "game_ended" ); self endon( "gone" ); self waittill( "death" ); if ( isdefined( self.largeprojectiledamage ) && self.largeprojectiledamage ) thread heli_explode( 1 ); else { var_0 = level.heliconfigs[self.streakname]; playfxontag( level.chopper_fx["damage"]["on_fire"], self, var_0.enginevfxtag ); thread heli_crash(); } } heli_crash() { self notify( "crashing" ); self clearlookatent(); var_0 = level.heli_crash_nodes[randomint( level.heli_crash_nodes.size )]; if ( isdefined( self.mgturretleft ) ) self.mgturretleft notify( "stop_shooting" ); if ( isdefined( self.mgturretright ) ) self.mgturretright notify( "stop_shooting" ); thread heli_spin( 180 ); thread heli_secondary_explosions(); heli_fly_simple_path( var_0 ); thread heli_explode(); } heli_secondary_explosions() { var_0 = heli_getteamforsoundclip(); var_1 = level.heliconfigs[self.streakname]; playfxontag( level.chopper_fx["explode"]["large"], self, var_1.enginevfxtag ); self playsound( level.heli_sound[var_0]["hitsecondary"] ); wait 3.0; if ( !isdefined( self ) ) return; playfxontag( level.chopper_fx["explode"]["large"], self, var_1.enginevfxtag ); self playsound( level.heli_sound[var_0]["hitsecondary"] ); } heli_spin( var_0 ) { self endon( "death" ); var_1 = heli_getteamforsoundclip(); self playsound( level.heli_sound[var_1]["hit"] ); thread spinsoundshortly(); self setyawspeed( var_0, var_0, var_0 ); while ( isdefined( self ) ) { self settargetyaw( self.angles[1] + var_0 * 0.9 ); wait 1; } } spinsoundshortly() { self endon( "death" ); wait 0.25; var_0 = heli_getteamforsoundclip(); self stoploopsound(); wait 0.05; self playloopsound( level.heli_sound[var_0]["spinloop"] ); wait 0.05; self playloopsound( level.heli_sound[var_0]["spinstart"] ); } heli_explode( var_0 ) { self notify( "death" ); if ( isdefined( var_0 ) && isdefined( level.chopper_fx["explode"]["air_death"][self.heli_type] ) ) { var_1 = self gettagangles( "tag_deathfx" ); playfx( level.chopper_fx["explode"]["air_death"][self.heli_type], self gettagorigin( "tag_deathfx" ), anglestoforward( var_1 ), anglestoup( var_1 ) ); } else { var_2 = self.origin; var_3 = self.origin + ( 0, 0, 1 ) - self.origin; playfx( level.chopper_fx["explode"]["death"][self.heli_type], var_2, var_3 ); } var_4 = heli_getteamforsoundclip(); self playsound( level.heli_sound[var_4]["crash"] ); wait 0.05; if ( isdefined( self.killcament ) ) self.killcament delete(); maps\mp\_utility::decrementfauxvehiclecount(); self delete(); } check_owner() { if ( !isdefined( self.owner ) || !isdefined( self.owner.pers["team"] ) || self.owner.pers["team"] != self.team ) { thread heli_leave(); return 0; } return 1; } heli_leave_on_disconnect( var_0 ) { self endon( "death" ); self endon( "helicopter_done" ); var_0 waittill( "disconnect" ); thread heli_leave(); } heli_leave_on_changeteams( var_0 ) { self endon( "death" ); self endon( "helicopter_done" ); if ( maps\mp\_utility::bot_is_fireteam_mode() ) return; var_0 common_scripts\utility::waittill_any( "joined_team", "joined_spectators" ); thread heli_leave(); } heli_leave_on_spawned( var_0 ) { self endon( "death" ); self endon( "helicopter_done" ); var_0 waittill( "spawned" ); thread heli_leave(); } heli_leave_on_gameended( var_0 ) { self endon( "death" ); self endon( "helicopter_done" ); level waittill( "game_ended" ); thread heli_leave(); } heli_leave_on_timeout( var_0 ) { self endon( "death" ); self endon( "helicopter_done" ); maps\mp\gametypes\_hostmigration::waitlongdurationwithhostmigrationpause( var_0 ); thread heli_leave(); } fireontarget( var_0 ) { self endon( "death" ); self endon( "crashing" ); self endon( "leaving" ); var_1 = 15; var_2 = 0; var_3 = 0; foreach ( var_5 in level.heli_loop_nodes ) { var_2++; var_3 = var_3 + var_5.origin[2]; } var_7 = var_3 / var_2; self notify( "newTarget" ); if ( isdefined( self.secondarytarget ) && self.secondarytarget.damagetaken < self.secondarytarget.maxhealth ) return; if ( isdefined( self.isperformingmaneuver ) && self.isperformingmaneuver ) return; var_8 = self.primarytarget; var_8.antithreat = 0; var_9 = self.primarytarget.origin * ( 1, 1, 0 ); var_10 = self.origin * ( 0, 0, 1 ); var_11 = var_9 + var_10; var_12 = distance2d( self.origin, var_8.origin ); if ( var_12 < 1000 ) var_1 = 600; var_13 = anglestoforward( var_8.angles ); var_13 = var_13 * ( 1, 1, 0 ); var_14 = var_11 + var_1 * var_13; var_15 = var_14 - var_11; var_16 = vectortoangles( var_15 ); var_16 = var_16 * ( 1, 1, 0 ); thread attackgroundtarget( var_8 ); self vehicle_setspeed( 80 ); if ( distance2d( self.origin, var_14 ) < 1000 ) var_14 = var_14 * 1.5; var_14 = var_14 * ( 1, 1, 0 ); var_14 = var_14 + ( 0, 0, var_7 ); _setvehgoalpos( var_14, 1, 1 ); self waittill( "near_goal" ); if ( !isdefined( var_8 ) || !isalive( var_8 ) ) return; self setlookatent( var_8 ); thread isfacing( 10, var_8 ); common_scripts\utility::waittill_any_timeout( 4, "facing" ); if ( !isdefined( var_8 ) || !isalive( var_8 ) ) return; self clearlookatent(); var_17 = var_11 + var_1 * anglestoforward( var_16 ); self setmaxpitchroll( 40, 30 ); _setvehgoalpos( var_17, 1, 1 ); self setmaxpitchroll( 30, 30 ); if ( isdefined( var_8 ) && isalive( var_8 ) ) { if ( isdefined( var_8.antithreat ) ) var_8.antithreat = var_8.antithreat + 100; else var_8.antithreat = 100; } common_scripts\utility::waittill_any_timeout( 3, "near_goal" ); } attackgroundtarget( var_0 ) { self notify( "attackGroundTarget" ); self endon( "attackGroundTarget" ); self stoploopsound(); self.isattacking = 1; self setturrettargetent( var_0 ); waitontargetordeath( var_0, 3.0 ); if ( !isalive( var_0 ) ) self.isattacking = 0; else { var_1 = distance2dsquared( self.origin, var_0.origin ); if ( var_1 < 640000 ) { thread dropbombs( var_0 ); self.isattacking = 0; return; } else { if ( checkisfacing( 50, var_0 ) && common_scripts\utility::cointoss() ) { thread firemissile( var_0 ); self.isattacking = 0; return; return; } var_2 = weaponfiretime( "cobra_20mm_mp" ); var_3 = 0; var_4 = 0; for ( var_5 = 0; var_5 < level.heli_turretclipsize; var_5++ ) { if ( !isdefined( self ) ) break; if ( self.empgrenaded ) break; if ( !isdefined( var_0 ) ) break; if ( !isalive( var_0 ) ) break; if ( self.damagetaken >= self.maxhealth ) continue; if ( !checkisfacing( 55, var_0 ) ) { self stoploopsound(); var_4 = 0; wait( var_2 ); var_5--; continue; } if ( var_5 < level.heli_turretclipsize - 1 ) wait( var_2 ); if ( !isdefined( var_0 ) || !isalive( var_0 ) ) break; if ( !var_4 ) { self playloopsound( "weap_hind_20mm_fire_npc" ); var_4 = 1; } self setvehweapon( "cobra_20mm_mp" ); self fireweapon( "tag_flash", var_0 ); } if ( !isdefined( self ) ) return; self stoploopsound(); var_4 = 0; self.isattacking = 0; } } } checkisfacing( var_0, var_1 ) { self endon( "death" ); self endon( "leaving" ); if ( !isdefined( var_0 ) ) var_0 = 10; var_2 = anglestoforward( self.angles ); var_3 = var_1.origin - self.origin; var_2 = var_2 * ( 1, 1, 0 ); var_3 = var_3 * ( 1, 1, 0 ); var_3 = vectornormalize( var_3 ); var_2 = vectornormalize( var_2 ); var_4 = vectordot( var_3, var_2 ); var_5 = cos( var_0 ); if ( var_4 >= var_5 ) return 1; else return 0; } isfacing( var_0, var_1 ) { self endon( "death" ); self endon( "leaving" ); if ( !isdefined( var_0 ) ) var_0 = 10; while ( isalive( var_1 ) ) { var_2 = anglestoforward( self.angles ); var_3 = var_1.origin - self.origin; var_2 = var_2 * ( 1, 1, 0 ); var_3 = var_3 * ( 1, 1, 0 ); var_3 = vectornormalize( var_3 ); var_2 = vectornormalize( var_2 ); var_4 = vectordot( var_3, var_2 ); var_5 = cos( var_0 ); if ( var_4 >= var_5 ) { self notify( "facing" ); break; } wait 0.1; } } waitontargetordeath( var_0, var_1 ) { self endon( "death" ); self endon( "helicopter_done" ); var_0 endon( "death" ); var_0 endon( "disconnect" ); common_scripts\utility::waittill_notify_or_timeout( "turret_on_target", var_1 ); } firemissile( var_0 ) { self endon( "death" ); self endon( "crashing" ); self endon( "leaving" ); if ( level.ps3 ) var_1 = 1; else var_1 = 2; for ( var_2 = 0; var_2 < var_1; var_2++ ) { if ( !isdefined( var_0 ) ) return; if ( common_scripts\utility::cointoss() ) { var_3 = magicbullet( "hind_missile_mp", self gettagorigin( "tag_missile_right" ) - ( 0, 0, 64 ), var_0.origin, self.owner ); var_3.vehicle_fired_from = self; } else { var_3 = magicbullet( "hind_missile_mp", self gettagorigin( "tag_missile_left" ) - ( 0, 0, 64 ), var_0.origin, self.owner ); var_3.vehicle_fired_from = self; } var_3 missile_settargetent( var_0 ); var_3.owner = self; var_3 missile_setflightmodedirect(); wait( 0.5 / var_1 ); } } dropbombs( var_0 ) { self endon( "death" ); self endon( "crashing" ); self endon( "leaving" ); if ( !isdefined( var_0 ) ) return; for ( var_1 = 0; var_1 < randomintrange( 2, 5 ); var_1++ ) { if ( common_scripts\utility::cointoss() ) { var_2 = magicbullet( "hind_bomb_mp", self gettagorigin( "tag_missile_left" ) - ( 0, 0, 45 ), var_0.origin, self.owner ); var_2.vehicle_fired_from = self; } else { var_2 = magicbullet( "hind_bomb_mp", self gettagorigin( "tag_missile_right" ) - ( 0, 0, 45 ), var_0.origin, self.owner ); var_2.vehicle_fired_from = self; } wait( randomfloatrange( 0.35, 0.65 ) ); } } getoriginoffsets( var_0 ) { var_1 = self.origin; var_2 = var_0.origin; var_3 = 0; var_4 = 40; var_5 = ( 0, 0, -196 ); for ( var_6 = bullettrace( var_1 + var_5, var_2 + var_5, 0, self ); distancesquared( var_6["position"], var_2 + var_5 ) > 10 && var_3 < var_4; var_6 = bullettrace( var_1 + var_5, var_2 + var_5, 0, self ) ) { if ( var_1[2] < var_2[2] ) var_1 = var_1 + ( 0, 0, 128 ); else if ( var_1[2] > var_2[2] ) var_2 = var_2 + ( 0, 0, 128 ); else { var_1 = var_1 + ( 0, 0, 128 ); var_2 = var_2 + ( 0, 0, 128 ); } var_3++; } var_7 = []; var_7["start"] = var_1; var_7["end"] = var_2; return var_7; } traveltonode( var_0 ) { var_1 = getoriginoffsets( var_0 ); if ( var_1["start"] != self.origin ) { self vehicle_setspeed( 75, 35 ); _setvehgoalpos( var_1["start"] + ( 0, 0, 30 ), 0 ); self setgoalyaw( var_0.angles[1] + level.heli_angle_offset ); self waittill( "goal" ); } if ( var_1["end"] != var_0.origin ) { if ( isdefined( var_0.script_airspeed ) && isdefined( var_0.script_accel ) ) { var_2 = var_0.script_airspeed; var_3 = var_0.script_accel; } else { var_2 = 30 + randomint( 20 ); var_3 = 15 + randomint( 15 ); } self vehicle_setspeed( 75, 35 ); _setvehgoalpos( var_1["end"] + ( 0, 0, 30 ), 0 ); self setgoalyaw( var_0.angles[1] + level.heli_angle_offset ); self waittill( "goal" ); } } _setvehgoalpos( var_0, var_1, var_2 ) { if ( !isdefined( var_1 ) ) var_1 = 0; var_2 = 0; if ( var_2 ) thread _setvehgoalposadheretomesh( var_0, var_1 ); else self setvehgoalpos( var_0, var_1 ); } _setvehgoalposadheretomesh( var_0, var_1 ) { self endon( "death" ); self endon( "leaving" ); self endon( "crashing" ); var_2 = var_0; for (;;) { if ( !isdefined( self ) ) return; if ( common_scripts\utility::distance_2d_squared( self.origin, var_2 ) < 65536 ) { self setvehgoalpos( var_2, var_1 ); break; } var_3 = vectortoangles( var_2 - self.origin ); var_4 = anglestoforward( var_3 ); var_5 = self.origin + var_4 * ( 1, 1, 0 ) * 250; var_6 = ( 0, 0, 2500 ); var_7 = var_5 + ( maps\mp\_utility::gethelipilotmeshoffset() + var_6 ); var_8 = var_5 + ( maps\mp\_utility::gethelipilotmeshoffset() - var_6 ); var_9 = bullettrace( var_7, var_8, 0, self, 0, 0, 1 ); var_10 = var_9; if ( isdefined( var_9["entity"] ) && var_9["entity"] == self && var_9["normal"][2] > 0.1 ) { var_11 = var_9["position"][2] - 4400; var_12 = var_11 - self.origin[2]; if ( var_12 > 256 ) { var_9["position"] = var_9["position"] * ( 1, 1, 0 ); var_9["position"] = var_9["position"] + ( 0, 0, self.origin[2] + 256 ); } else if ( var_12 < -256 ) { var_9["position"] = var_9["position"] * ( 1, 1, 0 ); var_9["position"] = var_9["position"] + ( 0, 0, self.origin[2] - 256 ); } var_10 = var_9["position"] - maps\mp\_utility::gethelipilotmeshoffset() + ( 0, 0, 600 ); } else var_10 = var_2; self setvehgoalpos( var_10, 0 ); wait 0.15; } } heli_fly_simple_path( var_0 ) { self endon( "death" ); self endon( "leaving" ); self notify( "flying" ); self endon( "flying" ); heli_reset(); var_1 = var_0; while ( isdefined( var_1.target ) ) { var_2 = getent( var_1.target, "targetname" ); if ( isdefined( var_1.script_airspeed ) && isdefined( var_1.script_accel ) ) { var_3 = var_1.script_airspeed; var_4 = var_1.script_accel; } else { var_3 = 30 + randomint( 20 ); var_4 = 15 + randomint( 15 ); } if ( isdefined( self.isattacking ) && self.isattacking ) { wait 0.05; continue; } if ( isdefined( self.isperformingmaneuver ) && self.isperformingmaneuver ) { wait 0.05; continue; } self vehicle_setspeed( 75, 35 ); if ( !isdefined( var_2.target ) ) { _setvehgoalpos( var_2.origin + self.zoffset, 1 ); self waittill( "near_goal" ); } else { _setvehgoalpos( var_2.origin + self.zoffset, 0 ); self waittill( "near_goal" ); self setgoalyaw( var_2.angles[1] ); self waittillmatch( "goal" ); } var_1 = var_2; } } heli_fly_loop_path( var_0 ) { self endon( "death" ); self endon( "crashing" ); self endon( "leaving" ); self notify( "flying" ); self endon( "flying" ); heli_reset(); thread heli_loop_speed_control( var_0 ); var_1 = var_0; while ( isdefined( var_1.target ) ) { var_2 = getent( var_1.target, "targetname" ); if ( isdefined( self.isperformingmaneuver ) && self.isperformingmaneuver ) { wait 0.25; continue; } if ( isdefined( self.isattacking ) && self.isattacking ) { wait 0.1; continue; } if ( isdefined( var_1.script_airspeed ) && isdefined( var_1.script_accel ) ) { self.desired_speed = var_1.script_airspeed; self.desired_accel = var_1.script_accel; } else { self.desired_speed = 30 + randomint( 20 ); self.desired_accel = 15 + randomint( 15 ); } if ( self.helitype == "flares" ) { self.desired_speed = self.desired_speed * 0.5; self.desired_accel = self.desired_accel * 0.5; } if ( isdefined( var_2.script_delay ) && isdefined( self.primarytarget ) && !heli_is_threatened() ) { _setvehgoalpos( var_2.origin + self.zoffset, 1, 1 ); self waittill( "near_goal" ); wait( var_2.script_delay ); } else { _setvehgoalpos( var_2.origin + self.zoffset, 0, 1 ); self waittill( "near_goal" ); self setgoalyaw( var_2.angles[1] ); self waittillmatch( "goal" ); } var_1 = var_2; } } heli_loop_speed_control( var_0 ) { self endon( "death" ); self endon( "crashing" ); self endon( "leaving" ); if ( isdefined( var_0.script_airspeed ) && isdefined( var_0.script_accel ) ) { self.desired_speed = var_0.script_airspeed; self.desired_accel = var_0.script_accel; } else { self.desired_speed = 30 + randomint( 20 ); self.desired_accel = 15 + randomint( 15 ); } var_1 = 0; var_2 = 0; for (;;) { var_3 = self.desired_speed; var_4 = self.desired_accel; if ( isdefined( self.isattacking ) && self.isattacking ) { wait 0.05; continue; } if ( self.helitype != "flares" && isdefined( self.primarytarget ) && !heli_is_threatened() ) var_3 = var_3 * 0.25; if ( var_1 != var_3 || var_2 != var_4 ) { self vehicle_setspeed( 75, 35 ); var_1 = var_3; var_2 = var_4; } wait 0.05; } } heli_is_threatened() { if ( self.recentdamageamount > 50 ) return 1; if ( self.currentstate == "heavy smoke" ) return 1; return 0; } heli_fly_well( var_0 ) { self notify( "flying" ); self endon( "flying" ); self endon( "death" ); self endon( "crashing" ); self endon( "leaving" ); for (;;) { if ( isdefined( self.isattacking ) && self.isattacking ) { wait 0.05; continue; } var_1 = get_best_area_attack_node( var_0 ); traveltonode( var_1 ); if ( isdefined( var_1.script_airspeed ) && isdefined( var_1.script_accel ) ) { var_2 = var_1.script_airspeed; var_3 = var_1.script_accel; } else { var_2 = 30 + randomint( 20 ); var_3 = 15 + randomint( 15 ); } self vehicle_setspeed( 75, 35 ); _setvehgoalpos( var_1.origin + self.zoffset, 1 ); self setgoalyaw( var_1.angles[1] + level.heli_angle_offset ); if ( level.heli_forced_wait != 0 ) { self waittill( "near_goal" ); wait( level.heli_forced_wait ); continue; } if ( !isdefined( var_1.script_delay ) ) { self waittill( "near_goal" ); wait( 5 + randomint( 5 ) ); continue; } self waittillmatch( "goal" ); wait( var_1.script_delay ); } } get_best_area_attack_node( var_0 ) { return updateareanodes( var_0 ); } heli_leave( var_0 ) { self notify( "leaving" ); self clearlookatent(); if ( isdefined( self.helitype ) && self.helitype == "osprey" && isdefined( self.pathgoal ) ) { _setvehgoalpos( self.pathgoal, 1 ); common_scripts\utility::waittill_any_timeout( 5, "goal" ); } if ( !isdefined( var_0 ) ) { var_1 = level.heli_leave_nodes[randomint( level.heli_leave_nodes.size )]; var_0 = var_1.origin; } var_2 = spawn( "script_origin", var_0 ); if ( isdefined( var_2 ) ) { self setlookatent( var_2 ); var_2 thread wait_and_delete( 3.0 ); } var_3 = ( var_0 - self.origin ) * 2000; heli_reset(); self vehicle_setspeed( 180, 45 ); _setvehgoalpos( var_3, 1 ); common_scripts\utility::waittill_any_timeout( 12, "goal" ); self notify( "gone" ); self notify( "death" ); wait 0.05; if ( isdefined( self.killcament ) ) self.killcament delete(); maps\mp\_utility::decrementfauxvehiclecount(); self delete(); } wait_and_delete( var_0 ) { self endon( "death" ); level endon( "game_ended" ); wait( var_0 ); self delete(); } debug_print3d( var_0, var_1, var_2, var_3, var_4 ) { if ( isdefined( level.heli_debug ) && level.heli_debug == 1.0 ) thread draw_text( var_0, var_1, var_2, var_3, var_4 ); } debug_print3d_simple( var_0, var_1, var_2, var_3 ) { if ( isdefined( level.heli_debug ) && level.heli_debug == 1.0 ) { if ( isdefined( var_3 ) ) thread draw_text( var_0, ( 0.8, 0.8, 0.8 ), var_1, var_2, var_3 ); else thread draw_text( var_0, ( 0.8, 0.8, 0.8 ), var_1, var_2, 0 ); } } debug_line( var_0, var_1, var_2, var_3 ) { if ( isdefined( level.heli_debug ) && level.heli_debug == 1.0 && !isdefined( var_3 ) ) thread draw_line( var_0, var_1, var_2 ); else if ( isdefined( level.heli_debug ) && level.heli_debug == 1.0 ) thread draw_line( var_0, var_1, var_2, var_3 ); } draw_text( var_0, var_1, var_2, var_3, var_4 ) { if ( var_4 == 0 ) { while ( isdefined( var_2 ) ) wait 0.05; } else { for ( var_5 = 0; var_5 < var_4; var_5++ ) { if ( !isdefined( var_2 ) ) break; wait 0.05; } } } draw_line( var_0, var_1, var_2, var_3 ) { if ( isdefined( var_3 ) ) { for ( var_4 = 0; var_4 < var_3; var_4++ ) wait 0.05; } else { for (;;) wait 0.05; } } addtohelilist() { level.helis[self getentitynumber()] = self; } removefromhelilist( var_0 ) { level.helis[var_0] = undefined; } addtolittlebirdlist( var_0 ) { if ( isdefined( var_0 ) && var_0 == "lbSniper" ) level.lbsniper = self; level.littlebirds[self getentitynumber()] = self; } removefromlittlebirdlistondeath( var_0 ) { var_1 = self getentitynumber(); self waittill( "death" ); if ( isdefined( var_0 ) && var_0 == "lbSniper" ) level.lbsniper = undefined; level.littlebirds[var_1] = undefined; } exceededmaxlittlebirds( var_0 ) { if ( level.littlebirds.size >= 4 || level.littlebirds.size >= 2 && var_0 == "littlebird_flock" ) return 1; else return 0; } pavelowmadeselectionvo() { self endon( "death" ); self endon( "disconnect" ); self playlocalsound( game["voice"][self.team] + "KS_hqr_pavelow" ); wait 3.5; self playlocalsound( game["voice"][self.team] + "KS_pvl_inbound" ); } lbonkilled() { self endon( "gone" ); if ( !isdefined( self ) ) return; self notify( "crashing" ); if ( isdefined( self.largeprojectiledamage ) && self.largeprojectiledamage ) common_scripts\utility::waitframe(); else { self vehicle_setspeed( 25, 5 ); thread lbspin( randomintrange( 180, 220 ) ); wait( randomfloatrange( 1.0, 2.0 ) ); } lbexplode(); } lbspin( var_0 ) { self endon( "explode" ); playfxontag( level.chopper_fx["explode"]["medium"], self, "tail_rotor_jnt" ); thread trail_fx( level.chopper_fx["smoke"]["trail"], "tail_rotor_jnt", "stop tail smoke" ); self setyawspeed( var_0, var_0, var_0 ); while ( isdefined( self ) ) { self settargetyaw( self.angles[1] + var_0 * 0.9 ); wait 1; } } lbexplode() { var_0 = self.origin + ( 0, 0, 1 ) - self.origin; var_1 = self gettagangles( "tag_deathfx" ); playfx( level.chopper_fx["explode"]["air_death"]["littlebird"], self gettagorigin( "tag_deathfx" ), anglestoforward( var_1 ), anglestoup( var_1 ) ); self playsound( "exp_helicopter_fuel" ); self notify( "explode" ); removelittlebird(); } trail_fx( var_0, var_1, var_2 ) { self notify( var_2 ); self endon( var_2 ); self endon( "death" ); for (;;) { playfxontag( var_0, self, var_1 ); wait 0.05; } } removelittlebird() { if ( isdefined( self.mgturretleft ) ) { if ( isdefined( self.mgturretleft.killcament ) ) self.mgturretleft.killcament delete(); self.mgturretleft delete(); } if ( isdefined( self.mgturretright ) ) { if ( isdefined( self.mgturretright.killcament ) ) self.mgturretright.killcament delete(); self.mgturretright delete(); } if ( isdefined( self.marker ) ) self.marker delete(); if ( isdefined( level.heli_pilot[self.team] ) && level.heli_pilot[self.team] == self ) level.heli_pilot[self.team] = undefined; maps\mp\_utility::decrementfauxvehiclecount(); self delete(); }