/src/map.ts
import gs from './gamestate';
import { ID, generateID } from './id';
import { GameObject, GameObjectType } from './object';
import { Cell, CellProperties } from './cell';
import Storable from './storable';
/* GameMap
The Map tracks positions of all the objects on the map, including the player.
*/
interface GameMapProperties {
id: ID
width: number
height: number
cells: CellProperties[]
}
export default class GameMap extends Storable {
id: ID
width: number
height: number
cells: Cell[][]
playerLocation: [number, number]
saveProperties = ['id', 'width', 'height']
constructor() {
super();
this.id = generateID();
this.width = this.height = 1;
this.build();
}
build() {
this.cells = this.cells || [];
for (let j = 0; j < this.height; j++) {
this.cells[j] = this.cells[j] || [];
for (let i = 0; i < this.width; i++) {
if (this.cells[j][i])
continue;
this.cells[j][i] = new Cell(i, j);
}
}
if (!this.player) {
this.playerLocation = [0, 0];
}
}
movePlayer(x: number, y: number) {
const [ oldX, oldY ] = this.playerLocation;
let rebuild = false;
if (x + 1 > this.width) {
this.width = x + 1;
rebuild = true;
} else if (x < 0) {
x = 0;
}
if (y + 1 > this.height) {
this.height = y + 1;
rebuild = true;
} else if (y < 0) {
y = 0;
}
if (x == oldX && y == oldY)
return;
if (rebuild)
this.build();
this.playerLocation = [x, y];
gs.mapView.updateAll();
gs.mapView.updateCoords(x, y);
}
movePlayerRel(dx: number, dy: number) {
const [ x, y ] = this.playerLocation;
this.movePlayer(x + dx, y + dy);
}
getPlayerPosition(): [number, number] {
const [ x, y ] = this.playerLocation;
return [ x, y ];
}
getCurrentCell(): Cell {
const [ x, y ] = this.playerLocation;
return this.cells[y][x];
}
toggleNavigable() {
const [ x, y ] = this.playerLocation;
this.cells[y][x].navigable = !this.cells[y][x].navigable;
gs.mapView.update(x, y);
}
editDescription() {
gs.cellEditor.onClose = (cell: Cell) => {
gs.mapView.update(cell.x, cell.y);
gs.enterCell();
};
gs.cellEditor.open(this.getCurrentCell());
}
store() {
const obj = <GameMapProperties>super.store();
const cells: CellProperties[] = [];
for (let j = 0; j < this.height; j++) {
for (let i = 0; i < this.width; i++) {
if (this.cells[j][i].navigable) {
cells.push(this.cells[j][i].store());
}
}
}
obj.cells = cells;
return obj;
}
load(obj: GameMapProperties) {
super.load(obj);
this.build();
for (let c of obj.cells) {
const { x, y } = c;
this.cells[y][x].load(c);
const p = Array.from(this.cells[y][x].objects).find(
([id, obj]) => obj.type == GameObjectType.Player
);
}
gs.mapView.updateAll();
}
}