IW4-Dump-Files/maps/_remotemissile.gsc

1675 lines
36 KiB
Plaintext

#include maps\_utility;
#include common_scripts\utility;
#include maps\_hud_util;
init()
{
//should make hellfires no do friendly fire
level.no_friendly_fire_splash_damage = true;
if ( !isdefined( level.min_time_between_uav_launches ) )
{
level.min_time_between_uav_launches = 12 * 1000;
}
level.last_uav_launch_time = 0 - level.min_time_between_uav_launches;
// level.last_uav_offline_time = 0;
level.uav_radio_offline_called = false;
PreCacheItem( "remote_missile_detonator" );
PreCacheItem( "remote_missile" );
PreCacheShader( "veh_hud_target" );
PreCacheShader( "veh_hud_target_offscreen" );
PreCacheShader( "veh_hud_missile_flash" );
PreCacheShader( "ac130_overlay_grain" );
PreCacheShader( "remotemissile_infantry_target" );
PreCacheShader( "hud_fofbox_self_sp" );
PreCacheShader( "dpad_killstreak_hellfire_missile_inactive" );
precacheString( &"HELLFIRE_DRONE_VIEW" );
precacheString( &"HELLFIRE_MISSILE_VIEW" );
precacheString( &"HELLFIRE_FIRE" );
// Predator Drone has been destroyed.
add_hint_string( "hint_predator_drone_destroyed", &"HELLFIRE_DESTROYED", ::should_break_destroyed );
// Predator Drone is unavailable.
add_hint_string( "hint_predator_drone_4", &"HELLFIRE_USE_DRONE", ::should_break_use_drone );
add_hint_string( "hint_predator_drone_2", &"HELLFIRE_USE_DRONE_2", ::should_break_use_drone );
add_hint_string( "hint_predator_drone_not_available", &"HELLFIRE_DRONE_NOT_AVAILABLE", ::should_break_available );
// array_thread( level.players, ::RemoteMissileDetonatorNotify );
VisionSetMissilecam( "missilecam" );
SetSavedDvar( "missileRemoteSpeedUp", "1000" );
SetSavedDvar( "missileRemoteSpeedTargetRange", "6000 12000" );
mapname = GetDvar( "mapname" );
if ( mapname == "zzz" )
{
}
else if ( mapname == "raymetest" )
{
SetSavedDvar( "missileRemoteSpeedUp", "500" );
SetSavedDvar( "missileRemoteSpeedTargetRange", "3000 6000" );
}
add_global_spawn_function( "axis", ::missile_kill_ai );
flag_init( "uav_reloading" );
flag_init( "uav_collecting_stats" );
flag_init( "uav_enabled" );
flag_set( "uav_enabled" );
}
should_break_use_drone()
{
break_hint = false;
if ( isdefined( level.uav_is_destroyed ) )
{
break_hint = true;
}
if ( !isalive( level.uav ) )
{
break_hint = true;
}
if ( isdefined( self.is_flying_missile ) )
{
break_hint = true;
}
// Sniper Fi Support
if ( flag_exist( "wave_wiped_out" ) && flag( "wave_wiped_out" ) )
{
break_hint = true;
}
if ( self ent_flag_exist( "coop_downed" ) && self ent_flag( "coop_downed" ) )
{
break_hint = true;
}
if( self getCurrentWeapon() == "remote_missile_detonator" )
{
break_hint = true;
}
return break_hint;
}
init_radio_dialogue()
{
if ( !IsDefined( level.scr_radio ) )
{
level.scr_radio = [];
}
level.uav_radio_initialized = true;
// Offline / Online
level.scr_radio[ "uav_reloading" ] = "cont_cmt_rearmhellfires";
level.scr_radio[ "uav_offline" ] = "cont_cmt_hellfiresoffline";
level.scr_radio[ "uav_online" ] = "cont_cmt_hellfireonline";
level.scr_radio[ "uav_online_repeat" ] = "cont_cmt_repeatonline";
level.scr_radio[ "uav_down" ] = "cont_cmt_uavdown";
// AI Kills
level.scr_radio[ "uav_multi_kill" ] = "cont_cmt_mutlipleconfirmed";
level.scr_radio[ "uav_multi_kill2" ] = "cont_cmt_fivepluskias";
level.scr_radio[ "uav_few_kills" ] = "cont_cmt_theyredown";
level.scr_radio[ "uav_3_kills" ] = "cont_cmt_3kills";
level.scr_radio[ "uav_1_kill" ] = "cont_cmt_hesdown";
// vehicle kills
level.scr_radio[ "uav_btr_kill" ] = "cont_cmt_mutlipleconfirmed";
level.scr_radio[ "uav_few_kills" ] = "cont_cmt_theyredown";
level.scr_radio[ "uav_3_kills" ] = "cont_cmt_3kills";
level.scr_radio[ "uav_1_kill" ] = "cont_cmt_hesdown";
level.scr_radio[ "uav_multi_vehicle_kill" ] = "cont_cmt_goodhitvehicles";
level.scr_radio[ "uav_multi_vehicle_kill2" ] = "cont_cmt_goodeffectkia";
level.scr_radio[ "uav_helo_kill" ] = "cont_cmt_directhitshelo";
level.scr_radio[ "uav_btr_kill" ] = "cont_cmt_btrdestroyed";
level.scr_radio[ "uav_truck_kill" ] = "cont_cmt_goodkilltruck";
level.scr_radio[ "uav_jeep_kill" ] = "cont_cmt_directhitjeep";
level.scr_radio[ "uav_direct_hit" ] = "cont_cmt_directhit";
}
is_radio_defined( alias )
{
return IsDefined( level.scr_radio[ alias ] ) || IsDefined( level.scr_radio[ alias + "_variant" ] );
}
should_break_available()
{
if ( IsDefined( level.uav_is_not_available ) )
return false;
else
return true;
}
should_break_destroyed()
{
if ( IsDefined( level.uav_is_destroyed ) )
return false;
else
return true;
}
enable_uav( do_radio, restore )
{
if ( !IsDefined( do_radio ) )
{
do_radio = true;
}
if ( !flag( "uav_enabled" ) )
{
flag_set( "uav_enabled" );
if ( !flag( "uav_reloading" ) && do_radio )
{
thread remotemissile_radio( "uav_online" );
}
}
if ( IsDefined( restore ) )
{
restore_uav_weapon( restore );
}
}
disable_uav( do_radio, remove )
{
if ( !IsDefined( do_radio ) )
{
do_radio = true;
}
if ( flag( "uav_enabled" ) )
{
flag_clear( "uav_enabled" );
if ( !flag( "uav_reloading" ) && do_radio )
{
thread remotemissile_radio( "uav_offline" );
}
}
if ( IsDefined( remove ) )
{
remove_uav_weapon();
}
}
restore_uav_weapon( restore )
{
if ( IsDefined( level.uav_is_destroyed ) )
{
return;
}
if ( IsString( restore ) )
{
weapon = restore;
}
else if ( IsDefined( self.uav_weaponname ) )
{
weapon = self.uav_weaponname;
}
else
{
return;
}
if ( !self HasWeapon( weapon ) )
{
return;
}
self SetWeaponHudIconOverride( "actionslot" + self get_remotemissile_actionslot(), "none" );
self SetActionSlot( self get_remotemissile_actionslot(), "weapon", weapon );
}
remove_uav_weapon()
{
self SetWeaponHudIconOverride( "actionslot" + self get_remotemissile_actionslot(), "dpad_killstreak_hellfire_missile_inactive" );
self SetActionSlot( self get_remotemissile_actionslot(), "" );
}
is_remote_missile_weapon( weap )
{
if ( !IsDefined( weap ) )
{
return false;
}
if ( weap == "remote_missile_detonator" )
{
return true;
}
if ( weap == "remote_missile_detonator_finite" )
{
return true;
}
return false;
}
give_remotemissile_weapon( weapon_name )
{
self set_remotemissile_actionslot();
self SetActionSlot( self get_remotemissile_actionslot(), "weapon", weapon_name );
self GiveWeapon( weapon_name );
self thread RemoteMissileDetonatorNotify();
}
// Sets the proper dpad depending if they have the claymore or not
set_remotemissile_actionslot()
{
if ( !self HasWeapon( "claymore" ) )
{
// Move the claymore (since we do not have it yet) to the down dpad
self.remotemissile_actionslot = 4;
}
else
{
self.remotemissile_actionslot = 2;
}
}
get_remotemissile_actionslot()
{
AssertEx( IsDefined( self.remotemissile_actionslot ), "self.remotemissile_actionslot is undefined, you need to use the give_remotemissile_weapon() function in here to give the player the weapon properly." );
return self.remotemissile_actionslot;
}
remotemissile_weapon_change()
{
self.using_uav = false;
while ( 1 )
{
self waittill( "weapon_change", weap );
if ( is_remote_missile_weapon( weap ) )
{
self.using_uav = true;
if ( IsDefined( level.uav_is_destroyed ) )
{
thread remotemissile_offline( false, "uav_down" );
self SwitchToWeapon( self.last_weapon );
self.using_uav = false;
continue;
}
if ( self ent_flag_exist( "coop_downed" ) && self ent_flag( "coop_downed" ) )
{
self SwitchBackToMainWeapon();
self.using_uav = false;
continue;
}
self.uav_weaponname = weap;
self thread cancel_on_player_damage();
if ( IsDefined( level.remote_missile_hide_stuff_func ) )
{
[[ level.remote_missile_hide_stuff_func ]]();
}
level.uav_user = self;
level.uav_killstats = [];
UAVRemoteLauncherSequence( self, weap );
level.uav_user = undefined;
self.using_uav = false;
if ( IsDefined( level.remote_missile_show_stuff_func ) )
{
[[ level.remote_missile_show_stuff_func ]]();
}
thread remotemissile_reload();
}
}
}
RemoteMissileDetonatorNotify()
{
Assert( self.classname == "player" );
self NotifyOnPlayerCommand( "switch_to_remotemissile", "+actionslot " + self get_remotemissile_actionslot() );
self thread remotemissile_weapon_change();
for ( ;; )
{
self waittill( "switch_to_remotemissile" );
if ( self.using_uav )
{
continue;
}
if ( !is_remote_missile_weapon( self GetCurrentWeapon() ) )
{
self.last_weapon = self GetCurrentWeapon();
}
if ( IsDefined( level.uav_is_destroyed ) )
{
thread remotemissile_offline( false, "uav_down" );
}
else if ( flag( "uav_reloading" ) || !flag( "uav_enabled" ) )
{
thread remotemissile_offline( true );
}
}
}
remotemissile_offline( extra_check, alias )
{
if ( !IsDefined( alias ) )
{
alias = "uav_offline";
}
curr_time = GetTime();
// Only use extra_check if you don't want the dialogue to happen just before the hellfire "online" is about to
// play
if ( extra_check && ( ( level.last_uav_launch_time + level.min_time_between_uav_launches ) - curr_time < 2000 ) || level.min_time_between_uav_launches < 5000 )
{
// These 2 checks are specific to levels.
// SO_ROOFTOP_CONTINGENCY needs dialogue if out of ammo.
// All other levels need uav_is_destroyed
if ( !IsDefined( level.uav_is_destroyed ) && ( IsDefined( self.uav_weaponname ) && self GetWeaponAmmoClip( self.uav_weaponname ) > 0 ) )
{
return;
}
}
if( flag( "uav_reloading" ) )
{
if( isdefined( level.scr_radio[ "uav_reloading" ] ) )
{
alias = "uav_reloading";
}
}
// if ( !flag( "uav_collecting_stats" ) && curr_time > level.last_uav_offline_time + 1000 )
if ( !flag( "uav_collecting_stats" ) && !level.uav_radio_offline_called )
{
level.uav_radio_offline_called = true;
remotemissile_radio( alias );
level.uav_radio_offline_called = false;
}
}
remotemissile_reload()
{
level endon( "stop_uav_reload" );
level endon( "special_op_terminated" );
// Wait for reload
if ( flag( "uav_reloading" ) )
{
if ( IsDefined( level.uav_is_destroyed ) )
{
return;
}
remove_uav_weapon();
if ( flag( "uav_collecting_stats" ) )
{
level waittill( "uav_collecting_stats" );
play_kills_dialogue();
}
if ( IsDefined( level.uav_is_destroyed ) )
{
return;
}
// Make uav_user undefined so missile_kill_ai returns immediately.
level.uav_user = undefined;
//z: dont want to hear hellfire off line after each shot
// Only do the dialogue if we have enough time between reloads.
//if ( level.min_time_between_uav_launches > 5000 )
//{
// thread remotemissile_offline( false );
//}
// Waiting for the flag_clear() notify
if ( flag( "uav_reloading" ) )
{
level waittill( "uav_reloading" );
}
if ( IsDefined( level.uav_is_destroyed ) )
{
return;
}
if ( !flag( "uav_enabled" ) )
{
return;
}
if ( self GetWeaponAmmoClip( self.uav_weaponname ) < 1 )
{
disable_uav();
return;
}
restore_uav_weapon();
thread remotemissile_radio( "uav_online" );
thread remotemissile_radio_reminder();
}
}
remotemissile_radio_reminder()
{
level notify( "stop_remotemissile_radio_reminder" );
level endon( "special_op_terminated" );
level endon( "starting_predator_drone_control" );
level endon( "stop_remotemissile_radio_reminder" );
while( 1 )
{
wait( 7 + RandomInt( 4 ) );
if ( flag_exist( "special_op_terminated" ) && flag( "special_op_terminated" ) )
{
return;
}
if ( IsDefined( level.uav_is_destroyed ) )
{
return;
}
if ( flag( "uav_reloading" ) )
{
return;
}
if ( !flag( "uav_enabled" ) )
{
return;
}
remotemissile_radio( "uav_online_repeat" );
wait( 15 + RandomInt( 10 ) );
if ( flag_exist( "special_op_terminated" ) && flag( "special_op_terminated" ) )
{
return;
}
if ( IsDefined( level.uav_is_destroyed ) )
{
return;
}
if ( IsDefined( level.no_remote_missile_reminders ) )
{
return;
}
remotemissile_radio( "uav_online" );
self thread display_hint_timeout( "hint_predator_drone_" + self get_remotemissile_actionslot(), 6 );
}
}
play_kills_dialogue()
{
if ( IsDefined( level.dont_use_global_uav_kill_dialog ) )
return;
if ( !IsDefined( level.uav_radio_initialized ) )
{
return;
}
// "Good hit. Multiple vehicles destroyed." level.scr_radio[ "multi_vehicle_kill" ] = "cont_cmt_goodhitvehicles";
// "Good effect on target. Multiple enemy vehicles KIA." level.scr_radio[ "multi_vehicle_kill2" ] = "cont_cmt_goodeffectkia";
// "Direct hit on the enemy helo. Nice shot Roach." level.scr_radio[ "helo_kill" ] = "cont_cmt_directhitshelo";
// "Good effect on target. BTR destroyed." level.scr_radio[ "btr_kill" ] = "cont_cmt_btrdestroyed";
// "Good kill. Truck destroyed." level.scr_radio[ "truck_kill" ] = "cont_cmt_goodkilltruck";
// "Direct hit on that jeep." level.scr_radio[ "jeep_kill" ] = "cont_cmt_directhitjeep";
// "Direct hit." level.scr_radio[ "direct_hit" ] = "cont_cmt_directhit";
// "Five plus KIAs. Good hit. Good hit. level.scr_radio[ "multi_kill2" ] = "cont_cmt_fivepluskias";
// "Multiple confirmed kills. Nice work." level.scr_radio[ "multi_kill" ] = "cont_cmt_mutlipleconfirmed";
// "They're down." level.scr_radio[ "few_kills" ] = "cont_cmt_theyredown";
// "Good hit. Looks like at least three kills." level.scr_radio[ "3_kills" ] = "cont_cmt_3kills";
// "He's down." level.scr_radio[ "1_kill" ] = "cont_cmt_hesdown";
ai_alias = undefined;
ai_kills = 0;
if ( IsDefined( level.uav_killstats[ "ai" ] ) )
{
ai_kills = level.uav_killstats[ "ai" ];
}
if ( ai_kills > 5 )
{
ai_alias = "uav_multi_kill";
if ( is_radio_defined( "uav_multi_kill2" ) && cointoss() )
{
ai_alias = "uav_multi_kill2";
}
}
else if ( ai_kills >= 3 )
{
ai_alias = "uav_3_kills";
}
else if ( ai_kills > 1 )
{
ai_alias = "uav_few_kills";
}
else if ( ai_kills > 0 )
{
ai_alias = "uav_1_kill";
}
vehicle_alias = undefined;
btr_kills = 0;
vehicle_kills = 0;
btr_kills = 0;
helo_kills = 0;
jeep_kills = 0;
truck_kills = 0;
foreach ( index, kills in level.uav_killstats )
{
if ( index == "ai" )
{
continue;
}
if ( kills > 0 )
{
vehicle_kills = vehicle_kills + kills;
if ( index == "btr" )
{
btr_kills = kills;
}
else if ( index == "helo" )
{
helo_kills = kills;
}
else if ( index == "jeep" )
{
jeep_kills = kills;
}
else if ( index == "truck" )
{
truck_kills = kills;
}
}
}
alias = ai_alias;
if ( btr_kills > 0 )
{
alias = "uav_btr_kill";
}
else if ( helo_kills > 0 )
{
alias = "uav_helo_kill";
}
else if ( vehicle_kills > 1 )
{
alias = "uav_multi_vehicle_kill";
if ( is_radio_defined( "uav_multi_vehicle_kill2" ) && cointoss() )
{
alias = "uav_multi_vehicle_kill2";
}
}
else if ( jeep_kills > 0 )
{
alias = "uav_jeep_kill";
if ( ai_kills > 2 && ai_kills <= 5 && is_radio_defined( "uav_direct_hit" ) && cointoss() )
{
alias = "uav_direct_hit";
}
}
else if ( truck_kills > 0 )
{
alias = "uav_truck_kill";
if ( ai_kills > 2 && ai_kills <= 5 && is_radio_defined( "uav_direct_hit" ) && cointoss() )
{
alias = "uav_direct_hit";
}
}
if ( !IsDefined( alias ) )
{
return;
}
if ( flag_exist( "special_op_terminated" ) && flag( "special_op_terminated" ) )
{
return;
}
remotemissile_radio( alias );
level notify( "remote_missile_kill_dialogue" );
}
set_variant_remotemissile_radio( alias )
{
if ( IsDefined( level.scr_radio[ alias + "_variant" ] ) && IsArray( level.scr_radio[ alias + "_variant" ] ) )
{
level.scr_radio[ alias ] = level.scr_radio[ alias + "_variant" ][ RandomInt( level.scr_radio[ alias + "_variant" ].size ) ];
}
}
remotemissile_radio( alias )
{
if ( !IsDefined( level.uav_radio_initialized ) )
{
return;
}
if ( IsDefined( level.uav_radio_disabled ) && level.uav_radio_disabled )
{
return;
}
if ( !is_radio_defined( alias ) )
{
return;
}
if ( flag_exist( "special_op_terminated" ) && flag( "special_op_terminated" ) )
{
return;
}
set_variant_remotemissile_radio( alias );
radio_dialogue( alias );
}
cancel_on_player_damage()
{
self.took_damage = false;
//self waittill( "damage" );
self waittill_any( "damage", "dtest", "force_out_of_uav" );
self.took_damage = true;
}
text_TitleCreate()
{
level.text1 = self createClientFontString( "objective", 2.0 );
level.text1 setPoint( "CENTER", undefined, 0, -175 );
}
text_TitleSetText( text )
{
level.text1 SetText( text );
}
text_TitleFadeout()
{
level.text1 FadeOverTime( 0.25 );
level.text1.alpha = 0;
}
text_TitleDestroy()
{
if ( !IsDefined( level.text1 ) )
return;
level.text1 Destroy();
level.text1 = undefined;
}
display_wait_to_fire( time_till_reload )
{
text_NoticeDestroy();
// MISSILE RELOADED IN:
self text_LabelCreate( &"HELLFIRE_RELOADING_WITH_TIME", time_till_reload );
wait( 1 );
text_NoticeDestroy();
}
text_LabelCreate( text, time )
{
level.text2 = self createClientFontString( "objective", 1.85 );
level.text2 SetPoint( "CENTER", undefined, 0, -120 );
level.text2.label = text;
level.text2 SetValue( time );
level.text2.color = ( 0.85, 0.85, 0.85 );
level.text2.alpha = 0.75;
}
text_NoticeCreate( text )
{
level.text2 = self createClientFontString( "objective", 1.85 );
level.text2 SetPoint( "CENTER", undefined, 0, -120 );
level.text2 SetText( text );
level.text2.color = ( 0.85, 0.85, 0.85 );
level.text2.alpha = 0.75;
}
text_NoticeFadeout()
{
if ( !IsDefined( level.text2 ) )
return;
level.text2 FadeOverTime( 0.25 );
level.text2.alpha = 0;
}
text_NoticeDestroy()
{
if ( !IsDefined( level.text2 ) )
return;
level.text2 Destroy();
level.text2 = undefined;
}
WaitWithAbortOnDamage( time )
{
finishTime = GetTime() + ( time * 1000 );
while ( GetTime() < finishTime )
{
if ( self.took_damage )
{
return false;
}
if ( IsDefined( level.uav_is_destroyed ) )
{
return false;
}
if ( !flag( "uav_enabled" ) )
{
return false;
}
wait 0.05;
}
return true;
}
NotifyOnMissileDeath( missile )
{
timeWeFired = GetTime();
level.remoteMissileFireTime = timeWeFired;
if ( IsDefined( missile ) )
{
level.remoteMissile = missile;
missile waittill( "death" );
}
//defensive check; make sure we're this is still the latest remote missile
if ( IsDefined( level.remoteMissileFireTime ) && ( level.remoteMissileFireTime == timeWeFired ) )
{
level notify( "remote_missile_exploded" );
level.remoteMissile = undefined;
}
level delayThread( 0.2, ::send_notify, "delayed_remote_missile_exploded" );
}
AbortLaptopSwitch( player )
{
player VisionSetNakedForPlayer( level.lvl_visionset, 0.5 );
player VisionSetThermalForPlayer( level.visionThermalDefault, 0.5 );
player SwitchBackToMainWeapon();
player FreezeControls( false );
player EnableOffhandWeapons();
level.uavTargetEnt = undefined;
wait 0.1;
HudItemsShow();
}
UAVRemoteLauncherSequence( player, weap )
{
if ( weap == "remote_missile_detonator" )
{
player GiveMaxAmmo( weap );
}
level notify( "starting_predator_drone_control" );
delay_switch_into_missile = false;
return_to_uav_after_impact = false;
level.VISION_BLACK = "black_bw";
if ( !isdefined( level.VISION_UAV ) )
{
level.VISION_UAV = "ac130";
}
level.VISION_MISSILE = "missilecam";
level.uavPlayerOrigin = player GetOrigin();
level.uavPlayerAngles = player GetPlayerAngles();
player DisableOffhandWeapons();
player FreezeControls( true );
noDamage = player WaitWithAbortOnDamage( 1.0 );
if ( !noDamage )
{
AbortLaptopSwitch( player );
return;
}
trans_time = .25;
player VisionSetNakedForPlayer( level.VISION_BLACK, trans_time );
player VisionSetThermalForPlayer( level.VISION_BLACK, trans_time );
HudItemsHide();
if ( IsDefined( level.remote_missile_targets ) && ( level.remote_missile_targets.size > 0 ) )
{
foreach ( thing in level.remote_missile_targets )
{
if ( !isalive( thing ) )
level.remote_missile_targets = array_remove( level.remote_missile_targets, thing );
}
}
noDamage = WaitWithAbortOnDamage( trans_time );
if ( !noDamage )
{
AbortLaptopSwitch( player );
return;
}
player.is_controlling_UAV = true;
level notify( "player_is_controlling_UAV" );
if( isdefined( level.uav ) )
{
if ( is_specialop() )
{
level.uav HideOnClient( self );
}
else
{
level.uav Hide();
}
}
player PlayerLinkWeaponViewToDelta( level.uavRig, "tag_player", 1.0, 4, 4, 4, 4 );
player FreezeControls( false );
player HideViewModel();
wait 0.05;
player text_TitleCreate();
// CAMERA: UAV_DRONE_011
text_TitleSetText( &"HELLFIRE_DRONE_VIEW" );
maps\_load::thermal_EffectsOn();
player ThermalVisionOn();
player SetPlayerAngles( level.uavRig GetTagAngles( "tag_origin" ) );
player VisionSetNakedForPlayer( level.lvl_visionset, 0.25 );
player VisionSetThermalForPlayer( level.VISION_UAV, 0.25 );
thread DrawTargetsStart();
wait 0.2;
doAttack = WaitForAttackCommand( player );
if ( !doAttack )
{
ExitFromCamera_UAV( player, player.took_damage );
return;
}
level.last_uav_launch_time = GetTime();
thread uav_reload();
level notify( "player_fired_remote_missile" );
missile = FireMissileFromUAVPlayer( player );
missile thread do_physics_impact_on_explosion( player );
if ( delay_switch_into_missile )
{
// -MISSILE LAUNCHED-
player text_NoticeCreate( &"HELLFIRE_FIRE" );
noDamage = WaitWithAbortOnDamage( 1.2 );
if ( !noDamage )
{
ExitFromCamera_UAV( player, true );
return;
}
text_NoticeFadeout();
DrawTargetsEnd();
//player VisionSetThermalForPlayer( level.VISION_BLACK, 0.25 );
wait 0.25;
}
player.is_flying_missile = true;// used to break the hint
// CAMERA: HELLFIRE
text_TitleSetText( &"HELLFIRE_MISSILE_VIEW" );
text_NoticeDestroy();
SwitchBackToMainWeaponFast();
player RemoteCameraSoundscapeOn();
player Unlink();
//player VisionSetThermalForPlayer( level.VISION_MISSILE, 0.5 );
player DisableWeapons();
player CameraLinkTo( missile, "tag_origin" );
player ControlsLinkTo( missile );
noDamage = WaitWithAbortOnDamage( 0.2 );
if ( !noDamage )
{
ExitFromCamera_Missile( player, true );
return;
}
thread DrawTargetsStart();
while ( IsDefined( level.remoteMissile ) )
{
wait 0.05;
if ( IsDefined( level.uav_is_destroyed ) )
{
ExitFromCamera_Missile( player, true );
return;
}
if ( player.took_damage )
{
ExitFromCamera_Missile( player, true );
return;
}
if ( !flag( "uav_enabled" ) )
{
ExitFromCamera_Missile( player, true );
return;
}
}
if ( !isdefined( level.uav ) )
{
ExitFromCamera_Missile( player, false );
return;
}
if ( return_to_uav_after_impact )
{
//new - go back to uav to see explosion
level.uav Hide();
SetSavedDvar( "cg_fov", 26 );
player.fov_is_altered = true;
player.is_flying_missile = undefined;
player ControlsUnlink();
player CameraUnlink();
player RemoteCameraSoundscapeOff();
player PlayerLinkWeaponViewToDelta( level.uavRig, "tag_player", 1.0, 4, 4, 4, 4 );
player SetPlayerAngles( level.uavRig GetTagAngles( "tag_origin" ) );
noDamage = WaitWithAbortOnDamage( 2 );
if ( !noDamage )
{
ExitFromCamera_UAV( player, player.took_damage );
return;
}
ExitFromCamera_UAV( player, false );
}
else
{
ExitFromCamera_Missile( player, false );
}
}
uav_reload()
{
level endon( "stop_uav_reload" );
flag_set( "uav_reloading" );
wait( level.min_time_between_uav_launches * 0.001 );
flag_clear( "uav_reloading" );
}
do_physics_impact_on_explosion( player )
{
player.fired_hellfire_missile = true;
player waittill( "projectile_impact", weaponName, position, radius );
level thread missile_kills( player );
level.uavTargetPos = position;
physicsSphereRadius = 1000;
physicsSphereForce = 6.0;
Earthquake( .3, 1.4, position, 8000 );
wait 0.1;
PhysicsExplosionSphere( position, physicsSphereRadius, physicsSphereRadius / 2, physicsSphereForce );
wait 2;
level.uavTargetPos = undefined;
player.fired_hellfire_missile = undefined;
//level notify ( "player_missile_finished_impact" );
}
missile_kills( player )
{
flag_set( "uav_collecting_stats" );
// ai_array = GetAIArray( "axis" );
// foreach ( ai in ai_array )
// {
// ai thread missile_kill_ai( player );
// }
vehicles = getVehicleArray();
foreach ( vehicle in vehicles )
{
vehicle thread missile_kill_vehicle( player );
}
wait( 1 );
flag_clear( "uav_collecting_stats" );
}
missile_kill_ai( attacker )
{
if ( !IsDefined( level.uav_radio_initialized ) )
{
return;
}
self waittill( "death", attacker, cause );
if ( !IsDefined( level.uav_user ) )
{
return;
}
if ( !IsDefined( level.uav_killstats[ "ai" ] ) )
{
level.uav_killstats[ "ai" ] = 0;
}
if ( IsDefined( attacker ) && IsDefined( level.uav_user ) )
{
if ( attacker == level.uav_user || ( IsDefined( attacker.attacker ) && attacker.attacker == level.uav_user ) )
{
level.uav_killstats[ "ai" ]++;
if( isplayer( level.uav_user ) && level.uav_killstats[ "ai" ] == 10 )
level.uav_user player_giveachievement_wrapper( "TEN_PLUS_FOOT_MOBILES" );
}
}
}
missile_kill_vehicle( player )
{
if ( !IsDefined( level.uav_radio_initialized ) )
{
return;
}
level endon( "delayed_remote_missile_exploded" );
type = undefined;
switch( self.vehicletype )
{
case "btr80":
case "btr80_physics":
type = "btr";
break;
case "ucav":
case "hind":
case "mi17":
case "mi17_noai":
case "mi17_bulletdamage":
type = "helo";
break;
case "uaz":
case "uaz_physics":
type = "jeep";
break;
case "bm21":
case "bm21_drivable":
case "bm21_troops":
type = "truck";
break;
default:
type = "vehicle";
break;
}
if ( !IsDefined( level.uav_killstats[ type ] ) )
{
level.uav_killstats[ type ] = 0;
}
self waittill( "death", attacker, cause );
if ( ( type == "helo" || type == "btr" ) || IsDefined( self.riders ) && self.riders.size > 0 )
{
if ( IsDefined( attacker ) && attacker == player )
{
level.uav_killstats[ type ]++;
}
}
}
ExitFromCamera_Missile( player, reasonIsPain )
{
player.is_flying_missile = undefined;
text_TitleDestroy();
DrawTargetsEnd();
if ( IsDefined( level.uav_is_destroyed ) )
thread staticEffect( .5 );
player ControlsUnlink();
player CameraUnlink();
maps\_load::thermal_EffectsOff();
player ThermalVisionOff();
player RemoteCameraSoundscapeOff();
player VisionSetThermalForPlayer( level.visionThermalDefault, 0 );
if ( IsDefined( level.uav ) )
{
if ( is_specialop() )
{
level.uav ShowOnClient( self );
}
else
{
level.uav Show();
}
}
if ( reasonIsPain )
{
//fast switch back - go right to weapon, no flash
player VisionSetNakedForPlayer( level.VISION_BLACK, 0 );
wait 0.05;
player VisionSetNakedForPlayer( level.lvl_visionset, 0.4 );
player EnableWeapons();
player FreezeControls( false );
player ShowViewModel();
wait 0.2;
HudItemsShow();
player EnableOffhandWeapons();
}
else
{
//slow switch back - flash from missile explosion
player VisionSetNakedForPlayer( "coup_sunblind", 0 );
player FreezeControls( true );
wait 0.05;
player VisionSetNakedForPlayer( level.lvl_visionset, 1.0 );
player EnableWeapons();
player ShowViewModel();
wait 0.5;
HudItemsShow();
player EnableOffhandWeapons();
player FreezeControls( false );
}
player.is_controlling_UAV = undefined;
level.uavTargetEnt = undefined;
}
ExitFromCamera_UAV( player, reasonIsPain )
{
DrawTargetsEnd();
text_TitleFadeout();
text_NoticeFadeout();
player VisionSetNakedForPlayer( level.VISION_BLACK, 0.25 );
player VisionSetThermalForPlayer( level.VISION_BLACK, 0.25 );
if ( IsDefined( level.uav_is_destroyed ) )
player thread staticEffect( .5 );
wait 0.15;
wait 0.35;
text_TitleDestroy();
text_NoticeDestroy();
player Unlink();
player VisionSetThermalForPlayer( level.visionThermalDefault, 0 );
maps\_load::thermal_EffectsOff();
player ThermalVisionOff();
if ( IsDefined( player.fov_is_altered ) )
SetSavedDvar( "cg_fov", 65 );
if ( IsDefined( level.uav ) )
{
if ( is_specialop() )
{
level.uav ShowOnClient( self );
}
else
{
level.uav Show();
}
}
if ( reasonIsPain )
{
//fast switch back - go right to weapon
player SwitchBackToMainWeaponFast();
player FreezeControls( true );
wait 0.15;
player VisionSetNakedForPlayer( level.lvl_visionset, 0.4 );
player EnableWeapons();
player ShowViewModel();
wait 0.10;
HudItemsShow();
player EnableOffhandWeapons();
player FreezeControls( false );
}
else
{
//slow switch back - show laptop, etc
player FreezeControls( true );
wait 0.05;
player VisionSetNakedForPlayer( level.lvl_visionset, 0.75 );
player EnableWeapons();
player ShowViewModel();
wait 0.5;
HudItemsShow();
player SwitchBackToMainWeapon();
player EnableOffhandWeapons();
player FreezeControls( false );
}
player.is_controlling_UAV = undefined;
level.uavTargetEnt = undefined;
return;
}
WaitForAttackCommand( player )
{
// I'd like to use GetCommandFromKey to make this "proper" incase of different keybindings
// but it's not mp friendly...
// dpad_left = GetCommandFromKey( "DPAD_LEFT" );
// dpad_left = GetCommandFromKey( "BUTTON_Y" );
// dpad_left = GetCommandFromKey( "BUTTON_B" );
// player NotifyOnPlayerCommand( "abort_remote_missile", "+actionslot 3" ); // DPad Left
player NotifyOnPlayerCommand( "abort_remote_missile", "weapnext" ); // BUTTON_Y
player NotifyOnPlayerCommand( "abort_remote_missile", "+stance" ); // BUTTON_B
player NotifyOnPlayerCommand( "launch_remote_missile", "+attack" ); // BUTTON_RTRIG
player thread wait_for_other();
player thread wait_for_command_thread( "abort_remote_missile", "abort" );
player thread wait_for_command_thread( "launch_remote_missile", "launch" );
player waittill( "remote_missile_attack", val );
if ( val == "launch" )
{
return true;
}
else
{
return false;
}
}
wait_for_command_thread( msg, val )
{
self endon( "remote_missile_attack" );
self waittill( msg );
self notify( "remote_missile_attack", val );
}
wait_for_other()
{
self endon( "remote_missile_attack" );
for ( ;; )
{
wait( 0.05 );
if ( self.took_damage )
{
break;
}
if ( !flag( "uav_enabled" ) )
{
break;
}
if ( IsDefined( level.uav_is_destroyed ) )
{
break;
}
}
self notify( "remote_missile_attack", "abort" );
}
HudItemsHide()
{
if ( level.players.size > 0 )
{
for ( i = 0; i < level.players.size; i++ )
{
if( isdefined( level.players[ i ].using_uav ) && level.players[ i ].using_uav )
setdvar( "ui_remotemissile_playernum", (i+1) ); // 0 = no uav, 1 = player1, 2 = player2
}
}
else
{
SetSavedDvar( "compass", "0" );
SetSavedDvar( "ammoCounterHide", "1" );
SetSavedDvar( "actionSlotsHide", "1" );
}
}
HudItemsShow()
{
if( level.players.size > 0 )
{
setdvar( "ui_remotemissile_playernum", 0 ); // 0 = no uav, 1 = player1, 2 = player2
}
else
{
SetSavedDvar( "compass", "1" );
SetSavedDvar( "ammoCounterHide", "0" );
SetSavedDvar( "actionSlotsHide", "0" );
}
}
FireMissileFromUAVPlayer( player )
{
Earthquake( 0.4, 1, level.uavRig.origin, 5000 );
org = level.uavRig.origin;
playerAngles = player GetPlayerAngles();
forward = AnglesToForward( playerAngles );
right = AnglesToRight( playerAngles );
start = org + ( right * 700.0 ) + ( forward * -300.0 );
end = start + forward * 10.0;
if ( IsDefined( level.remote_missile_snow ) )
{
missile = MagicBullet( "remote_missile_snow", start, end, player );
}
else
{
if ( IsDefined( level.remote_missile_invasion ) )
missile = MagicBullet( "remote_missile_invasion", start, end, player );
else
missile = MagicBullet( "remote_missile", start, end, player );
}
thread NotifyOnMissileDeath( missile );
return missile;
}
setup_remote_missile_target()
{
if ( !isdefined( level.remote_missile_targets ) )
level.remote_missile_targets = [];
level.remote_missile_targets[ level.remote_missile_targets.size ] = self;
if ( IsDefined( level.player.draw_red_boxes ) && !isdefined( level.uav_is_destroyed ) )
self draw_target();
self waittill( "death" );
if ( !isdefined( self ) )
return;
if ( IsDefined( self.has_target_shader ) )
{
self.has_target_shader = undefined;
Target_Remove( self );
}
level.remote_missile_targets = array_remove( level.remote_missile_targets, self );
}
DrawTargetsStart()
{
level.player.draw_red_boxes = true;
level endon( "uav_destroyed" );
level endon( "draw_target_end" );
//level.player ThermalVisionFOFOverlayOn();
targets_per_frame = 4;
targets_drawn = 0;
time_between_updates = .05;
if ( !isdefined( level.remote_missile_targets ) )
return;
foreach ( tgt in level.remote_missile_targets )
{
if ( IsAlive( tgt ) )
{
tgt draw_target();
targets_drawn++;
if ( targets_drawn >= targets_per_frame )
{
targets_drawn = 0;
wait time_between_updates;
}
}
else
{
level.remote_missile_targets = array_remove( level.remote_missile_targets, tgt );
}
}
}
draw_target()
{
self.has_target_shader = true;
if ( IsDefined( self.helicopter_predator_target_shader ) )
{
Target_Set( self, ( 0, 0, -96 ) );
}
else
{
Target_Set( self, ( 0, 0, 64 ) );
}
if ( IsAI( self ) )
{
Target_SetShader( self, "remotemissile_infantry_target" );
}
else if ( IsPlayer( self ) )// Make sure you add the player to the level.remote_missile_targets before use
{
Target_SetShader( self, "hud_fofbox_self_sp" );
}
else
{
Target_SetShader( self, "veh_hud_target" );
}
// There is an order of execution issue, which is why this is commented out.
// If player 2 ( level.players[ 1 ] ) runs the Target_ShowToPlayer() last, then player 1 will be able
// to see the targets.
// So, the work around is to figure out who is controlling the UAV, then call to Target_ShowToPlayer()
// before Target_HideFromPlayer()
// foreach( player in level.players )
// {
// if( IsDefined( player.is_controlling_UAV ) && player.is_controlling_UAV )
// Target_ShowToPlayer( self, player );
// else
// Target_HideFromPlayer( self, player );
// }
uav_controller = undefined;
non_uav_controller = undefined;
foreach ( player in level.players )
{
if ( IsDefined( player.is_controlling_UAV ) && player.is_controlling_UAV )
{
uav_controller = player;
}
else
{
non_uav_controller = player;
}
}
Target_ShowToPlayer( self, uav_controller );
if ( IsDefined( non_uav_controller ) )
{
Target_HideFromPlayer( self, non_uav_controller );
}
}
DrawTargetsEnd()
{
level notify( "draw_target_end" );
//level.player ThermalVisionFOFOverlayOff();
waittillframeend;// was colliding with self waittill death which also removes the target
level.player.draw_red_boxes = undefined;
if ( IsDefined( level.remote_missile_targets ) )
{
foreach ( tgt in level.remote_missile_targets )
{
if ( !isdefined( tgt ) )
{
level.remote_missile_targets = array_remove( level.remote_missile_targets, tgt );
}
if ( IsDefined( tgt ) )
{
if ( IsDefined( tgt.has_target_shader ) )
{
tgt.has_target_shader = undefined;
Target_Remove( tgt );
}
}
}
}
}
SwitchBackToMainWeapon()
{
return SwitchBackToMainWeapon_internal( ::_switcher );
}
SwitchBackToMainWeaponFast()
{
return SwitchBackToMainWeapon_internal( ::_switcherNow );
}
_switcher( weapName )
{
self SwitchToWeapon( weapName );
}
_switcherNow( weapName )
{
self SwitchToWeaponImmediate( weapName );
}
SwitchBackToMainWeapon_internal( func )
{
if ( self ent_flag_exist( "coop_downed" ) && self ent_flag( "coop_downed" ) )
{
return;
}
//"primary", "offhand", "item", "altmode", and "exclusive".
weapons = self GetWeaponsList( "primary", "altmode" );
foreach ( weapon in weapons )
{
if ( self.last_weapon == weapon )
{
self [[ func ]]( self.last_weapon );
return;
}
}
if ( weapons.size > 0 )
self [[ func ]]( weapons[ 0 ] );
}
staticEffect( duration )
{
org = Spawn( "script_origin", ( 0, 0, 1 ) );
org.origin = self.origin;
org PlaySound( "predator_drone_static", "sounddone" );
static = NewClientHudElem( self );
static.horzAlign = "fullscreen";
static.vertAlign = "fullscreen";
static SetShader( "ac130_overlay_grain", 640, 480 );
wait( duration );
static Destroy();
wait( 3 );
org StopSounds();
wait( 1 );
org Delete();
}