sonolus-pjsekai-js 1.1.11 → 1.2.0
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/dist/EnginePlayData +0 -0
- package/dist/EnginePreviewData +0 -0
- package/dist/EngineWatchData +0 -0
- package/dist/index.cjs +32 -30
- package/dist/index.d.cts +5 -4
- package/dist/sus/analyze.cjs +23 -25
- package/dist/sus/convert.cjs +19 -22
- package/dist/sus/convert.d.cts +1 -1
- package/dist/sus/decode.cjs +318 -0
- package/dist/sus/decode.d.cts +1 -0
- package/dist/sus/index.cjs +18 -0
- package/dist/{usc/index.d.ts → sus/index.d.cts} +19 -19
- package/dist/sus/revert.cjs +339 -0
- package/dist/sus/revert.d.cts +1 -0
- package/dist/usc/ccIndex.cjs +18 -0
- package/dist/usc/ccIndex.d.cts +91 -0
- package/dist/usc/convert.cjs +56 -142
- package/dist/usc/convert.d.cts +2 -2
- package/dist/usc/index.cjs +0 -16
- package/dist/usc/index.d.cts +16 -42
- package/dist/usc/revert.cjs +169 -0
- package/dist/usc/revert.d.cts +8 -0
- package/package.json +39 -39
- package/dist/sus/analyze.d.ts +0 -29
- package/dist/sus/analyze.js +0 -262
- package/dist/sus/convert.d.ts +0 -5
- package/dist/sus/convert.js +0 -301
- package/dist/usc/convert.d.ts +0 -3
- package/dist/usc/convert.js +0 -542
- package/dist/usc/index.js +0 -15
package/dist/usc/convert.js
DELETED
@@ -1,542 +0,0 @@
|
|
1
|
-
import { EngineArchetypeDataName, EngineArchetypeName, } from "@sonolus/core";
|
2
|
-
import { USCColor, USCFade, } from "./index.js";
|
3
|
-
export const uscToLevelData = (usc, offset = 0) => {
|
4
|
-
const entities = [];
|
5
|
-
const timeToIntermediates = new Map();
|
6
|
-
const intermediateToRef = new Map();
|
7
|
-
const intermediateToEntity = new Map();
|
8
|
-
let i = 0;
|
9
|
-
const getRef = (intermediate) => {
|
10
|
-
let ref = intermediateToRef.get(intermediate);
|
11
|
-
if (ref)
|
12
|
-
return ref;
|
13
|
-
ref = (i++).toString(36);
|
14
|
-
intermediateToRef.set(intermediate, ref);
|
15
|
-
const entity = intermediateToEntity.get(intermediate);
|
16
|
-
if (entity)
|
17
|
-
entity.name = ref;
|
18
|
-
return ref;
|
19
|
-
};
|
20
|
-
const append = (intermediate) => {
|
21
|
-
const entity = {
|
22
|
-
archetype: intermediate.archetype,
|
23
|
-
data: [],
|
24
|
-
};
|
25
|
-
if (intermediate.sim) {
|
26
|
-
const beat = intermediate.data[EngineArchetypeDataName.Beat];
|
27
|
-
if (typeof beat !== "number")
|
28
|
-
throw new Error("Unexpected beat");
|
29
|
-
const intermediates = timeToIntermediates.get(beat);
|
30
|
-
if (intermediates) {
|
31
|
-
intermediates.push(intermediate);
|
32
|
-
}
|
33
|
-
else {
|
34
|
-
timeToIntermediates.set(beat, [intermediate]);
|
35
|
-
}
|
36
|
-
}
|
37
|
-
const ref = intermediateToRef.get(intermediate);
|
38
|
-
if (ref)
|
39
|
-
entity.name = ref;
|
40
|
-
intermediateToEntity.set(intermediate, entity);
|
41
|
-
entities.push(entity);
|
42
|
-
for (const [name, value] of Object.entries(intermediate.data)) {
|
43
|
-
if (typeof value === "number") {
|
44
|
-
entity.data.push({
|
45
|
-
name,
|
46
|
-
value,
|
47
|
-
});
|
48
|
-
}
|
49
|
-
else if (typeof value === "boolean") {
|
50
|
-
entity.data.push({
|
51
|
-
name,
|
52
|
-
value: value ? 1 : 0,
|
53
|
-
});
|
54
|
-
}
|
55
|
-
else if (typeof value === "string") {
|
56
|
-
entity.data.push({
|
57
|
-
name,
|
58
|
-
ref: value,
|
59
|
-
});
|
60
|
-
}
|
61
|
-
else {
|
62
|
-
entity.data.push({
|
63
|
-
name,
|
64
|
-
ref: getRef(value),
|
65
|
-
});
|
66
|
-
}
|
67
|
-
}
|
68
|
-
if ("timeScaleGroup" in intermediate) {
|
69
|
-
entity.data.push({
|
70
|
-
name: "timeScaleGroup",
|
71
|
-
ref: `tsg:${intermediate.timeScaleGroup ?? 0}`,
|
72
|
-
});
|
73
|
-
}
|
74
|
-
};
|
75
|
-
append({
|
76
|
-
archetype: "Initialization",
|
77
|
-
data: {},
|
78
|
-
sim: false,
|
79
|
-
});
|
80
|
-
append({
|
81
|
-
archetype: "InputManager",
|
82
|
-
data: {},
|
83
|
-
sim: false,
|
84
|
-
});
|
85
|
-
append({
|
86
|
-
archetype: "Stage",
|
87
|
-
data: {},
|
88
|
-
sim: false,
|
89
|
-
});
|
90
|
-
let tsGroupIndex = -1;
|
91
|
-
const tsGroupEntities = [];
|
92
|
-
const tsChangeEntities = [];
|
93
|
-
for (const tsGroup of usc.objects) {
|
94
|
-
if (tsGroup.type !== "timeScaleGroup")
|
95
|
-
continue;
|
96
|
-
tsGroupIndex++;
|
97
|
-
const changes = [...tsGroup.changes];
|
98
|
-
changes.sort((a, b) => a.beat - b.beat);
|
99
|
-
for (const [index, change] of Object.entries(changes)) {
|
100
|
-
tsChangeEntities.push({
|
101
|
-
archetype: "TimeScaleChange",
|
102
|
-
data: [
|
103
|
-
{
|
104
|
-
name: EngineArchetypeDataName.Beat,
|
105
|
-
value: change.beat,
|
106
|
-
},
|
107
|
-
{
|
108
|
-
name: "timeScale",
|
109
|
-
value: change.timeScale === 0 ? 0.000001 : change.timeScale,
|
110
|
-
},
|
111
|
-
tsGroup.changes[+index + 1] === undefined
|
112
|
-
? {
|
113
|
-
name: "next",
|
114
|
-
value: -1,
|
115
|
-
}
|
116
|
-
: {
|
117
|
-
name: "next",
|
118
|
-
ref: `tsc:${tsGroupIndex}:${+index + 1}`,
|
119
|
-
},
|
120
|
-
],
|
121
|
-
name: `tsc:${tsGroupIndex}:${index}`,
|
122
|
-
});
|
123
|
-
}
|
124
|
-
tsGroupEntities.push({
|
125
|
-
archetype: "TimeScaleGroup",
|
126
|
-
data: [
|
127
|
-
{
|
128
|
-
name: "first",
|
129
|
-
ref: `tsc:${tsGroupIndex}:0`,
|
130
|
-
},
|
131
|
-
{
|
132
|
-
name: "length",
|
133
|
-
value: tsGroup.changes.length,
|
134
|
-
},
|
135
|
-
tsGroupIndex === tsGroup.changes.length - 1
|
136
|
-
? {
|
137
|
-
name: "next",
|
138
|
-
value: -1,
|
139
|
-
}
|
140
|
-
: {
|
141
|
-
name: "next",
|
142
|
-
ref: `tsg:${tsGroupIndex + 1}`,
|
143
|
-
},
|
144
|
-
],
|
145
|
-
name: `tsg:${tsGroupIndex}`,
|
146
|
-
});
|
147
|
-
}
|
148
|
-
if (tsGroupIndex === -1) {
|
149
|
-
entities.push({
|
150
|
-
archetype: "TimeScaleGroup",
|
151
|
-
data: [
|
152
|
-
{
|
153
|
-
name: "first",
|
154
|
-
ref: "tsc:0:0",
|
155
|
-
},
|
156
|
-
{
|
157
|
-
name: "length",
|
158
|
-
value: 0,
|
159
|
-
},
|
160
|
-
],
|
161
|
-
name: "tsg:0",
|
162
|
-
});
|
163
|
-
entities.push({
|
164
|
-
archetype: "TimeScaleChange",
|
165
|
-
data: [
|
166
|
-
{
|
167
|
-
name: EngineArchetypeDataName.Beat,
|
168
|
-
value: 0,
|
169
|
-
},
|
170
|
-
{
|
171
|
-
name: "timeScale",
|
172
|
-
value: 1,
|
173
|
-
},
|
174
|
-
{
|
175
|
-
name: "timeScaleGroup",
|
176
|
-
ref: "trg:0",
|
177
|
-
},
|
178
|
-
],
|
179
|
-
name: "tsc:0:0",
|
180
|
-
});
|
181
|
-
}
|
182
|
-
else {
|
183
|
-
entities.push(...tsGroupEntities);
|
184
|
-
entities.push(...tsChangeEntities);
|
185
|
-
}
|
186
|
-
for (const object of usc.objects) {
|
187
|
-
handlers[object.type](object, append);
|
188
|
-
}
|
189
|
-
for (const intermediates of timeToIntermediates.values()) {
|
190
|
-
for (let i = 1; i < intermediates.length; i++) {
|
191
|
-
append({
|
192
|
-
archetype: "SimLine",
|
193
|
-
data: {
|
194
|
-
a: intermediates[i - 1],
|
195
|
-
b: intermediates[i],
|
196
|
-
},
|
197
|
-
sim: false,
|
198
|
-
});
|
199
|
-
}
|
200
|
-
}
|
201
|
-
return {
|
202
|
-
bgmOffset: usc.offset + offset,
|
203
|
-
entities,
|
204
|
-
};
|
205
|
-
};
|
206
|
-
const directions = {
|
207
|
-
left: -1,
|
208
|
-
up: 0,
|
209
|
-
right: 1,
|
210
|
-
};
|
211
|
-
const eases = {
|
212
|
-
outIn: -2,
|
213
|
-
out: -1,
|
214
|
-
linear: 0,
|
215
|
-
in: 1,
|
216
|
-
inOut: 2,
|
217
|
-
};
|
218
|
-
const slideStarts = {
|
219
|
-
tap: 0,
|
220
|
-
trace: 1,
|
221
|
-
none: 2,
|
222
|
-
};
|
223
|
-
const bpm = (object, append) => {
|
224
|
-
append({
|
225
|
-
archetype: EngineArchetypeName.BpmChange,
|
226
|
-
data: {
|
227
|
-
[EngineArchetypeDataName.Beat]: object.beat,
|
228
|
-
[EngineArchetypeDataName.Bpm]: object.bpm,
|
229
|
-
},
|
230
|
-
sim: false,
|
231
|
-
});
|
232
|
-
};
|
233
|
-
const timeScaleGroup = () => undefined;
|
234
|
-
const single = (object, append) => {
|
235
|
-
const intermediate = {
|
236
|
-
archetype: object.critical ? "CriticalTapNote" : "NormalTapNote",
|
237
|
-
data: {
|
238
|
-
[EngineArchetypeDataName.Beat]: object.beat,
|
239
|
-
lane: object.lane,
|
240
|
-
size: object.size,
|
241
|
-
},
|
242
|
-
timeScaleGroup: object.timeScaleGroup,
|
243
|
-
sim: true,
|
244
|
-
};
|
245
|
-
if (object.trace) {
|
246
|
-
intermediate.archetype = object.critical
|
247
|
-
? "CriticalTraceNote"
|
248
|
-
: "NormalTraceNote";
|
249
|
-
if (object.direction) {
|
250
|
-
if (object.direction === "none") {
|
251
|
-
intermediate.archetype = "NonDirectionalTraceFlickNote";
|
252
|
-
}
|
253
|
-
else {
|
254
|
-
intermediate.archetype = object.critical
|
255
|
-
? "CriticalTraceFlickNote"
|
256
|
-
: "NormalTraceFlickNote";
|
257
|
-
intermediate.data.direction = directions[object.direction];
|
258
|
-
}
|
259
|
-
}
|
260
|
-
}
|
261
|
-
else {
|
262
|
-
if (object.direction) {
|
263
|
-
intermediate.archetype = object.critical
|
264
|
-
? "CriticalFlickNote"
|
265
|
-
: "NormalFlickNote";
|
266
|
-
if (object.direction === "none") {
|
267
|
-
return;
|
268
|
-
}
|
269
|
-
intermediate.data.direction = directions[object.direction];
|
270
|
-
}
|
271
|
-
}
|
272
|
-
append(intermediate);
|
273
|
-
};
|
274
|
-
const damage = (object, append) => {
|
275
|
-
const intermediate = {
|
276
|
-
archetype: "IgnoredSlideTickNote",
|
277
|
-
data: {
|
278
|
-
[EngineArchetypeDataName.Beat]: object.beat,
|
279
|
-
lane: object.lane,
|
280
|
-
size: object.size,
|
281
|
-
},
|
282
|
-
sim: false,
|
283
|
-
timeScaleGroup: object.timeScaleGroup,
|
284
|
-
};
|
285
|
-
append(intermediate);
|
286
|
-
};
|
287
|
-
const slide = (object, append) => {
|
288
|
-
const cis = [];
|
289
|
-
const joints = [];
|
290
|
-
const attaches = [];
|
291
|
-
const ends = [];
|
292
|
-
let startType = "tap";
|
293
|
-
const connections = getConnections(object);
|
294
|
-
for (const [i, connection] of connections.entries()) {
|
295
|
-
if (i === 0) {
|
296
|
-
if (connection.type !== "start")
|
297
|
-
continue;
|
298
|
-
let archetype;
|
299
|
-
let sim = true;
|
300
|
-
if (connection.judgeType === "none") {
|
301
|
-
archetype = "HiddenSlideStartNote";
|
302
|
-
sim = false;
|
303
|
-
startType = "none";
|
304
|
-
}
|
305
|
-
else if (connection.judgeType === "trace") {
|
306
|
-
if (connection.critical) {
|
307
|
-
archetype = "CriticalTraceSlideStartNote";
|
308
|
-
}
|
309
|
-
else {
|
310
|
-
archetype = "NormalTraceSlideStartNote";
|
311
|
-
}
|
312
|
-
startType = "trace";
|
313
|
-
}
|
314
|
-
else {
|
315
|
-
if (connection.critical) {
|
316
|
-
archetype = "CriticalSlideStartNote";
|
317
|
-
}
|
318
|
-
else {
|
319
|
-
archetype = "NormalSlideStartNote";
|
320
|
-
}
|
321
|
-
startType = "tap";
|
322
|
-
}
|
323
|
-
const ci = {
|
324
|
-
archetype,
|
325
|
-
data: {
|
326
|
-
[EngineArchetypeDataName.Beat]: connection.beat,
|
327
|
-
lane: connection.lane,
|
328
|
-
size: connection.size,
|
329
|
-
},
|
330
|
-
sim,
|
331
|
-
ease: connection.ease,
|
332
|
-
timeScaleGroup: connection.timeScaleGroup,
|
333
|
-
};
|
334
|
-
cis.push(ci);
|
335
|
-
joints.push(ci);
|
336
|
-
continue;
|
337
|
-
}
|
338
|
-
if (i === connections.length - 1) {
|
339
|
-
if (connection.type !== "end")
|
340
|
-
continue;
|
341
|
-
let ci;
|
342
|
-
if (connection.judgeType === "none") {
|
343
|
-
ci = {
|
344
|
-
archetype: "HiddenSlideTickNote",
|
345
|
-
data: {
|
346
|
-
[EngineArchetypeDataName.Beat]: connection.beat,
|
347
|
-
lane: connection.lane,
|
348
|
-
size: connection.size,
|
349
|
-
},
|
350
|
-
sim: false,
|
351
|
-
timeScaleGroup: connection.timeScaleGroup,
|
352
|
-
};
|
353
|
-
}
|
354
|
-
else {
|
355
|
-
let archetype;
|
356
|
-
if (connection.judgeType === "trace") {
|
357
|
-
if (connection.critical) {
|
358
|
-
archetype = "CriticalTraceSlideEndNote";
|
359
|
-
}
|
360
|
-
else {
|
361
|
-
archetype = "NormalTraceSlideEndNote";
|
362
|
-
}
|
363
|
-
}
|
364
|
-
else {
|
365
|
-
if (connection.critical) {
|
366
|
-
archetype = "CriticalSlideEndNote";
|
367
|
-
}
|
368
|
-
else {
|
369
|
-
archetype = "NormalSlideEndNote";
|
370
|
-
}
|
371
|
-
}
|
372
|
-
ci = {
|
373
|
-
archetype,
|
374
|
-
data: {
|
375
|
-
[EngineArchetypeDataName.Beat]: connection.beat,
|
376
|
-
lane: connection.lane,
|
377
|
-
size: connection.size,
|
378
|
-
},
|
379
|
-
sim: true,
|
380
|
-
timeScaleGroup: connection.timeScaleGroup,
|
381
|
-
};
|
382
|
-
if ("direction" in connection) {
|
383
|
-
ci.archetype = connection.critical
|
384
|
-
? "CriticalSlideEndFlickNote"
|
385
|
-
: "NormalSlideEndFlickNote";
|
386
|
-
ci.data.direction = directions[connection.direction];
|
387
|
-
}
|
388
|
-
}
|
389
|
-
cis.push(ci);
|
390
|
-
joints.push(ci);
|
391
|
-
ends.push(ci);
|
392
|
-
continue;
|
393
|
-
}
|
394
|
-
switch (connection.type) {
|
395
|
-
case "tick": {
|
396
|
-
const ci = {
|
397
|
-
archetype: "HiddenSlideTickNote",
|
398
|
-
data: {
|
399
|
-
[EngineArchetypeDataName.Beat]: connection.beat,
|
400
|
-
lane: connection.lane,
|
401
|
-
size: connection.size,
|
402
|
-
},
|
403
|
-
sim: false,
|
404
|
-
ease: connection.ease,
|
405
|
-
timeScaleGroup: connection.timeScaleGroup,
|
406
|
-
};
|
407
|
-
if ("critical" in connection)
|
408
|
-
ci.archetype = connection.critical
|
409
|
-
? "CriticalSlideTickNote"
|
410
|
-
: "NormalSlideTickNote";
|
411
|
-
cis.push(ci);
|
412
|
-
joints.push(ci);
|
413
|
-
break;
|
414
|
-
}
|
415
|
-
case "attach": {
|
416
|
-
const ci = {
|
417
|
-
archetype: "IgnoredSlideTickNote",
|
418
|
-
data: {
|
419
|
-
[EngineArchetypeDataName.Beat]: connection.beat,
|
420
|
-
},
|
421
|
-
sim: false,
|
422
|
-
};
|
423
|
-
if ("critical" in connection)
|
424
|
-
ci.archetype = connection.critical
|
425
|
-
? "CriticalAttachedSlideTickNote"
|
426
|
-
: "NormalAttachedSlideTickNote";
|
427
|
-
if ("timeScaleGroup" in connection)
|
428
|
-
ci.timeScaleGroup = connection.timeScaleGroup;
|
429
|
-
cis.push(ci);
|
430
|
-
attaches.push(ci);
|
431
|
-
break;
|
432
|
-
}
|
433
|
-
case "start":
|
434
|
-
case "end":
|
435
|
-
throw new Error("Unexpected slide tick");
|
436
|
-
}
|
437
|
-
}
|
438
|
-
const connectors = [];
|
439
|
-
const start = cis[0];
|
440
|
-
for (const [i, joint] of joints.entries()) {
|
441
|
-
if (i === 0)
|
442
|
-
continue;
|
443
|
-
const head = joints[i - 1];
|
444
|
-
if (!head.ease)
|
445
|
-
throw new Error("Unexpected missing ease");
|
446
|
-
const archetype = object.critical
|
447
|
-
? "CriticalSlideConnector"
|
448
|
-
: "NormalSlideConnector";
|
449
|
-
connectors.push({
|
450
|
-
archetype,
|
451
|
-
data: {
|
452
|
-
start,
|
453
|
-
end: ends[0],
|
454
|
-
head,
|
455
|
-
tail: joint,
|
456
|
-
ease: eases[head.ease],
|
457
|
-
startType: slideStarts[startType],
|
458
|
-
},
|
459
|
-
sim: false,
|
460
|
-
});
|
461
|
-
}
|
462
|
-
for (const attach of attaches) {
|
463
|
-
const index = cis.indexOf(attach);
|
464
|
-
const tailIndex = joints.findIndex((c) => cis.indexOf(c) > index);
|
465
|
-
attach.data.attach = connectors[tailIndex - 1];
|
466
|
-
}
|
467
|
-
for (const end of ends) {
|
468
|
-
end.data.slide = connectors[connectors.length - 1];
|
469
|
-
}
|
470
|
-
for (const ci of cis) {
|
471
|
-
append(ci);
|
472
|
-
}
|
473
|
-
for (const connector of connectors) {
|
474
|
-
append(connector);
|
475
|
-
}
|
476
|
-
};
|
477
|
-
const guide = (object, append) => {
|
478
|
-
const start = object.midpoints[0];
|
479
|
-
const end = object.midpoints[object.midpoints.length - 1];
|
480
|
-
for (const [i, joint] of object.midpoints.entries()) {
|
481
|
-
if (i === 0)
|
482
|
-
continue;
|
483
|
-
const head = object.midpoints[i - 1];
|
484
|
-
if (!head.ease)
|
485
|
-
throw new Error("Unexpected missing ease");
|
486
|
-
append({
|
487
|
-
archetype: object.color == 'yellow' ? "CriticalActiveSlideConnector" : "NormalActiveSlideConnector",
|
488
|
-
data: {
|
489
|
-
color: USCColor[object.color],
|
490
|
-
fade: USCFade[object.fade],
|
491
|
-
ease: eases[head.ease],
|
492
|
-
startLane: start.lane,
|
493
|
-
startSize: start.size,
|
494
|
-
startBeat: start.beat,
|
495
|
-
startTimeScaleGroup: `tsg:${start.timeScaleGroup ?? 0}`,
|
496
|
-
headLane: head.lane,
|
497
|
-
headSize: head.size,
|
498
|
-
headBeat: head.beat,
|
499
|
-
headTimeScaleGroup: `tsg:${head.timeScaleGroup ?? 0}`,
|
500
|
-
tailLane: joint.lane,
|
501
|
-
tailSize: joint.size,
|
502
|
-
tailBeat: joint.beat,
|
503
|
-
tailTimeScaleGroup: `tsg:${joint.timeScaleGroup ?? 0}`,
|
504
|
-
endLane: end.lane,
|
505
|
-
endSize: end.size,
|
506
|
-
endBeat: end.beat,
|
507
|
-
endTimeScaleGroup: `tsg:${end.timeScaleGroup ?? 0}`,
|
508
|
-
},
|
509
|
-
sim: false,
|
510
|
-
});
|
511
|
-
}
|
512
|
-
};
|
513
|
-
const handlers = {
|
514
|
-
bpm,
|
515
|
-
single,
|
516
|
-
timeScaleGroup,
|
517
|
-
slide,
|
518
|
-
guide,
|
519
|
-
damage,
|
520
|
-
};
|
521
|
-
const getConnections = (object) => {
|
522
|
-
const connections = [...object.connections];
|
523
|
-
const beats = connections.map(({ beat }) => beat).sort((a, b) => a - b);
|
524
|
-
const min = beats[0];
|
525
|
-
const max = beats[beats.length - 1];
|
526
|
-
const start = Math.max(Math.ceil(min / 0.5) * 0.5, Math.floor(min / 0.5 + 1) * 0.5);
|
527
|
-
for (let beat = start; beat < max; beat += 0.5) {
|
528
|
-
connections.push({
|
529
|
-
type: "attach",
|
530
|
-
beat,
|
531
|
-
});
|
532
|
-
}
|
533
|
-
const startStep = connections.find(({ type }) => type === "start");
|
534
|
-
const endStep = connections.find(({ type }) => type === "end");
|
535
|
-
const steps = connections.filter(({ type }) => type === "tick" || type === "attach");
|
536
|
-
steps.sort((a, b) => a.beat - b.beat);
|
537
|
-
if (!startStep)
|
538
|
-
throw "Missing start";
|
539
|
-
if (!endStep)
|
540
|
-
throw "Missing end";
|
541
|
-
return [startStep, ...steps, endStep];
|
542
|
-
};
|