|
- //System Imports
- const fs = require('fs');
-
- //Imports
- const phaseTemplate = require('./phases/phaseTemplate');
- const { mapList } = require('../world/mapManager');
-
- //Internals
- const phasePaths = [{
- type: 'end',
- path: './phases/phaseEnd'
- }];
-
- //Helpers
- const applyVariablesToDescription = (desc, variables) => {
- if (!variables)
- return desc;
-
- Object.entries(variables).forEach(e => {
- const [key, value] = e;
- desc = desc.split(`$${key}$`).join(value);
- });
-
- return desc;
- };
-
- //Exports
- module.exports = {
- configs: [],
- nextId: 0,
-
- init: function (instance) {
- this.instance = instance;
-
- this.instance.eventEmitter.emit('beforeGetEventPhasePaths', {
- phasePaths
- });
-
- const zoneName = this.instance.map.name;
- const zonePath = mapList.find(z => z.name === zoneName).path;
- const zoneEventPath = zonePath + '/' + zoneName + '/events';
-
- const paths = ['config/globalEvents', zoneEventPath];
- const files = [];
- paths.forEach(p => {
- if (!fs.existsSync(p))
- return;
-
- files.push(...fs.readdirSync(p).map(f => ('../' + p + '/' + f)));
- });
-
- this.instance.eventEmitter.emit('onBeforeGetEventList', zoneName, files);
-
- files.forEach(f => {
- if (!f.includes('.js'))
- return;
-
- const e = require(f);
- if (!e.disabled)
- this.configs.push(extend({}, e));
- }, this);
- },
-
- getEvent: function (name) {
- return this.configs.find(c => (c.name === name)).event.config;
- },
-
- setEventDescription: function (name, desc) {
- let config = this.getEvent(name);
- let event = config.event;
- if (!event)
- return;
-
- if (!config.oldDescription)
- config.oldDescription = config.description;
-
- if ((config.events) && (config.events.beforeSetDescription))
- config.events.beforeSetDescription(this);
-
- if (desc) {
- desc = applyVariablesToDescription(desc, event.variables);
-
- config.description = desc;
- }
-
- event.participators.forEach(p => p.events.syncList());
- },
-
- setEventRewards: function (name, rewards) {
- let config = this.getEvent(name);
- let event = config.event;
- if (!event)
- return;
-
- event.rewards = rewards;
- event.age = event.config.duration - 2;
- },
-
- setParticipantRewards: function (eventName, participantName, newRewards) {
- const { event: { rewards } } = this.getEvent(eventName);
-
- rewards[participantName] = newRewards;
- },
-
- addParticipantRewards: function (eventName, participantName, addRewards) {
- const { event: { rewards } } = this.getEvent(eventName);
-
- let pRewards = rewards[participantName];
- if (!pRewards) {
- pRewards = [];
- rewards[participantName] = pRewards;
- }
-
- if (!addRewards.push)
- addRewards = [ addRewards ];
-
- addRewards.forEach(r => {
- const { name, quantity = 1 } = r;
-
- const exists = pRewards.find(f => f.name === name);
- if (exists)
- exists.quantity = (exists.quantity || 1) + quantity;
- else
- pRewards.push(r);
- });
- },
-
- setWinText: function (name, text) {
- let config = this.getEvent(name);
- let event = config.event;
- if (!event)
- return;
-
- event.winText = text;
- },
-
- setEventVariable: function (eventName, variableName, value) {
- let config = this.getEvent(eventName);
- let event = config.event;
- if (!event)
- return;
-
- event.variables[variableName] = value;
- },
-
- incrementEventVariable: function (eventName, variableName, delta) {
- let config = this.getEvent(eventName);
- let event = config.event;
- if (!event)
- return;
-
- const currentValue = event.variables[variableName] || 0;
- event.variables[variableName] = currentValue + delta;
- },
-
- update: function () {
- let configs = this.configs;
- if (!configs)
- return;
-
- let scheduler = this.instance.scheduler;
-
- let cLen = configs.length;
- for (let i = 0; i < cLen; i++) {
- let c = configs[i];
-
- if (c.event) {
- this.updateEvent(c.event);
-
- const shouldStop = (
- c.event.done ||
- (
- c.cron &&
- c.durationEvent &&
- !scheduler.isActive(c)
- )
- );
-
- if (shouldStop)
- this.stopEvent(c);
-
- continue;
- } else if ((c.ttl) && (c.ttl > 0)) {
- c.ttl--;
- continue;
- } else if (c.cron) {
- if (c.durationEvent && !scheduler.isActive(c))
- continue;
- else if (!c.durationEvent && !scheduler.shouldRun(c))
- continue;
- } else if (c.manualTrigger)
- continue;
-
- c.event = this.startEvent(c);
- this.updateEvent(c.event);
- }
- },
-
- startEvent: function (config) {
- if (config.oldDescription)
- config.description = config.oldDescription;
-
- const event = {
- id: this.nextId++,
- config: extend({}, config),
- eventManager: this,
- variables: {},
- rewards: {},
- phases: [],
- participators: [],
- objects: [],
- nextPhase: 0,
- age: 0
- };
- event.config.event = event;
-
- const onStart = _.getDeepProperty(event, ['config', 'events', 'onStart']);
- if (onStart)
- onStart(this, event);
-
- return event;
- },
-
- startEventByCode: function (eventCode) {
- const config = this.configs.find(c => c.code === eventCode);
- if (!config || config.event)
- return;
-
- config.event = this.startEvent(config);
- this.updateEvent(config.event);
-
- this.instance.syncer.queue('onGetMessages', {
- messages: {
- class: 'color-pinkA',
- message: `The ${config.name} event has begun!`
- }
- }, -1);
- },
-
- stopEventByCode: function (eventCode) {
- const config = this.configs.find(c => c.code === eventCode);
- if (!config || !config.event)
- return;
-
- this.stopEvent(config);
-
- this.instance.syncer.queue('onGetMessages', {
- messages: {
- class: 'color-pinkA',
- message: `The ${config.name} event has come to an end!`
- }
- }, -1);
- },
-
- giveRewards: function (config) {
- const { event: { rewards = {} } } = config;
-
- const subject = `${config.name} Rewards`;
- const senderName = config.rewardSenderName;
-
- Object.entries(rewards).forEach(e => {
- const [ name, rList ] = e;
-
- if (!rList || !rList.length)
- return;
-
- //Hack: Mail is a mod. As such, events should be a mod that depends on mail
- if (global.mailManager) {
- global.mailManager.sendSystemMail({
- to: name,
- from: senderName,
- subject,
- msg: '',
- items: rList,
- notify: true
- });
- }
- });
-
- if ((config.events) && (config.events.afterGiveRewards))
- config.events.afterGiveRewards(this, config);
- },
-
- stopAll: function () {
- this.configs.forEach(c => {
- if (c.event)
- c.event.done = true;
- });
- },
-
- stopEvent: function (config) {
- let event = config.event;
-
- config.event.participators.forEach(function (p) {
- p.events.unregisterEvent(event);
- }, this);
-
- config.event.objects.forEach(function (o) {
- o.destroyed = true;
-
- this.instance.syncer.queue('onGetObject', {
- x: o.x,
- y: o.y,
- components: [{
- type: 'attackAnimation',
- row: 0,
- col: 4
- }]
- }, -1);
- }, this);
-
- if (event.winText) {
- this.instance.syncer.queue('serverModule', {
- module: 'cons',
- method: 'emit',
- msg: [
- 'event',
- {
- event: 'onGetMessages',
- data: {
- messages: {
- class: 'color-pinkA',
- message: event.winText
- }
- }
- }
- ]
- }, ['server']);
- }
-
- event.phases.forEach(function (p) {
- if ((p.destroy) && (!p.destroyed)) {
- p.destroyed = true;
- p.destroy();
- }
- });
-
- const onStop = _.getDeepProperty(event, ['config', 'events', 'onStop']);
- if (onStop)
- onStop(this, event);
-
- delete config.event;
- },
-
- handleNotification: function (event, { msg, desc, event: triggerEvent }) {
- if (msg) {
- this.instance.syncer.queue('serverModule', {
- module: 'cons',
- method: 'emit',
- msg: [
- 'event',
- {
- event: 'onGetMessages',
- data: {
- messages: {
- class: 'color-pinkA',
- message: msg
- }
- }
- }
- ]
- }, ['server']);
- }
-
- if (desc) {
- event.config.descTimer = desc;
- this.setEventDescription(event.config.name);
- }
-
- if (triggerEvent && event.config.events[triggerEvent])
- event.config.events[triggerEvent](this, event);
- },
-
- updateEvent: function (event) {
- const onTick = _.getDeepProperty(event, ['config', 'events', 'onTick']);
- if (onTick)
- onTick(this, event);
-
- let objects = event.objects;
- let oLen = objects.length;
- for (let i = 0; i < oLen; i++) {
- if (objects[i].destroyed) {
- objects.splice(i, 1);
- i--;
- oLen--;
- }
- }
-
- let currentPhases = event.phases;
- let cLen = currentPhases.length;
- let stillBusy = false;
- for (let i = 0; i < cLen; i++) {
- let phase = currentPhases[i];
- if (!phase.destroyed) {
- if (phase.end || (phase.endMark !== -1 && phase.endMark <= event.age)) {
- if ((phase.destroy) && (!phase.destroyed))
- phase.destroy();
- phase.destroyed = true;
- continue;
- } else {
- if (phase.has('ttl')) {
- if (phase.ttl === 0) {
- phase.end = true;
- continue;
- }
-
- phase.ttl--;
- stillBusy = true;
- } else if (!phase.auto)
- stillBusy = true;
-
- phase.update(event);
- }
- }
- }
-
- const notifications = event.config.notifications || [];
- notifications.forEach(n => {
- if (n.mark === event.age)
- this.handleNotification(event, n);
- });
-
- event.age++;
-
- if (event.age === event.config.duration)
- event.done = true;
-
- else if ((event.config.prizeTime) && (event.age === event.config.prizeTime))
- this.giveRewards(event.config);
-
- if (stillBusy)
- return;
-
- let config = event.config;
-
- let phases = config.phases;
- let pLen = phases.length;
- for (let i = event.nextPhase; i < pLen; i++) {
- let p = phases[i];
-
- let phase = event.phases[i];
- if (!phase) {
- let typeTemplate;
-
- const phasePathEntry = phasePaths.find(f => f.type === p.type);
- if (!phasePathEntry) {
- const phaseFile = 'phase' + p.type[0].toUpperCase() + p.type.substr(1);
- typeTemplate = require('./phases/' + phaseFile);
- } else
- typeTemplate = require(`../${phasePathEntry.path}`);
-
- phase = extend({
- instance: this.instance,
- event: event
- }, phaseTemplate, typeTemplate, p);
-
- event.phases.push(phase);
- event.currentPhase = phase;
- }
-
- event.nextPhase = i + 1;
- phase.init(event);
-
- if (!p.auto) {
- stillBusy = true;
- break;
- }
- }
-
- if ((event.nextPhase >= pLen) && (!stillBusy))
- event.done = true;
-
- let oList = this.instance.objects.objects;
- oLen = oList.length;
- for (let i = 0; i < oLen; i++) {
- let o = oList[i];
- if (!o.player)
- continue;
-
- o.events.events.afterMove.call(o.events);
- }
- },
-
- getCloseEvents: function (obj) {
- let x = obj.x;
- let y = obj.y;
-
- let configs = this.configs;
- if (!configs)
- return;
-
- let cLen = configs.length;
- let result = [];
- for (let i = 0; i < cLen; i++) {
- let event = configs[i].event;
- if (!event)
- continue;
-
- let exists = event.participators.find(p => (p.name === obj.name));
- if (exists) {
- event.participators.spliceWhere(p => (p === exists));
- event.participators.push(obj);
- result.push(event);
- continue;
- }
-
- let distance = event.config.distance;
- if (distance === -1) {
- event.participators.push(obj);
- result.push(event);
-
- if (event.config.events && event.config.events.onParticipantJoin)
- event.config.events.onParticipantJoin(this, obj);
-
- continue;
- }
-
- let objects = event.objects;
- let oLen = objects.length;
- for (let j = 0; j < oLen; j++) {
- let o = objects[j];
-
- if (
- (distance === -1) ||
- (!distance) ||
- (
- (Math.abs(x - o.x) < distance) &&
- (Math.abs(y - o.y) < distance)
- )
- ) {
- event.participators.push(obj);
- result.push(event);
-
- if (event.config.events && event.config.events.onParticipantJoin)
- event.config.events.onParticipantJoin(this, obj);
-
- break;
- }
- }
- }
-
- return result;
- }
- };
|