Advertisement
Guest User

Untitled

a guest
Sep 29th, 2010
463
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 56.50 KB | None | 0 0
  1. #include maps\mp\_utility;
  2. #include maps\mp\gametypes\_hud_util;
  3. #include common_scripts\utility;
  4.  
  5. FACTION_REF_COL = 0;
  6. FACTION_NAME_COL = 1;
  7. FACTION_SHORT_NAME_COL = 1;
  8. FACTION_WIN_GAME_COL = 3;
  9. FACTION_WIN_ROUND_COL = 4;
  10. FACTION_MISSION_ACCOMPLISHED_COL = 5;
  11. FACTION_ELIMINATED_COL = 6;
  12. FACTION_FORFEITED_COL = 7;
  13. FACTION_ICON_COL = 8;
  14. FACTION_HUD_ICON_COL = 9;
  15. FACTION_VOICE_PREFIX_COL = 10;
  16. FACTION_SPAWN_MUSIC_COL = 11;
  17. FACTION_WIN_MUSIC_COL = 12;
  18. FACTION_COLOR_R_COL = 13;
  19. FACTION_COLOR_G_COL = 14;
  20. FACTION_COLOR_B_COL = 15;
  21.  
  22. // when a team leaves completely, that team forfeited, team left wins round, ends game
  23. onForfeit( team )
  24. {
  25. if ( isDefined( level.forfeitInProgress ) )
  26. return;
  27.  
  28. level endon( "abort_forfeit" ); //end if the team is no longer in forfeit status
  29.  
  30. level.forfeitInProgress = true;
  31.  
  32. // in 1v1 DM, give players time to change teams
  33. if ( !level.teambased && level.players.size > 1 )
  34. wait 10;
  35.  
  36. forfeit_delay = 20.0; //forfeit wait, for switching teams and such
  37.  
  38. foreach ( player in level.players )
  39. {
  40. player setLowerMessage( "forfeit_warning", game["strings"]["opponent_forfeiting_in"], forfeit_delay, 100 );
  41. player thread forfeitWaitforAbort();
  42. }
  43.  
  44. wait ( forfeit_delay );
  45.  
  46. endReason = &"";
  47. if ( !isDefined( team ) )
  48. {
  49. endReason = game["strings"]["players_forfeited"];
  50. winner = level.players[0];
  51. }
  52. else if ( team == "allies" )
  53. {
  54. endReason = game["strings"]["allies_forfeited"];
  55. winner = "axis";
  56. }
  57. else if ( team == "axis" )
  58. {
  59. endReason = game["strings"]["axis_forfeited"];
  60. winner = "allies";
  61. }
  62. else
  63. {
  64. //shouldn't get here
  65. assertEx( isdefined( team ), "Forfeited team is not defined" );
  66. assertEx( 0, "Forfeited team " + team + " is not allies or axis" );
  67. winner = "tie";
  68. }
  69. //exit game, last round, no matter if round limit reached or not
  70. level.forcedEnd = true;
  71.  
  72. if ( isPlayer( winner ) )
  73. logString( "forfeit, win: " + winner getXuid() + "(" + winner.name + ")" );
  74. else
  75. logString( "forfeit, win: " + winner + ", allies: " + game["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
  76. thread endGame( winner, endReason );
  77. }
  78.  
  79.  
  80. forfeitWaitforAbort()
  81. {
  82. self endon ( "disconnect" );
  83. level endon ( "game_ended" );
  84.  
  85. level waittill ( "abort_forfeit" );
  86.  
  87. self clearLowerMessage( "forfeit_warning" );
  88. }
  89.  
  90.  
  91. default_onDeadEvent( team )
  92. {
  93. if ( team == "allies" )
  94. {
  95. iPrintLn( game["strings"]["allies_eliminated"] );
  96.  
  97. logString( "team eliminated, win: opfor, allies: " + game["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
  98.  
  99. thread endGame( "axis", game["strings"]["allies_eliminated"] );
  100. }
  101. else if ( team == "axis" )
  102. {
  103. iPrintLn( game["strings"]["axis_eliminated"] );
  104.  
  105. logString( "team eliminated, win: allies, allies: " + game["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
  106.  
  107. thread endGame( "allies", game["strings"]["axis_eliminated"] );
  108. }
  109. else
  110. {
  111. logString( "tie, allies: " + game["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
  112.  
  113. if ( level.teamBased )
  114. thread endGame( "tie", game["strings"]["tie"] );
  115. else
  116. thread endGame( undefined, game["strings"]["tie"] );
  117. }
  118. }
  119.  
  120.  
  121. default_onOneLeftEvent( team )
  122. {
  123. if ( level.teamBased )
  124. {
  125. assert( team == "allies" || team == "axis" );
  126.  
  127. lastPlayer = getLastLivingPlayer( team );
  128. lastPlayer thread giveLastOnTeamWarning();
  129. }
  130. else
  131. {
  132. lastPlayer = getLastLivingPlayer();
  133.  
  134. logString( "last one alive, win: " + lastPlayer.name );
  135. thread endGame( lastPlayer, &"MP_ENEMIES_ELIMINATED" );
  136. }
  137.  
  138. return true;
  139. }
  140.  
  141.  
  142. default_onTimeLimit()
  143. {
  144. winner = undefined;
  145.  
  146. if ( level.teamBased )
  147. {
  148. if ( game["teamScores"]["allies"] == game["teamScores"]["axis"] )
  149. winner = "tie";
  150. else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
  151. winner = "axis";
  152. else
  153. winner = "allies";
  154.  
  155. logString( "time limit, win: " + winner + ", allies: " + game["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
  156. }
  157. else
  158. {
  159. winner = maps\mp\gametypes\_gamescore::getHighestScoringPlayer();
  160.  
  161. if ( isDefined( winner ) )
  162. logString( "time limit, win: " + winner.name );
  163. else
  164. logString( "time limit, tie" );
  165. }
  166.  
  167. thread endGame( winner, game["strings"]["time_limit_reached"] );
  168. }
  169.  
  170.  
  171. default_onHalfTime()
  172. {
  173. winner = undefined;
  174.  
  175. thread endGame( "halftime", game["strings"]["time_limit_reached"] );
  176. }
  177.  
  178.  
  179. forceEnd()
  180. {
  181. if ( level.hostForcedEnd || level.forcedEnd )
  182. return;
  183.  
  184. winner = undefined;
  185.  
  186. if ( level.teamBased )
  187. {
  188. if ( game["teamScores"]["allies"] == game["teamScores"]["axis"] )
  189. winner = "tie";
  190. else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
  191. winner = "axis";
  192. else
  193. winner = "allies";
  194. logString( "host ended game, win: " + winner + ", allies: " + game["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
  195. }
  196. else
  197. {
  198. winner = maps\mp\gametypes\_gamescore::getHighestScoringPlayer();
  199. if ( isDefined( winner ) )
  200. logString( "host ended game, win: " + winner.name );
  201. else
  202. logString( "host ended game, tie" );
  203. }
  204.  
  205. level.forcedEnd = true;
  206. level.hostForcedEnd = true;
  207.  
  208. if ( level.splitscreen )
  209. endString = &"MP_ENDED_GAME";
  210. else
  211. endString = &"MP_HOST_ENDED_GAME";
  212.  
  213. thread endGame( winner, endString );
  214. }
  215.  
  216.  
  217. onScoreLimit()
  218. {
  219. scoreText = game["strings"]["score_limit_reached"];
  220. winner = undefined;
  221.  
  222. if ( level.teamBased )
  223. {
  224. if ( game["teamScores"]["allies"] == game["teamScores"]["axis"] )
  225. winner = "tie";
  226. else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
  227. winner = "axis";
  228. else
  229. winner = "allies";
  230. logString( "scorelimit, win: " + winner + ", allies: " + game["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] );
  231. }
  232. else
  233. {
  234. winner = maps\mp\gametypes\_gamescore::getHighestScoringPlayer();
  235. if ( isDefined( winner ) )
  236. logString( "scorelimit, win: " + winner.name );
  237. else
  238. logString( "scorelimit, tie" );
  239. }
  240.  
  241. thread endGame( winner, scoreText );
  242. return true;
  243. }
  244.  
  245.  
  246. updateGameEvents()
  247. {
  248. if ( matchMakingGame() && !level.inGracePeriod )
  249. {
  250. if ( level.teamBased )
  251. {
  252. // if allies disconnected, and axis still connected, axis wins round and game ends to lobby
  253. if ( level.teamCount["allies"] < 1 && level.teamCount["axis"] > 0 && game["state"] == "playing" )
  254. {
  255. //allies forfeited
  256. thread onForfeit( "allies" );
  257. return;
  258. }
  259.  
  260. // if axis disconnected, and allies still connected, allies wins round and game ends to lobby
  261. if ( level.teamCount["axis"] < 1 && level.teamCount["allies"] > 0 && game["state"] == "playing" )
  262. {
  263. //axis forfeited
  264. thread onForfeit( "axis" );
  265. return;
  266. }
  267.  
  268. if ( level.teamCount["axis"] > 0 && level.teamCount["allies"] > 0 )
  269. {
  270. level.forfeitInProgress = undefined;
  271. level notify( "abort_forfeit" );
  272. }
  273. }
  274. else
  275. {
  276. if ( level.teamCount["allies"] + level.teamCount["axis"] == 1 && level.maxPlayerCount > 1 )
  277. {
  278. thread onForfeit();
  279. return;
  280. }
  281.  
  282. if ( level.teamCount["axis"] + level.teamCount["allies"] > 1 )
  283. {
  284. level.forfeitInProgress = undefined;
  285. level notify( "abort_forfeit" );
  286. }
  287. }
  288. }
  289.  
  290. if ( !getGametypeNumLives() && (!isDefined( level.disableSpawning ) || !level.disableSpawning) )
  291. return;
  292.  
  293. if ( !gameHasStarted() )
  294. return;
  295.  
  296. if ( level.inGracePeriod )
  297. return;
  298.  
  299. if ( level.teamBased )
  300. {
  301. livesCount["allies"] = level.livesCount["allies"];
  302. livesCount["axis"] = level.livesCount["axis"];
  303.  
  304. if ( isDefined( level.disableSpawning ) && level.disableSpawning )
  305. {
  306. livesCount["allies"] = 0;
  307. livesCount["axis"] = 0;
  308. }
  309.  
  310. // if both allies and axis were alive and now they are both dead in the same instance
  311. if ( !level.aliveCount["allies"] && !level.aliveCount["axis"] && !livesCount["allies"] && !livesCount["axis"] )
  312. {
  313. return [[level.onDeadEvent]]( "all" );
  314. }
  315.  
  316. // if allies were alive and now they are not
  317. if ( !level.aliveCount["allies"] && !livesCount["allies"] )
  318. {
  319. return [[level.onDeadEvent]]( "allies" );
  320. }
  321.  
  322. // if axis were alive and now they are not
  323. if ( !level.aliveCount["axis"] && !livesCount["axis"] )
  324. {
  325. return [[level.onDeadEvent]]( "axis" );
  326. }
  327.  
  328. // one ally left
  329. if ( level.aliveCount["allies"] == 1 && !livesCount["allies"] )
  330. {
  331. if ( !isDefined( level.oneLeftTime["allies"] ) )
  332. {
  333. level.oneLeftTime["allies"] = getTime();
  334. return [[level.onOneLeftEvent]]( "allies" );
  335. }
  336. }
  337.  
  338. // one axis left
  339. if ( level.aliveCount["axis"] == 1 && !livesCount["axis"] )
  340. {
  341. if ( !isDefined( level.oneLeftTime["axis"] ) )
  342. {
  343. level.oneLeftTime["axis"] = getTime();
  344. return [[level.onOneLeftEvent]]( "axis" );
  345. }
  346. }
  347. }
  348. else
  349. {
  350. // everyone is dead
  351. if ( (!level.aliveCount["allies"] && !level.aliveCount["axis"]) && (!level.livesCount["allies"] && !level.livesCount["axis"]) )
  352. {
  353. return [[level.onDeadEvent]]( "all" );
  354. }
  355.  
  356. livePlayers = getPotentialLivingPlayers();
  357.  
  358. if ( livePlayers.size == 1 )
  359. {
  360. return [[level.onOneLeftEvent]]( "all" );
  361. }
  362. }
  363. }
  364.  
  365.  
  366. waittillFinalKillcamDone()
  367. {
  368. if ( !level.showingFinalKillcam )
  369. return false;
  370.  
  371. while ( level.showingFinalKillcam )
  372. wait ( 0.05 );
  373.  
  374. return true;
  375. }
  376.  
  377.  
  378. timeLimitClock_Intermission( waitTime )
  379. {
  380. setGameEndTime( getTime() + int(waitTime*1000) );
  381. clockObject = spawn( "script_origin", (0,0,0) );
  382. clockObject hide();
  383.  
  384. if ( waitTime >= 10.0 )
  385. wait ( waitTime - 10.0 );
  386.  
  387. for ( ;; )
  388. {
  389. clockObject playSound( "ui_mp_timer_countdown" );
  390. wait ( 1.0 );
  391. }
  392. }
  393.  
  394.  
  395. waitForPlayers( maxTime )
  396. {
  397. endTime = gettime() + maxTime * 1000 - 200;
  398.  
  399. if ( level.teamBased )
  400. while( (!level.hasSpawned[ "axis" ] || !level.hasSpawned[ "allies" ]) && gettime() < endTime )
  401. wait ( 0.05 );
  402. else
  403. while ( level.maxPlayerCount < 2 && gettime() < endTime )
  404. wait ( 0.05 );
  405. }
  406.  
  407.  
  408. prematchPeriod()
  409. {
  410. level endon( "game_ended" );
  411.  
  412. if ( level.prematchPeriod > 0 )
  413. {
  414. if ( level.console )
  415. {
  416. thread matchStartTimer( "match_starting_in", level.prematchPeriod );
  417. wait ( level.prematchPeriod );
  418. }
  419. else
  420. {
  421. matchStartTimerPC();
  422. }
  423. }
  424. else
  425. {
  426. matchStartTimerSkip();
  427. }
  428.  
  429. for ( index = 0; index < level.players.size; index++ )
  430. {
  431. level.players[index] freezeControlsWrapper( false );
  432. level.players[index] enableWeapons();
  433.  
  434. hintMessage = getObjectiveHintText( level.players[index].pers["team"] );
  435. if ( !isDefined( hintMessage ) || !level.players[index].hasSpawned )
  436. continue;
  437.  
  438. level.players[index] setClientDvar( "scr_objectiveText", hintMessage );
  439. level.players[index] thread maps\mp\gametypes\_hud_message::hintMessage( hintMessage );
  440. }
  441.  
  442. if ( game["state"] != "playing" )
  443. return;
  444. }
  445.  
  446.  
  447. gracePeriod()
  448. {
  449. level endon("game_ended");
  450.  
  451. while ( level.inGracePeriod )
  452. {
  453. wait ( 1.0 );
  454. level.inGracePeriod--;
  455. }
  456.  
  457. //wait ( level.gracePeriod );
  458.  
  459. level notify ( "grace_period_ending" );
  460. wait ( 0.05 );
  461.  
  462. gameFlagSet( "graceperiod_done" );
  463. level.inGracePeriod = false;
  464.  
  465. if ( game["state"] != "playing" )
  466. return;
  467.  
  468. if ( getGametypeNumLives() )
  469. {
  470. // Players on a team but without a weapon show as dead since they can not get in this round
  471. players = level.players;
  472.  
  473. for ( i = 0; i < players.size; i++ )
  474. {
  475. player = players[i];
  476.  
  477. if ( !player.hasSpawned && player.sessionteam != "spectator" && !isAlive( player ) )
  478. player.statusicon = "hud_status_dead";
  479. }
  480. }
  481.  
  482. level thread updateGameEvents();
  483. }
  484.  
  485.  
  486. updateWinStats( winner )
  487. {
  488. if ( !winner rankingEnabled() )
  489. return;
  490.  
  491. winner maps\mp\gametypes\_persistence::statAdd( "losses", -1 );
  492.  
  493. println( "setting winner: " + winner maps\mp\gametypes\_persistence::statGet( "wins" ) );
  494. winner maps\mp\gametypes\_persistence::statAdd( "wins", 1 );
  495. winner updatePersRatio( "winLossRatio", "wins", "losses" );
  496. winner maps\mp\gametypes\_persistence::statAdd( "currentWinStreak", 1 );
  497.  
  498. cur_win_streak = winner maps\mp\gametypes\_persistence::statGet( "currentWinStreak" );
  499. if ( cur_win_streak > winner maps\mp\gametypes\_persistence::statGet( "winStreak" ) )
  500. winner maps\mp\gametypes\_persistence::statSet( "winStreak", cur_win_streak );
  501.  
  502. winner maps\mp\gametypes\_persistence::statSetChild( "round", "win", true );
  503. winner maps\mp\gametypes\_persistence::statSetChild( "round", "loss", false );
  504. }
  505.  
  506.  
  507. updateLossStats( loser )
  508. {
  509. if ( !loser rankingEnabled() )
  510. return;
  511.  
  512. loser maps\mp\gametypes\_persistence::statAdd( "losses", 1 );
  513. loser updatePersRatio( "winLossRatio", "wins", "losses" );
  514. loser maps\mp\gametypes\_persistence::statSetChild( "round", "loss", true );
  515. }
  516.  
  517.  
  518. updateTieStats( loser )
  519. {
  520. if ( !loser rankingEnabled() )
  521. return;
  522.  
  523. loser maps\mp\gametypes\_persistence::statAdd( "losses", -1 );
  524.  
  525. loser maps\mp\gametypes\_persistence::statAdd( "ties", 1 );
  526. loser updatePersRatio( "winLossRatio", "wins", "losses" );
  527. loser maps\mp\gametypes\_persistence::statSet( "currentWinStreak", 0 );
  528. }
  529.  
  530.  
  531. updateWinLossStats( winner )
  532. {
  533. if ( privateMatch() )
  534. return;
  535.  
  536. if ( !wasLastRound() )
  537. return;
  538.  
  539. players = level.players;
  540.  
  541. if ( !isDefined( winner ) || ( isDefined( winner ) && isString( winner ) && winner == "tie" ) )
  542. {
  543. foreach ( player in level.players )
  544. {
  545. if ( isDefined( player.connectedPostGame ) )
  546. continue;
  547.  
  548. if ( level.hostForcedEnd && player isHost() )
  549. {
  550. player maps\mp\gametypes\_persistence::statSet( "currentWinStreak", 0 );
  551. continue;
  552. }
  553.  
  554. updateTieStats( player );
  555. }
  556. }
  557. else if ( isPlayer( winner ) )
  558. {
  559. if ( level.hostForcedEnd && winner isHost() )
  560. {
  561. winner maps\mp\gametypes\_persistence::statSet( "currentWinStreak", 0 );
  562. return;
  563. }
  564.  
  565. updateWinStats( winner );
  566. }
  567. else if ( isString( winner ) )
  568. {
  569. foreach ( player in level.players )
  570. {
  571. if ( isDefined( player.connectedPostGame ) )
  572. continue;
  573.  
  574. if ( level.hostForcedEnd && player isHost() )
  575. {
  576. player maps\mp\gametypes\_persistence::statSet( "currentWinStreak", 0 );
  577. continue;
  578. }
  579.  
  580. if ( winner == "tie" )
  581. updateTieStats( player );
  582. else if ( player.pers["team"] == winner )
  583. updateWinStats( player );
  584. else
  585. player maps\mp\gametypes\_persistence::statSet( "currentWinStreak", 0 );
  586. }
  587. }
  588. }
  589.  
  590.  
  591. freezePlayerForRoundEnd( delay )
  592. {
  593. self endon ( "disconnect" );
  594. self clearLowerMessages();
  595.  
  596. if ( !isDefined( delay ) )
  597. delay = 0.05;
  598.  
  599. self closepopupMenu();
  600. self closeInGameMenu();
  601.  
  602. wait ( delay );
  603. self freezeControlsWrapper( true );
  604. // self disableWeapons();
  605. }
  606.  
  607.  
  608. updateMatchBonusScores( winner )
  609. {
  610. if ( !game["timePassed"] )
  611. return;
  612.  
  613. if ( !matchMakingGame() )
  614. return;
  615.  
  616. if ( !getTimeLimit() || level.forcedEnd )
  617. {
  618. gameLength = getTimePassed() / 1000;
  619. // cap it at 20 minutes to avoid exploiting
  620. gameLength = min( gameLength, 1200 );
  621. }
  622. else
  623. {
  624. gameLength = getTimeLimit() * 60;
  625. }
  626.  
  627. if ( level.teamBased )
  628. {
  629. if ( winner == "allies" )
  630. {
  631. winningTeam = "allies";
  632. losingTeam = "axis";
  633. }
  634. else if ( winner == "axis" )
  635. {
  636. winningTeam = "axis";
  637. losingTeam = "allies";
  638. }
  639. else
  640. {
  641. winningTeam = "tie";
  642. losingTeam = "tie";
  643. }
  644.  
  645. if ( winningTeam != "tie" )
  646. {
  647. winnerScale = maps\mp\gametypes\_rank::getScoreInfoValue( "win" );
  648. loserScale = maps\mp\gametypes\_rank::getScoreInfoValue( "loss" );
  649. setWinningTeam( winningTeam );
  650. }
  651. else
  652. {
  653. winnerScale = maps\mp\gametypes\_rank::getScoreInfoValue( "tie" );
  654. loserScale = maps\mp\gametypes\_rank::getScoreInfoValue( "tie" );
  655. }
  656.  
  657. foreach ( player in level.players )
  658. {
  659. if ( isDefined( player.connectedPostGame ) )
  660. continue;
  661.  
  662. if ( !player rankingEnabled() )
  663. continue;
  664.  
  665. if ( player.timePlayed["total"] < 1 || player.pers["participation"] < 1 )
  666. {
  667. player thread maps\mp\gametypes\_rank::endGameUpdate();
  668. continue;
  669. }
  670.  
  671. // no bonus for hosts who force ends
  672. if ( level.hostForcedEnd && player isHost() )
  673. continue;
  674.  
  675. spm = player maps\mp\gametypes\_rank::getSPM();
  676. if ( winningTeam == "tie" )
  677. {
  678. playerScore = int( (winnerScale * ((gameLength/60) * spm)) * (player.timePlayed["total"] / gameLength) );
  679. player thread giveMatchBonus( "tie", playerScore );
  680. player.matchBonus = playerScore;
  681. }
  682. else if ( isDefined( player.pers["team"] ) && player.pers["team"] == winningTeam )
  683. {
  684. playerScore = int( (winnerScale * ((gameLength/60) * spm)) * (player.timePlayed["total"] / gameLength) );
  685. player thread giveMatchBonus( "win", playerScore );
  686. player.matchBonus = playerScore;
  687. }
  688. else if ( isDefined(player.pers["team"] ) && player.pers["team"] == losingTeam )
  689. {
  690. playerScore = int( (loserScale * ((gameLength/60) * spm)) * (player.timePlayed["total"] / gameLength) );
  691. player thread giveMatchBonus( "loss", playerScore );
  692. player.matchBonus = playerScore;
  693. }
  694. }
  695. }
  696. else
  697. {
  698. if ( isDefined( winner ) )
  699. {
  700. winnerScale = maps\mp\gametypes\_rank::getScoreInfoValue( "win" );
  701. loserScale = maps\mp\gametypes\_rank::getScoreInfoValue( "loss" );
  702. }
  703. else
  704. {
  705. winnerScale = maps\mp\gametypes\_rank::getScoreInfoValue( "tie" );
  706. loserScale = maps\mp\gametypes\_rank::getScoreInfoValue( "tie" );
  707. }
  708.  
  709. foreach ( player in level.players )
  710. {
  711. if ( isDefined( player.connectedPostGame ) )
  712. continue;
  713.  
  714. if ( player.timePlayed["total"] < 1 || player.pers["participation"] < 1 )
  715. {
  716. player thread maps\mp\gametypes\_rank::endGameUpdate();
  717. continue;
  718. }
  719.  
  720. spm = player maps\mp\gametypes\_rank::getSPM();
  721.  
  722. isWinner = false;
  723. for ( pIdx = 0; pIdx < min( level.placement["all"].size, 3 ); pIdx++ )
  724. {
  725. if ( level.placement["all"][pIdx] != player )
  726. continue;
  727. isWinner = true;
  728. }
  729.  
  730. if ( isWinner )
  731. {
  732. playerScore = int( (winnerScale * ((gameLength/60) * spm)) * (player.timePlayed["total"] / gameLength) );
  733. player thread giveMatchBonus( "win", playerScore );
  734. player.matchBonus = playerScore;
  735. }
  736. else
  737. {
  738. playerScore = int( (loserScale * ((gameLength/60) * spm)) * (player.timePlayed["total"] / gameLength) );
  739. player thread giveMatchBonus( "loss", playerScore );
  740. player.matchBonus = playerScore;
  741. }
  742. }
  743. }
  744. }
  745.  
  746.  
  747. giveMatchBonus( scoreType, score )
  748. {
  749. self endon ( "disconnect" );
  750.  
  751. level waittill ( "give_match_bonus" );
  752.  
  753. self maps\mp\gametypes\_rank::giveRankXP( scoreType, score );
  754. //logXPGains();
  755.  
  756. self maps\mp\gametypes\_rank::endGameUpdate();
  757. }
  758.  
  759.  
  760. setXenonRanks( winner )
  761. {
  762. players = level.players;
  763.  
  764. for ( i = 0; i < players.size; i++ )
  765. {
  766. player = players[i];
  767.  
  768. if( !isdefined(player.score) || !isdefined(player.pers["team"]) )
  769. continue;
  770.  
  771. }
  772.  
  773. for ( i = 0; i < players.size; i++ )
  774. {
  775. player = players[i];
  776.  
  777. if( !isdefined(player.score) || !isdefined(player.pers["team"]) )
  778. continue;
  779.  
  780. setPlayerTeamRank( player, player.clientid, player.score - 5 * player.deaths );
  781. }
  782. sendranks();
  783. }
  784.  
  785.  
  786. checkTimeLimit( prevTimePassed )
  787. {
  788. if ( isDefined( level.timeLimitOverride ) && level.timeLimitOverride )
  789. return;
  790.  
  791. if ( game["state"] != "playing" )
  792. {
  793. setGameEndTime( 0 );
  794. return;
  795. }
  796.  
  797. if ( getTimeLimit() <= 0 )
  798. {
  799. if ( isDefined( level.startTime ) )
  800. setGameEndTime( level.startTime );
  801. else
  802. setGameEndTime( 0 );
  803. return;
  804. }
  805.  
  806. if ( !gameFlag( "prematch_done" ) )
  807. {
  808. setGameEndTime( 0 );
  809. return;
  810. }
  811.  
  812. if ( !isdefined( level.startTime ) )
  813. return;
  814.  
  815. timeLeft = getTimeRemaining();
  816.  
  817. // want this accurate to the millisecond
  818. // if ( getHalfTime() && game["status"] != "halftime" )
  819. // setGameEndTime( getTime() + (int(timeLeft) - int(getTimeLimit()*60*1000*0.5)) );
  820. // else
  821. setGameEndTime( getTime() + int(timeLeft) );
  822.  
  823. if ( timeLeft > 0 )
  824. {
  825. if ( getHalfTime() && checkHalfTime( prevTimePassed ) )
  826. [[level.onHalfTime]]();
  827.  
  828. return;
  829. }
  830.  
  831. [[level.onTimeLimit]]();
  832. }
  833.  
  834.  
  835. checkHalfTime( prevTimePassed )
  836. {
  837. if ( !level.teamBased )
  838. return false;
  839.  
  840. if ( getTimeLimit() )
  841. {
  842. halfTime = (getTimeLimit() * 60 * 1000) * 0.5;
  843.  
  844. if ( getTimePassed() >= halfTime && prevTimePassed < halfTime && prevTimePassed > 0 )
  845. {
  846. game["roundMillisecondsAlreadyPassed"] = getTimePassed();
  847. return true;
  848. }
  849. }
  850.  
  851. return false;
  852. }
  853.  
  854.  
  855.  
  856. getTimeRemaining()
  857. {
  858. return getTimeLimit() * 60 * 1000 - getTimePassed();
  859. }
  860.  
  861.  
  862. checkTeamScoreLimitSoon( team )
  863. {
  864. assert( isDefined( team ) );
  865.  
  866. if ( getWatchedDvar( "scorelimit" ) <= 0 || isObjectiveBased() )
  867. return;
  868.  
  869. if ( isDefined( level.scoreLimitOverride ) && level.scoreLimitOverride )
  870. return;
  871.  
  872. if ( !level.teamBased )
  873. return;
  874.  
  875. // No checks until a minute has passed to let wild data settle
  876. if ( getTimePassed() < (60 * 1000) ) // 1 min
  877. return;
  878.  
  879. timeLeft = estimatedTimeTillScoreLimit( team );
  880.  
  881. if ( timeLeft < 2 )
  882. level notify( "match_ending_soon", "score" );
  883. }
  884.  
  885.  
  886. checkPlayerScoreLimitSoon()
  887. {
  888. if ( getWatchedDvar( "scorelimit" ) <= 0 || isObjectiveBased() )
  889. return;
  890.  
  891. if ( level.teamBased )
  892. return;
  893.  
  894. // No checks until a minute has passed to let wild data settle
  895. if ( getTimePassed() < (60 * 1000) ) // 1 min
  896. return;
  897.  
  898. timeLeft = self estimatedTimeTillScoreLimit();
  899.  
  900. if ( timeLeft < 2 )
  901. level notify( "match_ending_soon", "score" );
  902. }
  903.  
  904.  
  905. checkScoreLimit()
  906. {
  907. if ( isObjectiveBased() )
  908. return false;
  909.  
  910. if ( isDefined( level.scoreLimitOverride ) && level.scoreLimitOverride )
  911. return false;
  912.  
  913. if ( game["state"] != "playing" )
  914. return false;
  915.  
  916. if ( getWatchedDvar( "scorelimit" ) <= 0 )
  917. return false;
  918.  
  919. if ( level.teamBased )
  920. {
  921. if( game["teamScores"]["allies"] < getWatchedDvar( "scorelimit" ) && game["teamScores"]["axis"] < getWatchedDvar( "scorelimit" ) )
  922. return false;
  923. }
  924. else
  925. {
  926. if ( !isPlayer( self ) )
  927. return false;
  928.  
  929. if ( self.score < getWatchedDvar( "scorelimit" ) )
  930. return false;
  931. }
  932.  
  933. return onScoreLimit();
  934. }
  935.  
  936.  
  937. updateGameTypeDvars()
  938. {
  939. level endon ( "game_ended" );
  940.  
  941. while ( game["state"] == "playing" )
  942. {
  943. // make sure we check time limit right when game ends
  944. if ( isdefined( level.startTime ) )
  945. {
  946. if ( getTimeRemaining() < 3000 )
  947. {
  948. wait .1;
  949. continue;
  950. }
  951. }
  952. wait 1;
  953. }
  954. }
  955.  
  956.  
  957. matchStartTimerPC()
  958. {
  959. thread matchStartTimer( "waiting_for_teams", level.prematchPeriod + level.prematchPeriodEnd );
  960.  
  961. waitForPlayers( level.prematchPeriod );
  962.  
  963. if ( level.prematchPeriodEnd > 0 )
  964. matchStartTimer( "match_starting_in", level.prematchPeriodEnd );
  965. }
  966.  
  967. matchStartTimer_Internal( countTime, matchStartTimer )
  968. {
  969. waittillframeend; // wait till cleanup of previous start timer if multiple happen at once
  970. visionSetNaked( "mpIntro", 0 );
  971.  
  972. level endon( "match_start_timer_beginning" );
  973. while ( countTime > 0 && !level.gameEnded )
  974. {
  975. matchStartTimer thread maps\mp\gametypes\_hud::fontPulse( level );
  976. wait ( matchStartTimer.inFrames * 0.05 );
  977. matchStartTimer setValue( countTime );
  978. if ( countTime == 2 )
  979. visionSetNaked( getDvar( "mapname" ), 3.0 );
  980. countTime--;
  981. wait ( 1 - (matchStartTimer.inFrames * 0.05) );
  982. }
  983. }
  984.  
  985. matchStartTimer( type, duration )
  986. {
  987. level notify( "match_start_timer_beginning" );
  988.  
  989. matchStartText = createServerFontString( "objective", 1.5 );
  990. matchStartText setPoint( "CENTER", "CENTER", 0, -40 );
  991. matchStartText.sort = 1001;
  992. matchStartText setText( game["strings"]["waiting_for_teams"] );
  993. matchStartText.foreground = false;
  994. matchStartText.hidewheninmenu = true;
  995.  
  996. matchStartText setText( game["strings"][type] ); // "match begins in:"
  997.  
  998. matchStartTimer = createServerFontString( "hudbig", 1 );
  999. matchStartTimer setPoint( "CENTER", "CENTER", 0, 0 );
  1000. matchStartTimer.sort = 1001;
  1001. matchStartTimer.color = (1,1,0);
  1002. matchStartTimer.foreground = false;
  1003. matchStartTimer.hidewheninmenu = true;
  1004.  
  1005. matchStartTimer maps\mp\gametypes\_hud::fontPulseInit();
  1006.  
  1007. countTime = int( duration );
  1008.  
  1009. if ( countTime >= 2 )
  1010. {
  1011. matchStartTimer_Internal( countTime, matchStartTimer );
  1012. visionSetNaked( getDvar( "mapname" ), 3.0 );
  1013. }
  1014. else
  1015. {
  1016. visionSetNaked( "mpIntro", 0 );
  1017. visionSetNaked( getDvar( "mapname" ), 1.0 );
  1018. }
  1019.  
  1020. matchStartTimer destroyElem();
  1021. matchStartText destroyElem();
  1022. }
  1023.  
  1024. matchStartTimerSkip()
  1025. {
  1026. visionSetNaked( getDvar( "mapname" ), 0 );
  1027. }
  1028.  
  1029.  
  1030. onRoundSwitch()
  1031. {
  1032. if ( !isDefined( game["switchedsides"] ) )
  1033. game["switchedsides"] = false;
  1034.  
  1035. // overtime
  1036. if ( game["roundsWon"]["allies"] == getWatchedDvar( "winlimit" ) - 1 && game["roundsWon"]["axis"] == getWatchedDvar( "winlimit" ) - 1 )
  1037. {
  1038. aheadTeam = getBetterTeam();
  1039. if ( aheadTeam != game["defenders"] )
  1040. {
  1041. game["switchedsides"] = !game["switchedsides"];
  1042. }
  1043. else
  1044. {
  1045. level.halftimeSubCaption = "";
  1046. }
  1047. level.halftimeType = "overtime";
  1048. }
  1049. else
  1050. {
  1051. level.halftimeType = "halftime";
  1052. game["switchedsides"] = !game["switchedsides"];
  1053. }
  1054. }
  1055.  
  1056.  
  1057. checkRoundSwitch()
  1058. {
  1059. if ( !level.teamBased )
  1060. return false;
  1061.  
  1062. if ( !isDefined( level.roundSwitch ) || !level.roundSwitch )
  1063. return false;
  1064.  
  1065. assert( game["roundsPlayed"] > 0 );
  1066. if ( game["roundsPlayed"] % level.roundSwitch == 0 )
  1067. {
  1068. onRoundSwitch();
  1069. return true;
  1070. }
  1071.  
  1072. return false;
  1073. }
  1074.  
  1075.  
  1076. // returns the best guess of the exact time until the scoreboard will be displayed and player control will be lost.
  1077. // returns undefined if time is not known
  1078. timeUntilRoundEnd()
  1079. {
  1080. if ( level.gameEnded )
  1081. {
  1082. timePassed = (getTime() - level.gameEndTime) / 1000;
  1083. timeRemaining = level.postRoundTime - timePassed;
  1084.  
  1085. if ( timeRemaining < 0 )
  1086. return 0;
  1087.  
  1088. return timeRemaining;
  1089. }
  1090.  
  1091. if ( getTimeLimit() <= 0 )
  1092. return undefined;
  1093.  
  1094. if ( !isDefined( level.startTime ) )
  1095. return undefined;
  1096.  
  1097. tl = getTimeLimit();
  1098.  
  1099. timePassed = (getTime() - level.startTime)/1000;
  1100. timeRemaining = (getTimeLimit() * 60) - timePassed;
  1101.  
  1102. if ( isDefined( level.timePaused ) )
  1103. timeRemaining += level.timePaused;
  1104.  
  1105. return timeRemaining + level.postRoundTime;
  1106. }
  1107.  
  1108.  
  1109.  
  1110. freeGameplayHudElems()
  1111. {
  1112. // free up some hud elems so we have enough for other things.
  1113.  
  1114. // perk icons
  1115. if ( isdefined( self.perkicon ) )
  1116. {
  1117. if ( isdefined( self.perkicon[0] ) )
  1118. {
  1119. self.perkicon[0] destroyElem();
  1120. self.perkname[0] destroyElem();
  1121. }
  1122. if ( isdefined( self.perkicon[1] ) )
  1123. {
  1124. self.perkicon[1] destroyElem();
  1125. self.perkname[1] destroyElem();
  1126. }
  1127. if ( isdefined( self.perkicon[2] ) )
  1128. {
  1129. self.perkicon[2] destroyElem();
  1130. self.perkname[2] destroyElem();
  1131. }
  1132. }
  1133. self notify("perks_hidden"); // stop any threads that are waiting to hide the perk icons
  1134.  
  1135. // lower message
  1136. self.lowerMessage destroyElem();
  1137. self.lowerTimer destroyElem();
  1138.  
  1139. // progress bar
  1140. if ( isDefined( self.proxBar ) )
  1141. self.proxBar destroyElem();
  1142. if ( isDefined( self.proxBarText ) )
  1143. self.proxBarText destroyElem();
  1144. }
  1145.  
  1146.  
  1147. getHostPlayer()
  1148. {
  1149. players = getEntArray( "player", "classname" );
  1150.  
  1151. for ( index = 0; index < players.size; index++ )
  1152. {
  1153. if ( players[index] isHost() )
  1154. return players[index];
  1155. }
  1156. }
  1157.  
  1158.  
  1159. hostIdledOut()
  1160. {
  1161. hostPlayer = getHostPlayer();
  1162.  
  1163. // host never spawned
  1164. if ( isDefined( hostPlayer ) && !hostPlayer.hasSpawned && !isDefined( hostPlayer.selectedClass ) )
  1165. return true;
  1166.  
  1167. return false;
  1168. }
  1169.  
  1170.  
  1171.  
  1172. roundEndWait( defaultDelay, matchBonus )
  1173. {
  1174. //setSlowMotion( 1.0, 0.15, defaultDelay / 2 );
  1175.  
  1176. notifiesDone = false;
  1177. while ( !notifiesDone )
  1178. {
  1179. players = level.players;
  1180. notifiesDone = true;
  1181.  
  1182. foreach ( player in players )
  1183. {
  1184. if ( !isDefined( player.doingSplash ) )
  1185. continue;
  1186.  
  1187. if ( !player maps\mp\gametypes\_hud_message::isDoingSplash() )
  1188. continue;
  1189.  
  1190. notifiesDone = false;
  1191. }
  1192. wait ( 0.5 );
  1193. }
  1194.  
  1195. if ( !matchBonus )
  1196. {
  1197. wait ( defaultDelay );
  1198. level notify ( "round_end_finished" );
  1199. //setSlowMotion( 1.0, 1.0, 0.05 );
  1200. return;
  1201. }
  1202.  
  1203. wait ( defaultDelay / 2 );
  1204. level notify ( "give_match_bonus" );
  1205. wait ( defaultDelay / 2 );
  1206.  
  1207. notifiesDone = false;
  1208. while ( !notifiesDone )
  1209. {
  1210. players = level.players;
  1211. notifiesDone = true;
  1212. foreach ( player in players )
  1213. {
  1214. if ( !isDefined( player.doingSplash ) )
  1215. continue;
  1216.  
  1217. if ( !player maps\mp\gametypes\_hud_message::isDoingSplash() )
  1218. continue;
  1219.  
  1220. notifiesDone = false;
  1221. }
  1222. wait ( 0.5 );
  1223. }
  1224. //setSlowMotion( 1.0, 1.0, 0.05);
  1225.  
  1226. level notify ( "round_end_finished" );
  1227. }
  1228.  
  1229.  
  1230. roundEndDOF( time )
  1231. {
  1232. self setDepthOfField( 0, 128, 512, 4000, 6, 1.8 );
  1233. }
  1234.  
  1235.  
  1236. Callback_StartGameType()
  1237. {
  1238. maps\mp\_load::main();
  1239.  
  1240. levelFlagInit( "round_over", false );
  1241. levelFlagInit( "game_over", false );
  1242. levelFlagInit( "block_notifies", false );
  1243.  
  1244. level.prematchPeriod = 0;
  1245. level.prematchPeriodEnd = 0;
  1246. level.postGameNotifies = 0;
  1247.  
  1248. level.intermission = false;
  1249.  
  1250. makeDvarServerInfo( "cg_thirdPersonAngle", 356 );
  1251.  
  1252. makeDvarServerInfo( "scr_gameended", 0 );
  1253.  
  1254. if ( !isDefined( game["gamestarted"] ) )
  1255. {
  1256. game["clientid"] = 0;
  1257.  
  1258. alliesCharSet = getMapCustom( "allieschar" );
  1259. if ( (!isDefined( alliesCharSet ) || alliesCharSet == "") )
  1260. {
  1261. if ( !isDefined( game["allies"] ) )
  1262. alliesCharSet = "us_army";
  1263. else
  1264. alliesCharSet = game["allies"];
  1265. }
  1266.  
  1267. axisCharSet = getMapCustom( "axischar" );
  1268. if ( (!isDefined( axisCharSet ) || axisCharSet == "") )
  1269. {
  1270. if ( !isDefined( game["axis"] ) )
  1271. axisCharSet = "opforce_composite";
  1272. else
  1273. axisCharSet = game["axis"];
  1274. }
  1275.  
  1276. game["allies"] = alliesCharSet;
  1277. game["axis"] = axisCharSet;
  1278.  
  1279. if ( !isDefined( game["attackers"] ) || !isDefined( game["defenders"] ) )
  1280. thread error( "No attackers or defenders team defined in level .gsc." );
  1281.  
  1282. if ( !isDefined( game["attackers"] ) )
  1283. game["attackers"] = "allies";
  1284. if ( !isDefined( game["defenders"] ) )
  1285. game["defenders"] = "axis";
  1286.  
  1287. if ( !isDefined( game["state"] ) )
  1288. game["state"] = "playing";
  1289.  
  1290. precacheStatusIcon( "hud_status_dead" );
  1291. precacheStatusIcon( "hud_status_connecting" );
  1292. precacheString( &"MPUI_REVIVING" );
  1293. precacheString( &"MPUI_BEING_REVIVED" );
  1294.  
  1295. precacheRumble( "damage_heavy" );
  1296.  
  1297. precacheShader( "white" );
  1298. precacheShader( "black" );
  1299.  
  1300. game["strings"]["press_to_spawn"] = &"PLATFORM_PRESS_TO_SPAWN";
  1301. if ( level.teamBased )
  1302. {
  1303. game["strings"]["waiting_for_teams"] = &"MP_WAITING_FOR_TEAMS";
  1304. game["strings"]["opponent_forfeiting_in"] = &"MP_OPPONENT_FORFEITING_IN";
  1305. }
  1306. else
  1307. {
  1308. game["strings"]["waiting_for_teams"] = &"MP_WAITING_FOR_MORE_PLAYERS";
  1309. game["strings"]["opponent_forfeiting_in"] = &"MP_OPPONENT_FORFEITING_IN";
  1310. }
  1311. game["strings"]["match_starting_in"] = &"MP_MATCH_STARTING_IN";
  1312. game["strings"]["match_resuming_in"] = &"MP_MATCH_RESUMING_IN";
  1313. game["strings"]["waiting_for_players"] = &"MP_WAITING_FOR_PLAYERS";
  1314. game["strings"]["spawn_next_round"] = &"MP_SPAWN_NEXT_ROUND";
  1315. game["strings"]["waiting_to_spawn"] = &"MP_WAITING_TO_SPAWN";
  1316. game["strings"]["waiting_to_safespawn"] = &"MP_WAITING_TO_SAFESPAWN";
  1317. game["strings"]["match_starting"] = &"MP_MATCH_STARTING";
  1318. game["strings"]["change_class"] = &"MP_CHANGE_CLASS_NEXT_SPAWN";
  1319. game["strings"]["last_stand"] = &"MPUI_LAST_STAND";
  1320. game["strings"]["final_stand"] = &"MPUI_FINAL_STAND";
  1321. game["strings"]["c4_death"] = &"MPUI_C4_DEATH";
  1322.  
  1323. game["strings"]["cowards_way"] = &"PLATFORM_COWARDS_WAY_OUT";
  1324.  
  1325. game["strings"]["tie"] = &"MP_MATCH_TIE";
  1326. game["strings"]["round_draw"] = &"MP_ROUND_DRAW";
  1327.  
  1328. game["strings"]["grabbed_flag"] = &"MP_GRABBED_FLAG_FIRST";
  1329. game["strings"]["enemies_eliminated"] = &"MP_ENEMIES_ELIMINATED";
  1330. game["strings"]["score_limit_reached"] = &"MP_SCORE_LIMIT_REACHED";
  1331. game["strings"]["round_limit_reached"] = &"MP_ROUND_LIMIT_REACHED";
  1332. game["strings"]["time_limit_reached"] = &"MP_TIME_LIMIT_REACHED";
  1333. game["strings"]["players_forfeited"] = &"MP_PLAYERS_FORFEITED";
  1334. game["strings"]["S.A.S Win"] = &"SAS_WIN";
  1335. game["strings"]["Spetsnaz Win"] = &"SPETSNAZ_WIN";
  1336.  
  1337. game["colors"]["blue"] = (0.25,0.25,0.75);
  1338. game["colors"]["red"] = (0.75,0.25,0.25);
  1339. game["colors"]["white"] = (1.0,1.0,1.0);
  1340. game["colors"]["black"] = (0.0,0.0,0.0);
  1341. game["colors"]["green"] = (0.25,0.75,0.25);
  1342. game["colors"]["yellow"] = (0.65,0.65,0.0);
  1343. game["colors"]["orange"] = (1.0,0.45,0.0);
  1344.  
  1345. game["strings"]["allies_eliminated"] = maps\mp\gametypes\_teams::getTeamEliminatedString( "allies" );
  1346. game["strings"]["allies_forfeited"] = maps\mp\gametypes\_teams::getTeamForfeitedString( "allies" );
  1347. game["strings"]["allies_name"] = maps\mp\gametypes\_teams::getTeamName( "allies" );
  1348. game["icons"]["allies"] = maps\mp\gametypes\_teams::getTeamIcon( "allies" );
  1349. game["colors"]["allies"] = maps\mp\gametypes\_teams::getTeamColor( "allies" );
  1350.  
  1351. game["strings"]["axis_eliminated"] = maps\mp\gametypes\_teams::getTeamEliminatedString( "axis" );
  1352. game["strings"]["axis_forfeited"] = maps\mp\gametypes\_teams::getTeamForfeitedString( "axis" );
  1353. game["strings"]["axis_name"] = maps\mp\gametypes\_teams::getTeamName( "axis" );
  1354. game["icons"]["axis"] = maps\mp\gametypes\_teams::getTeamIcon( "axis" );
  1355. game["colors"]["axis"] = maps\mp\gametypes\_teams::getTeamColor( "axis" );
  1356.  
  1357. if ( game["colors"]["allies"] == (0,0,0) )
  1358. game["colors"]["allies"] = (0.5,0.5,0.5);
  1359.  
  1360. if ( game["colors"]["axis"] == (0,0,0) )
  1361. game["colors"]["axis"] = (0.5,0.5,0.5);
  1362.  
  1363. [[level.onPrecacheGameType]]();
  1364.  
  1365. if ( level.console )
  1366. {
  1367. if ( !level.splitscreen )
  1368. level.prematchPeriod = maps\mp\gametypes\_tweakables::getTweakableValue( "game", "graceperiod" );
  1369. }
  1370. else
  1371. {
  1372. // first round, so set up prematch
  1373. level.prematchPeriod = maps\mp\gametypes\_tweakables::getTweakableValue( "game", "playerwaittime" );
  1374. level.prematchPeriodEnd = maps\mp\gametypes\_tweakables::getTweakableValue( "game", "matchstarttime" );
  1375. }
  1376. }
  1377.  
  1378. if ( !isDefined( game["status"] ) )
  1379. game["status"] = "normal";
  1380.  
  1381. makeDvarServerInfo( "ui_overtime", (game["status"] == "overtime") );
  1382.  
  1383. if ( game["status"] != "overtime" && game["status"] != "halftime" )
  1384. {
  1385. game["teamScores"]["allies"] = 0;
  1386. game["teamScores"]["axis"] = 0;
  1387. }
  1388.  
  1389. if( !isDefined( game["timePassed"] ) )
  1390. game["timePassed"] = 0;
  1391.  
  1392. if( !isDefined( game["roundsPlayed"] ) )
  1393. game["roundsPlayed"] = 0;
  1394.  
  1395. if ( !isDefined( game["roundsWon"] ) )
  1396. game["roundsWon"] = [];
  1397.  
  1398. if ( level.teamBased )
  1399. {
  1400. if ( !isDefined( game["roundsWon"]["axis"] ) )
  1401. game["roundsWon"]["axis"] = 0;
  1402. if ( !isDefined( game["roundsWon"]["allies"] ) )
  1403. game["roundsWon"]["allies"] = 0;
  1404. }
  1405.  
  1406. level.gameEnded = false;
  1407. level.forcedEnd = false;
  1408. level.hostForcedEnd = false;
  1409.  
  1410. level.hardcoreMode = getDvarInt( "g_hardcore" );
  1411. if ( level.hardcoreMode )
  1412. logString( "game mode: hardcore" );
  1413.  
  1414. level.dieHardMode = getDvarInt( "scr_diehard" );
  1415.  
  1416. if ( !level.teamBased )
  1417. level.dieHardMode = 0;
  1418.  
  1419. if ( level.dieHardMode )
  1420. logString( "game mode: diehard" );
  1421.  
  1422. level.killstreakRewards = getDvarInt( "scr_game_hardpoints" );
  1423.  
  1424. /#
  1425. printLn( "SESSION INFO" );
  1426. printLn( "=====================================" );
  1427. printLn( " Map: " + level.script );
  1428. printLn( " Script: " + level.gametype );
  1429. printLn( " HardCore: " + level.hardcoreMode );
  1430. printLn( " Diehard: " + level.dieHardMode );
  1431. printLn( " 3rd Person: " + getDvarInt( "camera_thirdperson" ) );
  1432. printLn( " Round: " + game[ "roundsPlayed" ] );
  1433. printLn( " scr_" + level.gametype + "_scorelimit " + getDvar( "scr_" + level.gametype + "_scorelimit" ) );
  1434. printLn( " scr_" + level.gametype + "_roundlimit " +getDvar( "scr_" + level.gametype + "_roundlimit" ) );
  1435. printLn( " scr_" + level.gametype + "_winlimit " + getDvar( "scr_" + level.gametype + "_winlimit" ) );
  1436. printLn( " scr_" + level.gametype + "_timelimit " + getDvar( "scr_" + level.gametype + "_timelimit" ) );
  1437. printLn( " scr_" + level.gametype + "_numlives " + getDvar( "scr_" + level.gametype + "_numlives" ) );
  1438. printLn( " scr_" + level.gametype + "_halftime " + getDvar( "scr_" + level.gametype + "_halftime" ) );
  1439. printLn( " scr_" + level.gametype + "_roundswitch " + getDvar( "scr_" + level.gametype + "_roundswitch" ) );
  1440. printLn( "=====================================" );
  1441. #/
  1442.  
  1443. // this gets set to false when someone takes damage or a gametype-specific event happens.
  1444. level.useStartSpawns = true;
  1445.  
  1446. // multiplier for score from objectives
  1447. level.objectivePointsMod = 1;
  1448.  
  1449. if ( matchMakingGame() )
  1450. level.maxAllowedTeamKills = 2;
  1451. else
  1452. level.maxAllowedTeamKills = -1;
  1453.  
  1454. thread maps\mp\gametypes\_persistence::init();
  1455. thread maps\mp\gametypes\_menus::init();
  1456. thread maps\mp\gametypes\_hud::init();
  1457. thread maps\mp\gametypes\_serversettings::init();
  1458. thread maps\mp\gametypes\_teams::init();
  1459. thread maps\mp\gametypes\_weapons::init();
  1460. thread maps\mp\gametypes\_killcam::init();
  1461. thread maps\mp\gametypes\_shellshock::init();
  1462. thread maps\mp\gametypes\_deathicons::init();
  1463. thread maps\mp\gametypes\_damagefeedback::init();
  1464. thread maps\mp\gametypes\_healthoverlay::init();
  1465. thread maps\mp\gametypes\_spectating::init();
  1466. thread maps\mp\gametypes\_objpoints::init();
  1467. thread maps\mp\gametypes\_gameobjects::init();
  1468. thread maps\mp\gametypes\_spawnlogic::init();
  1469. thread maps\mp\gametypes\_battlechatter_mp::init();
  1470. thread maps\mp\gametypes\_music_and_dialog::init();
  1471. thread maps\mp\_matchdata::init();
  1472. thread maps\mp\_awards::init();
  1473. thread maps\mp\_skill::init();
  1474. thread maps\mp\_areas::init();
  1475. thread maps\mp\killstreaks\_killstreaks::init();
  1476. //thread maps\mp\_perks::init(); // No longer in use, removed from common scripts. (smart arrow)
  1477. thread maps\mp\perks\_perks::init();
  1478. thread maps\mp\_events::init();
  1479. thread maps\mp\_defcon::init();
  1480.  
  1481. if ( level.teamBased )
  1482. thread maps\mp\gametypes\_friendicons::init();
  1483.  
  1484. thread maps\mp\gametypes\_hud_message::init();
  1485.  
  1486. if ( !level.console )
  1487. thread maps\mp\gametypes\_quickmessages::init();
  1488.  
  1489. foreach ( locString in game["strings"] )
  1490. precacheString( locString );
  1491.  
  1492. foreach ( icon in game["icons"] )
  1493. precacheShader( icon );
  1494.  
  1495. game["gamestarted"] = true;
  1496.  
  1497. level.maxPlayerCount = 0;
  1498. level.waveDelay["allies"] = 0;
  1499. level.waveDelay["axis"] = 0;
  1500. level.lastWave["allies"] = 0;
  1501. level.lastWave["axis"] = 0;
  1502. level.wavePlayerSpawnIndex["allies"] = 0;
  1503. level.wavePlayerSpawnIndex["axis"] = 0;
  1504. level.alivePlayers["allies"] = [];
  1505. level.alivePlayers["axis"] = [];
  1506. level.activePlayers = [];
  1507.  
  1508. makeDvarServerInfo( "ui_scorelimit", 0 );
  1509. makeDvarServerInfo( "ui_allow_classchange", getDvar( "ui_allow_classchange" ) );
  1510. makeDvarServerInfo( "ui_allow_teamchange", 1 );
  1511. setDvar( "ui_allow_teamchange", 1 );
  1512.  
  1513. if ( getGametypeNumLives() )
  1514. setdvar( "g_deadChat", 0 );
  1515. else
  1516. setdvar( "g_deadChat", 1 );
  1517.  
  1518. waveDelay = getDvarInt( "scr_" + level.gameType + "_waverespawndelay" );
  1519. if ( waveDelay )
  1520. {
  1521. level.waveDelay["allies"] = waveDelay;
  1522. level.waveDelay["axis"] = waveDelay;
  1523. level.lastWave["allies"] = 0;
  1524. level.lastWave["axis"] = 0;
  1525.  
  1526. level thread maps\mp\gametypes\_gamelogic::waveSpawnTimer();
  1527. }
  1528.  
  1529. gameFlagInit( "prematch_done", false );
  1530.  
  1531. level.gracePeriod = 15;
  1532.  
  1533. level.inGracePeriod = level.gracePeriod;
  1534. gameFlagInit( "graceperiod_done", false );
  1535.  
  1536. level.roundEndDelay = 4;
  1537. level.halftimeRoundEndDelay = 4;
  1538.  
  1539.  
  1540. if ( level.teamBased )
  1541. {
  1542. maps\mp\gametypes\_gamescore::updateTeamScore( "axis" );
  1543. maps\mp\gametypes\_gamescore::updateTeamScore( "allies" );
  1544. }
  1545. else
  1546. {
  1547. thread maps\mp\gametypes\_gamescore::initialDMScoreUpdate();
  1548. }
  1549.  
  1550. thread updateUIScoreLimit();
  1551. level notify ( "update_scorelimit" );
  1552.  
  1553.  
  1554. [[level.onStartGameType]]();
  1555.  
  1556. // this must be after onstartgametype for scr_showspawns to work when set at start of game
  1557. /#
  1558. thread maps\mp\gametypes\_dev::init();
  1559. #/
  1560.  
  1561. thread startGame();
  1562.  
  1563. level thread updateWatchedDvars();
  1564. level thread timeLimitThread();
  1565. }
  1566.  
  1567.  
  1568. Callback_CodeEndGame()
  1569. {
  1570. endparty();
  1571.  
  1572. if ( !level.gameEnded )
  1573. level thread maps\mp\gametypes\_gamelogic::forceEnd();
  1574. }
  1575.  
  1576.  
  1577. timeLimitThread()
  1578. {
  1579. level endon ( "game_ended" );
  1580.  
  1581. prevTimePassed = getTimePassed();
  1582.  
  1583. while ( game["state"] == "playing" )
  1584. {
  1585. thread checkTimeLimit( prevTimePassed );
  1586. prevTimePassed = getTimePassed();
  1587.  
  1588. // make sure we check time limit right when game ends
  1589. if ( isdefined( level.startTime ) )
  1590. {
  1591. if ( getTimeRemaining() < 3000 )
  1592. {
  1593. wait .1;
  1594. continue;
  1595. }
  1596. }
  1597. wait 1;
  1598. }
  1599. }
  1600.  
  1601.  
  1602. updateUIScoreLimit()
  1603. {
  1604. for ( ;; )
  1605. {
  1606. level waittill_either ( "update_scorelimit", "update_winlimit" );
  1607.  
  1608. if ( !isRoundBased() || !isObjectiveBased() )
  1609. {
  1610. setDvar( "ui_scorelimit", getWatchedDvar( "scorelimit" ) );
  1611. thread checkScoreLimit();
  1612. }
  1613. else
  1614. {
  1615. setDvar( "ui_scorelimit", getWatchedDvar( "winlimit" ) );
  1616. }
  1617. }
  1618. }
  1619.  
  1620.  
  1621. playTickingSound()
  1622. {
  1623. self endon("death");
  1624. self endon("stop_ticking");
  1625. level endon("game_ended");
  1626.  
  1627. time = level.bombTimer;
  1628.  
  1629. while(1)
  1630. {
  1631. self playSound( "ui_mp_suitcasebomb_timer" );
  1632.  
  1633. if ( time > 10 )
  1634. {
  1635. time -= 1;
  1636. wait 1;
  1637. }
  1638. else if ( time > 4 )
  1639. {
  1640. time -= .5;
  1641. wait .5;
  1642. }
  1643. else if ( time > 1 )
  1644. {
  1645. time -= .4;
  1646. wait .4;
  1647. }
  1648. else
  1649. {
  1650. time -= .3;
  1651. wait .3;
  1652. }
  1653. maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
  1654. }
  1655. }
  1656.  
  1657. stopTickingSound()
  1658. {
  1659. self notify("stop_ticking");
  1660. }
  1661.  
  1662. timeLimitClock()
  1663. {
  1664. level endon ( "game_ended" );
  1665.  
  1666. wait .05;
  1667.  
  1668. clockObject = spawn( "script_origin", (0,0,0) );
  1669. clockObject hide();
  1670.  
  1671. while ( game["state"] == "playing" )
  1672. {
  1673. if ( !level.timerStopped && getTimeLimit() )
  1674. {
  1675. timeLeft = getTimeRemaining() / 1000;
  1676. timeLeftInt = int(timeLeft + 0.5); // adding .5 and flooring rounds it.
  1677.  
  1678. if ( getHalfTime() && timeLeftInt > (getTimeLimit()*60) * 0.5 )
  1679. timeLeftInt -= int((getTimeLimit()*60) * 0.5);
  1680.  
  1681. if ( (timeLeftInt >= 30 && timeLeftInt <= 60) )
  1682. level notify ( "match_ending_soon", "time" );
  1683.  
  1684. if ( timeLeftInt <= 10 || (timeLeftInt <= 30 && timeLeftInt % 2 == 0) )
  1685. {
  1686. level notify ( "match_ending_very_soon" );
  1687. // don't play a tick at exactly 0 seconds, that's when something should be happening!
  1688. if ( timeLeftInt == 0 )
  1689. break;
  1690.  
  1691. clockObject playSound( "ui_mp_timer_countdown" );
  1692. }
  1693.  
  1694. // synchronize to be exactly on the second
  1695. if ( timeLeft - floor(timeLeft) >= .05 )
  1696. wait timeLeft - floor(timeLeft);
  1697. }
  1698.  
  1699. wait ( 1.0 );
  1700. }
  1701. }
  1702.  
  1703.  
  1704. gameTimer()
  1705. {
  1706. level endon ( "game_ended" );
  1707.  
  1708. level waittill("prematch_over");
  1709.  
  1710. level.startTime = getTime();
  1711. level.discardTime = 0;
  1712.  
  1713. if ( isDefined( game["roundMillisecondsAlreadyPassed"] ) )
  1714. {
  1715. level.startTime -= game["roundMillisecondsAlreadyPassed"];
  1716. game["roundMillisecondsAlreadyPassed"] = undefined;
  1717. }
  1718.  
  1719. prevtime = gettime();
  1720.  
  1721. while ( game["state"] == "playing" )
  1722. {
  1723. if ( !level.timerStopped )
  1724. {
  1725. // the wait isn't always exactly 1 second. dunno why.
  1726. game["timePassed"] += gettime() - prevtime;
  1727. }
  1728. prevtime = gettime();
  1729. wait ( 1.0 );
  1730. }
  1731. }
  1732.  
  1733. UpdateTimerPausedness()
  1734. {
  1735. shouldBeStopped = level.timerStoppedForGameMode || isDefined( level.hostMigrationTimer );
  1736. if ( !gameFlag( "prematch_done" ) )
  1737. shouldBeStopped = false;
  1738.  
  1739. if ( !level.timerStopped && shouldBeStopped )
  1740. {
  1741. level.timerStopped = true;
  1742. level.timerPauseTime = gettime();
  1743. }
  1744. else if ( level.timerStopped && !shouldBeStopped )
  1745. {
  1746. level.timerStopped = false;
  1747. level.discardTime += gettime() - level.timerPauseTime;
  1748. }
  1749. }
  1750.  
  1751. pauseTimer()
  1752. {
  1753. level.timerStoppedForGameMode = true;
  1754. UpdateTimerPausedness();
  1755. }
  1756.  
  1757. resumeTimer()
  1758. {
  1759. level.timerStoppedForGameMode = false;
  1760. UpdateTimerPausedness();
  1761. }
  1762.  
  1763.  
  1764. startGame()
  1765. {
  1766. thread gameTimer();
  1767. level.timerStopped = false;
  1768. level.timerStoppedForGameMode = false;
  1769. thread maps\mp\gametypes\_spawnlogic::spawnPerFrameUpdate();
  1770.  
  1771. prematchPeriod();
  1772. gameFlagSet( "prematch_done" );
  1773. level notify("prematch_over");
  1774.  
  1775. UpdateTimerPausedness();
  1776.  
  1777. thread timeLimitClock();
  1778. thread gracePeriod();
  1779.  
  1780. thread maps\mp\gametypes\_missions::roundBegin();
  1781. }
  1782.  
  1783.  
  1784. waveSpawnTimer()
  1785. {
  1786. level endon( "game_ended" );
  1787.  
  1788. while ( game["state"] == "playing" )
  1789. {
  1790. time = getTime();
  1791.  
  1792. if ( time - level.lastWave["allies"] > (level.waveDelay["allies"] * 1000) )
  1793. {
  1794. level notify ( "wave_respawn_allies" );
  1795. level.lastWave["allies"] = time;
  1796. level.wavePlayerSpawnIndex["allies"] = 0;
  1797. }
  1798.  
  1799. if ( time - level.lastWave["axis"] > (level.waveDelay["axis"] * 1000) )
  1800. {
  1801. level notify ( "wave_respawn_axis" );
  1802. level.lastWave["axis"] = time;
  1803. level.wavePlayerSpawnIndex["axis"] = 0;
  1804. }
  1805.  
  1806. wait ( 0.05 );
  1807. }
  1808. }
  1809.  
  1810.  
  1811. getBetterTeam()
  1812. {
  1813. kills["allies"] = 0;
  1814. kills["axis"] = 0;
  1815. deaths["allies"] = 0;
  1816. deaths["axis"] = 0;
  1817.  
  1818. foreach ( player in level.players )
  1819. {
  1820. team = player.pers["team"];
  1821. if ( isDefined( team ) && (team == "allies" || team == "axis") )
  1822. {
  1823. kills[ team ] += player.kills;
  1824. deaths[ team ] += player.deaths;
  1825. }
  1826. }
  1827.  
  1828. if ( kills["allies"] > kills["axis"] )
  1829. return "allies";
  1830. else if ( kills["axis"] > kills["allies"] )
  1831. return "axis";
  1832.  
  1833. // same number of kills
  1834.  
  1835. if ( deaths["allies"] < deaths["axis"] )
  1836. return "allies";
  1837. else if ( deaths["axis"] < deaths["allies"] )
  1838. return "axis";
  1839.  
  1840. // same number of deaths
  1841.  
  1842. if ( randomint(2) == 0 )
  1843. return "allies";
  1844. return "axis";
  1845. }
  1846.  
  1847.  
  1848. rankedMatchUpdates( winner )
  1849. {
  1850. if ( matchMakingGame() )
  1851. {
  1852. setXenonRanks();
  1853.  
  1854. if ( hostIdledOut() )
  1855. {
  1856. level.hostForcedEnd = true;
  1857. logString( "host idled out" );
  1858. endLobby();
  1859. }
  1860.  
  1861. updateMatchBonusScores( winner );
  1862. }
  1863.  
  1864. updateWinLossStats( winner );
  1865. }
  1866.  
  1867.  
  1868. displayRoundEnd( winner, endReasonText )
  1869. {
  1870. foreach ( player in level.players )
  1871. {
  1872. if ( isDefined( player.connectedPostGame ) || player.pers["team"] == "spectator" )
  1873. continue;
  1874.  
  1875. if ( level.teamBased )
  1876. player thread maps\mp\gametypes\_hud_message::teamOutcomeNotify( winner, true, endReasonText );
  1877. else
  1878. player thread maps\mp\gametypes\_hud_message::outcomeNotify( winner, endReasonText );
  1879. }
  1880.  
  1881. if ( !wasLastRound() )
  1882. level notify ( "round_win", winner );
  1883.  
  1884. if ( wasLastRound() )
  1885. roundEndWait( level.roundEndDelay, false );
  1886. else
  1887. roundEndWait( level.roundEndDelay, true );
  1888. }
  1889.  
  1890.  
  1891. displayGameEnd( winner, endReasonText )
  1892. {
  1893. // catching gametype, since DM forceEnd sends winner as player entity, instead of string
  1894. foreach ( player in level.players )
  1895. {
  1896. if ( isDefined( player.connectedPostGame ) || player.pers["team"] == "spectator" )
  1897. continue;
  1898.  
  1899. if ( level.teamBased )
  1900. player thread maps\mp\gametypes\_hud_message::teamOutcomeNotify( winner, false, endReasonText );
  1901. else
  1902. player thread maps\mp\gametypes\_hud_message::outcomeNotify( winner, endReasonText );
  1903. }
  1904.  
  1905. level notify ( "game_win", winner );
  1906.  
  1907. roundEndWait( level.postRoundTime, true );
  1908. }
  1909.  
  1910.  
  1911. displayRoundSwitch()
  1912. {
  1913. switchType = level.halftimeType;
  1914. if ( switchType == "halftime" )
  1915. {
  1916. if ( getWatchedDvar( "roundlimit" ) )
  1917. {
  1918. if ( (game["roundsPlayed"] * 2) == getWatchedDvar( "roundlimit" ) )
  1919. switchType = "halftime";
  1920. else
  1921. switchType = "intermission";
  1922. }
  1923. else if ( getWatchedDvar( "winlimit" ) )
  1924. {
  1925. if ( game["roundsPlayed"] == (getWatchedDvar( "winlimit" ) - 1) )
  1926. switchType = "halftime";
  1927. else
  1928. switchType = "intermission";
  1929. }
  1930. else
  1931. {
  1932. switchType = "intermission";
  1933. }
  1934. }
  1935.  
  1936. level notify ( "round_switch", switchType );
  1937.  
  1938. foreach ( player in level.players )
  1939. {
  1940. if ( isDefined( player.connectedPostGame ) || player.pers["team"] == "spectator" )
  1941. continue;
  1942.  
  1943. player thread maps\mp\gametypes\_hud_message::teamOutcomeNotify( switchType, true, level.halftimeSubCaption );
  1944. }
  1945.  
  1946. roundEndWait( level.halftimeRoundEndDelay, false );
  1947. }
  1948.  
  1949.  
  1950. endGameOvertime( winner, endReasonText )
  1951. {
  1952. // freeze players
  1953. foreach ( player in level.players )
  1954. {
  1955. player thread freezePlayerForRoundEnd( 0 );
  1956. player thread roundEndDoF( 4.0 );
  1957.  
  1958. player freeGameplayHudElems();
  1959.  
  1960. player setClientDvars( "cg_everyoneHearsEveryone", 1 );
  1961. player setClientDvars( "cg_drawSpectatorMessages", 0,
  1962. "g_compassShowEnemies", 0 );
  1963.  
  1964. if ( player.pers["team"] == "spectator" )
  1965. player thread maps\mp\gametypes\_playerlogic::spawnIntermission();
  1966. }
  1967.  
  1968. level notify ( "round_switch", "overtime" );
  1969.  
  1970. // catching gametype, since DM forceEnd sends winner as player entity, instead of string
  1971. foreach ( player in level.players )
  1972. {
  1973. if ( isDefined( player.connectedPostGame ) || player.pers["team"] == "spectator" )
  1974. continue;
  1975.  
  1976. if ( level.teamBased )
  1977. player thread maps\mp\gametypes\_hud_message::teamOutcomeNotify( winner, false, endReasonText );
  1978. else
  1979. player thread maps\mp\gametypes\_hud_message::outcomeNotify( winner, endReasonText );
  1980. }
  1981.  
  1982. roundEndWait( level.roundEndDelay, false );
  1983.  
  1984. game["status"] = "overtime";
  1985. level notify ( "restarting" );
  1986. game["state"] = "playing";
  1987. map_restart( true );
  1988. }
  1989.  
  1990.  
  1991.  
  1992. endGameHalfTime()
  1993. {
  1994. visionSetNaked( "mpOutro", 0.5 );
  1995. setDvar( "scr_gameended", 2 );
  1996.  
  1997. game["switchedsides"] = !game["switchedsides"];
  1998.  
  1999. // freeze players
  2000. foreach ( player in level.players )
  2001. {
  2002. player thread freezePlayerForRoundEnd( 0 );
  2003. player thread roundEndDoF( 4.0 );
  2004.  
  2005. player freeGameplayHudElems();
  2006.  
  2007. player setClientDvars( "cg_everyoneHearsEveryone", 1 );
  2008. player setClientDvars( "cg_drawSpectatorMessages", 0,
  2009. "g_compassShowEnemies", 0 );
  2010.  
  2011. if ( player.pers["team"] == "spectator" )
  2012. player thread maps\mp\gametypes\_playerlogic::spawnIntermission();
  2013. }
  2014.  
  2015. foreach ( player in level.players )
  2016. player.pers["stats"] = player.stats;
  2017.  
  2018. level notify ( "round_switch", "halftime" );
  2019.  
  2020. foreach ( player in level.players )
  2021. {
  2022. if ( isDefined( player.connectedPostGame ) || player.pers["team"] == "spectator" )
  2023. continue;
  2024.  
  2025. player thread maps\mp\gametypes\_hud_message::teamOutcomeNotify( "halftime", true, level.halftimeSubCaption );
  2026. }
  2027.  
  2028. roundEndWait( level.roundEndDelay, false );
  2029.  
  2030. game["status"] = "halftime";
  2031. level notify ( "restarting" );
  2032. game["state"] = "playing";
  2033. map_restart( true );
  2034. }
  2035.  
  2036.  
  2037. endGame( winner, endReasonText, nukeDetonated )
  2038. {
  2039. if ( !isDefined(nukeDetonated) )
  2040. nukeDetonated = false;
  2041.  
  2042. // return if already ending via host quit or victory, or nuke incoming
  2043. if ( game["state"] == "postgame" || level.gameEnded || (isDefined(level.nukeIncoming) && !nukeDetonated) && ( !isDefined( level.gtnw ) || !level.gtnw ) )
  2044. return;
  2045.  
  2046. game["state"] = "postgame";
  2047.  
  2048. level.gameEndTime = getTime();
  2049. level.gameEnded = true;
  2050. level.inGracePeriod = false;
  2051. level notify ( "game_ended", winner );
  2052. levelFlagSet( "game_over" );
  2053. levelFlagSet( "block_notifies" );
  2054. waitframe(); // give "game_ended" notifies time to process
  2055.  
  2056. setGameEndTime( 0 ); // stop/hide the timers
  2057.  
  2058. maps\mp\gametypes\_playerlogic::printPredictedSpawnpointCorrectness();
  2059.  
  2060. if ( isDefined( winner ) && isString( winner ) && winner == "overtime" )
  2061. {
  2062. endGameOvertime( winner, endReasonText );
  2063. return;
  2064. }
  2065.  
  2066. if ( isDefined( winner ) && isString( winner ) && winner == "halftime" )
  2067. {
  2068. endGameHalftime();
  2069. return;
  2070. }
  2071.  
  2072. game["roundsPlayed"]++;
  2073.  
  2074. if ( level.teamBased )
  2075. {
  2076. if ( winner == "axis" || winner == "allies" )
  2077. game["roundsWon"][winner]++;
  2078.  
  2079. maps\mp\gametypes\_gamescore::updateTeamScore( "axis" );
  2080. maps\mp\gametypes\_gamescore::updateTeamScore( "allies" );
  2081. }
  2082. else
  2083. {
  2084. if ( isDefined( winner ) && isPlayer( winner ) )
  2085. game["roundsWon"][winner.guid]++;
  2086. }
  2087.  
  2088. maps\mp\gametypes\_gamescore::updatePlacement();
  2089.  
  2090. rankedMatchUpdates( winner );
  2091.  
  2092. foreach ( player in level.players )
  2093. {
  2094. player setClientDvar( "ui_opensummary", 1 );
  2095. }
  2096.  
  2097. setDvar( "g_deadChat", 1 );
  2098. setDvar( "ui_allow_teamchange", 0 );
  2099.  
  2100. // freeze players
  2101. foreach ( player in level.players )
  2102. {
  2103. player thread freezePlayerForRoundEnd( 1.0 );
  2104. player thread roundEndDoF( 4.0 );
  2105.  
  2106. player freeGameplayHudElems();
  2107.  
  2108. player setClientDvars( "cg_everyoneHearsEveryone", 1 );
  2109. player setClientDvars( "cg_drawSpectatorMessages", 0,
  2110. "g_compassShowEnemies", 0,
  2111. "cg_fovScale", 1 );
  2112.  
  2113. if ( player.pers["team"] == "spectator" )
  2114. player thread maps\mp\gametypes\_playerlogic::spawnIntermission();
  2115. }
  2116.  
  2117. if( !nukeDetonated )
  2118. visionSetNaked( "mpOutro", 0.5 );
  2119.  
  2120. // End of Round
  2121. if ( !wasOnlyRound() && !nukeDetonated )
  2122. {
  2123. setDvar( "scr_gameended", 2 );
  2124.  
  2125. displayRoundEnd( winner, endReasonText );
  2126.  
  2127. if ( level.showingFinalKillcam )
  2128. {
  2129. foreach ( player in level.players )
  2130. player notify ( "reset_outcome" );
  2131.  
  2132. level notify ( "game_cleanup" );
  2133.  
  2134. waittillFinalKillcamDone();
  2135. }
  2136.  
  2137. if ( !wasLastRound() )
  2138. {
  2139. levelFlagClear( "block_notifies" );
  2140. if ( checkRoundSwitch() )
  2141. displayRoundSwitch();
  2142.  
  2143. foreach ( player in level.players )
  2144. player.pers["stats"] = player.stats;
  2145.  
  2146. level notify ( "restarting" );
  2147. game["state"] = "playing";
  2148. map_restart( true );
  2149. return;
  2150. }
  2151.  
  2152. if ( !level.forcedEnd )
  2153. endReasonText = updateEndReasonText( winner );
  2154. }
  2155.  
  2156. setDvar( "scr_gameended", 1 );
  2157.  
  2158. if ( !isDefined( game["clientMatchDataDef"] ) )
  2159. {
  2160. game["clientMatchDataDef"] = "mp/clientmatchdata.def";
  2161. setClientMatchDataDef( game["clientMatchDataDef"] );
  2162. }
  2163.  
  2164. maps\mp\gametypes\_missions::roundEnd( winner );
  2165.  
  2166. displayGameEnd( winner, endReasonText );
  2167.  
  2168. if ( level.showingFinalKillcam && wasOnlyRound() )
  2169. {
  2170. foreach ( player in level.players )
  2171. player notify ( "reset_outcome" );
  2172.  
  2173. level notify ( "game_cleanup" );
  2174.  
  2175. waittillFinalKillcamDone();
  2176. }
  2177.  
  2178. levelFlagClear( "block_notifies" );
  2179.  
  2180. level.intermission = true;
  2181.  
  2182. level notify ( "spawning_intermission" );
  2183.  
  2184. foreach ( player in level.players )
  2185. {
  2186. player closepopupMenu();
  2187. player closeInGameMenu();
  2188. player notify ( "reset_outcome" );
  2189. player thread maps\mp\gametypes\_playerlogic::spawnIntermission();
  2190. }
  2191.  
  2192. processLobbyData();
  2193.  
  2194. wait ( 1.0 );
  2195.  
  2196. if ( matchMakingGame() )
  2197. sendMatchData();
  2198.  
  2199. foreach ( player in level.players )
  2200. player.pers["stats"] = player.stats;
  2201.  
  2202. //logString( "game ended" );
  2203. if( !nukeDetonated && !level.postGameNotifies )
  2204. {
  2205. if ( !wasOnlyRound() )
  2206. wait 6.0;
  2207. else
  2208. wait 3.0;
  2209. }
  2210. else
  2211. {
  2212. wait ( min( 10.0, 4.0 + level.postGameNotifies ) );
  2213. }
  2214.  
  2215. level notify( "exitLevel_called" );
  2216. exitLevel( false );
  2217. }
  2218.  
  2219. updateEndReasonText( winner )
  2220. {
  2221. if ( !level.teamBased )
  2222. return true;
  2223.  
  2224. if ( hitRoundLimit() )
  2225. return &"MP_ROUND_LIMIT_REACHED";
  2226.  
  2227. if ( hitWinLimit() )
  2228. return &"MP_SCORE_LIMIT_REACHED";
  2229.  
  2230. if ( winner == "axis" )
  2231. return &"SPETSNAZ_WIN";
  2232. else
  2233. return &"SAS_WIN";
  2234. }
  2235.  
  2236. estimatedTimeTillScoreLimit( team )
  2237. {
  2238. assert( isPlayer( self ) || isDefined( team ) );
  2239.  
  2240. scorePerMinute = getScorePerMinute( team );
  2241. scoreRemaining = getScoreRemaining( team );
  2242.  
  2243. estimatedTimeLeft = 999999;
  2244. if ( scorePerMinute )
  2245. estimatedTimeLeft = scoreRemaining / scorePerMinute;
  2246.  
  2247. //println( "estimatedTimeLeft: " + estimatedTimeLeft );
  2248. return estimatedTimeLeft;
  2249. }
  2250.  
  2251. getScorePerMinute( team )
  2252. {
  2253. assert( isPlayer( self ) || isDefined( team ) );
  2254.  
  2255. scoreLimit = getWatchedDvar( "scorelimit" );
  2256. timeLimit = getTimeLimit();
  2257. minutesPassed = (getTimePassed() / (60*1000)) + 0.0001;
  2258.  
  2259. if ( isPlayer( self ) )
  2260. scorePerMinute = self.score / minutesPassed;
  2261. else
  2262. scorePerMinute = getTeamScore( team ) / minutesPassed;
  2263.  
  2264. return scorePerMinute;
  2265. }
  2266.  
  2267. getScoreRemaining( team )
  2268. {
  2269. assert( isPlayer( self ) || isDefined( team ) );
  2270.  
  2271. scoreLimit = getWatchedDvar( "scorelimit" );
  2272.  
  2273. if ( isPlayer( self ) )
  2274. scoreRemaining = scoreLimit - self.score;
  2275. else
  2276. scoreRemaining = scoreLimit - getTeamScore( team );
  2277.  
  2278. return scoreRemaining;
  2279. }
  2280.  
  2281. giveLastOnTeamWarning()
  2282. {
  2283. self endon("death");
  2284. self endon("disconnect");
  2285. level endon( "game_ended" );
  2286.  
  2287. self waitTillRecoveredHealth( 3 );
  2288.  
  2289. otherTeam = getOtherTeam( self.pers["team"] );
  2290. thread teamPlayerCardSplash( "callout_lastteammemberalive", self, self.pers["team"] );
  2291. thread teamPlayerCardSplash( "callout_lastenemyalive", self, otherTeam );
  2292. level notify ( "last_alive", self );
  2293. }
  2294.  
  2295. processLobbyData()
  2296. {
  2297. curPlayer = 0;
  2298. foreach ( player in level.players )
  2299. {
  2300. if ( !isDefined( player ) )
  2301. continue;
  2302.  
  2303. player.clientMatchDataId = curPlayer;
  2304. curPlayer++;
  2305.  
  2306. // on PS3 cap long names
  2307. if ( level.ps3 && (player.name.size > level.MaxNameLength) )
  2308. {
  2309. playerName = "";
  2310. for ( i = 0; i < level.MaxNameLength-3; i++ )
  2311. playerName += player.name[i];
  2312.  
  2313. playerName += "...";
  2314. }
  2315. else
  2316. {
  2317. playerName = player.name;
  2318. }
  2319.  
  2320. setClientMatchData( "players", player.clientMatchDataId, "xuid", playerName );
  2321. }
  2322.  
  2323. maps\mp\_awards::assignAwards();
  2324. maps\mp\_scoreboard::processLobbyScoreboards();
  2325.  
  2326. sendClientMatchData();
  2327. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement