/* ** 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 . */ /*********************************************************************************************** *** Confidential - Westwood Studios *** *********************************************************************************************** * * * Project Name : Commando * * * * $Archive:: /Commando/Code/Commando/gdskirmish.cpp $* * * * $Author:: Tom_s $* * * * $Modtime:: 4/12/02 4:01p $* * * * $Revision:: 12 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "gdskirmish.h" #include "cnetwork.h" #include "translatedb.h" #include "string_ids.h" #include "assets.h" #include "multihud.h" #include "playerdata.h" #include "player.h" #include "playertype.h" #include "gameobjmanager.h" #include "spawn.h" //----------------------------------------------------------------------------- cGameDataSkirmish::cGameDataSkirmish(void) : IsPlaying (false), cGameData() { //WWDEBUG_SAY(("cGameDataSkirmish::cGameDataSkirmish\n")); Set_Time_Limit_Minutes(25); Set_Ini_Filename("svrcfg_skirmish.ini"); BaseDestructionEndsGame.Set(true); BeaconPlacementEndsGame.Set(true); StartingCredits = 400; //IsTeamChangingAllowed.Set(false); IsTeamChangingAllowed.Set(true); Set_Max_Players(1); Set_Radar_Mode(RADAR_TEAMMATES); Load_From_Server_Config(); Save_To_Server_Config(); // // Reload again to avoid LastServerConfigModTime issues // Load_From_Server_Config(); } //----------------------------------------------------------------------------- cGameDataSkirmish::~cGameDataSkirmish(void) { //WWDEBUG_SAY(("cGameDataSkirmish::~cGameDataSkirmish\n")); } //----------------------------------------------------------------------------- cGameDataSkirmish& cGameDataSkirmish::operator=(const cGameDataSkirmish& rhs) { // // Call the base class // cGameData::operator=(rhs); BaseDestructionEndsGame = rhs.BaseDestructionEndsGame; BeaconPlacementEndsGame = rhs.BeaconPlacementEndsGame; StartingCredits = rhs.StartingCredits; return (*this); } //----------------------------------------------------------------------------- const WCHAR* cGameDataSkirmish::Get_Static_Game_Name(void) { return TRANSLATION(IDS_MP_GAME_TYPE_SKIRMISH); } //----------------------------------------------------------------------------- void cGameDataSkirmish::Reset_Game(bool is_reloaded) { WWDEBUG_SAY(("cGameDataSkirmish::Reset_Game\n")); cGameData::Reset_Game(is_reloaded); // // TSS091201 - hack - On_Game_End not called in correct places // if (IsPlaying) { BaseGDI.Shutdown (); BaseNOD.Shutdown (); IsPlaying = false; } // // Initialize the base controllers // BaseGDI.Initialize ( PLAYERTYPE_GDI ); BaseNOD.Initialize ( PLAYERTYPE_NOD ); return ; } //----------------------------------------------------------------------------- void cGameDataSkirmish::On_Game_Begin (void) { WWDEBUG_SAY(("cGameDataSkirmish::On_Game_Begin\n")); cGameData::On_Game_Begin(); CombatManager::Set_Beacon_Placement_Ends_Game(BeaconPlacementEndsGame.Get()); // // Initialize the bases // IsPlaying = true; } //----------------------------------------------------------------------------- void cGameDataSkirmish::On_Game_End (void) { WWDEBUG_SAY(("cGameDataSkirmish::On_Game_End\n")); // // Close the bases // BaseGDI.Shutdown (); BaseNOD.Shutdown (); IsPlaying = false; cGameData::On_Game_End(); return ; } //----------------------------------------------------------------------------- void cGameDataSkirmish::Soldier_Added (SoldierGameObj *soldier) { cGameData::Soldier_Added (soldier); // // Give the soldier some starting credits // if ( soldier != NULL && soldier->Get_Player_Data() != NULL && soldier->Get_Player_Data()->Get_Game_Time () == 0) { soldier->Get_Player_Data ()->Set_Money (StartingCredits); } return ; } //----------------------------------------------------------------------------- void cGameDataSkirmish::Think(void) { cGameData::Think(); if (!cNetwork::I_Am_Server()) { return; } // // Let the bases think // if (IsPlaying) { BaseGDI.Think (); BaseNOD.Think (); } // // Weed out any soldiers or spawners that shouldn't be present. // Filter_Soldiers(); return ; } //----------------------------------------------------------------------------- void cGameDataSkirmish::Set_Starting_Credits(int credits) { Set_Generic_Num(credits, 0, MAX_CREDITS, StartingCredits); } //----------------------------------------------------------------------------- void cGameDataSkirmish::Base_Destruction_Score_Tweaking(void) { WWASSERT(cNetwork::I_Am_Server()); cTeam * p_nod = cTeamManager::Find_Team(PLAYERTYPE_NOD); WWASSERT(p_nod != NULL); cTeam * p_gdi = cTeamManager::Find_Team(PLAYERTYPE_GDI); WWASSERT(p_gdi != NULL); float nod_score = p_nod->Get_Score(); float gdi_score = p_gdi->Get_Score(); const int BASE_DESTRUCTION_POINTS_REWARD = 5000; // // Base destroyer gets a points reward. // If this isn't enough to beat other team, nudge score ahead by 1 point. // if (BaseGDI.Is_Base_Destroyed()) { nod_score += BASE_DESTRUCTION_POINTS_REWARD; if (nod_score <= gdi_score) { nod_score = gdi_score + 1; } p_nod->Set_Score(nod_score); } else { WWASSERT(BaseNOD.Is_Base_Destroyed()); gdi_score += BASE_DESTRUCTION_POINTS_REWARD; if (gdi_score <= nod_score) { gdi_score = nod_score + 1; } p_gdi->Set_Score(gdi_score); } } //----------------------------------------------------------------------------- bool cGameDataSkirmish::Is_Game_Over(void) { WWASSERT(cNetwork::I_Am_Server()); bool is_game_over = cGameData::Is_Game_Over(); if (!is_game_over && BaseDestructionEndsGame.Is_True()) { // // If a base is destroyed then the game is over and the other team wins. // To ensure this we may need to tweak the base-destroyer's score. // if (BaseGDI.Is_Base_Destroyed() || BaseNOD.Is_Base_Destroyed()) { is_game_over = true; Set_Win_Type(WIN_TYPE_BASE_DESTRUCTION); Base_Destruction_Score_Tweaking(); } } // // Beacon placement end game works via above base destruction method. // return is_game_over; } //----------------------------------------------------------------------------- void cGameDataSkirmish::Load_From_Server_Config(void) { cGameData::Load_From_Server_Config(Get_Ini_Filename()); INIClass * p_ini = Get_INI(Get_Ini_Filename()); WWASSERT(p_ini != NULL); bool b; int i; //float f; i = p_ini->Get_Int( INI_SECTION_NAME, "MaxPlayers", Get_Max_Players()); Set_Max_Players(i); b = p_ini->Get_Bool( INI_SECTION_NAME, "IsFriendlyFirePermitted", IsFriendlyFirePermitted.Get()); IsFriendlyFirePermitted.Set(b); b = p_ini->Get_Bool( INI_SECTION_NAME, "IsTeamChangingAllowed", IsTeamChangingAllowed.Get()); IsTeamChangingAllowed.Set(b); b = p_ini->Get_Bool( INI_SECTION_NAME, "IsClanGame", IsClanGame.Get()); IsClanGame.Set(b); b = p_ini->Get_Bool( INI_SECTION_NAME, "BaseDestructionEndsGame", BaseDestructionEndsGame.Get()); BaseDestructionEndsGame.Set(b); b = p_ini->Get_Bool( INI_SECTION_NAME, "BeaconPlacementEndsGame", BeaconPlacementEndsGame.Get()); BeaconPlacementEndsGame.Set(b); i = p_ini->Get_Int( INI_SECTION_NAME, "StartingCredits", Get_Starting_Credits()); Set_Starting_Credits(i); Release_INI(p_ini); return ; } //----------------------------------------------------------------------------- void cGameDataSkirmish::Save_To_Server_Config(void) { cGameData::Save_To_Server_Config(Get_Ini_Filename()); INIClass * p_ini = Get_INI(Get_Ini_Filename()); WWASSERT(p_ini != NULL); p_ini->Put_Bool( INI_SECTION_NAME, "IsFriendlyFirePermitted", IsFriendlyFirePermitted.Get()); p_ini->Put_Bool( INI_SECTION_NAME, "IsTeamChangingAllowed", IsTeamChangingAllowed.Get()); p_ini->Put_Bool( INI_SECTION_NAME, "IsClanGame", IsClanGame.Get()); p_ini->Put_Int( INI_SECTION_NAME, "MaxPlayers", Get_Max_Players()); p_ini->Put_Bool( INI_SECTION_NAME, "BaseDestructionEndsGame", BaseDestructionEndsGame.Get()); p_ini->Put_Bool( INI_SECTION_NAME, "BeaconPlacementEndsGame", BeaconPlacementEndsGame.Get()); p_ini->Put_Int( INI_SECTION_NAME, "StartingCredits", Get_Starting_Credits()); Save_INI(p_ini, Get_Ini_Filename()); Release_INI(p_ini); } //----------------------------------------------------------------------------- void cGameDataSkirmish::Show_My_Money(void) { if (cNetwork::I_Am_Client()) { cPlayer * p_player = cNetwork::Get_My_Player_Object(); if (p_player != NULL) { WideStringClass text(0,true); text.Format(L"%s: %d", TRANSLATION(IDS_MP_MONEY), (int) p_player->Get_Money()); Add_Bottom_Text(text); } } } //----------------------------------------------------------------------------- void cGameDataSkirmish::Show_Game_Settings_Limits(void) { /* if (IsIntermission.Is_True()) { return; } */ Show_My_Money(); cGameData::Show_Game_Settings_Limits(); } //----------------------------------------------------------------------------- void cGameDataSkirmish::Filter_Soldiers(void) { // // Remove any soldiers or spawners on your side, leaving only opponents. // cPlayer * p_player = cNetwork::Get_My_Player_Object(); if (p_player != NULL) { //int my_team = p_player->Get_Player_Type(); /* // // Remove soldiers // Whoa, design now wants these... comment out this code. // for ( SLNode * objnode = GameObjManager::Get_Smart_Game_Obj_List()->Head(); objnode != NULL; objnode = objnode->Next()) { SmartGameObj * p_smart_obj = objnode->Data(); WWASSERT(p_smart_obj != NULL); if ( p_smart_obj->As_SoldierGameObj() != NULL && !p_smart_obj->Is_Delete_Pending() && !p_smart_obj->Has_Player() && p_smart_obj->Get_Player_Type() == my_team) { p_smart_obj->Set_Delete_Pending(); } } */ /* // // Remove spawners... ugh how do I select just the appropriate ones? // DynamicVectorClass 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().Get_Player_Type() == my_team) { spawner_list[i]->Enable(false); } } */ } } //----------------------------------------------------------------------------- void cGameDataSkirmish::Get_Description(WideStringClass & description) { // // Call base class // cGameData::Get_Description(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); // // Starting Credits // attribute = TRANSLATE(IDS_MENU_TEXT349); value.Format(L"%d", StartingCredits); description += (attribute + delimiter + value + newline); // // Base Destruction Ends Game // attribute = TRANSLATE(IDS_MENU_TEXT314); value = (BaseDestructionEndsGame.Get() ? yes : no); description += (attribute + delimiter + value + newline); // // Beacon Placement Ends Game // attribute = TRANSLATE(IDS_MENU_TEXT315); value = (BeaconPlacementEndsGame.Get() ? yes : no); description += (attribute + delimiter + value + newline); }