Compare commits
6 Commits
d5af4aed83
...
fe412e710e
Author | SHA1 | Date | |
---|---|---|---|
|
fe412e710e | ||
|
f1b6a8b0d8 | ||
|
b630221f1f | ||
|
7af6b635bf | ||
|
cc8c78cb30 | ||
|
3b08a87f39 |
|
@ -2,7 +2,6 @@ import Schema from '@/ecs/schema.js';
|
||||||
|
|
||||||
export default function(Component) {
|
export default function(Component) {
|
||||||
return class Inventory extends Component {
|
return class Inventory extends Component {
|
||||||
|
|
||||||
insertMany(entities) {
|
insertMany(entities) {
|
||||||
for (const [id, {slotChange}] of entities) {
|
for (const [id, {slotChange}] of entities) {
|
||||||
if (slotChange) {
|
if (slotChange) {
|
||||||
|
@ -22,7 +21,6 @@ export default function(Component) {
|
||||||
}
|
}
|
||||||
return super.insertMany(entities);
|
return super.insertMany(entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
mergeDiff(original, update) {
|
mergeDiff(original, update) {
|
||||||
if (!update.slotChange) {
|
if (!update.slotChange) {
|
||||||
return super.mergeDiff(original, update);
|
return super.mergeDiff(original, update);
|
||||||
|
@ -57,6 +55,7 @@ export default function(Component) {
|
||||||
target[property] = value;
|
target[property] = value;
|
||||||
if ('qty' === property && value <= 0) {
|
if ('qty' === property && value <= 0) {
|
||||||
Component.markChange(instance.entity, 'slotChange', {[slot]: false});
|
Component.markChange(instance.entity, 'slotChange', {[slot]: false});
|
||||||
|
delete slots[slot];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Component.markChange(instance.entity, 'slotChange', {[slot]: {[property]: value}});
|
Component.markChange(instance.entity, 'slotChange', {[slot]: {[property]: value}});
|
||||||
|
|
|
@ -234,16 +234,22 @@ export default class Engine {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'use': {
|
case 'use': {
|
||||||
if (payload.value) {
|
|
||||||
const item = Inventory.item(Wielder.activeSlot + 1);
|
const item = Inventory.item(Wielder.activeSlot + 1);
|
||||||
this.server.readAsset(item.source + '/start.js')
|
if (item) {
|
||||||
.then((response) => response.text())
|
this.server.readAsset([
|
||||||
|
item.source,
|
||||||
|
payload.value ? 'start.js' : 'stop.js',
|
||||||
|
].join('/'))
|
||||||
|
.then((response) => response.ok ? response.text() : '')
|
||||||
.then((code) => {
|
.then((code) => {
|
||||||
|
if (code) {
|
||||||
Ticking.addTickingPromise(
|
Ticking.addTickingPromise(
|
||||||
Script.tickingPromise(code, {item, wielder: entity}),
|
Script.tickingPromise(code, {item, wielder: entity}),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,16 +6,18 @@ import Slot from './slot.jsx';
|
||||||
*/
|
*/
|
||||||
export default function Hotbar({active, onActivate, slots}) {
|
export default function Hotbar({active, onActivate, slots}) {
|
||||||
const Slots = slots.map((slot, i) => (
|
const Slots = slots.map((slot, i) => (
|
||||||
<button
|
<div
|
||||||
className={
|
className={
|
||||||
[styles.slotWrapper, active === i && styles.active]
|
[styles.slotWrapper, active === i && styles.active]
|
||||||
.filter(Boolean).join(' ')
|
.filter(Boolean).join(' ')
|
||||||
}
|
}
|
||||||
onClick={() => onActivate(i)}
|
|
||||||
key={i}
|
key={i}
|
||||||
>
|
>
|
||||||
<Slot {...slot} />
|
<Slot
|
||||||
</button>
|
onClick={() => onActivate(i)}
|
||||||
|
{...slot}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
));
|
));
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.slotWrapper {
|
.slotWrapper {
|
||||||
background-color: transparent;
|
|
||||||
border: var(--border) solid #999999;
|
border: var(--border) solid #999999;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
|
@ -3,9 +3,10 @@ import styles from './slot.module.css';
|
||||||
/**
|
/**
|
||||||
* An inventory slot. Displays an item image and the quantity of the item if > 1.
|
* An inventory slot. Displays an item image and the quantity of the item if > 1.
|
||||||
*/
|
*/
|
||||||
export default function Slot({image, onClick, qty = 1}) {
|
export default function Slot({source, onClick, qty = 1}) {
|
||||||
|
const image = source + '/icon.png';
|
||||||
return (
|
return (
|
||||||
<div
|
<button
|
||||||
className={styles.slot}
|
className={styles.slot}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
|
@ -24,6 +25,6 @@ export default function Slot({image, onClick, qty = 1}) {
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
.slot {
|
.slot {
|
||||||
--size: calc(var(--unit) * 50px);
|
--size: calc(var(--unit) * 50px);
|
||||||
--space: calc(var(--unit) * 10px);
|
--space: calc(var(--unit) * 10px);
|
||||||
|
background-color: transparent;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
|
border: none;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
height: var(--size);
|
height: var(--size);
|
||||||
image-rendering: pixelated;
|
image-rendering: pixelated;
|
||||||
|
|
|
@ -137,7 +137,7 @@ export default function Ui({disconnected}) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
}, [client]);
|
||||||
usePacket('Tick', (payload) => {
|
usePacket('Tick', (payload) => {
|
||||||
if (0 === Object.keys(payload.ecs).length) {
|
if (0 === Object.keys(payload.ecs).length) {
|
||||||
return;
|
return;
|
||||||
|
@ -154,13 +154,7 @@ export default function Ui({disconnected}) {
|
||||||
if (update.Inventory) {
|
if (update.Inventory) {
|
||||||
const newHotbarSlots = emptySlots();
|
const newHotbarSlots = emptySlots();
|
||||||
for (let i = 1; i < 11; ++i) {
|
for (let i = 1; i < 11; ++i) {
|
||||||
if (entity.Inventory.slots[i]) {
|
newHotbarSlots[i - 1] = entity.Inventory.slots[i];
|
||||||
const {qty, source} = entity.Inventory.slots[i];
|
|
||||||
newHotbarSlots[i - 1] = {
|
|
||||||
image: source + '/icon.png',
|
|
||||||
qty,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
setHotbarSlots(newHotbarSlots);
|
setHotbarSlots(newHotbarSlots);
|
||||||
}
|
}
|
||||||
|
@ -186,7 +180,7 @@ export default function Ui({disconnected}) {
|
||||||
onActivate={(i) => {
|
onActivate={(i) => {
|
||||||
client.send({
|
client.send({
|
||||||
type: 'Action',
|
type: 'Action',
|
||||||
payload: {type: 'changeSlot', value: i},
|
payload: {type: 'changeSlot', value: i + 1},
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
slots={hotbarSlots}
|
slots={hotbarSlots}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import {useEffect, useRef, useState} from 'react';
|
import {useEffect, useRef, useState} from 'react';
|
||||||
|
|
||||||
import Dom from '@/components/dom.jsx';
|
import Dom from '@/react-components/dom.jsx';
|
||||||
import {RESOLUTION} from '@/constants.js';
|
import {RESOLUTION} from '@/constants.js';
|
||||||
|
|
||||||
function Decorator({children, style}) {
|
function Decorator({children, style}) {
|
||||||
|
@ -26,6 +26,7 @@ function Decorator({children, style}) {
|
||||||
ref={ref}
|
ref={ref}
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: '#1099bb',
|
backgroundColor: '#1099bb',
|
||||||
|
flexDirection: 'column',
|
||||||
opacity: 0 === scale ? 0 : 1,
|
opacity: 0 === scale ? 0 : 1,
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
height: `calc(${RESOLUTION.y}px * ${scale})`,
|
height: `calc(${RESOLUTION.y}px * ${scale})`,
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
import {useArgs} from '@storybook/preview-api';
|
import {useArgs} from '@storybook/preview-api';
|
||||||
import {fn} from '@storybook/test';
|
import {fn} from '@storybook/test';
|
||||||
|
|
||||||
import Hotbar from '@/components/hotbar.jsx';
|
import Hotbar from '@/react-components/hotbar.jsx';
|
||||||
|
|
||||||
import DomDecorator from './dom-decorator.jsx';
|
import DomDecorator from './dom-decorator.jsx';
|
||||||
|
|
||||||
import potion from '/assets/potion.png?url';
|
|
||||||
|
|
||||||
const slots = Array(10).fill({});
|
const slots = Array(10).fill({});
|
||||||
slots[2] = {image: potion, qty: 24};
|
slots[2] = {qty: 24, source: '/assets/potion'};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: 'Dom/Inventory/Hotbar',
|
title: 'Dom/Inventory/Hotbar',
|
||||||
|
@ -25,7 +23,12 @@ export default {
|
||||||
};
|
};
|
||||||
return Hotbar();
|
return Hotbar();
|
||||||
},
|
},
|
||||||
DomDecorator(),
|
DomDecorator({
|
||||||
|
style: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
},
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
tags: ['autodocs'],
|
tags: ['autodocs'],
|
||||||
args: {
|
args: {
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
import Slot from '@/components/slot.jsx';
|
import Slot from '@/react-components/slot.jsx';
|
||||||
|
|
||||||
import DomDecorator from './dom-decorator.jsx';
|
import DomDecorator from './dom-decorator.jsx';
|
||||||
|
|
||||||
import potion from '/assets/potion.png?url';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: 'Dom/Inventory/Slot',
|
title: 'Dom/Inventory/Slot',
|
||||||
component: Slot,
|
component: Slot,
|
||||||
|
@ -33,7 +31,7 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
args: {
|
args: {
|
||||||
image: potion,
|
source: '/assets/potion',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user