Suppress right-click game interactions during free camera orbit (#12)

* Suppress right-click game interactions during free camera orbit

Rename IsTouchInputSuppressed to IsThirdPersonCameraActive and simplify
to return TRUE whenever the 3rd person camera is active. Use this in
ProcessOneEvent to skip right-click-only events, preventing accidental
game object interactions while orbiting the free camera.

https://claude.ai/code/session_01KuQtP2prfbVho2myKZ2pxE

* Move touch suppression logic into HandleTouchInput extension hook

Instead of checking IsThirdPersonCameraActive (which suppressed all
touch input whenever the camera was active), add a dedicated
HandleTouchInput hook that only suppresses touch input during active
multi-touch camera gestures. Move g_finger static into LegoInputManager
as m_touchFinger and grant friend access to MultiplayerExt so the
extension can manipulate touch state directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
foxtacles 2026-03-09 17:31:32 -07:00 committed by GitHub
parent fe5ef4f9a5
commit 04730bcc97
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 47 additions and 18 deletions

View File

@ -26,6 +26,11 @@ class LegoCameraController;
class LegoControlManager; class LegoControlManager;
class LegoWorld; class LegoWorld;
namespace Extensions
{
class MultiplayerExt;
}
extern MxS32 g_clickedObjectId; extern MxS32 g_clickedObjectId;
extern const char* g_clickedAtom; extern const char* g_clickedAtom;
@ -178,6 +183,8 @@ class LegoInputManager : public MxPresenter {
// SYNTHETIC: LEGO1 0x1005b8d0 // SYNTHETIC: LEGO1 0x1005b8d0
// LegoInputManager::`scalar deleting destructor' // LegoInputManager::`scalar deleting destructor'
friend class Extensions::MultiplayerExt;
private: private:
void InitializeHaptics(); void InitializeHaptics();
@ -204,6 +211,7 @@ class LegoInputManager : public MxPresenter {
TouchScheme m_touchScheme = e_none; TouchScheme m_touchScheme = e_none;
SDL_Point m_touchVirtualThumb = {0, 0}; SDL_Point m_touchVirtualThumb = {0, 0};
SDL_FPoint m_touchVirtualThumbOrigin; SDL_FPoint m_touchVirtualThumbOrigin;
SDL_FingerID m_touchFinger = 0;
std::map<SDL_FingerID, MxU32> m_touchFlags; std::map<SDL_FingerID, MxU32> m_touchFlags;
std::map<SDL_KeyboardID, std::pair<void*, void*>> m_keyboards; std::map<SDL_KeyboardID, std::pair<void*, void*>> m_keyboards;
std::map<SDL_MouseID, std::pair<void*, SDL_Haptic*>> m_mice; std::map<SDL_MouseID, std::pair<void*, SDL_Haptic*>> m_mice;

View File

@ -323,6 +323,12 @@ MxBool LegoInputManager::ProcessOneEvent(LegoEventNotificationParam& p_param)
} }
else { else {
if (!Lego()->IsPaused()) { if (!Lego()->IsPaused()) {
if ((p_param.GetModifier() & LegoEventNotificationParam::c_rButtonState) &&
!(p_param.GetModifier() & LegoEventNotificationParam::c_lButtonState) &&
Extension<MultiplayerExt>::Call(IsThirdPersonCameraActive).value_or(FALSE)) {
return FALSE;
}
processRoi = TRUE; processRoi = TRUE;
if (m_unk0x335 != 0) { if (m_unk0x335 != 0) {
@ -632,12 +638,7 @@ void LegoInputManager::RemoveJoystick(SDL_JoystickID p_joystickID)
MxBool LegoInputManager::HandleTouchEvent(SDL_Event* p_event, TouchScheme p_touchScheme) MxBool LegoInputManager::HandleTouchEvent(SDL_Event* p_event, TouchScheme p_touchScheme)
{ {
static SDL_FingerID g_finger = (SDL_FingerID) 0; if (Extension<MultiplayerExt>::Call(HandleTouchInput).value_or(FALSE)) {
if (Extension<MultiplayerExt>::Call(IsTouchInputSuppressed).value_or(FALSE)) {
g_finger = 0;
m_touchVirtualThumb = {0, 0};
m_touchFlags.clear();
return FALSE; return FALSE;
} }
@ -678,22 +679,22 @@ MxBool LegoInputManager::HandleTouchEvent(SDL_Event* p_event, TouchScheme p_touc
case e_gamepad: { case e_gamepad: {
switch (p_event->type) { switch (p_event->type) {
case SDL_EVENT_FINGER_DOWN: case SDL_EVENT_FINGER_DOWN:
if (!g_finger) { if (!m_touchFinger) {
g_finger = event.fingerID; m_touchFinger = event.fingerID;
m_touchVirtualThumb = {0, 0}; m_touchVirtualThumb = {0, 0};
m_touchVirtualThumbOrigin = {event.x, event.y}; m_touchVirtualThumbOrigin = {event.x, event.y};
} }
break; break;
case SDL_EVENT_FINGER_UP: case SDL_EVENT_FINGER_UP:
case SDL_EVENT_FINGER_CANCELED: case SDL_EVENT_FINGER_CANCELED:
if (event.fingerID == g_finger) { if (event.fingerID == m_touchFinger) {
g_finger = 0; m_touchFinger = 0;
m_touchVirtualThumb = {0, 0}; m_touchVirtualThumb = {0, 0};
m_touchVirtualThumbOrigin = {0, 0}; m_touchVirtualThumbOrigin = {0, 0};
} }
break; break;
case SDL_EVENT_FINGER_MOTION: case SDL_EVENT_FINGER_MOTION:
if (event.fingerID == g_finger) { if (event.fingerID == m_touchFinger) {
const float thumbstickRadius = 0.25f; const float thumbstickRadius = 0.25f;
const float deltaX = const float deltaX =
SDL_clamp(event.x - m_touchVirtualThumbOrigin.x, -thumbstickRadius, thumbstickRadius); SDL_clamp(event.x - m_touchVirtualThumbOrigin.x, -thumbstickRadius, thumbstickRadius);

View File

@ -66,9 +66,12 @@ class MultiplayerExt {
// Forwards SDL events to the third-person camera for orbit controls. // Forwards SDL events to the third-person camera for orbit controls.
static void HandleSDLEvent(SDL_Event* p_event); static void HandleSDLEvent(SDL_Event* p_event);
// Returns TRUE when a multi-touch camera gesture is active and touch // Returns TRUE when the third-person camera is active.
// movement input should be suppressed. static MxBool IsThirdPersonCameraActive();
static MxBool IsTouchInputSuppressed();
// Suppresses touch input when a multi-touch camera gesture is active.
// Returns TRUE if the caller should return early.
static MxBool HandleTouchInput();
static void SetNetworkManager(Multiplayer::NetworkManager* p_networkManager); static void SetNetworkManager(Multiplayer::NetworkManager* p_networkManager);
static Multiplayer::NetworkManager* GetNetworkManager(); static Multiplayer::NetworkManager* GetNetworkManager();
@ -95,7 +98,8 @@ constexpr auto HandleBeforeSaveLoad = &MultiplayerExt::HandleBeforeSaveLoad;
constexpr auto HandleSaveLoaded = &MultiplayerExt::HandleSaveLoaded; constexpr auto HandleSaveLoaded = &MultiplayerExt::HandleSaveLoaded;
constexpr auto CheckRejected = &MultiplayerExt::CheckRejected; constexpr auto CheckRejected = &MultiplayerExt::CheckRejected;
constexpr auto HandleSDLEvent = &MultiplayerExt::HandleSDLEvent; constexpr auto HandleSDLEvent = &MultiplayerExt::HandleSDLEvent;
constexpr auto IsTouchInputSuppressed = &MultiplayerExt::IsTouchInputSuppressed; constexpr auto IsThirdPersonCameraActive = &MultiplayerExt::IsThirdPersonCameraActive;
constexpr auto HandleTouchInput = &MultiplayerExt::HandleTouchInput;
#else #else
constexpr decltype(&MultiplayerExt::HandleCreate) HandleCreate = nullptr; constexpr decltype(&MultiplayerExt::HandleCreate) HandleCreate = nullptr;
constexpr decltype(&MultiplayerExt::HandleWorldEnable) HandleWorldEnable = nullptr; constexpr decltype(&MultiplayerExt::HandleWorldEnable) HandleWorldEnable = nullptr;
@ -110,7 +114,8 @@ constexpr decltype(&MultiplayerExt::HandleBeforeSaveLoad) HandleBeforeSaveLoad =
constexpr decltype(&MultiplayerExt::HandleSaveLoaded) HandleSaveLoaded = nullptr; constexpr decltype(&MultiplayerExt::HandleSaveLoaded) HandleSaveLoaded = nullptr;
constexpr decltype(&MultiplayerExt::CheckRejected) CheckRejected = nullptr; constexpr decltype(&MultiplayerExt::CheckRejected) CheckRejected = nullptr;
constexpr decltype(&MultiplayerExt::HandleSDLEvent) HandleSDLEvent = nullptr; constexpr decltype(&MultiplayerExt::HandleSDLEvent) HandleSDLEvent = nullptr;
constexpr decltype(&MultiplayerExt::IsTouchInputSuppressed) IsTouchInputSuppressed = nullptr; constexpr decltype(&MultiplayerExt::IsThirdPersonCameraActive) IsThirdPersonCameraActive = nullptr;
constexpr decltype(&MultiplayerExt::HandleTouchInput) HandleTouchInput = nullptr;
#endif #endif
}; // namespace Extensions }; // namespace Extensions

View File

@ -11,6 +11,7 @@
#include "legoentity.h" #include "legoentity.h"
#include "legoeventnotificationparam.h" #include "legoeventnotificationparam.h"
#include "legogamestate.h" #include "legogamestate.h"
#include "legoinputmanager.h"
#include "legopathactor.h" #include "legopathactor.h"
#include "misc.h" #include "misc.h"
#include "roi/legoroi.h" #include "roi/legoroi.h"
@ -299,10 +300,24 @@ void MultiplayerExt::HandleSDLEvent(SDL_Event* p_event)
} }
} }
MxBool MultiplayerExt::IsTouchInputSuppressed() MxBool MultiplayerExt::IsThirdPersonCameraActive()
{ {
if (s_networkManager && s_networkManager->GetThirdPersonCamera().IsActive()) { if (s_networkManager && s_networkManager->GetThirdPersonCamera().IsActive()) {
return s_networkManager->GetThirdPersonCamera().IsTouchGestureActive() ? TRUE : FALSE; return TRUE;
}
return FALSE;
}
MxBool MultiplayerExt::HandleTouchInput()
{
if (s_networkManager && s_networkManager->GetThirdPersonCamera().IsActive() &&
s_networkManager->GetThirdPersonCamera().IsTouchGestureActive()) {
LegoInputManager* im = InputManager();
im->m_touchFinger = 0;
im->m_touchVirtualThumb = {0, 0};
im->m_touchFlags.clear();
return TRUE;
} }
return FALSE; return FALSE;