MessageStream.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239
  1. /*
  2. ** Command & Conquer Generals Zero Hour(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. // MessageStream.cpp
  24. // Implementation of the message stream
  25. // Author: Michael S. Booth, February 2001
  26. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  27. #include "Common/MessageStream.h"
  28. #include "Common/Player.h"
  29. #include "Common/PlayerList.h"
  30. #include "Common/Recorder.h"
  31. #include "GameClient/InGameUI.h"
  32. #include "GameLogic/GameLogic.h"
  33. /// The singleton message stream for messages going to TheGameLogic
  34. MessageStream *TheMessageStream = NULL;
  35. CommandList *TheCommandList = NULL;
  36. #ifdef _INTERNAL
  37. // for occasional debugging...
  38. //#pragma optimize("", off)
  39. //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
  40. #endif
  41. //------------------------------------------------------------------------------------------------
  42. // GameMessage
  43. //
  44. /**
  45. * Constructor
  46. */
  47. GameMessage::GameMessage( GameMessage::Type type )
  48. {
  49. m_playerIndex = ThePlayerList->getLocalPlayer()->getPlayerIndex();
  50. m_type = type;
  51. m_argList = NULL;
  52. m_argTail = NULL;
  53. m_argCount = 0;
  54. m_list = 0;
  55. }
  56. /**
  57. * Destructor
  58. */
  59. GameMessage::~GameMessage( )
  60. {
  61. // free all arguments
  62. GameMessageArgument *arg, *nextArg;
  63. for( arg = m_argList; arg; arg=nextArg )
  64. {
  65. nextArg = arg->m_next;
  66. arg->deleteInstance();
  67. }
  68. // detach message from list
  69. if (m_list)
  70. m_list->removeMessage( this );
  71. }
  72. /**
  73. * Return the given argument union.
  74. * @todo This should be a more list-like interface. Very inefficient.
  75. */
  76. const GameMessageArgumentType *GameMessage::getArgument( Int argIndex ) const
  77. {
  78. static const GameMessageArgumentType junk = { 0 };
  79. int i=0;
  80. for( GameMessageArgument *a = m_argList; a; a=a->m_next, i++ )
  81. if (i == argIndex)
  82. return &a->m_data;
  83. DEBUG_CRASH(("argument not found"));
  84. return &junk;
  85. }
  86. /**
  87. * Return the given argument data type
  88. */
  89. GameMessageArgumentDataType GameMessage::getArgumentDataType( Int argIndex )
  90. {
  91. if (argIndex >= m_argCount) {
  92. return ARGUMENTDATATYPE_UNKNOWN;
  93. }
  94. int i=0;
  95. for (GameMessageArgument *a = m_argList; a && (i < argIndex); a=a->m_next, ++i );
  96. if (a != NULL)
  97. {
  98. return a->m_type;
  99. }
  100. return ARGUMENTDATATYPE_UNKNOWN;
  101. }
  102. /**
  103. * Allocate a new argument, add it to the argument list, and increment the total arg count
  104. */
  105. GameMessageArgument *GameMessage::allocArg( void )
  106. {
  107. // allocate a new argument
  108. GameMessageArgument *arg = newInstance(GameMessageArgument);
  109. // add to end of argument list
  110. if (m_argTail)
  111. m_argTail->m_next = arg;
  112. else
  113. {
  114. m_argList = arg;
  115. m_argTail = arg;
  116. }
  117. arg->m_next = NULL;
  118. m_argTail = arg;
  119. m_argCount++;
  120. return arg;
  121. }
  122. /**
  123. * Append an integer argument
  124. */
  125. void GameMessage::appendIntegerArgument( Int arg )
  126. {
  127. GameMessageArgument *a = allocArg();
  128. a->m_data.integer = arg;
  129. a->m_type = ARGUMENTDATATYPE_INTEGER;
  130. }
  131. void GameMessage::appendRealArgument( Real arg )
  132. {
  133. GameMessageArgument *a = allocArg();
  134. a->m_data.real = arg;
  135. a->m_type = ARGUMENTDATATYPE_REAL;
  136. }
  137. void GameMessage::appendBooleanArgument( Bool arg )
  138. {
  139. GameMessageArgument *a = allocArg();
  140. a->m_data.boolean = arg;
  141. a->m_type = ARGUMENTDATATYPE_BOOLEAN;
  142. }
  143. void GameMessage::appendObjectIDArgument( ObjectID arg )
  144. {
  145. GameMessageArgument *a = allocArg();
  146. a->m_data.objectID = arg;
  147. a->m_type = ARGUMENTDATATYPE_OBJECTID;
  148. }
  149. void GameMessage::appendDrawableIDArgument( DrawableID arg )
  150. {
  151. GameMessageArgument *a = allocArg();
  152. a->m_data.drawableID = arg;
  153. a->m_type = ARGUMENTDATATYPE_DRAWABLEID;
  154. }
  155. void GameMessage::appendTeamIDArgument( UnsignedInt arg )
  156. {
  157. GameMessageArgument *a = allocArg();
  158. a->m_data.teamID = arg;
  159. a->m_type = ARGUMENTDATATYPE_TEAMID;
  160. }
  161. void GameMessage::appendLocationArgument( const Coord3D& arg )
  162. {
  163. GameMessageArgument *a = allocArg();
  164. a->m_data.location = arg;
  165. a->m_type = ARGUMENTDATATYPE_LOCATION;
  166. }
  167. void GameMessage::appendPixelArgument( const ICoord2D& arg )
  168. {
  169. GameMessageArgument *a = allocArg();
  170. a->m_data.pixel = arg;
  171. a->m_type = ARGUMENTDATATYPE_PIXEL;
  172. }
  173. void GameMessage::appendPixelRegionArgument( const IRegion2D& arg )
  174. {
  175. GameMessageArgument *a = allocArg();
  176. a->m_data.pixelRegion = arg;
  177. a->m_type = ARGUMENTDATATYPE_PIXELREGION;
  178. }
  179. void GameMessage::appendTimestampArgument( UnsignedInt arg )
  180. {
  181. GameMessageArgument *a = allocArg();
  182. a->m_data.timestamp = arg;
  183. a->m_type = ARGUMENTDATATYPE_TIMESTAMP;
  184. }
  185. void GameMessage::appendWideCharArgument( const WideChar& arg )
  186. {
  187. GameMessageArgument *a = allocArg();
  188. a->m_data.wChar = arg;
  189. a->m_type = ARGUMENTDATATYPE_WIDECHAR;
  190. }
  191. AsciiString GameMessage::getCommandAsAsciiString( void )
  192. {
  193. return getCommandTypeAsAsciiString(m_type);
  194. }
  195. AsciiString GameMessage::getCommandTypeAsAsciiString(GameMessage::Type t)
  196. {
  197. #define CHECK_IF(x) if (t == x) { return #x; }
  198. AsciiString commandName = "UnknownMessage";
  199. if (t >= GameMessage::MSG_COUNT)
  200. {
  201. commandName = "Invalid command";
  202. }
  203. CHECK_IF(MSG_INVALID)
  204. CHECK_IF(MSG_FRAME_TICK)
  205. CHECK_IF(MSG_RAW_MOUSE_BEGIN)
  206. CHECK_IF(MSG_RAW_MOUSE_POSITION)
  207. CHECK_IF(MSG_RAW_MOUSE_LEFT_BUTTON_DOWN)
  208. CHECK_IF(MSG_RAW_MOUSE_LEFT_DOUBLE_CLICK)
  209. CHECK_IF(MSG_RAW_MOUSE_LEFT_BUTTON_UP)
  210. CHECK_IF(MSG_RAW_MOUSE_LEFT_CLICK)
  211. CHECK_IF(MSG_RAW_MOUSE_LEFT_DRAG)
  212. CHECK_IF(MSG_RAW_MOUSE_MIDDLE_BUTTON_DOWN)
  213. CHECK_IF(MSG_RAW_MOUSE_MIDDLE_DOUBLE_CLICK)
  214. CHECK_IF(MSG_RAW_MOUSE_MIDDLE_BUTTON_UP)
  215. CHECK_IF(MSG_RAW_MOUSE_MIDDLE_DRAG)
  216. CHECK_IF(MSG_RAW_MOUSE_RIGHT_BUTTON_DOWN)
  217. CHECK_IF(MSG_RAW_MOUSE_RIGHT_DOUBLE_CLICK)
  218. CHECK_IF(MSG_RAW_MOUSE_RIGHT_BUTTON_UP)
  219. CHECK_IF(MSG_RAW_MOUSE_RIGHT_DRAG)
  220. CHECK_IF(MSG_RAW_MOUSE_WHEEL)
  221. CHECK_IF(MSG_RAW_MOUSE_END)
  222. CHECK_IF(MSG_RAW_KEY_DOWN)
  223. CHECK_IF(MSG_RAW_KEY_UP)
  224. CHECK_IF(MSG_MOUSE_LEFT_CLICK)
  225. CHECK_IF(MSG_MOUSE_LEFT_DOUBLE_CLICK)
  226. CHECK_IF(MSG_MOUSE_MIDDLE_CLICK)
  227. CHECK_IF(MSG_MOUSE_MIDDLE_DOUBLE_CLICK)
  228. CHECK_IF(MSG_MOUSE_RIGHT_CLICK)
  229. CHECK_IF(MSG_MOUSE_RIGHT_DOUBLE_CLICK)
  230. CHECK_IF(MSG_CLEAR_GAME_DATA)
  231. CHECK_IF(MSG_NEW_GAME)
  232. CHECK_IF(MSG_BEGIN_META_MESSAGES)
  233. CHECK_IF(MSG_META_SAVE_VIEW1)
  234. CHECK_IF(MSG_META_SAVE_VIEW2)
  235. CHECK_IF(MSG_META_SAVE_VIEW3)
  236. CHECK_IF(MSG_META_SAVE_VIEW4)
  237. CHECK_IF(MSG_META_SAVE_VIEW5)
  238. CHECK_IF(MSG_META_SAVE_VIEW6)
  239. CHECK_IF(MSG_META_SAVE_VIEW7)
  240. CHECK_IF(MSG_META_SAVE_VIEW8)
  241. CHECK_IF(MSG_META_VIEW_VIEW1)
  242. CHECK_IF(MSG_META_VIEW_VIEW2)
  243. CHECK_IF(MSG_META_VIEW_VIEW3)
  244. CHECK_IF(MSG_META_VIEW_VIEW4)
  245. CHECK_IF(MSG_META_VIEW_VIEW5)
  246. CHECK_IF(MSG_META_VIEW_VIEW6)
  247. CHECK_IF(MSG_META_VIEW_VIEW7)
  248. CHECK_IF(MSG_META_VIEW_VIEW8)
  249. CHECK_IF(MSG_META_CREATE_TEAM0)
  250. CHECK_IF(MSG_META_CREATE_TEAM1)
  251. CHECK_IF(MSG_META_CREATE_TEAM2)
  252. CHECK_IF(MSG_META_CREATE_TEAM3)
  253. CHECK_IF(MSG_META_CREATE_TEAM4)
  254. CHECK_IF(MSG_META_CREATE_TEAM5)
  255. CHECK_IF(MSG_META_CREATE_TEAM6)
  256. CHECK_IF(MSG_META_CREATE_TEAM7)
  257. CHECK_IF(MSG_META_CREATE_TEAM8)
  258. CHECK_IF(MSG_META_CREATE_TEAM9)
  259. CHECK_IF(MSG_META_SELECT_TEAM0)
  260. CHECK_IF(MSG_META_SELECT_TEAM1)
  261. CHECK_IF(MSG_META_SELECT_TEAM2)
  262. CHECK_IF(MSG_META_SELECT_TEAM3)
  263. CHECK_IF(MSG_META_SELECT_TEAM4)
  264. CHECK_IF(MSG_META_SELECT_TEAM5)
  265. CHECK_IF(MSG_META_SELECT_TEAM6)
  266. CHECK_IF(MSG_META_SELECT_TEAM7)
  267. CHECK_IF(MSG_META_SELECT_TEAM8)
  268. CHECK_IF(MSG_META_SELECT_TEAM9)
  269. CHECK_IF(MSG_META_ADD_TEAM0)
  270. CHECK_IF(MSG_META_ADD_TEAM1)
  271. CHECK_IF(MSG_META_ADD_TEAM2)
  272. CHECK_IF(MSG_META_ADD_TEAM3)
  273. CHECK_IF(MSG_META_ADD_TEAM4)
  274. CHECK_IF(MSG_META_ADD_TEAM5)
  275. CHECK_IF(MSG_META_ADD_TEAM6)
  276. CHECK_IF(MSG_META_ADD_TEAM7)
  277. CHECK_IF(MSG_META_ADD_TEAM8)
  278. CHECK_IF(MSG_META_ADD_TEAM9)
  279. CHECK_IF(MSG_META_VIEW_TEAM0)
  280. CHECK_IF(MSG_META_VIEW_TEAM1)
  281. CHECK_IF(MSG_META_VIEW_TEAM2)
  282. CHECK_IF(MSG_META_VIEW_TEAM3)
  283. CHECK_IF(MSG_META_VIEW_TEAM4)
  284. CHECK_IF(MSG_META_VIEW_TEAM5)
  285. CHECK_IF(MSG_META_VIEW_TEAM6)
  286. CHECK_IF(MSG_META_VIEW_TEAM7)
  287. CHECK_IF(MSG_META_VIEW_TEAM8)
  288. CHECK_IF(MSG_META_VIEW_TEAM9)
  289. CHECK_IF(MSG_META_SELECT_MATCHING_UNITS)
  290. CHECK_IF(MSG_META_SELECT_NEXT_UNIT)
  291. CHECK_IF(MSG_META_SELECT_PREV_UNIT)
  292. CHECK_IF(MSG_META_SELECT_NEXT_WORKER)
  293. CHECK_IF(MSG_META_SELECT_PREV_WORKER)
  294. CHECK_IF(MSG_META_VIEW_COMMAND_CENTER)
  295. CHECK_IF(MSG_META_VIEW_LAST_RADAR_EVENT)
  296. CHECK_IF(MSG_META_SELECT_HERO)
  297. CHECK_IF(MSG_META_SELECT_ALL)
  298. CHECK_IF(MSG_META_SELECT_ALL_AIRCRAFT)
  299. CHECK_IF(MSG_META_SCATTER)
  300. CHECK_IF(MSG_META_STOP)
  301. CHECK_IF(MSG_META_DEPLOY)
  302. CHECK_IF(MSG_META_CREATE_FORMATION)
  303. CHECK_IF(MSG_META_FOLLOW)
  304. CHECK_IF(MSG_META_CHAT_PLAYERS)
  305. CHECK_IF(MSG_META_CHAT_ALLIES)
  306. CHECK_IF(MSG_META_CHAT_EVERYONE)
  307. CHECK_IF(MSG_META_DIPLOMACY)
  308. CHECK_IF(MSG_META_OPTIONS)
  309. #if defined(_DEBUG) || defined(_INTERNAL)
  310. CHECK_IF(MSG_META_HELP)
  311. #endif
  312. CHECK_IF(MSG_META_TOGGLE_LOWER_DETAILS)
  313. CHECK_IF(MSG_META_TOGGLE_CONTROL_BAR)
  314. CHECK_IF(MSG_META_BEGIN_PATH_BUILD)
  315. CHECK_IF(MSG_META_END_PATH_BUILD)
  316. CHECK_IF(MSG_META_BEGIN_FORCEATTACK)
  317. CHECK_IF(MSG_META_END_FORCEATTACK)
  318. CHECK_IF(MSG_META_BEGIN_FORCEMOVE)
  319. CHECK_IF(MSG_META_END_FORCEMOVE)
  320. CHECK_IF(MSG_META_BEGIN_WAYPOINTS)
  321. CHECK_IF(MSG_META_END_WAYPOINTS)
  322. CHECK_IF(MSG_META_BEGIN_PREFER_SELECTION)
  323. CHECK_IF(MSG_META_END_PREFER_SELECTION)
  324. CHECK_IF(MSG_META_TAKE_SCREENSHOT)
  325. CHECK_IF(MSG_META_ALL_CHEER)
  326. CHECK_IF(MSG_META_TOGGLE_ATTACKMOVE)
  327. CHECK_IF(MSG_META_BEGIN_CAMERA_ROTATE_LEFT)
  328. CHECK_IF(MSG_META_END_CAMERA_ROTATE_LEFT)
  329. CHECK_IF(MSG_META_BEGIN_CAMERA_ROTATE_RIGHT)
  330. CHECK_IF(MSG_META_END_CAMERA_ROTATE_RIGHT)
  331. CHECK_IF(MSG_META_BEGIN_CAMERA_ZOOM_IN)
  332. CHECK_IF(MSG_META_END_CAMERA_ZOOM_IN)
  333. CHECK_IF(MSG_META_BEGIN_CAMERA_ZOOM_OUT)
  334. CHECK_IF(MSG_META_END_CAMERA_ZOOM_OUT)
  335. CHECK_IF(MSG_META_CAMERA_RESET)
  336. CHECK_IF(MSG_META_TOGGLE_CAMERA_TRACKING_DRAWABLE)
  337. CHECK_IF(MSG_META_DEMO_INSTANT_QUIT)
  338. #if defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE)//may be defined in GameCommon.h
  339. CHECK_IF(MSG_CHEAT_RUNSCRIPT1)
  340. CHECK_IF(MSG_CHEAT_RUNSCRIPT2)
  341. CHECK_IF(MSG_CHEAT_RUNSCRIPT3)
  342. CHECK_IF(MSG_CHEAT_RUNSCRIPT4)
  343. CHECK_IF(MSG_CHEAT_RUNSCRIPT5)
  344. CHECK_IF(MSG_CHEAT_RUNSCRIPT6)
  345. CHECK_IF(MSG_CHEAT_RUNSCRIPT7)
  346. CHECK_IF(MSG_CHEAT_RUNSCRIPT8)
  347. CHECK_IF(MSG_CHEAT_RUNSCRIPT9)
  348. CHECK_IF(MSG_CHEAT_TOGGLE_SPECIAL_POWER_DELAYS)
  349. CHECK_IF(MSG_CHEAT_SWITCH_TEAMS)
  350. CHECK_IF(MSG_CHEAT_KILL_SELECTION)
  351. CHECK_IF(MSG_CHEAT_TOGGLE_HAND_OF_GOD_MODE)
  352. CHECK_IF(MSG_CHEAT_INSTANT_BUILD)
  353. CHECK_IF(MSG_CHEAT_DESHROUD)
  354. CHECK_IF(MSG_CHEAT_ADD_CASH)
  355. CHECK_IF(MSG_CHEAT_GIVE_ALL_SCIENCES)
  356. CHECK_IF(MSG_CHEAT_GIVE_SCIENCEPURCHASEPOINTS)
  357. CHECK_IF(MSG_CHEAT_SHOW_HEALTH)
  358. CHECK_IF(MSG_CHEAT_TOGGLE_MESSAGE_TEXT)
  359. #endif
  360. CHECK_IF(MSG_META_TOGGLE_FAST_FORWARD_REPLAY)
  361. #if defined(_DEBUG) || defined(_INTERNAL)
  362. CHECK_IF(MSG_META_DEMO_TOGGLE_BEHIND_BUILDINGS)
  363. CHECK_IF(MSG_META_DEMO_TOGGLE_LETTERBOX)
  364. CHECK_IF(MSG_META_DEMO_TOGGLE_MESSAGE_TEXT)
  365. CHECK_IF(MSG_META_DEMO_LOD_DECREASE)
  366. CHECK_IF(MSG_META_DEMO_LOD_INCREASE)
  367. CHECK_IF(MSG_META_DEMO_TOGGLE_ZOOM_LOCK)
  368. CHECK_IF(MSG_META_DEMO_PLAY_CAMEO_MOVIE)
  369. CHECK_IF(MSG_META_DEMO_TOGGLE_SPECIAL_POWER_DELAYS)
  370. CHECK_IF(MSG_META_DEMO_BATTLE_CRY)
  371. CHECK_IF(MSG_META_DEMO_SWITCH_TEAMS)
  372. CHECK_IF(MSG_META_DEMO_SWITCH_TEAMS_BETWEEN_CHINA_USA)
  373. CHECK_IF(MSG_META_DEMO_TOGGLE_PARTICLEDEBUG)
  374. CHECK_IF(MSG_META_DEMO_TOGGLE_SHADOW_VOLUMES)
  375. CHECK_IF(MSG_META_DEMO_TOGGLE_FOGOFWAR)
  376. CHECK_IF(MSG_META_DEMO_KILL_ALL_ENEMIES)
  377. CHECK_IF(MSG_META_DEMO_KILL_SELECTION)
  378. CHECK_IF(MSG_META_DEMO_TOGGLE_HURT_ME_MODE)
  379. CHECK_IF(MSG_META_DEMO_TOGGLE_HAND_OF_GOD_MODE)
  380. CHECK_IF(MSG_META_DEMO_DEBUG_SELECTION)
  381. CHECK_IF(MSG_META_DEMO_LOCK_CAMERA_TO_SELECTION)
  382. CHECK_IF(MSG_META_DEMO_TOGGLE_SOUND)
  383. CHECK_IF(MSG_META_DEMO_TOGGLE_TRACKMARKS)
  384. CHECK_IF(MSG_META_DEMO_TOGGLE_WATERPLANE)
  385. CHECK_IF(MSG_META_DEMO_TIME_OF_DAY)
  386. CHECK_IF(MSG_META_DEMO_TOGGLE_MUSIC)
  387. CHECK_IF(MSG_META_DEMO_MUSIC_NEXT_TRACK)
  388. CHECK_IF(MSG_META_DEMO_MUSIC_PREV_TRACK)
  389. CHECK_IF(MSG_META_DEMO_NEXT_OBJECTIVE_MOVIE)
  390. CHECK_IF(MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE1)
  391. CHECK_IF(MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE2)
  392. CHECK_IF(MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE3)
  393. CHECK_IF(MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE4)
  394. CHECK_IF(MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE5)
  395. CHECK_IF(MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE6)
  396. CHECK_IF(MSG_META_DEMO_BEGIN_ADJUST_PITCH)
  397. CHECK_IF(MSG_META_DEMO_END_ADJUST_PITCH)
  398. CHECK_IF(MSG_META_DEMO_BEGIN_ADJUST_FOV)
  399. CHECK_IF(MSG_META_DEMO_END_ADJUST_FOV)
  400. CHECK_IF(MSG_META_DEMO_LOCK_CAMERA_TO_PLANES)
  401. CHECK_IF(MSG_META_DEMO_REMOVE_PREREQ)
  402. CHECK_IF(MSG_META_DEMO_INSTANT_BUILD)
  403. CHECK_IF(MSG_META_DEMO_FREE_BUILD)
  404. CHECK_IF(MSG_META_DEMO_RUNSCRIPT1)
  405. CHECK_IF(MSG_META_DEMO_RUNSCRIPT2)
  406. CHECK_IF(MSG_META_DEMO_RUNSCRIPT3)
  407. CHECK_IF(MSG_META_DEMO_RUNSCRIPT4)
  408. CHECK_IF(MSG_META_DEMO_RUNSCRIPT5)
  409. CHECK_IF(MSG_META_DEMO_RUNSCRIPT6)
  410. CHECK_IF(MSG_META_DEMO_RUNSCRIPT7)
  411. CHECK_IF(MSG_META_DEMO_RUNSCRIPT8)
  412. CHECK_IF(MSG_META_DEMO_RUNSCRIPT9)
  413. CHECK_IF(MSG_META_DEMO_ENSHROUD)
  414. CHECK_IF(MSG_META_DEMO_DESHROUD)
  415. CHECK_IF(MSG_META_DEBUG_SHOW_EXTENTS)
  416. CHECK_IF(MSG_META_DEBUG_SHOW_AUDIO_LOCATIONS)
  417. CHECK_IF(MSG_META_DEBUG_SHOW_HEALTH)
  418. CHECK_IF(MSG_META_DEBUG_GIVE_VETERANCY)
  419. CHECK_IF(MSG_META_DEBUG_TAKE_VETERANCY)
  420. CHECK_IF(MSG_META_DEMO_TOGGLE_AI_DEBUG)
  421. CHECK_IF(MSG_META_DEMO_TOGGLE_SUPPLY_CENTER_PLACEMENT)
  422. CHECK_IF(MSG_META_DEMO_TOGGLE_CAMERA_DEBUG)
  423. CHECK_IF(MSG_META_DEMO_TOGGLE_AVI)
  424. CHECK_IF(MSG_META_DEMO_TOGGLE_BW_VIEW)
  425. CHECK_IF(MSG_META_DEMO_TOGGLE_RED_VIEW)
  426. CHECK_IF(MSG_META_DEMO_TOGGLE_GREEN_VIEW)
  427. CHECK_IF(MSG_META_DEMO_TOGGLE_MOTION_BLUR_ZOOM)
  428. CHECK_IF(MSG_META_DEMO_TOGGLE_MILITARY_SUBTITLES)
  429. CHECK_IF(MSG_META_DEMO_ADD_CASH)
  430. #ifdef ALLOW_SURRENDER
  431. CHECK_IF(MSG_META_DEMO_TEST_SURRENDER)
  432. #endif
  433. CHECK_IF(MSG_META_DEMO_TOGGLE_RENDER)
  434. CHECK_IF(MSG_META_DEMO_KILL_AREA_SELECTION)
  435. CHECK_IF(MSG_META_DEMO_CYCLE_LOD_LEVEL)
  436. CHECK_IF(MSG_META_DEBUG_INCR_ANIM_SKATE_SPEED)
  437. CHECK_IF(MSG_META_DEBUG_DECR_ANIM_SKATE_SPEED)
  438. CHECK_IF(MSG_META_DEBUG_CYCLE_EXTENT_TYPE)
  439. CHECK_IF(MSG_META_DEBUG_INCREASE_EXTENT_MAJOR)
  440. CHECK_IF(MSG_META_DEBUG_INCREASE_EXTENT_MAJOR_BIG)
  441. CHECK_IF(MSG_META_DEBUG_DECREASE_EXTENT_MAJOR)
  442. CHECK_IF(MSG_META_DEBUG_DECREASE_EXTENT_MAJOR_BIG)
  443. CHECK_IF(MSG_META_DEBUG_INCREASE_EXTENT_MINOR)
  444. CHECK_IF(MSG_META_DEBUG_INCREASE_EXTENT_MINOR_BIG)
  445. CHECK_IF(MSG_META_DEBUG_DECREASE_EXTENT_MINOR)
  446. CHECK_IF(MSG_META_DEBUG_DECREASE_EXTENT_MINOR_BIG)
  447. CHECK_IF(MSG_META_DEBUG_INCREASE_EXTENT_HEIGHT)
  448. CHECK_IF(MSG_META_DEBUG_INCREASE_EXTENT_HEIGHT_BIG)
  449. CHECK_IF(MSG_META_DEBUG_DECREASE_EXTENT_HEIGHT)
  450. CHECK_IF(MSG_META_DEBUG_DECREASE_EXTENT_HEIGHT_BIG)
  451. CHECK_IF(MSG_META_DEBUG_VTUNE_ON)
  452. CHECK_IF(MSG_META_DEBUG_VTUNE_OFF)
  453. CHECK_IF(MSG_META_DEBUG_TOGGLE_FEATHER_WATER)
  454. CHECK_IF(MSG_META_DEBUG_DUMP_ASSETS)
  455. CHECK_IF(MSG_NO_DRAW)
  456. CHECK_IF(MSG_META_DEMO_TOGGLE_METRICS)
  457. CHECK_IF(MSG_META_DEMO_TOGGLE_PROJECTILEDEBUG)
  458. CHECK_IF(MSG_META_DEMO_TOGGLE_VISIONDEBUG)
  459. CHECK_IF(MSG_META_DEMO_TOGGLE_THREATDEBUG)
  460. CHECK_IF(MSG_META_DEMO_TOGGLE_CASHMAPDEBUG)
  461. CHECK_IF(MSG_META_DEMO_TOGGLE_GRAPHICALFRAMERATEBAR)
  462. CHECK_IF(MSG_META_DEMO_GIVE_ALL_SCIENCES)
  463. CHECK_IF(MSG_META_DEMO_GIVE_RANKLEVEL)
  464. CHECK_IF(MSG_META_DEMO_TAKE_RANKLEVEL)
  465. CHECK_IF(MSG_META_DEMO_GIVE_SCIENCEPURCHASEPOINTS)
  466. CHECK_IF(MSG_META_DEBUG_TOGGLE_NETWORK)
  467. CHECK_IF(MSG_META_DEBUG_DUMP_PLAYER_OBJECTS)
  468. CHECK_IF(MSG_META_DEBUG_DUMP_ALL_PLAYER_OBJECTS)
  469. CHECK_IF(MSG_META_DEBUG_OBJECT_ID_PERFORMANCE)
  470. CHECK_IF(MSG_META_DEBUG_DRAWABLE_ID_PERFORMANCE)
  471. CHECK_IF(MSG_META_DEBUG_SLEEPY_UPDATE_PERFORMANCE)
  472. CHECK_IF(MSG_META_DEBUG_WIN)
  473. CHECK_IF(MSG_META_DEMO_TOGGLE_DEBUG_STATS)
  474. #endif // defined(_DEBUG) || defined(_INTERNAL)
  475. #if defined(_INTERNAL) || defined(_DEBUG)
  476. CHECK_IF(MSG_META_DEMO_TOGGLE_AUDIODEBUG)
  477. #endif//defined(_INTERNAL) || defined(_DEBUG)
  478. #ifdef DUMP_PERF_STATS
  479. CHECK_IF(MSG_META_DEMO_PERFORM_STATISTICAL_DUMP)
  480. #endif//DUMP_PERF_STATS
  481. CHECK_IF(MSG_META_PLACE_BEACON)
  482. CHECK_IF(MSG_META_REMOVE_BEACON)
  483. CHECK_IF(MSG_END_META_MESSAGES)
  484. CHECK_IF(MSG_MOUSEOVER_DRAWABLE_HINT)
  485. CHECK_IF(MSG_MOUSEOVER_LOCATION_HINT)
  486. CHECK_IF(MSG_VALID_GUICOMMAND_HINT)
  487. CHECK_IF(MSG_INVALID_GUICOMMAND_HINT)
  488. CHECK_IF(MSG_AREA_SELECTION_HINT)
  489. CHECK_IF(MSG_DO_ATTACK_OBJECT_HINT)
  490. CHECK_IF(MSG_DO_ATTACK_OBJECT_AFTER_MOVING_HINT)
  491. CHECK_IF(MSG_DO_FORCE_ATTACK_OBJECT_HINT)
  492. CHECK_IF(MSG_DO_FORCE_ATTACK_GROUND_HINT)
  493. CHECK_IF(MSG_GET_REPAIRED_HINT)
  494. CHECK_IF(MSG_GET_HEALED_HINT)
  495. CHECK_IF(MSG_DO_REPAIR_HINT)
  496. CHECK_IF(MSG_RESUME_CONSTRUCTION_HINT)
  497. CHECK_IF(MSG_ENTER_HINT)
  498. CHECK_IF(MSG_DOCK_HINT)
  499. CHECK_IF(MSG_DO_MOVETO_HINT)
  500. CHECK_IF(MSG_DO_ATTACKMOVETO_HINT)
  501. CHECK_IF(MSG_ADD_WAYPOINT_HINT)
  502. CHECK_IF(MSG_HIJACK_HINT)
  503. CHECK_IF(MSG_SABOTAGE_HINT)
  504. CHECK_IF(MSG_FIREBOMB_HINT)
  505. CHECK_IF(MSG_CONVERT_TO_CARBOMB_HINT)
  506. CHECK_IF(MSG_CAPTUREBUILDING_HINT)
  507. CHECK_IF(MSG_HACK_HINT)
  508. #ifdef ALLOW_SURRENDER
  509. CHECK_IF(MSG_PICK_UP_PRISONER_HINT)
  510. #endif
  511. CHECK_IF(MSG_SNIPE_VEHICLE_HINT)
  512. CHECK_IF(MSG_DEFECTOR_HINT)
  513. CHECK_IF(MSG_SET_RALLY_POINT_HINT)
  514. CHECK_IF(MSG_DO_SALVAGE_HINT)
  515. CHECK_IF(MSG_DO_INVALID_HINT)
  516. CHECK_IF(MSG_BEGIN_NETWORK_MESSAGES)
  517. CHECK_IF(MSG_CREATE_SELECTED_GROUP)
  518. CHECK_IF(MSG_CREATE_SELECTED_GROUP_NO_SOUND)
  519. CHECK_IF(MSG_DESTROY_SELECTED_GROUP)
  520. CHECK_IF(MSG_REMOVE_FROM_SELECTED_GROUP)
  521. CHECK_IF(MSG_SELECTED_GROUP_COMMAND)
  522. CHECK_IF(MSG_CREATE_TEAM0)
  523. CHECK_IF(MSG_CREATE_TEAM1)
  524. CHECK_IF(MSG_CREATE_TEAM2)
  525. CHECK_IF(MSG_CREATE_TEAM3)
  526. CHECK_IF(MSG_CREATE_TEAM4)
  527. CHECK_IF(MSG_CREATE_TEAM5)
  528. CHECK_IF(MSG_CREATE_TEAM6)
  529. CHECK_IF(MSG_CREATE_TEAM7)
  530. CHECK_IF(MSG_CREATE_TEAM8)
  531. CHECK_IF(MSG_CREATE_TEAM9)
  532. CHECK_IF(MSG_SELECT_TEAM0)
  533. CHECK_IF(MSG_SELECT_TEAM1)
  534. CHECK_IF(MSG_SELECT_TEAM2)
  535. CHECK_IF(MSG_SELECT_TEAM3)
  536. CHECK_IF(MSG_SELECT_TEAM4)
  537. CHECK_IF(MSG_SELECT_TEAM5)
  538. CHECK_IF(MSG_SELECT_TEAM6)
  539. CHECK_IF(MSG_SELECT_TEAM7)
  540. CHECK_IF(MSG_SELECT_TEAM8)
  541. CHECK_IF(MSG_SELECT_TEAM9)
  542. CHECK_IF(MSG_ADD_TEAM0)
  543. CHECK_IF(MSG_ADD_TEAM1)
  544. CHECK_IF(MSG_ADD_TEAM2)
  545. CHECK_IF(MSG_ADD_TEAM3)
  546. CHECK_IF(MSG_ADD_TEAM4)
  547. CHECK_IF(MSG_ADD_TEAM5)
  548. CHECK_IF(MSG_ADD_TEAM6)
  549. CHECK_IF(MSG_ADD_TEAM7)
  550. CHECK_IF(MSG_ADD_TEAM8)
  551. CHECK_IF(MSG_ADD_TEAM9)
  552. CHECK_IF(MSG_DO_ATTACKSQUAD)
  553. CHECK_IF(MSG_DO_WEAPON)
  554. CHECK_IF(MSG_DO_WEAPON_AT_LOCATION)
  555. CHECK_IF(MSG_DO_WEAPON_AT_OBJECT)
  556. CHECK_IF(MSG_DO_SPECIAL_POWER)
  557. CHECK_IF(MSG_DO_SPECIAL_POWER_AT_LOCATION)
  558. CHECK_IF(MSG_DO_SPECIAL_POWER_AT_OBJECT)
  559. CHECK_IF(MSG_SET_RALLY_POINT)
  560. CHECK_IF(MSG_PURCHASE_SCIENCE)
  561. CHECK_IF(MSG_QUEUE_UPGRADE)
  562. CHECK_IF(MSG_CANCEL_UPGRADE)
  563. CHECK_IF(MSG_QUEUE_UNIT_CREATE)
  564. CHECK_IF(MSG_CANCEL_UNIT_CREATE)
  565. CHECK_IF(MSG_DOZER_CONSTRUCT)
  566. CHECK_IF(MSG_DOZER_CONSTRUCT_LINE)
  567. CHECK_IF(MSG_DOZER_CANCEL_CONSTRUCT)
  568. CHECK_IF(MSG_SELL)
  569. CHECK_IF(MSG_EXIT)
  570. CHECK_IF(MSG_EVACUATE)
  571. CHECK_IF(MSG_EXECUTE_RAILED_TRANSPORT)
  572. CHECK_IF(MSG_COMBATDROP_AT_LOCATION)
  573. CHECK_IF(MSG_COMBATDROP_AT_OBJECT)
  574. CHECK_IF(MSG_AREA_SELECTION)
  575. CHECK_IF(MSG_DO_ATTACK_OBJECT)
  576. CHECK_IF(MSG_DO_FORCE_ATTACK_OBJECT)
  577. CHECK_IF(MSG_DO_FORCE_ATTACK_GROUND)
  578. CHECK_IF(MSG_GET_REPAIRED)
  579. CHECK_IF(MSG_GET_HEALED)
  580. CHECK_IF(MSG_DO_REPAIR)
  581. CHECK_IF(MSG_RESUME_CONSTRUCTION)
  582. CHECK_IF(MSG_ENTER)
  583. CHECK_IF(MSG_DOCK)
  584. CHECK_IF(MSG_DO_MOVETO)
  585. CHECK_IF(MSG_DO_ATTACKMOVETO)
  586. CHECK_IF(MSG_DO_FORCEMOVETO)
  587. CHECK_IF(MSG_ADD_WAYPOINT)
  588. CHECK_IF(MSG_DO_GUARD_POSITION)
  589. CHECK_IF(MSG_DO_GUARD_OBJECT)
  590. CHECK_IF(MSG_DO_STOP)
  591. CHECK_IF(MSG_DO_SCATTER)
  592. CHECK_IF(MSG_INTERNET_HACK)
  593. CHECK_IF(MSG_DO_CHEER)
  594. #ifdef ALLOW_SURRENDER
  595. CHECK_IF(MSG_DO_SURRENDER)
  596. #endif
  597. CHECK_IF(MSG_TOGGLE_OVERCHARGE)
  598. #ifdef ALLOW_SURRENDER
  599. CHECK_IF(MSG_RETURN_TO_PRISON)
  600. #endif
  601. CHECK_IF(MSG_SWITCH_WEAPONS)
  602. CHECK_IF(MSG_CONVERT_TO_CARBOMB)
  603. CHECK_IF(MSG_CAPTUREBUILDING)
  604. CHECK_IF(MSG_DISABLEVEHICLE_HACK)
  605. CHECK_IF(MSG_STEALCASH_HACK)
  606. CHECK_IF(MSG_DISABLEBUILDING_HACK)
  607. CHECK_IF(MSG_SNIPE_VEHICLE)
  608. #ifdef ALLOW_SURRENDER
  609. CHECK_IF(MSG_PICK_UP_PRISONER)
  610. #endif
  611. CHECK_IF(MSG_DO_SALVAGE)
  612. CHECK_IF(MSG_CLEAR_INGAME_POPUP_MESSAGE)
  613. CHECK_IF(MSG_PLACE_BEACON)
  614. CHECK_IF(MSG_REMOVE_BEACON)
  615. CHECK_IF(MSG_SET_BEACON_TEXT)
  616. CHECK_IF(MSG_SET_REPLAY_CAMERA)
  617. CHECK_IF(MSG_SELF_DESTRUCT)
  618. CHECK_IF(MSG_CREATE_FORMATION)
  619. CHECK_IF(MSG_LOGIC_CRC)
  620. #if defined(_DEBUG) || defined(_INTERNAL)
  621. CHECK_IF(MSG_DEBUG_KILL_SELECTION)
  622. CHECK_IF(MSG_DEBUG_HURT_OBJECT)
  623. CHECK_IF(MSG_DEBUG_KILL_OBJECT)
  624. #endif
  625. CHECK_IF(MSG_END_NETWORK_MESSAGES)
  626. CHECK_IF(MSG_TIMESTAMP)
  627. CHECK_IF(MSG_OBJECT_CREATED)
  628. CHECK_IF(MSG_OBJECT_DESTROYED)
  629. CHECK_IF(MSG_OBJECT_POSITION)
  630. CHECK_IF(MSG_OBJECT_ORIENTATION)
  631. CHECK_IF(MSG_OBJECT_JOINED_TEAM)
  632. CHECK_IF(MSG_SET_MINE_CLEARING_DETAIL)
  633. CHECK_IF(MSG_ENABLE_RETALIATION_MODE)
  634. return commandName;
  635. }
  636. //------------------------------------------------------------------------------------------------
  637. // GameMessageList
  638. //
  639. /**
  640. * Constructor
  641. */
  642. GameMessageList::GameMessageList( void )
  643. {
  644. m_firstMessage = 0;
  645. m_lastMessage = 0;
  646. }
  647. /**
  648. * Destructor
  649. */
  650. GameMessageList::~GameMessageList()
  651. {
  652. // destroy all messages currently on the list
  653. GameMessage *msg, *nextMsg;
  654. for( msg = m_firstMessage; msg; msg = nextMsg )
  655. {
  656. nextMsg = msg->next();
  657. // set list ptr to null to avoid it trying to remove itself from the list
  658. // that we are in the process of nuking...
  659. msg->friend_setList(NULL);
  660. msg->deleteInstance();
  661. }
  662. }
  663. /**
  664. * Append message to end of message list
  665. */
  666. void GameMessageList::appendMessage( GameMessage *msg )
  667. {
  668. msg->friend_setNext(NULL);
  669. if (m_lastMessage)
  670. {
  671. m_lastMessage->friend_setNext(msg);
  672. msg->friend_setPrev(m_lastMessage);
  673. m_lastMessage = msg;
  674. }
  675. else
  676. {
  677. // first message
  678. m_firstMessage = msg;
  679. m_lastMessage = msg;
  680. msg->friend_setPrev(NULL);
  681. }
  682. // note containment within message itself
  683. msg->friend_setList(this);
  684. }
  685. /**
  686. * Inserts the msg after messageToInsertAfter.
  687. */
  688. void GameMessageList::insertMessage( GameMessage *msg, GameMessage *messageToInsertAfter )
  689. {
  690. // First, set msg's next to be messageToInsertAfter's next.
  691. msg->friend_setNext(messageToInsertAfter->next());
  692. // Next, set msg's prev to be messageToInsertAfter
  693. msg->friend_setPrev(messageToInsertAfter);
  694. // Now update the next message's prev to be msg
  695. if (msg->next())
  696. msg->next()->friend_setPrev(msg);
  697. else // if the friend wasn't there, then messageToInsertAfter is the last message. Update it to be msg.
  698. m_lastMessage = msg;
  699. // Finally, update the messageToInsertAfter's next to be msg
  700. messageToInsertAfter->friend_setNext(msg);
  701. // note containment within the message itself
  702. msg->friend_setList(this);
  703. }
  704. /**
  705. * Remove given message from the list.
  706. */
  707. void GameMessageList::removeMessage( GameMessage *msg )
  708. {
  709. if (msg->next())
  710. msg->next()->friend_setPrev(msg->prev());
  711. else
  712. m_lastMessage = msg->prev();
  713. if (msg->prev())
  714. msg->prev()->friend_setNext(msg->next());
  715. else
  716. m_firstMessage = msg->next();
  717. msg->friend_setList(NULL);
  718. }
  719. /**
  720. * Return whether or not a message of the given type is in the message list
  721. */
  722. Bool GameMessageList::containsMessageOfType( GameMessage::Type type )
  723. {
  724. GameMessage *msg = getFirstMessage();
  725. while (msg) {
  726. if (msg->getType() == type) {
  727. return true;
  728. }
  729. msg = msg->next();
  730. }
  731. return false;
  732. }
  733. //------------------------------------------------------------------------------------------------
  734. // MessageStream
  735. //
  736. /**
  737. * Constructor
  738. */
  739. MessageStream::MessageStream( void )
  740. {
  741. m_firstTranslator = 0;
  742. m_nextTranslatorID = 1;
  743. }
  744. /**
  745. * Destructor
  746. */
  747. MessageStream::~MessageStream()
  748. {
  749. // destroy all translators
  750. TranslatorData *trans, *nextTrans;
  751. for( trans=m_firstTranslator; trans; trans=nextTrans )
  752. {
  753. nextTrans = trans->m_next;
  754. delete trans;
  755. }
  756. }
  757. /**
  758. * Init
  759. */
  760. void MessageStream::init( void )
  761. {
  762. // extend
  763. GameMessageList::init();
  764. }
  765. /**
  766. * Reset
  767. */
  768. void MessageStream::reset( void )
  769. {
  770. /// @todo Reset the MessageStream
  771. // extend
  772. GameMessageList::reset();
  773. }
  774. /**
  775. * Update
  776. */
  777. void MessageStream::update( void )
  778. {
  779. // extend
  780. GameMessageList::update();
  781. }
  782. /**
  783. * Create a new message of the given message type and append it
  784. * to this message stream. Return the message such that any data
  785. * associated with this message can be attached to it.
  786. */
  787. GameMessage *MessageStream::appendMessage( GameMessage::Type type )
  788. {
  789. GameMessage *msg = newInstance(GameMessage)( type );
  790. // add message to list
  791. GameMessageList::appendMessage( msg );
  792. return msg;
  793. }
  794. /**
  795. * Create a new message of the given message type and insert it
  796. * in the stream after messageToInsertAfter, which must not be NULL.
  797. */
  798. GameMessage *MessageStream::insertMessage( GameMessage::Type type, GameMessage *messageToInsertAfter )
  799. {
  800. GameMessage *msg = newInstance(GameMessage)(type);
  801. GameMessageList::insertMessage(msg, messageToInsertAfter);
  802. return msg;
  803. }
  804. /**
  805. * Attach the given Translator to the message stream, and return a
  806. * unique TranslatorID identifying it.
  807. * Translators are placed on a list, sorted by priority order. If two
  808. * Translators share a priority, they are kept in the same order they
  809. * were attached.
  810. */
  811. TranslatorID MessageStream::attachTranslator( GameMessageTranslator *translator,
  812. UnsignedInt priority)
  813. {
  814. MessageStream::TranslatorData *newSS = NEW MessageStream::TranslatorData;
  815. MessageStream::TranslatorData *ss;
  816. newSS->m_translator = translator;
  817. newSS->m_priority = priority;
  818. newSS->m_id = m_nextTranslatorID++;
  819. if (m_firstTranslator == NULL)
  820. {
  821. // first Translator to be attached
  822. newSS->m_prev = NULL;
  823. newSS->m_next = NULL;
  824. m_firstTranslator = newSS;
  825. m_lastTranslator = newSS;
  826. return newSS->m_id;
  827. }
  828. // seach the Translator list for our priority location
  829. for( ss=m_firstTranslator; ss; ss=ss->m_next )
  830. if (ss->m_priority > newSS->m_priority)
  831. break;
  832. if (ss)
  833. {
  834. // insert new Translator just BEFORE this one,
  835. // therefore, m_lastTranslator cannot be affected
  836. if (ss->m_prev)
  837. {
  838. ss->m_prev->m_next = newSS;
  839. newSS->m_prev = ss->m_prev;
  840. newSS->m_next = ss;
  841. ss->m_prev = newSS;
  842. }
  843. else
  844. {
  845. // insert at head of list
  846. newSS->m_prev = NULL;
  847. newSS->m_next = m_firstTranslator;
  848. m_firstTranslator->m_prev = newSS;
  849. m_firstTranslator = newSS;
  850. }
  851. }
  852. else
  853. {
  854. // append Translator to end of list
  855. m_lastTranslator->m_next = newSS;
  856. newSS->m_prev = m_lastTranslator;
  857. newSS->m_next = NULL;
  858. m_lastTranslator = newSS;
  859. }
  860. return newSS->m_id;
  861. }
  862. /**
  863. * Find a translator attached to this message stream given the ID
  864. */
  865. GameMessageTranslator* MessageStream::findTranslator( TranslatorID id )
  866. {
  867. MessageStream::TranslatorData *translatorData;
  868. for( translatorData = m_firstTranslator; translatorData; translatorData = translatorData->m_next )
  869. {
  870. if( translatorData->m_id == id )
  871. return translatorData->m_translator;
  872. }
  873. return NULL;
  874. }
  875. /**
  876. * Remove a previously attached translator.
  877. */
  878. void MessageStream::removeTranslator( TranslatorID id )
  879. {
  880. MessageStream::TranslatorData *ss;
  881. for( ss=m_firstTranslator; ss; ss=ss->m_next )
  882. if (ss->m_id == id)
  883. {
  884. // found the translator - remove it
  885. if (ss->m_prev)
  886. ss->m_prev->m_next = ss->m_next;
  887. else
  888. m_firstTranslator = ss->m_next;
  889. if (ss->m_next)
  890. ss->m_next->m_prev = ss->m_prev;
  891. else
  892. m_lastTranslator = ss->m_prev;
  893. // delete the translator data
  894. delete ss;
  895. break;
  896. }
  897. }
  898. // ------------------------------------------------------------------------------------------------
  899. // ------------------------------------------------------------------------------------------------
  900. #if defined(_DEBUG) || defined(_INTERNAL)
  901. Bool isInvalidDebugCommand( GameMessage::Type t )
  902. {
  903. // see if this is something that should be prevented in multiplayer games
  904. // Don't reject this stuff in skirmish games.
  905. if (TheGameLogic && !TheGameLogic->isInSkirmishGame() &&
  906. (TheRecorder && TheRecorder->isMultiplayer() && TheRecorder->getMode() == RECORDERMODETYPE_RECORD))
  907. {
  908. switch (t)
  909. {
  910. case GameMessage::MSG_META_DEMO_SWITCH_TEAMS:
  911. case GameMessage::MSG_META_DEMO_SWITCH_TEAMS_BETWEEN_CHINA_USA:
  912. case GameMessage::MSG_META_DEMO_KILL_ALL_ENEMIES:
  913. case GameMessage::MSG_META_DEMO_KILL_SELECTION:
  914. case GameMessage::MSG_META_DEMO_TOGGLE_HURT_ME_MODE:
  915. case GameMessage::MSG_META_DEMO_TOGGLE_HAND_OF_GOD_MODE:
  916. case GameMessage::MSG_META_DEMO_TOGGLE_SPECIAL_POWER_DELAYS:
  917. case GameMessage::MSG_META_DEMO_TIME_OF_DAY:
  918. case GameMessage::MSG_META_DEMO_LOCK_CAMERA_TO_PLANES:
  919. case GameMessage::MSG_META_DEMO_REMOVE_PREREQ:
  920. case GameMessage::MSG_META_DEMO_INSTANT_BUILD:
  921. case GameMessage::MSG_META_DEMO_FREE_BUILD:
  922. case GameMessage::MSG_META_DEMO_RUNSCRIPT1:
  923. case GameMessage::MSG_META_DEMO_RUNSCRIPT2:
  924. case GameMessage::MSG_META_DEMO_RUNSCRIPT3:
  925. case GameMessage::MSG_META_DEMO_RUNSCRIPT4:
  926. case GameMessage::MSG_META_DEMO_RUNSCRIPT5:
  927. case GameMessage::MSG_META_DEMO_RUNSCRIPT6:
  928. case GameMessage::MSG_META_DEMO_RUNSCRIPT7:
  929. case GameMessage::MSG_META_DEMO_RUNSCRIPT8:
  930. case GameMessage::MSG_META_DEMO_RUNSCRIPT9:
  931. case GameMessage::MSG_META_DEMO_ENSHROUD:
  932. case GameMessage::MSG_META_DEMO_DESHROUD:
  933. case GameMessage::MSG_META_DEBUG_GIVE_VETERANCY:
  934. case GameMessage::MSG_META_DEBUG_TAKE_VETERANCY:
  935. //#pragma MESSAGE ("WARNING - DEBUG key in multiplayer!")
  936. case GameMessage::MSG_META_DEMO_ADD_CASH:
  937. case GameMessage::MSG_META_DEBUG_INCR_ANIM_SKATE_SPEED:
  938. case GameMessage::MSG_META_DEBUG_DECR_ANIM_SKATE_SPEED:
  939. case GameMessage::MSG_META_DEBUG_CYCLE_EXTENT_TYPE:
  940. case GameMessage::MSG_META_DEMO_TOGGLE_RENDER:
  941. case GameMessage::MSG_META_DEBUG_INCREASE_EXTENT_MAJOR:
  942. case GameMessage::MSG_META_DEBUG_INCREASE_EXTENT_MAJOR_BIG:
  943. case GameMessage::MSG_META_DEBUG_DECREASE_EXTENT_MAJOR:
  944. case GameMessage::MSG_META_DEBUG_DECREASE_EXTENT_MAJOR_BIG:
  945. case GameMessage::MSG_META_DEBUG_INCREASE_EXTENT_MINOR:
  946. case GameMessage::MSG_META_DEBUG_INCREASE_EXTENT_MINOR_BIG:
  947. case GameMessage::MSG_META_DEBUG_DECREASE_EXTENT_MINOR:
  948. case GameMessage::MSG_META_DEBUG_DECREASE_EXTENT_MINOR_BIG:
  949. case GameMessage::MSG_META_DEBUG_INCREASE_EXTENT_HEIGHT:
  950. case GameMessage::MSG_META_DEBUG_INCREASE_EXTENT_HEIGHT_BIG:
  951. case GameMessage::MSG_META_DEBUG_DECREASE_EXTENT_HEIGHT:
  952. case GameMessage::MSG_META_DEBUG_DECREASE_EXTENT_HEIGHT_BIG:
  953. case GameMessage::MSG_META_DEMO_KILL_AREA_SELECTION:
  954. case GameMessage::MSG_DEBUG_KILL_SELECTION:
  955. case GameMessage::MSG_DEBUG_HURT_OBJECT:
  956. case GameMessage::MSG_DEBUG_KILL_OBJECT:
  957. case GameMessage::MSG_META_DEMO_GIVE_SCIENCEPURCHASEPOINTS:
  958. case GameMessage::MSG_META_DEMO_GIVE_ALL_SCIENCES:
  959. case GameMessage::MSG_META_DEMO_GIVE_RANKLEVEL:
  960. case GameMessage::MSG_META_DEMO_TAKE_RANKLEVEL:
  961. case GameMessage::MSG_META_DEBUG_WIN:
  962. return true;
  963. }
  964. }
  965. return false;
  966. }
  967. #endif
  968. /**
  969. * Propagate messages thru attached Translators, invoking each Translator's
  970. * callback for each message in the stream.
  971. * Once all Translators have evaluated the message stream, all messages
  972. * in the stream are destroyed.
  973. */
  974. void MessageStream::propagateMessages( void )
  975. {
  976. MessageStream::TranslatorData *ss;
  977. GameMessage *msg, *next;
  978. // process each Translator
  979. for( ss=m_firstTranslator; ss; ss=ss->m_next )
  980. {
  981. for( msg=m_firstMessage; msg; msg=next )
  982. {
  983. if (ss->m_translator
  984. #if defined(_DEBUG) || defined(_INTERNAL)
  985. && !isInvalidDebugCommand(msg->getType())
  986. #endif
  987. )
  988. {
  989. GameMessageDisposition disp = ss->m_translator->translateGameMessage(msg);
  990. next = msg->next();
  991. if (disp == DESTROY_MESSAGE)
  992. {
  993. msg->deleteInstance();
  994. }
  995. }
  996. else
  997. {
  998. next = msg->next();
  999. }
  1000. }
  1001. }
  1002. // transfer all messages that reached the end of the stream to TheCommandList
  1003. TheCommandList->appendMessageList( m_firstMessage );
  1004. // clear the stream
  1005. m_firstMessage = NULL;
  1006. m_lastMessage = NULL;
  1007. }
  1008. //------------------------------------------------------------------------------------------------
  1009. // CommandList
  1010. //
  1011. /**
  1012. * Constructor
  1013. */
  1014. CommandList::CommandList( void )
  1015. {
  1016. }
  1017. /**
  1018. * Destructor
  1019. */
  1020. CommandList::~CommandList()
  1021. {
  1022. destroyAllMessages();
  1023. }
  1024. /**
  1025. * Init
  1026. */
  1027. void CommandList::init( void )
  1028. {
  1029. // extend
  1030. GameMessageList::init();
  1031. }
  1032. /**
  1033. * Destroy all messages on the list, and reset list to empty
  1034. */
  1035. void CommandList::reset( void )
  1036. {
  1037. // extend
  1038. GameMessageList::reset();
  1039. // destroy all messages
  1040. destroyAllMessages();
  1041. }
  1042. /**
  1043. * Update
  1044. */
  1045. void CommandList::update( void )
  1046. {
  1047. // extend
  1048. GameMessageList::update();
  1049. }
  1050. /**
  1051. * Destroy all messages on the command list, this will get called from the
  1052. * destructor and reset methods, DO NOT throw exceptions
  1053. */
  1054. void CommandList::destroyAllMessages( void )
  1055. {
  1056. GameMessage *msg, *next;
  1057. for( msg=m_firstMessage; msg; msg=next )
  1058. {
  1059. next = msg->next();
  1060. msg->deleteInstance();
  1061. }
  1062. m_firstMessage = NULL;
  1063. m_lastMessage = NULL;
  1064. }
  1065. /**
  1066. * Adds messages to the end of TheCommandList.
  1067. * Primarily used by TheMessageStream to put the final messages that reach the end of the
  1068. * stream on TheCommandList. Since TheGameClient will update faster than TheNetwork
  1069. * and TheGameLogic, messages will accumulate on this list.
  1070. */
  1071. void CommandList::appendMessageList( GameMessage *list )
  1072. {
  1073. GameMessage *msg, *next;
  1074. for( msg = list; msg; msg = next )
  1075. {
  1076. next = msg->next();
  1077. appendMessage( msg );
  1078. }
  1079. }
  1080. //-----------------------------------------------------------------------------
  1081. /**
  1082. * Given an "anchor" point and the current mouse position (dest),
  1083. * construct a valid 2D bounding region.
  1084. */
  1085. void buildRegion( const ICoord2D *anchor, const ICoord2D *dest, IRegion2D *region )
  1086. {
  1087. // build rectangular region defined by the drag selection
  1088. if (anchor->x < dest->x)
  1089. {
  1090. region->lo.x = anchor->x;
  1091. region->hi.x = dest->x;
  1092. }
  1093. else
  1094. {
  1095. region->lo.x = dest->x;
  1096. region->hi.x = anchor->x;
  1097. }
  1098. if (anchor->y < dest->y)
  1099. {
  1100. region->lo.y = anchor->y;
  1101. region->hi.y = dest->y;
  1102. }
  1103. else
  1104. {
  1105. region->lo.y = dest->y;
  1106. region->hi.y = anchor->y;
  1107. }
  1108. }