123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923 |
- //
- // Copyright 2020 Electronic Arts Inc.
- //
- // TiberianDawn.DLL and RedAlert.dll and corresponding source code 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.
- // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
- // in the hope that it will be useful, but with permitted additional restrictions
- // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
- // distributed with this program. You should have received a copy of the
- // GNU General Public License along with permitted additional restrictions
- // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
- /* $Header: F:\projects\c&c\vcs\code\mapedit.cpv 2.18 16 Oct 1995 16:48:40 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 : MAPEDIT.CPP *
- * *
- * Programmer : Bill Randolph *
- * *
- * Start Date : October 20, 1994 *
- * *
- * Last Update : February 2, 1995 [BR] *
- * *
- *-------------------------------------------------------------------------*
- * Map Editor overloaded routines & utility routines *
- *-------------------------------------------------------------------------*
- * Map Editor modules: *
- * (Yes, they're all one huge class.) *
- * mapedit.cpp: overloaded routines, utility routines *
- * mapeddlg.cpp: map editor dialogs, most of the main menu options *
- * mapedplc.cpp: object-placing routines *
- * mapedsel.cpp: object-selection & manipulation routines *
- * mapedtm.cpp: team-editing routines *
- *-------------------------------------------------------------------------*
- * Functions: *
- * MapEditClass::MapEditClass -- class constructor *
- * MapEditClass::One_Time -- one-time initialization *
- * MapEditClass::Read_INI -- overloaded Read_INI function *
- * MapEditClass::Clear_List -- clears the internal choosable object list *
- * MapEditClass::Add_To_List -- adds a TypeClass to the choosable list *
- * MapEditClass::AI -- The map editor's main logic *
- * MapEditClass::Draw_It -- overloaded Redraw routine *
- * MapEditClass::Main_Menu -- main menu processor for map editor *
- * MapEditClass::AI_Menu -- menu of AI options *
- * MapEditClass::Mouse_Moved -- checks for mouse motion *
- * MapEditClass::Verify_House -- sees if given house can own given obj *
- * MapEditClass::Cycle_House -- finds next valid house for object type *
- * MapEditClass::Trigger_Needs_Team -- tells if a trigger needs a team *
- * MapEditClass::Fatal -- exits with error message *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "function.h"
- #ifdef SCENARIO_EDITOR
- /*
- ****************************** Globals/Externs ******************************
- */
- /*...........................................................................
- Array of all missions supported by the map editor
- ...........................................................................*/
- MissionType MapEditClass::MapEditMissions[] = {
- MISSION_GUARD,
- MISSION_STICKY,
- MISSION_HARVEST,
- MISSION_GUARD_AREA,
- MISSION_RETURN,
- MISSION_AMBUSH,
- MISSION_HUNT,
- MISSION_SLEEP,
- };
- #define NUM_EDIT_MISSIONS (sizeof(MapEditClass::MapEditMissions) / sizeof(MapEditClass::MapEditMissions[0]))
- /*...........................................................................
- For menu processing
- ...........................................................................*/
- extern int UnknownKey; // in menus.cpp
- char MapEditClass::HealthBuf[20];
- /***************************************************************************
- * MapEditClass::MapEditClass -- class constructor *
- * *
- * INPUT: *
- * none. *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 10/20/1994 BR : Created. *
- *=========================================================================*/
- MapEditClass::MapEditClass(void)
- {
- /*
- ** Init data members.
- */
- ScenVar = SCEN_VAR_A;
- ObjCount = 0;
- LastChoice = 0;
- LastHouse = HOUSE_GOOD;
- GrabbedObject = 0;
- for (int i=0; i < NUM_EDIT_CLASSES; i++) {
- NumType[i] = 0;
- TypeOffset[i] = 0;
- }
- Waypoint[WAYPT_HOME] = 0;
- CurrentCell = 0;
- CurTrigger = NULL;
- Changed = 0;
- LMouseDown = 0;
- BaseBuilding = 0;
- BasePercent = 100;
- }
- /***************************************************************************
- * MapEditClass::One_Time -- one-time initialization *
- * *
- * INPUT: *
- * none. *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 02/02/1995 BR : Created. *
- *=========================================================================*/
- void MapEditClass::One_Time(void)
- {
- MouseClass::One_Time();
- /*------------------------------------------------------------------------
- Create the pop-up controls
- ------------------------------------------------------------------------*/
- /*........................................................................
- The map: a single large "button"
- ........................................................................*/
- //MapArea = new ControlClass(MAP_AREA,0,8,312,192, GadgetClass::LEFTPRESS |
- //GadgetClass::LEFTRELEASE, false);
- MapArea = new ControlClass(MAP_AREA,0,16,624,384, GadgetClass::LEFTPRESS |
- GadgetClass::LEFTRELEASE, false);
- /*........................................................................
- House buttons
- ........................................................................*/
- GDIButton = new TextButtonClass (POPUP_GDI, "GDI",
- TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
- POPUP_GDI_X, POPUP_GDI_Y, POPUP_GDI_W, POPUP_GDI_H);
- NODButton = new TextButtonClass (POPUP_NOD, "NOD",
- TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
- POPUP_NOD_X, POPUP_NOD_Y, POPUP_NOD_W, POPUP_NOD_H);
- NeutralButton = new TextButtonClass (POPUP_NEUTRAL, "Neutral",
- TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
- POPUP_NEUTRAL_X, POPUP_NEUTRAL_Y, POPUP_NEUTRAL_W, POPUP_NEUTRAL_H);
- Multi1Button = new TextButtonClass (POPUP_MULTI1, "M1",
- TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
- POPUP_MULTI1_X, POPUP_MULTI1_Y, POPUP_MULTI1_W, POPUP_MULTI1_H);
- Multi2Button = new TextButtonClass (POPUP_MULTI2, "M2",
- TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
- POPUP_MULTI2_X, POPUP_MULTI2_Y, POPUP_MULTI2_W, POPUP_MULTI2_H);
- Multi3Button = new TextButtonClass (POPUP_MULTI3, "M3",
- TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
- POPUP_MULTI3_X, POPUP_MULTI3_Y, POPUP_MULTI3_W, POPUP_MULTI3_H);
- Multi4Button = new TextButtonClass (POPUP_MULTI4, "M4",
- TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
- POPUP_MULTI4_X, POPUP_MULTI4_Y, POPUP_MULTI4_W, POPUP_MULTI4_H);
- /*........................................................................
- The mission list box
- ........................................................................*/
- MissionList = new ListClass (POPUP_MISSIONLIST,
- POPUP_MISSION_X, POPUP_MISSION_Y, POPUP_MISSION_W, POPUP_MISSION_H,
- TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
- Hires_Retrieve("BTN-UP.SHP"),
- Hires_Retrieve("BTN-DN.SHP"));
- for (int i = 0; i < NUM_EDIT_MISSIONS; i++) {
- MissionList->Add_Item (MissionClass::Mission_Name(MapEditMissions[i]));
- }
- /*........................................................................
- The health bar
- ........................................................................*/
- HealthGauge = new TriColorGaugeClass (POPUP_HEALTHGAUGE,
- POPUP_HEALTH_X, POPUP_HEALTH_Y, POPUP_HEALTH_W, POPUP_HEALTH_H);
- HealthGauge->Use_Thumb(true);
- HealthGauge->Set_Maximum(0x100);
- HealthGauge->Set_Red_Limit(0x3f - 1);
- HealthGauge->Set_Yellow_Limit(0x7f - 1);
- /*........................................................................
- The health text label
- ........................................................................*/
- HealthBuf[0] = 0;
- HealthText = new TextLabelClass (HealthBuf,
- POPUP_HEALTH_X + POPUP_HEALTH_W / 2,
- POPUP_HEALTH_Y + POPUP_HEALTH_H + 1,
- CC_GREEN, TPF_CENTER | TPF_FULLSHADOW | TPF_6PT_GRAD | TPF_USE_GRAD_PAL);
- /*........................................................................
- The facing dial
- ........................................................................*/
- FacingDial = new Dial8Class (POPUP_FACINGDIAL, POPUP_FACEBOX_X,
- POPUP_FACEBOX_Y, POPUP_FACEBOX_W, POPUP_FACEBOX_H, (DirType)0);
- /*........................................................................
- The base percent-built slider & its label
- ........................................................................*/
- BaseGauge = new GaugeClass (POPUP_BASEPERCENT,
- POPUP_BASE_X, POPUP_BASE_Y, POPUP_BASE_W, POPUP_BASE_H);
- BaseLabel = new TextLabelClass ("Base:", POPUP_BASE_X - 3, POPUP_BASE_Y,
- CC_GREEN, TPF_RIGHT | TPF_NOSHADOW | TPF_6PT_GRAD | TPF_USE_GRAD_PAL);
- BaseGauge->Set_Maximum(100);
- BaseGauge->Set_Value(BasePercent);
- }
- /***********************************************************************************************
- * MapeditClass::Init_IO -- Reinitializes the radar map at scenario start. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 12/22/1994 JLB : Created. *
- *=============================================================================================*/
- void MapEditClass::Init_IO(void)
- {
- /*------------------------------------------------------------------------
- For normal game mode, jump to the parent's Init routine.
- ------------------------------------------------------------------------*/
- if (!Debug_Map) {
- MouseClass::Init_IO();
- } else {
- /*------------------------------------------------------------------------
- For editor mode, add the map area to the button input list
- ------------------------------------------------------------------------*/
- Buttons = 0;
- Add_A_Button(*BaseGauge);
- Add_A_Button(*BaseLabel);
- Add_A_Button(*MapArea);
- }
- }
- /***************************************************************************
- * MapEditClass::Read_INI -- overloaded Read_INI function *
- * *
- * Overloading this function gives the map editor a chance to initialize *
- * certain values every time a new INI is read. *
- * *
- * INPUT: *
- * buffer INI staging area *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 11/16/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::Read_INI(char *buffer)
- {
- /*
- ------------------------ Invoke parent's Read_INI ------------------------
- */
- MouseClass::Read_INI(buffer);
- BasePercent = WWGetPrivateProfileInt("Basic","Percent",0,buffer);
- BaseGauge->Set_Value(BasePercent);
- }
- /***************************************************************************
- * MapEditClass::Write_INI -- overloaded Read_INI function *
- * *
- * INPUT: *
- * buffer INI staging area *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 11/16/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::Write_INI(char *buffer)
- {
- /*
- ----------------------- Invoke parent's Write_INI ------------------------
- */
- MouseClass::Write_INI(buffer);
- /*
- ** Save the base's percent-built value; this must be saved into the BASIC
- ** section of the INI, since the Base section will be entirely erased
- ** by the Base's Write_INI routine.
- */
- WWWritePrivateProfileInt("Basic", "Percent", BasePercent, buffer);
- }
- /***************************************************************************
- * MapEditClass::Clear_List -- clears the internal choosable object list *
- * *
- * INPUT: *
- * none. *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 10/20/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::Clear_List(void)
- {
- /*------------------------------------------------------------------------
- Set # object type ptrs to 0, set NumType for each type to 0
- ------------------------------------------------------------------------*/
- ObjCount = 0;
- for (int i = 0; i < NUM_EDIT_CLASSES; i++) {
- NumType[i] = 0;
- }
- }
- /***************************************************************************
- * MapEditClass::Add_To_List -- adds a TypeClass to the choosable list *
- * *
- * Use this routine to add an object to the game object selection list. *
- * This list is used by the Add_Object function. All items located in the *
- * list will appear and be chooseable by that function. Make sure to *
- * clear the list before adding a sequence of items to it. Clearing *
- * the list is accomplished by the Clear_List() function. *
- * *
- * INPUT: *
- * object ptr to ObjectTypeClass to add *
- * *
- * OUTPUT: *
- * bool: was the object added to the list? A failure could occur if *
- * NULL were passed in or the list is full. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 06/04/1994 JLB : Created. *
- *=========================================================================*/
- bool MapEditClass::Add_To_List(ObjectTypeClass const *object)
- {
- /*
- ** Add the object if there's room.
- */
- if (object && ObjCount < MAX_EDIT_OBJECTS) {
- Objects[ObjCount++] = object;
- /*
- ** Update type counters.
- */
- switch (object->What_Am_I()) {
- case RTTI_TEMPLATETYPE:
- NumType[0]++;
- break;
- case RTTI_OVERLAYTYPE:
- NumType[1]++;
- break;
- case RTTI_SMUDGETYPE:
- NumType[2]++;
- break;
- case RTTI_TERRAINTYPE:
- NumType[3]++;
- break;
- case RTTI_UNITTYPE:
- NumType[4]++;
- break;
- case RTTI_INFANTRYTYPE:
- NumType[5]++;
- break;
- case RTTI_AIRCRAFTTYPE:
- NumType[6]++;
- break;
- case RTTI_BUILDINGTYPE:
- NumType[7]++;
- break;
- }
- return(true);
- }
- return(false);
- }
- /***************************************************************************
- * MapEditClass::AI -- The map editor's main logic *
- * *
- * This routine overloads the parent's (DisplayClass) AI function. *
- * It checks for any input specific to map editing, and calls the parent *
- * AI routine to handle scrolling and other mainstream map stuff. *
- * *
- * If this detects one of its special input keys, it sets 'input' to 0 *
- * before calling the parent AI routine; this prevents input conflict. *
- * *
- * SUPPORTED INPUT: *
- * General: *
- * F2/RMOUSE: main menu *
- * F6: toggles show-passable mode *
- * HOME: go to the Home Cell (scenario's start position)*
- * SHIFT-HOME: set the Home Cell to the current TacticalCell*
- * ESC: exits to DOS *
- * Object Placement: *
- * INSERT: go into placement mode *
- * ESC: exit placement mode *
- * LEFT/RIGHT: prev/next placement object *
- * PGUP/PGDN: prev/next placement category *
- * HOME: 1st placement object (clear template) *
- * h/H: toggle house of placement object *
- * LMOUSE: place the placement object *
- * MOUSE MOTION: "paint" with the placement object *
- * Object selection: *
- * LMOUSE: select & "grab" current object *
- * If no object is present where the mouse is *
- * clicked, the current object is de-selected *
- * If the same object is clicked on, it stays *
- * selected. Also displays the object-editing *
- * gadgets. *
- * LMOUSE RLSE: release currently-grabbed object *
- * MOUSE MOTION: if an object is grabbed, moves the object *
- * SHIFT|ALT|ARROW: moves object in that direction *
- * DELETE deletes currently-selected object *
- * Object-editing controls: *
- * POPUP_GDI: makes GDI the owner of this object *
- * POPUP_NOD: makes NOD the owner of this object *
- * POPUP_MISSIONLIST: sets that mission for this object *
- * POPUP_HEALTHGAUGE: sets that health value for this object *
- * POPUP_FACINGDIAL: sets the object's facing *
- * *
- * Changed is set when you: *
- * - place an object *
- * - move a grabbed object *
- * - delete an object *
- * - size the map *
- * - create a new scenario *
- * Changed is cleared when you: *
- * - Save the scenario *
- * - Load a scenario *
- * - Play the scenario *
- * *
- * INPUT: *
- * input KN_ value, 0 if none *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 10/20/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::AI(KeyNumType &input, int x, int y)
- {
- int rc;
- MissionType mission;
- int strength;
- CELL cell;
- int i;
- int found; // for removing a waypoint label
- int waypt_idx; // for labelling a waypoint
- BaseNodeClass *node; // for removing from an AI Base
- HousesType house;
- /*------------------------------------------------------------------------
- Trap 'F2' regardless of whether we're in game or editor mode
- ------------------------------------------------------------------------*/
- if (Debug_Flag) {
- if (/*(input == KN_F2 && Session == GAME_SOLO) ||*/ input == (KN_F2 | KN_CTRL_BIT)) {
- ScenarioInit = 0;
- /*
- ** If we're in editor mode & Changed is set, prompt for saving changes
- */
- if (Debug_Map && Changed) {
- rc = CCMessageBox().Process("Save Changes?", TXT_YES, TXT_NO);
- HiddenPage.Clear();
- Flag_To_Redraw(true);
- Render();
- /*
- ........................ User wants to save ........................
- */
- if (rc == 0) {
- /*
- ................ If save cancelled, abort game ..................
- */
- if (Save_Scenario()!=0) {
- input = KN_NONE;
- } else {
- Changed = 0;
- Go_Editor(!Debug_Map);
- }
- } else {
- /*
- .................... User doesn't want to save .....................
- */
- Go_Editor(!Debug_Map);
- }
- } else {
- /*
- ** If we're in game mode, set Changed to 0 (so if we didn't save our
- ** changes above, they won't keep coming back to haunt us with continual
- ** Save Changes? prompts!)
- */
- if (!Debug_Map) {
- Changed = 0;
- }
- Go_Editor(!Debug_Map);
- }
- }
- }
- /*------------------------------------------------------------------------
- For normal game mode, jump to the parent's AI routine.
- ------------------------------------------------------------------------*/
- if (!Debug_Map) {
- MouseClass::AI(input, x, y);
- return;
- }
- ::Frame++;
- /*------------------------------------------------------------------------
- Do special mouse processing if the mouse is over the map
- ------------------------------------------------------------------------*/
- if (Get_Mouse_X() > TacPixelX && Get_Mouse_X() <
- TacPixelX + Lepton_To_Pixel(TacLeptonWidth) &&
- Get_Mouse_Y() > TacPixelY && Get_Mouse_Y() <
- TacPixelY + Lepton_To_Pixel(TacLeptonHeight)) {
- /*.....................................................................
- When the mouse moves over a scrolling edge, ScrollClass changes its
- shape to the appropriate arrow or NO symbol; it's our job to change it
- back to normal (or whatever the shape is set to by Set_Default_Mouse())
- when it re-enters the map area.
- .....................................................................*/
- if (CurTrigger) {
- Override_Mouse_Shape(MOUSE_CAN_MOVE);
- } else {
- Override_Mouse_Shape(MOUSE_NORMAL);
- }
- }
- /*.....................................................................
- Set 'ZoneCell' to track the mouse cursor around over the map. Do this
- even if the map is scrolling.
- .....................................................................*/
- if (Get_Mouse_X() >= TacPixelX && Get_Mouse_X() <=
- TacPixelX + Lepton_To_Pixel(TacLeptonWidth) &&
- Get_Mouse_Y() >= TacPixelY && Get_Mouse_Y() <=
- TacPixelY + Lepton_To_Pixel(TacLeptonHeight)) {
- cell = Click_Cell_Calc(Get_Mouse_X(), Get_Mouse_Y());
- if (cell != -1) {
- Set_Cursor_Pos(cell);
- if (PendingObject) {
- Flag_To_Redraw(true);
- }
- }
- }
- /*------------------------------------------------------------------------
- Check for mouse motion while left button is down.
- ------------------------------------------------------------------------*/
- rc = Mouse_Moved();
- if (LMouseDown && rc) {
- /*.....................................................................
- "Paint" mode: place current object, and restart placement
- .....................................................................*/
- if (PendingObject) {
- Flag_To_Redraw(true);
- if (Place_Object() == 0) {
- Changed = 1;
- Start_Placement();
- }
- } else {
- /*.....................................................................
- Move the currently-grabbed object
- .....................................................................*/
- if (GrabbedObject) {
- GrabbedObject->Mark(MARK_CHANGE);
- if (Move_Grabbed_Object() == 0) {
- Changed = 1;
- }
- }
- }
- }
- /*------------------------------------------------------------------------
- Trap special editing keys; if one is detected, set 'input' to 0 to
- prevent a conflict with parent's AI().
- ------------------------------------------------------------------------*/
- switch (input) {
- /*---------------------------------------------------------------------
- F2/RMOUSE = pop up main menu
- ---------------------------------------------------------------------*/
- case KN_RMOUSE:
- /*
- ..................... Turn off placement mode ......................
- */
- if (PendingObject) {
- if (BaseBuilding) {
- Cancel_Base_Building();
- } else {
- Cancel_Placement();
- }
- }
- /*
- ................. Turn off trigger placement mode ..................
- */
- if (CurTrigger) {
- Stop_Trigger_Placement();
- }
- /*
- .............. Unselect object & hide popup controls ...............
- */
- if (CurrentObject.Count()) {
- CurrentObject[0]->Unselect();
- Popup_Controls();
- }
- Main_Menu();
- input = KN_NONE;
- break;
- /*---------------------------------------------------------------------
- F6 = toggle passable/impassable display
- ---------------------------------------------------------------------*/
- case KN_F6:
- Debug_Passable = (Debug_Passable == false);
- HiddenPage.Clear();
- Flag_To_Redraw(true);
- input = KN_NONE;
- break;
- /*---------------------------------------------------------------------
- INSERT = go into object-placement mode
- ---------------------------------------------------------------------*/
- case KN_INSERT:
- if (!PendingObject) {
- /*
- ......... Unselect current object, hide popup controls ..........
- */
- if (CurrentObject.Count()) {
- CurrentObject[0]->Unselect();
- Popup_Controls();
- }
- /*
- .................... Go into placement mode .....................
- */
- Start_Placement();
- }
- input = KN_NONE;
- break;
- /*---------------------------------------------------------------------
- ESC = exit placement mode, or exit to DOS
- ---------------------------------------------------------------------*/
- case KN_ESC:
- /*
- .................... Exit object placement mode ....................
- */
- if (PendingObject) {
- if (BaseBuilding) {
- Cancel_Base_Building();
- } else {
- Cancel_Placement();
- }
- input = KN_NONE;
- break;
- } else {
- /*
- ................... Exit trigger placement mode ....................
- */
- if (CurTrigger) {
- Stop_Trigger_Placement();
- input = KN_NONE;
- break;
- } else {
- rc = CCMessageBox().Process("Exit Scenario Editor?", TXT_YES, TXT_NO);
- HiddenPage.Clear();
- Flag_To_Redraw(true);
- Render();
- /*
- .......... User doesn't want to exit; return to editor ..........
- */
- if (rc==1) {
- input = KN_NONE;
- break;
- }
- /*
- ................. If changed, prompt for saving .................
- */
- if (Changed) {
- rc = CCMessageBox().Process("Save Changes?", TXT_YES, TXT_NO);
- HiddenPage.Clear();
- Flag_To_Redraw(true);
- Render();
- /*
- ..................... User wants to save .....................
- */
- if (rc == 0) {
- /*
- .............. If save cancelled, abort exit ..............
- */
- if (Save_Scenario()!=0) {
- input = KN_NONE;
- break;
- } else {
- Changed = 0;
- }
- }
- }
- }
- }
- Prog_End();
- exit (0);
- break;
- /*---------------------------------------------------------------------
- LEFT = go to previous placement object
- ---------------------------------------------------------------------*/
- case KN_LEFT:
- if (PendingObject) {
- Place_Prev();
- }
- input = KN_NONE;
- break;
- /*---------------------------------------------------------------------
- RIGHT = go to next placement object
- ---------------------------------------------------------------------*/
- case KN_RIGHT:
- if (PendingObject) {
- Place_Next();
- }
- input = KN_NONE;
- break;
- /*---------------------------------------------------------------------
- PGUP = go to previous placement category
- ---------------------------------------------------------------------*/
- case KN_PGUP:
- if (PendingObject) {
- Place_Prev_Category();
- }
- input = KN_NONE;
- break;
- /*---------------------------------------------------------------------
- PGDN = go to next placement category
- ---------------------------------------------------------------------*/
- case KN_PGDN:
- if (PendingObject) {
- Place_Next_Category();
- }
- input = KN_NONE;
- break;
- /*---------------------------------------------------------------------
- HOME = jump to first placement object, or go to Home Cell
- ---------------------------------------------------------------------*/
- case KN_HOME:
- if (PendingObject) {
- Place_Home();
- } else {
- /*
- ....................... Set map position ........................
- */
- ScenarioInit++;
- Set_Tactical_Position(Waypoint[WAYPT_HOME]);
- ScenarioInit--;
- /*
- ...................... Force map to redraw ......................
- */
- HiddenPage.Clear();
- Flag_To_Redraw(true);
- Render();
- }
- input = KN_NONE;
- break;
- /*---------------------------------------------------------------------
- SHIFT-HOME: set new Home Cell position
- ---------------------------------------------------------------------*/
- case ((int)KN_HOME | (int)KN_SHIFT_BIT):
- /*
- ** Unflag the old Home Cell, if there are no other waypoints
- ** pointing to it
- */
- cell = Waypoint[WAYPT_HOME];
- if (cell != -1) {
- found = 0;
- for (i = 0; i < WAYPT_COUNT; i++) {
- if (i != WAYPT_HOME && Waypoint[i]==cell) {
- found = 1;
- }
- }
- if (found==0) {
- (*this)[cell].IsWaypoint = 0;
- Flag_Cell(cell);
- }
- }
- /*
- ** Now set the new Home cell
- */
- Waypoint[WAYPT_HOME] = Coord_Cell(TacticalCoord);
- (*this)[Coord_Cell(TacticalCoord)].IsWaypoint = 1;
- Flag_Cell(Coord_Cell(TacticalCoord));
- Changed = 1;
- input = KN_NONE;
- break;
- /*---------------------------------------------------------------------
- SHIFT-R: set new Reinforcement Cell position. Don't allow setting
- the Reinf. Cell to the same as the Home Cell (for display purposes.)
- ---------------------------------------------------------------------*/
- case ((int)KN_R | (int)KN_SHIFT_BIT):
- if (CurrentCell==0 || CurrentCell==Waypoint[WAYPT_HOME]) {
- break;
- }
- /*
- ** Unflag the old Reinforcement Cell, if there are no other waypoints
- ** pointing to it
- */
- cell = Waypoint[WAYPT_REINF];
- if (cell != -1) {
- found = 0;
- for (i = 0; i < WAYPT_COUNT; i++) {
- if (i != WAYPT_REINF && Waypoint[i]==cell) {
- found = 1;
- }
- }
- if (found==0) {
- (*this)[cell].IsWaypoint = 0;
- Flag_Cell(cell);
- }
- }
- /*
- ** Now set the new Reinforcement cell
- */
- Waypoint[WAYPT_REINF] = CurrentCell;
- (*this)[CurrentCell].IsWaypoint = 1;
- Flag_Cell(CurrentCell);
- Changed = 1;
- input = KN_NONE;
- break;
- /*---------------------------------------------------------------------
- ALT-Letter: Label a waypoint cell
- ---------------------------------------------------------------------*/
- case ((int)KN_A | (int)KN_ALT_BIT):
- case ((int)KN_B | (int)KN_ALT_BIT):
- case ((int)KN_C | (int)KN_ALT_BIT):
- case ((int)KN_D | (int)KN_ALT_BIT):
- case ((int)KN_E | (int)KN_ALT_BIT):
- case ((int)KN_F | (int)KN_ALT_BIT):
- case ((int)KN_G | (int)KN_ALT_BIT):
- case ((int)KN_H | (int)KN_ALT_BIT):
- case ((int)KN_I | (int)KN_ALT_BIT):
- case ((int)KN_J | (int)KN_ALT_BIT):
- case ((int)KN_K | (int)KN_ALT_BIT):
- case ((int)KN_L | (int)KN_ALT_BIT):
- case ((int)KN_M | (int)KN_ALT_BIT):
- case ((int)KN_N | (int)KN_ALT_BIT):
- case ((int)KN_O | (int)KN_ALT_BIT):
- case ((int)KN_P | (int)KN_ALT_BIT):
- case ((int)KN_Q | (int)KN_ALT_BIT):
- case ((int)KN_R | (int)KN_ALT_BIT):
- case ((int)KN_S | (int)KN_ALT_BIT):
- case ((int)KN_T | (int)KN_ALT_BIT):
- case ((int)KN_U | (int)KN_ALT_BIT):
- case ((int)KN_V | (int)KN_ALT_BIT):
- case ((int)KN_W | (int)KN_ALT_BIT):
- case ((int)KN_X | (int)KN_ALT_BIT):
- case ((int)KN_Y | (int)KN_ALT_BIT):
- case ((int)KN_Z | (int)KN_ALT_BIT):
- if (CurrentCell != 0) {
- waypt_idx = KN_To_KA(input & 0xff) - KA_a;
- /*...............................................................
- Unflag cell for this waypoint if there is one
- ...............................................................*/
- cell = Waypoint[waypt_idx];
- if (cell != -1) {
- if (Waypoint[WAYPT_HOME] != cell &&
- Waypoint[WAYPT_REINF] != cell)
- (*this)[cell].IsWaypoint = 0;
- Flag_Cell(cell);
- }
- Waypoint[waypt_idx] = CurrentCell;
- (*this)[CurrentCell].IsWaypoint = 1;
- Changed = 1;
- Flag_Cell(CurrentCell);
- }
- input = KN_NONE;
- break;
- /*---------------------------------------------------------------------
- ALT-1-4: Designate a cell as a capture-the-flag cell.
- ---------------------------------------------------------------------*/
- case ((int)KN_1 | (int)KN_ALT_BIT):
- case ((int)KN_2 | (int)KN_ALT_BIT):
- case ((int)KN_3 | (int)KN_ALT_BIT):
- case ((int)KN_4 | (int)KN_ALT_BIT):
- /*------------------------------------------------------------------
- If there's a current cell, place the flag & waypoint there.
- ------------------------------------------------------------------*/
- if (CurrentCell != 0) {
- waypt_idx = (KN_To_KA(input & 0xff) - KA_1);
- house = (HousesType)(HOUSE_MULTI1 + waypt_idx);
- if (HouseClass::As_Pointer(house)) {
- HouseClass::As_Pointer(house)->Flag_Attach(CurrentCell,true);
- }
- } else {
- /*------------------------------------------------------------------
- If there's a current object, attach the flag to it and clear the
- waypoint.
- ------------------------------------------------------------------*/
- if (CurrentObject[0] != 0) {
- waypt_idx = (KN_To_KA(input & 0xff) - KA_1);
- house = (HousesType)(HOUSE_MULTI1 + waypt_idx);
- if (HouseClass::As_Pointer(house) && CurrentObject[0]->What_Am_I() == RTTI_UNIT) {
- HouseClass::As_Pointer(house)->Flag_Attach((UnitClass *)CurrentObject[0], true);
- }
- }
- }
- input = KN_NONE;
- break;
- /*---------------------------------------------------------------------
- ALT-Space: Remove a waypoint designation
- ---------------------------------------------------------------------*/
- case ((int)KN_SPACE | (int)KN_ALT_BIT):
- if (CurrentCell != 0) {
- /*...............................................................
- Loop through letter waypoints; if this cell is one of them,
- clear that waypoint.
- ...............................................................*/
- for (i = 0 ; i < 26; i++) {
- if (Waypoint[i]==CurrentCell)
- Waypoint[i] = -1;
- }
- /*...............................................................
- Loop through flag home values; if this cell is one of them, clear
- that waypoint.
- ...............................................................*/
- for (i = 0; i < MAX_PLAYERS; i++) {
- house = (HousesType)(HOUSE_MULTI1 + i);
- if (HouseClass::As_Pointer(house) &&
- CurrentCell == HouseClass::As_Pointer(house)->FlagHome)
- HouseClass::As_Pointer(house)->Flag_Remove(As_Target(CurrentCell),true);
- }
- /*...............................................................
- If there are no more waypoints on this cell, clear the cell's
- waypoint designation.
- ...............................................................*/
- if (Waypoint[WAYPT_HOME]!=CurrentCell &&
- Waypoint[WAYPT_REINF]!=CurrentCell)
- (*this)[CurrentCell].IsWaypoint = 0;
- Changed = 1;
- Flag_Cell(CurrentCell);
- }
- input = KN_NONE;
- break;
- /*---------------------------------------------------------------------
- 'H' = toggle current placement object's house
- ---------------------------------------------------------------------*/
- case KN_H:
- case ((int)KN_H | (int)KN_SHIFT_BIT):
- if (PendingObject) {
- Toggle_House();
- }
- input = KN_NONE;
- break;
- /*---------------------------------------------------------------------
- Left-mouse click:
- Button DOWN:
- - Toggle LMouseDown
- - If we're in placement mode, try to place the current object
- - If success, re-enter placement mode
- - Otherwise, try to select an object, and "grab" it if there is one
- - If no object, then select that cell as the "current" cell
- Button UP:
- - Toggle LMouseDown
- - release any grabbed object
- ---------------------------------------------------------------------*/
- case ((int)MAP_AREA | (int)KN_BUTTON):
- /*
- ------------------------- Left Button DOWN -------------------------
- */
- if (Keyboard::Down(KN_LMOUSE)) {
- LMouseDown = 1;
- /*
- ............... Placement mode: place an object .................
- */
- if (PendingObject) {
- if (Place_Object()==0) {
- Changed = 1;
- Start_Placement();
- }
- } else {
- /*
- ....................... Place a trigger .........................
- */
- if (CurTrigger) {
- Place_Trigger();
- Changed = 1;
- } else {
- /*
- ................. Select an object or a cell .................
- .................. Check for double-click ....................
- */
- if (CurrentObject.Count() &&
- ( (TickCount.Time() - LastClickTime) < 15)) {
- ; // stub
- } else {
- /*
- ................ Single-click: select object .................
- */
- if (Select_Object()==0) {
- CurrentCell = 0;
- Grab_Object();
- } else {
- /*
- ................ No object: select the cell ..................
- */
- CurrentCell = Click_Cell_Calc(_Kbd->MouseQX,_Kbd->MouseQY);
- HiddenPage.Clear();
- Flag_To_Redraw(true);
- Render();
- }
- }
- }
- }
- LastClickTime = TickCount.Time();
- input = KN_NONE;
- } else {
- /*
- -------------------------- Left Button UP --------------------------
- */
- LMouseDown = 0;
- GrabbedObject = 0;
- input = KN_NONE;
- }
- break;
- /*---------------------------------------------------------------------
- SHIFT-ALT-Arrow: move the current object
- ---------------------------------------------------------------------*/
- case (int)KN_UP | (int)KN_ALT_BIT | (int)KN_SHIFT_BIT:
- case (int)KN_DOWN | (int)KN_ALT_BIT | (int)KN_SHIFT_BIT:
- case (int)KN_LEFT | (int)KN_ALT_BIT | (int)KN_SHIFT_BIT:
- case (int)KN_RIGHT | (int)KN_ALT_BIT | (int)KN_SHIFT_BIT:
- if (CurrentObject.Count()) {
- CurrentObject[0]->Move(KN_To_Facing(input));
- Changed = 1;
- }
- input = KN_NONE;
- break;
- /*---------------------------------------------------------------------
- DELETE: delete currently-selected object
- ---------------------------------------------------------------------*/
- case KN_DELETE:
- /*..................................................................
- Delete currently-selected object's trigger, or the object
- ..................................................................*/
- if (CurrentObject.Count()) {
- /*
- ........................ Delete trigger .........................
- */
- if (CurrentObject[0]->Trigger) {
- CurrentObject[0]->Trigger = NULL;
- } else {
- /*
- ** If the current object is part of the AI's Base, remove it
- ** from the Base's Node list.
- */
- if (CurrentObject[0]->What_Am_I()==RTTI_BUILDING &&
- Base.Is_Node((BuildingClass *)CurrentObject[0])) {
- node = Base.Get_Node((BuildingClass *)CurrentObject[0]);
- Base.Nodes.Delete(*node);
- }
- /*
- ................... Delete current object ....................
- */
- delete CurrentObject[0];
- /*
- .................. Hide the popup controls ...................
- */
- Popup_Controls();
- }
- /*
- ........................ Force a redraw .........................
- */
- HiddenPage.Clear();
- Flag_To_Redraw(true);
- Changed = 1;
- } else {
- /*
- ................. Remove trigger from current cell .................
- */
- if (CurrentCell) {
- if ((*this)[CurrentCell].IsTrigger) {
- (*this)[CurrentCell].IsTrigger = 0;
- CellTriggers[CurrentCell] = NULL;
- /*
- ...................... Force a redraw ........................
- */
- HiddenPage.Clear();
- Flag_To_Redraw(true);
- Changed = 1;
- }
- }
- }
- input = KN_NONE;
- break;
- /*---------------------------------------------------------------------
- TAB: select next object on the map
- ---------------------------------------------------------------------*/
- case KN_TAB:
- Select_Next();
- input = KN_NONE;
- break;
- /*---------------------------------------------------------------------
- Object-Editing button: House Button
- ---------------------------------------------------------------------*/
- case (POPUP_GDI | KN_BUTTON):
- case (POPUP_NOD | KN_BUTTON):
- case (POPUP_NEUTRAL | KN_BUTTON):
- case (POPUP_MULTI1 | KN_BUTTON):
- case (POPUP_MULTI2 | KN_BUTTON):
- case (POPUP_MULTI3 | KN_BUTTON):
- case (POPUP_MULTI4 | KN_BUTTON):
- /*..................................................................
- Convert input value into a house value; assume HOUSE_GOOD is 0
- ..................................................................*/
- house = (HousesType)( (input & (~KN_BUTTON)) - POPUP_GDI);
- /*..................................................................
- If that house doesn't own this object, try to transfer it
- ..................................................................*/
- if (CurrentObject[0]->Owner()!=house) {
- if (Change_House(house)) {
- Changed = 1;
- }
- }
- Set_House_Buttons(CurrentObject[0]->Owner(), Buttons, POPUP_GDI);
- HiddenPage.Clear();
- Flag_To_Redraw(true);
- input = KN_NONE;
- break;
- /*---------------------------------------------------------------------
- Object-Editing button: Mission
- ---------------------------------------------------------------------*/
- case (POPUP_MISSIONLIST | KN_BUTTON):
- if (CurrentObject[0]->Is_Techno()) {
- /*
- ........................ Set new mission ........................
- */
- mission = MapEditMissions[MissionList->Current_Index()];
- if (CurrentObject[0]->Get_Mission() != mission) {
- ((TechnoClass *)CurrentObject[0])->Set_Mission(mission);
- Changed = 1;
- }
- }
- Flag_To_Redraw(true);
- input = KN_NONE;
- break;
- /*---------------------------------------------------------------------
- Object-Editing button: Health
- ---------------------------------------------------------------------*/
- case (POPUP_HEALTHGAUGE | KN_BUTTON):
- if (CurrentObject[0]->Is_Techno()) {
- /*
- .......... Derive strength from current gauge reading ...........
- */
- strength = Fixed_To_Cardinal(
- (unsigned)CurrentObject[0]->Class_Of().MaxStrength,
- (unsigned)HealthGauge->Get_Value());
- /*
- ........................... Clip to 1 ...........................
- */
- if (strength <= 0) {
- strength = 1;
- }
- /*
- ....................... Set new strength ........................
- */
- if (strength != CurrentObject[0]->Strength) {
- CurrentObject[0]->Strength = strength;
- HiddenPage.Clear();
- Flag_To_Redraw(true);
- Changed = 1;
- }
- /*
- ....................... Update text label .......................
- */
- sprintf(HealthBuf,"%d",strength);
- }
- input = KN_NONE;
- break;
- /*---------------------------------------------------------------------
- Object-Editing button: Facing
- ---------------------------------------------------------------------*/
- case (POPUP_FACINGDIAL | KN_BUTTON):
- if (CurrentObject[0]->Is_Techno()) {
- /*
- ........................ Set new facing .........................
- */
- if (FacingDial->Get_Direction() !=
- ((TechnoClass *)CurrentObject[0])->PrimaryFacing.Get()) {
- /*
- ..................... Set body's facing ......................
- */
- ((TechnoClass *)CurrentObject[0])->PrimaryFacing.Set(FacingDial->Get_Direction());
- /*
- ............. Set turret facing, if there is one .............
- */
- if (CurrentObject[0]->What_Am_I()==RTTI_UNIT) {
- ((UnitClass *)CurrentObject[0])->SecondaryFacing.Set(FacingDial->Get_Direction());
- }
- HiddenPage.Clear();
- Flag_To_Redraw(true);
- Changed = 1;
- }
- }
- input = KN_NONE;
- break;
- /*---------------------------------------------------------------------
- Object-Editing button: Facing
- ---------------------------------------------------------------------*/
- case (POPUP_BASEPERCENT | KN_BUTTON):
- if (BaseGauge->Get_Value() != BasePercent) {
- BasePercent = BaseGauge->Get_Value();
- Build_Base_To(BasePercent);
- HiddenPage.Clear();
- Flag_To_Redraw(true);
- }
- input = KN_NONE;
- break;
- case (KN_LMOUSE):
- input = KN_NONE;
- break;
- default:
- break;
- }
- /*
- ------------------------ Call parent's AI routine ------------------------
- */
- MouseClass::AI(input, x, y);
- }
- /***************************************************************************
- * MapEditClass::Draw_It -- overloaded Redraw routine *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 11/17/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::Draw_It(bool forced)
- {
- char const *label;
- char buf[40];
- char const *tptr;
- MouseClass::Draw_It(forced);
- if (!Debug_Map) {
- return;
- }
- //
- // Erase scrags at top of screen
- //
- LogicPage->Fill_Rect(0, 0, 640, 16, BLACK);
- /*
- ** Display the total value of all Tiberium on the map.
- */
- Fancy_Text_Print("Tiberium=%ld ", 0, 0, CC_GREEN, BLACK,
- TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, TotalValue);
- /*------------------------------------------------------------------------
- If there are no object controls displayed, just invoke parent's Redraw
- and return.
- ------------------------------------------------------------------------*/
- if (!Buttons) {
- return;
- }
- /*------------------------------------------------------------------------
- Otherwise, if 'display' is set, invoke the parent's Redraw to refresh
- the HIDPAGE; then, update the buttons & text labels onto HIDPAGE;
- then invoke the parent's Redraw to blit the HIDPAGE to SEENPAGE.
- ------------------------------------------------------------------------*/
- if (forced) {
- /*
- ....................... Update the text labels ........................
- */
- if (CurrentObject.Count()) {
- /*
- ------------------ Display the object's name & ID ------------------
- */
- label = Text_String(CurrentObject[0]->Full_Name());
- tptr = label;
- sprintf(buf,"%s (%d)",tptr,CurrentObject[0]->As_Target());
- /*
- ......................... print the label ..........................
- */
- Fancy_Text_Print (buf, 320, 0, CC_TAN, TBLACK,
- TPF_CENTER | TPF_NOSHADOW | TPF_6PT_GRAD | TPF_USE_GRAD_PAL);
- }
- }
- }
- /***************************************************************************
- * MapEditClass::Mouse_Moved -- checks for mouse motion *
- * *
- * Reports whether the mouse has moved or not. This varies based on the *
- * type of object currently selected. If there's an infantry object *
- * selected, mouse motion counts even within a cell; for all other types,*
- * mouse motion counts only if the mouse changes cells. *
- * *
- * The reason this routine is needed is to prevent Paint-Mode from putting*
- * gobs of trees and such into the same cell if the mouse moves just *
- * a little bit. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 11/08/1994 BR : Created. *
- *=========================================================================*/
- bool MapEditClass::Mouse_Moved(void)
- {
- static int old_mx = 0;
- static int old_my = 0;
- static CELL old_zonecell = 0;
- const ObjectTypeClass * objtype = NULL;
- bool retcode = false;
- /*
- -------------------------- Return if no motion ---------------------------
- */
- if (old_mx == Get_Mouse_X() && old_my == Get_Mouse_Y()) {
- return(false);
- }
- /*
- ---------------------- Get a ptr to ObjectTypeClass ----------------------
- */
- if (PendingObject) {
- objtype = PendingObject;
- } else {
- if (GrabbedObject) {
- objtype = &GrabbedObject->Class_Of();
- } else {
- old_mx = Get_Mouse_X();
- old_my = Get_Mouse_Y();
- old_zonecell = ZoneCell;
- return(false);
- }
- }
- /*
- --------------------- Check for motion based on type ---------------------
- */
- /*
- ............... Infantry: mouse moved if any motion at all ...............
- */
- if (objtype->What_Am_I() == RTTI_INFANTRYTYPE) {
- retcode = true;
- } else {
- /*
- ................ Others: mouse moved only if cell changed ................
- */
- if (old_zonecell!=ZoneCell) {
- retcode = true;
- } else {
- retcode = false;
- }
- }
- old_mx = Get_Mouse_X();
- old_my = Get_Mouse_Y();
- old_zonecell = ZoneCell;
- return(retcode);
- }
- /***************************************************************************
- * MapEditClass::Main_Menu -- main menu processor for map editor *
- * *
- * INPUT: *
- * none. *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 10/20/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::Main_Menu(void)
- {
- char const *_menus[MAX_MAIN_MENU_NUM + 1];
- int selection; // option the user picks
- bool process; // menu stays up while true
- int rc;
- /*
- --------------------------- Fill in menu items ---------------------------
- */
- _menus[0] = "New Scenario";
- _menus[1] = "Load Scenario";
- _menus[2] = "Save Scenario";
- _menus[3] = "Size Map";
- _menus[4] = "Add Game Object";
- _menus[5] = "Scenario Options";
- _menus[6] = "AI Options";
- _menus[7] = "Play Scenario";
- _menus[8] = NULL;
- /*
- ----------------------------- Main Menu loop -----------------------------
- */
- Override_Mouse_Shape(MOUSE_NORMAL); // display default mouse cursor
- process = true;
- while (process) {
- /*
- ................ Invoke game callback, to update music ................
- */
- Call_Back();
- /*
- ............................. Invoke menu .............................
- */
- Hide_Mouse(); // Do_Menu assumes the mouse is already hidden
- selection = Do_Menu(&_menus[0], true);
- Show_Mouse();
- if (UnknownKey==KN_ESC || UnknownKey==KN_LMOUSE || UnknownKey==KN_RMOUSE) {
- break;
- }
- /*
- .......................... Process selection ..........................
- */
- switch (selection) {
- /*
- ........................... New scenario ...........................
- */
- case 0:
- if (Changed) {
- rc = CCMessageBox().Process("Save Changes?", TXT_YES, TXT_NO);
- HiddenPage.Clear();
- Flag_To_Redraw(true);
- Render();
- if (rc==0) {
- if (Save_Scenario()!=0) {
- break;
- } else {
- Changed = 0;
- }
- }
- }
- if (New_Scenario()==0) {
- CarryOverMoney = 0;
- Changed = 1;
- }
- process = false;
- break;
- /*
- .......................... Load scenario ...........................
- */
- case 1:
- if (Changed) {
- rc = CCMessageBox().Process("Save Changes?", TXT_YES, TXT_NO);
- HiddenPage.Clear();
- Flag_To_Redraw(true);
- Render();
- if (rc==0) {
- if (Save_Scenario()!=0) {
- break;
- } else {
- Changed = 0;
- }
- }
- }
- if (Load_Scenario()==0) {
- CarryOverMoney = 0;
- Changed = 0;
- }
- process = false;
- break;
- /*
- .......................... Save scenario ...........................
- */
- case 2:
- if (Save_Scenario() == 0) {
- Changed = 0;
- }
- process = false;
- break;
- /*
- .......................... Edit map size ...........................
- */
- case 3:
- if (Size_Map(MapCellX, MapCellY, MapCellWidth, MapCellHeight)==0) {
- process = false;
- Changed = 1;
- }
- break;
- /*
- .......................... Add an object ...........................
- */
- case 4:
- if (Placement_Dialog() == 0) {
- Start_Placement();
- process = false;
- }
- break;
- /*
- ......................... Scenario options .........................
- */
- case 5:
- if (Scenario_Dialog() == 0) {
- Changed = 1;
- process = false;
- }
- break;
- /*
- .......................... Other options ...........................
- */
- case 6:
- AI_Menu();
- process = false;
- break;
- /*
- ...................... Test-drive this scenario ....................
- */
- case 7:
- if (Changed) {
- rc = CCMessageBox().Process("Save Changes?", TXT_YES, TXT_NO);
- HiddenPage.Clear();
- Flag_To_Redraw(true);
- Render();
- if (rc==0) {
- if (Save_Scenario()!=0) {
- break;
- } else {
- Changed = 0;
- }
- }
- }
- Changed = 0;
- Debug_Map = false;
- Start_Scenario(ScenarioName);
- return;
- }
- }
- /*------------------------------------------------------------------------
- Restore the display:
- - Clear HIDPAGE to erase any spurious drawing done by the menu system
- - Invoke Flag_To_Redraw to tell DisplayClass to re-render the whole screen
- - Invoke Redraw() to update the display
- ------------------------------------------------------------------------*/
- HiddenPage.Clear();
- Flag_To_Redraw(true);
- Render();
- }
- /***************************************************************************
- * MapEditClass::AI_Menu -- menu of AI options *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 11/29/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::AI_Menu(void)
- {
- int selection; // option the user picks
- bool process; // menu stays up while true
- char const *_menus[MAX_AI_MENU_NUM + 1];
- /*
- -------------------------- Fill in menu strings --------------------------
- */
- _menus[0] = "Pre-Build a Base";
- _menus[1] = "Import Triggers";
- _menus[2] = "Edit Triggers";
- _menus[3] = "Import Teams";
- _menus[4] = "Edit Teams";
- _menus[5] = NULL;
- /*
- ----------------------------- Main Menu loop -----------------------------
- */
- Override_Mouse_Shape(MOUSE_NORMAL); // display default mouse cursor
- process = true;
- while (process) {
- /*
- ................ Invoke game callback, to update music ................
- */
- Call_Back();
- /*
- ............................. Invoke menu .............................
- */
- Hide_Mouse(); // Do_Menu assumes the mouse is already hidden
- selection = Do_Menu(&_menus[0], true);
- Show_Mouse();
- if (UnknownKey==KN_ESC || UnknownKey==KN_LMOUSE || UnknownKey==KN_RMOUSE) {
- break;
- }
- /*
- .......................... Process selection ..........................
- */
- switch (selection) {
- /*
- ......................... Pre-Build a Base .........................
- */
- case 0:
- Start_Base_Building();
- process = false;
- break;
- /*
- ......................... Import Triggers ..........................
- */
- case 1:
- if (Import_Triggers()==0)
- process = false;
- break;
- /*
- ......................... Trigger Editing ..........................
- */
- case 2:
- Handle_Triggers();
- /*
- ................ Go into trigger placement mode .................
- */
- if (CurTrigger) {
- Start_Trigger_Placement();
- }
- process = false;
- break;
- /*
- ........................... Import Teams ...........................
- */
- case 3:
- if (Import_Teams()==0)
- process = false;
- break;
- /*
- ........................... Team Editing ...........................
- */
- case 4:
- Handle_Teams("Teams");
- process = false;
- break;
- }
- }
- }
- /***************************************************************************
- * MapEditClass::Verify_House -- is this objtype ownable by this house? *
- * *
- * INPUT: *
- * house house to check *
- * objtype ObjectTypeClass to check *
- * *
- * OUTPUT: *
- * 0 = isn't ownable, 1 = it is *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 11/16/1994 BR : Created. *
- *=========================================================================*/
- bool MapEditClass::Verify_House(HousesType house, ObjectTypeClass const *objtype)
- {
- /*
- --------------- Verify that new house can own this object ----------------
- */
- return((objtype->Get_Ownable() & (1 << house)) != 0);
- }
- /***************************************************************************
- * MapEditClass::Cycle_House -- finds next valid house for object type *
- * *
- * INPUT: *
- * objtype ObjectTypeClass ptr to get house for *
- * curhouse current house value to start with *
- * *
- * OUTPUT: *
- * HousesType that's valid for this object type *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 11/23/1994 BR : Created. *
- *=========================================================================*/
- HousesType MapEditClass::Cycle_House(HousesType curhouse,
- ObjectTypeClass const *objtype)
- {
- HousesType count; // prevents an infinite loop
- /*------------------------------------------------------------------------
- Loop through all house types, starting with the one after 'curhouse';
- return the first one that's valid
- ------------------------------------------------------------------------*/
- count = HOUSE_NONE;
- while (1) {
- /*
- .......................... Go to next house ...........................
- */
- curhouse++;
- if (curhouse == HOUSE_COUNT) {
- curhouse = HOUSE_FIRST;
- }
- /*
- ................ Count # iterations; don't go forever .................
- */
- count++;
- if (count == HOUSE_COUNT) {
- curhouse = HOUSE_NONE;
- break;
- }
- /*
- ................... Break if this is a valid house ....................
- */
- if (HouseClass::As_Pointer(curhouse) && Verify_House(curhouse,objtype)) {
- break;
- }
- }
- return(curhouse);
- }
- /***************************************************************************
- * MapEditClass::Fatal -- exits with error message *
- * *
- * INPUT: *
- * code tells which message to display; this minimizes the *
- * use of character strings in the code. *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 12/12/1994 BR : Created. *
- *=========================================================================*/
- void MapEditClass::Fatal(int txt)
- {
- Prog_End();
- printf("%s\n",txt);
- if (!RunningAsDLL) {
- exit(EXIT_FAILURE);
- }
- }
- bool MapEditClass::Scroll_Map(DirType facing, int & distance, bool really)
- {
- if (Debug_Map) {
- /*
- ** The popup gadgets require the entire map to be redrawn if we scroll.
- */
- if (really) {
- Flag_To_Redraw(true);
- }
- }
- return(MouseClass::Scroll_Map(facing, distance, really));
- }
- void MapEditClass::Detach(ObjectClass * object)
- {
- if (GrabbedObject == object) {
- GrabbedObject = 0;
- }
- }
- #endif
- #include "mapedsel.cpp"
|