jwm614

golballogiczm.gsc

Jun 21st, 2016
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 67.10 KB | None | 0 0
  1. #include maps\mp\_utility;
  2. #include maps\mp\gametypes_zm\_hud_util;
  3. //#include maps\mp\_burnplayer;
  4. #include maps\mp\_busing;
  5.  
  6. #include common_scripts\utility;
  7.  
  8. // must match the stats.ddl quitTypes_e enum
  9. #define MATCH_KICKED 2
  10. #define MATCH_QUIT 3
  11. #define MATCH_FINISHED 4
  12.  
  13.  
  14. init()
  15. {
  16.  
  17.     // hack to allow maps with no scripts to run correctly
  18.     if ( !isDefined( level.tweakablesInitialized ) )
  19.         maps\mp\gametypes_zm\_tweakables::init();
  20.    
  21.     init_session_mode_flags();
  22.  
  23.     level.splitscreen = isSplitScreen();
  24.     level.xenon = (GetDvar( "xenonGame") == "true");
  25.     level.ps3 = (GetDvar( "ps3Game") == "true");
  26.     level.wiiu = (GetDvar( "wiiuGame") == "true");
  27.  
  28.     level.onlineGame = SessionModeIsOnlineGame();
  29.     level.console = (level.xenon || level.ps3 || level.wiiu);
  30.    
  31.     level.rankedMatch = ( GameModeIsUsingXP() && !isPreGame() );
  32.     level.leagueMatch = ( GameModeIsMode( level.GAMEMODE_LEAGUE_MATCH ) );
  33.  
  34.     level.wagerMatch = false;
  35.    
  36.     level.contractsEnabled = !GetGametypeSetting( "disableContracts" );
  37.        
  38.     level.contractsEnabled = false;
  39.        
  40.     /#
  41.     if ( GetDvarint( "scr_forcerankedmatch" ) == 1 )
  42.         level.rankedMatch = true;
  43.     #/
  44.  
  45.     level.script = toLower( GetDvar( "mapname" ) );
  46.     level.gametype = toLower( GetDvar( "g_gametype" ) );
  47.  
  48.     level.teamBased = false;
  49.     level.teamCount = GetGametypeSetting( "teamCount" );
  50.     level.multiTeam = ( level.teamCount > 2 );
  51.    
  52.     if ( SessionModeIsZombiesGame() )
  53.     {
  54.         level.zombie_team_index = level.teamCount + 1;
  55.         if ( 2 == level.zombie_team_index )
  56.         {
  57.             level.zombie_team = "axis";
  58.         }
  59.         else
  60.         {
  61.             level.zombie_team = "team" + level.zombie_team_index;
  62.         }
  63.     }
  64.  
  65.     // used to loop through all valid playing teams ( not spectator )
  66.     // can also be used to check if a team is valid ( isdefined( level.teams[team] ) )
  67.     // NOTE: added in the same order they are defined in code
  68.     level.teams = [];
  69.     level.teamIndex = [];
  70.    
  71.     teamCount = level.teamCount;
  72.    
  73.     level.teams[ "allies" ] = "allies";
  74.     level.teams[ "axis" ] = "axis";
  75.  
  76.     level.teamIndex[ "neutral" ] = 0; // Neutral team set to 0 so that it can be used by objectives
  77.     level.teamIndex[ "allies" ] = 1;
  78.     level.teamIndex[ "axis" ] = 2;
  79.    
  80.     for( teamIndex = 3; teamIndex <= teamCount; teamIndex++ )
  81.     {
  82.         level.teams[ "team" + teamIndex ] = "team" + teamIndex;
  83.         level.teamIndex[ "team" + teamIndex ] = teamIndex;
  84.     }
  85.    
  86.     level.overrideTeamScore = false;
  87.     level.overridePlayerScore = false;
  88.     level.displayHalftimeText = false;
  89.     level.displayRoundEndText = true;
  90.    
  91.     level.endGameOnScoreLimit = true;
  92.     level.endGameOnTimeLimit = true;
  93.     level.scoreRoundBased = false;
  94.     level.resetPlayerScoreEveryRound = false;
  95.    
  96.     level.gameForfeited= false;
  97.     level.forceAutoAssign = false;
  98.    
  99.     level.halftimeType = "halftime";
  100.     level.halftimeSubCaption = &"MP_SWITCHING_SIDES_CAPS";
  101.    
  102.     level.lastStatusTime = 0;
  103.     level.wasWinning = [];
  104.    
  105.     level.lastSlowProcessFrame = 0;
  106.    
  107.     level.placement = [];
  108.     foreach( team in level.teams )
  109.     {
  110.         level.placement[team] = [];
  111.     }
  112.     level.placement["all"] = [];
  113.    
  114.     level.postRoundTime = 7.0;//Kevin Sherwood changed to 9 to have enough time for music stingers
  115.    
  116.     level.inOvertime = false;
  117.    
  118.     level.defaultOffenseRadius = 560;
  119.  
  120.     level.dropTeam = GetDvarint( "sv_maxclients" );
  121.    
  122.     level.inFinalKillcam = false;
  123.  
  124.     maps\mp\gametypes_zm\_globallogic_ui::init();
  125.  
  126.     registerDvars();
  127. //  maps\mp\gametypes_zm\_class::initPerkDvars();
  128.  
  129.     level.oldschool = ( GetDvarint( "scr_oldschool" ) == 1 );
  130.     if ( level.oldschool )
  131.     {
  132.         logString( "game mode: oldschool" );
  133.    
  134.         SetDvar( "jump_height", 64 );
  135.         SetDvar( "jump_slowdownEnable", 0 );
  136.         SetDvar( "bg_fallDamageMinHeight", 256 );
  137.         SetDvar( "bg_fallDamageMaxHeight", 512 );
  138.         SetDvar( "player_clipSizeMultiplier", 2.0 );
  139.     }
  140.  
  141.     precacheModel( "tag_origin" );
  142.     precacheRumble( "dtp_rumble" );
  143.     precacheRumble( "slide_rumble" );
  144.    
  145.     precacheStatusIcon( "hud_status_dead" );
  146.     precacheStatusIcon( "hud_status_connecting" );
  147.        
  148.     precache_mp_leaderboards();
  149.    
  150.     // sets up the flame fx
  151.     //maps\mp\_burnplayer::initBurnPlayer();
  152.    
  153.     if ( !isDefined( game["tiebreaker"] ) )
  154.         game["tiebreaker"] = false;
  155.        
  156.     maps\mp\gametypes_zm\_globallogic_audio::registerDialogGroup( "introboost", true );
  157.     maps\mp\gametypes_zm\_globallogic_audio::registerDialogGroup( "status", true );
  158.  
  159.     //thread maps\mp\_gameadvertisement::init();
  160.     //thread maps\mp\_gamerep::init();
  161. }
  162.  
  163. registerDvars()
  164. {
  165.     if ( GetDvar( "scr_oldschool" ) == "" )
  166.         SetDvar( "scr_oldschool", "0" );
  167.        
  168.     makeDvarServerInfo( "scr_oldschool" );
  169.  
  170.     if ( GetDvar( "ui_guncycle" ) == "" )
  171.         SetDvar( "ui_guncycle", 0 );
  172.        
  173.     makedvarserverinfo( "ui_guncycle" );
  174.  
  175.     if ( GetDvar( "ui_weapon_tiers" ) == "" )
  176.         SetDvar( "ui_weapon_tiers", 0 );
  177.     makedvarserverinfo( "ui_weapon_tiers" );
  178.  
  179.     SetDvar( "ui_text_endreason", "");
  180.     makeDvarServerInfo( "ui_text_endreason", "" );
  181.  
  182.     setMatchFlag( "bomb_timer", 0 );
  183.    
  184.     setMatchFlag( "enable_popups", 1 );
  185.    
  186.     setMatchFlag( "pregame", isPregame() );
  187.  
  188.     if ( GetDvar( "scr_vehicle_damage_scalar" ) == "" )
  189.         SetDvar( "scr_vehicle_damage_scalar", "1" );
  190.        
  191.     level.vehicleDamageScalar = GetDvarfloat( "scr_vehicle_damage_scalar");
  192.  
  193.     level.fire_audio_repeat_duration = GetDvarint( "fire_audio_repeat_duration" );
  194.     level.fire_audio_random_max_duration = GetDvarint( "fire_audio_random_max_duration" );
  195. }
  196.  
  197. blank( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 )
  198. {
  199. }
  200.  
  201. SetupCallbacks()
  202. {
  203.     level.spawnPlayer = maps\mp\gametypes_zm\_globallogic_spawn::spawnPlayer;
  204.     level.spawnPlayerPrediction = maps\mp\gametypes_zm\_globallogic_spawn::spawnPlayerPrediction;
  205.     level.spawnClient = maps\mp\gametypes_zm\_globallogic_spawn::spawnClient;
  206.     level.spawnSpectator = maps\mp\gametypes_zm\_globallogic_spawn::spawnSpectator;
  207.     level.spawnIntermission = maps\mp\gametypes_zm\_globallogic_spawn::spawnIntermission;
  208.     level.onPlayerScore = maps\mp\gametypes_zm\_globallogic_score::default_onPlayerScore;
  209.     level.onTeamScore = maps\mp\gametypes_zm\_globallogic_score::default_onTeamScore;
  210.    
  211.     level.waveSpawnTimer = ::waveSpawnTimer;
  212.     level.spawnMessage =    maps\mp\gametypes_zm\_globallogic_spawn::default_spawnMessage;
  213.    
  214.     level.onSpawnPlayer = ::blank;
  215.     level.onSpawnPlayerUnified = ::blank;
  216.     level.onSpawnSpectator = maps\mp\gametypes_zm\_globallogic_defaults::default_onSpawnSpectator;
  217.     level.onSpawnIntermission = maps\mp\gametypes_zm\_globallogic_defaults::default_onSpawnIntermission;
  218.     level.onRespawnDelay = ::blank;
  219.  
  220.     level.onForfeit = maps\mp\gametypes_zm\_globallogic_defaults::default_onForfeit;
  221.     level.onTimeLimit = maps\mp\gametypes_zm\_globallogic_defaults::default_onTimeLimit;
  222.     level.onScoreLimit = maps\mp\gametypes_zm\_globallogic_defaults::default_onScoreLimit;
  223.     level.onAliveCountChange = maps\mp\gametypes_zm\_globallogic_defaults::default_onAliveCountChange;
  224.     level.onDeadEvent = maps\mp\gametypes_zm\_globallogic_defaults::default_onDeadEvent;
  225.     level.onOneLeftEvent = maps\mp\gametypes_zm\_globallogic_defaults::default_onOneLeftEvent;
  226.     level.giveTeamScore = maps\mp\gametypes_zm\_globallogic_score::giveTeamScore;
  227.     level.onLastTeamAliveEvent = undefined;
  228.  
  229.     level.getTimeLimit = maps\mp\gametypes_zm\_globallogic_defaults::default_getTimeLimit;
  230.     level.getTeamKillPenalty =::blank; // maps\mp\gametypes_zm\_globallogic_defaults::default_getTeamKillPenalty;
  231.     level.getTeamKillScore = ::blank;  // maps\mp\gametypes_zm\_globallogic_defaults::default_getTeamKillScore;
  232.  
  233.     level.isKillBoosting = maps\mp\gametypes_zm\_globallogic_score::default_isKillBoosting;
  234.  
  235.     level._setTeamScore = maps\mp\gametypes_zm\_globallogic_score::_setTeamScore;
  236.     level._setPlayerScore = maps\mp\gametypes_zm\_globallogic_score::_setPlayerScore;
  237.  
  238.     level._getTeamScore = maps\mp\gametypes_zm\_globallogic_score::_getTeamScore;
  239.     level._getPlayerScore = maps\mp\gametypes_zm\_globallogic_score::_getPlayerScore;
  240.    
  241.     level.onPrecacheGametype = ::blank;
  242.     level.onStartGameType = ::blank;
  243.     level.onPlayerConnect = ::blank;
  244.     level.onPlayerDisconnect = ::blank;
  245.     level.onPlayerDamage = ::blank;
  246.     level.onPlayerKilled = ::blank;
  247.     level.onPlayerKilledExtraUnthreadedCBs = []; ///< Array of other CB function pointers
  248.  
  249.     level.onTeamOutcomeNotify = maps\mp\gametypes_zm\_hud_message::teamOutcomeNotify;
  250.     level.onOutcomeNotify = maps\mp\gametypes_zm\_hud_message::outcomeNotify;
  251.     level.onTeamWagerOutcomeNotify = maps\mp\gametypes_zm\_hud_message::teamWagerOutcomeNotify;
  252.     level.onWagerOutcomeNotify = maps\mp\gametypes_zm\_hud_message::wagerOutcomeNotify;
  253.     level.setMatchScoreHUDElemForTeam = maps\mp\gametypes_zm\_hud_message::setMatchScoreHUDElemForTeam;
  254.     level.onEndGame = ::blank;
  255.     level.onRoundEndGame = maps\mp\gametypes_zm\_globallogic_defaults::default_onRoundEndGame;
  256.     level.onMedalAwarded = ::blank;
  257.  
  258.     maps\mp\gametypes_zm\_globallogic_ui::SetupCallbacks();
  259. }
  260.  
  261. precache_mp_leaderboards()
  262. {
  263.     if( SessionModeIsZombiesGame() )
  264.         return;
  265.  
  266.     if( !level.rankedMatch )
  267.         return;
  268.        
  269.     mapname = GetDvar( "mapname" );
  270.  
  271.     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";
  272.  
  273.     gamemodeLeaderboard = " LB_MP_GM_" + level.gametype;
  274.                
  275.     if( getDvarInt( "g_hardcore" ) )
  276.         gamemodeLeaderboard += "_HC";
  277.    
  278.     mapLeaderboard = " LB_MP_MAP_" + getsubstr( mapname, 3, mapname.size ); // strip the MP_ from the map name
  279.        
  280.     precacheLeaderboards( globalLeaderboards + gamemodeLeaderboard + mapLeaderboard ); 
  281. }
  282.  
  283. compareTeamByGameStat( gameStat, teamA, teamB, previous_winner_score )
  284. {
  285.     winner = undefined;
  286.    
  287.     if ( teamA == "tie" )
  288.     {
  289.         winner = "tie";
  290.        
  291.         if ( previous_winner_score < game[gameStat][teamB] )
  292.             winner = teamB;
  293.     }
  294.     else if ( game[gameStat][teamA] == game[gameStat][teamB] )
  295.         winner = "tie";
  296.     else if ( game[gameStat][teamB] > game[gameStat][teamA] )
  297.         winner = teamB;
  298.     else
  299.         winner = teamA;
  300.    
  301.     return winner;
  302. }
  303.  
  304. determineTeamWinnerByGameStat( gameStat )
  305. {
  306.     teamKeys = GetArrayKeys(level.teams);
  307.     winner = teamKeys[0];
  308.     previous_winner_score = game[gameStat][winner];
  309.    
  310.     for ( teamIndex = 1; teamIndex < teamKeys.size; teamIndex++ )
  311.     {
  312.         winner = compareTeamByGameStat( gameStat, winner, teamKeys[teamIndex], previous_winner_score);
  313.        
  314.         if ( winner != "tie" )
  315.         {
  316.             previous_winner_score = game[gameStat][winner];
  317.         }  
  318.     }
  319.    
  320.     return winner;
  321. }
  322.  
  323. compareTeamByTeamScore( teamA, teamB, previous_winner_score )
  324. {
  325.     winner = undefined;
  326.   teamBScore = [[level._getTeamScore]]( teamB );
  327.  
  328.     if ( teamA == "tie" )
  329.     {
  330.         winner = "tie";
  331.        
  332.         if ( previous_winner_score < teamBScore )
  333.             winner = teamB;
  334.            
  335.         return winner;
  336.     }
  337.    
  338.   teamAScore = [[level._getTeamScore]]( teamA );
  339.  
  340.     if ( teamBScore == teamAScore )
  341.         winner = "tie";
  342.     else if ( teamBScore > teamAScore )
  343.         winner = teamB;
  344.     else
  345.         winner = teamA;
  346.        
  347.     return winner;
  348. }
  349.  
  350. determineTeamWinnerByTeamScore( )
  351. {
  352.     teamKeys = GetArrayKeys(level.teams);
  353.     winner = teamKeys[0];
  354.     previous_winner_score = [[level._getTeamScore]]( winner );
  355.    
  356.     for ( teamIndex = 1; teamIndex < teamKeys.size; teamIndex++ )
  357.     {
  358.         winner = compareTeamByTeamScore( winner, teamKeys[teamIndex], previous_winner_score);
  359.        
  360.         if ( winner != "tie" )
  361.         {
  362.             previous_winner_score = [[level._getTeamScore]]( winner );
  363.         }  
  364.     }
  365.    
  366.     return winner;
  367. }
  368.  
  369. forceEnd(hostsucks)
  370. {
  371.     if (!isDefined(hostsucks))
  372.         hostsucks = false;
  373.  
  374.     if ( level.hostForcedEnd || level.forcedEnd )
  375.         return;
  376.  
  377.     winner = undefined;
  378.    
  379.     if ( level.teamBased )
  380.     {
  381.         winner = determineTeamWinnerByGameStat("teamScores");
  382.         maps\mp\gametypes_zm\_globallogic_utils::logTeamWinString( "host ended game", winner );
  383.     }
  384.     else
  385.     {
  386.         winner = maps\mp\gametypes_zm\_globallogic_score::getHighestScoringPlayer();
  387.         if ( isDefined( winner ) )
  388.             logString( "host ended game, win: " + winner.name );
  389.         else
  390.             logString( "host ended game, tie" );
  391.     }
  392.    
  393.     level.forcedEnd = true;
  394.     level.hostForcedEnd = true;
  395.    
  396.     if (hostsucks)
  397.     {
  398.         endString = &"MP_HOST_SUCKS";
  399.     }
  400.     else
  401.     {
  402.         if ( level.splitscreen )
  403.             endString = &"MP_ENDED_GAME";
  404.         else
  405.             endString = &"MP_HOST_ENDED_GAME";
  406.     }
  407.    
  408.     setMatchFlag( "disableIngameMenu", 1 );
  409.     makeDvarServerInfo( "ui_text_endreason", endString );
  410.     SetDvar( "ui_text_endreason", endString );
  411.     thread endGame( winner, endString );
  412. }
  413.  
  414. killserverPc()
  415. {
  416.     if ( level.hostForcedEnd || level.forcedEnd )
  417.         return;
  418.        
  419.     winner = undefined;
  420.    
  421.     if ( level.teamBased )
  422.     {
  423.         winner = determineTeamWinnerByGameStat("teamScores");
  424.         maps\mp\gametypes_zm\_globallogic_utils::logTeamWinString( "host ended game", winner );
  425.     }
  426.     else
  427.     {
  428.         winner = maps\mp\gametypes_zm\_globallogic_score::getHighestScoringPlayer();
  429.         if ( isDefined( winner ) )
  430.             logString( "host ended game, win: " + winner.name );
  431.         else
  432.             logString( "host ended game, tie" );
  433.     }
  434.    
  435.     level.forcedEnd = true;
  436.     level.hostForcedEnd = true;
  437.    
  438.     level.killserver = true;
  439.    
  440.     endString = &"MP_HOST_ENDED_GAME";
  441.    
  442.    
  443. /#
  444.         PrintLn("kill server; ending game\n");
  445. #/
  446.  
  447.     thread endGame( winner, endString );
  448. }
  449.  
  450. someoneOnEachTeam()
  451. {
  452.     foreach ( team in level.teams )
  453.     {
  454.         if ( level.playerCount[team] == 0 )
  455.             return false;
  456.     }
  457.    
  458.     return true;
  459. }
  460.  
  461. checkIfTeamForfeits( team )
  462. {
  463.     if ( !level.everExisted[team] )
  464.         return false;
  465.        
  466.     if ( level.playerCount[team] < 1 && totalPlayerCount() > 0 )
  467.     {
  468.         return true;
  469.     }
  470.    
  471.     return false;
  472. }
  473.  
  474. checkForAnyTeamForfeit()
  475. {
  476.     foreach( team in level.teams )
  477.     {
  478.         if ( checkIfTeamForfeits( team ) )
  479.         {
  480.             //allies forfeited
  481.             thread [[level.onForfeit]]( team );
  482.             return true;
  483.         }
  484.     }
  485.    
  486.     return false;
  487. }
  488.  
  489. doSpawnQueueUpdates()
  490. {
  491.     foreach( team in level.teams )
  492.     {
  493.         if ( level.spawnQueueModified[team] )
  494.         {
  495.             [[level.onAliveCountChange]]( team );
  496.         }
  497.     }
  498. }
  499.  
  500. isTeamAllDead( team )
  501. {
  502.     return  (level.everExisted[team] && !level.aliveCount[team] && !level.playerLives[team] );
  503. }
  504.  
  505. areAllTeamsDead( )
  506. {
  507.     foreach( team in level.teams )
  508.     {
  509.         // if team was alive and now they are not
  510.         if ( !isTeamAllDead( team ) )
  511.         {  
  512.             return false;
  513.         }
  514.     }
  515.    
  516.     return true;
  517. }
  518.  
  519. allDeadTeamCount( )
  520. {
  521.     count = 0;
  522.     foreach( team in level.teams )
  523.     {
  524.         // if team was alive and now they are not
  525.         if ( isTeamAllDead( team ) )
  526.         {  
  527.             count++;
  528.         }
  529.     }
  530.    
  531.     return count;
  532. }
  533.  
  534. doDeadEventUpdates()
  535. {
  536.     if ( level.teamBased )
  537.     {
  538.         // if all teams were alive and now they are all dead in the same instance
  539.         if ( areAllTeamsDead( ) )
  540.         {
  541.             [[level.onDeadEvent]]( "all" );
  542.             return true;
  543.         }
  544.  
  545.         // TODO MTEAM - invert all onDeadEvent functions to be onLastTeamAliveEvent instead
  546.         if ( isdefined( level.onLastTeamAliveEvent ) )
  547.         {
  548.             if ( allDeadTeamCount( ) == level.teams.size - 1 )
  549.             {
  550.                 foreach( team in level.teams )
  551.                 {
  552.                     // if team is alive
  553.                     if ( !isTeamAllDead( team ) )
  554.                     {  
  555.                         [[level.onLastTeamAliveEvent]]( team );
  556.                         return true;
  557.                     }
  558.                 }
  559.             }
  560.         }
  561.         else
  562.         {
  563.             foreach( team in level.teams )
  564.             {
  565.                 // if team was alive and now they are not
  566.                 if ( isTeamAllDead( team ) )
  567.                 {  
  568.                     [[level.onDeadEvent]]( team );
  569.                     return true;
  570.                 }
  571.             }
  572.         }
  573.     }
  574.     else
  575.     {
  576.         // everyone is dead
  577.         if ( (totalAliveCount() == 0) && (totalPlayerLives() == 0) && level.maxPlayerCount > 1 )
  578.         {
  579.             [[level.onDeadEvent]]( "all" );
  580.             return true;;
  581.         }
  582.     }
  583.    
  584.     return false;
  585. }
  586.  
  587. isOnlyOneLeftAliveOnTeam( team )
  588. {
  589.     return  (level.lastAliveCount[team] > 1 && level.aliveCount[team] == 1 && level.playerLives[team] == 1 );
  590. }
  591.  
  592.  
  593. doOneLeftEventUpdates()
  594. {
  595.     if ( level.teamBased )
  596.     {
  597.         foreach( team in level.teams )
  598.         {
  599.             // one "team" left
  600.             if ( isOnlyOneLeftAliveOnTeam( team ) )
  601.             {  
  602.                 [[level.onOneLeftEvent]]( team );
  603.                 return true;;
  604.             }
  605.         }
  606.     }
  607.     else
  608.     {
  609.         // last man standing
  610.         if ( (totalAliveCount() == 1) && (totalPlayerLives() == 1) && level.maxPlayerCount > 1 )
  611.         {
  612.             [[level.onOneLeftEvent]]( "all" );
  613.             return true;;
  614.         }
  615.     }
  616.    
  617.     return false;
  618. }
  619.  
  620. updateGameEvents()
  621. {
  622. /#
  623.     if( GetDvarint( "scr_hostmigrationtest" ) == 1 )
  624.     {
  625.         return;
  626.     }
  627. #/
  628.     if ( ( level.rankedMatch || level.wagerMatch || level.leagueMatch ) && !level.inGracePeriod )
  629.     {
  630.         if ( level.teamBased )
  631.         {
  632.             if (!level.gameForfeited )
  633.             {
  634.                 if( game["state"] == "playing" && checkForAnyTeamForfeit() )
  635.                 {
  636.                     return;
  637.                 }
  638.             }
  639.             else // level.gameForfeited==true
  640.             {
  641.                 if ( someoneOnEachTeam() )
  642.                 {
  643.                     level.gameForfeited = false;
  644.                     level notify( "abort forfeit" );
  645.                 }
  646.             }
  647.         }
  648.         else
  649.         {
  650.             if (!level.gameForfeited)
  651.             {
  652.                 if ( totalPlayerCount() == 1 && level.maxPlayerCount > 1 )
  653.                 {
  654.                     thread [[level.onForfeit]]();
  655.                     return;
  656.                 }
  657.             }
  658.             else // level.gameForfeited==true
  659.             {
  660.                 if ( totalPlayerCount() > 1 )
  661.                 {
  662.                     level.gameForfeited = false;
  663.                     level notify( "abort forfeit" );
  664.                 }
  665.             }
  666.         }
  667.     }
  668.        
  669.     if ( !level.playerQueuedRespawn && !level.numLives && !level.inOverTime )
  670.         return;
  671.        
  672.     if ( level.inGracePeriod )
  673.         return;
  674.  
  675.     if ( level.playerQueuedRespawn )
  676.     {
  677.         doSpawnQueueUpdates();
  678.     }
  679.    
  680.     if ( doDeadEventUpdates() )
  681.         return;
  682.        
  683.     if ( doOneLeftEventUpdates() )
  684.         return;
  685. }
  686.  
  687.  
  688. matchStartTimer()
  689. {  
  690.     visionSetNaked( "mpIntro", 0 );
  691.  
  692.     matchStartText = createServerFontString( "objective", 1.5 );
  693.     matchStartText setPoint( "CENTER", "CENTER", 0, -40 );
  694.     matchStartText.sort = 1001;
  695.     matchStartText setText( game["strings"]["waiting_for_teams"] );
  696.     matchStartText.foreground = false;
  697.     matchStartText.hidewheninmenu = true;
  698.  
  699.     waitForPlayers();
  700.     matchStartText setText( game["strings"]["match_starting_in"] );
  701.  
  702.     matchStartTimer = createServerFontString( "objective", 2.2 );
  703.     matchStartTimer setPoint( "CENTER", "CENTER", 0, 0 );
  704.     matchStartTimer.sort = 1001;
  705.     matchStartTimer.color = (1,1,0);
  706.     matchStartTimer.foreground = false;
  707.     matchStartTimer.hidewheninmenu = true;
  708.    
  709.    
  710.     //Since the scaling is disabled, we cant see the pulse effect by scaling. We need to change keep switching between
  711.     //some small and big font to get the pulse effect. This will be fixed when we have fixed set of different sizes fonts.
  712.    
  713.     //matchStartTimer maps\mp\gametypes_zm\_hud::fontPulseInit();
  714.  
  715.     countTime = int( level.prematchPeriod );
  716.    
  717.     if ( countTime >= 2 )
  718.     {
  719.         while ( countTime > 0 && !level.gameEnded )
  720.         {
  721.             matchStartTimer setValue( countTime );
  722.             //matchStartTimer thread maps\mp\gametypes_zm\_hud::fontPulse( level );
  723.             if ( countTime == 2 )
  724.                 visionSetNaked( GetDvar( "mapname" ), 3.0 );
  725.             countTime--;
  726.             wait ( 1.0 );
  727.         }
  728.     }
  729.     else
  730.     {
  731.         visionSetNaked( GetDvar( "mapname" ), 1.0 );
  732.     }
  733.  
  734.     matchStartTimer destroyElem();
  735.     matchStartText destroyElem();
  736. }
  737.  
  738. matchStartTimerSkip()
  739. {
  740.     if ( !isPregame() )
  741.         visionSetNaked( GetDvar( "mapname" ), 0 );
  742.     else
  743.         visionSetNaked( "mpIntro", 0 );
  744. }
  745.  
  746. notifyTeamWaveSpawn( team, time )
  747. {
  748.     if ( time - level.lastWave[team] > (level.waveDelay[team] * 1000) )
  749.     {
  750.         level notify ( "wave_respawn_" + team );
  751.         level.lastWave[team] = time;
  752.         level.wavePlayerSpawnIndex[team] = 0;
  753.     }
  754. }
  755.  
  756. waveSpawnTimer()
  757. {
  758.     level endon( "game_ended" );
  759.  
  760.     while ( game["state"] == "playing" )
  761.     {
  762.         time = getTime();
  763.        
  764.         foreach( team in level.teams )
  765.         {
  766.             notifyTeamWaveSpawn( team, time );
  767.         }
  768.         wait ( 0.05 );
  769.     }
  770. }
  771.  
  772.  
  773. hostIdledOut()
  774. {
  775.     hostPlayer = getHostPlayer();
  776.    
  777. /#
  778.     if( GetDvarint( "scr_writeconfigstrings" ) == 1  || GetDvarint( "scr_hostmigrationtest" ) == 1 )
  779.         return false;
  780. #/
  781.  
  782.     // host never spawned
  783.     if ( isDefined( hostPlayer ) && !hostPlayer.hasSpawned && !isDefined( hostPlayer.selectedClass ) )
  784.         return true;
  785.  
  786.     return false;
  787. }
  788.  
  789. IncrementMatchCompletionStat( gameMode, playedOrHosted, stat )
  790. {
  791.     self AddDStat( "gameHistory", gameMode, "modeHistory", playedOrHosted, stat, 1 );
  792. }
  793.  
  794. SetMatchCompletionStat( gameMode, playedOrHosted, stat )
  795. {
  796.     self SetDStat( "gameHistory", gameMode, "modeHistory", playedOrHosted, stat, 1 );
  797. }
  798.  
  799. GetCurrentGameMode()
  800. {      
  801.     return "publicmatch";
  802. }
  803.  
  804. displayRoundEnd( winner, endReasonText )
  805. {
  806.     if ( level.displayRoundEndText )
  807.     {
  808.         if ( winner == "tie" )
  809.         {
  810.             maps\mp\_demo::gameResultBookmark( "round_result", level.teamIndex[ "neutral" ], level.teamIndex[ "neutral" ] );
  811.         }
  812.         else
  813.         {
  814.             maps\mp\_demo::gameResultBookmark( "round_result", level.teamIndex[ winner ], level.teamIndex[ "neutral" ] );
  815.         }
  816.  
  817.         setmatchflag( "cg_drawSpectatorMessages", 0 );
  818.         players = level.players;
  819.         for ( index = 0; index < players.size; index++ )
  820.         {
  821.             player = players[index];
  822.            
  823.             if ( !isDefined( player.pers["team"] ) )
  824.             {
  825.                 player [[level.spawnIntermission]]( true );
  826.                 player closeMenu();
  827.                 player closeInGameMenu();
  828.                 continue;
  829.             }
  830.            
  831.             if ( level.wagerMatch )
  832.             {
  833.                 if ( level.teamBased )
  834.                     player thread [[level.onTeamWagerOutcomeNotify]]( winner, true, endReasonText );
  835.                 else
  836.                     player thread [[level.onWagerOutcomeNotify]]( winner, endReasonText );
  837.             }
  838.             else
  839.             {
  840.                 if ( level.teamBased )
  841.                 {
  842.                     player thread [[level.onTeamOutcomeNotify]]( winner, true, endReasonText );
  843.                     player maps\mp\gametypes_zm\_globallogic_audio::set_music_on_player( "ROUND_END" );    
  844.                 }
  845.                 else
  846.                 {
  847.                     player thread [[level.onOutcomeNotify]]( winner, true, endReasonText );
  848.                     player maps\mp\gametypes_zm\_globallogic_audio::set_music_on_player( "ROUND_END" );
  849.                 }
  850.             }
  851.    
  852.         player setClientUIVisibilityFlag( "hud_visible", 0 );
  853.             player setClientUIVisibilityFlag( "g_compassShowEnemies", 0 );
  854.         }
  855.     }
  856.  
  857.     if ( wasLastRound() )
  858.     {
  859.         roundEndWait( level.roundEndDelay, false );
  860.     }
  861.     else
  862.     {
  863.         thread maps\mp\gametypes_zm\_globallogic_audio::announceRoundWinner( winner, level.roundEndDelay / 4 );
  864.         roundEndWait( level.roundEndDelay, true );
  865.     }
  866. }
  867.  
  868. displayRoundSwitch( winner, endReasonText )
  869. {
  870.     switchType = level.halftimeType;
  871.     if ( switchType == "halftime" )
  872.     {
  873.         if ( IsDefined( level.nextRoundIsOvertime ) && level.nextRoundIsOvertime )
  874.         {
  875.             switchType = "overtime";
  876.         }
  877.         else
  878.         {
  879.             if ( level.roundLimit )
  880.             {
  881.                 if ( (game["roundsplayed"] * 2) == level.roundLimit )
  882.                     switchType = "halftime";
  883.                 else
  884.                     switchType = "intermission";
  885.             }
  886.             else if ( level.scoreLimit )
  887.             {
  888.                 if ( game["roundsplayed"] == (level.scoreLimit - 1) )
  889.                     switchType = "halftime";
  890.                 else
  891.                     switchType = "intermission";
  892.             }
  893.             else
  894.             {
  895.                 switchType = "intermission";
  896.             }
  897.         }
  898.     }
  899.    
  900.     leaderdialog = maps\mp\gametypes_zm\_globallogic_audio::getRoundSwitchDialog( switchType );
  901.    
  902.     SetMatchTalkFlag( "EveryoneHearsEveryone", 1 );
  903.  
  904.     players = level.players;
  905.     for ( index = 0; index < players.size; index++ )
  906.     {
  907.         player = players[index];
  908.        
  909.         if ( !isDefined( player.pers["team"] ) )
  910.         {
  911.             player [[level.spawnIntermission]]( true );
  912.             player closeMenu();
  913.             player closeInGameMenu();
  914.             continue;
  915.         }
  916.        
  917.         player maps\mp\gametypes_zm\_globallogic_audio::leaderDialogOnPlayer( leaderdialog );
  918.         player maps\mp\gametypes_zm\_globallogic_audio::set_music_on_player( "ROUND_SWITCH" );
  919.        
  920.         if ( level.wagerMatch )
  921.             player thread [[level.onTeamWagerOutcomeNotify]]( switchType, true, level.halftimeSubCaption );
  922.         else
  923.             player thread [[level.onTeamOutcomeNotify]]( switchType, false, level.halftimeSubCaption );
  924.         player setClientUIVisibilityFlag( "hud_visible", 0 );
  925.     }
  926.  
  927.     roundEndWait( level.halftimeRoundEndDelay, false );
  928. }
  929.  
  930. displayGameEnd( winner, endReasonText )
  931. {
  932.     SetMatchTalkFlag( "EveryoneHearsEveryone", 1 );
  933.     setmatchflag( "cg_drawSpectatorMessages", 0 );
  934.  
  935.     if ( winner == "tie" )
  936.     {
  937.         maps\mp\_demo::gameResultBookmark( "game_result", level.teamIndex[ "neutral" ], level.teamIndex[ "neutral" ] );
  938.     }
  939.     else
  940.     {
  941.         maps\mp\_demo::gameResultBookmark( "game_result", level.teamIndex[ winner ], level.teamIndex[ "neutral" ] );
  942.     }
  943.  
  944.     // catching gametype, since DM forceEnd sends winner as player entity, instead of string
  945.     players = level.players;
  946.     for ( index = 0; index < players.size; index++ )
  947.     {
  948.         player = players[index];
  949.    
  950.         if ( !isDefined( player.pers["team"] ) )
  951.         {
  952.             player [[level.spawnIntermission]]( true );
  953.             player closeMenu();
  954.             player closeInGameMenu();
  955.             continue;
  956.         }
  957.        
  958.         if ( level.wagerMatch )
  959.         {
  960.             if ( level.teamBased )
  961.                 player thread [[level.onTeamWagerOutcomeNotify]]( winner, false, endReasonText );
  962.             else
  963.                 player thread [[level.onWagerOutcomeNotify]]( winner, endReasonText );
  964.         }
  965.         else
  966.         {
  967.             if ( level.teamBased )
  968.             {
  969.                 player thread [[level.onTeamOutcomeNotify]]( winner, false, endReasonText );
  970.             }
  971.             else
  972.             {
  973.                 player thread [[level.onOutcomeNotify]]( winner, false, endReasonText );
  974.                
  975.                 if ( isDefined( winner ) && player == winner )
  976.                     player maps\mp\gametypes_zm\_globallogic_audio::set_music_on_player( "VICTORY" );      
  977.                 else if ( !level.splitScreen )
  978.                     player maps\mp\gametypes_zm\_globallogic_audio::set_music_on_player( "LOSE" ); 
  979.             }
  980.         }
  981.        
  982.         player setClientUIVisibilityFlag( "hud_visible", 0 );
  983.         player setClientUIVisibilityFlag( "g_compassShowEnemies", 0 );
  984.     }
  985.    
  986.     if ( level.teamBased )
  987.     {
  988.         thread maps\mp\gametypes_zm\_globallogic_audio::announceGameWinner( winner, level.postRoundTime / 2 );
  989.  
  990.         players = level.players;
  991.         for ( index = 0; index < players.size; index++ )
  992.         {
  993.             player = players[index];
  994.             team = player.pers["team"];
  995.    
  996.             if ( level.splitscreen )
  997.             {
  998.                 if ( winner == "tie" )
  999.                 {
  1000.                     player maps\mp\gametypes_zm\_globallogic_audio::set_music_on_player( "DRAW" );
  1001.                 }                      
  1002.                 else if ( winner == team )
  1003.                 {  
  1004.                     player maps\mp\gametypes_zm\_globallogic_audio::set_music_on_player( "VICTORY" );              
  1005.                 }
  1006.                 else
  1007.                 {
  1008.                     player maps\mp\gametypes_zm\_globallogic_audio::set_music_on_player( "LOSE" ); 
  1009.                 }  
  1010.             }
  1011.             else
  1012.             {
  1013.                 if ( winner == "tie" )
  1014.                 {
  1015.                     player maps\mp\gametypes_zm\_globallogic_audio::set_music_on_player( "DRAW" );
  1016.                 }              
  1017.                 else if ( winner == team )
  1018.                 {
  1019.                     player maps\mp\gametypes_zm\_globallogic_audio::set_music_on_player( "VICTORY" );
  1020.                 }
  1021.                 else
  1022.                 {
  1023.                     player maps\mp\gametypes_zm\_globallogic_audio::set_music_on_player( "LOSE" ); 
  1024.                 }
  1025.             }
  1026.         }
  1027.     }
  1028.    
  1029.     bbPrint( "session_epilogs", "reason %s", endReasonText );
  1030.  
  1031.     // tagTMR<NOTE>: all round data aggregates that cannot be summed from other tables post-runtime
  1032.     bbPrint( "mpmatchfacts", "gametime %d winner %s killstreakcount %d", gettime(), winner, level.killstreak_counter );
  1033.    
  1034.     roundEndWait( level.postRoundTime, true );
  1035. }
  1036.  
  1037. getEndReasonText()
  1038. {
  1039.     if ( hitRoundLimit() || hitRoundWinLimit() )
  1040.         return  game["strings"]["round_limit_reached"];
  1041.     else if ( hitScoreLimit() )
  1042.         return  game["strings"]["score_limit_reached"];
  1043.  
  1044.     if ( level.forcedEnd )
  1045.     {
  1046.         if ( level.hostForcedEnd )
  1047.             return &"MP_HOST_ENDED_GAME";
  1048.         else
  1049.             return &"MP_ENDED_GAME";
  1050.     }
  1051.     return game["strings"]["time_limit_reached"];
  1052. }
  1053.  
  1054. resetOutcomeForAllPlayers()
  1055. {
  1056.     players = level.players;
  1057.     for ( index = 0; index < players.size; index++ )
  1058.     {
  1059.         player = players[index];
  1060.         player notify ( "reset_outcome" );
  1061.     }
  1062. }
  1063.  
  1064. startNextRound( winner, endReasonText )
  1065. {
  1066.     if ( !isOneRound() )
  1067.     {
  1068.         displayRoundEnd( winner, endReasonText );
  1069.  
  1070.         maps\mp\gametypes_zm\_globallogic_utils::executePostRoundEvents();
  1071.        
  1072.         if ( !wasLastRound() )
  1073.         {
  1074.             if ( checkRoundSwitch() )
  1075.             {
  1076.                 displayRoundSwitch( winner, endReasonText );
  1077.             }
  1078.            
  1079.             if ( IsDefined( level.nextRoundIsOvertime ) && level.nextRoundIsOvertime )
  1080.             {
  1081.                 if ( !IsDefined( game["overtime_round"] ) )
  1082.                 {
  1083.                     game["overtime_round"] = 1;
  1084.                 }
  1085.                 else
  1086.                 {
  1087.                     game["overtime_round"]++;
  1088.                 }
  1089.             }
  1090.  
  1091.             SetMatchTalkFlag( "DeadChatWithDead", level.voip.deadChatWithDead );
  1092.             SetMatchTalkFlag( "DeadChatWithTeam", level.voip.deadChatWithTeam );
  1093.             SetMatchTalkFlag( "DeadHearTeamLiving", level.voip.deadHearTeamLiving );
  1094.             SetMatchTalkFlag( "DeadHearAllLiving", level.voip.deadHearAllLiving );
  1095.             SetMatchTalkFlag( "EveryoneHearsEveryone", level.voip.everyoneHearsEveryone );
  1096.             SetMatchTalkFlag( "DeadHearKiller", level.voip.deadHearKiller );
  1097.             SetMatchTalkFlag( "KillersHearVictim", level.voip.killersHearVictim );
  1098.                
  1099.             game["state"] = "playing";
  1100.             level.allowBattleChatter = GetGametypeSetting( "allowBattleChatter" );
  1101.             map_restart( true );
  1102.             return true;
  1103.         }
  1104.     }
  1105.     return false;
  1106. }
  1107.  
  1108.    
  1109. setTopPlayerStats( )
  1110. {
  1111.     if( level.rankedMatch || level.wagerMatch )
  1112.     {
  1113.         placement = level.placement["all"];
  1114.         topThreePlayers = min( 3, placement.size );
  1115.            
  1116.         for ( index = 0; index < topThreePlayers; index++ )
  1117.         {
  1118.             if ( level.placement["all"][index].score )
  1119.             {
  1120.                 if ( !index )
  1121.                 {
  1122.                     level.placement["all"][index] AddPlayerStatWithGameType( "TOPPLAYER", 1 );
  1123.                     level.placement["all"][index] notify( "topplayer" );
  1124.                 }
  1125.                 else
  1126.                     level.placement["all"][index] notify( "nottopplayer" );
  1127.                
  1128.                 level.placement["all"][index] AddPlayerStatWithGameType( "TOP3", 1 );
  1129.                 level.placement["all"][index] notify( "top3" );
  1130.             }
  1131.         }
  1132.        
  1133.         for ( index = 3 ; index < placement.size ; index++ )
  1134.         {
  1135.             level.placement["all"][index] notify( "nottop3" );
  1136.             level.placement["all"][index] notify( "nottopplayer" );
  1137.         }
  1138.  
  1139.         if ( level.teambased )
  1140.         {      
  1141.             foreach ( team in level.teams )
  1142.             {
  1143.                 setTopTeamStats(team);
  1144.             }
  1145.         }
  1146.     }
  1147. }
  1148.  
  1149. setTopTeamStats(team)
  1150. {
  1151.     placementTeam = level.placement[team];
  1152.     topThreeTeamPlayers = min( 3, placementTeam.size );
  1153.     // should have at least 5 players on the team
  1154.     if ( placementTeam.size < 5 )
  1155.         return;
  1156.        
  1157.     for ( index = 0; index < topThreeTeamPlayers; index++ )
  1158.     {
  1159.         if ( placementTeam[index].score )
  1160.         {
  1161.             //placementTeam[index] AddPlayerStat( "BASIC_TOP_3_TEAM", 1 );
  1162.             placementTeam[index] AddPlayerStatWithGameType( "TOP3TEAM", 1 );
  1163.         }
  1164.     }
  1165. }
  1166.  
  1167. getGameLength()
  1168. {
  1169.     if ( !level.timeLimit || level.forcedEnd )
  1170.     {
  1171.         gameLength = maps\mp\gametypes_zm\_globallogic_utils::getTimePassed() / 1000;      
  1172.         // cap it at 20 minutes to avoid exploiting
  1173.         gameLength = min( gameLength, 1200 );
  1174.     }
  1175.     else
  1176.     {
  1177.         gameLength = level.timeLimit * 60;
  1178.     }
  1179.    
  1180.     return gameLength;
  1181. }
  1182.  
  1183. gameHistoryPlayerQuit()
  1184. {
  1185.     if ( !GameModeIsMode( level.GAMEMODE_PUBLIC_MATCH ) )
  1186.         return;
  1187.        
  1188.     teamScoreRatio = 0;
  1189.     self GameHistoryFinishMatch( MATCH_QUIT, 0, 0, 0, 0, teamScoreRatio );
  1190.  
  1191.     if ( IsDefined( self.pers["matchesPlayedStatsTracked"] ) )
  1192.     {
  1193.         gameMode = GetCurrentGameMode();
  1194.         self IncrementMatchCompletionStat( gameMode, "played", "quit" );
  1195.            
  1196.         if ( IsDefined( self.pers["matchesHostedStatsTracked"] ) )
  1197.         {
  1198.             self IncrementMatchCompletionStat( gameMode, "hosted", "quit" );
  1199.             self.pers["matchesHostedStatsTracked"] = undefined;
  1200.         }
  1201.        
  1202.         self.pers["matchesPlayedStatsTracked"] = undefined;
  1203.     }
  1204.    
  1205.     UploadStats( self );
  1206.  
  1207.     // wait until the player recieves the new stats
  1208.   wait(1);
  1209. }
  1210.  
  1211. endGame( winner, endReasonText )
  1212. {
  1213.     // return if already ending via host quit or victory
  1214.     if ( game["state"] == "postgame" || level.gameEnded )
  1215.         return;
  1216.  
  1217.     if ( isDefined( level.onEndGame ) )
  1218.         [[level.onEndGame]]( winner );
  1219.  
  1220.     //This wait was added possibly for wager match issues, but we think is no longer necessary.
  1221.     //It was creating issues with multiple players calling this fuction when checking game score. In modes like HQ,
  1222.     //The game score is given to every player on the team that captured the HQ, so when the points are dished out it loops through
  1223.     //all players on that team and checks if the score limit has been reached. But since this wait occured before the game["state"]
  1224.     //could be set to "postgame" the check score thread would send the next player that reached the score limit into this function,
  1225.     //when the following code should only be hit once. If this wait turns out to be needed, we need to try pulling the game["state"] = "postgame";
  1226.     //up above the wait.
  1227.     //wait 0.05;
  1228.    
  1229.     if ( !level.wagerMatch )
  1230.         setMatchFlag( "enable_popups", 0 );
  1231.     if ( !isdefined( level.disableOutroVisionSet ) || level.disableOutroVisionSet == false )
  1232.     {
  1233.         if ( SessionModeIsZombiesGame() && level.forcedEnd )
  1234.         {
  1235.             visionSetNaked( "zombie_last_stand", 2.0 );
  1236.         }
  1237.         else
  1238.         {
  1239.             visionSetNaked( "mpOutro", 2.0 );
  1240.         }
  1241.     }
  1242.    
  1243.     setmatchflag( "cg_drawSpectatorMessages", 0 );
  1244.     setmatchflag( "game_ended", 1 );
  1245.  
  1246.     game["state"] = "postgame";
  1247.     level.gameEndTime = getTime();
  1248.     level.gameEnded = true;
  1249.     SetDvar( "g_gameEnded", 1 );
  1250.     level.inGracePeriod = false;
  1251.     level notify ( "game_ended" );
  1252.     level.allowBattleChatter = false;
  1253.     maps\mp\gametypes_zm\_globallogic_audio::flushDialog();
  1254.  
  1255.     if ( !IsDefined( game["overtime_round"] ) || wasLastRound() ) // Want to treat all overtime rounds as a single round
  1256.     {
  1257.         game["roundsplayed"]++;
  1258.         game["roundwinner"][game["roundsplayed"]] = winner;
  1259.    
  1260.         //Added "if" check for FFA - Leif
  1261.         if( level.teambased )
  1262.         {
  1263.             game["roundswon"][winner]++;   
  1264.         }
  1265.     }
  1266.  
  1267.     if ( isdefined( winner ) && isdefined( level.teams[winner] ) )
  1268.     {
  1269.         level.finalKillCam_winner = winner;
  1270.     }
  1271.     else
  1272.     {
  1273.         level.finalKillCam_winner = "none";
  1274.     }
  1275.    
  1276.     setGameEndTime( 0 ); // stop/hide the timers
  1277.    
  1278.     updatePlacement();
  1279.  
  1280.     updateRankedMatch( winner );
  1281.    
  1282.     // freeze players
  1283.     players = level.players;
  1284.    
  1285.     newTime = getTime();
  1286.     gameLength = getGameLength();
  1287.    
  1288.     SetMatchTalkFlag( "EveryoneHearsEveryone", 1 );
  1289.  
  1290.     bbGameOver = 0;
  1291.     if ( isOneRound() || wasLastRound() )
  1292.     {
  1293.         bbGameOver = 1;
  1294.  
  1295.         if ( level.teambased )
  1296.         {
  1297.             if ( winner == "tie" )
  1298.             {
  1299.                 recordGameResult( "draw" );
  1300.             }
  1301.             else
  1302.             {
  1303.                 recordGameResult( winner );
  1304.             }
  1305.         }
  1306.         else
  1307.         {
  1308.             if ( !isDefined( winner ) )
  1309.             {
  1310.                 recordGameResult( "draw" );
  1311.             }
  1312.             else
  1313.             {
  1314.                 recordGameResult( winner.team );
  1315.             }
  1316.         }
  1317.     }
  1318.  
  1319.     for ( index = 0; index < players.size; index++ )
  1320.     {
  1321.         player = players[index];
  1322.         player maps\mp\gametypes_zm\_globallogic_player::freezePlayerForRoundEnd();
  1323.         player thread roundEndDoF( 4.0 );
  1324.  
  1325.         player maps\mp\gametypes_zm\_globallogic_ui::freeGameplayHudElems();
  1326.        
  1327.         // Update weapon usage stats
  1328.         player maps\mp\gametypes_zm\_weapons::updateWeaponTimings( newTime );
  1329.        
  1330.         player bbPlayerMatchEnd( gameLength, endReasonText, bbGameOver );
  1331.  
  1332.         if( isPregame() )
  1333.             continue;
  1334.  
  1335.         if( ( level.rankedMatch || level.wagerMatch || level.leagueMatch ) && !player IsSplitscreen() )
  1336.         {
  1337.             if ( isDefined( player.setPromotion ) )
  1338.                 player setDStat( "AfterActionReportStats", "lobbyPopup", "promotion" );
  1339.             else
  1340.                 player setDStat( "AfterActionReportStats", "lobbyPopup", "summary" );
  1341.         }
  1342.     }
  1343.  
  1344.     maps\mp\_music::setmusicstate( "SILENT" );
  1345.  
  1346. // temporarily disabling round end sound call to prevent the final killcam from not having sound
  1347.     if ( !level.inFinalKillcam )
  1348.     {
  1349. //      clientnotify ( "snd_end_rnd" );
  1350.     }
  1351.  
  1352.     //maps\mp\_gamerep::gameRepUpdateInformationForRound();
  1353. //  maps\mp\gametypes_zm\_wager::finalizeWagerRound();
  1354. //  maps\mp\gametypes_zm\_gametype_variants::onRoundEnd();
  1355.     thread maps\mp\_challenges::roundEnd( winner );
  1356.  
  1357.     if ( startNextRound( winner, endReasonText ) )
  1358.     {
  1359.         return;
  1360.     }
  1361.    
  1362.     ///////////////////////////////////////////
  1363.     // After this the match is really ending //
  1364.     ///////////////////////////////////////////
  1365.  
  1366.     if ( !isOneRound() )
  1367.     {
  1368.         if ( isDefined( level.onRoundEndGame ) )
  1369.             winner = [[level.onRoundEndGame]]( winner );
  1370.  
  1371.         endReasonText = getEndReasonText();
  1372.     }
  1373.    
  1374.     skillUpdate( winner, level.teamBased );
  1375.     recordLeagueWinner( winner );
  1376.    
  1377.     setTopPlayerStats();
  1378.     thread maps\mp\_challenges::gameEnd( winner );
  1379.  
  1380.     if ( IsDefined( winner ) && ( !isDefined( level.skipGameEnd ) || !level.skipGameEnd ) )
  1381.         displayGameEnd( winner, endReasonText );
  1382.    
  1383.     if ( isOneRound() )
  1384.     {
  1385.         maps\mp\gametypes_zm\_globallogic_utils::executePostRoundEvents();
  1386.     }
  1387.        
  1388.     level.intermission = true;
  1389.  
  1390.     //maps\mp\_gamerep::gameRepAnalyzeAndReport();
  1391.  
  1392. //  maps\mp\gametypes_zm\_wager::finalizeWagerGame();
  1393.    
  1394.     SetMatchTalkFlag( "EveryoneHearsEveryone", 1 );
  1395.  
  1396.     //regain players array since some might've disconnected during the wait above
  1397.     players = level.players;
  1398.     for ( index = 0; index < players.size; index++ )
  1399.     {
  1400.         player = players[index];
  1401.        
  1402.         recordPlayerStats( player, "presentAtEnd", 1 );
  1403.  
  1404.         player closeMenu();
  1405.         player closeInGameMenu();
  1406.         player notify ( "reset_outcome" );
  1407.         player thread [[level.spawnIntermission]]();
  1408.         player setClientUIVisibilityFlag( "hud_visible", 1 );
  1409.     }
  1410.     //Eckert - Fading out sound
  1411.     level notify ( "sfade");
  1412.     logString( "game ended" );
  1413.    
  1414.     if ( !isDefined( level.skipGameEnd ) || !level.skipGameEnd )
  1415.         wait 5.0;
  1416.    
  1417.     exitLevel( false );
  1418.  
  1419. }
  1420.  
  1421. bbPlayerMatchEnd( gameLength, endReasonString, gameOver ) // self == player
  1422. {        
  1423.     playerRank = getPlacementForPlayer( self );
  1424.    
  1425.     totalTimePlayed = 0;
  1426.     if ( isDefined( self.timePlayed ) && isDefined( self.timePlayed["total"] ) )
  1427.     {
  1428.         totalTimePlayed = self.timePlayed["total"];
  1429.         if ( totalTimePlayed > gameLength )
  1430.         {
  1431.             totalTimePlayed = gameLength;
  1432.         }
  1433.     }
  1434.  
  1435.     xuid = self GetXUID();
  1436.  
  1437.     bbPrint( "mpplayermatchfacts", "score %d momentum %d endreason %s sessionrank %d playtime %d xuid %s gameover %d team %s",
  1438.         self.pers["score"],
  1439.         self.pers["momentum"],
  1440.         endReasonString,
  1441.         playerRank,
  1442.         totalTimePlayed,
  1443.         xuid,
  1444.         gameOver,
  1445.         self.pers["team"] );
  1446. }
  1447.  
  1448. roundEndWait( defaultDelay, matchBonus )
  1449. {
  1450.     notifiesDone = false;
  1451.     while ( !notifiesDone )
  1452.     {
  1453.         players = level.players;
  1454.         notifiesDone = true;
  1455.         for ( index = 0; index < players.size; index++ )
  1456.         {
  1457.             if ( !isDefined( players[index].doingNotify ) || !players[index].doingNotify )
  1458.                 continue;
  1459.                
  1460.             notifiesDone = false;
  1461.         }
  1462.         wait ( 0.5 );
  1463.     }
  1464.  
  1465.     if ( !matchBonus )
  1466.     {
  1467.         wait ( defaultDelay );
  1468.         level notify ( "round_end_done" );
  1469.         return;
  1470.     }
  1471.  
  1472.   wait ( defaultDelay / 2 );
  1473.     level notify ( "give_match_bonus" );
  1474.     wait ( defaultDelay / 2 );
  1475.  
  1476.     notifiesDone = false;
  1477.     while ( !notifiesDone )
  1478.     {
  1479.         players = level.players;
  1480.         notifiesDone = true;
  1481.         for ( index = 0; index < players.size; index++ )
  1482.         {
  1483.             if ( !isDefined( players[index].doingNotify ) || !players[index].doingNotify )
  1484.                 continue;
  1485.                
  1486.             notifiesDone = false;
  1487.         }
  1488.         wait ( 0.5 );
  1489.     }
  1490.    
  1491.     level notify ( "round_end_done" );
  1492. }
  1493.  
  1494.  
  1495. roundEndDOF( time )
  1496. {
  1497.     self setDepthOfField( 0, 128, 512, 4000, 6, 1.8 );
  1498. }
  1499.  
  1500.  
  1501. checkTimeLimit()
  1502. {
  1503.     if ( isDefined( level.timeLimitOverride ) && level.timeLimitOverride )
  1504.         return;
  1505.    
  1506.     if ( game["state"] != "playing" )
  1507.     {
  1508.         setGameEndTime( 0 );
  1509.         return;
  1510.     }
  1511.        
  1512.     if ( level.timeLimit <= 0 )
  1513.     {
  1514.         setGameEndTime( 0 );
  1515.         return;
  1516.     }
  1517.        
  1518.     if ( level.inPrematchPeriod )
  1519.     {
  1520.         setGameEndTime( 0 );
  1521.         return;
  1522.     }
  1523.    
  1524.     if ( level.timerStopped )
  1525.     {
  1526.         setGameEndTime( 0 );
  1527.         return;
  1528.     }
  1529.    
  1530.     if ( !isdefined( level.startTime ) )
  1531.         return;
  1532.    
  1533.     timeLeft = maps\mp\gametypes_zm\_globallogic_utils::getTimeRemaining();
  1534.    
  1535.     // want this accurate to the millisecond
  1536.     setGameEndTime( getTime() + int(timeLeft) );
  1537.    
  1538.     if ( timeLeft > 0 )
  1539.         return;
  1540.    
  1541.     [[level.onTimeLimit]]();
  1542. }
  1543.  
  1544. allTeamsUnderScoreLimit()
  1545. {
  1546.     foreach ( team in level.teams )
  1547.     {
  1548.         if ( game["teamScores"][team] >= level.scoreLimit )
  1549.             return false;
  1550.     }
  1551.    
  1552.     return true;
  1553. }
  1554.  
  1555. checkScoreLimit()
  1556. {
  1557.     if ( game["state"] != "playing" )
  1558.         return false;
  1559.  
  1560.     if ( level.scoreLimit <= 0 )
  1561.         return false;
  1562.  
  1563.     if ( level.teamBased )
  1564.     {
  1565.         if( allTeamsUnderScoreLimit() )
  1566.             return false;
  1567.     }
  1568.     else
  1569.     {
  1570.         if ( !isPlayer( self ) )
  1571.             return false;
  1572.  
  1573.         if ( self.score < level.scoreLimit )
  1574.             return false;
  1575.     }
  1576.  
  1577.     [[level.onScoreLimit]]();
  1578. }
  1579.  
  1580.  
  1581. updateGameTypeDvars()
  1582. {
  1583.     level endon ( "game_ended" );
  1584.    
  1585.     while ( game["state"] == "playing" )
  1586.     {
  1587.         roundlimit = clamp( GetGametypeSetting( "roundLimit" ), level.roundLimitMin, level.roundLimitMax );
  1588.         if ( roundlimit != level.roundlimit )
  1589.         {
  1590.             level.roundlimit = roundlimit;
  1591.             level notify ( "update_roundlimit" );
  1592.         }
  1593.  
  1594.         timeLimit = [[level.getTimeLimit]]();
  1595.         if ( timeLimit != level.timeLimit )
  1596.         {
  1597.             level.timeLimit = timeLimit;
  1598.             SetDvar( "ui_timelimit", level.timeLimit );
  1599.             level notify ( "update_timelimit" );
  1600.         }
  1601.         thread checkTimeLimit();
  1602.  
  1603.         scoreLimit = clamp( GetGametypeSetting( "scoreLimit" ), level.scoreLimitMin, level.scoreLimitMax );
  1604.         if ( scoreLimit != level.scoreLimit )
  1605.         {
  1606.             level.scoreLimit = scoreLimit;
  1607.             SetDvar( "ui_scorelimit", level.scoreLimit );
  1608.             level notify ( "update_scorelimit" );
  1609.         }
  1610.         thread checkScoreLimit();
  1611.        
  1612.         // make sure we check time limit right when game ends
  1613.         if ( isdefined( level.startTime ) )
  1614.         {
  1615.             if ( maps\mp\gametypes_zm\_globallogic_utils::getTimeRemaining() < 3000 )
  1616.             {
  1617.                 wait .1;
  1618.                 continue;
  1619.             }
  1620.         }
  1621.         wait 1;
  1622.     }
  1623. }
  1624.  
  1625.  
  1626. removeDisconnectedPlayerFromPlacement()
  1627. {
  1628.     offset = 0;
  1629.     numPlayers = level.placement["all"].size;
  1630.     found = false;
  1631.     for ( i = 0; i < numPlayers; i++ )
  1632.     {
  1633.         if ( level.placement["all"][i] == self )
  1634.             found = true;
  1635.        
  1636.         if ( found )
  1637.             level.placement["all"][i] = level.placement["all"][ i + 1 ];
  1638.     }
  1639.     if ( !found )
  1640.         return;
  1641.    
  1642.     level.placement["all"][ numPlayers - 1 ] = undefined;
  1643.     assert( level.placement["all"].size == numPlayers - 1 );
  1644.  
  1645.     /#
  1646.     maps\mp\gametypes_zm\_globallogic_utils::assertProperPlacement();
  1647.     #/
  1648.    
  1649.     updateTeamPlacement();
  1650.    
  1651.     if ( level.teamBased )
  1652.         return;
  1653.        
  1654.     numPlayers = level.placement["all"].size;
  1655.     for ( i = 0; i < numPlayers; i++ )
  1656.     {
  1657.         player = level.placement["all"][i];
  1658.         player notify( "update_outcome" );
  1659.     }
  1660.    
  1661. }
  1662.  
  1663. updatePlacement()
  1664. {
  1665.    
  1666.     if ( !level.players.size )
  1667.         return;
  1668.  
  1669.     level.placement["all"] = [];
  1670.     for ( index = 0; index < level.players.size; index++ )
  1671.     {
  1672.         if ( isdefined( level.teams[ level.players[index].team ] ) )
  1673.             level.placement["all"][level.placement["all"].size] = level.players[index];
  1674.     }
  1675.        
  1676.     placementAll = level.placement["all"];
  1677.    
  1678.     for ( i = 1; i < placementAll.size; i++ )
  1679.     {
  1680.         player = placementAll[i];
  1681.         playerScore = player.score;
  1682.         for ( j = i - 1; j >= 0 && (playerScore > placementAll[j].score || (playerScore == placementAll[j].score && player.deaths < placementAll[j].deaths)); j-- )
  1683.             placementAll[j + 1] = placementAll[j];
  1684.         placementAll[j + 1] = player;
  1685.     }
  1686.    
  1687.     level.placement["all"] = placementAll;
  1688.    
  1689.     /#
  1690.     maps\mp\gametypes_zm\_globallogic_utils::assertProperPlacement();
  1691.     #/
  1692.    
  1693.     updateTeamPlacement();
  1694.  
  1695. }  
  1696.  
  1697.  
  1698. updateTeamPlacement()
  1699. {
  1700.     foreach( team in level.teams )
  1701.     {
  1702.         placement[team]    = [];
  1703.     }
  1704.     placement["spectator"] = [];
  1705.    
  1706.     if ( !level.teamBased )
  1707.         return;
  1708.    
  1709.     placementAll = level.placement["all"];
  1710.     placementAllSize = placementAll.size;
  1711.    
  1712.     for ( i = 0; i < placementAllSize; i++ )
  1713.     {
  1714.         player = placementAll[i];
  1715.         team = player.pers["team"];
  1716.        
  1717.         placement[team][ placement[team].size ] = player;
  1718.     }
  1719.    
  1720.     foreach( team in level.teams )
  1721.     {
  1722.         level.placement[team] = placement[team];
  1723.     }
  1724. }
  1725.  
  1726. getPlacementForPlayer( player )
  1727. {
  1728.     updatePlacement();
  1729.  
  1730.     playerRank = -1;
  1731.     placement = level.placement["all"];
  1732.     for ( placementIndex = 0; placementIndex < placement.size; placementIndex++ )
  1733.     {
  1734.         if ( level.placement["all"][placementIndex] == player )
  1735.         {
  1736.             playerRank = (placementIndex + 1);
  1737.             break;
  1738.         }              
  1739.     }
  1740.  
  1741.     return playerRank;
  1742. }
  1743.  
  1744. sortDeadPlayers( team )
  1745. {
  1746.     // only need to sort if we are running queued respawn
  1747.     if ( !level.playerQueuedRespawn )
  1748.         return;
  1749.        
  1750.     // sort by death time
  1751.     for ( i = 1; i < level.deadPlayers[team].size; i++ )
  1752.     {
  1753.         player = level.deadPlayers[team][i];
  1754.         for ( j = i - 1; j >= 0 && player.deathTime < level.deadPlayers[team][j].deathTime; j-- )
  1755.             level.deadPlayers[team][j + 1] = level.deadPlayers[team][j];
  1756.         level.deadPlayers[team][j + 1] = player;
  1757.     }
  1758.    
  1759.     for ( i = 0; i < level.deadPlayers[team].size; i++ )
  1760.     {
  1761.         if ( level.deadPlayers[team][i].spawnQueueIndex != i )
  1762.         {
  1763.             level.spawnQueueModified[team] = true;
  1764.         }
  1765.         level.deadPlayers[team][i].spawnQueueIndex = i;
  1766.     }
  1767. }
  1768.  
  1769. totalAliveCount()
  1770. {
  1771.     count = 0;
  1772.     foreach( team in level.teams )
  1773.     {
  1774.         count += level.aliveCount[team];
  1775.     }
  1776.     return count;
  1777. }
  1778.  
  1779. totalPlayerLives()
  1780. {
  1781.     count = 0;
  1782.     foreach( team in level.teams )
  1783.     {
  1784.         count += level.playerLives[team];
  1785.     }
  1786.     return count;
  1787. }
  1788.  
  1789. totalPlayerCount()
  1790. {
  1791.     count = 0;
  1792.     foreach( team in level.teams )
  1793.     {
  1794.         count += level.playerCount[team];
  1795.     }
  1796.     return count;
  1797. }
  1798.  
  1799. initTeamVariables( team )
  1800. {
  1801.    
  1802.     if ( !isdefined( level.aliveCount ) )
  1803.         level.aliveCount = [];
  1804.    
  1805.     level.aliveCount[team] = 0;
  1806.     level.lastAliveCount[team] = 0;
  1807.    
  1808.     level.everExisted[team] = false;
  1809.     level.waveDelay[team] = 0;
  1810.     level.lastWave[team] = 0;
  1811.     level.wavePlayerSpawnIndex[team] = 0;
  1812.  
  1813.     resetTeamVariables( team );
  1814. }
  1815.  
  1816. resetTeamVariables( team )
  1817. {
  1818.     level.playerCount[team] = 0;
  1819.     level.botsCount[team] = 0;
  1820.     level.lastAliveCount[team] = level.aliveCount[team];
  1821.     level.aliveCount[team] = 0;
  1822.     level.playerLives[team] = 0;
  1823.     level.alivePlayers[team] = [];
  1824.     level.deadPlayers[team] = [];
  1825.     level.squads[team] = [];
  1826.     level.spawnQueueModified[team] = false;
  1827. }
  1828.  
  1829. updateTeamStatus()
  1830. {
  1831.     // run only once per frame, at the end of the frame.
  1832.     level notify("updating_team_status");
  1833.     level endon("updating_team_status");
  1834.     level endon ( "game_ended" );
  1835.     waittillframeend;
  1836.    
  1837.     wait 0; // Required for Callback_PlayerDisconnect to complete before updateTeamStatus can execute
  1838.  
  1839.     if ( game["state"] == "postgame" )
  1840.         return;
  1841.  
  1842.     resetTimeout();
  1843.    
  1844.     foreach( team in level.teams )
  1845.     {
  1846.         resetTeamVariables( team );
  1847.     }
  1848.    
  1849.     level.activePlayers = [];
  1850.  
  1851.     players = level.players;
  1852.     for ( i = 0; i < players.size; i++ )
  1853.     {
  1854.         player = players[i];
  1855.        
  1856.         if ( !isDefined( player ) && level.splitscreen )
  1857.             continue;
  1858.  
  1859.         team = player.team;
  1860.         class = player.class;
  1861.        
  1862.         if ( team != "spectator" && (isDefined( class ) && class != "") )
  1863.         {
  1864.             level.playerCount[team]++;
  1865.            
  1866.             if( isDefined( player.pers["isBot"] ) )
  1867.                 level.botsCount[team]++;
  1868.            
  1869.             if ( player.sessionstate == "playing" )
  1870.             {
  1871.                 level.aliveCount[team]++;
  1872.                 level.playerLives[team]++;
  1873.                 player.spawnQueueIndex = -1;
  1874.                
  1875.                 if ( isAlive( player ) )
  1876.                 {
  1877.                     level.alivePlayers[team][level.alivePlayers[team].size] = player;
  1878.                     level.activeplayers[ level.activeplayers.size ] = player;
  1879.                 }
  1880.                 else
  1881.                 {
  1882.                     level.deadPlayers[team][level.deadPlayers[team].size] = player;
  1883.                 }
  1884.             }
  1885.             else
  1886.             {
  1887.                 level.deadPlayers[team][level.deadPlayers[team].size] = player;
  1888.                 if ( player maps\mp\gametypes_zm\_globallogic_spawn::maySpawn() )
  1889.                     level.playerLives[team]++;
  1890.             }
  1891.         }
  1892.     }
  1893.    
  1894.     totalAlive = totalAliveCount();
  1895.    
  1896.     if ( totalAlive > level.maxPlayerCount )
  1897.         level.maxPlayerCount = totalAlive;
  1898.    
  1899.     foreach( team in level.teams )
  1900.     {
  1901.         if ( level.aliveCount[team] )
  1902.             level.everExisted[team] = true;
  1903.    
  1904.         sortDeadPlayers( team );
  1905.     }
  1906.  
  1907.     level updateGameEvents();
  1908. }
  1909.  
  1910. checkTeamScoreLimitSoon( team )
  1911. {
  1912.     assert( IsDefined( team ) );
  1913.    
  1914.     if ( level.scoreLimit <= 0 )
  1915.         return;
  1916.        
  1917.     if ( !level.teamBased )
  1918.         return;
  1919.        
  1920.     // Give the data a minute to converge/settle
  1921.     if ( maps\mp\gametypes_zm\_globallogic_utils::getTimePassed() < ( 60 * 1000 ) )
  1922.         return;
  1923.    
  1924.     timeLeft = maps\mp\gametypes_zm\_globallogic_utils::getEstimatedTimeUntilScoreLimit( team );
  1925.    
  1926.     if ( timeLeft < 1 )
  1927.     {
  1928.         level notify( "match_ending_soon", "score" );
  1929.     //  maps\mp\_gameadvertisement::teamScoreLimitSoon( true );
  1930.     }
  1931. }
  1932.  
  1933. checkPlayerScoreLimitSoon()
  1934. {
  1935.     assert( IsPlayer( self ) );
  1936.    
  1937.     if ( level.scoreLimit <= 0 )
  1938.         return;
  1939.    
  1940.     if ( level.teamBased )
  1941.         return;
  1942.        
  1943.     // Give the data a minute to converge/settle
  1944.     if ( maps\mp\gametypes_zm\_globallogic_utils::getTimePassed() < ( 60 * 1000 ) )
  1945.         return;
  1946.        
  1947.     timeLeft = maps\mp\gametypes_zm\_globallogic_utils::getEstimatedTimeUntilScoreLimit( undefined );
  1948.    
  1949.     if ( timeLeft < 1 )
  1950.     {
  1951.         level notify( "match_ending_soon", "score" );
  1952.     //  maps\mp\_gameadvertisement::teamScoreLimitSoon( true );
  1953.     }
  1954. }
  1955.  
  1956. timeLimitClock()
  1957. {
  1958.     level endon ( "game_ended" );
  1959.    
  1960.     wait .05;
  1961.    
  1962.     clockObject = spawn( "script_origin", (0,0,0) );
  1963.    
  1964.     while ( game["state"] == "playing" )
  1965.     {
  1966.         if ( !level.timerStopped && level.timeLimit )
  1967.         {
  1968.             timeLeft = maps\mp\gametypes_zm\_globallogic_utils::getTimeRemaining() / 1000;
  1969.             timeLeftInt = int(timeLeft + 0.5); // adding .5 and flooring rounds it.
  1970.            
  1971.             if ( timeLeftInt == 601  )
  1972.                 clientnotify ( "notify_10" );
  1973.            
  1974.             if ( timeLeftInt == 301  )
  1975.                 clientnotify ( "notify_5" );
  1976.                
  1977.             if ( timeLeftInt == 60  )
  1978.                 clientnotify ( "notify_1" );
  1979.                
  1980.             if ( timeLeftInt == 12 )
  1981.                 clientnotify ( "notify_count" );
  1982.            
  1983.             if ( timeLeftInt >= 40 && timeLeftInt <= 60 )
  1984.                 level notify ( "match_ending_soon", "time" );
  1985.  
  1986.             if ( timeLeftInt >= 30 && timeLeftInt <= 40 )
  1987.                 level notify ( "match_ending_pretty_soon", "time" );
  1988.                
  1989.             if( timeLeftInt <= 32 )
  1990.                 level notify ( "match_ending_vox" );   
  1991.  
  1992.             if ( timeLeftInt <= 10 || (timeLeftInt <= 30 && timeLeftInt % 2 == 0) )
  1993.             {
  1994.                 level notify ( "match_ending_very_soon", "time" );
  1995.                 // don't play a tick at exactly 0 seconds, that's when something should be happening!
  1996.                 if ( timeLeftInt == 0 )
  1997.                     break;
  1998.                
  1999.                 clockObject playSound( "mpl_ui_timer_countdown" );
  2000.             }
  2001.            
  2002.             // synchronize to be exactly on the second
  2003.             if ( timeLeft - floor(timeLeft) >= .05 )
  2004.                 wait timeLeft - floor(timeLeft);
  2005.         }
  2006.  
  2007.         wait ( 1.0 );
  2008.     }
  2009. }
  2010.  
  2011. timeLimitClock_Intermission( waitTime )
  2012. {
  2013.     setGameEndTime( getTime() + int(waitTime*1000) );
  2014.     clockObject = spawn( "script_origin", (0,0,0) );
  2015.    
  2016.     if ( waitTime >= 10.0 )
  2017.         wait ( waitTime - 10.0 );
  2018.        
  2019.     for ( ;; )
  2020.     {
  2021.         clockObject playSound( "mpl_ui_timer_countdown" );
  2022.         wait ( 1.0 );
  2023.     }  
  2024. }
  2025.  
  2026.  
  2027. startGame()
  2028. {
  2029.     thread maps\mp\gametypes_zm\_globallogic_utils::gameTimer();
  2030.     level.timerStopped = false;
  2031.     // RF, disabled this, as it is not required anymore.
  2032.     //thread maps\mp\gametypes_zm\_spawnlogic::spawnPerFrameUpdate();
  2033.  
  2034.     SetMatchTalkFlag( "DeadChatWithDead", level.voip.deadChatWithDead );
  2035.     SetMatchTalkFlag( "DeadChatWithTeam", level.voip.deadChatWithTeam );
  2036.     SetMatchTalkFlag( "DeadHearTeamLiving", level.voip.deadHearTeamLiving );
  2037.     SetMatchTalkFlag( "DeadHearAllLiving", level.voip.deadHearAllLiving );
  2038.     SetMatchTalkFlag( "EveryoneHearsEveryone", level.voip.everyoneHearsEveryone );
  2039.     SetMatchTalkFlag( "DeadHearKiller", level.voip.deadHearKiller );
  2040.     SetMatchTalkFlag( "KillersHearVictim", level.voip.killersHearVictim );
  2041.    
  2042.     prematchPeriod();
  2043.     level notify("prematch_over");
  2044.    
  2045.     thread timeLimitClock();
  2046.     thread gracePeriod();
  2047.     thread watchMatchEndingSoon();
  2048.  
  2049.     thread maps\mp\gametypes_zm\_globallogic_audio::musicController();
  2050.  
  2051. //  thread maps\mp\gametypes_zm\_gametype_variants::onRoundBegin();
  2052.    
  2053.     recordMatchBegin();
  2054. }
  2055.  
  2056.  
  2057. waitForPlayers()
  2058. {
  2059.     /*
  2060.     if ( level.teamBased )
  2061.         while( !level.everExisted[ "axis" ] || !level.everExisted[ "allies" ] )
  2062.             wait ( 0.05 );
  2063.     else
  2064.         while ( level.maxPlayerCount < 2 )
  2065.             wait ( 0.05 );
  2066.     */
  2067. }  
  2068.  
  2069. prematchPeriod()
  2070. {
  2071.     setMatchFlag( "hud_hardcore", level.hardcoreMode );
  2072.  
  2073.     level endon( "game_ended" );
  2074.    
  2075.     if ( level.prematchPeriod > 0 )
  2076.     {
  2077.         thread matchStartTimer();
  2078.  
  2079.         waitForPlayers();
  2080.  
  2081.         wait ( level.prematchPeriod );
  2082.     }
  2083.     else
  2084.     {
  2085.         matchStartTimerSkip();
  2086.        
  2087.         wait 0.05;
  2088.     }
  2089.    
  2090.     level.inPrematchPeriod = false;
  2091.    
  2092.     for ( index = 0; index < level.players.size; index++ )
  2093.     {      
  2094.         level.players[index] freeze_player_controls( false );
  2095.         level.players[index] enableWeapons();
  2096.     }
  2097.    
  2098. //  maps\mp\gametypes_zm\_wager::prematchPeriod();
  2099.  
  2100.     if ( game["state"] != "playing" )
  2101.         return;
  2102. }
  2103.    
  2104. gracePeriod()
  2105. {
  2106.     level endon("game_ended");
  2107.    
  2108.     if ( IsDefined( level.gracePeriodFunc ) )
  2109.     {
  2110.         [[ level.gracePeriodFunc ]]();
  2111.     }
  2112.     else
  2113.     {
  2114.         wait ( level.gracePeriod );
  2115.     }
  2116.    
  2117.     level notify ( "grace_period_ending" );
  2118.     wait ( 0.05 );
  2119.    
  2120.     level.inGracePeriod = false;
  2121.    
  2122.     if ( game["state"] != "playing" )
  2123.         return;
  2124.    
  2125.     if ( level.numLives )
  2126.     {
  2127.         // Players on a team but without a weapon show as dead since they can not get in this round
  2128.         players = level.players;
  2129.        
  2130.         for ( i = 0; i < players.size; i++ )
  2131.         {
  2132.             player = players[i];
  2133.            
  2134.             if ( !player.hasSpawned && player.sessionteam != "spectator" && !isAlive( player ) )
  2135.                 player.statusicon = "hud_status_dead";
  2136.         }
  2137.     }
  2138.    
  2139.     level thread updateTeamStatus();
  2140. }
  2141.  
  2142. watchMatchEndingSoon()
  2143. {
  2144.     SetDvar( "xblive_matchEndingSoon", 0 );
  2145.     level waittill( "match_ending_soon", reason );
  2146.     SetDvar( "xblive_matchEndingSoon", 1 );
  2147. }
  2148.  
  2149. assertTeamVariables( )
  2150. {
  2151.     // these are defined in the teamset file
  2152.     if ( !level.createFX_enabled && !SessionModeIsZombiesGame() )
  2153.     {
  2154.         foreach ( team in level.teams )
  2155.         {
  2156.             Assert( IsDefined( game["strings"][ team + "_win"] ) );
  2157.             Assert( IsDefined( game["strings"][ team + "_win_round"] ) );
  2158.             Assert( IsDefined( game["strings"][ team + "_mission_accomplished"] ) );
  2159.             Assert( IsDefined( game["strings"][ team + "_eliminated"] ) );
  2160.             Assert( IsDefined( game["strings"][ team + "_forfeited"] ) );
  2161.             Assert( IsDefined( game["strings"][ team + "_name"] ) );
  2162.             Assert( IsDefined( game["music"]["spawn_" + team] ) );
  2163.             Assert( IsDefined( game["music"]["victory_" + team] ) );
  2164.             Assert( IsDefined( game["icons"][team] ) );
  2165.             Assert( IsDefined( game["voice"][team] ) );
  2166.         }
  2167.     }
  2168. }
  2169.  
  2170. anyTeamHasWaveDelay()
  2171. {
  2172.     foreach ( team in level.teams )
  2173.     {
  2174.         if ( level.waveDelay[team] )
  2175.             return true;
  2176.     }
  2177.    
  2178.     return false;
  2179. }
  2180.  
  2181. Callback_StartGameType()
  2182. {
  2183.     level.prematchPeriod = 0;
  2184.     level.intermission = false;
  2185.  
  2186.     setmatchflag( "cg_drawSpectatorMessages", 1 );
  2187.     setmatchflag( "game_ended", 0 );
  2188.    
  2189.     if ( !isDefined( game["gamestarted"] ) )
  2190.     {
  2191.         // defaults if not defined in level script
  2192.         if ( !isDefined( game["allies"] ) )
  2193.             game["allies"] = "seals";
  2194.         if ( !isDefined( game["axis"] ) )
  2195.             game["axis"] = "pmc";
  2196.         if ( !isDefined( game["attackers"] ) )
  2197.             game["attackers"] = "allies";
  2198.         if (  !isDefined( game["defenders"] ) )
  2199.             game["defenders"] = "axis";
  2200.  
  2201.         // if this hits the teams are not setup right
  2202.         assert( game["attackers"] != game["defenders"] );
  2203.        
  2204.         // TODO MTEAM - need to update this valid team
  2205.         foreach( team in level.teams )
  2206.         {
  2207.             if ( !isDefined( game[team] ) )
  2208.                 game[team] = "pmc";
  2209.         }
  2210.  
  2211.         if ( !isDefined( game["state"] ) )
  2212.             game["state"] = "playing";
  2213.    
  2214.         precacheRumble( "damage_heavy" );
  2215.         precacheRumble( "damage_light" );
  2216.  
  2217.         precacheShader( "white" );
  2218.         precacheShader( "black" );
  2219.        
  2220.         makeDvarServerInfo( "scr_allies", "marines" );
  2221.         makeDvarServerInfo( "scr_axis", "nva" );
  2222.        
  2223.         makeDvarServerInfo( "cg_thirdPersonAngle", 354 );
  2224.  
  2225.         SetDvar( "cg_thirdPersonAngle", 354 );
  2226.  
  2227.         game["strings"]["press_to_spawn"] = &"PLATFORM_PRESS_TO_SPAWN";
  2228.         if ( level.teamBased )
  2229.         {
  2230.             game["strings"]["waiting_for_teams"] = &"MP_WAITING_FOR_TEAMS";
  2231.             game["strings"]["opponent_forfeiting_in"] = &"MP_OPPONENT_FORFEITING_IN";
  2232.         }
  2233.         else
  2234.         {
  2235.             game["strings"]["waiting_for_teams"] = &"MP_WAITING_FOR_PLAYERS";
  2236.             game["strings"]["opponent_forfeiting_in"] = &"MP_OPPONENT_FORFEITING_IN";
  2237.         }
  2238.         game["strings"]["match_starting_in"] = &"MP_MATCH_STARTING_IN";
  2239.         game["strings"]["spawn_next_round"] = &"MP_SPAWN_NEXT_ROUND";
  2240.         game["strings"]["waiting_to_spawn"] = &"MP_WAITING_TO_SPAWN";
  2241.         game["strings"]["waiting_to_spawn_ss"] = &"MP_WAITING_TO_SPAWN_SS";
  2242.         //game["strings"]["waiting_to_safespawn"] = &"MP_WAITING_TO_SAFESPAWN";
  2243.         game["strings"]["you_will_spawn"] = &"MP_YOU_WILL_RESPAWN";
  2244.         game["strings"]["match_starting"] = &"MP_MATCH_STARTING";
  2245.         game["strings"]["change_class"] = &"MP_CHANGE_CLASS_NEXT_SPAWN";
  2246.         game["strings"]["last_stand"] = &"MPUI_LAST_STAND";
  2247.        
  2248.         game["strings"]["cowards_way"] = &"PLATFORM_COWARDS_WAY_OUT";
  2249.        
  2250.         game["strings"]["tie"] = &"MP_MATCH_TIE";
  2251.         game["strings"]["round_draw"] = &"MP_ROUND_DRAW";
  2252.  
  2253.         game["strings"]["enemies_eliminated"] = &"MP_ENEMIES_ELIMINATED";
  2254.         game["strings"]["score_limit_reached"] = &"MP_SCORE_LIMIT_REACHED";
  2255.         game["strings"]["round_limit_reached"] = &"MP_ROUND_LIMIT_REACHED";
  2256.         game["strings"]["time_limit_reached"] = &"MP_TIME_LIMIT_REACHED";
  2257.         game["strings"]["players_forfeited"] = &"MP_PLAYERS_FORFEITED";
  2258.  
  2259.         assertTeamVariables();
  2260.  
  2261.         [[level.onPrecacheGameType]]();
  2262.  
  2263.         game["gamestarted"] = true;
  2264.        
  2265.         game["totalKills"] = 0;
  2266.  
  2267.         foreach( team in level.teams )
  2268.         {
  2269.             game["teamScores"][team] = 0;
  2270.             game["totalKillsTeam"][team] = 0;
  2271.         }
  2272.  
  2273.         if ( !level.splitscreen && !isPreGame() )
  2274.             level.prematchPeriod = GetGametypeSetting( "prematchperiod" );
  2275.  
  2276.         if ( GetDvarint( "xblive_clanmatch" ) != 0 )
  2277.         {
  2278.             // TODO MTEAM is this code used anymore?
  2279.             foreach( team in level.teams )
  2280.             {
  2281.                 game["icons"][team] = "composite_emblem_team_axis";
  2282.             }
  2283.            
  2284.             game["icons"]["allies"] = "composite_emblem_team_allies";
  2285.             game["icons"]["axis"] = "composite_emblem_team_axis";
  2286.         }
  2287.     }
  2288.  
  2289.     if(!isdefined(game["timepassed"]))
  2290.         game["timepassed"] = 0;
  2291.  
  2292.     if(!isdefined(game["roundsplayed"]))
  2293.         game["roundsplayed"] = 0;
  2294.     SetRoundsPlayed( game["roundsplayed"] );
  2295.    
  2296.     if(!isdefined(game["roundwinner"] ))
  2297.         game["roundwinner"] = [];
  2298.  
  2299.     if(!isdefined(game["roundswon"] ))
  2300.         game["roundswon"] = [];
  2301.  
  2302.     if(!isdefined(game["roundswon"]["tie"] ))
  2303.         game["roundswon"]["tie"] = 0;
  2304.  
  2305.     foreach ( team in level.teams )
  2306.     {
  2307.         if(!isdefined(game["roundswon"][team] ))
  2308.             game["roundswon"][team] = 0;
  2309.  
  2310.         level.teamSpawnPoints[team] = [];
  2311.         level.spawn_point_team_class_names[team] = [];
  2312.     }
  2313.  
  2314.     level.skipVote = false;
  2315.     level.gameEnded = false;
  2316.     SetDvar( "g_gameEnded", 0 );
  2317.  
  2318.     level.objIDStart = 0;
  2319.     level.forcedEnd = false;
  2320.     level.hostForcedEnd = false;
  2321.  
  2322.     level.hardcoreMode = GetGametypeSetting( "hardcoreMode" );
  2323.     if ( level.hardcoreMode )
  2324.     {
  2325.         logString( "game mode: hardcore" );
  2326.        
  2327.         //set up friendly fire delay for hardcore
  2328.         if( !isDefined(level.friendlyFireDelayTime) )
  2329.             level.friendlyFireDelayTime = 0;
  2330.     }
  2331.  
  2332.     if ( GetDvar( "scr_max_rank" ) == "" )
  2333.             SetDvar( "scr_max_rank", "0" );
  2334.     level.rankCap = GetDvarint( "scr_max_rank" );
  2335.    
  2336.     if ( GetDvar( "scr_min_prestige" ) == "" )
  2337.     {
  2338.         SetDvar( "scr_min_prestige", "0" );
  2339.     }
  2340.     level.minPrestige = GetDvarint( "scr_min_prestige" );
  2341.  
  2342.     // this gets set to false when someone takes damage or a gametype-specific event happens.
  2343.     level.useStartSpawns = true;
  2344.  
  2345.     level.roundScoreCarry = GetGametypeSetting( "roundscorecarry" );
  2346.  
  2347.     level.allowHitMarkers = GetGametypeSetting( "allowhitmarkers" );
  2348.     level.playerQueuedRespawn = GetGametypeSetting( "playerQueuedRespawn" );
  2349.     level.playerForceRespawn = GetGametypeSetting( "playerForceRespawn" );
  2350.  
  2351.     level.perksEnabled = GetGametypeSetting( "perksEnabled" );
  2352.     level.disableAttachments = GetGametypeSetting( "disableAttachments" );
  2353.     level.disableTacInsert = GetGametypeSetting( "disableTacInsert" );
  2354.     level.disableCAC = GetGametypeSetting( "disableCAC" );
  2355.     level.disableWeaponDrop = GetGametypeSetting( "disableweapondrop" );
  2356.     level.onlyHeadShots = GetGametypeSetting( "onlyHeadshots" );
  2357.    
  2358.     // set to 0 to disable
  2359.     level.minimumAllowedTeamKills = GetGametypeSetting( "teamKillPunishCount" ) - 1; // punishment starts at the next one
  2360.     level.teamKillReducedPenalty = GetGametypeSetting( "teamKillReducedPenalty" );
  2361.     level.teamKillPointLoss = GetGametypeSetting( "teamKillPointLoss" );
  2362.     level.teamKillSpawnDelay = GetGametypeSetting( "teamKillSpawnDelay" );
  2363.    
  2364.     level.deathPointLoss = GetGametypeSetting( "deathPointLoss" );
  2365.     level.leaderBonus = GetGametypeSetting( "leaderBonus" );
  2366.     level.forceRadar = GetGametypeSetting( "forceRadar" );
  2367.     level.playerSprintTime = GetGametypeSetting( "playerSprintTime" );
  2368.     level.bulletDamageScalar = GetGametypeSetting( "bulletDamageScalar" );
  2369.    
  2370.     level.playerMaxHealth = GetGametypeSetting( "playerMaxHealth" );
  2371.     level.playerHealthRegenTime = GetGametypeSetting( "playerHealthRegenTime" );
  2372.    
  2373.     level.playerRespawnDelay = GetGametypeSetting( "playerRespawnDelay" );
  2374.     level.playerObjectiveHeldRespawnDelay = GetGametypeSetting( "playerObjectiveHeldRespawnDelay" );
  2375.     level.waveRespawnDelay = GetGametypeSetting( "waveRespawnDelay" );
  2376.    
  2377.     level.spectateType = GetGametypeSetting( "spectateType" );
  2378.    
  2379.     level.voip = SpawnStruct();
  2380.     level.voip.deadChatWithDead = GetGametypeSetting( "voipDeadChatWithDead" );
  2381.     level.voip.deadChatWithTeam = GetGametypeSetting( "voipDeadChatWithTeam" );
  2382.     level.voip.deadHearAllLiving = GetGametypeSetting( "voipDeadHearAllLiving" );
  2383.     level.voip.deadHearTeamLiving = GetGametypeSetting( "voipDeadHearTeamLiving" );
  2384.     level.voip.everyoneHearsEveryone = GetGametypeSetting( "voipEveryoneHearsEveryone" );
  2385.     level.voip.deadHearKiller = GetGametypeSetting( "voipDeadHearKiller" );
  2386.     level.voip.killersHearVictim = GetGametypeSetting( "voipKillersHearVictim" );
  2387.  
  2388.     if( GetDvar( "r_reflectionProbeGenerate" ) == "1" )
  2389.         level waittill( "eternity" );
  2390.        
  2391.     if( SessionModeIsZombiesGame() )
  2392.     {
  2393.         level.prematchPeriod = 0;
  2394.  
  2395.  
  2396.         //thread maps\mp\gametypes_zm\_persistence::init();
  2397.         level.persistentDataInfo = [];
  2398.         level.maxRecentStats = 10;
  2399.         level.maxHitLocations = 19;
  2400.         level.globalShotsFired = 0;
  2401.     //  thread maps\mp\gametypes_zm\_class::init();
  2402.  
  2403.  
  2404.     //  thread maps\mp\gametypes_zm\_menus::init();
  2405.         thread maps\mp\gametypes_zm\_hud::init();
  2406.         thread maps\mp\gametypes_zm\_serversettings::init();
  2407.         thread maps\mp\gametypes_zm\_clientids::init();
  2408.     //  thread maps\mp\teams\_teams::init();
  2409.         thread maps\mp\gametypes_zm\_weaponobjects::init();
  2410.         thread maps\mp\gametypes_zm\_scoreboard::init();
  2411.     //  thread maps\mp\gametypes_zm\_killcam::init();
  2412.         thread maps\mp\gametypes_zm\_shellshock::init();
  2413.     //  thread maps\mp\gametypes_zm\_deathicons::init();
  2414.     //  thread maps\mp\gametypes_zm\_damagefeedback::init();
  2415.         thread maps\mp\gametypes_zm\_spectating::init();
  2416.     //  thread maps\mp\gametypes_zm\_objpoints::init();
  2417.         thread maps\mp\gametypes_zm\_gameobjects::init();
  2418.         thread maps\mp\gametypes_zm\_spawnlogic::init();
  2419.     //  thread maps\mp\gametypes_zm\_battlechatter_mp::init();
  2420.     // FIX ME       thread maps\mp\killstreaks\_killstreaks::init();
  2421.         thread maps\mp\gametypes_zm\_globallogic_audio::init();
  2422.         //thread maps\mp\gametypes_zm\_wager::init();
  2423.     //  thread maps\mp\gametypes_zm\_gametype_variants::init();
  2424.         //thread maps\mp\bots\_bot::init();
  2425.         //thread maps\mp\_decoy::init();
  2426.     }
  2427.  
  2428. //  if ( level.teamBased )
  2429. //      thread maps\mp\gametypes_zm\_friendicons::init();
  2430.        
  2431.     thread maps\mp\gametypes_zm\_hud_message::init();
  2432.     //thread maps\mp\_multi_extracam::init();
  2433.  
  2434.     stringNames = getArrayKeys( game["strings"] );
  2435.     for ( index = 0; index < stringNames.size; index++ )
  2436.         precacheString( game["strings"][stringNames[index]] );
  2437.  
  2438.     foreach( team in level.teams )
  2439.     {
  2440.         initTeamVariables( team );
  2441.     }
  2442.    
  2443.     level.maxPlayerCount = 0;
  2444.     level.activePlayers = [];
  2445.  
  2446.     level.allowAnnouncer = GetGametypeSetting( "allowAnnouncer" );
  2447.  
  2448.     if ( !isDefined( level.timeLimit ) )
  2449.         registerTimeLimit( 1, 1440 );
  2450.        
  2451.     if ( !isDefined( level.scoreLimit ) )
  2452.         registerScoreLimit( 1, 500 );
  2453.  
  2454.     if ( !isDefined( level.roundLimit ) )
  2455.         registerRoundLimit( 0, 10 );
  2456.  
  2457.     if ( !isDefined( level.roundWinLimit ) )
  2458.         registerRoundWinLimit( 0, 10 );
  2459.    
  2460.     // The order the following functions are registered in are the order they will get called
  2461. //  maps\mp\gametypes_zm\_globallogic_utils::registerPostRoundEvent( maps\mp\gametypes_zm\_killcam::postRoundFinalKillcam );   
  2462. //  maps\mp\gametypes_zm\_globallogic_utils::registerPostRoundEvent( maps\mp\gametypes_zm\_wager::postRoundSideBet );
  2463.  
  2464.     makeDvarServerInfo( "ui_scorelimit" );
  2465.     makeDvarServerInfo( "ui_timelimit" );
  2466.     makeDvarServerInfo( "ui_allow_classchange", GetDvar( "ui_allow_classchange" ) );
  2467.  
  2468.     waveDelay = level.waveRespawnDelay;
  2469.     if ( waveDelay && !isPreGame() )
  2470.     {
  2471.         foreach ( team in level.teams )
  2472.         {
  2473.             level.waveDelay[team] = waveDelay;
  2474.             level.lastWave[team] = 0;
  2475.         }
  2476.        
  2477.         level thread [[level.waveSpawnTimer]]();
  2478.     }
  2479.    
  2480.     level.inPrematchPeriod = true;
  2481.    
  2482.     if ( level.prematchPeriod > 2.0 )
  2483.         level.prematchPeriod = level.prematchPeriod + (randomFloat( 4 ) - 2); // live host obfuscation
  2484.  
  2485.     if ( level.numLives || anyTeamHasWaveDelay() || level.playerQueuedRespawn )
  2486.         level.gracePeriod = 15;
  2487.     else
  2488.         level.gracePeriod = 5;
  2489.        
  2490.     level.inGracePeriod = true;
  2491.    
  2492.     level.roundEndDelay = 5;
  2493.     level.halftimeRoundEndDelay = 3;
  2494.    
  2495.     maps\mp\gametypes_zm\_globallogic_score::updateAllTeamScores();
  2496.    
  2497.     level.killstreaksenabled = 1;
  2498.    
  2499.     if ( GetDvar( "scr_game_rankenabled" ) == "" )
  2500.         SetDvar( "scr_game_rankenabled", true );
  2501.     level.rankEnabled = GetDvarint( "scr_game_rankenabled" );
  2502.    
  2503.     if ( GetDvar( "scr_game_medalsenabled" ) == "" )
  2504.         SetDvar( "scr_game_medalsenabled", true );
  2505.     level.medalsEnabled = GetDvarint( "scr_game_medalsenabled" );
  2506.  
  2507.     if( level.hardcoreMode && level.rankedMatch && GetDvar( "scr_game_friendlyFireDelay" ) == "" )
  2508.         SetDvar( "scr_game_friendlyFireDelay", true );
  2509.     level.friendlyFireDelay = GetDvarint( "scr_game_friendlyFireDelay" );
  2510.  
  2511.     // level gametype and features globals should be defaulted before this, and level.onstartgametype should reset them if desired
  2512.     if(GetDvar("createfx") == "")
  2513.     {
  2514.         [[level.onStartGameType]]();
  2515.     }
  2516.  
  2517.     // disable killstreaks for custom game modes
  2518.     if( GetDvarInt( "custom_killstreak_mode" ) == 1 )
  2519.     {
  2520.         level.killstreaksenabled = 0;
  2521.     }
  2522.    
  2523.     // this must be after onstartgametype for scr_showspawns to work when set at start of game
  2524. //  /#
  2525. //  thread maps\mp\gametypes_zm\_dev::init();
  2526. //  #/
  2527.  
  2528. /#
  2529.     PrintLn( "Globallogic Callback_StartGametype() isPregame() = " + isPregame() + "\n" );
  2530. #/
  2531.  
  2532.     //level thread maps\mp\gametypes_zm\_killcam::doFinalKillcam();
  2533.  
  2534.     thread startGame();
  2535.     level thread updateGameTypeDvars();
  2536.    
  2537. /#
  2538.     if( GetDvarint( "scr_writeconfigstrings" ) == 1 )
  2539.     {
  2540.         level.skipGameEnd = true;
  2541.         level.roundLimit = 1;
  2542.        
  2543.         // let things settle
  2544.         wait(1);
  2545. //      level.forcedEnd = true;
  2546.         thread forceEnd( false );
  2547. //      thread endgame( "tie","" );
  2548.     }
  2549.     if( GetDvarint( "scr_hostmigrationtest" ) == 1 )
  2550.     {
  2551.         thread ForceDebugHostMigration();
  2552.     }
  2553. #/
  2554. }
  2555.  
  2556. /#
  2557. ForceDebugHostMigration()
  2558. {
  2559.     while (1)
  2560.     {
  2561.         maps\mp\gametypes_zm\_hostmigration::waitTillHostMigrationDone();
  2562.         wait(60);
  2563.         starthostmigration();
  2564.         maps\mp\gametypes_zm\_hostmigration::waitTillHostMigrationDone();
  2565.         //thread forceEnd( false );
  2566.     }
  2567. }
  2568. #/
  2569.  
  2570. registerFriendlyFireDelay( dvarString, defaultValue, minValue, maxValue )
  2571. {
  2572.     dvarString = ("scr_" + dvarString + "_friendlyFireDelayTime");
  2573.     if ( getDvar( dvarString ) == "" )
  2574.         setDvar( dvarString, defaultValue );
  2575.        
  2576.     if ( getDvarInt( dvarString ) > maxValue )
  2577.         setDvar( dvarString, maxValue );
  2578.     else if ( getDvarInt( dvarString ) < minValue )
  2579.         setDvar( dvarString, minValue );
  2580.  
  2581.     level.friendlyFireDelayTime = getDvarInt( dvarString );
  2582. }
  2583.  
  2584. checkRoundSwitch()
  2585. {
  2586.     if ( !isdefined( level.roundSwitch ) || !level.roundSwitch )
  2587.         return false;
  2588.     if ( !isdefined( level.onRoundSwitch ) )
  2589.         return false;
  2590.    
  2591.     assert( game["roundsplayed"] > 0 );
  2592.    
  2593.     if ( game["roundsplayed"] % level.roundswitch == 0 )
  2594.     {
  2595.         [[level.onRoundSwitch]]();
  2596.         return true;
  2597.     }
  2598.        
  2599.     return false;
  2600. }
  2601.  
  2602.  
  2603. listenForGameEnd()
  2604. {
  2605.     self waittill( "host_sucks_end_game" );
  2606.     //if ( level.console )
  2607.     //  endparty();
  2608.     level.skipVote = true;
  2609.  
  2610.     if ( !level.gameEnded )
  2611.         level thread maps\mp\gametypes_zm\_globallogic::forceEnd(true);
  2612. }
  2613.  
  2614.  
  2615. getKillStreaks( player )
  2616. {
  2617.     for ( killstreakNum = 0; killstreakNum < level.maxKillstreaks; killstreakNum++ )
  2618.     {
  2619.         killstreak[ killstreakNum ] = "killstreak_null";
  2620.     }
  2621.    
  2622.     if ( isPlayer( player ) && !level.oldschool && ( level.disableCAC != 1 ) &&
  2623.     ( !isdefined( player.pers["isBot"] ) && isdefined(player.killstreak) ) )
  2624.     {
  2625.         currentKillstreak = 0;
  2626.         for ( killstreakNum = 0; killstreakNum < level.maxKillstreaks; killstreakNum++ )
  2627.         {
  2628.                 if ( isDefined( player.killstreak[ killstreakNum ] ) )
  2629.                 {
  2630.                     killstreak[ currentKillstreak ] = player.killstreak[ killstreakNum ];
  2631.                     currentKillstreak++;
  2632.                 }
  2633.         }
  2634.     }
  2635.    
  2636.     return killstreak;
  2637. }
  2638.  
  2639. updateRankedMatch(winner)
  2640. {
  2641.     if ( level.rankedMatch )
  2642.     {
  2643.         if ( hostIdledOut() )
  2644.         {
  2645.             level.hostForcedEnd = true;
  2646.             logString( "host idled out" );
  2647.             endLobby();
  2648.         }
  2649.     }
  2650.     if ( !level.wagerMatch && !SessionModeIsZombiesGame() )
  2651.     {
  2652.         maps\mp\gametypes_zm\_globallogic_score::updateMatchBonusScores( winner );
  2653.         maps\mp\gametypes_zm\_globallogic_score::updateWinLossStats( winner );
  2654.     }
  2655. }
Advertisement
Add Comment
Please, Sign In to add comment