diff --git a/Core/GameEngine/Include/GameClient/Mouse.h b/Core/GameEngine/Include/GameClient/Mouse.h index 849a933f37f..499ba4d4485 100644 --- a/Core/GameEngine/Include/GameClient/Mouse.h +++ b/Core/GameEngine/Include/GameClient/Mouse.h @@ -321,7 +321,9 @@ class Mouse : public SubsystemInterface void onGameModeChanged(GameMode prev, GameMode next); void onGamePaused(Bool paused); - Bool isClick(const ICoord2D *anchor, const ICoord2D *dest, UnsignedInt previousMouseClick, UnsignedInt currentMouseClick); + Bool isClick(const ICoord2D &mouseAnchor0, const ICoord2D &mouseAnchor1, UnsignedInt mouseClickTimeMs0, UnsignedInt mouseClickTimeMs1); + + Real getDragToleranceAdjustedForScrollFactor() const; AsciiString m_tooltipFontName; ///< tooltip font Int m_tooltipFontSize; ///< tooltip font diff --git a/Core/GameEngine/Include/GameClient/SelectionXlat.h b/Core/GameEngine/Include/GameClient/SelectionXlat.h index cdb6f56698b..bdeef4039d5 100644 --- a/Core/GameEngine/Include/GameClient/SelectionXlat.h +++ b/Core/GameEngine/Include/GameClient/SelectionXlat.h @@ -53,8 +53,6 @@ class SelectionTranslator : public GameMessageTranslator SelectCountMap m_selectCountMap; - Coord3D m_deselectDownCameraPosition; - Bool selectFriends( Drawable *draw, GameMessage *createTeamMsg, Bool dragSelecting ); Bool killThemKillThemAll( Drawable *draw, GameMessage *killThemAllMsg ); diff --git a/Core/GameEngine/Source/GameClient/Input/Mouse.cpp b/Core/GameEngine/Source/GameClient/Input/Mouse.cpp index a1c2cb97a4e..7114d899745 100644 --- a/Core/GameEngine/Source/GameClient/Input/Mouse.cpp +++ b/Core/GameEngine/Source/GameClient/Input/Mouse.cpp @@ -384,18 +384,19 @@ void Mouse::checkForDrag() //------------------------------------------------------------------------------------------------- /** Check for mouse click, using allowed drag forgiveness */ //------------------------------------------------------------------------------------------------- -Bool Mouse::isClick(const ICoord2D *anchor, const ICoord2D *dest, UnsignedInt previousMouseClick, UnsignedInt currentMouseClick) +Bool Mouse::isClick(const ICoord2D &mouseAnchor0, const ICoord2D &mouseAnchor1, UnsignedInt mouseClickTimeMs0, UnsignedInt mouseClickTimeMs1) { - ICoord2D delta; - delta.x = anchor->x - dest->x; - delta.y = anchor->y - dest->y; + const ICoord2D mouseAnchorDelta = mouseAnchor1 - mouseAnchor0; + const UnsignedInt timeMsDelta = mouseClickTimeMs1 - mouseClickTimeMs0; + // TheSuperHackers @bugfix Use the adjusted drag tolerance to prevent too far tolerances with high scroll factors, + // because higher scroll speeds will travel further by the delta. + const Real dragTolerance = getDragToleranceAdjustedForScrollFactor(); - // if the mouse hasn't moved further than the tolerance distance - // or the click took less than the tolerance duration - if ( abs(delta.x) > m_dragTolerance - || abs(delta.y) > m_dragTolerance - || currentMouseClick - previousMouseClick > m_dragToleranceMS) + // If the click took less than the tolerance duration + // or the mouse hasn't moved further than the tolerance distance + // TheSuperHackers @bugfix Now compares the distance in a circle instead of a rectangle. + if ( timeMsDelta > m_dragToleranceMS || mouseAnchorDelta.lengthSqr() > sqr(dragTolerance) ) { return FALSE; } @@ -403,6 +404,14 @@ Bool Mouse::isClick(const ICoord2D *anchor, const ICoord2D *dest, UnsignedInt pr } +//------------------------------------------------------------------------------------------------- +/** Get the scroll speed factor adjusted drag tolerance */ +//------------------------------------------------------------------------------------------------- +Real Mouse::getDragToleranceAdjustedForScrollFactor() const +{ + return m_dragTolerance * (TheGlobalData->m_keyboardDefaultScrollFactor / TheGlobalData->m_keyboardScrollFactor); +} + /////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC FUNCTIONS /////////////////////////////////////////////////////////////////////////////// diff --git a/Core/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp b/Core/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp index fa0d78a384f..6529e25d8c7 100644 --- a/Core/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp +++ b/Core/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp @@ -3884,7 +3884,7 @@ GameMessageDisposition CommandTranslator::translateGameMessage(const GameMessage //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_mouseRightDragAnchor, &m_mouseRightDragLift, m_mouseRightDown, m_mouseRightUp) ) + if( TheMouse->isClick(m_mouseRightDragAnchor, m_mouseRightDragLift, m_mouseRightDown, m_mouseRightUp) ) { TheInGameUI->placeBuildAvailable( nullptr, nullptr ); } @@ -3916,7 +3916,7 @@ 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_mouseRightDragAnchor, &m_mouseRightDragLift, m_mouseRightDown, m_mouseRightUp)) + && TheMouse->isClick(m_mouseRightDragAnchor, m_mouseRightDragLift, m_mouseRightDown, m_mouseRightUp)) { Bool isPoint = (msg->getArgument(0)->pixelRegion.height() == 0 && msg->getArgument(0)->pixelRegion.width() == 0); diff --git a/Core/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp b/Core/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp index caca08f832a..8c6519e2793 100644 --- a/Core/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp +++ b/Core/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp @@ -264,7 +264,6 @@ SelectionTranslator::SelectionTranslator() m_deselectFeedbackAnchor.x = 0; m_deselectFeedbackAnchor.y = 0; m_lastClick = 0; - m_deselectDownCameraPosition.zero(); m_displayedMaxWarning = FALSE; m_selectCountMap.clear(); @@ -942,13 +941,11 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa //----------------------------------------------------------------------------- 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_deselectFeedbackAnchor = msg->getArgument( 0 )->pixel; m_lastClick = (UnsignedInt) msg->getArgument( 2 )->integer; - m_deselectDownCameraPosition = TheTacticalView->getPosition(); break; } @@ -956,14 +953,11 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_RIGHT_BUTTON_UP: { - Coord3D cameraPos = TheTacticalView->getPosition(); - cameraPos.sub(&m_deselectDownCameraPosition); - ICoord2D pixel = msg->getArgument( 0 )->pixel; UnsignedInt currentTime = (UnsignedInt) msg->getArgument( 2 )->integer; // right click behavior (not right drag) - if (TheMouse->isClick(&m_deselectFeedbackAnchor, &pixel, m_lastClick, currentTime)) + if (TheMouse->isClick(m_deselectFeedbackAnchor, pixel, m_lastClick, currentTime)) { //Added support to cancel the GUI command without deselecting the unit(s) involved //when you right click. diff --git a/Core/Libraries/Include/Lib/BaseType.h b/Core/Libraries/Include/Lib/BaseType.h index 2cb718c9e27..a2de160cc1f 100644 --- a/Core/Libraries/Include/Lib/BaseType.h +++ b/Core/Libraries/Include/Lib/BaseType.h @@ -298,8 +298,55 @@ struct Coord2D Real toAngle() const; ///< turn 2D vector into angle (where angle 0 is down the +x axis) + void add( const Coord2D *a ) + { + x += a->x; + y += a->y; + } + + void sub( const Coord2D *a ) + { + x -= a->x; + y -= a->y; + } + + void operator+=(const Coord2D& a) + { + add(&a); + } + + void operator-=(const Coord2D& a) + { + sub(&a); + } + + void set( const Coord2D *a ) + { + x = a->x; + y = a->y; + } + + void set( Real ax, Real ay ) + { + x = ax; + y = ay; + } }; +inline Coord2D operator+(const Coord2D& a, const Coord2D& b) +{ + Coord2D c = a; + c.add(&b); + return c; +} + +inline Coord2D operator-(const Coord2D& a, const Coord2D& b) +{ + Coord2D c = a; + c.sub(&b); + return c; +} + inline Real Coord2D::toAngle() const { #if RTS_GENERALS /*&& RETAIL_COMPATIBLE_CRC*/ @@ -376,8 +423,57 @@ struct ICoord2D } Int length() const { return (Int)sqrt( (double)(x*x + y*y) ); } + Real lengthSqr() const { return x*x + y*y; } + + void add( const ICoord2D *a ) + { + x += a->x; + y += a->y; + } + + void sub( const ICoord2D *a ) + { + x -= a->x; + y -= a->y; + } + + void operator+=(const ICoord2D& a) + { + add(&a); + } + + void operator-=(const ICoord2D& a) + { + sub(&a); + } + + void set( const ICoord2D *a ) + { + x = a->x; + y = a->y; + } + + void set( Int ax, Int ay ) + { + x = ax; + y = ay; + } }; +inline ICoord2D operator+(const ICoord2D& a, const ICoord2D& b) +{ + ICoord2D c = a; + c.add(&b); + return c; +} + +inline ICoord2D operator-(const ICoord2D& a, const ICoord2D& b) +{ + ICoord2D c = a; + c.sub(&b); + return c; +} + struct Region2D { Coord2D lo, hi; // bounds of 2D rectangular region @@ -471,6 +567,16 @@ struct Coord3D z -= a->z; } + void operator+=(const Coord3D& a) + { + add(&a); + } + + void operator-=(const Coord3D& a) + { + sub(&a); + } + void set( const Coord3D *a ) { x = a->x; @@ -507,6 +613,20 @@ struct Coord3D } }; +inline Coord3D operator+(const Coord3D& a, const Coord3D& b) +{ + Coord3D c = a; + c.add(&b); + return c; +} + +inline Coord3D operator-(const Coord3D& a, const Coord3D& b) +{ + Coord3D c = a; + c.sub(&b); + return c; +} + struct ICoord3D { Int x, y, z; @@ -524,8 +644,60 @@ struct ICoord3D { return x == value && y == value && z == value; } + + void add( const ICoord3D *a ) + { + x += a->x; + y += a->y; + z += a->z; + } + + void sub( const ICoord3D *a ) + { + x -= a->x; + y -= a->y; + z -= a->z; + } + + void operator+=(const ICoord3D& a) + { + add(&a); + } + + void operator-=(const ICoord3D& a) + { + sub(&a); + } + + void set( const ICoord3D *a ) + { + x = a->x; + y = a->y; + z = a->z; + } + + void set( Int ax, Int ay, Int az ) + { + x = ax; + y = ay; + z = az; + } }; +inline ICoord3D operator+(const ICoord3D& a, const ICoord3D& b) +{ + ICoord3D c = a; + c.add(&b); + return c; +} + +inline ICoord3D operator-(const ICoord3D& a, const ICoord3D& b) +{ + ICoord3D c = a; + c.sub(&b); + return c; +} + // For alternative see AABoxClass struct Region3D {