/* ** Command & Conquer Generals(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 . */ //////////////////////////////////////////////////////////////////////////////// // // // (c) 2001-2003 Electronic Arts Inc. // // // //////////////////////////////////////////////////////////////////////////////// // FILE: ControlBar.h ///////////////////////////////////////////////////////////////////////////// // Author: Colin Day, March 2002 // Desc: Context sensitive command interface /////////////////////////////////////////////////////////////////////////////////////////////////// #pragma once #ifndef __CONTROLBAR_H_ #define __CONTROLBAR_H_ // USER INCLUDES ////////////////////////////////////////////////////////////////////////////////// #include "Common/AudioEventRTS.h" #include "Common/GameType.h" #include "Common/Overridable.h" #include "Common/Science.h" #include "GameClient/Color.h" // FORWARD REFERENCES ///////////////////////////////////////////////////////////////////////////// class Drawable; class GameWindow; class Image; class Object; class ThingTemplate; class WeaponTemplate; class SpecialPowerTemplate; class WindowVideoManager; class WindowVideoManager; class AnimateWindowManager; class GameWindow; class WindowLayout; class Player; class PlayerTemplate; class AudioEventRTS; class ControlBarSchemeManager; class UpgradeTemplate; class ControlBarResizer; class GameWindowTransitionsHandler; enum ProductionID; enum CommandSourceType; enum ProductionType; enum GadgetGameMessage; enum ScienceType; enum TimeOfDay; enum RadiusCursorType; //------------------------------------------------------------------------------------------------- /** Command options */ //------------------------------------------------------------------------------------------------- enum CommandOption { COMMAND_OPTION_NONE = 0x00000000, NEED_TARGET_ENEMY_OBJECT = 0x00000001, // command now needs user to select enemy target NEED_TARGET_NEUTRAL_OBJECT = 0x00000002, // command now needs user to select neutral target NEED_TARGET_ALLY_OBJECT = 0x00000004, // command now needs user to select ally target #ifdef ALLOW_SURRENDER NEED_TARGET_PRISONER = 0x00000008, // needs user to now select prisoner object #endif ALLOW_SHRUBBERY_TARGET = 0x00000010, // allow neutral shrubbery as a target NEED_TARGET_POS = 0x00000020, // command now needs user to select target position NEED_UPGRADE = 0x00000040, // command requires upgrade to be enabled NEED_SPECIAL_POWER_SCIENCE = 0x00000080, // command requires a science in the special power specified OK_FOR_MULTI_SELECT = 0x00000100, // command is ok to show when multiple objects selected CONTEXTMODE_COMMAND = 0x00000200, // a context sensitive command mode that requires code to determine whether cursor is valid or not. CHECK_LIKE = 0x00000400, // dynamically change the UI element push button to be "check like" ALLOW_MINE_TARGET = 0x00000800, // allow (land)mines as a target ATTACK_OBJECTS_POSITION = 0x00001000, // for weapons that need an object target but attack the position indirectly (like burning trees) OPTION_ONE = 0x00002000, // User data -- option 1 OPTION_TWO = 0x00004000, // User data -- option 2 OPTION_THREE = 0x00008000, // User data -- option 3 NOT_QUEUEABLE = 0x00010000, // Option not build queueable meaning you can only build it when queue is empty! SINGLE_USE_COMMAND = 0x00020000, // Once used, it can never be used again! COMMAND_FIRED_BY_SCRIPT = 0x00040000, // Used only by code to tell special powers that they have been fired by a script. SCRIPT_ONLY = 0x00080000, // Only a script can use this command (not by users) IGNORES_UNDERPOWERED = 0x00100000, // this button isn't disabled if its object is merely underpowered USES_MINE_CLEARING_WEAPONSET= 0x00200000, // uses the special mine-clearing weaponset, even if not current NUM_COMMAND_OPTIONS // keep this last }; #ifdef DEFINE_COMMAND_OPTION_NAMES static const char *TheCommandOptionNames[] = { "NEED_TARGET_ENEMY_OBJECT", "NEED_TARGET_NEUTRAL_OBJECT", "NEED_TARGET_ALLY_OBJECT", #ifdef ALLOW_SURRENDER "NEED_TARGET_PRISONER", #else "unused-reserved", #endif "ALLOW_SHRUBBERY_TARGET", "NEED_TARGET_POS", "NEED_UPGRADE", "NEED_SPECIAL_POWER_SCIENCE", "OK_FOR_MULTI_SELECT", "CONTEXTMODE_COMMAND", "CHECK_LIKE", "ALLOW_MINE_TARGET", "ATTACK_OBJECTS_POSITION", "OPTION_ONE", "OPTION_TWO", "OPTION_THREE", "NOT_QUEUEABLE", "SINGLE_USE_COMMAND", "---DO-NOT-USE---", //COMMAND_FIRED_BY_SCRIPT "SCRIPT_ONLY", "IGNORES_UNDERPOWERED", "USES_MINE_CLEARING_WEAPONSET", NULL }; #endif // end DEFINE_COMMAND_OPTION_NAMES // convenient bit masks to group some command options together const UnsignedInt COMMAND_OPTION_NEED_TARGET = NEED_TARGET_ENEMY_OBJECT | NEED_TARGET_NEUTRAL_OBJECT | NEED_TARGET_ALLY_OBJECT | NEED_TARGET_POS | CONTEXTMODE_COMMAND; const UnsignedInt COMMAND_OPTION_NEED_OBJECT_TARGET = NEED_TARGET_ENEMY_OBJECT | NEED_TARGET_NEUTRAL_OBJECT | NEED_TARGET_ALLY_OBJECT; //------------------------------------------------------------------------------------------------- /** These are the list of commands that can be assigned to buttons that will appear * in the context sensitive GUI for a selected unit. Not all commands are available * on all units, in fact, many commands are for a particular single command. It will * be up to the command GUI to translate the command assigned to a button into the * appropriate game command and get it across the network to the game logic to perform the * actual command logic * * IMPORTANT: Make sure the GUICommandType enum and the TheGuiCommandNames[] have the same * entries in the same order */ //------------------------------------------------------------------------------------------------- enum GUICommandType { GUI_COMMAND_NONE = 0, ///< invalid command GUI_COMMAND_DOZER_CONSTRUCT, ///< dozer construct GUI_COMMAND_DOZER_CONSTRUCT_CANCEL, ///< cancel a dozer construction process GUI_COMMAND_UNIT_BUILD, ///< build a unit GUI_COMMAND_CANCEL_UNIT_BUILD, ///< cancel a unit build GUI_COMMAND_PLAYER_UPGRADE, ///< put an upgrade that applies to the player in the queue GUI_COMMAND_OBJECT_UPGRADE, ///< put an object upgrade in the queue GUI_COMMAND_CANCEL_UPGRADE, ///< cancel an upgrade GUI_COMMAND_ATTACK_MOVE, ///< attack move command GUI_COMMAND_GUARD, ///< guard command GUI_COMMAND_GUARD_WITHOUT_PURSUIT, ///< guard command, no pursuit out of guard area GUI_COMMAND_GUARD_FLYING_UNITS_ONLY, ///< guard command, ignore nonflyers GUI_COMMAND_STOP, ///< stop moving GUI_COMMAND_WAYPOINTS, ///< create a set of waypoints for this unit GUI_COMMAND_EXIT_CONTAINER, ///< an inventory box for a container like a structure or transport GUI_COMMAND_EVACUATE, ///< dump all our contents GUI_COMMAND_EXECUTE_RAILED_TRANSPORT, ///< execute railed transport sequence GUI_COMMAND_BEACON_DELETE, ///< delete a beacon GUI_COMMAND_SET_RALLY_POINT, ///< set rally point for a structure GUI_COMMAND_SELL, ///< sell a structure GUI_COMMAND_FIRE_WEAPON, ///< fire a weapon GUI_COMMAND_SPECIAL_POWER, ///< do a special power GUI_COMMAND_PURCHASE_SCIENCE, ///< purchase science GUI_COMMAND_HACK_INTERNET, ///< Hey author, write me! GUI_COMMAND_TOGGLE_OVERCHARGE, ///< Overcharge command for power plants #ifdef ALLOW_SURRENDER GUI_COMMAND_POW_RETURN_TO_PRISON, ///< POW Truck, return to prison #endif GUI_COMMAND_COMBATDROP, ///< rappel contents to ground or bldg GUI_COMMAND_SWITCH_WEAPON, ///< switch weapon use //Context senstive command modes GUICOMMANDMODE_HIJACK_VEHICLE, GUICOMMANDMODE_CONVERT_TO_CARBOMB, #ifdef ALLOW_SURRENDER GUICOMMANDMODE_PICK_UP_PRISONER, ///< POW Truck assigned to pick up a specific prisoner #endif // context-insensitive command mode(s) GUICOMMANDMODE_PLACE_BEACON, GUI_COMMAND_SPECIAL_POWER_FROM_COMMAND_CENTER, ///< do a special power from localPlayer's command center, regardless of selection // add more commands here, don't forget to update the string command list below too ... GUI_COMMAND_NUM_COMMANDS // keep this last }; #ifdef DEFINE_GUI_COMMMAND_NAMES static const char *TheGuiCommandNames[] = { "NONE", "DOZER_CONSTRUCT", "DOZER_CONSTRUCT_CANCEL", "UNIT_BUILD", "CANCEL_UNIT_BUILD", "PLAYER_UPGRADE", "OBJECT_UPGRADE", "CANCEL_UPGRADE", "ATTACK_MOVE", "GUARD", "GUARD_WITHOUT_PURSUIT", "GUARD_FLYING_UNITS_ONLY", "STOP", "WAYPOINTS", "EXIT_CONTAINER", "EVACUATE", "EXECUTE_RAILED_TRANSPORT", "BEACON_DELETE", "SET_RALLY_POINT", "SELL", "FIRE_WEAPON", "SPECIAL_POWER", "PURCHASE_SCIENCE", "HACK_INTERNET", "TOGGLE_OVERCHARGE", #ifdef ALLOW_SURRENDER "POW_RETURN_TO_PRISON", #endif "COMBATDROP", "SWITCH_WEAPON", "HIJACK_VEHICLE", "CONVERT_TO_CARBOMB", #ifdef ALLOW_SURRENDER "PICK_UP_PRISONER", #endif "PLACE_BEACON", "SPECIAL_POWER_FROM_COMMAND_CENTER", NULL }; #endif // end DEFINE_GUI_COMMAND_NAMES enum CommandButtonMappedBorderType { COMMAND_BUTTON_BORDER_NONE = 0, COMMAND_BUTTON_BORDER_BUILD, COMMAND_BUTTON_BORDER_UPGRADE, COMMAND_BUTTON_BORDER_ACTION, COMMAND_BUTTON_BORDER_SYSTEM, COMMAND_BUTTON_BORDER_COUNT // keep this last }; static const LookupListRec CommandButtonMappedBorderTypeNames[] = { { "NONE", COMMAND_BUTTON_BORDER_NONE }, { "BUILD", COMMAND_BUTTON_BORDER_BUILD }, { "UPGRADE", COMMAND_BUTTON_BORDER_UPGRADE }, { "ACTION", COMMAND_BUTTON_BORDER_ACTION }, { "SYSTEM", COMMAND_BUTTON_BORDER_SYSTEM }, { NULL, 0 }// keep this last! }; //------------------------------------------------------------------------------------------------- /** Command buttons are used to load the buttons we place on throughout the command bar * interface in different context sensitive windows depending on the situation and * type of the object selected */ //------------------------------------------------------------------------------------------------- class CommandButton : public Overridable { MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( CommandButton, "CommandButton" ); public: CommandButton( void ); // virtual destructor prototype provided by MemoryPoolObject /// INI parsing const FieldParse *getFieldParse() const { return s_commandButtonFieldParseTable; } static const FieldParse s_commandButtonFieldParseTable[]; ///< the parse table static void parseCommand( INI* ini, void *instance, void *store, const void *userData ); Bool isContextCommand() const; ///< determines if this is a context sensitive command. Bool isValidRelationshipTarget(Relationship r) const; Bool isValidObjectTarget(const Player* sourcePlayer, const Object* targetObj) const; Bool isValidObjectTarget(const Object* sourceObj, const Object* targetObj) const; Bool isValidObjectTarget(const Drawable* source, const Drawable* target) const; // Note: It is perfectly valid for either (or both!) of targetObj and targetLocation to be NULL. // This is a convenience function to make several calls to other functions. Bool isValidToUseOn(const Object *sourceObj, const Object *targetObj, const Coord3D *targetLocation, CommandSourceType commandSource) const; Bool isReady(const Object *sourceObj) const; const AsciiString& getName() const { return m_name; } const AsciiString& getCursorName() const { return m_cursorName; } const AsciiString& getInvalidCursorName() const { return m_invalidCursorName; } const AsciiString& getTextLabel() const { return m_textLabel; } const AsciiString& getDescriptionLabel() const { return m_descriptionLabel; } const AsciiString& getPurchasedLabel() const { return m_purchasedLabel; } const AsciiString& getConflictingLabel() const { return m_conflictingLabel; } const AudioEventRTS* getUnitSpecificSound() const { return &m_unitSpecificSound; } GUICommandType getCommandType() const { return m_command; } UnsignedInt getOptions() const { return m_options; } OVERRIDE getThingTemplate() const { return m_thingTemplate; } const UpgradeTemplate* getUpgradeTemplate() const { return m_upgradeTemplate; } const SpecialPowerTemplate* getSpecialPowerTemplate() const { return m_specialPower; } RadiusCursorType getRadiusCursorType() const { return m_radiusCursor; } WeaponSlotType getWeaponSlot() const { return m_weaponSlot; } Int getMaxShotsToFire() const { return m_maxShotsToFire; } const ScienceVec& getScienceVec() const { return m_science; } CommandButtonMappedBorderType getCommandButtonMappedBorderType() const { return m_commandButtonBorder; } const Image* getButtonImage() const { return m_buttonImage; } void cacheButtonImage(); GameWindow* getWindow() const { return m_window; } Int getFlashCount() const { return m_flashCount; } const CommandButton* getNext() const { return m_next; } void setName(const AsciiString& n) { m_name = n; } void setButtonImage( const Image *image ) { m_buttonImage = image; } // bleah. shouldn't be const, but is. sue me. (srj) void copyImagesFrom( const CommandButton *button, Bool markUIDirtyIfChanged ) const; // bleah. shouldn't be const, but is. sue me. (srj) void setFlashCount(Int c) const { m_flashCount = c; } // only for ControlBar! void friend_addToList(CommandButton** list) { m_next = *list; *list = this; } CommandButton* friend_getNext() { return m_next; } private: AsciiString m_name; ///< template name GUICommandType m_command; ///< type of command this button CommandButton* m_next; UnsignedInt m_options; ///< command options (see CommandOption enum) const ThingTemplate* m_thingTemplate; ///< for commands that use thing templates in command data const UpgradeTemplate* m_upgradeTemplate; ///< for commands that use upgrade templates in command data const SpecialPowerTemplate* m_specialPower; ///< actual special power template RadiusCursorType m_radiusCursor; ///< radius cursor, if any AsciiString m_cursorName; ///< cursor name for placement (NEED_TARGET_POS) or valid version (CONTEXTMODE_COMMAND) AsciiString m_invalidCursorName; ///< cursor name for invalid version AsciiString m_textLabel; ///< string manager text label AsciiString m_descriptionLabel; ///< The description of the current command, read in from the ini AsciiString m_purchasedLabel; ///< Description for the current command if it has already been purchased. AsciiString m_conflictingLabel; ///< Description for the current command if it can't be selected due to multually-exclusive choice. WeaponSlotType m_weaponSlot; ///< for commands that refer to a weapon slot Int m_maxShotsToFire; ///< for commands that fire weapons ScienceVec m_science; ///< actual science CommandButtonMappedBorderType m_commandButtonBorder; AsciiString m_buttonImageName; GameWindow* m_window; ///< used during the run-time assignment of a button to a gadget button window AudioEventRTS m_unitSpecificSound; ///< Unit sound played whenever button is clicked. // bleah. shouldn't be mutable, but is. sue me. (srj) mutable const Image* m_buttonImage; ///< button image // bleah. shouldn't be mutable, but is. sue me. (srj) mutable Int m_flashCount; ///< the number of times a cameo is supposed to flash }; //------------------------------------------------------------------------------------------------- /** Command sets are collections of configurable command buttons. They are used in the * command context sensitive window in the battle user interface */ //------------------------------------------------------------------------------------------------- enum { MAX_COMMANDS_PER_SET = 12 }; // user interface max button limit for commands enum { MAX_RIGHT_HUD_UPGRADE_CAMEOS = 5}; enum { MAX_PURCHASE_SCIENCE_RANK_1 = 3, MAX_PURCHASE_SCIENCE_RANK_3 = 12, MAX_PURCHASE_SCIENCE_RANK_8 = 1, }; enum { MAX_STRUCTURE_INVENTORY_BUTTONS = 10 }; // there are this many physical buttons in "inventory" windows for structures enum { MAX_BUILD_QUEUE_BUTTONS = 9 };// physical button count for the build queue enum { MAX_SPECIAL_POWER_SHORTCUTS = 5}; class CommandSet : public Overridable { MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( CommandSet, "CommandSet" ) public: CommandSet( const AsciiString& name ); // virtual destructor prototype provided by MemoryPoolObject const AsciiString& getName() const { return m_name; } const CommandButton* getCommandButton(Int i) const; // only for the control bar. CommandSet* friend_getNext() { return m_next; } const FieldParse* friend_getFieldParse() const { return m_commandSetFieldParseTable; } void friend_addToList(CommandSet** listHead); private: static const FieldParse m_commandSetFieldParseTable[]; ///< the parse table static void parseCommandButton( INI* ini, void *instance, void *store, const void *userData ); AsciiString m_name; ///< name of this command set const CommandButton *m_command[ MAX_COMMANDS_PER_SET ]; ///< the set of command buttons that make this set CommandSet *m_next; }; //------------------------------------------------------------------------------------------------- /** The Side selece window data is used to animate on the proper generals select */ //------------------------------------------------------------------------------------------------- class SideSelectWindowData { public: SideSelectWindowData(void) { //Added By Sadullah Nader //Initializations generalSpeak = NULL; m_currColor = 0; m_gereralsNameWin = NULL; m_lastTime = 0; m_pTemplate = NULL; m_sideNameWin = NULL; m_startTime = 0; m_state = 0; m_upgradeImage1 = NULL; m_upgradeImage1Win = NULL; m_upgradeImage2 = NULL; m_upgradeImage2Win = NULL; m_upgradeImage3 = NULL; m_upgradeImage3Win = NULL; m_upgradeImage4 = NULL; m_upgradeImage4Win = NULL; m_upgradeImageSize.x = m_upgradeImageSize.y = 0; m_upgradeLabel1Win = NULL; m_upgradeLabel2Win = NULL; m_upgradeLabel3Win = NULL; m_upgradeLabel4Win = NULL; sideWindow = NULL; // } ~SideSelectWindowData(void); void init( ScienceType science, GameWindow *control ); void reset( void ); void update( void ); void draw( void ); GameWindow *sideWindow; GameWindow *m_animWindowWin; AudioEventRTS *generalSpeak; private: enum { STATE_NONE = 0, STATE_1, STATE_2, STATE_3, STATE_4, STATE_5, STATE_6 }; const PlayerTemplate *m_pTemplate; GameWindow *m_gereralsNameWin; GameWindow *m_sideNameWin; GameWindow *m_upgradeLabel1Win; GameWindow *m_upgradeLabel2Win; GameWindow *m_upgradeLabel3Win; GameWindow *m_upgradeLabel4Win; GameWindow *m_upgradeImage1Win; GameWindow *m_upgradeImage2Win; GameWindow *m_upgradeImage3Win; GameWindow *m_upgradeImage4Win; Image *m_upgradeImage1; Image *m_upgradeImage2; Image *m_upgradeImage3; Image *m_upgradeImage4; IRegion2D m_leftLineFromButton; IRegion2D m_rightLineFromButton; IRegion2D m_upgradeLine1a; IRegion2D m_upgradeLine2a; IRegion2D m_upgradeLine3a; IRegion2D m_upgradeLine4a; IRegion2D m_upgradeLine1; IRegion2D m_upgradeLine2; IRegion2D m_upgradeLine3; IRegion2D m_upgradeLine4; IRegion2D m_upgradeLine1MidReg; IRegion2D m_upgradeLine2MidReg; IRegion2D m_upgradeLine3MidReg; IRegion2D m_upgradeLine4MidReg; IRegion2D m_upgrade1Clip; IRegion2D m_upgrade2Clip; IRegion2D m_upgrade3Clip; IRegion2D m_upgrade4Clip; Color m_currColor; ICoord2D m_line1End; ICoord2D m_line2End; ICoord2D m_upgradeLine1Mid; ICoord2D m_upgradeLine2Mid; ICoord2D m_upgradeLine3Mid; ICoord2D m_upgradeLine4Mid; ICoord2D m_upgradeLine1End; ICoord2D m_upgradeLine2End; ICoord2D m_upgradeLine3End; ICoord2D m_upgradeLine4End; ICoord2D m_upgradeImagePos1; ICoord2D m_upgradeImagePos2; ICoord2D m_upgradeImagePos3; ICoord2D m_upgradeImagePos4; ICoord2D m_upgradeImageSize; Int m_state; UnsignedInt m_lastTime; UnsignedInt m_startTime; }; //------------------------------------------------------------------------------------------------- /** A command bar context is a window or set of windows that make up a context sensitive * display of commands and information to the user based on what objects are selected * and their capabilities */ //------------------------------------------------------------------------------------------------- enum ControlBarContext { CB_CONTEXT_NONE, ///< default view for center bar and portrait window // CB_CONTEXT_PURCHASE_SCIENCE, CB_CONTEXT_COMMAND, ///< set of commands (attack-move,stop,deploy etc) CB_CONTEXT_STRUCTURE_INVENTORY, ///< garrisonable building inventory interface CB_CONTEXT_BEACON, ///< beacon interface CB_CONTEXT_UNDER_CONSTRUCTION, ///< building under construction CB_CONTEXT_MULTI_SELECT, ///< for when we have multiple objects selected CB_CONTEXT_OBSERVER_INFO, ///< for when we want to populate the player info CB_CONTEXT_OBSERVER_LIST, ///< for when we want to update the observer list CB_CONTEXT_OCL_TIMER, ///< Countdown for OCL spewers NUM_CB_CONTEXTS }; //------------------------------------------------------------------------------------------------- /** Context parents, are parent windows in the control bar interface that are the key * parts we care about to make the whole interface a context sensitive one. We will * hide and un-hide these windows and their interface controls in order to make * the control bar context sensitive to the object that is selected */ //------------------------------------------------------------------------------------------------- enum ContextParent { CP_MASTER, ///< *The* control bar window as a whole CP_PURCHASE_SCIENCE, CP_COMMAND, ///< configurable command buttons parent CP_BUILD_QUEUE, ///< build queue parent CP_BEACON, ///< beacon parent CP_UNDER_CONSTRUCTION, ///< building under construction parent CP_OBSERVER_INFO, ///< Observer Info window parent CP_OBSERVER_LIST, ///< Observer player list parent CP_OCL_TIMER, ///< Countdown for OCL spewers NUM_CONTEXT_PARENTS }; //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- enum CBCommandStatus { CBC_COMMAND_NOT_USED = 0, ///< gui control message was *not* used CBC_COMMAND_USED ///< gui control message was used }; // ------------------------------------------------------------------------------------------------ /** Command availability is used during the context update so that we can set the * GUI button to be enabled/disabled/checked/unchecked to represent the current * state of that command availability */ // ------------------------------------------------------------------------------------------------ enum CommandAvailability { COMMAND_RESTRICTED, COMMAND_AVAILABLE, COMMAND_ACTIVE, COMMAND_HIDDEN, COMMAND_NOT_READY, COMMAND_CANT_AFFORD, }; enum ControlBarStages { CONTROL_BAR_STAGE_DEFAULT = 0, ///< full view for the world to see CONTROL_BAR_STAGE_SQUISHED, ///< squished just for expeirenced players CONTROL_BAR_STAGE_LOW, ///< control bar a la minimalist CONTROL_BAR_STAGE_HIDDEN, ///< yo, where be da control bar at? MAX_CONTROL_BAR_STAGES }; //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- class ControlBar : public SubsystemInterface { public: ControlBar( void ); virtual ~ControlBar( void ); virtual void init( void ); ///< from subsystem interface virtual void reset( void ); ///< from subsystem interface virtual void update( void ); ///< from subsystem interface /// mark the UI as dirty so the context of everything is re-evaluated void markUIDirty( void ) { m_UIDirty = TRUE; } /// a drawable has just become selected void onDrawableSelected( Drawable *draw ); /// a drawable has just become de-selected void onDrawableDeselected( Drawable *draw ); void onPlayerRankChanged(const Player *p); void onPlayerSciencePurchasePointsChanged(const Player *p); /** if this button is part of the context sensitive command system, process a button click the gadgetMessage is either a GBM_SELECTED or GBM_SELECTED_RIGHT */ CBCommandStatus processContextSensitiveButtonClick( GameWindow *button, GadgetGameMessage gadgetMessage ); /** if this button is part of the context sensitive command system, process the Transition gadgetMessage is either a GBM_MOUSE_LEAVING or GBM_MOUSE_ENTERING */ CBCommandStatus processContextSensitiveButtonTransition( GameWindow *button, GadgetGameMessage gadgetMessage ); /// is the drawable the currently selected drawable for the context sensitive UI? Bool isDrivingContextUI( Drawable *draw ) const { return draw == m_currentSelectedDrawable; } //----------------------------------------------------------------------------------------------- // the remaining methods are used to construct the command buttons and command sets for // the command bar //----------------------------------------------------------------------------------------------- /// find existing command button if present const CommandButton *findCommandButton( const AsciiString& name ); /// find existing command set const CommandSet *findCommandSet( const AsciiString& name ); void showPurchaseScience( void ); void hidePurchaseScience( void ); void togglePurchaseScience( void ); void showSpecialPowerShortcut( void ); void hideSpecialPowerShortcut( void ); void animateSpecialPowerShortcut( Bool isOn ); /// set the control bar to the proper scheme based off a player template that's passed in ControlBarSchemeManager *getControlBarSchemeManager( void ) { return m_controlBarSchemeManager; } void setControlBarSchemeByPlayer(Player *p); void setControlBarSchemeByName(const AsciiString& name); void setControlBarSchemeByPlayerTemplate(const PlayerTemplate *pt); /// We need to sometime change what the images look like depending on what scheme we're using void updateBuildQueueDisabledImages( const Image *image ); /// We need to sometime change what the images look like depending on what scheme we're using void updateRightHUDImage( const Image *image ); /// We need to be able to update the command marker image based on which scheme we're using. void updateCommandMarkerImage( const Image *image ); void updateSlotExitImage( const Image *image); void updateUpDownImages( const Image *toggleButtonUpIn, const Image *toggleButtonUpOn, const Image *toggleButtonUpPushed, const Image *toggleButtonDownIn, const Image *toggleButtonDownOn, const Image *toggleButtonDownPushed,const Image *generalButtonEnable, const Image *generalButtonHighlight ); void preloadAssets( TimeOfDay timeOfDay ); ///< preload the assets /// We want to be able to have the control bar scheme set the color of the build up clock void updateBuildUpClockColor( Color color); WindowVideoManager *m_videoManager; ///< Video manager to take care of all animations on screen. AnimateWindowManager *m_animateWindowManager; ///< The animate window manager AnimateWindowManager *m_animateWindowManagerForGenShortcuts; ///< The animate window manager void updatePurchaseScience( void ); AnimateWindowManager *m_generalsScreenAnimate; ///< The animate window manager // Initialize the Observer controls Must be called after we've already loaded the window void initObserverControls( void ); void setObserverLookAtPlayer (Player *p) { m_observerLookAtPlayer = p;} Player *getObserverLookAtPlayer (void ) { return m_observerLookAtPlayer;} void populateObserverInfoWindow ( void ); void populateObserverList( void ); Bool isObserverControlBarOn( void ) { return m_isObserverCommandBar;} // ControlBarResizer *getControlBarResizer( void ) {return m_controlBarResizer;} // Functions for repositioning/resizing the control bar void switchControlBarStage( ControlBarStages stage ); void toggleControlBarStage( void ); const Image *getStarImage( void ); Color getBorderColor( void ){return m_commandBarBorderColor;} void updateBorderColor( Color color) {m_commandBarBorderColor = color; } /// set the command data into the button void setControlCommand( GameWindow *button, const CommandButton *commandButton ); void getForegroundMarkerPos(Int *x, Int *y); void getBackgroundMarkerPos(Int *x, Int *y); static void parseCommandSetDefinition( INI *ini ); static void parseCommandButtonDefinition( INI *ini ); void drawTransitionHandler( void ); const Image *getArrowImage( void ){ return m_genArrow; } void setArrowImage( const Image *arrowImage ){ m_genArrow = arrowImage; } void initSpecialPowershortcutBar( Player *player); void triggerRadarAttackGlow( void ); protected: void updateRadarAttackGlow ( void ); void setDefaultControlBarConfig( void ); void setSquishedControlBarConfig( void ); void setLowControlBarConfig( void ); void setHiddenControlBar( void ); /// find existing command button if present CommandButton* findNonConstCommandButton( const AsciiString& name ); /// allocate a new command button, link to list, initialize to default, and return CommandButton *newCommandButton( const AsciiString& name ); CommandButton *newCommandButtonOverride( CommandButton *buttonToOverride ); /// allocate a new command set, link to list, initialize to default, and return it CommandSet *newCommandSet( const AsciiString& name ); CommandSet *newCommandSetOverride( CommandSet *setToOverride ); /// evaluate what the user should see based on what selected drawables we have in our UI void evaluateContextUI( void ); /// add the common commands of this drawable to the common command set void addCommonCommands( Drawable *draw, Bool firstDrawable ); /// switch the interface context to the new mode and populate as needed void switchToContext( ControlBarContext context, Drawable *draw ); /// set the command data into the button void setControlCommand( const AsciiString& buttonWindowName, GameWindow *parent, const CommandButton *commandButton ); /// show/hide the portrait window image using the image pointer to set void setPortraitByImage( const Image *image ); /// show/hide the portrait window image using the image from the object void setPortraitByObject( Object *obj ); /// show rally point at world location, a NULL location will hide any visible rally point marker void showRallyPoint( const Coord3D *loc ); /// post process step, after all commands and command sets are loaded void postProcessCommands( void ); // the following methods are for resetting data for vaious contexts void resetCommonCommandData( void ); /// reset shared command data void resetContainData( void ); /// reset container data we use to tie controls to objects IDs for containment void resetBuildQueueData( void ); /// reset the build queue data we use to die queue entires to control // the following methods are for populating the context GUI controls for a particular context static void populateButtonProc( Object *obj, void *userData ); void populatePurchaseScience(Player* player); void populateCommand( Object *obj ); void populateMultiSelect( void ); void populateBuildQueue( Object *producer ); void populateStructureInventory( Object *building ); void populateBeacon( Object *beacon ); void populateUnderConstruction( Object *objectUnderConstruction ); void populateOCLTimer( Object *creatorObject ); void doTransportInventoryUI( Object *transport, const CommandSet *commandSet ); static void populateInvDataCallback( Object *obj, void *userData ); // the following methods are for updating the currently showing context CommandAvailability getCommandAvailability( const CommandButton *command, Object *obj, GameWindow *win, Bool forceDisabledEvaluation = FALSE ) const; void updateContextMultiSelect( void ); void updateContextPurchaseScience( void ); void updateContextCommand( void ); void updateContextStructureInventory( void ); void updateContextBeacon( void ); void updateContextUnderConstruction( void ); void updateContextOCLTimer( void ); // the following methods are for the special power shortcut window void populateSpecialPowerShortcut( Player *player); void updateSpecialPowerShortcut( void ); static const Image* calculateVeterancyOverlayForThing( const ThingTemplate *thingTemplate ); static const Image* calculateVeterancyOverlayForObject( const Object *obj ); // the following methods do command processing for GUI selections CBCommandStatus processCommandUI( GameWindow *control, GadgetGameMessage gadgetMessage ); CBCommandStatus processCommandTransitionUI( GameWindow *control, GadgetGameMessage gadgetMessage ); // methods to help out with each context void updateConstructionTextDisplay( Object *obj ); void updateOCLTimerTextDisplay( UnsignedInt totalSeconds, Real percent ); void setUpDownImages( void ); // methods for flashing cameos public: void setFlash( Bool b ) { m_flash = b; } // get method for list of commandbuttons const CommandButton *getCommandButtons( void ) { return m_commandButtons; } protected: ICoord2D m_defaultControlBarPosition; ///< Stored the original position of the control bar on the screen ControlBarStages m_currentControlBarStage; Bool m_UIDirty; ///< the context UI must be re-evaluated CommandButton *m_commandButtons; ///< list of possible commands to have CommandSet *m_commandSets; ///< list of all command sets defined ControlBarSchemeManager *m_controlBarSchemeManager; ///< The Scheme singleton GameWindow *m_contextParent[ NUM_CONTEXT_PARENTS ]; ///< "parent" window for buttons that are part of the context sensitive interface Drawable *m_currentSelectedDrawable; ///< currently selected drawable for the context sensitive interface ControlBarContext m_currContext; ///< our current displayed context DrawableID m_rallyPointDrawableID; ///< rally point drawable for visual rally point Real m_displayedConstructPercent; ///< construct percent last displayed to user UnsignedInt m_displayedOCLTimerSeconds; ///< OCL Timer seconds remaining last displayed to user UnsignedInt m_displayedQueueCount; ///< queue count last displayed to user UnsignedInt m_lastRecordedInventoryCount; ///< last known UI state of an inventory count GameWindow *m_rightHUDWindow; ///< window of the right HUD display GameWindow *m_rightHUDCameoWindow; ///< window of the right HUD display GameWindow *m_rightHUDUpgradeCameos[MAX_RIGHT_HUD_UPGRADE_CAMEOS]; GameWindow *m_rightHUDUnitSelectParent; GameWindow *m_communicatorButton; ///< button for the communicator WindowLayout *m_scienceLayout; ///< the Science window layout GameWindow *m_sciencePurchaseWindowsRank1[ MAX_PURCHASE_SCIENCE_RANK_1 ]; ///< command window controls for easy access GameWindow *m_sciencePurchaseWindowsRank3[ MAX_PURCHASE_SCIENCE_RANK_3 ]; ///< command window controls for easy access GameWindow *m_sciencePurchaseWindowsRank8[ MAX_PURCHASE_SCIENCE_RANK_8 ]; ///< command window controls for easy access GameWindow *m_specialPowerShortcutButtons[ MAX_SPECIAL_POWER_SHORTCUTS ]; GameWindow *m_specialPowerShortcutButtonParents[ MAX_SPECIAL_POWER_SHORTCUTS ]; Int m_currentlyUsedSpecialPowersButtons; ///< Value will be <= MAX_SPECIAL_POWER_SHORTCUTS; WindowLayout *m_specialPowerLayout; GameWindow *m_specialPowerShortcutParent; GameWindow *m_commandWindows[ MAX_COMMANDS_PER_SET ]; ///< command window controls for easy access const CommandButton *m_commonCommands[ MAX_COMMANDS_PER_SET ]; ///< shared commands we will use for multi-selection // removed from multiplayer branch //GameWindow *m_commandMarkers[ MAX_COMMANDS_PER_SET ]; ///< When we don't have a command, they want to show an image // removed from multiplayer branch //void showCommandMarkers( void ); ///< function that compare's what's being shown in m_commandWindows and shows the ones that are hidden. public: // method for hiding communicator window CCB void hideCommunicator( Bool b ); protected: struct ContainEntry { GameWindow *control; ObjectID objectID; }; static ContainEntry m_containData[ MAX_COMMANDS_PER_SET ]; ///< inventory buttons integrated into the regular command set for buildings/transports struct QueueEntry { GameWindow *control; ///< window that the GUI control is tied to ProductionType type; ///< type of queue data union { ProductionID productionID; ///< production id for unit productions const UpgradeTemplate *upgradeToResearch; ///< upgrade template for upgrade productions }; }; QueueEntry m_queueData[ MAX_BUILD_QUEUE_BUTTONS ]; ///< what the build queue represents //cameo flash Bool m_flash; ///< tells update whether or not to check for flash Bool m_sideSelectAnimateDown; ICoord2D m_animateDownWin1Size; ICoord2D m_animateDownWin2Size; ICoord2D m_animateDownWin1Pos; ICoord2D m_animateDownWin2Pos; GameWindow *m_animateDownWindow; UnsignedInt m_animTime; Color m_buildUpClockColor; Bool m_isObserverCommandBar; ///< If this is true, the command bar behaves greatly differnt Player *m_observerLookAtPlayer; ///< The current player we're looking at, Null if we're not looking at anyone. WindowLayout *m_buildToolTipLayout; ///< The window that will slide on/display tooltips Bool m_showBuildToolTipLayout; ///< every frame we test to see if we aregoing to continue showing this or not. public: void showBuildTooltipLayout( GameWindow *cmdButton ); void hideBuildTooltipLayout( void ); void deleteBuildTooltipLayout( void ); Bool getShowBuildTooltipLayout( void ){return m_showBuildToolTipLayout; } void populateBuildTooltipLayout( const CommandButton *commandButton, GameWindow *tooltipWin = NULL ); void repopulateBuildTooltipLayout( void ); private: // Command Bar button border bars stuff Color m_commandButtonBorderBuildColor; Color m_commandButtonBorderActionColor; Color m_commandButtonBorderUpgradeColor; Color m_commandButtonBorderSystemColor; Color m_commandBarBorderColor; void setCommandBarBorder( GameWindow *button, CommandButtonMappedBorderType type); public: void updateCommanBarBorderColors(Color build, Color action, Color upgrade, Color system ); private: /// find existing command set CommandSet *findNonConstCommandSet( const AsciiString& name ); const Image *m_genStarOn; const Image *m_genStarOff; const Image *m_toggleButtonUpIn; const Image *m_toggleButtonUpOn; const Image *m_toggleButtonUpPushed; const Image *m_toggleButtonDownIn; const Image *m_toggleButtonDownOn; const Image *m_toggleButtonDownPushed; GameWindowTransitionsHandler *m_transitionHandler; const Image *m_genArrow; static const Image *m_rankVeteranIcon; static const Image *m_rankEliteIcon; static const Image *m_rankHeroicIcon; const Image *m_generalButtonEnable; const Image *m_generalButtonHighlight; Bool m_genStarFlash; Int m_lastFlashedAtPointValue; ICoord2D m_controlBarForegroundMarkerPos; ICoord2D m_controlBarBackgroundMarkerPos; Bool m_radarAttackGlowOn; Int m_remainingRadarAttackGlowFrames; GameWindow *m_radarAttackGlowWindow; // ControlBarResizer *m_controlBarResizer; }; // EXTERNALS ////////////////////////////////////////////////////////////////////////////////////// extern ControlBar *TheControlBar; #endif // end __CONTROLBAR_H_