@rpg-engine/long-bow 0.2.43 → 0.2.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/DayNightPeriod/DayNightPeriod.d.ts +11 -0
- package/dist/components/Item/Inventory/itemContainerHelper.d.ts +2 -2
- package/dist/components/StaticBook/StaticBook.d.ts +10 -0
- package/dist/components/TradingMenu/TradingItemRow.d.ts +2 -1
- package/dist/components/TradingMenu/TradingMenu.d.ts +1 -1
- package/dist/long-bow.cjs.development.js +67 -45
- package/dist/long-bow.cjs.development.js.map +1 -1
- package/dist/long-bow.cjs.production.min.js +1 -1
- package/dist/long-bow.cjs.production.min.js.map +1 -1
- package/dist/long-bow.esm.js +67 -45
- package/dist/long-bow.esm.js.map +1 -1
- package/dist/stories/DayNightPeriod.stories.d.ts +5 -0
- package/dist/stories/ItemTradingComponent.stories.d.ts +2 -2
- package/dist/stories/StaticBook.stories.d.ts +5 -0
- package/package.json +1 -1
- package/src/components/DayNightPeriod/DayNightPeriod.tsx +36 -0
- package/src/components/DayNightPeriod/Gif/Afternoon.gif +0 -0
- package/src/components/DayNightPeriod/Gif/Morning.gif +0 -0
- package/src/components/DayNightPeriod/Gif/Night.gif +0 -0
- package/src/components/Item/Inventory/ItemSlot.tsx +2 -2
- package/src/components/Item/Inventory/itemContainerHelper.ts +11 -5
- package/src/components/StaticBook/StaticBook.tsx +96 -0
- package/src/components/StaticBook/img/0.png +0 -0
- package/src/components/TradingMenu/TradingItemRow.tsx +15 -26
- package/src/components/TradingMenu/TradingMenu.tsx +47 -14
- package/src/mocks/itemContainer.mocks.ts +2 -2
- package/src/stories/DayNightPeriod.stories.tsx +20 -0
- package/src/stories/ItemTradingComponent.stories.tsx +20 -24
- package/src/stories/StaticBook.stories.tsx +39 -0
- package/src/stories/TradingMenu.stories.tsx +7 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Meta } from '@storybook/react';
|
|
2
|
+
import { PeriodOfDayProps } from '../components/DayNightPeriod/DayNightPeriod';
|
|
3
|
+
declare const meta: Meta;
|
|
4
|
+
export default meta;
|
|
5
|
+
export declare const Default: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, PeriodOfDayProps>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
1
2
|
import { Meta } from '@storybook/react';
|
|
2
|
-
import { ITradeComponentProps } from '../components/TradingMenu/TradingItemRow';
|
|
3
3
|
declare const meta: Meta;
|
|
4
4
|
export default meta;
|
|
5
|
-
export declare const Default:
|
|
5
|
+
export declare const Default: () => JSX.Element;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Meta } from '@storybook/react';
|
|
2
|
+
import { StaticBookProps } from '../components/StaticBook/StaticBook';
|
|
3
|
+
declare const meta: Meta;
|
|
4
|
+
export default meta;
|
|
5
|
+
export declare const Default: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, StaticBookProps>;
|
package/package.json
CHANGED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export enum IPeriodOfDay {
|
|
6
|
+
Morning = "static/media/src/components/DayNightPeriod/Gif/Morning.gif",
|
|
7
|
+
Afternoon = "static/media/src/components/DayNightPeriod/Gif/Afternoon.gif",
|
|
8
|
+
Night = "static/media/src/components/DayNightPeriod/Gif/Night.gif",
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface PeriodOfDayProps {
|
|
12
|
+
periodOfDay: IPeriodOfDay;
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const PeriodOfDay: React.FC<PeriodOfDayProps> = ({ periodOfDay }) => {
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<GifContainer >
|
|
21
|
+
|
|
22
|
+
<img src={periodOfDay} />
|
|
23
|
+
|
|
24
|
+
</GifContainer>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
interface IPeriodOfDayProps {
|
|
29
|
+
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const GifContainer = styled.span<IPeriodOfDayProps>`
|
|
33
|
+
width: 100%;
|
|
34
|
+
`;
|
|
35
|
+
|
|
36
|
+
export default PeriodOfDay;
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -10,12 +10,12 @@ import {
|
|
|
10
10
|
import { observer } from 'mobx-react-lite';
|
|
11
11
|
import React, { useEffect, useState } from 'react';
|
|
12
12
|
import styled from 'styled-components';
|
|
13
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
13
14
|
import { RelativeListMenu } from '../../RelativeListMenu';
|
|
14
15
|
import { SpriteFromAtlas } from '../../shared/SpriteFromAtlas';
|
|
15
16
|
import { ItemTooltip } from '../Cards/ItemTooltip';
|
|
16
17
|
import { ErrorBoundary } from './ErrorBoundary';
|
|
17
18
|
import { generateContextMenu, IContextMenuItem } from './itemContainerHelper';
|
|
18
|
-
import { v4 as uuidv4 } from 'uuid';
|
|
19
19
|
|
|
20
20
|
const EquipmentSlotSpriteByType: any = {
|
|
21
21
|
Neck: 'accessories/corruption-necklace.png',
|
|
@@ -77,7 +77,7 @@ export const ItemSlot: React.FC<IProps> = observer(
|
|
|
77
77
|
|
|
78
78
|
useEffect(() => {
|
|
79
79
|
if (item) {
|
|
80
|
-
setContextActions(generateContextMenu(item
|
|
80
|
+
setContextActions(generateContextMenu(item, containerType));
|
|
81
81
|
}
|
|
82
82
|
}, [item]);
|
|
83
83
|
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
ActionsForInventory,
|
|
4
4
|
ActionsForLoot,
|
|
5
5
|
ActionsForMapContainer,
|
|
6
|
+
IItem,
|
|
6
7
|
ItemContainerType,
|
|
7
8
|
ItemSocketEventsDisplayLabels,
|
|
8
9
|
ItemType,
|
|
@@ -23,13 +24,13 @@ const generateContextMenuListOptions = (actionsByTypeList: any) => {
|
|
|
23
24
|
};
|
|
24
25
|
|
|
25
26
|
export const generateContextMenu = (
|
|
26
|
-
|
|
27
|
+
item: IItem,
|
|
27
28
|
itemContainerType: ItemContainerType | null
|
|
28
29
|
) => {
|
|
29
30
|
let contextActionMenu: IContextMenuItem[] = [];
|
|
30
31
|
|
|
31
32
|
if (itemContainerType === ItemContainerType.Inventory) {
|
|
32
|
-
switch (
|
|
33
|
+
switch (item.type) {
|
|
33
34
|
case ItemType.Weapon:
|
|
34
35
|
case ItemType.Armor:
|
|
35
36
|
case ItemType.Accessory:
|
|
@@ -67,7 +68,7 @@ export const generateContextMenu = (
|
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
if (itemContainerType === ItemContainerType.Equipment) {
|
|
70
|
-
switch (
|
|
71
|
+
switch (item.type) {
|
|
71
72
|
case ItemType.Container:
|
|
72
73
|
contextActionMenu = generateContextMenuListOptions(
|
|
73
74
|
ActionsForEquipmentSet.Container
|
|
@@ -81,7 +82,7 @@ export const generateContextMenu = (
|
|
|
81
82
|
}
|
|
82
83
|
}
|
|
83
84
|
if (itemContainerType === ItemContainerType.Loot) {
|
|
84
|
-
switch (
|
|
85
|
+
switch (item.type) {
|
|
85
86
|
case ItemType.Weapon:
|
|
86
87
|
case ItemType.Armor:
|
|
87
88
|
case ItemType.Accessory:
|
|
@@ -111,7 +112,7 @@ export const generateContextMenu = (
|
|
|
111
112
|
}
|
|
112
113
|
}
|
|
113
114
|
if (itemContainerType === ItemContainerType.MapContainer) {
|
|
114
|
-
switch (
|
|
115
|
+
switch (item.type) {
|
|
115
116
|
case ItemType.Weapon:
|
|
116
117
|
case ItemType.Armor:
|
|
117
118
|
case ItemType.Accessory:
|
|
@@ -142,5 +143,10 @@ export const generateContextMenu = (
|
|
|
142
143
|
break;
|
|
143
144
|
}
|
|
144
145
|
}
|
|
146
|
+
|
|
147
|
+
if (item.hasUseWith) {
|
|
148
|
+
contextActionMenu.push({ id: 'use-with', text: 'Use With...' });
|
|
149
|
+
}
|
|
150
|
+
|
|
145
151
|
return contextActionMenu;
|
|
146
152
|
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
import SelectArrow from '../Arrow/SelectArrow';
|
|
4
|
+
import Book from './img/0.png';
|
|
5
|
+
|
|
6
|
+
export interface StaticBookProps {
|
|
7
|
+
availableBook: Array<staticProps>;
|
|
8
|
+
onChange: (selectedBook: staticProps) => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface staticProps {
|
|
12
|
+
text: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const StaticBook: React.FC<StaticBookProps> = ({
|
|
16
|
+
availableBook,
|
|
17
|
+
onChange,
|
|
18
|
+
}) => {
|
|
19
|
+
const [currentIndex, setCurrentIndex] = useState(0);
|
|
20
|
+
const bookLength = availableBook.length - 1;
|
|
21
|
+
|
|
22
|
+
const onLeftClick = () => {
|
|
23
|
+
if (currentIndex === 0) setCurrentIndex(bookLength);
|
|
24
|
+
else setCurrentIndex(index => index - 1);
|
|
25
|
+
};
|
|
26
|
+
const onRightClick = () => {
|
|
27
|
+
if (currentIndex === bookLength) setCurrentIndex(0);
|
|
28
|
+
else setCurrentIndex(index => index + 1);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
onChange(availableBook[currentIndex]);
|
|
33
|
+
}, [currentIndex]);
|
|
34
|
+
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
setCurrentIndex(0);
|
|
37
|
+
}, [JSON.stringify(availableBook)]);
|
|
38
|
+
|
|
39
|
+
const getCurrentSelectionName = () => {
|
|
40
|
+
const item = availableBook[currentIndex];
|
|
41
|
+
if (item) {
|
|
42
|
+
return item.text.slice(0, 600);
|
|
43
|
+
}
|
|
44
|
+
return '';
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<Container>
|
|
49
|
+
<Textbook><Colunbook>{getCurrentSelectionName()}</Colunbook></Textbook>
|
|
50
|
+
<ArrowContainer>
|
|
51
|
+
<SelectArrow
|
|
52
|
+
direction="left"
|
|
53
|
+
onClick={onLeftClick}
|
|
54
|
+
onTouchStart={onLeftClick}
|
|
55
|
+
></SelectArrow>
|
|
56
|
+
<SelectArrow
|
|
57
|
+
direction="right"
|
|
58
|
+
onClick={onRightClick}
|
|
59
|
+
onTouchStart={onRightClick}
|
|
60
|
+
></SelectArrow>
|
|
61
|
+
</ArrowContainer>
|
|
62
|
+
</Container>
|
|
63
|
+
);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
const Container = styled.div`
|
|
68
|
+
background-image: url(${Book});
|
|
69
|
+
background-repeat:no-repeat;
|
|
70
|
+
position: relative;
|
|
71
|
+
width: 778px;
|
|
72
|
+
height: 538px;
|
|
73
|
+
|
|
74
|
+
`;
|
|
75
|
+
const Textbook = styled.span`
|
|
76
|
+
position: absolute;
|
|
77
|
+
padding-left: 6em;
|
|
78
|
+
display: flex;
|
|
79
|
+
|
|
80
|
+
`;
|
|
81
|
+
const Colunbook = styled.span`
|
|
82
|
+
padding-left: 3px;
|
|
83
|
+
padding-top: 70px;
|
|
84
|
+
width: 86%;
|
|
85
|
+
column-count:2;
|
|
86
|
+
grid-gap: 50px;
|
|
87
|
+
|
|
88
|
+
`;
|
|
89
|
+
const ArrowContainer = styled.span`
|
|
90
|
+
display: flex;
|
|
91
|
+
height:100% ;
|
|
92
|
+
align-items: center;
|
|
93
|
+
|
|
94
|
+
`;
|
|
95
|
+
|
|
96
|
+
export default StaticBook;
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ITradeResponseItem } from '@rpg-engine/shared';
|
|
2
2
|
import capitalize from 'lodash/capitalize';
|
|
3
|
-
import React
|
|
3
|
+
import React from 'react';
|
|
4
4
|
import styled from 'styled-components';
|
|
5
5
|
import { uiColors } from '../../constants/uiColors';
|
|
6
6
|
import { uiFonts } from '../../constants/uiFonts';
|
|
@@ -9,43 +9,32 @@ import { Ellipsis } from '../shared/Ellipsis';
|
|
|
9
9
|
import { SpriteFromAtlas } from '../shared/SpriteFromAtlas';
|
|
10
10
|
export interface ITradeComponentProps {
|
|
11
11
|
traderItem: ITradeResponseItem;
|
|
12
|
-
|
|
12
|
+
onQuantityChange: (
|
|
13
|
+
traderItem: ITradeResponseItem,
|
|
14
|
+
selectedQty: number
|
|
15
|
+
) => void;
|
|
13
16
|
atlasJSON: any;
|
|
14
17
|
atlasIMG: any;
|
|
18
|
+
selectedQty: number;
|
|
15
19
|
}
|
|
16
20
|
|
|
17
21
|
export const TradingItemRow: React.FC<ITradeComponentProps> = ({
|
|
18
22
|
atlasIMG,
|
|
19
23
|
atlasJSON,
|
|
20
|
-
|
|
24
|
+
onQuantityChange,
|
|
21
25
|
traderItem,
|
|
26
|
+
selectedQty,
|
|
22
27
|
}) => {
|
|
23
|
-
const [itemQuantity, setItemQuantity] = useState(0);
|
|
24
|
-
|
|
25
28
|
const onLeftClick = () => {
|
|
26
|
-
if (
|
|
27
|
-
const newQuantity =
|
|
28
|
-
|
|
29
|
-
updateChartTotals({
|
|
30
|
-
key: traderItem.key,
|
|
31
|
-
qty: newQuantity,
|
|
32
|
-
price: traderItem.price,
|
|
33
|
-
texturePath: traderItem.texturePath,
|
|
34
|
-
name: traderItem.name,
|
|
35
|
-
});
|
|
29
|
+
if (selectedQty > 0) {
|
|
30
|
+
const newQuantity = selectedQty - 1;
|
|
31
|
+
onQuantityChange(traderItem, newQuantity);
|
|
36
32
|
}
|
|
37
33
|
};
|
|
38
34
|
const onRightClick = () => {
|
|
39
|
-
if (
|
|
40
|
-
const newQuantity =
|
|
41
|
-
|
|
42
|
-
updateChartTotals({
|
|
43
|
-
key: traderItem.key,
|
|
44
|
-
qty: newQuantity,
|
|
45
|
-
price: traderItem.price,
|
|
46
|
-
texturePath: traderItem.texturePath,
|
|
47
|
-
name: traderItem.name,
|
|
48
|
-
});
|
|
35
|
+
if (selectedQty < (traderItem.qty ?? 999)) {
|
|
36
|
+
const newQuantity = selectedQty + 1;
|
|
37
|
+
onQuantityChange(traderItem, newQuantity);
|
|
49
38
|
}
|
|
50
39
|
};
|
|
51
40
|
|
|
@@ -80,7 +69,7 @@ export const TradingItemRow: React.FC<ITradeComponentProps> = ({
|
|
|
80
69
|
></SelectArrow>
|
|
81
70
|
<QuantityDisplay>
|
|
82
71
|
<TextOverlay>
|
|
83
|
-
<Item>{
|
|
72
|
+
<Item>{selectedQty}</Item>
|
|
84
73
|
</TextOverlay>
|
|
85
74
|
</QuantityDisplay>
|
|
86
75
|
<SelectArrow
|
|
@@ -8,7 +8,7 @@ import { TradingItemRow } from './TradingItemRow';
|
|
|
8
8
|
export interface ITrandingMenu {
|
|
9
9
|
traderItems: ITradeResponseItem[];
|
|
10
10
|
onClose: () => void;
|
|
11
|
-
onConfirm: () => void;
|
|
11
|
+
onConfirm: (items: ITradeResponseItem[]) => void;
|
|
12
12
|
type: TradeTransactionType;
|
|
13
13
|
atlasJSON: any;
|
|
14
14
|
atlasIMG: any;
|
|
@@ -25,23 +25,55 @@ export const TradingMenu: React.FC<ITrandingMenu> = ({
|
|
|
25
25
|
onConfirm,
|
|
26
26
|
}) => {
|
|
27
27
|
const [sum, setSum] = useState(0);
|
|
28
|
-
|
|
29
|
-
const updateChartTotals = (item: ITradeResponseItem) => {
|
|
30
|
-
const itemIndex = traderItems.findIndex(
|
|
31
|
-
itemArray => itemArray.key === item.key
|
|
32
|
-
);
|
|
33
|
-
traderItems[itemIndex] = item;
|
|
28
|
+
const [qtyMap, setQtyMap] = useState(new Map());
|
|
34
29
|
|
|
30
|
+
const onQuantityChange = (item: ITradeResponseItem, selectedQty: number) => {
|
|
31
|
+
setQtyMap(new Map(qtyMap.set(item.key, selectedQty)));
|
|
32
|
+
|
|
33
|
+
let newSum = 0;
|
|
35
34
|
traderItems.forEach(item => {
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
const qty = qtyMap.get(item.key);
|
|
36
|
+
if (qty) newSum += qty * item.price;
|
|
37
|
+
setSum(newSum);
|
|
38
38
|
});
|
|
39
39
|
};
|
|
40
40
|
|
|
41
|
+
const isBuy = () => {
|
|
42
|
+
return type == 'buy';
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const hasGoldForSale = () => {
|
|
46
|
+
if (isBuy()) {
|
|
47
|
+
return !(sum > characterAvailableGold);
|
|
48
|
+
}
|
|
49
|
+
return true;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const getFinalGold = () => {
|
|
53
|
+
if (isBuy()) {
|
|
54
|
+
return characterAvailableGold - sum;
|
|
55
|
+
} else {
|
|
56
|
+
return characterAvailableGold + sum;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
41
60
|
const Capitalize = (word: string) => {
|
|
42
61
|
return word[0].toUpperCase() + word.substring(1);
|
|
43
62
|
};
|
|
44
63
|
|
|
64
|
+
const onConfirmClick = () => {
|
|
65
|
+
const items: ITradeResponseItem[] = [];
|
|
66
|
+
|
|
67
|
+
traderItems.forEach(item => {
|
|
68
|
+
const qty = qtyMap.get(item.key);
|
|
69
|
+
if (qty) {
|
|
70
|
+
items.push(Object.assign({}, item, { qty: qty }));
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
onConfirm(items);
|
|
75
|
+
};
|
|
76
|
+
|
|
45
77
|
return (
|
|
46
78
|
<DraggableContainer
|
|
47
79
|
type={RPGUIContainerTypes.Framed}
|
|
@@ -62,8 +94,9 @@ export const TradingMenu: React.FC<ITrandingMenu> = ({
|
|
|
62
94
|
<TradingItemRow
|
|
63
95
|
atlasIMG={atlasIMG}
|
|
64
96
|
atlasJSON={atlasJSON}
|
|
65
|
-
|
|
97
|
+
onQuantityChange={onQuantityChange}
|
|
66
98
|
traderItem={tradeItem}
|
|
99
|
+
selectedQty={qtyMap.get(tradeItem.key) ?? 0}
|
|
67
100
|
/>
|
|
68
101
|
</ItemWrapper>
|
|
69
102
|
))}
|
|
@@ -76,22 +109,22 @@ export const TradingMenu: React.FC<ITrandingMenu> = ({
|
|
|
76
109
|
<p>Total:</p>
|
|
77
110
|
<p>${sum}</p>
|
|
78
111
|
</TotalWrapper>
|
|
79
|
-
{
|
|
112
|
+
{!hasGoldForSale() ? (
|
|
80
113
|
<AlertWrapper>
|
|
81
114
|
<p> Sorry, not enough money.</p>
|
|
82
115
|
</AlertWrapper>
|
|
83
116
|
) : (
|
|
84
117
|
<GoldWrapper>
|
|
85
118
|
<p>Final Gold:</p>
|
|
86
|
-
<p>${
|
|
119
|
+
<p>${getFinalGold()}</p>
|
|
87
120
|
</GoldWrapper>
|
|
88
121
|
)}
|
|
89
122
|
|
|
90
123
|
<ButtonWrapper>
|
|
91
124
|
<Button
|
|
92
125
|
buttonType={ButtonTypes.RPGUIButton}
|
|
93
|
-
disabled={
|
|
94
|
-
onClick={() =>
|
|
126
|
+
disabled={!hasGoldForSale()}
|
|
127
|
+
onClick={() => onConfirmClick()}
|
|
95
128
|
>
|
|
96
129
|
Confirm
|
|
97
130
|
</Button>
|
|
@@ -141,7 +141,7 @@ export const items: IItem[] = [
|
|
|
141
141
|
},
|
|
142
142
|
{
|
|
143
143
|
_id: '629acek4j7c8e8002fg60034',
|
|
144
|
-
hasUseWith:
|
|
144
|
+
hasUseWith: true,
|
|
145
145
|
type: ItemType.Consumable,
|
|
146
146
|
subType: ItemSubType.Accessory,
|
|
147
147
|
textureAtlas: 'items',
|
|
@@ -156,7 +156,7 @@ export const items: IItem[] = [
|
|
|
156
156
|
layer: 1,
|
|
157
157
|
isItemContainer: false,
|
|
158
158
|
isSolid: false,
|
|
159
|
-
key: '
|
|
159
|
+
key: 'silver-key',
|
|
160
160
|
texturePath: 'others/silver-key.png',
|
|
161
161
|
textureKey: 'silver-key',
|
|
162
162
|
name: 'Key',
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Meta, Story } from '@storybook/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import DayNightPeriod, { IPeriodOfDay, PeriodOfDay, PeriodOfDayProps } from '../components/DayNightPeriod/DayNightPeriod';
|
|
4
|
+
import { RPGUIRoot } from '../components/RPGUIRoot';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
const meta: Meta = {
|
|
8
|
+
title: 'Day and Night Period',
|
|
9
|
+
component: DayNightPeriod,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default meta;
|
|
13
|
+
|
|
14
|
+
const Template: Story<PeriodOfDayProps> = () => (
|
|
15
|
+
<RPGUIRoot>
|
|
16
|
+
<PeriodOfDay periodOfDay={IPeriodOfDay.Afternoon} />
|
|
17
|
+
</RPGUIRoot>
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
export const Default = Template.bind({});
|
|
@@ -1,39 +1,35 @@
|
|
|
1
1
|
import { ITradeResponseItem } from '@rpg-engine/shared';
|
|
2
|
-
import { Meta
|
|
3
|
-
import React from 'react';
|
|
2
|
+
import { Meta } from '@storybook/react';
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
4
|
import { RPGUIRoot } from '../components/RPGUIRoot';
|
|
5
5
|
import { itemMock } from '../components/TradingMenu/items.mock';
|
|
6
|
-
import {
|
|
7
|
-
ITradeComponentProps,
|
|
8
|
-
TradingItemRow,
|
|
9
|
-
} from '../components/TradingMenu/TradingItemRow';
|
|
6
|
+
import { TradingItemRow } from '../components/TradingMenu/TradingItemRow';
|
|
10
7
|
import atlasJSON from '../mocks/atlas/items/items.json';
|
|
11
8
|
import atlasIMG from '../mocks/atlas/items/items.png';
|
|
12
9
|
|
|
13
|
-
const updateChartTotals = (itemInfo: ITradeResponseItem) => {
|
|
14
|
-
console.log(itemInfo);
|
|
15
|
-
// will be needed read all itens from chart list ignoring the current item (itemInfo) and recalculate the totals
|
|
16
|
-
// with the amount updated set the total to a state to be shown to the player.
|
|
17
|
-
// OBS: This list with Id, quantity and amount will be the one to send to API,
|
|
18
|
-
// because the API need to know wichi Items and the quantity of it to make a purchese and set the itens to the player.
|
|
19
|
-
};
|
|
20
|
-
|
|
21
10
|
const meta: Meta = {
|
|
22
11
|
title: 'Trading Item',
|
|
23
12
|
component: TradingItemRow,
|
|
24
13
|
};
|
|
25
14
|
export default meta;
|
|
26
15
|
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
<TradingItemRow {...args} traderItem={itemMock[0]} />
|
|
30
|
-
</RPGUIRoot>
|
|
31
|
-
);
|
|
16
|
+
export const Default = () => {
|
|
17
|
+
const [selectedQty, setSelectedQty] = useState(0);
|
|
32
18
|
|
|
33
|
-
|
|
19
|
+
const handleOnChange = (item: ITradeResponseItem, qty: number) => {
|
|
20
|
+
console.log(item);
|
|
21
|
+
setSelectedQty(qty);
|
|
22
|
+
};
|
|
34
23
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
24
|
+
return (
|
|
25
|
+
<RPGUIRoot>
|
|
26
|
+
<TradingItemRow
|
|
27
|
+
atlasIMG={atlasIMG}
|
|
28
|
+
atlasJSON={atlasJSON}
|
|
29
|
+
onQuantityChange={handleOnChange}
|
|
30
|
+
selectedQty={selectedQty}
|
|
31
|
+
traderItem={itemMock[0]}
|
|
32
|
+
/>
|
|
33
|
+
</RPGUIRoot>
|
|
34
|
+
);
|
|
39
35
|
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Meta, Story } from '@storybook/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { RPGUIRoot } from '..';
|
|
4
|
+
|
|
5
|
+
import StaticBook, { StaticBookProps } from '../components/StaticBook/StaticBook';
|
|
6
|
+
|
|
7
|
+
const meta: Meta = {
|
|
8
|
+
title: 'Static Book',
|
|
9
|
+
component: StaticBook,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default meta;
|
|
13
|
+
|
|
14
|
+
const Template: Story<StaticBookProps> = args => (
|
|
15
|
+
<RPGUIRoot>
|
|
16
|
+
<StaticBook {...args} />
|
|
17
|
+
</RPGUIRoot>
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
export const Default = Template.bind({});
|
|
21
|
+
|
|
22
|
+
const bookMock = [
|
|
23
|
+
{
|
|
24
|
+
text: '1 ... Computers and RPGs have always gone hand-in-hand. Even when the bes and Oubliette. A few, such as Oubliette, had simple graphics, though most started out as just text or used ASCII’s standard set of text-mode graphics The most successful dungeon crawler of all time is, of course, Blizzard’s Diablo. But Rogue’s longest-lived descendent is arguably a much more interesting game—1987’s Nethack. Technically, it was based on a Rogue clone called, yes, Hack, but let’s not quibble. Nethack takes the basic dungeon crawling concept and adds several decades worth of development.',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
text: '2 ... The original PC RPGs—such as MUDs, or multi-user dungeons—appeared in the mid-70s. These weren’t for home computers, but mainframes, typically found in universities. They tended to be based on either Dungeons & Dragons, which itself launched in 1974, or be variously disguised takes on Tolkien. These included Dungeon, DND, Orthanc, and Oubliette. A few, such as Oubliette, had simple graphics, though most started out as just text or used ASCII’s standard set of text-mode graphics The most successful dungeon crawler of all time is, of course, Blizzard’s Diablo. But Rogue’s longest-lived descendent is arguably a much more interesting game—1987’s Nethack. Technically, it was based on a Rogue clone called, yes, Hack, but let’s not quibble. Nethack takes the basic dungeon crawling concept and adds several decades worth of development. ',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
text: '3 ... Despite the primitive technology, these games often offered surprising depth. Don Daglow’s Dungeon for instance, a 1975 D&D pastiche, offered control of an entire multiplayer party, mapping, NPCs with AI, line-of-sight-based combat, and both melee and ranged attacks. Moria, from the same year, served up wireframe graphics for its characters, and even featured rudimentary 3D views of its corridors. Small ones, with no detail, but let’s not forget that even Space Invaders wasn’t out yet! Ever wondered if throwing a custard pie in a basilisk’s face will stop its petrifying stare? Nethack not only answers that question (it will), but also implements blindness if you get hit by a pie yourself, causes you to break your code if a vegan character eats one (seriously), and ensures the attack doesn’t count if you’re on a pacifist run (it does no damage, no matter your combat bonus). This level of detail lead to the saying “The Dev Team Thinks Of Everything”. Many versions are now available, from the original ASCII-based game to graphical overhauls like Vulture’s Eye. All are free, as a condition of the distribution licence. ',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
text: '4 ... Despite the primitive technology, these games often offered surprising depth. Don Daglow’s Dungeon for instance, a 1975 D&D pastiche, offered control of an entire multiplayer party, mapping, NPCs with AI, line-of-sight-based combat, and both melee and ranged attacks. Moria, from the same year, served up wireframe graphics for its characters, and even featured rudimentary 3D views of its corridors. Small ones, with no detail, but let’s not forget that even Space Invaders wasn’t out yet! Ever wondered if throwing a custard pie in a basilisk’s face will stop its petrifying stare? Nethack not only answers that question (it will), but also implements blindness if you get hit by a pie yourself, causes you to break your code if a vegan character eats one (seriously), and ensures the attack doesn’t count if you’re on a pacifist run (it does no damage, no matter your combat bonus). This level of detail lead to the saying “The Dev Team Thinks Of Everything”. Many versions are now available, from the original ASCII-based game to graphical overhauls like Vulture’s Eye. All are free, as a condition of the distribution licence. ',
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
Default.args = {
|
|
38
|
+
availableBook: bookMock,
|
|
39
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ITradeResponseItem } from '@rpg-engine/shared';
|
|
1
2
|
import { Meta, Story } from '@storybook/react';
|
|
2
3
|
import React from 'react';
|
|
3
4
|
import { RPGUIRoot } from '../components/RPGUIRoot';
|
|
@@ -24,6 +25,11 @@ const Template: Story<ITrandingMenu> = args => (
|
|
|
24
25
|
|
|
25
26
|
export const Default = Template.bind({});
|
|
26
27
|
|
|
28
|
+
const onConfirm = (items: ITradeResponseItem[]) => {
|
|
29
|
+
console.log('on confirm trading menu');
|
|
30
|
+
console.log(items);
|
|
31
|
+
};
|
|
32
|
+
|
|
27
33
|
const onClose = () => {
|
|
28
34
|
console.log('close');
|
|
29
35
|
};
|
|
@@ -31,6 +37,7 @@ const onClose = () => {
|
|
|
31
37
|
Default.args = {
|
|
32
38
|
traderItems: itemMock,
|
|
33
39
|
onClose: onClose,
|
|
40
|
+
onConfirm: onConfirm,
|
|
34
41
|
type: 'buy',
|
|
35
42
|
atlasJSON: atlasJSON,
|
|
36
43
|
atlasIMG: atlasIMG,
|