Move RTS menu panel authority to daemon
This commit is contained in:
parent
e4b155576f
commit
b86635fda5
15 changed files with 361 additions and 195 deletions
|
|
@ -5,7 +5,6 @@ import {
|
|||
type EveSurfaceComponent,
|
||||
} from "../node_modules/@gamecult/eve-browser-lowering/dist/index.js";
|
||||
import type {
|
||||
AetheriaMenuSurfaceComponent,
|
||||
AetheriaMenuSurfaceDocument,
|
||||
AetheriaRtsApi,
|
||||
Viewport,
|
||||
|
|
@ -22,7 +21,6 @@ declare global {
|
|||
const host = requiredElement<HTMLElement>("#eve-surface-host");
|
||||
const statusEl = requiredElement<HTMLElement>("#status");
|
||||
let latestEveSurfaceKey = "";
|
||||
let activeMainMenuSurfaceId = "aetheria.main_menu.root";
|
||||
let renderDaemonEveSurfaceNow: (() => Promise<void>) | null = null;
|
||||
let eveSurfacePoll: number | null = null;
|
||||
|
||||
|
|
@ -48,14 +46,13 @@ async function showDaemonEveSurface(): Promise<void> {
|
|||
const surface = await window.aetheriaRts.eveSurface({
|
||||
recordKey: "eve:surface:aetheria.daemon.game",
|
||||
});
|
||||
const loweredSurface = withActiveMainMenuPanel(surface, activeMainMenuSurfaceId);
|
||||
const surfaceKey = `${surface.providerId}:${surface.surface.id}:${surface.version}:${surface.updatedAtUtc}:${activeMainMenuSurfaceId}`;
|
||||
const surfaceKey = `${surface.providerId}:${surface.surface.id}:${surface.version}:${surface.updatedAtUtc}`;
|
||||
if (surfaceKey === latestEveSurfaceKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
latestEveSurfaceKey = surfaceKey;
|
||||
renderEveSurface(loweredSurface, host, {
|
||||
renderEveSurface(surface, host, {
|
||||
body: document.body,
|
||||
assetUrlResolver: resolveAetheriaAssetUrl,
|
||||
clientId: "aetheria.rts.electron",
|
||||
|
|
@ -79,70 +76,6 @@ async function showDaemonEveSurface(): Promise<void> {
|
|||
}
|
||||
}
|
||||
|
||||
async function showMainMenuPanel(surfaceId: string): Promise<void> {
|
||||
activeMainMenuSurfaceId = normalizeMainMenuSurfaceId(surfaceId);
|
||||
latestEveSurfaceKey = "";
|
||||
if (renderDaemonEveSurfaceNow) {
|
||||
await renderDaemonEveSurfaceNow();
|
||||
return;
|
||||
}
|
||||
|
||||
await showDaemonEveSurface();
|
||||
}
|
||||
|
||||
function normalizeMainMenuSurfaceId(surfaceId: string): string {
|
||||
switch (surfaceId) {
|
||||
case "aetheria.main_menu.settings":
|
||||
case "aetheria.main_menu.player_settings":
|
||||
case "aetheria.main_menu.verse_settings":
|
||||
case "aetheria.main_menu.input_settings":
|
||||
return surfaceId;
|
||||
default:
|
||||
return "aetheria.main_menu.root";
|
||||
}
|
||||
}
|
||||
|
||||
function withActiveMainMenuPanel(
|
||||
document: AetheriaMenuSurfaceDocument,
|
||||
panelSurfaceId: string,
|
||||
): AetheriaMenuSurfaceDocument {
|
||||
return {
|
||||
...document,
|
||||
surface: {
|
||||
...document.surface,
|
||||
root: rewriteMainMenuPanelSlot(document.surface.root, panelSurfaceId),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
type MutableEveComponent = AetheriaMenuSurfaceComponent & {
|
||||
layout?: Record<string, string>;
|
||||
style?: Record<string, string>;
|
||||
};
|
||||
|
||||
function rewriteMainMenuPanelSlot(
|
||||
component: AetheriaMenuSurfaceComponent,
|
||||
panelSurfaceId: string,
|
||||
): AetheriaMenuSurfaceComponent {
|
||||
const source = component as MutableEveComponent;
|
||||
const props = source.props ?? {};
|
||||
const embeddedDocuments = source.embeddedDocuments ?? [];
|
||||
const isMainMenuSlot = props.slotId === "mainMenuPanel" ||
|
||||
embeddedDocuments.some(slot => slot.slotId === "mainMenuPanel");
|
||||
return {
|
||||
...source,
|
||||
props: isMainMenuSlot
|
||||
? { ...props, documentId: panelSurfaceId }
|
||||
: props,
|
||||
embeddedDocuments: isMainMenuSlot
|
||||
? embeddedDocuments.map(slot => slot.slotId === "mainMenuPanel"
|
||||
? { ...slot, documentId: panelSurfaceId }
|
||||
: slot)
|
||||
: source.embeddedDocuments,
|
||||
children: source.children.map(child => rewriteMainMenuPanelSlot(child, panelSurfaceId)),
|
||||
};
|
||||
}
|
||||
|
||||
async function resolveEveDocument(
|
||||
request: EveEmbeddedDocumentRequest,
|
||||
component: EveSurfaceComponent,
|
||||
|
|
@ -219,11 +152,6 @@ function resolveAetheriaAssetUrl(uri: string): string {
|
|||
}
|
||||
|
||||
async function submitEveCommand(intent: EveCommandIntent): Promise<void> {
|
||||
if (intent.command.startsWith("aetheria.main_menu.")) {
|
||||
handleMenuCommand(intent.command);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const receipt = await window.aetheriaRts.submitEveCommand({
|
||||
providerId: intent.providerId,
|
||||
|
|
@ -234,37 +162,17 @@ async function submitEveCommand(intent: EveCommandIntent): Promise<void> {
|
|||
payload: intent.payload,
|
||||
});
|
||||
setStatus(`${intent.command}: ${receipt.accepted ? "submitted" : "rejected"}`);
|
||||
latestEveSurfaceKey = "";
|
||||
if (renderDaemonEveSurfaceNow) {
|
||||
window.setTimeout(() => {
|
||||
void renderDaemonEveSurfaceNow?.();
|
||||
}, 120);
|
||||
}
|
||||
} catch (error) {
|
||||
setStatus(error instanceof Error ? error.message : `Failed to submit ${intent.command}.`);
|
||||
}
|
||||
}
|
||||
|
||||
function handleMenuCommand(command: string): void {
|
||||
switch (command) {
|
||||
case "aetheria.main_menu.root.show_settings":
|
||||
void showMainMenuPanel("aetheria.main_menu.settings");
|
||||
return;
|
||||
case "aetheria.main_menu.settings.show_player_settings":
|
||||
void showMainMenuPanel("aetheria.main_menu.player_settings");
|
||||
return;
|
||||
case "aetheria.main_menu.settings.show_verse_settings":
|
||||
void showMainMenuPanel("aetheria.main_menu.verse_settings");
|
||||
return;
|
||||
case "aetheria.main_menu.settings.show_input_settings":
|
||||
void showMainMenuPanel("aetheria.main_menu.input_settings");
|
||||
return;
|
||||
case "aetheria.main_menu.settings.back_to_settings":
|
||||
void showMainMenuPanel("aetheria.main_menu.settings");
|
||||
return;
|
||||
case "aetheria.main_menu.settings.back_to_main":
|
||||
void showMainMenuPanel("aetheria.main_menu.root");
|
||||
return;
|
||||
default:
|
||||
setStatus(`Aetheria Starbridge: ${command || "no command"}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function wireWindowControls(): void {
|
||||
document.querySelectorAll<HTMLButtonElement>("[data-window-control]").forEach(button => {
|
||||
if (button.dataset.windowControlWired === "true") {
|
||||
|
|
|
|||
|
|
@ -98,6 +98,16 @@ export const AetheriaRuntimeEveCommandKinds = {
|
|||
setTradeValueQualityMaximum: 21,
|
||||
setTradeValueQualityExponent: 22,
|
||||
setTradeValueTierQuality: 23,
|
||||
mainMenuContinueRun: 24,
|
||||
mainMenuNewGame: 25,
|
||||
mainMenuShowSettings: 26,
|
||||
mainMenuQuit: 27,
|
||||
mainMenuShowPlayerSettings: 28,
|
||||
mainMenuShowVerseSettings: 29,
|
||||
mainMenuShowInputSettings: 30,
|
||||
mainMenuBackToMain: 31,
|
||||
mainMenuBackToSettings: 32,
|
||||
mainMenuOpenRuntimeInputScreen: 33,
|
||||
} as const;
|
||||
|
||||
export const AetheriaRtsIpcChannels = {
|
||||
|
|
|
|||
|
|
@ -1089,10 +1089,24 @@ static async Task PublishDaemonApiDocumentsAsync(
|
|||
await node.MutableDocument<AetheriaRuntimeStarbridgeSessionSummaryDocument>(AetheriaRuntimeVerseRecordKeys.StarbridgeSessionSummary)
|
||||
.ReplaceAsync(result.StarbridgeSessionSummary)
|
||||
.ConfigureAwait(false);
|
||||
var mainMenuState = await node.MutableDocument<AetheriaMainMenuState>(AetheriaStateNode.MainMenuStateKey)
|
||||
.ReadAsync()
|
||||
.ConfigureAwait(false);
|
||||
var activeMainMenuSurfaceId = string.IsNullOrWhiteSpace(mainMenuState?.ActiveSurfaceId)
|
||||
? AetheriaRuntimeMainMenuCommands.RootSurfaceId
|
||||
: mainMenuState.ActiveSurfaceId;
|
||||
if (result.GameSurface != null)
|
||||
{
|
||||
var gameSurface = AetheriaRuntimeDaemonGameSurfaceBuilder.Build(
|
||||
result.Frame,
|
||||
result.Health ?? new AetheriaRuntimeDaemonHealthDocument(),
|
||||
result.CommandBoundary ?? AetheriaRuntimeDaemonCommandBoundaryDocument.Create(options.DaemonId),
|
||||
result.StarbridgeSessionSummary,
|
||||
activeMainMenuSurfaceId);
|
||||
await node.MutableDocument<EveSurfaceDocument>(AetheriaRuntimeVerseRecordKeys.DaemonGameSurface)
|
||||
.ReplaceAsync(AetheriaRuntimeSurfaceDocuments.ToPortableSurface(result.GameSurface))
|
||||
.ReplaceAsync(AetheriaRuntimeSurfaceDocuments.ToPortableSurface(gameSurface))
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
if (result.GameTuiSurface != null)
|
||||
await node.MutableDocument<EveSurfaceDocument>(AetheriaRuntimeVerseRecordKeys.DaemonGameTuiSurface)
|
||||
.ReplaceAsync(AetheriaRuntimeSurfaceDocuments.ToPortableSurface(result.GameTuiSurface))
|
||||
|
|
@ -1375,6 +1389,7 @@ static async Task AcceptEveCommandsAsync(AetheriaStateNode node, AetheriaDaemonH
|
|||
AppliedInputSettingsCommands = report.AcceptedInputSettingsCommands,
|
||||
AppliedLoadoutTemplateCommands = report.AcceptedLoadoutTemplateCommands,
|
||||
AppliedVerseHostCommands = report.AcceptedVerseHostCommands,
|
||||
AppliedMainMenuCommands = report.AcceptedMainMenuCommands,
|
||||
AccountedCommandIds = report.AccountedCommandIds,
|
||||
LastRejectedCommand = report.LastRejectedCommand,
|
||||
LastRejectedReason = report.LastRejectedReason,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
using Aetheria.State;
|
||||
using Aetheria.State.Documents;
|
||||
using GameCult.Aetheria.State.Verse;
|
||||
using GameCult.Eve.Surface;
|
||||
using GameCult.Mesh;
|
||||
|
||||
var root = args.Length > 0 ? Path.GetFullPath(args[0]) : Directory.GetCurrentDirectory();
|
||||
var statePath = args.Length > 1
|
||||
|
|
@ -124,6 +126,7 @@ var surface = AetheriaEveSurfaceDocuments.BuildCatalogSurface(catalog, DateTimeO
|
|||
var tradeValuePolicy = await node.MutableDocument<AetheriaTradeValuePolicy>(AetheriaStateNode.TradeValuePolicyKey).ReadAsync()
|
||||
?? throw new InvalidOperationException("Missing authored trade value policy document.");
|
||||
await RequireTradeValuePolicyEveCommandPersistsAsync();
|
||||
await RequireMainMenuEveCommandPersistsAsync();
|
||||
var runtimeCatalog = catalog;
|
||||
|
||||
RequireCount(ledger, "aetheria.item_definition.v1", items.Length);
|
||||
|
|
@ -3935,7 +3938,7 @@ static void RequireMainMenuSettingsShellUsesEveSurface(string root)
|
|||
"BuildVerseSettings(",
|
||||
"private static AetheriaRuntimeSurfaceDocument BuildRoot(",
|
||||
"private static AetheriaRuntimeSurfaceDocument BuildInputSettings(",
|
||||
"var verseLabel = VerseLabel(verseTitle, verseId)",
|
||||
"\"STARBRIDGE\"",
|
||||
"AetheriaRuntimePlayerSettingsSurfaceBuilder.Build(playerSettings, updatedAtUtc, version)",
|
||||
"AetheriaRuntimeSurfaceDocument document",
|
||||
"WithBackAction(",
|
||||
|
|
@ -4096,7 +4099,9 @@ static void RequireMainMenuRootUsesEveSurface(string root)
|
|||
"AetheriaRuntimeMainMenuCommands.ShowSettings",
|
||||
"AetheriaRuntimeMainMenuCommands.Quit",
|
||||
"private static AetheriaRuntimeSurfaceDocument BuildRoot(",
|
||||
"var verseLabel = VerseLabel(verseTitle, verseId)",
|
||||
"\"STARBRIDGE\"",
|
||||
"\"Aetheria Starbridge\"",
|
||||
"GravitySurface($",
|
||||
"public enum AetheriaRuntimeMainMenuCommandKind",
|
||||
"public readonly struct AetheriaRuntimeMainMenuCommand",
|
||||
"public static class AetheriaRuntimeMainMenuSurfaceCommands",
|
||||
|
|
@ -9870,11 +9875,9 @@ static void RequireClientTargetBootAuthority(string root)
|
|||
var requiredMainMenuBuilderSymbols = new[]
|
||||
{
|
||||
"private static AetheriaRuntimeSurfaceDocument BuildRoot(",
|
||||
"var verseLabel = VerseLabel(verseTitle, verseId)",
|
||||
"\"Verse\"",
|
||||
"\"Target\"",
|
||||
"\"Daemon\"",
|
||||
"\"Transport\""
|
||||
"\"STARBRIDGE\"",
|
||||
"AetheriaMainMenuGravityField.FromDaemonFrame(daemonFrame)",
|
||||
"GravitySurface($"
|
||||
};
|
||||
var missingMainMenuSymbols = requiredMainMenuSymbols
|
||||
.Where(symbol => !mainMenu.Contains(symbol, StringComparison.Ordinal))
|
||||
|
|
@ -11614,7 +11617,10 @@ static void RequireDaemonVersePublication(string root)
|
|||
"public const string DaemonGameSurfaceKey = \"eve:surface:aetheria.daemon.game\"",
|
||||
"public const string DaemonGameTuiSurfaceKey = \"eve:surface:aetheria.daemon.game.tui\"",
|
||||
"public const string DaemonEditorSurfaceKey = \"eve:surface:aetheria.daemon.editor\"",
|
||||
"public const string DaemonEditorTuiSurfaceKey = \"eve:surface:aetheria.daemon.editor.tui\"",
|
||||
"public const string DaemonEditorTuiSurfaceKey = \"eve:surface:aetheria.daemon.editor.tui\""
|
||||
};
|
||||
var requiredDaemonProviderDocumentSymbols = new[]
|
||||
{
|
||||
"AetheriaRuntimeDaemonGameSurfaceBuilder.SurfaceId",
|
||||
"AetheriaRuntimeDaemonGameSurfaceBuilder.TuiSurfaceId",
|
||||
"AetheriaRuntimeDaemonEditorSurfaceBuilder.SurfaceId",
|
||||
|
|
@ -11629,6 +11635,15 @@ static void RequireDaemonVersePublication(string root)
|
|||
"Odin-visible provider advertisement no longer points at managed daemon CultMesh records: " +
|
||||
string.Join(", ", missingProviderAdvertisementSymbols));
|
||||
}
|
||||
var missingDaemonProviderDocumentSymbols = requiredDaemonProviderDocumentSymbols
|
||||
.Where(symbol => !daemonDocuments.Contains(symbol, StringComparison.Ordinal))
|
||||
.ToArray();
|
||||
if (missingDaemonProviderDocumentSymbols.Length > 0)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Daemon provider advertisement document no longer owns daemon surface ids: " +
|
||||
string.Join(", ", missingDaemonProviderDocumentSymbols));
|
||||
}
|
||||
|
||||
var forbiddenProviderAdvertisementSymbols = new[]
|
||||
{
|
||||
|
|
@ -13542,19 +13557,11 @@ static void RequireMainMenuVerseHostDocumentAccess(string root)
|
|||
"public static AetheriaRuntimeSurfaceDocument BuildRoot(",
|
||||
"AetheriaRuntimeStateBootReport stateBoot",
|
||||
"AetheriaRuntimeVerseHostSettingsDocument verseHost",
|
||||
"verseHost?.Title ?? stateBoot.Title",
|
||||
"verseHost?.VerseId ?? stateBoot.VerseId",
|
||||
"verseHost?.Visibility ?? \"unknown\"",
|
||||
"verseHost?.CultMeshAddress ?? stateBoot.CultMeshAddress",
|
||||
".TitleSubtitle(\"AETHERIA\", \"TERMINUS\")",
|
||||
".Metric(\"Verse\", verseLabel)",
|
||||
".Metric(\"Target\", targetLine)",
|
||||
".Metric(\"Daemon\", daemonLine)",
|
||||
".Metric(\"Transport\", transportLine)",
|
||||
"private static string VerseLabel(",
|
||||
"private static string TargetLine(",
|
||||
"\"No daemon frame\"",
|
||||
"\"Run {daemonRunId} / frame {daemonFrameId}\""
|
||||
"AetheriaMainMenuGravityField.FromDaemonFrame(daemonFrame)",
|
||||
"GravitySurface($",
|
||||
"\"AETHERIA\"",
|
||||
"\"STARBRIDGE\"",
|
||||
"\"Aetheria Starbridge\""
|
||||
};
|
||||
var requiredClientTargetBuilderSymbols = new[]
|
||||
{
|
||||
|
|
@ -16349,6 +16356,67 @@ static async Task RequireTradeValuePolicyEveCommandPersistsAsync()
|
|||
}
|
||||
}
|
||||
|
||||
static async Task RequireMainMenuEveCommandPersistsAsync()
|
||||
{
|
||||
var tempStatePath = Path.Combine(
|
||||
Path.GetTempPath(),
|
||||
$"aetheria-main-menu-command-{Guid.NewGuid():N}.cc");
|
||||
|
||||
try
|
||||
{
|
||||
await using var commandNode = await AetheriaStateNode.OpenAsync(
|
||||
tempStatePath,
|
||||
"aetheria-state-verify-main-menu",
|
||||
enableDurableShardLogs: false);
|
||||
|
||||
if (!AetheriaRuntimeEveCommandClient.TryCreateKnownSurfaceCommand(
|
||||
new EveSurfaceCommandRequest(
|
||||
AetheriaRuntimeMainMenuSurfaceBuilder.ProviderId,
|
||||
AetheriaRuntimeMainMenuCommands.RootSurfaceId,
|
||||
CultMesh.OperationInvocation(
|
||||
AetheriaRuntimeMainMenuCommands.ShowSettings,
|
||||
AetheriaRuntimeEveCommandDocument.SchemaId,
|
||||
new CultMeshRouteHint(CultMeshLocalityKind.Network, "aetheria-eve-command")),
|
||||
CultMesh.OperationPayload(),
|
||||
DateTimeOffset.UtcNow,
|
||||
"aetheria-state-verify"),
|
||||
out var envelope) ||
|
||||
envelope == null)
|
||||
{
|
||||
throw new InvalidOperationException("Main menu Eve surface command did not create a typed command envelope.");
|
||||
}
|
||||
|
||||
var command = AetheriaRuntimeEveCommandClient.ToDocument(envelope);
|
||||
await commandNode.SubmitEveCommandAsync(command).ConfigureAwait(false);
|
||||
|
||||
var report = await AetheriaEveCommandBridge.AcceptObservedAsync(commandNode).ConfigureAwait(false);
|
||||
if (report.AcceptedMainMenuCommands != 1)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Main menu Eve command was not accepted by the typed command bridge.");
|
||||
}
|
||||
|
||||
var menuState = await commandNode.MutableDocument<AetheriaMainMenuState>(AetheriaStateNode.MainMenuStateKey).ReadAsync().ConfigureAwait(false)
|
||||
?? throw new InvalidOperationException("Main menu state was not created by the typed Eve command.");
|
||||
if (!string.Equals(menuState.ActiveSurfaceId, AetheriaRuntimeMainMenuCommands.SettingsSurfaceId, StringComparison.Ordinal))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Main menu Eve command did not persist daemon-owned panel state. Expected {AetheriaRuntimeMainMenuCommands.SettingsSurfaceId}, got {menuState.ActiveSurfaceId}.");
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(tempStatePath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Best-effort cleanup for verifier scratch state.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void RequireDeadPropertiesPanelShellDeleted(string root)
|
||||
{
|
||||
var deletedShellPaths = new[]
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ public static class AetheriaDocumentRegistry
|
|||
typeof(AetheriaZoneState),
|
||||
typeof(AetheriaEntitySnapshot),
|
||||
typeof(AetheriaVerseHostSettings),
|
||||
typeof(AetheriaMainMenuState),
|
||||
typeof(AetheriaEveCommandAcceptanceStatus),
|
||||
typeof(AetheriaRuntimeDaemonProviderAdvertisementDocument),
|
||||
typeof(AetheriaRuntimeDaemonHealthDocument),
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ public sealed class AetheriaEveCommandAcceptanceReport
|
|||
public int AcceptedLoadoutTemplateCommands { get; set; }
|
||||
public int AcceptedVerseHostCommands { get; set; }
|
||||
public int AcceptedTradeValuePolicyCommands { get; set; }
|
||||
public int AcceptedMainMenuCommands { get; set; }
|
||||
public int RejectedCommands { get; set; }
|
||||
public string[] AcceptedCommandIds { get; set; } = [];
|
||||
public string[] RejectedCommandIds { get; set; } = [];
|
||||
|
|
@ -104,6 +105,19 @@ public static class AetheriaEveCommandBridge
|
|||
await ExecuteTradeValuePolicyCommandAsync(node, command).ConfigureAwait(false);
|
||||
report.AcceptedTradeValuePolicyCommands++;
|
||||
break;
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuContinueRun:
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuNewGame:
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuShowSettings:
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuQuit:
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuShowPlayerSettings:
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuShowVerseSettings:
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuShowInputSettings:
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuBackToMain:
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuBackToSettings:
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuOpenRuntimeInputScreen:
|
||||
await ExecuteMainMenuCommandAsync(node, command).ConfigureAwait(false);
|
||||
report.AcceptedMainMenuCommands++;
|
||||
break;
|
||||
}
|
||||
|
||||
accepted.Add(command.CommandId ?? "");
|
||||
|
|
@ -352,6 +366,64 @@ public static class AetheriaEveCommandBridge
|
|||
}
|
||||
}
|
||||
|
||||
private static async Task ExecuteMainMenuCommandAsync(
|
||||
AetheriaStateNode node,
|
||||
AetheriaRuntimeEveCommandDocument command)
|
||||
{
|
||||
var state = await node.MutableDocument<AetheriaMainMenuState>(AetheriaStateNode.MainMenuStateKey).ReadAsync().ConfigureAwait(false) ??
|
||||
new AetheriaMainMenuState();
|
||||
var activeSurfaceId = ActiveMainMenuSurfaceFor(command.Kind, state.ActiveSurfaceId);
|
||||
state.ActiveSurfaceId = activeSurfaceId;
|
||||
state.LastCommandId = command.CommandId ?? "";
|
||||
state.LastCommand = command.Command ?? "";
|
||||
state.UpdatedAtUtc = string.IsNullOrWhiteSpace(command.IssuedAtUtc)
|
||||
? DateTimeOffset.UtcNow.ToString("O")
|
||||
: command.IssuedAtUtc;
|
||||
await node.MutableDocument<AetheriaMainMenuState>(AetheriaStateNode.MainMenuStateKey)
|
||||
.ReplaceAsync(state)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private static string ActiveMainMenuSurfaceFor(
|
||||
AetheriaRuntimeEveCommandKind kind,
|
||||
string currentSurfaceId)
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuShowSettings:
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuBackToSettings:
|
||||
return AetheriaRuntimeMainMenuCommands.SettingsSurfaceId;
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuShowPlayerSettings:
|
||||
return AetheriaRuntimeMainMenuCommands.PlayerSettingsSurfaceId;
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuShowVerseSettings:
|
||||
return AetheriaRuntimeMainMenuCommands.VerseSettingsSurfaceId;
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuShowInputSettings:
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuOpenRuntimeInputScreen:
|
||||
return AetheriaRuntimeMainMenuCommands.InputSettingsSurfaceId;
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuBackToMain:
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuContinueRun:
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuNewGame:
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuQuit:
|
||||
return AetheriaRuntimeMainMenuCommands.RootSurfaceId;
|
||||
default:
|
||||
return NormalizeMainMenuSurfaceId(currentSurfaceId);
|
||||
}
|
||||
}
|
||||
|
||||
private static string NormalizeMainMenuSurfaceId(string surfaceId)
|
||||
{
|
||||
switch (surfaceId ?? "")
|
||||
{
|
||||
case AetheriaRuntimeMainMenuCommands.SettingsSurfaceId:
|
||||
case AetheriaRuntimeMainMenuCommands.InputSettingsSurfaceId:
|
||||
case AetheriaRuntimeMainMenuCommands.PlayerSettingsSurfaceId:
|
||||
case AetheriaRuntimeMainMenuCommands.VerseSettingsSurfaceId:
|
||||
return surfaceId;
|
||||
default:
|
||||
return AetheriaRuntimeMainMenuCommands.RootSurfaceId;
|
||||
}
|
||||
}
|
||||
|
||||
private static string Cycle(string current, params string[] values)
|
||||
{
|
||||
if (values.Length == 0)
|
||||
|
|
|
|||
|
|
@ -259,6 +259,9 @@ public sealed class AetheriaStateNode : IAsyncDisposable, IDisposable
|
|||
public static CultRecordKey EveCommandAcceptanceStatusKey { get; } =
|
||||
new("global:aetheria.eve_command_acceptance_status.v1");
|
||||
|
||||
public static CultRecordKey MainMenuStateKey { get; } =
|
||||
new("global:aetheria.main_menu_state.v1");
|
||||
|
||||
public static CultRecordKey TradeValuePolicyKey { get; } =
|
||||
new(AetheriaTradeValuePolicy.RecordKey);
|
||||
|
||||
|
|
|
|||
|
|
@ -69,4 +69,7 @@ public sealed class AetheriaEveCommandAcceptanceStatus
|
|||
|
||||
[Key(19)]
|
||||
public string[] AccountedCommandIds { get; set; } = [];
|
||||
|
||||
[Key(20)]
|
||||
public int AppliedMainMenuCommands { get; set; }
|
||||
}
|
||||
|
|
|
|||
26
Aetheria.State/Documents/AetheriaMainMenuState.cs
Normal file
26
Aetheria.State/Documents/AetheriaMainMenuState.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
using GameCult.Caching;
|
||||
using MessagePack;
|
||||
|
||||
namespace Aetheria.State.Documents;
|
||||
|
||||
[CultDocument("aetheria.main_menu_state", "aetheria.main_menu_state.v1")]
|
||||
[CultGlobal]
|
||||
[MessagePackObject]
|
||||
public sealed class AetheriaMainMenuState
|
||||
{
|
||||
[Key(0)]
|
||||
[CultName]
|
||||
public string Name { get; set; } = "Aetheria main menu state";
|
||||
|
||||
[Key(1)]
|
||||
public string ActiveSurfaceId { get; set; } = "";
|
||||
|
||||
[Key(2)]
|
||||
public string LastCommandId { get; set; } = "";
|
||||
|
||||
[Key(3)]
|
||||
public string LastCommand { get; set; } = "";
|
||||
|
||||
[Key(4)]
|
||||
public string UpdatedAtUtc { get; set; } = "";
|
||||
}
|
||||
|
|
@ -75,7 +75,7 @@ public sealed class AetheriaCultUiCompositionSurfaceWindow : EditorWindow
|
|||
_providerId = TextInput("Provider Id", DefaultProviderId, controls);
|
||||
_providerKind = TextInput("Provider Kind", DefaultProviderKind, controls);
|
||||
_title = TextInput("Title", "AETHERIA", controls);
|
||||
_subtitle = TextInput("Subtitle", "TERMINUS", controls);
|
||||
_subtitle = TextInput("Subtitle", "STARBRIDGE", controls);
|
||||
_note = TextInput("Note", "Live CultUI draft lowered through the shared Eve UI Toolkit path.", controls);
|
||||
_showStatusMetrics = ToggleInput("Status Metrics", true, controls);
|
||||
_useButtonRow = ToggleInput("Button Row", false, controls);
|
||||
|
|
@ -206,7 +206,7 @@ public sealed class AetheriaCultUiCompositionSurfaceWindow : EditorWindow
|
|||
_providerId.value = DefaultProviderId;
|
||||
_providerKind.value = DefaultProviderKind;
|
||||
_title.value = "AETHERIA";
|
||||
_subtitle.value = "TERMINUS";
|
||||
_subtitle.value = "STARBRIDGE";
|
||||
_note.value = "Live CultUI draft lowered through the shared Eve UI Toolkit path.";
|
||||
_showStatusMetrics.value = true;
|
||||
_useButtonRow.value = false;
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ public class MainMenu : MonoBehaviour
|
|||
private void ShowPlayerSettingsSurface(bool animateFromRight = true)
|
||||
{
|
||||
RenderMenuSurface(
|
||||
ResolveMainMenuSurface(AetheriaRuntimeMainMenuCommands.PlayerSettingsShellSurfaceId),
|
||||
ResolveMainMenuSurface(AetheriaRuntimeMainMenuCommands.PlayerSettingsSurfaceId),
|
||||
HandlePlayerSettingsSurfaceCommand,
|
||||
animateFromRight);
|
||||
}
|
||||
|
|
@ -191,7 +191,7 @@ public class MainMenu : MonoBehaviour
|
|||
private void ShowVerseSettingsSurface(bool animateFromRight = true)
|
||||
{
|
||||
RenderMenuSurface(
|
||||
ResolveMainMenuSurface(AetheriaRuntimeMainMenuCommands.VerseSettingsShellSurfaceId),
|
||||
ResolveMainMenuSurface(AetheriaRuntimeMainMenuCommands.VerseSettingsSurfaceId),
|
||||
HandleVerseSettingsSurfaceCommand,
|
||||
animateFromRight);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ namespace GameCult.Aetheria.State.Verse
|
|||
AetheriaRuntimeDaemonFrameDocument frame,
|
||||
AetheriaRuntimeDaemonHealthDocument health,
|
||||
AetheriaRuntimeDaemonCommandBoundaryDocument commandBoundary,
|
||||
AetheriaRuntimeStarbridgeSessionSummaryDocument? starbridge = null)
|
||||
AetheriaRuntimeStarbridgeSessionSummaryDocument? starbridge = null,
|
||||
string activeMainMenuSurfaceId = AetheriaRuntimeMainMenuCommands.RootSurfaceId)
|
||||
{
|
||||
frame ??= new AetheriaRuntimeDaemonFrameDocument();
|
||||
health ??= new AetheriaRuntimeDaemonHealthDocument();
|
||||
|
|
@ -28,10 +29,11 @@ namespace GameCult.Aetheria.State.Verse
|
|||
var entity = FindCurrentEntity(run, zone);
|
||||
var target = FindTargetEntity(zone, entity);
|
||||
var entityName = string.IsNullOrWhiteSpace(entity?.Name) ? "(no current entity)" : entity!.Name;
|
||||
activeMainMenuSurfaceId = NormalizeMainMenuSurfaceId(activeMainMenuSurfaceId);
|
||||
var surfaceChildren = new List<AetheriaRuntimeSurfaceComponent>
|
||||
{
|
||||
GravityFieldSurface("aetheria.daemon.game.field"),
|
||||
MainMenuOverlay("aetheria.daemon.game.main_menu"),
|
||||
MainMenuOverlay("aetheria.daemon.game.main_menu", activeMainMenuSurfaceId),
|
||||
Node(
|
||||
"aetheria.daemon.game.frame",
|
||||
"card",
|
||||
|
|
@ -363,15 +365,18 @@ namespace GameCult.Aetheria.State.Verse
|
|||
null);
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeSurfaceComponent MainMenuOverlay(string id)
|
||||
private static AetheriaRuntimeSurfaceComponent MainMenuOverlay(
|
||||
string id,
|
||||
string activeSurfaceId)
|
||||
{
|
||||
activeSurfaceId = NormalizeMainMenuSurfaceId(activeSurfaceId);
|
||||
return new AetheriaRuntimeSurfaceComponent(
|
||||
id,
|
||||
"surface.slot",
|
||||
new Dictionary<string, string>(StringComparer.Ordinal)
|
||||
{
|
||||
["slotId"] = "mainMenuPanel",
|
||||
["documentId"] = AetheriaRuntimeMainMenuCommands.RootSurfaceId,
|
||||
["documentId"] = activeSurfaceId,
|
||||
["schemaId"] = "gamecult.eve.surface.v1",
|
||||
["presentationKind"] = "menu.overlay"
|
||||
},
|
||||
|
|
@ -381,7 +386,7 @@ namespace GameCult.Aetheria.State.Verse
|
|||
{
|
||||
new AetheriaRuntimeEmbeddedDocumentSlot(
|
||||
"mainMenuPanel",
|
||||
AetheriaRuntimeMainMenuCommands.RootSurfaceId,
|
||||
activeSurfaceId,
|
||||
"gamecult.eve.surface.v1",
|
||||
"menu.overlay")
|
||||
},
|
||||
|
|
@ -401,6 +406,20 @@ namespace GameCult.Aetheria.State.Verse
|
|||
});
|
||||
}
|
||||
|
||||
private static string NormalizeMainMenuSurfaceId(string surfaceId)
|
||||
{
|
||||
switch (surfaceId ?? "")
|
||||
{
|
||||
case AetheriaRuntimeMainMenuCommands.SettingsSurfaceId:
|
||||
case AetheriaRuntimeMainMenuCommands.InputSettingsSurfaceId:
|
||||
case AetheriaRuntimeMainMenuCommands.PlayerSettingsSurfaceId:
|
||||
case AetheriaRuntimeMainMenuCommands.VerseSettingsSurfaceId:
|
||||
return surfaceId;
|
||||
default:
|
||||
return AetheriaRuntimeMainMenuCommands.RootSurfaceId;
|
||||
}
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeRtsViewportBounds DefaultViewport()
|
||||
{
|
||||
return new AetheriaRuntimeRtsViewportBounds
|
||||
|
|
|
|||
|
|
@ -245,6 +245,13 @@ namespace GameCult.Aetheria.State.Verse
|
|||
when AetheriaRuntimeTradeValuePolicyCommands.IsKnown(command):
|
||||
envelope = CreateTradeValuePolicyCommand(CommandKindForSurface(request), request, clientId);
|
||||
return true;
|
||||
case AetheriaRuntimeMainMenuCommands.RootSurfaceId:
|
||||
case AetheriaRuntimeMainMenuCommands.SettingsSurfaceId:
|
||||
case AetheriaRuntimeMainMenuCommands.InputSettingsSurfaceId:
|
||||
case AetheriaRuntimeMainMenuCommands.PlayerSettingsSurfaceId:
|
||||
case AetheriaRuntimeMainMenuCommands.VerseSettingsSurfaceId:
|
||||
envelope = CreateMainMenuCommand(CommandKindForSurface(request), request, clientId);
|
||||
return envelope.Kind != AetheriaRuntimeEveCommandKind.Unknown;
|
||||
}
|
||||
|
||||
envelope = null;
|
||||
|
|
@ -417,6 +424,23 @@ namespace GameCult.Aetheria.State.Verse
|
|||
payload: request.Payload);
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeEveCommandEnvelope CreateMainMenuCommand(
|
||||
AetheriaRuntimeEveCommandKind command,
|
||||
EveSurfaceCommandRequest request,
|
||||
string clientId)
|
||||
{
|
||||
return CreateTypedCommand(
|
||||
request.SurfaceId ?? AetheriaRuntimeMainMenuCommands.RootSurfaceId,
|
||||
command,
|
||||
string.IsNullOrWhiteSpace(clientId) ? request.ClientId ?? "" : clientId,
|
||||
playerSettings: ReadPlayerSettingsBody(request),
|
||||
inputSettings: ReadInputSettingsBody(request),
|
||||
loadoutTemplate: null,
|
||||
tradeValuePolicy: null,
|
||||
invocation: request.Operation,
|
||||
payload: request.Payload);
|
||||
}
|
||||
|
||||
public static AetheriaRuntimeEveCommandDocument ToDocument(AetheriaRuntimeEveCommandEnvelope envelope)
|
||||
{
|
||||
if (envelope == null) throw new ArgumentNullException(nameof(envelope));
|
||||
|
|
@ -616,6 +640,28 @@ namespace GameCult.Aetheria.State.Verse
|
|||
: AetheriaRuntimeEveCommandKind.Unknown;
|
||||
case AetheriaRuntimeTradeValuePolicyCommands.SurfaceId:
|
||||
return TradeValuePolicyKind(command);
|
||||
case AetheriaRuntimeMainMenuCommands.RootSurfaceId:
|
||||
return MainMenuRootKind(command);
|
||||
case AetheriaRuntimeMainMenuCommands.SettingsSurfaceId:
|
||||
return MainMenuSettingsKind(command);
|
||||
case AetheriaRuntimeMainMenuCommands.InputSettingsSurfaceId:
|
||||
return command == AetheriaRuntimeMainMenuCommands.OpenRuntimeInputScreen
|
||||
? AetheriaRuntimeEveCommandKind.MainMenuOpenRuntimeInputScreen
|
||||
: command == AetheriaRuntimeMainMenuCommands.BackToSettings
|
||||
? AetheriaRuntimeEveCommandKind.MainMenuBackToSettings
|
||||
: InputSettingsKind(command);
|
||||
case AetheriaRuntimeMainMenuCommands.PlayerSettingsSurfaceId:
|
||||
return command == AetheriaRuntimeMainMenuCommands.BackToSettings
|
||||
? AetheriaRuntimeEveCommandKind.MainMenuBackToSettings
|
||||
: PlayerSettingsKind(command);
|
||||
case AetheriaRuntimeMainMenuCommands.VerseSettingsSurfaceId:
|
||||
return command == AetheriaRuntimeMainMenuCommands.BackToSettings
|
||||
? AetheriaRuntimeEveCommandKind.MainMenuBackToSettings
|
||||
: command == AetheriaRuntimeVerseHostCommands.Refresh
|
||||
? AetheriaRuntimeEveCommandKind.VerseHostRefresh
|
||||
: command == AetheriaRuntimeVerseHostCommands.CycleVisibility
|
||||
? AetheriaRuntimeEveCommandKind.CycleVerseHostVisibility
|
||||
: AetheriaRuntimeEveCommandKind.Unknown;
|
||||
default:
|
||||
return AetheriaRuntimeEveCommandKind.Unknown;
|
||||
}
|
||||
|
|
@ -671,11 +717,57 @@ namespace GameCult.Aetheria.State.Verse
|
|||
return AetheriaRuntimeTradeValuePolicyCommands.SetQualityExponent;
|
||||
case AetheriaRuntimeEveCommandKind.SetTradeValueTierQuality:
|
||||
return AetheriaRuntimeTradeValuePolicyCommands.SetTierQuality;
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuContinueRun:
|
||||
return AetheriaRuntimeMainMenuCommands.ContinueRun;
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuNewGame:
|
||||
return AetheriaRuntimeMainMenuCommands.NewGame;
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuShowSettings:
|
||||
return AetheriaRuntimeMainMenuCommands.ShowSettings;
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuQuit:
|
||||
return AetheriaRuntimeMainMenuCommands.Quit;
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuShowPlayerSettings:
|
||||
return AetheriaRuntimeMainMenuCommands.ShowPlayerSettings;
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuShowVerseSettings:
|
||||
return AetheriaRuntimeMainMenuCommands.ShowVerseSettings;
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuShowInputSettings:
|
||||
return AetheriaRuntimeMainMenuCommands.ShowInputSettings;
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuBackToMain:
|
||||
return AetheriaRuntimeMainMenuCommands.BackToMain;
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuBackToSettings:
|
||||
return AetheriaRuntimeMainMenuCommands.BackToSettings;
|
||||
case AetheriaRuntimeEveCommandKind.MainMenuOpenRuntimeInputScreen:
|
||||
return AetheriaRuntimeMainMenuCommands.OpenRuntimeInputScreen;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeEveCommandKind MainMenuRootKind(string command)
|
||||
{
|
||||
if (command == AetheriaRuntimeMainMenuCommands.ContinueRun)
|
||||
return AetheriaRuntimeEveCommandKind.MainMenuContinueRun;
|
||||
if (command == AetheriaRuntimeMainMenuCommands.NewGame)
|
||||
return AetheriaRuntimeEveCommandKind.MainMenuNewGame;
|
||||
if (command == AetheriaRuntimeMainMenuCommands.ShowSettings)
|
||||
return AetheriaRuntimeEveCommandKind.MainMenuShowSettings;
|
||||
if (command == AetheriaRuntimeMainMenuCommands.Quit)
|
||||
return AetheriaRuntimeEveCommandKind.MainMenuQuit;
|
||||
return AetheriaRuntimeEveCommandKind.Unknown;
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeEveCommandKind MainMenuSettingsKind(string command)
|
||||
{
|
||||
if (command == AetheriaRuntimeMainMenuCommands.ShowPlayerSettings)
|
||||
return AetheriaRuntimeEveCommandKind.MainMenuShowPlayerSettings;
|
||||
if (command == AetheriaRuntimeMainMenuCommands.ShowVerseSettings)
|
||||
return AetheriaRuntimeEveCommandKind.MainMenuShowVerseSettings;
|
||||
if (command == AetheriaRuntimeMainMenuCommands.ShowInputSettings)
|
||||
return AetheriaRuntimeEveCommandKind.MainMenuShowInputSettings;
|
||||
if (command == AetheriaRuntimeMainMenuCommands.BackToMain)
|
||||
return AetheriaRuntimeEveCommandKind.MainMenuBackToMain;
|
||||
return AetheriaRuntimeEveCommandKind.Unknown;
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeEveCommandKind PlayerSettingsKind(string command)
|
||||
{
|
||||
if (command == AetheriaRuntimePlayerSettingsCommands.Refresh)
|
||||
|
|
|
|||
|
|
@ -33,7 +33,17 @@ namespace GameCult.Aetheria.State.Verse
|
|||
SetTradeValueQualityMinimum = 20,
|
||||
SetTradeValueQualityMaximum = 21,
|
||||
SetTradeValueQualityExponent = 22,
|
||||
SetTradeValueTierQuality = 23
|
||||
SetTradeValueTierQuality = 23,
|
||||
MainMenuContinueRun = 24,
|
||||
MainMenuNewGame = 25,
|
||||
MainMenuShowSettings = 26,
|
||||
MainMenuQuit = 27,
|
||||
MainMenuShowPlayerSettings = 28,
|
||||
MainMenuShowVerseSettings = 29,
|
||||
MainMenuShowInputSettings = 30,
|
||||
MainMenuBackToMain = 31,
|
||||
MainMenuBackToSettings = 32,
|
||||
MainMenuOpenRuntimeInputScreen = 33
|
||||
}
|
||||
|
||||
public sealed class AetheriaRuntimeEveCommandEnvelope
|
||||
|
|
|
|||
|
|
@ -41,17 +41,7 @@ namespace GameCult.Aetheria.State.Verse
|
|||
long version = 1)
|
||||
{
|
||||
return BuildRoot(
|
||||
stateBoot.TargetLabel,
|
||||
stateBoot.TargetKind,
|
||||
stateBoot.TargetSource,
|
||||
stateBoot.Title,
|
||||
stateBoot.VerseId,
|
||||
"unknown",
|
||||
stateBoot.CultMeshAddress,
|
||||
inGame,
|
||||
hasAuthoritativeDaemonFrame: false,
|
||||
daemonRunId: "",
|
||||
daemonFrameId: -1,
|
||||
gravityField: AetheriaMainMenuGravityField.Default(),
|
||||
updatedAtUtc,
|
||||
version);
|
||||
|
|
@ -68,17 +58,7 @@ namespace GameCult.Aetheria.State.Verse
|
|||
long version = 1)
|
||||
{
|
||||
return BuildRoot(
|
||||
stateBoot.TargetLabel,
|
||||
stateBoot.TargetKind,
|
||||
stateBoot.TargetSource,
|
||||
verseHost?.Title ?? stateBoot.Title,
|
||||
verseHost?.VerseId ?? stateBoot.VerseId,
|
||||
verseHost?.Visibility ?? "unknown",
|
||||
verseHost?.CultMeshAddress ?? stateBoot.CultMeshAddress,
|
||||
inGame,
|
||||
hasAuthoritativeDaemonFrame: daemonFrame != null,
|
||||
daemonFrame?.Run?.RunId ?? "",
|
||||
daemonFrame?.FrameId ?? -1,
|
||||
gravityField: AetheriaMainMenuGravityField.FromDaemonFrame(daemonFrame),
|
||||
updatedAtUtc,
|
||||
version);
|
||||
|
|
@ -95,17 +75,7 @@ namespace GameCult.Aetheria.State.Verse
|
|||
long version = 1)
|
||||
{
|
||||
return BuildRoot(
|
||||
stateBoot.TargetLabel,
|
||||
stateBoot.TargetKind,
|
||||
stateBoot.TargetSource,
|
||||
verseHost?.Title ?? stateBoot.Title,
|
||||
verseHost?.VerseId ?? stateBoot.VerseId,
|
||||
verseHost?.Visibility ?? "unknown",
|
||||
verseHost?.CultMeshAddress ?? stateBoot.CultMeshAddress,
|
||||
inGame,
|
||||
hasAuthoritativeDaemonFrame: sectorMap != null,
|
||||
sectorMap?.RunId ?? "",
|
||||
sectorMap?.FrameId ?? -1,
|
||||
gravityField: AetheriaMainMenuGravityField.Default(),
|
||||
updatedAtUtc,
|
||||
version);
|
||||
|
|
@ -141,17 +111,7 @@ namespace GameCult.Aetheria.State.Verse
|
|||
}
|
||||
|
||||
private static AetheriaRuntimeSurfaceDocument BuildRoot(
|
||||
string targetLabel,
|
||||
string targetKind,
|
||||
string targetSource,
|
||||
string verseTitle,
|
||||
string verseId,
|
||||
string verseVisibility,
|
||||
string verseCultMeshAddress,
|
||||
bool inGame,
|
||||
bool hasAuthoritativeDaemonFrame,
|
||||
string daemonRunId,
|
||||
long daemonFrameId,
|
||||
AetheriaMainMenuGravityField gravityField,
|
||||
string updatedAtUtc,
|
||||
long version)
|
||||
|
|
@ -195,7 +155,7 @@ namespace GameCult.Aetheria.State.Verse
|
|||
("font", "100 5.9rem/0.98 Montserrat, sans-serif"),
|
||||
("color", "rgba(232, 250, 255, 0.94)"),
|
||||
("whiteSpace", "nowrap"))),
|
||||
Text($"{AetheriaRuntimeMainMenuCommands.RootSurfaceId}.subtitle", "TERMINUS", "text.subtitle",
|
||||
Text($"{AetheriaRuntimeMainMenuCommands.RootSurfaceId}.subtitle", "STARBRIDGE", "text.subtitle",
|
||||
Layout(("margin", "0 0 0.35rem 16.8rem")),
|
||||
Style(
|
||||
("font", "100 2.6rem/1 Montserrat, sans-serif"),
|
||||
|
|
@ -212,7 +172,7 @@ namespace GameCult.Aetheria.State.Verse
|
|||
return new AetheriaRuntimeSurfaceDocument(
|
||||
ProviderId,
|
||||
ProviderKind,
|
||||
"Aetheria Terminus",
|
||||
"Aetheria Starbridge",
|
||||
version,
|
||||
updatedAtUtc,
|
||||
new AetheriaRuntimeSurfaceTree(
|
||||
|
|
@ -228,27 +188,6 @@ namespace GameCult.Aetheria.State.Verse
|
|||
});
|
||||
}
|
||||
|
||||
private static string VerseLabel(string verseTitle, string verseId)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(verseTitle))
|
||||
return string.IsNullOrWhiteSpace(verseId) ? "Unknown Verse" : verseId;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(verseId) || string.Equals(verseTitle, verseId, StringComparison.Ordinal))
|
||||
return verseTitle;
|
||||
|
||||
return $"{verseTitle} / {verseId}";
|
||||
}
|
||||
|
||||
private static string TargetLine(string targetLabel, string targetKind, string targetSource)
|
||||
{
|
||||
var label = string.IsNullOrWhiteSpace(targetLabel) ? "Unknown target" : targetLabel;
|
||||
var kind = string.IsNullOrWhiteSpace(targetKind) ? "unknown" : targetKind;
|
||||
if (string.IsNullOrWhiteSpace(targetSource))
|
||||
return $"{label} ({kind})";
|
||||
|
||||
return $"{label} ({kind}) / {targetSource}";
|
||||
}
|
||||
|
||||
public static AetheriaRuntimeSurfaceDocument BuildSettings(
|
||||
string updatedAtUtc,
|
||||
long version = 1)
|
||||
|
|
|
|||
Loading…
Reference in a new issue