diff --git a/common/combat/harmful.trait.js b/common/combat/harmful.trait.js index 43f2742..6ec9cfe 100644 --- a/common/combat/harmful.trait.js +++ b/common/combat/harmful.trait.js @@ -1,8 +1,6 @@ -import * as I from 'immutable'; - -import {compose, invokeHookFlat, iterateForEach, merge} from '@avocado/core'; +import {compose} from '@avocado/core'; import {StateProperty, Trait} from '@avocado/entity'; -import {fromRad, normalizeAngleRange, Vector} from '@avocado/math'; +import {Vector} from '@avocado/math'; import {AFFINITY_PHYSICAL} from './constants'; @@ -32,8 +30,6 @@ export class Harmful extends decorate(Trait) { constructor(entity, params, state) { super(entity, params, state); - this._doesNotHarm = []; - this.locks = new Map(); this._harmSpecs = this.params.harmSpecs.map((harmSpec) => { return { power: 0, @@ -44,28 +40,6 @@ export class Harmful extends decorate(Trait) { }); } - destroy() { - this.locks.clear(); - } - - doesNotHarmEntity(entity) { - if (!this.entity.isHarmful) { - return true; - } - return -1 !== this._doesNotHarm.indexOf(entity); - } - - tryHarmingEntity(entity) { - if (this.doesNotHarmEntity(entity)) { - return; - } - if (entity.is('vulnerable')) { - if (!entity.isInvulnerable) { - this.entity.harm(entity); - } - } - } - hooks() { return { @@ -110,7 +84,7 @@ export class Harmful extends decorate(Trait) { const listeners = {}; if (AVOCADO_SERVER) { listeners.collisionStart = (other) => { - this.tryHarmingEntity(other); + this.entity.harm(other); }; } return listeners; @@ -120,11 +94,17 @@ export class Harmful extends decorate(Trait) { return { harm: (entity) => { - if (this.locks.has(entity)) { + if (!this.entity.isHarmful) { return; } - if (this.params.harmLock > 0) { - this.locks.set(entity, this.params.harmLock); + if (!entity.is('vulnerable')) { + return; + } + if (!entity.isHarmedBy(this.entity)) { + return; + } + if (!entity.ensureVulnerabilityLock(this.entity, this.params.harmLock)) { + return; } for (let i = 0; i < this._harmSpecs.length; ++i) { const {power, type, variance} = this._harmSpecs[i]; @@ -170,19 +150,6 @@ export class Harmful extends decorate(Trait) { } }, - setDoesHarm: (entity) => { - const index = this._doesNotHarm.indexOf(entity); - if (-1 !== index) { - this._doesNotHarm.splice(index, 1); - } - }, - - setDoesNotHarm: (entity) => { - if (-1 === this._doesNotHarm.indexOf(entity)) { - this._doesNotHarm.push(entity); - } - }, - }; } @@ -191,18 +158,9 @@ export class Harmful extends decorate(Trait) { if (this.entity.is('collider')) { const isCollidingWith = this.entity.isCollidingWith; for (let i = 0; i < isCollidingWith.length; i++) { - this.tryHarmingEntity(isCollidingWith[i]); + this.entity.harm(isCollidingWith[i]); } } - iterateForEach(this.locks.keys(), (key) => { - const remaining = this.locks.get(key) - elapsed; - if (remaining <= 0) { - this.locks.delete(key); - } - else { - this.locks.set(key, remaining); - } - }); } } diff --git a/common/combat/vulnerable.trait.js b/common/combat/vulnerable.trait.js index 9305170..3727250 100644 --- a/common/combat/vulnerable.trait.js +++ b/common/combat/vulnerable.trait.js @@ -1,13 +1,13 @@ import {Trait} from '@avocado/entity'; import { behaviorItemFromJSON, - buildInvoke, - buildTraversal, Context, } from '@avocado/behavior'; -import {arrayUnique, flatten, invokeHookFlat} from '@avocado/core'; -import {hasGraphics, TextNodeRenderer} from '@avocado/graphics'; -import {randomNumber, Vector} from '@avocado/math'; +import { + arrayUnique, + invokeHookFlat, + iterateForEach, +} from '@avocado/core'; import {harmInteractions} from './harm'; import {HarmPacket} from './harm.packet'; @@ -29,6 +29,12 @@ export class Vulnerable extends Trait { super(entity, params, state); this._harms = []; this._isInvulnerable = false; + this._isNotHarmedBy = []; + this.locks = new Map(); + } + + destroy() { + this.locks.clear(); } acceptHarm(harm) { @@ -272,6 +278,36 @@ export class Vulnerable extends Trait { methods() { return { + ensureVulnerabilityLock: (entity, duration) => { + if (this.locks.has(entity)) { + return false; + } + if (duration > 0) { + this.locks.set(entity, duration); + } + return true; + }, + + isHarmedBy: (entity) => { + if (this._isInvulnerable) { + return false; + } + return -1 === this._isNotHarmedBy.indexOf(entity); + }, + + setHarmedBy: (entity) => { + const index = this._isNotHarmedBy.indexOf(entity); + if (-1 !== index) { + this._isNotHarmedBy.splice(index, 1); + } + }, + + setNotHarmedBy: (entity) => { + if (-1 === this._isNotHarmedBy.indexOf(entity)) { + this._isNotHarmedBy.push(entity); + } + }, + vulnerabilityTypes: () => { const hookTypes = this.entity.invokeHookFlat('vulnerabilityTypes'); return arrayUnique(hookTypes.concat(this.params.types)); @@ -280,4 +316,18 @@ export class Vulnerable extends Trait { }; } + tick(elapsed) { + if (AVOCADO_SERVER) { + iterateForEach(this.locks.keys(), (key) => { + const remaining = this.locks.get(key) - elapsed; + if (remaining <= 0) { + this.locks.delete(key); + } + else { + this.locks.set(key, remaining); + } + }); + } + } + }