1 #using scripts\codescripts\struct;
3 #using scripts\shared\callbacks_shared;
4 #using scripts\shared\clientfield_shared;
5 #using scripts\shared\killstreaks_shared;
6 #using scripts\shared\scoreevents_shared;
7 #using scripts\shared\system_shared;
8 #using scripts\shared\util_shared;
9 #using scripts\shared\weapons\_heatseekingmissile;
10 #using scripts\shared\weapons\_weaponobjects;
12 #insert scripts\shared\shared.gsh;
13 #insert scripts\shared\version.gsh;
15 #precache( "triggerstring", "MP_GENERIC_HACKING" );
17 #namespace hacker_tool;
21 level.weaponHackerTool = GetWeapon(
"pda_hack" );
23 level.hackerToolLostSightLimitMs = 1000;
24 level.hackerToolLockOnRadius = 25;
25 level.hackerToolLockOnFOV = 65;
26 level.hackerToolHackTimeMs = 0.4;
29 level.equipmentHackerToolRadius = 20;
30 level.equipmentHackerToolTimeMs = 100;
33 level.carePackageHackerToolRadius = 60;
34 level.carePackageHackerToolTimeMs = GetGametypeSetting(
"crateCaptureTime") * 500;
35 level.carePackageFriendlyHackerToolTimeMs = GetGametypeSetting(
"crateCaptureTime") * 2000 ;
36 level.carePackageOwnerHackerToolTimeMs = 250;
39 level.vehicleHackerToolRadius = 80;
40 level.vehicleHackerToolTimeMs = 5000;
53 self endon(
"disconnect" );
67 self notify(
"stop_lockon_sound" );
68 self notify(
"stop_locked_sound" );
69 self notify(
"clearHackerTarget" );
71 self.stingerlocksound = undefined;
72 self StopRumble(
"stinger_lock_rumble" );
74 self.hackerToolLockStartTime = 0;
75 self.hackerToolLockStarted =
false;
76 self.hackerToolLockFinalized =
false;
77 self.hackerToolLockTimeElapsed = 0.0;
79 if ( isdefined( weapon ) )
81 if ( weapon.isHackToolWeapon )
83 self SetWeaponHackPercent( weapon, 0.0 );
86 if( isdefined(
self.hackerToolTarget ))
92 if ( successfulHack ==
false )
96 if( isdefined(
self.hackerToolTarget ) )
97 self playsoundtoplayer(
"evt_hacker_hack_lost",
self );
103 if( isdefined(
self.hackerToolTarget ))
107 self.hackerToolTarget = undefined;
109 self WeaponLockFree();
110 self WeaponLockTargetTooClose(
false );
111 self WeaponLockNoClearance(
false );
113 self StopLocalSound( game[
"locking_on_sound"] );
114 self StopLocalSound( game[
"locked_on_sound"] );
125 self endon(
"disconnect" );
126 self endon (
"death" );
127 self endon (
"killHackerMonitor");
131 self waittill(
"hacker_tool_fired", hackerToolTarget, weapon );
133 if( isdefined( hackerToolTarget ))
138 hackerToolTarget notify(
"captured",
self,
true );
140 if ( isdefined( hackerToolTarget.owner ) && isplayer( hackerToolTarget.owner ) && hackerToolTarget.owner.team !=
self.team && isdefined( level.play_killstreak_hacked_dialog ) )
142 hackerToolTarget.owner [[level.play_killstreak_hacked_dialog]]( hackerToolTarget.killstreakType,hackerToolTarget.killstreakId, self );
148 hackerToolTarget.hackerTrigger notify(
"trigger",
self,
true );
149 hackerToolTarget.previouslyHacked =
true;
150 self.throwinggrenade =
false;
152 else if ( isdefined( hackerToolTarget.killstreak_hackedCallback ) && ( !isdefined( hackerToolTarget.killstreakTimedOut ) || hackerToolTarget.killstreakTimedOut ==
false ) )
154 if ( hackerToolTarget.killstreak_hackedProtection ==
false )
156 if ( isdefined( hackerToolTarget.owner ) && isplayer( hackerToolTarget.owner ) )
159 if ( isdefined( level.play_killstreak_hacked_dialog ) )
161 hackerToolTarget.owner [[level.play_killstreak_hacked_dialog]]( hackerToolTarget.killstreakType,hackerToolTarget.killstreakId, self );
164 self playsoundtoplayer(
"evt_hacker_fw_success",
self );
165 hackerToolTarget notify(
"killstreak_hacked",
self );
166 hackerToolTarget.previouslyHacked =
true;
167 hackerToolTarget [[ hackerToolTarget.killstreak_hackedCallback ]]( self );
171 self AddPlayerStat(
"hack_streak_with_blindeye_or_engineer", 1 );
176 if ( isdefined( hackerToolTarget.owner ) && isplayer( hackerToolTarget.owner ) )
179 if ( isdefined( level.play_killstreak_firewall_hacked_dialog ) )
181 self.hackerToolTarget.owner [[level.play_killstreak_firewall_hacked_dialog]](
self.hackerToolTarget.killstreakType,
self.hackerToolTarget.killstreakId );
184 self playsoundtoplayer(
"evt_hacker_ks_success",
self );
185 scoreevents::processscoreevent(
"hacked_killstreak_protection",
self, hackerToolTarget, level.weaponHackerTool );
187 hackerToolTarget.killstreak_hackedProtection =
false;
191 if ( isdefined( hackerToolTarget.classname ) && hackerToolTarget.classname ==
"grenade" )
195 else if ( isdefined( hackerToolTarget.hackerToolDamage ))
197 damage = hackerToolTarget.hackerToolDamage;
199 else if ( isdefined( hackerToolTarget.maxhealth ))
201 damage = hackerToolTarget.maxhealth + 1;
208 if ( isdefined( hackerToolTarget.numFlares ) && hackerToolTarget.numFlares > 0 )
211 hackerToolTarget.numFlares--;
215 hackerToolTarget DoDamage(
damage,
self.origin,
self,
self, 0,
"MOD_UNKNOWN", 0, weapon );
219 self AddPlayerStat(
"hack_enemy_target", 1 );
221 self AddWeaponStat( weapon,
"used", 1 );
225 self forceoffhandend();
227 if ( GetDvarint(
"player_sustainAmmo" ) == 0 )
229 clip_ammo =
self GetWeaponAmmoClip( weapon );
231 /#assert( clip_ammo >= 0);#/
233 self setWeaponAmmoClip( weapon, clip_ammo );
247 self endon(
"disconnect" );
248 self endon (
"death" );
252 self waittill (
"grenade_pullback", weapon );
254 if ( weapon.rootWeapon == level.weaponHackerTool )
257 currentOffhand =
self getCurrentOffhand();
258 if (
self isUsingOffhand() && ( currentOffhand.rootWeapon == level.weaponHackerTool ) )
275 self endon(
"disconnect" );
276 self endon(
"hacker_tool_fired" );
277 self endon(
"death" );
278 self endon(
"weapon_change" );
279 self endon(
"grenade_fire" );
283 level waittill(
"use_interrupt", interruptTarget );
285 if(
self.hackerToolTarget == interruptTarget )
296 self endon(
"disconnect" );
297 self endon(
"hacker_tool_fired" );
308 self endon(
"disconnect" );
309 self endon(
"hacker_tool_fired" );
310 self endon(
"weapon_change" );
311 self endon(
"death" );
316 self waittill(
"grenade_fire", grenade_instance, grenade_weapon, respawnFromHack );
318 if( isDefined( respawnFromHack ) && respawnFromHack )
323 clip_ammo =
self GetWeaponAmmoClip( grenade_weapon );
324 clip_max_ammo = grenade_weapon.clipSize;
326 if( clip_ammo < clip_max_ammo )
330 self setWeaponAmmoClip( grenade_weapon, clip_ammo );
338 if ( !isdefined(
self.hacker_sound_ent ) || ( isdefined(
self.hacker_alreadyhacked ) &&
self.hacker_alreadyhacked ==
true ) )
340 self playloopsound (
"evt_hacker_device_loop");
341 self.hacker_sound_ent =
true;
342 self.hacker_alreadyhacked =
false;
348 self StopLoopSound( 0.5 );
349 self.hacker_sound_ent = undefined;
350 self.hacker_alreadyhacked = undefined;
356 self endon(
"disconnect" );
357 self endon(
"death" );
358 self endon(
"weapon_change" );
359 self endon(
"grenade_fire" );
370 if (
self.hackerToolLockFinalized )
391 self notify(
"hacker_tool_fired",
self.hackerToolTarget, weapon );
395 if (
self.hackerToolLockStarted )
403 lockOnTime =
self getLockOnTime(
self.hackerToolTarget, weapon );
405 if ( lockOnTime == 0 )
411 if (
self.hackerToolLockTimeElapsed == 0.0 )
413 self PlayLocalSound (
"evt_hacker_hacking" );
415 if ( isdefined(
self.hackerToolTarget.owner ) && isplayer(
self.hackerToolTarget.owner ) )
417 if ( isdefined(
self.hackerToolTarget.killstreak_hackedCallback ) && ( !isdefined(
self.hackerToolTarget.killstreakTimedOut ) ||
self.hackerToolTarget.killstreakTimedOut ==
false ) )
419 if (
self.hackerToolTarget.killstreak_hackedProtection ==
false )
423 if ( isdefined( level.play_killstreak_being_hacked_dialog ) )
425 self.hackerToolTarget.owner [[level.play_killstreak_being_hacked_dialog]](
self.hackerToolTarget.killstreakType,
self.hackerToolTarget.killstreakId );
431 if ( isdefined( level.play_killstreak_firewall_being_hacked_dialog ) )
433 self.hackerToolTarget.owner [[level.play_killstreak_firewall_being_hacked_dialog]](
self.hackerToolTarget.killstreakType,
self.hackerToolTarget.killstreakId );
440 self WeaponLockStart(
self.hackerToolTarget );
442 if ( isdefined(
self.hackerToolTarget.killstreak_hackedProtection ) &&
self.hackerToolTarget.killstreak_hackedProtection ==
true )
461 if (
self.hackerToolLostSightlineTime == 0 )
463 self.hackerToolLockTimeElapsed += 0.1 *
hackingTimeScale(
self.hackerToolTarget );
464 hackPercentage = (
self.hackerToolLockTimeElapsed / ( lockOnTime )) * 100;
465 self SetWeaponHackPercent( weapon, hackPercentage );
471 if (
self.hackerToolLockTimeElapsed < 0 )
473 self.hackerToolLockTimeElapsed = 0;
477 hackPercentage = (
self.hackerToolLockTimeElapsed / ( lockOnTime )) * 100;
479 self SetWeaponHackPercent( weapon, hackPercentage );
483 if (
self.hackerToolLockTimeElapsed < lockOnTime )
488 assert( isdefined(
self.hackerToolTarget ));
490 self notify(
"stop_lockon_sound" );
491 self.hackerToolLockFinalized =
true;
493 self WeaponLockFinalize(
self.hackerToolTarget );
499 if (
self IsEMPJammed() )
507 if ( !isdefined( bestTarget ))
533 if ( !isdefined(
self.hacker_sound_ent ) || ( isdefined(
self.hacker_alreadyhacked ) &&
self.hacker_alreadyhacked ==
false ) )
535 self.hacker_sound_ent =
true;
536 self.hacker_alreadyhacked =
true;
537 self playloopsound(
"evt_hacker_unhackable_loop" );
548 self.hackerToolTarget = bestTarget;
551 self.hackerToolLockStartTime = getTime();
552 self.hackerToolLockStarted =
true;
553 self.hackerToolLostSightlineTime = 0;
554 self.hackerToolLockTimeElapsed = 0.0;
555 self SetWeaponHackPercent( weapon, 0.0 );
556 if ( isdefined(
self.hackerToolTarget ) )
565 self endon(
"death" );
566 self endon(
"disconnect" );
568 self notify(
"watchTargetEntityUpdate" );
569 self endon(
"watchTargetEntityUpdate" );
571 self endon(
"clearHackerTarget" );
573 bestTarget endon(
"death" );
575 bestTarget waittill(
"hackertool_update_ent", newEntity );
577 self.hackerToolTarget = newEntity;
584 targetsAll = ArrayCombine( target_getArray(), level.MissileEntities,
false,
false );
585 targetsAll = ArrayCombine( targetsAll, level.hackerToolTargets,
false,
false );
587 for ( idx = 0; idx < targetsAll.size; idx++ )
589 target_ent = targetsAll[ idx ];
591 if ( !isdefined( target_ent ) || !isdefined( target_ent.owner ) )
598 if( GetDvarString(
"scr_freelock") ==
"1" )
603 targetsValid[targetsValid.size] = targetsAll[idx];
609 if ( level.teamBased || level.use_team_based_logic_for_locking_on ===
true )
615 targetsValid[ targetsValid.size ] = target_ent;
618 else if ( isdefined( target_ent.team ))
620 if ( target_ent.team !=
self.team )
624 targetsValid[ targetsValid.size ] = target_ent;
628 else if ( isdefined( target_ent.owner.team ) )
630 if ( target_ent.owner.team !=
self.team )
634 targetsValid[ targetsValid.size ] = target_ent;
647 targetsValid[ targetsValid.size ] = target_ent;
650 else if( isdefined( target_ent.owner ) &&
self != target_ent.owner )
654 targetsValid[ targetsValid.size ] = target_ent;
661 chosenEnt = undefined;
663 if ( targetsValid.size != 0 )
666 chosenEnt = targetsValid[0];
687 if( Target_ScaleMinMaxRadius( target,
self, level.hackerToolLockOnFOV, radiusInner, radiusOuter ) > 0.0 )
692 return Target_BoundingIsUnderReticle(
self, target, weapon.lockOnMaxRange );
705 if ( radiusInner != radiusOuter )
708 scale = Target_ScaleMinMaxRadius( target,
self, level.hackerToolLockOnFOV, radiusInner, radiusOuter );
709 scale = scale * scale * scale * scale;
712 hackerToolDebugText = GetDvarInt(
"hackertoolDebugText", 0 ) ;
713 if ( hackerToolDebugText )
715 print3d( target.origin,
"scale: " + scale +
"\nInner: " + radiusInner +
" Outer: " + radiusOuter, ( 0, 0, 0 ), 1, hackerToolDebugText, 2 );
717 assert( hacktime > 0 );
721 if ( !isdefined( hackRatio ) )
734 if ( isdefined( target.killstreakHackLostLineOfSightTimeMs ) && target.killstreakHackLostLineOfSightTimeMs > 0 )
737 assert( target.killstreakHackLostLineOfSightTimeMs > 0 );
739 hackRatio = 1000 / target.killstreakHackLostLineOfSightTimeMs;
753 if ( isdefined( entity.classname ) && entity.classname ==
"grenade" )
755 if ( isdefined( entity.weapon ) )
758 if ( isdefined( watcher ))
760 if ( watcher.hackable )
763 assert( isdefined( watcher.hackerToolRadius ));
764 assert( isdefined( watcher.hackerToolTimeMs ));
783 assert( isdefined( entity.classname ));
784 assert( isdefined( entity.weapon ));
790 assert( watcher.hackable );
791 assert( isdefined( watcher.hackerToolRadius ));
794 return watcher.hackerToolRadius;
804 assert( isdefined( entity.classname ));
805 assert( isdefined( entity.weapon ));
811 assert( watcher.hackable );
812 assert( isdefined( watcher.hackerToolTimeMs ));
815 return watcher.hackerToolTimeMs;
824 if ( isdefined( entity.model ))
826 return entity.model ==
"wpn_t7_care_package_world";
840 if ( !isdefined( ent ))
850 if (
self IsEMPJammed() )
855 if ( !( target_isTarget( ent ) || isdefined( ent.allowHackingAfterCloak ) && ent.allowHackingAfterCloak ==
true )
857 && !IsInArray( level.hackerToolTargets, ent ) )
864 if ( DistanceSquared(
self.origin, ent.origin ) > ( weapon.lockOnMaxRange * weapon.lockOnMaxRange ) )
881 if (
IS_TRUE( entity.previouslyHacked ) )
898 if ( isdefined(
self.hackerToolTarget ) )
900 lockOnTime =
self getLockOnTime(
self.hackerToolTarget, weapon );
903 if ( lockOnTime == 0 ||
self IsEMPJammed() )
912 self.hackerToolLostSightlineTime = 0;
916 if (
self.hackerToolLostSightlineTime == 0 )
919 self.hackerToolLostSightlineTime = getTime();
922 timePassed = GetTime() -
self.hackerToolLostSightlineTime;
923 lostLineOfSightTimeLimitMsec = level.hackerToolLostSightLimitMs;
924 if ( isdefined(
self.hackerToolTarget.killstreakHackLostLineOfSightLimitMs ) )
926 lostLineOfSightTimeLimitMsec =
self.hackerToolTarget.killstreakHackLostLineOfSightLimitMs;
929 if ( timePassed >= lostLineOfSightTimeLimitMsec )
946 self endon(
"death" );
948 if ( isdefined( radius ))
950 self.hackerToolRadius = radius;
954 self.hackerToolRadius = level.hackerToolLockOnRadius;
957 if ( isdefined( hackTimeMs ))
959 self.hackerToolTimeMs = hackTimeMs;
963 self.hackerToolTimeMs = level.hackerToolHackTimeMs;
967 level.hackerToolTargets[ level.hackerToolTargets.size ] =
self;
976 self waittill(
"death" );
977 ArrayRemoveValue( level.hackerToolTargets,
self );
986 radius = level.hackerToolLockOnRadius;
990 /#assert( isdefined( target.hackerToolRadius ));#/
991 radius = target.hackerToolRadius;
997 else if ( isdefined( target.hackerToolInnerRadius ))
999 radius = target.hackerToolInnerRadius;
1001 else if ( isdefined( target.hackerToolRadius ))
1003 radius = target.hackerToolRadius;
1015 radius = level.hackerToolLockOnRadius;
1019 /#assert( isdefined( target.hackerToolRadius ));#/
1020 radius = target.hackerToolRadius;
1026 else if ( isdefined( target.hackerToolOuterRadius ))
1028 radius = target.hackerToolOuterRadius;
1030 else if ( isdefined( target.hackerToolRadius ))
1032 radius = target.hackerToolRadius;
1048 /#assert( isdefined( target.hackerToolTimeMs ));#/
1051 if ( isdefined( target.owner ) && ( target.owner ==
self ))
1053 time = level.carePackageOwnerHackerToolTimeMs;
1055 else if ( isdefined(target.owner) && (target.owner.team ==
self.team) )
1057 time = level.carePackageFriendlyHackerToolTimeMs;
1061 time = level.carePackageHackerToolTimeMs;
1068 else if ( isdefined( target.hackerToolInnerTimeMs ))
1070 time = target.hackerToolInnerTimeMs;
1075 time = level.vehicleHackerToolTimeMs;
1087 /#assert( isdefined( target.hackerToolTimeMs ));#/
1090 if ( isdefined( target.owner ) && ( target.owner ==
self ))
1092 time = level.carePackageOwnerHackerToolTimeMs;
1094 else if ( isdefined(target.owner) && (target.owner.team ==
self.team) )
1096 time = level.carePackageFriendlyHackerToolTimeMs;
1100 time = level.carePackageHackerToolTimeMs;
1107 else if ( isdefined( target.hackerToolOuterTimeMs ))
1109 time = target.hackerToolOuterTimeMs;
1114 time = level.vehicleHackerToolTimeMs;
1123 lockLengthMs =
self getHackTime(
self.hackerToolTarget );
1125 if ( lockLengthMs == 0 )
1130 lockOnSpeed = weapon.lockOnSpeed;
1132 if ( lockOnSpeed <= 0 )
1137 return lockLengthMs / lockOnSpeed;
1145 level.hackerToolLostSightLimitMs = GetDvarInt(
"scr_hackerToolLostSightLimitMs", 1000 );
1146 level.hackerToolLockOnRadius = GetDvarFloat(
"scr_hackerToolLockOnRadius", 20 );
1147 level.hackerToolLockOnFOV = GetDvarInt(
"scr_hackerToolLockOnFOV", 65 );