kipphi 2.1.3 → 2.1.4

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/env.ts CHANGED
@@ -13,7 +13,7 @@
13
13
 
14
14
 
15
15
  // 就挺神奇的!明明typeof后面跟值,这里却可以写成类型导入
16
- import { type TimeT, type EventValueType } from "./chartTypes";
16
+ import { type TimeT, type EventValueType, EventValueESType } from "./chartTypes";
17
17
  import { EventNode } from "./event";
18
18
  import { toTimeString } from "./util";
19
19
 
@@ -206,16 +206,23 @@ interface _Error extends _CheckMap {
206
206
  error: "";
207
207
  }
208
208
 
209
+ type GetEnumKey<TEnum extends Record<string, any>, TValue extends TEnum[keyof TEnum]> = {
210
+ [K in keyof TEnum]: TEnum[K] extends TValue ? K : never
211
+ }[keyof TEnum];
209
212
 
210
- interface ErrorMap extends Record<keyof typeof ERROR_IDS, Array<any>>{
211
- EVENT_NODE_NOT_DENSE: [EventNode];
213
+ type ERROR_NAMES = keyof typeof ERROR_IDS;
214
+
215
+ interface ErrorMap extends Record<ERROR_NAMES, Array<any>>{
216
+ EVENT_NODE_NOT_DENSE: [EventNode<EventValueESType>];
217
+ EVENT_NODE_TIME_NOT_INCREMENTAL: [EventNode<EventValueESType>];
218
+
212
219
  }
213
220
 
214
- type ArgsOf<ET extends ERROR_IDS> = ET extends keyof ErrorMap ? ErrorMap[ET] : never;
221
+ type ArgsOf<ET extends ERROR_IDS> = GetEnumKey<typeof ERROR_IDS, ET> extends keyof ErrorMap ? ErrorMap[GetEnumKey<typeof ERROR_IDS, ET>] : [];
215
222
 
216
223
  export class KPAError<ET extends ERROR_IDS> extends Error {
217
224
  fixed = false;
218
- args: ArgsOf<ET> | [];
225
+ args: ArgsOf<ET>;
219
226
  constructor(message: string, public id: ET) {
220
227
  super(message);
221
228
  }
@@ -224,16 +231,16 @@ export class KPAError<ET extends ERROR_IDS> extends Error {
224
231
  *
225
232
  * 此时可以调用该方法,该方法会输出错误并把它保存到KPAError的一个`buffer`静态属性下。
226
233
  */
227
- warn(...args: ArgsOf<ET> | []) {
234
+ warn(...args: ArgsOf<ET>) {
228
235
  console.warn(this.stack);
229
236
  this.args = args;
230
- KPAError.buffer.push(this);
237
+ KPAError.buffer.push(this as any);
231
238
  }
232
- fix(...args: ArgsOf<ET> | []) {
239
+ fix(...args: ArgsOf<ET>) {
233
240
  console.warn("[Auto Fixed]" + this.stack);
234
241
  this.fixed = true;
235
242
  this.args = args;
236
- KPAError.buffer.push(this);
243
+ KPAError.buffer.push(this as any);
237
244
  }
238
245
  static buffer: KPAError<ERROR_IDS>[] = [];
239
246
  static flush() {
@@ -241,9 +248,10 @@ export class KPAError<ET extends ERROR_IDS> extends Error {
241
248
  }
242
249
  }
243
250
 
251
+
244
252
  export const err = new Proxy(ERRORS, {
245
253
  get(target, name) {
246
- return (...args: any[]) => new KPAError(target[name](...args) + `(KP${ERROR_IDS[name].toString(16)})`, ERROR_IDS[name]);
254
+ return (...args: any[]) => new KPAError<typeof ERROR_IDS[keyof typeof ERROR_IDS]>(target[name](...args) + `(KP${ERROR_IDS[name].toString(16)})`, ERROR_IDS[name]);
247
255
  }
248
256
  }) as unknown as { [key in keyof typeof ERRORS]: (...args: Parameters<typeof ERRORS[key]>) => KPAError<typeof ERROR_IDS[key]>};
249
257
 
package/event.ts CHANGED
@@ -518,6 +518,7 @@ export class EventNodeSequence<VT extends EventValueESType = number> { // 泛型
518
518
  */
519
519
  static fromRPEJSON<T extends EventType, VT extends EventValueESType = number>(type: T, data: EventDataRPELike<VT>[], chart: Chart, pos: string, endValue?: number) {
520
520
  const {templateEasingLib: templates} = chart
521
+ data.sort((a, b) => TC.cmp(a.startTime, b.startTime));
521
522
  const length = data.length;
522
523
  // const isSpeed = type === EventType.Speed;
523
524
  // console.log(isSpeed)
@@ -540,16 +541,16 @@ export class EventNodeSequence<VT extends EventValueESType = number> { // 泛型
540
541
  // 读取事件列表
541
542
  for (let index = 0; index < length; index++) {
542
543
  const event = data[index];
544
+ const [start, end] = (type === EventType.text
545
+ ? EventNode.fromTextEvent(event as EventDataRPELike<string>, templates)
546
+ : EventNode.fromEvent(event as EventDataRPELike<number | RGB>, chart)) as unknown as [EventStartNode<VT>, EventEndNode<VT>];
543
547
  if (TC.lt(event.startTime, lastEndTime)) { // event.startTime < lastEndTime
544
- err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}] and the previous`).warn()
548
+ err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}] and the previous`).warn(start)
545
549
  }
546
550
  if (!TC.lt(event.startTime, event.endTime)) {
547
- err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}]`).warn()
551
+ err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}]`).warn(start)
548
552
  }
549
553
  lastEndTime = event.endTime;
550
- const [start, end] = (type === EventType.text
551
- ? EventNode.fromTextEvent(event as EventDataRPELike<string>, templates)
552
- : EventNode.fromEvent(event as EventDataRPELike<number | RGB>, chart)) as unknown as [EventStartNode<VT>, EventEndNode<VT>];
553
554
  // 刚开始时,上个节点是头
554
555
  if (lastEnd.type === NodeType.HEAD) {
555
556
  EventNode.connect(lastEnd, start)
@@ -649,21 +650,21 @@ export class EventNodeSequence<VT extends EventValueESType = number> { // 泛型
649
650
  // 从前面复制了,复用性减一
650
651
  // KPA2没有更改RPE的按事件存储的机制。
651
652
  if (TC.lt(event.startTime, lastEndTime)) { // event.startTime < lastEndTime
652
- err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}] and the previous`).warn()
653
+ err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}] and the previous`).warn(start)
653
654
  }
654
655
  if (!TC.lt(event.startTime, event.endTime)) {
655
656
  if (TC.eq(event.startTime, event.endTime)) {
656
657
  // 零长事件直接忽略,并认为已经修复
657
- err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}]`).fix();
658
+ err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}]`).fix(start);
658
659
  continue;
659
660
  } else {
660
- err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}]`).warn()
661
+ err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}]`).warn(start)
661
662
  }
662
663
  }
663
664
  if (lastEnd.type === NodeType.HEAD) {
664
665
  EventNode.connect(lastEnd, start)
665
666
  } else if (TC.gt(event.startTime, lastEndTime)) {
666
- err.EVENT_NODE_NOT_DENSE(`${pos}.events[${index}]`).warn();
667
+ err.EVENT_NODE_NOT_DENSE(`${pos}.events[${index}]`).warn(start);
667
668
  const mid = new EventStartNode(lastEndTime, start.value);
668
669
  const midEnd = new EventEndNode(event.startTime, end.value);
669
670
  EventNode.connect(lastEnd, mid);
@@ -953,7 +954,7 @@ export class EventNodeSequence<VT extends EventValueESType = number> { // 泛型
953
954
  checkErrors() {
954
955
  let currentNode: EventStartNode<VT> = this.head.next;
955
956
  if (TC.ne(currentNode.time, [0, 0, 1])) {
956
- err.EVENT_NODE_NOT_DENSE(`${this.id}, ${currentNode.time}`).fix();
957
+ err.EVENT_NODE_NOT_DENSE(`${this.id}, ${currentNode.time}`).fix(currentNode);
957
958
  currentNode.time = [0, 0, 1];
958
959
  }
959
960
  const endNode = currentNode.next;
@@ -982,10 +983,10 @@ export class EventNodeSequence<VT extends EventValueESType = number> { // 泛型
982
983
  break;
983
984
  }
984
985
  if (!TC.gt(endNode.time, currentNode.time)) {
985
- err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${this.id}, ${currentNode.time}`).warn();
986
+ err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${this.id}, ${currentNode.time}`).warn(currentNode);
986
987
  }
987
988
  if (TC.ne(lastEnd.time, currentNode.time)) {
988
- err.EVENT_NODE_NOT_DENSE(`${this.id}, ${currentNode.time}`).warn();
989
+ err.EVENT_NODE_NOT_DENSE(`${this.id}, ${currentNode.time}`).warn(currentNode);
989
990
  }
990
991
  currentNode = currentNode.next.next;
991
992
  lastEnd = endNode;
package/index.d.ts CHANGED
@@ -553,7 +553,7 @@ declare module "chartTypes" {
553
553
  export type ExtendedEventTypeName = "scaleX" | "scaleY" | "text" | "color";
554
554
  }
555
555
  declare module "version" {
556
- export const VERSION = 213;
556
+ export const VERSION = 214;
557
557
  export const SCHEMA = "https://cdn.jsdelivr.net/npm/kipphi@2.1.0/chartType2.schema.json";
558
558
  }
559
559
  declare module "util" {
@@ -2120,7 +2120,7 @@ declare module "event" {
2120
2120
  };
2121
2121
  }
2122
2122
  declare module "env" {
2123
- import { type TimeT, type EventValueType } from "chartTypes";
2123
+ import { type TimeT, type EventValueType, EventValueESType } from "chartTypes";
2124
2124
  import { EventNode } from "event";
2125
2125
  export enum ERROR_IDS {
2126
2126
  UI_OCCUPIED = 272,
@@ -2200,22 +2200,27 @@ declare module "env" {
2200
2200
  TEMPLATE_EASING_CIRCULAR_REFERENCE: (temEasName: string) => string;
2201
2201
  EASING_DELTA_CANNOT_BE_ZERO: (seqName: string, time: TimeT) => string;
2202
2202
  };
2203
- interface ErrorMap extends Record<keyof typeof ERROR_IDS, Array<any>> {
2204
- EVENT_NODE_NOT_DENSE: [EventNode];
2205
- }
2206
- type ArgsOf<ET extends ERROR_IDS> = ET extends keyof ErrorMap ? ErrorMap[ET] : never;
2203
+ type GetEnumKey<TEnum extends Record<string, any>, TValue extends TEnum[keyof TEnum]> = {
2204
+ [K in keyof TEnum]: TEnum[K] extends TValue ? K : never;
2205
+ }[keyof TEnum];
2206
+ type ERROR_NAMES = keyof typeof ERROR_IDS;
2207
+ interface ErrorMap extends Record<ERROR_NAMES, Array<any>> {
2208
+ EVENT_NODE_NOT_DENSE: [EventNode<EventValueESType>];
2209
+ EVENT_NODE_TIME_NOT_INCREMENTAL: [EventNode<EventValueESType>];
2210
+ }
2211
+ type ArgsOf<ET extends ERROR_IDS> = GetEnumKey<typeof ERROR_IDS, ET> extends keyof ErrorMap ? ErrorMap[GetEnumKey<typeof ERROR_IDS, ET>] : [];
2207
2212
  export class KPAError<ET extends ERROR_IDS> extends Error {
2208
2213
  id: ET;
2209
2214
  fixed: boolean;
2210
- args: ArgsOf<ET> | [];
2215
+ args: ArgsOf<ET>;
2211
2216
  constructor(message: string, id: ET);
2212
2217
  /**
2213
2218
  * 对于解析谱面等场景,有时可能需要找出全部的错误,不宜直接抛出错误中断代码执行
2214
2219
  *
2215
2220
  * 此时可以调用该方法,该方法会输出错误并把它保存到KPAError的一个`buffer`静态属性下。
2216
2221
  */
2217
- warn(...args: ArgsOf<ET> | []): void;
2218
- fix(...args: ArgsOf<ET> | []): void;
2222
+ warn(...args: ArgsOf<ET>): void;
2223
+ fix(...args: ArgsOf<ET>): void;
2219
2224
  static buffer: KPAError<ERROR_IDS>[];
2220
2225
  static flush(): void;
2221
2226
  }
@@ -2288,6 +2293,7 @@ declare module "time" {
2288
2293
  static gt(beaT1: TimeT, beaT2: TimeT): boolean;
2289
2294
  /** @returns beaT1 < beaT2 */
2290
2295
  static lt(beaT1: TimeT, beaT2: TimeT): boolean;
2296
+ static cmp(beaT1: TimeT, beaT2: TimeT): number;
2291
2297
  /** @returns beaT1 != beaT2 */
2292
2298
  static ne(beaT1: TimeT, beaT2: TimeT): boolean;
2293
2299
  /**
@@ -2971,7 +2977,7 @@ declare module "rpeChartCompiler" {
2971
2977
  deletesEmptyLines: boolean;
2972
2978
  constructor(chart: Chart);
2973
2979
  compileChart(): ChartDataRPE;
2974
- compileJudgeLine(judgeLine: JudgeLine): JudgeLineDataRPE;
2980
+ compileJudgeLine(judgeLine: JudgeLine, lines: JudgeLine[]): JudgeLineDataRPE;
2975
2981
  compileEasedEvent<VT extends EventValueESType>(snode: EventStartNode<VT> & {
2976
2982
  evaluator: EasedEvaluatorOfType<VT>;
2977
2983
  }, getValue: (node: EventStartNode<VT> | EventEndNode<VT>) => VT): EventDataRPELike<VT>;
@@ -2993,6 +2999,7 @@ declare module "rpeChartCompiler" {
2993
2999
  * @returns
2994
3000
  */
2995
3001
  substitute<VT extends EventValueESType>(seq: EventNodeSequence<VT>): EventNodeSequence<VT>;
3002
+ static replaceFilename(filename: string): string;
2996
3003
  }
2997
3004
  }
2998
3005
  declare module "index" {
package/index.js CHANGED
@@ -250,6 +250,16 @@ class TC2 {
250
250
  static lt(beaT1, beaT2) {
251
251
  return beaT1[0] < beaT2[0] || beaT1[0] === beaT2[0] && beaT1[1] * beaT2[2] < beaT1[2] * beaT2[1];
252
252
  }
253
+ static cmp(beaT1, beaT2) {
254
+ if (beaT1[0] > beaT2[0]) {
255
+ return 1;
256
+ } else if (beaT1[0] < beaT2[0]) {
257
+ return -1;
258
+ } else {
259
+ return beaT1[1] * beaT2[2] > beaT1[2] * beaT2[1] ? 1 : -1;
260
+ }
261
+ return 0;
262
+ }
253
263
  static ne(beaT1, beaT2) {
254
264
  return beaT1[0] !== beaT2[0] || beaT1[1] * beaT2[2] !== beaT1[2] * beaT2[1];
255
265
  }
@@ -1756,6 +1766,7 @@ class EventNodeSequence {
1756
1766
  }
1757
1767
  static fromRPEJSON(type, data, chart, pos, endValue) {
1758
1768
  const { templateEasingLib: templates } = chart;
1769
+ data.sort((a, b) => TC2.cmp(a.startTime, b.startTime));
1759
1770
  const length = data.length;
1760
1771
  const seq = new EventNodeSequence(type, type === 5 /* easing */ ? TC2.toBeats(data[length - 1].endTime) : chart.effectiveBeats);
1761
1772
  let listLength = length;
@@ -1771,14 +1782,14 @@ class EventNodeSequence {
1771
1782
  let lastEndTime = [0, 0, 1];
1772
1783
  for (let index = 0;index < length; index++) {
1773
1784
  const event = data[index];
1785
+ const [start, end] = type === 9 /* text */ ? EventNode.fromTextEvent(event, templates) : EventNode.fromEvent(event, chart);
1774
1786
  if (TC2.lt(event.startTime, lastEndTime)) {
1775
- err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}] and the previous`).warn();
1787
+ err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}] and the previous`).warn(start);
1776
1788
  }
1777
1789
  if (!TC2.lt(event.startTime, event.endTime)) {
1778
- err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}]`).warn();
1790
+ err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}]`).warn(start);
1779
1791
  }
1780
1792
  lastEndTime = event.endTime;
1781
- const [start, end] = type === 9 /* text */ ? EventNode.fromTextEvent(event, templates) : EventNode.fromEvent(event, chart);
1782
1793
  if (lastEnd.type === 0 /* HEAD */) {
1783
1794
  EventNode.connect(lastEnd, start);
1784
1795
  } else if (lastEnd.value === lastEnd.previous.value && lastEnd.previous.evaluator instanceof EasedEvaluator) {
@@ -1833,20 +1844,20 @@ class EventNodeSequence {
1833
1844
  chart.segmentedTemplates.set(evaluator.easing, [pos, start.time]);
1834
1845
  }
1835
1846
  if (TC2.lt(event.startTime, lastEndTime)) {
1836
- err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}] and the previous`).warn();
1847
+ err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}] and the previous`).warn(start);
1837
1848
  }
1838
1849
  if (!TC2.lt(event.startTime, event.endTime)) {
1839
1850
  if (TC2.eq(event.startTime, event.endTime)) {
1840
- err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}]`).fix();
1851
+ err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}]`).fix(start);
1841
1852
  continue;
1842
1853
  } else {
1843
- err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}]`).warn();
1854
+ err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}]`).warn(start);
1844
1855
  }
1845
1856
  }
1846
1857
  if (lastEnd.type === 0 /* HEAD */) {
1847
1858
  EventNode.connect(lastEnd, start);
1848
1859
  } else if (TC2.gt(event.startTime, lastEndTime)) {
1849
- err.EVENT_NODE_NOT_DENSE(`${pos}.events[${index}]`).warn();
1860
+ err.EVENT_NODE_NOT_DENSE(`${pos}.events[${index}]`).warn(start);
1850
1861
  const mid = new EventStartNode(lastEndTime, start.value);
1851
1862
  const midEnd = new EventEndNode(event.startTime, end.value);
1852
1863
  EventNode.connect(lastEnd, mid);
@@ -2064,7 +2075,7 @@ class EventNodeSequence {
2064
2075
  checkErrors() {
2065
2076
  let currentNode = this.head.next;
2066
2077
  if (TC2.ne(currentNode.time, [0, 0, 1])) {
2067
- err.EVENT_NODE_NOT_DENSE(`${this.id}, ${currentNode.time}`).fix();
2078
+ err.EVENT_NODE_NOT_DENSE(`${this.id}, ${currentNode.time}`).fix(currentNode);
2068
2079
  currentNode.time = [0, 0, 1];
2069
2080
  }
2070
2081
  const endNode = currentNode.next;
@@ -2092,10 +2103,10 @@ class EventNodeSequence {
2092
2103
  break;
2093
2104
  }
2094
2105
  if (!TC2.gt(endNode2.time, currentNode.time)) {
2095
- err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${this.id}, ${currentNode.time}`).warn();
2106
+ err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${this.id}, ${currentNode.time}`).warn(currentNode);
2096
2107
  }
2097
2108
  if (TC2.ne(lastEnd.time, currentNode.time)) {
2098
- err.EVENT_NODE_NOT_DENSE(`${this.id}, ${currentNode.time}`).warn();
2109
+ err.EVENT_NODE_NOT_DENSE(`${this.id}, ${currentNode.time}`).warn(currentNode);
2099
2110
  }
2100
2111
  currentNode = currentNode.next.next;
2101
2112
  lastEnd = endNode2;
@@ -3379,7 +3390,7 @@ class TimeCalculator {
3379
3390
  }
3380
3391
  }
3381
3392
  // src/version.ts
3382
- var VERSION = 213;
3393
+ var VERSION = 214;
3383
3394
  var SCHEMA = "https://cdn.jsdelivr.net/npm/kipphi@2.1.0/chartType2.schema.json";
3384
3395
 
3385
3396
  // src/chart.ts
@@ -5443,17 +5454,18 @@ class RPEChartCompiler {
5443
5454
  node = endNode.next;
5444
5455
  }
5445
5456
  return true;
5446
- });
5457
+ }) || line2.children.size > 0;
5447
5458
  } : () => true;
5448
- const judgeLineList = chart2.judgeLines.filter(filter).map((line2) => this.compileJudgeLine(line2));
5459
+ const judgeLineList = chart2.judgeLines.filter(filter);
5460
+ const judgeLineDataList = judgeLineList.map((line2) => this.compileJudgeLine(line2, judgeLineList));
5449
5461
  const BPMList = chart2.timeCalculator.dump();
5450
5462
  const META = {
5451
- RPEVersion: 1,
5463
+ RPEVersion: 170,
5452
5464
  background: "illustration.png",
5453
5465
  charter: chart2.charter,
5454
5466
  composer: chart2.composer,
5455
5467
  illustration: chart2.illustrator,
5456
- id: Math.random().toString().slice(2, 10),
5468
+ id: Math.random().toString().slice(2, 18),
5457
5469
  level: chart2.level,
5458
5470
  name: chart2.name,
5459
5471
  offset: chart2.offset,
@@ -5464,9 +5476,9 @@ class RPEChartCompiler {
5464
5476
  if (!target) {
5465
5477
  continue;
5466
5478
  }
5467
- const lineData = judgeLineList[target.id];
5479
+ const lineData = judgeLineDataList[judgeLineList.indexOf(target)];
5468
5480
  if (lineData.attachUI) {
5469
- judgeLineList.push({
5481
+ judgeLineDataList.push({
5470
5482
  Group: 0,
5471
5483
  Name: "Auto created for " + uiName,
5472
5484
  Texture: "line.png",
@@ -5474,7 +5486,7 @@ class RPEChartCompiler {
5474
5486
  notes: [],
5475
5487
  bpmfactor: 1,
5476
5488
  eventLayers: [],
5477
- father: target.id,
5489
+ father: judgeLineList.indexOf(target),
5478
5490
  isCover: lineData.isCover,
5479
5491
  numOfNotes: 0,
5480
5492
  anchor: target.anchor,
@@ -5487,7 +5499,7 @@ class RPEChartCompiler {
5487
5499
  return {
5488
5500
  BPMList,
5489
5501
  META,
5490
- judgeLineList,
5502
+ judgeLineList: judgeLineDataList,
5491
5503
  judgeLineGroup: judgeLineGroups,
5492
5504
  multiLineString: "",
5493
5505
  multiScale: 1,
@@ -5495,14 +5507,15 @@ class RPEChartCompiler {
5495
5507
  kpaChartTime: chart2.chartingSeconds
5496
5508
  };
5497
5509
  }
5498
- compileJudgeLine(judgeLine) {
5510
+ compileJudgeLine(judgeLine, lines) {
5499
5511
  const chart2 = this.chart;
5500
5512
  const notes = this.compileNNLists([...judgeLine.nnLists.values()], [...judgeLine.hnLists.values()]);
5513
+ const father = judgeLine.father ? lines.indexOf(judgeLine.father) : -1;
5501
5514
  return {
5502
5515
  notes,
5503
5516
  Group: chart2.judgeLineGroups.indexOf(judgeLine.group),
5504
5517
  Name: judgeLine.name,
5505
- Texture: judgeLine.texture,
5518
+ Texture: RPEChartCompiler.replaceFilename(judgeLine.texture),
5506
5519
  bpmfactor: 1,
5507
5520
  eventLayers: judgeLine.eventLayers.map((layer, index) => ({
5508
5521
  moveXEvents: layer.moveX ? this.dumpEventNodeSequence(layer.moveX) : undefined,
@@ -5517,7 +5530,7 @@ class RPEChartCompiler {
5517
5530
  textEvents: judgeLine.extendedLayer.text ? this.dumpEventNodeSequence(judgeLine.extendedLayer.text) : undefined,
5518
5531
  colorEvents: judgeLine.extendedLayer.color ? this.dumpEventNodeSequence(judgeLine.extendedLayer.color) : undefined
5519
5532
  },
5520
- father: judgeLine.father?.id ?? -1,
5533
+ father,
5521
5534
  isCover: judgeLine.cover ? 1 : 0,
5522
5535
  numOfNotes: notes.length,
5523
5536
  anchor: judgeLine.anchor,
@@ -5791,6 +5804,17 @@ class RPEChartCompiler {
5791
5804
  EventNode.connect(lastStart, newSeq.tail);
5792
5805
  return newSeq;
5793
5806
  }
5807
+ static replaceFilename(filename) {
5808
+ const arr = [];
5809
+ for (const char of filename) {
5810
+ if (char.charCodeAt(0) >= 128) {
5811
+ arr.push(`u(${char.charCodeAt(0).toString(16)})`);
5812
+ } else {
5813
+ arr.push(char);
5814
+ }
5815
+ }
5816
+ return arr.join("");
5817
+ }
5794
5818
  }
5795
5819
  export {
5796
5820
  toTimeString,
package/note.ts CHANGED
@@ -459,7 +459,7 @@ export class NNList {
459
459
 
460
460
  return newNode
461
461
  } else {
462
- return node;
462
+ return node as NoteNode;
463
463
  }
464
464
  }
465
465
  dumpKPA(): NNListDataKPA {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kipphi",
3
3
  "description": "Parse your Phigros Chart(.rpe.json or .kpa.json) into an editor-friendly format.",
4
- "version": "2.1.3",
4
+ "version": "2.1.4",
5
5
  "author": "Team Zincs (https://github.com/TeamZincs)",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -65,18 +65,20 @@ export class RPEChartCompiler {
65
65
  }
66
66
  return true; // 有超过两个的节点
67
67
  })
68
+ || line.children.size > 0;
68
69
  } : () => true
69
70
  const judgeLineList = chart.judgeLines
70
- .filter(filter)
71
- .map(line => this.compileJudgeLine(line));
71
+ .filter(filter);
72
+ const judgeLineDataList = judgeLineList
73
+ .map(line => this.compileJudgeLine(line, judgeLineList));
72
74
  const BPMList = chart.timeCalculator.dump();
73
75
  const META: MetaData = {
74
- RPEVersion: 1,
76
+ RPEVersion: 170,
75
77
  background: 'illustration.png',
76
78
  charter: chart.charter,
77
79
  composer: chart.composer,
78
80
  illustration: chart.illustrator,
79
- id: Math.random().toString().slice(2, 10),
81
+ id: Math.random().toString().slice(2, 18),
80
82
  level: chart.level,
81
83
  name: chart.name,
82
84
  offset: chart.offset,
@@ -88,11 +90,11 @@ export class RPEChartCompiler {
88
90
  if (!target) {
89
91
  continue;
90
92
  }
91
- const lineData = judgeLineList[target.id];
93
+ const lineData = judgeLineDataList[judgeLineList.indexOf(target)];
92
94
  // RPEJSON里面一条线只能绑一个UI,KPAJSON可以绑多个
93
95
  // 所以如果绑了多个,自动给它们创建子线
94
96
  if (lineData.attachUI) {
95
- judgeLineList.push({
97
+ judgeLineDataList.push({
96
98
  Group: 0,
97
99
  Name: "Auto created for " + uiName,
98
100
  Texture: "line.png",
@@ -100,7 +102,7 @@ export class RPEChartCompiler {
100
102
  notes: [],
101
103
  bpmfactor: 1.0,
102
104
  eventLayers: [],
103
- father: target.id,
105
+ father: judgeLineList.indexOf(target),
104
106
  isCover: lineData.isCover,
105
107
  numOfNotes: 0,
106
108
  anchor: target.anchor,
@@ -116,7 +118,7 @@ export class RPEChartCompiler {
116
118
  return {
117
119
  BPMList,
118
120
  META,
119
- judgeLineList,
121
+ judgeLineList: judgeLineDataList,
120
122
  judgeLineGroup: judgeLineGroups,
121
123
  multiLineString: '',
122
124
  multiScale: 1.0,
@@ -125,15 +127,17 @@ export class RPEChartCompiler {
125
127
  };
126
128
  }
127
129
 
128
- compileJudgeLine(judgeLine: JudgeLine): JudgeLineDataRPE {
130
+ compileJudgeLine(judgeLine: JudgeLine, lines: JudgeLine[]): JudgeLineDataRPE {
129
131
  const chart = this.chart;
130
132
  const notes = this.compileNNLists([...judgeLine.nnLists.values()], [...judgeLine.hnLists.values()]);
131
133
 
134
+ const father = judgeLine.father ? lines.indexOf(judgeLine.father) : -1;
135
+
132
136
  return {
133
137
  notes: notes,
134
138
  Group: chart.judgeLineGroups.indexOf(judgeLine.group),
135
139
  Name: judgeLine.name,
136
- Texture: judgeLine.texture,
140
+ Texture: RPEChartCompiler.replaceFilename(judgeLine.texture),
137
141
  bpmfactor: 1.0,
138
142
  eventLayers: judgeLine.eventLayers.map((layer, index): EventLayerDataRPE => ({
139
143
  moveXEvents: layer.moveX ? this.dumpEventNodeSequence(layer.moveX) : undefined,
@@ -148,7 +152,7 @@ export class RPEChartCompiler {
148
152
  textEvents: judgeLine.extendedLayer.text ? this.dumpEventNodeSequence(judgeLine.extendedLayer.text) : undefined,
149
153
  colorEvents: judgeLine.extendedLayer.color ? this.dumpEventNodeSequence(judgeLine.extendedLayer.color) : undefined
150
154
  },
151
- father: judgeLine.father?.id ?? -1,
155
+ father: father,
152
156
  isCover: judgeLine.cover ? 1 : 0,
153
157
  numOfNotes: notes.length,
154
158
  anchor: judgeLine.anchor,
@@ -521,6 +525,18 @@ export class RPEChartCompiler {
521
525
  EventNode.connect(lastStart, newSeq.tail)
522
526
  return newSeq;
523
527
  }
528
+
529
+ static replaceFilename(filename: string) {
530
+ const arr = [];
531
+ for (const char of filename) {
532
+ if (char.charCodeAt(0) >= 128) {
533
+ arr.push(`u(${char.charCodeAt(0).toString(16)})`);
534
+ } else {
535
+ arr.push(char);
536
+ }
537
+ }
538
+ return arr.join("");
539
+ }
524
540
  }
525
541
  // 现在是2025年10月18日,杨哲思已经改掉了此项目最史山的代码之一,但是还是一坨
526
542
 
package/time.ts CHANGED
@@ -25,6 +25,16 @@ export default class TC {
25
25
  static lt(beaT1:TimeT, beaT2: TimeT): boolean {
26
26
  return beaT1[0] < beaT2[0] || beaT1[0] === beaT2[0] && beaT1[1] * beaT2[2] < beaT1[2] * beaT2[1]
27
27
  }
28
+ static cmp(beaT1: TimeT, beaT2: TimeT): number {
29
+ if (beaT1[0] > beaT2[0]) {
30
+ return 1;
31
+ } else if (beaT1[0] < beaT2[0]) {
32
+ return -1;
33
+ } else {
34
+ return beaT1[1] * beaT2[2] > beaT1[2] * beaT2[1] ? 1 : -1;
35
+ }
36
+ return 0;
37
+ }
28
38
  /** @returns beaT1 != beaT2 */
29
39
  static ne(beaT1:TimeT, beaT2: TimeT): boolean {
30
40
  return beaT1[0] !== beaT2[0] || beaT1[1] * beaT2[2] !== beaT1[2] * beaT2[1]
package/version.ts CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  /// #declaration:global
4
4
 
5
- export const VERSION = 213;
5
+ export const VERSION = 214;
6
6
  export const SCHEMA = "https://cdn.jsdelivr.net/npm/kipphi@2.1.0/chartType2.schema.json"
7
7
 
8
8