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.
 
 
 

310 lines
5.8 KiB

  1. const effectTemplate = require('../config/effects/effectTemplate');
  2. module.exports = {
  3. type: 'effects',
  4. effects: [],
  5. nextId: 0,
  6. ccResistances: {
  7. stunned: 0,
  8. slowed: 0
  9. },
  10. init: function (blueprint) {
  11. let effects = blueprint.effects || [];
  12. let eLen = effects.length;
  13. for (let i = 0; i < eLen; i++) {
  14. let e = effects[i];
  15. if (!e.type)
  16. continue;
  17. this.addEffect(e);
  18. }
  19. delete blueprint.effects;
  20. },
  21. transfer: function () {
  22. let transferEffects = this.effects;
  23. this.effects = [];
  24. this.init({
  25. effects: transferEffects
  26. });
  27. },
  28. save: function () {
  29. let e = {
  30. type: 'effects',
  31. effects: this.effects
  32. .map(f => f.save ? f.save() : f)
  33. .filter(f => !!f)
  34. };
  35. return e;
  36. },
  37. simplify: function (self) {
  38. let e = {
  39. type: 'effects'
  40. };
  41. let effects = this.effects;
  42. if ((effects.length > 0) && (effects[0].obj)) {
  43. effects = effects
  44. .map(f => f.simplify())
  45. .filter(f => !!f);
  46. }
  47. e.effects = effects;
  48. return e;
  49. },
  50. destroy: function () {
  51. if (this.obj.instance)
  52. this.events.beforeRezone.call(this);
  53. },
  54. die: function () {
  55. this.events.beforeRezone.call(this, true);
  56. },
  57. reset: function () {
  58. let effects = this.effects;
  59. let eLen = effects.length;
  60. for (let i = 0; i < eLen; i++) {
  61. let effect = effects[i];
  62. if (effect.reset)
  63. effect.reset();
  64. }
  65. },
  66. reapply: function () {
  67. let effects = this.effects;
  68. let eLen = effects.length;
  69. for (let i = 0; i < eLen; i++) {
  70. let effect = effects[i];
  71. if (effect.reapply)
  72. effect.reapply();
  73. }
  74. },
  75. events: {
  76. beforeRezone: function (forceDestroy) {
  77. let effects = this.effects;
  78. let eLen = effects.length;
  79. for (let i = 0; i < eLen; i++) {
  80. let effect = effects[i];
  81. if (!forceDestroy) {
  82. if (effect.persist) {
  83. this.syncRemove(effect.id, effect.type);
  84. continue;
  85. }
  86. }
  87. if (effect.destroy)
  88. effect.destroy();
  89. this.syncRemove(effect.id, effect.type);
  90. effects.splice(i, 1);
  91. eLen--;
  92. i--;
  93. }
  94. }
  95. },
  96. canApplyEffect: function (type) {
  97. if (!this.ccResistances[type])
  98. return true;
  99. let ccResistances = this.ccResistances;
  100. if ((100 - ccResistances[type]) >= 50) {
  101. ccResistances[type] += 50;
  102. return true;
  103. } return false;
  104. },
  105. addEffect: function (options, source) {
  106. if ((options.has('ttl')) && (options.ttl === 0))
  107. return;
  108. options.caster = options.caster || source;
  109. if (!this.canApplyEffect(options.type))
  110. return;
  111. if (!options.new) {
  112. let exists = this.effects.find(e => e.type === options.type);
  113. if (exists) {
  114. exists.ttl += options.ttl;
  115. for (let p in options) {
  116. if (p === 'ttl')
  117. continue;
  118. exists[p] = options[p];
  119. }
  120. return exists;
  121. }
  122. }
  123. let typeTemplate = null;
  124. if (options.type) {
  125. let type = options.type[0].toUpperCase() + options.type.substr(1);
  126. let result = {
  127. type: type,
  128. url: 'config/effects/effect' + type + '.js'
  129. };
  130. this.obj.instance.eventEmitter.emit('onBeforeGetEffect', result);
  131. typeTemplate = require('../' + result.url);
  132. }
  133. let builtEffect = extend({}, effectTemplate, typeTemplate);
  134. for (let p in options)
  135. builtEffect[p] = options[p];
  136. builtEffect.obj = this.obj;
  137. builtEffect.id = this.nextId++;
  138. builtEffect.noMsg = options.noMsg;
  139. if (builtEffect.init)
  140. builtEffect.init(options.source);
  141. this.effects.push(builtEffect);
  142. if (!options.noMsg) {
  143. this.obj.instance.syncer.queue('onGetBuff', {
  144. type: options.type,
  145. id: builtEffect.id
  146. }, [this.obj.serverId]);
  147. this.obj.instance.syncer.queue('onGetDamage', {
  148. id: this.obj.id,
  149. event: true,
  150. text: '+' + options.type
  151. }, -1);
  152. this.obj.syncer.setArray(false, 'effects', 'addEffects', options.type);
  153. }
  154. return builtEffect;
  155. },
  156. syncRemove: function (id, type, noMsg) {
  157. if ((noMsg) || (!type))
  158. return;
  159. this.obj.instance.syncer.queue('onRemoveBuff', {
  160. id: id
  161. }, [this.obj.serverId]);
  162. this.obj.instance.syncer.queue('onGetDamage', {
  163. id: this.obj.id,
  164. event: true,
  165. text: '-' + type
  166. }, -1);
  167. this.obj.syncer.setArray(false, 'effects', 'removeEffects', type);
  168. },
  169. removeEffect: function (checkEffect, noMsg) {
  170. let effects = this.effects;
  171. let eLen = effects.length;
  172. for (let i = 0; i < eLen; i++) {
  173. let effect = effects[i];
  174. if (effect === checkEffect) {
  175. if (effect.destroy)
  176. effect.destroy();
  177. this.syncRemove(effect.id, effect.type, noMsg || effect.noMsg);
  178. effects.splice(i, 1);
  179. if (effect.destroy)
  180. effect.destroy();
  181. return;
  182. }
  183. }
  184. },
  185. removeEffectByName: function (effectName, noMsg) {
  186. let effects = this.effects;
  187. let eLen = effects.length;
  188. for (let i = 0; i < eLen; i++) {
  189. let effect = effects[i];
  190. if (effect.type === effectName) {
  191. this.syncRemove(effect.id, effect.type, noMsg || effects.noMsg);
  192. effects.splice(i, 1);
  193. if (effect.destroy)
  194. effect.destroy();
  195. return effect;
  196. }
  197. }
  198. },
  199. fireEvent: function (event, args) {
  200. let effects = this.effects;
  201. let eLen = effects.length;
  202. for (let i = 0; i < eLen; i++) {
  203. let e = effects[i];
  204. //Maybe the effect killed us?
  205. if (!e) {
  206. i--;
  207. eLen--;
  208. continue;
  209. }
  210. if (e.ttl === 0)
  211. continue;
  212. let events = e.events;
  213. if (!events)
  214. continue;
  215. let callback = events[event];
  216. if (!callback)
  217. continue;
  218. callback.apply(e, args);
  219. }
  220. },
  221. update: function () {
  222. let effects = this.effects;
  223. let eLen = effects.length;
  224. for (let i = 0; i < eLen; i++) {
  225. let e = effects[i];
  226. if (e.ttl > 0) {
  227. e.ttl--;
  228. if (e.ttl === 0)
  229. e.destroyed = true;
  230. }
  231. if (e.update)
  232. e.update();
  233. if (e.destroyed) {
  234. effects.splice(i, 1);
  235. eLen--;
  236. i--;
  237. if (e.destroy)
  238. e.destroy();
  239. this.syncRemove(e.id, e.type, e.noMsg);
  240. }
  241. }
  242. for (let p in this.ccResistances) {
  243. if (this.ccResistances[p] > 0)
  244. this.ccResistances[p]--;
  245. }
  246. }
  247. };