ui/phase-15: planet inspector production controls + order-draft collapse
Adds the second end-to-end command (`setProductionType`) with a collapse-by-`planetNumber` rule on the order draft, the segmented production-controls component on the planet inspector, the FBS encoder/decoder pair for `CommandPlanetProduce`, and the `localShipClass` projection on `GameReport`. Forecast number is deferred and tracked in the new `ui/docs/calc-bridge.md`.
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
// FlatBuffers payload builders for the Phase 14 Playwright suite.
|
||||
// Mirrors what `pkg/transcoder/order.go` produces in production for
|
||||
// the `user.games.order` POST response and the
|
||||
// `user.games.order.get` GET response.
|
||||
// FlatBuffers payload builders for the Phase 14 / Phase 15 Playwright
|
||||
// suites. Mirrors what `pkg/transcoder/order.go` produces in production
|
||||
// for the `user.games.order` POST response and the
|
||||
// `user.games.order.get` GET response. Phase 15 extends the fixture
|
||||
// with a `setProductionType` variant so a single mocked gateway can
|
||||
// echo either rename or production-switch commands back to the client.
|
||||
|
||||
import { Builder } from "flatbuffers";
|
||||
|
||||
@@ -10,20 +12,46 @@ import { UUID } from "../../../src/proto/galaxy/fbs/common";
|
||||
import {
|
||||
CommandItem,
|
||||
CommandPayload,
|
||||
CommandPlanetProduce,
|
||||
CommandPlanetRename,
|
||||
PlanetProduction,
|
||||
UserGamesOrder,
|
||||
UserGamesOrderGetResponse,
|
||||
UserGamesOrderResponse,
|
||||
} from "../../../src/proto/galaxy/fbs/order";
|
||||
|
||||
export interface CommandResultFixture {
|
||||
interface CommandResultFixtureBase {
|
||||
cmdId: string;
|
||||
planetNumber: number;
|
||||
name: string;
|
||||
applied: boolean | null;
|
||||
errorCode: number | null;
|
||||
}
|
||||
|
||||
export interface PlanetRenameResultFixture extends CommandResultFixtureBase {
|
||||
kind: "planetRename";
|
||||
planetNumber: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface SetProductionTypeResultFixture
|
||||
extends CommandResultFixtureBase {
|
||||
kind: "setProductionType";
|
||||
planetNumber: number;
|
||||
productionType:
|
||||
| "MAT"
|
||||
| "CAP"
|
||||
| "DRIVE"
|
||||
| "WEAPONS"
|
||||
| "SHIELDS"
|
||||
| "CARGO"
|
||||
| "SCIENCE"
|
||||
| "SHIP";
|
||||
subject: string;
|
||||
}
|
||||
|
||||
export type CommandResultFixture =
|
||||
| PlanetRenameResultFixture
|
||||
| SetProductionTypeResultFixture;
|
||||
|
||||
export function buildOrderResponsePayload(
|
||||
gameId: string,
|
||||
commands: CommandResultFixture[],
|
||||
@@ -83,19 +111,61 @@ export function buildOrderGetResponsePayload(
|
||||
|
||||
function encodeItem(builder: Builder, c: CommandResultFixture): number {
|
||||
const cmdIdOffset = builder.createString(c.cmdId);
|
||||
const nameOffset = builder.createString(c.name);
|
||||
const inner = CommandPlanetRename.createCommandPlanetRename(
|
||||
builder,
|
||||
BigInt(c.planetNumber),
|
||||
nameOffset,
|
||||
);
|
||||
let payloadType: CommandPayload;
|
||||
let inner: number;
|
||||
switch (c.kind) {
|
||||
case "planetRename": {
|
||||
const nameOffset = builder.createString(c.name);
|
||||
inner = CommandPlanetRename.createCommandPlanetRename(
|
||||
builder,
|
||||
BigInt(c.planetNumber),
|
||||
nameOffset,
|
||||
);
|
||||
payloadType = CommandPayload.CommandPlanetRename;
|
||||
break;
|
||||
}
|
||||
case "setProductionType": {
|
||||
const subjectOffset = builder.createString(c.subject);
|
||||
inner = CommandPlanetProduce.createCommandPlanetProduce(
|
||||
builder,
|
||||
BigInt(c.planetNumber),
|
||||
productionTypeToFBS(c.productionType),
|
||||
subjectOffset,
|
||||
);
|
||||
payloadType = CommandPayload.CommandPlanetProduce;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CommandItem.startCommandItem(builder);
|
||||
CommandItem.addCmdId(builder, cmdIdOffset);
|
||||
if (c.applied !== null) CommandItem.addCmdApplied(builder, c.applied);
|
||||
if (c.errorCode !== null) {
|
||||
CommandItem.addCmdErrorCode(builder, BigInt(c.errorCode));
|
||||
}
|
||||
CommandItem.addPayloadType(builder, CommandPayload.CommandPlanetRename);
|
||||
CommandItem.addPayloadType(builder, payloadType);
|
||||
CommandItem.addPayload(builder, inner);
|
||||
return CommandItem.endCommandItem(builder);
|
||||
}
|
||||
|
||||
function productionTypeToFBS(
|
||||
value: SetProductionTypeResultFixture["productionType"],
|
||||
): PlanetProduction {
|
||||
switch (value) {
|
||||
case "MAT":
|
||||
return PlanetProduction.MAT;
|
||||
case "CAP":
|
||||
return PlanetProduction.CAP;
|
||||
case "DRIVE":
|
||||
return PlanetProduction.DRIVE;
|
||||
case "WEAPONS":
|
||||
return PlanetProduction.WEAPONS;
|
||||
case "SHIELDS":
|
||||
return PlanetProduction.SHIELDS;
|
||||
case "CARGO":
|
||||
return PlanetProduction.CARGO;
|
||||
case "SCIENCE":
|
||||
return PlanetProduction.SCIENCE;
|
||||
case "SHIP":
|
||||
return PlanetProduction.SHIP;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,11 @@
|
||||
// fixture with the optional rich planet fields (size, resources,
|
||||
// stockpiles, population, industry, colonists, production, free
|
||||
// industry) so the inspector e2e can drive the read-only display
|
||||
// against realistic values. Later phases extend the helper as ships,
|
||||
// fleets, sciences, etc. land.
|
||||
// against realistic values. Phase 15 adds a minimal `LocalShipClass`
|
||||
// projection so the planet inspector's Build-Ship sub-picker has data
|
||||
// in e2e specs (`name` only — Phase 17 widens this when ship-class
|
||||
// CRUD lands). Later phases extend the helper as fleets, sciences,
|
||||
// etc. land.
|
||||
|
||||
import { Builder } from "flatbuffers";
|
||||
|
||||
@@ -17,6 +20,7 @@ import {
|
||||
LocalPlanet,
|
||||
OtherPlanet,
|
||||
Report,
|
||||
ShipClass,
|
||||
UnidentifiedPlanet,
|
||||
UninhabitedPlanet,
|
||||
} from "../../../src/proto/galaxy/fbs/report";
|
||||
@@ -44,6 +48,10 @@ export interface OtherPlanetFixture extends InhabitedFixture {
|
||||
owner: string;
|
||||
}
|
||||
|
||||
export interface ShipClassFixture {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface ReportFixture {
|
||||
turn: number;
|
||||
mapWidth?: number;
|
||||
@@ -52,6 +60,7 @@ export interface ReportFixture {
|
||||
otherPlanets?: OtherPlanetFixture[];
|
||||
uninhabitedPlanets?: PlanetFixture[];
|
||||
unidentifiedPlanets?: { number: number; x: number; y: number }[];
|
||||
localShipClass?: ShipClassFixture[];
|
||||
}
|
||||
|
||||
export function buildReportPayload(fixture: ReportFixture): Uint8Array {
|
||||
@@ -131,6 +140,13 @@ export function buildReportPayload(fixture: ReportFixture): Uint8Array {
|
||||
},
|
||||
);
|
||||
|
||||
const localShipClassOffsets = (fixture.localShipClass ?? []).map((cls) => {
|
||||
const name = builder.createString(cls.name);
|
||||
ShipClass.startShipClass(builder);
|
||||
ShipClass.addName(builder, name);
|
||||
return ShipClass.endShipClass(builder);
|
||||
});
|
||||
|
||||
const localVec =
|
||||
localOffsets.length === 0
|
||||
? null
|
||||
@@ -147,6 +163,10 @@ export function buildReportPayload(fixture: ReportFixture): Uint8Array {
|
||||
unidentifiedOffsets.length === 0
|
||||
? null
|
||||
: Report.createUnidentifiedPlanetVector(builder, unidentifiedOffsets);
|
||||
const localShipClassVec =
|
||||
localShipClassOffsets.length === 0
|
||||
? null
|
||||
: Report.createLocalShipClassVector(builder, localShipClassOffsets);
|
||||
|
||||
const totalPlanets =
|
||||
(fixture.localPlanets ?? []).length +
|
||||
@@ -163,6 +183,8 @@ export function buildReportPayload(fixture: ReportFixture): Uint8Array {
|
||||
if (otherVec !== null) Report.addOtherPlanet(builder, otherVec);
|
||||
if (uninhabitedVec !== null) Report.addUninhabitedPlanet(builder, uninhabitedVec);
|
||||
if (unidentifiedVec !== null) Report.addUnidentifiedPlanet(builder, unidentifiedVec);
|
||||
if (localShipClassVec !== null)
|
||||
Report.addLocalShipClass(builder, localShipClassVec);
|
||||
const reportOff = Report.endReport(builder);
|
||||
builder.finish(reportOff);
|
||||
return builder.asUint8Array();
|
||||
|
||||
Reference in New Issue
Block a user