| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- /*
- ** 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 <http://www.gnu.org/licenses/>.
- */
- ////////////////////////////////////////////////////////////////////////////////
- // //
- // (c) 2001-2003 Electronic Arts Inc. //
- // //
- ////////////////////////////////////////////////////////////////////////////////
- // FILE: ControlBarStructureInventory.cpp /////////////////////////////////////////////////////////
- // Author: Colin Day, March 2002
- // Desc: Methods specific to the control bar garrison display
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- // USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
- #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
- #include "Common/NameKeyGenerator.h"
- #include "Common/ThingTemplate.h"
- #include "Common/Player.h"
- #include "Common/PlayerList.h"
- #include "GameLogic/Object.h"
- #include "GameLogic/Module/OpenContain.h"
- #include "GameClient/InGameUI.h"
- #include "GameClient/Drawable.h"
- #include "GameClient/ControlBar.h"
- #include "GameClient/GameWindow.h"
- #include "GameClient/GameWindowManager.h"
- #include "GameClient/GadgetPushButton.h"
- #include "GameClient/Hotkey.h"
- #ifdef _INTERNAL
- // for occasional debugging...
- //#pragma optimize("", off)
- //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
- #endif
- #define STOP_ID 10
- #define EVACUATE_ID 11
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- struct PopulateButtonInfo
- {
- Object *source;
- Int buttonIndex;
- ControlBar* self;
- GameWindow** inventoryButtons;
- };
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- void ControlBar::populateButtonProc( Object *obj, void *userData )
- {
- PopulateButtonInfo* info = (PopulateButtonInfo*)userData;
- // sanity
- DEBUG_ASSERTCRASH( info->buttonIndex < MAX_STRUCTURE_INVENTORY_BUTTONS,
- ("Too many objects inside '%s' for the inventory buttons to hold",
- info->source->getTemplate()->getName().str()) );
- // put object in inventory data
- info->self->m_containData[ info->buttonIndex ].control = info->inventoryButtons[ info->buttonIndex ];
- info->self->m_containData[ info->buttonIndex ].objectID = obj->getID();
-
- // set the UI button that will allow us to press it and cause the object to exit the container
- const Image *image;
- image = obj->getTemplate()->getButtonImage();
- GadgetButtonSetEnabledImage( info->inventoryButtons[ info->buttonIndex ], image );
-
- //Show the auto-contained object's veterancy symbol!
- image = calculateVeterancyOverlayForObject( obj );
- GadgetButtonDrawOverlayImage( info->inventoryButtons[ info->buttonIndex ], image );
-
- // Enable the button
- info->inventoryButtons[ info->buttonIndex ]->winEnable( TRUE );
- // move to the next button index
- info->buttonIndex++;
- }
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- void ControlBar::populateStructureInventory( Object *building )
- {
- Int i;
- // reset the inventory data
- resetContainData();
- // reset hotkeys -- seeing it only is reset in switching contexts. This is a special case
- // because we are building the hotkeys on the fly sort of... and it changes as guys enter
- // and leave. Taking this call out will cause multiple hotkeys to be added.
- if(TheHotKeyManager)
- TheHotKeyManager->reset();
- // get the contain module of the object
- ContainModuleInterface *contain = building->getContain();
- DEBUG_ASSERTCRASH( contain, ("Object in structure inventory does not contain a Contain Module\n") );
- if (!contain)
- return;
- /// @todo srj -- remove hard-coding here, please
- const CommandButton *evacuateCommand = findCommandButton( "Command_Evacuate" );
- setControlCommand( m_commandWindows[ EVACUATE_ID ], evacuateCommand );
- m_commandWindows[ EVACUATE_ID ]->winEnable( FALSE );
- /// @todo srj -- remove hard-coding here, please
- const CommandButton *stopCommand = findCommandButton( "Command_Stop" );
- setControlCommand( m_commandWindows[ STOP_ID ], stopCommand );
- m_commandWindows[ STOP_ID ]->winEnable( FALSE );
- // get the inventory exit command to assign into the button
- /// @todo srj -- remove hard-coding here, please
- const CommandButton *exitCommand = findCommandButton( "Command_StructureExit" );
- // get window handles for each of the inventory buttons
- AsciiString windowName;
- for( i = 0; i < MAX_STRUCTURE_INVENTORY_BUTTONS; i++ )
- {
- // show the window
- m_commandWindows[ i ]->winHide( FALSE );
- //
- // disable the button for now, it will be enabled if there is something there
- // for its contents
- //
- m_commandWindows[ i ]->winEnable( FALSE );
- m_commandWindows[ i ]->winSetStatus( WIN_STATUS_ALWAYS_COLOR );
- m_commandWindows[ i ]->winClearStatus( WIN_STATUS_NOT_READY );
- // set an inventory command into the game window UI element
- setControlCommand( m_commandWindows[ i ], exitCommand );
- // Clear any veterancy icon incase the unit leaves!
- GadgetButtonDrawOverlayImage( m_commandWindows[ i ], NULL );
- //
- // if the structure can hold a lesser amount inside it than what the GUI displays
- // we will completely hide the buttons that can't contain anything
- //
- if( i + 1 > contain->getContainMax() )
- m_commandWindows[ i ]->winHide( TRUE );
- } // end for i
- // show the window
- m_commandWindows[ EVACUATE_ID ]->winHide( FALSE );
- m_commandWindows[ STOP_ID ]->winHide( FALSE );
- // if there is at least one item in there enable the evacuate and stop buttons
- if( contain->getContainCount() != 0 )
- {
- m_commandWindows[ EVACUATE_ID ]->winEnable( TRUE );
- m_commandWindows[ STOP_ID ]->winEnable( TRUE );
- }
- //
- // iterate each of the objects inside the container and put them in a button, note
- // we're iterating in reverse order here
- //
- PopulateButtonInfo info;
- info.source = building;
- info.buttonIndex = 0;
- info.self = this;
- info.inventoryButtons = m_commandWindows;
- contain->iterateContained(populateButtonProc, &info, FALSE );
- //
- // save how many items were contained by the object at this time so that we can update
- // it if they change in the future while selected
- //
- m_lastRecordedInventoryCount = contain->getContainCount();
- } // end populateStructureInventory
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- void ControlBar::updateContextStructureInventory( void )
- {
- Object *source = m_currentSelectedDrawable->getObject();
- //
- // we're visible, so there is something selected. It is possible that we had a building
- // selected that can be garrisoned, and while it was selected the enemy occupied it.
- // in that case we want to unselect the building so that we can't see the contents
- //
- Player *localPlayer = ThePlayerList->getLocalPlayer();
- if( source->isLocallyControlled() == FALSE &&
- localPlayer->getRelationship( source->getTeam() ) != NEUTRAL )
- {
- Drawable *draw = source->getDrawable();
- if( draw )
- TheInGameUI->deselectDrawable( draw );
- return;
- } // end if
- //
- // if the object being displayed in the interface has a different count than we last knew
- // about we need to repopulate the buttons of the interface
- //
- ContainModuleInterface *contain = source->getContain();
- DEBUG_ASSERTCRASH( contain, ("No contain module defined for object in the iventory bar\n") );
- if (!contain)
- return;
- if( m_lastRecordedInventoryCount != contain->getContainCount() )
- populateStructureInventory( source );
- } // end updateContextStructureInventory
|