@hytopia.com/examples 1.0.17 → 1.0.18
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/frontiers-rpg-game/assets/icons/buttons/e-mobile.png +0 -0
- package/frontiers-rpg-game/assets/icons/buttons/jump.png +0 -0
- package/frontiers-rpg-game/assets/ui/hud.html +336 -137
- package/frontiers-rpg-game/assets/ui/index.html +1089 -491
- package/frontiers-rpg-game/assets/ui/menus/backpack.html +121 -52
- package/frontiers-rpg-game/assets/ui/menus/crafting.html +63 -41
- package/frontiers-rpg-game/assets/ui/menus/dialogue.html +53 -75
- package/frontiers-rpg-game/assets/ui/menus/merchant.html +117 -123
- package/frontiers-rpg-game/assets/ui/menus/quests.html +151 -28
- package/frontiers-rpg-game/assets/ui/menus/skills.html +123 -30
- package/frontiers-rpg-game/assets/ui/shared/item-tooltips.html +125 -5
- package/frontiers-rpg-game/dev/persistence/player-player-1.json +11 -3
- package/frontiers-rpg-game/src/entities/BaseCombatEntity.ts +1 -1
- package/package.json +1 -1
|
@@ -77,6 +77,9 @@
|
|
|
77
77
|
function closeSkills() {
|
|
78
78
|
document.querySelector('.skills-overlay').style.display = 'none';
|
|
79
79
|
hytopia.lockPointer(true);
|
|
80
|
+
|
|
81
|
+
// Close any open mobile tooltips
|
|
82
|
+
closeAllMobileTooltips();
|
|
80
83
|
}
|
|
81
84
|
|
|
82
85
|
// Update Functions
|
|
@@ -107,6 +110,9 @@
|
|
|
107
110
|
const skillItem = createSkillItem(skill);
|
|
108
111
|
skillsGrid.appendChild(skillItem);
|
|
109
112
|
});
|
|
113
|
+
|
|
114
|
+
// Close any open mobile tooltips after updating skills
|
|
115
|
+
closeAllMobileTooltips();
|
|
110
116
|
}
|
|
111
117
|
|
|
112
118
|
function updateSkillsExp(data) {
|
|
@@ -174,6 +180,54 @@
|
|
|
174
180
|
// Event Listeners
|
|
175
181
|
function setupEventListeners() {
|
|
176
182
|
document.querySelector('.skills-close').addEventListener('click', closeSkills);
|
|
183
|
+
|
|
184
|
+
// Setup mobile tooltip handling
|
|
185
|
+
setupMobileTooltips();
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Mobile tooltip handling
|
|
189
|
+
function setupMobileTooltips() {
|
|
190
|
+
// Check if we're on mobile
|
|
191
|
+
const isMobile = document.body.classList.contains('mobile');
|
|
192
|
+
if (!isMobile) return;
|
|
193
|
+
|
|
194
|
+
// Add click handler to skills container for event delegation
|
|
195
|
+
document.querySelector('.skills-skills-grid').addEventListener('click', handleMobileTooltipClick);
|
|
196
|
+
|
|
197
|
+
// Add click handler to document to close tooltips when clicking outside
|
|
198
|
+
document.addEventListener('click', handleDocumentClick);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function handleMobileTooltipClick(e) {
|
|
202
|
+
const skillItem = e.target.closest('.skills-skill-item');
|
|
203
|
+
if (!skillItem) return;
|
|
204
|
+
|
|
205
|
+
e.stopPropagation();
|
|
206
|
+
|
|
207
|
+
const tooltip = skillItem.querySelector('.skills-skill-tooltip');
|
|
208
|
+
if (!tooltip) return;
|
|
209
|
+
|
|
210
|
+
// Close any other open tooltips
|
|
211
|
+
closeAllMobileTooltips();
|
|
212
|
+
|
|
213
|
+
// Toggle this tooltip
|
|
214
|
+
tooltip.classList.add('skills-mobile-tooltip-visible');
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function handleDocumentClick(e) {
|
|
218
|
+
// Close tooltips when clicking outside
|
|
219
|
+
if (!e.target.closest('.skills-skill-item')) {
|
|
220
|
+
closeAllMobileTooltips();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function closeAllMobileTooltips() {
|
|
225
|
+
const visibleTooltips = document.querySelectorAll('.skills-mobile-tooltip-visible');
|
|
226
|
+
if (visibleTooltips.length > 0) {
|
|
227
|
+
visibleTooltips.forEach(tooltip => {
|
|
228
|
+
tooltip.classList.remove('skills-mobile-tooltip-visible');
|
|
229
|
+
});
|
|
230
|
+
}
|
|
177
231
|
}
|
|
178
232
|
|
|
179
233
|
// Initialize
|
|
@@ -490,96 +544,135 @@
|
|
|
490
544
|
/* Mobile Styles */
|
|
491
545
|
body.mobile .skills-container {
|
|
492
546
|
width: auto;
|
|
493
|
-
max-width:
|
|
494
|
-
min-width:
|
|
547
|
+
max-width: 680px;
|
|
548
|
+
min-width: 475px;
|
|
549
|
+
border-radius: 8px;
|
|
495
550
|
}
|
|
496
551
|
|
|
497
552
|
body.mobile .skills-header {
|
|
498
|
-
padding:
|
|
553
|
+
padding: 8px 12px;
|
|
554
|
+
border-radius: 8px 8px 0 0;
|
|
499
555
|
}
|
|
500
556
|
|
|
501
557
|
body.mobile .skills-title {
|
|
502
|
-
font-size:
|
|
558
|
+
font-size: 14px;
|
|
503
559
|
}
|
|
504
560
|
|
|
505
561
|
body.mobile .skills-close {
|
|
506
|
-
width:
|
|
507
|
-
height:
|
|
508
|
-
font-size:
|
|
562
|
+
width: 24px;
|
|
563
|
+
height: 24px;
|
|
564
|
+
font-size: 16px;
|
|
565
|
+
border-radius: 6px;
|
|
509
566
|
}
|
|
510
567
|
|
|
511
568
|
body.mobile .skills-content {
|
|
512
|
-
padding:
|
|
569
|
+
padding: 12px;
|
|
513
570
|
}
|
|
514
571
|
|
|
515
572
|
body.mobile .skills-player-section,
|
|
516
573
|
body.mobile .skills-skills-section {
|
|
517
|
-
|
|
518
|
-
|
|
574
|
+
padding: 10px;
|
|
575
|
+
border-radius: 6px;
|
|
519
576
|
}
|
|
520
577
|
|
|
521
578
|
body.mobile .skills-section-title {
|
|
522
|
-
font-size:
|
|
523
|
-
margin-bottom:
|
|
579
|
+
font-size: 12px;
|
|
580
|
+
margin-bottom: 8px;
|
|
524
581
|
}
|
|
525
582
|
|
|
526
583
|
body.mobile .skills-level-display {
|
|
527
|
-
margin-bottom:
|
|
584
|
+
margin-bottom: 8px;
|
|
528
585
|
}
|
|
529
586
|
|
|
530
587
|
body.mobile .skills-level-number {
|
|
531
|
-
font-size:
|
|
588
|
+
font-size: 16px;
|
|
532
589
|
}
|
|
533
590
|
|
|
534
591
|
body.mobile .skills-exp-bar {
|
|
535
|
-
height:
|
|
592
|
+
height: 16px;
|
|
593
|
+
border-radius: 6px;
|
|
536
594
|
}
|
|
537
595
|
|
|
538
596
|
body.mobile .skills-exp-text {
|
|
539
|
-
font-size:
|
|
597
|
+
font-size: 10px;
|
|
540
598
|
}
|
|
541
599
|
|
|
542
600
|
body.mobile .skills-skills-grid {
|
|
543
|
-
grid-template-columns: 1fr 1fr;
|
|
544
|
-
gap:
|
|
601
|
+
grid-template-columns: 1fr 1fr 1fr;
|
|
602
|
+
gap: 6px;
|
|
545
603
|
}
|
|
546
604
|
|
|
547
605
|
body.mobile .skills-skill-item {
|
|
548
|
-
gap:
|
|
549
|
-
padding:
|
|
606
|
+
gap: 6px;
|
|
607
|
+
padding: 4px 8px;
|
|
608
|
+
border-radius: 6px;
|
|
609
|
+
min-height: 40px;
|
|
610
|
+
cursor: pointer;
|
|
611
|
+
-webkit-tap-highlight-color: rgba(255, 255, 255, 0.1);
|
|
550
612
|
}
|
|
551
613
|
|
|
552
614
|
body.mobile .skills-skill-icon {
|
|
553
615
|
width: 28px;
|
|
554
616
|
height: 28px;
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
body.mobile .skills-skill-icon-img {
|
|
558
|
-
width: 100%;
|
|
559
|
-
height: 100%;
|
|
617
|
+
border-radius: 6px;
|
|
560
618
|
}
|
|
561
619
|
|
|
562
620
|
body.mobile .skills-skill-header {
|
|
563
|
-
margin-bottom:
|
|
621
|
+
margin-bottom: 4px;
|
|
564
622
|
}
|
|
565
623
|
|
|
566
624
|
body.mobile .skills-skill-name {
|
|
567
|
-
font-size:
|
|
625
|
+
font-size: 10px;
|
|
626
|
+
overflow: hidden;
|
|
627
|
+
text-overflow: ellipsis;
|
|
628
|
+
white-space: nowrap;
|
|
568
629
|
}
|
|
569
630
|
|
|
570
631
|
body.mobile .skills-skill-level {
|
|
571
|
-
font-size:
|
|
632
|
+
font-size: 9px;
|
|
633
|
+
flex-shrink: 0;
|
|
572
634
|
}
|
|
573
635
|
|
|
574
636
|
body.mobile .skills-skill-exp-bar {
|
|
575
637
|
height: 10px;
|
|
638
|
+
border-radius: 6px;
|
|
576
639
|
}
|
|
577
640
|
|
|
578
641
|
body.mobile .skills-skill-exp-text {
|
|
579
|
-
font-size:
|
|
642
|
+
font-size: 7px;
|
|
580
643
|
}
|
|
581
644
|
|
|
582
645
|
body.mobile .skills-skill-tooltip {
|
|
583
|
-
|
|
646
|
+
opacity: 0;
|
|
647
|
+
visibility: hidden;
|
|
648
|
+
transform: translateY(-4px);
|
|
649
|
+
transition: all 0.2s ease;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
body.mobile .skills-mobile-tooltip-visible {
|
|
653
|
+
opacity: 1 !important;
|
|
654
|
+
visibility: visible !important;
|
|
655
|
+
transform: translateY(-8px) !important;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
body.mobile .skills-skill-tooltip-content {
|
|
659
|
+
max-width: 180px;
|
|
660
|
+
font-size: 10px;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
/* Center the caret on mobile */
|
|
664
|
+
body.mobile .skills-skill-tooltip-content::after {
|
|
665
|
+
left: 50% !important;
|
|
666
|
+
transform: translateX(-50%) !important;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
body.mobile .skills-skill-tooltip-content::before {
|
|
670
|
+
left: 50% !important;
|
|
671
|
+
transform: translateX(-50%) !important;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
/* Enable scrolling if needed */
|
|
675
|
+
body.mobile .skills-content * {
|
|
676
|
+
touch-action: pan-y !important;
|
|
584
677
|
}
|
|
585
678
|
</style>
|
|
@@ -123,12 +123,75 @@ window.ItemTooltips = (function() {
|
|
|
123
123
|
if (existingTooltip) existingTooltip.remove();
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
+
// Mobile tooltip handling
|
|
127
|
+
let mobileTooltipActive = false;
|
|
128
|
+
|
|
129
|
+
function initializeMobileTooltips() {
|
|
130
|
+
// Check if we're on mobile
|
|
131
|
+
const isMobile = document.body.classList.contains('mobile');
|
|
132
|
+
if (!isMobile) return;
|
|
133
|
+
|
|
134
|
+
// Add click handler to document for event delegation
|
|
135
|
+
document.addEventListener('click', handleMobileTooltipClick, true);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function handleMobileTooltipClick(e) {
|
|
139
|
+
// List of tooltip container selectors - include quest reward enabled class
|
|
140
|
+
const tooltipContainers = [
|
|
141
|
+
'.backpack-slot', '.backpack-hotbar-slot', '.backpack-wearable-slot',
|
|
142
|
+
'.hud-hotbar-slot', '.merchant-slot', '.merchant-hotbar-slot',
|
|
143
|
+
'.crafting-slot', '.crafting-requirement-item',
|
|
144
|
+
'.quests-reward-item', '.quests-reward-item-tooltip-enabled'
|
|
145
|
+
];
|
|
146
|
+
|
|
147
|
+
// Check if click is on a tooltip container
|
|
148
|
+
const container = e.target.closest(tooltipContainers.join(', '));
|
|
149
|
+
|
|
150
|
+
if (container) {
|
|
151
|
+
// Find tooltip in this container
|
|
152
|
+
const tooltip = container.querySelector([
|
|
153
|
+
'.item-tooltip', '.backpack-item-tooltip', '.merchant-item-tooltip',
|
|
154
|
+
'.crafting-item-tooltip', '.crafting-requirement-tooltip', '.quests-reward-item-tooltip'
|
|
155
|
+
].join(', '));
|
|
156
|
+
|
|
157
|
+
if (tooltip) {
|
|
158
|
+
// Close any other open tooltips
|
|
159
|
+
closeAllMobileTooltips();
|
|
160
|
+
|
|
161
|
+
// Show this tooltip
|
|
162
|
+
tooltip.classList.add('mobile-tooltip-visible');
|
|
163
|
+
mobileTooltipActive = true;
|
|
164
|
+
}
|
|
165
|
+
} else {
|
|
166
|
+
// Click outside any container - close all tooltips
|
|
167
|
+
closeAllMobileTooltips();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function closeAllMobileTooltips() {
|
|
172
|
+
const visibleTooltips = document.querySelectorAll('.mobile-tooltip-visible');
|
|
173
|
+
if (visibleTooltips.length > 0) {
|
|
174
|
+
visibleTooltips.forEach(tooltip => {
|
|
175
|
+
tooltip.classList.remove('mobile-tooltip-visible');
|
|
176
|
+
});
|
|
177
|
+
mobileTooltipActive = false;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Initialize mobile tooltips when DOM is ready
|
|
182
|
+
if (document.readyState === 'loading') {
|
|
183
|
+
document.addEventListener('DOMContentLoaded', initializeMobileTooltips);
|
|
184
|
+
} else {
|
|
185
|
+
initializeMobileTooltips();
|
|
186
|
+
}
|
|
187
|
+
|
|
126
188
|
// Public API
|
|
127
189
|
return {
|
|
128
190
|
parseText: parseText,
|
|
129
191
|
hasTooltipData: hasTooltipData,
|
|
130
192
|
createTooltip: createTooltip,
|
|
131
|
-
removeTooltip: removeTooltip
|
|
193
|
+
removeTooltip: removeTooltip,
|
|
194
|
+
closeAllMobileTooltips: closeAllMobileTooltips
|
|
132
195
|
};
|
|
133
196
|
})();
|
|
134
197
|
</script>
|
|
@@ -156,8 +219,7 @@ window.ItemTooltips = (function() {
|
|
|
156
219
|
.merchant-hotbar-slot:hover .item-tooltip,
|
|
157
220
|
.crafting-slot:hover .item-tooltip,
|
|
158
221
|
.crafting-requirement-item:hover .item-tooltip,
|
|
159
|
-
|
|
160
|
-
/* Tooltip visibility on hover - Specific classes */
|
|
222
|
+
|
|
161
223
|
.backpack-slot:hover .backpack-item-tooltip,
|
|
162
224
|
.backpack-hotbar-slot:hover .backpack-item-tooltip,
|
|
163
225
|
.backpack-wearable-slot:hover .backpack-item-tooltip,
|
|
@@ -281,14 +343,72 @@ window.ItemTooltips = (function() {
|
|
|
281
343
|
font-size: 11px;
|
|
282
344
|
}
|
|
283
345
|
|
|
284
|
-
/* Mobile -
|
|
346
|
+
/* Mobile - Control tooltip visibility on mobile devices */
|
|
285
347
|
body.mobile .item-tooltip,
|
|
286
348
|
body.mobile .backpack-item-tooltip,
|
|
287
349
|
body.mobile .merchant-item-tooltip,
|
|
288
350
|
body.mobile .crafting-item-tooltip,
|
|
289
351
|
body.mobile .crafting-requirement-tooltip,
|
|
290
352
|
body.mobile .quests-reward-item-tooltip {
|
|
291
|
-
|
|
353
|
+
opacity: 0;
|
|
354
|
+
visibility: hidden;
|
|
355
|
+
transform: translateY(-4px);
|
|
356
|
+
transition: all 0.2s ease;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/* Mobile tooltip visibility when tapped */
|
|
360
|
+
body.mobile .mobile-tooltip-visible {
|
|
361
|
+
opacity: 1 !important;
|
|
362
|
+
visibility: visible !important;
|
|
363
|
+
transform: translateY(-8px) !important;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/* Improve mobile tooltip positioning and touch targets */
|
|
367
|
+
body.mobile .backpack-slot,
|
|
368
|
+
body.mobile .backpack-hotbar-slot,
|
|
369
|
+
body.mobile .backpack-wearable-slot,
|
|
370
|
+
body.mobile .hud-hotbar-slot,
|
|
371
|
+
body.mobile .merchant-slot,
|
|
372
|
+
body.mobile .merchant-hotbar-slot,
|
|
373
|
+
body.mobile .crafting-slot,
|
|
374
|
+
body.mobile .crafting-requirement-item,
|
|
375
|
+
body.mobile .quests-reward-item,
|
|
376
|
+
body.mobile .quests-reward-item-tooltip-enabled {
|
|
377
|
+
cursor: pointer;
|
|
378
|
+
-webkit-tap-highlight-color: rgba(255, 255, 255, 0.1);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/* Center carets on mobile tooltips */
|
|
382
|
+
body.mobile .item-tooltip-content::after,
|
|
383
|
+
body.mobile .backpack-item-tooltip-content::after,
|
|
384
|
+
body.mobile .merchant-item-tooltip-content::after,
|
|
385
|
+
body.mobile .crafting-item-tooltip-content::after,
|
|
386
|
+
body.mobile .crafting-requirement-tooltip-content::after,
|
|
387
|
+
body.mobile .quests-reward-item-tooltip-content::after {
|
|
388
|
+
left: 50% !important;
|
|
389
|
+
transform: translateX(-50%) !important;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
body.mobile .item-tooltip-content::before,
|
|
393
|
+
body.mobile .backpack-item-tooltip-content::before,
|
|
394
|
+
body.mobile .merchant-item-tooltip-content::before,
|
|
395
|
+
body.mobile .crafting-item-tooltip-content::before,
|
|
396
|
+
body.mobile .crafting-requirement-tooltip-content::before,
|
|
397
|
+
body.mobile .quests-reward-item-tooltip-content::before {
|
|
398
|
+
left: 50% !important;
|
|
399
|
+
transform: translateX(-50%) !important;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/* Mobile tooltip content sizing */
|
|
403
|
+
body.mobile .item-tooltip-content,
|
|
404
|
+
body.mobile .backpack-item-tooltip-content,
|
|
405
|
+
body.mobile .merchant-item-tooltip-content,
|
|
406
|
+
body.mobile .crafting-item-tooltip-content,
|
|
407
|
+
body.mobile .crafting-requirement-tooltip-content,
|
|
408
|
+
body.mobile .quests-reward-item-tooltip-content {
|
|
409
|
+
max-width: 220px;
|
|
410
|
+
font-size: 11px;
|
|
411
|
+
padding: 8px 10px;
|
|
292
412
|
}
|
|
293
413
|
|
|
294
414
|
/* Mouse Follower Tooltip (for backpack drag system) */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"health": 120,
|
|
3
|
-
"currentRegionId": "
|
|
3
|
+
"currentRegionId": "stalkhaven",
|
|
4
4
|
"skillExperience": [
|
|
5
5
|
[
|
|
6
6
|
"exploration",
|
|
@@ -80,6 +80,14 @@
|
|
|
80
80
|
"dodge-3-times": 3,
|
|
81
81
|
"talk-to-mark": 0
|
|
82
82
|
}
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"questId": "dip-duck-dodge",
|
|
86
|
+
"state": "active",
|
|
87
|
+
"objectiveProgress": {
|
|
88
|
+
"dodge": 0,
|
|
89
|
+
"talk-to-sporn": 0
|
|
90
|
+
}
|
|
83
91
|
}
|
|
84
92
|
]
|
|
85
93
|
},
|
|
@@ -96,8 +104,8 @@
|
|
|
96
104
|
},
|
|
97
105
|
"currentRegionSpawnFacingAngle": 0,
|
|
98
106
|
"currentRegionSpawnPoint": {
|
|
99
|
-
"x":
|
|
107
|
+
"x": 1,
|
|
100
108
|
"y": 2,
|
|
101
|
-
"z":
|
|
109
|
+
"z": 40
|
|
102
110
|
}
|
|
103
111
|
}
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
|
|
16
16
|
const MOVEMENT_NOT_STUCK_DISTANCE_SQUARED = 3;
|
|
17
17
|
const COMBAT_REGEN_DEFAULT_DELAY_MS = 7000; // 7 seconds
|
|
18
|
-
const COMBAT_REGEN_DEFAULT_RATE = 0.
|
|
18
|
+
const COMBAT_REGEN_DEFAULT_RATE = 0.05; // 5% per interval
|
|
19
19
|
const COMBAT_REGEN_INTERVAL_MS = 3000; // 3 seconds
|
|
20
20
|
|
|
21
21
|
import BaseEntity, { BaseEntityOptions } from './BaseEntity';
|