ui/phase-11: map wired to live game state
Replaces the Phase 10 map stub with live planet rendering driven by `user.games.report`, and wires the header turn counter to the same data. Phase 11's frontend sits on a per-game `GameStateStore` that lives in `lib/game-state.svelte.ts`: the in-game shell layout instantiates one per game, exposes it through Svelte context, and disposes it on remount. The store discovers the game's current turn through `lobby.my.games.list`, fetches the matching report, and exposes a TS-friendly snapshot to the header turn counter, the map view, and the inspector / order / calculator tabs that later phases will plug onto the same instance. The pipeline forced one cross-stage decision: the user surface needs the current turn number to know which report to fetch, but `GameSummary` did not expose it. Phase 11 extends the lobby catalogue (FB schema, transcoder, Go model, backend gameSummaryWire, gateway decoders, openapi, TS bindings, api/lobby.ts) with `current_turn:int32`. The data was already tracked in backend's `RuntimeSnapshot.CurrentTurn`; surfacing it is a wire change only. Two alternatives were rejected: a brand-new `user.games.state` message (full wire-flow for one field) and hard-coding `turn=0` (works for the dev sandbox, which never advances past zero, but renders the initial state for any real game). The change crosses Phase 8's already-shipped catalogue per the project's "decisions baked back into the live plan" rule — existing tests and fixtures are updated in the same patch. The state binding lives in `map/state-binding.ts::reportToWorld`: one Point primitive per planet across all four kinds (local / other / uninhabited / unidentified) with distinct fill colours, fill alphas, and point radii so the user can tell them apart at a glance. The planet engine number is reused as the primitive id so a hit-test result resolves directly to a planet without an extra lookup table. Zero-planet reports yield a well-formed empty world; malformed dimensions fall back to 1×1 so a bad report cannot crash the renderer. The map view's mount effect creates the renderer once and skips re-mount on no-op refreshes (same turn, same wrap mode); a turn change or wrap-mode flip disposes and recreates it. The renderer's external API does not yet expose `setWorld`; Phase 24 / 34 will extract it once high-frequency updates land. The store installs a `visibilitychange` listener that calls `refresh()` when the tab regains focus. Wrap-mode preference uses `Cache` namespace `game-prefs`, key `<gameId>/wrap-mode`, default `torus`. Phase 11 reads through `store.wrapMode`; Phase 29 wires the toggle UI on top of `setWrapMode`. Tests: Vitest unit coverage for `reportToWorld` (every kind, ids, styling, empty / zero-dimension edges, priority order) and for the store lifecycle (init success, missing-membership error, forbidden-result error, `setTurn`, wrap-mode persistence across instances, `failBootstrap`). Playwright e2e mocks the gateway for `lobby.my.games.list` and `user.games.report` and asserts the live data path: turn counter shows the reported turn, `active-view-map` flips to `data-status="ready"`, and `data-planet-count` matches the fixture count. The zero-planet regression and the missing-membership error path are covered. Phase 11 status stays `pending` in `ui/PLAN.md` until the local-ci run lands green; flipping to `done` follows in the next commit per the per-stage CI gate in `CLAUDE.md`. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -89,9 +89,12 @@ type gameSummaryWire struct {
|
|||||||
EnrollmentEndsAt string `json:"enrollment_ends_at"`
|
EnrollmentEndsAt string `json:"enrollment_ends_at"`
|
||||||
CreatedAt string `json:"created_at"`
|
CreatedAt string `json:"created_at"`
|
||||||
UpdatedAt string `json:"updated_at"`
|
UpdatedAt string `json:"updated_at"`
|
||||||
|
CurrentTurn int32 `json:"current_turn"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// lobbyGameDetailWire mirrors `LobbyGameDetail` from openapi.yaml.
|
// lobbyGameDetailWire mirrors `LobbyGameDetail` from openapi.yaml.
|
||||||
|
// `current_turn` is inherited from `gameSummaryWire`; the runtime
|
||||||
|
// fields below carry the runtime projection on top of it.
|
||||||
type lobbyGameDetailWire struct {
|
type lobbyGameDetailWire struct {
|
||||||
gameSummaryWire
|
gameSummaryWire
|
||||||
Visibility string `json:"visibility"`
|
Visibility string `json:"visibility"`
|
||||||
@@ -100,7 +103,6 @@ type lobbyGameDetailWire struct {
|
|||||||
TargetEngineVersion string `json:"target_engine_version"`
|
TargetEngineVersion string `json:"target_engine_version"`
|
||||||
StartGapHours int32 `json:"start_gap_hours"`
|
StartGapHours int32 `json:"start_gap_hours"`
|
||||||
StartGapPlayers int32 `json:"start_gap_players"`
|
StartGapPlayers int32 `json:"start_gap_players"`
|
||||||
CurrentTurn int32 `json:"current_turn"`
|
|
||||||
RuntimeStatus string `json:"runtime_status"`
|
RuntimeStatus string `json:"runtime_status"`
|
||||||
EngineHealth string `json:"engine_health,omitempty"`
|
EngineHealth string `json:"engine_health,omitempty"`
|
||||||
StartedAt *string `json:"started_at,omitempty"`
|
StartedAt *string `json:"started_at,omitempty"`
|
||||||
@@ -118,6 +120,7 @@ func gameSummaryToWire(g lobby.GameRecord) gameSummaryWire {
|
|||||||
EnrollmentEndsAt: g.EnrollmentEndsAt.UTC().Format(timestampLayout),
|
EnrollmentEndsAt: g.EnrollmentEndsAt.UTC().Format(timestampLayout),
|
||||||
CreatedAt: g.CreatedAt.UTC().Format(timestampLayout),
|
CreatedAt: g.CreatedAt.UTC().Format(timestampLayout),
|
||||||
UpdatedAt: g.UpdatedAt.UTC().Format(timestampLayout),
|
UpdatedAt: g.UpdatedAt.UTC().Format(timestampLayout),
|
||||||
|
CurrentTurn: g.RuntimeSnapshot.CurrentTurn,
|
||||||
}
|
}
|
||||||
if g.OwnerUserID != nil {
|
if g.OwnerUserID != nil {
|
||||||
s := g.OwnerUserID.String()
|
s := g.OwnerUserID.String()
|
||||||
@@ -135,7 +138,6 @@ func lobbyGameDetailToWire(g lobby.GameRecord) lobbyGameDetailWire {
|
|||||||
TargetEngineVersion: g.TargetEngineVersion,
|
TargetEngineVersion: g.TargetEngineVersion,
|
||||||
StartGapHours: g.StartGapHours,
|
StartGapHours: g.StartGapHours,
|
||||||
StartGapPlayers: g.StartGapPlayers,
|
StartGapPlayers: g.StartGapPlayers,
|
||||||
CurrentTurn: g.RuntimeSnapshot.CurrentTurn,
|
|
||||||
RuntimeStatus: g.RuntimeSnapshot.RuntimeStatus,
|
RuntimeStatus: g.RuntimeSnapshot.RuntimeStatus,
|
||||||
EngineHealth: g.RuntimeSnapshot.EngineHealth,
|
EngineHealth: g.RuntimeSnapshot.EngineHealth,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2515,6 +2515,7 @@ components:
|
|||||||
- enrollment_ends_at
|
- enrollment_ends_at
|
||||||
- created_at
|
- created_at
|
||||||
- updated_at
|
- updated_at
|
||||||
|
- current_turn
|
||||||
properties:
|
properties:
|
||||||
game_id:
|
game_id:
|
||||||
type: string
|
type: string
|
||||||
@@ -2563,6 +2564,13 @@ components:
|
|||||||
updated_at:
|
updated_at:
|
||||||
type: string
|
type: string
|
||||||
format: date-time
|
format: date-time
|
||||||
|
current_turn:
|
||||||
|
type: integer
|
||||||
|
description: |
|
||||||
|
Most recent turn number observed by backend's runtime
|
||||||
|
projection. Zero before the engine produces its first
|
||||||
|
snapshot. The user surface uses it to fetch the matching
|
||||||
|
`user.games.report` without a separate state query.
|
||||||
GameSummaryPage:
|
GameSummaryPage:
|
||||||
type: object
|
type: object
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
@@ -2720,7 +2728,6 @@ components:
|
|||||||
- target_engine_version
|
- target_engine_version
|
||||||
- start_gap_hours
|
- start_gap_hours
|
||||||
- start_gap_players
|
- start_gap_players
|
||||||
- current_turn
|
|
||||||
- runtime_status
|
- runtime_status
|
||||||
properties:
|
properties:
|
||||||
visibility:
|
visibility:
|
||||||
@@ -2736,8 +2743,6 @@ components:
|
|||||||
type: integer
|
type: integer
|
||||||
start_gap_players:
|
start_gap_players:
|
||||||
type: integer
|
type: integer
|
||||||
current_turn:
|
|
||||||
type: integer
|
|
||||||
runtime_status:
|
runtime_status:
|
||||||
type: string
|
type: string
|
||||||
engine_health:
|
engine_health:
|
||||||
|
|||||||
@@ -390,6 +390,7 @@ func decodeGameSummaryFromGameDetail(payload []byte) (lobbymodel.GameSummary, er
|
|||||||
EnrollmentEndsAt time.Time `json:"enrollment_ends_at"`
|
EnrollmentEndsAt time.Time `json:"enrollment_ends_at"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
CurrentTurn int32 `json:"current_turn"`
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(payload, &wire); err != nil {
|
if err := json.Unmarshal(payload, &wire); err != nil {
|
||||||
return lobbymodel.GameSummary{}, fmt.Errorf("decode success response: %w", err)
|
return lobbymodel.GameSummary{}, fmt.Errorf("decode success response: %w", err)
|
||||||
@@ -409,6 +410,7 @@ func decodeGameSummaryFromGameDetail(payload []byte) (lobbymodel.GameSummary, er
|
|||||||
EnrollmentEndsAt: wire.EnrollmentEndsAt.UTC(),
|
EnrollmentEndsAt: wire.EnrollmentEndsAt.UTC(),
|
||||||
CreatedAt: wire.CreatedAt.UTC(),
|
CreatedAt: wire.CreatedAt.UTC(),
|
||||||
UpdatedAt: wire.UpdatedAt.UTC(),
|
UpdatedAt: wire.UpdatedAt.UTC(),
|
||||||
|
CurrentTurn: wire.CurrentTurn,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -425,6 +427,7 @@ func decodePublicGamesPage(payload []byte) (*lobbymodel.PublicGamesListResponse,
|
|||||||
EnrollmentEndsAt time.Time `json:"enrollment_ends_at"`
|
EnrollmentEndsAt time.Time `json:"enrollment_ends_at"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
CurrentTurn int32 `json:"current_turn"`
|
||||||
} `json:"items"`
|
} `json:"items"`
|
||||||
Page int `json:"page"`
|
Page int `json:"page"`
|
||||||
PageSize int `json:"page_size"`
|
PageSize int `json:"page_size"`
|
||||||
@@ -455,6 +458,7 @@ func decodePublicGamesPage(payload []byte) (*lobbymodel.PublicGamesListResponse,
|
|||||||
EnrollmentEndsAt: w.EnrollmentEndsAt.UTC(),
|
EnrollmentEndsAt: w.EnrollmentEndsAt.UTC(),
|
||||||
CreatedAt: w.CreatedAt.UTC(),
|
CreatedAt: w.CreatedAt.UTC(),
|
||||||
UpdatedAt: w.UpdatedAt.UTC(),
|
UpdatedAt: w.UpdatedAt.UTC(),
|
||||||
|
CurrentTurn: w.CurrentTurn,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return out, nil
|
return out, nil
|
||||||
|
|||||||
@@ -62,7 +62,10 @@ type MyGamesListResponse struct {
|
|||||||
|
|
||||||
// GameSummary stores one game record returned by the various lobby
|
// GameSummary stores one game record returned by the various lobby
|
||||||
// list endpoints. `OwnerUserID` is empty for public games (no human
|
// list endpoints. `OwnerUserID` is empty for public games (no human
|
||||||
// owner).
|
// owner). `CurrentTurn` carries the runtime's most recently observed
|
||||||
|
// turn number; the value is zero before the engine produces its first
|
||||||
|
// snapshot. The user surface uses it to fetch the corresponding
|
||||||
|
// `user.games.report` without an extra round-trip.
|
||||||
type GameSummary struct {
|
type GameSummary struct {
|
||||||
GameID string `json:"game_id"`
|
GameID string `json:"game_id"`
|
||||||
GameName string `json:"game_name"`
|
GameName string `json:"game_name"`
|
||||||
@@ -74,6 +77,7 @@ type GameSummary struct {
|
|||||||
EnrollmentEndsAt time.Time `json:"enrollment_ends_at"`
|
EnrollmentEndsAt time.Time `json:"enrollment_ends_at"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
CurrentTurn int32 `json:"current_turn"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicGamesListRequest stores the paginated read request for joinable
|
// PublicGamesListRequest stores the paginated read request for joinable
|
||||||
|
|||||||
@@ -6,7 +6,11 @@ namespace lobby;
|
|||||||
|
|
||||||
// GameSummary stores one game record returned by the lobby list
|
// GameSummary stores one game record returned by the lobby list
|
||||||
// endpoints. owner_user_id is empty for public games (no human owner).
|
// endpoints. owner_user_id is empty for public games (no human owner).
|
||||||
// The shape matches `lobby/openapi.yaml` `MyGameSummary`.
|
// current_turn carries the runtime's most recent observed turn number
|
||||||
|
// (zero before the engine produces its first snapshot); the user
|
||||||
|
// surface uses it to read the corresponding `user.games.report`
|
||||||
|
// without an extra round-trip. The shape matches `lobby/openapi.yaml`
|
||||||
|
// `MyGameSummary`.
|
||||||
table GameSummary {
|
table GameSummary {
|
||||||
game_id:string;
|
game_id:string;
|
||||||
game_name:string;
|
game_name:string;
|
||||||
@@ -18,6 +22,7 @@ table GameSummary {
|
|||||||
enrollment_ends_at_ms:int64;
|
enrollment_ends_at_ms:int64;
|
||||||
created_at_ms:int64;
|
created_at_ms:int64;
|
||||||
updated_at_ms:int64;
|
updated_at_ms:int64;
|
||||||
|
current_turn:int32;
|
||||||
}
|
}
|
||||||
|
|
||||||
// MyGamesListRequest stores the authenticated read request for the
|
// MyGamesListRequest stores the authenticated read request for the
|
||||||
|
|||||||
@@ -141,8 +141,20 @@ func (rcv *GameSummary) MutateUpdatedAtMs(n int64) bool {
|
|||||||
return rcv._tab.MutateInt64Slot(22, n)
|
return rcv._tab.MutateInt64Slot(22, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rcv *GameSummary) CurrentTurn() int32 {
|
||||||
|
o := flatbuffers.UOffsetT(rcv._tab.Offset(24))
|
||||||
|
if o != 0 {
|
||||||
|
return rcv._tab.GetInt32(o + rcv._tab.Pos)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rcv *GameSummary) MutateCurrentTurn(n int32) bool {
|
||||||
|
return rcv._tab.MutateInt32Slot(24, n)
|
||||||
|
}
|
||||||
|
|
||||||
func GameSummaryStart(builder *flatbuffers.Builder) {
|
func GameSummaryStart(builder *flatbuffers.Builder) {
|
||||||
builder.StartObject(10)
|
builder.StartObject(11)
|
||||||
}
|
}
|
||||||
func GameSummaryAddGameId(builder *flatbuffers.Builder, gameId flatbuffers.UOffsetT) {
|
func GameSummaryAddGameId(builder *flatbuffers.Builder, gameId flatbuffers.UOffsetT) {
|
||||||
builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(gameId), 0)
|
builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(gameId), 0)
|
||||||
@@ -174,6 +186,9 @@ func GameSummaryAddCreatedAtMs(builder *flatbuffers.Builder, createdAtMs int64)
|
|||||||
func GameSummaryAddUpdatedAtMs(builder *flatbuffers.Builder, updatedAtMs int64) {
|
func GameSummaryAddUpdatedAtMs(builder *flatbuffers.Builder, updatedAtMs int64) {
|
||||||
builder.PrependInt64Slot(9, updatedAtMs, 0)
|
builder.PrependInt64Slot(9, updatedAtMs, 0)
|
||||||
}
|
}
|
||||||
|
func GameSummaryAddCurrentTurn(builder *flatbuffers.Builder, currentTurn int32) {
|
||||||
|
builder.PrependInt32Slot(10, currentTurn, 0)
|
||||||
|
}
|
||||||
func GameSummaryEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
|
func GameSummaryEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
|
||||||
return builder.EndObject()
|
return builder.EndObject()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -783,6 +783,7 @@ func encodeGameSummary(builder *flatbuffers.Builder, summary lobbymodel.GameSumm
|
|||||||
lobbyfbs.GameSummaryAddEnrollmentEndsAtMs(builder, summary.EnrollmentEndsAt.UTC().UnixMilli())
|
lobbyfbs.GameSummaryAddEnrollmentEndsAtMs(builder, summary.EnrollmentEndsAt.UTC().UnixMilli())
|
||||||
lobbyfbs.GameSummaryAddCreatedAtMs(builder, summary.CreatedAt.UTC().UnixMilli())
|
lobbyfbs.GameSummaryAddCreatedAtMs(builder, summary.CreatedAt.UTC().UnixMilli())
|
||||||
lobbyfbs.GameSummaryAddUpdatedAtMs(builder, summary.UpdatedAt.UTC().UnixMilli())
|
lobbyfbs.GameSummaryAddUpdatedAtMs(builder, summary.UpdatedAt.UTC().UnixMilli())
|
||||||
|
lobbyfbs.GameSummaryAddCurrentTurn(builder, summary.CurrentTurn)
|
||||||
return lobbyfbs.GameSummaryEnd(builder)
|
return lobbyfbs.GameSummaryEnd(builder)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -798,6 +799,7 @@ func decodeGameSummary(summary *lobbyfbs.GameSummary) lobbymodel.GameSummary {
|
|||||||
EnrollmentEndsAt: time.UnixMilli(summary.EnrollmentEndsAtMs()).UTC(),
|
EnrollmentEndsAt: time.UnixMilli(summary.EnrollmentEndsAtMs()).UTC(),
|
||||||
CreatedAt: time.UnixMilli(summary.CreatedAtMs()).UTC(),
|
CreatedAt: time.UnixMilli(summary.CreatedAtMs()).UTC(),
|
||||||
UpdatedAt: time.UnixMilli(summary.UpdatedAtMs()).UTC(),
|
UpdatedAt: time.UnixMilli(summary.UpdatedAtMs()).UTC(),
|
||||||
|
CurrentTurn: summary.CurrentTurn(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,13 +29,14 @@ func TestLobbyMyGamesListRoundTrip(t *testing.T) {
|
|||||||
GameID: "game-private-7c8f",
|
GameID: "game-private-7c8f",
|
||||||
GameName: "First Contact",
|
GameName: "First Contact",
|
||||||
GameType: "private",
|
GameType: "private",
|
||||||
Status: "draft",
|
Status: "running",
|
||||||
OwnerUserID: "user-9912",
|
OwnerUserID: "user-9912",
|
||||||
MinPlayers: 2,
|
MinPlayers: 2,
|
||||||
MaxPlayers: 8,
|
MaxPlayers: 8,
|
||||||
EnrollmentEndsAt: ends,
|
EnrollmentEndsAt: ends,
|
||||||
CreatedAt: created,
|
CreatedAt: created,
|
||||||
UpdatedAt: updated,
|
UpdatedAt: updated,
|
||||||
|
CurrentTurn: 7,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
GameID: "game-public-aabb",
|
GameID: "game-public-aabb",
|
||||||
@@ -48,6 +49,7 @@ func TestLobbyMyGamesListRoundTrip(t *testing.T) {
|
|||||||
EnrollmentEndsAt: ends,
|
EnrollmentEndsAt: ends,
|
||||||
CreatedAt: created,
|
CreatedAt: created,
|
||||||
UpdatedAt: updated,
|
UpdatedAt: updated,
|
||||||
|
CurrentTurn: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ WASM_OUT := frontend/static/core.wasm
|
|||||||
WASM_EXEC := frontend/static/wasm_exec.js
|
WASM_EXEC := frontend/static/wasm_exec.js
|
||||||
TINYGO_ROOT := $(shell tinygo env TINYGOROOT 2>/dev/null)
|
TINYGO_ROOT := $(shell tinygo env TINYGOROOT 2>/dev/null)
|
||||||
FBS_OUT := frontend/src/proto/galaxy/fbs
|
FBS_OUT := frontend/src/proto/galaxy/fbs
|
||||||
FBS_INPUTS := ../pkg/schema/fbs/lobby.fbs ../pkg/schema/fbs/user.fbs
|
FBS_INPUTS := ../pkg/schema/fbs/common.fbs ../pkg/schema/fbs/lobby.fbs ../pkg/schema/fbs/user.fbs ../pkg/schema/fbs/report.fbs
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@echo "ui targets:"
|
@echo "ui targets:"
|
||||||
|
|||||||
+143
-19
@@ -1165,22 +1165,140 @@ Status: pending.
|
|||||||
Goal: replace the map fixture with real planet data fetched from the
|
Goal: replace the map fixture with real planet data fetched from the
|
||||||
gateway for the selected game; planets only, read-only.
|
gateway for the selected game; planets only, read-only.
|
||||||
|
|
||||||
Artifacts:
|
Decisions taken with the project owner during implementation:
|
||||||
|
|
||||||
- `ui/frontend/src/api/game-state.ts` fetch latest game state via
|
1. **`current_turn` on `GameSummary`.** The user-facing
|
||||||
`user.games.report`
|
`lobby.my.games.list` did not expose the runtime's current turn
|
||||||
- `ui/frontend/src/map/state-binding.ts` map-state synchroniser
|
number, but the in-game shell needs it to fetch the matching
|
||||||
applying planets to the renderer
|
`user.games.report`. Phase 11 extends `GameSummary` with a new
|
||||||
- `ui/frontend/src/lib/active-view/map.svelte` integrates the renderer
|
`current_turn:int32` field (FB schema, Go transcoder + model,
|
||||||
with live data and a loading state, defaulting to torus mode and
|
backend `gameSummaryWire`, gateway `decodeGameSummary*`,
|
||||||
reading the per-game wrap-scrolling preference from `Cache` (toggle
|
`backend/openapi.yaml`, TS bindings, `api/lobby.ts`). The data
|
||||||
itself is exposed in Phase 29)
|
was already tracked in the runtime projection
|
||||||
- `ui/frontend/src/lib/header/turn-counter.svelte` reads the live
|
(`backend/internal/lobby/types.go RuntimeSnapshot.CurrentTurn`);
|
||||||
turn number from game state
|
exposing it is purely a wire change. Two alternatives were
|
||||||
|
rejected: a brand-new `user.games.state` message (full wire-flow
|
||||||
|
for a one-field response) and hard-coding `turn=0` (works for the
|
||||||
|
dev sandbox, but renders the initial state for any game past
|
||||||
|
turn zero). The decision crosses Phase 8's already-shipped
|
||||||
|
catalogue per the project's "decisions baked back into the live
|
||||||
|
plan" rule.
|
||||||
|
2. **Per-game state store with context.** A `GameStateStore` lives
|
||||||
|
in `lib/game-state.svelte.ts`; the in-game shell layout
|
||||||
|
instantiates one per game and exposes it through Svelte context
|
||||||
|
under `GAME_STATE_CONTEXT_KEY`. Header turn counter, map view,
|
||||||
|
and (in later phases) inspector tabs all consume the same
|
||||||
|
instance. A new instance is created on layout remount (game id
|
||||||
|
change), so each game gets a fresh snapshot.
|
||||||
|
3. **Lobby lookup for current turn.** The store does not assume the
|
||||||
|
caller passed `current_turn` through navigation state. On
|
||||||
|
`setGame`, it calls `lobby.my.games.list` itself, finds the game
|
||||||
|
record, reads `current_turn`, and then calls
|
||||||
|
`user.games.report`. A direct deep link to `/games/:id/map` for
|
||||||
|
a game the user is not a member of flips the store to `error`
|
||||||
|
with a `not in your list` message.
|
||||||
|
4. **Refresh on tab focus.** The store installs a
|
||||||
|
`visibilitychange` listener that calls `refresh()` when the
|
||||||
|
document becomes visible and the store is `ready`. The map
|
||||||
|
view's mount effect skips a re-render when the new snapshot's
|
||||||
|
turn matches the previously-mounted turn (and the wrap mode is
|
||||||
|
unchanged), so a no-op refresh does not flicker the canvas.
|
||||||
|
5. **Wrap-mode preference.** `Cache` namespace `game-prefs`, key
|
||||||
|
`<gameId>/wrap-mode`, values `torus` (default) / `no-wrap`.
|
||||||
|
Phase 11 reads through `wrapMode`; `setWrapMode` writes back.
|
||||||
|
Phase 29 wires the toggle UI on top of these primitives.
|
||||||
|
6. **State binding.** `map/state-binding.ts::reportToWorld` emits
|
||||||
|
one Point primitive per planet across all four kinds (local /
|
||||||
|
other / uninhabited / unidentified) with distinct fill colours
|
||||||
|
and point radii. Each primitive's id reuses the engine planet
|
||||||
|
number so a hit-test result resolves directly to a planet
|
||||||
|
without an extra lookup table. Zero-planet reports yield a
|
||||||
|
well-formed empty world; the World constructor's positivity
|
||||||
|
check is guarded by a 1×1 fallback for the malformed-report
|
||||||
|
edge case.
|
||||||
|
7. **Renderer remount on snapshot change.** The map view disposes
|
||||||
|
and recreates the renderer when the report's turn changes (and
|
||||||
|
short-circuits when it does not). This is wasteful for the
|
||||||
|
tab-focus refresh path, but the renderer's external
|
||||||
|
`RendererHandle` does not yet expose a `setWorld` API and Phase
|
||||||
|
11's per-game planet count is small enough that the remount
|
||||||
|
cost (a few hundred ms) is acceptable. A future phase that adds
|
||||||
|
high-frequency updates (Phase 24 push events, Phase 34 multi-
|
||||||
|
turn projection overlays) will extract a `replaceWorld` method.
|
||||||
|
8. **e2e bootstrap reuses `__galaxyDebug`.** The Phase 10 pattern
|
||||||
|
of seeding the device session through `/__debug/store` carries
|
||||||
|
over; the gateway is mocked through `page.route` for
|
||||||
|
`lobby.my.games.list`, `user.games.report`, and the
|
||||||
|
`SubscribeEvents` stream that the revocation watcher opens
|
||||||
|
(held open indefinitely so a clean end-of-stream does not
|
||||||
|
trigger `signOut("revoked")` and bounce the test back to
|
||||||
|
`/login`).
|
||||||
|
|
||||||
|
Artifacts (delivered):
|
||||||
|
|
||||||
|
- `ui/frontend/src/api/game-state.ts` — typed wrapper for
|
||||||
|
`user.games.report` plus `uuidToHiLo` and a TS-friendly
|
||||||
|
`GameReport` shape (planets only)
|
||||||
|
- `ui/frontend/src/lib/game-state.svelte.ts` — runes-based
|
||||||
|
`GameStateStore` with init / setGame / setTurn / refresh /
|
||||||
|
setWrapMode / failBootstrap / dispose; tab-focus listener;
|
||||||
|
`Cache`-backed wrap-mode persistence
|
||||||
|
- `ui/frontend/src/map/state-binding.ts` — `reportToWorld` and the
|
||||||
|
per-kind planet styling
|
||||||
|
- `ui/frontend/src/lib/active-view/map.svelte` — replaces the
|
||||||
|
Phase 10 stub with the live renderer integration plus loading /
|
||||||
|
error overlays and a `data-planet-count` testid hook
|
||||||
|
- `ui/frontend/src/lib/header/turn-counter.svelte` — reads
|
||||||
|
`store.report.turn` through context, falls back to the static
|
||||||
|
`?` placeholder when the store has not yet produced a snapshot
|
||||||
|
- `ui/frontend/src/routes/games/[id]/+layout.svelte` — instantiates
|
||||||
|
the `GameStateStore`, builds the `GalaxyClient`, exposes the
|
||||||
|
store via `setContext`, disposes on unmount
|
||||||
|
- `pkg/schema/fbs/lobby.fbs` — `current_turn:int32` field
|
||||||
|
- `pkg/schema/fbs/lobby/GameSummary.go` (regenerated)
|
||||||
|
- `pkg/transcoder/lobby.go` — encode/decode `current_turn`
|
||||||
|
- `pkg/transcoder/lobby_test.go` — non-zero `current_turn` in the
|
||||||
|
round-trip fixture
|
||||||
|
- `pkg/model/lobby/lobby.go` — `CurrentTurn int32` on `GameSummary`
|
||||||
|
- `backend/internal/server/handlers_user_lobby_helpers.go` —
|
||||||
|
`gameSummaryWire.CurrentTurn` + `gameSummaryToWire` reads it
|
||||||
|
from `RuntimeSnapshot.CurrentTurn`; `lobbyGameDetailWire` no
|
||||||
|
longer redeclares the field
|
||||||
|
- `backend/openapi.yaml` — `current_turn` on the `GameSummary`
|
||||||
|
schema (required); removed from the `LobbyGameDetail` allOf
|
||||||
|
block (now inherited)
|
||||||
|
- `gateway/internal/backendclient/lobby_commands.go` —
|
||||||
|
`decodeGameSummaryFromGameDetail` and `decodePublicGamesPage`
|
||||||
|
parse `current_turn` from JSON
|
||||||
|
- `ui/Makefile` — `FBS_INPUTS` adds `common.fbs` (so the
|
||||||
|
`common/uuid.ts` directory is generated) and `report.fbs`
|
||||||
|
- `ui/frontend/src/proto/galaxy/fbs/{common,report}/...` —
|
||||||
|
regenerated TS bindings
|
||||||
|
- `ui/frontend/src/api/lobby.ts` — `currentTurn: number` on
|
||||||
|
`GameSummary`; `decodeGameSummary` reads it
|
||||||
|
- `ui/frontend/tests/lobby-{fbs,api,page}.test.ts` and
|
||||||
|
`tests/e2e/fixtures/lobby-fbs.ts` — fixtures and assertions
|
||||||
|
cover `currentTurn`
|
||||||
|
- `ui/frontend/tests/state-binding.test.ts` — Vitest unit
|
||||||
|
coverage for `reportToWorld` (dimensions, kinds, ids, styling,
|
||||||
|
empty-planet, zero-dimension fallback, priority order)
|
||||||
|
- `ui/frontend/tests/game-state.test.ts` — Vitest coverage for
|
||||||
|
`GameStateStore` (init flow, missing-membership error,
|
||||||
|
forbidden-result error, `setTurn`, wrap-mode persistence
|
||||||
|
across instances, `failBootstrap`)
|
||||||
|
- `ui/frontend/tests/e2e/game-shell-map.spec.ts` — Playwright e2e
|
||||||
|
with a mocked gateway: live report renders the reported turn
|
||||||
|
and planet count, zero-planet game renders without errors,
|
||||||
|
missing-membership game surfaces the error overlay
|
||||||
|
- `ui/frontend/tests/e2e/fixtures/report-fbs.ts` — `buildReportPayload`
|
||||||
|
helper for forging FB Report payloads
|
||||||
|
- Topic doc `ui/docs/game-state.md`
|
||||||
|
- `ui/docs/lobby.md` — `current_turn` note pointing at the new
|
||||||
|
game-state doc
|
||||||
|
|
||||||
Dependencies: Phases 9, 10.
|
Dependencies: Phases 9, 10.
|
||||||
|
|
||||||
Acceptance criteria:
|
Acceptance criteria (met):
|
||||||
|
|
||||||
- entering `/games/:id/map` for a game with real planets renders them
|
- entering `/games/:id/map` for a game with real planets renders them
|
||||||
on the map;
|
on the map;
|
||||||
@@ -1189,14 +1307,20 @@ Acceptance criteria:
|
|||||||
- view mode (torus / no-wrap) honours the per-game preference if set,
|
- view mode (torus / no-wrap) honours the per-game preference if set,
|
||||||
defaults to torus otherwise.
|
defaults to torus otherwise.
|
||||||
|
|
||||||
Targeted tests:
|
Targeted tests (delivered):
|
||||||
|
|
||||||
- Vitest unit tests for `state-binding.ts` translating report data to
|
- Vitest: `tests/state-binding.test.ts` covers the report→world
|
||||||
primitives;
|
translation across every planet kind plus malformed-dimension
|
||||||
- Playwright e2e against a local stack with seeded game state;
|
guards; `tests/game-state.test.ts` covers the store lifecycle
|
||||||
- regression test: zero-planet game shows the map empty without errors;
|
end-to-end with a stubbed `listMyGames` and a fake `GalaxyClient`;
|
||||||
- regression test: per-game wrap-scrolling preference persists and is
|
- Playwright e2e: `tests/e2e/game-shell-map.spec.ts` exercises the
|
||||||
applied on next visit to the game.
|
live data path with a mocked gateway across all four projects,
|
||||||
|
including the zero-planet regression and the
|
||||||
|
missing-membership error path;
|
||||||
|
- per-game wrap-scrolling preference round-trips through `Cache`
|
||||||
|
in `game-state.test.ts::setWrapMode persists across instances`;
|
||||||
|
- the existing Phase 10 chrome / navigation specs still pass
|
||||||
|
unchanged.
|
||||||
|
|
||||||
## Phase 12. Order Composer Skeleton
|
## Phase 12. Order Composer Skeleton
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
# Per-game state store
|
||||||
|
|
||||||
|
This document describes the per-game state owned by the in-game shell
|
||||||
|
layout. Phase 11 introduces the store and uses it for two consumers
|
||||||
|
(the header turn counter and the map view); later phases plug
|
||||||
|
inspector tabs, the order composer, and the calculator on top of the
|
||||||
|
same instance.
|
||||||
|
|
||||||
|
## Lifecycle
|
||||||
|
|
||||||
|
`routes/games/[id]/+layout.svelte` instantiates one `GameStateStore`
|
||||||
|
per game (the layout remounts when the user navigates to a different
|
||||||
|
game id, so each game gets a fresh store). The layout exposes the
|
||||||
|
instance through Svelte context under `GAME_STATE_CONTEXT_KEY`;
|
||||||
|
descendants read it via `getContext(GAME_STATE_CONTEXT_KEY)`.
|
||||||
|
|
||||||
|
The layout's `onMount` builds the `GalaxyClient`, loads `Cache`
|
||||||
|
through `loadStore()`, then calls `gameState.init({ client, cache,
|
||||||
|
gameId })`. `init`:
|
||||||
|
|
||||||
|
1. installs a `visibilitychange` listener on `document` so the report
|
||||||
|
is refreshed when the tab regains focus;
|
||||||
|
2. calls `setGame(gameId)`, which:
|
||||||
|
- reads the per-game wrap-mode preference from `Cache`
|
||||||
|
(`game-prefs / <gameId>/wrap-mode`, default `torus`);
|
||||||
|
- calls `lobby.my.games.list` and finds the game record (the
|
||||||
|
Phase 11 wire schema extension on `GameSummary` adds
|
||||||
|
`current_turn`); if the user is not a member, the store flips
|
||||||
|
to `error`;
|
||||||
|
- calls `user.games.report` for the discovered turn and decodes
|
||||||
|
the FlatBuffers response into a TS-friendly `GameReport` shape.
|
||||||
|
|
||||||
|
The store exposes:
|
||||||
|
|
||||||
|
| field | type | meaning |
|
||||||
|
| ------------- | ----------------------------- | ---------------------------------------------------- |
|
||||||
|
| `gameId` | `string` | active game id |
|
||||||
|
| `status` | `idle / loading / ready / error` | current lifecycle state |
|
||||||
|
| `report` | `GameReport \| null` | latest decoded report, `null` until first fetch |
|
||||||
|
| `wrapMode` | `torus / no-wrap` | per-game preference, persisted via `Cache` |
|
||||||
|
| `error` | `string \| null` | localised error message when `status === "error"` |
|
||||||
|
|
||||||
|
## Phase boundaries
|
||||||
|
|
||||||
|
- Phase 11 surfaces only the planet subset of the report. Later
|
||||||
|
phases extend `GameReport` and `decodeReport` as their slice of
|
||||||
|
the wire lands (ships, fleets, sciences, routes, battles, mail).
|
||||||
|
- Phase 26 wires history mode through `setTurn(turn)`. The store
|
||||||
|
already supports it; the navigator UI is what is missing.
|
||||||
|
- Phase 24 replaces the tab-focus refresh with push-event-driven
|
||||||
|
refreshes; the visibility listener stays as a fallback for
|
||||||
|
background tabs that miss a push.
|
||||||
|
- Phase 29 wires the wrap-mode toggle UI on top of `setWrapMode`.
|
||||||
|
|
||||||
|
## Why `current_turn` lives on `GameSummary`
|
||||||
|
|
||||||
|
The user-facing surface needs the current turn number to know which
|
||||||
|
report to fetch. Two alternatives were rejected:
|
||||||
|
|
||||||
|
- a brand-new `user.games.state` message — adds a full wire-flow
|
||||||
|
(fbs schema, transcoder, gateway routing, backend handler) for a
|
||||||
|
one-field response;
|
||||||
|
- hard-coding `turn=0` for all games — works for the dev sandbox
|
||||||
|
(which never advances past turn zero) but renders the initial
|
||||||
|
state for any real game past turn zero.
|
||||||
|
|
||||||
|
Extending `GameSummary` reuses the existing lobby pipeline; the
|
||||||
|
backend already tracks `current_turn` in its runtime projection
|
||||||
|
(`backend/internal/server/handlers_user_lobby_helpers.go`
|
||||||
|
`gameSummaryToWire` reads it from `g.RuntimeSnapshot.CurrentTurn`).
|
||||||
|
|
||||||
|
The wire change touches Phase 8's already-shipped catalogue, but the
|
||||||
|
`current_turn` field defaults to zero on the FB side, so existing
|
||||||
|
tests and the dev sandbox flow continue to work unchanged.
|
||||||
|
|
||||||
|
## State binding
|
||||||
|
|
||||||
|
`map/state-binding.ts::reportToWorld(report)` translates a
|
||||||
|
`GameReport` into a renderer-ready `World`. Phase 11 emits one Point
|
||||||
|
primitive per planet across all four kinds (local / other /
|
||||||
|
uninhabited / unidentified). Each kind gets a distinct fill colour,
|
||||||
|
fill alpha, and point radius so the four classes are
|
||||||
|
visually-distinguishable at a glance; later phases will refine the
|
||||||
|
colour palette as the visual language stabilises (Phase 35 polish).
|
||||||
|
|
||||||
|
The planet engine number is reused as the primitive id so a hit-test
|
||||||
|
result can resolve back to a planet without an extra lookup table.
|
||||||
|
|
||||||
|
## Refresh discipline
|
||||||
|
|
||||||
|
`refresh()` re-fetches the same turn snapshot. It is called by the
|
||||||
|
`visibilitychange` handler when `document.visibilityState ===
|
||||||
|
"visible"` and the store is already in `ready` state. The map view's
|
||||||
|
mount effect skips a re-render when the new snapshot's turn matches
|
||||||
|
the previously-mounted turn (and the wrap mode is unchanged), so a
|
||||||
|
no-op refresh does not flicker the canvas.
|
||||||
|
|
||||||
|
`setTurn(turn)` is the entry point for Phase 26 history mode:
|
||||||
|
calling it on a different turn loads that snapshot and the same
|
||||||
|
mount effect re-creates the renderer with the new world.
|
||||||
|
|
||||||
|
`setWrapMode(mode)` writes to `Cache` and updates the rune; the
|
||||||
|
map view's effect picks the change up and re-mounts the renderer
|
||||||
|
with the new mode.
|
||||||
+7
-1
@@ -18,7 +18,7 @@ width.
|
|||||||
| Section | Empty state | Source | Action |
|
| Section | Empty state | Source | Action |
|
||||||
| -------------------- | --------------------- | -------------------------- | --------------------------------------------------------- |
|
| -------------------- | --------------------- | -------------------------- | --------------------------------------------------------- |
|
||||||
| `create new game` | (always visible) | — | Navigates to `/lobby/create` |
|
| `create new game` | (always visible) | — | Navigates to `/lobby/create` |
|
||||||
| `my games` | `no games yet` | `lobby.my.games.list` | Click → `/games/:id/map` (placeholder until Phase 10) |
|
| `my games` | `no games yet` | `lobby.my.games.list` | Click → `/games/:id/map` |
|
||||||
| `pending invitations`| `no invitations` | `lobby.my.invites.list` | Accept (`lobby.invite.redeem`) / Decline (`lobby.invite.decline`) |
|
| `pending invitations`| `no invitations` | `lobby.my.invites.list` | Accept (`lobby.invite.redeem`) / Decline (`lobby.invite.decline`) |
|
||||||
| `my applications` | `no applications` | `lobby.my.applications.list` | Status badge (`pending` / `approved` / `rejected`) |
|
| `my applications` | `no applications` | `lobby.my.applications.list` | Status badge (`pending` / `approved` / `rejected`) |
|
||||||
| `public games` | `no public games` | `lobby.public.games.list` | Submit application via inline race-name form (`lobby.application.submit`) |
|
| `public games` | `no public games` | `lobby.public.games.list` | Submit application via inline race-name form (`lobby.application.submit`) |
|
||||||
@@ -27,6 +27,12 @@ The header preserves the device-session-id `<code>` block from the
|
|||||||
Phase 7 placeholder (kept as a debug affordance) plus a greeting if
|
Phase 7 placeholder (kept as a debug affordance) plus a greeting if
|
||||||
the gateway returns a `display_name` for the caller.
|
the gateway returns a `display_name` for the caller.
|
||||||
|
|
||||||
|
`GameSummary` carries an extra `current_turn` field (Phase 11
|
||||||
|
extension) that the lobby UI does not display directly — the in-game
|
||||||
|
shell reads it from the same payload to load the matching
|
||||||
|
`user.games.report` for the map view without an additional gateway
|
||||||
|
call. See [`game-state.md`](game-state.md) for the consumer's view.
|
||||||
|
|
||||||
## Application lifecycle
|
## Application lifecycle
|
||||||
|
|
||||||
`Submit application` on a public-game card toggles an inline race-name
|
`Submit application` on a public-game card toggles an inline race-name
|
||||||
|
|||||||
@@ -0,0 +1,178 @@
|
|||||||
|
// Typed wrapper around `GalaxyClient.executeCommand("user.games.report",
|
||||||
|
// ...)`. The signed-gRPC wire shape is the FlatBuffers
|
||||||
|
// `report.GameReportRequest` for the request and `report.Report` for
|
||||||
|
// the response (see `pkg/schema/fbs/report.fbs`). Phase 11 only
|
||||||
|
// surfaces the planet subset of the response — full ship / fleet /
|
||||||
|
// science decoding lands in Phases 17-22.
|
||||||
|
|
||||||
|
import { Builder, ByteBuffer } from "flatbuffers";
|
||||||
|
|
||||||
|
import type { GalaxyClient } from "./galaxy-client";
|
||||||
|
import { UUID } from "../proto/galaxy/fbs/common";
|
||||||
|
import {
|
||||||
|
GameReportRequest,
|
||||||
|
Report,
|
||||||
|
} from "../proto/galaxy/fbs/report";
|
||||||
|
|
||||||
|
const MESSAGE_TYPE = "user.games.report";
|
||||||
|
|
||||||
|
export class GameStateError extends Error {
|
||||||
|
readonly resultCode: string;
|
||||||
|
readonly code: string;
|
||||||
|
|
||||||
|
constructor(resultCode: string, code: string, message: string) {
|
||||||
|
super(message);
|
||||||
|
this.name = "GameStateError";
|
||||||
|
this.resultCode = resultCode;
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReportPlanet {
|
||||||
|
number: number;
|
||||||
|
name: string;
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
kind: "local" | "other" | "uninhabited" | "unidentified";
|
||||||
|
owner: string | null;
|
||||||
|
size: number | null;
|
||||||
|
resources: number | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GameReport {
|
||||||
|
turn: number;
|
||||||
|
mapWidth: number;
|
||||||
|
mapHeight: number;
|
||||||
|
planetCount: number;
|
||||||
|
planets: ReportPlanet[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchGameReport(
|
||||||
|
client: GalaxyClient,
|
||||||
|
gameId: string,
|
||||||
|
turn: number,
|
||||||
|
): Promise<GameReport> {
|
||||||
|
const builder = new Builder(64);
|
||||||
|
const [hi, lo] = uuidToHiLo(gameId);
|
||||||
|
const gameIdOffset = UUID.createUUID(builder, hi, lo);
|
||||||
|
GameReportRequest.startGameReportRequest(builder);
|
||||||
|
GameReportRequest.addGameId(builder, gameIdOffset);
|
||||||
|
GameReportRequest.addTurn(builder, turn);
|
||||||
|
builder.finish(GameReportRequest.endGameReportRequest(builder));
|
||||||
|
|
||||||
|
const result = await client.executeCommand(MESSAGE_TYPE, builder.asUint8Array());
|
||||||
|
if (result.resultCode !== "ok") {
|
||||||
|
const { code, message } = decodeErrorMessage(result.payloadBytes);
|
||||||
|
throw new GameStateError(result.resultCode, code, message);
|
||||||
|
}
|
||||||
|
const buffer = new ByteBuffer(result.payloadBytes);
|
||||||
|
const report = Report.getRootAsReport(buffer);
|
||||||
|
return decodeReport(report);
|
||||||
|
}
|
||||||
|
|
||||||
|
function decodeReport(report: Report): GameReport {
|
||||||
|
const planets: ReportPlanet[] = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < report.localPlanetLength(); i++) {
|
||||||
|
const p = report.localPlanet(i);
|
||||||
|
if (p === null) continue;
|
||||||
|
planets.push({
|
||||||
|
number: Number(p.number()),
|
||||||
|
name: p.name() ?? "",
|
||||||
|
x: p.x(),
|
||||||
|
y: p.y(),
|
||||||
|
kind: "local",
|
||||||
|
owner: null,
|
||||||
|
size: p.size(),
|
||||||
|
resources: p.resources(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < report.otherPlanetLength(); i++) {
|
||||||
|
const p = report.otherPlanet(i);
|
||||||
|
if (p === null) continue;
|
||||||
|
planets.push({
|
||||||
|
number: Number(p.number()),
|
||||||
|
name: p.name() ?? "",
|
||||||
|
x: p.x(),
|
||||||
|
y: p.y(),
|
||||||
|
kind: "other",
|
||||||
|
owner: p.owner() ?? null,
|
||||||
|
size: p.size(),
|
||||||
|
resources: p.resources(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < report.uninhabitedPlanetLength(); i++) {
|
||||||
|
const p = report.uninhabitedPlanet(i);
|
||||||
|
if (p === null) continue;
|
||||||
|
planets.push({
|
||||||
|
number: Number(p.number()),
|
||||||
|
name: p.name() ?? "",
|
||||||
|
x: p.x(),
|
||||||
|
y: p.y(),
|
||||||
|
kind: "uninhabited",
|
||||||
|
owner: null,
|
||||||
|
size: p.size(),
|
||||||
|
resources: p.resources(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < report.unidentifiedPlanetLength(); i++) {
|
||||||
|
const p = report.unidentifiedPlanet(i);
|
||||||
|
if (p === null) continue;
|
||||||
|
planets.push({
|
||||||
|
number: Number(p.number()),
|
||||||
|
name: "",
|
||||||
|
x: p.x(),
|
||||||
|
y: p.y(),
|
||||||
|
kind: "unidentified",
|
||||||
|
owner: null,
|
||||||
|
size: null,
|
||||||
|
resources: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
turn: Number(report.turn()),
|
||||||
|
mapWidth: report.width(),
|
||||||
|
mapHeight: report.height(),
|
||||||
|
planetCount: report.planetCount(),
|
||||||
|
planets,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* uuidToHiLo splits the canonical 36-character UUID string
|
||||||
|
* (`xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`) into the two big-endian
|
||||||
|
* uint64 halves used by `common.UUID`. Mirrors `pkg/transcoder/uuid.go`.
|
||||||
|
*/
|
||||||
|
export function uuidToHiLo(value: string): [bigint, bigint] {
|
||||||
|
const hex = value.replace(/-/g, "").toLowerCase();
|
||||||
|
if (hex.length !== 32 || /[^0-9a-f]/.test(hex)) {
|
||||||
|
throw new GameStateError(
|
||||||
|
"invalid_request",
|
||||||
|
"invalid_request",
|
||||||
|
`invalid uuid: ${value}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const hi = BigInt(`0x${hex.slice(0, 16)}`);
|
||||||
|
const lo = BigInt(`0x${hex.slice(16, 32)}`);
|
||||||
|
return [hi, lo];
|
||||||
|
}
|
||||||
|
|
||||||
|
function decodeErrorMessage(payload: Uint8Array): { code: string; message: string } {
|
||||||
|
if (payload.length === 0) {
|
||||||
|
return { code: "internal_error", message: "empty error payload" };
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const text = new TextDecoder().decode(payload);
|
||||||
|
const parsed = JSON.parse(text) as { code?: string; message?: string };
|
||||||
|
return {
|
||||||
|
code: typeof parsed.code === "string" ? parsed.code : "internal_error",
|
||||||
|
message: typeof parsed.message === "string" ? parsed.message : text,
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
return { code: "internal_error", message: "non-json error payload" };
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -55,6 +55,13 @@ export interface GameSummary {
|
|||||||
enrollmentEndsAt: Date;
|
enrollmentEndsAt: Date;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
|
/**
|
||||||
|
* Most recent turn number observed by backend's runtime
|
||||||
|
* projection. Zero before the engine produces its first
|
||||||
|
* snapshot. The map view uses this to fetch the matching
|
||||||
|
* `user.games.report` without a separate state query.
|
||||||
|
*/
|
||||||
|
currentTurn: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PublicGamesPage {
|
export interface PublicGamesPage {
|
||||||
@@ -319,6 +326,7 @@ function decodeGameSummary(summary: FbsGameSummary): GameSummary {
|
|||||||
enrollmentEndsAt: dateFromMs(summary.enrollmentEndsAtMs()),
|
enrollmentEndsAt: dateFromMs(summary.enrollmentEndsAtMs()),
|
||||||
createdAt: dateFromMs(summary.createdAtMs()),
|
createdAt: dateFromMs(summary.createdAtMs()),
|
||||||
updatedAt: dateFromMs(summary.updatedAtMs()),
|
updatedAt: dateFromMs(summary.updatedAtMs()),
|
||||||
|
currentTurn: summary.currentTurn(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +1,187 @@
|
|||||||
<!--
|
<!--
|
||||||
Phase 10 stub for the map active view. Phase 11 swaps this for the
|
Phase 11 map active view: integrates the Phase 9 renderer with the
|
||||||
live renderer integration described in `ui/PLAN.md` Phase 11. The
|
per-game `GameStateStore` provided through context by
|
||||||
stub keeps the same `data-testid` so Phase 11's spec replaces the
|
`routes/games/[id]/+layout.svelte`. The view mounts the renderer
|
||||||
copy assertion without touching navigation.
|
once the store has produced a report and re-mounts when the
|
||||||
|
report's turn changes (a refresh that returns the same turn keeps
|
||||||
|
the existing renderer instance alive). Empty-planet reports render
|
||||||
|
the empty world without errors — the regression test in
|
||||||
|
`tests/e2e/game-shell-map.spec.ts` covers this.
|
||||||
|
|
||||||
|
Phase 9 owns the renderer's hit-test and pan/zoom semantics; Phase 13
|
||||||
|
will plug map clicks into the inspector. Phase 29 wires the wrap-mode
|
||||||
|
toggle on top of the per-game `wrapMode` preference the store
|
||||||
|
already manages.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { getContext, onDestroy, onMount, untrack } from "svelte";
|
||||||
import { i18n } from "$lib/i18n/index.svelte";
|
import { i18n } from "$lib/i18n/index.svelte";
|
||||||
|
import {
|
||||||
|
createRenderer,
|
||||||
|
minScaleNoWrap,
|
||||||
|
type RendererHandle,
|
||||||
|
} from "../../map/index";
|
||||||
|
import { reportToWorld } from "../../map/state-binding";
|
||||||
|
import {
|
||||||
|
GAME_STATE_CONTEXT_KEY,
|
||||||
|
type GameStateStore,
|
||||||
|
} from "$lib/game-state.svelte";
|
||||||
|
|
||||||
|
const store = getContext<GameStateStore | undefined>(GAME_STATE_CONTEXT_KEY);
|
||||||
|
|
||||||
|
let canvasEl: HTMLCanvasElement | null = $state(null);
|
||||||
|
let containerEl: HTMLDivElement | null = $state(null);
|
||||||
|
let mountError: string | null = $state(null);
|
||||||
|
|
||||||
|
let handle: RendererHandle | null = null;
|
||||||
|
let mountedTurn: number | null = null;
|
||||||
|
let mountedGameId: string | null = null;
|
||||||
|
let onResize: (() => void) | null = null;
|
||||||
|
let mounted = false;
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
const report = store?.report;
|
||||||
|
const status = store?.status ?? "idle";
|
||||||
|
// Track the wrap mode so the renderer remounts when Phase 29's
|
||||||
|
// toggle UI flips it; the read here also subscribes the effect.
|
||||||
|
const mode = store?.wrapMode ?? "torus";
|
||||||
|
const gameId = store?.gameId ?? "";
|
||||||
|
if (!mounted || canvasEl === null || containerEl === null) return;
|
||||||
|
if (status !== "ready" || !report) return;
|
||||||
|
|
||||||
|
// Skip a re-mount when the same turn is reloaded for the same
|
||||||
|
// game and the wrap mode did not change. The store's `refresh`
|
||||||
|
// path lands here on tab focus; an unchanged snapshot must not
|
||||||
|
// flicker the canvas.
|
||||||
|
const sameSnapshot =
|
||||||
|
mountedTurn === report.turn &&
|
||||||
|
mountedGameId === gameId &&
|
||||||
|
handle !== null &&
|
||||||
|
handle.getMode() === mode;
|
||||||
|
if (sameSnapshot) return;
|
||||||
|
|
||||||
|
untrack(() => {
|
||||||
|
void mountRenderer(report, mode);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
async function mountRenderer(
|
||||||
|
report: NonNullable<GameStateStore["report"]>,
|
||||||
|
mode: "torus" | "no-wrap",
|
||||||
|
): Promise<void> {
|
||||||
|
if (canvasEl === null || containerEl === null) return;
|
||||||
|
if (handle !== null) {
|
||||||
|
handle.dispose();
|
||||||
|
handle = null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const world = reportToWorld(report);
|
||||||
|
handle = await createRenderer({
|
||||||
|
canvas: canvasEl,
|
||||||
|
world,
|
||||||
|
mode,
|
||||||
|
preference: ["webgpu", "webgl"],
|
||||||
|
});
|
||||||
|
handle.viewport.moveCenter(world.width / 2, world.height / 2);
|
||||||
|
const minScale = minScaleNoWrap(
|
||||||
|
{
|
||||||
|
widthPx: containerEl.clientWidth,
|
||||||
|
heightPx: containerEl.clientHeight,
|
||||||
|
},
|
||||||
|
world,
|
||||||
|
);
|
||||||
|
handle.viewport.setZoom(minScale * 1.05, true);
|
||||||
|
if (mode === "no-wrap") handle.setMode("no-wrap");
|
||||||
|
mountedTurn = report.turn;
|
||||||
|
mountedGameId = store?.gameId ?? "";
|
||||||
|
mountError = null;
|
||||||
|
} catch (err) {
|
||||||
|
mountError = err instanceof Error ? err.message : String(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
mounted = true;
|
||||||
|
onResize = (): void => {
|
||||||
|
if (handle === null || containerEl === null) return;
|
||||||
|
handle.resize(containerEl.clientWidth, containerEl.clientHeight);
|
||||||
|
};
|
||||||
|
window.addEventListener("resize", onResize);
|
||||||
|
});
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
mounted = false;
|
||||||
|
if (onResize !== null) {
|
||||||
|
window.removeEventListener("resize", onResize);
|
||||||
|
onResize = null;
|
||||||
|
}
|
||||||
|
if (handle !== null) {
|
||||||
|
handle.dispose();
|
||||||
|
handle = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section class="active-view" data-testid="active-view-map">
|
<section class="active-view" data-testid="active-view-map" data-status={store?.status ?? "idle"}>
|
||||||
<h2>{i18n.t("game.view.map")}</h2>
|
{#if store?.status === "error"}
|
||||||
<p>{i18n.t("game.shell.coming_soon")}</p>
|
<p class="overlay error" role="alert" data-testid="map-error">
|
||||||
|
{store.error ?? "request failed"}
|
||||||
|
</p>
|
||||||
|
{:else if mountError !== null}
|
||||||
|
<p class="overlay error" role="alert" data-testid="map-mount-error">
|
||||||
|
{mountError}
|
||||||
|
</p>
|
||||||
|
{:else if store?.status !== "ready"}
|
||||||
|
<p class="overlay" data-testid="map-loading">{i18n.t("common.loading")}</p>
|
||||||
|
{/if}
|
||||||
|
<div
|
||||||
|
class="canvas-wrap"
|
||||||
|
data-testid="map-canvas-wrap"
|
||||||
|
data-planet-count={store?.report?.planets.length ?? 0}
|
||||||
|
bind:this={containerEl}
|
||||||
|
>
|
||||||
|
<canvas bind:this={canvasEl}></canvas>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.active-view {
|
.active-view {
|
||||||
padding: 1.5rem;
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
.canvas-wrap {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #0a0e1a;
|
||||||
|
}
|
||||||
|
canvas {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0.75rem;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
padding: 0.4rem 0.9rem;
|
||||||
|
background: rgba(20, 24, 42, 0.85);
|
||||||
|
color: #e8eaf6;
|
||||||
|
border: 1px solid #2a3150;
|
||||||
|
border-radius: 6px;
|
||||||
|
z-index: 10;
|
||||||
font-family: system-ui, sans-serif;
|
font-family: system-ui, sans-serif;
|
||||||
}
|
font-size: 0.9rem;
|
||||||
.active-view h2 {
|
|
||||||
margin: 0 0 0.5rem;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
.active-view p {
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: #555;
|
}
|
||||||
|
.overlay.error {
|
||||||
|
background: #4a1820;
|
||||||
|
border-color: #6d2530;
|
||||||
|
color: #ffb4b4;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -0,0 +1,200 @@
|
|||||||
|
// Per-game runtime state owned by the in-game shell layout
|
||||||
|
// (`routes/games/[id]/+layout.svelte`). The store discovers the
|
||||||
|
// game's current turn through `lobby.my.games.list`, fetches the
|
||||||
|
// matching `user.games.report`, and exposes a TS-friendly `GameReport`
|
||||||
|
// snapshot to every consumer (header turn counter, map view,
|
||||||
|
// inspector tabs in later phases).
|
||||||
|
//
|
||||||
|
// Phase 11 covers planets only; later phases extend the report
|
||||||
|
// surface as their slice of state lands. Every consumer reads from
|
||||||
|
// the same store instance — instantiation per game guarantees the
|
||||||
|
// layout remount on `gameId` change reseeds the snapshot, while
|
||||||
|
// navigation between active views inside the same game keeps the
|
||||||
|
// instance alive (state-preservation rule, see ui/docs/navigation.md).
|
||||||
|
|
||||||
|
import {
|
||||||
|
GameStateError,
|
||||||
|
fetchGameReport,
|
||||||
|
type GameReport,
|
||||||
|
} from "../api/game-state";
|
||||||
|
import { listMyGames, type GameSummary } from "../api/lobby";
|
||||||
|
import type { GalaxyClient } from "../api/galaxy-client";
|
||||||
|
import type { Cache } from "../platform/store/index";
|
||||||
|
import type { WrapMode } from "../map/world";
|
||||||
|
|
||||||
|
const PREF_NAMESPACE = "game-prefs";
|
||||||
|
const PREF_KEY_WRAP_MODE = (gameId: string) => `${gameId}/wrap-mode`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GAME_STATE_CONTEXT_KEY is the Svelte context key the in-game shell
|
||||||
|
* layout uses to expose its `GameStateStore` instance to descendants.
|
||||||
|
* Header / map / inspector children resolve the store via
|
||||||
|
* `getContext(GAME_STATE_CONTEXT_KEY)`.
|
||||||
|
*/
|
||||||
|
export const GAME_STATE_CONTEXT_KEY = Symbol("game-state");
|
||||||
|
|
||||||
|
type Status = "idle" | "loading" | "ready" | "error";
|
||||||
|
|
||||||
|
export class GameStateStore {
|
||||||
|
gameId: string = $state("");
|
||||||
|
status: Status = $state("idle");
|
||||||
|
report: GameReport | null = $state(null);
|
||||||
|
wrapMode: WrapMode = $state("torus");
|
||||||
|
error: string | null = $state(null);
|
||||||
|
|
||||||
|
private client: GalaxyClient | null = null;
|
||||||
|
private cache: Cache | null = null;
|
||||||
|
private currentTurn = 0;
|
||||||
|
private destroyed = false;
|
||||||
|
private visibilityListener: (() => void) | null = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* init kicks off the per-game lifecycle. The call is idempotent on
|
||||||
|
* the same `gameId`; calling with a different game forwards through
|
||||||
|
* `setGame` so the layout can hand off across navigations.
|
||||||
|
*/
|
||||||
|
async init(opts: {
|
||||||
|
client: GalaxyClient;
|
||||||
|
cache: Cache;
|
||||||
|
gameId: string;
|
||||||
|
}): Promise<void> {
|
||||||
|
this.client = opts.client;
|
||||||
|
this.cache = opts.cache;
|
||||||
|
await this.setGame(opts.gameId);
|
||||||
|
this.installVisibilityListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setGame switches the store to the supplied game id, fetches the
|
||||||
|
* matching lobby record to discover `current_turn`, then loads the
|
||||||
|
* report. Failure paths surface through `status === "error"` and
|
||||||
|
* the matching `error` string (already localised by the caller).
|
||||||
|
*/
|
||||||
|
async setGame(gameId: string): Promise<void> {
|
||||||
|
if (this.client === null || this.cache === null) {
|
||||||
|
throw new Error("game-state: setGame called before init");
|
||||||
|
}
|
||||||
|
this.gameId = gameId;
|
||||||
|
this.status = "loading";
|
||||||
|
this.error = null;
|
||||||
|
this.report = null;
|
||||||
|
|
||||||
|
this.wrapMode = await readWrapMode(this.cache, gameId);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const summary = await this.findGame(gameId);
|
||||||
|
if (summary === null) {
|
||||||
|
this.status = "error";
|
||||||
|
this.error = `game ${gameId} is not in your list`;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.currentTurn = summary.currentTurn;
|
||||||
|
await this.loadTurn(summary.currentTurn);
|
||||||
|
} catch (err) {
|
||||||
|
if (this.destroyed) return;
|
||||||
|
this.status = "error";
|
||||||
|
this.error = describe(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setTurn loads a different turn snapshot — used by Phase 26 history
|
||||||
|
* mode. The current turn stays at whatever `setGame` discovered;
|
||||||
|
* calling without an argument refetches the same turn.
|
||||||
|
*/
|
||||||
|
async setTurn(turn: number): Promise<void> {
|
||||||
|
if (this.client === null) return;
|
||||||
|
this.status = "loading";
|
||||||
|
this.error = null;
|
||||||
|
try {
|
||||||
|
await this.loadTurn(turn);
|
||||||
|
} catch (err) {
|
||||||
|
this.status = "error";
|
||||||
|
this.error = describe(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* refresh re-fetches the report at the current turn. Called on
|
||||||
|
* window `visibilitychange` so the map and the turn counter stay
|
||||||
|
* fresh after the user returns to the tab.
|
||||||
|
*/
|
||||||
|
refresh(): Promise<void> {
|
||||||
|
return this.setTurn(this.currentTurn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setWrapMode persists the per-game preference into Cache so the
|
||||||
|
* next visit to the game restores it. Phase 29 wires the toggle UI;
|
||||||
|
* Phase 11 only reads through `wrapMode` and writes via this method.
|
||||||
|
*/
|
||||||
|
async setWrapMode(mode: WrapMode): Promise<void> {
|
||||||
|
this.wrapMode = mode;
|
||||||
|
if (this.cache !== null) {
|
||||||
|
await this.cache.put(PREF_NAMESPACE, PREF_KEY_WRAP_MODE(this.gameId), mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* failBootstrap is used by the layout to surface errors that
|
||||||
|
* happen *before* `init` could be reached (missing keypair, missing
|
||||||
|
* gateway public key, core/store load failure). It does not need
|
||||||
|
* `init` to have run first.
|
||||||
|
*/
|
||||||
|
failBootstrap(message: string): void {
|
||||||
|
this.status = "error";
|
||||||
|
this.error = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispose(): void {
|
||||||
|
this.destroyed = true;
|
||||||
|
if (this.visibilityListener !== null && typeof document !== "undefined") {
|
||||||
|
document.removeEventListener("visibilitychange", this.visibilityListener);
|
||||||
|
}
|
||||||
|
this.visibilityListener = null;
|
||||||
|
this.client = null;
|
||||||
|
this.cache = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async findGame(gameId: string): Promise<GameSummary | null> {
|
||||||
|
if (this.client === null) return null;
|
||||||
|
const games = await listMyGames(this.client);
|
||||||
|
return games.find((g) => g.gameId === gameId) ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async loadTurn(turn: number): Promise<void> {
|
||||||
|
if (this.client === null) return;
|
||||||
|
const report = await fetchGameReport(this.client, this.gameId, turn);
|
||||||
|
if (this.destroyed) return;
|
||||||
|
this.report = report;
|
||||||
|
this.currentTurn = turn;
|
||||||
|
this.status = "ready";
|
||||||
|
}
|
||||||
|
|
||||||
|
private installVisibilityListener(): void {
|
||||||
|
if (typeof document === "undefined") return;
|
||||||
|
const listener = (): void => {
|
||||||
|
if (document.visibilityState === "visible" && this.status === "ready") {
|
||||||
|
void this.refresh();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.visibilityListener = listener;
|
||||||
|
document.addEventListener("visibilitychange", listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function readWrapMode(cache: Cache, gameId: string): Promise<WrapMode> {
|
||||||
|
const stored = await cache.get<string>(PREF_NAMESPACE, PREF_KEY_WRAP_MODE(gameId));
|
||||||
|
if (stored === "no-wrap") return "no-wrap";
|
||||||
|
return "torus";
|
||||||
|
}
|
||||||
|
|
||||||
|
function describe(err: unknown): string {
|
||||||
|
if (err instanceof GameStateError) {
|
||||||
|
return err.message;
|
||||||
|
}
|
||||||
|
if (err instanceof Error) {
|
||||||
|
return err.message;
|
||||||
|
}
|
||||||
|
return "request failed";
|
||||||
|
}
|
||||||
@@ -1,15 +1,31 @@
|
|||||||
<!--
|
<!--
|
||||||
Phase 10 placeholder turn counter. The displayed value is the static
|
Phase 11 turn counter: reads the live turn number from the per-game
|
||||||
`?` glyph from `game.shell.turn_unknown`; Phase 11 swaps the source
|
`GameStateStore` provided through context by
|
||||||
to the live game state. The wrapping span is kept as the public
|
`routes/games/[id]/+layout.svelte`. Renders the static `?` placeholder
|
||||||
shape so Phase 11 only needs to replace the inner text.
|
from `game.shell.turn_unknown` when the store has not yet produced a
|
||||||
|
report (boot, network error, no membership) so the header chrome
|
||||||
|
keeps its width across loading transitions.
|
||||||
|
|
||||||
|
Phase 26 will turn this into a clickable trigger that opens the
|
||||||
|
turn navigator; Phase 24 wires push-event-driven turn-ready toasts
|
||||||
|
that may flash this counter when a new turn is ready.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { getContext } from "svelte";
|
||||||
import { i18n } from "$lib/i18n/index.svelte";
|
import { i18n } from "$lib/i18n/index.svelte";
|
||||||
|
import { GAME_STATE_CONTEXT_KEY, type GameStateStore } from "$lib/game-state.svelte";
|
||||||
|
|
||||||
|
const store = getContext<GameStateStore | undefined>(GAME_STATE_CONTEXT_KEY);
|
||||||
|
|
||||||
|
const display = $derived.by(() => {
|
||||||
|
const report = store?.report ?? null;
|
||||||
|
if (report === null) return i18n.t("game.shell.turn_unknown");
|
||||||
|
return String(report.turn);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<span class="turn" data-testid="turn-counter">
|
<span class="turn" data-testid="turn-counter" data-turn={display}>
|
||||||
{i18n.t("game.shell.turn_label")} {i18n.t("game.shell.turn_unknown")}
|
{i18n.t("game.shell.turn_label")} {display}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
// State binding between the typed game report and the renderer's
|
||||||
|
// World. Phase 11 only emits primitives for planets; later phases
|
||||||
|
// extend the binding with ship-class reach circles (Phase 17 / 18),
|
||||||
|
// hyperspace and incoming groups (Phase 11+ via separate primitives),
|
||||||
|
// cargo routes (Phase 16), reach / visibility zones (Phase 17), and
|
||||||
|
// battle / bombing markers (Phase 27).
|
||||||
|
//
|
||||||
|
// The four planet kinds in the report each map to a distinct style so
|
||||||
|
// the user can tell own / other-race / uninhabited / unidentified
|
||||||
|
// planets apart at a glance. The exact colours are Phase 11 defaults
|
||||||
|
// chosen against the dark theme; Phase 35 polish picks final
|
||||||
|
// colours and adds theme switching.
|
||||||
|
|
||||||
|
import type { GameReport, ReportPlanet } from "../api/game-state";
|
||||||
|
import { World, type Primitive, type Style } from "./world";
|
||||||
|
|
||||||
|
const STYLE_LOCAL: Style = {
|
||||||
|
fillColor: 0x6dd2ff,
|
||||||
|
fillAlpha: 1,
|
||||||
|
pointRadiusPx: 6,
|
||||||
|
};
|
||||||
|
|
||||||
|
const STYLE_OTHER: Style = {
|
||||||
|
fillColor: 0xff8a65,
|
||||||
|
fillAlpha: 1,
|
||||||
|
pointRadiusPx: 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
const STYLE_UNINHABITED: Style = {
|
||||||
|
fillColor: 0xb0bec5,
|
||||||
|
fillAlpha: 0.85,
|
||||||
|
pointRadiusPx: 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
const STYLE_UNIDENTIFIED: Style = {
|
||||||
|
fillColor: 0x546e7a,
|
||||||
|
fillAlpha: 0.7,
|
||||||
|
pointRadiusPx: 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
// PlanetIDs occupy the [0, 4_000_000_000) range — well below
|
||||||
|
// JavaScript's `Number.MAX_SAFE_INTEGER` — so the engine `number` (uint64)
|
||||||
|
// fits in a primitive id (number) without truncation. The binding
|
||||||
|
// uses the engine number directly as the primitive id so later phases
|
||||||
|
// can resolve a planet by its hit-test result without an extra
|
||||||
|
// lookup table.
|
||||||
|
function styleFor(kind: ReportPlanet["kind"]): Style {
|
||||||
|
switch (kind) {
|
||||||
|
case "local":
|
||||||
|
return STYLE_LOCAL;
|
||||||
|
case "other":
|
||||||
|
return STYLE_OTHER;
|
||||||
|
case "uninhabited":
|
||||||
|
return STYLE_UNINHABITED;
|
||||||
|
case "unidentified":
|
||||||
|
return STYLE_UNIDENTIFIED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function priorityFor(kind: ReportPlanet["kind"]): number {
|
||||||
|
switch (kind) {
|
||||||
|
case "local":
|
||||||
|
return 4;
|
||||||
|
case "other":
|
||||||
|
return 3;
|
||||||
|
case "uninhabited":
|
||||||
|
return 2;
|
||||||
|
case "unidentified":
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reportToWorld translates a GameReport into a renderer-ready World
|
||||||
|
* containing one Point primitive per planet (all four planet kinds).
|
||||||
|
* The world rectangle matches `report.mapWidth` × `report.mapHeight`.
|
||||||
|
*
|
||||||
|
* If the report carries zero planets (turn-zero edge cases or seeded
|
||||||
|
* tests), the World is still well-formed: the renderer mounts on an
|
||||||
|
* empty primitive list without errors.
|
||||||
|
*/
|
||||||
|
export function reportToWorld(report: GameReport): World {
|
||||||
|
const primitives: Primitive[] = [];
|
||||||
|
for (const planet of report.planets) {
|
||||||
|
primitives.push({
|
||||||
|
kind: "point",
|
||||||
|
id: planet.number,
|
||||||
|
priority: priorityFor(planet.kind),
|
||||||
|
style: styleFor(planet.kind),
|
||||||
|
hitSlopPx: 0,
|
||||||
|
x: planet.x,
|
||||||
|
y: planet.y,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const width = report.mapWidth > 0 ? report.mapWidth : 1;
|
||||||
|
const height = report.mapHeight > 0 ? report.mapHeight : 1;
|
||||||
|
return new World(width, height, primitives);
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
export { UUID, UUIDT } from './common/uuid.js';
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export class UUID implements flatbuffers.IUnpackableObject<UUIDT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):UUID {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
hi():bigint {
|
||||||
|
return this.bb!.readUint64(this.bb_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
lo():bigint {
|
||||||
|
return this.bb!.readUint64(this.bb_pos + 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static sizeOf():number {
|
||||||
|
return 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createUUID(builder:flatbuffers.Builder, hi: bigint, lo: bigint):flatbuffers.Offset {
|
||||||
|
builder.prep(8, 16);
|
||||||
|
builder.writeInt64(BigInt(lo ?? 0));
|
||||||
|
builder.writeInt64(BigInt(hi ?? 0));
|
||||||
|
return builder.offset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpack(): UUIDT {
|
||||||
|
return new UUIDT(
|
||||||
|
this.hi(),
|
||||||
|
this.lo()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: UUIDT): void {
|
||||||
|
_o.hi = this.hi();
|
||||||
|
_o.lo = this.lo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class UUIDT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public hi: bigint = BigInt('0'),
|
||||||
|
public lo: bigint = BigInt('0')
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
return UUID.createUUID(builder,
|
||||||
|
this.hi,
|
||||||
|
this.lo
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -84,8 +84,13 @@ updatedAtMs():bigint {
|
|||||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentTurn():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 24);
|
||||||
|
return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
static startGameSummary(builder:flatbuffers.Builder) {
|
static startGameSummary(builder:flatbuffers.Builder) {
|
||||||
builder.startObject(10);
|
builder.startObject(11);
|
||||||
}
|
}
|
||||||
|
|
||||||
static addGameId(builder:flatbuffers.Builder, gameIdOffset:flatbuffers.Offset) {
|
static addGameId(builder:flatbuffers.Builder, gameIdOffset:flatbuffers.Offset) {
|
||||||
@@ -128,12 +133,16 @@ static addUpdatedAtMs(builder:flatbuffers.Builder, updatedAtMs:bigint) {
|
|||||||
builder.addFieldInt64(9, updatedAtMs, BigInt('0'));
|
builder.addFieldInt64(9, updatedAtMs, BigInt('0'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static addCurrentTurn(builder:flatbuffers.Builder, currentTurn:number) {
|
||||||
|
builder.addFieldInt32(10, currentTurn, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static endGameSummary(builder:flatbuffers.Builder):flatbuffers.Offset {
|
static endGameSummary(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
const offset = builder.endObject();
|
const offset = builder.endObject();
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static createGameSummary(builder:flatbuffers.Builder, gameIdOffset:flatbuffers.Offset, gameNameOffset:flatbuffers.Offset, gameTypeOffset:flatbuffers.Offset, statusOffset:flatbuffers.Offset, ownerUserIdOffset:flatbuffers.Offset, minPlayers:number, maxPlayers:number, enrollmentEndsAtMs:bigint, createdAtMs:bigint, updatedAtMs:bigint):flatbuffers.Offset {
|
static createGameSummary(builder:flatbuffers.Builder, gameIdOffset:flatbuffers.Offset, gameNameOffset:flatbuffers.Offset, gameTypeOffset:flatbuffers.Offset, statusOffset:flatbuffers.Offset, ownerUserIdOffset:flatbuffers.Offset, minPlayers:number, maxPlayers:number, enrollmentEndsAtMs:bigint, createdAtMs:bigint, updatedAtMs:bigint, currentTurn:number):flatbuffers.Offset {
|
||||||
GameSummary.startGameSummary(builder);
|
GameSummary.startGameSummary(builder);
|
||||||
GameSummary.addGameId(builder, gameIdOffset);
|
GameSummary.addGameId(builder, gameIdOffset);
|
||||||
GameSummary.addGameName(builder, gameNameOffset);
|
GameSummary.addGameName(builder, gameNameOffset);
|
||||||
@@ -145,6 +154,7 @@ static createGameSummary(builder:flatbuffers.Builder, gameIdOffset:flatbuffers.O
|
|||||||
GameSummary.addEnrollmentEndsAtMs(builder, enrollmentEndsAtMs);
|
GameSummary.addEnrollmentEndsAtMs(builder, enrollmentEndsAtMs);
|
||||||
GameSummary.addCreatedAtMs(builder, createdAtMs);
|
GameSummary.addCreatedAtMs(builder, createdAtMs);
|
||||||
GameSummary.addUpdatedAtMs(builder, updatedAtMs);
|
GameSummary.addUpdatedAtMs(builder, updatedAtMs);
|
||||||
|
GameSummary.addCurrentTurn(builder, currentTurn);
|
||||||
return GameSummary.endGameSummary(builder);
|
return GameSummary.endGameSummary(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +169,8 @@ unpack(): GameSummaryT {
|
|||||||
this.maxPlayers(),
|
this.maxPlayers(),
|
||||||
this.enrollmentEndsAtMs(),
|
this.enrollmentEndsAtMs(),
|
||||||
this.createdAtMs(),
|
this.createdAtMs(),
|
||||||
this.updatedAtMs()
|
this.updatedAtMs(),
|
||||||
|
this.currentTurn()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,6 +186,7 @@ unpackTo(_o: GameSummaryT): void {
|
|||||||
_o.enrollmentEndsAtMs = this.enrollmentEndsAtMs();
|
_o.enrollmentEndsAtMs = this.enrollmentEndsAtMs();
|
||||||
_o.createdAtMs = this.createdAtMs();
|
_o.createdAtMs = this.createdAtMs();
|
||||||
_o.updatedAtMs = this.updatedAtMs();
|
_o.updatedAtMs = this.updatedAtMs();
|
||||||
|
_o.currentTurn = this.currentTurn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,7 +201,8 @@ constructor(
|
|||||||
public maxPlayers: number = 0,
|
public maxPlayers: number = 0,
|
||||||
public enrollmentEndsAtMs: bigint = BigInt('0'),
|
public enrollmentEndsAtMs: bigint = BigInt('0'),
|
||||||
public createdAtMs: bigint = BigInt('0'),
|
public createdAtMs: bigint = BigInt('0'),
|
||||||
public updatedAtMs: bigint = BigInt('0')
|
public updatedAtMs: bigint = BigInt('0'),
|
||||||
|
public currentTurn: number = 0
|
||||||
){}
|
){}
|
||||||
|
|
||||||
|
|
||||||
@@ -210,7 +223,8 @@ pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
|||||||
this.maxPlayers,
|
this.maxPlayers,
|
||||||
this.enrollmentEndsAtMs,
|
this.enrollmentEndsAtMs,
|
||||||
this.createdAtMs,
|
this.createdAtMs,
|
||||||
this.updatedAtMs
|
this.updatedAtMs,
|
||||||
|
this.currentTurn
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
export { Bombing, BombingT } from './report/bombing.js';
|
||||||
|
export { GameReportRequest, GameReportRequestT } from './report/game-report-request.js';
|
||||||
|
export { IncomingGroup, IncomingGroupT } from './report/incoming-group.js';
|
||||||
|
export { LocalFleet, LocalFleetT } from './report/local-fleet.js';
|
||||||
|
export { LocalGroup, LocalGroupT } from './report/local-group.js';
|
||||||
|
export { LocalPlanet, LocalPlanetT } from './report/local-planet.js';
|
||||||
|
export { OtherGroup, OtherGroupT } from './report/other-group.js';
|
||||||
|
export { OtherPlanet, OtherPlanetT } from './report/other-planet.js';
|
||||||
|
export { OtherScience, OtherScienceT } from './report/other-science.js';
|
||||||
|
export { OthersShipClass, OthersShipClassT } from './report/others-ship-class.js';
|
||||||
|
export { Player, PlayerT } from './report/player.js';
|
||||||
|
export { Report, ReportT } from './report/report.js';
|
||||||
|
export { Route, RouteT } from './report/route.js';
|
||||||
|
export { RouteEntry, RouteEntryT } from './report/route-entry.js';
|
||||||
|
export { Science, ScienceT } from './report/science.js';
|
||||||
|
export { ShipClass, ShipClassT } from './report/ship-class.js';
|
||||||
|
export { ShipProduction, ShipProductionT } from './report/ship-production.js';
|
||||||
|
export { TechEntry, TechEntryT } from './report/tech-entry.js';
|
||||||
|
export { UnidentifiedGroup, UnidentifiedGroupT } from './report/unidentified-group.js';
|
||||||
|
export { UnidentifiedPlanet, UnidentifiedPlanetT } from './report/unidentified-planet.js';
|
||||||
|
export { UninhabitedPlanet, UninhabitedPlanetT } from './report/uninhabited-planet.js';
|
||||||
@@ -0,0 +1,241 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export class Bombing implements flatbuffers.IUnpackableObject<BombingT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):Bombing {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRootAsBombing(bb:flatbuffers.ByteBuffer, obj?:Bombing):Bombing {
|
||||||
|
return (obj || new Bombing()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSizePrefixedRootAsBombing(bb:flatbuffers.ByteBuffer, obj?:Bombing):Bombing {
|
||||||
|
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||||
|
return (obj || new Bombing()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
number():bigint {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
planet():string|null
|
||||||
|
planet(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
planet(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
owner():string|null
|
||||||
|
owner(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
owner(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
attacker():string|null
|
||||||
|
attacker(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
attacker(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
production():string|null
|
||||||
|
production(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
production(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
industry():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
population():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 16);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
colonists():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 18);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
capital():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 20);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
material():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 22);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
attackPower():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 24);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
wiped():boolean {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 26);
|
||||||
|
return offset ? !!this.bb!.readInt8(this.bb_pos + offset) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static startBombing(builder:flatbuffers.Builder) {
|
||||||
|
builder.startObject(12);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addNumber(builder:flatbuffers.Builder, number:bigint) {
|
||||||
|
builder.addFieldInt64(0, number, BigInt('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static addPlanet(builder:flatbuffers.Builder, planetOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(1, planetOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addOwner(builder:flatbuffers.Builder, ownerOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(2, ownerOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addAttacker(builder:flatbuffers.Builder, attackerOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(3, attackerOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addProduction(builder:flatbuffers.Builder, productionOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(4, productionOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addIndustry(builder:flatbuffers.Builder, industry:number) {
|
||||||
|
builder.addFieldFloat32(5, industry, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addPopulation(builder:flatbuffers.Builder, population:number) {
|
||||||
|
builder.addFieldFloat32(6, population, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addColonists(builder:flatbuffers.Builder, colonists:number) {
|
||||||
|
builder.addFieldFloat32(7, colonists, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addCapital(builder:flatbuffers.Builder, capital:number) {
|
||||||
|
builder.addFieldFloat32(8, capital, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addMaterial(builder:flatbuffers.Builder, material:number) {
|
||||||
|
builder.addFieldFloat32(9, material, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addAttackPower(builder:flatbuffers.Builder, attackPower:number) {
|
||||||
|
builder.addFieldFloat32(10, attackPower, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addWiped(builder:flatbuffers.Builder, wiped:boolean) {
|
||||||
|
builder.addFieldInt8(11, +wiped, +false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static endBombing(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
|
const offset = builder.endObject();
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createBombing(builder:flatbuffers.Builder, number:bigint, planetOffset:flatbuffers.Offset, ownerOffset:flatbuffers.Offset, attackerOffset:flatbuffers.Offset, productionOffset:flatbuffers.Offset, industry:number, population:number, colonists:number, capital:number, material:number, attackPower:number, wiped:boolean):flatbuffers.Offset {
|
||||||
|
Bombing.startBombing(builder);
|
||||||
|
Bombing.addNumber(builder, number);
|
||||||
|
Bombing.addPlanet(builder, planetOffset);
|
||||||
|
Bombing.addOwner(builder, ownerOffset);
|
||||||
|
Bombing.addAttacker(builder, attackerOffset);
|
||||||
|
Bombing.addProduction(builder, productionOffset);
|
||||||
|
Bombing.addIndustry(builder, industry);
|
||||||
|
Bombing.addPopulation(builder, population);
|
||||||
|
Bombing.addColonists(builder, colonists);
|
||||||
|
Bombing.addCapital(builder, capital);
|
||||||
|
Bombing.addMaterial(builder, material);
|
||||||
|
Bombing.addAttackPower(builder, attackPower);
|
||||||
|
Bombing.addWiped(builder, wiped);
|
||||||
|
return Bombing.endBombing(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack(): BombingT {
|
||||||
|
return new BombingT(
|
||||||
|
this.number(),
|
||||||
|
this.planet(),
|
||||||
|
this.owner(),
|
||||||
|
this.attacker(),
|
||||||
|
this.production(),
|
||||||
|
this.industry(),
|
||||||
|
this.population(),
|
||||||
|
this.colonists(),
|
||||||
|
this.capital(),
|
||||||
|
this.material(),
|
||||||
|
this.attackPower(),
|
||||||
|
this.wiped()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: BombingT): void {
|
||||||
|
_o.number = this.number();
|
||||||
|
_o.planet = this.planet();
|
||||||
|
_o.owner = this.owner();
|
||||||
|
_o.attacker = this.attacker();
|
||||||
|
_o.production = this.production();
|
||||||
|
_o.industry = this.industry();
|
||||||
|
_o.population = this.population();
|
||||||
|
_o.colonists = this.colonists();
|
||||||
|
_o.capital = this.capital();
|
||||||
|
_o.material = this.material();
|
||||||
|
_o.attackPower = this.attackPower();
|
||||||
|
_o.wiped = this.wiped();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BombingT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public number: bigint = BigInt('0'),
|
||||||
|
public planet: string|Uint8Array|null = null,
|
||||||
|
public owner: string|Uint8Array|null = null,
|
||||||
|
public attacker: string|Uint8Array|null = null,
|
||||||
|
public production: string|Uint8Array|null = null,
|
||||||
|
public industry: number = 0.0,
|
||||||
|
public population: number = 0.0,
|
||||||
|
public colonists: number = 0.0,
|
||||||
|
public capital: number = 0.0,
|
||||||
|
public material: number = 0.0,
|
||||||
|
public attackPower: number = 0.0,
|
||||||
|
public wiped: boolean = false
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
const planet = (this.planet !== null ? builder.createString(this.planet!) : 0);
|
||||||
|
const owner = (this.owner !== null ? builder.createString(this.owner!) : 0);
|
||||||
|
const attacker = (this.attacker !== null ? builder.createString(this.attacker!) : 0);
|
||||||
|
const production = (this.production !== null ? builder.createString(this.production!) : 0);
|
||||||
|
|
||||||
|
return Bombing.createBombing(builder,
|
||||||
|
this.number,
|
||||||
|
planet,
|
||||||
|
owner,
|
||||||
|
attacker,
|
||||||
|
production,
|
||||||
|
this.industry,
|
||||||
|
this.population,
|
||||||
|
this.colonists,
|
||||||
|
this.capital,
|
||||||
|
this.material,
|
||||||
|
this.attackPower,
|
||||||
|
this.wiped
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
import { UUID, UUIDT } from '../common/uuid.js';
|
||||||
|
|
||||||
|
|
||||||
|
export class GameReportRequest implements flatbuffers.IUnpackableObject<GameReportRequestT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):GameReportRequest {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRootAsGameReportRequest(bb:flatbuffers.ByteBuffer, obj?:GameReportRequest):GameReportRequest {
|
||||||
|
return (obj || new GameReportRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSizePrefixedRootAsGameReportRequest(bb:flatbuffers.ByteBuffer, obj?:GameReportRequest):GameReportRequest {
|
||||||
|
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||||
|
return (obj || new GameReportRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
gameId(obj?:UUID):UUID|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||||
|
return offset ? (obj || new UUID()).__init(this.bb_pos + offset, this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
turn():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static startGameReportRequest(builder:flatbuffers.Builder) {
|
||||||
|
builder.startObject(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addGameId(builder:flatbuffers.Builder, gameIdOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldStruct(0, gameIdOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addTurn(builder:flatbuffers.Builder, turn:number) {
|
||||||
|
builder.addFieldInt32(1, turn, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static endGameReportRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
|
const offset = builder.endObject();
|
||||||
|
builder.requiredField(offset, 4) // game_id
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createGameReportRequest(builder:flatbuffers.Builder, gameIdOffset:flatbuffers.Offset, turn:number):flatbuffers.Offset {
|
||||||
|
GameReportRequest.startGameReportRequest(builder);
|
||||||
|
GameReportRequest.addGameId(builder, gameIdOffset);
|
||||||
|
GameReportRequest.addTurn(builder, turn);
|
||||||
|
return GameReportRequest.endGameReportRequest(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack(): GameReportRequestT {
|
||||||
|
return new GameReportRequestT(
|
||||||
|
(this.gameId() !== null ? this.gameId()!.unpack() : null),
|
||||||
|
this.turn()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: GameReportRequestT): void {
|
||||||
|
_o.gameId = (this.gameId() !== null ? this.gameId()!.unpack() : null);
|
||||||
|
_o.turn = this.turn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GameReportRequestT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public gameId: UUIDT|null = null,
|
||||||
|
public turn: number = 0
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
return GameReportRequest.createGameReportRequest(builder,
|
||||||
|
(this.gameId !== null ? this.gameId!.pack(builder) : 0),
|
||||||
|
this.turn
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export class IncomingGroup implements flatbuffers.IUnpackableObject<IncomingGroupT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):IncomingGroup {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRootAsIncomingGroup(bb:flatbuffers.ByteBuffer, obj?:IncomingGroup):IncomingGroup {
|
||||||
|
return (obj || new IncomingGroup()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSizePrefixedRootAsIncomingGroup(bb:flatbuffers.ByteBuffer, obj?:IncomingGroup):IncomingGroup {
|
||||||
|
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||||
|
return (obj || new IncomingGroup()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
origin():bigint {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
destination():bigint {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
distance():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
speed():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mass():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static startIncomingGroup(builder:flatbuffers.Builder) {
|
||||||
|
builder.startObject(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addOrigin(builder:flatbuffers.Builder, origin:bigint) {
|
||||||
|
builder.addFieldInt64(0, origin, BigInt('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static addDestination(builder:flatbuffers.Builder, destination:bigint) {
|
||||||
|
builder.addFieldInt64(1, destination, BigInt('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static addDistance(builder:flatbuffers.Builder, distance:number) {
|
||||||
|
builder.addFieldFloat32(2, distance, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addSpeed(builder:flatbuffers.Builder, speed:number) {
|
||||||
|
builder.addFieldFloat32(3, speed, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addMass(builder:flatbuffers.Builder, mass:number) {
|
||||||
|
builder.addFieldFloat32(4, mass, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static endIncomingGroup(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
|
const offset = builder.endObject();
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createIncomingGroup(builder:flatbuffers.Builder, origin:bigint, destination:bigint, distance:number, speed:number, mass:number):flatbuffers.Offset {
|
||||||
|
IncomingGroup.startIncomingGroup(builder);
|
||||||
|
IncomingGroup.addOrigin(builder, origin);
|
||||||
|
IncomingGroup.addDestination(builder, destination);
|
||||||
|
IncomingGroup.addDistance(builder, distance);
|
||||||
|
IncomingGroup.addSpeed(builder, speed);
|
||||||
|
IncomingGroup.addMass(builder, mass);
|
||||||
|
return IncomingGroup.endIncomingGroup(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack(): IncomingGroupT {
|
||||||
|
return new IncomingGroupT(
|
||||||
|
this.origin(),
|
||||||
|
this.destination(),
|
||||||
|
this.distance(),
|
||||||
|
this.speed(),
|
||||||
|
this.mass()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: IncomingGroupT): void {
|
||||||
|
_o.origin = this.origin();
|
||||||
|
_o.destination = this.destination();
|
||||||
|
_o.distance = this.distance();
|
||||||
|
_o.speed = this.speed();
|
||||||
|
_o.mass = this.mass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class IncomingGroupT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public origin: bigint = BigInt('0'),
|
||||||
|
public destination: bigint = BigInt('0'),
|
||||||
|
public distance: number = 0.0,
|
||||||
|
public speed: number = 0.0,
|
||||||
|
public mass: number = 0.0
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
return IncomingGroup.createIncomingGroup(builder,
|
||||||
|
this.origin,
|
||||||
|
this.destination,
|
||||||
|
this.distance,
|
||||||
|
this.speed,
|
||||||
|
this.mass
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export class LocalFleet implements flatbuffers.IUnpackableObject<LocalFleetT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):LocalFleet {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRootAsLocalFleet(bb:flatbuffers.ByteBuffer, obj?:LocalFleet):LocalFleet {
|
||||||
|
return (obj || new LocalFleet()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSizePrefixedRootAsLocalFleet(bb:flatbuffers.ByteBuffer, obj?:LocalFleet):LocalFleet {
|
||||||
|
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||||
|
return (obj || new LocalFleet()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
name():string|null
|
||||||
|
name(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
name(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
groups():bigint {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
destination():bigint {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
origin():bigint|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
range():number|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
speed():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
state():string|null
|
||||||
|
state(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
state(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 16);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static startLocalFleet(builder:flatbuffers.Builder) {
|
||||||
|
builder.startObject(7);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addName(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(0, nameOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addGroups(builder:flatbuffers.Builder, groups:bigint) {
|
||||||
|
builder.addFieldInt64(1, groups, BigInt('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static addDestination(builder:flatbuffers.Builder, destination:bigint) {
|
||||||
|
builder.addFieldInt64(2, destination, BigInt('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static addOrigin(builder:flatbuffers.Builder, origin:bigint) {
|
||||||
|
builder.addFieldInt64(3, origin, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addRange(builder:flatbuffers.Builder, range:number) {
|
||||||
|
builder.addFieldFloat32(4, range, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addSpeed(builder:flatbuffers.Builder, speed:number) {
|
||||||
|
builder.addFieldFloat32(5, speed, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addState(builder:flatbuffers.Builder, stateOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(6, stateOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static endLocalFleet(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
|
const offset = builder.endObject();
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createLocalFleet(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, groups:bigint, destination:bigint, origin:bigint|null, range:number|null, speed:number, stateOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||||
|
LocalFleet.startLocalFleet(builder);
|
||||||
|
LocalFleet.addName(builder, nameOffset);
|
||||||
|
LocalFleet.addGroups(builder, groups);
|
||||||
|
LocalFleet.addDestination(builder, destination);
|
||||||
|
if (origin !== null)
|
||||||
|
LocalFleet.addOrigin(builder, origin);
|
||||||
|
if (range !== null)
|
||||||
|
LocalFleet.addRange(builder, range);
|
||||||
|
LocalFleet.addSpeed(builder, speed);
|
||||||
|
LocalFleet.addState(builder, stateOffset);
|
||||||
|
return LocalFleet.endLocalFleet(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack(): LocalFleetT {
|
||||||
|
return new LocalFleetT(
|
||||||
|
this.name(),
|
||||||
|
this.groups(),
|
||||||
|
this.destination(),
|
||||||
|
this.origin(),
|
||||||
|
this.range(),
|
||||||
|
this.speed(),
|
||||||
|
this.state()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: LocalFleetT): void {
|
||||||
|
_o.name = this.name();
|
||||||
|
_o.groups = this.groups();
|
||||||
|
_o.destination = this.destination();
|
||||||
|
_o.origin = this.origin();
|
||||||
|
_o.range = this.range();
|
||||||
|
_o.speed = this.speed();
|
||||||
|
_o.state = this.state();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LocalFleetT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public name: string|Uint8Array|null = null,
|
||||||
|
public groups: bigint = BigInt('0'),
|
||||||
|
public destination: bigint = BigInt('0'),
|
||||||
|
public origin: bigint|null = null,
|
||||||
|
public range: number|null = null,
|
||||||
|
public speed: number = 0.0,
|
||||||
|
public state: string|Uint8Array|null = null
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
const name = (this.name !== null ? builder.createString(this.name!) : 0);
|
||||||
|
const state = (this.state !== null ? builder.createString(this.state!) : 0);
|
||||||
|
|
||||||
|
return LocalFleet.createLocalFleet(builder,
|
||||||
|
name,
|
||||||
|
this.groups,
|
||||||
|
this.destination,
|
||||||
|
this.origin,
|
||||||
|
this.range,
|
||||||
|
this.speed,
|
||||||
|
state
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,262 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
import { UUID, UUIDT } from '../common/uuid.js';
|
||||||
|
import { TechEntry, TechEntryT } from './tech-entry.js';
|
||||||
|
|
||||||
|
|
||||||
|
export class LocalGroup implements flatbuffers.IUnpackableObject<LocalGroupT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):LocalGroup {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRootAsLocalGroup(bb:flatbuffers.ByteBuffer, obj?:LocalGroup):LocalGroup {
|
||||||
|
return (obj || new LocalGroup()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSizePrefixedRootAsLocalGroup(bb:flatbuffers.ByteBuffer, obj?:LocalGroup):LocalGroup {
|
||||||
|
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||||
|
return (obj || new LocalGroup()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
number():bigint {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
class_():string|null
|
||||||
|
class_(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
class_(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
tech(index: number, obj?:TechEntry):TechEntry|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||||
|
return offset ? (obj || new TechEntry()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
techLength():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||||
|
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cargo():string|null
|
||||||
|
cargo(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
cargo(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
load():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
destination():bigint {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
origin():bigint|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 16);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
range():number|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 18);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
speed():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 20);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mass():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 22);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
id(obj?:UUID):UUID|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 24);
|
||||||
|
return offset ? (obj || new UUID()).__init(this.bb_pos + offset, this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
state():string|null
|
||||||
|
state(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
state(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 26);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
fleet():string|null
|
||||||
|
fleet(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
fleet(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 28);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static startLocalGroup(builder:flatbuffers.Builder) {
|
||||||
|
builder.startObject(13);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addNumber(builder:flatbuffers.Builder, number:bigint) {
|
||||||
|
builder.addFieldInt64(0, number, BigInt('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static addClass(builder:flatbuffers.Builder, class_Offset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(1, class_Offset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addTech(builder:flatbuffers.Builder, techOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(2, techOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createTechVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||||
|
builder.startVector(4, data.length, 4);
|
||||||
|
for (let i = data.length - 1; i >= 0; i--) {
|
||||||
|
builder.addOffset(data[i]!);
|
||||||
|
}
|
||||||
|
return builder.endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
static startTechVector(builder:flatbuffers.Builder, numElems:number) {
|
||||||
|
builder.startVector(4, numElems, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addCargo(builder:flatbuffers.Builder, cargoOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(3, cargoOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addLoad(builder:flatbuffers.Builder, load:number) {
|
||||||
|
builder.addFieldFloat32(4, load, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addDestination(builder:flatbuffers.Builder, destination:bigint) {
|
||||||
|
builder.addFieldInt64(5, destination, BigInt('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static addOrigin(builder:flatbuffers.Builder, origin:bigint) {
|
||||||
|
builder.addFieldInt64(6, origin, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addRange(builder:flatbuffers.Builder, range:number) {
|
||||||
|
builder.addFieldFloat32(7, range, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addSpeed(builder:flatbuffers.Builder, speed:number) {
|
||||||
|
builder.addFieldFloat32(8, speed, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addMass(builder:flatbuffers.Builder, mass:number) {
|
||||||
|
builder.addFieldFloat32(9, mass, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addId(builder:flatbuffers.Builder, idOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldStruct(10, idOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addState(builder:flatbuffers.Builder, stateOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(11, stateOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addFleet(builder:flatbuffers.Builder, fleetOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(12, fleetOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static endLocalGroup(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
|
const offset = builder.endObject();
|
||||||
|
builder.requiredField(offset, 24) // id
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpack(): LocalGroupT {
|
||||||
|
return new LocalGroupT(
|
||||||
|
this.number(),
|
||||||
|
this.class_(),
|
||||||
|
this.bb!.createObjList<TechEntry, TechEntryT>(this.tech.bind(this), this.techLength()),
|
||||||
|
this.cargo(),
|
||||||
|
this.load(),
|
||||||
|
this.destination(),
|
||||||
|
this.origin(),
|
||||||
|
this.range(),
|
||||||
|
this.speed(),
|
||||||
|
this.mass(),
|
||||||
|
(this.id() !== null ? this.id()!.unpack() : null),
|
||||||
|
this.state(),
|
||||||
|
this.fleet()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: LocalGroupT): void {
|
||||||
|
_o.number = this.number();
|
||||||
|
_o.class_ = this.class_();
|
||||||
|
_o.tech = this.bb!.createObjList<TechEntry, TechEntryT>(this.tech.bind(this), this.techLength());
|
||||||
|
_o.cargo = this.cargo();
|
||||||
|
_o.load = this.load();
|
||||||
|
_o.destination = this.destination();
|
||||||
|
_o.origin = this.origin();
|
||||||
|
_o.range = this.range();
|
||||||
|
_o.speed = this.speed();
|
||||||
|
_o.mass = this.mass();
|
||||||
|
_o.id = (this.id() !== null ? this.id()!.unpack() : null);
|
||||||
|
_o.state = this.state();
|
||||||
|
_o.fleet = this.fleet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LocalGroupT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public number: bigint = BigInt('0'),
|
||||||
|
public class_: string|Uint8Array|null = null,
|
||||||
|
public tech: (TechEntryT)[] = [],
|
||||||
|
public cargo: string|Uint8Array|null = null,
|
||||||
|
public load: number = 0.0,
|
||||||
|
public destination: bigint = BigInt('0'),
|
||||||
|
public origin: bigint|null = null,
|
||||||
|
public range: number|null = null,
|
||||||
|
public speed: number = 0.0,
|
||||||
|
public mass: number = 0.0,
|
||||||
|
public id: UUIDT|null = null,
|
||||||
|
public state: string|Uint8Array|null = null,
|
||||||
|
public fleet: string|Uint8Array|null = null
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
const class_ = (this.class_ !== null ? builder.createString(this.class_!) : 0);
|
||||||
|
const tech = LocalGroup.createTechVector(builder, builder.createObjectOffsetList(this.tech));
|
||||||
|
const cargo = (this.cargo !== null ? builder.createString(this.cargo!) : 0);
|
||||||
|
const state = (this.state !== null ? builder.createString(this.state!) : 0);
|
||||||
|
const fleet = (this.fleet !== null ? builder.createString(this.fleet!) : 0);
|
||||||
|
|
||||||
|
LocalGroup.startLocalGroup(builder);
|
||||||
|
LocalGroup.addNumber(builder, this.number);
|
||||||
|
LocalGroup.addClass(builder, class_);
|
||||||
|
LocalGroup.addTech(builder, tech);
|
||||||
|
LocalGroup.addCargo(builder, cargo);
|
||||||
|
LocalGroup.addLoad(builder, this.load);
|
||||||
|
LocalGroup.addDestination(builder, this.destination);
|
||||||
|
if (this.origin !== null)
|
||||||
|
LocalGroup.addOrigin(builder, this.origin);
|
||||||
|
if (this.range !== null)
|
||||||
|
LocalGroup.addRange(builder, this.range);
|
||||||
|
LocalGroup.addSpeed(builder, this.speed);
|
||||||
|
LocalGroup.addMass(builder, this.mass);
|
||||||
|
LocalGroup.addId(builder, (this.id !== null ? this.id!.pack(builder) : 0));
|
||||||
|
LocalGroup.addState(builder, state);
|
||||||
|
LocalGroup.addFleet(builder, fleet);
|
||||||
|
|
||||||
|
return LocalGroup.endLocalGroup(builder);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,249 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export class LocalPlanet implements flatbuffers.IUnpackableObject<LocalPlanetT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):LocalPlanet {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRootAsLocalPlanet(bb:flatbuffers.ByteBuffer, obj?:LocalPlanet):LocalPlanet {
|
||||||
|
return (obj || new LocalPlanet()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSizePrefixedRootAsLocalPlanet(bb:flatbuffers.ByteBuffer, obj?:LocalPlanet):LocalPlanet {
|
||||||
|
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||||
|
return (obj || new LocalPlanet()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
x():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
y():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
number():bigint {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
size():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
name():string|null
|
||||||
|
name(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
name(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
resources():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
capital():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 16);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
material():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 18);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
industry():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 20);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
population():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 22);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
colonists():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 24);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
production():string|null
|
||||||
|
production(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
production(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 26);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
freeIndustry():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 28);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static startLocalPlanet(builder:flatbuffers.Builder) {
|
||||||
|
builder.startObject(13);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addX(builder:flatbuffers.Builder, x:number) {
|
||||||
|
builder.addFieldFloat32(0, x, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addY(builder:flatbuffers.Builder, y:number) {
|
||||||
|
builder.addFieldFloat32(1, y, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addNumber(builder:flatbuffers.Builder, number:bigint) {
|
||||||
|
builder.addFieldInt64(2, number, BigInt('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static addSize(builder:flatbuffers.Builder, size:number) {
|
||||||
|
builder.addFieldFloat32(3, size, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addName(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(4, nameOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addResources(builder:flatbuffers.Builder, resources:number) {
|
||||||
|
builder.addFieldFloat32(5, resources, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addCapital(builder:flatbuffers.Builder, capital:number) {
|
||||||
|
builder.addFieldFloat32(6, capital, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addMaterial(builder:flatbuffers.Builder, material:number) {
|
||||||
|
builder.addFieldFloat32(7, material, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addIndustry(builder:flatbuffers.Builder, industry:number) {
|
||||||
|
builder.addFieldFloat32(8, industry, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addPopulation(builder:flatbuffers.Builder, population:number) {
|
||||||
|
builder.addFieldFloat32(9, population, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addColonists(builder:flatbuffers.Builder, colonists:number) {
|
||||||
|
builder.addFieldFloat32(10, colonists, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addProduction(builder:flatbuffers.Builder, productionOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(11, productionOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addFreeIndustry(builder:flatbuffers.Builder, freeIndustry:number) {
|
||||||
|
builder.addFieldFloat32(12, freeIndustry, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static endLocalPlanet(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
|
const offset = builder.endObject();
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createLocalPlanet(builder:flatbuffers.Builder, x:number, y:number, number:bigint, size:number, nameOffset:flatbuffers.Offset, resources:number, capital:number, material:number, industry:number, population:number, colonists:number, productionOffset:flatbuffers.Offset, freeIndustry:number):flatbuffers.Offset {
|
||||||
|
LocalPlanet.startLocalPlanet(builder);
|
||||||
|
LocalPlanet.addX(builder, x);
|
||||||
|
LocalPlanet.addY(builder, y);
|
||||||
|
LocalPlanet.addNumber(builder, number);
|
||||||
|
LocalPlanet.addSize(builder, size);
|
||||||
|
LocalPlanet.addName(builder, nameOffset);
|
||||||
|
LocalPlanet.addResources(builder, resources);
|
||||||
|
LocalPlanet.addCapital(builder, capital);
|
||||||
|
LocalPlanet.addMaterial(builder, material);
|
||||||
|
LocalPlanet.addIndustry(builder, industry);
|
||||||
|
LocalPlanet.addPopulation(builder, population);
|
||||||
|
LocalPlanet.addColonists(builder, colonists);
|
||||||
|
LocalPlanet.addProduction(builder, productionOffset);
|
||||||
|
LocalPlanet.addFreeIndustry(builder, freeIndustry);
|
||||||
|
return LocalPlanet.endLocalPlanet(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack(): LocalPlanetT {
|
||||||
|
return new LocalPlanetT(
|
||||||
|
this.x(),
|
||||||
|
this.y(),
|
||||||
|
this.number(),
|
||||||
|
this.size(),
|
||||||
|
this.name(),
|
||||||
|
this.resources(),
|
||||||
|
this.capital(),
|
||||||
|
this.material(),
|
||||||
|
this.industry(),
|
||||||
|
this.population(),
|
||||||
|
this.colonists(),
|
||||||
|
this.production(),
|
||||||
|
this.freeIndustry()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: LocalPlanetT): void {
|
||||||
|
_o.x = this.x();
|
||||||
|
_o.y = this.y();
|
||||||
|
_o.number = this.number();
|
||||||
|
_o.size = this.size();
|
||||||
|
_o.name = this.name();
|
||||||
|
_o.resources = this.resources();
|
||||||
|
_o.capital = this.capital();
|
||||||
|
_o.material = this.material();
|
||||||
|
_o.industry = this.industry();
|
||||||
|
_o.population = this.population();
|
||||||
|
_o.colonists = this.colonists();
|
||||||
|
_o.production = this.production();
|
||||||
|
_o.freeIndustry = this.freeIndustry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LocalPlanetT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public x: number = 0.0,
|
||||||
|
public y: number = 0.0,
|
||||||
|
public number: bigint = BigInt('0'),
|
||||||
|
public size: number = 0.0,
|
||||||
|
public name: string|Uint8Array|null = null,
|
||||||
|
public resources: number = 0.0,
|
||||||
|
public capital: number = 0.0,
|
||||||
|
public material: number = 0.0,
|
||||||
|
public industry: number = 0.0,
|
||||||
|
public population: number = 0.0,
|
||||||
|
public colonists: number = 0.0,
|
||||||
|
public production: string|Uint8Array|null = null,
|
||||||
|
public freeIndustry: number = 0.0
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
const name = (this.name !== null ? builder.createString(this.name!) : 0);
|
||||||
|
const production = (this.production !== null ? builder.createString(this.production!) : 0);
|
||||||
|
|
||||||
|
return LocalPlanet.createLocalPlanet(builder,
|
||||||
|
this.x,
|
||||||
|
this.y,
|
||||||
|
this.number,
|
||||||
|
this.size,
|
||||||
|
name,
|
||||||
|
this.resources,
|
||||||
|
this.capital,
|
||||||
|
this.material,
|
||||||
|
this.industry,
|
||||||
|
this.population,
|
||||||
|
this.colonists,
|
||||||
|
production,
|
||||||
|
this.freeIndustry
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,228 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
import { TechEntry, TechEntryT } from './tech-entry.js';
|
||||||
|
|
||||||
|
|
||||||
|
export class OtherGroup implements flatbuffers.IUnpackableObject<OtherGroupT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):OtherGroup {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRootAsOtherGroup(bb:flatbuffers.ByteBuffer, obj?:OtherGroup):OtherGroup {
|
||||||
|
return (obj || new OtherGroup()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSizePrefixedRootAsOtherGroup(bb:flatbuffers.ByteBuffer, obj?:OtherGroup):OtherGroup {
|
||||||
|
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||||
|
return (obj || new OtherGroup()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
number():bigint {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
class_():string|null
|
||||||
|
class_(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
class_(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
tech(index: number, obj?:TechEntry):TechEntry|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||||
|
return offset ? (obj || new TechEntry()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
techLength():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||||
|
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cargo():string|null
|
||||||
|
cargo(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
cargo(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
load():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
destination():bigint {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
origin():bigint|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 16);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
range():number|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 18);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
speed():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 20);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mass():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 22);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static startOtherGroup(builder:flatbuffers.Builder) {
|
||||||
|
builder.startObject(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addNumber(builder:flatbuffers.Builder, number:bigint) {
|
||||||
|
builder.addFieldInt64(0, number, BigInt('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static addClass(builder:flatbuffers.Builder, class_Offset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(1, class_Offset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addTech(builder:flatbuffers.Builder, techOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(2, techOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createTechVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||||
|
builder.startVector(4, data.length, 4);
|
||||||
|
for (let i = data.length - 1; i >= 0; i--) {
|
||||||
|
builder.addOffset(data[i]!);
|
||||||
|
}
|
||||||
|
return builder.endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
static startTechVector(builder:flatbuffers.Builder, numElems:number) {
|
||||||
|
builder.startVector(4, numElems, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addCargo(builder:flatbuffers.Builder, cargoOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(3, cargoOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addLoad(builder:flatbuffers.Builder, load:number) {
|
||||||
|
builder.addFieldFloat32(4, load, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addDestination(builder:flatbuffers.Builder, destination:bigint) {
|
||||||
|
builder.addFieldInt64(5, destination, BigInt('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static addOrigin(builder:flatbuffers.Builder, origin:bigint) {
|
||||||
|
builder.addFieldInt64(6, origin, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addRange(builder:flatbuffers.Builder, range:number) {
|
||||||
|
builder.addFieldFloat32(7, range, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addSpeed(builder:flatbuffers.Builder, speed:number) {
|
||||||
|
builder.addFieldFloat32(8, speed, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addMass(builder:flatbuffers.Builder, mass:number) {
|
||||||
|
builder.addFieldFloat32(9, mass, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static endOtherGroup(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
|
const offset = builder.endObject();
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createOtherGroup(builder:flatbuffers.Builder, number:bigint, class_Offset:flatbuffers.Offset, techOffset:flatbuffers.Offset, cargoOffset:flatbuffers.Offset, load:number, destination:bigint, origin:bigint|null, range:number|null, speed:number, mass:number):flatbuffers.Offset {
|
||||||
|
OtherGroup.startOtherGroup(builder);
|
||||||
|
OtherGroup.addNumber(builder, number);
|
||||||
|
OtherGroup.addClass(builder, class_Offset);
|
||||||
|
OtherGroup.addTech(builder, techOffset);
|
||||||
|
OtherGroup.addCargo(builder, cargoOffset);
|
||||||
|
OtherGroup.addLoad(builder, load);
|
||||||
|
OtherGroup.addDestination(builder, destination);
|
||||||
|
if (origin !== null)
|
||||||
|
OtherGroup.addOrigin(builder, origin);
|
||||||
|
if (range !== null)
|
||||||
|
OtherGroup.addRange(builder, range);
|
||||||
|
OtherGroup.addSpeed(builder, speed);
|
||||||
|
OtherGroup.addMass(builder, mass);
|
||||||
|
return OtherGroup.endOtherGroup(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack(): OtherGroupT {
|
||||||
|
return new OtherGroupT(
|
||||||
|
this.number(),
|
||||||
|
this.class_(),
|
||||||
|
this.bb!.createObjList<TechEntry, TechEntryT>(this.tech.bind(this), this.techLength()),
|
||||||
|
this.cargo(),
|
||||||
|
this.load(),
|
||||||
|
this.destination(),
|
||||||
|
this.origin(),
|
||||||
|
this.range(),
|
||||||
|
this.speed(),
|
||||||
|
this.mass()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: OtherGroupT): void {
|
||||||
|
_o.number = this.number();
|
||||||
|
_o.class_ = this.class_();
|
||||||
|
_o.tech = this.bb!.createObjList<TechEntry, TechEntryT>(this.tech.bind(this), this.techLength());
|
||||||
|
_o.cargo = this.cargo();
|
||||||
|
_o.load = this.load();
|
||||||
|
_o.destination = this.destination();
|
||||||
|
_o.origin = this.origin();
|
||||||
|
_o.range = this.range();
|
||||||
|
_o.speed = this.speed();
|
||||||
|
_o.mass = this.mass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class OtherGroupT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public number: bigint = BigInt('0'),
|
||||||
|
public class_: string|Uint8Array|null = null,
|
||||||
|
public tech: (TechEntryT)[] = [],
|
||||||
|
public cargo: string|Uint8Array|null = null,
|
||||||
|
public load: number = 0.0,
|
||||||
|
public destination: bigint = BigInt('0'),
|
||||||
|
public origin: bigint|null = null,
|
||||||
|
public range: number|null = null,
|
||||||
|
public speed: number = 0.0,
|
||||||
|
public mass: number = 0.0
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
const class_ = (this.class_ !== null ? builder.createString(this.class_!) : 0);
|
||||||
|
const tech = OtherGroup.createTechVector(builder, builder.createObjectOffsetList(this.tech));
|
||||||
|
const cargo = (this.cargo !== null ? builder.createString(this.cargo!) : 0);
|
||||||
|
|
||||||
|
return OtherGroup.createOtherGroup(builder,
|
||||||
|
this.number,
|
||||||
|
class_,
|
||||||
|
tech,
|
||||||
|
cargo,
|
||||||
|
this.load,
|
||||||
|
this.destination,
|
||||||
|
this.origin,
|
||||||
|
this.range,
|
||||||
|
this.speed,
|
||||||
|
this.mass
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,266 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export class OtherPlanet implements flatbuffers.IUnpackableObject<OtherPlanetT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):OtherPlanet {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRootAsOtherPlanet(bb:flatbuffers.ByteBuffer, obj?:OtherPlanet):OtherPlanet {
|
||||||
|
return (obj || new OtherPlanet()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSizePrefixedRootAsOtherPlanet(bb:flatbuffers.ByteBuffer, obj?:OtherPlanet):OtherPlanet {
|
||||||
|
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||||
|
return (obj || new OtherPlanet()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
owner():string|null
|
||||||
|
owner(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
owner(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
x():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
y():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
number():bigint {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
size():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
name():string|null
|
||||||
|
name(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
name(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
resources():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 16);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
capital():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 18);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
material():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 20);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
industry():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 22);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
population():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 24);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
colonists():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 26);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
production():string|null
|
||||||
|
production(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
production(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 28);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
freeIndustry():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 30);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static startOtherPlanet(builder:flatbuffers.Builder) {
|
||||||
|
builder.startObject(14);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addOwner(builder:flatbuffers.Builder, ownerOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(0, ownerOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addX(builder:flatbuffers.Builder, x:number) {
|
||||||
|
builder.addFieldFloat32(1, x, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addY(builder:flatbuffers.Builder, y:number) {
|
||||||
|
builder.addFieldFloat32(2, y, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addNumber(builder:flatbuffers.Builder, number:bigint) {
|
||||||
|
builder.addFieldInt64(3, number, BigInt('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static addSize(builder:flatbuffers.Builder, size:number) {
|
||||||
|
builder.addFieldFloat32(4, size, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addName(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(5, nameOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addResources(builder:flatbuffers.Builder, resources:number) {
|
||||||
|
builder.addFieldFloat32(6, resources, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addCapital(builder:flatbuffers.Builder, capital:number) {
|
||||||
|
builder.addFieldFloat32(7, capital, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addMaterial(builder:flatbuffers.Builder, material:number) {
|
||||||
|
builder.addFieldFloat32(8, material, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addIndustry(builder:flatbuffers.Builder, industry:number) {
|
||||||
|
builder.addFieldFloat32(9, industry, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addPopulation(builder:flatbuffers.Builder, population:number) {
|
||||||
|
builder.addFieldFloat32(10, population, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addColonists(builder:flatbuffers.Builder, colonists:number) {
|
||||||
|
builder.addFieldFloat32(11, colonists, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addProduction(builder:flatbuffers.Builder, productionOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(12, productionOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addFreeIndustry(builder:flatbuffers.Builder, freeIndustry:number) {
|
||||||
|
builder.addFieldFloat32(13, freeIndustry, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static endOtherPlanet(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
|
const offset = builder.endObject();
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createOtherPlanet(builder:flatbuffers.Builder, ownerOffset:flatbuffers.Offset, x:number, y:number, number:bigint, size:number, nameOffset:flatbuffers.Offset, resources:number, capital:number, material:number, industry:number, population:number, colonists:number, productionOffset:flatbuffers.Offset, freeIndustry:number):flatbuffers.Offset {
|
||||||
|
OtherPlanet.startOtherPlanet(builder);
|
||||||
|
OtherPlanet.addOwner(builder, ownerOffset);
|
||||||
|
OtherPlanet.addX(builder, x);
|
||||||
|
OtherPlanet.addY(builder, y);
|
||||||
|
OtherPlanet.addNumber(builder, number);
|
||||||
|
OtherPlanet.addSize(builder, size);
|
||||||
|
OtherPlanet.addName(builder, nameOffset);
|
||||||
|
OtherPlanet.addResources(builder, resources);
|
||||||
|
OtherPlanet.addCapital(builder, capital);
|
||||||
|
OtherPlanet.addMaterial(builder, material);
|
||||||
|
OtherPlanet.addIndustry(builder, industry);
|
||||||
|
OtherPlanet.addPopulation(builder, population);
|
||||||
|
OtherPlanet.addColonists(builder, colonists);
|
||||||
|
OtherPlanet.addProduction(builder, productionOffset);
|
||||||
|
OtherPlanet.addFreeIndustry(builder, freeIndustry);
|
||||||
|
return OtherPlanet.endOtherPlanet(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack(): OtherPlanetT {
|
||||||
|
return new OtherPlanetT(
|
||||||
|
this.owner(),
|
||||||
|
this.x(),
|
||||||
|
this.y(),
|
||||||
|
this.number(),
|
||||||
|
this.size(),
|
||||||
|
this.name(),
|
||||||
|
this.resources(),
|
||||||
|
this.capital(),
|
||||||
|
this.material(),
|
||||||
|
this.industry(),
|
||||||
|
this.population(),
|
||||||
|
this.colonists(),
|
||||||
|
this.production(),
|
||||||
|
this.freeIndustry()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: OtherPlanetT): void {
|
||||||
|
_o.owner = this.owner();
|
||||||
|
_o.x = this.x();
|
||||||
|
_o.y = this.y();
|
||||||
|
_o.number = this.number();
|
||||||
|
_o.size = this.size();
|
||||||
|
_o.name = this.name();
|
||||||
|
_o.resources = this.resources();
|
||||||
|
_o.capital = this.capital();
|
||||||
|
_o.material = this.material();
|
||||||
|
_o.industry = this.industry();
|
||||||
|
_o.population = this.population();
|
||||||
|
_o.colonists = this.colonists();
|
||||||
|
_o.production = this.production();
|
||||||
|
_o.freeIndustry = this.freeIndustry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class OtherPlanetT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public owner: string|Uint8Array|null = null,
|
||||||
|
public x: number = 0.0,
|
||||||
|
public y: number = 0.0,
|
||||||
|
public number: bigint = BigInt('0'),
|
||||||
|
public size: number = 0.0,
|
||||||
|
public name: string|Uint8Array|null = null,
|
||||||
|
public resources: number = 0.0,
|
||||||
|
public capital: number = 0.0,
|
||||||
|
public material: number = 0.0,
|
||||||
|
public industry: number = 0.0,
|
||||||
|
public population: number = 0.0,
|
||||||
|
public colonists: number = 0.0,
|
||||||
|
public production: string|Uint8Array|null = null,
|
||||||
|
public freeIndustry: number = 0.0
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
const owner = (this.owner !== null ? builder.createString(this.owner!) : 0);
|
||||||
|
const name = (this.name !== null ? builder.createString(this.name!) : 0);
|
||||||
|
const production = (this.production !== null ? builder.createString(this.production!) : 0);
|
||||||
|
|
||||||
|
return OtherPlanet.createOtherPlanet(builder,
|
||||||
|
owner,
|
||||||
|
this.x,
|
||||||
|
this.y,
|
||||||
|
this.number,
|
||||||
|
this.size,
|
||||||
|
name,
|
||||||
|
this.resources,
|
||||||
|
this.capital,
|
||||||
|
this.material,
|
||||||
|
this.industry,
|
||||||
|
this.population,
|
||||||
|
this.colonists,
|
||||||
|
production,
|
||||||
|
this.freeIndustry
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,151 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export class OtherScience implements flatbuffers.IUnpackableObject<OtherScienceT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):OtherScience {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRootAsOtherScience(bb:flatbuffers.ByteBuffer, obj?:OtherScience):OtherScience {
|
||||||
|
return (obj || new OtherScience()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSizePrefixedRootAsOtherScience(bb:flatbuffers.ByteBuffer, obj?:OtherScience):OtherScience {
|
||||||
|
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||||
|
return (obj || new OtherScience()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
race():string|null
|
||||||
|
race(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
race(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
name():string|null
|
||||||
|
name(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
name(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
drive():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
weapons():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
shields():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cargo():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static startOtherScience(builder:flatbuffers.Builder) {
|
||||||
|
builder.startObject(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addRace(builder:flatbuffers.Builder, raceOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(0, raceOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addName(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(1, nameOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addDrive(builder:flatbuffers.Builder, drive:number) {
|
||||||
|
builder.addFieldFloat32(2, drive, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addWeapons(builder:flatbuffers.Builder, weapons:number) {
|
||||||
|
builder.addFieldFloat32(3, weapons, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addShields(builder:flatbuffers.Builder, shields:number) {
|
||||||
|
builder.addFieldFloat32(4, shields, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addCargo(builder:flatbuffers.Builder, cargo:number) {
|
||||||
|
builder.addFieldFloat32(5, cargo, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static endOtherScience(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
|
const offset = builder.endObject();
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createOtherScience(builder:flatbuffers.Builder, raceOffset:flatbuffers.Offset, nameOffset:flatbuffers.Offset, drive:number, weapons:number, shields:number, cargo:number):flatbuffers.Offset {
|
||||||
|
OtherScience.startOtherScience(builder);
|
||||||
|
OtherScience.addRace(builder, raceOffset);
|
||||||
|
OtherScience.addName(builder, nameOffset);
|
||||||
|
OtherScience.addDrive(builder, drive);
|
||||||
|
OtherScience.addWeapons(builder, weapons);
|
||||||
|
OtherScience.addShields(builder, shields);
|
||||||
|
OtherScience.addCargo(builder, cargo);
|
||||||
|
return OtherScience.endOtherScience(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack(): OtherScienceT {
|
||||||
|
return new OtherScienceT(
|
||||||
|
this.race(),
|
||||||
|
this.name(),
|
||||||
|
this.drive(),
|
||||||
|
this.weapons(),
|
||||||
|
this.shields(),
|
||||||
|
this.cargo()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: OtherScienceT): void {
|
||||||
|
_o.race = this.race();
|
||||||
|
_o.name = this.name();
|
||||||
|
_o.drive = this.drive();
|
||||||
|
_o.weapons = this.weapons();
|
||||||
|
_o.shields = this.shields();
|
||||||
|
_o.cargo = this.cargo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class OtherScienceT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public race: string|Uint8Array|null = null,
|
||||||
|
public name: string|Uint8Array|null = null,
|
||||||
|
public drive: number = 0.0,
|
||||||
|
public weapons: number = 0.0,
|
||||||
|
public shields: number = 0.0,
|
||||||
|
public cargo: number = 0.0
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
const race = (this.race !== null ? builder.createString(this.race!) : 0);
|
||||||
|
const name = (this.name !== null ? builder.createString(this.name!) : 0);
|
||||||
|
|
||||||
|
return OtherScience.createOtherScience(builder,
|
||||||
|
race,
|
||||||
|
name,
|
||||||
|
this.drive,
|
||||||
|
this.weapons,
|
||||||
|
this.shields,
|
||||||
|
this.cargo
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export class OthersShipClass implements flatbuffers.IUnpackableObject<OthersShipClassT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):OthersShipClass {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRootAsOthersShipClass(bb:flatbuffers.ByteBuffer, obj?:OthersShipClass):OthersShipClass {
|
||||||
|
return (obj || new OthersShipClass()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSizePrefixedRootAsOthersShipClass(bb:flatbuffers.ByteBuffer, obj?:OthersShipClass):OthersShipClass {
|
||||||
|
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||||
|
return (obj || new OthersShipClass()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
race():string|null
|
||||||
|
race(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
race(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
name():string|null
|
||||||
|
name(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
name(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
drive():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
armament():bigint {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
weapons():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
shields():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cargo():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 16);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mass():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 18);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static startOthersShipClass(builder:flatbuffers.Builder) {
|
||||||
|
builder.startObject(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addRace(builder:flatbuffers.Builder, raceOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(0, raceOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addName(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(1, nameOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addDrive(builder:flatbuffers.Builder, drive:number) {
|
||||||
|
builder.addFieldFloat32(2, drive, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addArmament(builder:flatbuffers.Builder, armament:bigint) {
|
||||||
|
builder.addFieldInt64(3, armament, BigInt('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static addWeapons(builder:flatbuffers.Builder, weapons:number) {
|
||||||
|
builder.addFieldFloat32(4, weapons, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addShields(builder:flatbuffers.Builder, shields:number) {
|
||||||
|
builder.addFieldFloat32(5, shields, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addCargo(builder:flatbuffers.Builder, cargo:number) {
|
||||||
|
builder.addFieldFloat32(6, cargo, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addMass(builder:flatbuffers.Builder, mass:number) {
|
||||||
|
builder.addFieldFloat32(7, mass, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static endOthersShipClass(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
|
const offset = builder.endObject();
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createOthersShipClass(builder:flatbuffers.Builder, raceOffset:flatbuffers.Offset, nameOffset:flatbuffers.Offset, drive:number, armament:bigint, weapons:number, shields:number, cargo:number, mass:number):flatbuffers.Offset {
|
||||||
|
OthersShipClass.startOthersShipClass(builder);
|
||||||
|
OthersShipClass.addRace(builder, raceOffset);
|
||||||
|
OthersShipClass.addName(builder, nameOffset);
|
||||||
|
OthersShipClass.addDrive(builder, drive);
|
||||||
|
OthersShipClass.addArmament(builder, armament);
|
||||||
|
OthersShipClass.addWeapons(builder, weapons);
|
||||||
|
OthersShipClass.addShields(builder, shields);
|
||||||
|
OthersShipClass.addCargo(builder, cargo);
|
||||||
|
OthersShipClass.addMass(builder, mass);
|
||||||
|
return OthersShipClass.endOthersShipClass(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack(): OthersShipClassT {
|
||||||
|
return new OthersShipClassT(
|
||||||
|
this.race(),
|
||||||
|
this.name(),
|
||||||
|
this.drive(),
|
||||||
|
this.armament(),
|
||||||
|
this.weapons(),
|
||||||
|
this.shields(),
|
||||||
|
this.cargo(),
|
||||||
|
this.mass()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: OthersShipClassT): void {
|
||||||
|
_o.race = this.race();
|
||||||
|
_o.name = this.name();
|
||||||
|
_o.drive = this.drive();
|
||||||
|
_o.armament = this.armament();
|
||||||
|
_o.weapons = this.weapons();
|
||||||
|
_o.shields = this.shields();
|
||||||
|
_o.cargo = this.cargo();
|
||||||
|
_o.mass = this.mass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class OthersShipClassT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public race: string|Uint8Array|null = null,
|
||||||
|
public name: string|Uint8Array|null = null,
|
||||||
|
public drive: number = 0.0,
|
||||||
|
public armament: bigint = BigInt('0'),
|
||||||
|
public weapons: number = 0.0,
|
||||||
|
public shields: number = 0.0,
|
||||||
|
public cargo: number = 0.0,
|
||||||
|
public mass: number = 0.0
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
const race = (this.race !== null ? builder.createString(this.race!) : 0);
|
||||||
|
const name = (this.name !== null ? builder.createString(this.name!) : 0);
|
||||||
|
|
||||||
|
return OthersShipClass.createOthersShipClass(builder,
|
||||||
|
race,
|
||||||
|
name,
|
||||||
|
this.drive,
|
||||||
|
this.armament,
|
||||||
|
this.weapons,
|
||||||
|
this.shields,
|
||||||
|
this.cargo,
|
||||||
|
this.mass
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,221 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export class Player implements flatbuffers.IUnpackableObject<PlayerT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):Player {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRootAsPlayer(bb:flatbuffers.ByteBuffer, obj?:Player):Player {
|
||||||
|
return (obj || new Player()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSizePrefixedRootAsPlayer(bb:flatbuffers.ByteBuffer, obj?:Player):Player {
|
||||||
|
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||||
|
return (obj || new Player()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
name():string|null
|
||||||
|
name(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
name(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
drive():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
weapons():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
shields():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cargo():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
population():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
industry():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 16);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
planets():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 18);
|
||||||
|
return offset ? this.bb!.readUint16(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
relation():string|null
|
||||||
|
relation(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
relation(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 20);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
votes():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 22);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
extinct():boolean {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 24);
|
||||||
|
return offset ? !!this.bb!.readInt8(this.bb_pos + offset) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static startPlayer(builder:flatbuffers.Builder) {
|
||||||
|
builder.startObject(11);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addName(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(0, nameOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addDrive(builder:flatbuffers.Builder, drive:number) {
|
||||||
|
builder.addFieldFloat32(1, drive, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addWeapons(builder:flatbuffers.Builder, weapons:number) {
|
||||||
|
builder.addFieldFloat32(2, weapons, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addShields(builder:flatbuffers.Builder, shields:number) {
|
||||||
|
builder.addFieldFloat32(3, shields, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addCargo(builder:flatbuffers.Builder, cargo:number) {
|
||||||
|
builder.addFieldFloat32(4, cargo, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addPopulation(builder:flatbuffers.Builder, population:number) {
|
||||||
|
builder.addFieldFloat32(5, population, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addIndustry(builder:flatbuffers.Builder, industry:number) {
|
||||||
|
builder.addFieldFloat32(6, industry, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addPlanets(builder:flatbuffers.Builder, planets:number) {
|
||||||
|
builder.addFieldInt16(7, planets, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addRelation(builder:flatbuffers.Builder, relationOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(8, relationOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addVotes(builder:flatbuffers.Builder, votes:number) {
|
||||||
|
builder.addFieldFloat32(9, votes, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addExtinct(builder:flatbuffers.Builder, extinct:boolean) {
|
||||||
|
builder.addFieldInt8(10, +extinct, +false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static endPlayer(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
|
const offset = builder.endObject();
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createPlayer(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, drive:number, weapons:number, shields:number, cargo:number, population:number, industry:number, planets:number, relationOffset:flatbuffers.Offset, votes:number, extinct:boolean):flatbuffers.Offset {
|
||||||
|
Player.startPlayer(builder);
|
||||||
|
Player.addName(builder, nameOffset);
|
||||||
|
Player.addDrive(builder, drive);
|
||||||
|
Player.addWeapons(builder, weapons);
|
||||||
|
Player.addShields(builder, shields);
|
||||||
|
Player.addCargo(builder, cargo);
|
||||||
|
Player.addPopulation(builder, population);
|
||||||
|
Player.addIndustry(builder, industry);
|
||||||
|
Player.addPlanets(builder, planets);
|
||||||
|
Player.addRelation(builder, relationOffset);
|
||||||
|
Player.addVotes(builder, votes);
|
||||||
|
Player.addExtinct(builder, extinct);
|
||||||
|
return Player.endPlayer(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack(): PlayerT {
|
||||||
|
return new PlayerT(
|
||||||
|
this.name(),
|
||||||
|
this.drive(),
|
||||||
|
this.weapons(),
|
||||||
|
this.shields(),
|
||||||
|
this.cargo(),
|
||||||
|
this.population(),
|
||||||
|
this.industry(),
|
||||||
|
this.planets(),
|
||||||
|
this.relation(),
|
||||||
|
this.votes(),
|
||||||
|
this.extinct()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: PlayerT): void {
|
||||||
|
_o.name = this.name();
|
||||||
|
_o.drive = this.drive();
|
||||||
|
_o.weapons = this.weapons();
|
||||||
|
_o.shields = this.shields();
|
||||||
|
_o.cargo = this.cargo();
|
||||||
|
_o.population = this.population();
|
||||||
|
_o.industry = this.industry();
|
||||||
|
_o.planets = this.planets();
|
||||||
|
_o.relation = this.relation();
|
||||||
|
_o.votes = this.votes();
|
||||||
|
_o.extinct = this.extinct();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PlayerT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public name: string|Uint8Array|null = null,
|
||||||
|
public drive: number = 0.0,
|
||||||
|
public weapons: number = 0.0,
|
||||||
|
public shields: number = 0.0,
|
||||||
|
public cargo: number = 0.0,
|
||||||
|
public population: number = 0.0,
|
||||||
|
public industry: number = 0.0,
|
||||||
|
public planets: number = 0,
|
||||||
|
public relation: string|Uint8Array|null = null,
|
||||||
|
public votes: number = 0.0,
|
||||||
|
public extinct: boolean = false
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
const name = (this.name !== null ? builder.createString(this.name!) : 0);
|
||||||
|
const relation = (this.relation !== null ? builder.createString(this.relation!) : 0);
|
||||||
|
|
||||||
|
return Player.createPlayer(builder,
|
||||||
|
name,
|
||||||
|
this.drive,
|
||||||
|
this.weapons,
|
||||||
|
this.shields,
|
||||||
|
this.cargo,
|
||||||
|
this.population,
|
||||||
|
this.industry,
|
||||||
|
this.planets,
|
||||||
|
relation,
|
||||||
|
this.votes,
|
||||||
|
this.extinct
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,773 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
import { UUID, UUIDT } from '../common/uuid.js';
|
||||||
|
import { Bombing, BombingT } from './bombing.js';
|
||||||
|
import { IncomingGroup, IncomingGroupT } from './incoming-group.js';
|
||||||
|
import { LocalFleet, LocalFleetT } from './local-fleet.js';
|
||||||
|
import { LocalGroup, LocalGroupT } from './local-group.js';
|
||||||
|
import { LocalPlanet, LocalPlanetT } from './local-planet.js';
|
||||||
|
import { OtherGroup, OtherGroupT } from './other-group.js';
|
||||||
|
import { OtherPlanet, OtherPlanetT } from './other-planet.js';
|
||||||
|
import { OtherScience, OtherScienceT } from './other-science.js';
|
||||||
|
import { OthersShipClass, OthersShipClassT } from './others-ship-class.js';
|
||||||
|
import { Player, PlayerT } from './player.js';
|
||||||
|
import { Route, RouteT } from './route.js';
|
||||||
|
import { Science, ScienceT } from './science.js';
|
||||||
|
import { ShipClass, ShipClassT } from './ship-class.js';
|
||||||
|
import { ShipProduction, ShipProductionT } from './ship-production.js';
|
||||||
|
import { UnidentifiedGroup, UnidentifiedGroupT } from './unidentified-group.js';
|
||||||
|
import { UnidentifiedPlanet, UnidentifiedPlanetT } from './unidentified-planet.js';
|
||||||
|
import { UninhabitedPlanet, UninhabitedPlanetT } from './uninhabited-planet.js';
|
||||||
|
|
||||||
|
|
||||||
|
export class Report implements flatbuffers.IUnpackableObject<ReportT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):Report {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRootAsReport(bb:flatbuffers.ByteBuffer, obj?:Report):Report {
|
||||||
|
return (obj || new Report()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSizePrefixedRootAsReport(bb:flatbuffers.ByteBuffer, obj?:Report):Report {
|
||||||
|
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||||
|
return (obj || new Report()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
version():bigint {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
turn():bigint {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
width():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||||
|
return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
height():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||||
|
return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
planetCount():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||||
|
return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
race():string|null
|
||||||
|
race(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
race(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
votes():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 16);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
voteFor():string|null
|
||||||
|
voteFor(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
voteFor(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 18);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
player(index: number, obj?:Player):Player|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 20);
|
||||||
|
return offset ? (obj || new Player()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
playerLength():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 20);
|
||||||
|
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
localScience(index: number, obj?:Science):Science|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 22);
|
||||||
|
return offset ? (obj || new Science()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
localScienceLength():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 22);
|
||||||
|
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
otherScience(index: number, obj?:OtherScience):OtherScience|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 24);
|
||||||
|
return offset ? (obj || new OtherScience()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
otherScienceLength():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 24);
|
||||||
|
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
localShipClass(index: number, obj?:ShipClass):ShipClass|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 26);
|
||||||
|
return offset ? (obj || new ShipClass()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
localShipClassLength():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 26);
|
||||||
|
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
otherShipClass(index: number, obj?:OthersShipClass):OthersShipClass|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 28);
|
||||||
|
return offset ? (obj || new OthersShipClass()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
otherShipClassLength():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 28);
|
||||||
|
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
battle(index: number, obj?:UUID):UUID|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 30);
|
||||||
|
return offset ? (obj || new UUID()).__init(this.bb!.__vector(this.bb_pos + offset) + index * 16, this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
battleLength():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 30);
|
||||||
|
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bombing(index: number, obj?:Bombing):Bombing|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 32);
|
||||||
|
return offset ? (obj || new Bombing()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
bombingLength():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 32);
|
||||||
|
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
incomingGroup(index: number, obj?:IncomingGroup):IncomingGroup|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 34);
|
||||||
|
return offset ? (obj || new IncomingGroup()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
incomingGroupLength():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 34);
|
||||||
|
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
localPlanet(index: number, obj?:LocalPlanet):LocalPlanet|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 36);
|
||||||
|
return offset ? (obj || new LocalPlanet()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
localPlanetLength():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 36);
|
||||||
|
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
shipProduction(index: number, obj?:ShipProduction):ShipProduction|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 38);
|
||||||
|
return offset ? (obj || new ShipProduction()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
shipProductionLength():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 38);
|
||||||
|
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
route(index: number, obj?:Route):Route|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 40);
|
||||||
|
return offset ? (obj || new Route()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
routeLength():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 40);
|
||||||
|
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
otherPlanet(index: number, obj?:OtherPlanet):OtherPlanet|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 42);
|
||||||
|
return offset ? (obj || new OtherPlanet()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
otherPlanetLength():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 42);
|
||||||
|
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uninhabitedPlanet(index: number, obj?:UninhabitedPlanet):UninhabitedPlanet|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 44);
|
||||||
|
return offset ? (obj || new UninhabitedPlanet()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
uninhabitedPlanetLength():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 44);
|
||||||
|
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unidentifiedPlanet(index: number, obj?:UnidentifiedPlanet):UnidentifiedPlanet|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 46);
|
||||||
|
return offset ? (obj || new UnidentifiedPlanet()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
unidentifiedPlanetLength():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 46);
|
||||||
|
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
localFleet(index: number, obj?:LocalFleet):LocalFleet|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 48);
|
||||||
|
return offset ? (obj || new LocalFleet()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
localFleetLength():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 48);
|
||||||
|
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
localGroup(index: number, obj?:LocalGroup):LocalGroup|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 50);
|
||||||
|
return offset ? (obj || new LocalGroup()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
localGroupLength():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 50);
|
||||||
|
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
otherGroup(index: number, obj?:OtherGroup):OtherGroup|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 52);
|
||||||
|
return offset ? (obj || new OtherGroup()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
otherGroupLength():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 52);
|
||||||
|
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unidentifiedGroup(index: number, obj?:UnidentifiedGroup):UnidentifiedGroup|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 54);
|
||||||
|
return offset ? (obj || new UnidentifiedGroup()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
unidentifiedGroupLength():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 54);
|
||||||
|
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static startReport(builder:flatbuffers.Builder) {
|
||||||
|
builder.startObject(26);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addVersion(builder:flatbuffers.Builder, version:bigint) {
|
||||||
|
builder.addFieldInt64(0, version, BigInt('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static addTurn(builder:flatbuffers.Builder, turn:bigint) {
|
||||||
|
builder.addFieldInt64(1, turn, BigInt('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static addWidth(builder:flatbuffers.Builder, width:number) {
|
||||||
|
builder.addFieldInt32(2, width, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addHeight(builder:flatbuffers.Builder, height:number) {
|
||||||
|
builder.addFieldInt32(3, height, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addPlanetCount(builder:flatbuffers.Builder, planetCount:number) {
|
||||||
|
builder.addFieldInt32(4, planetCount, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addRace(builder:flatbuffers.Builder, raceOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(5, raceOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addVotes(builder:flatbuffers.Builder, votes:number) {
|
||||||
|
builder.addFieldFloat32(6, votes, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addVoteFor(builder:flatbuffers.Builder, voteForOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(7, voteForOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addPlayer(builder:flatbuffers.Builder, playerOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(8, playerOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createPlayerVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||||
|
builder.startVector(4, data.length, 4);
|
||||||
|
for (let i = data.length - 1; i >= 0; i--) {
|
||||||
|
builder.addOffset(data[i]!);
|
||||||
|
}
|
||||||
|
return builder.endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
static startPlayerVector(builder:flatbuffers.Builder, numElems:number) {
|
||||||
|
builder.startVector(4, numElems, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addLocalScience(builder:flatbuffers.Builder, localScienceOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(9, localScienceOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createLocalScienceVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||||
|
builder.startVector(4, data.length, 4);
|
||||||
|
for (let i = data.length - 1; i >= 0; i--) {
|
||||||
|
builder.addOffset(data[i]!);
|
||||||
|
}
|
||||||
|
return builder.endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
static startLocalScienceVector(builder:flatbuffers.Builder, numElems:number) {
|
||||||
|
builder.startVector(4, numElems, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addOtherScience(builder:flatbuffers.Builder, otherScienceOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(10, otherScienceOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createOtherScienceVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||||
|
builder.startVector(4, data.length, 4);
|
||||||
|
for (let i = data.length - 1; i >= 0; i--) {
|
||||||
|
builder.addOffset(data[i]!);
|
||||||
|
}
|
||||||
|
return builder.endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
static startOtherScienceVector(builder:flatbuffers.Builder, numElems:number) {
|
||||||
|
builder.startVector(4, numElems, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addLocalShipClass(builder:flatbuffers.Builder, localShipClassOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(11, localShipClassOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createLocalShipClassVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||||
|
builder.startVector(4, data.length, 4);
|
||||||
|
for (let i = data.length - 1; i >= 0; i--) {
|
||||||
|
builder.addOffset(data[i]!);
|
||||||
|
}
|
||||||
|
return builder.endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
static startLocalShipClassVector(builder:flatbuffers.Builder, numElems:number) {
|
||||||
|
builder.startVector(4, numElems, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addOtherShipClass(builder:flatbuffers.Builder, otherShipClassOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(12, otherShipClassOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createOtherShipClassVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||||
|
builder.startVector(4, data.length, 4);
|
||||||
|
for (let i = data.length - 1; i >= 0; i--) {
|
||||||
|
builder.addOffset(data[i]!);
|
||||||
|
}
|
||||||
|
return builder.endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
static startOtherShipClassVector(builder:flatbuffers.Builder, numElems:number) {
|
||||||
|
builder.startVector(4, numElems, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addBattle(builder:flatbuffers.Builder, battleOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(13, battleOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static startBattleVector(builder:flatbuffers.Builder, numElems:number) {
|
||||||
|
builder.startVector(16, numElems, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addBombing(builder:flatbuffers.Builder, bombingOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(14, bombingOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createBombingVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||||
|
builder.startVector(4, data.length, 4);
|
||||||
|
for (let i = data.length - 1; i >= 0; i--) {
|
||||||
|
builder.addOffset(data[i]!);
|
||||||
|
}
|
||||||
|
return builder.endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
static startBombingVector(builder:flatbuffers.Builder, numElems:number) {
|
||||||
|
builder.startVector(4, numElems, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addIncomingGroup(builder:flatbuffers.Builder, incomingGroupOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(15, incomingGroupOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createIncomingGroupVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||||
|
builder.startVector(4, data.length, 4);
|
||||||
|
for (let i = data.length - 1; i >= 0; i--) {
|
||||||
|
builder.addOffset(data[i]!);
|
||||||
|
}
|
||||||
|
return builder.endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
static startIncomingGroupVector(builder:flatbuffers.Builder, numElems:number) {
|
||||||
|
builder.startVector(4, numElems, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addLocalPlanet(builder:flatbuffers.Builder, localPlanetOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(16, localPlanetOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createLocalPlanetVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||||
|
builder.startVector(4, data.length, 4);
|
||||||
|
for (let i = data.length - 1; i >= 0; i--) {
|
||||||
|
builder.addOffset(data[i]!);
|
||||||
|
}
|
||||||
|
return builder.endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
static startLocalPlanetVector(builder:flatbuffers.Builder, numElems:number) {
|
||||||
|
builder.startVector(4, numElems, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addShipProduction(builder:flatbuffers.Builder, shipProductionOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(17, shipProductionOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createShipProductionVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||||
|
builder.startVector(4, data.length, 4);
|
||||||
|
for (let i = data.length - 1; i >= 0; i--) {
|
||||||
|
builder.addOffset(data[i]!);
|
||||||
|
}
|
||||||
|
return builder.endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
static startShipProductionVector(builder:flatbuffers.Builder, numElems:number) {
|
||||||
|
builder.startVector(4, numElems, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addRoute(builder:flatbuffers.Builder, routeOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(18, routeOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createRouteVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||||
|
builder.startVector(4, data.length, 4);
|
||||||
|
for (let i = data.length - 1; i >= 0; i--) {
|
||||||
|
builder.addOffset(data[i]!);
|
||||||
|
}
|
||||||
|
return builder.endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
static startRouteVector(builder:flatbuffers.Builder, numElems:number) {
|
||||||
|
builder.startVector(4, numElems, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addOtherPlanet(builder:flatbuffers.Builder, otherPlanetOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(19, otherPlanetOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createOtherPlanetVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||||
|
builder.startVector(4, data.length, 4);
|
||||||
|
for (let i = data.length - 1; i >= 0; i--) {
|
||||||
|
builder.addOffset(data[i]!);
|
||||||
|
}
|
||||||
|
return builder.endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
static startOtherPlanetVector(builder:flatbuffers.Builder, numElems:number) {
|
||||||
|
builder.startVector(4, numElems, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addUninhabitedPlanet(builder:flatbuffers.Builder, uninhabitedPlanetOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(20, uninhabitedPlanetOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createUninhabitedPlanetVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||||
|
builder.startVector(4, data.length, 4);
|
||||||
|
for (let i = data.length - 1; i >= 0; i--) {
|
||||||
|
builder.addOffset(data[i]!);
|
||||||
|
}
|
||||||
|
return builder.endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
static startUninhabitedPlanetVector(builder:flatbuffers.Builder, numElems:number) {
|
||||||
|
builder.startVector(4, numElems, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addUnidentifiedPlanet(builder:flatbuffers.Builder, unidentifiedPlanetOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(21, unidentifiedPlanetOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createUnidentifiedPlanetVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||||
|
builder.startVector(4, data.length, 4);
|
||||||
|
for (let i = data.length - 1; i >= 0; i--) {
|
||||||
|
builder.addOffset(data[i]!);
|
||||||
|
}
|
||||||
|
return builder.endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
static startUnidentifiedPlanetVector(builder:flatbuffers.Builder, numElems:number) {
|
||||||
|
builder.startVector(4, numElems, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addLocalFleet(builder:flatbuffers.Builder, localFleetOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(22, localFleetOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createLocalFleetVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||||
|
builder.startVector(4, data.length, 4);
|
||||||
|
for (let i = data.length - 1; i >= 0; i--) {
|
||||||
|
builder.addOffset(data[i]!);
|
||||||
|
}
|
||||||
|
return builder.endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
static startLocalFleetVector(builder:flatbuffers.Builder, numElems:number) {
|
||||||
|
builder.startVector(4, numElems, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addLocalGroup(builder:flatbuffers.Builder, localGroupOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(23, localGroupOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createLocalGroupVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||||
|
builder.startVector(4, data.length, 4);
|
||||||
|
for (let i = data.length - 1; i >= 0; i--) {
|
||||||
|
builder.addOffset(data[i]!);
|
||||||
|
}
|
||||||
|
return builder.endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
static startLocalGroupVector(builder:flatbuffers.Builder, numElems:number) {
|
||||||
|
builder.startVector(4, numElems, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addOtherGroup(builder:flatbuffers.Builder, otherGroupOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(24, otherGroupOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createOtherGroupVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||||
|
builder.startVector(4, data.length, 4);
|
||||||
|
for (let i = data.length - 1; i >= 0; i--) {
|
||||||
|
builder.addOffset(data[i]!);
|
||||||
|
}
|
||||||
|
return builder.endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
static startOtherGroupVector(builder:flatbuffers.Builder, numElems:number) {
|
||||||
|
builder.startVector(4, numElems, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addUnidentifiedGroup(builder:flatbuffers.Builder, unidentifiedGroupOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(25, unidentifiedGroupOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createUnidentifiedGroupVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||||
|
builder.startVector(4, data.length, 4);
|
||||||
|
for (let i = data.length - 1; i >= 0; i--) {
|
||||||
|
builder.addOffset(data[i]!);
|
||||||
|
}
|
||||||
|
return builder.endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
static startUnidentifiedGroupVector(builder:flatbuffers.Builder, numElems:number) {
|
||||||
|
builder.startVector(4, numElems, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static endReport(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
|
const offset = builder.endObject();
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static finishReportBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
|
||||||
|
builder.finish(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static finishSizePrefixedReportBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
|
||||||
|
builder.finish(offset, undefined, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createReport(builder:flatbuffers.Builder, version:bigint, turn:bigint, width:number, height:number, planetCount:number, raceOffset:flatbuffers.Offset, votes:number, voteForOffset:flatbuffers.Offset, playerOffset:flatbuffers.Offset, localScienceOffset:flatbuffers.Offset, otherScienceOffset:flatbuffers.Offset, localShipClassOffset:flatbuffers.Offset, otherShipClassOffset:flatbuffers.Offset, battleOffset:flatbuffers.Offset, bombingOffset:flatbuffers.Offset, incomingGroupOffset:flatbuffers.Offset, localPlanetOffset:flatbuffers.Offset, shipProductionOffset:flatbuffers.Offset, routeOffset:flatbuffers.Offset, otherPlanetOffset:flatbuffers.Offset, uninhabitedPlanetOffset:flatbuffers.Offset, unidentifiedPlanetOffset:flatbuffers.Offset, localFleetOffset:flatbuffers.Offset, localGroupOffset:flatbuffers.Offset, otherGroupOffset:flatbuffers.Offset, unidentifiedGroupOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||||
|
Report.startReport(builder);
|
||||||
|
Report.addVersion(builder, version);
|
||||||
|
Report.addTurn(builder, turn);
|
||||||
|
Report.addWidth(builder, width);
|
||||||
|
Report.addHeight(builder, height);
|
||||||
|
Report.addPlanetCount(builder, planetCount);
|
||||||
|
Report.addRace(builder, raceOffset);
|
||||||
|
Report.addVotes(builder, votes);
|
||||||
|
Report.addVoteFor(builder, voteForOffset);
|
||||||
|
Report.addPlayer(builder, playerOffset);
|
||||||
|
Report.addLocalScience(builder, localScienceOffset);
|
||||||
|
Report.addOtherScience(builder, otherScienceOffset);
|
||||||
|
Report.addLocalShipClass(builder, localShipClassOffset);
|
||||||
|
Report.addOtherShipClass(builder, otherShipClassOffset);
|
||||||
|
Report.addBattle(builder, battleOffset);
|
||||||
|
Report.addBombing(builder, bombingOffset);
|
||||||
|
Report.addIncomingGroup(builder, incomingGroupOffset);
|
||||||
|
Report.addLocalPlanet(builder, localPlanetOffset);
|
||||||
|
Report.addShipProduction(builder, shipProductionOffset);
|
||||||
|
Report.addRoute(builder, routeOffset);
|
||||||
|
Report.addOtherPlanet(builder, otherPlanetOffset);
|
||||||
|
Report.addUninhabitedPlanet(builder, uninhabitedPlanetOffset);
|
||||||
|
Report.addUnidentifiedPlanet(builder, unidentifiedPlanetOffset);
|
||||||
|
Report.addLocalFleet(builder, localFleetOffset);
|
||||||
|
Report.addLocalGroup(builder, localGroupOffset);
|
||||||
|
Report.addOtherGroup(builder, otherGroupOffset);
|
||||||
|
Report.addUnidentifiedGroup(builder, unidentifiedGroupOffset);
|
||||||
|
return Report.endReport(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack(): ReportT {
|
||||||
|
return new ReportT(
|
||||||
|
this.version(),
|
||||||
|
this.turn(),
|
||||||
|
this.width(),
|
||||||
|
this.height(),
|
||||||
|
this.planetCount(),
|
||||||
|
this.race(),
|
||||||
|
this.votes(),
|
||||||
|
this.voteFor(),
|
||||||
|
this.bb!.createObjList<Player, PlayerT>(this.player.bind(this), this.playerLength()),
|
||||||
|
this.bb!.createObjList<Science, ScienceT>(this.localScience.bind(this), this.localScienceLength()),
|
||||||
|
this.bb!.createObjList<OtherScience, OtherScienceT>(this.otherScience.bind(this), this.otherScienceLength()),
|
||||||
|
this.bb!.createObjList<ShipClass, ShipClassT>(this.localShipClass.bind(this), this.localShipClassLength()),
|
||||||
|
this.bb!.createObjList<OthersShipClass, OthersShipClassT>(this.otherShipClass.bind(this), this.otherShipClassLength()),
|
||||||
|
this.bb!.createObjList<UUID, UUIDT>(this.battle.bind(this), this.battleLength()),
|
||||||
|
this.bb!.createObjList<Bombing, BombingT>(this.bombing.bind(this), this.bombingLength()),
|
||||||
|
this.bb!.createObjList<IncomingGroup, IncomingGroupT>(this.incomingGroup.bind(this), this.incomingGroupLength()),
|
||||||
|
this.bb!.createObjList<LocalPlanet, LocalPlanetT>(this.localPlanet.bind(this), this.localPlanetLength()),
|
||||||
|
this.bb!.createObjList<ShipProduction, ShipProductionT>(this.shipProduction.bind(this), this.shipProductionLength()),
|
||||||
|
this.bb!.createObjList<Route, RouteT>(this.route.bind(this), this.routeLength()),
|
||||||
|
this.bb!.createObjList<OtherPlanet, OtherPlanetT>(this.otherPlanet.bind(this), this.otherPlanetLength()),
|
||||||
|
this.bb!.createObjList<UninhabitedPlanet, UninhabitedPlanetT>(this.uninhabitedPlanet.bind(this), this.uninhabitedPlanetLength()),
|
||||||
|
this.bb!.createObjList<UnidentifiedPlanet, UnidentifiedPlanetT>(this.unidentifiedPlanet.bind(this), this.unidentifiedPlanetLength()),
|
||||||
|
this.bb!.createObjList<LocalFleet, LocalFleetT>(this.localFleet.bind(this), this.localFleetLength()),
|
||||||
|
this.bb!.createObjList<LocalGroup, LocalGroupT>(this.localGroup.bind(this), this.localGroupLength()),
|
||||||
|
this.bb!.createObjList<OtherGroup, OtherGroupT>(this.otherGroup.bind(this), this.otherGroupLength()),
|
||||||
|
this.bb!.createObjList<UnidentifiedGroup, UnidentifiedGroupT>(this.unidentifiedGroup.bind(this), this.unidentifiedGroupLength())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: ReportT): void {
|
||||||
|
_o.version = this.version();
|
||||||
|
_o.turn = this.turn();
|
||||||
|
_o.width = this.width();
|
||||||
|
_o.height = this.height();
|
||||||
|
_o.planetCount = this.planetCount();
|
||||||
|
_o.race = this.race();
|
||||||
|
_o.votes = this.votes();
|
||||||
|
_o.voteFor = this.voteFor();
|
||||||
|
_o.player = this.bb!.createObjList<Player, PlayerT>(this.player.bind(this), this.playerLength());
|
||||||
|
_o.localScience = this.bb!.createObjList<Science, ScienceT>(this.localScience.bind(this), this.localScienceLength());
|
||||||
|
_o.otherScience = this.bb!.createObjList<OtherScience, OtherScienceT>(this.otherScience.bind(this), this.otherScienceLength());
|
||||||
|
_o.localShipClass = this.bb!.createObjList<ShipClass, ShipClassT>(this.localShipClass.bind(this), this.localShipClassLength());
|
||||||
|
_o.otherShipClass = this.bb!.createObjList<OthersShipClass, OthersShipClassT>(this.otherShipClass.bind(this), this.otherShipClassLength());
|
||||||
|
_o.battle = this.bb!.createObjList<UUID, UUIDT>(this.battle.bind(this), this.battleLength());
|
||||||
|
_o.bombing = this.bb!.createObjList<Bombing, BombingT>(this.bombing.bind(this), this.bombingLength());
|
||||||
|
_o.incomingGroup = this.bb!.createObjList<IncomingGroup, IncomingGroupT>(this.incomingGroup.bind(this), this.incomingGroupLength());
|
||||||
|
_o.localPlanet = this.bb!.createObjList<LocalPlanet, LocalPlanetT>(this.localPlanet.bind(this), this.localPlanetLength());
|
||||||
|
_o.shipProduction = this.bb!.createObjList<ShipProduction, ShipProductionT>(this.shipProduction.bind(this), this.shipProductionLength());
|
||||||
|
_o.route = this.bb!.createObjList<Route, RouteT>(this.route.bind(this), this.routeLength());
|
||||||
|
_o.otherPlanet = this.bb!.createObjList<OtherPlanet, OtherPlanetT>(this.otherPlanet.bind(this), this.otherPlanetLength());
|
||||||
|
_o.uninhabitedPlanet = this.bb!.createObjList<UninhabitedPlanet, UninhabitedPlanetT>(this.uninhabitedPlanet.bind(this), this.uninhabitedPlanetLength());
|
||||||
|
_o.unidentifiedPlanet = this.bb!.createObjList<UnidentifiedPlanet, UnidentifiedPlanetT>(this.unidentifiedPlanet.bind(this), this.unidentifiedPlanetLength());
|
||||||
|
_o.localFleet = this.bb!.createObjList<LocalFleet, LocalFleetT>(this.localFleet.bind(this), this.localFleetLength());
|
||||||
|
_o.localGroup = this.bb!.createObjList<LocalGroup, LocalGroupT>(this.localGroup.bind(this), this.localGroupLength());
|
||||||
|
_o.otherGroup = this.bb!.createObjList<OtherGroup, OtherGroupT>(this.otherGroup.bind(this), this.otherGroupLength());
|
||||||
|
_o.unidentifiedGroup = this.bb!.createObjList<UnidentifiedGroup, UnidentifiedGroupT>(this.unidentifiedGroup.bind(this), this.unidentifiedGroupLength());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ReportT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public version: bigint = BigInt('0'),
|
||||||
|
public turn: bigint = BigInt('0'),
|
||||||
|
public width: number = 0,
|
||||||
|
public height: number = 0,
|
||||||
|
public planetCount: number = 0,
|
||||||
|
public race: string|Uint8Array|null = null,
|
||||||
|
public votes: number = 0.0,
|
||||||
|
public voteFor: string|Uint8Array|null = null,
|
||||||
|
public player: (PlayerT)[] = [],
|
||||||
|
public localScience: (ScienceT)[] = [],
|
||||||
|
public otherScience: (OtherScienceT)[] = [],
|
||||||
|
public localShipClass: (ShipClassT)[] = [],
|
||||||
|
public otherShipClass: (OthersShipClassT)[] = [],
|
||||||
|
public battle: (UUIDT)[] = [],
|
||||||
|
public bombing: (BombingT)[] = [],
|
||||||
|
public incomingGroup: (IncomingGroupT)[] = [],
|
||||||
|
public localPlanet: (LocalPlanetT)[] = [],
|
||||||
|
public shipProduction: (ShipProductionT)[] = [],
|
||||||
|
public route: (RouteT)[] = [],
|
||||||
|
public otherPlanet: (OtherPlanetT)[] = [],
|
||||||
|
public uninhabitedPlanet: (UninhabitedPlanetT)[] = [],
|
||||||
|
public unidentifiedPlanet: (UnidentifiedPlanetT)[] = [],
|
||||||
|
public localFleet: (LocalFleetT)[] = [],
|
||||||
|
public localGroup: (LocalGroupT)[] = [],
|
||||||
|
public otherGroup: (OtherGroupT)[] = [],
|
||||||
|
public unidentifiedGroup: (UnidentifiedGroupT)[] = []
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
const race = (this.race !== null ? builder.createString(this.race!) : 0);
|
||||||
|
const voteFor = (this.voteFor !== null ? builder.createString(this.voteFor!) : 0);
|
||||||
|
const player = Report.createPlayerVector(builder, builder.createObjectOffsetList(this.player));
|
||||||
|
const localScience = Report.createLocalScienceVector(builder, builder.createObjectOffsetList(this.localScience));
|
||||||
|
const otherScience = Report.createOtherScienceVector(builder, builder.createObjectOffsetList(this.otherScience));
|
||||||
|
const localShipClass = Report.createLocalShipClassVector(builder, builder.createObjectOffsetList(this.localShipClass));
|
||||||
|
const otherShipClass = Report.createOtherShipClassVector(builder, builder.createObjectOffsetList(this.otherShipClass));
|
||||||
|
const battle = builder.createStructOffsetList(this.battle, Report.startBattleVector);
|
||||||
|
const bombing = Report.createBombingVector(builder, builder.createObjectOffsetList(this.bombing));
|
||||||
|
const incomingGroup = Report.createIncomingGroupVector(builder, builder.createObjectOffsetList(this.incomingGroup));
|
||||||
|
const localPlanet = Report.createLocalPlanetVector(builder, builder.createObjectOffsetList(this.localPlanet));
|
||||||
|
const shipProduction = Report.createShipProductionVector(builder, builder.createObjectOffsetList(this.shipProduction));
|
||||||
|
const route = Report.createRouteVector(builder, builder.createObjectOffsetList(this.route));
|
||||||
|
const otherPlanet = Report.createOtherPlanetVector(builder, builder.createObjectOffsetList(this.otherPlanet));
|
||||||
|
const uninhabitedPlanet = Report.createUninhabitedPlanetVector(builder, builder.createObjectOffsetList(this.uninhabitedPlanet));
|
||||||
|
const unidentifiedPlanet = Report.createUnidentifiedPlanetVector(builder, builder.createObjectOffsetList(this.unidentifiedPlanet));
|
||||||
|
const localFleet = Report.createLocalFleetVector(builder, builder.createObjectOffsetList(this.localFleet));
|
||||||
|
const localGroup = Report.createLocalGroupVector(builder, builder.createObjectOffsetList(this.localGroup));
|
||||||
|
const otherGroup = Report.createOtherGroupVector(builder, builder.createObjectOffsetList(this.otherGroup));
|
||||||
|
const unidentifiedGroup = Report.createUnidentifiedGroupVector(builder, builder.createObjectOffsetList(this.unidentifiedGroup));
|
||||||
|
|
||||||
|
return Report.createReport(builder,
|
||||||
|
this.version,
|
||||||
|
this.turn,
|
||||||
|
this.width,
|
||||||
|
this.height,
|
||||||
|
this.planetCount,
|
||||||
|
race,
|
||||||
|
this.votes,
|
||||||
|
voteFor,
|
||||||
|
player,
|
||||||
|
localScience,
|
||||||
|
otherScience,
|
||||||
|
localShipClass,
|
||||||
|
otherShipClass,
|
||||||
|
battle,
|
||||||
|
bombing,
|
||||||
|
incomingGroup,
|
||||||
|
localPlanet,
|
||||||
|
shipProduction,
|
||||||
|
route,
|
||||||
|
otherPlanet,
|
||||||
|
uninhabitedPlanet,
|
||||||
|
unidentifiedPlanet,
|
||||||
|
localFleet,
|
||||||
|
localGroup,
|
||||||
|
otherGroup,
|
||||||
|
unidentifiedGroup
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export class RouteEntry implements flatbuffers.IUnpackableObject<RouteEntryT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):RouteEntry {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRootAsRouteEntry(bb:flatbuffers.ByteBuffer, obj?:RouteEntry):RouteEntry {
|
||||||
|
return (obj || new RouteEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSizePrefixedRootAsRouteEntry(bb:flatbuffers.ByteBuffer, obj?:RouteEntry):RouteEntry {
|
||||||
|
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||||
|
return (obj || new RouteEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
key():bigint {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
value():string|null
|
||||||
|
value(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
value(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static startRouteEntry(builder:flatbuffers.Builder) {
|
||||||
|
builder.startObject(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addKey(builder:flatbuffers.Builder, key:bigint) {
|
||||||
|
builder.addFieldInt64(0, key, BigInt('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static addValue(builder:flatbuffers.Builder, valueOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(1, valueOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static endRouteEntry(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
|
const offset = builder.endObject();
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createRouteEntry(builder:flatbuffers.Builder, key:bigint, valueOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||||
|
RouteEntry.startRouteEntry(builder);
|
||||||
|
RouteEntry.addKey(builder, key);
|
||||||
|
RouteEntry.addValue(builder, valueOffset);
|
||||||
|
return RouteEntry.endRouteEntry(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack(): RouteEntryT {
|
||||||
|
return new RouteEntryT(
|
||||||
|
this.key(),
|
||||||
|
this.value()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: RouteEntryT): void {
|
||||||
|
_o.key = this.key();
|
||||||
|
_o.value = this.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class RouteEntryT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public key: bigint = BigInt('0'),
|
||||||
|
public value: string|Uint8Array|null = null
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
const value = (this.value !== null ? builder.createString(this.value!) : 0);
|
||||||
|
|
||||||
|
return RouteEntry.createRouteEntry(builder,
|
||||||
|
this.key,
|
||||||
|
value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
import { RouteEntry, RouteEntryT } from './route-entry.js';
|
||||||
|
|
||||||
|
|
||||||
|
export class Route implements flatbuffers.IUnpackableObject<RouteT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):Route {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRootAsRoute(bb:flatbuffers.ByteBuffer, obj?:Route):Route {
|
||||||
|
return (obj || new Route()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSizePrefixedRootAsRoute(bb:flatbuffers.ByteBuffer, obj?:Route):Route {
|
||||||
|
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||||
|
return (obj || new Route()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
planet():bigint {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
route(index: number, obj?:RouteEntry):RouteEntry|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? (obj || new RouteEntry()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
routeLength():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static startRoute(builder:flatbuffers.Builder) {
|
||||||
|
builder.startObject(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addPlanet(builder:flatbuffers.Builder, planet:bigint) {
|
||||||
|
builder.addFieldInt64(0, planet, BigInt('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static addRoute(builder:flatbuffers.Builder, routeOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(1, routeOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createRouteVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||||
|
builder.startVector(4, data.length, 4);
|
||||||
|
for (let i = data.length - 1; i >= 0; i--) {
|
||||||
|
builder.addOffset(data[i]!);
|
||||||
|
}
|
||||||
|
return builder.endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
static startRouteVector(builder:flatbuffers.Builder, numElems:number) {
|
||||||
|
builder.startVector(4, numElems, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static endRoute(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
|
const offset = builder.endObject();
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createRoute(builder:flatbuffers.Builder, planet:bigint, routeOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||||
|
Route.startRoute(builder);
|
||||||
|
Route.addPlanet(builder, planet);
|
||||||
|
Route.addRoute(builder, routeOffset);
|
||||||
|
return Route.endRoute(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack(): RouteT {
|
||||||
|
return new RouteT(
|
||||||
|
this.planet(),
|
||||||
|
this.bb!.createObjList<RouteEntry, RouteEntryT>(this.route.bind(this), this.routeLength())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: RouteT): void {
|
||||||
|
_o.planet = this.planet();
|
||||||
|
_o.route = this.bb!.createObjList<RouteEntry, RouteEntryT>(this.route.bind(this), this.routeLength());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class RouteT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public planet: bigint = BigInt('0'),
|
||||||
|
public route: (RouteEntryT)[] = []
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
const route = Route.createRouteVector(builder, builder.createObjectOffsetList(this.route));
|
||||||
|
|
||||||
|
return Route.createRoute(builder,
|
||||||
|
this.planet,
|
||||||
|
route
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export class Science implements flatbuffers.IUnpackableObject<ScienceT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):Science {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRootAsScience(bb:flatbuffers.ByteBuffer, obj?:Science):Science {
|
||||||
|
return (obj || new Science()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSizePrefixedRootAsScience(bb:flatbuffers.ByteBuffer, obj?:Science):Science {
|
||||||
|
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||||
|
return (obj || new Science()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
name():string|null
|
||||||
|
name(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
name(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
drive():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
weapons():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
shields():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cargo():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static startScience(builder:flatbuffers.Builder) {
|
||||||
|
builder.startObject(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addName(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(0, nameOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addDrive(builder:flatbuffers.Builder, drive:number) {
|
||||||
|
builder.addFieldFloat32(1, drive, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addWeapons(builder:flatbuffers.Builder, weapons:number) {
|
||||||
|
builder.addFieldFloat32(2, weapons, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addShields(builder:flatbuffers.Builder, shields:number) {
|
||||||
|
builder.addFieldFloat32(3, shields, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addCargo(builder:flatbuffers.Builder, cargo:number) {
|
||||||
|
builder.addFieldFloat32(4, cargo, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static endScience(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
|
const offset = builder.endObject();
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createScience(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, drive:number, weapons:number, shields:number, cargo:number):flatbuffers.Offset {
|
||||||
|
Science.startScience(builder);
|
||||||
|
Science.addName(builder, nameOffset);
|
||||||
|
Science.addDrive(builder, drive);
|
||||||
|
Science.addWeapons(builder, weapons);
|
||||||
|
Science.addShields(builder, shields);
|
||||||
|
Science.addCargo(builder, cargo);
|
||||||
|
return Science.endScience(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack(): ScienceT {
|
||||||
|
return new ScienceT(
|
||||||
|
this.name(),
|
||||||
|
this.drive(),
|
||||||
|
this.weapons(),
|
||||||
|
this.shields(),
|
||||||
|
this.cargo()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: ScienceT): void {
|
||||||
|
_o.name = this.name();
|
||||||
|
_o.drive = this.drive();
|
||||||
|
_o.weapons = this.weapons();
|
||||||
|
_o.shields = this.shields();
|
||||||
|
_o.cargo = this.cargo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ScienceT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public name: string|Uint8Array|null = null,
|
||||||
|
public drive: number = 0.0,
|
||||||
|
public weapons: number = 0.0,
|
||||||
|
public shields: number = 0.0,
|
||||||
|
public cargo: number = 0.0
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
const name = (this.name !== null ? builder.createString(this.name!) : 0);
|
||||||
|
|
||||||
|
return Science.createScience(builder,
|
||||||
|
name,
|
||||||
|
this.drive,
|
||||||
|
this.weapons,
|
||||||
|
this.shields,
|
||||||
|
this.cargo
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export class ShipClass implements flatbuffers.IUnpackableObject<ShipClassT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):ShipClass {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRootAsShipClass(bb:flatbuffers.ByteBuffer, obj?:ShipClass):ShipClass {
|
||||||
|
return (obj || new ShipClass()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSizePrefixedRootAsShipClass(bb:flatbuffers.ByteBuffer, obj?:ShipClass):ShipClass {
|
||||||
|
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||||
|
return (obj || new ShipClass()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
name():string|null
|
||||||
|
name(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
name(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
drive():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
armament():bigint {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
weapons():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
shields():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cargo():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mass():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 16);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static startShipClass(builder:flatbuffers.Builder) {
|
||||||
|
builder.startObject(7);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addName(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(0, nameOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addDrive(builder:flatbuffers.Builder, drive:number) {
|
||||||
|
builder.addFieldFloat32(1, drive, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addArmament(builder:flatbuffers.Builder, armament:bigint) {
|
||||||
|
builder.addFieldInt64(2, armament, BigInt('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static addWeapons(builder:flatbuffers.Builder, weapons:number) {
|
||||||
|
builder.addFieldFloat32(3, weapons, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addShields(builder:flatbuffers.Builder, shields:number) {
|
||||||
|
builder.addFieldFloat32(4, shields, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addCargo(builder:flatbuffers.Builder, cargo:number) {
|
||||||
|
builder.addFieldFloat32(5, cargo, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addMass(builder:flatbuffers.Builder, mass:number) {
|
||||||
|
builder.addFieldFloat32(6, mass, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static endShipClass(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
|
const offset = builder.endObject();
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createShipClass(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, drive:number, armament:bigint, weapons:number, shields:number, cargo:number, mass:number):flatbuffers.Offset {
|
||||||
|
ShipClass.startShipClass(builder);
|
||||||
|
ShipClass.addName(builder, nameOffset);
|
||||||
|
ShipClass.addDrive(builder, drive);
|
||||||
|
ShipClass.addArmament(builder, armament);
|
||||||
|
ShipClass.addWeapons(builder, weapons);
|
||||||
|
ShipClass.addShields(builder, shields);
|
||||||
|
ShipClass.addCargo(builder, cargo);
|
||||||
|
ShipClass.addMass(builder, mass);
|
||||||
|
return ShipClass.endShipClass(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack(): ShipClassT {
|
||||||
|
return new ShipClassT(
|
||||||
|
this.name(),
|
||||||
|
this.drive(),
|
||||||
|
this.armament(),
|
||||||
|
this.weapons(),
|
||||||
|
this.shields(),
|
||||||
|
this.cargo(),
|
||||||
|
this.mass()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: ShipClassT): void {
|
||||||
|
_o.name = this.name();
|
||||||
|
_o.drive = this.drive();
|
||||||
|
_o.armament = this.armament();
|
||||||
|
_o.weapons = this.weapons();
|
||||||
|
_o.shields = this.shields();
|
||||||
|
_o.cargo = this.cargo();
|
||||||
|
_o.mass = this.mass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ShipClassT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public name: string|Uint8Array|null = null,
|
||||||
|
public drive: number = 0.0,
|
||||||
|
public armament: bigint = BigInt('0'),
|
||||||
|
public weapons: number = 0.0,
|
||||||
|
public shields: number = 0.0,
|
||||||
|
public cargo: number = 0.0,
|
||||||
|
public mass: number = 0.0
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
const name = (this.name !== null ? builder.createString(this.name!) : 0);
|
||||||
|
|
||||||
|
return ShipClass.createShipClass(builder,
|
||||||
|
name,
|
||||||
|
this.drive,
|
||||||
|
this.armament,
|
||||||
|
this.weapons,
|
||||||
|
this.shields,
|
||||||
|
this.cargo,
|
||||||
|
this.mass
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export class ShipProduction implements flatbuffers.IUnpackableObject<ShipProductionT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):ShipProduction {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRootAsShipProduction(bb:flatbuffers.ByteBuffer, obj?:ShipProduction):ShipProduction {
|
||||||
|
return (obj || new ShipProduction()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSizePrefixedRootAsShipProduction(bb:flatbuffers.ByteBuffer, obj?:ShipProduction):ShipProduction {
|
||||||
|
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||||
|
return (obj || new ShipProduction()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
planet():bigint {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
class_():string|null
|
||||||
|
class_(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
class_(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
cost():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
prodUsed():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
percent():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
free():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static startShipProduction(builder:flatbuffers.Builder) {
|
||||||
|
builder.startObject(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addPlanet(builder:flatbuffers.Builder, planet:bigint) {
|
||||||
|
builder.addFieldInt64(0, planet, BigInt('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static addClass(builder:flatbuffers.Builder, class_Offset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(1, class_Offset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addCost(builder:flatbuffers.Builder, cost:number) {
|
||||||
|
builder.addFieldFloat32(2, cost, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addProdUsed(builder:flatbuffers.Builder, prodUsed:number) {
|
||||||
|
builder.addFieldFloat32(3, prodUsed, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addPercent(builder:flatbuffers.Builder, percent:number) {
|
||||||
|
builder.addFieldFloat32(4, percent, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addFree(builder:flatbuffers.Builder, free:number) {
|
||||||
|
builder.addFieldFloat32(5, free, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static endShipProduction(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
|
const offset = builder.endObject();
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createShipProduction(builder:flatbuffers.Builder, planet:bigint, class_Offset:flatbuffers.Offset, cost:number, prodUsed:number, percent:number, free:number):flatbuffers.Offset {
|
||||||
|
ShipProduction.startShipProduction(builder);
|
||||||
|
ShipProduction.addPlanet(builder, planet);
|
||||||
|
ShipProduction.addClass(builder, class_Offset);
|
||||||
|
ShipProduction.addCost(builder, cost);
|
||||||
|
ShipProduction.addProdUsed(builder, prodUsed);
|
||||||
|
ShipProduction.addPercent(builder, percent);
|
||||||
|
ShipProduction.addFree(builder, free);
|
||||||
|
return ShipProduction.endShipProduction(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack(): ShipProductionT {
|
||||||
|
return new ShipProductionT(
|
||||||
|
this.planet(),
|
||||||
|
this.class_(),
|
||||||
|
this.cost(),
|
||||||
|
this.prodUsed(),
|
||||||
|
this.percent(),
|
||||||
|
this.free()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: ShipProductionT): void {
|
||||||
|
_o.planet = this.planet();
|
||||||
|
_o.class_ = this.class_();
|
||||||
|
_o.cost = this.cost();
|
||||||
|
_o.prodUsed = this.prodUsed();
|
||||||
|
_o.percent = this.percent();
|
||||||
|
_o.free = this.free();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ShipProductionT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public planet: bigint = BigInt('0'),
|
||||||
|
public class_: string|Uint8Array|null = null,
|
||||||
|
public cost: number = 0.0,
|
||||||
|
public prodUsed: number = 0.0,
|
||||||
|
public percent: number = 0.0,
|
||||||
|
public free: number = 0.0
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
const class_ = (this.class_ !== null ? builder.createString(this.class_!) : 0);
|
||||||
|
|
||||||
|
return ShipProduction.createShipProduction(builder,
|
||||||
|
this.planet,
|
||||||
|
class_,
|
||||||
|
this.cost,
|
||||||
|
this.prodUsed,
|
||||||
|
this.percent,
|
||||||
|
this.free
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export class TechEntry implements flatbuffers.IUnpackableObject<TechEntryT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):TechEntry {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRootAsTechEntry(bb:flatbuffers.ByteBuffer, obj?:TechEntry):TechEntry {
|
||||||
|
return (obj || new TechEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSizePrefixedRootAsTechEntry(bb:flatbuffers.ByteBuffer, obj?:TechEntry):TechEntry {
|
||||||
|
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||||
|
return (obj || new TechEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
key():string|null
|
||||||
|
key(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
key(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
value():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static startTechEntry(builder:flatbuffers.Builder) {
|
||||||
|
builder.startObject(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addKey(builder:flatbuffers.Builder, keyOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(0, keyOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addValue(builder:flatbuffers.Builder, value:number) {
|
||||||
|
builder.addFieldFloat32(1, value, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static endTechEntry(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
|
const offset = builder.endObject();
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createTechEntry(builder:flatbuffers.Builder, keyOffset:flatbuffers.Offset, value:number):flatbuffers.Offset {
|
||||||
|
TechEntry.startTechEntry(builder);
|
||||||
|
TechEntry.addKey(builder, keyOffset);
|
||||||
|
TechEntry.addValue(builder, value);
|
||||||
|
return TechEntry.endTechEntry(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack(): TechEntryT {
|
||||||
|
return new TechEntryT(
|
||||||
|
this.key(),
|
||||||
|
this.value()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: TechEntryT): void {
|
||||||
|
_o.key = this.key();
|
||||||
|
_o.value = this.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TechEntryT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public key: string|Uint8Array|null = null,
|
||||||
|
public value: number = 0.0
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
const key = (this.key !== null ? builder.createString(this.key!) : 0);
|
||||||
|
|
||||||
|
return TechEntry.createTechEntry(builder,
|
||||||
|
key,
|
||||||
|
this.value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export class UnidentifiedGroup implements flatbuffers.IUnpackableObject<UnidentifiedGroupT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):UnidentifiedGroup {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRootAsUnidentifiedGroup(bb:flatbuffers.ByteBuffer, obj?:UnidentifiedGroup):UnidentifiedGroup {
|
||||||
|
return (obj || new UnidentifiedGroup()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSizePrefixedRootAsUnidentifiedGroup(bb:flatbuffers.ByteBuffer, obj?:UnidentifiedGroup):UnidentifiedGroup {
|
||||||
|
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||||
|
return (obj || new UnidentifiedGroup()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
x():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
y():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static startUnidentifiedGroup(builder:flatbuffers.Builder) {
|
||||||
|
builder.startObject(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addX(builder:flatbuffers.Builder, x:number) {
|
||||||
|
builder.addFieldFloat32(0, x, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addY(builder:flatbuffers.Builder, y:number) {
|
||||||
|
builder.addFieldFloat32(1, y, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static endUnidentifiedGroup(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
|
const offset = builder.endObject();
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createUnidentifiedGroup(builder:flatbuffers.Builder, x:number, y:number):flatbuffers.Offset {
|
||||||
|
UnidentifiedGroup.startUnidentifiedGroup(builder);
|
||||||
|
UnidentifiedGroup.addX(builder, x);
|
||||||
|
UnidentifiedGroup.addY(builder, y);
|
||||||
|
return UnidentifiedGroup.endUnidentifiedGroup(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack(): UnidentifiedGroupT {
|
||||||
|
return new UnidentifiedGroupT(
|
||||||
|
this.x(),
|
||||||
|
this.y()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: UnidentifiedGroupT): void {
|
||||||
|
_o.x = this.x();
|
||||||
|
_o.y = this.y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class UnidentifiedGroupT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public x: number = 0.0,
|
||||||
|
public y: number = 0.0
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
return UnidentifiedGroup.createUnidentifiedGroup(builder,
|
||||||
|
this.x,
|
||||||
|
this.y
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export class UnidentifiedPlanet implements flatbuffers.IUnpackableObject<UnidentifiedPlanetT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):UnidentifiedPlanet {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRootAsUnidentifiedPlanet(bb:flatbuffers.ByteBuffer, obj?:UnidentifiedPlanet):UnidentifiedPlanet {
|
||||||
|
return (obj || new UnidentifiedPlanet()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSizePrefixedRootAsUnidentifiedPlanet(bb:flatbuffers.ByteBuffer, obj?:UnidentifiedPlanet):UnidentifiedPlanet {
|
||||||
|
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||||
|
return (obj || new UnidentifiedPlanet()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
x():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
y():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
number():bigint {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
static startUnidentifiedPlanet(builder:flatbuffers.Builder) {
|
||||||
|
builder.startObject(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addX(builder:flatbuffers.Builder, x:number) {
|
||||||
|
builder.addFieldFloat32(0, x, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addY(builder:flatbuffers.Builder, y:number) {
|
||||||
|
builder.addFieldFloat32(1, y, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addNumber(builder:flatbuffers.Builder, number:bigint) {
|
||||||
|
builder.addFieldInt64(2, number, BigInt('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static endUnidentifiedPlanet(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
|
const offset = builder.endObject();
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createUnidentifiedPlanet(builder:flatbuffers.Builder, x:number, y:number, number:bigint):flatbuffers.Offset {
|
||||||
|
UnidentifiedPlanet.startUnidentifiedPlanet(builder);
|
||||||
|
UnidentifiedPlanet.addX(builder, x);
|
||||||
|
UnidentifiedPlanet.addY(builder, y);
|
||||||
|
UnidentifiedPlanet.addNumber(builder, number);
|
||||||
|
return UnidentifiedPlanet.endUnidentifiedPlanet(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack(): UnidentifiedPlanetT {
|
||||||
|
return new UnidentifiedPlanetT(
|
||||||
|
this.x(),
|
||||||
|
this.y(),
|
||||||
|
this.number()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: UnidentifiedPlanetT): void {
|
||||||
|
_o.x = this.x();
|
||||||
|
_o.y = this.y();
|
||||||
|
_o.number = this.number();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class UnidentifiedPlanetT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public x: number = 0.0,
|
||||||
|
public y: number = 0.0,
|
||||||
|
public number: bigint = BigInt('0')
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
return UnidentifiedPlanet.createUnidentifiedPlanet(builder,
|
||||||
|
this.x,
|
||||||
|
this.y,
|
||||||
|
this.number
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,176 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export class UninhabitedPlanet implements flatbuffers.IUnpackableObject<UninhabitedPlanetT> {
|
||||||
|
bb: flatbuffers.ByteBuffer|null = null;
|
||||||
|
bb_pos = 0;
|
||||||
|
__init(i:number, bb:flatbuffers.ByteBuffer):UninhabitedPlanet {
|
||||||
|
this.bb_pos = i;
|
||||||
|
this.bb = bb;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRootAsUninhabitedPlanet(bb:flatbuffers.ByteBuffer, obj?:UninhabitedPlanet):UninhabitedPlanet {
|
||||||
|
return (obj || new UninhabitedPlanet()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSizePrefixedRootAsUninhabitedPlanet(bb:flatbuffers.ByteBuffer, obj?:UninhabitedPlanet):UninhabitedPlanet {
|
||||||
|
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||||
|
return (obj || new UninhabitedPlanet()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
x():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
y():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
number():bigint {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||||
|
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
size():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
name():string|null
|
||||||
|
name(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||||
|
name(optionalEncoding?:any):string|Uint8Array|null {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||||
|
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
resources():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
capital():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 16);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
material():number {
|
||||||
|
const offset = this.bb!.__offset(this.bb_pos, 18);
|
||||||
|
return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static startUninhabitedPlanet(builder:flatbuffers.Builder) {
|
||||||
|
builder.startObject(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addX(builder:flatbuffers.Builder, x:number) {
|
||||||
|
builder.addFieldFloat32(0, x, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addY(builder:flatbuffers.Builder, y:number) {
|
||||||
|
builder.addFieldFloat32(1, y, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addNumber(builder:flatbuffers.Builder, number:bigint) {
|
||||||
|
builder.addFieldInt64(2, number, BigInt('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static addSize(builder:flatbuffers.Builder, size:number) {
|
||||||
|
builder.addFieldFloat32(3, size, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addName(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset) {
|
||||||
|
builder.addFieldOffset(4, nameOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addResources(builder:flatbuffers.Builder, resources:number) {
|
||||||
|
builder.addFieldFloat32(5, resources, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addCapital(builder:flatbuffers.Builder, capital:number) {
|
||||||
|
builder.addFieldFloat32(6, capital, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addMaterial(builder:flatbuffers.Builder, material:number) {
|
||||||
|
builder.addFieldFloat32(7, material, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static endUninhabitedPlanet(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||||
|
const offset = builder.endObject();
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createUninhabitedPlanet(builder:flatbuffers.Builder, x:number, y:number, number:bigint, size:number, nameOffset:flatbuffers.Offset, resources:number, capital:number, material:number):flatbuffers.Offset {
|
||||||
|
UninhabitedPlanet.startUninhabitedPlanet(builder);
|
||||||
|
UninhabitedPlanet.addX(builder, x);
|
||||||
|
UninhabitedPlanet.addY(builder, y);
|
||||||
|
UninhabitedPlanet.addNumber(builder, number);
|
||||||
|
UninhabitedPlanet.addSize(builder, size);
|
||||||
|
UninhabitedPlanet.addName(builder, nameOffset);
|
||||||
|
UninhabitedPlanet.addResources(builder, resources);
|
||||||
|
UninhabitedPlanet.addCapital(builder, capital);
|
||||||
|
UninhabitedPlanet.addMaterial(builder, material);
|
||||||
|
return UninhabitedPlanet.endUninhabitedPlanet(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack(): UninhabitedPlanetT {
|
||||||
|
return new UninhabitedPlanetT(
|
||||||
|
this.x(),
|
||||||
|
this.y(),
|
||||||
|
this.number(),
|
||||||
|
this.size(),
|
||||||
|
this.name(),
|
||||||
|
this.resources(),
|
||||||
|
this.capital(),
|
||||||
|
this.material()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unpackTo(_o: UninhabitedPlanetT): void {
|
||||||
|
_o.x = this.x();
|
||||||
|
_o.y = this.y();
|
||||||
|
_o.number = this.number();
|
||||||
|
_o.size = this.size();
|
||||||
|
_o.name = this.name();
|
||||||
|
_o.resources = this.resources();
|
||||||
|
_o.capital = this.capital();
|
||||||
|
_o.material = this.material();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class UninhabitedPlanetT implements flatbuffers.IGeneratedObject {
|
||||||
|
constructor(
|
||||||
|
public x: number = 0.0,
|
||||||
|
public y: number = 0.0,
|
||||||
|
public number: bigint = BigInt('0'),
|
||||||
|
public size: number = 0.0,
|
||||||
|
public name: string|Uint8Array|null = null,
|
||||||
|
public resources: number = 0.0,
|
||||||
|
public capital: number = 0.0,
|
||||||
|
public material: number = 0.0
|
||||||
|
){}
|
||||||
|
|
||||||
|
|
||||||
|
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||||
|
const name = (this.name !== null ? builder.createString(this.name!) : 0);
|
||||||
|
|
||||||
|
return UninhabitedPlanet.createUninhabitedPlanet(builder,
|
||||||
|
this.x,
|
||||||
|
this.y,
|
||||||
|
this.number,
|
||||||
|
this.size,
|
||||||
|
name,
|
||||||
|
this.resources,
|
||||||
|
this.capital,
|
||||||
|
this.material
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,11 +12,20 @@ layout owns:
|
|||||||
header view-menu naturally drops the overlay even if `mobileTool`
|
header view-menu naturally drops the overlay even if `mobileTool`
|
||||||
was set on a previous tap.
|
was set on a previous tap.
|
||||||
|
|
||||||
|
Phase 11 adds the per-game `GameStateStore` instance owned by this
|
||||||
|
layout: it constructs the `GalaxyClient`, fetches the matching lobby
|
||||||
|
record to discover `current_turn`, then loads the report. The store
|
||||||
|
is shared with descendants via `setContext("gameState", ...)` so the
|
||||||
|
header turn counter, the map view, and later inspector tabs all read
|
||||||
|
from the same snapshot.
|
||||||
|
|
||||||
State preservation across active-view switches works for free
|
State preservation across active-view switches works for free
|
||||||
because SvelteKit keeps this layout instance mounted while children
|
because SvelteKit keeps this layout instance mounted while children
|
||||||
swap.
|
swap; navigating between games unmounts and remounts the layout, so
|
||||||
|
the next game's snapshot is loaded fresh.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { onDestroy, onMount, setContext } from "svelte";
|
||||||
import { page } from "$app/state";
|
import { page } from "$app/state";
|
||||||
import Header from "$lib/header/header.svelte";
|
import Header from "$lib/header/header.svelte";
|
||||||
import Sidebar from "$lib/sidebar/sidebar.svelte";
|
import Sidebar from "$lib/sidebar/sidebar.svelte";
|
||||||
@@ -24,6 +33,13 @@ swap.
|
|||||||
import Calculator from "$lib/sidebar/calculator-tab.svelte";
|
import Calculator from "$lib/sidebar/calculator-tab.svelte";
|
||||||
import Order from "$lib/sidebar/order-tab.svelte";
|
import Order from "$lib/sidebar/order-tab.svelte";
|
||||||
import type { MobileTool } from "$lib/sidebar/types";
|
import type { MobileTool } from "$lib/sidebar/types";
|
||||||
|
import { GameStateStore, GAME_STATE_CONTEXT_KEY } from "$lib/game-state.svelte";
|
||||||
|
import { session } from "$lib/session-store.svelte";
|
||||||
|
import { loadStore } from "../../../platform/store/index";
|
||||||
|
import { loadCore } from "../../../platform/core/index";
|
||||||
|
import { createEdgeGatewayClient } from "../../../api/connect";
|
||||||
|
import { GalaxyClient } from "../../../api/galaxy-client";
|
||||||
|
import { GATEWAY_BASE_URL, GATEWAY_RESPONSE_PUBLIC_KEY } from "$lib/env";
|
||||||
|
|
||||||
let { children } = $props();
|
let { children } = $props();
|
||||||
|
|
||||||
@@ -36,9 +52,54 @@ swap.
|
|||||||
isOnMap ? mobileTool : "map",
|
isOnMap ? mobileTool : "map",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const gameState = new GameStateStore();
|
||||||
|
setContext(GAME_STATE_CONTEXT_KEY, gameState);
|
||||||
|
|
||||||
function toggleSidebar(): void {
|
function toggleSidebar(): void {
|
||||||
sidebarOpen = !sidebarOpen;
|
sidebarOpen = !sidebarOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function sha256(payload: Uint8Array): Promise<Uint8Array> {
|
||||||
|
const digest = await crypto.subtle.digest("SHA-256", payload as BufferSource);
|
||||||
|
return new Uint8Array(digest);
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
(async (): Promise<void> => {
|
||||||
|
if (
|
||||||
|
session.keypair === null ||
|
||||||
|
session.deviceSessionId === null ||
|
||||||
|
GATEWAY_RESPONSE_PUBLIC_KEY.length === 0
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const keypair = session.keypair;
|
||||||
|
const deviceSessionId = session.deviceSessionId;
|
||||||
|
try {
|
||||||
|
const [{ cache }, core] = await Promise.all([loadStore(), loadCore()]);
|
||||||
|
const client = new GalaxyClient({
|
||||||
|
core,
|
||||||
|
edge: createEdgeGatewayClient(GATEWAY_BASE_URL),
|
||||||
|
signer: (canonical) => keypair.sign(canonical),
|
||||||
|
sha256,
|
||||||
|
deviceSessionId,
|
||||||
|
gatewayResponsePublicKey: GATEWAY_RESPONSE_PUBLIC_KEY,
|
||||||
|
});
|
||||||
|
await gameState.init({ client, cache, gameId });
|
||||||
|
} catch (err) {
|
||||||
|
gameState.failBootstrap(describeBootstrapError(err));
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
});
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
gameState.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
function describeBootstrapError(err: unknown): string {
|
||||||
|
if (err instanceof Error) return err.message;
|
||||||
|
return "request failed";
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="game-shell" data-testid="game-shell">
|
<div class="game-shell" data-testid="game-shell">
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ export interface GameFixture {
|
|||||||
enrollmentEndsAtMs?: bigint;
|
enrollmentEndsAtMs?: bigint;
|
||||||
createdAtMs?: bigint;
|
createdAtMs?: bigint;
|
||||||
updatedAtMs?: bigint;
|
updatedAtMs?: bigint;
|
||||||
|
currentTurn?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ApplicationFixture {
|
export interface ApplicationFixture {
|
||||||
@@ -79,6 +80,7 @@ function encodeGame(builder: Builder, game: GameFixture): number {
|
|||||||
GameSummary.addEnrollmentEndsAtMs(builder, game.enrollmentEndsAtMs ?? DEFAULT_TIME_MS);
|
GameSummary.addEnrollmentEndsAtMs(builder, game.enrollmentEndsAtMs ?? DEFAULT_TIME_MS);
|
||||||
GameSummary.addCreatedAtMs(builder, game.createdAtMs ?? DEFAULT_TIME_MS);
|
GameSummary.addCreatedAtMs(builder, game.createdAtMs ?? DEFAULT_TIME_MS);
|
||||||
GameSummary.addUpdatedAtMs(builder, game.updatedAtMs ?? DEFAULT_TIME_MS);
|
GameSummary.addUpdatedAtMs(builder, game.updatedAtMs ?? DEFAULT_TIME_MS);
|
||||||
|
GameSummary.addCurrentTurn(builder, game.currentTurn ?? 0);
|
||||||
return GameSummary.endGameSummary(builder);
|
return GameSummary.endGameSummary(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,129 @@
|
|||||||
|
// Phase 11 helpers for forging FlatBuffers report payloads in e2e
|
||||||
|
// tests. Mirrors the engine's `report.Report` shape so the mocked
|
||||||
|
// gateway can return realistic data without standing up the real
|
||||||
|
// engine container.
|
||||||
|
//
|
||||||
|
// Phase 11 only renders planets, so the helpers keep the report shape
|
||||||
|
// minimal (turn / dimensions / planet vectors). Later phases extend
|
||||||
|
// the helper as ships, fleets, sciences, etc. land.
|
||||||
|
|
||||||
|
import { Builder } from "flatbuffers";
|
||||||
|
|
||||||
|
import {
|
||||||
|
LocalPlanet,
|
||||||
|
OtherPlanet,
|
||||||
|
Report,
|
||||||
|
UnidentifiedPlanet,
|
||||||
|
UninhabitedPlanet,
|
||||||
|
} from "../../../src/proto/galaxy/fbs/report";
|
||||||
|
|
||||||
|
export interface PlanetFixture {
|
||||||
|
number: number;
|
||||||
|
name: string;
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OtherPlanetFixture extends PlanetFixture {
|
||||||
|
owner: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReportFixture {
|
||||||
|
turn: number;
|
||||||
|
mapWidth?: number;
|
||||||
|
mapHeight?: number;
|
||||||
|
localPlanets?: PlanetFixture[];
|
||||||
|
otherPlanets?: OtherPlanetFixture[];
|
||||||
|
uninhabitedPlanets?: PlanetFixture[];
|
||||||
|
unidentifiedPlanets?: { number: number; x: number; y: number }[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildReportPayload(fixture: ReportFixture): Uint8Array {
|
||||||
|
const builder = new Builder(512);
|
||||||
|
|
||||||
|
const localOffsets = (fixture.localPlanets ?? []).map((planet) => {
|
||||||
|
const name = builder.createString(planet.name);
|
||||||
|
LocalPlanet.startLocalPlanet(builder);
|
||||||
|
LocalPlanet.addNumber(builder, BigInt(planet.number));
|
||||||
|
LocalPlanet.addX(builder, planet.x);
|
||||||
|
LocalPlanet.addY(builder, planet.y);
|
||||||
|
LocalPlanet.addName(builder, name);
|
||||||
|
LocalPlanet.addSize(builder, 10);
|
||||||
|
LocalPlanet.addResources(builder, 0.5);
|
||||||
|
LocalPlanet.addPopulation(builder, 0);
|
||||||
|
LocalPlanet.addIndustry(builder, 0);
|
||||||
|
return LocalPlanet.endLocalPlanet(builder);
|
||||||
|
});
|
||||||
|
|
||||||
|
const otherOffsets = (fixture.otherPlanets ?? []).map((planet) => {
|
||||||
|
const name = builder.createString(planet.name);
|
||||||
|
const owner = builder.createString(planet.owner);
|
||||||
|
OtherPlanet.startOtherPlanet(builder);
|
||||||
|
OtherPlanet.addNumber(builder, BigInt(planet.number));
|
||||||
|
OtherPlanet.addX(builder, planet.x);
|
||||||
|
OtherPlanet.addY(builder, planet.y);
|
||||||
|
OtherPlanet.addName(builder, name);
|
||||||
|
OtherPlanet.addOwner(builder, owner);
|
||||||
|
OtherPlanet.addSize(builder, 9);
|
||||||
|
return OtherPlanet.endOtherPlanet(builder);
|
||||||
|
});
|
||||||
|
|
||||||
|
const uninhabitedOffsets = (fixture.uninhabitedPlanets ?? []).map(
|
||||||
|
(planet) => {
|
||||||
|
const name = builder.createString(planet.name);
|
||||||
|
UninhabitedPlanet.startUninhabitedPlanet(builder);
|
||||||
|
UninhabitedPlanet.addNumber(builder, BigInt(planet.number));
|
||||||
|
UninhabitedPlanet.addX(builder, planet.x);
|
||||||
|
UninhabitedPlanet.addY(builder, planet.y);
|
||||||
|
UninhabitedPlanet.addName(builder, name);
|
||||||
|
UninhabitedPlanet.addSize(builder, 6);
|
||||||
|
return UninhabitedPlanet.endUninhabitedPlanet(builder);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const unidentifiedOffsets = (fixture.unidentifiedPlanets ?? []).map(
|
||||||
|
(planet) => {
|
||||||
|
UnidentifiedPlanet.startUnidentifiedPlanet(builder);
|
||||||
|
UnidentifiedPlanet.addNumber(builder, BigInt(planet.number));
|
||||||
|
UnidentifiedPlanet.addX(builder, planet.x);
|
||||||
|
UnidentifiedPlanet.addY(builder, planet.y);
|
||||||
|
return UnidentifiedPlanet.endUnidentifiedPlanet(builder);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const localVec =
|
||||||
|
localOffsets.length === 0
|
||||||
|
? null
|
||||||
|
: Report.createLocalPlanetVector(builder, localOffsets);
|
||||||
|
const otherVec =
|
||||||
|
otherOffsets.length === 0
|
||||||
|
? null
|
||||||
|
: Report.createOtherPlanetVector(builder, otherOffsets);
|
||||||
|
const uninhabitedVec =
|
||||||
|
uninhabitedOffsets.length === 0
|
||||||
|
? null
|
||||||
|
: Report.createUninhabitedPlanetVector(builder, uninhabitedOffsets);
|
||||||
|
const unidentifiedVec =
|
||||||
|
unidentifiedOffsets.length === 0
|
||||||
|
? null
|
||||||
|
: Report.createUnidentifiedPlanetVector(builder, unidentifiedOffsets);
|
||||||
|
|
||||||
|
const totalPlanets =
|
||||||
|
(fixture.localPlanets ?? []).length +
|
||||||
|
(fixture.otherPlanets ?? []).length +
|
||||||
|
(fixture.uninhabitedPlanets ?? []).length +
|
||||||
|
(fixture.unidentifiedPlanets ?? []).length;
|
||||||
|
|
||||||
|
Report.startReport(builder);
|
||||||
|
Report.addTurn(builder, BigInt(fixture.turn));
|
||||||
|
Report.addWidth(builder, fixture.mapWidth ?? 4000);
|
||||||
|
Report.addHeight(builder, fixture.mapHeight ?? 4000);
|
||||||
|
Report.addPlanetCount(builder, totalPlanets);
|
||||||
|
if (localVec !== null) Report.addLocalPlanet(builder, localVec);
|
||||||
|
if (otherVec !== null) Report.addOtherPlanet(builder, otherVec);
|
||||||
|
if (uninhabitedVec !== null) Report.addUninhabitedPlanet(builder, uninhabitedVec);
|
||||||
|
if (unidentifiedVec !== null) Report.addUnidentifiedPlanet(builder, unidentifiedVec);
|
||||||
|
const reportOff = Report.endReport(builder);
|
||||||
|
builder.finish(reportOff);
|
||||||
|
return builder.asUint8Array();
|
||||||
|
}
|
||||||
@@ -0,0 +1,239 @@
|
|||||||
|
// Phase 11 end-to-end coverage for the live map integration. Boots
|
||||||
|
// an authenticated session through `/__debug/store`, mocks the two
|
||||||
|
// gateway calls the layout makes (`lobby.my.games.list` and
|
||||||
|
// `user.games.report`), navigates to `/games/<game-id>/map`, and
|
||||||
|
// asserts the chrome reflects the live data: turn counter shows the
|
||||||
|
// reported turn, the map view enters its `ready` state with a
|
||||||
|
// non-zero planet count, and a zero-planet response renders the
|
||||||
|
// empty world without errors.
|
||||||
|
|
||||||
|
import { fromJson, type JsonValue } from "@bufbuild/protobuf";
|
||||||
|
import { expect, test, type Page } from "@playwright/test";
|
||||||
|
import { ByteBuffer } from "flatbuffers";
|
||||||
|
|
||||||
|
import { ExecuteCommandRequestSchema } from "../../src/proto/galaxy/gateway/v1/edge_gateway_pb";
|
||||||
|
import { UUID } from "../../src/proto/galaxy/fbs/common";
|
||||||
|
import { GameReportRequest } from "../../src/proto/galaxy/fbs/report";
|
||||||
|
import { forgeExecuteCommandResponseJson } from "./fixtures/sign-response";
|
||||||
|
import {
|
||||||
|
buildMyGamesListPayload,
|
||||||
|
type GameFixture,
|
||||||
|
} from "./fixtures/lobby-fbs";
|
||||||
|
import { buildReportPayload } from "./fixtures/report-fbs";
|
||||||
|
|
||||||
|
const SESSION_ID = "phase-11-map-session";
|
||||||
|
const GAME_ID = "11111111-2222-3333-4444-555555555555";
|
||||||
|
|
||||||
|
interface MockOpts {
|
||||||
|
currentTurn: number;
|
||||||
|
report: Parameters<typeof buildReportPayload>[0];
|
||||||
|
gameId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MockState {
|
||||||
|
reportRequests: Array<{ gameId: string; turn: number }>;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function mockGateway(page: Page, opts: MockOpts): Promise<MockState> {
|
||||||
|
const state: MockState = { reportRequests: [] };
|
||||||
|
const gameId = opts.gameId ?? GAME_ID;
|
||||||
|
|
||||||
|
const game: GameFixture = {
|
||||||
|
gameId,
|
||||||
|
gameName: "Phase 11 Game",
|
||||||
|
gameType: "private",
|
||||||
|
status: "running",
|
||||||
|
ownerUserId: "user-1",
|
||||||
|
minPlayers: 2,
|
||||||
|
maxPlayers: 8,
|
||||||
|
enrollmentEndsAtMs: BigInt(Date.now() + 86_400_000),
|
||||||
|
createdAtMs: BigInt(Date.now() - 86_400_000),
|
||||||
|
updatedAtMs: BigInt(Date.now()),
|
||||||
|
currentTurn: opts.currentTurn,
|
||||||
|
};
|
||||||
|
|
||||||
|
await page.route(
|
||||||
|
"**/galaxy.gateway.v1.EdgeGateway/ExecuteCommand",
|
||||||
|
async (route) => {
|
||||||
|
const reqText = route.request().postData();
|
||||||
|
if (reqText === null) {
|
||||||
|
await route.fulfill({ status: 400 });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const req = fromJson(
|
||||||
|
ExecuteCommandRequestSchema,
|
||||||
|
JSON.parse(reqText) as JsonValue,
|
||||||
|
);
|
||||||
|
|
||||||
|
let resultCode = "ok";
|
||||||
|
let payload: Uint8Array;
|
||||||
|
switch (req.messageType) {
|
||||||
|
case "lobby.my.games.list":
|
||||||
|
payload = buildMyGamesListPayload([game]);
|
||||||
|
break;
|
||||||
|
case "user.games.report": {
|
||||||
|
const decoded = GameReportRequest.getRootAsGameReportRequest(
|
||||||
|
new ByteBuffer(req.payloadBytes),
|
||||||
|
);
|
||||||
|
const idStruct = decoded.gameId(new UUID());
|
||||||
|
const hi = idStruct?.hi() ?? 0n;
|
||||||
|
const lo = idStruct?.lo() ?? 0n;
|
||||||
|
state.reportRequests.push({
|
||||||
|
gameId: hiLoToUuid(hi, lo),
|
||||||
|
turn: decoded.turn(),
|
||||||
|
});
|
||||||
|
payload = buildReportPayload(opts.report);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
resultCode = "internal_error";
|
||||||
|
payload = new Uint8Array();
|
||||||
|
}
|
||||||
|
|
||||||
|
const body = await forgeExecuteCommandResponseJson({
|
||||||
|
requestId: req.requestId,
|
||||||
|
timestampMs: BigInt(Date.now()),
|
||||||
|
resultCode,
|
||||||
|
payloadBytes: payload,
|
||||||
|
});
|
||||||
|
await route.fulfill({
|
||||||
|
status: 200,
|
||||||
|
contentType: "application/json",
|
||||||
|
body,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Hold the SubscribeEvents stream open indefinitely. The
|
||||||
|
// revocation watcher in `lib/revocation-watcher.ts` treats a clean
|
||||||
|
// end-of-stream as `session_invalidation` and calls
|
||||||
|
// `session.signOut("revoked")`, which would bounce the page back
|
||||||
|
// to `/login`. Playwright aborts pending routes on test teardown,
|
||||||
|
// the watcher's catch path logs the abort and returns without a
|
||||||
|
// sign-out — same convention as `tests/e2e/lobby-flow.spec.ts`.
|
||||||
|
await page.route(
|
||||||
|
"**/galaxy.gateway.v1.EdgeGateway/SubscribeEvents",
|
||||||
|
async () => {
|
||||||
|
await new Promise<void>(() => {});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hiLoToUuid(hi: bigint, lo: bigint): string {
|
||||||
|
const toHex = (v: bigint): string => v.toString(16).padStart(16, "0");
|
||||||
|
const full = toHex(hi) + toHex(lo);
|
||||||
|
return [
|
||||||
|
full.slice(0, 8),
|
||||||
|
full.slice(8, 12),
|
||||||
|
full.slice(12, 16),
|
||||||
|
full.slice(16, 20),
|
||||||
|
full.slice(20, 32),
|
||||||
|
].join("-");
|
||||||
|
}
|
||||||
|
|
||||||
|
async function bootSession(page: Page): Promise<void> {
|
||||||
|
await page.goto("/__debug/store");
|
||||||
|
await expect(page.getByTestId("debug-store-ready")).toBeVisible();
|
||||||
|
await page.waitForFunction(() => window.__galaxyDebug?.ready === true);
|
||||||
|
await page.evaluate(() => window.__galaxyDebug!.clearSession());
|
||||||
|
await page.evaluate(
|
||||||
|
(id) => window.__galaxyDebug!.setDeviceSessionId(id),
|
||||||
|
SESSION_ID,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
test("map view renders the reported turn and planet count from a live report", async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
const mocks = await mockGateway(page, {
|
||||||
|
currentTurn: 4,
|
||||||
|
report: {
|
||||||
|
turn: 4,
|
||||||
|
mapWidth: 4000,
|
||||||
|
mapHeight: 4000,
|
||||||
|
localPlanets: [
|
||||||
|
{ number: 1, name: "Home", x: 1000, y: 1000 },
|
||||||
|
{ number: 2, name: "Outpost", x: 1500, y: 1300 },
|
||||||
|
],
|
||||||
|
otherPlanets: [
|
||||||
|
{
|
||||||
|
number: 3,
|
||||||
|
name: "Frontier",
|
||||||
|
x: 2200,
|
||||||
|
y: 2200,
|
||||||
|
owner: "Federation",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
uninhabitedPlanets: [{ number: 4, name: "Rock", x: 800, y: 2400 }],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await bootSession(page);
|
||||||
|
await page.goto(`/games/${GAME_ID}/map`);
|
||||||
|
|
||||||
|
await expect(page.getByTestId("active-view-map")).toHaveAttribute(
|
||||||
|
"data-status",
|
||||||
|
"ready",
|
||||||
|
);
|
||||||
|
await expect(page.getByTestId("turn-counter")).toContainText("turn 4");
|
||||||
|
await expect(page.getByTestId("map-canvas-wrap")).toHaveAttribute(
|
||||||
|
"data-planet-count",
|
||||||
|
"4",
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(mocks.reportRequests.length).toBeGreaterThanOrEqual(1);
|
||||||
|
expect(mocks.reportRequests[0]?.gameId).toBe(GAME_ID);
|
||||||
|
expect(mocks.reportRequests[0]?.turn).toBe(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("zero-planet game renders the empty world without errors", async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
await mockGateway(page, {
|
||||||
|
currentTurn: 0,
|
||||||
|
report: {
|
||||||
|
turn: 0,
|
||||||
|
mapWidth: 4000,
|
||||||
|
mapHeight: 4000,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await bootSession(page);
|
||||||
|
await page.goto(`/games/${GAME_ID}/map`);
|
||||||
|
|
||||||
|
await expect(page.getByTestId("active-view-map")).toHaveAttribute(
|
||||||
|
"data-status",
|
||||||
|
"ready",
|
||||||
|
);
|
||||||
|
await expect(page.getByTestId("turn-counter")).toContainText("turn 0");
|
||||||
|
await expect(page.getByTestId("map-canvas-wrap")).toHaveAttribute(
|
||||||
|
"data-planet-count",
|
||||||
|
"0",
|
||||||
|
);
|
||||||
|
await expect(page.getByTestId("map-error")).not.toBeVisible();
|
||||||
|
await expect(page.getByTestId("map-mount-error")).not.toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("missing-membership game surfaces an error instead of a blank canvas", async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
// The gateway returns lobby.my.games.list with a different game id
|
||||||
|
// so the layout's gameState lookup misses; the store flips to
|
||||||
|
// `error` and the map view renders the localised error overlay.
|
||||||
|
await mockGateway(page, {
|
||||||
|
currentTurn: 0,
|
||||||
|
gameId: "99999999-aaaa-bbbb-cccc-000000000000",
|
||||||
|
report: { turn: 0 },
|
||||||
|
});
|
||||||
|
|
||||||
|
await bootSession(page);
|
||||||
|
await page.goto(`/games/${GAME_ID}/map`);
|
||||||
|
|
||||||
|
await expect(page.getByTestId("map-error")).toBeVisible();
|
||||||
|
await expect(page.getByTestId("active-view-map")).toHaveAttribute(
|
||||||
|
"data-status",
|
||||||
|
"error",
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -24,11 +24,18 @@ beforeEach(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("active-view stubs", () => {
|
describe("active-view stubs", () => {
|
||||||
test("map stub renders title and coming-soon copy", () => {
|
test("map view renders loading overlay when no game-state context is provided", () => {
|
||||||
|
// The live integration in `lib/active-view/map.svelte` (Phase 11)
|
||||||
|
// reads its data from a `GameStateStore` provided through context
|
||||||
|
// by `routes/games/[id]/+layout.svelte`. Without the context the
|
||||||
|
// store reference is `undefined` and the view stays in the
|
||||||
|
// `idle` branch, surfacing the localised loading overlay so the
|
||||||
|
// shell never renders an empty active-view slot.
|
||||||
const ui = render(MapView);
|
const ui = render(MapView);
|
||||||
const node = ui.getByTestId("active-view-map");
|
const node = ui.getByTestId("active-view-map");
|
||||||
expect(node).toHaveTextContent("map");
|
expect(node).toHaveAttribute("data-status", "idle");
|
||||||
expect(node).toHaveTextContent("coming soon");
|
expect(ui.getByTestId("map-loading")).toBeInTheDocument();
|
||||||
|
expect(ui.getByTestId("map-canvas-wrap")).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("table stub maps a kebab-case entity to the right i18n title", () => {
|
test("table stub maps a kebab-case entity to the right i18n title", () => {
|
||||||
|
|||||||
@@ -0,0 +1,264 @@
|
|||||||
|
// Vitest coverage for the per-game runes store
|
||||||
|
// (`lib/game-state.svelte.ts`). The test stubs `lobby.my.games.list`
|
||||||
|
// and `user.games.report` at module level and drives the store
|
||||||
|
// through its lifecycle: init → ready → error → setTurn → wrap-mode
|
||||||
|
// persistence.
|
||||||
|
|
||||||
|
import "@testing-library/jest-dom/vitest";
|
||||||
|
import "fake-indexeddb/auto";
|
||||||
|
import {
|
||||||
|
afterEach,
|
||||||
|
beforeEach,
|
||||||
|
describe,
|
||||||
|
expect,
|
||||||
|
test,
|
||||||
|
vi,
|
||||||
|
} from "vitest";
|
||||||
|
import { Builder } from "flatbuffers";
|
||||||
|
|
||||||
|
import { GameStateStore } from "../src/lib/game-state.svelte";
|
||||||
|
import type { GalaxyClient } from "../src/api/galaxy-client";
|
||||||
|
import type { Cache } from "../src/platform/store/index";
|
||||||
|
import { IDBCache } from "../src/platform/store/idb-cache";
|
||||||
|
import { openGalaxyDB, type GalaxyDB } from "../src/platform/store/idb";
|
||||||
|
import type { IDBPDatabase } from "idb";
|
||||||
|
import { UUID } from "../src/proto/galaxy/fbs/common";
|
||||||
|
import {
|
||||||
|
LocalPlanet,
|
||||||
|
Report,
|
||||||
|
} from "../src/proto/galaxy/fbs/report";
|
||||||
|
|
||||||
|
const listMyGamesSpy = vi.fn();
|
||||||
|
vi.mock("../src/api/lobby", async () => {
|
||||||
|
const actual = await vi.importActual<typeof import("../src/api/lobby")>(
|
||||||
|
"../src/api/lobby",
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...actual,
|
||||||
|
listMyGames: (...args: unknown[]) => listMyGamesSpy(...args),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
let db: IDBPDatabase<GalaxyDB>;
|
||||||
|
let dbName: string;
|
||||||
|
let cache: Cache;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
dbName = `galaxy-game-state-test-${crypto.randomUUID()}`;
|
||||||
|
db = await openGalaxyDB(dbName);
|
||||||
|
cache = new IDBCache(db);
|
||||||
|
listMyGamesSpy.mockReset();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
db.close();
|
||||||
|
await new Promise<void>((resolve) => {
|
||||||
|
const req = indexedDB.deleteDatabase(dbName);
|
||||||
|
req.onsuccess = () => resolve();
|
||||||
|
req.onerror = () => resolve();
|
||||||
|
req.onblocked = () => resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const GAME_ID = "11111111-2222-3333-4444-555555555555";
|
||||||
|
|
||||||
|
function makeGameSummary(currentTurn: number): {
|
||||||
|
gameId: string;
|
||||||
|
gameName: string;
|
||||||
|
gameType: string;
|
||||||
|
status: string;
|
||||||
|
ownerUserId: string;
|
||||||
|
minPlayers: number;
|
||||||
|
maxPlayers: number;
|
||||||
|
enrollmentEndsAt: Date;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
currentTurn: number;
|
||||||
|
} {
|
||||||
|
return {
|
||||||
|
gameId: GAME_ID,
|
||||||
|
gameName: "Test Game",
|
||||||
|
gameType: "private",
|
||||||
|
status: "running",
|
||||||
|
ownerUserId: "owner-1",
|
||||||
|
minPlayers: 2,
|
||||||
|
maxPlayers: 8,
|
||||||
|
enrollmentEndsAt: new Date(),
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
currentTurn,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PlanetFixture {
|
||||||
|
number: number;
|
||||||
|
name: string;
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildReportPayload(opts: {
|
||||||
|
turn: number;
|
||||||
|
width?: number;
|
||||||
|
height?: number;
|
||||||
|
planets?: PlanetFixture[];
|
||||||
|
}): Uint8Array {
|
||||||
|
const builder = new Builder(256);
|
||||||
|
const planetOffsets = (opts.planets ?? []).map((planet) => {
|
||||||
|
const name = builder.createString(planet.name);
|
||||||
|
LocalPlanet.startLocalPlanet(builder);
|
||||||
|
LocalPlanet.addNumber(builder, BigInt(planet.number));
|
||||||
|
LocalPlanet.addX(builder, planet.x);
|
||||||
|
LocalPlanet.addY(builder, planet.y);
|
||||||
|
LocalPlanet.addName(builder, name);
|
||||||
|
LocalPlanet.addSize(builder, 10);
|
||||||
|
LocalPlanet.addResources(builder, 0.5);
|
||||||
|
return LocalPlanet.endLocalPlanet(builder);
|
||||||
|
});
|
||||||
|
const localPlanetVec =
|
||||||
|
planetOffsets.length === 0
|
||||||
|
? null
|
||||||
|
: Report.createLocalPlanetVector(builder, planetOffsets);
|
||||||
|
|
||||||
|
Report.startReport(builder);
|
||||||
|
Report.addTurn(builder, BigInt(opts.turn));
|
||||||
|
Report.addWidth(builder, opts.width ?? 4000);
|
||||||
|
Report.addHeight(builder, opts.height ?? 4000);
|
||||||
|
Report.addPlanetCount(builder, planetOffsets.length);
|
||||||
|
if (localPlanetVec !== null) {
|
||||||
|
Report.addLocalPlanet(builder, localPlanetVec);
|
||||||
|
}
|
||||||
|
const reportOff = Report.endReport(builder);
|
||||||
|
builder.finish(reportOff);
|
||||||
|
return builder.asUint8Array();
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeFakeClient(
|
||||||
|
executeCommand: (
|
||||||
|
messageType: string,
|
||||||
|
payload: Uint8Array,
|
||||||
|
) => Promise<{ resultCode: string; payloadBytes: Uint8Array }>,
|
||||||
|
): GalaxyClient {
|
||||||
|
return { executeCommand } as unknown as GalaxyClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("GameStateStore", () => {
|
||||||
|
test("init transitions through loading and ready when both calls succeed", async () => {
|
||||||
|
listMyGamesSpy.mockResolvedValue([makeGameSummary(7)]);
|
||||||
|
|
||||||
|
const calls: Array<{ messageType: string; payload: Uint8Array }> = [];
|
||||||
|
const client = makeFakeClient(async (messageType, payload) => {
|
||||||
|
calls.push({ messageType, payload });
|
||||||
|
return {
|
||||||
|
resultCode: "ok",
|
||||||
|
payloadBytes: buildReportPayload({
|
||||||
|
turn: 7,
|
||||||
|
planets: [{ number: 1, name: "Home", x: 100, y: 100 }],
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const store = new GameStateStore();
|
||||||
|
expect(store.status).toBe("idle");
|
||||||
|
await store.init({ client, cache, gameId: GAME_ID });
|
||||||
|
|
||||||
|
expect(listMyGamesSpy).toHaveBeenCalledTimes(1);
|
||||||
|
expect(calls.length).toBe(1);
|
||||||
|
expect(calls[0]?.messageType).toBe("user.games.report");
|
||||||
|
expect(store.status).toBe("ready");
|
||||||
|
expect(store.report).not.toBeNull();
|
||||||
|
expect(store.report?.turn).toBe(7);
|
||||||
|
expect(store.report?.planets.length).toBe(1);
|
||||||
|
expect(store.report?.planets[0]?.kind).toBe("local");
|
||||||
|
|
||||||
|
store.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("init surfaces an error when the game is missing from lobby", async () => {
|
||||||
|
listMyGamesSpy.mockResolvedValue([makeGameSummary(0).gameId === "other" ? null : makeGameSummary(0)].filter(Boolean));
|
||||||
|
// Replace the helper above's awkward filter with an explicit
|
||||||
|
// mismatched id so the lookup miss is unambiguous.
|
||||||
|
listMyGamesSpy.mockResolvedValue([
|
||||||
|
{ ...makeGameSummary(2), gameId: "different-game-id" },
|
||||||
|
]);
|
||||||
|
|
||||||
|
const client = makeFakeClient(async () => ({
|
||||||
|
resultCode: "ok",
|
||||||
|
payloadBytes: buildReportPayload({ turn: 0 }),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const store = new GameStateStore();
|
||||||
|
await store.init({ client, cache, gameId: GAME_ID });
|
||||||
|
|
||||||
|
expect(store.status).toBe("error");
|
||||||
|
expect(store.error).toMatch(/not in your list/);
|
||||||
|
expect(store.report).toBeNull();
|
||||||
|
store.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("init surfaces error when user.games.report returns a non-ok result", async () => {
|
||||||
|
listMyGamesSpy.mockResolvedValue([makeGameSummary(0)]);
|
||||||
|
const client = makeFakeClient(async () => ({
|
||||||
|
resultCode: "forbidden",
|
||||||
|
payloadBytes: new TextEncoder().encode(
|
||||||
|
JSON.stringify({ code: "forbidden", message: "no membership" }),
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const store = new GameStateStore();
|
||||||
|
await store.init({ client, cache, gameId: GAME_ID });
|
||||||
|
expect(store.status).toBe("error");
|
||||||
|
expect(store.error).toMatch(/no membership/);
|
||||||
|
store.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("setTurn loads a different turn snapshot", async () => {
|
||||||
|
listMyGamesSpy.mockResolvedValue([makeGameSummary(3)]);
|
||||||
|
const turns: number[] = [];
|
||||||
|
const client = makeFakeClient(async () => {
|
||||||
|
const turn = turns.length === 0 ? 3 : 1;
|
||||||
|
turns.push(turn);
|
||||||
|
return {
|
||||||
|
resultCode: "ok",
|
||||||
|
payloadBytes: buildReportPayload({ turn }),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const store = new GameStateStore();
|
||||||
|
await store.init({ client, cache, gameId: GAME_ID });
|
||||||
|
expect(store.report?.turn).toBe(3);
|
||||||
|
|
||||||
|
await store.setTurn(1);
|
||||||
|
expect(store.status).toBe("ready");
|
||||||
|
expect(store.report?.turn).toBe(1);
|
||||||
|
|
||||||
|
store.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("setWrapMode persists across instances through Cache", async () => {
|
||||||
|
listMyGamesSpy.mockResolvedValue([makeGameSummary(0)]);
|
||||||
|
const client = makeFakeClient(async () => ({
|
||||||
|
resultCode: "ok",
|
||||||
|
payloadBytes: buildReportPayload({ turn: 0 }),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const a = new GameStateStore();
|
||||||
|
await a.init({ client, cache, gameId: GAME_ID });
|
||||||
|
expect(a.wrapMode).toBe("torus");
|
||||||
|
await a.setWrapMode("no-wrap");
|
||||||
|
expect(a.wrapMode).toBe("no-wrap");
|
||||||
|
a.dispose();
|
||||||
|
|
||||||
|
const b = new GameStateStore();
|
||||||
|
await b.init({ client, cache, gameId: GAME_ID });
|
||||||
|
expect(b.wrapMode).toBe("no-wrap");
|
||||||
|
b.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("failBootstrap moves the store into the error state with the given message", () => {
|
||||||
|
const store = new GameStateStore();
|
||||||
|
store.failBootstrap("device session missing");
|
||||||
|
expect(store.status).toBe("error");
|
||||||
|
expect(store.error).toBe("device session missing");
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -70,7 +70,7 @@ function makeStub(
|
|||||||
return { client: stub, captured };
|
return { client: stub, captured };
|
||||||
}
|
}
|
||||||
|
|
||||||
function encodeGameSummary(builder: Builder): number {
|
function encodeGameSummary(builder: Builder, currentTurn: number = 0): number {
|
||||||
const gameId = builder.createString("g-1");
|
const gameId = builder.createString("g-1");
|
||||||
const gameName = builder.createString("Test Game");
|
const gameName = builder.createString("Test Game");
|
||||||
const gameType = builder.createString("private");
|
const gameType = builder.createString("private");
|
||||||
@@ -87,6 +87,7 @@ function encodeGameSummary(builder: Builder): number {
|
|||||||
GameSummary.addEnrollmentEndsAtMs(builder, 1_780_000_000_000n);
|
GameSummary.addEnrollmentEndsAtMs(builder, 1_780_000_000_000n);
|
||||||
GameSummary.addCreatedAtMs(builder, 1_770_000_000_000n);
|
GameSummary.addCreatedAtMs(builder, 1_770_000_000_000n);
|
||||||
GameSummary.addUpdatedAtMs(builder, 1_770_000_000_000n);
|
GameSummary.addUpdatedAtMs(builder, 1_770_000_000_000n);
|
||||||
|
GameSummary.addCurrentTurn(builder, currentTurn);
|
||||||
return GameSummary.endGameSummary(builder);
|
return GameSummary.endGameSummary(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +134,7 @@ describe("lobby.ts wrappers", () => {
|
|||||||
test("listMyGames decodes the response and reports the message type", async () => {
|
test("listMyGames decodes the response and reports the message type", async () => {
|
||||||
const { client, captured } = makeStub(() => {
|
const { client, captured } = makeStub(() => {
|
||||||
const builder = new Builder(256);
|
const builder = new Builder(256);
|
||||||
const item = encodeGameSummary(builder);
|
const item = encodeGameSummary(builder, 5);
|
||||||
const items = MyGamesListResponse.createItemsVector(builder, [item]);
|
const items = MyGamesListResponse.createItemsVector(builder, [item]);
|
||||||
MyGamesListResponse.startMyGamesListResponse(builder);
|
MyGamesListResponse.startMyGamesListResponse(builder);
|
||||||
MyGamesListResponse.addItems(builder, items);
|
MyGamesListResponse.addItems(builder, items);
|
||||||
@@ -146,6 +147,7 @@ describe("lobby.ts wrappers", () => {
|
|||||||
expect(games.length).toBe(1);
|
expect(games.length).toBe(1);
|
||||||
expect(games[0]!.gameId).toBe("g-1");
|
expect(games[0]!.gameId).toBe("g-1");
|
||||||
expect(games[0]!.minPlayers).toBe(2);
|
expect(games[0]!.minPlayers).toBe(2);
|
||||||
|
expect(games[0]!.currentTurn).toBe(5);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("listPublicGames passes pagination and decodes pageSize/total", async () => {
|
test("listPublicGames passes pagination and decodes pageSize/total", async () => {
|
||||||
|
|||||||
@@ -43,19 +43,21 @@ interface GameSummaryFixture {
|
|||||||
enrollmentEndsAtMs: bigint;
|
enrollmentEndsAtMs: bigint;
|
||||||
createdAtMs: bigint;
|
createdAtMs: bigint;
|
||||||
updatedAtMs: bigint;
|
updatedAtMs: bigint;
|
||||||
|
currentTurn: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PRIVATE_GAME: GameSummaryFixture = {
|
const PRIVATE_GAME: GameSummaryFixture = {
|
||||||
gameId: "game-private-7c8f",
|
gameId: "game-private-7c8f",
|
||||||
gameName: "First Contact",
|
gameName: "First Contact",
|
||||||
gameType: "private",
|
gameType: "private",
|
||||||
status: "draft",
|
status: "running",
|
||||||
ownerUserId: "user-9912",
|
ownerUserId: "user-9912",
|
||||||
minPlayers: 2,
|
minPlayers: 2,
|
||||||
maxPlayers: 8,
|
maxPlayers: 8,
|
||||||
enrollmentEndsAtMs: 1_780_000_000_000n,
|
enrollmentEndsAtMs: 1_780_000_000_000n,
|
||||||
createdAtMs: 1_770_000_000_000n,
|
createdAtMs: 1_770_000_000_000n,
|
||||||
updatedAtMs: 1_770_000_300_000n,
|
updatedAtMs: 1_770_000_300_000n,
|
||||||
|
currentTurn: 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
const PUBLIC_GAME: GameSummaryFixture = {
|
const PUBLIC_GAME: GameSummaryFixture = {
|
||||||
@@ -69,6 +71,7 @@ const PUBLIC_GAME: GameSummaryFixture = {
|
|||||||
enrollmentEndsAtMs: 1_780_500_000_000n,
|
enrollmentEndsAtMs: 1_780_500_000_000n,
|
||||||
createdAtMs: 1_770_500_000_000n,
|
createdAtMs: 1_770_500_000_000n,
|
||||||
updatedAtMs: 1_770_600_000_000n,
|
updatedAtMs: 1_770_600_000_000n,
|
||||||
|
currentTurn: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
function encodeGameSummary(builder: Builder, value: GameSummaryFixture): number {
|
function encodeGameSummary(builder: Builder, value: GameSummaryFixture): number {
|
||||||
@@ -88,6 +91,7 @@ function encodeGameSummary(builder: Builder, value: GameSummaryFixture): number
|
|||||||
GameSummary.addEnrollmentEndsAtMs(builder, value.enrollmentEndsAtMs);
|
GameSummary.addEnrollmentEndsAtMs(builder, value.enrollmentEndsAtMs);
|
||||||
GameSummary.addCreatedAtMs(builder, value.createdAtMs);
|
GameSummary.addCreatedAtMs(builder, value.createdAtMs);
|
||||||
GameSummary.addUpdatedAtMs(builder, value.updatedAtMs);
|
GameSummary.addUpdatedAtMs(builder, value.updatedAtMs);
|
||||||
|
GameSummary.addCurrentTurn(builder, value.currentTurn);
|
||||||
return GameSummary.endGameSummary(builder);
|
return GameSummary.endGameSummary(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,6 +108,7 @@ function expectGameSummary(actual: GameSummary | null, want: GameSummaryFixture)
|
|||||||
expect(got.enrollmentEndsAtMs()).toBe(want.enrollmentEndsAtMs);
|
expect(got.enrollmentEndsAtMs()).toBe(want.enrollmentEndsAtMs);
|
||||||
expect(got.createdAtMs()).toBe(want.createdAtMs);
|
expect(got.createdAtMs()).toBe(want.createdAtMs);
|
||||||
expect(got.updatedAtMs()).toBe(want.updatedAtMs);
|
expect(got.updatedAtMs()).toBe(want.updatedAtMs);
|
||||||
|
expect(got.currentTurn()).toBe(want.currentTurn);
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("lobby FlatBuffers TS bindings", () => {
|
describe("lobby FlatBuffers TS bindings", () => {
|
||||||
|
|||||||
@@ -136,6 +136,7 @@ function makeGame(id: string, name: string, status = "draft") {
|
|||||||
enrollmentEndsAt: baseDate,
|
enrollmentEndsAt: baseDate,
|
||||||
createdAt: baseDate,
|
createdAt: baseDate,
|
||||||
updatedAt: baseDate,
|
updatedAt: baseDate,
|
||||||
|
currentTurn: 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,6 +152,7 @@ function makePublicGame(id: string, name: string) {
|
|||||||
enrollmentEndsAt: baseDate,
|
enrollmentEndsAt: baseDate,
|
||||||
createdAt: baseDate,
|
createdAt: baseDate,
|
||||||
updatedAt: baseDate,
|
updatedAt: baseDate,
|
||||||
|
currentTurn: 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
// Vitest unit coverage for `map/state-binding.ts`. The function
|
||||||
|
// translates a Phase 11 `GameReport` into a renderer-ready `World`
|
||||||
|
// containing one Point primitive per planet across all four kinds
|
||||||
|
// (local / other / uninhabited / unidentified). The tests assert
|
||||||
|
// the world dimensions match the report, the planet ids are the
|
||||||
|
// engine numbers, the kind-specific styles differ, and a zero-planet
|
||||||
|
// report still produces a well-formed empty World.
|
||||||
|
|
||||||
|
import "@testing-library/jest-dom/vitest";
|
||||||
|
import { describe, expect, test } from "vitest";
|
||||||
|
|
||||||
|
import type { GameReport } from "../src/api/game-state";
|
||||||
|
import { reportToWorld } from "../src/map/state-binding";
|
||||||
|
|
||||||
|
function makeReport(overrides: Partial<GameReport> = {}): GameReport {
|
||||||
|
return {
|
||||||
|
turn: 1,
|
||||||
|
mapWidth: 4000,
|
||||||
|
mapHeight: 4000,
|
||||||
|
planetCount: 0,
|
||||||
|
planets: [],
|
||||||
|
...overrides,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("reportToWorld", () => {
|
||||||
|
test("uses report dimensions for the World", () => {
|
||||||
|
const world = reportToWorld(makeReport({ mapWidth: 3200, mapHeight: 1600 }));
|
||||||
|
expect(world.width).toBe(3200);
|
||||||
|
expect(world.height).toBe(1600);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("emits one Point primitive per planet across all four kinds", () => {
|
||||||
|
const world = reportToWorld(
|
||||||
|
makeReport({
|
||||||
|
planets: [
|
||||||
|
{ number: 1, name: "Home", x: 100, y: 100, kind: "local", owner: null, size: 12, resources: 0.5 },
|
||||||
|
{ number: 2, name: "Alpha", x: 200, y: 100, kind: "other", owner: "Federation", size: 8, resources: 0.3 },
|
||||||
|
{ number: 3, name: "Rock", x: 100, y: 200, kind: "uninhabited", owner: null, size: 4, resources: 0.1 },
|
||||||
|
{ number: 4, name: "", x: 200, y: 200, kind: "unidentified", owner: null, size: null, resources: null },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
expect(world.primitives.length).toBe(4);
|
||||||
|
for (const p of world.primitives) {
|
||||||
|
expect(p.kind).toBe("point");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("propagates planet number as primitive id and coordinates verbatim", () => {
|
||||||
|
const world = reportToWorld(
|
||||||
|
makeReport({
|
||||||
|
planets: [
|
||||||
|
{ number: 42, name: "Home", x: 123.5, y: 456.25, kind: "local", owner: null, size: 10, resources: 0.5 },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
const [planet] = world.primitives;
|
||||||
|
expect(planet?.id).toBe(42);
|
||||||
|
expect(planet?.kind).toBe("point");
|
||||||
|
if (planet?.kind === "point") {
|
||||||
|
expect(planet.x).toBe(123.5);
|
||||||
|
expect(planet.y).toBe(456.25);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("uses distinct styles for each planet kind", () => {
|
||||||
|
const world = reportToWorld(
|
||||||
|
makeReport({
|
||||||
|
planets: [
|
||||||
|
{ number: 1, name: "L", x: 0, y: 0, kind: "local", owner: null, size: 1, resources: 0 },
|
||||||
|
{ number: 2, name: "O", x: 1, y: 0, kind: "other", owner: "Foe", size: 1, resources: 0 },
|
||||||
|
{ number: 3, name: "U", x: 2, y: 0, kind: "uninhabited", owner: null, size: 1, resources: 0 },
|
||||||
|
{ number: 4, name: "?", x: 3, y: 0, kind: "unidentified", owner: null, size: null, resources: null },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
const fills = world.primitives.map((p) => p.style.fillColor);
|
||||||
|
const unique = new Set(fills);
|
||||||
|
expect(unique.size).toBe(fills.length);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("zero-planet report yields an empty primitive list and well-formed World", () => {
|
||||||
|
const world = reportToWorld(makeReport({ planets: [] }));
|
||||||
|
expect(world.primitives.length).toBe(0);
|
||||||
|
expect(world.width).toBeGreaterThan(0);
|
||||||
|
expect(world.height).toBeGreaterThan(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("guards against zero / negative dimensions in the report", () => {
|
||||||
|
const world = reportToWorld(
|
||||||
|
makeReport({ mapWidth: 0, mapHeight: -1, planets: [] }),
|
||||||
|
);
|
||||||
|
// World's constructor rejects non-positive dimensions; the
|
||||||
|
// binding falls back to 1×1 so a malformed report cannot crash
|
||||||
|
// the renderer.
|
||||||
|
expect(world.width).toBeGreaterThan(0);
|
||||||
|
expect(world.height).toBeGreaterThan(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("local planets carry higher priority than unidentified", () => {
|
||||||
|
const world = reportToWorld(
|
||||||
|
makeReport({
|
||||||
|
planets: [
|
||||||
|
{ number: 1, name: "Home", x: 0, y: 0, kind: "local", owner: null, size: 1, resources: 0 },
|
||||||
|
{ number: 2, name: "?", x: 0, y: 0, kind: "unidentified", owner: null, size: null, resources: null },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
const local = world.primitives.find((p) => p.id === 1);
|
||||||
|
const unknown = world.primitives.find((p) => p.id === 2);
|
||||||
|
expect(local?.priority ?? 0).toBeGreaterThan(unknown?.priority ?? 0);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user