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;