Skip to content

Commit 8ca8f81

Browse files
committed
bugfix(mouse): Fix bad drag tolerances with high scroll speed factors (#2823)
1 parent b103a26 commit 8ca8f81

5 files changed

Lines changed: 25 additions & 22 deletions

File tree

Core/GameEngine/Include/GameClient/Mouse.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,9 @@ class Mouse : public SubsystemInterface
321321
void onGameModeChanged(GameMode prev, GameMode next);
322322
void onGamePaused(Bool paused);
323323

324-
Bool isClick(const ICoord2D *anchor, const ICoord2D *dest, UnsignedInt previousMouseClick, UnsignedInt currentMouseClick);
324+
Bool isClick(const ICoord2D &mouseAnchor0, const ICoord2D &mouseAnchor1, UnsignedInt mouseClickTimeMs0, UnsignedInt mouseClickTimeMs1);
325+
326+
Real getDragToleranceAdjustedForScrollFactor() const;
325327

326328
AsciiString m_tooltipFontName; ///< tooltip font
327329
Int m_tooltipFontSize; ///< tooltip font

Core/GameEngine/Include/GameClient/SelectionXlat.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ class SelectionTranslator : public GameMessageTranslator
5353

5454
SelectCountMap m_selectCountMap;
5555

56-
Coord3D m_deselectDownCameraPosition;
57-
5856
Bool selectFriends( Drawable *draw, GameMessage *createTeamMsg, Bool dragSelecting );
5957
Bool killThemKillThemAll( Drawable *draw, GameMessage *killThemAllMsg );
6058

Core/GameEngine/Source/GameClient/Input/Mouse.cpp

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -384,25 +384,34 @@ void Mouse::checkForDrag()
384384
//-------------------------------------------------------------------------------------------------
385385
/** Check for mouse click, using allowed drag forgiveness */
386386
//-------------------------------------------------------------------------------------------------
387-
Bool Mouse::isClick(const ICoord2D *anchor, const ICoord2D *dest, UnsignedInt previousMouseClick, UnsignedInt currentMouseClick)
387+
Bool Mouse::isClick(const ICoord2D &mouseAnchor0, const ICoord2D &mouseAnchor1, UnsignedInt mouseClickTimeMs0, UnsignedInt mouseClickTimeMs1)
388388
{
389-
ICoord2D delta;
390-
delta.x = anchor->x - dest->x;
391-
delta.y = anchor->y - dest->y;
389+
const ICoord2D mouseAnchorDelta = mouseAnchor1 - mouseAnchor0;
390+
const UnsignedInt timeMsDelta = mouseClickTimeMs1 - mouseClickTimeMs0;
392391

392+
// TheSuperHackers @bugfix Use the adjusted drag tolerance to prevent too far tolerances with high scroll factors,
393+
// because higher scroll speeds will travel further by the delta.
394+
const Real dragTolerance = getDragToleranceAdjustedForScrollFactor();
393395

394-
// if the mouse hasn't moved further than the tolerance distance
395-
// or the click took less than the tolerance duration
396-
if ( abs(delta.x) > m_dragTolerance
397-
|| abs(delta.y) > m_dragTolerance
398-
|| currentMouseClick - previousMouseClick > m_dragToleranceMS)
396+
// If the click took less than the tolerance duration
397+
// or the mouse hasn't moved further than the tolerance distance
398+
// TheSuperHackers @bugfix Now compares the distance in a circle instead of a rectangle.
399+
if ( timeMsDelta > m_dragToleranceMS || mouseAnchorDelta.lengthSqr() > sqr(m_dragTolerance) )
399400
{
400401
return FALSE;
401402
}
402403
return TRUE;
403404
}
404405

405406

407+
//-------------------------------------------------------------------------------------------------
408+
/** Get the scroll speed factor adjusted drag tolerance */
409+
//-------------------------------------------------------------------------------------------------
410+
Real Mouse::getDragToleranceAdjustedForScrollFactor() const
411+
{
412+
return m_dragTolerance * (TheGlobalData->m_keyboardDefaultScrollFactor / TheGlobalData->m_keyboardScrollFactor);
413+
}
414+
406415

407416
///////////////////////////////////////////////////////////////////////////////////////////////////
408417
// PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////////////////////////

Core/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3884,7 +3884,7 @@ GameMessageDisposition CommandTranslator::translateGameMessage(const GameMessage
38843884
//a bug where you couldn't cancel the sneak attack mode via right click. This only happened when you
38853885
//didn't have anything selected which is possible via the shortcut bar. Normally, it would get deselected
38863886
//via the deselect drawable code.
3887-
if( TheMouse->isClick(&m_mouseRightDragAnchor, &m_mouseRightDragLift, m_mouseRightDown, m_mouseRightUp) )
3887+
if( TheMouse->isClick(m_mouseRightDragAnchor, m_mouseRightDragLift, m_mouseRightDown, m_mouseRightUp) )
38883888
{
38893889
TheInGameUI->placeBuildAvailable( nullptr, nullptr );
38903890
}
@@ -3916,7 +3916,7 @@ GameMessageDisposition CommandTranslator::translateGameMessage(const GameMessage
39163916
{
39173917
// right click is only actioned here if we're in alternate mouse mode
39183918
if (TheGlobalData->m_useAlternateMouse
3919-
&& TheMouse->isClick(&m_mouseRightDragAnchor, &m_mouseRightDragLift, m_mouseRightDown, m_mouseRightUp))
3919+
&& TheMouse->isClick(m_mouseRightDragAnchor, m_mouseRightDragLift, m_mouseRightDown, m_mouseRightUp))
39203920
{
39213921
Bool isPoint = (msg->getArgument(0)->pixelRegion.height() == 0 && msg->getArgument(0)->pixelRegion.width() == 0);
39223922

Core/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,6 @@ SelectionTranslator::SelectionTranslator()
264264
m_deselectFeedbackAnchor.x = 0;
265265
m_deselectFeedbackAnchor.y = 0;
266266
m_lastClick = 0;
267-
m_deselectDownCameraPosition.zero();
268267
m_displayedMaxWarning = FALSE;
269268
m_selectCountMap.clear();
270269

@@ -942,28 +941,23 @@ GameMessageDisposition SelectionTranslator::translateGameMessage(const GameMessa
942941
//-----------------------------------------------------------------------------
943942
case GameMessage::MSG_RAW_MOUSE_RIGHT_BUTTON_DOWN:
944943
{
945-
// There are three ways in which we can ignore this as a deselect:
944+
// There are two ways in which we can ignore this as a deselect:
946945
// 1) 2-D position on screen
947946
// 2) Time has exceeded the time which we allow for this to be a click.
948-
// 3) 3-D camera position has changed
949947
m_deselectFeedbackAnchor = msg->getArgument( 0 )->pixel;
950948
m_lastClick = (UnsignedInt) msg->getArgument( 2 )->integer;
951-
m_deselectDownCameraPosition = TheTacticalView->getPosition();
952949

953950
break;
954951
}
955952

956953
//-----------------------------------------------------------------------------
957954
case GameMessage::MSG_RAW_MOUSE_RIGHT_BUTTON_UP:
958955
{
959-
Coord3D cameraPos = TheTacticalView->getPosition();
960-
cameraPos.sub(&m_deselectDownCameraPosition);
961-
962956
ICoord2D pixel = msg->getArgument( 0 )->pixel;
963957
UnsignedInt currentTime = (UnsignedInt) msg->getArgument( 2 )->integer;
964958

965959
// right click behavior (not right drag)
966-
if (TheMouse->isClick(&m_deselectFeedbackAnchor, &pixel, m_lastClick, currentTime))
960+
if (TheMouse->isClick(m_deselectFeedbackAnchor, pixel, m_lastClick, currentTime))
967961
{
968962
//Added support to cancel the GUI command without deselecting the unit(s) involved
969963
//when you right click.

0 commit comments

Comments
 (0)