@rpgjs/client 5.0.0-beta.23 → 5.0.0-beta.25
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/CHANGELOG.md +29 -0
- package/dist/Game/Object.d.ts +5 -0
- package/dist/Game/Object.js +48 -2
- package/dist/Game/Object.js.map +1 -1
- package/dist/Gui/Gui.js +5 -0
- package/dist/Gui/Gui.js.map +1 -1
- package/dist/components/character.ce.js +9 -2
- package/dist/components/character.ce.js.map +1 -1
- package/dist/components/gui/dialogbox/index.ce.js +54 -4
- package/dist/components/gui/dialogbox/index.ce.js.map +1 -1
- package/dist/components/gui/hud/hud.ce.js +2 -2
- package/dist/components/gui/hud/hud.ce.js.map +1 -1
- package/dist/components/gui/index.d.ts +3 -1
- package/dist/components/gui/index.js +2 -0
- package/dist/components/gui/input-field.ce.js +123 -0
- package/dist/components/gui/input-field.ce.js.map +1 -0
- package/dist/components/gui/input.ce.js +40 -0
- package/dist/components/gui/input.ce.js.map +1 -0
- package/dist/components/gui/menu/items-menu.ce.js +27 -4
- package/dist/components/gui/menu/items-menu.ce.js.map +1 -1
- package/dist/components/gui/menu/main-menu.ce.js +210 -155
- package/dist/components/gui/menu/main-menu.ce.js.map +1 -1
- package/dist/components/gui/save-load.ce.js +33 -4
- package/dist/components/gui/save-load.ce.js.map +1 -1
- package/dist/components/gui/shop/shop.ce.js +47 -4
- package/dist/components/gui/shop/shop.ce.js.map +1 -1
- package/dist/i18n.d.ts +11 -0
- package/dist/i18n.js +11 -0
- package/dist/i18n.js.map +1 -1
- package/dist/index.js +13 -11
- package/package.json +4 -4
- package/src/Game/Object.spec.ts +26 -2
- package/src/Game/Object.ts +71 -2
- package/src/Gui/Gui.spec.ts +5 -0
- package/src/Gui/Gui.ts +5 -1
- package/src/components/character.ce +12 -6
- package/src/components/gui/dialogbox/index.ce +82 -41
- package/src/components/gui/hud/hud.ce +2 -2
- package/src/components/gui/index.ts +5 -1
- package/src/components/gui/input-field.ce +106 -0
- package/src/components/gui/input.ce +26 -0
- package/src/components/gui/menu/items-menu.ce +12 -2
- package/src/components/gui/menu/main-menu.ce +37 -6
- package/src/components/gui/save-load.ce +48 -32
- package/src/components/gui/shop/shop.ce +28 -3
- package/src/i18n.ts +11 -0
- package/vite.config.ts +5 -2
|
@@ -112,6 +112,24 @@ function component($$props) {
|
|
|
112
112
|
view.set("menu");
|
|
113
113
|
});
|
|
114
114
|
};
|
|
115
|
+
const stopEvent = (event) => {
|
|
116
|
+
event?.stopPropagation?.();
|
|
117
|
+
};
|
|
118
|
+
const closeSaveOverlayFromPointer = (event) => {
|
|
119
|
+
stopEvent(event);
|
|
120
|
+
closeSaveOverlay();
|
|
121
|
+
};
|
|
122
|
+
const closeMenu = () => {
|
|
123
|
+
if (saveOverlay()) {
|
|
124
|
+
closeSaveOverlay();
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
onFinish();
|
|
128
|
+
};
|
|
129
|
+
const closeMenuFromPointer = (event) => {
|
|
130
|
+
stopEvent(event);
|
|
131
|
+
closeMenu();
|
|
132
|
+
};
|
|
115
133
|
const confirmExit = () => {
|
|
116
134
|
if (onInteraction) onInteraction("exit");
|
|
117
135
|
};
|
|
@@ -210,11 +228,18 @@ function component($$props) {
|
|
|
210
228
|
gamepad: { enabled: true }
|
|
211
229
|
});
|
|
212
230
|
mount((element) => {
|
|
231
|
+
const inputLockToken = {};
|
|
232
|
+
const previousStopProcessingInput = engine.stopProcessingInput;
|
|
233
|
+
const previousGamePause = engine.gamePause();
|
|
234
|
+
engine.__rpgMainMenuInputLock = inputLockToken;
|
|
235
|
+
engine.stopProcessingInput = true;
|
|
213
236
|
engine.gamePause.set(true);
|
|
214
237
|
return () => {
|
|
215
238
|
delay(() => {
|
|
216
|
-
engine.
|
|
217
|
-
engine.
|
|
239
|
+
if (engine.__rpgMainMenuInputLock !== inputLockToken) return;
|
|
240
|
+
engine.__rpgMainMenuInputLock = void 0;
|
|
241
|
+
engine.stopProcessingInput = previousStopProcessingInput;
|
|
242
|
+
engine.gamePause.set(previousGamePause);
|
|
218
243
|
});
|
|
219
244
|
};
|
|
220
245
|
});
|
|
@@ -223,177 +248,207 @@ function component($$props) {
|
|
|
223
248
|
height: "100%",
|
|
224
249
|
controls: menuControls
|
|
225
250
|
}, h(DOMElement, {
|
|
226
|
-
element: "div",
|
|
227
|
-
attrs: { class: "rpg-ui-main-menu rpg-anim-fade-in" }
|
|
228
|
-
}, [h(DOMElement, {
|
|
229
|
-
element: "div",
|
|
230
|
-
attrs: { class: "rpg-ui-main-menu-layout" }
|
|
231
|
-
}, [h(DOMElement, {
|
|
232
|
-
element: "div",
|
|
233
|
-
attrs: { class: "rpg-ui-main-menu-left rpg-ui-menu rpg-ui-panel" }
|
|
234
|
-
}, [h(DOMElement, {
|
|
235
|
-
element: "div",
|
|
236
|
-
attrs: { class: "rpg-ui-menu-header" },
|
|
237
|
-
textContent: computed(() => t("rpg.menu.title"))
|
|
238
|
-
}), h(DOMElement, {
|
|
239
|
-
element: "div",
|
|
240
|
-
attrs: { class: "rpg-ui-main-menu-list" }
|
|
241
|
-
}, loop(computed(() => menuEntries()), (entry, index) => h(DOMElement, {
|
|
242
251
|
element: "div",
|
|
243
252
|
attrs: {
|
|
244
|
-
class:
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
click: selectMenu(index)
|
|
248
|
-
},
|
|
249
|
-
textContent: entry.label
|
|
250
|
-
})))]), h(DOMElement, {
|
|
251
|
-
element: "div",
|
|
252
|
-
attrs: { class: "rpg-ui-main-menu-right" }
|
|
253
|
+
class: "rpg-ui-main-menu rpg-anim-fade-in",
|
|
254
|
+
click: closeMenuFromPointer
|
|
255
|
+
}
|
|
253
256
|
}, [
|
|
254
|
-
|
|
257
|
+
h(DOMElement, {
|
|
255
258
|
element: "div",
|
|
256
|
-
attrs: { class: "rpg-ui-
|
|
259
|
+
attrs: { class: "rpg-ui-main-menu-backdrop" }
|
|
260
|
+
}),
|
|
261
|
+
h(DOMElement, {
|
|
262
|
+
element: "button",
|
|
263
|
+
attrs: {
|
|
264
|
+
class: "rpg-ui-close-button",
|
|
265
|
+
type: "button",
|
|
266
|
+
title: "Close",
|
|
267
|
+
"aria-label": "Close menu",
|
|
268
|
+
click: closeMenuFromPointer
|
|
269
|
+
},
|
|
270
|
+
textContent: "x"
|
|
271
|
+
}),
|
|
272
|
+
h(DOMElement, {
|
|
273
|
+
element: "div",
|
|
274
|
+
attrs: {
|
|
275
|
+
class: "rpg-ui-main-menu-layout",
|
|
276
|
+
click: stopEvent
|
|
277
|
+
}
|
|
278
|
+
}, [h(DOMElement, {
|
|
279
|
+
element: "div",
|
|
280
|
+
attrs: { class: "rpg-ui-main-menu-left rpg-ui-menu rpg-ui-panel" }
|
|
281
|
+
}, [h(DOMElement, {
|
|
282
|
+
element: "div",
|
|
283
|
+
attrs: { class: "rpg-ui-menu-header" },
|
|
284
|
+
textContent: computed(() => t("rpg.menu.title"))
|
|
285
|
+
}), h(DOMElement, {
|
|
286
|
+
element: "div",
|
|
287
|
+
attrs: { class: "rpg-ui-main-menu-list" }
|
|
288
|
+
}, loop(computed(() => menuEntries()), (entry, index) => h(DOMElement, {
|
|
289
|
+
element: "div",
|
|
290
|
+
attrs: {
|
|
291
|
+
class: ["rpg-ui-menu-item", computed(() => ({ disabled: isMenuDisabled(entry) }))],
|
|
292
|
+
"data-selected": computed(() => selectedMenu() === index ? "true" : "false"),
|
|
293
|
+
tabindex: index,
|
|
294
|
+
click: selectMenu(index)
|
|
295
|
+
},
|
|
296
|
+
textContent: entry.label
|
|
297
|
+
})))]), h(DOMElement, {
|
|
298
|
+
element: "div",
|
|
299
|
+
attrs: { class: "rpg-ui-main-menu-right" }
|
|
257
300
|
}, [
|
|
258
|
-
h(DOMElement, {
|
|
259
|
-
element: "div",
|
|
260
|
-
attrs: { class: "rpg-ui-main-menu-section-title" },
|
|
261
|
-
textContent: computed(() => t("rpg.menu.status"))
|
|
262
|
-
}),
|
|
263
|
-
h(DOMElement, {
|
|
301
|
+
cond(computed(() => view() === "menu"), () => h(DOMElement, {
|
|
264
302
|
element: "div",
|
|
265
|
-
attrs: { class: "rpg-ui-
|
|
303
|
+
attrs: { class: "rpg-ui-panel" }
|
|
266
304
|
}, [
|
|
267
305
|
h(DOMElement, {
|
|
268
306
|
element: "div",
|
|
269
|
-
attrs: { class: "rpg-ui-main-menu-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
attrs: { class: "rpg-ui-main-menu-status-label" },
|
|
273
|
-
textContent: computed(() => t("rpg.menu.level"))
|
|
274
|
-
}), h(DOMElement, {
|
|
275
|
-
element: "div",
|
|
276
|
-
attrs: { class: "rpg-ui-main-menu-status-value" },
|
|
277
|
-
textContent: computed(() => level())
|
|
278
|
-
})]),
|
|
307
|
+
attrs: { class: "rpg-ui-main-menu-section-title" },
|
|
308
|
+
textContent: computed(() => t("rpg.menu.status"))
|
|
309
|
+
}),
|
|
279
310
|
h(DOMElement, {
|
|
280
311
|
element: "div",
|
|
281
|
-
attrs: { class: "rpg-ui-main-menu-status-
|
|
282
|
-
}, [
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
312
|
+
attrs: { class: "rpg-ui-main-menu-status-card" }
|
|
313
|
+
}, [
|
|
314
|
+
h(DOMElement, {
|
|
315
|
+
element: "div",
|
|
316
|
+
attrs: { class: "rpg-ui-main-menu-status-block" }
|
|
317
|
+
}, [h(DOMElement, {
|
|
318
|
+
element: "div",
|
|
319
|
+
attrs: { class: "rpg-ui-main-menu-status-label" },
|
|
320
|
+
textContent: computed(() => t("rpg.menu.level"))
|
|
321
|
+
}), h(DOMElement, {
|
|
322
|
+
element: "div",
|
|
323
|
+
attrs: { class: "rpg-ui-main-menu-status-value" },
|
|
324
|
+
textContent: computed(() => level())
|
|
325
|
+
})]),
|
|
326
|
+
h(DOMElement, {
|
|
327
|
+
element: "div",
|
|
328
|
+
attrs: { class: "rpg-ui-main-menu-status-block" }
|
|
329
|
+
}, [h(DOMElement, {
|
|
330
|
+
element: "div",
|
|
331
|
+
attrs: { class: "rpg-ui-main-menu-status-label" },
|
|
332
|
+
textContent: computed(() => t("rpg.menu.gold"))
|
|
333
|
+
}), h(DOMElement, {
|
|
334
|
+
element: "div",
|
|
335
|
+
attrs: { class: "rpg-ui-main-menu-status-value" },
|
|
336
|
+
textContent: computed(() => gold())
|
|
337
|
+
})]),
|
|
338
|
+
h(DOMElement, {
|
|
339
|
+
element: "div",
|
|
340
|
+
attrs: { class: "rpg-ui-main-menu-status-block" }
|
|
341
|
+
}, [h(DOMElement, {
|
|
342
|
+
element: "div",
|
|
343
|
+
attrs: { class: "rpg-ui-main-menu-status-label" },
|
|
344
|
+
textContent: computed(() => "HP " + hp() + "/" + hpMax())
|
|
345
|
+
}), h(DOMElement, {
|
|
346
|
+
element: "div",
|
|
347
|
+
attrs: { class: "rpg-ui-main-menu-status-bar" }
|
|
348
|
+
}, h(DOMElement, {
|
|
349
|
+
element: "div",
|
|
350
|
+
attrs: {
|
|
351
|
+
class: "rpg-ui-main-menu-status-bar-fill hp",
|
|
352
|
+
style: { width: hpPercent }
|
|
353
|
+
}
|
|
354
|
+
}))]),
|
|
355
|
+
h(DOMElement, {
|
|
356
|
+
element: "div",
|
|
357
|
+
attrs: { class: "rpg-ui-main-menu-status-block" }
|
|
358
|
+
}, [h(DOMElement, {
|
|
359
|
+
element: "div",
|
|
360
|
+
attrs: { class: "rpg-ui-main-menu-status-label" },
|
|
361
|
+
textContent: computed(() => "SP " + sp() + "/" + spMax())
|
|
362
|
+
}), h(DOMElement, {
|
|
363
|
+
element: "div",
|
|
364
|
+
attrs: { class: "rpg-ui-main-menu-status-bar" }
|
|
365
|
+
}, h(DOMElement, {
|
|
366
|
+
element: "div",
|
|
367
|
+
attrs: {
|
|
368
|
+
class: "rpg-ui-main-menu-status-bar-fill sp",
|
|
369
|
+
style: { width: spPercent }
|
|
370
|
+
}
|
|
371
|
+
}))]),
|
|
372
|
+
h(DOMElement, {
|
|
373
|
+
element: "div",
|
|
374
|
+
attrs: {
|
|
375
|
+
class: "rpg-ui-main-menu-status-block",
|
|
376
|
+
style: { gridColumn: "span 2" }
|
|
377
|
+
}
|
|
378
|
+
}, [h(DOMElement, {
|
|
379
|
+
element: "div",
|
|
380
|
+
attrs: { class: "rpg-ui-main-menu-status-label" },
|
|
381
|
+
textContent: computed(() => "EXP " + exp() + "/" + expForNextlevel())
|
|
382
|
+
}), h(DOMElement, {
|
|
383
|
+
element: "div",
|
|
384
|
+
attrs: { class: "rpg-ui-main-menu-status-bar" }
|
|
385
|
+
}, h(DOMElement, {
|
|
386
|
+
element: "div",
|
|
387
|
+
attrs: {
|
|
388
|
+
class: "rpg-ui-main-menu-status-bar-fill exp",
|
|
389
|
+
style: { width: expPercent }
|
|
390
|
+
}
|
|
391
|
+
}))])
|
|
392
|
+
]),
|
|
291
393
|
h(DOMElement, {
|
|
292
394
|
element: "div",
|
|
293
|
-
attrs: { class: "rpg-ui-main-menu-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
attrs: { class: "rpg-ui-main-menu-status-label" },
|
|
297
|
-
textContent: computed(() => "HP " + hp() + "/" + hpMax())
|
|
298
|
-
}), h(DOMElement, {
|
|
299
|
-
element: "div",
|
|
300
|
-
attrs: { class: "rpg-ui-main-menu-status-bar" }
|
|
301
|
-
}, h(DOMElement, {
|
|
302
|
-
element: "div",
|
|
303
|
-
attrs: {
|
|
304
|
-
class: "rpg-ui-main-menu-status-bar-fill hp",
|
|
305
|
-
style: { width: hpPercent }
|
|
306
|
-
}
|
|
307
|
-
}))]),
|
|
395
|
+
attrs: { class: "rpg-ui-main-menu-section-title" },
|
|
396
|
+
textContent: computed(() => t("rpg.menu.parameters"))
|
|
397
|
+
}),
|
|
308
398
|
h(DOMElement, {
|
|
309
399
|
element: "div",
|
|
310
|
-
attrs: { class: "rpg-ui-main-menu-
|
|
311
|
-
},
|
|
312
|
-
element: "div",
|
|
313
|
-
attrs: { class: "rpg-ui-main-menu-status-label" },
|
|
314
|
-
textContent: computed(() => "SP " + sp() + "/" + spMax())
|
|
315
|
-
}), h(DOMElement, {
|
|
316
|
-
element: "div",
|
|
317
|
-
attrs: { class: "rpg-ui-main-menu-status-bar" }
|
|
318
|
-
}, h(DOMElement, {
|
|
319
|
-
element: "div",
|
|
320
|
-
attrs: {
|
|
321
|
-
class: "rpg-ui-main-menu-status-bar-fill sp",
|
|
322
|
-
style: { width: spPercent }
|
|
323
|
-
}
|
|
324
|
-
}))]),
|
|
325
|
-
h(DOMElement, {
|
|
400
|
+
attrs: { class: "rpg-ui-main-menu-params" }
|
|
401
|
+
}, loop(paramsList, (param, index) => h(DOMElement, {
|
|
326
402
|
element: "div",
|
|
327
|
-
attrs: {
|
|
328
|
-
class: "rpg-ui-main-menu-status-block",
|
|
329
|
-
style: { gridColumn: "span 2" }
|
|
330
|
-
}
|
|
403
|
+
attrs: { class: "rpg-ui-main-menu-param" }
|
|
331
404
|
}, [h(DOMElement, {
|
|
332
|
-
element: "
|
|
333
|
-
|
|
334
|
-
textContent: computed(() => "EXP " + exp() + "/" + expForNextlevel())
|
|
405
|
+
element: "span",
|
|
406
|
+
textContent: param.label
|
|
335
407
|
}), h(DOMElement, {
|
|
336
|
-
element: "
|
|
337
|
-
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
})
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
}))
|
|
379
|
-
|
|
380
|
-
cond(computed(() => view() === "exit"), () => h(__ce_component$6, {
|
|
381
|
-
onConfirm: confirmExit,
|
|
382
|
-
onBack: goBack
|
|
383
|
-
}))
|
|
384
|
-
])]), cond(saveOverlay, () => h(DOMElement, {
|
|
385
|
-
element: "div",
|
|
386
|
-
attrs: { class: "rpg-ui-main-menu-overlay" }
|
|
387
|
-
}, [h(DOMElement, {
|
|
388
|
-
element: "div",
|
|
389
|
-
attrs: { class: "rpg-ui-main-menu-overlay-backdrop" }
|
|
390
|
-
}), h(DOMElement, {
|
|
391
|
-
element: "div",
|
|
392
|
-
attrs: { class: "rpg-ui-main-menu-overlay-content" }
|
|
393
|
-
}, h(__ce_component$1, {
|
|
394
|
-
data: saveLoadData,
|
|
395
|
-
onFinish: closeSaveOverlay
|
|
396
|
-
}))]))]));
|
|
408
|
+
element: "span",
|
|
409
|
+
textContent: param.value
|
|
410
|
+
})])))
|
|
411
|
+
])),
|
|
412
|
+
cond(computed(() => view() === "items"), () => h(__ce_component$2, {
|
|
413
|
+
data,
|
|
414
|
+
onInteraction,
|
|
415
|
+
onBack: goBack
|
|
416
|
+
})),
|
|
417
|
+
cond(computed(() => view() === "skills"), () => h(__ce_component$3, {
|
|
418
|
+
data,
|
|
419
|
+
onBack: goBack
|
|
420
|
+
})),
|
|
421
|
+
cond(computed(() => view() === "equip"), () => h(__ce_component$4, {
|
|
422
|
+
data,
|
|
423
|
+
onInteraction,
|
|
424
|
+
onBack: goBack
|
|
425
|
+
})),
|
|
426
|
+
cond(computed(() => view() === "options"), () => h(__ce_component$5, { onBack: goBack })),
|
|
427
|
+
cond(computed(() => view() === "exit"), () => h(__ce_component$6, {
|
|
428
|
+
onConfirm: confirmExit,
|
|
429
|
+
onBack: goBack
|
|
430
|
+
}))
|
|
431
|
+
])]),
|
|
432
|
+
cond(saveOverlay, () => h(DOMElement, {
|
|
433
|
+
element: "div",
|
|
434
|
+
attrs: { class: "rpg-ui-main-menu-overlay" }
|
|
435
|
+
}, [h(DOMElement, {
|
|
436
|
+
element: "div",
|
|
437
|
+
attrs: {
|
|
438
|
+
class: "rpg-ui-main-menu-overlay-backdrop",
|
|
439
|
+
click: closeSaveOverlayFromPointer
|
|
440
|
+
}
|
|
441
|
+
}), h(DOMElement, {
|
|
442
|
+
element: "div",
|
|
443
|
+
attrs: {
|
|
444
|
+
class: "rpg-ui-main-menu-overlay-content",
|
|
445
|
+
click: stopEvent
|
|
446
|
+
}
|
|
447
|
+
}, h(__ce_component$1, {
|
|
448
|
+
data: saveLoadData,
|
|
449
|
+
onFinish: closeSaveOverlay
|
|
450
|
+
}))]))
|
|
451
|
+
]));
|
|
397
452
|
}
|
|
398
453
|
var __ce_component = component;
|
|
399
454
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main-menu.ce.js","names":[],"sources":["../../../../src/components/gui/menu/main-menu.ce"],"sourcesContent":["<DOMContainer width=\"100%\" height=\"100%\" controls={menuControls}>\n <div class=\"rpg-ui-main-menu rpg-anim-fade-in\">\n <div class=\"rpg-ui-main-menu-layout\">\n <div class=\"rpg-ui-main-menu-left rpg-ui-menu rpg-ui-panel\">\n <div class=\"rpg-ui-menu-header\">{t(\"rpg.menu.title\")}</div>\n <div class=\"rpg-ui-main-menu-list\">\n @for ((entry,index) of menuEntries()) {\n <div\n class=\"rpg-ui-menu-item\"\n class={{disabled: isMenuDisabled(entry)}}\n data-selected={selectedMenu() === index ? \"true\" : \"false\"}\n tabindex={index}\n click={selectMenu(index)}\n >{entry.label}</div>\n }\n </div>\n </div>\n <div class=\"rpg-ui-main-menu-right\">\n @if (view() === \"menu\") {\n <div class=\"rpg-ui-panel\">\n <div class=\"rpg-ui-main-menu-section-title\">{t(\"rpg.menu.status\")}</div>\n <div class=\"rpg-ui-main-menu-status-card\">\n <div class=\"rpg-ui-main-menu-status-block\">\n <div class=\"rpg-ui-main-menu-status-label\">{t(\"rpg.menu.level\")}</div>\n <div class=\"rpg-ui-main-menu-status-value\">{level()}</div>\n </div>\n <div class=\"rpg-ui-main-menu-status-block\">\n <div class=\"rpg-ui-main-menu-status-label\">{t(\"rpg.menu.gold\")}</div>\n <div class=\"rpg-ui-main-menu-status-value\">{gold()}</div>\n </div>\n <div class=\"rpg-ui-main-menu-status-block\">\n <div class=\"rpg-ui-main-menu-status-label\">HP {hp()}/{hpMax()}</div>\n <div class=\"rpg-ui-main-menu-status-bar\">\n <div class=\"rpg-ui-main-menu-status-bar-fill hp\" style={{width: hpPercent}}></div>\n </div>\n </div>\n <div class=\"rpg-ui-main-menu-status-block\">\n <div class=\"rpg-ui-main-menu-status-label\">SP {sp()}/{spMax()}</div>\n <div class=\"rpg-ui-main-menu-status-bar\">\n <div class=\"rpg-ui-main-menu-status-bar-fill sp\" style={{width: spPercent}}></div>\n </div>\n </div>\n <div class=\"rpg-ui-main-menu-status-block\" style={{gridColumn: \"span 2\"}}>\n <div class=\"rpg-ui-main-menu-status-label\">EXP {exp()}/{expForNextlevel()}</div>\n <div class=\"rpg-ui-main-menu-status-bar\">\n <div class=\"rpg-ui-main-menu-status-bar-fill exp\" style={{width: expPercent}}></div>\n </div>\n </div>\n </div>\n <div class=\"rpg-ui-main-menu-section-title\">{t(\"rpg.menu.parameters\")}</div>\n <div class=\"rpg-ui-main-menu-params\">\n @for ((param,index) of paramsList) {\n <div class=\"rpg-ui-main-menu-param\">\n <span>{param.label}</span>\n <span>{param.value}</span>\n </div>\n }\n </div>\n </div>\n }\n @if (view() === \"items\") {\n <ItemsMenu data={data} onInteraction={onInteraction} onBack={goBack} />\n }\n @if (view() === \"skills\") {\n <SkillsMenu data={data} onBack={goBack} />\n }\n @if (view() === \"equip\") {\n <EquipMenu data={data} onInteraction={onInteraction} onBack={goBack} />\n }\n @if (view() === \"options\") {\n <OptionsMenu onBack={goBack} />\n }\n @if (view() === \"exit\") {\n <ExitMenu onConfirm={confirmExit} onBack={goBack} />\n }\n </div>\n </div>\n @if (saveOverlay) {\n <div class=\"rpg-ui-main-menu-overlay\">\n <div class=\"rpg-ui-main-menu-overlay-backdrop\"></div>\n <div class=\"rpg-ui-main-menu-overlay-content\">\n <SaveLoadComponent\n data={saveLoadData}\n onFinish={closeSaveOverlay}\n />\n </div>\n </div>\n }\n </div>\n</DOMContainer>\n\n<script>\n import { signal, computed, effect, mount } from \"canvasengine\";\n import { inject } from \"../../../core/inject\";\n import { RpgClientEngine } from \"../../../RpgClientEngine\";\n import SaveLoadComponent from \"../save-load.ce\";\n import ItemsMenu from \"./items-menu.ce\";\n import SkillsMenu from \"./skills-menu.ce\";\n import EquipMenu from \"./equip-menu.ce\";\n import OptionsMenu from \"./options-menu.ce\";\n import ExitMenu from \"./exit-menu.ce\";\n import { getEntityProp } from \"../../../utils/getEntityProp\";\n import { delay } from \"@rpgjs/common\";\n import { getKeyboardControlBind } from \"../../../services/actionInput\";\n\n const engine = inject(RpgClientEngine);\n const { t } = engine.i18n();\n const currentPlayer = engine.scene.currentPlayer;\n const keyboardControls = engine.globalConfig.keyboardControls;\n\n const { data, onFinish, onInteraction } = defineProps();\n const { menus, items, skills, equips, saveLoad } = data();\n\n const defaultMenus = [\n { id: \"items\", label: t(\"rpg.menu.items\") },\n { id: \"skills\", label: t(\"rpg.menu.skills\") },\n { id: \"equip\", label: t(\"rpg.menu.equip\") },\n { id: \"options\", label: t(\"rpg.menu.options\") },\n { id: \"save\", label: t(\"rpg.menu.save\") },\n { id: \"exit\", label: t(\"rpg.menu.exit\") }\n ];\n\n const menuEntries = computed(() => {\n if (menus && Array.isArray(menus) && menus.length) return menus;\n return defaultMenus;\n });\n\n const resolveProp = (value) => typeof value === \"function\" ? value() : value;\n const saveLoadData = computed(() => resolveProp(saveLoad) || {});\n const saveLoadMode = computed(() => saveLoadData().mode || \"load\");\n const saveLoadSlots = computed(() => saveLoadData().slots || []);\n const saveLoadCanSave = computed(() => saveLoadData().canSave !== false);\n\n const isMenuDisabled = (entry) => {\n if (!entry) return true;\n if (entry.disabled) return true;\n if (entry.enabled === false) return true;\n if (entry.id === \"save\" && !saveLoadCanSave()) return true;\n return false;\n };\n\n const selectedMenu = signal(0);\n const view = signal(\"menu\");\n const saveOverlay = signal(false);\n\n const selectableIndexes = computed(() => {\n const entries = menuEntries();\n return entries\n .map((entry, index) => (isMenuDisabled(entry) ? null : index))\n .filter((value) => value !== null);\n });\n\n effect(() => {\n const available = selectableIndexes();\n if (!available.length) return;\n const current = selectedMenu();\n if (!available.includes(current)) {\n selectedMenu.set(available[0]);\n }\n });\n\n const moveMenu = (delta) => {\n const available = selectableIndexes();\n if (!available.length) return;\n const current = selectedMenu();\n const currentIndex = Math.max(0, available.indexOf(current));\n const nextIndex = (currentIndex + delta + available.length) % available.length;\n selectedMenu.set(available[nextIndex]);\n };\n\n function selectMenu(index) {\n return function() {\n selectedMenu.set(index);\n openMenu();\n }\n }\n\n const openMenu = () => {\n const entry = menuEntries()[selectedMenu()];\n if (!entry || isMenuDisabled(entry)) return;\n if (entry.id === \"save\") {\n saveOverlay.set(true);\n return;\n }\n if (entry.id === \"exit\") {\n view.set(\"exit\");\n return;\n }\n view.set(entry.id);\n };\n\n const goBack = () => {\n delay(() => {\n view.set(\"menu\");\n });\n };\n\n const closeSaveOverlay = () => {\n delay(() => {\n saveOverlay.set(false);\n view.set(\"menu\");\n });\n };\n\n const confirmExit = () => {\n if (onInteraction) onInteraction(\"exit\");\n };\n\n const hp = getEntityProp(currentPlayer, \"hp\");\n const hpMax = getEntityProp(currentPlayer, \"params.maxHp\");\n const sp = getEntityProp(currentPlayer, \"sp\");\n const spMax = getEntityProp(currentPlayer, \"params.maxSp\");\n const level = getEntityProp(currentPlayer, \"level\");\n const exp = getEntityProp(currentPlayer, \"exp\");\n const gold = getEntityProp(currentPlayer, \"gold\");\n const expForNextlevel = computed(() => data().expForNextlevel || 0);\n const hpPercent = computed(() => {\n const max = hpMax() || 1;\n return `${Math.max(0, Math.min(100, (hp() / max) * 100))}%`;\n });\n const spPercent = computed(() => {\n const max = spMax() || 1;\n return `${Math.max(0, Math.min(100, (sp() / max) * 100))}%`;\n });\n const expPercent = computed(() => {\n const max = expForNextlevel() || 1;\n return `${Math.max(0, Math.min(100, (exp() / max) * 100))}%`;\n });\n\n const paramsList = computed(() => {\n return [\n { label: \"ATK\", value: data().playerStats.atk },\n { label: \"PDEF\", value: data().playerStats.pdef },\n { label: \"SDEF\", value: data().playerStats.sdef },\n { label: \"STR\", value: data().playerStats.str },\n { label: \"DEX\", value: data().playerStats.dex },\n { label: \"INT\", value: data().playerStats.int },\n { label: \"AGI\", value: data().playerStats.agi }\n ]\n }\n\n const menuControls = signal({\n up: {\n repeat: true,\n bind: keyboardControls.up,\n throttle: 150,\n keyDown() {\n if (saveOverlay()) return;\n if (view() !== \"menu\") return;\n moveMenu(-1);\n }\n },\n down: {\n repeat: true,\n bind: keyboardControls.down,\n throttle: 150,\n keyDown() {\n if (saveOverlay()) return;\n if (view() !== \"menu\") return;\n moveMenu(1);\n }\n },\n action: {\n bind: getKeyboardControlBind(keyboardControls.action),\n keyDown() {\n if (saveOverlay()) return;\n if (view() !== \"menu\") return;\n openMenu();\n }\n },\n escape: {\n bind: keyboardControls.escape,\n keyDown() {\n if (saveOverlay()) return;\n if (view() !== \"menu\") {\n goBack();\n return;\n }\n onFinish()\n }\n },\n gamepad: {\n enabled: true\n }\n });\n\n mount((element) => {\n engine.gamePause.set(true);\n return () => {\n delay(() => {\n engine.stopProcessingInput = false;\n engine.gamePause.set(false);\n });\n }\n });\n</script>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"main-menu.ce.js","names":[],"sources":["../../../../src/components/gui/menu/main-menu.ce"],"sourcesContent":["<DOMContainer width=\"100%\" height=\"100%\" controls={menuControls}>\n <div class=\"rpg-ui-main-menu rpg-anim-fade-in\" click={closeMenuFromPointer}>\n <div class=\"rpg-ui-main-menu-backdrop\"></div>\n <button class=\"rpg-ui-close-button\" type=\"button\" title=\"Close\" aria-label=\"Close menu\" click={closeMenuFromPointer}>x</button>\n <div class=\"rpg-ui-main-menu-layout\" click={stopEvent}>\n <div class=\"rpg-ui-main-menu-left rpg-ui-menu rpg-ui-panel\">\n <div class=\"rpg-ui-menu-header\">{t(\"rpg.menu.title\")}</div>\n <div class=\"rpg-ui-main-menu-list\">\n @for ((entry,index) of menuEntries()) {\n <div\n class=\"rpg-ui-menu-item\"\n class={{disabled: isMenuDisabled(entry)}}\n data-selected={selectedMenu() === index ? \"true\" : \"false\"}\n tabindex={index}\n click={selectMenu(index)}\n >{entry.label}</div>\n }\n </div>\n </div>\n <div class=\"rpg-ui-main-menu-right\">\n @if (view() === \"menu\") {\n <div class=\"rpg-ui-panel\">\n <div class=\"rpg-ui-main-menu-section-title\">{t(\"rpg.menu.status\")}</div>\n <div class=\"rpg-ui-main-menu-status-card\">\n <div class=\"rpg-ui-main-menu-status-block\">\n <div class=\"rpg-ui-main-menu-status-label\">{t(\"rpg.menu.level\")}</div>\n <div class=\"rpg-ui-main-menu-status-value\">{level()}</div>\n </div>\n <div class=\"rpg-ui-main-menu-status-block\">\n <div class=\"rpg-ui-main-menu-status-label\">{t(\"rpg.menu.gold\")}</div>\n <div class=\"rpg-ui-main-menu-status-value\">{gold()}</div>\n </div>\n <div class=\"rpg-ui-main-menu-status-block\">\n <div class=\"rpg-ui-main-menu-status-label\">HP {hp()}/{hpMax()}</div>\n <div class=\"rpg-ui-main-menu-status-bar\">\n <div class=\"rpg-ui-main-menu-status-bar-fill hp\" style={{width: hpPercent}}></div>\n </div>\n </div>\n <div class=\"rpg-ui-main-menu-status-block\">\n <div class=\"rpg-ui-main-menu-status-label\">SP {sp()}/{spMax()}</div>\n <div class=\"rpg-ui-main-menu-status-bar\">\n <div class=\"rpg-ui-main-menu-status-bar-fill sp\" style={{width: spPercent}}></div>\n </div>\n </div>\n <div class=\"rpg-ui-main-menu-status-block\" style={{gridColumn: \"span 2\"}}>\n <div class=\"rpg-ui-main-menu-status-label\">EXP {exp()}/{expForNextlevel()}</div>\n <div class=\"rpg-ui-main-menu-status-bar\">\n <div class=\"rpg-ui-main-menu-status-bar-fill exp\" style={{width: expPercent}}></div>\n </div>\n </div>\n </div>\n <div class=\"rpg-ui-main-menu-section-title\">{t(\"rpg.menu.parameters\")}</div>\n <div class=\"rpg-ui-main-menu-params\">\n @for ((param,index) of paramsList) {\n <div class=\"rpg-ui-main-menu-param\">\n <span>{param.label}</span>\n <span>{param.value}</span>\n </div>\n }\n </div>\n </div>\n }\n @if (view() === \"items\") {\n <ItemsMenu data={data} onInteraction={onInteraction} onBack={goBack} />\n }\n @if (view() === \"skills\") {\n <SkillsMenu data={data} onBack={goBack} />\n }\n @if (view() === \"equip\") {\n <EquipMenu data={data} onInteraction={onInteraction} onBack={goBack} />\n }\n @if (view() === \"options\") {\n <OptionsMenu onBack={goBack} />\n }\n @if (view() === \"exit\") {\n <ExitMenu onConfirm={confirmExit} onBack={goBack} />\n }\n </div>\n </div>\n @if (saveOverlay) {\n <div class=\"rpg-ui-main-menu-overlay\">\n <div class=\"rpg-ui-main-menu-overlay-backdrop\" click={closeSaveOverlayFromPointer}></div>\n <div class=\"rpg-ui-main-menu-overlay-content\" click={stopEvent}>\n <SaveLoadComponent\n data={saveLoadData}\n onFinish={closeSaveOverlay}\n />\n </div>\n </div>\n }\n </div>\n</DOMContainer>\n\n<script>\n import { signal, computed, effect, mount } from \"canvasengine\";\n import { inject } from \"../../../core/inject\";\n import { RpgClientEngine } from \"../../../RpgClientEngine\";\n import SaveLoadComponent from \"../save-load.ce\";\n import ItemsMenu from \"./items-menu.ce\";\n import SkillsMenu from \"./skills-menu.ce\";\n import EquipMenu from \"./equip-menu.ce\";\n import OptionsMenu from \"./options-menu.ce\";\n import ExitMenu from \"./exit-menu.ce\";\n import { getEntityProp } from \"../../../utils/getEntityProp\";\n import { delay } from \"@rpgjs/common\";\n import { getKeyboardControlBind } from \"../../../services/actionInput\";\n\n const engine = inject(RpgClientEngine);\n const { t } = engine.i18n();\n const currentPlayer = engine.scene.currentPlayer;\n const keyboardControls = engine.globalConfig.keyboardControls;\n\n const { data, onFinish, onInteraction } = defineProps();\n const { menus, items, skills, equips, saveLoad } = data();\n\n const defaultMenus = [\n { id: \"items\", label: t(\"rpg.menu.items\") },\n { id: \"skills\", label: t(\"rpg.menu.skills\") },\n { id: \"equip\", label: t(\"rpg.menu.equip\") },\n { id: \"options\", label: t(\"rpg.menu.options\") },\n { id: \"save\", label: t(\"rpg.menu.save\") },\n { id: \"exit\", label: t(\"rpg.menu.exit\") }\n ];\n\n const menuEntries = computed(() => {\n if (menus && Array.isArray(menus) && menus.length) return menus;\n return defaultMenus;\n });\n\n const resolveProp = (value) => typeof value === \"function\" ? value() : value;\n const saveLoadData = computed(() => resolveProp(saveLoad) || {});\n const saveLoadMode = computed(() => saveLoadData().mode || \"load\");\n const saveLoadSlots = computed(() => saveLoadData().slots || []);\n const saveLoadCanSave = computed(() => saveLoadData().canSave !== false);\n\n const isMenuDisabled = (entry) => {\n if (!entry) return true;\n if (entry.disabled) return true;\n if (entry.enabled === false) return true;\n if (entry.id === \"save\" && !saveLoadCanSave()) return true;\n return false;\n };\n\n const selectedMenu = signal(0);\n const view = signal(\"menu\");\n const saveOverlay = signal(false);\n\n const selectableIndexes = computed(() => {\n const entries = menuEntries();\n return entries\n .map((entry, index) => (isMenuDisabled(entry) ? null : index))\n .filter((value) => value !== null);\n });\n\n effect(() => {\n const available = selectableIndexes();\n if (!available.length) return;\n const current = selectedMenu();\n if (!available.includes(current)) {\n selectedMenu.set(available[0]);\n }\n });\n\n const moveMenu = (delta) => {\n const available = selectableIndexes();\n if (!available.length) return;\n const current = selectedMenu();\n const currentIndex = Math.max(0, available.indexOf(current));\n const nextIndex = (currentIndex + delta + available.length) % available.length;\n selectedMenu.set(available[nextIndex]);\n };\n\n function selectMenu(index) {\n return function() {\n selectedMenu.set(index);\n openMenu();\n }\n }\n\n const openMenu = () => {\n const entry = menuEntries()[selectedMenu()];\n if (!entry || isMenuDisabled(entry)) return;\n if (entry.id === \"save\") {\n saveOverlay.set(true);\n return;\n }\n if (entry.id === \"exit\") {\n view.set(\"exit\");\n return;\n }\n view.set(entry.id);\n };\n\n const goBack = () => {\n delay(() => {\n view.set(\"menu\");\n });\n };\n\n const closeSaveOverlay = () => {\n delay(() => {\n saveOverlay.set(false);\n view.set(\"menu\");\n });\n };\n\n const stopEvent = (event) => {\n event?.stopPropagation?.();\n };\n\n const closeSaveOverlayFromPointer = (event) => {\n stopEvent(event);\n closeSaveOverlay();\n };\n\n const closeMenu = () => {\n if (saveOverlay()) {\n closeSaveOverlay();\n return;\n }\n onFinish();\n };\n\n const closeMenuFromPointer = (event) => {\n stopEvent(event);\n closeMenu();\n };\n\n const confirmExit = () => {\n if (onInteraction) onInteraction(\"exit\");\n };\n\n const hp = getEntityProp(currentPlayer, \"hp\");\n const hpMax = getEntityProp(currentPlayer, \"params.maxHp\");\n const sp = getEntityProp(currentPlayer, \"sp\");\n const spMax = getEntityProp(currentPlayer, \"params.maxSp\");\n const level = getEntityProp(currentPlayer, \"level\");\n const exp = getEntityProp(currentPlayer, \"exp\");\n const gold = getEntityProp(currentPlayer, \"gold\");\n const expForNextlevel = computed(() => data().expForNextlevel || 0);\n const hpPercent = computed(() => {\n const max = hpMax() || 1;\n return `${Math.max(0, Math.min(100, (hp() / max) * 100))}%`;\n });\n const spPercent = computed(() => {\n const max = spMax() || 1;\n return `${Math.max(0, Math.min(100, (sp() / max) * 100))}%`;\n });\n const expPercent = computed(() => {\n const max = expForNextlevel() || 1;\n return `${Math.max(0, Math.min(100, (exp() / max) * 100))}%`;\n });\n\n const paramsList = computed(() => {\n return [\n { label: \"ATK\", value: data().playerStats.atk },\n { label: \"PDEF\", value: data().playerStats.pdef },\n { label: \"SDEF\", value: data().playerStats.sdef },\n { label: \"STR\", value: data().playerStats.str },\n { label: \"DEX\", value: data().playerStats.dex },\n { label: \"INT\", value: data().playerStats.int },\n { label: \"AGI\", value: data().playerStats.agi }\n ]\n }\n\n const menuControls = signal({\n up: {\n repeat: true,\n bind: keyboardControls.up,\n throttle: 150,\n keyDown() {\n if (saveOverlay()) return;\n if (view() !== \"menu\") return;\n moveMenu(-1);\n }\n },\n down: {\n repeat: true,\n bind: keyboardControls.down,\n throttle: 150,\n keyDown() {\n if (saveOverlay()) return;\n if (view() !== \"menu\") return;\n moveMenu(1);\n }\n },\n action: {\n bind: getKeyboardControlBind(keyboardControls.action),\n keyDown() {\n if (saveOverlay()) return;\n if (view() !== \"menu\") return;\n openMenu();\n }\n },\n escape: {\n bind: keyboardControls.escape,\n keyDown() {\n if (saveOverlay()) return;\n if (view() !== \"menu\") {\n goBack();\n return;\n }\n onFinish()\n }\n },\n gamepad: {\n enabled: true\n }\n });\n\n mount((element) => {\n const inputLockToken = {};\n const previousStopProcessingInput = engine.stopProcessingInput;\n const previousGamePause = engine.gamePause();\n engine.__rpgMainMenuInputLock = inputLockToken;\n engine.stopProcessingInput = true;\n engine.gamePause.set(true);\n return () => {\n delay(() => {\n if (engine.__rpgMainMenuInputLock !== inputLockToken) return;\n engine.__rpgMainMenuInputLock = undefined;\n engine.stopProcessingInput = previousStopProcessingInput;\n engine.gamePause.set(previousGamePause);\n });\n }\n });\n</script>\n"],"mappings":"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"}
|
|
@@ -107,6 +107,17 @@ function component($$props) {
|
|
|
107
107
|
triggerSelect(index);
|
|
108
108
|
};
|
|
109
109
|
}
|
|
110
|
+
const stopEvent = (event) => {
|
|
111
|
+
event?.stopPropagation?.();
|
|
112
|
+
};
|
|
113
|
+
const closeSaveLoad = () => {
|
|
114
|
+
if (onFinish) onFinish();
|
|
115
|
+
gui.hide(PrebuiltGui.Save);
|
|
116
|
+
};
|
|
117
|
+
const closeSaveLoadFromPointer = (event) => {
|
|
118
|
+
stopEvent(event);
|
|
119
|
+
closeSaveLoad();
|
|
120
|
+
};
|
|
110
121
|
const controls = signal({
|
|
111
122
|
up: {
|
|
112
123
|
repeat: true,
|
|
@@ -133,8 +144,7 @@ function component($$props) {
|
|
|
133
144
|
escape: {
|
|
134
145
|
bind: keyboardControls.escape,
|
|
135
146
|
keyDown() {
|
|
136
|
-
|
|
137
|
-
gui.hide(PrebuiltGui.Save);
|
|
147
|
+
closeSaveLoad();
|
|
138
148
|
}
|
|
139
149
|
},
|
|
140
150
|
gamepad: { enabled: true }
|
|
@@ -147,7 +157,26 @@ function component($$props) {
|
|
|
147
157
|
height: "100%"
|
|
148
158
|
}, h(DOMElement, {
|
|
149
159
|
element: "div",
|
|
150
|
-
attrs: {
|
|
160
|
+
attrs: {
|
|
161
|
+
class: "rpg-ui-save-load-layer",
|
|
162
|
+
click: closeSaveLoadFromPointer
|
|
163
|
+
}
|
|
164
|
+
}, [h(DOMElement, {
|
|
165
|
+
element: "button",
|
|
166
|
+
attrs: {
|
|
167
|
+
class: "rpg-ui-close-button",
|
|
168
|
+
type: "button",
|
|
169
|
+
title: "Close",
|
|
170
|
+
"aria-label": "Close save menu",
|
|
171
|
+
click: closeSaveLoadFromPointer
|
|
172
|
+
},
|
|
173
|
+
textContent: "x"
|
|
174
|
+
}), h(DOMElement, {
|
|
175
|
+
element: "div",
|
|
176
|
+
attrs: {
|
|
177
|
+
class: "rpg-ui-save-load rpg-anim-fade-in",
|
|
178
|
+
click: stopEvent
|
|
179
|
+
}
|
|
151
180
|
}, [h(DOMElement, {
|
|
152
181
|
element: "div",
|
|
153
182
|
attrs: { class: "rpg-ui-save-load-header" }
|
|
@@ -205,7 +234,7 @@ function component($$props) {
|
|
|
205
234
|
element: "div",
|
|
206
235
|
attrs: { class: "rpg-ui-save-load-slot-empty" },
|
|
207
236
|
textContent: computed(() => t("rpg.save.empty-slot"))
|
|
208
|
-
}))]))))]));
|
|
237
|
+
}))]))))])]));
|
|
209
238
|
}
|
|
210
239
|
var __ce_component = component;
|
|
211
240
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"save-load.ce.js","names":[],"sources":["../../../src/components/gui/save-load.ce"],"sourcesContent":["<DOMContainer width=\"100%\" height=\"100%\">\n <div class=\"rpg-ui-save-load rpg-anim-fade-in\">\n <div class=\"rpg-ui-save-load-header\">\n <div class=\"rpg-ui-save-load-title\">{title()}</div>\n <div class=\"rpg-ui-save-load-subtitle\">{subtitle()}</div>\n </div>\n <Navigation tabindex={selectedSlot} controls={controls}>\n <div class=\"rpg-ui-save-load-list\">\n @for ((item,displayIndex) of displaySlots) {\n <div\n class=\"rpg-ui-save-load-slot\"\n class={{active: selectedSlot() === displayIndex}}\n tabindex={displayIndex}\n data-slot-index={displayIndex}\n click={selectSlot(displayIndex)}\n >\n <div class=\"rpg-ui-save-load-slot-index\">{item.label}</div>\n @if (item.slot) {\n <div class=\"rpg-ui-save-load-slot-meta\">\n <div class=\"rpg-ui-save-load-slot-line\">{t(\"rpg.save.level\")}: {item.slot.level ?? \"-\"}</div>\n <div class=\"rpg-ui-save-load-slot-line\">{t(\"rpg.save.exp\")}: {item.slot.exp ?? \"-\"}</div>\n <div class=\"rpg-ui-save-load-slot-line\">{t(\"rpg.save.map\")}: {item.slot.map ?? \"-\"}</div>\n <div class=\"rpg-ui-save-load-slot-line\">{t(\"rpg.save.date\")}: {item.slot.date ?? \"-\"}</div>\n </div>\n }\n @else {\n <div class=\"rpg-ui-save-load-slot-empty\">{t(\"rpg.save.empty-slot\")}</div>\n }\n </div>\n }\n </div>\n </Navigation>\n </div>\n</DOMContainer>\n\n<script>\n import { signal, computed, effect, createTabindexNavigator, mount } from \"canvasengine\";\n import { inject } from \"../../core/inject\";\n import { RpgClientEngine } from \"../../RpgClientEngine\";\n import { SaveClientService } from \"../../services/save\";\n import { PrebuiltGui } from \"@rpgjs/common\";\n import { RpgGui } from \"../../Gui/Gui\";\n import { getKeyboardControlBind } from \"../../services/actionInput\";\n\n const engine = inject(RpgClientEngine);\n const { t } = engine.i18n();\n const saveClient = inject(SaveClientService);\n const gui = inject(RpgGui);\n const keyboardControls = engine.globalConfig.keyboardControls;\n\n const selectedSlot = signal(0);\n const DEFAULT_SLOTS = 4;\n const defaultSlots = () => Array.from({ length: DEFAULT_SLOTS }, () => null);\n const localSlots = signal(defaultSlots());\n\n const { data, onFinish } = defineProps();\n\n const title = computed(() => data().mode === \"save\" ? t(\"rpg.save.title\") : t(\"rpg.load.title\"));\n const subtitle = computed(() => data().mode === \"save\"\n ? t(\"rpg.save.subtitle\")\n : t(\"rpg.load.subtitle\")\n );\n\n const slotsValue = computed(() => localSlots());\n const displaySlots = computed(() => {\n const slots = slotsValue();\n const items = slots.map((slot, index) => ({\n kind: \"slot\",\n slot,\n slotIndex: index,\n label: t(\"rpg.save.slot\", { index: index + 1 }),\n readonly: false\n }));\n if (!data().showAutoSlot) return items;\n const index = typeof data().autoSlotIndex === \"number\" ? data().autoSlotIndex : 0;\n const autoSlot = slots[index] ?? null;\n const readonly = data().mode === \"save\";\n return [\n {\n kind: \"auto\",\n slot: autoSlot,\n slotIndex: index,\n label: data().autoSlotLabel || t(\"rpg.save.auto\"),\n readonly\n },\n ...items\n ];\n });\n const nav = createTabindexNavigator(selectedSlot, { count: () => displaySlots().length }, \"wrap\");\n\n const canSelect = (item) => {\n if (item.readonly) return false;\n if (data().mode === \"load\" && !item.slot) return false;\n return true;\n };\n\n const normalizeSlotValue = (value) => {\n if (!value) return null;\n if (typeof value === \"string\") {\n try {\n return JSON.parse(value);\n } catch {\n return null;\n }\n }\n return value;\n };\n\n const normalizeSlots = (list) => {\n if (Array.isArray(list)) {\n const length = Math.max(list.length, DEFAULT_SLOTS);\n return Array.from({ length }, (_, index) => normalizeSlotValue(list[index]));\n }\n if (!list || typeof list !== \"object\") {\n return defaultSlots();\n }\n const keys = Object.keys(list).filter((key) => /^\\d+$/.test(key));\n const indices = keys.map((key) => Number(key)).filter((index) => index >= 0);\n const maxIndex = indices.length ? Math.max(...indices) : -1;\n const length = Math.max(maxIndex + 1, DEFAULT_SLOTS);\n const slots = Array.from({ length }, () => null);\n keys.forEach((key) => {\n const index = Number(key);\n if (index < 0 || index >= length) return;\n slots[index] = normalizeSlotValue(list[key]);\n });\n return slots;\n };\n\n const hasProvidedSlots = (list) => {\n if (Array.isArray(list)) return list.length > 0;\n return !!(list && typeof list === \"object\" && Object.keys(list).length > 0);\n };\n\n const refreshSlots = async () => {\n try {\n const list = await saveClient.listSlots();\n localSlots.set(normalizeSlots(list));\n } catch (err) {\n localSlots.set(defaultSlots());\n }\n };\n\n const triggerSelect = async (displayIndex) => {\n const list = displaySlots();\n const item = list[displayIndex];\n if (!item) return;\n if (!canSelect(item)) return;\n const action = data().mode === \"save\" ? \"save\" : \"load\";\n if (action === \"save\") {\n await saveClient.saveSlot(item.slotIndex);\n await refreshSlots();\n }\n if (action === \"load\") {\n await saveClient.loadSlot(item.slotIndex);\n }\n setTimeout(() => {\n if (onFinish) onFinish();\n gui.hide(PrebuiltGui.Save);\n gui.hide(PrebuiltGui.TitleScreen);\n }, 50);\n\n };\n\n function selectSlot(index) {\n return function() {\n selectedSlot.set(index);\n triggerSelect(index);\n }\n }\n\n const controls = signal({\n up: {\n repeat: true,\n bind: keyboardControls.up,\n throttle: 150,\n keyDown() {\n nav.next(-1);\n }\n },\n down: {\n repeat: true,\n bind: keyboardControls.down,\n throttle: 150,\n keyDown() {\n nav.next(1);\n }\n },\n action: {\n bind: getKeyboardControlBind(keyboardControls.action),\n keyDown() {\n triggerSelect(selectedSlot());\n }\n },\n escape: {\n bind: keyboardControls.escape,\n keyDown() {\n if (onFinish) onFinish();\n gui.hide(PrebuiltGui.Save);\n }\n },\n gamepad: {\n enabled: true\n }\n });\n\n mount((element) => {\n refreshSlots();\n });\n</script>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"save-load.ce.js","names":[],"sources":["../../../src/components/gui/save-load.ce"],"sourcesContent":["<DOMContainer width=\"100%\" height=\"100%\">\n <div class=\"rpg-ui-save-load-layer\" click={closeSaveLoadFromPointer}>\n <button class=\"rpg-ui-close-button\" type=\"button\" title=\"Close\" aria-label=\"Close save menu\" click={closeSaveLoadFromPointer}>x</button>\n <div class=\"rpg-ui-save-load rpg-anim-fade-in\" click={stopEvent}>\n <div class=\"rpg-ui-save-load-header\">\n <div class=\"rpg-ui-save-load-title\">{title()}</div>\n <div class=\"rpg-ui-save-load-subtitle\">{subtitle()}</div>\n </div>\n <Navigation tabindex={selectedSlot} controls={controls}>\n <div class=\"rpg-ui-save-load-list\">\n @for ((item,displayIndex) of displaySlots) {\n <div\n class=\"rpg-ui-save-load-slot\"\n class={{active: selectedSlot() === displayIndex}}\n tabindex={displayIndex}\n data-slot-index={displayIndex}\n click={selectSlot(displayIndex)}\n >\n <div class=\"rpg-ui-save-load-slot-index\">{item.label}</div>\n @if (item.slot) {\n <div class=\"rpg-ui-save-load-slot-meta\">\n <div class=\"rpg-ui-save-load-slot-line\">{t(\"rpg.save.level\")}: {item.slot.level ?? \"-\"}</div>\n <div class=\"rpg-ui-save-load-slot-line\">{t(\"rpg.save.exp\")}: {item.slot.exp ?? \"-\"}</div>\n <div class=\"rpg-ui-save-load-slot-line\">{t(\"rpg.save.map\")}: {item.slot.map ?? \"-\"}</div>\n <div class=\"rpg-ui-save-load-slot-line\">{t(\"rpg.save.date\")}: {item.slot.date ?? \"-\"}</div>\n </div>\n }\n @else {\n <div class=\"rpg-ui-save-load-slot-empty\">{t(\"rpg.save.empty-slot\")}</div>\n }\n </div>\n }\n </div>\n </Navigation>\n </div>\n </div>\n</DOMContainer>\n\n<script>\n import { signal, computed, effect, createTabindexNavigator, mount } from \"canvasengine\";\n import { inject } from \"../../core/inject\";\n import { RpgClientEngine } from \"../../RpgClientEngine\";\n import { SaveClientService } from \"../../services/save\";\n import { PrebuiltGui } from \"@rpgjs/common\";\n import { RpgGui } from \"../../Gui/Gui\";\n import { getKeyboardControlBind } from \"../../services/actionInput\";\n\n const engine = inject(RpgClientEngine);\n const { t } = engine.i18n();\n const saveClient = inject(SaveClientService);\n const gui = inject(RpgGui);\n const keyboardControls = engine.globalConfig.keyboardControls;\n\n const selectedSlot = signal(0);\n const DEFAULT_SLOTS = 4;\n const defaultSlots = () => Array.from({ length: DEFAULT_SLOTS }, () => null);\n const localSlots = signal(defaultSlots());\n\n const { data, onFinish } = defineProps();\n\n const title = computed(() => data().mode === \"save\" ? t(\"rpg.save.title\") : t(\"rpg.load.title\"));\n const subtitle = computed(() => data().mode === \"save\"\n ? t(\"rpg.save.subtitle\")\n : t(\"rpg.load.subtitle\")\n );\n\n const slotsValue = computed(() => localSlots());\n const displaySlots = computed(() => {\n const slots = slotsValue();\n const items = slots.map((slot, index) => ({\n kind: \"slot\",\n slot,\n slotIndex: index,\n label: t(\"rpg.save.slot\", { index: index + 1 }),\n readonly: false\n }));\n if (!data().showAutoSlot) return items;\n const index = typeof data().autoSlotIndex === \"number\" ? data().autoSlotIndex : 0;\n const autoSlot = slots[index] ?? null;\n const readonly = data().mode === \"save\";\n return [\n {\n kind: \"auto\",\n slot: autoSlot,\n slotIndex: index,\n label: data().autoSlotLabel || t(\"rpg.save.auto\"),\n readonly\n },\n ...items\n ];\n });\n const nav = createTabindexNavigator(selectedSlot, { count: () => displaySlots().length }, \"wrap\");\n\n const canSelect = (item) => {\n if (item.readonly) return false;\n if (data().mode === \"load\" && !item.slot) return false;\n return true;\n };\n\n const normalizeSlotValue = (value) => {\n if (!value) return null;\n if (typeof value === \"string\") {\n try {\n return JSON.parse(value);\n } catch {\n return null;\n }\n }\n return value;\n };\n\n const normalizeSlots = (list) => {\n if (Array.isArray(list)) {\n const length = Math.max(list.length, DEFAULT_SLOTS);\n return Array.from({ length }, (_, index) => normalizeSlotValue(list[index]));\n }\n if (!list || typeof list !== \"object\") {\n return defaultSlots();\n }\n const keys = Object.keys(list).filter((key) => /^\\d+$/.test(key));\n const indices = keys.map((key) => Number(key)).filter((index) => index >= 0);\n const maxIndex = indices.length ? Math.max(...indices) : -1;\n const length = Math.max(maxIndex + 1, DEFAULT_SLOTS);\n const slots = Array.from({ length }, () => null);\n keys.forEach((key) => {\n const index = Number(key);\n if (index < 0 || index >= length) return;\n slots[index] = normalizeSlotValue(list[key]);\n });\n return slots;\n };\n\n const hasProvidedSlots = (list) => {\n if (Array.isArray(list)) return list.length > 0;\n return !!(list && typeof list === \"object\" && Object.keys(list).length > 0);\n };\n\n const refreshSlots = async () => {\n try {\n const list = await saveClient.listSlots();\n localSlots.set(normalizeSlots(list));\n } catch (err) {\n localSlots.set(defaultSlots());\n }\n };\n\n const triggerSelect = async (displayIndex) => {\n const list = displaySlots();\n const item = list[displayIndex];\n if (!item) return;\n if (!canSelect(item)) return;\n const action = data().mode === \"save\" ? \"save\" : \"load\";\n if (action === \"save\") {\n await saveClient.saveSlot(item.slotIndex);\n await refreshSlots();\n }\n if (action === \"load\") {\n await saveClient.loadSlot(item.slotIndex);\n }\n setTimeout(() => {\n if (onFinish) onFinish();\n gui.hide(PrebuiltGui.Save);\n gui.hide(PrebuiltGui.TitleScreen);\n }, 50);\n\n };\n\n function selectSlot(index) {\n return function() {\n selectedSlot.set(index);\n triggerSelect(index);\n }\n }\n\n const stopEvent = (event) => {\n event?.stopPropagation?.();\n };\n\n const closeSaveLoad = () => {\n if (onFinish) onFinish();\n gui.hide(PrebuiltGui.Save);\n };\n\n const closeSaveLoadFromPointer = (event) => {\n stopEvent(event);\n closeSaveLoad();\n };\n\n const controls = signal({\n up: {\n repeat: true,\n bind: keyboardControls.up,\n throttle: 150,\n keyDown() {\n nav.next(-1);\n }\n },\n down: {\n repeat: true,\n bind: keyboardControls.down,\n throttle: 150,\n keyDown() {\n nav.next(1);\n }\n },\n action: {\n bind: getKeyboardControlBind(keyboardControls.action),\n keyDown() {\n triggerSelect(selectedSlot());\n }\n },\n escape: {\n bind: keyboardControls.escape,\n keyDown() {\n closeSaveLoad();\n }\n },\n gamepad: {\n enabled: true\n }\n });\n\n mount((element) => {\n refreshSlots();\n });\n</script>\n"],"mappings":"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"}
|