humus-old/common/damage/vulnerable.trait.js

109 lines
2.5 KiB
JavaScript

import * as I from 'immutable';
import {Trait} from '@avocado/entity';
import {hasGraphics, TextNodeRenderer} from '@avocado/graphics';
import {DamageEmitter} from './emitter';
export class Vulnerable extends Trait {
static defaultState() {
return {
damageList: I.Map(),
};
}
initialize() {
this.damageList = {};
this.locks = new Map();
if (hasGraphics) {
this.emitter = new DamageEmitter();
this.setRenderer();
}
}
patchStateStep(key, step) {
if ('state' !== key) {
return;
}
const stateKey = step.path.substr(1);
const value = this.transformPatchValue(stateKey, step.value);
const stateKeyParts = stateKey.split('/');
switch (stateKeyParts[0]) {
case 'damageList':
for (let i = 0; i < value.length; ++i) {
const amount = value[i];
this.emitter.emit(this.entity.position, amount);
}
break;
default:
super.patchStateStep(key, step);
break;
}
}
setRenderer() {
if (this.entity.is('staged') && this.entity.stage) {
const renderer = new TextNodeRenderer('.damage', this.entity.stage);
this.emitter.addRenderer(renderer);
}
}
listeners() {
return {
stageChanged: () => {
this.setRenderer();
},
};
}
methods() {
return {
takeDamageFrom: (entity) => {
if (this.locks.has(entity)) {
return;
}
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);
},
};
}
tick(elapsed) {
if (this.state.get('damageList').size > 0) {
this.state = this.state.set('damageList', I.Map());
}
if (Object.keys(this.damageList).length > 0) {
this.state = this.state.set('damageList', I.Map(this.damageList));
this.isDirty = true;
this.damageList = {};
}
if (hasGraphics) {
this.emitter.tick(elapsed);
}
const keys = Array.from(this.locks.keys());
for (let i = 0; i < keys.length; ++i) {
const key = keys[i];
const remaining = this.locks.get(key) - elapsed;
if (remaining <= 0) {
this.locks.delete(key);
}
else {
this.locks.set(key, remaining);
}
}
}
}