sonolus-next-rush-engine 1.0.17 → 1.0.18

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,17 @@ 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 getUltimateTailRef(archetype, startRef, tailRef) {
468
478
  let ultimateTailRef = tailRef;
469
479
  let ultimateTailBeat = getNum(resolveOriginal(ext, tailRef) ?? { archetype: '', data: [] }, '#BEAT');
470
480
  const visited = new Set();
@@ -473,7 +483,12 @@ export const extendedToLevelData = (data, offset = 0) => {
473
483
  if (headRef === undefined || visited.has(key))
474
484
  return;
475
485
  visited.add(key);
476
- const nextConnectors = ext.connectors.filter((c) => getField(c.e, 'head') === headRef && getField(c.e, 'start') === startRef);
486
+ const nextConnectors = ext.connectors.filter((c) => c.e.archetype === archetype &&
487
+ getField(c.e, 'head') === headRef &&
488
+ getField(c.e, 'start') === startRef);
489
+ if (nextConnectors.length === 0) {
490
+ nextConnectors.push(...ext.connectors.filter((c) => c.e.archetype === archetype && getField(c.e, 'head') === headRef));
491
+ }
477
492
  if (nextConnectors.length === 0) {
478
493
  const beat = getNum(resolveOriginal(ext, headRef) ?? { archetype: '', data: [] }, '#BEAT');
479
494
  if (beat >= ultimateTailBeat) {
@@ -489,6 +504,33 @@ export const extendedToLevelData = (data, offset = 0) => {
489
504
  visit(tailRef);
490
505
  return ultimateTailRef;
491
506
  }
507
+ function getUltimateStartRef(archetype, startRef, headRef) {
508
+ if (!isSlideTickRef(headRef))
509
+ return startRef;
510
+ let ultimateStartRef = startRef;
511
+ let ultimateStartBeat = getNum(resolveOriginal(ext, startRef) ?? { archetype: '', data: [] }, '#BEAT');
512
+ const visited = new Set();
513
+ function visit(currentHeadRef) {
514
+ const key = `${archetype}|${String(currentHeadRef)}`;
515
+ if (currentHeadRef === undefined || visited.has(key))
516
+ return;
517
+ visited.add(key);
518
+ if (!isSlideTickRef(currentHeadRef))
519
+ return;
520
+ const previousConnectors = ext.connectors.filter((c) => c.e.archetype === archetype && getField(c.e, 'tail') === currentHeadRef);
521
+ for (const previousConnector of previousConnectors) {
522
+ const previousStartRef = getField(previousConnector.e, 'start');
523
+ const previousStartBeat = getNum(resolveOriginal(ext, previousStartRef) ?? { archetype: '', data: [] }, '#BEAT');
524
+ if (previousStartBeat <= ultimateStartBeat) {
525
+ ultimateStartBeat = previousStartBeat;
526
+ ultimateStartRef = previousStartRef;
527
+ }
528
+ visit(getField(previousConnector.e, 'head'));
529
+ }
530
+ }
531
+ visit(headRef);
532
+ return ultimateStartRef;
533
+ }
492
534
  function setInferredActiveHead(note, activeHead) {
493
535
  if (note.refs.activeHead)
494
536
  return;
@@ -497,10 +539,13 @@ export const extendedToLevelData = (data, offset = 0) => {
497
539
  function isIgnoredSlideTickRef(ref) {
498
540
  return resolveOriginal(ext, ref)?.archetype === 'IgnoredSlideTickNote';
499
541
  }
500
- function getNextConnectorWithHead(startRef, headRef) {
501
- return ext.connectors.find(({ e }) => getField(e, 'start') === startRef && getField(e, 'head') === headRef);
542
+ function getNextConnectorWithHead(archetype, startRef, headRef) {
543
+ return (ext.connectors.find(({ e }) => e.archetype === archetype &&
544
+ getField(e, 'start') === startRef &&
545
+ getField(e, 'head') === headRef) ??
546
+ ext.connectors.find(({ e }) => e.archetype === archetype && getField(e, 'head') === headRef));
502
547
  }
503
- function resolveConnectorTailRef(startRef, tailRef) {
548
+ function resolveConnectorTailRef(archetype, startRef, tailRef) {
504
549
  const skippedNoteRefs = [];
505
550
  const skippedConnectors = [];
506
551
  const visited = new Set();
@@ -513,7 +558,7 @@ export const extendedToLevelData = (data, offset = 0) => {
513
558
  break;
514
559
  visited.add(key);
515
560
  skippedNoteRefs.push(resolvedTailRef);
516
- const nextConnector = getNextConnectorWithHead(startRef, resolvedTailRef);
561
+ const nextConnector = getNextConnectorWithHead(archetype, startRef, resolvedTailRef);
517
562
  if (!nextConnector)
518
563
  break;
519
564
  skippedConnectors.push(nextConnector);
@@ -526,21 +571,22 @@ export const extendedToLevelData = (data, offset = 0) => {
526
571
  const headRef = getField(e, 'head');
527
572
  if (isIgnoredSlideTickRef(headRef))
528
573
  continue;
529
- const { tailRef, skippedNoteRefs, skippedConnectors } = resolveConnectorTailRef(startRef, getField(e, 'tail'));
574
+ const { tailRef, skippedNoteRefs, skippedConnectors } = resolveConnectorTailRef(e.archetype, startRef, getField(e, 'tail'));
530
575
  if (isIgnoredSlideTickRef(tailRef))
531
576
  continue;
532
577
  const tail = getNote(tailRef);
533
578
  const rawHeadOriginal = resolveOriginal(ext, headRef);
534
579
  const tailOriginal = resolveOriginal(ext, tailRef);
535
580
  const rawHead = getNote(headRef);
536
- const activeHead = getNote(startRef);
581
+ const activeStartRef = getUltimateStartRef(e.archetype, startRef, headRef);
582
+ const activeHead = getNote(activeStartRef);
537
583
  const usesStartAsHead = shouldUseStartAsHead(startRef, headRef);
538
584
  const head = usesStartAsHead ? activeHead : rawHead;
539
585
  const headOriginal = resolveOriginal(ext, usesStartAsHead ? startRef : headRef);
540
586
  const endRef = getField(e, 'end');
541
587
  let activeTail = getNote(endRef);
542
588
  if (!activeTail) {
543
- activeTail = getNote(getUltimateTailRef(startRef, tailRef));
589
+ activeTail = getNote(getUltimateTailRef(e.archetype, activeStartRef, tailRef));
544
590
  }
545
591
  if (!activeTail) {
546
592
  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.18";
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.18';
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.18",
4
4
  "description": "Perspective-lane rhythm game for Sonolus",
5
5
  "author": "Hyeon2",
6
6
  "repository": {