refactor: update progress

This commit is contained in:
hypercross 2026-04-17 12:23:10 +08:00
parent c11bceeb44
commit 0f04af2c6e
2 changed files with 8 additions and 31 deletions

View File

@ -1,13 +1,11 @@
import { Mulberry32RNG, type RNG } from '@/utils/rng';
import { generatePointCrawlMap, getNode } from '../map/generator';
import type { MapNode } from '../map/types';
import { getNode } from '../map/generator';
import type {MapNode, PointCrawlMap} from '../map/types';
import { placeItem, validatePlacement, createGridInventory, removeItem as gridRemoveItem } from '../grid-inventory/transform';
import type { GameItem, GameItemMeta, RunMutationResult, RunState } from './types';
import type { GridInventory } from '../grid-inventory/types';
import { IDENTITY_TRANSFORM, type Transform2D } from '../utils/shape-collision';
import { parseShapeString, type ParsedShape } from '../utils/parse-shape';
import type { HeroItemFighter1 } from '../data/heroItemFighter1.csv';
import { heroItemFighter1Data } from '../data';
import {ItemData} from "@/samples/slay-the-spire-like/system/types";
// Re-export types
export type {
@ -28,21 +26,13 @@ const INVENTORY_HEIGHT = 4;
const DEFAULT_MAX_HP = 50;
const DEFAULT_GOLD = 50;
/** Starter items to give the player at the beginning of a run. */
const STARTER_ITEM_NAMES = ['治疗药剂', '绷带', '水袋', '短刀', '剑'];
// -- Run creation --
/**
* Creates a new run state with a generated map, player stats, and starter inventory.
*
* @param seed RNG seed for reproducibility. If omitted, uses current timestamp.
* @param rng Optional RNG instance for controlled randomness (overrides seed).
*/
export function createRunState(seed?: number, rng?: RNG): RunState {
const actualSeed = seed ?? new Mulberry32RNG().nextInt(2 ** 31);
const map = generatePointCrawlMap(actualSeed);
export function createRunState(map: PointCrawlMap, starterItems: ItemData[]): RunState {
// Find the start node
const startNode = map.layers[0].nodes[0];
@ -51,10 +41,7 @@ export function createRunState(seed?: number, rng?: RNG): RunState {
const idCounter = { value: 0 };
// Place starter items
for (const itemName of STARTER_ITEM_NAMES) {
const itemData = findItemByName(itemName);
if (!itemData) continue;
for (const itemData of starterItems) {
const shape = parseShapeString(itemData.shape);
const itemInstance = tryPlaceItemInInventory(inventory, itemData, shape, idCounter);
if (!itemInstance) {
@ -63,7 +50,6 @@ export function createRunState(seed?: number, rng?: RNG): RunState {
}
return {
seed: actualSeed,
map,
player: {
maxHp: DEFAULT_MAX_HP,
@ -215,9 +201,9 @@ export function spendGold(runState: RunState, amount: number): RunMutationResult
*
* @returns The placed item instance, or undefined if no valid position exists.
*/
export function addItemFromCsv(
export function addItem(
runState: RunState,
itemData: HeroItemFighter1
itemData: ItemData
): GameItem | undefined {
const shape = parseShapeString(itemData.shape);
return tryPlaceItemInInventory(runState.inventory, itemData, shape, runState._idCounter);
@ -277,13 +263,6 @@ export function isAtEndNode(runState: RunState): boolean {
// -- Internal helpers --
/**
* Finds a hero item by name from the CSV data.
*/
function findItemByName(name: string): HeroItemFighter1 | undefined {
return heroItemFighter1Data.find(item => item.name === name);
}
/**
* Generates a unique item instance ID.
*/
@ -298,7 +277,7 @@ function generateInstanceId(counter: { value: number }): string {
*/
function tryPlaceItemInInventory(
inventory: GridInventory<GameItemMeta>,
itemData: HeroItemFighter1,
itemData: ItemData,
shape: ParsedShape,
idCounter: { value: number }
): GameItem | undefined {

View File

@ -65,8 +65,6 @@ export interface PlayerState {
* Designed to be used inside `MutableSignal.produce()` callbacks.
*/
export interface RunState {
/** RNG seed used for map generation */
seed: number;
/** Generated point crawl map */
map: PointCrawlMap;
/** Player HP and gold */