import vector2d from './helpers/vector-2d'; import Schema from '@/ecs/schema.js'; export default function(Component) { return class TileLayers extends Component { insertMany(entities) { for (const [id, {layerChange}] of entities) { if (layerChange) { const component = this.get(id); const {layers} = component; for (const layerIndex in layerChange) { for (const calculated in layerChange[layerIndex]) { const tile = layerChange[layerIndex][calculated]; layers[layerIndex].data[calculated] = tile; } layers[layerIndex] = {...layers[layerIndex]}; } } } return super.insertMany(entities); } mergeDiff(original, update) { if (!update.layerChange) { return super.mergeDiff(original, update); } const layerChange = { ...original.layerChange, }; for (const index in update.layerChange) { layerChange[index] = { ...layerChange[index], ...update.layerChange[index], }; } return {layerChange}; } instanceFromSchema() { const Instance = super.instanceFromSchema(); const Component = this; Instance.prototype.layer = function (index) { const {layers} = this; if (!(index in layers)) { return undefined; } const instance = this; class LayerProxy { constructor(layer) { this.layer = layer; } get area() { return this.layer.area; } get source() { return this.layer.source; } stamp(at, data) { const changes = {}; for (const row in data) { const columns = data[row]; for (const column in columns) { const tile = columns[column]; const x = at.x + parseInt(column); const y = at.y + parseInt(row); if (x < 0 || y < 0 || x >= this.layer.area.x || y >= this.layer.area.y) { continue; } const calculated = y * this.layer.area.x + x; this.layer.data[calculated] = tile; changes[calculated] = tile; } } Component.markChange(instance.entity, 'layerChange', {[index]: changes}); } tile({x, y}) { if (x < 0 || y < 0 || x >= this.layer.area.x || y >= this.layer.area.y) { return undefined; } return this.layer.data[y * this.layer.area.x + x]; } get tileSize() { return this.layer.tileSize; } } return new LayerProxy(layers[index]); }; return Instance; } static schema = new Schema({ type: 'object', properties: { layers: { type: 'array', subtype: { type: 'object', properties: { area: vector2d('float32'), data: { type: 'array', subtype: { type: 'uint16', }, }, source: {type: 'string'}, tileSize: vector2d('float32'), }, }, }, }, }); } }