@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpg-engine/long-bow",
3
- "version": "0.2.68",
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: React.FC<IButtonProps &
17
- React.DetailedHTMLProps<
18
- React.ButtonHTMLAttributes<HTMLButtonElement>,
19
- HTMLButtonElement
20
- >> = ({ disabled = false, children, buttonType, ...props }) => {
18
+ export const Button = ({
19
+ disabled = false,
20
+ children,
21
+ buttonType,
22
+ onClick,
23
+ ...props
24
+ }: IButtonProps) => {
21
25
  return (
22
- <ButtonContainer className={`${buttonType}`} disabled={disabled} {...props}>
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<any>`
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>{'Harvesting instruments'}</Title>
94
- <Subtitle>{'Use the tool, you need it'}</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.key}
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={`${option.key}`}
137
+ spriteKey={option.texturePath}
138
138
  imgScale={1}
139
139
  />
140
140
  <StyledItem>
@@ -1,41 +1,43 @@
1
- import { ICraftableItem } from "@rpg-engine/shared"
1
+ import { ICraftableItem } from '@rpg-engine/shared';
2
2
 
3
3
  export const craftableItems: ICraftableItem[] = [
4
- {
5
-
6
- canCraft: true,
7
- key: 'axes/frost-double-axe.png',
8
- name: 'rost-double-axe',
9
- ingredients: [
10
- {key: "crafting-resources/blue-sapphire.png", qty: 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
- canCraft: true,
25
- key: 'axes/frost-double-axe.png',
26
- name: 'rost-double-axe',
27
- ingredients: [
28
- {key: "crafting-resources/blue-sapphire.png", qty: 10},
29
- ]
30
- } , {
31
-
32
- canCraft: true,
33
- key: 'axes/frost-double-axe.png',
34
- name: 'rost-double-axe',
35
- ingredients: [
36
- {key: "crafting-resources/blue-sapphire.png", qty: 10},
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, { useState } from '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
- onStartStep={() => setShowGoNextIndicator(false)}
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: () => void;
10
- onStartStep: () => void;
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
- const hasNextChunk = textChunks?.[chunkIndex + 1] || false;
43
-
44
- if (hasNextChunk) {
45
- setChunkIndex(prev => prev + 1);
46
- } else {
47
- // if there's no more text chunks, close the dialog
48
- onClose();
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={onEndStep}
64
- onStart={onStartStep}
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
+ `;
@@ -0,0 +1,5 @@
1
+ import isMobile from 'is-mobile';
2
+
3
+ export const IS_MOBILE_OR_TABLET = isMobile({
4
+ tablet: true,
5
+ });