SIDEBAR.CPP 111 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478
  1. //
  2. // Copyright 2020 Electronic Arts Inc.
  3. //
  4. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
  5. // software: you can redistribute it and/or modify it under the terms of
  6. // the GNU General Public License as published by the Free Software Foundation,
  7. // either version 3 of the License, or (at your option) any later version.
  8. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
  9. // in the hope that it will be useful, but with permitted additional restrictions
  10. // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
  11. // distributed with this program. You should have received a copy of the
  12. // GNU General Public License along with permitted additional restrictions
  13. // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
  14. /* $Header: /counterstrike/SIDEBAR.CPP 2 3/17/97 1:05a Steve_tall $ */
  15. /***********************************************************************************************
  16. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  17. ***********************************************************************************************
  18. * *
  19. * Project Name : Command & Conquer *
  20. * *
  21. * File Name : SIDEBAR.CPP *
  22. * *
  23. * Programmer : Joe L. Bostic *
  24. * *
  25. * Start Date : October 20, 1994 *
  26. * *
  27. * Last Update : October 9, 1996 [JLB] *
  28. * *
  29. *---------------------------------------------------------------------------------------------*
  30. * Functions: *
  31. * SidebarClass::AI -- Handles player clicking on sidebar area. *
  32. * SidebarClass::Abandon_Production -- Stops production of the object specified. *
  33. * SidebarClass::Activate -- Controls the sidebar activation. *
  34. * SidebarClass::Activate_Demolish -- Controls the demolish button on the sidebar. *
  35. * SidebarClass::Activate_Repair -- Controls the repair button on the sidebar. *
  36. * SidebarClass::Activate_Upgrade -- Controls the upgrade button on the sidebar. *
  37. * SidebarClass::Add -- Adds a game object to the sidebar list. *
  38. * SidebarClass::Draw_It -- Renders the sidebar display. *
  39. * SidebarClass::Factory_Link -- Links a factory to a sidebar strip. *
  40. * SidebarClass::Init_Clear -- Sets sidebar to a known (and deactivated) state *
  41. * SidebarClass::Init_IO -- Adds buttons to the button list *
  42. * SidebarClass::Init_Theater -- Performs theater-specific initialization *
  43. * SidebarClass::One_Time -- Handles the one time game initializations. *
  44. * SidebarClass::One_Time -- Handles the one time game initializations. *
  45. * SidebarClass::Recalc -- Examines the sidebar data and updates it as necessary. *
  46. * SidebarClass::Refresh_Cells -- Intercepts the refresh, looking for sidebar controls. *
  47. * SidebarClass::SBGadgetClass::Action -- Special function that controls the mouse over the s*
  48. * SidebarClass::Scroll -- Handles scrolling the sidebar object strip. *
  49. * SidebarClass::Set_Current -- Sets a specified object that controls the sidebar display. *
  50. * SidebarClass::SidebarClass -- Default constructor for the sidebar. *
  51. * SidebarClass::SidebarClass -- This is the no initialization constructor for the sidebar. *
  52. * SidebarClass::StripClass::AI -- Input and AI processing for the side strip. *
  53. * SidebarClass::StripClass::Abandon_Produ -- Abandons production associated with sidebar. *
  54. * SidebarClass::StripClass::Activate -- Adds the strip buttons to the input system. *
  55. * SidebarClass::StripClass::Add -- Add an object to the side strip. *
  56. * SidebarClass::StripClass::Deactivate -- Removes the side strip buttons from the input syst*
  57. * SidebarClass::StripClass::Draw_It -- Render the sidebar display. *
  58. * SidebarClass::StripClass::Factory_Link -- Links a factory to a sidebar button. *
  59. * SidebarClass::StripClass::Flag_To_Redra -- Flags the sidebar strip to be redrawn. *
  60. * SidebarClass::StripClass::Get_Special_Cameo -- Fetches the special event cameo shape. *
  61. * SidebarClass::StripClass::Init_Clear -- Sets sidebar to a known (and deactivated) state *
  62. * SidebarClass::StripClass::Init_IO -- Adds buttons to the button list *
  63. * SidebarClass::StripClass::Init_Theater -- Performs theater-specific initialization *
  64. * SidebarClass::StripClass::One_Time -- Performs one time actions necessary for the side str*
  65. * SidebarClass::StripClass::Recalc -- Revalidates the current sidebar list of objects. *
  66. * SidebarClass::StripClass::Scroll -- Causes the side strip to scroll. *
  67. * SidebarClass::StripClass::SelectClass:: -- Action function when buildable cameo is selecte*
  68. * SidebarClass::StripClass::SelectClass:: -- Assigns special values to a buildable select bu*
  69. * SidebarClass::StripClass::SelectClass::SelectClass -- Default constructor. *
  70. * SidebarClass::StripClass::StripClass -- Default constructor for the side strip class. *
  71. * SidebarClass::Which_Column -- Determines which column a given type should appear. *
  72. * SidebarClass::Zoom_Mode_Control -- Handles the zoom mode toggle operation. *
  73. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  74. #include "function.h"
  75. void * SidebarClass::SidebarShape = NULL;
  76. void * SidebarClass::SidebarMiddleShape = NULL;
  77. void * SidebarClass::SidebarBottomShape = NULL;
  78. /***************************************************************************
  79. ** This holds the translucent table for use with the construction clock
  80. ** animation.
  81. */
  82. char SidebarClass::StripClass::ClockTranslucentTable[(1+1)*256];
  83. /***************************************************************************
  84. ** This points to the main sidebar shapes. These include the upgrade and
  85. ** repair buttons.
  86. */
  87. //TheaterType SidebarClass::StripClass::LastTheater = THEATER_NONE;
  88. typedef enum ButtonNumberType {
  89. BUTTON_RADAR = 100,
  90. BUTTON_REPAIR,
  91. BUTTON_DEMOLISH,
  92. BUTTON_UPGRADE,
  93. BUTTON_SELECT,
  94. BUTTON_ZOOM
  95. } ButtonNumberType;
  96. /*
  97. ** Sidebar buttons
  98. */
  99. SidebarClass::SBGadgetClass SidebarClass::Background;
  100. ShapeButtonClass SidebarClass::Repair;
  101. ShapeButtonClass SidebarClass::Upgrade;
  102. ShapeButtonClass SidebarClass::Zoom;
  103. ShapeButtonClass SidebarClass::StripClass::UpButton[COLUMNS];
  104. ShapeButtonClass SidebarClass::StripClass::DownButton[COLUMNS];
  105. SidebarClass::StripClass::SelectClass
  106. SidebarClass::StripClass::SelectButton[COLUMNS][MAX_VISIBLE];
  107. /*
  108. ** Shape data pointers
  109. */
  110. void * SidebarClass::StripClass::LogoShapes = NULL;
  111. void const * SidebarClass::StripClass::ClockShapes;
  112. void const * SidebarClass::StripClass::SpecialShapes[SPC_COUNT];
  113. /***********************************************************************************************
  114. * SidebarClass::SidebarClass -- Default constructor for the sidebar. *
  115. * *
  116. * Constructor for the sidebar handler. It basically sets up the sidebar to the empty *
  117. * condition. *
  118. * *
  119. * INPUT: none *
  120. * *
  121. * OUTPUT: none *
  122. * *
  123. * WARNINGS: none *
  124. * *
  125. * HISTORY: *
  126. * 11/17/1994 JLB : Created. *
  127. *=============================================================================================*/
  128. SidebarClass::SidebarClass(void) :
  129. IsSidebarActive(false),
  130. IsToRedraw(true),
  131. IsRepairActive(false),
  132. IsUpgradeActive(false),
  133. IsDemolishActive(false)
  134. {
  135. /*
  136. ** This sets up the clipping window. This window is used by the shape drawing
  137. ** code so that as the sidebar buildable buttons scroll, they get properly
  138. ** clipped at the top and bottom edges.
  139. */
  140. WindowList[WINDOW_SIDEBAR][WINDOWX] = (SIDE_X+8);
  141. WindowList[WINDOW_SIDEBAR][WINDOWY] = SIDE_Y + 1 + TOP_HEIGHT;
  142. WindowList[WINDOW_SIDEBAR][WINDOWWIDTH] = SIDE_WIDTH;
  143. WindowList[WINDOW_SIDEBAR][WINDOWHEIGHT] = StripClass::MAX_VISIBLE * StripClass::OBJECT_HEIGHT;
  144. // WindowList[WINDOW_SIDEBAR][WINDOWHEIGHT] = StripClass::MAX_VISIBLE * StripClass::OBJECT_HEIGHT-1;
  145. /*
  146. ** Set up the coordinates for the sidebar strips. These coordinates are for
  147. ** the upper left corner.
  148. */
  149. new (&Column[0]) StripClass(InitClass());
  150. new (&Column[1]) StripClass(InitClass());
  151. Column[0].X = COLUMN_ONE_X * RESFACTOR;
  152. Column[0].Y = COLUMN_ONE_Y * RESFACTOR;
  153. Column[1].X = COLUMN_TWO_X * RESFACTOR;
  154. Column[1].Y = COLUMN_TWO_Y * RESFACTOR;
  155. }
  156. /***********************************************************************************************
  157. * SidebarClass::SidebarClass -- This is the no initialization constructor for the sidebar. *
  158. * *
  159. * Unlike the normal constructor, this one doesn't do any initialization. There is one *
  160. * exception to this. The stip classes can't call an explicit NoInitClass constructor *
  161. * since they are an array. Since the default constructor is called for these strips, we *
  162. * must reset the X and Y location to what we know they should be. *
  163. * *
  164. * INPUT: flag to indicate that this is a no initialization constructor. *
  165. * *
  166. * OUTPUT: none *
  167. * *
  168. * WARNINGS: none *
  169. * *
  170. * HISTORY: *
  171. * 08/06/1996 JLB : Created. *
  172. *=============================================================================================*/
  173. SidebarClass::SidebarClass(NoInitClass const & x) : PowerClass(x)
  174. {
  175. /*
  176. ** Set up the coordinates for the sidebar strips. These coordinates are for
  177. ** the upper left corner.
  178. */
  179. // Column[0].X = COLUMN_ONE_X * RESFACTOR;
  180. // Column[0].Y = COLUMN_ONE_Y * RESFACTOR;
  181. // Column[1].X = COLUMN_TWO_X * RESFACTOR;
  182. // Column[1].Y = COLUMN_TWO_Y * RESFACTOR;
  183. }
  184. /***********************************************************************************************
  185. * SidebarClass::One_Time -- Handles the one time game initializations. *
  186. * *
  187. * This routine is used to load the graphic data that is needed by the sidebar display. It *
  188. * should only be called ONCE. *
  189. * *
  190. * INPUT: none *
  191. * *
  192. * OUTPUT: none *
  193. * *
  194. * WARNINGS: Only call this routine once when the game first starts. *
  195. * *
  196. * HISTORY: *
  197. * 10/28/94 JLB : Created. *
  198. *=============================================================================================*/
  199. void SidebarClass::One_Time(void)
  200. {
  201. PowerClass::One_Time();
  202. /*
  203. ** This sets up the clipping window. This window is used by the shape drawing
  204. ** code so that as the sidebar buildable buttons scroll, they get properly
  205. ** clipped at the top and bottom edges.
  206. */
  207. WindowList[WINDOW_SIDEBAR][WINDOWX] = ((SIDE_X+8)) * RESFACTOR;
  208. WindowList[WINDOW_SIDEBAR][WINDOWY] = (SIDE_Y + 1 + TOP_HEIGHT) * RESFACTOR;
  209. WindowList[WINDOW_SIDEBAR][WINDOWWIDTH] = (SIDE_WIDTH) * RESFACTOR;
  210. WindowList[WINDOW_SIDEBAR][WINDOWHEIGHT] = (StripClass::MAX_VISIBLE * StripClass::OBJECT_HEIGHT) * RESFACTOR;
  211. // WindowList[WINDOW_SIDEBAR][WINDOWHEIGHT] = (StripClass::MAX_VISIBLE * StripClass::OBJECT_HEIGHT-1) * RESFACTOR;
  212. /*
  213. ** Top of the window seems to be wrong for the new sidebar. ST - 5/2/96 2:49AM
  214. */
  215. WindowList[WINDOW_SIDEBAR][WINDOWY] -= 1*RESFACTOR;
  216. /*
  217. ** Set up the coordinates for the sidebar strips. These coordinates are for
  218. ** the upper left corner.
  219. */
  220. // Column[0].X = COLUMN_ONE_X * RESFACTOR;
  221. // Column[0].Y = COLUMN_ONE_Y * RESFACTOR;
  222. // Column[1].X = COLUMN_TWO_X * RESFACTOR;
  223. // Column[1].Y = COLUMN_TWO_Y * RESFACTOR;
  224. Column[0].One_Time(0);
  225. Column[1].One_Time(1);
  226. /*
  227. ** Load the sidebar shape in at this time. (Hi-Res sidebar is theater dependant)
  228. */
  229. if (SidebarShape == NULL) {
  230. SidebarShape = (void*)MFCD::Retrieve("SIDEBAR.SHP");
  231. }
  232. }
  233. /***********************************************************************************************
  234. * SidebarClass::Init_Clear -- Sets sidebar to a known (and deactivated) state *
  235. * *
  236. * INPUT: none *
  237. * *
  238. * OUTPUT: none *
  239. * *
  240. * WARNINGS: none *
  241. * *
  242. * HISTORY: *
  243. * 12/24/1994 JLB : Created. *
  244. *=============================================================================================*/
  245. void SidebarClass::Init_Clear(void)
  246. {
  247. PowerClass::Init_Clear();
  248. IsToRedraw = true;
  249. IsRepairActive = false;
  250. IsUpgradeActive = false;
  251. IsDemolishActive = false;
  252. Column[0].Init_Clear();
  253. Column[1].Init_Clear();
  254. Activate(false);
  255. }
  256. /***********************************************************************************************
  257. * SidebarClass::Init_IO -- Adds buttons to the button list *
  258. * *
  259. * INPUT: none *
  260. * *
  261. * OUTPUT: none *
  262. * *
  263. * WARNINGS: none *
  264. * *
  265. * HISTORY: *
  266. * 12/24/1994 JLB : Created. *
  267. *=============================================================================================*/
  268. void SidebarClass::Init_IO(void)
  269. {
  270. PowerClass::Init_IO();
  271. /*
  272. ** Add the sidebar's buttons only if we're not in editor mode.
  273. */
  274. if (!Debug_Map) {
  275. Repair.IsSticky = true;
  276. Repair.ID = BUTTON_REPAIR;
  277. Repair.X = (0x1f2/2)*RESFACTOR;
  278. Repair.Y = (0x96/2)*RESFACTOR;
  279. Repair.IsPressed = false;
  280. Repair.IsToggleType = true;
  281. Repair.ReflectButtonState = true;
  282. Repair.Set_Shape(MFCD::Retrieve("REPAIR.SHP"));
  283. Upgrade.IsSticky = true;
  284. Upgrade.ID = BUTTON_UPGRADE;
  285. #ifdef WIN32
  286. Upgrade.X = 0x21f;
  287. #else
  288. Upgrade.X = ((0x21f/2)+1)*RESFACTOR;
  289. #endif
  290. Upgrade.Y = (0x96/2)*RESFACTOR;
  291. Upgrade.IsPressed = false;
  292. Upgrade.IsToggleType = true;
  293. Upgrade.ReflectButtonState = true;
  294. Upgrade.Set_Shape(MFCD::Retrieve("SELL.SHP"));
  295. Zoom.IsSticky = true;
  296. Zoom.ID = BUTTON_ZOOM;
  297. Zoom.X = (0x24c/2)*RESFACTOR;
  298. Zoom.Y = (0x96/2)*RESFACTOR;
  299. Zoom.IsPressed = false;
  300. Zoom.Set_Shape(MFCD::Retrieve("MAP.SHP"));
  301. if ((IsRadarActive && Is_Zoomable()) || Session.Type != GAME_NORMAL) {
  302. Zoom.Enable();
  303. } else {
  304. Zoom.Disable();
  305. }
  306. Column[0].Init_IO(0);
  307. Column[1].Init_IO(1);
  308. /*
  309. ** If a game was loaded & the sidebar was enabled, pop it up now
  310. */
  311. if (IsSidebarActive) {
  312. IsSidebarActive = false;
  313. Activate(1);
  314. // Background.Zap();
  315. // Add_A_Button(Background);
  316. }
  317. }
  318. }
  319. /***********************************************************************************************
  320. * SidebarClass::Init_Theater -- Performs theater-specific initialization *
  321. * *
  322. * INPUT: theater -- The theater that is being initialized. Sometimes this has an effect on *
  323. * the data that is loaded. *
  324. * *
  325. * OUTPUT: none *
  326. * *
  327. * WARNINGS: none *
  328. * *
  329. * HISTORY: *
  330. * 12/24/1994 JLB : Created. *
  331. *=============================================================================================*/
  332. void SidebarClass::Init_Theater(TheaterType theater)
  333. {
  334. Reload_Sidebar();
  335. PowerClass::Init_Theater(theater);
  336. Column[0].Init_Theater(theater);
  337. Column[1].Init_Theater(theater);
  338. }
  339. /***********************************************************************************************
  340. * SidebarClass::Reload_Sidebar -- Loads appropriate sidebar shapes depending on house *
  341. * *
  342. * INPUT: none *
  343. * *
  344. * OUTPUT: none *
  345. * *
  346. * WARNINGS: none *
  347. * *
  348. * HISTORY: *
  349. * 9/18/1996 BWG : Created. *
  350. *=============================================================================================*/
  351. void SidebarClass::Reload_Sidebar(void)
  352. {
  353. static char * sidebarnames[]={
  354. "SIDE?NA.SHP", //NATO
  355. "SIDE?NA.SHP",
  356. "SIDE?US.SHP", //USSR
  357. "SIDE?NA.SHP",
  358. "SIDE?US.SHP", //UKRAINE
  359. "SIDE?NA.SHP",
  360. "SIDE?NA.SHP",
  361. "SIDE?NA.SHP",
  362. "SIDE?NA.SHP", //HOUSE_GOOD
  363. "SIDE?US.SHP" //HOUSE_BAD
  364. };
  365. int houseloaded = 0;
  366. if(PlayerPtr) {
  367. houseloaded = PlayerPtr->ActLike;
  368. }
  369. /* Don't have write access to the static char array. ST - 5/20/2019 */
  370. #if (0)
  371. char * sidename = sidebarnames[houseloaded];
  372. *(sidename+4) = '1';
  373. SidebarShape = (void*)MFCD::Retrieve(sidename);
  374. *(sidename+4) = '2';
  375. SidebarMiddleShape = (void*)MFCD::Retrieve(sidename);
  376. *(sidename+4) = '3';
  377. SidebarBottomShape = (void*)MFCD::Retrieve(sidename);
  378. #else
  379. char sb_name[16];
  380. strcpy(sb_name, sidebarnames[houseloaded]);
  381. sb_name[4] = '1';
  382. SidebarShape = (void*)MFCD::Retrieve(sb_name);
  383. sb_name[4] = '2';
  384. SidebarMiddleShape = (void*)MFCD::Retrieve(sb_name);
  385. sb_name[4] = '3';
  386. SidebarBottomShape = (void*)MFCD::Retrieve(sb_name);
  387. #endif
  388. Column[0].Reload_LogoShapes();
  389. Column[1].Reload_LogoShapes();
  390. }
  391. /***********************************************************************************************
  392. * SidebarClass::Which_Column -- Determines which column a given type should appear. *
  393. * *
  394. * Use this function to resolve what column the specified object type should be placed *
  395. * into. *
  396. * *
  397. * INPUT: otype -- Pointer to the object type class of the object in question. *
  398. * *
  399. * OUTPUT: Returns with the column number that the object should be placed in. *
  400. * *
  401. * WARNINGS: none *
  402. * *
  403. * HISTORY: *
  404. * 01/01/1995 JLB : Created. *
  405. *=============================================================================================*/
  406. int SidebarClass::Which_Column(RTTIType type)
  407. {
  408. if (type == RTTI_BUILDINGTYPE || type == RTTI_BUILDING) {
  409. return(0);
  410. }
  411. return(1);
  412. }
  413. /***********************************************************************************************
  414. * SidebarClass::Factory_Link -- Links a factory to a sidebar strip. *
  415. * *
  416. * This routine will link the specified factory to the sidebar strip. A factory must be *
  417. * linked to the sidebar so that as the factory production progresses, the sidebar will *
  418. * show the production progress. *
  419. * *
  420. * INPUT: factory -- The factory number to attach. *
  421. * *
  422. * type -- The object type number. *
  423. * *
  424. * id -- The object sub-type number. *
  425. * *
  426. * OUTPUT: Was the factory successfully attached to the sidebar strip? *
  427. * *
  428. * WARNINGS: none *
  429. * *
  430. * HISTORY: *
  431. * 05/19/1995 JLB : Created. *
  432. *=============================================================================================*/
  433. bool SidebarClass::Factory_Link(int factory, RTTIType type, int id)
  434. {
  435. assert((unsigned)type < RTTI_COUNT);
  436. assert(id >= 0);
  437. return(Column[Which_Column(type)].Factory_Link(factory, type, id));
  438. }
  439. /***********************************************************************************************
  440. * SidebarClass::Refresh_Cells -- Intercepts the refresh, looking for sidebar controls. *
  441. * *
  442. * This routine intercepts the Refresh_Cells call in order to see if the sidebar needs *
  443. * to be refreshed as well. If the special code to refresh the sidebar was found, it *
  444. * flags the sidebar to be redrawn and then removes the code from the list. *
  445. * *
  446. * INPUT: cell -- The cell to base the refresh list on. *
  447. * *
  448. * list -- Pointer to the cell offset list that elaborates all the cells that *
  449. * need to be flagged for redraw. *
  450. * *
  451. * OUTPUT: none *
  452. * *
  453. * WARNINGS: none *
  454. * *
  455. * HISTORY: *
  456. * 01/19/1995 JLB : Created. *
  457. *=============================================================================================*/
  458. void SidebarClass::Refresh_Cells(CELL cell, short const * list)
  459. {
  460. if (*list == REFRESH_SIDEBAR) {
  461. IsToRedraw = true;
  462. Column[0].IsToRedraw = true;
  463. Column[1].IsToRedraw = true;
  464. Flag_To_Redraw(false);
  465. }
  466. PowerClass::Refresh_Cells(cell, list);
  467. }
  468. /***********************************************************************************************
  469. * SidebarClass::Activate_Repair -- Controls the repair button on the sidebar. *
  470. * *
  471. * Use this routine to turn the repair sidebar button on and off. Typically, the button *
  472. * is enabled when the currently selected structure is friendly and damaged. *
  473. * *
  474. * INPUT: control -- The controls how the button is to be activated or deactivated; *
  475. * 0 -- Turn button off. *
  476. * 1 -- Turn button on. *
  477. * -1 -- Toggle button state. *
  478. * *
  479. * OUTPUT: bool; Was the button previously activated? *
  480. * *
  481. * WARNINGS: none *
  482. * *
  483. * HISTORY: *
  484. * 12/24/1994 JLB : Created. *
  485. *=============================================================================================*/
  486. bool SidebarClass::Activate_Repair(int control)
  487. {
  488. bool old = IsRepairActive;
  489. if (control == -1) {
  490. control = IsRepairActive ? 0 : 1;
  491. }
  492. switch (control) {
  493. case 1:
  494. IsRepairActive = true;
  495. break;
  496. default:
  497. case 0:
  498. IsRepairActive = false;
  499. break;
  500. }
  501. if (old != IsRepairActive) {
  502. Flag_To_Redraw(false);
  503. IsToRedraw = true;
  504. if (!IsRepairActive) {
  505. Help_Text(TXT_NONE);
  506. Set_Default_Mouse(MOUSE_NORMAL, false);
  507. }
  508. }
  509. return(old);
  510. }
  511. /***********************************************************************************************
  512. * SidebarClass::Activate_Upgrade -- Controls the upgrade button on the sidebar. *
  513. * *
  514. * Use this routine to turn the upgrade sidebar button on and off. Typically, the button *
  515. * is enabled when the currently selected structure can be upgraded and disabled otherwise. *
  516. * *
  517. * INPUT: control -- The controls how the button is to be activated or deactivated; *
  518. * 0 -- Turn button off. *
  519. * 1 -- Turn button on. *
  520. * -1 -- Toggle button state. *
  521. * *
  522. * OUTPUT: bool; Was the button previously activated? *
  523. * *
  524. * WARNINGS: none *
  525. * *
  526. * HISTORY: *
  527. * 12/24/1994 JLB : Created. *
  528. *=============================================================================================*/
  529. bool SidebarClass::Activate_Upgrade(int control)
  530. {
  531. bool old = IsUpgradeActive;
  532. if (control == -1) {
  533. control = IsUpgradeActive ? 0 : 1;
  534. }
  535. switch (control) {
  536. case 1:
  537. IsUpgradeActive = true;
  538. break;
  539. default:
  540. case 0:
  541. IsUpgradeActive = false;
  542. break;
  543. }
  544. if (old != IsUpgradeActive) {
  545. Flag_To_Redraw(false);
  546. IsToRedraw = true;
  547. if (!IsUpgradeActive) {
  548. Set_Default_Mouse(MOUSE_NORMAL, false);
  549. }
  550. }
  551. return(old);
  552. }
  553. /***********************************************************************************************
  554. * SidebarClass::Activate_Demolish -- Controls the demolish button on the sidebar. *
  555. * *
  556. * Use this routine to turn the demolish/dismantle sidebar button on and off. Typically, *
  557. * the button is enabled when a friendly building is selected and disabled otherwise. *
  558. * *
  559. * INPUT: control -- The controls how the button is to be activated or deactivated; *
  560. * 0 -- Turn button off. *
  561. * 1 -- Turn button on. *
  562. * -1 -- Toggle button state. *
  563. * *
  564. * OUTPUT: bool; Was the button previously activated? *
  565. * *
  566. * WARNINGS: none *
  567. * *
  568. * HISTORY: *
  569. * 12/24/1994 JLB : Created. *
  570. *=============================================================================================*/
  571. bool SidebarClass::Activate_Demolish(int control)
  572. {
  573. bool old = IsDemolishActive;
  574. if (control == -1) {
  575. control = IsDemolishActive ? 0 : 1;
  576. }
  577. switch (control) {
  578. case 1:
  579. IsDemolishActive = true;
  580. break;
  581. default:
  582. case 0:
  583. IsDemolishActive = false;
  584. break;
  585. }
  586. if (old != IsDemolishActive) {
  587. Flag_To_Redraw(false);
  588. IsToRedraw = true;
  589. if (!IsDemolishActive) {
  590. Set_Default_Mouse(MOUSE_NORMAL, false);
  591. }
  592. }
  593. return(old);
  594. }
  595. /***********************************************************************************************
  596. * SidebarClass::Add -- Adds a game object to the sidebar list. *
  597. * *
  598. * This routine is used to add a game object to the sidebar. Call this routine when a *
  599. * factory type building is created. It handles the case of adding an item that has already *
  600. * been added -- it just ignores it. *
  601. * *
  602. * INPUT: object -- Pointer to the object that is being added. *
  603. * *
  604. * OUTPUT: bool; Was the object added to the sidebar? *
  605. * *
  606. * WARNINGS: none *
  607. * *
  608. * HISTORY: *
  609. * 11/17/1994 JLB : Created. *
  610. * 9/24/2019 3:17PM : Added via capture parameter for new sidebar functionality *
  611. *=============================================================================================*/
  612. bool SidebarClass::Add(RTTIType type, int id, bool via_capture)
  613. {
  614. assert((unsigned)type < RTTI_COUNT);
  615. /*
  616. ** Add the sidebar only if we're not in editor mode.
  617. */
  618. if (!Debug_Map) {
  619. int column = Which_Column(type);
  620. if (Column[column].Add(type, id, via_capture)) {
  621. Activate(1);
  622. IsToRedraw = true;
  623. Flag_To_Redraw(false);
  624. return(true);
  625. }
  626. return(false);
  627. }
  628. return(false);
  629. }
  630. /***********************************************************************************************
  631. * SidebarClass::Scroll -- Handles scrolling the sidebar object strip. *
  632. * *
  633. * This routine is used to scroll the sidebar strip of objects. The strip appears whenever *
  634. * a building is selected that can produce units. If the number of units to produce is *
  635. * greater than what the sidebar can hold, this routine is used to scroll the other object *
  636. * into view so they can be selected. *
  637. * *
  638. * INPUT: up -- Should the scroll be upwards? Upward scrolling reveals object that are *
  639. * later in the list of objects. *
  640. * *
  641. * OUTPUT: bool; Did scrolling occur? *
  642. * *
  643. * WARNINGS: none *
  644. * *
  645. * HISTORY: *
  646. * 10/28/94 JLB : Created. *
  647. *=============================================================================================*/
  648. bool SidebarClass::Scroll(bool up, int column)
  649. {
  650. if (column == -1) {
  651. bool scr = false;
  652. scr |= Column[0].Scroll(up);
  653. scr |= Column[1].Scroll(up);
  654. if (!scr) {
  655. Sound_Effect(VOC_SCOLD);
  656. }
  657. if (scr) {
  658. IsToRedraw = true;
  659. Flag_To_Redraw(false);
  660. return(true);
  661. }
  662. return(false);
  663. }
  664. if (Column[column].Scroll(up)) {
  665. // No need to redraw the whole sidebar juts because we scrolled a strip is there? ST - 10/15/96 7:29PM
  666. //IsToRedraw = true;
  667. Flag_To_Redraw(false);
  668. return(true);
  669. }
  670. return(false);
  671. }
  672. /***********************************************************************************************
  673. * SidebarClass::Draw_It -- Renders the sidebar display. *
  674. * *
  675. * This routine performs the actual drawing of the sidebar display. *
  676. * *
  677. * INPUT: none *
  678. * *
  679. * OUTPUT: bool; Was the sidebar imagery changed at all? *
  680. * *
  681. * WARNINGS: none *
  682. * *
  683. * HISTORY: *
  684. * 10/28/94 JLB : Created. *
  685. * 12/31/1994 JLB : Split rendering off into the sidebar strip class. *
  686. *=============================================================================================*/
  687. void SidebarClass::Draw_It(bool complete)
  688. {
  689. PowerClass::Draw_It(complete);
  690. BStart(BENCH_SIDEBAR);
  691. if (IsSidebarActive && (IsToRedraw || complete) && !Debug_Map) {
  692. IsToRedraw = false;
  693. if (LogicPage->Lock()) {
  694. /*
  695. ** Draw the outline box around the sidebar buttons.
  696. */
  697. int shape = complete ? 0 : 1;
  698. /*
  699. ** The sidebar shape is too big in 640x400 so it needs to be drawn in three chunks.
  700. */
  701. CC_Draw_Shape(SidebarShape, 0, SIDE_X * RESFACTOR, 8*RESFACTOR, WINDOW_MAIN, SHAPE_WIN_REL);
  702. CC_Draw_Shape(SidebarMiddleShape, shape, SIDE_X * RESFACTOR, (8+80)*RESFACTOR, WINDOW_MAIN, SHAPE_WIN_REL);
  703. CC_Draw_Shape(SidebarBottomShape, shape, SIDE_X * RESFACTOR, (8+80+50)*RESFACTOR, WINDOW_MAIN, SHAPE_WIN_REL);
  704. Repair.Draw_Me(true);
  705. Upgrade.Draw_Me(true);
  706. Zoom.Draw_Me(true);
  707. LogicPage->Unlock();
  708. }
  709. }
  710. /*
  711. ** Draw the side strip elements by calling their respective draw functions.
  712. */
  713. if (IsSidebarActive) {
  714. Column[0].Draw_It(complete);
  715. Column[1].Draw_It(complete);
  716. if (complete || IsToRedraw) {
  717. Repair.Draw_Me(true);
  718. Upgrade.Draw_Me(true);
  719. Zoom.Draw_Me(true);
  720. }
  721. }
  722. IsToRedraw = false;
  723. BEnd(BENCH_SIDEBAR);
  724. }
  725. /***********************************************************************************************
  726. * SidebarClass::AI -- Handles player clicking on sidebar area. *
  727. * *
  728. * This routine handles the processing necessary when the player clicks on the sidebar. *
  729. * Typically, this is selection of the item to build. *
  730. * *
  731. * INPUT: input -- Reference to the keyboard input value. *
  732. * *
  733. * x,y -- Mouse coordinates at time of input. *
  734. * *
  735. * OUTPUT: bool; Was the click handled? *
  736. * *
  737. * WARNINGS: none *
  738. * *
  739. * HISTORY: *
  740. * 10/28/94 JLB : Created. *
  741. * 11/11/1994 JLB : Processes input directly. *
  742. * 12/26/1994 JLB : Uses factory manager class for construction handling. *
  743. * 12/31/1994 JLB : Simplified to use the sidebar strip class handlers. *
  744. * 12/31/1994 JLB : Uses mouse coordinate parameters. *
  745. * 06/27/1995 JLB : <TAB> key toggles sidebar. *
  746. *=============================================================================================*/
  747. void SidebarClass::AI(KeyNumType & input, int x, int y)
  748. {
  749. bool redraw = false;
  750. //
  751. // We need to process the sidebar differently in multiplayer. ST - 8/7/2019 10:48AM
  752. //
  753. if (Session.Type == GAME_GLYPHX_MULTIPLAYER) {
  754. PowerClass::AI(input, x, y);
  755. return;
  756. }
  757. /*
  758. ** Toggle the sidebar in and out with the <TAB> key.
  759. */
  760. #ifndef WIN32
  761. if (input == KN_TAB) {
  762. Activate(-1);
  763. }
  764. #else
  765. if (!Debug_Map) {
  766. Activate(1); // Force the sidebar always on in Win95 mode
  767. }
  768. #endif //WIN32
  769. if (!Debug_Map) {
  770. Column[0].AI(input, x, y);
  771. Column[1].AI(input, x, y);
  772. }
  773. #ifdef NEVER
  774. if (IsSidebarActive && !Debug_Map) {
  775. if (input == KN_DOWN) {
  776. int scr = 0;
  777. scr |= Column[0].Scroll(false);
  778. scr |= Column[1].Scroll(false);
  779. if (!scr) {
  780. Sound_Effect(VOC_SCOLD);
  781. }
  782. redraw |= scr;
  783. input = KN_NONE;
  784. }
  785. if (input == KN_UP) {
  786. int scr = 0;
  787. scr |= Column[0].Scroll(true);
  788. scr |= Column[1].Scroll(true);
  789. if (!scr) {
  790. Sound_Effect(VOC_SCOLD);
  791. }
  792. redraw |= scr;
  793. input = KN_NONE;
  794. }
  795. }
  796. #endif
  797. if (IsSidebarActive) {
  798. /*
  799. ** If there are any buildings in the payer's inventory, then allow the repair
  800. ** option.
  801. */
  802. if (PlayerPtr->BScan) {
  803. Activate_Repair(true);
  804. } else {
  805. Activate_Repair(false);
  806. }
  807. if (input == (BUTTON_REPAIR|KN_BUTTON)) {
  808. Repair_Mode_Control(-1);
  809. }
  810. if (input == (BUTTON_ZOOM|KN_BUTTON)) {
  811. Zoom_Mode_Control();
  812. }
  813. if (input == (BUTTON_UPGRADE|KN_BUTTON)) {
  814. Sell_Mode_Control(-1);
  815. }
  816. if (redraw) {
  817. //IsToRedraw = true;
  818. Column[0].Flag_To_Redraw();
  819. Column[1].Flag_To_Redraw();
  820. Flag_To_Redraw(false);
  821. }
  822. }
  823. if ((!IsRepairMode) && Repair.IsOn) {
  824. Repair.Turn_Off();
  825. }
  826. if ((!IsSellMode) && Upgrade.IsOn) {
  827. Upgrade.Turn_Off();
  828. }
  829. PowerClass::AI(input, x, y);
  830. }
  831. /***********************************************************************************************
  832. * SidebarClass::Recalc -- Examines the sidebar data and updates it as necessary. *
  833. * *
  834. * Occasionally a factory gets destroyed. This routine must be called in such a case *
  835. * because it might be possible that sidebar object need to be removed. This routine will *
  836. * examine all existing objects in the sidebar class and if no possible factory can *
  837. * produce it, then it will be removed. *
  838. * *
  839. * INPUT: none *
  840. * *
  841. * OUTPUT: none *
  842. * *
  843. * WARNINGS: This routine is exhaustive and thus time consuming. Only call it when really *
  844. * necessary. Such as when a factory is destroyed rather than when a non-factory *
  845. * is destroyed. *
  846. * *
  847. * HISTORY: *
  848. * 11/30/1994 JLB : Created. *
  849. *=============================================================================================*/
  850. void SidebarClass::Recalc(void)
  851. {
  852. bool redraw = false;
  853. // Done elsewhere for new multiplayer. ST - 8/7/2019 10:49AM
  854. if (Session.Type == GAME_GLYPHX_MULTIPLAYER) {
  855. return;
  856. }
  857. redraw |= Column[0].Recalc();
  858. redraw |= Column[1].Recalc();
  859. if (redraw) {
  860. IsToRedraw = true;
  861. Flag_To_Redraw(false);
  862. }
  863. }
  864. /***********************************************************************************************
  865. * SidebarClass::Activate -- Controls the sidebar activation. *
  866. * *
  867. * Use this routine to turn the sidebar on or off. This routine handles updating the *
  868. * necessary flags. *
  869. * *
  870. * INPUT: control -- Tells what to do with the sidebar according to the following: *
  871. * 0 = Turn sidebar off. *
  872. * 1 = Turn sidebar on. *
  873. * -1= Toggle sidebar on or off. *
  874. * *
  875. * OUTPUT: bool; Was the sidebar already on? *
  876. * *
  877. * WARNINGS: none *
  878. * *
  879. * HISTORY: *
  880. * 12/09/1994 JLB : Created. *
  881. *=============================================================================================*/
  882. bool SidebarClass::Activate(int control)
  883. {
  884. //
  885. // We don't want the original sidebar to be visible. ST - 1/31/2019 11:28AM
  886. //
  887. if (control < 100) {
  888. return IsSidebarActive;
  889. }
  890. bool old = IsSidebarActive;
  891. if (Session.Play)
  892. return (old);
  893. /*
  894. ** Determine the new state of the sidebar.
  895. */
  896. switch (control) {
  897. case -1:
  898. IsSidebarActive = IsSidebarActive == false;
  899. break;
  900. case 1:
  901. IsSidebarActive = true;
  902. break;
  903. default:
  904. case 0:
  905. IsSidebarActive = false;
  906. break;
  907. }
  908. /*
  909. ** Only if there is a change in the state of the sidebar will anything
  910. ** be done to change it.
  911. */
  912. if (IsSidebarActive != old) {
  913. /*
  914. ** If the sidebar is activated but was on the right side of the screen, then
  915. ** activate it on the left side of the screen.
  916. */
  917. if (IsSidebarActive /*&& X*/) {
  918. Set_View_Dimensions(0, 8 * RESFACTOR, ((320-SIDE_WIDTH)/ICON_PIXEL_W) * RESFACTOR);
  919. IsToRedraw = true;
  920. Help_Text(TXT_NONE);
  921. Repair.Zap();
  922. Add_A_Button(Repair);
  923. Upgrade.Zap();
  924. Add_A_Button(Upgrade);
  925. Zoom.Zap();
  926. Add_A_Button(Zoom);
  927. Column[0].Activate();
  928. Column[1].Activate();
  929. Background.Zap();
  930. Add_A_Button(Background);
  931. Map.RadarButton.Zap();
  932. Add_A_Button(Map.RadarButton);
  933. Map.PowerButton.Zap();
  934. Add_A_Button(Map.PowerButton);
  935. } else {
  936. Help_Text(TXT_NONE);
  937. Set_View_Dimensions(0, 8 * RESFACTOR);
  938. Remove_A_Button(Repair);
  939. Remove_A_Button(Upgrade);
  940. Remove_A_Button(Zoom);
  941. Remove_A_Button(Background);
  942. Column[0].Deactivate();
  943. Column[1].Deactivate();
  944. Remove_A_Button(Map.RadarButton);
  945. Remove_A_Button(Map.PowerButton);
  946. }
  947. /*
  948. ** Since the sidebar status has changed, update the map so that the graphics
  949. ** will be rendered correctly.
  950. */
  951. Flag_To_Redraw(true);
  952. }
  953. return(old);
  954. }
  955. /***********************************************************************************************
  956. * SidebarClass::StripClass::StripClass -- Default constructor for the side strip class. *
  957. * *
  958. * This constructor is used to reset the side strip to default empty state. *
  959. * *
  960. * INPUT: none *
  961. * *
  962. * OUTPUT: none *
  963. * *
  964. * WARNINGS: none *
  965. * *
  966. * HISTORY: *
  967. * 12/31/1994 JLB : Created. *
  968. *=============================================================================================*/
  969. SidebarClass::StripClass::StripClass(InitClass const & ) :
  970. X(0),
  971. Y(0),
  972. ID(0),
  973. IsToRedraw(true),
  974. IsBuilding(false),
  975. IsScrollingDown(false),
  976. IsScrolling(false),
  977. Flasher(-1),
  978. TopIndex(0),
  979. Scroller(0),
  980. Slid(0),
  981. BuildableCount(0)
  982. {
  983. for (int index = 0; index < MAX_BUILDABLES; index++) {
  984. Buildables[index].BuildableID = 0;
  985. Buildables[index].BuildableType = RTTI_NONE;
  986. Buildables[index].Factory = -1;
  987. Buildables[index].BuildableViaCapture = false; // Added for new sidebar functionality. ST - 9/24/2019 3:10PM
  988. }
  989. }
  990. /***********************************************************************************************
  991. * SidebarClass::StripClass::One_Time -- Performs one time actions necessary for the side stri *
  992. * *
  993. * Call this routine ONCE at the beginning of the game. It handles retrieving pointers to *
  994. * the shape files it needs for rendering. *
  995. * *
  996. * INPUT: none *
  997. * *
  998. * OUTPUT: none *
  999. * *
  1000. * WARNINGS: none *
  1001. * *
  1002. * HISTORY: *
  1003. * 12/31/1994 JLB : Created. *
  1004. *=============================================================================================*/
  1005. void SidebarClass::StripClass::One_Time(int )
  1006. {
  1007. /*
  1008. ** Sidebar is player team specific in Hires
  1009. */
  1010. ClockShapes = MFCD::Retrieve("CLOCK.SHP");
  1011. for (SpecialWeaponType lp = SPC_FIRST; lp < SPC_COUNT; lp++) {
  1012. char buffer[_MAX_FNAME];
  1013. sprintf(buffer, "%sICON", SpecialWeaponFile[lp]);
  1014. char fullname[_MAX_FNAME+_MAX_EXT];
  1015. _makepath(fullname, NULL, NULL, buffer, ".SHP");
  1016. SpecialShapes[lp] = MFCD::Retrieve(fullname);
  1017. }
  1018. }
  1019. /***********************************************************************************************
  1020. * SidebarClass::StripClass::Get_Special_Cameo -- Fetches the special event cameo shape. *
  1021. * *
  1022. * This routine will return with a pointer to the cameo data for the special objects that *
  1023. * can appear on the sidebar (e.g., nuclear bomb). *
  1024. * *
  1025. * INPUT: type -- The special type to fetch the cameo imagery for. *
  1026. * *
  1027. * OUTPUT: Returns with a pointer to the cameo imagery for the specified special object. *
  1028. * *
  1029. * WARNINGS: none *
  1030. * *
  1031. * HISTORY: *
  1032. * 05/19/1995 JLB : commented *
  1033. *=============================================================================================*/
  1034. void const * SidebarClass::StripClass::Get_Special_Cameo(SpecialWeaponType type)
  1035. {
  1036. if ((unsigned)type < SPC_COUNT) {
  1037. return(SpecialShapes[type]);
  1038. }
  1039. return(0);
  1040. }
  1041. /***********************************************************************************************
  1042. * SidebarClass::StripClass::Init_Clear -- Sets sidebar to a known (and deactivated) state *
  1043. * *
  1044. * INPUT: none *
  1045. * *
  1046. * OUTPUT: none *
  1047. * *
  1048. * WARNINGS: none *
  1049. * *
  1050. * HISTORY: *
  1051. * 12/24/1994 JLB : Created. *
  1052. *=============================================================================================*/
  1053. void SidebarClass::StripClass::Init_Clear(void)
  1054. {
  1055. IsScrollingDown = false;
  1056. IsScrolling = false;
  1057. IsBuilding = false;
  1058. Flasher = -1;
  1059. TopIndex = 0;
  1060. Slid = 0;
  1061. BuildableCount = 0;
  1062. /*
  1063. ** Since we're resetting the strips, clear out all the buildables & factory pointers.
  1064. */
  1065. for (int index = 0; index < MAX_BUILDABLES; index++) {
  1066. Buildables[index].BuildableID = 0;
  1067. Buildables[index].BuildableType = RTTI_NONE;
  1068. Buildables[index].Factory = -1;
  1069. Buildables[index].BuildableViaCapture = false; // Added for new sidebar functionality. ST - 9/24/2019 3:10PM
  1070. }
  1071. }
  1072. /***********************************************************************************************
  1073. * SidebarClass::StripClass::Init_IO -- Initializes the strip's buttons *
  1074. * *
  1075. * This routine doesn't actually add any buttons to the list. *
  1076. * *
  1077. * INPUT: none *
  1078. * *
  1079. * OUTPUT: none *
  1080. * *
  1081. * WARNINGS: none *
  1082. * *
  1083. * HISTORY: *
  1084. * 12/24/1994 JLB : Created. *
  1085. *=============================================================================================*/
  1086. void SidebarClass::StripClass::Init_IO(int id)
  1087. {
  1088. ID = id;
  1089. UpButton[ID].IsSticky = true;
  1090. UpButton[ID].ID = BUTTON_UP+id;
  1091. UpButton[ID].X = X+(UP_X_OFFSET * RESFACTOR);
  1092. UpButton[ID].Y = Y+(UP_Y_OFFSET * RESFACTOR);
  1093. #if (FRENCH)
  1094. #ifdef WIN32
  1095. UpButton[ID].Set_Shape(MFCD::Retrieve("STRIPUP.SHP"));
  1096. #else
  1097. UpButton[ID].Set_Shape(MFCD::Retrieve("STUP_FIX.SHP"));
  1098. #endif
  1099. #else //FRENCH
  1100. UpButton[ID].Set_Shape(MFCD::Retrieve("STRIPUP.SHP"));
  1101. #endif //FRENCH
  1102. DownButton[ID].IsSticky = true;
  1103. DownButton[ID].ID = BUTTON_DOWN+id;
  1104. DownButton[ID].X = X+(DOWN_X_OFFSET * RESFACTOR);
  1105. DownButton[ID].Y = Y+(DOWN_Y_OFFSET * RESFACTOR);
  1106. /*
  1107. ** Buttons are in a slightly different position in the new sidebar
  1108. */
  1109. UpButton[ID].Y--;
  1110. DownButton[ID].Y--;
  1111. DownButton[ID].Set_Shape(MFCD::Retrieve("STRIPDN.SHP"));
  1112. for (int index = 0; index < MAX_VISIBLE; index++) {
  1113. SelectClass & g = SelectButton[ID][index];
  1114. g.ID = BUTTON_SELECT;
  1115. g.X = X;
  1116. g.Y = Y + ((OBJECT_HEIGHT*index) * RESFACTOR);
  1117. g.Width = OBJECT_WIDTH * RESFACTOR;
  1118. g.Height = OBJECT_HEIGHT * RESFACTOR;
  1119. g.Set_Owner(*this, index);
  1120. }
  1121. }
  1122. /***********************************************************************************************
  1123. * SidebarClass::StripClass::Init_Theater -- Performs theater-specific initialization *
  1124. * *
  1125. * INPUT: theater *
  1126. * *
  1127. * OUTPUT: none *
  1128. * *
  1129. * WARNINGS: none *
  1130. * *
  1131. * HISTORY: *
  1132. * 12/24/1994 JLB : Created. *
  1133. *=============================================================================================*/
  1134. void SidebarClass::StripClass::Init_Theater(TheaterType theater)
  1135. {
  1136. Reload_LogoShapes();
  1137. if ( (theater != THEATER_NONE) && (theater != ::LastTheater)) {
  1138. static TLucentType const ClockCols[1] = {
  1139. {GREEN, BLACK, 100, 0}
  1140. // {GREEN, LTGREY, 180, 0}
  1141. };
  1142. /*
  1143. ** Make sure that remapping doesn't occur on the colors that cycle.
  1144. */
  1145. PaletteClass pal = OriginalPalette;
  1146. memset(&pal[CYCLE_COLOR_START*3], 0x3f, CYCLE_COLOR_COUNT*3);
  1147. Build_Translucent_Table(pal, &ClockCols[0], 1, (void*)ClockTranslucentTable);
  1148. // Mem_Copy(GamePalette, OriginalPalette, 768);
  1149. // memset(&GamePalette[CYCLE_COLOR_START*3], 0x3f, CYCLE_COLOR_COUNT*3);
  1150. /*
  1151. ** Create the translucent table used for the sidebar.
  1152. */
  1153. // Build_Translucent_Table(GamePalette, &ClockCols[0], 1, (void*)ClockTranslucentTable);
  1154. // GamePalette = OriginalPalette;
  1155. Conquer_Build_Fading_Table(GamePalette, &ClockTranslucentTable[256], BLACK, 100);
  1156. }
  1157. }
  1158. void SidebarClass::StripClass::Reload_LogoShapes(void)
  1159. {
  1160. /*
  1161. ** Load hi-res strip art here since it is player side specific
  1162. */
  1163. static char * stripnames[]={
  1164. "stripna.shp", //Nato
  1165. "stripna.shp",
  1166. "stripus.shp", //USSR
  1167. "stripna.shp",
  1168. "stripus.shp", //UKRAINE
  1169. "stripna.shp",
  1170. "stripna.shp",
  1171. "stripna.shp",
  1172. "stripna.shp", //HOUSE_GOOD
  1173. "stripus.shp", //HOUSE_BAD
  1174. };
  1175. int houseloaded = 0;
  1176. /*
  1177. ** Sidebar art is dependent on the side of the player
  1178. */
  1179. if(PlayerPtr) {
  1180. houseloaded = PlayerPtr->ActLike;
  1181. }
  1182. LogoShapes = (void*)MFCD::Retrieve(stripnames[houseloaded]);
  1183. }
  1184. /***********************************************************************************************
  1185. * SidebarClass::StripClass::Activate -- Adds the strip buttons to the input system. *
  1186. * *
  1187. * This routine will add the side strip buttons to the map's input system. This routine *
  1188. * should be called once when the sidebar activates. *
  1189. * *
  1190. * INPUT: none *
  1191. * *
  1192. * OUTPUT: none *
  1193. * *
  1194. * WARNINGS: Never call this routine a second time without first calling Deactivate(). *
  1195. * *
  1196. * HISTORY: *
  1197. * 01/19/1995 JLB : Created. *
  1198. *=============================================================================================*/
  1199. void SidebarClass::StripClass::Activate(void)
  1200. {
  1201. UpButton[ID].Zap();
  1202. Map.Add_A_Button(UpButton[ID]);
  1203. DownButton[ID].Zap();
  1204. Map.Add_A_Button(DownButton[ID]);
  1205. for (int index = 0; index < MAX_VISIBLE; index++) {
  1206. SelectButton[ID][index].Zap();
  1207. Map.Add_A_Button(SelectButton[ID][index]);
  1208. }
  1209. }
  1210. /***********************************************************************************************
  1211. * SidebarClass::StripClass::Deactivate -- Removes the side strip buttons from the input syste *
  1212. * *
  1213. * Call this routine to remove all the buttons on the side strip from the map's input *
  1214. * system. *
  1215. * *
  1216. * INPUT: none *
  1217. * *
  1218. * OUTPUT: none *
  1219. * *
  1220. * WARNINGS: Never call this routine unless the Activate() function was previously called. *
  1221. * *
  1222. * HISTORY: *
  1223. * 01/19/1995 JLB : Created. *
  1224. *=============================================================================================*/
  1225. void SidebarClass::StripClass::Deactivate(void)
  1226. {
  1227. Map.Remove_A_Button(UpButton[ID]);
  1228. Map.Remove_A_Button(DownButton[ID]);
  1229. for (int index = 0; index < MAX_VISIBLE; index++) {
  1230. Map.Remove_A_Button(SelectButton[ID][index]);
  1231. }
  1232. }
  1233. /***********************************************************************************************
  1234. * SidebarClass::StripClass::Add -- Add an object to the side strip. *
  1235. * *
  1236. * Use this routine to add a buildable object to the side strip. *
  1237. * *
  1238. * INPUT: object -- Pointer to the object type that can be built and is to be added to *
  1239. * the side strip. *
  1240. * *
  1241. * OUTPUT: bool; Was the object successfully added to the side strip? Failure could be the *
  1242. * result of running out of room in the side strip array or the object might *
  1243. * already be in the list. *
  1244. * *
  1245. * WARNINGS: none. *
  1246. * *
  1247. * HISTORY: *
  1248. * 12/31/1994 JLB : Created. *
  1249. * 9/24/2019 3:17PM : Added via capture parameter for new sidebar functionality *
  1250. *=============================================================================================*/
  1251. bool SidebarClass::StripClass::Add(RTTIType type, int id, bool via_capture)
  1252. {
  1253. if (BuildableCount <= MAX_BUILDABLES) {
  1254. for (int index = 0; index < BuildableCount; index++) {
  1255. if (Buildables[index].BuildableType == type && Buildables[index].BuildableID == id) {
  1256. return(false);
  1257. }
  1258. }
  1259. if (!ScenarioInit && type != RTTI_SPECIAL) {
  1260. Speak(VOX_NEW_CONSTRUCT);
  1261. }
  1262. Buildables[BuildableCount].BuildableType = type;
  1263. Buildables[BuildableCount].BuildableID = id;
  1264. Buildables[BuildableCount].BuildableViaCapture = via_capture;
  1265. BuildableCount++;
  1266. IsToRedraw = true;
  1267. return(true);
  1268. }
  1269. return(false);
  1270. }
  1271. /***********************************************************************************************
  1272. * SidebarClass::StripClass::Scroll -- Causes the side strip to scroll. *
  1273. * *
  1274. * Use this routine to flag the side strip to scroll. The direction scrolled is controlled *
  1275. * by the parameter. Scrolling is merely initiated by this routine. Subsequent calls to *
  1276. * the AI function and the Draw_It function are required to properly give the appearance *
  1277. * of scrolling. *
  1278. * *
  1279. * INPUT: bool; Should the side strip scroll UP? If it is to scroll down then pass false. *
  1280. * *
  1281. * OUTPUT: bool; Was the side strip started to scroll in the desired direction? *
  1282. * *
  1283. * WARNINGS: none *
  1284. * *
  1285. * HISTORY: *
  1286. * 12/31/1994 JLB : Created. *
  1287. * 07/29/1995 JLB : Simplified scrolling logic. *
  1288. *=============================================================================================*/
  1289. bool SidebarClass::StripClass::Scroll(bool up)
  1290. {
  1291. if (up) {
  1292. if (!TopIndex) return(false);
  1293. Scroller--;
  1294. } else {
  1295. if (TopIndex+MAX_VISIBLE >= BuildableCount) return(false);
  1296. Scroller++;
  1297. }
  1298. return(true);
  1299. }
  1300. /***********************************************************************************************
  1301. * SidebarClass::StripClass::Flag_To_Redra -- Flags the sidebar strip to be redrawn. *
  1302. * *
  1303. * This utility routine is called when something changes on the sidebar and it must be *
  1304. * reflected the next time drawing is performed. *
  1305. * *
  1306. * INPUT: none *
  1307. * *
  1308. * OUTPUT: none *
  1309. * *
  1310. * WARNINGS: none *
  1311. * *
  1312. * HISTORY: *
  1313. * 05/18/1995 JLB : Created. *
  1314. *=============================================================================================*/
  1315. void SidebarClass::StripClass::Flag_To_Redraw(void)
  1316. {
  1317. IsToRedraw = true;
  1318. //Map.SidebarClass::IsToRedraw = true;
  1319. Map.Flag_To_Redraw(false);
  1320. }
  1321. /***********************************************************************************************
  1322. * SidebarClass::StripClass::AI -- Input and AI processing for the side strip. *
  1323. * *
  1324. * The side strip AI processing is performed by this function. This function not only *
  1325. * checks for player input, but also handles any graphic logic updating necessary as a *
  1326. * result of flashing or construction animation. *
  1327. * *
  1328. * INPUT: input -- The player input code. *
  1329. * *
  1330. * x,y -- Mouse coordinate to use. *
  1331. * *
  1332. * OUTPUT: bool; Did the AI detect that it will need a rendering change? If this routine *
  1333. * returns true, then the Draw_It function should be called at the *
  1334. * earliest opportunity. *
  1335. * *
  1336. * WARNINGS: none *
  1337. * *
  1338. * HISTORY: *
  1339. * 12/31/1994 JLB : Created. *
  1340. * 12/31/1994 JLB : Uses mouse coordinate parameters. *
  1341. *=============================================================================================*/
  1342. bool SidebarClass::StripClass::AI(KeyNumType & input, int , int )
  1343. {
  1344. bool redraw = false;
  1345. /*
  1346. ** If this is scroll button for this side strip, then scroll the strip as
  1347. ** indicated.
  1348. */
  1349. if (input == (UpButton[ID].ID|KN_BUTTON)) { // && !IsScrolling
  1350. UpButton[ID].IsPressed = false;
  1351. if (!Scroll(true)) {
  1352. Sound_Effect(VOC_SCOLD);
  1353. }
  1354. }
  1355. if (input == (DownButton[ID].ID|KN_BUTTON)) { // && !IsScrolling
  1356. DownButton[ID].IsPressed = false;
  1357. if (!Scroll(false)) {
  1358. Sound_Effect(VOC_SCOLD);
  1359. }
  1360. }
  1361. /*
  1362. ** Reflect the scroll desired direction/value into the scroll
  1363. ** logic handler. This might result in up or down scrolling.
  1364. */
  1365. if (!IsScrolling && Scroller) {
  1366. if (BuildableCount <= MAX_VISIBLE) {
  1367. Scroller = 0;
  1368. } else {
  1369. /*
  1370. ** Top of list is moving toward lower ordered entries in the object list. It looks like
  1371. ** the "window" to the object list is moving up even though the actual object images are
  1372. ** scrolling downward.
  1373. */
  1374. if (Scroller < 0) {
  1375. if (!TopIndex) {
  1376. Scroller = 0;
  1377. } else {
  1378. Scroller++;
  1379. IsScrollingDown = false;
  1380. IsScrolling = true;
  1381. TopIndex--;
  1382. Slid = 0;
  1383. }
  1384. } else {
  1385. if (TopIndex+MAX_VISIBLE >= BuildableCount) {
  1386. Scroller = 0;
  1387. } else {
  1388. Scroller--;
  1389. Slid = OBJECT_HEIGHT;
  1390. IsScrollingDown = true;
  1391. IsScrolling = true;
  1392. }
  1393. }
  1394. }
  1395. }
  1396. /*
  1397. ** Scroll logic is handled here.
  1398. */
  1399. if (IsScrolling) {
  1400. if (IsScrollingDown) {
  1401. Slid -= SCROLL_RATE;
  1402. if (Slid <= 0) {
  1403. IsScrolling = false;
  1404. Slid = 0;
  1405. TopIndex++;
  1406. }
  1407. } else {
  1408. Slid += SCROLL_RATE;
  1409. if (Slid >= OBJECT_HEIGHT) {
  1410. IsScrolling = false;
  1411. Slid = 0;
  1412. }
  1413. }
  1414. redraw = true;
  1415. }
  1416. /*
  1417. ** Handle any flashing logic. Flashing occurs when the player selects an object
  1418. ** and provides the visual feedback of a recognized and legal selection.
  1419. */
  1420. if (Flasher != -1) {
  1421. if (Graphic_Logic()) {
  1422. redraw = true;
  1423. if (Fetch_Stage() >= 7) {
  1424. Set_Rate(0);
  1425. Set_Stage(0);
  1426. Flasher = -1;
  1427. }
  1428. }
  1429. }
  1430. /*
  1431. ** Handle any building clock animation logic.
  1432. */
  1433. if (IsBuilding) {
  1434. for (int index = 0; index < BuildableCount; index++) {
  1435. int factoryid = Buildables[index].Factory;
  1436. if (factoryid != -1) {
  1437. FactoryClass * factory = Factories.Raw_Ptr(factoryid);
  1438. if (factory && (factory->Has_Changed() || factory->Is_Blocked())) {
  1439. redraw = true;
  1440. if (factory->Has_Completed()) {
  1441. /*
  1442. ** Construction has been completed. Announce this fact to the player and
  1443. ** try to get the object to automatically leave the factory. Buildings are
  1444. ** the main exception to the ability to leave the factory under their own
  1445. ** power.
  1446. */
  1447. TechnoClass * pending = factory->Get_Object();
  1448. if (pending != NULL) {
  1449. switch (pending->What_Am_I()) {
  1450. case RTTI_VESSEL:
  1451. case RTTI_UNIT:
  1452. case RTTI_AIRCRAFT:
  1453. OutList.Add(EventClass(EventClass::PLACE, pending->What_Am_I(), -1));
  1454. if (!factory->Is_Blocked()) {
  1455. Speak(VOX_UNIT_READY);
  1456. }
  1457. break;
  1458. case RTTI_BUILDING:
  1459. Speak(VOX_CONSTRUCTION);
  1460. break;
  1461. case RTTI_INFANTRY:
  1462. OutList.Add(EventClass(EventClass::PLACE, pending->What_Am_I(), -1));
  1463. if (!factory->Is_Blocked()) {
  1464. Speak(VOX_UNIT_READY);
  1465. }
  1466. break;
  1467. }
  1468. }
  1469. }
  1470. }
  1471. }
  1472. }
  1473. }
  1474. /*
  1475. ** If any of the logic determined that this side strip needs to be redrawn, then
  1476. ** set the redraw flag for this side strip.
  1477. */
  1478. if (redraw) {
  1479. Flag_To_Redraw();
  1480. }
  1481. return(redraw);
  1482. }
  1483. /***********************************************************************************************
  1484. * SidebarClass::StripClass::Draw_It -- Render the sidebar display. *
  1485. * *
  1486. * Use this routine to render the sidebar display. It checks to see if it needs to be *
  1487. * redrawn and only redraw if necessary. If the "complete" parameter is true, then it *
  1488. * will force redraw the entire strip. *
  1489. * *
  1490. * INPUT: complete -- Should the redraw be forced? A force redraw will ignore the redraw *
  1491. * flag. *
  1492. * *
  1493. * OUTPUT: none *
  1494. * *
  1495. * WARNINGS: none *
  1496. * *
  1497. * HISTORY: *
  1498. * 12/31/1994 JLB : Created. *
  1499. * 08/06/1995 JLB : Handles multi factory tracking in same strip. *
  1500. *=============================================================================================*/
  1501. void SidebarClass::StripClass::Draw_It(bool complete)
  1502. {
  1503. if (IsToRedraw || complete) {
  1504. IsToRedraw = false;
  1505. if (RunningAsDLL) {
  1506. return;
  1507. }
  1508. SidebarRedraws++;
  1509. /*
  1510. ** Fills the background to the side strip. We shouldnt need to do this if the strip
  1511. ** has a full complement of icons.
  1512. */
  1513. /*
  1514. ** New sidebar needs to be drawn not filled
  1515. */
  1516. if (BuildableCount < MAX_VISIBLE) {
  1517. CC_Draw_Shape(LogoShapes, ID, X+(2*RESFACTOR), Y, WINDOW_MAIN, SHAPE_WIN_REL|SHAPE_NORMAL, 0);
  1518. }
  1519. /*
  1520. ** Redraw the scroll buttons.
  1521. */
  1522. UpButton[ID].Draw_Me(true);
  1523. DownButton[ID].Draw_Me(true);
  1524. /*
  1525. ** Loop through all the buildable objects that are visible in the strip and render
  1526. ** them. Their Y offset may be adjusted if the strip is in the process of scrolling.
  1527. */
  1528. for (int i = 0; i < MAX_VISIBLE + (IsScrolling ? 1 : 0); i++) {
  1529. bool production;
  1530. bool completed;
  1531. int stage;
  1532. bool darken = false;
  1533. void const * shapefile = 0;
  1534. int shapenum = 0;
  1535. void const * remapper = 0;
  1536. FactoryClass * factory = 0;
  1537. int index = i+TopIndex;
  1538. int x = X;
  1539. int y = Y + (i*OBJECT_HEIGHT * RESFACTOR);
  1540. /*
  1541. ** If the strip is scrolling, then the offset is adjusted accordingly.
  1542. */
  1543. if (IsScrolling) {
  1544. y -= (OBJECT_HEIGHT - Slid) * RESFACTOR;
  1545. // y -= OBJECT_HEIGHT - Slid;
  1546. }
  1547. /*
  1548. ** Fetch the shape number for the object type located at this current working
  1549. ** slot. This shape pointer is used to draw the underlying graphic there.
  1550. */
  1551. if (index < BuildableCount) {
  1552. ObjectTypeClass const * obj = NULL;
  1553. SpecialWeaponType spc = SPC_NONE;
  1554. if (Buildables[index].BuildableType != RTTI_SPECIAL) {
  1555. obj = Fetch_Techno_Type(Buildables[index].BuildableType, Buildables[index].BuildableID);
  1556. if (obj != NULL) {
  1557. /*
  1558. ** Fetch the remap table that is appropriate for this object
  1559. ** type.
  1560. */
  1561. remapper = PlayerPtr->Remap_Table(false, ((TechnoTypeClass const *)obj)->Remap);
  1562. /*
  1563. ** If there is already a factory producing this kind of object, then all
  1564. ** objects of this type are displays in a disabled state.
  1565. */
  1566. bool isbusy = (PlayerPtr->Fetch_Factory(Buildables[index].BuildableType) != NULL);
  1567. if (!isbusy && PlayerPtr->Is_Hack_Prevented(Buildables[index].BuildableType, Buildables[index].BuildableID)) {
  1568. isbusy = true;
  1569. }
  1570. /*
  1571. ** Infantry don't get remapped in the sidebar (special case).
  1572. */
  1573. if (Buildables[index].BuildableType == RTTI_INFANTRYTYPE) {
  1574. remapper = 0;
  1575. }
  1576. shapefile = obj->Get_Cameo_Data();
  1577. shapenum = 0;
  1578. if (Buildables[index].Factory != -1) {
  1579. factory = Factories.Raw_Ptr(Buildables[index].Factory);
  1580. production = true;
  1581. completed = factory->Has_Completed();
  1582. stage = factory->Completion();
  1583. darken = false;
  1584. } else {
  1585. production = false;
  1586. // darken = IsBuilding;
  1587. /*
  1588. ** Darken the imagery if a factory of a matching type is
  1589. ** already busy.
  1590. */
  1591. darken = isbusy;
  1592. }
  1593. } else {
  1594. darken = PlayerPtr->Is_Hack_Prevented(Buildables[index].BuildableType, Buildables[index].BuildableID);
  1595. }
  1596. } else {
  1597. spc = SpecialWeaponType(Buildables[index].BuildableID);
  1598. shapefile = Get_Special_Cameo(spc);
  1599. shapenum = 0;
  1600. production = true;
  1601. completed = PlayerPtr->SuperWeapon[spc].Is_Ready();
  1602. stage = PlayerPtr->SuperWeapon[spc].Anim_Stage();
  1603. darken = false;
  1604. }
  1605. if (obj != NULL || spc != SPC_NONE) {
  1606. /*
  1607. ** If this item is flashing then take care of it.
  1608. **
  1609. */
  1610. if (Flasher == index && (Fetch_Stage() & 0x01)) {
  1611. remapper = Map.FadingLight;
  1612. }
  1613. } else {
  1614. shapefile = LogoShapes;
  1615. if (!darken) {
  1616. shapenum = SB_BLANK;
  1617. }
  1618. }
  1619. } else {
  1620. shapefile = LogoShapes;
  1621. shapenum = SB_BLANK;
  1622. production = false;
  1623. }
  1624. remapper = 0;
  1625. /*
  1626. ** Now that the shape of the object at the current working slot has been found,
  1627. ** draw it and any graphic overlays as necessary.
  1628. **
  1629. ** Don't draw blank shapes over the new 640x400 sidebar art - ST 5/1/96 6:01PM
  1630. */
  1631. if (shapenum != SB_BLANK || shapefile != LogoShapes) {
  1632. CC_Draw_Shape(shapefile, shapenum,
  1633. x-(WindowList[WINDOW_SIDEBAR][WINDOWX])+(LEFT_EDGE_OFFSET * RESFACTOR),
  1634. y-WindowList[WINDOW_SIDEBAR][WINDOWY],
  1635. WINDOW_SIDEBAR,
  1636. SHAPE_NORMAL|SHAPE_WIN_REL| (remapper ? SHAPE_FADING : SHAPE_NORMAL),
  1637. remapper);
  1638. /*
  1639. ** Darken this object because it cannot be produced or is otherwise
  1640. ** unavailable.
  1641. */
  1642. if (darken) {
  1643. CC_Draw_Shape(ClockShapes, 0,
  1644. x-(WindowList[WINDOW_SIDEBAR][WINDOWX])+(LEFT_EDGE_OFFSET * RESFACTOR),
  1645. y-WindowList[WINDOW_SIDEBAR][WINDOWY],
  1646. WINDOW_SIDEBAR,
  1647. SHAPE_NORMAL|SHAPE_WIN_REL|SHAPE_GHOST,
  1648. NULL, ClockTranslucentTable);
  1649. }
  1650. }
  1651. /*
  1652. ** Draw the overlapping clock shape if this is object is being constructed.
  1653. ** If the object is completed, then display "Ready" with no clock shape.
  1654. */
  1655. if (production) {
  1656. if (completed) {
  1657. /*
  1658. ** Display text showing that the object is ready to place.
  1659. */
  1660. CC_Draw_Shape(ObjectTypeClass::PipShapes, PIP_READY,
  1661. (x-(WindowList[WINDOW_SIDEBAR][WINDOWX]))+(LEFT_EDGE_OFFSET+15) * RESFACTOR,
  1662. (y-WindowList[WINDOW_SIDEBAR][WINDOWY])+(4 * RESFACTOR),
  1663. WINDOW_SIDEBAR, SHAPE_CENTER);
  1664. } else {
  1665. CC_Draw_Shape(ClockShapes, stage+1,
  1666. x-(WindowList[WINDOW_SIDEBAR][WINDOWX])+(LEFT_EDGE_OFFSET * RESFACTOR),
  1667. y-WindowList[WINDOW_SIDEBAR][WINDOWY],
  1668. WINDOW_SIDEBAR,
  1669. SHAPE_NORMAL|SHAPE_WIN_REL|SHAPE_GHOST,
  1670. NULL, ClockTranslucentTable);
  1671. /*
  1672. ** Display text showing that the construction is temporarily on hold.
  1673. */
  1674. if (factory && !factory->Is_Building()) {
  1675. CC_Draw_Shape(ObjectTypeClass::PipShapes, PIP_HOLDING,
  1676. (x-(WindowList[WINDOW_SIDEBAR][WINDOWX])) + ((LEFT_EDGE_OFFSET+15) * RESFACTOR),
  1677. (y-WindowList[WINDOW_SIDEBAR][WINDOWY])+(4 * RESFACTOR),
  1678. WINDOW_SIDEBAR, SHAPE_CENTER);
  1679. }
  1680. }
  1681. }
  1682. }
  1683. LastSlid = Slid;
  1684. }
  1685. }
  1686. /***********************************************************************************************
  1687. * SidebarClass::StripClass::Recalc -- Revalidates the current sidebar list of objects. *
  1688. * *
  1689. * This routine will revalidate all the buildable objects in the sidebar. This routine *
  1690. * comes in handy when a factory has been destroyed, and the sidebar needs to reflect any *
  1691. * change that this requires. It checks every object to see if there is a factory available *
  1692. * that could produce it. If none can be found, then the object is removed from the *
  1693. * sidebar. *
  1694. * *
  1695. * INPUT: none *
  1696. * *
  1697. * OUTPUT: bool; The sidebar has changed as a result of this call? *
  1698. * *
  1699. * WARNINGS: none *
  1700. * *
  1701. * HISTORY: *
  1702. * 01/19/1995 JLB : Created. *
  1703. * 06/26/1995 JLB : Doesn't collapse sidebar when buildables removed. *
  1704. *=============================================================================================*/
  1705. bool SidebarClass::StripClass::Recalc(void)
  1706. {
  1707. int ok;
  1708. if (Debug_Map || !BuildableCount) {
  1709. return(false);
  1710. }
  1711. /*
  1712. ** Sweep through all objects listed in the sidebar. If any of those object can
  1713. ** not be created -- even in theory -- then they must be removed form the sidebar and
  1714. ** any current production must be abandoned.
  1715. */
  1716. bool redraw = false;
  1717. for (int index = 0; index < BuildableCount; index++) {
  1718. TechnoTypeClass const * tech = Fetch_Techno_Type(Buildables[index].BuildableType, Buildables[index].BuildableID);
  1719. if (tech != NULL) {
  1720. ok = tech->Who_Can_Build_Me(true, false, PlayerPtr->Class->House) != NULL;
  1721. } else {
  1722. if ((unsigned)Buildables[index].BuildableID < SPC_COUNT) {
  1723. ok = PlayerPtr->SuperWeapon[Buildables[index].BuildableID].Is_Present();
  1724. } else {
  1725. ok = false;
  1726. }
  1727. }
  1728. if (!ok) {
  1729. /*
  1730. ** Removes this entry from the list.
  1731. */
  1732. if (BuildableCount > 1 && index < BuildableCount-1) {
  1733. memcpy(&Buildables[index], &Buildables[index+1], sizeof(Buildables[0])*((BuildableCount-index)-1));
  1734. }
  1735. TopIndex = 0;
  1736. IsToRedraw = true;
  1737. redraw = true;
  1738. BuildableCount--;
  1739. index--;
  1740. }
  1741. }
  1742. #ifdef NEVER
  1743. /*
  1744. ** If there are no more buildable objects to display, make the sidebar go away.
  1745. */
  1746. if (!BuildableCount) {
  1747. Map.SidebarClass::Activate(0);
  1748. }
  1749. #endif
  1750. return(redraw);
  1751. }
  1752. /***********************************************************************************************
  1753. * SidebarClass::StripClass::SelectClass::SelectClass -- Default constructor. *
  1754. * *
  1755. * This is the default constructor for the button that controls the buildable cameos on *
  1756. * the sidebar strip. *
  1757. * *
  1758. * INPUT: none *
  1759. * *
  1760. * OUTPUT: none *
  1761. * *
  1762. * WARNINGS: The coordinates are set to zero by this routine. They must be set to the *
  1763. * correct values before this button will function. *
  1764. * *
  1765. * HISTORY: *
  1766. * 01/19/1995 JLB : Created. *
  1767. *=============================================================================================*/
  1768. SidebarClass::StripClass::SelectClass::SelectClass(void) :
  1769. ControlClass(0, 0, 0, (OBJECT_WIDTH-1) * RESFACTOR, OBJECT_HEIGHT * RESFACTOR, LEFTPRESS|RIGHTPRESS|LEFTUP),
  1770. Strip(0),
  1771. Index(0)
  1772. {
  1773. }
  1774. /***********************************************************************************************
  1775. * SidebarClass::StripClass::SelectClass:: -- Assigns special values to a buildable select but *
  1776. * *
  1777. * Use this routine to set custom buildable vars for this particular select button. It *
  1778. * uses this information to properly know what buildable object to start or stop production *
  1779. * on. *
  1780. * *
  1781. * INPUT: strip -- Reference to the strip that owns this buildable button. *
  1782. * *
  1783. * index -- The index (0 .. MAX_VISIBLE-1) of this button. This is used to let *
  1784. * the owning strip know what index this button refers to. *
  1785. * *
  1786. * OUTPUT: none *
  1787. * *
  1788. * WARNINGS: none *
  1789. * *
  1790. * HISTORY: *
  1791. * 01/19/1995 JLB : Created. *
  1792. *=============================================================================================*/
  1793. void SidebarClass::StripClass::SelectClass::Set_Owner(StripClass & strip, int index)
  1794. {
  1795. Strip = &strip;
  1796. Index = index;
  1797. X = strip.X;
  1798. Y = strip.Y + ((index * OBJECT_HEIGHT) * RESFACTOR);
  1799. }
  1800. /***********************************************************************************************
  1801. * SidebarClass::StripClass::SelectClass:: -- Action function when buildable cameo is selected *
  1802. * *
  1803. * This function is called when the buildable icon (cameo) is clicked on. It handles *
  1804. * starting and stopping production as indicated. *
  1805. * *
  1806. * INPUT: flags -- The input event that triggered the call. *
  1807. * *
  1808. * key -- The keyboard value at the time of the input. *
  1809. * *
  1810. * OUTPUT: Returns with whether the input list should be scanned further. *
  1811. * *
  1812. * WARNINGS: none *
  1813. * *
  1814. * HISTORY: *
  1815. * 01/19/1995 JLB : Created. *
  1816. * 10/09/1996 JLB : Sonar pulse converted to regular event type. *
  1817. *=============================================================================================*/
  1818. int SidebarClass::StripClass::SelectClass::Action(unsigned flags, KeyNumType & key)
  1819. {
  1820. int index = Strip->TopIndex + Index;
  1821. RTTIType otype = Strip->Buildables[index].BuildableType;
  1822. int oid = Strip->Buildables[index].BuildableID;
  1823. int fnumber = Strip->Buildables[index].Factory;
  1824. RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
  1825. ObjectTypeClass const * choice = NULL;
  1826. SpecialWeaponType spc = SPC_NONE;
  1827. /*
  1828. ** Determine the factory number that would apply to objects of the type
  1829. ** the mouse is currently addressing. This doesn't mean that the factory number
  1830. ** fetched is actually producing the indicated object, merely that that particular
  1831. ** kind of factory is specified by the "genfactory" value. This can be used to see
  1832. ** if the factory type is currently busy or not.
  1833. */
  1834. FactoryClass * factory = PlayerPtr->Fetch_Factory(otype);
  1835. Map.Override_Mouse_Shape(MOUSE_NORMAL);
  1836. if (index < Strip->BuildableCount) {
  1837. if (otype != RTTI_SPECIAL) {
  1838. choice = Fetch_Techno_Type(otype, oid);
  1839. } else {
  1840. spc = SpecialWeaponType(oid);
  1841. }
  1842. if (fnumber != -1) {
  1843. factory = Factories.Raw_Ptr(fnumber);
  1844. }
  1845. } else {
  1846. Map.Help_Text(TXT_NONE);
  1847. }
  1848. if (spc != SPC_NONE) {
  1849. /*
  1850. ** Display the help text if the mouse is over the button.
  1851. */
  1852. if (flags & LEFTUP) {
  1853. Map.Help_Text(SpecialWeaponHelp[spc], X, Y, scheme->Color, true);
  1854. flags &= ~LEFTUP;
  1855. }
  1856. /*
  1857. ** A right mouse button signals "cancel". If we are in targeting
  1858. ** mode then we don't want to be any more.
  1859. */
  1860. if (flags & RIGHTPRESS) {
  1861. Map.IsTargettingMode = SPC_NONE;
  1862. }
  1863. /*
  1864. ** A left mouse press signal "activate". If our weapon type is
  1865. ** available then we should activate it.
  1866. */
  1867. if (flags & LEFTPRESS) {
  1868. if ((unsigned)spc < SPC_COUNT) {
  1869. if (PlayerPtr->SuperWeapon[spc].Is_Ready()) {
  1870. if (spc != SPC_SONAR_PULSE) {
  1871. Map.IsTargettingMode = spc;
  1872. Unselect_All();
  1873. Speak(VOX_SELECT_TARGET);
  1874. } else {
  1875. OutList.Add(EventClass(EventClass::SPECIAL_PLACE, SPC_SONAR_PULSE, 0));
  1876. }
  1877. } else {
  1878. PlayerPtr->SuperWeapon[spc].Impatient_Click();
  1879. }
  1880. }
  1881. }
  1882. } else {
  1883. if (choice != NULL) {
  1884. /*
  1885. ** Display the help text if the mouse is over the button.
  1886. */
  1887. if (flags & LEFTUP) {
  1888. Map.Help_Text(choice->Full_Name(), X, Y, scheme->Color, true);
  1889. Map.Set_Cost(choice->Cost_Of() * PlayerPtr->CostBias);
  1890. flags &= ~LEFTUP;
  1891. }
  1892. /*
  1893. ** A right mouse button signals "cancel".
  1894. */
  1895. if (flags & RIGHTPRESS) {
  1896. /*
  1897. ** If production is in progress, put it on hold. If production is already
  1898. ** on hold, then abandon it. Money will be refunded, the factory
  1899. ** manager deleted, and the object under construction is returned to
  1900. ** the free pool.
  1901. */
  1902. if (factory != NULL) {
  1903. /*
  1904. ** Cancels placement mode if the sidebar factory is abandoned or
  1905. ** suspended.
  1906. */
  1907. if (Map.PendingObjectPtr && Map.PendingObjectPtr->Is_Techno()) {
  1908. Map.PendingObjectPtr = 0;
  1909. Map.PendingObject = 0;
  1910. Map.PendingHouse = HOUSE_NONE;
  1911. Map.Set_Cursor_Shape(0);
  1912. }
  1913. if (!factory->Is_Building()) {
  1914. Speak(VOX_CANCELED);
  1915. OutList.Add(EventClass(EventClass::ABANDON, otype, oid));
  1916. } else {
  1917. Speak(VOX_SUSPENDED);
  1918. OutList.Add(EventClass(EventClass::SUSPEND, otype, oid));
  1919. Map.Column[0].IsToRedraw = true;
  1920. Map.Column[1].IsToRedraw = true;
  1921. }
  1922. }
  1923. }
  1924. if (flags & LEFTPRESS) {
  1925. /*
  1926. ** If there is already a factory attached to this strip but the player didn't click
  1927. ** on the icon that has the attached factory, then say that the factory is busy and
  1928. ** ignore the click.
  1929. */
  1930. if (fnumber == -1 && factory != NULL) {
  1931. Speak(VOX_NO_FACTORY);
  1932. ControlClass::Action(flags, key);
  1933. return(true);
  1934. }
  1935. if (factory != NULL) {
  1936. /*
  1937. ** If this object is currently being built, then give a scold sound and text and then
  1938. ** bail.
  1939. */
  1940. if (factory->Is_Building()) {
  1941. Speak(VOX_NO_FACTORY);
  1942. } else {
  1943. /*
  1944. ** If production has completed, then attempt to have the object exit
  1945. ** the factory or go into placement mode.
  1946. */
  1947. if (factory->Has_Completed()) {
  1948. TechnoClass * pending = factory->Get_Object();
  1949. if (!pending && factory->Get_Special_Item()) {
  1950. Map.IsTargettingMode = SPC_ANY;
  1951. } else {
  1952. BuildingClass * builder = pending->Who_Can_Build_Me(false, false);
  1953. if (!builder) {
  1954. OutList.Add(EventClass(EventClass::ABANDON, otype, oid));
  1955. Speak(VOX_NO_FACTORY);
  1956. } else {
  1957. /*
  1958. ** If the completed object is a building, then change the
  1959. ** game state into building placement mode. This fact is
  1960. ** not transmitted to any linked computers until the moment
  1961. ** the building is actually placed down.
  1962. */
  1963. if (pending->What_Am_I() == RTTI_BUILDING) {
  1964. PlayerPtr->Manual_Place(builder, (BuildingClass *)pending);
  1965. } else {
  1966. /*
  1967. ** For objects that can leave the factory under their own
  1968. ** power, queue this event and process through normal house
  1969. ** production channels.
  1970. */
  1971. OutList.Add(EventClass(EventClass::PLACE, otype, -1));
  1972. }
  1973. }
  1974. }
  1975. } else {
  1976. if (PlayerPtr->Is_Hack_Prevented(otype, oid)) {
  1977. // Eva scolds the player here.
  1978. } else {
  1979. /*
  1980. ** The factory must have been in a suspended state. Resume construction
  1981. ** normally.
  1982. */
  1983. if (otype == RTTI_INFANTRYTYPE) {
  1984. Speak(VOX_TRAINING);
  1985. } else {
  1986. Speak(VOX_BUILDING);
  1987. }
  1988. OutList.Add(EventClass(EventClass::PRODUCE, Strip->Buildables[index].BuildableType, Strip->Buildables[index].BuildableID));
  1989. }
  1990. }
  1991. }
  1992. } else {
  1993. if (PlayerPtr->Is_Hack_Prevented(otype, oid)) {
  1994. // Eva scolds the player here.
  1995. } else {
  1996. /*
  1997. ** If this side strip is already busy with production, then ignore the
  1998. ** input and announce this fact.
  1999. */
  2000. if (otype == RTTI_INFANTRYTYPE) {
  2001. Speak(VOX_TRAINING);
  2002. } else {
  2003. Speak(VOX_BUILDING);
  2004. }
  2005. OutList.Add(EventClass(EventClass::PRODUCE, Strip->Buildables[index].BuildableType, Strip->Buildables[index].BuildableID));
  2006. }
  2007. }
  2008. }
  2009. } else {
  2010. flags = 0;
  2011. }
  2012. }
  2013. ControlClass::Action(flags, key);
  2014. return(true);
  2015. }
  2016. /***********************************************************************************************
  2017. * SidebarClass::SBGadgetClass::Action -- Special function that controls the mouse over the si *
  2018. * *
  2019. * This routine is called whenever the mouse is over the sidebar. It makes sure that the *
  2020. * mouse is always the normal shape while over the sidebar. *
  2021. * *
  2022. * INPUT: flags -- The event flags that resulted in this routine being called. *
  2023. * *
  2024. * key -- Reference the keyboard code that may be present. *
  2025. * *
  2026. * OUTPUT: Returns that no further keyboard processing is necessary. *
  2027. * *
  2028. * WARNINGS: none *
  2029. * *
  2030. * HISTORY: *
  2031. * 03/28/1995 JLB : Created. *
  2032. *=============================================================================================*/
  2033. int SidebarClass::SBGadgetClass::Action(unsigned , KeyNumType & )
  2034. {
  2035. Map.Help_Text(TXT_NONE);
  2036. Map.Override_Mouse_Shape(MOUSE_NORMAL, false);
  2037. return(true);
  2038. }
  2039. /***********************************************************************************************
  2040. * SidebarClass::StripClass::Factory_Link -- Links a factory to a sidebar button. *
  2041. * *
  2042. * This routine will link the specified factory to this sidebar strip. The exact button to *
  2043. * link to is determined from the object type and id specified. A linked button is one that *
  2044. * will show appropriate construction animation (clock shape) that matches the state of *
  2045. * the factory. *
  2046. * *
  2047. * INPUT: factory -- The factory number to link to the sidebar. *
  2048. * *
  2049. * type -- The object type that this factory refers to. *
  2050. * *
  2051. * id -- The object sub-type that this factory refers to. *
  2052. * *
  2053. * OUTPUT: Was the factory successfully attached? Failure would indicate that there is no *
  2054. * object of the specified type and sub-type in the sidebar list. *
  2055. * *
  2056. * WARNINGS: none *
  2057. * *
  2058. * HISTORY: *
  2059. * 05/18/1995 JLB : Created. *
  2060. *=============================================================================================*/
  2061. bool SidebarClass::StripClass::Factory_Link(int factory, RTTIType type, int id)
  2062. {
  2063. for (int index = 0; index < BuildableCount; index++) {
  2064. if (Buildables[index].BuildableType == type && Buildables[index].BuildableID == id) {
  2065. Buildables[index].Factory = factory;
  2066. IsBuilding = true;
  2067. /*
  2068. ** Flag that all the icons on this strip need to be redrawn
  2069. */
  2070. Flag_To_Redraw();
  2071. return(true);
  2072. }
  2073. }
  2074. return(false);
  2075. }
  2076. /***********************************************************************************************
  2077. * SidebarClass::Abandon_Production -- Stops production of the object specified. *
  2078. * *
  2079. * This routine is used to abandon production of the object specified. The factory will *
  2080. * be completely disabled by this call. *
  2081. * *
  2082. * INPUT: type -- The object type that is to be abandoned. The sub-type is not needed *
  2083. * since it is presumed there can be only one type in production at any *
  2084. * one time. *
  2085. * *
  2086. * factory -- The factory number that is doing the production. *
  2087. * *
  2088. * OUTPUT: Was the factory successfully abandoned? *
  2089. * *
  2090. * WARNINGS: none *
  2091. * *
  2092. * HISTORY: *
  2093. * 05/18/1995 JLB : Created. *
  2094. *=============================================================================================*/
  2095. bool SidebarClass::Abandon_Production(RTTIType type, int factory)
  2096. {
  2097. return(Column[Which_Column(type)].Abandon_Production(factory));
  2098. }
  2099. /***********************************************************************************************
  2100. * SidebarClass::StripClass::Abandon_Produ -- Abandons production associated with sidebar. *
  2101. * *
  2102. * Production of the object associated with this sidebar is abandoned when this routine is *
  2103. * called. *
  2104. * *
  2105. * INPUT: factory -- The factory index that is to be suspended. *
  2106. * *
  2107. * OUTPUT: Was the production abandonment successful? *
  2108. * *
  2109. * WARNINGS: none *
  2110. * *
  2111. * HISTORY: *
  2112. * 05/18/1995 JLB : Created. *
  2113. * 08/06/1995 JLB : More intelligent abandon logic for multiple factories. *
  2114. *=============================================================================================*/
  2115. bool SidebarClass::StripClass::Abandon_Production(int factory)
  2116. {
  2117. bool noprod = true;
  2118. bool abandon = false;
  2119. for (int index = 0; index < BuildableCount; index++) {
  2120. if (Buildables[index].Factory == factory) {
  2121. Factories.Raw_Ptr(factory)->Abandon();
  2122. Buildables[index].Factory = -1;
  2123. abandon = true;
  2124. } else {
  2125. if (Buildables[index].Factory != -1) {
  2126. noprod = false;
  2127. }
  2128. }
  2129. }
  2130. /*
  2131. ** If there was a change to the strip, then flag the strip to be redrawn.
  2132. */
  2133. if (abandon) {
  2134. Flag_To_Redraw();
  2135. }
  2136. /*
  2137. ** If there is no production whatsoever on this strip, then flag it so.
  2138. */
  2139. if (noprod) {
  2140. IsBuilding = false;
  2141. }
  2142. return(abandon);
  2143. }
  2144. /***********************************************************************************************
  2145. * SidebarClass::Zoom_Mode_Control -- Handles the zoom mode toggle operation. *
  2146. * *
  2147. * This is the function that is called when the map button is pressed. It will toggle *
  2148. * between the different modes that the radar map can assume. *
  2149. * *
  2150. * INPUT: none *
  2151. * *
  2152. * OUTPUT: none *
  2153. * *
  2154. * WARNINGS: none *
  2155. * *
  2156. * HISTORY: *
  2157. * 07/31/1996 JLB : Created. *
  2158. *=============================================================================================*/
  2159. void SidebarClass::Zoom_Mode_Control(void)
  2160. {
  2161. #ifdef WIN32
  2162. /*
  2163. ** If radar is active, cycle as follows:
  2164. ** Zoomed => not zoomed
  2165. ** not zoomed => player status (multiplayer only)
  2166. ** player status => radar spying readout
  2167. ** radar spying readout => zoomed
  2168. */
  2169. if (IsRadarActive) {
  2170. if (Is_Zoomed() || Session.Type==GAME_NORMAL) {
  2171. if (Is_Zoomed() || !Spy_Next_House()) {
  2172. Zoom_Mode(Coord_Cell(TacticalCoord));
  2173. }
  2174. } else {
  2175. if (!Spying_On_House() && !Is_Player_Names()) {
  2176. Player_Names(1);
  2177. } else {
  2178. Player_Names(0);
  2179. if (!Spy_Next_House()) {
  2180. Zoom_Mode(Coord_Cell(TacticalCoord));
  2181. }
  2182. }
  2183. }
  2184. } else {
  2185. if (Session.Type!=GAME_NORMAL) {
  2186. Player_Names(Is_Player_Names()==0);
  2187. }
  2188. }
  2189. #else
  2190. /*
  2191. ** If radar is active, cycle as follows:
  2192. ** not zoomed => player status (multiplayer only)
  2193. ** player status => radar spying readout
  2194. ** radar spying readout => not zoomed
  2195. */
  2196. if (IsRadarActive) {
  2197. if (Session.Type==GAME_NORMAL) {
  2198. if (!Spy_Next_House()) {
  2199. Zoom_Mode(Coord_Cell(TacticalCoord));
  2200. }
  2201. } else {
  2202. if (!Spying_On_House() && !Is_Player_Names()) {
  2203. Player_Names(1);
  2204. } else {
  2205. Player_Names(0);
  2206. if (!Spy_Next_House()) {
  2207. Zoom_Mode(Coord_Cell(TacticalCoord));
  2208. }
  2209. }
  2210. }
  2211. } else {
  2212. if (Session.Type!=GAME_NORMAL) {
  2213. Player_Names(Is_Player_Names()==0);
  2214. }
  2215. }
  2216. #endif
  2217. }