| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513 |
- /*
- ** Command & Conquer Renegade(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** 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, see <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** Confidential - Westwood Studios ***
- ***********************************************************************************************
- * *
- * Project Name : Commando *
- * *
- * $Archive:: /Commando/Code/Commando/gamedata.cpp $*
- * *
- * $Author:: Steve_t $*
- * *
- * $Modtime:: 11/01/02 4:32p $*
- * *
- * $Revision:: 221 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "gamedata.h"
- #include <stdio.h>
- #include <string.h>
- #include "win.h"
- #include "miscutil.h"
- #include "cnetwork.h"
- #include "chatshre.h"
- #include "wwdebug.h"
- #include "netinterface.h"
- #include "translatedb.h"
- #include "playertype.h"
- #include "teammanager.h"
- #include "playermanager.h"
- #include "assets.h"
- #include "translatedb.h"
- #include "string_ids.h"
- #include "gamemode.h"
- #include "savegame.h"
- #include "bandwidth.h"
- #include "gametype.h"
- #include "systimer.h"
- #include "objlibrary.h"
- #include "scriptzone.h"
- #include "aabox.h"
- #include "rendobj.h"
- #include "weaponbag.h"
- #include "multihud.h"
- #include "wwaudio.h"
- #include "textdisplay.h"
- #include "render2d.h"
- #include "render2dsentence.h"
- #include "wwprofile.h"
- #include "winevent.h"
- #include "realcrc.h"
- #include "useroptions.h"
- #include "gdsingleplayer.h"
- #include "gdcnc.h"
- #include "wolgmode.h"
- #include "font3d.h"
- #include "nat.h"
- #include "csdamageevent.h"
- #include "sctextobj.h"
- #include "widestring.h"
- #include "vehicle.h"
- #include "wolgameinfo.h"
- #include "spawn.h"
- #include "dlgcncwinscreen.h"
- #include "dialogmgr.h"
- #include "rawfile.h"
- #include "consolemode.h"
- #include "gamedataupdateevent.h"
- #include "stylemgr.h"
- #include "modpackagemgr.h"
- #include "modpackage.h"
- #include "bandwidthcheck.h"
- #include "serversettings.h"
- #include "gamespyadmin.h"
- #include "specialbuilds.h"
- #include "demosupport.h"
- #include "specialbuilds.h"
- const int cGameData::MAX_TIME_LIMIT = 999;
- cGameData * PTheGameData = NULL;
- static WideStringClass renderer_time_text;
- static WideStringClass renderer_dedicated_server_label;
- static WideStringClass renderer_gameplay_label;
- static unsigned renderer_dedicated_server_color;
- static unsigned renderer_gameplay_color;
- //
- // Class statics
- //
- const StringClass cGameData::INI_SECTION_NAME = "Settings";
- const float cGameData::LIMITS_X_POS = 0.8f;
- Render2DSentenceClass * cGameData::PTextRenderer = NULL;
- int cGameData::HostedGameNumber = 0;
- bool cGameData::IsManualRestart = false;
- bool cGameData::IsManualExit = false;
- WideStringClass cGameData::WinText;
- //
- // hack
- //
- ULONG g_ip_override = INADDR_NONE;
- //------------------------------------------------------------------------------------
- void cGameData::Onetime_Init(void)
- {
- WWDEBUG_SAY(("cGameData::Onetime_Init\n"));
- if (!ConsoleBox.Is_Exclusive()) {
- PTextRenderer = new Render2DSentenceClass;
- StyleMgrClass::Assign_Font(PTextRenderer, StyleMgrClass::FONT_INGAME_TXT);
- PTextRenderer->Set_Mono_Spaced(true);
- PTextRenderer->Set_Clipping_Rect(Render2DClass::Get_Screen_Resolution());
- }
- }
- //------------------------------------------------------------------------------------
- void cGameData::Onetime_Shutdown(void)
- {
- WWDEBUG_SAY(("cGameData::Onetime_Shutdown\n"));
- if (!ConsoleBox.Is_Exclusive()) {
- WWASSERT(PTextRenderer != NULL);
- delete PTextRenderer;
- PTextRenderer = NULL;
- }
- }
- //-----------------------------------------------------------------------------
- cGameData::cGameData(void) :
- DoExeVersionsMatch (true),
- DoStringVersionsMatch (true),
- DoMapsLoop (true),
- IsMapCycleOver (false),
- MapCycleIndex(0)
- {
- //WWDEBUG_SAY(("cGameData::cGameData\n"));
- IsIntermission.Set( false);
- IsDedicated.Set( false);
- IsAutoRestart.Set( false);
- IsFriendlyFirePermitted.Set( false);
- IsTeamChangingAllowed.Set( true);
- IsPassworded.Set( false);
- IsFreeWeapons.Set( false);
- IsLaddered.Set( false);
- IsClanGame.Set( false);
- IsClientTrusted.Set( true);
- RemixTeams.Set( false);
- CanRepairBuildings.Set( true);
- DriverIsAlwaysGunner.Set( true);
- SpawnWeapons.Set( false);
- mWinnerID = -1;
- MaxPlayers = 16;
- TimeLimitMinutes = 0;
- RadarMode = RADAR_ALL;
- IniFilename = "";
- Motd.Format(L"");
- Set_Password( L"");
- //Set_Owner( "UNOWNED");
- Set_Owner( cNetInterface::Get_Nickname());
- IntermissionTimeSeconds = 15;
- Set_Version_Number( cNetwork::Get_Exe_Key());
- Set_Ip_Address(0);
- Set_Port( 4848);//TSS - hardcoded port
- Set_Current_Players(0);
- IntermissionTimeRemaining = 0;
- TimeRemainingSeconds = 0;
- MaximumWorldDistance = 0;
- MinQualifyingTimeMinutes = 2;
- IsQuickMatchServer = false;
- //ServerIsGameplayPermitted = false;
- WinType = WIN_TYPE_TIME;
- GameDurationS = 0;
- LastServerConfigModTime = 0;
- SettingsDescription = TRANSLATE(IDS_SERVER_SAVELOAD_CUSTOM_DEFAULT);
- Clear_Clans();
- MvpCount = 0;
- #ifdef MULTIPLAYERDEMO
- MapName.Format("C&C_Under.mix");
- #endif // MULTIPLAYERDEMO
- }
- //-----------------------------------------------------------------------------
- cGameData::~cGameData(void)
- {
- //WWDEBUG_SAY(("cGameData::~cGameData\n"));
- }
- //-----------------------------------------------------------------------------
- cGameData& cGameData::operator=(const cGameData& rhs)
- {
- IsIntermission = rhs.IsIntermission;
- IsDedicated = rhs.IsDedicated;
- IsAutoRestart = rhs.IsAutoRestart;
- IsFriendlyFirePermitted = rhs.IsFriendlyFirePermitted;
- IsTeamChangingAllowed = rhs.IsTeamChangingAllowed;
- IsPassworded = rhs.IsPassworded;
- IsFreeWeapons = rhs.IsFreeWeapons;
- IsLaddered = rhs.IsLaddered;
- IsClanGame = rhs.IsClanGame;
- IsClientTrusted = rhs.IsClientTrusted;
- RemixTeams = rhs.RemixTeams;
- CanRepairBuildings = rhs.CanRepairBuildings;
- DriverIsAlwaysGunner = rhs.DriverIsAlwaysGunner;
- SpawnWeapons = rhs.SpawnWeapons;
- Password = rhs.Password;
- GameTitle = rhs.GameTitle;
- Motd = rhs.Motd;
- #ifdef MULTIPLAYERDEMO
- MapName.Format("C&C_Under.mix");
- #else
- MapName = rhs.MapName;
- ModName = rhs.ModName;
- #endif
- Owner = rhs.Owner;
- MaxPlayers = rhs.MaxPlayers;
- TimeLimitMinutes = rhs.TimeLimitMinutes;
- IntermissionTimeSeconds = rhs.IntermissionTimeSeconds;
- VersionNumber = rhs.VersionNumber;
- IpAddress = rhs.IpAddress;
- Port = rhs.Port;
- IniFilename = rhs.IniFilename;
- RadarMode = rhs.RadarMode;
- CurrentPlayers = rhs.CurrentPlayers;
- IntermissionTimeRemaining = rhs.IntermissionTimeRemaining;
- TimeRemainingSeconds = rhs.TimeRemainingSeconds;
- MaximumWorldDistance = rhs.MaximumWorldDistance;
- MinQualifyingTimeMinutes = rhs.MinQualifyingTimeMinutes;
- for (int clanSlot = 0; clanSlot < MAX_CLAN_SLOTS; ++clanSlot) {
- mClanSlots[clanSlot] = rhs.mClanSlots[clanSlot];
- }
- return (*this);
- }
- //-----------------------------------------------------------------------------
- void cGameData::Reset_Game(bool is_reloaded)
- {
- WWDEBUG_SAY(("cGameData::Reset_Game\n"));
- //
- // Game_Reset is called on both C & S at the beginning of every game.
- //
- mWinnerID = -1;
- IsIntermission.Set(false);
- //
- // 12/11/01
- // This dialog flush was added to remove the purchase screen because it persists
- // over reload.
- //
- if (GameModeManager::Find ("Combat")->Is_Active ()) {
- if (GameModeManager::Find ("Menu")->Is_Active ()) {
- GameModeManager::Find ("Menu")->Deactivate ();
- } else {
- DialogMgrClass::Flush_Dialogs ();
- }
- }
- if (Get_Text_Display()) {
- WWASSERT(Get_Text_Display() != NULL);
- Get_Text_Display()->Flush();
- }
- if (!IS_MISSION) {
- WWAudioClass::Get_Instance()->Create_Instant_Sound("Game_Start", Matrix3D(1));
- }
- //TSS092601 if ( !is_reloaded ) {
- if ( !IS_MISSION || !is_reloaded ) {
- cPlayerManager::Reset_Players();
- }
- //}
- cTeamManager::Reset_Teams();
- if (Is_Time_Limit()) {
- Reset_Time_Remaining_Seconds();
- if (cNetwork::I_Am_Server()) {
- cGameDataUpdateEvent * p_event = new cGameDataUpdateEvent();
- p_event->Init(-1);
- }
- }
- if (cNetwork::I_Am_Server())
- {
- HostedGameNumber++;
- }
- }
- //-----------------------------------------------------------------------------
- void cGameData::Swap_Team_Sides(void)
- {
- //WWASSERT(Is_Team_Game());
- WWASSERT(cNetwork::I_Am_Server());
- for (
- SLNode<cPlayer> * player_node = cPlayerManager::Get_Player_Object_List()->Head();
- player_node;
- player_node = player_node->Next()) {
- cPlayer * p_player = player_node->Data();
- WWASSERT(p_player != NULL);
- int team = p_player->Get_Player_Type();
- WWASSERT(team == PLAYERTYPE_NOD || team == PLAYERTYPE_GDI);
- int new_team = PLAYERTYPE_NOD;
- if (team == PLAYERTYPE_NOD)
- {
- new_team = PLAYERTYPE_GDI;
- }
- else
- {
- new_team = PLAYERTYPE_NOD;
- }
- p_player->Set_Player_Type(new_team);
- }
- //
- // Inform the players
- //
- //WideStringClass text;
- //text.Format(L"_TEAMS_SWAPPED_!_");
- WideStringClass text = TRANSLATE(IDS_MP_TEAMS_SWAPPED);
- cScTextObj * p_text_obj = new cScTextObj();
- p_text_obj->Init(text, TEXT_MESSAGE_PUBLIC, false, HOST_TEXT_SENDER, -1);
- }
- //-----------------------------------------------------------------------------
- void cGameData::Remix_Team_Sides(void)
- {
- //WWASSERT(Is_Team_Game());
- WWASSERT(cNetwork::I_Am_Server());
- WWASSERT(IsClanGame.Is_False() && "Remix teams not allowed");
- if (IsClanGame.Is_True()) {
- return;
- }
- //
- // Randomly choose a team for each player
- //
- for (
- SLNode<cPlayer> * player_node = cPlayerManager::Get_Player_Object_List()->Head();
- player_node;
- player_node = player_node->Next()) {
- cPlayer * p_player = player_node->Data();
- WWASSERT(p_player != NULL);
- int new_team = PLAYERTYPE_NOD;
- if (rand() % 2 == 0)
- {
- new_team = PLAYERTYPE_GDI;
- }
- else
- {
- new_team = PLAYERTYPE_NOD;
- }
- p_player->Set_Player_Type(new_team);
- }
- //
- // Inform the players
- //
- //WideStringClass text;
- //text.Format(L"_TEAMS_REMIXED_!_");
- WideStringClass text = TRANSLATE(IDS_MP_TEAMS_REMIXED);
- cScTextObj * p_text_obj = new cScTextObj();
- p_text_obj->Init(text, TEXT_MESSAGE_PUBLIC, false, HOST_TEXT_SENDER, -1);
- }
- //-----------------------------------------------------------------------------
- void cGameData::Rebalance_Team_Sides(void)
- {
- //WWASSERT(Is_Team_Game());
- WWASSERT(cNetwork::I_Am_Server());
- WWASSERT(IsClanGame.Is_False() && "Rebalance teams not allowed");
- if (IsClanGame.Is_True()) {
- return;
- }
- //
- // Rebalance teams numerically
- //
- cTeam * p_nod = cTeamManager::Find_Team(PLAYERTYPE_NOD);
- WWASSERT(p_nod != NULL);
- cTeam * p_gdi = cTeamManager::Find_Team(PLAYERTYPE_GDI);
- WWASSERT(p_gdi != NULL);
- int move_count = 0;
- int nod_tally = 0;
- int gdi_tally = 0;
- do
- {
- nod_tally = p_nod->Tally_Size();
- gdi_tally = p_gdi->Tally_Size();
- if (nod_tally > gdi_tally + 1)
- {
- cPlayer * p_player = cPlayerManager::Find_Team_Player(PLAYERTYPE_NOD);
- WWASSERT(p_player != NULL);
- p_player->Set_Player_Type(PLAYERTYPE_GDI);
- move_count++;
- }
- else if (gdi_tally > nod_tally + 1)
- {
- cPlayer * p_player = cPlayerManager::Find_Team_Player(PLAYERTYPE_GDI);
- WWASSERT(p_player != NULL);
- p_player->Set_Player_Type(PLAYERTYPE_NOD);
- move_count++;
- }
- } while (::abs(nod_tally - gdi_tally) > 1);
- if (move_count > 0) {
- //
- // Inform the players
- //
- //WideStringClass text;
- //text.Format(L"_TEAMS_REBALANCED_!_");
- WideStringClass text = TRANSLATE(IDS_MP_TEAMS_REBALANCED);
- cScTextObj * p_text_obj = new cScTextObj();
- p_text_obj->Init(text, TEXT_MESSAGE_PUBLIC, false, HOST_TEXT_SENDER, -1);
- }
- }
- //-----------------------------------------------------------------------------
- void cGameData::Set_Ip_And_Port(void)
- {
- /*
- SOCKADDR_IN local_address;
- bool retcode = cNetUtil::Get_Local_Address(&local_address);
- WWASSERT(retcode == true);
- //
- // hack
- //
- if (g_ip_override != INADDR_NONE) {
- local_address.sin_addr.s_addr = g_ip_override;
- }
- Set_Ip_Address(local_address.sin_addr.s_addr);
- */
- ULONG ip = 0;
- if (cGameSpyAdmin::Get_Is_Server_Gamespy_Listed()) {
- ip = cUserOptions::PreferredGameSpyNic.Get();
- } else {
- ip = cUserOptions::PreferredLanNic.Get();
- }
- if (g_ip_override != INADDR_NONE) {
- ip = g_ip_override;
- }
- //
- // IP is set automatically in WOL unless there is an IP override and a port overrride.
- //
- if (GameModeManager::Find("WOL")->Is_Active()) {
- if (g_ip_override == INADDR_NONE || WOLNATInterface.Get_Force_Port() == 0) {
- unsigned long temp = FirewallHelper.Get_Local_Address();
- if (temp) {
- //ip = temp;
- ip = ::ntohl(temp);
- }
- }
- }
- //WWASSERT(ip != 0);
- Set_Ip_Address(ip);
- }
- //-----------------------------------------------------------------------------
- //
- // A convenience function...
- //
- bool cGameData::Set_Generic_Num(int generic_num,
- int lower_bound, int upper_bound, int & set_num)
- {
- if (generic_num >= lower_bound && generic_num <= upper_bound) {
- set_num = generic_num;
- return true;
- } else {
- return false;
- }
- }
- //-----------------------------------------------------------------------------
- bool cGameData::Set_Max_Players(int max)
- {
- return Set_Generic_Num(max, 0, MAX_PLAYERS, MaxPlayers);
- }
- //-----------------------------------------------------------------------------
- bool cGameData::Set_Time_Limit_Minutes(int time_limit_minutes)
- {
- return Set_Generic_Num(time_limit_minutes, 0, MAX_TIME_LIMIT, TimeLimitMinutes);
- }
- //-----------------------------------------------------------------------------
- void cGameData::Set_Radar_Mode(RadarModeEnum mode)
- {
- RadarMode = mode;
- }
- //-----------------------------------------------------------------------------
- void cGameData::Set_Intermission_Time_Seconds(int time)
- {
- WWASSERT(time >= 0);
- IntermissionTimeSeconds = time;
- }
- //-----------------------------------------------------------------------------
- void cGameData::Set_Motd(const WCHAR * motd)
- {
- WWASSERT(motd != NULL);
- Motd = motd;
- }
- //-----------------------------------------------------------------------------
- void cGameData::Set_Mod_Name(const StringClass &mod_name)
- {
- ModName = mod_name;
- ModPackageMgrClass::Set_Current_Package (ModName);
- return ;
- }
- //-----------------------------------------------------------------------------
- void cGameData::Set_Map_Name(const StringClass & map_name)
- {
- #ifdef MULTIPLAYERDEMO
- MapName.Format("C&C_Under.mix");
- #else
- MapName = map_name;
- #endif
- }
- //-----------------------------------------------------------------------------
- bool cGameData::Set_Current_Players(int current)
- {
- return Set_Generic_Num(current, 0, MAX_PLAYERS, CurrentPlayers);
- }
- //-----------------------------------------------------------------------------
- void cGameData::Set_Owner(WideStringClass & owner)
- {
- Owner = owner;
- }
- //-----------------------------------------------------------------------------
- void cGameData::Set_Ip_Address(ULONG ip_address)
- {
- IpAddress = ip_address;
- }
- //-----------------------------------------------------------------------------
- void cGameData::Set_Port(int port)
- {
- WWASSERT(port >= MIN_SERVER_PORT && port <= MAX_SERVER_PORT);
- Port = port;
- }
- //-----------------------------------------------------------------------------
- bool cGameData::Is_Limited(void) const
- {
- return Is_Time_Limit();
- }
- //-----------------------------------------------------------------------------
- bool cGameData::Is_Map_Valid(char **out_filename)
- {
- bool map_exists = false;
- if (ModName.Is_Empty () == false) {
- if (out_filename) {
- *out_filename = ModName.Peek_Buffer();
- }
- map_exists = cMiscUtil::File_Exists (ModName);
- } else {
- if (out_filename) {
- *out_filename = MapName.Peek_Buffer();
- }
- map_exists = cMiscUtil::File_Exists (MapName);
- }
- return(map_exists);
- }
- #define PRINT_CONFIG_ERROR ConsoleBox.Print("File %s - Error:\r\n\t ", Get_Ini_Filename());
- //-----------------------------------------------------------------------------
- bool cGameData::Is_Valid_Settings(WideStringClass& outMsg, bool check_as_server)
- {
- if (MapName.Is_Empty()) {
- //cHelpText::Set(TRANSLATION(IDS_MP_NO_LEVEL_SELECTED));
- Debug_Say(( "cGameData::No level file selected.\n" ));
- PRINT_CONFIG_ERROR;
- ConsoleBox.Print("No initial level file selected\n\n");
- outMsg = TRANSLATE(IDS_HOPTERR_NO_LEVEL);
- return false;
- } else {
- //
- // Test to see whether or not the map exists
- //
- char *filename = NULL;
- if (!Is_Map_Valid(&filename)) {
- Debug_Say(("cGameData::Is_Valid_Settings: Level \"%s\" not found\n", filename));
- PRINT_CONFIG_ERROR;
- ConsoleBox.Print("Map file '%s' not found\n\n", filename);
- outMsg.Format(TRANSLATE(IDS_HOPTERR_MAP_NOTFOUND), filename);
- return(false);
- }
- }
- if (IsPassworded.Is_True() && Password.Get_Length () == 0) {
- //cHelpText::Set(TRANSLATION(IDS_MP_BLANK_PASSWORD_ILLEGAL));
- Debug_Say(( "cGameData::Is_Valid_Settings: You can not use a blank password.\n" ));
- PRINT_CONFIG_ERROR;
- ConsoleBox.Print("Blank passwords are not allowed\n\n");
- outMsg = TRANSLATE(IDS_HOPTERR_BLANK_PASS);
- return false;
- }
- #ifndef FREEDEDICATEDSERVER
- if (GameModeManager::Find("WOL")->Is_Active()) {
- #endif //FREEDEDICATEDSERVER
- if (IsPassworded.Is_True() && Is_QuickMatch_Server()) {
- Debug_Say(("cGameData::Is_Valid_Settings: Quickmatch can not have passwords.\n" ));
- PRINT_CONFIG_ERROR;
- ConsoleBox.Print("A password cannot be used on a Quickmatch server\n\n");
- outMsg = TRANSLATE(IDS_HOPTERR_QM_HASPASS);
- return false;
- }
- if (Is_QuickMatch_Server() && IsLaddered.Is_False()) {
- Debug_Say(("cGameData::Is_Valid_Settings: Quickmatch must be laddered.\n" ));
- PRINT_CONFIG_ERROR;
- ConsoleBox.Print("A Quickmatch server must also be laddered\n\n");
- outMsg = TRANSLATE(IDS_HOPTERR_QM_NOLADDER);
- return false;
- }
- if (Is_QuickMatch_Server() && IsClanGame.Is_True()) {
- Debug_Say(("cGameData::Is_Valid_Settings: Quickmatch cannot be clanned.\n" ));
- PRINT_CONFIG_ERROR;
- ConsoleBox.Print("Clans are not allowed in a quickmatch server\n\n");
- outMsg = TRANSLATE(IDS_HOPTERR_QM_NOCLANS);
- return false;
- }
- if (IsLaddered.Is_True() && IsTeamChangingAllowed.Is_True()) {
- PRINT_CONFIG_ERROR;
- ConsoleBox.Print("Team changing not allowed on a laddered server\n\n");
- outMsg = TRANSLATE(IDS_HOPTERR_NO_TEAMCHANGE);
- return false;
- }
- if (IsClanGame.Is_True() && (IsTeamChangingAllowed.Is_True() || RemixTeams.Is_True())) {
- PRINT_CONFIG_ERROR;
- ConsoleBox.Print("Team changing or Team Remix not allowed on a clan game server.\n");
- outMsg = "Team changing or Team Remix not allowed on a clan game server."; //TRANSLATE(IDS_HOPTERR_NO_TEAMCHANGE);
- return false;
- }
- #ifndef FREEDEDICATEDSERVER
- }
- #endif //FREEDEDICATEDSERVER
- #ifdef FREEDEDICATEDSERVER
- if (Get_Max_Players() == 0 && ServerSettingsClass::Get_Game_Mode() !=
- ServerSettingsClass::MODE_WOL) {
- #else
- if (Get_Max_Players() == 0) {
- #endif
- PRINT_CONFIG_ERROR;
- ConsoleBox.Print("Max player count must be greater than 0\n\n");
- outMsg = TRANSLATE(IDS_HOPTERR_MAXPLAYER_0);
- return(false);
- }
- // Check server only parameters
- if (check_as_server || ConsoleBox.Is_Exclusive()) {
- if (Get_Max_Players() > NetworkObjectClass::MAX_CLIENT_COUNT-1) {
- PRINT_CONFIG_ERROR;
- ConsoleBox.Print("Max player count must be less than %d\n\n", NetworkObjectClass::MAX_CLIENT_COUNT);
- outMsg.Format(TRANSLATE(IDS_HOPTERR_MAXPLAYER_TOOBIG), NetworkObjectClass::MAX_CLIENT_COUNT);
- return(false);
- }
- if (DoMapsLoop && Get_Map_Cycle(0).Get_Length() == 0) {
- PRINT_CONFIG_ERROR;
- ConsoleBox.Print("Map cycling is enabled but there are no maps in the cycle\n\n");
- outMsg = TRANSLATE(IDS_HOPTERR_NO_MAPCYCLE);
- return(false);
- }
- /*
- ** Make sure all the maps exist.
- */
- if (DoMapsLoop && ModName.Is_Empty ()) {
- for (int i=0 ; i<MAX_MAPS ; i++) {
- StringClass map_name = Get_Map_Cycle(i);
- if (map_name.Get_Length()) {
- char filename[_MAX_PATH];
- sprintf(filename, "data\\%s", map_name.Peek_Buffer());
- RawFileClass file(filename);
- if (!file.Is_Available()) {
- PRINT_CONFIG_ERROR;
- ConsoleBox.Print("Map file '%s' not found\n\n", filename);
- outMsg.Format(TRANSLATE(IDS_HOPTERR_MAP_NOTFOUND), filename);
- return(false);
- }
- }
- }
- }
- /*
- ** Check the game end conditions.
- */
- if (!Is_Limited()) {
- //cHelpText::Set(TRANSLATION(IDS_MP_GAMEMODE_NEEDS_LIMIT));
- PRINT_CONFIG_ERROR;
- ConsoleBox.Print("Game must end by time limit or base destruction\n\n");
- outMsg = TRANSLATE(IDS_HOPTERR_NO_GAMEEND);
- return false;
- }
- /*
- ** Check the Message of the day for excessive length.
- */
- if (Motd.Get_Length() > MAX_MOTD_LENGTH) {
- PRINT_CONFIG_ERROR;
- ConsoleBox.Print("Message of the day cannot exceed %d characters\n\n", MAX_MOTD_LENGTH);
- outMsg.Format(TRANSLATE(IDS_HOPTERR_MOTD_TOOBIG), MAX_MOTD_LENGTH);
- return false;
- }
- /*
- ** Check the game title for length. The buffers are pretty much all 256 bytes but 100 seems a more reasonable figure.
- */
- if (GameTitle.Get_Length() > 100) {
- PRINT_CONFIG_ERROR;
- ConsoleBox.Print("Game title cannot exceed %d characters\n\n", 100);
- outMsg.Format(TRANSLATE(IDS_HOPTERR_TITLE_TOOBIG), 100);
- return false;
- }
- }
- return true; // it's valid !
- }
- //-----------------------------------------------------------------------------
- //
- // Server options are exported in 2 tiers. Tier 1 is the basic parameters
- // that show up in the list of games. Tier 2 is the remainder of the full
- // set of server settings.
- //
- void cGameData::Export_Tier_1_Data(cPacket & packet)
- {
- packet.Add(IpAddress);
- packet.Add_Wide_Terminated_String(Owner);
- packet.Add_Wide_Terminated_String(GameTitle, true);
- packet.Add(Port);
- packet.Add(CurrentPlayers);
- packet.Add(MaxPlayers);
- packet.Add(VersionNumber);
- //
- // Send the individual CRC's (for internal use)
- //
- packet.Add(cNetwork::Get_Exe_CRC ());
- packet.Add(cNetwork::Get_Strings_CRC ());
- packet.Add(IsDedicated.Get());
- packet.Add(IsTeamChangingAllowed.Get());
- packet.Add(IsPassworded.Get());
- packet.Add(IsLaddered.Get());
- packet.Add(IsClanGame.Get());
- #ifndef MULTIPLAYERDEMO
- packet.Add(::CRC_Stringi(MapName));
- packet.Add(::CRC_Stringi(ModName));
- #endif // MULTIPLAYERDEMO
- }
- //-----------------------------------------------------------------------------
- void cGameData::Import_Tier_1_Data(cPacket & packet)
- {
- ULONG ip_address = packet.Get(ip_address);
- Set_Ip_Address(ip_address);
- WideStringClass owner;
- packet.Get_Wide_Terminated_String(owner.Get_Buffer(256), 256);
- Set_Owner(owner);
- WideStringClass title;
- packet.Get_Wide_Terminated_String(title.Get_Buffer(256), 256, true);
- Set_Game_Title(title);
- int i_placeholder;
- bool b_placeholder;
- Set_Port( packet.Get(i_placeholder));
- Set_Current_Players( packet.Get(i_placeholder));
- Set_Max_Players( packet.Get(i_placeholder));
- Set_Version_Number( packet.Get(i_placeholder));
- //
- // Compare the individual CRC's against our own
- //
- DoExeVersionsMatch = (packet.Get(i_placeholder) == cNetwork::Get_Exe_CRC ());
- DoStringVersionsMatch = (packet.Get(i_placeholder) == cNetwork::Get_Strings_CRC ());
- IsDedicated.Set( packet.Get(b_placeholder));
- IsTeamChangingAllowed.Set( packet.Get(b_placeholder));
- IsPassworded.Set( packet.Get(b_placeholder));
- IsLaddered.Set( packet.Get(b_placeholder));
- IsClanGame.Set( packet.Get(b_placeholder));
- #ifndef MULTIPLAYERDEMO
- //
- // Get the CRC of the map and the mod
- //
- ULONG map_name_crc = packet.Get(map_name_crc);
- ULONG mod_name_crc = packet.Get(mod_name_crc);
- //
- // Determine what the name of the mod and the map are from their CRC's
- //
- StringClass mod_name(0,true);
- StringClass map_name(0,true);
- if (ModPackageMgrClass::Get_Mod_Map_Name_From_CRC (mod_name_crc, map_name_crc, &mod_name, &map_name)) {
- Set_Mod_Name (mod_name);
- Set_Map_Name (map_name);
- } else {
- ModName = L"";
- MapName = L"";
- }
- #endif // MULTIPLAYERDEMO
- return ;
- }
- //-----------------------------------------------------------------------------
- bool cGameData::Does_Map_Exist (void)
- {
- bool retval = true;
- //
- // If the map and mod names are empty then it is due to the fact
- // that we couldn't find the map and/or mod when we looked
- //
- if (ModName.Is_Empty () && MapName.Is_Empty ()) {
- retval = false;
- }
- return retval;
- }
- //-----------------------------------------------------------------------------
- void cGameData::Import_Tier_1_Data(const WOLGameInfo& gameInfo)
- {
- Set_Map_Name(gameInfo.MapName());
- Set_Mod_Name(gameInfo.ModName());
- WideStringClass title(0, true);
- title.Convert_From(gameInfo.Title());
- Set_Game_Title(title);
- Set_Max_Players(gameInfo.MaxPlayers());
- Set_Current_Players(gameInfo.NumPlayers());
- // Set game flags
- IsDedicated.Set(gameInfo.IsDedicated());
- IsPassworded.Set(gameInfo.IsPassworded());
- IsLaddered.Set(gameInfo.IsLaddered());
- IsFriendlyFirePermitted.Set(gameInfo.IsFriendlyFire());
- IsFreeWeapons.Set(gameInfo.IsFreeWeapons());
- RemixTeams.Set(gameInfo.IsTeamRemix());
- IsTeamChangingAllowed.Set(gameInfo.IsTeamChange());
- IsClanGame.Set(gameInfo.IsClanGame());
- IsQuickMatchServer = gameInfo.IsQuickmatch();
- CanRepairBuildings.Set(gameInfo.IsRepairBuildings());
- DriverIsAlwaysGunner.Set(gameInfo.IsDriverGunner());
- SpawnWeapons.Set(gameInfo.IsSpawnWeapons());
- Clear_Clans();
- mClanSlots[0] = gameInfo.ClanID1();
- mClanSlots[1] = gameInfo.ClanID2();
- }
- //-----------------------------------------------------------------------------
- void cGameData::Export_Tier_2_Data(cPacket & packet)
- {
- packet.Add(TimeLimitMinutes);
- packet.Add((int) RadarMode);
- packet.Add(IntermissionTimeSeconds);
- packet.Add(MinQualifyingTimeMinutes);
- packet.Add(IsFriendlyFirePermitted.Get());
- packet.Add(IsFreeWeapons.Get());
- packet.Add(IsClientTrusted.Get());
- packet.Add(RemixTeams.Get());
- if (Is_Cnc()) {
- packet.Add(CanRepairBuildings.Get());
- packet.Add(DriverIsAlwaysGunner.Get());
- packet.Add(SpawnWeapons.Get());
- }
- packet.Add_Wide_Terminated_String(Motd, true);
- }
- //-----------------------------------------------------------------------------
- void cGameData::Import_Tier_2_Data(cPacket & packet)
- {
- int i_placeholder = 0;
- bool b_placeholder = false;
- Set_Time_Limit_Minutes( packet.Get(i_placeholder));
- Set_Radar_Mode((RadarModeEnum) packet.Get(i_placeholder));
- Set_Intermission_Time_Seconds( packet.Get(i_placeholder));
- Set_Min_Qualifying_Time_Minutes( packet.Get(i_placeholder));
- IsFriendlyFirePermitted.Set( packet.Get(b_placeholder));
- IsFreeWeapons.Set( packet.Get(b_placeholder));
- IsClientTrusted.Set( packet.Get(b_placeholder));
- RemixTeams.Set( packet.Get(b_placeholder));
- if (Is_Cnc()) {
- CanRepairBuildings.Set( packet.Get(b_placeholder));
- DriverIsAlwaysGunner.Set( packet.Get(b_placeholder));
- SpawnWeapons.Set( packet.Get(b_placeholder));
- }
- WideStringClass motd;
- packet.Get_Wide_Terminated_String(motd.Get_Buffer(MAX_MOTD_LENGTH), MAX_MOTD_LENGTH, true);
- Set_Motd(motd);
- }
- //-----------------------------------------------------------------------------
- void cGameData::Load_From_Server_Config(LPCSTR config_file)
- {
- WWASSERT(config_file != NULL);
- WWASSERT(cMiscUtil::Is_String_Different(config_file, ""));
- INIClass * p_ini = Get_INI(config_file);
- StringClass full_filename(config_file, true);
- if (p_ini == NULL) {
- full_filename.Format("data\\%s", config_file);
- FILE * file = fopen(full_filename, "w");
- fclose(file);
- p_ini = Get_INI(config_file);
- }
- WWASSERT(p_ini != NULL);
- LastServerConfigModTime = Get_Config_File_Mod_Time();
- char map_name[MAX_MAPNAME_SIZE];
- char mod_name[MAX_MAPNAME_SIZE];
- char string8[256];
- bool b;
- int i;
- //float f;
- //p_ini->Get_String( INI_SECTION_NAME, "Password", Get_Password(), password, sizeof(password));
- //Set_Password(password);
- p_ini->Get_String( INI_SECTION_NAME, "MapName", "", map_name, sizeof(map_name));
- StringClass map(map_name,true);
- Set_Map_Name(map);
- p_ini->Get_String( INI_SECTION_NAME, "ModName", "", mod_name, sizeof(mod_name));
- StringClass mod(mod_name,true);
- Set_Mod_Name(mod);
- i = p_ini->Get_Int( INI_SECTION_NAME, "TimeLimitMinutes", Get_Time_Limit_Minutes());
- Set_Time_Limit_Minutes(i);
- i = p_ini->Get_Int( INI_SECTION_NAME, "RadarMode", Get_Radar_Mode());
- Set_Radar_Mode((RadarModeEnum) i);
- //i = p_ini->Get_Int( INI_SECTION_NAME, "IntermissionTimeSeconds", Get_Intermission_Time_Seconds());
- //Set_Intermission_Time_Seconds(i);
- #ifndef FREEDEDICATEDSERVER
- i = p_ini->Get_Int( INI_SECTION_NAME, "Port", Get_Port());
- Set_Port(i);
- b = p_ini->Get_Bool( INI_SECTION_NAME, "IsDedicated", IsDedicated.Get());
- IsDedicated.Set(b);
- #else ////FREEDEDICATEDSERVER
- IsDedicated.Set(true);
- #endif //FREEDEDICATEDSERVER
- b = p_ini->Get_Bool( INI_SECTION_NAME, "IsAutoRestart", IsAutoRestart.Get());
- IsAutoRestart.Set(b);
- b = p_ini->Get_Bool( INI_SECTION_NAME, "IsPassworded", IsPassworded.Get());
- IsPassworded.Set(b);
- b = p_ini->Get_Bool( INI_SECTION_NAME, "IsQuickMatch", IsQuickMatchServer.Get());
- IsQuickMatchServer.Set(b);
- b = p_ini->Get_Bool( INI_SECTION_NAME, "IsLaddered", IsLaddered.Get());
- #ifndef FREEDEDICATEDSERVER
- b = ((IsQuickMatchServer.Get() == true) ? true : b);
- #endif //FREEDEDICATEDSERVER
- IsLaddered.Set(b);
- b = p_ini->Get_Bool( INI_SECTION_NAME, "IsClanGame", IsClanGame.Get());
- #ifndef FREEDEDICATEDSERVER
- b = ((IsQuickMatchServer.Get() == true) ? false : b);
- #endif /FREEDEDICATEDSERVER
- IsClanGame.Set(b);
- b = p_ini->Get_Bool( INI_SECTION_NAME, "RemixTeams", RemixTeams.Get());
- RemixTeams.Set(b);
- b = p_ini->Get_Bool( INI_SECTION_NAME, "CanRepairBuildings", CanRepairBuildings.Get());
- CanRepairBuildings.Set(b);
- b = p_ini->Get_Bool( INI_SECTION_NAME, "DriverIsAlwaysGunner", DriverIsAlwaysGunner.Get());
- DriverIsAlwaysGunner.Set(b);
- b = p_ini->Get_Bool( INI_SECTION_NAME, "SpawnWeapons", SpawnWeapons.Get());
- SpawnWeapons.Set(b);
- //
- // Disguise "IsClientTrusted" with something that sounds like you need it but
- // that doesn't scream "hack me"
- //
- //b = p_ini->Get_Bool( INI_SECTION_NAME, "IsClientTrusted", IsClientTrusted.Get());
- b = p_ini->Get_Bool( INI_SECTION_NAME, "UseLagReduction", IsClientTrusted.Get());
- IsClientTrusted.Set(b);
- // Read the 8 bit versions of the strings first and use those as defaults.
- p_ini->Get_String(INI_SECTION_NAME, "bGameTitle", "", string8, sizeof(string8));
- Set_Game_Title(WideStringClass(string8, true));
- p_ini->Get_String(INI_SECTION_NAME, "bMotd", "", string8, sizeof(string8));
- Set_Motd(WideStringClass(string8, true));
- p_ini->Get_String(INI_SECTION_NAME, "bPassword", "", string8, sizeof(string8));
- Set_Password(WideStringClass(string8, true));
- p_ini->Get_String(INI_SECTION_NAME, "bConfigName", "", string8, sizeof(string8));
- Set_Settings_Description(WideStringClass(string8, true));
- // Now read the 16 bit versions as overrides.
- WideStringClass wide_string(Get_Game_Title(), true);
- p_ini->Get_Wide_String(wide_string, INI_SECTION_NAME, "wGameTitle", wide_string.Peek_Buffer());
- Set_Game_Title(wide_string);
- wide_string = Get_Password();
- p_ini->Get_Wide_String(wide_string, INI_SECTION_NAME, "wPassword", wide_string.Peek_Buffer());
- Set_Password(wide_string);
- wide_string = Get_Motd();
- p_ini->Get_Wide_String(wide_string, INI_SECTION_NAME, "wMotd", wide_string.Peek_Buffer());
- Set_Motd(wide_string);
- wide_string = Get_Settings_Description();
- p_ini->Get_Wide_String(wide_string, INI_SECTION_NAME, "wConfigName", wide_string.Peek_Buffer());
- Set_Settings_Description(wide_string);
- for (int j = 0; j < MAX_MAPS; j++) {
- StringClass item_name(0,true);
- item_name.Format("MapName%02d", j);
- p_ini->Get_String( INI_SECTION_NAME, item_name, "", map_name, sizeof(map_name));
- StringClass map(map_name,true);
- MapCycle[j] = map;
- }
- //char motd[2 * MAX_MOTD_LENGTH];
- //p_ini->Get_String( INI_SECTION_NAME, "Motd", "", motd, sizeof(motd));
- //if (::strlen(motd) > 0) {
- // Motd.Convert_From(motd);
- //}
- Release_INI(p_ini);
- }
- //-----------------------------------------------------------------------------
- void cGameData::Save_To_Server_Config(LPCSTR config_file)
- {
- WWASSERT(config_file != NULL);
- WWASSERT(cMiscUtil::Is_String_Different(config_file, ""));
- INIClass * p_ini = Get_INI(config_file);
- WWASSERT(p_ini != NULL);
- //
- // We can't overwrite entries, so clear them out first.
- //
- p_ini->Clear(INI_SECTION_NAME);
- p_ini->Put_Wide_String( INI_SECTION_NAME, "wConfigName", Get_Settings_Description());
- p_ini->Put_Wide_String( INI_SECTION_NAME, "wPassword", Get_Password());
- p_ini->Put_String( INI_SECTION_NAME, "MapName", Get_Map_Name());
- p_ini->Put_String( INI_SECTION_NAME, "ModName", Get_Mod_Name());
- p_ini->Put_Int( INI_SECTION_NAME, "TimeLimitMinutes", Get_Time_Limit_Minutes());
- p_ini->Put_Int( INI_SECTION_NAME, "RadarMode", Get_Radar_Mode());
- //p_ini->Put_Int( INI_SECTION_NAME, "IntermissionTimeSeconds", Get_Intermission_Time_Seconds());
- p_ini->Put_Int( INI_SECTION_NAME, "Port", Get_Port());
- p_ini->Put_Bool( INI_SECTION_NAME, "IsDedicated", IsDedicated.Get());
- p_ini->Put_Bool( INI_SECTION_NAME, "IsAutoRestart", IsAutoRestart.Get());
- p_ini->Put_Bool( INI_SECTION_NAME, "IsPassworded", IsPassworded.Get());
- p_ini->Put_Bool( INI_SECTION_NAME, "IsQuickMatch", IsQuickMatchServer.Get());
- p_ini->Put_Bool( INI_SECTION_NAME, "IsLaddered", IsLaddered.Get());
- p_ini->Put_Bool( INI_SECTION_NAME, "IsClanGame", IsClanGame.Get());
- p_ini->Put_Bool( INI_SECTION_NAME, "RemixTeams", RemixTeams.Get());
- p_ini->Put_Bool( INI_SECTION_NAME, "CanRepairBuildings", CanRepairBuildings.Get());
- p_ini->Put_Bool( INI_SECTION_NAME, "DriverIsAlwaysGunner", DriverIsAlwaysGunner.Get());
- p_ini->Put_Bool( INI_SECTION_NAME, "SpawnWeapons", SpawnWeapons.Get());
- //p_ini->Put_Bool( INI_SECTION_NAME, "IsClientTrusted", IsClientTrusted.Get());
- p_ini->Put_Bool( INI_SECTION_NAME, "UseLagReduction", IsClientTrusted.Get());
- p_ini->Put_Wide_String( INI_SECTION_NAME, "wGameTitle", Get_Game_Title());
- p_ini->Put_Wide_String( INI_SECTION_NAME, "wMOTD", Get_Motd());
- #if (0)
- // Save out 8 bit string versions too.
- StringClass string8(256, true);
- WideStringClass(Get_Game_Title(), true).Convert_To(string8);
- p_ini->Put_String( INI_SECTION_NAME, "bGameTitle", string8);
- WideStringClass(Get_Motd(), true).Convert_To(string8);
- p_ini->Put_String( INI_SECTION_NAME, "bMOTD", string8);
- WideStringClass(Get_Password(), true).Convert_To(string8);
- p_ini->Put_String( INI_SECTION_NAME, "bPassword", string8);
- #endif //(0)
- for (int j = 0; j < MAX_MAPS; j++) {
- StringClass item_name(0,true);
- item_name.Format("MapName%02d", j);
- p_ini->Put_String( INI_SECTION_NAME, item_name, MapCycle[j]);
- }
- if (!Motd.Is_Empty()) {
- StringClass motd;
- Motd.Convert_To(motd);
- p_ini->Put_String( INI_SECTION_NAME, "Motd", motd.Peek_Buffer());
- }
- Save_INI(p_ini, config_file);
- Release_INI(p_ini);
- }
- //-----------------------------------------------------------------------------
- void cGameData::Soldier_Added(SoldierGameObj * p_soldier)
- {
- WWASSERT(p_soldier != NULL);
- if (IsFreeWeapons.Is_True() &&
- p_soldier->Get_Player_Type() != PLAYERTYPE_NEUTRAL) {
- p_soldier->Give_All_Weapons();
- int weapon = 0;
- if (p_soldier->Is_Human_Controlled()) {
- weapon = 1;
- } else {
- weapon = 1 + rand() % 7;
- }
- WWASSERT(p_soldier->Get_Weapon_Bag() != NULL);
- p_soldier->Get_Weapon_Bag()->Select_Key_Number(weapon);
- }
- }
- //-----------------------------------------------------------------------------
- void cGameData::Begin_Intermission(void)
- {
- // If we are transitioning from one game to another we must first end the
- // previous game.
- GameModeClass* gameMode = GameModeManager::Find("WOL");
- if (gameMode && gameMode->Is_Active()) {
- WolGameModeClass* wolGame = reinterpret_cast<WolGameModeClass*>(gameMode);
- wolGame->End_Game();
- }
- IsIntermission.Set(true);
- IntermissionTimeRemaining = Get_Intermission_Time_Seconds();
- //
- // Display a dialog with the win information on it
- //
- if (!ConsoleBox.Is_Exclusive()) {
- START_DIALOG (CNCWinScreenMenuClass);
- }
- return ;
- }
- //-----------------------------------------------------------------------------
- void cGameData::Set_Maximum_World_Distance(float distance)
- {
- //
- // You will typically get this assert if you don't have the level file.
- //
- WWASSERT(distance > 0);
- MaximumWorldDistance = distance;
- }
- //-----------------------------------------------------------------------------
- void cGameData::Set_Min_Qualifying_Time_Minutes(int minutes)
- {
- WWASSERT(minutes >= 0);
- MinQualifyingTimeMinutes = minutes;
- }
- //-----------------------------------------------------------------------------
- int cGameData::Get_Duration_Seconds(void)
- {
- return (int)(TimeLimitMinutes * 60 - TimeRemainingSeconds);
- }
- //-----------------------------------------------------------------------------
- WideStringClass cGameData::Get_Team_Word(void)
- {
- //
- // In clan games, the work "Clan" is used instead of "Team"
- //
- if (IsClanGame.Is_True()) {
- return TRANSLATION(IDS_MP_CLAN);
- } else {
- return TRANSLATION(IDS_MP_TEAM);
- }
- }
- //-----------------------------------------------------------------------------
- void cGameData::Set_Time_Remaining_Seconds(float time_remaining_seconds)
- {
- WWASSERT(time_remaining_seconds >= 0);
- TimeRemainingSeconds = time_remaining_seconds;
- }
- //-----------------------------------------------------------------------------
- void cGameData::Reset_Time_Remaining_Seconds(void)
- {
- TimeRemainingSeconds = 60 * TimeLimitMinutes;
- }
- //-----------------------------------------------------------------------------
- float cGameData::Get_Time_Remaining_Seconds(void)
- {
- return TimeRemainingSeconds;
- }
- //-----------------------------------------------------------------------------
- bool cGameData::Is_Valid_Player_Type(int player_type)
- {
- bool is_valid = true;
- if (!Is_Single_Player()) {
- //if (player_type == PLAYERTYPE_RENEGADE &&
- // Is_Team_Game()) {
- if (player_type == PLAYERTYPE_RENEGADE) {
- is_valid = false;
- }
- /*
- if ((player_type == PLAYERTYPE_NOD || player_type == PLAYERTYPE_GDI) &&
- !Is_Team_Game()) {
- is_valid = false;
- }
- */
- }
- return is_valid;
- }
- //-----------------------------------------------------------------------------
- int cGameData::Choose_Player_Type(cPlayer* player, int team_choice, bool is_grunt)
- {
- if (IsClanGame.Is_True() && !is_grunt) {
- // Bots are assigned to the smallest team.
- if (player && !player->Is_Human()) {
- int team = Choose_Smallest_Team();
- WWDEBUG_SAY(("CLANS: Bot '%S' assigned to smallest team (%d)\n",
- (const WCHAR*)player->Get_Name(), team));
- return team;
- }
- // If there are other players from the same clan then team up them.
- // Otherwise we must be the first of our clan so select the next available team.
- cPlayer* clanMate = cPlayerManager::Find_Clan_Mate(player);
- if (clanMate) {
- int team = clanMate->Get_Player_Type();
- WWDEBUG_SAY(("CLANS: Player '%S' assigned to team with clanmates (%d)\n",
- (const WCHAR*)player->Get_Name(), team));
- return team;
- } else {
- int team = Choose_Available_Team(team_choice);
- WWDEBUG_SAY(("CLANS: Player '%S' assigned to available team (%d)\n",
- (const WCHAR*)player->Get_Name(), team));
- return team;
- }
- WWDEBUG_SAY(("CLANS: ERROR - Player not assigned to team\n"));
- WWASSERT("ERROR: Player not assigned to team");
- } else {
- if (PLAYERTYPE_RENEGADE == team_choice || IsTeamChangingAllowed.Is_False()) {
- return Choose_Smallest_Team();
- }
- }
- return team_choice;
- }
- int cGameData::Choose_Available_Team(int preference)
- {
- // If the perferred team is available then use it.
- if (preference != -1) {
- cTeam* team = cTeamManager::Find_Team(preference);
- if (team && (team->Tally_Size() == 0)) {
- return team->Get_Id();
- }
- }
- // Find the next available team
- cTeam* team = cTeamManager::Find_Empty_Team();
- if (team) {
- return team->Get_Id();
- }
- WWDEBUG_SAY(("ERROR: No available team found\n"));
- WWASSERT("ERROR: No available team found");
- return -1;
- }
- //-----------------------------------------------------------------------------
- int cGameData::Choose_Smallest_Team(void)
- {
- //WWASSERT(Is_Team_Game());
- cTeam * p_team_0 = cTeamManager::Find_Team(0);
- WWASSERT(p_team_0 != NULL);
- cTeam * p_team_1 = cTeamManager::Find_Team(1);
- WWASSERT(p_team_1 != NULL);
- int team = -999;
- int size_team_0 = p_team_0->Tally_Size();
- int size_team_1 = p_team_1->Tally_Size();
- if (size_team_0 < size_team_1) {
- team = p_team_0->Get_Id();
- } else if (size_team_1 < size_team_0) {
- team = p_team_1->Get_Id();
- } else {
- //
- // Both teams are equal in size, so choose the losing team.
- //
- if (p_team_0->Get_Score() < p_team_1->Get_Score()) {
- team = p_team_0->Get_Id();
- } else if (p_team_0->Get_Score() > p_team_1->Get_Score()) {
- team = p_team_1->Get_Id();
- } else {
- //
- // Both teams have the same score. Choose Randomly.
- //
- if (rand() % 2 == 0) {
- team = p_team_0->Get_Id();
- } else {
- team = p_team_1->Get_Id();
- }
- }
- }
- WWASSERT(team != -999);
- return team;
- }
- //-----------------------------------------------------------------------------
- bool cGameData::Is_Game_Over(void)
- {
- WWASSERT(cNetwork::I_Am_Server());
- bool is_game_over = false;
- //
- // Games may be manually ended with the "gameover" command.
- //
- if (IsManualRestart) {
- IsManualRestart = false;
- WinType = WIN_TYPE_FORCED;
- is_game_over = true;
- }
- //
- // Games may be ended with the "quit" command.
- //
- if (!is_game_over && IsManualExit) {
- WinType = WIN_TYPE_FORCED;
- is_game_over = true;
- }
- //
- // Time expired?
- //
- if (!is_game_over && Is_Time_Limit() && TimeRemainingSeconds <= WWMATH_EPSILON) {
- WinType = WIN_TYPE_TIME;
- is_game_over = true;
- }
- //
- // If game time has passed but gameplay now pends, end the game
- //
- if (!is_game_over && Get_Game_Duration_S() > 0 && !Is_Gameplay_Permitted()) {
- WinType = WIN_TYPE_FORCED;
- is_game_over = true;
- }
- /*
- //
- // THIS NEEDS REFINEMENT
- //
- // The following test will end a non-mission game when your opponents
- // abandon you. To determine whether any combat has occurred we simply
- // examine the IsBloodShed flag.
- //
- if (!Is_Mission() && IsBloodShed.Is_True() &&
- ((Is_Team_Game() && cTeamManager::Get_Living_Count() <= 1) ||
- (!Is_Team_Game() && cPlayerManager::Get_Living_Count() <= 1))) {
- return true;
- }
- */
- if (is_game_over)
- {
- TimeRemainingSeconds = 0;
- }
- return is_game_over;
- }
- //-----------------------------------------------------------------------------
- bool cGameData::Has_Config_File_Changed(void)
- {
- unsigned long mod_time = Get_Config_File_Mod_Time();
- if (LastServerConfigModTime != mod_time) {
- return(true);
- }
- return(false);
- }
- //-----------------------------------------------------------------------------
- unsigned long cGameData::Get_Config_File_Mod_Time(void)
- {
- StringClass full_filename(IniFilename, true);
- RawFileClass file(full_filename);
- if (!file.Is_Available()) {
- full_filename.Format("data\\%s", IniFilename);
- file.Set_Name(full_filename);
- }
- if (file.Is_Available()) {
- file.Open();
- unsigned long mod_time = file.Get_Date_Time();
- file.Close();
- return(mod_time);
- }
- return(0);
- }
- //-----------------------------------------------------------------------------
- void cGameData::Game_Over_Processing(void)
- {
- WWDEBUG_SAY(("cGameData::Game_Over_Processing\n"));
- WWASSERT(cNetwork::I_Am_Server());
- int winning_team = cTeamManager::Get_Leaders_Id();
- //
- // Reload the game settings if they changed on disk.
- //
- if (Has_Config_File_Changed()) {
- //
- // Verify that the new settings are good.
- //
- cGameDataCnc *test_game_settings = (cGameDataCnc*) Create_Game_Of_Type(cGameData::GAME_TYPE_CNC);
- WWASSERT(test_game_settings != NULL);
- bool ok = false;
- if (test_game_settings) {
- test_game_settings->Set_Ini_Filename(IniFilename);
- test_game_settings->Load_From_Server_Config();
- WideStringClass outMsg;
- ok = test_game_settings->Is_Valid_Settings(outMsg, true);
- delete test_game_settings;
- }
- //
- // If they are good settings then reload them.
- //
- if (ok) {
- ConsoleBox.Print("Game settings changed - realoading settings\n");
- Load_From_Server_Config();
- }
- }
- Rotate_Map();
- cPlayerManager::Increment_Player_Times();
- //
- // Compute the game duration
- //
- DWORD duration_s = (int)((TIMEGETTIME() - GameStartTimeMs) / 1000.0f);
- Set_Game_Duration_S(duration_s);
- //
- // Record the MVP name and track the number of consecutives
- //
- WideStringClass mvp_name = cPlayerManager::Determine_Mvp_Name();
- if (mvp_name.Compare_No_Case(MvpName)) {
- Set_Mvp_Count(1);
- Set_Mvp_Name(cPlayerManager::Determine_Mvp_Name());
- } else {
- Increment_Mvp_Count();
- }
- mWinnerID = winning_team;
- cWinEvent * p_win = new cWinEvent;
- p_win->Init(mWinnerID, PLAYER_ID_UNKNOWN, IsMapCycleOver);
- cPlayerManager::Compute_Ladder_Points(winning_team);
- cTeamManager::Log_Team_List();
- cPlayerManager::Log_Player_List();
- //
- // Results logs wrap back to 1 after 100, and overwrite.
- //
- int log_num = cUserOptions::ResultsLogNumber.Get();
- log_num++;
- if (log_num > 100)
- {
- log_num = 1;
- }
- cUserOptions::ResultsLogNumber.Set(log_num);
- Begin_Intermission();
- }
- //-----------------------------------------------------------------------------
- bool cGameData::Is_Gameplay_Permitted(void)
- {
- bool permitted = true;
- if (IsIntermission.Is_True()) {
- permitted = false;
- }
- if (!GameModeManager::Find ("Combat")->Is_Active ()) {
- permitted = false;
- }
- return permitted;
- }
- void cGameData::Set_Clan(int slot, unsigned long clanID)
- {
- WWASSERT(slot >= 0 && slot < MAX_CLAN_SLOTS);
- mClanSlots[slot] = clanID;
- }
- unsigned long cGameData::Get_Clan(int slot) const
- {
- WWASSERT(slot >= 0 && slot < MAX_CLAN_SLOTS);
- return mClanSlots[slot];
- }
- void cGameData::Clear_Clans(void)
- {
- for (int slot = 0; slot < MAX_CLAN_SLOTS; ++slot) {
- mClanSlots[slot] = 0;
- }
- }
- int cGameData::Find_Free_Clan_Slot(void) const
- {
- if (IsClanGame.Is_True()) {
- for (int slot = 0; slot < MAX_CLAN_SLOTS; ++slot) {
- if (mClanSlots[slot] == 0) {
- return slot;
- }
- }
- }
- return -1;
- }
- bool cGameData::Is_Clan_Competing(unsigned long clanID) const
- {
- if (IsClanGame.Is_True() && (clanID != 0)) {
- for (int slot = 0; slot < MAX_CLAN_SLOTS; ++slot) {
- if (mClanSlots[slot] == clanID) {
- return true;
- }
- }
- }
- return false;
- }
- //-----------------------------------------------------------------------------
- bool cGameData::Is_Clan_Game_Open(void) const
- {
- if (IsClanGame.Is_True()) {
- for (int slot = 0; slot < MAX_CLAN_SLOTS; ++slot) {
- if (mClanSlots[slot] == 0) {
- return true;
- }
- }
- }
- return false;
- }
- //-----------------------------------------------------------------------------
- cGameData * cGameData::Create_Game_Of_Type(GameTypeEnum game_type)
- {
- /*
- cGameData * p_game_data = NULL;
- switch (game_type) {
- //case GAME_TYPE_DEATHMATCH: p_game_data = new cGameDataDeathMatch; break;
- //case GAME_TYPE_TEAM_DEATHMATCH: p_game_data = new cGameDataTeamDeathMatch; break;
- case GAME_TYPE_CNC: p_game_data = new cGameDataCnc; break;
- default: DIE; break;
- }
- return p_game_data;
- */
- WWASSERT(game_type == GAME_TYPE_CNC);
- return new cGameDataCnc;
- }
- /*
- //-----------------------------------------------------------------------------
- const char* cGameData::Get_Game_Type_Name(GameTypeEnum type)
- {
- static const char* _modeNames[] = {"SP", "SK", "CNC"};
- return _modeNames[type];
- }
- */
- //-----------------------------------------------------------------------------
- const char * cGameData::Get_Game_Type_Name(void) const
- {
- WideStringClass wide_name;
- wide_name.Format(L"%s", Get_Game_Name());
- StringClass name;
- wide_name.Convert_To(name);
- return name.Peek_Buffer();
- }
- //-----------------------------------------------------------------------------
- void cGameData::Add_Bottom_Text(WideStringClass & text)
- {
- //WWASSERT(text != NULL);
- /* WWASSERT(PFont != NULL);
- float x = Render2DClass::Get_Screen_Resolution().Center().X -
- PFont->String_Width(text) / 2.0f;
- float y = MultiHUDClass::Get_Bottom_Text_Y_Pos();
- y -= 1.2 * PFont->Char_Height();
- MultiHUDClass::Set_Bottom_Text_Y_Pos(y);
- WWASSERT(PTextRenderer != NULL);
- PTextRenderer->Set_Location(Vector2(cMathUtil::Round(x), cMathUtil::Round(y)));
- PTextRenderer->Draw_Text(text);
- */
- BottomText.Add(text);
- }
- //-----------------------------------------------------------------------------
- void cGameData::Show_Game_Settings_Limits(void)
- {
- if (PTextRenderer == NULL) {
- return;
- }
- bool changed=false;
- WideStringClass text(0,true);
- unsigned color;
- Get_Time_Limit_Text(text);
- if (text!=renderer_time_text) {
- renderer_time_text=text;
- changed=true;
- }
- // Dedicated server label
- if (cNetwork::I_Am_Only_Server()) {
- Get_Dedicated_Server_Label(text,color);
- }
- else {
- text="";
- color=0;
- }
- if (text!=renderer_dedicated_server_label) {
- renderer_dedicated_server_label=text;
- changed=true;
- }
- if (color!=renderer_dedicated_server_color) {
- renderer_dedicated_server_color=color;
- changed=true;
- }
- // Gameplay pending label -
- bool show_gameplay_label = false;
- if (!Is_Gameplay_Permitted() || (COMBAT_STAR == NULL)) {
- show_gameplay_label = true;
- }
- //if (IsIntermission.Is_False() && (!Is_Gameplay_Permitted() || (COMBAT_STAR == NULL))) {
- if (show_gameplay_label) {
- Get_Gameplay_Not_Permitted_Label(text,color);
- } else {
- text="";
- color=0;
- }
- if (text!=renderer_gameplay_label) {
- renderer_gameplay_label=text;
- changed=true;
- }
- if (color!=renderer_gameplay_color) {
- renderer_gameplay_color=color;
- changed=true;
- }
- if (!changed) {
- if (BottomText.Count()!=OldBottomText.Count()) {
- changed=true;
- }
- else {
- for (int j=0;j<BottomText.Count();++j) {
- if (BottomText[j]!=OldBottomText[j]) {
- changed=true;
- break;
- }
- }
- }
- }
- // Render if needed -------------------------------------------------------
- float charHeight = PTextRenderer->Peek_Font()->Get_Char_Height();
- if (!changed) {
- // Proceed the multihud by one line (as we are caching the time render which would usually do this)
- float y = MultiHUDClass::Get_Bottom_Text_Y_Pos();
- y -= 1.2 * charHeight;
- MultiHUDClass::Set_Bottom_Text_Y_Pos(y);
- BottomText.Reset_Active();
- return;
- }
- // Re-compose the OldBottomText vector
- OldBottomText.Reset_Active();
- for (int j=0;j<BottomText.Count();++j) {
- OldBottomText.Add(BottomText[j]);
- }
- BottomText.Reset_Active();
- PTextRenderer->Reset();
- float x,y;
- // Render bottom text (start with time text, which is to be first)
- Vector2 textExtent = PTextRenderer->Get_Text_Extents(text);
- x = Render2DClass::Get_Screen_Resolution().Center().X - textExtent.X / 2.0f;
- //Always draw on the bottom
- MultiHUDClass::Set_Bottom_Text_Y_Pos( Render2DClass::Get_Screen_Resolution().Bottom - 15 );
- y = MultiHUDClass::Get_Bottom_Text_Y_Pos();
- y -= 1.2 * charHeight;
- Vector2 loc(cMathUtil::Round(x), cMathUtil::Round(y));
- PTextRenderer->Set_Location(loc);
- PTextRenderer->Build_Sentence(renderer_time_text);
- PTextRenderer->Draw_Sentence();
- for (j=0;j<OldBottomText.Count();++j) {
- y -= 1.2 * charHeight;
- loc[1]=cMathUtil::Round(y);
- PTextRenderer->Set_Location(loc);
- PTextRenderer->Build_Sentence(OldBottomText[j]);
- PTextRenderer->Draw_Sentence();
- }
- MultiHUDClass::Set_Bottom_Text_Y_Pos(y);
- // Dedicated server label
- if (cNetwork::I_Am_Only_Server()) {
- Vector2 extent = PTextRenderer->Get_Text_Extents(renderer_dedicated_server_label);
- x = Render2DClass::Get_Screen_Resolution().Center().X - extent.X / 2.0f;
- y = Render2DClass::Get_Screen_Resolution().Center().Y;
- PTextRenderer->Set_Location(Vector2(cMathUtil::Round(x), cMathUtil::Round(y)));
- PTextRenderer->Build_Sentence(renderer_dedicated_server_label);
- PTextRenderer->Draw_Sentence(renderer_dedicated_server_color);
- }
- // Gameplay pending label
- if (show_gameplay_label) {
- Vector2 extent = PTextRenderer->Get_Text_Extents(renderer_gameplay_label);
- x = Render2DClass::Get_Screen_Resolution().Center().X - extent.X / 2.0f;
- y = Render2DClass::Get_Screen_Resolution().Center().Y + 1.2 * charHeight;
- PTextRenderer->Set_Location(Vector2(cMathUtil::Round(x), cMathUtil::Round(y)));
- PTextRenderer->Build_Sentence(renderer_gameplay_label);
- PTextRenderer->Draw_Sentence(color);
- }
- }
- //-----------------------------------------------------------------------------
- void cGameData::Get_Dedicated_Server_Label(WideStringClass& text, unsigned& color)
- {
- color = 0xFFFFFFFF; // white
- if (cMathUtil::Round(TimeManager::Get_Seconds()) % 2 != 0) {
- color = 0xFF00FF00; // green
- }
- text = TRANSLATION(IDS_MP_DEDICATED_SERVER);
- }
- //-----------------------------------------------------------------------------
- void cGameData::Get_Gameplay_Not_Permitted_Label(WideStringClass& text, unsigned& color)
- {
- color = 0xFFFFFFFF; // white
- if (cMathUtil::Round(TimeManager::Get_Seconds()) % 2 != 0) {
- color = 0xFF00FF00; // green
- }
- text = TRANSLATION(IDS_MP_GAMEPLAY_PENDING);
- }
- //-----------------------------------------------------------------------------
- void cGameData::Get_Time_Limit_Text(WideStringClass& text)
- {
- if (IsIntermission.Is_True()) {
- text.Format(
- L"%s: %d",
- TRANSLATION(IDS_MP_NEXTGAME_COUNTDOWN),
- cMathUtil::Round(Get_Intermission_Time_Remaining()));
- } else if (Is_Time_Limit()) {
- int hours = 0;
- int mins = 0;
- int seconds = 0;
- cMiscUtil::Seconds_To_Hms(TimeRemainingSeconds, hours, mins, seconds);
- WideStringClass time_string(0, true);
- time_string.Format(L"%02d:%02d:%02d", hours, mins, seconds);
- text.Format(L"%s: %s", TRANSLATION(IDS_MP_TIME_REMAINING), time_string);
- }
- }
- //-----------------------------------------------------------------------------
- void cGameData::Think(void)
- {
- if (IsIntermission.Is_True()) {
- IntermissionTimeRemaining -= TimeManager::Get_Frame_Real_Seconds();
- if (IntermissionTimeRemaining < 0) {
- IntermissionTimeRemaining = 0;
- }
- } else if (Is_Gameplay_Permitted()) {
- TimeRemainingSeconds -= TimeManager::Get_Frame_Real_Seconds();
- if (TimeRemainingSeconds < 0) {
- TimeRemainingSeconds = 0;
- }
- DWORD duration_s = (int)((TIMEGETTIME() - GameStartTimeMs) / 1000.0f);
- Set_Game_Duration_S(duration_s);
- }
- if (cNetwork::I_Am_Server()) {
- //
- // Update CurrentPlayers
- //
- int max = (int) WWMath::Max(
- cPlayerManager::Count(),
- cNetwork::PServerConnection->Get_Num_RHosts());
- Set_Current_Players(max);
- }
- DEMO_SECURITY_CHECK;
- FrameCount++;
- }
- //-----------------------------------------------------------------------------
- void cGameData::Render(void)
- {
- Show_Game_Settings_Limits();
- if (PTextRenderer != NULL) {
- WWPROFILE("cGameData::Render");
- PTextRenderer->Render();
- }
- }
- //-----------------------------------------------------------------------------
- void cGameData::On_Game_Begin(void)
- {
- //
- // Note, On_Game_Begin happens after load.
- //
- WWDEBUG_SAY(("cGameData::On_Game_Begin\n"));
- GetSystemTime(&GameStartTime);
- FrameCount = 0;
- GameStartTimeMs = TIMEGETTIME();
- //
- // Clear the MVP name
- // Let MVP carry over into next game.
- //
- //MvpName.Format(L"");
- //MvpCount = 0;
- //
- // Reset the game duration
- //
- GameDurationS = 0;
- //
- // Notify the combat layer about various server options
- //
- cCsDamageEvent::Set_Are_Clients_Trusted(IsClientTrusted.Get());
- BuildingGameObj::Set_Can_Repair_Buildings(CanRepairBuildings.Get());
- VehicleGameObj::Set_Default_Driver_Is_Gunner(DriverIsAlwaysGunner.Get());
- CombatManager::Set_Friendly_Fire_Permitted(IsFriendlyFirePermitted.Get());
- CombatManager::Set_Beacon_Placement_Ends_Game(false);
- //
- // Filter out unwanted spawners
- //
- if (cNetwork::I_Am_Server()) {
- Filter_Spawners();
- }
- //
- // Adjust teaming for auto-teamed games
- //
- //if (!IS_MISSION && cNetwork::I_Am_Server() && Is_Team_Game() && IsTeamChangingAllowed.Is_False()) {
- if (!IS_MISSION && cNetwork::I_Am_Server()) {
- if (IsClanGame.Is_False() && IsTeamChangingAllowed.Is_False() && RemixTeams.Is_True()) {
- //
- // Remix Teams if the server option is set.
- //
- Remix_Team_Sides();
- } else {
- //
- // In non-remixed C&C mode, we have a 50-50 chance of the teams being swapped. I prefer this
- // to simply alternating, because if you alternate and the number of maps in the
- // cycle is even, you will always play GDI on the same 50% of the maps.
- //
- if (Is_Skirmish() || (Is_Cnc() && (rand() % 2 == 0))) {
- Swap_Team_Sides();
- }
- }
- if (IsClanGame.Is_False() && IsTeamChangingAllowed.Is_False())
- {
- //
- // We always rebalance the teams numerically
- //
- Rebalance_Team_Sides();
- }
- }
- GameModeClass* gameMode = GameModeManager::Find("WOL");
- if (gameMode && gameMode->Is_Active()) {
- WolGameModeClass* wolGame = reinterpret_cast<WolGameModeClass*>(gameMode);
- WWASSERT(wolGame != NULL);
- wolGame->Start_Game(this);
- }
- }
- //-----------------------------------------------------------------------------
- void cGameData::On_Game_End(void)
- {
- WWDEBUG_SAY(("cGameData::On_Game_End\n"));
- GameModeClass* gameMode = GameModeManager::Find("WOL");
- if (gameMode && gameMode->Is_Active()) {
- WolGameModeClass* wolGame = reinterpret_cast<WolGameModeClass*>(gameMode);
- wolGame->End_Game();
- }
- }
- //-----------------------------------------------------------------------------
- int cGameData::Get_Mission_Number_From_Map_Name( const char * map_name )
- {
- // If tutorial, return tutorial number
- if ( ::strnicmp( map_name, "M00_T", 5 ) == 0 ) {
- #define TUTORIAL_LOAD_MENU_NUMBER 90
- return TUTORIAL_LOAD_MENU_NUMBER;
- }
- // Assume the map name is in the form "mXX.mix" where xx is the level number
- if ( ::strlen( map_name ) > 0 ) {
- return ::atoi( ((const char *)map_name)+1 );
- }
- return 0;
- }
- //-----------------------------------------------------------------------------
- const StringClass& cGameData::Get_Map_Cycle(int map)
- {
- WWASSERT(map >= 0 && map < MAX_MAPS);
- #ifdef MULTIPLAYERDEMO
- MapCycle[map].Format("C&C_Under.mix");
- #endif // MULTIPLAYERDEMO
- return MapCycle[map];
- }
- //-----------------------------------------------------------------------------
- void
- cGameData::Set_Map_Cycle(int map, const StringClass & map_name)
- {
- WWASSERT(map >= 0 && map < MAX_MAPS);
- MapCycle[map] = map_name;
- }
- //-----------------------------------------------------------------------------
- void
- cGameData::Clear_Map_Cycle(void)
- {
- for (int i = 0; i < MAX_MAPS; i++)
- {
- MapCycle[i].Format("");
- }
- }
- //-----------------------------------------------------------------------------
- void
- cGameData::Rotate_Map(void)
- {
- IsMapCycleOver = false;
- //
- // Determine the current map
- //
- int current_map = MapCycleIndex;
- #if (0)
- int current_map = 0;
- for (int i = 0; i < MAX_MAPS; i++)
- {
- if (MapName == MapCycle[i]) {
- current_map = i;
- break;
- }
- }
- #endif //(0)
-
- //
- // Increment it
- //
- current_map++;
- //
- // Go back to the first map if necessary
- //
- if (current_map >= MAX_MAPS || MapCycle[current_map].Is_Empty()) {
- current_map = 0;
- if (DoMapsLoop == false) {
- IsMapCycleOver = true;
- }
- }
- //
- // Set the map name
- //
- #ifdef MULTIPLAYERDEMO
- MapName.Format("C&C_Under.mix");
- #else
- MapName = MapCycle[current_map];
- #endif
- MapCycleIndex = current_map;
- return ;
- }
- //-----------------------------------------------------------------------------
- void cGameData::Set_Win_Text(WideStringClass & text)
- {
- WinText = text;
- }
- //-----------------------------------------------------------------------------
- void cGameData::ReceiveSignal(MPChooseTeamSignal& choice)
- {
- if (choice.GetItemA() == true) {
- //
- // Do nothing if the player selected 'auto' rather than GDI or NOD.
- //
- if (choice.GetItemB() != PLAYERTYPE_RENEGADE) {
- cNetwork::SwitchTeam(choice.GetItemB());
- }
- }
- }
- //-----------------------------------------------------------------------------
- void cGameData::Filter_Spawners(void)
- {
- WWASSERT(cNetwork::I_Am_Server());
- if (SpawnWeapons.Is_False()) {
- //
- // Disable multiplay weapons spawners
- //
- DynamicVectorClass<SpawnerClass*> spawner_list = SpawnManager::Get_Spawner_List();
- for (int i = 0; i < spawner_list.Count(); i++) {
- WWASSERT(spawner_list[i] != NULL);
- if (spawner_list[i]->Get_Definition().Is_Multiplay_Weapon_Spawner()) {
- spawner_list[i]->Enable(false);
- }
- }
- }
- }
- //------------------------------------------------------------------------------------
- void cGameData::Set_Mvp_Name(const WideStringClass name)
- {
- MvpName = name;
- }
- //------------------------------------------------------------------------------------
- void cGameData::Set_Mvp_Count(int count)
- {
- WWASSERT(count >= 0);
- MvpCount = count;
- }
- //------------------------------------------------------------------------------------
- void cGameData::Set_Win_Type(WinTypeEnum type)
- {
- WinType = type;
- }
- //------------------------------------------------------------------------------------
- void cGameData::Set_Game_Duration_S(DWORD seconds)
- {
- GameDurationS = seconds;
- }
- //-----------------------------------------------------------------------------
- void cGameData::Get_Description(WideStringClass & description)
- {
- const WideStringClass delimiter = L"\t";
- const WideStringClass newline = L"\n";
- const WideStringClass yes = TRANSLATE(IDS_YES);
- const WideStringClass no = TRANSLATE(IDS_NO);
- WideStringClass attribute(0, true);
- WideStringClass value(0, true);
- //
- // Host
- //
- attribute = TRANSLATE(IDS_MP_HOST);
- value = Owner;
- description += (attribute + delimiter + value + newline);
- //
- // Game Name
- //
- attribute = TRANSLATE(IDS_MENU_TEXT292);
- value = GameTitle;
- description += (attribute + delimiter + value + newline);
- //
- // Map Name
- //
- if (ModName.Is_Empty () == false) {
- attribute = L"Mod Name:";
- value = ModName;
- description += (attribute + delimiter + value + newline);
- }
- //
- // Map Name
- //
- attribute = TRANSLATE(IDS_MP_GAME_LIST_HEADER_GAME_MAP);
- value = MapName;
- description += (attribute + delimiter + value + newline);
- //
- // Time Limit
- //
- attribute = TRANSLATE(IDS_MENU_TEXT298);
- if (Is_Time_Limit()) {
- value.Format(L"%d %s", TimeLimitMinutes, TRANSLATE(IDS_MP_MINUTES));
- } else {
- value = TRANSLATE(IDS_MP_NONE);
- }
- description += (attribute + delimiter + value + newline);
- //
- // Max. Players
- //
- attribute = TRANSLATE(IDS_MENU_TEXT294);
- value.Format(L"%d", MaxPlayers);
- description += (attribute + delimiter + value + newline);
- //
- // Radar
- //
- attribute = TRANSLATE(IDS_MENU_TEXT488);
- switch (RadarMode) {
- case RADAR_NOBODY:
- value = TRANSLATION(IDS_MP_RADAR_MODE_NOBODY);
- break;
- case RADAR_TEAMMATES:
- value = TRANSLATION(IDS_MP_RADAR_MODE_TEAMMATES);
- break;
- case RADAR_ALL:
- value = TRANSLATION(IDS_MP_RADAR_MODE_ALL);
- break;
- default:
- DIE;
- }
- description += (attribute + delimiter + value + newline);
- //
- // Allow Quickmatching
- //
- attribute = TRANSLATE(IDS_MENU_TEXT584);
- value = (IsQuickMatchServer.Get() ? yes : no);
- description += (attribute + delimiter + value + newline);
- //
- // Dedicated
- //
- attribute = TRANSLATE(IDS_MENU_TEXT309);
- value = (IsDedicated.Get() ? yes : no);
- description += (attribute + delimiter + value + newline);
- //
- // Friendly Fire
- //
- attribute = TRANSLATE(IDS_MENU_TEXT301);
- value = (IsFriendlyFirePermitted.Get() ? yes : no);
- description += (attribute + delimiter + value + newline);
- //
- // Manual Teaming
- //
- attribute = TRANSLATE(IDS_MENU_TEXT490);
- value = (IsTeamChangingAllowed.Get() ? yes : no);
- description += (attribute + delimiter + value + newline);
- //
- // Passworded
- //
- attribute = TRANSLATE(IDS_MP_PASSWORDED);
- value = (IsPassworded.Get() ? yes : no);
- description += (attribute + delimiter + value + newline);
- //
- // Laddered
- //
- attribute = TRANSLATE(IDS_MENU_TEXT496);
- value = (IsLaddered.Get() ? yes : no);
- description += (attribute + delimiter + value + newline);
- //
- // Clan Game
- //
- attribute = TRANSLATE(IDS_MENU_TEXT497);
- value = (IsClanGame.Get() ? yes : no);
- description += (attribute + delimiter + value + newline);
- /*
- //
- // Trust Clients
- //
- attribute = TRANSLATE(IDS_MENU_TEXT585);
- value = (IsClientTrusted.Get() ? yes : no);
- description += (attribute + delimiter + value + newline);
- */
- //
- // Remix Teams
- //
- attribute = TRANSLATE(IDS_MENU_TEXT587);
- value = (RemixTeams.Get() ? yes : no);
- description += (attribute + delimiter + value + newline);
- //
- // Can Repair Buildings
- //
- attribute = TRANSLATE(IDS_MENU_TEXT590);
- value = (CanRepairBuildings.Get() ? yes : no);
- description += (attribute + delimiter + value + newline);
- //
- // Driver Is Always Gunner
- //
- attribute = TRANSLATE(IDS_MENU_TEXT591);
- value = (DriverIsAlwaysGunner.Get() ? yes : no);
- description += (attribute + delimiter + value + newline);
- //
- // Weapon spawning
- //
- attribute = TRANSLATE(IDS_MENU_TEXT592);
- value = (SpawnWeapons.Get() ? yes : no);
- description += (attribute + delimiter + value + newline);
- }
- //-----------------------------------------------------------------------------
- //cGameData * The_Game(void) {WWASSERT(PTheGameData != NULL); return PTheGameData;}
- cGameData * The_Game(void) {return PTheGameData;}
- cGameDataSinglePlayer * The_Single_Player_Game(void) {WWASSERT(The_Game()->As_Single_Player() != NULL); return The_Game()->As_Single_Player();}
- cGameDataSkirmish * The_Skirmish_Game(void) {WWASSERT(The_Game()->As_Skirmish() != NULL); return The_Game()->As_Skirmish();}
- cGameDataCnc * The_Cnc_Game(void) {WWASSERT(The_Game()->As_Cnc() != NULL); return The_Game()->As_Cnc();}
- /*
- if (Is_Team_Game()) {
- has_opponents =
- cPlayerManager::Get_Count(PLAYERTYPE_NOD) > 0 &&
- cPlayerManager::Get_Count(PLAYERTYPE_GDI) > 0;
- } else {
- has_opponents = (cPlayerManager::Get_Count(PLAYERTYPE_RENEGADE) > 1);
- }
- */
- /*
- //-----------------------------------------------------------------------------
- void cGameData::Set_Min_Game_Time_Required_Mins(int mins)
- {
- WWASSERT(mins >= 0 );
- MinGameTimeRequiredMins = mins;
- }
- */
- /*
- //-----------------------------------------------------------------------------
- void cGameData::Set_Full_Score_Time_Threshold_Mins(int mins)
- {
- WWASSERT(mins >= 0);
- FullScoreTimeThresholdMins = mins;
- }
- */
- //#include "helptext.h"
- //#include "gddeathmatch.h"
- //#include "gdteamdeathmatch.h"
- //MinGameTimeRequiredMins = 10;
- //FullScoreTimeThresholdMins = 30;
- //MinGameTimeRequiredMins = rhs.MinGameTimeRequiredMins;
- //FullScoreTimeThresholdMins = rhs.FullScoreTimeThresholdMins;
- //packet.Add(MinGameTimeRequiredMins);
- //packet.Add(FullScoreTimeThresholdMins);
- //Set_Min_Game_Time_Required_Mins( packet.Get(i_placeholder));
- //Set_Full_Score_Time_Threshold_Mins( packet.Get(i_placeholder));
- //cGameDataDeathMatch * The_Deathmatch_Game(void) {WWASSERT(The_Game()->As_Deathmatch() != NULL); return The_Game()->As_Deathmatch();}
- //cGameDataTeamDeathMatch * The_Team_Deathmatch_Game(void) {WWASSERT(The_Game()->As_Team_Deathmatch() != NULL); return The_Game()->As_Team_Deathmatch();}
- //if (Is_Team_Game()) {
- /*
- } else {
- has_opponents = (cPlayerManager::Tally_Team_Size(PLAYERTYPE_RENEGADE) > 1);
- }
- */
- //IsBloodShed.Set( false);
- //IsBloodShed = rhs.IsBloodShed;
- /*
- if (cNetwork::I_Am_Server()) {
- IsBloodShed.Set(false);
- }
- */
|