| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535 |
- /*
- ** Command & Conquer(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /* $Header: F:\projects\c&c\vcs\code\sidebar.cpv 2.13 02 Aug 1995 17:03:22 JOE_BOSTIC $ */
- /***********************************************************************************************
- *** 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 ***
- ***********************************************************************************************
- * *
- * Project Name : Command & Conquer *
- * *
- * File Name : SIDEBAR.CPP *
- * *
- * Programmer : Joe L. Bostic *
- * *
- * Start Date : October 20, 1994 *
- * *
- * Last Update : January 25, 1996 [] *
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * SidebarClass::Abandon_Production -- Stops production of the object specified. *
- * SidebarClass::Activate -- Controls the sidebar activation. *
- * SidebarClass::Activate_Demolish -- Controls the demolish button on the sidebar. *
- * SidebarClass::Activate_Repair -- Controls the repair button on the sidebar. *
- * SidebarClass::Activate_Upgrade -- Controls the upgrade button on the sidebar. *
- * SidebarClass::Add -- Adds a game object to the sidebar list. *
- * SidebarClass::AI -- Handles player clicking on sidebar area. *
- * SidebarClass::Draw_It -- Renders the sidebar display. *
- * SidebarClass::Factory_Link -- Links a factory to a sidebar strip. *
- * SidebarClass::Init_Clear -- Sets sidebar to a known (and deactivated) state *
- * SidebarClass::Init_IO -- Adds buttons to the button list *
- * SidebarClass::Init_Theater -- Performs theater-specific initialization *
- * SidebarClass::One_Time -- Handles the one time game initializations. *
- * SidebarClass::One_Time -- Handles the one time game initializations. *
- * SidebarClass::Recalc -- Examines the sidebar data and updates it as necessary. *
- * SidebarClass::Refresh_Cells -- Intercepts the refresh, looking for sidebar controls. *
- * SidebarClass::SBGadgetClass::Action -- Special function that controls the mouse over the s*
- * SidebarClass::Scroll -- Handles scrolling the sidebar object strip. *
- * SidebarClass::Set_Current -- Sets a specified object that controls the sidebar display. *
- * SidebarClass::SidebarClass -- Default constructor for the sidebar. *
- * SidebarClass::StripClass::Abandon_Produ -- Abandons production associated with sidebar. *
- * SidebarClass::StripClass::Activate -- Adds the strip buttons to the input system. *
- * SidebarClass::StripClass::Add -- Add an object to the side strip. *
- * SidebarClass::StripClass::AI -- Input and AI processing for the side strip. *
- * SidebarClass::StripClass::Deactivate -- Removes the side strip buttons from the input syst*
- * SidebarClass::StripClass::Draw_It -- Render the sidebar display. *
- * SidebarClass::StripClass::Factory_Link -- Links a factory to a sidebar button. *
- * SidebarClass::StripClass::Flag_To_Redra -- Flags the sidebar strip to be redrawn. *
- * SidebarClass::StripClass::Get_Special_Cameo -- Fetches the special event cameo shape. *
- * SidebarClass::StripClass::Init_Clear -- Sets sidebar to a known (and deactivated) state *
- * SidebarClass::StripClass::Init_IO -- Adds buttons to the button list *
- * SidebarClass::StripClass::Init_Theater -- Performs theater-specific initialization *
- * SidebarClass::StripClass::One_Time -- Performs one time actions necessary for the side str*
- * SidebarClass::StripClass::Recalc -- Revalidates the current sidebar list of objects. *
- * SidebarClass::StripClass::Scroll -- Causes the side strip to scroll. *
- * SidebarClass::StripClass::SelectClass:: -- Action function when buildable cameo is selecte*
- * SidebarClass::StripClass::SelectClass:: -- Assigns special values to a buildable select bu*
- * SidebarClass::StripClass::SelectClass::SelectClass -- Default constructor. *
- * SidebarClass::StripClass::StripClass -- Default constructor for the side strip class. *
- * SidebarClass::Which_Column -- Determines which column a given type should appear. *
- * sortfunc -- Utility routine that handles 'qsort' the strip buttons. *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "function.h"
- /*
- ** Define "_RETRIEVE" if the palette morphing tables are part of the loaded data. If this
- ** is undefined, then the files will be created.
- */
- #define _RETRIEVE
- /***************************************************************************
- ** This holds the translucent table for use with the construction clock
- ** animation.
- */
- char SidebarClass::StripClass::ClockTranslucentTable[(1+1)*256];
- /***************************************************************************
- ** This points to the main sidebar shapes. These include the upgrade and
- ** repair buttons.
- */
- TheaterType SidebarClass::StripClass::LastTheater = THEATER_NONE;
- typedef enum ButtonNumberType {
- BUTTON_RADAR = 100,
- BUTTON_REPAIR,
- BUTTON_DEMOLISH,
- BUTTON_UPGRADE,
- BUTTON_SELECT,
- BUTTON_ZOOM
- } ButtonNumberType;
- /*
- ** Sidebar buttons
- */
- SidebarClass::SBGadgetClass SidebarClass::Background;
- ShapeButtonClass SidebarClass::Repair;
- ShapeButtonClass SidebarClass::Upgrade;
- ShapeButtonClass SidebarClass::Zoom;
- ShapeButtonClass SidebarClass::StripClass::UpButton[COLUMNS];
- ShapeButtonClass SidebarClass::StripClass::DownButton[COLUMNS];
- SidebarClass::StripClass::SelectClass
- SidebarClass::StripClass::SelectButton[COLUMNS][MAX_VISIBLE];
- /*
- ** Shape data pointers
- */
- void const * SidebarClass::StripClass::LogoShapes;
- void const * SidebarClass::StripClass::ClockShapes;
- void const * SidebarClass::StripClass::SpecialShapes[3];
- void const * SidebarClass::SidebarShape1;
- void const * SidebarClass::SidebarShape2;
- /***********************************************************************************************
- * SidebarClass::SidebarClass -- Default constructor for the sidebar. *
- * *
- * Constructor for the sidebar handler. It basically sets up the sidebar to the empty *
- * condition. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 11/17/1994 JLB : Created. *
- *=============================================================================================*/
- SidebarClass::SidebarClass(void)
- {
- IsSidebarActive = false;
- IsRepairActive = false;
- IsUpgradeActive = false;
- IsDemolishActive = false;
- IsToRedraw = true;
- }
- /***********************************************************************************************
- * SidebarClass::One_Time -- Handles the one time game initializations. *
- * *
- * This routine is used to load the graphic data that is needed by the sidebar display. It *
- * should only be called ONCE. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: Only call this routine once when the game first starts. *
- * *
- * HISTORY: *
- * 10/28/94 JLB : Created. *
- *=============================================================================================*/
- void SidebarClass::One_Time(void)
- {
- PowerClass::One_Time();
- /*
- ** Set up the pixel offsets and widths and heights used to render the
- ** sidebar. They are now variables because we need to change them for
- ** variable resolutions.
- */
- int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2;
- SideBarWidth = SIDEBARWIDTH * factor;
- SideX = SeenBuff.Get_Width() - SideBarWidth;
- SideY = Map.RadY + Map.RadHeight + 1;
- SideWidth = SeenBuff.Get_Width() - SideX;
- SideHeight = SeenBuff.Get_Height() - SideY;
- MaxVisible = 4;
- ButtonHeight = 9 * factor;
- TopHeight = ButtonHeight + (4 * factor);
- Background.X = SideX+8 * factor;
- Background.Y = SideY,
- Background.Width = SideWidth-1;
- Background.Height = SideHeight-1;
- /*
- ** This sets up the clipping window. This window is used by the shape drawing
- ** code so that as the sidebar buildable buttons scroll, they get properly
- ** clipped at the top and bottom edges.
- */
- WindowList[WINDOW_SIDEBAR][WINDOWX] = (SideX+PowWidth) >> 3;
- WindowList[WINDOW_SIDEBAR][WINDOWY] = SideY + 1 + TopHeight;
- WindowList[WINDOW_SIDEBAR][WINDOWWIDTH] = SideWidth>>3;
- WindowList[WINDOW_SIDEBAR][WINDOWHEIGHT] = (MaxVisible * (StripClass::OBJECT_HEIGHT * factor)) - 1;
- /*
- ** Set up the coordinates for the sidebar strips. These coordinates are for
- ** the upper left corner.
- */
- int width = (SideWidth - PowWidth) - (((StripClass::STRIP_WIDTH ) * factor) << 1);
- int spacing = width / 3;
- Column[0].X = SideX + PowWidth + spacing;
- Column[0].Y = SideY + TopHeight + 1;
- Column[1].X = Column[0].X + (StripClass::STRIP_WIDTH * factor) + spacing -1;
- Column[1].Y = SideY + TopHeight + 1;
- Column[0].One_Time(0);
- Column[1].One_Time(1);
- SidebarShape1 = Hires_Retrieve("SIDE1.SHP");
- SidebarShape2 = Hires_Retrieve("SIDE2.SHP");
- }
- /***********************************************************************************************
- * SidebarClass::Init_Clear -- Sets sidebar to a known (and deactivated) state *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 12/24/1994 JLB : Created. *
- *=============================================================================================*/
- void SidebarClass::Init_Clear(void)
- {
- PowerClass::Init_Clear();
- IsToRedraw = true;
- IsRepairActive = false;
- IsUpgradeActive = false;
- IsDemolishActive = false;
- Column[0].Init_Clear();
- Column[1].Init_Clear();
- Activate(false);
- }
- /***********************************************************************************************
- * SidebarClass::Init_IO -- Adds buttons to the button list *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 12/24/1994 JLB : Created. *
- *=============================================================================================*/
- void SidebarClass::Init_IO(void)
- {
- void *oldfont;
- int oldx;
- PowerClass::Init_IO();
- /*
- ** Add the sidebar's buttons only if we're not in editor mode.
- */
- int buttonspacing = (SideBarWidth - (ButtonOneWidth + ButtonTwoWidth + ButtonThreeWidth)) / 4;
- if (!Debug_Map) {
- /*
- ** Set the button widths based on the string that goes in them.
- */
- oldfont = Set_Font(Font6Ptr);
- oldx = FontXSpacing;
- FontXSpacing = -1;
- Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, TPF_6POINT | TPF_NOSHADOW);
- int maxwidth = String_Pixel_Width(Text_String(TXT_REPAIR_BUTTON)) + 8;
- maxwidth = MAX(maxwidth, String_Pixel_Width(Text_String(TXT_BUTTON_SELL)) + 8);
- maxwidth = MAX(maxwidth, String_Pixel_Width(Text_String(TXT_MAP)) + 8);
- Repair.Width = maxwidth;
- Upgrade.Width = maxwidth;
- Zoom.Width = maxwidth;
- // Repair.Width = String_Pixel_Width(Text_String(TXT_REPAIR_BUTTON)) + 8;
- // Upgrade.Width = String_Pixel_Width(Text_String(TXT_BUTTON_SELL)) + 8;
- // Zoom.Width = String_Pixel_Width(Text_String(TXT_MAP)) + 8;
- /*
- ** find the spacing between buttons by getting remaining width
- ** and dividing it between the buttons.
- */
- int buttonspacing = (SideBarWidth - (Repair.Width + Upgrade.Width + Zoom.Width)) / 4;
- Repair.IsSticky = true;
- Repair.ID = BUTTON_REPAIR;
- Repair.X = 484;
- Repair.Y = 160;
- Repair.IsPressed = false;
- Repair.IsToggleType = true;
- Repair.ReflectButtonState = true;
- #if (FRENCH)
- Repair.Set_Shape(Hires_Retrieve("REPAIRF.SHP"));
- #else
- #if (GERMAN)
- Repair.Set_Shape(Hires_Retrieve("REPAIRG.SHP"));
- #else
- Repair.Set_Shape(Hires_Retrieve("REPAIR.SHP"));
- #endif
- #endif
- Upgrade.IsSticky = true;
- Upgrade.ID = BUTTON_UPGRADE;
- Upgrade.X = 480+57;
- Upgrade.Y = 160;
- Upgrade.IsPressed = false;
- Upgrade.IsToggleType = true;
- Upgrade.ReflectButtonState = true;
- #if (FRENCH)
- Upgrade.Set_Shape(Hires_Retrieve("SELLF.SHP"));
- #else
- #if (GERMAN)
- Upgrade.Set_Shape(Hires_Retrieve("SELLG.SHP"));
- #else
- Upgrade.Set_Shape(Hires_Retrieve("SELL.SHP"));
- #endif
- #endif
- Zoom.IsSticky = true;
- Zoom.ID = BUTTON_ZOOM;
- Zoom.X = 480 + 110;
- Zoom.Y = 160;
- Zoom.IsPressed = false;
- #if (FRENCH)
- Zoom.Set_Shape(Hires_Retrieve("MAPF.SHP"));
- #else
- #if (GERMAN)
- Zoom.Set_Shape(Hires_Retrieve("MAPG.SHP"));
- #else
- Zoom.Set_Shape(Hires_Retrieve("MAP.SHP"));
- #endif
- #endif
- if (IsRadarActive || GameToPlay!=GAME_NORMAL) {
- Zoom.Enable();
- } else {
- Zoom.Disable();
- }
- Set_Font(oldfont);
- FontXSpacing = oldx;
- FontXSpacing = -1;
- Column[0].Init_IO(0);
- Column[1].Init_IO(1);
- /*
- ** If a game was loaded & the sidebar was enabled, pop it up now
- */
- if (IsSidebarActive) {
- IsSidebarActive = false;
- Activate(1);
- // Background.Zap();
- // Add_A_Button(Background);
- }
- }
- }
- /***********************************************************************************************
- * SidebarClass::Init_Theater -- Performs theater-specific initialization *
- * *
- * INPUT: theater -- The theater that is being initialized. Sometimes this has an effect on *
- * the data that is loaded. *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 12/24/1994 JLB : Created. *
- *=============================================================================================*/
- void SidebarClass::Init_Theater(TheaterType theater)
- {
- PowerClass::Init_Theater(theater);
- Column[0].Init_Theater(theater);
- Column[1].Init_Theater(theater);
- }
- /***********************************************************************************************
- * SidebarClass::Which_Column -- Determines which column a given type should appear. *
- * *
- * Use this function to resolve what column the specified object type should be placed *
- * into. *
- * *
- * INPUT: otype -- Pointer to the object type class of the object in question. *
- * *
- * OUTPUT: Returns with the column number that the object should be placed in. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 01/01/1995 JLB : Created. *
- *=============================================================================================*/
- int SidebarClass::Which_Column(RTTIType type)
- {
- if (type == RTTI_BUILDINGTYPE || type == RTTI_BUILDING) {
- return(0);
- }
- return(1);
- }
- /***********************************************************************************************
- * SidebarClass::Factory_Link -- Links a factory to a sidebar strip. *
- * *
- * This routine will link the specified factory to the sidebar strip. A factory must be *
- * linked to the sidebar so that as the factory production progresses, the sidebar will *
- * show the production progress. *
- * *
- * INPUT: factory -- The factory number to attach. *
- * *
- * type -- The object type number. *
- * *
- * id -- The object sub-type number. *
- * *
- * OUTPUT: Was the factory successfully attached to the sidebar strip? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 05/19/1995 JLB : Created. *
- *=============================================================================================*/
- bool SidebarClass::Factory_Link(int factory, RTTIType type, int id)
- {
- return(Column[Which_Column(type)].Factory_Link(factory, type, id));
- }
- /***********************************************************************************************
- * SidebarClass::Refresh_Cells -- Intercepts the refresh, looking for sidebar controls. *
- * *
- * This routine intercepts the Refresh_Cells call in order to see if the sidebar needs *
- * to be refreshed as well. If the special code to refresh the sidebar was found, it *
- * flags the sidebar to be redrawn and then removes the code from the list. *
- * *
- * INPUT: cell -- The cell to base the refresh list on. *
- * *
- * list -- Pointer to the cell offset list that elaborates all the cells that *
- * need to be flagged for redraw. *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 01/19/1995 JLB : Created. *
- *=============================================================================================*/
- void SidebarClass::Refresh_Cells(CELL cell, short const *list)
- {
- if (*list == REFRESH_SIDEBAR) {
- IsToRedraw = true;
- Column[0].IsToRedraw = true;
- Column[1].IsToRedraw = true;
- Flag_To_Redraw(false);
- }
- PowerClass::Refresh_Cells(cell, list);
- }
- /***********************************************************************************************
- * SidebarClass::Activate_Repair -- Controls the repair button on the sidebar. *
- * *
- * Use this routine to turn the repair sidebar button on and off. Typically, the button *
- * is enabled when the currently selected structure is friendly and damaged. *
- * *
- * INPUT: control -- The controls how the button is to be activated or deactivated; *
- * 0 -- Turn button off. *
- * 1 -- Turn button on. *
- * -1 -- Toggle button state. *
- * *
- * OUTPUT: bool; Was the button previously activated? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 12/24/1994 JLB : Created. *
- *=============================================================================================*/
- bool SidebarClass::Activate_Repair(int control)
- {
- bool old = IsRepairActive;
- if (control == -1) {
- control = IsRepairActive ? 0 : 1;
- }
- switch (control) {
- case 1:
- IsRepairActive = true;
- break;
- default:
- case 0:
- IsRepairActive = false;
- break;
- }
- if (old != IsRepairActive) {
- Flag_To_Redraw(false);
- IsToRedraw = true;
- if (!IsRepairActive) {
- Help_Text(TXT_NONE);
- Set_Default_Mouse(MOUSE_NORMAL, false);
- }
- }
- return(old);
- }
- /***********************************************************************************************
- * SidebarClass::Activate_Upgrade -- Controls the upgrade button on the sidebar. *
- * *
- * Use this routine to turn the upgrade sidebar button on and off. Typically, the button *
- * is enabled when the currently selected structure can be upgraded and disabled otherwise. *
- * *
- * INPUT: control -- The controls how the button is to be activated or deactivated; *
- * 0 -- Turn button off. *
- * 1 -- Turn button on. *
- * -1 -- Toggle button state. *
- * *
- * OUTPUT: bool; Was the button previously activated? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 12/24/1994 JLB : Created. *
- *=============================================================================================*/
- bool SidebarClass::Activate_Upgrade(int control)
- {
- bool old = IsUpgradeActive;
- if (control == -1) {
- control = IsUpgradeActive ? 0 : 1;
- }
- switch (control) {
- case 1:
- IsUpgradeActive = true;
- break;
- default:
- case 0:
- IsUpgradeActive = false;
- break;
- }
- if (old != IsUpgradeActive) {
- Flag_To_Redraw(false);
- IsToRedraw = true;
- if (!IsUpgradeActive) {
- Set_Default_Mouse(MOUSE_NORMAL, false);
- }
- }
- return(old);
- }
- /***********************************************************************************************
- * SidebarClass::Activate_Demolish -- Controls the demolish button on the sidebar. *
- * *
- * Use this routine to turn the demolish/dismantle sidebar button on and off. Typically, *
- * the button is enabled when a friendly building is selected and disabled otherwise. *
- * *
- * INPUT: control -- The controls how the button is to be activated or deactivated; *
- * 0 -- Turn button off. *
- * 1 -- Turn button on. *
- * -1 -- Toggle button state. *
- * *
- * OUTPUT: bool; Was the button previously activated? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 12/24/1994 JLB : Created. *
- *=============================================================================================*/
- bool SidebarClass::Activate_Demolish(int control)
- {
- bool old = IsDemolishActive;
- if (control == -1) {
- control = IsDemolishActive ? 0 : 1;
- }
- switch (control) {
- case 1:
- IsDemolishActive = true;
- break;
- default:
- case 0:
- IsDemolishActive = false;
- break;
- }
- if (old != IsDemolishActive) {
- Flag_To_Redraw(false);
- IsToRedraw = true;
- if (!IsDemolishActive) {
- Set_Default_Mouse(MOUSE_NORMAL, false);
- }
- }
- return(old);
- }
- /***********************************************************************************************
- * SidebarClass::Add -- Adds a game object to the sidebar list. *
- * *
- * This routine is used to add a game object to the sidebar. Call this routine when a *
- * factory type building is created. It handles the case of adding an item that has already *
- * been added -- it just ignores it. *
- * *
- * INPUT: object -- Pointer to the object that is being added. *
- * *
- * OUTPUT: bool; Was the object added to the sidebar? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 11/17/1994 JLB : Created. *
- *=============================================================================================*/
- bool SidebarClass::Add(RTTIType type, int id)
- {
- int column;
- /*
- ** Add the sidebar only if we're not in editor mode.
- */
- if (!Debug_Map) {
- column = Which_Column(type);
- if (Column[column].Add(type, id)) {
- Activate(1);
- IsToRedraw = true;
- Flag_To_Redraw(false);
- return(true);
- }
- return(false);
- }
- return(false);
- }
- /***********************************************************************************************
- * SidebarClass::Scroll -- Handles scrolling the sidebar object strip. *
- * *
- * This routine is used to scroll the sidebar strip of objects. The strip appears whenever *
- * a building is selected that can produce units. If the number of units to produce is *
- * greater than what the sidebar can hold, this routine is used to scroll the other object *
- * into view so they can be selected. *
- * *
- * INPUT: up -- Should the scroll be upwards? Upward scrolling reveals object that are *
- * later in the list of objects. *
- * *
- * OUTPUT: bool; Did scrolling occur? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 10/28/94 JLB : Created. *
- *=============================================================================================*/
- bool SidebarClass::Scroll(bool up, int column)
- {
- if (Column[column].Scroll(up)) {
- IsToRedraw = true;
- Flag_To_Redraw(false);
- return(true);
- }
- return(false);
- }
- /***********************************************************************************************
- * SidebarClass::Draw_It -- Renders the sidebar display. *
- * *
- * This routine performs the actual drawing of the sidebar display. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: bool; Was the sidebar imagery changed at all? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 10/28/94 JLB : Created. *
- * 12/31/1994 JLB : Split rendering off into the sidebar strip class. *
- *=============================================================================================*/
- void SidebarClass::Draw_It(bool complete)
- {
- PowerClass::Draw_It(complete);
- if (IsSidebarActive && (IsToRedraw || complete) && !Debug_Map) {
- IsToRedraw = false;
- if (LogicPage->Lock()){
- /*
- ** Draw the outline box around the sidebar buttons.
- */
- //CC_Draw_Shape(SidebarShape1, (int)complete, SideX, 158, WINDOW_MAIN, SHAPE_WIN_REL);
- //CC_Draw_Shape(SidebarShape2, (int)complete, SideX, 158+118, WINDOW_MAIN, SHAPE_WIN_REL);
- LogicPage->Draw_Line(SideX, 157, SeenBuff.Get_Width()-1, 157, 0);
- CC_Draw_Shape(SidebarShape1, 0, SideX, 158, WINDOW_MAIN, SHAPE_WIN_REL);
- CC_Draw_Shape(SidebarShape2, 0, SideX, 158+118, WINDOW_MAIN, SHAPE_WIN_REL);
- #if (0)
- if ( complete ) {
- LogicPage->Fill_Rect(SideX+Map.PowWidth, SideY, SideX+SideWidth-1, SideY+SideHeight-1, LTGREY);
- }
- LogicPage->Fill_Rect(SideX, SideY, SideX+SideWidth-1, SideY+TopHeight-1, LTGREY);
- Draw_Box(SideX+Map.PowWidth, SideY+TopHeight, SideWidth-Map.PowWidth, SideHeight-TopHeight, BOXSTYLE_RAISED, false);
- #endif //(0)
- //Repair.Draw_Me(true);
- //Upgrade.Draw_Me(true);
- //Zoom.Draw_Me(true);
- // } else {
- // if (IsToRedraw || complete) {
- // LogicPage->Fill_Rect(TacPixelX + Lepton_To_Pixel(TacLeptonWidth), SIDE_Y, 319, SIDE_Y+TOP_HEIGHT, BLACK);
- // }
- LogicPage->Unlock();
- }
- }
- /*
- ** Draw the side strip elements by calling their respective draw functions.
- */
- if (IsSidebarActive){
- Column[0].Draw_It(complete);
- Column[1].Draw_It(complete);
- Repair.Draw_Me(true);
- Upgrade.Draw_Me(true);
- Zoom.Draw_Me(true);
- }
- IsToRedraw = false;
- }
- /***********************************************************************************************
- * SidebarClass::AI -- Handles player clicking on sidebar area. *
- * *
- * This routine handles the processing necessary when the player clicks on the sidebar. *
- * Typically, this is selection of the item to build. *
- * *
- * INPUT: input -- Reference to the keyboard input value. *
- * *
- * x,y -- Mouse coordinates at time of input. *
- * *
- * OUTPUT: bool; Was the click handled? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 10/28/94 JLB : Created. *
- * 11/11/1994 JLB : Processes input directly. *
- * 12/26/1994 JLB : Uses factory manager class for construction handling. *
- * 12/31/1994 JLB : Simplified to use the sidebar strip class handlers. *
- * 12/31/1994 JLB : Uses mouse coordinate parameters. *
- * 06/27/1995 JLB : <TAB> key toggles sidebar. *
- *=============================================================================================*/
- void SidebarClass::AI(KeyNumType & input, int x, int y)
- {
- bool redraw = false;
- /*
- ** Toggle the sidebar in and out with the <TAB> key.
- */
- if (input == KN_TAB) {
- Activate(-1);
- }
- if (!Debug_Map) {
- Column[0].AI(input, x, y);
- Column[1].AI(input, x, y);
- }
- if (IsSidebarActive && !Debug_Map) {
- if (input == KN_DOWN) {
- redraw |= Column[0].Scroll(false);
- redraw |= Column[1].Scroll(false);
- input = KN_NONE;
- }
- if (input == KN_UP) {
- redraw |= Column[0].Scroll(true);
- redraw |= Column[1].Scroll(true);
- input = KN_NONE;
- }
- }
- if (IsSidebarActive) {
- /*
- ** If there are any buildings in the payer's inventory, then allow the repair
- ** option.
- */
- if (PlayerPtr->BScan) {
- Activate_Repair(true);
- } else {
- Activate_Repair(false);
- }
- if (input == (BUTTON_REPAIR|KN_BUTTON)) {
- Repair_Mode_Control(-1);
- }
- if (input == (BUTTON_ZOOM|KN_BUTTON)) {
- /*
- ** If radar is active, cycle as follows:
- ** Zoomed => not zoomed
- ** not zoomed => player status (multiplayer only)
- ** player status => zoomed
- */
- if (IsRadarActive) {
- if (Is_Zoomed() || GameToPlay==GAME_NORMAL) {
- Zoom_Mode(Coord_Cell(TacticalCoord));
- } else {
- if (!Is_Player_Names()) {
- Player_Names(1);
- } else {
- Player_Names(0);
- Zoom_Mode(Coord_Cell(TacticalCoord));
- }
- }
- } else {
- if (GameToPlay!=GAME_NORMAL) {
- Player_Names(Is_Player_Names()==0);
- }
- }
- }
- if (input == (BUTTON_UPGRADE|KN_BUTTON)) {
- Sell_Mode_Control(-1);
- }
- #ifdef NEVER
- // int index = -1;
- if (index != -1) {
- /*
- ** Display help text if the mouse is over a sidebar button.
- */
- switch (index) {
- default:
- case 2:
- Map.Help_Text(TXT_UPGRADE, -1, -1, PlayerPtr->Class->Color);
- break;
- case 1:
- Map.Help_Text(PlayerPtr->Class->House == HOUSE_GOOD ? TXT_SELL : TXT_DEMOLISH, x, y, PlayerPtr->Class->Color);
- break;
- case 0:
- Map.Help_Text(TXT_REPAIR, x, y, PlayerPtr->Class->Color);
- break;
- }
- }
- #endif
- if (redraw) {
- //IsToRedraw = true;
- Column[0].Flag_To_Redraw();
- Column[1].Flag_To_Redraw();
- Flag_To_Redraw(false);
- }
- }
- if ((!IsRepairMode) && Repair.IsOn){
- Repair.Turn_Off();
- }
- if ((!IsSellMode) && Upgrade.IsOn){
- Upgrade.Turn_Off();
- }
- PowerClass::AI(input, x, y);
- }
- /***********************************************************************************************
- * SidebarClass::Recalc -- Examines the sidebar data and updates it as necessary. *
- * *
- * Occasionally a factory gets destroyed. This routine must be called in such a case *
- * because it might be possible that sidebar object need to be removed. This routine will *
- * examine all existing objects in the sidebar class and if no possible factory can *
- * produce it, then it will be removed. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: This routine is exhaustive and thus time consuming. Only call it when really *
- * necessary. Such as when a factory is destroyed rather than when a non-factory *
- * is destroyed. *
- * *
- * HISTORY: *
- * 11/30/1994 JLB : Created. *
- *=============================================================================================*/
- void SidebarClass::Recalc(void)
- {
- bool redraw = false;
- redraw |= Column[0].Recalc();
- redraw |= Column[1].Recalc();
- if (redraw) {
- IsToRedraw = true;
- Flag_To_Redraw(false);
- }
- }
- /***********************************************************************************************
- * SidebarClass::Activate -- Controls the sidebar activation. *
- * *
- * Use this routine to turn the sidebar on or off. This routine handles updating the *
- * necessary flags. *
- * *
- * INPUT: control -- Tells what to do with the sidebar according to the following: *
- * 0 = Turn sidebar off. *
- * 1 = Turn sidebar on. *
- * -1= Toggle sidebar on or off. *
- * *
- * OUTPUT: bool; Was the sidebar already on? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 12/09/1994 JLB : Created. *
- *=============================================================================================*/
- bool SidebarClass::Activate(int control)
- {
- bool old = IsSidebarActive;
- int sidex = SeenBuff.Get_Width() - SideBarWidth;
- int sidey = Map.RadY + Map.RadHeight;
- int topheight = 13;
- int sidewidth = SeenBuff.Get_Width() - sidex;
- int sideheight = SeenBuff.Get_Height() - sidey;
- if (PlaybackGame)
- return (old);
- /*
- ** Determine the new state of the sidebar.
- */
- switch (control) {
- case -1:
- IsSidebarActive = IsSidebarActive == false;
- break;
- case 1:
- IsSidebarActive = true;
- break;
- default:
- case 0:
- IsSidebarActive = false;
- break;
- }
- /*
- ** Only if there is a change in the state of the sidebar will anything
- ** be done to change it.
- */
- if (IsSidebarActive != old) {
- /*
- ** If the sidebar is activated but was on the right side of the screen, then
- ** activate it on the left side of the screen.
- */
- if (IsSidebarActive /*&& X*/) {
- Set_View_Dimensions(0, Map.Get_Tab_Height(), SeenBuff.Get_Width() - sidewidth);
- IsToRedraw = true;
- Help_Text(TXT_NONE);
- Repair.Zap();
- Add_A_Button(Repair);
- Upgrade.Zap();
- Add_A_Button(Upgrade);
- Zoom.Zap();
- Add_A_Button(Zoom);
- Column[0].Activate();
- Column[1].Activate();
- Background.Zap();
- Add_A_Button(Background);
- Map.RadarButton.Zap();
- Add_A_Button(Map.RadarButton);
- Map.PowerButton.Zap();
- Add_A_Button(Map.PowerButton);
- } else {
- Help_Text(TXT_NONE);
- Set_View_Dimensions(0, Map.Get_Tab_Height());
- Remove_A_Button(Repair);
- Remove_A_Button(Upgrade);
- Remove_A_Button(Zoom);
- Remove_A_Button(Background);
- Column[0].Deactivate();
- Column[1].Deactivate();
- Remove_A_Button(Map.RadarButton);
- Remove_A_Button(Map.PowerButton);
- }
- /*
- ** Since the sidebar status has changed, update the map so that the graphics
- ** will be rendered correctly.
- */
- Flag_To_Redraw(true);
- }
- return(old);
- }
- /***********************************************************************************************
- * SidebarClass::StripClass::StripClass -- Default constructor for the side strip class. *
- * *
- * This constructor is used to reset the side strip to default empty state. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 12/31/1994 JLB : Created. *
- *=============================================================================================*/
- SidebarClass::StripClass::StripClass(void)
- {
- IsScrollingDown = false;
- IsScrolling = false;
- IsBuilding = false; TopIndex = 0;
- Slid = 0;
- BuildableCount = 0;
- for (int index = 0; index < MAX_BUILDABLES; index++) {
- Buildables[index].BuildableID = 0;
- Buildables[index].BuildableType = RTTI_NONE;
- Buildables[index].Factory = -1;
- }
- }
- /***********************************************************************************************
- * SidebarClass::StripClass::One_Time -- Performs one time actions necessary for the side stri *
- * *
- * Call this routine ONCE at the beginning of the game. It handles retrieving pointers to *
- * the shape files it needs for rendering. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 12/31/1994 JLB : Created. *
- *=============================================================================================*/
- void SidebarClass::StripClass::One_Time(int )
- {
- static char *_file[3] = {
- "ION",
- "ATOM",
- "BOMB"
- };
- int factor = Get_Resolution_Factor();
- ObjectWidth = OBJECT_WIDTH << factor;
- ObjectHeight = OBJECT_HEIGHT << factor;
- StripWidth = STRIP_WIDTH << factor;
- LeftEdgeOffset = (StripWidth - ObjectWidth) >> 1;
- ButtonSpacingOffset = (StripWidth - ((BUTTON_WIDTH << factor) << 1)) / 3;
- LogoShapes = Hires_Retrieve("STRIP.SHP");
- ClockShapes = Hires_Retrieve("CLOCK.SHP");
- char fullname[_MAX_FNAME+_MAX_EXT];
- char buffer[_MAX_FNAME];
- for (int lp = 0; lp < 3; lp++) {
- if ( Get_Resolution_Factor() ) {
- sprintf(buffer, "%sICNH", _file[lp]);
- } else {
- sprintf(buffer, "%sICON", _file[lp]);
- }
- _makepath(fullname, NULL, NULL, buffer, ".SHP");
- SpecialShapes[lp] = MixFileClass::Retrieve(fullname);
- }
- }
- /***********************************************************************************************
- * SidebarClass::StripClass::Get_Special_Cameo -- Fetches the special event cameo shape. *
- * *
- * This routine will return with a pointer to the cameo data for the special objects that *
- * can appear on the sidebar (e.g., nuclear bomb). *
- * *
- * INPUT: type -- The special type to fetch the cameo imagery for. *
- * *
- * OUTPUT: Returns with a pointer to the cameo imagery for the specified special object. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 05/19/1995 JLB : commented *
- *=============================================================================================*/
- void const * SidebarClass::StripClass::Get_Special_Cameo(int type)
- {
- return(SpecialShapes[type]);
- }
- /***********************************************************************************************
- * SidebarClass::StripClass::Init_Clear -- Sets sidebar to a known (and deactivated) state *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 12/24/1994 JLB : Created. *
- *=============================================================================================*/
- void SidebarClass::StripClass::Init_Clear(void)
- {
- IsScrollingDown = false;
- IsScrolling = false;
- IsBuilding = false;
- Flasher = -1;
- TopIndex = 0;
- Slid = 0;
- BuildableCount = 0;
- /*
- ** Since we're resetting the strips, clear out all the buildables & factory pointers.
- */
- for (int index = 0; index < MAX_BUILDABLES; index++) {
- Buildables[index].BuildableID = 0;
- Buildables[index].BuildableType = RTTI_NONE;
- Buildables[index].Factory = -1;
- }
- }
- /***********************************************************************************************
- * SidebarClass::StripClass::Init_IO -- Initializes the strip's buttons *
- * *
- * This routine doesn't actually add any buttons to the list;
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 12/24/1994 JLB : Created. *
- *=============================================================================================*/
- void SidebarClass::StripClass::Init_IO(int id)
- {
- ID = id;
- UpButton[ID].IsSticky = true;
- UpButton[ID].ID = BUTTON_UP+id;
- UpButton[ID].X = X+ButtonSpacingOffset+1;
- UpButton[ID].Y = Y+MAX_VISIBLE*ObjectHeight-1;
- UpButton[ID].Set_Shape(Hires_Retrieve("STRIPUP.SHP"));
- DownButton[ID].IsSticky = true;
- DownButton[ID].ID = BUTTON_DOWN+id;
- DownButton[ID].X = UpButton[ID].X + UpButton[ID].Width + ButtonSpacingOffset-2;
- DownButton[ID].Y = Y+MAX_VISIBLE*ObjectHeight-1;
- DownButton[ID].Set_Shape(Hires_Retrieve("STRIPDN.SHP"));
- for (int index = 0; index < MAX_VISIBLE; index++) {
- SelectClass & g = SelectButton[ID][index];
- g.ID = BUTTON_SELECT;
- g.X = X;
- g.Y = Y + (ObjectHeight*index);
- g.Width = ObjectWidth;
- g.Height = ObjectHeight;
- g.Set_Owner(*this, index);
- }
- }
- /***********************************************************************************************
- * SidebarClass::StripClass::Init_Theater -- Performs theater-specific initialization *
- * *
- * INPUT: theater *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 12/24/1994 JLB : Created. *
- *=============================================================================================*/
- void SidebarClass::StripClass::Init_Theater(TheaterType theater)
- {
- //if (theater != LastTheater) {
- static char *_file[3] = {
- "ION",
- "ATOM",
- "BOMB"
- };
- int factor = Get_Resolution_Factor();
- char fullname[_MAX_FNAME+_MAX_EXT];
- char buffer[_MAX_FNAME];
- void const * cameo_ptr;
- for (int lp = 0; lp < 3; lp++) {
- if ( Get_Resolution_Factor() ) {
- sprintf(buffer, "%sICNH", _file[lp]);
- } else {
- sprintf(buffer, "%sICON", _file[lp]);
- }
- _makepath(fullname, NULL, NULL, buffer, Theaters[theater].Suffix);
- cameo_ptr = MixFileClass::Retrieve(fullname);
- if (cameo_ptr){
- SpecialShapes[lp] = cameo_ptr;
- }
- }
- #ifndef _RETRIEVE
- static TLucentType const ClockCols[1] = {
- // {LTGREEN, BLACK, 0, 0},
- {GREEN, LTGREY, 180, 0}
- };
- /*
- ** Make sure that remapping doesn't occur on the colors that cycle.
- */
- Mem_Copy(GamePalette, OriginalPalette, 768);
- memset(&GamePalette[CYCLE_COLOR_START*3], 0x3f, CYCLE_COLOR_COUNT*3);
- /*
- ** Create the translucent table used for the sidebar.
- */
- Build_Translucent_Table(GamePalette, &ClockCols[0], 1, (void*)ClockTranslucentTable);
- CCFileClass(Fading_Table_Name("CLOCK", theater)).Write(ClockTranslucentTable, sizeof(ClockTranslucentTable));
- Mem_Copy(OriginalPalette, GamePalette, 768);
- #else
- CCFileClass(Fading_Table_Name("CLOCK", theater)).Read(ClockTranslucentTable, sizeof(ClockTranslucentTable));
- #endif
- LastTheater = theater;
- //}
- }
- /***********************************************************************************************
- * SidebarClass::StripClass::Activate -- Adds the strip buttons to the input system. *
- * *
- * This routine will add the side strip buttons to the map's input system. This routine *
- * should be called once when the sidebar activates. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: Never call this routine a second time without first calling Deactivate(). *
- * *
- * HISTORY: *
- * 01/19/1995 JLB : Created. *
- *=============================================================================================*/
- void SidebarClass::StripClass::Activate(void)
- {
- UpButton[ID].Zap();
- Map.Add_A_Button(UpButton[ID]);
- DownButton[ID].Zap();
- Map.Add_A_Button(DownButton[ID]);
- for (int index = 0; index < MAX_VISIBLE; index++) {
- SelectButton[ID][index].Zap();
- Map.Add_A_Button(SelectButton[ID][index]);
- }
- }
- /***********************************************************************************************
- * SidebarClass::StripClass::Deactivate -- Removes the side strip buttons from the input syste *
- * *
- * Call this routine to remove all the buttons on the side strip from the map's input *
- * system. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: Never call this routine unless the Activate() function was prevously called. *
- * *
- * HISTORY: *
- * 01/19/1995 JLB : Created. *
- *=============================================================================================*/
- void SidebarClass::StripClass::Deactivate(void)
- {
- Map.Remove_A_Button(UpButton[ID]);
- Map.Remove_A_Button(DownButton[ID]);
- for (int index = 0; index < MAX_VISIBLE; index++) {
- Map.Remove_A_Button(SelectButton[ID][index]);
- }
- }
- #ifdef NEVER
- /***********************************************************************************************
- * sortfunc -- Utility routine that handles 'qsort' the strip buttons. *
- * *
- * This routine is called by qsort() in order to sort the sidebar buttons. This sorting *
- * forces the sidebar buttons to always occur in the order that they can be built in, *
- * rather than the order that they were added to the sidebar list. *
- * *
- * INPUT: ptr1 -- Pointer to the first sidebar class object. *
- * *
- * ptr2 -- Pointer to the second sidebar class object. *
- * *
- * OUTPUT: Returns <0 if the first object can be produced before the second. It returns *
- * >0 if the reverse is true. It returns exactly 0 if the production scneario for *
- * both objects is the same. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 05/18/1995 JLB : Created. *
- *=============================================================================================*/
- static int sortfunc(void const * ptr1, void const * ptr2)
- {
- SidebarClass::StripClass::BuildType * b1 = (SidebarClass::StripClass::BuildType *)ptr1;
- SidebarClass::StripClass::BuildType * b2 = (SidebarClass::StripClass::BuildType *)ptr2;
- TechnoTypeClass const * p1 = Fetch_Techno_Type(b1->BuildableType, b1->BuildableID);
- TechnoTypeClass const * p2 = Fetch_Techno_Type(b2->BuildableType, b2->BuildableID);
- int i1 = 0;
- int i2 = 0;
- if (p1) i1 = p1->What_Am_I()*2;
- if (p2) i2 = p2->What_Am_I()*2;
- /*
- ** Walls should be sorted after the regular buildings.
- */
- if (p1 && p1->What_Am_I() == RTTI_BUILDINGTYPE && ((BuildingTypeClass * const)p1)->IsWall) {
- i1++;
- }
- if (p2 && p2->What_Am_I() == RTTI_BUILDINGTYPE && ((BuildingTypeClass * const)p2)->IsWall) {
- i2++;
- }
- /*
- ** If the object types are identical, then sort by scenario available.
- */
- if (i1 == i2) {
- /*
- ** In the case of walls (can tell if there is an odd value), then sort
- ** by cost.
- */
- if (i1 & 0x01) {
- i1 = p1->Cost;
- i2 = p2->Cost;
- } else {
- i1 = p1->Scenario;
- i2 = p2->Scenario;
- }
- }
- return(i1 - i2);
- }
- #endif
- /***********************************************************************************************
- * SidebarClass::StripClass::Add -- Add an object to the side strip. *
- * *
- * Use this routine to add a buildable object to the side strip. *
- * *
- * INPUT: object -- Pointer to the object type that can be built and is to be added to *
- * the side strip. *
- * *
- * OUTPUT: bool; Was the object successfully added to the side strip? Failure could be the *
- * result of running out of room in the side strip array or the object might *
- * already be in the list. *
- * *
- * WARNINGS: none. *
- * *
- * HISTORY: *
- * 12/31/1994 JLB : Created. *
- *=============================================================================================*/
- bool SidebarClass::StripClass::Add(RTTIType type, int id)
- {
- if (BuildableCount <= MAX_BUILDABLES) {
- for (int index = 0; index < BuildableCount; index++) {
- if (Buildables[index].BuildableType == type && Buildables[index].BuildableID == id) {
- return(false);
- }
- }
- if (!ScenarioInit && type != RTTI_SPECIAL) {
- Speak(VOX_NEW_CONSTRUCT);
- }
- Buildables[BuildableCount].BuildableType = type;
- Buildables[BuildableCount].BuildableID = id;
- BuildableCount++;
- IsToRedraw = true;
- #ifdef OBSOLETE
- if (GameToPlay == GAME_NORMAL) {
- qsort(&Buildables[0], BuildableCount, sizeof(Buildables[0]), sortfunc);
- }
- #endif
- return(true);
- }
- return(false);
- }
- /***********************************************************************************************
- * SidebarClass::StripClass::Scroll -- Causes the side strip to scroll. *
- * *
- * Use this routine to flag the side strip to scroll. The direction scrolled is controlled *
- * by the parameter. Scrolling is merely initiated by this routine. Subsequent calls to *
- * the AI function and the Draw_It function are required to properly give the appearence *
- * of scrolling. *
- * *
- * INPUT: bool; Should the side strip scroll UP? If it is to scroll down then pass false. *
- * *
- * OUTPUT: bool; Was the side strip started to scroll in the desired direction? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 12/31/1994 JLB : Created. *
- * 07/29/1995 JLB : Simplified scrolling logic. *
- *=============================================================================================*/
- bool SidebarClass::StripClass::Scroll(bool up)
- {
- if (up) {
- Scroller--;
- } else {
- Scroller++;
- }
- #ifdef NEVER
- if (BuildableCount <= MAX_VISIBLE) return(false);
- /*
- ** Top of list is moving toward lower ordered entries in the object list. It looks like
- ** the "window" to the object list is moving up even though the actual object images are
- ** scrolling downward.
- */
- if (up) {
- if (!TopIndex) return(false);
- TopIndex--;
- Slid = 0;
- } else {
- if (TopIndex+MAX_VISIBLE >= BuildableCount) return(false);
- Slid = ObjectHeight;
- }
- IsScrollingDown = !up;
- IsScrolling = true;
- #endif
- return(true);
- }
- /***********************************************************************************************
- * SidebarClass::StripClass::Flag_To_Redra -- Flags the sidebar strip to be redrawn. *
- * *
- * This utility routine is called when something changes on the sidebar and it must be *
- * reflected the next time drawing is performed. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 05/18/1995 JLB : Created. *
- *=============================================================================================*/
- void SidebarClass::StripClass::Flag_To_Redraw(void)
- {
- IsToRedraw = true;
- //Map.SidebarClass::IsToRedraw = true;
- Map.Flag_To_Redraw(false);
- }
- /***********************************************************************************************
- * SidebarClass::StripClass::AI -- Input and AI processing for the side strip. *
- * *
- * The side strip AI processing is performed by this function. This function not only *
- * checks for player input, but also handles any graphic logic updating necessary as a *
- * result of flashing or construction animation. *
- * *
- * INPUT: input -- The player input code. *
- * *
- * x,y -- Mouse coordinate to use. *
- * *
- * OUTPUT: bool; Did the AI detect that it will need a rendering change? If this routine *
- * returns true, then the Draw_It function should be called at the *
- * earliest opportunity. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 12/31/1994 JLB : Created. *
- * 12/31/1994 JLB : Uses mouse coordinate parameters. *
- *=============================================================================================*/
- bool SidebarClass::StripClass::AI(KeyNumType & input, int , int )
- {
- bool redraw = false;
- /*
- ** If this is scroll button for this side strip, then scroll the strip as
- ** indicated.
- */
- if (input == (UpButton[ID].ID|KN_BUTTON)) { // && !IsScrolling
- UpButton[ID].IsPressed = false;
- Scroll(true);
- }
- if (input == (DownButton[ID].ID|KN_BUTTON)) { // && !IsScrolling
- DownButton[ID].IsPressed = false;
- Scroll(false);
- }
- /*
- ** Reflect the scroll desired direction/value into the scroll
- ** logic handler. This might result in up or down scrolling.
- */
- if (!IsScrolling && Scroller) {
- if (BuildableCount <= MAX_VISIBLE) {
- Scroller = 0;
- } else {
- /*
- ** Top of list is moving toward lower ordered entries in the object list. It looks like
- ** the "window" to the object list is moving up even though the actual object images are
- ** scrolling downward.
- */
- if (Scroller < 0) {
- if (!TopIndex) {
- Scroller = 0;
- } else {
- Scroller++;
- IsScrollingDown = false;
- IsScrolling = true;
- TopIndex--;
- Slid = 0;
- }
- } else {
- if (TopIndex+MAX_VISIBLE >= BuildableCount) {
- Scroller = 0;
- } else {
- Scroller--;
- Slid = ObjectHeight;
- IsScrollingDown = true;
- IsScrolling = true;
- }
- }
- }
- }
- /*
- ** Scroll logic is handled here.
- */
- if (IsScrolling) {
- if (IsScrollingDown) {
- Slid -= SCROLL_RATE;
- if (Slid <= 0) {
- IsScrolling = false;
- Slid = 0;
- TopIndex++;
- }
- } else {
- Slid += SCROLL_RATE;
- if (Slid >= ObjectHeight) {
- IsScrolling = false;
- Slid = 0;
- }
- }
- redraw = true;
- }
- /*
- ** Handle any flashing logic. Flashing occurs when the player selects an object
- ** and provides the visual feedback of a recognized and legal selection.
- */
- if (Flasher != -1) {
- if (Graphic_Logic()) {
- redraw = true;
- if (Fetch_Stage() >= 7) {
- Set_Rate(0);
- Set_Stage(0);
- Flasher = -1;
- }
- }
- }
- /*
- ** Handle any building clock animation logic.
- */
- if (IsBuilding) {
- for (int index = 0; index < BuildableCount; index++) {
- int factoryid = Buildables[index].Factory;
- if (factoryid != -1) {
- FactoryClass * factory = Factories.Raw_Ptr(factoryid);
- if (factory && factory->Has_Changed()) {
- redraw = true;
- if (factory->Has_Completed()) {
- /*
- ** Construction has been completed. Announce this fact to the player and
- ** try to get the object to automatically leave the factory. Buildings are
- ** the main exception to the ability to leave the factory under their own
- ** power.
- */
- TechnoClass * pending = factory->Get_Object();
- if (pending) {
- switch (pending->What_Am_I()) {
- case RTTI_UNIT:
- case RTTI_AIRCRAFT:
- OutList.Add(EventClass(EventClass::PLACE, pending->What_Am_I(), -1));
- // Fall into next case.
- case RTTI_BUILDING:
- Speak(VOX_CONSTRUCTION);
- break;
- case RTTI_INFANTRY:
- OutList.Add(EventClass(EventClass::PLACE, pending->What_Am_I(), -1));
- Speak(VOX_UNIT_READY);
- break;
- }
- }
- }
- }
- }
- }
- }
- /*
- ** If any of the logic determined that this side strip needs to be redrawn, then
- ** set the redraw flag for this side strip.
- */
- if (redraw) {
- Flag_To_Redraw();
- }
- return(redraw);
- }
- /***********************************************************************************************
- * SidebarClass::StripClass::Draw_It -- Render the sidebar display. *
- * *
- * Use this routine to render the sidebar display. It checks to see if it needs to be *
- * redrawn and only redraw if necessary. If the "complete" parameter is true, then it *
- * will force redraw the entire strip. *
- * *
- * INPUT: complete -- Should the redraw be forced? A force redraw will ignore the redraw *
- * flag. *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 12/31/1994 JLB : Created. *
- * 08/06/1995 JLB : Handles multi factory tracking in same strip. *
- *=============================================================================================*/
- void SidebarClass::StripClass::Draw_It(bool complete)
- {
- if (IsToRedraw || complete) {
- IsToRedraw = false;
- /*
- ** Fills the background to the side strip. We shouldnt need to do this if the strip
- ** has a full complement of icons. ST - 10/7/96 6:03PM
- */
- if (BuildableCount < MAX_VISIBLE){
- CC_Draw_Shape(LogoShapes, ID, X+3, Y-1, WINDOW_MAIN, SHAPE_WIN_REL|SHAPE_NORMAL, 0);
- }
- /*
- ** Redraw the scroll buttons.
- */
- UpButton[ID].Draw_Me(true);
- DownButton[ID].Draw_Me(true);
- /*
- ** Loop through all the buildable objects that are visible in the strip and render
- ** them. Their Y offset may be adjusted if the strip is in the process of scrolling.
- */
- for (int i = 0; i < MAX_VISIBLE + (IsScrolling ? 1 : 0); i++) {
- bool production;
- bool completed;
- int stage;
- bool darken = false;
- void const * shapefile = 0;
- int shapenum = 0;
- void const * remapper = 0;
- FactoryClass * factory = 0;
- int index = i+TopIndex;
- int x = X;
- int y = Y + i*ObjectHeight;
- y--;
- /*
- ** If the strip is scrolling, then the offset is adjusted accordingly.
- */
- if (IsScrolling) {
- y -= ObjectHeight - Slid;
- }
- /*
- ** Fetch the shape number for the object type located at this current working
- ** slot. This shape pointer is used to draw the underlying graphic there.
- */
- if ((unsigned)index < BuildableCount) {
- ObjectTypeClass const * obj = NULL;
- int spc = 0;
- if (Buildables[index].BuildableType != RTTI_SPECIAL) {
- obj = Fetch_Techno_Type(Buildables[index].BuildableType, Buildables[index].BuildableID);
- if (obj) {
- bool isbusy = false;
- switch (Buildables[index].BuildableType) {
- case RTTI_INFANTRYTYPE:
- isbusy = (PlayerPtr->InfantryFactory != -1);
- break;
- case RTTI_BUILDINGTYPE:
- isbusy = (PlayerPtr->BuildingFactory != -1);
- if (!BuildingTypeClass::As_Reference((StructType)Buildables[index].BuildableID).IsWall) {
- remapper = PlayerPtr->Remap_Table(false, false);
- }
- break;
- case RTTI_UNITTYPE:
- isbusy = (PlayerPtr->UnitFactory != -1);
- switch (Buildables[index].BuildableID) {
- case UNIT_MCV:
- case UNIT_HARVESTER:
- remapper = PlayerPtr->Remap_Table(false, false);
- break;
- default:
- remapper = PlayerPtr->Remap_Table(false, true);
- break;
- }
- break;
- case RTTI_AIRCRAFTTYPE:
- isbusy = (PlayerPtr->AircraftFactory != -1);
- remapper = PlayerPtr->Remap_Table(false, true);
- break;
- }
- shapefile = obj->Get_Cameo_Data();
- shapenum = 0;
- if (Buildables[index].Factory != -1) {
- factory = Factories.Raw_Ptr(Buildables[index].Factory);
- production = true;
- completed = factory->Has_Completed();
- stage = factory->Completion();
- darken = false;
- } else {
- production = false;
- // darken = IsBuilding;
- /*
- ** Darken the imagery if a factory of a matching type is
- ** already busy.
- */
- darken = isbusy;
- }
- }
- } else {
- spc = Buildables[index].BuildableID;
- shapefile = Get_Special_Cameo(spc - 1);
- shapenum = 0;
- switch (spc) {
- case SPC_ION_CANNON:
- production = true;
- completed = PlayerPtr->IonCannon.Is_Ready();
- stage = PlayerPtr->IonCannon.Anim_Stage();
- darken = false;
- break;
- case SPC_AIR_STRIKE:
- production = true;
- completed = PlayerPtr->AirStrike.Is_Ready();
- stage = PlayerPtr->AirStrike.Anim_Stage();
- darken = false;
- break;
- case SPC_NUCLEAR_BOMB:
- production = true;
- completed = PlayerPtr->NukeStrike.Is_Ready();
- stage = PlayerPtr->NukeStrike.Anim_Stage();
- darken = false;
- break;
- }
- }
- if (obj || spc) {
- /*
- ** If this item is flashing then take care of it.
- **
- */
- if (Flasher == index && (Fetch_Stage() & 0x01)) {
- remapper = Map.FadingLight;
- }
- } else {
- shapefile = LogoShapes;
- shapenum = SB_BLANK;
- }
- } else {
- shapefile = LogoShapes;
- shapenum = SB_BLANK;
- production = false;
- }
- remapper = 0;
- /*
- ** Now that the shape of the object at the current working slot has been found,
- ** draw it and any graphic overlays as necessary.
- **
- ** Dont draw blank shapes over the new 640x400 sidebar art - ST 5/1/96 6:01PM
- */
- if (shapenum != SB_BLANK || shapefile != LogoShapes){
- IsTheaterShape = true; // This shape is theater specific
- CC_Draw_Shape(shapefile, shapenum,
- x-(WindowList[WINDOW_SIDEBAR][WINDOWX]*8)+LeftEdgeOffset,
- y-WindowList[WINDOW_SIDEBAR][WINDOWY],
- WINDOW_SIDEBAR,
- SHAPE_NORMAL|SHAPE_WIN_REL| (remapper ? SHAPE_FADING : SHAPE_NORMAL),
- remapper);
- IsTheaterShape = false;
- /*
- ** Darken this object because it cannot be produced or is otherwise
- ** unavailable.
- */
- if (darken) {
- CC_Draw_Shape(ClockShapes, 0,
- x-(WindowList[WINDOW_SIDEBAR][WINDOWX]*8)+LeftEdgeOffset,
- y-WindowList[WINDOW_SIDEBAR][WINDOWY],
- WINDOW_SIDEBAR,
- SHAPE_NORMAL|SHAPE_WIN_REL|SHAPE_GHOST,
- NULL, ClockTranslucentTable);
- }
- }
- /*
- ** Draw the overlapping clock shape if this is object is being constructed.
- ** If the object is completed, then display "Ready" with no clock shape.
- */
- if (production) {
- if (completed) {
- /*
- ** Display text showing that the object is ready to place.
- */
- CC_Draw_Shape(ObjectTypeClass::PipShapes, PIP_READY,
- (x-(WindowList[WINDOW_SIDEBAR][WINDOWX]*8))+LeftEdgeOffset+(ObjectWidth >> 1),
- (y-WindowList[WINDOW_SIDEBAR][WINDOWY])+ObjectHeight-Get_Build_Frame_Height(ObjectTypeClass::PipShapes) -8,
- WINDOW_SIDEBAR, SHAPE_CENTER);
- // Fancy_Text_Print(TXT_READY, x+TEXT_X_OFFSET, y+TEXT_Y_OFFSET, TEXT_COLOR, TBLACK, TPF_6POINT|TPF_CENTER|TPF_NOSHADOW);
- } else {
- CC_Draw_Shape(ClockShapes, stage+1,
- x-(WindowList[WINDOW_SIDEBAR][WINDOWX]*8)+LeftEdgeOffset,
- y-WindowList[WINDOW_SIDEBAR][WINDOWY],
- WINDOW_SIDEBAR,
- SHAPE_NORMAL|SHAPE_WIN_REL|SHAPE_GHOST,
- NULL, ClockTranslucentTable);
- /*
- ** Display text showing that the construction is temporarily on hold.
- */
- if (factory && !factory->Is_Building()) {
- CC_Draw_Shape(ObjectTypeClass::PipShapes, PIP_HOLDING,
- (x-(WindowList[WINDOW_SIDEBAR][WINDOWX]*8))+LeftEdgeOffset+(ObjectWidth >> 1),
- (y-WindowList[WINDOW_SIDEBAR][WINDOWY])+ObjectHeight-Get_Build_Frame_Height(ObjectTypeClass::PipShapes) - 8, // Moved up now that icons have names on them
- WINDOW_SIDEBAR, SHAPE_CENTER);
- // Fancy_Text_Print(TXT_HOLDING, x+TEXT_X_OFFSET, y+TEXT_Y_OFFSET, TEXT_COLOR, TBLACK, TPF_6POINT|TPF_CENTER|TPF_NOSHADOW);
- }
- }
- }
- }
- }
- }
- /***********************************************************************************************
- * SidebarClass::StripClass::Recalc -- Revalidates the current sidebar list of objects. *
- * *
- * This routine will revalidate all the buildable objects in the sidebar. This routine *
- * comes in handy when a factory has been destroyed, and the sidebar needs to reflect any *
- * change that this requires. It checks every object to see if there is a factory available *
- * that could produce it. If none can be found, then the object is removed from the *
- * sidebar. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: bool; The sidebar has changed as a result of this call? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 01/19/1995 JLB : Created. *
- * 06/26/1995 JLB : Doesn't collapse sidebar when buildables removed. *
- *=============================================================================================*/
- bool SidebarClass::StripClass::Recalc(void)
- {
- int ok;
- if (Debug_Map || !BuildableCount) {
- return(false);
- }
- /*
- ** Sweep through all objects listed in the sidebar. If any of those object can
- ** not be created -- even in theory -- then they must be removed form the sidebar and
- ** any current production must be abandoned.
- */
- bool redraw = false;
- for (int index = 0; index < BuildableCount; index++) {
- TechnoTypeClass const * tech = Fetch_Techno_Type(Buildables[index].BuildableType, Buildables[index].BuildableID);
- if (tech) {
- ok = tech->Who_Can_Build_Me(true, false, PlayerPtr->Class->House) != NULL;
- } else {
- switch (Buildables[index].BuildableID) {
- case SPC_ION_CANNON:
- ok = PlayerPtr->IonCannon.Is_Present();
- break;
- case SPC_NUCLEAR_BOMB:
- ok = PlayerPtr->NukeStrike.Is_Present();
- break;
- case SPC_AIR_STRIKE:
- ok = PlayerPtr->AirStrike.Is_Present();
- break;
- default:
- ok = false;
- break;
- }
- #ifdef OBSOLETE
- } else {
- switch (Buildables[index].BuildableID) {
- case SPC_ION_CANNON:
- ok = (PlayerPtr->BScan & STRUCTF_EYE) != 0 || PlayerPtr->IonOneTimeFlag;
- if (!ok) {
- PlayerPtr->Remove_Ion_Cannon();
- }
- break;
- case SPC_NUCLEAR_BOMB:
- ok = (PlayerPtr->BScan & STRUCTF_TEMPLE) != 0 && PlayerPtr->Has_Nuke_Device();
- ok = ok || PlayerPtr->NukeOneTimeFlag;
- if (!ok) {
- PlayerPtr->Remove_Nuke_Bomb();
- }
- break;
- case SPC_AIR_STRIKE:
- // ok = (PlayerPtr->BScan & STRUCTF_SAM) == 0;
- // ok = !PlayerPtr->Does_Enemy_Building_Exist(STRUCT_SAM);
- ok = (PlayerPtr->AirPresent /*&& !PlayerPtr->Does_Enemy_Building_Exist(STRUCT_SAM)*/) || PlayerPtr->AirOneTimeFlag;
- if (!ok) {
- PlayerPtr->Remove_Air_Strike();
- }
- break;
- default:
- ok = false;
- break;
- }
- #endif
- }
- if (!ok) {
- /*
- ** If there was something in production, then abandon it before deleting the
- ** factory manager.
- */
- //if (Buildables[index].Factory != -1) {
- //FactoryClass * factory = Factories.Raw_Ptr(Buildables[index].Factory);
- //factory->Abandon();
- //delete factory;
- //Buildables[index].Factory = -1;
- //}
- // Buildables[index].Factory = -1;
- /*
- ** Removes this entry from the list.
- */
- if (BuildableCount > 1 && index < BuildableCount-1) {
- memcpy(&Buildables[index], &Buildables[index+1], sizeof(Buildables[0])*((BuildableCount-index)-1));
- }
- TopIndex = 0;
- IsToRedraw = true;
- redraw = true;
- BuildableCount--;
- index--;
- }
- }
- #ifdef NEVER
- /*
- ** If there are no more buildable objects to display, make the sidebar go away.
- */
- if (!BuildableCount) {
- Map.SidebarClass::Activate(0);
- }
- #endif
- return(redraw);
- }
- /***********************************************************************************************
- * SidebarClass::StripClass::SelectClass::SelectClass -- Default constructor. *
- * *
- * This is the default constructor for the button that controls the buildable cameos on *
- * the sidebar strip. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: The coordinates are set to zero by this routine. They must be set to the *
- * correct values before this button will function. *
- * *
- * HISTORY: *
- * 01/19/1995 JLB : Created. *
- *=============================================================================================*/
- SidebarClass::StripClass::SelectClass::SelectClass(void) :
- ControlClass(0, 0, 0, 0, 0, LEFTPRESS|RIGHTPRESS|LEFTUP)
- {
- int factor = Get_Resolution_Factor();
- Strip = 0;
- Index = 0;
- Width = StripClass::OBJECT_WIDTH << factor;
- Height = StripClass::OBJECT_HEIGHT << factor;
- }
- /***********************************************************************************************
- * SidebarClass::StripClass::SelectClass:: -- Assigns special values to a buildable select but *
- * *
- * Use this routine to set custom buildable vars for this particular select button. It *
- * uses this information to properly know what buildable object to start or stop production *
- * on. *
- * *
- * INPUT: strip -- Reference to the strip that owns this buildable button. *
- * *
- * index -- The index (0 .. MAX_VISIBLE-1) of this button. This is used to let *
- * the owning strip know what index this button refers to. *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 01/19/1995 JLB : Created. *
- *=============================================================================================*/
- void SidebarClass::StripClass::SelectClass::Set_Owner(StripClass & strip, int index)
- {
- int factor = Get_Resolution_Factor();
- Strip = &strip;
- Index = index;
- X = strip.X;
- Y = strip.Y + (index * (StripClass::OBJECT_HEIGHT << factor));
- }
- /***********************************************************************************************
- * SidebarClass::StripClass::SelectClass:: -- Action function when buildable cameo is selected *
- * *
- * This function is called when the buildable icon (cameo) is clicked on. It handles *
- * starting and stopping production as indicated. *
- * *
- * INPUT: flags -- The input event that triggered the call. *
- * *
- * key -- The keyboard value at the time of the input. *
- * *
- * OUTPUT: Returns with whether the input list should be scanned further. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 01/19/1995 JLB : Created. *
- *=============================================================================================*/
- int SidebarClass::StripClass::SelectClass::Action(unsigned flags, KeyNumType & key)
- {
- int index = Strip->TopIndex + Index;
- RTTIType otype = Strip->Buildables[index].BuildableType;
- int oid = Strip->Buildables[index].BuildableID;
- int fnumber = Strip->Buildables[index].Factory;
- FactoryClass * factory = NULL;
- ObjectTypeClass const * choice = NULL;
- int spc = 0;
- /*
- ** Determine the factory number that would apply to objects of the type
- ** the mouse is currently addressing. This doesn't mean that the factory number
- ** fetched is actually producing the indicated object, merely that that particular
- ** kind of factory is specified by the "genfactory" value. This can be used to see
- ** if the factory type is currently busy or not.
- */
- int genfactory = -1;
- switch (otype) {
- case RTTI_INFANTRYTYPE:
- genfactory = PlayerPtr->InfantryFactory;
- break;
- case RTTI_UNITTYPE:
- genfactory = PlayerPtr->UnitFactory;
- break;
- case RTTI_AIRCRAFTTYPE:
- genfactory = PlayerPtr->AircraftFactory;
- break;
- case RTTI_BUILDINGTYPE:
- genfactory = PlayerPtr->BuildingFactory;
- break;
- default:
- genfactory = -1;
- break;
- }
- Map.Override_Mouse_Shape(MOUSE_NORMAL);
- if (index < Strip->BuildableCount) {
- if (otype != RTTI_SPECIAL) {
- choice = Fetch_Techno_Type(otype, oid);
- } else {
- spc = oid;
- }
- if (fnumber != -1) {
- factory = Factories.Raw_Ptr(fnumber);
- }
- } else {
- Map.Help_Text(TXT_NONE);
- }
- if (spc) {
- /*
- ** Display the help text if the mouse is over the button.
- */
- if (flags & LEFTUP) {
- switch (spc) {
- case SPC_ION_CANNON:
- Map.Help_Text(TXT_ION_CANNON, X, Y, CC_GREEN, true);
- break;
- case SPC_NUCLEAR_BOMB:
- Map.Help_Text(TXT_NUKE_STRIKE, X, Y, CC_GREEN, true);
- break;
- case SPC_AIR_STRIKE:
- Map.Help_Text(TXT_AIR_STRIKE, X, Y, CC_GREEN, true);
- break;
- }
- flags &= ~LEFTUP;
- }
- /*
- ** A right mouse button signals "cancel". If we are in targetting
- ** mode then we don't want to be any more.
- */
- if (flags & RIGHTPRESS) {
- Map.IsTargettingMode = false;
- }
- /*
- ** A left mouse press signal "activate". If our weapon type is
- ** available then we should activate it.
- */
- if (flags & LEFTPRESS) {
- switch (spc) {
- case SPC_ION_CANNON:
- if (PlayerPtr->IonCannon.Is_Ready()) {
- Map.IsTargettingMode = spc;
- Unselect_All();
- Speak(VOX_SELECT_TARGET);
- } else {
- PlayerPtr->IonCannon.Impatient_Click();
- }
- break;
- case SPC_AIR_STRIKE:
- if (PlayerPtr->AirStrike.Is_Ready()) {
- Map.IsTargettingMode = spc;
- Unselect_All();
- Speak(VOX_SELECT_TARGET);
- } else {
- PlayerPtr->AirStrike.Impatient_Click();
- }
- break;
- case SPC_NUCLEAR_BOMB:
- if (PlayerPtr->NukeStrike.Is_Ready()) {
- Map.IsTargettingMode = spc;
- Unselect_All();
- Speak(VOX_SELECT_TARGET);
- } else {
- PlayerPtr->NukeStrike.Impatient_Click();
- }
- break;
- }
- }
- } else {
- if (choice) {
- /*
- ** Display the help text if the mouse is over the button.
- */
- if (flags & LEFTUP) {
- Map.Help_Text(choice->Full_Name(), X, Y, CC_GREEN, true, choice->Cost_Of());
- flags &= ~LEFTUP;
- }
- /*
- ** A right mouse button signals "cancel".
- */
- if (flags & RIGHTPRESS) {
- /*
- ** If production is in progress, put it on hold. If production is already
- ** on hold, then abandon it. Money will be refunded, the factory
- ** manager deleted, and the object under construction is returned to
- ** the free pool.
- */
- if (factory) {
- /*
- ** Cancels placement mode if the sidebar factory is abandoned or
- ** suspended.
- */
- if (Map.PendingObjectPtr && Map.PendingObjectPtr->Is_Techno()) {
- Map.PendingObjectPtr = 0;
- Map.PendingObject = 0;
- Map.PendingHouse = HOUSE_NONE;
- Map.Set_Cursor_Shape(0);
- }
- if (!factory->Is_Building()) {
- Speak(VOX_CANCELED);
- OutList.Add(EventClass(EventClass::ABANDON, otype, oid));
- } else {
- Speak(VOX_SUSPENDED);
- OutList.Add(EventClass(EventClass::SUSPEND, otype, oid));
- }
- }
- }
- if (flags & LEFTPRESS) {
- /*
- ** If there is already a factory attached to this strip but the player didn't click
- ** on the icon that has the attached factory, then say that the factory is busy and
- ** ignore the click.
- */
- if (fnumber == -1 && genfactory != -1) {
- Speak(VOX_NO_FACTORY);
- ControlClass::Action(flags, key);
- return(true);
- }
- if (factory) {
- /*
- ** If this object is currently being built, then give a scold sound and text and then
- ** bail.
- */
- if (factory->Is_Building()) {
- Speak(VOX_NO_FACTORY);
- } else {
- /*
- ** If production has completed, then attempt to have the object exit
- ** the factory or go into placement mode.
- */
- if (factory->Has_Completed()) {
- TechnoClass * pending = factory->Get_Object();
- if (!pending && factory->Get_Special_Item()) {
- Map.IsTargettingMode = true;
- } else {
- BuildingClass * builder = pending->Who_Can_Build_Me(false, false);
- if (!builder) {
- OutList.Add(EventClass(EventClass::ABANDON, otype, oid));
- Speak(VOX_NO_FACTORY);
- } else {
- /*
- ** If the completed object is a building, then change the
- ** game state into building placement mode. This fact is
- ** not transmitted to any linked computers until the moment
- ** the building is actually placed down.
- */
- if (pending->What_Am_I() == RTTI_BUILDING) {
- PlayerPtr->Manual_Place(builder, (BuildingClass *)pending);
- } else {
- /*
- ** For objects that can leave the factory under their own
- ** power, queue this event and process through normal house
- ** production channels.
- */
- OutList.Add(EventClass(EventClass::PLACE, otype, -1));
- }
- }
- }
- } else {
- /*
- ** The factory must have been in a suspended state. Resume construction
- ** normally.
- */
- Speak(VOX_BUILDING);
- OutList.Add(EventClass(EventClass::PRODUCE, Strip->Buildables[index].BuildableType, Strip->Buildables[index].BuildableID));
- }
- }
- } else {
- /*
- ** If this side strip is already busy with production, then ignore the
- ** input and announce this fact.
- */
- // if (Strip->IsBuilding) {
- // Speak(VOX_NO_FACTORY);
- // } else {
- Speak(VOX_BUILDING);
- OutList.Add(EventClass(EventClass::PRODUCE, Strip->Buildables[index].BuildableType, Strip->Buildables[index].BuildableID));
- // }
- }
- }
- } else {
- flags = 0;
- }
- }
- ControlClass::Action(flags, key);
- return(true);
- }
- /***********************************************************************************************
- * SidebarClass::SBGadgetClass::Action -- Special function that controls the mouse over the si *
- * *
- * This routine is called whenever the mouse is over the sidebar. It makes sure that the *
- * mouse is always the normal shape while over the sidebar. *
- * *
- * INPUT: flags -- The event flags that resuled in this routine being called. *
- * *
- * key -- Reference the keyboard code that may be present. *
- * *
- * OUTPUT: Returns that no further keyboard processing is necessary. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 03/28/1995 JLB : Created. *
- *=============================================================================================*/
- int SidebarClass::SBGadgetClass::Action(unsigned , KeyNumType & )
- {
- Map.Help_Text(TXT_NONE);
- Map.Override_Mouse_Shape(MOUSE_NORMAL, false);
- return(true);
- }
- /***********************************************************************************************
- * SidebarClass::StripClass::Factory_Link -- Links a factory to a sidebar button. *
- * *
- * This routine will link the specified factory to this sidebar strip. The exact button to *
- * link to is determined from the object type and id specified. A linked button is one that *
- * will show appropriate construction animation (clock shape) that matches the state of *
- * the factory. *
- * *
- * INPUT: factory -- The factory number to link to the sidebar. *
- * *
- * type -- The object type that this factory refers to. *
- * *
- * id -- The object sub-type that this factory refers to. *
- * *
- * OUTPUT: Was the factory successfully attached? Failure would indicate that there is no *
- * object of the specified type and sub-type in the sidebar list. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 05/18/1995 JLB : Created. *
- *=============================================================================================*/
- bool SidebarClass::StripClass::Factory_Link(int factory, RTTIType type, int id)
- {
- for (int index = 0; index < BuildableCount; index++) {
- if (Buildables[index].BuildableType == type && Buildables[index].BuildableID == id) {
- Buildables[index].Factory = factory;
- IsBuilding = true;
- /*
- ** Flag that all the icons on this strip need to be redrawn
- */
- Flag_To_Redraw();
- return(true);
- }
- }
- return(false);
- }
- /***********************************************************************************************
- * SidebarClass::Abandon_Production -- Stops production of the object specified. *
- * *
- * This routine is used to abandon production of the object specified. The factory will *
- * be completely disabled by this call. *
- * *
- * INPUT: type -- The object type that is to be abandoned. The sub-type is not needed *
- * since it is presumed there can be only one type in production at any *
- * one time. *
- * *
- * factory -- The factory number that is doing the production. *
- * *
- * OUTPUT: Was the factory successfully abandoned? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 05/18/1995 JLB : Created. *
- *=============================================================================================*/
- bool SidebarClass::Abandon_Production(RTTIType type, int factory)
- {
- return(Column[Which_Column(type)].Abandon_Production(factory));
- }
- /***********************************************************************************************
- * SidebarClass::StripClass::Abandon_Produ -- Abandons production associated with sidebar. *
- * *
- * Production of the object associated with this sidebar is abandoned when this routine is *
- * called. *
- * *
- * INPUT: factory -- The factory index that is to be suspended. *
- * *
- * OUTPUT: Was the production abandonment successful? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 05/18/1995 JLB : Created. *
- * 08/06/1995 JLB : More intelligent abandon logic for multiple factories. *
- *=============================================================================================*/
- bool SidebarClass::StripClass::Abandon_Production(int factory)
- {
- bool noprod = true;
- bool abandon = false;
- for (int index = 0; index < BuildableCount; index++) {
- if (Buildables[index].Factory == factory) {
- Factories.Raw_Ptr(factory)->Abandon();
- Buildables[index].Factory = -1;
- abandon = true;
- } else {
- if (Buildables[index].Factory != -1) {
- noprod = false;
- }
- }
- }
- /*
- ** If there was a change to the strip, then flag the strip to be redrawn.
- */
- if (abandon) {
- Flag_To_Redraw();
- }
- /*
- ** If there is no production whatsoever on this strip, then flag it so.
- */
- if (noprod) {
- IsBuilding = false;
- }
- return(abandon);
- }
|