|
- const eventEmitter = require('../misc/events');
-
- let objBase = require('./objBase');
-
- module.exports = {
- lastId: 0,
- instance: null,
-
- objects: [],
-
- init: function (_instance) {
- this.instance = _instance;
- this.physics = this.instance.physics;
- },
-
- getNextId: function () {
- return ++this.lastId;
- },
-
- build: function (isClientObj, id) {
- let o = extend({}, objBase);
-
- if (isClientObj)
- o.update = null;
- else {
- o.id = id || this.getNextId();
- o.addComponent('syncer');
- o.instance = this.instance;
- }
-
- return o;
- },
-
- pushObjectToList: function (obj) {
- this.objects.push(obj);
- },
-
- transferObject: function (o) {
- const obj = this.build();
-
- let components = o.components;
- delete o.components;
- delete o.id;
-
- for (let p in o)
- obj[p] = o[p];
-
- const cLen = components.length;
- for (let i = 0; i < cLen; i++) {
- let c = components[i];
-
- const cpn = obj.addComponent(c.type, null, true);
-
- for (let p in c)
- cpn[p] = c[p];
-
- if (cpn.transfer)
- cpn.transfer();
- }
-
- this.pushObjectToList(obj);
- this.physics.addObject(obj, obj.x, obj.y);
-
- return obj;
- },
-
- buildObjects: function (list, skipPush) {
- let lLen = list.length;
- for (let i = 0; i < lLen; i++) {
- let l = list[i];
-
- let obj = this.build(l.clientObj, l.id);
-
- obj.sheetName = l.sheetName;
- obj.cell = l.cell;
- obj.name = l.name;
-
- obj.x = l.x;
- obj.y = l.y;
-
- if (l.ttl)
- obj.ttl = l.ttl;
-
- if (l.width) {
- obj.width = l.width;
- obj.height = l.height;
- }
-
- if (l.area)
- obj.area = l.area;
-
- //Add components (certain ones need to happen first)
- //TODO: Clean this part up
- let properties = extend({}, l.properties);
- ['cpnMob'].forEach(function (c) {
- let blueprint = properties[c] || null;
- if ((blueprint) && (typeof (blueprint) === 'string'))
- blueprint = JSON.parse(blueprint);
-
- if (!blueprint)
- return;
-
- delete properties[c];
-
- let type = c.replace('cpn', '').toLowerCase();
-
- obj.addComponent(type, blueprint);
- }, this);
-
- for (let p in properties) {
- if (p.indexOf('cpn') === -1) {
- obj[p] = properties[p];
- continue;
- }
-
- let type = p.replace('cpn', '');
- type = type[0].toLowerCase() + type.substr(1);
- let blueprint = properties[p] || null;
- if ((blueprint) && (typeof (blueprint) === 'string'))
- blueprint = JSON.parse(blueprint);
-
- obj.addComponent(type, blueprint);
- }
-
- let extraProperties = l.extraProperties || {};
- for (let p in extraProperties) {
- let cpn = obj[p];
- let e = extraProperties[p];
- for (let pp in e)
- cpn[pp] = e[pp];
-
- if (cpn.init)
- cpn.init();
- }
-
- if ((this.physics) && (!obj.dead)) {
- if (!obj.width)
- this.physics.addObject(obj, obj.x, obj.y);
- else
- this.physics.addRegion(obj);
- }
-
- if (obj.aggro)
- obj.aggro.move();
-
- if (!skipPush)
- this.pushObjectToList(obj);
-
- if (lLen === 1)
- return obj;
- }
- },
-
- find: function (callback) {
- return this.objects.find(callback);
- },
-
- filter: function (callback) {
- return this.objects.filter(callback);
- },
-
- removeObject: function (obj, callback, useServerId) {
- let found = this.objects.spliceFirstWhere(o => obj.id === (useServerId ? o.serverId : o.id));
- if (!found)
- return;
-
- let physics = this.physics;
- if (physics) {
- if (!found.width)
- physics.removeObject(found, found.x, found.y);
- else
- physics.removeRegion(found);
- }
-
- found.destroy();
-
- if (callback)
- callback(found);
- },
-
- addObject: function (o, callback) {
- const newO = this.build();
-
- const components = o.components;
-
- delete o.components;
-
- for (let p in o)
- newO[p] = o[p];
-
- const len = components.length;
- for (let i = 0; i < len; i++) {
- const c = components[i];
-
- const newC = newO.addComponent(c.type, c);
- extend(newC, c);
- }
-
- this.pushObjectToList(newO);
-
- if (!newO.dead)
- this.physics.addObject(newO, newO.x, newO.y);
-
- callback(newO);
-
- return newO;
- },
-
- sendEvent: function (msg, { name: sourceZone }) {
- const { id, data } = msg;
-
- const player = this.objects.find(p => p.id === id);
- if (!player || player.zoneName !== sourceZone)
- return;
-
- player.socket.emit('event', {
- event: data.event,
- data: data.data
- });
- },
-
- sendEvents: function ({ data }, { name: sourceZone }) {
- const { objects } = this;
-
- //Store will contain all events to be sent to players
- const store = {};
-
- for (let e in data) {
- const event = data[e];
- const eLen = event.length;
-
- for (let j = 0; j < eLen; j++) {
- const eventEntry = event[j];
-
- const { obj: eventObj, to } = eventEntry;
-
- if (e === 'serverModule') {
- const { method, msg } = eventObj;
-
- if (Array.isArray(msg))
- global[eventObj.module][method](...msg);
- else
- global[eventObj.module][method](msg);
-
- continue;
- }
-
- const toLen = to.length;
- for (let i = 0; i < toLen; i++) {
- const toId = to[i];
-
- let storeEntry = store[toId];
- if (!storeEntry) {
- const playerObj = objects.find(o => o.id === toId);
-
- if (!playerObj || playerObj.zoneName !== sourceZone)
- continue;
-
- store[toId] = {
- obj: playerObj,
- events: { [e]: [eventObj] }
- };
-
- continue;
- }
-
- if (!storeEntry.events[e])
- storeEntry.events[e] = [];
-
- storeEntry.events[e].push(eventObj);
- }
- }
- }
-
- for (let p in store) {
- const { obj: { socket }, events } = store[p];
-
- socket.emit('events', events);
- }
- },
-
- updateObject: async function (msg) {
- let player = this.objects.find(p => p.id === msg.serverId);
- if (!player)
- return;
-
- let obj = msg.obj;
- for (let p in obj)
- player[p] = obj[p];
-
- if (obj.permadead)
- await leaderboard.killCharacter(player.name);
-
- if (obj.level) {
- await leaderboard.setLevel(player.name, obj.level);
-
- player.components.find(c => c.type === 'stats').values.level = obj.level;
-
- cons.emit('events', {
- onGetMessages: [{
- messages: [{
- class: 'color-blueB',
- message: player.name + ' has reached level ' + obj.level
- }]
- }]
- });
-
- eventEmitter.emit('playerObjChanged', {
- obj: player
- });
- }
- },
-
- notifyCollisionChange: function (x, y, collides) {
- this.objects
- .filter(o => o.player)
- .forEach(function (o) {
- o.syncer.setArray(true, 'player', 'collisionChanges', {
- x,
- y,
- collides
- });
- });
- },
-
- notifyMapChange: function (x, y, mapCellString) {
- this.objects
- .filter(o => o.player)
- .forEach(function (o) {
- o.syncer.setArray(true, 'player', 'mapChanges', {
- x,
- y,
- mapCellString
- });
- });
- },
-
- update: function () {
- let objects = this.objects;
- let len = objects.length;
-
- for (let i = 0; i < len; i++) {
- let o = objects[i];
-
- //If object A causes object B (layer in the list) to rezone, we won't find it here
- if (!o) {
- len--;
-
- continue;
- }
-
- //Don't remove it from the list if it's destroyed, but don't update it either
- //That's syncer's job
- if ((o.update) && (!o.destroyed))
- o.update();
-
- //When objects are sent to other zones, we destroy them immediately (thhrough sendObjToZone)
- if (o.forceDestroy) {
- i--;
- len--;
- continue;
- }
-
- if (o.ttl) {
- o.ttl--;
- if (!o.ttl)
- o.destroyed = true;
- }
-
- o.fireEvent('afterTick');
- }
- }
- };
|