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 | 42x 42x 42x 42x 42x 13x 13x 13x 1x 2x 2x 2x 1x 1x 1x 9x 9x 7x 7x 7x 7x 6x 3x 3x 1x 2x 1x 9x 7x 7x 7x 3x 3x 1x 1x | 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 (null != this.position && null != world && null !== world.getMap()) {
const map: GameMap = world.getMap();
const tile: TileInterface = map.getTile(this.position);
const targets: Entity[] = this.filterTargetsAtPosition();
if (null !== tile) {
// if there is a target, attack
if (0 !== targets.length) {
this.attack(targets[0], world);
} else {
// else move
if (tile.isWalkable) {
move.canMove = true;
} else if (tile.isDiggable) {
map.dig(this.position);
}
}
}
}
return move;
}
private filterTargetsAtPosition(): Entity[] {
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 {
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);
}
}
}
|