diff --git a/Generals/Code/GameEngine/Include/Common/BuildAssistant.h b/Generals/Code/GameEngine/Include/Common/BuildAssistant.h index b9f49b03470..e3e414408dd 100644 --- a/Generals/Code/GameEngine/Include/Common/BuildAssistant.h +++ b/Generals/Code/GameEngine/Include/Common/BuildAssistant.h @@ -92,6 +92,7 @@ enum LegalBuildCode CPP_11(: Int) LBC_NO_CLEAR_PATH, LBC_SHROUD, LBC_TOO_CLOSE_TO_SUPPLIES, + LBC_GENERIC_FAILURE, }; //------------------------------------------------------------------------------------------------- @@ -109,12 +110,14 @@ class BuildAssistant : public SubsystemInterface enum LocalLegalToBuildOptions { - TERRAIN_RESTRICTIONS = 0x00000001, ///< Check for basic terrain restrictions - CLEAR_PATH = 0x00000002, ///< Must be able to path find to location - NO_OBJECT_OVERLAP = 0X00000004, ///< Can't overlap enemy objects, or locally controlled objects that can't move out of the way - USE_QUICK_PATHFIND = 0x00000008, ///< Use the quick pathfind method for CLEAR_PATH - SHROUD_REVEALED = 0x00000010, ///< Check to make sure the shroud is revealed - NO_ENEMY_OBJECT_OVERLAP=0x00000020, ///< Can't overlap enemy objects only. + TERRAIN_RESTRICTIONS = 0x00000001, ///< Check for basic terrain restrictions + CLEAR_PATH = 0x00000002, ///< Must be able to path find to location + NO_OBJECT_OVERLAP = 0X00000004, ///< Can't overlap enemy objects, or locally controlled objects that can't move out of the way + USE_QUICK_PATHFIND = 0x00000008, ///< Use the quick pathfind method for CLEAR_PATH + SHROUD_REVEALED = 0x00000010, ///< Check to make sure the shroud is revealed + NO_ENEMY_OBJECT_OVERLAP = 0x00000020, ///< Can't overlap enemy objects only. + IGNORE_STEALTHED = 0x00000040, ///< Units that we can't see are legal to "build" on. (when moving mouse around) + FAIL_STEALTHED_WITHOUT_FEEDBACK = 0x00000080 ///< USE WITH IGNORE_STEALTHED except it will fail without BIB feedback (when clicking to place). }; public: diff --git a/Generals/Code/GameEngine/Source/GameClient/MessageStream/GUICommandTranslator.cpp b/Generals/Code/GameEngine/Source/GameClient/MessageStream/GUICommandTranslator.cpp index 3fa40e099fe..3ae17884275 100644 --- a/Generals/Code/GameEngine/Source/GameClient/MessageStream/GUICommandTranslator.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/MessageStream/GUICommandTranslator.cpp @@ -451,7 +451,7 @@ GameMessageDisposition GUICommandTranslator::translateGameMessage(const GameMess //Special weapons are now always context commands... //--------------------------------------------------------------------------------------- case GUI_COMMAND_SPECIAL_POWER: - case GUI_COMMAND_SPECIAL_POWER_FROM_COMMAND_CENTER: + case GUI_COMMAND_SPECIAL_POWER_FROM_SHORTCUT: { return KEEP_MESSAGE; break; diff --git a/Generals/Code/GameEngine/Source/GameClient/MessageStream/HintSpy.cpp b/Generals/Code/GameEngine/Source/GameClient/MessageStream/HintSpy.cpp index 37174941ebb..10eb2016a0d 100644 --- a/Generals/Code/GameEngine/Source/GameClient/MessageStream/HintSpy.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/MessageStream/HintSpy.cpp @@ -78,6 +78,7 @@ GameMessageDisposition HintSpyTranslator::translateGameMessage(const GameMessage case GameMessage::MSG_RESUME_CONSTRUCTION_HINT: case GameMessage::MSG_ENTER_HINT: case GameMessage::MSG_HIJACK_HINT: + case GameMessage::MSG_SABOTAGE_HINT: case GameMessage::MSG_CONVERT_TO_CARBOMB_HINT: #ifdef ALLOW_SURRENDER case GameMessage::MSG_PICK_UP_PRISONER_HINT: diff --git a/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp b/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp index 1b7109eac99..55fae085a7b 100644 --- a/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp @@ -261,8 +261,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage m_anchor = msg->getArgument( 0 )->pixel; m_currentPos = msg->getArgument( 0 )->pixel; - // disable mouse scrolling in alternate mouse mode, per Harvard 7/15/03 - if (!TheGlobalData->m_useAlternateMouse && !TheInGameUI->isSelecting() && !m_isScrolling) + if (!TheInGameUI->isSelecting() && !m_isScrolling) { setScrolling(SCROLL_RMB); } @@ -611,6 +610,18 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage } #endif // #if defined(RTS_DEBUG) + // ------------------------------------------------------------------------ +#if defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE) + case GameMessage::MSG_CHEAT_DESHROUD: + { + if (!TheGameLogic->isInMultiplayerGame()) + { + ThePartitionManager->revealMapForPlayerPermanently( ThePlayerList->getLocalPlayer()->getPlayerIndex() ); + } + break; + } +#endif // #if defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE) + // ------------------------------------------------------------------------ #if defined(RTS_DEBUG) case GameMessage::MSG_META_DEMO_ENSHROUD: @@ -626,7 +637,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage #if defined(RTS_DEBUG) case GameMessage::MSG_META_DEMO_BEGIN_ADJUST_FOV: { - DEBUG_ASSERTCRASH(!m_isChangingFOV, ("hmm, mismatched m_isChangingFOV")); + //DEBUG_ASSERTCRASH(!m_isChangingFOV, ("hmm, mismatched m_isChangingFOV")); m_isChangingFOV = true; m_anchor = m_currentPos; disp = DESTROY_MESSAGE; @@ -638,7 +649,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage #if defined(RTS_DEBUG) case GameMessage::MSG_META_DEMO_END_ADJUST_FOV: { - DEBUG_ASSERTCRASH(m_isChangingFOV, ("hmm, mismatched m_isChangingFOV")); + // DEBUG_ASSERTCRASH(m_isChangingFOV, ("hmm, mismatched m_isChangingFOV")); m_isChangingFOV = false; disp = DESTROY_MESSAGE; break; diff --git a/Generals/Code/GameEngine/Source/GameClient/MessageStream/PlaceEventTranslator.cpp b/Generals/Code/GameEngine/Source/GameClient/MessageStream/PlaceEventTranslator.cpp index 28ac68051b2..142af157c40 100644 --- a/Generals/Code/GameEngine/Source/GameClient/MessageStream/PlaceEventTranslator.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/MessageStream/PlaceEventTranslator.cpp @@ -27,19 +27,25 @@ #include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine +#include "Common/BuildAssistant.h" #include "Common/GameAudio.h" #include "Common/Player.h" #include "Common/PlayerList.h" +#include "Common/SpecialPower.h" #include "Common/ThingTemplate.h" -#include "Common/BuildAssistant.h" - -#include "GameLogic/Object.h" -#include "GameLogic/GameLogic.h" #include "GameClient/CommandXlat.h" -#include "GameClient/PlaceEventTranslator.h" +#include "GameClient/ControlBar.h" #include "GameClient/Drawable.h" #include "GameClient/Eva.h" +#include "GameClient/PlaceEventTranslator.h" + +#include "GameLogic/GameLogic.h" +#include "GameLogic/Object.h" + +#include "GameLogic/Module/ProductionUpdate.h" + + //------------------------------------------------------------------------------------------------- PlaceEventTranslator::PlaceEventTranslator() : m_frameOfUpButton(-1) @@ -218,13 +224,42 @@ GameMessageDisposition PlaceEventTranslator::translateGameMessage(const GameMess BuildAssistant::TERRAIN_RESTRICTIONS | BuildAssistant::CLEAR_PATH | BuildAssistant::NO_OBJECT_OVERLAP | - BuildAssistant::SHROUD_REVEALED, + BuildAssistant::SHROUD_REVEALED | + BuildAssistant::IGNORE_STEALTHED | + BuildAssistant::FAIL_STEALTHED_WITHOUT_FEEDBACK, builderObj, nullptr ); if( lbc == LBC_OK ) { - - /** @todo Do not send local player id as argument once we have player ids - tied into all messages automatically */ + //Are we building this structure via the special power system? (special case for sneak attack) + if( builderObj ) + { + ProductionUpdateInterface *puInterface = builderObj->getProductionUpdateInterface(); + if( puInterface ) + { + const CommandButton *commandButton = puInterface->getSpecialPowerConstructionCommandButton(); + if( commandButton ) + { + //If we get this far, then we aren't going to really build the object using the production update + //interface. Instead, we're going to trigger the special power to create it magically without a + //dozer/worker. + placeMsg = TheMessageStream->appendMessage( GameMessage::MSG_DO_SPECIAL_POWER_AT_LOCATION ); + placeMsg->appendIntegerArgument( commandButton->getSpecialPowerTemplate()->getID() ); //The ID of the special power template. + placeMsg->appendLocationArgument( world ); //Position of special to be fired. + placeMsg->appendRealArgument( angle ); //Angle of special to be fired. + placeMsg->appendObjectIDArgument( INVALID_ID ); //There is no object in the way. + placeMsg->appendIntegerArgument( commandButton->getOptions() ); //Command button options. + placeMsg->appendObjectIDArgument( builderObj->getID() ); //The source object responsible for firing the special. + + // get out of pending placement mode, this will also clear the arrow anchor status + TheInGameUI->placeBuildAvailable( nullptr, nullptr ); + + // used the input + disp = DESTROY_MESSAGE; + m_frameOfUpButton = TheGameLogic->getFrame(); + break; + } + } + } // create the right kind of message if( isLineBuild ) diff --git a/Generals/Code/GameEngine/Source/GameClient/MessageStream/WindowXlat.cpp b/Generals/Code/GameEngine/Source/GameClient/MessageStream/WindowXlat.cpp index 863b1da61b9..9c790c3ab79 100644 --- a/Generals/Code/GameEngine/Source/GameClient/MessageStream/WindowXlat.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/MessageStream/WindowXlat.cpp @@ -173,7 +173,25 @@ GameMessageDisposition WindowTranslator::translateGameMessage(const GameMessage if (TheTacticalView && TheTacticalView->isMouseLocked()) { - return KEEP_MESSAGE; + //Kris: Aug 15, 2003 + //Added the scrolling check that will not return KEEP_MESSAGE if we happen + //to in scrolling mode (via keyboard or mouse) and left click in the controlbar. + //Without this code, the left click goes through the interface ignoring buttons and blockage + //and ends up issuing orders right through the controlbar! + if( TheInGameUI->isScrolling() ) + { + if( msg->getType() != GameMessage::MSG_RAW_MOUSE_LEFT_BUTTON_UP && + msg->getType() != GameMessage::MSG_RAW_MOUSE_LEFT_BUTTON_DOWN ) + { + //We're scrolling, but unless we're clicking the left button, get out. + return KEEP_MESSAGE; + } + //Pass through and handle button clicks or getting input blocked! + } + else + { + return KEEP_MESSAGE; + } } switch( msg->getType() )