ui/phase-20: ship-group inspector actions
Eight ship-group operations land on the inspector behind a single inline-form panel: split, send, load, unload, modernize, dismantle, transfer, join fleet. Each action either appends a typed command to the local order draft or surfaces a tooltip explaining the disabled state. Partial-ship operations emit an implicit breakShipGroup command before the targeted action so the engine sees a clean (Break, Action) pair on the wire. `pkg/calc.BlockUpgradeCost` migrates from `game/internal/controller/ship_group_upgrade.go` so the calc bridge can wrap a pure pkg/calc formula; the controller now imports it. The bridge surfaces the function as `core.blockUpgradeCost`, which the inspector calls once per ship block to render the modernize cost preview. `GameReport.otherRaces` is decoded from the report's player block (non-extinct, ≠ self) and feeds the transfer-to-race picker. The planet inspector's stationed-ship rows become clickable for own groups so the actions panel is reachable from the standard click flow (the renderer continues to hide on-planet groups). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
// - speed(fields) -> number
|
||||
// - cargoCapacity(fields) -> number
|
||||
// - carryingMass(fields) -> number
|
||||
// - blockUpgradeCost(fields) -> number (Phase 20: modernize cost preview)
|
||||
//
|
||||
// Field objects are plain JS objects with camelCase keys matching the
|
||||
// TypeScript `Core` interface, and bytes fields are Uint8Array.
|
||||
@@ -59,6 +60,7 @@ func main() {
|
||||
"speed": js.FuncOf(speed),
|
||||
"cargoCapacity": js.FuncOf(cargoCapacity),
|
||||
"carryingMass": js.FuncOf(carryingMass),
|
||||
"blockUpgradeCost": js.FuncOf(blockUpgradeCost),
|
||||
}))
|
||||
|
||||
// Block forever so the Go runtime stays alive while JS keeps calling
|
||||
@@ -224,6 +226,21 @@ func carryingMass(_ js.Value, args []js.Value) any {
|
||||
return js.ValueOf(calc.CarryingMass(load, cargoTech))
|
||||
}
|
||||
|
||||
// blockUpgradeCost bridges `calc.BlockUpgradeCost`. Input
|
||||
// `{ blockMass, currentTech, targetTech }`, output a JS number
|
||||
// (production cost of moving one block from currentTech to
|
||||
// targetTech; zero when blockMass is zero or targetTech is not
|
||||
// above currentTech).
|
||||
func blockUpgradeCost(_ js.Value, args []js.Value) any {
|
||||
if len(args) != 1 {
|
||||
return js.Null()
|
||||
}
|
||||
blockMass := args[0].Get("blockMass").Float()
|
||||
currentTech := args[0].Get("currentTech").Float()
|
||||
targetTech := args[0].Get("targetTech").Float()
|
||||
return js.ValueOf(calc.BlockUpgradeCost(blockMass, currentTech, targetTech))
|
||||
}
|
||||
|
||||
// copyBytesFromJS materialises a JS Uint8Array (or any indexable
|
||||
// byte-shaped value) into a Go byte slice. We avoid `js.CopyBytesToGo`
|
||||
// because TinyGo's implementation panics on values it does not
|
||||
|
||||
Reference in New Issue
Block a user