Files
Recompilable-gscs-for-BO2-z…/patch_mp/maps/mp/killstreaks/_missile_drone.gsc

695 lines
18 KiB
Plaintext

#include maps/mp/_challenges;
#include maps/mp/_scoreevents;
#include maps/mp/killstreaks/_dogs;
#include maps/mp/killstreaks/_missile_swarm;
#include maps/mp/_popups;
#include maps/mp/killstreaks/_killstreakrules;
#include maps/mp/killstreaks/_airsupport;
#include maps/mp/killstreaks/_killstreaks;
#include common_scripts/utility;
#include maps/mp/_utility;
#using_animtree( "mp_missile_drone" );
init()
{
registerclientfield( "toplayer", "missile_drone_active", 1, 2, "int" );
registerclientfield( "missile", "missile_drone_projectile_active", 1, 1, "int" );
registerclientfield( "missile", "missile_drone_projectile_animate", 1, 1, "int" );
level.missile_drone_flyheight = 2400;
level.missile_drone_anim = %o_drone_hunter_launch;
precacheitem( "missile_drone_projectile_mp" );
loadfx( "weapon/missile/fx_missile_drone_light_red" );
registerkillstreak( "inventory_missile_drone_mp", "inventory_missile_drone_mp", "killstreak_missile_drone", "missile_drone_used", ::missile_drone_killstreak, 1 );
registerkillstreakstrings( "inventory_missile_drone_mp", &"KILLSTREAK_EARNED_MISSILE_DRONE", &"KILLSTREAK_MISSILE_DRONE_NOT_AVAILABLE", &"KILLSTREAK_MISSILE_DRONE_INBOUND" );
registerkillstreakdialog( "inventory_missile_drone_mp", "mpl_killstreak_missile_drone", "kls_hkdrone_used", "", "kls_hkdrone_enemy", "", "kls_hkdrone_ready" );
registerkillstreakdevdvar( "inventory_missile_drone_mp", "scr_givemissiledrone" );
registerkillstreak( "missile_drone_mp", "missile_drone_mp", "killstreak_missile_drone", "missile_drone_used", ::missile_drone_killstreak, 1 );
registerkillstreakaltweapon( "missile_drone_mp", "missile_drone_projectile_mp" );
registerkillstreakaltweapon( "inventory_missile_drone_mp", "missile_drone_projectile_mp" );
registerkillstreakstrings( "missile_drone_mp", &"KILLSTREAK_EARNED_MISSILE_DRONE", &"KILLSTREAK_MISSILE_DRONE_NOT_AVAILABLE", &"KILLSTREAK_MISSILE_DRONE_INBOUND" );
registerkillstreakdialog( "missile_drone_mp", "mpl_killstreak_missile_drone", "kls_hkdrone_used", "", "kls_hkdrone_enemy", "", "kls_hkdrone_ready" );
setkillstreakteamkillpenaltyscale( "missile_drone_mp", 0 );
}
missile_drone_killstreak( weaponname )
{
/#
if ( weaponname != "missile_drone_mp" )
{
assert( weaponname == "inventory_missile_drone_mp" );
}
#/
level.missile_drone_origin = level.mapcenter + ( 0, 0, level.missile_drone_flyheight );
hardpointtype = "missile_drone_mp";
result = usemissiledrone( hardpointtype );
if ( !isDefined( result ) || !result )
{
return 0;
}
return result;
}
usemissiledrone( hardpointtype )
{
if ( self maps/mp/killstreaks/_killstreakrules::iskillstreakallowed( hardpointtype, self.team ) == 0 )
{
return 0;
}
self thread missiledronewatcher( hardpointtype );
missileweapon = self getcurrentweapon();
missileweapon = undefined;
currentweapon = self getcurrentweapon();
if ( ismissiledroneweapon( currentweapon ) )
{
missileweapon = currentweapon;
}
/#
assert( isDefined( missileweapon ) );
#/
notifystring = self waittill_any_return( "weapon_change", "grenade_fire", "death" );
if ( notifystring == "weapon_change" || notifystring == "death" )
{
return 0;
}
notifystring = self waittill_any_return( "weapon_change", "death" );
if ( notifystring == "death" )
{
return 1;
}
if ( !isDefined( missileweapon ) )
{
return 0;
}
self takeweapon( missileweapon );
if ( self hasweapon( missileweapon ) || self getammocount( missileweapon ) )
{
return 0;
}
return 1;
}
ismissiledroneweapon( weapon )
{
if ( weapon == "missile_drone_mp" || weapon == "inventory_missile_drone_mp" )
{
return 1;
}
return 0;
}
missiledronewatcher( hardpointtype )
{
self notify( "missileDroneWatcher" );
self endon( "missileDroneWatcher" );
self endon( "spawned_player" );
self endon( "disconnect" );
self endon( "weapon_change" );
self endon( "death" );
team = self.team;
killstreak_id = maps/mp/killstreaks/_killstreakrules::killstreakstart( hardpointtype, team, 0, 0 );
if ( killstreak_id == -1 )
{
self maps/mp/killstreaks/_killstreaks::switchtolastnonkillstreakweapon();
return;
}
self thread checkforemp();
self thread checkweaponchange( hardpointtype, team, killstreak_id );
self thread watchownerdeath( hardpointtype, team, killstreak_id );
self thread updatetargetting();
self waittill( "grenade_fire", grenade, weapname );
origin = grenade.origin;
self notify( "missile_drone_active" );
level thread maps/mp/_popups::displaykillstreakteammessagetoall( hardpointtype, self );
self maps/mp/killstreaks/_killstreaks::playkillstreakstartdialog( hardpointtype, self.team, 1 );
level.globalkillstreakscalled++;
self addweaponstat( "missile_drone_mp", "used", 1 );
self setclientfieldtoplayer( "missile_drone_active", 0 );
grenade thread waitthendelete( 0,05 );
grenade.origin += vectorScale( ( 0, 0, 1 ), 1000 );
self thread domissiledrone( origin, weapname, killstreak_id, hardpointtype, team );
self maps/mp/killstreaks/_killstreaks::switchtolastnonkillstreakweapon();
}
domissiledrone( origin, weapname, killstreak_id, hardpointtype, team )
{
direction = self getplayerangles();
forward = anglesToForward( direction );
target = origin + vectorScale( forward, 10000 );
debug_line( origin, target, ( 0,9, 0,1, 0,1 ) );
projectile = maps/mp/killstreaks/_missile_swarm::projectile_spawn_utility( self, target, origin, "missile_drone_projectile_mp", "drone_missile", 0 );
projectile missile_dronesetvisible( 1 );
projectile.originaltarget = target;
projectile thread maps/mp/killstreaks/_missile_swarm::projectile_abort_think();
projectile thread drone_target_search( hardpointtype );
projectile thread projectile_death_think();
projectile thread watchdamage();
projectile.targetname = "remote_drone";
projectile playsound( "wpn_hunter_ignite" );
projectile thread killstreak_stop_think( killstreak_id, hardpointtype, team );
projectile setclientfield( "missile_drone_projectile_animate", 1 );
}
waitthendelete( waittime )
{
self endon( "delete" );
self endon( "death" );
wait waittime;
self delete();
}
projectile_death_think()
{
self waittill( "death" );
self.goal delete();
}
drone_target_acquired( hardpointtype, target )
{
self endon( "death" );
self notify( "drone_target_acquired" );
self setclientfield( "missile_drone_projectile_active", 1 );
self set_drone_target( hardpointtype, target );
}
drone_target_search( hardpointtype )
{
self endon( "death" );
if ( isDefined( self.dronetarget ) )
{
self drone_target_acquired( hardpointtype, self.dronetarget );
self missile_settarget( self.goal );
}
self setclientfield( "missile_drone_projectile_active", 0 );
searchdotprodminimums = [];
searchdotprodminimums[ 0 ] = 0,9;
searchdotprodminimums[ 1 ] = 0,7071;
searchdotprodminimums[ 2 ] = 0,5;
searchdotprodminimums[ 3 ] = 0;
wait 0,1;
searchcounter = 0;
for ( ;; )
{
if ( !isDefined( self ) )
{
self notify( "death" );
}
target = self projectile_find_target( self.owner, searchdotprodminimums[ searchcounter ] );
if ( searchcounter < ( searchdotprodminimums.size - 1 ) )
{
searchcounter++;
}
else if ( level.missile_drone_origin[ 2 ] != self.goal.origin[ 2 ] )
{
currentangles = self.angles;
direction = vectornormalize( anglesToForward( self.angles ) );
direction = vecscale( direction, 1024 );
self.goal.origin = ( self.origin[ 0 ] + direction[ 0 ], self.origin[ 1 ] + direction[ 1 ], level.missile_drone_origin[ 2 ] );
/#
debug_line( self.origin, self.goal.origin, ( 0, 0, 1 ), 5000 );
#/
}
else
{
currentangles = self.angles;
direction = vectornormalize( anglesToForward( self.angles ) );
direction = vecscale( direction, 1024 );
self.goal.origin = ( level.missile_drone_origin[ 0 ] + direction[ 0 ], level.missile_drone_origin[ 1 ] + direction[ 1 ], level.missile_drone_origin[ 2 ] );
/#
debug_line( self.origin, self.goal.origin, ( 0, 1, 1 ), 5000 );
#/
}
if ( isDefined( target ) )
{
self set_drone_target( hardpointtype, target );
self missile_settarget( self.goal );
}
wait 0,25;
}
}
vecscale( vec, scalar )
{
return ( vec[ 0 ] * scalar, vec[ 1 ] * scalar, vec[ 2 ] * scalar );
}
set_drone_target( hardpointtype, target )
{
self endon( "target_lost" );
self thread check_target_lost( target );
self.swarm_target = target[ "entity" ];
target[ "entity" ].swarm = self;
debug_line( self.origin, target[ "entity" ].origin, ( 0, 0, 1 ), 5000 );
self missile_settarget( target[ "entity" ], target[ "offset" ] );
self playsound( "veh_harpy_drone_swarm_incomming" );
if ( !isDefined( target[ "entity" ].swarmsound ) || target[ "entity" ].swarmsound == 0 )
{
self thread target_sounds( target[ "entity" ] );
}
target[ "entity" ] notify( "stinger_fired_at_me" );
self setclientfield( "missile_drone_projectile_active", 1 );
target[ "entity" ] waittill_any( "death", "disconnect", "joined_team" );
self setclientfield( "missile_drone_projectile_active", 0 );
self missile_settarget( self.goal );
}
check_target_lost( target )
{
self endon( "death" );
target[ "entity" ] endon( "death" );
target[ "entity" ] endon( "disconnect" );
target[ "entity" ] endon( "joined_team" );
failurelimit = 3;
failurecount = 0;
for ( ;; )
{
/#
debug_star( target[ "entity" ].origin, ( 0, 0, 1 ), 1000 );
debug_star( self.origin, ( 0, 0, 1 ), 1000 );
#/
if ( bullettracepassed( self.origin, target[ "entity" ].origin + target[ "offset" ], 0, target[ "entity" ] ) )
{
/#
debug_line( self.origin, target[ "entity" ].origin, ( 0, 0, 1 ), 1000 );
#/
failurecount = 0;
}
else
{
failurecount++;
if ( failurecount >= failurelimit )
{
self notify( "target_lost" );
return;
}
}
wait 0,25;
}
}
projectile_find_target( owner, mincos )
{
ks = self projectile_find_target_killstreak( owner, mincos );
player = self projectile_find_target_player( owner, mincos );
if ( isDefined( ks ) && !isDefined( player ) )
{
return ks;
}
else
{
if ( !isDefined( ks ) && isDefined( player ) )
{
return player;
}
else
{
if ( isDefined( ks ) && isDefined( player ) )
{
if ( player[ "dotprod" ] < ks[ "dotprod" ] )
{
return ks;
}
return player;
}
}
}
return undefined;
}
projectile_find_target_killstreak( owner, mincos )
{
ks = [];
ks[ "offset" ] = vectorScale( ( 0, 0, 1 ), 10 );
targets = target_getarray();
rcbombs = getentarray( "rcbomb", "targetname" );
dogs = maps/mp/killstreaks/_dogs::dog_manager_get_dogs();
targets = arraycombine( targets, rcbombs, 1, 0 );
targets = arraycombine( targets, dogs, 1, 0 );
if ( targets.size <= 0 )
{
return undefined;
}
targets = get_array_sorted_dot_prod( targets, mincos );
_a389 = targets;
_k389 = getFirstArrayKey( _a389 );
while ( isDefined( _k389 ) )
{
target = _a389[ _k389 ];
if ( isDefined( target.owner ) && target.owner == owner )
{
}
else
{
if ( isDefined( target.script_owner ) && target.script_owner == owner )
{
break;
}
else
{
if ( level.teambased && isDefined( target.team ) )
{
if ( target.team == self.team )
{
break;
}
}
else if ( level.teambased && isDefined( target.aiteam ) )
{
if ( target.aiteam == self.team )
{
break;
}
}
else if ( isDefined( target.vehicletype ) && target.vehicletype == "heli_supplydrop_mp" )
{
break;
}
else
{
if ( bullettracepassed( self.origin, target.origin, 0, target ) )
{
ks[ "entity" ] = target;
if ( isDefined( target.sorteddotprod ) )
{
ks[ "dotprod" ] = target.sorteddotprod;
}
else
{
ks[ "dotprod" ] = -1;
}
return ks;
}
}
}
}
_k389 = getNextArrayKey( _a389, _k389 );
}
return undefined;
}
projectile_find_target_player( owner, mincos )
{
target = [];
players = self get_array_sorted_dot_prod( get_players(), mincos );
if ( isplayer( self ) )
{
startoffset = self getplayerviewheight();
startorigin = ( self.origin[ 0 ], self.origin[ 1 ], self.origin[ 2 ] + startoffset );
startangles = self getplayerangles();
/#
debug_star( startorigin, ( 0, 0, 1 ), 1000 );
#/
}
else
{
startorigin = self.origin;
startangles = self.angles;
}
bestplayerrating = -1;
_a470 = players;
_k470 = getFirstArrayKey( _a470 );
while ( isDefined( _k470 ) )
{
player = _a470[ _k470 ];
if ( !player_valid_target( player, owner.team, owner ) )
{
}
else
{
currentplayeroffset = undefined;
currentplayerdotprod = undefined;
currentplayerrating = 0;
/#
debug_star( player.origin, ( 0, 0, 1 ), 1000 );
#/
if ( bullettracepassed( startorigin, player.origin, 0, player ) )
{
/#
debug_line( startorigin, player.origin, ( 0, 0, 1 ), 1000 );
#/
if ( !isDefined( currentplayeroffset ) )
{
currentplayeroffset = ( 0, 0, 1 );
}
currentplayerrating += 4;
}
verticaloffset = player getplayerviewheight();
playerheadoffset = ( 0, 0, verticaloffset );
/#
debug_star( player.origin + playerheadoffset, ( 0, 0, 1 ), 1000 );
#/
if ( bullettracepassed( startorigin, player.origin + playerheadoffset, 0, player ) )
{
/#
debug_line( startorigin, player.origin + playerheadoffset, ( 0, 0, 1 ), 1000 );
#/
if ( !isDefined( currentplayeroffset ) )
{
currentplayeroffset = playerheadoffset;
}
currentplayerrating += 3;
}
end = player.origin + playerheadoffset + vectorScale( ( 0, 0, 1 ), 96 );
/#
debug_star( end, ( 0, 0, 1 ), 1000 );
#/
if ( bullettracepassed( player.origin + playerheadoffset, end, 0, player ) )
{
/#
debug_line( player.origin + playerheadoffset, end, ( 0, 0, 1 ), 1000 );
#/
if ( !isDefined( currentplayeroffset ) )
{
currentplayeroffset = vectorScale( ( 0, 0, 1 ), 30 );
}
currentplayerrating += 2;
}
if ( currentplayerrating > bestplayerrating )
{
bestplayerrating = currentplayerrating;
target[ "entity" ] = player;
target[ "offset" ] = currentplayeroffset;
if ( isDefined( player.sorteddotprod ) )
{
target[ "dotprod" ] = player.sorteddotprod;
}
else
{
target[ "dotprod" ] = -1;
}
if ( bestplayerrating >= 9 )
{
return target;
}
}
}
_k470 = getNextArrayKey( _a470, _k470 );
}
if ( bestplayerrating >= 3 )
{
return target;
}
return undefined;
}
killstreak_stop_think( killstreak_id, hardpointtype, team )
{
self waittill( "death" );
maps/mp/killstreaks/_killstreakrules::killstreakstop( hardpointtype, team, killstreak_id );
}
checkweaponchange( hardpointtype, team, killstreak_id )
{
self endon( "spawned_player" );
self endon( "death" );
self endon( "disconnect" );
self endon( "grenade_fire" );
self waittill( "weapon_change" );
self setclientfieldtoplayer( "missile_drone_active", 0 );
maps/mp/killstreaks/_killstreakrules::killstreakstop( hardpointtype, team, killstreak_id );
}
watchownerdeath( hardpointtype, team, killstreak_id )
{
self endon( "spawned_player" );
self endon( "disconnect" );
self endon( "weapon_change" );
self endon( "missile_drone_active" );
self waittill( "death" );
maps/mp/killstreaks/_killstreakrules::killstreakstop( hardpointtype, team, killstreak_id );
}
checkforemp()
{
self endon( "spawned_player" );
self endon( "disconnect" );
self endon( "weapon_change" );
self endon( "death" );
self endon( "grenade_fire" );
self waittill( "emp_jammed" );
self setclientfieldtoplayer( "missile_drone_active", 0 );
self maps/mp/killstreaks/_killstreaks::switchtolastnonkillstreakweapon();
}
watchdamage()
{
self endon( "death" );
self setcandamage( 1 );
self.maxhealth = 100000;
self.health = self.maxhealth;
for ( ;; )
{
self waittill( "damage", damage, attacker, direction, point, type, tagname, modelname, partname, weaponname );
if ( !isDefined( attacker ) || !isplayer( attacker ) )
{
continue;
}
else
{
if ( isplayer( attacker ) && level.teambased && isDefined( attacker.team ) && self.team == attacker.team && level.friendlyfire == 0 )
{
break;
}
else
{
if ( self.owner isenemyplayer( attacker ) )
{
maps/mp/_scoreevents::processscoreevent( "destroyed_missile_drone", attacker, self.owner, weaponname );
attacker maps/mp/_challenges::addflyswatterstat( weaponname, self );
break;
}
self detonate();
}
}
}
}
get_array_sorted_dot_prod( array, mincos )
{
if ( isplayer( self ) )
{
org = self.origin;
angles = self getplayerangles();
/#
assert( isDefined( angles ) );
#/
}
else
{
org = self.origin;
/#
assert( isDefined( self.angles ) );
#/
angles = self.angles;
}
forwardvec = vectornormalize( anglesToForward( angles ) );
dotprod = [];
index = [];
i = 0;
while ( i < array.size )
{
/#
assert( isDefined( forwardvec ) );
#/
/#
assert( isDefined( array[ i ] ) );
#/
/#
assert( isDefined( array[ i ].origin ) );
#/
/#
assert( isDefined( org ) );
#/
cosa = vectordot( forwardvec, vectornormalize( array[ i ].origin - org ) );
/#
assert( isDefined( cosa ) );
#/
if ( isDefined( mincos ) && cosa < mincos )
{
i++;
continue;
}
else
{
array[ i ].sorteddotprod = cosa;
dotprod[ dotprod.size ] = cosa;
index[ index.size ] = i;
}
i++;
}
for ( ;; )
{
change = 0;
i = 0;
while ( i < ( dotprod.size - 1 ) )
{
if ( dotprod[ i ] >= dotprod[ i + 1 ] )
{
i++;
continue;
}
else
{
change = 1;
temp = dotprod[ i ];
dotprod[ i ] = dotprod[ i + 1 ];
dotprod[ i + 1 ] = temp;
temp = index[ i ];
index[ i ] = index[ i + 1 ];
index[ i + 1 ] = temp;
}
i++;
}
if ( !change )
{
break;
}
else
{
}
}
newarray = [];
i = 0;
while ( i < dotprod.size )
{
newarray[ i ] = array[ index[ i ] ];
i++;
}
return newarray;
}
updatetargetting()
{
self endon( "spawned_player" );
self endon( "disconnect" );
self endon( "weapon_change" );
self endon( "death" );
self endon( "grenade_fire" );
mincos = getdvarfloatdefault( "scr_missile_drone_min_cos", 0,9 );
updatewait = getdvarfloatdefault( "scr_missile_drone_update_wait", 0,5 );
for ( ;; )
{
self.dronetarget = self projectile_find_target( self, mincos );
if ( isDefined( self.dronetarget ) )
{
self thread clearinvaliddronetarget();
self setclientfieldtoplayer( "missile_drone_active", 2 );
}
else
{
self setclientfieldtoplayer( "missile_drone_active", 1 );
}
wait updatewait;
}
}
clearinvaliddronetarget()
{
self endon( "death" );
self notify( "clearInvalidDroneTarget" );
self endon( "clearInvalidDroneTarget" );
self endon( "drone_target_acquired" );
self.dronetarget[ "entity" ] waittill_any( "death", "disconnect", "joined_team" );
self.dronetarget = undefined;
}