silphius/app/ecs-components/wielder.js
2024-06-27 11:06:58 -05:00

95 lines
2.9 KiB
JavaScript

import Component from '@/ecs/component.js';
import Script from '@/util/script.js';
export default class Wielder extends Component {
instanceFromSchema() {
const {ecs} = this;
const Instance = super.instanceFromSchema();
return class WielderInstance extends Instance {
async activeItem() {
const {Inventory, Wielder} = ecs.get(this.entity);
return Inventory.item(Wielder.activeSlot + 1);
}
project(position, projection) {
const {TileLayers: {layers: [layer]}} = ecs.get(1);
const {Direction: {direction}} = ecs.get(this.entity);
let startX = position.x;
let startY = position.y;
switch (direction) {
case 0:
startX += projection.distance[1];
startY -= projection.distance[0];
break;
case 1:
startX += projection.distance[0];
startY += projection.distance[1];
break;
case 2:
startX -= projection.distance[1];
startY += projection.distance[0];
break;
case 3:
startX -= projection.distance[0];
startY -= projection.distance[1];
break;
}
const projected = [];
for (const row in projection.grid) {
const columns = projection.grid[row];
for (const column in columns) {
const targeted = projection.grid[row][column];
if (targeted) {
let axe;
switch (direction) {
case 0:
axe = [column, row];
break;
case 1:
axe = [-row, column];
break;
case 2:
axe = [-column, -row];
break;
case 3:
axe = [row, -column];
break;
}
const x = startX + parseInt(axe[0]);
const y = startY + parseInt(axe[1]);
if (x < 0 || y < 0 || x >= layer.area.x || y >= layer.area.y) {
continue;
}
projected.push({x, y});
}
}
}
return projected;
}
async useActiveItem(state) {
const entity = ecs.get(this.entity);
const {Ticking} = entity;
const activeItem = await this.activeItem();
if (activeItem) {
ecs.readAsset([activeItem.source, state ? 'start.js' : 'stop.js'].join('/'))
.then((script) => (script.ok ? script.text() : ''))
.then((code) => {
if (code) {
const context = {
ecs,
item: activeItem,
wielder: entity,
};
Ticking.addTickingPromise(Script.tickingPromise(code, context));
}
});
}
}
}
}
static properties = {
activeSlot: {type: 'uint16'},
};
}