@vylos/core 0.4.2 → 0.4.4
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/package.json
CHANGED
|
@@ -6,28 +6,31 @@
|
|
|
6
6
|
<!-- z-10: Foreground / character sprites -->
|
|
7
7
|
<ForegroundLayer />
|
|
8
8
|
|
|
9
|
-
<!--
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
9
|
+
<!-- UI layer — hidden with H key (Ren'Py style) -->
|
|
10
|
+
<template v-if="!engineState.uiHidden">
|
|
11
|
+
<!-- z-15–25: HUD (hidden during dialogue/choices) -->
|
|
12
|
+
<template v-if="!hideHud">
|
|
13
|
+
<DrawableOverlay />
|
|
14
|
+
<LocationOverlay />
|
|
15
|
+
<ActionOverlay />
|
|
16
|
+
<TopBar />
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<!-- z-30: Dialogue box -->
|
|
20
|
+
<DialogueBox />
|
|
21
|
+
|
|
22
|
+
<!-- z-35: Choice panel (inside DialogueBox z-range) -->
|
|
23
|
+
<ChoicePanel />
|
|
24
|
+
|
|
25
|
+
<!-- z-40: Custom overlay -->
|
|
26
|
+
<CustomOverlay />
|
|
27
|
+
</template>
|
|
27
28
|
</div>
|
|
28
29
|
</template>
|
|
29
30
|
|
|
30
31
|
<script setup lang="ts">
|
|
32
|
+
import { computed } from 'vue';
|
|
33
|
+
import { useEngineStateStore } from '../../stores/engineState';
|
|
31
34
|
import BackgroundLayer from '../core/BackgroundLayer.vue';
|
|
32
35
|
import ForegroundLayer from '../core/ForegroundLayer.vue';
|
|
33
36
|
import DrawableOverlay from '../core/DrawableOverlay.vue';
|
|
@@ -37,4 +40,7 @@ import CustomOverlay from '../core/CustomOverlay.vue';
|
|
|
37
40
|
import ActionOverlay from '../menu/ActionOverlay.vue';
|
|
38
41
|
import LocationOverlay from '../menu/LocationOverlay.vue';
|
|
39
42
|
import TopBar from '../menu/TopBar.vue';
|
|
43
|
+
|
|
44
|
+
const engineState = useEngineStateStore();
|
|
45
|
+
const hideHud = computed(() => !!engineState.dialogue || !!engineState.choices);
|
|
40
46
|
</script>
|
|
@@ -184,6 +184,13 @@ function handleForward(): void {
|
|
|
184
184
|
|
|
185
185
|
function handleViewportClick(e: MouseEvent): void {
|
|
186
186
|
if (!engine) return;
|
|
187
|
+
|
|
188
|
+
// Any click unhides UI
|
|
189
|
+
if (engineState.uiHidden) {
|
|
190
|
+
engineState.uiHidden = false;
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
|
|
187
194
|
// Only during Running phase, no menu open, no choices showing
|
|
188
195
|
if (!isRunning.value || engineState.menuOpen || engineState.choices) return;
|
|
189
196
|
|
|
@@ -211,6 +218,18 @@ onMounted(() => {
|
|
|
211
218
|
return;
|
|
212
219
|
}
|
|
213
220
|
|
|
221
|
+
// H toggles UI visibility
|
|
222
|
+
if (action === 'hide-ui') {
|
|
223
|
+
engineState.uiHidden = !engineState.uiHidden;
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Any other key unhides UI first
|
|
228
|
+
if (engineState.uiHidden) {
|
|
229
|
+
engineState.uiHidden = false;
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
|
|
214
233
|
switch (action) {
|
|
215
234
|
case 'continue':
|
|
216
235
|
handleKeyboardContinue();
|
|
@@ -1,27 +1,32 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<Transition name="dlg-slide">
|
|
3
3
|
<div
|
|
4
|
-
v-if="engineState.dialogue"
|
|
5
|
-
class="
|
|
6
|
-
@click="handleClick"
|
|
4
|
+
v-if="engineState.dialogue && !engineState.overlayId"
|
|
5
|
+
class="absolute bottom-0 left-0 right-0 z-30 p-[2cqh_2cqw] pointer-events-none select-none"
|
|
7
6
|
>
|
|
8
|
-
<div
|
|
7
|
+
<div
|
|
8
|
+
class="bg-black/80 border border-white/20 rounded-[1cqw] p-[2cqh_2.5cqw] max-w-[85cqw] mx-auto transition-colors duration-200"
|
|
9
|
+
:class="{ 'border-blue-300/40': engineState.historyBrowsing }"
|
|
10
|
+
>
|
|
9
11
|
<!-- Speaker name -->
|
|
10
12
|
<div
|
|
11
13
|
v-if="engineState.dialogue.speaker"
|
|
12
|
-
class="
|
|
14
|
+
class="font-bold text-[1.8cqw] mb-[1cqh] uppercase tracking-wider text-yellow-300"
|
|
13
15
|
:style="engineState.dialogue.speaker.color ? { color: engineState.dialogue.speaker.color } : undefined"
|
|
14
16
|
>
|
|
15
17
|
{{ speakerName }}
|
|
16
18
|
</div>
|
|
17
19
|
|
|
18
20
|
<!-- Dialogue text -->
|
|
19
|
-
<p
|
|
21
|
+
<p
|
|
22
|
+
class="text-white text-[2cqw] leading-relaxed m-0"
|
|
23
|
+
:class="{ 'italic text-white/80': engineState.dialogue.isNarration }"
|
|
24
|
+
>
|
|
20
25
|
{{ engineState.dialogue.text }}
|
|
21
26
|
</p>
|
|
22
27
|
|
|
23
28
|
<!-- Continue / History indicator -->
|
|
24
|
-
<div class="
|
|
29
|
+
<div class="text-right text-white/40 text-[1.2cqw] mt-[1cqh]">
|
|
25
30
|
<template v-if="engineState.historyBrowsing">
|
|
26
31
|
◀ ▶ history
|
|
27
32
|
</template>
|
|
@@ -35,14 +40,11 @@
|
|
|
35
40
|
</template>
|
|
36
41
|
|
|
37
42
|
<script setup lang="ts">
|
|
38
|
-
import {
|
|
43
|
+
import { computed } from 'vue';
|
|
39
44
|
import { useEngineStateStore } from '../../stores/engineState';
|
|
40
|
-
import { ENGINE_INJECT_KEY } from '../../composables/useEngine';
|
|
41
45
|
import { useLanguage } from '../../composables/useLanguage';
|
|
42
|
-
import type { Engine } from '../../engine/core/Engine';
|
|
43
46
|
|
|
44
47
|
const engineState = useEngineStateStore();
|
|
45
|
-
const engine = inject<Engine>(ENGINE_INJECT_KEY);
|
|
46
48
|
const { resolveText } = useLanguage();
|
|
47
49
|
|
|
48
50
|
const speakerName = computed(() => {
|
|
@@ -50,44 +52,6 @@ const speakerName = computed(() => {
|
|
|
50
52
|
if (!speaker) return '';
|
|
51
53
|
return resolveText(speaker.name);
|
|
52
54
|
});
|
|
53
|
-
|
|
54
|
-
function handleClick(): void {
|
|
55
|
-
if (!engine) return;
|
|
56
|
-
|
|
57
|
-
if (engine.eventRunner.isBrowsingHistory) {
|
|
58
|
-
// In history mode — advance through history (click = forward)
|
|
59
|
-
const step = engine.eventRunner.historyForward();
|
|
60
|
-
if (step) {
|
|
61
|
-
if (step.type === 'say' && step.dialogue) {
|
|
62
|
-
engineState.setDialogue(step.dialogue);
|
|
63
|
-
engineState.setChoices(null);
|
|
64
|
-
} else if (step.type === 'choice' && step.choiceOptions) {
|
|
65
|
-
engineState.setDialogue(null);
|
|
66
|
-
engineState.setChoices({
|
|
67
|
-
prompt: null,
|
|
68
|
-
options: step.choiceOptions,
|
|
69
|
-
historyStepIndex: step.stepIndex,
|
|
70
|
-
historySelectedValue: step.choiceResult,
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
if (!engine.eventRunner.isBrowsingHistory) {
|
|
75
|
-
engineState.historyBrowsing = false;
|
|
76
|
-
const live = engine.eventRunner.getLiveDialogue();
|
|
77
|
-
if (live) {
|
|
78
|
-
engineState.setDialogue({
|
|
79
|
-
text: live.text,
|
|
80
|
-
speaker: live.speaker,
|
|
81
|
-
isNarration: !live.speaker,
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
engineState.setChoices(null);
|
|
85
|
-
}
|
|
86
|
-
} else {
|
|
87
|
-
// Normal mode — resolve the wait to advance dialogue
|
|
88
|
-
engine.eventRunner.resolveWait();
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
55
|
</script>
|
|
92
56
|
|
|
93
57
|
<style scoped>
|
|
@@ -100,57 +64,4 @@ function handleClick(): void {
|
|
|
100
64
|
transform: translateY(100%);
|
|
101
65
|
opacity: 0;
|
|
102
66
|
}
|
|
103
|
-
|
|
104
|
-
.dlg-wrapper {
|
|
105
|
-
position: absolute;
|
|
106
|
-
bottom: 0;
|
|
107
|
-
left: 0;
|
|
108
|
-
right: 0;
|
|
109
|
-
z-index: 30;
|
|
110
|
-
padding: 2cqh 2cqw;
|
|
111
|
-
cursor: pointer;
|
|
112
|
-
user-select: none;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
.dlg-box {
|
|
116
|
-
background: rgba(0, 0, 0, 0.8);
|
|
117
|
-
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
118
|
-
border-radius: 1cqw;
|
|
119
|
-
padding: 2cqh 2.5cqw;
|
|
120
|
-
max-width: 85cqw;
|
|
121
|
-
margin: 0 auto;
|
|
122
|
-
transition: border-color 0.2s ease;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
.dlg-box--history {
|
|
126
|
-
border-color: rgba(147, 197, 253, 0.4);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
.dlg-speaker {
|
|
130
|
-
color: #fde047; /* default — overridden by Character.color via :style */
|
|
131
|
-
font-weight: 700;
|
|
132
|
-
font-size: 1.8cqw;
|
|
133
|
-
margin-bottom: 1cqh;
|
|
134
|
-
text-transform: uppercase;
|
|
135
|
-
letter-spacing: 0.05em;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
.dlg-text {
|
|
139
|
-
color: white;
|
|
140
|
-
font-size: 2cqw;
|
|
141
|
-
line-height: 1.6;
|
|
142
|
-
margin: 0;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
.dlg-text--narration {
|
|
146
|
-
font-style: italic;
|
|
147
|
-
color: rgba(255, 255, 255, 0.8);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
.dlg-continue {
|
|
151
|
-
text-align: right;
|
|
152
|
-
color: rgba(255, 255, 255, 0.4);
|
|
153
|
-
font-size: 1.2cqw;
|
|
154
|
-
margin-top: 1cqh;
|
|
155
|
-
}
|
|
156
67
|
</style>
|
|
@@ -89,10 +89,14 @@ export class InputManager {
|
|
|
89
89
|
if (key === 'ArrowRight') return 'forward';
|
|
90
90
|
if (key === 'ArrowLeft') return 'back';
|
|
91
91
|
|
|
92
|
+
// Hide UI toggle (Ren'Py style)
|
|
93
|
+
if (key === 'h' || key === 'H') return 'hide-ui';
|
|
94
|
+
|
|
92
95
|
// Skip toggle — same key on both layouts
|
|
93
96
|
if (key === 's' || key === 'S') return 'skip-toggle';
|
|
94
97
|
|
|
95
|
-
// Forward
|
|
98
|
+
// Forward / continue: D on both layouts, E on both layouts
|
|
99
|
+
if (key === 'd' || key === 'D') return 'forward';
|
|
96
100
|
if (key === 'e' || key === 'E') return 'continue';
|
|
97
101
|
|
|
98
102
|
// Layout-dependent back key
|
|
@@ -23,6 +23,7 @@ export const useEngineStateStore = defineStore('engineState', () => {
|
|
|
23
23
|
const skipMode = ref(false);
|
|
24
24
|
const autoMode = ref(false);
|
|
25
25
|
const historyBrowsing = ref(false);
|
|
26
|
+
const uiHidden = ref(false);
|
|
26
27
|
const drawableEvents = ref<DrawableEventEntry[]>([]);
|
|
27
28
|
const overlayId = ref<string | null>(null);
|
|
28
29
|
const overlayProps = ref<Record<string, unknown> | null>(null);
|
|
@@ -89,6 +90,7 @@ export const useEngineStateStore = defineStore('engineState', () => {
|
|
|
89
90
|
skipMode.value = false;
|
|
90
91
|
autoMode.value = false;
|
|
91
92
|
historyBrowsing.value = false;
|
|
93
|
+
uiHidden.value = false;
|
|
92
94
|
drawableEvents.value = [];
|
|
93
95
|
overlayId.value = null;
|
|
94
96
|
overlayProps.value = null;
|
|
@@ -107,6 +109,7 @@ export const useEngineStateStore = defineStore('engineState', () => {
|
|
|
107
109
|
skipMode,
|
|
108
110
|
autoMode,
|
|
109
111
|
historyBrowsing,
|
|
112
|
+
uiHidden,
|
|
110
113
|
drawableEvents,
|
|
111
114
|
overlayId,
|
|
112
115
|
overlayProps,
|