sonolus-pjsekai-js 1.1.12 → 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/package.json
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
{
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
2
|
+
"name": "sonolus-pjsekai-js",
|
3
|
+
"version": "1.2.0",
|
4
|
+
"description": "A recreation of Project Sekai: Colorful Stage! engine in Sonolus",
|
5
|
+
"type": "module",
|
6
|
+
"files": [
|
7
|
+
"dist"
|
8
|
+
],
|
9
|
+
"exports": {
|
10
|
+
".": "./dist/index.cjs",
|
11
|
+
"./EngineConfiguration": "./dist/EngineConfiguration",
|
12
|
+
"./EnginePlayData": "./dist/EnginePlayData",
|
13
|
+
"./EngineWatchData": "./dist/EngineWatchData",
|
14
|
+
"./EnginePreviewData": "./dist/EnginePreviewData",
|
15
|
+
"./EngineTutorialData": "./dist/EngineTutorialData",
|
16
|
+
"./EngineThumbnail": "./dist/thumbnail.png"
|
17
|
+
},
|
18
|
+
"scripts": {
|
19
|
+
"dev:play": "sonolus-cli --dev ./play",
|
20
|
+
"dev:watch": "sonolus-cli --dev ./watch",
|
21
|
+
"dev:preview": "sonolus-cli --dev ./preview",
|
22
|
+
"dev:tutorial": "sonolus-cli --dev ./tutorial",
|
23
|
+
"format": "prettier . --write",
|
24
|
+
"lint": "eslint .",
|
25
|
+
"lint-fix": "eslint . --fix",
|
26
|
+
"build": "tsc -p ./lib && sonolus-cli --build ./play && sonolus-cli --build ./watch && sonolus-cli --build ./preview && sonolus-cli --build ./tutorial && node ./lib/build.mjs"
|
27
|
+
},
|
28
|
+
"devDependencies": {
|
29
|
+
"@sonolus/sonolus.js": "~9.5.6",
|
30
|
+
"@eslint/js": "^9.27.0",
|
31
|
+
"eslint": "^9.27.0",
|
32
|
+
"eslint-config-prettier": "^10.1.5",
|
33
|
+
"prettier": "^3.5.3",
|
34
|
+
"prettier-plugin-organize-imports": "^4.1.0",
|
35
|
+
"typescript": "~5.8.3",
|
36
|
+
"typescript-eslint": "^8.33.0"
|
37
|
+
},
|
38
|
+
"dependencies": {
|
39
|
+
"@sonolus/core": "~7.13.2"
|
40
|
+
}
|
41
41
|
}
|
package/dist/sus/analyze.d.ts
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
type Meta = Map<string, string[]>;
|
2
|
-
export type TimeScaleChangeObject = {
|
3
|
-
tick: number;
|
4
|
-
timeScale: number;
|
5
|
-
};
|
6
|
-
export type BpmChangeObject = {
|
7
|
-
tick: number;
|
8
|
-
bpm: number;
|
9
|
-
};
|
10
|
-
export type NoteObject = {
|
11
|
-
tick: number;
|
12
|
-
lane: number;
|
13
|
-
width: number;
|
14
|
-
type: number;
|
15
|
-
timeScaleGroup: number;
|
16
|
-
};
|
17
|
-
export type Score = {
|
18
|
-
offset: number;
|
19
|
-
ticksPerBeat: number;
|
20
|
-
timeScaleChanges: TimeScaleChangeObject[][];
|
21
|
-
bpmChanges: BpmChangeObject[];
|
22
|
-
tapNotes: NoteObject[];
|
23
|
-
directionalNotes: NoteObject[];
|
24
|
-
slides: NoteObject[][];
|
25
|
-
guides: NoteObject[][];
|
26
|
-
meta: Meta;
|
27
|
-
};
|
28
|
-
export declare const analyze: (sus: string) => Score;
|
29
|
-
export {};
|
package/dist/sus/analyze.js
DELETED
@@ -1,262 +0,0 @@
|
|
1
|
-
export const analyze = (sus) => {
|
2
|
-
const { lines, measureChanges, timeScaleGroupChanges, meta } = parse(sus);
|
3
|
-
const offset = -+(meta.get("WAVEOFFSET")?.[0] ?? "0");
|
4
|
-
if (Number.isNaN(offset))
|
5
|
-
throw "Unexpected offset";
|
6
|
-
const ticksPerBeat = getTicksPerBeat(meta) ?? 480;
|
7
|
-
if (!ticksPerBeat)
|
8
|
-
throw "Missing or unexpected ticks per beat";
|
9
|
-
const barLengths = getBarLengths(lines, measureChanges);
|
10
|
-
const toTick = getToTick(barLengths, ticksPerBeat);
|
11
|
-
const bpms = new Map();
|
12
|
-
const bpmChanges = [];
|
13
|
-
const timeScaleGroups = new Map();
|
14
|
-
const timeScaleChanges = [];
|
15
|
-
const tapNotes = [];
|
16
|
-
const directionalNotes = [];
|
17
|
-
const streams = new Map();
|
18
|
-
const guideStreams = new Map();
|
19
|
-
for (const [, timeScaleGroup] of timeScaleGroupChanges) {
|
20
|
-
if (timeScaleGroups.has(timeScaleGroup))
|
21
|
-
continue;
|
22
|
-
timeScaleGroups.set(timeScaleGroup, timeScaleGroups.size);
|
23
|
-
timeScaleChanges.push([]);
|
24
|
-
}
|
25
|
-
// Time Scale Changes
|
26
|
-
for (const line of lines) {
|
27
|
-
const [header] = line;
|
28
|
-
if (header.length === 5 && header.startsWith("TIL")) {
|
29
|
-
const timeScaleGroup = header.substring(3, 5);
|
30
|
-
const timeScaleIndex = timeScaleGroups.get(timeScaleGroup);
|
31
|
-
if (timeScaleIndex === undefined) {
|
32
|
-
continue;
|
33
|
-
}
|
34
|
-
timeScaleChanges[timeScaleIndex].push(...toTimeScaleChanges(line, toTick));
|
35
|
-
}
|
36
|
-
}
|
37
|
-
lines.forEach((line, index) => {
|
38
|
-
const [header, data] = line;
|
39
|
-
const measureOffset = measureChanges.find(([changeIndex]) => changeIndex <= index)?.[1] ?? 0;
|
40
|
-
const timeScaleGroupName = timeScaleGroupChanges.find(([changeIndex]) => changeIndex <= index)?.[1] ?? "00";
|
41
|
-
let timeScaleGroup = timeScaleGroups.get(timeScaleGroupName);
|
42
|
-
if (timeScaleGroup === undefined) {
|
43
|
-
timeScaleGroup = timeScaleGroups.size;
|
44
|
-
timeScaleGroups.set(timeScaleGroupName, timeScaleGroups.size);
|
45
|
-
timeScaleChanges.push([]);
|
46
|
-
}
|
47
|
-
// Hispeed definitions
|
48
|
-
if (header.length === 5 && header.startsWith("TIL")) {
|
49
|
-
return;
|
50
|
-
}
|
51
|
-
// BPM
|
52
|
-
if (header.length === 5 && header.startsWith("BPM")) {
|
53
|
-
bpms.set(header.substring(3), +data);
|
54
|
-
return;
|
55
|
-
}
|
56
|
-
// BPM Changes
|
57
|
-
if (header.length === 5 && header.endsWith("08")) {
|
58
|
-
bpmChanges.push(...toBpmChanges(line, measureOffset, bpms, toTick));
|
59
|
-
return;
|
60
|
-
}
|
61
|
-
// Tap Notes
|
62
|
-
if (header.length === 5 && header[3] === "1") {
|
63
|
-
tapNotes.push(...toNotes(line, measureOffset, timeScaleGroup, toTick));
|
64
|
-
return;
|
65
|
-
}
|
66
|
-
// Streams
|
67
|
-
if (header.length === 6 && header[3] === "3") {
|
68
|
-
const channel = header[5];
|
69
|
-
const stream = streams.get(channel);
|
70
|
-
if (stream) {
|
71
|
-
stream.push(...toNotes(line, measureOffset, timeScaleGroup, toTick));
|
72
|
-
}
|
73
|
-
else {
|
74
|
-
streams.set(channel, toNotes(line, measureOffset, timeScaleGroup, toTick));
|
75
|
-
}
|
76
|
-
return;
|
77
|
-
}
|
78
|
-
// Guides
|
79
|
-
if (header.length === 6 && header[3] === "9") {
|
80
|
-
const channel = header[5];
|
81
|
-
const stream = guideStreams.get(channel);
|
82
|
-
if (stream) {
|
83
|
-
stream.push(...toNotes(line, measureOffset, timeScaleGroup, toTick));
|
84
|
-
}
|
85
|
-
else {
|
86
|
-
guideStreams.set(channel, toNotes(line, measureOffset, timeScaleGroup, toTick));
|
87
|
-
}
|
88
|
-
return;
|
89
|
-
}
|
90
|
-
// Directional Notes
|
91
|
-
if (header.length === 5 && header[3] === "5") {
|
92
|
-
directionalNotes.push(...toNotes(line, measureOffset, timeScaleGroup, toTick));
|
93
|
-
return;
|
94
|
-
}
|
95
|
-
});
|
96
|
-
const slides = [...streams.values()].map(toSlides).flat();
|
97
|
-
const guides = [...guideStreams.values()].map(toSlides).flat();
|
98
|
-
return {
|
99
|
-
offset,
|
100
|
-
ticksPerBeat,
|
101
|
-
timeScaleChanges,
|
102
|
-
bpmChanges,
|
103
|
-
tapNotes,
|
104
|
-
directionalNotes,
|
105
|
-
slides,
|
106
|
-
guides,
|
107
|
-
meta,
|
108
|
-
};
|
109
|
-
};
|
110
|
-
const parse = (sus) => {
|
111
|
-
const lines = [];
|
112
|
-
const measureChanges = [];
|
113
|
-
const timeScaleGroupChanges = [];
|
114
|
-
const meta = new Map();
|
115
|
-
sus
|
116
|
-
.split("\n")
|
117
|
-
.map((line) => line.trim())
|
118
|
-
.filter((line) => line.startsWith("#"))
|
119
|
-
.forEach((line) => {
|
120
|
-
const isLine = line.includes(":");
|
121
|
-
const index = line.indexOf(isLine ? ":" : " ");
|
122
|
-
if (index === -1)
|
123
|
-
return;
|
124
|
-
const left = line.substring(1, index).trim();
|
125
|
-
const right = line.substring(index + 1).trim();
|
126
|
-
if (isLine) {
|
127
|
-
lines.push([left, right]);
|
128
|
-
}
|
129
|
-
else if (left === "MEASUREBS") {
|
130
|
-
measureChanges.unshift([lines.length, +right]);
|
131
|
-
}
|
132
|
-
else if (left === "HISPEED") {
|
133
|
-
timeScaleGroupChanges.unshift([lines.length, right]);
|
134
|
-
}
|
135
|
-
else {
|
136
|
-
if (!meta.has(left))
|
137
|
-
meta.set(left, []);
|
138
|
-
meta.get(left)?.push(right);
|
139
|
-
}
|
140
|
-
});
|
141
|
-
return {
|
142
|
-
lines,
|
143
|
-
measureChanges,
|
144
|
-
timeScaleGroupChanges,
|
145
|
-
meta,
|
146
|
-
};
|
147
|
-
};
|
148
|
-
const getTicksPerBeat = (meta) => {
|
149
|
-
const request = meta.get("REQUEST");
|
150
|
-
if (!request)
|
151
|
-
return;
|
152
|
-
const tpbRequest = request.find((r) => JSON.parse(r).startsWith("ticks_per_beat"));
|
153
|
-
if (!tpbRequest)
|
154
|
-
return;
|
155
|
-
return +JSON.parse(tpbRequest).split(" ")[1];
|
156
|
-
};
|
157
|
-
const getBarLengths = (lines, measureChanges) => {
|
158
|
-
const barLengths = [];
|
159
|
-
lines.forEach((line, index) => {
|
160
|
-
const [header, data] = line;
|
161
|
-
if (header.length !== 5)
|
162
|
-
return;
|
163
|
-
if (!header.endsWith("02"))
|
164
|
-
return;
|
165
|
-
const measure = +header.substring(0, 3) +
|
166
|
-
(measureChanges.find(([changeIndex]) => changeIndex <= index)?.[1] ?? 0);
|
167
|
-
if (Number.isNaN(measure))
|
168
|
-
return;
|
169
|
-
barLengths.push({ measure, length: +data });
|
170
|
-
});
|
171
|
-
return barLengths;
|
172
|
-
};
|
173
|
-
const getToTick = (barLengths, ticksPerBeat) => {
|
174
|
-
let ticks = 0;
|
175
|
-
const bars = barLengths
|
176
|
-
.sort((a, b) => a.measure - b.measure)
|
177
|
-
.map(({ measure, length }, i, values) => {
|
178
|
-
if (i) {
|
179
|
-
const prev = values[i - 1];
|
180
|
-
ticks += (measure - prev.measure) * prev.length * ticksPerBeat;
|
181
|
-
}
|
182
|
-
return { measure, ticksPerMeasure: length * ticksPerBeat, ticks };
|
183
|
-
})
|
184
|
-
.reverse();
|
185
|
-
return (measure, p, q) => {
|
186
|
-
const bar = bars.find((bar) => measure >= bar.measure);
|
187
|
-
if (!bar)
|
188
|
-
throw new Error("Unexpected missing bar");
|
189
|
-
return (bar.ticks +
|
190
|
-
(measure - bar.measure) * bar.ticksPerMeasure +
|
191
|
-
(p * bar.ticksPerMeasure) / q);
|
192
|
-
};
|
193
|
-
};
|
194
|
-
const toBpmChanges = (line, measureOffset, bpms, toTick) => toRaws(line, measureOffset, toTick).map(({ tick, value }) => ({
|
195
|
-
tick,
|
196
|
-
bpm: bpms.get(value) ?? 0,
|
197
|
-
}));
|
198
|
-
const toTimeScaleChanges = ([, data], toTick) => {
|
199
|
-
if (!data.startsWith('"') || !data.endsWith('"'))
|
200
|
-
throw new Error("Unexpected time scale changes");
|
201
|
-
return data
|
202
|
-
.slice(1, -1)
|
203
|
-
.split(",")
|
204
|
-
.map((segment) => segment.trim())
|
205
|
-
.filter((segment) => !!segment)
|
206
|
-
.map((segment) => {
|
207
|
-
const [l, rest] = segment.split("'");
|
208
|
-
const [m, r] = rest.split(":");
|
209
|
-
const measure = +l;
|
210
|
-
const tick = +m;
|
211
|
-
const timeScale = +r;
|
212
|
-
if (Number.isNaN(measure) ||
|
213
|
-
Number.isNaN(tick) ||
|
214
|
-
Number.isNaN(timeScale))
|
215
|
-
throw new Error("Unexpected time scale change");
|
216
|
-
return {
|
217
|
-
tick: toTick(measure, 0, 1) + tick,
|
218
|
-
timeScale,
|
219
|
-
};
|
220
|
-
})
|
221
|
-
.sort((a, b) => a.tick - b.tick);
|
222
|
-
};
|
223
|
-
const toNotes = (line, measureOffset, timeScaleGroup, toTick) => {
|
224
|
-
const [header] = line;
|
225
|
-
const lane = parseInt(header[4], 36);
|
226
|
-
return toRaws(line, measureOffset, toTick).map(({ tick, value }) => {
|
227
|
-
const width = parseInt(value[1], 36);
|
228
|
-
return {
|
229
|
-
tick,
|
230
|
-
lane,
|
231
|
-
width,
|
232
|
-
type: parseInt(value[0], 36),
|
233
|
-
timeScaleGroup,
|
234
|
-
};
|
235
|
-
});
|
236
|
-
};
|
237
|
-
const toSlides = (stream) => {
|
238
|
-
const slides = [];
|
239
|
-
let current;
|
240
|
-
stream
|
241
|
-
.sort((a, b) => a.tick - b.tick)
|
242
|
-
.forEach((note) => {
|
243
|
-
if (!current) {
|
244
|
-
current = [];
|
245
|
-
slides.push(current);
|
246
|
-
}
|
247
|
-
current.push(note);
|
248
|
-
if (note.type === 2) {
|
249
|
-
current = undefined;
|
250
|
-
}
|
251
|
-
});
|
252
|
-
return slides;
|
253
|
-
};
|
254
|
-
const toRaws = ([header, data], measureOffset, toTick) => {
|
255
|
-
const measure = +header.substring(0, 3) + measureOffset;
|
256
|
-
return (data.match(/.{2}/g) ?? [])
|
257
|
-
.map((value, i, values) => value !== "00" && {
|
258
|
-
tick: toTick(measure, i, values.length),
|
259
|
-
value,
|
260
|
-
})
|
261
|
-
.filter((object) => !!object);
|
262
|
-
};
|
package/dist/sus/convert.d.ts
DELETED
package/dist/sus/convert.js
DELETED
@@ -1,301 +0,0 @@
|
|
1
|
-
import { analyze } from "./analyze.js";
|
2
|
-
/** Convert a SUS to a USC */
|
3
|
-
export const susToUSC = (sus) => chsLikeToUSC(analyze(sus));
|
4
|
-
export const chsLikeToUSC = (score) => {
|
5
|
-
const flickMods = new Map();
|
6
|
-
const criticalMods = new Set();
|
7
|
-
const tickRemoveMods = new Set();
|
8
|
-
const judgeRemoveMods = new Set();
|
9
|
-
const easeMods = new Map();
|
10
|
-
const preventSingles = new Set();
|
11
|
-
const dedupeSingles = new Set();
|
12
|
-
const dedupeSlides = new Map();
|
13
|
-
const requests = {
|
14
|
-
sideLane: false,
|
15
|
-
laneOffset: 0,
|
16
|
-
};
|
17
|
-
const requestsRaw = score.meta.get("REQUEST");
|
18
|
-
if (requestsRaw) {
|
19
|
-
for (const request of requestsRaw) {
|
20
|
-
try {
|
21
|
-
const [key, value] = JSON.parse(request).split(" ", 2);
|
22
|
-
switch (key) {
|
23
|
-
case "side_lane":
|
24
|
-
requests.sideLane = value === "true";
|
25
|
-
break;
|
26
|
-
case "lane_offset":
|
27
|
-
requests.laneOffset = Number(value);
|
28
|
-
break;
|
29
|
-
}
|
30
|
-
}
|
31
|
-
catch (e) {
|
32
|
-
// Noop
|
33
|
-
}
|
34
|
-
}
|
35
|
-
}
|
36
|
-
for (const slides of [score.slides, score.guides]) {
|
37
|
-
for (const slide of slides) {
|
38
|
-
for (const note of slide) {
|
39
|
-
const key = getKey(note);
|
40
|
-
switch (note.type) {
|
41
|
-
case 1:
|
42
|
-
case 2:
|
43
|
-
case 3:
|
44
|
-
case 5:
|
45
|
-
preventSingles.add(key);
|
46
|
-
break;
|
47
|
-
}
|
48
|
-
}
|
49
|
-
}
|
50
|
-
}
|
51
|
-
for (const note of score.directionalNotes) {
|
52
|
-
const key = getKey(note);
|
53
|
-
switch (note.type) {
|
54
|
-
case 1:
|
55
|
-
flickMods.set(key, "up");
|
56
|
-
break;
|
57
|
-
case 3:
|
58
|
-
flickMods.set(key, "left");
|
59
|
-
break;
|
60
|
-
case 4:
|
61
|
-
flickMods.set(key, "right");
|
62
|
-
break;
|
63
|
-
case 2:
|
64
|
-
easeMods.set(key, "in");
|
65
|
-
break;
|
66
|
-
case 5:
|
67
|
-
case 6:
|
68
|
-
easeMods.set(key, "out");
|
69
|
-
break;
|
70
|
-
}
|
71
|
-
}
|
72
|
-
for (const note of score.tapNotes) {
|
73
|
-
const key = getKey(note);
|
74
|
-
switch (note.type) {
|
75
|
-
case 2:
|
76
|
-
criticalMods.add(key);
|
77
|
-
break;
|
78
|
-
case 4:
|
79
|
-
judgeRemoveMods.add(key);
|
80
|
-
break;
|
81
|
-
case 3:
|
82
|
-
case 5:
|
83
|
-
tickRemoveMods.add(key);
|
84
|
-
break;
|
85
|
-
case 6:
|
86
|
-
criticalMods.add(key);
|
87
|
-
tickRemoveMods.add(key);
|
88
|
-
break;
|
89
|
-
case 7:
|
90
|
-
judgeRemoveMods.add(key);
|
91
|
-
break;
|
92
|
-
case 8:
|
93
|
-
criticalMods.add(key);
|
94
|
-
judgeRemoveMods.add(key);
|
95
|
-
break;
|
96
|
-
}
|
97
|
-
}
|
98
|
-
const objects = [];
|
99
|
-
for (const timeScaleChanges of score.timeScaleChanges) {
|
100
|
-
objects.push({
|
101
|
-
type: "timeScaleGroup",
|
102
|
-
changes: timeScaleChanges.map((timeScaleChange) => ({
|
103
|
-
beat: timeScaleChange.tick / score.ticksPerBeat,
|
104
|
-
timeScale: timeScaleChange.timeScale,
|
105
|
-
})),
|
106
|
-
});
|
107
|
-
}
|
108
|
-
for (const bpmChange of score.bpmChanges) {
|
109
|
-
objects.push({
|
110
|
-
type: "bpm",
|
111
|
-
beat: bpmChange.tick / score.ticksPerBeat,
|
112
|
-
bpm: bpmChange.bpm,
|
113
|
-
});
|
114
|
-
}
|
115
|
-
for (const note of score.tapNotes) {
|
116
|
-
if (!requests.sideLane && (note.lane <= 1 || note.lane >= 14))
|
117
|
-
continue;
|
118
|
-
const key = getKey(note);
|
119
|
-
if (preventSingles.has(key))
|
120
|
-
continue;
|
121
|
-
if (dedupeSingles.has(key))
|
122
|
-
continue;
|
123
|
-
dedupeSingles.add(key);
|
124
|
-
let object;
|
125
|
-
switch (note.type) {
|
126
|
-
case 1:
|
127
|
-
case 2:
|
128
|
-
case 3:
|
129
|
-
case 5:
|
130
|
-
case 6: {
|
131
|
-
object = {
|
132
|
-
type: "single",
|
133
|
-
beat: note.tick / score.ticksPerBeat,
|
134
|
-
lane: note.lane - 8 + note.width / 2 + requests.laneOffset,
|
135
|
-
size: note.width / 2,
|
136
|
-
critical: [2, 6].includes(note.type) || criticalMods.has(key),
|
137
|
-
trace: [3, 5, 6].includes(note.type) || tickRemoveMods.has(key),
|
138
|
-
timeScaleGroup: note.timeScaleGroup,
|
139
|
-
};
|
140
|
-
const flickMod = flickMods.get(key);
|
141
|
-
if (flickMod)
|
142
|
-
object.direction = flickMod;
|
143
|
-
if (easeMods.has(key))
|
144
|
-
object.direction = "none";
|
145
|
-
break;
|
146
|
-
}
|
147
|
-
case 4:
|
148
|
-
object = {
|
149
|
-
type: "damage",
|
150
|
-
beat: note.tick / score.ticksPerBeat,
|
151
|
-
lane: note.lane - 8 + note.width / 2 + requests.laneOffset,
|
152
|
-
size: note.width / 2,
|
153
|
-
timeScaleGroup: note.timeScaleGroup,
|
154
|
-
};
|
155
|
-
break;
|
156
|
-
default:
|
157
|
-
continue;
|
158
|
-
}
|
159
|
-
objects.push(object);
|
160
|
-
}
|
161
|
-
for (const [isDummy, slides] of [
|
162
|
-
[false, score.slides],
|
163
|
-
[true, score.guides],
|
164
|
-
]) {
|
165
|
-
for (const slide of slides) {
|
166
|
-
const startNote = slide.find(({ type }) => type === 1 || type === 2);
|
167
|
-
if (!startNote)
|
168
|
-
continue;
|
169
|
-
const endNote = slide.find(({ type }) => type === 2);
|
170
|
-
if (!endNote)
|
171
|
-
continue;
|
172
|
-
const object = {
|
173
|
-
type: "slide",
|
174
|
-
critical: criticalMods.has(getKey(startNote)),
|
175
|
-
connections: [],
|
176
|
-
};
|
177
|
-
for (const note of slide) {
|
178
|
-
const key = getKey(note);
|
179
|
-
const beat = note.tick / score.ticksPerBeat;
|
180
|
-
const lane = note.lane - 8 + note.width / 2 + requests.laneOffset;
|
181
|
-
const size = note.width / 2;
|
182
|
-
const timeScaleGroup = note.timeScaleGroup;
|
183
|
-
const critical = ("critical" in object && object.critical) || criticalMods.has(key);
|
184
|
-
const ease = easeMods.get(key) ?? "linear";
|
185
|
-
switch (note.type) {
|
186
|
-
case 1: {
|
187
|
-
let judgeType = "normal";
|
188
|
-
if (tickRemoveMods.has(key))
|
189
|
-
judgeType = "trace";
|
190
|
-
if (judgeRemoveMods.has(key))
|
191
|
-
judgeType = "none";
|
192
|
-
const connection = {
|
193
|
-
type: "start",
|
194
|
-
beat,
|
195
|
-
lane,
|
196
|
-
size,
|
197
|
-
critical,
|
198
|
-
ease: easeMods.get(key) ?? "linear",
|
199
|
-
judgeType,
|
200
|
-
timeScaleGroup,
|
201
|
-
};
|
202
|
-
object.connections.push(connection);
|
203
|
-
break;
|
204
|
-
}
|
205
|
-
case 2: {
|
206
|
-
let judgeType = "normal";
|
207
|
-
if (tickRemoveMods.has(key))
|
208
|
-
judgeType = "trace";
|
209
|
-
if (judgeRemoveMods.has(key))
|
210
|
-
judgeType = "none";
|
211
|
-
const connection = {
|
212
|
-
type: "end",
|
213
|
-
beat,
|
214
|
-
lane,
|
215
|
-
size,
|
216
|
-
critical,
|
217
|
-
judgeType,
|
218
|
-
timeScaleGroup,
|
219
|
-
};
|
220
|
-
const flickMod = flickMods.get(key);
|
221
|
-
if (flickMod)
|
222
|
-
connection.direction = flickMod;
|
223
|
-
object.connections.push(connection);
|
224
|
-
break;
|
225
|
-
}
|
226
|
-
case 3: {
|
227
|
-
if (tickRemoveMods.has(key)) {
|
228
|
-
const connection = {
|
229
|
-
type: "attach",
|
230
|
-
beat,
|
231
|
-
critical,
|
232
|
-
timeScaleGroup,
|
233
|
-
};
|
234
|
-
object.connections.push(connection);
|
235
|
-
}
|
236
|
-
else {
|
237
|
-
const connection = {
|
238
|
-
type: "tick",
|
239
|
-
beat,
|
240
|
-
lane,
|
241
|
-
size,
|
242
|
-
critical,
|
243
|
-
ease,
|
244
|
-
timeScaleGroup,
|
245
|
-
};
|
246
|
-
object.connections.push(connection);
|
247
|
-
}
|
248
|
-
break;
|
249
|
-
}
|
250
|
-
case 5: {
|
251
|
-
if (tickRemoveMods.has(key))
|
252
|
-
break;
|
253
|
-
const connection = {
|
254
|
-
type: "tick",
|
255
|
-
beat,
|
256
|
-
lane,
|
257
|
-
size,
|
258
|
-
ease,
|
259
|
-
timeScaleGroup,
|
260
|
-
};
|
261
|
-
object.connections.push(connection);
|
262
|
-
break;
|
263
|
-
}
|
264
|
-
}
|
265
|
-
}
|
266
|
-
if (isDummy ||
|
267
|
-
(tickRemoveMods.has(getKey(startNote)) &&
|
268
|
-
judgeRemoveMods.has(getKey(startNote)))) {
|
269
|
-
objects.push({
|
270
|
-
type: "guide",
|
271
|
-
color: criticalMods.has(getKey(startNote)) ? "yellow" : "green",
|
272
|
-
fade: judgeRemoveMods.has(getKey(endNote)) ? "none" : "out",
|
273
|
-
midpoints: object.connections.flatMap((connection) => connection.type === "attach"
|
274
|
-
? []
|
275
|
-
: [
|
276
|
-
{
|
277
|
-
beat: connection.beat,
|
278
|
-
lane: connection.lane,
|
279
|
-
size: connection.size,
|
280
|
-
ease: connection.type === "end" ? "linear" : connection.ease,
|
281
|
-
timeScaleGroup: connection.timeScaleGroup,
|
282
|
-
},
|
283
|
-
]),
|
284
|
-
});
|
285
|
-
}
|
286
|
-
else {
|
287
|
-
objects.push(object);
|
288
|
-
}
|
289
|
-
const key = getKey(startNote);
|
290
|
-
const dupe = dedupeSlides.get(key);
|
291
|
-
if (dupe)
|
292
|
-
objects.splice(objects.indexOf(dupe), 1);
|
293
|
-
dedupeSlides.set(key, object);
|
294
|
-
}
|
295
|
-
}
|
296
|
-
return {
|
297
|
-
offset: score.offset,
|
298
|
-
objects,
|
299
|
-
};
|
300
|
-
};
|
301
|
-
const getKey = (note) => `${note.lane}-${note.tick}`;
|
package/dist/usc/convert.d.ts
DELETED