LanGameOptionsMenu.cpp 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311
  1. /*
  2. ** Command & Conquer Generals(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. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. ///////////////////////////////////////////////////////////////////////////////////////
  24. // FILE: LanGameOptionsMenu.cpp
  25. // Author: Chris Huybregts, October 2001
  26. // Description: Lan Game Options Menu
  27. ///////////////////////////////////////////////////////////////////////////////////////
  28. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  29. #include "Common/PlayerTemplate.h"
  30. #include "Common/GameEngine.h"
  31. #include "Common/UserPreferences.h"
  32. #include "Common/QuotedPrintable.h"
  33. #include "GameClient/AnimateWindowManager.h"
  34. #include "GameClient/WindowLayout.h"
  35. #include "GameClient/Gadget.h"
  36. #include "GameClient/Shell.h"
  37. #include "GameClient/KeyDefs.h"
  38. #include "GameClient/GameWindowManager.h"
  39. #include "GameClient/GadgetListBox.h"
  40. #include "GameClient/GadgetComboBox.h"
  41. #include "GameClient/GadgetTextEntry.h"
  42. #include "GameClient/GadgetStaticText.h"
  43. #include "GameClient/GadgetPushButton.h"
  44. #include "GameClient/MapUtil.h"
  45. #include "GameClient/Mouse.h"
  46. #include "GameClient/GameWindowTransitions.h"
  47. #include "GameNetwork/FirewallHelper.h"
  48. #include "GameNetwork/LANAPI.h"
  49. #include "GameNetwork/IPEnumeration.h"
  50. #include "GameNetwork/LANAPICallbacks.h"
  51. #include "Common/MultiplayerSettings.h"
  52. #include "GameClient/GameText.h"
  53. #include "GameNetwork/GUIUtil.h"
  54. #ifdef _INTERNAL
  55. // for occasional debugging...
  56. //#pragma optimize("", off)
  57. //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
  58. #endif
  59. extern char *LANnextScreen;
  60. extern Bool LANisShuttingDown;
  61. extern Bool LANbuttonPushed;
  62. extern void MapSelectorTooltip(GameWindow *window, WinInstanceData *instData, UnsignedInt mouse);
  63. extern void gameAcceptTooltip(GameWindow *window, WinInstanceData *instData, UnsignedInt mouse);
  64. Color white = GameMakeColor( 255, 255, 255, 255 );
  65. static bool s_isIniting = FALSE;
  66. // window ids ------------------------------------------------------------------------------
  67. static NameKeyType parentLanGameOptionsID = NAMEKEY_INVALID;
  68. static NameKeyType comboBoxPlayerID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
  69. NAMEKEY_INVALID,NAMEKEY_INVALID,
  70. NAMEKEY_INVALID,NAMEKEY_INVALID,
  71. NAMEKEY_INVALID,NAMEKEY_INVALID };
  72. static NameKeyType buttonAcceptID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
  73. NAMEKEY_INVALID,NAMEKEY_INVALID,
  74. NAMEKEY_INVALID,NAMEKEY_INVALID,
  75. NAMEKEY_INVALID,NAMEKEY_INVALID };
  76. static NameKeyType comboBoxColorID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
  77. NAMEKEY_INVALID,NAMEKEY_INVALID,
  78. NAMEKEY_INVALID,NAMEKEY_INVALID,
  79. NAMEKEY_INVALID,NAMEKEY_INVALID };
  80. static NameKeyType comboBoxPlayerTemplateID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
  81. NAMEKEY_INVALID,NAMEKEY_INVALID,
  82. NAMEKEY_INVALID,NAMEKEY_INVALID,
  83. NAMEKEY_INVALID,NAMEKEY_INVALID };
  84. static NameKeyType comboBoxTeamID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
  85. NAMEKEY_INVALID,NAMEKEY_INVALID,
  86. NAMEKEY_INVALID,NAMEKEY_INVALID,
  87. NAMEKEY_INVALID,NAMEKEY_INVALID };
  88. //static NameKeyType buttonStartPositionID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
  89. // NAMEKEY_INVALID,NAMEKEY_INVALID,
  90. // NAMEKEY_INVALID,NAMEKEY_INVALID,
  91. // NAMEKEY_INVALID,NAMEKEY_INVALID };
  92. static NameKeyType buttonMapStartPositionID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
  93. NAMEKEY_INVALID,NAMEKEY_INVALID,
  94. NAMEKEY_INVALID,NAMEKEY_INVALID,
  95. NAMEKEY_INVALID,NAMEKEY_INVALID };
  96. static NameKeyType textEntryChatID = NAMEKEY_INVALID;
  97. static NameKeyType textEntryMapDisplayID = NAMEKEY_INVALID;
  98. static NameKeyType buttonBackID = NAMEKEY_INVALID;
  99. static NameKeyType buttonStartID = NAMEKEY_INVALID;
  100. static NameKeyType buttonEmoteID = NAMEKEY_INVALID;
  101. static NameKeyType buttonSelectMapID = NAMEKEY_INVALID;
  102. static NameKeyType windowMapID = NAMEKEY_INVALID;
  103. // Window Pointers ------------------------------------------------------------------------
  104. static GameWindow *parentLanGameOptions = NULL;
  105. static GameWindow *buttonBack = NULL;
  106. static GameWindow *buttonStart = NULL;
  107. static GameWindow *buttonSelectMap = NULL;
  108. static GameWindow *buttonEmote = NULL;
  109. static GameWindow *textEntryChat = NULL;
  110. static GameWindow *textEntryMapDisplay = NULL;
  111. static GameWindow *windowMap = NULL;
  112. static GameWindow *comboBoxPlayer[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
  113. NULL,NULL,NULL,NULL };
  114. static GameWindow *buttonAccept[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
  115. NULL,NULL,NULL,NULL };
  116. static GameWindow *comboBoxColor[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
  117. NULL,NULL,NULL,NULL };
  118. static GameWindow *comboBoxPlayerTemplate[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
  119. NULL,NULL,NULL,NULL };
  120. static GameWindow *comboBoxTeam[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
  121. NULL,NULL,NULL,NULL };
  122. //static GameWindow *buttonStartPosition[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
  123. // NULL,NULL,NULL,NULL };
  124. //
  125. static GameWindow *buttonMapStartPosition[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
  126. NULL,NULL,NULL,NULL };
  127. //external declarations of the Gadgets the callbacks can use
  128. GameWindow *listboxChatWindowLanGame = NULL;
  129. NameKeyType listboxChatWindowLanGameID = NAMEKEY_INVALID;
  130. WindowLayout *mapSelectLayout = NULL;
  131. static Int getNextSelectablePlayer(Int start)
  132. {
  133. LANGameInfo *game = TheLAN->GetMyGame();
  134. if (!game->amIHost())
  135. return -1;
  136. for (Int j=start; j<MAX_SLOTS; ++j)
  137. {
  138. LANGameSlot *slot = game->getLANSlot(j);
  139. if (slot && slot->getStartPos() == -1 &&
  140. ( (j==game->getLocalSlotNum() && game->getConstSlot(j)->getPlayerTemplate()!=PLAYERTEMPLATE_OBSERVER)
  141. || slot->isAI()))
  142. {
  143. return j;
  144. }
  145. }
  146. return -1;
  147. }
  148. static Int getFirstSelectablePlayer(const GameInfo *game)
  149. {
  150. const GameSlot *slot = game->getConstSlot(game->getLocalSlotNum());
  151. if (!game->amIHost() || slot && slot->getPlayerTemplate() != PLAYERTEMPLATE_OBSERVER)
  152. return game->getLocalSlotNum();
  153. for (Int i=0; i<MAX_SLOTS; ++i)
  154. {
  155. slot = game->getConstSlot(i);
  156. if (slot && slot->isAI())
  157. return i;
  158. }
  159. return game->getLocalSlotNum();
  160. }
  161. void updateMapStartSpots( GameInfo *myGame, GameWindow *buttonMapStartPositions[], Bool onLoadScreen = FALSE );
  162. void positionStartSpots( GameInfo *myGame, GameWindow *buttonMapStartPositions[], GameWindow *mapWindow);
  163. void LanPositionStartSpots( void )
  164. {
  165. positionStartSpots( TheLAN->GetMyGame(), buttonMapStartPosition, windowMap);
  166. }
  167. static void playerTooltip(GameWindow *window,
  168. WinInstanceData *instData,
  169. UnsignedInt mouse)
  170. {
  171. Int idx = -1;
  172. for (Int i=0; i<MAX_SLOTS; ++i)
  173. {
  174. if (window && window == GadgetComboBoxGetEditBox(comboBoxPlayer[i]))
  175. {
  176. idx = i;
  177. break;
  178. }
  179. }
  180. if (idx == -1)
  181. return;
  182. LANGameSlot *slot = TheLAN->GetMyGame()->getLANSlot(i);
  183. if (!slot)
  184. return;
  185. LANPlayer *player = slot->getUser();
  186. if (!player)
  187. {
  188. DEBUG_ASSERTCRASH(TheLAN->GetMyGame()->getIP(i) == 0, ("No player info in listbox!"));
  189. TheMouse->setCursorTooltip( UnicodeString::TheEmptyString );
  190. return;
  191. }
  192. UnicodeString tooltip;
  193. tooltip.format(TheGameText->fetch("TOOLTIP:LANPlayer"), player->getName().str(), player->getLogin().str(), player->getHost().str());
  194. TheMouse->setCursorTooltip( tooltip );
  195. }
  196. void StartPressed(void)
  197. {
  198. LANGameInfo *myGame = TheLAN->GetMyGame();
  199. Bool isReady = true;
  200. Bool allHaveMap = true;
  201. Int playerCount = 0;
  202. if (!myGame)
  203. {
  204. return;
  205. }
  206. myGame->getLANSlot(0)->setAccept(); // cause we are, of course!
  207. int i;
  208. int numUsers = 0;
  209. int numHumans = 0;
  210. for (i=0; i<MAX_SLOTS; ++i)
  211. {
  212. GameSlot *slot = myGame->getSlot(i);
  213. if (slot && slot->isOccupied() && slot->getPlayerTemplate() != PLAYERTEMPLATE_OBSERVER)
  214. {
  215. if (slot && slot->isHuman())
  216. numHumans++;
  217. numUsers++;
  218. }
  219. }
  220. // Check for too many players
  221. const MapMetaData *md = TheMapCache->findMap( myGame->getMap() );
  222. if (!md || md->m_numPlayers < numUsers)
  223. {
  224. if (TheLAN->AmIHost())
  225. {
  226. UnicodeString text;
  227. text.format(TheGameText->fetch("LAN:TooManyPlayers"), (md)?md->m_numPlayers:0);
  228. TheLAN->OnChat(UnicodeString(L"SYSTEM"), TheLAN->GetLocalIP(), text, LANAPI::LANCHAT_SYSTEM);
  229. }
  230. return;
  231. }
  232. // Check for observer + AI players
  233. if (TheGlobalData->m_netMinPlayers && !numHumans)
  234. {
  235. if (TheLAN->AmIHost())
  236. {
  237. UnicodeString text = TheGameText->fetch("GUI:NeedHumanPlayers");
  238. TheLAN->OnChat(UnicodeString(L"SYSTEM"), TheLAN->GetLocalIP(), text, LANAPI::LANCHAT_SYSTEM);
  239. }
  240. return;
  241. }
  242. // Check for too few players
  243. if (numUsers < TheGlobalData->m_netMinPlayers)
  244. {
  245. if (TheLAN->AmIHost())
  246. {
  247. UnicodeString text;
  248. text.format(TheGameText->fetch("LAN:NeedMorePlayers"),numUsers);
  249. TheLAN->OnChat(UnicodeString(L"SYSTEM"), TheLAN->GetLocalIP(), text, LANAPI::LANCHAT_SYSTEM);
  250. }
  251. return;
  252. }
  253. // Check for too few teams
  254. int numRandom = 0;
  255. std::set<Int> teams;
  256. for (i=0; i<MAX_SLOTS; ++i)
  257. {
  258. GameSlot *slot = myGame->getSlot(i);
  259. if (slot && slot->isOccupied() && slot->getPlayerTemplate() != PLAYERTEMPLATE_OBSERVER)
  260. {
  261. if (slot->getTeamNumber() >= 0)
  262. {
  263. teams.insert(slot->getTeamNumber());
  264. }
  265. else
  266. {
  267. ++numRandom;
  268. }
  269. }
  270. }
  271. if (numRandom + teams.size() < TheGlobalData->m_netMinPlayers)
  272. {
  273. if (TheLAN->AmIHost())
  274. {
  275. UnicodeString text;
  276. text.format(TheGameText->fetch("LAN:NeedMoreTeams"));
  277. TheLAN->OnChat(UnicodeString(L"SYSTEM"), TheLAN->GetLocalIP(), text, LANAPI::LANCHAT_SYSTEM);
  278. }
  279. return;
  280. }
  281. if (numRandom + teams.size() < 2)
  282. {
  283. UnicodeString text;
  284. text.format(TheGameText->fetch("GUI:SandboxMode"));
  285. TheLAN->OnChat(UnicodeString(L"SYSTEM"), TheLAN->GetLocalIP(), text, LANAPI::LANCHAT_SYSTEM);
  286. }
  287. // see if everyone's accepted and count the number of players in the game
  288. UnicodeString mapDisplayName;
  289. const MapMetaData *mapData = TheMapCache->findMap( myGame->getMap() );
  290. Bool willTransfer = TRUE;
  291. if (mapData)
  292. {
  293. mapDisplayName.format(L"%ls", mapData->m_displayName.str());
  294. willTransfer = !mapData->m_isOfficial;
  295. }
  296. else
  297. {
  298. mapDisplayName.format(L"%hs", myGame->getMap().str());
  299. willTransfer = WouldMapTransfer(myGame->getMap());
  300. }
  301. for( i = 0; i < MAX_SLOTS; i++ )
  302. {
  303. LANGameSlot *slot = myGame->getLANSlot(i);
  304. if( slot->isHuman() && !slot->isAccepted())
  305. {
  306. isReady = false;
  307. if (!willTransfer)
  308. {
  309. if (!slot->hasMap())
  310. {
  311. UnicodeString msg;
  312. msg.format(TheGameText->fetch("GUI:PlayerNoMap"), slot->getName().str(), mapDisplayName.str());
  313. GadgetListBoxAddEntryText(listboxChatWindowLanGame, msg , chatSystemColor, -1, 0);
  314. allHaveMap = false;
  315. }
  316. }
  317. }
  318. if( slot->isHuman() && slot->getPlayerTemplate() != PLAYERTEMPLATE_OBSERVER )
  319. playerCount++;
  320. }
  321. if(isReady)
  322. {
  323. for( i = 0; i < MAX_SLOTS; i++ )
  324. {
  325. LANGameSlot *slot = myGame->getLANSlot(i);
  326. if (slot && slot->isOpen())
  327. {
  328. slot->setState( SLOT_CLOSED );
  329. GadgetComboBoxSetSelectedPos(comboBoxPlayer[i], SLOT_CLOSED);
  330. }
  331. }
  332. Int seconds = TheMultiplayerSettings->getStartCountdownTimerSeconds();
  333. if (seconds)
  334. TheLAN->RequestGameStartTimer(seconds);
  335. else
  336. TheLAN->RequestGameStart();
  337. LANEnableStartButton(false);
  338. }
  339. else
  340. {
  341. // Does everyone have the map?
  342. if (allHaveMap)
  343. {
  344. GadgetListBoxAddEntryText(listboxChatWindowLanGame, TheGameText->fetch("GUI:NotifiedStartIntent") , chatSystemColor, -1, 0);
  345. TheLAN->RequestAccept();
  346. }
  347. }
  348. }//void StartPressed(void)
  349. void LANEnableStartButton(Bool enabled)
  350. {
  351. buttonStart->winEnable(enabled);
  352. buttonSelectMap->winEnable(enabled);
  353. }
  354. static void handleColorSelection(int index)
  355. {
  356. GameWindow *combo = comboBoxColor[index];
  357. Int color, selIndex;
  358. GadgetComboBoxGetSelectedPos(combo, &selIndex);
  359. color = (Int)GadgetComboBoxGetItemData(combo, selIndex);
  360. LANGameInfo *myGame = TheLAN->GetMyGame();
  361. if (myGame)
  362. {
  363. LANGameSlot * slot = myGame->getLANSlot(index);
  364. if (color == slot->getColor())
  365. return;
  366. if (color >= -1 && color < TheMultiplayerSettings->getNumColors())
  367. {
  368. Bool colorAvailable = TRUE;
  369. if(color != -1 )
  370. {
  371. for(Int i=0; i <MAX_SLOTS; i++)
  372. {
  373. LANGameSlot *checkSlot = myGame->getLANSlot(i);
  374. if(color == checkSlot->getColor() && slot != checkSlot)
  375. {
  376. colorAvailable = FALSE;
  377. break;
  378. }
  379. }
  380. }
  381. if(!colorAvailable)
  382. return;
  383. }
  384. slot->setColor(color);
  385. if (myGame->amIHost())
  386. {
  387. if (!s_isIniting)
  388. {
  389. // send around a new slotlist
  390. TheLAN->RequestGameOptions(GenerateGameOptionsString(), true);
  391. lanUpdateSlotList();
  392. }
  393. }
  394. else
  395. {
  396. // request the color from the host
  397. if (!slot->isLocalPlayer() || !AreSlotListUpdatesEnabled())
  398. return;
  399. AsciiString options;
  400. options.format("Color=%d", color);
  401. TheLAN->RequestGameOptions(options, true);
  402. }
  403. }
  404. }
  405. static void handlePlayerTemplateSelection(int index)
  406. {
  407. GameWindow *combo = comboBoxPlayerTemplate[index];
  408. Int playerTemplate, selIndex;
  409. GadgetComboBoxGetSelectedPos(combo, &selIndex);
  410. playerTemplate = (Int)GadgetComboBoxGetItemData(combo, selIndex);
  411. LANGameInfo *myGame = TheLAN->GetMyGame();
  412. if (myGame)
  413. {
  414. LANGameSlot * slot = myGame->getLANSlot(index);
  415. if (playerTemplate == slot->getPlayerTemplate())
  416. return;
  417. Int oldTemplate = slot->getPlayerTemplate();
  418. slot->setPlayerTemplate(playerTemplate);
  419. if (oldTemplate == PLAYERTEMPLATE_OBSERVER)
  420. {
  421. // was observer, so populate color & team with all, and enable
  422. GadgetComboBoxSetSelectedPos(comboBoxColor[index], 0);
  423. GadgetComboBoxSetSelectedPos(comboBoxTeam[index], 0);
  424. slot->setStartPos(-1);
  425. }
  426. else if (playerTemplate == PLAYERTEMPLATE_OBSERVER)
  427. {
  428. // is becoming observer, so populate color & team with random only, and disable
  429. GadgetComboBoxSetSelectedPos(comboBoxColor[index], 0);
  430. GadgetComboBoxSetSelectedPos(comboBoxTeam[index], 0);
  431. slot->setStartPos(-1);
  432. }
  433. myGame->resetAccepted();
  434. if (myGame->amIHost())
  435. {
  436. if (!s_isIniting)
  437. {
  438. // send around a new slotlist
  439. TheLAN->RequestGameOptions(GenerateGameOptionsString(), true);
  440. lanUpdateSlotList();
  441. }
  442. }
  443. else
  444. {
  445. // request the playerTemplate from the host
  446. if (AreSlotListUpdatesEnabled())
  447. {
  448. AsciiString options;
  449. options.format("PlayerTemplate=%d", playerTemplate);
  450. TheLAN->RequestGameOptions(options, true);
  451. }
  452. }
  453. }
  454. }
  455. static void handleStartPositionSelection(Int player, int startPos)
  456. {
  457. LANGameInfo *myGame = TheLAN->GetMyGame();
  458. if (myGame)
  459. {
  460. LANGameSlot * slot = myGame->getLANSlot(player);
  461. if (startPos == slot->getStartPos())
  462. return;
  463. Bool skip = FALSE;
  464. if (startPos < 0)
  465. {
  466. skip = TRUE;
  467. }
  468. if(!skip)
  469. {
  470. Bool isAvailable = TRUE;
  471. for(Int i = 0; i < MAX_SLOTS; ++i)
  472. {
  473. if(i != player && myGame->getSlot(i)->getStartPos() == startPos)
  474. {
  475. isAvailable = FALSE;
  476. break;
  477. }
  478. }
  479. if( !isAvailable )
  480. return;
  481. }
  482. slot->setStartPos(startPos);
  483. if (myGame->amIHost())
  484. {
  485. if (!s_isIniting)
  486. {
  487. // send around a new slotlist
  488. myGame->resetAccepted();
  489. TheLAN->RequestGameOptions(GenerateGameOptionsString(), true);
  490. lanUpdateSlotList();
  491. }
  492. }
  493. else
  494. {
  495. // request the color from the host
  496. if (AreSlotListUpdatesEnabled())
  497. {
  498. AsciiString options;
  499. options.format("StartPos=%d", slot->getStartPos());
  500. TheLAN->RequestGameOptions(options, true);
  501. }
  502. }
  503. }
  504. }
  505. static void handleTeamSelection(int index)
  506. {
  507. GameWindow *combo = comboBoxTeam[index];
  508. Int team, selIndex;
  509. GadgetComboBoxGetSelectedPos(combo, &selIndex);
  510. team = (Int)GadgetComboBoxGetItemData(combo, selIndex);
  511. LANGameInfo *myGame = TheLAN->GetMyGame();
  512. if (myGame)
  513. {
  514. LANGameSlot * slot = myGame->getLANSlot(index);
  515. if (team == slot->getTeamNumber())
  516. return;
  517. slot->setTeamNumber(team);
  518. myGame->resetAccepted();
  519. if (myGame->amIHost())
  520. {
  521. if (!s_isIniting)
  522. {
  523. // send around a new slotlist
  524. myGame->resetAccepted();
  525. TheLAN->RequestGameOptions(GenerateGameOptionsString(), true);
  526. lanUpdateSlotList();
  527. }
  528. }
  529. else
  530. {
  531. // request the team from the host
  532. if (AreSlotListUpdatesEnabled())
  533. {
  534. AsciiString options;
  535. options.format("Team=%d", team);
  536. TheLAN->RequestGameOptions(options, true);
  537. }
  538. }
  539. }
  540. }
  541. void lanUpdateSlotList( void )
  542. {
  543. if(!AreSlotListUpdatesEnabled() || s_isIniting)
  544. return;
  545. UpdateSlotList( TheLAN->GetMyGame(), comboBoxPlayer, comboBoxColor,
  546. comboBoxPlayerTemplate, comboBoxTeam, buttonAccept, buttonStart, buttonMapStartPosition);
  547. updateMapStartSpots(TheLAN->GetMyGame(), buttonMapStartPosition);
  548. }
  549. //-------------------------------------------------------------------------------------------------
  550. /** Initialize the Gadgets Options Menu */
  551. //-------------------------------------------------------------------------------------------------
  552. void InitLanGameGadgets( void )
  553. {
  554. //Initialize the gadget IDs
  555. parentLanGameOptionsID = TheNameKeyGenerator->nameToKey( AsciiString( "LanGameOptionsMenu.wnd:LanGameOptionsMenuParent" ) );
  556. buttonBackID = TheNameKeyGenerator->nameToKey( AsciiString( "LanGameOptionsMenu.wnd:ButtonBack" ) );
  557. buttonStartID = TheNameKeyGenerator->nameToKey( AsciiString( "LanGameOptionsMenu.wnd:ButtonStart" ) );
  558. textEntryChatID = TheNameKeyGenerator->nameToKey( AsciiString( "LanGameOptionsMenu.wnd:TextEntryChat" ) );
  559. textEntryMapDisplayID = TheNameKeyGenerator->nameToKey( AsciiString( "LanGameOptionsMenu.wnd:TextEntryMapDisplay" ) );
  560. listboxChatWindowLanGameID = TheNameKeyGenerator->nameToKey( AsciiString( "LanGameOptionsMenu.wnd:ListboxChatWindowLanGame" ) );
  561. buttonEmoteID = TheNameKeyGenerator->nameToKey( AsciiString( "LanGameOptionsMenu.wnd:ButtonEmote" ) );
  562. buttonSelectMapID = TheNameKeyGenerator->nameToKey( AsciiString( "LanGameOptionsMenu.wnd:ButtonSelectMap" ) );
  563. windowMapID = TheNameKeyGenerator->nameToKey( AsciiString( "LanGameOptionsMenu.wnd:MapWindow" ) );
  564. // Initialize the pointers to our gadgets
  565. parentLanGameOptions = TheWindowManager->winGetWindowFromId( NULL, parentLanGameOptionsID );
  566. DEBUG_ASSERTCRASH(parentLanGameOptions, ("Could not find the parentLanGameOptions"));
  567. buttonEmote = TheWindowManager->winGetWindowFromId( parentLanGameOptions,buttonEmoteID );
  568. DEBUG_ASSERTCRASH(buttonEmote, ("Could not find the buttonEmote"));
  569. buttonSelectMap = TheWindowManager->winGetWindowFromId( parentLanGameOptions,buttonSelectMapID );
  570. DEBUG_ASSERTCRASH(buttonSelectMap, ("Could not find the buttonSelectMap"));
  571. buttonStart = TheWindowManager->winGetWindowFromId( parentLanGameOptions,buttonStartID );
  572. DEBUG_ASSERTCRASH(buttonStart, ("Could not find the buttonStart"));
  573. buttonBack = TheWindowManager->winGetWindowFromId( parentLanGameOptions, buttonBackID);
  574. DEBUG_ASSERTCRASH(buttonBack, ("Could not find the buttonBack"));
  575. listboxChatWindowLanGame = TheWindowManager->winGetWindowFromId( parentLanGameOptions, listboxChatWindowLanGameID );
  576. DEBUG_ASSERTCRASH(listboxChatWindowLanGame, ("Could not find the listboxChatWindowLanGame"));
  577. textEntryChat = TheWindowManager->winGetWindowFromId( parentLanGameOptions, textEntryChatID );
  578. DEBUG_ASSERTCRASH(textEntryChat, ("Could not find the textEntryChat"));
  579. textEntryMapDisplay = TheWindowManager->winGetWindowFromId( parentLanGameOptions, textEntryMapDisplayID );
  580. DEBUG_ASSERTCRASH(textEntryMapDisplay, ("Could not find the textEntryMapDisplay"));
  581. windowMap = TheWindowManager->winGetWindowFromId( parentLanGameOptions,windowMapID );
  582. DEBUG_ASSERTCRASH(windowMap, ("Could not find the LanGameOptionsMenu.wnd:MapWindow" ));
  583. Int localSlotNum = TheLAN->GetMyGame()->getLocalSlotNum();
  584. DEBUG_ASSERTCRASH(localSlotNum >= 0, ("Bad slot number!"));
  585. //Added By Sadullah Nader
  586. //Tooltip function is being set for techBuildings, and supplyDocks
  587. windowMap->winSetTooltipFunc(MapSelectorTooltip);
  588. //End Add
  589. for (Int i = 0; i < MAX_SLOTS; i++)
  590. {
  591. AsciiString tmpString;
  592. tmpString.format("LanGameOptionsMenu.wnd:ComboBoxPlayer%d", i);
  593. comboBoxPlayerID[i] = TheNameKeyGenerator->nameToKey( tmpString );
  594. comboBoxPlayer[i] = TheWindowManager->winGetWindowFromId( parentLanGameOptions, comboBoxPlayerID[i] );
  595. GadgetComboBoxReset(comboBoxPlayer[i]);
  596. GadgetComboBoxGetEditBox(comboBoxPlayer[i])->winSetTooltipFunc(playerTooltip);
  597. if(localSlotNum == i)
  598. {
  599. GadgetComboBoxAddEntry(comboBoxPlayer[i],TheLAN->GetMyName(),white);
  600. }
  601. else
  602. {
  603. GadgetComboBoxAddEntry(comboBoxPlayer[i],TheGameText->fetch("GUI:Open"),white);
  604. GadgetComboBoxAddEntry(comboBoxPlayer[i],TheGameText->fetch("GUI:Closed"),white);
  605. GadgetComboBoxAddEntry(comboBoxPlayer[i],TheGameText->fetch("GUI:EasyAI"),white);
  606. GadgetComboBoxAddEntry(comboBoxPlayer[i],TheGameText->fetch("GUI:MediumAI"),white);
  607. GadgetComboBoxAddEntry(comboBoxPlayer[i],TheGameText->fetch("GUI:HardAI"),white);
  608. GadgetComboBoxSetSelectedPos(comboBoxPlayer[i],0);
  609. }
  610. /*
  611. if(i != 0)
  612. {
  613. TheLAN->GetMyGame()->getLANSlot(i)->setState(SLOT_OPEN);
  614. }
  615. */
  616. tmpString.format("LanGameOptionsMenu.wnd:ComboBoxColor%d", i);
  617. comboBoxColorID[i] = TheNameKeyGenerator->nameToKey( tmpString );
  618. comboBoxColor[i] = TheWindowManager->winGetWindowFromId( parentLanGameOptions, comboBoxColorID[i] );
  619. DEBUG_ASSERTCRASH(comboBoxColor[i], ("Could not find the comboBoxColor[%d]",i ));
  620. PopulateColorComboBox(i, comboBoxColor, TheLAN->GetMyGame());
  621. GadgetComboBoxSetSelectedPos(comboBoxColor[i], 0);
  622. tmpString.format("LanGameOptionsMenu.wnd:ComboBoxPlayerTemplate%d", i);
  623. comboBoxPlayerTemplateID[i] = TheNameKeyGenerator->nameToKey( tmpString );
  624. comboBoxPlayerTemplate[i] = TheWindowManager->winGetWindowFromId( parentLanGameOptions, comboBoxPlayerTemplateID[i] );
  625. DEBUG_ASSERTCRASH(comboBoxPlayerTemplate[i], ("Could not find the comboBoxPlayerTemplate[%d]",i ));
  626. PopulatePlayerTemplateComboBox(i, comboBoxPlayerTemplate, TheLAN->GetMyGame(), TRUE);
  627. tmpString.format("LanGameOptionsMenu.wnd:ComboBoxTeam%d", i);
  628. comboBoxTeamID[i] = TheNameKeyGenerator->nameToKey( tmpString );
  629. comboBoxTeam[i] = TheWindowManager->winGetWindowFromId( parentLanGameOptions, comboBoxTeamID[i] );
  630. DEBUG_ASSERTCRASH(comboBoxTeam[i], ("Could not find the comboBoxTeam[%d]",i ));
  631. PopulateTeamComboBox(i, comboBoxTeam, TheLAN->GetMyGame());
  632. tmpString.clear();
  633. tmpString.format("LanGameOptionsMenu.wnd:ButtonAccept%d", i);
  634. buttonAcceptID[i] = TheNameKeyGenerator->nameToKey( tmpString );
  635. buttonAccept[i] = TheWindowManager->winGetWindowFromId( parentLanGameOptions, buttonAcceptID[i] );
  636. DEBUG_ASSERTCRASH(buttonAccept[i], ("Could not find the buttonAccept[%d]",i ));
  637. //Added by Saad for the tooltips on the MultiPlayer icons
  638. buttonAccept[i]->winSetTooltipFunc(gameAcceptTooltip);
  639. //
  640. // tmpString.format("LanGameOptionsMenu.wnd:ButtonStartPosition%d", i);
  641. // buttonStartPositionID[i] = TheNameKeyGenerator->nameToKey( tmpString );
  642. // buttonStartPosition[i] = TheWindowManager->winGetWindowFromId( parentLanGameOptions, buttonStartPositionID[i] );
  643. // DEBUG_ASSERTCRASH(buttonStartPosition[i], ("Could not find the ButtonStartPosition[%d]",i ));
  644. tmpString.format("LanGameOptionsMenu.wnd:ButtonMapStartPosition%d", i);
  645. buttonMapStartPositionID[i] = TheNameKeyGenerator->nameToKey( tmpString );
  646. buttonMapStartPosition[i] = TheWindowManager->winGetWindowFromId( parentLanGameOptions, buttonMapStartPositionID[i] );
  647. DEBUG_ASSERTCRASH(buttonMapStartPosition[i], ("Could not find the ButtonMapStartPosition[%d]",i ));
  648. if(i !=0 && buttonAccept[i])
  649. buttonAccept[i]->winHide(TRUE);
  650. }
  651. if( buttonAccept[0] )
  652. GadgetButtonSetEnabledColor(buttonAccept[0], acceptTrueColor );
  653. }
  654. void DeinitLanGameGadgets( void )
  655. {
  656. parentLanGameOptions = NULL;
  657. buttonEmote = NULL;
  658. buttonSelectMap = NULL;
  659. buttonStart = NULL;
  660. buttonBack = NULL;
  661. listboxChatWindowLanGame = NULL;
  662. textEntryChat = NULL;
  663. textEntryMapDisplay = NULL;
  664. windowMap = NULL;
  665. for (Int i = 0; i < MAX_SLOTS; i++)
  666. {
  667. comboBoxPlayer[i] = NULL;
  668. comboBoxColor[i] = NULL;
  669. comboBoxPlayerTemplate[i] = NULL;
  670. comboBoxTeam[i] = NULL;
  671. buttonAccept[i] = NULL;
  672. // buttonStartPosition[i] = NULL;
  673. buttonMapStartPosition[i] = NULL;
  674. }
  675. }
  676. //-------------------------------------------------------------------------------------------------
  677. /** Initialize the Lan Game Options Menu */
  678. //-------------------------------------------------------------------------------------------------
  679. void LanGameOptionsMenuInit( WindowLayout *layout, void *userData )
  680. {
  681. if (TheLAN->GetMyGame() && TheLAN->GetMyGame()->isGameInProgress())
  682. {
  683. // If we init while the game is in progress, we are really returning to the menu
  684. // after the game. So, we pop the menu and go back to the lobby. Whee!
  685. DEBUG_LOG(("Popping to lobby after a game!\n"));
  686. TheShell->popImmediate();
  687. return;
  688. }
  689. s_isIniting = TRUE;
  690. LANbuttonPushed = false;
  691. LANisShuttingDown = false;
  692. //initialize the gadgets
  693. EnableSlotListUpdates(FALSE);
  694. InitLanGameGadgets();
  695. EnableSlotListUpdates(TRUE);
  696. Int start = 0;
  697. // Make sure the text fields are clear
  698. GadgetListBoxReset( listboxChatWindowLanGame );
  699. GadgetTextEntrySetText(textEntryChat, UnicodeString::TheEmptyString);
  700. //The dialog needs to react differently depending on whether it's the host or not.
  701. TheMapCache->updateCache();
  702. if (TheLAN->AmIHost())
  703. {
  704. // read in some prefs
  705. LANGameInfo *game = TheLAN->GetMyGame();
  706. LANGameSlot *slot = game->getLANSlot(0);
  707. LANPreferences pref;
  708. slot->setColor( pref.getPreferredColor() );
  709. slot->setPlayerTemplate( pref.getPreferredFaction() );
  710. slot->setNATBehavior(FirewallHelperClass::FIREWALL_TYPE_SIMPLE);
  711. game->setMap( pref.getPreferredMap() );
  712. AsciiString lowerMap = pref.getPreferredMap();
  713. lowerMap.toLower();
  714. std::map<AsciiString, MapMetaData>::iterator it = TheMapCache->find(lowerMap);
  715. if (it != TheMapCache->end())
  716. {
  717. TheLAN->GetMyGame()->getSlot(0)->setMapAvailability(true);
  718. TheLAN->GetMyGame()->setMapCRC( it->second.m_CRC );
  719. TheLAN->GetMyGame()->setMapSize( it->second.m_filesize );
  720. TheLAN->GetMyGame()->adjustSlotsForMap(); // BGC- adjust the slots for the selected map.
  721. }
  722. //GadgetTextEntrySetText(comboBoxPlayer[0], TheLAN->GetMyName());
  723. lanUpdateSlotList();
  724. updateGameOptions();
  725. start = 1; // leave my combo boxes usable
  726. }
  727. else
  728. {
  729. //DEBUG_LOG(("LanGameOptionsMenuInit(): map is %s\n", TheLAN->GetMyGame()->getMap().str()));
  730. buttonStart->winSetText(TheGameText->fetch("GUI:Accept"));
  731. buttonSelectMap->winEnable( FALSE );
  732. TheLAN->GetMyGame()->setMapCRC( TheLAN->GetMyGame()->getMapCRC() ); // force a recheck
  733. TheLAN->GetMyGame()->setMapSize( TheLAN->GetMyGame()->getMapSize() ); // of if we have the map
  734. TheLAN->RequestHasMap();
  735. lanUpdateSlotList();
  736. updateGameOptions();
  737. }
  738. for (Int i = start; i < MAX_SLOTS; ++i)
  739. {
  740. //I'm a client, disable the controls I can't touch.
  741. if (!TheLAN->AmIHost())
  742. comboBoxPlayer[i]->winEnable(FALSE);
  743. comboBoxColor[i]->winEnable(FALSE);
  744. comboBoxPlayerTemplate[i]->winEnable(FALSE);
  745. comboBoxTeam[i]->winEnable(FALSE);
  746. // buttonStartPosition[i]->winEnable(FALSE);
  747. }
  748. // for (i = 0; i < MAX_SLOTS; ++i)
  749. // {
  750. // if (buttonStartPosition[i])
  751. // buttonStartPosition[i]->winHide(TRUE); // not picking start spots this way any more
  752. // }
  753. //
  754. // Show the Menu
  755. layout->hide( FALSE );
  756. // Set Keyboard to Main Parent
  757. TheWindowManager->winSetFocus( parentLanGameOptions );
  758. s_isIniting = FALSE;
  759. if (TheLAN->AmIHost())
  760. {
  761. TheLAN->RequestGameOptions(GenerateGameOptionsString(),true);
  762. TheLAN->RequestGameAnnounce();
  763. }
  764. lanUpdateSlotList();
  765. LanPositionStartSpots();
  766. TheTransitionHandler->setGroup("LanGameOptionsFade");
  767. // animate controls
  768. //TheShell->registerWithAnimateManager(buttonBack, WIN_ANIMATION_SLIDE_RIGHT, TRUE, 1);
  769. }// void LanGameOptionsMenuInit( WindowLayout *layout, void *userData )
  770. //-------------------------------------------------------------------------------------------------
  771. /** Update options on screen */
  772. //-------------------------------------------------------------------------------------------------
  773. void updateGameOptions( void )
  774. {
  775. LANGameInfo *theGame = TheLAN->GetMyGame();
  776. UnicodeString mapDisplayName;
  777. if (theGame && AreSlotListUpdatesEnabled())
  778. {
  779. const GameSlot *localSlot = theGame->getConstSlot(theGame->getLocalSlotNum());
  780. const MapMetaData *mapData = TheMapCache->findMap( TheLAN->GetMyGame()->getMap() );
  781. if (mapData && localSlot && localSlot->hasMap())
  782. {
  783. mapDisplayName.format(L"%ls", mapData->m_displayName.str());
  784. }
  785. else
  786. {
  787. AsciiString s = TheLAN->GetMyGame()->getMap();
  788. if (s.reverseFind('\\'))
  789. {
  790. s = s.reverseFind('\\') + 1;
  791. }
  792. mapDisplayName.format(L"%hs", s.str());
  793. }
  794. UnicodeString old = GadgetStaticTextGetText(textEntryMapDisplay);
  795. if(old.compare(mapDisplayName) != 0)
  796. LanPositionStartSpots();
  797. GadgetStaticTextSetText(textEntryMapDisplay, mapDisplayName);
  798. }
  799. }
  800. //-------------------------------------------------------------------------------------------------
  801. /** This is called when a shutdown is complete for this menu */
  802. //-------------------------------------------------------------------------------------------------
  803. static void shutdownComplete( WindowLayout *layout )
  804. {
  805. DeinitLanGameGadgets();
  806. textEntryMapDisplay = NULL;
  807. LANisShuttingDown = false;
  808. // hide the layout
  809. layout->hide( TRUE );
  810. // our shutdown is complete
  811. TheShell->shutdownComplete( layout, (LANnextScreen != NULL) );
  812. if (LANnextScreen != NULL)
  813. {
  814. TheShell->push(LANnextScreen);
  815. }
  816. LANnextScreen = NULL;
  817. } // end if
  818. //-------------------------------------------------------------------------------------------------
  819. /** Lan Game Options menu shutdown method */
  820. //-------------------------------------------------------------------------------------------------
  821. void LanGameOptionsMenuShutdown( WindowLayout *layout, void *userData )
  822. {
  823. TheMouse->setCursor(Mouse::ARROW);
  824. TheMouse->setMouseText(UnicodeString::TheEmptyString,NULL,NULL);
  825. EnableSlotListUpdates(FALSE);
  826. LANisShuttingDown = true;
  827. // if we are shutting down for an immediate pop, skip the animations
  828. Bool popImmediate = *(Bool *)userData;
  829. if( popImmediate )
  830. {
  831. shutdownComplete( layout );
  832. return;
  833. } //end if
  834. TheShell->reverseAnimatewindow();
  835. TheTransitionHandler->reverse("LanGameOptionsFade");
  836. if (TheLAN)
  837. TheLAN->ResetGameStartTimer();
  838. /*
  839. // hide menu
  840. layout->hide( TRUE );
  841. // Reset the LAN singleton
  842. // TheLAN->reset();
  843. // our shutdown is complete
  844. TheShell->shutdownComplete( layout );
  845. */
  846. } // void LanGameOptionsMenuShutdown( WindowLayout *layout, void *userData )
  847. //-------------------------------------------------------------------------------------------------
  848. /** Lan Game Options menu update method */
  849. //-------------------------------------------------------------------------------------------------
  850. void LanGameOptionsMenuUpdate( WindowLayout * layout, void *userData)
  851. {
  852. if(LANisShuttingDown && TheShell->isAnimFinished() && TheTransitionHandler->isFinished())
  853. shutdownComplete(layout);
  854. //TheLAN->update(); // this is handled in the lobby
  855. }// void LanGameOptionsMenuUpdate( WindowLayout * layout, void *userData)
  856. //-------------------------------------------------------------------------------------------------
  857. /** Lan Game Options menu input callback */
  858. //-------------------------------------------------------------------------------------------------
  859. WindowMsgHandledType LanGameOptionsMenuInput( GameWindow *window, UnsignedInt msg,
  860. WindowMsgData mData1, WindowMsgData mData2 )
  861. {
  862. switch( msg )
  863. {
  864. // --------------------------------------------------------------------------------------------
  865. case GWM_CHAR:
  866. {
  867. UnsignedByte key = mData1;
  868. UnsignedByte state = mData2;
  869. if (LANbuttonPushed)
  870. break;
  871. switch( key )
  872. {
  873. // ----------------------------------------------------------------------------------------
  874. case KEY_ESC:
  875. {
  876. //
  877. // send a simulated selected event to the parent window of the
  878. // back/exit button
  879. //
  880. if( BitTest( state, KEY_STATE_UP ) )
  881. {
  882. TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
  883. (WindowMsgData)buttonBack, buttonBackID );
  884. } // end if
  885. // don't let key fall through anywhere else
  886. return MSG_HANDLED;
  887. } // end escape
  888. } // end switch( key )
  889. } // end char
  890. } // end switch( msg )
  891. return MSG_IGNORED;
  892. }//WindowMsgHandledType LanGameOptionsMenuInput( GameWindow *window, UnsignedInt msg,
  893. //-------------------------------------------------------------------------------------------------
  894. /** Lan Game Options menu window system callback */
  895. //-------------------------------------------------------------------------------------------------
  896. WindowMsgHandledType LanGameOptionsMenuSystem( GameWindow *window, UnsignedInt msg,
  897. WindowMsgData mData1, WindowMsgData mData2 )
  898. {
  899. UnicodeString txtInput;
  900. switch( msg )
  901. {
  902. //-------------------------------------------------------------------------------------------------
  903. case GWM_CREATE:
  904. {
  905. break;
  906. } // case GWM_DESTROY:
  907. //-------------------------------------------------------------------------------------------------
  908. case GWM_DESTROY:
  909. {
  910. break;
  911. } // case GWM_DESTROY:
  912. //-------------------------------------------------------------------------------------------------
  913. case GWM_INPUT_FOCUS:
  914. {
  915. // if we're givin the opportunity to take the keyboard focus we must say we want it
  916. if( mData1 == TRUE )
  917. *(Bool *)mData2 = TRUE;
  918. return MSG_HANDLED;
  919. }//case GWM_INPUT_FOCUS:
  920. //-------------------------------------------------------------------------------------------------
  921. case GCM_SELECTED:
  922. {
  923. if (LANbuttonPushed)
  924. break;
  925. GameWindow *control = (GameWindow *)mData1;
  926. Int controlID = control->winGetWindowId();
  927. LANGameInfo *myGame = TheLAN->GetMyGame();
  928. for (Int i = 0; i < MAX_SLOTS; i++)
  929. {
  930. if (controlID == comboBoxColorID[i])
  931. {
  932. handleColorSelection(i);
  933. }
  934. else if (controlID == comboBoxPlayerTemplateID[i])
  935. {
  936. handlePlayerTemplateSelection(i);
  937. }
  938. else if (controlID == comboBoxTeamID[i])
  939. {
  940. handleTeamSelection(i);
  941. }
  942. else if( controlID == comboBoxPlayerID[i] && myGame->amIHost() )
  943. {
  944. // We don't have anything that'll happen if we click on ourselves
  945. if(i == myGame->getLocalSlotNum())
  946. break;
  947. // Get
  948. Int pos = -1;
  949. GadgetComboBoxGetSelectedPos(comboBoxPlayer[i], &pos);
  950. if( pos != SLOT_PLAYER && pos >= 0)
  951. {
  952. if( myGame->getLANSlot(i)->getState() == SLOT_PLAYER )
  953. {
  954. UnicodeString name = myGame->getPlayerName(i);
  955. myGame->getLANSlot(i)->setState(SlotState(pos));
  956. myGame->resetAccepted();
  957. TheLAN->OnPlayerLeave(name);
  958. }
  959. else if( myGame->getLANSlot(i)->getState() != pos )
  960. {
  961. Bool wasAI = (myGame->getLANSlot(i)->isAI());
  962. myGame->getLANSlot(i)->setState(SlotState(pos));
  963. Bool isAI = (myGame->getLANSlot(i)->isAI());
  964. if (wasAI || isAI)
  965. myGame->resetAccepted();
  966. if (wasAI ^ isAI)
  967. PopulatePlayerTemplateComboBox(i, comboBoxPlayerTemplate, myGame, wasAI);
  968. if (!s_isIniting)
  969. {
  970. TheLAN->RequestGameOptions(GenerateGameOptionsString(), true);
  971. lanUpdateSlotList();
  972. }
  973. }
  974. }
  975. break;
  976. }
  977. }
  978. }// case GCM_SELECTED:
  979. //-------------------------------------------------------------------------------------------------
  980. case GBM_SELECTED:
  981. {
  982. if (LANbuttonPushed)
  983. break;
  984. GameWindow *control = (GameWindow *)mData1;
  985. Int controlID = control->winGetWindowId();
  986. if ( controlID == buttonBackID )
  987. {
  988. if( mapSelectLayout )
  989. {
  990. mapSelectLayout->destroyWindows();
  991. mapSelectLayout->deleteInstance();
  992. mapSelectLayout = NULL;
  993. }
  994. TheLAN->RequestGameLeave();
  995. //TheShell->pop();
  996. } //if ( controlID == buttonBack )
  997. else if ( controlID == buttonEmoteID )
  998. {
  999. // read the user's input
  1000. txtInput.set(GadgetTextEntryGetText( textEntryChat ));
  1001. // Clear the text entry line
  1002. GadgetTextEntrySetText(textEntryChat, UnicodeString::TheEmptyString);
  1003. // Clean up the text (remove leading/trailing chars, etc)
  1004. txtInput.trim();
  1005. // Echo the user's input to the chat window
  1006. if (!txtInput.isEmpty())
  1007. TheLAN->RequestChat(txtInput, LANAPIInterface::LANCHAT_EMOTE);
  1008. } //if ( controlID == buttonEmote )
  1009. else if ( controlID == buttonSelectMapID )
  1010. {
  1011. //buttonBack->winEnable( false );
  1012. mapSelectLayout = TheWindowManager->winCreateLayout( AsciiString( "Menus/LanMapSelectMenu.wnd" ) );
  1013. mapSelectLayout->runInit();
  1014. mapSelectLayout->hide( FALSE );
  1015. mapSelectLayout->bringForward();
  1016. }
  1017. else if ( controlID == buttonStartID )
  1018. {
  1019. if (TheLAN->AmIHost())
  1020. {
  1021. StartPressed();
  1022. //TheLAN->RequestGameStart();
  1023. }
  1024. else
  1025. {
  1026. //I'm the Client... send an accept message to the host.
  1027. TheLAN->RequestAccept();
  1028. // Disable the accept button
  1029. EnableAcceptControls(TRUE, TheLAN->GetMyGame(), comboBoxPlayer, comboBoxColor, comboBoxPlayerTemplate,
  1030. comboBoxTeam, buttonAccept, buttonStart, buttonMapStartPosition);
  1031. }
  1032. }
  1033. else
  1034. {
  1035. for (Int i = 0; i < MAX_SLOTS; i++)
  1036. {
  1037. if (controlID == buttonMapStartPositionID[i])
  1038. {
  1039. LANGameInfo *game = TheLAN->GetMyGame();
  1040. Int playerIdxInPos = -1;
  1041. for (Int j=0; j<MAX_SLOTS; ++j)
  1042. {
  1043. LANGameSlot *slot = game->getLANSlot(j);
  1044. if (slot && slot->getStartPos() == i)
  1045. {
  1046. playerIdxInPos = j;
  1047. break;
  1048. }
  1049. }
  1050. if (playerIdxInPos >= 0)
  1051. {
  1052. LANGameSlot *slot = game->getLANSlot(playerIdxInPos);
  1053. if (playerIdxInPos == game->getLocalSlotNum() || (game->amIHost() && slot && slot->isAI()))
  1054. {
  1055. // it's one of my type. Try to change it.
  1056. Int nextPlayer = getNextSelectablePlayer(playerIdxInPos+1);
  1057. handleStartPositionSelection(playerIdxInPos, -1);
  1058. if (nextPlayer >= 0)
  1059. {
  1060. handleStartPositionSelection(nextPlayer, i);
  1061. }
  1062. }
  1063. }
  1064. else
  1065. {
  1066. // nobody in the slot - put us in
  1067. Int nextPlayer = getNextSelectablePlayer(0);
  1068. if (nextPlayer < 0)
  1069. nextPlayer = getFirstSelectablePlayer(game);
  1070. handleStartPositionSelection(nextPlayer, i);
  1071. }
  1072. }
  1073. }
  1074. }
  1075. break;
  1076. }// case GBM_SELECTED:
  1077. //-------------------------------------------------------------------------------------------------
  1078. case GBM_SELECTED_RIGHT:
  1079. {
  1080. if (LANbuttonPushed)
  1081. break;
  1082. GameWindow *control = (GameWindow *)mData1;
  1083. Int controlID = control->winGetWindowId();
  1084. for (Int i = 0; i < MAX_SLOTS; i++)
  1085. {
  1086. if (controlID == buttonMapStartPositionID[i])
  1087. {
  1088. LANGameInfo *game = TheLAN->GetMyGame();
  1089. Int playerIdxInPos = -1;
  1090. for (Int j=0; j<MAX_SLOTS; ++j)
  1091. {
  1092. LANGameSlot *slot = game->getLANSlot(j);
  1093. if (slot && slot->getStartPos() == i)
  1094. {
  1095. playerIdxInPos = j;
  1096. break;
  1097. }
  1098. }
  1099. if (playerIdxInPos >= 0)
  1100. {
  1101. LANGameSlot *slot = game->getLANSlot(playerIdxInPos);
  1102. if (playerIdxInPos == game->getLocalSlotNum() || (game->amIHost() && slot && slot->isAI()))
  1103. {
  1104. // it's one of my type. Remove it.
  1105. handleStartPositionSelection(playerIdxInPos, -1);
  1106. }
  1107. }
  1108. }
  1109. }
  1110. break;
  1111. }
  1112. //-------------------------------------------------------------------------------------------------
  1113. case GEM_EDIT_DONE:
  1114. {
  1115. if (LANbuttonPushed)
  1116. break;
  1117. GameWindow *control = (GameWindow *)mData1;
  1118. Int controlID = control->winGetWindowId();
  1119. // Take the user's input and echo it into the chat window as well as
  1120. // send it to the other clients on the lan
  1121. if ( controlID == textEntryChatID )
  1122. {
  1123. // read the user's input
  1124. txtInput.set(GadgetTextEntryGetText( textEntryChat ));
  1125. // Clear the text entry line
  1126. GadgetTextEntrySetText(textEntryChat, UnicodeString::TheEmptyString);
  1127. // Clean up the text (remove leading/trailing chars, etc)
  1128. txtInput.trim();
  1129. // Echo the user's input to the chat window
  1130. if (!txtInput.isEmpty())
  1131. TheLAN->RequestChat(txtInput, LANAPIInterface::LANCHAT_NORMAL);
  1132. }// if ( controlID == textEntryChatID )
  1133. break;
  1134. }
  1135. //-------------------------------------------------------------------------------------------------
  1136. default:
  1137. return MSG_IGNORED;
  1138. }//Switch
  1139. return MSG_HANDLED;
  1140. }//WindowMsgHandledType LanGameOptionsMenuSystem( GameWindow *window, UnsignedInt msg,
  1141. //-------------------------------------------------------------------------------------------------
  1142. /** Utility FUnction used as a bridge from other windows to this one */
  1143. //-------------------------------------------------------------------------------------------------
  1144. void PostToLanGameOptions( PostToLanGameType post )
  1145. {
  1146. if (post >= POST_TO_LAN_GAME_TYPE_COUNT)
  1147. return;
  1148. LanPositionStartSpots();
  1149. switch (post)
  1150. {
  1151. //-------------------------------------------------------------------------------------------------
  1152. case SEND_GAME_OPTS:
  1153. {
  1154. LANGameInfo *game = TheLAN->GetMyGame();
  1155. game->resetAccepted();
  1156. updateGameOptions();
  1157. lanUpdateSlotList();
  1158. //buttonBack->winEnable( true );
  1159. for(Int i = 0; i < MAX_SLOTS; ++i)
  1160. {
  1161. game->getSlot(i)->setStartPos(-1);
  1162. }
  1163. TheLAN->RequestGameOptions(GenerateGameOptionsString(), true);
  1164. break;
  1165. } //-------------------------------------------------------------------------------------------------
  1166. case MAP_BACK:
  1167. {
  1168. //buttonBack->winEnable( true );
  1169. }
  1170. default:
  1171. return;
  1172. }
  1173. }