sonolus-next-rush-engine 1.0.17 → 1.0.19

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.
@@ -464,7 +464,25 @@ export const extendedToLevelData = (data, offset = 0) => {
464
464
  return false;
465
465
  return getNum(tailOriginal, '#BEAT') < getNum(headOriginal, '#BEAT') - 1e-6;
466
466
  }
467
- function getUltimateTailRef(startRef, tailRef) {
467
+ function isSlideTickRef(ref) {
468
+ return [
469
+ 'IgnoredSlideTickNote',
470
+ 'NormalSlideTickNote',
471
+ 'CriticalSlideTickNote',
472
+ 'HiddenSlideTickNote',
473
+ 'NormalAttachedSlideTickNote',
474
+ 'CriticalAttachedSlideTickNote',
475
+ ].includes(resolveOriginal(ext, ref)?.archetype ?? '');
476
+ }
477
+ function isScoredSlideTickRef(ref) {
478
+ return [
479
+ 'NormalSlideTickNote',
480
+ 'CriticalSlideTickNote',
481
+ 'NormalAttachedSlideTickNote',
482
+ 'CriticalAttachedSlideTickNote',
483
+ ].includes(resolveOriginal(ext, ref)?.archetype ?? '');
484
+ }
485
+ function getUltimateTailRef(archetype, startRef, tailRef) {
468
486
  let ultimateTailRef = tailRef;
469
487
  let ultimateTailBeat = getNum(resolveOriginal(ext, tailRef) ?? { archetype: '', data: [] }, '#BEAT');
470
488
  const visited = new Set();
@@ -473,7 +491,12 @@ export const extendedToLevelData = (data, offset = 0) => {
473
491
  if (headRef === undefined || visited.has(key))
474
492
  return;
475
493
  visited.add(key);
476
- const nextConnectors = ext.connectors.filter((c) => getField(c.e, 'head') === headRef && getField(c.e, 'start') === startRef);
494
+ const nextConnectors = ext.connectors.filter((c) => c.e.archetype === archetype &&
495
+ getField(c.e, 'head') === headRef &&
496
+ getField(c.e, 'start') === startRef);
497
+ if (nextConnectors.length === 0) {
498
+ nextConnectors.push(...ext.connectors.filter((c) => c.e.archetype === archetype && getField(c.e, 'head') === headRef));
499
+ }
477
500
  if (nextConnectors.length === 0) {
478
501
  const beat = getNum(resolveOriginal(ext, headRef) ?? { archetype: '', data: [] }, '#BEAT');
479
502
  if (beat >= ultimateTailBeat) {
@@ -487,8 +510,49 @@ export const extendedToLevelData = (data, offset = 0) => {
487
510
  }
488
511
  }
489
512
  visit(tailRef);
513
+ if (isScoredSlideTickRef(ultimateTailRef)) {
514
+ for (const connector of ext.connectors) {
515
+ if (connector.e.archetype !== archetype)
516
+ continue;
517
+ if (getField(connector.e, 'start') !== startRef)
518
+ continue;
519
+ const candidateTailRef = getField(connector.e, 'tail');
520
+ const candidateTailBeat = getNum(resolveOriginal(ext, candidateTailRef) ?? { archetype: '', data: [] }, '#BEAT');
521
+ if (candidateTailBeat > ultimateTailBeat) {
522
+ ultimateTailBeat = candidateTailBeat;
523
+ ultimateTailRef = candidateTailRef;
524
+ }
525
+ }
526
+ }
490
527
  return ultimateTailRef;
491
528
  }
529
+ function getUltimateStartRef(archetype, startRef, headRef) {
530
+ if (!isSlideTickRef(headRef))
531
+ return startRef;
532
+ let ultimateStartRef = startRef;
533
+ let ultimateStartBeat = getNum(resolveOriginal(ext, startRef) ?? { archetype: '', data: [] }, '#BEAT');
534
+ const visited = new Set();
535
+ function visit(currentHeadRef) {
536
+ const key = `${archetype}|${String(currentHeadRef)}`;
537
+ if (currentHeadRef === undefined || visited.has(key))
538
+ return;
539
+ visited.add(key);
540
+ if (!isSlideTickRef(currentHeadRef))
541
+ return;
542
+ const previousConnectors = ext.connectors.filter((c) => c.e.archetype === archetype && getField(c.e, 'tail') === currentHeadRef);
543
+ for (const previousConnector of previousConnectors) {
544
+ const previousStartRef = getField(previousConnector.e, 'start');
545
+ const previousStartBeat = getNum(resolveOriginal(ext, previousStartRef) ?? { archetype: '', data: [] }, '#BEAT');
546
+ if (previousStartBeat <= ultimateStartBeat) {
547
+ ultimateStartBeat = previousStartBeat;
548
+ ultimateStartRef = previousStartRef;
549
+ }
550
+ visit(getField(previousConnector.e, 'head'));
551
+ }
552
+ }
553
+ visit(headRef);
554
+ return ultimateStartRef;
555
+ }
492
556
  function setInferredActiveHead(note, activeHead) {
493
557
  if (note.refs.activeHead)
494
558
  return;
@@ -497,10 +561,13 @@ export const extendedToLevelData = (data, offset = 0) => {
497
561
  function isIgnoredSlideTickRef(ref) {
498
562
  return resolveOriginal(ext, ref)?.archetype === 'IgnoredSlideTickNote';
499
563
  }
500
- function getNextConnectorWithHead(startRef, headRef) {
501
- return ext.connectors.find(({ e }) => getField(e, 'start') === startRef && getField(e, 'head') === headRef);
564
+ function getNextConnectorWithHead(archetype, startRef, headRef) {
565
+ return (ext.connectors.find(({ e }) => e.archetype === archetype &&
566
+ getField(e, 'start') === startRef &&
567
+ getField(e, 'head') === headRef) ??
568
+ ext.connectors.find(({ e }) => e.archetype === archetype && getField(e, 'head') === headRef));
502
569
  }
503
- function resolveConnectorTailRef(startRef, tailRef) {
570
+ function resolveConnectorTailRef(archetype, startRef, tailRef) {
504
571
  const skippedNoteRefs = [];
505
572
  const skippedConnectors = [];
506
573
  const visited = new Set();
@@ -513,7 +580,7 @@ export const extendedToLevelData = (data, offset = 0) => {
513
580
  break;
514
581
  visited.add(key);
515
582
  skippedNoteRefs.push(resolvedTailRef);
516
- const nextConnector = getNextConnectorWithHead(startRef, resolvedTailRef);
583
+ const nextConnector = getNextConnectorWithHead(archetype, startRef, resolvedTailRef);
517
584
  if (!nextConnector)
518
585
  break;
519
586
  skippedConnectors.push(nextConnector);
@@ -526,21 +593,22 @@ export const extendedToLevelData = (data, offset = 0) => {
526
593
  const headRef = getField(e, 'head');
527
594
  if (isIgnoredSlideTickRef(headRef))
528
595
  continue;
529
- const { tailRef, skippedNoteRefs, skippedConnectors } = resolveConnectorTailRef(startRef, getField(e, 'tail'));
596
+ const { tailRef, skippedNoteRefs, skippedConnectors } = resolveConnectorTailRef(e.archetype, startRef, getField(e, 'tail'));
530
597
  if (isIgnoredSlideTickRef(tailRef))
531
598
  continue;
532
599
  const tail = getNote(tailRef);
533
600
  const rawHeadOriginal = resolveOriginal(ext, headRef);
534
601
  const tailOriginal = resolveOriginal(ext, tailRef);
535
602
  const rawHead = getNote(headRef);
536
- const activeHead = getNote(startRef);
603
+ const activeStartRef = getUltimateStartRef(e.archetype, startRef, headRef);
604
+ const activeHead = getNote(activeStartRef);
537
605
  const usesStartAsHead = shouldUseStartAsHead(startRef, headRef);
538
606
  const head = usesStartAsHead ? activeHead : rawHead;
539
607
  const headOriginal = resolveOriginal(ext, usesStartAsHead ? startRef : headRef);
540
608
  const endRef = getField(e, 'end');
541
609
  let activeTail = getNote(endRef);
542
610
  if (!activeTail) {
543
- activeTail = getNote(getUltimateTailRef(startRef, tailRef));
611
+ activeTail = getNote(getUltimateTailRef(e.archetype, activeStartRef, tailRef));
544
612
  }
545
613
  if (!activeTail) {
546
614
  activeTail = tail;
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.17";
10
+ export declare const version = "1.0.19";
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.17';
68
+ export const version = '1.0.19';
69
69
  export const databaseEngineItem = {
70
70
  name: 'next-rush',
71
71
  version: 13,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sonolus-next-rush-engine",
3
- "version": "1.0.17",
3
+ "version": "1.0.19",
4
4
  "description": "Perspective-lane rhythm game for Sonolus",
5
5
  "author": "Hyeon2",
6
6
  "repository": {