SIDEBAR.CPP 110 KB

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