refactor: items
This commit is contained in:
parent
023e82c521
commit
deb88b07ba
|
@ -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'],
|
||||
|
|
|
@ -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,8 +116,15 @@ export default class Inventory extends Component {
|
|||
}
|
||||
}
|
||||
}
|
||||
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) {
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -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 (
|
||||
<button
|
||||
className={styles.slot}
|
||||
|
@ -28,7 +27,7 @@ export default function Slot({
|
|||
>
|
||||
<div
|
||||
className={styles.slotInner}
|
||||
style={image ? {backgroundImage: `url(${image})`} : {}}
|
||||
style={json?.icon ? {backgroundImage: `url(${json.icon})`} : {}}
|
||||
>
|
||||
{qty > 1 && (
|
||||
<span
|
||||
|
|
|
@ -176,7 +176,7 @@ export default function Ui({disconnected}) {
|
|||
setBufferSlot(entity.Inventory.slots[0]);
|
||||
const newHotbarSlots = emptySlots();
|
||||
for (let i = 1; i < 11; ++i) {
|
||||
newHotbarSlots[i - 1] = entity.Inventory.slots[i];
|
||||
newHotbarSlots[i - 1] = entity.Inventory.item(i);
|
||||
}
|
||||
setHotbarSlots(newHotbarSlots);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import Components from '@/ecs-components/index.js';
|
|||
import Systems from '@/ecs-systems/index.js';
|
||||
import Ui from '@/react-components/ui.jsx';
|
||||
import {juggleSession} from '@/session.server';
|
||||
import Script from '@/util/script.js';
|
||||
|
||||
import {LRUCache} from 'lru-cache';
|
||||
|
||||
|
@ -20,7 +21,7 @@ export const cache = new LRUCache({
|
|||
});
|
||||
|
||||
class ClientEcs extends Ecs {
|
||||
readAsset(uri) {
|
||||
async readAsset(uri) {
|
||||
if (!cache.has(uri)) {
|
||||
let promise, resolve, reject;
|
||||
promise = new Promise((res, rej) => {
|
||||
|
@ -36,6 +37,16 @@ class ClientEcs extends Ecs {
|
|||
}
|
||||
return cache.get(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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function loader({request}) {
|
||||
|
|
11
public/assets/hoe/hoe.json
Normal file
11
public/assets/hoe/hoe.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"icon": "/assets/hoe/icon.png",
|
||||
"projectionCheck": "/assets/hoe/projection-check.js",
|
||||
"projection": {
|
||||
"distance": [1, 0],
|
||||
"grid": [
|
||||
[1]
|
||||
]
|
||||
},
|
||||
"start": "/assets/hoe/start.js"
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"projection": {
|
||||
"distance": [1, 0],
|
||||
"grid": [
|
||||
[1]
|
||||
]
|
||||
}
|
||||
}
|
10
public/assets/hoe/projection-check.js
Normal file
10
public/assets/hoe/projection-check.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
const filtered = []
|
||||
|
||||
for (let i = 0; i < projected.length; ++i) {
|
||||
const tile = layer.tile(projected[i])
|
||||
if ([1, 2, 3, 4, 6].includes(tile)) {
|
||||
filtered.push(projected[i])
|
||||
}
|
||||
}
|
||||
|
||||
return filtered
|
3
public/assets/potion/potion.json
Normal file
3
public/assets/potion/potion.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"icon": "/assets/potion/icon.png"
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"projection": {
|
||||
"distance": [1, -1],
|
||||
"grid": [
|
||||
[1, 1, 1],
|
||||
[1, 1, 1],
|
||||
[1, 1, 1]
|
||||
]
|
||||
}
|
||||
}
|
10
public/assets/tomato-seeds/projection-check.js
Normal file
10
public/assets/tomato-seeds/projection-check.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
const filtered = []
|
||||
|
||||
for (let i = 0; i < projected.length; ++i) {
|
||||
const tile = layer.tile(projected[i])
|
||||
if ([7].includes(tile)) {
|
||||
filtered.push(projected[i])
|
||||
}
|
||||
}
|
||||
|
||||
return filtered
|
13
public/assets/tomato-seeds/tomato-seeds.json
Normal file
13
public/assets/tomato-seeds/tomato-seeds.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"icon": "/assets/tomato-seeds/icon.png",
|
||||
"projection": {
|
||||
"distance": [1, -1],
|
||||
"grid": [
|
||||
[1, 1, 1],
|
||||
[1, 1, 1],
|
||||
[1, 1, 1]
|
||||
]
|
||||
},
|
||||
"projectionCheck": "/assets/tomato-seeds/projection-check.js",
|
||||
"start": "/assets/tomato-seeds/start.js"
|
||||
}
|
Loading…
Reference in New Issue
Block a user