"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // node_modules/eventemitter3/index.js var require_eventemitter3 = __commonJS({ "node_modules/eventemitter3/index.js"(exports, module2) { "use strict"; var has = Object.prototype.hasOwnProperty; var prefix = "~"; function Events() { } if (Object.create) { Events.prototype = /* @__PURE__ */ Object.create(null); if (!new Events().__proto__) prefix = false; } function EE(fn, context, once) { this.fn = fn; this.context = context; this.once = once || false; } function addListener(emitter, event, fn, context, once) { if (typeof fn !== "function") { throw new TypeError("The listener must be a function"); } var listener = new EE(fn, context || emitter, once), evt = prefix ? prefix + event : event; if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++; else if (!emitter._events[evt].fn) emitter._events[evt].push(listener); else emitter._events[evt] = [emitter._events[evt], listener]; return emitter; } function clearEvent(emitter, evt) { if (--emitter._eventsCount === 0) emitter._events = new Events(); else delete emitter._events[evt]; } function EventEmitter2() { this._events = new Events(); this._eventsCount = 0; } EventEmitter2.prototype.eventNames = function eventNames() { var names = [], events, name; if (this._eventsCount === 0) return names; for (name in events = this._events) { if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); } if (Object.getOwnPropertySymbols) { return names.concat(Object.getOwnPropertySymbols(events)); } return names; }; EventEmitter2.prototype.listeners = function listeners(event) { var evt = prefix ? prefix + event : event, handlers = this._events[evt]; if (!handlers) return []; if (handlers.fn) return [handlers.fn]; for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) { ee[i] = handlers[i].fn; } return ee; }; EventEmitter2.prototype.listenerCount = function listenerCount(event) { var evt = prefix ? prefix + event : event, listeners = this._events[evt]; if (!listeners) return 0; if (listeners.fn) return 1; return listeners.length; }; EventEmitter2.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { var evt = prefix ? prefix + event : event; if (!this._events[evt]) return false; var listeners = this._events[evt], len = arguments.length, args, i; if (listeners.fn) { if (listeners.once) this.removeListener(event, listeners.fn, void 0, true); switch (len) { case 1: return listeners.fn.call(listeners.context), true; case 2: return listeners.fn.call(listeners.context, a1), true; case 3: return listeners.fn.call(listeners.context, a1, a2), true; case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true; case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; } for (i = 1, args = new Array(len - 1); i < len; i++) { args[i - 1] = arguments[i]; } listeners.fn.apply(listeners.context, args); } else { var length = listeners.length, j; for (i = 0; i < length; i++) { if (listeners[i].once) this.removeListener(event, listeners[i].fn, void 0, true); switch (len) { case 1: listeners[i].fn.call(listeners[i].context); break; case 2: listeners[i].fn.call(listeners[i].context, a1); break; case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break; case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break; default: if (!args) for (j = 1, args = new Array(len - 1); j < len; j++) { args[j - 1] = arguments[j]; } listeners[i].fn.apply(listeners[i].context, args); } } } return true; }; EventEmitter2.prototype.on = function on(event, fn, context) { return addListener(this, event, fn, context, false); }; EventEmitter2.prototype.once = function once(event, fn, context) { return addListener(this, event, fn, context, true); }; EventEmitter2.prototype.removeListener = function removeListener(event, fn, context, once) { var evt = prefix ? prefix + event : event; if (!this._events[evt]) return this; if (!fn) { clearEvent(this, evt); return this; } var listeners = this._events[evt]; if (listeners.fn) { if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) { clearEvent(this, evt); } } else { for (var i = 0, events = [], length = listeners.length; i < length; i++) { if (listeners[i].fn !== fn || once && !listeners[i].once || context && listeners[i].context !== context) { events.push(listeners[i]); } } if (events.length) this._events[evt] = events.length === 1 ? events[0] : events; else clearEvent(this, evt); } return this; }; EventEmitter2.prototype.removeAllListeners = function removeAllListeners(event) { var evt; if (event) { evt = prefix ? prefix + event : event; if (this._events[evt]) clearEvent(this, evt); } else { this._events = new Events(); this._eventsCount = 0; } return this; }; EventEmitter2.prototype.off = EventEmitter2.prototype.removeListener; EventEmitter2.prototype.addListener = EventEmitter2.prototype.on; EventEmitter2.prefixed = prefix; EventEmitter2.EventEmitter = EventEmitter2; if ("undefined" !== typeof module2) { module2.exports = EventEmitter2; } } }); // src/index.ts var src_exports = {}; __export(src_exports, { Area: () => Area, Mob: () => Mob }); module.exports = __toCommonJS(src_exports); // node_modules/eventemitter3/index.mjs var import_index = __toESM(require_eventemitter3(), 1); var eventemitter3_default = import_index.default; // src/Position.ts var Position = class { __area; __mob; __x = 0; __y = 0; __z = 0; __w = 0; static GetDistance(a, b) { const x = Math.abs(a.__x) - Math.abs(b.__x); const y = Math.abs(a.__y) - Math.abs(b.__y); const z = Math.abs(a.__z) - Math.abs(b.__z); const w = Math.abs(a.__w) - Math.abs(b.__w); return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2) + Math.pow(w, 2)); } constructor(area, mob) { this.__area = area; this.__mob = mob; } get x() { return this.__x; } get y() { return this.__y; } get z() { return this.__z; } get w() { return this.__w; } set x(v) { this.__x = v; this.__area.dirties.add(this.__mob); } set y(v) { this.__y = v; this.__area.dirties.add(this.__mob); } set z(v) { this.__z = v; this.__area.dirties.add(this.__mob); } set w(v) { this.__w = v; this.__area.dirties.add(this.__mob); } set(x, y = 0, z = 0, w = 0) { if (typeof x === "number") { this.x = x; this.y = y; this.z = z; this.w = w; } else { this.x = x.x ?? this.x; this.y = x.y ?? this.y; this.z = x.z ?? this.z; this.w = x.w ?? this.w; } return this; } }; // src/Mob.ts var Mob = class { id; position; emitter; neighbors = /* @__PURE__ */ new Set(); __thresholdRadius; area; constructor(id, thresholdRadius, area) { this.id = id; this.area = area; this.position = new Position(area, this); this.emitter = new eventemitter3_default(); this.__thresholdRadius = thresholdRadius; this.__setDirty(); } get thresholdRadius() { return this.__thresholdRadius; } set thresholdRadius(v) { this.__thresholdRadius = v; this.area.dirties.add(this); } __setDirty() { this.area.dirties.add(this); } /** * It is same as `area.removeMob(mob.id)` */ destroy() { this.neighbors.clear(); this.area.dirties.delete(this); this.area.mobs.delete(this.id); this.area.mobs.forEach((mob) => { const isExists = mob.neighbors.delete(this); if (isExists) { mob.emitter.emit("out", this); } }); } }; // src/Area.ts var Area = class { mobs = /* @__PURE__ */ new Map(); dirties = /* @__PURE__ */ new Set(); /** * Create a new mobility object. You can use `mob.id` property for `getMob` or `removeMob` method. * @param id Mobility identifier. If same id is already exists, it will be not create mob and returns exists one. * @param thresholdRadius Sight of mob. */ addMob(id, thresholdRadius) { const alreadyExists = this.getMob(id); if (alreadyExists) { return alreadyExists; } const mob = new Mob(id, thresholdRadius, this); this.mobs.set(mob.id, mob); return mob; } /** * Get a added mobility object from area instance. If object not exists, It will be returns `null`. * @param id Mobility identifier what you want find. */ getMob(id) { return this.mobs.get(id) || null; } /** * Remove a added mobility. If object exists, returns `true`. otherwise, returns `false`. * @param id Mobility identifier what you want remove. */ removeMob(id) { const mob = this.getMob(id); if (mob) { mob.destroy(); } return !!mob; } /** * When this function is called, an 'in', 'out' event emits according to the coordinates of the mob. */ update() { for (const dirty of this.dirties) { for (const current of this.mobs.values()) { if (current === dirty) { continue; } const isNeighbor = dirty.neighbors.has(current); const threshold = dirty.thresholdRadius; const distance = Position.GetDistance(dirty.position, current.position); if (isNeighbor && threshold < distance) { dirty.emitter.emit("out", current); dirty.neighbors.delete(current); } else if (!isNeighbor && threshold > distance) { dirty.emitter.emit("in", current); dirty.neighbors.add(current); } } } this.dirties.clear(); } /** * Destroys all mob. */ destroy() { this.mobs.forEach((mob) => mob.destroy()); this.mobs.clear(); this.dirties.clear(); } };