diff --git a/packages/entity/index.hooks.js b/packages/entity/index.hooks.js index 5d6247d..60e0496 100644 --- a/packages/entity/index.hooks.js +++ b/packages/entity/index.hooks.js @@ -1,15 +1,29 @@ export function behaviorContextTypes() { return { - entity: (entity) => ( - Object.values(entity.allTraitInstances()) - .reduce( - (r, {constructor: {behaviorContextTypes, describeParams, describeState}}) => ({ - ...r, - ...behaviorContextTypes(), - ...describeParams(), - ...describeState(), - }), {}, - ) - ), + entity: (entity) => { + const traitTypes = !entity + ? {} + : Object.values(entity.allTraitInstances()) + .reduce( + (r, {constructor: {behaviorContextTypes, describeParams, describeState}}) => ({ + ...r, + ...behaviorContextTypes(), + ...describeParams(), + ...describeState(), + }), {}, + ); + return { + ...traitTypes, + invokeHook: { + type: 'object', + label: 'Invoke hook.', + args: [ + ['hook', { + type: 'string', + }], + ], + }, + }; + }, }; } diff --git a/packages/entity/traits/existent.trait.js b/packages/entity/traits/existent.trait.js index bccb6c3..6dd129e 100644 --- a/packages/entity/traits/existent.trait.js +++ b/packages/entity/traits/existent.trait.js @@ -12,8 +12,16 @@ export default class Existent extends decorate(Trait) { static behaviorContextTypes() { return { + destroy: { + type: 'void', + label: 'Destroy', + }, + destroyGently: { + type: 'void', + label: 'Kill? Then destroy', + }, transition: { - type: 'ticking-promise', + type: 'void', label: 'Transition $1 for $2 seconds using $3.', args: [ ['props', { diff --git a/packages/entity/traits/perishable.trait.js b/packages/entity/traits/perishable.trait.js index b2997d1..bebb233 100644 --- a/packages/entity/traits/perishable.trait.js +++ b/packages/entity/traits/perishable.trait.js @@ -13,6 +13,15 @@ export default class Perishable extends decorate(Trait) { }; } + static describeParams() { + return { + ttl: { + type: 'number', + label: 'Time-to-live in seconds', + }, + }; + } + static type() { return 'perishable'; } diff --git a/packages/entity/traits/positioned.trait.js b/packages/entity/traits/positioned.trait.js index d2adadb..abb4037 100644 --- a/packages/entity/traits/positioned.trait.js +++ b/packages/entity/traits/positioned.trait.js @@ -19,6 +19,10 @@ export default class Positioned extends decorate(Trait) { static behaviorContextTypes() { return { + position: { + type: 'vector', + label: 'Position', + }, setPosition: { type: 'void', label: 'Set position to $1.', diff --git a/packages/entity/traits/spawner.trait.js b/packages/entity/traits/spawner.trait.js index 764262c..e080b63 100644 --- a/packages/entity/traits/spawner.trait.js +++ b/packages/entity/traits/spawner.trait.js @@ -15,6 +15,10 @@ export default class Spawner extends decorate(Trait) { static behaviorContextTypes() { return { + killAllChildren: { + type: 'void', + label: 'Kill all spawned children', + }, spawn: { type: 'entity', label: 'Spawn $1 with $2 extensions.', @@ -72,6 +76,15 @@ export default class Spawner extends decorate(Trait) { }; } + static describeParams() { + return { + spawns: { + type: 'object', + label: 'Entities that may be spawned', + }, + }; + } + static defaultState() { return { isSpawning: true, @@ -79,6 +92,19 @@ export default class Spawner extends decorate(Trait) { }; } + static describeState() { + return { + isSpawning: { + type: 'bool', + label: 'Is spawning', + }, + maxSpawns: { + type: 'number', + label: 'Maximum concurrent spawns', + }, + }; + } + static type() { return 'spawner'; } diff --git a/packages/graphics/traits/pictured.trait.js b/packages/graphics/traits/pictured.trait.js index 950f1b8..b2f99b6 100644 --- a/packages/graphics/traits/pictured.trait.js +++ b/packages/graphics/traits/pictured.trait.js @@ -25,6 +25,24 @@ export default class Pictured extends decorate(Trait) { }; } + static describeParams() { + return { + images: { + type: 'object', + label: 'Images', + }, + }; + } + + static describeState() { + return { + currentImage: { + type: 'string', + label: 'Current image', + }, + }; + } + static type() { return 'pictured'; } diff --git a/packages/graphics/traits/primitive.trait.js b/packages/graphics/traits/primitive.trait.js index 925681c..233246d 100644 --- a/packages/graphics/traits/primitive.trait.js +++ b/packages/graphics/traits/primitive.trait.js @@ -13,6 +13,15 @@ export default class Primitive extends decorate(Trait) { }; } + static describeParams() { + return { + primitives: { + type: 'object', + label: 'Primitives', + }, + }; + } + static type() { return 'primitive'; } diff --git a/packages/graphics/traits/textual.trait.js b/packages/graphics/traits/textual.trait.js index 8022c07..9618cc3 100644 --- a/packages/graphics/traits/textual.trait.js +++ b/packages/graphics/traits/textual.trait.js @@ -17,6 +17,19 @@ export default class Textual extends decorate(Trait) { }; } + static describeState() { + return { + text: { + type: 'string', + label: 'Text', + }, + textStyle: { + type: 'object', + label: 'Text style', + }, + }; + } + static type() { return 'textual'; } diff --git a/packages/graphics/traits/visible.trait.js b/packages/graphics/traits/visible.trait.js index ebd6d0d..e962aca 100644 --- a/packages/graphics/traits/visible.trait.js +++ b/packages/graphics/traits/visible.trait.js @@ -57,6 +57,44 @@ export default class Visible extends decorate(Trait) { }; } + static describeParams() { + return { + filter: { + type: 'object', + label: 'Filter', + }, + trackPosition: { + type: 'bool', + label: 'Track position', + }, + }; + } + + static describeState() { + return { + isVisible: { + type: 'bool', + label: 'Is visible', + }, + opacity: { + type: 'number', + label: 'Opacity', + }, + rotation: { + type: 'number', + label: 'Rotation', + }, + visibleScale: { + type: 'vector', + label: 'Scale', + }, + zIndex: { + type: 'number', + label: 'Z index', + }, + }; + } + static type() { return 'visible'; } diff --git a/packages/physics/traits/collider.trait.js b/packages/physics/traits/collider.trait.js index 8c6ec16..268d253 100644 --- a/packages/physics/traits/collider.trait.js +++ b/packages/physics/traits/collider.trait.js @@ -75,6 +75,35 @@ export default class Collider extends decorate(Trait) { } } + static describeParams() { + return { + activeCollision: { + type: 'bool', + label: 'Actively check collisions', + }, + collidesWithGroups: { + type: 'object', + label: 'Collides with groups', + }, + collisionEndActions: { + type: 'actions', + label: 'Collision ending actions', + }, + collisionStartActions: { + type: 'actions', + label: 'Collision starting actions', + }, + collisionGroup: { + type: 'string', + label: 'Collision group', + }, + isSensor: { + type: 'bool', + label: 'Is sensor', + }, + }; + } + static describeState() { return { isCheckingCollisions: { @@ -83,7 +112,7 @@ export default class Collider extends decorate(Trait) { }, isColliding: { type: 'bool', - label: 'Is colliding', + label: 'Is able to collide', }, } } diff --git a/packages/physics/traits/emitted.trait.js b/packages/physics/traits/emitted.trait.js index c32c97d..598077c 100644 --- a/packages/physics/traits/emitted.trait.js +++ b/packages/physics/traits/emitted.trait.js @@ -8,6 +8,15 @@ const decorate = compose( export default class Emitted extends decorate(Trait) { + static behaviorContextTypes() { + return { + particle: { + type: 'particle', + label: 'Create particle.', + }, + }; + } + static defaultParams() { return { alpha: { @@ -35,6 +44,51 @@ export default class Emitted extends decorate(Trait) { }; } + static describeParams() { + return { + alpha: { + type: 'object', + label: 'Alpha', + }, + force: { + type: 'vector', + label: 'Force', + }, + listed: { + type: 'bool', + label: 'Is listed', + }, + mass: { + type: 'number', + label: 'Mass', + }, + position: { + type: 'vector', + label: 'Position', + }, + rotation: { + type: 'object', + label: 'Rotation', + }, + scale: { + type: 'object', + label: 'Scale', + }, + transient: { + type: 'bool', + label: 'Is transient', + }, + ttl: { + type: 'number', + label: 'Time to live in seconds', + }, + velocity: { + type: 'object', + label: 'Velocity', + }, + }; + } + static type() { return 'emitted'; } diff --git a/packages/physics/traits/emitter.trait.js b/packages/physics/traits/emitter.trait.js index f4a5dc7..49b17a2 100644 --- a/packages/physics/traits/emitter.trait.js +++ b/packages/physics/traits/emitter.trait.js @@ -14,12 +14,56 @@ const decorate = compose( export default class Emitter extends decorate(Trait) { + static behaviorContextTypes() { + return { + emitParticleEntity: { + type: 'entity', + label: 'Create particle.', + args: [ + ['entity', { + type: 'entity', + }], + ], + }, + emitParticleJson: { + type: 'stream', + label: 'Create particle.', + args: [ + ['json', { + type: 'object', + }], + ], + }, + emitParticle: { + type: 'stream', + label: 'Create particle.', + args: [ + ['key', { + type: 'string', + }], + ['json', { + type: 'object', + }], + ], + }, + }; + } + static defaultParams() { return { particles: {}, }; } + static describeParams() { + return { + particles: { + type: 'object', + label: 'Particles', + }, + }; + } + static type() { return 'emitter'; } diff --git a/packages/physics/traits/physical.trait.js b/packages/physics/traits/physical.trait.js index 9ebc561..764bae7 100644 --- a/packages/physics/traits/physical.trait.js +++ b/packages/physics/traits/physical.trait.js @@ -12,6 +12,29 @@ const decorate = compose( export default class Physical extends decorate(Trait) { + static behaviorContextTypes() { + return { + applyForce: { + type: 'void', + label: 'Apply force.', + args: [ + ['force', { + type: 'vector', + }], + ], + }, + applyImpulse: { + type: 'void', + label: 'Apply impulse.', + args: [ + ['impulse', { + type: 'vector', + }], + ], + }, + }; + } + static defaultState() { return { addedToPhysics: true, diff --git a/packages/physics/traits/shaped.trait.js b/packages/physics/traits/shaped.trait.js index 5a86c1a..835bb16 100644 --- a/packages/physics/traits/shaped.trait.js +++ b/packages/physics/traits/shaped.trait.js @@ -15,6 +15,15 @@ export default class Shaped extends decorate(Trait) { }; } + static describeParams() { + return { + shape: { + type: 'object', + label: 'Shape', + }, + }; + } + static type() { return 'shaped'; } diff --git a/packages/sound/traits/audible.trait.js b/packages/sound/traits/audible.trait.js index dc558f2..1f2d2ff 100644 --- a/packages/sound/traits/audible.trait.js +++ b/packages/sound/traits/audible.trait.js @@ -6,6 +6,15 @@ export default class Audible extends Trait { static behaviorContextTypes() { return { + hasSound: { + type: 'bool', + label: 'Has $1 sound', + args: [ + ['key', { + type: 'string', + }], + ], + }, playSound: { type: 'void', label: 'Play the $1 sound.', @@ -24,6 +33,15 @@ export default class Audible extends Trait { }; } + static describeParams() { + return { + sounds: { + type: 'object', + label: 'Sounds', + }, + }; + } + static type() { return 'audible'; } diff --git a/packages/timing/traits/animated.trait.js b/packages/timing/traits/animated.trait.js index e294724..edcfdac 100644 --- a/packages/timing/traits/animated.trait.js +++ b/packages/timing/traits/animated.trait.js @@ -30,6 +30,15 @@ export default class Animated extends decorate(Trait) { }; } + static describeParams() { + return { + animations: { + type: 'object', + label: 'Animations', + }, + }; + } + static describeState() { return { isAnimating: { diff --git a/packages/topdown/traits/followed.trait.js b/packages/topdown/traits/followed.trait.js index 977269f..9529f61 100644 --- a/packages/topdown/traits/followed.trait.js +++ b/packages/topdown/traits/followed.trait.js @@ -10,6 +10,15 @@ export default class Followed extends Trait { } } + static describeParams() { + return { + viewSize: { + type: 'vector', + label: 'View size', + }, + }; + } + static type() { return 'followed'; } diff --git a/packages/topdown/traits/layered.trait.js b/packages/topdown/traits/layered.trait.js index b12931a..517af5c 100644 --- a/packages/topdown/traits/layered.trait.js +++ b/packages/topdown/traits/layered.trait.js @@ -3,6 +3,24 @@ import {Vector} from '@avocado/math'; export default class Layered extends Trait { + static behaviorContextTypes() { + return { + removeFromLayer: { + type: 'void', + label: 'Remove from layer.', + }, + setIntoLayer: { + type: 'void', + label: 'Set into layer $1.', + args: [ + ['layer', { + type: 'layer', + }], + ], + }, + }; + } + static type() { return 'layered'; } diff --git a/packages/topdown/traits/roomed.trait.js b/packages/topdown/traits/roomed.trait.js index 5803883..32d67c5 100644 --- a/packages/topdown/traits/roomed.trait.js +++ b/packages/topdown/traits/roomed.trait.js @@ -2,6 +2,24 @@ import {Trait} from '@avocado/entity'; export default class Roomed extends Trait { + static behaviorContextTypes() { + return { + detachFromRoom: { + type: 'void', + label: 'Remove from room.', + }, + attachToRoom: { + type: 'void', + label: 'Set into room $1.', + args: [ + ['room', { + type: 'room', + }], + ], + }, + }; + } + static type() { return 'roomed'; } diff --git a/packages/topdown/traits/tile-entity.trait.js b/packages/topdown/traits/tile-entity.trait.js index eb7fd34..525d173 100644 --- a/packages/topdown/traits/tile-entity.trait.js +++ b/packages/topdown/traits/tile-entity.trait.js @@ -16,6 +16,15 @@ export default class TileEntity extends decorate(Trait) { }; } + static describeState() { + return { + tileIndex: { + type: 'number', + label: 'Tile index', + }, + }; + } + static type() { return 'tile-entity'; }