343 lines
21 KiB
Plaintext
343 lines
21 KiB
Plaintext
#using scripts\codescripts\struct;
|
|
|
|
#using scripts\shared\challenges_shared;
|
|
#using scripts\shared\clientfield_shared;
|
|
#using scripts\shared\scoreevents_shared;
|
|
#using scripts\shared\util_shared;
|
|
|
|
#using scripts\mp\_challenges;
|
|
#using scripts\mp\_util;
|
|
#using scripts\mp\gametypes\_spawning;
|
|
#using scripts\mp\killstreaks\_airsupport;
|
|
#using scripts\mp\killstreaks\_killstreakrules;
|
|
#using scripts\mp\killstreaks\_killstreaks;
|
|
#using scripts\mp\killstreaks\_satellite;
|
|
#using scripts\mp\killstreaks\_planemortar;
|
|
#using scripts\mp\killstreaks\_killstreak_bundles;
|
|
#using scripts\mp\gametypes\_globallogic_audio;
|
|
#using scripts\shared\weapons\_hacker_tool;
|
|
#using scripts\mp\killstreaks\_killstreak_hacking;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#namespace drone_strike;
|
|
|
|
|
|
#precache( "locationselector", "map_directional_selector" );
|
|
#precache( "string", "KILLSTREAK_DRONE_STRIKE_NOT_AVAILABLE" );
|
|
#precache( "string", "KILLSTREAK_DRONE_STRIKE_EARNED" );
|
|
#precache( "string", "KILLSTREAK_DRONE_STRIKE_INBOUND" );
|
|
#precache( "string", "KILLSTREAK_DRONE_STRIKE_INBOUND_NEAR_PLAYER" );
|
|
#precache( "string", "KILLSTREAK_DRONE_STRIKE_HACKED" );
|
|
#precache( "string", "KILLSTREAK_DESTROYED_ROLLING_THUNDER_DRONE" );
|
|
#precache( "string", "KILLSTREAK_DESTROYED_ROLLING_THUNDER_ALL_DRONES" );
|
|
|
|
#precache( "eventstring", "mpl_killstreak_DRONE_STRIKE" );
|
|
#precache( "fx", "killstreaks/fx_rolling_thunder_thruster_trails" );
|
|
|
|
function init()
|
|
{
|
|
killstreaks::register( "drone_strike", "drone_strike", "killstreak_drone_strike", "drone_strike_used", &ActivateDroneStrike, true );
|
|
killstreaks::register_strings( "drone_strike", &"KILLSTREAK_DRONE_STRIKE_EARNED", &"KILLSTREAK_DRONE_STRIKE_NOT_AVAILABLE", &"KILLSTREAK_DRONE_STRIKE_INBOUND", &"KILLSTREAK_DRONE_STRIKE_INBOUND_NEAR_PLAYER", &"KILLSTREAK_DRONE_STRIKE_HACKED" );
|
|
killstreaks::register_dialog( "drone_strike", "mpl_killstreak_drone_strike", "droneStrikeDialogBundle", undefined, "friendlyDroneStrike", "enemyDroneStrike", "enemyDroneStrikeMultiple", "friendlyDroneStrikeHacked", "enemyDroneStrikeHacked", "requestDroneStrike", "threatDroneStrike" );
|
|
killstreaks::set_team_kill_penalty_scale( "drone_strike", level.teamKillReducedPenalty );
|
|
}
|
|
|
|
function ActivateDroneStrike()
|
|
{
|
|
if ( self killstreakrules::isKillstreakAllowed( "drone_strike", self.team ) == false )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
result = self SelectDroneStrikePath();
|
|
|
|
if ( !isdefined( result ) || !result )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function SelectDroneStrikePath()
|
|
{
|
|
self BeginLocationNapalmSelection( "map_directional_selector" );
|
|
self.selectingLocation = true;
|
|
self thread airsupport::EndSelectionThink();
|
|
|
|
locations = [];
|
|
if( !isdefined( self.pers["drone_strike_radar_used"] ) || !self.pers["drone_strike_radar_used"] )
|
|
{
|
|
self thread planemortar::SingleRadarSweep();
|
|
}
|
|
|
|
location = self WaitForLocationSelection();
|
|
|
|
// if the player gets disconnected, self will be undefined
|
|
if( !isdefined( self ) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if ( !isdefined( location.origin ) )
|
|
{
|
|
self.pers["drone_strike_radar_used"] = true;
|
|
self notify( "cancel_selection" );
|
|
return false;
|
|
}
|
|
|
|
if ( self killstreakrules::isKillstreakAllowed( "drone_strike", self.team ) == false)
|
|
{
|
|
self.pers["drone_strike_radar_used"] = true;
|
|
self notify("cancel_selection");
|
|
return false;
|
|
}
|
|
|
|
self.pers["drone_strike_radar_used"] = false;
|
|
return self airsupport::finishHardpointLocationUsage( location, &DroneStrikeLocationSelected );
|
|
}
|
|
|
|
function WaitForLocationSelection()
|
|
{
|
|
self endon( "emp_jammed" );
|
|
self endon( "emp_grenaded" );
|
|
|
|
self waittill( "confirm_location", location, yaw );
|
|
|
|
locationInfo = SpawnStruct();
|
|
locationInfo.origin = location;
|
|
locationInfo.yaw = yaw;
|
|
|
|
return locationInfo;
|
|
}
|
|
|
|
function DroneStrikeLocationSelected( location )
|
|
{
|
|
team = self.team;
|
|
killstreak_id = self killstreakrules::killstreakStart( "drone_strike", team, false, true );
|
|
if( killstreak_id == (-1) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
self killstreaks::play_killstreak_start_dialog( "drone_strike", team, killstreak_id );
|
|
self AddWeaponStat( GetWeapon( "drone_strike" ), "used", 1 );
|
|
|
|
spawn_influencer = level spawning::create_enemy_influencer( "artillery", location.origin, team );
|
|
|
|
self thread WatchForKillstreakEnd( team, spawn_influencer, killstreak_id );
|
|
self thread StartDroneStrike( location.origin, location.yaw, team, killstreak_id );
|
|
|
|
return true;
|
|
}
|
|
|
|
function WatchForKillstreakEnd( team, influencer, killstreak_id )
|
|
{
|
|
self util::waittill_any( "disconnect", "joined_team", "joined_spectators", "drone_strike_complete", "emp_jammed" );
|
|
killstreakrules::killstreakStop( "drone_strike", team, killstreak_id );
|
|
}
|
|
|
|
function StartDroneStrike( position, yaw, team, killstreak_id )
|
|
{
|
|
self endon( "emp_jammed" );
|
|
self endon( "joined_team" );
|
|
self endon( "joined_spectators" );
|
|
self endon( "disconnect" );
|
|
|
|
angles = ( 0, yaw, 0 );
|
|
direction = AnglesToForward( angles );
|
|
height = airsupport::getMinimumFlyHeight() + ( 3000 );
|
|
|
|
selectedPosition = ( position[0], position[1], height );
|
|
startPoint = selectedPosition + VectorScale( direction, ( -14000 ) );
|
|
endPoint = selectedPosition + VectorScale( direction, ( -6000 ) );
|
|
|
|
// trace to get the target point
|
|
traceStartPos = ( position[0], position[1], height );
|
|
traceEndPos = ( position[0], position[1], -height );
|
|
trace = BulletTrace( traceStartPos, traceEndPos, 0, undefined );
|
|
targetPoint = ( ( trace[ "fraction" ] < 1.0 ) ? trace[ "position" ] : ( position[0], position[1], 0.0 ) );
|
|
|
|
///#sphere( targetPoint, 20, ( 1, 0, 0 ), 1, true, 10, 400 );#/
|
|
|
|
initialOffset = -VectorScale( direction, ( ( ( 12 ) * 0.5 ) - 1 ) * ( 500 ) );
|
|
|
|
for( i = 0; i < ( 12 ); i++ )
|
|
{
|
|
right = AnglesToRight( angles );
|
|
rightOffset = VectorScale( right, ( 300 ) );
|
|
leftOffset = VectorScale( right, ( 900 ) );
|
|
forwardOffset = endPoint + initialOffset + VectorScale( direction, i * ( 500 ) );
|
|
|
|
self thread SpawnDrone( startPoint + rightOffset, forwardOffset + rightOffset, targetPoint, angles, self.team, killstreak_id );
|
|
self thread SpawnDrone( startPoint - rightOffset, forwardOffset - rightOffset, targetPoint, angles, self.team, killstreak_id );
|
|
self thread SpawnDrone( startPoint + leftOffset, forwardOffset + leftOffset, targetPoint, angles, self.team, killstreak_id );
|
|
wait( ( 1 ) );
|
|
|
|
self playsound ("mpl_thunder_flyover_wash");
|
|
}
|
|
|
|
wait( 3 ); //Wait for the last drone to explode
|
|
self notify( "drone_strike_complete" );
|
|
}
|
|
|
|
function SpawnDrone( startPoint, endPoint, targetPoint, angles, team, killstreak_id )
|
|
{
|
|
drone = SpawnPlane( self, "script_model", startPoint );
|
|
drone.team = team;
|
|
drone.targetname = "drone_strike";
|
|
drone SetOwner( self );
|
|
drone.owner = self;
|
|
drone.owner thread WatchOwnerEvents( drone );
|
|
drone killstreaks::configure_team( "drone_strike", killstreak_id, self );
|
|
drone killstreak_hacking::enable_hacking( "drone_strike" );
|
|
Target_Set( drone );
|
|
|
|
drone endon( "delete" );
|
|
drone endon( "death" );
|
|
|
|
drone.angles = angles;
|
|
drone SetModel( "veh_t7_drone_rolling_thunder" );
|
|
drone SetEnemyModel( "veh_t7_drone_rolling_thunder" );
|
|
drone NotSolid();
|
|
|
|
PlayFxOnTag( "killstreaks/fx_rolling_thunder_thruster_trails", drone, "tag_fx");
|
|
drone clientfield::set( "enemyvehicle", 1 );
|
|
|
|
drone SetupDamageHandling();
|
|
drone thread WatchForEmp( self );
|
|
|
|
drone MoveTo( endpoint, ( 1.8 ), 0, 0 );
|
|
wait ( ( 1.8 ) );
|
|
|
|
weapon = GetWeapon( "drone_strike" );
|
|
velocity = drone GetVelocity();
|
|
|
|
halfGravity = 386;
|
|
dXY = Abs( ( -6000 ) );
|
|
dZ = endPoint[2] - targetPoint[2];
|
|
dVxy = dXY * sqrt( halfGravity / dZ );
|
|
|
|
nvel = VectorNormalize( velocity );
|
|
launchVel = nvel * dVxy;
|
|
|
|
bomb = self LaunchBomb( weapon, drone.origin, launchVel );
|
|
|
|
Target_Set( bomb );
|
|
|
|
bomb killstreaks::configure_team( "drone_strike", killstreak_id, self );
|
|
bomb killstreak_hacking::enable_hacking( "drone_strike" );
|
|
drone notify( "hackertool_update_ent", bomb );
|
|
|
|
bomb clientfield::set( "enemyvehicle", 1 );
|
|
bomb.targetname = "drone_strike";
|
|
bomb SetOwner( self );
|
|
bomb.owner = self;
|
|
bomb.team = team;
|
|
bomb playsound( "mpl_thunder_incoming_start" );
|
|
bomb SetupDamageHandling();
|
|
bomb thread WatchForEmp( self );
|
|
|
|
bomb.owner thread WatchOwnerEvents( bomb );
|
|
{wait(.05);};
|
|
|
|
drone Hide();
|
|
|
|
{wait(.05);};
|
|
|
|
drone Delete();
|
|
}
|
|
|
|
function SetupDamageHandling()
|
|
{
|
|
drone = self;
|
|
drone SetCanDamage( true );
|
|
drone.maxhealth = killstreak_bundles::get_max_health( "drone_strike" );
|
|
drone.lowhealth = killstreak_bundles::get_low_health( "drone_strike" );
|
|
drone.health = drone.maxhealth;
|
|
drone thread killstreaks::MonitorDamage( "drone_strike", drone.maxhealth, &DestroyDronePlane, drone.lowhealth, undefined, 0, &EmpDamageDrone, true );
|
|
}
|
|
|
|
function DestroyDronePlane( attacker, weapon )
|
|
{
|
|
self endon( "death" );
|
|
|
|
attacker = self [[ level.figure_out_attacker ]]( attacker );
|
|
if( isdefined( attacker ) && ( !isdefined( self.owner ) || self.owner util::IsEnemyPlayer( attacker ) ) )
|
|
{
|
|
challenges::destroyedAircraft( attacker, weapon, false );
|
|
attacker challenges::addFlySwatterStat( weapon, self );
|
|
scoreevents::processScoreEvent( "destroyed_rolling_thunder_drone", attacker, self.owner, weapon );
|
|
LUINotifyEvent( &"player_callout", 2, &"KILLSTREAK_DESTROYED_ROLLING_THUNDER_DRONE", attacker.entnum );
|
|
}
|
|
|
|
params = level.killstreakBundle["drone_strike"];
|
|
if( isdefined( params.ksExplosionFX ) )
|
|
PlayFXOnTag( params.ksExplosionFX, self, "tag_origin" );
|
|
|
|
self setModel( "tag_origin" );
|
|
|
|
wait( 0.5 );
|
|
|
|
self delete();
|
|
}
|
|
|
|
function WatchOwnerEvents( bomb )
|
|
{
|
|
player = self;
|
|
|
|
bomb endon( "death" );
|
|
|
|
player util::waittill_any( "disconnect", "joined_team", "joined_spectators" );
|
|
|
|
if( isdefined( isalive( bomb ) ) )
|
|
bomb delete();
|
|
}
|
|
|
|
function WatchForEmp( owner )
|
|
{
|
|
self endon( "delete" );
|
|
self endon( "death" );
|
|
|
|
self waittill( "emp_deployed", attacker );
|
|
|
|
thread DroneStrikeAwardEMPScoreEvent( attacker, self );
|
|
self BlowUpDroneStrike();
|
|
}
|
|
|
|
function EmpDamageDrone( attacker )
|
|
{
|
|
thread DroneStrikeAwardEMPScoreEvent( attacker, self );
|
|
self BlowUpDroneStrike();
|
|
}
|
|
|
|
function DroneStrikeAwardEMPScoreEvent( attacker, victim )
|
|
{
|
|
owner = self.owner;
|
|
|
|
attacker endon( "disconnect" );
|
|
attacker notify( "DroneStrikeAwardScoreEvent_singleton" );
|
|
attacker endon( "DroneStrikeAwardScoreEvent_singleton" );
|
|
waittillframeend;
|
|
|
|
attacker = self [[ level.figure_out_attacker ]]( attacker );
|
|
scoreevents::processScoreEvent( "destroyed_rolling_thunder_all_drones", attacker, victim, GetWeapon( "emp" ) );
|
|
challenges::destroyedAircraft( attacker, GetWeapon( "emp" ), false );
|
|
attacker challenges::addFlySwatterStat( GetWeapon( "emp" ), self );
|
|
LUINotifyEvent( &"player_callout", 2, &"KILLSTREAK_DESTROYED_ROLLING_THUNDER_ALL_DRONES", attacker.entnum );
|
|
|
|
owner globallogic_audio::play_taacom_dialog( "destroyed", "drone_strike" );
|
|
}
|
|
|
|
function BlowUpDroneStrike()
|
|
{
|
|
params = level.killstreakBundle["drone_strike"];
|
|
if( isdefined( self ) && isdefined( params.ksExplosionFX ) )
|
|
PlayFX( params.ksExplosionFX, self.origin );
|
|
self delete();
|
|
}
|