deadhead-space-freight-tycoon/packages/schema/src/requests.ts

143 lines
5.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { z } from "zod";
import {
baySchema,
companySchema,
contractSchema,
dispatchSchema,
idSchema,
pilotSchema,
playerStateSchema,
shipSchema,
timeSchema,
} from "./entities";
/** Request with no body or parameters. */
export const emptyRequestSchema = z.object({}).strict();
export const createGuestResponseSchema = z.object({
playerId: idSchema,
state: playerStateSchema,
});
export const contractBoardRequestSchema = z.object({ locationId: idSchema });
export const contractBoardResponseSchema = z.object({
contracts: z.array(contractSchema),
/** When this board period ends and every contract on it expires. */
periodEndsAt: timeSchema,
});
export const createDispatchRequestSchema = z.discriminatedUnion("kind", [
z.object({
kind: z.literal("contract"),
contractId: idSchema,
shipId: idSchema,
pilotId: idSchema,
}),
/** The avatar flies the loaner; no ship or pilot to choose. */
z.object({ kind: z.literal("tutorial"), contractId: idSchema }),
z.object({
kind: z.literal("reposition"),
shipId: idSchema,
pilotId: idSchema,
destinationId: idSchema,
}),
]);
export type CreateDispatchRequest = z.infer<typeof createDispatchRequestSchema>;
export const dispatchResponseSchema = z.object({ dispatch: dispatchSchema });
/** Decision 0.5.35: the ship is delivered to one of the player's bays. */
export const buyShipRequestSchema = z.object({ modelId: idSchema, bayId: idSchema });
export const shipResponseSchema = z.object({ ship: shipSchema });
/** CR-009: start the next level of an upgrade on a ship at an HQ. */
export const startUpgradeRequestSchema = z.object({ shipId: idSchema, upgradeId: idSchema });
/** CR-015: buy fuel where the ship is; no amount fills the tank. */
export const refuelRequestSchema = z.object({
shipId: idSchema,
amountFu: z.number().positive().optional(),
});
/** CR-015: Auto top-up on landing, or Manual. */
export const refuelPolicyRequestSchema = z.object({
shipId: idSchema,
policy: z.enum(["auto", "manual"]),
});
/** CR-015: emergency fuel for a ship that can't get anywhere (decision 0.5.99). */
export const emergencyFuelRequestSchema = z.object({ shipId: idSchema });
export const leaseBayRequestSchema = z.object({ locationId: idSchema });
export const bayResponseSchema = z.object({ bay: baySchema });
/** Decision 0.5.22: hire at one of the player's bays. */
export const hirePilotRequestSchema = z.object({ locationId: idSchema });
export const assignPilotRequestSchema = z.object({ pilotId: idSchema, shipId: idSchema });
export const unassignPilotRequestSchema = z.object({ pilotId: idSchema });
/** CR-004: rest an idle pilot now, at any duty level. */
export const restPilotRequestSchema = z.object({ pilotId: idSchema });
export const spendSkillPointRequestSchema = z.object({ pilotId: idSchema, skillId: idSchema });
export const pilotResponseSchema = z.object({ pilot: pilotSchema });
export const acknowledgeSummariesRequestSchema = z
.object({
dispatchIds: z.array(idSchema),
/** Ships whose finished upgrade the player has now seen (CR-009). */
shipIds: z.array(idSchema).optional(),
})
.refine((r) => r.dispatchIds.length + (r.shipIds?.length ?? 0) > 0, {
message: "Acknowledge at least one summary or ship",
});
export const acknowledgeSummariesResponseSchema = z.object({
acknowledged: z.number().int().nonnegative(),
});
/** Pay the loan down by up to `amount` credits (decision 0.5.32). */
export const repayLoanRequestSchema = z.object({ amount: z.number().int().positive() });
export const claimGoalRequestSchema = z.object({ goalId: idSchema });
export const companyResponseSchema = z.object({ company: companySchema });
/**
* A company name (decision 0.5.75): trimmed, 3–32 characters of letters,
* digits, spaces and basic punctuation.
*/
export const companyNameSchema = z
.string()
.trim()
.min(3, "At least 3 characters")
.max(32, "At most 32 characters")
.regex(/^[A-Za-z0-9 .,'&!?-]+$/, "Letters, digits, spaces and . , ' & ! ? - only");
export const renameCompanyRequestSchema = z.object({ name: companyNameSchema });
/** Export save (decision 0.5.92): the whole save as one text code. */
export const exportSaveResponseSchema = z.object({ code: z.string().min(1) });
/** Import save: a pasted or opened export code (generous: big companies make long codes). */
export const importSaveRequestSchema = z.object({ code: z.string().trim().min(1).max(10_000_000) });
/** Developer tools, non-production only (CR-011). */
export const devAdvanceClockRequestSchema = z.object({
advanceMs: z
.number()
.int()
.positive()
.max(30 * 24 * 3_600_000),
});
export const devAdvanceClockResponseSchema = z.object({
offsetMs: z.number().int(),
realTime: timeSchema,
});
export const devAddCreditsRequestSchema = z.object({
amount: z.number().int().positive().max(10_000_000),
});
/** A pilot to the next level's XP, or out of duty and rest. */
export const devPilotRequestSchema = z.object({
pilotId: idSchema,
action: z.enum(["level-up", "clear-rest"]),
});
/** A ship's upgrades maxed or removed, its shop work finished, or moved while idle. */
export const devShipRequestSchema = z.discriminatedUnion("action", [
z.object({
shipId: idSchema,
action: z.enum(["max-upgrades", "reset-upgrades", "finish-shop"]),
}),
z.object({ shipId: idSchema, action: z.literal("move"), locationId: idSchema }),
]);