106 lines
2.5 KiB
JavaScript
106 lines
2.5 KiB
JavaScript
const EventScheduler = require("./EventScheduler");
|
|
|
|
const constants = require("../Data/constants");
|
|
const { TYPES, TIMING_EVENTS } = constants;
|
|
const { ENTITY_TYPE_PLAYER } = TYPES;
|
|
const { TIMING_EVENT_RESPAWN } = TIMING_EVENTS;
|
|
|
|
class Entity extends EventScheduler {
|
|
constructor(info) {
|
|
const id = info.type === ENTITY_TYPE_PLAYER ? info.id : Entity.composeID(info.type - 1, info.id);
|
|
super(info.type, id, info.map.id);
|
|
|
|
this.isAlive = info.isAlive ?? true;
|
|
this.chunk = null;
|
|
this.type = null;
|
|
this.map = info.map;
|
|
this.typeID = info.type;
|
|
this.id = id;
|
|
|
|
const { map } = this;
|
|
|
|
if (info.position) {
|
|
const cell = info.map.grid.getCell(info.position.x, info.position.y);
|
|
const coordinate = info.map.grid.getCoords(cell.xw, cell.xh)
|
|
|
|
this.position = coordinate;
|
|
} else this.position = map.grid.randomNode(10);
|
|
|
|
if (info.type !== ENTITY_TYPE_PLAYER) {
|
|
const currentChunk = this.getCurrentChunk();
|
|
map[currentChunk].addItem(id, this);
|
|
|
|
this.chunk = currentChunk;
|
|
};
|
|
};
|
|
|
|
static composeID(entityType, entityID) {
|
|
return ((entityType & 0xFF) << 24) | (entityID & 0xFFFFFF);
|
|
}
|
|
|
|
static getType(compositeID) {
|
|
return (compositeID >> 24) & 0xFF;
|
|
}
|
|
|
|
static getID(compositeID) {
|
|
return compositeID & 0xFFFFFF;
|
|
}
|
|
|
|
getCurrentChunk() {
|
|
return `chunk_${Math.floor(this.position.x / (10 * 120))}-${Math.floor(this.position.y / (10 * 90))}`;
|
|
}
|
|
|
|
removeFromChunk() {
|
|
if (!this.chunk) return;
|
|
|
|
this.map[this.chunk].removeItem(this.id);
|
|
|
|
this.chunk = null;
|
|
}
|
|
|
|
updateChunk() {
|
|
const { chunk, map, id } = this;
|
|
|
|
const currentChunk = this.getCurrentChunk();
|
|
if (chunk !== currentChunk) {
|
|
this.removeFromChunk();
|
|
|
|
map[currentChunk].addItem(id, this);
|
|
this.chunk = currentChunk;
|
|
|
|
this.chunkIndex = [Math.floor(this.position.x / (10 * 120)), Math.floor(this.position.y / (10 * 90))];
|
|
|
|
return true;
|
|
};
|
|
|
|
return false;
|
|
}
|
|
|
|
die() {
|
|
if (!this.isAlive) return;
|
|
|
|
this.isAlive = false;
|
|
|
|
this.removeFromChunk();
|
|
|
|
const players = this.map.getLivingEntities([ENTITY_TYPE_PLAYER]);
|
|
players.forEach(p => delete p.inDistance[this.id]); // this is not efficient, should update
|
|
}
|
|
|
|
respawn(respawn = {}) {
|
|
if (this.isAlive) return;
|
|
|
|
this.isAlive = true;
|
|
this.position = respawn.position ? respawn.position : this.map.grid.randomNode(10);
|
|
|
|
this.updateChunk();
|
|
|
|
this.removeEvent(TIMING_EVENT_RESPAWN);
|
|
}
|
|
|
|
markActive() {
|
|
this.map[`chunkTest_${Math.floor(this.position.x / (10 * 120))}-${Math.floor(this.position.y / (10 * 90))}`].addItem(this.id, this);
|
|
}
|
|
};
|
|
|
|
module.exports = Entity; |