123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467 |
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Copyright 2016 RWS Inc, All Rights Reserved
- //
- // This program is free software; you can redistribute it and/or modify
- // it under the terms of version 2 of the GNU General Public License as published by
- // the Free Software Foundation
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License along
- // with this program; if not, write to the Free Software Foundation, Inc.,
- // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- //
- // Score.cpp
- // Project: Postal
- //
- // Description:
- // This module will be used to collect and display the scoring for the
- // game. Characters that die will call a function to register the kill
- // giving their ID and the ID of the character that killed them. Play
- // will call a function to update the display for the score and depending
- // on the mode of scoring, this module will draw the score into the given
- // image. The first scoring mode will be for multiplayer where all 8
- // players will have the number of kills displayed with their names.
- // Single player score may show something like Number of victims and
- // number of enemies. A timed challenge level may show the kills and the
- // time remaining.
- //
- // History:
- //
- // 06/11/97 BRH Started this module for scoring of different types.
- //
- // 06/12/97 BRH Added Scoring display for multiplayer and moved the
- // single player score from Realm to the same display
- // function here in score.
- //
- // 06/13/97 BRH Fixed the formatting for multiplayer mode.
- //
- // 06/15/97 BRH Took out temporary code that forced it into multiplayer
- // display for testing. Put back the normal code to
- // work for either single or multiplayer mode.
- //
- // 06/16/97 BRH Added a reset function to reset the scores and
- // display time.
- //
- // 06/17/97 BRH Fixed the display area for the score.
- //
- // 06/26/97 BRH Changed the score so that the population number goes
- // down when someone is killed.
- //
- // 06/29/97 BRH Separated the score and status lines so that the mission
- // goal can be displayed for a short period of time while
- // the score displays constantly.
- //
- // 07/04/97 BRH Added scoring displays for some of the other types
- // of games, timed, goal, capture the flag, etc.
- //
- // 07/06/97 BRH Added scoring displays and staus lines for the challenge
- // levels.
- //
- // 07/07/97 JMI Now ScoreUpdateDisplay() returns true if it drew into
- // the passed in buffer and false otherwise.
- //
- // 07/08/97 BRH Changed the check for scoring mode from the scoreboard
- // to the realm's enumerated type.
- //
- // 07/14/97 BRH Fixed clock format to use %2.2d to correctly display
- // 2 digits for seconds.
- //
- // 07/22/97 BRH Added ScoreDisplayHighScores function which is called
- // from Play.cpp after the goal level has been met. This
- // will check the player's score against the top 5 stored
- // scores for the level and if they place, it will allow
- // them to enter their name. The initial version of this
- // will just skip the dialog for now, but will soon
- // do a switch statement for each scoring mode.
- //
- // 07/26/97 BRH Added loading and saving of high scores in a prefs type
- // file. Now the only thing that needs to be changed is
- // to use the function that returns the realm name or
- // descriptive string which will be used as the section
- // name to find the scores particular to this realm.
- //
- // 07/27/97 BRH Made use of the new realm variable m_lScoreIntialTime
- // to calculate the elapsed time for two of the scoring
- // modes.
- //
- // 07/30/97 BRH Used the realm's string to identify the current realm
- // being played so that the high scores for this realm
- // can be loaded and saved.
- //
- // 08/10/97 JRD Modified ScoreUpdateDisplay to accept a hood pointer so
- // it could create a graphical back drop.
- //
- // 09/10/97 JRD Added color matching and shadow drop to the upper score bar.
- //
- // 08/14/97 BRH Changed location of gui for high scores, moved from
- // /game/ to /shell directory so that the textures used
- // for it could be shared easier with the other shell gui's
- //
- // 08/17/97 MJR Now uses g_resmgrShell to load gui's. Also now frees
- // the resources (ooooohhh Bill!)
- //
- // 08/19/97 BRH Fixed the problem with checkpoint scoring, probably
- // some typo that Mike put in by accident.
- //
- // 08/19/97 JMI There was a missing '}' ala Mike via Bill.
- //
- // 08/20/97 BRH No thanks to Mike or Jon, I had to fix the multiplayer
- // score displays so that new time information would
- // fit on a third line.
- //
- // 08/25/97 JMI Moved gsStatus* to toolbar.h.
- //
- // 08/28/97 JMI Added GetRes/ReleaseRes callbacks to dialogs, PalTrans,
- // Postal Font, and sound to name edit field.
- //
- // 08/29/97 BRH Changed challenge modes to use Population numbers
- // rather than just hostile numbers so that the victims
- // count also.
- //
- // 08/29/97 JMI Now ScoreDisplayHighScores() quits immediately for
- // scoring modes that don't track high scores (currently,
- // only standard).
- //
- // 08/30/97 JMI Now uses population deaths instead of hostile deaths
- // for timed challenge scoring.
- // Also, sets the palette every time the dialog is shown.
- //
- // 09/01/97 JMI Now your high score is entered in the high score dialog
- // itself. Also, now uses a listbox for high scores so
- // that we could edit merely one high score item and fill
- // the listbox with instances of that same item.
- //
- // 09/01/97 JMI Now displays new highscore in different color.
- //
- // 09/02/97 JMI Now ScoreDisplayHighScores() makes sure you're not playing
- // a demo before displaying the highscores.
- //
- // 09/02/97 JMI Now has separate cases for determing scoring for every
- // mode in ScoreDisplayHighScores().
- //
- // 09/04/97 BRH Fixed font size for the MPFrag scoring mode.
- //
- // 09/07/97 JMI Added ability to display high scores for multiplayer.
- // Also, added optional high score display timeout.
- //
- // 09/07/97 BRH Fixed problem with long multi player names wrapping
- // to the next line.
- //
- // 09/07/97 JMI Now colors this player's score in MP mode. Also, dialog
- // is much smaller so name length is restricted more. But
- // does allow up to 16 scores now.
- //
- // 09/08/97 BRH Fixed Goal and TimedGoal to display the Remaining: as
- // the number remaining in the goal, not the number of
- // people remaining in the realm.
- //
- // 09/08/97 BRH Adjusted the posiiton of the MP mission goals since
- // the font size is smaller, they weren't centered properly.
- //
- // 09/08/97 JMI Changed "Congratulations! Please enter your name for your
- // score." to "Please enter your name, Asshole." but the end
- // clips off (just kidding).
- //
- // 09/08/97 JMI Now sorts multiplayer names by score.
- //
- // 06/04/98 JMI Strings used for storage and sorting of multiplayer names
- // were sized at MAX_PLAYER_NAME_LEN (to fit the high score
- // GUI without overlapping the score) but Postal's net
- // client (from which the names are querried) allows longer
- // names (specifically Net::MaxPlayerNameSize). Now only
- // copies first MAX_PLAYER_NAME_LEN chars from the player's
- // name.
- //
- //////////////////////////////////////////////////////////////////////////////
- #define SCORE_CPP
- //////////////////////////////////////////////////////////////////////////////
- // C Headers
- //////////////////////////////////////////////////////////////////////////////
- #include "RSPiX.h"
- #include "score.h"
- #include "dude.h"
- #include "toolbar.h"
- #include "update.h"
- //////////////////////////////////////////////////////////////////////////////
- // Macros
- //////////////////////////////////////////////////////////////////////////////
- // Time, in ms, between status updates.
- #define SCORE_UPDATE_INTERVAL 1000
- #define STATUS_DISPLAY_TIMEOUT 8000
- #define STATUS_PRINT_X 2
- #define STATUS_PRINT_Y 0
- #define STATUS_PRINT_Y2 14
- #define STATUS_PRINT_Y3 28
- #define STATUS_FONT_SIZE 19
- #define STATUS_DISPLAY_HEIGHT 40
- #define MP_FONT_SIZE 11 //15
- #define MP_PRINT_X 2
- #define MP_PRINT_Y1 0
- #define MP_PRINT_Y2 11
- #define MP_PRINT_Y3 22
- //------------------------ These are color matched in the toolbar module
- #define HIGHSCORE_NAMEDIALOG_FILE "menu/addname.gui"
- #define HIGHSCORE_DIALOG_FILE "menu/hiscore.gui"
- #define HIGHSCORE_ITEM_FILE "menu/HiScoreItem.gui"
- #define HIGHSCORE_SCORES_FILE "res/savegame/high.ini"
- #define TEXT_SHADOW_COLOR 220
- #define TEXT_HIGHLIGHT_COLOR 9
- // This path gets prepended to the resource path before passing the
- // GUI res request to the resource manager. This makes it easy to
- // keep the path for the file simple while in the GUI Editor so the default
- // handling can take care of it there. The GUI Editor does not use the resmgr,
- // it simply loads it blindly with no regard to its current directory.
- #define GUI_RES_DIR "menu/"
- // Maximum name length.
- #define MAX_PLAYER_NAME_LEN 17
- #define MAX_HIGH_SCORES 16
- //////////////////////////////////////////////////////////////////////////////
- // Variables
- //////////////////////////////////////////////////////////////////////////////
- CScoreboard g_scoreboard;
- RPrint ms_print;
- static long ms_lScoreMaxTimeOut; // Optional score timeout (max time spent
- // on score screen).
- //////////////////////////////////////////////////////////////////////////////
- // Functions.
- //////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- // Helper to make a time value.
- //////////////////////////////////////////////////////////////////////////////
- inline char* CreateTimeString( // Returns time string. No failures.
- long lTimeVal) // In: Time value in milliseconds.
- {
- static char szTime[100];
- short sMinutes = lTimeVal / 60000;
- short sSeconds = (lTimeVal / 1000) % 60;
- sprintf(szTime, "%2.2d:%2.2d", sMinutes, sSeconds);
- return szTime;
- }
- //////////////////////////////////////////////////////////////////////////////
- // GuiReleaseRes - Release a resource that the requesting GUI wants to
- // discard.
- //////////////////////////////////////////////////////////////////////////////
- static void GuiReleaseRes( // Returns nothing.
- RGuiItem* pgui) // In: Requesting GUI.
- {
- rspReleaseResource(&g_resmgrShell, &pgui->m_pimBkdRes);
- }
- //////////////////////////////////////////////////////////////////////////////
- // GuiGetRes - Get a resource that the requesting GUI wants to use for its
- // background or state image.
- //////////////////////////////////////////////////////////////////////////////
- static short GuiGetRes( // Returns 0 on success; non-zero on failure.
- RGuiItem* pgui) // In: Requesting GUI.
- {
- short sResult = 0;
- // Release resources first (just in case)
- GuiReleaseRes(pgui);
- // Allocate and load new resources. We get the name of the file (which
- // is ASSUMED to have NO PATH!!) from the gui itself, then tack on the
- // path we need and get the resource from the resource manager.
- char szFile[RSP_MAX_PATH * 2];
- sprintf(szFile, "%s%s", GUI_RES_DIR, pgui->m_szBkdResName);
- if (rspGetResource(&g_resmgrShell, szFile, &pgui->m_pimBkdRes) == 0)
- {
- // Set palette via resource.
- ASSERT(pgui->m_pimBkdRes->m_pPalette != NULL);
- ASSERT(pgui->m_pimBkdRes->m_pPalette->m_type == RPal::PDIB);
- rspSetPaletteEntries(
- 0,
- 230,
- pgui->m_pimBkdRes->m_pPalette->Red(0),
- pgui->m_pimBkdRes->m_pPalette->Green(0),
- pgui->m_pimBkdRes->m_pPalette->Blue(0),
- pgui->m_pimBkdRes->m_pPalette->m_sPalEntrySize);
- // Update hardware palette.
- rspUpdatePalette();
- }
- else
- {
- sResult = -1;
- TRACE("GuiGetRes(): Failed to open file '%s'\n", szFile);
- }
- return sResult;
- }
- //////////////////////////////////////////////////////////////////////////////
- // EditInputUserFeedback -- Whines when the user causes an input
- // disgruntlement.
- //////////////////////////////////////////////////////////////////////////////
- static void EditInputUserFeedback( // Called when a user input notification
- // should occur.
- REdit* pedit) // In: Edit field.
- {
- PlaySample(g_smidEmptyWeapon, SampleMaster::UserFeedBack);
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Callback from RProcessGui for system update.
- //
- ////////////////////////////////////////////////////////////////////////////////
- static long SysUpdate( // Returns a non-zero ID to abort or zero
- // to continue.
- RInputEvent* pie) // Out: Next input event to process.
- {
- long lIdRes = 0; // Assume no GUI ID pressed (i.e., continue).
- UpdateSystem();
- rspGetNextInputEvent(pie);
- // If timeout has expired . . .
- if (rspGetMilliseconds() > ms_lScoreMaxTimeOut)
- {
- // Auto push OK.
- lIdRes = 1;
- }
- return lIdRes;
- }
- //////////////////////////////////////////////////////////////////////////////
- // ScoreInit - Set up the RPrint for the score
- //////////////////////////////////////////////////////////////////////////////
- void ScoreInit(void)
- {
- // Setup print.
- ms_print.SetFont(STATUS_FONT_SIZE, &g_fontBig);
- ms_print.SetColor(
- gsStatusFontForeIndex,
- gsStatusFontBackIndex,
- gsStatusFontShadowIndex);
- // Make sure shadow is one off:
- ms_print.SetEffectAbs(RPrint::SHADOW_X,+1);
- ms_print.SetEffectAbs(RPrint::SHADOW_Y,+1);
- // Warning! This may need to be set back again for gui items - if so, use
- // my OWN print!
- }
- //////////////////////////////////////////////////////////////////////////////
- // ScoreReset - Reset the scores and the display time
- //////////////////////////////////////////////////////////////////////////////
- void ScoreReset(void)
- {
- g_scoreboard.Reset();
- }
- //////////////////////////////////////////////////////////////////////////////
- // ScoreResetDisplay - Reset the timer for the display before the start
- // of each realm
- //////////////////////////////////////////////////////////////////////////////
- void ScoreResetDisplay(void)
- {
- g_scoreboard.m_lLastStatusDrawTime = 0;
- g_scoreboard.m_lLastScoreDrawTime = 0;
- }
- //////////////////////////////////////////////////////////////////////////////
- // ScoreRegisterKill - Characters should call this when they die
- //////////////////////////////////////////////////////////////////////////////
- void ScoreRegisterKill(CRealm* pRealm, U16 u16DeadGuy, U16 u16Killer)
- {
- CThing* pShooter = NULL;
- pRealm->m_idbank.GetThingByID(&pShooter, u16Killer);
- if (pShooter && pShooter->GetClassID() == CThing::CDudeID)
- {
- if (u16DeadGuy == u16Killer)
- g_scoreboard.SubtractOne(((CDude*) pShooter)->m_sDudeNum);
- else
- g_scoreboard.AddOne(((CDude*) pShooter)->m_sDudeNum);
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- // ScoreUpdateDisplay - Display the score for the current mode
- // Returns true, if pImage was updated; false otherwise.
- //////////////////////////////////////////////////////////////////////////////
- bool ScoreUpdateDisplay(RImage* pim, RRect* prc, CRealm* pRealm, CNetClient* pclient,
- short sDstX,short sDstY,CHood* pHood)
- {
- RRect rcBox;
- RRect rcDst;
- rcDst.sX = prc->sX + STATUS_PRINT_X;
- rcDst.sY = prc->sY + STATUS_PRINT_Y;
- rcDst.sW = prc->sW - 2 * STATUS_PRINT_X;
- rcDst.sH = prc->sH - STATUS_PRINT_Y;
- short sMinutes = pRealm->m_lScoreTimeDisplay / 60000;
- short sSeconds = (pRealm->m_lScoreTimeDisplay / 1000) % 60;
- bool bDrew = false; // Assume we do not draw.
- long lCurTime = pRealm->m_time.GetGameTime();
- if (lCurTime > g_scoreboard.m_lLastScoreDrawTime + SCORE_UPDATE_INTERVAL)
- {
- ms_print.SetColor( // set current color
- gsStatusFontForeIndex,
- gsStatusFontBackIndex,
- gsStatusFontShadowIndex);
- // Set print/clip to area.
- // instead of clearing, drop the special backdrop.
- //rspRect(RSP_BLACK_INDEX, pim, rcDst.sX, rcDst.sY, rcDst.sW, rcDst.sH);
- if (pHood) rspBlit(pHood->m_pimTopBar,pim,0,0,sDstX,sDstY,
- pHood->m_pimTopBar->m_sWidth,pHood->m_pimTopBar->m_sHeight);
-
- short sNumDudes = pRealm->m_asClassNumThings[CThing::CDudeID];
- short i;
- switch (pRealm->m_ScoringMode)
- {
- case CRealm::MPFrag:
- ms_print.SetFont(MP_FONT_SIZE, &g_fontBig);
- rcBox.sY = prc->sY + MP_PRINT_Y1;
- rcBox.sH = MP_FONT_SIZE + 1;
- rcBox.sW = rcDst.sW / sNumDudes;
- ms_print.SetJustifyLeft();
- ms_print.SetWordWrap(FALSE);
- for (i = 0; i < sNumDudes; i++)
- {
- rcBox.sX = rcDst.sX + (i * rcBox.sW);
- rcBox.sY = prc->sY + STATUS_PRINT_Y;
- ms_print.SetDestination(pim, &rcBox);
- ms_print.print(
- rcBox.sX,
- rcBox.sY,
- "%s",
- pclient->GetPlayerName(i)
- );
- rcBox.sY = prc->sY + STATUS_PRINT_Y2;
- ms_print.SetDestination(pim, &rcBox);
- ms_print.print(
- rcBox.sX,
- rcBox.sY,
- "%d",
- g_scoreboard.m_asScores[i]
- );
- }
- break;
- // These have the same display, but different ending conditions
- case CRealm::MPTimed:
- case CRealm::MPTimedFrag:
- ms_print.SetFont(MP_FONT_SIZE, &g_fontBig);
- rcBox.sY = prc->sY + MP_PRINT_Y1;
- rcBox.sH = MP_FONT_SIZE + 1;
- rcBox.sW = rcDst.sW / sNumDudes;
- ms_print.SetJustifyLeft();
- ms_print.SetWordWrap(FALSE);
- for (i = 0; i < sNumDudes; i++)
- {
- rcBox.sX = rcDst.sX + (i * rcBox.sW);
- rcBox.sY = prc->sY + MP_PRINT_Y1;
- ms_print.SetDestination(pim, &rcBox);
- ms_print.print(
- rcBox.sX,
- rcBox.sY,
- "%s",
- pclient->GetPlayerName(i)
- );
- rcBox.sY = prc->sY + MP_PRINT_Y2;
- ms_print.SetDestination(pim, &rcBox);
- ms_print.print(
- rcBox.sX,
- rcBox.sY,
- "%d",
- g_scoreboard.m_asScores[i]
- );
- }
- rcBox.sY = prc->sY + MP_PRINT_Y3;
- rcBox.sX = prc->sX;
- ms_print.SetDestination(pim, &rcBox);
- ms_print.print(
- rcDst.sX,
- rcDst.sY,
- // "Time Remaining %d:%2.2d",
- g_apszScoreDisplayText[pRealm->m_ScoringMode],
- sMinutes,
- sSeconds);
- break;
- case CRealm::MPLastMan:
- rcBox.sY = prc->sY + STATUS_PRINT_Y;
- rcBox.sH = STATUS_FONT_SIZE + 1;
- rcBox.sW = rcDst.sW / sNumDudes;
- ms_print.SetJustifyLeft();
- ms_print.SetWordWrap(FALSE);
- for (i = 0; i < sNumDudes; i++)
- {
- // If this player is dead, set the color to dead color
- /*
- ms_print.SetColor( // set current color
- gsStatusFontForeDeadIndex,
- gsStatusFontBackIndex,
- gsStatusFontShadowIndex);
- else
- ms_print.SetColor( // set current color
- gsStatusFontForeIndex,
- gsStatusFontBackIndex,
- gsStatusFontShadowIndex);
- */
- rcBox.sX = rcDst.sX + (i * rcBox.sW);
- rcBox.sY = prc->sY + STATUS_PRINT_Y;
- ms_print.SetDestination(pim, &rcBox);
- ms_print.print(
- rcBox.sX,
- rcBox.sY,
- "%s",
- pclient->GetPlayerName(i)
- );
- rcBox.sY = prc->sY + STATUS_PRINT_Y2;
- ms_print.SetDestination(pim, &rcBox);
- ms_print.print(
- rcBox.sX,
- rcBox.sY,
- "%d",
- g_scoreboard.m_asScores[i]
- );
- }
- break;
- case CRealm::MPLastManTimed:
- break;
- case CRealm::MPLastManFrag:
- break;
- case CRealm::MPLastManTimedFrag:
- break;
- case CRealm::Standard:
- ms_print.SetDestination(pim, &rcDst);
- ms_print.print(
- pim,
- rcDst.sX,
- rcDst.sY,
- // " Population %d Hostiles %d Killed %d (%d%% / %d%%)",
- g_apszScoreDisplayText[pRealm->m_ScoringMode],
- pRealm->m_sPopulation,
- pRealm->m_sHostiles,
- pRealm->m_sHostileKills,
- pRealm->m_sHostileKills * 100 / ((pRealm->m_sHostileBirths != 0) ? pRealm->m_sHostileBirths : 1),
- (short) pRealm->m_dKillsPercentGoal
- );
- break;
- case CRealm::Timed:
- ms_print.SetDestination(pim, &rcDst);
- ms_print.print(
- pim,
- rcDst.sX,
- rcDst.sY,
- // " Time Remaining %d:%2.2d Kills %d",
- g_apszScoreDisplayText[pRealm->m_ScoringMode],
- sMinutes,
- sSeconds,
- pRealm->m_sPopulationDeaths
- );
- break;
- case CRealm::TimedGoal:
- ms_print.SetDestination(pim, &rcDst);
- ms_print.print(
- pim,
- rcDst.sX,
- rcDst.sY,
- // " Time Remaining %d:%2.2d Kills %d Remaining %d / %d",
- g_apszScoreDisplayText[pRealm->m_ScoringMode],
- sMinutes,
- sSeconds,
- pRealm->m_sPopulationDeaths,
- pRealm->m_sKillsGoal - pRealm->m_sPopulationDeaths, pRealm->m_sPopulation
- );
- break;
- case CRealm::TimedFlag:
- ms_print.SetDestination(pim, &rcDst);
- ms_print.print(
- pim,
- rcDst.sX,
- rcDst.sY,
- // " Time Remaining %d:%2.2d",
- g_apszScoreDisplayText[pRealm->m_ScoringMode],
- sMinutes,
- sSeconds
- );
- break;
- case CRealm::Goal:
- ms_print.SetDestination(pim, &rcDst);
- ms_print.print(
- pim,
- rcDst.sX,
- rcDst.sY,
- // " Kills %d Remaining %d Time Elapsed %d:%2.2d",
- g_apszScoreDisplayText[pRealm->m_ScoringMode],
- pRealm->m_sPopulationDeaths,
- pRealm->m_sKillsGoal - pRealm->m_sPopulationDeaths /*pRealm->m_sPopulation*/,
- sMinutes,
- sSeconds
- );
- break;
- case CRealm::CaptureFlag:
- ms_print.SetDestination(pim, &rcDst);
- ms_print.print(
- pim,
- rcDst.sX,
- rcDst.sY,
- // " Time Elapsed %d:%2.2d",
- g_apszScoreDisplayText[pRealm->m_ScoringMode],
- sMinutes,
- sSeconds
- );
- break;
- case CRealm::Checkpoint:
- ms_print.SetDestination(pim, &rcDst);
- ms_print.print(
- pim,
- rcDst.sX,
- rcDst.sY,
- // " Clock %d:%2.2d You have %d flags Flags Remaining %d",
- g_apszScoreDisplayText[pRealm->m_ScoringMode],
- sMinutes,
- sSeconds,
- pRealm->m_sFlagsCaptured,
- pRealm->m_asClassNumThings[CThing::CFlagID] - pRealm->m_sFlagsCaptured
- );
- break;
- default:
- break;
- }
- g_scoreboard.m_lLastScoreDrawTime = lCurTime;
- // Display the status or mission statement line
- if (lCurTime < g_scoreboard.m_lLastStatusDrawTime + STATUS_DISPLAY_TIMEOUT)
- {
- switch (pRealm->m_ScoringMode)
- {
- case CRealm::MPFrag:
- rcDst.sY = prc->sY + MP_PRINT_Y3;
- if (pRealm->m_sKillsGoal < 1)
- {
- rcDst.sX = prc->sX + 0;
- ms_print.SetDestination(pim, &rcDst);
- ms_print.print(
- rcDst.sX,
- rcDst.sY,
- // " There are no time or kill limits on this game - play as long as you like"
- g_apszScoreGoalText[CRealm::MPLastManTimedFrag] // Cheating since this is
- // Really none of the scoring modes
- );
- }
- else
- {
- rcDst.sX = prc->sX + 220;
- ms_print.SetDestination(pim, &rcDst);
- ms_print.print(
- rcDst.sX,
- rcDst.sY,
- // " The first player to get %d kills wins",
- g_apszScoreGoalText[pRealm->m_ScoringMode],
- pRealm->m_sKillsGoal
- );
- }
- break;
- case CRealm::MPTimed:
- rcDst.sY = prc->sY + MP_PRINT_Y3;
- rcDst.sX = prc->sX + 180;
- ms_print.SetDestination(pim, &rcDst);
- ms_print.print(
- rcDst.sX,
- rcDst.sY,
- // " The player with the most kills when time expires is the winner"
- g_apszScoreGoalText[pRealm->m_ScoringMode]
- );
- break;
- case CRealm::MPTimedFrag:
- rcDst.sY = prc->sY + MP_PRINT_Y3;
- rcDst.sX = prc->sX + 220;
- ms_print.SetDestination(pim, &rcDst);
- ms_print.print(
- rcDst.sX,
- rcDst.sY,
- // " Try to reach %d kills before time expires",
- g_apszScoreGoalText[pRealm->m_ScoringMode],
- pRealm->m_sKillsGoal
- );
- break;
- case CRealm::Standard:
- rcDst.sY = prc->sY + STATUS_PRINT_Y2;
- ms_print.SetDestination(pim, &rcDst);
- ms_print.print(
- rcDst.sX,
- rcDst.sY,
- // " You must kill %d%% of the hostiles.",
- g_apszScoreGoalText[pRealm->m_ScoringMode],
- (short) pRealm->m_dKillsPercentGoal
- );
- break;
- case CRealm::Timed:
- rcDst.sY = prc->sY + STATUS_PRINT_Y2;
- ms_print.SetDestination(pim, &rcDst);
- ms_print.print(
- rcDst.sX,
- rcDst.sY,
- // " Score as many kills as possible in the time remaining."
- g_apszScoreGoalText[pRealm->m_ScoringMode]
- );
- break;
- case CRealm::TimedGoal:
- rcDst.sY = prc->sY + STATUS_PRINT_Y2;
- ms_print.SetDestination(pim, &rcDst);
- ms_print.print(
- rcDst.sX,
- rcDst.sY,
- // " Kill everyone before time runs out."
- g_apszScoreGoalText[pRealm->m_ScoringMode]
- );
- break;
- case CRealm::TimedFlag:
- rcDst.sY = prc->sY + STATUS_PRINT_Y2;
- ms_print.SetDestination(pim, &rcDst);
- ms_print.print(
- rcDst.sX,
- rcDst.sY,
- // " Capture the flag before time runs out."
- g_apszScoreGoalText[pRealm->m_ScoringMode]
- );
- break;
- case CRealm::Goal:
- rcDst.sY = prc->sY + STATUS_PRINT_Y2;
- ms_print.SetDestination(pim, &rcDst);
- ms_print.print(
- rcDst.sX,
- rcDst.sY,
- // " Kill %d People in as little time as possible.",
- g_apszScoreGoalText[pRealm->m_ScoringMode],
- pRealm->m_sKillsGoal
- );
- break;
- case CRealm::CaptureFlag:
- rcDst.sY = prc->sY + STATUS_PRINT_Y2;
- ms_print.SetDestination(pim, &rcDst);
- ms_print.print(
- rcDst.sX,
- rcDst.sY,
- // " Capture the flag in as little time as possible."
- g_apszScoreGoalText[pRealm->m_ScoringMode]
- );
- break;
- case CRealm::Checkpoint:
- rcDst.sY = prc->sY + STATUS_PRINT_Y2;
- ms_print.SetDestination(pim, &rcDst);
- ms_print.print(
- rcDst.sX,
- rcDst.sY,
- // " Grab as many flags as possible before time runs out."
- g_apszScoreGoalText[pRealm->m_ScoringMode]
- );
- break;
- default:
- break;
- }
- }
- // Note that we drew.
- bDrew = true;
- }
- return bDrew;
- }
- //////////////////////////////////////////////////////////////////////////////
- // ScoreDisplayStatus
- //
- // Sets the status display timer so it will show for a few seconds
- //////////////////////////////////////////////////////////////////////////////
- void ScoreDisplayStatus(CRealm* pRealm)
- {
- g_scoreboard.m_lLastStatusDrawTime = pRealm->m_time.GetGameTime();
- }
- //////////////////////////////////////////////////////////////////////////////
- // ScoreSetMode - Set mode of scoring
- //////////////////////////////////////////////////////////////////////////////
- void ScoreSetMode(CScoreboard::ScoringMode Mode)
- {
- g_scoreboard.SetScoringMode(Mode);
- }
- //////////////////////////////////////////////////////////////////////////////
- // ScoreDisplayHighScores
- //////////////////////////////////////////////////////////////////////////////
- void ScoreDisplayHighScores( // Returns nothing.
- CRealm* pRealm, // In: Realm won.
- CNetClient* pclient, // In: Client ptr for MP mode, or NULL in SP mode.
- long lMaxTimeOut) // In: Max time on score screen (quits after this
- // duration, if not -1).
- {
- RGuiItem* pguiRoot;
- RGuiItem::ms_print.SetFont(15, &g_fontPostal);
- RProcessGui guiDialog;
- short sResult;
- char szScoringExplanation[512] = "";
- long alScores[MAX_HIGH_SCORES];
- char astrNames[MAX_HIGH_SCORES][MAX_PLAYER_NAME_LEN + 1];
- char szKeyName[256];
- RPrefs scores;
- typedef enum
- {
- Value,
- Time
- } ValType;
- ValType vtScoringUnit = Value;
- // Let's just not do any of this for modes that have no scoring . . .
- if (pRealm->m_ScoringMode >= CRealm::Timed && pRealm->m_ScoringMode <= CRealm::MPLastManTimedFrag && GetInputMode() != INPUT_MODE_PLAYBACK)
- {
- // Determine player's score and note how we determined it in a string
- // for the user.
- long lPlayerScore = 0;
- switch (pRealm->m_ScoringMode)
- {
- case CRealm::Standard:
- // No high scores for this mode
- break;
- case CRealm::Timed:
- sprintf(szScoringExplanation, g_apszScoreExplanations[pRealm->m_ScoringMode], CreateTimeString(pRealm->m_lScoreInitialTime) );
- // Number of deaths.
- lPlayerScore = pRealm->m_sPopulationDeaths;
- vtScoringUnit = Value;
- break;
- case CRealm::TimedGoal:
- sprintf(szScoringExplanation, g_apszScoreExplanations[pRealm->m_ScoringMode], pRealm->m_sKillsGoal);
- // Elapsed time, if goal met.
- if (pRealm->m_sPopulationDeaths >= pRealm->m_sKillsGoal)
- {
- lPlayerScore = pRealm->m_lScoreInitialTime - pRealm->m_lScoreTimeDisplay;
- }
- else
- {
- // Really bad elapsed time.
- lPlayerScore = LONG_MAX;
- }
- vtScoringUnit = Time;
- break;
- case CRealm::TimedFlag:
- sprintf(szScoringExplanation, g_apszScoreExplanations[pRealm->m_ScoringMode], pRealm->m_sKillsGoal);
- // Elapsed time, if goal met.
- if (pRealm->m_sFlagbaseCaptured >= pRealm->m_sFlagsGoal)
- {
- lPlayerScore = pRealm->m_lScoreInitialTime - pRealm->m_lScoreTimeDisplay;
- }
- else
- {
- // Really bad elapsed time.
- lPlayerScore = LONG_MAX;
- }
- vtScoringUnit = Time;
- break;
- case CRealm::CaptureFlag:
- sprintf(szScoringExplanation, g_apszScoreExplanations[pRealm->m_ScoringMode], pRealm->m_sKillsGoal);
- // Time left, if goal met.
- if (pRealm->m_sFlagbaseCaptured >= pRealm->m_sFlagsGoal)
- {
- lPlayerScore = pRealm->m_lScoreTimeDisplay;
- }
- else
- {
- // Really bad time.
- lPlayerScore = LONG_MIN;
- }
- vtScoringUnit = Time;
- break;
- case CRealm::Goal:
- sprintf(szScoringExplanation, g_apszScoreExplanations[pRealm->m_ScoringMode], pRealm->m_sKillsGoal);
- // Time left, if goal met.
- if (pRealm->m_sPopulationDeaths >= pRealm->m_sKillsGoal)
- {
- lPlayerScore = pRealm->m_lScoreTimeDisplay;
- }
- else
- {
- // Really bad time.
- lPlayerScore = LONG_MIN;
- }
- vtScoringUnit = Time;
- break;
- case CRealm::Checkpoint:
- sprintf(szScoringExplanation, g_apszScoreExplanations[pRealm->m_ScoringMode], 0);
- // Number of flags captured.
- lPlayerScore = pRealm->m_sFlagsCaptured;
- vtScoringUnit = Value;
- break;
- case CRealm::MPTimed:
- case CRealm::MPFrag:
- case CRealm::MPLastMan:
- case CRealm::MPCaptureFlag:
- case CRealm::MPTimedFlag:
- case CRealm::MPTimedFrag:
- case CRealm::MPLastManFrag:
- case CRealm::MPLastManTimed:
- case CRealm::MPLastManTimedFrag:
- sprintf(szScoringExplanation, g_apszScoreExplanations[pRealm->m_ScoringMode], MAX_HIGH_SCORES);
- vtScoringUnit = Value;
- break;
- }
- // Get the name or description string for this realm file and use that as
- // the prefs section name from which to get the high scores. Scores are
- // stored as longs whether they be times in seconds or counts and the names
- // are stored as strings.
- // Temporarily I will base the section name on the scoring method
- // until the realm description function is available.
- short sPlayersScorePosition = -1; // Valid score index once/if we find a slot
- // for this player's score.
- // If not a multiplayer scoring . . .
- if (pRealm->m_flags.bMultiplayer == false)
- {
- // Try to open the file, but if it doesn't exist, then we simply won't be
- // getting any values from it.
- short sOpenRes = scores.Open(FullPathHD(HIGHSCORE_SCORES_FILE), "r");
-
- // Read in the scores file
- short sSrcIndex;
- short sDstIndex;
- for (sSrcIndex = 0, sDstIndex = 0; sDstIndex < MAX_HIGH_SCORES; sDstIndex++)
- {
- sprintf(szKeyName, "Player%d", sSrcIndex);
- if (sOpenRes == 0)
- scores.GetVal((char*) pRealm->m_rsRealmString, szKeyName, "<Empty>", astrNames[sDstIndex]);
- else
- strcpy(astrNames[sDstIndex], "<Empty>");
-
- // Determine if our score beat this score.
- bool bPlayerBeatThisScore = false;
- sprintf(szKeyName, "Score%d", sSrcIndex);
- // Some scoring modes need to default to zero scores, but the timed levels
- // need to default to some high, easy to beat time if there is no saved score
- if (vtScoringUnit == Value)
- {
- if (sOpenRes == 0)
- scores.GetVal((char*) pRealm->m_rsRealmString, szKeyName, (long) 0, &(alScores[sDstIndex]));
- else
- alScores[sDstIndex] = 0;
-
- // Did we get a higher value than in score?
- if (lPlayerScore > alScores[sDstIndex])
- {
- bPlayerBeatThisScore = true;
- }
- }
- else
- {
- if (sOpenRes == 0)
- scores.GetVal((char*) pRealm->m_rsRealmString, szKeyName, (long) 3600000, &(alScores[sDstIndex]));
- else
- alScores[sDstIndex] = (long) 3600000;
-
- // Did we get a better time than read in score?
- if (lPlayerScore < alScores[sDstIndex] )
- {
- bPlayerBeatThisScore = true;
- }
- }
- // If we beat this score and haven't yet found a score position . . .
- if (bPlayerBeatThisScore == true && sPlayersScorePosition < 0)
- {
- // Remember player's score.
- alScores[sDstIndex] = lPlayerScore;
- // Clear player's name.
- astrNames[sDstIndex][0] = '\0';
- // Remember player's score position.
- sPlayersScorePosition = sDstIndex;
- // Don't increment the source index.
- }
- else
- {
- // Move to the next source score val and name from the INI.
- sSrcIndex++;
- }
- }
- scores.Close();
- }
- else
- {
- ASSERT(pclient);
- long alTempScores[MAX_HIGH_SCORES];
- char astrTempNames[MAX_HIGH_SCORES][MAX_PLAYER_NAME_LEN + 1];
- short sIndex;
- for (sIndex = 0; sIndex < MAX_HIGH_SCORES ; sIndex++)
- {
- if (sIndex < pRealm->m_asClassNumThings[CThing::CDudeID])
- {
- strncpy(astrTempNames[sIndex], pclient->GetPlayerName(sIndex), MAX_PLAYER_NAME_LEN);
- // Strncpy does not NULL terminate if the 'n' is less than or equal to the length
- // of the src string.
- astrTempNames[sIndex][MAX_PLAYER_NAME_LEN] = '\0';
- alTempScores[sIndex] = g_scoreboard.m_asScores[sIndex];
- }
- else
- {
- astrTempNames[sIndex][0] = '\0';
- alTempScores[sIndex] = LONG_MIN + 1;
- }
- }
- // Find the largest score (most frags in all modes) and put it at the
- // next position.
- short sDstIndex;
- short sSrcIndex;
- short sHighestScoreIndex;
- long lHighestScore;
-
- // This declaration relies on false being zero!!
- ASSERT(false == 0);
- bool abAlreadyCopied[MAX_HIGH_SCORES] = { false, };
- for (sDstIndex = 0; sDstIndex < MAX_HIGH_SCORES; sDstIndex++)
- {
- sHighestScoreIndex = -1;
- lHighestScore = LONG_MIN;
- // Find the highest score of the ones not yet copied.
- for (sSrcIndex = 0; sSrcIndex < MAX_HIGH_SCORES; sSrcIndex++)
- {
- // If not yet copied . . .
- if (abAlreadyCopied[sSrcIndex] == false)
- {
- // If this score is higher . . .
- if (alTempScores[sSrcIndex] > lHighestScore)
- {
- sHighestScoreIndex = sSrcIndex;
- lHighestScore = alTempScores[sSrcIndex];
- }
- }
- }
- // Use the highest score.
- ASSERT(sHighestScoreIndex != -1);
- alScores[sDstIndex] = alTempScores[sHighestScoreIndex];
- // This copy is safe b/c astrTempNames[] and astrNames[] are the
- // same length.
-
- // Check for safety (future changes).
- ASSERT(sizeof(astrNames[0]) >= sizeof(astrTempNames[0]) );
- strcpy(astrNames[sDstIndex], astrTempNames[sHighestScoreIndex] );
- // Note that this score is already placed.
- abAlreadyCopied[sHighestScoreIndex] = true;
- // If this is us . . .
- if (sHighestScoreIndex == pclient->GetID() )
- {
- // Remember our position (placement) so we can highlight it.
- sPlayersScorePosition = sDstIndex;
- }
- }
- // Note that Player's score position stays -1 since there's no name to enter.
- }
- short i;
- if (rspGetResource(&g_resmgrShell, HIGHSCORE_DIALOG_FILE, (RDlg**)&pguiRoot) == 0)
- {
- RGuiItem* pguiOk = pguiRoot->GetItemFromId(1);
- RGuiItem* pguiCancel = pguiRoot->GetItemFromId(2);
- RTxt* ptextExplain1 = (RTxt*) pguiRoot->GetItemFromId(50);
- RTxt* ptextExplain2 = (RTxt*) pguiRoot->GetItemFromId(51);
- RListBox* plbScores = (RListBox*) pguiRoot->GetItemFromId(1000);
- // Set to the input field if the player gets a high score.
- RGuiItem* pguiPlayersName = NULL;
- // Create and add all score items.
- short sScoreIndex;
- bool bGotAllScoreItems = true;
- if (plbScores)
- {
- ASSERT(plbScores->m_type == RGuiItem::ListBox);
- for (sScoreIndex = 0; sScoreIndex < MAX_HIGH_SCORES && bGotAllScoreItems; sScoreIndex++)
- {
- // If there's an associated name or this is the one we're adding . . .
- if (astrNames[sScoreIndex][0] != '\0' || sPlayersScorePosition == sScoreIndex)
- {
- RGuiItem* pguiItem;
- if (rspGetResourceInstance(&g_resmgrShell, HIGHSCORE_ITEM_FILE, &pguiItem) == 0)
- {
- // Get the two settable items.
- RGuiItem* pguiName = pguiItem->GetItemFromId(100);
- RGuiItem* pguiScore = pguiItem->GetItemFromId(101);
- RGuiItem* pguiPlace = pguiItem->GetItemFromId(102);
- if (pguiName && pguiScore)
- {
- // Add shadow attributes.
- pguiName->m_sTextEffects |= RGuiItem::Shadow;
- pguiName->m_u32TextShadowColor = TEXT_SHADOW_COLOR;
- pguiScore->m_sTextEffects |= RGuiItem::Shadow;
- pguiScore->m_u32TextShadowColor = TEXT_SHADOW_COLOR;
- // If this is the place for the new name . . .
- if (sPlayersScorePosition == sScoreIndex)
- {
- // Set the focus to this item.
- pguiName->SetFocus();
- // Limit input text to the space in our storage area.
- // Must be edit field for this op.
- ASSERT(pguiName->m_type == RGuiItem::Edit);
- ((REdit*)pguiName)->m_sMaxText = sizeof(astrNames[0]) - 1;
- // Highlight this entry.
- pguiName->m_u32TextColor = TEXT_HIGHLIGHT_COLOR;
- // Remember which one so we can get the name later.
- pguiPlayersName = pguiName;
- }
- else
- {
- // Deactivate all others.
- pguiName->m_sActive = FALSE;
- }
- // Set placement.
- pguiPlace->SetText("%d)", sScoreIndex + 1);
- pguiPlace->Compose();
- // Set name.
- pguiName->SetText("%s", astrNames[sScoreIndex]);
- pguiName->Compose();
- // Set score.
- // There are two types of scores.
- if (vtScoringUnit == Value)
- {
- // Value.
- pguiScore->SetText("%ld %s", alScores[sScoreIndex], g_apszScoreUnits[pRealm->m_ScoringMode] );
- }
- else
- {
- // Time.
- pguiScore->SetText("%s %s", CreateTimeString(alScores[sScoreIndex] ), g_apszScoreUnits[pRealm->m_ScoringMode] );
- }
- pguiScore->Compose();
- // Mark item as an encapsulator. When an item is marked this way the listbox
- // knows it's okay to move it around and stuff.
- RListBox::MakeEncapsulator(pguiItem);
-
- // Add to the list box . . .
- if (plbScores->AddItem(pguiItem) )
- {
- // Success.
- }
- else
- {
- TRACE("ScoreDisplayHighScores(): Unable to add item to listbox.\n");
- bGotAllScoreItems = false;
- }
- }
- else
- {
- TRACE("ScoreDisplayHighScores(): Missing items in this instance of \"%d\".\n",
- HIGHSCORE_ITEM_FILE);
- bGotAllScoreItems = false;
- }
- }
- else
- {
- TRACE("ScoreDisplayHighScores(): Failed to get instance of \"%d\".\n",
- HIGHSCORE_ITEM_FILE);
- bGotAllScoreItems = false;
- }
- }
- }
- // Repaginate now.
- plbScores->AdjustContents();
- // If we have an entry . . .
- if (pguiPlayersName)
- {
- // Make sure it's visible . . .
- plbScores->EnsureVisible(pguiPlayersName, RListBox::Bottom);
- }
- }
- if (ptextExplain1 != NULL &&
- ptextExplain2 != NULL &&
- plbScores != NULL &&
- bGotAllScoreItems == true)
- {
- // Get some colors free.
- PalTranOn();
- // Set the callbacks for the resource load and discard (note that it
- // already tried to load it during the above rspGetResource() and failed
- // b/c the default implementation has no clue about the resmgr).
- pguiRoot->m_fnGetRes = GuiGetRes;
- pguiRoot->m_fnReleaseRes = GuiReleaseRes;
- pguiRoot->ReleaseRes();
- // Recompose the root item (does not recompose children). This time
- // it should successfully find the resources via the Get callback.
- pguiRoot->Compose();
-
- // Let us handle updates.
- guiDialog.m_fnUpdate = SysUpdate;
- // Center the GUI root.
- pguiRoot->Move(
- g_pimScreenBuf->m_sWidth / 2 - pguiRoot->m_im.m_sWidth / 2,
- g_pimScreenBuf->m_sHeight / 2 - pguiRoot->m_im.m_sHeight / 2);
- // Make the explanation texts shadowed.
- ptextExplain1->m_sTextEffects |= RGuiItem::Shadow;
- ptextExplain1->m_u32TextShadowColor = TEXT_SHADOW_COLOR;
-
- ptextExplain2->m_sTextEffects |= RGuiItem::Shadow;
- ptextExplain2->m_u32TextShadowColor = TEXT_SHADOW_COLOR;
- ptextExplain2->Compose();
- // Store current mouse show level so we can restore it.
- short sOrigShowLevel = rspGetMouseCursorShowLevel();
- // Make sure it's visible.
- // Let's not do this and instead try to insinuate keyboard use.
- // rspSetMouseCursorShowLevel(1);
- // Make sure there's no timeout on while player is adding their name.
- ms_lScoreMaxTimeOut = LONG_MAX;
- // If we want a high score from this player . . .
- if (sPlayersScorePosition >= 0 && pRealm->m_flags.bMultiplayer == false)
- {
- // Ask the player for their name.
- ptextExplain1->SetText("Please enter your name.\n");
- ptextExplain1->Compose();
- // Don't clean the screen when done so we can have a smooth transition
- // to the next DoModal().
- guiDialog.m_sFlags = RProcessGui::NoCleanScreen;
- // Do the dialog once to get the name.
- guiDialog.DoModal(pguiRoot, pguiOk, pguiCancel);
- // Clear the focus.
- RGuiItem::SetFocus(NULL);
- ASSERT(pguiPlayersName);
- // Get the user's name for saving.
- pguiPlayersName->GetText(astrNames[sPlayersScorePosition], sizeof(astrNames[sPlayersScorePosition]) );
- }
- // Set the explanation text.
- ptextExplain1->SetText("%s", szScoringExplanation);
- ptextExplain1->Compose();
- // Don't set time out time until after player has entered name for
- // reduced frustration.
- // If timeout specified . . .
- if (lMaxTimeOut >= 0)
- {
- ms_lScoreMaxTimeOut = rspGetMilliseconds() + lMaxTimeOut;
- }
- else
- {
- ms_lScoreMaxTimeOut = LONG_MAX;
- }
- // Set the focus to the listbox's vertical scrollbar so that the arrows will work.
- plbScores->m_sbVert.SetFocus();
- // This time we want the screen cleared.
- guiDialog.m_sFlags = 0;
- // Display the high scores.
- guiDialog.DoModal(pguiRoot, pguiOk, pguiCancel);
- // Restore mouse cursor show level.
- rspSetMouseCursorShowLevel(sOrigShowLevel);
- // If we got a high score . . .
- if (sPlayersScorePosition >= 0 && pRealm->m_flags.bMultiplayer == false)
- {
- RPrefs prefsScores;
- // Save the scores to the file. First we open it in read+ mode, which is
- // safe if the file already exists. If that fails, we assume the file does
- // NOT exist and we try to open it in write+ mode, which will clobber the
- // contents of the file if it does exist.
- sResult = prefsScores.Open(FullPathHD(HIGHSCORE_SCORES_FILE), "r+");
- if (sResult != SUCCESS)
- sResult = prefsScores.Open(FullPathHD(HIGHSCORE_SCORES_FILE), "w+");
- if (sResult == SUCCESS)
- {
- for (i = 0; i < MAX_HIGH_SCORES; i++)
- {
- sprintf(szKeyName, "Player%d", i);
- prefsScores.SetVal((char*) pRealm->m_rsRealmString, szKeyName, astrNames[i]);
- sprintf(szKeyName, "Score%d", i);
- prefsScores.SetVal((char*) pRealm->m_rsRealmString, szKeyName, alScores[i]);
- }
- }
- prefsScores.Close();
- }
- // Put the colors back.
- PalTranOff();
- }
- if (plbScores)
- {
- #if 0
- // Get rid of all score item instances.
- RGuiItem* pguiScoreItem = plbScores->GetFirst();
- while (pguiScoreItem)
- {
- // Remove the listbox's encapsulator property.
- pguiScoreItem->RemoveProp(ENCAPSULATOR_PROP_KEY);
- // Release the current one.
- rspReleaseResourceInstance(&g_resmgrShell, &pguiScoreItem);
- // Set the next one as the current.
- pguiScoreItem = plbScores->GetNext();
- }
- #else
- plbScores->RemoveAll();
- #endif
- }
-
- rspReleaseResource(&g_resmgrShell, &pguiRoot);
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- // ScoreHighestKills
- //
- // Return the highest number of kills among all of the players. This will
- // be called to determine if a frag limit level is over.
- //
- //////////////////////////////////////////////////////////////////////////////
- short ScoreHighestKills(CRealm* pRealm)
- {
- short sHighest = 0;
- short sNumDudes = pRealm->m_asClassNumThings[CThing::CDudeID];
- short i;
- for (i = 0; i < sNumDudes; i++)
- {
- if (g_scoreboard.m_asScores[i] > sHighest)
- sHighest = g_scoreboard.m_asScores[i];
- }
-
- return sHighest;
- }
- //////////////////////////////////////////////////////////////////////////////
- // EOF
- //////////////////////////////////////////////////////////////////////////////
|