feat(slay-the-spire-like): add map navigation logic
Implement `canMoveTo` and `moveToNode` for navigating the point crawl map, and add `PointCrawlMapNavigator` type. Also reformat map module files to use double quotes.
This commit is contained in:
parent
88d31430a6
commit
423cc7c841
|
|
@ -1,5 +1,18 @@
|
|||
export { MapNodeType, MapLayerType } from './types';
|
||||
export type { MapNode, MapLayer, PointCrawlMap, MapGenerationConfig } from './types';
|
||||
export { MapNodeType, MapLayerType } from "./types";
|
||||
export type {
|
||||
MapNode,
|
||||
MapLayer,
|
||||
PointCrawlMap,
|
||||
MapGenerationConfig,
|
||||
} from "./types";
|
||||
|
||||
export { generatePointCrawlMap } from './generator';
|
||||
export { getNode, getChildren, getParents, hasPath, findAllPaths } from './generator';
|
||||
export { generatePointCrawlMap } from "./generator";
|
||||
export {
|
||||
getNode,
|
||||
getChildren,
|
||||
getParents,
|
||||
hasPath,
|
||||
findAllPaths,
|
||||
} from "./generator";
|
||||
|
||||
export { canMoveTo, moveToNode } from "./navigation";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
import { getNode } from "./generator";
|
||||
import { PointCrawlMap, PointCrawlMapNavigator } from "./types";
|
||||
|
||||
export function canMoveTo(
|
||||
navigator: PointCrawlMapNavigator,
|
||||
map: PointCrawlMap,
|
||||
targetNodeId: string,
|
||||
): boolean {
|
||||
const currentNode = getNode(map, navigator.currentNodeId);
|
||||
if (!currentNode) return false;
|
||||
|
||||
return currentNode.childIds.includes(targetNodeId);
|
||||
}
|
||||
|
||||
export function moveToNode(
|
||||
navigator: PointCrawlMapNavigator,
|
||||
map: PointCrawlMap,
|
||||
targetNodeId: string,
|
||||
): boolean {
|
||||
if (!canMoveTo(navigator, map, targetNodeId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const targetNode = getNode(map, targetNodeId);
|
||||
if (!targetNode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update current position
|
||||
navigator.currentNodeId = targetNodeId;
|
||||
navigator.visitedNodes.add(targetNodeId);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1,83 +1,88 @@
|
|||
import {EncounterData} from "@/samples/slay-the-spire-like/system/types";
|
||||
import { EncounterData } from "@/samples/slay-the-spire-like/system/types";
|
||||
|
||||
/**
|
||||
* Types of nodes that can appear on the point crawl map.
|
||||
*/
|
||||
export enum MapNodeType {
|
||||
Start = 'start',
|
||||
End = 'end',
|
||||
Minion = 'minion',
|
||||
Elite = 'elite',
|
||||
Event = 'event',
|
||||
Camp = 'camp',
|
||||
Shop = 'shop',
|
||||
Curio = 'curio',
|
||||
Start = "start",
|
||||
End = "end",
|
||||
Minion = "minion",
|
||||
Elite = "elite",
|
||||
Event = "event",
|
||||
Camp = "camp",
|
||||
Shop = "shop",
|
||||
Curio = "curio",
|
||||
}
|
||||
|
||||
/**
|
||||
* Semantic type of a layer.
|
||||
*/
|
||||
export enum MapLayerType {
|
||||
Wild = 'wild',
|
||||
Settlement = 'settlement',
|
||||
Wild = "wild",
|
||||
Settlement = "settlement",
|
||||
}
|
||||
|
||||
/**
|
||||
* A single node on the map.
|
||||
*/
|
||||
export interface MapNode {
|
||||
/** Unique identifier */
|
||||
id: string;
|
||||
/** Which layer this node belongs to */
|
||||
layerIndex: number;
|
||||
/** Semantic type of the node */
|
||||
type: MapNodeType;
|
||||
/** IDs of nodes in the next layer this node connects to */
|
||||
childIds: string[];
|
||||
/** Encounter data assigned to this node (from encounter CSV) */
|
||||
encounter?: EncounterData;
|
||||
/** Unique identifier */
|
||||
id: string;
|
||||
/** Which layer this node belongs to */
|
||||
layerIndex: number;
|
||||
/** Semantic type of the node */
|
||||
type: MapNodeType;
|
||||
/** IDs of nodes in the next layer this node connects to */
|
||||
childIds: string[];
|
||||
/** Encounter data assigned to this node (from encounter CSV) */
|
||||
encounter?: EncounterData;
|
||||
}
|
||||
|
||||
/**
|
||||
* A horizontal layer of nodes at the same progression stage.
|
||||
*/
|
||||
export interface MapLayer {
|
||||
/** Layer index (0 = start, last = end) */
|
||||
index: number;
|
||||
/** Ordered IDs of nodes in this layer */
|
||||
nodeIds: string[];
|
||||
/** Semantic type of the layer */
|
||||
layerType: MapLayerType | 'start' | 'end';
|
||||
/** Direct references to nodes in this layer (for performance) */
|
||||
nodes: MapNode[];
|
||||
/** Layer index (0 = start, last = end) */
|
||||
index: number;
|
||||
/** Ordered IDs of nodes in this layer */
|
||||
nodeIds: string[];
|
||||
/** Semantic type of the layer */
|
||||
layerType: MapLayerType | "start" | "end";
|
||||
/** Direct references to nodes in this layer (for performance) */
|
||||
nodes: MapNode[];
|
||||
}
|
||||
|
||||
/**
|
||||
* A fully generated point crawl map.
|
||||
*/
|
||||
export interface PointCrawlMap {
|
||||
/** Layers from start to end */
|
||||
layers: MapLayer[];
|
||||
/** All nodes keyed by ID */
|
||||
nodes: Map<string, MapNode>;
|
||||
/** Reverse index: nodeId → parent node IDs (for fast getParent lookup) */
|
||||
parentIndex?: Map<string, string[]>;
|
||||
/** Layers from start to end */
|
||||
layers: MapLayer[];
|
||||
/** All nodes keyed by ID */
|
||||
nodes: Map<string, MapNode>;
|
||||
/** Reverse index: nodeId → parent node IDs (for fast getParent lookup) */
|
||||
parentIndex?: Map<string, string[]>;
|
||||
}
|
||||
|
||||
export interface PointCrawlMapNavigator {
|
||||
currentNodeId: string;
|
||||
visitedNodes: Set<string>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration for map generation.
|
||||
*/
|
||||
export interface MapGenerationConfig {
|
||||
/** Total number of layers (including start and end) */
|
||||
totalLayers: number;
|
||||
/** Number of nodes in each wild layer */
|
||||
wildLayerNodeCount: number;
|
||||
/** Number of nodes in each settlement layer */
|
||||
settlementLayerNodeCount: number;
|
||||
/** Probability weights for wild node types (should sum to 100) */
|
||||
wildNodeTypeWeights: {
|
||||
[MapNodeType.Minion]: number;
|
||||
[MapNodeType.Elite]: number;
|
||||
[MapNodeType.Event]: number;
|
||||
};
|
||||
/** Total number of layers (including start and end) */
|
||||
totalLayers: number;
|
||||
/** Number of nodes in each wild layer */
|
||||
wildLayerNodeCount: number;
|
||||
/** Number of nodes in each settlement layer */
|
||||
settlementLayerNodeCount: number;
|
||||
/** Probability weights for wild node types (should sum to 100) */
|
||||
wildNodeTypeWeights: {
|
||||
[MapNodeType.Minion]: number;
|
||||
[MapNodeType.Elite]: number;
|
||||
[MapNodeType.Event]: number;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue