@rpg-engine/long-bow 0.3.91 → 0.3.93

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.
@@ -0,0 +1,4 @@
1
+ import { Meta } from '@storybook/react';
2
+ declare const meta: Meta;
3
+ export default meta;
4
+ export declare const Default: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, import("@storybook/react").Args>;
@@ -0,0 +1,4 @@
1
+ import { Meta } from '@storybook/react';
2
+ declare const meta: Meta;
3
+ export default meta;
4
+ export declare const Default: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, import("@storybook/react").Args>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpg-engine/long-bow",
3
- "version": "0.3.91",
3
+ "version": "0.3.93",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -83,7 +83,7 @@
83
83
  },
84
84
  "dependencies": {
85
85
  "@rollup/plugin-image": "^2.1.1",
86
- "@rpg-engine/shared": "^0.7.40",
86
+ "@rpg-engine/shared": "^0.7.51",
87
87
  "dayjs": "^1.11.2",
88
88
  "font-awesome": "^4.7.0",
89
89
  "fs-extra": "^10.1.0",
@@ -165,6 +165,16 @@ export const CraftBook: React.FC<IItemCraftSelectorProps> = ({
165
165
  </StyledItem>
166
166
  </Recipes>
167
167
  ))}
168
+ {isShown && isShown.index === index && (
169
+ <MinCraftingRequirementsText
170
+ levelIsOk={option?.levelIsOk ?? false}
171
+ >
172
+ {modifyString(
173
+ `${option?.minCraftingRequirements?.[0] ?? ''} ${option
174
+ ?.minCraftingRequirements?.[1] ?? ''}`
175
+ )}
176
+ </MinCraftingRequirementsText>
177
+ )}
168
178
  </div>
169
179
  </RadioOptionsWrapper>
170
180
  ))}
@@ -242,3 +252,9 @@ const ButtonWrapper = styled.div`
242
252
  padding: 0px 50px;
243
253
  }
244
254
  `;
255
+
256
+ const MinCraftingRequirementsText = styled.div<{ levelIsOk: boolean }>`
257
+ font-size: 0.6rem;
258
+ font-weight: bold;
259
+ color: ${({ levelIsOk }) => (levelIsOk ? '#72f100' : 'gray')};
260
+ `;
@@ -4,7 +4,7 @@ import { items } from '../../mocks/itemContainer.mocks';
4
4
  export const craftableItems: ICraftableItem[] = [
5
5
  {
6
6
  ...items[0],
7
- canCraft: true,
7
+ canCraft: false,
8
8
  ingredients: [
9
9
  {
10
10
  key: 'leather',
@@ -13,6 +13,8 @@ export const craftableItems: ICraftableItem[] = [
13
13
  texturePath: 'crafting-resources/leather.png',
14
14
  },
15
15
  ],
16
+ minCraftingRequirements: ['Blacksmithing', 4],
17
+ levelIsOk: true,
16
18
  },
17
19
  {
18
20
  ...items[1],
@@ -25,6 +27,8 @@ export const craftableItems: ICraftableItem[] = [
25
27
  texturePath: 'crafting-resources/leather.png',
26
28
  },
27
29
  ],
30
+ minCraftingRequirements: ['Blacksmithing', 4],
31
+ levelIsOk: false,
28
32
  },
29
33
  {
30
34
  ...items[2],
@@ -37,6 +41,8 @@ export const craftableItems: ICraftableItem[] = [
37
41
  texturePath: 'crafting-resources/leather.png',
38
42
  },
39
43
  ],
44
+ minCraftingRequirements: ['Blacksmithing', 4],
45
+ levelIsOk: false,
40
46
  },
41
47
  {
42
48
  ...items[0],
@@ -49,6 +55,8 @@ export const craftableItems: ICraftableItem[] = [
49
55
  texturePath: 'crafting-resources/leather.png',
50
56
  },
51
57
  ],
58
+ minCraftingRequirements: ['Blacksmithing', 4],
59
+ levelIsOk: false,
52
60
  },
53
61
  {
54
62
  ...items[1],
@@ -61,6 +69,8 @@ export const craftableItems: ICraftableItem[] = [
61
69
  texturePath: 'crafting-resources/leather.png',
62
70
  },
63
71
  ],
72
+ minCraftingRequirements: ['Blacksmithing', 1],
73
+ levelIsOk: true,
64
74
  },
65
75
  {
66
76
  ...items[2],
@@ -73,5 +83,7 @@ export const craftableItems: ICraftableItem[] = [
73
83
  texturePath: 'crafting-resources/leather.png',
74
84
  },
75
85
  ],
86
+ minCraftingRequirements: ['Blacksmithing', 4],
87
+ levelIsOk: true,
76
88
  },
77
89
  ];
@@ -5,7 +5,7 @@ import { v4 as uuidv4 } from 'uuid';
5
5
  export interface IOptionsProps {
6
6
  id: number;
7
7
  value: string;
8
- option: string;
8
+ option: string | JSX.Element;
9
9
  }
10
10
 
11
11
  export interface IDropdownProps {
@@ -22,7 +22,9 @@ export const Dropdown: React.FC<IDropdownProps> = ({
22
22
  const dropdownId = uuidv4();
23
23
 
24
24
  const [selectedValue, setSelectedValue] = useState<string>('');
25
- const [selectedOption, setSelectedOption] = useState<string>('');
25
+ const [selectedOption, setSelectedOption] = useState<string | JSX.Element>(
26
+ ''
27
+ );
26
28
  const [opened, setOpened] = useState<boolean>(false);
27
29
 
28
30
  useEffect(() => {
@@ -0,0 +1,132 @@
1
+ import { IEquipmentSet, IItem } from '@rpg-engine/shared';
2
+ import React, { ChangeEvent } from 'react';
3
+ import styled from 'styled-components';
4
+ import { DraggableContainer } from '../DraggableContainer';
5
+ import { Dropdown, IOptionsProps } from '../Dropdown';
6
+ import { Input } from '../Input';
7
+ import { RPGUIContainerTypes } from '../RPGUIContainer';
8
+ import { MarketplaceRows } from './MarketplaceRows';
9
+
10
+ export interface IMarketPlaceProps {
11
+ items: IItem[] | null;
12
+ atlasJSON: any;
13
+ atlasIMG: any;
14
+ optionsType: IOptionsProps[];
15
+ optionsRarity: IOptionsProps[];
16
+ optionsPrice: IOptionsProps[];
17
+ onClose: () => void;
18
+ onChangeType: (value: string) => void;
19
+ onChangeRarity: (value: string) => void;
20
+ onChangeOrder: (value: string) => void;
21
+ onChangeNameInput: (event: ChangeEvent<HTMLInputElement>) => void;
22
+ scale?: number;
23
+ equipmentSet?: IEquipmentSet | null;
24
+ onHandleClick: (value: string) => void;
25
+ }
26
+
27
+ export const Marketplace: React.FC<IMarketPlaceProps> = ({
28
+ items,
29
+ atlasIMG,
30
+ atlasJSON,
31
+ onClose,
32
+ optionsType,
33
+ optionsRarity,
34
+ optionsPrice,
35
+ onChangeType,
36
+ onChangeRarity,
37
+ onChangeOrder,
38
+ onChangeNameInput,
39
+ scale,
40
+ equipmentSet,
41
+ onHandleClick,
42
+ }) => {
43
+ return (
44
+ <DraggableContainer
45
+ type={RPGUIContainerTypes.Framed}
46
+ onCloseButton={() => {
47
+ if (onClose) onClose();
48
+ }}
49
+ width="800px"
50
+ cancelDrag="#MarketContainer"
51
+ scale={scale}
52
+ >
53
+ <>
54
+ <InputWrapper>
55
+ <p> Search By Name</p>
56
+ <Input onChange={onChangeNameInput} placeholder={'Search...'} />
57
+ </InputWrapper>
58
+
59
+ <WrapperContainer>
60
+ <StyledDropdown
61
+ options={optionsType}
62
+ onChange={onChangeType}
63
+ width={'220px'}
64
+ />
65
+ <StyledDropdown
66
+ options={optionsRarity}
67
+ onChange={onChangeRarity}
68
+ width={'220px'}
69
+ />
70
+ <StyledDropdown
71
+ options={optionsPrice}
72
+ onChange={onChangeOrder}
73
+ width={'220px'}
74
+ />
75
+ </WrapperContainer>
76
+ <ItemComponentScrollWrapper id="MarketContainer">
77
+ {items?.map((item, index) => (
78
+ <MarketplaceRows
79
+ key={`${item.key}_${index}`}
80
+ atlasIMG={atlasIMG}
81
+ atlasJSON={atlasJSON}
82
+ item={item}
83
+ itemPrice={10}
84
+ equipmentSet={equipmentSet}
85
+ onHandleClick={onHandleClick}
86
+ />
87
+ ))}
88
+ </ItemComponentScrollWrapper>
89
+ </>
90
+ </DraggableContainer>
91
+ );
92
+ };
93
+
94
+ const InputWrapper = styled.div`
95
+ width: 95%;
96
+ display: flex;
97
+ justify-content: flex-start;
98
+ align-items: center;
99
+ margin: auto;
100
+ margin-bottom: 10px;
101
+ p {
102
+ width: auto;
103
+ margin-right: 20px;
104
+ }
105
+ input {
106
+ width: 68%;
107
+ height: 10px;
108
+ }
109
+ `;
110
+
111
+ const WrapperContainer = styled.div`
112
+ display: grid;
113
+ grid-template-columns: 30% 30% 30%;
114
+ justify-content: space-between;
115
+ width: 90%;
116
+ margin-left: 10px;
117
+ .rpgui-content .rpgui-dropdown-imp-header {
118
+ padding: 0px 10px 0 !important;
119
+ }
120
+ `;
121
+
122
+ const ItemComponentScrollWrapper = styled.div`
123
+ overflow-y: scroll;
124
+ height: 390px;
125
+ width: 100%;
126
+ margin-top: 1rem;
127
+ `;
128
+
129
+ const StyledDropdown = styled(Dropdown)`
130
+ margin: 3px !important;
131
+ width: 170px !important;
132
+ `;
@@ -0,0 +1,171 @@
1
+ import {
2
+ getItemTextureKeyPath,
3
+ IEquipmentSet,
4
+ IItem,
5
+ } from '@rpg-engine/shared';
6
+ import React from 'react';
7
+ import styled from 'styled-components';
8
+ import { uiColors } from '../../constants/uiColors';
9
+ import { uiFonts } from '../../constants/uiFonts';
10
+ import { Button, ButtonTypes } from '../Button';
11
+ import { ItemInfoWrapper } from '../Item/Cards/ItemInfoWrapper';
12
+ import { Ellipsis } from '../shared/Ellipsis';
13
+ import { SpriteFromAtlas } from '../shared/SpriteFromAtlas';
14
+
15
+ export interface IMarketPlaceRowsPropos {
16
+ atlasJSON: any;
17
+ atlasIMG: any;
18
+ item: IItem;
19
+ itemPrice: number;
20
+ equipmentSet?: IEquipmentSet | null;
21
+ scale?: number;
22
+ onHandleClick: (value: string) => void;
23
+ }
24
+
25
+ export const MarketplaceRows: React.FC<IMarketPlaceRowsPropos> = ({
26
+ atlasJSON,
27
+ atlasIMG,
28
+ item,
29
+ itemPrice,
30
+ equipmentSet,
31
+ scale,
32
+ onHandleClick,
33
+ }) => {
34
+ return (
35
+ <MarketPlaceWrapper>
36
+ <ItemIconContainer>
37
+ <SpriteContainer>
38
+ <ItemInfoWrapper
39
+ item={item}
40
+ atlasIMG={atlasIMG}
41
+ atlasJSON={atlasJSON}
42
+ equipmentSet={equipmentSet}
43
+ scale={scale}
44
+ >
45
+ <SpriteFromAtlas
46
+ atlasIMG={atlasIMG}
47
+ atlasJSON={atlasJSON}
48
+ spriteKey={getItemTextureKeyPath(
49
+ {
50
+ key: item.key,
51
+ stackQty: item.stackQty || 1,
52
+ texturePath: item.texturePath,
53
+ isStackable: item.isStackable,
54
+ },
55
+ atlasJSON
56
+ )}
57
+ imgScale={2}
58
+ />
59
+ </ItemInfoWrapper>
60
+ </SpriteContainer>
61
+ <PriceValue>
62
+ <p>
63
+ <Ellipsis maxLines={1} maxWidth="150px" fontSize="10px">
64
+ {item.name}
65
+ </Ellipsis>
66
+ </p>
67
+ </PriceValue>
68
+ </ItemIconContainer>
69
+ <QuantityContainer>
70
+ <QuantityDisplay>
71
+ <TextOverlay>
72
+ <Item>
73
+ <Ellipsis maxLines={1} maxWidth="150px" fontSize="10px">
74
+ {item.rarity}
75
+ </Ellipsis>
76
+ </Item>
77
+ </TextOverlay>
78
+ </QuantityDisplay>
79
+ </QuantityContainer>
80
+ <ItemIconContainer>
81
+ <SpriteContainer>
82
+ <SpriteFromAtlas
83
+ atlasIMG={atlasIMG}
84
+ atlasJSON={atlasJSON}
85
+ spriteKey={'others/gold-coin-qty-4.png'}
86
+ imgScale={2}
87
+ />
88
+ </SpriteContainer>
89
+ <PriceValue>
90
+ <p>
91
+ <Ellipsis maxLines={1} maxWidth="150px" fontSize="10px">
92
+ ${itemPrice}
93
+ </Ellipsis>
94
+ </p>
95
+ </PriceValue>
96
+ </ItemIconContainer>
97
+ <ButtonContainer>
98
+ <Button
99
+ buttonType={ButtonTypes.RPGUIButton}
100
+ onClick={() => onHandleClick(item.name)}
101
+ >
102
+ Buy
103
+ </Button>
104
+ </ButtonContainer>
105
+ </MarketPlaceWrapper>
106
+ );
107
+ };
108
+
109
+ const MarketPlaceWrapper = styled.div`
110
+ margin: auto;
111
+ display: grid;
112
+ grid-template-columns: 35% 20% 20% 25%;
113
+
114
+ &:hover {
115
+ background-color: ${uiColors.darkGray};
116
+ }
117
+ padding: 0.5rem;
118
+ p {
119
+ font-size: 0.8rem;
120
+ }
121
+ `;
122
+
123
+ const ItemIconContainer = styled.div`
124
+ display: flex;
125
+ justify-content: flex-start;
126
+ align-items: center;
127
+ `;
128
+
129
+ const SpriteContainer = styled.div`
130
+ position: relative;
131
+ top: -0.5rem;
132
+ left: 0.5rem;
133
+ `;
134
+
135
+ const Item = styled.span`
136
+ color: white;
137
+ text-align: center;
138
+ z-index: 1;
139
+ width: 100%;
140
+ `;
141
+
142
+ const TextOverlay = styled.div`
143
+ width: 100%;
144
+ position: relative;
145
+ `;
146
+
147
+ interface IContainerProps {
148
+ percentageWidth?: number;
149
+ minWidth?: number;
150
+ style?: Record<string, any>;
151
+ }
152
+
153
+ const QuantityContainer = styled.div<IContainerProps>`
154
+ position: relative;
155
+ display: flex;
156
+ min-width: 100px;
157
+ justify-content: center;
158
+ align-items: center;
159
+ `;
160
+
161
+ const QuantityDisplay = styled.div`
162
+ font-size: ${uiFonts.size.small};
163
+ `;
164
+
165
+ const PriceValue = styled.div`
166
+ margin-left: 40px;
167
+ `;
168
+
169
+ const ButtonContainer = styled.div`
170
+ margin: auto;
171
+ `;
@@ -0,0 +1,65 @@
1
+ import { ItemRarities, ItemType } from '@rpg-engine/shared';
2
+ import React from 'react';
3
+ import { IOptionsProps } from '../../Dropdown';
4
+
5
+ export enum OrderByType {
6
+ Name = 'Name',
7
+ Rarity = 'Rarity',
8
+ Price = 'Price',
9
+ DateAdded = 'Date Added',
10
+ }
11
+
12
+ export const itemTypeOptions: IOptionsProps[] = Object.values(ItemType).map(
13
+ (itemType, index) => ({
14
+ id: index + 1,
15
+ value: itemType,
16
+ option: itemType,
17
+ })
18
+ );
19
+
20
+ export const itemRarityOptions: IOptionsProps[] = Object.values(
21
+ ItemRarities
22
+ ).map((itemRarity, index) => ({
23
+ id: index + 1,
24
+ value: itemRarity,
25
+ option: itemRarity,
26
+ }));
27
+
28
+ export const orderByOptions: IOptionsProps[] = Object.values(
29
+ OrderByType
30
+ ).flatMap((orderBy, index) => [
31
+ {
32
+ id: index * 2 + 1,
33
+ value: orderBy,
34
+ option: (
35
+ <>
36
+ {orderBy}{' '}
37
+ <span
38
+ style={{
39
+ transform: 'translateY(-2px)',
40
+ display: 'inline-block',
41
+ }}
42
+ >
43
+
44
+ </span>
45
+ </>
46
+ ),
47
+ },
48
+ {
49
+ id: index * 2 + 2,
50
+ value: '-' + orderBy.toLowerCase(),
51
+ option: (
52
+ <>
53
+ {orderBy}{' '}
54
+ <span
55
+ style={{
56
+ transform: 'translateY(-2px)',
57
+ display: 'inline-block',
58
+ }}
59
+ >
60
+
61
+ </span>
62
+ </>
63
+ ),
64
+ },
65
+ ]);
@@ -35,6 +35,7 @@ const Container = styled.div<IContainerProps>`
35
35
  text-overflow: ellipsis;
36
36
  overflow: hidden;
37
37
  max-width: ${props => props.maxWidth};
38
+ font-size: ${props => props.fontSize};
38
39
 
39
40
  ${props => props.center && `margin: 0 auto;`}
40
41
  }
@@ -49,6 +50,7 @@ const Container = styled.div<IContainerProps>`
49
50
  -webkit-box-orient: vertical;
50
51
  text-overflow: ellipsis;
51
52
  overflow: hidden;
53
+ font-size: ${props => props.fontSize};
52
54
  }
53
55
  .ellipsis-3-lines {
54
56
  display: -webkit-box;
@@ -61,5 +63,6 @@ const Container = styled.div<IContainerProps>`
61
63
  -webkit-box-orient: vertical;
62
64
  text-overflow: ellipsis;
63
65
  overflow: hidden;
66
+ font-size: ${props => props.fontSize};
64
67
  }
65
68
  `;
package/src/index.tsx CHANGED
@@ -16,6 +16,8 @@ export * from './components/Item/Inventory/ItemContainer';
16
16
  export * from './components/Item/Inventory/ItemSlot';
17
17
  export * from './components/itemSelector/ItemSelector';
18
18
  export * from './components/ListMenu';
19
+ export * from './components/Marketplace/Marketplace';
20
+ export * from './components/Marketplace/MarketplaceRows';
19
21
  export * from './components/NPCDialog/NPCDialog';
20
22
  export * from './components/NPCDialog/NPCMultiDialog';
21
23
  export * from './components/NPCDialog/QuestionDialog/QuestionDialog';
@@ -0,0 +1,42 @@
1
+ import { Meta, Story } from '@storybook/react';
2
+ import React from 'react';
3
+ import { RPGUIRoot } from '..';
4
+ import { Marketplace } from '../components/Marketplace/Marketplace';
5
+ import {
6
+ itemRarityOptions,
7
+ itemTypeOptions,
8
+ orderByOptions,
9
+ } from '../components/Marketplace/__mocks__';
10
+ import atlasJSON from '../mocks/atlas/items/items.json';
11
+ import atlasIMG from '../mocks/atlas/items/items.png';
12
+ import { equipmentSetMock } from '../mocks/equipmentSet.mocks';
13
+ import { items } from '../mocks/itemContainer.mocks';
14
+
15
+ const meta: Meta = {
16
+ title: 'Marketplace',
17
+ component: Marketplace,
18
+ };
19
+
20
+ export default meta;
21
+
22
+ const Template: Story = () => (
23
+ <RPGUIRoot>
24
+ <Marketplace
25
+ onChangeOrder={value => console.log(value)}
26
+ onChangeRarity={value => console.log(value)}
27
+ onChangeType={value => console.log(value)}
28
+ onChangeNameInput={event => console.log(event.target.value)}
29
+ atlasIMG={atlasIMG}
30
+ atlasJSON={atlasJSON}
31
+ onClose={() => console.log('close')}
32
+ items={items}
33
+ optionsPrice={orderByOptions}
34
+ optionsRarity={itemRarityOptions}
35
+ optionsType={itemTypeOptions}
36
+ equipmentSet={equipmentSetMock}
37
+ onHandleClick={value => console.log(value)}
38
+ />
39
+ </RPGUIRoot>
40
+ );
41
+
42
+ export const Default = Template.bind({});
@@ -0,0 +1,28 @@
1
+ import { Meta, Story } from '@storybook/react';
2
+ import React from 'react';
3
+ import { RPGUIRoot } from '..';
4
+ import { MarketplaceRows } from '../components/Marketplace/MarketplaceRows';
5
+ import atlasJSON from '../mocks/atlas/items/items.json';
6
+ import atlasIMG from '../mocks/atlas/items/items.png';
7
+ import { items } from '../mocks/itemContainer.mocks';
8
+
9
+ const meta: Meta = {
10
+ title: 'MarketplaceRows',
11
+ component: MarketplaceRows,
12
+ };
13
+
14
+ export default meta;
15
+
16
+ const Template: Story = () => (
17
+ <RPGUIRoot>
18
+ <MarketplaceRows
19
+ atlasIMG={atlasIMG}
20
+ atlasJSON={atlasJSON}
21
+ itemPrice={10}
22
+ onHandleClick={value => console.log(value)}
23
+ item={items[0]}
24
+ />
25
+ </RPGUIRoot>
26
+ );
27
+
28
+ export const Default = Template.bind({});