kipphi 2.1.3-beta.1 → 2.1.3-beta.2
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/chart.ts +32 -1
- package/env.ts +3 -0
- package/event.ts +24 -0
- package/index.d.ts +15 -1
- package/index.js +49 -5
- package/note.ts +4 -4
- package/operation/easy.ts +21 -16
- package/package.json +1 -1
package/chart.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
NormalEasing,
|
|
11
11
|
rpeEasingArray,
|
|
12
12
|
SegmentedEasing,
|
|
13
|
+
TemplateEasing,
|
|
13
14
|
TemplateEasingLib,
|
|
14
15
|
} from "./easing";
|
|
15
16
|
|
|
@@ -149,6 +150,11 @@ export class Chart {
|
|
|
149
150
|
/** 难度等级显示绑定的判定线 */
|
|
150
151
|
levelAttach: JudgeLine | null = null;
|
|
151
152
|
|
|
153
|
+
/** 仅用于构造时检查
|
|
154
|
+
* @internal
|
|
155
|
+
*/
|
|
156
|
+
segmentedTemplates: Map<(SegmentedEasing & { easing: TemplateEasing}), [string, TimeT]> = new Map();
|
|
157
|
+
|
|
152
158
|
constructor() {}
|
|
153
159
|
|
|
154
160
|
/**
|
|
@@ -286,6 +292,9 @@ export class Chart {
|
|
|
286
292
|
for (let i = 0; i < len; i++) {
|
|
287
293
|
const easingData = templateEasings[i];
|
|
288
294
|
const sequence = chart.sequenceMap.get(easingData.content);
|
|
295
|
+
if (!sequence) {
|
|
296
|
+
continue; // 后面check的时候会错误处理
|
|
297
|
+
}
|
|
289
298
|
if (sequence.type !== EventType.easing) {
|
|
290
299
|
throw err.CANNOT_IMPLEMENT_TEMEAS_WITH_NON_EASING_ENS(easingData.name);
|
|
291
300
|
}
|
|
@@ -303,7 +312,10 @@ export class Chart {
|
|
|
303
312
|
}
|
|
304
313
|
}
|
|
305
314
|
|
|
306
|
-
chart.templateEasingLib.check()
|
|
315
|
+
chart.templateEasingLib.check();
|
|
316
|
+
|
|
317
|
+
chart.checkSegmentedTemplates();
|
|
318
|
+
|
|
307
319
|
for (const lineData of data.orphanLines) {
|
|
308
320
|
const line: JudgeLine = JudgeLine.fromKPAJSON(data.version, chart, lineData.id, lineData, chart.templateEasingLib, chart.timeCalculator)
|
|
309
321
|
chart.orphanLines.push(line)
|
|
@@ -727,6 +739,25 @@ export class Chart {
|
|
|
727
739
|
|
|
728
740
|
}
|
|
729
741
|
*/
|
|
742
|
+
checkErrors() {
|
|
743
|
+
KPAError.flush();
|
|
744
|
+
for (const [_, seq] of this.sequenceMap) {
|
|
745
|
+
seq.checkErrors();
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* 用于构造谱面时检查
|
|
750
|
+
*/
|
|
751
|
+
protected checkSegmentedTemplates() {
|
|
752
|
+
for (const [easing, [pos, time]] of this.segmentedTemplates) {
|
|
753
|
+
const inner = easing.easing;
|
|
754
|
+
if (inner.getValue(easing.left) === inner.getValue(easing.right)) {
|
|
755
|
+
err.EASING_DELTA_CANNOT_BE_ZERO(pos, time).warn();
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
this.segmentedTemplates.clear();
|
|
759
|
+
// 查完就清除,不再需要
|
|
760
|
+
}
|
|
730
761
|
}
|
|
731
762
|
|
|
732
763
|
/**
|
package/env.ts
CHANGED
|
@@ -74,6 +74,7 @@ export enum ERROR_IDS {
|
|
|
74
74
|
NODES_NOT_BELONG_TO_SAME_SEQUENCE = EASING | INVALID_USAGE | 2,
|
|
75
75
|
NODES_HAS_ZERO_DELTA = EASING | INVALID_USAGE | 3,
|
|
76
76
|
TEMPLATE_EASING_CIRCULAR_REFERENCE = EASING | INVALID_USAGE | 4,
|
|
77
|
+
EASING_DELTA_CANNOT_BE_ZERO = EASING | INVALID_USAGE | 5,
|
|
77
78
|
|
|
78
79
|
CANNOT_DIVIDE_EXPRESSION_EVALUATOR = EVALUATOR | INVALID_USAGE | 0,
|
|
79
80
|
MISSING_MACRO_EVALUATOR_KEY = EVALUATOR | INVALID_DATA | 0,
|
|
@@ -184,6 +185,8 @@ export const ERRORS = {
|
|
|
184
185
|
`Hold should have a duration.`,
|
|
185
186
|
TEMPLATE_EASING_CIRCULAR_REFERENCE: (temEasName: string) =>
|
|
186
187
|
`Template Easing '${temEasName}' has circular reference`,
|
|
188
|
+
EASING_DELTA_CANNOT_BE_ZERO: (seqName: string, time: TimeT) =>
|
|
189
|
+
`Easing delta cannot be zero. (at ${seqName}, ${toTimeString(time)}`,
|
|
187
190
|
} satisfies Record<keyof typeof ERROR_IDS, (...args: any[]) => string>
|
|
188
191
|
|
|
189
192
|
type EnumKeys<E extends Record<string, string | number>> = E[keyof E];
|
package/event.ts
CHANGED
|
@@ -640,6 +640,12 @@ export class EventNodeSequence<VT extends EventValueESType = number> { // 泛型
|
|
|
640
640
|
for (let index = 0; index < length; index++) {
|
|
641
641
|
const event = data[index];
|
|
642
642
|
const [start, end] = chart.createEventFromData<VT>(event, valueType, `${pos}.events[${index}]`);
|
|
643
|
+
|
|
644
|
+
// 收集被截的模板缓动
|
|
645
|
+
const evaluator = start.evaluator;
|
|
646
|
+
if (evaluator instanceof EasedEvaluator && evaluator.easing instanceof SegmentedEasing && evaluator.easing.easing instanceof TemplateEasing) {
|
|
647
|
+
chart.segmentedTemplates.set(evaluator.easing as any, [pos, start.time]);
|
|
648
|
+
}
|
|
643
649
|
// 从前面复制了,复用性减一
|
|
644
650
|
// KPA2没有更改RPE的按事件存储的机制。
|
|
645
651
|
if (TC.lt(event.startTime, lastEndTime)) { // event.startTime < lastEndTime
|
|
@@ -956,15 +962,33 @@ export class EventNodeSequence<VT extends EventValueESType = number> { // 泛型
|
|
|
956
962
|
}
|
|
957
963
|
|
|
958
964
|
let lastEnd: EventEndNode<VT> = endNode;
|
|
965
|
+
currentNode = endNode.next;
|
|
959
966
|
while (true) {
|
|
967
|
+
const evaluator = currentNode.evaluator;
|
|
968
|
+
if (this.type === EventType.easing && evaluator instanceof EasedEvaluator && evaluator.easing instanceof TemplateEasing) {
|
|
969
|
+
if (TemplateEasing.checkCircularReference(this as EventNodeSequence, evaluator.easing)) {
|
|
970
|
+
err.TEMPLATE_EASING_CIRCULAR_REFERENCE(this.id).warn();
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
if (evaluator instanceof EasedEvaluator && evaluator.easing instanceof SegmentedEasing) {
|
|
974
|
+
const easing = evaluator.easing;
|
|
975
|
+
const inner = easing.easing;
|
|
976
|
+
if (inner.getValue(easing.left) === inner.getValue(easing.right)) {
|
|
977
|
+
err.EASING_DELTA_CANNOT_BE_ZERO(this.id, currentNode.time).warn();
|
|
978
|
+
}
|
|
979
|
+
}
|
|
960
980
|
const endNode = currentNode.next;
|
|
961
981
|
if (endNode.type === NodeType.TAIL) {
|
|
962
982
|
break;
|
|
963
983
|
}
|
|
984
|
+
if (!TC.gt(endNode.time, currentNode.time)) {
|
|
985
|
+
err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${this.id}, ${currentNode.time}`).warn();
|
|
986
|
+
}
|
|
964
987
|
if (TC.ne(lastEnd.time, currentNode.time)) {
|
|
965
988
|
err.EVENT_NODE_NOT_DENSE(`${this.id}, ${currentNode.time}`).warn();
|
|
966
989
|
}
|
|
967
990
|
currentNode = currentNode.next.next;
|
|
991
|
+
lastEnd = endNode;
|
|
968
992
|
}
|
|
969
993
|
}
|
|
970
994
|
hasReferenceTo(this: EventNodeSequence<number>, seq: EventNodeSequence<number>) {
|
package/index.d.ts
CHANGED
|
@@ -1697,7 +1697,7 @@ declare module "easing" {
|
|
|
1697
1697
|
}
|
|
1698
1698
|
declare module "chart" {
|
|
1699
1699
|
import { TimeCalculator } from "bpm";
|
|
1700
|
-
import { Easing, TemplateEasingLib } from "easing";
|
|
1700
|
+
import { Easing, SegmentedEasing, TemplateEasing, TemplateEasingLib } from "easing";
|
|
1701
1701
|
import { EventNodeSequence, EventStartNode, EventEndNode, EventNode } from "event";
|
|
1702
1702
|
import { JudgeLine } from "judgeline";
|
|
1703
1703
|
import { NNNList, NNNode } from "note";
|
|
@@ -1765,6 +1765,12 @@ declare module "chart" {
|
|
|
1765
1765
|
nameAttach: JudgeLine | null;
|
|
1766
1766
|
/** 难度等级显示绑定的判定线 */
|
|
1767
1767
|
levelAttach: JudgeLine | null;
|
|
1768
|
+
/** 仅用于构造时检查
|
|
1769
|
+
* @internal
|
|
1770
|
+
*/
|
|
1771
|
+
segmentedTemplates: Map<(SegmentedEasing & {
|
|
1772
|
+
easing: TemplateEasing;
|
|
1773
|
+
}), [string, TimeT]>;
|
|
1768
1774
|
constructor();
|
|
1769
1775
|
/**
|
|
1770
1776
|
* 获取有效节拍数
|
|
@@ -1898,6 +1904,11 @@ declare module "chart" {
|
|
|
1898
1904
|
bindTimeMacro(node: EventStartNode<any>, macroData: MacroData, pos: string): any;
|
|
1899
1905
|
bindValueMacro(node: EventNode<any>, macroData: MacroData, pos: string): any;
|
|
1900
1906
|
linkMacro(node: EventNode<EventValueESType>, linkData: MacroLink, pos: string): any;
|
|
1907
|
+
checkErrors(): void;
|
|
1908
|
+
/**
|
|
1909
|
+
* 用于构造谱面时检查
|
|
1910
|
+
*/
|
|
1911
|
+
protected checkSegmentedTemplates(): void;
|
|
1901
1912
|
}
|
|
1902
1913
|
/**
|
|
1903
1914
|
* 表示一组判定线的容器
|
|
@@ -2262,6 +2273,7 @@ declare module "env" {
|
|
|
2262
2273
|
NODES_NOT_BELONG_TO_SAME_SEQUENCE = 2610,
|
|
2263
2274
|
NODES_HAS_ZERO_DELTA = 2611,
|
|
2264
2275
|
TEMPLATE_EASING_CIRCULAR_REFERENCE = 2612,
|
|
2276
|
+
EASING_DELTA_CANNOT_BE_ZERO = 2613,
|
|
2265
2277
|
CANNOT_DIVIDE_EXPRESSION_EVALUATOR = 2352,
|
|
2266
2278
|
MISSING_MACRO_EVALUATOR_KEY = 2336,
|
|
2267
2279
|
MACRO_EVALUATOR_NOT_FOUND = 2337,
|
|
@@ -2313,6 +2325,7 @@ declare module "env" {
|
|
|
2313
2325
|
EVENT_NODE_NOT_DENSE: (pos: string) => string;
|
|
2314
2326
|
HOLD_HAS_NO_DURATION: () => string;
|
|
2315
2327
|
TEMPLATE_EASING_CIRCULAR_REFERENCE: (temEasName: string) => string;
|
|
2328
|
+
EASING_DELTA_CANNOT_BE_ZERO: (seqName: string, time: TimeT) => string;
|
|
2316
2329
|
};
|
|
2317
2330
|
interface ErrorMap extends Record<keyof typeof ERROR_IDS, Array<any>> {
|
|
2318
2331
|
EVENT_NODE_NOT_DENSE: [EventNode];
|
|
@@ -2379,6 +2392,7 @@ declare module "env" {
|
|
|
2379
2392
|
EVENT_NODE_NOT_DENSE: (pos: string) => KPAError<ERROR_IDS.EVENT_NODE_NOT_DENSE>;
|
|
2380
2393
|
HOLD_HAS_NO_DURATION: () => KPAError<ERROR_IDS.HOLD_HAS_NO_DURATION>;
|
|
2381
2394
|
TEMPLATE_EASING_CIRCULAR_REFERENCE: (temEasName: string) => KPAError<ERROR_IDS.TEMPLATE_EASING_CIRCULAR_REFERENCE>;
|
|
2395
|
+
EASING_DELTA_CANNOT_BE_ZERO: (seqName: string, time: TimeT) => KPAError<ERROR_IDS.EASING_DELTA_CANNOT_BE_ZERO>;
|
|
2382
2396
|
};
|
|
2383
2397
|
freeze(): void;
|
|
2384
2398
|
};
|
package/index.js
CHANGED
|
@@ -79,6 +79,7 @@ var ERROR_IDS;
|
|
|
79
79
|
ERROR_IDS2[ERROR_IDS2["NODES_NOT_BELONG_TO_SAME_SEQUENCE"] = EASING | INVALID_USAGE | 2] = "NODES_NOT_BELONG_TO_SAME_SEQUENCE";
|
|
80
80
|
ERROR_IDS2[ERROR_IDS2["NODES_HAS_ZERO_DELTA"] = EASING | INVALID_USAGE | 3] = "NODES_HAS_ZERO_DELTA";
|
|
81
81
|
ERROR_IDS2[ERROR_IDS2["TEMPLATE_EASING_CIRCULAR_REFERENCE"] = EASING | INVALID_USAGE | 4] = "TEMPLATE_EASING_CIRCULAR_REFERENCE";
|
|
82
|
+
ERROR_IDS2[ERROR_IDS2["EASING_DELTA_CANNOT_BE_ZERO"] = EASING | INVALID_USAGE | 5] = "EASING_DELTA_CANNOT_BE_ZERO";
|
|
82
83
|
ERROR_IDS2[ERROR_IDS2["CANNOT_DIVIDE_EXPRESSION_EVALUATOR"] = EVALUATOR | INVALID_USAGE | 0] = "CANNOT_DIVIDE_EXPRESSION_EVALUATOR";
|
|
83
84
|
ERROR_IDS2[ERROR_IDS2["MISSING_MACRO_EVALUATOR_KEY"] = EVALUATOR | INVALID_DATA | 0] = "MISSING_MACRO_EVALUATOR_KEY";
|
|
84
85
|
ERROR_IDS2[ERROR_IDS2["MACRO_EVALUATOR_NOT_FOUND"] = EVALUATOR | INVALID_DATA | 1] = "MACRO_EVALUATOR_NOT_FOUND";
|
|
@@ -129,7 +130,8 @@ var ERRORS = {
|
|
|
129
130
|
MACRO_NOT_PARAMETRIC: (macroId, pos) => `Macro '${macroId}' is not parametric. At ${pos}`,
|
|
130
131
|
EVENT_NODE_NOT_DENSE: (pos) => `EventNode is not dense. At ${pos}`,
|
|
131
132
|
HOLD_HAS_NO_DURATION: () => `Hold should have a duration.`,
|
|
132
|
-
TEMPLATE_EASING_CIRCULAR_REFERENCE: (temEasName) => `Template Easing '${temEasName}' has circular reference
|
|
133
|
+
TEMPLATE_EASING_CIRCULAR_REFERENCE: (temEasName) => `Template Easing '${temEasName}' has circular reference`,
|
|
134
|
+
EASING_DELTA_CANNOT_BE_ZERO: (seqName, time) => `Easing delta cannot be zero. (at ${seqName}, ${toTimeString(time)}`
|
|
133
135
|
};
|
|
134
136
|
|
|
135
137
|
class KPAError extends Error {
|
|
@@ -1771,6 +1773,10 @@ class EventNodeSequence {
|
|
|
1771
1773
|
for (let index = 0;index < length; index++) {
|
|
1772
1774
|
const event = data[index];
|
|
1773
1775
|
const [start, end] = chart.createEventFromData(event, valueType, `${pos}.events[${index}]`);
|
|
1776
|
+
const evaluator = start.evaluator;
|
|
1777
|
+
if (evaluator instanceof EasedEvaluator && evaluator.easing instanceof SegmentedEasing && evaluator.easing.easing instanceof TemplateEasing) {
|
|
1778
|
+
chart.segmentedTemplates.set(evaluator.easing, [pos, start.time]);
|
|
1779
|
+
}
|
|
1774
1780
|
if (TC2.lt(event.startTime, lastEndTime)) {
|
|
1775
1781
|
err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}] and the previous`).warn();
|
|
1776
1782
|
}
|
|
@@ -2011,15 +2017,33 @@ class EventNodeSequence {
|
|
|
2011
2017
|
return;
|
|
2012
2018
|
}
|
|
2013
2019
|
let lastEnd = endNode;
|
|
2020
|
+
currentNode = endNode.next;
|
|
2014
2021
|
while (true) {
|
|
2022
|
+
const evaluator = currentNode.evaluator;
|
|
2023
|
+
if (this.type === 5 /* easing */ && evaluator instanceof EasedEvaluator && evaluator.easing instanceof TemplateEasing) {
|
|
2024
|
+
if (TemplateEasing.checkCircularReference(this, evaluator.easing)) {
|
|
2025
|
+
err.TEMPLATE_EASING_CIRCULAR_REFERENCE(this.id).warn();
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
if (evaluator instanceof EasedEvaluator && evaluator.easing instanceof SegmentedEasing) {
|
|
2029
|
+
const easing = evaluator.easing;
|
|
2030
|
+
const inner = easing.easing;
|
|
2031
|
+
if (inner.getValue(easing.left) === inner.getValue(easing.right)) {
|
|
2032
|
+
err.EASING_DELTA_CANNOT_BE_ZERO(this.id, currentNode.time).warn();
|
|
2033
|
+
}
|
|
2034
|
+
}
|
|
2015
2035
|
const endNode2 = currentNode.next;
|
|
2016
2036
|
if (endNode2.type === 1 /* TAIL */) {
|
|
2017
2037
|
break;
|
|
2018
2038
|
}
|
|
2039
|
+
if (!TC2.gt(endNode2.time, currentNode.time)) {
|
|
2040
|
+
err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${this.id}, ${currentNode.time}`).warn();
|
|
2041
|
+
}
|
|
2019
2042
|
if (TC2.ne(lastEnd.time, currentNode.time)) {
|
|
2020
2043
|
err.EVENT_NODE_NOT_DENSE(`${this.id}, ${currentNode.time}`).warn();
|
|
2021
2044
|
}
|
|
2022
2045
|
currentNode = currentNode.next.next;
|
|
2046
|
+
lastEnd = endNode2;
|
|
2023
2047
|
}
|
|
2024
2048
|
}
|
|
2025
2049
|
hasReferenceTo(seq) {
|
|
@@ -2137,8 +2161,8 @@ class Note {
|
|
|
2137
2161
|
visibleTime,
|
|
2138
2162
|
yOffset: this.yOffset / this.speed,
|
|
2139
2163
|
speed: this.speed,
|
|
2140
|
-
tint: this.tint !== undefined ? hex2rgb(this.tint) : undefined,
|
|
2141
|
-
tintHitEffects: this.
|
|
2164
|
+
tint: this.tint !== undefined && this.tint !== 16777215 ? hex2rgb(this.tint) : undefined,
|
|
2165
|
+
tintHitEffects: this.tintHitEffects !== undefined && this.tintHitEffects !== 16777215 ? hex2rgb(this.tintHitEffects) : undefined,
|
|
2142
2166
|
judgeArea: this.judgeSize
|
|
2143
2167
|
};
|
|
2144
2168
|
}
|
|
@@ -2156,8 +2180,8 @@ class Note {
|
|
|
2156
2180
|
yOffset: this.yOffset / this.speed,
|
|
2157
2181
|
absoluteYOffset: this.yOffset,
|
|
2158
2182
|
speed: this.speed,
|
|
2159
|
-
tint: this.tint !== undefined ? hex2rgb(this.tint) : undefined,
|
|
2160
|
-
tintHitEffects: this.
|
|
2183
|
+
tint: this.tint !== undefined && this.tint !== 16777215 ? hex2rgb(this.tint) : undefined,
|
|
2184
|
+
tintHitEffects: this.tintHitEffects !== undefined && this.tintHitEffects !== 16777215 ? hex2rgb(this.tintHitEffects) : undefined,
|
|
2161
2185
|
judgeSize: this.judgeSize && this.judgeSize !== 1 ? this.judgeSize : undefined
|
|
2162
2186
|
};
|
|
2163
2187
|
}
|
|
@@ -3327,6 +3351,7 @@ class Chart {
|
|
|
3327
3351
|
scoreAttach = null;
|
|
3328
3352
|
nameAttach = null;
|
|
3329
3353
|
levelAttach = null;
|
|
3354
|
+
segmentedTemplates = new Map;
|
|
3330
3355
|
constructor() {}
|
|
3331
3356
|
getEffectiveBeats() {
|
|
3332
3357
|
const effectiveBeats = this.timeCalculator.secondsToBeats(this.duration);
|
|
@@ -3418,6 +3443,9 @@ class Chart {
|
|
|
3418
3443
|
for (let i = 0;i < len; i++) {
|
|
3419
3444
|
const easingData = templateEasings[i];
|
|
3420
3445
|
const sequence = chart.sequenceMap.get(easingData.content);
|
|
3446
|
+
if (!sequence) {
|
|
3447
|
+
continue;
|
|
3448
|
+
}
|
|
3421
3449
|
if (sequence.type !== 5 /* easing */) {
|
|
3422
3450
|
throw err.CANNOT_IMPLEMENT_TEMEAS_WITH_NON_EASING_ENS(easingData.name);
|
|
3423
3451
|
}
|
|
@@ -3434,6 +3462,7 @@ class Chart {
|
|
|
3434
3462
|
}
|
|
3435
3463
|
}
|
|
3436
3464
|
chart.templateEasingLib.check();
|
|
3465
|
+
chart.checkSegmentedTemplates();
|
|
3437
3466
|
for (const lineData of data.orphanLines) {
|
|
3438
3467
|
const line = JudgeLine.fromKPAJSON(data.version, chart, lineData.id, lineData, chart.templateEasingLib, chart.timeCalculator);
|
|
3439
3468
|
chart.orphanLines.push(line);
|
|
@@ -3729,6 +3758,21 @@ class Chart {
|
|
|
3729
3758
|
}
|
|
3730
3759
|
return null;
|
|
3731
3760
|
}
|
|
3761
|
+
checkErrors() {
|
|
3762
|
+
KPAError.flush();
|
|
3763
|
+
for (const [_, seq] of this.sequenceMap) {
|
|
3764
|
+
seq.checkErrors();
|
|
3765
|
+
}
|
|
3766
|
+
}
|
|
3767
|
+
checkSegmentedTemplates() {
|
|
3768
|
+
for (const [easing, [pos, time]] of this.segmentedTemplates) {
|
|
3769
|
+
const inner = easing.easing;
|
|
3770
|
+
if (inner.getValue(easing.left) === inner.getValue(easing.right)) {
|
|
3771
|
+
err.EASING_DELTA_CANNOT_BE_ZERO(pos, time).warn();
|
|
3772
|
+
}
|
|
3773
|
+
}
|
|
3774
|
+
this.segmentedTemplates.clear();
|
|
3775
|
+
}
|
|
3732
3776
|
}
|
|
3733
3777
|
|
|
3734
3778
|
class JudgeLineGroup {
|
package/note.ts
CHANGED
|
@@ -168,8 +168,8 @@ export class Note {
|
|
|
168
168
|
visibleTime: visibleTime,
|
|
169
169
|
yOffset: this.yOffset / this.speed,
|
|
170
170
|
speed: this.speed,
|
|
171
|
-
tint: this.tint !== undefined ? hex2rgb(this.tint) : undefined,
|
|
172
|
-
tintHitEffects: this.
|
|
171
|
+
tint: this.tint !== undefined && this.tint !== 0xffffff ? hex2rgb(this.tint) : undefined,
|
|
172
|
+
tintHitEffects: this.tintHitEffects !== undefined && this.tintHitEffects !== 0xffffff ? hex2rgb(this.tintHitEffects) : undefined,
|
|
173
173
|
judgeArea: this.judgeSize
|
|
174
174
|
}
|
|
175
175
|
}
|
|
@@ -189,8 +189,8 @@ export class Note {
|
|
|
189
189
|
/** 但是有历史包袱,所以加字段 */
|
|
190
190
|
absoluteYOffset: this.yOffset,
|
|
191
191
|
speed: this.speed,
|
|
192
|
-
tint: this.tint !== undefined ? hex2rgb(this.tint) : undefined,
|
|
193
|
-
tintHitEffects: this.
|
|
192
|
+
tint: this.tint !== undefined && this.tint !== 0xffffff ? hex2rgb(this.tint) : undefined,
|
|
193
|
+
tintHitEffects: this.tintHitEffects !== undefined && this.tintHitEffects !== 0xffffff ? hex2rgb(this.tintHitEffects) : undefined,
|
|
194
194
|
judgeSize: this.judgeSize && this.judgeSize !== 1.0 ? this.judgeSize : undefined,
|
|
195
195
|
}
|
|
196
196
|
}
|
package/operation/easy.ts
CHANGED
|
@@ -35,20 +35,21 @@ class Operable {
|
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
class OperableNote extends Operable {
|
|
38
|
-
|
|
39
|
-
private
|
|
40
|
-
|
|
38
|
+
// @ts-expect-error 后面会赋值
|
|
39
|
+
private _fields: {
|
|
40
|
+
[x in NotePropName]: Note[x]
|
|
41
|
+
} = {};
|
|
41
42
|
constructor(public target: Note, buffer: Operation[]) {
|
|
42
43
|
super(buffer);
|
|
43
44
|
if (target.parentNode === null) {
|
|
44
45
|
throw new Error("Note has no parent node")
|
|
45
46
|
}
|
|
46
|
-
this.
|
|
47
|
-
this.
|
|
48
|
-
this.
|
|
47
|
+
this._fields.startTime = target.startTime;
|
|
48
|
+
this._fields.endTime = target.endTime;
|
|
49
|
+
this._fields.type = target.type;
|
|
49
50
|
}
|
|
50
51
|
get startTime() {
|
|
51
|
-
return this.
|
|
52
|
+
return this._fields.startTime;
|
|
52
53
|
}
|
|
53
54
|
set startTime(userTime: Time) {
|
|
54
55
|
const timeT = userTimeToTuple(userTime);
|
|
@@ -60,28 +61,28 @@ class OperableNote extends Operable {
|
|
|
60
61
|
if (beats > nnList.effectiveBeats) {
|
|
61
62
|
throw new Error("")
|
|
62
63
|
}
|
|
63
|
-
this.
|
|
64
|
+
this._fields.startTime = timeT;
|
|
64
65
|
const node = nnList.getNodeOf(timeT);
|
|
65
66
|
this.buffer.push(NoteTimeChangeOperation.lazy(this.target, node));
|
|
66
67
|
}
|
|
67
|
-
get endTime() { return this.
|
|
68
|
+
get endTime() { return this._fields.endTime; }
|
|
68
69
|
set endTime(userTime: Time) {
|
|
69
|
-
if (this.
|
|
70
|
+
if (this._fields.type !== NoteType.hold) {
|
|
70
71
|
throw new Error("Note is not a hold note");
|
|
71
72
|
}
|
|
72
73
|
const timeT = userTimeToTuple(userTime);
|
|
73
|
-
if (!TC.gt(timeT, this.
|
|
74
|
+
if (!TC.gt(timeT, this._fields.startTime)) {
|
|
74
75
|
throw new Error("");
|
|
75
76
|
}
|
|
76
|
-
this.
|
|
77
|
+
this._fields.endTime = timeT;
|
|
77
78
|
this.buffer.push(HoldEndTimeChangeOperation.lazy(this.target, timeT));
|
|
78
79
|
}
|
|
79
|
-
get type() { return this.
|
|
80
|
+
get type() { return this._fields.type; }
|
|
80
81
|
set type(type: NoteType) {
|
|
81
|
-
if (this.
|
|
82
|
+
if (this._fields.type === type) {
|
|
82
83
|
return;
|
|
83
84
|
}
|
|
84
|
-
this.
|
|
85
|
+
this._fields.type = type;
|
|
85
86
|
this.buffer.push(NoteTypeChangeOperation.lazy(this.target, type));
|
|
86
87
|
}
|
|
87
88
|
}
|
|
@@ -109,8 +110,12 @@ interface OperableNote {
|
|
|
109
110
|
|
|
110
111
|
for (const propName of ["above", "alpha", "positionX", "judgeSize", "isFake", "size", "tint", "tintHitEffects", "visibleBeats"] satisfies NotePropName[]) {
|
|
111
112
|
Object.defineProperty(OperableNote.prototype, propName, {
|
|
112
|
-
get() { return this.target[propName]},
|
|
113
|
+
get() { return this._fields[propName] ?? this.target[propName]},
|
|
113
114
|
set(value) {
|
|
115
|
+
if (this._fields[propName] === value) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
this._fields[propName] = value;
|
|
114
119
|
this.buffer.push(NotePropChangeOperation.lazy(this.target, propName, value));
|
|
115
120
|
}
|
|
116
121
|
});
|
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-beta.
|
|
4
|
+
"version": "2.1.3-beta.2",
|
|
5
5
|
"author": "Team Zincs (https://github.com/TeamZincs)",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|