refactor: harm/vuln yin yang

This commit is contained in:
cha0s 2020-04-22 23:33:17 -05:00
parent f4517f4b50
commit dfb74b5eeb
2 changed files with 68 additions and 60 deletions

View File

@ -1,8 +1,6 @@
import * as I from 'immutable'; import {compose} from '@avocado/core';
import {compose, invokeHookFlat, iterateForEach, merge} from '@avocado/core';
import {StateProperty, Trait} from '@avocado/entity'; import {StateProperty, Trait} from '@avocado/entity';
import {fromRad, normalizeAngleRange, Vector} from '@avocado/math'; import {Vector} from '@avocado/math';
import {AFFINITY_PHYSICAL} from './constants'; import {AFFINITY_PHYSICAL} from './constants';
@ -32,8 +30,6 @@ export class Harmful extends decorate(Trait) {
constructor(entity, params, state) { constructor(entity, params, state) {
super(entity, params, state); super(entity, params, state);
this._doesNotHarm = [];
this.locks = new Map();
this._harmSpecs = this.params.harmSpecs.map((harmSpec) => { this._harmSpecs = this.params.harmSpecs.map((harmSpec) => {
return { return {
power: 0, 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() { hooks() {
return { return {
@ -110,7 +84,7 @@ export class Harmful extends decorate(Trait) {
const listeners = {}; const listeners = {};
if (AVOCADO_SERVER) { if (AVOCADO_SERVER) {
listeners.collisionStart = (other) => { listeners.collisionStart = (other) => {
this.tryHarmingEntity(other); this.entity.harm(other);
}; };
} }
return listeners; return listeners;
@ -120,11 +94,17 @@ export class Harmful extends decorate(Trait) {
return { return {
harm: (entity) => { harm: (entity) => {
if (this.locks.has(entity)) { if (!this.entity.isHarmful) {
return; return;
} }
if (this.params.harmLock > 0) { if (!entity.is('vulnerable')) {
this.locks.set(entity, this.params.harmLock); 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) { for (let i = 0; i < this._harmSpecs.length; ++i) {
const {power, type, variance} = this._harmSpecs[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')) { if (this.entity.is('collider')) {
const isCollidingWith = this.entity.isCollidingWith; const isCollidingWith = this.entity.isCollidingWith;
for (let i = 0; i < isCollidingWith.length; i++) { 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);
}
});
} }
} }

View File

@ -1,13 +1,13 @@
import {Trait} from '@avocado/entity'; import {Trait} from '@avocado/entity';
import { import {
behaviorItemFromJSON, behaviorItemFromJSON,
buildInvoke,
buildTraversal,
Context, Context,
} from '@avocado/behavior'; } from '@avocado/behavior';
import {arrayUnique, flatten, invokeHookFlat} from '@avocado/core'; import {
import {hasGraphics, TextNodeRenderer} from '@avocado/graphics'; arrayUnique,
import {randomNumber, Vector} from '@avocado/math'; invokeHookFlat,
iterateForEach,
} from '@avocado/core';
import {harmInteractions} from './harm'; import {harmInteractions} from './harm';
import {HarmPacket} from './harm.packet'; import {HarmPacket} from './harm.packet';
@ -29,6 +29,12 @@ export class Vulnerable extends Trait {
super(entity, params, state); super(entity, params, state);
this._harms = []; this._harms = [];
this._isInvulnerable = false; this._isInvulnerable = false;
this._isNotHarmedBy = [];
this.locks = new Map();
}
destroy() {
this.locks.clear();
} }
acceptHarm(harm) { acceptHarm(harm) {
@ -272,6 +278,36 @@ export class Vulnerable extends Trait {
methods() { methods() {
return { 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: () => { vulnerabilityTypes: () => {
const hookTypes = this.entity.invokeHookFlat('vulnerabilityTypes'); const hookTypes = this.entity.invokeHookFlat('vulnerabilityTypes');
return arrayUnique(hookTypes.concat(this.params.types)); 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);
}
});
}
}
} }