1 #using scripts\codescripts\struct;
2 #using scripts\shared\abilities\_ability_power;
3 #using scripts\shared\callbacks_shared;
4 #using scripts\shared\challenges_shared;
5 #using scripts\shared\demo_shared;
6 #using scripts\shared\flag_shared;
7 #using scripts\shared\flagsys_shared;
8 #using scripts\shared\hud_message_shared;
9 #using scripts\shared\hud_util_shared;
10 #using scripts\shared\math_shared;
11 #using scripts\shared\tweakables_shared;
12 #using scripts\shared\util_shared;
13 #using scripts\shared\weapons_shared;
14 #using scripts\shared\weapons\_weapon_utils;
16 #insert scripts\shared\shared.gsh;
18 #using scripts\zm\gametypes\_damagefeedback;
19 #using scripts\zm\gametypes\_globallogic;
20 #using scripts\zm\gametypes\_globallogic_audio;
21 #using scripts\zm\gametypes\_globallogic_score;
22 #using scripts\zm\gametypes\_globallogic_spawn;
23 #using scripts\zm\gametypes\_globallogic_ui;
24 #using scripts\zm\gametypes\_globallogic_utils;
25 #using scripts\zm\gametypes\_hostmigration;
26 #using scripts\zm\gametypes\_spawning;
27 #using scripts\zm\gametypes\_spawnlogic;
28 #using scripts\zm\gametypes\_spectating;
29 #using scripts\zm\gametypes\_weapons;
31 #using scripts\zm\_challenges;
32 #using scripts\zm\_util;
33 #using scripts\zm\_zm_stats;
35 #namespace globallogic_player;
41 self closeInGameMenu();
50 self.statusicon =
"hud_status_connecting";
51 self waittill(
"begin" );
53 if( isdefined( level.reset_clientdvars ) )
54 self [[level.reset_clientdvars]]();
59 self.guid =
self getGuid();
61 profilelog_begintiming( 4,
"ship" );
63 level notify(
"connected",
self );
69 if( !level.splitscreen && !isdefined(
self.pers[
"score"] ) )
71 iPrintLn(&
"MP_CONNECTED",
self);
74 if( !isdefined(
self.pers[
"score"] ) )
85 if ( !isdefined(
self.pers[
"matchesHostedStatsTracked"] ) &&
self IsLocalToHost() )
88 self.pers[
"matchesHostedStatsTracked"] =
true;
91 self.pers[
"matchesPlayedStatsTracked"] =
true;
97 lpselfnum =
self getEntityNumber();
98 lpGuid =
self getGuid();
99 lpXuid =
self getXuid(
true);
100 logPrint(
"J;" + lpGuid +
";" + lpselfnum +
";" +
self.
name +
"\n");
101 bbPrint(
"global_joins",
"name %s client %s xuid %s",
self.
name, lpselfnum, lpXuid );
103 if( !SessionModeIsZombiesGame() )
105 self setClientUIVisibilityFlag(
"hud_visible", 1 );
106 self setClientUIVisibilityFlag(
"weapon_hud_visible", 1 );
109 if ( level.forceRadar == 1 )
111 self.pers[
"hasRadar"] =
true;
112 self.hasSpyplane =
true;
113 level.activeUAVs[
self getEntityNumber()] = 1;
116 if ( level.forceRadar == 2 )
118 self setClientUIVisibilityFlag(
"g_compassShowEnemies", level.forceRadar );
122 self SetClientUIVisibilityFlag(
"g_compassShowEnemies", 0 );
125 self SetClientPlayerSprintTime( level.playerSprintTime );
126 self SetClientNumLives( level.numLives );
130 if ( level.hardcoreMode )
132 self SetClientDrawTalk( 3 );
135 self [[level.player_stats_init]]();
137 self.killedPlayersCurrent = [];
139 if( !isdefined(
self.pers[
"best_kill_streak"] ) )
141 self.pers[
"killed_players"] = [];
142 self.pers[
"killed_by"] = [];
143 self.pers[
"nemesis_tracking"] = [];
144 self.pers[
"artillery_kills"] = 0;
145 self.pers[
"dog_kills"] = 0;
146 self.pers[
"nemesis_name"] =
"";
147 self.pers[
"nemesis_rank"] = 0;
148 self.pers[
"nemesis_rankIcon"] = 0;
149 self.pers[
"nemesis_xp"] = 0;
150 self.pers[
"nemesis_xuid"] =
"";
158 self.pers[
"best_kill_streak"] = 0;
162 if( !isdefined(
self.pers[
"music"] ) )
164 self.pers[
"music"] = spawnstruct();
165 self.pers[
"music"].spawn =
false;
166 self.pers[
"music"].inque =
false;
167 self.pers[
"music"].currentState =
"SILENT";
168 self.pers[
"music"].previousState =
"SILENT";
169 self.pers[
"music"].nextstate =
"UNDERSCORE";
170 self.pers[
"music"].returnState =
"UNDERSCORE";
173 self.leaderDialogQueue = [];
174 self.leaderDialogActive =
false;
175 self.leaderDialogGroups = [];
176 self.currentLeaderDialogGroup =
"";
177 self.currentLeaderDialog =
"";
178 self.currentLeaderDialogTime = 0;
180 if ( !isdefined(
self.pers[
"cur_kill_streak"] ) )
182 self.pers[
"cur_kill_streak"] = 0;
185 if ( !isdefined(
self.pers[
"cur_total_kill_streak"] ) )
187 self.pers[
"cur_total_kill_streak"] = 0;
188 self setplayercurrentstreak( 0 );
191 if ( !isdefined(
self.pers[
"totalKillstreakCount"] ) )
192 self.pers[
"totalKillstreakCount"] = 0;
195 if ( !isdefined(
self.pers[
"killstreaksEarnedThisKillstreak"] ) )
196 self.pers[
"killstreaksEarnedThisKillstreak"] = 0;
198 if ( isdefined( level.usingScoreStreaks ) && level.usingScoreStreaks && !isdefined(
self.pers[
"killstreak_quantity"] ) )
199 self.pers[
"killstreak_quantity"] = [];
201 if ( isdefined( level.usingScoreStreaks ) && level.usingScoreStreaks && !isdefined(
self.pers[
"held_killstreak_ammo_count"] ) )
202 self.pers[
"held_killstreak_ammo_count"] = [];
204 self.lastKillTime = 0;
206 self.cur_death_streak = 0;
207 self disabledeathstreak();
208 self.death_streak = 0;
209 self.kill_streak = 0;
210 self.gametype_kill_streak = 0;
211 self.spawnQueueIndex = -1;
221 self.lastGrenadeSuicideTime = -1;
223 self.teamkillsThisRound = 0;
225 if ( !isdefined( level.livesDoNotReset ) || !level.livesDoNotReset || !isdefined(
self.pers[
"lives"] ) )
226 self.pers[
"lives"] = level.numLives;
229 if ( !level.teamBased )
231 self.pers[
"team"] = undefined;
234 self.hasSpawned =
false;
235 self.waitingToSpawn =
false;
236 self.wantSafeSpawn =
false;
239 self.wasAliveAtMatchStart =
false;
241 level.players[level.players.size] =
self;
243 if( level.splitscreen )
244 SetDvar(
"splitscreen_playerNum", level.players.size );
248 if ( game[
"state"] ==
"postgame" )
250 self.pers[
"needteam"] = 1;
251 self.pers[
"team"] =
"spectator";
252 self.team =
"spectator";
253 self.sessionteam =
"spectator";
254 self setClientUIVisibilityFlag(
"hud_visible", 0 );
256 self [[level.spawnIntermission]]();
257 self closeInGameMenu();
258 profilelog_endtiming( 4,
"gs=" + game[
"state"] +
" zom=" + SessionModeIsZombiesGame() );
262 level endon(
"game_ended" );
264 if ( isdefined( level.hostMigrationTimer ) )
267 if ( level.oldschool )
269 self.pers[
"class"] = undefined;
270 self.curClass =
self.pers[
"class"];
273 if ( isdefined(
self.pers[
"team"] ) )
274 self.team =
self.pers[
"team"];
276 if ( isdefined(
self.pers[
"class"] ) )
277 self.curClass =
self.pers[
"class"];
279 if ( !isdefined(
self.pers[
"team"] ) || isdefined(
self.pers[
"needteam"] ) )
283 self.pers[
"needteam"] = undefined;
284 self.pers[
"team"] =
"spectator";
285 self.team =
"spectator";
286 self.sessionstate =
"dead";
290 [[level.spawnSpectator]]();
292 if ( level.rankedMatch )
294 [[level.autoassign]]( false );
301 [[level.autoassign]]( false );
304 if (
self.pers[
"team"] ==
"spectator" )
306 self.sessionteam =
"spectator";
310 if ( level.teamBased )
313 self.sessionteam =
self.pers[
"team"];
314 if ( !isAlive(
self ) )
315 self.statusicon =
"hud_status_dead";
319 else if (
self.pers[
"team"] ==
"spectator" )
321 self SetClientScriptMainMenu( game[
"menu_start_menu" ] );
322 [[level.spawnSpectator]]();
323 self.sessionteam =
"spectator";
324 self.sessionstate =
"spectator";
329 self.sessionteam =
self.pers[
"team"];
330 self.sessionstate =
"dead";
334 [[level.spawnSpectator]]();
338 self thread [[level.spawnClient]]();
348 if (
self.sessionteam !=
"spectator" )
353 profilelog_endtiming( 4,
"gs=" + game[
"state"] +
" zom=" + SessionModeIsZombiesGame() );
358 self endon(
"disconnect" );
360 self.watchingActiveClient =
true;
361 self.waitingForPlayersText = undefined;
365 if (
self.pers[
"team"] !=
"spectator" || level.gameEnded )
368 self FreezeControls(
false );
369 self.watchingActiveClient =
false;
377 if ( !level.splitscreen && !level.hardcoreMode && GetDvarint(
"scr_showperksonspawn" ) == 1 && game[
"state"] !=
"postgame" && !isdefined(
self.perkHudelem ) )
379 if ( level.perksEnabled == 1 )
386 for ( i = 0; i < level.players.size; i++ )
388 if ( level.players[i].team !=
"spectator" )
397 if ( !
self.watchingActiveClient )
400 self FreezeControls(
false );
405 self.watchingActiveClient =
true;
409 if (
self.watchingActiveClient )
411 [[level.onSpawnSpectator]]();
412 self FreezeControls(
true );
416 self.watchingActiveClient =
false;
428 if ( isdefined(
self.connected ) &&
self.connected )
440 level.hostMigrationReturnedPlayerCount++;
441 if ( level.hostMigrationReturnedPlayerCount >= level.players.size * 2 / 3 )
444 level notify(
"hostmigration_enoughplayers" );
450 self endon(
"disconnect");
459 for (i=0; i < inputArray.size; i++)
461 targetString += inputArray[i];
462 if (i != inputArray.size-1)
474 profilelog_begintiming( 5,
"ship" );
476 if ( game[
"state"] !=
"postgame" && !level.gameEnded )
482 ArrayRemoveValue( level.players,
self );
484 if ( level.splitscreen )
486 players = level.players;
488 if ( players.size <= 1 )
492 SetDvar(
"splitscreen_playerNum", players.size );
495 if ( isdefined(
self.score ) && isdefined(
self.pers[
"team"] ) )
501 [[level.onPlayerDisconnect]]();
503 lpselfnum =
self getEntityNumber();
504 lpGuid =
self getGuid();
505 logPrint(
"Q;" + lpGuid +
";" + lpselfnum +
";" +
self.
name +
"\n");
511 for ( entry = 0; entry < level.players.size; entry++ )
513 if ( level.players[entry] ==
self )
515 while ( entry < level.players.size-1 )
517 level.players[entry] = level.players[entry+1];
520 level.players[entry] = undefined;
524 for ( entry = 0; entry < level.players.size; entry++ )
526 if ( isdefined( level.players[entry].pers[
"killed_players"][
self.name] ) )
527 level.players[entry].pers[
"killed_players"][
self.name] = undefined;
529 if ( isdefined( level.players[entry].killedPlayersCurrent[
self.name] ) )
530 level.players[entry].killedPlayersCurrent[
self.name] = undefined;
532 if ( isdefined( level.players[entry].pers[
"killed_by"][
self.name] ) )
533 level.players[entry].pers[
"killed_by"][
self.name] = undefined;
535 if ( isdefined( level.players[entry].pers[
"nemesis_tracking"][
self.name] ) )
536 level.players[entry].pers[
"nemesis_tracking"][
self.name] = undefined;
539 if ( level.players[entry].pers[
"nemesis_name"] ==
self.name )
545 if ( level.gameEnded )
550 profilelog_endtiming( 5,
"gs=" + game[
"state"] +
" zom=" + SessionModeIsZombiesGame() );
557 if ( level.teamBased &&
self.team == eAttacker.team )
559 if ( level.friendlyfire == 0 )
565 self finishMeleeHit( eAttacker, weapon, vOrigin, vDir, boneIndex, shieldHit, hit, fromBehind );
570 nemesisArray =
self.pers[
"nemesis_tracking"];
571 nemesisArrayKeys = getArrayKeys( nemesisArray );
575 if ( nemesisArrayKeys.size > 0 )
577 for ( i = 0; i < nemesisArrayKeys.size; i++ )
579 nemesisArrayKey = nemesisArrayKeys[i];
580 if ( nemesisArray[nemesisArrayKey] > nemesisAmount )
582 nemesisName = nemesisArrayKey;
583 nemesisAmount = nemesisArray[nemesisArrayKey];
589 self.pers[
"nemesis_name"] = nemesisName;
591 if ( nemesisName !=
"" )
594 for( ; playerIndex < level.players.size; playerIndex++ )
596 if ( level.players[playerIndex].name == nemesisName )
598 nemesisPlayer = level.players[playerIndex];
599 self.pers[
"nemesis_rank"] = nemesisPlayer.pers[
"rank"];
600 self.pers[
"nemesis_rankIcon"] = nemesisPlayer.pers[
"rankxp"];
601 self.pers[
"nemesis_xp"] = nemesisPlayer.pers[
"prestige"];
602 self.pers[
"nemesis_xuid"] = nemesisPlayer GetXUID();
609 self.pers[
"nemesis_xuid"] =
"";
616 if ( level.onlinegame && !SessionModeIsPrivate() )
621 if( isdefined( eAttacker) && isdefined( eAttacker.damageModifier ) )
623 iDamage *= eAttacker.damageModifier;
625 if ( ( sMeansOfDeath ==
"MOD_PISTOL_BULLET" ) || ( sMeansOfDeath ==
"MOD_RIFLE_BULLET" ) )
627 iDamage = int( iDamage * level.bulletDamageScalar );
635 if ( isdefined(eAttacker) )
637 if( isai(eAttacker) && isdefined( eAttacker.script_owner ) )
641 if ( eAttacker.script_owner.team != team )
642 eAttacker = eAttacker.script_owner;
645 if( eAttacker.classname ==
"script_vehicle" && isdefined( eAttacker.owner ) )
646 eAttacker = eAttacker.owner;
647 else if( eAttacker.classname ==
"auto_turret" && isdefined( eAttacker.owner ) )
648 eAttacker = eAttacker.owner;
657 if ( weapon == level.weaponNone && isdefined( eInflictor ) )
659 if ( isdefined( eInflictor.targetname ) && eInflictor.targetname ==
"explodable_barrel" )
661 weapon = GetWeapon(
"explodable_barrel" );
663 else if ( isdefined( eInflictor.destructible_type ) && isSubStr( eInflictor.destructible_type,
"vehicle_" ) )
665 weapon = GetWeapon(
"destructible_car" );
674 return level.friendlyfire;
679 if ( level.hardcoreMode )
682 if ( !isdefined( eAttacker ) )
685 if (
self != eAttacker )
688 return weapon.doNotDamageOwner;
691 function Callback_PlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex )
693 profilelog_begintiming( 6,
"ship" );
695 if ( game[
"state"] ==
"postgame" )
698 if (
self.sessionteam ==
"spectator" )
701 if ( isdefined(
self.canDoCombat ) && !
self.canDoCombat )
704 if ( isdefined( eAttacker ) && isPlayer( eAttacker ) && isdefined( eAttacker.canDoCombat ) && !eAttacker.canDoCombat )
707 if ( isdefined( level.hostMigrationTimer ) )
710 if (
self.scene_takedamage ===
false )
715 weaponName = weapon.name;
716 if ( ( weaponName ==
"ai_tank_drone_gun" || weaponName ==
"ai_tank_drone_rocket" ) && !level.hardcoreMode )
719 if ( isdefined( eAttacker ) && eAttacker ==
self )
721 if ( isdefined( eInflictor ) && isdefined( eInflictor.from_ai ) )
728 if ( isdefined( eAttacker ) && isdefined( eAttacker.owner ) && eAttacker.owner ==
self )
736 self notify(
"emp_grenaded", eAttacker );
745 iDamage = int(iDamage);
746 self.iDFlags = iDFlags;
747 self.iDFlagsTime = getTime();
751 pixbeginevent(
"PlayerDamage flags/tweaks" );
754 if( !isdefined( vDir ) )
755 iDFlags |= level.iDFLAGS_NO_KNOCKBACK;
762 if (
self.health !=
self.maxhealth )
764 self notify(
"snd_pain_player", sMeansOfDeath );
767 if ( isdefined( eInflictor) && isdefined( eInflictor.script_noteworthy) && eInflictor.script_noteworthy ==
"ragdoll_now" )
769 sMeansOfDeath =
"MOD_FALLING";
779 sMeansOfDeath =
"MOD_HEAD_SHOT";
784 modifiedDamage = [[level.onPlayerDamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime );
786 if ( isdefined( modifiedDamage ) )
788 if ( modifiedDamage <= 0 )
791 iDamage = modifiedDamage;
795 if ( level.onlyHeadShots )
797 if ( sMeansOfDeath ==
"MOD_PISTOL_BULLET" || sMeansOfDeath ==
"MOD_RIFLE_BULLET" )
799 else if ( sMeansOfDeath ==
"MOD_HEAD_SHOT" )
807 if (isdefined (eAttacker) && isPlayer(eAttacker) && (
self.team != eAttacker.team))
809 self.lastAttackWeapon = weapon;
819 attackerIsHittingTeammate = isPlayer( eAttacker ) && (
self util::IsEnemyPlayer( eAttacker ) == false );
821 if ( sHitLoc ==
"riotshield" )
823 if ( attackerIsHittingTeammate && level.friendlyfire == 0 )
828 if ( sMeansOfDeath ==
"MOD_PISTOL_BULLET" || sMeansOfDeath ==
"MOD_RIFLE_BULLET" && !attackerIsHittingTeammate )
830 previous_shield_damage =
self.shieldDamageBlocked;
831 self.shieldDamageBlocked += iDamage;
833 if ( isPlayer( eAttacker ))
835 eAttacker.lastAttackedShieldPlayer =
self;
836 eAttacker.lastAttackedShieldTime = getTime();
840 if ( iDFlags & level.iDFLAGS_SHIELD_EXPLOSIVE_IMPACT )
843 if ( !(iDFlags & level.iDFLAGS_SHIELD_EXPLOSIVE_IMPACT_HUGE) )
848 else if ( iDFlags & level.iDFLAGS_SHIELD_EXPLOSIVE_SPLASH )
850 if ( isdefined( eInflictor ) && isdefined( eInflictor.stuckToPlayer ) && eInflictor.stuckToPlayer ==
self )
1086 if ( isdefined( eAttacker ) && eAttacker !=
self && !friendly )
1087 level.useStartSpawns =
false;
1089 pixbeginevent(
"PlayerDamage log" );
1091 if(
self.sessionstate !=
"dead")
1093 lpselfnum =
self getEntityNumber();
1094 lpselfname =
self.name;
1095 lpselfteam =
self.team;
1096 lpselfGuid =
self getGuid();
1097 lpattackerteam =
"";
1098 lpattackerorigin = ( 0, 0, 0 );
1100 if(isPlayer(eAttacker))
1102 lpattacknum = eAttacker getEntityNumber();
1103 lpattackGuid = eAttacker getGuid();
1104 lpattackname = eAttacker.name;
1105 lpattackerteam = eAttacker.team;
1106 lpattackerorigin = eAttacker.origin;
1115 lpattackerteam =
"world";
1119 logPrint(
"D;" + lpselfGuid +
";" + lpselfnum +
";" + lpselfteam +
";" + lpselfname +
";" + lpattackGuid +
";" + lpattacknum +
";" + lpattackerteam +
";" + lpattackname +
";" + weapon.name +
";" + iDamage +
";" + sMeansOfDeath +
";" + sHitLoc +
"\n");
1124 profilelog_endtiming( 6,
"gs=" + game[
"state"] +
" zom=" + SessionModeIsZombiesGame() );
1129 self.attackers = [];
1130 self.attackerData = [];
1131 self.attackerDamage = [];
1132 self.firstTimeDamaged = 0;
1137 if ( !isdefined( weapon ) )
1140 if ( level.allowHitMarkers == 0 )
1143 if ( level.allowHitMarkers == 1 )
1145 if ( isdefined( sMeansOfDeath ) && isdefined( iDamage ) )
1162 if (
"Smoke Grenade" == weapon.offhandClass )
1164 if ( sMeansOfDeath ==
"MOD_GRENADE_SPLASH" )
1167 else if ( iDamage == 1 )
1177 perkFeedback = undefined;
1192 return perkFeedback;
1197 if ( weapon.isAIKillstreakDamage )
1199 if ( weapon.name !=
"ai_tank_drone_rocket" || isdefined( eInflictor.firedByAI ) )
1208 function finishPlayerDamageWrapper( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal )
1210 pixbeginevent(
"finishPlayerDamageWrapper");
1212 if( !level.console && iDFlags & level.iDFLAGS_PENETRATION && isplayer ( eAttacker ) )
1214 eAttacker AddPlayerStat(
"penetration_shots", 1 );
1217 if ( GetDvarString(
"scr_csmode" ) !=
"" )
1218 self shellShock(
"damage", 0.2 );
1224 self finishPlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal );
1240 function Callback_PlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration)
1242 profilelog_begintiming( 7,
"ship" );
1244 self endon(
"spawned" );
1245 self notify(
"killed_player" );
1249 if (
self.sessionteam ==
"spectator" )
1252 if ( game[
"state"] ==
"postgame" )
1255 self needsRevive(
false );
1257 if ( isdefined(
self.burning ) &&
self.burning ==
true )
1262 self.suicide =
false;
1264 if ( isdefined( level.takeLivesOnDeath ) && ( level.takeLivesOnDeath ==
true ) )
1266 if (
self.pers[
"lives"] )
1268 self.pers[
"lives"]--;
1269 if (
self.pers[
"lives"] == 0 )
1271 level notify(
"player_eliminated" );
1272 self notify(
"player_eliminated" );
1282 pixbeginevent(
"PlayerKilled pre constants" );
1284 wasInLastStand =
false;
1285 deathTimeOffset = 0;
1286 lastWeaponBeforeDroppingIntoLastStand = undefined;
1287 attackerStance = undefined;
1288 self.lastStandThisLife = undefined;
1289 self.vAttackerOrigin = undefined;
1291 if ( isdefined(
self.useLastStandParams ) )
1293 self.useLastStandParams = undefined;
1295 assert( isdefined(
self.lastStandParams ) );
1296 if ( !level.teamBased || ( !isdefined( attacker ) || !isplayer( attacker ) || attacker.team !=
self.team || attacker ==
self ) )
1298 eInflictor =
self.lastStandParams.eInflictor;
1299 attacker =
self.lastStandParams.attacker;
1300 attackerStance =
self.lastStandParams.attackerStance;
1301 iDamage =
self.lastStandParams.iDamage;
1302 sMeansOfDeath =
self.lastStandParams.sMeansOfDeath;
1303 weapon =
self.lastStandParams.weapon;
1304 vDir =
self.lastStandParams.vDir;
1305 sHitLoc =
self.lastStandParams.sHitLoc;
1306 self.vAttackerOrigin =
self.lastStandParams.vAttackerOrigin;
1307 deathTimeOffset = (gettime() -
self.lastStandParams.lastStandStartTime) / 1000;
1311 if ( isdefined(
self.previousPrimary ) )
1313 wasInLastStand =
true;
1314 lastWeaponBeforeDroppingIntoLastStand =
self.previousPrimary;
1317 self.lastStandParams = undefined;
1320 bestPlayer = undefined;
1321 bestPlayerMeansOfDeath = undefined;
1322 obituaryMeansOfDeath = undefined;
1323 bestPlayerWeapon = undefined;
1324 obituaryWeapon = undefined;
1326 if ( (!isdefined( attacker ) || attacker.classname ==
"trigger_hurt" || attacker.classname ==
"worldspawn" || ( isdefined( attacker.isMagicBullet ) && attacker.isMagicBullet ==
true ) || attacker ==
self ) && isdefined(
self.attackers ) )
1328 if ( !isdefined(bestPlayer) )
1330 for ( i = 0; i <
self.attackers.size; i++ )
1332 player =
self.attackers[i];
1333 if ( !isdefined( player ) )
1336 if (!isdefined(
self.attackerDamage[ player.clientId ] ) || ! isdefined(
self.attackerDamage[ player.clientId ].damage ) )
1339 if ( player ==
self || (level.teamBased && player.team ==
self.team ) )
1342 if (
self.attackerDamage[ player.clientId ].lasttimedamaged + 2500 < getTime() )
1348 if (
self.attackerDamage[ player.clientId ].damage > 1 && ! isdefined( bestPlayer ) )
1350 bestPlayer = player;
1351 bestPlayerMeansOfDeath =
self.attackerDamage[ player.clientId ].meansOfDeath;
1352 bestPlayerWeapon =
self.attackerDamage[ player.clientId ].weapon;
1354 else if ( isdefined( bestPlayer ) &&
self.attackerDamage[ player.clientId ].damage >
self.attackerDamage[ bestPlayer.clientId ].damage )
1356 bestPlayer = player;
1357 bestPlayerMeansOfDeath =
self.attackerDamage[ player.clientId ].meansOfDeath;
1358 bestPlayerWeapon =
self.attackerDamage[ player.clientId ].weapon;
1362 if ( isdefined ( bestPlayer ) )
1364 self RecordKillModifier(
"assistedsuicide");
1368 if ( isdefined ( bestPlayer ) )
1370 attacker = bestPlayer;
1371 obituaryMeansOfDeath = bestPlayerMeansOfDeath;
1372 obituaryWeapon = bestPlayerWeapon;
1375 if ( isplayer( attacker ) )
1376 attacker.damagedPlayers[
self.clientid] = undefined;
1380 attacker playLocalSound(
"prj_bullet_impact_headshot_helmet_nodie_2d" );
1383 sMeansOfDeath =
"MOD_HEAD_SHOT";
1386 self.deathTime = getTime();
1393 if ( isdefined(
self.hasRiotShieldEquipped) && (
self.hasRiotShieldEquipped==
true) )
1395 self DetachShieldModel( level.carriedShieldModel,
"tag_weapon_left" );
1396 self.hasRiotShield =
false;
1397 self.hasRiotShieldEquipped =
false;
1403 if ( isPlayer( attacker ) && attacker !=
self && ( !level.teamBased || ( level.teamBased &&
self.team != attacker.team ) ) )
1405 self AddWeaponStat( weapon,
"deaths", 1 );
1407 if ( wasInLastStand && isdefined( lastWeaponBeforeDroppingIntoLastStand ) )
1408 weapon = lastWeaponBeforeDroppingIntoLastStand;
1410 weapon =
self.lastdroppableweapon;
1412 if ( isdefined( weapon ) )
1414 self AddWeaponStat( weapon,
"deathsDuringUse", 1 );
1417 if ( sMeansOfDeath !=
"MOD_FALLING" )
1419 attacker AddWeaponStat( weapon,
"kills", 1 );
1422 if ( sMeansOfDeath ==
"MOD_HEAD_SHOT" )
1424 attacker AddWeaponStat( weapon,
"headshots", 1 );
1428 if ( !isdefined( obituaryMeansOfDeath ) )
1429 obituaryMeansOfDeath = sMeansOfDeath;
1430 if ( !isdefined( obituaryWeapon ) )
1431 obituaryWeapon = weapon;
1436 level notify(
"reset_obituary_count" );
1437 level.lastObituaryPlayerCount = 0;
1438 level.lastObituaryPlayer = undefined;
1442 if ( isdefined( level.lastObituaryPlayer ) && level.lastObituaryPlayer == attacker )
1444 level.lastObituaryPlayerCount++;
1448 level notify(
"reset_obituary_count" );
1449 level.lastObituaryPlayer = attacker;
1450 level.lastObituaryPlayerCount = 1;
1453 if ( level.lastObituaryPlayerCount >= 4 )
1455 level notify(
"reset_obituary_count" );
1456 level.lastObituaryPlayerCount = 0;
1457 level.lastObituaryPlayer = undefined;
1461 overrideEntityCamera =
false;
1464 if( level.teamBased && isdefined( attacker.pers ) &&
self.team == attacker.team && obituaryMeansOfDeath ==
"MOD_GRENADE" && level.friendlyfire == 0 )
1466 obituary(
self,
self, obituaryWeapon, obituaryMeansOfDeath);
1467 demo::bookmark(
"kill", gettime(),
self,
self, 0, eInflictor, overrideEntityCamera );
1471 obituary(
self, attacker, obituaryWeapon, obituaryMeansOfDeath);
1472 demo::bookmark(
"kill", gettime(), attacker,
self, 0, eInflictor, overrideEntityCamera );
1475 if ( !level.inGracePeriod )
1483 self.sessionstate =
"dead";
1484 self.statusicon =
"hud_status_dead";
1486 self.pers[
"weapon"] = undefined;
1488 self.killedPlayersCurrent = [];
1492 if( !isdefined(
self.switching_teams ) )
1495 if ( isPlayer( attacker ) && level.teamBased && ( attacker !=
self ) && (
self.team == attacker.team ) )
1498 self.pers[
"cur_kill_streak"] = 0;
1499 self.pers[
"cur_total_kill_streak"] = 0;
1500 self.pers[
"totalKillstreakCount"] = 0;
1501 self.pers[
"killstreaksEarnedThisKillstreak"] = 0;
1502 self setplayercurrentstreak( 0 );
1508 self UpdateStatRatio(
"kdratio",
"kills",
"deaths" );
1510 if(
self.pers[
"cur_kill_streak"] >
self.pers[
"best_kill_streak"] )
1511 self.pers[
"best_kill_streak"] =
self.pers[
"cur_kill_streak"];
1514 self.pers[
"kill_streak_before_death"] =
self.pers[
"cur_kill_streak"];
1517 self.pers[
"cur_kill_streak"] = 0;
1518 self.pers[
"cur_total_kill_streak"] = 0;
1519 self.pers[
"totalKillstreakCount"] = 0;
1520 self.pers[
"killstreaksEarnedThisKillstreak"] = 0;
1521 self setplayercurrentstreak( 0 );
1523 self.cur_death_streak++;
1525 if (
self.cur_death_streak >
self.death_streak )
1527 if ( level.rankedMatch )
1529 self setDStat(
"HighestStats",
"death_streak",
self.cur_death_streak );
1531 self.death_streak =
self.cur_death_streak;
1534 if(
self.cur_death_streak >= GetDvarint(
"perk_deathStreakCountRequired" ) )
1536 self enabledeathstreak();
1542 self.pers[
"totalKillstreakCount"] = 0;
1543 self.pers[
"killstreaksEarnedThisKillstreak"] = 0;
1546 lpselfnum =
self getEntityNumber();
1547 lpselfname =
self.name;
1550 lpselfteam =
self.team;
1551 lpselfguid =
self getGuid();
1553 lpattackorigin = ( 0, 0, 0 );
1558 awardAssists =
false;
1564 if( isPlayer( attacker ) )
1566 lpattackGuid = attacker getGuid();
1567 lpattackname = attacker.name;
1568 lpattackteam = attacker.team;
1569 lpattackorigin = attacker.origin;
1571 if ( attacker ==
self )
1599 if ( sMeansOfDeath ==
"MOD_SUICIDE" && sHitLoc ==
"none" &&
self.throwingGrenade )
1601 self.lastGrenadeSuicideTime = gettime();
1608 awardAssists =
true;
1609 self.suicide =
true;
1612 if( isdefined(
self.friendlydamage ) )
1614 self iPrintLn(&
"MP_FRIENDLY_FIRE_WILL_NOT");
1615 if ( level.teamKillPointLoss )
1617 scoreSub =
self [[level.getTeamKillScore]]( eInflictor, attacker, sMeansOfDeath, weapon);
1624 pixbeginevent(
"PlayerKilled attacker" );
1626 lpattacknum = attacker getEntityNumber();
1632 if ( level.teamBased &&
self.team == attacker.team && sMeansOfDeath ==
"MOD_GRENADE" && level.friendlyfire == 0 )
1635 else if ( level.teamBased &&
self.team == attacker.team )
1639 teamkill_penalty =
self [[level.getTeamKillPenalty]]( eInflictor, attacker, sMeansOfDeath, weapon);
1643 attacker.teamkillsThisRound++;
1645 if ( level.teamKillPointLoss )
1647 scoreSub =
self [[level.getTeamKillScore]]( eInflictor, attacker, sMeansOfDeath, weapon);
1658 if ( teamKillDelay > 0 )
1660 attacker.teamKillPunish =
true;
1682 if ( isAlive( attacker ) )
1684 pixbeginevent(
"killstreak");
1686 if ( !isdefined( eInflictor ) || !isdefined( eInflictor.requiredDeathCount ) || attacker.deathCount == eInflictor.requiredDeathCount )
1688 shouldGiveKillstreak =
false;
1696 attacker.pers[
"cur_total_kill_streak"]++;
1697 attacker setplayercurrentstreak( attacker.pers[
"cur_total_kill_streak"] );
1700 if ( isdefined( level.killstreaks ) && shouldGiveKillstreak )
1702 attacker.pers[
"cur_kill_streak"]++;
1717 if ( attacker.pers[
"cur_kill_streak"] > attacker.kill_streak )
1719 if ( level.rankedMatch )
1721 attacker setDStat(
"HighestStats",
"kill_streak", attacker.pers[
"totalKillstreakCount"] );
1723 attacker.kill_streak = attacker.pers[
"cur_kill_streak"];
1732 killstreak = undefined;
1736 attackerName = attacker.name;
1743 if ( level.teamBased && attacker.team !=
"spectator")
1746 if( isai(Attacker) )
1752 scoreSub = level.deathPointLoss;
1753 if ( scoreSub != 0 )
1760 if ( level.teamBased )
1763 awardAssists =
true;
1770 else if ( isdefined( attacker ) && ( attacker.classname ==
"trigger_hurt" || attacker.classname ==
"worldspawn" ) )
1777 lpattackteam =
"world";
1786 awardAssists =
true;
1796 lpattackteam =
"world";
1798 if ( isdefined( eInflictor ) && isdefined( eInflictor.killCamEnt ) )
1801 lpattacknum =
self getEntityNumber();
1805 if ( isdefined( attacker ) && isdefined( attacker.team ) && ( isdefined( level.teams[attacker.team] ) ) )
1807 if ( attacker.team !=
self.team )
1809 if ( level.teamBased )
1814 awardAssists =
true;
1818 pixbeginevent(
"PlayerKilled post constants" );
1820 self.lastAttacker = attacker;
1821 self.lastDeathPos =
self.origin;
1823 if ( isdefined( attacker ) && isPlayer( attacker ) && attacker !=
self && (!level.teambased || attacker.team !=
self.team) )
1829 self notify(
"playerKilledChallengesProcessed");
1832 if ( isdefined (
self.attackers ))
1833 self.attackers = [];
1834 if( isPlayer( attacker ) )
1843 logPrint(
"K;" + lpselfguid +
";" + lpselfnum +
";" + lpselfteam +
";" + lpselfname +
";" + lpattackguid +
";" + lpattacknum +
";" + lpattackteam +
";" + lpattackname +
";" + weapon.name +
";" + iDamage +
";" + sMeansOfDeath +
";" + sHitLoc +
"\n" );
1844 attackerString =
"none";
1845 if ( isPlayer( attacker ) )
1846 attackerString = attacker getXuid() +
"(" + lpattackname +
")";
1852 killcamentityindex = -1;
1853 killcamentitystarttime = 0;
1855 if ( isdefined( killcamentity ) )
1857 killcamentityindex = killcamentity getEntityNumber();
1858 if ( isdefined( killcamentity.startTime ) )
1860 killcamentitystarttime = killcamentity.startTime;
1864 killcamentitystarttime = killcamentity.birthtime;
1866 if ( !isdefined( killcamentitystarttime ) )
1867 killcamentitystarttime = 0;
1871 if ( isdefined(
self.killstreak_waitamount) &&
self.killstreak_waitamount > 0 )
1876 died_in_vehicle=
false;
1877 if (isdefined(
self.diedOnVehicle))
1879 died_in_vehicle =
self.diedOnVehicle;
1883 pixbeginevent(
"PlayerKilled body and gibbing" );
1884 if ( !died_in_vehicle )
1886 vAttackerOrigin = undefined;
1887 if ( isdefined( attacker ) )
1888 vAttackerOrigin = attacker.origin;
1890 ragdoll_now =
false;
1891 if( isdefined(
self.usingvehicle) &&
self.usingvehicle && isdefined(
self.vehicleposition) &&
self.vehicleposition == 1 )
1894 body =
self clonePlayer( deathAnimDuration, weapon, attacker );
1895 self createDeadBody( iDamage, sMeansOfDeath, weapon, sHitLoc, vDir, vAttackerOrigin, deathAnimDuration, eInflictor, ragdoll_now, body );
1901 self.switching_teams = undefined;
1902 self.joining_team = undefined;
1903 self.leaving_team = undefined;
1905 self thread [[level.onPlayerKilled]](eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration);
1907 for ( iCB = 0; iCB < level.onPlayerKilledExtraUnthreadedCBs.size; iCB++ )
1909 self [[ level.onPlayerKilledExtraUnthreadedCBs[ iCB ] ]](
1918 deathAnimDuration );
1921 self.wantSafeSpawn =
false;
1924 killstreaks = globallogic::getKillstreaks( attacker );
1926 if( !isdefined(
self.killstreak_waitamount ) )
1929 self thread [[level.spawnPlayerPrediction]]();
1932 profilelog_endtiming( 7,
"gs=" + game[
"state"] +
" zom=" + SessionModeIsZombiesGame() );
1937 self.cancelKillcam =
false;
1940 defaultPlayerDeathWatchTime = 1.75;
1941 if ( sMeansOfDeath ==
"MOD_MELEE_ASSASSINATE" || 0 > weapon.deathCamTime )
1943 defaultPlayerDeathWatchTime = (deathAnimDuration * 0.001) + 0.5;
1945 else if ( 0 < weapon.deathCamTime )
1947 defaultPlayerDeathWatchTime = weapon.deathCamTime;
1950 if ( isdefined ( level.overridePlayerDeathWatchTimer ) )
1952 defaultPlayerDeathWatchTime = [[level.overridePlayerDeathWatchTimer]]( defaultPlayerDeathWatchTime );
1957 self notify (
"death_delay_finished" );
1959 if ( game[
"state"] !=
"playing" )
1967 self.respawnTimerStartTime = gettime();
1969 if ( !
self.cancelKillcam && doKillcam && level.killcam )
1971 livesLeft = !(level.numLives && !
self.pers[
"lives"]);
1973 willRespawnImmediately = livesLeft && (timeUntilSpawn <= 0) && !level.playerQueuedRespawn;
1978 if ( game[
"state"] !=
"playing" )
1980 self.sessionstate =
"dead";
1981 self.spectatorclient = -1;
1982 self.killcamtargetentity = -1;
1983 self.killcamentity = -1;
1984 self.archivetime = 0;
1985 self.psoffsettime = 0;
1994 timePassed = undefined;
1996 if ( isdefined(
self.respawnTimerStartTime ) )
1998 timePassed = (gettime() -
self.respawnTimerStartTime) / 1000;
2001 self thread [[level.spawnClient]]( timePassed );
2002 self.respawnTimerStartTime = undefined;
2008 if ( isdefined(
self.pers[
"isBot"] ) )
2010 level.globalLarrysKilled++;
2017 if( isdefined(
self.killstreak_waitamount ) )
2019 starttime = gettime();
2020 waitTime =
self.killstreak_waitamount * 1000;
2022 while( (gettime() < (starttime+waitTime)) && isdefined(
self.killstreak_waitamount ) )
2030 self.killstreak_waitamount = undefined;
2038 self endon(
"disconnect");
2045 if ( playlistbanquantum > 0 && playlistbanpenalty > 0 )
2047 timeplayedtotal =
self GetDStat(
"playerstatslist",
"time_played_total",
"StatValue" );
2048 minutesplayed = timeplayedtotal / 60;
2052 banallowance = int( floor(minutesplayed / playlistbanquantum) ) + freebees;
2054 if (
self.sessionbans > banallowance )
2056 self SetDStat(
"playerstatslist",
"gametypeban",
"StatValue", timeplayedtotal + (playlistbanpenalty * 60) );
2062 level notify(
"bot_kicked",
self.team );
2065 ban(
self getentitynumber() );
2071 teamkills =
self.pers[
"teamkills_nostats"];
2072 if ( level.minimumAllowedTeamKills < 0 || teamkills <= level.minimumAllowedTeamKills )
2075 exceeded = (teamkills - level.minimumAllowedTeamKills);
2076 return level.teamKillSpawnDelay * exceeded;
2082 if ( teamKillDelay && ( level.minimumAllowedTeamKills >= 0 ) )
2091 if (
self.pers[
"teamkills_nostats"] > 1 )
2102 timePerOneTeamkillReduction = 20.0;
2103 reductionPerSecond = 1.0 / timePerOneTeamkillReduction;
2107 if ( isAlive(
self ) )
2109 self.pers[
"teamkills_nostats"] -= reductionPerSecond;
2110 if (
self.pers[
"teamkills_nostats"] < level.minimumAllowedTeamKills )
2112 self.pers[
"teamkills_nostats"] = level.minimumAllowedTeamKills;
2123 if( SessionModeIsZombiesGame() )
2126 if ( sMeansOfDeath ==
"MOD_MELEE" )
2129 if ( weapon.name ==
"briefcase_bomb" )
2132 if ( weapon.name ==
"supplydrop" )
2148 self PlayRumbleOnEntity(
"damage_heavy" );
2152 function createDeadBody( iDamage, sMeansOfDeath, weapon, sHitLoc, vDir, vAttackerOrigin, deathAnimDuration, eInflictor, ragdoll_jib, body )
2154 if ( sMeansOfDeath ==
"MOD_HIT_BY_OBJECT" &&
self GetStance() ==
"prone" )
2163 if ( isdefined( level.ragdoll_override ) &&
self [[level.ragdoll_override]]() )
2168 if ( ragdoll_jib ||
self isOnLadder() ||
self isMantling() || sMeansOfDeath ==
"MOD_CRUSH" || sMeansOfDeath ==
"MOD_HIT_BY_OBJECT" )
2169 body startRagDoll();
2171 if ( !
self IsOnGround() )
2173 if ( GetDvarint(
"scr_disable_air_death_ragdoll" ) == 0 )
2175 body startRagDoll();
2202 if ( !isdefined( weapon ) )
2208 if ( weapon.name ==
"destructible_car" || weapon.name ==
"explodable_barrel" )
2214 if ( weapon.projExplosionType ==
"grenade" )
2216 if ( isdefined( inflictor ) && isdefined( inflictor.stuckToPlayer ) )
2218 if ( inflictor.stuckToPlayer ==
self )
2230 if ( !isdefined(
self ) )
2235 x = RandomIntRange( 50, 100 );
2236 y = RandomIntRange( 50, 100 );
2237 z = RandomIntRange( 10, 20 );
2239 if ( isdefined( weapon ) && ( weapon.name ==
"sticky_grenade" || weapon.name ==
"explosive_bolt" ) )
2241 if ( isdefined( dir ) && LengthSquared( dir ) > 0 )
2259 self StartRagdoll();
2260 self LaunchRagdoll( ( x, y, z ) );
2268 if( isdefined(
self ) )
2270 level notify(
"connecting",
self );
2278 if ( isdefined( ent ) )
2280 deathAnim = ent getcorpseanim();
2281 if ( animhasnotetrack( deathAnim,
"ignore_ragdoll" ) )
2285 if ( level.oldschool )
2287 if ( !isdefined( vDir ) )
2291 explosionPos -= vDir * 20;
2293 explosionRadius = 40;
2294 explosionForce = .75;
2295 if ( sMeansOfDeath ==
"MOD_IMPACT" || sMeansOfDeath ==
"MOD_EXPLOSIVE" || isSubStr(sMeansOfDeath,
"MOD_GRENADE") || isSubStr(sMeansOfDeath,
"MOD_PROJECTILE") || sHitLoc ==
"head" || sHitLoc ==
"helmet" )
2297 explosionForce = 2.5;
2300 ent startragdoll( 1 );
2304 if ( !isdefined( ent ) )
2308 physicsExplosionSphere( explosionPos, explosionRadius, explosionRadius/2, explosionForce );
2314 if ( !isdefined( ent ) )
2317 if ( ent isRagDoll() )
2320 deathAnim = ent getcorpseanim();
2324 if ( animhasnotetrack( deathAnim,
"start_ragdoll" ) )
2326 times = getnotetracktimes( deathAnim,
"start_ragdoll" );
2327 if ( isdefined( times ) )
2328 startFrac = times[0];
2331 waitTime = startFrac * getanimlength( deathAnim );
2334 if ( isdefined( ent ) )
2336 ent startragdoll( 1 );
2342 if( !IsDefined( eAttacker ) )
2345 if ( !IsPlayer( eAttacker ) )
2348 if (
self.attackerData.size == 0 )
2350 self.firstTimeDamaged = getTime();
2352 if ( !isdefined(
self.attackerData[eAttacker.clientid] ) )
2354 self.attackerDamage[eAttacker.clientid] = spawnstruct();
2355 self.attackerDamage[eAttacker.clientid].damage = iDamage;
2356 self.attackerDamage[eAttacker.clientid].meansOfDeath = sMeansOfDeath;
2357 self.attackerDamage[eAttacker.clientid].weapon = weapon;
2358 self.attackerDamage[eAttacker.clientid].time = getTime();
2360 self.attackers[
self.attackers.size ] = eAttacker;
2365 self.attackerData[eAttacker.clientid] =
false;
2369 self.attackerDamage[eAttacker.clientid].damage += iDamage;
2370 self.attackerDamage[eAttacker.clientid].meansOfDeath = sMeansOfDeath;
2371 self.attackerDamage[eAttacker.clientid].weapon = weapon;
2372 if ( !isdefined(
self.attackerDamage[eAttacker.clientid].time ) )
2373 self.attackerDamage[eAttacker.clientid].time = getTime();
2376 self.attackerDamage[eAttacker.clientid].lasttimedamaged = getTime();
2378 self.attackerData[eAttacker.clientid] =
true;
2388 if ( !isdefined( eInflictor ) )
2391 if ( !isdefined( eInflictor.owner ) )
2394 if ( !isdefined( eInflictor.ownerGetsAssist ) )
2397 if ( !eInflictor.ownerGetsAssist )
2402 if ( isdefined( eAttacker ) && eAttacker == eInflictor.owner )
2411 switch ( weapon.name )
2413 case "knife_ballistic":
2415 if ( ( sMeansOfDeath !=
"MOD_HEAD_SHOT" ) && ( sMeansOfDeath !=
"MOD_MELEE" ) )
2417 sMeansOfDeath =
"MOD_PISTOL_BULLET";
2422 sMeansOfDeath =
"MOD_PISTOL_BULLET";
2424 case "destructible_car":
2425 sMeansOfDeath =
"MOD_EXPLOSIVE";
2427 case "explodable_barrel":
2428 sMeansOfDeath =
"MOD_EXPLOSIVE";
2432 return sMeansOfDeath;
2437 if( isai(attacker) && isdefined( attacker.script_owner ) )
2441 if ( !level.teambased || attacker.script_owner.team !=
self.team )
2442 attacker = attacker.script_owner;
2445 if( attacker.classname ==
"script_vehicle" && isdefined( attacker.owner ) )
2447 attacker notify(
"killed",
self);
2449 attacker = attacker.owner;
2452 if( isai(attacker) )
2453 attacker notify(
"killed",
self);
2455 if ( ( isdefined (
self.capturingLastFlag ) ) && (
self.capturingLastFlag ==
true ) )
2457 attacker.lastCapKiller =
true;
2460 if( isdefined( attacker ) && isdefined( weapon ) && weapon.name ==
"planemortar" )
2462 if ( !isdefined( attacker.planeMortarBda ) )
2464 attacker.planeMortarBda = 0;
2466 attacker.planeMortarBda ++;
2474 if( isdefined( eInflictor ) && eInflictor.classname ==
"script_vehicle" )
2476 eInflictor notify(
"killed",
self);
2478 if ( isdefined( eInflictor.bda ) )
2490 if ( weapon == level.weaponNone && isdefined( eInflictor ) )
2492 if ( isdefined( eInflictor.targetname ) && eInflictor.targetname ==
"explodable_barrel" )
2493 weapon = GetWeapon(
"explodable_barrel" );
2494 else if ( isdefined( eInflictor.destructible_type ) && isSubStr( eInflictor.destructible_type,
"vehicle_" ) )
2495 weapon = GetWeapon(
"destructible_car" );
2503 if ( !isdefined( depth ) )
2506 closestKillcamEnt = undefined;
2507 closestKillcamEntIndex = undefined;
2508 closestKillcamEntDist = undefined;
2511 foreach( killcamEntIndex, killcamEnt
in killCamEntities )
2513 if ( killcamEnt == attacker )
2516 origin = killcamEnt.origin;
2517 if ( isdefined( killcamEnt.offsetPoint ) )
2518 origin += killcamEnt.offsetPoint;
2520 dist = DistanceSquared(
self.origin, origin );
2522 if ( !isdefined( closestKillcamEnt ) || dist < closestKillcamEntDist )
2524 closestKillcamEnt = killcamEnt;
2525 closestKillcamEntDist = dist;
2526 closestKillcamEntIndex = killcamEntIndex;
2531 if ( depth < 3 && isdefined( closestKillcamEnt ) )
2533 if ( !BulletTracePassed( closestKillcamEnt.origin,
self.origin,
false,
self ) )
2535 killCamEntities[closestKillcamEntIndex] = undefined;
2539 if ( isdefined( betterKillcamEnt ) )
2541 closestKillcamEnt = betterKillcamEnt;
2546 return closestKillcamEnt;
2551 if ( !isdefined( eInflictor ) )
2554 if ( eInflictor == attacker )
2556 if( !isdefined( eInflictor.isMagicBullet ) )
2558 if( isdefined( eInflictor.isMagicBullet ) && !eInflictor.isMagicBullet )
2561 else if ( isdefined( level.levelSpecificKillcam ) )
2563 levelSpecificKillcamEnt =
self [[level.levelSpecificKillcam]]();
2564 if ( isdefined( levelSpecificKillcamEnt ) )
2565 return levelSpecificKillcamEnt;
2568 if ( weapon.name ==
"m220_tow" )
2571 if ( isdefined(eInflictor.killCamEnt) )
2574 if ( eInflictor.killCamEnt == attacker )
2577 return eInflictor.killCamEnt;
2579 else if ( isdefined(eInflictor.killCamEntities) )
2584 if ( isdefined( eInflictor.script_gameobjectname ) && eInflictor.script_gameobjectname ==
"bombzone" )
2585 return eInflictor.killCamEnt;
2603 foreach (player
in level.players)
2605 recordPlayerMatchEnd( player );
2606 RecordPlayerStats(player,
"presentAtEnd", 1 );