@rpg-engine/long-bow 0.2.68 → 0.2.70
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/Button.d.ts +3 -2
- package/dist/components/CraftBook/MockItems.d.ts +1 -1
- package/dist/components/NPCDialog/NPCDialogText.d.ts +4 -2
- package/dist/constants/uiDevices.d.ts +1 -0
- package/dist/long-bow.cjs.development.js +75 -53
- 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 +75 -53
- package/dist/long-bow.esm.js.map +1 -1
- package/package.json +2 -1
- package/src/components/Button.tsx +21 -8
- package/src/components/CraftBook/CraftBook.tsx +4 -4
- package/src/components/CraftBook/MockItems.ts +39 -37
- package/src/components/NPCDialog/NPCDialog.tsx +3 -27
- package/src/components/NPCDialog/NPCDialogText.tsx +55 -12
- package/src/components/NPCDialog/img/press-button.gif +0 -0
- package/src/constants/uiDevices.ts +5 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rpg-engine/long-bow",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.70",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
@@ -86,6 +86,7 @@
|
|
|
86
86
|
"@rpg-engine/shared": "^0.6.27",
|
|
87
87
|
"dayjs": "^1.11.2",
|
|
88
88
|
"fs-extra": "^10.1.0",
|
|
89
|
+
"is-mobile": "^3.1.1",
|
|
89
90
|
"lodash": "^4.17.21",
|
|
90
91
|
"lodash-es": "^4.17.21",
|
|
91
92
|
"mobx": "^6.6.0",
|
|
@@ -7,25 +7,38 @@ export enum ButtonTypes {
|
|
|
7
7
|
RPGUIGoldButton = 'rpgui-button golden',
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
export interface IButtonProps
|
|
10
|
+
export interface IButtonProps
|
|
11
|
+
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
11
12
|
disabled?: boolean;
|
|
12
13
|
children: React.ReactNode;
|
|
13
14
|
buttonType: ButtonTypes;
|
|
15
|
+
onClick?: (e: any) => void;
|
|
14
16
|
}
|
|
15
17
|
|
|
16
|
-
export const Button
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
export const Button = ({
|
|
19
|
+
disabled = false,
|
|
20
|
+
children,
|
|
21
|
+
buttonType,
|
|
22
|
+
onClick,
|
|
23
|
+
...props
|
|
24
|
+
}: IButtonProps) => {
|
|
21
25
|
return (
|
|
22
|
-
<ButtonContainer
|
|
26
|
+
<ButtonContainer
|
|
27
|
+
className={`${buttonType}`}
|
|
28
|
+
disabled={disabled}
|
|
29
|
+
{...props}
|
|
30
|
+
onTouchStart={e => {
|
|
31
|
+
if (onClick) {
|
|
32
|
+
onClick(e);
|
|
33
|
+
}
|
|
34
|
+
}}
|
|
35
|
+
>
|
|
23
36
|
<p>{children}</p>
|
|
24
37
|
</ButtonContainer>
|
|
25
38
|
);
|
|
26
39
|
};
|
|
27
40
|
|
|
28
|
-
const ButtonContainer = styled.button
|
|
41
|
+
const ButtonContainer = styled.button`
|
|
29
42
|
height: 45px;
|
|
30
43
|
font-size: ${uiFonts.size.small};
|
|
31
44
|
`;
|
|
@@ -90,8 +90,8 @@ export const CraftBook: React.FC<IItemCraftSelectorProps> = ({
|
|
|
90
90
|
}}
|
|
91
91
|
>
|
|
92
92
|
<div style={{ width: '100%' }}>
|
|
93
|
-
<Title>{'
|
|
94
|
-
<Subtitle>{'
|
|
93
|
+
<Title>{'Craftbook'}</Title>
|
|
94
|
+
<Subtitle>{'Select an item to craft'}</Subtitle>
|
|
95
95
|
<hr className="golden" />
|
|
96
96
|
</div>
|
|
97
97
|
<Dropdown
|
|
@@ -105,7 +105,7 @@ export const CraftBook: React.FC<IItemCraftSelectorProps> = ({
|
|
|
105
105
|
<SpriteFromAtlas
|
|
106
106
|
atlasIMG={atlasIMG}
|
|
107
107
|
atlasJSON={atlasJSON}
|
|
108
|
-
spriteKey={option.
|
|
108
|
+
spriteKey={option.texturePath}
|
|
109
109
|
imgScale={3}
|
|
110
110
|
grayScale={!option.canCraft}
|
|
111
111
|
/>
|
|
@@ -134,7 +134,7 @@ export const CraftBook: React.FC<IItemCraftSelectorProps> = ({
|
|
|
134
134
|
<SpriteFromAtlas
|
|
135
135
|
atlasIMG={atlasIMG}
|
|
136
136
|
atlasJSON={atlasJSON}
|
|
137
|
-
spriteKey={
|
|
137
|
+
spriteKey={option.texturePath}
|
|
138
138
|
imgScale={1}
|
|
139
139
|
/>
|
|
140
140
|
<StyledItem>
|
|
@@ -1,41 +1,43 @@
|
|
|
1
|
-
import { ICraftableItem } from
|
|
1
|
+
import { ICraftableItem } from '@rpg-engine/shared';
|
|
2
2
|
|
|
3
3
|
export const craftableItems: ICraftableItem[] = [
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
canCraft: true,
|
|
16
|
-
key: 'axes/frost-double-axe.png',
|
|
17
|
-
name: 'rost-double-axe',
|
|
18
|
-
ingredients: [
|
|
19
|
-
{key: "crafting-resources/blue-sapphire.png", qty: 10},
|
|
20
|
-
]
|
|
4
|
+
{
|
|
5
|
+
canCraft: true,
|
|
6
|
+
key: 'frost-double-axe',
|
|
7
|
+
texturePath: 'axes/frost-double-axe.png',
|
|
8
|
+
name: 'Frost Double Axe',
|
|
9
|
+
ingredients: [
|
|
10
|
+
{
|
|
11
|
+
key: 'blue-sapphire',
|
|
12
|
+
qty: 10,
|
|
13
|
+
texturePath: 'crafting-resources/blue-sapphire.png',
|
|
21
14
|
},
|
|
15
|
+
],
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
key: 'frost-double-axe',
|
|
19
|
+
canCraft: true,
|
|
20
|
+
texturePath: 'axes/frost-double-axe.png',
|
|
21
|
+
name: 'Frost Double Axe',
|
|
22
|
+
ingredients: [
|
|
22
23
|
{
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
24
|
+
key: 'blue-sapphire',
|
|
25
|
+
texturePath: 'crafting-resources/blue-sapphire.png',
|
|
26
|
+
qty: 10,
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
key: 'frost-double-axe',
|
|
32
|
+
canCraft: false,
|
|
33
|
+
texturePath: 'axes/frost-double-axe.png',
|
|
34
|
+
name: 'Frost Double Axe',
|
|
35
|
+
ingredients: [
|
|
36
|
+
{
|
|
37
|
+
key: 'blue-sapphire',
|
|
38
|
+
texturePath: 'crafting-resources/blue-sapphire.png',
|
|
39
|
+
qty: 10,
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
];
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
import { RPGUIContainer, RPGUIContainerTypes } from '../RPGUIContainer';
|
|
4
|
-
import aliceDefaultThumbnail from './img/npcDialog/npcThumbnails/alice.png';
|
|
5
|
-
import pressSpaceGif from './img/space.gif';
|
|
6
4
|
import { NPCDialogText } from './NPCDialogText';
|
|
7
5
|
import {
|
|
8
6
|
IQuestionDialog,
|
|
9
7
|
IQuestionDialogAnswer,
|
|
10
8
|
QuestionDialog,
|
|
11
9
|
} from './QuestionDialog/QuestionDialog';
|
|
10
|
+
import aliceDefaultThumbnail from './img/npcDialog/npcThumbnails/alice.png';
|
|
12
11
|
|
|
13
12
|
export enum NPCDialogType {
|
|
14
13
|
TextOnly = 'TextOnly',
|
|
@@ -34,10 +33,6 @@ export const NPCDialog: React.FC<INPCDialogProps> = ({
|
|
|
34
33
|
questions,
|
|
35
34
|
answers,
|
|
36
35
|
}) => {
|
|
37
|
-
const [showGoNextIndicator, setShowGoNextIndicator] = useState<boolean>(
|
|
38
|
-
false
|
|
39
|
-
);
|
|
40
|
-
|
|
41
36
|
return (
|
|
42
37
|
<RPGUIContainer
|
|
43
38
|
type={RPGUIContainerTypes.FramedGold}
|
|
@@ -72,8 +67,7 @@ export const NPCDialog: React.FC<INPCDialogProps> = ({
|
|
|
72
67
|
flex={type === NPCDialogType.TextAndThumbnail ? '70%' : '100%'}
|
|
73
68
|
>
|
|
74
69
|
<NPCDialogText
|
|
75
|
-
|
|
76
|
-
onEndStep={() => setShowGoNextIndicator(true)}
|
|
70
|
+
type={type}
|
|
77
71
|
text={text || 'No text provided.'}
|
|
78
72
|
onClose={() => {
|
|
79
73
|
if (onClose) {
|
|
@@ -88,12 +82,6 @@ export const NPCDialog: React.FC<INPCDialogProps> = ({
|
|
|
88
82
|
</ThumbnailContainer>
|
|
89
83
|
)}
|
|
90
84
|
</Container>
|
|
91
|
-
{showGoNextIndicator && (
|
|
92
|
-
<PressSpaceIndicator
|
|
93
|
-
right={type === NPCDialogType.TextOnly ? '1rem' : '10.5rem'}
|
|
94
|
-
src={pressSpaceGif}
|
|
95
|
-
/>
|
|
96
|
-
)}
|
|
97
85
|
</>
|
|
98
86
|
)}
|
|
99
87
|
</RPGUIContainer>
|
|
@@ -131,15 +119,3 @@ const NPCThumbnail = styled.img`
|
|
|
131
119
|
height: 128px;
|
|
132
120
|
width: 128px;
|
|
133
121
|
`;
|
|
134
|
-
|
|
135
|
-
interface IPressSpaceIndicatorProps {
|
|
136
|
-
right: string;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const PressSpaceIndicator = styled.img<IPressSpaceIndicatorProps>`
|
|
140
|
-
position: absolute;
|
|
141
|
-
right: ${({ right }) => right};
|
|
142
|
-
bottom: 1rem;
|
|
143
|
-
height: 20.7px;
|
|
144
|
-
image-rendering: -webkit-optimize-contrast;
|
|
145
|
-
`;
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useState } from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
|
+
import { NPCDialogType } from '../..';
|
|
4
|
+
import { IS_MOBILE_OR_TABLET } from '../../constants/uiDevices';
|
|
3
5
|
import { chunkString } from '../../libs/StringHelpers';
|
|
4
6
|
import { DynamicText } from '../typography/DynamicText';
|
|
7
|
+
import pressButtonGif from './img/press-button.gif';
|
|
8
|
+
import pressSpaceGif from './img/space.gif';
|
|
5
9
|
|
|
6
10
|
interface IProps {
|
|
7
11
|
text: string;
|
|
8
12
|
onClose: () => void;
|
|
9
|
-
onEndStep
|
|
10
|
-
onStartStep
|
|
13
|
+
onEndStep?: () => void;
|
|
14
|
+
onStartStep?: () => void;
|
|
15
|
+
type?: NPCDialogType;
|
|
11
16
|
}
|
|
12
17
|
|
|
13
18
|
export const NPCDialogText: React.FC<IProps> = ({
|
|
@@ -15,6 +20,7 @@ export const NPCDialogText: React.FC<IProps> = ({
|
|
|
15
20
|
onClose,
|
|
16
21
|
onEndStep,
|
|
17
22
|
onStartStep,
|
|
23
|
+
type,
|
|
18
24
|
}) => {
|
|
19
25
|
const windowSize = useRef([window.innerWidth, window.innerHeight]);
|
|
20
26
|
function maxCharacters(width: number) {
|
|
@@ -39,14 +45,18 @@ export const NPCDialogText: React.FC<IProps> = ({
|
|
|
39
45
|
const [chunkIndex, setChunkIndex] = useState<number>(0);
|
|
40
46
|
const onHandleSpacePress = (event: KeyboardEvent) => {
|
|
41
47
|
if (event.code === 'Space') {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
goToNextStep();
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const goToNextStep = () => {
|
|
53
|
+
const hasNextChunk = textChunks?.[chunkIndex + 1] || false;
|
|
54
|
+
|
|
55
|
+
if (hasNextChunk) {
|
|
56
|
+
setChunkIndex(prev => prev + 1);
|
|
57
|
+
} else {
|
|
58
|
+
// if there's no more text chunks, close the dialog
|
|
59
|
+
onClose();
|
|
50
60
|
}
|
|
51
61
|
};
|
|
52
62
|
|
|
@@ -56,15 +66,48 @@ export const NPCDialogText: React.FC<IProps> = ({
|
|
|
56
66
|
return () => document.removeEventListener('keydown', onHandleSpacePress);
|
|
57
67
|
}, [chunkIndex]);
|
|
58
68
|
|
|
69
|
+
const [showGoNextIndicator, setShowGoNextIndicator] = useState<boolean>(
|
|
70
|
+
false
|
|
71
|
+
);
|
|
72
|
+
|
|
59
73
|
return (
|
|
60
74
|
<Container>
|
|
61
75
|
<DynamicText
|
|
62
76
|
text={textChunks?.[chunkIndex] || ''}
|
|
63
|
-
onFinish={
|
|
64
|
-
|
|
77
|
+
onFinish={() => {
|
|
78
|
+
setShowGoNextIndicator(true);
|
|
79
|
+
|
|
80
|
+
onEndStep && onEndStep();
|
|
81
|
+
}}
|
|
82
|
+
onStart={() => {
|
|
83
|
+
setShowGoNextIndicator(false);
|
|
84
|
+
|
|
85
|
+
onStartStep && onStartStep();
|
|
86
|
+
}}
|
|
65
87
|
/>
|
|
88
|
+
{showGoNextIndicator && (
|
|
89
|
+
<PressSpaceIndicator
|
|
90
|
+
right={type === NPCDialogType.TextOnly ? '1rem' : '10.5rem'}
|
|
91
|
+
src={IS_MOBILE_OR_TABLET ? pressButtonGif : pressSpaceGif}
|
|
92
|
+
onClick={() => {
|
|
93
|
+
goToNextStep();
|
|
94
|
+
}}
|
|
95
|
+
/>
|
|
96
|
+
)}
|
|
66
97
|
</Container>
|
|
67
98
|
);
|
|
68
99
|
};
|
|
69
100
|
|
|
70
101
|
const Container = styled.div``;
|
|
102
|
+
|
|
103
|
+
interface IPressSpaceIndicatorProps {
|
|
104
|
+
right: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const PressSpaceIndicator = styled.img<IPressSpaceIndicatorProps>`
|
|
108
|
+
position: absolute;
|
|
109
|
+
right: ${({ right }) => right};
|
|
110
|
+
bottom: 1rem;
|
|
111
|
+
height: 20.7px;
|
|
112
|
+
image-rendering: -webkit-optimize-contrast;
|
|
113
|
+
`;
|
|
Binary file
|