2020-06-23 11:19:59 -05:00
|
|
|
import {compose, flatten, mapObject} from '@avocado/core';
|
2019-04-14 20:21:52 -05:00
|
|
|
import {StateProperty, Trait} from '@avocado/entity';
|
2019-04-09 09:42:40 -05:00
|
|
|
|
2020-06-23 11:19:59 -05:00
|
|
|
import Actions from '../actions';
|
|
|
|
import compile from '../compile';
|
|
|
|
import Context from '../context';
|
2019-04-14 20:33:52 -05:00
|
|
|
|
2019-04-09 09:42:40 -05:00
|
|
|
const decorate = compose(
|
2019-06-05 20:12:45 -05:00
|
|
|
StateProperty('currentRoutine', {
|
|
|
|
track: true,
|
|
|
|
}),
|
|
|
|
StateProperty('isBehaving'),
|
2019-04-09 09:42:40 -05:00
|
|
|
);
|
|
|
|
|
2020-06-15 17:26:20 -05:00
|
|
|
export default class Behaved extends decorate(Trait) {
|
2019-04-09 09:42:40 -05:00
|
|
|
|
2020-06-23 11:19:59 -05:00
|
|
|
static behaviorTypes() {
|
2020-06-20 02:02:34 -05:00
|
|
|
return {
|
|
|
|
context: {
|
|
|
|
type: 'context',
|
|
|
|
label: 'Context',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-04-09 09:42:40 -05:00
|
|
|
static defaultParams() {
|
|
|
|
return {
|
|
|
|
routines: {},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
static defaultState() {
|
|
|
|
return {
|
|
|
|
currentRoutine: 'initial',
|
2019-06-05 20:12:45 -05:00
|
|
|
isBehaving: true,
|
2019-04-09 09:42:40 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-19 15:31:35 -05:00
|
|
|
static describeParams() {
|
|
|
|
return {
|
|
|
|
routines: {
|
|
|
|
type: 'routines',
|
|
|
|
label: 'Routines',
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-17 18:18:03 -05:00
|
|
|
static describeState() {
|
|
|
|
return {
|
|
|
|
isBehaving: {
|
|
|
|
type: 'bool',
|
|
|
|
label: 'Is behaving',
|
|
|
|
},
|
|
|
|
currentRoutine: {
|
|
|
|
type: 'string',
|
|
|
|
label: 'Current routine',
|
2020-06-25 10:50:15 -05:00
|
|
|
options: (entity) => (
|
|
|
|
Object.keys(entity.traitInstance('behaved').params.routines)
|
|
|
|
.reduce((r, key) => ({...r, [key]: key}), {})
|
|
|
|
),
|
2020-06-17 18:18:03 -05:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-05 04:26:35 -05:00
|
|
|
static type() {
|
|
|
|
return 'behaved';
|
|
|
|
}
|
|
|
|
|
2019-05-06 04:03:43 -05:00
|
|
|
constructor(entity, params, state) {
|
|
|
|
super(entity, params, state);
|
2019-09-08 06:04:31 -05:00
|
|
|
this._context = new Context({
|
2020-06-19 17:59:14 -05:00
|
|
|
entity: [this.entity, 'entity'],
|
2019-09-08 06:04:31 -05:00
|
|
|
});
|
2019-04-16 18:04:53 -05:00
|
|
|
this._currentRoutine = undefined;
|
2020-06-23 11:19:59 -05:00
|
|
|
this._routines = mapObject(
|
|
|
|
this.params.routines,
|
|
|
|
(routine) => new Actions(compile(routine))
|
|
|
|
);
|
2019-05-13 21:07:51 -05:00
|
|
|
this.updateCurrentRoutine(this.state.currentRoutine);
|
2019-04-09 09:42:40 -05:00
|
|
|
}
|
|
|
|
|
2019-04-30 17:11:41 -05:00
|
|
|
destroy() {
|
2019-09-08 04:33:13 -05:00
|
|
|
this._context.destroy();
|
2019-04-30 17:11:41 -05:00
|
|
|
this._currentRoutine = undefined;
|
|
|
|
this._routines = undefined;
|
|
|
|
}
|
|
|
|
|
2019-04-09 09:42:40 -05:00
|
|
|
get context() {
|
|
|
|
return this._context;
|
|
|
|
}
|
|
|
|
|
2019-05-06 04:03:43 -05:00
|
|
|
updateCurrentRoutine(currentRoutine) {
|
2020-06-23 11:19:59 -05:00
|
|
|
this._currentRoutine = this._routines[currentRoutine];
|
2019-04-16 18:04:53 -05:00
|
|
|
}
|
|
|
|
|
2019-04-09 09:42:40 -05:00
|
|
|
listeners() {
|
|
|
|
return {
|
|
|
|
|
2019-05-06 04:03:43 -05:00
|
|
|
currentRoutineChanged: (old, currentRoutine) => {
|
|
|
|
this.updateCurrentRoutine(currentRoutine);
|
2019-04-16 18:04:53 -05:00
|
|
|
},
|
|
|
|
|
2019-10-10 01:27:02 -05:00
|
|
|
isDyingChanged: (_, isDying) => {
|
|
|
|
this.entity.isBehaving = !isDying;
|
2019-04-09 09:42:40 -05:00
|
|
|
},
|
|
|
|
|
2020-06-22 04:25:58 -05:00
|
|
|
traitAdded: (type) => {
|
|
|
|
flatten(this.entity.invokeHookFlat('contextTypeHints'))
|
|
|
|
.forEach(([key, type]) => this._context.add(key, undefined, type));
|
|
|
|
},
|
|
|
|
|
2019-04-09 09:42:40 -05:00
|
|
|
};
|
|
|
|
}
|
2019-04-12 13:05:30 -05:00
|
|
|
|
|
|
|
tick(elapsed) {
|
2019-06-05 20:12:45 -05:00
|
|
|
if (AVOCADO_SERVER) {
|
|
|
|
if (this._currentRoutine && this.entity.isBehaving) {
|
2019-09-08 08:18:16 -05:00
|
|
|
this._currentRoutine.tick(this._context, elapsed);
|
2019-06-05 20:12:45 -05:00
|
|
|
}
|
2019-04-12 13:05:30 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-09 09:42:40 -05:00
|
|
|
}
|