1 #using scripts\codescripts\struct;
3 #using scripts\shared\callbacks_shared;
4 #using scripts\shared\challenges_shared;
5 #using scripts\shared\demo_shared;
6 #using scripts\shared\gameobjects_shared;
7 #using scripts\shared\hud_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\medals_shared;
12 #using scripts\shared\music_shared;
13 #using scripts\shared\persistence_shared;
14 #using scripts\shared\popups_shared;
15 #using scripts\shared\rank_shared;
16 #using scripts\shared\tweakables_shared;
17 #using scripts\shared\util_shared;
18 #using scripts\shared\simple_hostmigration;
19 #using scripts\shared\bb_shared;
21 #insert scripts\shared\shared.gsh;
23 #using scripts\zm\gametypes\_dev;
24 #using scripts\zm\gametypes\_globallogic_audio;
25 #using scripts\zm\gametypes\_globallogic_defaults;
26 #using scripts\zm\gametypes\_globallogic_player;
27 #using scripts\zm\gametypes\_globallogic_score;
28 #using scripts\zm\gametypes\_globallogic_spawn;
29 #using scripts\zm\gametypes\_globallogic_ui;
30 #using scripts\zm\gametypes\_globallogic_utils;
31 #using scripts\zm\gametypes\_hostmigration;
32 #using scripts\zm\gametypes\_hud_message;
33 #using scripts\zm\gametypes\_spawnlogic;
34 #using scripts\zm\gametypes\_weaponobjects;
35 #using scripts\zm\gametypes\_weapon_utils;
36 #using scripts\zm\gametypes\_weapons;
38 #using scripts\zm\_rat;
39 #using scripts\zm\_challenges;
40 #using scripts\zm\_util;
43 #define MATCH_KICKED 2
45 #define MATCH_FINISHED 4
47 #namespace globallogic;
49 #precache( "model", "tag_origin" );
51 #precache( "statusicon", "hud_status_dead" );
52 #precache( "statusicon", "hud_status_connecting" );
54 #precache( "material", "white" );
55 #precache( "material", "black" );
56 #precache( "string", "PLATFORM_PRESS_TO_SPAWN" );
57 #precache( "string", "MP_WAITING_FOR_TEAMS" );
58 #precache( "string", "MP_OPPONENT_FORFEITING_IN" );
59 #precache( "string", "MP_WAITING_FOR_PLAYERS" );
60 #precache( "string", "MP_OPPONENT_FORFEITING_IN" );
61 #precache( "string", "MP_MATCH_STARTING_IN" );
62 #precache( "string", "MP_SPAWN_NEXT_ROUND" );
63 #precache( "string", "MP_WAITING_TO_SPAWN" );
64 #precache( "string", "MP_WAITING_TO_SPAWN_SS" );
65 #precache( "string", "MP_YOU_WILL_RESPAWN" );
66 #precache( "string", "MP_MATCH_STARTING" );
67 #precache( "string", "MP_CHANGE_CLASS_NEXT_SPAWN" );
68 #precache( "string", "MPUI_LAST_STAND" );
69 #precache( "string", "PLATFORM_COWARDS_WAY_OUT" );
70 #precache( "string", "MP_MATCH_TIE" );
71 #precache( "string", "MP_ROUND_DRAW" );
72 #precache( "string", "MP_ENEMIES_ELIMINATED" );
73 #precache( "string", "MP_SCORE_LIMIT_REACHED" );
74 #precache( "string", "MP_ROUND_LIMIT_REACHED" );
75 #precache( "string", "MP_TIME_LIMIT_REACHED" );
76 #precache( "string", "MP_PLAYERS_FORFEITED" );
80 level.language = GetDvarString(
"language" );
81 level.splitscreen = isSplitScreen();
82 level.xenon = (GetDvarString(
"xenonGame") ==
"true");
83 level.ps3 = (GetDvarString(
"ps3Game") ==
"true");
84 level.wiiu = (GetDvarString(
"wiiuGame") ==
"true");
85 level.orbis = (GetDvarString(
"orbisGame") ==
"true");
86 level.durango = (GetDvarString(
"durangoGame") ==
"true");
88 level.createFX_disable_fx = (GetDvarInt(
"disable_fx") == 1);
90 level.onlineGame = SessionModeIsOnlineGame(); level.systemLink = SessionModeIsSystemlink();
91 level.console = ( level.xenon || level.ps3 || level.wiiu || level.orbis || level.durango );
93 level.rankedMatch = ( GameModeIsUsingXP() );
94 level.leagueMatch =
false;
95 level.arenaMatch =
false;
97 level.wagerMatch =
false;
99 level.contractsEnabled = !GetGametypeSetting(
"disableContracts" );
101 level.contractsEnabled =
false;
103 level.script = toLower( GetDvarString(
"mapname" ) );
104 level.gametype = toLower( GetDvarString(
"g_gametype" ) );
106 level.teamBased =
false;
107 level.teamCount = GetGametypeSetting(
"teamCount" );
108 level.multiTeam = ( level.teamCount > 2 );
110 if ( SessionModeIsZombiesGame() )
112 level.zombie_team_index = level.teamCount + 1;
113 if ( 2 == level.zombie_team_index )
115 level.zombie_team =
"axis";
119 level.zombie_team =
"team" + level.zombie_team_index;
127 level.teamIndex = [];
129 teamCount = level.teamCount;
131 level.teams[
"allies" ] =
"allies";
132 level.teams[
"axis" ] =
"axis";
134 level.teamIndex[
"neutral" ] = 0;
135 level.teamIndex[
"allies" ] = 1;
136 level.teamIndex[
"axis" ] = 2;
138 for( teamIndex = 3; teamIndex <= teamCount; teamIndex++ )
140 level.teams[
"team" + teamIndex ] =
"team" + teamIndex;
141 level.teamIndex[
"team" + teamIndex ] = teamIndex;
144 level.overrideTeamScore =
false;
145 level.overridePlayerScore =
false;
146 level.displayHalftimeText =
false;
147 level.displayRoundEndText =
true;
149 level.endGameOnScoreLimit =
true;
150 level.endGameOnTimeLimit =
true;
151 level.scoreRoundWinBased =
false;
152 level.resetPlayerScoreEveryRound =
false;
154 level.gameForfeited=
false;
155 level.forceAutoAssign =
false;
157 level.halftimeType =
"halftime";
158 level.halftimeSubCaption = &
"MP_SWITCHING_SIDES_CAPS";
160 level.lastStatusTime = 0;
161 level.wasWinning = [];
163 level.lastSlowProcessFrame = 0;
165 level.placement = [];
166 foreach( team
in level.teams )
168 level.placement[team] = [];
170 level.placement[
"all"] = [];
172 level.postRoundTime = 7.0;
174 level.inOvertime =
false;
176 level.defaultOffenseRadius = 560;
178 level.dropTeam = GetDvarint(
"sv_maxclients" );
180 level.inFinalKillcam =
false;
185 level.oldschool = ( GetDvarint(
"scr_oldschool" ) == 1 );
186 if ( level.oldschool )
190 SetDvar(
"jump_height", 64 );
191 SetDvar(
"jump_slowdownEnable", 0 );
192 SetDvar(
"bg_fallDamageMinHeight", 256 );
193 SetDvar(
"bg_fallDamageMaxHeight", 512 );
194 SetDvar(
"player_clipSizeMultiplier", 2.0 );
202 if ( !isdefined( game[
"tiebreaker"] ) )
203 game[
"tiebreaker"] =
false;
212 level.playersDrivingVehiclesBecomeInvulnerable =
true;
222 if ( GetDvarString(
"scr_oldschool" ) ==
"" )
223 SetDvar(
"scr_oldschool",
"0" );
227 if ( GetDvarString(
"ui_guncycle" ) ==
"" )
228 SetDvar(
"ui_guncycle", 0 );
232 if ( GetDvarString(
"ui_weapon_tiers" ) ==
"" )
233 SetDvar(
"ui_weapon_tiers", 0 );
236 SetDvar(
"ui_text_endreason",
"");
239 setMatchFlag(
"bomb_timer", 0 );
243 if ( GetDvarString(
"scr_vehicle_damage_scalar" ) ==
"" )
244 SetDvar(
"scr_vehicle_damage_scalar",
"1" );
246 level.vehicleDamageScalar = GetDvarfloat(
"scr_vehicle_damage_scalar");
248 level.fire_audio_repeat_duration = GetDvarint(
"fire_audio_repeat_duration" );
249 level.fire_audio_random_max_duration = GetDvarint(
"fire_audio_random_max_duration" );
252 function blank( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 )
270 level.onSpawnPlayer =&
blank;
271 level.onSpawnPlayerUnified =&
blank;
274 level.onRespawnDelay =&
blank;
283 level.onLastTeamAliveEvent = undefined;
287 level.getTeamKillPenalty =&
blank;
288 level.getTeamKillScore =&
blank;
298 level.onPrecacheGametype =&
blank;
299 level.onStartGameType =&
blank;
300 level.onPlayerConnect =&
blank;
301 level.onPlayerDisconnect =&
blank;
302 level.onPlayerDamage =&
blank;
303 level.onPlayerKilled =&
blank;
304 level.onPlayerKilledExtraUnthreadedCBs = [];
313 level.onMedalAwarded = &
blank;
314 level.dogManagerOnGetDogs = &
blank;
321 if( SessionModeIsZombiesGame() )
324 if( !level.rankedMatch )
327 mapname = GetDvarString(
"mapname" );
329 globalLeaderboards =
"LB_MP_GB_XPPRESTIGE LB_MP_GB_TOTALXP_AT LB_MP_GB_TOTALXP_LT LB_MP_GB_WINS_AT LB_MP_GB_WINS_LT LB_MP_GB_KILLS_AT LB_MP_GB_KILLS_LT LB_MP_GB_ACCURACY_AT LB_MP_GB_ACCURACY_LT";
331 gamemodeLeaderboard =
" LB_MP_GM_" + level.gametype;
333 if( getDvarInt(
"g_hardcore" ) )
334 gamemodeLeaderboard +=
"_HC";
336 mapLeaderboard =
" LB_MP_MAP_" + getsubstr( mapname, 3, mapname.size );
338 precacheLeaderboards( globalLeaderboards + gamemodeLeaderboard + mapLeaderboard );
345 if ( teamA ==
"tie" )
349 if ( previous_winner_score < game[gameStat][teamB] )
352 else if ( game[gameStat][teamA] == game[gameStat][teamB] )
354 else if ( game[gameStat][teamB] > game[gameStat][teamA] )
364 teamKeys = GetArrayKeys(level.teams);
365 winner = teamKeys[0];
366 previous_winner_score = game[gameStat][winner];
368 for ( teamIndex = 1; teamIndex < teamKeys.size; teamIndex++ )
372 if ( winner !=
"tie" )
374 previous_winner_score = game[gameStat][winner];
384 teamBScore = [[level._getTeamScore]]( teamB );
386 if ( teamA ==
"tie" )
390 if ( previous_winner_score < teamBScore )
396 teamAScore = [[level._getTeamScore]]( teamA );
398 if ( teamBScore == teamAScore )
400 else if ( teamBScore > teamAScore )
410 teamKeys = GetArrayKeys(level.teams);
411 winner = teamKeys[0];
412 previous_winner_score = [[level._getTeamScore]]( winner );
414 for ( teamIndex = 1; teamIndex < teamKeys.size; teamIndex++ )
418 if ( winner !=
"tie" )
420 previous_winner_score = [[level._getTeamScore]]( winner );
429 if (!isdefined(hostsucks))
432 if ( level.hostForcedEnd || level.forcedEnd )
437 if ( level.teamBased )
447 level.forcedEnd =
true;
448 level.hostForcedEnd =
true;
452 endString = &
"MP_HOST_SUCKS";
456 if ( level.splitscreen )
457 endString = &
"MP_ENDED_GAME";
459 endString = &
"MP_HOST_ENDED_GAME";
462 setMatchFlag(
"disableIngameMenu", 1 );
464 SetDvar(
"ui_text_endreason", endString );
465 thread
endGame( winner, endString );
470 if ( level.hostForcedEnd || level.forcedEnd )
475 if ( level.teamBased )
485 level.forcedEnd =
true;
486 level.hostForcedEnd =
true;
488 level.killserver =
true;
490 endString = &
"MP_HOST_ENDED_GAME";
492 thread
endGame( winner, endString );
497 foreach ( team
in level.teams )
499 if ( level.playerCount[team] == 0 )
508 if ( !level.everExisted[team] )
521 foreach( team
in level.teams )
526 thread [[level.onForfeit]]( team );
536 foreach( team
in level.teams )
538 if ( level.spawnQueueModified[team] )
540 [[level.onAliveCountChange]]( team );
547 return (level.everExisted[team] && !level.aliveCount[team] && !level.playerLives[team] );
552 foreach( team
in level.teams )
567 foreach( team
in level.teams )
581 if ( level.teamBased )
586 [[level.onDeadEvent]](
"all" );
591 if ( isdefined( level.onLastTeamAliveEvent ) )
595 foreach( team
in level.teams )
600 [[level.onLastTeamAliveEvent]]( team );
608 foreach( team
in level.teams )
613 [[level.onDeadEvent]]( team );
624 [[level.onDeadEvent]](
"all" );
634 return (level.lastAliveCount[team] > 1 && level.aliveCount[team] == 1 && level.playerLives[team] == 1 );
640 if ( level.teamBased )
642 foreach( team
in level.teams )
647 [[level.onOneLeftEvent]]( team );
657 [[level.onOneLeftEvent]](
"all" );
667 if ( ( level.rankedMatch || level.wagerMatch || level.leagueMatch ) && !level.inGracePeriod )
669 if ( level.teamBased )
671 if (!level.gameForfeited )
682 level.gameForfeited =
false;
683 level notify(
"abort forfeit" );
689 if (!level.gameForfeited)
693 thread [[level.onForfeit]]();
701 level.gameForfeited =
false;
702 level notify(
"abort forfeit" );
708 if ( !level.playerQueuedRespawn && !level.numLives && !level.inOverTime )
711 if ( level.inGracePeriod )
714 if ( level.playerQueuedRespawn )
731 matchStartText.sort = 1001;
732 matchStartText setText( game[
"strings"][
"waiting_for_teams"] );
733 matchStartText.foreground =
false;
734 matchStartText.hidewheninmenu =
true;
737 matchStartText setText( game[
"strings"][
"match_starting_in"] );
752 countTime = int( level.prematchPeriod );
754 if ( countTime >= 2 )
756 while ( countTime > 0 && !level.gameEnded )
760 if ( countTime == 2 )
761 visionSetNaked( GetDvarString(
"mapname" ), 3.0 );
768 visionSetNaked( GetDvarString(
"mapname" ), 1.0 );
777 visionSetNaked( GetDvarString(
"mapname" ), 0 );
782 if ( time - level.lastWave[team] > (level.waveDelay[team] * 1000) )
784 level notify (
"wave_respawn_" + team );
785 level.lastWave[team] = time;
786 level.wavePlayerSpawnIndex[team] = 0;
792 level endon(
"game_ended" );
794 while ( game[
"state"] ==
"playing" )
798 foreach( team
in level.teams )
812 if ( isdefined( hostPlayer ) && !hostPlayer.hasSpawned && !isdefined( hostPlayer.selectedClass ) )
820 self AddDStat(
"gameHistory", gameMode,
"modeHistory", playedOrHosted, stat, 1 );
825 self SetDStat(
"gameHistory", gameMode,
"modeHistory", playedOrHosted, stat, 1 );
830 if ( level.displayRoundEndText )
832 if ( winner ==
"tie" )
841 setmatchflag(
"cg_drawSpectatorMessages", 0 );
842 players = level.players;
843 for ( index = 0; index < players.size; index++ )
845 player = players[index];
847 if ( !isdefined( player.pers[
"team"] ) )
849 player [[level.spawnIntermission]]( true );
850 player closeInGameMenu();
854 if ( level.wagerMatch )
856 if ( level.teamBased )
857 player thread [[level.onTeamWagerOutcomeNotify]]( winner,
true, endReasonText );
859 player thread [[level.onWagerOutcomeNotify]]( winner, endReasonText );
863 if ( level.teamBased )
865 player thread [[level.onTeamOutcomeNotify]]( winner,
true, endReasonText );
870 player thread [[level.onOutcomeNotify]]( winner,
true, endReasonText );
875 player setClientUIVisibilityFlag(
"hud_visible", 0 );
876 player setClientUIVisibilityFlag(
"g_compassShowEnemies", 0 );
893 switchType = level.halftimeType;
894 if ( switchType ==
"halftime" )
896 if ( isdefined( level.nextRoundIsOvertime ) && level.nextRoundIsOvertime )
898 switchType =
"overtime";
902 if ( level.roundLimit )
904 if ( (game[
"roundsplayed"] * 2) == level.roundLimit )
905 switchType =
"halftime";
907 switchType =
"intermission";
909 else if ( level.scoreLimit )
911 if ( game[
"roundsplayed"] == (level.scoreLimit - 1) )
912 switchType =
"halftime";
914 switchType =
"intermission";
918 switchType =
"intermission";
925 SetMatchTalkFlag(
"EveryoneHearsEveryone", 1 );
927 players = level.players;
928 for ( index = 0; index < players.size; index++ )
930 player = players[index];
932 if ( !isdefined( player.pers[
"team"] ) )
934 player [[level.spawnIntermission]]( true );
935 player closeInGameMenu();
942 if ( level.wagerMatch )
943 player thread [[level.onTeamWagerOutcomeNotify]]( switchType,
true, level.halftimeSubCaption );
945 player thread [[level.onTeamOutcomeNotify]]( switchType,
false, level.halftimeSubCaption );
946 player setClientUIVisibilityFlag(
"hud_visible", 0 );
954 SetMatchTalkFlag(
"EveryoneHearsEveryone", 1 );
955 setmatchflag(
"cg_drawSpectatorMessages", 0 );
957 if ( winner ==
"tie" )
967 players = level.players;
968 for ( index = 0; index < players.size; index++ )
970 player = players[index];
972 if ( !isdefined( player.pers[
"team"] ) )
974 player [[level.spawnIntermission]]( true );
975 player closeInGameMenu();
979 if ( level.wagerMatch )
981 if ( level.teamBased )
982 player thread [[level.onTeamWagerOutcomeNotify]]( winner,
false, endReasonText );
984 player thread [[level.onWagerOutcomeNotify]]( winner, endReasonText );
988 if ( level.teamBased )
990 player thread [[level.onTeamOutcomeNotify]]( winner,
false, endReasonText );
994 player thread [[level.onOutcomeNotify]]( winner,
false, endReasonText );
996 if ( isdefined( winner ) && player == winner )
998 else if ( !level.splitScreen )
1003 player setClientUIVisibilityFlag(
"hud_visible", 0 );
1004 player setClientUIVisibilityFlag(
"g_compassShowEnemies", 0 );
1007 if ( level.teamBased )
1011 players = level.players;
1012 for ( index = 0; index < players.size; index++ )
1014 player = players[index];
1015 team = player.pers[
"team"];
1017 if ( level.splitscreen )
1019 if ( winner ==
"tie" )
1023 else if ( winner == team )
1034 if ( winner ==
"tie" )
1038 else if ( winner == team )
1050 bbPrint(
"global_session_epilogs",
"reason %s", endReasonText );
1061 return game[
"strings"][
"round_limit_reached"];
1063 return game[
"strings"][
"score_limit_reached"];
1065 if ( level.forcedEnd )
1067 if ( level.hostForcedEnd )
1068 return &
"MP_HOST_ENDED_GAME";
1070 return &
"MP_ENDED_GAME";
1072 return game[
"strings"][
"time_limit_reached"];
1077 players = level.players;
1078 for ( index = 0; index < players.size; index++ )
1080 player = players[index];
1081 player notify (
"reset_outcome" );
1100 if ( isdefined( level.nextRoundIsOvertime ) && level.nextRoundIsOvertime )
1102 if ( !isdefined( game[
"overtime_round"] ) )
1104 game[
"overtime_round"] = 1;
1108 game[
"overtime_round"]++;
1112 SetMatchTalkFlag(
"DeadChatWithDead", level.voip.deadChatWithDead );
1113 SetMatchTalkFlag(
"DeadChatWithTeam", level.voip.deadChatWithTeam );
1114 SetMatchTalkFlag(
"DeadHearTeamLiving", level.voip.deadHearTeamLiving );
1115 SetMatchTalkFlag(
"DeadHearAllLiving", level.voip.deadHearAllLiving );
1116 SetMatchTalkFlag(
"EveryoneHearsEveryone", level.voip.everyoneHearsEveryone );
1117 SetMatchTalkFlag(
"DeadHearKiller", level.voip.deadHearKiller );
1118 SetMatchTalkFlag(
"KillersHearVictim", level.voip.killersHearVictim );
1120 game[
"state"] =
"playing";
1121 level.allowbattlechatter[
"bc"] = GetGametypeSetting(
"allowBattleChatter" );
1122 map_restart(
true );
1131 if ( !level.timeLimit || level.forcedEnd )
1135 gameLength = min( gameLength, 1200 );
1139 gameLength = level.timeLimit * 60;
1151 self GameHistoryFinishMatch(
MATCH_QUIT, 0, 0, 0, 0, teamScoreRatio );
1153 if ( isdefined(
self.pers[
"matchesPlayedStatsTracked"] ) )
1158 if ( isdefined(
self.pers[
"matchesHostedStatsTracked"] ) )
1161 self.pers[
"matchesHostedStatsTracked"] = undefined;
1164 self.pers[
"matchesPlayedStatsTracked"] = undefined;
1167 UploadStats(
self );
1175 players = level.players;
1176 for ( index = 0; index < players.size; index++ )
1185 if ( game[
"state"] ==
"postgame" || level.gameEnded )
1188 if ( isdefined( level.onEndGame ) )
1189 [[level.onEndGame]]( winner );
1202 if ( !isdefined( level.disableOutroVisionSet ) || level.disableOutroVisionSet == false )
1204 if ( SessionModeIsZombiesGame() && level.forcedEnd )
1206 visionSetNaked(
"zombie_last_stand", 2.0 );
1210 visionSetNaked(
"mpOutro", 2.0 );
1214 setmatchflag(
"cg_drawSpectatorMessages", 0 );
1215 setmatchflag(
"game_ended", 1 );
1217 game[
"state"] =
"postgame";
1218 level.gameEndTime = getTime();
1219 level.gameEnded =
true;
1220 SetDvar(
"g_gameEnded", 1 );
1221 level.inGracePeriod =
false;
1222 level notify (
"game_ended" );
1223 level.allowbattlechatter[
"bc"] =
false;
1228 game[
"roundsplayed"]++;
1229 game[
"roundwinner"][game[
"roundsplayed"]] = winner;
1232 if( level.teambased )
1234 game[
"roundswon"][winner]++;
1238 if ( isdefined( winner ) && isdefined( level.teams[winner] ) )
1240 level.finalKillCam_winner = winner;
1244 level.finalKillCam_winner =
"none";
1247 setGameEndTime( 0 );
1254 players = level.players;
1256 newTime = getTime();
1259 SetMatchTalkFlag(
"EveryoneHearsEveryone", 1 );
1266 if ( level.teambased )
1268 if ( winner ==
"tie" )
1270 recordGameResult(
"draw" );
1274 recordGameResult( winner );
1279 if ( !isdefined( winner ) )
1281 recordGameResult(
"draw" );
1285 recordGameResult( winner.team );
1290 for ( index = 0; index < players.size; index++ )
1292 player = players[index];
1294 player thread roundEndDoF( 4.0 );
1303 if( ( level.rankedMatch || level.wagerMatch || level.leagueMatch ) && !player IsSplitscreen() )
1305 if ( isdefined( player.setPromotion ) )
1306 player setDStat(
"AfterActionReportStats",
"lobbyPopup",
"promotion" );
1308 player setDStat(
"AfterActionReportStats",
"lobbyPopup",
"summary" );
1312 music::setmusicstate(
"SILENT" );
1327 if ( isdefined( level.onRoundEndGame ) )
1328 winner = [[level.onRoundEndGame]]( winner );
1333 skillUpdate( winner, level.teamBased );
1334 recordLeagueWinner( winner );
1336 if ( isdefined( winner ) && ( !isdefined( level.skipGameEnd ) || !level.skipGameEnd ) )
1344 level.intermission =
true;
1350 SetMatchTalkFlag(
"EveryoneHearsEveryone", 1 );
1352 stopdemorecording();
1355 players = level.players;
1356 for ( index = 0; index < players.size; index++ )
1358 player = players[index];
1360 recordPlayerStats( player,
"presentAtEnd", 1 );
1362 player closeInGameMenu();
1363 player notify (
"reset_outcome" );
1364 player thread [[level.spawnIntermission]]();
1365 player setClientUIVisibilityFlag(
"hud_visible", 1 );
1366 player setClientUIVisibilityFlag(
"weapon_hud_visible", 1 );
1369 level notify (
"sfade");
1372 if ( !isdefined( level.skipGameEnd ) || !level.skipGameEnd )
1383 totalTimePlayed = 0;
1384 if ( isdefined(
self.timePlayed ) && isdefined(
self.timePlayed[
"total"] ) )
1386 totalTimePlayed =
self.timePlayed[
"total"];
1387 if ( totalTimePlayed > gameLength )
1389 totalTimePlayed = gameLength;
1393 xuid =
self GetXUID();
1400 notifiesDone =
false;
1401 while ( !notifiesDone )
1403 players = level.players;
1404 notifiesDone =
true;
1405 for ( index = 0; index < players.size; index++ )
1407 if ( !isdefined( players[index].doingNotify ) || !players[index].doingNotify )
1410 notifiesDone =
false;
1417 wait ( defaultDelay );
1418 level notify (
"round_end_done" );
1422 wait ( defaultDelay / 2 );
1423 level notify (
"give_match_bonus" );
1424 wait ( defaultDelay / 2 );
1426 notifiesDone =
false;
1427 while ( !notifiesDone )
1429 players = level.players;
1430 notifiesDone =
true;
1431 for ( index = 0; index < players.size; index++ )
1433 if ( !isdefined( players[index].doingNotify ) || !players[index].doingNotify )
1436 notifiesDone =
false;
1441 level notify (
"round_end_done" );
1447 self setDepthOfField( 0, 128, 512, 4000, 6, 1.8 );
1453 if ( isdefined( level.timeLimitOverride ) && level.timeLimitOverride )
1456 if ( game[
"state"] !=
"playing" )
1458 setGameEndTime( 0 );
1462 if ( level.timeLimit <= 0 )
1464 setGameEndTime( 0 );
1468 if ( level.inPrematchPeriod )
1470 setGameEndTime( 0 );
1474 if ( level.timerStopped )
1476 setGameEndTime( 0 );
1480 if ( !isdefined( level.startTime ) )
1486 setGameEndTime( getTime() +
int(timeLeft) );
1491 [[level.onTimeLimit]]();
1496 foreach ( team
in level.teams )
1498 if ( game[
"teamScores"][team] >= level.scoreLimit )
1507 if ( game[
"state"] !=
"playing" )
1510 if ( level.scoreLimit <= 0 )
1513 if ( level.teamBased )
1520 if ( !isPlayer(
self ) )
1523 if (
self.score < level.scoreLimit )
1527 [[level.onScoreLimit]]();
1533 level endon (
"game_ended" );
1535 while ( game[
"state"] ==
"playing" )
1537 roundlimit =
math::clamp( GetGametypeSetting(
"roundLimit" ), level.roundLimitMin, level.roundLimitMax );
1538 if ( roundlimit != level.roundlimit )
1540 level.roundlimit = roundlimit;
1541 level notify (
"update_roundlimit" );
1544 timeLimit = [[level.getTimeLimit]]();
1545 if ( timeLimit != level.timeLimit )
1547 level.timeLimit = timeLimit;
1548 SetDvar(
"ui_timelimit", level.timeLimit );
1549 level notify (
"update_timelimit" );
1553 scoreLimit =
math::clamp( GetGametypeSetting(
"scoreLimit" ), level.scoreLimitMin, level.scoreLimitMax );
1554 if ( scoreLimit != level.scoreLimit )
1556 level.scoreLimit = scoreLimit;
1557 SetDvar(
"ui_scorelimit", level.scoreLimit );
1558 level notify (
"update_scorelimit" );
1563 if ( isdefined( level.startTime ) )
1579 numPlayers = level.placement[
"all"].size;
1581 for ( i = 0; i < numPlayers; i++ )
1583 if ( level.placement[
"all"][i] ==
self )
1587 level.placement[
"all"][i] = level.placement[
"all"][ i + 1 ];
1592 level.placement[
"all"][ numPlayers - 1 ] = undefined;
1593 assert( level.placement[
"all"].size == numPlayers - 1 );
1597 if ( level.teamBased )
1600 numPlayers = level.placement[
"all"].size;
1601 for ( i = 0; i < numPlayers; i++ )
1603 player = level.placement[
"all"][i];
1604 player notify(
"update_outcome" );
1612 if ( !level.players.size )
1615 level.placement[
"all"] = [];
1616 foreach ( player
in level.players )
1618 if ( !level.teambased || isdefined( level.teams[ player.team ] ) )
1619 level.placement[
"all"][level.placement[
"all"].size] = player;
1622 placementAll = level.placement[
"all"];
1624 for ( i = 1; i < placementAll.size; i++ )
1626 player = placementAll[i];
1627 playerScore = player.score;
1628 for ( j = i - 1; j >= 0 && (playerScore > placementAll[j].score || (playerScore == placementAll[j].score && player.deaths < placementAll[j].deaths)); j-- )
1629 placementAll[j + 1] = placementAll[j];
1630 placementAll[j + 1] = player;
1633 level.placement[
"all"] = placementAll;
1642 foreach( team
in level.teams )
1644 placement[team] = [];
1646 placement[
"spectator"] = [];
1648 if ( !level.teamBased )
1651 placementAll = level.placement[
"all"];
1652 placementAllSize = placementAll.size;
1654 for ( i = 0; i < placementAllSize; i++ )
1656 player = placementAll[i];
1657 if (isdefined(player))
1659 team = player.pers[
"team"];
1661 placement[team][ placement[team].size ] = player;
1665 foreach( team
in level.teams )
1667 level.placement[team] = placement[team];
1676 placement = level.placement[
"all"];
1677 for ( placementIndex = 0; placementIndex < placement.size; placementIndex++ )
1679 if ( level.placement[
"all"][placementIndex] == player )
1681 playerRank = (placementIndex + 1);
1692 if ( !level.playerQueuedRespawn )
1696 for ( i = 1; i < level.deadPlayers[team].size; i++ )
1698 player = level.deadPlayers[team][i];
1699 for ( j = i - 1; j >= 0 && player.deathTime < level.deadPlayers[team][j].deathTime; j-- )
1700 level.deadPlayers[team][j + 1] = level.deadPlayers[team][j];
1701 level.deadPlayers[team][j + 1] = player;
1704 for ( i = 0; i < level.deadPlayers[team].size; i++ )
1706 if ( level.deadPlayers[team][i].spawnQueueIndex != i )
1708 level.spawnQueueModified[team] =
true;
1710 level.deadPlayers[team][i].spawnQueueIndex = i;
1717 foreach( team
in level.teams )
1719 count += level.aliveCount[team];
1727 foreach( team
in level.teams )
1729 count += level.playerLives[team];
1737 if ( !isdefined( level.aliveCount ) )
1738 level.aliveCount = [];
1740 level.aliveCount[team] = 0;
1741 level.lastAliveCount[team] = 0;
1743 level.everExisted[team] =
false;
1744 level.waveDelay[team] = 0;
1745 level.lastWave[team] = 0;
1746 level.wavePlayerSpawnIndex[team] = 0;
1753 level.playerCount[team] = 0;
1754 level.botsCount[team] = 0;
1755 level.lastAliveCount[team] = level.aliveCount[team];
1756 level.aliveCount[team] = 0;
1757 level.playerLives[team] = 0;
1758 level.alivePlayers[team] = [];
1759 level.deadPlayers[team] = [];
1760 level.squads[team] = [];
1761 level.spawnQueueModified[team] =
false;
1767 level notify(
"updating_team_status");
1768 level endon(
"updating_team_status");
1769 level endon (
"game_ended" );
1774 if ( game[
"state"] ==
"postgame" )
1779 foreach( team
in level.teams )
1784 level.activePlayers = [];
1786 players = level.players;
1787 for ( i = 0; i < players.size; i++ )
1789 player = players[i];
1791 if ( !isdefined( player ) && level.splitscreen )
1796 if ( team !=
"spectator" )
1798 level.playerCount[team]++;
1800 if( isdefined( player.pers[
"isBot"] ) )
1801 level.botsCount[team]++;
1803 if ( player.sessionstate ==
"playing" )
1805 level.aliveCount[team]++;
1806 level.playerLives[team]++;
1807 player.spawnQueueIndex = -1;
1809 if ( isAlive( player ) )
1811 level.alivePlayers[team][level.alivePlayers[team].size] = player;
1812 level.activeplayers[ level.activeplayers.size ] = player;
1816 level.deadPlayers[team][level.deadPlayers[team].size] = player;
1821 level.deadPlayers[team][level.deadPlayers[team].size] = player;
1823 level.playerLives[team]++;
1830 if ( totalAlive > level.maxPlayerCount )
1831 level.maxPlayerCount = totalAlive;
1833 foreach( team
in level.teams )
1835 if ( level.aliveCount[team] )
1836 level.everExisted[team] =
true;
1846 assert( isdefined( team ) );
1848 if ( level.scoreLimit <= 0 )
1851 if ( !level.teamBased )
1862 level notify(
"match_ending_soon",
"score" );
1868 assert( IsPlayer(
self ) );
1870 if ( level.scoreLimit <= 0 )
1873 if ( level.teamBased )
1884 level notify(
"match_ending_soon",
"score" );
1891 level.timerStopped =
false;
1895 SetMatchTalkFlag(
"DeadChatWithDead", level.voip.deadChatWithDead );
1896 SetMatchTalkFlag(
"DeadChatWithTeam", level.voip.deadChatWithTeam );
1897 SetMatchTalkFlag(
"DeadHearTeamLiving", level.voip.deadHearTeamLiving );
1898 SetMatchTalkFlag(
"DeadHearAllLiving", level.voip.deadHearAllLiving );
1899 SetMatchTalkFlag(
"EveryoneHearsEveryone", level.voip.everyoneHearsEveryone );
1900 SetMatchTalkFlag(
"DeadHearKiller", level.voip.deadHearKiller );
1901 SetMatchTalkFlag(
"KillersHearVictim", level.voip.killersHearVictim );
1904 level notify(
"prematch_over");
1930 setMatchFlag(
"hud_hardcore", level.hardcoreMode );
1932 level endon(
"game_ended" );
1934 if ( level.prematchPeriod > 0 )
1940 wait ( level.prematchPeriod );
1949 level.inPrematchPeriod =
false;
1951 for ( index = 0; index < level.players.size; index++ )
1954 level.players[index] enableWeapons();
1959 if ( game[
"state"] !=
"playing" )
1965 level endon(
"game_ended");
1967 if ( isdefined( level.gracePeriodFunc ) )
1969 [[ level.gracePeriodFunc ]]();
1973 wait ( level.gracePeriod );
1976 level notify (
"grace_period_ending" );
1979 level.inGracePeriod =
false;
1981 if ( game[
"state"] !=
"playing" )
1984 if ( level.numLives )
1987 players = level.players;
1989 for ( i = 0; i < players.size; i++ )
1991 player = players[i];
1993 if ( !player.hasSpawned && player.sessionteam !=
"spectator" && !isAlive( player ) )
1994 player.statusicon =
"hud_status_dead";
2003 SetDvar(
"xblive_matchEndingSoon", 0 );
2004 level waittill(
"match_ending_soon", reason );
2005 SetDvar(
"xblive_matchEndingSoon", 1 );
2014 foreach ( team
in level.teams )
2016 if ( level.waveDelay[team] )
2025 level.prematchPeriod = 0;
2026 level.intermission =
false;
2028 setmatchflag(
"cg_drawSpectatorMessages", 1 );
2029 setmatchflag(
"game_ended", 0 );
2031 if ( !isdefined( game[
"gamestarted"] ) )
2034 if ( !isdefined( game[
"allies"] ) )
2035 game[
"allies"] =
"seals";
2036 if ( !isdefined( game[
"axis"] ) )
2037 game[
"axis"] =
"pmc";
2038 if ( !isdefined( game[
"attackers"] ) )
2039 game[
"attackers"] =
"allies";
2040 if ( !isdefined( game[
"defenders"] ) )
2041 game[
"defenders"] =
"axis";
2044 assert( game[
"attackers"] != game[
"defenders"] );
2047 foreach( team
in level.teams )
2049 if ( !isdefined( game[team] ) )
2053 if ( !isdefined( game[
"state"] ) )
2054 game[
"state"] =
"playing";
2058 SetDvar(
"cg_thirdPersonAngle", 354 );
2060 game[
"strings"][
"press_to_spawn"] = &
"PLATFORM_PRESS_TO_SPAWN";
2061 if ( level.teamBased )
2063 game[
"strings"][
"waiting_for_teams"] = &
"MP_WAITING_FOR_TEAMS";
2064 game[
"strings"][
"opponent_forfeiting_in"] = &
"MP_OPPONENT_FORFEITING_IN";
2068 game[
"strings"][
"waiting_for_teams"] = &
"MP_WAITING_FOR_PLAYERS";
2069 game[
"strings"][
"opponent_forfeiting_in"] = &
"MP_OPPONENT_FORFEITING_IN";
2071 game[
"strings"][
"match_starting_in"] = &
"MP_MATCH_STARTING_IN";
2072 game[
"strings"][
"spawn_next_round"] = &
"MP_SPAWN_NEXT_ROUND";
2073 game[
"strings"][
"waiting_to_spawn"] = &
"MP_WAITING_TO_SPAWN";
2074 game[
"strings"][
"waiting_to_spawn_ss"] = &
"MP_WAITING_TO_SPAWN_SS";
2076 game[
"strings"][
"you_will_spawn"] = &
"MP_YOU_WILL_RESPAWN";
2077 game[
"strings"][
"match_starting"] = &
"MP_MATCH_STARTING";
2078 game[
"strings"][
"change_class"] = &
"MP_CHANGE_CLASS_NEXT_SPAWN";
2079 game[
"strings"][
"last_stand"] = &
"MPUI_LAST_STAND";
2081 game[
"strings"][
"cowards_way"] = &
"PLATFORM_COWARDS_WAY_OUT";
2083 game[
"strings"][
"tie"] = &
"MP_MATCH_TIE";
2084 game[
"strings"][
"round_draw"] = &
"MP_ROUND_DRAW";
2086 game[
"strings"][
"enemies_eliminated"] = &
"MP_ENEMIES_ELIMINATED";
2087 game[
"strings"][
"score_limit_reached"] = &
"MP_SCORE_LIMIT_REACHED";
2088 game[
"strings"][
"round_limit_reached"] = &
"MP_ROUND_LIMIT_REACHED";
2089 game[
"strings"][
"time_limit_reached"] = &
"MP_TIME_LIMIT_REACHED";
2090 game[
"strings"][
"players_forfeited"] = &
"MP_PLAYERS_FORFEITED";
2094 [[level.onPrecacheGameType]]();
2096 game[
"gamestarted"] =
true;
2098 game[
"totalKills"] = 0;
2100 foreach( team
in level.teams )
2102 game[
"teamScores"][team] = 0;
2103 game[
"totalKillsTeam"][team] = 0;
2106 if ( !level.splitscreen )
2107 level.prematchPeriod = GetGametypeSetting(
"prematchperiod" );
2109 if ( GetDvarint(
"xblive_clanmatch" ) != 0 )
2112 foreach( team
in level.teams )
2114 game[
"icons"][team] =
"composite_emblem_team_axis";
2117 game[
"icons"][
"allies"] =
"composite_emblem_team_allies";
2118 game[
"icons"][
"axis"] =
"composite_emblem_team_axis";
2122 if(!isdefined(game[
"timepassed"]))
2123 game[
"timepassed"] = 0;
2125 if(!isdefined(game[
"roundsplayed"]))
2126 game[
"roundsplayed"] = 0;
2127 SetRoundsPlayed( game[
"roundsplayed"] );
2129 if(!isdefined(game[
"roundwinner"] ))
2130 game[
"roundwinner"] = [];
2132 if(!isdefined(game[
"roundswon"] ))
2133 game[
"roundswon"] = [];
2135 if(!isdefined(game[
"roundswon"][
"tie"] ))
2136 game[
"roundswon"][
"tie"] = 0;
2138 foreach ( team
in level.teams )
2140 if(!isdefined(game[
"roundswon"][team] ))
2141 game[
"roundswon"][team] = 0;
2143 level.teamSpawnPoints[team] = [];
2144 level.spawn_point_team_class_names[team] = [];
2147 level.skipVote =
false;
2148 level.gameEnded =
false;
2149 SetDvar(
"g_gameEnded", 0 );
2151 level.objIDStart = 0;
2152 level.forcedEnd =
false;
2153 level.hostForcedEnd =
false;
2155 level.hardcoreMode = GetGametypeSetting(
"hardcoreMode" );
2156 if ( level.hardcoreMode )
2161 if( !isdefined(level.friendlyFireDelayTime) )
2162 level.friendlyFireDelayTime = 0;
2165 if ( GetDvarString(
"scr_max_rank" ) ==
"" )
2166 SetDvar(
"scr_max_rank",
"0" );
2167 level.rankCap = GetDvarint(
"scr_max_rank" );
2169 if ( GetDvarString(
"scr_min_prestige" ) ==
"" )
2171 SetDvar(
"scr_min_prestige",
"0" );
2173 level.minPrestige = GetDvarint(
"scr_min_prestige" );
2176 level.useStartSpawns =
true;
2178 level.cumulativeRoundScores = GetGametypeSetting(
"cumulativeRoundScores" );
2180 level.allowHitMarkers = GetGametypeSetting(
"allowhitmarkers" );
2181 level.playerQueuedRespawn = GetGametypeSetting(
"playerQueuedRespawn" );
2182 level.playerForceRespawn = GetGametypeSetting(
"playerForceRespawn" );
2184 level.perksEnabled = GetGametypeSetting(
"perksEnabled" );
2185 level.disableAttachments = GetGametypeSetting(
"disableAttachments" );
2186 level.disableTacInsert = GetGametypeSetting(
"disableTacInsert" );
2187 level.disableCAC = GetGametypeSetting(
"disableCAC" );
2188 level.disableWeaponDrop = GetGametypeSetting(
"disableweapondrop" );
2189 level.onlyHeadShots = GetGametypeSetting(
"onlyHeadshots" );
2192 level.minimumAllowedTeamKills = GetGametypeSetting(
"teamKillPunishCount" ) - 1;
2193 level.teamKillReducedPenalty = GetGametypeSetting(
"teamKillReducedPenalty" );
2194 level.teamKillPointLoss = GetGametypeSetting(
"teamKillPointLoss" );
2195 level.teamKillSpawnDelay = GetGametypeSetting(
"teamKillSpawnDelay" );
2197 level.deathPointLoss = GetGametypeSetting(
"deathPointLoss" );
2198 level.leaderBonus = GetGametypeSetting(
"leaderBonus" );
2199 level.forceRadar = GetGametypeSetting(
"forceRadar" );
2200 level.playerSprintTime = GetGametypeSetting(
"playerSprintTime" );
2201 level.bulletDamageScalar = GetGametypeSetting(
"bulletDamageScalar" );
2203 level.playerMaxHealth = GetGametypeSetting(
"playerMaxHealth" );
2204 level.playerHealthRegenTime = GetGametypeSetting(
"playerHealthRegenTime" );
2206 level.playerRespawnDelay = GetGametypeSetting(
"playerRespawnDelay" );
2207 level.playerObjectiveHeldRespawnDelay = GetGametypeSetting(
"playerObjectiveHeldRespawnDelay" );
2208 level.waveRespawnDelay = GetGametypeSetting(
"waveRespawnDelay" );
2210 level.spectateType = GetGametypeSetting(
"spectateType" );
2212 level.voip = SpawnStruct();
2213 level.voip.deadChatWithDead = GetGametypeSetting(
"voipDeadChatWithDead" );
2214 level.voip.deadChatWithTeam = GetGametypeSetting(
"voipDeadChatWithTeam" );
2215 level.voip.deadHearAllLiving = GetGametypeSetting(
"voipDeadHearAllLiving" );
2216 level.voip.deadHearTeamLiving = GetGametypeSetting(
"voipDeadHearTeamLiving" );
2217 level.voip.everyoneHearsEveryone = GetGametypeSetting(
"voipEveryoneHearsEveryone" );
2218 level.voip.deadHearKiller = GetGametypeSetting(
"voipDeadHearKiller" );
2219 level.voip.killersHearVictim = GetGametypeSetting(
"voipKillersHearVictim" );
2223 level.prematchPeriod = 0;
2225 level.persistentDataInfo = [];
2226 level.maxRecentStats = 10;
2227 level.maxHitLocations = 19;
2228 level.globalShotsFired = 0;
2249 foreach( team
in level.teams )
2254 level.maxPlayerCount = 0;
2255 level.activePlayers = [];
2257 level.allowAnnouncer = GetGametypeSetting(
"allowAnnouncer" );
2259 if ( !isdefined( level.timeLimit ) )
2262 if ( !isdefined( level.scoreLimit ) )
2265 if ( !isdefined( level.roundLimit ) )
2268 if ( !isdefined( level.roundWinLimit ) )
2279 waveDelay = level.waveRespawnDelay;
2282 foreach ( team
in level.teams )
2284 level.waveDelay[team] = waveDelay;
2285 level.lastWave[team] = 0;
2288 level thread [[level.waveSpawnTimer]]();
2291 level.inPrematchPeriod =
true;
2293 if ( level.prematchPeriod > 2.0 )
2294 level.prematchPeriod = level.prematchPeriod + (randomFloat( 4 ) - 2);
2297 level.gracePeriod = 15;
2299 level.gracePeriod = 5;
2301 level.inGracePeriod =
true;
2303 level.roundEndDelay = 5;
2304 level.halftimeRoundEndDelay = 3;
2308 level.killstreaksenabled = 1;
2310 if ( GetDvarString(
"scr_game_rankenabled" ) ==
"" )
2311 SetDvar(
"scr_game_rankenabled",
true );
2312 level.rankEnabled = GetDvarint(
"scr_game_rankenabled" );
2314 if ( GetDvarString(
"scr_game_medalsenabled" ) ==
"" )
2315 SetDvar(
"scr_game_medalsenabled",
true );
2316 level.medalsEnabled = GetDvarint(
"scr_game_medalsenabled" );
2318 if( level.hardcoreMode && level.rankedMatch && GetDvarString(
"scr_game_friendlyFireDelay" ) ==
"" )
2319 SetDvar(
"scr_game_friendlyFireDelay",
true );
2320 level.friendlyFireDelay = GetDvarint(
"scr_game_friendlyFireDelay" );
2323 [[level.onStartGameType]]();
2326 if( GetDvarInt(
"custom_killstreak_mode" ) == 1 )
2328 level.killstreaksenabled = 0;
2335 level thread simple_hostmigration::UpdateHostMigrationData();
2342 dvarString = (
"scr_" + dvarString +
"_friendlyFireDelayTime");
2343 if ( GetDvarString( dvarString ) ==
"" )
2344 SetDvar( dvarString, defaultValue );
2346 if ( getDvarInt( dvarString ) > maxValue )
2347 SetDvar( dvarString, maxValue );
2348 else if ( getDvarInt( dvarString ) < minValue )
2349 SetDvar( dvarString, minValue );
2351 level.friendlyFireDelayTime = getDvarInt( dvarString );
2356 if ( !isdefined( level.roundSwitch ) || !level.roundSwitch )
2358 if ( !isdefined( level.onRoundSwitch ) )
2361 assert( game[
"roundsplayed"] > 0 );
2363 if ( game[
"roundsplayed"] % level.roundswitch == 0 )
2365 [[level.onRoundSwitch]]();
2375 self waittill(
"host_sucks_end_game" );
2378 level.skipVote =
true;
2380 if ( !level.gameEnded )
2387 for ( killstreakNum = 0; killstreakNum < level.maxKillstreaks; killstreakNum++ )
2389 killstreak[ killstreakNum ] =
"killstreak_null";
2392 if ( isPlayer( player ) && !level.oldschool && ( level.disableCAC != 1 ) &&
2393 ( !isdefined( player.pers[
"isBot"] ) && isdefined(player.killstreak) ) )
2395 currentKillstreak = 0;
2396 for ( killstreakNum = 0; killstreakNum < level.maxKillstreaks; killstreakNum++ )
2398 if ( isdefined( player.killstreak[ killstreakNum ] ) )
2400 killstreak[ currentKillstreak ] = player.killstreak[ killstreakNum ];
2401 currentKillstreak++;
2411 if ( level.rankedMatch )
2415 level.hostForcedEnd =
true;