Files
pixel.horse/src/ts/server/controllers/collectableController.ts
T
2019-08-28 21:15:02 -07:00

73 lines
2.0 KiB
TypeScript

import { remove, sample } from 'lodash';
import { Entity, CreateEntityMethod } from '../../common/interfaces';
import { IClient, Controller, ServerEntity, ServerMap } from '../serverInterfaces';
import { World } from '../world';
import { timingEnd, timingStart } from '../timing';
import { canPlaceItem, canBePickedByPlayer, pushRemoveEntityToClient } from '../entityUtils';
export function randomPosition(map: ServerMap) {
const x = Math.random() * map.width;
const y = Math.random() * map.height;
return { x, y };
}
export class CollectableController implements Controller {
private items: Entity[] = [];
constructor(
private world: World,
private map: ServerMap,
private ctors: CreateEntityMethod[],
public limit: number,
private pick: (client: IClient, entity: ServerEntity) => void,
private check: (client: IClient) => boolean = () => true,
private tries = 1,
private position = randomPosition,
private active = () => true
) {
}
initialize() {
}
update() {
timingStart('CollectableController.update()');
if (this.active()) {
for (let i = 0; i < this.tries; i++) {
if (this.items.length < this.limit) {
this.generateItem();
}
}
}
timingEnd();
}
private generateItem() {
const { world, map } = this;
const { x, y } = this.position(map);
const ctor = sample(this.ctors)!;
const entity = ctor(x, y) as ServerEntity;
if (!entity.interactRange) {
entity.interactRange = 1.5;
}
if (
x > 0 && y > 0 && x < map.width && y < map.height && canPlaceItem(map, entity) && !canBePickedByPlayer(map, entity)
) {
entity.interact = this.interact;
this.items.push(world.addEntity(entity, map));
}
}
private interact = (entity: Entity, client: IClient) => {
if (this.check(client)) {
if (client.shadowed) {
pushRemoveEntityToClient(client, entity);
} else {
remove(this.items, e => e === entity);
this.world.removeEntity(entity, this.map);
this.generateItem();
this.pick(client, entity);
}
}
}
}