Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 

483 wiersze
10 KiB

  1. let phaseTemplate = require('./phases/phaseTemplate');
  2. let fs = require('fs');
  3. let mapList = require('../config/maps/mapList');
  4. const applyVariablesToDescription = (desc, variables) => {
  5. if (!variables)
  6. return desc;
  7. Object.entries(variables).forEach(e => {
  8. const [key, value] = e;
  9. desc = desc.split(`$${key}$`).join(value);
  10. });
  11. return desc;
  12. };
  13. module.exports = {
  14. configs: [],
  15. nextId: 0,
  16. init: function (instance) {
  17. this.instance = instance;
  18. const zoneName = this.instance.map.name;
  19. const zonePath = mapList.mapList.find(z => z.name === zoneName).path;
  20. const zoneEventPath = zonePath + '/' + zoneName + '/events';
  21. const paths = ['config/globalEvents', zoneEventPath];
  22. const files = [];
  23. paths.forEach(p => {
  24. if (!fs.existsSync(p))
  25. return;
  26. files.push(...fs.readdirSync(p).map(f => ('../' + p + '/' + f)));
  27. });
  28. this.instance.eventEmitter.emit('onBeforeGetEventList', zoneName, files);
  29. files.forEach(f => {
  30. const e = require(f);
  31. if (!e.disabled)
  32. this.configs.push(extend({}, e));
  33. }, this);
  34. },
  35. getEvent: function (name) {
  36. return this.configs.find(c => (c.name === name)).event.config;
  37. },
  38. setEventDescription: function (name, desc) {
  39. let config = this.getEvent(name);
  40. let event = config.event;
  41. if (!event)
  42. return;
  43. if (!config.oldDescription)
  44. config.oldDescription = config.description;
  45. if ((config.events) && (config.events.beforeSetDescription))
  46. config.events.beforeSetDescription(this);
  47. if (desc) {
  48. desc = applyVariablesToDescription(desc, event.variables);
  49. config.description = desc;
  50. }
  51. event.participators.forEach(p => p.events.syncList());
  52. },
  53. setEventRewards: function (name, rewards) {
  54. let config = this.getEvent(name);
  55. let event = config.event;
  56. if (!event)
  57. return;
  58. event.rewards = rewards;
  59. event.age = event.config.duration - 2;
  60. },
  61. setParticipantRewards: function (eventName, participantName, newRewards) {
  62. const { event: { rewards } } = this.getEvent(eventName);
  63. rewards[participantName] = newRewards;
  64. },
  65. addParticipantRewards: function (eventName, participantName, addRewards) {
  66. const { event: { rewards } } = this.getEvent(eventName);
  67. let pRewards = rewards[participantName];
  68. if (!pRewards) {
  69. pRewards = [];
  70. rewards[participantName] = pRewards;
  71. }
  72. if (!addRewards.push)
  73. addRewards = [ addRewards ];
  74. addRewards.forEach(r => {
  75. const { name, quantity = 1 } = r;
  76. const exists = pRewards.find(f => f.name === name);
  77. if (exists)
  78. exists.quantity = (exists.quantity || 1) + quantity;
  79. else
  80. pRewards.push(r);
  81. });
  82. },
  83. setWinText: function (name, text) {
  84. let config = this.getEvent(name);
  85. let event = config.event;
  86. if (!event)
  87. return;
  88. event.winText = text;
  89. },
  90. setEventVariable: function (eventName, variableName, value) {
  91. let config = this.getEvent(eventName);
  92. let event = config.event;
  93. if (!event)
  94. return;
  95. event.variables[variableName] = value;
  96. },
  97. incrementEventVariable: function (eventName, variableName, delta) {
  98. let config = this.getEvent(eventName);
  99. let event = config.event;
  100. if (!event)
  101. return;
  102. const currentValue = event.variables[variableName] || 0;
  103. event.variables[variableName] = currentValue + delta;
  104. },
  105. update: function () {
  106. let configs = this.configs;
  107. if (!configs)
  108. return;
  109. let scheduler = this.instance.scheduler;
  110. let cLen = configs.length;
  111. for (let i = 0; i < cLen; i++) {
  112. let c = configs[i];
  113. if (c.event) {
  114. this.updateEvent(c.event);
  115. if (c.event.done)
  116. this.stopEvent(c);
  117. continue;
  118. } else if ((c.ttl) && (c.ttl > 0)) {
  119. c.ttl--;
  120. continue;
  121. } else if (c.cron) {
  122. if (c.durationEvent && !scheduler.isActive(c))
  123. continue;
  124. else if (!c.durationEvent && !scheduler.shouldRun(c))
  125. continue;
  126. } else if (c.manualTrigger)
  127. continue;
  128. c.event = this.startEvent(c);
  129. this.updateEvent(c.event);
  130. }
  131. },
  132. startEvent: function (config) {
  133. if (config.oldDescription)
  134. config.description = config.oldDescription;
  135. let event = {
  136. id: this.nextId++,
  137. config: extend({}, config),
  138. eventManager: this,
  139. variables: {},
  140. rewards: {},
  141. phases: [],
  142. participators: [],
  143. objects: [],
  144. nextPhase: 0,
  145. age: 0
  146. };
  147. event.config.event = event;
  148. return event;
  149. },
  150. startEventByCode: function (eventCode) {
  151. const config = this.configs.find(c => c.code === eventCode);
  152. if (!config || config.event)
  153. return;
  154. config.event = this.startEvent(config);
  155. this.updateEvent(config.event);
  156. this.instance.syncer.queue('onGetMessages', {
  157. messages: {
  158. class: 'color-pinkA',
  159. message: `The ${config.name} event has begun!`
  160. }
  161. }, -1);
  162. },
  163. stopEventByCode: function (eventCode) {
  164. const config = this.configs.find(c => c.code === eventCode);
  165. if (!config || !config.event)
  166. return;
  167. this.stopEvent(config);
  168. this.instance.syncer.queue('onGetMessages', {
  169. messages: {
  170. class: 'color-pinkA',
  171. message: `The ${config.name} event has come to an end!`
  172. }
  173. }, -1);
  174. },
  175. giveRewards: function (config) {
  176. const { event: { rewards = {} } } = config;
  177. Object.entries(rewards).forEach(e => {
  178. const { name, rList } = e;
  179. if (!rList.length)
  180. return;
  181. rList[0].msg = `${config.name} reward:`;
  182. this.instance.mail.sendMail(name, rList);
  183. });
  184. if ((config.events) && (config.events.afterGiveRewards))
  185. config.events.afterGiveRewards(this, config);
  186. },
  187. stopEvent: function (config) {
  188. let event = config.event;
  189. config.event.participators.forEach(function (p) {
  190. p.events.unregisterEvent(event);
  191. }, this);
  192. config.event.objects.forEach(function (o) {
  193. o.destroyed = true;
  194. this.instance.syncer.queue('onGetObject', {
  195. x: o.x,
  196. y: o.y,
  197. components: [{
  198. type: 'attackAnimation',
  199. row: 0,
  200. col: 4
  201. }]
  202. }, -1);
  203. }, this);
  204. if (event.winText) {
  205. this.instance.syncer.queue('serverModule', {
  206. module: 'cons',
  207. method: 'emit',
  208. msg: [
  209. 'event',
  210. {
  211. event: 'onGetMessages',
  212. data: {
  213. messages: {
  214. class: 'color-pinkA',
  215. message: event.winText
  216. }
  217. }
  218. }
  219. ]
  220. }, 'server');
  221. }
  222. event.phases.forEach(function (p) {
  223. if ((p.destroy) && (!p.destroyed)) {
  224. p.destroyed = true;
  225. p.destroy();
  226. }
  227. });
  228. delete config.event;
  229. },
  230. handleNotification: function (event, { msg, desc, event: triggerEvent }) {
  231. if (msg) {
  232. this.instance.syncer.queue('serverModule', {
  233. module: 'cons',
  234. method: 'emit',
  235. msg: [
  236. 'event',
  237. {
  238. event: 'onGetMessages',
  239. data: {
  240. messages: {
  241. class: 'color-pinkA',
  242. message: msg
  243. }
  244. }
  245. }
  246. ]
  247. }, 'server');
  248. }
  249. if (desc) {
  250. event.config.descTimer = desc;
  251. this.setEventDescription(event.config.name);
  252. }
  253. if (triggerEvent && event.config.events[triggerEvent])
  254. event.config.events[triggerEvent](this, event);
  255. },
  256. updateEvent: function (event) {
  257. const onTick = _.getDeepProperty(event, ['config', 'events', 'onTick']);
  258. if (onTick)
  259. onTick(this, event);
  260. let objects = event.objects;
  261. let oLen = objects.length;
  262. for (let i = 0; i < oLen; i++) {
  263. if (objects[i].destroyed) {
  264. objects.splice(i, 1);
  265. i--;
  266. oLen--;
  267. }
  268. }
  269. let currentPhases = event.phases;
  270. let cLen = currentPhases.length;
  271. let stillBusy = false;
  272. for (let i = 0; i < cLen; i++) {
  273. let phase = currentPhases[i];
  274. if (!phase.destroyed) {
  275. if (phase.end || (phase.endMark !== -1 && phase.endMark <= event.age)) {
  276. if ((phase.destroy) && (!phase.destroyed))
  277. phase.destroy();
  278. phase.destroyed = true;
  279. continue;
  280. } else {
  281. if (phase.has('ttl')) {
  282. if (phase.ttl === 0) {
  283. phase.end = true;
  284. continue;
  285. }
  286. phase.ttl--;
  287. stillBusy = true;
  288. } else if (!phase.auto)
  289. stillBusy = true;
  290. phase.update(event);
  291. }
  292. }
  293. }
  294. const notifications = event.config.notifications || [];
  295. notifications.forEach(n => {
  296. if (n.mark === event.age)
  297. this.handleNotification(event, n);
  298. });
  299. event.age++;
  300. if (event.age === event.config.duration)
  301. event.done = true;
  302. else if ((event.config.prizeTime) && (event.age === event.config.prizeTime))
  303. this.giveRewards(event.config);
  304. if (stillBusy)
  305. return;
  306. let config = event.config;
  307. let phases = config.phases;
  308. let pLen = phases.length;
  309. for (let i = event.nextPhase; i < pLen; i++) {
  310. let p = phases[i];
  311. let phase = event.phases[i];
  312. if (!phase) {
  313. let phaseFile = 'phase' + p.type[0].toUpperCase() + p.type.substr(1);
  314. let typeTemplate = require('./phases/' + phaseFile);
  315. phase = extend({
  316. instance: this.instance,
  317. event: event
  318. }, phaseTemplate, typeTemplate, p);
  319. event.phases.push(phase);
  320. event.currentPhase = phase;
  321. }
  322. event.nextPhase = i + 1;
  323. phase.init(event);
  324. if (!p.auto) {
  325. stillBusy = true;
  326. break;
  327. }
  328. }
  329. if ((event.nextPhase >= pLen) && (!stillBusy))
  330. event.done = true;
  331. let oList = this.instance.objects.objects;
  332. oLen = oList.length;
  333. for (let i = 0; i < oLen; i++) {
  334. let o = oList[i];
  335. if (!o.player)
  336. continue;
  337. o.events.events.afterMove.call(o.events);
  338. }
  339. },
  340. getCloseEvents: function (obj) {
  341. let x = obj.x;
  342. let y = obj.y;
  343. let configs = this.configs;
  344. if (!configs)
  345. return;
  346. let cLen = configs.length;
  347. let result = [];
  348. for (let i = 0; i < cLen; i++) {
  349. let event = configs[i].event;
  350. if (!event)
  351. continue;
  352. let exists = event.participators.find(p => (p.name === obj.name));
  353. if (exists) {
  354. event.participators.spliceWhere(p => (p === exists));
  355. event.participators.push(obj);
  356. result.push(event);
  357. continue;
  358. }
  359. let distance = event.config.distance;
  360. if (distance === -1) {
  361. event.participators.push(obj);
  362. result.push(event);
  363. if (event.config.events && event.config.events.onParticipantJoin)
  364. event.config.events.onParticipantJoin(this, obj);
  365. continue;
  366. }
  367. let objects = event.objects;
  368. let oLen = objects.length;
  369. for (let j = 0; j < oLen; j++) {
  370. let o = objects[j];
  371. if (
  372. (distance === -1) ||
  373. (!distance) ||
  374. (
  375. (Math.abs(x - o.x) < distance) &&
  376. (Math.abs(y - o.y) < distance)
  377. )
  378. ) {
  379. event.participators.push(obj);
  380. result.push(event);
  381. if (event.config.events && event.config.events.onParticipantJoin)
  382. event.config.events.onParticipantJoin(this, obj);
  383. break;
  384. }
  385. }
  386. }
  387. return result;
  388. }
  389. };