@rpgjs/client 5.0.0-beta.12 → 5.0.0-beta.13
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 +10 -0
- package/dist/Game/Object.d.ts +2 -0
- package/dist/Game/Object.js +20 -6
- package/dist/Game/Object.js.map +1 -1
- package/dist/Gui/Gui.d.ts +3 -2
- package/dist/Gui/Gui.js +18 -6
- package/dist/Gui/Gui.js.map +1 -1
- package/dist/RpgClient.d.ts +21 -1
- package/dist/RpgClientEngine.d.ts +20 -2
- package/dist/RpgClientEngine.js +180 -17
- package/dist/RpgClientEngine.js.map +1 -1
- package/dist/components/character.ce.js +82 -7
- package/dist/components/character.ce.js.map +1 -1
- package/dist/components/gui/dialogbox/index.ce.js +27 -12
- package/dist/components/gui/dialogbox/index.ce.js.map +1 -1
- package/dist/components/gui/gameover.ce.js +4 -3
- package/dist/components/gui/gameover.ce.js.map +1 -1
- package/dist/components/gui/menu/equip-menu.ce.js +9 -8
- package/dist/components/gui/menu/equip-menu.ce.js.map +1 -1
- package/dist/components/gui/menu/exit-menu.ce.js +7 -5
- package/dist/components/gui/menu/exit-menu.ce.js.map +1 -1
- package/dist/components/gui/menu/items-menu.ce.js +8 -7
- package/dist/components/gui/menu/items-menu.ce.js.map +1 -1
- package/dist/components/gui/menu/main-menu.ce.js +12 -11
- package/dist/components/gui/menu/main-menu.ce.js.map +1 -1
- package/dist/components/gui/menu/options-menu.ce.js +7 -5
- package/dist/components/gui/menu/options-menu.ce.js.map +1 -1
- package/dist/components/gui/menu/skills-menu.ce.js +4 -2
- package/dist/components/gui/menu/skills-menu.ce.js.map +1 -1
- package/dist/components/gui/notification/notification.ce.js +4 -1
- package/dist/components/gui/notification/notification.ce.js.map +1 -1
- package/dist/components/gui/save-load.ce.js +10 -9
- package/dist/components/gui/save-load.ce.js.map +1 -1
- package/dist/components/gui/shop/shop.ce.js +17 -16
- package/dist/components/gui/shop/shop.ce.js.map +1 -1
- package/dist/components/gui/title-screen.ce.js +4 -3
- package/dist/components/gui/title-screen.ce.js.map +1 -1
- package/dist/components/interaction-components.ce.js +20 -0
- package/dist/components/interaction-components.ce.js.map +1 -0
- package/dist/components/scenes/canvas.ce.js +12 -7
- package/dist/components/scenes/canvas.ce.js.map +1 -1
- package/dist/components/scenes/draw-map.ce.js +18 -13
- package/dist/components/scenes/draw-map.ce.js.map +1 -1
- package/dist/i18n.d.ts +55 -0
- package/dist/i18n.js +60 -0
- package/dist/i18n.js.map +1 -0
- package/dist/i18n.spec.d.ts +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -1
- package/dist/module.js +23 -3
- package/dist/module.js.map +1 -1
- package/dist/services/interactions.d.ts +159 -0
- package/dist/services/interactions.js +460 -0
- package/dist/services/interactions.js.map +1 -0
- package/dist/services/interactions.spec.d.ts +1 -0
- package/dist/services/keyboardControls.d.ts +1 -0
- package/dist/services/keyboardControls.js +1 -0
- package/dist/services/keyboardControls.js.map +1 -1
- package/package.json +4 -4
- package/src/Game/Object.spec.ts +14 -1
- package/src/Game/Object.ts +34 -10
- package/src/Gui/Gui.spec.ts +67 -0
- package/src/Gui/Gui.ts +24 -7
- package/src/RpgClient.ts +28 -1
- package/src/RpgClientEngine.ts +248 -29
- package/src/components/character.ce +90 -7
- package/src/components/gui/dialogbox/index.ce +35 -14
- package/src/components/gui/gameover.ce +4 -3
- package/src/components/gui/menu/equip-menu.ce +9 -8
- package/src/components/gui/menu/exit-menu.ce +4 -3
- package/src/components/gui/menu/items-menu.ce +8 -7
- package/src/components/gui/menu/main-menu.ce +12 -11
- package/src/components/gui/menu/options-menu.ce +4 -3
- package/src/components/gui/menu/skills-menu.ce +2 -1
- package/src/components/gui/notification/notification.ce +7 -1
- package/src/components/gui/save-load.ce +11 -10
- package/src/components/gui/shop/shop.ce +17 -16
- package/src/components/gui/title-screen.ce +4 -3
- package/src/components/interaction-components.ce +23 -0
- package/src/components/scenes/canvas.ce +12 -7
- package/src/components/scenes/draw-map.ce +16 -5
- package/src/i18n.spec.ts +39 -0
- package/src/i18n.ts +59 -0
- package/src/index.ts +2 -0
- package/src/module.ts +32 -10
- package/src/services/interactions.spec.ts +175 -0
- package/src/services/interactions.ts +722 -0
- package/src/services/keyboardControls.ts +2 -1
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
@if (hasChoices()) {
|
|
18
18
|
<Navigation tabindex={selectedItem} controls={controls}>
|
|
19
19
|
<div class="rpg-ui-dialog-choices">
|
|
20
|
-
@for ((choice,index) of
|
|
20
|
+
@for ((choice,index) of dialogChoices()) {
|
|
21
21
|
<div
|
|
22
22
|
class="rpg-ui-dialog-choice"
|
|
23
23
|
class={{active: selectedItem() === index}}
|
|
@@ -62,27 +62,38 @@
|
|
|
62
62
|
engine.stopProcessingInput = true;
|
|
63
63
|
|
|
64
64
|
const selectedItem = signal(0)
|
|
65
|
-
|
|
65
|
+
const ACTION_OPEN_GUARD_MS = 150;
|
|
66
|
+
const openedAt = Date.now();
|
|
66
67
|
|
|
67
68
|
const {
|
|
68
69
|
data,
|
|
69
70
|
onFinish,
|
|
70
|
-
onInteraction
|
|
71
|
+
onInteraction,
|
|
72
|
+
guiOpenId
|
|
71
73
|
} = defineProps();
|
|
72
74
|
|
|
73
|
-
const
|
|
74
|
-
const
|
|
75
|
+
const dialogData = computed(() => data() || {});
|
|
76
|
+
const dialogChoices = computed(() => Array.isArray(dialogData().choices) ? dialogData().choices : []);
|
|
77
|
+
const message = computed(() => dialogData().message);
|
|
78
|
+
const speaker = computed(() => dialogData().speaker);
|
|
79
|
+
const position = computed(() => dialogData().position);
|
|
80
|
+
const typewriterEffect = computed(() => dialogData().typewriterEffect);
|
|
81
|
+
const fullWidth = computed(() => dialogData().fullWidth || false);
|
|
75
82
|
|
|
76
83
|
const resolveProp = (value) => typeof value === "function" ? value() : value;
|
|
84
|
+
const normalizeOpenId = (value) => {
|
|
85
|
+
const resolved = resolveProp(value);
|
|
86
|
+
return typeof resolved === "string" && resolved.length > 0 ? resolved : undefined;
|
|
87
|
+
};
|
|
77
88
|
|
|
78
89
|
const speakerName = computed(() => {
|
|
79
|
-
const value = resolveProp(speaker);
|
|
90
|
+
const value = resolveProp(speaker());
|
|
80
91
|
return value ? String(value) : "";
|
|
81
92
|
});
|
|
82
93
|
|
|
83
|
-
const dialogPosition = computed(() => resolveProp(position) || "bottom");
|
|
94
|
+
const dialogPosition = computed(() => resolveProp(position()) || "bottom");
|
|
84
95
|
const isFullWidth = computed(() => resolveProp(fullWidth) !== false);
|
|
85
|
-
const dialogFace = computed(() => resolveProp(face));
|
|
96
|
+
const dialogFace = computed(() => resolveProp(dialogData().face));
|
|
86
97
|
const hasFace = computed(() => {
|
|
87
98
|
const value = dialogFace();
|
|
88
99
|
return !!(value && value.id);
|
|
@@ -123,9 +134,9 @@
|
|
|
123
134
|
};
|
|
124
135
|
|
|
125
136
|
effect(() => {
|
|
126
|
-
const text = resolveProp(message) || "";
|
|
137
|
+
const text = resolveProp(message()) || "";
|
|
127
138
|
fullMessage.set(text);
|
|
128
|
-
const useTypewriter = resolveProp(typewriterEffect) !== false;
|
|
139
|
+
const useTypewriter = resolveProp(typewriterEffect()) !== false;
|
|
129
140
|
if (!useTypewriter) {
|
|
130
141
|
finishTyping();
|
|
131
142
|
return;
|
|
@@ -134,9 +145,9 @@
|
|
|
134
145
|
});
|
|
135
146
|
|
|
136
147
|
|
|
137
|
-
const hasChoices = computed(() =>
|
|
148
|
+
const hasChoices = computed(() => dialogChoices().length > 0);
|
|
138
149
|
const showIndicator = computed(() => !hasChoices() && !isTyping());
|
|
139
|
-
const nav = createTabindexNavigator(selectedItem, { count: () =>
|
|
150
|
+
const nav = createTabindexNavigator(selectedItem, { count: () => dialogChoices().length }, 'wrap');
|
|
140
151
|
|
|
141
152
|
function selectChoice(index) {
|
|
142
153
|
return function() {
|
|
@@ -146,13 +157,15 @@
|
|
|
146
157
|
}
|
|
147
158
|
|
|
148
159
|
function _onFinish(value) {
|
|
149
|
-
if (onFinish) onFinish(value);
|
|
160
|
+
if (onFinish) onFinish(value, normalizeOpenId(guiOpenId));
|
|
150
161
|
}
|
|
151
162
|
|
|
152
163
|
const onSelect = (index) => {
|
|
153
164
|
_onFinish(index);
|
|
154
165
|
};
|
|
155
166
|
|
|
167
|
+
const canAcceptAction = () => Date.now() - openedAt >= ACTION_OPEN_GUARD_MS;
|
|
168
|
+
|
|
156
169
|
const controls = signal({
|
|
157
170
|
up: {
|
|
158
171
|
repeat: true,
|
|
@@ -175,6 +188,9 @@
|
|
|
175
188
|
action: {
|
|
176
189
|
bind: getKeyboardControlBind(keyboardControls.action),
|
|
177
190
|
keyDown() {
|
|
191
|
+
if (!canAcceptAction()) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
178
194
|
if (isTyping()) {
|
|
179
195
|
finishTyping();
|
|
180
196
|
return;
|
|
@@ -192,6 +208,9 @@
|
|
|
192
208
|
action: {
|
|
193
209
|
bind: getKeyboardControlBind(keyboardControls.action),
|
|
194
210
|
keyDown() {
|
|
211
|
+
if (!canAcceptAction()) {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
195
214
|
if (isTyping()) {
|
|
196
215
|
finishTyping();
|
|
197
216
|
return;
|
|
@@ -203,6 +222,9 @@
|
|
|
203
222
|
})
|
|
204
223
|
|
|
205
224
|
const faceSheet = (faceValue) => {
|
|
225
|
+
if (!faceValue || !faceValue.id) {
|
|
226
|
+
return undefined;
|
|
227
|
+
}
|
|
206
228
|
return {
|
|
207
229
|
definition: engine.getSpriteSheet(faceValue.id),
|
|
208
230
|
playing: faceValue.expression || "default",
|
|
@@ -211,7 +233,6 @@
|
|
|
211
233
|
|
|
212
234
|
mount((element) => {
|
|
213
235
|
return () => {
|
|
214
|
-
isDestroyed = true;
|
|
215
236
|
// Wait destroy is finished before start processing input
|
|
216
237
|
delay(() => {
|
|
217
238
|
engine.stopProcessingInput = false;
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
import { getKeyboardControlBind } from "../../services/actionInput";
|
|
35
35
|
|
|
36
36
|
const engine = inject(RpgClientEngine);
|
|
37
|
+
const { t } = engine.i18n();
|
|
37
38
|
const guiService = inject(RpgGui);
|
|
38
39
|
const keyboardControls = engine.globalConfig.keyboardControls;
|
|
39
40
|
|
|
@@ -50,12 +51,12 @@
|
|
|
50
51
|
});
|
|
51
52
|
|
|
52
53
|
const defaultEntries = [
|
|
53
|
-
{ id: "title", label: "
|
|
54
|
-
{ id: "load", label: "
|
|
54
|
+
{ id: "title", label: t("rpg.gameover.title-screen") },
|
|
55
|
+
{ id: "load", label: t("rpg.gameover.load-game") }
|
|
55
56
|
];
|
|
56
57
|
|
|
57
58
|
const resolveProp = (value) => typeof value === "function" ? value() : value;
|
|
58
|
-
const titleText = computed(() => resolveProp(title) || "
|
|
59
|
+
const titleText = computed(() => resolveProp(title) || t("rpg.gameover.title"));
|
|
59
60
|
const subtitleText = computed(() => resolveProp(subtitle) || "");
|
|
60
61
|
const localActionsEnabled = computed(() => resolveProp(localActions) === true);
|
|
61
62
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<DOMContainer width="100%" height="100%">
|
|
2
2
|
<div class="rpg-ui-menu-panel rpg-ui-panel">
|
|
3
|
-
<div class="rpg-ui-menu-panel-header">
|
|
3
|
+
<div class="rpg-ui-menu-panel-header">{t("rpg.menu.equip")}</div>
|
|
4
4
|
<div class="rpg-ui-menu-panel-body rpg-ui-menu-panel-body-stacked">
|
|
5
5
|
<div>
|
|
6
6
|
<div class="rpg-ui-menu-panel-details rpg-ui-panel">
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
</div>
|
|
17
17
|
<div>
|
|
18
18
|
<div class="rpg-ui-menu-panel-details-title">
|
|
19
|
-
{detailsItem()?.name || currentSlot()?.label || "
|
|
19
|
+
{detailsItem()?.name || currentSlot()?.label || t("rpg.menu.equip")}
|
|
20
20
|
</div>
|
|
21
21
|
<div class="rpg-ui-menu-panel-details-desc">
|
|
22
22
|
{detailsItem()?.description || ""}
|
|
@@ -93,6 +93,7 @@
|
|
|
93
93
|
import { getKeyboardControlBind } from "../../../services/actionInput";
|
|
94
94
|
|
|
95
95
|
const engine = inject(RpgClientEngine);
|
|
96
|
+
const { t } = engine.i18n();
|
|
96
97
|
const keyboardControls = engine.globalConfig.keyboardControls;
|
|
97
98
|
const currentPlayer = engine.scene.currentPlayer;
|
|
98
99
|
|
|
@@ -104,8 +105,8 @@
|
|
|
104
105
|
const slots = computed(() => data().slots);
|
|
105
106
|
|
|
106
107
|
const defaultSlots = [
|
|
107
|
-
{ id: "weapon", label: "
|
|
108
|
-
{ id: "armor", label: "
|
|
108
|
+
{ id: "weapon", label: t("rpg.menu.weapons"), types: ["weapon"] },
|
|
109
|
+
{ id: "armor", label: t("rpg.menu.armor"), types: ["armor"] }
|
|
109
110
|
];
|
|
110
111
|
const resolveProp = (value) => typeof value === "function" ? value() : value;
|
|
111
112
|
const safeEquips = computed(() => {
|
|
@@ -170,15 +171,15 @@
|
|
|
170
171
|
const items = slotItems().map((item) => ({
|
|
171
172
|
...item,
|
|
172
173
|
kind: "item",
|
|
173
|
-
tag: itemEquipped(item) ? "
|
|
174
|
+
tag: itemEquipped(item) ? t("rpg.shop.equipped") : ""
|
|
174
175
|
}));
|
|
175
176
|
const equipped = currentEquippedItem();
|
|
176
177
|
if (!equipped) return items;
|
|
177
178
|
return [
|
|
178
179
|
{
|
|
179
180
|
id: "__unequip__",
|
|
180
|
-
name: "
|
|
181
|
-
description: "
|
|
181
|
+
name: t("rpg.menu.unequip"),
|
|
182
|
+
description: t("rpg.menu.remove-equipment"),
|
|
182
183
|
kind: "unequip",
|
|
183
184
|
tag: ""
|
|
184
185
|
},
|
|
@@ -197,7 +198,7 @@
|
|
|
197
198
|
const slot = currentSlot();
|
|
198
199
|
if (!slot) return "";
|
|
199
200
|
const equipped = currentEquippedItem();
|
|
200
|
-
return equipped ? `${slot.label}: ${equipped.name}` : `${slot.label}:
|
|
201
|
+
return equipped ? `${slot.label}: ${equipped.name}` : `${slot.label}: ${t("rpg.menu.empty")}`;
|
|
201
202
|
});
|
|
202
203
|
const listEmpty = computed(() => listEntries().length === 0);
|
|
203
204
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<DOMContainer width="100%" height="100%" controls={controls}>
|
|
2
2
|
<div class="rpg-ui-menu-panel rpg-ui-panel">
|
|
3
|
-
<div class="rpg-ui-menu-panel-header">
|
|
3
|
+
<div class="rpg-ui-menu-panel-header">{t("rpg.menu.exit")}</div>
|
|
4
4
|
<div class="rpg-ui-menu-panel-body">
|
|
5
5
|
<div class="rpg-ui-menu-panel-details">
|
|
6
|
-
<div class="rpg-ui-menu-panel-details-title">
|
|
6
|
+
<div class="rpg-ui-menu-panel-details-title">{t("rpg.menu.leave-game")}</div>
|
|
7
7
|
<div class="rpg-ui-menu-panel-details-desc">
|
|
8
|
-
|
|
8
|
+
{t("rpg.menu.exit-help")}
|
|
9
9
|
</div>
|
|
10
10
|
</div>
|
|
11
11
|
</div>
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
import { getKeyboardControlBind } from "../../../services/actionInput";
|
|
20
20
|
|
|
21
21
|
const engine = inject(RpgClientEngine);
|
|
22
|
+
const { t } = engine.i18n();
|
|
22
23
|
const keyboardControls = engine.globalConfig.keyboardControls;
|
|
23
24
|
const { onConfirm, onBack } = defineProps();
|
|
24
25
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<DOMContainer width="100%" height="100%">
|
|
2
2
|
<div class="rpg-ui-menu-panel rpg-ui-panel">
|
|
3
|
-
<div class="rpg-ui-menu-panel-header">
|
|
3
|
+
<div class="rpg-ui-menu-panel-header">{t("rpg.menu.items")}</div>
|
|
4
4
|
<div class="rpg-ui-menu-panel-body rpg-ui-menu-panel-body-stacked">
|
|
5
5
|
<div>
|
|
6
6
|
@if (currentItem) {
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
@if (confirmOpen) {
|
|
66
66
|
<div class="rpg-ui-menu-confirm">
|
|
67
67
|
<div class="rpg-ui-menu-confirm-card">
|
|
68
|
-
<div class="rpg-ui-menu-confirm-title">
|
|
68
|
+
<div class="rpg-ui-menu-confirm-title">{t("rpg.menu.use")} {confirmItem()?.name}?</div>
|
|
69
69
|
<Navigation tabindex={selectedConfirm} controls={confirmControls}>
|
|
70
70
|
<div class="rpg-ui-menu-confirm-actions">
|
|
71
71
|
@for ((option,index) of confirmOptions) {
|
|
@@ -93,6 +93,7 @@
|
|
|
93
93
|
import { getKeyboardControlBind } from "../../../services/actionInput";
|
|
94
94
|
|
|
95
95
|
const engine = inject(RpgClientEngine);
|
|
96
|
+
const { t } = engine.i18n();
|
|
96
97
|
const keyboardControls = engine.globalConfig.keyboardControls;
|
|
97
98
|
|
|
98
99
|
const selectedItem = signal(0);
|
|
@@ -106,9 +107,9 @@
|
|
|
106
107
|
const items = computed(() => data().items);
|
|
107
108
|
|
|
108
109
|
const tabs = [
|
|
109
|
-
{ id: "item", label: "
|
|
110
|
-
{ id: "weapon", label: "
|
|
111
|
-
{ id: "armor", label: "
|
|
110
|
+
{ id: "item", label: t("rpg.menu.items") },
|
|
111
|
+
{ id: "weapon", label: t("rpg.menu.weapons") },
|
|
112
|
+
{ id: "armor", label: t("rpg.menu.armor") }
|
|
112
113
|
];
|
|
113
114
|
|
|
114
115
|
const resolveProp = (value) => typeof value === "function" ? value() : value;
|
|
@@ -125,8 +126,8 @@
|
|
|
125
126
|
});
|
|
126
127
|
|
|
127
128
|
const confirmOptions = [
|
|
128
|
-
{ id: "use", label: "
|
|
129
|
-
{ id: "cancel", label: "
|
|
129
|
+
{ id: "use", label: t("rpg.menu.use") },
|
|
130
|
+
{ id: "cancel", label: t("rpg.menu.cancel") }
|
|
130
131
|
];
|
|
131
132
|
|
|
132
133
|
const nav = createTabindexNavigator(selectedItem, { count: () => filteredItems().length }, "wrap");
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<div class="rpg-ui-main-menu rpg-anim-fade-in">
|
|
3
3
|
<div class="rpg-ui-main-menu-layout">
|
|
4
4
|
<div class="rpg-ui-main-menu-left rpg-ui-menu rpg-ui-panel">
|
|
5
|
-
<div class="rpg-ui-menu-header">
|
|
5
|
+
<div class="rpg-ui-menu-header">{t("rpg.menu.title")}</div>
|
|
6
6
|
<div class="rpg-ui-main-menu-list">
|
|
7
7
|
@for ((entry,index) of menuEntries()) {
|
|
8
8
|
<div
|
|
@@ -18,14 +18,14 @@
|
|
|
18
18
|
<div class="rpg-ui-main-menu-right">
|
|
19
19
|
@if (view() === "menu") {
|
|
20
20
|
<div class="rpg-ui-panel">
|
|
21
|
-
<div class="rpg-ui-main-menu-section-title">
|
|
21
|
+
<div class="rpg-ui-main-menu-section-title">{t("rpg.menu.status")}</div>
|
|
22
22
|
<div class="rpg-ui-main-menu-status-card">
|
|
23
23
|
<div class="rpg-ui-main-menu-status-block">
|
|
24
|
-
<div class="rpg-ui-main-menu-status-label">
|
|
24
|
+
<div class="rpg-ui-main-menu-status-label">{t("rpg.menu.level")}</div>
|
|
25
25
|
<div class="rpg-ui-main-menu-status-value">{level()}</div>
|
|
26
26
|
</div>
|
|
27
27
|
<div class="rpg-ui-main-menu-status-block">
|
|
28
|
-
<div class="rpg-ui-main-menu-status-label">
|
|
28
|
+
<div class="rpg-ui-main-menu-status-label">{t("rpg.menu.gold")}</div>
|
|
29
29
|
<div class="rpg-ui-main-menu-status-value">{gold()}</div>
|
|
30
30
|
</div>
|
|
31
31
|
<div class="rpg-ui-main-menu-status-block">
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
</div>
|
|
48
48
|
</div>
|
|
49
49
|
</div>
|
|
50
|
-
<div class="rpg-ui-main-menu-section-title">
|
|
50
|
+
<div class="rpg-ui-main-menu-section-title">{t("rpg.menu.parameters")}</div>
|
|
51
51
|
<div class="rpg-ui-main-menu-params">
|
|
52
52
|
@for ((param,index) of paramsList) {
|
|
53
53
|
<div class="rpg-ui-main-menu-param">
|
|
@@ -104,6 +104,7 @@
|
|
|
104
104
|
import { getKeyboardControlBind } from "../../../services/actionInput";
|
|
105
105
|
|
|
106
106
|
const engine = inject(RpgClientEngine);
|
|
107
|
+
const { t } = engine.i18n();
|
|
107
108
|
const currentPlayer = engine.scene.currentPlayer;
|
|
108
109
|
const keyboardControls = engine.globalConfig.keyboardControls;
|
|
109
110
|
|
|
@@ -111,12 +112,12 @@
|
|
|
111
112
|
const { menus, items, skills, equips, saveLoad } = data();
|
|
112
113
|
|
|
113
114
|
const defaultMenus = [
|
|
114
|
-
{ id: "items", label: "
|
|
115
|
-
{ id: "skills", label: "
|
|
116
|
-
{ id: "equip", label: "
|
|
117
|
-
{ id: "options", label: "
|
|
118
|
-
{ id: "save", label: "
|
|
119
|
-
{ id: "exit", label: "
|
|
115
|
+
{ id: "items", label: t("rpg.menu.items") },
|
|
116
|
+
{ id: "skills", label: t("rpg.menu.skills") },
|
|
117
|
+
{ id: "equip", label: t("rpg.menu.equip") },
|
|
118
|
+
{ id: "options", label: t("rpg.menu.options") },
|
|
119
|
+
{ id: "save", label: t("rpg.menu.save") },
|
|
120
|
+
{ id: "exit", label: t("rpg.menu.exit") }
|
|
120
121
|
];
|
|
121
122
|
|
|
122
123
|
const menuEntries = computed(() => {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<DOMContainer width="100%" height="100%" controls={controls}>
|
|
2
2
|
<div class="rpg-ui-menu-panel rpg-ui-panel">
|
|
3
|
-
<div class="rpg-ui-menu-panel-header">
|
|
3
|
+
<div class="rpg-ui-menu-panel-header">{t("rpg.menu.options")}</div>
|
|
4
4
|
<div class="rpg-ui-menu-panel-body">
|
|
5
5
|
<div class="rpg-ui-menu-panel-details">
|
|
6
|
-
<div class="rpg-ui-menu-panel-details-title">
|
|
6
|
+
<div class="rpg-ui-menu-panel-details-title">{t("rpg.menu.options")}</div>
|
|
7
7
|
<div class="rpg-ui-menu-panel-details-desc">
|
|
8
|
-
|
|
8
|
+
{t("rpg.menu.options-help")}
|
|
9
9
|
</div>
|
|
10
10
|
</div>
|
|
11
11
|
</div>
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
import { RpgClientEngine } from "../../../RpgClientEngine";
|
|
19
19
|
|
|
20
20
|
const engine = inject(RpgClientEngine);
|
|
21
|
+
const { t } = engine.i18n();
|
|
21
22
|
const keyboardControls = engine.globalConfig.keyboardControls;
|
|
22
23
|
const { onBack } = defineProps();
|
|
23
24
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<DOMContainer width="100%" height="100%">
|
|
2
2
|
<div class="rpg-ui-menu-panel rpg-ui-panel">
|
|
3
|
-
<div class="rpg-ui-menu-panel-header">
|
|
3
|
+
<div class="rpg-ui-menu-panel-header">{t("rpg.menu.skills")}</div>
|
|
4
4
|
<div class="rpg-ui-menu-panel-body rpg-ui-menu-panel-body-stacked">
|
|
5
5
|
<div class="rpg-ui-menu-panel-details rpg-ui-panel">
|
|
6
6
|
@if (currentSkill) {
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
import { RpgClientEngine } from "../../../RpgClientEngine";
|
|
39
39
|
|
|
40
40
|
const engine = inject(RpgClientEngine);
|
|
41
|
+
const { t } = engine.i18n();
|
|
41
42
|
const keyboardControls = engine.globalConfig.keyboardControls;
|
|
42
43
|
|
|
43
44
|
const selectedSkill = signal(0);
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
<DOMContainer
|
|
1
|
+
<DOMContainer
|
|
2
|
+
width="100%"
|
|
3
|
+
height="100%"
|
|
4
|
+
zIndex={100}
|
|
5
|
+
class="notification"
|
|
6
|
+
style="pointer-events: none !important;"
|
|
7
|
+
>
|
|
2
8
|
<div class="rpg-ui-notifications">
|
|
3
9
|
@for ((notif,index) of notifications) {
|
|
4
10
|
<div
|
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
<div class="rpg-ui-save-load-slot-index">{item.label}</div>
|
|
18
18
|
@if (item.slot) {
|
|
19
19
|
<div class="rpg-ui-save-load-slot-meta">
|
|
20
|
-
<div class="rpg-ui-save-load-slot-line">
|
|
21
|
-
<div class="rpg-ui-save-load-slot-line">
|
|
22
|
-
<div class="rpg-ui-save-load-slot-line">
|
|
23
|
-
<div class="rpg-ui-save-load-slot-line">
|
|
20
|
+
<div class="rpg-ui-save-load-slot-line">{t("rpg.save.level")}: {item.slot.level ?? "-"}</div>
|
|
21
|
+
<div class="rpg-ui-save-load-slot-line">{t("rpg.save.exp")}: {item.slot.exp ?? "-"}</div>
|
|
22
|
+
<div class="rpg-ui-save-load-slot-line">{t("rpg.save.map")}: {item.slot.map ?? "-"}</div>
|
|
23
|
+
<div class="rpg-ui-save-load-slot-line">{t("rpg.save.date")}: {item.slot.date ?? "-"}</div>
|
|
24
24
|
</div>
|
|
25
25
|
}
|
|
26
26
|
@else {
|
|
27
|
-
<div class="rpg-ui-save-load-slot-empty">
|
|
27
|
+
<div class="rpg-ui-save-load-slot-empty">{t("rpg.save.empty-slot")}</div>
|
|
28
28
|
}
|
|
29
29
|
</div>
|
|
30
30
|
}
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
import { getKeyboardControlBind } from "../../services/actionInput";
|
|
44
44
|
|
|
45
45
|
const engine = inject(RpgClientEngine);
|
|
46
|
+
const { t } = engine.i18n();
|
|
46
47
|
const saveClient = inject(SaveClientService);
|
|
47
48
|
const gui = inject(RpgGui);
|
|
48
49
|
const keyboardControls = engine.globalConfig.keyboardControls;
|
|
@@ -54,10 +55,10 @@
|
|
|
54
55
|
|
|
55
56
|
const { data, onFinish } = defineProps();
|
|
56
57
|
|
|
57
|
-
const title = computed(() => data().mode === "save" ? "
|
|
58
|
+
const title = computed(() => data().mode === "save" ? t("rpg.save.title") : t("rpg.load.title"));
|
|
58
59
|
const subtitle = computed(() => data().mode === "save"
|
|
59
|
-
? "
|
|
60
|
-
: "
|
|
60
|
+
? t("rpg.save.subtitle")
|
|
61
|
+
: t("rpg.load.subtitle")
|
|
61
62
|
);
|
|
62
63
|
|
|
63
64
|
const slotsValue = computed(() => localSlots());
|
|
@@ -67,7 +68,7 @@
|
|
|
67
68
|
kind: "slot",
|
|
68
69
|
slot,
|
|
69
70
|
slotIndex: index,
|
|
70
|
-
label:
|
|
71
|
+
label: t("rpg.save.slot", { index: index + 1 }),
|
|
71
72
|
readonly: false
|
|
72
73
|
}));
|
|
73
74
|
if (!data().showAutoSlot) return items;
|
|
@@ -79,7 +80,7 @@
|
|
|
79
80
|
kind: "auto",
|
|
80
81
|
slot: autoSlot,
|
|
81
82
|
slotIndex: index,
|
|
82
|
-
label: data().autoSlotLabel || "
|
|
83
|
+
label: data().autoSlotLabel || t("rpg.save.auto"),
|
|
83
84
|
readonly
|
|
84
85
|
},
|
|
85
86
|
...items
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<div class="rpg-shop-details rpg-shop-details-mode">
|
|
31
31
|
<div class="rpg-shop-details-header">
|
|
32
32
|
<div class="rpg-shop-details-icon">🛒</div>
|
|
33
|
-
<h2 style="margin: 0;">
|
|
33
|
+
<h2 style="margin: 0;">{t("rpg.shop.choose-action")}</h2>
|
|
34
34
|
</div>
|
|
35
35
|
<div class="rpg-shop-trade">
|
|
36
36
|
<Navigation tabindex={selectedModeIndex} controls={modeControls}>
|
|
@@ -39,12 +39,12 @@
|
|
|
39
39
|
class="rpg-shop-tab"
|
|
40
40
|
class={{active: selectedModeIndex() === 0}}
|
|
41
41
|
click={selectMode('buy')}
|
|
42
|
-
>
|
|
42
|
+
>{t("rpg.shop.buy")}</div>
|
|
43
43
|
<div
|
|
44
44
|
class="rpg-shop-tab"
|
|
45
45
|
class={{active: selectedModeIndex() === 1}}
|
|
46
46
|
click={selectMode('sell')}
|
|
47
|
-
>
|
|
47
|
+
>{t("rpg.shop.sell")}</div>
|
|
48
48
|
</div>
|
|
49
49
|
</Navigation>
|
|
50
50
|
</div>
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
<div class="rpg-shop-card-qty">x{{ item.quantity }}</div>
|
|
89
89
|
}
|
|
90
90
|
@if (item.equipped) {
|
|
91
|
-
<div class="rpg-shop-card-tag">
|
|
91
|
+
<div class="rpg-shop-card-tag">{t("rpg.shop.equipped")}</div>
|
|
92
92
|
}
|
|
93
93
|
</div>
|
|
94
94
|
}
|
|
@@ -109,12 +109,12 @@
|
|
|
109
109
|
<h2 style="margin: 0;">{{ currentItem()?.name || "" }}</h2>
|
|
110
110
|
<p style="color: #ffd700; font-weight: bold; margin: 8px 0;">{{ currentItem()?.price ?? 0 }} {{ goldTerm }}</p>
|
|
111
111
|
@if (currentItem()?.quantity !== undefined) {
|
|
112
|
-
<div class="rpg-shop-details-qty">
|
|
112
|
+
<div class="rpg-shop-details-qty">{t("rpg.shop.qty")}: x{{ currentItem()?.quantity }}</div>
|
|
113
113
|
}
|
|
114
114
|
</div>
|
|
115
115
|
<div>
|
|
116
116
|
@if (currentItem()?.equipped) {
|
|
117
|
-
<div class="rpg-shop-equipped">
|
|
117
|
+
<div class="rpg-shop-equipped">{t("rpg.shop.already-equipped")}</div>
|
|
118
118
|
}
|
|
119
119
|
</div>
|
|
120
120
|
<div class="rpg-shop-details-desc">
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
</div>
|
|
138
138
|
}
|
|
139
139
|
</div>
|
|
140
|
-
<button class="rpg-shop-btn" click={backToMode()}>
|
|
140
|
+
<button class="rpg-shop-btn" click={backToMode()}>{t("rpg.shop.back")}</button>
|
|
141
141
|
</div>
|
|
142
142
|
</div>
|
|
143
143
|
</div>
|
|
@@ -148,10 +148,10 @@
|
|
|
148
148
|
<div class="rpg-shop-modal-title">{{ actionLabel }}</div>
|
|
149
149
|
<div class="rpg-shop-modal-item">{{ currentItem()?.name || "" }}</div>
|
|
150
150
|
@if (currentItem()?.quantity !== undefined) {
|
|
151
|
-
<div class="rpg-shop-modal-qty">
|
|
151
|
+
<div class="rpg-shop-modal-qty">{t("rpg.shop.available")}: x{{ currentItem()?.quantity }}</div>
|
|
152
152
|
}
|
|
153
153
|
<div class="rpg-shop-quantity">
|
|
154
|
-
<div class="rpg-shop-quantity-label">
|
|
154
|
+
<div class="rpg-shop-quantity-label">{t("rpg.shop.quantity")}</div>
|
|
155
155
|
<div class="rpg-shop-quantity-controls">
|
|
156
156
|
<button class="rpg-shop-btn" click={changeQuantity(-1)}>-</button>
|
|
157
157
|
<div class="rpg-shop-quantity-value">{{ quantity }}</div>
|
|
@@ -159,11 +159,11 @@
|
|
|
159
159
|
</div>
|
|
160
160
|
</div>
|
|
161
161
|
<div class="rpg-shop-modal-total">
|
|
162
|
-
<span>
|
|
162
|
+
<span>{t("rpg.shop.total")}</span>
|
|
163
163
|
<span>{{ totalPrice() }} {{ goldTerm }}</span>
|
|
164
164
|
</div>
|
|
165
165
|
<div class="rpg-shop-modal-actions">
|
|
166
|
-
<button class="rpg-shop-btn rpg-shop-btn-secondary" click={closeQuantityDialog()}>
|
|
166
|
+
<button class="rpg-shop-btn rpg-shop-btn-secondary" click={closeQuantityDialog()}>{t("rpg.menu.cancel")}</button>
|
|
167
167
|
<button class="rpg-shop-btn" click={confirmTrade()}>
|
|
168
168
|
{{ actionLabel() }} x{{ quantity() }}
|
|
169
169
|
</button>
|
|
@@ -183,6 +183,7 @@
|
|
|
183
183
|
import { getKeyboardControlBind } from "../../../services/actionInput";
|
|
184
184
|
|
|
185
185
|
const engine = inject(RpgClientEngine)
|
|
186
|
+
const { t } = engine.i18n()
|
|
186
187
|
const currentPlayer = engine.scene.currentPlayer
|
|
187
188
|
const keyboardControls = engine.globalConfig.keyboardControls
|
|
188
189
|
const iconSheet = (iconId) => ({
|
|
@@ -198,11 +199,11 @@
|
|
|
198
199
|
const selectedModeIndex = signal(0)
|
|
199
200
|
const quantity = signal(1)
|
|
200
201
|
const quantityDialogOpen = signal(false)
|
|
201
|
-
const defaultMessage =
|
|
202
|
+
const defaultMessage = t("rpg.shop.default-message")
|
|
202
203
|
const tabs = [
|
|
203
|
-
{ id: 'item', label:
|
|
204
|
-
{ id: 'weapon', label:
|
|
205
|
-
{ id: 'armor', label:
|
|
204
|
+
{ id: 'item', label: t("rpg.menu.items") },
|
|
205
|
+
{ id: 'weapon', label: t("rpg.menu.weapons") },
|
|
206
|
+
{ id: 'armor', label: t("rpg.menu.armor") }
|
|
206
207
|
]
|
|
207
208
|
|
|
208
209
|
const { data, onInteraction , onFinish } = defineProps()
|
|
@@ -229,7 +230,7 @@
|
|
|
229
230
|
})
|
|
230
231
|
const currentItem = computed(() => filteredItems()[selectedItem()])
|
|
231
232
|
const gold = computed(() => currentPlayer()._gold())
|
|
232
|
-
const actionLabel = computed(() => tradeMode() === 'buy' ?
|
|
233
|
+
const actionLabel = computed(() => tradeMode() === 'buy' ? t("rpg.shop.buy") : t("rpg.shop.sell"))
|
|
233
234
|
const faceSheet = (graphicId, animationName) => ({
|
|
234
235
|
definition: engine.getSpriteSheet(graphicId),
|
|
235
236
|
playing: animationName || "default"
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
import { getKeyboardControlBind } from "../../services/actionInput";
|
|
35
35
|
|
|
36
36
|
const engine = inject(RpgClientEngine);
|
|
37
|
+
const { t } = engine.i18n();
|
|
37
38
|
const guiService = inject(RpgGui);
|
|
38
39
|
const keyboardControls = engine.globalConfig.keyboardControls;
|
|
39
40
|
|
|
@@ -52,12 +53,12 @@
|
|
|
52
53
|
const { entries, title, subtitle, version, saveLoad, localActions } = data();
|
|
53
54
|
|
|
54
55
|
const defaultEntries = [
|
|
55
|
-
{ id: "start", label: "
|
|
56
|
-
{ id: "load", label: "
|
|
56
|
+
{ id: "start", label: t("rpg.title.start") },
|
|
57
|
+
{ id: "load", label: t("rpg.title.load") }
|
|
57
58
|
];
|
|
58
59
|
|
|
59
60
|
const resolveProp = (value) => typeof value === "function" ? value() : value;
|
|
60
|
-
const titleText = computed(() => resolveProp(title) || "
|
|
61
|
+
const titleText = computed(() => resolveProp(title) || t("rpg.title.default"));
|
|
61
62
|
const subtitleText = computed(() => resolveProp(subtitle) || "");
|
|
62
63
|
const versionText = computed(() => resolveProp(version) || "");
|
|
63
64
|
const localActionsEnabled = computed(() => resolveProp(localActions) === true);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<Container>
|
|
2
|
+
@for (entry of renderedComponents) {
|
|
3
|
+
<Container dependencies={entry.dependencies}>
|
|
4
|
+
<entry.component ...entry.props />
|
|
5
|
+
</Container>
|
|
6
|
+
}
|
|
7
|
+
</Container>
|
|
8
|
+
|
|
9
|
+
<script>
|
|
10
|
+
import { computed } from "canvasengine";
|
|
11
|
+
import { RpgClientEngine } from "../RpgClientEngine";
|
|
12
|
+
import { inject } from "../core/inject";
|
|
13
|
+
|
|
14
|
+
const { object, bounds, hitboxBounds, graphicBounds } = defineProps();
|
|
15
|
+
const client = inject(RpgClientEngine);
|
|
16
|
+
const sprite = object();
|
|
17
|
+
|
|
18
|
+
const renderedComponents = computed(() => client.interactions.getRenderedComponents(sprite, {
|
|
19
|
+
bounds: typeof bounds === "function" ? bounds() : undefined,
|
|
20
|
+
hitbox: typeof hitboxBounds === "function" ? hitboxBounds() : undefined,
|
|
21
|
+
graphic: typeof graphicBounds === "function" ? graphicBounds() : undefined,
|
|
22
|
+
}));
|
|
23
|
+
</script>
|