ControlBar.cpp 115 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420
  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. // FILE: ControlBar.cpp ///////////////////////////////////////////////////////////////////////////
  24. // Author: Colin Day, March 2002
  25. // Desc: Context sensitive command interface
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. // USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
  28. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  29. #define DEFINE_GUI_COMMMAND_NAMES
  30. #define DEFINE_COMMAND_OPTION_NAMES
  31. #define DEFINE_WEAPONSLOTTYPE_NAMES
  32. #define DEFINE_RADIUSCURSOR_NAMES
  33. #include "Common/ActionManager.h"
  34. #include "Common/GameType.h"
  35. #include "Common/MultiplayerSettings.h"
  36. #include "Common/NameKeyGenerator.h"
  37. #include "Common/OVERRIDE.h"
  38. #include "Common/PlayerTemplate.h"
  39. #include "Common/Player.h"
  40. #include "Common/PlayerList.h"
  41. #include "Common/ProductionPrerequisite.h"
  42. #include "Common/SpecialPower.h"
  43. #include "Common/ThingTemplate.h"
  44. #include "Common/ThingFactory.h"
  45. #include "Common/Upgrade.h"
  46. #include "Common/Recorder.h"
  47. #include "GameLogic/GameLogic.h"
  48. #include "GameLogic/Object.h"
  49. #include "GameLogic/Module/ProductionUpdate.h"
  50. #include "GameLogic/Module/OCLUpdate.h"
  51. #include "GameLogic/Module/ContainModule.h"
  52. #include "GameLogic/Module/SpecialPowerModule.h"
  53. #include "GameLogic/Module/StealthUpdate.h"
  54. #include "GameLogic/Module/RebuildHoleBehavior.h"
  55. #include "GameLogic/ScriptEngine.h"
  56. #include "GameClient/AnimateWindowManager.h"
  57. #include "GameClient/ControlBar.h"
  58. #include "GameClient/ControlBarScheme.h"
  59. #include "GameClient/Drawable.h"
  60. #include "GameClient/Display.h"
  61. #include "GameClient/GameClient.h"
  62. #include "GameClient/GameWindowManager.h"
  63. #include "GameClient/GameText.h"
  64. #include "GameClient/GadgetPushButton.h"
  65. #include "GameClient/GadgetProgressBar.h"
  66. #include "GameClient/GadgetStaticText.h"
  67. #include "GameClient/GadgetTextEntry.h"
  68. #include "GameClient/InGameUI.h"
  69. #include "GameClient/WindowVideoManager.h"
  70. #include "GameClient/ControlBarResizer.h"
  71. #include "GameClient/GadgetListBox.h"
  72. #include "GameClient/HotKey.h"
  73. #include "GameClient/GameWindowTransitions.h"
  74. #include "GameClient/GUICallbacks.h"
  75. #include "GameNetwork/GameInfo.h"
  76. #ifdef _INTERNAL
  77. // for occasional debugging...
  78. //#pragma optimize("", off)
  79. //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
  80. #endif
  81. // PUBLIC /////////////////////////////////////////////////////////////////////////////////////////
  82. ControlBar *TheControlBar = NULL;
  83. const Image* ControlBar::m_rankVeteranIcon = NULL;
  84. const Image* ControlBar::m_rankEliteIcon = NULL;
  85. const Image* ControlBar::m_rankHeroicIcon = NULL;
  86. ///////////////////////////////////////////////////////////////////////////////////////////////////
  87. // CommandButton //////////////////////////////////////////////////////////////////////////////////
  88. ///////////////////////////////////////////////////////////////////////////////////////////////////
  89. //-------------------------------------------------------------------------------------------------
  90. //-------------------------------------------------------------------------------------------------
  91. const FieldParse CommandButton::s_commandButtonFieldParseTable[] =
  92. {
  93. { "Command", CommandButton::parseCommand, NULL, offsetof( CommandButton, m_command ) },
  94. { "Options", INI::parseBitString32, TheCommandOptionNames, offsetof( CommandButton, m_options ) },
  95. { "Object", INI::parseThingTemplate, NULL, offsetof( CommandButton, m_thingTemplate ) },
  96. { "Upgrade", INI::parseUpgradeTemplate, NULL, offsetof( CommandButton, m_upgradeTemplate ) },
  97. { "WeaponSlot", INI::parseLookupList, TheWeaponSlotTypeNamesLookupList, offsetof( CommandButton, m_weaponSlot ) },
  98. { "MaxShotsToFire", INI::parseInt, NULL, offsetof( CommandButton, m_maxShotsToFire ) },
  99. { "Science", INI::parseScienceVector, NULL, offsetof( CommandButton, m_science ) },
  100. { "SpecialPower", INI::parseSpecialPowerTemplate, NULL, offsetof( CommandButton, m_specialPower ) },
  101. { "TextLabel", INI::parseAsciiString, NULL, offsetof( CommandButton, m_textLabel ) },
  102. { "DescriptLabel", INI::parseAsciiString, NULL, offsetof( CommandButton, m_descriptionLabel ) },
  103. { "PurchasedLabel", INI::parseAsciiString, NULL, offsetof( CommandButton, m_purchasedLabel ) },
  104. { "ConflictingLabel", INI::parseAsciiString, NULL, offsetof( CommandButton, m_conflictingLabel ) },
  105. { "ButtonImage", INI::parseAsciiString, NULL, offsetof( CommandButton, m_buttonImageName ) },
  106. { "CursorName", INI::parseAsciiString, NULL, offsetof( CommandButton, m_cursorName ) },
  107. { "InvalidCursorName", INI::parseAsciiString, NULL, offsetof( CommandButton, m_invalidCursorName ) },
  108. { "ButtonBorderType", INI::parseLookupList, CommandButtonMappedBorderTypeNames, offsetof( CommandButton, m_commandButtonBorder ) },
  109. { "RadiusCursorType", INI::parseIndexList, TheRadiusCursorNames, offsetof( CommandButton, m_radiusCursor ) },
  110. { "UnitSpecificSound", INI::parseAudioEventRTS, NULL, offsetof( CommandButton, m_unitSpecificSound ) },
  111. { NULL, NULL, NULL, 0 } // keep this last
  112. };
  113. static void commandButtonTooltip(GameWindow *window,
  114. WinInstanceData *instData,
  115. UnsignedInt mouse)
  116. {
  117. TheControlBar->showBuildTooltipLayout(window);
  118. }
  119. void ControlBar::populatePurchaseScience( Player* player )
  120. {
  121. // TheInGameUI->deselectAllDrawables();
  122. const CommandSet *commandSet1;
  123. const CommandSet *commandSet3;
  124. const CommandSet *commandSet8;
  125. Int i;
  126. if(TheScriptEngine->isGameEnding())
  127. return;
  128. // get command set
  129. if(!player ||!player->getPlayerTemplate() || player->getPlayerTemplate()->getPurchaseScienceCommandSetRank1().isEmpty() ||
  130. player->getPlayerTemplate()->getPurchaseScienceCommandSetRank3().isEmpty() ||
  131. player->getPlayerTemplate()->getPurchaseScienceCommandSetRank8().isEmpty())
  132. return;
  133. commandSet1 = TheControlBar->findCommandSet(player->getPlayerTemplate()->getPurchaseScienceCommandSetRank1()); // TEMP WILL CHANGE TO PROPER WAY ONCE WORKING
  134. commandSet3 = TheControlBar->findCommandSet(player->getPlayerTemplate()->getPurchaseScienceCommandSetRank3()); // TEMP WILL CHANGE TO PROPER WAY ONCE WORKING
  135. commandSet8 = TheControlBar->findCommandSet(player->getPlayerTemplate()->getPurchaseScienceCommandSetRank8()); // TEMP WILL CHANGE TO PROPER WAY ONCE WORKING
  136. for( i = 0; i < MAX_PURCHASE_SCIENCE_RANK_1; i++ )
  137. m_sciencePurchaseWindowsRank1[i]->winHide(TRUE);
  138. for( i = 0; i < MAX_PURCHASE_SCIENCE_RANK_3; i++ )
  139. m_sciencePurchaseWindowsRank3[i]->winHide(TRUE);
  140. for( i = 0; i < MAX_PURCHASE_SCIENCE_RANK_8; i++ )
  141. m_sciencePurchaseWindowsRank8[i]->winHide(TRUE);
  142. // if no command set match is found hide all the buttons
  143. if( commandSet1 == NULL ||
  144. commandSet3 == NULL ||
  145. commandSet8 == NULL )
  146. return;
  147. // populate the button with commands defined
  148. const CommandButton *commandButton;
  149. for( i = 0; i < MAX_PURCHASE_SCIENCE_RANK_1; i++ )
  150. {
  151. // get command button
  152. commandButton = commandSet1->getCommandButton(i);
  153. // if button is not present, just hide the window
  154. if( commandButton == NULL )
  155. {
  156. // hide window on interface
  157. m_sciencePurchaseWindowsRank1[ i ]->winHide( TRUE );
  158. } // end if
  159. else
  160. {
  161. // make sure the window is not hidden
  162. m_sciencePurchaseWindowsRank1[ i ]->winHide( FALSE );
  163. // Disable by default
  164. m_sciencePurchaseWindowsRank1[ i ]->winEnable( FALSE );
  165. // populate the visible button with data from the command button
  166. setControlCommand( m_sciencePurchaseWindowsRank1[ i ], commandButton );
  167. if (!commandButton->getScienceVec().empty())
  168. {
  169. ScienceType st = commandButton->getScienceVec()[ 0 ];
  170. if( player->isScienceDisabled( st ) )
  171. {
  172. //A script has deemed this science disabled.
  173. m_sciencePurchaseWindowsRank1[ i ]->winEnable( FALSE );
  174. }
  175. else if( player->isScienceHidden( st ) )
  176. {
  177. //A script has deemed this science unavailable, thus hidden
  178. m_sciencePurchaseWindowsRank1[ i ]->winHide( TRUE );
  179. }
  180. else
  181. {
  182. //Handle normal game logic cases!
  183. if(!player->hasScience(st) && TheScienceStore->playerHasPrereqsForScience(player, st) && TheScienceStore->getSciencePurchaseCost(st) <= player->getSciencePurchasePoints())
  184. {
  185. m_sciencePurchaseWindowsRank1[ i ]->winEnable( TRUE );
  186. }
  187. if(player->hasScience(st))
  188. {
  189. m_sciencePurchaseWindowsRank1[ i ]->winSetStatus(WIN_STATUS_ALWAYS_COLOR);
  190. }
  191. else
  192. {
  193. m_sciencePurchaseWindowsRank1[ i ]->winClearStatus(WIN_STATUS_ALWAYS_COLOR);
  194. }
  195. if(!TheScienceStore->playerHasRootPrereqsForScience(player, st))
  196. m_sciencePurchaseWindowsRank1[ i ]->winHide(TRUE);
  197. }
  198. }
  199. } // end else
  200. } // end for
  201. for( i = 0; i < MAX_PURCHASE_SCIENCE_RANK_3; i++ )
  202. {
  203. // get command button
  204. commandButton = commandSet3->getCommandButton(i);
  205. // if button is not present, just hide the window
  206. if( commandButton == NULL )
  207. {
  208. // hide window on interface
  209. m_sciencePurchaseWindowsRank3[ i ]->winHide( TRUE );
  210. } // end if
  211. else
  212. {
  213. // make sure the window is not hidden
  214. m_sciencePurchaseWindowsRank3[ i ]->winHide( FALSE );
  215. // Disable by default
  216. m_sciencePurchaseWindowsRank3[ i ]->winEnable( FALSE );
  217. // populate the visible button with data from the command button
  218. setControlCommand( m_sciencePurchaseWindowsRank3[ i ], commandButton );
  219. ScienceType st = SCIENCE_INVALID;
  220. st = commandButton->getScienceVec()[ 0 ];
  221. if( player->isScienceDisabled( st ) )
  222. {
  223. //A script has deemed this science disabled.
  224. m_sciencePurchaseWindowsRank3[ i ]->winEnable( FALSE );
  225. }
  226. else if( player->isScienceHidden( st ) )
  227. {
  228. //A script has deemed this science unavailable, thus hidden
  229. m_sciencePurchaseWindowsRank3[ i ]->winHide( TRUE );
  230. }
  231. else
  232. {
  233. //Handle normal game logic cases!
  234. if(!player->hasScience(st) && TheScienceStore->playerHasPrereqsForScience(player, st) && TheScienceStore->getSciencePurchaseCost(st) <= player->getSciencePurchasePoints())
  235. {
  236. m_sciencePurchaseWindowsRank3[ i ]->winEnable( TRUE );
  237. }
  238. if(player->hasScience(st))
  239. {
  240. m_sciencePurchaseWindowsRank3[ i ]->winSetStatus(WIN_STATUS_ALWAYS_COLOR);
  241. }
  242. else
  243. {
  244. m_sciencePurchaseWindowsRank3[ i ]->winClearStatus(WIN_STATUS_ALWAYS_COLOR);
  245. }
  246. if(!TheScienceStore->playerHasRootPrereqsForScience(player, st))
  247. m_sciencePurchaseWindowsRank3[ i ]->winHide(TRUE);
  248. }
  249. } // end else
  250. } // end for
  251. for( i = 0; i < MAX_PURCHASE_SCIENCE_RANK_8; i++ )
  252. {
  253. // get command button
  254. commandButton = commandSet8->getCommandButton(i);
  255. // if button is not present, just hide the window
  256. if( commandButton == NULL )
  257. {
  258. // hide window on interface
  259. m_sciencePurchaseWindowsRank8[ i ]->winHide( TRUE );
  260. } // end if
  261. else
  262. {
  263. // make sure the window is not hidden
  264. m_sciencePurchaseWindowsRank8[ i ]->winHide( FALSE );
  265. // Disable by default
  266. m_sciencePurchaseWindowsRank8[ i ]->winEnable( FALSE );
  267. // populate the visible button with data from the command button
  268. setControlCommand( m_sciencePurchaseWindowsRank8[ i ], commandButton );
  269. ScienceType st = SCIENCE_INVALID;
  270. st = commandButton->getScienceVec()[ 0 ];
  271. if( player->isScienceDisabled( st ) )
  272. {
  273. //A script has deemed this science disabled.
  274. m_sciencePurchaseWindowsRank8[ i ]->winEnable( FALSE );
  275. }
  276. else if( player->isScienceHidden( st ) )
  277. {
  278. //A script has deemed this science unavailable, thus hidden
  279. m_sciencePurchaseWindowsRank8[ i ]->winHide( TRUE );
  280. }
  281. else
  282. {
  283. //Handle normal game logic cases!
  284. if(!player->hasScience(st) && TheScienceStore->playerHasPrereqsForScience(player, st) && TheScienceStore->getSciencePurchaseCost(st) <= player->getSciencePurchasePoints())
  285. {
  286. m_sciencePurchaseWindowsRank8[ i ]->winEnable( TRUE );
  287. }
  288. if(player->hasScience(st))
  289. {
  290. m_sciencePurchaseWindowsRank8[ i ]->winSetStatus(WIN_STATUS_ALWAYS_COLOR);
  291. }
  292. else
  293. {
  294. m_sciencePurchaseWindowsRank8[ i ]->winClearStatus(WIN_STATUS_ALWAYS_COLOR);
  295. }
  296. if(!TheScienceStore->playerHasRootPrereqsForScience(player, st))
  297. m_sciencePurchaseWindowsRank8[ i ]->winHide(TRUE);
  298. }
  299. } // end else
  300. } // end for
  301. GameWindow *win = NULL;
  302. UnicodeString tempUS;
  303. win = TheWindowManager->winGetWindowFromId( m_contextParent[ CP_PURCHASE_SCIENCE ], TheNameKeyGenerator->nameToKey( "GeneralsExpPoints.wnd:StaticTextRankPointsAvailable" ) );
  304. if(win)
  305. {
  306. tempUS.format(L"%d", player->getSciencePurchasePoints());
  307. GadgetStaticTextSetText(win, tempUS);
  308. }
  309. win = TheWindowManager->winGetWindowFromId( m_contextParent[ CP_PURCHASE_SCIENCE ], TheNameKeyGenerator->nameToKey( "GeneralsExpPoints.wnd:StaticTextLevel" ) );
  310. if(win)
  311. {
  312. tempUS.format(TheGameText->fetch("SCIENCE:Rank"), player->getRankLevel());
  313. GadgetStaticTextSetText(win, tempUS);
  314. }
  315. win = TheWindowManager->winGetWindowFromId( m_contextParent[ CP_PURCHASE_SCIENCE ], TheNameKeyGenerator->nameToKey( "GeneralsExpPoints.wnd:ProgressBarExperience" ) );
  316. if(win)
  317. {
  318. Int progress;
  319. progress = ((player->getSkillPoints() - player->getSkillPointsLevelDown()) * 100) /(player->getSkillPointsLevelUp() - player->getSkillPointsLevelDown());
  320. GadgetProgressBarSetProgress(win, progress);
  321. }
  322. win = TheWindowManager->winGetWindowFromId( m_contextParent[ CP_PURCHASE_SCIENCE ], TheNameKeyGenerator->nameToKey( "GeneralsExpPoints.wnd:StaticTextTitle" ) );
  323. if(win)
  324. {
  325. AsciiString tempAs;
  326. tempAs.format("SCIENCE:Rank%d", player->getRankLevel());
  327. GadgetStaticTextSetText(win, TheGameText->fetch(tempAs));
  328. }
  329. //
  330. // to avoid a one frame delay where windows may become enabled/disabled, run the update
  331. // at once to get it all in the correct state immediately
  332. //
  333. updateContextPurchaseScience();
  334. /*
  335. // get the side select buttons
  336. GameWindow* win = m_contextParent[ CP_PURCHASE_SCIENCE ];
  337. Color color = GameMakeColor(255, 255, 255, 255);
  338. /// @todo srj -- evil hack testing code. do not imitate.
  339. ScienceVec purchasable, potential;
  340. TheScienceStore->getPurchasableSciences(player, purchasable, potential);
  341. GadgetListBoxReset(win);
  342. for (ScienceVec::const_iterator it = purchasable.begin(); it != purchasable.end(); ++it)
  343. {
  344. ScienceType st = *it;
  345. UnicodeString u;
  346. u.translate(TheScienceStore->getInternalNameForScience(st));
  347. GadgetListBoxAddEntryText(win, u, color, -1, -1);
  348. }
  349. for (ScienceVec::const_iterator it2 = potential.begin(); it2 != potential.end(); ++it2)
  350. {
  351. ScienceType st = *it2;
  352. AsciiString foo = "(Not Yet)";
  353. foo.concat(TheScienceStore->getInternalNameForScience(st));
  354. UnicodeString u;
  355. u.translate(foo);
  356. GadgetListBoxAddEntryText(win, u, color, -1, -1);
  357. }
  358. GadgetListBoxAddEntryText(win, UnicodeString(L"Cancel"), color, -1, -1);*/
  359. }
  360. //-------------------------------------------------------------------------------------------------
  361. //-------------------------------------------------------------------------------------------------
  362. void ControlBar::updateContextPurchaseScience( void )
  363. {
  364. GameWindow *win =NULL;
  365. Player *player = ThePlayerList->getLocalPlayer();
  366. win = TheWindowManager->winGetWindowFromId( m_contextParent[ CP_PURCHASE_SCIENCE ], TheNameKeyGenerator->nameToKey( "GeneralsExpPoints.wnd:ProgressBarExperience" ) );
  367. if(win)
  368. {
  369. Int progress;
  370. progress = ((player->getSkillPoints() - player->getSkillPointsLevelDown()) * 100) /(player->getSkillPointsLevelUp() - player->getSkillPointsLevelDown());
  371. GadgetProgressBarSetProgress(win, progress);
  372. }
  373. // win = TheWindowManager->winGetWindowFromId( m_contextParent[ CP_PURCHASE_SCIENCE ], TheNameKeyGenerator->nameToKey( "ControlBar.wnd:TextEntryGeneralName" ) );
  374. // if(win)
  375. // {
  376. // UnicodeString temp = GadgetTextEntryGetText(win);
  377. // if(temp.compare(player->getGeneralName()) != 0)
  378. // player->setGeneralName(temp);
  379. // }
  380. /*
  381. /// @todo srj -- evil hack testing code. do not imitate.
  382. Object *obj = m_currentSelectedDrawable->getObject();
  383. if( obj == NULL )
  384. return;
  385. // sanity
  386. if( obj->isKindOf( KINDOF_COMMANDCENTER ) == FALSE )
  387. switchToContext( CB_CONTEXT_NONE, NULL );
  388. GameWindow* win = m_contextParent[ CP_PURCHASE_SCIENCE ];
  389. Int selected;
  390. GadgetListBoxGetSelected( win, &selected );
  391. if( selected != -1 )
  392. {
  393. UnicodeString usci = GadgetListBoxGetText( win, selected, 0 );
  394. AsciiString sci;
  395. sci.translate(usci);
  396. ScienceType st = usci.getCharAt(0) == '(' ? SCIENCE_INVALID : TheScienceStore->getScienceFromInternalName(sci);
  397. if (st != SCIENCE_INVALID)
  398. {
  399. GameMessage *msg = TheMessageStream->appendMessage( GameMessage::MSG_PURCHASE_SCIENCE );
  400. msg->appendIntegerArgument( st );
  401. }
  402. switchToContext( CB_CONTEXT_NONE, NULL );
  403. }
  404. */
  405. }
  406. //-------------------------------------------------------------------------------------------------
  407. /** parse command definition */
  408. //-------------------------------------------------------------------------------------------------
  409. void CommandButton::parseCommand( INI* ini, void *instance, void *store, const void *userData )
  410. {
  411. const char *token = ini->getNextToken();
  412. Int i;
  413. for( i = 0; TheGuiCommandNames[ i ]; i++ )
  414. {
  415. if( stricmp( TheGuiCommandNames[ i ], token ) == 0 )
  416. {
  417. GUICommandType *command = (GUICommandType *)store;
  418. *command = (GUICommandType)i;
  419. return;
  420. } // end if
  421. } // end for i
  422. // if we're here the command was not found
  423. throw INI_INVALID_DATA;
  424. } // end parseCommand
  425. //-------------------------------------------------------------------------------------------------
  426. //-------------------------------------------------------------------------------------------------
  427. CommandButton::CommandButton( void )
  428. {
  429. m_command = GUI_COMMAND_NONE;
  430. m_thingTemplate = NULL;
  431. m_upgradeTemplate = NULL;
  432. m_weaponSlot = PRIMARY_WEAPON;
  433. m_maxShotsToFire = 0x7fffffff; // huge number
  434. m_science.clear();
  435. m_specialPower = NULL;
  436. m_buttonImage = NULL;
  437. //Code renderer handles these states now.
  438. //m_disabledImage = NULL;
  439. //m_hiliteImage = NULL;
  440. //m_pushedImage = NULL;
  441. m_flashCount = 0;
  442. // Added by Sadullah Nader
  443. // The purpose is to initialize these variable to values that are zero or empty
  444. m_conflictingLabel.clear();
  445. m_cursorName.clear();
  446. m_descriptionLabel.clear();
  447. m_invalidCursorName.clear();
  448. m_name.clear();
  449. m_options = 0;
  450. m_purchasedLabel.clear();
  451. m_textLabel.clear();
  452. // End Add
  453. m_window = NULL;
  454. m_commandButtonBorder = COMMAND_BUTTON_BORDER_NONE;
  455. //m_prev = NULL;
  456. m_next = NULL;
  457. m_radiusCursor = RADIUSCURSOR_NONE;
  458. }
  459. //-------------------------------------------------------------------------------------------------
  460. //-------------------------------------------------------------------------------------------------
  461. CommandButton::~CommandButton( void )
  462. {
  463. }
  464. //-------------------------------------------------------------------------------------------------
  465. Bool CommandButton::isValidRelationshipTarget(Relationship r) const
  466. {
  467. UnsignedInt mask = 0;
  468. if (r == ENEMIES) mask |= NEED_TARGET_ENEMY_OBJECT;
  469. else if (r == ALLIES) mask |= NEED_TARGET_ALLY_OBJECT;
  470. else if (r == NEUTRAL) mask |= NEED_TARGET_NEUTRAL_OBJECT;
  471. return (m_options & mask) != 0;
  472. }
  473. //-------------------------------------------------------------------------------------------------
  474. Bool CommandButton::isValidObjectTarget(const Player* sourcePlayer, const Object* targetObj) const
  475. {
  476. if (!sourcePlayer || !targetObj)
  477. return false;
  478. Relationship r = sourcePlayer->getRelationship(targetObj->getTeam());
  479. return isValidRelationshipTarget(r);
  480. }
  481. //-------------------------------------------------------------------------------------------------
  482. Bool CommandButton::isValidObjectTarget(const Object* sourceObj, const Object* targetObj) const
  483. {
  484. if (!sourceObj || !targetObj)
  485. return false;
  486. Relationship r = sourceObj->getRelationship(targetObj);
  487. return isValidRelationshipTarget(r);
  488. }
  489. //-------------------------------------------------------------------------------------------------
  490. Bool CommandButton::isValidToUseOn(const Object *sourceObj, const Object *targetObj, const Coord3D *targetLocation, CommandSourceType commandSource) const
  491. {
  492. if (m_upgradeTemplate) {
  493. // @todo: Make a const version of pui. We're not altering the production queue, so this const-cast
  494. // is okay.
  495. ProductionUpdateInterface *pui = const_cast<Object*>(sourceObj)->getProductionUpdateInterface();
  496. if (pui) {
  497. const ProductionEntry *pe = pui->firstProduction();
  498. while (pe) {
  499. if (pe->getProductionUpgrade() != NULL)
  500. return false;
  501. pe = pui->nextProduction(pe);
  502. }
  503. return sourceObj->affectedByUpgrade(m_upgradeTemplate) && !sourceObj->hasUpgrade(m_upgradeTemplate);
  504. }
  505. // No ProductionUpdateInterface means we can't do this.
  506. return false;
  507. }
  508. if( BitTest( m_options, COMMAND_OPTION_NEED_OBJECT_TARGET ) && !targetObj )
  509. {
  510. return false;
  511. }
  512. if( BitTest( m_options, NEED_TARGET_POS ) && !targetLocation )
  513. {
  514. return false;
  515. }
  516. if( BitTest( m_options, COMMAND_OPTION_NEED_OBJECT_TARGET ) )
  517. {
  518. return TheActionManager->canDoSpecialPowerAtObject( sourceObj, targetObj, commandSource, m_specialPower, m_options, false );
  519. }
  520. if( BitTest( m_options, NEED_TARGET_POS ) )
  521. {
  522. return TheActionManager->canDoSpecialPowerAtLocation( sourceObj, targetLocation, commandSource, m_specialPower, NULL, m_options, false );
  523. }
  524. return TheActionManager->canDoSpecialPower( sourceObj, m_specialPower, commandSource, m_options, false );
  525. }
  526. //-------------------------------------------------------------------------------------------------
  527. Bool CommandButton::isReady(const Object *sourceObj) const
  528. {
  529. SpecialPowerModuleInterface *mod = sourceObj->getSpecialPowerModule( m_specialPower );
  530. if( mod && mod->getPercentReady() == 1.0f )
  531. return true;
  532. if (m_upgradeTemplate && sourceObj->affectedByUpgrade(m_upgradeTemplate) && !sourceObj->hasUpgrade(m_upgradeTemplate))
  533. return true;
  534. return false;
  535. }
  536. //-------------------------------------------------------------------------------------------------
  537. Bool CommandButton::isValidObjectTarget(const Drawable* source, const Drawable* target) const
  538. {
  539. return isValidObjectTarget(source ? source->getObject() : NULL, target ? target->getObject() : NULL);
  540. }
  541. ///////////////////////////////////////////////////////////////////////////////////////////////////
  542. // CommandSet /////////////////////////////////////////////////////////////////////////////////////
  543. ///////////////////////////////////////////////////////////////////////////////////////////////////
  544. //-------------------------------------------------------------------------------------------------
  545. /** These are the fields you can define in a command set, they correspond to physical
  546. * buttons in the GUI */
  547. //-------------------------------------------------------------------------------------------------
  548. const FieldParse CommandSet::m_commandSetFieldParseTable[] =
  549. {
  550. { "1", CommandSet::parseCommandButton, (void *)0, offsetof( CommandSet, m_command ) },
  551. { "2", CommandSet::parseCommandButton, (void *)1, offsetof( CommandSet, m_command ) },
  552. { "3", CommandSet::parseCommandButton, (void *)2, offsetof( CommandSet, m_command ) },
  553. { "4", CommandSet::parseCommandButton, (void *)3, offsetof( CommandSet, m_command ) },
  554. { "5", CommandSet::parseCommandButton, (void *)4, offsetof( CommandSet, m_command ) },
  555. { "6", CommandSet::parseCommandButton, (void *)5, offsetof( CommandSet, m_command ) },
  556. { "7", CommandSet::parseCommandButton, (void *)6, offsetof( CommandSet, m_command ) },
  557. { "8", CommandSet::parseCommandButton, (void *)7, offsetof( CommandSet, m_command ) },
  558. { "9", CommandSet::parseCommandButton, (void *)8, offsetof( CommandSet, m_command ) },
  559. { "10", CommandSet::parseCommandButton, (void *)9, offsetof( CommandSet, m_command ) },
  560. { "11", CommandSet::parseCommandButton, (void *)10, offsetof( CommandSet, m_command ) },
  561. { "12", CommandSet::parseCommandButton, (void *)11, offsetof( CommandSet, m_command ) },
  562. { NULL, NULL, NULL, 0 } // keep this last
  563. };
  564. //-------------------------------------------------------------------------------------------------
  565. Bool CommandButton::isContextCommand() const
  566. {
  567. return BitTest( m_options, CONTEXTMODE_COMMAND );
  568. }
  569. //-------------------------------------------------------------------------------------------------
  570. // bleah. shouldn't be const, but is. sue me. (srj)
  571. void CommandButton::copyImagesFrom( const CommandButton *button, Bool markUIDirtyIfChanged ) const
  572. {
  573. if( m_buttonImage != button->getButtonImage() )
  574. {
  575. m_buttonImage = button->getButtonImage();
  576. //Code renderer handles these states now.
  577. //m_disabledImage = button->getDisabledImage();
  578. //m_hiliteImage = button->getHiliteImage();
  579. //m_pushedImage = button->getPushedImage();
  580. if( markUIDirtyIfChanged )
  581. {
  582. TheControlBar->markUIDirty();
  583. }
  584. }
  585. }
  586. //-------------------------------------------------------------------------------------------------
  587. /** Parse a single command button definition */
  588. //-------------------------------------------------------------------------------------------------
  589. void CommandSet::parseCommandButton( INI* ini, void *instance, void *store, const void *userData )
  590. {
  591. const char *token = ini->getNextToken();
  592. // get find the command button from this name
  593. const CommandButton *commandButton = TheControlBar->findCommandButton( AsciiString( token ) );
  594. if( commandButton == NULL )
  595. {
  596. DEBUG_CRASH(( "[LINE: %d - FILE: '%s'] Unknown command '%s' found in command set\n",
  597. ini->getLineNum(), ini->getFilename().str(), token ));
  598. throw INI_INVALID_DATA;
  599. } // end if
  600. // get the index to store the command at, and the command array itself
  601. const CommandButton **buttonArray = (const CommandButton **)store;
  602. Int buttonIndex = (Int)userData;
  603. // sanity
  604. DEBUG_ASSERTCRASH( buttonIndex < MAX_COMMANDS_PER_SET, ("parseCommandButton: button index '%d' out of range\n",
  605. buttonIndex) );
  606. // save it
  607. buttonArray[ buttonIndex ] = commandButton;
  608. } // end parseCommand
  609. //-------------------------------------------------------------------------------------------------
  610. //-------------------------------------------------------------------------------------------------
  611. CommandSet::CommandSet(const AsciiString& name) :
  612. m_name(name),
  613. m_next(NULL)
  614. {
  615. for( Int i = 0; i < MAX_COMMANDS_PER_SET; i++ )
  616. m_command[ i ] = NULL;
  617. }
  618. //-------------------------------------------------------------------------------------------------
  619. //-------------------------------------------------------------------------------------------------
  620. const CommandButton* CommandSet::getCommandButton(Int i) const
  621. {
  622. const CommandButton* button;
  623. // Check for TheGameLogic == null, cause it is in Worldbuilder, and wb gets command bar info. jba.
  624. if (TheGameLogic && TheGameLogic->findControlBarOverride(m_name, i, button))
  625. return button;
  626. return m_command[i];
  627. }
  628. //-------------------------------------------------------------------------------------------------
  629. //-------------------------------------------------------------------------------------------------
  630. void CommandSet::friend_addToList(CommandSet** listHead)
  631. {
  632. m_next = *listHead;
  633. *listHead = this;
  634. }
  635. //-------------------------------------------------------------------------------------------------
  636. //-------------------------------------------------------------------------------------------------
  637. CommandSet::~CommandSet( void )
  638. {
  639. } // end ~CommandSet
  640. ///////////////////////////////////////////////////////////////////////////////////////////////////
  641. // ControlBar /////////////////////////////////////////////////////////////////////////////////////
  642. ///////////////////////////////////////////////////////////////////////////////////////////////////
  643. //-------------------------------------------------------------------------------------------------
  644. //-------------------------------------------------------------------------------------------------
  645. ControlBar::ControlBar( void )
  646. {
  647. Int i;
  648. m_commandButtons = NULL;
  649. m_commandSets = NULL;
  650. m_controlBarSchemeManager = NULL;
  651. m_isObserverCommandBar = FALSE;
  652. m_observerLookAtPlayer = NULL;
  653. m_buildToolTipLayout = NULL;
  654. m_showBuildToolTipLayout = FALSE;
  655. // Added By Sadullah Nader
  656. // initializing vars to zero
  657. m_animateDownWin1Pos.x = m_animateDownWin1Pos.y = 0;
  658. m_animateDownWin1Size.x = m_animateDownWin1Size.y = 0;
  659. m_animateDownWin2Pos.x = m_animateDownWin2Pos.y = 0;
  660. m_animateDownWin2Size.x = m_animateDownWin2Size.y = 0;
  661. m_animateDownWindow = NULL;
  662. m_animTime = 0;
  663. for( i = 0; i < MAX_COMMANDS_PER_SET; i++)
  664. {
  665. m_commonCommands[i] = 0;
  666. }
  667. m_currContext = CB_CONTEXT_NONE;
  668. m_defaultControlBarPosition.x = m_defaultControlBarPosition.y = 0;
  669. m_genStarFlash = FALSE;
  670. m_genStarOff = NULL;
  671. m_genStarOn = NULL;
  672. m_UIDirty = FALSE;
  673. //
  674. // m_controlBarResizer = NULL;
  675. m_buildUpClockColor = GameMakeColor(0,0,0,100);
  676. m_commandBarBorderColor = GameMakeColor(0,0,0,100);
  677. for( i = 0; i < NUM_CONTEXT_PARENTS; i++ )
  678. m_contextParent[ i ] = NULL;
  679. for( i = 0; i < MAX_COMMANDS_PER_SET; i++ )
  680. {
  681. m_commandWindows[ i ] = NULL;
  682. // removed from multiplayer branch
  683. //m_commandMarkers[ i ] = NULL;
  684. }
  685. for( i = 0; i < MAX_PURCHASE_SCIENCE_RANK_1; i++ )
  686. m_sciencePurchaseWindowsRank1[i] = NULL;
  687. for( i = 0; i < MAX_PURCHASE_SCIENCE_RANK_3; i++ )
  688. m_sciencePurchaseWindowsRank3[i] = NULL;
  689. for( i = 0; i < MAX_PURCHASE_SCIENCE_RANK_8; i++ )
  690. m_sciencePurchaseWindowsRank8[i] = NULL;
  691. for( i = 0; i < MAX_SPECIAL_POWER_SHORTCUTS; i++ )
  692. {
  693. m_specialPowerShortcutButtons[i] = NULL;
  694. m_specialPowerShortcutButtonParents[i] = NULL;
  695. }
  696. m_specialPowerShortcutParent = NULL;
  697. m_specialPowerLayout = NULL;
  698. m_scienceLayout = NULL;
  699. m_rightHUDWindow = NULL;
  700. m_rightHUDCameoWindow = NULL;
  701. for( i = 0; i < MAX_RIGHT_HUD_UPGRADE_CAMEOS; i++ )
  702. m_rightHUDUpgradeCameos[i];
  703. m_rightHUDUnitSelectParent = NULL;
  704. m_communicatorButton = NULL;
  705. m_currentSelectedDrawable = NULL;
  706. m_currContext = CB_CONTEXT_NONE;
  707. m_rallyPointDrawableID = INVALID_DRAWABLE_ID;
  708. m_displayedConstructPercent = -1.0f;
  709. m_displayedOCLTimerSeconds = 0;
  710. m_displayedQueueCount = 0;
  711. resetBuildQueueData();
  712. resetContainData();
  713. m_lastRecordedInventoryCount = 0;
  714. m_videoManager = NULL;
  715. m_animateWindowManager = NULL;
  716. m_generalsScreenAnimate = NULL;
  717. m_animateWindowManagerForGenShortcuts = NULL;
  718. m_flash = FALSE;
  719. m_toggleButtonUpIn = NULL;
  720. m_toggleButtonUpOn = NULL;
  721. m_toggleButtonUpPushed = NULL;
  722. m_toggleButtonDownIn = NULL;
  723. m_toggleButtonDownOn = NULL;
  724. m_toggleButtonDownPushed = NULL;
  725. m_generalButtonEnable = NULL;
  726. m_generalButtonHighlight = NULL;
  727. m_genArrow = NULL;
  728. m_sideSelectAnimateDown = FALSE;
  729. updateCommanBarBorderColors(GAME_COLOR_UNDEFINED,GAME_COLOR_UNDEFINED,GAME_COLOR_UNDEFINED,GAME_COLOR_UNDEFINED);
  730. m_radarAttackGlowOn = FALSE;
  731. m_remainingRadarAttackGlowFrames = 0;
  732. m_radarAttackGlowWindow = NULL;
  733. } // end ControlBar
  734. //-------------------------------------------------------------------------------------------------
  735. //-------------------------------------------------------------------------------------------------
  736. ControlBar::~ControlBar( void )
  737. {
  738. if(m_scienceLayout)
  739. {
  740. m_scienceLayout->destroyWindows();
  741. m_scienceLayout->deleteInstance();
  742. }
  743. m_scienceLayout = NULL;
  744. m_genArrow = NULL;
  745. if(m_videoManager)
  746. delete m_videoManager;
  747. m_videoManager = NULL;
  748. if(m_animateWindowManagerForGenShortcuts)
  749. delete m_animateWindowManagerForGenShortcuts;
  750. m_animateWindowManagerForGenShortcuts = NULL;
  751. if(m_animateWindowManager)
  752. delete m_animateWindowManager;
  753. m_animateWindowManager = NULL;
  754. if(m_generalsScreenAnimate)
  755. delete m_generalsScreenAnimate;
  756. m_generalsScreenAnimate = NULL;
  757. if( m_controlBarSchemeManager )
  758. delete m_controlBarSchemeManager;
  759. m_controlBarSchemeManager = NULL;
  760. // if(m_controlBarResizer)
  761. // delete m_controlBarResizer;
  762. // m_controlBarResizer = NULL;
  763. // destroy all the command set definitions
  764. CommandSet *set;
  765. while( m_commandSets )
  766. {
  767. set = m_commandSets->friend_getNext();
  768. m_commandSets->deleteInstance();
  769. m_commandSets = set;
  770. } // end while
  771. // destroy all our command button definitions
  772. CommandButton *button;
  773. while( m_commandButtons )
  774. {
  775. button = m_commandButtons->friend_getNext();
  776. m_commandButtons->deleteInstance();
  777. m_commandButtons = button;
  778. } // end while
  779. if(m_buildToolTipLayout)
  780. {
  781. m_buildToolTipLayout->destroyWindows();
  782. m_buildToolTipLayout->deleteInstance();
  783. m_buildToolTipLayout = NULL;
  784. }
  785. if(m_specialPowerLayout)
  786. {
  787. m_specialPowerLayout->destroyWindows();
  788. m_specialPowerLayout->deleteInstance();
  789. m_specialPowerLayout = NULL;
  790. }
  791. m_radarAttackGlowWindow = NULL;
  792. } // end ~ControlBar
  793. void ControlBarPopupDescriptionUpdateFunc( WindowLayout *layout, void *param );
  794. //-------------------------------------------------------------------------------------------------
  795. /** Initialzie the control bar, this is our interface to the context sinsitive GUI */
  796. //-------------------------------------------------------------------------------------------------
  797. void ControlBar::init( void )
  798. {
  799. INI ini;
  800. m_sideSelectAnimateDown = FALSE;
  801. // load the command buttons
  802. ini.load( AsciiString( "Data\\INI\\Default\\CommandButton.ini" ), INI_LOAD_OVERWRITE, NULL );
  803. ini.load( AsciiString( "Data\\INI\\CommandButton.ini" ), INI_LOAD_OVERWRITE, NULL );
  804. // load the command sets
  805. ini.load( AsciiString( "Data\\INI\\CommandSet.ini" ), INI_LOAD_OVERWRITE, NULL );
  806. // post process step after loading the command buttons and command sets
  807. postProcessCommands();
  808. // Init the scheme manager, this will call it's won INI init funciton.
  809. m_controlBarSchemeManager = NEW ControlBarSchemeManager;
  810. m_controlBarSchemeManager->init();
  811. //Added this check because the builder uses the ControlBar, but doesn't care about
  812. //the GUI.
  813. if( TheWindowManager )
  814. {
  815. //
  816. // the control bar has several windows that make up our context sensitive interface, we
  817. // want those parent windows so that we can easily hide and show them to make the
  818. // interface context sensitive
  819. //
  820. NameKeyType id;
  821. id = TheNameKeyGenerator->nameToKey( "ControlBar.wnd:ControlBarParent" );
  822. m_contextParent[ CP_MASTER ] = TheWindowManager->winGetWindowFromId( NULL, id );
  823. m_contextParent[ CP_MASTER ]->winGetPosition(&m_defaultControlBarPosition.x, &m_defaultControlBarPosition.y);
  824. m_scienceLayout = TheWindowManager->winCreateLayout("GeneralsExpPoints.wnd");
  825. m_scienceLayout->hide(TRUE);
  826. id = TheNameKeyGenerator->nameToKey( "GeneralsExpPoints.wnd:GenExpParent" );
  827. m_contextParent[ CP_PURCHASE_SCIENCE ] = TheWindowManager->winGetWindowFromId( NULL, id );//m_scienceLayout->getFirstWindow();
  828. id = TheNameKeyGenerator->nameToKey( "ControlBar.wnd:UnderConstructionWindow" );
  829. m_contextParent[ CP_UNDER_CONSTRUCTION ] = TheWindowManager->winGetWindowFromId( NULL, id );
  830. id = TheNameKeyGenerator->nameToKey( "ControlBar.wnd:OCLTimerWindow" );
  831. m_contextParent[ CP_OCL_TIMER ] = TheWindowManager->winGetWindowFromId( NULL, id );
  832. id = TheNameKeyGenerator->nameToKey( "ControlBar.wnd:BeaconWindow" );
  833. m_contextParent[ CP_BEACON ] = TheWindowManager->winGetWindowFromId( NULL, id );
  834. id = TheNameKeyGenerator->nameToKey( "ControlBar.wnd:CommandWindow" );
  835. m_contextParent[ CP_COMMAND ] = TheWindowManager->winGetWindowFromId( NULL, id );
  836. id = TheNameKeyGenerator->nameToKey( "ControlBar.wnd:ProductionQueueWindow" );
  837. m_contextParent[ CP_BUILD_QUEUE ] = TheWindowManager->winGetWindowFromId( NULL, id );
  838. id = TheNameKeyGenerator->nameToKey( "ControlBar.wnd:ObserverPlayerListWindow" );
  839. m_contextParent[ CP_OBSERVER_LIST ] = TheWindowManager->winGetWindowFromId( NULL, id );
  840. id = TheNameKeyGenerator->nameToKey( "ControlBar.wnd:ObserverPlayerInfoWindow" );
  841. m_contextParent[ CP_OBSERVER_INFO ] = TheWindowManager->winGetWindowFromId( NULL, id );
  842. // get the command windows and save for easy access later
  843. Int i;
  844. ICoord2D commandSize, commandPos;
  845. AsciiString windowName;
  846. for( i = 0; i < MAX_COMMANDS_PER_SET; i++ )
  847. {
  848. windowName.format( "ControlBar.wnd:ButtonCommand%02d", i + 1 );
  849. id = TheNameKeyGenerator->nameToKey( windowName.str() );
  850. m_commandWindows[ i ] =
  851. TheWindowManager->winGetWindowFromId( m_contextParent[ CP_COMMAND ], id );
  852. m_commandWindows[ i ]->winGetPosition(&commandPos.x, &commandPos.y);
  853. m_commandWindows[ i ]->winGetSize(&commandSize.x, &commandSize.y);
  854. m_commandWindows[ i ]->winSetStatus( WIN_STATUS_USE_OVERLAY_STATES );
  855. // removed from multiplayer branch
  856. // windowName.format( "ControlBar.wnd:CommandMarker%02d", i + 1 );
  857. // id = TheNameKeyGenerator->nameToKey( windowName.str() );
  858. // m_commandMarkers[ i ] =
  859. // TheWindowManager->winGetWindowFromId( m_contextParent[ CP_COMMAND ], id );
  860. // // set the size and position to make sure their in the same place as the buttons.
  861. // m_commandMarkers[i]->winSetPosition(commandPos.x -2, commandPos.y - 2);
  862. // m_commandMarkers[i]->winSetSize(commandSize.x + 2, commandSize.y + 2);
  863. } // end for i
  864. for( i = 0; i < MAX_PURCHASE_SCIENCE_RANK_1; i++ )
  865. {
  866. windowName.format( "GeneralsExpPoints.wnd:ButtonRank1Number%d", i );
  867. id = TheNameKeyGenerator->nameToKey( windowName.str() );
  868. m_sciencePurchaseWindowsRank1[ i ] =
  869. TheWindowManager->winGetWindowFromId( m_contextParent[ CP_PURCHASE_SCIENCE ], id );
  870. m_sciencePurchaseWindowsRank1[ i ]->winSetStatus( WIN_STATUS_USE_OVERLAY_STATES );
  871. } // end for i
  872. for( i = 0; i < MAX_PURCHASE_SCIENCE_RANK_3; i++ )
  873. {
  874. windowName.format( "GeneralsExpPoints.wnd:ButtonRank3Number%d", i );
  875. id = TheNameKeyGenerator->nameToKey( windowName.str() );
  876. m_sciencePurchaseWindowsRank3[ i ] =
  877. TheWindowManager->winGetWindowFromId( m_contextParent[ CP_PURCHASE_SCIENCE ], id );
  878. m_sciencePurchaseWindowsRank3[ i ]->winSetStatus( WIN_STATUS_USE_OVERLAY_STATES );
  879. } // end for i
  880. for( i = 0; i < MAX_PURCHASE_SCIENCE_RANK_8; i++ )
  881. {
  882. windowName.format( "GeneralsExpPoints.wnd:ButtonRank8Number%d", i );
  883. id = TheNameKeyGenerator->nameToKey( windowName.str() );
  884. m_sciencePurchaseWindowsRank8[ i ] =
  885. TheWindowManager->winGetWindowFromId( m_contextParent[ CP_PURCHASE_SCIENCE ], id );
  886. m_sciencePurchaseWindowsRank8[ i ]->winSetStatus( WIN_STATUS_USE_OVERLAY_STATES );
  887. } // end for i
  888. // keep a pointer to the window making up the right HUD display
  889. id = TheNameKeyGenerator->nameToKey( "ControlBar.wnd:RightHUD" );
  890. m_rightHUDWindow = TheWindowManager->winGetWindowFromId( NULL, id );
  891. id = TheNameKeyGenerator->nameToKey( "ControlBar.wnd:WinUnitSelected" );
  892. m_rightHUDUnitSelectParent = TheWindowManager->winGetWindowFromId( NULL, id );
  893. id = TheNameKeyGenerator->nameToKey( "ControlBar.wnd:CameoWindow" );
  894. m_rightHUDCameoWindow = TheWindowManager->winGetWindowFromId( NULL, id );
  895. for( i = 0; i < MAX_RIGHT_HUD_UPGRADE_CAMEOS; i++ )
  896. {
  897. windowName.format( "ControlBar.wnd:UnitUpgrade%d", i+1 );
  898. id = TheNameKeyGenerator->nameToKey( windowName.str() );
  899. m_rightHUDUpgradeCameos[ i ] =
  900. TheWindowManager->winGetWindowFromId( m_rightHUDWindow, id );
  901. m_rightHUDUpgradeCameos[ i ]->winSetStatus( WIN_STATUS_USE_OVERLAY_STATES );
  902. }
  903. // m_transitionHandler = NEW GameWindowTransitionsHandler;
  904. // m_transitionHandler->load();
  905. // m_transitionHandler->init();
  906. // don't forget about the communicator button CCB
  907. id = TheNameKeyGenerator->nameToKey( "ControlBar.wnd:PopupCommunicator" );
  908. m_communicatorButton = TheWindowManager->winGetWindowFromId( NULL, id );
  909. setControlCommand(m_communicatorButton, findCommandButton("NonCommand_Communicator") );
  910. m_communicatorButton->winSetTooltipFunc(commandButtonTooltip);
  911. GameWindow *win = TheWindowManager->winGetWindowFromId(NULL,TheNameKeyGenerator->nameToKey("ControlBar.wnd:ButtonOptions"));
  912. if(win)
  913. {
  914. setControlCommand(win, findCommandButton("NonCommand_Options") );
  915. win->winSetTooltipFunc(commandButtonTooltip);
  916. }
  917. win = TheWindowManager->winGetWindowFromId(NULL,TheNameKeyGenerator->nameToKey("ControlBar.wnd:ButtonIdleWorker"));
  918. if(win)
  919. {
  920. setControlCommand(win, findCommandButton("NonCommand_IdleWorker") );
  921. win->winSetTooltipFunc(commandButtonTooltip);
  922. }
  923. win = TheWindowManager->winGetWindowFromId(NULL,TheNameKeyGenerator->nameToKey("ControlBar.wnd:ButtonPlaceBeacon"));
  924. if(win)
  925. {
  926. setControlCommand(win, findCommandButton("NonCommand_Beacon") );
  927. win->winSetTooltipFunc(commandButtonTooltip);
  928. }
  929. win = TheWindowManager->winGetWindowFromId(NULL,TheNameKeyGenerator->nameToKey("ControlBar.wnd:ButtonGeneral"));
  930. if(win)
  931. {
  932. setControlCommand(win, findCommandButton("NonCommand_GeneralsExperience") );
  933. win->winSetTooltipFunc(commandButtonTooltip);
  934. }
  935. win = TheWindowManager->winGetWindowFromId(NULL,TheNameKeyGenerator->nameToKey("ControlBar.wnd:ButtonLarge"));
  936. if(win)
  937. {
  938. setControlCommand(win, findCommandButton("NonCommand_UpDown") );
  939. win->winSetTooltipFunc(commandButtonTooltip);
  940. }
  941. win = TheWindowManager->winGetWindowFromId(NULL,TheNameKeyGenerator->nameToKey("ControlBar.wnd:PowerWindow"));
  942. if(win)
  943. {
  944. win->winSetTooltipFunc(commandButtonTooltip);
  945. }
  946. win = TheWindowManager->winGetWindowFromId(NULL,TheNameKeyGenerator->nameToKey("ControlBar.wnd:MoneyDisplay"));
  947. if(win)
  948. {
  949. win->winSetTooltipFunc(commandButtonTooltip);
  950. }
  951. win = TheWindowManager->winGetWindowFromId(NULL, TheNameKeyGenerator->nameToKey("ControlBar.wnd:GeneralsExp"));
  952. if(win)
  953. {
  954. win->winSetTooltipFunc(commandButtonTooltip);
  955. }
  956. m_radarAttackGlowWindow = TheWindowManager->winGetWindowFromId(NULL, TheNameKeyGenerator->nameToKey("ControlBar.wnd:WinUAttack"));
  957. win = TheWindowManager->winGetWindowFromId(NULL,TheNameKeyGenerator->nameToKey( AsciiString( "ControlBar.wnd:BackgroundMarker" ) ));
  958. win->winGetScreenPosition(&m_controlBarForegroundMarkerPos.x, &m_controlBarForegroundMarkerPos.y);
  959. win = TheWindowManager->winGetWindowFromId(NULL,TheNameKeyGenerator->nameToKey( AsciiString( "ControlBar.wnd:BackgroundMarker" ) ));
  960. win->winGetScreenPosition(&m_controlBarBackgroundMarkerPos.x,&m_controlBarBackgroundMarkerPos.y);
  961. if(!m_videoManager)
  962. m_videoManager = NEW WindowVideoManager;
  963. if(!m_animateWindowManager)
  964. m_animateWindowManager = NEW AnimateWindowManager;
  965. if(!m_generalsScreenAnimate)
  966. m_generalsScreenAnimate = NEW AnimateWindowManager;
  967. if(!m_animateWindowManagerForGenShortcuts)
  968. m_animateWindowManagerForGenShortcuts = NEW AnimateWindowManager;
  969. m_buildToolTipLayout = TheWindowManager->winCreateLayout( "ControlBarPopupDescription.wnd" );
  970. if(m_buildToolTipLayout)
  971. {
  972. m_buildToolTipLayout->hide(TRUE);
  973. m_buildToolTipLayout->setUpdate(ControlBarPopupDescriptionUpdateFunc);
  974. }
  975. m_genStarOn = TheMappedImageCollection ? (Image *)TheMappedImageCollection->findImageByName("BarButtonGenStarON") : NULL;
  976. m_genStarOff = TheMappedImageCollection ? (Image *)TheMappedImageCollection->findImageByName("BarButtonGenStarOFF") : NULL;
  977. m_genStarFlash = TRUE;
  978. m_lastFlashedAtPointValue = -1;
  979. m_rankVeteranIcon = TheMappedImageCollection ? TheMappedImageCollection->findImageByName( "SSChevron1L" ) : NULL;
  980. m_rankEliteIcon = TheMappedImageCollection ? TheMappedImageCollection->findImageByName( "SSChevron2L" ) : NULL;
  981. m_rankHeroicIcon = TheMappedImageCollection ? TheMappedImageCollection->findImageByName( "SSChevron3L" ) : NULL;
  982. // if(!m_controlBarResizer)
  983. // m_controlBarResizer = NEW ControlBarResizer;
  984. // m_controlBarResizer->init();
  985. // Initialize the Observer controls
  986. initObserverControls();
  987. // by default switch to the none context
  988. switchToContext( CB_CONTEXT_NONE, NULL );
  989. }
  990. } // end init
  991. //-------------------------------------------------------------------------------------------------
  992. /** Reset the context sensitive control bar GUI */
  993. //-------------------------------------------------------------------------------------------------
  994. void ControlBar::reset( void )
  995. {
  996. hideSpecialPowerShortcut();
  997. // do not destroy the rally drawable, it will get destroyed with everythign else during a reset
  998. m_rallyPointDrawableID = INVALID_DRAWABLE_ID;
  999. if(m_radarAttackGlowWindow)
  1000. m_radarAttackGlowWindow->winEnable(TRUE);
  1001. m_radarAttackGlowOn = FALSE;
  1002. m_remainingRadarAttackGlowFrames = 0;
  1003. m_displayedConstructPercent = -1.0f;
  1004. m_displayedOCLTimerSeconds = 0;
  1005. m_isObserverCommandBar = FALSE; // reset us to use a normal command bar
  1006. m_observerLookAtPlayer = NULL;
  1007. if(m_buildToolTipLayout)
  1008. m_buildToolTipLayout->hide(TRUE);
  1009. m_showBuildToolTipLayout = FALSE;
  1010. if(m_animateWindowManager)
  1011. m_animateWindowManager->reset();
  1012. if(m_animateWindowManagerForGenShortcuts)
  1013. m_animateWindowManagerForGenShortcuts->reset();
  1014. if(m_generalsScreenAnimate)
  1015. m_generalsScreenAnimate->reset();
  1016. if(m_videoManager)
  1017. m_videoManager->reset();
  1018. // go back to default context
  1019. switchToContext( CB_CONTEXT_NONE, NULL );
  1020. m_sideSelectAnimateDown = FALSE;
  1021. if(m_animateDownWindow)
  1022. {
  1023. TheWindowManager->winDestroy( m_animateDownWindow );
  1024. m_animateDownWindow = NULL;
  1025. }
  1026. // Remove any overridden sets.
  1027. CommandSet *set, *nextSet;
  1028. set = m_commandSets;
  1029. while (set) {
  1030. Bool possibleAdjustment = FALSE;
  1031. nextSet = set->friend_getNext();
  1032. if (set == m_commandSets) {
  1033. possibleAdjustment = TRUE;
  1034. }
  1035. Overridable *stillValid = set->deleteOverrides();
  1036. if (stillValid == NULL && possibleAdjustment) {
  1037. m_commandSets = nextSet;
  1038. }
  1039. set = nextSet;
  1040. }
  1041. // Remove any overridden command buttons.
  1042. CommandButton *button, *nextButton;
  1043. button = m_commandButtons;
  1044. while (button) {
  1045. Bool possibleAdjustment = FALSE;
  1046. nextButton = button->friend_getNext();
  1047. if (button == m_commandButtons) {
  1048. possibleAdjustment = TRUE;
  1049. }
  1050. Overridable *stillValid = button->deleteOverrides();
  1051. if (stillValid == NULL && possibleAdjustment) {
  1052. m_commandButtons = nextButton;
  1053. }
  1054. button = nextButton;
  1055. }
  1056. if(TheTransitionHandler)
  1057. TheTransitionHandler->remove("ControlBarArrow");
  1058. m_genArrow = NULL;
  1059. m_lastFlashedAtPointValue = -1;
  1060. m_genStarFlash = TRUE;
  1061. } // end reset
  1062. //-------------------------------------------------------------------------------------------------
  1063. /** Update phase, we can track if our selected object is destroyed, update button
  1064. * percentages, status, enabled status etc */
  1065. //-------------------------------------------------------------------------------------------------
  1066. void ControlBar::update( void )
  1067. {
  1068. getStarImage();
  1069. updateRadarAttackGlow();
  1070. if(m_controlBarSchemeManager)
  1071. m_controlBarSchemeManager->update();
  1072. // Update our video manager
  1073. if( m_videoManager )
  1074. m_videoManager->update();
  1075. if (m_animateWindowManager)
  1076. m_animateWindowManager->update();
  1077. if (m_animateWindowManager)
  1078. {
  1079. if (m_animateWindowManager->isFinished() && m_animateWindowManager->isReversed())
  1080. {
  1081. Int id = (Int)TheNameKeyGenerator->nameToKey(AsciiString("ControlBar.wnd:ControlBarParent"));
  1082. GameWindow *window = TheWindowManager->winGetWindowFromId(NULL, id);
  1083. if (window && !window->winIsHidden())
  1084. window->winHide(TRUE);
  1085. }
  1086. }
  1087. if(m_animateWindowManagerForGenShortcuts)
  1088. m_animateWindowManagerForGenShortcuts->update();
  1089. if (m_animateWindowManagerForGenShortcuts && m_specialPowerShortcutParent)
  1090. {
  1091. if (m_animateWindowManagerForGenShortcuts->isFinished() && m_animateWindowManagerForGenShortcuts->isReversed())
  1092. {
  1093. if (m_specialPowerShortcutParent && !m_specialPowerShortcutParent->winIsHidden())
  1094. m_specialPowerShortcutParent->winHide(TRUE);
  1095. }
  1096. }
  1097. if( !m_buildToolTipLayout->isHidden())
  1098. {
  1099. m_buildToolTipLayout->runUpdate();
  1100. m_showBuildToolTipLayout = FALSE;
  1101. }
  1102. /*
  1103. else if( m_buildToolTipLayout )
  1104. {
  1105. hideBuildTooltipLayout();
  1106. }*/
  1107. updateSpecialPowerShortcut();
  1108. // if we're an observer, don't do the complete update
  1109. if( m_isObserverCommandBar)
  1110. {
  1111. if((TheGameLogic->getFrame() % (LOGICFRAMES_PER_SECOND/2)) == 0)
  1112. populateObserverInfoWindow();
  1113. Drawable *drawToEvaluateFor = NULL;
  1114. Bool multiSelect = FALSE;
  1115. if( TheInGameUI->getSelectCount() > 1 )
  1116. {
  1117. // Attempt to isolate a Drawable here to evaluate
  1118. // The need arises when selected is an AngryMob,
  1119. // whose selection actually consists of varied units
  1120. // but is represented in the UI as a single unit,
  1121. // so we must isolate and evaluate only the Nexus
  1122. drawToEvaluateFor = TheGameClient->findDrawableByID( TheInGameUI->getSoloNexusSelectedDrawableID() ) ;
  1123. multiSelect = ( drawToEvaluateFor == NULL );
  1124. }
  1125. else // get the first and only drawble in the selection list
  1126. drawToEvaluateFor = TheInGameUI->getAllSelectedDrawables()->front();
  1127. Object *obj = drawToEvaluateFor ? drawToEvaluateFor->getObject() : NULL;
  1128. setPortraitByObject( obj );
  1129. return;
  1130. }
  1131. // check flashing
  1132. if( m_flash )
  1133. {
  1134. // go through all the command buttons to see which one needs to flash
  1135. for( Int i = 0; i < MAX_COMMANDS_PER_SET; ++i )
  1136. {
  1137. GameWindow *button = m_commandWindows[ i ];
  1138. if( button != NULL)
  1139. {
  1140. const CommandButton *commandButton = (const CommandButton *)GadgetButtonGetData(button);
  1141. if( commandButton != NULL )
  1142. {
  1143. if( commandButton->getFlashCount() > 0 && TheGameClient->getFrame() % 10 == 0 )
  1144. {
  1145. if( commandButton->getFlashCount() % 2 == 0 )
  1146. {
  1147. commandButton->setFlashCount(commandButton->getFlashCount() - 1);
  1148. button->winSetStatus( WIN_STATUS_FLASHING );
  1149. }
  1150. else
  1151. {
  1152. commandButton->setFlashCount(commandButton->getFlashCount() - 1);
  1153. button->winClearStatus( WIN_STATUS_FLASHING );
  1154. if( commandButton->getFlashCount() == 0 )
  1155. {
  1156. setFlash( FALSE );
  1157. }
  1158. }
  1159. }
  1160. }
  1161. }
  1162. }
  1163. }
  1164. if(!m_contextParent[ CP_PURCHASE_SCIENCE ]->winIsHidden())
  1165. updateContextPurchaseScience();
  1166. //
  1167. // first, if the UI is dirty repopulate the UI with what the user should see for all the
  1168. // selected drawables
  1169. //
  1170. if( m_UIDirty )
  1171. {
  1172. evaluateContextUI();
  1173. populateSpecialPowerShortcut(ThePlayerList->getLocalPlayer());
  1174. // if we have a build tooltip layout, update it with the new data.
  1175. repopulateBuildTooltipLayout();
  1176. }
  1177. // enable/disable the beacon button depending on if the max has been reached
  1178. if (ThePlayerList && ThePlayerList->getLocalPlayer() && ThePlayerList->getLocalPlayer()->getPlayerTemplate())
  1179. {
  1180. Int count;
  1181. const ThingTemplate *thing = TheThingFactory->findTemplate( ThePlayerList->getLocalPlayer()->getPlayerTemplate()->getBeaconTemplate() );
  1182. ThePlayerList->getLocalPlayer()->countObjectsByThingTemplate( 1, &thing, false, &count );
  1183. static NameKeyType beaconPlacementButtonID = NAMEKEY("ControlBar.wnd:ButtonPlaceBeacon");
  1184. GameWindow *win = TheWindowManager->winGetWindowFromId(NULL, beaconPlacementButtonID);
  1185. if (win)
  1186. {
  1187. if (count < TheMultiplayerSettings->getMaxBeaconsPerPlayer())
  1188. {
  1189. win->winEnable(TRUE);
  1190. }
  1191. else
  1192. {
  1193. win->winEnable(FALSE);
  1194. }
  1195. }
  1196. }
  1197. //
  1198. // most control bar contexts have one selected thing that we switch on and update
  1199. // based on if that thing changed in some way ... the exception is when multi selected
  1200. //
  1201. if( m_currContext == CB_CONTEXT_MULTI_SELECT )
  1202. {
  1203. updateContextMultiSelect();
  1204. return;
  1205. } // end if
  1206. // if nothing is selected get out of here except if we're in the Purchase science context... that requires
  1207. // us to not have anything selected
  1208. if( m_currentSelectedDrawable == NULL )
  1209. {
  1210. // we better be in the default none context
  1211. DEBUG_ASSERTCRASH( m_currContext == CB_CONTEXT_NONE, ("ControlBar::update no selection, but not we're not showing the default NONE context\n") );
  1212. return;
  1213. } // end if
  1214. // if our selected drawable has no object get out of here
  1215. Object *obj = NULL;
  1216. if(m_currentSelectedDrawable)
  1217. obj = m_currentSelectedDrawable->getObject();
  1218. if( obj == NULL )
  1219. {
  1220. switchToContext( CB_CONTEXT_NONE, NULL );
  1221. return;
  1222. } // end if
  1223. switch( m_currContext )
  1224. {
  1225. //---------------------------------------------------------------------------------------------
  1226. case CB_CONTEXT_NONE:
  1227. break;
  1228. //---------------------------------------------------------------------------------------------
  1229. case CB_CONTEXT_COMMAND:
  1230. updateContextCommand();
  1231. break;
  1232. //---------------------------------------------------------------------------------------------
  1233. case CB_CONTEXT_STRUCTURE_INVENTORY:
  1234. updateContextStructureInventory();
  1235. break;
  1236. //---------------------------------------------------------------------------------------------
  1237. case CB_CONTEXT_BEACON:
  1238. updateContextBeacon();
  1239. break;
  1240. //---------------------------------------------------------------------------------------------
  1241. case CB_CONTEXT_UNDER_CONSTRUCTION:
  1242. updateContextUnderConstruction();
  1243. break;
  1244. //---------------------------------------------------------------------------------------------
  1245. case CB_CONTEXT_OCL_TIMER:
  1246. updateContextOCLTimer();
  1247. break;
  1248. } // end switch
  1249. } // end update
  1250. //-------------------------------------------------------------------------------------------------
  1251. //-------------------------------------------------------------------------------------------------
  1252. void ControlBar::onDrawableSelected( Drawable *draw )
  1253. {
  1254. // set a dirty flag so next time we update we can reconstruct the UI
  1255. markUIDirty();
  1256. // cancel any pending GUI commands
  1257. TheInGameUI->setGUICommand( NULL );
  1258. } // end onDrawableSelected
  1259. //-------------------------------------------------------------------------------------------------
  1260. //-------------------------------------------------------------------------------------------------
  1261. void ControlBar::onDrawableDeselected( Drawable *draw )
  1262. {
  1263. // set a dirty flag so next time we update we can reconstruct the UI
  1264. markUIDirty();
  1265. if (TheInGameUI->getSelectCount() == 0)
  1266. {
  1267. // we just deselected everything - cancel any pending GUI commands
  1268. TheInGameUI->setGUICommand( NULL );
  1269. }
  1270. //
  1271. // always when becoming unselected should we remove any build placement icons because if
  1272. // we have some and are in the middle of a build process, it must obiously be over now
  1273. // because we are no longer selecting the dozer or worker
  1274. //
  1275. TheInGameUI->placeBuildAvailable( NULL, NULL );
  1276. } // end onDrawableDeselected
  1277. //-------------------------------------------------------------------------------------------------
  1278. const Image *ControlBar::getStarImage(void )
  1279. {
  1280. if(m_lastFlashedAtPointValue > ThePlayerList->getLocalPlayer()->getSciencePurchasePoints() || ThePlayerList->getLocalPlayer()->getSciencePurchasePoints() <= 0)
  1281. m_genStarFlash = FALSE;
  1282. else
  1283. m_lastFlashedAtPointValue = ThePlayerList->getLocalPlayer()->getSciencePurchasePoints();
  1284. GameWindow *win= TheWindowManager->winGetWindowFromId( NULL, TheNameKeyGenerator->nameToKey( "ControlBar.wnd:ButtonGeneral" ) );
  1285. if(!win)
  1286. return NULL;
  1287. if(!m_genStarFlash)
  1288. {
  1289. GadgetButtonSetEnabledImage(win, m_generalButtonEnable);
  1290. return NULL;
  1291. }
  1292. if(TheGameLogic->getFrame()% LOGICFRAMES_PER_SECOND > LOGICFRAMES_PER_SECOND/2)
  1293. {
  1294. GadgetButtonSetEnabledImage(win, m_generalButtonHighlight);
  1295. return NULL;
  1296. }
  1297. GadgetButtonSetEnabledImage(win, m_generalButtonEnable);
  1298. return NULL;
  1299. }
  1300. //-------------------------------------------------------------------------------------------------
  1301. void ControlBar::onPlayerRankChanged(const Player *p)
  1302. {
  1303. if (!p->isLocalPlayer())
  1304. return;
  1305. if(!(m_lastFlashedAtPointValue > ThePlayerList->getLocalPlayer()->getSciencePurchasePoints()))
  1306. {
  1307. if(TheTransitionHandler && TheInGameUI->getInputEnabled())
  1308. TheTransitionHandler->setGroup("ControlBarArrow");
  1309. }
  1310. // populateSpecialPowerShortcut((Player *)p);
  1311. m_genStarFlash = TRUE;
  1312. /// @todo implement me
  1313. markUIDirty();
  1314. }
  1315. //-------------------------------------------------------------------------------------------------
  1316. //-------------------------------------------------------------------------------------------------
  1317. void ControlBar::onPlayerSciencePurchasePointsChanged(const Player *p)
  1318. {
  1319. if (!p->isLocalPlayer())
  1320. return;
  1321. if(!(m_lastFlashedAtPointValue > ThePlayerList->getLocalPlayer()->getSciencePurchasePoints()))
  1322. {
  1323. if(TheTransitionHandler && TheInGameUI->getInputEnabled())
  1324. TheTransitionHandler->setGroup("ControlBarArrow");
  1325. }
  1326. // populateSpecialPowerShortcut((Player *)p);
  1327. m_genStarFlash = TRUE;
  1328. /// @todo implement me
  1329. markUIDirty();
  1330. }
  1331. //-------------------------------------------------------------------------------------------------
  1332. /** Given the drawables that we have selected into our context sensitive UI, evaluate
  1333. * and perform all UI manipulations to make the GUI show to the user what we want them
  1334. * to see */
  1335. //-------------------------------------------------------------------------------------------------
  1336. void ControlBar::evaluateContextUI( void )
  1337. {
  1338. //
  1339. // the UI has been "evaluated" and is now displaying the most current and correct
  1340. // information to the player
  1341. //
  1342. m_UIDirty = FALSE;
  1343. // if our purchase science window is up, we will want to update it by repopulating it.
  1344. if(!m_contextParent[ CP_PURCHASE_SCIENCE ]->winIsHidden())
  1345. showPurchaseScience();
  1346. // erase any current state of the GUI by switching out to the empty context
  1347. switchToContext( CB_CONTEXT_NONE, NULL );
  1348. // sanity, nothing selected
  1349. if( TheInGameUI->getSelectCount() == 0 )
  1350. return;
  1351. // get the list of drawable IDs from the in game UI
  1352. const DrawableList *selectedDrawables = TheInGameUI->getAllSelectedDrawables();
  1353. // sanity
  1354. if( selectedDrawables->empty() == TRUE )
  1355. return;
  1356. //Make sure the selected objects are in fact, controllable! If not, then
  1357. //we don't show any GUI commands for them!!!
  1358. //This is used when we select enemy objects or objects on another team.
  1359. //@todo we may want to show their portrait
  1360. if( !TheInGameUI->areSelectedObjectsControllable() )
  1361. {
  1362. //Also make sure the unit isn't a garrisonable neutral civ team building!
  1363. Drawable *draw = selectedDrawables->front();
  1364. //sanity
  1365. if( !draw )
  1366. {
  1367. return;
  1368. }
  1369. Object *obj = draw->getObject();
  1370. if( !obj )
  1371. {
  1372. return;
  1373. }
  1374. if (obj->getControllingPlayer()
  1375. && obj->getControllingPlayer()->getPlayerTemplate()
  1376. && obj->getControllingPlayer()->getPlayerTemplate()->getBeaconTemplate().compare(obj->getTemplate()->getName()) == 0
  1377. )
  1378. {
  1379. switchToContext( CB_CONTEXT_BEACON, draw );
  1380. }
  1381. else
  1382. {
  1383. switchToContext( CB_CONTEXT_NONE, draw );
  1384. }
  1385. //Check for a contain interface and a enemy relationship and reject that!
  1386. ContainModuleInterface *contain = obj->getContain();
  1387. if( contain && contain->getContainMax() > 0 )
  1388. {
  1389. const Player *otherPlayer = contain->getApparentControllingPlayer(ThePlayerList->getLocalPlayer());
  1390. if (!otherPlayer)
  1391. otherPlayer = obj->getControllingPlayer();
  1392. Player *player = ThePlayerList->getLocalPlayer();
  1393. if( !player || !otherPlayer )
  1394. {
  1395. //Sanity.
  1396. return;
  1397. }
  1398. Relationship relation = player->getRelationship( otherPlayer->getDefaultTeam() );
  1399. //Note: All following checks already account for the fact that this object
  1400. //isn't ours.
  1401. //The only case we can actually see a non-controlled controlbar is a neutral garrisonable structure.
  1402. if( !contain->isGarrisonable() || relation != NEUTRAL )
  1403. {
  1404. //Can't peek inside enemy/allied containers period!
  1405. return;
  1406. }
  1407. }
  1408. else
  1409. {
  1410. return;
  1411. }
  1412. }
  1413. //
  1414. // when we have multiple things selected, we will only display the common commands
  1415. // in the center command bar that can be displayed with multi-units selected
  1416. //
  1417. Drawable *drawToEvaluateFor = NULL;
  1418. Bool multiSelect = FALSE;
  1419. if( TheInGameUI->getSelectCount() > 1 )
  1420. {
  1421. // Attempt to isolate a Drawable here to evaluate
  1422. // The need arises when selected is an AngryMob,
  1423. // whose selection actually consists of varied units
  1424. // but is represented in the UI as a single unit,
  1425. // so we must isolate and evaluate only the Nexus
  1426. drawToEvaluateFor = TheGameClient->findDrawableByID( TheInGameUI->getSoloNexusSelectedDrawableID() ) ;
  1427. multiSelect = ( drawToEvaluateFor == NULL );
  1428. }
  1429. else // get the first and only drawble in the selection list
  1430. drawToEvaluateFor = selectedDrawables->front();
  1431. if( multiSelect )
  1432. {
  1433. switchToContext( CB_CONTEXT_MULTI_SELECT, NULL );
  1434. }
  1435. else if ( drawToEvaluateFor )// either we have exactly one drawable, or we have isolated one to evaluate for...
  1436. {
  1437. // get the first and only drawble in the selection list
  1438. //Drawable *draw = selectedDrawables->front();
  1439. // sanity
  1440. //if( draw == NULL )
  1441. // return;
  1442. // get object
  1443. Object *obj = drawToEvaluateFor->getObject();
  1444. if( obj == NULL )
  1445. return;
  1446. // we show no interface for objects being sold
  1447. if( BitTest( obj->getStatusBits(), OBJECT_STATUS_SOLD ) )
  1448. return;
  1449. static const NameKeyType key_OCLUpdate = NAMEKEY( "OCLUpdate" );
  1450. OCLUpdate *update = (OCLUpdate*)obj->findUpdateModule( key_OCLUpdate );
  1451. //
  1452. // a command center is context sensitive itself, if a side has *NOT* been chosen we display
  1453. // the side select interface for command centers only, but note how under construction is
  1454. // more important than anything
  1455. //
  1456. Bool contextSelected = FALSE;
  1457. if( BitTest( obj->getStatusBits(), OBJECT_STATUS_UNDER_CONSTRUCTION ) )
  1458. {
  1459. switchToContext( CB_CONTEXT_UNDER_CONSTRUCTION, drawToEvaluateFor );
  1460. contextSelected = TRUE;
  1461. } // end else if
  1462. // check for a regular switch to the appropriate context
  1463. if( contextSelected == FALSE )
  1464. {
  1465. ContainModuleInterface *cmi = obj->getContain();
  1466. if( cmi && cmi->isGarrisonable() && obj->getCommandSetString().isEmpty() )
  1467. {
  1468. //Kris: This is a convenient section to graft an inventory commandset for
  1469. //garrisoned troops. However, we only want to use this if we DON'T have
  1470. //a commandset defined. If we do, then trust that the commandset will
  1471. //handle it!
  1472. Player *localPlayer = ThePlayerList->getLocalPlayer();
  1473. Relationship relationship;
  1474. // we cannot select objects that are controlled by our enemies
  1475. relationship = localPlayer->getRelationship( obj->getTeam() );
  1476. if( obj->isLocallyControlled() == TRUE || relationship == NEUTRAL )
  1477. switchToContext( CB_CONTEXT_STRUCTURE_INVENTORY, drawToEvaluateFor );
  1478. } // end else if
  1479. else if( update )
  1480. {
  1481. switchToContext( CB_CONTEXT_OCL_TIMER, drawToEvaluateFor );
  1482. }
  1483. else if( obj->getCommandSetString().isEmpty() == FALSE )
  1484. {
  1485. switchToContext( CB_CONTEXT_COMMAND, drawToEvaluateFor );
  1486. } // end else if
  1487. else if (obj->getControllingPlayer()->getPlayerTemplate()->getBeaconTemplate().compare(obj->getTemplate()->getName()) == 0)
  1488. {
  1489. switchToContext( CB_CONTEXT_BEACON, drawToEvaluateFor );
  1490. }
  1491. else
  1492. switchToContext( CB_CONTEXT_NONE, drawToEvaluateFor );
  1493. } // end else
  1494. } // end else
  1495. } // end evaluateContextUI
  1496. //-------------------------------------------------------------------------------------------------
  1497. /** Find a command button of the given name if present */
  1498. //-------------------------------------------------------------------------------------------------
  1499. CommandButton *ControlBar::findNonConstCommandButton( const AsciiString& name )
  1500. {
  1501. for( const CommandButton *command = m_commandButtons; command; command = command->getNext() )
  1502. if( command->getName() == name )
  1503. return const_cast<CommandButton*>((const CommandButton*)command->getFinalOverride());
  1504. return NULL; // not found
  1505. } // end findCommandButton
  1506. //-------------------------------------------------------------------------------------------------
  1507. /** Allocate a new command button, assign name, and tie to list */
  1508. //-------------------------------------------------------------------------------------------------
  1509. CommandButton *ControlBar::newCommandButton( const AsciiString& name )
  1510. {
  1511. CommandButton *newButton;
  1512. // allocate new button
  1513. newButton = newInstance(CommandButton);
  1514. // assign name
  1515. newButton->setName(name);
  1516. // link to list
  1517. newButton->friend_addToList(&m_commandButtons);
  1518. // return the new button
  1519. return newButton;
  1520. } // end newCommandButton
  1521. //-------------------------------------------------------------------------------------------------
  1522. //-------------------------------------------------------------------------------------------------
  1523. CommandButton *ControlBar::newCommandButtonOverride( CommandButton *buttonToOverride )
  1524. {
  1525. if (!buttonToOverride) {
  1526. return NULL;
  1527. }
  1528. CommandButton *newOverride;
  1529. // allocate new button
  1530. newOverride = newInstance(CommandButton);
  1531. *newOverride = *buttonToOverride;
  1532. newOverride->markAsOverride();
  1533. buttonToOverride->setNextOverride(newOverride);
  1534. return newOverride;
  1535. }
  1536. //-------------------------------------------------------------------------------------------------
  1537. /** Parse a command set */
  1538. //-------------------------------------------------------------------------------------------------
  1539. /*static*/ void ControlBar::parseCommandSetDefinition( INI *ini )
  1540. {
  1541. AsciiString name;
  1542. CommandSet *commandSet;
  1543. // read the name
  1544. const char* c = ini->getNextToken();
  1545. name.set( c );
  1546. // find existing item if present
  1547. commandSet = TheControlBar->findNonConstCommandSet( name );
  1548. if( commandSet == NULL )
  1549. {
  1550. // allocate a new item
  1551. commandSet = TheControlBar->newCommandSet( name );
  1552. if (ini->getLoadType() == INI_LOAD_CREATE_OVERRIDES) {
  1553. commandSet->markAsOverride();
  1554. }
  1555. } // end if
  1556. else if( ini->getLoadType() != INI_LOAD_CREATE_OVERRIDES )
  1557. {
  1558. //Holy crap, this sucks to debug!!!
  1559. //If you have two different command sets, the previous
  1560. //code would simply allow you to define multiple command set
  1561. //with the same name, and just nuke the old button with the new one.
  1562. //So, I (KM) have added this assert to notify in case of two same-name
  1563. //command set.
  1564. DEBUG_CRASH(( "[LINE: %d in '%s'] Duplicate commandset %s found!", ini->getLineNum(), ini->getFilename().str(), name.str() ));
  1565. throw INI_INVALID_DATA;
  1566. //@todo SUPPORT OVERRIDES -- JM
  1567. } else {
  1568. commandSet = TheControlBar->newCommandSetOverride(commandSet);
  1569. }
  1570. // sanity
  1571. DEBUG_ASSERTCRASH( commandSet, ("parseCommandSetDefinition: Unable to allocate set '%s'\n", name.str()) );
  1572. // parse the ini definition
  1573. ini->initFromINI( commandSet, commandSet->friend_getFieldParse() );
  1574. } // end parseCommandSetDefinition
  1575. //-------------------------------------------------------------------------------------------------
  1576. /** Find existing command set by name */
  1577. //-------------------------------------------------------------------------------------------------
  1578. CommandSet* ControlBar::findNonConstCommandSet( const AsciiString& name )
  1579. {
  1580. CommandSet* set;
  1581. for( set = m_commandSets; set != NULL; set = set->friend_getNext() )
  1582. if( set->getName() == name )
  1583. return const_cast<CommandSet*>((const CommandSet *) set);
  1584. return NULL; // set not found
  1585. }
  1586. //-------------------------------------------------------------------------------------------------
  1587. /** find existing command button if present */
  1588. //-------------------------------------------------------------------------------------------------
  1589. const CommandButton *ControlBar::findCommandButton( const AsciiString& name )
  1590. {
  1591. CommandButton *btn = findNonConstCommandButton(name);
  1592. btn = (CommandButton *)btn->friend_getFinalOverride();
  1593. return btn;
  1594. }
  1595. //-------------------------------------------------------------------------------------------------
  1596. /** Find existing command set by name */
  1597. //-------------------------------------------------------------------------------------------------
  1598. const CommandSet *ControlBar::findCommandSet( const AsciiString& name )
  1599. {
  1600. CommandSet *set = findNonConstCommandSet(name);
  1601. if (set)
  1602. set = (CommandSet*)set->friend_getFinalOverride();
  1603. return set;
  1604. }
  1605. //-------------------------------------------------------------------------------------------------
  1606. /** Allocate a new command set, link to list, initialize to default, and return it */
  1607. //-------------------------------------------------------------------------------------------------
  1608. CommandSet *ControlBar::newCommandSet( const AsciiString& name )
  1609. {
  1610. // allocate a new set
  1611. CommandSet* set = newInstance(CommandSet)(name);
  1612. // add it to the list.
  1613. set->friend_addToList(&m_commandSets);
  1614. // return the newly created set
  1615. return set;
  1616. } // end newCommandSet
  1617. //-------------------------------------------------------------------------------------------------
  1618. /** Create an overridden command set. */
  1619. //-------------------------------------------------------------------------------------------------
  1620. CommandSet *ControlBar::newCommandSetOverride( CommandSet *setToOverride )
  1621. {
  1622. if (!setToOverride) {
  1623. return NULL;
  1624. }
  1625. // allocate a new set
  1626. CommandSet* set = newInstance(CommandSet)(setToOverride->getName());
  1627. // it's an override; DON'T add it to the main list.
  1628. // !!! DO NOT DO THIS !!! -- > set->friend_addToList(&m_commandSets); <-- !!! DO NOT DO THIS !!!
  1629. *set = *setToOverride;
  1630. set->markAsOverride();
  1631. setToOverride->setNextOverride(set);
  1632. return set;
  1633. }
  1634. //-------------------------------------------------------------------------------------------------
  1635. /** Process a button click for the context sensitive GUI */
  1636. //-------------------------------------------------------------------------------------------------
  1637. CBCommandStatus ControlBar::processContextSensitiveButtonClick( GameWindow *button,
  1638. GadgetGameMessage gadgetMessage )
  1639. {
  1640. // call command processing method
  1641. return processCommandUI( button, gadgetMessage );
  1642. } // end processContextSensitiveButtonClick
  1643. //-------------------------------------------------------------------------------------------------
  1644. /** Process a button click for the context sensitive GUI */
  1645. //-------------------------------------------------------------------------------------------------
  1646. CBCommandStatus ControlBar::processContextSensitiveButtonTransition( GameWindow *button,
  1647. GadgetGameMessage gadgetMessage )
  1648. {
  1649. // call command processing method
  1650. return processCommandTransitionUI( button, gadgetMessage );
  1651. } // end processContextSensitiveButtonClick
  1652. //-------------------------------------------------------------------------------------------------
  1653. /** Switch the user interface to the new context specified and fill out any of the
  1654. * art and/or buttons that we need to for the new context using data from the object
  1655. * passed in */
  1656. //-------------------------------------------------------------------------------------------------
  1657. void ControlBar::switchToContext( ControlBarContext context, Drawable *draw )
  1658. {
  1659. // restore the right hud to a plain window
  1660. setPortraitByObject( NULL );
  1661. Object *obj = draw ? draw->getObject() : NULL;
  1662. setPortraitByObject( obj );
  1663. // if we're switching context, we have to repopulate the hotkey manager
  1664. if(TheHotKeyManager)
  1665. TheHotKeyManager->reset();
  1666. // ... and also remove any radius cursor that is active.
  1667. TheInGameUI->setRadiusCursorNone();
  1668. // save a pointer for the currently selected drawable
  1669. m_currentSelectedDrawable = draw;
  1670. if (IsInGameChatActive() == FALSE && TheGameLogic && !TheGameLogic->isInShellGame()) {
  1671. TheWindowManager->winSetFocus( NULL );
  1672. }
  1673. // hide/un-hide the appropriate windows for the context
  1674. switch( context )
  1675. {
  1676. //-------------------------------------------------------------------------------------------------
  1677. case CB_CONTEXT_NONE:
  1678. {
  1679. // show or hide the right window groups
  1680. //m_contextParent[ CP_PURCHASE_SCIENCE ]->winHide( TRUE );
  1681. m_contextParent[ CP_COMMAND ]->winHide( TRUE );
  1682. m_contextParent[ CP_BUILD_QUEUE ]->winHide( TRUE );
  1683. m_contextParent[ CP_BEACON ]->winHide( TRUE );
  1684. m_contextParent[ CP_UNDER_CONSTRUCTION ]->winHide( TRUE );
  1685. m_contextParent[ CP_OCL_TIMER ]->winHide( TRUE );
  1686. m_contextParent[ CP_OBSERVER_INFO ]->winHide( TRUE );
  1687. m_contextParent[ CP_OBSERVER_LIST ]->winHide( TRUE );
  1688. //Clear any potentially flashing buttons!
  1689. for( int i = 0; i < MAX_COMMANDS_PER_SET; i++ )
  1690. {
  1691. m_commandWindows[ i ]->winClearStatus( WIN_STATUS_FLASHING );
  1692. }
  1693. // if there is a current selected drawable then we wil display a selection portrait if present
  1694. if( draw )
  1695. {
  1696. //Get the current thing template.
  1697. const ThingTemplate *thing = draw->getTemplate();
  1698. //Special case -- if we are a GLA hole, then get the rebuild building template
  1699. Object *obj = draw->getObject();
  1700. if( obj && obj->isKindOf( KINDOF_REBUILD_HOLE ) )
  1701. {
  1702. RebuildHoleBehaviorInterface *rhbi = RebuildHoleBehavior::getRebuildHoleBehaviorInterfaceFromObject( obj );
  1703. if( rhbi )
  1704. {
  1705. thing = rhbi->getRebuildTemplate();
  1706. }
  1707. }
  1708. //Set the correct portrait.
  1709. setPortraitByObject( obj );
  1710. }
  1711. // do not show any rally point marker
  1712. showRallyPoint( NULL );
  1713. break;
  1714. } // end none
  1715. //---------------------------------------------------------------------------------------------
  1716. case CB_CONTEXT_COMMAND:
  1717. {
  1718. // show or hide the right window groups
  1719. //m_contextParent[ CP_PURCHASE_SCIENCE ]->winHide( TRUE );
  1720. m_contextParent[ CP_COMMAND ]->winHide( FALSE );
  1721. m_contextParent[ CP_BUILD_QUEUE ]->winHide( TRUE );
  1722. m_contextParent[ CP_BEACON ]->winHide( TRUE );
  1723. m_contextParent[ CP_UNDER_CONSTRUCTION ]->winHide( TRUE );
  1724. m_contextParent[ CP_OCL_TIMER ]->winHide( TRUE );
  1725. m_contextParent[ CP_OBSERVER_INFO ]->winHide( TRUE );
  1726. m_contextParent[ CP_OBSERVER_LIST ]->winHide( TRUE );
  1727. // fill the specific UI info
  1728. populateCommand( draw->getObject() );
  1729. //
  1730. // for objects that are able to create units, we show a build queue if we actually
  1731. // actually have something in production, otherwise we show the selection portrait
  1732. //
  1733. if( obj )
  1734. {
  1735. ProductionUpdateInterface *pu = obj->getProductionUpdateInterface();
  1736. if( pu && pu->firstProduction() != NULL )
  1737. {
  1738. m_contextParent[ CP_BUILD_QUEUE ]->winHide( FALSE );
  1739. populateBuildQueue( obj );
  1740. setPortraitByObject( NULL );
  1741. } // end if
  1742. else
  1743. {
  1744. setPortraitByObject( obj );
  1745. }
  1746. } // end if
  1747. break;
  1748. } // end command
  1749. //---------------------------------------------------------------------------------------------
  1750. case CB_CONTEXT_STRUCTURE_INVENTORY:
  1751. {
  1752. // show or hide the right window groups
  1753. //m_contextParent[ CP_PURCHASE_SCIENCE ]->winHide( TRUE );
  1754. m_contextParent[ CP_COMMAND ]->winHide( FALSE );
  1755. m_contextParent[ CP_BUILD_QUEUE ]->winHide( TRUE );
  1756. m_contextParent[ CP_BEACON ]->winHide( TRUE );
  1757. m_contextParent[ CP_UNDER_CONSTRUCTION ]->winHide( TRUE );
  1758. m_contextParent[ CP_OCL_TIMER ]->winHide( TRUE );
  1759. m_contextParent[ CP_OBSERVER_INFO ]->winHide( TRUE );
  1760. m_contextParent[ CP_OBSERVER_LIST ]->winHide( TRUE );
  1761. // fill the specific UI info
  1762. populateStructureInventory( draw->getObject() );
  1763. break;
  1764. } // end inventory
  1765. //---------------------------------------------------------------------------------------------
  1766. case CB_CONTEXT_BEACON:
  1767. {
  1768. // show or hide the right window groups
  1769. //m_contextParent[ CP_PURCHASE_SCIENCE ]->winHide( TRUE );
  1770. m_contextParent[ CP_COMMAND ]->winHide( TRUE );
  1771. m_contextParent[ CP_BUILD_QUEUE ]->winHide( TRUE );
  1772. m_contextParent[ CP_BEACON ]->winHide( FALSE );
  1773. m_contextParent[ CP_UNDER_CONSTRUCTION ]->winHide( TRUE );
  1774. m_contextParent[ CP_OCL_TIMER ]->winHide( TRUE );
  1775. m_contextParent[ CP_OBSERVER_INFO ]->winHide( TRUE );
  1776. m_contextParent[ CP_OBSERVER_LIST ]->winHide( TRUE );
  1777. // fill the specific UI info
  1778. populateBeacon( draw->getObject() );
  1779. break;
  1780. } // end beacon
  1781. //---------------------------------------------------------------------------------------------
  1782. case CB_CONTEXT_UNDER_CONSTRUCTION:
  1783. {
  1784. // show or hide the right window groups
  1785. //m_contextParent[ CP_PURCHASE_SCIENCE ]->winHide( TRUE );
  1786. m_contextParent[ CP_COMMAND ]->winHide( TRUE );
  1787. m_contextParent[ CP_BUILD_QUEUE ]->winHide( TRUE );
  1788. m_contextParent[ CP_BEACON ]->winHide( TRUE );
  1789. m_contextParent[ CP_UNDER_CONSTRUCTION ]->winHide( FALSE );
  1790. m_contextParent[ CP_OCL_TIMER ]->winHide( TRUE );
  1791. m_contextParent[ CP_OBSERVER_INFO ]->winHide( TRUE );
  1792. m_contextParent[ CP_OBSERVER_LIST ]->winHide( TRUE );
  1793. // fill the specific UI info
  1794. populateUnderConstruction( draw->getObject() );
  1795. break;
  1796. } // end under construction
  1797. //---------------------------------------------------------------------------------------------
  1798. case CB_CONTEXT_OCL_TIMER:
  1799. {
  1800. // show or hide the right window groups
  1801. // m_contextParent[ CP_PURCHASE_SCIENCE ]->winHide( TRUE );
  1802. m_contextParent[ CP_COMMAND ]->winHide( TRUE );
  1803. m_contextParent[ CP_BUILD_QUEUE ]->winHide( TRUE );
  1804. m_contextParent[ CP_BEACON ]->winHide( TRUE );
  1805. m_contextParent[ CP_UNDER_CONSTRUCTION ]->winHide( TRUE );
  1806. m_contextParent[ CP_OCL_TIMER ]->winHide( FALSE );
  1807. m_contextParent[ CP_OBSERVER_INFO ]->winHide( TRUE );
  1808. m_contextParent[ CP_OBSERVER_LIST ]->winHide( TRUE );
  1809. // fill the specific UI info
  1810. populateOCLTimer( draw->getObject() );
  1811. break;
  1812. } // end under construction
  1813. //---------------------------------------------------------------------------------------------
  1814. case CB_CONTEXT_MULTI_SELECT:
  1815. {
  1816. // show or hide the right window groups
  1817. // m_contextParent[ CP_PURCHASE_SCIENCE ]->winHide( TRUE );
  1818. m_contextParent[ CP_COMMAND ]->winHide( FALSE ); // multi select shows common commands
  1819. m_contextParent[ CP_BUILD_QUEUE ]->winHide( TRUE );
  1820. m_contextParent[ CP_BEACON ]->winHide( TRUE );
  1821. m_contextParent[ CP_UNDER_CONSTRUCTION ]->winHide( TRUE );
  1822. m_contextParent[ CP_OCL_TIMER ]->winHide( TRUE );
  1823. m_contextParent[ CP_OBSERVER_INFO ]->winHide( TRUE );
  1824. m_contextParent[ CP_OBSERVER_LIST ]->winHide( TRUE );
  1825. // fill the specific UI info
  1826. populateMultiSelect();
  1827. break;
  1828. } // end multi select
  1829. case CB_CONTEXT_OBSERVER_LIST:
  1830. {
  1831. // show or hide the right window groups
  1832. // m_contextParent[ CP_PURCHASE_SCIENCE ]->winHide( TRUE );
  1833. m_contextParent[ CP_COMMAND ]->winHide( TRUE );
  1834. m_contextParent[ CP_BUILD_QUEUE ]->winHide( TRUE );
  1835. m_contextParent[ CP_BEACON ]->winHide( TRUE );
  1836. m_contextParent[ CP_UNDER_CONSTRUCTION ]->winHide( TRUE );
  1837. m_contextParent[ CP_OCL_TIMER ]->winHide( TRUE );
  1838. m_contextParent[ CP_OBSERVER_INFO ]->winHide( TRUE );
  1839. m_contextParent[ CP_OBSERVER_LIST ]->winHide( FALSE );
  1840. // fill the specific UI info
  1841. populateObserverList();
  1842. break;
  1843. } // end multi select
  1844. //---------------------------------------------------------------------------------------------
  1845. default:
  1846. {
  1847. DEBUG_ASSERTCRASH( 0, ("ControlBar::switchToContext, unknown context '%d'\n", context) );
  1848. break;
  1849. } // end default
  1850. } // end switch
  1851. // save our context
  1852. m_currContext = context;
  1853. } // end switchToContext
  1854. void ControlBar::setCommandBarBorder( GameWindow *button, CommandButtonMappedBorderType type)
  1855. {
  1856. if(!button)
  1857. return;
  1858. switch( type )
  1859. {
  1860. case COMMAND_BUTTON_BORDER_BUILD:
  1861. {
  1862. GadgetButtonSetBorder(button, m_commandButtonBorderBuildColor);
  1863. break;
  1864. }
  1865. //-------------------------------------------------------------------------------------------------
  1866. case COMMAND_BUTTON_BORDER_UPGRADE:
  1867. {
  1868. GadgetButtonSetBorder(button, m_commandButtonBorderUpgradeColor );
  1869. break;
  1870. }
  1871. //-------------------------------------------------------------------------------------------------
  1872. case COMMAND_BUTTON_BORDER_ACTION:
  1873. {
  1874. GadgetButtonSetBorder(button, m_commandButtonBorderActionColor);
  1875. break;
  1876. }
  1877. //-------------------------------------------------------------------------------------------------
  1878. case COMMAND_BUTTON_BORDER_SYSTEM:
  1879. {
  1880. GadgetButtonSetBorder(button, m_commandButtonBorderSystemColor);
  1881. break;
  1882. }
  1883. //-------------------------------------------------------------------------------------------------
  1884. case COMMAND_BUTTON_BORDER_NONE:
  1885. default:
  1886. GadgetButtonSetBorder(button, GAME_COLOR_UNDEFINED, FALSE);
  1887. }
  1888. }
  1889. //-------------------------------------------------------------------------------------------------
  1890. /** Set the command data into the control */
  1891. //-------------------------------------------------------------------------------------------------
  1892. void ControlBar::setControlCommand( GameWindow *button, const CommandButton *commandButton )
  1893. {
  1894. // the window must be a gadget button
  1895. if( button->winGetInputFunc() != GadgetPushButtonInput )
  1896. {
  1897. DEBUG_ASSERTCRASH( 0, ("setControlCommand: Window is not a button\n") );
  1898. return;
  1899. } // end if
  1900. // sanity
  1901. if( commandButton == NULL )
  1902. {
  1903. DEBUG_ASSERTCRASH( 0, ("setControlCommand: NULL commandButton passed in\n") );
  1904. return;
  1905. } // end if
  1906. //
  1907. // set the button gadget control to be a normal button or a check like button if
  1908. // the command says it needs one
  1909. //
  1910. if( BitTest( commandButton->getOptions(), CHECK_LIKE ))
  1911. GadgetButtonEnableCheckLike( button, TRUE, FALSE );
  1912. else
  1913. GadgetButtonEnableCheckLike( button, FALSE, FALSE );
  1914. //
  1915. // set the imagry ... note that for 99% of the command buttons it's sufficient to specify
  1916. // only the disabled, enabled, hilite, and hilite pushed images. For push-like buttons
  1917. // we actually utilize all the state available to a GameWindow. We will replicate the
  1918. // hilite pushed image to be the enabled pushed image ... and we will also replicate
  1919. // the disabled image to be the disabled pushed image. For complete control over all
  1920. // the states of these buttons we would add additional lines to the INI for a command
  1921. // button and store those additional images in the command button
  1922. //
  1923. if( commandButton->getButtonImage() )
  1924. GadgetButtonSetEnabledImage( button, commandButton->getButtonImage() );
  1925. //if( commandButton->getDisabledImage() )
  1926. //{
  1927. // GadgetButtonSetDisabledImage( button, commandButton->getDisabledImage() );
  1928. // GadgetButtonSetDisabledSelectedImage( button, commandButton->getDisabledImage() );
  1929. //} //end if
  1930. //if( commandButton->getHiliteImage() )
  1931. // GadgetButtonSetHiliteImage( button, commandButton->getHiliteImage() );
  1932. //if( commandButton->getPushedImage() )
  1933. //{
  1934. // GadgetButtonSetHiliteSelectedImage( button, commandButton->getPushedImage() );
  1935. // GadgetButtonSetEnabledSelectedImage( button, commandButton->getPushedImage() );
  1936. //} // end if
  1937. // set the text
  1938. if( commandButton->getTextLabel().isEmpty() == FALSE || !commandButton->getScienceVec().empty())
  1939. {
  1940. button->winSetTooltipFunc(commandButtonTooltip);
  1941. }
  1942. else
  1943. GadgetButtonSetText( button, UnicodeString( L"" ) );
  1944. // save the command in the user data of the window
  1945. GadgetButtonSetData(button, (void*)commandButton);
  1946. //button->winSetUserData( commandButton );
  1947. setCommandBarBorder(button, commandButton->getCommandButtonMappedBorderType());
  1948. if (TheHotKeyManager)
  1949. {
  1950. AsciiString hotKey = TheHotKeyManager->searchHotKey(commandButton->getTextLabel());
  1951. if(hotKey.isNotEmpty())
  1952. TheHotKeyManager->addHotKey(button, hotKey);
  1953. }
  1954. GadgetButtonSetAltSound(button, "GUICommandBarClick");
  1955. } // end setControlCommand
  1956. //-------------------------------------------------------------------------------------------------
  1957. void CommandButton::cacheButtonImage()
  1958. {
  1959. if (!TheMappedImageCollection) {
  1960. return;
  1961. }
  1962. if( m_buttonImageName.isNotEmpty() )
  1963. {
  1964. m_buttonImage = TheMappedImageCollection->findImageByName( m_buttonImageName );
  1965. DEBUG_ASSERTCRASH( m_buttonImage, ("CommandButton: %s is looking for button image %s but can't find it. Skipping...", m_name.str(), m_buttonImageName.str() ) );
  1966. m_buttonImageName.clear(); // we're done with this, so nuke it
  1967. }
  1968. }
  1969. //-------------------------------------------------------------------------------------------------
  1970. /** post process step, after all commands and command sets are loaded */
  1971. //-------------------------------------------------------------------------------------------------
  1972. void ControlBar::postProcessCommands( void )
  1973. {
  1974. for ( CommandButton *button = m_commandButtons; button; button = button->friend_getNext() )
  1975. {
  1976. button->cacheButtonImage();
  1977. }
  1978. }
  1979. //-------------------------------------------------------------------------------------------------
  1980. /** set the command for the button identified by the window name
  1981. * NOTE that parent may be NULL, it only helps to speed up the search for a particular
  1982. * window ID */
  1983. //-------------------------------------------------------------------------------------------------
  1984. void ControlBar::setControlCommand( const AsciiString& buttonWindowName, GameWindow *parent,
  1985. const CommandButton *commandButton )
  1986. {
  1987. UnsignedInt winID = TheNameKeyGenerator->nameToKey( buttonWindowName );
  1988. GameWindow *win = TheWindowManager->winGetWindowFromId( parent, winID );
  1989. if( win == NULL )
  1990. {
  1991. DEBUG_ASSERTCRASH( 0, ("setControlCommand: Unable to find window '%s'\n", buttonWindowName.str()) );
  1992. return;
  1993. } // end if
  1994. // call the workhorse
  1995. setControlCommand( win, commandButton );
  1996. } // end setControlCommand
  1997. //-------------------------------------------------------------------------------------------------
  1998. /** show/hide the portrait window image */
  1999. //-------------------------------------------------------------------------------------------------
  2000. void ControlBar::setPortraitByImage( const Image *image )
  2001. {
  2002. if( image )
  2003. {
  2004. m_rightHUDUnitSelectParent->winHide(FALSE);
  2005. m_rightHUDCameoWindow->winSetEnabledImage( 0, image );
  2006. //m_rightHUDWindow->winSetEnabledImage( 0, image );
  2007. m_rightHUDWindow->winClearStatus( WIN_STATUS_IMAGE );
  2008. m_rightHUDCameoWindow->winSetStatus( WIN_STATUS_IMAGE );
  2009. for(Int i = 0; i < MAX_UPGRADE_CAMEO_UPGRADES; ++i)
  2010. m_rightHUDUpgradeCameos[i]->winHide(TRUE);
  2011. } // end if
  2012. else
  2013. {
  2014. m_rightHUDWindow->winSetStatus( WIN_STATUS_IMAGE );
  2015. m_rightHUDCameoWindow->winClearStatus( WIN_STATUS_IMAGE );
  2016. m_rightHUDUnitSelectParent->winHide(TRUE);
  2017. for(Int i = 0; i < MAX_UPGRADE_CAMEO_UPGRADES; ++i)
  2018. m_rightHUDUpgradeCameos[i]->winHide(TRUE);
  2019. //m_rightHUDWindow->winSetEnabledImage( 0, image );
  2020. //m_rightHUDWindow->winSetStatus( WIN_STATUS_IMAGE );
  2021. }
  2022. } // end setPortraitByImage
  2023. //-------------------------------------------------------------------------------------------------
  2024. /** show/hide the portrait image by object. We like to use this method as opposed to the
  2025. * plain image one above so that we can build more intelligence into what portrait to
  2026. * show for an object given its current state or object type */
  2027. //-------------------------------------------------------------------------------------------------
  2028. void ControlBar::setPortraitByObject( Object *obj )
  2029. {
  2030. if( obj )
  2031. {
  2032. if( obj->isKindOf( KINDOF_SHOW_PORTRAIT_WHEN_CONTROLLED ) && !obj->isLocallyControlled() )
  2033. {
  2034. //Handles civ vehicles without terrorists in them
  2035. setPortraitByObject( NULL );
  2036. return;
  2037. }
  2038. const ThingTemplate *thing = obj->getTemplate();
  2039. Player *player = obj->getControllingPlayer();
  2040. //If we have an enemy stealth disguised unit, swap portraits!
  2041. Drawable *draw = obj->getDrawable();
  2042. if( draw && draw->getStealthLook() == STEALTHLOOK_DISGUISED_ENEMY )
  2043. {
  2044. thing = draw->getTemplate();
  2045. if( thing->isKindOf( KINDOF_SHOW_PORTRAIT_WHEN_CONTROLLED ) )
  2046. {
  2047. //If a bomb truck disguises as a civ vehicle, don't use it's portrait (or else you'll see the terrorist).
  2048. setPortraitByObject( NULL );
  2049. return;
  2050. }
  2051. static NameKeyType key_StealthUpdate = NAMEKEY("StealthUpdate");
  2052. StealthUpdate* stealth = (StealthUpdate *)obj->findUpdateModule(key_StealthUpdate);
  2053. if( stealth && stealth->isDisguised() )
  2054. {
  2055. //Fake player upgrades too!
  2056. player = ThePlayerList->getNthPlayer( stealth->getDisguisedPlayerIndex() );
  2057. }
  2058. }
  2059. const Image* portrait = thing->getSelectedPortraitImage();
  2060. m_rightHUDUnitSelectParent->winHide(FALSE);
  2061. // enable the window window as an image window and set the image
  2062. m_rightHUDCameoWindow->winSetEnabledImage( 0, portrait );
  2063. //Display the veterancy rank of the object on the portrait.
  2064. const Image *image = calculateVeterancyOverlayForObject( obj );
  2065. GadgetButtonDrawOverlayImage( m_rightHUDCameoWindow, image );
  2066. //m_rightHUDWindow->winSetEnabledImage( 0, portrait );
  2067. m_rightHUDWindow->winClearStatus( WIN_STATUS_IMAGE );
  2068. m_rightHUDCameoWindow->winSetStatus( WIN_STATUS_IMAGE );
  2069. for(Int i = 0; i < MAX_UPGRADE_CAMEO_UPGRADES; ++i)
  2070. {
  2071. AsciiString upgradeName = thing->getUpgradeCameoName(i);
  2072. if(upgradeName.isEmpty())
  2073. {
  2074. m_rightHUDUpgradeCameos[i]->winHide(TRUE);
  2075. continue;
  2076. }
  2077. const UpgradeTemplate *ut = TheUpgradeCenter->findUpgrade(upgradeName);
  2078. if(!ut)
  2079. {
  2080. m_rightHUDUpgradeCameos[i]->winHide(TRUE);
  2081. continue;
  2082. }
  2083. m_rightHUDUpgradeCameos[i]->winHide(FALSE);
  2084. m_rightHUDUpgradeCameos[i]->winSetEnabledImage( 0, ut->getButtonImage() );
  2085. if( obj->hasUpgrade(ut) )
  2086. {
  2087. //Object level upgrades
  2088. m_rightHUDUpgradeCameos[i]->winEnable( TRUE );
  2089. }
  2090. else if( player && player->hasUpgradeComplete( ut ) )
  2091. {
  2092. //Player level upgrades
  2093. m_rightHUDUpgradeCameos[i]->winEnable( TRUE );
  2094. }
  2095. else
  2096. {
  2097. //Failure
  2098. m_rightHUDUpgradeCameos[i]->winEnable( FALSE );
  2099. }
  2100. }
  2101. } // end if
  2102. else
  2103. {
  2104. m_rightHUDUnitSelectParent->winHide(TRUE);
  2105. m_rightHUDWindow->winSetStatus( WIN_STATUS_IMAGE );
  2106. m_rightHUDCameoWindow->winClearStatus( WIN_STATUS_IMAGE );
  2107. for(Int i = 0; i < MAX_UPGRADE_CAMEO_UPGRADES; ++i)
  2108. m_rightHUDUpgradeCameos[i]->winHide(TRUE);
  2109. //Clear any overlay the portrait had on it.
  2110. GadgetButtonDrawOverlayImage( m_rightHUDCameoWindow, NULL );
  2111. }
  2112. } // end setPortraitByObject
  2113. // ------------------------------------------------------------------------------------------------
  2114. /** Show a rally point marker at the world location specified. If no location is specified
  2115. * any marker that we might have visible is hidden */
  2116. // ------------------------------------------------------------------------------------------------
  2117. void ControlBar::showRallyPoint( const Coord3D *loc )
  2118. {
  2119. // if loc is NULL, destroy any rally point drawble we have shown
  2120. if( loc == NULL )
  2121. {
  2122. // destroy rally point drawable if present
  2123. if( m_rallyPointDrawableID != INVALID_DRAWABLE_ID )
  2124. TheGameClient->destroyDrawable( TheGameClient->findDrawableByID( m_rallyPointDrawableID ) );
  2125. m_rallyPointDrawableID = INVALID_DRAWABLE_ID;
  2126. } // end if
  2127. else
  2128. {
  2129. Drawable *marker = NULL;
  2130. // create a rally point drawble if necessary
  2131. if( m_rallyPointDrawableID == INVALID_DRAWABLE_ID )
  2132. {
  2133. const ThingTemplate* ttn = TheThingFactory->findTemplate("RallyPointMarker");
  2134. marker = TheThingFactory->newDrawable( ttn );
  2135. DEBUG_ASSERTCRASH( marker, ("showRallyPoint: Unable to create rally point drawable\n") );
  2136. if (marker)
  2137. {
  2138. marker->setDrawableStatus(DRAWABLE_STATUS_NO_SAVE);
  2139. m_rallyPointDrawableID = marker->getID();
  2140. }
  2141. } // end if
  2142. else
  2143. marker = TheGameClient->findDrawableByID( m_rallyPointDrawableID );
  2144. // sanity
  2145. DEBUG_ASSERTCRASH( marker, ("showRallyPoint: No rally point marker found\n" ) );
  2146. // set the position of the rally point drawble to the position passed in
  2147. marker->setPosition( loc );
  2148. marker->setOrientation( TheGlobalData->m_downwindAngle );//To blow down wind -- ML
  2149. // set the marker colors to that of the local player
  2150. Player *player = ThePlayerList->getLocalPlayer();
  2151. if (TheGlobalData->m_timeOfDay == TIME_OF_DAY_NIGHT)
  2152. marker->setIndicatorColor( player->getPlayerNightColor() );
  2153. else
  2154. marker->setIndicatorColor( player->getPlayerColor() );
  2155. } // end else
  2156. } // end showRallyPoint
  2157. // ------------------------------------------------------------------------------------------------
  2158. /** Show a rally point marker at the world location specified. If no location is specified
  2159. * any marker that we might have visible is hidden */
  2160. // ------------------------------------------------------------------------------------------------
  2161. void ControlBar::setControlBarSchemeByPlayer(Player *p)
  2162. {
  2163. if(m_controlBarSchemeManager)
  2164. m_controlBarSchemeManager->setControlBarSchemeByPlayer(p);
  2165. static NameKeyType buttonPlaceBeaconID = NAMEKEY( "ControlBar.wnd:ButtonPlaceBeacon" );
  2166. static NameKeyType buttonIdleWorkerID = NAMEKEY("ControlBar.wnd:ButtonIdleWorker");
  2167. static NameKeyType buttonGeneralID = NAMEKEY("ControlBar.wnd:ButtonGeneral");
  2168. GameWindow *buttonPlaceBeacon = TheWindowManager->winGetWindowFromId( NULL, buttonPlaceBeaconID );
  2169. GameWindow *buttonIdleWorker = TheWindowManager->winGetWindowFromId( NULL, buttonIdleWorkerID );
  2170. GameWindow *buttonGeneral = TheWindowManager->winGetWindowFromId( NULL, buttonGeneralID );
  2171. if( !p->isPlayerActive() )
  2172. {
  2173. m_isObserverCommandBar = TRUE;
  2174. switchToContext( CB_CONTEXT_OBSERVER_LIST, NULL );
  2175. DEBUG_LOG(("We're loading the Observer Command Bar\n"));
  2176. if (buttonPlaceBeacon)
  2177. buttonPlaceBeacon->winHide(TRUE);
  2178. if (buttonIdleWorker)
  2179. buttonIdleWorker->winHide(TRUE);
  2180. if (buttonGeneral)
  2181. buttonGeneral->winEnable(FALSE);
  2182. }
  2183. else
  2184. {
  2185. switchToContext( CB_CONTEXT_NONE, NULL );
  2186. m_isObserverCommandBar = FALSE;
  2187. if (buttonPlaceBeacon)
  2188. buttonPlaceBeacon->winHide(
  2189. (TheGameLogic->getGameMode() != GAME_LAN && TheGameLogic->getGameMode() != GAME_INTERNET) ||
  2190. !TheGameInfo->isMultiPlayer());
  2191. if (buttonIdleWorker)
  2192. buttonIdleWorker->winHide(FALSE);
  2193. if (buttonGeneral)
  2194. {
  2195. buttonGeneral->winHide(FALSE);
  2196. buttonGeneral->winEnable(TRUE);
  2197. }
  2198. }
  2199. switchControlBarStage(CONTROL_BAR_STAGE_DEFAULT);
  2200. }
  2201. void ControlBar::setControlBarSchemeByPlayerTemplate( const PlayerTemplate *pt)
  2202. {
  2203. if(m_controlBarSchemeManager)
  2204. m_controlBarSchemeManager->setControlBarSchemeByPlayerTemplate(pt);
  2205. static NameKeyType buttonPlaceBeaconID = NAMEKEY( "ControlBar.wnd:ButtonPlaceBeacon" );
  2206. static NameKeyType buttonIdleWorkerID = NAMEKEY("ControlBar.wnd:ButtonIdleWorker");
  2207. static NameKeyType buttonGeneralID = NAMEKEY("ControlBar.wnd:ButtonGeneral");
  2208. GameWindow *buttonPlaceBeacon = TheWindowManager->winGetWindowFromId( NULL, buttonPlaceBeaconID );
  2209. GameWindow *buttonIdleWorker = TheWindowManager->winGetWindowFromId( NULL, buttonIdleWorkerID );
  2210. GameWindow *buttonGeneral = TheWindowManager->winGetWindowFromId( NULL, buttonGeneralID );
  2211. if(pt == ThePlayerTemplateStore->findPlayerTemplate(TheNameKeyGenerator->nameToKey("FactionObserver")))
  2212. {
  2213. m_isObserverCommandBar = TRUE;
  2214. switchToContext( CB_CONTEXT_OBSERVER_LIST, NULL );
  2215. DEBUG_LOG(("We're loading the Observer Command Bar\n"));
  2216. if (buttonPlaceBeacon)
  2217. buttonPlaceBeacon->winHide(TRUE);
  2218. if (buttonIdleWorker)
  2219. buttonIdleWorker->winHide(TRUE);
  2220. if (buttonGeneral)
  2221. buttonGeneral->winEnable(FALSE);
  2222. }
  2223. else
  2224. {
  2225. switchToContext( CB_CONTEXT_NONE, NULL );
  2226. m_isObserverCommandBar = FALSE;
  2227. if (buttonPlaceBeacon)
  2228. buttonPlaceBeacon->winHide(
  2229. (TheGameLogic->getGameMode() != GAME_LAN && TheGameLogic->getGameMode() != GAME_INTERNET) ||
  2230. !TheGameInfo->isMultiPlayer());
  2231. if (buttonIdleWorker)
  2232. buttonIdleWorker->winHide(FALSE);
  2233. if (buttonGeneral)
  2234. {
  2235. buttonGeneral->winHide(FALSE);
  2236. buttonGeneral->winEnable(TRUE);
  2237. }
  2238. }
  2239. switchControlBarStage(CONTROL_BAR_STAGE_DEFAULT);
  2240. hidePurchaseScience();
  2241. }
  2242. void ControlBar::setControlBarSchemeByName(const AsciiString& name)
  2243. {
  2244. if(m_controlBarSchemeManager)
  2245. m_controlBarSchemeManager->setControlBarScheme( name );
  2246. switchControlBarStage(CONTROL_BAR_STAGE_DEFAULT);
  2247. }
  2248. void ControlBar::preloadAssets( TimeOfDay timeOfDay )
  2249. {
  2250. if (m_controlBarSchemeManager)
  2251. m_controlBarSchemeManager->preloadAssets( timeOfDay );
  2252. }
  2253. void ControlBar::updateBuildQueueDisabledImages( const Image *image )
  2254. {
  2255. if(!image)
  2256. return;
  2257. // We have to do this because the build queue data might have been reset
  2258. static NameKeyType buildQueueIDs[ MAX_BUILD_QUEUE_BUTTONS ];
  2259. static Bool idsInitialized = FALSE;
  2260. Int i;
  2261. // get name key ids for the build queue buttons
  2262. if( idsInitialized == FALSE )
  2263. {
  2264. AsciiString buttonName;
  2265. for( i = 0; i < MAX_BUILD_QUEUE_BUTTONS; i++ )
  2266. {
  2267. buttonName.format( "ControlBar.wnd:ButtonQueue%02d", i + 1 );
  2268. buildQueueIDs[ i ] = TheNameKeyGenerator->nameToKey( buttonName );
  2269. } // end for i
  2270. idsInitialized = TRUE;
  2271. } // end if
  2272. // get window pointers to all the buttons for the build queue
  2273. for( i = 0; i < MAX_BUILD_QUEUE_BUTTONS; i++ )
  2274. {
  2275. // get window commented out cause I believe we already set this. We'll see in a few minutes
  2276. m_queueData[ i ].control = TheWindowManager->winGetWindowFromId( m_contextParent[ CP_BUILD_QUEUE ],
  2277. buildQueueIDs[ i ] );
  2278. GadgetButtonSetDisabledImage( m_queueData[ i ].control, image );
  2279. } // end for i
  2280. }
  2281. void ControlBar::updateRightHUDImage( const Image *image )
  2282. {
  2283. if(!m_rightHUDWindow || !image)
  2284. return;
  2285. m_rightHUDWindow->winSetEnabledImage(0, image);
  2286. }
  2287. void ControlBar::updateBuildUpClockColor( Color color)
  2288. {
  2289. m_buildUpClockColor = color;
  2290. }
  2291. void ControlBar::updateCommanBarBorderColors(Color build, Color action, Color upgrade, Color system )
  2292. {
  2293. m_commandButtonBorderBuildColor = build;
  2294. m_commandButtonBorderActionColor = action;
  2295. m_commandButtonBorderUpgradeColor = upgrade;
  2296. m_commandButtonBorderSystemColor = system;
  2297. }
  2298. // ---------------------------------------------------------------------------------------
  2299. // hides the communicator button
  2300. void ControlBar::hideCommunicator( Bool b )
  2301. {
  2302. //sanity
  2303. if( m_communicatorButton != NULL )
  2304. m_communicatorButton->winHide( b );
  2305. }
  2306. // ---------------------------------------------------------------------------------------
  2307. // Outside hook so when the genera's head is pushed, we can switch to the purchase science
  2308. // context
  2309. void ControlBar::updatePurchaseScience( void )
  2310. {
  2311. // if(m_generalsScreenAnimate && TheGlobalData->m_animateWindows)
  2312. // {
  2313. // Bool wasFinished = m_generalsScreenAnimate->isFinished();
  2314. // m_generalsScreenAnimate->update();
  2315. // if (m_generalsScreenAnimate->isFinished() && !wasFinished && m_generalsScreenAnimate->isReversed())
  2316. // m_contextParent[ CP_PURCHASE_SCIENCE ]->winHide(TRUE);
  2317. // }
  2318. }
  2319. void ControlBar::showPurchaseScience( void )
  2320. {
  2321. if(TheScriptEngine->isGameEnding())
  2322. return;
  2323. populatePurchaseScience(ThePlayerList->getLocalPlayer());
  2324. m_genStarFlash = FALSE;
  2325. if(!m_contextParent[ CP_PURCHASE_SCIENCE ]->winIsHidden())
  2326. return;
  2327. //switchToContext(CB_CONTEXT_PURCHASE_SCIENCE, NULL);
  2328. m_contextParent[ CP_PURCHASE_SCIENCE ]->winHide(FALSE);
  2329. if (TheGlobalData->m_animateWindows)
  2330. TheTransitionHandler->setGroup("GenExpFade");
  2331. //m_generalsScreenAnimate->registerGameWindow( m_contextParent[ CP_PURCHASE_SCIENCE ], WIN_ANIMATION_SLIDE_TOP, TRUE, 200 );
  2332. }
  2333. void ControlBar::hidePurchaseScience( void )
  2334. {
  2335. if(m_contextParent[ CP_PURCHASE_SCIENCE ]->winIsHidden())
  2336. return;
  2337. if( m_contextParent[ CP_PURCHASE_SCIENCE ] )
  2338. {
  2339. m_contextParent[ CP_PURCHASE_SCIENCE ]->winHide( TRUE );
  2340. }
  2341. // if (!TheGlobalData->m_animateWindows)
  2342. // {
  2343. // if( m_contextParent[ CP_PURCHASE_SCIENCE ] )
  2344. // {
  2345. // m_contextParent[ CP_PURCHASE_SCIENCE ]->winHide( TRUE );
  2346. // }
  2347. // }
  2348. // else
  2349. // {
  2350. // //if (m_generalsScreenAnimate->isFinished())
  2351. // if(TheTransitionHandler->isFinished())
  2352. // TheTransitionHandler->reverse("GenExpFade");
  2353. // //m_generalsScreenAnimate->reverseAnimateWindow();
  2354. // }
  2355. }
  2356. void ControlBar::togglePurchaseScience( void )
  2357. {
  2358. if(m_contextParent[ CP_PURCHASE_SCIENCE ]->winIsHidden())
  2359. showPurchaseScience();
  2360. else
  2361. hidePurchaseScience();
  2362. }
  2363. void ControlBar::toggleControlBarStage( void )
  2364. {
  2365. if(m_currentControlBarStage == CONTROL_BAR_STAGE_DEFAULT )
  2366. switchControlBarStage(CONTROL_BAR_STAGE_LOW);
  2367. else
  2368. switchControlBarStage(CONTROL_BAR_STAGE_DEFAULT);
  2369. }
  2370. // Functions for repositioning/resizing the control bar
  2371. void ControlBar::switchControlBarStage( ControlBarStages stage )
  2372. {
  2373. if(stage < CONTROL_BAR_STAGE_DEFAULT || stage >= MAX_CONTROL_BAR_STAGES)
  2374. return;
  2375. if (TheRecorder && TheRecorder->getMode() == RECORDERMODETYPE_PLAYBACK)
  2376. return;
  2377. switch (stage) {
  2378. case CONTROL_BAR_STAGE_DEFAULT:
  2379. setDefaultControlBarConfig();
  2380. break;
  2381. // case CONTROL_BAR_STAGE_SQUISHED:
  2382. // setSquishedControlBarConfig();
  2383. // break;
  2384. case CONTROL_BAR_STAGE_LOW:
  2385. setLowControlBarConfig();
  2386. break;
  2387. case CONTROL_BAR_STAGE_HIDDEN:
  2388. setHiddenControlBar();
  2389. break;
  2390. default:
  2391. DEBUG_ASSERTCRASH(FALSE,("ControlBar::switchControlBarStage we were passed in a stage that's not supported %d", stage));
  2392. }
  2393. }
  2394. void ControlBar::setDefaultControlBarConfig( void )
  2395. {
  2396. // if(m_currentControlBarStage == CONTROL_BAR_STAGE_SQUISHED)
  2397. // {
  2398. // m_controlBarResizer->sizeWindowsDefault();
  2399. // m_controlBarSchemeManager->setControlBarSchemeByPlayerTemplate(ThePlayerList->getLocalPlayer()->getPlayerTemplate(), FALSE);
  2400. // }
  2401. m_currentControlBarStage = CONTROL_BAR_STAGE_DEFAULT;
  2402. TheTacticalView->setHeight((Int)(TheDisplay->getHeight() * 0.80f));
  2403. m_contextParent[ CP_MASTER ]->winSetPosition(m_defaultControlBarPosition.x, m_defaultControlBarPosition.y);
  2404. m_contextParent[ CP_MASTER ]->winHide(FALSE);
  2405. repopulateBuildTooltipLayout();
  2406. setUpDownImages();
  2407. }
  2408. void ControlBar::setSquishedControlBarConfig( void )
  2409. {
  2410. if(m_currentControlBarStage == CONTROL_BAR_STAGE_SQUISHED)
  2411. return;
  2412. m_currentControlBarStage = CONTROL_BAR_STAGE_SQUISHED;
  2413. m_contextParent[ CP_MASTER ]->winSetPosition(m_defaultControlBarPosition.x, m_defaultControlBarPosition.y);
  2414. // m_controlBarResizer->sizeWindowsAlt();
  2415. repopulateBuildTooltipLayout();
  2416. TheTacticalView->setHeight((Int)(TheDisplay->getHeight()));
  2417. m_controlBarSchemeManager->setControlBarSchemeByPlayerTemplate(ThePlayerList->getLocalPlayer()->getPlayerTemplate(), TRUE);
  2418. }
  2419. void ControlBar::setLowControlBarConfig( void )
  2420. {
  2421. // if(m_currentControlBarStage == CONTROL_BAR_STAGE_SQUISHED)
  2422. // {
  2423. // m_controlBarResizer->sizeWindowsDefault();
  2424. // m_controlBarSchemeManager->setControlBarSchemeByPlayerTemplate(ThePlayerList->getLocalPlayer()->getPlayerTemplate(), FALSE);
  2425. // }
  2426. m_currentControlBarStage = CONTROL_BAR_STAGE_LOW;
  2427. ICoord2D pos;
  2428. pos.x = m_defaultControlBarPosition.x;
  2429. pos.y = TheDisplay->getHeight() - .1 * TheDisplay->getHeight();
  2430. TheTacticalView->setHeight((Int)(TheDisplay->getHeight()));
  2431. m_contextParent[ CP_MASTER ]->winSetPosition(pos.x, pos.y);
  2432. m_contextParent[ CP_MASTER ]->winHide(FALSE);
  2433. setUpDownImages();
  2434. }
  2435. void ControlBar::setHiddenControlBar( void )
  2436. {
  2437. m_currentControlBarStage = CONTROL_BAR_STAGE_HIDDEN;
  2438. m_contextParent[ CP_MASTER ]->winHide(TRUE);
  2439. }
  2440. // removed from multiplayer test
  2441. //void ControlBar::showCommandMarkers( void )
  2442. //{
  2443. // for(Int i =0; i < MAX_COMMANDS_PER_SET; ++i)
  2444. // {
  2445. // if(m_commandWindows[i]->winIsHidden())
  2446. // m_commandMarkers[i]->winHide(FALSE);
  2447. // else
  2448. // m_commandMarkers[i]->winHide(TRUE);
  2449. // }
  2450. //}
  2451. //
  2452. void ControlBar::updateCommandMarkerImage( const Image *image )
  2453. {
  2454. // removed from multiplayer branch
  2455. // // we don't mind if the image is null, that way we can not draw anything
  2456. // for(Int i =0; i < MAX_COMMANDS_PER_SET; ++i)
  2457. // {
  2458. // m_commandMarkers[i]->winSetEnabledImage(0, image);
  2459. // }
  2460. }
  2461. void ControlBar::updateSlotExitImage( const Image *image )
  2462. {
  2463. //Hardcoding values here Not a good thing but there's no other way right now.
  2464. if(!image)
  2465. return;
  2466. CommandButton *cmdButton = findNonConstCommandButton( "Command_StructureExit" );
  2467. if(cmdButton)
  2468. cmdButton->setButtonImage(image);
  2469. cmdButton = findNonConstCommandButton( "Command_TransportExit" );
  2470. if(cmdButton)
  2471. cmdButton->setButtonImage(image);
  2472. }
  2473. void ControlBar::updateUpDownImages( const Image *toggleButtonUpIn, const Image *toggleButtonUpOn, const Image *toggleButtonUpPushed,
  2474. const Image *toggleButtonDownIn, const Image *toggleButtonDownOn, const Image *toggleButtonDownPushed,
  2475. const Image *generalButtonEnable, const Image *generalButtonHighlight )
  2476. {
  2477. m_toggleButtonUpIn = toggleButtonUpIn;
  2478. m_toggleButtonUpOn = toggleButtonUpOn;
  2479. m_toggleButtonUpPushed = toggleButtonUpPushed;
  2480. m_toggleButtonDownIn = toggleButtonDownIn;
  2481. m_toggleButtonDownOn = toggleButtonDownOn;
  2482. m_toggleButtonDownPushed = toggleButtonDownPushed;
  2483. m_generalButtonEnable = generalButtonEnable;
  2484. m_generalButtonHighlight = generalButtonHighlight;
  2485. setUpDownImages();
  2486. }
  2487. void ControlBar::setUpDownImages( void )
  2488. {
  2489. GameWindow *win= TheWindowManager->winGetWindowFromId( NULL, TheNameKeyGenerator->nameToKey( "ControlBar.wnd:ButtonLarge" ) );
  2490. if(!win)
  2491. return;
  2492. // we only care if it's in it's low state, else we put the default images up
  2493. if(m_currentControlBarStage == CONTROL_BAR_STAGE_LOW)
  2494. {
  2495. GadgetButtonSetEnabledImage(win, m_toggleButtonUpOn);
  2496. GadgetButtonSetHiliteImage(win, m_toggleButtonUpIn);
  2497. GadgetButtonSetHiliteSelectedImage(win, m_toggleButtonUpPushed);
  2498. return;
  2499. }
  2500. GadgetButtonSetEnabledImage(win, m_toggleButtonDownOn);
  2501. GadgetButtonSetHiliteImage(win, m_toggleButtonDownIn);
  2502. GadgetButtonSetHiliteSelectedImage(win, m_toggleButtonDownPushed);
  2503. }
  2504. void ControlBar::getForegroundMarkerPos(Int *x, Int *y)
  2505. {
  2506. *x = m_controlBarForegroundMarkerPos.x;
  2507. *y = m_controlBarForegroundMarkerPos.y;
  2508. }
  2509. void ControlBar::getBackgroundMarkerPos(Int *x, Int *y)
  2510. {
  2511. *x = m_controlBarBackgroundMarkerPos.x;
  2512. *y = m_controlBarBackgroundMarkerPos.y;
  2513. }
  2514. void ControlBar::drawTransitionHandler( void )
  2515. {
  2516. // if(m_transitionHandler)
  2517. // m_transitionHandler->draw();
  2518. }
  2519. enum{
  2520. RADAR_ATTACK_GLOW_FRAMES = 150,
  2521. RADAR_ATTACK_GLOW_NUM_TIMES = 15 ///< number of times we'll flash
  2522. };
  2523. void ControlBar::triggerRadarAttackGlow( void )
  2524. {
  2525. if(!m_radarAttackGlowWindow)
  2526. return;
  2527. m_radarAttackGlowOn = TRUE;
  2528. m_remainingRadarAttackGlowFrames = RADAR_ATTACK_GLOW_FRAMES;
  2529. if(BitTest(m_radarAttackGlowWindow->winGetStatus(),WIN_STATUS_ENABLED) == TRUE)
  2530. m_radarAttackGlowWindow->winEnable(FALSE);
  2531. }
  2532. void ControlBar::updateRadarAttackGlow ( void )
  2533. {
  2534. if(!m_radarAttackGlowOn || !m_radarAttackGlowWindow)
  2535. return;
  2536. m_remainingRadarAttackGlowFrames--;
  2537. if(m_remainingRadarAttackGlowFrames <= 0)
  2538. {
  2539. m_radarAttackGlowOn = FALSE;
  2540. m_radarAttackGlowWindow->winEnable(TRUE);
  2541. return;
  2542. }
  2543. if(m_remainingRadarAttackGlowFrames % RADAR_ATTACK_GLOW_NUM_TIMES == 0)
  2544. {
  2545. m_radarAttackGlowWindow->winEnable(!BitTest(m_radarAttackGlowWindow->winGetStatus(),WIN_STATUS_ENABLED));
  2546. }
  2547. }
  2548. void ControlBar::initSpecialPowershortcutBar( Player *player)
  2549. {
  2550. for( Int i = 0; i < MAX_SPECIAL_POWER_SHORTCUTS; ++i )
  2551. {
  2552. m_specialPowerShortcutButtonParents[i] = NULL;
  2553. m_specialPowerShortcutButtons[i] = NULL;
  2554. }
  2555. if(m_specialPowerLayout)
  2556. {
  2557. m_specialPowerLayout->destroyWindows();
  2558. m_specialPowerLayout->deleteInstance();
  2559. m_specialPowerLayout = NULL;
  2560. }
  2561. m_specialPowerShortcutParent = NULL;
  2562. m_currentlyUsedSpecialPowersButtons = 0;
  2563. const PlayerTemplate *pt = player->getPlayerTemplate();
  2564. if(!player || !pt|| !player->isLocalPlayer()
  2565. || pt->getSpecialPowerShortcutButtonCount() == 0
  2566. || pt->getSpecialPowerShortcutWinName().isEmpty()
  2567. || !player->isPlayerActive())
  2568. return;
  2569. m_currentlyUsedSpecialPowersButtons = pt->getSpecialPowerShortcutButtonCount();
  2570. AsciiString layoutName, tempName, windowName, parentName;
  2571. layoutName = pt->getSpecialPowerShortcutWinName();
  2572. m_specialPowerLayout = TheWindowManager->winCreateLayout(layoutName);
  2573. m_specialPowerLayout->hide(TRUE);
  2574. tempName = layoutName;
  2575. tempName.concat(":GenPowersShortcutBarParent");
  2576. NameKeyType id = TheNameKeyGenerator->nameToKey( tempName );
  2577. m_specialPowerShortcutParent = TheWindowManager->winGetWindowFromId( NULL, id );//m_scienceLayout->getFirstWindow();
  2578. tempName = layoutName;
  2579. tempName.concat(":ButtonCommand%d");
  2580. parentName = layoutName;
  2581. parentName.concat(":ButtonParent%d");
  2582. m_currentlyUsedSpecialPowersButtons = MIN(pt->getSpecialPowerShortcutButtonCount(), MAX_SPECIAL_POWER_SHORTCUTS);
  2583. for( i = 0; i < m_currentlyUsedSpecialPowersButtons; i++ )
  2584. {
  2585. windowName.format( tempName, i+1 );
  2586. id = TheNameKeyGenerator->nameToKey( windowName.str() );
  2587. m_specialPowerShortcutButtons[ i ] =
  2588. TheWindowManager->winGetWindowFromId( m_specialPowerShortcutParent, id );
  2589. m_specialPowerShortcutButtons[ i ]->winSetStatus( WIN_STATUS_USE_OVERLAY_STATES );
  2590. windowName.format( parentName, i+1 );
  2591. id = TheNameKeyGenerator->nameToKey( windowName.str() );
  2592. m_specialPowerShortcutButtonParents[ i ] =
  2593. TheWindowManager->winGetWindowFromId( m_specialPowerShortcutParent, id );
  2594. } // end for i
  2595. }
  2596. void ControlBar::populateSpecialPowerShortcut( Player *player)
  2597. {
  2598. const CommandSet *commandSet;
  2599. Int i;
  2600. if(!player || !player->getPlayerTemplate()
  2601. || !player->isLocalPlayer() || m_currentlyUsedSpecialPowersButtons == 0
  2602. || m_specialPowerShortcutButtons == NULL || m_specialPowerShortcutButtonParents == NULL)
  2603. return;
  2604. for( i = 0; i < m_currentlyUsedSpecialPowersButtons; ++i )
  2605. {
  2606. if (m_specialPowerShortcutButtons[i])
  2607. m_specialPowerShortcutButtons[i]->winHide(TRUE);
  2608. if (m_specialPowerShortcutButtonParents[i])
  2609. m_specialPowerShortcutButtonParents[i]->winHide(TRUE);
  2610. }
  2611. // get command set
  2612. if(player->getPlayerTemplate()->getSpecialPowerShortcutCommandSet().isEmpty() )
  2613. return;
  2614. commandSet = TheControlBar->findCommandSet(player->getPlayerTemplate()->getSpecialPowerShortcutCommandSet()); // TEMP WILL CHANGE TO PROPER WAY ONCE WORKING
  2615. if(!commandSet)
  2616. return;
  2617. // populate the button with commands defined
  2618. Int currentButton = 0;
  2619. const CommandButton *commandButton;
  2620. for( i = 0; i < m_currentlyUsedSpecialPowersButtons; i++ )
  2621. {
  2622. // get command button
  2623. commandButton = commandSet->getCommandButton(i);
  2624. // if button is not present, just hide the window
  2625. if( commandButton == NULL )
  2626. {
  2627. continue;
  2628. // hide window on interface
  2629. //m_specialPowerShortcutButtons[ i ]->winHide( TRUE );
  2630. } // end if
  2631. else
  2632. {
  2633. //
  2634. // commands that require sciences we don't have are hidden so they never show up
  2635. // cause we can never pick "another" general technology throughout the game
  2636. //
  2637. if( BitTest( commandButton->getOptions(), NEED_SPECIAL_POWER_SCIENCE ) )
  2638. {
  2639. const SpecialPowerTemplate *power = commandButton->getSpecialPowerTemplate();
  2640. if( power && power->getRequiredScience() != SCIENCE_INVALID )
  2641. {
  2642. if( player->hasScience( power->getRequiredScience() ) == FALSE )
  2643. {
  2644. //Hide the power
  2645. //m_specialPowerShortcutButtons[ i ]->winHide( TRUE );
  2646. continue;
  2647. }
  2648. else
  2649. {
  2650. //The player does have the special power! Now determine if the images require
  2651. //enhancement based on upgraded versions. This is determined by the command
  2652. //button specifying a vector of sciences in the command button.
  2653. Int bestIndex = -1;
  2654. ScienceType science;
  2655. for( Int scienceIndex = 0; scienceIndex < commandButton->getScienceVec().size(); ++scienceIndex )
  2656. {
  2657. science = commandButton->getScienceVec()[ scienceIndex ];
  2658. //Keep going until we reach the end or don't have the required science!
  2659. if( player->hasScience( science ) )
  2660. {
  2661. bestIndex = scienceIndex;
  2662. }
  2663. else
  2664. {
  2665. break;
  2666. }
  2667. }
  2668. if( bestIndex != -1 )
  2669. {
  2670. //Now get the best sciencetype.
  2671. science = commandButton->getScienceVec()[ bestIndex ];
  2672. //Now we have to search through the command buttons to find a matching purchase science button.
  2673. for( const CommandButton *command = m_commandButtons; command; command = command->getNext() )
  2674. {
  2675. if( command->getCommandType() == GUI_COMMAND_PURCHASE_SCIENCE )
  2676. {
  2677. //All purchase sciences specify a single science.
  2678. if( command->getScienceVec().empty() )
  2679. {
  2680. DEBUG_CRASH( ("Commandbutton %s is a purchase science button without any science! Please add it.", command->getName().str() ) );
  2681. }
  2682. else if( command->getScienceVec()[0] == science )
  2683. {
  2684. commandButton->copyImagesFrom( command, true );
  2685. }
  2686. }
  2687. }
  2688. }
  2689. }
  2690. }
  2691. } // end if
  2692. // make sure the window is not hidden
  2693. m_specialPowerShortcutButtons[ currentButton ]->winHide( FALSE );
  2694. m_specialPowerShortcutButtonParents[ currentButton ]->winHide( FALSE );
  2695. // enable by default
  2696. m_specialPowerShortcutButtons[ currentButton ]->winEnable( TRUE );
  2697. m_specialPowerShortcutButtonParents[ currentButton ]->winEnable( TRUE );
  2698. // populate the visible button with data from the command button
  2699. setControlCommand( m_specialPowerShortcutButtons[ currentButton ], commandButton );
  2700. GadgetButtonSetAltSound(m_specialPowerShortcutButtons[ currentButton ], "GUIGenShortcutClick");
  2701. currentButton++;
  2702. } // end else
  2703. } // end for i
  2704. if(m_contextParent[ CP_MASTER ] && !m_contextParent[ CP_MASTER ]->winIsHidden() && m_specialPowerShortcutParent->winIsHidden())
  2705. {
  2706. showSpecialPowerShortcut();
  2707. animateSpecialPowerShortcut(TRUE);
  2708. }
  2709. updateSpecialPowerShortcut();
  2710. }
  2711. void ControlBar::updateSpecialPowerShortcut( void )
  2712. {
  2713. if(!m_specialPowerShortcutParent || !m_specialPowerShortcutButtons
  2714. || !ThePlayerList || !ThePlayerList->getLocalPlayer())
  2715. return;
  2716. if(ThePlayerList->getLocalPlayer()->findNaturalCommandCenter() &&
  2717. m_specialPowerShortcutParent->winIsHidden() &&
  2718. m_contextParent[ CP_MASTER ] && !m_contextParent[ CP_MASTER ]->winIsHidden())
  2719. {
  2720. showSpecialPowerShortcut();
  2721. animateSpecialPowerShortcut(TRUE);
  2722. }
  2723. else if( !ThePlayerList->getLocalPlayer()->findNaturalCommandCenter() && !m_specialPowerShortcutParent->winIsHidden() && m_animateWindowManagerForGenShortcuts->isFinished())
  2724. {
  2725. animateSpecialPowerShortcut(FALSE);
  2726. }
  2727. if(m_specialPowerShortcutParent->winIsHidden())
  2728. return;
  2729. if(!ThePlayerList->getLocalPlayer()->isPlayerActive())
  2730. {
  2731. hideSpecialPowerShortcut();
  2732. return;
  2733. }
  2734. if(m_contextParent[ CP_MASTER ] && !m_contextParent[ CP_MASTER ]->winIsHidden() && m_specialPowerShortcutParent->winIsHidden())
  2735. showSpecialPowerShortcut();
  2736. for( Int i = 0; i < m_currentlyUsedSpecialPowersButtons; i++ )
  2737. {
  2738. GameWindow *win;
  2739. const CommandButton *command;
  2740. // get the window
  2741. win = m_specialPowerShortcutButtons[ i ];
  2742. if( win->winIsHidden() == TRUE )
  2743. continue;
  2744. // get the command from the control
  2745. command = (const CommandButton *)GadgetButtonGetData(win);
  2746. //command = (const CommandButton *)win->winGetUserData();
  2747. if( command == NULL )
  2748. continue;
  2749. win->winClearStatus( WIN_STATUS_NOT_READY );
  2750. win->winClearStatus( WIN_STATUS_ALWAYS_COLOR );
  2751. // is the command available
  2752. CommandAvailability availability = COMMAND_RESTRICTED;
  2753. if(ThePlayerList->getLocalPlayer()->findNaturalCommandCenter())
  2754. availability = getCommandAvailability( command,ThePlayerList->getLocalPlayer()->findNaturalCommandCenter() , win );
  2755. // enable/disable the window control
  2756. switch( availability )
  2757. {
  2758. case COMMAND_HIDDEN:
  2759. win->winHide( TRUE );
  2760. break;
  2761. case COMMAND_RESTRICTED:
  2762. win->winEnable( FALSE );
  2763. break;
  2764. case COMMAND_NOT_READY:
  2765. win->winEnable( FALSE );
  2766. win->winSetStatus( WIN_STATUS_NOT_READY );
  2767. break;
  2768. case COMMAND_CANT_AFFORD:
  2769. win->winEnable( FALSE );
  2770. win->winSetStatus( WIN_STATUS_ALWAYS_COLOR );
  2771. break;
  2772. default:
  2773. win->winEnable( TRUE );
  2774. break;
  2775. }
  2776. }
  2777. }
  2778. void ControlBar::animateSpecialPowerShortcut( Bool isOn )
  2779. {
  2780. if(!m_specialPowerShortcutParent || !m_animateWindowManagerForGenShortcuts || !m_currentlyUsedSpecialPowersButtons)
  2781. return;
  2782. Bool dontAnimate = TRUE;
  2783. for( Int i = 0; i < m_currentlyUsedSpecialPowersButtons; ++i )
  2784. {
  2785. if (m_specialPowerShortcutButtons[i]->winGetUserData())
  2786. {
  2787. dontAnimate = FALSE;
  2788. break;
  2789. }
  2790. }
  2791. if(dontAnimate)
  2792. return;
  2793. if(isOn)
  2794. {
  2795. m_animateWindowManagerForGenShortcuts->reset();
  2796. m_animateWindowManagerForGenShortcuts->registerGameWindow(m_specialPowerShortcutParent,WIN_ANIMATION_SLIDE_RIGHT,TRUE,500,0);
  2797. }
  2798. else
  2799. {
  2800. m_animateWindowManagerForGenShortcuts->reverseAnimateWindow();
  2801. }
  2802. }
  2803. void ControlBar::showSpecialPowerShortcut( void )
  2804. {
  2805. if(TheScriptEngine->isGameEnding() || !m_specialPowerShortcutParent
  2806. ||!m_specialPowerShortcutButtons || !ThePlayerList || !ThePlayerList->getLocalPlayer())
  2807. return;
  2808. Bool dontAnimate = TRUE;
  2809. for( Int i = 0; i < m_currentlyUsedSpecialPowersButtons; ++i )
  2810. {
  2811. if (m_specialPowerShortcutButtons[i]->winGetUserData())
  2812. {
  2813. dontAnimate = FALSE;
  2814. break;
  2815. }
  2816. }
  2817. if(dontAnimate || !ThePlayerList->getLocalPlayer()->findNaturalCommandCenter())
  2818. return;
  2819. m_specialPowerShortcutParent->winHide(FALSE);
  2820. populateSpecialPowerShortcut(ThePlayerList->getLocalPlayer());
  2821. }
  2822. void ControlBar::hideSpecialPowerShortcut( void )
  2823. {
  2824. if(!m_specialPowerShortcutParent)
  2825. return;
  2826. m_specialPowerShortcutParent->winHide(TRUE);
  2827. }