@doodle-engine/core 0.0.8 → 0.0.10
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 +12 -0
- package/dist/core.cjs +2 -2
- package/dist/core.js +582 -536
- package/dist/effects/index.d.ts.map +1 -1
- package/dist/engine/index.d.ts +9 -0
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/parser/index.d.ts.map +1 -1
- package/dist/snapshot/index.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/effects.d.ts +10 -1
- package/dist/types/effects.d.ts.map +1 -1
- package/dist/types/entities.d.ts +28 -0
- package/dist/types/entities.d.ts.map +1 -1
- package/dist/types/registry.d.ts +3 -1
- package/dist/types/registry.d.ts.map +1 -1
- package/dist/types/snapshot.d.ts +25 -0
- package/dist/types/snapshot.d.ts.map +1 -1
- package/dist/types/state.d.ts +2 -0
- package/dist/types/state.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/core.js
CHANGED
|
@@ -1,441 +1,465 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
function O(
|
|
5
|
-
switch (
|
|
1
|
+
var x = Object.defineProperty;
|
|
2
|
+
var k = (t, e, n) => e in t ? x(t, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : t[e] = n;
|
|
3
|
+
var T = (t, e, n) => k(t, typeof e != "symbol" ? e + "" : e, n);
|
|
4
|
+
function O(t, e) {
|
|
5
|
+
switch (t.type) {
|
|
6
6
|
case "hasFlag":
|
|
7
|
-
return
|
|
7
|
+
return V(t.flag, e);
|
|
8
8
|
case "notFlag":
|
|
9
|
-
return
|
|
9
|
+
return R(t.flag, e);
|
|
10
10
|
case "hasItem":
|
|
11
|
-
return
|
|
11
|
+
return D(t.itemId, e);
|
|
12
12
|
case "variableEquals":
|
|
13
|
-
return
|
|
13
|
+
return P(t.variable, t.value, e);
|
|
14
14
|
case "variableGreaterThan":
|
|
15
|
-
return
|
|
15
|
+
return $(t.variable, t.value, e);
|
|
16
16
|
case "variableLessThan":
|
|
17
|
-
return
|
|
17
|
+
return q(t.variable, t.value, e);
|
|
18
18
|
case "atLocation":
|
|
19
|
-
return
|
|
19
|
+
return F(t.locationId, e);
|
|
20
20
|
case "questAtStage":
|
|
21
|
-
return
|
|
21
|
+
return W(t.questId, t.stageId, e);
|
|
22
22
|
case "characterAt":
|
|
23
|
-
return
|
|
23
|
+
return M(t.characterId, t.locationId, e);
|
|
24
24
|
case "characterInParty":
|
|
25
|
-
return
|
|
25
|
+
return G(t.characterId, e);
|
|
26
26
|
case "relationshipAbove":
|
|
27
|
-
return
|
|
27
|
+
return H(t.characterId, t.value, e);
|
|
28
28
|
case "relationshipBelow":
|
|
29
|
-
return
|
|
29
|
+
return j(t.characterId, t.value, e);
|
|
30
30
|
case "timeIs":
|
|
31
|
-
return
|
|
31
|
+
return Q(t.startHour, t.endHour, e);
|
|
32
32
|
case "itemAt":
|
|
33
|
-
return
|
|
33
|
+
return J(t.itemId, t.locationId, e);
|
|
34
34
|
default:
|
|
35
35
|
return !1;
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
function
|
|
39
|
-
return
|
|
38
|
+
function v(t, e) {
|
|
39
|
+
return t.every((n) => O(n, e));
|
|
40
40
|
}
|
|
41
|
-
function
|
|
42
|
-
return
|
|
41
|
+
function V(t, e) {
|
|
42
|
+
return e.flags[t] === !0;
|
|
43
43
|
}
|
|
44
|
-
function
|
|
45
|
-
return
|
|
44
|
+
function R(t, e) {
|
|
45
|
+
return e.flags[t] !== !0;
|
|
46
46
|
}
|
|
47
|
-
function
|
|
48
|
-
return
|
|
47
|
+
function D(t, e) {
|
|
48
|
+
return e.inventory.includes(t);
|
|
49
49
|
}
|
|
50
|
-
function
|
|
51
|
-
return
|
|
50
|
+
function P(t, e, n) {
|
|
51
|
+
return n.variables[t] === e;
|
|
52
52
|
}
|
|
53
|
-
function
|
|
54
|
-
const r =
|
|
55
|
-
return typeof r == "number" && r >
|
|
53
|
+
function $(t, e, n) {
|
|
54
|
+
const r = n.variables[t];
|
|
55
|
+
return typeof r == "number" && r > e;
|
|
56
56
|
}
|
|
57
|
-
function
|
|
58
|
-
const r =
|
|
59
|
-
return typeof r == "number" && r <
|
|
57
|
+
function q(t, e, n) {
|
|
58
|
+
const r = n.variables[t];
|
|
59
|
+
return typeof r == "number" && r < e;
|
|
60
60
|
}
|
|
61
|
-
function
|
|
62
|
-
return
|
|
61
|
+
function F(t, e) {
|
|
62
|
+
return e.currentLocation === t;
|
|
63
63
|
}
|
|
64
|
-
function
|
|
65
|
-
return
|
|
64
|
+
function W(t, e, n) {
|
|
65
|
+
return n.questProgress[t] === e;
|
|
66
66
|
}
|
|
67
|
-
function
|
|
68
|
-
const r =
|
|
69
|
-
return (r == null ? void 0 : r.location) ===
|
|
67
|
+
function M(t, e, n) {
|
|
68
|
+
const r = n.characterState[t];
|
|
69
|
+
return (r == null ? void 0 : r.location) === e;
|
|
70
70
|
}
|
|
71
|
-
function
|
|
72
|
-
const
|
|
73
|
-
return (
|
|
71
|
+
function G(t, e) {
|
|
72
|
+
const n = e.characterState[t];
|
|
73
|
+
return (n == null ? void 0 : n.inParty) === !0;
|
|
74
74
|
}
|
|
75
|
-
function
|
|
76
|
-
const r =
|
|
77
|
-
return r !== void 0 && r.relationship >
|
|
75
|
+
function H(t, e, n) {
|
|
76
|
+
const r = n.characterState[t];
|
|
77
|
+
return r !== void 0 && r.relationship > e;
|
|
78
78
|
}
|
|
79
|
-
function
|
|
80
|
-
const r =
|
|
81
|
-
return r !== void 0 && r.relationship <
|
|
79
|
+
function j(t, e, n) {
|
|
80
|
+
const r = n.characterState[t];
|
|
81
|
+
return r !== void 0 && r.relationship < e;
|
|
82
82
|
}
|
|
83
|
-
function
|
|
84
|
-
const r =
|
|
85
|
-
return
|
|
83
|
+
function Q(t, e, n) {
|
|
84
|
+
const r = n.currentTime.hour;
|
|
85
|
+
return t < e ? r >= t && r < e : r >= t || r < e;
|
|
86
86
|
}
|
|
87
|
-
function
|
|
88
|
-
return
|
|
87
|
+
function J(t, e, n) {
|
|
88
|
+
return n.itemLocations[t] === e;
|
|
89
89
|
}
|
|
90
|
-
function
|
|
91
|
-
switch (
|
|
90
|
+
function U(t, e) {
|
|
91
|
+
switch (t.type) {
|
|
92
92
|
case "setFlag":
|
|
93
|
-
return
|
|
93
|
+
return B(t.flag, e);
|
|
94
94
|
case "clearFlag":
|
|
95
|
-
return
|
|
95
|
+
return _(t.flag, e);
|
|
96
96
|
case "setVariable":
|
|
97
|
-
return
|
|
97
|
+
return z(t.variable, t.value, e);
|
|
98
98
|
case "addVariable":
|
|
99
|
-
return
|
|
99
|
+
return Y(t.variable, t.value, e);
|
|
100
100
|
case "addItem":
|
|
101
|
-
return
|
|
101
|
+
return K(t.itemId, e);
|
|
102
102
|
case "removeItem":
|
|
103
|
-
return
|
|
103
|
+
return X(t.itemId, e);
|
|
104
104
|
case "moveItem":
|
|
105
|
-
return
|
|
105
|
+
return Z(t.itemId, t.locationId, e);
|
|
106
106
|
case "goToLocation":
|
|
107
|
-
return
|
|
107
|
+
return ee(t.locationId, e);
|
|
108
108
|
case "advanceTime":
|
|
109
|
-
return
|
|
109
|
+
return te(t.hours, e);
|
|
110
110
|
case "setQuestStage":
|
|
111
|
-
return
|
|
111
|
+
return ne(t.questId, t.stageId, e);
|
|
112
112
|
case "addJournalEntry":
|
|
113
|
-
return
|
|
113
|
+
return re(t.entryId, e);
|
|
114
114
|
case "startDialogue":
|
|
115
|
-
return
|
|
115
|
+
return ae(t.dialogueId, e);
|
|
116
116
|
case "endDialogue":
|
|
117
|
-
return
|
|
117
|
+
return ie(e);
|
|
118
118
|
case "setCharacterLocation":
|
|
119
|
-
return
|
|
119
|
+
return se(t.characterId, t.locationId, e);
|
|
120
120
|
case "addToParty":
|
|
121
|
-
return
|
|
121
|
+
return oe(t.characterId, e);
|
|
122
122
|
case "removeFromParty":
|
|
123
|
-
return
|
|
123
|
+
return le(t.characterId, e);
|
|
124
124
|
case "setRelationship":
|
|
125
|
-
return
|
|
125
|
+
return ce(t.characterId, t.value, e);
|
|
126
126
|
case "addRelationship":
|
|
127
|
-
return
|
|
127
|
+
return ue(t.characterId, t.value, e);
|
|
128
128
|
case "setCharacterStat":
|
|
129
|
-
return
|
|
129
|
+
return de(t.characterId, t.stat, t.value, e);
|
|
130
130
|
case "addCharacterStat":
|
|
131
|
-
return
|
|
131
|
+
return he(t.characterId, t.stat, t.value, e);
|
|
132
132
|
case "setMapEnabled":
|
|
133
|
-
return
|
|
133
|
+
return pe(t.enabled, e);
|
|
134
134
|
case "playMusic":
|
|
135
|
-
return
|
|
135
|
+
return e;
|
|
136
136
|
case "playSound":
|
|
137
|
-
return
|
|
137
|
+
return fe(t.sound, e);
|
|
138
138
|
case "notify":
|
|
139
|
-
return
|
|
139
|
+
return ge(t.message, e);
|
|
140
140
|
case "playVideo":
|
|
141
|
-
return
|
|
141
|
+
return me(t.file, e);
|
|
142
|
+
case "showInterlude":
|
|
143
|
+
return be(t.interludeId, e);
|
|
142
144
|
default:
|
|
143
|
-
return
|
|
145
|
+
return e;
|
|
144
146
|
}
|
|
145
147
|
}
|
|
146
|
-
function
|
|
147
|
-
return
|
|
148
|
+
function S(t, e) {
|
|
149
|
+
return t.reduce((n, r) => U(r, n), e);
|
|
148
150
|
}
|
|
149
|
-
function
|
|
151
|
+
function B(t, e) {
|
|
150
152
|
return {
|
|
151
|
-
...
|
|
153
|
+
...e,
|
|
152
154
|
flags: {
|
|
153
|
-
...
|
|
154
|
-
[
|
|
155
|
+
...e.flags,
|
|
156
|
+
[t]: !0
|
|
155
157
|
}
|
|
156
158
|
};
|
|
157
159
|
}
|
|
158
|
-
function
|
|
160
|
+
function _(t, e) {
|
|
159
161
|
return {
|
|
160
|
-
...
|
|
162
|
+
...e,
|
|
161
163
|
flags: {
|
|
162
|
-
...
|
|
163
|
-
[
|
|
164
|
+
...e.flags,
|
|
165
|
+
[t]: !1
|
|
164
166
|
}
|
|
165
167
|
};
|
|
166
168
|
}
|
|
167
|
-
function
|
|
169
|
+
function z(t, e, n) {
|
|
168
170
|
return {
|
|
169
|
-
...
|
|
171
|
+
...n,
|
|
170
172
|
variables: {
|
|
171
|
-
...
|
|
172
|
-
[
|
|
173
|
+
...n.variables,
|
|
174
|
+
[t]: e
|
|
173
175
|
}
|
|
174
176
|
};
|
|
175
177
|
}
|
|
176
|
-
function
|
|
177
|
-
const r =
|
|
178
|
+
function Y(t, e, n) {
|
|
179
|
+
const r = n.variables[t], a = typeof r == "number" ? r + e : e;
|
|
178
180
|
return {
|
|
179
|
-
...
|
|
181
|
+
...n,
|
|
180
182
|
variables: {
|
|
181
|
-
...
|
|
182
|
-
[
|
|
183
|
+
...n.variables,
|
|
184
|
+
[t]: a
|
|
183
185
|
}
|
|
184
186
|
};
|
|
185
187
|
}
|
|
186
|
-
function
|
|
187
|
-
return
|
|
188
|
-
...
|
|
189
|
-
inventory: [...
|
|
188
|
+
function K(t, e) {
|
|
189
|
+
return e.inventory.includes(t) ? e : {
|
|
190
|
+
...e,
|
|
191
|
+
inventory: [...e.inventory, t],
|
|
190
192
|
itemLocations: {
|
|
191
|
-
...
|
|
192
|
-
[
|
|
193
|
+
...e.itemLocations,
|
|
194
|
+
[t]: "inventory"
|
|
193
195
|
}
|
|
194
196
|
};
|
|
195
197
|
}
|
|
196
|
-
function
|
|
198
|
+
function X(t, e) {
|
|
197
199
|
return {
|
|
198
|
-
...
|
|
199
|
-
inventory:
|
|
200
|
+
...e,
|
|
201
|
+
inventory: e.inventory.filter((n) => n !== t)
|
|
200
202
|
// Note: itemLocation is NOT updated here - the item stays at "inventory"
|
|
201
203
|
// or wherever it was. Use moveItem to relocate it.
|
|
202
204
|
};
|
|
203
205
|
}
|
|
204
|
-
function
|
|
206
|
+
function Z(t, e, n) {
|
|
205
207
|
return {
|
|
206
|
-
...
|
|
207
|
-
inventory:
|
|
208
|
+
...n,
|
|
209
|
+
inventory: n.inventory.filter((r) => r !== t),
|
|
208
210
|
itemLocations: {
|
|
209
|
-
...
|
|
210
|
-
[
|
|
211
|
+
...n.itemLocations,
|
|
212
|
+
[t]: e
|
|
211
213
|
}
|
|
212
214
|
};
|
|
213
215
|
}
|
|
214
|
-
function
|
|
216
|
+
function ee(t, e) {
|
|
215
217
|
return {
|
|
216
|
-
...
|
|
217
|
-
currentLocation:
|
|
218
|
+
...e,
|
|
219
|
+
currentLocation: t
|
|
218
220
|
};
|
|
219
221
|
}
|
|
220
|
-
function
|
|
221
|
-
const
|
|
222
|
+
function te(t, e) {
|
|
223
|
+
const n = e.currentTime.hour + t, r = Math.floor(n / 24), a = n % 24;
|
|
222
224
|
return {
|
|
223
|
-
...
|
|
225
|
+
...e,
|
|
224
226
|
currentTime: {
|
|
225
|
-
day:
|
|
227
|
+
day: e.currentTime.day + r,
|
|
226
228
|
hour: a
|
|
227
229
|
}
|
|
228
230
|
};
|
|
229
231
|
}
|
|
230
|
-
function
|
|
232
|
+
function ne(t, e, n) {
|
|
231
233
|
return {
|
|
232
|
-
...
|
|
234
|
+
...n,
|
|
233
235
|
questProgress: {
|
|
234
|
-
...
|
|
235
|
-
[
|
|
236
|
+
...n.questProgress,
|
|
237
|
+
[t]: e
|
|
236
238
|
}
|
|
237
239
|
};
|
|
238
240
|
}
|
|
239
|
-
function
|
|
240
|
-
return
|
|
241
|
-
...
|
|
242
|
-
unlockedJournalEntries: [...
|
|
241
|
+
function re(t, e) {
|
|
242
|
+
return e.unlockedJournalEntries.includes(t) ? e : {
|
|
243
|
+
...e,
|
|
244
|
+
unlockedJournalEntries: [...e.unlockedJournalEntries, t]
|
|
243
245
|
};
|
|
244
246
|
}
|
|
245
|
-
function
|
|
247
|
+
function ae(t, e) {
|
|
246
248
|
return {
|
|
247
|
-
...
|
|
249
|
+
...e,
|
|
248
250
|
dialogueState: {
|
|
249
|
-
dialogueId:
|
|
251
|
+
dialogueId: t,
|
|
250
252
|
nodeId: ""
|
|
251
253
|
// Will be set by engine when it looks up the dialogue
|
|
252
254
|
}
|
|
253
255
|
};
|
|
254
256
|
}
|
|
255
|
-
function
|
|
257
|
+
function ie(t) {
|
|
256
258
|
return {
|
|
257
|
-
...
|
|
259
|
+
...t,
|
|
258
260
|
dialogueState: null
|
|
259
261
|
};
|
|
260
262
|
}
|
|
261
|
-
function
|
|
262
|
-
const r =
|
|
263
|
+
function se(t, e, n) {
|
|
264
|
+
const r = n.characterState[t];
|
|
263
265
|
return r ? {
|
|
264
|
-
...
|
|
266
|
+
...n,
|
|
265
267
|
characterState: {
|
|
266
|
-
...
|
|
267
|
-
[
|
|
268
|
+
...n.characterState,
|
|
269
|
+
[t]: {
|
|
268
270
|
...r,
|
|
269
|
-
location:
|
|
271
|
+
location: e
|
|
270
272
|
}
|
|
271
273
|
}
|
|
272
|
-
} :
|
|
274
|
+
} : n;
|
|
273
275
|
}
|
|
274
|
-
function
|
|
275
|
-
const
|
|
276
|
-
return
|
|
277
|
-
...
|
|
276
|
+
function oe(t, e) {
|
|
277
|
+
const n = e.characterState[t];
|
|
278
|
+
return n ? {
|
|
279
|
+
...e,
|
|
278
280
|
characterState: {
|
|
279
|
-
...
|
|
280
|
-
[
|
|
281
|
-
...
|
|
281
|
+
...e.characterState,
|
|
282
|
+
[t]: {
|
|
283
|
+
...n,
|
|
282
284
|
inParty: !0
|
|
283
285
|
}
|
|
284
286
|
}
|
|
285
|
-
} :
|
|
287
|
+
} : e;
|
|
286
288
|
}
|
|
287
|
-
function
|
|
288
|
-
const
|
|
289
|
-
return
|
|
290
|
-
...
|
|
289
|
+
function le(t, e) {
|
|
290
|
+
const n = e.characterState[t];
|
|
291
|
+
return n ? {
|
|
292
|
+
...e,
|
|
291
293
|
characterState: {
|
|
292
|
-
...
|
|
293
|
-
[
|
|
294
|
-
...
|
|
294
|
+
...e.characterState,
|
|
295
|
+
[t]: {
|
|
296
|
+
...n,
|
|
295
297
|
inParty: !1
|
|
296
298
|
}
|
|
297
299
|
}
|
|
298
|
-
} :
|
|
300
|
+
} : e;
|
|
299
301
|
}
|
|
300
|
-
function
|
|
301
|
-
const r =
|
|
302
|
+
function ce(t, e, n) {
|
|
303
|
+
const r = n.characterState[t];
|
|
302
304
|
return r ? {
|
|
303
|
-
...
|
|
305
|
+
...n,
|
|
304
306
|
characterState: {
|
|
305
|
-
...
|
|
306
|
-
[
|
|
307
|
+
...n.characterState,
|
|
308
|
+
[t]: {
|
|
307
309
|
...r,
|
|
308
|
-
relationship:
|
|
310
|
+
relationship: e
|
|
309
311
|
}
|
|
310
312
|
}
|
|
311
|
-
} :
|
|
313
|
+
} : n;
|
|
312
314
|
}
|
|
313
|
-
function
|
|
314
|
-
const r =
|
|
315
|
+
function ue(t, e, n) {
|
|
316
|
+
const r = n.characterState[t];
|
|
315
317
|
return r ? {
|
|
316
|
-
...
|
|
318
|
+
...n,
|
|
317
319
|
characterState: {
|
|
318
|
-
...
|
|
319
|
-
[
|
|
320
|
+
...n.characterState,
|
|
321
|
+
[t]: {
|
|
320
322
|
...r,
|
|
321
|
-
relationship: r.relationship +
|
|
323
|
+
relationship: r.relationship + e
|
|
322
324
|
}
|
|
323
325
|
}
|
|
324
|
-
} :
|
|
326
|
+
} : n;
|
|
325
327
|
}
|
|
326
|
-
function
|
|
327
|
-
const a = r.characterState[
|
|
328
|
+
function de(t, e, n, r) {
|
|
329
|
+
const a = r.characterState[t];
|
|
328
330
|
return a ? {
|
|
329
331
|
...r,
|
|
330
332
|
characterState: {
|
|
331
333
|
...r.characterState,
|
|
332
|
-
[
|
|
334
|
+
[t]: {
|
|
333
335
|
...a,
|
|
334
336
|
stats: {
|
|
335
337
|
...a.stats,
|
|
336
|
-
[
|
|
338
|
+
[e]: n
|
|
337
339
|
}
|
|
338
340
|
}
|
|
339
341
|
}
|
|
340
342
|
} : r;
|
|
341
343
|
}
|
|
342
|
-
function
|
|
343
|
-
const a = r.characterState[
|
|
344
|
+
function he(t, e, n, r) {
|
|
345
|
+
const a = r.characterState[t];
|
|
344
346
|
if (!a)
|
|
345
347
|
return r;
|
|
346
|
-
const s = a.stats[
|
|
348
|
+
const s = a.stats[e], i = typeof s == "number" ? s + n : n;
|
|
347
349
|
return {
|
|
348
350
|
...r,
|
|
349
351
|
characterState: {
|
|
350
352
|
...r.characterState,
|
|
351
|
-
[
|
|
353
|
+
[t]: {
|
|
352
354
|
...a,
|
|
353
355
|
stats: {
|
|
354
356
|
...a.stats,
|
|
355
|
-
[
|
|
357
|
+
[e]: i
|
|
356
358
|
}
|
|
357
359
|
}
|
|
358
360
|
}
|
|
359
361
|
};
|
|
360
362
|
}
|
|
361
|
-
function
|
|
363
|
+
function pe(t, e) {
|
|
362
364
|
return {
|
|
363
|
-
...
|
|
364
|
-
mapEnabled:
|
|
365
|
+
...e,
|
|
366
|
+
mapEnabled: t
|
|
365
367
|
};
|
|
366
368
|
}
|
|
367
|
-
function
|
|
369
|
+
function ge(t, e) {
|
|
368
370
|
return {
|
|
369
|
-
...
|
|
370
|
-
notifications: [...
|
|
371
|
+
...e,
|
|
372
|
+
notifications: [...e.notifications, t]
|
|
371
373
|
};
|
|
372
374
|
}
|
|
373
|
-
function
|
|
375
|
+
function fe(t, e) {
|
|
374
376
|
return {
|
|
375
|
-
...
|
|
376
|
-
pendingSounds: [...
|
|
377
|
+
...e,
|
|
378
|
+
pendingSounds: [...e.pendingSounds, t]
|
|
377
379
|
};
|
|
378
380
|
}
|
|
379
|
-
function
|
|
381
|
+
function me(t, e) {
|
|
380
382
|
return {
|
|
381
|
-
...
|
|
382
|
-
pendingVideo:
|
|
383
|
+
...e,
|
|
384
|
+
pendingVideo: t
|
|
383
385
|
};
|
|
384
386
|
}
|
|
385
|
-
function
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
}
|
|
391
|
-
function kt(n) {
|
|
392
|
-
return (t) => A(t, n);
|
|
387
|
+
function be(t, e) {
|
|
388
|
+
return {
|
|
389
|
+
...e,
|
|
390
|
+
pendingInterlude: t
|
|
391
|
+
};
|
|
393
392
|
}
|
|
394
|
-
function
|
|
395
|
-
|
|
393
|
+
function C(t, e) {
|
|
394
|
+
if (!t.startsWith("@"))
|
|
395
|
+
return t;
|
|
396
|
+
const n = t.slice(1);
|
|
397
|
+
return e[n] ?? t;
|
|
398
|
+
}
|
|
399
|
+
function Re(t) {
|
|
400
|
+
return (e) => C(e, t);
|
|
401
|
+
}
|
|
402
|
+
function ye(t, e) {
|
|
403
|
+
const n = e.locales[t.currentLocale] ?? {}, r = (m) => C(m, n), a = Se(t.currentLocation, e, r), s = ve(t, e, r), i = Ie(t, e, r), { dialogue: o, choices: l } = Te(t, e, r), c = Ne(t, e, r), d = Ee(t, e, r), f = Ae(t, e, r), b = we(t, e, r), u = t.mapEnabled ? Ce(t, e, r) : null, g = e.locations[t.currentLocation], h = (g == null ? void 0 : g.music) ?? "", p = (g == null ? void 0 : g.ambient) ?? "", y = t.notifications.map(r), I = [...t.pendingSounds], L = t.pendingVideo;
|
|
404
|
+
let w = null;
|
|
405
|
+
if (t.pendingInterlude) {
|
|
406
|
+
const m = e.interludes[t.pendingInterlude];
|
|
407
|
+
m && (w = {
|
|
408
|
+
id: m.id,
|
|
409
|
+
background: m.background,
|
|
410
|
+
banner: m.banner,
|
|
411
|
+
music: m.music,
|
|
412
|
+
voice: m.voice,
|
|
413
|
+
sounds: m.sounds,
|
|
414
|
+
scroll: m.scroll ?? !0,
|
|
415
|
+
scrollSpeed: m.scrollSpeed ?? 30,
|
|
416
|
+
text: r(m.text)
|
|
417
|
+
});
|
|
418
|
+
}
|
|
396
419
|
return {
|
|
397
420
|
location: a,
|
|
398
421
|
charactersHere: s,
|
|
399
422
|
itemsHere: i,
|
|
400
|
-
choices:
|
|
423
|
+
choices: l,
|
|
401
424
|
dialogue: o,
|
|
402
|
-
party:
|
|
425
|
+
party: c,
|
|
403
426
|
inventory: d,
|
|
404
427
|
quests: f,
|
|
405
|
-
journal:
|
|
406
|
-
variables: { ...
|
|
407
|
-
time:
|
|
428
|
+
journal: b,
|
|
429
|
+
variables: { ...t.variables },
|
|
430
|
+
time: t.currentTime,
|
|
408
431
|
map: u,
|
|
409
432
|
music: h,
|
|
410
433
|
ambient: p,
|
|
411
|
-
notifications:
|
|
412
|
-
pendingSounds:
|
|
413
|
-
pendingVideo:
|
|
434
|
+
notifications: y,
|
|
435
|
+
pendingSounds: I,
|
|
436
|
+
pendingVideo: L,
|
|
437
|
+
pendingInterlude: w
|
|
414
438
|
};
|
|
415
439
|
}
|
|
416
|
-
function
|
|
417
|
-
const r =
|
|
440
|
+
function Se(t, e, n) {
|
|
441
|
+
const r = e.locations[t];
|
|
418
442
|
return r ? {
|
|
419
443
|
id: r.id,
|
|
420
|
-
name:
|
|
421
|
-
description:
|
|
444
|
+
name: n(r.name),
|
|
445
|
+
description: n(r.description),
|
|
422
446
|
banner: r.banner
|
|
423
447
|
} : {
|
|
424
|
-
id:
|
|
425
|
-
name:
|
|
426
|
-
description: `Location not found: ${
|
|
448
|
+
id: t,
|
|
449
|
+
name: t,
|
|
450
|
+
description: `Location not found: ${t}`,
|
|
427
451
|
banner: ""
|
|
428
452
|
};
|
|
429
453
|
}
|
|
430
|
-
function
|
|
454
|
+
function ve(t, e, n) {
|
|
431
455
|
const r = [];
|
|
432
|
-
for (const [a, s] of Object.entries(
|
|
433
|
-
if (s.location ===
|
|
434
|
-
const i =
|
|
456
|
+
for (const [a, s] of Object.entries(t.characterState))
|
|
457
|
+
if (s.location === t.currentLocation) {
|
|
458
|
+
const i = e.characters[a];
|
|
435
459
|
i && r.push({
|
|
436
460
|
id: i.id,
|
|
437
|
-
name:
|
|
438
|
-
biography:
|
|
461
|
+
name: n(i.name),
|
|
462
|
+
biography: n(i.biography),
|
|
439
463
|
portrait: i.portrait,
|
|
440
464
|
location: s.location,
|
|
441
465
|
inParty: s.inParty,
|
|
@@ -445,15 +469,15 @@ function yt(n, t, e) {
|
|
|
445
469
|
}
|
|
446
470
|
return r;
|
|
447
471
|
}
|
|
448
|
-
function
|
|
472
|
+
function Ie(t, e, n) {
|
|
449
473
|
const r = [];
|
|
450
|
-
for (const [a, s] of Object.entries(
|
|
451
|
-
if (s ===
|
|
452
|
-
const i =
|
|
474
|
+
for (const [a, s] of Object.entries(t.itemLocations))
|
|
475
|
+
if (s === t.currentLocation) {
|
|
476
|
+
const i = e.items[a];
|
|
453
477
|
i && r.push({
|
|
454
478
|
id: i.id,
|
|
455
|
-
name:
|
|
456
|
-
description:
|
|
479
|
+
name: n(i.name),
|
|
480
|
+
description: n(i.description),
|
|
457
481
|
icon: i.icon,
|
|
458
482
|
image: i.image,
|
|
459
483
|
stats: i.stats
|
|
@@ -461,40 +485,40 @@ function St(n, t, e) {
|
|
|
461
485
|
}
|
|
462
486
|
return r;
|
|
463
487
|
}
|
|
464
|
-
function
|
|
465
|
-
var
|
|
466
|
-
if (!
|
|
488
|
+
function Te(t, e, n) {
|
|
489
|
+
var l, c;
|
|
490
|
+
if (!t.dialogueState)
|
|
467
491
|
return { dialogue: null, choices: [] };
|
|
468
|
-
const r =
|
|
492
|
+
const r = e.dialogues[t.dialogueState.dialogueId];
|
|
469
493
|
if (!r)
|
|
470
494
|
return { dialogue: null, choices: [] };
|
|
471
495
|
const a = r.nodes.find((d) => {
|
|
472
496
|
var f;
|
|
473
|
-
return d.id === ((f =
|
|
497
|
+
return d.id === ((f = t.dialogueState) == null ? void 0 : f.nodeId);
|
|
474
498
|
});
|
|
475
499
|
if (!a)
|
|
476
500
|
return { dialogue: null, choices: [] };
|
|
477
|
-
const s = a.speaker ?
|
|
501
|
+
const s = a.speaker ? n(((l = e.characters[a.speaker]) == null ? void 0 : l.name) ?? a.speaker) : "Narrator", i = {
|
|
478
502
|
speaker: a.speaker,
|
|
479
503
|
speakerName: s,
|
|
480
|
-
text:
|
|
481
|
-
portrait: a.portrait ?? ((
|
|
504
|
+
text: n(a.text),
|
|
505
|
+
portrait: a.portrait ?? ((c = e.characters[a.speaker ?? ""]) == null ? void 0 : c.portrait),
|
|
482
506
|
voice: a.voice
|
|
483
|
-
}, o = a.choices.filter((d) => !d.conditions || d.conditions.length === 0 ? !0 :
|
|
507
|
+
}, o = a.choices.filter((d) => !d.conditions || d.conditions.length === 0 ? !0 : v(d.conditions, t)).map((d) => ({
|
|
484
508
|
id: d.id,
|
|
485
|
-
text:
|
|
509
|
+
text: n(d.text)
|
|
486
510
|
}));
|
|
487
511
|
return { dialogue: i, choices: o };
|
|
488
512
|
}
|
|
489
|
-
function
|
|
513
|
+
function Ne(t, e, n) {
|
|
490
514
|
const r = [];
|
|
491
|
-
for (const [a, s] of Object.entries(
|
|
515
|
+
for (const [a, s] of Object.entries(t.characterState))
|
|
492
516
|
if (s.inParty) {
|
|
493
|
-
const i =
|
|
517
|
+
const i = e.characters[a];
|
|
494
518
|
i && r.push({
|
|
495
519
|
id: i.id,
|
|
496
|
-
name:
|
|
497
|
-
biography:
|
|
520
|
+
name: n(i.name),
|
|
521
|
+
biography: n(i.biography),
|
|
498
522
|
portrait: i.portrait,
|
|
499
523
|
location: s.location,
|
|
500
524
|
inParty: s.inParty,
|
|
@@ -504,80 +528,80 @@ function It(n, t, e) {
|
|
|
504
528
|
}
|
|
505
529
|
return r;
|
|
506
530
|
}
|
|
507
|
-
function
|
|
508
|
-
return
|
|
509
|
-
const a =
|
|
531
|
+
function Ee(t, e, n) {
|
|
532
|
+
return t.inventory.map((r) => {
|
|
533
|
+
const a = e.items[r];
|
|
510
534
|
return a ? {
|
|
511
535
|
id: a.id,
|
|
512
|
-
name:
|
|
513
|
-
description:
|
|
536
|
+
name: n(a.name),
|
|
537
|
+
description: n(a.description),
|
|
514
538
|
icon: a.icon,
|
|
515
539
|
image: a.image,
|
|
516
540
|
stats: a.stats
|
|
517
541
|
} : null;
|
|
518
542
|
}).filter((r) => r !== null);
|
|
519
543
|
}
|
|
520
|
-
function
|
|
544
|
+
function Ae(t, e, n) {
|
|
521
545
|
const r = [];
|
|
522
|
-
for (const [a, s] of Object.entries(
|
|
523
|
-
const i =
|
|
546
|
+
for (const [a, s] of Object.entries(t.questProgress)) {
|
|
547
|
+
const i = e.quests[a];
|
|
524
548
|
if (!i) continue;
|
|
525
|
-
const o = i.stages.find((
|
|
549
|
+
const o = i.stages.find((l) => l.id === s);
|
|
526
550
|
o && r.push({
|
|
527
551
|
id: i.id,
|
|
528
|
-
name:
|
|
529
|
-
description:
|
|
552
|
+
name: n(i.name),
|
|
553
|
+
description: n(i.description),
|
|
530
554
|
currentStage: o.id,
|
|
531
|
-
currentStageDescription:
|
|
555
|
+
currentStageDescription: n(o.description)
|
|
532
556
|
});
|
|
533
557
|
}
|
|
534
558
|
return r;
|
|
535
559
|
}
|
|
536
|
-
function
|
|
537
|
-
return
|
|
538
|
-
const a =
|
|
560
|
+
function we(t, e, n) {
|
|
561
|
+
return t.unlockedJournalEntries.map((r) => {
|
|
562
|
+
const a = e.journalEntries[r];
|
|
539
563
|
return a ? {
|
|
540
564
|
id: a.id,
|
|
541
|
-
title:
|
|
542
|
-
text:
|
|
565
|
+
title: n(a.title),
|
|
566
|
+
text: n(a.text),
|
|
543
567
|
category: a.category
|
|
544
568
|
} : null;
|
|
545
569
|
}).filter((r) => r !== null);
|
|
546
570
|
}
|
|
547
|
-
function
|
|
548
|
-
const r = Object.keys(
|
|
571
|
+
function Ce(t, e, n) {
|
|
572
|
+
const r = Object.keys(e.maps);
|
|
549
573
|
if (r.length === 0) return null;
|
|
550
|
-
const a =
|
|
574
|
+
const a = e.maps[r[0]];
|
|
551
575
|
if (!a) return null;
|
|
552
576
|
const s = a.locations.map((i) => {
|
|
553
|
-
const o =
|
|
577
|
+
const o = e.locations[i.id];
|
|
554
578
|
return {
|
|
555
579
|
id: i.id,
|
|
556
|
-
name: o ?
|
|
580
|
+
name: o ? n(o.name) : i.id,
|
|
557
581
|
x: i.x,
|
|
558
582
|
y: i.y,
|
|
559
|
-
isCurrent: i.id ===
|
|
583
|
+
isCurrent: i.id === t.currentLocation
|
|
560
584
|
};
|
|
561
585
|
});
|
|
562
586
|
return {
|
|
563
587
|
id: a.id,
|
|
564
|
-
name:
|
|
588
|
+
name: n(a.name),
|
|
565
589
|
image: a.image,
|
|
566
590
|
scale: a.scale,
|
|
567
591
|
locations: s
|
|
568
592
|
};
|
|
569
593
|
}
|
|
570
|
-
class
|
|
594
|
+
class De {
|
|
571
595
|
/**
|
|
572
596
|
* Create a new engine instance.
|
|
573
597
|
*
|
|
574
598
|
* @param registry - Content registry with all game entities
|
|
575
599
|
* @param state - Initial game state
|
|
576
600
|
*/
|
|
577
|
-
constructor(
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
this.registry =
|
|
601
|
+
constructor(e, n) {
|
|
602
|
+
T(this, "registry");
|
|
603
|
+
T(this, "state");
|
|
604
|
+
this.registry = e, this.state = n;
|
|
581
605
|
}
|
|
582
606
|
// ===========================================================================
|
|
583
607
|
// Core API Methods
|
|
@@ -590,10 +614,10 @@ class Vt {
|
|
|
590
614
|
* @param config - Game configuration with starting conditions
|
|
591
615
|
* @returns Initial snapshot
|
|
592
616
|
*/
|
|
593
|
-
newGame(
|
|
594
|
-
const
|
|
617
|
+
newGame(e) {
|
|
618
|
+
const n = {};
|
|
595
619
|
for (const [a, s] of Object.entries(this.registry.characters))
|
|
596
|
-
|
|
620
|
+
n[a] = {
|
|
597
621
|
location: s.location,
|
|
598
622
|
inParty: !1,
|
|
599
623
|
relationship: 0,
|
|
@@ -604,24 +628,25 @@ class Vt {
|
|
|
604
628
|
for (const [a, s] of Object.entries(this.registry.items))
|
|
605
629
|
r[a] = s.location;
|
|
606
630
|
return this.state = {
|
|
607
|
-
currentLocation:
|
|
608
|
-
currentTime: { ...
|
|
609
|
-
flags: { ...
|
|
610
|
-
variables: { ...
|
|
611
|
-
inventory: [...
|
|
631
|
+
currentLocation: e.startLocation,
|
|
632
|
+
currentTime: { ...e.startTime },
|
|
633
|
+
flags: { ...e.startFlags },
|
|
634
|
+
variables: { ...e.startVariables },
|
|
635
|
+
inventory: [...e.startInventory],
|
|
612
636
|
questProgress: {},
|
|
613
637
|
unlockedJournalEntries: [],
|
|
614
638
|
playerNotes: [],
|
|
615
639
|
dialogueState: null,
|
|
616
|
-
characterState:
|
|
640
|
+
characterState: n,
|
|
617
641
|
itemLocations: r,
|
|
618
642
|
mapEnabled: !0,
|
|
619
643
|
notifications: [],
|
|
620
644
|
pendingSounds: [],
|
|
621
645
|
pendingVideo: null,
|
|
646
|
+
pendingInterlude: null,
|
|
622
647
|
currentLocale: "en"
|
|
623
648
|
// Default locale
|
|
624
|
-
}, this.checkTriggeredDialogues(), this.buildSnapshotAndClearTransients();
|
|
649
|
+
}, this.checkTriggeredDialogues(), this.checkTriggeredInterludes(), this.buildSnapshotAndClearTransients();
|
|
625
650
|
}
|
|
626
651
|
/**
|
|
627
652
|
* Load a game from save data.
|
|
@@ -631,8 +656,8 @@ class Vt {
|
|
|
631
656
|
* @param saveData - Saved game data
|
|
632
657
|
* @returns Snapshot of the loaded game
|
|
633
658
|
*/
|
|
634
|
-
loadGame(
|
|
635
|
-
return this.state = { ...
|
|
659
|
+
loadGame(e) {
|
|
660
|
+
return this.state = { ...e.state }, this.buildSnapshotAndClearTransients();
|
|
636
661
|
}
|
|
637
662
|
/**
|
|
638
663
|
* Save the current game state.
|
|
@@ -656,23 +681,23 @@ class Vt {
|
|
|
656
681
|
* @param choiceId - ID of the selected choice
|
|
657
682
|
* @returns New snapshot after processing the choice
|
|
658
683
|
*/
|
|
659
|
-
selectChoice(
|
|
684
|
+
selectChoice(e) {
|
|
660
685
|
if (!this.state.dialogueState)
|
|
661
686
|
return this.buildSnapshotAndClearTransients();
|
|
662
|
-
const
|
|
663
|
-
if (!
|
|
687
|
+
const n = this.registry.dialogues[this.state.dialogueState.dialogueId];
|
|
688
|
+
if (!n)
|
|
664
689
|
return this.buildSnapshotAndClearTransients();
|
|
665
|
-
const r =
|
|
690
|
+
const r = n.nodes.find((i) => {
|
|
666
691
|
var o;
|
|
667
692
|
return i.id === ((o = this.state.dialogueState) == null ? void 0 : o.nodeId);
|
|
668
693
|
});
|
|
669
694
|
if (!r)
|
|
670
695
|
return this.buildSnapshotAndClearTransients();
|
|
671
|
-
const a = r.choices.find((i) => i.id ===
|
|
696
|
+
const a = r.choices.find((i) => i.id === e);
|
|
672
697
|
if (!a)
|
|
673
698
|
return this.buildSnapshotAndClearTransients();
|
|
674
|
-
a.effects && (this.state =
|
|
675
|
-
const s =
|
|
699
|
+
a.effects && (this.state = S(a.effects, this.state));
|
|
700
|
+
const s = n.nodes.find((i) => i.id === a.next);
|
|
676
701
|
if (!s)
|
|
677
702
|
return this.state = {
|
|
678
703
|
...this.state,
|
|
@@ -681,15 +706,15 @@ class Vt {
|
|
|
681
706
|
if (this.state = {
|
|
682
707
|
...this.state,
|
|
683
708
|
dialogueState: {
|
|
684
|
-
dialogueId:
|
|
709
|
+
dialogueId: n.id,
|
|
685
710
|
nodeId: s.id
|
|
686
711
|
}
|
|
687
|
-
}, s.effects && (this.state =
|
|
712
|
+
}, s.effects && (this.state = S(s.effects, this.state)), s.choices.length === 0) {
|
|
688
713
|
const i = this.resolveNextNode(s);
|
|
689
714
|
i ? this.state = {
|
|
690
715
|
...this.state,
|
|
691
716
|
dialogueState: {
|
|
692
|
-
dialogueId:
|
|
717
|
+
dialogueId: n.id,
|
|
693
718
|
nodeId: i
|
|
694
719
|
}
|
|
695
720
|
} : this.state = {
|
|
@@ -707,11 +732,11 @@ class Vt {
|
|
|
707
732
|
* @param characterId - ID of the character to talk to
|
|
708
733
|
* @returns New snapshot with dialogue started
|
|
709
734
|
*/
|
|
710
|
-
talkTo(
|
|
711
|
-
const
|
|
712
|
-
if (!
|
|
735
|
+
talkTo(e) {
|
|
736
|
+
const n = this.registry.characters[e];
|
|
737
|
+
if (!n || !n.dialogue)
|
|
713
738
|
return this.buildSnapshotAndClearTransients();
|
|
714
|
-
const r = this.registry.dialogues[
|
|
739
|
+
const r = this.registry.dialogues[n.dialogue];
|
|
715
740
|
if (!r)
|
|
716
741
|
return this.buildSnapshotAndClearTransients();
|
|
717
742
|
const a = r.nodes.find((s) => s.id === r.startNode);
|
|
@@ -723,7 +748,7 @@ class Vt {
|
|
|
723
748
|
dialogueId: r.id,
|
|
724
749
|
nodeId: a.id
|
|
725
750
|
}
|
|
726
|
-
}, a.effects && (this.state =
|
|
751
|
+
}, a.effects && (this.state = S(a.effects, this.state)), a.choices.length === 0) {
|
|
727
752
|
const s = this.resolveNextNode(a);
|
|
728
753
|
s ? this.state = {
|
|
729
754
|
...this.state,
|
|
@@ -746,13 +771,13 @@ class Vt {
|
|
|
746
771
|
* @param itemId - ID of the item to take
|
|
747
772
|
* @returns New snapshot with item in inventory
|
|
748
773
|
*/
|
|
749
|
-
takeItem(
|
|
750
|
-
return this.state.itemLocations[
|
|
774
|
+
takeItem(e) {
|
|
775
|
+
return this.state.itemLocations[e] !== this.state.currentLocation ? this.buildSnapshotAndClearTransients() : (this.state = {
|
|
751
776
|
...this.state,
|
|
752
|
-
inventory: [...this.state.inventory,
|
|
777
|
+
inventory: [...this.state.inventory, e],
|
|
753
778
|
itemLocations: {
|
|
754
779
|
...this.state.itemLocations,
|
|
755
|
-
[
|
|
780
|
+
[e]: "inventory"
|
|
756
781
|
}
|
|
757
782
|
}, this.buildSnapshotAndClearTransients());
|
|
758
783
|
}
|
|
@@ -764,30 +789,30 @@ class Vt {
|
|
|
764
789
|
* @param locationId - ID of the destination location
|
|
765
790
|
* @returns New snapshot at the new location
|
|
766
791
|
*/
|
|
767
|
-
travelTo(
|
|
792
|
+
travelTo(e) {
|
|
768
793
|
if (!this.state.mapEnabled)
|
|
769
794
|
return this.buildSnapshotAndClearTransients();
|
|
770
|
-
const
|
|
771
|
-
if (
|
|
795
|
+
const n = Object.keys(this.registry.maps);
|
|
796
|
+
if (n.length === 0)
|
|
772
797
|
return this.buildSnapshotAndClearTransients();
|
|
773
|
-
const r = this.registry.maps[
|
|
798
|
+
const r = this.registry.maps[n[0]];
|
|
774
799
|
if (!r)
|
|
775
800
|
return this.buildSnapshotAndClearTransients();
|
|
776
|
-
const a = r.locations.find((f) => f.id === this.state.currentLocation), s = r.locations.find((f) => f.id ===
|
|
801
|
+
const a = r.locations.find((f) => f.id === this.state.currentLocation), s = r.locations.find((f) => f.id === e);
|
|
777
802
|
if (!a || !s)
|
|
778
803
|
return this.buildSnapshotAndClearTransients();
|
|
779
804
|
const i = Math.sqrt(
|
|
780
805
|
Math.pow(s.x - a.x, 2) + Math.pow(s.y - a.y, 2)
|
|
781
|
-
), o = Math.round(i * r.scale),
|
|
806
|
+
), o = Math.round(i * r.scale), l = this.state.currentTime.hour + o, c = Math.floor(l / 24), d = l % 24;
|
|
782
807
|
return this.state = {
|
|
783
808
|
...this.state,
|
|
784
|
-
currentLocation:
|
|
809
|
+
currentLocation: e,
|
|
785
810
|
dialogueState: null,
|
|
786
811
|
currentTime: {
|
|
787
|
-
day: this.state.currentTime.day +
|
|
812
|
+
day: this.state.currentTime.day + c,
|
|
788
813
|
hour: d
|
|
789
814
|
}
|
|
790
|
-
}, this.checkTriggeredDialogues(), this.buildSnapshotAndClearTransients();
|
|
815
|
+
}, this.checkTriggeredDialogues(), this.checkTriggeredInterludes(), this.buildSnapshotAndClearTransients();
|
|
791
816
|
}
|
|
792
817
|
/**
|
|
793
818
|
* Player wrote a note.
|
|
@@ -798,11 +823,11 @@ class Vt {
|
|
|
798
823
|
* @param text - Note content
|
|
799
824
|
* @returns New snapshot with note added
|
|
800
825
|
*/
|
|
801
|
-
writeNote(
|
|
826
|
+
writeNote(e, n) {
|
|
802
827
|
const r = {
|
|
803
828
|
id: `note_${Date.now()}`,
|
|
804
|
-
title:
|
|
805
|
-
text:
|
|
829
|
+
title: e,
|
|
830
|
+
text: n
|
|
806
831
|
};
|
|
807
832
|
return this.state = {
|
|
808
833
|
...this.state,
|
|
@@ -817,10 +842,10 @@ class Vt {
|
|
|
817
842
|
* @param noteId - ID of the note to delete
|
|
818
843
|
* @returns New snapshot with note removed
|
|
819
844
|
*/
|
|
820
|
-
deleteNote(
|
|
845
|
+
deleteNote(e) {
|
|
821
846
|
return this.state = {
|
|
822
847
|
...this.state,
|
|
823
|
-
playerNotes: this.state.playerNotes.filter((
|
|
848
|
+
playerNotes: this.state.playerNotes.filter((n) => n.id !== e)
|
|
824
849
|
}, this.buildSnapshotAndClearTransients();
|
|
825
850
|
}
|
|
826
851
|
/**
|
|
@@ -831,10 +856,10 @@ class Vt {
|
|
|
831
856
|
* @param locale - Language code (e.g., "en", "es")
|
|
832
857
|
* @returns New snapshot with updated locale
|
|
833
858
|
*/
|
|
834
|
-
setLocale(
|
|
859
|
+
setLocale(e) {
|
|
835
860
|
return this.state = {
|
|
836
861
|
...this.state,
|
|
837
|
-
currentLocale:
|
|
862
|
+
currentLocale: e
|
|
838
863
|
}, this.buildSnapshotAndClearTransients();
|
|
839
864
|
}
|
|
840
865
|
/**
|
|
@@ -855,13 +880,14 @@ class Vt {
|
|
|
855
880
|
* Transient state is data that should only appear in one snapshot.
|
|
856
881
|
*/
|
|
857
882
|
buildSnapshotAndClearTransients() {
|
|
858
|
-
const
|
|
883
|
+
const e = ye(this.state, this.registry);
|
|
859
884
|
return this.state = {
|
|
860
885
|
...this.state,
|
|
861
886
|
notifications: [],
|
|
862
887
|
pendingSounds: [],
|
|
863
|
-
pendingVideo: null
|
|
864
|
-
|
|
888
|
+
pendingVideo: null,
|
|
889
|
+
pendingInterlude: null
|
|
890
|
+
}, e;
|
|
865
891
|
}
|
|
866
892
|
/**
|
|
867
893
|
* Resolve the next node ID from a dialogue node.
|
|
@@ -873,13 +899,13 @@ class Vt {
|
|
|
873
899
|
* @param node - The dialogue node to resolve next from
|
|
874
900
|
* @returns Next node ID, or null to end dialogue
|
|
875
901
|
*/
|
|
876
|
-
resolveNextNode(
|
|
877
|
-
if (
|
|
878
|
-
for (const
|
|
879
|
-
if (
|
|
880
|
-
return
|
|
902
|
+
resolveNextNode(e) {
|
|
903
|
+
if (e.conditionalNext && e.conditionalNext.length > 0) {
|
|
904
|
+
for (const n of e.conditionalNext)
|
|
905
|
+
if (v([n.condition], this.state))
|
|
906
|
+
return n.next;
|
|
881
907
|
}
|
|
882
|
-
return
|
|
908
|
+
return e.next ?? null;
|
|
883
909
|
}
|
|
884
910
|
/**
|
|
885
911
|
* Check for dialogues that should auto-trigger at the current location.
|
|
@@ -890,23 +916,23 @@ class Vt {
|
|
|
890
916
|
* This is called after location changes (newGame, travelTo).
|
|
891
917
|
*/
|
|
892
918
|
checkTriggeredDialogues() {
|
|
893
|
-
for (const
|
|
894
|
-
if (
|
|
919
|
+
for (const e of Object.values(this.registry.dialogues)) {
|
|
920
|
+
if (e.triggerLocation !== this.state.currentLocation || e.conditions && !v(e.conditions, this.state))
|
|
895
921
|
continue;
|
|
896
|
-
const
|
|
897
|
-
if (
|
|
922
|
+
const n = e.nodes.find((r) => r.id === e.startNode);
|
|
923
|
+
if (n) {
|
|
898
924
|
if (this.state = {
|
|
899
925
|
...this.state,
|
|
900
926
|
dialogueState: {
|
|
901
|
-
dialogueId:
|
|
902
|
-
nodeId:
|
|
927
|
+
dialogueId: e.id,
|
|
928
|
+
nodeId: n.id
|
|
903
929
|
}
|
|
904
|
-
},
|
|
905
|
-
const r = this.resolveNextNode(
|
|
930
|
+
}, n.effects && (this.state = S(n.effects, this.state)), n.choices.length === 0) {
|
|
931
|
+
const r = this.resolveNextNode(n);
|
|
906
932
|
r ? this.state = {
|
|
907
933
|
...this.state,
|
|
908
934
|
dialogueState: {
|
|
909
|
-
dialogueId:
|
|
935
|
+
dialogueId: e.id,
|
|
910
936
|
nodeId: r
|
|
911
937
|
}
|
|
912
938
|
} : this.state = {
|
|
@@ -918,211 +944,231 @@ class Vt {
|
|
|
918
944
|
}
|
|
919
945
|
}
|
|
920
946
|
}
|
|
947
|
+
/**
|
|
948
|
+
* Check for interludes that should auto-trigger at the current location.
|
|
949
|
+
*
|
|
950
|
+
* If an interlude matches the current location and all its conditions pass,
|
|
951
|
+
* queue that interlude to show.
|
|
952
|
+
*
|
|
953
|
+
* This is called after location changes (newGame, travelTo).
|
|
954
|
+
*/
|
|
955
|
+
checkTriggeredInterludes() {
|
|
956
|
+
for (const e of Object.values(this.registry.interludes))
|
|
957
|
+
if (e.triggerLocation === this.state.currentLocation && !(e.triggerConditions && !v(e.triggerConditions, this.state))) {
|
|
958
|
+
this.state = {
|
|
959
|
+
...this.state,
|
|
960
|
+
pendingInterlude: e.id
|
|
961
|
+
};
|
|
962
|
+
break;
|
|
963
|
+
}
|
|
964
|
+
}
|
|
921
965
|
}
|
|
922
|
-
function
|
|
923
|
-
return
|
|
924
|
-
`).map((
|
|
925
|
-
original:
|
|
926
|
-
lineNumber:
|
|
927
|
-
})).map(({ original:
|
|
928
|
-
let r =
|
|
929
|
-
const a =
|
|
966
|
+
function Le(t) {
|
|
967
|
+
return t.split(`
|
|
968
|
+
`).map((e, n) => ({
|
|
969
|
+
original: e,
|
|
970
|
+
lineNumber: n + 1
|
|
971
|
+
})).map(({ original: e, lineNumber: n }) => {
|
|
972
|
+
let r = e;
|
|
973
|
+
const a = e.indexOf("#");
|
|
930
974
|
if (a === -1)
|
|
931
|
-
r =
|
|
975
|
+
r = e;
|
|
932
976
|
else {
|
|
933
|
-
const o =
|
|
977
|
+
const o = e.match(/"[^"]*"/);
|
|
934
978
|
if (o) {
|
|
935
|
-
const
|
|
936
|
-
a <
|
|
979
|
+
const l = e.indexOf(o[0]), c = l + o[0].length;
|
|
980
|
+
a < l ? r = e.substring(0, a) : a >= l && a < c ? r = e.substring(0, c) + e.substring(c).split("#")[0] : r = e.substring(0, a);
|
|
937
981
|
} else
|
|
938
|
-
r =
|
|
982
|
+
r = e.substring(0, a);
|
|
939
983
|
}
|
|
940
984
|
const s = r.length - r.trimStart().length;
|
|
941
|
-
return { line: r.trim(), lineNumber:
|
|
942
|
-
}).filter((
|
|
985
|
+
return { line: r.trim(), lineNumber: n, indent: s };
|
|
986
|
+
}).filter((e) => e.line.length > 0);
|
|
943
987
|
}
|
|
944
|
-
function
|
|
945
|
-
const
|
|
946
|
-
return
|
|
988
|
+
function N(t) {
|
|
989
|
+
const e = t.trim();
|
|
990
|
+
return e.startsWith("@") ? e : e.startsWith('"') && e.endsWith('"') ? e.substring(1, e.length - 1) : e;
|
|
947
991
|
}
|
|
948
|
-
function
|
|
949
|
-
const
|
|
950
|
-
switch (
|
|
992
|
+
function E(t) {
|
|
993
|
+
const e = t.trim().split(/\s+/), n = e[0];
|
|
994
|
+
switch (n) {
|
|
951
995
|
case "hasFlag":
|
|
952
|
-
return { type: "hasFlag", flag:
|
|
996
|
+
return { type: "hasFlag", flag: e[1] };
|
|
953
997
|
case "notFlag":
|
|
954
|
-
return { type: "notFlag", flag:
|
|
998
|
+
return { type: "notFlag", flag: e[1] };
|
|
955
999
|
case "hasItem":
|
|
956
|
-
return { type: "hasItem", itemId:
|
|
1000
|
+
return { type: "hasItem", itemId: e[1] };
|
|
957
1001
|
case "variableEquals":
|
|
958
1002
|
return {
|
|
959
1003
|
type: "variableEquals",
|
|
960
|
-
variable:
|
|
961
|
-
value: isNaN(Number(
|
|
1004
|
+
variable: e[1],
|
|
1005
|
+
value: isNaN(Number(e[2])) ? e[2] : Number(e[2])
|
|
962
1006
|
};
|
|
963
1007
|
case "variableGreaterThan":
|
|
964
1008
|
return {
|
|
965
1009
|
type: "variableGreaterThan",
|
|
966
|
-
variable:
|
|
967
|
-
value: Number(
|
|
1010
|
+
variable: e[1],
|
|
1011
|
+
value: Number(e[2])
|
|
968
1012
|
};
|
|
969
1013
|
case "variableLessThan":
|
|
970
1014
|
return {
|
|
971
1015
|
type: "variableLessThan",
|
|
972
|
-
variable:
|
|
973
|
-
value: Number(
|
|
1016
|
+
variable: e[1],
|
|
1017
|
+
value: Number(e[2])
|
|
974
1018
|
};
|
|
975
1019
|
case "atLocation":
|
|
976
|
-
return { type: "atLocation", locationId:
|
|
1020
|
+
return { type: "atLocation", locationId: e[1] };
|
|
977
1021
|
case "questAtStage":
|
|
978
|
-
return { type: "questAtStage", questId:
|
|
1022
|
+
return { type: "questAtStage", questId: e[1], stageId: e[2] };
|
|
979
1023
|
case "characterAt":
|
|
980
1024
|
return {
|
|
981
1025
|
type: "characterAt",
|
|
982
|
-
characterId:
|
|
983
|
-
locationId:
|
|
1026
|
+
characterId: e[1],
|
|
1027
|
+
locationId: e[2]
|
|
984
1028
|
};
|
|
985
1029
|
case "characterInParty":
|
|
986
|
-
return { type: "characterInParty", characterId:
|
|
1030
|
+
return { type: "characterInParty", characterId: e[1] };
|
|
987
1031
|
case "relationshipAbove":
|
|
988
1032
|
return {
|
|
989
1033
|
type: "relationshipAbove",
|
|
990
|
-
characterId:
|
|
991
|
-
value: Number(
|
|
1034
|
+
characterId: e[1],
|
|
1035
|
+
value: Number(e[2])
|
|
992
1036
|
};
|
|
993
1037
|
case "relationshipBelow":
|
|
994
1038
|
return {
|
|
995
1039
|
type: "relationshipBelow",
|
|
996
|
-
characterId:
|
|
997
|
-
value: Number(
|
|
1040
|
+
characterId: e[1],
|
|
1041
|
+
value: Number(e[2])
|
|
998
1042
|
};
|
|
999
1043
|
case "timeIs":
|
|
1000
|
-
return { type: "timeIs", startHour: Number(
|
|
1044
|
+
return { type: "timeIs", startHour: Number(e[1]), endHour: Number(e[2]) };
|
|
1001
1045
|
case "itemAt":
|
|
1002
|
-
return { type: "itemAt", itemId:
|
|
1046
|
+
return { type: "itemAt", itemId: e[1], locationId: e[2] };
|
|
1003
1047
|
default:
|
|
1004
|
-
throw new Error(`Unknown condition type: ${
|
|
1048
|
+
throw new Error(`Unknown condition type: ${n}`);
|
|
1005
1049
|
}
|
|
1006
1050
|
}
|
|
1007
|
-
function
|
|
1008
|
-
const
|
|
1009
|
-
if (
|
|
1010
|
-
return { type: "notify", message:
|
|
1011
|
-
if (
|
|
1012
|
-
return { type: "playMusic", track:
|
|
1013
|
-
if (
|
|
1014
|
-
return { type: "playSound", sound:
|
|
1015
|
-
if (
|
|
1016
|
-
return { type: "playVideo", file:
|
|
1017
|
-
|
|
1051
|
+
function A(t) {
|
|
1052
|
+
const e = t.trim();
|
|
1053
|
+
if (e.startsWith("NOTIFY "))
|
|
1054
|
+
return { type: "notify", message: N(e.substring(7)) };
|
|
1055
|
+
if (e.startsWith("MUSIC "))
|
|
1056
|
+
return { type: "playMusic", track: e.substring(6).trim() };
|
|
1057
|
+
if (e.startsWith("SOUND "))
|
|
1058
|
+
return { type: "playSound", sound: e.substring(6).trim() };
|
|
1059
|
+
if (e.startsWith("VIDEO "))
|
|
1060
|
+
return { type: "playVideo", file: e.substring(6).trim() };
|
|
1061
|
+
if (e.startsWith("INTERLUDE "))
|
|
1062
|
+
return { type: "showInterlude", interludeId: e.substring(10).trim() };
|
|
1063
|
+
const n = e.split(/\s+/), r = n[0];
|
|
1018
1064
|
switch (r) {
|
|
1019
1065
|
case "SET":
|
|
1020
|
-
if (
|
|
1021
|
-
return { type: "setFlag", flag:
|
|
1022
|
-
if (
|
|
1066
|
+
if (n[1] === "flag")
|
|
1067
|
+
return { type: "setFlag", flag: n[2] };
|
|
1068
|
+
if (n[1] === "variable")
|
|
1023
1069
|
return {
|
|
1024
1070
|
type: "setVariable",
|
|
1025
|
-
variable:
|
|
1026
|
-
value: isNaN(Number(
|
|
1071
|
+
variable: n[2],
|
|
1072
|
+
value: isNaN(Number(n[3])) ? n[3] : Number(n[3])
|
|
1027
1073
|
};
|
|
1028
|
-
if (
|
|
1029
|
-
return { type: "setQuestStage", questId:
|
|
1030
|
-
if (
|
|
1074
|
+
if (n[1] === "questStage")
|
|
1075
|
+
return { type: "setQuestStage", questId: n[2], stageId: n[3] };
|
|
1076
|
+
if (n[1] === "characterLocation")
|
|
1031
1077
|
return {
|
|
1032
1078
|
type: "setCharacterLocation",
|
|
1033
|
-
characterId:
|
|
1034
|
-
locationId:
|
|
1079
|
+
characterId: n[2],
|
|
1080
|
+
locationId: n[3]
|
|
1035
1081
|
};
|
|
1036
|
-
if (
|
|
1082
|
+
if (n[1] === "relationship")
|
|
1037
1083
|
return {
|
|
1038
1084
|
type: "setRelationship",
|
|
1039
|
-
characterId:
|
|
1040
|
-
value: Number(
|
|
1085
|
+
characterId: n[2],
|
|
1086
|
+
value: Number(n[3])
|
|
1041
1087
|
};
|
|
1042
|
-
if (
|
|
1088
|
+
if (n[1] === "characterStat")
|
|
1043
1089
|
return {
|
|
1044
1090
|
type: "setCharacterStat",
|
|
1045
|
-
characterId:
|
|
1046
|
-
stat:
|
|
1047
|
-
value: isNaN(Number(
|
|
1091
|
+
characterId: n[2],
|
|
1092
|
+
stat: n[3],
|
|
1093
|
+
value: isNaN(Number(n[4])) ? n[4] : Number(n[4])
|
|
1048
1094
|
};
|
|
1049
|
-
if (
|
|
1050
|
-
return { type: "setMapEnabled", enabled:
|
|
1051
|
-
throw new Error(`Unknown SET effect: ${
|
|
1095
|
+
if (n[1] === "mapEnabled")
|
|
1096
|
+
return { type: "setMapEnabled", enabled: n[2] === "true" };
|
|
1097
|
+
throw new Error(`Unknown SET effect: ${n[1]}`);
|
|
1052
1098
|
case "CLEAR":
|
|
1053
|
-
if (
|
|
1054
|
-
return { type: "clearFlag", flag:
|
|
1055
|
-
throw new Error(`Unknown CLEAR effect: ${
|
|
1099
|
+
if (n[1] === "flag")
|
|
1100
|
+
return { type: "clearFlag", flag: n[2] };
|
|
1101
|
+
throw new Error(`Unknown CLEAR effect: ${n[1]}`);
|
|
1056
1102
|
case "ADD":
|
|
1057
|
-
if (
|
|
1103
|
+
if (n[1] === "variable")
|
|
1058
1104
|
return {
|
|
1059
1105
|
type: "addVariable",
|
|
1060
|
-
variable:
|
|
1061
|
-
value: Number(
|
|
1106
|
+
variable: n[2],
|
|
1107
|
+
value: Number(n[3])
|
|
1062
1108
|
};
|
|
1063
|
-
if (
|
|
1064
|
-
return { type: "addItem", itemId:
|
|
1065
|
-
if (
|
|
1066
|
-
return { type: "addJournalEntry", entryId:
|
|
1067
|
-
if (
|
|
1068
|
-
return { type: "addToParty", characterId:
|
|
1069
|
-
if (
|
|
1109
|
+
if (n[1] === "item")
|
|
1110
|
+
return { type: "addItem", itemId: n[2] };
|
|
1111
|
+
if (n[1] === "journalEntry")
|
|
1112
|
+
return { type: "addJournalEntry", entryId: n[2] };
|
|
1113
|
+
if (n[1] === "toParty")
|
|
1114
|
+
return { type: "addToParty", characterId: n[2] };
|
|
1115
|
+
if (n[1] === "relationship")
|
|
1070
1116
|
return {
|
|
1071
1117
|
type: "addRelationship",
|
|
1072
|
-
characterId:
|
|
1073
|
-
value: Number(
|
|
1118
|
+
characterId: n[2],
|
|
1119
|
+
value: Number(n[3])
|
|
1074
1120
|
};
|
|
1075
|
-
if (
|
|
1121
|
+
if (n[1] === "characterStat")
|
|
1076
1122
|
return {
|
|
1077
1123
|
type: "addCharacterStat",
|
|
1078
|
-
characterId:
|
|
1079
|
-
stat:
|
|
1080
|
-
value: Number(
|
|
1124
|
+
characterId: n[2],
|
|
1125
|
+
stat: n[3],
|
|
1126
|
+
value: Number(n[4])
|
|
1081
1127
|
};
|
|
1082
|
-
throw new Error(`Unknown ADD effect: ${
|
|
1128
|
+
throw new Error(`Unknown ADD effect: ${n[1]}`);
|
|
1083
1129
|
case "REMOVE":
|
|
1084
|
-
if (
|
|
1085
|
-
return { type: "removeItem", itemId:
|
|
1086
|
-
if (
|
|
1087
|
-
return { type: "removeFromParty", characterId:
|
|
1088
|
-
throw new Error(`Unknown REMOVE effect: ${
|
|
1130
|
+
if (n[1] === "item")
|
|
1131
|
+
return { type: "removeItem", itemId: n[2] };
|
|
1132
|
+
if (n[1] === "fromParty")
|
|
1133
|
+
return { type: "removeFromParty", characterId: n[2] };
|
|
1134
|
+
throw new Error(`Unknown REMOVE effect: ${n[1]}`);
|
|
1089
1135
|
case "MOVE":
|
|
1090
|
-
if (
|
|
1091
|
-
return { type: "moveItem", itemId:
|
|
1092
|
-
throw new Error(`Unknown MOVE effect: ${
|
|
1136
|
+
if (n[1] === "item")
|
|
1137
|
+
return { type: "moveItem", itemId: n[2], locationId: n[3] };
|
|
1138
|
+
throw new Error(`Unknown MOVE effect: ${n[1]}`);
|
|
1093
1139
|
case "GOTO":
|
|
1094
|
-
if (
|
|
1095
|
-
return { type: "goToLocation", locationId:
|
|
1140
|
+
if (n[1] === "location")
|
|
1141
|
+
return { type: "goToLocation", locationId: n[2] };
|
|
1096
1142
|
throw new Error("GOTO should not be parsed as an effect");
|
|
1097
1143
|
case "ADVANCE":
|
|
1098
|
-
if (
|
|
1099
|
-
return { type: "advanceTime", hours: Number(
|
|
1100
|
-
throw new Error(`Unknown ADVANCE effect: ${
|
|
1144
|
+
if (n[1] === "time")
|
|
1145
|
+
return { type: "advanceTime", hours: Number(n[2]) };
|
|
1146
|
+
throw new Error(`Unknown ADVANCE effect: ${n[1]}`);
|
|
1101
1147
|
case "START":
|
|
1102
|
-
if (
|
|
1103
|
-
return { type: "startDialogue", dialogueId:
|
|
1104
|
-
throw new Error(`Unknown START effect: ${
|
|
1148
|
+
if (n[1] === "dialogue")
|
|
1149
|
+
return { type: "startDialogue", dialogueId: n[2] };
|
|
1150
|
+
throw new Error(`Unknown START effect: ${n[1]}`);
|
|
1105
1151
|
case "END":
|
|
1106
|
-
if (
|
|
1152
|
+
if (n[1] === "dialogue")
|
|
1107
1153
|
return { type: "endDialogue" };
|
|
1108
1154
|
throw new Error("END should not be parsed as an effect");
|
|
1109
1155
|
default:
|
|
1110
1156
|
throw new Error(`Unknown effect keyword: ${r}`);
|
|
1111
1157
|
}
|
|
1112
1158
|
}
|
|
1113
|
-
function
|
|
1114
|
-
const r =
|
|
1115
|
-
let o = "",
|
|
1116
|
-
const
|
|
1117
|
-
for (;
|
|
1118
|
-
const u =
|
|
1119
|
-
if (u.line === "END" && u.indent ===
|
|
1120
|
-
|
|
1159
|
+
function xe(t, e, n) {
|
|
1160
|
+
const r = t[e], a = N(r.line.substring(7)), s = [], i = [];
|
|
1161
|
+
let o = "", l = e + 1;
|
|
1162
|
+
const c = r.indent;
|
|
1163
|
+
for (; l < t.length; ) {
|
|
1164
|
+
const u = t[l];
|
|
1165
|
+
if (u.line === "END" && u.indent === c) {
|
|
1166
|
+
l++;
|
|
1121
1167
|
break;
|
|
1122
1168
|
}
|
|
1123
1169
|
if (u.line.startsWith("REQUIRE ")) {
|
|
1124
1170
|
const g = u.line.substring(8).trim();
|
|
1125
|
-
s.push(
|
|
1171
|
+
s.push(E(g)), l++;
|
|
1126
1172
|
} else if (u.line.startsWith("GOTO ")) {
|
|
1127
1173
|
const g = u.line.substring(5).trim();
|
|
1128
1174
|
if (g.startsWith("location ")) {
|
|
@@ -1130,71 +1176,71 @@ function Ct(n, t, e) {
|
|
|
1130
1176
|
i.push({ type: "goToLocation", locationId: h }), i.push({ type: "endDialogue" }), o = "";
|
|
1131
1177
|
} else
|
|
1132
1178
|
o = g;
|
|
1133
|
-
|
|
1134
|
-
} else u.line.includes(":") || i.push(
|
|
1179
|
+
l++;
|
|
1180
|
+
} else u.line.includes(":") || i.push(A(u.line)), l++;
|
|
1135
1181
|
}
|
|
1136
1182
|
const d = a.replace(/[@"]/g, "").replace(/[^a-z0-9]/gi, "_");
|
|
1137
1183
|
return { choice: {
|
|
1138
|
-
id: `${
|
|
1184
|
+
id: `${n}_choice_${d.toLowerCase().substring(0, 30)}`,
|
|
1139
1185
|
text: a,
|
|
1140
1186
|
conditions: s.length > 0 ? s : void 0,
|
|
1141
1187
|
effects: i.length > 0 ? i : void 0,
|
|
1142
1188
|
next: o || ""
|
|
1143
|
-
}, nextIndex:
|
|
1189
|
+
}, nextIndex: l };
|
|
1144
1190
|
}
|
|
1145
|
-
function
|
|
1146
|
-
const
|
|
1191
|
+
function ke(t, e) {
|
|
1192
|
+
const n = t[e], r = n.line.substring(3).trim(), a = E(r);
|
|
1147
1193
|
let s;
|
|
1148
1194
|
const i = [];
|
|
1149
|
-
let o =
|
|
1150
|
-
const
|
|
1151
|
-
for (; o <
|
|
1152
|
-
const
|
|
1153
|
-
if (
|
|
1195
|
+
let o = e + 1;
|
|
1196
|
+
const l = n.indent;
|
|
1197
|
+
for (; o < t.length; ) {
|
|
1198
|
+
const c = t[o];
|
|
1199
|
+
if (c.line === "END" && c.indent === l) {
|
|
1154
1200
|
o++;
|
|
1155
1201
|
break;
|
|
1156
1202
|
}
|
|
1157
|
-
|
|
1203
|
+
c.line.startsWith("GOTO ") ? (s = c.line.substring(5).trim(), o++) : (i.push(A(c.line)), o++);
|
|
1158
1204
|
}
|
|
1159
1205
|
return { condition: a, next: s, effects: i, nextIndex: o };
|
|
1160
1206
|
}
|
|
1161
|
-
function
|
|
1162
|
-
const r =
|
|
1207
|
+
function Oe(t, e) {
|
|
1208
|
+
const r = t[e].line.substring(5).trim();
|
|
1163
1209
|
let a = null, s = "", i, o;
|
|
1164
|
-
const
|
|
1210
|
+
const l = [], c = [], d = [];
|
|
1165
1211
|
let f;
|
|
1166
|
-
const
|
|
1167
|
-
let u =
|
|
1168
|
-
for (; u <
|
|
1169
|
-
const h =
|
|
1212
|
+
const b = [];
|
|
1213
|
+
let u = e + 1;
|
|
1214
|
+
for (; u < t.length; ) {
|
|
1215
|
+
const h = t[u];
|
|
1170
1216
|
if (h.line.startsWith("NODE "))
|
|
1171
1217
|
break;
|
|
1172
1218
|
if (h.line.includes(":") && !h.line.startsWith("VOICE")) {
|
|
1173
|
-
const p = h.line.indexOf(":"),
|
|
1174
|
-
|
|
1219
|
+
const p = h.line.indexOf(":"), y = h.line.substring(0, p).trim(), I = h.line.substring(p + 1).trim();
|
|
1220
|
+
y === "NARRATOR" ? a = null : a = y.toLowerCase(), s = N(I), u++;
|
|
1175
1221
|
} else if (h.line.startsWith("VOICE "))
|
|
1176
1222
|
i = h.line.substring(6).trim(), u++;
|
|
1177
1223
|
else if (h.line.startsWith("PORTRAIT "))
|
|
1178
1224
|
o = h.line.substring(9).trim(), u++;
|
|
1179
1225
|
else if (h.line.startsWith("CHOICE ")) {
|
|
1180
|
-
const p =
|
|
1181
|
-
|
|
1226
|
+
const p = xe(t, u, r);
|
|
1227
|
+
c.push(p.choice), u = p.nextIndex;
|
|
1182
1228
|
} else if (h.line.startsWith("IF ")) {
|
|
1183
|
-
const p =
|
|
1184
|
-
p.next &&
|
|
1229
|
+
const p = ke(t, u);
|
|
1230
|
+
p.next && b.push({
|
|
1185
1231
|
condition: p.condition,
|
|
1186
1232
|
next: p.next
|
|
1187
1233
|
}), d.push(...p.effects), u = p.nextIndex;
|
|
1188
1234
|
} else if (h.line.startsWith("GOTO ")) {
|
|
1189
1235
|
const p = h.line.substring(5).trim();
|
|
1190
1236
|
if (p.startsWith("location ")) {
|
|
1191
|
-
const
|
|
1192
|
-
d.push({ type: "goToLocation", locationId:
|
|
1237
|
+
const y = p.substring(9).trim();
|
|
1238
|
+
d.push({ type: "goToLocation", locationId: y }), d.push({ type: "endDialogue" });
|
|
1193
1239
|
} else
|
|
1194
1240
|
f = p;
|
|
1195
1241
|
u++;
|
|
1196
1242
|
} else
|
|
1197
|
-
d.push(
|
|
1243
|
+
d.push(A(h.line)), u++;
|
|
1198
1244
|
}
|
|
1199
1245
|
const g = {
|
|
1200
1246
|
id: r,
|
|
@@ -1202,64 +1248,64 @@ function xt(n, t) {
|
|
|
1202
1248
|
text: s,
|
|
1203
1249
|
voice: i,
|
|
1204
1250
|
portrait: o,
|
|
1205
|
-
conditions:
|
|
1206
|
-
choices:
|
|
1251
|
+
conditions: l.length > 0 ? l : void 0,
|
|
1252
|
+
choices: c,
|
|
1207
1253
|
effects: d.length > 0 ? d : void 0,
|
|
1208
1254
|
next: f
|
|
1209
1255
|
};
|
|
1210
|
-
return
|
|
1256
|
+
return b.length > 0 && (g.conditionalNext = b), { node: g, nextIndex: u };
|
|
1211
1257
|
}
|
|
1212
|
-
function
|
|
1213
|
-
const
|
|
1258
|
+
function Pe(t, e) {
|
|
1259
|
+
const n = Le(t);
|
|
1214
1260
|
let r;
|
|
1215
1261
|
const a = [], s = [];
|
|
1216
1262
|
let i = "", o = 0;
|
|
1217
|
-
for (; o <
|
|
1218
|
-
const
|
|
1219
|
-
if (
|
|
1220
|
-
r =
|
|
1221
|
-
else if (
|
|
1222
|
-
const
|
|
1223
|
-
a.push(
|
|
1224
|
-
} else if (
|
|
1225
|
-
const
|
|
1226
|
-
s.push(
|
|
1263
|
+
for (; o < n.length; ) {
|
|
1264
|
+
const l = n[o];
|
|
1265
|
+
if (l.line.startsWith("TRIGGER "))
|
|
1266
|
+
r = l.line.substring(8).trim(), o++;
|
|
1267
|
+
else if (l.line.startsWith("REQUIRE ")) {
|
|
1268
|
+
const c = l.line.substring(8).trim();
|
|
1269
|
+
a.push(E(c)), o++;
|
|
1270
|
+
} else if (l.line.startsWith("NODE ")) {
|
|
1271
|
+
const c = Oe(n, o);
|
|
1272
|
+
s.push(c.node), i || (i = c.node.id), o = c.nextIndex;
|
|
1227
1273
|
} else
|
|
1228
|
-
throw new Error(`Unexpected token at line ${
|
|
1274
|
+
throw new Error(`Unexpected token at line ${l.lineNumber}: ${l.line}`);
|
|
1229
1275
|
}
|
|
1230
1276
|
return {
|
|
1231
|
-
id:
|
|
1277
|
+
id: e,
|
|
1232
1278
|
triggerLocation: r,
|
|
1233
1279
|
conditions: a.length > 0 ? a : void 0,
|
|
1234
1280
|
startNode: i,
|
|
1235
1281
|
nodes: s
|
|
1236
1282
|
};
|
|
1237
1283
|
}
|
|
1238
|
-
function
|
|
1239
|
-
const
|
|
1284
|
+
function $e(t, e) {
|
|
1285
|
+
const n = t;
|
|
1240
1286
|
window.doodle = {
|
|
1241
1287
|
// Flag manipulation
|
|
1242
1288
|
setFlag(r) {
|
|
1243
|
-
|
|
1289
|
+
n.state.flags[r] = !0, e(), console.log(`🐾 Flag set: ${r}`);
|
|
1244
1290
|
},
|
|
1245
1291
|
clearFlag(r) {
|
|
1246
|
-
delete
|
|
1292
|
+
delete n.state.flags[r], e(), console.log(`🐾 Flag cleared: ${r}`);
|
|
1247
1293
|
},
|
|
1248
1294
|
// Variable manipulation
|
|
1249
1295
|
setVariable(r, a) {
|
|
1250
|
-
|
|
1296
|
+
n.state.variables[r] = a, e(), console.log(`🐾 Variable set: ${r} = ${a}`);
|
|
1251
1297
|
},
|
|
1252
1298
|
getVariable(r) {
|
|
1253
|
-
const a =
|
|
1299
|
+
const a = n.state.variables[r];
|
|
1254
1300
|
return console.log(`🐾 Variable: ${r} = ${a}`), a;
|
|
1255
1301
|
},
|
|
1256
1302
|
// Location control
|
|
1257
1303
|
teleport(r) {
|
|
1258
|
-
|
|
1304
|
+
t.travelTo(r), e(), console.log(`🐾 Teleported to: ${r}`);
|
|
1259
1305
|
},
|
|
1260
1306
|
// Dialogue control
|
|
1261
1307
|
triggerDialogue(r) {
|
|
1262
|
-
const a =
|
|
1308
|
+
const a = n.registry.dialogues[r];
|
|
1263
1309
|
if (!a) {
|
|
1264
1310
|
console.error(`🐾 Dialogue not found: ${r}`);
|
|
1265
1311
|
return;
|
|
@@ -1269,49 +1315,49 @@ function Dt(n, t) {
|
|
|
1269
1315
|
console.error(`🐾 Start node not found for dialogue: ${r}`);
|
|
1270
1316
|
return;
|
|
1271
1317
|
}
|
|
1272
|
-
|
|
1318
|
+
n.state.dialogueState = {
|
|
1273
1319
|
dialogueId: a.id,
|
|
1274
1320
|
nodeId: s.id
|
|
1275
|
-
},
|
|
1321
|
+
}, e(), console.log(`🐾 Triggered dialogue: ${r}`);
|
|
1276
1322
|
},
|
|
1277
1323
|
// Quest control
|
|
1278
1324
|
setQuestStage(r, a) {
|
|
1279
|
-
|
|
1325
|
+
n.state.questProgress[r] = a, e(), console.log(`🐾 Quest stage set: ${r} -> ${a}`);
|
|
1280
1326
|
},
|
|
1281
1327
|
// Inventory control
|
|
1282
1328
|
addItem(r) {
|
|
1283
|
-
|
|
1329
|
+
n.state.inventory.includes(r) ? console.log(`🐾 Item already in inventory: ${r}`) : (n.state.inventory.push(r), n.state.itemLocations[r] = "inventory", e(), console.log(`🐾 Item added: ${r}`));
|
|
1284
1330
|
},
|
|
1285
1331
|
removeItem(r) {
|
|
1286
|
-
const a =
|
|
1287
|
-
a !== -1 ? (
|
|
1332
|
+
const a = n.state.inventory.indexOf(r);
|
|
1333
|
+
a !== -1 ? (n.state.inventory.splice(a, 1), delete n.state.itemLocations[r], e(), console.log(`🐾 Item removed: ${r}`)) : console.log(`🐾 Item not in inventory: ${r}`);
|
|
1288
1334
|
},
|
|
1289
1335
|
// Inspection
|
|
1290
1336
|
inspect() {
|
|
1291
|
-
const r =
|
|
1292
|
-
console.log("🐾 DOODLE ENGINE INSPECTOR 🐾"), console.log(""), console.log("Current Location:", r.location.name), console.log("Current Time:", `Day ${r.time.day}, Hour ${r.time.hour}`), console.log("Flags:", Object.keys(
|
|
1337
|
+
const r = t.getSnapshot();
|
|
1338
|
+
console.log("🐾 DOODLE ENGINE INSPECTOR 🐾"), console.log(""), console.log("Current Location:", r.location.name), console.log("Current Time:", `Day ${r.time.day}, Hour ${r.time.hour}`), console.log("Flags:", Object.keys(n.state.flags)), console.log("Variables:", n.state.variables), console.log("Inventory:", r.inventory.map((a) => a.name)), console.log("Quest Progress:", n.state.questProgress), console.log(""), console.log("Available commands:"), console.log(" doodle.setFlag(flag)"), console.log(" doodle.clearFlag(flag)"), console.log(" doodle.setVariable(variable, value)"), console.log(" doodle.getVariable(variable)"), console.log(" doodle.teleport(locationId)"), console.log(" doodle.triggerDialogue(dialogueId)"), console.log(" doodle.setQuestStage(questId, stageId)"), console.log(" doodle.addItem(itemId)"), console.log(" doodle.removeItem(itemId)"), console.log(" doodle.inspectState()"), console.log(" doodle.inspectRegistry()");
|
|
1293
1339
|
},
|
|
1294
1340
|
inspectState() {
|
|
1295
|
-
return console.log("🐾 GAME STATE:",
|
|
1341
|
+
return console.log("🐾 GAME STATE:", n.state), n.state;
|
|
1296
1342
|
},
|
|
1297
1343
|
inspectRegistry() {
|
|
1298
|
-
return console.log("🐾 CONTENT REGISTRY:",
|
|
1344
|
+
return console.log("🐾 CONTENT REGISTRY:", n.registry), n.registry;
|
|
1299
1345
|
}
|
|
1300
1346
|
}, console.log("🐾 Doodle Engine dev tools enabled! Type `doodle.inspect()` to see available commands.");
|
|
1301
1347
|
}
|
|
1302
|
-
const
|
|
1348
|
+
const qe = "0.0.1";
|
|
1303
1349
|
export {
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1350
|
+
De as Engine,
|
|
1351
|
+
qe as VERSION,
|
|
1352
|
+
U as applyEffect,
|
|
1353
|
+
S as applyEffects,
|
|
1354
|
+
ye as buildSnapshot,
|
|
1355
|
+
Re as createResolver,
|
|
1356
|
+
$e as enableDevTools,
|
|
1311
1357
|
O as evaluateCondition,
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1358
|
+
v as evaluateConditions,
|
|
1359
|
+
E as parseCondition,
|
|
1360
|
+
Pe as parseDialogue,
|
|
1361
|
+
A as parseEffect,
|
|
1362
|
+
C as resolveText
|
|
1317
1363
|
};
|