@rpg-engine/long-bow 0.8.21 → 0.8.22
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/InformationCenter/InformationCenter.d.ts +16 -13
- package/dist/components/InformationCenter/sections/bestiary/InformationCenterBestiarySection.d.ts +1 -1
- package/dist/components/InformationCenter/sections/bestiary/InformationCenterNPCDetails.d.ts +2 -1
- package/dist/components/InformationCenter/sections/bestiary/InformationCenterNPCTooltip.d.ts +1 -1
- package/dist/components/InformationCenter/sections/faq/InformationCenterFaqSection.d.ts +1 -1
- package/dist/components/InformationCenter/sections/items/InformationCenterItemDetails.d.ts +1 -1
- package/dist/components/InformationCenter/sections/items/InformationCenterItemTooltip.d.ts +1 -1
- package/dist/components/InformationCenter/sections/items/InformationCenterItemsSection.d.ts +2 -1
- package/dist/components/InformationCenter/sections/tutorials/InformationCenterTutorialsSection.d.ts +1 -1
- package/dist/long-bow.cjs.development.js +788 -687
- 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 +789 -688
- package/dist/long-bow.esm.js.map +1 -1
- package/dist/mocks/informationCenter.mocks.d.ts +1 -2
- package/package.json +2 -2
- package/src/components/CraftBook/CraftBook.tsx +1 -1
- package/src/components/Dropdown.tsx +25 -3
- package/src/components/InformationCenter/InformationCenter.tsx +125 -124
- package/src/components/InformationCenter/sections/bestiary/InformationCenterBestiarySection.tsx +52 -7
- package/src/components/InformationCenter/sections/bestiary/InformationCenterNPCDetails.tsx +201 -207
- package/src/components/InformationCenter/sections/bestiary/InformationCenterNPCTooltip.tsx +7 -6
- package/src/components/InformationCenter/sections/faq/InformationCenterFaqSection.tsx +1 -1
- package/src/components/InformationCenter/sections/items/InformationCenterItemDetails.tsx +8 -6
- package/src/components/InformationCenter/sections/items/InformationCenterItemTooltip.tsx +1 -1
- package/src/components/InformationCenter/sections/items/InformationCenterItemsSection.tsx +36 -10
- package/src/components/InformationCenter/sections/tutorials/InformationCenterTutorialsSection.tsx +133 -34
- package/src/mocks/informationCenter.mocks.ts +158 -47
- package/src/stories/UI/info/InformationCenter.stories.tsx +1 -1
- package/dist/components/InformationCenter/InformationCenterTypes.d.ts +0 -96
- package/src/components/InformationCenter/InformationCenterTypes.ts +0 -105
package/src/components/InformationCenter/sections/tutorials/InformationCenterTutorialsSection.tsx
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
IVideoGuide,
|
|
3
|
+
VideoGuideCategory,
|
|
4
|
+
VideoGuideLanguage,
|
|
5
|
+
} from '@rpg-engine/shared';
|
|
6
|
+
import React, { useMemo, useState } from 'react';
|
|
2
7
|
import styled from 'styled-components';
|
|
3
8
|
import { uiColors } from '../../../../constants/uiColors';
|
|
4
9
|
import { IOptionsProps } from '../../../Dropdown';
|
|
5
10
|
import { PaginatedContent } from '../../../shared/PaginatedContent/PaginatedContent';
|
|
6
|
-
|
|
11
|
+
|
|
12
|
+
import { formatItemType } from '../items/InformationCenterItemsSection';
|
|
7
13
|
|
|
8
14
|
interface ITutorialsSectionProps {
|
|
9
15
|
videoGuides: IVideoGuide[];
|
|
@@ -11,6 +17,9 @@ interface ITutorialsSectionProps {
|
|
|
11
17
|
tabId: string;
|
|
12
18
|
}
|
|
13
19
|
|
|
20
|
+
const ITEMS_PER_PAGE = 3;
|
|
21
|
+
const GRID_COLUMNS = 3;
|
|
22
|
+
|
|
14
23
|
export const InformationCenterTutorialsSection: React.FC<ITutorialsSectionProps> = ({
|
|
15
24
|
videoGuides,
|
|
16
25
|
initialSearchQuery,
|
|
@@ -18,37 +27,96 @@ export const InformationCenterTutorialsSection: React.FC<ITutorialsSectionProps>
|
|
|
18
27
|
}) => {
|
|
19
28
|
const [searchQuery, setSearchQuery] = useState(initialSearchQuery);
|
|
20
29
|
const [selectedCategory, setSelectedCategory] = useState<string>('all');
|
|
30
|
+
const [, setCurrentPage] = useState(1);
|
|
21
31
|
|
|
32
|
+
const getYouTubeThumbnail = (videoUrl: string): string => {
|
|
33
|
+
const regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=)([^#&?]*).*/;
|
|
34
|
+
const match = videoUrl.match(regExp);
|
|
35
|
+
const videoId = match && match[2].length === 11 ? match[2] : null;
|
|
36
|
+
|
|
37
|
+
return videoId
|
|
38
|
+
? `https://img.youtube.com/vi/${videoId}/hqdefault.jpg`
|
|
39
|
+
: '/placeholder-thumbnail.png';
|
|
40
|
+
};
|
|
22
41
|
const categoryOptions: IOptionsProps[] = [
|
|
23
|
-
{ id: 0, value: 'all', option: 'All' },
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
42
|
+
{ id: 0, value: 'all', option: 'All Categories' },
|
|
43
|
+
...(VideoGuideCategory
|
|
44
|
+
? Object.entries(VideoGuideCategory).map(([, value], index) => ({
|
|
45
|
+
id: index + 1,
|
|
46
|
+
value: value as string,
|
|
47
|
+
option: formatItemType(value),
|
|
48
|
+
}))
|
|
49
|
+
: []),
|
|
50
|
+
...(VideoGuideLanguage
|
|
51
|
+
? Object.entries(VideoGuideLanguage).map(([, value], index) => ({
|
|
52
|
+
id:
|
|
53
|
+
index +
|
|
54
|
+
(VideoGuideCategory
|
|
55
|
+
? Object.entries(VideoGuideCategory).length
|
|
56
|
+
: 0) +
|
|
57
|
+
1,
|
|
58
|
+
value: value as string,
|
|
59
|
+
option: formatItemType(value),
|
|
60
|
+
}))
|
|
61
|
+
: []),
|
|
28
62
|
];
|
|
29
63
|
|
|
64
|
+
const handleVideoClick = (videoUrl: string) => {
|
|
65
|
+
window.open(videoUrl, '_blank', 'noopener,noreferrer');
|
|
66
|
+
};
|
|
67
|
+
|
|
30
68
|
const renderItem = (guide: IVideoGuide) => (
|
|
31
|
-
<GuideItem key={guide.id}>
|
|
69
|
+
<GuideItem key={guide.id} onClick={() => handleVideoClick(guide.videoUrl)}>
|
|
32
70
|
<GuideThumbnail>
|
|
33
71
|
<img
|
|
34
|
-
src={guide.
|
|
72
|
+
src={guide.localImage || getYouTubeThumbnail(guide.videoUrl)}
|
|
35
73
|
alt={guide.title}
|
|
36
74
|
/>
|
|
37
75
|
</GuideThumbnail>
|
|
38
76
|
<GuideContent>
|
|
39
77
|
<GuideTitle>{guide.title}</GuideTitle>
|
|
40
78
|
<GuideDescription>{guide.description}</GuideDescription>
|
|
41
|
-
<
|
|
79
|
+
<GuideLabelsContainer>
|
|
80
|
+
<GuideCategory>{guide.category}</GuideCategory>
|
|
81
|
+
<GuideLanguage>{guide.language}</GuideLanguage>
|
|
82
|
+
</GuideLabelsContainer>
|
|
42
83
|
</GuideContent>
|
|
43
84
|
</GuideItem>
|
|
44
85
|
);
|
|
45
86
|
|
|
46
|
-
const filteredGuides =
|
|
47
|
-
guide =>
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
guide.description.toLowerCase().includes(searchQuery.toLowerCase())
|
|
51
|
-
|
|
87
|
+
const filteredGuides = useMemo(() => {
|
|
88
|
+
return videoGuides.filter(guide => {
|
|
89
|
+
const matchesSearch =
|
|
90
|
+
guide.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
|
91
|
+
guide.description.toLowerCase().includes(searchQuery.toLowerCase());
|
|
92
|
+
|
|
93
|
+
const matchesCategory =
|
|
94
|
+
selectedCategory === 'all' ||
|
|
95
|
+
(Object.values(VideoGuideCategory).includes(
|
|
96
|
+
selectedCategory as VideoGuideCategory
|
|
97
|
+
) &&
|
|
98
|
+
guide.category === selectedCategory) ||
|
|
99
|
+
(Object.values(VideoGuideLanguage).includes(
|
|
100
|
+
selectedCategory as VideoGuideLanguage
|
|
101
|
+
) &&
|
|
102
|
+
guide.language === selectedCategory);
|
|
103
|
+
|
|
104
|
+
return matchesSearch && matchesCategory;
|
|
105
|
+
});
|
|
106
|
+
}, [videoGuides, searchQuery, selectedCategory]);
|
|
107
|
+
|
|
108
|
+
const handleSearchChange = (newQuery: string) => {
|
|
109
|
+
setSearchQuery(newQuery);
|
|
110
|
+
setCurrentPage(1);
|
|
111
|
+
if (newQuery && selectedCategory !== 'all') {
|
|
112
|
+
setSelectedCategory('all');
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const handleCategoryChange = (category: string) => {
|
|
117
|
+
setSelectedCategory(category);
|
|
118
|
+
setCurrentPage(1);
|
|
119
|
+
};
|
|
52
120
|
|
|
53
121
|
return (
|
|
54
122
|
<PaginatedContent<IVideoGuide>
|
|
@@ -57,20 +125,20 @@ export const InformationCenterTutorialsSection: React.FC<ITutorialsSectionProps>
|
|
|
57
125
|
emptyMessage="No guides found"
|
|
58
126
|
searchOptions={{
|
|
59
127
|
value: searchQuery,
|
|
60
|
-
onChange:
|
|
128
|
+
onChange: handleSearchChange,
|
|
61
129
|
placeholder: 'Search guides...',
|
|
62
130
|
}}
|
|
63
131
|
filterOptions={{
|
|
64
132
|
options: categoryOptions,
|
|
65
133
|
selectedOption: selectedCategory,
|
|
66
|
-
onOptionChange:
|
|
134
|
+
onOptionChange: handleCategoryChange,
|
|
67
135
|
}}
|
|
68
136
|
dependencies={[selectedCategory]}
|
|
69
137
|
tabId={tabId}
|
|
70
138
|
layout="grid"
|
|
71
|
-
gridColumns={
|
|
72
|
-
itemsPerPage={
|
|
73
|
-
itemHeight="
|
|
139
|
+
gridColumns={GRID_COLUMNS}
|
|
140
|
+
itemsPerPage={ITEMS_PER_PAGE}
|
|
141
|
+
itemHeight="320px"
|
|
74
142
|
/>
|
|
75
143
|
);
|
|
76
144
|
};
|
|
@@ -82,7 +150,10 @@ const GuideItem = styled.div`
|
|
|
82
150
|
border: 1px solid ${uiColors.darkGray};
|
|
83
151
|
cursor: pointer;
|
|
84
152
|
transition: transform 0.2s ease;
|
|
153
|
+
display: flex;
|
|
154
|
+
flex-direction: column;
|
|
85
155
|
height: 100%;
|
|
156
|
+
padding: 0;
|
|
86
157
|
&:hover {
|
|
87
158
|
transform: translateY(-2px);
|
|
88
159
|
}
|
|
@@ -99,37 +170,65 @@ const GuideThumbnail = styled.div`
|
|
|
99
170
|
height: 100%;
|
|
100
171
|
object-fit: cover;
|
|
101
172
|
}
|
|
102
|
-
|
|
103
|
-
font-size: 0.8rem;
|
|
104
|
-
line-height: 1.8;
|
|
105
173
|
`;
|
|
106
174
|
|
|
107
175
|
const GuideContent = styled.div`
|
|
108
|
-
padding: 12px;
|
|
176
|
+
padding: 0 12px 12px;
|
|
177
|
+
flex: 1;
|
|
178
|
+
display: flex;
|
|
179
|
+
flex-direction: column;
|
|
109
180
|
`;
|
|
110
181
|
|
|
111
182
|
const GuideTitle = styled.h3`
|
|
112
183
|
margin: 0;
|
|
113
|
-
font-size: 0.6rem;
|
|
184
|
+
font-size: 0.6rem !important;
|
|
114
185
|
color: ${uiColors.yellow};
|
|
115
186
|
font-family: 'Press Start 2P', cursive;
|
|
116
|
-
margin-bottom:
|
|
187
|
+
margin-bottom: 5px;
|
|
117
188
|
`;
|
|
118
189
|
|
|
119
190
|
const GuideDescription = styled.p`
|
|
120
191
|
margin: 0;
|
|
121
|
-
font-size: 0.
|
|
192
|
+
font-size: 0.5rem !important;
|
|
122
193
|
color: ${uiColors.lightGray};
|
|
194
|
+
text-align: center;
|
|
123
195
|
font-family: 'Press Start 2P', cursive;
|
|
124
196
|
margin-bottom: 8px;
|
|
125
197
|
line-height: 1.4;
|
|
126
198
|
`;
|
|
127
199
|
|
|
128
|
-
const GuideCategory = styled.
|
|
129
|
-
font-size: 0.5rem;
|
|
130
|
-
color: ${uiColors.yellow};
|
|
200
|
+
const GuideCategory = styled.label`
|
|
201
|
+
font-size: 0.5rem !important;
|
|
131
202
|
font-family: 'Press Start 2P', cursive;
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
203
|
+
color: ${uiColors.yellow} !important;
|
|
204
|
+
line-height: 1.4;
|
|
205
|
+
|
|
206
|
+
&::before {
|
|
207
|
+
content: '🏷️';
|
|
208
|
+
padding-right: 6px;
|
|
209
|
+
font-size: 0.7rem;
|
|
210
|
+
transform: translateY(-2px);
|
|
211
|
+
display: inline-block;
|
|
212
|
+
}
|
|
213
|
+
`;
|
|
214
|
+
|
|
215
|
+
const GuideLanguage = styled.label`
|
|
216
|
+
font-size: 0.5rem !important;
|
|
217
|
+
font-family: 'Press Start 2P', cursive;
|
|
218
|
+
color: ${uiColors.blue} !important;
|
|
219
|
+
line-height: 1.4;
|
|
220
|
+
|
|
221
|
+
&::before {
|
|
222
|
+
content: '🌐';
|
|
223
|
+
padding-right: 6px;
|
|
224
|
+
font-size: 0.6rem;
|
|
225
|
+
transform: translateY(-2px);
|
|
226
|
+
display: inline-block;
|
|
227
|
+
}
|
|
228
|
+
`;
|
|
229
|
+
|
|
230
|
+
const GuideLabelsContainer = styled.div`
|
|
231
|
+
display: flex;
|
|
232
|
+
justify-content: space-between;
|
|
233
|
+
padding: 0 6px 6px;
|
|
135
234
|
`;
|
|
@@ -3,25 +3,25 @@ import {
|
|
|
3
3
|
CharacterBuffDurationType,
|
|
4
4
|
CharacterBuffType,
|
|
5
5
|
EntityAttackType,
|
|
6
|
+
EntityEffectBlueprint,
|
|
7
|
+
IFaqItem,
|
|
8
|
+
IInformationCenterItem,
|
|
9
|
+
IInformationCenterNPC,
|
|
6
10
|
ItemRarities,
|
|
7
11
|
ItemSlotType,
|
|
8
12
|
ItemSubType,
|
|
9
13
|
ItemType,
|
|
14
|
+
IVideoGuide,
|
|
15
|
+
LootProbability,
|
|
16
|
+
MovementSpeed,
|
|
10
17
|
NPCAlignment,
|
|
11
18
|
NPCSubtype,
|
|
12
19
|
RangeTypes,
|
|
20
|
+
SpellsBlueprint,
|
|
21
|
+
VideoGuideCategory,
|
|
22
|
+
VideoGuideLanguage
|
|
13
23
|
} from '@rpg-engine/shared';
|
|
14
|
-
|
|
15
|
-
IFaqItem,
|
|
16
|
-
IVideoGuide,
|
|
17
|
-
} from '../components/InformationCenter/InformationCenter';
|
|
18
|
-
import {
|
|
19
|
-
EntityEffectBlueprint,
|
|
20
|
-
IInformationCenterItem,
|
|
21
|
-
IInformationCenterNPC,
|
|
22
|
-
LootProbability,
|
|
23
|
-
MovementSpeed,
|
|
24
|
-
} from '../components/InformationCenter/InformationCenterTypes';
|
|
24
|
+
|
|
25
25
|
|
|
26
26
|
export const mockBestiaryItems: IInformationCenterNPC[] = [
|
|
27
27
|
{
|
|
@@ -34,6 +34,7 @@ export const mockBestiaryItems: IInformationCenterNPC[] = [
|
|
|
34
34
|
maxRangeAttack: RangeTypes.High,
|
|
35
35
|
speed: MovementSpeed.Standard,
|
|
36
36
|
baseHealth: 5000,
|
|
37
|
+
isBoss: true,
|
|
37
38
|
skills: {
|
|
38
39
|
level: 300,
|
|
39
40
|
strength: { level: 280 },
|
|
@@ -82,6 +83,7 @@ export const mockBestiaryItems: IInformationCenterNPC[] = [
|
|
|
82
83
|
maxRangeAttack: RangeTypes.High,
|
|
83
84
|
speed: MovementSpeed.Standard,
|
|
84
85
|
baseHealth: 800,
|
|
86
|
+
isBoss: false,
|
|
85
87
|
skills: {
|
|
86
88
|
level: 85,
|
|
87
89
|
strength: { level: 95 },
|
|
@@ -120,6 +122,7 @@ export const mockBestiaryItems: IInformationCenterNPC[] = [
|
|
|
120
122
|
maxRangeAttack: RangeTypes.High,
|
|
121
123
|
speed: MovementSpeed.Standard,
|
|
122
124
|
baseHealth: 400,
|
|
125
|
+
isBoss: false,
|
|
123
126
|
skills: {
|
|
124
127
|
level: 45,
|
|
125
128
|
strength: { level: 50 },
|
|
@@ -161,6 +164,7 @@ export const mockBestiaryItems: IInformationCenterNPC[] = [
|
|
|
161
164
|
maxRangeAttack: RangeTypes.High,
|
|
162
165
|
speed: MovementSpeed.Fast,
|
|
163
166
|
baseHealth: 350,
|
|
167
|
+
isBoss: false,
|
|
164
168
|
skills: {
|
|
165
169
|
level: 40,
|
|
166
170
|
strength: { level: 45 },
|
|
@@ -195,6 +199,7 @@ export const mockBestiaryItems: IInformationCenterNPC[] = [
|
|
|
195
199
|
maxRangeAttack: RangeTypes.High,
|
|
196
200
|
speed: MovementSpeed.Fast,
|
|
197
201
|
baseHealth: 420,
|
|
202
|
+
isBoss: false,
|
|
198
203
|
skills: {
|
|
199
204
|
level: 50,
|
|
200
205
|
strength: { level: 55 },
|
|
@@ -236,6 +241,7 @@ export const mockBestiaryItems: IInformationCenterNPC[] = [
|
|
|
236
241
|
maxRangeAttack: RangeTypes.High,
|
|
237
242
|
speed: MovementSpeed.Standard,
|
|
238
243
|
baseHealth: 2200,
|
|
244
|
+
isBoss: false,
|
|
239
245
|
skills: {
|
|
240
246
|
level: 200,
|
|
241
247
|
strength: { level: 160 },
|
|
@@ -288,6 +294,7 @@ export const mockBestiaryItems: IInformationCenterNPC[] = [
|
|
|
288
294
|
maxRangeAttack: RangeTypes.High,
|
|
289
295
|
speed: MovementSpeed.Slow,
|
|
290
296
|
baseHealth: 1800,
|
|
297
|
+
isBoss: false,
|
|
291
298
|
skills: {
|
|
292
299
|
level: 150,
|
|
293
300
|
strength: { level: 180 },
|
|
@@ -333,6 +340,7 @@ export const mockBestiaryItems: IInformationCenterNPC[] = [
|
|
|
333
340
|
maxRangeAttack: RangeTypes.High,
|
|
334
341
|
speed: MovementSpeed.Standard,
|
|
335
342
|
baseHealth: 1200,
|
|
343
|
+
isBoss: false,
|
|
336
344
|
skills: {
|
|
337
345
|
level: 100,
|
|
338
346
|
strength: { level: 130 },
|
|
@@ -368,6 +376,108 @@ export const mockBestiaryItems: IInformationCenterNPC[] = [
|
|
|
368
376
|
},
|
|
369
377
|
],
|
|
370
378
|
},
|
|
379
|
+
{
|
|
380
|
+
id: '9',
|
|
381
|
+
name: "Red Deer",
|
|
382
|
+
subType: NPCSubtype.Animal,
|
|
383
|
+
key: 'red-deer/up/walking/2.png',
|
|
384
|
+
alignment: NPCAlignment.Neutral,
|
|
385
|
+
attackType: EntityAttackType.Melee,
|
|
386
|
+
maxRangeAttack: RangeTypes.High,
|
|
387
|
+
speed: MovementSpeed.Standard,
|
|
388
|
+
isBoss: false,
|
|
389
|
+
baseHealth: 30,
|
|
390
|
+
skills: {
|
|
391
|
+
level: 3,
|
|
392
|
+
strength: {
|
|
393
|
+
level: 3,
|
|
394
|
+
},
|
|
395
|
+
dexterity: {
|
|
396
|
+
level: 1,
|
|
397
|
+
},
|
|
398
|
+
resistance: {
|
|
399
|
+
level: 5,
|
|
400
|
+
},
|
|
401
|
+
},
|
|
402
|
+
loots: [
|
|
403
|
+
{
|
|
404
|
+
itemBlueprintKey: 'foods/red-meat.png',
|
|
405
|
+
chance: 30,
|
|
406
|
+
quantityRange: [1, 4],
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
itemBlueprintKey: 'crafting-resources/leather.png',
|
|
410
|
+
chance: 50,
|
|
411
|
+
quantityRange: [1, 3],
|
|
412
|
+
},
|
|
413
|
+
],
|
|
414
|
+
fleeOnLowHealth: false,
|
|
415
|
+
entityEffects: [],
|
|
416
|
+
areaSpells: []
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
id: '10',
|
|
420
|
+
name: 'Inferno Widow',
|
|
421
|
+
key: 'giant-spider/down/standing/0.png',
|
|
422
|
+
subType: NPCSubtype.Insect,
|
|
423
|
+
alignment: NPCAlignment.Hostile,
|
|
424
|
+
attackType: EntityAttackType.MeleeRanged,
|
|
425
|
+
speed: MovementSpeed.Standard,
|
|
426
|
+
maxRangeAttack: RangeTypes.High,
|
|
427
|
+
baseHealth: 60000,
|
|
428
|
+
isBoss: true,
|
|
429
|
+
skills: {
|
|
430
|
+
level: 298,
|
|
431
|
+
strength: {
|
|
432
|
+
level: 298,
|
|
433
|
+
},
|
|
434
|
+
dexterity: {
|
|
435
|
+
level: 298,
|
|
436
|
+
},
|
|
437
|
+
resistance: {
|
|
438
|
+
level: 298,
|
|
439
|
+
}
|
|
440
|
+
},
|
|
441
|
+
fleeOnLowHealth: true,
|
|
442
|
+
loots: [
|
|
443
|
+
{
|
|
444
|
+
itemBlueprintKey: 'accessories/gilded-necklace.png',
|
|
445
|
+
chance: LootProbability.Rare,
|
|
446
|
+
},
|
|
447
|
+
|
|
448
|
+
{
|
|
449
|
+
itemBlueprintKey: 'armors/golden-armor.png',
|
|
450
|
+
chance: LootProbability.SemiCommon,
|
|
451
|
+
}
|
|
452
|
+
],
|
|
453
|
+
entityEffects: [EntityEffectBlueprint.Poison],
|
|
454
|
+
areaSpells: [
|
|
455
|
+
{
|
|
456
|
+
spellKey: SpellsBlueprint.NaturesRevenge,
|
|
457
|
+
texturePath: 'spell-icons/natures-revenge.png',
|
|
458
|
+
probability: 10,
|
|
459
|
+
power: 'High',
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
spellKey: SpellsBlueprint.VampiricStorm,
|
|
463
|
+
texturePath: 'spell-icons/vampiric-storm.png',
|
|
464
|
+
probability: 50,
|
|
465
|
+
power: 'High',
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
spellKey: SpellsBlueprint.FireStorm,
|
|
469
|
+
texturePath: 'spell-icons/fire-storm.png',
|
|
470
|
+
probability: 90,
|
|
471
|
+
power: 'Medium',
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
spellKey: SpellsBlueprint.SelfHealingSpell,
|
|
475
|
+
texturePath: 'spell-icons/self-healing-spell.png',
|
|
476
|
+
probability: 90,
|
|
477
|
+
power: "Hidh",
|
|
478
|
+
},
|
|
479
|
+
],
|
|
480
|
+
}
|
|
371
481
|
];
|
|
372
482
|
|
|
373
483
|
export const mockItems: IInformationCenterItem[] = [
|
|
@@ -484,88 +594,89 @@ export const mockTutorials: IVideoGuide[] = [
|
|
|
484
594
|
{
|
|
485
595
|
id: '1',
|
|
486
596
|
title: 'Getting Started Guide',
|
|
487
|
-
description:
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
category: 'General',
|
|
597
|
+
description: 'Learn the basics of character creation, movement, and basic combat.',
|
|
598
|
+
videoUrl: 'https://youtu.be/_8d7e-otQoo',
|
|
599
|
+
category: VideoGuideCategory.General,
|
|
600
|
+
language: VideoGuideLanguage.English,
|
|
492
601
|
},
|
|
493
602
|
{
|
|
494
603
|
id: '2',
|
|
495
604
|
title: 'Advanced Combat Techniques',
|
|
496
|
-
description:
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
category: 'Combat',
|
|
605
|
+
description: 'Master the art of combat with advanced combos and spell casting.',
|
|
606
|
+
videoUrl: 'https://youtu.be/7LQlyy0Y720?si=wZ79VC4sCsI781Mn',
|
|
607
|
+
category: VideoGuideCategory.Combat,
|
|
608
|
+
language: VideoGuideLanguage.English,
|
|
501
609
|
},
|
|
502
610
|
{
|
|
503
611
|
id: '3',
|
|
504
612
|
title: 'Crafting System Tutorial',
|
|
505
|
-
description:
|
|
506
|
-
|
|
507
|
-
thumbnailUrl: '/tutorials/crafting.jpg',
|
|
613
|
+
description: 'Everything you need to know about crafting weapons and items.',
|
|
614
|
+
localImage: 'https://youtube.com/watch?v=crafting',
|
|
508
615
|
videoUrl: 'https://youtube.com/watch?v=crafting',
|
|
509
|
-
category:
|
|
616
|
+
category: VideoGuideCategory.Crafting,
|
|
617
|
+
language: VideoGuideLanguage.English,
|
|
510
618
|
},
|
|
511
619
|
{
|
|
512
620
|
id: '4',
|
|
513
621
|
title: 'Secret Areas Guide',
|
|
514
622
|
description: 'Discover hidden locations and treasures across the world.',
|
|
515
|
-
|
|
623
|
+
localImage: 'https://youtube.com/watch?v=exploration',
|
|
516
624
|
videoUrl: 'https://youtube.com/watch?v=exploration',
|
|
517
|
-
category:
|
|
625
|
+
category: VideoGuideCategory.Exploration,
|
|
626
|
+
language: VideoGuideLanguage.English,
|
|
518
627
|
},
|
|
519
628
|
{
|
|
520
629
|
id: '5',
|
|
521
630
|
title: 'Boss Battle Strategies',
|
|
522
|
-
description:
|
|
523
|
-
|
|
524
|
-
thumbnailUrl: '/tutorials/boss-battles.jpg',
|
|
631
|
+
description: 'Learn effective strategies to defeat challenging boss encounters.',
|
|
632
|
+
localImage: 'https://youtube.com/watch?v=boss-battles',
|
|
525
633
|
videoUrl: 'https://youtube.com/watch?v=boss-battles',
|
|
526
|
-
category:
|
|
634
|
+
category: VideoGuideCategory.Combat,
|
|
635
|
+
language: VideoGuideLanguage.English,
|
|
527
636
|
},
|
|
528
637
|
{
|
|
529
638
|
id: '6',
|
|
530
639
|
title: 'Resource Gathering Guide',
|
|
531
|
-
description:
|
|
532
|
-
|
|
533
|
-
thumbnailUrl: '/tutorials/resource-gathering.jpg',
|
|
640
|
+
description: 'Efficient methods for gathering crafting materials and resources.',
|
|
641
|
+
localImage: 'https://youtube.com/watch?v=resource-gathering',
|
|
534
642
|
videoUrl: 'https://youtube.com/watch?v=resource-gathering',
|
|
535
|
-
category:
|
|
643
|
+
category: VideoGuideCategory.Crafting,
|
|
644
|
+
language: VideoGuideLanguage.English,
|
|
536
645
|
},
|
|
537
646
|
{
|
|
538
647
|
id: '7',
|
|
539
648
|
title: 'Dungeon Exploration Tips',
|
|
540
|
-
description:
|
|
541
|
-
|
|
542
|
-
thumbnailUrl: '/tutorials/dungeon-tips.jpg',
|
|
649
|
+
description: 'Essential tips for surviving and navigating dangerous dungeons.',
|
|
650
|
+
localImage: 'https://youtube.com/watch?v=dungeon-tips',
|
|
543
651
|
videoUrl: 'https://youtube.com/watch?v=dungeon-tips',
|
|
544
|
-
category:
|
|
652
|
+
category: VideoGuideCategory.Exploration,
|
|
653
|
+
language: VideoGuideLanguage.English,
|
|
545
654
|
},
|
|
546
655
|
{
|
|
547
656
|
id: '8',
|
|
548
657
|
title: 'Character Build Guide',
|
|
549
658
|
description: 'Optimize your character builds for different playstyles.',
|
|
550
|
-
|
|
659
|
+
localImage: 'https://youtube.com/watch?v=character-builds',
|
|
551
660
|
videoUrl: 'https://youtube.com/watch?v=character-builds',
|
|
552
|
-
category:
|
|
661
|
+
category: VideoGuideCategory.General,
|
|
662
|
+
language: VideoGuideLanguage.Portuguese,
|
|
553
663
|
},
|
|
554
664
|
{
|
|
555
665
|
id: '9',
|
|
556
666
|
title: 'PvP Combat Guide',
|
|
557
667
|
description: 'Advanced tactics for player versus player combat scenarios.',
|
|
558
|
-
|
|
668
|
+
localImage: 'https://youtube.com/watch?v=pvp-combat',
|
|
559
669
|
videoUrl: 'https://youtube.com/watch?v=pvp-combat',
|
|
560
|
-
category:
|
|
670
|
+
category: VideoGuideCategory.Combat,
|
|
671
|
+
language: VideoGuideLanguage.Portuguese,
|
|
561
672
|
},
|
|
562
673
|
{
|
|
563
674
|
id: '10',
|
|
564
675
|
title: 'Rare Item Crafting',
|
|
565
|
-
description:
|
|
566
|
-
|
|
567
|
-
thumbnailUrl: '/tutorials/rare-crafting.jpg',
|
|
676
|
+
description: 'Special recipes and techniques for crafting rare and legendary items.',
|
|
677
|
+
localImage: 'https://youtube.com/watch?v=rare-crafting',
|
|
568
678
|
videoUrl: 'https://youtube.com/watch?v=rare-crafting',
|
|
569
|
-
category:
|
|
679
|
+
category: VideoGuideCategory.Crafting,
|
|
680
|
+
language: VideoGuideLanguage.Portuguese,
|
|
570
681
|
},
|
|
571
682
|
];
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Meta, Story } from '@storybook/react';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { InformationCenter } from '../../../components/InformationCenter/InformationCenter';
|
|
4
|
-
import { IInformationCenterItem } from '../../../components/InformationCenter/InformationCenterTypes';
|
|
5
4
|
import { RPGUIRoot } from '../../../components/RPGUI/RPGUIRoot';
|
|
6
5
|
import entitiesAtlasJSON from '../../../mocks/atlas/entities/entities.json';
|
|
7
6
|
import entitiesAtlasIMG from '../../../mocks/atlas/entities/entities.png';
|
|
@@ -10,6 +9,7 @@ import iconsAtlasIMG from '../../../mocks/atlas/icons/icons.png';
|
|
|
10
9
|
import itemsAtlasJSON from '../../../mocks/atlas/items/items.json';
|
|
11
10
|
import itemsAtlasIMG from '../../../mocks/atlas/items/items.png';
|
|
12
11
|
|
|
12
|
+
import { IInformationCenterItem } from '@rpg-engine/shared';
|
|
13
13
|
import { mockBestiaryItems, mockFaqItems, mockItems, mockTutorials } from '../../../mocks/informationCenter.mocks';
|
|
14
14
|
|
|
15
15
|
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { EntityAttackType, ICharacterPermanentBuff, IEquippableItemBlueprint, INPCLoot, ItemRarities, NPCAlignment, NPCSubtype, RangeTypes } from '@rpg-engine/shared';
|
|
2
|
-
import { IFaqItem, IVideoGuide } from './InformationCenter';
|
|
3
|
-
export declare enum MovementSpeed {
|
|
4
|
-
ExtraSlow = 1.5,
|
|
5
|
-
Slow = 2.25,
|
|
6
|
-
Standard = 2.6,
|
|
7
|
-
Fast = 3,
|
|
8
|
-
ExtraFast = 3.5
|
|
9
|
-
}
|
|
10
|
-
export declare enum EntityEffectBlueprint {
|
|
11
|
-
Poison = "poison",
|
|
12
|
-
Bleeding = "bleeding",
|
|
13
|
-
Freezing = "freezing",
|
|
14
|
-
Burning = "burning",
|
|
15
|
-
Corruption = "corruption",
|
|
16
|
-
VineGrasp = "vine-grasp",
|
|
17
|
-
Curse = "curse",
|
|
18
|
-
Drain = "drain",
|
|
19
|
-
Shadow = "shadow",
|
|
20
|
-
Stun = "stun",
|
|
21
|
-
Knockback = "knockback",
|
|
22
|
-
Rage = "rage",
|
|
23
|
-
Weakness = "weakness",
|
|
24
|
-
Cripple = "cripple",
|
|
25
|
-
Regeneration = "regeneration"
|
|
26
|
-
}
|
|
27
|
-
export declare enum LootProbability {
|
|
28
|
-
VeryRare = 0.5,
|
|
29
|
-
Rare = 1,
|
|
30
|
-
Uncommon = 10,
|
|
31
|
-
SemiCommon = 15,
|
|
32
|
-
Common = 20,
|
|
33
|
-
VeryCommon = 35
|
|
34
|
-
}
|
|
35
|
-
interface INPCBlueprintSpellArea {
|
|
36
|
-
spellKey: string;
|
|
37
|
-
probability: number;
|
|
38
|
-
power: string;
|
|
39
|
-
texturePath: string;
|
|
40
|
-
}
|
|
41
|
-
export interface IInformationCenterNPC {
|
|
42
|
-
id: string;
|
|
43
|
-
name: string;
|
|
44
|
-
key: string;
|
|
45
|
-
subType: NPCSubtype;
|
|
46
|
-
alignment: NPCAlignment;
|
|
47
|
-
attackType: EntityAttackType;
|
|
48
|
-
maxRangeAttack: RangeTypes;
|
|
49
|
-
speed: MovementSpeed;
|
|
50
|
-
baseHealth: number;
|
|
51
|
-
skills: {
|
|
52
|
-
level: number;
|
|
53
|
-
strength?: {
|
|
54
|
-
level: number;
|
|
55
|
-
};
|
|
56
|
-
dexterity?: {
|
|
57
|
-
level: number;
|
|
58
|
-
};
|
|
59
|
-
resistance?: {
|
|
60
|
-
level: number;
|
|
61
|
-
};
|
|
62
|
-
};
|
|
63
|
-
fleeOnLowHealth: boolean;
|
|
64
|
-
entityEffects: EntityEffectBlueprint[];
|
|
65
|
-
areaSpells: INPCBlueprintSpellArea[];
|
|
66
|
-
loots: INPCLoot[];
|
|
67
|
-
}
|
|
68
|
-
export interface IInformationCenterItem extends IEquippableItemBlueprint {
|
|
69
|
-
tier: number;
|
|
70
|
-
rarity: ItemRarities;
|
|
71
|
-
rangeType?: EntityAttackType;
|
|
72
|
-
basePrice: number;
|
|
73
|
-
canSell: boolean;
|
|
74
|
-
maxStackSize: number;
|
|
75
|
-
usableEffectDescription?: string;
|
|
76
|
-
entityEffects?: [EntityEffectBlueprint];
|
|
77
|
-
entityEffectChance?: number;
|
|
78
|
-
equippedBuff?: ICharacterPermanentBuff[];
|
|
79
|
-
equippedBuffDescription?: string;
|
|
80
|
-
}
|
|
81
|
-
export interface IInformationCenterProps {
|
|
82
|
-
itemsAtlasJSON: Record<string, any>;
|
|
83
|
-
itemsAtlasIMG: string;
|
|
84
|
-
entitiesAtlasJSON: Record<string, any>;
|
|
85
|
-
entitiesAtlasIMG: string;
|
|
86
|
-
iconsAtlasJSON: any;
|
|
87
|
-
iconsAtlasIMG: any;
|
|
88
|
-
faqItems?: IFaqItem[];
|
|
89
|
-
bestiaryItems?: IInformationCenterNPC[];
|
|
90
|
-
videoGuides?: IVideoGuide[];
|
|
91
|
-
items?: IInformationCenterItem[];
|
|
92
|
-
loading?: boolean;
|
|
93
|
-
error?: string;
|
|
94
|
-
initialSearchQuery?: string;
|
|
95
|
-
}
|
|
96
|
-
export {};
|