ui/phase-20: pick-first Send + lock after Modernize/Dismantle/Transfer

Send no longer carries a destination control inside the form: a
click on the action drops the inspector straight into map-pick
mode, and the form (ship count + confirm) only mounts after the
player chooses a destination. Cancelling the picker leaves no
form behind.

A queued Modernize / Dismantle / Transfer for a given group
locks every action button on its inspector and surfaces a banner
that points the player at the order list. Cancelling the queued
entry from the order tab releases the lock on the next render —
the derivation watches draft.commands directly. Send / Load /
Unload / Split / Join Fleet do not lock; Send is naturally
followed by an out-of-orbit state at turn cutoff, the rest can
stack legitimately.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Ilia Denisov
2026-05-10 17:20:48 +02:00
parent de824dfc9a
commit ac14eaff10
7 changed files with 332 additions and 77 deletions
+32 -1
View File
@@ -61,7 +61,11 @@ every action with `ships are busy ({state})`. Per-action gates:
pre-filters destinations by reach
(`localPlayerDrive * 40`), so a valid pick is always within
range. With no reachable planet, the action is disabled with
the "no planets in drive range" tooltip.
the "no planets in drive range" tooltip. Click drops the
inspector straight into map-pick mode; the form (ship count +
confirm) appears only after the player chooses a destination —
there is no destination control inside the form, so cancelling
the picker leaves the inspector untouched.
- **Load**: requires the orbit planet to be owned by the player
or unowned (`controller/ship_group.go:215`) and the ship class
to have a cargo block (`shipGroupLoad:220`). The dropdown is
@@ -88,6 +92,33 @@ every action with `ships are busy ({state})`. Per-action gates:
in the same orbit (`fleet.go:135-137`); creating a new fleet
always works.
## Destructive-command lock
`Modernize`, `Dismantle`, and `Transfer` are *state-changing* at
turn cutoff: the engine moves the group into `StateUpgrade`,
removes it, or marks it `StateTransfer` respectively. Issuing a
follow-up action against the same group during the same draft
window would race the engine's pre-condition check, so the
inspector locks the group as soon as one of the three commands
lands in the draft for that `groupId`:
- every action button on the group's inspector becomes disabled
with the "an order is already queued" tooltip;
- a banner above the buttons row names the queued command
(modernize / dismantle / transfer) and tells the player to
cancel it in the order list to issue something else;
- removing the queued entry from the order tab releases the lock
on the next render — the derivation watches `draft.commands`
directly.
Send, Load, Unload, Split, and Join Fleet do not lock the group:
Send is naturally followed by an out-of-orbit state at turn
cutoff (the engine's busy check fires next turn anyway), and the
other four can stack legitimately during the same window. The
group continues to appear in the planet inspector's stationed-
ship list while locked — the player can still navigate to the
inspector to read the state and find the order to cancel.
## Modernize cost preview
The form's preview line calls