1 #using scripts\codescripts\struct;
3 #using scripts\shared\abilities\_ability_player;
4 #using scripts\shared\array_shared;
5 #using scripts\shared\callbacks_shared;
6 #using scripts\shared\challenges_shared;
7 #using scripts\shared\clientfield_shared;
8 #using scripts\shared\damagefeedback_shared;
9 #using scripts\shared\hostmigration_shared;
10 #using scripts\shared\hud_shared;
11 #using scripts\shared\hud_message_shared;
12 #using scripts\shared\hud_util_shared;
13 #using scripts\shared\killstreaks_shared;
14 #using scripts\shared\popups_shared;
15 #using scripts\shared\system_shared;
16 #using scripts\shared\util_shared;
17 #using scripts\shared\weapons_shared;
18 #using scripts\shared\weapons\_weaponobjects;
19 #using scripts\shared\weapons\_weapons;
21 #using scripts\mp\_teamops;
22 #using scripts\mp\_util;
23 #using scripts\mp\gametypes\_battlechatter;
24 #using scripts\mp\gametypes\_globallogic_audio;
25 #using scripts\mp\gametypes\_globallogic_score;
26 #using scripts\mp\gametypes\_globallogic_utils;
27 #using scripts\mp\gametypes\_hostmigration;
28 #using scripts\mp\gametypes\_hud_message;
29 #using scripts\mp\gametypes\_loadout;
30 #using scripts\mp\gametypes\_spawning;
31 #using scripts\mp\killstreaks\_ai_tank;
32 #using scripts\mp\killstreaks\_airsupport;
33 #using scripts\mp\killstreaks\_combat_robot;
34 #using scripts\mp\killstreaks\_counteruav;
35 #using scripts\mp\killstreaks\_dart;
36 #using scripts\mp\killstreaks\_dogs;
37 #using scripts\mp\killstreaks\_drone_strike;
38 #using scripts\mp\killstreaks\_emp;
39 #using scripts\mp\killstreaks\_flak_drone;
40 #using scripts\mp\killstreaks\_helicopter;
41 #using scripts\mp\killstreaks\_helicopter_gunner;
42 #using scripts\mp\killstreaks\_killstreak_bundles;
43 #using scripts\mp\killstreaks\_killstreak_detect;
44 #using scripts\mp\killstreaks\_killstreak_hacking;
45 #using scripts\mp\killstreaks\_killstreakrules;
46 #using scripts\mp\killstreaks\_killstreaks;
47 #using scripts\mp\killstreaks\_microwave_turret;
48 #using scripts\mp\killstreaks\_planemortar;
49 #using scripts\mp\killstreaks\_qrdrone;
50 #using scripts\mp\killstreaks\_raps;
51 #using scripts\mp\killstreaks\_rcbomb;
52 #using scripts\mp\killstreaks\_remote_weapons;
53 #using scripts\mp\killstreaks\_remotemissile;
54 #using scripts\mp\killstreaks\_satellite;
55 #using scripts\mp\killstreaks\_sentinel;
56 #using scripts\mp\killstreaks\_supplydrop;
57 #using scripts\mp\killstreaks\_turret;
58 #using scripts\mp\killstreaks\_uav;
60 #insert scripts\mp\_hacker_tool.gsh;
61 #insert scripts\shared\shared.gsh;
62 #insert scripts\shared\clientfields.gsh;
63 #insert scripts\shared\statstable_shared.gsh;
64 #insert scripts\shared\version.gsh;
65 #insert scripts\shared\abilities\_ability_util.gsh;
67 #define TAACOM_KILLSTREAK_READY_WAIT 2.4
69 #precache( "string", "MP_KILLSTREAK_N" );
71 #namespace killstreaks;
77 level.killstreaks = [];
78 level.killstreakWeapons = [];
79 level.dropLocations = [];
80 level.zOffsetCounter = 0;
89 if ( GetDvarString(
"scr_allow_killstreak_building") ==
"" )
91 SetDvar(
"scr_allow_killstreak_building",
"0" );
94 level.menuReferenceForKillStreak = [];
95 level.numKillstreakReservedObjectives = 0;
96 level.killstreakCounter = 0;
102 if( !isdefined(level.roundStartKillstreakDelay) )
104 level.roundStartKillstreakDelay = 0;
140 if( GetDvarint(
"teamOpsEnabled" ) == 1 )
146 function register( killstreakType,
147 killstreakWeaponName,
150 killstreakUseFunction,
151 killstreakDelayStreak,
152 weaponHoldAllowed =
false,
153 killstreakStatsName = undefined,
155 registerInventory = true )
157 assert( isdefined(killstreakType),
"Can not register a killstreak without a valid type name.");
158 assert( !isdefined(level.killstreaks[killstreakType]),
"Killstreak " + killstreakType +
" already registered");
159 assert( isdefined(killstreakUseFunction),
"No use function defined for killstreak " + killstreakType);
161 level.killstreaks[killstreakType] = SpawnStruct();
170 level.killstreaks[killstreakType].usageKey = killstreakUsageKey;
171 level.killstreaks[killstreakType].useFunction = killstreakUseFunction;
172 level.killstreaks[killstreakType].menuName = killstreakMenuName;
173 level.killstreaks[killstreakType].delayStreak = killstreakDelayStreak;
174 level.killstreaks[killstreakType].allowAssists =
false;
175 level.killstreaks[killstreakType].overrideEntityCameraInDemo =
false;
176 level.killstreaks[killstreakType].teamKillPenaltyScale = 1.0;
178 if ( isdefined( killstreakWeaponName ) )
180 killstreakWeapon = GetWeapon( killstreakWeaponName );
181 assert( killstreakWeapon != level.weaponNone );
182 assert( !isdefined(level.killstreakWeapons[killstreakWeapon]),
"Can not have a weapon associated with multiple killstreaks.");
183 level.killstreaks[killstreakType].weapon = killstreakWeapon;
184 level.killstreakWeapons[killstreakWeapon] = killstreakType;
187 if( isdefined( killstreakStatsName ) )
189 level.killstreaks[killstreakType].killstreakStatsName = killstreakStatsName;
192 level.killstreaks[killstreakType].weaponHoldAllowed = weaponHoldAllowed;
196 level.menuReferenceForKillStreak[killstreakMenuName] = killstreakType;
205 register(
"inventory_" + killstreakType,
206 "inventory_" + killstreakWeaponName,
209 killstreakUseFunction,
210 killstreakDelayStreak,
220 return isdefined(level.killstreaks[killstreakType]);
223 function register_strings( killstreakType, receivedText, notUsableText, inboundText, inboundNearPlayerText, hackedText, utilizesAirspace =
true, isInventory =
false )
225 assert( isdefined(killstreakType),
"Can not register a killstreak without a valid type name.");
226 assert( isdefined(level.killstreaks[killstreakType]),
"Killstreak needs to be registered before calling register_strings.");
228 level.killstreaks[killstreakType].receivedText = receivedText;
229 level.killstreaks[killstreakType].notAvailableText = notUsableText;
230 level.killstreaks[killstreakType].inboundText = inboundText;
231 level.killstreaks[killstreakType].inboundNearPlayerText = inboundNearPlayerText;
232 level.killstreaks[killstreakType].hackedText = hackedText;
233 level.killstreaks[killstreakType].utilizesAirspace = utilizesAirspace;
236 register_strings(
"inventory_" + killstreakType, receivedText, notUsableText, inboundText, inboundNearPlayerText, hackedText, utilizesAirspace,
true );
242 taacomDialogBundleKey,
246 enemyStartMultipleDialogKey,
248 hackedStartDialogKey,
254 assert( isdefined(killstreakType),
"Can not register a killstreak without a valid type name.");
255 assert( isdefined(level.killstreaks[killstreakType]),
"Killstreak needs to be registered before calling register_dialog.");
257 level.killstreaks[killstreakType].informDialog = informDialog;
259 level.killstreaks[killstreakType].taacomDialogBundleKey = taacomDialogBundleKey;
261 level.killstreaks[killstreakType].startDialogKey = startDialogKey;
262 level.killstreaks[killstreakType].enemyStartDialogKey = enemyStartDialogKey;
263 level.killstreaks[killstreakType].enemyStartMultipleDialogKey = enemyStartMultipleDialogKey;
265 level.killstreaks[killstreakType].hackedDialogKey = hackedDialogKey;
266 level.killstreaks[killstreakType].hackedStartDialogKey = hackedStartDialogKey;
268 level.killstreaks[killstreakType].requestDialogKey = requestDialogKey;
269 level.killstreaks[killstreakType].threatDialogKey = threatDialogKey;
271 if ( isdefined( pilotDialogarrayKey ) )
276 foreach ( bundle
in taacomBundles )
278 if ( !isdefined( bundle.pilotBundles ) )
280 bundle.pilotBundles = [];
283 bundle.pilotBundles[killstreakType] = [];
286 field = pilotDialogArrayKey + i;
287 fieldValue = GetStructField( bundle, field );
289 while ( isdefined( fieldValue ) )
291 bundle.pilotBundles[killstreakType][i] = fieldValue;
294 field = pilotDialogArrayKey + i;
295 fieldValue = GetStructField( bundle, field );
302 "inventory_" + killstreakType,
304 taacomDialogBundleKey,
308 enemyStartMultipleDialogKey,
310 hackedStartDialogKey,
320 assert( isdefined(killstreakType),
"Can not register a killstreak without a valid type name.");
321 assert( isdefined(level.killstreaks[killstreakType]),
"Killstreak needs to be registered before calling register_alt_weapon.");
323 weapon = GetWeapon( weaponName );
325 if( weapon == level.weaponNone )
328 if ( level.killstreaks[killstreakType].weapon == weapon )
333 if ( !isdefined( level.killstreaks[killstreakType].altWeapons ) )
335 level.killstreaks[killstreakType].altWeapons = [];
338 if( !isdefined( level.killstreakWeapons[weapon] ) )
340 level.killstreakWeapons[weapon] = killstreakType;
342 level.killstreaks[killstreakType].altWeapons[level.killstreaks[killstreakType].altWeapons.size] = weapon;
351 assert( isdefined(killstreakType),
"Can not register a killstreak without a valid type name.");
352 assert( isdefined(level.killstreaks[killstreakType]),
"Killstreak needs to be registered before calling register_remote_override_weapon.");
354 weapon = GetWeapon( weaponName );
355 if ( level.killstreaks[killstreakType].weapon == weapon )
360 if ( !isdefined( level.killstreaks[killstreakType].remoteOverrideWeapons ) )
362 level.killstreaks[killstreakType].remoteOverrideWeapons = [];
365 if( !isdefined( level.killstreakWeapons[weapon] ) )
367 level.killstreakWeapons[weapon] = killstreakType;
369 level.killstreaks[killstreakType].remoteOverrideWeapons[level.killstreaks[killstreakType].remoteOverrideWeapons.size] = weapon;
377 if ( isdefined( level.killstreaks[killstreakType].remoteOverrideWeapons ) )
379 for ( i=0; i<level.killstreaks[killstreakType].remoteOverrideWeapons.size; i++)
381 if ( level.killstreaks[killstreakType].remoteOverrideWeapons[i] == weapon)
396 level.teamops_dvar = dvar;
401 level.killstreaks[killstreakType].allowAssists = allow;
406 level.killstreaks[killstreakType].teamKillPenaltyScale = scale;
413 level.killstreaks[killstreakType].overrideEntityCameraInDemo = value;
420 if ( isdefined( level.menuReferenceForKillStreak[killstreak] ) )
432 return level.menuReferenceForKillStreak[killstreak];
437 Assert( isdefined(level.killstreaks[killstreakType] ) );
438 return level.killstreaks[killstreakType].menuName;
443 killstreakLevel = level.killstreaks[
get_by_menu_name( killstreak ) ].killstreakLevel;
444 if( GetDvarInt(
"custom_killstreak_mode" ) == 2 )
446 if ( isdefined(
self.killstreak[ index ] ) && ( killstreak ==
self.killstreak[ index ] ) )
448 killsRequired = GetDvarInt(
"custom_killstreak_" + index + 1 +
"_kills" );
451 killstreakLevel = GetDvarInt(
"custom_killstreak_" + index + 1 +
"_kills" );
455 return killstreakLevel;
462 hasAlreadyEarnedKillstreak =
true;
466 hasAlreadyEarnedKillstreak =
false;
469 if ( isdefined( killstreak ) &&
is_available(killstreak) && !hasAlreadyEarnedKillstreak )
471 killstreakLevel =
get_level( index, killstreak );
473 if (
self HasPerk(
"specialty_killstreak" ) )
475 reduction = GetDvarint(
"perk_killstreakReduction" );
476 killstreakLevel -= reduction;
479 if( killstreakLevel <= 0 )
485 if ( killstreakLevel == streakCount )
488 self.pers[
"killstreaksEarnedThisKillstreak"] = index + 1;
506 if( !isdefined(
self.pers[
"totalKillstreakCount"]) )
508 self.pers[
"totalKillstreakCount"] = 0;
514 for ( i = 0; i <
self.killstreak.size; i++ )
522 onKillstreak =
false;
523 if( !isdefined(
self.pers[
"kill_streak_before_death"] ) )
525 self.pers[
"kill_streak_before_death"] = 0;
528 streakPlusOne =
self.pers[
"kill_streak_before_death"] + 1;
530 if (
self.pers[
"kill_streak_before_death"] >= 5 )
539 function give( killstreakType, streak, suppressNotification, noXP, toBottom )
541 self endon(
"disconnect");
542 level endon(
"game_ended" );
544 had_to_delay =
false;
546 killstreakGiven =
false;
547 if( isdefined( noXP ) )
549 if (
self give_internal( killstreakType, undefined, noXP, toBottom ) )
551 killstreakGiven =
true;
552 if (
self.just_given_new_inventory_killstreak ===
true )
560 killstreakGiven =
true;
561 if (
self.just_given_new_inventory_killstreak ===
true )
570 self endon(
"disconnect" );
575 if (
self GetInventoryWeapon() == killstreak_weapon )
577 self SetInventoryWeapon( level.weaponNone );
582 currentWeapon =
self GetCurrentWeapon();
583 if( currentWeapon != killstreak_weapon || killstreak_weapon.isCarriedKillstreak )
594 if( isdefined(
self.pers[
"killstreaks"][0] ) )
596 currentWeapon =
self getCurrentWeapon();
600 primaries =
self GetWeaponsListPrimaries();
602 if( primaries.size > 0 )
604 self SwitchToWeapon( primaries[0] );
608 self notify(
"oldest_killstreak_removed",
self.pers[
"killstreaks"][0],
self.pers[
"killstreak_unique_id"][0] );
613 function give_internal( killstreakType, do_not_update_death_count, noXP, toBottom )
615 self.just_given_new_inventory_killstreak = undefined;
617 if ( level.gameEnded )
627 if ( !isdefined( level.killstreaks[killstreakType] ) )
632 if ( !isdefined(
self.pers[
"killstreaks"] ) )
634 self.pers[
"killstreaks"] = [];
636 if( !isdefined(
self.pers[
"killstreak_has_been_used"] ) )
638 self.pers[
"killstreak_has_been_used"] = [];
640 if( !isdefined(
self.pers[
"killstreak_unique_id"] ) )
642 self.pers[
"killstreak_unique_id"] = [];
644 if( !isdefined(
self.pers[
"killstreak_ammo_count"] ) )
646 self.pers[
"killstreak_ammo_count"] = [];
649 just_max_stack_removed_inventory_killstreak = undefined;
651 if( isdefined( toBottom ) && toBottom )
653 size =
self.pers[
"killstreaks"].size;
655 if(
self.pers[
"killstreaks"].size >= level.maxInventoryScoreStreaks )
658 just_max_stack_removed_inventory_killstreak =
self.just_removed_used_killstreak;
661 for( i = size; i > 0; i-- )
663 self.pers[
"killstreaks"][i] =
self.pers[
"killstreaks"][i - 1];
664 self.pers[
"killstreak_has_been_used"][i] =
self.pers[
"killstreak_has_been_used"][i - 1];
665 self.pers[
"killstreak_unique_id"][i] =
self.pers[
"killstreak_unique_id"][i - 1];
666 self.pers[
"killstreak_ammo_count"][i] =
self.pers[
"killstreak_ammo_count"][i - 1];
668 self.pers[
"killstreaks"][0] = killstreakType;
669 self.pers[
"killstreak_unique_id"][0] = level.killstreakCounter;
670 level.killstreakCounter++;
672 if( isdefined(noXP) )
674 self.pers[
"killstreak_has_been_used"][0] = noXP;
678 self.pers[
"killstreak_has_been_used"][0] =
false;
688 self.pers[
"killstreak_ammo_count"][0] = 0;
692 self.pers[
"killstreaks"][
self.pers[
"killstreaks"].size] = killstreakType;
693 self.pers[
"killstreak_unique_id"][
self.pers[
"killstreak_unique_id"].size] = level.killstreakCounter;
694 level.killstreakCounter++;
696 if(
self.pers[
"killstreaks"].size > level.maxInventoryScoreStreaks )
699 just_max_stack_removed_inventory_killstreak =
self.just_removed_used_killstreak;
702 if( isdefined(noXP) )
704 self.pers[
"killstreak_has_been_used"][
self.pers[
"killstreak_has_been_used"].size] = noXP;
708 self.pers[
"killstreak_has_been_used"][
self.pers[
"killstreak_has_been_used"].size] =
false;
715 self.pers[
"killstreak_ammo_count"][
self.pers[
"killstreak_ammo_count"].size] = ammoCount;
718 self.just_given_new_inventory_killstreak = ( killstreakType !== just_max_stack_removed_inventory_killstreak );
725 killstreakTableNumber = level.killStreakIndices[ menuName ];
727 if ( !isdefined( killstreakTableNumber ) )
732 if( isdefined( noNotify ) && noNotify )
739 if( GetDvarInt(
"teamOpsEnabled" ) == 0 )
743 self LUINotifyEvent( &
"killstreak_received", 2, killstreakTableNumber, istring( informDialog ) );
744 self LUINotifyEventToSpectators( &
"killstreak_received", 2, killstreakTableNumber, istring( informDialog ) );
752 currentWeapon =
self getCurrentWeapon();
754 keys = getarraykeys( level.killstreaks );
755 for ( i = 0; i < keys.size; i++ )
757 if ( level.killstreaks[keys[i]].weapon == currentWeapon )
768 keys = getarraykeys( level.killstreaks );
770 foreach( key
in keys )
772 killstreak = level.killstreaks[ key ];
774 if ( killstreak.weapon == weapon )
779 if ( isdefined( killstreak.altweapons ) )
781 foreach( altweapon
in killstreak.altweapons )
783 if ( altweapon == weapon )
790 if ( isdefined( killstreak.remoteoverrideweapons ) )
792 foreach( remoteOverrideWeapon
in killstreak.remoteoverrideweapons )
794 if( remoteOverrideWeapon == weapon )
808 if( weapon == level.weaponNone )
814 if( !isdefined( res ) )
823 currentWeapon =
self GetCurrentWeapon();
825 if ( currentWeapon != level.weaponNone && !
IS_TRUE( level.usingMomentum ) )
827 weaponsList =
self GetWeaponsList();
828 for( idx = 0; idx < weaponsList.size; idx++ )
830 carriedWeapon = weaponsList[idx];
832 if ( currentWeapon == carriedWeapon )
838 switch ( carriedWeapon.name )
847 self TakeWeapon( carriedWeapon );
854 if( currentWeapon != weapon && (
self hasWeapon(weapon) ==
false ) )
856 self TakeWeapon( weapon );
857 self GiveWeapon( weapon );
860 if (
IS_TRUE( level.usingMomentum ) )
862 self SetInventoryWeapon( weapon );
864 if( weapon.isCarriedKillstreak )
866 if( !isdefined(
self.pers[
"held_killstreak_ammo_count"][weapon] ) )
868 self.pers[
"held_killstreak_ammo_count"][weapon] = 0;
871 if( !isdefined(
self.pers[
"held_killstreak_clip_count"][weapon] ) )
873 self.pers[
"held_killstreak_clip_count"][weapon] = weapon.clipSize;
876 if( !isdefined(
self.pers[
"killstreak_quantity"][weapon] ) )
878 self.pers[
"killstreak_quantity"][weapon] = 0;
883 return weapon.maxAmmo;
885 else if(
IS_TRUE( useStoredAmmo ) &&
self.pers[
"killstreak_ammo_count"][
self.pers[
"killstreak_ammo_count"].size - 1] > 0 )
887 switch( weapon.name )
889 case "inventory_minigun":
890 if(
IS_TRUE(
self.minigunActive ) )
892 return self.pers[
"held_killstreak_ammo_count"][weapon];
895 case "inventory_m32":
898 return self.pers[
"held_killstreak_ammo_count"][weapon];
904 self.pers[
"held_killstreak_ammo_count"][weapon] =
self.pers[
"killstreak_ammo_count"][
self.pers[
"killstreak_ammo_count"].size - 1];
909 self.pers[
"held_killstreak_ammo_count"][weapon] = weapon.maxAmmo;
910 self.pers[
"held_killstreak_clip_count"][weapon] = weapon.clipSize;
913 return self.pers[
"held_killstreak_ammo_count"][weapon];
917 switch ( weapon.name )
919 case "inventory_minigun_drop":
920 case "inventory_m32_drop":
921 case "inventory_missile_drone":
923 case "combat_robot_marker":
924 case "inventory_combat_robot_marker":
927 case "inventory_dart":
929 case "ai_tank_marker":
930 case "inventory_ai_tank_marker":
932 case "supplydrop_marker":
933 case "inventory_supplydrop_marker":
946 self setActionSlot( 4,
"weapon", weapon );
953 if ( level.gameEnded )
958 if (
IS_TRUE( level.usingMomentum ) )
960 self SetInventoryWeapon( level.weaponNone );
964 self setActionSlot( 4,
"" );
967 if ( !isdefined(
self.pers[
"killstreaks"] ) ||
self.pers[
"killstreaks"].size == 0 )
972 killstreakType =
self.pers[
"killstreaks"][
self.pers[
"killstreaks"].size - 1];
974 if ( !isdefined( level.killstreaks[killstreakType] ) )
979 weapon = level.killstreaks[killstreakType].weapon;
985 if( weapon.isCarriedKillstreak )
987 self setWeaponAmmoClip( weapon,
self.pers[
"held_killstreak_clip_count"][weapon] );
988 self setWeaponAmmoStock( weapon, ammoCount -
self.pers[
"held_killstreak_clip_count"][weapon] );
991 if ( !isdefined( do_not_update_death_count ) || do_not_update_death_count !=
false )
993 self.pers[
"killstreakItemDeathCount"+killstreakType] =
self.deathCount;
1001 if ( isdefined(
self.pers[
"killstreaks"] ) &&
self.pers[
"killstreaks"].size > 0 )
1009 return VAL(
self.pers[
"killstreak_quantity"][killstreakWeapon], 0 );
1016 previousQuantity = quantity;
1019 if ( quantity > level.scoreStreaksMaxStacking )
1021 quantity = level.scoreStreaksMaxStacking;
1026 if(
self hasWeapon( killstreakWeapon ) ==
false )
1028 self TakeWeapon( killstreakWeapon );
1029 self GiveWeapon( killstreakWeapon );
1030 self SetEverHadWeaponAll(
true );
1033 self.pers[
"killstreak_quantity"][killstreakWeapon] = quantity;
1034 self SetWeaponAmmoClip( killstreakWeapon, quantity );
1040 foreach ( equippedKillstreak
in self.killstreak )
1042 if ( equippedKillstreak == killstreakMenuName )
1054 if( !isdefined( killstreak ) || !isdefined( player.pers[
"killstreaks"] ) )
1057 for( i = 0; i <
self.pers[
"killstreaks"].size; i++ )
1059 if( player.pers[
"killstreaks"][i] == killstreak )
1068 if(!isPlayer(player) || !isDefined(recordstreakindex))
1073 if( !isdefined(
self.killstreakEvents) )
1074 player.killstreakEvents = associativeArray();
1078 if(isDefined(
self.killstreakEvents[recordStreakIndex]))
1080 kills = player.killstreakEvents[recordStreakIndex];
1081 eventIndex = player RecordKillStreakEvent( recordStreakIndex );
1084 player.killstreakEvents[recordStreakIndex] = undefined;
1089 eventIndex = player RecordKillStreakEvent( recordStreakIndex );
1090 player.killstreakEvents[recordStreakIndex] = eventIndex;
1096 self endon(
"disconnect" );
1098 continue_wait =
true;
1100 while( continue_wait )
1102 self waittill(
"killstreak_done", successful, killstreakType );
1104 if ( killstreakType == killstreak )
1105 continue_wait =
false;
1112 recordStreakIndex = undefined;
1113 if( isdefined( level.killstreaks[killstreak].menuname ) )
1115 recordStreakIndex = level.killstreakindices[level.killstreaks[killstreak].menuname];
1119 if (
IS_TRUE( level.usingScoreStreaks ) )
1124 if (
self GetInventoryWeapon() == killstreak_weapon )
1126 self SetInventoryWeapon( level.weaponNone );
1134 else if (
IS_TRUE( level.usingMomentum ) )
1136 if (
IS_TRUE( isFromInventory ) && (
self GetInventoryWeapon() == killstreak_weapon ) )
1139 self SetInventoryWeapon( level.weaponNone );
1151 if ( !
IS_TRUE( level.usingMomentum ) )
1153 self setActionSlot( 4,
"" );
1164 currentWeapon =
self GetCurrentWeapon();
1166 if( currentWeapon == killstreak_weapon && killstreak_weapon.isCarriedKillstreak )
1180 if ( currentWeapon.isGameplayWeapon )
1189 if ( !isdefined( killstreakForCurrentWeapon ) && currentWeapon.isHeroWeapon )
1194 if ( successful || !isdefined( killstreakForCurrentWeapon ) || killstreakForCurrentWeapon == killstreak )
1213 if ( isdefined(
self.selectingLocation ) )
1218 self thread
remove_when_done( killstreak, hasKillstreakBeenUsed, isFromInventory );
1224 self.just_removed_used_killstreak = undefined;
1226 if( !isdefined(
self.pers[
"killstreaks"] ) )
1232 killstreakIndex = undefined;
1234 for ( i =
self.pers[
"killstreaks"].size - 1; i >= 0; i-- )
1236 if (
self.pers[
"killstreaks"][i] == killstreak )
1238 if( isdefined( killstreakId ) &&
self.pers[
"killstreak_unique_id"][i] != killstreakId )
1243 killstreakIndex = i;
1248 if ( !isdefined(killstreakIndex) )
1253 self.just_removed_used_killstreak = killstreak;
1260 arraySize =
self.pers[
"killstreaks"].size;
1261 for ( i = killstreakIndex; i < arraySize - 1; i++ )
1263 self.pers[
"killstreaks"][i] =
self.pers[
"killstreaks"][i + 1];
1264 self.pers[
"killstreak_has_been_used"][i] =
self.pers[
"killstreak_has_been_used"][i + 1];
1265 self.pers[
"killstreak_unique_id"][i] =
self.pers[
"killstreak_unique_id"][i + 1];
1266 self.pers[
"killstreak_ammo_count"][i] =
self.pers[
"killstreak_ammo_count"][i + 1];
1269 self.pers[
"killstreaks"][arraySize-1] = undefined;
1270 self.pers[
"killstreak_has_been_used"][arraySize-1] = undefined;
1271 self.pers[
"killstreak_unique_id"][arraySize-1] = undefined;
1272 self.pers[
"killstreak_ammo_count"][arraySize-1] = undefined;
1279 self endon(
"disconnect");
1280 self endon(
"death");
1281 self endon(
"joined_team" );
1282 self endon(
"joined_spectators" );
1284 self waittill(
"weapon_change" );
1286 inventoryWeapon =
self GetInventoryWeapon();
1287 if ( inventoryWeapon != killstreakWeapon )
1289 self TakeWeapon( killstreakWeapon );
1295 if (
self.pers[
"killstreaks"].size == 0 )
1300 return self.pers[
"killstreaks"][
self.pers[
"killstreaks"].size-1];
1305 if ( !
IS_TRUE( level.usingMomentum ) )
1307 if (
self.pers[
"killstreak_has_been_used"].size == 0 )
1312 return self.pers[
"killstreak_has_been_used"][
self.pers[
"killstreak_has_been_used"].size-1];
1318 if (
self.pers[
"killstreak_unique_id"].size == 0 )
1323 return self.pers[
"killstreak_unique_id"][
self.pers[
"killstreak_unique_id"].size-1];
1328 for( index =
self.pers[
"killstreak_unique_id"].size - 1; index >= 0; index-- )
1330 if(
self.pers[
"killstreak_unique_id"][index] == killstreakId )
1342 if ( !
IS_TRUE( level.usingMomentum ) )
1347 if ( !isdefined( killstreak ) )
1352 Assert( isdefined(level.killstreaks[killstreak]) );
1354 return level.killstreaks[killstreak].momentumCost;
1359 if( isdefined( level.killstreakWeapons[weapon] ) )
1360 return level.killstreakWeapons[weapon];
1362 return level.killstreakWeapons[weapon.rootweapon];
1367 prefix =
"inventory_";
1371 if ( isdefined( killstreak ) )
1373 if ( StrStartsWith( killstreak, prefix ) )
1374 killstreak = getSubStr( killstreak, prefix.size );
1384 if ( !isdefined( killstreak ) )
1389 if ( level.killstreaks[killstreak].allowAssists )
1401 if ( !isdefined( killstreak ) )
1406 return level.killstreaks[killstreak].teamKillPenaltyScale;
1413 if ( !isdefined( killstreak ) )
1418 if ( level.killstreaks[killstreak].overrideEntityCameraInDemo )
1423 if ( isdefined( player.remoteWeapon ) &&
IS_TRUE( player.remoteWeapon.controlled ) )
1433 self endon(
"death" );
1434 self endon(
"disconnect" );
1435 self endon(
"weapon_change" );
1437 slot =
self GadgetGetSlot( weapon );
1443 self.lastNonKillstreakWeapon = weapon;
1452 self endon(
"death" );
1453 self endon(
"disconnect" );
1455 self.lastNonKillstreakWeapon =
self GetCurrentWeapon();
1456 lastValidPimary =
self GetCurrentWeapon();
1457 if (
self.lastNonKillstreakWeapon == level.weaponNone )
1459 weapons =
self GetWeaponsListPrimaries();
1460 if ( weapons.size > 0 )
1462 self.lastNonKillstreakWeapon = weapons[0];
1466 self.lastNonKillstreakWeapon = level.weaponBaseMelee;
1469 Assert(
self.lastNonKillstreakWeapon != level.weaponNone );
1473 currentWeapon =
self GetCurrentWeapon();
1474 self waittill(
"weapon_change", weapon );
1478 lastValidPimary = weapon;
1481 if ( weapon ==
self.lastNonKillstreakWeapon || weapon == level.weaponNone || weapon == level.weaponBaseMelee )
1486 if ( weapon.isGameplayWeapon )
1491 if( isdefined(
self.resurrect_weapon ) && ( weapon ==
self.resurrect_weapon ) )
1498 if ( isdefined(
name ) && !weapon.isCarriedKillstreak )
1500 killstreak = level.killstreaks[
name ];
1504 if ( currentWeapon.isEquipment )
1506 if (
self.lastNonKillstreakWeapon.isCarriedKillstreak )
1508 self.lastNonKillstreakWeapon = lastValidPimary;
1513 if ( weapon.isHeroWeapon )
1515 if ( weapon.gadget_heroversion_2_0 )
1517 if ( weapon.isGadget &&
self GetAmmoCount(weapon ) > 0 )
1526 self.lastNonKillstreakWeapon = weapon;
1532 self endon (
"death" );
1533 self endon (
"disconnect" );
1534 level endon (
"game_ended" );
1542 self waittill(
"weapon_change", weapon );
1551 if ( !
IS_TRUE( level.usingMomentum ) )
1563 inventoryButtonPressed = (
self InventoryButtonPressed() ) || ( isdefined(
self.pers[
"isBot"] ) );
1567 if(
IS_TRUE(
self.usingKillstreakHeldWeapon ) && weapon.isCarriedKillstreak )
1572 isFromInventory = undefined;
1574 if (
IS_TRUE( level.usingScoreStreaks ) )
1576 if ( ( weapon ==
self GetInventoryWeapon() ) )
1578 isFromInventory =
true;
1580 else if ((
self GetAmmoCount( weapon ) <= 0 ) && (weapon.name !=
"killstreak_ai_tank"))
1586 else if (
IS_TRUE( level.usingMomentum ) )
1588 if ( ( weapon ==
self GetInventoryWeapon() ) && inventoryButtonPressed )
1590 isFromInventory =
true;
1592 else if (
self.momentum < level.killstreaks[killstreak].momentumCost )
1600 if ( !isdefined( level.startTime ) && ( level.roundStartKillstreakDelay > 0 ) )
1612 if( !isdefined(level.startTime) )
1617 if( level.roundStartKillstreakDelay < ( ( ( gettime() - level.startTime ) - level.discardTime ) / 1000 ) )
1628 if( killstreakWeapon.isCarriedKillstreak )
1644 if( isdefined( level.killstreaks[killstreakType] ) &&
IS_TRUE( level.killstreaks[killstreakType].delayStreak ) )
1657 switch( level.killstreaks[killstreakType].killstreakLevel )
1697 if ( timeLeft <= 0 )
1702 self iPrintLnBold( &
"MP_UNAVAILABLE_FOR_N",
" " + timeLeft +
" ", &
"EXE_SECONDS" );
1707 assert( isdefined(level.killstreaks[killstreakType].useFunction),
"No use function defined for killstreak " + killstreakType);
1709 self.usingKillstreakFromInventory = isFromInventory;
1711 if ( level.inFinalKillcam )
1720 else if ( [[level.killstreaks[killstreakType].useFunction]](killstreakType) )
1724 if ( isdefined(
self ) )
1727 if ( !isdefined(
self.pers[level.killstreaks[killstreakType].usageKey] ) )
1729 self.pers[level.killstreaks[killstreakType].usageKey] = 0;
1732 self.pers[level.killstreaks[killstreakType].usageKey]++;
1733 self notify(
"killstreak_used", killstreakType );
1734 self notify(
"killstreak_done",
true, killstreakType );
1737 self.usingKillstreakFromInventory = undefined;
1742 self.usingKillstreakFromInventory = undefined;
1744 if ( isdefined(
self ) )
1746 self notify(
"killstreak_done",
false, killstreakType );
1753 if ( !isdefined(
self.pers[
"totalKillstreakCount"] ) )
1755 self.pers[
"totalKillstreakCount"] = 0;
1759 self.pers[
"totalKillstreakCount"]++;
1764 assert( isdefined(level.killstreaks[killstreakType]),
"Killstreak not registered.");
1766 if( isdefined( level.killstreaks[killstreakType].altWeapons ) )
1768 for( i = 0; i < level.killstreaks[killstreakType].altWeapons.size; i++ )
1770 if( isdefined( level.killstreaks[killstreakType].altWeapons[i] ) )
1772 return level.killstreaks[killstreakType].altWeapons[i];
1777 return level.weaponNone;
1782 if( GetDvarInt(
"teamOpsEnabled" ) == 1 )
1785 killstreakBuilding = GetDvarint(
"scr_allow_killstreak_building" );
1787 if ( killstreakBuilding == 0 )
1800 return distance2d( point, targetpos ) <= radius * 1.25;
1805 if ( !isdefined( level.killstreaks[killstreakType] ) )
1810 if ( level.teambased )
1812 players = level.players;
1813 if ( !level.hardcoreMode && isdefined(level.killstreaks[killstreakType].inboundNearPlayerText))
1815 for(i = 0; i < players.size; i++)
1817 if(isalive(players[i]) && (isdefined(players[i].pers[
"team"])) && (players[i].pers[
"team"] == team))
1821 players[i] iprintlnbold(level.killstreaks[killstreakType].inboundNearPlayerText);
1827 if ( isdefined(level.killstreaks[killstreakType]) )
1829 for ( i = 0; i < level.players.size; i++ )
1831 player = level.players[i];
1832 playerteam = player.pers[
"team"];
1833 if ( isdefined( playerteam ) )
1835 if ( playerteam == team )
1837 player iprintln( level.killstreaks[killstreakType].inboundText, owner );
1845 if ( !level.hardcoreMode && isdefined(level.killstreaks[killstreakType].inboundNearPlayerText) )
1849 owner iprintlnbold(level.killstreaks[killstreakType].inboundNearPlayerText);
1891 excludeSelf[0] =
self;
1893 if ( level.teambased )
1907 if ( !isdefined( killstreakType ) ||
1908 !isdefined( killstreakId ) )
1914 self notify (
"killstreak_start_" + killstreakType );
1915 self notify (
"killstreak_start_inventory_" + killstreakType );
1917 dialogKey = level.killstreaks[killstreakType].requestDialogKey;
1919 if ( !isdefined(
self.currentKillstreakDialog ) && isdefined( dialogKey ) && isdefined( level.heroPlayDialog ) )
1921 self thread [[level.heroPlayDialog]]( dialogKey );
1925 excludeSelf[0] =
self;
1927 if ( level.teambased )
1942 if ( !isdefined( level.gameEnded ) || !level.gameEnded )
1944 ready_sfx_alias =
"mpl_killstreak_" + killstreaktype;
1946 if ( isdefined (ready_sfx_alias))
1948 self playsoundtoplayer (ready_sfx_alias,
self );
1955 self notify(
"killstreak_ready_" + killstreakType );
1957 self endon(
"death" );
1958 self endon(
"killstreak_start_" + killstreakType );
1959 self endon(
"killstreak_ready_" + killstreakType );
1961 level endon(
"game_ended" );
1963 if ( isdefined( level.gameEnded ) && level.gameEnded )
1973 if ( isdefined( taacomWaitTime ) )
1975 wait ( taacomWaitTime );
1984 if ( !isdefined(
self.owner ) ||
1985 !isdefined(
self.team ) ||
1986 self.team !=
self.owner.team )
1999 if ( !isdefined(
self.owner ) ||
2000 !isdefined(
self.team ) ||
2001 self.team !=
self.owner.team )
2012 if ( !isdefined(
self.owner ) ||
2013 !isdefined(
self.owner.team ) ||
2014 !isdefined(
self.team ) ||
2015 self.team !=
self.owner.team )
2020 self.owner
play_pilot_dialog( dialogKey, killstreakType, killstreakId,
self.pilotIndex );
2026 if ( !isdefined( killstreakType ) ||
2027 !isdefined( pilotIndex ) )
2038 assert( isdefined( dialogKey ) );
2039 assert( isdefined( killstreakType ) );
2041 if ( !isdefined(
self.owner ) ||
2042 !isdefined(
self.team ) ||
2043 self.team !=
self.owner.team )
2054 assert( isdefined( dialogKey ) );
2055 assert( isdefined( killstreakType ) );
2057 if ( !isdefined( pilotIndex ) )
2069 if ( !isdefined( killstreakType ) )
2076 if( !isdefined( taacomBundle.pilotBundles[killstreakType] ) )
2081 numPilots = taacomBundle.pilotBundles[killStreakType].size;
2083 if ( numPilots <= 0 )
2088 return RandomInt( numPilots );
2094 assert( isdefined( killstreakType ) );
2096 self endon (
"death" );
2097 self endon (
"delete" );
2098 self endon (
"leaving" );
2099 level endon(
"game_ended" );
2103 if ( !isdefined(
self.owner ) )
2109 players = array::randomize( players );
2111 foreach( player
in players )
2118 lookAngles = player GetPlayerAngles();
2120 if ( lookAngles[0] < 270 || lookAngles[0] > 330 )
2125 lookDir = AnglesToForward( lookAngles );
2126 eyePoint = player getEye();
2128 streakDir = VectorNormalize(
self.origin - eyePoint );
2130 dot = VectorDot( streakDir, lookDir );
2137 traceResult = BulletTrace( eyePoint,
self.origin,
true, player );
2138 if ( traceResult[
"fraction"] >= 1.0 || traceResult[
"entity"] ===
self )
2158 if ( isdefined( level.killstreaks[killstreakType].informDialog ) )
2160 return level.killstreaks[killstreakType].informDialog;
2167 assert( isdefined(level.killstreaks[killstreakType]),
"Killstreak needs to be registered before calling get_killstreak_usage.");
2174 if ( !isdefined(
self.pers[usageKey] ) )
2179 return self.pers[usageKey];
2184 self endon(
"disconnect");
2188 if ( !isdefined(
self.pers[
"killstreaks"] ) )
2190 self.pers[
"killstreaks"] = [];
2192 if ( !isdefined(
self.pers[
"killstreak_has_been_used"] ) )
2194 self.pers[
"killstreak_has_been_used"] = [];
2196 if ( !isdefined(
self.pers[
"killstreak_unique_id"] ) )
2198 self.pers[
"killstreak_unique_id"] = [];
2200 if( !isdefined(
self.pers[
"killstreak_ammo_count"] ) )
2202 self.pers[
"killstreak_ammo_count"] = [];
2205 size =
self.pers[
"killstreaks"].size;
2212 self.killcamKilledByEnt = undefined;
2217 self endon(
"disconnect");
2219 self SetInventoryWeapon( level.weaponNone );
2220 self.pers[
"cur_kill_streak"] = 0;
2221 self.pers[
"cur_total_kill_streak"] = 0;
2222 self setplayercurrentstreak( 0 );
2223 self.pers[
"totalKillstreakCount"] = 0;
2224 self.pers[
"killstreaks"] = [];
2225 self.pers[
"killstreak_has_been_used"] = [];
2226 self.pers[
"killstreak_unique_id"] = [];
2227 self.pers[
"killstreak_ammo_count"] = [];
2229 if (
IS_TRUE( level.usingScoreStreaks ) )
2231 self.pers[
"killstreak_quantity"] = [];
2232 self.pers[
"held_killstreak_ammo_count"] = [];
2233 self.pers[
"held_killstreak_clip_count"] = [];
2239 self disableUsability();
2242 if ( isdefined(
self ) )
2244 self enableUsability();
2252 self endon(
"endWatchForRemoveRemoteWeapon" );
2255 self waittill(
"remove_remote_weapon" );
2257 self enableUsability();
2263 if ( isdefined( streak ) && ( ( streak ==
"qrdrone" ) || ( streak ==
"dart" ) || ( streak ==
"killstreak_remote_turret" ) || ( streak ==
"killstreak_ai_tank" ) || (streak ==
"qrdrone") || (streak ==
"sentinel") ) )
2265 laptopWait =
"timeout";
2274 if ( laptopWait ==
"weapon_switch_started" )
2279 if ( !isAlive(
self ) && !always_allow )
2284 if ( laptopWait ==
"disconnect" || laptopWait ==
"death" )
2286 if ( laptopWait ==
"disconnect" )
2288 return (
"disconnect" );
2291 if (
self.team ==
"spectator" )
2296 return (
"success" );
2299 if (
self IsEMPJammed() && !
IS_TRUE(
self.ignoreEMPJammed ) )
2312 self notify(
"endWatchForRemoveRemoteWeapon" );
2316 if ( blackOutWait !=
"disconnect" )
2320 if (
self.team ==
"spectator" )
2328 if ( blackOutWait ==
"disconnect" )
2330 return (
"disconnect" );
2334 return (
"success" );
2338 if (
self isOnLadder() )
2343 if ( !isAlive(
self ) )
2348 if (
self IsEMPJammed() && !
IS_TRUE(
self.ignoreEMPJammed ) )
2363 if ( blackOutWait ==
"disconnect" )
2365 return (
"disconnect" );
2369 return (
"success" );
2375 self endon(
"disconnect" );
2377 if ( isdefined(
delay ) )
2386 if (
self isCarryingTurret() )
2405 if ( !isdefined(
self ) )
2410 self.dofutz =
false;
2411 self.no_fade2black =
false;
2414 if ( isdefined(
self.carryIcon ) )
2416 self.carryIcon.alpha = 1;
2419 self.usingRemote = undefined;
2421 self enableOffhandWeapons();
2422 self enableWeaponCycling();
2424 curWeapon =
self getCurrentWeapon();
2426 if ( isalive(
self ) )
2431 if( !level.gameEnded )
2434 self notify(
"stopped_using_remote" );
2441 self endon(
"disconnect");
2448 self.killstreak_delay_killcam = killstreak_name;
2453 self.killstreak_delay_killcam = undefined;
2468 self.maxhealth = max_health;
2469 self.lowhealth = low_health;
2475 if ( isdefined( tableMaxHealth ) )
2477 self.maxhealth = tableMaxHealth;
2482 if ( isdefined( tableLowHealth ) )
2484 self.lowhealth = tableLowHealth;
2489 if ( isdefined( tableHackedHealth ) )
2491 self.hackedHealth = tableHackedHealth;
2495 self.hackedHealth =
self.maxhealth;
2500 max_health, destroyed_callback,
2501 low_health, low_health_callback,
2502 emp_damage, emp_callback,
2503 allow_bullet_damage )
2505 self endon(
"death" );
2506 self endon(
"delete" );
2508 self.health = 9999999;
2509 self.damageTaken = 0;
2511 self setup_health( killstreak_ref, max_health, low_health );
2513 assert( ( !IsVehicle(
self ) || !IsSentient(
self ) ),
"MonitorDamage should not be called on a sentient vehicle. For sentient vehicles, use overrideVehicleDamage instead.");
2517 weapon_damage = undefined;
2519 self waittill(
"damage",
damage, attacker, direction, point, type, tagName, modelName, partname, weapon, flags, inflictor, chargeLevel );
2521 if(
IS_TRUE(
self.invulnerable ) )
2526 if( !isdefined( attacker ) || !isplayer( attacker ) )
2537 if( isdefined(
self.owner ) && attacker ==
self.owner )
2542 isValidAttacker =
true;
2543 if( level.teambased )
2545 isValidAttacker = ( isdefined( attacker.team ) && attacker.team !=
self.team );
2548 if( !isValidAttacker )
2555 damage = [[
self.killstreakDamageModifier]](
damage, attacker, direction, point, type, tagName, modelName, partname, weapon, flags, inflictor, chargeLevel );
2560 if( weapon.isEmp && type ==
"MOD_GRENADE_SPLASH" )
2564 if ( !isdefined( emp_damage_to_apply ) )
2565 emp_damage_to_apply = ( isdefined( emp_damage ) ? emp_damage : 1 );
2567 if( isdefined( emp_callback ) && emp_damage_to_apply > 0 )
2569 self [[ emp_callback ]]( attacker );
2572 weapon_damage = emp_damage_to_apply;
2575 if (
IS_TRUE(
self.selfDestruct ) )
2577 weapon_damage =
self.maxhealth + 1;
2580 if ( !isdefined( weapon_damage ) )
2584 if ( !isdefined( weapon_damage ) )
2590 if ( weapon_damage > 0 )
2600 self.damageTaken += weapon_damage;
2602 if ( !IsSentient(
self ) && weapon_damage > 0 )
2603 self.attacker = attacker;
2605 if(
self.damageTaken >
self.maxhealth )
2607 weaponStatName =
"destroyed";
2608 switch( weapon.name )
2612 case "tow_turret_drop":
2613 weaponStatName =
"kills";
2617 level.globalKillstreaksDestroyed++;
2618 attacker AddWeaponStat( GetWeapon( killstreak_ref ),
"destroyed", 1 );
2620 if( isdefined( destroyed_callback ) )
2622 self thread [[ destroyed_callback ]]( attacker, weapon );
2628 remaining_health = ( max_health -
self.damageTaken );
2630 if( ( remaining_health < low_health ) && weapon_damage > 0 )
2632 if( isdefined( low_health_callback ) && ( !isdefined(
self.currentState ) ||
self.currentState !=
"damaged" ) )
2634 self [[ low_health_callback ]]( attacker, weapon );
2637 self.currentstate =
"damaged";
2640 if( isdefined(
self.extra_low_health ) && ( remaining_health <
self.extra_low_health ) && weapon_damage > 0 )
2642 if( isdefined(
self.extra_low_health_callback ) && ( !isdefined(
self.extra_low_damage_notified ) ) )
2644 self [[
self.extra_low_health_callback ]]( attacker, weapon );
2646 self.extra_low_damage_notified =
true;
2656 assert( isdefined(
self.maxHealth ) );
2657 assert( isdefined(
self.hackedHealth ) );
2658 assert( isdefined(
self.damageTaken ) );
2660 damageAfterHacking =
self.maxHealth -
self.hackedHealth;
2661 if (
self.damageTaken < damageAfterHacking )
2663 self.damageTaken = damageAfterHacking;
2668 attacker,
damage, flags, type, weapon,
2669 max_health, destroyed_callback,
2670 low_health, low_health_callback,
2671 emp_damage, emp_callback,
2672 allow_bullet_damage, chargeLevel )
2674 self.maxhealth = max_health;
2675 self.lowhealth = low_health;
2679 if ( isdefined( tableHealth ) )
2681 self.maxhealth = tableHealth;
2686 if ( isdefined( tableHealth ) )
2688 self.lowhealth = tableHealth;
2691 if(
IS_TRUE(
self.invulnerable ) )
2696 if( !isdefined( attacker ) || !isplayer( attacker ) )
2707 isValidAttacker =
true;
2708 if( level.teambased )
2710 isValidAttacker = ( isdefined( attacker.team ) && attacker.team !=
self.team );
2713 if( !isValidAttacker )
2718 if( weapon.isEmp && type ==
"MOD_GRENADE_SPLASH" )
2722 if ( !isdefined( emp_damage_to_apply ) )
2723 emp_damage_to_apply = ( isdefined( emp_damage ) ? emp_damage : 1 );
2725 if( isdefined( emp_callback ) && emp_damage_to_apply > 0 )
2727 self [[ emp_callback ]]( attacker, weapon );
2730 return emp_damage_to_apply;
2735 if ( !isdefined( weapon_damage ) )
2740 if ( weapon_damage <= 0 )
2745 iDamage = int( weapon_damage );
2746 if( iDamage >
self.health )
2748 if( isdefined( destroyed_callback ) )
2750 self thread [[ destroyed_callback ]]( attacker, weapon );
2761 case "MOD_RIFLE_BULLET":
2762 case "MOD_PISTOL_BULLET":
2764 if( !allow_bullet_damage )
2770 if ( isdefined( attacker ) && isplayer( attacker ) )
2772 hasFMJ = attacker HasPerk(
"specialty_armorpiercing" );
2782 case "MOD_PROJECTILE":
2783 case "MOD_EXPLOSIVE":
2784 case "MOD_PROJECTILE_SPLASH":
2785 if ( ( weapon.statIndex == level.weaponPistolEnergy.statIndex ) || ( weapon.statIndex != level.weaponShotgunEnergy.statIndex ) || ( weapon.statIndex == level.weaponSpecialCrossbow.statIndex ) )
2788 if( isdefined(
self.remoteMissileDamage ) && isdefined( weapon ) && weapon.name ==
"remote_missile_missile")
2790 damage =
self.remoteMissileDamage;
2792 else if( isdefined(
self.rocketDamage ) )
2806 function configure_team( killstreakType, killstreakId, owner, influencerType, configureTeamPreFunction, configureTeamPostFunction,
isHacked =
false )
2810 killstreak.killstreakType = killstreakType;
2811 killstreak.killstreakId = killstreakId;
2821 self endon(
"disconnect" );
2823 killstreakIndex = killstreak.killstreakID;
2824 if( isdefined( killstreakIndex ) )
2826 self.pers[
"activeKillstreaks"][ killstreakIndex ] = killstreak;
2830 self.pers[
"activeKillstreaks"][ killstreakIndex ] = undefined;
2836 return self.pers[
"activeKillstreaks"];
2844 killstreak.originalOwner = owner;
2845 killstreak.originalteam = owner.team;
2849 assert( killstreak.killstreakTeamConfigured,
"configure_team must be called before a killstreak can be hacked" );
2852 if ( isdefined( killstreak.killstreakConfigureTeamPreFunction ) )
2854 killstreak thread [[killstreak.killstreakConfigureTeamPreFunction]]( owner, ishacked );
2857 if ( isdefined( killstreak.killstreakInfluencerType ) )
2862 killstreak SetTeam( owner.team );
2863 killstreak.team = owner.team;
2864 if ( !IsAI( killstreak ) )
2866 killstreak SetOwner( owner );
2868 killstreak.owner = owner;
2869 killstreak.ownerEntnum = owner.entnum;
2873 if ( isdefined( killstreak.killstreakInfluencerType ) )
2878 if ( isdefined( killstreak.killstreakConfigureTeamPostFunction ) )
2880 killstreak thread [[killstreak.killstreakConfigureTeamPostFunction]]( owner, ishacked );
2888 killstreak.killstreakTeamConfigured =
true;
2889 killstreak.killstreakInfluencerType = influencerType;
2890 killstreak.killstreakConfigureTeamPreFunction = configureTeamPreFunction;
2891 killstreak.killstreakConfigureTeamPostFunction = configureTeamPostFunction;
2897 self notify( teamChangeNotify+
"_Singleton" );
2898 self endon ( teamChangeNotify+
"_Singleton" );
2901 killstreak endon(
"death" );
2903 killstreak endon( teamChangeNotify );
2904 killstreak.owner
util::waittill_any(
"joined_team",
"disconnect",
"joined_spectators",
"emp_jammed" );
2905 killstreak notify( teamChangeNotify );
2915 self endon(
"killstreak_hacked" );
2917 if( isdefined( endCondition1 ) )
2918 self endon( endCondition1 );
2919 if( isdefined( endCondition2 ) )
2920 self endon( endCondition2 );
2921 if( isdefined( endCondition3 ) )
2922 self endon( endCondition3 );
2924 self thread waitForTimeoutHacked( killstreak,
callback, endCondition1, endCondition2, endCondition3 );
2926 killstreakBundle = level.killstreakBundle[
self.killstreakType];
2927 self.killstreakEndTime = getTime() + duration;
2928 if ( isdefined( killstreakBundle ) && isdefined( killstreakBundle.ksTimeoutBeepDuration ) )
2937 self notify(
"kill_WaitForTimeoutHacked_thread" );
2938 self.killstreakTimedOut =
true;
2939 self.killstreakEndTime = 0;
2940 self notify(
"timed_out" );
2947 self endon(
"death");
2948 beepDuration = killstreakBundle.ksTimeoutBeepDuration * 1000;
2951 if ( IsVehicle(
self ) )
2956 if ( isdefined( killstreakBundle.ksTimeoutFastBeepDuration ) )
2958 fastBeepDuration = killstreakBundle.ksTimeoutFastBeepDuration * 1000;
2961 if ( IsVehicle(
self ) )
2969 if ( IsVehicle(
self ) )
2978 self endon(
"kill_WaitForTimeoutHacked_thread" );
2980 if( isdefined( endCondition1 ) )
2981 self endon( endCondition1 );
2982 if( isdefined( endCondition2 ) )
2983 self endon( endCondition2 );
2984 if( isdefined( endCondition3 ) )
2985 self endon( endCondition3 );
2987 self waittill(
"killstreak_hacked" );
2990 self.killstreakEndTime = getTime() + hackedDuration;
2992 self.killstreakEndTime = 0;
2993 self notify(
"timed_out" );
3001 player.threatlevel = 0;
3004 dist = distance( player.origin, heli.origin );
3005 player.threatlevel += ( ( level.heli_visual_range - dist ) / level.heli_visual_range ) * 100;
3008 if( isdefined( heli.attacker ) && player == heli.attacker )
3009 player.threatlevel += 100;
3011 if( isdefined( player.carryObject ) )
3012 player.threatlevel += 200;
3015 if( isdefined( player.score ) )
3016 player.threatlevel += player.score * 2;
3021 player.threatlevel += 1000;
3023 player.threatlevel += 500;
3027 player.threatlevel += 300;
3030 player.threatlevel += 200;
3032 if( isdefined( player.antithreat ) )
3033 player.threatlevel -= player.antithreat;
3035 if( player.threatlevel <= 0 )
3036 player.threatlevel = 1;
3043 non_player.threatlevel = 0;
3046 dist = distance( non_player.origin, heli.origin );
3047 non_player.threatlevel += ( ( level.heli_visual_range - dist ) / level.heli_visual_range ) * 100;
3049 if( non_player.threatlevel <= 0 )
3050 non_player.threatlevel = 1;
3056 actor.threatlevel = 0;
3059 dist = distance( actor.origin, heli.origin );
3060 actor.threatlevel += ( ( level.heli_visual_range - dist ) / level.heli_visual_range ) * 100;
3063 if( isdefined( actor.owner ) )
3066 if( isdefined( heli.attacker ) && actor.owner == heli.attacker )
3067 actor.threatlevel += 100;
3069 if( isdefined( actor.owner.carryObject ) )
3070 actor.threatlevel += 200;
3072 if( isdefined( actor.owner.score ) )
3073 actor.threatlevel += actor.owner.score * 4;
3075 if( isdefined( actor.owner.antithreat ) )
3076 actor.threatlevel -= actor.owner.antithreat;
3079 if( actor.threatlevel <= 0 )
3080 actor.threatlevel = 1;
3086 dog.threatlevel = 0;
3089 dist = distance( dog.origin, heli.origin );
3090 dog.threatlevel += ( ( level.heli_visual_range - dist ) / level.heli_visual_range ) * 100;
3096 heli2target_normal = vectornormalize( missiletarget.origin -
self.origin );
3097 heli2forward = anglestoforward(
self.angles );
3098 heli2forward_normal = vectornormalize( heli2forward );
3100 heli_dot_target = vectordot( heli2target_normal, heli2forward_normal );
3102 if ( heli_dot_target >= level.heli_valid_target_cone )
3111 player.missilethreatlevel = 0;
3114 dist = distance( player.origin,
self.origin );
3115 player.missilethreatlevel += ( (level.heli_missile_range - dist)/level.heli_missile_range )*100;
3120 player.missilethreatlevel = 1;
3125 if ( isdefined(
self.attacker ) && player ==
self.attacker )
3126 player.missilethreatlevel += 100;
3129 player.missilethreatlevel += player.score*4;
3131 if( isdefined( player.antithreat ) )
3132 player.missilethreatlevel -= player.antithreat;
3134 if( player.missilethreatlevel <= 0 )
3135 player.missilethreatlevel = 1;
3141 dog.missilethreatlevel = 1;
3146 victim RecordKillstreakAssist(victim, assister, killstreak);
3153 if ( !level.hardcoreMode && !testing )
3156 if ( !isdefined( ricochet_distance ) || ricochet_distance == 0 )
3159 DEFAULT( owner.ricochet_protection, [] );
3161 owner.ricochet_protection[ killstreak_id ] = SpawnStruct();
3162 owner.ricochet_protection[ killstreak_id ].origin = origin;
3163 owner.ricochet_protection[ killstreak_id ].distanceSq =
SQR( ricochet_distance );
3168 if ( !isdefined( owner ) || !isdefined( owner.ricochet_protection ) || !isdefined( killstreak_id ) )
3171 if ( !isdefined( owner.ricochet_protection[ killstreak_id ] ) )
3174 owner.ricochet_protection[ killstreak_id ].endTime = endTime;
3179 if ( !isdefined( owner ) || !isdefined( owner.ricochet_protection ) || !isdefined( killstreak_id ) )
3182 owner.ricochet_protection[ killstreak_id ] = undefined;
3187 if ( !isdefined( player ) || !isdefined( player.ricochet_protection ) )
3190 foreach( protection
in player.ricochet_protection )
3192 if ( !isdefined( protection ) )
3195 if ( isdefined( protection.endTime ) && protection.endTime < GetTime() )
3198 if ( DistanceSquared( protection.origin, player.origin ) < protection.distanceSq )
3207 return ( isdefined(
self.dart_thrown_time ) && ( GetTime() -
self.dart_thrown_time < 1500 ) );