117 lines
4.7 KiB
TypeScript
117 lines
4.7 KiB
TypeScript
import * as PIXI from 'pixi.js';
|
|
import { Engine } from '../Bastion';
|
|
import { TerrainType, TowerDefinition } from '../Definitions';
|
|
import GameAssets from '../Assets';
|
|
import { Tower, TowerEvents } from './Tower';
|
|
import { Cell, GridEvents } from './Grid';
|
|
|
|
export enum TowerBehaviours {
|
|
BasicTowerBehaviour = 'BasicTowerBehaviour',
|
|
}
|
|
|
|
export default class TowerManager {
|
|
public isPlacingTower: boolean = false;
|
|
public canPlaceTowers: boolean = true;
|
|
public selectedTower: TowerDefinition | null = null;
|
|
private previewSprite: PIXI.Sprite = new PIXI.Sprite({
|
|
parent: Engine.GameMaster.currentScene.stage,
|
|
zIndex: 10,
|
|
width: 64,
|
|
height: 64,
|
|
alpha: 0.8,
|
|
});
|
|
private towers: Tower[] = [];
|
|
constructor() {
|
|
Engine.TowerManager = this;
|
|
Engine.GameScene.events.on(GridEvents.CellMouseOver, (cell: Cell) => {
|
|
if (this.isPlacingTower) {
|
|
let cantPlace = cell.checkIfCantPlace();
|
|
if (cantPlace) {
|
|
cell.rangePreview.clear();
|
|
cell.showRangePreview(true, this.selectedTower.stats.range);
|
|
this.previewSprite.tint = 0xff0000;
|
|
} else {
|
|
cell.showRangePreview(false, this.selectedTower.stats.range);
|
|
this.previewSprite.tint = 0xffffff;
|
|
}
|
|
this.previewSprite.x = cell.column * Engine.GridCellSize;
|
|
this.previewSprite.y = cell.row * Engine.GridCellSize;
|
|
this.previewSprite.texture = this.selectedTower.texture;
|
|
}
|
|
});
|
|
}
|
|
public ResetChooseTower() {
|
|
this.selectedTower = null;
|
|
this.isPlacingTower = false;
|
|
Engine.Grid.toggleGrid('hide');
|
|
}
|
|
public ToggleChoosingTowerLocation(towerName: string) {
|
|
if (!this.canPlaceTowers) return;
|
|
Engine.Grid.toggleGrid();
|
|
if (!this.isPlacingTower) {
|
|
GameAssets.Towers.forEach((item) => {
|
|
if (item.name == towerName) {
|
|
this.selectedTower = item;
|
|
console.log(this.selectedTower);
|
|
}
|
|
});
|
|
} else {
|
|
this.previewSprite.texture = null;
|
|
this.selectedTower = null;
|
|
}
|
|
this.isPlacingTower = !this.isPlacingTower;
|
|
}
|
|
public PlayerClickOnGrid(row, column) {
|
|
if (!this.canPlaceTowers) return;
|
|
if (this.isPlacingTower) {
|
|
if (!this.selectedTower) {
|
|
Engine.NotificationManager.Notify(
|
|
'TowerManager.selectedTower is null when trying to place tower.',
|
|
'danger'
|
|
);
|
|
throw console.warn('TowerManager.selectedTower is null when trying to place tower.');
|
|
}
|
|
this.PlaceTower(this.selectedTower, row, column, this.selectedTower.behaviour);
|
|
}
|
|
}
|
|
public GetTowerByRowAndCol(row, col) {
|
|
// i just want to say that this is really stupid, why do i need to define a type for a local
|
|
// variable i will temporarily use? TS is weird
|
|
let returnTower: Tower | null = null;
|
|
this.towers.forEach((tower) => {
|
|
if (tower.row == row && tower.column == col) returnTower = tower;
|
|
});
|
|
// console.log(returnTower, row, col);
|
|
return returnTower;
|
|
}
|
|
public PlaceTower(definition: TowerDefinition, row, column, behaviour: string, ignoreCost?) {
|
|
const sprite = this.selectedTower.texture;
|
|
if (!Engine.GameScene.MissionStats.hasEnoughGold(definition.stats.cost) && !ignoreCost)
|
|
return Engine.NotificationManager.Notify('Not enough gold.', 'warn');
|
|
if (
|
|
!this.GetTowerByRowAndCol(row, column) &&
|
|
Engine.Grid.getCellByRowAndCol(row, column).type != TerrainType.Path &&
|
|
Engine.Grid.getCellByRowAndCol(row, column).type != TerrainType.Restricted
|
|
) {
|
|
Engine.GameScene.MissionStats.spendGold(definition.stats.cost);
|
|
let tower = new Tower(row, column, sprite, definition, behaviour);
|
|
this.towers.push(tower);
|
|
this.ToggleChoosingTowerLocation('RESET');
|
|
this.selectedTower = null;
|
|
this.previewSprite.x = -100;
|
|
Engine.GameScene.events.emit(TowerEvents.TowerPlacedEvent, definition.name, row, column);
|
|
} else {
|
|
Engine.NotificationManager.Notify(
|
|
'Can not place tower on path or other tower, choose another spot.',
|
|
'warn'
|
|
);
|
|
console.warn('Can not place tower on occupied spot or path. Try again.');
|
|
}
|
|
}
|
|
public update(elapsedMS) {
|
|
this.towers.forEach((twr) => {
|
|
twr.update(elapsedMS);
|
|
});
|
|
}
|
|
}
|