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 +18 -10
- package/event.ts +13 -12
- package/index.d.ts +17 -10
- package/index.js +46 -22
- package/note.ts +1 -1
- package/package.json +1 -1
- package/rpeChartCompiler.ts +27 -11
- package/time.ts +10 -0
- package/version.ts +1 -1
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
|
-
|
|
211
|
-
|
|
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] :
|
|
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 =
|
|
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
|
-
|
|
2204
|
-
|
|
2205
|
-
}
|
|
2206
|
-
type
|
|
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>
|
|
2218
|
-
fix(...args: ArgsOf<ET>
|
|
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 =
|
|
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)
|
|
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:
|
|
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,
|
|
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
|
|
5479
|
+
const lineData = judgeLineDataList[judgeLineList.indexOf(target)];
|
|
5468
5480
|
if (lineData.attachUI) {
|
|
5469
|
-
|
|
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
|
|
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
|
|
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
package/package.json
CHANGED
package/rpeChartCompiler.ts
CHANGED
|
@@ -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
|
-
|
|
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:
|
|
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,
|
|
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
|
|
93
|
+
const lineData = judgeLineDataList[judgeLineList.indexOf(target)];
|
|
92
94
|
// RPEJSON里面一条线只能绑一个UI,KPAJSON可以绑多个
|
|
93
95
|
// 所以如果绑了多个,自动给它们创建子线
|
|
94
96
|
if (lineData.attachUI) {
|
|
95
|
-
|
|
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
|
|
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:
|
|
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]
|