sonolus-next-rush-engine 1.4.0-beta.v5 → 1.4.0-beta.v6

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.
Binary file
@@ -97,6 +97,8 @@ const guideKindMapping = {
97
97
  class ExtData {
98
98
  constructor(entities) {
99
99
  this.byArch = new Map();
100
+ this.byName = new Map();
101
+ this.indexByEntity = new Map();
100
102
  this.notes = [];
101
103
  this.connectors = [];
102
104
  this.entities = entities;
@@ -105,6 +107,10 @@ class ExtData {
105
107
  if (!this.byArch.has(arch))
106
108
  this.byArch.set(arch, []);
107
109
  this.byArch.get(arch)?.push({ idx, e });
110
+ if (e.name !== undefined && !this.byName.has(e.name))
111
+ this.byName.set(e.name, e);
112
+ if (!this.indexByEntity.has(e))
113
+ this.indexByEntity.set(e, idx);
108
114
  if (arch in noteTypeMapping)
109
115
  this.notes.push({ idx, e });
110
116
  if (arch in activeConnectorKindMapping)
@@ -183,11 +189,31 @@ function resolveOriginal(ext, ref) {
183
189
  if (typeof ref === 'number')
184
190
  return ext.get(ref);
185
191
  if (typeof ref === 'string')
186
- return ext.entities.find((x) => x.name === ref);
192
+ return ext.byName.get(ref);
187
193
  return undefined;
188
194
  }
189
195
  export const extendedToLevelData = (data, offset = 0) => {
190
196
  const ext = new ExtData(data.entities);
197
+ const connectorsByHeadRef = new Map();
198
+ const connectorsByTailRef = new Map();
199
+ const connectorsByStartRef = new Map();
200
+ const pushConnectorIndex = (map, key, entry) => {
201
+ if (key === undefined)
202
+ return;
203
+ const list = map.get(key);
204
+ if (list)
205
+ list.push(entry);
206
+ else
207
+ map.set(key, [entry]);
208
+ };
209
+ for (const entry of ext.connectors) {
210
+ pushConnectorIndex(connectorsByHeadRef, getField(entry.e, 'head'), entry);
211
+ pushConnectorIndex(connectorsByTailRef, getField(entry.e, 'tail'), entry);
212
+ pushConnectorIndex(connectorsByStartRef, getField(entry.e, 'start'), entry);
213
+ }
214
+ const getConnectorsByHeadRef = (ref) => ref === undefined ? [] : (connectorsByHeadRef.get(ref) ?? []);
215
+ const getConnectorsByTailRef = (ref) => ref === undefined ? [] : (connectorsByTailRef.get(ref) ?? []);
216
+ const getConnectorsByStartRef = (ref) => ref === undefined ? [] : (connectorsByStartRef.get(ref) ?? []);
191
217
  const finalEntities = [];
192
218
  const defaultTsg = new EntityBuilder('#TIMESCALE_GROUP');
193
219
  finalEntities.push(defaultTsg);
@@ -491,11 +517,10 @@ export const extendedToLevelData = (data, offset = 0) => {
491
517
  if (headRef === undefined || visited.has(key))
492
518
  return;
493
519
  visited.add(key);
494
- const nextConnectors = ext.connectors.filter((c) => c.e.archetype === archetype &&
495
- getField(c.e, 'head') === headRef &&
496
- getField(c.e, 'start') === startRef);
520
+ const headConnectors = getConnectorsByHeadRef(headRef);
521
+ const nextConnectors = headConnectors.filter((c) => c.e.archetype === archetype && getField(c.e, 'start') === startRef);
497
522
  if (nextConnectors.length === 0) {
498
- nextConnectors.push(...ext.connectors.filter((c) => c.e.archetype === archetype && getField(c.e, 'head') === headRef));
523
+ nextConnectors.push(...headConnectors.filter((c) => c.e.archetype === archetype));
499
524
  }
500
525
  if (nextConnectors.length === 0) {
501
526
  const beat = getNum(resolveOriginal(ext, headRef) ?? { archetype: '', data: [] }, '#BEAT');
@@ -511,11 +536,9 @@ export const extendedToLevelData = (data, offset = 0) => {
511
536
  }
512
537
  visit(tailRef);
513
538
  if (isScoredSlideTickRef(ultimateTailRef)) {
514
- for (const connector of ext.connectors) {
539
+ for (const connector of getConnectorsByStartRef(startRef)) {
515
540
  if (connector.e.archetype !== archetype)
516
541
  continue;
517
- if (getField(connector.e, 'start') !== startRef)
518
- continue;
519
542
  const candidateTailRef = getField(connector.e, 'tail');
520
543
  const candidateTailBeat = getNum(resolveOriginal(ext, candidateTailRef) ?? { archetype: '', data: [] }, '#BEAT');
521
544
  if (candidateTailBeat > ultimateTailBeat) {
@@ -538,10 +561,10 @@ export const extendedToLevelData = (data, offset = 0) => {
538
561
  visited.add(key);
539
562
  if (!isSlideTickRef(currentHeadRef))
540
563
  return;
541
- let previousConnectors = ext.connectors.filter((c) => c.e.archetype === archetype && getField(c.e, 'tail') === currentHeadRef);
564
+ const tailConnectors = getConnectorsByTailRef(currentHeadRef);
565
+ let previousConnectors = tailConnectors.filter((c) => c.e.archetype === archetype);
542
566
  if (previousConnectors.length === 0) {
543
- previousConnectors = ext.connectors.filter((c) => c.e.archetype in activeConnectorKindMapping &&
544
- getField(c.e, 'tail') === currentHeadRef);
567
+ previousConnectors = tailConnectors.filter((c) => c.e.archetype in activeConnectorKindMapping);
545
568
  }
546
569
  for (const previousConnector of previousConnectors) {
547
570
  const previousStartRef = getField(previousConnector.e, 'start');
@@ -561,10 +584,8 @@ export const extendedToLevelData = (data, offset = 0) => {
561
584
  return resolveOriginal(ext, ref)?.archetype === 'IgnoredSlideTickNote';
562
585
  }
563
586
  function getNextConnectorWithHead(archetype, startRef, headRef) {
564
- return (ext.connectors.find(({ e }) => e.archetype === archetype &&
565
- getField(e, 'start') === startRef &&
566
- getField(e, 'head') === headRef) ??
567
- ext.connectors.find(({ e }) => e.archetype === archetype && getField(e, 'head') === headRef));
587
+ const headConnectors = getConnectorsByHeadRef(headRef);
588
+ return (headConnectors.find(({ e }) => e.archetype === archetype && getField(e, 'start') === startRef) ?? headConnectors.find(({ e }) => e.archetype === archetype));
568
589
  }
569
590
  function resolveConnectorTailRef(archetype, startRef, tailRef) {
570
591
  const skippedNoteRefs = [];
@@ -589,7 +610,7 @@ export const extendedToLevelData = (data, offset = 0) => {
589
610
  }
590
611
  function refKey(ref) {
591
612
  const original = resolveOriginal(ext, ref);
592
- const index = original ? ext.entities.indexOf(original) : -1;
613
+ const index = original ? (ext.indexByEntity.get(original) ?? -1) : -1;
593
614
  return index >= 0 ? `index:${index}` : `${typeof ref}:${String(ref)}`;
594
615
  }
595
616
  function getRefBeat(ref) {
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.4.0-beta.v5";
10
+ export declare const version = "1.4.0-beta.v6";
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.4.0-beta.v5';
68
+ export const version = '1.4.0-beta.v6';
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.4.0-beta.v5",
3
+ "version": "1.4.0-beta.v6",
4
4
  "description": "Perspective-lane rhythm game for Sonolus",
5
5
  "author": "Hyeon2",
6
6
  "repository": {