From 2c51f51e6f2d955e0a3de83b7b4e674a5935f3f0 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Tue, 30 Jun 2026 19:41:20 +0200 Subject: [PATCH] bugfix(commandxlat): Re-enable right mouse click move commands during camera scrolling --- .../Include/GameClient/CommandXlat.h | 2 - Core/GameEngine/Include/GameClient/Mouse.h | 13 +++++-- .../Source/GameClient/Input/Mouse.cpp | 37 ++++++++++++++----- .../GameClient/MessageStream/CommandXlat.cpp | 17 +++------ .../MessageStream/SelectionXlat.cpp | 5 ++- 5 files changed, 47 insertions(+), 27 deletions(-) diff --git a/Core/GameEngine/Include/GameClient/CommandXlat.h b/Core/GameEngine/Include/GameClient/CommandXlat.h index db988f8150d..8c861646e62 100644 --- a/Core/GameEngine/Include/GameClient/CommandXlat.h +++ b/Core/GameEngine/Include/GameClient/CommandXlat.h @@ -55,8 +55,6 @@ class CommandTranslator : public GameMessageTranslator ICoord2D m_rightMouseUpAnchor; // the location of a possible mouse drag end UnsignedInt m_rightMouseDownTimeMs; // when the mouse down happened UnsignedInt m_rightMouseUpTimeMs; // when the mouse up happened - Coord3D m_rightMouseDownCameraPos; - Coord3D m_rightMouseUpCameraPos; GameMessage::Type createMoveToLocationMessage( Drawable *draw, const Coord3D *dest, CommandEvaluateType commandType ); GameMessage::Type createAttackMessage( Drawable *draw, Drawable *other, CommandEvaluateType commandType ); diff --git a/Core/GameEngine/Include/GameClient/Mouse.h b/Core/GameEngine/Include/GameClient/Mouse.h index 19e00fc3730..63efd1f991d 100644 --- a/Core/GameEngine/Include/GameClient/Mouse.h +++ b/Core/GameEngine/Include/GameClient/Mouse.h @@ -322,12 +322,19 @@ class Mouse : public SubsystemInterface void onGamePaused(Bool paused); Bool isClick( + UnsignedInt mouseClickTimeMs0, + UnsignedInt mouseClickTimeMs1, + const ICoord2D &mouseAnchor0, + const ICoord2D &mouseAnchor1 + ); + + Bool isClick( + UnsignedInt mouseClickTimeMs0, + UnsignedInt mouseClickTimeMs1, const ICoord2D &mouseAnchor0, const ICoord2D &mouseAnchor1, const Coord3D &cameraPos0, - const Coord3D &cameraPos1, - UnsignedInt mouseClickTimeMs0, - UnsignedInt mouseClickTimeMs1 + const Coord3D &cameraPos1 ); AsciiString m_tooltipFontName; ///< tooltip font diff --git a/Core/GameEngine/Source/GameClient/Input/Mouse.cpp b/Core/GameEngine/Source/GameClient/Input/Mouse.cpp index 92241385981..0251facecc1 100644 --- a/Core/GameEngine/Source/GameClient/Input/Mouse.cpp +++ b/Core/GameEngine/Source/GameClient/Input/Mouse.cpp @@ -385,29 +385,48 @@ void Mouse::checkForDrag() /** Check for mouse click, using allowed drag forgiveness */ //------------------------------------------------------------------------------------------------- Bool Mouse::isClick( - const ICoord2D &mouseAnchor0, - const ICoord2D &mouseAnchor1, - const Coord3D &cameraPos0, - const Coord3D &cameraPos1, UnsignedInt mouseClickTimeMs0, - UnsignedInt mouseClickTimeMs1) + UnsignedInt mouseClickTimeMs1, + const ICoord2D &mouseAnchor0, + const ICoord2D &mouseAnchor1) { const ICoord2D mouseAnchorDelta = mouseAnchor1 - mouseAnchor0; - const Coord3D cameraPosDelta = cameraPos1 - cameraPos0; const UnsignedInt timeMsDelta = mouseClickTimeMs1 - mouseClickTimeMs0; // if the mouse hasn't moved further than the tolerance distance // or the click took less than the tolerance duration // TheSuperHackers @bugfix Now compares the distance in a circle instead of a rectangle. - if ( timeMsDelta > m_dragToleranceMS - || mouseAnchorDelta.lengthSqr() > sqr(m_dragTolerance) - || cameraPosDelta.lengthSqr() > sqr(m_dragTolerance3D) ) + if ( timeMsDelta > m_dragToleranceMS || mouseAnchorDelta.lengthSqr() > sqr(m_dragTolerance) ) { return FALSE; } return TRUE; } +//------------------------------------------------------------------------------------------------- +/** Check for mouse click with 3d drag tolerance, using allowed drag forgiveness */ +//------------------------------------------------------------------------------------------------- +Bool Mouse::isClick( + UnsignedInt mouseClickTimeMs0, + UnsignedInt mouseClickTimeMs1, + const ICoord2D &mouseAnchor0, + const ICoord2D &mouseAnchor1, + const Coord3D &cameraPos0, + const Coord3D &cameraPos1) +{ + if ( !isClick(mouseClickTimeMs0, mouseClickTimeMs1, mouseAnchor0, mouseAnchor1) ) + { + return FALSE; + } + + const Coord3D cameraPosDelta = cameraPos1 - cameraPos0; + + if ( cameraPosDelta.lengthSqr() > sqr(m_dragTolerance3D) ) + { + return FALSE; + } + return TRUE; +} /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Core/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp b/Core/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp index 7b6335f5920..966945dd559 100644 --- a/Core/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp +++ b/Core/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp @@ -1450,8 +1450,6 @@ CommandTranslator::CommandTranslator() : { m_rightMouseDownAnchor.zero(); m_rightMouseUpAnchor.zero(); - m_rightMouseDownCameraPos.zero(); - m_rightMouseUpCameraPos.zero(); } //==================================================================================== @@ -3864,13 +3862,11 @@ GameMessageDisposition CommandTranslator::translateGameMessage(const GameMessage case GameMessage::MSG_RAW_MOUSE_RIGHT_DOUBLE_CLICK: case GameMessage::MSG_RAW_MOUSE_RIGHT_BUTTON_DOWN: { - // There are three ways in which we can ignore this as a deselect: + // There are two ways in which we can ignore this as a deselect: // 1) 2-D position on screen // 2) Time has exceeded the time which we allow for this to be a click. - // 3) 3-D camera position has changed m_rightMouseDownAnchor = msg->getArgument( 0 )->pixel; m_rightMouseDownTimeMs = (UnsignedInt) msg->getArgument( 2 )->integer; - m_rightMouseDownCameraPos = TheTacticalView->getPosition(); break; } @@ -3881,16 +3877,14 @@ GameMessageDisposition CommandTranslator::translateGameMessage(const GameMessage // register this event for determining if the click was fast or short enough not to be a drag m_rightMouseUpAnchor = msg->getArgument( 0 )->pixel; m_rightMouseUpTimeMs = (UnsignedInt) msg->getArgument( 2 )->integer; - m_rightMouseUpCameraPos = TheTacticalView->getPosition(); //Kris: July 7, 2003. Added this code to deselect build placement mode when right clicked. This fixes //a bug where you couldn't cancel the sneak attack mode via right click. This only happened when you //didn't have anything selected which is possible via the shortcut bar. Normally, it would get deselected //via the deselect drawable code. if( TheMouse->isClick( - m_rightMouseDownAnchor, m_rightMouseUpAnchor, - m_rightMouseDownCameraPos, m_rightMouseUpCameraPos, - m_rightMouseDownTimeMs, m_rightMouseUpTimeMs) ) + m_rightMouseDownTimeMs, m_rightMouseUpTimeMs, + m_rightMouseDownAnchor, m_rightMouseUpAnchor) ) { TheInGameUI->placeBuildAvailable( nullptr, nullptr ); } @@ -3925,9 +3919,8 @@ GameMessageDisposition CommandTranslator::translateGameMessage(const GameMessage // right click is only actioned here if we're in alternate mouse mode if (TheGlobalData->m_useAlternateMouse && TheMouse->isClick( - m_rightMouseDownAnchor, m_rightMouseUpAnchor, - m_rightMouseDownCameraPos, m_rightMouseUpCameraPos, - m_rightMouseDownTimeMs, m_rightMouseUpTimeMs)) + m_rightMouseDownTimeMs, m_rightMouseUpTimeMs, + m_rightMouseDownAnchor, m_rightMouseUpAnchor)) { // NOTE: RIGHT_CLICK is not transmitted if AREA_SELECTION or DRAWABLE_PICKED occurs. // If we see this msg, no object was clicked on, therefore clicked on ground. diff --git a/Core/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp b/Core/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp index 32756e70f4b..d6216c00151 100644 --- a/Core/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp +++ b/Core/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp @@ -1099,7 +1099,10 @@ GameMessageDisposition SelectionTranslator::onRawMouseRightButtonUp(MAYBE_UNUSED const Coord3D cameraPos = TheTacticalView->getPosition(); // right click behavior (not right drag) - if (TheMouse->isClick(m_rightMouseDownAnchor, anchor, m_rightMouseDownCameraPos, cameraPos, m_rightMouseDownTimeMs, timeMs)) + if (TheMouse->isClick( + m_rightMouseDownTimeMs, timeMs, + m_rightMouseDownAnchor, anchor, + m_rightMouseDownCameraPos, cameraPos)) { //Added support to cancel the GUI command without deselecting the unit(s) involved //when you right click.