From deb88b07ba0fbd9e4da3addff6e40faac2f05e6a Mon Sep 17 00:00:00 2001 From: cha0s Date: Fri, 28 Jun 2024 12:12:38 -0500 Subject: [PATCH] refactor: items --- app/astride/traverse.js | 1 + app/ecs-components/inventory.js | 39 +++++++++++++------ app/ecs-components/wielder.js | 22 ++++------- app/engine.js | 19 +++++++-- app/react-components/slot.jsx | 5 +-- app/react-components/ui.jsx | 2 +- app/routes/_main-menu.play.$.$/route.jsx | 13 ++++++- public/assets/hoe/hoe.json | 11 ++++++ public/assets/hoe/item.json | 8 ---- public/assets/hoe/projection-check.js | 10 +++++ public/assets/potion/potion.json | 3 ++ public/assets/tomato-seeds/item.json | 10 ----- .../assets/tomato-seeds/projection-check.js | 10 +++++ public/assets/tomato-seeds/tomato-seeds.json | 13 +++++++ 14 files changed, 113 insertions(+), 53 deletions(-) create mode 100644 public/assets/hoe/hoe.json delete mode 100644 public/assets/hoe/item.json create mode 100644 public/assets/hoe/projection-check.js create mode 100644 public/assets/potion/potion.json delete mode 100644 public/assets/tomato-seeds/item.json create mode 100644 public/assets/tomato-seeds/projection-check.js create mode 100644 public/assets/tomato-seeds/tomato-seeds.json diff --git a/app/astride/traverse.js b/app/astride/traverse.js index 230065b..9f52130 100644 --- a/app/astride/traverse.js +++ b/app/astride/traverse.js @@ -6,6 +6,7 @@ export const TRAVERSAL_PATH = { BinaryExpression: ['left', 'right'], BlockStatement: ['body'], CallExpression: ['arguments', 'callee'], + ChainExpression: ['expression'], ConditionalExpression: ['alternate', 'consequent', 'test'], DoWhileStatement: ['body', 'test'], ExpressionStatement: ['expression'], diff --git a/app/ecs-components/inventory.js b/app/ecs-components/inventory.js index ed98dff..87fd0da 100644 --- a/app/ecs-components/inventory.js +++ b/app/ecs-components/inventory.js @@ -52,16 +52,20 @@ export default class Inventory extends Component { } async load(instance) { const Component = this; - const {readAsset} = this.ecs; const {slots} = instance; class ItemProxy { - constructor(slot, json) { + constructor(slot, json, scripts) { this.json = json; + this.scripts = scripts; this.slot = slot; } project(position, direction) { - const {TileLayers: {layers: [layer]}} = Component.ecs.get(1); + const {TileLayers} = Component.ecs.get(1); + const layer = TileLayers.layer(0); const {projection} = this.json; + if (!projection) { + return []; + } let startX = position.x; let startY = position.y; switch (direction) { @@ -112,7 +116,14 @@ export default class Inventory extends Component { } } } - return projected; + if (this.scripts.projectionCheckInstance) { + this.scripts.projectionCheckInstance.context.layer = layer; + this.scripts.projectionCheckInstance.context.projected = projected; + return this.scripts.projectionCheckInstance.evaluateSync(); + } + else { + return projected; + } } get qty() { return slots[this.slot].qty; @@ -128,15 +139,19 @@ export default class Inventory extends Component { } } } - for (const slot in slots) { - const chars = await readAsset([slots[slot].source, 'item.json'].join('/')) - const json = chars.byteLength > 0 - ? JSON.parse( - (new TextDecoder()).decode(chars), - ) - : {}; - instance.$$items[slot] = new ItemProxy(slots, json); + const json = await this.ecs.readJson(slots[slot].source); + const scripts = {}; + if (json.projectionCheck) { + scripts.projectionCheckInstance = await this.ecs.readScript(json.projectionCheck); + } + if (json.start) { + scripts.startInstance = await this.ecs.readScript(json.start); + } + if (json.stop) { + scripts.stopInstance = await this.ecs.readScript(json.stop); + } + instance.$$items[slot] = new ItemProxy(slots, json, scripts); } } mergeDiff(original, update) { diff --git a/app/ecs-components/wielder.js b/app/ecs-components/wielder.js index 1f123ca..c130e62 100644 --- a/app/ecs-components/wielder.js +++ b/app/ecs-components/wielder.js @@ -1,5 +1,4 @@ import Component from '@/ecs/component.js'; -import Script from '@/util/script.js'; export default class Wielder extends Component { instanceFromSchema() { @@ -15,20 +14,15 @@ export default class Wielder extends Component { const {Ticking} = entity; const activeItem = this.activeItem(); if (activeItem) { - ecs.readAsset([activeItem.source, state ? 'start.js' : 'stop.js'].join('/')) - .then((code) => { - if (code.byteLength > 0) { - const context = { - ecs, - item: activeItem, - wielder: entity, - }; - Ticking.addTickingPromise(Script.tickingPromise((new TextDecoder()).decode(code), context)); - } - }); + const {startInstance, stopInstance} = activeItem.scripts; + const script = state ? startInstance : stopInstance; + if (script) { + script.context.ecs = ecs; + script.context.item = activeItem; + script.context.wielder = entity; + Ticking.addTickingPromise(script.tickingPromise()); + } } - - } } } diff --git a/app/engine.js b/app/engine.js index f6b5ce7..09b8148 100644 --- a/app/engine.js +++ b/app/engine.js @@ -5,6 +5,7 @@ import Ecs from '@/ecs/ecs.js'; import Components from '@/ecs-components/index.js'; import Systems from '@/ecs-systems/index.js'; import {decode, encode} from '@/packets/index.js'; +import Script from '@/util/script.js'; function join(...parts) { return parts.join('/'); @@ -33,9 +34,19 @@ export default class Engine { } const server = this.server = new SilphiusServer(); this.Ecs = class EngineEcs extends Ecs { - readAsset(uri) { + async readAsset(uri) { return server.readAsset(uri); } + async readJson(uri) { + const chars = await this.readAsset(uri); + return chars.byteLength > 0 ? JSON.parse((new TextDecoder()).decode(chars)) : {}; + } + async readScript(uri) { + const code = await this.readAsset(uri); + if (code.byteLength > 0) { + return Script.fromCode((new TextDecoder()).decode(code)); + } + } } this.server.addPacketListener('Action', (connection, payload) => { this.incomingActions.push([this.connectedPlayers.get(connection).entity, payload]); @@ -184,15 +195,15 @@ export default class Engine { slots: { 1: { qty: 10, - source: '/assets/potion', + source: '/assets/potion/potion.json', }, 3: { qty: 1, - source: '/assets/tomato-seeds', + source: '/assets/tomato-seeds/tomato-seeds.json', }, 4: { qty: 1, - source: '/assets/hoe', + source: '/assets/hoe/hoe.json', }, }, }, diff --git a/app/react-components/slot.jsx b/app/react-components/slot.jsx index 2b09b88..78e4caf 100644 --- a/app/react-components/slot.jsx +++ b/app/react-components/slot.jsx @@ -4,15 +4,14 @@ import styles from './slot.module.css'; * An inventory slot. Displays an item image and the quantity of the item if > 1. */ export default function Slot({ + json, onClick, onDragEnter, onDragOver, onDragStart, onDrop, qty = 1, - source, }) { - const image = source + '/icon.png'; return (