sonolus-d4dj-engine 1.1.1

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/README.md ADDED
@@ -0,0 +1,88 @@
1
+ # Sonolus D4DJ Engine
2
+
3
+ A recreation of D4DJ Groovy Mix engine in Sonolus.
4
+
5
+ Unfinished.
6
+
7
+ Todo list:
8
+
9
+ - [x] Finish writing play mode
10
+ - [x] Make it customizable
11
+ - [x] Finish writing tutorial mode
12
+ - [x] Finish writing preview mode
13
+ - [x] Finish writing watch mode
14
+ - [ ] Designed particle effect for D4DJ
15
+
16
+ ## Links
17
+
18
+ - [Sonolus Website](https://sonolus.com)
19
+ - [Sonolus Wiki](https://github.com/NonSpicyBurrito/sonolus-wiki)
20
+
21
+ ## Installation
22
+
23
+ ```
24
+ npm install sonolus-bandori-engine
25
+ ```
26
+
27
+ ## Custom Resources
28
+
29
+ ### Skin Sprites
30
+
31
+ | Name |
32
+ | --------------------------------------------- |
33
+ | `DJ Stage` |
34
+ | `DJ Scratch Note` |
35
+ | `DJ Scratch Arrow` |
36
+ | `DJ Slider` |
37
+ | `DJ Slider Bar` |
38
+ | `DJ Line` |
39
+
40
+ ### Effect Clips
41
+
42
+ | Name |
43
+ | --------------------------------------------- |
44
+ | `DJ Scratch Empty` |
45
+ | `DJ Scratch Perfect` |
46
+ | `DJ Tap 1 Good` |
47
+ | `DJ Tap 1 Great` |
48
+ | `DJ Tap 1 Perfect` |
49
+ | `DJ Tap 2 Good` |
50
+ | `DJ Tap 2 Great` |
51
+ | `DJ Tap 2 Perfect` |
52
+ | `DJ Long Good` |
53
+ | `DJ Long Great` |
54
+ | `DJ Long Perfect` |
55
+ | `DJ Slider Good` |
56
+ | `DJ Slider Great` |
57
+ | `DJ Slider Perfect` |
58
+ | `DJ Slider Flick Perfect` |
59
+
60
+ ## Documentation
61
+
62
+ ### `version`
63
+
64
+ Package version.
65
+
66
+ ### `databaseEngineItem`
67
+
68
+ Partial database engine item compatible with [sonolus-express](https://github.com/NonSpicyBurrito/sonolus-express).
69
+
70
+ ### `b34djToLevelData(chart, offset?)`
71
+
72
+ Converts D4DJ (bangbangboom-editor) chart to Level Data.
73
+
74
+ - `chart`: D4DJ chart.
75
+ - `offset`: offset (default: `0`).
76
+
77
+ ### Assets
78
+
79
+ The following assets are exposed as package entry points:
80
+
81
+ - `EngineConfiguration`
82
+ - `EnginePlayData`
83
+ - `EngineWatchData`
84
+ - `EnginePreviewData`
85
+ - `EngineTutorialData`
86
+ - `EngineThumbnail`
87
+
88
+ In Node.js, you can obtain path to assets using `require.resolve('sonolus-d4dj-engine/EngineConfiguration')` or `import.meta.resolve('sonolus-d4dj-engine/EngineConfiguration')`.
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,361 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.b34djToLevelData = void 0;
4
+ function b34djToLevelData(chartData, offset = 0) {
5
+ let chart = Object.values(chartData);
6
+ chart[2] = chart[2].map((obj) => Object.values(obj));
7
+ chart[3] = chart[3].map((obj) => Object.values(obj));
8
+ const timescale = chart[2];
9
+ chart[2] = [];
10
+ timescale.forEach((ts) => {
11
+ const i = chart[2].findIndex((tsc) => (tsc[0] === ts[0]) && (tsc[1] === ts[1]));
12
+ if (i === -1)
13
+ chart[2].push(ts);
14
+ else
15
+ chart[2][i][2] = 3;
16
+ });
17
+ chart = JSON.parse(JSON.stringify(chart)
18
+ .replaceAll('"Tap1"', "0")
19
+ .replaceAll('"Tap2"', "1")
20
+ .replaceAll('"ScratchLeft"', "2")
21
+ .replaceAll('"ScratchRight"', "3")
22
+ .replaceAll('"StopStart"', "4")
23
+ .replaceAll('"StopEnd"', "5")
24
+ .replaceAll('"LongStart"', "6")
25
+ .replaceAll('"LongMiddle"', "7")
26
+ .replaceAll('"LongEnd"', "8")
27
+ .replaceAll('"Slide"', "9"));
28
+ const temp = chart[1];
29
+ chart[1] = chart[2];
30
+ chart[2] = temp;
31
+ chart[3] = chart[3].map((note) => {
32
+ const temp = note[1];
33
+ note[1] = note[2];
34
+ note[2] = temp;
35
+ return note;
36
+ });
37
+ return parse(chart, offset);
38
+ }
39
+ exports.b34djToLevelData = b34djToLevelData;
40
+ ;
41
+ function parse(chart, offset = 0) {
42
+ let sus = {
43
+ bgmOffset: offset,
44
+ entities: [
45
+ {
46
+ archetype: "Initialization",
47
+ data: [],
48
+ },
49
+ {
50
+ archetype: "Stage",
51
+ data: [],
52
+ },
53
+ {
54
+ archetype: "#BPM_CHANGE",
55
+ data: [
56
+ {
57
+ name: "#TIME",
58
+ value: 0,
59
+ },
60
+ {
61
+ name: "#BPM",
62
+ value: 60,
63
+ },
64
+ ],
65
+ },
66
+ {
67
+ archetype: "TimeScaleGroup",
68
+ data: [
69
+ {
70
+ name: "first",
71
+ ref: "tsc:0:0",
72
+ },
73
+ {
74
+ name: "length",
75
+ value: chart[1].length + 1,
76
+ },
77
+ {
78
+ name: "next",
79
+ ref: "tsg:1",
80
+ },
81
+ ],
82
+ name: "tsg:0",
83
+ },
84
+ {
85
+ archetype: "TimeScaleGroup",
86
+ data: [
87
+ {
88
+ name: "first",
89
+ ref: "tsc:1:0",
90
+ },
91
+ {
92
+ name: "length",
93
+ value: 1,
94
+ },
95
+ {
96
+ name: "next",
97
+ ref: "tsg:2",
98
+ },
99
+ ],
100
+ name: "tsg:1",
101
+ },
102
+ {
103
+ archetype: "TimeScaleGroup",
104
+ data: [
105
+ {
106
+ name: "first",
107
+ ref: "tsc:2:0",
108
+ },
109
+ {
110
+ name: "length",
111
+ value: 1,
112
+ },
113
+ {
114
+ name: "next",
115
+ ref: "tsg:3",
116
+ },
117
+ ],
118
+ name: "tsg:2",
119
+ },
120
+ {
121
+ archetype: "TimeScaleChange",
122
+ data: [
123
+ {
124
+ name: "#BEAT",
125
+ value: 0,
126
+ },
127
+ {
128
+ name: "timeScale",
129
+ value: 1,
130
+ },
131
+ {
132
+ name: "next",
133
+ ref: `tsc:0:1`,
134
+ },
135
+ ],
136
+ name: `tsc:0:0`,
137
+ },
138
+ {
139
+ archetype: "TimeScaleChange",
140
+ data: [
141
+ {
142
+ name: "#BEAT",
143
+ value: 0,
144
+ },
145
+ {
146
+ name: "timeScale",
147
+ value: 1,
148
+ },
149
+ {
150
+ name: "next",
151
+ value: -1,
152
+ },
153
+ ],
154
+ name: `tsc:1:0`,
155
+ },
156
+ {
157
+ archetype: "TimeScaleChange",
158
+ data: [
159
+ {
160
+ name: "#BEAT",
161
+ value: 0,
162
+ },
163
+ {
164
+ name: "timeScale",
165
+ value: 1,
166
+ },
167
+ {
168
+ name: "next",
169
+ value: -1,
170
+ },
171
+ ],
172
+ name: `tsc:2:0`,
173
+ },
174
+ ],
175
+ };
176
+ let ts = chart[1].map((arr, i) => ({
177
+ archetype: "TimeScaleChange",
178
+ data: [
179
+ {
180
+ name: "#BEAT",
181
+ value: arr[0],
182
+ },
183
+ {
184
+ name: "timeScale",
185
+ value: arr[1],
186
+ },
187
+ {
188
+ name: "disc",
189
+ value: arr[2],
190
+ },
191
+ {
192
+ name: "next",
193
+ ref: `tsc:0:${i + 2}`,
194
+ },
195
+ ],
196
+ name: `tsc:0:${i + 1}`,
197
+ }));
198
+ let bl = chart[2].map((time) => ({
199
+ archetype: "BarLine",
200
+ data: [
201
+ {
202
+ name: "#BEAT",
203
+ value: time,
204
+ },
205
+ {
206
+ name: "timeScaleGroup",
207
+ ref: "tsg:0",
208
+ },
209
+ ],
210
+ }));
211
+ let notes = note(chart);
212
+ sus.entities.push(...ts, ...notes, ...bl);
213
+ return sus;
214
+ }
215
+ function note(chart) {
216
+ let hold = [];
217
+ let slider = [];
218
+ let notes = {};
219
+ let sol = chart[3].map((arr, i) => {
220
+ const sus = {
221
+ archetype: arr[1] === 0
222
+ ? "DarkTapNote"
223
+ : arr[1] === 1
224
+ ? "LightTapNote"
225
+ : arr[1] === 2 || arr[1] === 3
226
+ ? "ScratchNote"
227
+ : arr[1] === 4
228
+ ? "StopStartNote"
229
+ : arr[1] === 5
230
+ ? "StopEndNote"
231
+ : arr[1] === 6
232
+ ? "HoldStartNote"
233
+ : arr[1] === 8
234
+ ? "HoldEndNote"
235
+ : arr[1] === 7
236
+ ? "HoldMiddleNote"
237
+ : arr[4] !== 0
238
+ ? "SliderFlickNote"
239
+ : "SliderTickNote",
240
+ data: [
241
+ {
242
+ name: "#BEAT",
243
+ value: arr[2],
244
+ },
245
+ {
246
+ name: "lane",
247
+ value: arr[0] - 3,
248
+ },
249
+ {
250
+ name: "timeScaleGroup",
251
+ ref: arr[0] === 0
252
+ ? "tsg:1"
253
+ : arr[0] === 6
254
+ ? "tsg:2"
255
+ : "tsg:0",
256
+ },
257
+ ],
258
+ name: `note${i}`,
259
+ };
260
+ notes[arr[2]]
261
+ ? notes[arr[2]].push({ name: `note${i}`, lane: arr[0] })
262
+ : (notes[arr[2]] = [{ name: `note${i}`, lane: arr[0] }]);
263
+ if (arr[3] && (arr[1] === 4 || arr[1] === 6)) {
264
+ let note = {};
265
+ note.head = sus.name;
266
+ note.tail = `note${arr[3]}`;
267
+ hold.push(note);
268
+ sus.data.push({
269
+ name: "tail",
270
+ ref: `note${arr[3]}`,
271
+ });
272
+ }
273
+ if (arr[1] === 9) {
274
+ if (arr[3] > 0) {
275
+ slider.push({ prev: sus.name, next: `note${arr[3]}` });
276
+ sus.data.push({
277
+ name: "next",
278
+ ref: `note${arr[3]}`,
279
+ });
280
+ }
281
+ const sld = slider.find((note) => note.next === sus.name);
282
+ if (sld)
283
+ sus.data.push({
284
+ name: "prev",
285
+ ref: sld.prev,
286
+ });
287
+ }
288
+ if (arr[1] === 5 || arr[1] === 8) {
289
+ sus.data.push({
290
+ name: "head",
291
+ ref: hold.find((note) => note.tail === sus.name).head,
292
+ });
293
+ }
294
+ if (arr[4])
295
+ sus.data.push({
296
+ name: "direction",
297
+ value: arr[4],
298
+ });
299
+ return sus;
300
+ });
301
+ hold.forEach(({ head, tail }, i) => sol.splice(parseInt(head.replace("note", "")) + 1 + i, 0, {
302
+ archetype: "HoldConnector",
303
+ data: [
304
+ {
305
+ name: "head",
306
+ ref: head,
307
+ },
308
+ {
309
+ name: "tail",
310
+ ref: tail,
311
+ },
312
+ ],
313
+ }));
314
+ for (const beat in notes) {
315
+ const sim = notes[beat].sort((a, b) => a.lane - b.lane);
316
+ if (sim.length === 2) {
317
+ sol.push({
318
+ archetype: "SimLine",
319
+ data: [
320
+ {
321
+ name: "a",
322
+ ref: sim[0].name,
323
+ },
324
+ {
325
+ name: "b",
326
+ ref: sim[1].name,
327
+ },
328
+ ],
329
+ });
330
+ }
331
+ else if (sim.length === 3) {
332
+ sol.push({
333
+ archetype: "SimLine",
334
+ data: [
335
+ {
336
+ name: "a",
337
+ ref: sim[0].name,
338
+ },
339
+ {
340
+ name: "b",
341
+ ref: sim[1].name,
342
+ },
343
+ ],
344
+ });
345
+ sol.push({
346
+ archetype: "SimLine",
347
+ data: [
348
+ {
349
+ name: "a",
350
+ ref: sim[1].name,
351
+ },
352
+ {
353
+ name: "b",
354
+ ref: sim[2].name,
355
+ },
356
+ ],
357
+ });
358
+ }
359
+ }
360
+ return sol;
361
+ }
@@ -0,0 +1,3 @@
1
+ import { LevelData } from '@sonolus/core';
2
+ import { B34DJChart } from './index.cjs';
3
+ export declare function b34djToLevelData(chartData: B34DJChart, offset?: number): LevelData;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,19 @@
1
+ export type B34DJChart = {
2
+ MusicName: "music_0000001";
3
+ BarLineList: number[];
4
+ SoflanDataList: B34DJSoflanData[];
5
+ };
6
+ export type B34DJSoflanData = {
7
+ Time: number;
8
+ TimeScale: number;
9
+ LeftRight: number;
10
+ };
11
+ export type B34DJNoteData = {
12
+ LaneId: number;
13
+ Time: number;
14
+ Type: "Tap1" | "Tap2" | "ScratchLeft" | "ScratchRight" | "StopStart" | "StopEnd" | "LongStart" | "LongMiddle" | "LongEnd" | "Slide";
15
+ NextId: number;
16
+ Direction: number;
17
+ EffectType: number;
18
+ EffectParameter: number;
19
+ };
package/dist/index.cjs ADDED
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.databaseEngineItem = exports.version = exports.b34djToLevelData = void 0;
18
+ var convert_cjs_1 = require("./b34dj/convert.cjs");
19
+ Object.defineProperty(exports, "b34djToLevelData", { enumerable: true, get: function () { return convert_cjs_1.b34djToLevelData; } });
20
+ __exportStar(require("./b34dj/index.cjs"), exports);
21
+ exports.version = '1.1.1';
22
+ exports.databaseEngineItem = {
23
+ name: 'd4dj',
24
+ version: 12,
25
+ title: {
26
+ en: 'D4DJ'
27
+ },
28
+ subtitle: {
29
+ en: 'D4DJ Groovy Mix',
30
+ ja: 'D4DJグルミク',
31
+ },
32
+ author: {
33
+ en: 'Gorengan Hunter',
34
+ },
35
+ description: {
36
+ en: [
37
+ 'A recreation of D4DJ Groovy Mix engine in Sonolus.',
38
+ '',
39
+ 'Version:',
40
+ exports.version,
41
+ '',
42
+ 'GitHub Repository:',
43
+ 'https://github.com/gorenganhunter/sonolus-d4dj-engine',
44
+ ].join('\n'),
45
+ },
46
+ };
@@ -0,0 +1,20 @@
1
+ export { b34djToLevelData } from './b34dj/convert.cjs';
2
+ export * from './b34dj/index.cjs';
3
+ export declare const version = "1.1.1";
4
+ export declare const databaseEngineItem: {
5
+ readonly name: "d4dj";
6
+ readonly version: 12;
7
+ readonly title: {
8
+ readonly en: "D4DJ";
9
+ };
10
+ readonly subtitle: {
11
+ readonly en: "D4DJ Groovy Mix";
12
+ readonly ja: "D4DJグルミク";
13
+ };
14
+ readonly author: {
15
+ readonly en: "Gorengan Hunter";
16
+ };
17
+ readonly description: {
18
+ readonly en: string;
19
+ };
20
+ };
Binary file
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "sonolus-d4dj-engine",
3
+ "version": "1.1.1",
4
+ "description": "A recreation of D4DJ Groovy Mix engine in Sonolus.",
5
+ "type": "module",
6
+ "author": "Gorengan Hunter",
7
+ "repository": "github:gorenganhunter/sonolus-d4dj-engine",
8
+ "license": "MIT",
9
+ "keywords": [
10
+ "Sonolus",
11
+ "D4DJ"
12
+ ],
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "exports": {
17
+ ".": "./dist/index.cjs",
18
+ "./EngineConfiguration": "./dist/EngineConfiguration",
19
+ "./EnginePlayData": "./dist/EnginePlayData",
20
+ "./EngineWatchData": "./dist/EngineWatchData",
21
+ "./EnginePreviewData": "./dist/EnginePreviewData",
22
+ "./EngineTutorialData": "./dist/EngineTutorialData",
23
+ "./EngineThumbnail": "./dist/thumbnail.png"
24
+ },
25
+ "scripts": {
26
+ "dev:play": "sonolus-cli --dev ./play",
27
+ "dev:watch": "sonolus-cli --dev ./watch",
28
+ "dev:preview": "sonolus-cli --dev ./preview",
29
+ "dev:tutorial": "sonolus-cli --dev ./tutorial",
30
+ "check-type": "tsc -p ./lib --noEmit && tsc -p ./shared --noEmit && tsc -p ./play --noEmit && tsc -p ./watch --noEmit && tsc -p ./preview --noEmit && tsc -p ./tutorial --noEmit",
31
+ "check-lint": "eslint .",
32
+ "check-format": "prettier . --check",
33
+ "build": "tsc -p ./lib && sonolus-cli --build ./play && sonolus-cli --build ./watch && sonolus-cli --build ./preview && sonolus-cli --build ./tutorial && node ./lib/build.mjs"
34
+ },
35
+ "dependencies": {
36
+ "@sonolus/core": "~7.9.1"
37
+ },
38
+ "devDependencies": {
39
+ "@eslint/js": "^8.57.0",
40
+ "@sonolus/sonolus.js": "^9.5.0",
41
+ "eslint": "^8.57.0",
42
+ "eslint-config-prettier": "^9.1.0",
43
+ "prettier": "^3.3.1",
44
+ "prettier-plugin-organize-imports": "^3.2.4",
45
+ "typescript": "~5.4.5",
46
+ "typescript-eslint": "^7.12.0"
47
+ }
48
+ }