diff --git a/packages/entity/traits/spawner.trait.js b/packages/entity/traits/spawner.trait.js index b105c39..cdd08fd 100644 --- a/packages/entity/traits/spawner.trait.js +++ b/packages/entity/traits/spawner.trait.js @@ -40,6 +40,15 @@ export class Spawner extends decorate(Trait) { this.spawnJSONs = this.params.spawns; } + destinationEntityList() { + if (this.entity.is('listed')) { + return this.entity.list; + } + if (this.entity.wielder && this.entity.wielder.is('listed')) { + return this.entity.wielder.list; + } + } + listeners() { return { @@ -60,9 +69,6 @@ export class Spawner extends decorate(Trait) { }, spawn: (key, json = {}) => { - if (!this.entity.is('listed')) { - return; - } if (this.maxSpawns <= this.children.length) { return; } @@ -70,9 +76,16 @@ export class Spawner extends decorate(Trait) { if (!spawnJSON) { return; } - const list = this.entity.list; - Entity.loadOrInstance(merge(spawnJSON, json)).then((spawn) => { - this.children.push(spawn); + const list = this.destinationEntityList(); + if (!list) { + return; + } + const mergedJSON = merge({}, spawnJSON, json); + // Add null to children to prevent race. + const childIndex = this.children.length; + this.children.push(null); + return Entity.loadOrInstance(mergedJSON).then((spawn) => { + this.children[childIndex] = spawn; spawn.once('destroy', () => { const index = this.children.indexOf(spawn); this.children.splice(index, 1); @@ -81,6 +94,24 @@ export class Spawner extends decorate(Trait) { }); }, + spawnAt: (key, position, json = {}) => { + if (this.maxSpawns <= this.children.length) { + return; + } + if (!json.traits) { + json.traits = {}; + } + if (!json.traits.positioned) { + json.traits.positioned = {}; + } + if (!json.traits.positioned.state) { + json.traits.positioned.state = {}; + } + json.traits.positioned.state.x = position[0] << 2; + json.traits.positioned.state.y = position[1] << 2; + return this.entity.spawn(key, json); + }, + }; }