module.exports = { type: 'follower', master: null, lifetime: -1, maxDistance: 10, lastMasterPos: { x: 0, y: 0 }, noNeedMaster: false, fGetHighest: { inCombat: null, outOfCombat: null }, bindEvents: function () { let master = this.master; this.lastMasterPos.x = master.x; this.lastMasterPos.y = master.y; this.obj.aggro.faction = master.aggro.faction; this.fGetHighest.inCombat = master.aggro.getHighest.bind(master.aggro); this.fGetHighest.outOfCombat = this.returnNoAggro.bind(this); }, returnNoAggro: function () { let master = this.master; let obj = this.obj; let mob = obj.mob; mob.originX = master.x + ~~((Math.random() * 2) * 2) - 1; mob.originY = master.y + ~~((Math.random() * 2) * 2) - 1; return null; }, despawn: function () { let obj = this.obj; obj.destroyed = true; this.obj.instance.syncer.queue('onGetObject', { x: obj.x, y: obj.y, components: [{ type: 'attackAnimation', row: 0, col: 4 }] }, -1); }, teleport: function () { let obj = this.obj; let physics = obj.instance.physics; let syncer = obj.syncer; let master = this.master; let newPosition = physics.getOpenCellInArea(master.x - 1, master.y - 1, master.x + 1, master.y + 1); if (!newPosition) return; physics.removeObject(obj, obj.x, obj.y); obj.x = newPosition.x; obj.y = newPosition.y; syncer.o.x = obj.x; syncer.o.y = obj.y; physics.addObject(obj, obj.x, obj.y); obj.instance.syncer.queue('onGetObject', { x: obj.x, y: obj.y, components: [{ type: 'attackAnimation', row: 0, col: 4 }] }, -1); }, update: function () { if (this.lifetime > 0) { this.lifetime--; if (this.lifetime <= 0) { this.despawn(); return; } } let obj = this.obj; let master = this.master; if ((master.destroyed) && (!this.noNeedMaster)) { this.despawn(); return; } let attacker = this.fGetHighest.inCombat(); let maxDistance = this.maxDistance; let distance = Math.max(Math.abs(obj.x - master.x), Math.abs(obj.y - master.y)); //When we're too far, just teleport if ((!attacker) && (distance >= maxDistance * 2)) { this.teleport(); return; } let doMove = false; //If we're not too far from the master but the master is not in combat, move anyway if (!attacker) { let lastMasterPos = this.lastMasterPos; if ((master.x !== lastMasterPos.x) || (master.y !== lastMasterPos.y)) { doMove = true; lastMasterPos.x = master.x; lastMasterPos.y = master.y; } } if (doMove) { this.obj.clearQueue(); obj.mob.target = obj; } obj.aggro.getHighest = doMove ? this.fGetHighest.outOfCombat : this.fGetHighest.inCombat; }, simplify: function () { return { type: 'follower', master: this.master.id }; } };