Files
pgames-manager/frontend/src/player/tomie-gameplay.ts
T

42 lines
2.6 KiB
TypeScript

import type { NaniRuntime } from "./nani-runtime";
export interface BoardCell { index: number; code: number; area: string; icon: string; title: string; detail: string }
export class TomieGameplay {
constructor(private runtime: NaniRuntime, private routes: Record<string, { script: string; label: string }>) {}
cells(): BoardCell[] {
return String(this.runtime.variables.savedBlock ?? "").split("&").filter(Boolean).flatMap((value) => {
const parts = value.split("@");
return parts.length < 6 ? [] : [{ index: Number(parts[0]), code: Number(parts[1]), area: parts[2], icon: parts[3], title: parts[4], detail: parts[5] }];
});
}
roll(type = 0): { ok: boolean; message?: string; roll?: number; destination?: number } {
const vm = this.runtime, values = vm.variables;
if (vm.waiting !== "board") return { ok: false, message: "Сначала завершите текущее действие." };
const cost = type === 2 ? 10 : [3, 4, 5].includes(type) ? 5 : 0;
if (Number(values.iWillpower ?? 0) < cost) return { ok: false, message: "Недостаточно воли для этого кубика." };
if (type > 10 && (type > 16 || Number(values.iJoker ?? 0) < 1)) return { ok: false, message: "Нужна одна карта Joker." };
const rng = vm.evaluator;
let number: number;
if (type === 0 || type === 1) {
number = rng.integer(1, 6);
if (type === 1 && rng.random() >= 0.6) number = Math.min(6, Math.max(1, Math.trunc(Number(values._godot_dice_slider ?? 0) * 3) + 1));
} else if (type === 2) number = rng.integer(1, 3);
else if (type === 3) number = rng.integer(4, 6);
else if (type === 4) number = rng.integer(1, 3) * 2 - 1;
else if (type === 5) number = rng.integer(1, 3) * 2;
else if (type > 10) number = type - 10;
else return { ok: false, message: "Этот тип кубика не подключён." };
const cells = this.cells(), destination = Math.min(Number(values.currentPosition ?? 0) + number, cells.length - 1);
const cell = cells[destination], target = cell && this.routes[String(cell.code)];
if (!cell || !target || !vm.content.scripts[target.script]) return { ok: false, message: "Неизвестный тип клетки. Позиция и ресурсы сохранены." };
values.mDiceResult = number; values.currentPosition = destination; values.thisBlockNumber = cell.code;
values.iWillpower = Number(values.iWillpower ?? 0) - cost;
if (type > 10) values.iJoker = Number(values.iJoker ?? 0) - 1;
values.isAppScreen = false;
vm.runExternal(target.script, target.label);
return { ok: true, roll: number, destination };
}
}