828 lines
33 KiB
Plaintext
828 lines
33 KiB
Plaintext
#using scripts\codescripts\struct;
|
|
|
|
#using scripts\shared\callbacks_shared;
|
|
#using scripts\shared\challenges_shared;
|
|
#using scripts\shared\clientfield_shared;
|
|
#using scripts\shared\hostmigration_shared;
|
|
#using scripts\shared\killstreaks_shared;
|
|
#using scripts\shared\popups_shared;
|
|
#using scripts\shared\util_shared;
|
|
#using scripts\shared\vehicle_shared;
|
|
#using scripts\shared\vehicle_death_shared;
|
|
#using scripts\shared\weapons\_hacker_tool;
|
|
#using scripts\shared\scoreevents_shared;
|
|
#using scripts\shared\math_shared;
|
|
#using scripts\shared\weapons\_heatseekingmissile;
|
|
#using scripts\mp\killstreaks\_qrdrone;
|
|
#using scripts\mp\killstreaks\_airsupport;
|
|
#using scripts\shared\vehicle_ai_shared;
|
|
|
|
#using scripts\mp\_util;
|
|
#using scripts\mp\gametypes\_shellshock;
|
|
#using scripts\mp\killstreaks\_killstreak_bundles;
|
|
#using scripts\mp\killstreaks\_killstreak_detect;
|
|
#using scripts\mp\killstreaks\_killstreak_hacking;
|
|
#using scripts\mp\killstreaks\_killstreakrules;
|
|
#using scripts\mp\killstreaks\_killstreaks;
|
|
#using scripts\mp\killstreaks\_remote_weapons;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#using scripts\shared\visionset_mgr_shared;
|
|
|
|
#namespace dart;
|
|
|
|
|
|
|
|
|
|
#precache( "string", "KILLSTREAK_DART_HACKED" );
|
|
#precache( "string", "KILLSTREAK_DART_EARNED" );
|
|
#precache( "string", "KILLSTREAK_DART_NOT_AVAILABLE" );
|
|
#precache( "string", "KILLSTREAK_DART_INBOUND" );
|
|
#precache( "string", "KILLSTREAK_DART_HACKED" );
|
|
#precache( "string", "KILLSTREAK_DESTROYED_DART" );
|
|
#precache( "string", "mpl_killstreak_dart_strt" );
|
|
|
|
function init()
|
|
{
|
|
killstreaks::register( "dart", "dart", "killstreak_dart", "dart_used", &ActivateDart, true) ;
|
|
killstreaks::register_strings( "dart", &"KILLSTREAK_DART_EARNED", &"KILLSTREAK_DART_NOT_AVAILABLE", &"KILLSTREAK_DART_INBOUND", undefined, &"KILLSTREAK_DART_HACKED" );
|
|
killstreaks::register_dialog( "dart", "mpl_killstreak_dart_strt", "dartDialogBundle", "dartPilotDialogBundle", "friendlyDart", "enemyDart", "enemyDartMultiple", "friendlyDartHacked", "enemyDartHacked", "requestDart", "threatDart" );
|
|
killstreaks::override_entity_camera_in_demo( "dart", true );
|
|
|
|
killstreaks::register_alt_weapon( "dart", "killstreak_remote" );
|
|
killstreaks::register_alt_weapon( "dart", "dart_blade" );
|
|
killstreaks::register_alt_weapon( "dart", "dart_turret" );
|
|
|
|
clientfield::register( "toplayer", "dart_update_ammo", 1, 2, "int" );
|
|
clientfield::register( "toplayer", "fog_bank_3", 1, 1, "int" );
|
|
|
|
remote_weapons::RegisterRemoteWeapon( "dart", &"", &StartDartRemoteControl, &EndDartRemoteControl, true );
|
|
|
|
visionset_mgr::register_info( "visionset", "dart_visionset", 1, 90, 16, true, &visionset_mgr::ramp_in_out_thread_per_player_death_shutdown, false );
|
|
}
|
|
|
|
function wait_dart_timed_out( time )
|
|
{
|
|
self endon( "disconnect" );
|
|
self endon( "death" );
|
|
self endon( "dart_throw_failed" );
|
|
self endon( "dart_entered" );
|
|
|
|
wait( time );
|
|
|
|
self notify( "dart_throw_timed_out" );
|
|
}
|
|
|
|
function wait_for_throw_status()
|
|
{
|
|
thread dart::wait_dart_timed_out( 5 );
|
|
|
|
notifyString = self util::waittill_any_return( "death", "disconnect", "dart_entered", "dart_throw_timed_out","dart_throw_failed" );
|
|
|
|
if ( notifyString == "dart_entered" || notifyString == "death" )
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
function ActivateDart( killstreakType )
|
|
{
|
|
player = self;
|
|
|
|
assert( IsPlayer( player ) );
|
|
|
|
if( !player killstreakrules::isKillstreakAllowed( "dart", player.team ) )
|
|
return false;
|
|
|
|
player DisableOffhandWeapons();
|
|
|
|
missileWeapon = player GetCurrentWeapon();
|
|
if( !( isdefined( missileWeapon ) && ( ( missileWeapon.name == "dart" ) || ( missileWeapon.name == "inventory_dart" ) ) ) )
|
|
return false;
|
|
|
|
player thread WatchThrow( missileWeapon );
|
|
|
|
notifyString = player util::waittill_any_return( "weapon_change", "grenade_fire", "death", "disconnect", "joined_team", "emp_jammed", "emp_grenaded" );
|
|
|
|
if( notifyString == "death" || notifyString == "emp_jammed" || notifyString == "emp_grenaded" )
|
|
{
|
|
///#iprintln( "death" );#/
|
|
if( player.waitingOnDartThrow )
|
|
player notify( "dart_putaway" );
|
|
|
|
player EnableOffhandWeapons();
|
|
return false;
|
|
}
|
|
|
|
if( notifyString == "grenade_fire" )
|
|
{
|
|
// wait for the killStreakStart results
|
|
return player wait_for_throw_status();
|
|
}
|
|
|
|
if( notifyString == "weapon_change" )
|
|
{
|
|
if( player.waitingOnDartThrow )
|
|
player notify( "dart_putaway" );
|
|
|
|
player EnableOffhandWeapons();
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function cleanup_grenade()
|
|
{
|
|
self thread waitThenDelete( 0.05 );
|
|
self.origin = self.origin + ( 0, 0, 1000 );
|
|
}
|
|
|
|
function WatchThrow( missileWeapon )
|
|
{
|
|
assert( IsPlayer( self ) );
|
|
player = self;
|
|
playerEntNum = player.entNum;
|
|
|
|
player endon( "disconnect" );
|
|
player endon( "joined_team" );
|
|
// player endon( "death" ); // once the dart is thrown, even after death, the player should control it
|
|
player endon( "dart_putaway" );
|
|
|
|
level endon( "game_ended" );
|
|
|
|
player.waitingOnDartThrow = 1;
|
|
player waittill( "grenade_fire", grenade, weapon );
|
|
player.waitingOnDartThrow = 0;
|
|
|
|
if( weapon != missileWeapon )
|
|
{
|
|
self notify("dart_throw_failed");
|
|
return;
|
|
}
|
|
|
|
trace = player check_launch_space(grenade.origin);
|
|
|
|
if ( trace["fraction"] < 1.0 )
|
|
{
|
|
self iprintlnbold( &"KILLSTREAK_DART_NOT_AVAILABLE" );
|
|
grenade cleanup_grenade();
|
|
self notify("dart_throw_failed");
|
|
return;
|
|
}
|
|
|
|
killstreak_id = player killstreakrules::killstreakStart( "dart", player.team, undefined, false );
|
|
if( killstreak_id == (-1) )
|
|
{
|
|
grenade cleanup_grenade();
|
|
self notify("dart_throw_failed");
|
|
return;
|
|
}
|
|
|
|
player.dart_thrown_time = GetTime();
|
|
|
|
player TakeWeapon( missileWeapon );
|
|
|
|
player killstreaks::set_killstreak_delay_killcam( "dart" ); // special case: death while watching does not prevent riding dart, and thus no killcam
|
|
player.resurrect_not_allowed_by = "dart";
|
|
|
|
player AddWeaponStat( GetWeapon( "dart" ), "used", 1 );
|
|
level thread popups::DisplayKillstreakTeamMessageToAll( "dart", player );
|
|
|
|
dart = player SpawnDart( grenade, killstreak_id, trace["position"] );
|
|
if( isdefined( dart ) )
|
|
{
|
|
player killstreaks::play_killstreak_start_dialog( "dart", player.team, killstreak_id );
|
|
}
|
|
}
|
|
|
|
function HackedPreFunction( hacker )
|
|
{
|
|
dart = self;
|
|
dart.owner util::freeze_player_controls( false );
|
|
visionset_mgr::deactivate( "visionset", "dart_visionset", dart.owner );
|
|
dart.owner clientfield::set_to_player( "fog_bank_3", 0 );
|
|
dart.owner unlink();
|
|
dart clientfield::set( "vehicletransition", 0 );
|
|
dart.owner killstreaks::clear_using_remote();
|
|
dart.owner killstreaks::unhide_compass();
|
|
dart.owner vehicle::stop_monitor_missiles_locked_on_to_me();
|
|
dart.owner vehicle::stop_monitor_damage_as_occupant();
|
|
dart DisableDartMissileLocking();
|
|
}
|
|
|
|
function HackedPostFunction( hacker )
|
|
{
|
|
dart = self;
|
|
hacker StartDartRemoteControl( dart );
|
|
|
|
hacker killstreak_hacking::set_vehicle_drivable_time_starting_now( dart );
|
|
hacker remote_weapons::UseRemoteWeapon( dart, "dart", false );
|
|
hacker killstreaks::set_killstreak_delay_killcam( "dart" );
|
|
}
|
|
|
|
function dart_hacked_health_update( hacker )
|
|
{
|
|
dart = self;
|
|
if ( dart.health > dart.hackedhealth )
|
|
{
|
|
dart.health = dart.hackedhealth;
|
|
}
|
|
}
|
|
|
|
function check_launch_space(origin)
|
|
{
|
|
player_angles = self getPlayerAngles();
|
|
forward = AnglesToForward( player_angles );
|
|
spawn_origin = origin + VectorScale( forward, 50 );
|
|
|
|
radius = 10;
|
|
return physicstrace( origin, spawn_origin, ( -radius, -radius, 0 ), ( radius, radius, 2 * radius ), self, (1 << 0) );
|
|
}
|
|
|
|
function SpawnDart( grenade, killstreak_id, spawn_origin )
|
|
{
|
|
///#iprintln( "Spawn Dart" );#/
|
|
player = self;
|
|
assert( IsPlayer( player ) );
|
|
playerEntNum = player.entNum;
|
|
player_angles = player getPlayerAngles();
|
|
|
|
grenade cleanup_grenade();
|
|
|
|
params = level.killstreakBundle["dart"];
|
|
|
|
if(!isdefined(params.ksDartVehicle))params.ksDartVehicle="veh_dart_mp";
|
|
if(!isdefined(params.ksDartInitialSpeed))params.ksDartInitialSpeed=35;
|
|
if(!isdefined(params.ksDartAcceleration))params.ksDartAcceleration=35;
|
|
|
|
dart = SpawnVehicle( params.ksDartVehicle, spawn_origin, player_angles, "dynamic_spawn_ai" );
|
|
|
|
//dart thread debug_origin();
|
|
|
|
dart.is_shutting_down = 0;
|
|
dart.team = player.team;
|
|
dart SetSpeedImmediate( params.ksDartInitialSpeed, params.ksDartAcceleration );
|
|
dart.maxhealth = killstreak_bundles::get_max_health( "dart" );
|
|
dart.health = dart.maxhealth;
|
|
dart.hackedhealth = killstreak_bundles::get_hacked_health( "dart" );
|
|
dart.hackedHealthUpdateCallback = &dart_hacked_health_update;
|
|
|
|
dart killstreaks::configure_team( "dart", killstreak_id, player, "small_vehicle" );
|
|
dart killstreak_hacking::enable_hacking( "dart", &HackedPreFunction, &HackedPostFunction );
|
|
|
|
dart clientfield::set( "enemyvehicle", 1 );
|
|
dart.killstreak_id = killstreak_id;
|
|
dart.hardpointType = "dart";
|
|
dart thread killstreaks::WaitForTimeout( "dart", ( 30 * 1000 ), &stop_remote_weapon, "remote_weapon_end", "death" );
|
|
dart hacker_tool::registerWithhackerTool( ( 50 ), ( 2000 ) );
|
|
dart.overrideVehicleDamage = &dartDamageOverride;
|
|
dart.DetonateViaEMP = &emp_damage_cb;
|
|
dart.do_scripted_crash = false;
|
|
dart.delete_on_death = true;
|
|
dart.one_remote_use = true;
|
|
dart.vehcheckforpredictedcrash = true;
|
|
dart.predictedCollisionTime = 0.2;
|
|
dart.glasscollision_alt = true;
|
|
dart.damageTaken = 0;
|
|
dart.death_enter_cb = &waitRemoteControl;
|
|
|
|
Target_Set( dart );
|
|
|
|
dart vehicle::init_target_group();
|
|
dart vehicle::add_to_target_group( dart );
|
|
|
|
dart thread WatchCollision();
|
|
|
|
dart thread WatchDeath();
|
|
|
|
dart thread WatchOwnerNonDeathEvents();
|
|
|
|
dart.forceWaitRemoteControl = true;
|
|
|
|
player util::waittill_any( "weapon_change", "death" ); // wait for the killstreak weapon to go away, or the player dies (special case for Dart)
|
|
|
|
player remote_weapons::UseRemoteWeapon( dart, "dart", true, true, true );
|
|
|
|
player notify( "dart_entered" );
|
|
|
|
return dart;
|
|
}
|
|
|
|
function debug_origin()
|
|
{
|
|
self endon( "death" );
|
|
while( 1 )
|
|
{
|
|
/#sphere( self.origin, 5, ( 1.0, 0, 0 ), 1.0, true, 2, 120 );#/
|
|
{wait(.05);};
|
|
}
|
|
}
|
|
|
|
function waitRemoteControl()
|
|
{
|
|
dart = self;
|
|
|
|
remote_controlled = ( isdefined( dart.control_initiated ) && dart.control_initiated ) || ( isdefined( dart.controlled ) && dart.controlled );
|
|
|
|
if( remote_controlled )
|
|
{
|
|
notifyString = dart util::waittill_any_return( "remote_weapon_end", "dart_left" );
|
|
if ( isdefined( notifyString ) )
|
|
{
|
|
if( notifyString == "remote_weapon_end" )
|
|
dart waittill( "dart_left" );
|
|
else
|
|
dart waittill( "remote_weapon_end" );
|
|
}
|
|
}
|
|
else
|
|
dart waittill( "dart_left" );
|
|
}
|
|
|
|
function StartDartRemoteControl( dart )
|
|
{
|
|
///#iprintln( "StartDartRemoteControl" );#/
|
|
player = self;
|
|
assert( IsPlayer( player ) );
|
|
|
|
if( !dart.is_shutting_down )
|
|
{
|
|
player.dart_thrown_time = undefined;
|
|
|
|
///#iprintln( "UseVehicle" );#/
|
|
dart UseVehicle( player, 0 );///
|
|
player.resurrect_not_allowed_by = undefined;
|
|
dart clientfield::set( "vehicletransition", 1 );
|
|
dart thread WatchAmmo();
|
|
dart thread vehicle::monitor_missiles_locked_on_to_me( player );
|
|
dart thread vehicle::monitor_damage_as_occupant( player );
|
|
|
|
player vehicle::set_vehicle_drivable_time_starting_now( ( 30 * 1000 ) );
|
|
player.no_fade2black = true;
|
|
|
|
dart.inHeliProximity = false;
|
|
|
|
minHeightOverride = undefined;
|
|
minz_struct = struct::get( "vehicle_oob_minz", "targetname");
|
|
if( isdefined( minz_struct ) )
|
|
minHeightOverride = minz_struct.origin[2];
|
|
|
|
dart thread qrdrone::QRDrone_watch_distance( ( 2000 ), minHeightOverride );
|
|
dart.distance_shutdown_override = &DartDistanceFailure;
|
|
|
|
dart EnableDartMissileLocking();
|
|
visionset_mgr::activate( "visionset", "dart_visionset", self, 1, 90000, 1 );
|
|
player clientfield::set_to_player( "fog_bank_3", 1 );
|
|
}
|
|
}
|
|
|
|
function EndDartRemoteControl( dart, exitRequestedByOwner )
|
|
{
|
|
dart thread leave_dart();
|
|
}
|
|
|
|
function DartDistanceFailure()
|
|
{
|
|
thread stop_remote_weapon();
|
|
}
|
|
|
|
function stop_remote_weapon( attacker, weapon )
|
|
{
|
|
dart = self;
|
|
|
|
dart.DetonateViaEMP = undefined;
|
|
|
|
attacker = self [[ level.figure_out_attacker ]]( attacker );
|
|
if ( isdefined( attacker ) && ( !isdefined( dart.owner ) || dart.owner util::IsEnemyPlayer( attacker ) ) )
|
|
{
|
|
challenges::destroyedAircraft( attacker, weapon, true );
|
|
attacker challenges::addFlySwatterStat( weapon, self );
|
|
scoreevents::processScoreEvent( "destroyed_dart", attacker, dart.owner, weapon );
|
|
LUINotifyEvent( &"player_callout", 2, &"KILLSTREAK_DESTROYED_DART", attacker.entnum );
|
|
}
|
|
|
|
if( isdefined( attacker ) && attacker != dart.owner )
|
|
{
|
|
dart killstreaks::play_destroyed_dialog_on_owner( "dart", dart.killstreak_id );
|
|
}
|
|
|
|
dart thread remote_weapons::EndRemoteControlWeaponUse( false );
|
|
}
|
|
|
|
function dartDamageOverride( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, damageFromUnderneath, modelIndex, partName, vSurfaceNormal )
|
|
{
|
|
dart = self;
|
|
|
|
if( ( sMeansOfDeath == "MOD_TRIGGER_HURT" ) || ( isdefined( dart.is_shutting_down ) && dart.is_shutting_down ) )
|
|
return 0;
|
|
|
|
player = dart.owner;
|
|
|
|
iDamage = killstreaks::OnDamagePerWeapon( "dart", eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, self.maxhealth, &stop_remote_weapon, self.maxhealth*0.4, undefined,
|
|
0, &emp_damage_cb, true, 1.0 );
|
|
|
|
return iDamage;
|
|
}
|
|
|
|
function emp_damage_cb( attacker, weapon )
|
|
{
|
|
dart = self;
|
|
dart stop_remote_weapon( attacker, weapon );
|
|
}
|
|
|
|
function DarPredictedCollision()
|
|
{
|
|
self endon( "death" );
|
|
|
|
while( 1 )
|
|
{
|
|
self waittill( "veh_predictedcollision", velocity, normal, ent, stype );
|
|
self notify( "veh_collision", velocity, normal, ent, stype );
|
|
|
|
if( stype == "glass" )
|
|
continue;
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
|
|
function WatchCollision()
|
|
{
|
|
dart = self;
|
|
dart endon( "death" );
|
|
dart.owner endon( "disconnect" );
|
|
|
|
dart thread DarPredictedCollision();
|
|
|
|
|
|
while( 1 )
|
|
{
|
|
dart waittill( "veh_collision", velocity, normal, ent, stype );
|
|
|
|
///#sphere( dart.origin, 5, ( 1.0, 0, 0 ), 1.0, true, 100, 120 );#/
|
|
if( stype === "glass" )
|
|
continue;
|
|
|
|
dart SetSpeedImmediate( 0 );
|
|
dart vehicle_death::death_fx();
|
|
|
|
dart thread stop_remote_weapon();
|
|
break;
|
|
}
|
|
}
|
|
|
|
function WatchDeath()
|
|
{
|
|
dart = self;
|
|
player = dart.owner;
|
|
|
|
player endon( "dart_entered" ); // the remote weapon script should handle it from here on
|
|
dart endon( "delete" );
|
|
|
|
dart waittill( "death" );
|
|
//dart waittill( "death", attacker, damageFromUnderneath, weapon, point, dir, modType );
|
|
|
|
dart thread leave_dart();
|
|
}
|
|
|
|
function WatchOwnerNonDeathEvents( endCondition1, endCondition2 )
|
|
{
|
|
dart = self;
|
|
player = dart.owner;
|
|
|
|
player endon( "dart_entered" ); // the remote weapon script should handle it from here on
|
|
dart endon( "death" );
|
|
|
|
dart thread WatchForGameEnd();
|
|
|
|
player util::waittill_any( "joined_team", "disconnect", "joined_spectators", "emp_jammed" );
|
|
|
|
dart thread leave_dart();
|
|
}
|
|
|
|
function WatchForGameEnd()
|
|
{
|
|
dart = self;
|
|
dart endon( "death" );
|
|
|
|
level waittill( "game_ended" );
|
|
|
|
dart thread leave_dart();
|
|
}
|
|
|
|
function WatchAmmo()
|
|
{
|
|
dart = self;
|
|
dart endon( "death" );
|
|
|
|
player = dart.owner;
|
|
|
|
player endon( "disconnect" );
|
|
|
|
shotCount = 0;
|
|
|
|
params = level.killstreakBundle["dart"];
|
|
|
|
if(!isdefined(params.ksDartShotCount))params.ksDartShotCount=3;
|
|
if(!isdefined(params.ksDartBladeCount))params.ksDartBladeCount=6;
|
|
if(!isdefined(params.ksDartWaitTimeAfterLastShot))params.ksDartWaitTimeAfterLastShot=1;
|
|
|
|
if(!isdefined(params.ksBladeStartDistance))params.ksBladeStartDistance=0;
|
|
if(!isdefined(params.ksBladeEndDistance))params.ksBladeEndDistance=10000;
|
|
if(!isdefined(params.ksBladeStartSpreadRadius))params.ksBladeStartSpreadRadius=50;
|
|
if(!isdefined(params.ksBladeEndSpreadRadius))params.ksBladeEndSpreadRadius=1;
|
|
|
|
player clientfield::set_to_player( "dart_update_ammo", params.ksDartShotCount );
|
|
|
|
while( true )
|
|
{
|
|
dart waittill( "weapon_fired" );
|
|
shotCount++;
|
|
|
|
player clientfield::set_to_player( "dart_update_ammo", params.ksDartShotCount - shotCount );
|
|
|
|
if( shotCount >= params.ksDartShotCount )
|
|
{
|
|
dart DisableDriverFiring( true );
|
|
wait( params.ksDartWaitTimeAfterLastShot );
|
|
dart stop_remote_weapon();
|
|
}
|
|
}
|
|
}
|
|
|
|
function leave_dart()
|
|
{
|
|
dart = self;
|
|
owner = dart.owner;
|
|
|
|
if( isdefined( owner ) )
|
|
{
|
|
visionset_mgr::deactivate( "visionset", "dart_visionset", owner );
|
|
owner clientfield::set_to_player( "fog_bank_3", 0 );
|
|
owner qrdrone::destroyHud();
|
|
}
|
|
|
|
if( isdefined( dart ) && ( dart.is_shutting_down == 1 ) )
|
|
return;
|
|
|
|
dart.is_shutting_down = 1;
|
|
|
|
dart clientfield::set( "timeout_beep", 0 );
|
|
dart vehicle::lights_off();
|
|
dart vehicle_death::death_fx();
|
|
dart Hide();
|
|
|
|
dart_original_team = dart.originalteam;
|
|
dart_killstreak_id = dart.killstreak_id;
|
|
|
|
if( Target_IsTarget( dart ) )
|
|
Target_Remove( dart );
|
|
|
|
iF( isalive( dart ) )
|
|
dart notify( "death" );
|
|
|
|
params = level.killstreakBundle["dart"];
|
|
|
|
if(!isdefined(params.ksDartExplosionOuterRadius))params.ksDartExplosionOuterRadius=200;
|
|
if(!isdefined(params.ksDartExplosionInnerRadius))params.ksDartExplosionInnerRadius=1;
|
|
if(!isdefined(params.ksDartExplosionOuterDamage))params.ksDartExplosionOuterDamage=25;
|
|
if(!isdefined(params.ksDartExplosionInnerDamage))params.ksDartExplosionInnerDamage=350;
|
|
if(!isdefined(params.ksDartExplosionMagnitude))params.ksDartExplosionMagnitude=1;
|
|
|
|
PhysicsExplosionSphere( dart.origin,
|
|
params.ksDartExplosionOuterRadius,
|
|
params.ksDartExplosionInnerRadius,
|
|
params.ksDartExplosionMagnitude,
|
|
params.ksDartExplosionOuterDamage,
|
|
params.ksDartExplosionInnerDamage );
|
|
|
|
if( isdefined( owner ) )
|
|
{
|
|
owner killstreaks::set_killstreak_delay_killcam( "dart" ); // hold the respawn till we finish here
|
|
|
|
dart RadiusDamage( dart.origin,
|
|
params.ksDartExplosionOuterRadius,
|
|
params.ksDartExplosionInnerDamage,
|
|
params.ksDartExplosionOuterDamage,
|
|
owner,
|
|
"MOD_EXPLOSIVE",
|
|
GetWeapon( "dart" ) );
|
|
|
|
owner thread play_bda_dialog( self.pilotIndex );
|
|
|
|
if( ( isdefined( dart.controlled ) && dart.controlled ) || ( isdefined( dart.control_initiated ) && dart.control_initiated ) )
|
|
{
|
|
owner SetClientUIVisibilityFlag( "hud_visible", 0 );
|
|
owner unlink();
|
|
dart clientfield::set( "vehicletransition", 0 );
|
|
|
|
if( isdefined( params.ksExplosionRumble ) )
|
|
owner PlayRumbleOnEntity( params.ksExplosionRumble );
|
|
|
|
owner vehicle::stop_monitor_missiles_locked_on_to_me();
|
|
owner vehicle::stop_monitor_damage_as_occupant();
|
|
|
|
dart DisableDartMissileLocking();
|
|
|
|
owner util::freeze_player_controls( true );
|
|
|
|
forward = AnglesToForward( dart.angles );
|
|
if(!isdefined(params.ksDartCameraWatchDistance))params.ksDartCameraWatchDistance=350;
|
|
moveAmount = VectorScale( forward, -( params.ksDartCameraWatchDistance ) );
|
|
|
|
size = 4;
|
|
trace = physicstrace( dart.origin, dart.origin + moveAmount, ( -size, -size, -size ), ( size, size, size ), undefined, (1 << 0) );
|
|
|
|
cam = spawn( "script_model", trace["position"] );
|
|
cam SetModel( "tag_origin" );
|
|
cam LinkTo( dart );
|
|
dart SetSpeedImmediate( 0 );
|
|
|
|
owner CameraSetPosition( cam.origin );
|
|
owner CameraSetLookAt( dart.origin );
|
|
owner CameraActivate( true );
|
|
|
|
if(!isdefined(params.ksDartCameraWatchDuration))params.ksDartCameraWatchDuration=2;
|
|
wait( params.ksDartCameraWatchDuration );
|
|
|
|
if ( isdefined( owner ) )
|
|
{
|
|
owner CameraActivate( false );
|
|
}
|
|
|
|
cam delete();
|
|
|
|
if( isdefined( owner ) )
|
|
{
|
|
if( !level.gameEnded )
|
|
owner util::freeze_player_controls( false );
|
|
|
|
owner SetClientUIVisibilityFlag( "hud_visible", 1 );
|
|
}
|
|
}
|
|
|
|
if ( isdefined( owner ) )
|
|
{
|
|
owner killstreaks::reset_killstreak_delay_killcam();
|
|
}
|
|
}
|
|
|
|
killstreakrules::killstreakStop( "dart", dart_original_team, dart_killstreak_id );
|
|
|
|
if ( isdefined( dart ) )
|
|
{
|
|
dart notify( "dart_left" );
|
|
}
|
|
}
|
|
|
|
function DeleteOnConditions( condition )
|
|
{
|
|
dart = self;
|
|
dart endon( "delete" );
|
|
|
|
if( isdefined( condition ) )
|
|
dart waittill( condition );
|
|
|
|
dart notify( "delete" );
|
|
dart delete();
|
|
}
|
|
|
|
function waitThenDelete( waitTime )
|
|
{
|
|
self endon( "delete" );
|
|
self endon( "death" );
|
|
wait( waitTime );
|
|
self delete();
|
|
}
|
|
|
|
function play_bda_dialog( pilotIndex )
|
|
{
|
|
self endon( "game_ended" );
|
|
|
|
wait( 0.5 );
|
|
|
|
if ( !isdefined( self.dartBda ) || self.dartBda == 0 )
|
|
{
|
|
bdaDialog = "killNone";
|
|
}
|
|
else if ( self.dartBda == 1 )
|
|
{
|
|
bdaDialog = "kill1";
|
|
}
|
|
else if ( self.dartBda == 2 )
|
|
{
|
|
bdaDialog = "kill2";
|
|
}
|
|
else if ( self.dartBda == 3 )
|
|
{
|
|
bdaDialog = "kill3";
|
|
}
|
|
else if ( self.dartBda > 3 )
|
|
{
|
|
bdaDialog = "killMultiple";
|
|
}
|
|
|
|
self killstreaks::play_pilot_dialog( bdaDialog, "dart", undefined, pilotIndex );
|
|
|
|
self.dartBda = undefined;
|
|
}
|
|
|
|
function EnableDartMissileLocking() // self == dart
|
|
{
|
|
dart = self;
|
|
player = dart.owner;
|
|
weapon = dart SeatGetWeapon( 0 );
|
|
|
|
player.get_stinger_target_override = &GetDartMissileTargets;
|
|
player.is_still_valid_target_for_stinger_override = &IsStillValidDartMissileTarget;
|
|
player.is_valid_target_for_stinger_override = &IsValidDartMissileTarget;
|
|
player.dart_killstreak_weapon = weapon;
|
|
|
|
player thread heatseekingmissile::StingerIRTLoop( weapon );
|
|
}
|
|
|
|
function DisableDartMissileLocking() // self == dart
|
|
{
|
|
player = self.owner;
|
|
|
|
player.get_stinger_target_override = undefined;
|
|
player.is_still_valid_target_for_stinger_override = undefined;
|
|
player.is_valid_target_for_stinger_override = undefined;
|
|
player.dart_killstreak_weapon = undefined;
|
|
|
|
player notify( "stinger_IRT_off" );
|
|
player heatseekingmissile::ClearIRTarget();
|
|
}
|
|
|
|
function GetDartMissileTargets()
|
|
{
|
|
targets = ArrayCombine( target_getArray(), level.MissileEntities, false, false );
|
|
targets = ArrayCombine( targets, level.players, false, false );
|
|
|
|
return targets;
|
|
}
|
|
|
|
function IsValidDartMissileTarget( ent ) // self == player
|
|
{
|
|
player = self;
|
|
|
|
if ( !isdefined( ent ) )
|
|
return false;
|
|
|
|
entIsPlayer = IsPlayer( ent );
|
|
|
|
if ( entIsPlayer && !IsAlive( ent ) )
|
|
return false;
|
|
|
|
if ( ent.ignoreme === true )
|
|
return false;
|
|
|
|
dart = player GetVehicleOccupied();
|
|
if ( !isdefined( dart ) )
|
|
return false;
|
|
|
|
if ( DistanceSquared( dart.origin, ent.origin ) > ( (player.dart_killstreak_weapon.lockOnMaxRange) * (player.dart_killstreak_weapon.lockOnMaxRange) ) )
|
|
return false;
|
|
|
|
if ( entIsPlayer && ent HasPerk( "specialty_nokillstreakreticle" ) )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
function IsStillValidDartMissileTarget( ent, weapon ) // self == player
|
|
{
|
|
player = self;
|
|
|
|
if ( !( target_isTarget( ent ) || IsPlayer( ent ) ) && !( isdefined( ent.allowContinuedLockonAfterInvis ) && ent.allowContinuedLockonAfterInvis ) )
|
|
return false;
|
|
|
|
dart = player GetVehicleOccupied();
|
|
if ( !isdefined( dart ) )
|
|
return false;
|
|
|
|
entIsPlayer = IsPlayer( ent );
|
|
|
|
if ( entIsPlayer && !IsAlive( ent ) )
|
|
return false;
|
|
|
|
if ( ent.ignoreme === true )
|
|
return false;
|
|
|
|
if ( DistanceSquared( dart.origin, ent.origin ) > ( (player.dart_killstreak_weapon.lockOnMaxRange) * (player.dart_killstreak_weapon.lockOnMaxRange) ) )
|
|
return false;
|
|
|
|
if ( entIsPlayer && ent HasPerk( "specialty_nokillstreakreticle" ) )
|
|
return false;
|
|
|
|
if ( !heatseekingmissile::InsideStingerReticleLocked( ent, weapon ) )
|
|
return false;
|
|
|
|
return true;
|
|
}
|