@rpg-engine/long-bow 0.8.29 → 0.8.30

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.8.29",
3
+ "version": "0.8.30",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -84,7 +84,7 @@
84
84
  "dependencies": {
85
85
  "@capacitor/core": "^6.1.0",
86
86
  "@rollup/plugin-image": "^2.1.1",
87
- "@rpg-engine/shared": "^0.10.0",
87
+ "@rpg-engine/shared": "^0.9.104",
88
88
  "dayjs": "^1.11.2",
89
89
  "font-awesome": "^4.7.0",
90
90
  "fs-extra": "^10.1.0",
@@ -9,9 +9,9 @@ import {
9
9
  } from '@rpg-engine/shared';
10
10
  import { DraggableContainer } from '../DraggableContainer';
11
11
  import { InternalTabs } from '../InternalTabs/InternalTabs';
12
- import { RPGUIContainerTypes } from '../RPGUI/RPGUIContainer';
13
12
  import { InformationCenterBestiarySection } from './sections/bestiary/InformationCenterBestiarySection';
14
13
  import { InformationCenterFAQSection } from './sections/faq/InformationCenterFaqSection';
14
+ import { InformationCenterItemDetails } from './sections/items/InformationCenterItemDetails';
15
15
  import { InformationCenterItemsSection } from './sections/items/InformationCenterItemsSection';
16
16
  import { InformationCenterTutorialsSection } from './sections/tutorials/InformationCenterTutorialsSection';
17
17
 
@@ -47,6 +47,10 @@ export const InformationCenter: React.FC<IInformationCenterProps> = ({
47
47
  initialSearchQuery = '',
48
48
  }) => {
49
49
  const [activeTab, setActiveTab] = useState('bestiary');
50
+ const [
51
+ selectedItem,
52
+ setSelectedItem,
53
+ ] = useState<IInformationCenterItem | null>(null);
50
54
 
51
55
  if (loading) {
52
56
  return <LoadingMessage>Loading...</LoadingMessage>;
@@ -113,10 +117,7 @@ export const InformationCenter: React.FC<IInformationCenterProps> = ({
113
117
  ];
114
118
 
115
119
  return (
116
- <DraggableContainer
117
- title="Information Center"
118
- type={RPGUIContainerTypes.Framed}
119
- >
120
+ <DraggableContainer title="Information Center">
120
121
  <Container>
121
122
  <InternalTabs
122
123
  tabs={tabs}
@@ -128,6 +129,19 @@ export const InformationCenter: React.FC<IInformationCenterProps> = ({
128
129
  borderColor="#f59e0b"
129
130
  hoverColor="#fef3c7"
130
131
  />
132
+ {selectedItem && (
133
+ <InformationCenterItemDetails
134
+ item={selectedItem}
135
+ itemsAtlasJSON={itemsAtlasJSON}
136
+ itemsAtlasIMG={itemsAtlasIMG}
137
+ droppedBy={bestiaryItems.filter(npc =>
138
+ npc.loots?.some(
139
+ loot => loot.itemBlueprintKey === selectedItem.key
140
+ )
141
+ )}
142
+ onBack={() => setSelectedItem(null)}
143
+ />
144
+ )}
131
145
  </Container>
132
146
  </DraggableContainer>
133
147
  );
@@ -1,8 +1,4 @@
1
- import {
2
- IInformationCenterNPC,
3
- NPCAlignment,
4
- isMobileOrTablet,
5
- } from '@rpg-engine/shared';
1
+ import { IInformationCenterNPC, NPCAlignment } from '@rpg-engine/shared';
6
2
  import React, { useMemo, useState } from 'react';
7
3
  import styled from 'styled-components';
8
4
  import { IOptionsProps } from '../../../Dropdown';
@@ -12,7 +8,6 @@ import { InformationCenterCell } from '../../InformationCenterCell';
12
8
  import { formatItemType } from '../items/InformationCenterItemsSection';
13
9
  import { InformationCenterNPCDetails } from './InformationCenterNPCDetails';
14
10
  import { InformationCenterNPCTooltip } from './InformationCenterNPCTooltip';
15
-
16
11
  interface IBestiarySectionProps {
17
12
  bestiaryItems: IInformationCenterNPC[];
18
13
  itemsAtlasJSON: Record<string, any>;
@@ -36,7 +31,6 @@ export const InformationCenterBestiarySection: React.FC<IBestiarySectionProps> =
36
31
  initialSearchQuery,
37
32
  tabId,
38
33
  }) => {
39
- const isMobile = isMobileOrTablet();
40
34
  const [searchQuery, setSearchQuery] = useState(initialSearchQuery);
41
35
  const [tooltipData, setTooltipData] = useState<{
42
36
  npc: IInformationCenterNPC;
@@ -46,12 +40,13 @@ export const InformationCenterBestiarySection: React.FC<IBestiarySectionProps> =
46
40
  selectedMonster,
47
41
  setSelectedMonster,
48
42
  ] = useState<IInformationCenterNPC | null>(null);
43
+ const [isTouchDevice] = useState('ontouchstart' in window);
49
44
 
50
45
  const handleMouseEnter = (
51
46
  monster: IInformationCenterNPC,
52
47
  event: React.MouseEvent
53
48
  ) => {
54
- if (!isMobile && !selectedMonster) {
49
+ if (!isTouchDevice && !selectedMonster) {
55
50
  setTooltipData({
56
51
  npc: monster,
57
52
  position: { x: event.clientX, y: event.clientY },
@@ -60,13 +55,13 @@ export const InformationCenterBestiarySection: React.FC<IBestiarySectionProps> =
60
55
  };
61
56
 
62
57
  const handleMouseLeave = () => {
63
- if (!isMobile) {
58
+ if (!isTouchDevice) {
64
59
  setTooltipData(null);
65
60
  }
66
61
  };
67
62
 
68
63
  const handleMouseMove = (event: React.MouseEvent) => {
69
- if (!isMobile && tooltipData) {
64
+ if (!isTouchDevice && tooltipData) {
70
65
  setTooltipData({
71
66
  ...tooltipData,
72
67
  position: { x: event.clientX, y: event.clientY },
@@ -78,9 +73,18 @@ export const InformationCenterBestiarySection: React.FC<IBestiarySectionProps> =
78
73
  monster: IInformationCenterNPC,
79
74
  event: React.TouchEvent
80
75
  ) => {
81
- event.preventDefault();
82
- setSelectedMonster(monster);
83
- setTooltipData(null);
76
+ if (isTouchDevice) {
77
+ event.preventDefault();
78
+ const touch = event.touches[0];
79
+ if (tooltipData?.npc.id === monster.id) {
80
+ setTooltipData(null);
81
+ } else {
82
+ setTooltipData({
83
+ npc: monster,
84
+ position: { x: touch.clientX, y: touch.clientY },
85
+ });
86
+ }
87
+ }
84
88
  };
85
89
 
86
90
  const handleMonsterClick = (monster: IInformationCenterNPC) => {
@@ -166,7 +170,7 @@ export const InformationCenterBestiarySection: React.FC<IBestiarySectionProps> =
166
170
  dependencies={[selectedBestiaryCategory]}
167
171
  itemHeight="180px"
168
172
  />
169
- {!isMobile && tooltipData && (
173
+ {tooltipData && (
170
174
  <Portal>
171
175
  <TooltipWrapper
172
176
  style={{
@@ -184,18 +188,16 @@ export const InformationCenterBestiarySection: React.FC<IBestiarySectionProps> =
184
188
  </Portal>
185
189
  )}
186
190
  {selectedMonster && (
187
- <Portal>
188
- <InformationCenterNPCDetails
189
- npc={selectedMonster}
190
- itemsAtlasJSON={itemsAtlasJSON}
191
- itemsAtlasIMG={itemsAtlasIMG}
192
- iconAtlasIMG={iconsAtlasIMG}
193
- iconAtlasJSON={iconsAtlasJSON}
194
- entitiesAtlasJSON={entitiesAtlasJSON}
195
- entitiesAtlasIMG={entitiesAtlasIMG}
196
- onBack={() => setSelectedMonster(null)}
197
- />
198
- </Portal>
191
+ <InformationCenterNPCDetails
192
+ npc={selectedMonster}
193
+ itemsAtlasJSON={itemsAtlasJSON}
194
+ itemsAtlasIMG={itemsAtlasIMG}
195
+ iconAtlasIMG={iconsAtlasIMG}
196
+ iconAtlasJSON={iconsAtlasJSON}
197
+ entitiesAtlasJSON={entitiesAtlasJSON}
198
+ entitiesAtlasIMG={entitiesAtlasIMG}
199
+ onBack={() => setSelectedMonster(null)}
200
+ />
199
201
  )}
200
202
  </>
201
203
  );
@@ -265,11 +265,9 @@ const Value = styled.span`
265
265
  const StyledCollapsible = styled(Collapsible)`
266
266
  background: rgba(255, 255, 255, 0.05);
267
267
  border-radius: 4px;
268
- overflow: visible;
268
+ overflow: auto;
269
269
  scrollbar-width: thin;
270
270
  scrollbar-color: ${uiColors.darkGray} transparent;
271
- width: 100%;
272
- box-sizing: border-box;
273
271
  `;
274
272
 
275
273
  const StatGrid = styled.div`
@@ -356,49 +354,27 @@ const Separator = styled.span`
356
354
  `;
357
355
 
358
356
  const LootSearchContainer = styled.div`
359
- padding: 8px;
360
- background: rgba(0, 0, 0, 0.2);
361
- border-radius: 4px;
362
- margin: 8px 8px 4px;
363
- box-sizing: border-box;
357
+ padding: 12px 12px 0;
364
358
  `;
365
359
 
366
360
  const StyledSearchBar = styled(SearchBar)`
367
361
  width: 100%;
368
- box-sizing: border-box;
369
- input {
370
- background: rgba(0, 0, 0, 0.2) !important;
371
- border: 1px solid rgba(255, 255, 255, 0.1) !important;
372
- box-sizing: border-box;
373
- &:focus {
374
- border-color: ${uiColors.yellow} !important;
375
- }
376
- }
377
362
  `;
378
363
 
379
364
  const LootGrid = styled.div`
380
365
  display: grid;
381
- grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
382
- gap: 4px;
383
- padding: 4px 8px;
384
- width: 100%;
385
- max-width: 100%;
386
- box-sizing: border-box;
387
-
388
- @media (max-width: 768px) {
389
- grid-template-columns: 1fr;
390
- padding: 4px;
391
- }
366
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
367
+ gap: 8px;
368
+ padding: 12px;
392
369
  `;
393
370
 
394
371
  const LootItem = styled.div`
395
372
  display: flex;
396
373
  align-items: center;
397
- gap: 4px;
374
+ gap: 8px;
398
375
  background: rgba(255, 255, 255, 0.05);
399
- padding: 4px;
376
+ padding: 8px;
400
377
  border-radius: 4px;
401
- min-width: 0;
402
378
  `;
403
379
 
404
380
  const LootDetails = styled.div`
@@ -2,13 +2,11 @@ import {
2
2
  IInformationCenterItem,
3
3
  IInformationCenterNPC,
4
4
  ItemType,
5
- isMobileOrTablet,
6
5
  } from '@rpg-engine/shared';
7
6
  import React, { useState } from 'react';
8
7
  import styled from 'styled-components';
9
8
  import { IOptionsProps } from '../../../Dropdown';
10
9
  import { PaginatedContent } from '../../../shared/PaginatedContent/PaginatedContent';
11
- import { Portal } from '../../../shared/Portal/Portal';
12
10
  import { InformationCenterCell } from '../../InformationCenterCell';
13
11
  import { InformationCenterItemDetails } from './InformationCenterItemDetails';
14
12
  import { InformationCenterItemTooltip } from './InformationCenterItemTooltip';
@@ -49,7 +47,6 @@ export const InformationCenterItemsSection: React.FC<IItemsSectionProps> = ({
49
47
  initialSearchQuery,
50
48
  tabId,
51
49
  }) => {
52
- const isMobile = isMobileOrTablet();
53
50
  const [searchQuery, setSearchQuery] = useState(initialSearchQuery);
54
51
  const [selectedItemCategory, setSelectedItemCategory] = useState<string>(
55
52
  'all'
@@ -93,17 +90,15 @@ export const InformationCenterItemsSection: React.FC<IItemsSectionProps> = ({
93
90
  e: React.MouseEvent,
94
91
  item: IInformationCenterItem
95
92
  ) => {
96
- if (!isMobile) {
97
- setTooltipPosition({
98
- x: e.clientX + TOOLTIP_OFFSET,
99
- y: e.clientY,
100
- });
101
- setHoveredItem(item);
102
- }
93
+ setTooltipPosition({
94
+ x: e.clientX + TOOLTIP_OFFSET,
95
+ y: e.clientY,
96
+ });
97
+ setHoveredItem(item);
103
98
  };
104
99
 
105
100
  const handleMouseMove = (e: React.MouseEvent) => {
106
- if (!isMobile && hoveredItem) {
101
+ if (hoveredItem) {
107
102
  setTooltipPosition({
108
103
  x: e.clientX + TOOLTIP_OFFSET,
109
104
  y: e.clientY,
@@ -112,17 +107,19 @@ export const InformationCenterItemsSection: React.FC<IItemsSectionProps> = ({
112
107
  };
113
108
 
114
109
  const handleMouseLeave = () => {
115
- if (!isMobile) {
116
- setHoveredItem(null);
117
- }
110
+ setHoveredItem(null);
118
111
  };
119
112
 
120
113
  const handleTouchStart = (
121
114
  e: React.TouchEvent,
122
115
  item: IInformationCenterItem
123
116
  ) => {
124
- e.preventDefault();
125
- setSelectedItem(item);
117
+ const touch = e.touches[0];
118
+ setTooltipPosition({
119
+ x: touch.clientX + TOOLTIP_OFFSET,
120
+ y: touch.clientY,
121
+ });
122
+ setHoveredItem(item);
126
123
  };
127
124
 
128
125
  const handleItemClick = (item: IInformationCenterItem) => {
@@ -173,7 +170,7 @@ export const InformationCenterItemsSection: React.FC<IItemsSectionProps> = ({
173
170
  layout="grid"
174
171
  itemHeight="180px"
175
172
  />
176
- {!isMobile && hoveredItem && (
173
+ {hoveredItem && (
177
174
  <TooltipWrapper
178
175
  style={{ top: tooltipPosition.y, left: tooltipPosition.x }}
179
176
  >
@@ -181,15 +178,13 @@ export const InformationCenterItemsSection: React.FC<IItemsSectionProps> = ({
181
178
  </TooltipWrapper>
182
179
  )}
183
180
  {selectedItem && (
184
- <Portal>
185
- <InformationCenterItemDetails
186
- item={selectedItem}
187
- itemsAtlasJSON={itemsAtlasJSON}
188
- itemsAtlasIMG={itemsAtlasIMG}
189
- droppedBy={getDroppedByNPCs(selectedItem.key, bestiaryItems)}
190
- onBack={() => setSelectedItem(null)}
191
- />
192
- </Portal>
181
+ <InformationCenterItemDetails
182
+ item={selectedItem}
183
+ itemsAtlasJSON={itemsAtlasJSON}
184
+ itemsAtlasIMG={itemsAtlasIMG}
185
+ droppedBy={getDroppedByNPCs(selectedItem.key, bestiaryItems)}
186
+ onBack={() => setSelectedItem(null)}
187
+ />
193
188
  )}
194
189
  </>
195
190
  );
@@ -49,45 +49,32 @@ export const BaseInformationDetails: React.FC<IBaseInformationDetailsProps> = ({
49
49
  };
50
50
 
51
51
  const Container = styled.div`
52
- position: fixed;
52
+ position: absolute;
53
53
  inset: 0;
54
54
  display: flex;
55
55
  justify-content: center;
56
56
  align-items: center;
57
- z-index: 9999;
57
+ z-index: 1000;
58
58
  `;
59
59
 
60
60
  const Overlay = styled.div`
61
- position: fixed;
61
+ position: absolute;
62
62
  inset: 0;
63
63
  background-color: rgba(0, 0, 0, 0.8);
64
64
  `;
65
65
 
66
66
  const Modal = styled.div`
67
- position: fixed;
67
+ position: relative;
68
+ width: 90%;
69
+ height: 90%;
68
70
  background-color: rgba(0, 0, 0, 0.95);
69
71
  border-radius: 4px;
70
- padding: 12px;
71
- overflow: hidden;
72
+ padding: 16px;
73
+ overflow-y: auto;
72
74
  z-index: 1;
73
75
  font-family: 'Press Start 2P', cursive;
74
76
  border: 1px solid ${uiColors.darkGray};
75
77
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
76
- width: 90%;
77
- height: 90%;
78
- top: 5%;
79
- left: 5%;
80
- max-width: 800px;
81
- margin: 0 auto;
82
-
83
- @media (max-width: 768px) {
84
- width: 100%;
85
- height: 100%;
86
- top: 0;
87
- left: 0;
88
- border-radius: 0;
89
- padding: 8px;
90
- }
91
78
 
92
79
  &::-webkit-scrollbar {
93
80
  width: 2px;
@@ -139,19 +126,9 @@ const Header = styled.div`
139
126
  const Content = styled.div`
140
127
  display: flex;
141
128
  flex-direction: column;
142
- gap: 12px;
143
- height: calc(100% - 80px);
144
- overflow-y: auto;
145
- overflow-x: hidden;
146
- padding-right: 6px;
147
- margin-right: -6px;
148
-
149
- @media (max-width: 768px) {
150
- height: calc(100% - 64px);
151
- gap: 8px;
152
- padding-right: 4px;
153
- margin-right: -4px;
154
- }
129
+ gap: 16px;
130
+ height: 100%;
131
+ overflow: auto;
155
132
  `;
156
133
 
157
134
  const Title = styled.h2`
@@ -1,4 +1,4 @@
1
- import { IItem } from '@rpg-engine/shared';
1
+ import { IItem, ItemQualityLevel } from '@rpg-engine/shared';
2
2
  import React from 'react';
3
3
  import styled from 'styled-components';
4
4
  import { uiColors } from '../../../constants/uiColors';
@@ -6,6 +6,7 @@ import { uiFonts } from '../../../constants/uiFonts';
6
6
  import { SpriteFromAtlas } from '../../shared/SpriteFromAtlas';
7
7
  import { ErrorBoundary } from '../Inventory/ErrorBoundary';
8
8
  import { EquipmentSlotSpriteByType } from '../Inventory/ItemSlot';
9
+ import { qualityColorHex } from '../Inventory/ItemSlotQuality';
9
10
  import { rarityColor } from '../Inventory/ItemSlotRarity';
10
11
 
11
12
  interface IItemInfoProps {
@@ -191,8 +192,24 @@ const Container = styled.div<{ item: IItem }>`
191
192
  padding: 0.5rem;
192
193
  font-size: ${uiFonts.size.small};
193
194
  border: 3px solid ${({ item }) => rarityColor(item) ?? uiColors.lightGray};
195
+ box-shadow: ${({ item }) => `0 0 5px 2px ${rarityColor(item)}`};
194
196
  height: max-content;
195
197
  width: 18rem;
198
+ position: relative;
199
+
200
+ ${({ item }) =>
201
+ item?.quality && item.quality !== ItemQualityLevel.Normal &&
202
+ `
203
+ &::before {
204
+ content: '★';
205
+ position: absolute;
206
+ top: 0.2rem;
207
+ left: 0.5rem;
208
+ font-size: 1.2rem;
209
+ color: ${qualityColorHex(item)};
210
+ text-shadow: 0 0 3px black;
211
+ }
212
+ `}
196
213
 
197
214
  @media (max-width: 640px) {
198
215
  width: 80vw;
@@ -6,7 +6,7 @@ import {
6
6
  ItemContainerType,
7
7
  ItemSlotType,
8
8
  ItemSubType,
9
- ItemType,
9
+ ItemType
10
10
  } from '@rpg-engine/shared';
11
11
 
12
12
  import { observer } from 'mobx-react-lite';
@@ -15,10 +15,11 @@ import Draggable, { DraggableEventHandler } from 'react-draggable';
15
15
  import styled from 'styled-components';
16
16
  import useTouchTarget from '../../../hooks/useTouchTarget';
17
17
  import { IPosition } from '../../../types/eventTypes';
18
- import { rarityColor } from './ItemSlotRarity';
19
- import { ItemSlotRenderer } from './ItemSlotRenderer';
20
18
  import { useItemSlotDetails } from './context/ItemSlotDetailsContext';
21
19
  import { useItemSlotDragging } from './context/ItemSlotDraggingContext';
20
+ import { qualityColorHex } from './ItemSlotQuality';
21
+ import { rarityColor } from './ItemSlotRarity';
22
+ import { ItemSlotRenderer } from './ItemSlotRenderer';
22
23
 
23
24
  export const EquipmentSlotSpriteByType: any = {
24
25
  Neck: 'accessories/corruption-necklace.png',
@@ -539,6 +540,17 @@ const Container = styled.div<ContainerTypes>`
539
540
  ${({ item }) => `0 0 4px 3px ${rarityColor(item)}`};
540
541
  }
541
542
 
543
+ .quality-star {
544
+ position: absolute;
545
+ top: 0.5rem;
546
+ left: 0.5rem;
547
+ font-size: 1.2rem;
548
+ z-index: 2;
549
+ text-shadow: 0 0 3px black;
550
+ pointer-events: none;
551
+ color: ${({ item }) => qualityColorHex(item)};
552
+ }
553
+
542
554
  &::before {
543
555
  content: '';
544
556
  position: absolute;
@@ -0,0 +1,18 @@
1
+ import { IItem, ItemQualityLevel } from '@rpg-engine/shared';
2
+
3
+ export const qualityColorHex = (item: IItem | null) => {
4
+ switch (item?.quality) {
5
+ case ItemQualityLevel.HighQuality:
6
+ return '#00bfff';
7
+ case ItemQualityLevel.Exceptional:
8
+ return '#ff8c00';
9
+ case ItemQualityLevel.Mastercrafted:
10
+ return '#ff00ff';
11
+ case ItemQualityLevel.Ancient:
12
+ return '#ffd700';
13
+ case ItemQualityLevel.Mythic:
14
+ return '#ff0080';
15
+ default:
16
+ return 'transparent';
17
+ }
18
+ };
@@ -1,8 +1,9 @@
1
1
  import {
2
+ getItemTextureKeyPath,
2
3
  IItem,
3
4
  ItemContainerType,
5
+ ItemQualityLevel,
4
6
  ItemSlotType,
5
- getItemTextureKeyPath,
6
7
  } from '@rpg-engine/shared';
7
8
  import React from 'react';
8
9
  import { v4 as uuidv4 } from 'uuid';
@@ -46,6 +47,9 @@ export const ItemSlotRenderer: React.FC<IProps> = ({
46
47
 
47
48
  return (
48
49
  <ErrorBoundary key={item._id}>
50
+ {item.quality && item.quality !== ItemQualityLevel.Normal && (
51
+ <div className="quality-star">★</div>
52
+ )}
49
53
  <SpriteFromAtlas
50
54
  atlasIMG={atlasIMG}
51
55
  atlasJSON={atlasJSON}
@@ -101,5 +105,5 @@ export const ItemSlotRenderer: React.FC<IProps> = ({
101
105
  }
102
106
  };
103
107
 
104
- return <>{onRenderSlot(item)}</>;
108
+ return onRenderSlot(item);
105
109
  };
@@ -66,5 +66,5 @@ const Icon = styled.span`
66
66
  `;
67
67
 
68
68
  const Content = styled.div`
69
- padding: 6px;
69
+ padding: 12px;
70
70
  `;
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  IItem,
3
3
  IItemContainer,
4
+ ItemQualityLevel,
4
5
  ItemRarities,
5
6
  ItemSlotType,
6
7
  ItemSubType,
@@ -81,6 +82,7 @@ export const items: IItem[] = [
81
82
  createdAt: '2022-06-04T03:18:09.335Z',
82
83
  updatedAt: '2022-06-04T18:16:49.056Z',
83
84
  rarity: ItemRarities.Legendary,
85
+ quality: ItemQualityLevel.Mythic,
84
86
  canBePurchasedOnlyByPremiumPlans: [
85
87
  UserAccountTypes.PremiumGold,
86
88
  UserAccountTypes.PremiumUltimate,
@@ -167,6 +169,7 @@ export const items: IItem[] = [
167
169
  createdAt: '2022-06-04T03:18:09.335Z',
168
170
  updatedAt: '2022-06-04T18:16:49.056Z',
169
171
  rarity: ItemRarities.Epic,
172
+ quality: ItemQualityLevel.Normal,
170
173
  attachedGems: [
171
174
  {
172
175
  gemEntityEffectsAdd: ['poison'],
@@ -221,6 +224,7 @@ export const items: IItem[] = [
221
224
  createdAt: '2022-06-04T03:18:09.335Z',
222
225
  updatedAt: '2022-06-04T18:16:49.056Z',
223
226
  rarity: ItemRarities.Uncommon,
227
+ quality: ItemQualityLevel.HighQuality,
224
228
  },
225
229
  {
226
230
  _id: '629acek4j7c8e8002ff60034',
@@ -255,6 +259,7 @@ export const items: IItem[] = [
255
259
  createdAt: '2022-06-04T03:18:09.335Z',
256
260
  updatedAt: '2022-06-04T18:16:49.056Z',
257
261
  rarity: ItemRarities.Rare,
262
+ quality: ItemQualityLevel.Ancient,
258
263
  },
259
264
  {
260
265
  _id: '629acek4j7c8e8002fg60034',
@@ -289,6 +294,7 @@ export const items: IItem[] = [
289
294
  createdAt: '2022-06-04T03:18:09.335Z',
290
295
  updatedAt: '2022-06-04T18:16:49.056Z',
291
296
  rarity: ItemRarities.Common,
297
+ quality: ItemQualityLevel.Mastercrafted,
292
298
  },
293
299
  {
294
300
  _id: '392acek4j7c8e8002ff60403',
@@ -323,6 +329,7 @@ export const items: IItem[] = [
323
329
  createdAt: '2022-06-04T03:18:09.335Z',
324
330
  updatedAt: '2022-06-04T18:16:49.056Z',
325
331
  rarity: ItemRarities.Common,
332
+ quality: ItemQualityLevel.Exceptional,
326
333
  },
327
334
  createBagItem('392acek4j7c8e8002ff60404', '#FF0000'), // red
328
335
  createBagItem('392acek4j7c8e8002ff60405', '#0000FF'), // blue