You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

340 lines
6.9 KiB

  1. let phaseTemplate = require('../config/eventPhases/phaseTemplate');
  2. let fs = require('fs');
  3. module.exports = {
  4. configs: [],
  5. nextId: 0,
  6. init: function (instance) {
  7. this.instance = instance;
  8. let path = 'config/maps/' + this.instance.map.name + '/events';
  9. if (!fs.existsSync(path))
  10. return;
  11. let files = fs.readdirSync(path)
  12. .map(f => ('../' + path + '/' + f));
  13. this.instance.eventEmitter.emit('onBeforeGetEventList', this.instance.map.name, files);
  14. files.forEach(function (f) {
  15. let e = require(f);
  16. if (!e.disabled)
  17. this.configs.push(extend(true, {}, e));
  18. }, this);
  19. },
  20. getEvent: function (name) {
  21. return this.configs.find(c => (c.name === name)).event.config;
  22. },
  23. setEventDescription: function (name, desc) {
  24. let config = this.getEvent(name);
  25. let event = config.event;
  26. if (!event)
  27. return;
  28. if (!config.oldDescription)
  29. config.oldDescription = config.description;
  30. if ((config.events) && (config.events.beforeSetDescription))
  31. config.events.beforeSetDescription(this);
  32. if (desc)
  33. config.description = desc;
  34. event.participators.forEach(p => p.events.syncList());
  35. },
  36. setEventRewards: function (name, rewards) {
  37. let config = this.getEvent(name);
  38. let event = config.event;
  39. if (!event)
  40. return;
  41. event.rewards = rewards;
  42. event.age = event.config.duration - 2;
  43. },
  44. setWinText: function (name, text) {
  45. let config = this.getEvent(name);
  46. let event = config.event;
  47. if (!event)
  48. return;
  49. event.winText = text;
  50. },
  51. update: function () {
  52. let configs = this.configs;
  53. if (!configs)
  54. return;
  55. let scheduler = this.instance.scheduler;
  56. let cLen = configs.length;
  57. for (let i = 0; i < cLen; i++) {
  58. let c = configs[i];
  59. if (c.event) {
  60. this.updateEvent(c.event);
  61. if (c.event.done)
  62. this.stopEvent(c);
  63. continue;
  64. } else if ((c.ttl) && (c.ttl > 0)) {
  65. c.ttl--;
  66. continue;
  67. } else if ((c.cron) && (!scheduler.shouldRun(c)))
  68. continue;
  69. c.event = this.startEvent(c);
  70. this.updateEvent(c.event);
  71. }
  72. },
  73. startEvent: function (config) {
  74. if (config.oldDescription)
  75. config.description = config.oldDescription;
  76. let event = {
  77. id: this.nextId++,
  78. config: extend(true, {}, config),
  79. phases: [],
  80. participators: [],
  81. objects: [],
  82. nextPhase: 0,
  83. age: 0
  84. };
  85. event.config.event = event;
  86. return event;
  87. },
  88. giveRewards: function (config) {
  89. let event = config.event;
  90. config.event.participators.forEach(function (p) {
  91. let rList = [{
  92. nameLike: 'Ancient Carp',
  93. removeAll: true
  94. }];
  95. let rewards = event.rewards;
  96. if ((rewards) && (rewards[p.name])) {
  97. rewards[p.name].forEach(r => rList.push(r));
  98. if (rList.length > 1)
  99. rList[1].msg = 'Fishing tournament reward:';
  100. }
  101. this.instance.mail.sendMail(p.name, rList);
  102. }, this);
  103. if ((config.events) && (config.events.afterGiveRewards))
  104. config.events.afterGiveRewards(this);
  105. },
  106. stopEvent: function (config) {
  107. let event = config.event;
  108. config.event.participators.forEach(function (p) {
  109. p.events.unregisterEvent(event);
  110. }, this);
  111. config.event.objects.forEach(function (o) {
  112. o.destroyed = true;
  113. this.instance.syncer.queue('onGetObject', {
  114. x: o.x,
  115. y: o.y,
  116. components: [{
  117. type: 'attackAnimation',
  118. row: 0,
  119. col: 4
  120. }]
  121. }, -1);
  122. }, this);
  123. if (event.winText) {
  124. this.instance.syncer.queue('onGetMessages', {
  125. messages: {
  126. class: 'color-pinkB',
  127. message: event.winText
  128. }
  129. }, -1);
  130. }
  131. event.phases.forEach(function (p) {
  132. if ((p.destroy) && (!p.destroyed)) {
  133. p.destroyed = true;
  134. p.destroy();
  135. }
  136. });
  137. delete config.event;
  138. },
  139. updateEvent: function (event) {
  140. let objects = event.objects;
  141. let oLen = objects.length;
  142. for (let i = 0; i < oLen; i++) {
  143. if (objects[i].destroyed) {
  144. objects.splice(i, 1);
  145. i--;
  146. oLen--;
  147. }
  148. }
  149. let currentPhases = event.phases;
  150. let cLen = currentPhases.length;
  151. let stillBusy = false;
  152. for (let i = 0; i < cLen; i++) {
  153. let phase = currentPhases[i];
  154. if (!phase.destroyed) {
  155. if ((phase.end) || (phase.endMark <= event.age)) {
  156. if ((phase.destroy) && (!phase.destroyed))
  157. phase.destroy();
  158. phase.destroyed = true;
  159. continue;
  160. } else {
  161. if (!phase.auto)
  162. stillBusy = true;
  163. phase.update();
  164. }
  165. }
  166. }
  167. if (event.config.notifications) {
  168. let n = event.config.notifications.find(f => (f.mark === event.age));
  169. if (n) {
  170. this.instance.syncer.queue('onGetMessages', {
  171. messages: {
  172. class: 'color-pinkB',
  173. message: n.msg
  174. }
  175. }, -1);
  176. if (n.desc !== null) {
  177. event.config.descTimer = n.desc;
  178. this.setEventDescription(event.config.name);
  179. }
  180. }
  181. }
  182. event.age++;
  183. if (event.age === event.config.duration)
  184. event.done = true;
  185. else if ((event.config.prizeTime) && (event.age === event.config.prizeTime))
  186. this.giveRewards(event.config);
  187. if (stillBusy)
  188. return;
  189. let config = event.config;
  190. let phases = config.phases;
  191. let pLen = phases.length;
  192. for (let i = event.nextPhase; i < pLen; i++) {
  193. let p = phases[i];
  194. let phaseFile = 'phase' + p.type[0].toUpperCase() + p.type.substr(1);
  195. let typeTemplate = require('../config/eventPhases/' + phaseFile);
  196. let phase = extend(true, {
  197. instance: this.instance,
  198. event: event
  199. }, phaseTemplate, typeTemplate, p);
  200. event.phases.push(phase);
  201. phase.init();
  202. event.nextPhase = i + 1;
  203. if (!p.auto) {
  204. stillBusy = true;
  205. break;
  206. }
  207. }
  208. if ((event.nextPhase >= pLen) && (!stillBusy))
  209. event.done = true;
  210. let oList = this.instance.objects.objects;
  211. oLen = oList.length;
  212. for (let i = 0; i < oLen; i++) {
  213. let o = oList[i];
  214. if (!o.player)
  215. continue;
  216. o.events.events.afterMove.call(o.events);
  217. }
  218. },
  219. getCloseEvents: function (obj) {
  220. let x = obj.x;
  221. let y = obj.y;
  222. let configs = this.configs;
  223. if (!configs)
  224. return;
  225. let cLen = configs.length;
  226. let result = [];
  227. for (let i = 0; i < cLen; i++) {
  228. let event = configs[i].event;
  229. if (!event)
  230. continue;
  231. let exists = event.participators.find(p => (p.name === obj.name));
  232. if (exists) {
  233. event.participators.spliceWhere(p => (p === exists));
  234. event.participators.push(obj);
  235. result.push(event);
  236. continue;
  237. }
  238. let distance = event.config.distance;
  239. if (distance === -1) {
  240. event.participators.push(obj);
  241. result.push(event);
  242. let rList = [{
  243. nameLike: 'Ancient Carp',
  244. removeAll: true
  245. }];
  246. this.instance.mail.sendMail(obj.name, rList);
  247. continue;
  248. }
  249. let objects = event.objects;
  250. let oLen = objects.length;
  251. for (let j = 0; j < oLen; j++) {
  252. let o = objects[j];
  253. if (
  254. (distance === -1) ||
  255. (!distance) ||
  256. (
  257. (Math.abs(x - o.x) < distance) &&
  258. (Math.abs(y - o.y) < distance)
  259. )
  260. ) {
  261. event.participators.push(obj);
  262. result.push(event);
  263. let rList = [{
  264. nameLike: 'Ancient Carp',
  265. removeAll: true
  266. }];
  267. this.instance.mail.sendMail(obj.name, rList);
  268. break;
  269. }
  270. }
  271. }
  272. return result;
  273. }
  274. };