kipphi 2.0.1 → 2.1.0
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/README.md +1 -3
- package/basic.ts +285 -0
- package/bpm.ts +133 -14
- package/chart.ts +272 -52
- package/chartType.schema.json +584 -0
- package/chartType2.schema.json +1107 -0
- package/chartTypes.ts +70 -11
- package/easing.ts +37 -8
- package/env.ts +36 -1
- package/evaluator.ts +72 -10
- package/event.ts +97 -43
- package/index.d.ts +3055 -0
- package/index.js +5530 -0
- package/index.ts +5 -2
- package/judgeline.ts +25 -21
- package/jumparray.ts +0 -1
- package/line.ts +246 -0
- package/macro.ts +215 -0
- package/note.ts +1 -1
- package/operation/basic.ts +285 -0
- package/operation/chart.ts +21 -0
- package/operation/event.ts +511 -0
- package/operation/index.ts +6 -0
- package/operation/line.ts +304 -0
- package/operation/macro.ts +60 -0
- package/operation/note.ts +457 -0
- package/package.json +7 -1
- package/tsconfig.json +1 -1
- package/version.ts +2 -1
- package/operation.ts +0 -1378
package/event.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Chart } from "./chart";
|
|
2
|
-
import { EventType, type TimeT, type EventDataKPA, type RGB, type EventDataRPELike, InterpreteAs, type ValueTypeOfEventType, type EventNodeSequenceDataKPA, type EventDataKPA2, type EventNodeSequenceDataKPA2, type EventValueESType, EventValueType, EventValueTypeOfType } from "./chartTypes";
|
|
2
|
+
import { EventType, type TimeT, type EventDataKPA, type RGB, type EventDataRPELike, InterpreteAs, type ValueTypeOfEventType, type EventNodeSequenceDataKPA, type EventDataKPA2, type EventNodeSequenceDataKPA2, type EventValueESType, EventValueType, EventValueTypeOfType, FinalEventStartNodeDataKPA2, EvaluatorType, EasingType } from "./chartTypes";
|
|
3
3
|
import { TemplateEasingLib, BezierEasing, Easing, rpeEasingArray, SegmentedEasing, linearEasing, fixedEasing, TemplateEasing, NormalEasing } from "./easing";
|
|
4
4
|
import { ColorEasedEvaluator, EasedEvaluator, ExpressionEvaluator, NumericEasedEvaluator, TextEasedEvaluator, type Evaluator } from "./evaluator";
|
|
5
5
|
import { JumpArray } from "./jumparray";
|
|
@@ -10,9 +10,10 @@ import { NodeType } from "./util";
|
|
|
10
10
|
|
|
11
11
|
import { err, ERROR_IDS, KPAError } from "./env";
|
|
12
12
|
import { JudgeLine } from "./judgeline";
|
|
13
|
+
import { EventMacro, EventMacroTime, EventMacroValue, Macroable } from "./macro";
|
|
13
14
|
|
|
14
15
|
/// #declaration:global
|
|
15
|
-
export class EventNodeLike<T extends NodeType, VT = number> {
|
|
16
|
+
export class EventNodeLike<T extends NodeType, VT extends EventValueESType = number> {
|
|
16
17
|
type: T;
|
|
17
18
|
/** 后一个事件节点 */
|
|
18
19
|
next: [EventStartNode<VT>, null, ENOrTail<VT>][T] | null = null;
|
|
@@ -23,10 +24,10 @@ export class EventNodeLike<T extends NodeType, VT = number> {
|
|
|
23
24
|
this.type = type;
|
|
24
25
|
}
|
|
25
26
|
}
|
|
26
|
-
export type ENOrTail<VT = number> = EventNode<VT> | EventNodeLike<NodeType.TAIL, VT>;
|
|
27
|
-
export type ENOrHead<VT = number> = EventNode<VT> | EventNodeLike<NodeType.HEAD, VT>;
|
|
28
|
-
export type AnyEN<VT = number> = EventNode<VT> | EventNodeLike<NodeType.HEAD, VT> | EventNodeLike<NodeType.TAIL, VT>;
|
|
29
|
-
export type EvSoE<VT = number> = EventEndNode<VT> | EventStartNode<VT>;
|
|
27
|
+
export type ENOrTail<VT extends EventValueESType = number> = EventNode<VT> | EventNodeLike<NodeType.TAIL, VT>;
|
|
28
|
+
export type ENOrHead<VT extends EventValueESType = number> = EventNode<VT> | EventNodeLike<NodeType.HEAD, VT>;
|
|
29
|
+
export type AnyEN<VT extends EventValueESType = number> = EventNode<VT> | EventNodeLike<NodeType.HEAD, VT> | EventNodeLike<NodeType.TAIL, VT>;
|
|
30
|
+
export type EvSoE<VT extends EventValueESType = number> = EventEndNode<VT> | EventStartNode<VT>;
|
|
30
31
|
|
|
31
32
|
/**
|
|
32
33
|
* 事件节点基类
|
|
@@ -43,10 +44,12 @@ export type EvSoE<VT = number> = EventEndNode<VT> | EventStartNode<VT>;
|
|
|
43
44
|
* 与RPE不同的是,KPA使用两个节点来表示一个事件,而不是一个对象。
|
|
44
45
|
* Different from that in RPE, KPA uses two nodes rather than one object to represent an event.
|
|
45
46
|
*/
|
|
46
|
-
export abstract class EventNode<VT = number> extends EventNodeLike<NodeType.MIDDLE, VT> {
|
|
47
|
+
export abstract class EventNode<VT extends EventValueESType = number> extends EventNodeLike<NodeType.MIDDLE, VT> {
|
|
47
48
|
time: TimeT;
|
|
48
49
|
value: VT;
|
|
49
50
|
evaluator: Evaluator<VT>;
|
|
51
|
+
macroValue: EventMacroValue;
|
|
52
|
+
linkedMacros: Set<EventMacro<Macroable>> = new Set();
|
|
50
53
|
constructor(time: TimeT, value: VT) {
|
|
51
54
|
super(NodeType.MIDDLE);
|
|
52
55
|
this.time = TC.validateIp([...time]);
|
|
@@ -106,12 +109,11 @@ export abstract class EventNode<VT = number> extends EventNodeLike<NodeType.MIDD
|
|
|
106
109
|
const right = data.easingRight;
|
|
107
110
|
const wrap = (easing: Easing): EasedEvaluator<VT> => {
|
|
108
111
|
if (typeof data.start === "number") {
|
|
109
|
-
return new NumericEasedEvaluator(easing) as EasedEvaluator<VT>;
|
|
112
|
+
return new NumericEasedEvaluator(easing) as unknown as EasedEvaluator<VT>;
|
|
110
113
|
} else if (typeof data.start === "string") {
|
|
111
|
-
|
|
112
|
-
return new TextEasedEvaluator(easing, interpreteAs);
|
|
114
|
+
return new TextEasedEvaluator(easing, interpreteAs) as unknown as EasedEvaluator<VT>;
|
|
113
115
|
} else {
|
|
114
|
-
return new ColorEasedEvaluator(easing) as EasedEvaluator<VT>;
|
|
116
|
+
return new ColorEasedEvaluator(easing) as unknown as EasedEvaluator<VT>;
|
|
115
117
|
}
|
|
116
118
|
};
|
|
117
119
|
if ((left && right) && (left !== 0.0 || right !== 1.0)) {
|
|
@@ -173,9 +175,9 @@ export abstract class EventNode<VT = number> extends EventNodeLike<NodeType.MIDD
|
|
|
173
175
|
EventNode.connect(start, end)
|
|
174
176
|
return [start, end]
|
|
175
177
|
}
|
|
176
|
-
static connect<VT>(node1: EventStartNode<VT>, node2: EventEndNode<VT> | EventNodeLike<NodeType.TAIL, VT>): void
|
|
177
|
-
static connect<VT>(node1: EventEndNode<VT> | EventNodeLike<NodeType.HEAD, VT>, node2: EventStartNode<VT>): void
|
|
178
|
-
static connect<VT>(node1: ENOrHead<VT>, node2: ENOrTail<VT>): void {
|
|
178
|
+
static connect<VT extends EventValueESType>(node1: EventStartNode<VT>, node2: EventEndNode<VT> | EventNodeLike<NodeType.TAIL, VT>): void
|
|
179
|
+
static connect<VT extends EventValueESType>(node1: EventEndNode<VT> | EventNodeLike<NodeType.HEAD, VT>, node2: EventStartNode<VT>): void
|
|
180
|
+
static connect<VT extends EventValueESType>(node1: ENOrHead<VT>, node2: ENOrTail<VT>): void {
|
|
179
181
|
node1.next = node2;
|
|
180
182
|
node2.previous = node1;
|
|
181
183
|
if (node1 && node2) {
|
|
@@ -188,7 +190,7 @@ export abstract class EventNode<VT = number> extends EventNodeLike<NodeType.MIDD
|
|
|
188
190
|
* @param startNode
|
|
189
191
|
* @returns 应该在何范围内更新跳数组
|
|
190
192
|
*/
|
|
191
|
-
static removeNodePair<VT>(endNode: EventEndNode<VT>, startNode: EventStartNode<VT>): [EventStartNode<VT> | EventNodeLike<NodeType.HEAD, VT>, EventStartNode<VT> | EventNodeLike<NodeType.TAIL,VT>] {
|
|
193
|
+
static removeNodePair<VT extends EventValueESType>(endNode: EventEndNode<VT>, startNode: EventStartNode<VT>): [EventStartNode<VT> | EventNodeLike<NodeType.HEAD, VT>, EventStartNode<VT> | EventNodeLike<NodeType.TAIL,VT>] {
|
|
192
194
|
const prev = endNode.previous;
|
|
193
195
|
const next = startNode.next;
|
|
194
196
|
prev.next = next;
|
|
@@ -199,7 +201,7 @@ export abstract class EventNode<VT = number> extends EventNodeLike<NodeType.MIDD
|
|
|
199
201
|
startNode.parentSeq = null; // 每亩的东西(
|
|
200
202
|
return [this.previousStartOfStart(prev), this.nextStartOfEnd(next)]
|
|
201
203
|
}
|
|
202
|
-
static insert<VT>(node: EventStartNode<VT>, tarPrev: EventStartNode<VT>): [EventNodeLike<NodeType.HEAD, VT> | EventStartNode<VT>, EventStartNode<VT> | EventNodeLike<NodeType.TAIL, VT>] {
|
|
204
|
+
static insert<VT extends EventValueESType>(node: EventStartNode<VT>, tarPrev: EventStartNode<VT>): [EventNodeLike<NodeType.HEAD, VT> | EventStartNode<VT>, EventStartNode<VT> | EventNodeLike<NodeType.TAIL, VT>] {
|
|
203
205
|
const tarNext = tarPrev.next;
|
|
204
206
|
if (node.previous.type === NodeType.HEAD) {
|
|
205
207
|
throw err.CANNOT_INSERT_BEFORE_HEAD();
|
|
@@ -214,7 +216,7 @@ export abstract class EventNode<VT = number> extends EventNodeLike<NodeType.MIDD
|
|
|
214
216
|
* @param node
|
|
215
217
|
* @returns the next node if it is a tailer, otherwise the next start node
|
|
216
218
|
*/
|
|
217
|
-
static nextStartOfStart<VT>(node: EventStartNode<VT>) {
|
|
219
|
+
static nextStartOfStart<VT extends EventValueESType>(node: EventStartNode<VT>) {
|
|
218
220
|
return node.next.type === NodeType.TAIL ? node.next : node.next.next
|
|
219
221
|
}
|
|
220
222
|
/**
|
|
@@ -222,10 +224,10 @@ export abstract class EventNode<VT = number> extends EventNodeLike<NodeType.MIDD
|
|
|
222
224
|
* @param node
|
|
223
225
|
* @returns itself if node is a tailer, otherwise the next start node
|
|
224
226
|
*/
|
|
225
|
-
static nextStartOfEnd<VT>(node: EventEndNode<VT> | EventNodeLike<NodeType.TAIL, VT>) {
|
|
227
|
+
static nextStartOfEnd<VT extends EventValueESType>(node: EventEndNode<VT> | EventNodeLike<NodeType.TAIL, VT>) {
|
|
226
228
|
return node.type === NodeType.TAIL ? node : node.next
|
|
227
229
|
}
|
|
228
|
-
static previousStartOfStart<VT>(node: EventStartNode<VT>): EventStartNode<VT> | EventNodeLike<NodeType.HEAD, VT> {
|
|
230
|
+
static previousStartOfStart<VT extends EventValueESType>(node: EventStartNode<VT>): EventStartNode<VT> | EventNodeLike<NodeType.HEAD, VT> {
|
|
229
231
|
return node.previous.type === NodeType.HEAD ? node.previous : node.previous.previous;
|
|
230
232
|
}
|
|
231
233
|
/**
|
|
@@ -233,10 +235,10 @@ export abstract class EventNode<VT = number> extends EventNodeLike<NodeType.MIDD
|
|
|
233
235
|
* @param node
|
|
234
236
|
* @returns
|
|
235
237
|
*/
|
|
236
|
-
static secondPreviousStartOfEnd<VT>(node: EventEndNode<VT>): EventStartNode<VT> | EventNodeLike<NodeType.HEAD, VT> {
|
|
238
|
+
static secondPreviousStartOfEnd<VT extends EventValueESType>(node: EventEndNode<VT>): EventStartNode<VT> | EventNodeLike<NodeType.HEAD, VT> {
|
|
237
239
|
return this.previousStartOfStart(node.previous);
|
|
238
240
|
}
|
|
239
|
-
static nextStartInJumpArray<VT>(node: EventStartNode<VT>): EventStartNode<VT> | EventNodeLike<NodeType.TAIL, VT> {
|
|
241
|
+
static nextStartInJumpArray<VT extends EventValueESType>(node: EventStartNode<VT>): EventStartNode<VT> | EventNodeLike<NodeType.TAIL, VT> {
|
|
240
242
|
if ((node.next as EventEndNode<VT>).next.isLastStart()) {
|
|
241
243
|
return node.next.next.next as EventNodeLike<NodeType.TAIL, VT>;
|
|
242
244
|
} else {
|
|
@@ -248,7 +250,7 @@ export abstract class EventNode<VT = number> extends EventNodeLike<NodeType.MIDD
|
|
|
248
250
|
* @param node
|
|
249
251
|
* @returns
|
|
250
252
|
*/
|
|
251
|
-
static getEndStart<VT>(node: EventStartNode<VT> | EventEndNode<VT>): [EventEndNode<VT>, EventStartNode<VT>] {
|
|
253
|
+
static getEndStart<VT extends EventValueESType>(node: EventStartNode<VT> | EventEndNode<VT>): [EventEndNode<VT>, EventStartNode<VT>] {
|
|
252
254
|
if (node instanceof EventStartNode) {
|
|
253
255
|
if (node.isFirstStart()) {
|
|
254
256
|
throw new Error("Cannot get previous start node of the first start node");
|
|
@@ -258,7 +260,7 @@ export abstract class EventNode<VT = number> extends EventNodeLike<NodeType.MIDD
|
|
|
258
260
|
return [node, node.next]
|
|
259
261
|
}
|
|
260
262
|
}
|
|
261
|
-
static getStartEnd<VT>(node: EventStartNode<VT> | EventEndNode<VT>): [EventStartNode<VT>, EventEndNode<VT>] {
|
|
263
|
+
static getStartEnd<VT extends EventValueESType>(node: EventStartNode<VT> | EventEndNode<VT>): [EventStartNode<VT>, EventEndNode<VT>] {
|
|
262
264
|
if (node instanceof EventStartNode) {
|
|
263
265
|
return [node, <EventEndNode<VT>>node.next]
|
|
264
266
|
} else if (node instanceof EventEndNode) {
|
|
@@ -267,7 +269,7 @@ export abstract class EventNode<VT = number> extends EventNodeLike<NodeType.MIDD
|
|
|
267
269
|
throw new Error("unreachable");
|
|
268
270
|
}
|
|
269
271
|
}
|
|
270
|
-
static setToNewOrderedArray<VT>(dest: TimeT, set: Set<EventStartNode<VT>>): [EventStartNode<VT>[], EventStartNode<VT>[]] {
|
|
272
|
+
static setToNewOrderedArray<VT extends EventValueESType>(dest: TimeT, set: Set<EventStartNode<VT>>): [EventStartNode<VT>[], EventStartNode<VT>[]] {
|
|
271
273
|
const nodes = [...set]
|
|
272
274
|
nodes.sort((a, b) => TC.gt(a.time, b.time) ? 1 : -1);
|
|
273
275
|
const offset = TC.sub(dest, nodes[0].time)
|
|
@@ -302,9 +304,10 @@ export abstract class EventNode<VT = number> extends EventNodeLike<NodeType.MIDD
|
|
|
302
304
|
// #endregion
|
|
303
305
|
}
|
|
304
306
|
|
|
305
|
-
export class EventStartNode<VT = number> extends EventNode<VT> {
|
|
307
|
+
export class EventStartNode<VT extends EventValueESType = number> extends EventNode<VT> {
|
|
306
308
|
override next: EventEndNode<VT> | EventNodeLike<NodeType.TAIL, VT>;
|
|
307
309
|
override previous: EventEndNode<VT> | EventNodeLike<NodeType.HEAD, VT>;
|
|
310
|
+
macroTime: EventMacroTime | null = null;
|
|
308
311
|
/**
|
|
309
312
|
* 对于速度事件,从0时刻到此节点的总积分
|
|
310
313
|
*/
|
|
@@ -325,16 +328,32 @@ export class EventStartNode<VT = number> extends EventNode<VT> {
|
|
|
325
328
|
end: endNode.value,
|
|
326
329
|
startTime: this.time,
|
|
327
330
|
endTime: endNode.time,
|
|
328
|
-
evaluator: this.evaluator.
|
|
331
|
+
evaluator: this.evaluator.dumpFor(this),
|
|
332
|
+
macroStart: this.macroValue?.dumpForNode(this),
|
|
333
|
+
macroEnd: this.macroValue?.dumpForNode(endNode),
|
|
334
|
+
macroStartTime: this.macroTime?.dumpForNode(this),
|
|
335
|
+
// 没有macroEndTime
|
|
336
|
+
startLinkedMacro: [...this.linkedMacros].map(macro => macro.dumpLinkForNode(this)),
|
|
337
|
+
endLinkedMacro: [...endNode.linkedMacros].map(macro => macro.dumpLinkForNode(endNode))
|
|
329
338
|
}
|
|
330
339
|
}
|
|
340
|
+
dumpAsFinal(): FinalEventStartNodeDataKPA2<VT> {
|
|
341
|
+
return {
|
|
342
|
+
start: this.value,
|
|
343
|
+
startTime: this.time,
|
|
344
|
+
evaluator: this.evaluator.dumpFor(this),
|
|
345
|
+
macro: this.macroValue?.dumpForNode(this),
|
|
346
|
+
macroTime: this.macroTime?.dumpForNode(this),
|
|
347
|
+
linkedMacro: [...this.linkedMacros].map(macro => macro.dumpLinkForNode(this)),
|
|
348
|
+
}
|
|
349
|
+
}
|
|
331
350
|
getValueAt(beats: number): VT {
|
|
332
351
|
// 除了尾部的开始节点,其他都有下个节点
|
|
333
352
|
// 钩定型缓动也有
|
|
334
353
|
if (this.next.type === NodeType.TAIL) {
|
|
335
354
|
return this.value;
|
|
336
355
|
}
|
|
337
|
-
return this.evaluator.eval(this
|
|
356
|
+
return this.evaluator.eval(this as NonLastStartNode<VT>, beats);
|
|
338
357
|
}
|
|
339
358
|
getSpeedValueAt(this: EventStartNode<number>, beats: number) {
|
|
340
359
|
if (this.next.type === NodeType.TAIL) {
|
|
@@ -384,7 +403,7 @@ export class EventStartNode<VT = number> extends EventNode<VT> {
|
|
|
384
403
|
|
|
385
404
|
export type NonLastStartNode<VT extends EventValueESType> = EventStartNode<VT> & {next: EventEndNode<VT>}
|
|
386
405
|
|
|
387
|
-
export class EventEndNode<VT = number> extends EventNode<VT> {
|
|
406
|
+
export class EventEndNode<VT extends EventValueESType = number> extends EventNode<VT> {
|
|
388
407
|
override next!: EventStartNode<VT>;
|
|
389
408
|
override previous!: EventStartNode<VT>;
|
|
390
409
|
|
|
@@ -435,7 +454,7 @@ export enum Monotonicity {
|
|
|
435
454
|
* 插入或删除节点时,需要更新跳数组。
|
|
436
455
|
* Remember to update the jump array when inserting or deleting nodes.
|
|
437
456
|
*/
|
|
438
|
-
export class EventNodeSequence<VT = number> { // 泛型的传染性这一块
|
|
457
|
+
export class EventNodeSequence<VT extends EventValueESType = number> { // 泛型的传染性这一块
|
|
439
458
|
/**
|
|
440
459
|
* @deprecated 谱面属性未实装,以后有必要的时候会添加为其赋值的逻辑
|
|
441
460
|
*/
|
|
@@ -489,7 +508,18 @@ export class EventNodeSequence<VT = number> { // 泛型的传染性这一块
|
|
|
489
508
|
type === EventType.color ? [0, 0, 0] :
|
|
490
509
|
0
|
|
491
510
|
}
|
|
492
|
-
|
|
511
|
+
/**
|
|
512
|
+
* 从RPEJSON数据创建一个事件序列。
|
|
513
|
+
*
|
|
514
|
+
* KPAJSON 1.x也会使用此接口
|
|
515
|
+
* @param type 事件类型(不是数值类型,也不是数值ECMAScript类型)
|
|
516
|
+
* @param data 事件数据的数组
|
|
517
|
+
* @param chart
|
|
518
|
+
* @param pos 当前事件序列应当具有什么ID(用于报错和警告,外部调用可以写空字符串)
|
|
519
|
+
* @param endValue 结束值(RPEJSON没有)
|
|
520
|
+
* @returns
|
|
521
|
+
*/
|
|
522
|
+
static fromRPEJSON<T extends EventType, VT extends EventValueESType = number>(type: T, data: EventDataRPELike<VT>[], chart: Chart, pos: string, endValue?: number) {
|
|
493
523
|
const {templateEasingLib: templates} = chart
|
|
494
524
|
const length = data.length;
|
|
495
525
|
// const isSpeed = type === EventType.Speed;
|
|
@@ -507,6 +537,7 @@ export class EventNodeSequence<VT = number> { // 泛型的传染性这一块
|
|
|
507
537
|
lastEnd = end;
|
|
508
538
|
}
|
|
509
539
|
|
|
540
|
+
// 当前仅用于检查时间递增
|
|
510
541
|
let lastEndTime: TimeT = [0, 0, 1];
|
|
511
542
|
|
|
512
543
|
// 读取事件列表
|
|
@@ -551,7 +582,7 @@ export class EventNodeSequence<VT = number> { // 泛型的传染性这一块
|
|
|
551
582
|
const last = lastEnd;
|
|
552
583
|
const tail = new EventStartNode(
|
|
553
584
|
last.type === NodeType.HEAD ? [0, 0, 1] : last.time,
|
|
554
|
-
endValue ?? last.value
|
|
585
|
+
endValue ?? (last as EventEndNode<VT>).value
|
|
555
586
|
);
|
|
556
587
|
EventNode.connect(last, tail);
|
|
557
588
|
// last can be a header, in which case easing is undefined.
|
|
@@ -565,12 +596,21 @@ export class EventNodeSequence<VT = number> { // 泛型的传染性这一块
|
|
|
565
596
|
}
|
|
566
597
|
return seq;
|
|
567
598
|
}
|
|
599
|
+
/**
|
|
600
|
+
* 从KPAJSON 2.x数据创建一个事件序列。
|
|
601
|
+
* @param type 事件类型(不是数值类型,也不是数值ECMAScript类型)
|
|
602
|
+
* @param data 事件数据的数组
|
|
603
|
+
* @param chart
|
|
604
|
+
* @param pos 当前事件序列应当具有什么ID(用于报错和警告)
|
|
605
|
+
* @param finalNodeData 最终节点数据
|
|
606
|
+
* @returns
|
|
607
|
+
*/
|
|
568
608
|
static fromKPA2JSON<T extends EventType, VT extends EventValueESType = number>(
|
|
569
609
|
type: T,
|
|
570
610
|
data: EventDataKPA2<VT>[],
|
|
571
611
|
chart: Chart,
|
|
572
612
|
pos: string,
|
|
573
|
-
|
|
613
|
+
finalNodeData: FinalEventStartNodeDataKPA2<VT>
|
|
574
614
|
)
|
|
575
615
|
{
|
|
576
616
|
const length = data.length;
|
|
@@ -602,7 +642,7 @@ export class EventNodeSequence<VT = number> { // 泛型的传染性这一块
|
|
|
602
642
|
let lastEndTime: TimeT = [0, 0, 1];
|
|
603
643
|
for (let index = 0; index < length; index++) {
|
|
604
644
|
const event = data[index];
|
|
605
|
-
const [start, end] = chart.createEventFromData<VT>(event, valueType);
|
|
645
|
+
const [start, end] = chart.createEventFromData<VT>(event, valueType, `${pos}.events[${index}]`);
|
|
606
646
|
// 从前面复制了,复用性减一
|
|
607
647
|
// KPA2没有更改RPE的按事件存储的机制。
|
|
608
648
|
if (TC.lt(event.startTime, lastEndTime)) { // event.startTime < lastEndTime
|
|
@@ -638,15 +678,25 @@ export class EventNodeSequence<VT = number> { // 泛型的传染性这一块
|
|
|
638
678
|
lastEnd = end;
|
|
639
679
|
}
|
|
640
680
|
const last = lastEnd;
|
|
641
|
-
const
|
|
642
|
-
|
|
643
|
-
|
|
681
|
+
const final = chart.createFinalEventStartNodeFromData(
|
|
682
|
+
finalNodeData || {
|
|
683
|
+
// @ts-expect-error 简化写法
|
|
684
|
+
start: last.value ?? this.getDefaultValueFromEventType(type),
|
|
685
|
+
// @ts-expect-error 极其边缘情况,finalNodeData只有在内测的谱面里面才可能为null,且last一般都有值
|
|
686
|
+
startTime: last.time,
|
|
687
|
+
evaluator: {
|
|
688
|
+
type: EvaluatorType.eased,
|
|
689
|
+
easing: {
|
|
690
|
+
type: EasingType.normal,
|
|
691
|
+
identifier: linearEasing.rpeId
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
} satisfies FinalEventStartNodeDataKPA2<any>,
|
|
695
|
+
valueType,
|
|
696
|
+
pos + ".finalNode"
|
|
644
697
|
);
|
|
645
|
-
EventNode.connect(last,
|
|
646
|
-
|
|
647
|
-
// then we use the easing that initialized in the EventStartNode constructor.
|
|
648
|
-
tail.evaluator = last.previous?.evaluator ?? tail.evaluator;
|
|
649
|
-
EventNode.connect(tail, seq.tail)
|
|
698
|
+
EventNode.connect(last, final);
|
|
699
|
+
EventNode.connect(final, seq.tail)
|
|
650
700
|
seq.listLength = listLength;
|
|
651
701
|
seq.initJump();
|
|
652
702
|
if (type === EventType.speed) {
|
|
@@ -711,7 +761,7 @@ export class EventNodeSequence<VT = number> { // 泛型的传染性这一块
|
|
|
711
761
|
(node: EventStartNode<VT>, beats: number) => {
|
|
712
762
|
return TC.toBeats((node.next as EventEndNode<VT>).time) > beats ? false : EventNode.nextStartInJumpArray(node)
|
|
713
763
|
},
|
|
714
|
-
(node:
|
|
764
|
+
(node: AnyEN<VT>) => {
|
|
715
765
|
return node.next && node.next.type === NodeType.TAIL ? node.next : node;
|
|
716
766
|
}
|
|
717
767
|
/*(node: EventStartNode) => {
|
|
@@ -767,6 +817,10 @@ export class EventNodeSequence<VT = number> { // 泛型的传染性这一块
|
|
|
767
817
|
* @param this
|
|
768
818
|
* @param node
|
|
769
819
|
* @param tc
|
|
820
|
+
*
|
|
821
|
+
* @example
|
|
822
|
+
* node.value += 1;
|
|
823
|
+
* (node.parentSequence as SpeedENS).updateFloorPositionAfter(node, tc);
|
|
770
824
|
*/
|
|
771
825
|
updateFloorPositionAfter(this: SpeedENS, node: EventStartNode, tc: TimeCalculator): void {
|
|
772
826
|
let currentFP: number;
|
|
@@ -802,7 +856,7 @@ export class EventNodeSequence<VT = number> { // 泛型的传染性这一块
|
|
|
802
856
|
type: this.type,
|
|
803
857
|
events: nodes,
|
|
804
858
|
id: this.id,
|
|
805
|
-
|
|
859
|
+
final: currentNode.dumpAsFinal()
|
|
806
860
|
};
|
|
807
861
|
}
|
|
808
862
|
|