mirror of
https://github.com/JezuzLizard/Recompilable-gscs-for-BO2-zombies-and-multiplayer.git
synced 2025-06-10 10:47:58 -05:00
1147 lines
27 KiB
Plaintext
1147 lines
27 KiB
Plaintext
#include maps/mp/_scoreevents;
|
|
#include maps/mp/gametypes/_globallogic_audio;
|
|
#include maps/mp/_popups;
|
|
#include maps/mp/gametypes/_damagefeedback;
|
|
#include maps/mp/gametypes/_globallogic_player;
|
|
#include maps/mp/gametypes/_weaponobjects;
|
|
#include maps/mp/_heatseekingmissile;
|
|
#include maps/mp/killstreaks/_killstreakrules;
|
|
#include maps/mp/_challenges;
|
|
#include maps/mp/gametypes/_hostmigration;
|
|
#include maps/mp/killstreaks/_radar;
|
|
#include maps/mp/gametypes/_spawnlogic;
|
|
#include maps/mp/gametypes/_battlechatter_mp;
|
|
#include maps/mp/killstreaks/_airsupport;
|
|
#include common_scripts/utility;
|
|
#include maps/mp/gametypes/_hud_util;
|
|
#include maps/mp/_utility;
|
|
|
|
init()
|
|
{
|
|
level.spyplanemodel = "veh_t6_drone_uav";
|
|
level.counteruavmodel = "veh_t6_drone_cuav";
|
|
level.u2_maxhealth = 700;
|
|
level.spyplane = [];
|
|
level.spyplaneentrancetime = 5;
|
|
level.spyplaneexittime = 10;
|
|
level.counteruavweapon = "counteruav_mp";
|
|
level.counteruavlength = 25;
|
|
precachemodel( level.spyplanemodel );
|
|
precachemodel( level.counteruavmodel );
|
|
level.counteruavplaneentrancetime = 5;
|
|
level.counteruavplaneexittime = 10;
|
|
level.counteruavlight = loadfx( "vehicle/light/fx_cuav_lights_red" );
|
|
level.uavlight = loadfx( "vehicle/light/fx_u2_lights_red" );
|
|
level.fx_spyplane_afterburner = loadfx( "vehicle/exhaust/fx_exhaust_u2_spyplane_afterburner" );
|
|
level.fx_spyplane_burner = loadfx( "vehicle/exhaust/fx_exhaust_u2_spyplane_burner" );
|
|
level.fx_cuav_afterburner = loadfx( "vehicle/exhaust/fx_exhaust_cuav_afterburner" );
|
|
level.fx_cuav_burner = loadfx( "vehicle/exhaust/fx_exhaust_cuav_burner" );
|
|
level.satelliteheight = 10000;
|
|
level.satelliteflydistance = 10000;
|
|
level.fx_u2_damage_trail = loadfx( "trail/fx_trail_u2_plane_damage_mp" );
|
|
level.fx_u2_explode = loadfx( "vehicle/vexplosion/fx_vexplode_u2_exp_mp" );
|
|
minimaporigins = getentarray( "minimap_corner", "targetname" );
|
|
if ( minimaporigins.size )
|
|
{
|
|
uavorigin = maps/mp/gametypes/_spawnlogic::findboxcenter( minimaporigins[ 0 ].origin, minimaporigins[ 1 ].origin );
|
|
}
|
|
else
|
|
{
|
|
uavorigin = ( 0, 0, 1 );
|
|
}
|
|
if ( level.script == "mp_hydro" )
|
|
{
|
|
uavorigin += vectorScale( ( 0, 0, 1 ), 1200 );
|
|
}
|
|
if ( level.teambased )
|
|
{
|
|
_a54 = level.teams;
|
|
_k54 = getFirstArrayKey( _a54 );
|
|
while ( isDefined( _k54 ) )
|
|
{
|
|
team = _a54[ _k54 ];
|
|
level.activeuavs[ team ] = 0;
|
|
level.activecounteruavs[ team ] = 0;
|
|
level.activesatellites[ team ] = 0;
|
|
_k54 = getNextArrayKey( _a54, _k54 );
|
|
}
|
|
}
|
|
else level.activeuavs = [];
|
|
level.activecounteruavs = [];
|
|
level.activesatellites = [];
|
|
level.uavrig = spawn( "script_model", uavorigin + vectorScale( ( 0, 0, 1 ), 1100 ) );
|
|
level.uavrig setmodel( "tag_origin" );
|
|
level.uavrig.angles = vectorScale( ( 0, 0, 1 ), 115 );
|
|
level.uavrig hide();
|
|
level.uavrig thread rotateuavrig( 1 );
|
|
level.uavrig thread swayuavrig();
|
|
level.counteruavrig = spawn( "script_model", uavorigin + vectorScale( ( 0, 0, 1 ), 1500 ) );
|
|
level.counteruavrig setmodel( "tag_origin" );
|
|
level.counteruavrig.angles = vectorScale( ( 0, 0, 1 ), 115 );
|
|
level.counteruavrig hide();
|
|
level.counteruavrig thread rotateuavrig( 0 );
|
|
level.counteruavrig thread swayuavrig();
|
|
level thread uavtracker();
|
|
level thread onplayerconnect();
|
|
}
|
|
|
|
onplayerconnect()
|
|
{
|
|
for ( ;; )
|
|
{
|
|
level waittill( "connected", player );
|
|
player.entnum = player getentitynumber();
|
|
level.activeuavs[ player.entnum ] = 0;
|
|
level.activecounteruavs[ player.entnum ] = 0;
|
|
level.activesatellites[ player.entnum ] = 0;
|
|
if ( level.teambased == 0 || level.multiteam == 1 )
|
|
{
|
|
player thread watchffaandmultiteamspawn();
|
|
}
|
|
}
|
|
}
|
|
|
|
watchffaandmultiteamspawn()
|
|
{
|
|
self endon( "disconnect" );
|
|
for ( ;; )
|
|
{
|
|
self waittill( "spawned_player" );
|
|
level notify( "uav_update" );
|
|
}
|
|
}
|
|
|
|
rotateuavrig( clockwise )
|
|
{
|
|
turn = 360;
|
|
if ( clockwise )
|
|
{
|
|
turn = -360;
|
|
}
|
|
for ( ;; )
|
|
{
|
|
if ( !clockwise )
|
|
{
|
|
self rotateyaw( turn, 40 );
|
|
wait 40;
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
self rotateyaw( turn, 60 );
|
|
wait 60;
|
|
}
|
|
}
|
|
}
|
|
|
|
swayuavrig()
|
|
{
|
|
centerorigin = self.origin;
|
|
for ( ;; )
|
|
{
|
|
z = randomintrange( -200, -100 );
|
|
time = randomintrange( 3, 6 );
|
|
self moveto( centerorigin + ( 0, 0, z ), time, 1, 1 );
|
|
wait time;
|
|
z = randomintrange( 100, 200 );
|
|
time = randomintrange( 3, 6 );
|
|
self moveto( centerorigin + ( 0, 0, z ), time, 1, 1 );
|
|
wait time;
|
|
}
|
|
}
|
|
|
|
callcounteruav( type, displaymessage, killstreak_id )
|
|
{
|
|
timeinair = self maps/mp/killstreaks/_radar::useradaritem( type, self.team, displaymessage );
|
|
iscounter = 1;
|
|
counteruavplane = generateplane( self, timeinair, iscounter );
|
|
if ( !isDefined( counteruavplane ) )
|
|
{
|
|
return 0;
|
|
}
|
|
counteruavplane thread counteruav_watchfor_gamerules_destruction( self );
|
|
counteruavplane setclientflag( 11 );
|
|
counteruavplane addactivecounteruav();
|
|
self.counteruavtime = getTime();
|
|
counteruavplane thread playcounterspyplanefx();
|
|
counteruavplane thread counteruavplane_death_waiter();
|
|
counteruavplane thread counteruavplane_timeout( timeinair, self );
|
|
counteruavplane thread plane_damage_monitor( 0 );
|
|
counteruavplane thread plane_health();
|
|
counteruavplane.killstreak_id = killstreak_id;
|
|
counteruavplane.iscounter = 1;
|
|
counteruavplane playloopsound( "veh_uav_engine_loop", 1 );
|
|
return 1;
|
|
}
|
|
|
|
callspyplane( type, displaymessage, killstreak_id )
|
|
{
|
|
timeinair = self maps/mp/killstreaks/_radar::useradaritem( type, self.team, displaymessage );
|
|
iscounter = 0;
|
|
spyplane = generateplane( self, timeinair, iscounter );
|
|
if ( !isDefined( spyplane ) )
|
|
{
|
|
return 0;
|
|
}
|
|
spyplane thread spyplane_watchfor_gamerules_destruction( self );
|
|
spyplane addactiveuav();
|
|
self.uavtime = getTime();
|
|
spyplane.leaving = 0;
|
|
spyplane thread playspyplanefx();
|
|
spyplane thread spyplane_timeout( timeinair, self );
|
|
spyplane thread spyplane_death_waiter();
|
|
spyplane thread plane_damage_monitor( 1 );
|
|
spyplane thread plane_health();
|
|
spyplane.killstreak_id = killstreak_id;
|
|
spyplane.iscounter = 0;
|
|
spyplane playloopsound( "veh_uav_engine_loop", 1 );
|
|
return 1;
|
|
}
|
|
|
|
callsatellite( type, displaymessage, killstreak_id )
|
|
{
|
|
timeinair = self maps/mp/killstreaks/_radar::useradaritem( type, self.team, displaymessage );
|
|
satellite = spawn( "script_model", level.mapcenter + ( 0 - level.satelliteflydistance, 0, level.satelliteheight ) );
|
|
satellite setmodel( "tag_origin" );
|
|
satellite moveto( level.mapcenter + ( level.satelliteflydistance, 0, level.satelliteheight ), timeinair );
|
|
satellite.owner = self;
|
|
satellite.team = self.team;
|
|
satellite setteam( self.team );
|
|
satellite setowner( self );
|
|
satellite.targetname = "satellite";
|
|
satellite addactivesatellite();
|
|
self.satellitetime = getTime();
|
|
satellite thread satellite_timeout( timeinair, self );
|
|
satellite thread satellite_watchfor_gamerules_destruction( self );
|
|
satellite.iscounter = 0;
|
|
if ( level.teambased )
|
|
{
|
|
satellite thread updatevisibility();
|
|
}
|
|
satellite.killstreak_id = killstreak_id;
|
|
return 1;
|
|
}
|
|
|
|
spyplane_watchfor_gamerules_destruction( player )
|
|
{
|
|
self endon( "death" );
|
|
self endon( "crashing" );
|
|
self endon( "delete" );
|
|
player waittill_any( "joined_team", "disconnect", "joined_spectators" );
|
|
self spyplane_death();
|
|
}
|
|
|
|
counteruav_watchfor_gamerules_destruction( player )
|
|
{
|
|
self endon( "death" );
|
|
self endon( "crashing" );
|
|
self endon( "delete" );
|
|
player waittill_any( "joined_team", "disconnect", "joined_spectators" );
|
|
maps/mp/gametypes/_hostmigration::waittillhostmigrationdone();
|
|
self counteruavplane_death();
|
|
}
|
|
|
|
satellite_watchfor_gamerules_destruction( player )
|
|
{
|
|
self endon( "death" );
|
|
self endon( "delete" );
|
|
player waittill_any( "joined_team", "disconnect", "joined_spectators" );
|
|
maps/mp/gametypes/_hostmigration::waittillhostmigrationdone();
|
|
self removeactivesatellite();
|
|
self delete();
|
|
}
|
|
|
|
addactivecounteruav()
|
|
{
|
|
if ( level.teambased )
|
|
{
|
|
self.owner.activecounteruavs++;
|
|
level.activecounteruavs[ self.team ]++;
|
|
_a284 = level.teams;
|
|
_k284 = getFirstArrayKey( _a284 );
|
|
while ( isDefined( _k284 ) )
|
|
{
|
|
team = _a284[ _k284 ];
|
|
if ( team == self.team )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
if ( level.activesatellites[ team ] > 0 )
|
|
{
|
|
self.owner maps/mp/_challenges::blockedsatellite();
|
|
}
|
|
}
|
|
_k284 = getNextArrayKey( _a284, _k284 );
|
|
}
|
|
}
|
|
else /#
|
|
assert( isDefined( self.owner.entnum ) );
|
|
#/
|
|
if ( !isDefined( self.owner.entnum ) )
|
|
{
|
|
self.owner.entnum = self.owner getentitynumber();
|
|
}
|
|
level.activecounteruavs[ self.owner.entnum ]++;
|
|
keys = getarraykeys( level.activecounteruavs );
|
|
i = 0;
|
|
while ( i < keys.size )
|
|
{
|
|
if ( keys[ i ] == self.owner.entnum )
|
|
{
|
|
i++;
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
if ( level.activecounteruavs[ keys[ i ] ] )
|
|
{
|
|
self.owner maps/mp/_challenges::blockedsatellite();
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
i++;
|
|
}
|
|
}
|
|
level notify( "uav_update" );
|
|
}
|
|
|
|
addactiveuav()
|
|
{
|
|
if ( level.teambased )
|
|
{
|
|
self.owner.activeuavs++;
|
|
level.activeuavs[ self.team ]++;
|
|
}
|
|
else
|
|
{
|
|
/#
|
|
assert( isDefined( self.owner.entnum ) );
|
|
#/
|
|
if ( !isDefined( self.owner.entnum ) )
|
|
{
|
|
self.owner.entnum = self.owner getentitynumber();
|
|
}
|
|
level.activeuavs[ self.owner.entnum ]++;
|
|
}
|
|
level notify( "uav_update" );
|
|
}
|
|
|
|
addactivesatellite()
|
|
{
|
|
if ( level.teambased )
|
|
{
|
|
self.owner.activesatellites++;
|
|
level.activesatellites[ self.team ]++;
|
|
}
|
|
else
|
|
{
|
|
/#
|
|
assert( isDefined( self.owner.entnum ) );
|
|
#/
|
|
if ( !isDefined( self.owner.entnum ) )
|
|
{
|
|
self.owner.entnum = self.owner getentitynumber();
|
|
}
|
|
level.activesatellites[ self.owner.entnum ]++;
|
|
}
|
|
level notify( "uav_update" );
|
|
}
|
|
|
|
removeactiveuav()
|
|
{
|
|
if ( level.teambased )
|
|
{
|
|
if ( isDefined( self.owner ) && self.owner.spawntime < self.birthtime )
|
|
{
|
|
self.owner.activeuavs--;
|
|
|
|
/#
|
|
assert( self.owner.activeuavs >= 0 );
|
|
#/
|
|
if ( self.owner.activeuavs < 0 )
|
|
{
|
|
self.owner.activeuavs = 0;
|
|
}
|
|
}
|
|
level.activeuavs[ self.team ]--;
|
|
|
|
/#
|
|
assert( level.activeuavs[ self.team ] >= 0 );
|
|
#/
|
|
if ( level.activeuavs[ self.team ] < 0 )
|
|
{
|
|
level.activeuavs[ self.team ] = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( isDefined( self.owner ) )
|
|
{
|
|
/#
|
|
assert( isDefined( self.owner.entnum ) );
|
|
#/
|
|
if ( !isDefined( self.owner.entnum ) )
|
|
{
|
|
self.owner.entnum = self.owner getentitynumber();
|
|
}
|
|
level.activeuavs[ self.owner.entnum ]--;
|
|
|
|
/#
|
|
assert( level.activeuavs[ self.owner.entnum ] >= 0 );
|
|
#/
|
|
if ( level.activeuavs[ self.owner.entnum ] < 0 )
|
|
{
|
|
level.activeuavs[ self.owner.entnum ] = 0;
|
|
}
|
|
}
|
|
}
|
|
maps/mp/killstreaks/_killstreakrules::killstreakstop( "radar_mp", self.team, self.killstreak_id );
|
|
level notify( "uav_update" );
|
|
}
|
|
|
|
removeactivecounteruav()
|
|
{
|
|
if ( level.teambased )
|
|
{
|
|
if ( isDefined( self.owner ) && self.owner.spawntime < self.birthtime )
|
|
{
|
|
self.owner.activecounteruavs--;
|
|
|
|
/#
|
|
assert( self.owner.activecounteruavs >= 0 );
|
|
#/
|
|
if ( self.owner.activecounteruavs < 0 )
|
|
{
|
|
self.owner.activecounteruavs = 0;
|
|
}
|
|
}
|
|
level.activecounteruavs[ self.team ]--;
|
|
|
|
/#
|
|
assert( level.activecounteruavs[ self.team ] >= 0 );
|
|
#/
|
|
if ( level.activecounteruavs[ self.team ] < 0 )
|
|
{
|
|
level.activecounteruavs[ self.team ] = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( isDefined( self.owner ) )
|
|
{
|
|
/#
|
|
assert( isDefined( self.owner.entnum ) );
|
|
#/
|
|
if ( !isDefined( self.owner.entnum ) )
|
|
{
|
|
self.owner.entnum = self.owner getentitynumber();
|
|
}
|
|
level.activecounteruavs[ self.owner.entnum ]--;
|
|
|
|
/#
|
|
assert( level.activecounteruavs[ self.owner.entnum ] >= 0 );
|
|
#/
|
|
if ( level.activecounteruavs[ self.owner.entnum ] < 0 )
|
|
{
|
|
level.activecounteruavs[ self.owner.entnum ] = 0;
|
|
}
|
|
}
|
|
}
|
|
maps/mp/killstreaks/_killstreakrules::killstreakstop( "counteruav_mp", self.team, self.killstreak_id );
|
|
level notify( "uav_update" );
|
|
}
|
|
|
|
removeactivesatellite()
|
|
{
|
|
if ( level.teambased )
|
|
{
|
|
if ( self.owner.spawntime < self.birthtime && isDefined( self.owner ) )
|
|
{
|
|
self.owner.activesatellites--;
|
|
|
|
/#
|
|
assert( self.owner.activesatellites >= 0 );
|
|
#/
|
|
if ( self.owner.activesatellites < 0 )
|
|
{
|
|
self.owner.activesatellites = 0;
|
|
}
|
|
}
|
|
level.activesatellites[ self.team ]--;
|
|
|
|
/#
|
|
assert( level.activesatellites[ self.team ] >= 0 );
|
|
#/
|
|
if ( level.activesatellites[ self.team ] < 0 )
|
|
{
|
|
level.activesatellites[ self.team ] = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( isDefined( self.owner ) )
|
|
{
|
|
/#
|
|
assert( isDefined( self.owner.entnum ) );
|
|
#/
|
|
if ( !isDefined( self.owner.entnum ) )
|
|
{
|
|
self.owner.entnum = self.owner getentitynumber();
|
|
}
|
|
level.activesatellites[ self.owner.entnum ]--;
|
|
|
|
/#
|
|
assert( level.activesatellites[ self.owner.entnum ] >= 0 );
|
|
#/
|
|
if ( level.activesatellites[ self.owner.entnum ] < 0 )
|
|
{
|
|
level.activesatellites[ self.owner.entnum ] = 0;
|
|
}
|
|
}
|
|
}
|
|
maps/mp/killstreaks/_killstreakrules::killstreakstop( "radardirection_mp", self.team, self.killstreak_id );
|
|
level notify( "uav_update" );
|
|
}
|
|
|
|
playspyplanefx()
|
|
{
|
|
wait 0,1;
|
|
playfxontag( level.fx_spyplane_burner, self, "tag_origin" );
|
|
}
|
|
|
|
playspyplaneafterburnerfx()
|
|
{
|
|
self endon( "death" );
|
|
wait 0,1;
|
|
playfxontag( level.fx_spyplane_afterburner, self, "tag_origin" );
|
|
}
|
|
|
|
playcounterspyplanefx()
|
|
{
|
|
wait 0,1;
|
|
if ( isDefined( self ) )
|
|
{
|
|
playfxontag( level.fx_cuav_burner, self, "tag_origin" );
|
|
}
|
|
}
|
|
|
|
playcounterspyplaneafterburnerfx()
|
|
{
|
|
self endon( "death" );
|
|
wait 0,1;
|
|
playfxontag( level.fx_cuav_afterburner, self, "tag_origin" );
|
|
}
|
|
|
|
playuavpilotdialog( dialog, owner, delaytime )
|
|
{
|
|
if ( isDefined( delaytime ) )
|
|
{
|
|
wait delaytime;
|
|
}
|
|
self.pilotvoicenumber = owner.bcvoicenumber + 1;
|
|
soundalias = level.teamprefix[ owner.team ] + self.pilotvoicenumber + "_" + dialog;
|
|
while ( isDefined( owner.pilotisspeaking ) )
|
|
{
|
|
while ( owner.pilotisspeaking )
|
|
{
|
|
while ( owner.pilotisspeaking )
|
|
{
|
|
wait 0,2;
|
|
}
|
|
}
|
|
}
|
|
if ( isDefined( owner ) )
|
|
{
|
|
owner playlocalsound( soundalias );
|
|
owner.pilotisspeaking = 1;
|
|
owner thread waitplaybacktime( soundalias );
|
|
owner waittill_any( soundalias, "death", "disconnect" );
|
|
owner.pilotisspeaking = 0;
|
|
}
|
|
}
|
|
|
|
generateplane( owner, timeinair, iscounter )
|
|
{
|
|
uavrig = level.uavrig;
|
|
attach_angle = -90;
|
|
if ( iscounter )
|
|
{
|
|
uavrig = level.counteruavrig;
|
|
attach_angle = 90;
|
|
}
|
|
plane = spawn( "script_model", uavrig gettagorigin( "tag_origin" ) );
|
|
if ( iscounter )
|
|
{
|
|
plane setmodel( level.counteruavmodel );
|
|
plane.targetname = "counteruav";
|
|
}
|
|
else
|
|
{
|
|
plane setmodel( level.spyplanemodel );
|
|
plane.targetname = "uav";
|
|
}
|
|
plane setteam( owner.team );
|
|
plane setowner( owner );
|
|
target_set( plane );
|
|
plane thread play_light_fx( iscounter );
|
|
plane.owner = owner;
|
|
plane.team = owner.team;
|
|
plane thread updatevisibility();
|
|
plane thread maps/mp/_heatseekingmissile::missiletarget_proximitydetonateincomingmissile( "crashing" );
|
|
level.plane[ self.team ] = plane;
|
|
plane.health_low = level.u2_maxhealth * 0,4;
|
|
plane.maxhealth = level.u2_maxhealth;
|
|
plane.health = 99999;
|
|
plane.rocketdamageoneshot = level.u2_maxhealth + 1;
|
|
plane.rocketdamagetwoshot = ( level.u2_maxhealth / 2 ) + 1;
|
|
plane setdrawinfrared( 1 );
|
|
zoffset = randomintrange( 4000, 5000 );
|
|
angle = randomint( 360 );
|
|
if ( iscounter )
|
|
{
|
|
radiusoffset = randomint( 1000 ) + 3000;
|
|
}
|
|
else
|
|
{
|
|
radiusoffset = randomint( 1000 ) + 4000;
|
|
}
|
|
xoffset = cos( angle ) * radiusoffset;
|
|
yoffset = sin( angle ) * radiusoffset;
|
|
anglevector = vectornormalize( ( xoffset, yoffset, zoffset ) );
|
|
anglevector *= randomintrange( 4000, 5000 );
|
|
if ( iscounter )
|
|
{
|
|
plane linkto( uavrig, "tag_origin", anglevector, ( 0, angle + attach_angle, -10 ) );
|
|
}
|
|
else
|
|
{
|
|
plane linkto( uavrig, "tag_origin", anglevector, ( 0, angle + attach_angle, 0 ) );
|
|
}
|
|
return plane;
|
|
}
|
|
|
|
play_light_fx( iscounter )
|
|
{
|
|
self endon( "death" );
|
|
wait 0,1;
|
|
if ( iscounter )
|
|
{
|
|
playfxontag( level.counteruavlight, self, "tag_origin" );
|
|
}
|
|
else
|
|
{
|
|
playfxontag( level.uavlight, self, "tag_origin" );
|
|
}
|
|
}
|
|
|
|
updatevisibility()
|
|
{
|
|
self endon( "death" );
|
|
for ( ;; )
|
|
{
|
|
if ( level.teambased )
|
|
{
|
|
self setvisibletoallexceptteam( self.team );
|
|
}
|
|
else
|
|
{
|
|
self setvisibletoall();
|
|
self setinvisibletoplayer( self.owner );
|
|
}
|
|
level waittill( "joined_team" );
|
|
}
|
|
}
|
|
|
|
debugline( frompoint, topoint, color, durationframes )
|
|
{
|
|
/#
|
|
i = 0;
|
|
while ( i < ( durationframes * 20 ) )
|
|
{
|
|
line( frompoint, topoint, color );
|
|
wait 0,05;
|
|
i++;
|
|
#/
|
|
}
|
|
}
|
|
|
|
plane_damage_monitor( isspyplane )
|
|
{
|
|
self endon( "death" );
|
|
self endon( "crashing" );
|
|
self endon( "delete" );
|
|
self setcandamage( 1 );
|
|
self.damagetaken = 0;
|
|
for ( ;; )
|
|
{
|
|
self waittill( "damage", damage, attacker, direction, point, type, tagname, modelname, partname, weapon );
|
|
if ( !isDefined( attacker ) || !isplayer( attacker ) )
|
|
{
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
friendlyfire = maps/mp/gametypes/_weaponobjects::friendlyfirecheck( self.owner, attacker );
|
|
if ( !friendlyfire )
|
|
{
|
|
break;
|
|
}
|
|
else if ( isDefined( self.owner ) && attacker == self.owner )
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
isvalidattacker = 1;
|
|
if ( level.teambased )
|
|
{
|
|
if ( isDefined( attacker.team ) )
|
|
{
|
|
isvalidattacker = attacker.team != self.team;
|
|
}
|
|
}
|
|
if ( !isvalidattacker )
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if ( maps/mp/gametypes/_globallogic_player::dodamagefeedback( weapon, attacker ) )
|
|
{
|
|
attacker thread maps/mp/gametypes/_damagefeedback::updatedamagefeedback( type );
|
|
}
|
|
self.attacker = attacker;
|
|
switch( type )
|
|
{
|
|
case "MOD_PISTOL_BULLET":
|
|
case "MOD_RIFLE_BULLET":
|
|
if ( attacker hasperk( "specialty_armorpiercing" ) )
|
|
{
|
|
self.damagetaken += int( damage * level.cac_armorpiercing_data );
|
|
}
|
|
else
|
|
{
|
|
self.damagetaken += damage;
|
|
}
|
|
break;
|
|
case "MOD_PROJECTILE":
|
|
self.damagetaken += self.rocketdamageoneshot;
|
|
break;
|
|
default:
|
|
self.damagetaken += damage;
|
|
break;
|
|
}
|
|
self.health += damage;
|
|
if ( self.damagetaken > self.maxhealth )
|
|
{
|
|
killstreakreference = "radar_mp";
|
|
if ( !isspyplane )
|
|
{
|
|
killstreakreference = "counteruav_mp";
|
|
}
|
|
attacker notify( "destroyed_spyplane" );
|
|
weaponstatname = "destroyed";
|
|
switch( weapon )
|
|
{
|
|
case "auto_tow_mp":
|
|
case "tow_turret_drop_mp":
|
|
case "tow_turret_mp":
|
|
weaponstatname = "kills";
|
|
break;
|
|
}
|
|
attacker addweaponstat( weapon, weaponstatname, 1 );
|
|
level.globalkillstreaksdestroyed++;
|
|
attacker addweaponstat( killstreakreference, "destroyed", 1 );
|
|
maps/mp/_challenges::destroyedaircraft( attacker, weapon );
|
|
if ( isspyplane )
|
|
{
|
|
level thread maps/mp/_popups::displayteammessagetoall( &"KILLSTREAK_DESTROYED_UAV", attacker );
|
|
if ( isDefined( self.owner ) )
|
|
{
|
|
self.owner maps/mp/gametypes/_globallogic_audio::leaderdialogonplayer( "uav_destroyed", "item_destroyed" );
|
|
}
|
|
if ( !isDefined( self.owner ) || self.owner isenemyplayer( attacker ) )
|
|
{
|
|
thread maps/mp/_scoreevents::processscoreevent( "destroyed_uav", attacker, self.owner, weapon );
|
|
attacker maps/mp/_challenges::addflyswatterstat( weapon, self );
|
|
break;
|
|
}
|
|
spyplane_death();
|
|
}
|
|
else
|
|
{
|
|
level thread maps/mp/_popups::displayteammessagetoall( &"KILLSTREAK_DESTROYED_COUNTERUAV", attacker );
|
|
if ( isDefined( self.owner ) )
|
|
{
|
|
self.owner maps/mp/gametypes/_globallogic_audio::leaderdialogonplayer( "cuav_destroyed", "item_destroyed" );
|
|
}
|
|
if ( !isDefined( self.owner ) || self.owner isenemyplayer( attacker ) )
|
|
{
|
|
thread maps/mp/_scoreevents::processscoreevent( "destroyed_counter_uav", attacker, self.owner, weapon );
|
|
attacker maps/mp/_challenges::addflyswatterstat( weapon, self );
|
|
break;
|
|
}
|
|
counteruavplane_death();
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
plane_health()
|
|
{
|
|
self endon( "death" );
|
|
self endon( "crashing" );
|
|
self.currentstate = "ok";
|
|
self.laststate = "ok";
|
|
while ( self.currentstate != "leaving" )
|
|
{
|
|
if ( self.damagetaken >= self.health_low )
|
|
{
|
|
self.currentstate = "damaged";
|
|
}
|
|
if ( self.currentstate == "damaged" && self.laststate != "damaged" )
|
|
{
|
|
self.laststate = self.currentstate;
|
|
self thread playdamagefx();
|
|
}
|
|
/#
|
|
debug_print3d_simple( "Health: " + ( self.maxhealth - self.damagetaken ), self, vectorScale( ( 0, 0, 1 ), 100 ), 20 );
|
|
#/
|
|
wait 1;
|
|
}
|
|
}
|
|
|
|
playdamagefx()
|
|
{
|
|
self endon( "death" );
|
|
self endon( "crashing" );
|
|
playfxontag( level.fx_u2_damage_trail, self, "tag_body" );
|
|
}
|
|
|
|
u2_crash()
|
|
{
|
|
self notify( "crashing" );
|
|
playfxontag( level.fx_u2_explode, self, "tag_origin" );
|
|
wait 0,1;
|
|
self setmodel( "tag_origin" );
|
|
wait 0,2;
|
|
self notify( "delete" );
|
|
self delete();
|
|
}
|
|
|
|
counteruavplane_death_waiter()
|
|
{
|
|
self endon( "delete" );
|
|
self endon( "leaving" );
|
|
self waittill( "death" );
|
|
counteruavplane_death();
|
|
}
|
|
|
|
spyplane_death_waiter()
|
|
{
|
|
self endon( "delete" );
|
|
self endon( "leaving" );
|
|
self waittill( "death" );
|
|
spyplane_death();
|
|
}
|
|
|
|
counteruavplane_death()
|
|
{
|
|
self clearclientflag( 11 );
|
|
self playsound( "evt_helicopter_midair_exp" );
|
|
self removeactivecounteruav();
|
|
target_remove( self );
|
|
self thread u2_crash();
|
|
}
|
|
|
|
spyplane_death()
|
|
{
|
|
self playsound( "evt_helicopter_midair_exp" );
|
|
if ( !self.leaving )
|
|
{
|
|
self removeactiveuav();
|
|
}
|
|
target_remove( self );
|
|
self thread u2_crash();
|
|
}
|
|
|
|
counteruavplane_timeout( timeinair, owner )
|
|
{
|
|
self endon( "death" );
|
|
self endon( "delete" );
|
|
maps/mp/gametypes/_hostmigration::waittillhostmigrationdone();
|
|
timeremaining = timeinair * 1000;
|
|
self waittilltimeoutmigrationaware( timeremaining, owner );
|
|
self clearclientflag( 11 );
|
|
self plane_leave();
|
|
wait level.counteruavplaneexittime;
|
|
self removeactivecounteruav();
|
|
target_remove( self );
|
|
self delete();
|
|
}
|
|
|
|
satellite_timeout( timeinair, owner )
|
|
{
|
|
self endon( "death" );
|
|
self endon( "delete" );
|
|
maps/mp/gametypes/_hostmigration::waittillhostmigrationdone();
|
|
timeremaining = timeinair * 1000;
|
|
self waittilltimeoutmigrationaware( timeremaining, owner );
|
|
self removeactivesatellite();
|
|
self delete();
|
|
}
|
|
|
|
watchforemp()
|
|
{
|
|
self endon( "death" );
|
|
self endon( "delete" );
|
|
self waittill( "emp_deployed", attacker );
|
|
weapon = "emp_mp";
|
|
maps/mp/_challenges::destroyedaircraft( attacker, weapon );
|
|
thread maps/mp/_scoreevents::processscoreevent( "destroyed_satellite", attacker, self.owner, weapon );
|
|
attacker maps/mp/_challenges::addflyswatterstat( weapon, self );
|
|
self removeactivesatellite();
|
|
self delete();
|
|
}
|
|
|
|
spyplane_timeout( timeinair, owner )
|
|
{
|
|
self endon( "death" );
|
|
self endon( "delete" );
|
|
self endon( "crashing" );
|
|
maps/mp/gametypes/_hostmigration::waittillhostmigrationdone();
|
|
timeremaining = timeinair * 1000;
|
|
self waittilltimeoutmigrationaware( timeremaining, owner );
|
|
self plane_leave();
|
|
self.leaving = 1;
|
|
self removeactiveuav();
|
|
wait level.spyplaneexittime;
|
|
target_remove( self );
|
|
self delete();
|
|
}
|
|
|
|
waittilltimeoutmigrationaware( timeremaining, owner )
|
|
{
|
|
owner endon( "disconnect" );
|
|
for ( ;; )
|
|
{
|
|
self.endtime = getTime() + timeremaining;
|
|
event = level waittill_any_timeout( timeremaining / 1000, "game_ended", "host_migration_begin" );
|
|
if ( event != "host_migration_begin" )
|
|
{
|
|
return;
|
|
}
|
|
else timeremaining = self.endtime - getTime();
|
|
if ( timeremaining <= 0 )
|
|
{
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
maps/mp/gametypes/_hostmigration::waittillhostmigrationdone();
|
|
}
|
|
}
|
|
}
|
|
|
|
planestoploop( time )
|
|
{
|
|
self endon( "death" );
|
|
wait time;
|
|
self stoploopsound();
|
|
}
|
|
|
|
plane_leave()
|
|
{
|
|
self unlink();
|
|
if ( isDefined( self.iscounter ) && self.iscounter )
|
|
{
|
|
self thread playcounterspyplaneafterburnerfx();
|
|
self playsound( "veh_kls_uav_afterburner" );
|
|
self thread play_light_fx( 1 );
|
|
self thread planestoploop( 1 );
|
|
}
|
|
else
|
|
{
|
|
self thread playspyplaneafterburnerfx();
|
|
self playsound( "veh_kls_spy_afterburner" );
|
|
self thread play_light_fx( 0 );
|
|
self thread planestoploop( 1 );
|
|
}
|
|
self.currentstate = "leaving";
|
|
if ( self.laststate == "damaged" )
|
|
{
|
|
playfxontag( level.fx_u2_damage_trail, self, "tag_body" );
|
|
}
|
|
mult = getdvarintdefault( "scr_spymult", 20000 );
|
|
tries = 10;
|
|
yaw = 0;
|
|
while ( tries > 0 )
|
|
{
|
|
exitvector = anglesToForward( self.angles + ( 0, yaw, 0 ) ) * 20000;
|
|
if ( isDefined( self.iscounter ) && self.iscounter )
|
|
{
|
|
self thread playcounterspyplanefx();
|
|
exitvector *= 1;
|
|
}
|
|
exitpoint = ( self.origin[ 0 ] + exitvector[ 0 ], self.origin[ 1 ] + exitvector[ 1 ], self.origin[ 2 ] - 2500 );
|
|
exitpoint = self.origin + exitvector;
|
|
nfz = crossesnoflyzone( self.origin, exitpoint );
|
|
if ( isDefined( nfz ) )
|
|
{
|
|
if ( tries != 1 )
|
|
{
|
|
if ( ( tries % 2 ) == 1 )
|
|
{
|
|
yaw *= -1;
|
|
tries--;
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
yaw += 10;
|
|
yaw *= -1;
|
|
}
|
|
}
|
|
tries--;
|
|
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
tries = 0;
|
|
}
|
|
}
|
|
self thread flattenyaw( self.angles[ 1 ] + yaw );
|
|
if ( self.angles[ 2 ] != 0 )
|
|
{
|
|
self thread flattenroll();
|
|
}
|
|
self moveto( exitpoint, level.spyplaneexittime, 0, 0 );
|
|
self notify( "leaving" );
|
|
}
|
|
|
|
flattenroll()
|
|
{
|
|
self endon( "death" );
|
|
while ( self.angles[ 2 ] < 0 )
|
|
{
|
|
self.angles = ( self.angles[ 0 ], self.angles[ 1 ], self.angles[ 2 ] + 2,5 );
|
|
wait 0,05;
|
|
}
|
|
}
|
|
|
|
flattenyaw( goal )
|
|
{
|
|
self endon( "death" );
|
|
increment = 3;
|
|
if ( self.angles[ 1 ] > goal )
|
|
{
|
|
increment *= -1;
|
|
}
|
|
while ( abs( self.angles[ 1 ] - goal ) > 3 )
|
|
{
|
|
self.angles = ( self.angles[ 0 ], self.angles[ 1 ] + increment, self.angles[ 2 ] );
|
|
wait 0,05;
|
|
}
|
|
}
|
|
|
|
uavtracker()
|
|
{
|
|
level endon( "game_ended" );
|
|
for ( ;; )
|
|
{
|
|
level waittill( "uav_update" );
|
|
if ( level.teambased )
|
|
{
|
|
_a1102 = level.teams;
|
|
_k1102 = getFirstArrayKey( _a1102 );
|
|
while ( isDefined( _k1102 ) )
|
|
{
|
|
team = _a1102[ _k1102 ];
|
|
updateteamuavstatus( team );
|
|
_k1102 = getNextArrayKey( _a1102, _k1102 );
|
|
}
|
|
}
|
|
else updateplayersuavstatus();
|
|
}
|
|
}
|
|
|
|
updateteamuavstatus( team )
|
|
{
|
|
activeuavs = level.activeuavs[ team ];
|
|
activesatellites = level.activesatellites[ team ];
|
|
radarmode = 1;
|
|
if ( activesatellites > 0 )
|
|
{
|
|
maps/mp/killstreaks/_radar::setteamspyplanewrapper( team, 0 );
|
|
maps/mp/killstreaks/_radar::setteamsatellitewrapper( team, 1 );
|
|
return;
|
|
}
|
|
maps/mp/killstreaks/_radar::setteamsatellitewrapper( team, 0 );
|
|
if ( !activeuavs )
|
|
{
|
|
maps/mp/killstreaks/_radar::setteamspyplanewrapper( team, 0 );
|
|
return;
|
|
}
|
|
if ( activeuavs > 1 )
|
|
{
|
|
radarmode = 2;
|
|
}
|
|
maps/mp/killstreaks/_radar::setteamspyplanewrapper( team, radarmode );
|
|
}
|
|
|
|
updateplayersuavstatus()
|
|
{
|
|
i = 0;
|
|
while ( i < level.players.size )
|
|
{
|
|
player = level.players[ i ];
|
|
/#
|
|
assert( isDefined( player.entnum ) );
|
|
#/
|
|
if ( !isDefined( player.entnum ) )
|
|
{
|
|
player.entnum = player getentitynumber();
|
|
}
|
|
activeuavs = level.activeuavs[ player.entnum ];
|
|
activesatellites = level.activesatellites[ player.entnum ];
|
|
if ( activesatellites > 0 )
|
|
{
|
|
player.hassatellite = 1;
|
|
player.hasspyplane = 0;
|
|
player setclientuivisibilityflag( "radar_client", 1 );
|
|
i++;
|
|
continue;
|
|
}
|
|
else player.hassatellite = 0;
|
|
if ( activeuavs == 0 && isDefined( player.pers[ "hasRadar" ] ) && !player.pers[ "hasRadar" ] )
|
|
{
|
|
player.hasspyplane = 0;
|
|
player setclientuivisibilityflag( "radar_client", 0 );
|
|
i++;
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
if ( activeuavs > 1 )
|
|
{
|
|
spyplaneupdatespeed = 2;
|
|
}
|
|
else
|
|
{
|
|
spyplaneupdatespeed = 1;
|
|
}
|
|
player setclientuivisibilityflag( "radar_client", 1 );
|
|
player.hasspyplane = spyplaneupdatespeed;
|
|
}
|
|
i++;
|
|
}
|
|
}
|