You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
AdLike2048/assets/mx/module/merge/board/MapTileBoard.ts

141 lines
4.5 KiB

3 weeks ago
import { MapCellKind, type MapTileRecord } from '../types/MergeTypes';
export interface MapCellSnapshot {
kind: MapCellKind;
/** 地图编辑时即为可放置且初始无字块 */
builtinPut: boolean;
/** 编辑器标记:该可走格是否允许放置 type3 扩展格子 */
canPutGrid: boolean;
/** 本轮备战 type3 扩展格:仅改格状态,不挂字块节点 */
prepType3?: boolean;
/** type3 落子时刻(Date.now),用于限时可拖 */
prepType3PlacedAtMs?: number;
}
/** 地图字块棋盘(纯数据,格索引 = MapGrid.Index) */
export class MapTileBoard {
private _cells = new Map<number, MapCellSnapshot>();
private _tiles = new Map<number, MapTileRecord>();
initCell(gridIndex: number, snapshot: MapCellSnapshot): void {
this._cells.set(gridIndex, { ...snapshot });
}
getCellKind(gridIndex: number): MapCellKind | null {
return this._cells.get(gridIndex)?.kind ?? null;
}
isBuiltinPut(gridIndex: number): boolean {
return this._cells.get(gridIndex)?.builtinPut ?? false;
}
isPrepType3(gridIndex: number): boolean {
return this._cells.get(gridIndex)?.prepType3 ?? false;
}
/** type3 落子时刻;非 prepType3 时为 null */
getPrepType3PlacedAtMs(gridIndex: number): number | null {
const cell = this._cells.get(gridIndex);
if (!cell?.prepType3) return null;
return cell.prepType3PlacedAtMs ?? null;
}
canPutGrid(gridIndex: number): boolean {
return this._cells.get(gridIndex)?.canPutGrid ?? false;
}
setPrepType3(gridIndex: number, value: boolean): void {
const cell = this._cells.get(gridIndex);
if (!cell) return;
cell.prepType3 = value;
if (value) {
cell.prepType3PlacedAtMs = Date.now();
} else {
cell.prepType3PlacedAtMs = undefined;
}
}
hasTile(gridIndex: number): boolean {
return this._tiles.has(gridIndex);
}
getTile(gridIndex: number): MapTileRecord | null {
return this._tiles.get(gridIndex) ?? null;
}
setCellKind(gridIndex: number, kind: MapCellKind): void {
const cell = this._cells.get(gridIndex);
if (!cell) return;
cell.kind = kind;
}
/** 铲等效果:格变为可放置(与原生 Put 格一致) */
markCellAsPut(gridIndex: number): void {
const cell = this._cells.get(gridIndex);
if (!cell) return;
cell.kind = MapCellKind.Put;
cell.builtinPut = true;
}
/** 蟠桃树落到空 Put:格变为可开挖、不可放置 */
markCellAsDig(gridIndex: number): void {
const cell = this._cells.get(gridIndex);
if (!cell) return;
cell.kind = MapCellKind.Dig;
cell.builtinPut = false;
}
placeTile(gridIndex: number, tile: MapTileRecord): void {
this._tiles.set(gridIndex, { ...tile });
}
removeTile(gridIndex: number): MapTileRecord | null {
const t = this._tiles.get(gridIndex) ?? null;
this._tiles.delete(gridIndex);
return t;
}
/** gridIndex → weapon2Id(供组合扫描;不含 type3 格状态) */
getWeapon2Layout(): Map<number, number> {
const layout = new Map<number, number>();
this._tiles.forEach((tile, idx) => layout.set(idx, tile.weapon2Id));
return layout;
}
forEachTile(fn: (gridIndex: number, tile: MapTileRecord) => void): void {
this._tiles.forEach((tile, idx) => fn(idx, { ...tile }));
}
get gridIndices(): number[] {
const out: number[] = [];
this._cells.forEach((_cell, idx) => out.push(idx));
return out;
}
exportCell(gridIndex: number): MapCellSnapshot | null {
const cell = this._cells.get(gridIndex);
return cell ? { ...cell } : null;
}
clearTiles(): void {
this._tiles.clear();
}
restoreBoard(
cells: ReadonlyArray<{ gridIndex: number; cell: MapCellSnapshot }>,
tiles: ReadonlyArray<{ gridIndex: number; tile: MapTileRecord }>,
): void {
for (const { gridIndex, cell } of cells) {
this._cells.set(gridIndex, { ...cell });
}
this._tiles.clear();
for (const { gridIndex, tile } of tiles) {
this._tiles.set(gridIndex, { ...tile });
}
}
getTileWeapon2IdsByIndices(indices: number[]): number[] {
return indices.map((i) => this._tiles.get(i)?.weapon2Id).filter((id): id is number => id != null);
}
}