| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824 |
- /*
- ** Command & Conquer Red Alert(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: /CounterStrike/MAPEDPLC.CPP 1 3/03/97 10:25a 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 : MAPEDPLC.CPP *
- * *
- * Programmer : Bill Randolph *
- * *
- * Start Date : November 18, 1994 *
- * *
- * Last Update : May 12, 1996 [JLB] *
- * *
- *-------------------------------------------------------------------------*
- * Object-placement routines *
- *-------------------------------------------------------------------------*
- * Functions: *
- * MapEditClass::Build_Base_To -- builds the AI base to the given percent*
- * MapEditClass::Cancel_Base_Building -- stops base-building mode *
- * MapEditClass::Cancel_Placement -- cancels placement mode *
- * MapEditClass::Place_Home -- homes the placement object *
- * MapEditClass::Place_Next -- while placing object, goes to next *
- * MapEditClass::Place_Next_Category -- places next object category *
- * MapEditClass::Place_Object -- attempts to place the current object *
- * MapEditClass::Place_Prev -- while placing object, goes to previous *
- * MapEditClass::Place_Prev_Category -- places previous object category *
- * MapEditClass::Place_Trigger -- assigns trigger to object or cell *
- * MapEditClass::Placement_Dialog -- adds an object to the scenario *
- * MapEditClass::Set_House_Buttons -- toggles house buttons for btn list *
- * MapEditClass::Start_Base_Building -- starts base-building mode *
- * MapEditClass::Start_Placement -- enters placement mode *
- * MapEditClass::Start_Trigger_Placement -- enters trigger placement mode*
- * MapEditClass::Stop_Trigger_Placement -- exits trigger placement mode *
- * MapEditClass::Toggle_House -- toggles current placement object's house*
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "function.h"
- #ifdef SCENARIO_EDITOR
- /***************************************************************************
- * MapEditClass::Placement_Dialog -- adds an object to the scenario *
- * *
- * This function sets LastChoice & LastHouse to the values chosen *
- * by the user. It's up to the caller to call Start_Placement to enter *
- * placement mode. *
- * This routine does not modify PendingObject or PendingHouse. *
- * *
- * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ *
- * ³ [GDI] [NOD] [Neutral] ³ *
- * ³ ³ *
- * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ *
- * ³ ³ ³ [Template] ³ *
- * ³ ³ ³ [Overlay ] ³ *
- * ³ ³ ³ [Smudge ] ³ *
- * ³ ³ ³ [Terrain ] ³ *
- * ³ ³ (Object picture) ³ [Unit ] ³ *
- * ³ ³ ³ [Infantry] ³ *
- * ³ ³ ³ [Aircraft] ³ *
- * ³ ³ ³ [Building] ³ *
- * ³ ³ ³ ³ *
- * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÚÄÄÄÄÄÄ¿ ³ *
- * ³ [<-] [->] ³(Grid)³ ³ *
- * ³ ³ ³ ³ *
- * ³ [OK] [Cancel] ÀÄÄÄÄÄÄÙ ³ *
- * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ *
- * *
- * INPUT: *
- * none. *
- * *
- * OUTPUT: *
- * 0 = OK, -1 = cancel *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 10/21/1994 BR : Created. *
- * 12/13/1995 JLB : Fixed house buttons to handle expanded house list. *
- * 05/12/1996 JLB : Handles hi-res. *
- *=========================================================================*/
- int MapEditClass::Placement_Dialog(void)
- {
- HousesType house;
- RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
- /*
- ** Dialog & button dimensions
- */
- enum {
- D_DIALOG_W = 400,
- D_DIALOG_H = 180,
- D_DIALOG_X = 0,
- D_DIALOG_Y = 0,
- D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2),
- D_TXT8_H = 11,
- D_MARGIN = 7,
- D_PICTURE_W = 152, // must be divisible by 8!
- D_PICTURE_H = 105,
- D_PICTURE_X = D_DIALOG_X + 35, // must start on a byte boundary!
- D_PICTURE_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H + D_MARGIN,
- D_PICTURE_CX = D_PICTURE_X + D_PICTURE_W / 2,
- D_GDI_W = 65,
- D_GDI_H = 9,
- D_GDI_X = D_PICTURE_X+D_PICTURE_W+5,
- D_GDI_Y = D_PICTURE_Y,
- D_LEFT_W = 45,
- D_LEFT_H = 9,
- D_LEFT_X = D_PICTURE_CX - 5 - D_LEFT_W,
- D_LEFT_Y = D_PICTURE_Y + D_PICTURE_H + D_MARGIN,
- D_RIGHT_W = 45,
- D_RIGHT_H = 9,
- D_RIGHT_X = D_PICTURE_CX + 5,
- D_RIGHT_Y = D_PICTURE_Y + D_PICTURE_H + D_MARGIN,
- D_TEMPLATE_W = 70,
- D_TEMPLATE_H = 9,
- D_TEMPLATE_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_TEMPLATE_W - 30,
- D_TEMPLATE_Y = D_PICTURE_Y,
- D_OVERLAY_W = 70,
- D_OVERLAY_H = 9,
- D_OVERLAY_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_OVERLAY_W - 30,
- D_OVERLAY_Y = D_TEMPLATE_Y + D_TEMPLATE_H,
- D_SMUDGE_W = 70,
- D_SMUDGE_H = 9,
- D_SMUDGE_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_SMUDGE_W - 30,
- D_SMUDGE_Y = D_OVERLAY_Y + D_OVERLAY_H,
- D_TERRAIN_W = 70,
- D_TERRAIN_H = 9,
- D_TERRAIN_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_TERRAIN_W - 30,
- D_TERRAIN_Y = D_SMUDGE_Y + D_SMUDGE_H,
- D_UNIT_W = 70,
- D_UNIT_H = 9,
- D_UNIT_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_UNIT_W - 30,
- D_UNIT_Y = D_TERRAIN_Y + D_TERRAIN_H,
- D_INFANTRY_W = 70,
- D_INFANTRY_H = 9,
- D_INFANTRY_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_INFANTRY_W - 30,
- D_INFANTRY_Y = D_UNIT_Y + D_UNIT_H,
- D_AIRCRAFT_W = 70,
- D_AIRCRAFT_H = 9,
- D_AIRCRAFT_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_AIRCRAFT_W - 30,
- D_AIRCRAFT_Y = D_INFANTRY_Y + D_INFANTRY_H,
- D_BUILDING_W = 70,
- D_BUILDING_H = 9,
- D_BUILDING_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_BUILDING_W - 30,
- D_BUILDING_Y = D_AIRCRAFT_Y + D_AIRCRAFT_H,
- D_AIR_W = 70,
- D_AIR_H = 9,
- D_AIR_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_AIR_W - 30,
- D_AIR_Y = D_BUILDING_Y + D_BUILDING_H,
- D_OK_W = 45,
- D_OK_H = 9,
- D_OK_X = D_PICTURE_CX - D_OK_W - 5,
- D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_OK_H - D_MARGIN - 15,
- D_CANCEL_W = 45,
- D_CANCEL_H = 9,
- D_CANCEL_X = D_PICTURE_CX + 5,
- D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_CANCEL_H - D_MARGIN - 15,
- GRIDSIZE = 10,
- GRIDBLOCK_W = 3,
- GRIDBLOCK_H = 3,
- D_GRID_X = D_DIALOG_X + D_DIALOG_W - (GRIDSIZE * GRIDBLOCK_W) - D_MARGIN - 35,
- D_GRID_Y = D_DIALOG_Y + D_DIALOG_H - (GRIDSIZE * GRIDBLOCK_H) - D_MARGIN - 35,
- };
- /*
- ** Button enumerations:
- */
- enum {
- BUTTON_GDI=100,
- BUTTON_HOUSE,
- BUTTON_NEXT,
- BUTTON_PREV,
- BUTTON_OK,
- BUTTON_CANCEL,
- BUTTON_TEMPLATE,
- BUTTON_OVERLAY,
- BUTTON_SMUDGE,
- BUTTON_TERRAIN,
- BUTTON_UNIT,
- BUTTON_INFANTRY,
- BUTTON_AIRCRAFT,
- BUTTON_BUILDING,
- BUTTON_AIR,
- };
- /*
- ** Dialog variables
- */
- bool cancel = false; // true = user cancels
- const ObjectTypeClass * curobj; // Working object pointer.
- int x,y; // for drawing the grid
- KeyNumType input; // user input
- short const * occupy; // ptr into object's OccupyList
- int cell; // cell index for parsing OccupyList
- int i;
- int typeindex; // index of class type
- /*
- ** Buttons
- */
- ControlClass * commands;
- ListClass housebtn(BUTTON_HOUSE,
- D_GDI_X, D_GDI_Y, 60, 8*16,
- TPF_EFNT | TPF_NOSHADOW,
- MFCD::Retrieve("EBTN-UP.SHP"),
- MFCD::Retrieve("EBTN-DN.SHP"));
- for (house = HOUSE_FIRST; house < HOUSE_COUNT; house++) {
- housebtn.Add_Item(HouseTypeClass::As_Reference(house).IniName);
- }
- house = HOUSE_FIRST;
- TextButtonClass nextbtn(BUTTON_NEXT, TXT_RIGHT, TPF_EBUTTON, D_RIGHT_X, D_RIGHT_Y, D_RIGHT_W, D_RIGHT_H);
- TextButtonClass prevbtn(BUTTON_PREV, TXT_LEFT, TPF_EBUTTON, D_LEFT_X, D_LEFT_Y, D_LEFT_W, D_LEFT_H);
- TextButtonClass okbtn(BUTTON_OK, "OK", TPF_EBUTTON, D_OK_X, D_OK_Y, D_OK_W, D_OK_H);
- TextButtonClass cancelbtn(BUTTON_CANCEL, "Cancel", TPF_EBUTTON, D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H);
- TextButtonClass templatebtn(BUTTON_TEMPLATE, "Template", TPF_EBUTTON, D_TEMPLATE_X, D_TEMPLATE_Y, D_TEMPLATE_W, D_TEMPLATE_H);
- TextButtonClass overlaybtn(BUTTON_OVERLAY, "Overlay", TPF_EBUTTON, D_OVERLAY_X, D_OVERLAY_Y, D_OVERLAY_W, D_OVERLAY_H);
- TextButtonClass smudgebtn(BUTTON_SMUDGE, "Smudge", TPF_EBUTTON, D_SMUDGE_X, D_SMUDGE_Y, D_SMUDGE_W, D_SMUDGE_H);
- TextButtonClass terrainbtn(BUTTON_TERRAIN, "Terrain", TPF_EBUTTON, D_TERRAIN_X, D_TERRAIN_Y, D_TERRAIN_W, D_TERRAIN_H);
- TextButtonClass unitbtn(BUTTON_UNIT, "Unit", TPF_EBUTTON, D_UNIT_X, D_UNIT_Y, D_UNIT_W, D_UNIT_H);
- TextButtonClass infantrybtn(BUTTON_INFANTRY, "Infantry", TPF_EBUTTON, D_INFANTRY_X, D_INFANTRY_Y, D_INFANTRY_W, D_INFANTRY_H);
- TextButtonClass aircraftbtn(BUTTON_AIRCRAFT, "Ships", TPF_EBUTTON, D_AIRCRAFT_X, D_AIRCRAFT_Y, D_AIRCRAFT_W, D_AIRCRAFT_H);
- TextButtonClass buildingbtn(BUTTON_BUILDING, "Building", TPF_EBUTTON, D_BUILDING_X, D_BUILDING_Y, D_BUILDING_W, D_BUILDING_H);
- TextButtonClass airbtn(BUTTON_AIR, "Aircraft", TPF_EBUTTON, D_AIR_X, D_AIR_Y, D_AIR_W, D_AIR_H);
- /*
- ** Initialize addable objects list; we must do this every time in case one
- ** of the object pools has become exhausted; that object won't be available
- ** for adding. (Skip aircraft, since they won't be used in the editor.)
- */
- Clear_List();
- TemplateTypeClass::Prep_For_Add();
- OverlayTypeClass::Prep_For_Add();
- SmudgeTypeClass::Prep_For_Add();
- TerrainTypeClass::Prep_For_Add();
- UnitTypeClass::Prep_For_Add();
- InfantryTypeClass::Prep_For_Add();
- VesselTypeClass::Prep_For_Add();
- BuildingTypeClass::Prep_For_Add();
- AircraftTypeClass::Prep_For_Add();
- /*
- ** Compute offset of each class type in the Objects array
- */
- TypeOffset[0] = 0;
- for (i = 1; i < NUM_EDIT_CLASSES; i++) {
- TypeOffset[i] = TypeOffset[i-1] + NumType[i-1];
- }
- /*
- ** Return if no objects to place
- */
- if (!ObjCount) {
- return(-1);
- }
- /*
- ** Initialize
- */
- Set_Logic_Page(SeenBuff);
- if (LastChoice >= ObjCount) {
- LastChoice = 0;
- }
- curobj = Objects[LastChoice]; // current object to choose
- commands = &nextbtn;
- housebtn.Add_Tail(*commands);
- prevbtn.Add_Tail(*commands);
- okbtn.Add_Tail(*commands);
- cancelbtn.Add_Tail(*commands);
- templatebtn.Add_Tail(*commands);
- overlaybtn.Add_Tail(*commands);
- smudgebtn.Add_Tail(*commands);
- terrainbtn.Add_Tail(*commands);
- unitbtn.Add_Tail(*commands);
- infantrybtn.Add_Tail(*commands);
- aircraftbtn.Add_Tail(*commands);
- buildingbtn.Add_Tail(*commands);
- airbtn.Add_Tail(*commands);
- /*
- ** Make sure the recorded house selection matches the house list
- ** box selection.
- */
- LastHouse = HousesType(housebtn.Current_Index());
- /*
- ** Main processing loop
- */
- bool display = true;
- bool process = true;
- while (process) {
- /*
- ** Invoke game callback
- */
- Call_Back();
- /*
- ** Refresh display if needed
- */
- if (display) {
- /*
- ** Display the dialog box
- */
- Hide_Mouse();
- Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H);
- Draw_Caption(TXT_PLACE_OBJECT, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W);
- /*
- ** Display the current object:
- ** - save the current window dimensions
- ** - adjust the window size to the actual drawable area
- ** - draw the shape
- ** - reset the window dimensions
- */
- WindowList[WINDOW_EDITOR][WINDOWX] = D_PICTURE_X;
- WindowList[WINDOW_EDITOR][WINDOWY] = D_PICTURE_Y;
- WindowList[WINDOW_EDITOR][WINDOWWIDTH] = D_PICTURE_W;
- WindowList[WINDOW_EDITOR][WINDOWHEIGHT] = D_PICTURE_H;
- Change_Window((int)WINDOW_EDITOR);
- Draw_Box(D_PICTURE_X, D_PICTURE_Y, D_PICTURE_W, D_PICTURE_H, BOXSTYLE_DOWN, false);
- curobj->Display(WinW/2, WinH>>1, WINDOW_EDITOR, LastHouse);
- // curobj->Display(WinW<<2, WinH>>1, WINDOW_EDITOR, LastHouse);
- /*
- ** Erase the grid
- */
- LogicPage->Fill_Rect(D_GRID_X - GRIDBLOCK_W * 2, D_GRID_Y,
- D_GRID_X + GRIDSIZE * GRIDBLOCK_W,
- D_GRID_Y + GRIDSIZE * GRIDBLOCK_H, BLACK);
- /*
- ** Draw a box for every cell occupied
- */
- occupy = curobj->Occupy_List();
- while ( (*occupy) != REFRESH_EOL) {
- cell = (*occupy);
- occupy++;
- x = D_GRID_X + ((cell % MAP_CELL_W) * GRIDBLOCK_W);
- y = D_GRID_Y + ((cell / MAP_CELL_W) * GRIDBLOCK_H);
- LogicPage->Fill_Rect(x, y, x + GRIDBLOCK_W - 1, y + GRIDBLOCK_H - 1, scheme->Bright);
- }
- /*
- ** Draw the grid itself
- */
- for (y = 0; y <= GRIDSIZE; y++) {
- for (x = 0; x <= GRIDSIZE; x++) {
- LogicPage->Draw_Line(D_GRID_X + x * GRIDBLOCK_W, D_GRID_Y,
- D_GRID_X + x * GRIDBLOCK_W,
- D_GRID_Y + GRIDSIZE * GRIDBLOCK_H, scheme->Shadow);
- }
- LogicPage->Draw_Line(D_GRID_X, D_GRID_Y + y * GRIDBLOCK_H,
- D_GRID_X + GRIDSIZE * GRIDBLOCK_W, D_GRID_Y + y * GRIDBLOCK_H,
- scheme->Shadow);
- }
- /*
- ** Print the object's label from the class's Full_Name().
- ** Warning: Text_String returns an EMS pointer, so standard string
- ** functions won't work!
- */
- Fancy_Text_Print (curobj->Full_Name(),
- D_PICTURE_CX, D_PICTURE_Y + D_MARGIN, scheme, TBLACK,
- TPF_CENTER | TPF_EFNT | TPF_NOSHADOW);
- /*
- ** Redraw buttons
- ** Figure out which class category we're in & highlight that button
- ** This updates 'typeindex', which is used below, and it also updates
- ** the category button states.
- */
- i = 0;
- for (typeindex = 0; typeindex < NUM_EDIT_CLASSES; typeindex++) {
- i += NumType[typeindex];
- if (LastChoice < i) break;
- }
- templatebtn.Turn_Off();
- overlaybtn.Turn_Off();
- smudgebtn.Turn_Off();
- terrainbtn.Turn_Off();
- unitbtn.Turn_Off();
- infantrybtn.Turn_Off();
- aircraftbtn.Turn_Off();
- airbtn.Turn_Off();
- buildingbtn.Turn_Off();
- switch (typeindex + BUTTON_TEMPLATE) {
- case BUTTON_TEMPLATE:
- templatebtn.Turn_On();
- break;
- case BUTTON_OVERLAY:
- overlaybtn.Turn_On();
- break;
- case BUTTON_SMUDGE:
- smudgebtn.Turn_On();
- break;
- case BUTTON_TERRAIN:
- terrainbtn.Turn_On();
- break;
- case BUTTON_UNIT:
- unitbtn.Turn_On();
- break;
- case BUTTON_INFANTRY:
- infantrybtn.Turn_On();
- break;
- case BUTTON_AIRCRAFT:
- aircraftbtn.Turn_On();
- break;
- case BUTTON_AIR:
- airbtn.Turn_On();
- break;
- case BUTTON_BUILDING:
- buildingbtn.Turn_On();
- break;
- }
- /*
- ** Redraw buttons
- */
- commands->Draw_All();
- Show_Mouse();
- display = false;
- }
- /*
- ** Get user input
- */
- input = commands->Input();
- /*
- ** Process user input
- */
- switch (input) {
- /*
- ** GDI House
- */
- case (BUTTON_HOUSE | KN_BUTTON):
- house = HousesType(housebtn.Current_Index());
- /*
- ** Set flags & buttons
- */
- LastHouse = house;
- display = true;
- break;
- /*
- ** Next in list
- */
- case (KN_RIGHT):
- case (BUTTON_NEXT | KN_BUTTON):
- /*
- ** Increment to next obj
- */
- LastChoice++;
- if (LastChoice == ObjCount) {
- LastChoice = 0;
- }
- curobj = Objects[LastChoice];
- nextbtn.Turn_Off();
- display = true;
- break;
- /*
- ** Previous in list
- */
- case (KN_LEFT):
- case (BUTTON_PREV | KN_BUTTON):
- /*
- ** Decrement to prev obj
- */
- LastChoice--;
- if (LastChoice < 0) {
- LastChoice = ObjCount-1;
- }
- curobj = Objects[LastChoice];
- prevbtn.Turn_Off();
- display = true;
- break;
- /*
- ** Select a class type
- */
- case (BUTTON_TEMPLATE | KN_BUTTON):
- case (BUTTON_OVERLAY | KN_BUTTON):
- case (BUTTON_SMUDGE | KN_BUTTON):
- case (BUTTON_TERRAIN | KN_BUTTON):
- case (BUTTON_UNIT | KN_BUTTON):
- case (BUTTON_INFANTRY | KN_BUTTON):
- case (BUTTON_AIRCRAFT | KN_BUTTON):
- case (BUTTON_BUILDING | KN_BUTTON):
- case (BUTTON_AIR | KN_BUTTON):
- /*
- ** Find index of class
- */
- typeindex = input - (BUTTON_TEMPLATE | KN_BUTTON);
- /*
- ** If no objects of that type, do nothing
- */
- if (NumType[typeindex]==0) {
- display = true;
- break;
- }
- /*
- ** Set current object
- */
- LastChoice = TypeOffset[typeindex];
- curobj = Objects[LastChoice];
- display = true;
- break;
- /*
- ** Next category
- */
- case KN_PGDN:
- typeindex++;
- if (typeindex==NUM_EDIT_CLASSES) {
- typeindex = 0;
- }
- /*
- ** Set current object
- */
- LastChoice = TypeOffset[typeindex];
- curobj = Objects[LastChoice];
- display = true;
- break;
- /*
- ** Previous category
- */
- case KN_PGUP:
- typeindex--;
- if (typeindex < 0) {
- typeindex = NUM_EDIT_CLASSES - 1;
- }
- /*
- ** Set current object
- */
- LastChoice = TypeOffset[typeindex];
- curobj = Objects[LastChoice];
- display = true;
- break;
- /*
- ** Jump to 1st choice
- */
- case KN_HOME:
- LastChoice = 0;
- /*
- ** Set current object
- */
- curobj = Objects[LastChoice];
- display = true;
- break;
- /*
- ** OK
- */
- case (KN_RETURN):
- case (BUTTON_OK | KN_BUTTON):
- cancel = false;
- process = false;
- break;
- /*
- ** Cancel
- */
- case (KN_ESC):
- case (BUTTON_CANCEL | KN_BUTTON):
- cancel = true;
- process = false;
- break;
- default:
- break;
- }
- }
- /*
- ** Redraw the display
- */
- HidPage.Clear();
- Flag_To_Redraw(true);
- Render();
- if (cancel) {
- return(-1);
- }
- return(0);
- }
- /***************************************************************************
- * MapEditClass::Start_Placement -- enters placement mode *
- * *
- * INPUT: *
- * none. *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 11/04/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::Start_Placement(void)
- {
- /*
- ** Initialize addable objects list; we must do this every time in case one
- ** of the object pools has become exhausted; that object won't be available
- ** for adding. These must be added in the same order expected by the
- ** object selection dialog (same as button order).
- */
- Clear_List();
- TemplateTypeClass::Prep_For_Add();
- OverlayTypeClass::Prep_For_Add();
- SmudgeTypeClass::Prep_For_Add();
- TerrainTypeClass::Prep_For_Add();
- UnitTypeClass::Prep_For_Add();
- InfantryTypeClass::Prep_For_Add();
- VesselTypeClass::Prep_For_Add();
- BuildingTypeClass::Prep_For_Add();
- AircraftTypeClass::Prep_For_Add();
- /*
- ** Compute offset of each class type in the Objects array
- */
- TypeOffset[0] = 0;
- for (int i = 1; i < NUM_EDIT_CLASSES; i++) {
- TypeOffset[i] = TypeOffset[i-1] + NumType[i-1];
- }
- /*
- ** Create the placement object:
- ** - For normal placement mode, use the last-used index into Objects
- ** (LastChoice), and the last-used house (LastHouse).
- ** - For base-building mode, force the object to be a building, and use the
- ** House specified in the Base object
- */
- if (!BaseBuilding) {
- if (LastChoice >= ObjCount) {
- LastChoice = ObjCount - 1;
- }
- PendingObject = Objects[LastChoice];
- PendingHouse = LastHouse;
- PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(LastHouse));
- } else {
- if (LastChoice < TypeOffset[7]) {
- LastChoice = TypeOffset[7];
- }
- if (LastChoice >= ObjCount) {
- LastChoice = ObjCount - 1;
- }
- PendingObject = Objects[LastChoice];
- PendingHouse = LastHouse = Base.House;
- PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(LastHouse));
- }
- /*
- ** Error if no more objects available
- */
- if (!PendingObjectPtr) {
- WWMessageBox().Process("No more objects of this type available.");
- HidPage.Clear();
- Flag_To_Redraw(true);
- Render();
- PendingObject = NULL;
- if (BaseBuilding) {
- Cancel_Base_Building();
- }
- return;
- }
- /*
- ** Set the placement cursor
- */
- Set_Cursor_Pos();
- Set_Cursor_Shape(PendingObject->Occupy_List());
- }
- /***************************************************************************
- * MapEditClass::Place_Object -- attempts to place the current object *
- * *
- * Placement of "real" objects is simply checked via their Unlimbo routine.*
- * Placement of templates is more complex: *
- * - for every cell in the template's OccupyList, check for objects *
- * already in that cell by looking at the cell's OccupyList & *
- * OverlapList *
- * - "lift" all the objects in the cell by Mark'ing them *
- * - temporarily place the template in that cell *
- * - try to Unlimbo all the objects that were in the cell. If any *
- * objects fail to Unlimbo onto that template, the template cannot *
- * be placed here *
- * *
- * It is assumed that the object being placed is a "new" object; the *
- * object's strength & mission are not set during Unlimbo. *
- * *
- * INPUT: *
- * none. *
- * *
- * OUTPUT: *
- * 0 = OK, -1 = unable to place *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 11/04/1994 BR : Created. *
- *=========================================================================*/
- int MapEditClass::Place_Object(void)
- {
- CELL template_cell; // cell being checked for template
- COORDINATE obj_coord; // coord of occupier object
- int okflag; // OK to place a template?
- short const * occupy; // ptr into template's OccupyList
- ObjectClass * occupier; // occupying object
- TemplateType save_ttype; // for saving cell's TType
- unsigned char save_ticon; // for saving cell's TIcon
- // BaseNodeClass node; // for adding to an AI Base
- /*
- ** Placing a template:
- ** - first lift up any objects in the cell
- ** - place the template, and try to replace the objects; if they won't go
- ** back, the template can't go there
- */
- //ScenarioInit++;
- if (PendingObject->What_Am_I() == RTTI_TEMPLATETYPE) {
- /*
- ** Loop through all cells this template will occupy
- */
- okflag = true;
- occupy = PendingObject->Occupy_List();
- while ((*occupy) != REFRESH_EOL) {
- /*
- ** Check this cell for an occupier
- */
- template_cell = (ZoneCell+ZoneOffset) + (*occupy);
- if ((*this)[template_cell].Cell_Occupier()) {
- occupier = (*this)[template_cell].Cell_Occupier();
- /*
- ** Save object's coordinates
- */
- obj_coord = occupier->Coord;
- /*
- ** Place the object in limbo
- */
- occupier->Mark(MARK_UP);
- /*
- ** Set the cell's template values
- */
- save_ttype = (*this)[template_cell].TType;
- save_ticon = (*this)[template_cell].TIcon;
- (*this)[template_cell].TType =
- ((TemplateTypeClass *)PendingObject)->Type;
- (*this)[template_cell].TIcon = Cell_X(*occupy) + Cell_Y(*occupy) *
- ((TemplateTypeClass *)PendingObject)->Width;
- (*this)[template_cell].Recalc_Attributes();
- /*
- ** Try to put the object back down
- */
- if (occupier->Can_Enter_Cell(Coord_Cell(obj_coord)) != MOVE_OK) {
- okflag = false;
- }
- /*
- ** Put everything back the way it was
- */
- (*this)[template_cell].TType = save_ttype;
- (*this)[template_cell].TIcon = save_ticon;
- (*this)[template_cell].Recalc_Attributes();
- /*
- ** Major error if can't replace the object now
- */
- occupier->Mark(MARK_DOWN);
- }
- occupy++;
- }
- /*
- ** If it's still OK after ALL THAT, place the template
- */
- if (okflag) {
- if (PendingObjectPtr->Unlimbo(Cell_Coord(ZoneCell + ZoneOffset))) {
- /*
- ** Loop through all cells occupied by this template, and clear the
- ** smudge & overlay.
- */
- occupy = PendingObject->Occupy_List();
- while ((*occupy) != REFRESH_EOL) {
- /*
- ** Get cell for this occupy item
- */
- template_cell = (ZoneCell+ZoneOffset) + (*occupy);
- /*
- ** Clear smudge & overlay
- */
- (*this)[template_cell].Overlay = OVERLAY_NONE;
- (*this)[template_cell].OverlayData = 0;
- (*this)[template_cell].Smudge = SMUDGE_NONE;
- /*
- ** make adjacent cells recalc attrib's
- */
- (*this)[template_cell].Recalc_Attributes();
- (*this)[template_cell].Wall_Update();
- (*this)[template_cell].Concrete_Calc();
- occupy++;
- }
- /*
- ** Set flags etc
- */
- PendingObjectPtr = 0;
- PendingObject = 0;
- PendingHouse = HOUSE_NONE;
- Set_Cursor_Shape(0);
- //ScenarioInit--;
- TotalValue = Overpass();
- Flag_To_Redraw(false);
- return(0);
- }
- /*
- ** Failure to deploy results in a returned failure code.
- */
- //ScenarioInit--;
- return(-1);
- }
- /*
- ** Not OK; return error
- */
- //ScenarioInit--;
- return(-1);
- }
- /*
- ** Placing infantry: Infantry can go into cell sub-positions, so find the
- ** sub-position closest to the mouse & put him there
- */
- if (PendingObject->What_Am_I() == RTTI_INFANTRYTYPE) {
- /*
- ** Find cell sub-position
- */
- if (Is_Spot_Free(Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()))) {
- obj_coord = Closest_Free_Spot(Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()));
- } else {
- obj_coord = NULL;
- }
- /*
- ** No free spots; don't place the object
- */
- if (obj_coord == NULL) {
- //ScenarioInit--;
- return(-1);
- }
- /*
- ** Unlimbo the object
- */
- if (PendingObjectPtr->Unlimbo(obj_coord)) {
- ((InfantryClass *)PendingObjectPtr)->Set_Occupy_Bit(obj_coord);
- // Map[obj_coord].Flag.Composite |=
- // (1 << CellClass::Spot_Index(obj_coord));
- PendingObjectPtr = 0;
- PendingObject = 0;
- PendingHouse = HOUSE_NONE;
- Set_Cursor_Shape(0);
- //ScenarioInit--;
- return(0);
- }
- //ScenarioInit--;
- return(-1);
- }
- /*
- ** Placing an object
- */
- if (PendingObjectPtr->Unlimbo(Cell_Coord(ZoneCell + ZoneOffset))) {
- /*
- ** Update the Tiberium computation if we're placing an overlay
- */
- if (PendingObject->What_Am_I() == RTTI_OVERLAYTYPE &&
- ((OverlayTypeClass *)PendingObject)->IsTiberium) {
- TotalValue = Overpass();
- Flag_To_Redraw(false);
- }
- /*
- ** If we're building a base, add this building to the base's Node list.
- */
- if (BaseBuilding && PendingObject->What_Am_I() == RTTI_BUILDINGTYPE) {
- // node.Type = ((BuildingTypeClass *)PendingObject)->Type;
- // node.Cell = Coord_Cell(PendingObjectPtr->Coord);
- Base.Nodes.Add(BaseNodeClass(((BuildingTypeClass *)PendingObject)->Type, Coord_Cell(PendingObjectPtr->Coord)));
- }
- PendingObjectPtr = 0;
- PendingObject = 0;
- PendingHouse = HOUSE_NONE;
- Set_Cursor_Shape(0);
- //ScenarioInit--;
- return(0);
- }
- return(-1);
- }
- /***************************************************************************
- * MapEditClass::Cancel_Placement -- cancels placement mode *
- * *
- * INPUT: *
- * none. *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 11/04/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::Cancel_Placement(void)
- {
- /*
- ** Delete the placement object
- */
- delete PendingObjectPtr;
- PendingObject = 0;
- PendingObjectPtr = 0;
- PendingHouse = HOUSE_NONE;
- /*
- ** Restore cursor shape
- */
- Set_Cursor_Shape(0);
- /*
- ** Redraw the map to erase old leftovers
- */
- HidPage.Clear();
- Flag_To_Redraw(true);
- Render();
- }
- /***************************************************************************
- * MapEditClass::Place_Next -- while placing object, goes to next *
- * *
- * - Deletes the current 'PendingObjectPtr' *
- * - Increments LastChoice *
- * - Tries to create a new 'PendingObjectPtr'; if fails, keeps *
- * incrementing until it gets it *
- * *
- * INPUT: *
- * none. *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 11/03/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::Place_Next(void)
- {
- delete PendingObjectPtr;
- PendingObjectPtr = NULL;
- PendingObject = NULL;
- /*
- ** Loop until we create a valid object
- */
- while (!PendingObjectPtr) {
- /*
- ** Go to next object in Objects list
- */
- LastChoice++;
- if (LastChoice == ObjCount) {
- /*
- ** If we're in normal placement mode, wrap to the 1st object;
- ** if we're in base-building mode, wrap to the 1st building
- */
- if (!BaseBuilding) {
- LastChoice = 0;
- } else {
- LastChoice = TypeOffset[7];
- }
- }
- /*
- ** Create placement object
- */
- PendingObject = Objects[LastChoice];
- PendingHouse = LastHouse;
- PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(PendingHouse));
- if (!PendingObjectPtr) {
- PendingObject = NULL;
- }
- }
- /*
- ** Set the new cursor shape
- */
- Set_Cursor_Pos();
- Set_Cursor_Shape(0);
- Set_Cursor_Shape(PendingObject->Occupy_List());
- /*
- ** Redraw the map to erase old leftovers
- */
- HidPage.Clear();
- Flag_To_Redraw(true);
- Render();
- }
- /***************************************************************************
- * MapEditClass::Place_Prev -- while placing object, goes to previous *
- * *
- * - Deletes the current 'PendingObjectPtr' *
- * - Decrements LastChoice *
- * - Tries to create a new 'PendingObjectPtr'; if fails, keeps *
- * decrementing until it gets it *
- * *
- * INPUT: *
- * none. *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 11/03/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::Place_Prev(void)
- {
- delete PendingObjectPtr;
- PendingObjectPtr = NULL;
- PendingObject = NULL;
- /*
- ** Loop until we create a valid object
- */
- while (!PendingObjectPtr) {
- /*
- ** Go to prev object in Objects list
- */
- LastChoice--;
- /*
- ** If we're in normal placement mode, wrap at the 1st object.
- ** If we're building a base, wrap at the 1st building.
- */
- if (!BaseBuilding) {
- if (LastChoice < 0) {
- LastChoice = ObjCount - 1;
- }
- } else {
- if (LastChoice < TypeOffset[7]) {
- LastChoice = ObjCount - 1;
- }
- }
- /*
- ** Create placement object
- */
- PendingObject = Objects[LastChoice];
- PendingHouse = LastHouse;
- PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(PendingHouse));
- if (!PendingObjectPtr) {
- PendingObject = NULL;
- }
- }
- /*
- ** Set the new cursor shape
- */
- Set_Cursor_Pos();
- Set_Cursor_Shape(0);
- Set_Cursor_Shape(PendingObject->Occupy_List());
- /*
- ** Redraw the map to erase old leftovers
- */
- HidPage.Clear();
- Flag_To_Redraw(true);
- Render();
- }
- /***************************************************************************
- * MapEditClass::Place_Next_Category -- places next category of object *
- * *
- * INPUT: *
- * none. *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 11/03/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::Place_Next_Category(void)
- {
- int i;
- /*
- ** Don't allow this command if we're building a base; the only valid
- ** category for base-building is buildings.
- */
- if (BaseBuilding) {
- return;
- }
- delete PendingObjectPtr;
- PendingObjectPtr = NULL;
- PendingObject = NULL;
- /*
- ** Go to next category in Objects list
- */
- i = LastChoice;
- while (Objects[i]->What_Am_I() == Objects[LastChoice]->What_Am_I()) {
- i++;
- if (i == ObjCount) {
- i = 0;
- }
- }
- LastChoice = i;
- /*
- ** Loop until we create a valid object
- */
- while (!PendingObjectPtr) {
- /*
- ** Get house for this object type
- */
- // if (!Verify_House(LastHouse, Objects[LastChoice])) {
- // LastHouse = Cycle_House(LastHouse, Objects[LastChoice]);
- // }
- /*
- ** Create placement object
- */
- PendingObject = Objects[LastChoice];
- PendingHouse = LastHouse;
- PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(PendingHouse));
- /*
- ** If this one failed, try the next
- */
- if (!PendingObjectPtr) {
- PendingObject = NULL;
- LastChoice++;
- if (LastChoice == ObjCount) {
- LastChoice = 0;
- }
- }
- }
- /*
- ** Set the new cursor shape
- */
- Set_Cursor_Pos();
- Set_Cursor_Shape(0);
- Set_Cursor_Shape(PendingObject->Occupy_List());
- /*
- ** Redraw the map to erase old leftovers
- */
- HidPage.Clear();
- Flag_To_Redraw(true);
- Render();
- }
- /***************************************************************************
- * MapEditClass::Place_Prev_Category -- places previous category of object *
- * *
- * INPUT: *
- * none. *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 11/03/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::Place_Prev_Category(void)
- {
- int i;
- /*
- ** Don't allow this command if we're building a base; the only valid
- ** category for base-building is buildings.
- */
- if (BaseBuilding) {
- return;
- }
- delete PendingObjectPtr;
- PendingObjectPtr = NULL;
- PendingObject = NULL;
- /*
- ** Go to prev category in Objects list
- */
- i = LastChoice;
- /*
- ** Scan for start of this category
- */
- while (Objects[i]->What_Am_I() == Objects[LastChoice]->What_Am_I()) {
- i--;
- if (i < 0) {
- i = ObjCount - 1;
- }
- }
- i--;
- if (i < 0) i = ObjCount-1;
- LastChoice = i;
- /*
- ** Scan for the previous category
- */
- while (Objects[i]->What_Am_I() == Objects[LastChoice]->What_Am_I()) {
- i--;
- if (i < 0) {
- i = ObjCount - 1;
- }
- }
- i++;
- if (i >= ObjCount) i = 0;
- LastChoice = i;
- /*
- ** Loop until we create a valid object
- */
- while (!PendingObjectPtr) {
- /*
- ** Get house for this object type
- */
- // if (!Verify_House(LastHouse, Objects[LastChoice])) {
- // LastHouse = Cycle_House(LastHouse, Objects[LastChoice]);
- // }
- /*
- ** Create placement object
- */
- PendingObject = Objects[LastChoice];
- PendingHouse = LastHouse;
- PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(PendingHouse));
- /*
- ** If this one failed, try the next
- */
- if (!PendingObjectPtr) {
- PendingObject = NULL;
- LastChoice--;
- if (LastChoice < 0) {
- LastChoice = ObjCount - 1;
- }
- }
- }
- /*
- ** Set the new cursor shape
- */
- Set_Cursor_Pos();
- Set_Cursor_Shape(0);
- Set_Cursor_Shape(PendingObject->Occupy_List());
- /*
- ** Redraw the map to erase old leftovers
- */
- HidPage.Clear();
- Flag_To_Redraw(true);
- Render();
- }
- /***************************************************************************
- * MapEditClass::Place_Home -- homes the placement object *
- * *
- * INPUT: *
- * none. *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 11/03/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::Place_Home(void)
- {
- delete PendingObjectPtr;
- PendingObjectPtr = NULL;
- PendingObject = NULL;
- /*
- ** Don't allow this command if we're building a base; the only valid
- ** category for base-building is buildings.
- */
- if (BaseBuilding) {
- return;
- }
- /*
- ** Loop until we create a valid object
- */
- LastChoice = 0;
- while (!PendingObjectPtr) {
- /*
- ** Get house for this object type
- */
- if (!Verify_House(LastHouse, Objects[LastChoice])) {
- LastHouse = Cycle_House(LastHouse, Objects[LastChoice]);
- }
- /*
- ** Create placement object
- */
- PendingObject = Objects[LastChoice];
- PendingHouse = LastHouse;
- PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(PendingHouse));
- /*
- ** If this one failed, try the next
- */
- if (!PendingObjectPtr) {
- PendingObject = NULL;
- LastChoice++;
- if (LastChoice == ObjCount) {
- LastChoice = 0;
- }
- }
- }
- /*
- ** Set the new cursor shape
- */
- Set_Cursor_Pos();
- Set_Cursor_Shape(0);
- Set_Cursor_Shape(PendingObject->Occupy_List());
- /*
- ** Redraw the map to erase old leftovers
- */
- HidPage.Clear();
- Flag_To_Redraw(true);
- Render();
- }
- /***************************************************************************
- * MapEditClass::Toggle_House -- toggles current placement object's house *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 11/04/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::Toggle_House(void)
- {
- TechnoClass *tp;
- /*
- ** Don't allow this command if we're building a base; the only valid
- ** house for base-building is the one assigned to the base.
- */
- if (BaseBuilding) {
- return;
- }
- /*
- ** Only techno objects can be owned by a house; return if not a techno
- */
- if (!PendingObjectPtr->Is_Techno()) {
- return;
- }
- /*
- ** Select the house that will own this object
- */
- LastHouse = Cycle_House(PendingObjectPtr->Owner(), PendingObject);
- /*
- ** Change the house
- */
- tp = (TechnoClass *)PendingObjectPtr;
- tp->House = HouseClass::As_Pointer(LastHouse);
- /*
- ** Set house variables to new house
- */
- PendingHouse = LastHouse;
- }
- /***************************************************************************
- * MapEditClass::Set_House_Buttons -- toggles house buttons for btn list *
- * *
- * Looks in the given button list for the given GDI, NOD & Neutral button *
- * id's. Sets the On/Off state of the buttons based on the given house, *
- * only if that button is found in the list. *
- * *
- * INPUT: *
- * house house to set buttons to *
- * btnlist ptr to button list to search *
- * base_id button ID for GDI; assumes other id's are sequential*
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 11/23/1994 BR : Created. *
- * 01/26/1996 JLB : Uses new house selection list method. *
- *=========================================================================*/
- void MapEditClass::Set_House_Buttons(HousesType house, GadgetClass *, int )
- //void MapEditClass::Set_House_Buttons(HousesType house, GadgetClass * btnlist, int base_id)
- {
- HouseList->Set_Selected_Index(house);
- #ifdef NEVER
- HousesType h;
- int id;
- TextButtonClass * btn;
- /*
- ** Loop through all houses, searching the button list for each one.
- */
- for (h = HOUSE_FIRST; h < HOUSE_COUNT; h++) {
- /*
- ** Compute the desired button ID; get a pointer to the button
- */
- id = (int)h + base_id;
- btn = (TextButtonClass *)btnlist->Extract_Gadget(id);
- if (btn) {
- /*
- ** If this house value is the desired one, turn the button on;
- ** otherwise, turn it off.
- */
- if (h == house) {
- btn->Turn_On();
- } else {
- btn->Turn_Off();
- }
- }
- }
- #endif
- }
- /***************************************************************************
- * MapEditClass::Start_Trigger_Placement -- enters trigger placement mode *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 12/01/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::Start_Trigger_Placement(void)
- {
- Set_Default_Mouse(MOUSE_CAN_MOVE);
- Override_Mouse_Shape(MOUSE_CAN_MOVE);
- }
- /***************************************************************************
- * MapEditClass::Stop_Trigger_Placement -- exits trigger placement mode *
- * *
- * INPUT: *
- * none. *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 12/01/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::Stop_Trigger_Placement(void)
- {
- CurTrigger = NULL;
- Set_Default_Mouse(MOUSE_NORMAL);
- Override_Mouse_Shape(MOUSE_NORMAL);
- }
- /***************************************************************************
- * MapEditClass::Place_Trigger -- assigns trigger to object or cell *
- * *
- * INPUT: *
- * none. *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 12/01/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::Place_Trigger(void)
- {
- ObjectClass * object=NULL; // Generic object clicked on.
- int x,y;
- CELL cell; // Cell that was selected.
- /*
- ** See if an object was clicked on
- */
- x = Keyboard->MouseQX;
- y = Keyboard->MouseQY;
- /*
- ** Get cell for x,y
- */
- cell = Click_Cell_Calc(x, y);
- /*
- ** Convert x,y to offset from cell upper-left
- */
- x = (x-TacPixelX) % ICON_PIXEL_W;
- y = (y-TacPixelY) % ICON_PIXEL_H;
- /*
- ** Get object at that x,y
- */
- object = Cell_Object(cell, x, y);
- /*
- ** Assign trigger to an object
- */
- AttachType a1 = CurTrigger->Attaches_To();
- if (object && (a1 & ATTACH_OBJECT) != 0) {
- if (CurTrigger) {
- TriggerClass * tt = Find_Or_Make(CurTrigger);
- if (tt) {
- object->Trigger = tt;
- }
- }
- } else {
- /*
- ** Assign trigger to a cell
- */
- if ((a1 & ATTACH_CELL) != 0) {
- if (CurTrigger) {
- TriggerClass * tt = Find_Or_Make(CurTrigger);
- Map[cell].Trigger = tt;
- }
- // CellTriggers[cell] = CurTrigger;
- }
- }
- /*
- ** Force map to redraw
- */
- HidPage.Clear();
- Flag_To_Redraw(true);
- }
- /***************************************************************************
- * MapEditClass::Start_Base_Building -- starts base-building mode *
- * *
- * INPUT: *
- * none. *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 12/01/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::Start_Base_Building(void)
- {
- /*
- ** Fully build the base so the user can edit it
- */
- Build_Base_To(100);
- /*
- ** Start placement mode
- */
- BaseBuilding = true;
- Start_Placement();
- /*
- ** Force map to redraw
- */
- HidPage.Clear();
- Flag_To_Redraw(true);
- }
- /***************************************************************************
- * MapEditClass::Cancel_Base_Building -- stops base-building mode *
- * *
- * INPUT: *
- * none. *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 12/01/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::Cancel_Base_Building(void)
- {
- /*
- ** Build the base to the proper amount
- */
- Build_Base_To(Scen.Percent);
- /*
- ** Cancel placement mode
- */
- Cancel_Placement();
- BaseBuilding = false;
- /*
- ** Force map to redraw
- */
- HidPage.Clear();
- Flag_To_Redraw(true);
- }
- /***************************************************************************
- * MapEditClass::Build_Base_To -- builds the AI base to the given percent *
- * *
- * INPUT: *
- * percent percentage to build base to *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 12/01/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::Build_Base_To(int percent)
- {
- int i;
- int num_buildings;
- BuildingTypeClass const * objtype;
- BuildingClass * obj;
- //ScenarioInit++;
- /*
- ** Completely dismantle the base, so we start at a known point
- */
- for (i = 0; i < Base.Nodes.Count(); i++) {
- if (Base.Is_Built(i)) {
- obj = Base.Get_Building(i);
- delete obj;
- }
- }
- /*
- ** Compute number of buildings to build
- */
- num_buildings = (Base.Nodes.Count() * percent) / 100;
- /*
- ** Build the base to the desired amount
- */
- for (i = 0; i < num_buildings; i++) {
- /*
- ** Get a ptr to the type of building to build, create one, and unlimbo it.
- */
- objtype = &BuildingTypeClass::As_Reference(Base.Nodes[i].Type);
- obj = (BuildingClass *)objtype->Create_One_Of(HouseClass::As_Pointer(Base.House));
- /*
- ** If unlimbo fails, error out
- */
- ScenarioInit++;
- if (!obj->Unlimbo(Cell_Coord(Base.Nodes[i].Cell))) {
- delete obj;
- WWMessageBox().Process("Unable to build base!");
- ScenarioInit--;
- return;
- }
- ScenarioInit--;
- }
- //ScenarioInit--;
- }
- #endif
|