|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 |
- const effectTemplate = require('../config/effects/effectTemplate');
-
- module.exports = {
- type: 'effects',
-
- effects: [],
- nextId: 0,
-
- ccResistances: {
- stunned: 0,
- slowed: 0
- },
-
- init: function (blueprint) {
- let effects = blueprint.effects || [];
- let eLen = effects.length;
- for (let i = 0; i < eLen; i++) {
- let e = effects[i];
- if (!e.type)
- continue;
-
- this.addEffect(e);
- }
-
- delete blueprint.effects;
- },
-
- transfer: function () {
- let transferEffects = this.effects;
- this.effects = [];
-
- this.init({
- effects: transferEffects
- });
- },
-
- save: function () {
- let e = {
- type: 'effects',
- effects: this.effects
- .map(f => f.save ? f.save() : f)
- .filter(f => !!f)
- };
-
- return e;
- },
-
- simplify: function (self) {
- let e = {
- type: 'effects'
- };
-
- let effects = this.effects;
- if ((effects.length > 0) && (effects[0].obj)) {
- effects = effects
- .map(f => f.simplify())
- .filter(f => !!f);
- }
- e.effects = effects;
-
- return e;
- },
-
- destroy: function () {
- if (this.obj.instance)
- this.events.beforeRezone.call(this);
- },
-
- die: function () {
- this.events.beforeRezone.call(this, true);
- },
-
- reset: function () {
- let effects = this.effects;
- let eLen = effects.length;
- for (let i = 0; i < eLen; i++) {
- let effect = effects[i];
-
- if (effect.reset)
- effect.reset();
- }
- },
-
- reapply: function () {
- let effects = this.effects;
- let eLen = effects.length;
- for (let i = 0; i < eLen; i++) {
- let effect = effects[i];
-
- if (effect.reapply)
- effect.reapply();
- }
- },
-
- destroyEffect: function (effect) {
- this.obj.fireEvent('beforeDestroyEffect', effect);
-
- if (effect.events && effect.events.beforeDestroy)
- effect.events.beforeDestroy(effect);
-
- if (effect.destroy)
- effect.destroy();
- },
-
- events: {
- beforeRezone: function (forceDestroy) {
- let effects = this.effects;
- let eLen = effects.length;
- for (let i = 0; i < eLen; i++) {
- let effect = effects[i];
- if (!forceDestroy) {
- if (effect.persist) {
- this.syncRemove(effect.id);
- continue;
- }
- }
-
- this.destroyEffect(effect);
-
- this.syncRemove(effect.id);
- effects.splice(i, 1);
- eLen--;
- i--;
- }
- }
- },
-
- canApplyEffect: function (type) {
- if (!this.ccResistances.has(type))
- return true;
-
- let ccResistances = this.ccResistances;
- if ((100 - ccResistances[type]) >= 50) {
- ccResistances[type] += 50;
- return true;
- } return false;
- },
-
- addEffect: function (options, source) {
- //Skip 0-duration effects
- if ((options.has('ttl')) && (options.ttl === 0))
- return;
-
- options.caster = options.caster || source;
-
- //"X of Y in Z" cc resist check
- if (!options.force && !this.canApplyEffect(options.type))
- return;
-
- let oldEffect = this.effects.find(e => e.type === options.type);
-
- //If there is no existing effect or the effect is not stackable, make a new effect
- if (!oldEffect || !oldEffect.shouldStack)
- return this.buildEffect(options);
-
- //If the effect is stackable and the new effect should stack, stack with the old effect
- let shouldStack = oldEffect.shouldStack(options);
- if (shouldStack && oldEffect.incrementStack) {
- oldEffect.incrementStack(options);
- return oldEffect;
- }
-
- //Otherwise make a new effect
- return this.buildEffect(options);
- },
-
- getTypeTemplate: function (type) {
- let typeTemplate = null;
- if (type) {
- let capitalizedType = type[0].toUpperCase() + type.substr(1);
- let result = {
- type: type,
- url: 'config/effects/effect' + capitalizedType + '.js'
- };
- this.obj.instance.eventEmitter.emit('onBeforeGetEffect', result);
-
- typeTemplate = require('../' + result.url);
- }
-
- let builtEffect = extend({}, effectTemplate, typeTemplate);
- return builtEffect;
- },
-
- buildEffect: function (options) {
- let builtEffect = this.getTypeTemplate(options.type);
-
- for (let p in options)
- builtEffect[p] = options[p];
-
- builtEffect.obj = this.obj;
- builtEffect.id = this.nextId++;
- builtEffect.silent = options.silent;
-
- if (builtEffect.init)
- builtEffect.init(options.source);
-
- this.effects.push(builtEffect);
-
- if (!options.silent)
- this.obj.syncer.setArray(false, 'effects', 'addEffects', builtEffect.simplify());
-
- this.obj.instance.eventEmitter.emit('onAddEffect', this.obj, builtEffect);
-
- return builtEffect;
- },
-
- syncExtend: function (id, data) {
- let effect = this.effects.find(e => e.id === id);
- if (!effect)
- return;
-
- //Never sync silent effects
- if (effect.silent)
- return;
-
- this.obj.syncer.setArray(false, 'effects', 'extendEffects', {
- id,
- data
- });
- },
-
- syncRemove: function (id) {
- let effect = this.effects.find(e => e.id === id);
-
- if (!effect)
- return;
-
- if (effect.silent)
- return;
-
- this.obj.syncer.setArray(false, 'effects', 'removeEffects', id);
- },
-
- removeEffect: function (id) {
- const effect = this.effects.find(e => e.id === id);
-
- //It's possible that something else has removed the effect
- if (!effect)
- return;
-
- this.destroyEffect(effect);
-
- this.syncRemove(effect.id);
-
- this.effects.spliceWhere(e => e.id === id);
- },
-
- removeEffectByType: function (type) {
- const effects = this.effects.filter(e => e.type === type);
-
- effects.forEach(e => this.removeEffect(e.id));
- },
-
- getEffectByType: function (effectType) {
- const effect = this.effects.find(e => e.type === effectType);
-
- return effect;
- },
-
- fireEvent: function (event, args) {
- let effects = this.effects;
- let eLen = effects.length;
- for (let i = 0; i < eLen; i++) {
- let e = effects[i];
-
- //Maybe the effect killed us?
- if (!e) {
- i--;
- eLen--;
- continue;
- }
-
- if (e.ttl === 0)
- continue;
- let events = e.events;
- if (!events)
- continue;
-
- let callback = events[event];
- if (!callback)
- continue;
-
- callback.apply(e, args);
- }
- },
-
- update: function () {
- let effects = this.effects;
- let eLen = effects.length;
- for (let i = 0; i < eLen; i++) {
- let e = effects[i];
-
- if (e.ttl > 0)
- e.ttl--;
- else if (e.ttl === 0)
- e.destroyed = true;
-
- if (e.update)
- e.update();
-
- if (e.destroyed) {
- this.destroyEffect(e);
-
- this.syncRemove(e.id);
-
- effects.splice(i, 1);
- eLen--;
- i--;
- }
- }
-
- for (let p in this.ccResistances) {
- if (this.ccResistances[p] > 0)
- this.ccResistances[p]--;
- }
- }
- };
|