import type { Action } from "./contracts/action"; import type { Entity } from "./contracts/entity"; import type { ValidationResult } from "./contracts/validation"; import type { WorldState } from "./contracts/world"; function getEntity(worldState: WorldState, entityId: string | undefined): Entity | undefined { if (!entityId) { return undefined; } return worldState.entities[entityId]; } function hasKey(actor: Entity, requiredKeyId: string): boolean { return actor.attributes[`has_${requiredKeyId}`] === true; } export function validateActions(actions: Action[], worldState: WorldState): ValidationResult[] { return actions.map((action, actionIndex): ValidationResult => { const actor = getEntity(worldState, action.actorId); if (!actor) { return { actionIndex, success: false, reason: "actor_not_found", message: `Actor '${action.actorId}' does not exist.`, }; } switch (action.type) { case "inspect": return { actionIndex, success: true }; case "take": { const target = getEntity(worldState, action.targetId); if (!target) { return { actionIndex, success: false, reason: "target_not_found", message: `Target '${action.targetId ?? "(missing)"}' does not exist.`, }; } const actorLocation = String(actor.attributes.location ?? ""); const targetLocation = String(target.attributes.location ?? ""); if (actorLocation !== targetLocation) { return { actionIndex, success: false, reason: "not_in_same_location", message: `Target '${target.id}' is not in the same location as '${actor.id}'.`, }; } if (target.attributes.takeable !== true) { return { actionIndex, success: false, reason: "not_takeable", message: `Target '${target.id}' cannot be taken.`, }; } return { actionIndex, success: true }; } case "open": { const target = getEntity(worldState, action.targetId); if (!target) { return { actionIndex, success: false, reason: "target_not_found", message: `Target '${action.targetId ?? "(missing)"}' does not exist.`, }; } if (target.attributes.openable !== true) { return { actionIndex, success: false, reason: "not_openable", message: `Target '${target.id}' is not openable.`, }; } if (target.attributes.locked === true) { const requiredKey = String(target.attributes.requiredKey ?? "key_1"); if (!hasKey(actor, requiredKey)) { return { actionIndex, success: false, reason: "locked_requires_key", message: `Target '${target.id}' is locked and requires '${requiredKey}'.`, }; } } return { actionIndex, success: true }; } case "move": { const target = getEntity(worldState, action.targetId); if (!target || target.type !== "room") { return { actionIndex, success: false, reason: "target_not_found", message: `Move target '${action.targetId ?? "(missing)"}' is not a valid room.`, }; } return { actionIndex, success: true }; } default: return { actionIndex, success: false, reason: "unknown_action", message: `Action type '${action.type}' is not supported.`, }; } }); }