input handlers
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
import { GdRoot } from "../data/GdRoot";
|
||||
import { EDirection } from "../util/EDirection";
|
||||
import { Hex } from "../util/Hex";
|
||||
import { PathFinding } from "../util/PathFinding";
|
||||
import { ECellType } from "./ECellType";
|
||||
import { SimCell } from "./SimCell";
|
||||
import { SimEnemy } from "./SimEnemy";
|
||||
import { SimProjectile } from "./SimProjectile";
|
||||
import { GdRoot } from '../data/GdRoot';
|
||||
import { EDirection } from '../util/EDirection';
|
||||
import { Hex } from '../util/Hex';
|
||||
import { PathFinding } from '../util/PathFinding';
|
||||
import { ECellType } from './ECellType';
|
||||
import { SimCell } from './SimCell';
|
||||
import { SimEnemy } from './SimEnemy';
|
||||
import { SimProjectile } from './SimProjectile';
|
||||
|
||||
export class SimLevel {
|
||||
paused: boolean = true;
|
||||
@@ -23,159 +23,156 @@ export class SimLevel {
|
||||
index: number = 0;
|
||||
radius: number = 0;
|
||||
|
||||
constructor(gdRoot: GdRoot, levelIdx: number) {
|
||||
const gdLevel = gdRoot.levels[levelIdx];
|
||||
this.index = levelIdx;
|
||||
this.currency = gdLevel.currency;
|
||||
this.enemiesLeftToSpawn = gdLevel.waves[0].amount;
|
||||
constructor(gdRoot: GdRoot, levelIdx: number) {
|
||||
const gdLevel = gdRoot.levels[levelIdx];
|
||||
this.index = levelIdx;
|
||||
this.currency = gdLevel.currency;
|
||||
this.enemiesLeftToSpawn = gdLevel.waves[0].amount;
|
||||
|
||||
this.radius = gdLevel.radius;
|
||||
this.stride = 2 * this.radius + 1;
|
||||
const h0 = new Hex(0, 0);
|
||||
for (let y = -this.radius; y <= this.radius; ++y) {
|
||||
for (let x = -this.radius; x <= this.radius; ++x) {
|
||||
const hex = new Hex(x, y);
|
||||
const distance = Hex.distance(hex, h0);
|
||||
const type = distance >= this.radius ? ECellType.Blocked : ECellType.Free;
|
||||
const cellIndex = this.getCellIndex(hex);
|
||||
this.cells[cellIndex] = new SimCell(hex, distance, type, cellIndex);
|
||||
}
|
||||
}
|
||||
this.radius = gdLevel.radius;
|
||||
this.stride = 2 * this.radius + 1;
|
||||
const h0 = new Hex(0, 0);
|
||||
for (let y = -this.radius; y <= this.radius; ++y) {
|
||||
for (let x = -this.radius; x <= this.radius; ++x) {
|
||||
const hex = new Hex(x, y);
|
||||
const distance = Hex.distance(hex, h0);
|
||||
const type = distance >= this.radius ? ECellType.Blocked : ECellType.Free;
|
||||
const cellIndex = this.getCellIndex(hex);
|
||||
this.cells[cellIndex] = new SimCell(hex, distance, type, cellIndex);
|
||||
}
|
||||
}
|
||||
|
||||
gdLevel.walls.forEach((wall: Hex) => {
|
||||
const cellIndex = this.getCellIndex(wall);
|
||||
this.cells[cellIndex].type = ECellType.Blocked;
|
||||
});
|
||||
gdLevel.walls.forEach((wall: Hex) => {
|
||||
const cellIndex = this.getCellIndex(wall);
|
||||
this.cells[cellIndex].type = ECellType.Blocked;
|
||||
});
|
||||
|
||||
gdLevel.enemySpawns.forEach((hex: Hex) => {
|
||||
const cellIndex = this.getCellIndex(hex);
|
||||
this.cells[cellIndex].type = ECellType.Entry;
|
||||
});
|
||||
gdLevel.enemySpawns.forEach((hex: Hex) => {
|
||||
const cellIndex = this.getCellIndex(hex);
|
||||
this.cells[cellIndex].type = ECellType.Entry;
|
||||
});
|
||||
|
||||
gdLevel.enemyTargets.forEach((hex: Hex) => {
|
||||
const cellIndex = this.getCellIndex(hex);
|
||||
this.cells[cellIndex].type = ECellType.Entry;
|
||||
});
|
||||
gdLevel.enemyTargets.forEach((hex: Hex) => {
|
||||
const cellIndex = this.getCellIndex(hex);
|
||||
this.cells[cellIndex].type = ECellType.Entry;
|
||||
});
|
||||
|
||||
this.cells.forEach((cell: SimCell) => {
|
||||
this.updateBlockedType(cell);
|
||||
});
|
||||
this.cells.forEach((cell: SimCell) => {
|
||||
this.updateBlockedType(cell);
|
||||
});
|
||||
|
||||
this.updatePaths(gdRoot);
|
||||
};
|
||||
this.updatePaths(gdRoot);
|
||||
}
|
||||
|
||||
public getCellIndex(hex: Hex) {
|
||||
const x = hex.col + this.radius;
|
||||
const y = hex.row + this.radius;
|
||||
if (x < 0 || x >= this.stride || y < 0 || y >= this.stride) {
|
||||
return -1;
|
||||
}
|
||||
return y * this.stride + x;
|
||||
}
|
||||
public getCellIndex(hex: Hex) {
|
||||
const x = hex.col + this.radius;
|
||||
const y = hex.row + this.radius;
|
||||
if (x < 0 || x >= this.stride || y < 0 || y >= this.stride) {
|
||||
return -1;
|
||||
}
|
||||
return y * this.stride + x;
|
||||
}
|
||||
|
||||
public getNeighbourCell(cell: SimCell, direction: EDirection) {
|
||||
const hex = cell.hex;
|
||||
const neighbourHex = Hex.neighbour(hex, direction);
|
||||
const neighbourIndex = this.getCellIndex(neighbourHex);
|
||||
return this.cells[neighbourIndex];
|
||||
}
|
||||
public getNeighbourCell(cell: SimCell, direction: EDirection) {
|
||||
const hex = cell.hex;
|
||||
const neighbourHex = Hex.neighbour(hex, direction);
|
||||
const neighbourIndex = this.getCellIndex(neighbourHex);
|
||||
return this.cells[neighbourIndex];
|
||||
}
|
||||
|
||||
public updateBlockedType(cell: SimCell) {
|
||||
if (cell.type == ECellType.Free) {
|
||||
cell.blockedType = -1;
|
||||
return;
|
||||
}
|
||||
public updateBlockedType(cell: SimCell) {
|
||||
if (cell.type == ECellType.Free) {
|
||||
cell.blockedType = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (cell.type == ECellType.Entry && cell.blockedType != -1) {
|
||||
return;
|
||||
}
|
||||
if (cell.type == ECellType.Entry && cell.blockedType != -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
let blockedType = 0;
|
||||
for (let direction = 0; direction < 6; ++direction) {
|
||||
const neighbourCell = this.getNeighbourCell(cell, direction);
|
||||
if (!!neighbourCell && neighbourCell.type == ECellType.Free) {
|
||||
blockedType |= 1 << direction;
|
||||
}
|
||||
}
|
||||
let blockedType = 0;
|
||||
for (let direction = 0; direction < 6; ++direction) {
|
||||
const neighbourCell = this.getNeighbourCell(cell, direction);
|
||||
if (!!neighbourCell && neighbourCell.type == ECellType.Free) {
|
||||
blockedType |= 1 << direction;
|
||||
}
|
||||
}
|
||||
|
||||
cell.blockedType = blockedType;
|
||||
}
|
||||
cell.blockedType = blockedType;
|
||||
}
|
||||
|
||||
public reservePaths(gdRoot: GdRoot, hexToBlock: Hex | null): boolean {
|
||||
try {
|
||||
if (!!hexToBlock) {
|
||||
const reservedCell = this.cells[this.getCellIndex(hexToBlock)];
|
||||
if (reservedCell.type != ECellType.Free || !!reservedCell.tower)
|
||||
return false;
|
||||
public reservePaths(gdRoot: GdRoot, hexToBlock: Hex | null): boolean {
|
||||
try {
|
||||
if (!!hexToBlock) {
|
||||
const reservedCell = this.cells[this.getCellIndex(hexToBlock)];
|
||||
if (reservedCell.type != ECellType.Free || !!reservedCell.tower) return false;
|
||||
|
||||
reservedCell.type = ECellType.Reserved;
|
||||
}
|
||||
reservedCell.type = ECellType.Reserved;
|
||||
}
|
||||
|
||||
return this.updatePaths(gdRoot);
|
||||
}
|
||||
finally {
|
||||
if (!!hexToBlock) {
|
||||
const reservedCell = this.cells[this.getCellIndex(hexToBlock)];
|
||||
if (reservedCell.type == ECellType.Reserved)
|
||||
reservedCell.type = ECellType.Free
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.updatePaths(gdRoot);
|
||||
} finally {
|
||||
if (!!hexToBlock) {
|
||||
const reservedCell = this.cells[this.getCellIndex(hexToBlock)];
|
||||
if (reservedCell.type == ECellType.Reserved) reservedCell.type = ECellType.Free;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public updatePaths(gdRoot: GdRoot): boolean {
|
||||
const newRoutePaths: number[][] = [];
|
||||
const newEnemyPaths: number[][] = [];
|
||||
const gdLevel = gdRoot.levels[this.index];
|
||||
let invalid = false;
|
||||
public updatePaths(gdRoot: GdRoot): boolean {
|
||||
const newRoutePaths: number[][] = [];
|
||||
const newEnemyPaths: number[][] = [];
|
||||
const gdLevel = gdRoot.levels[this.index];
|
||||
let invalid = false;
|
||||
|
||||
for (const routeIdx in gdLevel.enemyRoutes) {
|
||||
const route = gdLevel.enemyRoutes[routeIdx];
|
||||
const enemySpawnHex = gdLevel.enemySpawns[route[0]];
|
||||
const enemySpawnCell = this.cells[this.getCellIndex(enemySpawnHex)];
|
||||
const enemyTargetHex = gdLevel.enemyTargets[route[1]];
|
||||
const enemyTargetCell = this.cells[this.getCellIndex(enemyTargetHex)];
|
||||
const path = PathFinding.bfs(this, enemySpawnCell.index, enemyTargetCell.index);
|
||||
if (path == null) {
|
||||
invalid = true;
|
||||
break;
|
||||
}
|
||||
newRoutePaths[routeIdx] = path;
|
||||
}
|
||||
for (const routeIdx in gdLevel.enemyRoutes) {
|
||||
const route = gdLevel.enemyRoutes[routeIdx];
|
||||
const enemySpawnHex = gdLevel.enemySpawns[route[0]];
|
||||
const enemySpawnCell = this.cells[this.getCellIndex(enemySpawnHex)];
|
||||
const enemyTargetHex = gdLevel.enemyTargets[route[1]];
|
||||
const enemyTargetCell = this.cells[this.getCellIndex(enemyTargetHex)];
|
||||
const path = PathFinding.bfs(this, enemySpawnCell.index, enemyTargetCell.index);
|
||||
if (path == null) {
|
||||
invalid = true;
|
||||
break;
|
||||
}
|
||||
newRoutePaths[routeIdx] = path;
|
||||
}
|
||||
|
||||
if (invalid) {
|
||||
return false;
|
||||
}
|
||||
if (invalid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let idx in this.enemies) {
|
||||
const simEnemy = this.enemies[idx];
|
||||
const hex = Hex.fromWorld(simEnemy.position);
|
||||
const startIndex = this.getCellIndex(hex);
|
||||
const endIndex = this.getCellIndex(simEnemy.endHex);
|
||||
const path = PathFinding.bfs(this, startIndex, endIndex);
|
||||
if (path == null) {
|
||||
invalid = true;
|
||||
break;
|
||||
}
|
||||
newEnemyPaths[idx] = path;
|
||||
}
|
||||
for (let idx in this.enemies) {
|
||||
const simEnemy = this.enemies[idx];
|
||||
const hex = Hex.fromWorld(simEnemy.position);
|
||||
const startIndex = this.getCellIndex(hex);
|
||||
const endIndex = this.getCellIndex(simEnemy.endHex);
|
||||
const path = PathFinding.bfs(this, startIndex, endIndex);
|
||||
if (path == null) {
|
||||
invalid = true;
|
||||
break;
|
||||
}
|
||||
newEnemyPaths[idx] = path;
|
||||
}
|
||||
|
||||
if (invalid) {
|
||||
return false;
|
||||
}
|
||||
if (invalid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const routeIdx in gdLevel.enemyRoutes) {
|
||||
const route = gdLevel.enemyRoutes[routeIdx];
|
||||
const enemySpawnHex = gdLevel.enemySpawns[route[0]];
|
||||
const enemySpawnCell = this.cells[this.getCellIndex(enemySpawnHex)];
|
||||
enemySpawnCell.pathsToTarget[routeIdx] = newRoutePaths[routeIdx];
|
||||
}
|
||||
for (const routeIdx in gdLevel.enemyRoutes) {
|
||||
const route = gdLevel.enemyRoutes[routeIdx];
|
||||
const enemySpawnHex = gdLevel.enemySpawns[route[0]];
|
||||
const enemySpawnCell = this.cells[this.getCellIndex(enemySpawnHex)];
|
||||
enemySpawnCell.pathsToTarget[routeIdx] = newRoutePaths[routeIdx];
|
||||
}
|
||||
|
||||
this.enemies.forEach((simEnemy: SimEnemy, idx: number) => {
|
||||
simEnemy.path = newEnemyPaths[idx];
|
||||
simEnemy.currentPathIndex = 0;
|
||||
simEnemy.onPathUpdated(this);
|
||||
});
|
||||
this.enemies.forEach((simEnemy: SimEnemy, idx: number) => {
|
||||
simEnemy.path = newEnemyPaths[idx];
|
||||
simEnemy.currentPathIndex = 0;
|
||||
simEnemy.onPathUpdated(this);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user