Refactor runtime bootstrap and ship control flows
This commit is contained in:
@@ -14,16 +14,22 @@ import {
|
||||
upsertPlayerDirective,
|
||||
upsertPlayerPolicy,
|
||||
} from "../../api";
|
||||
import { getShipBehaviorLabel, getShipOrderLabel } from "../../shipAutomationPresentation";
|
||||
import type { PlayerFactionSnapshot } from "../../contractsPlayerFaction";
|
||||
import { useGmStore } from "../../ui/stores/gmStore";
|
||||
import { useAuthStore } from "../../ui/stores/authStore";
|
||||
import { usePlayerFactionStore } from "../../ui/stores/playerFactionStore";
|
||||
import { useShipAutomationCatalogStore } from "../../ui/stores/shipAutomationCatalogStore";
|
||||
import { useViewerSelectionStore } from "../../ui/stores/viewerSelection";
|
||||
|
||||
const gmStore = useGmStore();
|
||||
const authStore = useAuthStore();
|
||||
const playerStore = usePlayerFactionStore();
|
||||
const automationStore = useShipAutomationCatalogStore();
|
||||
const selectionStore = useViewerSelectionStore();
|
||||
const { selectedEntityId, selectedEntityKind } = storeToRefs(selectionStore);
|
||||
const { playerFaction } = storeToRefs(playerStore);
|
||||
const { session } = storeToRefs(authStore);
|
||||
|
||||
const statusMessage = ref("");
|
||||
const errorMessage = ref("");
|
||||
@@ -129,56 +135,22 @@ const selectedOrganizationSummary = computed(() => {
|
||||
return lines;
|
||||
});
|
||||
|
||||
const behaviorOptions = [
|
||||
"idle",
|
||||
"hold-position",
|
||||
"follow-ship",
|
||||
"patrol",
|
||||
"police",
|
||||
"protect-position",
|
||||
"protect-ship",
|
||||
"protect-station",
|
||||
"local-auto-mine",
|
||||
"advanced-auto-mine",
|
||||
"expert-auto-mine",
|
||||
"local-auto-trade",
|
||||
"advanced-auto-trade",
|
||||
"fill-shortages",
|
||||
"find-build-tasks",
|
||||
"revisit-known-stations",
|
||||
"supply-fleet",
|
||||
"dock-and-wait",
|
||||
"fly-and-wait",
|
||||
"fly-to-object",
|
||||
"auto-salvage",
|
||||
"repeat-orders",
|
||||
];
|
||||
const behaviorOptions = computed(() =>
|
||||
(automationStore.catalog?.behaviors ?? [])
|
||||
.filter((entry) => entry.supportStatus !== "InternalOnly")
|
||||
.map((entry) => entry.id),
|
||||
);
|
||||
|
||||
onMounted(async () => {
|
||||
if (playerStore.playerFaction) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setPlayerSnapshot(await fetchPlayerFaction());
|
||||
} catch {
|
||||
// The world snapshot path normally provides this; ignore here and let the parent lifecycle recover.
|
||||
}
|
||||
await automationStore.load();
|
||||
await loadPlayerSnapshotIfNeeded();
|
||||
});
|
||||
|
||||
const orderOptions = [
|
||||
"move",
|
||||
"dock-at-station",
|
||||
"dock-and-wait",
|
||||
"fly-and-wait",
|
||||
"fly-to-object",
|
||||
"follow-ship",
|
||||
"trade-route",
|
||||
"mine-and-deliver",
|
||||
"build-at-site",
|
||||
"attack-target",
|
||||
"hold-position",
|
||||
];
|
||||
const orderOptions = computed(() =>
|
||||
(automationStore.catalog?.orders ?? [])
|
||||
.filter((entry) => entry.supportStatus !== "InternalOnly")
|
||||
.map((entry) => entry.id),
|
||||
);
|
||||
|
||||
const orgForm = reactive({
|
||||
kind: "fleet",
|
||||
@@ -278,7 +250,7 @@ const behaviorForm = reactive({
|
||||
homeSystemId: "",
|
||||
areaSystemId: "",
|
||||
targetEntityId: "",
|
||||
preferredItemId: "",
|
||||
itemId: "",
|
||||
preferredNodeId: "",
|
||||
preferredConstructionSiteId: "",
|
||||
preferredModuleId: "",
|
||||
@@ -353,6 +325,15 @@ watch(player, (value) => {
|
||||
}
|
||||
}, { immediate: true });
|
||||
|
||||
watch(session, async (value) => {
|
||||
if (!value) {
|
||||
playerStore.setPlayerFaction(null);
|
||||
return;
|
||||
}
|
||||
|
||||
await loadPlayerSnapshotIfNeeded();
|
||||
});
|
||||
|
||||
watch(selectedShip, (ship) => {
|
||||
if (!ship) {
|
||||
return;
|
||||
@@ -362,7 +343,7 @@ watch(selectedShip, (ship) => {
|
||||
behaviorForm.homeSystemId = ship.defaultBehavior.homeSystemId ?? ship.systemId;
|
||||
behaviorForm.areaSystemId = ship.defaultBehavior.areaSystemId ?? ship.systemId;
|
||||
behaviorForm.targetEntityId = ship.defaultBehavior.targetEntityId ?? "";
|
||||
behaviorForm.preferredItemId = ship.defaultBehavior.preferredItemId ?? "";
|
||||
behaviorForm.itemId = ship.defaultBehavior.itemId ?? "";
|
||||
behaviorForm.preferredNodeId = ship.defaultBehavior.preferredNodeId ?? "";
|
||||
behaviorForm.preferredConstructionSiteId = ship.defaultBehavior.preferredConstructionSiteId ?? "";
|
||||
behaviorForm.preferredModuleId = ship.defaultBehavior.preferredModuleId ?? "";
|
||||
@@ -426,6 +407,18 @@ function setPlayerSnapshot(snapshot: PlayerFactionSnapshot) {
|
||||
playerStore.setPlayerFaction(snapshot);
|
||||
}
|
||||
|
||||
async function loadPlayerSnapshotIfNeeded() {
|
||||
if (!authStore.isAuthenticated || playerStore.playerFaction) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setPlayerSnapshot(await fetchPlayerFaction());
|
||||
} catch {
|
||||
// Player domain may not exist yet for the current world; leave the panel empty.
|
||||
}
|
||||
}
|
||||
|
||||
async function runAction(action: () => Promise<void>, successMessage: string) {
|
||||
busy.value = true;
|
||||
errorMessage.value = "";
|
||||
@@ -618,7 +611,7 @@ async function submitDirectBehavior() {
|
||||
homeStationId: null,
|
||||
areaSystemId: behaviorForm.areaSystemId || null,
|
||||
targetEntityId: behaviorForm.targetEntityId || null,
|
||||
preferredItemId: behaviorForm.preferredItemId || null,
|
||||
itemId: behaviorForm.itemId || null,
|
||||
preferredNodeId: behaviorForm.preferredNodeId || null,
|
||||
preferredConstructionSiteId: behaviorForm.preferredConstructionSiteId || null,
|
||||
preferredModuleId: behaviorForm.preferredModuleId || null,
|
||||
@@ -690,14 +683,14 @@ async function submitDirectOrder() {
|
||||
<h4>Selected Asset Control</h4>
|
||||
<div v-if="selectedShip || selectedStation" class="player-card-list">
|
||||
<div class="player-card">
|
||||
<strong>{{ selectedShip?.label ?? selectedStation?.label }}</strong>
|
||||
<strong>{{ selectedShip?.name ?? selectedStation?.label }}</strong>
|
||||
<span>{{ selectedShip ? "Ship" : "Station" }} · {{ selectedShip?.systemId ?? selectedStation?.systemId }}</span>
|
||||
<span v-if="selectedAssignment">Assignment {{ selectedAssignment.role }} · {{ selectedAssignment.directiveId ?? "no directive" }}</span>
|
||||
<span v-else>No player assignment</span>
|
||||
</div>
|
||||
<div v-if="selectedShip" class="player-card">
|
||||
<strong>Behavior</strong>
|
||||
<span>{{ titleCase(selectedShip.defaultBehavior.kind) }}</span>
|
||||
<span>{{ getShipBehaviorLabel(selectedShip.defaultBehavior.kind) }}</span>
|
||||
<span>Orders {{ selectedShip.orderQueue.length }} · Plan {{ selectedShip.activePlan?.kind ?? "none" }}</span>
|
||||
<span>Command {{ titleCase(selectedShip.controlSourceKind) }}<template v-if="selectedShip.controlReason"> · {{ selectedShip.controlReason }}</template></span>
|
||||
<span v-if="selectedShip.lastReplanReason">Replan {{ selectedShip.lastReplanReason }}</span>
|
||||
@@ -708,11 +701,11 @@ async function submitDirectOrder() {
|
||||
|
||||
<form v-if="selectedShip" class="player-form" @submit.prevent="submitDirectBehavior">
|
||||
<h5>Direct Ship Behavior</h5>
|
||||
<label><span>Behavior</span><select v-model="behaviorForm.kind"><option v-for="option in behaviorOptions" :key="option" :value="option">{{ option }}</option></select></label>
|
||||
<label><span>Behavior</span><select v-model="behaviorForm.kind"><option v-for="option in behaviorOptions" :key="option" :value="option">{{ getShipBehaviorLabel(option) }}</option></select></label>
|
||||
<label><span>Home System</span><input v-model="behaviorForm.homeSystemId" type="text"></label>
|
||||
<label><span>Area System</span><input v-model="behaviorForm.areaSystemId" type="text"></label>
|
||||
<label><span>Target Entity</span><input v-model="behaviorForm.targetEntityId" type="text"></label>
|
||||
<label><span>Preferred Item</span><input v-model="behaviorForm.preferredItemId" type="text"></label>
|
||||
<label><span>Item</span><input v-model="behaviorForm.itemId" type="text"></label>
|
||||
<label><span>Preferred Node</span><input v-model="behaviorForm.preferredNodeId" type="text"></label>
|
||||
<label><span>Construction Site</span><input v-model="behaviorForm.preferredConstructionSiteId" type="text"></label>
|
||||
<label><span>Module</span><input v-model="behaviorForm.preferredModuleId" type="text"></label>
|
||||
@@ -725,7 +718,7 @@ async function submitDirectOrder() {
|
||||
|
||||
<form v-if="selectedShip" class="player-form" @submit.prevent="submitDirectOrder">
|
||||
<h5>Direct Ship Order</h5>
|
||||
<label><span>Order</span><select v-model="orderForm.kind"><option v-for="option in orderOptions" :key="option" :value="option">{{ option }}</option></select></label>
|
||||
<label><span>Order</span><select v-model="orderForm.kind"><option v-for="option in orderOptions" :key="option" :value="option">{{ getShipOrderLabel(option) }}</option></select></label>
|
||||
<label><span>Label</span><input v-model="orderForm.label" type="text"></label>
|
||||
<label><span>Target System</span><input v-model="orderForm.targetSystemId" type="text"></label>
|
||||
<label><span>Target Entity</span><input v-model="orderForm.targetEntityId" type="text"></label>
|
||||
@@ -793,7 +786,7 @@ async function submitDirectOrder() {
|
||||
<form class="player-form" @submit.prevent="submitCoreAutomation">
|
||||
<h5>Core Automation</h5>
|
||||
<label><span>Label</span><input v-model="automationForm.label" type="text"></label>
|
||||
<label><span>Behavior</span><select v-model="automationForm.behaviorKind"><option v-for="option in behaviorOptions" :key="option" :value="option">{{ option }}</option></select></label>
|
||||
<label><span>Behavior</span><select v-model="automationForm.behaviorKind"><option v-for="option in behaviorOptions" :key="option" :value="option">{{ getShipBehaviorLabel(option) }}</option></select></label>
|
||||
<label><span>Order Staging</span><input v-model="automationForm.stagingOrderKind" type="text"></label>
|
||||
<label><span>Preferred Item</span><input v-model="automationForm.preferredItemId" type="text"></label>
|
||||
<label><span>System Range</span><input v-model.number="automationForm.maxSystemRange" type="number" min="0" step="1"></label>
|
||||
@@ -852,7 +845,7 @@ async function submitDirectOrder() {
|
||||
<label><span>Kind</span><input v-model="directiveForm.kind" type="text"></label>
|
||||
<label><span>Scope Kind</span><input v-model="directiveForm.scopeKind" type="text"></label>
|
||||
<label><span>Scope Id</span><input v-model="directiveForm.scopeId" type="text" :placeholder="selectedEntityId ?? ''"></label>
|
||||
<label><span>Behavior</span><select v-model="directiveForm.behaviorKind"><option v-for="option in behaviorOptions" :key="option" :value="option">{{ option }}</option></select></label>
|
||||
<label><span>Behavior</span><select v-model="directiveForm.behaviorKind"><option v-for="option in behaviorOptions" :key="option" :value="option">{{ getShipBehaviorLabel(option) }}</option></select></label>
|
||||
<label><span>Staging Order</span><input v-model="directiveForm.stagingOrderKind" type="text"></label>
|
||||
<label><span>Target System</span><input v-model="directiveForm.targetSystemId" type="text"></label>
|
||||
<label><span>Target Entity</span><input v-model="directiveForm.targetEntityId" type="text"></label>
|
||||
|
||||
Reference in New Issue
Block a user