Skip to content

Add right-click-to-command control scheme and type selection by multi-click - #2298

Open
leosnake2208 wants to merge 5 commits into
Phobos-developers:developfrom
leosnake2208:feature/modern-controls
Open

Add right-click-to-command control scheme and type selection by multi-click#2298
leosnake2208 wants to merge 5 commits into
Phobos-developers:developfrom
leosnake2208:feature/modern-controls

Conversation

@leosnake2208

@leosnake2208 leosnake2208 commented Jul 18, 2026

Copy link
Copy Markdown

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:

  • Right mouse button issues orders to the current selection — move, attack, enter, capture, harvest, guard, and so on.
  • Left mouse button only selects, box-selects and self-deploys, and deselects when clicking empty ground.
  • Double click on a unit selects the same units nearby, triple click selects them on the whole map. Optional, and only works with the scheme on.
  • The minimap follows the same scheme: the right button gives orders, the left button moves the view. In vanilla it is the other way around.

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:

[Phobos]
RightClickCommand=false                 ; boolean
TypeSelectByMultiClick=false            ; boolean, needs RightClickCommand
TypeSelectByMultiClick.Range=-1         ; integer, cells, negative means the whole screen
TypeSelectByMultiClick.DeployDelay=500  ; integer, milliseconds

TypeSelectByMultiClick is turned off with a log line if RightClickCommand is not on. Range is how far the double click reaches, DeployDelay is 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. RBUTTONUP and LBUTTONUP are two cases of the same function, sharing one stack frame and this.

  • RMB → command (0x693397): the RBUTTONUP handler, past its drag-flag gate, populates the view-relative click point and jumps into the shared LMB-up command dispatch at 0x69323E, so the order flows through the game's own DecideAction → 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.
  • LMB → select/deploy only (0x6931B4, 0x693276): right after DecideAction, any command action is downgraded to Action::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.
  • Multi-click type select (0x693290): after the click's own selection was applied, on the single-click path only. The clicked unit is read from ProcessClickCoords' output slot, not from CurrentObjects[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 reuses TechnoTypeExt::GetSelectionGroupID, so it matches the type select in Selection.cpp.
  • Minimap (0x6539D3): RadarClass::GetMouseAction reads 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.
  • A special-mode guard (InSpecialLeftClickMode) keeps repair/sell/placement/beacon/planning/superweapon-targeting on their vanilla buttons.

Validated with the repo's check-hooks skill — 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

  • Net-safe: client-side input mapping only; orders reuse the game's own networked dispatch.
  • Could later be split into finer toggles (RMB-to-command vs LMB-select-only) if that is preferred.

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).
@Coronia

Coronia commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

rename the tag to RightClickCommand since ModernControl is an ambigious name that can refer to many things

@github-actions

Copy link
Copy Markdown

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>
@leosnake2208 leosnake2208 changed the title Add modern control scheme (right-click to command) Add right-click-to-command control scheme Jul 19, 2026
@leosnake2208

Copy link
Copy Markdown
Author

Done — renamed the tag to RightClickCommand (and updated the config field, source file, namespace, hook names, docs and CREDITS to match). PR title/body updated too. Thanks!

leosnake2208 added a commit to leosnake2208/Phobos that referenced this pull request Jul 19, 2026
… 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>
@Metadorius

Copy link
Copy Markdown
Member

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>
@leosnake2208
leosnake2208 deleted the feature/modern-controls branch August 7, 2026 19:24
@leosnake2208
leosnake2208 restored the feature/modern-controls branch August 7, 2026 19:25
@leosnake2208 leosnake2208 reopened this Aug 7, 2026
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>
@leosnake2208 leosnake2208 changed the title Add right-click-to-command control scheme Add right-click-to-command control scheme and type selection by multi-click Aug 7, 2026
@leosnake2208

Copy link
Copy Markdown
Author

hint: we'd appreciate (even broken) real human English more than an LLM text ;)

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.

@leosnake2208

Copy link
Copy Markdown
Author

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.

@leosnake2208
leosnake2208 marked this pull request as ready for review August 7, 2026 21:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants