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.
 
 
 

119 lines
2.8 KiB

  1. //Imports
  2. const spellBaseTemplate = require('../spells/spellTemplate');
  3. //Helpers
  4. const getItemEffect = item => {
  5. return item.effects.find(e => (e.type === 'castSpellOnHit'));
  6. };
  7. const doesEventMatch = (firedEvent, eventCondition) => {
  8. if (
  9. !firedEvent ||
  10. (
  11. eventCondition.targetNotSelf === false &&
  12. firedEvent.target === firedEvent.source
  13. )
  14. )
  15. return false;
  16. const foundNonMatch = Object.entries(eventCondition).some(([k, v]) => {
  17. if (v !== null && typeof(v) === 'object') {
  18. if (!doesEventMatch(firedEvent[k], v))
  19. return true;
  20. return false;
  21. }
  22. return firedEvent[k] !== v;
  23. });
  24. return !foundNonMatch;
  25. };
  26. const shouldApplyEffect = (itemEffect, firedEvent, firedEventName) => {
  27. const { rolls: { chance, combatEvent: { [firedEventName]: eventCondition } } } = itemEffect;
  28. if (!eventCondition || !doesEventMatch(firedEvent, eventCondition))
  29. return false;
  30. if (chance !== undefined && Math.random() * 100 >= chance)
  31. return false;
  32. return true;
  33. };
  34. const handler = (obj, item, event, firedEventName) => {
  35. const itemEffect = getItemEffect(item);
  36. if (!shouldApplyEffect(itemEffect, event, firedEventName))
  37. return;
  38. const { rolls: { castSpell, castTarget } } = itemEffect;
  39. const spellConfig = extend({}, castSpell);
  40. spellConfig.noEvents = true;
  41. const scaleDamage = spellConfig.scaleDamage;
  42. delete spellConfig.scaleDamage;
  43. if (scaleDamage) {
  44. if (scaleDamage.useOriginal) {
  45. scaleDamage.useOriginal.forEach(s => {
  46. spellConfig[s] = event.spell[s];
  47. });
  48. }
  49. if (scaleDamage.percentage)
  50. spellConfig.damage *= (scaleDamage.percentage / 100);
  51. }
  52. const typeTemplate = {
  53. type: spellConfig.type[0].toUpperCase() + spellConfig.type.substr(1),
  54. template: null
  55. };
  56. obj.instance.eventEmitter.emit('onBeforeGetSpellTemplate', typeTemplate);
  57. if (!typeTemplate.template)
  58. typeTemplate.template = require('../spells/spell' + typeTemplate.type);
  59. const builtSpell = extend({ obj }, spellBaseTemplate, typeTemplate.template, spellConfig);
  60. let target = event.target;
  61. if (castTarget === 'self')
  62. target = obj;
  63. else if (castTarget === 'none')
  64. target = undefined;
  65. //Need to write a generic way to apply these
  66. else if (castTarget === '{{event.oldPos}}')
  67. target = extend({}, event.oldPos);
  68. else if (JSON.stringify(castTarget) === '{"x":"{{event.follower.x}}","y":"{{event.follower.y}}"}') {
  69. target = {
  70. x: event.follower.x,
  71. y: event.follower.y
  72. };
  73. }
  74. builtSpell.cast({ target });
  75. };
  76. //Effect
  77. module.exports = {
  78. events: {
  79. afterGiveHp: function (item, event) {
  80. handler(this, item, event, 'afterGiveHp');
  81. },
  82. afterDealDamage: function (item, event) {
  83. handler(this, item, event, 'afterDealDamage');
  84. },
  85. afterPositionChange: function (item, event) {
  86. handler(this, item, event, 'afterPositionChange');
  87. },
  88. afterFollowerDeath: function (item, event) {
  89. handler(this, item, event, 'afterFollowerDeath');
  90. }
  91. }
  92. };