All files / games/engine/src world.ts

100% Statements 38/38
87.5% Branches 7/8
100% Functions 14/14
100% Lines 38/38

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 104  11x 11x 11x 11x 11x 11x 11x     13x 13x 13x 13x 13x     7x 7x 7x     2x 2x 2x     3x     3x     1x     1x 1x       4x 3x 3x   1x     1x     1x     1x         5x 5x 5x   5x 1x 1x   5x     11x                                                                  
import { random } from "jga-algorithms-random";
import { World as BaseWorld, EntityInterface } from "jga-patterns-ecs";
import { Command, CommandManager, CommandResultInterface } from "jga-patterns-command";
import { GameMap, PositionInterface } from "jga-games-maps";
 
import { Scheduler } from "./scheduler";
import { Loop } from "./loop";
 
import { Entity, Player } from "./entities";
import { ComponentName, PositionComponent } from "./components";
import { System } from "./systems";
 
export class World extends BaseWorld {
    private player!: Player;
    private scheduler: Scheduler;
    private map: GameMap;
    private loop: Loop;
    private commandManager: CommandManager;
 
    public constructor(scheduler: Scheduler, map: GameMap, commandManager: CommandManager) {
        super();
        this.scheduler = scheduler;
        this.map = map;
        this.loop = new Loop(this.scheduler);
        this.commandManager = commandManager;
    }
 
    public addEntity(entity: Entity, repeatable = false): Map<string, EntityInterface> {
        const entities = super.addEntity(entity);
 
        this.scheduler.add(entity, repeatable);
 
        return entities;
    }
 
    public createPlayer(): Player {
        this.player = new Player(this.generateId());
 
        this.addEntityAtRandomPosition(this.player, true);
 
        return this.getPlayer();
    }
 
    public getPlayer(): Player {
        return this.player;
    }
 
    public getMap(): GameMap {
        return this.map;
    }
 
    public execute(command: Command): CommandResultInterface {
        return this.commandManager.execute(command);
    }
 
    public process(systems: System[]): void {
        return systems.forEach((system): void => {
            system.run(this.map);
        });
    }
 
    public addEntityAtRandomPosition(entity: Entity, repeatable = false): Map<string, EntityInterface> {
        if (true === entity.hasComponent(ComponentName.POSITION)) {
            (entity.getComponent(ComponentName.POSITION) as PositionComponent).setPosition(
                this.getRandomFloorPosition(),
            );
 
            return this.addEntity(entity, repeatable);
        }
 
        return this.entities;
    }
 
    public lock(): Loop {
        return this.loop.lock();
    }
 
    public unlock(): Loop {
        return this.loop.unlock();
    }
 
    public async mainLoop(): Promise<Loop> {
        return this.loop.start();
    }
 
    private getRandomFloorPosition(): PositionInterface {
        let x: number;
        let y: number;
 
        do {
            x = random(0, this.map.getWidth() - 1);
            y = random(0, this.map.getHeight() - 1);
        } while (null !== this.map.getTile({ x, y }) && !this.map.getTile({ x, y }).isWalkable);
 
        const targets: EntityInterface[] = Array.from(this.entities.values()).filter((entity) => {
            const entityPosition = entity.getComponent(ComponentName.POSITION) as PositionComponent;
 
            return { x, y } === entityPosition.getPosition();
        });
 
        return targets.length === 0 ? { x, y } : this.getRandomFloorPosition();
    }
}