import Schema from '@/ecs/schema.js'; export default function(Component) { return class Inventory extends Component { insertMany(entities) { for (const [id, {slotChange}] of entities) { if (slotChange) { const {slots} = this.get(id); for (const slotIndex in slotChange) { if (false === slotChange[slotIndex]) { delete slots[slotIndex]; } else { slots[slotIndex] = { ...slots[slotIndex], ...slotChange[slotIndex], }; } } } } return super.insertMany(entities); } mergeDiff(original, update) { if (!update.slotChange) { return super.mergeDiff(original, update); } const slotChange = { ...original.slotChange, }; for (const index in update.slotChange) { if (false === update.slotChange[index]) { slotChange[index] = false; } else { slotChange[index] = { ...slotChange[index], ...update.slotChange[index], }; } } return {slotChange}; } instanceFromSchema() { const Instance = super.instanceFromSchema(); const Component = this; Instance.prototype.item = async function (slot) { const {slots} = this; if (!(slot in slots)) { return undefined; } const json = await ( fetch([slots[slot].source, 'item.json'].join('/')) .then((response) => (response.ok ? response.json() : {})) ); const item = { ...slots[slot], ...json, }; const instance = this; const proxy = new Proxy(item, { set(target, property, value) { slots[slot][property] = value; if ('qty' === property && value <= 0) { Component.markChange(instance.entity, 'slotChange', {[slot]: false}); delete slots[slot]; } else { Component.markChange(instance.entity, 'slotChange', {[slot]: {[property]: value}}); } return true; }, }); return proxy; }; Instance.prototype.swapSlots = function(l, r) { const {slots} = this; const tmp = slots[l]; const change = {}; if (slots[r]) { change[l] = slots[l] = slots[r]; } else { change[l] = false; delete slots[l]; } if (tmp) { change[r] = slots[r] = tmp; } else { change[r] = false; delete slots[r]; } Component.markChange(this.entity, 'slotChange', change); }; return Instance; } static schema = new Schema({ type: 'object', properties: { slots: { type: 'map', value: { type: 'object', properties: { quantity: {type: 'uint16'}, source: {type: 'string'}, }, }, }, }, }); } }