Results 1 to 14 of 14
  1. #1
    Arasonic's Avatar
    Join Date
    Jun 2010
    Gender
    male
    Posts
    569
    Reputation
    11
    Thanks
    115

    What happens if you combine AC130 and Attack Heli..

    This happens.
    (Excuse my bad aim )



    Add _helicopter.gsc to your killstreaks folder
    And yeah I went a bit crazy with the shaking, easy changeable
    Code:
    #include maps\mp\_utility;
    #include maps\mp\gametypes\_hud_util;
    #include common_scripts\utility;
    
    
    init()
    {
    	path_start = getentarray( "heli_start", "targetname" ); 		// start pointers, point to the actual start node on path
    	loop_start = getentarray( "heli_loop_start", "targetname" ); 	// start pointers for loop path in the map
    
    	if ( !path_start.size && !loop_start.size)
    		return;
    
    	level.heli_types = [];
    
    	precacheHelicopter( "vehicle_cobra_helicopter_fly_low", "cobra" );
    	precacheHelicopter( "vehicle_mi24p_hind_mp", "hind" );
    	precacheHelicopter( "vehicle_mi-28_mp", "mi28" );
    	precacheHelicopter( "vehicle_apache_mp", "apache" );
    	precacheHelicopter( "vehicle_pavelow", "pavelow" );
    	precacheHelicopter( "vehicle_pavelow_opfor", "pavelow" );
    	precacheHelicopter( "vehicle_little_bird_armed", "cobra" );
    	
    	precacheitem( "cobra_FFAR_mp" );
    	precacheitem( "cobra_20mm_mp" );
    	precacheitem( "cobra_player_minigun_mp" );
    	precacheitem( "heli_remote_mp" );
    	precacheVehicle( "cobra_mp" );
    	precacheVehicle( "cobra_minigun_mp" );
    	precacheVehicle( "pavelow_mp" );
    	precacheTurret( "pavelow_minigun_mp" );
    	precacheString( &"MP_CIVILIAN_AIR_TRAFFIC" );
    	
    	level.chopper = undefined;
    
    	// array of paths, each element is an array of start nodes that all leads to a single destination node
    	level.heli_start_nodes = getEntArray( "heli_start", "targetname" );
    	assertEx( level.heli_start_nodes.size, "No \"heli_start\" nodes found in map!" );
    
    	level.heli_loop_nodes = getEntArray( "heli_loop_start", "targetname" );
    	assertEx( level.heli_loop_nodes.size, "No \"heli_loop_start\" nodes found in map!" );
    
    	level.heli_leave_nodes = getEntArray( "heli_leave", "targetname" );
    	assertEx( level.heli_leave_nodes.size, "No \"heli_leave\" nodes found in map!" );
    
    	level.heli_crash_nodes = getEntArray( "heli_crash_start", "targetname" );
    	assertEx( level.heli_crash_nodes.size, "No \"heli_crash_start\" nodes found in map!" );
    	
    	level.heli_missile_rof 	= 5;	// missile rate of fire, one every this many seconds per target, could fire two at the same time to different targets
    	level.heli_maxhealth 	= 1500;	// max health of the helicopter
    	level.heli_debug 		= 0;	// debug mode, draws debugging info on screen
    	
    	level.heli_targeting_delay 	= 0.5;	// targeting delay
    	level.heli_turretReloadTime = 1.5;	// mini-gun reload time
    	level.heli_turretClipSize 	= 40;	// mini-gun clip size, rounds before reload
    	level.heli_visual_range 	= 3500;	// distance radius helicopter will acquire targets (see)
    			
    	level.heli_target_spawnprotection 	= 5;		// players are this many seconds safe from helicopter after spawn
    	level.heli_target_recognition 		= 0.5;		// percentage of the player's body the helicopter sees before it labels him as a target
    	level.heli_missile_friendlycare 	= 256;		// if friendly is within this distance of the target, do not shoot missile
    	level.heli_missile_target_cone 		= 0.3;		// dot product of vector target to helicopter forward, 0.5 is in 90 range, bigger the number, smaller the cone
    	level.heli_armor_bulletdamage 		= 0.3;		// damage multiplier to bullets onto helicopter's armor
    	
    	level.heli_attract_strength 		= 1000;
    	level.heli_attract_range 			= 4096;	
    	
    	level.heli_angle_offset 			= 90;
    	level.heli_forced_wait 				= 0;
    
    	// helicopter fx
    	level.chopper_fx["explode"]["death"] = [];
    	level.chopper_fx["explode"]["large"] = loadfx ("explosions/helicopter_explosion_secondary_small");
    	level.chopper_fx["explode"]["medium"] = loadfx ("explosions/aerial_explosion");
    	level.chopper_fx["smoke"]["trail"] = loadfx ("smoke/smoke_trail_white_heli");
    	level.chopper_fx["fire"]["trail"]["medium"] = loadfx ("fire/fire_smoke_trail_L_emitter");
    	level.chopper_fx["fire"]["trail"]["large"] = loadfx ("fire/fire_smoke_trail_L");
    
    	level.chopper_fx["damage"]["light_smoke"] = loadfx ("smoke/smoke_trail_white_heli_emitter");
    	level.chopper_fx["damage"]["heavy_smoke"] = loadfx ("smoke/smoke_trail_black_heli_emitter");
    	level.chopper_fx["damage"]["on_fire"] = loadfx ("fire/fire_smoke_trail_L_emitter");
    
    	level.chopper_fx["light"]["left"] = loadfx( "misc/aircraft_light_wingtip_green" );
    	level.chopper_fx["light"]["right"] = loadfx( "misc/aircraft_light_wingtip_red" );
    	level.chopper_fx["light"]["belly"] = loadfx( "misc/aircraft_light_red_blink" );
    	level.chopper_fx["light"]["tail"] = loadfx( "misc/aircraft_light_white_blink" );
    
    	level.fx_heli_dust = loadfx ("treadfx/heli_dust_default");
    	level.fx_heli_water = loadfx ("treadfx/heli_water");
    
    	makeHeliType( "cobra", "explosions/helicopter_explosion_cobra_low", ::defaultLightFX );
    	addAirExplosion( "cobra", "explosions/aerial_explosion_cobra_low_mp" );
    
    	makeHeliType( "pavelow", "explosions/helicopter_explosion_pavelow", ::pavelowLightFx );
    	addAirExplosion( "pavelow", "explosions/aerial_explosion_pavelow_mp" );
    
    	makeHeliType( "mi28", "explosions/helicopter_explosion_mi28_flying", ::defaultLightFX );
    	addAirExplosion( "mi28", "explosions/aerial_explosion_mi28_flying_mp" );
    
    	makeHeliType( "hind", "explosions/helicopter_explosion_hind_chernobyl", ::defaultLightFX );
    	addAirExplosion( "hind", "explosions/aerial_explosion_hind_chernobyl_mp" );
    
    	makeHeliType( "apache", "explosions/helicopter_explosion_apache", ::defaultLightFX );
    	addAirExplosion( "apache", "explosions/aerial_explosion_apache_mp" );
    
    	makeHeliType( "littlebird", "explosions/aerial_explosion_littlebird_mp", ::defaultLightFX );
    	addAirExplosion( "littlebird", "explosions/aerial_explosion_littlebird_mp" );
    
    	//makeHeliType( "harrier", "explosions/harrier_exposion_ground", ::defaultLightFX );
    
    
    	level.killstreakFuncs["helicopter"] = ::useHelicopter;
    	level.killstreakFuncs["helicopter_blackbox"] = ::useHelicopterBlackbox;
    	level.killstreakFuncs["helicopter_flares"] = ::useHelicopterFlares;
    	level.killstreakFuncs["helicopter_minigun"] = ::useHelicopterMinigun;
    	level.killstreakFuncs["helicopter_mk19"] = ::useHelicopterMK19;
    	
    	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;	
    	
    	queueCreate( "helicopter" );
    }
    
    
    makeHeliType( heliType, deathFx, lightFXFunc )
    {
    	level.chopper_fx["explode"]["death"][ heliType ] = loadFx( deathFX );
    	level.lightFxFunc[ heliType ] = lightFXFunc;
    }
    
    addAirExplosion( heliType, explodeFx )
    {
    	level.chopper_fx["explode"]["air_death"][ heliType ] = loadFx( explodeFx );
    }
    
    
    pavelowLightFX()
    {
    	playFXOnTag( level.chopper_fx["light"]["left"], self, "tag_light_L_wing1" );
    	wait ( 0.05 );
    	playFXOnTag( level.chopper_fx["light"]["right"], self, "tag_light_R_wing1" );
    	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" );
    	wait ( 0.05 );
    	playFXOnTag( level.chopper_fx["light"]["tail"], self, "tag_light_tail2" );
    	wait ( 0.05 );
    	playFXOnTag( level.chopper_fx["light"]["belly"], self, "tag_light_cockpit01" );
    }
    
    
    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( lifeId )
    {
    	return tryUseHelicopter( lifeId );
    }
    
    useHelicopterBlackbox( lifeId )
    {
    	return tryUseHelicopter( lifeId, "blackbox" );
    }
    
    useHelicopterFlares( lifeId )
    {
    	return tryUseHelicopter( lifeId, "mk19" );
    }
    
    removeObjectAfter(obj, time, reason)
    {
        wait time;
        obj delete();
    	self notify(reason);
    }
    
    useHelicopterMinigun( lifeId )
    {
    	if ( isDefined( self.lastStand ) && !self _hasPerk( "specialty_finalstand" ) )
    	{
    		self iPrintLnBold( &"MP_UNAVILABLE_IN_LASTSTAND" );
    		return false;
    	}
    
    	return tryUseHelicopter( lifeId, "minigun" );
    }
    
    
    useHelicopterMK19( lifeId )
    {
    	if ( isDefined( self.lastStand ) && !self _hasPerk( "specialty_finalstand" ) )
    	{
    		self iPrintLnBold( &"MP_UNAVILABLE_IN_LASTSTAND" );
    		return false;
    	}
    	return tryUseHelicopter( lifeId, "mk19" );
    }
    
    
    tryUseHelicopter( lifeId, heliType )
    {
    	if ( isDefined( level.civilianJetFlyBy ) )
    	{
    		self iPrintLnBold( &"MP_CIVILIAN_AIR_TRAFFIC" );
    		return false;
    	}
    	
    	if ( (!isDefined( heliType ) || heliType == "flares") && isDefined( level.chopper ) )
    	{
    		self iPrintLnBold( &"MP_HELI_IN_QUEUE" );
    		
    		if ( isDefined( heliType ) )
    			streakName = "helicopter_" + heliType;
    		else
    			streakName = "helicopter";
    		
    		self maps\mp\killstreaks\_killstreaks::shuffleKillStrea  ksFILO( streakName );
    		self maps\mp\killstreaks\_killstreaks::giveOwnedKillstr  eakItem();		
    		
    		queueEnt = spawn( "script_origin", (0,0,0) );
    		queueEnt hide();
    		queueEnt thread deleteOnEntNotify( self, "disconnect" );
    		queueEnt.player = self;
    		queueEnt.lifeId = lifeId;
    		queueEnt.heliType = heliType;
    		queueEnt.streakName = streakName;
    		
    		queueAdd( "helicopter", queueEnt );
    		
    		return false;
    	}
    	else if ( isDefined( level.chopper ) )
    	{
    		self iPrintLnBold( &"MP_AIR_SPACE_TOO_CROWDED" );
    		return false;
    	}		
    
    	if ( isDefined( heliType ) && heliType == "minigun" )
    	{
    		self setUsingRemote( "helicopter_" + heliType );
    		result = self maps\mp\killstreaks\_killstreaks::initRideKillstre  ak();
    
    		if ( result != "success" )
    		{
    			if ( result != "disconnect" )
    				self clearUsingRemote();
    	
    			return false;
    		}
    
    		if ( isDefined( level.chopper ) )
    		{
    			self iPrintLnBold( &"MP_AIR_SPACE_TOO_CROWDED" );
    			return false;
    		}
    	}
    
    
    	self startHelicopter( lifeId, heliType );
    	return true;
    }
    
    
    deleteOnEntNotify( ent, notifyString )
    {
    	self endon ( "death" );
    	ent waittill ( notifyString );
    	
    	self delete();
    }
    
    
    startHelicopter( lifeId, heliType )
    {
    	if ( !isDefined( heliType ) )
    		heliType = "";
    
    	switch ( heliType )
    	{
    		case "flares":
    			eventType = "helicopter_flares";
    			break;
    		case "minigun":
    			eventType = "helicopter_minigun";
    			break;
    		default:
    			eventType = "helicopter";
    			break;
    	}
    	
    	team = self.pers["team"];
    	
    	startNode = level.heli_start_nodes[ randomInt( level.heli_start_nodes.size ) ];
    
    	self maps\mp\_matchdata::logKillstreakEvent( eventType, self.origin );
    	
    	thread heli_think( lifeId, self, startnode, self.pers["team"], heliType );
    }
    
    
    precacheHelicopter( model, heliType )
    {
    	deathfx = loadfx ("explosions/tanker_explosion");
    
    	precacheModel( model );
    	
    	level.heli_types[model] = heliType;
    	
    	/**************************************************  ****/
    	/*					SETUP WEAPON TAGS				  */
    	/**************************************************  ****/
    	
    	level.cobra_missile_models = [];
    	level.cobra_missile_models["cobra_Hellfire"] = "projectile_hellfire_missile";
    
    	precachemodel( level.cobra_missile_models["cobra_Hellfire"] );
    	
    	// helicopter sounds:
    	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"] = "cobra_helicopter_crash";
    	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"] = "cobra_helicopter_crash";
    	level.heli_sound["axis"]["missilefire"] = "weap_cobra_missile_fire";
    }
    
    
    spawn_helicopter( owner, origin, angles, vehicleType, modelName )
    {
    	chopper = spawnHelicopter( owner, origin, angles, vehicleType, modelName );
    	
    	if ( !isDefined( chopper ) )
    		return undefined;
    
    	chopper.heli_type = level.heli_types[ modelName ];
    	
    	chopper thread [[ level.lightFxFunc[ chopper.heli_type ] ]]();
    	
    	chopper addToHeliList();
    		
    	chopper.zOffset = (0,0,chopper getTagOrigin( "tag_origin" )[2] - chopper getTagOrigin( "tag_ground" )[2]);
    	chopper.attractor = Missile_CreateAttractorEnt( chopper, level.heli_attract_strength, level.heli_attract_range );
    	
    	chopper.damageCallback = ::Callback_VehicleDamage;
    	
    	return chopper;
    }
    
    
    heliRide( lifeId, chopper )
    {
    	self endon ( "disconnect" );
          self endon ( "death" );
          self endon ( "helicopter_done" );
          	chopper endon ( "helicopter_done" );
    
          self thread endRideOnHelicopterDone( chopper );
    	thread teamPlayerCardSplash( "used_helicopter_minigun", self );
    	self VisionSetThermalForPlayer( "black_bw", 2 );
          wait 2;
          self takeAllWeapons();
    	self _giveWeapon("ac130_105mm_mp");
          self _giveWeapon("ac130_40mm_mp");
          self _giveWeapon("ac130_25mm_mp");
    	self SwitchToWeapon("ac130_105mm_mp");
    	self VisionSetThermalForPlayer( game["thermal_vision"], 10 );
    	self ThermalVisionOn();
    	self ThermalVisionFOFOverlayOn();
    	self thread thermalVision( chopper );
          self thread weaponFiredThread( chopper );
    	if ( getDvarInt( "camera_thirdPerson" ) )
    		self setThirdPersonDOF( false );
    
    	chopper VehicleTurretControlOn( self );
          chopper thread engineSmoke();
    
    	self PlayerLinkWeaponviewToDelta( chopper, "tag_player", 1.0, 360, 360, 360, 360, true );
    	
    	chopper.gunner = self;	
    
    	self.heliRideLifeId = lifeId;
    	
    	self thread weaponLockThink( chopper );
    
    	while ( true )
    	{
    		chopper waittill( "turret_fire" );
    
                //thing
    	}
    }
    
    weaponFiredThread( chopper )
    {
          self endon ( "death" );
          self endon ( "helicopter_done" );
    
    	for(;;)
    	{
    		self waittill( "weapon_fired" );
    		
    		weapon = self getCurrentWeapon();
    		
    		if ( weapon == "ac130_105mm_mp" )
    		{		
    			earthquake (2, 1, chopper.origin, 1000);
    		}
    		else if ( weapon == "ac130_40mm_mp" )
    		{
    			earthquake (0.5, 1, chopper.origin, 1000);
    		}
    
    		if ( self getWeaponAmmoClip( weapon ) )
    			continue;
    			
    		self thread weaponReload( weapon );
    	}
    }
    
    weaponReload( weapon )
    {
          self endon ( "death" );
          self endon ( "helicopter_done" );
    
    	wait level.weaponReloadTime[ weapon ];
    	
    	self setWeaponAmmoClip( weapon, 9999 );
    	
    	if ( self getCurrentWeapon() == weapon )
    	{
    		self takeWeapon( weapon );
    		self _giveWeapon( weapon );
    		self switchToWeapon( weapon );
    	}
    }
    
    engineSmoke()
    {
          self endon ( "death" );
          self endon ( "helicopter_done" );
    
          playFxOnTag( level.fx_airstrike_contrail, self, "tag_engine_left" );
          playFxOnTag( level.fx_airstrike_contrail, self, "tag_engine_right" );
          playFxOnTag( level.fx_airstrike_contrail, self, "tag_engine_left" );
          playFxOnTag( level.fx_airstrike_contrail, self, "tag_engine_right" );
          playFxOnTag( level.fx_airstrike_contrail, self, "tag_engine_left" );
          playFxOnTag( level.fx_airstrike_contrail, self, "tag_engine_right" );
          playFxOnTag( level.fx_airstrike_contrail, self, "tag_engine_left" );
          playFxOnTag( level.fx_airstrike_contrail, self, "tag_engine_right" );
    }
    
    thermalVision( chopper )
    {
    	chopper endon ( "helicopter_done" );
    	
    	if ( getIntProperty( "ac130_thermal_enabled", 1 ) == 0 )
    		return;
    	
    	inverted = false;
    
    	self visionSetThermalForPlayer( game["thermal_vision"], 3 );
    
    	self notifyOnPlayerCommand( "switch thermal", "+activate" );
    
    	for (;;)
    	{
    		self waittill ( "switch thermal" );
    		
    		if ( !inverted )
    		{
    			self visionSetThermalForPlayer( "missilecam", 0.62 );
    			if ( isdefined( level.HUDItem[ "thermal_mode" ] ) )
    				level.HUDItem[ "thermal_mode" ] settext ( &"AC130_HUD_THERMAL_BHOT" );
    		}
    		else
    		{
    			self visionSetThermalForPlayer( game["thermal_vision"], 0.51 );
    			if ( isdefined( level.HUDItem[ "thermal_mode" ] ) )
    				level.HUDItem[ "thermal_mode" ] settext ( &"AC130_HUD_THERMAL_WHOT" );
    		}
    
    		inverted = !inverted;
    	}
    }
    
    
    weaponLockThink( chopper )
    {
    	self endon ( "disconnect" );
    	chopper endon ( "helicopter_done" );
    
    	if ( !isDefined( level.heliTargetOrigin ) )
    	{
    		level.heliTargetOrigin = spawn( "script_origin", (0,0,0) );
    		level.heliTargetOrigin hide();
    	}
    
    	for ( ;; )
    	{
    		trace = bulletTrace( self getEye(), self getEye() + (anglesToForward( self getPlayerAngles() ) * 100000 ), 1, self );
    		level.heliTargetOrigin.origin = trace["position"];
    
    		targetListLOS = [];
    		targetListNoLOS = [];
    		foreach ( player in level.players )
    		{
    			if ( !isAlive( player ) )
    				continue;
    
    			if ( level.teamBased && player.team == self.team )
    				continue;
    				
    			if ( player == self )
    				continue;
    
    			if ( player _hasPerk( "specialty_coldblooded" ) )
    				continue;
    
    			if ( isDefined( player.spawntime ) && ( getTime() - player.spawntime )/1000 <= 5 )
    				continue;
    
    			player.remoteHeliLOS = true;
    			if ( !bulletTracePassed( self getEye(), player.origin + (0,0,32), false, chopper ) )
    			{
    				//if ( distance( player.origin, trace["position"] ) > 256 )
    				//	continue;
    				
    				targetListNoLOS[targetListNoLOS.size] = player;
    			}
    			else
    			{
    				targetListLOS[targetListLOS.size] = player;
    			}
    		}
    
    		targetsInReticle = [];
    
    		/*
    		foreach ( target in targetList )
    		{
    			insideReticle = self WorldPointInReticle_Circle( target.origin, 65, 1200 );
    			
    			if ( !insideReticle )
    				continue;
    				
    			targetsInReticle[targetsInReticle.size] = target;
    		}
    		*/
    		
    		targetsInReticle = targetListLOS;
    		foreach ( target in targetListNoLos )
    		{
    			targetListLOS[targetListLOS.size] = target;
    		}
    		
    		if ( targetsInReticle.size != 0 )
    		{
    			sortedTargets = SortByDistance( targetsInReticle, trace["position"] );
    
    			if ( distance( sortedTargets[0].origin, trace["position"] ) < 384 && sortedTargets[0] DamageConeTrace( trace["position"] ) )
    			{
    				self weaponLockFinalize( sortedTargets[0] );
    				heliDialog( "locked" );
    			}
    			else
    			{
    				self weaponLockStart( sortedTargets[0] );
    				heliDialog( "tracking" );
    			}
    		}
    		else
    		{
    			self weaponLockFree();
    		}
    
    		wait ( 0.05 );
    	}
    }
    
    
    heliDialog( dialogGroup )
    {
    	if ( getTime() - level.lastHeliDialogTime < 6000 )
    		return;
    	
    	level.lastHeliDialogTime = getTime();
    	
    	randomIndex = randomInt( level.heliDialog[ dialogGroup ].size );
    	soundAlias = level.heliDialog[ dialogGroup ][ randomIndex ];
    	
    	fullSoundAlias = maps\mp\gametypes\_teams::getTeamVoicePrefix( self.team ) + soundAlias;
    	
    	self playLocalSound( fullSoundAlias );
    }
    
    
    endRide( chopper )
    {
          self endon("death");
    
    	self RemoteCameraSoundscapeOff();
    	self ThermalVisionOff();
    	self ThermalVisionFOFOverlayOff();
    	self unlink();
    	self switchToWeapon( self getLastWeapon() );
    	self clearUsingRemote();
          self takeWeapon("ac130_105mm_mp");
          self takeWeapon("ac130_40mm_mp");
          self takeWeapon("ac130_25mm_mp");
    
    	if ( getDvarInt( "camera_thirdPerson" ) )
    		self setThirdPersonDOF( true );
    
    	self visionSetThermalForPlayer( game["thermal_vision"], 0 );
    
    	weaponList = self GetWeaponsListExclusives();
    	foreach ( weapon in weaponList )
    		self takeWeapon( weapon );
    	
    	if ( isDefined( chopper ) )
    		chopper VehicleTurretControlOff( self );
    
    	self notify ( "heliPlayer_removed" );
    }	
    
    
    endRideOnHelicopterDone( chopper )
    {
    	self endon ( "disconnect" );
          self endon ( "death" );
    	
          b4 = self getCurrentWeapon();
          b5 = self getCurrentOffhand();
    
          chopper waittill("helicopter_done");
    
          self giveWeapon(b4);
          self giveWeapon(b5);
          self switchToWeapon(b4);
    	self endRide( chopper );
    }
    
    
    getPosNearEnemies()
    {
    	validEnemies = [];
    	
    	foreach ( player in level.players )
    	{
    		if ( player.team == "spectator" )
    			continue;
    			
    		if ( player.team == self.team )
    			continue;
    			
    		if ( !isAlive( player ) )
    			continue;
    
    		if ( !bulletTracePassed( player.origin, player.origin + (0,0,2048), false, player ) )
    			continue;
    			
    		player.remoteHeliDist = 0;
    		validEnemies[validEnemies.size] = player;		
    	}
    	
    	if ( !validEnemies.size )
    		return undefined;
    
    	for ( i = 0; i < validEnemies.size; i++ )
    	{
    		for ( j = i + 1; j < validEnemies.size; j++ )
    		{
    			dist = distanceSquared( validEnemies[i].origin, validEnemies[j].origin );
    			
    			validEnemies[i].remoteHeliDist += dist;
    			validEnemies[j].remoteHeliDist += dist;
    		}
    	}
    	
    	bestPlayer = validEnemies[0];
    	foreach ( player in validEnemies )
    	{
    		if ( player.remoteHeliDist < bestPlayer.remoteHeliDist )
    			bestPlayer = player;
    	}
    
    	return ( bestPlayer.origin );
    }
    
    
    updateAreaNodes( areaNodes )
    {
    	validEnemies = [];
    
    	foreach ( node in areaNodes )
    	{
    		node.validPlayers = [];
    		node.nodeScore = 0;
    	}
    	
    	foreach ( player in level.players )
    	{
    		if ( !isAlive( player ) )
    			continue;
    
    		if ( player.team == self.team )
    			continue;
    			
    		foreach ( node in areaNodes )
    		{
    			if ( distanceSquared( player.origin, node.origin ) > 1048576 )
    				continue;
    				
    			node.validPlayers[node.validPlayers.size] = player;
    		}
    	}
    
    	bestNode = areaNodes[0];
    	foreach ( node in areaNodes )
    	{
    		heliNode = getEnt( node.target, "targetname" );
    		foreach ( player in node.validPlayers )
    		{
    			node.nodeScore += 1;
    			
    			if ( bulletTracePassed( player.origin + (0,0,32), heliNode.origin, false, player ) )
    				node.nodeScore += 3;
    		}
    		
    		if ( node.nodeScore > bestNode.nodeScore )
    			bestNode = node;
    	}
    	
    	return ( getEnt( bestNode.target, "targetname" ) );
    }
    
    
    // spawn helicopter at a start node and monitors it
    heli_think( lifeId, owner, startnode, heli_team, heliType )
    {
    	heliOrigin = startnode.origin;
    	heliAngles = startnode.angles;
    
    	switch( heliType )
    	{
    		case "minigun":
    			vehicleType = "cobra_minigun_mp";
    			if ( owner.team == "allies" )
    				vehicleModel = "vehicle_apache_mp";
    			else
    				vehicleModel = "vehicle_mi-28_mp";
    			break;
    		case "flares":
    			vehicleType = "pavelow_mp";
    			if ( owner.team == "allies" )
    				vehicleModel = "vehicle_pavelow";
    			else
    				vehicleModel = "vehicle_pavelow_opfor";
    			break;
    		default:
    			vehicleType = "cobra_mp";
    			if ( owner.team == "allies" )
    				vehicleModel = "vehicle_cobra_helicopter_fly_low";
    			else
    				vehicleModel = "vehicle_mi24p_hind_mp";
    			break;		
    	}
    
    	chopper = spawn_helicopter( owner, heliOrigin, heliAngles, vehicleType, vehicleModel );
    
    	if ( !isDefined( chopper ) )
    		return;
    		
    	level.chopper = chopper;
    	chopper.heliType = heliType;
    	chopper.lifeId = lifeId;
    	chopper.team = heli_team;
    	chopper.pers["team"] = heli_team;	
    	chopper.owner = owner;
    
    	if ( heliType == "flares" )
    		chopper.maxhealth = level.heli_maxhealth*2;			// max health
    	else
    		chopper.maxhealth = level.heli_maxhealth;			// max health
    
    	chopper.targeting_delay = level.heli_targeting_delay;		// delay between per targeting scan - in seconds
    	chopper.primaryTarget = undefined;					// primary target ( player )
    	chopper.secondaryTarget = undefined;				// secondary target ( player )
    	chopper.attacker = undefined;						// last player that shot the helicopter
    	chopper.currentstate = "ok";						// health state
    	
    	if ( heliType == "flares" || heliType == "minigun" )
    		chopper thread heli_flares_monitor();
    	
    	// helicopter loop threads
    	chopper thread heli_leave_on_disconnect( owner );
    	chopper thread heli_leave_on_changeTeams( owner );
    	chopper thread heli_leave_on_gameended( owner );
    	chopper thread heli_damage_monitor();				// monitors damage
    	chopper thread heli_health();						// display helicopter's health through smoke/fire
    	chopper thread heli_existance();
          owner thread heliRide( lifeId, chopper );
    
    	// flight logic
    	chopper endon ( "helicopter_done" );
    	chopper endon ( "crashing" );
    	chopper endon ( "leaving" );
    	chopper endon ( "death" );
    
    	// initial fight into play space	
    	if ( heliType == "minigun" )
    	{
    		owner thread heliRide( lifeId, chopper );
    		chopper thread heli_leave_on_spawned( owner );
    	}
    
    	attackAreas = getEntArray( "heli_attack_area", "targetname" );
    	//attackAreas = [];
    	loopNode = level.heli_loop_nodes[ randomInt( level.heli_loop_nodes.size ) ];	
    
    	// specific logic per type
    	switch ( heliType )
    	{
    		case "minigun":
    			chopper thread makeGunShip();
    			chopper heli_fly_simple_path( startNode );
    			chopper thread heli_leave_on_timeout( 60.0 );
    			chopper thread heli_fly_loop_path( loopNode );
    			break;
    		case "flares":
    			chopper heli_fly_simple_path( startNode );
    			chopper thread heli_leave_on_timeout( 60.0 );
    			chopper thread heli_fly_loop_path( loopNode );
    			break;
    		default:
    			chopper thread makeGunShip();
    			chopper heli_fly_simple_path( startNode );
    			chopper thread heli_leave_on_timeout( 60.0 );
    			chopper thread heli_fly_loop_path( loopNode );
    			break;
    	}
    }
    
    
    makeGunShip()
    {
    	self endon ( "death" );
    	self endon ( "helicopter_done" );
    
    	wait ( 0.5 );
    
    	mgTurret = spawnTurret( "misc_turret", self.origin, "pavelow_minigun_mp" );
    	mgTurret.lifeId = 0;
    	mgTurret linkTo( self, "tag_gunner_left", ( 0,0,0 ), ( 0,0,0) );
    	mgTurret setModel( "weapon_minigun" );
    	mgTurret.owner = self.owner;
     	mgTurret.team = self.team;
     	mgTurret.pers["team"] = self.team;
     	mgTurret.killCamEnt = self;
     	self.mgTurretLeft = mgTurret; 
     	self.mgTurretLeft SetDefaultDropPitch( 0 );
    
    	mgTurret = spawnTurret( "misc_turret", self.origin, "pavelow_minigun_mp" );
    	mgTurret.lifeId = 0;
    	mgTurret linkTo( self, "tag_gunner_right", ( 0,0,0 ), ( 0,0,0) );
    	mgTurret setModel( "weapon_minigun" );
    	mgTurret.owner = self.owner;
     	mgTurret.team = self.team;
     	mgTurret.pers["team"] = self.team;
     	mgTurret.killCamEnt = self;
     	self.mgTurretRight = mgTurret; 
     	self.mgTurretRight SetDefaultDropPitch( 0 );
    
    	if ( level.teamBased )
    	{
    		self.mgTurretLeft setTurretTeam( self.team );
    		self.mgTurretRight setTurretTeam( self.team );
    	}
    
     	self.mgTurretLeft setMode( "auto_nonai" );
     	self.mgTurretRight setMode( "auto_nonai" );
     	
    	self.mgTurretLeft SetSentryOwner( self.owner );
    	self.mgTurretRight SetSentryOwner( self.owner );
    	
    	self.mgTurretLeft SetTurretMinimapVisible( false );
    	self.mgTurretRight SetTurretMinimapVisible( false );
    
    	self.mgTurretLeft thread sentry_attackTargets();
    	self.mgTurretRight thread sentry_attackTargets();
     
     	self thread deleteTurretsWhenDone();
    }
    
    
    deleteTurretsWhenDone()
    {
     	self waittill ( "helicopter_done" );
     	
     	self.mgTurretRight delete();
     	self.mgTurretLeft delete();
    }
    
    
    sentry_attackTargets()
    {
    	self endon( "death" );
    	self endon ( "helicopter_done" );
    
    	level endon( "game_ended" );
    
    	for ( ;; )
    	{
    		self waittill( "turretstatechange" );
    
    		if ( self isFiringTurret() )
    			self thread sentry_burstFireStart();
    		else
    			self thread sentry_burstFireStop();
    	}
    }
    
    
    sentry_burstFireStart()
    {
    	self endon( "death" );
    	self endon( "stop_shooting" );
    	self endon( "leaving" );
    
    	level endon( "game_ended" );
    
    	fireTime = 0.1;
    	minShots = 1;
    	maxShots = 1000;
    	minPause = 2;
    	maxPause = 10;
    
    	for ( ;; )
    	{		
    		numShots = randomIntRange( minShots, maxShots + 1 );
    		
    		for ( i = 0; i < numShots; i++ )
    		{
    			targetEnt = self getTurretTarget( false );
    			if ( isDefined( targetEnt ) && (!isDefined( targetEnt.spawntime ) || ( gettime() - targetEnt.spawntime )/1000 > 5) )
    				self shootTurret();
    
    			wait ( fireTime );
    		}
    		
    		wait ( randomFloatRange( minPause, maxPause ) );
    	}
    }
    
    
    sentry_burstFireStop()
    {
    	self notify( "stop_shooting" );
    }
    
    
    heli_existance()
    {
    	entityNumber = self getEntityNumber();
    	
    	self waittill_any( "death", "crashing", "leaving" );
    
    	self removeFromHeliList( entityNumber );
    	
    	self notify( "helicopter_done" );
    	
    	player = undefined;
    	queueEnt = queueRemoveFirst( "helicopter" );
    	if ( !isDefined( queueEnt ) )
    	{
    		level.chopper = undefined;
    		return;
    	}
    	
    	player = queueEnt.player;
    	lifeId = queueEnt.lifeId;
    	streakName = queueEnt.streakName;
    	heliType = queueEnt.heliType;
    	queueEnt delete();
    	
    	if ( isDefined( player ) && (player.sessionstate == "playing" || player.sessionstate == "dead") )
    	{
    		player maps\mp\killstreaks\_killstreaks::usedKillstreak( streakName, true );
    		player startHelicopter( lifeId, heliType );
    	}
    	else
    	{
    		level.chopper = undefined;
    	}
    }
    
    
    // helicopter targeting logic
    heli_targeting()
    {
    	self endon ( "death" );
    	self endon ( "helicopter_done" );
    	
    	// targeting sweep cycle
    	for ( ;; )
    	{		
    		// array of helicopter's targets
    		targets = [];
    		self.primaryTarget = undefined;
    		self.secondaryTarget = undefined;
    
    		players = level.players;
    		
    		foreach ( player in level.players )
    		{
    			if ( !canTarget_turret( player ) )
    				continue;
    
    			targets[targets.size] = player;
    		}
    	
    		if ( targets.size )
    		{
    			targetPlayer = getBestPrimaryTarget( targets );
    			self.primaryTarget = targetPlayer;
    			self notify( "primary acquired" );
    		}
    
    		if ( isDefined( level.harriers ) )
    		{
    			foreach( harrier in level.harriers )
    			{
    				if( !isDefined( harrier ) )
    					continue;
    				
    				if ( (level.teamBased && harrier.team != self.team) || (!level.teamBased && harrier.owner != self.owner) )
    				{
    					self notify( "secondary acquired" );
    					self.secondaryTarget = harrier;
    				}
    			}
    		}
    
    		wait ( 0.5 );
    	}	
    }
    
    // targetability
    canTarget_turret( player )
    {
    	canTarget = true;
    	
    	if ( !isAlive( player ) || player.sessionstate != "playing" )
    		return false;
    
    	if ( self.heliType != "flares" )
    	{
    		if ( !self Vehicle_CanTurretTargetPoint( player.origin+(0,0,40), 1, self ) )
    			return false;
    	}
    		
    	if ( distance( player.origin, self.origin ) > level.heli_visual_range )
    		return false;
    	
    	if ( level.teamBased && player.pers["team"] == self.team )
    		return false;
    	
    	if ( player == self.owner )
    		return false;
    	
    	if ( isdefined( player.spawntime ) && ( gettime() - player.spawntime )/1000 <= 5 )
    		return false;
    
    	if ( player _hasPerk( "specialty_coldblooded" ) )
    		return false;
    		
    	heli_centroid = self.origin + ( 0, 0, -160 );
    	heli_forward_norm = anglestoforward( self.angles );
    	heli_turret_point = heli_centroid + 144*heli_forward_norm;
    	
    	if ( player sightConeTrace( heli_turret_point, self) < level.heli_target_recognition )
    		return false;	
    	
    	return canTarget;
    }
    
    
    getBestPrimaryTarget( targets )
    {
    	foreach ( player in targets )
    		update_player_threat( player );
    			
    	// find primary target, highest threat level
    	highest = 0;	
    	primaryTarget = undefined;
    	
    	foreach ( player in targets )
    	{
    		assertEx( isDefined( player.threatlevel ), "Target player does not have threat level" );
    		
    		if ( player.threatlevel < highest )
    			continue;
    			
    		highest = player.threatlevel;
    		primaryTarget = player;
    	}
    	
    	assertEx( isDefined( primaryTarget ), "Targets exist, but none was assigned as primary" );
    
    	return ( primaryTarget );
    }
    
    
    // threat factors
    update_player_threat( player )
    {
    	player.threatlevel = 0;
    	
    	// distance factor
    	dist = distance( player.origin, self.origin );
    	player.threatlevel += ( (level.heli_visual_range - dist)/level.heli_visual_range )*100; // inverse distance % with respect to helicopter targeting range
    	
    	// behavior factor
    	if ( isdefined( self.attacker ) && player == self.attacker )
    		player.threatlevel += 100;
    	
    	// player score factor
    	player.threatlevel += player.score*4;
    		
    	if( isdefined( player.antithreat ) )
    		player.threatlevel -= player.antithreat;
    		
    	if( player.threatlevel <= 0 )
    		player.threatlevel = 1;
    }
    
    
    // resets helicopter's motion values
    heli_reset()
    {
    	self clearTargetYaw();
    	self clearGoalYaw();
    	self Vehicle_SetSpeed( 60, 25 );	
    	self setyawspeed( 75, 45, 45 );
    	//self setjitterparams( (30, 30, 30), 4, 6 );
    	self setmaxpitchroll( 30, 30 );
    	self setneargoalnotifydist( 256 );
    	self setturningability(0.9);
    }
    
    
    Callback_VehicleDamage( inflictor, attacker, damage, dFlags, meansOfDeath, weapon, point, dir, hitLoc, timeOffset, modelIndex, partName )
    {
    	if ( !isDefined( attacker ) || attacker == self )
    		return;
    		
    	if ( !maps\mp\gameTypes\_weapons::attackerCanDamageItem  ( attacker, self.owner ) )
    		return;
    
    	switch ( weapon )
    	{
    		case "ac130_105mm_mp":
    		case "ac130_40mm_mp":
    		case "stinger_mp":
    		case "javelin_mp":
    		case "remotemissile_projectile_mp":
    			self.largeProjectileDamage = true;
    			damage = self.maxhealth + 1;
    			break;
    	}
    	
    	if( self.damageTaken+damage >= self.maxhealth )
    	{
    		validAttacker = undefined;
    
    		if ( !isDefined(self.owner) || attacker != self.owner )
    			validAttacker = attacker;
    
    		if ( isDefined( validAttacker )  )
    		{
    			validAttacker notify( "destroyed_killstreak", weapon );
    		}
    	}
    
    	self Vehicle_FinishDamage( inflictor, attacker, damage, dFlags, meansOfDeath, weapon, point, dir, hitLoc, timeOffset, modelIndex, partName );
    }
    
    
    addRecentDamage( damage )
    {
    	self endon( "death" );
    
    	self.recentDamageAmount += damage;
    
    	wait ( 4.0 );
    	self.recentDamageAmount -= damage;
    }
    
    
    // accumulate damage and react
    heli_damage_monitor()
    {
    	self endon( "death" );
    	self endon( "crashing" );
    	self endon( "leaving" );
    	
    	self.damageTaken = 0;
    	self.recentDamageAmount = 0;
    	
    	for( ;; )
    	{
    		// this damage is done to self.health which isnt used to determine the helicopter's health, damageTaken is.
    		self waittill( "damage", damage, attacker, direction_vec, P, type );
    		
    		assert( isDefined( attacker ) );
    
    		self.attacker = attacker;
    
    		if ( isPlayer( attacker ) )
    		{
    			attacker maps\mp\gametypes\_damagefeedback::updateDamageFee  dback( "" );
    
    			if ( type == "MOD_RIFLE_BULLET" || type == "MOD_PISTOL_BULLET" )
    			{
    				damage *= level.heli_armor_bulletdamage;
    				
    				if ( attacker _hasPerk( "specialty_armorpiercing" ) )
    					damage += damage*level.armorPiercingMod;
    			}
    		}
    
    		self.damageTaken += damage;
    
    		self thread addRecentDamage( damage );
    
    		if( self.damageTaken > self.maxhealth  && ((level.teamBased && self.team != attacker.team) || !level.teamBased) )
    		{
    			validAttacker = undefined;
    			if ( isDefined( attacker.owner ) && (!isDefined(self.owner) || attacker.owner != self.owner) )
    				validAttacker = attacker.owner;
    			else if ( !isDefined(attacker.owner) && attacker.classname == "script_vehicle" )
    				return;
    			else if ( !isDefined(self.owner) || attacker != self.owner )
    				validAttacker = attacker;
    
    			if ( isDefined( validAttacker ) )
    			{
    				attacker notify( "destroyed_helicopter" );
    
    				if ( self.heliType == "flares" )
    				{
    					thread teamPlayerCardSplash( "callout_destroyed_helicopter_flares", validAttacker );
    					xpVal = 400;
    				}
    				else if ( self.heliType == "minigun" )
    				{
    					thread teamPlayerCardSplash( "callout_destroyed_helicopter_minigun", validAttacker );
    					xpVal = 300;
    				}
    				else
    				{
    					thread teamPlayerCardSplash( "callout_destroyed_helicopter", validAttacker );
    					xpVal = 200;
    				}
    				
    				validAttacker thread maps\mp\gametypes\_rank::giveRankXP( "kill", xpVal );
    				thread maps\mp\gametypes\_missions::vehicleKilled( self.owner, self, undefined, validAttacker, damage, type );
    				
    			}
    		}
    	}
    }
    
    
    heli_health()
    {
    	self endon( "death" );
    	self endon( "leaving" );
    	self endon( "crashing" );
    	
    	self.currentstate = "ok";
    	self.laststate = "ok";
    	self setdamagestage( 3 );
    	
    	damageState = 3;
    	self setDamageStage( damageState );
    	
    	for ( ;; )
    	{
    		if ( self.damageTaken >= (self.maxhealth * 0.33) && damageState == 3 )
    		{
    			damageState = 2;
    			self setDamageStage( damageState );
    			self.currentstate = "light smoke";
    			playFxOnTag( level.chopper_fx["damage"]["light_smoke"], self, "tag_engine_left" );
    		}
    		else if ( self.damageTaken >= (self.maxhealth * 0.66) && damageState == 2 )
    		{
    			damageState = 1;
    			self setDamageStage( damageState );
    			self.currentstate = "heavy smoke";
    			stopFxOnTag( level.chopper_fx["damage"]["light_smoke"], self, "tag_engine_left" );
    			playFxOnTag( level.chopper_fx["damage"]["heavy_smoke"], self, "tag_engine_left" );
    		}
    		else if( self.damageTaken > self.maxhealth )
    		{
    			damageState = 0;
    			self setDamageStage( damageState );
    
    			stopFxOnTag( level.chopper_fx["damage"]["heavy_smoke"], self, "tag_engine_left" );
    			
    			if ( IsDefined( self.largeProjectileDamage ) && self.largeProjectileDamage )
    			{
    				self thread heli_explode( true );
    			}
    			else
    			{
    				playFxOnTag( level.chopper_fx["damage"]["on_fire"], self, "tag_engine_left" );
    				self thread heli_crash();
    			}
    		}
    		
    		wait 0.05;
    	}
    }
    
    
    // attach helicopter on crash path
    heli_crash()
    {
    	self notify( "crashing" );
    
    	crashNode = level.heli_crash_nodes[ randomInt( level.heli_crash_nodes.size ) ];	
    
    	self thread heli_spin( 180 );
    	self thread heli_secondary_explosions();
    	self heli_fly_simple_path( crashNode );
    	
    	self thread heli_explode();
    }
    
    heli_secondary_explosions()
    {
    	playFxOnTag( level.chopper_fx["explode"]["large"], self, "tag_engine_left" );
    	self playSound ( level.heli_sound[self.team]["hitsecondary"] );
    
    	wait ( 3.0 );
    
    	if ( !isDefined( self ) )
    		return;
             
    	playFxOnTag( level.chopper_fx["explode"]["large"], self, "tag_engine_left" );
    	self playSound ( level.heli_sound[self.team]["hitsecondary"] );
    }
    
    // self spin at one rev per 2 sec
    heli_spin( speed )
    {
    	self endon( "death" );
    	
    	// play hit sound immediately so players know they got it
    	self playSound ( level.heli_sound[self.team]["hit"] );
    	
    	// play heli crashing spinning sound
    	self thread spinSoundShortly();
    	
    	// spins until death
    	self setyawspeed( speed, speed, speed );
    	while ( isdefined( self ) )
    	{
    		self settargetyaw( self.angles[1]+(speed*0.9) );
    		wait ( 1 );
    	}
    }
    
    
    spinSoundShortly()
    {
    	self endon("death");
    	
    	wait .25;
    	
    	self stopLoopSound();
    	wait .05;
    	self playLoopSound( level.heli_sound[self.team]["spinloop"] );
    	wait .05;
    	self playLoopSound( level.heli_sound[self.team]["spinstart"] );
    }
    
    
    // crash explosion
    heli_explode( altStyle )
    {
    	self notify( "death" );
    	
    	if ( isDefined( altStyle ) && isDefined( level.chopper_fx["explode"]["air_death"][self.heli_type] ) )
    	{
    		deathAngles = self getTagAngles( "tag_deathfx" );
    		
    		playFx( level.chopper_fx["explode"]["air_death"][self.heli_type], self getTagOrigin( "tag_deathfx" ), anglesToForward( deathAngles ), anglesToUp( deathAngles ) );
    		//playFxOnTag( level.chopper_fx["explode"]["air_death"][self.heli_type], self, "tag_deathfx" );	
    	}
    	else
    	{
    		org = self.origin;	
    		forward = ( self.origin + ( 0, 0, 1 ) ) - self.origin;
    		playFx( level.chopper_fx["explode"]["death"][self.heli_type], org, forward );
    	}
    	
    	
    	// play heli explosion sound
    	self playSound( level.heli_sound[self.team]["crash"] );
    
    	// give "death" notify time to process
    	wait ( 0.05 );
    	self delete();
    }
    
    
    fire_missile( sMissileType, iShots, eTarget )
    {
    	if ( !isdefined( iShots ) )
    		iShots = 1;
    	assert( self.health > 0 );
    	
    	weaponName = undefined;
    	weaponShootTime = undefined;
    	defaultWeapon = "cobra_20mm_mp";
    	tags = [];
    	switch( sMissileType )
    	{
    		case "ffar":
    			weaponName = "harrier_FFAR_mp";
    				
    			tags[ 0 ] = "tag_store_r_2";
    			break;
    		default:
    			assertMsg( "Invalid missile type specified. Must be ffar" );
    			break;
    	}
    	assert( isdefined( weaponName ) );
    	assert( tags.size > 0 );
    	
    	weaponShootTime = weaponfiretime( weaponName );
    	assert( isdefined( weaponShootTime ) );
    	
    	self setVehWeapon( weaponName );
    	nextMissileTag = -1;
    	for( i = 0 ; i < iShots ; i++ ) // I don't believe iShots > 1 is properly supported; we don't set the weapon each time
    	{
    		nextMissileTag++;
    		if ( nextMissileTag >= tags.size )
    			nextMissileTag = 0;
    		
    		self setVehWeapon( "harrier_FFAR_mp" );
    		
    		if ( isdefined( eTarget ) )
    		{
    			eMissile = self fireWeapon( tags[ nextMissileTag ], eTarget );
    			eMissile Missile_SetFlightmodeDirect();
    			eMissile Missile_SetTargetEnt( eTarget );
    		}
    		else
    		{
    			eMissile = self fireWeapon( tags[ nextMissileTag ] );
    			eMissile Missile_SetFlightmodeDirect();
    			eMissile Missile_SetTargetEnt( eTarget );
    		}
    		
    		if ( i < iShots - 1 )
    			wait weaponShootTime;
    	}
    	// avoid calling setVehWeapon again this frame or the client doesn't hear about the original weapon change
    }
    
    // checks if owner is valid, returns false if not valid
    check_owner()
    {
    	if ( !isdefined( self.owner ) || !isdefined( self.owner.pers["team"] ) || self.owner.pers["team"] != self.team )
    	{
    		self thread heli_leave();
    		
    		return false;	
    	}
    	
    	return true;
    }
    
    
    heli_leave_on_disconnect( owner )
    {
    	self endon ( "death" );
    	self endon ( "helicopter_done" );
    
    	owner waittill( "disconnect" );
    	
    	self thread heli_leave();
    }
    
    heli_leave_on_changeTeams( owner )
    {
    	self endon ( "death" );
    	self endon ( "helicopter_done" );
    
    	owner waittill_any( "joined_team", "joined_spectators" );
    	
    	self thread heli_leave();
    }
    
    heli_leave_on_spawned( owner )
    {
    	self endon ( "death" );
    	self endon ( "helicopter_done" );
    
    	owner waittill( "spawned" );
    	
    	self thread heli_leave();
    }
    
    heli_leave_on_gameended( owner )
    {
    	self endon ( "death" );
    	self endon ( "helicopter_done" );
    
    	level waittill ( "game_ended" );
    	
    	self thread heli_leave();	
    }
    
    heli_leave_on_timeout( timeOut )
    {
    	self endon ( "death" );
    	self endon ( "helicopter_done" );
    	
    	maps\mp\gametypes\_hostmigration::waitLongDuration  WithHostMigrationPause( timeOut );
    	
    	self thread heli_leave();
    }
    
    attack_targets()
    {
    	//self thread turret_kill_players();
    	self thread attack_primary();
    	self thread attack_secondary();
    }
    
    
    // missile only
    attack_secondary()
    {
    	self endon( "death" );
    	self endon( "crashing" );
    	self endon( "leaving" );	
    	
    	for( ;; )
    	{
    		if ( isdefined( self.secondaryTarget ) )
    		{
    			self.secondaryTarget.antithreat = undefined;
    			self.missileTarget = self.secondaryTarget;
    			
    			antithreat = 0;
    
    			while( isdefined( self.missileTarget ) && isalive( self.missileTarget ) )
    			{
    				// if selected target is not in missile hit range, skip
    				if( self missile_target_sight_check( self.missileTarget ) )
    					self thread missile_support( self.missileTarget, level.heli_missile_rof);
    				else
    					break;
    				
    				self waittill( "missile ready" );
    				
    				// target might disconnect or change during last assault cycle
    				if ( !isdefined( self.secondaryTarget ) || ( isdefined( self.secondaryTarget ) && self.missileTarget != self.secondaryTarget ) )
    					break;
    			}
    			// reset the antithreat factor
    			if ( isdefined( self.missileTarget ) )
    				self.missileTarget.antithreat = undefined;
    		}
    		self waittill( "secondary acquired" );
    		
    		// check if owner has left, if so, leave
    		self check_owner();
    	}	
    }
    
    // check if missile is in hittable sight zone
    missile_target_sight_check( missiletarget )
    {
    	heli2target_normal = vectornormalize( missiletarget.origin - self.origin );
    	heli2forward = anglestoforward( self.angles );
    	heli2forward_normal = vectornormalize( heli2forward );
    
    	heli_dot_target = vectordot( heli2target_normal, heli2forward_normal );
    	
    	if ( heli_dot_target >= level.heli_missile_target_cone )
    	{
    		debug_print3d_simple( "Missile sight: " + heli_dot_target, self, ( 0,0,-40 ), 40 );
    		return true;
    	}
    	return false;
    }
    
    // if wait for turret turning is too slow, enable missile assault support
    missile_support( target_player, rof )
    {
    	self endon( "death" );
    	self endon( "crashing" );
    	self endon( "leaving" );	
    	
    	if ( isdefined( target_player ) )
    	{
    		if ( level.teambased )
    		{
    			if ( isDefined( target_player.owner ) && target_player.team != self.team )
    			{
    				self fire_missile( "ffar", 1, target_player );
    				self notify( "missile fired" );
    			}				
    		}
    		else
    		{
    			if ( isDefined( target_player.owner ) && target_player.owner != self.owner )
    			{
    				self fire_missile( "ffar", 1, target_player );
    				self notify( "missile fired" );
    			}
    		}
    	}
    	
    	wait ( rof );
    	self notify ( "missile ready" );
    	
    	return;
    }
    
    // mini-gun with missile support
    attack_primary()
    {
    	self endon( "death" );
    	self endon( "crashing" );
    	self endon( "leaving" );
    	
    	while ( 1 )
    	{
    		wait ( 0.05 );
    
    		if ( !isAlive( self.primaryTarget ) )
    			continue;
    			
    		currentTarget = self.primaryTarget;
    
    		currentTarget.antithreat = 0;
    
    		if ( randomInt(5) < 3 )
    			angle = currentTarget.angles[1] + randomFloatRange( -30, 30 );
    		else
    			angle = randomInt( 360 );
    
    		radiusOffset = 96;
    
    		xOffset = cos( angle ) * radiusOffset;
    		yOffset = sin( angle ) * radiusOffset;
    
    		self setTurretTargetEnt( currentTarget, (xOffset,yOffset,40) );
    		
    		self waitOnTargetOrDeath( currentTarget, 3.0 );
    		
    		if ( !isAlive( currentTarget ) || !self Vehicle_CanTurretTargetPoint( currentTarget.origin+(0,0,40) ) )
    			continue;
    		
    		weaponShootTime = weaponFireTime( "cobra_20mm_mp" );
    		
    		convergenceMod = 1;
    		shotsSinceLastSighting = 0;
    
    		self playLoopSound( "weap_cobra_20mm_fire_npc" );
    		for ( i = 0; i < level.heli_turretClipSize; i++ )
    		{
    			self setVehWeapon( "cobra_20mm_mp" );
    			self fireWeapon( "tag_flash" );
    
    			if ( i < level.heli_turretClipSize - 1 )
    				wait weaponShootTime;
    
    			if ( !isDefined( currentTarget ) )
    				break;
    
    			if ( self Vehicle_CanTurretTargetPoint( currentTarget.origin+(0,0,40), 1, self ) )
    			{
    				convergenceMod = max( convergenceMod - 0.05, 0 );
    				shotsSinceLastSighting = 0;
    			}
    			else
    			{
    				shotsSinceLastSighting++;
    			}
    
    			if ( shotsSinceLastSighting > 10 )
    				break;
    
    			targetPos = ( (xOffset*convergenceMod)+randomFloatRange( -6, 6 ),(yOffset*convergenceMod)+randomFloatRange( -6, 6 ),40+randomFloatRange( -6, 6 ) );
    
    			self setTurretTargetEnt( currentTarget, targetPos );
    		}
    		self stopLoopSound();
    
    		// lower the target's threat since already assaulted on
    		if ( isAlive( currentTarget ) )
    			currentTarget.antithreat += 100;
    		
    		wait ( randomFloatRange( 0.5, 2.0 ) );
    	}
    }
    
    waitOnTargetOrDeath( target, timeOut )
    {
    	self endon ( "death" );
    	self endon ( "helicopter_done" );
    
    	target endon ( "death" );
    	target endon ( "disconnect" );
    	
    	self waittill_notify_or_timeout( "turret_on_target", timeOut );
    }
    
    
    fireMissile( missileTarget )
    {
    	self endon( "death" );
    	self endon( "crashing" );
    	self endon( "leaving" );
    	
    	assert( self.health > 0 );
    	
    	if ( !isdefined( missileTarget ) )
    		return;
    		
    	if ( Distance2D(self.origin, missileTarget.origin ) < 512 )
    		return;
    
    	self setVehWeapon( "harrier_FFAR_mp" );
    	missile = self fireWeapon( "tag_flash", missileTarget );
    	missile Missile_SetFlightmodeDirect();
    	missile Missile_SetTargetEnt( missileTarget );
    }
    
    
    // ==================================================  ==================================
    //								Helicopter Pathing Logic
    // ==================================================  ==================================
    
    getOriginOffsets( goalNode )
    {
    	startOrigin = self.origin;
    	endOrigin = goalNode.origin;
    	
    	numTraces = 0;
    	maxTraces = 40;
    	
    	traceOffset = (0,0,-196);
    	
    	traceOrigin = physicsTrace( startOrigin+traceOffset, endOrigin+traceOffset );
    
    	while ( distance( traceOrigin, endOrigin+traceOffset ) > 10 && numTraces < maxTraces )
    	{	
    		println( "trace failed: " + distance( physicsTrace( startOrigin+traceOffset, endOrigin+traceOffset ), endOrigin+traceOffset ) );
    			
    		if ( startOrigin[2] < endOrigin[2] )
    		{
    			startOrigin += (0,0,128);
    		}
    		else if ( startOrigin[2] > endOrigin[2] )
    		{
    			endOrigin += (0,0,128);
    		}
    		else
    		{	
    			startOrigin += (0,0,128);
    			endOrigin += (0,0,128);
    		}
    		
    		//thread draw_line( startOrigin+traceOffset, endOrigin+traceOffset, (0,1,9), 200 );
    		numTraces++;
    
    		traceOrigin = physicsTrace( startOrigin+traceOffset, endOrigin+traceOffset );
    	}
    	
    	offsets = [];
    	offsets["start"] = startOrigin;
    	offsets["end"] = endOrigin;
    	return offsets;
    }
    
    
    travelToNode( goalNode )
    {
    	originOffets = getOriginOffsets( goalNode );
    	
    	if ( originOffets["start"] != self.origin )
    	{
    		// motion change via node
    		if( isdefined( goalNode.script_airspeed ) && isdefined( goalNode.script_accel ) )
    		{
    			heli_speed = goalNode.script_airspeed;
    			heli_accel = goalNode.script_accel;
    		}
    		else
    		{
    			heli_speed = 30+randomInt(20);
    			heli_accel = 15+randomInt(15);
    		}
    		
    		self Vehicle_SetSpeed( heli_speed, heli_accel );
    		self setvehgoalpos( originOffets["start"] + (0,0,30), 0 );
    		// calculate ideal yaw
    		self setgoalyaw( goalNode.angles[ 1 ] + level.heli_angle_offset );
    		
    		//println( "setting goal to startOrigin" );
    		
    		self waittill ( "goal" );
    	}
    	
    	if ( originOffets["end"] != goalNode.origin )
    	{
    		// motion change via node
    		if( isdefined( goalNode.script_airspeed ) && isdefined( goalNode.script_accel ) )
    		{
    			heli_speed = goalNode.script_airspeed;
    			heli_accel = goalNode.script_accel;
    		}
    		else
    		{
    			heli_speed = 30+randomInt(20);
    			heli_accel = 15+randomInt(15);
    		}
    		
    		self Vehicle_SetSpeed( heli_speed, heli_accel );
    		self setvehgoalpos( originOffets["end"] + (0,0,30), 0 );
    		// calculate ideal yaw
    		self setgoalyaw( goalNode.angles[ 1 ] + level.heli_angle_offset );
    
    		//println( "setting goal to endOrigin" );
    		
    		self waittill ( "goal" );
    	}
    }
    
    
    heli_fly_simple_path( startNode )
    {
    	self endon ( "death" );
    	self endon ( "leaving" );
    
    	// only one thread instance allowed
    	self notify( "flying");
    	self endon( "flying" );
    	
    	heli_reset();
    	
    	currentNode = startNode;
    	while ( isDefined( currentNode.target ) )
    	{
    		nextNode = getEnt( currentNode.target, "targetname" );
    		assertEx( isDefined( nextNode ), "Next node in path is undefined, but has targetname" );
    		
    		if( isDefined( currentNode.script_airspeed ) && isDefined( currentNode.script_accel ) )
    		{
    			heli_speed = currentNode.script_airspeed;
    			heli_accel = currentNode.script_accel;
    		}
    		else
    		{
    			heli_speed = 30 + randomInt(20);
    			heli_accel = 15 + randomInt(15);
    		}
    
    		self Vehicle_SetSpeed( heli_speed, heli_accel );
    		
    		// end of the path
    		if ( !isDefined( nextNode.target ) )
    		{
    			self setVehGoalPos( nextNode.origin+(self.zOffset), true );
    			self waittill( "near_goal" );
    		}
    		else
    		{
    			self setVehGoalPos( nextNode.origin+(self.zOffset), false );
    			self waittill( "near_goal" );
    
    			self setGoalYaw( nextNode.angles[ 1 ] );
    
    			self waittillmatch( "goal" );
    		}
    
    		currentNode = nextNode;
    	}
    	
    	printLn( currentNode.origin );
    	printLn( self.origin );
    }
    
    
    heli_fly_loop_path( startNode )
    {
    	self endon ( "death" );
    	self endon ( "crashing" );
    	self endon ( "leaving" );
    
    	// only one thread instance allowed
    	self notify( "flying");
    	self endon( "flying" );
    	
    	heli_reset();
    	
    	self thread heli_loop_speed_control( startNode );
    	
    	currentNode = startNode;
    	while ( isDefined( currentNode.target ) )
    	{
    		nextNode = getEnt( currentNode.target, "targetname" );
    		assertEx( isDefined( nextNode ), "Next node in path is undefined, but has targetname" );
    		
    		if( isDefined( currentNode.script_airspeed ) && isDefined( currentNode.script_accel ) )
    		{
    			self.desired_speed = currentNode.script_airspeed;
    			self.desired_accel = currentNode.script_accel;
    		}
    		else
    		{
    			self.desired_speed = 30 + randomInt( 20 );
    			self.desired_accel = 15 + randomInt( 15 );
    		}
    		
    		if ( self.heliType == "flares" )
    		{
    			self.desired_speed *= 0.5;
    			self.desired_accel *= 0.5;
    		}
    		
    		if ( isDefined( nextNode.script_delay ) && isDefined( self.primaryTarget ) && !self heli_is_threatened() )
    		{
    			self setVehGoalPos( nextNode.origin+(self.zOffset), true );
    			self waittill( "near_goal" );
    
    			wait ( nextNode.script_delay );
    		}
    		else
    		{
    			self setVehGoalPos( nextNode.origin+(self.zOffset), false );
    			self waittill( "near_goal" );
    
    			self setGoalYaw( nextNode.angles[ 1 ] );
    
    			self waittillmatch( "goal" );
    		}
    
    		currentNode = nextNode;
    	}
    }
    
    
    heli_loop_speed_control( currentNode )
    {
    	self endon ( "death" );
    	self endon ( "crashing" );
    	self endon ( "leaving" );
    
    	if( isDefined( currentNode.script_airspeed ) && isDefined( currentNode.script_accel ) )
    	{
    		self.desired_speed = currentNode.script_airspeed;
    		self.desired_accel = currentNode.script_accel;
    	}
    	else
    	{
    		self.desired_speed = 30 + randomInt( 20 );
    		self.desired_accel = 15 + randomInt( 15 );
    	}
    	
    	lastSpeed = 0;
    	lastAccel = 0;
    	
    	while ( 1 )
    	{
    		goalSpeed = self.desired_speed;
    		goalAccel = self.desired_accel;
    		
    		if ( self.heliType != "flares" && isDefined( self.primaryTarget ) && !self heli_is_threatened() )
    			goalSpeed *= 0.25;
    					
    		if ( lastSpeed != goalSpeed || lastAccel != goalAccel )
    		{
    			self Vehicle_SetSpeed( goalSpeed, goalAccel );
    			
    			lastSpeed = goalSpeed;
    			lastAccel = goalAccel;
    		}
    		
    		wait ( 0.05 );
    	}
    }
    
    
    heli_is_threatened()
    {
    	if ( self.recentDamageAmount > 50 )
    		return true;
    
    	if ( self.currentState == "heavy smoke" )
    		return true;
    		
    	return false;	
    }
    
    
    heli_fly_well( destNodes )
    {
    	self notify( "flying");
    	self endon( "flying" );
    
    	self endon ( "death" );
    	self endon ( "crashing" );
    	self endon ( "leaving" );
    
    	for ( ;; )	
    	{
    		currentNode = self get_best_area_attack_node( destNodes );
    	
    		travelToNode( currentNode );
    		
    		// motion change via node
    		if( isdefined( currentNode.script_airspeed ) && isdefined( currentNode.script_accel ) )
    		{
    			heli_speed = currentNode.script_airspeed;
    			heli_accel = currentNode.script_accel;
    		}
    		else
    		{
    			heli_speed = 30+randomInt(20);
    			heli_accel = 15+randomInt(15);
    		}
    		
    		self Vehicle_SetSpeed( heli_speed, heli_accel );	
    		self setvehgoalpos( currentNode.origin + self.zOffset, 1 );
    		self setgoalyaw( currentNode.angles[ 1 ] + level.heli_angle_offset );	
    
    		if ( level.heli_forced_wait != 0 )
    		{
    			self waittill( "near_goal" ); //self waittillmatch( "goal" );
    			wait ( level.heli_forced_wait );			
    		}
    		else if ( !isdefined( currentNode.script_delay ) )
    		{
    			self waittill( "near_goal" ); //self waittillmatch( "goal" );
    
    			wait ( 5 + randomInt( 5 ) );
    		}
    		else
    		{				
    			self waittillmatch( "goal" );				
    			wait ( currentNode.script_delay );
    		}
    	}
    }
    
    
    get_best_area_attack_node( destNodes )
    {
    	return updateAreaNodes( destNodes );
    }
    
    
    // helicopter leaving parameter, can not be damaged while leaving
    heli_leave()
    {
    	self notify( "leaving" );
    
    	leaveNode = level.heli_leave_nodes[ randomInt( level.heli_leave_nodes.size ) ];
    	
    	self heli_reset();
    	self Vehicle_SetSpeed( 100, 45 );	
    	self setvehgoalpos( leaveNode.origin, 1 );
    	self waittillmatch( "goal" );
    	self notify( "death" );
    	
    	// give "death" notify time to process
    	wait ( 0.05 );
    	self delete();
    }
    
    
    // ==================================================  ==================================
    // 								DEBUG INFORMATION
    // ==================================================  ==================================
    
    debug_print3d( message, color, ent, origin_offset, frames )
    {
    	if ( isdefined( level.heli_debug ) && level.heli_debug == 1.0 )
    		self thread draw_text( message, color, ent, origin_offset, frames );
    }
    
    debug_print3d_simple( message, ent, offset, frames )
    {
    	if ( isdefined( level.heli_debug ) && level.heli_debug == 1.0 )
    	{
    		if( isdefined( frames ) )
    			thread draw_text( message, ( 0.8, 0.8, 0.8 ), ent, offset, frames );
    		else
    			thread draw_text( message, ( 0.8, 0.8, 0.8 ), ent, offset, 0 );
    	}
    }
    
    debug_line( from, to, color, frames )
    {
    	if ( isdefined( level.heli_debug ) && level.heli_debug == 1.0 && !isdefined( frames ) )
    	{
    		thread draw_line( from, to, color );
    	}
    	else if ( isdefined( level.heli_debug ) && level.heli_debug == 1.0 )
    		thread draw_line( from, to, color, frames);
    }
    
    draw_text( msg, color, ent, offset, frames )
    {
    	//level endon( "helicopter_done" );
    	if( frames == 0 )
    	{
    		while ( isdefined( ent ) )
    		{
    			print3d( ent.origin+offset, msg , color, 0.5, 4 );
    			wait 0.05;
    		}
    	}
    	else
    	{
    		for( i=0; i < frames; i++ )
    		{
    			if( !isdefined( ent ) )
    				break;
    			print3d( ent.origin+offset, msg , color, 0.5, 4 );
    			wait 0.05;
    		}
    	}
    }
    
    draw_line( from, to, color, frames )
    {
    	//level endon( "helicopter_done" );
    	if( isdefined( frames ) )
    	{
    		for( i=0; i<frames; i++ )
    		{
    			line( from, to, color );
    			wait 0.05;
    		}		
    	}
    	else
    	{
    		for( ;; )
    		{
    			line( from, to, color );
    			wait 0.05;
    		}
    	}
    }
    
    
    
    addToHeliList()
    {
    	level.helis[self getEntityNumber()] = self;	
    }
    
    removeFromHeliList( entityNumber )
    {
    	level.helis[entityNumber] = undefined;
    }	
    
    
    playFlareFx()
    {
    	for ( i = 0; i < 10; i++ )
    	{
    		if ( !isDefined( self ) )
    			return;
    		PlayFXOnTag( level._effect[ "ac130_flare" ], self, "TAG_FLARE" );
    		wait ( 0.15 );
    	}
    }
    
    
    deployFlares()
    {
    	flareObject = spawn( "script_origin", level.ac130.planemodel.origin );
    	flareObject.angles = level.ac130.planemodel.angles;
    
    	flareObject moveGravity( (0, 0, 0), 5.0 );
    	
    	flareObject thread deleteAfterTime( 5.0 );
    
    	return flareObject;
    }
    
    
    heli_flares_monitor()
    {
    	level endon ( "game_ended" );
    	
    	for ( ;; )
    	{
    		level waittill ( "stinger_fired", player, missile, lockTarget );
    		
    		if ( !IsDefined( lockTarget ) || (lockTarget != self) )
    			continue;
    		
    		missile endon ( "death" );
    		
    		self thread playFlareFx();	
    		newTarget = self deployFlares();
    		missile Missile_SetTargetEnt( newTarget );
    		return;
    	}	
    }
    
    deleteAfterTime( delay )
    {
    	wait ( delay );
    	
    	self delete();
    }
    Current bugs:
    Using chopper gunner will crash the game
    No weapon when the chopper has ended
    -------------------------------------------------
    Should probably be used for a mod where you sett killstreaks to none, and use
    self maps\mp\killstreaks\_killstreaks::giveKillstreak( "helicopter", false );
    Upcoming fix for the weapon bug might come soon
    Last edited by Arasonic; 11-20-2010 at 05:45 PM.

  2. The Following 2 Users Say Thank You to Arasonic For This Useful Post:

    solha (11-21-2010),Yamato (11-21-2010)

  3. #2
    jimmynguyen3030's Avatar
    Join Date
    Sep 2010
    Gender
    male
    Location
    NukeTown
    Posts
    263
    Reputation
    10
    Thanks
    18
    My Mood
    Bored
    cool how to change shake? theres actully no point for tht though
    If I Helped You, Plz Thanks.
    It Would Help Alot

    What Do You Do For A Living?
    I Mostly Own Noobs With The AK-47 With Silencer
    What's That?
    (Turns To Friend)
    HAHAHA Noob!!!!!!
    [img]https://www.danasof*****m/sig/asd248737.jpg[/img]

  4. #3
    Arasonic's Avatar
    Join Date
    Jun 2010
    Gender
    male
    Posts
    569
    Reputation
    11
    Thanks
    115
    Making it realistic, shooting those big bullets from a small heli? lawl.

    Find
    Code:
    weaponFiredThread( chopper )
    {
          self endon ( "death" );
          self endon ( "helicopter_done" );
    
    	for(;;)
    	{
    		self waittill( "weapon_fired" );
    		
    		weapon = self getCurrentWeapon();
    		
    		if ( weapon == "ac130_105mm_mp" )
    		{		
    			earthquake (2, 1, chopper.origin, 1000);
    		}
    		else if ( weapon == "ac130_40mm_mp" )
    		{
    			earthquake (0.5, 1, chopper.origin, 1000);
    		}
    
    		if ( self getWeaponAmmoClip( weapon ) )
    			continue;
    			
    		self thread weaponReload( weapon );
    	}
    }
    And change the eartquake to what you want

  5. #4
    master131's Avatar
    Join Date
    Apr 2010
    Gender
    male
    Location
    Melbourne, Australia
    Posts
    8,858
    Reputation
    3438
    Thanks
    101,662
    My Mood
    Breezy
    earthquake function.
    Donate:
    BTC: 1GEny3y5tsYfw8E8A45upK6PKVAEcUDNv9


    Handy Tools/Hacks:
    Extreme Injector v3.7.3
    A powerful and advanced injector in a simple GUI.
    Can scramble DLLs on injection making them harder to detect and even make detected hacks work again!

    Minion Since: 13th January 2011
    Moderator Since: 6th May 2011
    Global Moderator Since: 29th April 2012
    Super User/Unknown Since: 23rd July 2013
    'Game Hacking' Team Since: 30th July 2013

    --My Art--
    [Roxas - Pixel Art, WIP]
    [Natsu - Drawn]
    [Natsu - Coloured]


    All drawings are coloured using Photoshop.

    --Gifts--
    [Kyle]

  6. #5
    Wolfeman's Avatar
    Join Date
    Jul 2010
    Gender
    male
    Location
    look behind you
    Posts
    137
    Reputation
    10
    Thanks
    8
    My Mood
    Tired
    made by AgentGOD (the 1st but not good one) but.... nice release!
    BEST CL PATCH EVER!!!

  7. #6
    Arasonic's Avatar
    Join Date
    Jun 2010
    Gender
    male
    Posts
    569
    Reputation
    11
    Thanks
    115
    It's made before?

    And I dont like adding lots of smileys, but now I think it fits

  8. #7
    spiritwo's Avatar
    Join Date
    Aug 2010
    Gender
    male
    Location
    Rochester, NY
    Posts
    709
    Reputation
    17
    Thanks
    76
    My Mood
    Happy
    Very nice Very nice
    --
    "Life is tough. It's tougher if you're stupid."

    Spiritwo |






  9. #8
    panzerbjørn's Avatar
    Join Date
    Oct 2010
    Gender
    male
    Location
    Pizza Hut...
    Posts
    305
    Reputation
    7
    Thanks
    17
    My Mood
    Angelic
    Super uber cool

  10. #9
    cgallagher21's Avatar
    Join Date
    Jun 2010
    Gender
    male
    Posts
    1,627
    Reputation
    11
    Thanks
    325
    My Mood
    Angelic
    Wow nice goodjob

  11. #10
    Yamato's Avatar
    Join Date
    Jul 2010
    Gender
    male
    Posts
    839
    Reputation
    13
    Thanks
    154
    My Mood
    Amazed
    Very cool chronalis, gj

  12. #11
    jimmynguyen3030's Avatar
    Join Date
    Sep 2010
    Gender
    male
    Location
    NukeTown
    Posts
    263
    Reputation
    10
    Thanks
    18
    My Mood
    Bored
    offtopic so what mod now? drive a uav?
    If I Helped You, Plz Thanks.
    It Would Help Alot

    What Do You Do For A Living?
    I Mostly Own Noobs With The AK-47 With Silencer
    What's That?
    (Turns To Friend)
    HAHAHA Noob!!!!!!
    [img]https://www.danasof*****m/sig/asd248737.jpg[/img]

  13. #12
    Yamato's Avatar
    Join Date
    Jul 2010
    Gender
    male
    Posts
    839
    Reputation
    13
    Thanks
    154
    My Mood
    Amazed
    Quote Originally Posted by jimmynguyen3030 View Post
    offtopic so what mod now? drive a uav?
    I have done that using the FlyableJetMod by 4funplaying, ^^

    Chronalis: you can try to do some new air strike, for exaple a UAV that comes and drop a bomb or something like that

  14. #13
    Arasonic's Avatar
    Join Date
    Jun 2010
    Gender
    male
    Posts
    569
    Reputation
    11
    Thanks
    115
    In making, or atleast tomorrow:

    Blackbird
    Packapunch
    Easy cash system, 'cause I really dont understand a shit from other mods.

    If you got any ideas, please tell me in the thread i made in the gsc modding help section
    ---------------------------
    Nao, get on topic of theres something you want to say

  15. #14
    xbeatsszzx's Avatar
    Join Date
    Feb 2010
    Gender
    male
    Location
    Behind a dumpster jerking off. xD jks
    Posts
    2,519
    Reputation
    13
    Thanks
    1,508
    My Mood
    Asleep
    Nice cool release.
    I Am on this site for the mods for mw2 ONLY. Not hacks.