@rpg-engine/long-bow 0.6.70 → 0.6.72
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/QuestList.d.ts +1 -3
- package/dist/components/shared/Ellipsis.d.ts +1 -1
- package/dist/components/shared/SimpleTooltip.d.ts +12 -0
- package/dist/long-bow.cjs.development.js +256 -80
- 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 +257 -81
- package/dist/long-bow.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/QuestList.tsx +143 -107
- package/src/components/Table/Table.tsx +5 -1
- package/src/components/shared/Ellipsis.tsx +2 -2
- package/src/components/shared/SimpleTooltip.tsx +198 -0
- package/src/stories/QuestList.stories.tsx +12 -42
package/package.json
CHANGED
|
@@ -1,135 +1,171 @@
|
|
|
1
|
-
import { IQuest } from '@rpg-engine/shared';
|
|
2
1
|
import React from 'react';
|
|
2
|
+
|
|
3
3
|
import styled from 'styled-components';
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
IQuest,
|
|
7
|
+
IQuestObjectiveInteraction,
|
|
8
|
+
IQuestObjectiveKill,
|
|
9
|
+
QuestStatus,
|
|
10
|
+
} from '@rpg-engine/shared';
|
|
11
|
+
import { uiColors } from '../constants/uiColors';
|
|
12
|
+
import { Table, TableCell, TableHeader, TableRow } from './Table/Table';
|
|
13
|
+
import { Ellipsis } from './shared/Ellipsis';
|
|
14
|
+
import { SimpleTooltip } from './shared/SimpleTooltip';
|
|
7
15
|
|
|
8
16
|
export interface IQuestListProps {
|
|
9
17
|
quests?: IQuest[];
|
|
10
|
-
onClose: () => void;
|
|
11
|
-
scale?: number;
|
|
12
18
|
}
|
|
13
19
|
|
|
14
|
-
export const QuestList: React.FC<IQuestListProps> = ({
|
|
15
|
-
quests,
|
|
16
|
-
onClose,
|
|
17
|
-
scale,
|
|
18
|
-
}) => {
|
|
20
|
+
export const QuestList: React.FC<IQuestListProps> = ({ quests }) => {
|
|
19
21
|
return (
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
<
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
22
|
+
<QuestListContainer>
|
|
23
|
+
{quests && quests.length > 0 ? (
|
|
24
|
+
<>
|
|
25
|
+
<Table>
|
|
26
|
+
<thead>
|
|
27
|
+
<TableRow>
|
|
28
|
+
<TableHeader>Status</TableHeader>
|
|
29
|
+
<TableHeader>Title</TableHeader>
|
|
30
|
+
<TableHeader>Description</TableHeader>
|
|
31
|
+
<TableHeader>Objectives</TableHeader>
|
|
32
|
+
<TableHeader>Rewards</TableHeader>
|
|
33
|
+
</TableRow>
|
|
34
|
+
</thead>
|
|
35
|
+
<tbody>
|
|
36
|
+
{quests.map((quest, i) => (
|
|
37
|
+
<TableRow key={i}>
|
|
38
|
+
<TableCell style={{ color: getStatusColor(quest.status) }}>
|
|
39
|
+
{quest.status ?? 'Unknown'}
|
|
40
|
+
</TableCell>
|
|
41
|
+
<TableCell>
|
|
42
|
+
<SimpleTooltip
|
|
43
|
+
content={formatText(quest.title)}
|
|
44
|
+
direction="bottom"
|
|
45
|
+
>
|
|
46
|
+
<Ellipsis maxWidth="300px">
|
|
47
|
+
{formatText(quest.title)}
|
|
48
|
+
</Ellipsis>
|
|
49
|
+
</SimpleTooltip>
|
|
50
|
+
</TableCell>
|
|
51
|
+
<TableCell>
|
|
52
|
+
<SimpleTooltip
|
|
53
|
+
content={quest.description}
|
|
54
|
+
direction="bottom"
|
|
55
|
+
>
|
|
56
|
+
<Ellipsis maxWidth="300px">{quest.description}</Ellipsis>
|
|
57
|
+
</SimpleTooltip>
|
|
58
|
+
</TableCell>
|
|
59
|
+
<TableCell>
|
|
60
|
+
<SimpleTooltip
|
|
61
|
+
content={formatObjectives(quest.objectives)}
|
|
62
|
+
direction="bottom"
|
|
63
|
+
>
|
|
64
|
+
<Ellipsis maxWidth="300px">
|
|
65
|
+
{formatObjectives(quest.objectives)}
|
|
66
|
+
</Ellipsis>
|
|
67
|
+
</SimpleTooltip>
|
|
68
|
+
</TableCell>
|
|
69
|
+
<TableCell>
|
|
70
|
+
<SimpleTooltip
|
|
71
|
+
content={formatRewards(quest.rewards)}
|
|
72
|
+
direction="bottom"
|
|
73
|
+
>
|
|
74
|
+
<Ellipsis maxWidth="200px">
|
|
75
|
+
{formatRewards(quest.rewards)}
|
|
76
|
+
</Ellipsis>
|
|
77
|
+
</SimpleTooltip>
|
|
78
|
+
</TableCell>
|
|
79
|
+
</TableRow>
|
|
80
|
+
))}
|
|
81
|
+
</tbody>
|
|
82
|
+
</Table>
|
|
83
|
+
</>
|
|
84
|
+
) : (
|
|
85
|
+
<NoQuestContainer>
|
|
86
|
+
<p>There are no ongoing quests</p>
|
|
87
|
+
</NoQuestContainer>
|
|
88
|
+
)}
|
|
89
|
+
</QuestListContainer>
|
|
53
90
|
);
|
|
54
91
|
};
|
|
55
92
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
93
|
+
// Updated helper function to format objectives
|
|
94
|
+
const formatObjectives = (
|
|
95
|
+
objectives: (IQuestObjectiveKill | IQuestObjectiveInteraction)[]
|
|
96
|
+
) => {
|
|
97
|
+
return objectives
|
|
98
|
+
.map(objective => {
|
|
99
|
+
if ('killCountTarget' in objective) {
|
|
100
|
+
// This is an IQuestObjectiveKill
|
|
101
|
+
const killObjective = objective as IQuestObjectiveKill;
|
|
102
|
+
return `Kill ${formatText(killObjective.creatureKeys.join(', '))}: ${
|
|
103
|
+
killObjective.killCount
|
|
104
|
+
}/${killObjective.killCountTarget}`;
|
|
105
|
+
} else if ('targetNPCkey' in objective) {
|
|
106
|
+
// This is an IQuestObjectiveInteraction
|
|
107
|
+
const interactionObjective = objective as IQuestObjectiveInteraction;
|
|
108
|
+
return `Interact with NPC: ${formatText(
|
|
109
|
+
interactionObjective.targetNPCkey ?? 'Unknown'
|
|
110
|
+
)}`;
|
|
111
|
+
} else {
|
|
112
|
+
return 'Unknown objective';
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
.join('; ');
|
|
116
|
+
};
|
|
61
117
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
118
|
+
// Other helper functions remain the same
|
|
119
|
+
const formatRewards = (rewards: IQuest['rewards']) => {
|
|
120
|
+
return rewards
|
|
121
|
+
.map(reward => {
|
|
122
|
+
return `${formatText(
|
|
123
|
+
reward.itemKeys.map(itemKey => itemKey + ' x' + reward.qty).join(', ')
|
|
124
|
+
)}${
|
|
125
|
+
reward.spellKeys
|
|
126
|
+
? `, Spells: ${formatText(reward.spellKeys.join(', '))}`
|
|
127
|
+
: ''
|
|
128
|
+
}`;
|
|
129
|
+
})
|
|
130
|
+
.join('; ');
|
|
131
|
+
};
|
|
68
132
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
133
|
+
const formatText = (text: string) => {
|
|
134
|
+
return text
|
|
135
|
+
.split('-')
|
|
136
|
+
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
|
|
137
|
+
.join(' ');
|
|
138
|
+
};
|
|
73
139
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
140
|
+
const getStatusColor = (status?: QuestStatus) => {
|
|
141
|
+
switch (status) {
|
|
142
|
+
case QuestStatus.Pending:
|
|
143
|
+
return uiColors.orange; // Orange
|
|
144
|
+
case QuestStatus.InProgress:
|
|
145
|
+
return uiColors.blue; // Deep Sky Blue
|
|
146
|
+
case QuestStatus.Completed:
|
|
147
|
+
return uiColors.lightGreen; // Lime Green
|
|
148
|
+
default:
|
|
149
|
+
return uiColors.white; // Default to white
|
|
77
150
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const Title = styled.h1`
|
|
81
|
-
z-index: 22;
|
|
82
|
-
font-size: ${uiFonts.size.medium} !important;
|
|
83
|
-
color: yellow !important;
|
|
84
|
-
`;
|
|
151
|
+
};
|
|
85
152
|
|
|
86
153
|
const QuestListContainer = styled.div`
|
|
87
154
|
margin-top: 20px;
|
|
88
155
|
margin-bottom: 40px;
|
|
89
156
|
overflow-y: auto;
|
|
90
157
|
max-height: 400px;
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
.quest-number {
|
|
99
|
-
border-radius: 50%;
|
|
100
|
-
width: 28px;
|
|
101
|
-
height: 28px;
|
|
102
|
-
display: flex;
|
|
103
|
-
align-items: center;
|
|
104
|
-
justify-content: center;
|
|
105
|
-
margin-right: 16px;
|
|
106
|
-
background-color: brown;
|
|
107
|
-
flex-shrink: 0;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
.quest-number.completed {
|
|
111
|
-
background-color: yellow;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
p {
|
|
115
|
-
margin: 0;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
.quest-detail__title {
|
|
119
|
-
color: yellow;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
.quest-detail__description {
|
|
123
|
-
margin-top: 5px;
|
|
124
|
-
}
|
|
125
|
-
.Noquest-detail__description {
|
|
126
|
-
margin-top: 5px;
|
|
127
|
-
margin: auto;
|
|
128
|
-
}
|
|
158
|
+
background-color: ${uiColors.darkGray};
|
|
159
|
+
padding: 20px;
|
|
160
|
+
border-radius: 10px;
|
|
161
|
+
border: 1px solid ${uiColors.gray};
|
|
162
|
+
font-size: 0.7rem;
|
|
129
163
|
`;
|
|
164
|
+
|
|
130
165
|
const NoQuestContainer = styled.div`
|
|
131
166
|
text-align: center;
|
|
132
167
|
p {
|
|
133
168
|
margin-top: 5px;
|
|
169
|
+
color: ${uiColors.lightGray};
|
|
134
170
|
}
|
|
135
171
|
`;
|
|
@@ -11,6 +11,9 @@ export const TableRow = styled.tr`
|
|
|
11
11
|
&:nth-child(even) {
|
|
12
12
|
background-color: rgba(255, 255, 255, 0.05) !important;
|
|
13
13
|
}
|
|
14
|
+
&:hover {
|
|
15
|
+
background-color: rgba(255, 255, 255, 0.1) !important;
|
|
16
|
+
}
|
|
14
17
|
`;
|
|
15
18
|
|
|
16
19
|
export const TableHeader = styled.th`
|
|
@@ -18,13 +21,14 @@ export const TableHeader = styled.th`
|
|
|
18
21
|
padding: 0.5rem;
|
|
19
22
|
color: ${uiColors.yellow} !important;
|
|
20
23
|
border-bottom: 1px solid ${uiColors.lightGray};
|
|
24
|
+
text-shadow: -2px 0 black, 0 2px black, 2px 0 black, 0 -2px black;
|
|
21
25
|
`;
|
|
22
26
|
|
|
23
27
|
export const TableCell = styled.td`
|
|
24
28
|
padding: 0.5rem;
|
|
25
29
|
color: ${uiColors.white};
|
|
26
30
|
border-bottom: 1px solid ${uiColors.lightGray};
|
|
27
|
-
text-
|
|
31
|
+
text-shadow: -2px 0 black, 0 2px black, 2px 0 black, 0 -2px black;
|
|
28
32
|
`;
|
|
29
33
|
|
|
30
34
|
export const ActionButtons = styled.div`
|
|
@@ -3,7 +3,7 @@ import styled from 'styled-components';
|
|
|
3
3
|
|
|
4
4
|
interface IProps {
|
|
5
5
|
children: React.ReactNode;
|
|
6
|
-
maxLines
|
|
6
|
+
maxLines?: 1 | 2 | 3;
|
|
7
7
|
maxWidth: string;
|
|
8
8
|
fontSize?: string;
|
|
9
9
|
center?: boolean;
|
|
@@ -11,7 +11,7 @@ interface IProps {
|
|
|
11
11
|
|
|
12
12
|
export const Ellipsis = ({
|
|
13
13
|
children,
|
|
14
|
-
maxLines,
|
|
14
|
+
maxLines = 1,
|
|
15
15
|
maxWidth,
|
|
16
16
|
fontSize,
|
|
17
17
|
center,
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import React, { ReactNode, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import ReactDOM from 'react-dom';
|
|
3
|
+
import styled, { keyframes } from 'styled-components';
|
|
4
|
+
import { uiColors } from '../../constants/uiColors';
|
|
5
|
+
import { RPGUIRoot } from '../RPGUI/RPGUIRoot';
|
|
6
|
+
|
|
7
|
+
interface TooltipProps {
|
|
8
|
+
content: string | ReactNode;
|
|
9
|
+
direction?: 'top' | 'bottom' | 'left' | 'right';
|
|
10
|
+
backgroundColor?: string;
|
|
11
|
+
textColor?: string;
|
|
12
|
+
children: ReactNode;
|
|
13
|
+
showDelay?: number;
|
|
14
|
+
hideDelay?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const SimpleTooltip: React.FC<TooltipProps> = ({
|
|
18
|
+
content,
|
|
19
|
+
direction = 'top',
|
|
20
|
+
backgroundColor = uiColors.raisinBlack,
|
|
21
|
+
textColor = uiColors.white,
|
|
22
|
+
children,
|
|
23
|
+
showDelay = 200,
|
|
24
|
+
hideDelay = 200,
|
|
25
|
+
}) => {
|
|
26
|
+
const [visible, setVisible] = useState(false);
|
|
27
|
+
const [tooltipPosition, setTooltipPosition] = useState({ top: 0, left: 0 });
|
|
28
|
+
const tooltipRef = useRef<HTMLDivElement>(null);
|
|
29
|
+
const triggerRef = useRef<HTMLDivElement>(null);
|
|
30
|
+
const timeoutRef = useRef<NodeJS.Timeout>();
|
|
31
|
+
|
|
32
|
+
const calculatePosition = () => {
|
|
33
|
+
if (!triggerRef.current || !tooltipRef.current) return;
|
|
34
|
+
|
|
35
|
+
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
36
|
+
const tooltipRect = tooltipRef.current.getBoundingClientRect();
|
|
37
|
+
|
|
38
|
+
let top, left;
|
|
39
|
+
|
|
40
|
+
switch (direction) {
|
|
41
|
+
case 'top':
|
|
42
|
+
top = triggerRect.top - tooltipRect.height - 8;
|
|
43
|
+
left = triggerRect.left + (triggerRect.width - tooltipRect.width) / 2;
|
|
44
|
+
break;
|
|
45
|
+
case 'bottom':
|
|
46
|
+
top = triggerRect.bottom + 8;
|
|
47
|
+
left = triggerRect.left + (triggerRect.width - tooltipRect.width) / 2;
|
|
48
|
+
break;
|
|
49
|
+
case 'left':
|
|
50
|
+
top = triggerRect.top + (triggerRect.height - tooltipRect.height) / 2;
|
|
51
|
+
left = triggerRect.left - tooltipRect.width - 8;
|
|
52
|
+
break;
|
|
53
|
+
case 'right':
|
|
54
|
+
top = triggerRect.top + (triggerRect.height - tooltipRect.height) / 2;
|
|
55
|
+
left = triggerRect.right + 8;
|
|
56
|
+
break;
|
|
57
|
+
default:
|
|
58
|
+
top = triggerRect.top - tooltipRect.height - 8;
|
|
59
|
+
left = triggerRect.left + (triggerRect.width - tooltipRect.width) / 2;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Ensure the tooltip stays within the viewport
|
|
63
|
+
if (left < 8) left = 8;
|
|
64
|
+
if (left + tooltipRect.width > window.innerWidth)
|
|
65
|
+
left = window.innerWidth - tooltipRect.width - 8;
|
|
66
|
+
if (top < 8) top = 8;
|
|
67
|
+
if (top + tooltipRect.height > window.innerHeight)
|
|
68
|
+
top = window.innerHeight - tooltipRect.height - 8;
|
|
69
|
+
|
|
70
|
+
setTooltipPosition({ top: Math.round(top), left: Math.round(left) });
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const showTooltip = () => {
|
|
74
|
+
clearTimeout(timeoutRef.current);
|
|
75
|
+
timeoutRef.current = setTimeout(() => {
|
|
76
|
+
setVisible(true);
|
|
77
|
+
calculatePosition();
|
|
78
|
+
}, showDelay);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const hideTooltip = () => {
|
|
82
|
+
clearTimeout(timeoutRef.current);
|
|
83
|
+
timeoutRef.current = setTimeout(() => {
|
|
84
|
+
setVisible(false);
|
|
85
|
+
}, hideDelay);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
const handleMouseMove = (event: MouseEvent) => {
|
|
90
|
+
if (visible && tooltipRef.current && triggerRef.current) {
|
|
91
|
+
const tooltipRect = tooltipRef.current.getBoundingClientRect();
|
|
92
|
+
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
93
|
+
|
|
94
|
+
const isOutsideTooltip =
|
|
95
|
+
event.clientX < tooltipRect.left ||
|
|
96
|
+
event.clientX > tooltipRect.right ||
|
|
97
|
+
event.clientY < tooltipRect.top ||
|
|
98
|
+
event.clientY > tooltipRect.bottom;
|
|
99
|
+
|
|
100
|
+
const isOutsideTrigger =
|
|
101
|
+
event.clientX < triggerRect.left ||
|
|
102
|
+
event.clientX > triggerRect.right ||
|
|
103
|
+
event.clientY < triggerRect.top ||
|
|
104
|
+
event.clientY > triggerRect.bottom;
|
|
105
|
+
|
|
106
|
+
if (isOutsideTooltip && isOutsideTrigger) {
|
|
107
|
+
hideTooltip();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const handleScroll = () => {
|
|
113
|
+
if (visible) {
|
|
114
|
+
hideTooltip();
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const handleResize = () => {
|
|
119
|
+
if (visible) {
|
|
120
|
+
calculatePosition();
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
document.addEventListener('mousemove', handleMouseMove);
|
|
125
|
+
window.addEventListener('scroll', handleScroll);
|
|
126
|
+
window.addEventListener('resize', handleResize);
|
|
127
|
+
|
|
128
|
+
return () => {
|
|
129
|
+
document.removeEventListener('mousemove', handleMouseMove);
|
|
130
|
+
window.removeEventListener('scroll', handleScroll);
|
|
131
|
+
window.removeEventListener('resize', handleResize);
|
|
132
|
+
clearTimeout(timeoutRef.current);
|
|
133
|
+
};
|
|
134
|
+
}, [visible]);
|
|
135
|
+
|
|
136
|
+
return (
|
|
137
|
+
<TooltipContainer
|
|
138
|
+
ref={triggerRef}
|
|
139
|
+
onMouseEnter={showTooltip}
|
|
140
|
+
onMouseLeave={hideTooltip}
|
|
141
|
+
onFocus={showTooltip}
|
|
142
|
+
onBlur={hideTooltip}
|
|
143
|
+
>
|
|
144
|
+
{children}
|
|
145
|
+
{visible &&
|
|
146
|
+
ReactDOM.createPortal(
|
|
147
|
+
<RPGUIRoot>
|
|
148
|
+
<TooltipBox
|
|
149
|
+
ref={tooltipRef}
|
|
150
|
+
direction={direction}
|
|
151
|
+
backgroundColor={backgroundColor}
|
|
152
|
+
textColor={textColor}
|
|
153
|
+
style={{ top: tooltipPosition.top, left: tooltipPosition.left }}
|
|
154
|
+
>
|
|
155
|
+
{content}
|
|
156
|
+
</TooltipBox>
|
|
157
|
+
</RPGUIRoot>,
|
|
158
|
+
document.body
|
|
159
|
+
)}
|
|
160
|
+
</TooltipContainer>
|
|
161
|
+
);
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const TooltipContainer = styled.div`
|
|
165
|
+
display: inline-block;
|
|
166
|
+
cursor: inherit;
|
|
167
|
+
`;
|
|
168
|
+
|
|
169
|
+
const fadeIn = keyframes`
|
|
170
|
+
from {
|
|
171
|
+
opacity: 0;
|
|
172
|
+
transform: scale(0.95);
|
|
173
|
+
}
|
|
174
|
+
to {
|
|
175
|
+
opacity: 1;
|
|
176
|
+
transform: scale(1);
|
|
177
|
+
}
|
|
178
|
+
`;
|
|
179
|
+
|
|
180
|
+
interface TooltipBoxProps {
|
|
181
|
+
direction: 'top' | 'bottom' | 'left' | 'right';
|
|
182
|
+
backgroundColor: string;
|
|
183
|
+
textColor: string;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const TooltipBox = styled.div<TooltipBoxProps>`
|
|
187
|
+
position: fixed;
|
|
188
|
+
z-index: 1000;
|
|
189
|
+
background-color: ${({ backgroundColor }) => backgroundColor};
|
|
190
|
+
color: ${({ textColor }) => textColor};
|
|
191
|
+
padding: 8px;
|
|
192
|
+
border-radius: 4px;
|
|
193
|
+
font-size: 0.65rem;
|
|
194
|
+
max-width: 250px;
|
|
195
|
+
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
|
|
196
|
+
animation: ${fadeIn} 0.2s ease-out;
|
|
197
|
+
line-height: 1.3;
|
|
198
|
+
`;
|
|
@@ -22,61 +22,31 @@ const IQuestMock = [
|
|
|
22
22
|
_id: '6317996c77f2420047a20b55',
|
|
23
23
|
rewards: [
|
|
24
24
|
{
|
|
25
|
-
id: '
|
|
26
|
-
itemKeys: ['
|
|
27
|
-
spellKeys: ['6317996c77f2420047a20b53'],
|
|
25
|
+
id: '66cd2b039b486b00436a4ace',
|
|
26
|
+
itemKeys: ['iron-armor'],
|
|
28
27
|
qty: 1,
|
|
29
28
|
},
|
|
30
29
|
],
|
|
31
30
|
objectives: [
|
|
32
31
|
{
|
|
33
|
-
id: '
|
|
34
|
-
type: QuestType.
|
|
32
|
+
id: '66cd2b049b486b00436a4b1a',
|
|
33
|
+
type: QuestType.Interaction,
|
|
35
34
|
status: QuestStatus.Pending,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
creatureKeys: ['6317996c77f2420047a20b53'],
|
|
35
|
+
targetNPCkey: 'durgan-miner',
|
|
36
|
+
items: [{ itemKey: 'iron-ingot', qty: 10 }],
|
|
39
37
|
},
|
|
40
38
|
],
|
|
41
39
|
npcId: '6317996b77f2420047a20825',
|
|
42
|
-
title: '
|
|
43
|
-
key: 'interaction-
|
|
40
|
+
title: 'Iron Ingot Craftsmanship',
|
|
41
|
+
key: 'interaction-durgan-miner',
|
|
44
42
|
description:
|
|
45
|
-
"
|
|
46
|
-
createdAt: '
|
|
47
|
-
updatedAt: '
|
|
48
|
-
|
|
49
|
-
{
|
|
50
|
-
_id: '6317996c77f2420047a20b55',
|
|
51
|
-
rewards: [
|
|
52
|
-
{
|
|
53
|
-
id: '6317996c77f2420047a20b53',
|
|
54
|
-
itemKeys: ['6317996c77f2420047a20b53'],
|
|
55
|
-
spellKeys: ['6317996c77f2420047a20b53'],
|
|
56
|
-
qty: 1,
|
|
57
|
-
},
|
|
58
|
-
],
|
|
59
|
-
objectives: [
|
|
60
|
-
{
|
|
61
|
-
id: '6317996c77f2420047a20b53',
|
|
62
|
-
type: QuestType.Kill,
|
|
63
|
-
status: QuestStatus.Pending,
|
|
64
|
-
killCount: 10,
|
|
65
|
-
killCountTarget: 30,
|
|
66
|
-
creatureKeys: ['6317996c77f2420047a20b53'],
|
|
67
|
-
},
|
|
68
|
-
],
|
|
69
|
-
npcId: '6317996b77f2420047a20825',
|
|
70
|
-
title: 'Deliver message to the trader2',
|
|
71
|
-
key: 'interaction-trader',
|
|
72
|
-
description:
|
|
73
|
-
"Need to send a message to my brother, the trader, about my father's health. I cannot do it because it is too dangerous out there. Please, help me by delivering this message to him.",
|
|
74
|
-
createdAt: '2022-09-06T19:03:08.285+0000',
|
|
75
|
-
updatedAt: '2022-09-06T19:03:08.304+0000',
|
|
43
|
+
"Employ your pickaxe to mine ore, followed by utilizing your blacksmith hammer. Select 'Use with,' then target an anvil to forge ingots. Provide me with 10 Iron Ingots, and I shall craft you an Iron Armor!",
|
|
44
|
+
createdAt: '2024-08-27T01:25:24.285+0000',
|
|
45
|
+
updatedAt: '2024-08-27T01:25:24.304+0000',
|
|
46
|
+
status: QuestStatus.Pending,
|
|
76
47
|
},
|
|
77
48
|
];
|
|
78
49
|
|
|
79
50
|
Default.args = {
|
|
80
51
|
quests: IQuestMock,
|
|
81
|
-
onClose: () => console.log('closing'),
|
|
82
52
|
};
|