sonolus-next-rush-engine 1.0.12 → 1.0.13
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/extended/convert.js +96 -31
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/extended/convert.js
CHANGED
|
@@ -348,6 +348,8 @@ export const extendedToLevelData = (data, offset = 0) => {
|
|
|
348
348
|
note.set('size', getNum(e, 'size', 0.0));
|
|
349
349
|
note.set('direction', flickDirectionMapping[getNum(e, 'direction', 0)] ?? FlickDirection.UP_OMNI);
|
|
350
350
|
note.set('segmentKind', ConnectorKind.ACTIVE_NORMAL);
|
|
351
|
+
note.set('segmentAlpha', 1);
|
|
352
|
+
note.set('segmentLayer', 0);
|
|
351
353
|
note.set('isAttached', 0);
|
|
352
354
|
note.set('connectorEase', 0);
|
|
353
355
|
note.set('isSeparator', 0);
|
|
@@ -363,6 +365,10 @@ export const extendedToLevelData = (data, offset = 0) => {
|
|
|
363
365
|
return notesByName.get(ref);
|
|
364
366
|
return undefined;
|
|
365
367
|
}
|
|
368
|
+
function getTimeScaleAt(changes, beat) {
|
|
369
|
+
const change = [...changes].reverse().find((change) => change.beat < beat - 1e-6);
|
|
370
|
+
return change?.timeScale ?? 1;
|
|
371
|
+
}
|
|
366
372
|
function shouldUseStartAsHead(startRef, headRef) {
|
|
367
373
|
if (startRef === headRef)
|
|
368
374
|
return false;
|
|
@@ -378,6 +384,27 @@ export const extendedToLevelData = (data, offset = 0) => {
|
|
|
378
384
|
nearlyEqual(getNum(start, 'lane'), getNum(head, 'lane')) &&
|
|
379
385
|
nearlyEqual(getNum(start, 'size'), getNum(head, 'size')));
|
|
380
386
|
}
|
|
387
|
+
function findExistingConnectorSplitNote(beat, lane, size, tsg) {
|
|
388
|
+
const splitTsg = tsg ?? defaultTsg;
|
|
389
|
+
for (const { idx, e } of ext.notes) {
|
|
390
|
+
const note = notesByIndex.get(idx);
|
|
391
|
+
if (!note)
|
|
392
|
+
continue;
|
|
393
|
+
if (getField(e, 'attach') !== undefined)
|
|
394
|
+
continue;
|
|
395
|
+
if (!nearlyEqual(getNum(e, '#BEAT'), beat))
|
|
396
|
+
continue;
|
|
397
|
+
if (!nearlyEqual(getNum(e, 'lane'), lane))
|
|
398
|
+
continue;
|
|
399
|
+
if (!nearlyEqual(getNum(e, 'size'), size))
|
|
400
|
+
continue;
|
|
401
|
+
const noteTsg = getTSG(getField(e, 'timeScaleGroup')) ?? defaultTsg;
|
|
402
|
+
if (noteTsg !== splitTsg)
|
|
403
|
+
continue;
|
|
404
|
+
return note;
|
|
405
|
+
}
|
|
406
|
+
return undefined;
|
|
407
|
+
}
|
|
381
408
|
function createConnectorAnchor(beat, lane, size, tsg, kind) {
|
|
382
409
|
const anchor = new EntityBuilder('AnchorNote');
|
|
383
410
|
anchor.set('#BEAT', beat);
|
|
@@ -404,8 +431,12 @@ export const extendedToLevelData = (data, offset = 0) => {
|
|
|
404
431
|
const headChanges = getTSGChanges(headTsgRef);
|
|
405
432
|
const tailChanges = getTSGChanges(tailTsgRef);
|
|
406
433
|
const splitBeats = headChanges
|
|
407
|
-
.
|
|
408
|
-
|
|
434
|
+
.filter((change) => {
|
|
435
|
+
if (!(headBeat + 1e-6 < change.beat && change.beat < tailBeat - 1e-6))
|
|
436
|
+
return false;
|
|
437
|
+
return !nearlyEqual(change.timeScale, getTimeScaleAt(headChanges, change.beat));
|
|
438
|
+
})
|
|
439
|
+
.map(({ beat }) => beat);
|
|
409
440
|
if (splitBeats.length === 0)
|
|
410
441
|
return [];
|
|
411
442
|
const headScaledTime = timeToScaledTime(beatToTime(headBeat), headChanges);
|
|
@@ -433,7 +464,10 @@ export const extendedToLevelData = (data, offset = 0) => {
|
|
|
433
464
|
const scaledTime = timeToScaledTime(beatToTime(beat), headChanges);
|
|
434
465
|
const frac = unlerp(headScaledTime, tailScaledTime, scaledTime);
|
|
435
466
|
const easedFrac = applyEase(ease, frac);
|
|
436
|
-
|
|
467
|
+
const lane = lerp(headLane, tailLane, easedFrac);
|
|
468
|
+
const size = lerp(headSize, tailSize, easedFrac);
|
|
469
|
+
return (findExistingConnectorSplitNote(beat, lane, size, tsg) ??
|
|
470
|
+
createConnectorAnchor(beat, lane, size, tsg, kind));
|
|
437
471
|
});
|
|
438
472
|
}
|
|
439
473
|
function isReverseHiddenPopConnector(headOriginal, tailOriginal) {
|
|
@@ -445,6 +479,31 @@ export const extendedToLevelData = (data, offset = 0) => {
|
|
|
445
479
|
return false;
|
|
446
480
|
return getNum(tailOriginal, '#BEAT') < getNum(headOriginal, '#BEAT') - 1e-6;
|
|
447
481
|
}
|
|
482
|
+
function getUltimateTailRef(startRef, tailRef) {
|
|
483
|
+
let ultimateTailRef = tailRef;
|
|
484
|
+
let ultimateTailBeat = getNum(resolveOriginal(ext, tailRef) ?? { archetype: '', data: [] }, '#BEAT');
|
|
485
|
+
const visited = new Set();
|
|
486
|
+
function visit(headRef) {
|
|
487
|
+
const key = `${String(startRef)}|${String(headRef)}`;
|
|
488
|
+
if (headRef === undefined || visited.has(key))
|
|
489
|
+
return;
|
|
490
|
+
visited.add(key);
|
|
491
|
+
const nextConnectors = ext.connectors.filter((c) => getField(c.e, 'head') === headRef && getField(c.e, 'start') === startRef);
|
|
492
|
+
if (nextConnectors.length === 0) {
|
|
493
|
+
const beat = getNum(resolveOriginal(ext, headRef) ?? { archetype: '', data: [] }, '#BEAT');
|
|
494
|
+
if (beat >= ultimateTailBeat) {
|
|
495
|
+
ultimateTailBeat = beat;
|
|
496
|
+
ultimateTailRef = headRef;
|
|
497
|
+
}
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
for (const nextConnector of nextConnectors) {
|
|
501
|
+
visit(getField(nextConnector.e, 'tail'));
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
visit(tailRef);
|
|
505
|
+
return ultimateTailRef;
|
|
506
|
+
}
|
|
448
507
|
for (const { idx, e } of ext.connectors) {
|
|
449
508
|
const startRef = getField(e, 'start');
|
|
450
509
|
const headRef = getField(e, 'head');
|
|
@@ -460,21 +519,7 @@ export const extendedToLevelData = (data, offset = 0) => {
|
|
|
460
519
|
const endRef = getField(e, 'end');
|
|
461
520
|
let activeTail = getNote(endRef);
|
|
462
521
|
if (!activeTail) {
|
|
463
|
-
|
|
464
|
-
let ultimateTailRef = currentTailRef;
|
|
465
|
-
const visited = new Set();
|
|
466
|
-
while (ultimateTailRef !== undefined && !visited.has(ultimateTailRef)) {
|
|
467
|
-
visited.add(ultimateTailRef);
|
|
468
|
-
const nextConn = ext.connectors.find((c) => getField(c.e, 'head') === ultimateTailRef &&
|
|
469
|
-
getField(c.e, 'start') === startRef);
|
|
470
|
-
if (nextConn) {
|
|
471
|
-
ultimateTailRef = getField(nextConn.e, 'tail');
|
|
472
|
-
}
|
|
473
|
-
else {
|
|
474
|
-
break;
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
activeTail = getNote(ultimateTailRef);
|
|
522
|
+
activeTail = getNote(getUltimateTailRef(startRef, getField(e, 'tail')));
|
|
478
523
|
}
|
|
479
524
|
if (!activeTail) {
|
|
480
525
|
activeTail = tail;
|
|
@@ -490,6 +535,7 @@ export const extendedToLevelData = (data, offset = 0) => {
|
|
|
490
535
|
: [];
|
|
491
536
|
const segmentEase = splitAnchors.length > 0 ? EaseType.LINEAR : ease;
|
|
492
537
|
const segmentNotes = [head, ...splitAnchors, tail];
|
|
538
|
+
const segments = [];
|
|
493
539
|
if (reverseHiddenPopConnector && rawHeadOriginal && tailOriginal) {
|
|
494
540
|
const segmentHead = createConnectorAnchor(getNum(rawHeadOriginal, '#BEAT'), getNum(rawHeadOriginal, 'lane'), getNum(rawHeadOriginal, 'size'), getTSG(getField(rawHeadOriginal, 'timeScaleGroup')) ?? tsg, kind);
|
|
495
541
|
const connector = new EntityBuilder('Connector');
|
|
@@ -501,6 +547,7 @@ export const extendedToLevelData = (data, offset = 0) => {
|
|
|
501
547
|
connector.set('activeHead', activeHead);
|
|
502
548
|
connector.set('activeTail', activeTail);
|
|
503
549
|
finalEntities.push(connector);
|
|
550
|
+
segments.push({ head: segmentHead, tail });
|
|
504
551
|
}
|
|
505
552
|
else {
|
|
506
553
|
for (let i = 0; i < segmentNotes.length - 1; i++) {
|
|
@@ -514,13 +561,16 @@ export const extendedToLevelData = (data, offset = 0) => {
|
|
|
514
561
|
connector.set('activeHead', activeHead);
|
|
515
562
|
connector.set('activeTail', activeTail);
|
|
516
563
|
finalEntities.push(connector);
|
|
564
|
+
segments.push({ head: segmentHead, tail: segmentTail });
|
|
517
565
|
}
|
|
518
566
|
}
|
|
519
|
-
const connectorLink =
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
567
|
+
const connectorLink = {
|
|
568
|
+
head,
|
|
569
|
+
tail,
|
|
570
|
+
activeHead,
|
|
571
|
+
activeTail,
|
|
572
|
+
segments,
|
|
573
|
+
};
|
|
524
574
|
for (const segmentHead of segmentNotes.slice(0, -1)) {
|
|
525
575
|
segmentHead.set('connectorEase', segmentEase);
|
|
526
576
|
segmentHead.set('segmentKind', kind);
|
|
@@ -540,6 +590,18 @@ export const extendedToLevelData = (data, offset = 0) => {
|
|
|
540
590
|
return connectorsByName.get(ref);
|
|
541
591
|
return undefined;
|
|
542
592
|
}
|
|
593
|
+
function getAttachSegment(conn, beat) {
|
|
594
|
+
for (const segment of conn.segments) {
|
|
595
|
+
const headBeat = segment.head.getBeat();
|
|
596
|
+
const tailBeat = segment.tail.getBeat();
|
|
597
|
+
const minBeat = Math.min(headBeat, tailBeat);
|
|
598
|
+
const maxBeat = Math.max(headBeat, tailBeat);
|
|
599
|
+
if (minBeat - 1e-6 <= beat && beat <= maxBeat + 1e-6) {
|
|
600
|
+
return segment;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
return { head: conn.head, tail: conn.tail };
|
|
604
|
+
}
|
|
543
605
|
for (const [idx, note] of notesByIndex.entries()) {
|
|
544
606
|
const e = ext.get(idx);
|
|
545
607
|
const tsgRef = getField(e, 'timeScaleGroup');
|
|
@@ -548,17 +610,18 @@ export const extendedToLevelData = (data, offset = 0) => {
|
|
|
548
610
|
const attachRef = getField(e, 'attach');
|
|
549
611
|
if (attachRef !== undefined) {
|
|
550
612
|
const attachConn = getConn(attachRef);
|
|
551
|
-
if (attachConn
|
|
552
|
-
|
|
553
|
-
note.set('
|
|
613
|
+
if (attachConn) {
|
|
614
|
+
const attachSegment = getAttachSegment(attachConn, getNum(e, '#BEAT'));
|
|
615
|
+
note.set('attachHead', attachSegment.head);
|
|
616
|
+
note.set('attachTail', attachSegment.tail);
|
|
554
617
|
note.set('isAttached', 1);
|
|
555
618
|
}
|
|
556
619
|
}
|
|
557
620
|
const slideRef = getField(e, 'slide');
|
|
558
621
|
if (slideRef !== undefined) {
|
|
559
622
|
const slideConn = getConn(slideRef);
|
|
560
|
-
if (slideConn
|
|
561
|
-
note.set('activeHead', slideConn.
|
|
623
|
+
if (slideConn) {
|
|
624
|
+
note.set('activeHead', slideConn.activeHead);
|
|
562
625
|
}
|
|
563
626
|
}
|
|
564
627
|
}
|
|
@@ -575,6 +638,7 @@ export const extendedToLevelData = (data, offset = 0) => {
|
|
|
575
638
|
const anchorsByBeat = new Map();
|
|
576
639
|
const anchorPositions = new Map();
|
|
577
640
|
function getAnchor(beat, lane, size, tsg, pos, segmentKind = -1, segmentAlpha = -1, connectorEase = -1) {
|
|
641
|
+
const anchorTsg = tsg ?? defaultTsg;
|
|
578
642
|
const anchors = anchorsByBeat.get(beat) || [];
|
|
579
643
|
for (const anchor of anchors) {
|
|
580
644
|
const positions = anchorPositions.get(anchor);
|
|
@@ -582,7 +646,7 @@ export const extendedToLevelData = (data, offset = 0) => {
|
|
|
582
646
|
continue;
|
|
583
647
|
if (anchor.values.lane === lane &&
|
|
584
648
|
anchor.values.size === size &&
|
|
585
|
-
anchor.refs['#TIMESCALE_GROUP'] ===
|
|
649
|
+
anchor.refs['#TIMESCALE_GROUP'] === anchorTsg &&
|
|
586
650
|
(segmentKind === -1 ||
|
|
587
651
|
anchor.values.segmentKind === segmentKind ||
|
|
588
652
|
anchor.values.segmentKind === -1) &&
|
|
@@ -606,10 +670,11 @@ export const extendedToLevelData = (data, offset = 0) => {
|
|
|
606
670
|
newAnchor.set('#BEAT', beat);
|
|
607
671
|
newAnchor.set('lane', lane);
|
|
608
672
|
newAnchor.set('size', size);
|
|
609
|
-
|
|
610
|
-
|
|
673
|
+
newAnchor.set('direction', FlickDirection.UP_OMNI);
|
|
674
|
+
newAnchor.set('#TIMESCALE_GROUP', anchorTsg);
|
|
611
675
|
newAnchor.set('segmentKind', segmentKind);
|
|
612
676
|
newAnchor.set('segmentAlpha', segmentAlpha);
|
|
677
|
+
newAnchor.set('segmentLayer', 0);
|
|
613
678
|
newAnchor.set('connectorEase', connectorEase);
|
|
614
679
|
newAnchor.set('isAttached', 0);
|
|
615
680
|
newAnchor.set('isSeparator', 0);
|
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { USC } from './usc/index.js';
|
|
|
7
7
|
export * from './usc/index.js';
|
|
8
8
|
export { type ExtendedEntityData, type ExtendedEntityDataField, extendedToLevelData, mmwsToUSC, susToUSC, ucmmwsToLevelData, uscToLevelData, };
|
|
9
9
|
export declare const convertToLevelData: (input: string | Uint8Array | USC | LevelData, offset?: number) => LevelData;
|
|
10
|
-
export declare const version = "1.0.
|
|
10
|
+
export declare const version = "1.0.13";
|
|
11
11
|
export declare const databaseEngineItem: {
|
|
12
12
|
readonly name: "next-rush";
|
|
13
13
|
readonly version: 13;
|
package/dist/index.js
CHANGED
|
@@ -65,7 +65,7 @@ export const convertToLevelData = (input, offset = 0) => {
|
|
|
65
65
|
}
|
|
66
66
|
return uscToLevelData(usc, offset, true, true);
|
|
67
67
|
};
|
|
68
|
-
export const version = '1.0.
|
|
68
|
+
export const version = '1.0.13';
|
|
69
69
|
export const databaseEngineItem = {
|
|
70
70
|
name: 'next-rush',
|
|
71
71
|
version: 13,
|