@rpgjs/client 5.0.0-beta.23 → 5.0.0-beta.24
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 +13 -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/components/character.ce.js +9 -2
- package/dist/components/character.ce.js.map +1 -1
- package/dist/components/gui/dialogbox/index.ce.js +31 -2
- 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/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/package.json +4 -4
- package/src/Game/Object.spec.ts +26 -2
- package/src/Game/Object.ts +71 -2
- package/src/components/character.ce +12 -6
- package/src/components/gui/dialogbox/index.ce +56 -40
- package/src/components/gui/hud/hud.ce +2 -2
- 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
|
@@ -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":";;;;;;;;AAcM,SAAS,UAAS,SAAO;CACX,SAAA,OAAA;CACZ,MAAM,cAAc,eAAe,OAAK;CACpB,eAAY,OAAA;CAChC,MAAM,SAAS,OAAM,eAAe;CAC5C,MAAM,EAAE,MAAM,OAAO,KAAK;CAC1B,MAAM,aAAa,OAAO,iBAAiB;CAC3C,MAAM,MAAM,OAAO,MAAM;CACzB,MAAM,mBAAmB,OAAO,aAAY;CAC5C,MAAM,eAAe,OAAO,CAAC;CAC7B,MAAM,gBAAgB;CACtB,MAAM,qBAAmB,MAAK,KAAA,EAAA,QAAA,cAAA,SAAA,IAAA;CAC9B,MAAM,aAAa,OAAO,aAAa,CAAC;CACxC,MAAM,EAAE,MAAM,aAAU,YAAA;CACxB,MAAM,QAAQ,eAAW,KAAA,EAAA,SAAA,SAAA,EAAA,gBAAA,IAAA,EAAA,gBAAA,CAAA;CACzB,MAAM,WAAU,eAAA,KAAA,EAAA,SAAA,SACV,EAAE,mBAAS,IACX,EAAE,mBAAY,CAAA;CACpB,MAAM,aAAG,eAAA,WAAA,CAAA;CACT,MAAE,eAAY,eAAA;;EAEb,MAAM,QAAA,MAAA,KAAA,MAAA,WAAA;GACH,MAAS;GACT;GACA,WAAS;GACT,OAAS,EAAA,iBAAoB,EAAA,OAAU,QAAE,EAAQ,CAAC;GAClD,UAAS;EACT,EAAA;EACA,IAAA,CAAA,KAAS,EAAA,cAAA,OAAA;EAET,MAAM,QAAQ,OAAO,KAAC,EAAA,kBAAgB,WAAA,KAAA,EAAA,gBAAA;EACtC,MAAM,WAAQ,MAAO,UAAM;EAC3B,MAAM,WAAW,KAAE,EAAA,SAAO;EAC1B,OAAM,CACN;;GAEM,MAAA;GACA,WAAa;GACb,OAAA,KAAc,EAAE,iBAAiB,EAAC,eAAQ;GAC1C;KAEN,GAAO,KAAA;CAEX,CAAC;CACD,MAAI,MAAM,wBAA0B,cAAc,EAAE,aAAK,aAAA,EAAA,OAAA,GAAA,MAAA;CACzD,MAAM,aAAW,SAAK;EAClB,IAAI,KAAK,UACR,OAAA;4CAED,OAAM;EACN,OAAM;CACV;CACA,MAAM,sBAAsB,UAAU;EAClC,IAAI,CAAC,OACD,OAAI;EACR,IAAI,OAAI,UAAW,UACf,IAAI;GACA,OAAA,KAAU,MAAA,KAAA;EACd,QACK;GACL,OAAW;EACX;EAEJ,OAAI;CACR;CACA,MAAM,kBAAiB,SAAK;EACxB,IAAI,MAAM,QAAQ,IAAA,GAAA;GACd,MAAM,SAAE,KAAW,IAAK,KAAA,QAAA,aAAA;GACxB,OAAO,MAAM,KAAE,EAAK,OAAE,IAAA,GAAA,UAAoB,mBAAe,KAAA,MAAA,CAAA;EAC7D;EACA,IAAI,CAAC,QAAI,OAAA,SAAA,UACL,OAAO,aAAA;EAEX,MAAE,OAAA,OAAA,KAAA,IAAA,EAAA,QAAA,QAAA,QAAA,KAAA,GAAA,CAAA;EACF,MAAM,UAAM,KAAA,KAAA,QAAA,OAAwB,GAAA,CAAA,EAAA,QAAgB,UAAa,SAAA,CAAA;;EAEjE,MAAM,SAAS,KAAI,IAAK,WAAI,GAAA,aAAA;EAC5B,MAAM,QAAO,MAAA,KAAU,EAAA,OAAO,SAAK,IAAA;EACnC,KAAI,SAAU,QAAQ;GAClB,MAAM,QAAK,OAAA,GAAA;GACd,IAAA,QAAA,KAAA,SAAA,QAAA;GAED,MAAM,SAAA,mBAAgC,KAAA,IAAA;EACtC,CAAC;EACD,OAAO;CACX;CAMA,MAAM,eAAc,YAAA;EAChB,IAAC;;GAED,WAAM,IAAA,eAA2B,IAAA,CAAA;EACjC,SACO,KAAC;GACJ,WAAW,IAAA,aAAa,CAAA;EAC5B;CACJ;CACA,MAAM,gBAAa,OAAA,iBAAc;EAE7B,MAAI,OADA,aACY,EAAC;EACjB,IAAI,CAAA,MACA;EACJ,IAAI,CAAA,UAAM,IAAS,GACf;EACJ,MAAI,SAAK,KAAS,EAAI,SAAI,SAAA,SAAA;EAC1B,IAAI,WAAU,QAAQ;GAClB,MAAM,WAAW,SAAS,KAAI,SAAQ;GACtC,MAAI,aAAe;EACvB;EACA,IAAI,WAAO,QACV,MAAA,WAAA,SAAA,KAAA,SAAA;EAED,iBAAM;GACF,IAAI,UACJ,SAAU;GACb,IAAA,KAAA,YAAA,IAAA;;EAED,GAAA,EAAK;CACT;CACA,SAAS,WAAS,OAAO;EACrB,OAAO,WAAY;GACf,aAAa,IAAC,KAAA;GACd,cAAc,KAAK;EACvB;CACJ;;EAEI,IAAA;GACI,QAAM;GACN,MAAM,iBAAY;GAClB,UAAU;GACV,UAAK;IACL,IAAM,KAAO,EAAE;GACf;EACJ;EACA,MAAM;GACF,QAAA;GACA,MAAI,iBAAmB;GACvB,UAAU;GACV,UAAA;IACA,IAAA,KAAa,CAAC;GACd;EACJ;EACA,QAAQ;GACJ,MAAM,uBAAA,iBAAA,MAAA;;IAET,cAAA,aAAA,CAAA;;EAED;EACA,QAAI;GACA,MAAI,iBAAiB;GACrB,UAAI;IACJ,IAAA,UACJ,SAAA;;GAEA;EACA;EACA,SAAQ,EACJ,SAAS,KACb;CACJ,CAAC;CACD,OAAO,YAAY;EACf,aAAQ;CACZ,CAAC;CAEO,OADM,EAAA,cAAA;EAAA,OAAA;EAAA,QAAA;CAAA,GAAA,EAAA,YAAA;EAAA,SAAA;EAAA,OAAA,EAAA,OAAA,oCAAA;CAAA,GAAA,CAAA,EAAA,YAAA;EAAA,SAAA;EAAA,OAAA,EAAA,OAAA,0BAAA;CAAA,GAAA,CAAA,EAAA,YAAA;EAAA,SAAA;EAAA,OAAA,EAAA,OAAA,yBAAA;EAAA,aAAA,eAAA,MAAA,CAAA;CAAA,CAAA,GAAA,EAAA,YAAA;EAAA,SAAA;EAAA,OAAA,EAAA,OAAA,4BAAA;EAAA,aAAA,eAAA,SAAA,CAAA;CAAA,CAAA,CAAA,CAAA,GAAA,EAAA,YAAA;EAAA,UAAA;EAAA;CAAA,GAAA,EAAA,YAAA;EAAA,SAAA;EAAA,OAAA,EAAA,OAAA,wBAAA;CAAA,GAAA,KAAA,eAAA,MAAA,iBAAA,EAAA,YAAA;EAAA,SAAA;EAAA,OAAA;GAAA,OAAA,CAAA,yBAAA,gBAAA,EAAA,QAAA,aAAA,MAAA,aAAA,EAAA,CAAA;GAAA,UAAA;GAAA,mBAAA;GAAA,OAAA,WAAA,YAAA;EAAA;CAAA,GAAA,CAAA,EAAA,YAAA;EAAA,SAAA;EAAA,OAAA,EAAA,OAAA,8BAAA;EAAA,aAAA,KAAA;CAAA,CAAA,GAAA,KAAA,KAAA,YAAA,EAAA,YAAA;EAAA,SAAA;EAAA,OAAA,EAAA,OAAA,6BAAA;CAAA,GAAA;EAAA,EAAA,YAAA;GAAA,SAAA;GAAA,OAAA,EAAA,OAAA,6BAAA;GAAA,aAAA,EAAA,gBAAA,IAAA,OAAA,KAAA,KAAA;EAAA,CAAA;EAAA,EAAA,YAAA;GAAA,SAAA;GAAA,OAAA,EAAA,OAAA,6BAAA;GAAA,aAAA,EAAA,cAAA,IAAA,OAAA,KAAA,KAAA;EAAA,CAAA;EAAA,EAAA,YAAA;GAAA,SAAA;GAAA,OAAA,EAAA,OAAA,6BAAA;GAAA,aAAA,EAAA,cAAA,IAAA,OAAA,KAAA,KAAA;EAAA,CAAA;EAAA,EAAA,YAAA;GAAA,SAAA;GAAA,OAAA,EAAA,OAAA,6BAAA;GAAA,aAAA,EAAA,eAAA,IAAA,OAAA,KAAA,KAAA;EAAA,CAAA;CAAA,CAAA,SAAA,EAAA,YAAA;EAAA,SAAA;EAAA,OAAA,EAAA,OAAA,8BAAA;EAAA,aAAA,eAAA,EAAA,qBAAA,CAAA;CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CACK;AACb;AAEA,IAAM,iBAAU"}
|
|
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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"}
|
|
@@ -177,6 +177,24 @@ function component($$props) {
|
|
|
177
177
|
quantityDialogOpen.set(false);
|
|
178
178
|
};
|
|
179
179
|
}
|
|
180
|
+
const stopEvent = (event) => {
|
|
181
|
+
event?.stopPropagation?.();
|
|
182
|
+
};
|
|
183
|
+
const closeQuantityDialogFromPointer = (event) => {
|
|
184
|
+
stopEvent(event);
|
|
185
|
+
quantityDialogOpen.set(false);
|
|
186
|
+
};
|
|
187
|
+
const closeShop = () => {
|
|
188
|
+
if (quantityDialogOpen()) {
|
|
189
|
+
quantityDialogOpen.set(false);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
onFinish();
|
|
193
|
+
};
|
|
194
|
+
const closeShopFromPointer = (event) => {
|
|
195
|
+
stopEvent(event);
|
|
196
|
+
closeShop();
|
|
197
|
+
};
|
|
180
198
|
function confirmTrade() {
|
|
181
199
|
return function() {
|
|
182
200
|
const item = currentItem();
|
|
@@ -312,7 +330,26 @@ function component($$props) {
|
|
|
312
330
|
height: "100%"
|
|
313
331
|
}, h(DOMElement, {
|
|
314
332
|
element: "div",
|
|
315
|
-
attrs: {
|
|
333
|
+
attrs: {
|
|
334
|
+
class: "rpg-shop-layer",
|
|
335
|
+
click: closeShopFromPointer
|
|
336
|
+
}
|
|
337
|
+
}, [h(DOMElement, {
|
|
338
|
+
element: "button",
|
|
339
|
+
attrs: {
|
|
340
|
+
class: "rpg-ui-close-button",
|
|
341
|
+
type: "button",
|
|
342
|
+
title: "Close",
|
|
343
|
+
"aria-label": "Close shop",
|
|
344
|
+
click: closeShopFromPointer
|
|
345
|
+
},
|
|
346
|
+
textContent: "x"
|
|
347
|
+
}), h(DOMElement, {
|
|
348
|
+
element: "div",
|
|
349
|
+
attrs: {
|
|
350
|
+
class: "rpg-shop-container rpg-anim-fade-in",
|
|
351
|
+
click: stopEvent
|
|
352
|
+
}
|
|
316
353
|
}, [h(DOMElement, {
|
|
317
354
|
element: "div",
|
|
318
355
|
attrs: { class: "rpg-shop-header" }
|
|
@@ -527,10 +564,16 @@ function component($$props) {
|
|
|
527
564
|
})
|
|
528
565
|
])])])), cond(quantityDialogOpen, () => h(DOMElement, {
|
|
529
566
|
element: "div",
|
|
530
|
-
attrs: {
|
|
567
|
+
attrs: {
|
|
568
|
+
class: "rpg-shop-modal",
|
|
569
|
+
click: closeQuantityDialogFromPointer
|
|
570
|
+
}
|
|
531
571
|
}, h(DOMElement, {
|
|
532
572
|
element: "div",
|
|
533
|
-
attrs: {
|
|
573
|
+
attrs: {
|
|
574
|
+
class: "rpg-shop-modal-card",
|
|
575
|
+
click: stopEvent
|
|
576
|
+
}
|
|
534
577
|
}, [
|
|
535
578
|
h(DOMElement, {
|
|
536
579
|
element: "div",
|
|
@@ -608,7 +651,7 @@ function component($$props) {
|
|
|
608
651
|
},
|
|
609
652
|
textContent: computed(() => actionLabel() + " x" + quantity())
|
|
610
653
|
})])
|
|
611
|
-
])))]))]));
|
|
654
|
+
])))]))])]));
|
|
612
655
|
}
|
|
613
656
|
var __ce_component = component;
|
|
614
657
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shop.ce.js","names":[],"sources":["../../../../src/components/gui/shop/shop.ce"],"sourcesContent":[" <DOMContainer width=\"100%\" height=\"100%\">\n <div class=\"rpg-shop-container rpg-anim-fade-in\">\n <div class=\"rpg-shop-header\">\n <div class=\"rpg-shop-merchant\">\n <div>\n @if (hasFace) {\n <div class=\"rpg-shop-merchant-avatar\">\n <DOMSprite \n sheet={faceSheet(face().id, face().expression)} \n width=\"50px\"\n height=\"50px\"\n objectFit=\"contain\"\n /> \n </div>\n }\n </div>\n <div class=\"rpg-shop-merchant-info\">\n <p>{{ shopMessage() }}</p>\n </div>\n </div>\n <div class=\"rpg-shop-gold\">\n {{ gold() }} {{ goldTerm }}\n </div>\n </div>\n\n <div class=\"rpg-shop-body\">\n <div class=\"rpg-shop-left\">\n @if (tradeView() === 'mode') {\n <div class=\"rpg-shop-content rpg-shop-content-mode\">\n <div class=\"rpg-shop-details rpg-shop-details-mode\">\n <div class=\"rpg-shop-details-header\">\n <div class=\"rpg-shop-details-icon\">🛒</div>\n <h2 style=\"margin: 0;\">{t(\"rpg.shop.choose-action\")}</h2>\n </div>\n <div class=\"rpg-shop-trade\">\n <Navigation tabindex={selectedModeIndex} controls={modeControls}>\n <div class=\"rpg-shop-tabs rpg-shop-trade-tabs\">\n <div\n class=\"rpg-shop-tab\"\n class={{active: selectedModeIndex() === 0}}\n click={selectMode('buy')}\n >{t(\"rpg.shop.buy\")}</div>\n <div\n class=\"rpg-shop-tab\"\n class={{active: selectedModeIndex() === 1}}\n click={selectMode('sell')}\n >{t(\"rpg.shop.sell\")}</div>\n </div>\n </Navigation>\n </div>\n </div>\n </div>\n }\n @else {\n <div>\n <Navigation tabindex={selectedTab} controls={tabControls}> \n <div class=\"rpg-shop-tabs\">\n @for ((tab,index) of tabs) {\n <div \n class=\"rpg-shop-tab\" \n class={{active: selectedTab() === index}} \n tabindex={index} \n click={selectTab(index)}\n >{{ tab.label }}</div>\n }\n </div>\n </Navigation>\n\n <div class=\"rpg-shop-content\">\n <div class=\"rpg-shop-grid\">\n <Navigation tabindex={selectedItem} controls={itemControls}> \n @for ((item,index) of filteredItems) { \n <div class=\"rpg-shop-card\" class={{disabled: isItemDisabled(item), selected: selectedItem() === index}} tabindex={index} click={selectItem(index)}>\n <div class=\"rpg-shop-card-icon\">\n @if (item.icon) {\n <DOMSprite \n sheet={iconSheet(item.icon)} \n playing=\"default\" \n width=\"48px\"\n height=\"48px\"\n objectFit=\"contain\"\n />\n }\n </div>\n <div class=\"rpg-shop-card-name\">{{ item.name }}</div>\n <div class=\"rpg-shop-card-price\">{{ item.price }} {{ goldTerm }}</div>\n @if (item.quantity !== undefined) {\n <div class=\"rpg-shop-card-qty\">x{{ item.quantity }}</div>\n }\n @if (item.equipped) {\n <div class=\"rpg-shop-card-tag\">{t(\"rpg.shop.equipped\")}</div>\n }\n </div>\n }\n </Navigation>\n </div>\n\n <div class=\"rpg-shop-details\">\n <div class=\"rpg-shop-details-header\">\n <div class=\"rpg-shop-details-icon\">\n <DOMSprite \n sheet={iconSheet(currentItem()?.icon)} \n playing=\"default\" \n width=\"80px\"\n height=\"80px\"\n objectFit=\"contain\"\n />\n </div>\n <h2 style=\"margin: 0;\">{{ currentItem()?.name || \"\" }}</h2>\n <p style=\"color: #ffd700; font-weight: bold; margin: 8px 0;\">{{ currentItem()?.price ?? 0 }} {{ goldTerm }}</p>\n @if (currentItem()?.quantity !== undefined) {\n <div class=\"rpg-shop-details-qty\">{t(\"rpg.shop.qty\")}: x{{ currentItem()?.quantity }}</div>\n }\n </div>\n <div>\n @if (currentItem()?.equipped) {\n <div class=\"rpg-shop-equipped\">{t(\"rpg.shop.already-equipped\")}</div>\n }\n </div>\n <div class=\"rpg-shop-details-desc\">\n {{ currentItem()?.description || \"\" }}\n </div>\n <div>\n @if (displayStats().length > 0) {\n <div class=\"rpg-shop-stats\">\n @for ((stat,index) of displayStats) {\n <div class=\"rpg-shop-stat\" class={{positive: stat.delta > 0, negative: stat.delta < 0}}>\n <div class=\"rpg-shop-stat-key\">{{ stat.label }}</div>\n <div class=\"rpg-shop-stat-value\">\n {{ stat.delta > 0 ? '+' : '' }}{{ stat.delta }}\n </div>\n @if (stat.current !== undefined) {\n <div class=\"rpg-shop-stat-current\">{{ stat.current }} → {{ stat.next }}</div>\n }\n </div>\n }\n </div>\n }\n </div>\n <button class=\"rpg-shop-btn\" click={backToMode()}>{t(\"rpg.shop.back\")}</button>\n </div>\n </div>\n </div>\n }\n @if (quantityDialogOpen) {\n <div class=\"rpg-shop-modal\">\n <div class=\"rpg-shop-modal-card\">\n <div class=\"rpg-shop-modal-title\">{{ actionLabel }}</div>\n <div class=\"rpg-shop-modal-item\">{{ currentItem()?.name || \"\" }}</div>\n @if (currentItem()?.quantity !== undefined) {\n <div class=\"rpg-shop-modal-qty\">{t(\"rpg.shop.available\")}: x{{ currentItem()?.quantity }}</div>\n }\n <div class=\"rpg-shop-quantity\">\n <div class=\"rpg-shop-quantity-label\">{t(\"rpg.shop.quantity\")}</div>\n <div class=\"rpg-shop-quantity-controls\">\n <button class=\"rpg-shop-btn\" click={changeQuantity(-1)}>-</button>\n <div class=\"rpg-shop-quantity-value\">{{ quantity }}</div>\n <button class=\"rpg-shop-btn\" click={changeQuantity(1)}>+</button>\n </div>\n </div>\n <div class=\"rpg-shop-modal-total\">\n <span>{t(\"rpg.shop.total\")}</span>\n <span>{{ totalPrice() }} {{ goldTerm }}</span>\n </div>\n <div class=\"rpg-shop-modal-actions\">\n <button class=\"rpg-shop-btn rpg-shop-btn-secondary\" click={closeQuantityDialog()}>{t(\"rpg.menu.cancel\")}</button>\n <button class=\"rpg-shop-btn\" click={confirmTrade()}>\n {{ actionLabel() }} x{{ quantity() }}\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </DOMContainer>\n\n<script>\n import { mount, signal, computed, createTabindexNavigator, effect } from \"canvasengine\";\n import { inject } from \"../../../core/inject\";\n import { RpgClientEngine } from \"../../../RpgClientEngine\";\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 const iconSheet = (iconId) => ({\n definition: engine.getSpriteSheet(iconId),\n playing: \"default\"\n })\n const goldTerm = engine.globalConfig.goldTerm || 'G'\n\n const selectedItem = signal(0)\n const selectedTab = signal(0)\n const tradeMode = signal('buy')\n const tradeView = signal('mode')\n const selectedModeIndex = signal(0)\n const quantity = signal(1)\n const quantityDialogOpen = signal(false)\n const defaultMessage = t(\"rpg.shop.default-message\")\n const tabs = [\n { id: 'item', label: t(\"rpg.menu.items\") },\n { id: 'weapon', label: t(\"rpg.menu.weapons\") },\n { id: 'armor', label: t(\"rpg.menu.armor\") }\n ]\n\n const { data, onInteraction , onFinish } = defineProps()\n\n const resolveProp = (value) => typeof value === \"function\" ? value() : value\n const guiData = computed(() => resolveProp(data) || {})\n const shopMessage = computed(() => {\n const message = resolveProp(guiData().message)\n return message ? String(message) : defaultMessage\n })\n const face = computed(() => resolveProp(guiData().face))\n const hasFace = computed(() => {\n const value = face()\n return value && value.id\n })\n const buyItems = computed(() => guiData().items || [])\n const sellItems = computed(() => guiData().sellItems || [])\n const activeItems = computed(() => tradeMode() === 'buy' ? buyItems() : sellItems())\n const filteredItems = computed(() => {\n const tab = tabs[selectedTab()]\n const items = activeItems()\n if (!tab) return []\n return items.filter((item) => item?.type === tab.id)\n })\n const currentItem = computed(() => filteredItems()[selectedItem()])\n const gold = computed(() => currentPlayer()._gold())\n const actionLabel = computed(() => tradeMode() === 'buy' ? t(\"rpg.shop.buy\") : t(\"rpg.shop.sell\"))\n const faceSheet = (graphicId, animationName) => ({\n definition: engine.getSpriteSheet(graphicId),\n playing: animationName || \"default\"\n })\n const maxQuantity = computed(() => {\n const item = currentItem()\n if (!item) return 0\n const price = item?.price || 0\n if (price <= 0) return 0\n if (tradeMode() === 'sell') {\n const qty = item?.quantity ?? 0\n return Math.max(0, qty)\n }\n return Math.max(1, Math.floor(gold() / price))\n })\n const totalPrice = computed(() => {\n const price = currentItem()?.price || 0\n return price * quantity()\n })\n const displayStats = computed(() => {\n const stats = currentItem()?.stats || {}\n const params = guiData().playerParams || {}\n const order = ['atk', 'def', 'pdef', 'sdef', 'str', 'dex', 'int', 'agi', 'maxHp', 'maxSp']\n const labels = {\n atk: 'ATK',\n def: 'DEF',\n pdef: 'PDEF',\n sdef: 'SDEF',\n str: 'STR',\n dex: 'DEX',\n int: 'INT',\n agi: 'AGI',\n maxHp: 'MAX HP',\n maxSp: 'MAX SP'\n }\n const orderedKeys = order.filter((key) => stats[key] !== undefined)\n const extraKeys = Object.keys(stats).filter((key) => !order.includes(key))\n const keys = orderedKeys.concat(extraKeys)\n const list = []\n for (const key of keys) {\n const delta = stats[key]\n if (delta === undefined || delta === 0) continue\n let current = params[key]\n if (current === undefined && key === 'def') current = params.pdef\n const next = current !== undefined ? current + delta : undefined\n list.push({\n key,\n label: labels[key] || key.toUpperCase(),\n delta,\n current,\n next\n })\n }\n return list\n })\n const nav = createTabindexNavigator(selectedItem, { count: () => filteredItems().length }, 'wrap')\n const navTab = createTabindexNavigator(selectedTab, { count: () => tabs.length }, 'wrap')\n const navMode = createTabindexNavigator(selectedModeIndex, { count: () => 2 }, 'wrap')\n\n function selectItem(index) {\n return function() {\n selectedItem.set(index)\n quantity.set(1)\n if (!isItemDisabled(filteredItems()[index])) {\n quantityDialogOpen.set(true)\n }\n }\n }\n\n function selectTab(index) {\n return function() {\n selectedTab.set(index)\n selectedItem.set(0)\n }\n }\n\n function selectMode(mode) {\n return function() {\n tradeMode.set(mode)\n selectedModeIndex.set(mode === 'buy' ? 0 : 1)\n selectedItem.set(0)\n quantity.set(1)\n tradeView.set('items')\n }\n }\n\n function isItemDisabled(item) {\n if (!item) return true\n const price = item?.price || 0\n if (price <= 0) return true\n if (tradeMode() === 'sell') {\n const qty = item?.quantity ?? 0\n return qty <= 0\n }\n return gold() < price\n }\n\n function backToMode() {\n return function() {\n tradeView.set('mode')\n }\n }\n\n function changeQuantity(delta) {\n return function() {\n const limit = maxQuantity()\n if (limit <= 0) return\n const nextValue = Math.max(1, Math.min(limit, quantity() + delta))\n if (nextValue !== quantity()) {\n quantity.set(nextValue)\n }\n }\n }\n\n function closeQuantityDialog() {\n return function() {\n quantityDialogOpen.set(false)\n }\n }\n\n function confirmTrade() {\n return function() {\n const item = currentItem()\n if (!item || isItemDisabled(item)) {\n quantityDialogOpen.set(false)\n return\n }\n const action = tradeMode() === 'buy' ? 'buyItem' : 'sellItem'\n onInteraction(action, { id: item.id, nb: quantity() })\n quantityDialogOpen.set(false)\n }\n }\n\n effect(() => {\n const count = filteredItems().length\n if (selectedItem() >= count) {\n selectedItem.set(Math.max(0, count - 1))\n }\n })\n\n const modeControls = signal({\n left: {\n repeat: true,\n bind: keyboardControls.left,\n throttle: 150,\n keyDown() {\n navMode.next(-1)\n }\n },\n right: {\n repeat: true,\n bind: keyboardControls.right,\n throttle: 150,\n keyDown() {\n navMode.next(1)\n }\n },\n action: {\n bind: getKeyboardControlBind(keyboardControls.action),\n keyDown() {\n const mode = selectedModeIndex() === 0 ? 'buy' : 'sell'\n tradeMode.set(mode)\n selectedItem.set(0)\n quantity.set(1)\n tradeView.set('items')\n }\n },\n escape: {\n bind: keyboardControls.escape,\n keyDown() {\n onFinish()\n }\n },\n gamepad: {\n enabled: true\n }\n });\n\n const itemControls = signal({\n up: {\n repeat: true,\n bind: keyboardControls.up,\n throttle: 150,\n keyDown() {\n if (quantityDialogOpen()) {\n changeQuantity(1)()\n return\n }\n nav.next(-1)\n }\n },\n down: {\n repeat: true,\n bind: keyboardControls.down,\n throttle: 150,\n keyDown() {\n if (quantityDialogOpen()) {\n changeQuantity(-1)()\n return\n }\n nav.next(1)\n }\n },\n action: {\n bind: getKeyboardControlBind(keyboardControls.action),\n keyDown() {\n if (quantityDialogOpen()) {\n const item = currentItem()\n if (!item || isItemDisabled(item)) {\n quantityDialogOpen.set(false)\n return\n }\n const action = tradeMode() === 'buy' ? 'buyItem' : 'sellItem'\n onInteraction(action, { id: item.id, nb: quantity() })\n quantityDialogOpen.set(false)\n return\n }\n const item = currentItem()\n if (!isItemDisabled(item)) {\n quantityDialogOpen.set(true)\n }\n }\n },\n escape: {\n bind: keyboardControls.escape,\n keyDown() {\n if (quantityDialogOpen()) {\n quantityDialogOpen.set(false)\n return\n }\n tradeView.set('mode')\n }\n },\n gamepad: {\n enabled: true\n }\n });\n\n const tabControls = signal({\n left: {\n repeat: true,\n bind: keyboardControls.left,\n throttle: 150,\n keyDown() {\n if (quantityDialogOpen()) return\n navTab.next(-1)\n }\n },\n right: {\n repeat: true,\n bind: keyboardControls.right,\n throttle: 150,\n keyDown() {\n if (quantityDialogOpen()) return\n navTab.next(1)\n }\n },\n gamepad: {\n enabled: true\n }\n })\n</script>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"shop.ce.js","names":[],"sources":["../../../../src/components/gui/shop/shop.ce"],"sourcesContent":[" <DOMContainer width=\"100%\" height=\"100%\">\n <div class=\"rpg-shop-layer\" click={closeShopFromPointer}>\n <button class=\"rpg-ui-close-button\" type=\"button\" title=\"Close\" aria-label=\"Close shop\" click={closeShopFromPointer}>x</button>\n <div class=\"rpg-shop-container rpg-anim-fade-in\" click={stopEvent}>\n <div class=\"rpg-shop-header\">\n <div class=\"rpg-shop-merchant\">\n <div>\n @if (hasFace) {\n <div class=\"rpg-shop-merchant-avatar\">\n <DOMSprite \n sheet={faceSheet(face().id, face().expression)} \n width=\"50px\"\n height=\"50px\"\n objectFit=\"contain\"\n /> \n </div>\n }\n </div>\n <div class=\"rpg-shop-merchant-info\">\n <p>{{ shopMessage() }}</p>\n </div>\n </div>\n <div class=\"rpg-shop-gold\">\n {{ gold() }} {{ goldTerm }}\n </div>\n </div>\n\n <div class=\"rpg-shop-body\">\n <div class=\"rpg-shop-left\">\n @if (tradeView() === 'mode') {\n <div class=\"rpg-shop-content rpg-shop-content-mode\">\n <div class=\"rpg-shop-details rpg-shop-details-mode\">\n <div class=\"rpg-shop-details-header\">\n <div class=\"rpg-shop-details-icon\">🛒</div>\n <h2 style=\"margin: 0;\">{t(\"rpg.shop.choose-action\")}</h2>\n </div>\n <div class=\"rpg-shop-trade\">\n <Navigation tabindex={selectedModeIndex} controls={modeControls}>\n <div class=\"rpg-shop-tabs rpg-shop-trade-tabs\">\n <div\n class=\"rpg-shop-tab\"\n class={{active: selectedModeIndex() === 0}}\n click={selectMode('buy')}\n >{t(\"rpg.shop.buy\")}</div>\n <div\n class=\"rpg-shop-tab\"\n class={{active: selectedModeIndex() === 1}}\n click={selectMode('sell')}\n >{t(\"rpg.shop.sell\")}</div>\n </div>\n </Navigation>\n </div>\n </div>\n </div>\n }\n @else {\n <div>\n <Navigation tabindex={selectedTab} controls={tabControls}> \n <div class=\"rpg-shop-tabs\">\n @for ((tab,index) of tabs) {\n <div \n class=\"rpg-shop-tab\" \n class={{active: selectedTab() === index}} \n tabindex={index} \n click={selectTab(index)}\n >{{ tab.label }}</div>\n }\n </div>\n </Navigation>\n\n <div class=\"rpg-shop-content\">\n <div class=\"rpg-shop-grid\">\n <Navigation tabindex={selectedItem} controls={itemControls}> \n @for ((item,index) of filteredItems) { \n <div class=\"rpg-shop-card\" class={{disabled: isItemDisabled(item), selected: selectedItem() === index}} tabindex={index} click={selectItem(index)}>\n <div class=\"rpg-shop-card-icon\">\n @if (item.icon) {\n <DOMSprite \n sheet={iconSheet(item.icon)} \n playing=\"default\" \n width=\"48px\"\n height=\"48px\"\n objectFit=\"contain\"\n />\n }\n </div>\n <div class=\"rpg-shop-card-name\">{{ item.name }}</div>\n <div class=\"rpg-shop-card-price\">{{ item.price }} {{ goldTerm }}</div>\n @if (item.quantity !== undefined) {\n <div class=\"rpg-shop-card-qty\">x{{ item.quantity }}</div>\n }\n @if (item.equipped) {\n <div class=\"rpg-shop-card-tag\">{t(\"rpg.shop.equipped\")}</div>\n }\n </div>\n }\n </Navigation>\n </div>\n\n <div class=\"rpg-shop-details\">\n <div class=\"rpg-shop-details-header\">\n <div class=\"rpg-shop-details-icon\">\n <DOMSprite \n sheet={iconSheet(currentItem()?.icon)} \n playing=\"default\" \n width=\"80px\"\n height=\"80px\"\n objectFit=\"contain\"\n />\n </div>\n <h2 style=\"margin: 0;\">{{ currentItem()?.name || \"\" }}</h2>\n <p style=\"color: #ffd700; font-weight: bold; margin: 8px 0;\">{{ currentItem()?.price ?? 0 }} {{ goldTerm }}</p>\n @if (currentItem()?.quantity !== undefined) {\n <div class=\"rpg-shop-details-qty\">{t(\"rpg.shop.qty\")}: x{{ currentItem()?.quantity }}</div>\n }\n </div>\n <div>\n @if (currentItem()?.equipped) {\n <div class=\"rpg-shop-equipped\">{t(\"rpg.shop.already-equipped\")}</div>\n }\n </div>\n <div class=\"rpg-shop-details-desc\">\n {{ currentItem()?.description || \"\" }}\n </div>\n <div>\n @if (displayStats().length > 0) {\n <div class=\"rpg-shop-stats\">\n @for ((stat,index) of displayStats) {\n <div class=\"rpg-shop-stat\" class={{positive: stat.delta > 0, negative: stat.delta < 0}}>\n <div class=\"rpg-shop-stat-key\">{{ stat.label }}</div>\n <div class=\"rpg-shop-stat-value\">\n {{ stat.delta > 0 ? '+' : '' }}{{ stat.delta }}\n </div>\n @if (stat.current !== undefined) {\n <div class=\"rpg-shop-stat-current\">{{ stat.current }} → {{ stat.next }}</div>\n }\n </div>\n }\n </div>\n }\n </div>\n <button class=\"rpg-shop-btn\" click={backToMode()}>{t(\"rpg.shop.back\")}</button>\n </div>\n </div>\n </div>\n }\n @if (quantityDialogOpen) {\n <div class=\"rpg-shop-modal\" click={closeQuantityDialogFromPointer}>\n <div class=\"rpg-shop-modal-card\" click={stopEvent}>\n <div class=\"rpg-shop-modal-title\">{{ actionLabel }}</div>\n <div class=\"rpg-shop-modal-item\">{{ currentItem()?.name || \"\" }}</div>\n @if (currentItem()?.quantity !== undefined) {\n <div class=\"rpg-shop-modal-qty\">{t(\"rpg.shop.available\")}: x{{ currentItem()?.quantity }}</div>\n }\n <div class=\"rpg-shop-quantity\">\n <div class=\"rpg-shop-quantity-label\">{t(\"rpg.shop.quantity\")}</div>\n <div class=\"rpg-shop-quantity-controls\">\n <button class=\"rpg-shop-btn\" click={changeQuantity(-1)}>-</button>\n <div class=\"rpg-shop-quantity-value\">{{ quantity }}</div>\n <button class=\"rpg-shop-btn\" click={changeQuantity(1)}>+</button>\n </div>\n </div>\n <div class=\"rpg-shop-modal-total\">\n <span>{t(\"rpg.shop.total\")}</span>\n <span>{{ totalPrice() }} {{ goldTerm }}</span>\n </div>\n <div class=\"rpg-shop-modal-actions\">\n <button class=\"rpg-shop-btn rpg-shop-btn-secondary\" click={closeQuantityDialog()}>{t(\"rpg.menu.cancel\")}</button>\n <button class=\"rpg-shop-btn\" click={confirmTrade()}>\n {{ actionLabel() }} x{{ quantity() }}\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </DOMContainer>\n\n<script>\n import { mount, signal, computed, createTabindexNavigator, effect } from \"canvasengine\";\n import { inject } from \"../../../core/inject\";\n import { RpgClientEngine } from \"../../../RpgClientEngine\";\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 const iconSheet = (iconId) => ({\n definition: engine.getSpriteSheet(iconId),\n playing: \"default\"\n })\n const goldTerm = engine.globalConfig.goldTerm || 'G'\n\n const selectedItem = signal(0)\n const selectedTab = signal(0)\n const tradeMode = signal('buy')\n const tradeView = signal('mode')\n const selectedModeIndex = signal(0)\n const quantity = signal(1)\n const quantityDialogOpen = signal(false)\n const defaultMessage = t(\"rpg.shop.default-message\")\n const tabs = [\n { id: 'item', label: t(\"rpg.menu.items\") },\n { id: 'weapon', label: t(\"rpg.menu.weapons\") },\n { id: 'armor', label: t(\"rpg.menu.armor\") }\n ]\n\n const { data, onInteraction , onFinish } = defineProps()\n\n const resolveProp = (value) => typeof value === \"function\" ? value() : value\n const guiData = computed(() => resolveProp(data) || {})\n const shopMessage = computed(() => {\n const message = resolveProp(guiData().message)\n return message ? String(message) : defaultMessage\n })\n const face = computed(() => resolveProp(guiData().face))\n const hasFace = computed(() => {\n const value = face()\n return value && value.id\n })\n const buyItems = computed(() => guiData().items || [])\n const sellItems = computed(() => guiData().sellItems || [])\n const activeItems = computed(() => tradeMode() === 'buy' ? buyItems() : sellItems())\n const filteredItems = computed(() => {\n const tab = tabs[selectedTab()]\n const items = activeItems()\n if (!tab) return []\n return items.filter((item) => item?.type === tab.id)\n })\n const currentItem = computed(() => filteredItems()[selectedItem()])\n const gold = computed(() => currentPlayer()._gold())\n const actionLabel = computed(() => tradeMode() === 'buy' ? t(\"rpg.shop.buy\") : t(\"rpg.shop.sell\"))\n const faceSheet = (graphicId, animationName) => ({\n definition: engine.getSpriteSheet(graphicId),\n playing: animationName || \"default\"\n })\n const maxQuantity = computed(() => {\n const item = currentItem()\n if (!item) return 0\n const price = item?.price || 0\n if (price <= 0) return 0\n if (tradeMode() === 'sell') {\n const qty = item?.quantity ?? 0\n return Math.max(0, qty)\n }\n return Math.max(1, Math.floor(gold() / price))\n })\n const totalPrice = computed(() => {\n const price = currentItem()?.price || 0\n return price * quantity()\n })\n const displayStats = computed(() => {\n const stats = currentItem()?.stats || {}\n const params = guiData().playerParams || {}\n const order = ['atk', 'def', 'pdef', 'sdef', 'str', 'dex', 'int', 'agi', 'maxHp', 'maxSp']\n const labels = {\n atk: 'ATK',\n def: 'DEF',\n pdef: 'PDEF',\n sdef: 'SDEF',\n str: 'STR',\n dex: 'DEX',\n int: 'INT',\n agi: 'AGI',\n maxHp: 'MAX HP',\n maxSp: 'MAX SP'\n }\n const orderedKeys = order.filter((key) => stats[key] !== undefined)\n const extraKeys = Object.keys(stats).filter((key) => !order.includes(key))\n const keys = orderedKeys.concat(extraKeys)\n const list = []\n for (const key of keys) {\n const delta = stats[key]\n if (delta === undefined || delta === 0) continue\n let current = params[key]\n if (current === undefined && key === 'def') current = params.pdef\n const next = current !== undefined ? current + delta : undefined\n list.push({\n key,\n label: labels[key] || key.toUpperCase(),\n delta,\n current,\n next\n })\n }\n return list\n })\n const nav = createTabindexNavigator(selectedItem, { count: () => filteredItems().length }, 'wrap')\n const navTab = createTabindexNavigator(selectedTab, { count: () => tabs.length }, 'wrap')\n const navMode = createTabindexNavigator(selectedModeIndex, { count: () => 2 }, 'wrap')\n\n function selectItem(index) {\n return function() {\n selectedItem.set(index)\n quantity.set(1)\n if (!isItemDisabled(filteredItems()[index])) {\n quantityDialogOpen.set(true)\n }\n }\n }\n\n function selectTab(index) {\n return function() {\n selectedTab.set(index)\n selectedItem.set(0)\n }\n }\n\n function selectMode(mode) {\n return function() {\n tradeMode.set(mode)\n selectedModeIndex.set(mode === 'buy' ? 0 : 1)\n selectedItem.set(0)\n quantity.set(1)\n tradeView.set('items')\n }\n }\n\n function isItemDisabled(item) {\n if (!item) return true\n const price = item?.price || 0\n if (price <= 0) return true\n if (tradeMode() === 'sell') {\n const qty = item?.quantity ?? 0\n return qty <= 0\n }\n return gold() < price\n }\n\n function backToMode() {\n return function() {\n tradeView.set('mode')\n }\n }\n\n function changeQuantity(delta) {\n return function() {\n const limit = maxQuantity()\n if (limit <= 0) return\n const nextValue = Math.max(1, Math.min(limit, quantity() + delta))\n if (nextValue !== quantity()) {\n quantity.set(nextValue)\n }\n }\n }\n\n function closeQuantityDialog() {\n return function() {\n quantityDialogOpen.set(false)\n }\n }\n\n const stopEvent = (event) => {\n event?.stopPropagation?.()\n }\n\n const closeQuantityDialogFromPointer = (event) => {\n stopEvent(event)\n quantityDialogOpen.set(false)\n }\n\n const closeShop = () => {\n if (quantityDialogOpen()) {\n quantityDialogOpen.set(false)\n return\n }\n onFinish()\n }\n\n const closeShopFromPointer = (event) => {\n stopEvent(event)\n closeShop()\n }\n\n function confirmTrade() {\n return function() {\n const item = currentItem()\n if (!item || isItemDisabled(item)) {\n quantityDialogOpen.set(false)\n return\n }\n const action = tradeMode() === 'buy' ? 'buyItem' : 'sellItem'\n onInteraction(action, { id: item.id, nb: quantity() })\n quantityDialogOpen.set(false)\n }\n }\n\n effect(() => {\n const count = filteredItems().length\n if (selectedItem() >= count) {\n selectedItem.set(Math.max(0, count - 1))\n }\n })\n\n const modeControls = signal({\n left: {\n repeat: true,\n bind: keyboardControls.left,\n throttle: 150,\n keyDown() {\n navMode.next(-1)\n }\n },\n right: {\n repeat: true,\n bind: keyboardControls.right,\n throttle: 150,\n keyDown() {\n navMode.next(1)\n }\n },\n action: {\n bind: getKeyboardControlBind(keyboardControls.action),\n keyDown() {\n const mode = selectedModeIndex() === 0 ? 'buy' : 'sell'\n tradeMode.set(mode)\n selectedItem.set(0)\n quantity.set(1)\n tradeView.set('items')\n }\n },\n escape: {\n bind: keyboardControls.escape,\n keyDown() {\n onFinish()\n }\n },\n gamepad: {\n enabled: true\n }\n });\n\n const itemControls = signal({\n up: {\n repeat: true,\n bind: keyboardControls.up,\n throttle: 150,\n keyDown() {\n if (quantityDialogOpen()) {\n changeQuantity(1)()\n return\n }\n nav.next(-1)\n }\n },\n down: {\n repeat: true,\n bind: keyboardControls.down,\n throttle: 150,\n keyDown() {\n if (quantityDialogOpen()) {\n changeQuantity(-1)()\n return\n }\n nav.next(1)\n }\n },\n action: {\n bind: getKeyboardControlBind(keyboardControls.action),\n keyDown() {\n if (quantityDialogOpen()) {\n const item = currentItem()\n if (!item || isItemDisabled(item)) {\n quantityDialogOpen.set(false)\n return\n }\n const action = tradeMode() === 'buy' ? 'buyItem' : 'sellItem'\n onInteraction(action, { id: item.id, nb: quantity() })\n quantityDialogOpen.set(false)\n return\n }\n const item = currentItem()\n if (!isItemDisabled(item)) {\n quantityDialogOpen.set(true)\n }\n }\n },\n escape: {\n bind: keyboardControls.escape,\n keyDown() {\n if (quantityDialogOpen()) {\n quantityDialogOpen.set(false)\n return\n }\n tradeView.set('mode')\n }\n },\n gamepad: {\n enabled: true\n }\n });\n\n const tabControls = signal({\n left: {\n repeat: true,\n bind: keyboardControls.left,\n throttle: 150,\n keyDown() {\n if (quantityDialogOpen()) return\n navTab.next(-1)\n }\n },\n right: {\n repeat: true,\n bind: keyboardControls.right,\n throttle: 150,\n keyDown() {\n if (quantityDialogOpen()) return\n navTab.next(1)\n }\n },\n gamepad: {\n enabled: true\n }\n })\n</script>\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rpgjs/client",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.24",
|
|
4
4
|
"description": "RPGJS is a framework for creating RPG/MMORPG games",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
"pixi.js": "^8.9.2"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@rpgjs/common": "5.0.0-beta.
|
|
26
|
-
"@rpgjs/server": "5.0.0-beta.
|
|
27
|
-
"@rpgjs/ui-css": "5.0.0-beta.
|
|
25
|
+
"@rpgjs/common": "5.0.0-beta.23",
|
|
26
|
+
"@rpgjs/server": "5.0.0-beta.24",
|
|
27
|
+
"@rpgjs/ui-css": "5.0.0-beta.22",
|
|
28
28
|
"@signe/di": "3.1.0",
|
|
29
29
|
"@signe/room": "3.1.0",
|
|
30
30
|
"@signe/sync": "3.1.0",
|
package/src/Game/Object.spec.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, test, vi } from "vitest";
|
|
2
2
|
import { signal } from "canvasengine";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
appendFramePayload,
|
|
5
|
+
mergeFreshFramePayload,
|
|
6
|
+
multiplyGraphicDisplayScale,
|
|
7
|
+
RpgClientObject,
|
|
8
|
+
withGraphicDisplayScale,
|
|
9
|
+
} from "./Object";
|
|
4
10
|
import { RpgClientEvent } from "./Event";
|
|
5
11
|
import { RpgClientPlayer } from "./Player";
|
|
6
12
|
|
|
@@ -40,10 +46,28 @@ describe("RpgClientObject animations", () => {
|
|
|
40
46
|
).toEqual([{ x: 10, y: 20, ts: 1 }]);
|
|
41
47
|
});
|
|
42
48
|
|
|
49
|
+
test("drops stale movement frames that arrive after a newer frame was applied", () => {
|
|
50
|
+
expect(
|
|
51
|
+
mergeFreshFramePayload(
|
|
52
|
+
[],
|
|
53
|
+
[{ x: 733, y: 551, ts: 200 }],
|
|
54
|
+
300,
|
|
55
|
+
),
|
|
56
|
+
).toEqual([]);
|
|
57
|
+
});
|
|
58
|
+
|
|
43
59
|
test("keeps instance scale outside the spritesheet transform scale", () => {
|
|
44
60
|
expect(withGraphicDisplayScale({ id: "hero" }, 0.5)).toEqual({
|
|
45
61
|
id: "hero",
|
|
46
|
-
displayScale: 0.5,
|
|
62
|
+
displayScale: [0.5, 0.5],
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test("combines media and instance display scales", () => {
|
|
67
|
+
expect(multiplyGraphicDisplayScale(0.5, 2)).toEqual([1, 1]);
|
|
68
|
+
expect(withGraphicDisplayScale({ id: "hero", displayScale: 0.5 }, { x: 2, y: 3 })).toEqual({
|
|
69
|
+
id: "hero",
|
|
70
|
+
displayScale: [1, 1.5],
|
|
47
71
|
});
|
|
48
72
|
});
|
|
49
73
|
|