747 lines
18 KiB
Plaintext

#include maps/mp/gametypes/_weaponobjects;
#include maps/mp/killstreaks/_supplydrop;
#include maps/mp/_heatseekingmissile;
#include maps/mp/gametypes/_hud_util;
#include common_scripts/utility;
#include maps/mp/_utility;
init()
{
level.hackertoolmaxequipmentdistance = 2000;
level.hackertoolmaxequipmentdistancesq = level.hackertoolmaxequipmentdistance * level.hackertoolmaxequipmentdistance;
level.hackertoolnosighthackdistance = 750;
level.hackertoollostsightlimitms = 450;
level.hackertoollockonradius = 20;
level.hackertoollockonfov = 65;
level.hackertoolhacktimems = 0,5;
level.equipmenthackertoolradius = 60;
level.equipmenthackertooltimems = 50;
level.carepackagehackertoolradius = 60;
level.carepackagehackertooltimems = getgametypesetting( "crateCaptureTime" ) * 500;
level.carepackagefriendlyhackertooltimems = getgametypesetting( "crateCaptureTime" ) * 2000;
level.carepackageownerhackertooltimems = 250;
level.sentryhackertoolradius = 80;
level.sentryhackertooltimems = 4000;
level.microwavehackertoolradius = 80;
level.microwavehackertooltimems = 4000;
level.vehiclehackertoolradius = 80;
level.vehiclehackertooltimems = 4000;
level.rcxdhackertooltimems = 1500;
level.rcxdhackertoolradius = 20;
level.uavhackertooltimems = 4000;
level.uavhackertoolradius = 40;
level.cuavhackertooltimems = 4000;
level.cuavhackertoolradius = 40;
level.carepackagechopperhackertooltimems = 3000;
level.carepackagechopperhackertoolradius = 60;
level.littlebirdhackertooltimems = 4000;
level.littlebirdhackertoolradius = 80;
level.qrdronehackertooltimems = 3000;
level.qrdronehackertoolradius = 60;
level.aitankhackertooltimems = 4000;
level.aitankhackertoolradius = 60;
level.stealthchopperhackertooltimems = 4000;
level.stealthchopperhackertoolradius = 80;
level.warthoghackertooltimems = 4000;
level.warthoghackertoolradius = 80;
level.lodestarhackertooltimems = 4000;
level.lodestarhackertoolradius = 60;
level.choppergunnerhackertooltimems = 4000;
level.choppergunnerhackertoolradius = 260;
thread onplayerconnect();
}
onplayerconnect()
{
for ( ;; )
{
level waittill( "connecting", player );
player thread onplayerspawned();
}
}
onplayerspawned()
{
self endon( "disconnect" );
for ( ;; )
{
self waittill( "spawned_player" );
self clearhackertarget();
self thread watchhackertooluse();
self thread watchhackertoolfired();
}
}
clearhackertarget()
{
self notify( "stop_lockon_sound" );
self notify( "stop_locked_sound" );
self.stingerlocksound = undefined;
self stoprumble( "stinger_lock_rumble" );
self.hackertoollockstarttime = 0;
self.hackertoollockstarted = 0;
self.hackertoollockfinalized = 0;
self.hackertoollocktimeelapsed = 0;
self setweaponheatpercent( "pda_hack_mp", 0 );
if ( isDefined( self.hackertooltarget ) )
{
lockingon( self.hackertooltarget, 0 );
lockedon( self.hackertooltarget, 0 );
}
self.hackertooltarget = undefined;
self weaponlockfree();
self weaponlocktargettooclose( 0 );
self weaponlocknoclearance( 0 );
self stoplocalsound( game[ "locking_on_sound" ] );
self stoplocalsound( game[ "locked_on_sound" ] );
self destroylockoncanceledmessage();
}
watchhackertoolfired()
{
self endon( "disconnect" );
self endon( "death" );
while ( 1 )
{
self waittill( "hacker_tool_fired", hackertooltarget );
if ( isDefined( hackertooltarget ) )
{
if ( isentityhackablecarepackage( hackertooltarget ) )
{
maps/mp/killstreaks/_supplydrop::givecratecapturemedal( hackertooltarget, self );
hackertooltarget notify( "captured" );
}
if ( isentityhackableweaponobject( hackertooltarget ) || isDefined( hackertooltarget.hackertrigger ) )
{
hackertooltarget.hackertrigger notify( "trigger" );
}
else
{
if ( isDefined( hackertooltarget.classname ) && hackertooltarget.classname == "grenade" )
{
damage = 1;
}
else
{
if ( isDefined( hackertooltarget.maxhealth ) )
{
damage = hackertooltarget.maxhealth + 1;
break;
}
else
{
damage = 999999;
}
}
if ( isDefined( hackertooltarget.numflares ) && hackertooltarget.numflares > 0 )
{
damage = 1;
hackertooltarget.numflares--;
hackertooltarget maps/mp/_heatseekingmissile::missiletarget_playflarefx();
}
hackertooltarget dodamage( damage, self.origin, self, self, 0, "MOD_UNKNOWN", 0, "pda_hack_mp" );
}
self addplayerstat( "hack_enemy_target", 1 );
self addweaponstat( "pda_hack_mp", "used", 1 );
}
clearhackertarget();
self forceoffhandend();
clip_ammo = self getweaponammoclip( "pda_hack_mp" );
clip_ammo--;
/#
assert( clip_ammo >= 0 );
#/
self setweaponammoclip( "pda_hack_mp", clip_ammo );
self switchtoweapon( self getlastweapon() );
}
}
watchhackertooluse()
{
self endon( "disconnect" );
self endon( "death" );
for ( ;; )
{
self waittill( "grenade_pullback", weapon );
if ( weapon == "pda_hack_mp" )
{
wait 0,05;
if ( self isusingoffhand() && self getcurrentoffhand() == "pda_hack_mp" )
{
self thread hackertooltargetloop();
self thread watchhackertoolend();
self thread watchforgrenadefire();
self thread watchhackertoolinterrupt();
}
}
}
}
watchhackertoolinterrupt()
{
self endon( "disconnect" );
self endon( "hacker_tool_fired" );
self endon( "death" );
self endon( "weapon_change" );
self endon( "grenade_fire" );
while ( 1 )
{
level waittill( "use_interrupt", interrupttarget );
if ( self.hackertooltarget == interrupttarget )
{
clearhackertarget();
}
wait 0,05;
}
}
watchhackertoolend()
{
self endon( "disconnect" );
self endon( "hacker_tool_fired" );
msg = self waittill_any_return( "weapon_change", "death" );
clearhackertarget();
}
watchforgrenadefire()
{
self endon( "disconnect" );
self endon( "hacker_tool_fired" );
self endon( "weapon_change" );
self endon( "death" );
while ( 1 )
{
self waittill( "grenade_fire", grenade, grenadename, respawnfromhack );
if ( isDefined( respawnfromhack ) && respawnfromhack )
{
continue;
}
clearhackertarget();
clip_ammo = self getweaponammoclip( "pda_hack_mp" );
clip_max_ammo = weaponclipsize( "pda_hack_mp" );
if ( clip_ammo < clip_max_ammo )
{
clip_ammo++;
}
self setweaponammoclip( "pda_hack_mp", clip_ammo );
return;
}
}
hackertooltargetloop()
{
self endon( "disconnect" );
self endon( "death" );
self endon( "weapon_change" );
self endon( "grenade_fire" );
while ( 1 )
{
wait 0,05;
if ( self.hackertoollockfinalized )
{
while ( !self isvalidhackertooltarget( self.hackertooltarget ) )
{
self clearhackertarget();
}
passed = self hackersoftsighttest();
while ( !passed )
{
continue;
}
lockingon( self.hackertooltarget, 0 );
lockedon( self.hackertooltarget, 1 );
thread looplocallocksound( game[ "locked_on_sound" ], 0,75 );
self notify( "hacker_tool_fired" );
return;
}
while ( self.hackertoollockstarted )
{
while ( !self isvalidhackertooltarget( self.hackertooltarget ) )
{
self clearhackertarget();
}
locklengthms = self gethacktime( self.hackertooltarget );
while ( locklengthms == 0 )
{
self clearhackertarget();
}
if ( self.hackertoollocktimeelapsed == 0 )
{
self playlocalsound( "evt_hacker_hacking" );
}
lockingon( self.hackertooltarget, 1 );
lockedon( self.hackertooltarget, 0 );
passed = self hackersoftsighttest();
while ( !passed )
{
continue;
}
if ( self.hackertoollostsightlinetime == 0 )
{
self.hackertoollocktimeelapsed += 0,05;
hackpercentage = self.hackertoollocktimeelapsed / ( locklengthms / 1000 );
self setweaponheatpercent( "pda_hack_mp", hackpercentage );
}
while ( self.hackertoollocktimeelapsed < ( locklengthms / 1000 ) )
{
continue;
}
/#
assert( isDefined( self.hackertooltarget ) );
#/
self notify( "stop_lockon_sound" );
self.hackertoollockfinalized = 1;
self weaponlockfinalize( self.hackertooltarget );
}
besttarget = self getbesthackertooltarget();
while ( !isDefined( besttarget ) )
{
self destroylockoncanceledmessage();
}
while ( !self locksighttest( besttarget ) && distance2d( self.origin, besttarget.origin ) > level.hackertoolnosighthackdistance )
{
self destroylockoncanceledmessage();
}
while ( self locksighttest( besttarget ) && isDefined( besttarget.lockondelay ) && besttarget.lockondelay )
{
self displaylockoncanceledmessage();
}
self destroylockoncanceledmessage();
initlockfield( besttarget );
self.hackertooltarget = besttarget;
self.hackertoollockstarttime = getTime();
self.hackertoollockstarted = 1;
self.hackertoollostsightlinetime = 0;
self.hackertoollocktimeelapsed = 0;
self setweaponheatpercent( "pda_hack_mp", 0 );
self thread looplocalseeksound( game[ "locking_on_sound" ], 0,6 );
}
}
getbesthackertooltarget()
{
targetsvalid = [];
targetsall = arraycombine( target_getarray(), level.missileentities, 0, 0 );
targetsall = arraycombine( targetsall, level.hackertooltargets, 0, 0 );
idx = 0;
while ( idx < targetsall.size )
{
target_ent = targetsall[ idx ];
if ( !isDefined( target_ent ) || !isDefined( target_ent.owner ) )
{
idx++;
continue;
}
else
{
/#
if ( getDvar( "scr_freelock" ) == "1" )
{
if ( self iswithinhackertoolreticle( targetsall[ idx ] ) )
{
targetsvalid[ targetsvalid.size ] = targetsall[ idx ];
}
idx++;
continue;
#/
}
else if ( level.teambased )
{
if ( isentityhackablecarepackage( target_ent ) )
{
if ( self iswithinhackertoolreticle( target_ent ) )
{
targetsvalid[ targetsvalid.size ] = target_ent;
}
}
else if ( isDefined( target_ent.team ) )
{
if ( target_ent.team != self.team )
{
if ( self iswithinhackertoolreticle( target_ent ) )
{
targetsvalid[ targetsvalid.size ] = target_ent;
}
}
}
else
{
if ( isDefined( target_ent.owner.team ) )
{
if ( target_ent.owner.team != self.team )
{
if ( self iswithinhackertoolreticle( target_ent ) )
{
targetsvalid[ targetsvalid.size ] = target_ent;
}
}
}
}
idx++;
continue;
}
else if ( self iswithinhackertoolreticle( target_ent ) )
{
if ( isentityhackablecarepackage( target_ent ) )
{
targetsvalid[ targetsvalid.size ] = target_ent;
idx++;
continue;
}
else
{
if ( isDefined( target_ent.owner ) && self != target_ent.owner )
{
targetsvalid[ targetsvalid.size ] = target_ent;
}
}
}
}
idx++;
}
chosenent = undefined;
if ( targetsvalid.size != 0 )
{
chosenent = targetsvalid[ 0 ];
}
return chosenent;
}
iswithinhackertoolreticle( target )
{
radius = gethackertoolradius( target );
return target_isincircle( target, self, level.hackertoollockonfov, radius, 0 );
}
isentityhackableweaponobject( entity )
{
if ( isDefined( entity.classname ) && entity.classname == "grenade" )
{
if ( isDefined( entity.name ) )
{
watcher = maps/mp/gametypes/_weaponobjects::getweaponobjectwatcherbyweapon( entity.name );
if ( isDefined( watcher ) )
{
if ( watcher.hackable )
{
/#
assert( isDefined( watcher.hackertoolradius ) );
assert( isDefined( watcher.hackertooltimems ) );
#/
return 1;
}
}
}
}
return 0;
}
getweaponobjecthackerradius( entity )
{
/#
assert( isDefined( entity.classname ) );
assert( isDefined( entity.name ) );
#/
watcher = maps/mp/gametypes/_weaponobjects::getweaponobjectwatcherbyweapon( entity.name );
/#
assert( watcher.hackable );
assert( isDefined( watcher.hackertoolradius ) );
#/
return watcher.hackertoolradius;
}
getweaponobjecthacktimems( entity )
{
/#
assert( isDefined( entity.classname ) );
assert( isDefined( entity.name ) );
#/
watcher = maps/mp/gametypes/_weaponobjects::getweaponobjectwatcherbyweapon( entity.name );
/#
assert( watcher.hackable );
assert( isDefined( watcher.hackertooltimems ) );
#/
return watcher.hackertooltimems;
}
isentityhackablecarepackage( entity )
{
if ( isDefined( entity.model ) )
{
return entity.model == "t6_wpn_supply_drop_ally";
}
else
{
return 0;
}
}
isvalidhackertooltarget( ent )
{
if ( !isDefined( ent ) )
{
return 0;
}
if ( self isusingremote() )
{
return 0;
}
if ( self isempjammed() )
{
return 0;
}
if ( !target_istarget( ent ) && !isentityhackableweaponobject( ent ) && !isinarray( level.hackertooltargets, ent ) )
{
return 0;
}
if ( isentityhackableweaponobject( ent ) )
{
if ( distancesquared( self.origin, ent.origin ) > level.hackertoolmaxequipmentdistancesq )
{
return 0;
}
}
return 1;
}
hackersoftsighttest()
{
passed = 1;
locklengthms = 0;
if ( isDefined( self.hackertooltarget ) )
{
locklengthms = self gethacktime( self.hackertooltarget );
}
if ( self isempjammed() || locklengthms == 0 )
{
self clearhackertarget();
passed = 0;
}
else
{
if ( iswithinhackertoolreticle( self.hackertooltarget ) )
{
self.hackertoollostsightlinetime = 0;
}
else
{
if ( self.hackertoollostsightlinetime == 0 )
{
self.hackertoollostsightlinetime = getTime();
}
timepassed = getTime() - self.hackertoollostsightlinetime;
if ( timepassed >= level.hackertoollostsightlimitms )
{
self clearhackertarget();
passed = 0;
}
}
}
return passed;
}
registerwithhackertool( radius, hacktimems )
{
self endon( "death" );
if ( isDefined( radius ) )
{
self.hackertoolradius = radius;
}
else
{
self.hackertoolradius = level.hackertoollockonradius;
}
if ( isDefined( hacktimems ) )
{
self.hackertooltimems = hacktimems;
}
else
{
self.hackertooltimems = level.hackertoolhacktimems;
}
self thread watchhackableentitydeath();
level.hackertooltargets[ level.hackertooltargets.size ] = self;
}
watchhackableentitydeath()
{
self waittill( "death" );
arrayremovevalue( level.hackertooltargets, self );
}
gethackertoolradius( target )
{
radius = 20;
if ( isentityhackablecarepackage( target ) )
{
/#
assert( isDefined( target.hackertoolradius ) );
#/
radius = target.hackertoolradius;
break;
}
else if ( isentityhackableweaponobject( target ) )
{
radius = getweaponobjecthackerradius( target );
break;
}
else if ( isDefined( target.hackertoolradius ) )
{
radius = target.hackertoolradius;
break;
}
else radius = level.vehiclehackertoolradius;
switch( target.model )
{
case "veh_t6_drone_uav":
radius = level.uavhackertoolradius;
break;
case "veh_t6_drone_cuav":
radius = level.cuavhackertoolradius;
break;
case "t5_veh_rcbomb_axis":
radius = level.rcxdhackertoolradius;
break;
case "veh_iw_mh6_littlebird_mp":
radius = level.carepackagechopperhackertoolradius;
break;
case "veh_t6_drone_quad_rotor_mp":
case "veh_t6_drone_quad_rotor_mp_alt":
radius = level.qrdronehackertoolradius;
break;
case "veh_t6_drone_tank":
case "veh_t6_drone_tank_alt":
radius = level.aitankhackertoolradius;
break;
case "veh_t6_air_attack_heli_mp_dark":
case "veh_t6_air_attack_heli_mp_light":
radius = level.stealthchopperhackertoolradius;
break;
case "veh_t6_drone_overwatch_dark":
case "veh_t6_drone_overwatch_light":
radius = level.littlebirdhackertoolradius;
break;
case "veh_t6_drone_pegasus":
radius = level.lodestarhackertoolradius;
break;
case "veh_iw_air_apache_killstreak":
radius = level.choppergunnerhackertoolradius;
break;
case "veh_t6_air_a10f":
case "veh_t6_air_a10f_alt":
radius = level.warthoghackertoolradius;
break;
}
return radius;
}
gethacktime( target )
{
time = 500;
if ( isentityhackablecarepackage( target ) )
{
/#
assert( isDefined( target.hackertooltimems ) );
#/
if ( isDefined( target.owner ) && target.owner == self )
{
time = level.carepackageownerhackertooltimems;
}
else
{
if ( isDefined( target.owner ) && target.owner.team == self.team )
{
time = level.carepackagefriendlyhackertooltimems;
}
else
{
time = level.carepackagehackertooltimems;
}
}
break;
}
else if ( isentityhackableweaponobject( target ) )
{
time = getweaponobjecthacktimems( target );
break;
}
else if ( isDefined( target.hackertooltimems ) )
{
time = target.hackertooltimems;
break;
}
else time = level.vehiclehackertooltimems;
switch( target.model )
{
case "veh_t6_drone_uav":
time = level.uavhackertooltimems;
break;
case "veh_t6_drone_cuav":
time = level.cuavhackertooltimems;
break;
case "t5_veh_rcbomb_axis":
time = level.rcxdhackertooltimems;
break;
case "veh_t6_drone_supply_alt":
case "veh_t6_drone_supply_alt":
time = level.carepackagechopperhackertooltimems;
break;
case "veh_t6_drone_quad_rotor_mp":
case "veh_t6_drone_quad_rotor_mp_alt":
time = level.qrdronehackertooltimems;
break;
case "veh_t6_drone_tank":
case "veh_t6_drone_tank_alt":
time = level.aitankhackertooltimems;
break;
case "veh_t6_air_attack_heli_mp_dark":
case "veh_t6_air_attack_heli_mp_light":
time = level.stealthchopperhackertooltimems;
break;
case "veh_t6_drone_overwatch_dark":
case "veh_t6_drone_overwatch_light":
time = level.littlebirdhackertooltimems;
break;
case "veh_t6_drone_pegasus":
time = level.lodestarhackertooltimems;
break;
case "veh_t6_air_v78_vtol_killstreak":
case "veh_t6_air_v78_vtol_killstreak_alt":
time = level.choppergunnerhackertooltimems;
break;
case "veh_t6_air_a10f":
case "veh_t6_air_a10f_alt":
time = level.warthoghackertooltimems;
break;
}
return time;
}
tunables()
{
/#
while ( 1 )
{
level.hackertoollostsightlimitms = weapons_get_dvar_int( "scr_hackerToolLostSightLimitMs", 1000 );
level.hackertoollockonradius = weapons_get_dvar( "scr_hackerToolLockOnRadius", 20 );
level.hackertoollockonfov = weapons_get_dvar_int( "scr_hackerToolLockOnFOV", 65 );
level.rcxd_time = weapons_get_dvar( "scr_rcxd_time", 1,5 );
level.uav_time = weapons_get_dvar_int( "scr_uav_time", 4 );
level.cuav_time = weapons_get_dvar_int( "scr_cuav_time", 4 );
level.care_package_chopper_time = weapons_get_dvar_int( "scr_care_package_chopper_time", 3 );
level.guardian_time = weapons_get_dvar_int( "scr_guardian_time", 5 );
level.sentry_time = weapons_get_dvar_int( "scr_sentry_time", 5 );
level.wasp_time = weapons_get_dvar_int( "scr_wasp_time", 5 );
level.agr_time = weapons_get_dvar_int( "scr_agr_time", 5 );
level.stealth_helicopter_time = weapons_get_dvar_int( "scr_stealth_helicopter_time", 7 );
level.escort_drone_time = weapons_get_dvar_int( "scr_escort_drone_time", 7 );
level.warthog_time = weapons_get_dvar_int( "scr_warthog_time", 7 );
level.lodestar_time = weapons_get_dvar_int( "scr_lodestar_time", 7 );
level.chopper_gunner_time = weapons_get_dvar_int( "scr_chopper_gunner_time", 7 );
wait 1;
#/
}
}