refactor: damage spec

This commit is contained in:
cha0s 2019-04-19 12:16:28 -05:00
parent 266eb840a7
commit 3f8c9b6af3
5 changed files with 100 additions and 78 deletions

View File

@ -16,12 +16,21 @@ const decorate = compose(
overflow: hidden;
}
.particle {
display: inline-block;
}
.particle .text {
display: inline-block;
font-family: monospace;
font-weight: bold;
text-shadow: 1px 1px 0px black;
}
.particle .text.fire.is-damage {
color: #FF1000;
text-shadow: -0.5px -0.5px 0px #FFFF00, 1px 1px black;
}
.particle .text.is-healing {
color: #00FF77;
text-shadow: -0.5px -0.5px 0px #0077FF, 1px 1px black;
}
`),
);

View File

@ -6,55 +6,32 @@ export class Damaging extends Trait {
static defaultParams() {
return {
affinities: [],
lock: 0.1,
power: 0,
variance: 0.2,
damageSpecs: [],
};
}
initialize() {
this._affinities = this.params.get('affinities').toJS();
this._collidingWith = [];
this._lock = this.params.get('lock');
this._power = this.params.get('power');
this._variance = this.params.get('variance');
const damageSpecsJSON = this.params.get('damageSpecs').toJS();
this._damageSpecs = damageSpecsJSON.map((damageSpec) => {
return {
affinity: 'physical',
lock: 0.1,
power: 0,
variance: 0.2,
...damageSpec,
};
});
}
get affinities() {
return this._affinities;
}
get lock() {
return this._lock;
}
get power() {
return this._power;
}
get variance() {
return this._variance;
}
listeners() {
return {
collisionEnd: (other) => {
const index = this._collidingWith.indexOf(other);
this._collidingWith.splice(index, 1);
},
collisionStart: (other) => {
this._collidingWith.push(other);
},
};
get damageSpecs() {
return this._damageSpecs;
}
tick(elapsed) {
for (let i = 0; i < this._collidingWith.length; ++i) {
const entity = this._collidingWith[i];
const isCollidingWith = this.entity.isCollidingWith;
for (let i = 0; i < isCollidingWith.length; ++i) {
const entity = isCollidingWith[i];
if (entity.is('vulnerable')) {
entity.takeDamageFrom(this.entity);
}

View File

@ -1,5 +1,35 @@
import {Proton, TextNode, TextNodeRenderer} from '@avocado/graphics';
class DamageTextNode extends TextNode {
constructor(damage) {
const {amount, damageSpec, isDamage} = damage;
super(amount);
// Big numbers are literally big.
if (amount > 999) {
this.span.style.fontSize = '2em';
}
else if (amount > 99) {
this.span.style.fontSize = '1.5em';
}
else if (amount > 9) {
this.span.style.fontSize = '1.2em';
}
else {
this.span.style.fontSize = '1em';
}
// Class by affinity and whether it's damage or healing.
this.span.className += ' ' + damageSpec.affinity;
if (isDamage) {
this.span.className += ' is-damage';
}
else {
this.span.className += ' is-healing';
}
}
}
export class DamageEmitter {
constructor() {
@ -15,13 +45,13 @@ export class DamageEmitter {
this.proton.addRender(this.renderer);
}
emit(position, amount) {
emit(position, damage) {
// BUGS
const pz = new Proton.PointZone();
pz.x = position[0];
pz.y = -position[1];
const initializers = [
new Proton.Body(new DamageTextNode(Math.abs(amount))),
new Proton.Body(new DamageTextNode(damage)),
new Proton.Position(pz),
new Proton.Mass(1),
new Proton.Life(2),
@ -36,7 +66,6 @@ export class DamageEmitter {
rot.a = new Proton.Span(-.005, .005);
const behaviors = [
new Proton.Alpha(1, .5),
new Proton.Color(amount < 0 ? 0x00ff00 : 0xff0000),
new Proton.Scale(.8, 1.2),
new Proton.Force(0, -1, 0),
rot,
@ -49,23 +78,3 @@ export class DamageEmitter {
}
}
export class DamageTextNode extends TextNode {
constructor(damage) {
super(damage);
if (damage > 999) {
this.span.style.fontSize = '2em';
}
else if (damage > 99) {
this.span.style.fontSize = '1.5em';
}
else if (damage > 9) {
this.span.style.fontSize = '1.2em';
}
else {
this.span.style.fontSize = '1em';
}
}
}

View File

@ -32,8 +32,8 @@ export class Vulnerable extends Trait {
switch (stateKeyParts[0]) {
case 'damageList':
for (let i = 0; i < value.length; ++i) {
const amount = value[i];
this.emitter.emit(this.entity.position, amount);
const damage = value[i];
this.emitter.emit(this.entity.position, damage);
}
break;
default:
@ -63,17 +63,40 @@ export class Vulnerable extends Trait {
return {
takeDamageFrom: (entity) => {
if (this.locks.has(entity)) {
return;
const damageSpecs = entity.damageSpecs;
for (let i = 0; i < damageSpecs.length; ++i) {
const damageSpec = damageSpecs[i];
if (this.locks.has(damageSpec)) {
return;
}
this.locks.set(damageSpec, damageSpec.lock);
const variance = Math.random() * damageSpec.variance * 2 - damageSpec.variance;
const difference = damageSpec.power * variance;
// Account for variance past 0, so track if it's damage or not.
let amount = Math.round(damageSpec.power + difference);
let isDamage;
if (damageSpec.power < 0) {
isDamage = false;
if (amount > 0) {
amount = 0;
}
}
else {
isDamage = true;
if (amount < 0) {
amount = 0;
}
}
amount = Math.abs(amount);
if (!this.damageList[entity.instanceUuid]) {
this.damageList[entity.instanceUuid] = [];
}
this.damageList[entity.instanceUuid].push({
isDamage,
amount,
damageSpec,
});
}
this.locks.set(entity, entity.lock);
const variance = Math.random() * entity.variance * 2 - entity.variance;
const difference = entity.power * variance;
const amount = (entity.power + difference) >> 0;
if (!this.damageList[entity.instanceUuid]) {
this.damageList[entity.instanceUuid] = [];
}
this.damageList[entity.instanceUuid].push(amount);
},
};

View File

@ -11,10 +11,14 @@ function fireJSON(position) {
},
damaging: {
params: {
affinities: ['fire'],
lock: 0.15,
power: 3,
variance: .5,
damageSpecs: [
{
affinity: 'fire',
lock: 0.15,
power: 5,
variance: 0.25,
},
],
},
},
existent: {},