2019-04-19 17:23:40 -05:00
|
|
|
import {behaviorItemFromJSON, createContext} from '@avocado/behavior';
|
2019-04-19 14:51:05 -05:00
|
|
|
import {compose} from '@avocado/core';
|
|
|
|
import {StateProperty, Trait} from '@avocado/entity';
|
|
|
|
|
|
|
|
const decorate = compose(
|
|
|
|
StateProperty('life', {
|
|
|
|
track: true,
|
|
|
|
}),
|
|
|
|
StateProperty('maxLife', {
|
|
|
|
track: true,
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
|
|
|
|
export class Alive extends decorate(Trait) {
|
|
|
|
|
2019-04-19 17:23:40 -05:00
|
|
|
static defaultParams() {
|
|
|
|
return {
|
|
|
|
deathActions: {
|
|
|
|
type: 'actions',
|
|
|
|
traversals: [
|
|
|
|
{
|
|
|
|
type: 'traversal',
|
|
|
|
steps: [
|
|
|
|
{
|
|
|
|
type: 'key',
|
|
|
|
key: 'entity',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'key',
|
|
|
|
key: 'transition',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'invoke',
|
|
|
|
args: [
|
|
|
|
{
|
|
|
|
type: 'literal',
|
|
|
|
value: {
|
|
|
|
opacity: 0,
|
|
|
|
visibleScaleX: .3,
|
|
|
|
visibleScaleY: 3,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'literal',
|
|
|
|
value: 0.2,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
// By default, die when life <= 0.
|
|
|
|
deathCondition: {
|
|
|
|
type: 'condition',
|
|
|
|
operator: '<=',
|
|
|
|
operands: [
|
|
|
|
{
|
|
|
|
type: 'traversal',
|
|
|
|
steps: [
|
|
|
|
{
|
|
|
|
type: 'key',
|
|
|
|
key: 'entity',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'key',
|
|
|
|
key: 'life',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'literal',
|
|
|
|
value: 0,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-04-19 14:51:05 -05:00
|
|
|
static defaultState() {
|
|
|
|
return {
|
|
|
|
life: 100,
|
|
|
|
maxLife: 100,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-04-19 17:23:40 -05:00
|
|
|
initialize() {
|
|
|
|
this._context = createContext();
|
|
|
|
this._context.add('entity', this.entity);
|
|
|
|
const actionsJSON = this.params.get('deathActions').toJS();
|
|
|
|
this._deathActions = behaviorItemFromJSON(actionsJSON);
|
|
|
|
const conditionJSON = this.params.get('deathCondition').toJS();
|
|
|
|
this._deathCondition = behaviorItemFromJSON(conditionJSON);
|
|
|
|
this._isDying = false;
|
|
|
|
}
|
|
|
|
|
2019-04-19 14:51:05 -05:00
|
|
|
listeners() {
|
|
|
|
return {
|
|
|
|
|
|
|
|
tookDamage: (damage) => {
|
|
|
|
this.entity.life -= damage.amount;
|
|
|
|
// Clamp health between 0 and max.
|
|
|
|
this.entity.life = Math.min(
|
|
|
|
Math.max(0, this.entity.life),
|
|
|
|
this.entity.maxLife
|
|
|
|
);
|
|
|
|
},
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-19 17:23:40 -05:00
|
|
|
methods() {
|
|
|
|
return {
|
2019-04-19 14:51:05 -05:00
|
|
|
|
2019-04-19 17:23:40 -05:00
|
|
|
die: () => {
|
|
|
|
this._isDying = true;
|
|
|
|
this.entity.emit('dying');
|
|
|
|
this._deathActions.on('actionsFinished', () => {
|
|
|
|
this.entity.destroy();
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
tick(elapsed) {
|
|
|
|
if (this._isDying) {
|
|
|
|
this._deathActions.tick(this._context, elapsed);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (this._deathCondition.check(this._context)) {
|
2019-04-19 14:51:05 -05:00
|
|
|
// It's a good day to die.
|
2019-04-19 17:23:40 -05:00
|
|
|
this.entity.die();
|
2019-04-19 14:51:05 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|