‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
_globallogic_player.gsc
Go to the documentation of this file.
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;
15 
16 #insert scripts\shared\shared.gsh;
17 
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;
30 
31 #using scripts\zm\_challenges;
32 #using scripts\zm\_util;
33 #using scripts\zm\_zm_stats;
34 
35 #namespace globallogic_player;
36 
38 {
40 
41  self closeInGameMenu();
42 
44 }
45 
47 {
48  thread ‪notifyConnecting();
49 
50  self.statusicon = "hud_status_connecting";
51  self waittill( "begin" );
52 
53  if( isdefined( level.reset_clientdvars ) )
54  self [[level.reset_clientdvars]]();
55 
56  waittillframeend;
57  self.statusicon = "";
58 
59  self.guid = self getGuid();
60 
61  profilelog_begintiming( 4, "ship" );
62 
63  level notify( "connected", self );
64 
65  if ( self IsHost() )
67 
68  // only print that we connected if we haven't connected in a previous round
69  if( !level.splitscreen && !isdefined( self.pers["score"] ) )
70  {
71  iPrintLn(&"MP_CONNECTED", self);
72  }
73 
74  if( !isdefined( self.pers["score"] ) )
75  {
76  self thread ‪zm_stats::adjustRecentStats();
77  }
78 
79  // track match and hosting stats once per match
80  if( GameModeIsMode( ‪GAMEMODE_PUBLIC_MATCH ) && !isdefined( self.pers["matchesPlayedStatsTracked"] ) )
81  {
82  gameMode = ‪util::GetCurrentGameMode();
83  self ‪globallogic::IncrementMatchCompletionStat( gameMode, "played", "started" );
84 
85  if ( !isdefined( self.pers["matchesHostedStatsTracked"] ) && self IsLocalToHost() )
86  {
87  self ‪globallogic::IncrementMatchCompletionStat( gameMode, "hosted", "started" );
88  self.pers["matchesHostedStatsTracked"] = true;
89  }
90 
91  self.pers["matchesPlayedStatsTracked"] = true;
92  self thread ‪zm_stats::uploadStatsSoon();
93  }
94 
95  //self _gamerep::gameRepPlayerConnected();
96 
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 );
102 
103  if( !SessionModeIsZombiesGame() ) // it will be set after intro screen is faded out for zombie
104  {
105  self setClientUIVisibilityFlag( "hud_visible", 1 );
106  self setClientUIVisibilityFlag( "weapon_hud_visible", 1 );
107  }
108 
109  if ( level.forceRadar == 1 ) // radar always sweeping
110  {
111  self.pers["hasRadar"] = true;
112  self.hasSpyplane = true;
113  level.activeUAVs[self getEntityNumber()] = 1;
114  }
115 
116  if ( level.forceRadar == 2 ) // radar constant
117  {
118  self setClientUIVisibilityFlag( "g_compassShowEnemies", level.forceRadar );
119  }
120  else
121  {
122  self SetClientUIVisibilityFlag( "g_compassShowEnemies", 0 );
123  }
124 
125  self SetClientPlayerSprintTime( level.playerSprintTime );
126  self SetClientNumLives( level.numLives );
127 
128  //makeDvarServerInfo( "cg_drawTalk", 1 );
129 
130  if ( level.hardcoreMode )
131  {
132  self SetClientDrawTalk( 3 );
133  }
134 
135  self [[level.player_stats_init]]();
136 
137  self.killedPlayersCurrent = [];
138 
139  if( !isdefined( self.pers["best_kill_streak"] ) )
140  {
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"] = "";
151 
152 
153  /*self.killstreakKills["artillery"] = 0;
154  self.killstreakKills["dogs"] = 0;
155  self.killstreaksUsed["radar"] = 0;
156  self.killstreaksUsed["artillery"] = 0;
157  self.killstreaksUsed["dogs"] = 0;*/
158  self.pers["best_kill_streak"] = 0;
159  }
160 
161 // Adding Music tracking per player CDC
162  if( !isdefined( self.pers["music"] ) )
163  {
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";
171 
172  }
173  self.leaderDialogQueue = [];
174  self.leaderDialogActive = false;
175  self.leaderDialogGroups = [];
176  self.currentLeaderDialogGroup = "";
177  self.currentLeaderDialog = "";
178  self.currentLeaderDialogTime = 0;
179 
180  if ( !isdefined( self.pers["cur_kill_streak"] ) )
181  {
182  self.pers["cur_kill_streak"] = 0;
183  }
184 
185  if ( !isdefined( self.pers["cur_total_kill_streak"] ) )
186  {
187  self.pers["cur_total_kill_streak"] = 0;
188  self setplayercurrentstreak( 0 );
189  }
190 
191  if ( !isdefined( self.pers["totalKillstreakCount"] ) )
192  self.pers["totalKillstreakCount"] = 0;
193 
194  //Keep track of how many killstreaks have been earned in the current streak
195  if ( !isdefined( self.pers["killstreaksEarnedThisKillstreak"] ) )
196  self.pers["killstreaksEarnedThisKillstreak"] = 0;
197 
198  if ( isdefined( level.usingScoreStreaks ) && level.usingScoreStreaks && !isdefined( self.pers["killstreak_quantity"] ) )
199  self.pers["killstreak_quantity"] = [];
200 
201  if ( isdefined( level.usingScoreStreaks ) && level.usingScoreStreaks && !isdefined( self.pers["held_killstreak_ammo_count"] ) )
202  self.pers["held_killstreak_ammo_count"] = [];
203 
204  self.lastKillTime = 0;
205 
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;
212  self.deathTime = 0;
213 
214  /*if ( level.onlineGame )
215  {
216  self.death_streak = self getDStat( "HighestStats", "death_streak" );
217  self.kill_streak = self getDStat( "HighestStats", "kill_streak" );
218  self.gametype_kill_streak = self _persistence::statGetWithGameType( "kill_streak" );
219  }*/
220 
221  self.lastGrenadeSuicideTime = -1;
222 
223  self.teamkillsThisRound = 0;
224 
225  if ( !isdefined( level.livesDoNotReset ) || !level.livesDoNotReset || !isdefined( self.pers["lives"] ) )
226  self.pers["lives"] = level.numLives;
227 
228  // multi round FFA games in custom game mode should maintain team in-between rounds
229  if ( !level.teamBased )
230  {
231  self.pers["team"] = undefined;
232  }
233 
234  self.hasSpawned = false;
235  self.waitingToSpawn = false;
236  self.wantSafeSpawn = false;
237  self.deathCount = 0;
238 
239  self.wasAliveAtMatchStart = false;
240 
241  level.players[level.players.size] = self;
242 
243  if( level.splitscreen )
244  SetDvar( "splitscreen_playerNum", level.players.size );
245  // removed underscore for debug CDC
246  //globallogic_audio::set_music_on_team( "UNDERSCORE", "both", true );;
247  // When joining a game in progress, if the game is at the post game state (scoreboard) the connecting player should spawn into intermission
248  if ( game["state"] == "postgame" )
249  {
250  self.pers["needteam"] = 1;
251  self.pers["team"] = "spectator";
252  self.team = "spectator";
253  self.sessionteam = "spectator";
254  self setClientUIVisibilityFlag( "hud_visible", 0 );
255 
256  self [[level.spawnIntermission]]();
257  self closeInGameMenu();
258  profilelog_endtiming( 4, "gs=" + game["state"] + " zom=" + SessionModeIsZombiesGame() );
259  return;
260  }
261 
262  level endon( "game_ended" );
263 
264  if ( isdefined( level.hostMigrationTimer ) )
266 
267  if ( level.oldschool )
268  {
269  self.pers["class"] = undefined;
270  self.curClass = self.pers["class"];
271  }
272 
273  if ( isdefined( self.pers["team"] ) )
274  self.team = self.pers["team"];
275 
276  if ( isdefined( self.pers["class"] ) )
277  self.curClass = self.pers["class"];
278 
279  if ( !isdefined( self.pers["team"] ) || isdefined( self.pers["needteam"] ) )
280  {
281  // Don't set .sessionteam until we've gotten the assigned team from code,
282  // because it overrides the assigned team.
283  self.pers["needteam"] = undefined;
284  self.pers["team"] = "spectator";
285  self.team = "spectator";
286  self.sessionstate = "dead";
287 
289 
290  [[level.spawnSpectator]]();
291 
292  if ( level.rankedMatch )
293  {
294  [[level.autoassign]]( false );
295 
296  //self thread globallogic_spawn::forceSpawn();
298  }
299  else
300  {
301  [[level.autoassign]]( false );
302  }
303 
304  if ( self.pers["team"] == "spectator" )
305  {
306  self.sessionteam = "spectator";
307  self thread ‪spectate_player_watcher();
308  }
309 
310  if ( level.teamBased )
311  {
312  // set team and spectate permissions so the map shows waypoint info on connect
313  self.sessionteam = self.pers["team"];
314  if ( !isAlive( self ) )
315  self.statusicon = "hud_status_dead";
317  }
318  }
319  else if ( self.pers["team"] == "spectator" )
320  {
321  self SetClientScriptMainMenu( game[ "menu_start_menu" ] );
322  [[level.spawnSpectator]]();
323  self.sessionteam = "spectator";
324  self.sessionstate = "spectator";
325  self thread ‪spectate_player_watcher();
326  }
327  else
328  {
329  self.sessionteam = self.pers["team"];
330  self.sessionstate = "dead";
331 
333 
334  [[level.spawnSpectator]]();
335 
336  if ( ‪globallogic_utils::isValidClass( self.pers["class"] ) )
337  {
338  self thread [[level.spawnClient]]();
339  }
340  else
341  {
343  }
344 
346  }
347 
348  if ( self.sessionteam != "spectator" )
349  {
350  self thread ‪spawning::onSpawnPlayer_Unified(true);
351  }
352 
353  profilelog_endtiming( 4, "gs=" + game["state"] + " zom=" + SessionModeIsZombiesGame() );
354 }
355 
357 {
358  self endon( "disconnect" );
359 
360  self.watchingActiveClient = true;
361  self.waitingForPlayersText = undefined;
362 
363  while ( 1 )
364  {
365  if ( self.pers["team"] != "spectator" || level.gameEnded )
366  {
368  self FreezeControls( false );
369  self.watchingActiveClient = false;
370  break;
371  }
372  else
373  {
374  // Setup the perks hud elem for the spectator if its not yet initalized
375  // We have to do it here, since the perk hudelem is generally initalized only on spawn, and the spectator will not able able to
376  // look at the perk loadout of some player.
377  if ( !level.splitscreen && !level.hardcoreMode && GetDvarint( "scr_showperksonspawn" ) == 1 && game["state"] != "postgame" && !isdefined( self.perkHudelem ) )
378  {
379  if ( level.perksEnabled == 1 )
380  {
381  self ‪hud::showPerks( );
382  }
383  }
384 
385  count = 0;
386  for ( i = 0; i < level.players.size; i++ )
387  {
388  if ( level.players[i].team != "spectator" )
389  {
390  count++;
391  break;
392  }
393  }
394 
395  if ( count > 0 )
396  {
397  if ( !self.watchingActiveClient )
398  {
400  self FreezeControls( false );
401 
402 
403  }
404 
405  self.watchingActiveClient = true;
406  }
407  else
408  {
409  if ( self.watchingActiveClient )
410  {
411  [[level.onSpawnSpectator]]();
412  self FreezeControls( true );
414  }
415 
416  self.watchingActiveClient = false;
417  }
418 
419  wait( 0.5 );
420  }
421  }
422 }
423 
425 {
426 
427 
428  if ( isdefined( self.connected ) && self.connected )
429  {
431 // self globallogic_ui::updateObjectiveText();
432 // self updateMainMenu();
433 
434 // if ( level.teambased )
435 // self updateScores();
436  }
437 
438  self thread ‪inform_clientvm_of_migration();
439 
440  level.hostMigrationReturnedPlayerCount++;
441  if ( level.hostMigrationReturnedPlayerCount >= level.players.size * 2 / 3 )
442  {
443 
444  level notify( "hostmigration_enoughplayers" );
445  }
446 }
447 
449 {
450  self endon("disconnect");
451  wait 1.0;
452 
453  self ‪util::clientNotify("hmo");
454 }
455 
456 function ‪ArrayToString( inputArray )
457 {
458  targetString = "";
459  for (i=0; i < inputArray.size; i++)
460  {
461  targetString += inputArray[i];
462  if (i != inputArray.size-1)
463  targetString += ",";
464  }
465  return targetString;
466 }
467 
469 {
470 }
471 
473 {
474  profilelog_begintiming( 5, "ship" );
475 
476  if ( game["state"] != "postgame" && !level.gameEnded )
477  {
478  gameLength = ‪globallogic::getGameLength();
479  self ‪globallogic::bbPlayerMatchEnd( gameLength, "MP_PLAYER_DISCONNECT", 0 );
480  }
481 
482  ArrayRemoveValue( level.players, self );
483 
484  if ( level.splitscreen )
485  {
486  players = level.players;
487 
488  if ( players.size <= 1 )
489  level thread ‪globallogic::forceEnd();
490 
491  // passing number of players to menus in splitscreen to display leave or end game option
492  SetDvar( "splitscreen_playerNum", players.size );
493  }
494 
495  if ( isdefined( self.score ) && isdefined( self.pers["team"] ) )
496  {
497 
498  level.dropTeam += 1;
499  }
500 
501  [[level.onPlayerDisconnect]]();
502 
503  lpselfnum = self getEntityNumber();
504  lpGuid = self getGuid();
505  logPrint("Q;" + lpGuid + ";" + lpselfnum + ";" + self.‪name + "\n");
506 
507  //self _gamerep::gameRepPlayerDisconnected();
508 
509  ‪recordZMEndGameComScoreEventForPlayer( self, "disconnected" );
510 
511  for ( entry = 0; entry < level.players.size; entry++ )
512  {
513  if ( level.players[entry] == self )
514  {
515  while ( entry < level.players.size-1 )
516  {
517  level.players[entry] = level.players[entry+1];
518  entry++;
519  }
520  level.players[entry] = undefined;
521  break;
522  }
523  }
524  for ( entry = 0; entry < level.players.size; entry++ )
525  {
526  if ( isdefined( level.players[entry].pers["killed_players"][self.name] ) )
527  level.players[entry].pers["killed_players"][self.name] = undefined;
528 
529  if ( isdefined( level.players[entry].killedPlayersCurrent[self.name] ) )
530  level.players[entry].killedPlayersCurrent[self.name] = undefined;
531 
532  if ( isdefined( level.players[entry].pers["killed_by"][self.name] ) )
533  level.players[entry].pers["killed_by"][self.name] = undefined;
534 
535  if ( isdefined( level.players[entry].pers["nemesis_tracking"][self.name] ) )
536  level.players[entry].pers["nemesis_tracking"][self.name] = undefined;
537 
538  // player that disconnected was our nemesis
539  if ( level.players[entry].pers["nemesis_name"] == self.name )
540  {
541  level.players[entry] ‪chooseNextBestNemesis();
542  }
543  }
544 
545  if ( level.gameEnded )
547 
548  level thread ‪globallogic::updateTeamStatus();
549 
550  profilelog_endtiming( 5, "gs=" + game["state"] + " zom=" + SessionModeIsZombiesGame() );
551 }
552 
553 function ‪Callback_PlayerMelee( eAttacker, iDamage, weapon, vOrigin, vDir, boneIndex, shieldHit, fromBehind )
554 {
555  hit = true;
556 
557  if ( level.teamBased && self.team == eAttacker.team )
558  {
559  if ( level.friendlyfire == 0 ) // no one takes damage
560  {
561  hit = false;
562  }
563  }
564 
565  self finishMeleeHit( eAttacker, weapon, vOrigin, vDir, boneIndex, shieldHit, hit, fromBehind );
566 }
567 
569 {
570  nemesisArray = self.pers["nemesis_tracking"];
571  nemesisArrayKeys = getArrayKeys( nemesisArray );
572  nemesisAmount = 0;
573  nemesisName = "";
574 
575  if ( nemesisArrayKeys.size > 0 )
576  {
577  for ( i = 0; i < nemesisArrayKeys.size; i++ )
578  {
579  nemesisArrayKey = nemesisArrayKeys[i];
580  if ( nemesisArray[nemesisArrayKey] > nemesisAmount )
581  {
582  nemesisName = nemesisArrayKey;
583  nemesisAmount = nemesisArray[nemesisArrayKey];
584  }
585 
586  }
587  }
588 
589  self.pers["nemesis_name"] = nemesisName;
590 
591  if ( nemesisName != "" )
592  {
593  playerIndex = 0;
594  for( ; playerIndex < level.players.size; playerIndex++ )
595  {
596  if ( level.players[playerIndex].name == nemesisName )
597  {
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();
603  break;
604  }
605  }
606  }
607  else
608  {
609  self.pers["nemesis_xuid"] = "";
610  }
611 }
612 
613 function ‪custom_gamemodes_modified_damage( victim, eAttacker, iDamage, sMeansOfDeath, weapon, eInflictor, sHitLoc )
614 {
615  // regular public matches should early out
616  if ( level.onlinegame && !SessionModeIsPrivate() )
617  {
618  return iDamage;
619  }
620 
621  if( isdefined( eAttacker) && isdefined( eAttacker.damageModifier ) )
622  {
623  iDamage *= eAttacker.damageModifier;
624  }
625  if ( ( sMeansOfDeath == "MOD_PISTOL_BULLET" ) || ( sMeansOfDeath == "MOD_RIFLE_BULLET" ) )
626  {
627  iDamage = int( iDamage * level.bulletDamageScalar );
628  }
629 
630  return iDamage;
631 }
632 
633 function ‪figureOutAttacker( eAttacker )
634 {
635  if ( isdefined(eAttacker) )
636  {
637  if( isai(eAttacker) && isdefined( eAttacker.script_owner ) )
638  {
639  team = self.team;
640 
641  if ( eAttacker.script_owner.team != team )
642  eAttacker = eAttacker.script_owner;
643  }
644 
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;
649  }
650 
651  return eAttacker;
652 }
653 
654 function ‪figureOutWeapon( weapon, eInflictor )
655 {
656  // explosive barrel/car detection
657  if ( weapon == level.weaponNone && isdefined( eInflictor ) )
658  {
659  if ( isdefined( eInflictor.targetname ) && eInflictor.targetname == "explodable_barrel" )
660  {
661  weapon = GetWeapon( "explodable_barrel" );
662  }
663  else if ( isdefined( eInflictor.destructible_type ) && isSubStr( eInflictor.destructible_type, "vehicle_" ) )
664  {
665  weapon = GetWeapon( "destructible_car" );
666  }
667  }
668 
669  return weapon;
670 }
671 
672 function ‪figureOutFriendlyFire( victim )
673 {
674  return level.friendlyfire;
675 }
676 
677 function ‪isPlayerImmuneToKillstreak( eAttacker, weapon )
678 {
679  if ( level.hardcoreMode )
680  return false;
681 
682  if ( !isdefined( eAttacker ) )
683  return false;
684 
685  if ( self != eAttacker )
686  return false;
687 
688  return weapon.doNotDamageOwner;
689 }
690 
691 function ‪Callback_PlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex )
692 {
693  profilelog_begintiming( 6, "ship" );
694 
695  if ( game["state"] == "postgame" )
696  return;
697 
698  if ( self.sessionteam == "spectator" )
699  return;
700 
701  if ( isdefined( self.canDoCombat ) && !self.canDoCombat )
702  return;
703 
704  if ( isdefined( eAttacker ) && isPlayer( eAttacker ) && isdefined( eAttacker.canDoCombat ) && !eAttacker.canDoCombat )
705  return;
706 
707  if ( isdefined( level.hostMigrationTimer ) )
708  return;
709 
710  if ( self.scene_takedamage === false )
711  {
712  return;
713  }
714 
715  weaponName = weapon.name;
716  if ( ( weaponName == "ai_tank_drone_gun" || weaponName == "ai_tank_drone_rocket" ) && !level.hardcoreMode )
717  {
718  // rocket fired from AI
719  if ( isdefined( eAttacker ) && eAttacker == self )
720  {
721  if ( isdefined( eInflictor ) && isdefined( eInflictor.from_ai ) )
722  {
723  return;
724  }
725  }
726 
727  // bullet weapon fired from AI
728  if ( isdefined( eAttacker ) && isdefined( eAttacker.owner ) && eAttacker.owner == self )
729  {
730  return;
731  }
732  }
733 
734  if ( weapon.isEmp )
735  {
736  self notify( "emp_grenaded", eAttacker );
737  }
738 
739 /* if ( isdefined( eAttacker ) )
740  {
741  iDamage = _class::cac_modified_damage( self, eAttacker, iDamage, sMeansOfDeath, weapon, eInflictor, sHitLoc );
742  }*/
743  iDamage = ‪custom_gamemodes_modified_damage( self, eAttacker, iDamage, sMeansOfDeath, weapon, eInflictor, sHitLoc );
744 
745  iDamage = int(iDamage);
746  self.iDFlags = iDFlags;
747  self.iDFlagsTime = getTime();
748 
749  eAttacker = ‪figureOutAttacker( eAttacker );
750 
751  pixbeginevent( "PlayerDamage flags/tweaks" );
752 
753  // Don't do knockback if the damage direction was not specified
754  if( !isdefined( vDir ) )
755  iDFlags |= level.iDFLAGS_NO_KNOCKBACK;
756 
757  friendly = false;
758  // Todo MGordon - Fix this stat collection
759  //self thread globallogic_score::threadedSetStatLBByName( weapon, 1, "hits by", 2 );
760 
761  // added check to notify chatter to play pain vo
762  if ( self.health != self.maxhealth )
763  {
764  self notify( "snd_pain_player", sMeansOfDeath );
765  }
766 
767  if ( isdefined( eInflictor) && isdefined( eInflictor.script_noteworthy) && eInflictor.script_noteworthy == "ragdoll_now" )
768  {
769  sMeansOfDeath = "MOD_FALLING";
770  }
771 
772  if ( ‪globallogic_utils::isHeadShot( weapon, sHitLoc, sMeansOfDeath, eInflictor ) && isPlayer(eAttacker) )
773  {
774  //Turning off damage headshot sounds to avoid confusion from the killing headshot sound.
775  //if (self.team != eAttacker.team)
776  //{
777  // eAttacker playLocalSound( "prj_bullet_impact_headshot_helmet_nodie_2d" );
778  //}
779  sMeansOfDeath = "MOD_HEAD_SHOT";
780  }
781 
782  if ( level.onPlayerDamage != &‪globallogic::blank )
783  {
784  modifiedDamage = [[level.onPlayerDamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime );
785 
786  if ( isdefined( modifiedDamage ) )
787  {
788  if ( modifiedDamage <= 0 )
789  return;
790 
791  iDamage = modifiedDamage;
792  }
793  }
794 
795  if ( level.onlyHeadShots )
796  {
797  if ( sMeansOfDeath == "MOD_PISTOL_BULLET" || sMeansOfDeath == "MOD_RIFLE_BULLET" )
798  return;
799  else if ( sMeansOfDeath == "MOD_HEAD_SHOT" )
800  iDamage = 150;
801  }
802 
803  // Make all vehicle drivers invulnerable to bullets
804 // if ( self _vehicles::player_is_occupant_invulnerable( sMeansOfDeath ) )
805 // return;
806 
807  if (isdefined (eAttacker) && isPlayer(eAttacker) && (self.team != eAttacker.team))
808  {
809  self.lastAttackWeapon = weapon;
810  }
811 
812  weapon = ‪figureOutWeapon( weapon, eInflictor );
813 
814  pixendevent(); // "END: PlayerDamage flags/tweaks"
815 
816 // if( iDFlags & level.iDFLAGS_PENETRATION && isplayer ( eAttacker ) && eAttacker hasPerk( "specialty_bulletpenetration" ) )
817 // self thread _battlechatter_mp::perkSpecificBattleChatter( "deepimpact", true );
818 
819  attackerIsHittingTeammate = isPlayer( eAttacker ) && ( self ‪util::IsEnemyPlayer( eAttacker ) == false );
820 
821  if ( sHitLoc == "riotshield" )
822  {
823  if ( attackerIsHittingTeammate && level.friendlyfire == 0 )
824  {
825  return;
826  }
827 
828  if ( sMeansOfDeath == "MOD_PISTOL_BULLET" || sMeansOfDeath == "MOD_RIFLE_BULLET" && !attackerIsHittingTeammate )
829  {
830  previous_shield_damage = self.shieldDamageBlocked;
831  self.shieldDamageBlocked += iDamage;
832 
833  if ( isPlayer( eAttacker ))
834  {
835  eAttacker.lastAttackedShieldPlayer = self;
836  eAttacker.lastAttackedShieldTime = getTime();
837  }
838  }
839 
840  if ( iDFlags & level.iDFLAGS_SHIELD_EXPLOSIVE_IMPACT )
841  {
842  sHitLoc = "none"; // code ignores any damage to a "shield" bodypart.
843  if ( !(iDFlags & level.iDFLAGS_SHIELD_EXPLOSIVE_IMPACT_HUGE) )
844  {
845  iDamage *= 0.0;
846  }
847  }
848  else if ( iDFlags & level.iDFLAGS_SHIELD_EXPLOSIVE_SPLASH )
849  {
850  if ( isdefined( eInflictor ) && isdefined( eInflictor.stuckToPlayer ) && eInflictor.stuckToPlayer == self )
851  {
852  //does enough damage to shield carrier to ensure death
853  iDamage = 101;
854  }
855 
856  sHitLoc = "none";
857  }
858  else
859  {
860  return;
861  }
862  }
863 
864  // check for completely getting out of the damage
865  /*if( !(iDFlags & level.iDFLAGS_NO_PROTECTION) )
866  {
867  if ( isdefined( eInflictor ) && ( sMeansOfDeath == "MOD_GAS" || _class::isExplosiveDamage( sMeansOfDeath ) ) )
868  {
869  // protect players from spawnkill grenades, tabun and incendiary
870  if ( ( eInflictor.classname == "grenade" || weaponName == "tabun_gas" ) && (self.lastSpawnTime + 3500) > getTime() && DistanceSquared( eInflictor.origin, self.lastSpawnPoint.origin ) < 250 * 250 )
871  {
872 // pixmarker( "END: Callback_PlayerDamage player" );
873  return;
874  }
875 
876  // protect players from their own non-player controlled killstreaks
877  if ( self isPlayerImmuneToKillstreak( eAttacker, weapon ) )
878  {
879  return;
880  }
881 
882  self.explosiveInfo = [];
883  self.explosiveInfo["damageTime"] = getTime();
884  self.explosiveInfo["damageId"] = eInflictor getEntityNumber();
885  self.explosiveInfo["originalOwnerKill"] = false;
886  self.explosiveInfo["bulletPenetrationKill"] = false;
887  self.explosiveInfo["chainKill"] = false;
888  self.explosiveInfo["damageExplosiveKill"] = false;
889  self.explosiveInfo["chainKill"] = false;
890  self.explosiveInfo["cookedKill"] = false;
891  self.explosiveInfo["weapon"] = weapon;
892  self.explosiveInfo["originalowner"] = eInflictor.originalowner;
893 
894  isFrag = ( weaponName == "frag_grenade" );
895 
896  if ( isdefined( eAttacker ) && eAttacker != self )
897  {
898  if ( isdefined( eAttacker ) && isdefined( eInflictor.owner ) && ( weaponName == "satchel_charge" || weaponName == "claymore" || weaponName == "bouncingbetty" ) )
899  {
900  self.explosiveInfo["originalOwnerKill"] = (eInflictor.owner == self);
901  self.explosiveInfo["damageExplosiveKill"] = isdefined( eInflictor.wasDamaged );
902  self.explosiveInfo["chainKill"] = isdefined( eInflictor.wasChained );
903  self.explosiveInfo["wasJustPlanted"] = isdefined( eInflictor.wasJustPlanted );
904  self.explosiveInfo["bulletPenetrationKill"] = isdefined( eInflictor.wasDamagedFromBulletPenetration );
905  self.explosiveInfo["cookedKill"] = false;
906  }
907  if ( ( weaponName == "sticky_grenade" || weaponName == "explosive_bolt" ) && isdefined( eInflictor ) && isdefined( eInflictor.stuckToPlayer ) )
908  {
909  self.explosiveInfo["stuckToPlayer"] = eInflictor.stuckToPlayer;
910  }
911  if ( weapon.isStun )
912  {
913  self.lastStunnedBy = eAttacker;
914  self.lastStunnedTime = self.iDFlagsTime;
915  }
916  if ( isdefined( eAttacker.lastGrenadeSuicideTime ) && eAttacker.lastGrenadeSuicideTime >= gettime() - 50 && isFrag )
917  {
918  self.explosiveInfo["suicideGrenadeKill"] = true;
919  }
920  else
921  {
922  self.explosiveInfo["suicideGrenadeKill"] = false;
923  }
924  }
925 
926  if ( isFrag )
927  {
928  self.explosiveInfo["cookedKill"] = isdefined( eInflictor.isCooked );
929  self.explosiveInfo["throwbackKill"] = isdefined( eInflictor.threwBack );
930  }
931 
932  if( isdefined( eAttacker ) && isPlayer( eAttacker ) && eAttacker != self )
933  {
934  self globallogic_score::setInflictorStat( eInflictor, eAttacker, weapon );
935  }
936  }
937 
938  if( sMeansOfDeath == "MOD_IMPACT" && isdefined( eAttacker ) && isPlayer( eAttacker ) && eAttacker != self )
939  {
940  if ( weapon != level.weaponBallisticKnife )
941  {
942  self globallogic_score::setInflictorStat( eInflictor, eAttacker, sWeapon );
943  }
944 
945  if ( weaponName == "hatchet" && isdefined( eInflictor ) )
946  {
947  self.explosiveInfo["projectile_bounced"] = isdefined( eInflictor.bounced );
948  }
949  }
950 
951  if ( isPlayer( eAttacker ) )
952  eAttacker.pers["participation"]++;
953 
954  prevHealthRatio = self.health / self.maxhealth;
955 
956  if ( level.teamBased && isPlayer( eAttacker ) && (self != eAttacker) && (self.team == eAttacker.team) )
957  {
958  pixmarker( "BEGIN: PlayerDamage player" ); // profs automatically end when the function returns
959  if ( level.friendlyfire == 0 ) // no one takes damage
960  {
961  if ( weapon.forceDamageShellshockAndRumble )
962  {
963  self damageShellshockAndRumble( eAttacker, eInflictor, sWeapon, sMeansOfDeath, iDamage );
964  }
965  return;
966  }
967  else if ( level.friendlyfire == 1 ) // the friendly takes damage
968  {
969  // Make sure at least one point of damage is done
970  if ( iDamage < 1 )
971  iDamage = 1;
972 
973  //check for friendly fire at the begining of the match. apply the damage to the attacker only
974  if( level.friendlyFireDelay && level.friendlyFireDelayTime >= ( ( ( gettime() - level.startTime ) - level.discardTime ) / 1000 ) )
975  {
976  eAttacker.lastDamageWasFromEnemy = false;
977 
978  eAttacker.friendlydamage = true;
979  eAttacker finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex);
980  eAttacker.friendlydamage = undefined;
981  }
982  else
983  {
984  self.lastDamageWasFromEnemy = false;
985 
986  self finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex);
987  }
988  }
989  else if ( level.friendlyfire == 2 && isAlive( eAttacker ) ) // only the attacker takes damage
990  {
991  iDamage = int(iDamage * .5);
992 
993  // Make sure at least one point of damage is done
994  if(iDamage < 1)
995  iDamage = 1;
996 
997  eAttacker.lastDamageWasFromEnemy = false;
998 
999  eAttacker.friendlydamage = true;
1000  eAttacker finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex);
1001  eAttacker.friendlydamage = undefined;
1002  }
1003  else if ( level.friendlyfire == 3 && isAlive( eAttacker ) ) // both friendly and attacker take damage
1004  {
1005  iDamage = int(iDamage * .5);
1006 
1007  // Make sure at least one point of damage is done
1008  if ( iDamage < 1 )
1009  iDamage = 1;
1010 
1011  self.lastDamageWasFromEnemy = false;
1012  eAttacker.lastDamageWasFromEnemy = false;
1013 
1014  self finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex);
1015  eAttacker.friendlydamage = true;
1016  eAttacker finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex);
1017  eAttacker.friendlydamage = undefined;
1018  }
1019 
1020  friendly = true;
1021  pixmarker( "END: PlayerDamage player" );
1022  }
1023  else
1024  {
1025  // Make sure at least one point of damage is done
1026  if(iDamage < 1)
1027  iDamage = 1;
1028 
1029  if ( isdefined( eAttacker ) && isPlayer( eAttacker ) && allowedAssistWeapon( weapon ) )
1030  {
1031  self trackAttackerDamage( eAttacker, iDamage, sMeansOfDeath, weapon );
1032  }
1033 
1034  giveAttackerAndInflictorOwnerAssist( eAttacker, eInflictor, iDamage, sMeansOfDeath, weapon );
1035 
1036  if ( isdefined( eAttacker ) )
1037  level.lastLegitimateAttacker = eAttacker;
1038 
1039  if ( ( sMeansOfDeath == "MOD_GRENADE" || sMeansOfDeath == "MOD_GRENADE_SPLASH" ) && isdefined( eInflictor ) && isdefined( eInflictor.isCooked ) )
1040  self.wasCooked = getTime();
1041  else
1042  self.wasCooked = undefined;
1043 
1044  self.lastDamageWasFromEnemy = (isdefined( eAttacker ) && (eAttacker != self));
1045 
1046  if ( self.lastDamageWasFromEnemy )
1047  {
1048  if ( isplayer( eAttacker ) )
1049  {
1050  if ( isdefined ( eAttacker.damagedPlayers[ self.clientId ] ) == false )
1051  eAttacker.damagedPlayers[ self.clientId ] = spawnstruct();
1052 
1053  eAttacker.damagedPlayers[ self.clientId ].time = getTime();
1054  eAttacker.damagedPlayers[ self.clientId ].entity = self;
1055  }
1056  }
1057 
1058  self finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex);
1059 
1060  //self thread _missions::playerDamaged(eInflictor, eAttacker, iDamage, sMeansOfDeath, weapon, sHitLoc );
1061  }
1062 
1063  if ( isdefined(eAttacker) && isplayer( eAttacker ) && eAttacker != self )
1064  {
1065  if ( doDamageFeedback( weapon, eInflictor, iDamage, sMeansOfDeath ) )
1066  {
1067  if ( iDamage > 0 )
1068  {
1069  // the perk feedback should be shown only if the enemy is damaged and not killed.
1070  if ( self.health > 0 )
1071  {
1072  perkFeedback = doPerkFeedBack( self, weapon, sMeansOfDeath, eInflictor );
1073  }
1074 
1075  eAttacker thread damagefeedback::updateDamageFeedback( sMeansOfDeath, eInflictor, perkFeedback );
1076  }
1077  }
1078  }
1079 
1080  self.hasDoneCombat = true;
1081  }*/
1082 
1083 // if(self.sessionstate != "dead")
1084 // self _gametype_variants::onPlayerTakeDamage( eAttacker, eInflictor, weapon, iDamage, sMeansOfDeath );
1085 
1086  if ( isdefined( eAttacker ) && eAttacker != self && !friendly )
1087  level.useStartSpawns = false;
1088 
1089  pixbeginevent( "PlayerDamage log" );
1090 
1091  if(self.sessionstate != "dead")
1092  {
1093  lpselfnum = self getEntityNumber();
1094  lpselfname = self.name;
1095  lpselfteam = self.team;
1096  lpselfGuid = self getGuid();
1097  lpattackerteam = "";
1098  lpattackerorigin = ( 0, 0, 0 );
1099 
1100  if(isPlayer(eAttacker))
1101  {
1102  lpattacknum = eAttacker getEntityNumber();
1103  lpattackGuid = eAttacker getGuid();
1104  lpattackname = eAttacker.name;
1105  lpattackerteam = eAttacker.team;
1106  lpattackerorigin = eAttacker.origin;
1107 
1108  // Removed a blackbox print for "mpattacks" from here
1109  }
1110  else
1111  {
1112  lpattacknum = -1;
1113  lpattackGuid = "";
1114  lpattackname = "";
1115  lpattackerteam = "world";
1116 
1117  // Removed a blackbox print for "mpattacks" from here
1118  }
1119  logPrint("D;" + lpselfGuid + ";" + lpselfnum + ";" + lpselfteam + ";" + lpselfname + ";" + lpattackGuid + ";" + lpattacknum + ";" + lpattackerteam + ";" + lpattackname + ";" + weapon.name + ";" + iDamage + ";" + sMeansOfDeath + ";" + sHitLoc + "\n");
1120  }
1121 
1122  pixendevent(); // "END: PlayerDamage log"
1123 
1124  profilelog_endtiming( 6, "gs=" + game["state"] + " zom=" + SessionModeIsZombiesGame() );
1125 }
1126 
1128 {
1129  self.attackers = [];
1130  self.attackerData = [];
1131  self.attackerDamage = [];
1132  self.firstTimeDamaged = 0;
1133 }
1134 
1135 function ‪doDamageFeedback( weapon, eInflictor, iDamage, sMeansOfDeath )
1136 {
1137  if ( !isdefined( weapon ) )
1138  return false;
1139 
1140  if ( level.allowHitMarkers == 0 )
1141  return false;
1142 
1143  if ( level.allowHitMarkers == 1 ) // no tac grenades
1144  {
1145  if ( isdefined( sMeansOfDeath ) && isdefined( iDamage ) )
1146  {
1147  if ( ‪isTacticalHitMarker( weapon, sMeansOfDeath, iDamage ) )
1148  {
1149  return false;
1150  }
1151  }
1152  }
1153 
1154  return true;
1155 }
1156 
1157 function ‪isTacticalHitMarker( weapon, sMeansOfDeath, iDamage )
1158 {
1159 
1160  if ( ‪weapons::is_grenade( weapon ) )
1161  {
1162  if ( "Smoke Grenade" == weapon.offhandClass )
1163  {
1164  if ( sMeansOfDeath == "MOD_GRENADE_SPLASH" )
1165  return true;
1166  }
1167  else if ( iDamage == 1 )
1168  {
1169  return true;
1170  }
1171  }
1172  return false;
1173 }
1174 
1175 function ‪doPerkFeedBack( player, weapon, sMeansOfDeath, eInflictor )
1176 {
1177  perkFeedback = undefined;
1178  /*hasTacticalMask = _class::hasTacticalMask( player );
1179  hasFlakJacket = ( player HasPerk( "specialty_flakjacket" ) );
1180  //isExplosiveDamage = _class::isExplosiveDamage( weapon, sMeansOfDeath );
1181  isFlashOrStunDamage = weapon_utils::isFlashOrStunDamage( weapon, sMeansOfDeath );
1182 
1183  if ( isFlashOrStunDamage && hasTacticalMask )
1184  {
1185  perkFeedback = "tacticalMask";
1186  }
1187  else if ( isExplosiveDamage && hasFlakJacket && !weapon.ignoresFlakJacket && ( !isAIKillstreakDamage( weapon, eInflictor ) ) )
1188  {
1189  perkFeedback = "flakjacket";
1190  }
1191  */
1192  return perkFeedback;
1193 }
1194 
1195 function ‪isAIKillstreakDamage( weapon, eInflictor )
1196 {
1197  if ( weapon.isAIKillstreakDamage )
1198  {
1199  if ( weapon.name != "ai_tank_drone_rocket" || isdefined( eInflictor.firedByAI ) )
1200  {
1201  return true;
1202  }
1203  }
1204 
1205  return false;
1206 }
1207 
1208 function ‪finishPlayerDamageWrapper( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal )
1209 {
1210  pixbeginevent("finishPlayerDamageWrapper");
1211 
1212  if( !level.console && iDFlags & level.iDFLAGS_PENETRATION && isplayer ( eAttacker ) )
1213  {
1214  eAttacker AddPlayerStat( "penetration_shots", 1 );
1215  }
1216 
1217  if ( GetDvarString( "scr_csmode" ) != "" )
1218  self shellShock( "damage", 0.2 );
1219 
1220  self ‪damageShellshockAndRumble( eAttacker, eInflictor, weapon, sMeansOfDeath, iDamage );
1221 
1222  self ‪ability_power::power_loss_event_took_damage( eAttacker, eInflictor, weapon, sMeansOfDeath, iDamage );
1223 
1224  self finishPlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal );
1225 
1226  pixendevent();
1227 }
1228 
1229 function ‪allowedAssistWeapon( weapon )
1230 {
1231  //if ( !_killstreaks::isKillstreakWeapon( weapon ) )
1232  return true;
1233 
1234  //if (_killstreaks::isKillstreakWeaponAssistAllowed( weapon ) )
1235  // return true;
1236 
1237  //return false;
1238 }
1239 
1240 function ‪Callback_PlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration)
1241 {
1242  profilelog_begintiming( 7, "ship" );
1243 
1244  self endon( "spawned" );
1245  self notify( "killed_player" );
1246 
1247  self ‪flagsys::clear( "loadout_given" );
1248 
1249  if ( self.sessionteam == "spectator" )
1250  return;
1251 
1252  if ( game["state"] == "postgame" )
1253  return;
1254 
1255  self needsRevive( false );
1256 
1257  if ( isdefined( self.burning ) && self.burning == true )
1258  {
1259  self setburn( 0 );
1260  }
1261 
1262  self.suicide = false;
1263 
1264  if ( isdefined( level.takeLivesOnDeath ) && ( level.takeLivesOnDeath == true ) )
1265  {
1266  if ( self.pers["lives"] )
1267  {
1268  self.pers["lives"]--;
1269  if ( self.pers["lives"] == 0 )
1270  {
1271  level notify( "player_eliminated" );
1272  self notify( "player_eliminated" );
1273  }
1274 
1275  }
1276  }
1277 
1278  self thread ‪globallogic_audio::flushGroupDialogOnPlayer( "item_destroyed" );
1279 
1280  weapon = ‪updateWeapon( eInflictor, weapon );
1281 
1282  pixbeginevent( "PlayerKilled pre constants" );
1283 
1284  wasInLastStand = false;
1285  deathTimeOffset = 0;
1286  lastWeaponBeforeDroppingIntoLastStand = undefined;
1287  attackerStance = undefined;
1288  self.lastStandThisLife = undefined;
1289  self.vAttackerOrigin = undefined;
1290 
1291  if ( isdefined( self.useLastStandParams ) )
1292  {
1293  self.useLastStandParams = undefined;
1294 
1295  assert( isdefined( self.lastStandParams ) );
1296  if ( !level.teamBased || ( !isdefined( attacker ) || !isplayer( attacker ) || attacker.team != self.team || attacker == self ) )
1297  {
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;
1308 
1309  // self thread _battlechatter_mp::perkSpecificBattleChatter( "secondchance" );
1310 
1311  if ( isdefined( self.previousPrimary ) )
1312  {
1313  wasInLastStand = true;
1314  lastWeaponBeforeDroppingIntoLastStand = self.previousPrimary;
1315  }
1316  }
1317  self.lastStandParams = undefined;
1318  }
1319 
1320  bestPlayer = undefined;
1321  bestPlayerMeansOfDeath = undefined;
1322  obituaryMeansOfDeath = undefined;
1323  bestPlayerWeapon = undefined;
1324  obituaryWeapon = undefined;
1325 
1326  if ( (!isdefined( attacker ) || attacker.classname == "trigger_hurt" || attacker.classname == "worldspawn" || ( isdefined( attacker.isMagicBullet ) && attacker.isMagicBullet == true ) || attacker == self ) && isdefined( self.attackers ) )
1327  {
1328  if ( !isdefined(bestPlayer) )
1329  {
1330  for ( i = 0; i < self.attackers.size; i++ )
1331  {
1332  player = self.attackers[i];
1333  if ( !isdefined( player ) )
1334  continue;
1335 
1336  if (!isdefined( self.attackerDamage[ player.clientId ] ) || ! isdefined( self.attackerDamage[ player.clientId ].damage ) )
1337  continue;
1338 
1339  if ( player == self || (level.teamBased && player.team == self.team ) )
1340  continue;
1341 
1342  if ( self.attackerDamage[ player.clientId ].lasttimedamaged + 2500 < getTime() )
1343  continue;
1344 
1345  if ( !‪allowedAssistWeapon( self.attackerDamage[ player.clientId ].weapon ) )
1346  continue;
1347 
1348  if ( self.attackerDamage[ player.clientId ].damage > 1 && ! isdefined( bestPlayer ) )
1349  {
1350  bestPlayer = player;
1351  bestPlayerMeansOfDeath = self.attackerDamage[ player.clientId ].meansOfDeath;
1352  bestPlayerWeapon = self.attackerDamage[ player.clientId ].weapon;
1353  }
1354  else if ( isdefined( bestPlayer ) && self.attackerDamage[ player.clientId ].damage > self.attackerDamage[ bestPlayer.clientId ].damage )
1355  {
1356  bestPlayer = player;
1357  bestPlayerMeansOfDeath = self.attackerDamage[ player.clientId ].meansOfDeath;
1358  bestPlayerWeapon = self.attackerDamage[ player.clientId ].weapon;
1359  }
1360  }
1361  }
1362  if ( isdefined ( bestPlayer ) )
1363  {
1364  self RecordKillModifier("assistedsuicide");
1365  }
1366  }
1367 
1368  if ( isdefined ( bestPlayer ) )
1369  {
1370  attacker = bestPlayer;
1371  obituaryMeansOfDeath = bestPlayerMeansOfDeath;
1372  obituaryWeapon = bestPlayerWeapon;
1373  }
1374 
1375  if ( isplayer( attacker ) )
1376  attacker.damagedPlayers[self.clientid] = undefined;
1377 
1378  if( ‪globallogic_utils::isHeadShot( weapon, sHitLoc, sMeansOfDeath, eInflictor ) && isPlayer( attacker ) )
1379  {
1380  attacker playLocalSound( "prj_bullet_impact_headshot_helmet_nodie_2d" );
1381  //attacker playLocalSound( "prj_bullet_impact_headshot_2d" );
1382 
1383  sMeansOfDeath = "MOD_HEAD_SHOT";
1384  }
1385 
1386  self.deathTime = getTime();
1387 
1388  attacker = ‪updateAttacker( attacker, weapon );
1389  eInflictor = ‪updateInflictor( eInflictor );
1390 
1391  sMeansOfDeath = ‪updateMeansOfDeath( weapon, sMeansOfDeath );
1392 
1393  if ( isdefined(self.hasRiotShieldEquipped) && (self.hasRiotShieldEquipped==true) )
1394  {
1395  self DetachShieldModel( level.carriedShieldModel, "tag_weapon_left" );
1396  self.hasRiotShield = false;
1397  self.hasRiotShieldEquipped = false;
1398  }
1399 
1400  self thread ‪updateGlobalBotKilledCounter();
1401 
1402  // Don't increment weapon stats for team kills or deaths
1403  if ( isPlayer( attacker ) && attacker != self && ( !level.teamBased || ( level.teamBased && self.team != attacker.team ) ) )
1404  {
1405  self AddWeaponStat( weapon, "deaths", 1 );
1406 
1407  if ( wasInLastStand && isdefined( lastWeaponBeforeDroppingIntoLastStand ) )
1408  weapon = lastWeaponBeforeDroppingIntoLastStand;
1409  else
1410  weapon = self.lastdroppableweapon;
1411 
1412  if ( isdefined( weapon ) )
1413  {
1414  self AddWeaponStat( weapon, "deathsDuringUse", 1 );
1415  }
1416 
1417  if ( sMeansOfDeath != "MOD_FALLING" )
1418  {
1419  attacker AddWeaponStat( weapon, "kills", 1 );
1420  }
1421 
1422  if ( sMeansOfDeath == "MOD_HEAD_SHOT" )
1423  {
1424  attacker AddWeaponStat( weapon, "headshots", 1 );
1425  }
1426  }
1427 
1428  if ( !isdefined( obituaryMeansOfDeath ) )
1429  obituaryMeansOfDeath = sMeansOfDeath;
1430  if ( !isdefined( obituaryWeapon ) )
1431  obituaryWeapon = weapon;
1432 
1433 
1434  if ( !isplayer( attacker ) || ( self ‪util::IsEnemyPlayer( attacker ) == false ) )
1435  {
1436  level notify( "reset_obituary_count" );
1437  level.lastObituaryPlayerCount = 0;
1438  level.lastObituaryPlayer = undefined;
1439  }
1440  else
1441  {
1442  if ( isdefined( level.lastObituaryPlayer ) && level.lastObituaryPlayer == attacker )
1443  {
1444  level.lastObituaryPlayerCount++;
1445  }
1446  else
1447  {
1448  level notify( "reset_obituary_count" );
1449  level.lastObituaryPlayer = attacker;
1450  level.lastObituaryPlayerCount = 1;
1451  }
1452 
1453  if ( level.lastObituaryPlayerCount >= 4 )
1454  {
1455  level notify( "reset_obituary_count" );
1456  level.lastObituaryPlayerCount = 0;
1457  level.lastObituaryPlayer = undefined;
1458  }
1459  }
1460 
1461  overrideEntityCamera = false;//_killstreaks::shouldOverrideEntityCameraInDemo( weapon );
1462 
1463  // send out an obituary message to all clients about the kill
1464  if( level.teamBased && isdefined( attacker.pers ) && self.team == attacker.team && obituaryMeansOfDeath == "MOD_GRENADE" && level.friendlyfire == 0 )
1465  {
1466  obituary(self, self, obituaryWeapon, obituaryMeansOfDeath);
1467  ‪demo::bookmark( "kill", gettime(), self, self, 0, eInflictor, overrideEntityCamera );
1468  }
1469  else
1470  {
1471  obituary(self, attacker, obituaryWeapon, obituaryMeansOfDeath);
1472  ‪demo::bookmark( "kill", gettime(), attacker, self, 0, eInflictor, overrideEntityCamera );
1473  }
1474 
1475  if ( !level.inGracePeriod )
1476  {
1477  self ‪weapons::dropScavengerForDeath( attacker );
1478  self ‪weapons::dropWeaponForDeath( attacker );
1479  }
1480 
1481  ‪spawnlogic::deathOccured(self, attacker);
1482 
1483  self.sessionstate = "dead";
1484  self.statusicon = "hud_status_dead";
1485 
1486  self.pers["weapon"] = undefined;
1487 
1488  self.killedPlayersCurrent = [];
1489 
1490  self.deathCount++;
1491 
1492  if( !isdefined( self.switching_teams ) )
1493  {
1494  // if team killed we reset kill streak, but dont count death and death streak
1495  if ( isPlayer( attacker ) && level.teamBased && ( attacker != self ) && ( self.team == attacker.team ) )
1496  {
1497 
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 );
1503  }
1504  else
1505  {
1506  self ‪globallogic_score::incPersStat( "deaths", 1, true, true );
1507  self.deaths = self ‪globallogic_score::getPersStat( "deaths" );
1508  self UpdateStatRatio( "kdratio", "kills", "deaths" );
1509 
1510  if( self.pers["cur_kill_streak"] > self.pers["best_kill_streak"] )
1511  self.pers["best_kill_streak"] = self.pers["cur_kill_streak"];
1512 
1513  // need to keep the current killstreak to see if this was a buzzkill later
1514  self.pers["kill_streak_before_death"] = self.pers["cur_kill_streak"];
1515 
1516 
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 );
1522 
1523  self.cur_death_streak++;
1524 
1525  if ( self.cur_death_streak > self.death_streak )
1526  {
1527  if ( level.rankedMatch )
1528  {
1529  self setDStat( "HighestStats", "death_streak", self.cur_death_streak );
1530  }
1531  self.death_streak = self.cur_death_streak;
1532  }
1533 
1534  if( self.cur_death_streak >= GetDvarint( "perk_deathStreakCountRequired" ) )
1535  {
1536  self enabledeathstreak();
1537  }
1538  }
1539  }
1540  else
1541  {
1542  self.pers["totalKillstreakCount"] = 0;
1543  self.pers["killstreaksEarnedThisKillstreak"] = 0;
1544  }
1545 
1546  lpselfnum = self getEntityNumber();
1547  lpselfname = self.name;
1548  lpattackGuid = "";
1549  lpattackname = "";
1550  lpselfteam = self.team;
1551  lpselfguid = self getGuid();
1552  lpattackteam = "";
1553  lpattackorigin = ( 0, 0, 0 );
1554 
1555  lpattacknum = -1;
1556 
1557  //check if we should award assist points
1558  awardAssists = false;
1559 
1560  pixendevent(); // "PlayerKilled pre constants" );
1561 
1563 
1564  if( isPlayer( attacker ) )
1565  {
1566  lpattackGuid = attacker getGuid();
1567  lpattackname = attacker.name;
1568  lpattackteam = attacker.team;
1569  lpattackorigin = attacker.origin;
1570 
1571  if ( attacker == self ) // killed himself
1572  {
1573  doKillcam = false;
1574 
1575  // switching teams
1576  /*
1577  if ( isdefined( self.switching_teams ) )
1578  {
1579  if ( !level.teamBased && ( isdefined( level.teams[ self.leaving_team ] ) && isdefined( level.teams[ self.joining_team ] ) && level.teams[ self.leaving_team ] != level.teams[ self.joining_team ] ) )
1580  {
1581  playerCounts = self _teams::CountPlayers();
1582  playerCounts[self.leaving_team]--;
1583  playerCounts[self.joining_team]++;
1584 
1585  if( (playerCounts[self.joining_team] - playerCounts[self.leaving_team]) > 1 )
1586  {
1587  // self thread _rank::giveRankXP( "suicide" );
1588  self globallogic_score::incPersStat( "suicides", 1 );
1589  self.suicides = self globallogic_score::getPersStat( "suicides" );
1590  }
1591  }
1592  }
1593  else
1594  */
1595  {
1596  self ‪globallogic_score::incPersStat( "suicides", 1 );
1597  self.suicides = self ‪globallogic_score::getPersStat( "suicides" );
1598 
1599  if ( sMeansOfDeath == "MOD_SUICIDE" && sHitLoc == "none" && self.throwingGrenade )
1600  {
1601  self.lastGrenadeSuicideTime = gettime();
1602  }
1603 
1604  //Check for player death related battlechatter
1605  // thread _battlechatter_mp::onPlayerSuicideOrTeamKill( self, "suicide" ); //Play suicide battlechatter
1606 
1607  //check if assist points should be awarded
1608  awardAssists = true;
1609  self.suicide = true;
1610  }
1611 
1612  if( isdefined( self.friendlydamage ) )
1613  {
1614  self iPrintLn(&"MP_FRIENDLY_FIRE_WILL_NOT");
1615  if ( level.teamKillPointLoss )
1616  {
1617  scoreSub = self [[level.getTeamKillScore]]( eInflictor, attacker, sMeansOfDeath, weapon);
1619  }
1620  }
1621  }
1622  else
1623  {
1624  pixbeginevent( "PlayerKilled attacker" );
1625 
1626  lpattacknum = attacker getEntityNumber();
1627 
1628  doKillcam = true;
1629 
1630  // self thread _gametype_variants::playerKilled( attacker );
1631 
1632  if ( level.teamBased && self.team == attacker.team && sMeansOfDeath == "MOD_GRENADE" && level.friendlyfire == 0 )
1633  {
1634  }
1635  else if ( level.teamBased && self.team == attacker.team ) // killed by a friendly
1636  {
1637  if ( !‪IgnoreTeamKills( weapon, sMeansOfDeath ) )
1638  {
1639  teamkill_penalty = self [[level.getTeamKillPenalty]]( eInflictor, attacker, sMeansOfDeath, weapon);
1640 
1641  attacker ‪globallogic_score::incPersStat( "teamkills_nostats", teamkill_penalty, false );
1642  attacker ‪globallogic_score::incPersStat( "teamkills", 1 ); //save team kills to player stats
1643  attacker.teamkillsThisRound++;
1644 
1645  if ( level.teamKillPointLoss )
1646  {
1647  scoreSub = self [[level.getTeamKillScore]]( eInflictor, attacker, sMeansOfDeath, weapon);
1649  }
1650 
1651  if ( ‪globallogic_utils::getTimePassed() < 5000 )
1652  teamKillDelay = 1;
1653  else if ( attacker.pers["teamkills_nostats"] > 1 && ‪globallogic_utils::getTimePassed() < (8000 + (attacker.pers["teamkills_nostats"] * 1000)) )
1654  teamKillDelay = 1;
1655  else
1656  teamKillDelay = attacker ‪TeamKillDelay();
1657 
1658  if ( teamKillDelay > 0 )
1659  {
1660  attacker.teamKillPunish = true;
1661  attacker ‪suicide();
1662 
1663  if ( attacker ‪ShouldTeamKillKick(teamKillDelay) )
1664  {
1665  attacker ‪TeamKillKick();
1666  }
1667 
1668  attacker thread ‪reduceTeamKillsOverTime();
1669  }
1670 
1671  // //Play teamkill battlechatter
1672  // if( isPlayer( attacker ) )
1673  // thread _battlechatter_mp::onPlayerSuicideOrTeamKill( attacker, "teamkill" );
1674  }
1675  }
1676  else
1677  {
1678  ‪globallogic_score::incTotalKills(attacker.team);
1679 
1680  attacker thread ‪globallogic_score::giveKillStats( sMeansOfDeath, weapon, self );
1681 
1682  if ( isAlive( attacker ) )
1683  {
1684  pixbeginevent("killstreak");
1685 
1686  if ( !isdefined( eInflictor ) || !isdefined( eInflictor.requiredDeathCount ) || attacker.deathCount == eInflictor.requiredDeathCount )
1687  {
1688  shouldGiveKillstreak = false;//_killstreaks::shouldGiveKillstreak( weapon );
1689  //attacker thread _properks::earnedAKill();
1690 
1691  // if ( shouldGiveKillstreak )
1692  // {
1693  // attacker _killstreaks::addToKillstreakCount(eapon);
1694  // }
1695 
1696  attacker.pers["cur_total_kill_streak"]++;
1697  attacker setplayercurrentstreak( attacker.pers["cur_total_kill_streak"] );
1698 
1699  //Kills gotten through killstreak weapons should not the players killstreak
1700  if ( isdefined( level.killstreaks ) && shouldGiveKillstreak )
1701  {
1702  attacker.pers["cur_kill_streak"]++;
1703 
1704  // if ( !isdefined( level.usingMomentum ) || !level.usingMomentum )
1705  // {
1706  // attacker thread _killstreaks::giveKillstreakForStreak();
1707  // }
1708  }
1709  }
1710 
1711  // if( isPlayer( attacker ) )
1712  // self thread _battlechatter_mp::onPlayerKillstreak( attacker );
1713 
1714  pixendevent(); // "killstreak"
1715  }
1716 
1717  if ( attacker.pers["cur_kill_streak"] > attacker.kill_streak )
1718  {
1719  if ( level.rankedMatch )
1720  {
1721  attacker setDStat( "HighestStats", "kill_streak", attacker.pers["totalKillstreakCount"] );
1722  }
1723  attacker.kill_streak = attacker.pers["cur_kill_streak"];
1724  }
1725 
1726  /* if ( attacker.pers["cur_kill_streak"] > attacker.gametype_kill_streak )
1727  {
1728  attacker _persistence::statSetWithGametype( "kill_streak", attacker.pers["cur_kill_streak"] );
1729  attacker.gametype_kill_streak = attacker.pers["cur_kill_streak"];
1730  }*/
1731 
1732  killstreak = undefined;//_killstreaks::getKillstreakForWeapon( weapon );
1733 
1734  attacker thread ‪globallogic_score::trackAttackerKill( self.‪name, self.pers["rank"], self.pers["rankxp"], self.pers["prestige"], self getXuid() );
1735 
1736  attackerName = attacker.name;
1737  self thread ‪globallogic_score::trackAttackeeDeath( attackerName, attacker.pers["rank"], attacker.pers["rankxp"], attacker.pers["prestige"], attacker getXuid() );
1738  // self thread _medals::setLastKilledBy( attacker );
1739 
1740  attacker thread ‪globallogic_score::incKillstreakTracker( weapon );
1741 
1742  // to prevent spectator gain score for team-spectator after throwing a granade and killing someone before he switched
1743  if ( level.teamBased && attacker.team != "spectator")
1744  {
1745  // dog score for team
1746  if( isai(Attacker) )
1747  ‪globallogic_score::giveTeamScore( "kill", attacker.team, attacker, self );
1748  else
1749  ‪globallogic_score::giveTeamScore( "kill", attacker.team, attacker, self );
1750  }
1751 
1752  scoreSub = level.deathPointLoss;
1753  if ( scoreSub != 0 )
1754  {
1756  }
1757 
1758  level thread ‪playKillBattleChatter( attacker, weapon, self );
1759 
1760  if ( level.teamBased )
1761  {
1762  //check if assist points should be awarded
1763  awardAssists = true;
1764  }
1765  }
1766 
1767  pixendevent(); //"PlayerKilled attacker"
1768  }
1769  }
1770  else if ( isdefined( attacker ) && ( attacker.classname == "trigger_hurt" || attacker.classname == "worldspawn" ) )
1771  {
1772  doKillcam = false;
1773 
1774  lpattacknum = -1;
1775  lpattackguid = "";
1776  lpattackname = "";
1777  lpattackteam = "world";
1778 
1779  self ‪globallogic_score::incPersStat( "suicides", 1 );
1780  self.suicides = self ‪globallogic_score::getPersStat( "suicides" );
1781 
1782  //Check for player death related battlechatter
1783  //thread _battlechatter_mp::onPlayerSuicideOrTeamKill( self, "suicide" ); //Play suicide battlechatter
1784 
1785  //check if assist points should be awarded
1786  awardAssists = true;
1787 
1788  }
1789  else
1790  {
1791  doKillcam = false;
1792 
1793  lpattacknum = -1;
1794  lpattackguid = "";
1795  lpattackname = "";
1796  lpattackteam = "world";
1797 
1798  if ( isdefined( eInflictor ) && isdefined( eInflictor.killCamEnt ) )
1799  {
1800  doKillcam = true;
1801  lpattacknum = self getEntityNumber();
1802  }
1803 
1804  // even if the attacker isn't a player, it might be on a team
1805  if ( isdefined( attacker ) && isdefined( attacker.team ) && ( isdefined( level.teams[attacker.team] ) ) )
1806  {
1807  if ( attacker.team != self.team )
1808  {
1809  if ( level.teamBased )
1810  ‪globallogic_score::giveTeamScore( "kill", attacker.team, attacker, self );
1811  }
1812  }
1813  //check if assist points should be awarded
1814  awardAssists = true;
1815 
1816  }
1817 
1818  pixbeginevent( "PlayerKilled post constants" );
1819 
1820  self.lastAttacker = attacker;
1821  self.lastDeathPos = self.origin;
1822 
1823  if ( isdefined( attacker ) && isPlayer( attacker ) && attacker != self && (!level.teambased || attacker.team != self.team) )
1824  {
1825  }
1826  else
1827  {
1828 
1829  self notify("playerKilledChallengesProcessed");
1830  }
1831 
1832  if ( isdefined ( self.attackers ))
1833  self.attackers = [];
1834  if( isPlayer( attacker ) )
1835  {
1836  // Removed a blackbox print for "mpattacks" from here
1837  }
1838  else
1839  {
1840  // Removed a blackbox print for "mpattacks" from here
1841  }
1842 
1843  logPrint( "K;" + lpselfguid + ";" + lpselfnum + ";" + lpselfteam + ";" + lpselfname + ";" + lpattackguid + ";" + lpattacknum + ";" + lpattackteam + ";" + lpattackname + ";" + weapon.name + ";" + iDamage + ";" + sMeansOfDeath + ";" + sHitLoc + "\n" );
1844  attackerString = "none";
1845  if ( isPlayer( attacker ) ) // attacker can be the worldspawn if it's not a player
1846  attackerString = attacker getXuid() + "(" + lpattackname + ")";
1847 
1848 
1849  level thread ‪globallogic::updateTeamStatus();
1850 
1851  killcamentity = self ‪getKillcamEntity( attacker, eInflictor, weapon );
1852  killcamentityindex = -1;
1853  killcamentitystarttime = 0;
1854 
1855  if ( isdefined( killcamentity ) )
1856  {
1857  killcamentityindex = killcamentity getEntityNumber(); // must do this before any waiting lest the entity be deleted
1858  if ( isdefined( killcamentity.startTime ) )
1859  {
1860  killcamentitystarttime = killcamentity.startTime;
1861  }
1862  else
1863  {
1864  killcamentitystarttime = killcamentity.birthtime;
1865  }
1866  if ( !isdefined( killcamentitystarttime ) )
1867  killcamentitystarttime = 0;
1868  }
1869 
1870  // no killcam if the player is still involved with a killstreak
1871  if ( isdefined(self.killstreak_waitamount) && self.killstreak_waitamount > 0 )
1872  doKillcam = false;
1873 
1875 
1876  died_in_vehicle= false;
1877  if (isdefined(self.diedOnVehicle))
1878  {
1879  died_in_vehicle = self.diedOnVehicle; // only works when vehicle blows up
1880  }
1881  pixendevent(); //"END: PlayerKilled post constants"
1882 
1883  pixbeginevent( "PlayerKilled body and gibbing" );
1884  if ( !died_in_vehicle )
1885  {
1886  vAttackerOrigin = undefined;
1887  if ( isdefined( attacker ) )
1888  vAttackerOrigin = attacker.origin;
1889 
1890  ragdoll_now = false;
1891  if( isdefined(self.usingvehicle) && self.usingvehicle && isdefined(self.vehicleposition) && self.vehicleposition == 1 )
1892  ragdoll_now = true;
1893 
1894  body = self clonePlayer( deathAnimDuration, weapon, attacker );
1895  self ‪createDeadBody( iDamage, sMeansOfDeath, weapon, sHitLoc, vDir, vAttackerOrigin, deathAnimDuration, eInflictor, ragdoll_now, body );
1896  }
1897  pixendevent();// "END: PlayerKilled body and gibbing"
1898 
1899  thread ‪globallogic_spawn::spawnQueuedClient( self.team, attacker );
1900 
1901  self.switching_teams = undefined;
1902  self.joining_team = undefined;
1903  self.leaving_team = undefined;
1904 
1905  self thread [[level.onPlayerKilled]](eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration);
1906 
1907  for ( iCB = 0; iCB < level.onPlayerKilledExtraUnthreadedCBs.size; iCB++ )
1908  {
1909  self [[ level.onPlayerKilledExtraUnthreadedCBs[ iCB ] ]](
1910  eInflictor,
1911  attacker,
1912  iDamage,
1913  sMeansOfDeath,
1914  weapon,
1915  vDir,
1916  sHitLoc,
1917  psOffsetTime,
1918  deathAnimDuration );
1919  }
1920 
1921  self.wantSafeSpawn = false;
1922  perks = [];
1923  // perks = globallogic::getPerks( attacker );
1924  killstreaks = globallogic::getKillstreaks( attacker );
1925 
1926  if( !isdefined( self.killstreak_waitamount ) )
1927  {
1928  // start the prediction now so the client gets updates while waiting to spawn
1929  self thread [[level.spawnPlayerPrediction]]();
1930  }
1931 
1932  profilelog_endtiming( 7, "gs=" + game["state"] + " zom=" + SessionModeIsZombiesGame() );
1933 
1934  // let the player watch themselves die
1935  wait ( 0.25 );
1936 
1937  self.cancelKillcam = false;
1938  //self thread _killcam::cancelKillCamOnUse();
1939 
1940  defaultPlayerDeathWatchTime = 1.75;
1941  if ( sMeansOfDeath == "MOD_MELEE_ASSASSINATE" || 0 > weapon.deathCamTime )
1942  {
1943  defaultPlayerDeathWatchTime = (deathAnimDuration * 0.001) + 0.5;
1944  }
1945  else if ( 0 < weapon.deathCamTime )
1946  {
1947  defaultPlayerDeathWatchTime = weapon.deathCamTime;
1948  }
1949 
1950  if ( isdefined ( level.overridePlayerDeathWatchTimer ) )
1951  {
1952  defaultPlayerDeathWatchTime = [[level.overridePlayerDeathWatchTimer]]( defaultPlayerDeathWatchTime );
1953  }
1954 
1955  ‪globallogic_utils::waitForTimeOrNotifies( defaultPlayerDeathWatchTime );
1956 
1957  self notify ( "death_delay_finished" );
1958 
1959  if ( game["state"] != "playing" )
1960  {
1961  // if no longer playing then this was probably the kill that ended the round
1962  // store off the killcam info
1963 // level thread _killcam::startFinalKillcam( lpattacknum, self getEntityNumber(), killcamentity, killcamentityindex, killcamentitystarttime, weapon, self.deathTime, deathTimeOffset, psOffsetTime, perks, killstreaks, attacker );
1964  return;
1965  }
1966 
1967  self.respawnTimerStartTime = gettime();
1968 
1969  if ( !self.cancelKillcam && doKillcam && level.killcam )
1970  {
1971  livesLeft = !(level.numLives && !self.pers["lives"]);
1972  timeUntilSpawn = ‪globallogic_spawn::TimeUntilSpawn( true );
1973  willRespawnImmediately = livesLeft && (timeUntilSpawn <= 0) && !level.playerQueuedRespawn;
1974 
1975  //self _killcam::killcam( lpattacknum, self getEntityNumber(), killcamentity, killcamentityindex, killcamentitystarttime, weapon, self.deathTime, deathTimeOffset, psOffsetTime, willRespawnImmediately, globallogic_utils::timeUntilRoundEnd(), perks, killstreaks, attacker );
1976  }
1977 
1978  if ( game["state"] != "playing" )
1979  {
1980  self.sessionstate = "dead";
1981  self.spectatorclient = -1;
1982  self.killcamtargetentity = -1;
1983  self.killcamentity = -1;
1984  self.archivetime = 0;
1985  self.psoffsettime = 0;
1986  return;
1987  }
1988 
1990 
1991  // class may be undefined if we have changed teams
1992  if ( ‪globallogic_utils::isValidClass( self.curClass ) )
1993  {
1994  timePassed = undefined;
1995 
1996  if ( isdefined( self.respawnTimerStartTime ) )
1997  {
1998  timePassed = (gettime() - self.respawnTimerStartTime) / 1000;
1999  }
2000 
2001  self thread [[level.spawnClient]]( timePassed );
2002  self.respawnTimerStartTime = undefined;
2003  }
2004 }
2005 
2007 {
2008  if ( isdefined( self.pers["isBot"] ) )
2009  {
2010  level.globalLarrysKilled++;
2011  }
2012 }
2013 
2014 
2016 {
2017  if( isdefined( self.killstreak_waitamount ) )
2018  {
2019  starttime = gettime();
2020  waitTime = self.killstreak_waitamount * 1000;
2021 
2022  while( (gettime() < (starttime+waitTime)) && isdefined( self.killstreak_waitamount ) )
2023  {
2024  wait( 0.1 );
2025  }
2026 
2027  //Plus a small amount so we can see our dead body
2028  wait( 2.0 );
2029 
2030  self.killstreak_waitamount = undefined;
2031  }
2032 }
2033 
2035 {
2036  self ‪globallogic_score::incPersStat( "sessionbans", 1 );
2037 
2038  self endon("disconnect");
2039  waittillframeend;
2040 
2041  //for test purposes lets lock them out of certain game type for 2mins
2042 
2043  playlistbanquantum = ‪tweakables::getTweakableValue( "team", "teamkillerplaylistbanquantum" );
2044  playlistbanpenalty = ‪tweakables::getTweakableValue( "team", "teamkillerplaylistbanpenalty" );
2045  if ( playlistbanquantum > 0 && playlistbanpenalty > 0 )
2046  {
2047  timeplayedtotal = self GetDStat( "playerstatslist", "time_played_total", "StatValue" );
2048  minutesplayed = timeplayedtotal / 60;
2049 
2050  freebees = 2;
2051 
2052  banallowance = int( floor(minutesplayed / playlistbanquantum) ) + freebees;
2053 
2054  if ( self.sessionbans > banallowance )
2055  {
2056  self SetDStat( "playerstatslist", "gametypeban", "StatValue", timeplayedtotal + (playlistbanpenalty * 60) );
2057  }
2058  }
2059 
2060  if ( self ‪util::is_bot() )
2061  {
2062  level notify( "bot_kicked", self.team );
2063  }
2064 
2065  ban( self getentitynumber() );
2067 }
2068 
2070 {
2071  teamkills = self.pers["teamkills_nostats"];
2072  if ( level.minimumAllowedTeamKills < 0 || teamkills <= level.minimumAllowedTeamKills )
2073  return 0;
2074 
2075  exceeded = (teamkills - level.minimumAllowedTeamKills);
2076  return level.teamKillSpawnDelay * exceeded;
2077 }
2078 
2079 
2080 function ‪ShouldTeamKillKick(teamKillDelay)
2081 {
2082  if ( teamKillDelay && ( level.minimumAllowedTeamKills >= 0 ) )
2083  {
2084  // if its more then 5 seconds into the match and we have a delay then just kick them
2085  if ( ‪globallogic_utils::getTimePassed() >= 5000 )
2086  {
2087  return true;
2088  }
2089 
2090  // if its under 5 seconds into the match only kick them if they have killed more then one players so far
2091  if ( self.pers["teamkills_nostats"] > 1 )
2092  {
2093  return true;
2094  }
2095  }
2096 
2097  return false;
2098 }
2099 
2101 {
2102  timePerOneTeamkillReduction = 20.0;
2103  reductionPerSecond = 1.0 / timePerOneTeamkillReduction;
2104 
2105  while(1)
2106  {
2107  if ( isAlive( self ) )
2108  {
2109  self.pers["teamkills_nostats"] -= reductionPerSecond;
2110  if ( self.pers["teamkills_nostats"] < level.minimumAllowedTeamKills )
2111  {
2112  self.pers["teamkills_nostats"] = level.minimumAllowedTeamKills;
2113  break;
2114  }
2115  }
2116  wait 1;
2117  }
2118 }
2119 
2120 
2121 function ‪IgnoreTeamKills( weapon, sMeansOfDeath )
2122 {
2123  if( SessionModeIsZombiesGame() )
2124  return true;
2125 
2126  if ( sMeansOfDeath == "MOD_MELEE" )
2127  return false;
2128 
2129  if ( weapon.name == "briefcase_bomb" )
2130  return true;
2131 
2132  if ( weapon.name == "supplydrop" )
2133  return true;
2134 
2135  return false;
2136 }
2137 
2138 
2139 function ‪Callback_PlayerLastStand( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
2140 {
2141  //_laststand::playerlaststand(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration );
2142 }
2143 
2144 
2145 function ‪damageShellshockAndRumble( eAttacker, eInflictor, weapon, sMeansOfDeath, iDamage )
2146 {
2147  self thread ‪weapons::onWeaponDamage( eAttacker, eInflictor, weapon, sMeansOfDeath, iDamage );
2148  self PlayRumbleOnEntity( "damage_heavy" );
2149 }
2150 
2151 
2152 function ‪createDeadBody( iDamage, sMeansOfDeath, weapon, sHitLoc, vDir, vAttackerOrigin, deathAnimDuration, eInflictor, ragdoll_jib, body )
2153 {
2154  if ( sMeansOfDeath == "MOD_HIT_BY_OBJECT" && self GetStance() == "prone" )
2155  {
2156  self.body = body;
2157  // if ( !isdefined( self.switching_teams ) )
2158  // thread _deathicons::addDeathicon( body, self, self.team, 5.0 );
2159 
2160  return;
2161  }
2162 
2163  if ( isdefined( level.ragdoll_override ) && self [[level.ragdoll_override]]() )
2164  {
2165  return;
2166  }
2167 
2168  if ( ragdoll_jib || self isOnLadder() || self isMantling() || sMeansOfDeath == "MOD_CRUSH" || sMeansOfDeath == "MOD_HIT_BY_OBJECT" )
2169  body startRagDoll();
2170 
2171  if ( !self IsOnGround() )
2172  {
2173  if ( GetDvarint( "scr_disable_air_death_ragdoll" ) == 0 )
2174  {
2175  body startRagDoll();
2176  }
2177  }
2178 
2179  if ( self ‪is_explosive_ragdoll( weapon, eInflictor ) )
2180  {
2181  body ‪start_explosive_ragdoll( vDir, weapon );
2182  }
2183 
2184  thread ‪delayStartRagdoll( body, sHitLoc, vDir, weapon, eInflictor, sMeansOfDeath );
2185 
2186  //if( sMeansOfDeath == "MOD_BURNED" || isdefined( self.burning ) )
2187  //{
2188  // body _burnplayer::burnedToDeath();
2189  //}
2190  //if ( sMeansOfDeath == "MOD_CRUSH" )
2191  //{
2192  // body globallogic_vehicle::vehicleCrush();
2193  //}
2194 
2195  self.body = body;
2196 // if ( !isdefined( self.switching_teams ) )
2197 // thread _deathicons::addDeathicon( body, self, self.team, 5.0 );
2198 }
2199 
2200 function ‪is_explosive_ragdoll( weapon, inflictor )
2201 {
2202  if ( !isdefined( weapon ) )
2203  {
2204  return false;
2205  }
2206 
2207  // destructible explosives
2208  if ( weapon.name == "destructible_car" || weapon.name == "explodable_barrel" )
2209  {
2210  return true;
2211  }
2212 
2213  // special explosive weapons
2214  if ( weapon.projExplosionType == "grenade" )
2215  {
2216  if ( isdefined( inflictor ) && isdefined( inflictor.stuckToPlayer ) )
2217  {
2218  if ( inflictor.stuckToPlayer == self )
2219  {
2220  return true;
2221  }
2222  }
2223  }
2224 
2225  return false;
2226 }
2227 
2228 function ‪start_explosive_ragdoll( dir, weapon )
2229 {
2230  if ( !isdefined( self ) )
2231  {
2232  return;
2233  }
2234 
2235  x = RandomIntRange( 50, 100 );
2236  y = RandomIntRange( 50, 100 );
2237  z = RandomIntRange( 10, 20 );
2238 
2239  if ( isdefined( weapon ) && ( weapon.name == "sticky_grenade" || weapon.name == "explosive_bolt" ) )
2240  {
2241  if ( isdefined( dir ) && LengthSquared( dir ) > 0 )
2242  {
2243  x = dir[0] * x;
2244  y = dir[1] * y;
2245  }
2246  }
2247  else
2248  {
2249  if ( ‪math::cointoss() )
2250  {
2251  x = x * -1;
2252  }
2253  if ( ‪math::cointoss() )
2254  {
2255  y = y * -1;
2256  }
2257  }
2258 
2259  self StartRagdoll();
2260  self LaunchRagdoll( ( x, y, z ) );
2261 }
2262 
2263 
2265 {
2266  waittillframeend;
2267 
2268  if( isdefined( self ) )
2269  {
2270  level notify( "connecting", self );
2271  self ‪callback::callback( #"on_player_connecting" );
2272  }
2273 }
2274 
2275 
2276 function ‪delayStartRagdoll( ent, sHitLoc, vDir, weapon, eInflictor, sMeansOfDeath )
2277 {
2278  if ( isdefined( ent ) )
2279  {
2280  deathAnim = ent getcorpseanim();
2281  if ( animhasnotetrack( deathAnim, "ignore_ragdoll" ) )
2282  return;
2283  }
2284 
2285  if ( level.oldschool )
2286  {
2287  if ( !isdefined( vDir ) )
2288  vDir = (0,0,0);
2289 
2290  explosionPos = ent.origin + ( 0, 0, ‪globallogic_utils::getHitLocHeight( sHitLoc ) );
2291  explosionPos -= vDir * 20;
2292  //thread globallogic_utils::debugLine( ent.origin + (0,0,(explosionPos[2] - ent.origin[2])), explosionPos );
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" )
2296  {
2297  explosionForce = 2.5;
2298  }
2299 
2300  ent startragdoll( 1 );
2301 
2302  wait .05;
2303 
2304  if ( !isdefined( ent ) )
2305  return;
2306 
2307  // apply extra physics force to make the ragdoll go crazy
2308  physicsExplosionSphere( explosionPos, explosionRadius, explosionRadius/2, explosionForce );
2309  return;
2310  }
2311 
2312  wait( 0.2 );
2313 
2314  if ( !isdefined( ent ) )
2315  return;
2316 
2317  if ( ent isRagDoll() )
2318  return;
2319 
2320  deathAnim = ent getcorpseanim();
2321 
2322  startFrac = 0.35;
2323 
2324  if ( animhasnotetrack( deathAnim, "start_ragdoll" ) )
2325  {
2326  times = getnotetracktimes( deathAnim, "start_ragdoll" );
2327  if ( isdefined( times ) )
2328  startFrac = times[0];
2329  }
2330 
2331  waitTime = startFrac * getanimlength( deathAnim );
2332  wait( waitTime );
2333 
2334  if ( isdefined( ent ) )
2335  {
2336  ent startragdoll( 1 );
2337  }
2338 }
2339 
2340 function ‪trackAttackerDamage( eAttacker, iDamage, sMeansOfDeath, weapon )
2341 {
2342  if( !IsDefined( eAttacker ) )
2343  return;
2344 
2345  if ( !IsPlayer( eAttacker ) )
2346  return;
2347 
2348  if ( self.attackerData.size == 0 )
2349  {
2350  self.firstTimeDamaged = getTime();
2351  }
2352  if ( !isdefined( self.attackerData[eAttacker.clientid] ) )
2353  {
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();
2359 
2360  self.attackers[ self.attackers.size ] = eAttacker;
2361 
2362  // we keep an array of attackers by their client ID so we can easily tell
2363  // if they're already one of the existing attackers in the above if().
2364  // we store in this array data that is useful for other things, like challenges
2365  self.attackerData[eAttacker.clientid] = false;
2366  }
2367  else
2368  {
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();
2374  }
2375 
2376  self.attackerDamage[eAttacker.clientid].lasttimedamaged = getTime();
2377  if ( ‪weapons::is_primary_weapon( weapon ) )
2378  self.attackerData[eAttacker.clientid] = true;
2379 }
2380 
2381 function ‪giveAttackerAndInflictorOwnerAssist( eAttacker, eInflictor, iDamage, sMeansOfDeath, weapon )
2382 {
2383  if ( !‪allowedAssistWeapon( weapon ) )
2384  return;
2385 
2386  self ‪trackAttackerDamage( eAttacker, iDamage, sMeansOfDeath, weapon );
2387 
2388  if ( !isdefined( eInflictor ) )
2389  return;
2390 
2391  if ( !isdefined( eInflictor.owner ) )
2392  return;
2393 
2394  if ( !isdefined( eInflictor.ownerGetsAssist ) )
2395  return;
2396 
2397  if ( !eInflictor.ownerGetsAssist )
2398  return;
2399 
2400  // if attacker and inflictor owner are the same no additional points
2401  // I dont ever know if they are different
2402  if ( isdefined( eAttacker ) && eAttacker == eInflictor.owner )
2403  return;
2404 
2405  self ‪trackAttackerDamage( eInflictor.owner, iDamage, sMeansOfDeath, weapon );
2406 }
2407 
2408 function ‪updateMeansOfDeath( weapon, sMeansOfDeath )
2409 {
2410  // we do not want the melee icon to show up for dog attacks
2411  switch ( weapon.name )
2412  {
2413  case "knife_ballistic":
2414  {
2415  if ( ( sMeansOfDeath != "MOD_HEAD_SHOT" ) && ( sMeansOfDeath != "MOD_MELEE" ) )
2416  {
2417  sMeansOfDeath = "MOD_PISTOL_BULLET";
2418  }
2419  }
2420  break;
2421  case "dog_bite":
2422  sMeansOfDeath = "MOD_PISTOL_BULLET";
2423  break;
2424  case "destructible_car":
2425  sMeansOfDeath = "MOD_EXPLOSIVE";
2426  break;
2427  case "explodable_barrel":
2428  sMeansOfDeath = "MOD_EXPLOSIVE";
2429  break;
2430  }
2431 
2432  return sMeansOfDeath;
2433 }
2434 
2435 function ‪updateAttacker( attacker, weapon )
2436 {
2437  if( isai(attacker) && isdefined( attacker.script_owner ) )
2438  {
2439  // if the person who called the dogs in switched teams make sure they don't
2440  // get penalized for the kill
2441  if ( !level.teambased || attacker.script_owner.team != self.team )
2442  attacker = attacker.script_owner;
2443  }
2444 
2445  if( attacker.classname == "script_vehicle" && isdefined( attacker.owner ) )
2446  {
2447  attacker notify("killed",self);
2448 
2449  attacker = attacker.owner;
2450  }
2451 
2452  if( isai(attacker) )
2453  attacker notify("killed",self);
2454 
2455  if ( ( isdefined ( self.capturingLastFlag ) ) && ( self.capturingLastFlag == true ) )
2456  {
2457  attacker.lastCapKiller = true;
2458  }
2459 
2460  if( isdefined( attacker ) && isdefined( weapon ) && weapon.name == "planemortar" )
2461  {
2462  if ( !isdefined( attacker.planeMortarBda ) )
2463  {
2464  attacker.planeMortarBda = 0;
2465  }
2466  attacker.planeMortarBda ++;
2467  }
2468 
2469  return attacker;
2470 }
2471 
2472 function ‪updateInflictor( eInflictor )
2473 {
2474  if( isdefined( eInflictor ) && eInflictor.classname == "script_vehicle" )
2475  {
2476  eInflictor notify("killed",self);
2477 
2478  if ( isdefined( eInflictor.bda ) )
2479  {
2480  eInflictor.bda++;
2481  }
2482  }
2483 
2484  return eInflictor;
2485 }
2486 
2487 function ‪updateWeapon( eInflictor, weapon )
2488 {
2489  // explosive barrel/car detection
2490  if ( weapon == level.weaponNone && isdefined( eInflictor ) )
2491  {
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" );
2496  }
2497 
2498  return weapon;
2499 }
2500 
2501 function ‪getClosestKillcamEntity( attacker, killCamEntities, depth )
2502 {
2503  if ( !isdefined( depth ) )
2504  depth = 0;
2505 
2506  closestKillcamEnt = undefined;
2507  closestKillcamEntIndex = undefined;
2508  closestKillcamEntDist = undefined;
2509  origin = undefined;
2510 
2511  foreach( killcamEntIndex, killcamEnt in killCamEntities )
2512  {
2513  if ( killcamEnt == attacker )
2514  continue;
2515 
2516  origin = killcamEnt.origin;
2517  if ( isdefined( killcamEnt.offsetPoint ) )
2518  origin += killcamEnt.offsetPoint;
2519 
2520  dist = DistanceSquared( self.origin, origin );
2521 
2522  if ( !isdefined( closestKillcamEnt ) || dist < closestKillcamEntDist )
2523  {
2524  closestKillcamEnt = killcamEnt;
2525  closestKillcamEntDist = dist;
2526  closestKillcamEntIndex = killcamEntIndex;
2527  }
2528  }
2529 
2530  // check to see if the player is visible at time of death
2531  if ( depth < 3 && isdefined( closestKillcamEnt ) )
2532  {
2533  if ( !BulletTracePassed( closestKillcamEnt.origin, self.origin, false, self ) )
2534  {
2535  killCamEntities[closestKillcamEntIndex] = undefined;
2536 
2537  betterKillcamEnt = ‪getClosestKillcamEntity( attacker, killCamEntities, depth + 1 );
2538 
2539  if ( isdefined( betterKillcamEnt ) )
2540  {
2541  closestKillcamEnt = betterKillcamEnt;
2542  }
2543  }
2544  }
2545 
2546  return closestKillcamEnt;
2547 }
2548 
2549 function ‪getKillcamEntity( attacker, eInflictor, weapon )
2550 {
2551  if ( !isdefined( eInflictor ) )
2552  return undefined;
2553 
2554  if ( eInflictor == attacker )
2555  {
2556  if( !isdefined( eInflictor.isMagicBullet ) )
2557  return undefined;
2558  if( isdefined( eInflictor.isMagicBullet ) && !eInflictor.isMagicBullet )
2559  return undefined;
2560  }
2561  else if ( isdefined( level.levelSpecificKillcam ) )
2562  {
2563  levelSpecificKillcamEnt = self [[level.levelSpecificKillcam]]();
2564  if ( isdefined( levelSpecificKillcamEnt ) )
2565  return levelSpecificKillcamEnt;
2566  }
2567 
2568  if ( weapon.name == "m220_tow" )
2569  return undefined;
2570 
2571  if ( isdefined(eInflictor.killCamEnt) )
2572  {
2573  // this is the case with the player helis
2574  if ( eInflictor.killCamEnt == attacker )
2575  return undefined;
2576 
2577  return eInflictor.killCamEnt;
2578  }
2579  else if ( isdefined(eInflictor.killCamEntities) )
2580  {
2581  return ‪getClosestKillcamEntity( attacker, eInflictor.killCamEntities );
2582  }
2583 
2584  if ( isdefined( eInflictor.script_gameobjectname ) && eInflictor.script_gameobjectname == "bombzone" )
2585  return eInflictor.killCamEnt;
2586 
2587  return eInflictor;
2588 }
2589 
2590 function ‪playKillBattleChatter( attacker, weapon, victim )
2591 {
2592  /*if( IsPlayer( attacker ) )
2593  {
2594  //if ( !_killstreaks::isKillstreakWeapon( weapon ) )
2595  {
2596  level thread _battlechatter_mp::sayKillBattleChatter( attacker, weapon, victim );
2597  }
2598  }*/
2599 }
2600 
2602 {
2603  foreach (player in level.players)
2604  {
2605  recordPlayerMatchEnd( player );
2606  RecordPlayerStats(player, "presentAtEnd", 1 );
2607  }
2608 }
‪flushGroupDialogOnPlayer
‪function flushGroupDialogOnPlayer(group)
Definition: _globallogic_audio.gsc:481
‪callback
‪function callback(event, localclientnum, params)
Definition: callbacks_shared.csc:13
‪recordActivePlayersEndGameMatchRecordStats
‪function recordActivePlayersEndGameMatchRecordStats()
Definition: _globallogic_player.gsc:2601
‪spectate_player_watcher
‪function spectate_player_watcher()
Definition: _globallogic_player.gsc:1271
‪getHitLocHeight
‪function getHitLocHeight(sHitLoc)
Definition: _globallogic_utils.gsc:426
‪Callback_PlayerMigrated
‪function Callback_PlayerMigrated()
Definition: _globallogic_player.gsc:1343
‪updateAttacker
‪function updateAttacker(attacker, weapon)
Definition: _globallogic_player.gsc:4284
‪updateWeapon
‪function updateWeapon(eInflictor, weapon)
Definition: _globallogic_player.gsc:4354
‪playKillBattleChatter
‪function playKillBattleChatter(attacker, weapon, victim, eInflictor)
Definition: _globallogic_player.gsc:4368
‪blank
‪function blank(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
Definition: _globallogic.gsc:333
‪adjustRecentStats
‪function adjustRecentStats()
Definition: _zm_stats.gsc:741
‪leaderDialog
‪function leaderDialog(dialog, team, group, excludeList, squadDialog)
Definition: _globallogic_audio.gsc:375
‪TeamKillKick
‪function TeamKillKick()
Definition: _globallogic_player.gsc:3883
‪is_bot
‪function is_bot()
Definition: util_shared.gsc:2488
‪waitForTimeOrNotifies
‪function waitForTimeOrNotifies(desiredDelay)
Definition: _globallogic_utils.gsc:481
‪showPerks
‪function showPerks()
Definition: hud_util_shared.gsc:904
‪IgnoreTeamKills
‪function IgnoreTeamKills(weapon, sMeansOfDeath, eInflictor)
Definition: _globallogic_player.gsc:3967
‪uploadStatsSoon
‪function uploadStatsSoon()
Definition: _zm_stats.gsc:746
‪forceEnd
‪function forceEnd(hostsucks)
Definition: _globallogic.gsc:643
‪clear
‪function clear(str_flag)
Definition: flag_shared.csc:130
‪updateGlobalBotKilledCounter
‪function updateGlobalBotKilledCounter()
Definition: _globallogic_player.gsc:3845
‪detach_carry_object_model
‪function detach_carry_object_model()
Definition: weapons_shared.gsc:43
‪doPerkFeedBack
‪function doPerkFeedBack(player, weapon, sMeansOfDeath, eInflictor, armor_damaged)
Definition: _globallogic_player.gsc:2400
‪onWeaponDamage
‪function onWeaponDamage(eAttacker, eInflictor, weapon, meansOfDeath, damage)
Definition: _weapons.gsc:1115
‪cointoss
‪function cointoss()
Definition: math_shared.csc:171
‪GAMEMODE_PUBLIC_MATCH
‪#define GAMEMODE_PUBLIC_MATCH
Definition: shared.gsh:10
‪setShoutcasterWaitingMessage
‪function setShoutcasterWaitingMessage()
Definition: hud_message_shared.gsc:517
‪figureOutAttacker
‪function figureOutAttacker(eAttacker)
Definition: _globallogic_player.gsc:633
‪Callback_PlayerKilled
‪function Callback_PlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, enteredResurrect=false)
Definition: _globallogic_player.gsc:3020
‪getTweakableValue
‪function getTweakableValue(category, name)
Definition: _tweakables.gsc:12
‪recordZMEndGameComScoreEventForPlayer
‪function recordZMEndGameComScoreEventForPlayer(player, result)
Definition: _globallogic_player.gsc:468
‪WaitTillKillStreakDone
‪function WaitTillKillStreakDone()
Definition: _globallogic_player.gsc:3854
‪finishPlayerDamageWrapper
‪function finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal)
Definition: _globallogic_player.gsc:2441
‪freezePlayerForRoundEnd
‪function freezePlayerForRoundEnd()
Definition: _globallogic_player.gsc:81
‪updateInflictor
‪function updateInflictor(eInflictor)
Definition: _globallogic_player.gsc:4339
‪freeze_player_controls
‪function freeze_player_controls(b_frozen=true)
Definition: util_shared.gsc:2474
‪allowedAssistWeapon
‪function allowedAssistWeapon(weapon)
Definition: _globallogic_player.gsc:2473
‪getClosestKillcamEntity
‪function getClosestKillcamEntity(attacker, killCamEntities, depth)
Definition: _globallogic_player.gsc:2501
‪trackAttackerDamage
‪function trackAttackerDamage(eAttacker, iDamage, sMeansOfDeath, weapon)
Definition: _globallogic_player.gsc:4187
‪power_loss_event_took_damage
‪function power_loss_event_took_damage(eAttacker, eInflictor, weapon, sMeansOfDeath, iDamage)
Definition: _ability_power.gsc:166
‪clearShoutcasterWaitingMessage
‪function clearShoutcasterWaitingMessage()
Definition: hud_message_shared.gsc:530
‪IsEnemyPlayer
‪function IsEnemyPlayer(player)
Definition: util_shared.csc:1220
‪giveAttackerAndInflictorOwnerAssist
‪function giveAttackerAndInflictorOwnerAssist(eAttacker, eInflictor, iDamage, sMeansOfDeath, weapon)
Definition: _globallogic_player.gsc:4233
‪ArrayToString
‪function ArrayToString(inputArray)
Definition: _globallogic_player.gsc:97
‪isHeadShot
‪function isHeadShot(weapon, sHitLoc, sMeansOfDeath, eInflictor)
Definition: _globallogic_utils.gsc:397
‪createDeadBody
‪function createDeadBody(attacker, iDamage, sMeansOfDeath, weapon, sHitLoc, vDir, vAttackerOrigin, deathAnimDuration, eInflictor, body)
Definition: _globallogic_player.gsc:4004
‪IncrementMatchCompletionStat
‪function IncrementMatchCompletionStat(gameMode, playedOrHosted, stat)
Definition: _globallogic.gsc:1119
‪kickIfDontSpawn
‪function kickIfDontSpawn()
Definition: _globallogic_spawn.gsc:619
‪suicide
‪function suicide()
Definition: _vehicle.gsc:1309
‪Callback_PlayerDamage
‪function Callback_PlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal)
Definition: _globallogic_player.gsc:2186
‪TimeUntilSpawn
‪function TimeUntilSpawn(includeTeamkillDelay)
Definition: _globallogic_spawn.gsc:37
‪listenForGameEnd
‪function listenForGameEnd()
Definition: _globallogic.gsc:3950
‪hostMigrationTimerThink
‪function hostMigrationTimerThink()
Definition: hostmigration_shared.gsc:180
‪notifyConnecting
‪function notifyConnecting()
Definition: _globallogic_player.gsc:4134
‪updateTeamStatus
‪function updateTeamStatus()
Definition: _globallogic.gsc:2920
‪GetCurrentGameMode
‪function GetCurrentGameMode()
Definition: util_shared.gsc:3750
‪delayStartRagdoll
‪function delayStartRagdoll(ent, sHitLoc, vDir, weapon, eInflictor, sMeansOfDeath)
Definition: _globallogic_player.gsc:4147
‪_setPlayerScore
‪function _setPlayerScore(player, score)
Definition: _globallogic_score.gsc:519
‪is_primary_weapon
‪function is_primary_weapon(weapon)
Definition: weapons_shared.gsc:15
‪_getPlayerScore
‪function _getPlayerScore(player)
Definition: _globallogic_score.gsc:538
‪getTimePassed
‪function getTimePassed()
Definition: _globallogic_utils.gsc:274
‪doDamageFeedback
‪function doDamageFeedback(weapon, eInflictor, iDamage, sMeansOfDeath)
Definition: _globallogic_player.gsc:1135
‪incKillstreakTracker
‪function incKillstreakTracker(weapon)
Definition: _globallogic_score.gsc:1340
‪reduceTeamKillsOverTime
‪function reduceTeamKillsOverTime()
Definition: _globallogic_player.gsc:3946
‪bbPlayerMatchEnd
‪function bbPlayerMatchEnd(gameLength, endReasonString, gameOver)
Definition: _globallogic.gsc:2417
‪showMainMenuForTeam
‪function showMainMenuForTeam()
Definition: _globallogic_ui.gsc:461
‪Callback_PlayerMelee
‪function Callback_PlayerMelee(eAttacker, iDamage, weapon, vOrigin, vDir, boneIndex, shieldHit, fromBehind)
Definition: _globallogic_player.gsc:1477
‪giveKillStats
‪function giveKillStats(sMeansOfDeath, weapon, eVictim)
Definition: _globallogic_score.gsc:1475
‪trackAttackeeDeath
‪function trackAttackeeDeath(attackerName, rank, xp, prestige, xuid)
Definition: _globallogic_score.gsc:1424
‪isAIKillstreakDamage
‪function isAIKillstreakDamage(weapon, eInflictor)
Definition: _globallogic_player.gsc:2428
‪figureOutWeapon
‪function figureOutWeapon(weapon, eInflictor)
Definition: _globallogic_player.gsc:654
‪setSpectatePermissions
‪function setSpectatePermissions(isOn)
Definition: _zm.gsc:2709
‪Callback_PlayerDisconnect
‪function Callback_PlayerDisconnect()
Definition: _globallogic_player.gsc:1360
‪Callback_PlayerConnect
‪function Callback_PlayerConnect()
Definition: _globallogic_player.gsc:577
‪onSpawnPlayer_Unified
‪function onSpawnPlayer_Unified(predictedSpawn)
Definition: _spawning.gsc:524
‪isPlayerImmuneToKillstreak
‪function isPlayerImmuneToKillstreak(eAttacker, weapon)
Definition: _globallogic_player.gsc:1636
‪Callback_PlayerLastStand
‪function Callback_PlayerLastStand(eInflictor, eAttacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration)
Definition: _globallogic_player.gsc:3988
‪getPersStat
‪function getPersStat(dataName)
Definition: _globallogic_score.gsc:1018
‪start_explosive_ragdoll
‪function start_explosive_ragdoll(dir, weapon)
Definition: _globallogic_player.gsc:4087
‪bookmark
‪function bookmark(type, time, mainClientEnt, otherClientEnt, eventPriority, inflictorEnt, overrideEntityCamera, actorEnt)
Definition: demo_shared.gsc:25
‪isValidClass
‪function isValidClass(c)
Definition: _globallogic_utils.gsc:144
‪resetPlayerMomentumOnDeath
‪function resetPlayerMomentumOnDeath()
Definition: _globallogic_score.gsc:125
‪isTacticalHitMarker
‪function isTacticalHitMarker(weapon, sMeansOfDeath, iDamage)
Definition: _globallogic_player.gsc:1157
‪custom_gamemodes_modified_damage
‪function custom_gamemodes_modified_damage(victim, eAttacker, iDamage, sMeansOfDeath, weapon, eInflictor, sHitLoc)
Definition: _globallogic_player.gsc:1537
‪trackAttackerKill
‪function trackAttackerKill(name, rank, xp, prestige, xuid, weapon)
Definition: _globallogic_score.gsc:1353
‪updateMeansOfDeath
‪function updateMeansOfDeath(weapon, sMeansOfDeath)
Definition: _globallogic_player.gsc:2408
‪clientNotify
‪function clientNotify(event)
Definition: util_shared.gsc:1416
‪giveTeamScore
‪function giveTeamScore(event, team, player, victim)
Definition: _globallogic_score.gsc:727
‪is_grenade
‪function is_grenade(weapon)
Definition: weapons_shared.gsc:30
‪getGameLength
‪function getGameLength()
Definition: _globallogic.gsc:1129
‪getKillcamEntity
‪function getKillcamEntity(attacker, eInflictor, weapon)
Definition: _globallogic_player.gsc:2549
‪deathOccured
‪function deathOccured(dier, killer)
Definition: _spawnlogic.gsc:831
‪ShouldTeamKillKick
‪function ShouldTeamKillKick(teamKillDelay)
Definition: _globallogic_player.gsc:3926
‪spawnQueuedClient
‪function spawnQueuedClient(dead_player_team, killer)
Definition: _globallogic_spawn.gsc:755
‪inform_clientvm_of_migration
‪function inform_clientvm_of_migration()
Definition: _globallogic_player.gsc:448
‪updateObjectiveText
‪function updateObjectiveText()
Definition: _globallogic_ui.gsc:397
‪figureOutFriendlyFire
‪function figureOutFriendlyFire(victim)
Definition: _globallogic_player.gsc:672
‪incTotalKills
‪function incTotalKills(team)
Definition: _globallogic_score.gsc:1503
‪removeDisconnectedPlayerFromPlacement
‪function removeDisconnectedPlayerFromPlacement()
Definition: _globallogic.gsc:2659
‪damageShellshockAndRumble
‪function damageShellshockAndRumble(eAttacker, eInflictor, weapon, sMeansOfDeath, iDamage)
Definition: _globallogic_player.gsc:3993
‪TeamKillDelay
‪function TeamKillDelay()
Definition: _globallogic_player.gsc:3915
‪result
‪function result(death, attacker, mod, weapon)
Definition: _zm_aat_blast_furnace.gsc:46
‪resetAttackerList
‪function resetAttackerList()
Definition: _globallogic_player.gsc:2387
‪name
‪class GroundFx name
‪dropScavengerForDeath
‪function dropScavengerForDeath(attacker)
Definition: _weapons.gsc:1503
‪chooseNextBestNemesis
‪function chooseNextBestNemesis()
Definition: _globallogic_player.gsc:1492
‪incPersStat
‪function incPersStat(dataName, increment, record_stats, includeGametype)
Definition: _globallogic_score.gsc:1024
‪dropWeaponForDeath
‪function dropWeaponForDeath(attacker)
Definition: _weapons.gsc:275
‪is_explosive_ragdoll
‪function is_explosive_ragdoll(weapon, inflictor)
Definition: _globallogic_player.gsc:4059
‪clearLowerMessage
‪function clearLowerMessage(fadetime)
Definition: _util.gsc:166