mirror of
https://github.com/Terncode/pixel.horse.git
synced 2026-09-25 06:05:52 +02:00
73 lines
2.0 KiB
TypeScript
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);
|
|
}
|
|
}
|
|
}
|
|
}
|