1 #using scripts\shared\abilities\_ability_player;
2 #using scripts\shared\abilities\_ability_power;
3 #using scripts\shared\abilities\_ability_util;
4 #using scripts\shared\callbacks_shared;
5 #using scripts\shared\challenges_shared;
6 #using scripts\shared\clientfield_shared;
7 #using scripts\shared\damagefeedback_shared;
8 #using scripts\shared\demo_shared;
9 #using scripts\shared\flag_shared;
10 #using scripts\shared\hostmigration_shared;
11 #using scripts\shared\hud_message_shared;
12 #using scripts\shared\hud_util_shared;
13 #using scripts\shared\killstreaks_shared;
14 #using scripts\shared\math_shared;
15 #using scripts\shared\medals_shared;
16 #using scripts\shared\persistence_shared;
17 #using scripts\shared\player_shared;
18 #using scripts\shared\rank_shared;
19 #using scripts\shared\scoreevents_shared;
20 #using scripts\shared\tweakables_shared;
21 #using scripts\shared\util_shared;
22 #using scripts\shared\weapons_shared;
23 #using scripts\shared\weapons\_weapon_utils;
24 #using scripts\shared\weapons\_weapons;
25 #using scripts\shared\ai\systems\gib;
27 #insert scripts\shared\shared.gsh;
29 #using scripts\mp\gametypes\_battlechatter;
30 #using scripts\mp\gametypes\_deathicons;
31 #using scripts\mp\gametypes\_globallogic;
32 #using scripts\mp\gametypes\_globallogic_audio;
33 #using scripts\mp\gametypes\_globallogic_score;
34 #using scripts\mp\gametypes\_globallogic_spawn;
35 #using scripts\mp\gametypes\_globallogic_ui;
36 #using scripts\mp\gametypes\_globallogic_utils;
37 #using scripts\mp\gametypes\_globallogic_vehicle;
38 #using scripts\mp\gametypes\_hostmigration;
39 #using scripts\mp\gametypes\_hud_message;
40 #using scripts\mp\gametypes\_killcam;
41 #using scripts\mp\gametypes\_loadout;
42 #using scripts\mp\gametypes\_spawning;
43 #using scripts\mp\gametypes\_spawnlogic;
44 #using scripts\mp\gametypes\_spectating;
45 #using scripts\mp\gametypes\_weapons;
47 #using scripts\mp\_armor;
48 #using scripts\mp\_behavior_tracker;
49 #using scripts\shared\_burnplayer;
50 #using scripts\mp\_challenges;
51 #using scripts\mp\_contracts;
52 #using scripts\mp\_gamerep;
53 #using scripts\mp\_laststand;
54 #using scripts\mp\_teamops;
55 #using scripts\mp\_util;
56 #using scripts\mp\_vehicle;
57 #using scripts\mp\killstreaks\_killstreaks;
58 #using scripts\mp\teams\_teams;
60 #insert scripts\shared\abilities\_ability_util.gsh;
61 #insert scripts\mp\_contracts.gsh;
63 #define TAUNT_TYPE_FIRST_PLACE 0
65 #define GESTURE_TYPE_GOOD_GAME 0
66 #define GESTURE_TYPE_THREATEN 1
67 #define GESTURE_TYPE_BOAST 2
68 #define GESTURE_TYPE_MAX 7
70 #namespace globallogic_player;
75 if ( !level.rankedMatch && !level.teambased )
85 self closeInGameMenu();
89 if( !SessionModeIsZombiesGame() )
91 currentWeapon =
self GetCurrentWeapon();
93 self takeWeapon( currentWeapon );
100 for (i=0; i < inputArray.size; i++)
102 targetString += inputArray[i];
103 if (i != inputArray.size-1)
112 lpselfnum = player getEntityNumber();
113 lpXuid = player getxuid(
true);
115 weeklyAContractId = 0;
116 weeklyAContractTarget = 0;
117 weeklyAContractCurrent = 0;
118 weeklyAContractCompleted = 0;
120 weeklyBContractId = 0;
121 weeklyBContractTarget = 0;
122 weeklyBContractCurrent = 0;
123 weeklyBContractCompleted = 0;
126 dailyContractTarget = 0;
127 dailyContractCurrent = 0;
128 dailyContractCompleted = 0;
130 specialContractId = 0;
131 specialContractTarget = 0;
132 specialContractCurent = 0;
133 specialContractCompleted = 0;
143 prevXP = player.pers[
"rankxp"];
147 specialContractId = 1;
148 specialContractTarget = GetDvarInt(
"weapon_contract_target_value", 100 );
149 specialContractCurent = player GetDStat(
"weaponContractData",
"currentValue" );
150 if (
VAL( player GetDStat(
"weaponContractData",
"completeTimestamp" ), 0 ) != 0 )
152 specialContractCompleted = 1;
161 weeklyAContractId = contractId;
162 weeklyAContractTarget = player.pers[
"contracts" ][ weeklyAContractId ].target_value;
170 weeklyBContractId = contractId;
171 weeklyBContractTarget = player.pers[
"contracts" ][ weeklyBContractId ].target_value;
179 dailyContractId = contractId;
180 dailyContractTarget = player.pers[
"contracts" ][ dailyContractId ].target_value;
187 if ( !isdefined( prevXP ) )
196 if ( isDefined(player.team) &&
result == player.team )
201 xpEarned = currXP - prevXP;
205 primaryWeaponName =
"";
206 primaryWeaponAttachStr=
"";
207 secondaryWeaponName =
"";
208 secondaryWeaponAttachStr=
"";
209 grenadePrimaryName =
"";
210 grenadeSecondaryName =
"";
214 if (isdefined( player.primaryLoadoutWeapon ))
216 primaryWeaponName = player.primaryLoadoutWeapon.name;
217 primaryWeaponAttachStr =
ArrayToString( GetArrayKeys(player.primaryLoadoutWeapon.attachments) );
219 if (isdefined( player.secondaryLoadoutWeapon ))
221 secondaryWeaponName = player.secondaryLoadoutWeapon.name;
222 secondaryWeaponAttachStr =
ArrayToString( GetArrayKeys(player.secondaryLoadoutWeapon.attachments) );
225 if (isdefined( player.grenadeTypePrimary ))
226 grenadePrimaryName = player.grenadeTypePrimary.name;
227 if (isdefined( player.grenadeTypeSecondary ))
228 grenadeSecondaryName = player.grenadeTypeSecondary.name;
232 gameLength = game[
"timepassed"] / 1000;
241 if ( level.gametype !=
"fr" )
243 totalKills = player GetDStat(
"playerstatslist",
"kills",
"statValue" );
244 totalHits = player GetDStat(
"playerstatslist",
"hits",
"statValue" );
245 totalDeaths = player GetDStat(
"playerstatslist",
"deaths",
"statValue" );
246 totalWins = player GetDStat(
"playerstatslist",
"wins",
"statValue" );
247 totalXP = player GetDStat(
"playerstatslist",
"rankxp",
"statValue" );
253 if( level.mpCustomMatch )
255 killCount = player.kills;
256 hitCount = player.shotshit;
260 if ( isdefined( player.startKills ) )
261 killCount = totalKills - player.startKills;
263 if ( isdefined( player.startHits ) )
264 hitCount = totalHits - player.startHits;
268 if ( isdefined( player.pers[
"lastHighestScore"] ) && player.score > player.pers[
"lastHighestScore"] )
272 if ( isdefined( player.pers[
"lastHighestKills"] ) && killCount > player.pers[
"lastHighestKills"] )
276 if ( isdefined( player.totalMatchShots) )
277 totalMatchShots = player.totalMatchShots;
279 deaths = player.deaths;
282 kdRatio = player.kills*1000/deaths;
284 if ( isdefined( player.pers[
"lastHighestKDRatio"] ) && kdRatio > player.pers[
"lastHighestKDRatio"] )
287 showcaseWeapon = player GetPlayerShowcaseWeapon();
289 RecordComScoreEvent(
"end_match",
290 "match_id", getDemoFileID(),
291 "game_variant",
"mp",
292 "game_mode", level.gametype,
293 "private_match", SessionModeIsPrivate(),
294 "esports_flag", level.leagueMatch,
295 "ranked_play_flag", level.arenaMatch,
296 "league_team_id", player getLeagueTeamID(),
297 "game_map", GetDvarString(
"mapname" ),
298 "player_xuid", player getxuid(
true),
299 "player_ip", player getipaddress(),
300 "match_kills", killCount,
301 "match_deaths", player.deaths,
302 "match_xp", xpEarned,
303 "match_score", player.score,
304 "match_streak", player.pers[
"best_kill_streak"],
305 "match_captures", player.pers[
"captures"],
306 "match_defends", player.pers[
"defends"],
307 "match_headshots", player.pers[
"headshots"],
308 "match_longshots", player.pers[
"longshots"],
309 "match_objtime", player.pers[
"objtime"],
310 "match_plants", player.pers[
"plants"],
311 "match_defuses", player.pers[
"defuses"],
312 "match_throws", player.pers[
"throws"],
313 "match_carries", player.pers[
"carries"],
314 "match_returns", player.pers[
"returns"],
315 "prestige_max", player.pers[
"plevel"],
316 "level_max", player.pers[
"rank"],
317 "match_result", resultStr,
318 "match_duration", timePlayed,
319 "match_shots", totalMatchShots,
320 "match_hits", hitCount,
321 "player_gender", player GetPlayerGenderType( CurrentSessionMode() ),
322 "specialist_kills", player.heroweaponKillCount,
323 "specialist_used", player GetMpDialogName(),
324 "season_pass_owned", player HasSeasonPass(0),
325 "loadout_perks", perkStr,
326 "loadout_lethal", grenadePrimaryName,
327 "loadout_tactical", grenadeSecondaryName,
328 "loadout_scorestreaks", killStreakStr,
329 "loadout_primary_weapon", primaryWeaponName,
330 "loadout_secondary_weapon", secondaryWeaponName,
331 "dlc_owned", player GetDLCAvailable(),
332 "loadout_primary_attachments", primaryWeaponAttachStr,
333 "loadout_secondary_attachments",secondaryWeaponAttachStr,
334 "best_score", bestScore,
335 "best_kills", bestKills,
336 "best_kd", bestKDRatio,
337 "total_kills", totalKills,
338 "total_deaths", totalDeaths,
339 "total_wins", totalWins,
341 "daily_contract_id", dailyContractId,
342 "daily_contract_target", dailyContractTarget,
343 "daily_contract_current", dailyContractCurrent,
344 "daily_contract_completed", dailyContractCompleted,
345 "weeklyA_contract_id", weeklyAContractId,
346 "weeklyA_contract_target", weeklyAContractTarget,
347 "weeklyA_contract_current", weeklyAContractCurrent,
348 "weeklyA_contract_completed", weeklyAContractCompleted,
349 "weeklyB_contract_id", weeklyBContractId,
350 "weeklyB_contract_target", weeklyBContractTarget,
351 "weeklyB_contract_current", weeklyBContractCurrent,
352 "weeklyB_contract_completed", weeklyBContractCompleted,
353 "special_contract_id ", specialContractId,
354 "special_contract_target", specialContractTarget,
355 "special_contract_curent", specialContractCurent,
356 "special_contract_completed", specialContractCompleted,
357 "specialist_power", player.heroabilityname,
358 "specialist_head", player GetCharacterHelmetModel(),
359 "specialist_body", player GetCharacterBodyModel(),
364 "specialist_showcase", showcaseWeapon.weapon.name
370 self endon (
"death" );
371 self endon (
"disconnect" );
373 minimumMoveDistance = 16;
378 prevpos =
self.origin;
379 positionPTM =
self.origin;
386 self waittill (
"stopped_using_remote");
387 prevpos =
self.origin;
388 positionPTM =
self.origin;
392 distance = distance(
self.origin, prevpos );
393 self.pers[
"total_distance_travelled"] += distance;
394 self.pers[
"movement_Update_Count"]++;
395 prevpos =
self.origin;
397 if ((
self.pers[
"movement_Update_Count"] % 5) == 0)
399 distanceMoving = distance(
self.origin, positionPTM);
400 positionPTM =
self.origin;
401 if ( distanceMoving > minimumMoveDistance )
403 self.pers[
"num_speeds_when_moving_entries"]++;
404 self.pers[
"total_speeds_when_moving"] += ( distanceMoving / waitTime );
405 self.pers[
"time_played_moving"] += waitTime;
416 if( !isDefined(
self.lastSwimmingStartTime) || !isDefined(
self.lastWallRunStartTime) || !isDefined(
self.lastSlideStartTime) || !isDefined(
self.lastDoubleJumpStartTime) ||
417 !isDefined(
self.timeSpentSwimmingInLife) || !isDefined(
self.timeSpentWallRunningInLife) || !isDefined(
self.numberOfDoubleJumpsInLife) || !isDefined(
self.numberOfSlidesInLife) )
420 println(
"record_special_move_data_for_life - fields on self not defined!");
425 if( isDefined(killer) )
427 if( !isDefined( killer.lastSwimmingStartTime) || !isDefined( killer.lastWallRunStartTime) || !isDefined( killer.lastSlideStartTime) || !isDefined( killer.lastDoubleJumpStartTime) )
430 println(
"record_special_move_data_for_life - fields one killer not defined!");
434 matchRecordLogSpecialMoveDataForLife(
self,
self.lastSwimmingStartTime,
self.lastWallRunStartTime,
self.lastSlideStartTime,
self.lastDoubleJumpStartTime,
435 self.timeSpentSwimmingInLife,
self.timeSpentWallRunningInLife,
self.numberOfDoubleJumpsInLife,
self.numberOfSlidesInLife,
436 killer, killer.lastSwimmingStartTime, killer.lastWallRunStartTime, killer.lastSlideStartTime, killer.lastDoubleJumpStartTime );
440 matchRecordLogSpecialMoveDataForLife(
self,
self.lastSwimmingStartTime,
self.lastWallRunStartTime,
self.lastSlideStartTime,
self.lastDoubleJumpStartTime,
441 self.timeSpentSwimmingInLife,
self.timeSpentWallRunningInLife,
self.numberOfDoubleJumpsInLife,
self.numberOfSlidesInLife );
448 self endon (
"disconnect" );
451 self notify(
"stop_player_monitor_wall_run");
452 self endon(
"stop_player_monitor_wall_run");
454 self.lastWallRunStartTime = 0;
455 self.timeSpentWallRunningInLife = 0;
459 if( notification ==
"death" )
462 self.lastWallRunStartTime = getTime();
466 self.timeSpentWallRunningInLife += (getTime() -
self.lastWallRunStartTime);
468 if( notification ==
"death" )
476 self endon (
"disconnect" );
479 self notify(
"stop_player_monitor_swimming");
480 self endon(
"stop_player_monitor_swimming");
482 self.lastSwimmingStartTime = 0;
483 self.timeSpentSwimmingInLife = 0;
487 if( notification ==
"death" )
490 self.lastSwimmingStartTime = getTime();
494 self.timeSpentSwimmingInLife += (getTime() -
self.lastSwimmingStartTime);
496 if( notification ==
"death" )
504 self endon (
"disconnect" );
507 self notify(
"stop_player_monitor_slide");
508 self endon(
"stop_player_monitor_slide");
510 self.lastSlideStartTime = 0;
511 self.numberOfSlidesInLife = 0;
515 if( notification ==
"death" )
518 self.lastSlideStartTime = getTime();
519 self.numberOfSlidesInLife++;
523 if( notification ==
"death" )
530 self endon (
"disconnect" );
533 self notify(
"stop_player_monitor_doublejump");
534 self endon(
"stop_player_monitor_doublejump");
536 self.lastDoubleJumpStartTime = 0;
537 self.numberOfDoubleJumpsInLife = 0;
540 notification =
self util::waittill_any_return(
"doublejump_begin",
"death",
"disconnect",
"stop_player_monitor_doublejump" );
541 if( notification ==
"death" )
544 self.lastDoubleJumpStartTime = getTime();
545 self.numberOfDoubleJumpsInLife++;
549 if( notification ==
"death" )
557 self endon (
"disconnect" );
559 self notify(
"player_monitor_inactivity" );
560 self endon(
"player_monitor_inactivity" );
566 if ( isdefined(
self ) )
570 self ResetInactivityTimer();
581 self.statusicon =
"hud_status_connecting";
582 self waittill(
"begin" );
584 if( isdefined( level.reset_clientdvars ) )
585 self [[level.reset_clientdvars]]();
588 self.statusicon =
"";
590 self.guid =
self getGuid();
592 self.killstreak = [];
594 self.leaderDialogQueue = [];
595 self.killstreakDialogQueue = [];
597 profilelog_begintiming( 4,
"ship" );
599 level notify(
"connected",
self );
606 if( !level.splitscreen && !isdefined(
self.pers[
"score"] ) )
608 iPrintLn(&
"MP_CONNECTED",
self);
611 if( !isdefined(
self.pers[
"score"] ) )
622 if( ( level.rankedMatch || level.wagerMatch || level.leagueMatch ) && !isdefined(
self.pers[
"matchesPlayedStatsTracked"] ) )
627 if ( !isdefined(
self.pers[
"matchesHostedStatsTracked"] ) &&
self IsLocalToHost() )
630 self.pers[
"matchesHostedStatsTracked"] =
true;
633 self.pers[
"matchesPlayedStatsTracked"] =
true;
639 lpselfnum =
self getEntityNumber();
640 lpGuid =
self getGuid();
641 lpXuid =
self getxuid(
true);
642 /#logPrint(
"J;" + lpGuid +
";" + lpselfnum +
";" +
self.
name +
"\n");#/
646 recordPlayerStats(
self,
"codeClientNum", lpselfnum);
648 if( !SessionModeIsZombiesGame() )
650 self setClientUIVisibilityFlag(
"hud_visible", 1 );
651 self setClientUIVisibilityFlag(
"weapon_hud_visible", 1 );
654 self SetClientPlayerSprintTime( level.playerSprintTime );
655 self SetClientNumLives( level.numLives );
659 if ( level.hardcoreMode )
661 self SetClientDrawTalk( 3 );
664 if( SessionModeIsZombiesGame() )
667 self [[level.player_stats_init]]();
673 if ( level.resetPlayerScoreEveryRound )
675 self.pers[
"score"] = 0;
677 self.score =
self.pers[
"score"];
680 if ( level.scoreRoundWinBased )
682 self.pers[
"pointstowin"] = 0;
684 self.pointstowin =
self.pers[
"pointstowin"];
819 self.teamKillPunish =
false;
820 if ( level.minimumAllowedTeamKills >= 0 &&
self.pers[
"teamkills_nostats"] > level.minimumAllowedTeamKills )
826 self.killedPlayersCurrent = [];
828 if ( !isdefined(
self.pers[
"totalTimePlayed"] ) )
830 self setEnterTime( getTime() );
831 self.pers[
"totalTimePlayed"] = 0;
834 if ( !isdefined(
self.pers[
"totalMatchBonus"] ) )
836 self.pers[
"totalMatchBonus"] = 0;
839 if( !isdefined(
self.pers[
"best_kill_streak"] ) )
841 self.pers[
"killed_players"] = [];
842 self.pers[
"killed_by"] = [];
843 self.pers[
"nemesis_tracking"] = [];
844 self.pers[
"artillery_kills"] = 0;
845 self.pers[
"dog_kills"] = 0;
846 self.pers[
"nemesis_name"] =
"";
847 self.pers[
"nemesis_rank"] = 0;
848 self.pers[
"nemesis_rankIcon"] = 0;
849 self.pers[
"nemesis_xp"] = 0;
850 self.pers[
"nemesis_xuid"] =
"";
851 self.pers[
"killed_players_with_specialist"] = [];
858 self.pers[
"best_kill_streak"] = 0;
862 if( !isdefined(
self.pers[
"music"] ) )
864 self.pers[
"music"] = spawnstruct();
865 self.pers[
"music"].spawn =
false;
866 self.pers[
"music"].inque =
false;
867 self.pers[
"music"].currentState =
"SILENT";
868 self.pers[
"music"].previousState =
"SILENT";
869 self.pers[
"music"].nextstate =
"UNDERSCORE";
870 self.pers[
"music"].returnState =
"UNDERSCORE";
874 if (
self.team !=
"spectator" )
879 if ( !isdefined(
self.pers[
"cur_kill_streak"] ) )
881 self.pers[
"cur_kill_streak"] = 0;
884 if ( !isdefined(
self.pers[
"cur_total_kill_streak"] ) )
886 self.pers[
"cur_total_kill_streak"] = 0;
887 self setplayercurrentstreak( 0 );
890 if ( !isdefined(
self.pers[
"totalKillstreakCount"] ) )
891 self.pers[
"totalKillstreakCount"] = 0;
894 if ( !isdefined(
self.pers[
"killstreaksEarnedThisKillstreak"] ) )
895 self.pers[
"killstreaksEarnedThisKillstreak"] = 0;
897 if ( isdefined( level.usingScoreStreaks ) && level.usingScoreStreaks && !isdefined(
self.pers[
"killstreak_quantity"] ) )
898 self.pers[
"killstreak_quantity"] = [];
900 if ( isdefined( level.usingScoreStreaks ) && level.usingScoreStreaks && !isdefined(
self.pers[
"held_killstreak_ammo_count"] ) )
901 self.pers[
"held_killstreak_ammo_count"] = [];
903 if ( IsDefined( level.usingScoreStreaks ) && level.usingScoreStreaks && !IsDefined(
self.pers[
"held_killstreak_clip_count"] ) )
904 self.pers[
"held_killstreak_clip_count"] = [];
906 if( !isDefined(
self.pers[
"changed_class"] ) )
907 self.pers[
"changed_class"] =
false;
909 if( !isDefined(
self.pers[
"lastroundscore"] ) )
910 self.pers[
"lastroundscore"] = 0;
912 self.lastKillTime = 0;
914 self.cur_death_streak = 0;
915 self disabledeathstreak();
916 self.death_streak = 0;
917 self.kill_streak = 0;
918 self.gametype_kill_streak = 0;
919 self.spawnQueueIndex = -1;
922 self.aliveTimes = [];
923 for( index = 0; index < level.aliveTimeMaxCount; index++ )
925 self.aliveTimes[index] = 0;
928 self.aliveTimeCurrentIndex = 0;
930 if ( level.onlineGame && !
IS_TRUE( level.freerun ) )
932 self.death_streak =
self getDStat(
"HighestStats",
"death_streak" );
933 self.kill_streak =
self getDStat(
"HighestStats",
"kill_streak" );
937 self.lastGrenadeSuicideTime = -1;
939 self.teamkillsThisRound = 0;
941 if ( !isdefined( level.livesDoNotReset ) || !level.livesDoNotReset || !isdefined(
self.pers[
"lives"] ) )
943 self.pers[
"lives"] = level.numLives;
947 if ( !level.teamBased )
949 self.pers[
"team"] = undefined;
952 self.hasSpawned =
false;
953 self.waitingToSpawn =
false;
954 self.wantSafeSpawn =
false;
957 self.wasAliveAtMatchStart =
false;
959 level.players[level.players.size] =
self;
961 if( level.splitscreen )
962 SetDvar(
"splitscreen_playerNum", level.players.size );
964 if ( game[
"state"] ==
"postgame" )
966 self.pers[
"needteam"] = 1;
967 self.pers[
"team"] =
"spectator";
968 self.team =
self.sessionteam;
970 self setClientUIVisibilityFlag(
"hud_visible", 0 );
972 self [[level.spawnIntermission]]();
973 self closeInGameMenu();
974 profilelog_endtiming( 4,
"gs=" + game[
"state"] +
" zom=" + SessionModeIsZombiesGame() );
979 if ( ( level.rankedMatch || level.wagerMatch || level.leagueMatch ) && !isdefined(
self.pers[
"lossAlreadyReported"] ) )
981 if ( level.leagueMatch )
983 self recordLeaguePreLoser();
988 self.pers[
"lossAlreadyReported"] =
true;
990 if ((level.rankedMatch || level.leagueMatch) && !isDefined(
self.pers[
"lateJoin"] ) )
992 if (game[
"state"] ==
"playing" && !level.inPrematchPeriod )
994 self.pers[
"lateJoin"] =
true;
998 self.pers[
"lateJoin"] =
false;
1003 if ( !isdefined(
self.pers[
"winstreakAlreadyCleared"] ) )
1006 self.pers[
"winstreakAlreadyCleared"] =
true;
1009 if(
self istestclient() )
1011 self.pers[
"isBot" ] =
true;
1012 recordPlayerStats(
self,
"isBot",
true);
1015 if ( level.rankedMatch || level.leagueMatch )
1020 level endon(
"game_ended" );
1022 if ( isdefined( level.hostMigrationTimer ) )
1025 if ( isdefined(
self.pers[
"team"] ) )
1026 self.team =
self.pers[
"team"];
1028 if ( isdefined(
self.pers[
"class"] ) )
1029 self.curClass =
self.pers[
"class"];
1031 if ( !isdefined(
self.pers[
"team"] ) || isdefined(
self.pers[
"needteam"] ) )
1035 self.pers[
"needteam"] = undefined;
1036 self.pers[
"team"] =
"spectator";
1037 self.team =
"spectator";
1038 self.sessionstate =
"dead";
1042 [[level.spawnSpectator]]();
1044 [[level.autoassign]]( false );
1045 if ( level.rankedMatch || level.leagueMatch )
1050 if (
self.pers[
"team"] ==
"spectator" )
1052 self.sessionteam =
"spectator";
1056 if ( level.teamBased )
1059 self.sessionteam =
self.pers[
"team"];
1060 if ( !isAlive(
self ) )
1061 self.statusicon =
"hud_status_dead";
1065 else if (
self.pers[
"team"] ==
"spectator" )
1067 self SetClientScriptMainMenu( game[
"menu_start_menu" ] );
1068 [[level.spawnSpectator]]();
1069 self.sessionteam =
"spectator";
1070 self.sessionstate =
"spectator";
1075 self.sessionteam =
self.pers[
"team"];
1076 self.sessionstate =
"dead";
1080 [[level.spawnSpectator]]();
1084 self thread [[level.spawnClient]]();
1094 if (
self.sessionteam !=
"spectator" )
1099 if ( level.forceRadar == 1 )
1101 self.pers[
"hasRadar"] =
true;
1102 self.hasSpyplane =
true;
1104 if ( level.teambased )
1106 level.activeUAVs[
self.team]++;
1110 level.activeUAVs[
self getEntityNumber()]++;
1113 level.activePlayerUAVs[
self getEntityNumber()]++;
1116 if ( level.forceRadar == 2 )
1118 self setClientUIVisibilityFlag(
"g_compassShowEnemies", level.forceRadar );
1122 self SetClientUIVisibilityFlag(
"g_compassShowEnemies", 0 );
1125 profilelog_endtiming( 4,
"gs=" + game[
"state"] +
" zom=" + SessionModeIsZombiesGame() );
1127 if ( isdefined(
self.pers[
"isBot"] ) )
1133 num_con = getnumconnectedplayers();
1134 num_exp = getnumexpectedplayers();
1135 /#println(
"all_players_connected(): getnumconnectedplayers=", num_con,
"getnumexpectedplayers=", num_exp );#/
1137 if(num_con == num_exp && (num_exp != 0))
1140 SetDvar(
"all_players_are_connected",
"1" );
1148 if( isdefined( level.disableStatTracking ) && level.disableStatTracking ==
true )
1153 startKills =
self GetDStat(
"playerstatslist",
"kills",
"statValue" );
1154 startDeaths =
self GetDStat(
"playerstatslist",
"deaths",
"statValue" );
1155 startWins =
self GetDStat(
"playerstatslist",
"wins",
"statValue" );
1156 startLosses =
self GetDStat(
"playerstatslist",
"losses",
"statValue" );
1157 startHits =
self GetDStat(
"playerstatslist",
"hits",
"statValue" );
1158 startMisses =
self GetDStat(
"playerstatslist",
"misses",
"statValue" );
1159 startTimePlayedTotal =
self GetDStat(
"playerstatslist",
"time_played_total",
"statValue" );
1160 startScore =
self GetDStat(
"playerstatslist",
"score",
"statValue" );
1161 startPrestige =
self GetDStat(
"playerstatslist",
"plevel",
"statValue" );
1162 startUnlockPoints =
self GetDStat(
"unlocks", 0);
1164 ties =
self GetDStat(
"playerstatslist",
"ties",
"statValue" );
1165 startGamesPlayed = startWins + startLosses + ties;
1167 self.startKills = startKills;
1168 self.startHits = startHits;
1169 self.totalMatchShots = 0;
1171 recordPlayerStats(
self,
"startKills", startKills );
1172 recordPlayerStats(
self,
"startDeaths", startDeaths );
1173 recordPlayerStats(
self,
"startWins", startWins );
1174 recordPlayerStats(
self,
"startLosses", startLosses );
1175 recordPlayerStats(
self,
"startHits", startHits );
1176 recordPlayerStats(
self,
"startMisses", startMisses );
1177 recordPlayerStats(
self,
"startTimePlayedTotal", startTimePlayedTotal );
1178 recordPlayerStats(
self,
"startScore", startScore );
1179 recordPlayerStats(
self,
"startPrestige", startPrestige );
1180 recordPlayerStats(
self,
"startUnlockPoints", startUnlockPoints );
1181 recordPlayerStats(
self,
"startGamesPlayed", startGamesPlayed );
1184 lootXPBeforeMatch =
self GetDStat(
"AfterActionReportStats",
"lootXPBeforeMatch" );
1185 cryptoKeysBeforeMatch =
self GetDStat(
"AfterActionReportStats",
"cryptoKeysBeforeMatch" );
1186 recordPlayerStats(
self,
"lootXPBeforeMatch", lootXPBeforeMatch );
1187 recordPlayerStats(
self,
"cryptoKeysBeforeMatch", cryptoKeysBeforeMatch );
1193 if( isdefined( level.disableStatTracking ) && level.disableStatTracking ==
true )
1198 endKills =
self GetDStat(
"playerstatslist",
"kills",
"statValue" );
1199 endDeaths =
self GetDStat(
"playerstatslist",
"deaths",
"statValue" );
1200 endWins =
self GetDStat(
"playerstatslist",
"wins",
"statValue" );
1201 endLosses =
self GetDStat(
"playerstatslist",
"losses",
"statValue" );
1202 endHits =
self GetDStat(
"playerstatslist",
"hits",
"statValue" );
1203 endMisses =
self GetDStat(
"playerstatslist",
"misses",
"statValue" );
1204 endTimePlayedTotal =
self GetDStat(
"playerstatslist",
"time_played_total",
"statValue" );
1205 endScore =
self GetDStat(
"playerstatslist",
"score",
"statValue" );
1206 endPrestige =
self GetDStat(
"playerstatslist",
"plevel",
"statValue" );
1207 endUnlockPoints =
self GetDStat(
"unlocks", 0);
1209 ties =
self GetDStat(
"playerstatslist",
"ties",
"statValue" );
1210 endGamesPlayed = endWins + endLosses + ties;
1214 recordPlayerStats(
self,
"endKills", endKills );
1215 recordPlayerStats(
self,
"endDeaths", endDeaths );
1216 recordPlayerStats(
self,
"endWins", endWins );
1217 recordPlayerStats(
self,
"endLosses", endLosses );
1218 recordPlayerStats(
self,
"endHits", endHits );
1219 recordPlayerStats(
self,
"endMisses", endMisses );
1220 recordPlayerStats(
self,
"endTimePlayedTotal", endTimePlayedTotal );
1221 recordPlayerStats(
self,
"endScore", endScore );
1222 recordPlayerStats(
self,
"endPrestige", endPrestige );
1223 recordPlayerStats(
self,
"endUnlockPoints", endUnlockPoints );
1224 recordPlayerStats(
self,
"endGamesPlayed", endGamesPlayed );
1230 if( isdefined( level.disableStatTracking ) && level.disableStatTracking ==
true )
1236 recordPlayerStats(
self,
"UTCEndTimeSeconds", getUTC() );
1237 if( isdefined(
self.weaponPickupsCount ) )
1239 recordPlayerStats(
self,
"weaponPickupsCount",
self.weaponPickupsCount );
1241 if( isdefined(
self.killcamsSkipped) )
1243 recordPlayerStats(
self,
"totalKillcamsSkipped",
self.killcamsSkipped );
1245 if( isdefined(
self.matchBonus) )
1247 recordPlayerStats(
self,
"matchXp",
self.matchBonus );
1249 if( isdefined(
self.killsdenied ) )
1251 recordPlayerStats(
self,
"killsDenied",
self.killsdenied );
1253 if( isdefined(
self.killsconfirmed ) )
1255 recordPlayerStats(
self,
"killsConfirmed",
self.killsconfirmed );
1257 if(
self IsSplitscreen() )
1259 recordPlayerStats(
self,
"isSplitscreen",
true );
1263 recordPlayerStats(
self,
"objectiveTime",
self.objtime );
1267 recordPlayerStats(
self,
"escortTime",
self.escorts );
1273 self endon(
"disconnect" );
1278 if ( !level.splitscreen && !level.hardcoreMode && GetDvarint(
"scr_showperksonspawn" ) == 1 && game[
"state"] !=
"postgame" && !isdefined(
self.perkHudelem ) )
1280 if ( level.perksEnabled == 1 )
1286 self.watchingActiveClient =
true;
1287 self.waitingForPlayersText = undefined;
1291 if (
self.pers[
"team"] !=
"spectator" || level.gameEnded )
1294 if ( !
IS_TRUE( level.inPrematchPeriod ) )
1296 self FreezeControls(
false );
1298 self.watchingActiveClient =
false;
1304 for ( i = 0; i < level.players.size; i++ )
1306 if ( level.players[i].team !=
"spectator" )
1315 if ( !
self.watchingActiveClient )
1318 self FreezeControls(
false );
1321 self LUINotifyEvent( &
"player_spawned", 0 );
1324 self.watchingActiveClient =
true;
1328 if (
self.watchingActiveClient )
1330 [[level.onSpawnSpectator]]();
1331 self FreezeControls(
true );
1335 self.watchingActiveClient =
false;
1345 /# println(
"Player " +
self.
name +
" finished migrating at time " + gettime() ); #/
1347 if ( isdefined(
self.connected ) &&
self.connected )
1352 level.hostMigrationReturnedPlayerCount++;
1353 if ( level.hostMigrationReturnedPlayerCount >= level.players.size * 2 / 3 )
1355 /# println(
"2/3 of players have finished migrating" ); #/
1356 level notify(
"hostmigration_enoughplayers" );
1362 profilelog_begintiming( 5,
"ship" );
1364 if ( game[
"state"] !=
"postgame" && !level.gameEnded )
1366 gameLength = game[
"timepassed"];
1371 recordPlayerStats(
self,
"playerQuitRoundNumber", game[
"roundsplayed"] + 1 );
1374 if( level.teambased )
1376 ourTeam =
self.team;
1377 if( ourTeam ==
"allies" || ourTeam ==
"axis" )
1380 if( ourTeam ==
"allies" )
1384 else if( ourTeam ==
"axis" )
1386 theirTeam =
"allies";
1388 recordPlayerStats(
self,
"playerQuitTeamScore", getTeamScore( ourTeam ) );
1389 recordPlayerStats(
self,
"playerQuitOpposingTeamScore", getTeamScore( theirTeam ) );
1399 ArrayRemoveValue( level.players,
self );
1401 if ( level.splitscreen )
1403 players = level.players;
1405 if ( players.size <= 1 )
1409 SetDvar(
"splitscreen_playerNum", players.size );
1412 if ( isdefined(
self.score ) && isdefined(
self.pers[
"team"] ) )
1414 /#print(
"team: score " +
self.pers[
"team"] +
":" +
self.score );#/
1415 level.dropTeam += 1;
1418 [[level.onPlayerDisconnect]]();
1420 lpselfnum =
self getEntityNumber();
1421 lpGuid =
self getGuid();
1422 /#logPrint(
"Q;" + lpGuid +
";" + lpselfnum +
";" +
self.
name +
"\n");#/
1431 for ( entry = 0; entry < level.players.size; entry++ )
1433 if ( level.players[entry] ==
self )
1435 while ( entry < level.players.size-1 )
1437 level.players[entry] = level.players[entry+1];
1440 level.players[entry] = undefined;
1444 for ( entry = 0; entry < level.players.size; entry++ )
1446 if ( isdefined( level.players[entry].pers[
"killed_players"][
self.name] ) )
1447 level.players[entry].pers[
"killed_players"][
self.name] = undefined;
1449 if ( isdefined( level.players[entry].pers[
"killed_players_with_specialist"][
self.name] ) )
1450 level.players[entry].pers[
"killed_players_with_specialist"][
self.name] = undefined;
1452 if ( isdefined( level.players[entry].killedPlayersCurrent[
self.name] ) )
1453 level.players[entry].killedPlayersCurrent[
self.name] = undefined;
1455 if ( isdefined( level.players[entry].pers[
"killed_by"][
self.name] ) )
1456 level.players[entry].pers[
"killed_by"][
self.name] = undefined;
1458 if ( isdefined( level.players[entry].pers[
"nemesis_tracking"][
self.name] ) )
1459 level.players[entry].pers[
"nemesis_tracking"][
self.name] = undefined;
1462 if ( level.players[entry].pers[
"nemesis_name"] ==
self.name )
1468 if ( level.gameEnded )
1474 profilelog_endtiming( 5,
"gs=" + game[
"state"] +
" zom=" + SessionModeIsZombiesGame() );
1481 if ( level.teamBased &&
self.team == eAttacker.team )
1483 if ( level.friendlyfire == 0 )
1489 self finishMeleeHit( eAttacker, weapon, vOrigin, vDir, boneIndex, shieldHit, hit, fromBehind );
1494 nemesisArray =
self.pers[
"nemesis_tracking"];
1495 nemesisArrayKeys = getArrayKeys( nemesisArray );
1499 if ( nemesisArrayKeys.size > 0 )
1501 for ( i = 0; i < nemesisArrayKeys.size; i++ )
1503 nemesisArrayKey = nemesisArrayKeys[i];
1504 if ( nemesisArray[nemesisArrayKey] > nemesisAmount )
1506 nemesisName = nemesisArrayKey;
1507 nemesisAmount = nemesisArray[nemesisArrayKey];
1513 self.pers[
"nemesis_name"] = nemesisName;
1515 if ( nemesisName !=
"" )
1518 for( ; playerIndex < level.players.size; playerIndex++ )
1520 if ( level.players[playerIndex].name == nemesisName )
1522 nemesisPlayer = level.players[playerIndex];
1523 self.pers[
"nemesis_rank"] = nemesisPlayer.pers[
"rank"];
1524 self.pers[
"nemesis_rankIcon"] = nemesisPlayer.pers[
"rankxp"];
1525 self.pers[
"nemesis_xp"] = nemesisPlayer.pers[
"prestige"];
1526 self.pers[
"nemesis_xuid"] = nemesisPlayer GetXUID();
1533 self.pers[
"nemesis_xuid"] =
"";
1540 if ( level.onlinegame && !SessionModeIsPrivate() )
1545 if( isdefined( eAttacker) && isdefined( eAttacker.damageModifier ) )
1547 iDamage *= eAttacker.damageModifier;
1549 if ( ( sMeansOfDeath ==
"MOD_PISTOL_BULLET" ) || ( sMeansOfDeath ==
"MOD_RIFLE_BULLET" ) )
1551 iDamage = int( iDamage * level.bulletDamageScalar );
1559 if ( isdefined(eAttacker) )
1561 if( isai(eAttacker) && isdefined( eAttacker.script_owner ) )
1565 if ( eAttacker.script_owner.team != team )
1566 eAttacker = eAttacker.script_owner;
1569 if( eAttacker.classname ==
"script_vehicle" && isdefined( eAttacker.owner ) )
1570 eAttacker = eAttacker.owner;
1571 else if( eAttacker.classname ==
"auto_turret" && isdefined( eAttacker.owner ) )
1572 eAttacker = eAttacker.owner;
1573 else if( eAttacker.classname ==
"actor_spawner_bo3_robot_grunt_assault_mp" && isdefined( eAttacker.owner ) )
1574 eAttacker = eAttacker.owner;
1583 if ( weapon == level.weaponNone && isdefined( eInflictor ) )
1585 if ( isdefined( eInflictor.targetname ) && eInflictor.targetname ==
"explodable_barrel" )
1587 weapon = GetWeapon(
"explodable_barrel" );
1589 else if ( isdefined( eInflictor.destructible_type ) && isSubStr( eInflictor.destructible_type,
"vehicle_" ) )
1591 weapon = GetWeapon(
"destructible_car" );
1593 else if( isdefined( eInflictor.scriptvehicletype ) )
1595 veh_weapon = GetWeapon( eInflictor.scriptvehicletype );
1596 if( isdefined( veh_weapon ) )
1598 weapon = veh_weapon;
1603 if ( isdefined( eInflictor ) && isdefined( eInflictor.script_noteworthy ) )
1605 if ( IsDefined( level.overrideWeaponFunc ) )
1607 weapon = [[level.overrideWeaponFunc]]( weapon, eInflictor.script_noteworthy );
1616 if ( level.hardcoreMode && level.friendlyfire > 0 && isdefined( victim ) && victim.is_capturing_own_supply_drop ===
true )
1628 if ( isdefined( level.figure_out_gametype_friendly_fire ) )
1630 return [[ level.figure_out_gametype_friendly_fire ]]( victim );
1633 return level.friendlyfire;
1638 if ( level.hardcoreMode )
1641 if ( !isdefined( eAttacker ) )
1644 if (
self != eAttacker )
1647 return weapon.doNotDamageOwner;
1653 if ( game[
"state"] ==
"postgame" )
1656 if (
self.sessionteam ==
"spectator" )
1659 if ( isdefined(
self.canDoCombat ) && !
self.canDoCombat )
1662 if ( isdefined( eAttacker ) && isPlayer( eAttacker ) && isdefined( eAttacker.canDoCombat ) && !eAttacker.canDoCombat )
1665 if ( isdefined( level.hostMigrationTimer ) )
1668 if ( level.onlyHeadShots )
1670 if ( sMeansOfDeath ==
"MOD_PISTOL_BULLET" || sMeansOfDeath ==
"MOD_RIFLE_BULLET" )
1678 if ( weapon.isSupplyDropWeapon && !weapon.isGrenadeWeapon && ( smeansofdeath !=
"MOD_TRIGGER_HURT" ) )
1681 if (
self.scene_takedamage ===
false )
1691 function apply_damage_to_armor( eInflictor, eAttacker, iDamage, sMeansOfDeath, weapon, sHitLoc, friendlyFire, ignore_round_start_friendly_fire )
1699 if( IsDefined( victim.lightArmorHP ) )
1701 if ( weapon.ignoresLightArmor && sMeansOfDeath !=
"MOD_MELEE" )
1705 else if ( weapon.meleeIgnoresLightArmor && sMeansOfDeath ==
"MOD_MELEE" )
1710 else if( IsDefined( eInflictor ) && IsDefined( eInflictor.stuckToPlayer ) && eInflictor.stuckToPlayer == victim )
1712 iDamage = victim.health;
1718 if ( sMeansOfDeath !=
"MOD_FALLING"
1726 if ( victim.lightArmorHP <= 0 )
1729 iDamage = abs( victim.lightArmorHP );
1751 return int(iDamage);
1756 friendlyfire = [[ level.figure_out_friendly_fire ]]( self );
1759 if ( friendlyfire == 2 || friendlyfire == 3 )
1761 iDamage = int(iDamage * .5);
1767 function modify_player_damage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex )
1769 if ( isdefined(
self.overridePlayerDamage ) )
1771 iDamage =
self [[
self.overridePlayerDamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex );
1773 else if ( isdefined( level.overridePlayerDamage ) )
1775 iDamage =
self [[level.overridePlayerDamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex );
1778 assert(isdefined(iDamage),
"You must return a value from a damage override function.");
1780 if ( isdefined( eAttacker ) )
1784 if( isdefined( eAttacker.pickup_damage_scale ) && eAttacker.pickup_damage_scale_time > GetTime() )
1786 iDamage = iDamage * eAttacker.pickup_damage_scale;
1793 modifiedDamage = [[level.onPlayerDamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime );
1795 if ( isdefined( modifiedDamage ) )
1797 if ( modifiedDamage <= 0 )
1800 iDamage = modifiedDamage;
1804 if ( level.onlyHeadShots )
1806 if ( sMeansOfDeath ==
"MOD_HEAD_SHOT" )
1810 if ( weapon.damageAlwaysKillsPlayer )
1812 iDamage =
self.maxHealth + 1;
1815 if ( sHitLoc ==
"riotshield" )
1826 if ( isdefined( eInflictor ) && isdefined( eInflictor.stuckToPlayer ) && eInflictor.stuckToPlayer == self )
1829 iDamage =
self.maxhealth + 1;
1834 return int(iDamage);
1839 if (
globallogic_utils::isHeadShot( weapon, sHitLoc, sMeansOfDeath, eInflictor ) && isPlayer(eAttacker) && !weapon_utils::ismeleemod( sMeansOfDeath ) )
1841 sMeansOfDeath =
"MOD_HEAD_SHOT";
1844 if ( isdefined( eInflictor ) && isdefined( eInflictor.script_noteworthy ) )
1846 if ( eInflictor.script_noteworthy ==
"ragdoll_now" )
1848 sMeansOfDeath =
"MOD_FALLING";
1852 return sMeansOfDeath;
1857 if ( isdefined( eInflictor ) && isPlayer( eAttacker ) && eAttacker == eInflictor )
1859 if ( sMeansOfDeath ==
"MOD_HEAD_SHOT" || sMeansOfDeath ==
"MOD_PISTOL_BULLET" || sMeansOfDeath ==
"MOD_RIFLE_BULLET" )
1868 if ( isPlayer( eAttacker ) )
1869 eAttacker.pers[
"participation"]++;
1879 if ( weapon.explosionradius == 0 )
1882 distSqr = ( ( isdefined( eInflictor ) && isdefined(
self.lastSpawnPoint ) ) ? DistanceSquared( eInflictor.origin,
self.lastSpawnPoint.origin ) : 0 );
1885 if ( distSqr <
SQR( 250 ) )
1887 if ( sMeansOfDeath ==
"MOD_GRENADE" || sMeansOfDeath ==
"MOD_GRENADE_SPLASH" )
1892 if ( sMeansOfDeath ==
"MOD_PROJECTILE" || sMeansOfDeath ==
"MOD_PROJECTILE_SPLASH" )
1897 if ( sMeansOfDeath ==
"MOD_EXPLOSIVE" )
1911 function player_damage_update_explosive_info( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex )
1932 self.explosiveInfo = [];
1933 self.explosiveInfo[
"damageTime"] = getTime();
1934 self.explosiveInfo[
"damageId"] = eInflictor getEntityNumber();
1935 self.explosiveInfo[
"originalOwnerKill"] =
false;
1936 self.explosiveInfo[
"bulletPenetrationKill"] =
false;
1937 self.explosiveInfo[
"chainKill"] =
false;
1938 self.explosiveInfo[
"damageExplosiveKill"] =
false;
1939 self.explosiveInfo[
"chainKill"] =
false;
1940 self.explosiveInfo[
"cookedKill"] =
false;
1941 self.explosiveInfo[
"weapon"] = weapon;
1942 self.explosiveInfo[
"originalowner"] = eInflictor.originalowner;
1944 isFrag = ( weapon.rootweapon.name ==
"frag_grenade" );
1946 if ( isdefined( eAttacker ) && eAttacker != self )
1948 if ( isdefined( eAttacker ) && isdefined( eInflictor.owner ) && (weapon.name ==
"satchel_charge" || weapon.name ==
"claymore" || weapon.name ==
"bouncingbetty") )
1950 self.explosiveInfo[
"originalOwnerKill"] = (eInflictor.owner ==
self);
1951 self.explosiveInfo[
"damageExplosiveKill"] = isdefined( eInflictor.wasDamaged );
1952 self.explosiveInfo[
"chainKill"] = isdefined( eInflictor.wasChained );
1953 self.explosiveInfo[
"wasJustPlanted"] = isdefined( eInflictor.wasJustPlanted );
1954 self.explosiveInfo[
"bulletPenetrationKill"] = isdefined( eInflictor.wasDamagedFromBulletPenetration );
1955 self.explosiveInfo[
"cookedKill"] =
false;
1957 if ( isdefined( eInflictor ) && isdefined( eInflictor.stuckToPlayer ) && weapon.projExplosionType ==
"grenade" )
1959 self.explosiveInfo[
"stuckToPlayer"] = eInflictor.stuckToPlayer;
1961 if ( weapon.doStun )
1963 self.lastStunnedBy = eAttacker;
1964 self.lastStunnedTime =
self.iDFlagsTime;
1966 if ( isdefined( eAttacker.lastGrenadeSuicideTime ) && eAttacker.lastGrenadeSuicideTime >= gettime() - 50 && isFrag )
1968 self.explosiveInfo[
"suicideGrenadeKill"] =
true;
1972 self.explosiveInfo[
"suicideGrenadeKill"] =
false;
1978 self.explosiveInfo[
"cookedKill"] = isdefined( eInflictor.isCooked );
1979 self.explosiveInfo[
"throwbackKill"] = isdefined( eInflictor.threwBack );
1982 if( isdefined( eAttacker ) && isPlayer( eAttacker ) && eAttacker !=
self )
1988 if( sMeansOfDeath ==
"MOD_IMPACT" && isdefined( eAttacker ) && isPlayer( eAttacker ) && eAttacker !=
self )
1990 if ( weapon != level.weaponBallisticKnife )
1995 if ( weapon.rootweapon.name ==
"hatchet" && isdefined( eInflictor ) )
1997 self.explosiveInfo[
"projectile_bounced"] = isdefined( eInflictor.bounced );
2007 if( level.friendlyFireDelay && level.friendlyFireDelayTime >= ( ( ( gettime() - level.startTime ) - level.discardTime ) / 1000 ) )
2017 if ( !IsAlive( eAttacker ) )
2020 friendlyfire = [[ level.figure_out_friendly_fire ]]( self );
2022 if ( friendlyfire == 1 )
2031 if ( friendlyfire == 2 )
2036 if ( friendlyfire == 3 )
2046 friendlyfire = [[ level.figure_out_friendly_fire ]]( self );
2048 if ( friendlyfire == 1 )
2059 if ( friendlyfire == 3 )
2069 if (( sMeansOfDeath ==
"MOD_PISTOL_BULLET" || sMeansOfDeath ==
"MOD_RIFLE_BULLET" ) &&
2071 ( !attackerIsHittingTeammate ) )
2073 if (
self.hasRiotShieldEquipped )
2075 if ( isPlayer( eAttacker ))
2077 eAttacker.lastAttackedShieldPlayer =
self;
2078 eAttacker.lastAttackedShieldTime = getTime();
2081 previous_shield_damage =
self.shieldDamageBlocked;
2082 self.shieldDamageBlocked += iDamage;
2084 if ((
self.shieldDamageBlocked % 400 ) < ( previous_shield_damage % 400 ))
2086 score_event =
"shield_blocked_damage";
2088 if ((
self.shieldDamageBlocked > 2000 ))
2090 score_event =
"shield_blocked_damage_reduced";
2093 if ( isdefined( level.scoreInfo[ score_event ][
"value"] ) )
2096 self AddWeaponStat( level.weaponRiotshield,
"score_from_blocked_damage", level.scoreInfo[ score_event ][
"value"] );
2111 if ( friendlyFire && level.friendlyfire == 0 )
2114 if ( sHitLoc ==
"riotshield" )
2121 if( weapon.isEmp && sMeansOfDeath ==
"MOD_GRENADE_SPLASH" )
2123 if(
self hasperk(
"specialty_immuneemp") )
2131 function player_damage_log( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex )
2133 if(
self.sessionstate !=
"dead")
2135 lpselfnum =
self getEntityNumber();
2136 lpselfname =
self.name;
2137 lpselfteam =
self.team;
2138 lpselfGuid =
self getGuid();
2139 lpattackerteam =
"";
2140 lpattackerorigin = ( 0, 0, 0 );
2142 if(isPlayer(eAttacker))
2144 lpattacknum = eAttacker getEntityNumber();
2145 lpattackGuid = eAttacker getGuid();
2146 lpattackname = eAttacker.name;
2147 lpattackerteam = eAttacker.team;
2148 lpattackerorigin = eAttacker.origin;
2149 isusingheropower = 0;
2152 isusingheropower = 1;
2160 lpattackerteam =
"world";
2162 /#logPrint(
"D;" + lpselfGuid +
";" + lpselfnum +
";" + lpselfteam +
";" + lpselfname +
";" + lpattackGuid +
";" + lpattacknum +
";" + lpattackerteam +
";" + lpattackname +
";" + weapon.name +
";" + iDamage +
";" + sMeansOfDeath +
";" + sHitLoc +
"\n");#/
2168 if ( sMeansOfDeath ==
"MOD_TRIGGER_HURT" || sMeansOfDeath ==
"MOD_CRUSH" )
2174 function do_post_game_damage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal )
2176 if ( game[
"state"] !=
"postgame" )
2183 self finishPlayerDamage( eInflictor, eAttacker, iDamage, iDFlags,
"MOD_POST_GAME", weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal );
2186 function Callback_PlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal )
2188 profilelog_begintiming( 6,
"ship" );
2190 do_post_game_damage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal );
2192 if ( sMeansOfDeath ==
"MOD_CRUSH" && isdefined( eInflictor ) && ( eInflictor.deal_no_crush_damage ===
true ) )
2197 if ( isdefined( eInflictor ) && eInflictor.killstreakType ===
"siegebot" )
2199 if ( eInflictor.team ===
"neutral" )
2203 self.iDFlags = iDFlags;
2204 self.iDFlagsTime = getTime();
2207 if ( !IsPlayer( eAttacker ) && isdefined( eAttacker ) && eAttacker.owner ===
self )
2209 treat_self_damage_as_friendly_fire = eAttacker.treat_owner_damage_as_friendly_fire;
2213 ignore_round_start_friendly_fire = ( isdefined( eInflictor ) && ( sMeansOfDeath ==
"MOD_CRUSH" ) || sMeansOfDeath ==
"MOD_HIT_BY_OBJECT" );
2218 if ( IsPlayer( eAttacker ) &&
IS_TRUE( eAttacker.laststand ) )
2233 if( !isdefined( vDir ) )
2236 attackerIsHittingTeammate = isPlayer( eAttacker ) && (
self util::IsEnemyPlayer( eAttacker ) == false );
2237 attackerIsHittingSelf = IsPlayer( eAttacker ) && (
self == eAttacker);
2239 friendlyFire = ( ( attackerIsHittingSelf && treat_self_damage_as_friendly_fire === true )
2240 || ( level.teamBased && !attackerIsHittingSelf && attackerIsHittingTeammate ) );
2242 iDamage =
modify_player_damage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex );
2248 if(
IS_TRUE(
self.power_armor_took_damage ) )
2253 if ( sHitLoc ==
"riotshield" )
2271 iDamage =
apply_damage_to_armor( eInflictor, eAttacker, iDamage, sMeansOfDeath, weapon, sHitLoc, friendlyFire, ignore_round_start_friendly_fire );
2277 if ( sHitLoc ==
"riotshield" )
2282 if ( !
player_damage_update_explosive_info( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex ) )
2285 prevHealthRatio =
self.health /
self.maxhealth;
2291 self.lastDamageWasFromEnemy =
false;
2293 self finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal);
2295 else if ( weapon.forceDamageShellshockAndRumble )
2302 eAttacker.lastDamageWasFromEnemy =
false;
2304 eAttacker.friendlydamage =
true;
2305 eAttacker
finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal);
2306 eAttacker.friendlydamage = undefined;
2313 self.lastAttackWeapon = weapon;
2317 if ( isdefined( eAttacker ) )
2318 level.lastLegitimateAttacker = eAttacker;
2320 if ( ( sMeansOfDeath ==
"MOD_GRENADE" || sMeansOfDeath ==
"MOD_GRENADE_SPLASH" ) && isdefined( eInflictor ) && isdefined( eInflictor.isCooked ) )
2321 self.wasCooked = getTime();
2323 self.wasCooked = undefined;
2325 self.lastDamageWasFromEnemy = (isdefined( eAttacker ) && (eAttacker !=
self));
2327 if (
self.lastDamageWasFromEnemy )
2329 if ( isplayer( eAttacker ) )
2331 if ( isdefined ( eAttacker.damagedPlayers[
self.clientId ] ) == false )
2332 eAttacker.damagedPlayers[
self.clientId ] = spawnstruct();
2334 eAttacker.damagedPlayers[
self.clientId ].time = getTime();
2335 eAttacker.damagedPlayers[
self.clientId ].entity =
self;
2341 if( isDefined(eAttacker.heroweaponHits) )
2343 eAttacker.heroweaponHits++;
2347 self finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal);
2350 if ( isdefined( eAttacker ) && !attackerIsHittingSelf )
2355 if ( iDamage > 0 &&
self.health > 0 )
2357 perkFeedback =
doPerkFeedBack(
self, weapon, sMeansOfDeath, eInflictor, armor_damaged );
2360 eAttacker thread
damagefeedback::update( sMeansOfDeath, eInflictor, perkFeedback, weapon,
self, psOffsetTime, sHitLoc );
2364 if( !isdefined(eAttacker) || !friendlyFire ||
IS_TRUE( level.hardcoreMode ) )
2369 self.hasDoneCombat =
true;
2371 if( weapon.isEmp && sMeansOfDeath ==
"MOD_GRENADE_SPLASH" )
2373 if( !
self hasperk(
"specialty_immuneemp") )
2375 self notify(
"emp_grenaded", eAttacker, vPoint );
2379 if ( isdefined( eAttacker ) && eAttacker !=
self && !friendlyFire )
2380 level.useStartSpawns =
false;
2382 player_damage_log( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex );
2384 profilelog_endtiming( 6,
"gs=" + game[
"state"] +
" zom=" + SessionModeIsZombiesGame() );
2389 self.attackers = [];
2390 self.attackerData = [];
2391 self.attackerDamage = [];
2392 self.firstTimeDamaged = 0;
2397 self.attackersThisSpawn = [];
2402 perkFeedback = undefined;
2404 hasFlakJacket = ( player HasPerk(
"specialty_flakjacket" ) );
2410 perkFeedback =
"tacticalMask";
2414 perkFeedback =
"flakjacket";
2418 perkFeedback =
"flakjacket";
2420 else if ( armor_damaged )
2422 perkFeedback =
"armor";
2425 return perkFeedback;
2430 if ( weapon.isAIKillstreakDamage )
2432 if ( weapon.name !=
"ai_tank_drone_rocket" || isdefined( eInflictor.firedByAI ) )
2441 function finishPlayerDamageWrapper( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal )
2446 println(
"penetrated:" +
self getEntityNumber() +
" health:" +
self.health +
" attacker:" + eAttacker.clientid +
" inflictor is player:" + isPlayer(eInflictor) +
" damage:" + iDamage +
" hitLoc:" + sHitLoc);
2448 eAttacker AddPlayerStat(
"penetration_shots", 1 );
2451 if ( GetDvarString(
"scr_csmode" ) !=
"" )
2452 self shellShock(
"damage_mp", 0.2 );
2458 if( isPlayer( eAttacker) )
2460 self.lastShotBy = eAttacker.clientid;
2463 if ( sMeansOfDeath ==
"MOD_BURNED" )
2468 self.gadget_was_active_last_damage =
self GadgetIsActive( 0 );
2470 self finishPlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal );
2486 if( !isdefined(
self.switching_teams ) )
2489 if ( isPlayer( attacker ) && level.teamBased && ( attacker !=
self ) && (
self.team == attacker.team ) )
2492 self.pers[
"cur_kill_streak"] = 0;
2493 self.pers[
"cur_total_kill_streak"] = 0;
2494 self.pers[
"totalKillstreakCount"] = 0;
2495 self.pers[
"killstreaksEarnedThisKillstreak"] = 0;
2496 self setplayercurrentstreak( 0 );
2502 self UpdateStatRatio(
"kdratio",
"kills",
"deaths" );
2504 if(
self.pers[
"cur_kill_streak"] >
self.pers[
"best_kill_streak"] )
2505 self.pers[
"best_kill_streak"] =
self.pers[
"cur_kill_streak"];
2508 self.pers[
"kill_streak_before_death"] =
self.pers[
"cur_kill_streak"];
2511 self.pers[
"cur_kill_streak"] = 0;
2512 self.pers[
"cur_total_kill_streak"] = 0;
2513 self.pers[
"totalKillstreakCount"] = 0;
2514 self.pers[
"killstreaksEarnedThisKillstreak"] = 0;
2515 self setplayercurrentstreak( 0 );
2517 self.cur_death_streak++;
2519 if (
self.cur_death_streak >
self.death_streak )
2521 if ( level.rankedMatch && !level.disableStatTracking )
2523 self setDStat(
"HighestStats",
"death_streak",
self.cur_death_streak );
2525 self.death_streak =
self.cur_death_streak;
2528 if(
self.cur_death_streak >= GetDvarint(
"perk_deathStreakCountRequired" ) )
2530 self enabledeathstreak();
2536 self.pers[
"totalKillstreakCount"] = 0;
2537 self.pers[
"killstreaksEarnedThisKillstreak"] = 0;
2542 level.globalKillstreaksDeathsFrom++;
2549 if ( isPlayer( attacker ) && attacker !=
self && ( !level.teamBased || ( level.teamBased &&
self.team != attacker.team ) ) )
2551 attackerWeaponPickedUp =
false;
2552 if( isdefined( attacker.pickedUpWeapons ) && isdefined( attacker.pickedUpWeapons[weapon] ) )
2554 attackerWeaponPickedUp =
true;
2556 self AddWeaponStat( weapon,
"deaths", 1,
self.class_num, attackerWeaponPickedUp, undefined,
self.primaryLoadoutGunSmithVariantIndex,
self.secondaryLoadoutGunSmithVariantIndex );
2558 if ( wasInLastStand && isdefined( lastWeaponBeforeDroppingIntoLastStand ) )
2559 victim_weapon = lastWeaponBeforeDroppingIntoLastStand;
2561 victim_weapon =
self.lastdroppableweapon;
2563 if ( isdefined( victim_weapon ) )
2565 victimWeaponPickedUp =
false;
2566 if( isdefined(
self.pickedUpWeapons ) && isdefined(
self.pickedUpWeapons[victim_weapon] ) )
2568 victimWeaponPickedUp =
true;
2570 self AddWeaponStat( victim_weapon,
"deathsDuringUse", 1,
self.class_num, victimWeaponPickedUp, undefined,
self.primaryLoadoutGunSmithVariantIndex,
self.secondaryLoadoutGunSmithVariantIndex );
2574 recordWeaponStatKills =
true;
2575 if ( ( attacker.isThief ===
true ) && isdefined( weapon ) && ( weapon.isHeroWeapon ===
true ) )
2577 recordWeaponStatKills =
false;
2580 if ( sMeansOfDeath !=
"MOD_FALLING" && recordWeaponStatKills )
2582 if ( weapon.name ==
"explosive_bolt" && IsDefined( inflictor ) && IsDefined( inflictor.ownerWeaponAtLaunch ) && inflictor.ownerAdsAtLaunch )
2584 inflictorOwnerWeaponAtLaunchPickedUp =
false;
2585 if( isdefined( attacker.pickedUpWeapons ) && isdefined( attacker.pickedUpWeapons[inflictor.ownerWeaponAtLaunch] ) )
2587 inflictorOwnerWeaponAtLaunchPickedUp =
true;
2589 attacker AddWeaponStat( inflictor.ownerWeaponAtLaunch,
"kills", 1, attacker.class_num, inflictorOwnerWeaponAtLaunchPickedUp,
true, attacker.primaryLoadoutGunSmithVariantIndex, attacker.secondaryLoadoutGunSmithVariantIndex );
2593 attacker AddWeaponStat( weapon,
"kills", 1, attacker.class_num, attackerWeaponPickedUp, undefined, attacker.primaryLoadoutGunSmithVariantIndex, attacker.secondaryLoadoutGunSmithVariantIndex );
2597 if ( sMeansOfDeath ==
"MOD_HEAD_SHOT" )
2599 attacker AddWeaponStat( weapon,
"headshots", 1, attacker.class_num, attackerWeaponPickedUp, undefined, attacker.primaryLoadoutGunSmithVariantIndex, attacker.secondaryLoadoutGunSmithVariantIndex );
2602 if ( sMeansOfDeath ==
"MOD_PROJECTILE" || ( ( sMeansOfDeath ==
"MOD_GRENADE" || sMeansOfDeath ==
"MOD_IMPACT" ) && weapon.rootWeapon.statIndex == level.weaponLauncherEx41.statIndex ) )
2604 attacker AddWeaponStat( weapon,
"direct_hit_kills", 1 );
2607 victimIsRoulette = (
self.isRoulette === true );
2610 attacker AddWeaponStat( attacker.heroAbility,
"kills_while_active", 1 );
2619 level notify(
"reset_obituary_count" );
2620 level.lastObituaryPlayerCount = 0;
2621 level.lastObituaryPlayer = undefined;
2625 if ( isdefined( level.lastObituaryPlayer ) && level.lastObituaryPlayer == attacker )
2627 level.lastObituaryPlayerCount++;
2631 level notify(
"reset_obituary_count" );
2632 level.lastObituaryPlayer = attacker;
2633 level.lastObituaryPlayerCount = 1;
2638 if ( level.lastObituaryPlayerCount >= 4 )
2640 level notify(
"reset_obituary_count" );
2641 level.lastObituaryPlayerCount = 0;
2642 level.lastObituaryPlayer = undefined;
2654 if( isdefined( eInflictor ) && ( eInflictor.archetype ===
"robot" ) )
2656 if( sMeansOfDeath ==
"MOD_HIT_BY_OBJECT" )
2657 weapon = GetWeapon(
"combat_robot_marker" );
2658 sMeansOfDeath =
"MOD_RIFLE_BULLET";
2661 if( level.teamBased && isdefined( attacker.pers ) &&
self.team == attacker.team && sMeansOfDeath ==
"MOD_GRENADE" && level.friendlyfire == 0 )
2663 obituary(
self,
self, weapon, sMeansOfDeath);
2664 demo::bookmark(
"kill", gettime(),
self,
self, 0, eInflictor, overrideEntityCamera );
2668 obituary(
self, attacker, weapon, sMeansOfDeath);
2669 demo::bookmark(
"kill", gettime(), attacker,
self, 0, eInflictor, overrideEntityCamera );
2675 awardAssists =
false;
2676 self.suicide =
false;
2679 if ( isdefined(
self.switching_teams ) )
2682 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 ] ) )
2685 playerCounts[
self.leaving_team]--;
2686 playerCounts[
self.joining_team]++;
2688 if( (playerCounts[
self.joining_team] - playerCounts[
self.leaving_team]) > 1 )
2694 self.suicide =
true;
2704 if ( sMeansOfDeath ==
"MOD_SUICIDE" && sHitLoc ==
"none" &&
self.throwingGrenade )
2706 self.lastGrenadeSuicideTime = gettime();
2709 if ( level.maxSuicidesBeforeKick > 0 && level.maxSuicidesBeforeKick <=
self.suicides )
2712 self notify(
"teamKillKicked" );
2720 awardAssists =
true;
2721 self.suicide =
true;
2724 if( isdefined(
self.friendlydamage ) )
2726 self iPrintLn(&
"MP_FRIENDLY_FIRE_WILL_NOT");
2727 if ( level.teamKillPointLoss )
2729 scoreSub =
self [[level.getTeamKillScore]]( eInflictor, attacker, sMeansOfDeath, weapon);
2740 return awardAssists;
2747 self.teamKilled =
true;
2751 teamkill_penalty =
self [[level.getTeamKillPenalty]]( eInflictor, attacker, sMeansOfDeath, weapon);
2755 attacker.teamkillsThisRound++;
2757 if ( level.teamKillPointLoss )
2759 scoreSub =
self [[level.getTeamKillScore]]( eInflictor, attacker, sMeansOfDeath, weapon);
2778 if ( teamKillDelay > 0 )
2780 attacker.teamKillPunish =
true;
2786 attacker notify(
"teamKillKicked" );
2794 if( isPlayer( attacker ) )
2801 self endon(
"disconnect" );
2811 if ( isdefined(
self.attackers ) )
2813 for ( j = 0; j <
self.attackers.size; j++ )
2815 player =
self.attackers[j];
2817 if ( !isdefined( player ) )
2820 if ( player == attacker )
2823 if ( player.team != lpattackteam )
2826 damage_done =
self.attackerDamage[player.clientId].damage;
2831 if ( level.teamBased )
2836 if ( isdefined(
self.lastAttackedShieldPlayer ) && isdefined(
self.lastAttackedShieldTime ) &&
self.lastAttackedShieldPlayer != attacker )
2838 if ( gettime() -
self.lastAttackedShieldTime < 4000 )
2850 if( GetDvarInt(
"teamOpsEnabled" ) == 1 )
2852 if( isdefined( eInflictor ) &&
IS_TRUE( eInflictor.teamops ) )
2863 if ( isAlive( attacker ) )
2865 if ( !isdefined( eInflictor ) || !isdefined( eInflictor.requiredDeathCount ) || attacker.deathCount == eInflictor.requiredDeathCount )
2870 if ( shouldGiveKillstreak )
2875 attacker.pers[
"cur_total_kill_streak"]++;
2876 attacker setplayercurrentstreak( attacker.pers[
"cur_total_kill_streak"] );
2879 if ( isdefined( level.killstreaks ) && shouldGiveKillstreak )
2881 attacker.pers[
"cur_kill_streak"]++;
2883 if ( attacker.pers[
"cur_kill_streak"] >= 2 )
2885 if ( attacker.pers[
"cur_kill_streak"] == 10 )
2889 if ( attacker.pers[
"cur_kill_streak"] <= 30 )
2893 if ( attacker.pers[
"cur_kill_streak"] == 30 )
2904 if ( !isdefined( level.usingMomentum ) || !level.usingMomentum )
2906 if( GetDvarInt(
"teamOpsEnabled" ) == 0 )
2913 if ( attacker.pers[
"cur_kill_streak"] > attacker.kill_streak )
2915 if ( level.rankedMatch && !level.disableStatTracking )
2917 attacker setDStat(
"HighestStats",
"kill_streak", attacker.pers[
"totalKillstreakCount"] );
2919 attacker.kill_streak = attacker.pers[
"cur_kill_streak"];
2923 if ( attacker.pers[
"cur_kill_streak"] > attacker.gametype_kill_streak )
2926 attacker.gametype_kill_streak = attacker.pers[
"cur_kill_streak"];
2931 if ( isdefined( killstreak ) )
2938 if( isdefined( eInflictor ) && ( killstreak ==
"dart" || killstreak ==
"inventory_dart" ) )
2940 eInflictor notify(
"veh_collision" );
2948 if ( sMeansOfDeath ==
"MOD_HEAD_SHOT" )
2961 attackerName = attacker.name;
2968 if ( level.teamBased && attacker.team !=
"spectator")
2970 if( !isdefined( killstreak ) ||
IS_TRUE( level.killstreaksGiveGameScore ) )
2974 scoreSub = level.deathPointLoss;
2975 if ( scoreSub != 0 )
2985 if ( sMeansOfDeath ==
"MOD_POST_GAME" )
2991 function do_post_game_death(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration)
2998 self.sessionstate =
"dead";
2999 self.spectatorclient = -1;
3000 self.killcamentity = -1;
3001 self.archivetime = 0;
3002 self.psoffsettime = 0;
3004 clone_weapon = weapon;
3010 clone_weapon = level.weaponNone;
3012 body =
self clonePlayer( deathAnimDuration, clone_weapon, attacker );
3014 if ( isdefined( body ) )
3016 self createDeadBody( attacker, iDamage, sMeansOfDeath, weapon, sHitLoc, vDir, (0,0,0), deathAnimDuration, eInflictor, body );
3020 function Callback_PlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, enteredResurrect =
false)
3022 profilelog_begintiming( 7,
"ship" );
3024 self endon(
"spawned" );
3027 if ( game[
"state"] ==
"postgame" )
3029 do_post_game_death(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration);
3033 if (
self.sessionteam ==
"spectator" )
3036 self notify(
"killed_player" );
3039 self needsRevive(
false );
3041 if ( isdefined(
self.burning ) &&
self.burning ==
true )
3046 self.suicide =
false;
3047 self.teamKilled =
false;
3049 if ( isdefined( level.takeLivesOnDeath ) && ( level.takeLivesOnDeath ==
true ) )
3051 if (
self.pers[
"lives"] )
3053 self.pers[
"lives"]--;
3054 if (
self.pers[
"lives"] == 0 )
3056 level notify(
"player_eliminated" );
3057 self notify(
"player_eliminated" );
3060 if ( game[
self.team +
"_lives"] )
3062 game[
self.team +
"_lives"]--;
3063 if ( game[
self.team +
"_lives"] == 0 )
3065 level notify(
"player_eliminated" );
3066 self notify(
"player_eliminated" );
3076 wasInLastStand =
false;
3078 deathTimeOffset = 0;
3079 lastWeaponBeforeDroppingIntoLastStand = undefined;
3080 attackerStance = undefined;
3081 self.lastStandThisLife = undefined;
3082 self.vAttackerOrigin = undefined;
3085 weapon_at_time_of_death =
self GetCurrentWeapon();
3087 if ( isdefined(
self.useLastStandParams ) && enteredResurrect ==
false )
3089 self.useLastStandParams = undefined;
3091 assert( isdefined(
self.lastStandParams ) );
3092 if ( !level.teamBased || ( !isdefined( attacker ) || !isplayer( attacker ) || attacker.team !=
self.team || attacker ==
self ) )
3094 eInflictor =
self.lastStandParams.eInflictor;
3095 attacker =
self.lastStandParams.attacker;
3096 attackerStance =
self.lastStandParams.attackerStance;
3097 iDamage =
self.lastStandParams.iDamage;
3098 sMeansOfDeath =
self.lastStandParams.sMeansOfDeath;
3099 weapon =
self.lastStandParams.sWeapon;
3100 vDir =
self.lastStandParams.vDir;
3101 sHitLoc =
self.lastStandParams.sHitLoc;
3102 self.vAttackerOrigin =
self.lastStandParams.vAttackerOrigin;
3103 self.killcam_entity_info_cached =
self.lastStandParams.killcam_entity_info_cached;
3104 deathTimeOffset = (gettime() -
self.lastStandParams.lastStandStartTime) / 1000;
3106 if ( isdefined(
self.previousPrimary ) )
3108 wasInLastStand =
true;
3109 lastWeaponBeforeDroppingIntoLastStand =
self.previousPrimary;
3112 self.lastStandParams = undefined;
3117 bestPlayer = undefined;
3118 bestPlayerMeansOfDeath = undefined;
3119 obituaryMeansOfDeath = undefined;
3120 bestPlayerWeapon = undefined;
3121 obituaryWeapon = weapon;
3122 assistedSuicide =
false;
3123 if ( (!isdefined( attacker ) || attacker.classname ==
"trigger_hurt" || attacker.classname ==
"worldspawn" || ( isdefined( attacker.isMagicBullet ) && attacker.isMagicBullet ==
true ) || attacker ==
self ) && isdefined(
self.attackers ) && !
self IsPlayerUnderwater() )
3125 if ( !isdefined(bestPlayer) )
3127 for ( i = 0; i <
self.attackers.size; i++ )
3129 player =
self.attackers[i];
3130 if ( !isdefined( player ) )
3133 if (!isdefined(
self.attackerDamage[ player.clientId ] ) || ! isdefined(
self.attackerDamage[ player.clientId ].damage ) )
3136 if ( player ==
self || (level.teamBased && player.team ==
self.team ) )
3139 if (
self.attackerDamage[ player.clientId ].lasttimedamaged + 2500 < getTime() )
3145 if (
self.attackerDamage[ player.clientId ].damage > 1 && ! isdefined( bestPlayer ) )
3147 bestPlayer = player;
3148 bestPlayerMeansOfDeath =
self.attackerDamage[ player.clientId ].meansOfDeath;
3149 bestPlayerWeapon =
self.attackerDamage[ player.clientId ].weapon;
3151 else if ( isdefined( bestPlayer ) &&
self.attackerDamage[ player.clientId ].damage >
self.attackerDamage[ bestPlayer.clientId ].damage )
3153 bestPlayer = player;
3154 bestPlayerMeansOfDeath =
self.attackerDamage[ player.clientId ].meansOfDeath;
3155 bestPlayerWeapon =
self.attackerDamage[ player.clientId ].weapon;
3159 if ( isdefined ( bestPlayer ) )
3162 self RecordKillModifier(
"assistedsuicide");
3163 assistedSuicide =
true;
3167 if ( isdefined ( bestPlayer ) )
3169 attacker = bestPlayer;
3170 obituaryMeansOfDeath = bestPlayerMeansOfDeath;
3171 obituaryWeapon = bestPlayerWeapon;
3172 if ( isdefined( bestPlayerWeapon ) )
3174 weapon = bestPlayerWeapon;
3178 if ( isplayer( attacker ) )
3179 attacker.damagedPlayers[
self.clientid] = undefined;
3181 if ( enteredResurrect ==
false )
3186 self.deathTime = getTime();
3188 if ( attacker !=
self && (!level.teamBased || attacker.team !=
self.team ))
3190 assert( IsDefined(
self.lastspawntime ) );
3191 self.aliveTimes[
self.aliveTimeCurrentIndex] =
self.deathTime -
self.lastspawntime;
3192 self.aliveTimeCurrentIndex = (
self.aliveTimeCurrentIndex + 1) % level.aliveTimeMaxCount;
3200 if ( !isdefined( obituaryMeansOfDeath ) )
3201 obituaryMeansOfDeath = sMeansOfDeath;
3203 self.hasRiotShield =
false;
3204 self.hasRiotShieldEquipped =
false;
3208 self PlayerKilled_WeaponStats( attacker, weapon, sMeansOfDeath, wasInLastStand, lastWeaponBeforeDroppingIntoLastStand, eInflictor );
3210 if ( bledOut ==
false )
3212 if( GetDvarInt(
"teamOpsEnabled" ) == 1 && ( isdefined( eInflictor ) &&
IS_TRUE( eInflictor.teamops ) ) )
3222 if ( enteredResurrect ==
false )
3226 self.sessionstate =
"dead";
3227 self.statusicon =
"hud_status_dead";
3230 self.pers[
"weapon"] = undefined;
3232 self.killedPlayersCurrent = [];
3237 println(
"players("+
self.clientId+
") death count ++: " +
self.deathCount );
3240 if ( bledout ==
false )
3245 lpselfnum =
self getEntityNumber();
3246 lpselfname =
self.name;
3249 lpselfteam =
self.team;
3250 lpselfguid =
self getGuid();
3252 lpattackorigin = ( 0, 0, 0 );
3257 awardAssists =
false;
3258 wasTeamKill =
false;
3262 self.pers[
"resetMomentumOnSpawn"] = level.scoreResetOnDeath;
3265 if( isPlayer( attacker ) )
3267 lpattackGuid = attacker getGuid();
3268 lpattackname = attacker.name;
3269 lpattackteam = attacker.team;
3270 lpattackorigin = attacker.origin;
3272 if ( attacker ==
self || assistedSuicide ==
true )
3278 if( assistedSuicide ==
true )
3283 lpattacknum = attacker getEntityNumber();
3287 if ( level.teamBased &&
self.team == attacker.team && sMeansOfDeath ==
"MOD_GRENADE" && level.friendlyfire == 0 )
3290 else if ( level.teamBased &&
self.team == attacker.team )
3298 if ( bledOut ==
false )
3302 if ( level.teamBased )
3305 awardAssists =
true;
3311 else if ( isdefined( attacker ) && ( attacker.classname ==
"trigger_hurt" || attacker.classname ==
"worldspawn" ) )
3318 lpattackteam =
"world";
3324 self.suicide =
true;
3330 awardAssists =
true;
3332 if ( level.maxSuicidesBeforeKick > 0 && level.maxSuicidesBeforeKick <=
self.suicides )
3335 self notify(
"teamKillKicked" );
3346 lpattackteam =
"world";
3351 if ( isdefined( eInflictor ) && isdefined( eInflictor.killCamEnt ) )
3354 lpattacknum =
self getEntityNumber();
3359 if ( isdefined( attacker ) && isdefined( attacker.team ) && ( isdefined( level.teams[attacker.team] ) ) )
3361 if ( attacker.team !=
self.team )
3363 if ( level.teamBased )
3374 awardAssists =
true;
3377 if ( !level.inGracePeriod && enteredResurrect ==
false )
3379 if ( sMeansOfDeath !=
"MOD_GRENADE" && sMeansOfDeath !=
"MOD_GRENADE_SPLASH" && sMeansOfDeath !=
"MOD_EXPLOSIVE" && sMeansOfDeath !=
"MOD_EXPLOSIVE_SPLASH" && sMeansOfDeath !=
"MOD_PROJECTILE_SPLASH" && sMeansOfDeath !=
"MOD_FALLING" )
3381 if ( weapon.name !=
"incendiary_fire" )
3399 self.lastAttacker = attacker;
3400 self.lastDeathPos =
self.origin;
3402 if ( isdefined( attacker ) && isPlayer( attacker ) && attacker !=
self && (!level.teambased || attacker.team !=
self.team) )
3404 attacker notify(
"killed_enemy_player",
self, weapon );
3405 if( isDefined( attacker.gadget_thief_kill_callback ) )
3407 attacker [[attacker.gadget_thief_kill_callback]](
self, weapon );
3409 self thread
challenges::playerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, sHitLoc, attackerStance, bledOut );
3414 self notify(
"playerKilledChallengesProcessed");
3417 if ( isdefined (
self.attackers ))
3418 self.attackers = [];
3422 killerHeroPowerActive = 0;
3424 killerLoadoutIndex = -1;
3425 killerWasADS =
false;
3426 killerInVictimFOV =
false;
3427 victimInKillerFOV =
false;
3429 if( isPlayer( attacker ) )
3431 attacker.lastKillTime = gettime();
3434 killerLoadoutIndex = attacker.class_num;
3435 killerWasADS = attacker playerADS() >= 1;
3437 killerInVictimFOV =
util::within_fov(
self.origin,
self.angles, attacker.origin,
self.fovcosine );
3438 victimInKillerFOV =
util::within_fov( attacker.origin, attacker.angles,
self.origin, attacker.fovcosine );
3441 killerHeroPowerActive = 1;
3458 victimWeapon = undefined;
3459 victimWeaponPickedUp =
false;
3460 victimKillstreakWeaponIndex = 0;
3461 if( isdefined( weapon_at_time_of_death ) )
3463 victimWeapon = weapon_at_time_of_death;
3464 if( isdefined(
self.pickedUpWeapons ) && isdefined(
self.pickedUpWeapons[victimWeapon] ) )
3466 victimWeaponPickedUp =
true;
3472 if( isdefined( level.killstreaks[killstreak].menuname ) )
3474 victimKillstreakWeaponIndex = level.killstreakindices[level.killstreaks[killstreak].menuname];
3478 victimWasADS =
self playerADS() >= 1;
3481 killerWeaponPickedUp =
false;
3482 killerKillstreakWeaponIndex = 0;
3483 killerKillstreakEventIndex = 125;
3484 if( isdefined( weapon ) )
3486 if( isdefined( killer ) && isdefined( killer.pickedUpWeapons ) && isdefined( killer.pickedUpWeapons[weapon] ) )
3488 killerWeaponPickedUp =
true;
3494 if( isdefined( level.killstreaks[killstreak].menuname ) )
3496 killerKillstreakWeaponIndex = level.killstreakindices[level.killstreaks[killstreak].menuname];
3498 if( isdefined( killer.killstreakEvents ) && isdefined( killer.killstreakEvents[ killerkillstreakweaponindex ] ) )
3500 killerKillstreakEventIndex = killer.killstreakEvents[killerkillstreakweaponindex];
3504 killerkillstreakeventindex = 126;
3515 matchRecordLogAdditionalDeathInfo(
self, killer, victimWeapon, weapon,
3516 self.class_num, victimWeaponPickedUp, victimWasADS,
3517 killerLoadoutIndex, killerWeaponPickedUp, killerWasADS,
3518 victimHeroPowerActive, killerHeroPowerActive,
3519 victimInKillerFOV, killerInVictimFOV,
3520 killerKillstreakWeaponIndex, victimKillstreakWeaponIndex,
3521 killerkillstreakeventindex);
3526 self.pickedUpWeapons = [];
3529 /#logPrint(
"K;" + lpselfguid +
";" + lpselfnum +
";" + lpselfteam +
";" + lpselfname +
";" + lpattackguid +
";" + lpattacknum +
";" + lpattackteam +
";" + lpattackname +
";" + weapon.name +
";" + iDamage +
";" + sMeansOfDeath +
";" + sHitLoc +
"\n" );#/
3530 attackerString =
"none";
3531 if ( isPlayer( attacker ) )
3532 attackerString = attacker getXuid() +
"(" + lpattackname +
")";
3533 /#print(
"d " + sMeansOfDeath +
"(" + weapon.name +
") a:" + attackerString +
" d:" + iDamage +
" l:" + sHitLoc +
" @ " +
int(
self.origin[0] ) +
" " +
int(
self.origin[1] ) +
" " +
int(
self.origin[2] ) );#/
3536 if ( !level.rankedMatch && !level.teambased )
3544 if ( isdefined(
self.killcam_entity_info_cached ) )
3546 killcam_entity_info =
self.killcam_entity_info_cached;
3547 self.killcam_entity_info_cached = undefined;
3556 if ( isdefined(
self.killstreak_delay_killcam ) )
3561 vAttackerOrigin = undefined;
3562 if ( isdefined( attacker ) )
3564 vAttackerOrigin = attacker.origin;
3567 if ( enteredResurrect ==
false )
3569 clone_weapon = weapon;
3575 clone_weapon = level.weaponNone;
3577 body =
self clonePlayer( deathAnimDuration, clone_weapon, attacker );
3579 if ( isdefined( body ) )
3581 self createDeadBody( attacker, iDamage, sMeansOfDeath, weapon, sHitLoc, vDir, vAttackerOrigin, deathAnimDuration, eInflictor, body );
3589 if ( enteredResurrect )
3594 self.switching_teams = undefined;
3595 self.joining_team = undefined;
3596 self.leaving_team = undefined;
3598 if ( bledOut ==
false )
3600 self thread [[level.onPlayerKilled]](eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration);
3603 if ( isdefined( level.teamopsOnPlayerKilled ) )
3605 self [[level.teamopsOnPlayerKilled]]( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration);
3608 for ( iCB = 0; iCB < level.onPlayerKilledExtraUnthreadedCBs.size; iCB++ )
3610 self [[ level.onPlayerKilledExtraUnthreadedCBs[ iCB ] ]](
3619 deathAnimDuration );
3622 self.wantSafeSpawn =
false;
3625 killstreaks = globallogic::getKillstreaks( attacker );
3627 if( !isdefined(
self.killstreak_delay_killcam ) )
3630 self thread [[level.spawnPlayerPrediction]]();
3633 profilelog_endtiming( 7,
"gs=" + game[
"state"] +
" zom=" + SessionModeIsZombiesGame() );
3636 if ( wasTeamKill ==
false && assistedSuicide ==
false && sMeansOfDeath !=
"MOD_SUICIDE" && !( !isdefined( attacker ) || attacker.classname ==
"trigger_hurt" || attacker.classname ==
"worldspawn" || attacker ==
self || isdefined ( attacker.disableFinalKillcam ) ) )
3638 level thread
killcam::record_settings( lpattacknum,
self getEntityNumber(), weapon, sMeansOfDeath,
self.deathTime, deathTimeOffset, psOffsetTime, killcam_entity_info, perks, killstreaks, attacker );
3640 if ( enteredResurrect )
3650 if( isdefined( weaponClass ) && weaponClass ==
"weapon_sniper" )
3658 self.cancelKillcam =
false;
3666 if ( game[
"state"] !=
"playing" )
3671 self.respawnTimerStartTime = gettime();
3672 keep_deathcam =
false;
3673 if ( isdefined(
self.overridePlayerDeadStatus ) )
3675 keep_deathcam =
self [[
self.overridePlayerDeadStatus ]]();
3678 if ( !
self.cancelKillcam && doKillcam && level.killcam && ( wasTeamKill ==
false ) )
3680 livesLeft = !(level.numLives && !
self.pers[
"lives"]) && !(level.numTeamLives && !game[
self.team+
"_lives"]);
3682 willRespawnImmediately = livesLeft && (timeUntilSpawn <= 0) && !level.playerQueuedRespawn;
3684 self killcam::killcam( lpattacknum,
self getEntityNumber(), killcam_entity_info, weapon, sMeansOfDeath,
self.deathTime, deathTimeOffset, psOffsetTime, willRespawnImmediately,
globallogic_utils::timeUntilRoundEnd(), perks, killstreaks, attacker, keep_deathcam );
3686 else if(
self.cancelKillcam )
3691 if( isdefined(
self.killcamsSkipped) )
3693 self.killcamsSkipped++;
3697 self.killcamsSkipped = 1;
3703 secondary_deathcam = 0.0;
3706 shouldDoSecondDeathCam = timeUntilSpawn > 0;
3708 if ( shouldDoSecondDeathCam && IsDefined(
self.secondaryDeathCamTime) )
3710 secondary_deathcam =
self [[
self.secondaryDeathCamTime]]();
3713 if ( secondary_deathcam > 0.0 && !
self.cancelKillcam )
3715 self.spectatorclient = -1;
3716 self.killcamentity = -1;
3717 self.archivetime = 0;
3718 self.psoffsettime = 0;
3719 self.spectatekillcam =
false;
3721 self notify (
"death_delay_finished" );
3726 if ( !
self.cancelKillcam && doKillcam && level.killcam && keep_deathcam )
3728 self.sessionstate =
"dead";
3729 self.spectatorclient = -1;
3730 self.killcamentity = -1;
3731 self.archivetime = 0;
3732 self.psoffsettime = 0;
3733 self.spectatekillcam =
false;
3736 if ( game[
"state"] !=
"playing" )
3738 self.sessionstate =
"dead";
3739 self.spectatorclient = -1;
3740 self.killcamtargetentity = -1;
3741 self.killcamentity = -1;
3742 self.archivetime = 0;
3743 self.psoffsettime = 0;
3744 self.spectatekillcam =
false;
3749 useRespawnTime =
true;
3750 if( isDefined( level.hostMigrationTimer ) )
3752 useRespawnTime =
false;
3761 timePassed = undefined;
3763 if ( isdefined(
self.respawnTimerStartTime ) && useRespawnTime )
3765 timePassed = (gettime() -
self.respawnTimerStartTime) / 1000;
3768 self thread [[level.spawnClient]]( timePassed );
3769 self.respawnTimerStartTime = undefined;
3777 if ( !level.players.size || level.gameEnded )
3781 foreach ( player
in level.players )
3783 if ( player.team !=
"spectator" )
3784 placement[placement.size] = player;
3787 for ( i = 1; i < placement.size; i++ )
3789 player = placement[i];
3790 playerScore = player.pointstowin;
3791 for ( j = i - 1; j >= 0 && (playerScore > placement[j].pointstowin || (playerScore == placement[j].pointstowin && player.deaths < placement[j].deaths) || (playerScore == placement[j].pointstowin && player.deaths == placement[j].deaths && player.lastKillTime > placement[j].lastKillTime)); j-- )
3792 placement[j + 1] = placement[j];
3793 placement[j + 1] = player;
3797 for ( i = 0; i < placement.size && i < 3; i++ )
3799 SetTopScorer( i, placement[i], 0, 0, 0, 0, level.weaponNone );
3805 defaultPlayerDeathWatchTime = 1.75;
3806 if ( sMeansOfDeath ==
"MOD_MELEE_ASSASSINATE" || 0 > weapon.deathCamTime )
3808 defaultPlayerDeathWatchTime = (deathAnimDuration * 0.001) + 0.5;
3810 else if ( 0 < weapon.deathCamTime )
3812 defaultPlayerDeathWatchTime = weapon.deathCamTime;
3815 if ( isdefined ( level.overridePlayerDeathWatchTimer ) )
3817 defaultPlayerDeathWatchTime = [[level.overridePlayerDeathWatchTimer]]( defaultPlayerDeathWatchTime );
3822 self notify (
"death_delay_finished" );
3835 if ( sMeansOfDeath ==
"MOD_TRIGGER_HURT" && !
self IsOnGround())
3839 if ( IsDefined(current_weapon) && current_weapon.isHeroWeapon )
3847 if ( isdefined(
self.pers[
"isBot"] ) )
3849 level.globalLarrysKilled++;
3856 if( isdefined(
self.killstreak_delay_killcam ) )
3858 while( isdefined(
self.killstreak_delay_killcam ) )
3874 self endon(
"disconnect");
3879 ban(
self getentitynumber() );
3887 self endon(
"disconnect");
3894 if ( playlistbanquantum > 0 && playlistbanpenalty > 0 )
3896 timeplayedtotal =
self GetDStat(
"playerstatslist",
"time_played_total",
"StatValue" );
3897 minutesplayed = timeplayedtotal / 60;
3901 banallowance = int( floor(minutesplayed / playlistbanquantum) ) + freebees;
3903 if (
self.sessionbans > banallowance )
3905 self SetDStat(
"playerstatslist",
"gametypeban",
"StatValue", timeplayedtotal + (playlistbanpenalty * 60) );
3911 ban(
self getentitynumber() );
3917 teamkills =
self.pers[
"teamkills_nostats"];
3918 if ( level.minimumAllowedTeamKills < 0 || teamkills <= level.minimumAllowedTeamKills )
3921 exceeded = (teamkills - level.minimumAllowedTeamKills);
3922 return level.teamKillSpawnDelay * exceeded;
3928 if ( teamKillDelay && ( level.minimumAllowedTeamKills >= 0 ) )
3937 if (
self.pers[
"teamkills_nostats"] > 1 )
3948 timePerOneTeamkillReduction = 20.0;
3949 reductionPerSecond = 1.0 / timePerOneTeamkillReduction;
3953 if ( isAlive(
self ) )
3955 self.pers[
"teamkills_nostats"] -= reductionPerSecond;
3956 if (
self.pers[
"teamkills_nostats"] < level.minimumAllowedTeamKills )
3958 self.pers[
"teamkills_nostats"] = level.minimumAllowedTeamKills;
3972 if ( weapon.ignoreTeamKills )
3975 if ( isdefined( eInflictor ) && eInflictor.ignore_team_kills ===
true )
3978 if( isDefined( eInflictor ) && isDefined( eInflictor.destroyedBy ) && isDefined( eInflictor.owner ) && eInflictor.destroyedBy != eInflictor.owner )
3981 if ( isDefined( eInflictor ) && eInflictor.classname ==
"worldspawn" )
3990 laststand::PlayerLastStand( eInflictor, eAttacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration );
3999 self PlayRumbleOnEntity(
"damage_heavy" );
4004 function createDeadBody( attacker, iDamage, sMeansOfDeath, weapon, sHitLoc, vDir, vAttackerOrigin, deathAnimDuration, eInflictor, body )
4006 if ( sMeansOfDeath ==
"MOD_HIT_BY_OBJECT" &&
self GetStance() ==
"prone" )
4009 if ( !isdefined(
self.switching_teams ) )
4015 ragdoll_now =
false;
4016 if( isdefined(
self.usingvehicle) &&
self.usingvehicle && isdefined(
self.vehicleposition) &&
self.vehicleposition == 1 )
4021 if ( isdefined( level.ragdoll_override ) &&
self [[level.ragdoll_override]]( iDamage, sMeansOfDeath, weapon, sHitLoc, vDir, vAttackerOrigin, deathAnimDuration, eInflictor, ragdoll_now, body ) )
4026 if ( ( ragdoll_now ) ||
self isOnLadder() ||
self isMantling() || sMeansOfDeath ==
"MOD_CRUSH" || sMeansOfDeath ==
"MOD_HIT_BY_OBJECT" )
4027 body startRagDoll();
4029 if ( !
self IsOnGround() && sMeansOfDeath !=
"MOD_FALLING" )
4031 if ( GetDvarint(
"scr_disable_air_death_ragdoll" ) == 0 )
4033 body startRagDoll();
4037 if( sMeansOfDeath ==
"MOD_MELEE_ASSASSINATE" && !attacker isOnGround() )
4049 if ( sMeansOfDeath ==
"MOD_CRUSH" )
4055 if ( !isdefined(
self.switching_teams ) )
4061 if ( !isdefined( weapon ) )
4067 if ( weapon.name ==
"destructible_car" || weapon.name ==
"explodable_barrel" )
4073 if ( weapon.projExplosionType ==
"grenade" )
4075 if ( isdefined( inflictor ) && isdefined( inflictor.stuckToPlayer ) )
4077 if ( inflictor.stuckToPlayer ==
self )
4089 if ( !isdefined(
self ) )
4094 x = RandomIntRange( 50, 100 );
4095 y = RandomIntRange( 50, 100 );
4096 z = RandomIntRange( 10, 20 );
4098 if ( isdefined( weapon ) && (weapon.name ==
"sticky_grenade" || weapon.name ==
"explosive_bolt") )
4100 if ( isdefined( dir ) && LengthSquared( dir ) > 0 )
4118 self StartRagdoll();
4119 self LaunchRagdoll( ( x, y, z ) );
4124 if ( !isdefined(
self ) )
4129 self StartRagdoll();
4130 self LaunchRagdoll( ( 0, 0, -100 ) );
4138 if( isdefined(
self ) )
4140 level notify(
"connecting",
self );
4149 if ( isdefined( ent ) )
4151 deathAnim = ent getcorpseanim();
4152 if ( animhasnotetrack( deathAnim,
"ignore_ragdoll" ) )
4158 if ( !isdefined( ent ) )
4161 if ( ent isRagDoll() )
4164 deathAnim = ent getcorpseanim();
4168 if ( animhasnotetrack( deathAnim,
"start_ragdoll" ) )
4170 times = getnotetracktimes( deathAnim,
"start_ragdoll" );
4171 if ( isdefined( times ) )
4172 startFrac = times[0];
4175 waitTime = startFrac * getanimlength( deathAnim );
4181 if ( isdefined( ent ) )
4189 if( !IsDefined( eAttacker ) )
4192 if ( !IsPlayer( eAttacker ) )
4195 if (
self.attackerData.size == 0 )
4197 self.firstTimeDamaged = getTime();
4199 if ( !isdefined(
self.attackerData[eAttacker.clientid] ) )
4201 self.attackerDamage[eAttacker.clientid] = spawnstruct();
4202 self.attackerDamage[eAttacker.clientid].damage = iDamage;
4203 self.attackerDamage[eAttacker.clientid].meansOfDeath = sMeansOfDeath;
4204 self.attackerDamage[eAttacker.clientid].weapon = weapon;
4205 self.attackerDamage[eAttacker.clientid].time = getTime();
4207 self.attackers[
self.attackers.size ] = eAttacker;
4212 self.attackerData[eAttacker.clientid] =
false;
4216 self.attackerDamage[eAttacker.clientid].damage += iDamage;
4217 self.attackerDamage[eAttacker.clientid].meansOfDeath = sMeansOfDeath;
4218 self.attackerDamage[eAttacker.clientid].weapon = weapon;
4219 if ( !isdefined(
self.attackerDamage[eAttacker.clientid].time ) )
4220 self.attackerDamage[eAttacker.clientid].time = getTime();
4223 if ( IsArray(
self.attackersThisSpawn ) )
4225 self.attackersThisSpawn[ eAttacker.clientid ] = eAttacker;
4228 self.attackerDamage[eAttacker.clientid].lasttimedamaged = getTime();
4230 self.attackerData[eAttacker.clientid] =
true;
4240 if ( !isdefined( eInflictor ) )
4243 if ( !isdefined( eInflictor.owner ) )
4246 if ( !isdefined( eInflictor.ownerGetsAssist ) )
4249 if ( !eInflictor.ownerGetsAssist )
4254 if ( isdefined( eAttacker ) && eAttacker == eInflictor.owner )
4262 if(
globallogic_utils::isHeadShot( weapon, sHitLoc, sMeansOfDeath, eInflictor ) && isPlayer( attacker ) && !weapon_utils::ismeleemod( sMeansOfDeath ) )
4264 return "MOD_HEAD_SHOT";
4268 switch( weapon.name )
4271 sMeansOfDeath =
"MOD_PISTOL_BULLET";
4273 case "destructible_car":
4274 sMeansOfDeath =
"MOD_EXPLOSIVE";
4276 case "explodable_barrel":
4277 sMeansOfDeath =
"MOD_EXPLOSIVE";
4281 return sMeansOfDeath;
4286 if( isai(attacker) && isdefined( attacker.script_owner ) )
4290 if ( !level.teambased || attacker.script_owner.team !=
self.team )
4291 attacker = attacker.script_owner;
4294 if( attacker.classname ==
"script_vehicle" && isdefined( attacker.owner ) )
4296 attacker notify(
"killed",
self);
4298 attacker = attacker.owner;
4301 if( isai(attacker) )
4302 attacker notify(
"killed",
self);
4304 if ( ( isdefined (
self.capturingLastFlag ) ) && (
self.capturingLastFlag ==
true ) )
4306 attacker.lastCapKiller =
true;
4309 if( isdefined( attacker ) && attacker !=
self && isdefined( weapon ) )
4311 if ( weapon.name ==
"planemortar" )
4313 DEFAULT( attacker.planeMortarBda, 0 );
4314 attacker.planeMortarBda++;
4316 else if( weapon.name ==
"dart" ||
4317 weapon.name ==
"dart_turret" )
4322 else if( weapon.name ==
"straferun_rockets" || weapon.name ==
"straferun_gun")
4324 if( isdefined( attacker.strafeRunbda ) )
4326 attacker.strafeRunbda++;
4329 else if ( weapon.name ==
"remote_missile_missile" || weapon.name ==
"remote_missile_bomblet" )
4331 DEFAULT( attacker.remotemissileBda, 0 );
4332 attacker.remotemissileBda++;
4341 if( isdefined( eInflictor ) && eInflictor.classname ==
"script_vehicle" )
4343 eInflictor notify(
"killed",
self);
4345 if ( isdefined( eInflictor.bda ) )
4357 if ( weapon == level.weaponNone && isdefined( eInflictor ) )
4359 if ( isdefined( eInflictor.targetname ) && eInflictor.targetname ==
"explodable_barrel" )
4360 weapon = GetWeapon(
"explodable_barrel" );
4361 else if ( isdefined( eInflictor.destructible_type ) && isSubStr( eInflictor.destructible_type,
"vehicle_" ) )
4362 weapon = GetWeapon(
"destructible_car" );
4370 if( IsPlayer( attacker ) )
4378 if( isdefined( eInflictor ) )
4380 eInflictor notify(
"bhtn_action_notify",
"attack_kill" );