Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 25x 25x 25x 25x 25x 25x 25x 25x 25x 25x 25x 25x 1x 1x 25x 25x 6x 6x 6x 6x 1x 1x 1x 1x 1x 1x 6x 6x 25x 25x 13x 13x 13x 13x 13x 13x 11x 11x 11x 11x 11x 10x 10x 7x 7x 3x 3x 3x 1x 3x 1x 1x 3x 10x 11x 13x 13x 13x 25x 25x 11x 11x 11x 11x 11x 11x 11x 11x 11x 25x 25x 7x 7x 7x 7x 7x 5x 5x 5x 7x 5x 5x 5x 7x 25x | import { GameMap, PositionInterface } from "../../maps/index";
import { TileInterface } from "../../tiles/index";
import { ComponentName, isPositionComponent } from "../components";
import { isActor, Entity, isEntity } from "../entities";
import { World } from "../world";
import { DamageSystem } from "./damage";
import { System } from "./system";
export interface MoveInterface {
canMove: boolean;
newPosition: PositionInterface | null;
}
export class MovementSystem extends System {
protected position: PositionInterface;
protected targets: Map<string, Entity>;
public constructor(entities: Map<string, Entity>, position: PositionInterface, targets: Map<string, Entity>) {
super(entities, [ComponentName.MOVEABLE, ComponentName.POSITION]);
this.position = position;
this.targets = this.filterEntities(targets, [ComponentName.POSITION]);
}
public getPosition(): PositionInterface {
return this.position;
}
public run(world: World): void {
return this.entities.forEach((entity): void => {
const move = this.canMove(world);
if (move.canMove) {
const positionComponent = entity.getComponent(ComponentName.POSITION);
if (isPositionComponent(positionComponent)) {
positionComponent.setPosition(this.position);
}
}
});
}
public canMove(world: World): MoveInterface {
const move: MoveInterface = {
canMove: false,
newPosition: this.position,
};
if (this.position != undefined && world != undefined && world.getMap() !== null) {
const map: GameMap = world.getMap();
const tile: TileInterface = map.getTile(this.position);
const targets: Entity[] = this.filterTargetsAtPosition();
if (tile !== null) {
// if there is a target, attack
if (targets.length > 0) {
this.attack(targets[0], world);
} else {
// else move
// eslint-disable-next-line no-lonely-if
if (tile.isWalkable) {
move.canMove = true;
} else if (tile.isDiggable) {
map.dig(this.position);
}
}
}
}
return move;
}
private filterTargetsAtPosition(): Entity[] {
// eslint-disable-next-line compat/compat
return Array.from(this.targets.values()).filter((entity) => {
const entityPosition = entity.getComponent(ComponentName.POSITION);
return isPositionComponent(entityPosition)
? this.position.x === entityPosition.getPosition().x &&
this.position.y === entityPosition.getPosition().y
: false;
});
}
private attack(target: Entity, world: World): void {
// eslint-disable-next-line compat/compat
const attacker = Array.from(this.entities.values())[0];
if (
isActor(attacker) &&
isEntity(target) &&
attacker.hasComponent(ComponentName.ATTACK) &&
target.hasComponent(ComponentName.DAMAGEABLE)
) {
const damageSystem = new DamageSystem(attacker, target);
damageSystem.run(world);
}
}
}
|