Add right-click-to-command control scheme and type selection by multi-click - #2298
Add right-click-to-command control scheme and type selection by multi-click#2298leosnake2208 wants to merge 5 commits into
Conversation
Optional control scheme matching modern RTS games: the right mouse button issues orders to the current selection, while the left mouse button only selects/deploys and deselects on empty ground. Reuses the game's own command dispatch (and network path) by redirecting the RMB-up handler into the shared LMB-up command dispatch. Special left-click modes (repair/sell/place/beacon/ superweapon/planning) keep their vanilla behaviour. Gated behind [Phobos] ModernControls (default off).
|
rename the tag to RightClickCommand since ModernControl is an ambigious name that can refer to many things |
|
Nightly build for this pull request:
This comment is automatic and is meant to allow guests to get latest nightly builds for this pull request without registering. It is updated on every successful build. |
Address review feedback (Coronia): "ModernControls" is an ambiguous name. Rename the INI tag, config field, source file, namespace and hook names to the clearer "RightClickCommand"; update docs and CREDITS. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Done — renamed the tag to |
… TypeSelectByMultiClick Mirror the upstream PR structure in the integrated local build. The single ModernControls toggle/file is replaced by two, matching PR Phobos-developers#2298 (right-click to command) and PR Phobos-developers#2297 (multi-click type-select): - src/Misc/RightClickCommand.cpp - RMB command + LMB select/deselect, gated by [Phobos] -> RightClickCommand - src/Misc/MultiClickTypeSelect.cpp - double/triple-click type-select, gated by [Phobos] -> TypeSelectByMultiClick Both default true (this is the personal build). The fork-only 250px double-click radius and selection-group matching are preserved. The two features share RightClickCommand::RmbCommandInProgress: the RMB redirect flows through the 0x693290 multi-click hook, which clears the flag and skips the event, so an RMB order is never miscounted as a left-click. WASD panning stays separate and always-on (CameraPanWASD.cpp). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
hint: we'd appreciate (even broken) real human English more than an LLM text ;) |
Double and triple click only work once the left button stops commanding, so type select by multi-click moves here and is ignored unless RightClickCommand is on (TaranDahl's point on Phobos-developers#2297). Take the clicked unit from ProcessClickCoords' output instead of CurrentObjects[0], which picked the wrong unit whenever several were selected. Add TypeSelectByMultiClick.Range (double-click reach in cells, negative for the whole screen) and TypeSelectByMultiClick.DeployDelay (how long the left button will not deploy after a click selected something), both asked for by TAK02. Apply the scheme to the minimap too. RadarClass::GetMouseAction reads the buttons out of its flags argument, so swapping the press/held/release bits there makes the right button command and the left button move the view, the other way around from vanilla. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Clicking empty ground crashed: the clicked object is read from ProcessClickCoords' output slot, which is null there, and abstract_cast's second argument skips the null check instead of making the cast stricter. The hold-off never armed when it mattered. It started the timer on a Select action, but a click on a unit that is part of a selection is reported as NoMove just as often, while the applier narrows the selection down to that unit all the same. The next click then saw a stale timer and unpacked the unit. Decide by the clicked object instead: a click reselects when the unit was not selected yet, or when it was one of several, and such a click starts the timer and never deploys. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
mea culpa. i wasn't thinking much and didn't have any idea about the type of dinamics here. it's good to talk to real people. |
|
Thanks for the comments to all. The bugs you found and the notes about where it does not work are taken into account. So the idea itself is reworked into a full remap of the mouse buttons, like in modern strategy games (right button - orders, left button - select and deselect + multi-click). There is also a fix for clicks on the radar, so they work the same way. |
Replaces #2297. Type selection by multi-click is part of this PR now: a double click can only select units once the left button stops giving orders, otherwise it deploys an MCV or an Allied GI instead.
Feature
An opt-in control scheme matching modern RTS games:
Special left-click modes are preserved on both buttons: while placing a building, repairing, selling, toggling power, planting a beacon, planning a path, or targeting a superweapon, the left button performs that action and the right button cancels it — exactly as in vanilla. Only mouse behaviour changes; no keyboard hotkeys are rebound.
Config
Gated behind a new user setting, default off:
TypeSelectByMultiClickis turned off with a log line ifRightClickCommandis not on.Rangeis how far the double click reaches,DeployDelayis how long the left button will not deploy after a click selected something, so the second click of a double click selects instead of unpacking the unit. Both were asked for by @TAK02 on #2297, the delay works like the one in Emperor: Battle for Dune 1.009.Implementation
The tactical mouse message handler (
MouseClass@0x6930A0) dispatches window mouse messages through a jump table.RBUTTONUPandLBUTTONUPare two cases of the same function, sharing one stack frame andthis.0x693397): the RBUTTONUP handler, past its drag-flag gate, populates the view-relative click point and jumps into the shared LMB-up command dispatch at0x69323E, so the order flows through the game's ownDecideAction→ apply path — reusing 100% of the command and network logic (no argument/packet reconstruction). A flag tells the LBUTTONUP hook to let this RMB-issued order pass unmodified.0x6931B4,0x693276): right afterDecideAction, any command action is downgraded toAction::None, so the left button only selects/box-selects/deploys. On empty ground a would-be move becomes a deselect (MapClass::UnselectAll). Completed band-selects exit earlier and never reach this point.0x693290): after the click's own selection was applied, on the single-click path only. The clicked unit is read fromProcessClickCoords' output slot, not fromCurrentObjects[0]— that was the bug @TaranDahl found on Add type selection by double/triple-click #2297, it picks the wrong unit whenever several are selected. Grouping reusesTechnoTypeExt::GetSelectionGroupID, so it matches the type select inSelection.cpp.0x6539D3):RadarClass::GetMouseActionreads the buttons out of its flags argument, so swapping the press/held/release bits at the top of it swaps the two buttons for the radar. Vanilla already gives orders from the minimap with the left button, through the same applier the tactical view uses; the hover bits are left alone so the radar cursor still updates.InSpecialLeftClickMode) keeps repair/sell/placement/beacon/planning/superweapon-targeting on their vanilla buttons.Validated with the repo's
check-hooksskill — no conflicts with Phobos or Ares 3.0p1; hook sizes and return targets check out. Built clean (Debug/Release, 0 warnings). The scheme was developed and extensively tested in-game on the CnCNet Yuri's Revenge build.Notes