@block_factory/lib 0.0.4 → 0.0.5

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.
@@ -1,3 +1,5 @@
1
+ export { _INITIALIZE_BF_FRAMEWORK_ } from "@block_factory/lib/_module/Framework/_INIT";
2
+
1
3
  export { MathUtils } from "./util/Math";
2
4
  export { Signal } from "./util/Signal";
3
5
  export { Vec2, Vec3 } from "./util/Vector";
@@ -15,4 +17,6 @@ export { Inventory, ContainerWrapper } from "./util/Wrapper/Container";
15
17
  export { type IEntity, IEntityWrapper } from "./util/Wrapper/IEntity";
16
18
  export { type IPlayer, IPlayerWrapper } from "./util/Wrapper/IPlayer";
17
19
 
18
- export { _THREAD_ } from "./sys/Threads";
20
+ export { type Sound, type Animation } from "./Types";
21
+ export { _THREAD_ } from "@block_factory/lib/_module/Framework/Threads";
22
+ export { _EntityHandler_, type EntityEmissionEvent, onEntityEmission } from "@block_factory/lib/_module/Framework/EntityTasks";
@@ -0,0 +1,203 @@
1
+ import {
2
+ Entity,
3
+ system,
4
+ ScriptEventCommandMessageAfterEvent,
5
+ ScriptEventCommandMessageAfterEventSignal,
6
+ world,
7
+ WorldLoadAfterEventSignal,
8
+ WorldLoadAfterEvent,
9
+ EntitySpawnAfterEventSignal,
10
+ EntityRemoveAfterEventSignal,
11
+ EntitySpawnAfterEvent,
12
+ EntityRemoveAfterEvent,
13
+ EntityRemoveBeforeEvent,
14
+ EntityRemoveBeforeEventSignal,
15
+ } from "@minecraft/server";
16
+
17
+ import { Signal } from "../util/Signal";
18
+ import { IEntityWrapper, IEntity } from "../util/Wrapper/IEntity";
19
+
20
+ /* -------------------------------------------------------------------------- */
21
+ /* Public API */
22
+ /* -------------------------------------------------------------------------- */
23
+
24
+ export type EntityEmissionEvent = {
25
+ iEntity: IEntity;
26
+ parms: any;
27
+ };
28
+
29
+ export const onEntityEmission = new Signal<EntityEmissionEvent>();
30
+
31
+ /* -------------------------------------------------------------------------- */
32
+ /* Singleton */
33
+ /* -------------------------------------------------------------------------- */
34
+
35
+
36
+
37
+ class EntityHandler {
38
+ private PACK_ID: string | undefined;
39
+ private GLOBAL_MEMORY_ID = "GLB_MEM.ENTITY";
40
+
41
+ private readonly scriptEventSignal: ScriptEventCommandMessageAfterEventSignal = system.afterEvents.scriptEventReceive;
42
+ private readonly loadEventSignal: WorldLoadAfterEventSignal = world.afterEvents.worldLoad;
43
+ private readonly spawnEventSignal: EntitySpawnAfterEventSignal = world.afterEvents.entitySpawn;
44
+ private readonly removeAfterEventSignal: EntityRemoveAfterEventSignal = world.afterEvents.entityRemove;
45
+ private readonly removeBeforeEventSignal: EntityRemoveBeforeEventSignal = world.beforeEvents.entityRemove;
46
+
47
+ private readonly EM_INDEX = new Map<string, Entity>();
48
+ private readonly EM_KEYS: string[] = [];
49
+ private readonly SEARCH_TYPES = new Set<string>();
50
+
51
+ private _started = false;
52
+ private _wired = false;
53
+
54
+ public configure(): void {
55
+ if (this._started) throw new Error("BFLIB: EntityHandler already started;");
56
+ }
57
+
58
+ public registerEntity(typeId: string | string[]): void {
59
+ if (Array.isArray(typeId)) typeId.forEach((t) => this.SEARCH_TYPES.add(t));
60
+ else this.SEARCH_TYPES.add(typeId);
61
+ }
62
+
63
+ public start(packId: string): void {
64
+ if (this._started) return;
65
+ this._started = true;
66
+ this.PACK_ID = packId;
67
+
68
+ this.loadEventSignal.subscribe(this.onWorldLoad);
69
+ }
70
+
71
+ public stop(): void {
72
+ if (!this._started) return;
73
+
74
+ this.loadEventSignal.unsubscribe(this.onWorldLoad);
75
+ if (this._wired) {
76
+ this.scriptEventSignal.unsubscribe(this.processScriptEvents);
77
+ this.spawnEventSignal.unsubscribe(this.onEntitySpawned);
78
+ this.removeBeforeEventSignal.unsubscribe(this.onEntityRemovedBefore);
79
+ this.removeAfterEventSignal.unsubscribe(this.onEntityRemovedAfter);
80
+ this._wired = false;
81
+ }
82
+
83
+ this._started = false;
84
+ }
85
+
86
+ /* ------------------------------------------------------------------------ */
87
+ /* Event Wiring */
88
+ /* ------------------------------------------------------------------------ */
89
+
90
+ private onWorldLoad = (_event: WorldLoadAfterEvent): void => {
91
+
92
+ this.scriptEventSignal.subscribe(this.processScriptEvents);
93
+
94
+ if (this.SEARCH_TYPES.size > 0) {
95
+ this.spawnEventSignal.subscribe(this.onEntitySpawned);
96
+ this.removeBeforeEventSignal.subscribe(this.onEntityRemovedBefore);
97
+ this.removeAfterEventSignal.subscribe(this.onEntityRemovedAfter);
98
+ }
99
+
100
+ this._wired = true;
101
+ this.reloadEntityMemory();
102
+ this.loadEventSignal.unsubscribe(this.onWorldLoad);
103
+ };
104
+
105
+ private processScriptEvents = (event: ScriptEventCommandMessageAfterEvent): void => {
106
+ if (!event.sourceEntity) return;
107
+ if (event.id !== `${this.PACK_ID}:entity_emitter`) return;
108
+
109
+ let parms: any;
110
+ try {
111
+ parms = JSON.parse(event.message);
112
+ } catch (e) {
113
+ console.error(`BFLIB: entity_emitter JSON parse failed:`, e);
114
+ return;
115
+ }
116
+
117
+ onEntityEmission.emit({
118
+ iEntity: IEntityWrapper.wrap(event.sourceEntity),
119
+ parms,
120
+ });
121
+ };
122
+
123
+ /* ------------------------------------------------------------------------ */
124
+ /* Filters */
125
+ /* ------------------------------------------------------------------------ */
126
+
127
+ private isValidType(typeId: string): boolean {
128
+ return this.SEARCH_TYPES.has(typeId);
129
+ }
130
+
131
+ private onEntitySpawned = (event: EntitySpawnAfterEvent): void => {
132
+ const entity = event.entity;
133
+ if (!this.isValidType(entity.typeId)) return;
134
+ this.saveEntityInMemory(entity);
135
+ };
136
+
137
+ private onEntityRemovedBefore = (event: EntityRemoveBeforeEvent): void => {
138
+ const entity = event.removedEntity;
139
+ if (!this.isValidType(entity.typeId)) return;
140
+ this.deleteEntityInMemory(entity);
141
+ };
142
+
143
+ private onEntityRemovedAfter = (_event: EntityRemoveAfterEvent): void => {
144
+ //
145
+ };
146
+
147
+ /* ------------------------------------------------------------------------ */
148
+ /* Persistence */
149
+ /* ------------------------------------------------------------------------ */
150
+
151
+ private reloadEntityMemory(): void {
152
+ this.EM_INDEX.clear();
153
+ this.EM_KEYS.length = 0;
154
+
155
+ const raw = world.getDynamicProperty(this.GLOBAL_MEMORY_ID) as string | undefined;
156
+ if (!raw) return;
157
+
158
+ let parsed: string[];
159
+ try {
160
+ parsed = JSON.parse(raw) as string[];
161
+ } catch (e) {
162
+ console.error(`BFLIB: Failed to parse ${this.GLOBAL_MEMORY_ID}:`, e);
163
+ return;
164
+ }
165
+
166
+ for (const id of parsed) {
167
+ this.EM_KEYS.push(id);
168
+ const entity = world.getEntity(id);
169
+ if (entity) this.EM_INDEX.set(entity.id, entity);
170
+ }
171
+ }
172
+
173
+ private persistKeys(): void {
174
+ world.setDynamicProperty(this.GLOBAL_MEMORY_ID, JSON.stringify(this.EM_KEYS));
175
+ }
176
+
177
+ public saveEntityInMemory(entity: Entity): boolean {
178
+ if (this.EM_INDEX.has(entity.id)) return false;
179
+ this.EM_KEYS.push(entity.id);
180
+ this.EM_INDEX.set(entity.id, entity);
181
+ this.persistKeys();
182
+
183
+ return true;
184
+ }
185
+
186
+ public deleteEntityInMemory(entity: Entity): boolean {
187
+ const existed = this.EM_INDEX.delete(entity.id);
188
+ if (!existed) return false;
189
+
190
+ const idx = this.EM_KEYS.indexOf(entity.id);
191
+ if (idx !== -1) this.EM_KEYS.splice(idx, 1);
192
+
193
+ this.persistKeys();
194
+
195
+ return true;
196
+ }
197
+
198
+ public getEntitiesInMemory(): Entity[] {
199
+ return Array.from(this.EM_INDEX.values());
200
+ }
201
+ }
202
+
203
+ export const _EntityHandler_ = new EntityHandler();
@@ -0,0 +1,72 @@
1
+ import { system, TicksPerSecond } from "@minecraft/server";
2
+ import { Signal } from "../util/Signal";
3
+
4
+ export type ThreadConfig = {
5
+ mainRate?: number; // interval ticks
6
+ lateRate?: number; // interval ticks
7
+ };
8
+
9
+ class Threads {
10
+ public readonly MAIN = new Signal<number>();
11
+ public readonly LATE = new Signal<void>();
12
+
13
+ private _mainRate = 0;
14
+ private _lateRate = TicksPerSecond;
15
+
16
+ private _MAIN_ID: number | undefined;
17
+ private _LATE_ID: number | undefined;
18
+
19
+ private _delta = this.createDeltaTimer();
20
+ private _started = false;
21
+
22
+ public configure(cfg: ThreadConfig) {
23
+ if (this._started) throw new Error("BFLIB: _THREAD_ already started; configure before start().");
24
+ if (cfg.mainRate !== undefined) this._mainRate = cfg.mainRate;
25
+ if (cfg.lateRate !== undefined) this._lateRate = cfg.lateRate;
26
+ }
27
+
28
+ public start() {
29
+ if (this._started) return; // idempotent
30
+ this._started = true;
31
+
32
+ this._MAIN_ID = system.runInterval(() => {
33
+ if (this.MAIN.count <= 0) return;
34
+ try {
35
+ const delta = this._delta();
36
+ this.MAIN.emit(delta);
37
+ } catch (e) {
38
+ console.error(`ERROR: _THREAD_.MAIN:${this._MAIN_ID} |`, e);
39
+ }
40
+ }, this._mainRate);
41
+
42
+ this._LATE_ID = system.runInterval(() => {
43
+ if (this.LATE.count <= 0) return;
44
+ try {
45
+ this.LATE.emit();
46
+ } catch (e) {
47
+ console.error(`ERROR: _THREAD_.LATE:${this._LATE_ID} |`, e);
48
+ }
49
+ }, this._lateRate);
50
+ }
51
+
52
+ public stop() {
53
+ if (this._MAIN_ID !== undefined) system.clearRun(this._MAIN_ID);
54
+ if (this._LATE_ID !== undefined) system.clearRun(this._LATE_ID);
55
+ this._MAIN_ID = undefined;
56
+ this._LATE_ID = undefined;
57
+ this._started = false;
58
+ this._delta = this.createDeltaTimer(); // reset delta timing
59
+ }
60
+
61
+ private createDeltaTimer() {
62
+ let last = Date.now();
63
+ return () => {
64
+ const now = Date.now();
65
+ const delta = (now - last) / 1000;
66
+ last = now;
67
+ return delta;
68
+ };
69
+ }
70
+ }
71
+
72
+ export const _THREAD_ = new Threads();
@@ -0,0 +1,39 @@
1
+ let IS_INITIALIZED: boolean = false
2
+ let PACK_ID: string | undefined = undefined
3
+
4
+ /* -------------------------------------------------------------------------- */
5
+ /* Public API */
6
+ /* -------------------------------------------------------------------------- */
7
+
8
+ /**
9
+ * Initializes the Block Factory framework.
10
+ *
11
+ * This **must be called exactly once** before using any backend systems
12
+ * such as threads, entity tasks, or event routing.
13
+ *
14
+ * @param packId - Unique identifier for the active pack instance.
15
+ *
16
+ * @throws Error if the framework has already been initialized.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * _INITIALIZE_BF_FRAMEWORK_("bf:utility_tools");
21
+ * ```
22
+ */
23
+ export function _INITIALIZE_BF_FRAMEWORK_(packId: string): void {
24
+ if (IS_INITIALIZED) throw Error(`CONFLICT WARNING: ${PACK_ID} already initialized.`);
25
+ PACK_ID = packId; IS_INITIALIZED = true;
26
+ console.log("Block Factory Framework Loaded");
27
+ }
28
+
29
+ /* -------------------------------------------------------------------------- */
30
+ /* Internal API */
31
+ /* -------------------------------------------------------------------------- */
32
+
33
+ export function getPackId(): string | undefined {
34
+ return PACK_ID;
35
+ }
36
+
37
+ export function isInitalized(): boolean {
38
+ return IS_INITIALIZED;
39
+ }
@@ -0,0 +1,10 @@
1
+ export type Sound = {
2
+ id: string,
3
+ length: number
4
+ }
5
+
6
+ export type Animation = {
7
+ id: string,
8
+ length: number,
9
+ loop?: boolean,
10
+ }
@@ -24,8 +24,10 @@ export class Signal<T = void> {
24
24
  }
25
25
 
26
26
  public emit(data: T): void {
27
- for (const cb of Array.from(this.listeners)) {
28
- cb(data);
27
+ for (const callback of Array.from(this.listeners)) {
28
+ try { callback(data) } catch (err) {
29
+ console.error("BFLIB: Signal listener error:", err);
30
+ }
29
31
  }
30
32
  }
31
33
  }
@@ -1,6 +1,7 @@
1
- import { Entity, EntityInventoryComponent } from "@minecraft/server";
1
+ import { Entity, EntityInventoryComponent, PlayAnimationOptions, system, TicksPerSecond } from "@minecraft/server";
2
2
  import { ContainerWrapper, Inventory } from "./Container";
3
3
  import { System } from "../System";
4
+ import { Animation } from "../../Types";
4
5
 
5
6
  export type IEntity = IEntityWrapper & Entity;
6
7
 
@@ -17,9 +18,8 @@ export class IEntityWrapper {
17
18
  }
18
19
 
19
20
  //======================== Interal ========================
20
- public isAlive: boolean = false;
21
21
 
22
- public get inventory(): Inventory {
22
+ public get inventory(): Inventory | undefined {
23
23
  const i = this.source.getComponent(
24
24
  EntityInventoryComponent.componentId
25
25
  ) as EntityInventoryComponent;
@@ -27,8 +27,9 @@ export class IEntityWrapper {
27
27
  return ContainerWrapper.wrap(i.container);
28
28
  }
29
29
 
30
- public test(): void {
31
- //this.source.sendMessage(`${this.source.name} was tested`);
30
+ public async playAnimationAsync(animation: Animation, options: PlayAnimationOptions): Promise<void> {
31
+ this.source.playAnimation(animation.id, options);
32
+ await system.waitTicks(animation.length * TicksPerSecond);
32
33
  }
33
34
 
34
35
  }
@@ -1,6 +1,7 @@
1
- import { EntityInventoryComponent, Player } from "@minecraft/server";
1
+ import { EntityInventoryComponent, PlayAnimationOptions, Player, PlayerSoundOptions, system, TicksPerSecond } from "@minecraft/server";
2
2
  import { ContainerWrapper, Inventory } from "./Container";
3
3
  import { System } from "../System";
4
+ import { Animation, Sound } from "../../Types";
4
5
 
5
6
  export type IPlayer = IPlayerWrapper & Player;
6
7
 
@@ -17,7 +18,6 @@ export class IPlayerWrapper {
17
18
  }
18
19
 
19
20
  //======================== Interal ========================
20
- public isAlive: boolean = false;
21
21
 
22
22
  public get inventory(): Inventory {
23
23
  const i = this.source.getComponent(
@@ -27,8 +27,14 @@ export class IPlayerWrapper {
27
27
  return ContainerWrapper.wrap(i.container);
28
28
  }
29
29
 
30
- public test(): void {
31
- this.source.sendMessage(`${this.source.name} was tested`);
30
+ public async playSoundAsync(sound:Sound, options: PlayerSoundOptions): Promise<void>{
31
+ this.source.playSound(sound.id, options);
32
+ await system.waitTicks(sound.length * TicksPerSecond);
33
+ }
34
+
35
+ public async playAnimationAsync(animation: Animation, options: PlayAnimationOptions): Promise<void> {
36
+ this.source.playAnimation(animation.id, options);
37
+ await system.waitTicks(animation.length * TicksPerSecond);
32
38
  }
33
39
 
34
40
  }
@@ -1,3 +1,4 @@
1
+ export { _INITIALIZE_BF_FRAMEWORK_ } from "@block_factory/lib/_module/Framework/_INIT";
1
2
  export { MathUtils } from "./util/Math";
2
3
  export { Signal } from "./util/Signal";
3
4
  export { Vec2, Vec3 } from "./util/Vector";
@@ -12,5 +13,7 @@ export { type IFormRegistration, RegisterForm } from "./util/Forms/FormRegistry"
12
13
  export { Inventory, ContainerWrapper } from "./util/Wrapper/Container";
13
14
  export { type IEntity, IEntityWrapper } from "./util/Wrapper/IEntity";
14
15
  export { type IPlayer, IPlayerWrapper } from "./util/Wrapper/IPlayer";
15
- export { _THREAD_ } from "./sys/Threads";
16
+ export { type Sound, type Animation } from "./Types";
17
+ export { _THREAD_ } from "@block_factory/lib/_module/Framework/Threads";
18
+ export { _EntityHandler_, type EntityEmissionEvent, onEntityEmission } from "@block_factory/lib/_module/Framework/EntityTasks";
16
19
  //# sourceMappingURL=BlockFactory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"BlockFactory.d.ts","sourceRoot":"","sources":["../../_module/BlockFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,KAAK,mBAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC9H,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC/K,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAC5F,OAAO,EAAE,KAAK,iBAAiB,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEjF,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,KAAK,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,KAAK,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAEtE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"BlockFactory.d.ts","sourceRoot":"","sources":["../../_module/BlockFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AAEvF,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,KAAK,mBAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC9H,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC/K,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAC5F,OAAO,EAAE,KAAK,iBAAiB,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEjF,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,KAAK,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,KAAK,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAEtE,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,8CAA8C,CAAC;AACxE,OAAO,EAAE,eAAe,EAAG,KAAK,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,kDAAkD,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { Entity } from "@minecraft/server";
2
+ import { Signal } from "../util/Signal";
3
+ import { IEntity } from "../util/Wrapper/IEntity";
4
+ export type EntityEmissionEvent = {
5
+ iEntity: IEntity;
6
+ parms: any;
7
+ };
8
+ export declare const onEntityEmission: Signal<EntityEmissionEvent>;
9
+ declare class EntityHandler {
10
+ private PACK_ID;
11
+ private GLOBAL_MEMORY_ID;
12
+ private readonly scriptEventSignal;
13
+ private readonly loadEventSignal;
14
+ private readonly spawnEventSignal;
15
+ private readonly removeAfterEventSignal;
16
+ private readonly removeBeforeEventSignal;
17
+ private readonly EM_INDEX;
18
+ private readonly EM_KEYS;
19
+ private readonly SEARCH_TYPES;
20
+ private _started;
21
+ private _wired;
22
+ configure(): void;
23
+ registerEntity(typeId: string | string[]): void;
24
+ start(): void;
25
+ stop(): void;
26
+ private onWorldLoad;
27
+ private processScriptEvents;
28
+ private isValidType;
29
+ private onEntitySpawned;
30
+ private onEntityRemovedBefore;
31
+ private onEntityRemovedAfter;
32
+ private reloadEntityMemory;
33
+ private persistKeys;
34
+ saveEntityInMemory(entity: Entity): boolean;
35
+ deleteEntityInMemory(entity: Entity): boolean;
36
+ getEntitiesInMemory(): Entity[];
37
+ }
38
+ export declare const _EntityHandler_: EntityHandler;
39
+ export {};
40
+ //# sourceMappingURL=EntityTasks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntityTasks.d.ts","sourceRoot":"","sources":["../../../_module/Framework/EntityTasks.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,MAAM,EAaT,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAkB,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAOlE,MAAM,MAAM,mBAAmB,GAAG;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,GAAG,CAAC;CACd,CAAC;AAEF,eAAO,MAAM,gBAAgB,6BAAoC,CAAC;AAQlE,cAAM,aAAa;IACf,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,gBAAgB,CAAoB;IAE5C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAoF;IACtH,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA0D;IAC1F,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA8D;IAC/F,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAgE;IACvG,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAkE;IAE1G,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6B;IACtD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAElD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAS;IAEhB,SAAS,IAAI,IAAI;IAIjB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI;IAK/C,KAAK,IAAI,IAAI;IAWb,IAAI,IAAI,IAAI;IAmBnB,OAAO,CAAC,WAAW,CAcjB;IAEF,OAAO,CAAC,mBAAmB,CAgBzB;IAMF,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,eAAe,CAIrB;IAEF,OAAO,CAAC,qBAAqB,CAI3B;IAEF,OAAO,CAAC,oBAAoB,CAE1B;IAMF,OAAO,CAAC,kBAAkB;IAsB1B,OAAO,CAAC,WAAW;IAIZ,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAU3C,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAY7C,mBAAmB,IAAI,MAAM,EAAE;CAGzC;AAED,eAAO,MAAM,eAAe,eAAsB,CAAC"}
@@ -1,14 +1,20 @@
1
1
  import { Signal } from "../util/Signal";
2
+ export type ThreadConfig = {
3
+ mainRate?: number;
4
+ lateRate?: number;
5
+ };
2
6
  declare class Threads {
3
- static create(): Threads;
4
7
  readonly MAIN: Signal<number>;
5
8
  readonly LATE: Signal<void>;
6
- MAIN_INTERVAL_RATE: number;
7
- LATE_INTERVAL_RATE: number;
9
+ private _mainRate;
10
+ private _lateRate;
8
11
  private _MAIN_ID;
9
12
  private _LATE_ID;
10
13
  private _delta;
11
- private constructor();
14
+ private _started;
15
+ configure(cfg: ThreadConfig): void;
16
+ start(): void;
17
+ stop(): void;
12
18
  private createDeltaTimer;
13
19
  }
14
20
  export declare const _THREAD_: Threads;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Threads.d.ts","sourceRoot":"","sources":["../../../_module/Framework/Threads.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,MAAM,MAAM,YAAY,GAAG;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,cAAM,OAAO;IACT,SAAgB,IAAI,iBAAwB;IAC5C,SAAgB,IAAI,eAAsB;IAE1C,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,SAAS,CAAkB;IAEnC,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,QAAQ,CAAqB;IAErC,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,QAAQ,CAAS;IAElB,SAAS,CAAC,GAAG,EAAE,YAAY;IAM3B,KAAK;IAwBL,IAAI;IASX,OAAO,CAAC,gBAAgB;CAS3B;AAED,eAAO,MAAM,QAAQ,SAAgB,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Initializes the Block Factory framework.
3
+ *
4
+ * This **must be called exactly once** before using any backend systems
5
+ * such as threads, entity tasks, or event routing.
6
+ *
7
+ * @param packId - Unique identifier for the active pack instance.
8
+ *
9
+ * @throws Error if the framework has already been initialized.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * _INITIALIZE_BF_FRAMEWORK_("bf:utility_tools");
14
+ * ```
15
+ */
16
+ export declare function _INITIALIZE_BF_FRAMEWORK_(packId: string): void;
17
+ export declare function getPackId(): string | undefined;
18
+ export declare function isInitalized(): boolean;
19
+ //# sourceMappingURL=_INIT.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_INIT.d.ts","sourceRoot":"","sources":["../../../_module/Framework/_INIT.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAI9D;AAMD,wBAAgB,SAAS,IAAI,MAAM,GAAG,SAAS,CAE9C;AAED,wBAAgB,YAAY,IAAI,OAAO,CAEtC"}
@@ -0,0 +1,10 @@
1
+ export type Sound = {
2
+ id: string;
3
+ length: number;
4
+ };
5
+ export type Animation = {
6
+ id: string;
7
+ length: number;
8
+ loop?: boolean;
9
+ };
10
+ //# sourceMappingURL=Types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Types.d.ts","sourceRoot":"","sources":["../../_module/Types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,KAAK,GAAG;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"Signal.d.ts","sourceRoot":"","sources":["../../../_module/util/Signal.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;AAE5C,qBAAa,MAAM,CAAC,CAAC,GAAG,IAAI;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;IAEpD,IAAW,KAAK,IAAI,MAAM,CAEzB;IAEM,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI;IAIpC,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO;IAI1C,KAAK,IAAI,IAAI;IAIb,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO;IAI3C,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI;CAK7B"}
1
+ {"version":3,"file":"Signal.d.ts","sourceRoot":"","sources":["../../../_module/util/Signal.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;AAE5C,qBAAa,MAAM,CAAC,CAAC,GAAG,IAAI;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;IAEpD,IAAW,KAAK,IAAI,MAAM,CAEzB;IAEM,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI;IAIpC,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO;IAI1C,KAAK,IAAI,IAAI;IAIb,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO;IAI3C,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI;CAO7B"}
@@ -1,12 +1,12 @@
1
- import { Entity } from "@minecraft/server";
1
+ import { Entity, PlayAnimationOptions } from "@minecraft/server";
2
2
  import { Inventory } from "./Container";
3
+ import { Animation } from "../../Types";
3
4
  export type IEntity = IEntityWrapper & Entity;
4
5
  export declare class IEntityWrapper {
5
6
  readonly source: Entity;
6
7
  private constructor();
7
8
  static wrap(source: Entity): IEntity;
8
- isAlive: boolean;
9
- get inventory(): Inventory;
10
- test(): void;
9
+ get inventory(): Inventory | undefined;
10
+ playAnimationAsync(animation: Animation, options: PlayAnimationOptions): Promise<void>;
11
11
  }
12
12
  //# sourceMappingURL=IEntity.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IEntity.d.ts","sourceRoot":"","sources":["../../../../_module/util/Wrapper/IEntity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA4B,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAoB,SAAS,EAAE,MAAM,aAAa,CAAC;AAG1D,MAAM,MAAM,OAAO,GAAG,cAAc,GAAG,MAAM,CAAC;AAE9C,qBAAa,cAAc;IACvB,SAAgB,MAAM,EAAE,MAAM,CAAC;IAE/B,OAAO;WAKO,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAKpC,OAAO,EAAE,OAAO,CAAS;IAEhC,IAAW,SAAS,IAAI,SAAS,CAMhC;IAEM,IAAI,IAAI,IAAI;CAItB"}
1
+ {"version":3,"file":"IEntity.d.ts","sourceRoot":"","sources":["../../../../_module/util/Wrapper/IEntity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA4B,oBAAoB,EAA0B,MAAM,mBAAmB,CAAC;AACnH,OAAO,EAAoB,SAAS,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,MAAM,OAAO,GAAG,cAAc,GAAG,MAAM,CAAC;AAE9C,qBAAa,cAAc;IACvB,SAAgB,MAAM,EAAE,MAAM,CAAC;IAE/B,OAAO;WAKO,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAM3C,IAAW,SAAS,IAAI,SAAS,GAAG,SAAS,CAM5C;IAEY,kBAAkB,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;CAKtG"}
@@ -1,12 +1,13 @@
1
- import { Player } from "@minecraft/server";
1
+ import { PlayAnimationOptions, Player, PlayerSoundOptions } from "@minecraft/server";
2
2
  import { Inventory } from "./Container";
3
+ import { Animation, Sound } from "../../Types";
3
4
  export type IPlayer = IPlayerWrapper & Player;
4
5
  export declare class IPlayerWrapper {
5
6
  readonly source: Player;
6
7
  private constructor();
7
8
  static wrap(player: Player): IPlayer;
8
- isAlive: boolean;
9
9
  get inventory(): Inventory;
10
- test(): void;
10
+ playSoundAsync(sound: Sound, options: PlayerSoundOptions): Promise<void>;
11
+ playAnimationAsync(animation: Animation, options: PlayAnimationOptions): Promise<void>;
11
12
  }
12
13
  //# sourceMappingURL=IPlayer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IPlayer.d.ts","sourceRoot":"","sources":["../../../../_module/util/Wrapper/IPlayer.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAoB,SAAS,EAAE,MAAM,aAAa,CAAC;AAG1D,MAAM,MAAM,OAAO,GAAG,cAAc,GAAG,MAAM,CAAC;AAE9C,qBAAa,cAAc;IACvB,SAAgB,MAAM,EAAE,MAAM,CAAC;IAE/B,OAAO;WAKO,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAKpC,OAAO,EAAE,OAAO,CAAS;IAEhC,IAAW,SAAS,IAAI,SAAS,CAMhC;IAEM,IAAI,IAAI,IAAI;CAItB"}
1
+ {"version":3,"file":"IPlayer.d.ts","sourceRoot":"","sources":["../../../../_module/util/Wrapper/IPlayer.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,oBAAoB,EAAE,MAAM,EAAE,kBAAkB,EAA0B,MAAM,mBAAmB,CAAC;AACvI,OAAO,EAAoB,SAAS,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,MAAM,OAAO,GAAG,cAAc,GAAG,MAAM,CAAC;AAE9C,qBAAa,cAAc;IACvB,SAAgB,MAAM,EAAE,MAAM,CAAC;IAE/B,OAAO;WAKO,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAM3C,IAAW,SAAS,IAAI,SAAS,CAMhC;IAEY,cAAc,CAAC,KAAK,EAAC,KAAK,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAKvE,kBAAkB,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;CAKtG"}
package/index.js CHANGED
@@ -1,8 +1,10 @@
1
1
  var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2
3
  var __export = (target, all) => {
3
4
  for (var name in all)
4
5
  __defProp(target, name, { get: all[name], enumerable: true });
5
6
  };
7
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
6
8
 
7
9
  // _module/BlockFactory.ts
8
10
  var BlockFactory_exports = {};
@@ -19,9 +21,22 @@ __export(BlockFactory_exports, {
19
21
  System: () => System,
20
22
  Vec2: () => Vec2,
21
23
  Vec3: () => Vec3,
22
- _THREAD_: () => _THREAD_
24
+ _EntityHandler_: () => _EntityHandler_,
25
+ _INITIALIZE_BF_FRAMEWORK_: () => _INITIALIZE_BF_FRAMEWORK_,
26
+ _THREAD_: () => _THREAD_,
27
+ onEntityEmission: () => onEntityEmission
23
28
  });
24
29
 
30
+ // _module/Framework/_INIT.ts
31
+ var IS_INITIALIZED = false;
32
+ var PACK_ID = void 0;
33
+ function _INITIALIZE_BF_FRAMEWORK_(packId) {
34
+ if (IS_INITIALIZED) throw Error(`CONFLICT WARNING: ${PACK_ID} already initialized.`);
35
+ PACK_ID = packId;
36
+ IS_INITIALIZED = true;
37
+ console.log("Block Factory Framework Loaded");
38
+ }
39
+
25
40
  // _module/util/Math.ts
26
41
  var MathUtils;
27
42
  ((MathUtils2) => {
@@ -95,7 +110,7 @@ var MathUtils;
95
110
  // _module/util/Signal.ts
96
111
  var Signal = class {
97
112
  constructor() {
98
- this.listeners = /* @__PURE__ */ new Set();
113
+ __publicField(this, "listeners", /* @__PURE__ */ new Set());
99
114
  }
100
115
  get count() {
101
116
  return this.listeners.size;
@@ -113,8 +128,12 @@ var Signal = class {
113
128
  return this.listeners.has(callback);
114
129
  }
115
130
  emit(data) {
116
- for (const cb of Array.from(this.listeners)) {
117
- cb(data);
131
+ for (const callback of Array.from(this.listeners)) {
132
+ try {
133
+ callback(data);
134
+ } catch (err) {
135
+ console.error("BFLIB: Signal listener error:", err);
136
+ }
118
137
  }
119
138
  }
120
139
  };
@@ -247,15 +266,15 @@ var _Vec2 = class _Vec2 {
247
266
  }
248
267
  };
249
268
  /** Constant zero vector (0, 0) */
250
- _Vec2.ZERO = new _Vec2(0, 0);
269
+ __publicField(_Vec2, "ZERO", new _Vec2(0, 0));
251
270
  /** Up direction (0, 1) */
252
- _Vec2.UP = new _Vec2(0, 1);
271
+ __publicField(_Vec2, "UP", new _Vec2(0, 1));
253
272
  /** Down direction (0, -1) */
254
- _Vec2.DOWN = new _Vec2(0, -1);
273
+ __publicField(_Vec2, "DOWN", new _Vec2(0, -1));
255
274
  /** Left direction (-1, 0) */
256
- _Vec2.LEFT = new _Vec2(-1, 0);
275
+ __publicField(_Vec2, "LEFT", new _Vec2(-1, 0));
257
276
  /** Right direction (1, 0) */
258
- _Vec2.RIGHT = new _Vec2(1, 0);
277
+ __publicField(_Vec2, "RIGHT", new _Vec2(1, 0));
259
278
  var Vec2 = _Vec2;
260
279
  var _Vec3 = class _Vec3 {
261
280
  /**
@@ -416,27 +435,27 @@ var _Vec3 = class _Vec3 {
416
435
  }
417
436
  };
418
437
  /** Constant zero vector (0, 0, 0) */
419
- _Vec3.ZERO = new _Vec3(0, 0, 0);
438
+ __publicField(_Vec3, "ZERO", new _Vec3(0, 0, 0));
420
439
  /** Up direction (0, 1, 0) */
421
- _Vec3.UP = new _Vec3(0, 1, 0);
440
+ __publicField(_Vec3, "UP", new _Vec3(0, 1, 0));
422
441
  /** Down direction (0, -1, 0) */
423
- _Vec3.DOWN = new _Vec3(0, -1, 0);
442
+ __publicField(_Vec3, "DOWN", new _Vec3(0, -1, 0));
424
443
  /** Left direction (-1, 0, 0) */
425
- _Vec3.LEFT = new _Vec3(-1, 0, 0);
444
+ __publicField(_Vec3, "LEFT", new _Vec3(-1, 0, 0));
426
445
  /** Right direction (1, 0, 0) */
427
- _Vec3.RIGHT = new _Vec3(1, 0, 0);
446
+ __publicField(_Vec3, "RIGHT", new _Vec3(1, 0, 0));
428
447
  /** Forward direction (0, 0, 1) */
429
- _Vec3.FORWARD = new _Vec3(0, 0, 1);
448
+ __publicField(_Vec3, "FORWARD", new _Vec3(0, 0, 1));
430
449
  /** Backward direction (0, 0, -1) */
431
- _Vec3.BACK = new _Vec3(0, 0, -1);
450
+ __publicField(_Vec3, "BACK", new _Vec3(0, 0, -1));
432
451
  /** West direction (-1, 0, 0) */
433
- _Vec3.WEST = new _Vec3(-1, 0, 0);
452
+ __publicField(_Vec3, "WEST", new _Vec3(-1, 0, 0));
434
453
  /** East direction (1, 0, 0) */
435
- _Vec3.EAST = new _Vec3(1, 0, 0);
454
+ __publicField(_Vec3, "EAST", new _Vec3(1, 0, 0));
436
455
  /** North direction (0, 0, 1) */
437
- _Vec3.NORTH = new _Vec3(0, 0, 1);
456
+ __publicField(_Vec3, "NORTH", new _Vec3(0, 0, 1));
438
457
  /** South direction (0, 0, -1) */
439
- _Vec3.SOUTH = new _Vec3(0, 0, -1);
458
+ __publicField(_Vec3, "SOUTH", new _Vec3(0, 0, -1));
440
459
  var Vec3 = _Vec3;
441
460
 
442
461
  // _module/util/RawText.ts
@@ -482,7 +501,7 @@ var RawText = class {
482
501
  /**
483
502
  * Common formatting and color codes.
484
503
  */
485
- RawText.FORMAT = {
504
+ __publicField(RawText, "FORMAT", {
486
505
  DarkRed: "\xA74",
487
506
  Red: "\xA7c",
488
507
  Gold: "\xA76",
@@ -505,7 +524,7 @@ RawText.FORMAT = {
505
524
  Italic: "\xA7o",
506
525
  Reset: "\xA7r",
507
526
  NewLine: "\n"
508
- };
527
+ });
509
528
 
510
529
  // _module/util/Command.ts
511
530
  import {
@@ -514,6 +533,14 @@ import {
514
533
  var Command;
515
534
  ((Command2) => {
516
535
  class ICustomCommand {
536
+ constructor() {
537
+ /** Whether cheats must be enabled */
538
+ __publicField(this, "cheatsRequired");
539
+ /** Required command parameters */
540
+ __publicField(this, "mandatoryParameters");
541
+ /** Optional command parameters */
542
+ __publicField(this, "optionalParameters");
543
+ }
517
544
  }
518
545
  Command2.ICustomCommand = ICustomCommand;
519
546
  ;
@@ -581,8 +608,8 @@ var _IForm = class _IForm {
581
608
  else _IForm.occupiedPlayers.delete(player.id);
582
609
  }
583
610
  };
584
- _IForm.occupiedPlayers = /* @__PURE__ */ new Set();
585
- _IForm.returnText = "Back";
611
+ __publicField(_IForm, "occupiedPlayers", /* @__PURE__ */ new Set());
612
+ __publicField(_IForm, "returnText", "Back");
586
613
  var IForm = _IForm;
587
614
 
588
615
  // _module/util/Forms/FormAction.ts
@@ -617,6 +644,7 @@ world2.afterEvents.itemUse.subscribe((event) => {
617
644
  // _module/util/Wrapper/Container.ts
618
645
  var ContainerWrapper = class _ContainerWrapper {
619
646
  constructor(source) {
647
+ __publicField(this, "source");
620
648
  this.source = source;
621
649
  return System.ProxyConstructor(this, source);
622
650
  }
@@ -638,83 +666,107 @@ var ContainerWrapper = class _ContainerWrapper {
638
666
  };
639
667
 
640
668
  // _module/util/Wrapper/IEntity.ts
641
- import { EntityInventoryComponent } from "@minecraft/server";
669
+ import { EntityInventoryComponent, system as system2, TicksPerSecond } from "@minecraft/server";
642
670
  var IEntityWrapper = class _IEntityWrapper {
643
671
  constructor(source) {
644
- //======================== Interal ========================
645
- this.isAlive = false;
672
+ __publicField(this, "source");
646
673
  this.source = source;
647
674
  return System.ProxyConstructor(this, source);
648
675
  }
649
676
  static wrap(source) {
650
677
  return new _IEntityWrapper(source);
651
678
  }
679
+ //======================== Interal ========================
652
680
  get inventory() {
653
681
  const i = this.source.getComponent(
654
682
  EntityInventoryComponent.componentId
655
683
  );
656
684
  return ContainerWrapper.wrap(i.container);
657
685
  }
658
- test() {
686
+ async playAnimationAsync(animation, options) {
687
+ this.source.playAnimation(animation.id, options);
688
+ await system2.waitTicks(animation.length * TicksPerSecond);
659
689
  }
660
690
  };
661
691
 
662
692
  // _module/util/Wrapper/IPlayer.ts
663
- import { EntityInventoryComponent as EntityInventoryComponent2 } from "@minecraft/server";
693
+ import { EntityInventoryComponent as EntityInventoryComponent2, system as system3, TicksPerSecond as TicksPerSecond2 } from "@minecraft/server";
664
694
  var IPlayerWrapper = class _IPlayerWrapper {
665
695
  constructor(source) {
666
- //======================== Interal ========================
667
- this.isAlive = false;
696
+ __publicField(this, "source");
668
697
  this.source = source;
669
698
  return System.ProxyConstructor(this, source);
670
699
  }
671
700
  static wrap(player) {
672
701
  return new _IPlayerWrapper(player);
673
702
  }
703
+ //======================== Interal ========================
674
704
  get inventory() {
675
705
  const i = this.source.getComponent(
676
706
  EntityInventoryComponent2.componentId
677
707
  );
678
708
  return ContainerWrapper.wrap(i.container);
679
709
  }
680
- test() {
681
- this.source.sendMessage(`${this.source.name} was tested`);
710
+ async playSoundAsync(sound, options) {
711
+ this.source.playSound(sound.id, options);
712
+ await system3.waitTicks(sound.length * TicksPerSecond2);
713
+ }
714
+ async playAnimationAsync(animation, options) {
715
+ this.source.playAnimation(animation.id, options);
716
+ await system3.waitTicks(animation.length * TicksPerSecond2);
682
717
  }
683
718
  };
684
719
 
685
- // _module/sys/Threads.ts
686
- import { system as system2, TicksPerSecond } from "@minecraft/server";
687
- var Threads = class _Threads {
720
+ // _module/Framework/Threads.ts
721
+ import { system as system4, TicksPerSecond as TicksPerSecond3 } from "@minecraft/server";
722
+ var Threads = class {
688
723
  constructor() {
689
- this.MAIN = new Signal();
690
- this.LATE = new Signal();
691
- this.MAIN_INTERVAL_RATE = 0;
692
- this.LATE_INTERVAL_RATE = TicksPerSecond;
693
- this._delta = this.createDeltaTimer();
694
- this._MAIN_ID = system2.runInterval(() => {
724
+ __publicField(this, "MAIN", new Signal());
725
+ __publicField(this, "LATE", new Signal());
726
+ __publicField(this, "_mainRate", 0);
727
+ __publicField(this, "_lateRate", TicksPerSecond3);
728
+ __publicField(this, "_MAIN_ID");
729
+ __publicField(this, "_LATE_ID");
730
+ __publicField(this, "_delta", this.createDeltaTimer());
731
+ __publicField(this, "_started", false);
732
+ }
733
+ configure(cfg) {
734
+ if (this._started) throw new Error("BFLIB: _THREAD_ already started; configure before start().");
735
+ if (cfg.mainRate !== void 0) this._mainRate = cfg.mainRate;
736
+ if (cfg.lateRate !== void 0) this._lateRate = cfg.lateRate;
737
+ }
738
+ start() {
739
+ if (this._started) return;
740
+ this._started = true;
741
+ this._MAIN_ID = system4.runInterval(() => {
695
742
  if (this.MAIN.count <= 0) return;
696
743
  try {
697
744
  const delta = this._delta();
698
745
  this.MAIN.emit(delta);
699
- } catch (error) {
700
- throw Error(`ERROR: _THREAD_.MAIN:${this._MAIN_ID} | ${error}`);
746
+ } catch (e) {
747
+ console.error(`ERROR: _THREAD_.MAIN:${this._MAIN_ID} |`, e);
701
748
  }
702
- }, this.MAIN_INTERVAL_RATE);
703
- this._LATE_ID = system2.runInterval(() => {
749
+ }, this._mainRate);
750
+ this._LATE_ID = system4.runInterval(() => {
704
751
  if (this.LATE.count <= 0) return;
705
752
  try {
706
753
  this.LATE.emit();
707
- } catch (error) {
708
- throw Error(`ERROR: _THREAD_.LATE:${this._LATE_ID} | ${error}`);
754
+ } catch (e) {
755
+ console.error(`ERROR: _THREAD_.LATE:${this._LATE_ID} |`, e);
709
756
  }
710
- }, this.LATE_INTERVAL_RATE);
711
- }
712
- static create() {
713
- return new _Threads();
757
+ }, this._lateRate);
758
+ }
759
+ stop() {
760
+ if (this._MAIN_ID !== void 0) system4.clearRun(this._MAIN_ID);
761
+ if (this._LATE_ID !== void 0) system4.clearRun(this._LATE_ID);
762
+ this._MAIN_ID = void 0;
763
+ this._LATE_ID = void 0;
764
+ this._started = false;
765
+ this._delta = this.createDeltaTimer();
714
766
  }
715
767
  createDeltaTimer() {
716
768
  let last = Date.now();
717
- return function nextDelta() {
769
+ return () => {
718
770
  const now = Date.now();
719
771
  const delta = (now - last) / 1e3;
720
772
  last = now;
@@ -722,7 +774,145 @@ var Threads = class _Threads {
722
774
  };
723
775
  }
724
776
  };
725
- var _THREAD_ = Threads.create();
777
+ var _THREAD_ = new Threads();
778
+
779
+ // _module/Framework/EntityTasks.ts
780
+ import {
781
+ system as system5,
782
+ world as world3
783
+ } from "@minecraft/server";
784
+ var onEntityEmission = new Signal();
785
+ var EntityHandler = class {
786
+ constructor() {
787
+ __publicField(this, "PACK_ID");
788
+ __publicField(this, "GLOBAL_MEMORY_ID", "GLB_MEM.ENTITY");
789
+ __publicField(this, "scriptEventSignal", system5.afterEvents.scriptEventReceive);
790
+ __publicField(this, "loadEventSignal", world3.afterEvents.worldLoad);
791
+ __publicField(this, "spawnEventSignal", world3.afterEvents.entitySpawn);
792
+ __publicField(this, "removeAfterEventSignal", world3.afterEvents.entityRemove);
793
+ __publicField(this, "removeBeforeEventSignal", world3.beforeEvents.entityRemove);
794
+ __publicField(this, "EM_INDEX", /* @__PURE__ */ new Map());
795
+ __publicField(this, "EM_KEYS", []);
796
+ __publicField(this, "SEARCH_TYPES", /* @__PURE__ */ new Set());
797
+ __publicField(this, "_started", false);
798
+ __publicField(this, "_wired", false);
799
+ /* ------------------------------------------------------------------------ */
800
+ /* Event Wiring */
801
+ /* ------------------------------------------------------------------------ */
802
+ __publicField(this, "onWorldLoad", (_event) => {
803
+ this.scriptEventSignal.subscribe(this.processScriptEvents);
804
+ if (this.SEARCH_TYPES.size > 0) {
805
+ this.spawnEventSignal.subscribe(this.onEntitySpawned);
806
+ this.removeBeforeEventSignal.subscribe(this.onEntityRemovedBefore);
807
+ this.removeAfterEventSignal.subscribe(this.onEntityRemovedAfter);
808
+ }
809
+ this._wired = true;
810
+ this.reloadEntityMemory();
811
+ this.loadEventSignal.unsubscribe(this.onWorldLoad);
812
+ });
813
+ __publicField(this, "processScriptEvents", (event) => {
814
+ if (!event.sourceEntity) return;
815
+ if (event.id !== `${this.PACK_ID}:entity_emitter`) return;
816
+ let parms;
817
+ try {
818
+ parms = JSON.parse(event.message);
819
+ } catch (e) {
820
+ console.error(`BFLIB: entity_emitter JSON parse failed:`, e);
821
+ return;
822
+ }
823
+ onEntityEmission.emit({
824
+ iEntity: IEntityWrapper.wrap(event.sourceEntity),
825
+ parms
826
+ });
827
+ });
828
+ __publicField(this, "onEntitySpawned", (event) => {
829
+ const entity = event.entity;
830
+ if (!this.isValidType(entity.typeId)) return;
831
+ this.saveEntityInMemory(entity);
832
+ });
833
+ __publicField(this, "onEntityRemovedBefore", (event) => {
834
+ const entity = event.removedEntity;
835
+ if (!this.isValidType(entity.typeId)) return;
836
+ this.deleteEntityInMemory(entity);
837
+ });
838
+ __publicField(this, "onEntityRemovedAfter", (_event) => {
839
+ });
840
+ }
841
+ configure() {
842
+ if (this._started) throw new Error("BFLIB: EntityHandler already started;");
843
+ }
844
+ registerEntity(typeId) {
845
+ if (Array.isArray(typeId)) typeId.forEach((t) => this.SEARCH_TYPES.add(t));
846
+ else this.SEARCH_TYPES.add(typeId);
847
+ }
848
+ start(packId) {
849
+ if (this._started) return;
850
+ this._started = true;
851
+ this.PACK_ID = packId;
852
+ this.loadEventSignal.subscribe(this.onWorldLoad);
853
+ }
854
+ stop() {
855
+ if (!this._started) return;
856
+ this.loadEventSignal.unsubscribe(this.onWorldLoad);
857
+ if (this._wired) {
858
+ this.scriptEventSignal.unsubscribe(this.processScriptEvents);
859
+ this.spawnEventSignal.unsubscribe(this.onEntitySpawned);
860
+ this.removeBeforeEventSignal.unsubscribe(this.onEntityRemovedBefore);
861
+ this.removeAfterEventSignal.unsubscribe(this.onEntityRemovedAfter);
862
+ this._wired = false;
863
+ }
864
+ this._started = false;
865
+ }
866
+ /* ------------------------------------------------------------------------ */
867
+ /* Filters */
868
+ /* ------------------------------------------------------------------------ */
869
+ isValidType(typeId) {
870
+ return this.SEARCH_TYPES.has(typeId);
871
+ }
872
+ /* ------------------------------------------------------------------------ */
873
+ /* Persistence */
874
+ /* ------------------------------------------------------------------------ */
875
+ reloadEntityMemory() {
876
+ this.EM_INDEX.clear();
877
+ this.EM_KEYS.length = 0;
878
+ const raw = world3.getDynamicProperty(this.GLOBAL_MEMORY_ID);
879
+ if (!raw) return;
880
+ let parsed;
881
+ try {
882
+ parsed = JSON.parse(raw);
883
+ } catch (e) {
884
+ console.error(`BFLIB: Failed to parse ${this.GLOBAL_MEMORY_ID}:`, e);
885
+ return;
886
+ }
887
+ for (const id of parsed) {
888
+ this.EM_KEYS.push(id);
889
+ const entity = world3.getEntity(id);
890
+ if (entity) this.EM_INDEX.set(entity.id, entity);
891
+ }
892
+ }
893
+ persistKeys() {
894
+ world3.setDynamicProperty(this.GLOBAL_MEMORY_ID, JSON.stringify(this.EM_KEYS));
895
+ }
896
+ saveEntityInMemory(entity) {
897
+ if (this.EM_INDEX.has(entity.id)) return false;
898
+ this.EM_KEYS.push(entity.id);
899
+ this.EM_INDEX.set(entity.id, entity);
900
+ this.persistKeys();
901
+ return true;
902
+ }
903
+ deleteEntityInMemory(entity) {
904
+ const existed = this.EM_INDEX.delete(entity.id);
905
+ if (!existed) return false;
906
+ const idx = this.EM_KEYS.indexOf(entity.id);
907
+ if (idx !== -1) this.EM_KEYS.splice(idx, 1);
908
+ this.persistKeys();
909
+ return true;
910
+ }
911
+ getEntitiesInMemory() {
912
+ return Array.from(this.EM_INDEX.values());
913
+ }
914
+ };
915
+ var _EntityHandler_ = new EntityHandler();
726
916
  export {
727
917
  BlockFactory_exports as BlockFactory,
728
918
  Command,
@@ -737,5 +927,8 @@ export {
737
927
  System,
738
928
  Vec2,
739
929
  Vec3,
740
- _THREAD_
930
+ _EntityHandler_,
931
+ _INITIALIZE_BF_FRAMEWORK_,
932
+ _THREAD_,
933
+ onEntityEmission
741
934
  };
package/package.json CHANGED
@@ -1,34 +1,34 @@
1
- {
2
- "name": "@block_factory/lib",
3
- "version": "0.0.4",
4
- "main": "index.js",
5
- "types": "index.d.ts",
6
- "description": "Typescript Library for Minecraft Bedrock Edition",
7
- "repository": {
8
- "type": "git",
9
- "url": "git+https://github.com/Block-Factory-Studio/bf-lib.git"
10
- },
11
- "author": "Block Factory x Donthedev",
12
- "contributors": [
13
- {
14
- "name": "Donthedev",
15
- "email": "donthedev@blockfactory.studio"
16
- }
17
- ],
18
- "license": "MIT",
19
- "bugs": {
20
- "url": "https://github.com/Block-Factory-Studio/bf-mcbr-library/issues"
21
- },
22
- "homepage": "https://github.com/Block-Factory-Studio/bf-mcbr-library#readme",
23
- "dependencies": {
24
- "@minecraft/server": "^2.4.0",
25
- "@minecraft/server-ui": "^2.0.0"
26
- },
27
- "devDependencies": {
28
- "esbuild": "^0.25.9"
29
- },
30
- "scripts": {
31
- "build": "node esbuild.config.mjs",
32
- "build:types": "tsc -p tsconfig.types.json"
33
- }
34
- }
1
+ {
2
+ "name": "@block_factory/lib",
3
+ "version": "0.0.5",
4
+ "main": "index.js",
5
+ "types": "index.d.ts",
6
+ "description": "Typescript Library for Minecraft Bedrock Edition",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/Block-Factory-Studio/bf-lib.git"
10
+ },
11
+ "author": "Block Factory x Donthedev",
12
+ "contributors": [
13
+ {
14
+ "name": "Donthedev",
15
+ "email": "donthedev@blockfactory.studio"
16
+ }
17
+ ],
18
+ "license": "MIT",
19
+ "bugs": {
20
+ "url": "https://github.com/Block-Factory-Studio/bf-mcbr-library/issues"
21
+ },
22
+ "homepage": "https://github.com/Block-Factory-Studio/bf-mcbr-library#readme",
23
+ "dependencies": {
24
+ "@minecraft/server": "^2.4.0",
25
+ "@minecraft/server-ui": "^2.0.0"
26
+ },
27
+ "devDependencies": {
28
+ "esbuild": "^0.25.9"
29
+ },
30
+ "scripts": {
31
+ "build": "node esbuild.config.mjs",
32
+ "build:types": "tsc -p tsconfig.types.json"
33
+ }
34
+ }
@@ -1,43 +0,0 @@
1
- import { system, TicksPerSecond } from "@minecraft/server";
2
- import { Signal } from "../util/Signal";
3
-
4
- class Threads {
5
- public static create(): Threads { return new Threads() }
6
- public readonly MAIN = new Signal<number>();
7
- public readonly LATE = new Signal();
8
- public MAIN_INTERVAL_RATE: number = 0;
9
- public LATE_INTERVAL_RATE: number = TicksPerSecond;
10
-
11
- private _MAIN_ID: number;
12
- private _LATE_ID: number;
13
- private _delta = this.createDeltaTimer();
14
-
15
- private constructor() {
16
- this._MAIN_ID = system.runInterval(() => {
17
- if (this.MAIN.count <= 0) return;
18
- try { const delta = this._delta(); this.MAIN.emit(delta) }
19
- catch (error) {
20
- throw Error(`ERROR: _THREAD_.MAIN:${this._MAIN_ID} | ${error}`)
21
- }
22
- }, this.MAIN_INTERVAL_RATE);
23
-
24
- this._LATE_ID = system.runInterval(() => {
25
- if (this.LATE.count <= 0) return;
26
- try { this.LATE.emit() }
27
- catch (error) { throw Error(`ERROR: _THREAD_.LATE:${this._LATE_ID} | ${error}`) }
28
- }, this.LATE_INTERVAL_RATE);
29
- }
30
-
31
- private createDeltaTimer() {
32
- let last = Date.now();
33
-
34
- return function nextDelta(): number {
35
- const now = Date.now();
36
- const delta = (now - last) / 1000; // seconds
37
- last = now;
38
- return delta;
39
- };
40
- }
41
- }
42
-
43
- export const _THREAD_ = Threads.create();
@@ -1 +0,0 @@
1
- {"version":3,"file":"Threads.d.ts","sourceRoot":"","sources":["../../../_module/sys/Threads.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,cAAM,OAAO;WACK,MAAM,IAAI,OAAO;IAC/B,SAAgB,IAAI,iBAAwB;IAC5C,SAAgB,IAAI,eAAgB;IAC7B,kBAAkB,EAAE,MAAM,CAAK;IAC/B,kBAAkB,EAAE,MAAM,CAAkB;IAEnD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAA2B;IAEzC,OAAO;IAgBP,OAAO,CAAC,gBAAgB;CAU3B;AAED,eAAO,MAAM,QAAQ,SAAmB,CAAC"}