From 6e952983c78138c5e7f730d3e0ba70e06b473042 Mon Sep 17 00:00:00 2001 From: cha0s Date: Thu, 12 Dec 2019 19:27:19 -0600 Subject: [PATCH] refactor: damage -> harm --- TODO.md | 8 +- client/app.js | 4 +- .../{damage.packet.js => harm.packet.js} | 6 +- .../{damaging.trait.js => harmful.trait.js} | 65 +++++----- common/combat/vulnerable.trait.js | 118 +++++++++--------- server/fixtures/blue-fire.entity.js | 2 +- server/fixtures/fire.entity.js | 6 +- server/fixtures/kitty-fire.room.js | 15 ++- server/fixtures/kitty.entity.js | 12 ++ server/fixtures/potion.entity.js | 6 +- server/fixtures/rock-projectile.entity.js | 14 +-- 11 files changed, 137 insertions(+), 119 deletions(-) rename common/combat/{damage.packet.js => harm.packet.js} (72%) rename common/combat/{damaging.trait.js => harmful.trait.js} (68%) diff --git a/TODO.md b/TODO.md index 7b43a57..453c338 100644 --- a/TODO.md +++ b/TODO.md @@ -1,10 +1,14 @@ # TODO - ✔ React UI -- ❌ Multiple rooms - ✔ Send relevant entity URIs to client; cache and use instead of full transfer - ✔ Forget remembered entities after a while - ✔ Optimize informed and Packer::pack: don't use .map on immutables -- ✔ Optimize Damaging::tick +- ✔ Optimize Harmful::tick - ✔ Manual state sync - ✔ Informed tracks seen entities (etc?), responsible for upgrading updates +- ❌ Multiple rooms +- ✔ Refactor input to send serial actions +- ✔ "use" action +- ❌ chat + diff --git a/client/app.js b/client/app.js index 4948e22..c9cfe07 100644 --- a/client/app.js +++ b/client/app.js @@ -448,8 +448,8 @@ export class App extends decorate(class {}) { } renderIntoDom(node) { - // Maintain damage element. - const promise = this.stage.findUiElement('.damage'); + // Maintain harm element. + const promise = this.stage.findUiElement('.harm'); promise.then((inner) => { const innerStyles = () => { const {realOffset} = this.stage.camera; diff --git a/common/combat/damage.packet.js b/common/combat/harm.packet.js similarity index 72% rename from common/combat/damage.packet.js rename to common/combat/harm.packet.js index 326b2c8..aa33626 100644 --- a/common/combat/damage.packet.js +++ b/common/combat/harm.packet.js @@ -1,6 +1,6 @@ import {Packet} from '@avocado/net'; -export class DamagePacket extends Packet { +export class HarmPacket extends Packet { static get schema() { return { @@ -8,11 +8,11 @@ export class DamagePacket extends Packet { data: [ { amount: 'varuint', - damageSpec: { + harmSpec: { affinity: 'uint8', }, from: 'uint32', - isDamage: 'bool', + isHarm: 'bool', }, ] } diff --git a/common/combat/damaging.trait.js b/common/combat/harmful.trait.js similarity index 68% rename from common/combat/damaging.trait.js rename to common/combat/harmful.trait.js index 2bac75f..d3d8dc1 100644 --- a/common/combat/damaging.trait.js +++ b/common/combat/harmful.trait.js @@ -7,66 +7,65 @@ import {fromRad, normalizeAngleRange, Vector} from '@avocado/math'; import {AFFINITY_PHYSICAL} from './constants'; const decorate = compose( - StateProperty('isDamaging'), + StateProperty('isHarmful'), ); -export class Damaging extends decorate(Trait) { +export class Harmful extends decorate(Trait) { static defaultParams() { return { - damagingSound: '', - damageSpecs: [], + harmfulSound: '', + harmSpecs: [], }; } static defaultState() { return { - isDamaging: true, + isHarmful: true, }; } static type() { - return 'damaging'; + return 'harmful'; } constructor(entity, params, state) { super(entity, params, state); - this._doesNotDamage = []; - const damageSpecsJSON = this.params.damageSpecs; - this._damageSpecs = damageSpecsJSON.map((damageSpec) => { + this._doesNotHarm = []; + const harmSpecsJSON = this.params.harmSpecs; + this._harmSpecs = harmSpecsJSON.map((harmSpec) => { return { - affinity: AFFINITY_PHYSICAL, lock: 0.1, power: 0, variance: 0.2, - ...damageSpec, + ...harmSpec, }; }); - this._damagingSound = this.params.damagingSound; + this._harmfulSound = this.params.harmfulSound; } - doesNotDamageEntity(entity) { - if (!this.entity.isDamaging) { + doesNotHarmEntity(entity) { + if (!this.entity.isHarmful) { return true; } - return -1 !== this._doesNotDamage.indexOf(entity); + return -1 !== this._doesNotHarm.indexOf(entity); } - get damageSpecs() { - return this._damageSpecs; + get harmSpecs() { + return this._harmSpecs; } - get damagingSound() { - return this._damagingSound; + get harmfulSound() { + return this._harmfulSound; } - tryDamagingEntity(entity) { - if (this.doesNotDamageEntity(entity)) { + tryHarmfulEntity(entity) { + if (this.doesNotHarmEntity(entity)) { return; } if (entity.is('vulnerable')) { if (!entity.isInvulnerable) { - entity.takeDamageFrom(this.entity); + entity.takeHarmFrom(this.entity); } } } @@ -76,7 +75,7 @@ export class Damaging extends decorate(Trait) { particles: () => { return { - damaging: { + harmful: { traits: { emitted: { params: { @@ -115,7 +114,7 @@ export class Damaging extends decorate(Trait) { const listeners = {}; if (AVOCADO_SERVER) { listeners.collisionStart = (other) => { - this.tryDamagingEntity(other); + this.tryHarmfulEntity(other); }; } return listeners; @@ -124,14 +123,14 @@ export class Damaging extends decorate(Trait) { methods() { return { - emitDamagingParticles: (other, json = {}) => { + emitHarmfulParticles: (other, json = {}) => { const diff = Vector.sub(this.entity.position, other.position); const velocityAngle = Vector.toAngle(Vector.normalize(diff)); const [fromAngle, toAngle] = normalizeAngleRange( velocityAngle - Math.PI / 8, velocityAngle + Math.PI / 8, ); - this.entity.emitParticle('damaging', merge( + this.entity.emitParticle('harmful', merge( {}, { traits: { @@ -153,16 +152,16 @@ export class Damaging extends decorate(Trait) { )); }, - setDoesDamage: (entity) => { - const index = this._doesNotDamage.indexOf(entity); + setDoesHarm: (entity) => { + const index = this._doesNotHarm.indexOf(entity); if (-1 !== index) { - this._doesNotDamage.splice(index, 1); + this._doesNotHarm.splice(index, 1); } }, - setDoesNotDamage: (entity) => { - if (-1 === this._doesNotDamage.indexOf(entity)) { - this._doesNotDamage.push(entity); + setDoesNotHarm: (entity) => { + if (-1 === this._doesNotHarm.indexOf(entity)) { + this._doesNotHarm.push(entity); } }, @@ -174,7 +173,7 @@ export class Damaging extends decorate(Trait) { if (this.entity.is('collider')) { const isCollidingWith = this.entity.isCollidingWith; for (let i = 0; i < isCollidingWith.length; i++) { - this.tryDamagingEntity(isCollidingWith[i]); + this.tryHarmfulEntity(isCollidingWith[i]); } } } diff --git a/common/combat/vulnerable.trait.js b/common/combat/vulnerable.trait.js index dce32b9..6eaeca1 100644 --- a/common/combat/vulnerable.trait.js +++ b/common/combat/vulnerable.trait.js @@ -5,27 +5,27 @@ import { buildTraversal, Context, } from '@avocado/behavior'; -import {iterateForEach} from '@avocado/core'; +import {flatten, invokeHookFlat, iterateForEach} from '@avocado/core'; import {hasGraphics, TextNodeRenderer} from '@avocado/graphics'; import {randomNumber, Vector} from '@avocado/math'; -import {DamagePacket} from './damage.packet'; +import {HarmPacket} from './harm.packet'; export class Vulnerable extends Trait { static defaultParams() { - const emitDamage = buildInvoke(['entity', 'emitDamageParticles'], [ - buildTraversal(['damage']), + const emitHarm = buildInvoke(['entity', 'emitHarmParticles'], [ + buildTraversal(['harm']), ]); - const playDamagingSound = buildInvoke(['damage', 'from', 'playSound'], [ - buildTraversal(['damage', 'from', 'damagingSound']), + const playHarmfulSound = buildInvoke(['harm', 'from', 'playSound'], [ + buildTraversal(['harm', 'from', 'harmfulSound']), ]); return { - tookDamageActions: { + tookHarmActions: { type: 'actions', traversals: [ - emitDamage, - playDamagingSound, + emitHarm, + playHarmfulSound, ], }, modifiers: undefined, @@ -38,55 +38,55 @@ export class Vulnerable extends Trait { constructor(entity, params, state) { super(entity, params, state); - this.damageTickingPromises = []; - this.damages = []; + this.harmTickingPromises = []; + this.harms = []; this._isInvulnerable = false; this.locks = new Map(); - this._tookDamageActions = behaviorItemFromJSON( - this.params.tookDamageActions + this._tookHarmActions = behaviorItemFromJSON( + this.params.tookHarmActions ); } destroy() { this.locks.clear(); - this.damageTickingPromises = []; + this.harmTickingPromises = []; } - acceptDamage(damage) { + acceptHarm(harm) { const context = new Context({ - damage, + harm, entity: this.entity, }); - const tickingPromise = this._tookDamageActions.tickingPromise(context); + const tickingPromise = this._tookHarmActions.tickingPromise(context); tickingPromise.then(() => { context.destroy(); }); - this.damageTickingPromises.push(tickingPromise); - if (damage.from) { - damage.from.emitDamagingParticles(this.entity); + this.harmTickingPromises.push(tickingPromise); + if (harm.from) { + harm.from.emitHarmfulParticles(this.entity); } } acceptPacket(packet) { - if (packet instanceof DamagePacket) { + if (packet instanceof HarmPacket) { for (let i = 0; i < packet.data.length; ++i) { - const damage = packet.data[i]; + const harm = packet.data[i]; if (this.entity.is('listed') && this.entity.list) { - damage.from = this.entity.list.findEntity(damage.from); + harm.from = this.entity.list.findEntity(harm.from); } else { - damage.from = undefined; + harm.from = undefined; } - this.acceptDamage(damage); + this.acceptHarm(harm); } } } cleanPackets() { - this.damages = []; + this.harms = []; } - damageTextSize(amount) { + harmTextSize(amount) { const biggest = 16; const smallest = biggest / 2; const step = biggest / 6; @@ -113,8 +113,8 @@ export class Vulnerable extends Trait { } packets(informed) { - if (this.damages.length > 0) { - return new DamagePacket(this.damages); + if (this.harms.length > 0) { + return new HarmPacket(this.harms); } } @@ -123,7 +123,7 @@ export class Vulnerable extends Trait { particles: () => { return { - damage: { + harm: { traits: { darkened: { params: { @@ -242,9 +242,9 @@ export class Vulnerable extends Trait { this._isInvulnerable = isDying; }, - tookDamage: (damage) => { + tookHarm: (harm) => { if (AVOCADO_SERVER) { - this.damages.push(damage); + this.harms.push(harm); this.setDirty(); } }, @@ -255,10 +255,10 @@ export class Vulnerable extends Trait { methods() { return { - emitDamageParticles: (damage) => { - const {amount, isDamage} = damage; - const fill = isDamage ? '#FF0000' : '#00FF77'; - this.entity.emitParticle('damage', { + emitHarmParticles: (harm) => { + const {amount, isHarm} = harm; + const fill = isHarm ? '#FF0000' : '#00FF77'; + this.entity.emitParticle('harm', { traits: { textual: { state: { @@ -266,7 +266,7 @@ export class Vulnerable extends Trait { textStyle: { fill, fontFamily: 'joystix', - fontSize: this.damageTextSize(amount), + fontSize: this.harmTextSize(amount), strokeThickness: 2, }, }, @@ -279,23 +279,23 @@ export class Vulnerable extends Trait { }); }, - takeDamageFrom: (entity) => { - const damageSpecs = entity.damageSpecs; - for (let i = 0; i < damageSpecs.length; ++i) { - const damageSpec = damageSpecs[i]; - if (this.locks.has(damageSpec)) { + takeHarmFrom: (entity) => { + const harmSpecs = entity.harmSpecs; + for (let i = 0; i < harmSpecs.length; ++i) { + const harmSpec = harmSpecs[i]; + if (this.locks.has(harmSpec)) { continue; } - this.locks.set(damageSpec, damageSpec.lock); - let power = damageSpec.power; + this.locks.set(harmSpec, harmSpec.lock); + let power = harmSpec.power; // Check if vulnerable to this affinity. if (this.params.modifiers) { - if (damageSpec.affinity in this.params.modifiers) { - power *= this.params.modifiers[damageSpec.affinity]; + if (harmSpec.affinity in this.params.modifiers) { + power *= this.params.modifiers[harmSpec.affinity]; } } // Give any knockback. - if (damageSpec.knockback) { + if (harmSpec.knockback) { if ( this.entity.is('mobile') && this.entity.is('positioned') @@ -306,35 +306,35 @@ export class Vulnerable extends Trait { entity.position, ); const unit = Vector.normalize(difference) - const knockback = Vector.scale(unit, damageSpec.knockback); + const knockback = Vector.scale(unit, harmSpec.knockback); this.entity.applyMovement(knockback); } } - const variance = Math.random() * damageSpec.variance * 2 - damageSpec.variance; + const variance = Math.random() * harmSpec.variance * 2 - harmSpec.variance; const difference = power * variance; - // Account for variance past 0, so track if it's damage or not. + // Account for variance past 0, so track if it's harm or not. let amount = Math.round(power + difference); - let isDamage; + let isHarm; if (power < 0) { - isDamage = false; + isHarm = false; if (amount > 0) { amount = 0; } } else { - isDamage = true; + isHarm = true; if (amount < 0) { amount = 0; } } amount = Math.abs(amount); - const damage = { - isDamage, + const harm = { + isHarm, amount, - damageSpec, + harmSpec, from: entity.numericUid, }; - this.entity.emit('tookDamage', damage); + this.entity.emit('tookHarm', harm); } }, @@ -342,8 +342,8 @@ export class Vulnerable extends Trait { } tick(elapsed) { - for (let i = 0; i < this.damageTickingPromises.length; ++i) { - this.damageTickingPromises[i].tick(elapsed); + for (let i = 0; i < this.harmTickingPromises.length; ++i) { + this.harmTickingPromises[i].tick(elapsed); } if (AVOCADO_SERVER) { iterateForEach(this.locks.keys(), (key) => { diff --git a/server/fixtures/blue-fire.entity.js b/server/fixtures/blue-fire.entity.js index 606ba22..1f420f8 100644 --- a/server/fixtures/blue-fire.entity.js +++ b/server/fixtures/blue-fire.entity.js @@ -7,7 +7,7 @@ export function blueFireJSON() { const json = fireJSON(); json.traits.animated.params.animations.idle.uri = '/blue-fire.animation.json'; json.traits.existent.state.name = 'Blue fire'; - json.traits.damaging.params.damageSpecs[0].power = -15; + json.traits.harmful.params.harmSpecs[0].power = -15; json.traits.audible.params.sounds.fire.uri = '/blue-fire.sound.json'; return json; } diff --git a/server/fixtures/fire.entity.js b/server/fixtures/fire.entity.js index 94a3e1c..49ce114 100644 --- a/server/fixtures/fire.entity.js +++ b/server/fixtures/fire.entity.js @@ -32,10 +32,10 @@ export function fireJSON() { isSensor: true, }, }, - damaging: { + harmful: { params: { - damagingSound: 'fire', - damageSpecs: [ + harmfulSound: 'fire', + harmSpecs: [ { affinity: AFFINITY_FIRE, lock: 0.15, diff --git a/server/fixtures/kitty-fire.room.js b/server/fixtures/kitty-fire.room.js index 5037b37..7c013e8 100644 --- a/server/fixtures/kitty-fire.room.js +++ b/server/fixtures/kitty-fire.room.js @@ -67,14 +67,17 @@ export function kittyFireJSON() { // for (let i = 0; i < 30; ++i) { // addEntityWithRandomPosition('/flower-barrel.entity.json'); // } - for (let i = 0; i < 5; ++i) { - addEntityWithRandomPosition('/mama-kitty-spawner.entity.json'); + // for (let i = 0; i < 15; ++i) { + // addEntityWithRandomPosition('/mama-kitty-spawner.entity.json'); + // } + for (let i = 0; i < 50; ++i) { + addEntityWithRandomPosition('/kitty.entity.json'); } - // for (let i = 0; i < 50; ++i) { + // for (let i = 0; i < 150; ++i) { // addEntityWithRandomPosition('/fire.entity.json'); // } - for (let i = 0; i < 5; ++i) { - addEntityWithRandomPosition('/blue-fire.entity.json'); - } + // for (let i = 0; i < 5; ++i) { + // addEntityWithRandomPosition('/blue-fire.entity.json'); + // } return roomJSON; } diff --git a/server/fixtures/kitty.entity.js b/server/fixtures/kitty.entity.js index 0fec8db..5f41fbe 100644 --- a/server/fixtures/kitty.entity.js +++ b/server/fixtures/kitty.entity.js @@ -125,6 +125,18 @@ export function kittyJSON() { uri: '/yarn-ball.entity.json', }, }, + { + perc: 80, + json: { + uri: '/yarn-ball.entity.json', + }, + }, + { + perc: 90, + json: { + uri: '/yarn-ball.entity.json', + }, + }, ], }, }, diff --git a/server/fixtures/potion.entity.js b/server/fixtures/potion.entity.js index 8871648..b89fbe8 100644 --- a/server/fixtures/potion.entity.js +++ b/server/fixtures/potion.entity.js @@ -4,7 +4,7 @@ import {AFFINITY_NONE} from '../../common/combat/constants'; // Healing potion. export function potionJSON() { - const causeHealing = buildInvoke(['wielder', 'takeDamageFrom'], [ + const causeHealing = buildInvoke(['wielder', 'takeHarmFrom'], [ buildTraversal(['item']), ]); const decrement = buildInvoke( @@ -15,9 +15,9 @@ export function potionJSON() { ); return { traits: { - damaging: { + harmful: { params: { - damageSpecs: [ + harmSpecs: [ { affinity: AFFINITY_NONE, lock: 0, diff --git a/server/fixtures/rock-projectile.entity.js b/server/fixtures/rock-projectile.entity.js index cba309d..b13d279 100644 --- a/server/fixtures/rock-projectile.entity.js +++ b/server/fixtures/rock-projectile.entity.js @@ -4,7 +4,7 @@ import {AFFINITY_NONE} from '../../common/combat/constants'; // Projectile rock. export function rockProjectileJSON() { - // Set as not damaging to user. + // Set as not harmful to user. const setDoesNotCollideWith = buildInvoke( ['entity', 'setDoesNotCollideWith'], [ @@ -44,8 +44,8 @@ export function rockProjectileJSON() { ['entity', 'isColliding'], false, ); - const setIsNotDamaging = buildTraversal( - ['entity', 'isDamaging'], + const setIsNotHarmful = buildTraversal( + ['entity', 'isHarmful'], false, ); const fadeOutAndSlowDown = buildInvoke( @@ -114,7 +114,7 @@ export function rockProjectileJSON() { type: 'actions', traversals: [ setIsNotColliding, - setIsNotDamaging, + setIsNotHarmful, afterImpact, destroy, ], @@ -149,9 +149,9 @@ export function rockProjectileJSON() { isSensor: true, }, }, - damaging: { + harmful: { params: { - damageSpecs: [ + harmSpecs: [ { affinity: AFFINITY_NONE, knockback: 500, @@ -170,7 +170,7 @@ export function rockProjectileJSON() { emitter: { params: { particles: { - damaging: { + harmful: { rate: 0.0125, count: 5, traits: {