Advertisement
NachosEater

_gamelogic

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