keystonemc 1.0.0 → 1.0.1
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/dist/core/event/eventManager.d.ts +33 -0
- package/dist/core/event/flow.d.ts +18 -0
- package/dist/core/event/priority.d.ts +8 -0
- package/dist/core/event/types.d.ts +6 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/keystone.d.ts +5 -0
- package/dist/core/math/vector3.d.ts +195 -0
- package/dist/core/timer/timer.d.ts +94 -0
- package/dist/core/utils/debugger.d.ts +1 -0
- package/dist/index.js +770 -0
- package/dist/vite-plugin/index.d.ts +11 -0
- package/dist/vite-plugin/index.js +120 -0
- package/package.json +1 -1
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { world } from '@minecraft/server';
|
|
2
|
+
import { Listener } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* AfterEventMap / BeforeEventMap を world.afterEvents / world.beforeEvents の
|
|
5
|
+
* subscribe のハンドラ引数から自動抽出する。
|
|
6
|
+
*
|
|
7
|
+
* 例: world.afterEvents.playerSpawn.subscribe((ev: PlayerSpawnAfterEvent) => {...})
|
|
8
|
+
* の ev の型を自動的に E として取り出す。
|
|
9
|
+
*/
|
|
10
|
+
type ExtractSubscribeArg<T> = T extends {
|
|
11
|
+
subscribe: (handler: (ev: infer E) => any) => any;
|
|
12
|
+
} ? E : never;
|
|
13
|
+
export type AfterEventMap = {
|
|
14
|
+
[K in keyof typeof world.afterEvents]: ExtractSubscribeArg<(typeof world.afterEvents)[K]>;
|
|
15
|
+
};
|
|
16
|
+
export type BeforeEventMap = {
|
|
17
|
+
[K in keyof typeof world.beforeEvents]: ExtractSubscribeArg<(typeof world.beforeEvents)[K]>;
|
|
18
|
+
};
|
|
19
|
+
type AfterEventName = keyof AfterEventMap;
|
|
20
|
+
type BeforeEventName = keyof BeforeEventMap;
|
|
21
|
+
export declare class EventManager {
|
|
22
|
+
private static afterListeners;
|
|
23
|
+
private static beforeListeners;
|
|
24
|
+
/** init: world.beforeEvents / world.afterEvents を全自動で subscribe して dispatch に流す */
|
|
25
|
+
static initialize(): void;
|
|
26
|
+
static registerAfter<K extends AfterEventName>(eventName: K, listener: Listener<AfterEventMap[K]>): void;
|
|
27
|
+
static registerBefore<K extends BeforeEventName>(eventName: K, listener: Listener<BeforeEventMap[K]>): void;
|
|
28
|
+
private static dispatchAfter;
|
|
29
|
+
private static dispatchBefore;
|
|
30
|
+
/** 登録済みリスナーを全部クリア(Plugin 単位で実装するなら拡張する) */
|
|
31
|
+
private static clearAll;
|
|
32
|
+
}
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface WaitForOptions {
|
|
2
|
+
onInterval?: () => void;
|
|
3
|
+
onTimeout?: () => void;
|
|
4
|
+
interval?: number;
|
|
5
|
+
timeout?: number;
|
|
6
|
+
resolveOnInterval?: boolean;
|
|
7
|
+
resolveOnTimeout?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* イベントを条件付きで待機(タイムアウト付き)
|
|
11
|
+
*/
|
|
12
|
+
export declare function waitFor<T extends object>(predicate: (event: T) => boolean, options?: WaitForOptions): Promise<T>;
|
|
13
|
+
/**
|
|
14
|
+
* 複数イベントを束ねて非同期フローを開始
|
|
15
|
+
* すべてのイベントで、Entityを自動検出
|
|
16
|
+
*/
|
|
17
|
+
export declare function flowListen<E extends object>(...args: any[]): void;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { keystone } from './keystone';
|
|
2
|
+
export { Vector3 } from './math/vector3';
|
|
3
|
+
export { Priority } from './event/priority';
|
|
4
|
+
export { EventManager } from './event/eventManager';
|
|
5
|
+
export { debug } from './utils/debugger';
|
|
6
|
+
export { RepeatingTimer, DelayedTimer, repeating, delayed, sleep } from './timer/timer';
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { Vector3 as _Vector3 } from '@minecraft/server';
|
|
2
|
+
export declare class Vector3 {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
z: number;
|
|
6
|
+
constructor(x: number, y: number, z: number);
|
|
7
|
+
/**
|
|
8
|
+
* ゼロベクトルで生成
|
|
9
|
+
* @return {Vector3}
|
|
10
|
+
*/
|
|
11
|
+
static zero(): Vector3;
|
|
12
|
+
/**
|
|
13
|
+
* {x, y, z} オブジェクトから生成
|
|
14
|
+
* @param {_Vector3} pos
|
|
15
|
+
* @returns
|
|
16
|
+
*/
|
|
17
|
+
static fromBDS(pos: _Vector3): Vector3;
|
|
18
|
+
getX(): number;
|
|
19
|
+
getY(): number;
|
|
20
|
+
getZ(): number;
|
|
21
|
+
getFloorX(): number;
|
|
22
|
+
getFloorY(): number;
|
|
23
|
+
getFloorZ(): number;
|
|
24
|
+
/**
|
|
25
|
+
* 加算
|
|
26
|
+
* @param {number} x
|
|
27
|
+
* @param {number} y
|
|
28
|
+
* @param {number} z
|
|
29
|
+
* @return {Vector3}
|
|
30
|
+
*/
|
|
31
|
+
add(x: number, y: number, z: number): Vector3;
|
|
32
|
+
/**
|
|
33
|
+
* ベクトル単位での加算
|
|
34
|
+
* @param {_Vector3} v
|
|
35
|
+
* @returns {Vector3}
|
|
36
|
+
*/
|
|
37
|
+
addVector(v: _Vector3): Vector3;
|
|
38
|
+
/**
|
|
39
|
+
* 減算
|
|
40
|
+
* @param {number} x
|
|
41
|
+
* @param {number} y
|
|
42
|
+
* @param {number} z
|
|
43
|
+
* @return {Vector3}
|
|
44
|
+
*/
|
|
45
|
+
subtract(x: number, y: number, z: number): Vector3;
|
|
46
|
+
/**
|
|
47
|
+
* ベクトル単位での減算
|
|
48
|
+
* @param {_Vector3} v
|
|
49
|
+
* @return {Vector3}
|
|
50
|
+
*/
|
|
51
|
+
subtractVector(v: _Vector3): Vector3;
|
|
52
|
+
/**
|
|
53
|
+
* 乗算
|
|
54
|
+
* @param {number} value
|
|
55
|
+
* @return {Vector3}
|
|
56
|
+
*/
|
|
57
|
+
multiply(value: number): Vector3;
|
|
58
|
+
/**
|
|
59
|
+
* 除算
|
|
60
|
+
* @param {number} value
|
|
61
|
+
* @return {Vector3}
|
|
62
|
+
*/
|
|
63
|
+
divide(value: number): Vector3;
|
|
64
|
+
/**
|
|
65
|
+
* ベクトルの内部数値小数点切り上げ
|
|
66
|
+
* @return {Vector3}
|
|
67
|
+
*/
|
|
68
|
+
ceil(): Vector3;
|
|
69
|
+
/**
|
|
70
|
+
* ベクトルの内部数値小数点切り捨て
|
|
71
|
+
* @return {Vector3}
|
|
72
|
+
*/
|
|
73
|
+
floor(): Vector3;
|
|
74
|
+
/**
|
|
75
|
+
* ベクトルの内部数値小数点四捨五入
|
|
76
|
+
* @param {number} precision
|
|
77
|
+
* @return {Vector3}
|
|
78
|
+
*/
|
|
79
|
+
round(precision?: number): Vector3;
|
|
80
|
+
/**
|
|
81
|
+
* ベクトルの内部数値の絶対値
|
|
82
|
+
* @return {Vector3}
|
|
83
|
+
*/
|
|
84
|
+
abs(): Vector3;
|
|
85
|
+
/**
|
|
86
|
+
* 指定した2点間のユークリッド距離
|
|
87
|
+
* @param {_Vector3} pos
|
|
88
|
+
* @return {number}
|
|
89
|
+
*/
|
|
90
|
+
distance(pos: _Vector3): number;
|
|
91
|
+
/**
|
|
92
|
+
* 指定した2点間のユークリッド距離の2乗
|
|
93
|
+
* @param {_Vector3} pos
|
|
94
|
+
* @return {number}
|
|
95
|
+
*/
|
|
96
|
+
distanceSquared(pos: _Vector3): number;
|
|
97
|
+
/**
|
|
98
|
+
* 内積
|
|
99
|
+
* @param {_Vector3} pos
|
|
100
|
+
* @return {number}
|
|
101
|
+
*/
|
|
102
|
+
dot(pos: _Vector3): number;
|
|
103
|
+
/**
|
|
104
|
+
* 外積
|
|
105
|
+
* @param {_Vector3} pos
|
|
106
|
+
* @return {Vector3}
|
|
107
|
+
*/
|
|
108
|
+
cross(pos: _Vector3): Vector3;
|
|
109
|
+
/**
|
|
110
|
+
* ベクトルの比較
|
|
111
|
+
* @param {_Vector3} pos
|
|
112
|
+
* @return {boolean}
|
|
113
|
+
*/
|
|
114
|
+
equals(pos: _Vector3): boolean;
|
|
115
|
+
/**
|
|
116
|
+
* ベクトルの長さ
|
|
117
|
+
* @return {number}
|
|
118
|
+
*/
|
|
119
|
+
length(): number;
|
|
120
|
+
/**
|
|
121
|
+
* ベクトルの長さの2乗
|
|
122
|
+
* @return {number}
|
|
123
|
+
*/
|
|
124
|
+
lengthSquared(): number;
|
|
125
|
+
/**
|
|
126
|
+
* 正規化
|
|
127
|
+
* @return {Vector3}
|
|
128
|
+
*/
|
|
129
|
+
normalize(): Vector3;
|
|
130
|
+
/**
|
|
131
|
+
* オブジェクトの数値指定再生成
|
|
132
|
+
* @param {number} x
|
|
133
|
+
* @param {number} y
|
|
134
|
+
* @param {number} z
|
|
135
|
+
* @return {Vector3}
|
|
136
|
+
*/
|
|
137
|
+
withComponents(x?: number, y?: number, z?: number): Vector3;
|
|
138
|
+
/**
|
|
139
|
+
* X座標をxValueにしたとき線分上に存在する点を返す
|
|
140
|
+
* @param end 終点
|
|
141
|
+
* @param xValue 途中点のX値
|
|
142
|
+
* @returns {Vector3 | undefined}
|
|
143
|
+
*/
|
|
144
|
+
getIntermediateWithXValue(end: Vector3, xValue: number): Vector3 | undefined;
|
|
145
|
+
/**
|
|
146
|
+
* Y座標をyValueにしたとき線分上に存在する点を返す
|
|
147
|
+
* @param end 終点
|
|
148
|
+
* @param yValue 途中点のY値
|
|
149
|
+
* @returns {Vector3 | undefined}
|
|
150
|
+
*/
|
|
151
|
+
getIntermediateWithYValue(end: Vector3, yValue: number): Vector3 | undefined;
|
|
152
|
+
/**
|
|
153
|
+
* Z座標をzValueにしたとき線分上に存在する点を返す
|
|
154
|
+
* @param end 終点
|
|
155
|
+
* @param zValue 途中点のZ値
|
|
156
|
+
* @returns {Vector3 | undefined}
|
|
157
|
+
*/
|
|
158
|
+
getIntermediateWithZValue(end: Vector3, zValue: number): Vector3 | undefined;
|
|
159
|
+
/**
|
|
160
|
+
* BDS ScriptAPIで使える {x, y, z} 形式に変換
|
|
161
|
+
* @returns {_Vector3}
|
|
162
|
+
*/
|
|
163
|
+
toBDS(): _Vector3;
|
|
164
|
+
/** 通常のオブジェクトに変換 */
|
|
165
|
+
toObject(): {
|
|
166
|
+
x: number;
|
|
167
|
+
y: number;
|
|
168
|
+
z: number;
|
|
169
|
+
};
|
|
170
|
+
toString(): string;
|
|
171
|
+
/**
|
|
172
|
+
* 最大点
|
|
173
|
+
* @param {_Vector3} vector
|
|
174
|
+
* @param {_Vector3[]} vectors
|
|
175
|
+
* @returns {Vector3}
|
|
176
|
+
*/
|
|
177
|
+
static maxComponents(vector: _Vector3, ...vectors: _Vector3[]): Vector3;
|
|
178
|
+
/**
|
|
179
|
+
* 最小点
|
|
180
|
+
* @param {_Vector3} vector
|
|
181
|
+
* @param {_Vector3[]} vectors
|
|
182
|
+
* @returns {Vector3}
|
|
183
|
+
*/
|
|
184
|
+
static minComponents(vector: _Vector3, ...vectors: _Vector3[]): Vector3;
|
|
185
|
+
/**
|
|
186
|
+
* 合計
|
|
187
|
+
* @param {_Vector3[]} vectors
|
|
188
|
+
* @returns {Vector3}
|
|
189
|
+
*/
|
|
190
|
+
static sum(...vectors: {
|
|
191
|
+
x: number;
|
|
192
|
+
y: number;
|
|
193
|
+
z: number;
|
|
194
|
+
}[]): Vector3;
|
|
195
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ============================================================
|
|
3
|
+
* マスター Interval(負荷分散スケジューラ)
|
|
4
|
+
* ============================================================
|
|
5
|
+
*/
|
|
6
|
+
export declare class TimerScheduler {
|
|
7
|
+
private static tasks;
|
|
8
|
+
private static tick;
|
|
9
|
+
private static started;
|
|
10
|
+
/** スケジューラにタスクを登録 */
|
|
11
|
+
static addTask(task: () => void): void;
|
|
12
|
+
/** タスクを削除 */
|
|
13
|
+
static removeTask(task: () => void): void;
|
|
14
|
+
/** Interval を開始(1 本だけ) */
|
|
15
|
+
private static ensureStarted;
|
|
16
|
+
}
|
|
17
|
+
/** 内部キャンセル結果 */
|
|
18
|
+
declare enum CancelResult {
|
|
19
|
+
SUCCESS = 0,
|
|
20
|
+
FORCE = 1,
|
|
21
|
+
FAILURE = 2
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* ============================================================
|
|
25
|
+
* Base Timer
|
|
26
|
+
* ============================================================
|
|
27
|
+
* スケジューラに登録され、tick ごとに管理される抽象クラス
|
|
28
|
+
*/
|
|
29
|
+
declare abstract class Timer {
|
|
30
|
+
protected currentTick: number;
|
|
31
|
+
protected onRun?: (currentTick: number) => void;
|
|
32
|
+
protected onCancel?: () => void;
|
|
33
|
+
protected stopped: boolean;
|
|
34
|
+
protected canceled: boolean;
|
|
35
|
+
protected forceCanceled: boolean;
|
|
36
|
+
/** スケジューラに登録されたタスク */
|
|
37
|
+
protected task?: () => void;
|
|
38
|
+
constructor(onRun?: (currentTick: number) => void, onCancel?: () => void);
|
|
39
|
+
/** 開始(各派生クラスで実装) */
|
|
40
|
+
abstract start(): void;
|
|
41
|
+
/** 一時停止 */
|
|
42
|
+
stop(): void;
|
|
43
|
+
/** 再開 */
|
|
44
|
+
resume(): void;
|
|
45
|
+
/** 停止しているか */
|
|
46
|
+
isStopped(): boolean;
|
|
47
|
+
/** キャンセル要求 */
|
|
48
|
+
cancel(force?: boolean): void;
|
|
49
|
+
/** タイマー内部キャンセル */
|
|
50
|
+
protected internalCancel(force?: boolean): CancelResult;
|
|
51
|
+
}
|
|
52
|
+
export interface RepeatingOptions {
|
|
53
|
+
period?: number;
|
|
54
|
+
endless?: boolean;
|
|
55
|
+
silenceOnStop?: boolean;
|
|
56
|
+
maxElapsedTicks?: number;
|
|
57
|
+
onFinal?: () => void;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 一定間隔で実行される繰り返しタイマー
|
|
61
|
+
*/
|
|
62
|
+
export declare class RepeatingTimer extends Timer {
|
|
63
|
+
private period;
|
|
64
|
+
private endless;
|
|
65
|
+
private silenceOnStop;
|
|
66
|
+
private maxElapsedTicks?;
|
|
67
|
+
private onFinal?;
|
|
68
|
+
constructor(onRun?: (currentTick: number) => void, opts?: RepeatingOptions, onCancel?: () => void);
|
|
69
|
+
/** タイマー開始 */
|
|
70
|
+
start(): void;
|
|
71
|
+
}
|
|
72
|
+
export interface DelayedOptions {
|
|
73
|
+
delay?: number;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* 指定 tick 後に一度だけ実行されるタイマー
|
|
77
|
+
*/
|
|
78
|
+
export declare class DelayedTimer extends Timer {
|
|
79
|
+
private delay;
|
|
80
|
+
constructor(onRun?: (currentTick: number) => void, opts?: DelayedOptions, onCancel?: () => void);
|
|
81
|
+
start(): void;
|
|
82
|
+
}
|
|
83
|
+
export declare function repeating(opts: {
|
|
84
|
+
every?: number;
|
|
85
|
+
endless?: boolean;
|
|
86
|
+
max?: number;
|
|
87
|
+
silenceWhenStopped?: boolean;
|
|
88
|
+
run?: (tick: number) => void;
|
|
89
|
+
cancel?: () => void;
|
|
90
|
+
final?: () => void;
|
|
91
|
+
}): RepeatingTimer;
|
|
92
|
+
export declare function delayed(ticks: number, run: () => void, cancel?: () => void): DelayedTimer;
|
|
93
|
+
export declare function sleep(tick: number): Promise<void>;
|
|
94
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function debug(...args: any[]): void;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,770 @@
|
|
|
1
|
+
import { world, system } from "@minecraft/server";
|
|
2
|
+
class Keystone {
|
|
3
|
+
constructor() {
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
const keystone = new Keystone();
|
|
7
|
+
class Vector3 {
|
|
8
|
+
constructor(x, y, z) {
|
|
9
|
+
this.x = x;
|
|
10
|
+
this.y = y;
|
|
11
|
+
this.z = z;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* ゼロベクトルで生成
|
|
15
|
+
* @return {Vector3}
|
|
16
|
+
*/
|
|
17
|
+
static zero() {
|
|
18
|
+
return new Vector3(0, 0, 0);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* {x, y, z} オブジェクトから生成
|
|
22
|
+
* @param {_Vector3} pos
|
|
23
|
+
* @returns
|
|
24
|
+
*/
|
|
25
|
+
static fromBDS(pos) {
|
|
26
|
+
return new Vector3(pos.x, pos.y, pos.z);
|
|
27
|
+
}
|
|
28
|
+
// ===== 基本ゲッター =====
|
|
29
|
+
getX() {
|
|
30
|
+
return this.x;
|
|
31
|
+
}
|
|
32
|
+
getY() {
|
|
33
|
+
return this.y;
|
|
34
|
+
}
|
|
35
|
+
getZ() {
|
|
36
|
+
return this.z;
|
|
37
|
+
}
|
|
38
|
+
getFloorX() {
|
|
39
|
+
return Math.floor(this.x);
|
|
40
|
+
}
|
|
41
|
+
getFloorY() {
|
|
42
|
+
return Math.floor(this.y);
|
|
43
|
+
}
|
|
44
|
+
getFloorZ() {
|
|
45
|
+
return Math.floor(this.z);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 加算
|
|
49
|
+
* @param {number} x
|
|
50
|
+
* @param {number} y
|
|
51
|
+
* @param {number} z
|
|
52
|
+
* @return {Vector3}
|
|
53
|
+
*/
|
|
54
|
+
add(x, y, z) {
|
|
55
|
+
return new Vector3(
|
|
56
|
+
this.x + x,
|
|
57
|
+
this.y + y,
|
|
58
|
+
this.z + z
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* ベクトル単位での加算
|
|
63
|
+
* @param {_Vector3} v
|
|
64
|
+
* @returns {Vector3}
|
|
65
|
+
*/
|
|
66
|
+
addVector(v) {
|
|
67
|
+
return this.add(v.x, v.y, v.z);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 減算
|
|
71
|
+
* @param {number} x
|
|
72
|
+
* @param {number} y
|
|
73
|
+
* @param {number} z
|
|
74
|
+
* @return {Vector3}
|
|
75
|
+
*/
|
|
76
|
+
subtract(x, y, z) {
|
|
77
|
+
return this.add(-x, -y, -z);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* ベクトル単位での減算
|
|
81
|
+
* @param {_Vector3} v
|
|
82
|
+
* @return {Vector3}
|
|
83
|
+
*/
|
|
84
|
+
subtractVector(v) {
|
|
85
|
+
return this.add(-v.x, -v.y, -v.z);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* 乗算
|
|
89
|
+
* @param {number} value
|
|
90
|
+
* @return {Vector3}
|
|
91
|
+
*/
|
|
92
|
+
multiply(value) {
|
|
93
|
+
return new Vector3(
|
|
94
|
+
this.x * value,
|
|
95
|
+
this.y * value,
|
|
96
|
+
this.z * value
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* 除算
|
|
101
|
+
* @param {number} value
|
|
102
|
+
* @return {Vector3}
|
|
103
|
+
*/
|
|
104
|
+
divide(value) {
|
|
105
|
+
return new Vector3(
|
|
106
|
+
this.x / value,
|
|
107
|
+
this.y / value,
|
|
108
|
+
this.z / value
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* ベクトルの内部数値小数点切り上げ
|
|
113
|
+
* @return {Vector3}
|
|
114
|
+
*/
|
|
115
|
+
ceil() {
|
|
116
|
+
return new Vector3(
|
|
117
|
+
Math.ceil(this.x),
|
|
118
|
+
Math.ceil(this.y),
|
|
119
|
+
Math.ceil(this.z)
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* ベクトルの内部数値小数点切り捨て
|
|
124
|
+
* @return {Vector3}
|
|
125
|
+
*/
|
|
126
|
+
floor() {
|
|
127
|
+
return new Vector3(
|
|
128
|
+
Math.floor(this.x),
|
|
129
|
+
Math.floor(this.y),
|
|
130
|
+
Math.floor(this.z)
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* ベクトルの内部数値小数点四捨五入
|
|
135
|
+
* @param {number} precision
|
|
136
|
+
* @return {Vector3}
|
|
137
|
+
*/
|
|
138
|
+
round(precision = 0) {
|
|
139
|
+
const factor = Math.pow(10, precision);
|
|
140
|
+
return new Vector3(
|
|
141
|
+
Math.round(this.x * factor) / factor,
|
|
142
|
+
Math.round(this.y * factor) / factor,
|
|
143
|
+
Math.round(this.z * factor) / factor
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* ベクトルの内部数値の絶対値
|
|
148
|
+
* @return {Vector3}
|
|
149
|
+
*/
|
|
150
|
+
abs() {
|
|
151
|
+
return new Vector3(
|
|
152
|
+
Math.abs(this.x),
|
|
153
|
+
Math.abs(this.y),
|
|
154
|
+
Math.abs(this.z)
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* 指定した2点間のユークリッド距離
|
|
159
|
+
* @param {_Vector3} pos
|
|
160
|
+
* @return {number}
|
|
161
|
+
*/
|
|
162
|
+
distance(pos) {
|
|
163
|
+
return Math.sqrt(this.distanceSquared(pos));
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* 指定した2点間のユークリッド距離の2乗
|
|
167
|
+
* @param {_Vector3} pos
|
|
168
|
+
* @return {number}
|
|
169
|
+
*/
|
|
170
|
+
distanceSquared(pos) {
|
|
171
|
+
const dx = this.x - pos.x;
|
|
172
|
+
const dy = this.y - pos.y;
|
|
173
|
+
const dz = this.z - pos.z;
|
|
174
|
+
return dx * dx + dy * dy + dz * dz;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* 内積
|
|
178
|
+
* @param {_Vector3} pos
|
|
179
|
+
* @return {number}
|
|
180
|
+
*/
|
|
181
|
+
dot(pos) {
|
|
182
|
+
return this.x * pos.x + this.y * pos.y + this.z * pos.z;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* 外積
|
|
186
|
+
* @param {_Vector3} pos
|
|
187
|
+
* @return {Vector3}
|
|
188
|
+
*/
|
|
189
|
+
cross(pos) {
|
|
190
|
+
return new Vector3(
|
|
191
|
+
this.y * pos.z - this.z * pos.y,
|
|
192
|
+
this.z * pos.x - this.x * pos.z,
|
|
193
|
+
this.x * pos.y - this.y * pos.x
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* ベクトルの比較
|
|
198
|
+
* @param {_Vector3} pos
|
|
199
|
+
* @return {boolean}
|
|
200
|
+
*/
|
|
201
|
+
equals(pos) {
|
|
202
|
+
return this.x === pos.x && this.y === pos.y && this.z === pos.z;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* ベクトルの長さ
|
|
206
|
+
* @return {number}
|
|
207
|
+
*/
|
|
208
|
+
length() {
|
|
209
|
+
return Math.sqrt(this.lengthSquared());
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* ベクトルの長さの2乗
|
|
213
|
+
* @return {number}
|
|
214
|
+
*/
|
|
215
|
+
lengthSquared() {
|
|
216
|
+
return this.x * this.x + this.y * this.y + this.z * this.z;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* 正規化
|
|
220
|
+
* @return {Vector3}
|
|
221
|
+
*/
|
|
222
|
+
normalize() {
|
|
223
|
+
const len = this.length();
|
|
224
|
+
if (len > 0) {
|
|
225
|
+
return this.divide(len);
|
|
226
|
+
}
|
|
227
|
+
return new Vector3(0, 0, 0);
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* オブジェクトの数値指定再生成
|
|
231
|
+
* @param {number} x
|
|
232
|
+
* @param {number} y
|
|
233
|
+
* @param {number} z
|
|
234
|
+
* @return {Vector3}
|
|
235
|
+
*/
|
|
236
|
+
withComponents(x, y, z) {
|
|
237
|
+
return new Vector3(
|
|
238
|
+
x !== void 0 ? x : this.x,
|
|
239
|
+
y !== void 0 ? y : this.y,
|
|
240
|
+
z !== void 0 ? z : this.z
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* X座標をxValueにしたとき線分上に存在する点を返す
|
|
245
|
+
* @param end 終点
|
|
246
|
+
* @param xValue 途中点のX値
|
|
247
|
+
* @returns {Vector3 | undefined}
|
|
248
|
+
*/
|
|
249
|
+
getIntermediateWithXValue(end, xValue) {
|
|
250
|
+
const dx = end.x - this.x;
|
|
251
|
+
if (dx === 0) return;
|
|
252
|
+
const t = (xValue - this.x) / dx;
|
|
253
|
+
if (t < 0 || t > 1) return;
|
|
254
|
+
return new Vector3(
|
|
255
|
+
this.x + dx * t,
|
|
256
|
+
this.y + (end.y - this.y) * t,
|
|
257
|
+
this.z + (end.z - this.z) * t
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Y座標をyValueにしたとき線分上に存在する点を返す
|
|
262
|
+
* @param end 終点
|
|
263
|
+
* @param yValue 途中点のY値
|
|
264
|
+
* @returns {Vector3 | undefined}
|
|
265
|
+
*/
|
|
266
|
+
getIntermediateWithYValue(end, yValue) {
|
|
267
|
+
const dy = end.y - this.y;
|
|
268
|
+
if (dy === 0) return;
|
|
269
|
+
const t = (yValue - this.y) / dy;
|
|
270
|
+
if (t < 0 || t > 1) return;
|
|
271
|
+
return new Vector3(
|
|
272
|
+
this.x + (end.x - this.x) * t,
|
|
273
|
+
this.y + dy * t,
|
|
274
|
+
this.z + (end.z - this.z) * t
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Z座標をzValueにしたとき線分上に存在する点を返す
|
|
279
|
+
* @param end 終点
|
|
280
|
+
* @param zValue 途中点のZ値
|
|
281
|
+
* @returns {Vector3 | undefined}
|
|
282
|
+
*/
|
|
283
|
+
getIntermediateWithZValue(end, zValue) {
|
|
284
|
+
const dz = end.z - this.z;
|
|
285
|
+
if (dz === 0) return;
|
|
286
|
+
const t = (zValue - this.z) / dz;
|
|
287
|
+
if (t < 0 || t > 1) return;
|
|
288
|
+
return new Vector3(
|
|
289
|
+
this.x + (end.x - this.x) * t,
|
|
290
|
+
this.y + (end.y - this.y) * t,
|
|
291
|
+
this.z + dz * t
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* BDS ScriptAPIで使える {x, y, z} 形式に変換
|
|
296
|
+
* @returns {_Vector3}
|
|
297
|
+
*/
|
|
298
|
+
toBDS() {
|
|
299
|
+
return { x: this.x, y: this.y, z: this.z };
|
|
300
|
+
}
|
|
301
|
+
/** 通常のオブジェクトに変換 */
|
|
302
|
+
toObject() {
|
|
303
|
+
return { x: this.x, y: this.y, z: this.z };
|
|
304
|
+
}
|
|
305
|
+
toString() {
|
|
306
|
+
return `_Vector3(x=${this.x}, y=${this.y}, z=${this.z})`;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* 最大点
|
|
310
|
+
* @param {_Vector3} vector
|
|
311
|
+
* @param {_Vector3[]} vectors
|
|
312
|
+
* @returns {Vector3}
|
|
313
|
+
*/
|
|
314
|
+
static maxComponents(vector, ...vectors) {
|
|
315
|
+
let x = vector.x;
|
|
316
|
+
let y = vector.y;
|
|
317
|
+
let z = vector.z;
|
|
318
|
+
for (const pos of vectors) {
|
|
319
|
+
x = Math.max(x, pos.x);
|
|
320
|
+
y = Math.max(y, pos.y);
|
|
321
|
+
z = Math.max(z, pos.z);
|
|
322
|
+
}
|
|
323
|
+
return new Vector3(x, y, z);
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* 最小点
|
|
327
|
+
* @param {_Vector3} vector
|
|
328
|
+
* @param {_Vector3[]} vectors
|
|
329
|
+
* @returns {Vector3}
|
|
330
|
+
*/
|
|
331
|
+
static minComponents(vector, ...vectors) {
|
|
332
|
+
let x = vector.x;
|
|
333
|
+
let y = vector.y;
|
|
334
|
+
let z = vector.z;
|
|
335
|
+
for (const pos of vectors) {
|
|
336
|
+
x = Math.min(x, pos.x);
|
|
337
|
+
y = Math.min(y, pos.y);
|
|
338
|
+
z = Math.min(z, pos.z);
|
|
339
|
+
}
|
|
340
|
+
return new Vector3(x, y, z);
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* 合計
|
|
344
|
+
* @param {_Vector3[]} vectors
|
|
345
|
+
* @returns {Vector3}
|
|
346
|
+
*/
|
|
347
|
+
static sum(...vectors) {
|
|
348
|
+
let x = 0, y = 0, z = 0;
|
|
349
|
+
for (const v of vectors) {
|
|
350
|
+
x += v.x;
|
|
351
|
+
y += v.y;
|
|
352
|
+
z += v.z;
|
|
353
|
+
}
|
|
354
|
+
return new Vector3(x, y, z);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
var Priority = /* @__PURE__ */ ((Priority2) => {
|
|
358
|
+
Priority2[Priority2["LOWEST"] = 5] = "LOWEST";
|
|
359
|
+
Priority2[Priority2["LOW"] = 4] = "LOW";
|
|
360
|
+
Priority2[Priority2["NORMAL"] = 3] = "NORMAL";
|
|
361
|
+
Priority2[Priority2["HIGH"] = 2] = "HIGH";
|
|
362
|
+
Priority2[Priority2["HIGHEST"] = 1] = "HIGHEST";
|
|
363
|
+
Priority2[Priority2["MONITOR"] = 0] = "MONITOR";
|
|
364
|
+
return Priority2;
|
|
365
|
+
})(Priority || {});
|
|
366
|
+
const _EventManager = class _EventManager {
|
|
367
|
+
/** init: world.beforeEvents / world.afterEvents を全自動で subscribe して dispatch に流す */
|
|
368
|
+
static initialize() {
|
|
369
|
+
for (const name in world.afterEvents) {
|
|
370
|
+
world.afterEvents[name].subscribe((ev) => {
|
|
371
|
+
_EventManager.dispatchAfter(name, ev);
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
for (const name in world.beforeEvents) {
|
|
375
|
+
world.beforeEvents[name].subscribe((ev) => {
|
|
376
|
+
_EventManager.dispatchBefore(name, ev);
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
// ---------- register ----------
|
|
381
|
+
static registerAfter(eventName, listener) {
|
|
382
|
+
if (!this.afterListeners[eventName]) {
|
|
383
|
+
this.afterListeners[eventName] = [];
|
|
384
|
+
}
|
|
385
|
+
const arr = this.afterListeners[eventName];
|
|
386
|
+
arr.push(listener);
|
|
387
|
+
arr.sort((a, b) => (b.priority ?? Priority.NORMAL) - (a.priority ?? Priority.NORMAL));
|
|
388
|
+
}
|
|
389
|
+
static registerBefore(eventName, listener) {
|
|
390
|
+
if (!this.beforeListeners[eventName]) {
|
|
391
|
+
this.beforeListeners[eventName] = [];
|
|
392
|
+
}
|
|
393
|
+
const arr = this.beforeListeners[eventName];
|
|
394
|
+
arr.push(listener);
|
|
395
|
+
arr.sort((a, b) => (b.priority ?? Priority.NORMAL) - (a.priority ?? Priority.NORMAL));
|
|
396
|
+
}
|
|
397
|
+
// ---------- dispatch ----------
|
|
398
|
+
static dispatchAfter(eventName, event) {
|
|
399
|
+
const arr = this.afterListeners[eventName];
|
|
400
|
+
if (!arr) return;
|
|
401
|
+
for (const listener of arr) {
|
|
402
|
+
try {
|
|
403
|
+
listener.handler(event);
|
|
404
|
+
} catch (e) {
|
|
405
|
+
console.error(`[EventManager] after:${String(eventName)} handler threw:`, e);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
static dispatchBefore(eventName, event) {
|
|
410
|
+
const arr = this.beforeListeners[eventName];
|
|
411
|
+
if (!arr) return;
|
|
412
|
+
for (const listener of arr) {
|
|
413
|
+
try {
|
|
414
|
+
listener.handler(event);
|
|
415
|
+
} catch (e) {
|
|
416
|
+
console.error(`[EventManager] before:${String(eventName)} handler threw:`, e);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
// ---------- utility ----------
|
|
421
|
+
/** 登録済みリスナーを全部クリア(Plugin 単位で実装するなら拡張する) */
|
|
422
|
+
static clearAll() {
|
|
423
|
+
this.afterListeners = {};
|
|
424
|
+
this.beforeListeners = {};
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
_EventManager.afterListeners = {};
|
|
428
|
+
_EventManager.beforeListeners = {};
|
|
429
|
+
let EventManager = _EventManager;
|
|
430
|
+
const COLOR = {
|
|
431
|
+
reset: "\x1B[0m",
|
|
432
|
+
bold: "\x1B[1m",
|
|
433
|
+
dim: "\x1B[2m",
|
|
434
|
+
red: "\x1B[31m",
|
|
435
|
+
green: "\x1B[32m",
|
|
436
|
+
yellow: "\x1B[33m",
|
|
437
|
+
blue: "\x1B[34m",
|
|
438
|
+
magenta: "\x1B[35m",
|
|
439
|
+
cyan: "\x1B[36m",
|
|
440
|
+
white: "\x1B[37m",
|
|
441
|
+
gray: "\x1B[90m"
|
|
442
|
+
};
|
|
443
|
+
const _VLQDecoder = class _VLQDecoder {
|
|
444
|
+
static decode(str) {
|
|
445
|
+
const result = [];
|
|
446
|
+
let shift = 0;
|
|
447
|
+
let value = 0;
|
|
448
|
+
for (let i = 0; i < str.length; i++) {
|
|
449
|
+
const digit = this.BASE64_CHARS.indexOf(str[i]);
|
|
450
|
+
if (digit === -1) continue;
|
|
451
|
+
const continuation = (digit & 32) !== 0;
|
|
452
|
+
value += (digit & 31) << shift;
|
|
453
|
+
if (continuation) {
|
|
454
|
+
shift += 5;
|
|
455
|
+
} else {
|
|
456
|
+
const negative = (value & 1) !== 0;
|
|
457
|
+
value >>>= 1;
|
|
458
|
+
result.push(negative ? -value : value);
|
|
459
|
+
value = 0;
|
|
460
|
+
shift = 0;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
return result;
|
|
464
|
+
}
|
|
465
|
+
};
|
|
466
|
+
_VLQDecoder.BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
467
|
+
let VLQDecoder = _VLQDecoder;
|
|
468
|
+
class SourceMapDebugger {
|
|
469
|
+
constructor() {
|
|
470
|
+
this.decodedMappings = [];
|
|
471
|
+
this.initialized = false;
|
|
472
|
+
this.initialize();
|
|
473
|
+
}
|
|
474
|
+
initialize() {
|
|
475
|
+
if (typeof globalThis.__SOURCE_MAP__ !== "undefined") {
|
|
476
|
+
this.sourceMap = globalThis.__SOURCE_MAP__;
|
|
477
|
+
this.decodeMappings();
|
|
478
|
+
this.initialized = true;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
decodeMappings() {
|
|
482
|
+
if (!this.sourceMap?.mappings) return;
|
|
483
|
+
const lines = this.sourceMap.mappings.split(";");
|
|
484
|
+
let generatedLine = 1;
|
|
485
|
+
let prevOriginalLine = 0;
|
|
486
|
+
let prevOriginalColumn = 0;
|
|
487
|
+
let prevSource = 0;
|
|
488
|
+
let prevName = 0;
|
|
489
|
+
for (const line of lines) {
|
|
490
|
+
if (!line) {
|
|
491
|
+
generatedLine++;
|
|
492
|
+
continue;
|
|
493
|
+
}
|
|
494
|
+
const segments = line.split(",");
|
|
495
|
+
let generatedColumn = 0;
|
|
496
|
+
for (const segment of segments) {
|
|
497
|
+
if (!segment) continue;
|
|
498
|
+
const decoded = VLQDecoder.decode(segment);
|
|
499
|
+
if (decoded.length < 1) continue;
|
|
500
|
+
generatedColumn += decoded[0];
|
|
501
|
+
const mapping = {
|
|
502
|
+
generatedLine,
|
|
503
|
+
generatedColumn,
|
|
504
|
+
originalLine: 0,
|
|
505
|
+
originalColumn: 0,
|
|
506
|
+
sourceIndex: 0
|
|
507
|
+
};
|
|
508
|
+
if (decoded.length > 1) {
|
|
509
|
+
prevSource += decoded[1];
|
|
510
|
+
mapping.sourceIndex = prevSource;
|
|
511
|
+
if (decoded.length > 2) {
|
|
512
|
+
prevOriginalLine += decoded[2];
|
|
513
|
+
mapping.originalLine = prevOriginalLine;
|
|
514
|
+
if (decoded.length > 3) {
|
|
515
|
+
prevOriginalColumn += decoded[3];
|
|
516
|
+
mapping.originalColumn = prevOriginalColumn;
|
|
517
|
+
if (decoded.length > 4) {
|
|
518
|
+
prevName += decoded[4];
|
|
519
|
+
mapping.name = this.sourceMap.names?.[prevName];
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
this.decodedMappings.push(mapping);
|
|
525
|
+
}
|
|
526
|
+
generatedLine++;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
getOriginalPosition(line, column) {
|
|
530
|
+
if (!this.initialized || this.decodedMappings.length === 0) return null;
|
|
531
|
+
let best = null;
|
|
532
|
+
let bestDistance = Infinity;
|
|
533
|
+
for (const m of this.decodedMappings) {
|
|
534
|
+
if (m.generatedLine === line) {
|
|
535
|
+
const distance = column !== void 0 ? Math.abs(m.generatedColumn - column) : 0;
|
|
536
|
+
if (distance < bestDistance) {
|
|
537
|
+
bestDistance = distance;
|
|
538
|
+
best = m;
|
|
539
|
+
}
|
|
540
|
+
} else if (m.generatedLine < line) {
|
|
541
|
+
if (!best || m.generatedLine > best.generatedLine) best = m;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
if (best && this.sourceMap.sources?.[best.sourceIndex]) {
|
|
545
|
+
return {
|
|
546
|
+
source: this.sourceMap.sources[best.sourceIndex],
|
|
547
|
+
line: best.originalLine,
|
|
548
|
+
column: best.originalColumn,
|
|
549
|
+
content: this.sourceMap.sourcesContent?.[best.sourceIndex],
|
|
550
|
+
name: best.name
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
return null;
|
|
554
|
+
}
|
|
555
|
+
debug(...args) {
|
|
556
|
+
try {
|
|
557
|
+
const err = new Error();
|
|
558
|
+
const stack = err.stack || "";
|
|
559
|
+
const stackLines = stack.split("\n");
|
|
560
|
+
const output = [];
|
|
561
|
+
output.push(`${COLOR.yellow}━━━━━━━━━━━━━━━━━━━━━━${COLOR.reset}`);
|
|
562
|
+
output.push(`${COLOR.bold}${COLOR.cyan}📍 DEBUG${COLOR.reset}`);
|
|
563
|
+
let position = null;
|
|
564
|
+
for (let i = 2; i < Math.min(stackLines.length, 8); i++) {
|
|
565
|
+
const line = stackLines[i];
|
|
566
|
+
console.log(JSON.stringify(line));
|
|
567
|
+
const match = /(?:\()?(?:[A-Za-z0-9._/-]+):(\d+)(?::(\d+))?\)?$/.exec(line);
|
|
568
|
+
if (match) {
|
|
569
|
+
const lineNum = parseInt(match[1]);
|
|
570
|
+
const colNum = match[2] ? parseInt(match[2]) : void 0;
|
|
571
|
+
position = this.getOriginalPosition(lineNum, colNum);
|
|
572
|
+
if (position) break;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
if (position) {
|
|
576
|
+
const file = position.source.replace(/^.*\//, "");
|
|
577
|
+
output.push(`${COLOR.blue}📄 ${file}:${position.line}:${position.column}${COLOR.reset}`);
|
|
578
|
+
if (position.name) output.push(`${COLOR.cyan}🏷 ${position.name}${COLOR.reset}`);
|
|
579
|
+
if (position.content) {
|
|
580
|
+
const lines = position.content.split("\n");
|
|
581
|
+
const target = position.line - 1;
|
|
582
|
+
const range = 2;
|
|
583
|
+
output.push(`${COLOR.gray}─────────────────────${COLOR.reset}`);
|
|
584
|
+
for (let i = Math.max(0, target - range); i <= Math.min(lines.length - 1, target + range); i++) {
|
|
585
|
+
const num = `${(i + 1).toString().padStart(3, " ")}`;
|
|
586
|
+
const content = lines[i];
|
|
587
|
+
if (i === target) {
|
|
588
|
+
output.push(`${COLOR.red}${COLOR.bold}→ ${num}: ${COLOR.white}${content}${COLOR.reset}`);
|
|
589
|
+
} else {
|
|
590
|
+
output.push(`${COLOR.gray} ${num}: ${content}${COLOR.reset}`);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
} else {
|
|
595
|
+
output.push(`${COLOR.gray}📍 Location: (source map not available)${COLOR.reset}`);
|
|
596
|
+
}
|
|
597
|
+
output.push(`${COLOR.gray}─────────────────────${COLOR.reset}`);
|
|
598
|
+
output.push(`${COLOR.bold}${COLOR.white}💾 Values:${COLOR.reset}`);
|
|
599
|
+
args.forEach((arg, i) => {
|
|
600
|
+
let val;
|
|
601
|
+
if (arg === void 0) val = "undefined";
|
|
602
|
+
else if (arg === null) val = "null";
|
|
603
|
+
else if (typeof arg === "object") {
|
|
604
|
+
try {
|
|
605
|
+
val = JSON.stringify(arg, null, 2);
|
|
606
|
+
} catch {
|
|
607
|
+
val = "[Circular or Complex Object]";
|
|
608
|
+
}
|
|
609
|
+
} else if (typeof arg === "function") {
|
|
610
|
+
val = `[Function: ${arg.name || "anonymous"}]`;
|
|
611
|
+
} else {
|
|
612
|
+
val = String(arg);
|
|
613
|
+
}
|
|
614
|
+
output.push(`${COLOR.green}[${i}]:${COLOR.reset} ${val}`);
|
|
615
|
+
});
|
|
616
|
+
output.push(`${COLOR.yellow}━━━━━━━━━━━━━━━━━━━━━━${COLOR.reset}`);
|
|
617
|
+
console.log(output.join("\n"));
|
|
618
|
+
} catch (err) {
|
|
619
|
+
console.log(`${COLOR.red}[DEBUG ERROR]${COLOR.reset}`, err);
|
|
620
|
+
console.log(args);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
const debuggerInstance = new SourceMapDebugger();
|
|
625
|
+
function debug(...args) {
|
|
626
|
+
debuggerInstance.debug(...args);
|
|
627
|
+
}
|
|
628
|
+
const _TimerScheduler = class _TimerScheduler {
|
|
629
|
+
/** スケジューラにタスクを登録 */
|
|
630
|
+
static addTask(task) {
|
|
631
|
+
this.tasks.add(task);
|
|
632
|
+
this.ensureStarted();
|
|
633
|
+
}
|
|
634
|
+
/** タスクを削除 */
|
|
635
|
+
static removeTask(task) {
|
|
636
|
+
this.tasks.delete(task);
|
|
637
|
+
}
|
|
638
|
+
/** Interval を開始(1 本だけ) */
|
|
639
|
+
static ensureStarted() {
|
|
640
|
+
if (this.started) return;
|
|
641
|
+
this.started = true;
|
|
642
|
+
system.runInterval(() => {
|
|
643
|
+
this.tick++;
|
|
644
|
+
for (const task of this.tasks) {
|
|
645
|
+
try {
|
|
646
|
+
task();
|
|
647
|
+
} catch (e) {
|
|
648
|
+
console.error("[TimerScheduler] Task error:", e);
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}, 1);
|
|
652
|
+
}
|
|
653
|
+
};
|
|
654
|
+
_TimerScheduler.tasks = /* @__PURE__ */ new Set();
|
|
655
|
+
_TimerScheduler.tick = 0;
|
|
656
|
+
_TimerScheduler.started = false;
|
|
657
|
+
let TimerScheduler = _TimerScheduler;
|
|
658
|
+
class Timer {
|
|
659
|
+
constructor(onRun, onCancel) {
|
|
660
|
+
this.currentTick = 0;
|
|
661
|
+
this.stopped = false;
|
|
662
|
+
this.canceled = false;
|
|
663
|
+
this.forceCanceled = false;
|
|
664
|
+
this.onRun = onRun;
|
|
665
|
+
this.onCancel = onCancel;
|
|
666
|
+
}
|
|
667
|
+
/** 一時停止 */
|
|
668
|
+
stop() {
|
|
669
|
+
this.stopped = true;
|
|
670
|
+
}
|
|
671
|
+
/** 再開 */
|
|
672
|
+
resume() {
|
|
673
|
+
this.stopped = false;
|
|
674
|
+
}
|
|
675
|
+
/** 停止しているか */
|
|
676
|
+
isStopped() {
|
|
677
|
+
return this.stopped;
|
|
678
|
+
}
|
|
679
|
+
/** キャンセル要求 */
|
|
680
|
+
cancel(force = false) {
|
|
681
|
+
if (force) this.forceCanceled = true;
|
|
682
|
+
this.canceled = true;
|
|
683
|
+
}
|
|
684
|
+
/** タイマー内部キャンセル */
|
|
685
|
+
internalCancel(force = false) {
|
|
686
|
+
if (!this.task) return 2;
|
|
687
|
+
TimerScheduler.removeTask(this.task);
|
|
688
|
+
this.onCancel?.();
|
|
689
|
+
return force ? 1 : 0;
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
class RepeatingTimer extends Timer {
|
|
693
|
+
constructor(onRun, opts = {}, onCancel) {
|
|
694
|
+
super(onRun, onCancel);
|
|
695
|
+
this.period = opts.period ?? 1;
|
|
696
|
+
this.endless = opts.endless ?? true;
|
|
697
|
+
this.silenceOnStop = opts.silenceOnStop ?? true;
|
|
698
|
+
this.maxElapsedTicks = opts.maxElapsedTicks;
|
|
699
|
+
this.onFinal = opts.onFinal;
|
|
700
|
+
}
|
|
701
|
+
/** タイマー開始 */
|
|
702
|
+
start() {
|
|
703
|
+
this.task = () => {
|
|
704
|
+
if (this.forceCanceled) return this.internalCancel(true);
|
|
705
|
+
if (this.canceled) return this.internalCancel();
|
|
706
|
+
if (!this.endless && this.maxElapsedTicks !== void 0 && this.currentTick >= this.maxElapsedTicks) {
|
|
707
|
+
this.onFinal?.();
|
|
708
|
+
return this.internalCancel();
|
|
709
|
+
}
|
|
710
|
+
if (this.currentTick % this.period === 0) {
|
|
711
|
+
if (!this.stopped || this.stopped && !this.silenceOnStop)
|
|
712
|
+
this.onRun?.(this.currentTick);
|
|
713
|
+
}
|
|
714
|
+
if (!this.stopped) this.currentTick++;
|
|
715
|
+
};
|
|
716
|
+
TimerScheduler.addTask(this.task);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
class DelayedTimer extends Timer {
|
|
720
|
+
constructor(onRun, opts = {}, onCancel) {
|
|
721
|
+
super(onRun, onCancel);
|
|
722
|
+
this.delay = opts.delay ?? 1;
|
|
723
|
+
}
|
|
724
|
+
start() {
|
|
725
|
+
this.task = () => {
|
|
726
|
+
if (this.forceCanceled) return this.internalCancel(true);
|
|
727
|
+
if (this.canceled) return this.internalCancel();
|
|
728
|
+
if (this.currentTick >= this.delay) {
|
|
729
|
+
this.onRun?.(this.currentTick);
|
|
730
|
+
return this.internalCancel();
|
|
731
|
+
}
|
|
732
|
+
this.currentTick++;
|
|
733
|
+
};
|
|
734
|
+
TimerScheduler.addTask(this.task);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
function repeating(opts) {
|
|
738
|
+
const options = {
|
|
739
|
+
period: opts.every,
|
|
740
|
+
endless: opts.endless,
|
|
741
|
+
silenceOnStop: opts.silenceWhenStopped,
|
|
742
|
+
maxElapsedTicks: opts.max,
|
|
743
|
+
onFinal: opts.final
|
|
744
|
+
};
|
|
745
|
+
const t = new RepeatingTimer(opts.run, options, opts.cancel);
|
|
746
|
+
t.start();
|
|
747
|
+
return t;
|
|
748
|
+
}
|
|
749
|
+
function delayed(ticks, run, cancel) {
|
|
750
|
+
const t = new DelayedTimer(() => run(), { delay: ticks }, cancel);
|
|
751
|
+
t.start();
|
|
752
|
+
return t;
|
|
753
|
+
}
|
|
754
|
+
function sleep(tick) {
|
|
755
|
+
return new Promise((resolve) => {
|
|
756
|
+
new DelayedTimer(() => resolve(), { delay: tick }).start();
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
export {
|
|
760
|
+
DelayedTimer,
|
|
761
|
+
EventManager,
|
|
762
|
+
Priority,
|
|
763
|
+
RepeatingTimer,
|
|
764
|
+
Vector3,
|
|
765
|
+
debug,
|
|
766
|
+
delayed,
|
|
767
|
+
keystone,
|
|
768
|
+
repeating,
|
|
769
|
+
sleep
|
|
770
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
type PluginConfig = {
|
|
3
|
+
name: string;
|
|
4
|
+
uuid?: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
authors?: string[];
|
|
7
|
+
version?: number[];
|
|
8
|
+
embedSourceMap?: boolean;
|
|
9
|
+
};
|
|
10
|
+
declare const behaviorPacker: ({ name, uuid, description, authors, version, embedSourceMap, }?: PluginConfig) => Plugin;
|
|
11
|
+
export default behaviorPacker;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { resolve } from "path";
|
|
2
|
+
import * as crypto from "node:crypto";
|
|
3
|
+
import * as fs from "node:fs";
|
|
4
|
+
const behaviorPacker = ({
|
|
5
|
+
name = "my first plugin",
|
|
6
|
+
uuid,
|
|
7
|
+
description = "",
|
|
8
|
+
authors = [],
|
|
9
|
+
version = [1, 0, 0],
|
|
10
|
+
embedSourceMap = true
|
|
11
|
+
} = {
|
|
12
|
+
name: "my first plugin",
|
|
13
|
+
description: "",
|
|
14
|
+
authors: [],
|
|
15
|
+
version: [1, 0, 0],
|
|
16
|
+
embedSourceMap: true
|
|
17
|
+
}) => ({
|
|
18
|
+
name: "BehaviorPacker",
|
|
19
|
+
config: (config) => {
|
|
20
|
+
return {
|
|
21
|
+
...config,
|
|
22
|
+
build: {
|
|
23
|
+
sourcemap: true,
|
|
24
|
+
minify: false,
|
|
25
|
+
outDir: "./dist_behavior_pack/scripts",
|
|
26
|
+
emptyOutDir: true,
|
|
27
|
+
assetsDir: "",
|
|
28
|
+
rollupOptions: {
|
|
29
|
+
external: [
|
|
30
|
+
"@minecraft/server",
|
|
31
|
+
"@minecraft/server-net",
|
|
32
|
+
"@minecraft/server-ui"
|
|
33
|
+
],
|
|
34
|
+
input: {
|
|
35
|
+
index: resolve(process.cwd(), "./src/index.ts")
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
generateBundle(options, bundle) {
|
|
42
|
+
if (!embedSourceMap) return;
|
|
43
|
+
for (const [fileName, file] of Object.entries(bundle)) {
|
|
44
|
+
if (file.type === "chunk" && file.map) {
|
|
45
|
+
const sourceMapData = file.map;
|
|
46
|
+
const embeddedSourceMap = {
|
|
47
|
+
version: sourceMapData.version,
|
|
48
|
+
sources: sourceMapData.sources,
|
|
49
|
+
sourcesContent: sourceMapData.sourcesContent,
|
|
50
|
+
mappings: sourceMapData.mappings,
|
|
51
|
+
names: sourceMapData.names
|
|
52
|
+
};
|
|
53
|
+
const sourceMapEmbed = `// ========== Embedded Source Map ==========
|
|
54
|
+
globalThis.__SOURCE_MAP__ = ${JSON.stringify(embeddedSourceMap)};
|
|
55
|
+
// ========== End of Embedded Source Map ==========
|
|
56
|
+
|
|
57
|
+
`;
|
|
58
|
+
const originalCode = file.code;
|
|
59
|
+
const modifiedCode = sourceMapEmbed + originalCode;
|
|
60
|
+
file.code = modifiedCode.replace(/\/\/# sourceMappingURL=.+$/gm, "");
|
|
61
|
+
file.map = null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
for (const fileName in bundle) {
|
|
65
|
+
if (fileName.endsWith(".map")) {
|
|
66
|
+
delete bundle[fileName];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
writeBundle: async (_options, bundle) => {
|
|
71
|
+
const entryFile = Object.values(bundle).find(
|
|
72
|
+
(file) => file.type === "chunk" && file.isEntry
|
|
73
|
+
);
|
|
74
|
+
if (!entryFile || entryFile.type !== "chunk") {
|
|
75
|
+
throw new Error("No entry file found");
|
|
76
|
+
}
|
|
77
|
+
const behaviorUUID = uuid ?? crypto.randomUUID();
|
|
78
|
+
const manifestStub = {
|
|
79
|
+
"format_version": 2,
|
|
80
|
+
"header": {
|
|
81
|
+
"name": name,
|
|
82
|
+
"description": description,
|
|
83
|
+
"uuid": behaviorUUID,
|
|
84
|
+
"version": version,
|
|
85
|
+
"min_engine_version": [1, 21, 120]
|
|
86
|
+
},
|
|
87
|
+
"modules": [
|
|
88
|
+
{
|
|
89
|
+
"description": "script",
|
|
90
|
+
"type": "script",
|
|
91
|
+
"language": "javascript",
|
|
92
|
+
"uuid": crypto.randomUUID(),
|
|
93
|
+
"version": [1, 0, 0],
|
|
94
|
+
"entry": `scripts/${entryFile.fileName}`
|
|
95
|
+
}
|
|
96
|
+
],
|
|
97
|
+
"dependencies": [
|
|
98
|
+
{
|
|
99
|
+
"module_name": "@minecraft/server",
|
|
100
|
+
"version": "beta"
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"module_name": "@minecraft/server-ui",
|
|
104
|
+
"version": "beta"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"module_name": "@minecraft/server-net",
|
|
108
|
+
"version": "beta"
|
|
109
|
+
}
|
|
110
|
+
],
|
|
111
|
+
"metadata": {
|
|
112
|
+
"authors": authors
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
fs.writeFileSync("./dist_behavior_pack/manifest.json", JSON.stringify(manifestStub, null, 2));
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
export {
|
|
119
|
+
behaviorPacker as default
|
|
120
|
+
};
|