gdskirmish.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** Confidential - Westwood Studios ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Commando *
  23. * *
  24. * $Archive:: /Commando/Code/Commando/gdskirmish.cpp $*
  25. * *
  26. * $Author:: Tom_s $*
  27. * *
  28. * $Modtime:: 4/12/02 4:01p $*
  29. * *
  30. * $Revision:: 12 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "gdskirmish.h"
  36. #include "cnetwork.h"
  37. #include "translatedb.h"
  38. #include "string_ids.h"
  39. #include "assets.h"
  40. #include "multihud.h"
  41. #include "playerdata.h"
  42. #include "player.h"
  43. #include "playertype.h"
  44. #include "gameobjmanager.h"
  45. #include "spawn.h"
  46. //-----------------------------------------------------------------------------
  47. cGameDataSkirmish::cGameDataSkirmish(void) :
  48. IsPlaying (false),
  49. cGameData()
  50. {
  51. //WWDEBUG_SAY(("cGameDataSkirmish::cGameDataSkirmish\n"));
  52. Set_Time_Limit_Minutes(25);
  53. Set_Ini_Filename("svrcfg_skirmish.ini");
  54. BaseDestructionEndsGame.Set(true);
  55. BeaconPlacementEndsGame.Set(true);
  56. StartingCredits = 400;
  57. //IsTeamChangingAllowed.Set(false);
  58. IsTeamChangingAllowed.Set(true);
  59. Set_Max_Players(1);
  60. Set_Radar_Mode(RADAR_TEAMMATES);
  61. Load_From_Server_Config();
  62. Save_To_Server_Config();
  63. //
  64. // Reload again to avoid LastServerConfigModTime issues
  65. //
  66. Load_From_Server_Config();
  67. }
  68. //-----------------------------------------------------------------------------
  69. cGameDataSkirmish::~cGameDataSkirmish(void)
  70. {
  71. //WWDEBUG_SAY(("cGameDataSkirmish::~cGameDataSkirmish\n"));
  72. }
  73. //-----------------------------------------------------------------------------
  74. cGameDataSkirmish& cGameDataSkirmish::operator=(const cGameDataSkirmish& rhs)
  75. {
  76. //
  77. // Call the base class
  78. //
  79. cGameData::operator=(rhs);
  80. BaseDestructionEndsGame = rhs.BaseDestructionEndsGame;
  81. BeaconPlacementEndsGame = rhs.BeaconPlacementEndsGame;
  82. StartingCredits = rhs.StartingCredits;
  83. return (*this);
  84. }
  85. //-----------------------------------------------------------------------------
  86. const WCHAR* cGameDataSkirmish::Get_Static_Game_Name(void)
  87. {
  88. return TRANSLATION(IDS_MP_GAME_TYPE_SKIRMISH);
  89. }
  90. //-----------------------------------------------------------------------------
  91. void cGameDataSkirmish::Reset_Game(bool is_reloaded)
  92. {
  93. WWDEBUG_SAY(("cGameDataSkirmish::Reset_Game\n"));
  94. cGameData::Reset_Game(is_reloaded);
  95. //
  96. // TSS091201 - hack - On_Game_End not called in correct places
  97. //
  98. if (IsPlaying) {
  99. BaseGDI.Shutdown ();
  100. BaseNOD.Shutdown ();
  101. IsPlaying = false;
  102. }
  103. //
  104. // Initialize the base controllers
  105. //
  106. BaseGDI.Initialize ( PLAYERTYPE_GDI );
  107. BaseNOD.Initialize ( PLAYERTYPE_NOD );
  108. return ;
  109. }
  110. //-----------------------------------------------------------------------------
  111. void
  112. cGameDataSkirmish::On_Game_Begin (void)
  113. {
  114. WWDEBUG_SAY(("cGameDataSkirmish::On_Game_Begin\n"));
  115. cGameData::On_Game_Begin();
  116. CombatManager::Set_Beacon_Placement_Ends_Game(BeaconPlacementEndsGame.Get());
  117. //
  118. // Initialize the bases
  119. //
  120. IsPlaying = true;
  121. }
  122. //-----------------------------------------------------------------------------
  123. void
  124. cGameDataSkirmish::On_Game_End (void)
  125. {
  126. WWDEBUG_SAY(("cGameDataSkirmish::On_Game_End\n"));
  127. //
  128. // Close the bases
  129. //
  130. BaseGDI.Shutdown ();
  131. BaseNOD.Shutdown ();
  132. IsPlaying = false;
  133. cGameData::On_Game_End();
  134. return ;
  135. }
  136. //-----------------------------------------------------------------------------
  137. void
  138. cGameDataSkirmish::Soldier_Added (SoldierGameObj *soldier)
  139. {
  140. cGameData::Soldier_Added (soldier);
  141. //
  142. // Give the soldier some starting credits
  143. //
  144. if ( soldier != NULL &&
  145. soldier->Get_Player_Data() != NULL &&
  146. soldier->Get_Player_Data()->Get_Game_Time () == 0)
  147. {
  148. soldier->Get_Player_Data ()->Set_Money (StartingCredits);
  149. }
  150. return ;
  151. }
  152. //-----------------------------------------------------------------------------
  153. void cGameDataSkirmish::Think(void)
  154. {
  155. cGameData::Think();
  156. if (!cNetwork::I_Am_Server()) {
  157. return;
  158. }
  159. //
  160. // Let the bases think
  161. //
  162. if (IsPlaying) {
  163. BaseGDI.Think ();
  164. BaseNOD.Think ();
  165. }
  166. //
  167. // Weed out any soldiers or spawners that shouldn't be present.
  168. //
  169. Filter_Soldiers();
  170. return ;
  171. }
  172. //-----------------------------------------------------------------------------
  173. void cGameDataSkirmish::Set_Starting_Credits(int credits)
  174. {
  175. Set_Generic_Num(credits, 0, MAX_CREDITS, StartingCredits);
  176. }
  177. //-----------------------------------------------------------------------------
  178. void cGameDataSkirmish::Base_Destruction_Score_Tweaking(void)
  179. {
  180. WWASSERT(cNetwork::I_Am_Server());
  181. cTeam * p_nod = cTeamManager::Find_Team(PLAYERTYPE_NOD);
  182. WWASSERT(p_nod != NULL);
  183. cTeam * p_gdi = cTeamManager::Find_Team(PLAYERTYPE_GDI);
  184. WWASSERT(p_gdi != NULL);
  185. float nod_score = p_nod->Get_Score();
  186. float gdi_score = p_gdi->Get_Score();
  187. const int BASE_DESTRUCTION_POINTS_REWARD = 5000;
  188. //
  189. // Base destroyer gets a points reward.
  190. // If this isn't enough to beat other team, nudge score ahead by 1 point.
  191. //
  192. if (BaseGDI.Is_Base_Destroyed()) {
  193. nod_score += BASE_DESTRUCTION_POINTS_REWARD;
  194. if (nod_score <= gdi_score) {
  195. nod_score = gdi_score + 1;
  196. }
  197. p_nod->Set_Score(nod_score);
  198. } else {
  199. WWASSERT(BaseNOD.Is_Base_Destroyed());
  200. gdi_score += BASE_DESTRUCTION_POINTS_REWARD;
  201. if (gdi_score <= nod_score) {
  202. gdi_score = nod_score + 1;
  203. }
  204. p_gdi->Set_Score(gdi_score);
  205. }
  206. }
  207. //-----------------------------------------------------------------------------
  208. bool cGameDataSkirmish::Is_Game_Over(void)
  209. {
  210. WWASSERT(cNetwork::I_Am_Server());
  211. bool is_game_over = cGameData::Is_Game_Over();
  212. if (!is_game_over && BaseDestructionEndsGame.Is_True())
  213. {
  214. //
  215. // If a base is destroyed then the game is over and the other team wins.
  216. // To ensure this we may need to tweak the base-destroyer's score.
  217. //
  218. if (BaseGDI.Is_Base_Destroyed() || BaseNOD.Is_Base_Destroyed()) {
  219. is_game_over = true;
  220. Set_Win_Type(WIN_TYPE_BASE_DESTRUCTION);
  221. Base_Destruction_Score_Tweaking();
  222. }
  223. }
  224. //
  225. // Beacon placement end game works via above base destruction method.
  226. //
  227. return is_game_over;
  228. }
  229. //-----------------------------------------------------------------------------
  230. void cGameDataSkirmish::Load_From_Server_Config(void)
  231. {
  232. cGameData::Load_From_Server_Config(Get_Ini_Filename());
  233. INIClass * p_ini = Get_INI(Get_Ini_Filename());
  234. WWASSERT(p_ini != NULL);
  235. bool b;
  236. int i;
  237. //float f;
  238. i = p_ini->Get_Int( INI_SECTION_NAME, "MaxPlayers", Get_Max_Players());
  239. Set_Max_Players(i);
  240. b = p_ini->Get_Bool( INI_SECTION_NAME, "IsFriendlyFirePermitted", IsFriendlyFirePermitted.Get());
  241. IsFriendlyFirePermitted.Set(b);
  242. b = p_ini->Get_Bool( INI_SECTION_NAME, "IsTeamChangingAllowed", IsTeamChangingAllowed.Get());
  243. IsTeamChangingAllowed.Set(b);
  244. b = p_ini->Get_Bool( INI_SECTION_NAME, "IsClanGame", IsClanGame.Get());
  245. IsClanGame.Set(b);
  246. b = p_ini->Get_Bool( INI_SECTION_NAME, "BaseDestructionEndsGame", BaseDestructionEndsGame.Get());
  247. BaseDestructionEndsGame.Set(b);
  248. b = p_ini->Get_Bool( INI_SECTION_NAME, "BeaconPlacementEndsGame", BeaconPlacementEndsGame.Get());
  249. BeaconPlacementEndsGame.Set(b);
  250. i = p_ini->Get_Int( INI_SECTION_NAME, "StartingCredits", Get_Starting_Credits());
  251. Set_Starting_Credits(i);
  252. Release_INI(p_ini);
  253. return ;
  254. }
  255. //-----------------------------------------------------------------------------
  256. void cGameDataSkirmish::Save_To_Server_Config(void)
  257. {
  258. cGameData::Save_To_Server_Config(Get_Ini_Filename());
  259. INIClass * p_ini = Get_INI(Get_Ini_Filename());
  260. WWASSERT(p_ini != NULL);
  261. p_ini->Put_Bool( INI_SECTION_NAME, "IsFriendlyFirePermitted", IsFriendlyFirePermitted.Get());
  262. p_ini->Put_Bool( INI_SECTION_NAME, "IsTeamChangingAllowed", IsTeamChangingAllowed.Get());
  263. p_ini->Put_Bool( INI_SECTION_NAME, "IsClanGame", IsClanGame.Get());
  264. p_ini->Put_Int( INI_SECTION_NAME, "MaxPlayers", Get_Max_Players());
  265. p_ini->Put_Bool( INI_SECTION_NAME, "BaseDestructionEndsGame", BaseDestructionEndsGame.Get());
  266. p_ini->Put_Bool( INI_SECTION_NAME, "BeaconPlacementEndsGame", BeaconPlacementEndsGame.Get());
  267. p_ini->Put_Int( INI_SECTION_NAME, "StartingCredits", Get_Starting_Credits());
  268. Save_INI(p_ini, Get_Ini_Filename());
  269. Release_INI(p_ini);
  270. }
  271. //-----------------------------------------------------------------------------
  272. void cGameDataSkirmish::Show_My_Money(void)
  273. {
  274. if (cNetwork::I_Am_Client()) {
  275. cPlayer * p_player = cNetwork::Get_My_Player_Object();
  276. if (p_player != NULL) {
  277. WideStringClass text(0,true);
  278. text.Format(L"%s: %d",
  279. TRANSLATION(IDS_MP_MONEY), (int) p_player->Get_Money());
  280. Add_Bottom_Text(text);
  281. }
  282. }
  283. }
  284. //-----------------------------------------------------------------------------
  285. void cGameDataSkirmish::Show_Game_Settings_Limits(void)
  286. {
  287. /*
  288. if (IsIntermission.Is_True()) {
  289. return;
  290. }
  291. */
  292. Show_My_Money();
  293. cGameData::Show_Game_Settings_Limits();
  294. }
  295. //-----------------------------------------------------------------------------
  296. void cGameDataSkirmish::Filter_Soldiers(void)
  297. {
  298. //
  299. // Remove any soldiers or spawners on your side, leaving only opponents.
  300. //
  301. cPlayer * p_player = cNetwork::Get_My_Player_Object();
  302. if (p_player != NULL) {
  303. //int my_team = p_player->Get_Player_Type();
  304. /*
  305. //
  306. // Remove soldiers
  307. // Whoa, design now wants these... comment out this code.
  308. //
  309. for (
  310. SLNode<SmartGameObj> * objnode = GameObjManager::Get_Smart_Game_Obj_List()->Head();
  311. objnode != NULL;
  312. objnode = objnode->Next())
  313. {
  314. SmartGameObj * p_smart_obj = objnode->Data();
  315. WWASSERT(p_smart_obj != NULL);
  316. if ( p_smart_obj->As_SoldierGameObj() != NULL &&
  317. !p_smart_obj->Is_Delete_Pending() &&
  318. !p_smart_obj->Has_Player() &&
  319. p_smart_obj->Get_Player_Type() == my_team) {
  320. p_smart_obj->Set_Delete_Pending();
  321. }
  322. }
  323. */
  324. /*
  325. //
  326. // Remove spawners... ugh how do I select just the appropriate ones?
  327. //
  328. DynamicVectorClass<SpawnerClass*> spawner_list = SpawnManager::Get_Spawner_List();
  329. for (int i = 0; i < spawner_list.Count(); i++) {
  330. WWASSERT(spawner_list[i] != NULL);
  331. if (spawner_list[i]->Get_Definition().Get_Player_Type() == my_team) {
  332. spawner_list[i]->Enable(false);
  333. }
  334. }
  335. */
  336. }
  337. }
  338. //-----------------------------------------------------------------------------
  339. void cGameDataSkirmish::Get_Description(WideStringClass & description)
  340. {
  341. //
  342. // Call base class
  343. //
  344. cGameData::Get_Description(description);
  345. const WideStringClass delimiter = L"\t";
  346. const WideStringClass newline = L"\n";
  347. const WideStringClass yes = TRANSLATE(IDS_YES);
  348. const WideStringClass no = TRANSLATE(IDS_NO);
  349. WideStringClass attribute(0, true);
  350. WideStringClass value(0, true);
  351. //
  352. // Starting Credits
  353. //
  354. attribute = TRANSLATE(IDS_MENU_TEXT349);
  355. value.Format(L"%d", StartingCredits);
  356. description += (attribute + delimiter + value + newline);
  357. //
  358. // Base Destruction Ends Game
  359. //
  360. attribute = TRANSLATE(IDS_MENU_TEXT314);
  361. value = (BaseDestructionEndsGame.Get() ? yes : no);
  362. description += (attribute + delimiter + value + newline);
  363. //
  364. // Beacon Placement Ends Game
  365. //
  366. attribute = TRANSLATE(IDS_MENU_TEXT315);
  367. value = (BeaconPlacementEndsGame.Get() ? yes : no);
  368. description += (attribute + delimiter + value + newline);
  369. }