Compare commits

...

5 Commits

14 changed files with 388 additions and 195 deletions

30
bun.lock Normal file
View File

@@ -0,0 +1,30 @@
{
"lockfileVersion": 1,
"configVersion": 1,
"workspaces": {
"": {
"devDependencies": {
"oxlint": "^1.39.0",
},
},
},
"packages": {
"@oxlint/darwin-arm64": ["@oxlint/darwin-arm64@1.39.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-lT3hNhIa02xCujI6YGgjmYGg3Ht/X9ag5ipUVETaMpx5Rd4BbTNWUPif1WN1YZHxt3KLCIqaAe7zVhatv83HOQ=="],
"@oxlint/darwin-x64": ["@oxlint/darwin-x64@1.39.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-UT+rfTWd+Yr7iJeSLd/7nF8X4gTYssKh+n77hxl6Oilp3NnG1CKRHxZDy3o3lIBnwgzJkdyUAiYWO1bTMXQ1lA=="],
"@oxlint/linux-arm64-gnu": ["@oxlint/linux-arm64-gnu@1.39.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-qocBkvS2V6rH0t9AT3DfQunMnj3xkM7srs5/Ycj2j5ZqMoaWd/FxHNVJDFP++35roKSvsRJoS0mtA8/77jqm6Q=="],
"@oxlint/linux-arm64-musl": ["@oxlint/linux-arm64-musl@1.39.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-arZzAc1PPcz9epvGBBCMHICeyQloKtHX3eoOe62B3Dskn7gf6Q14wnDHr1r9Vp4vtcBATNq6HlKV14smdlC/qA=="],
"@oxlint/linux-x64-gnu": ["@oxlint/linux-x64-gnu@1.39.0", "", { "os": "linux", "cpu": "x64" }, "sha512-ZVt5qsECpuNprdWxAPpDBwoixr1VTcZ4qAEQA2l/wmFyVPDYFD3oBY/SWACNnWBddMrswjTg9O8ALxYWoEpmXw=="],
"@oxlint/linux-x64-musl": ["@oxlint/linux-x64-musl@1.39.0", "", { "os": "linux", "cpu": "x64" }, "sha512-pB0hlGyKPbxr9NMIV783lD6cWL3MpaqnZRM9MWni4yBdHPTKyFNYdg5hGD0Bwg+UP4S2rOevq/+OO9x9Bi7E6g=="],
"@oxlint/win32-arm64": ["@oxlint/win32-arm64@1.39.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-Gg2SFaJohI9+tIQVKXlPw3FsPQFi/eCSWiCgwPtPn5uzQxHRTeQEZKuluz1fuzR5U70TXubb2liZi4Dgl8LJQA=="],
"@oxlint/win32-x64": ["@oxlint/win32-x64@1.39.0", "", { "os": "win32", "cpu": "x64" }, "sha512-sbi25lfj74hH+6qQtb7s1wEvd1j8OQbTaH8v3xTcDjrwm579Cyh0HBv1YSZ2+gsnVwfVDiCTL1D0JsNqYXszVA=="],
"oxlint": ["oxlint@1.39.0", "", { "optionalDependencies": { "@oxlint/darwin-arm64": "1.39.0", "@oxlint/darwin-x64": "1.39.0", "@oxlint/linux-arm64-gnu": "1.39.0", "@oxlint/linux-arm64-musl": "1.39.0", "@oxlint/linux-x64-gnu": "1.39.0", "@oxlint/linux-x64-musl": "1.39.0", "@oxlint/win32-arm64": "1.39.0", "@oxlint/win32-x64": "1.39.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.10.0" }, "optionalPeers": ["oxlint-tsgolint"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-wSiLr0wjG+KTU6c1LpVoQk7JZ7l8HCKlAkVDVTJKWmCGazsNxexxnOXl7dsar92mQcRnzko5g077ggP3RINSjA=="],
}
}

View File

@@ -1,14 +1,16 @@
{ {
"$schema": "https://www.schemastore.org/jsconfig.json", "$schema": "https://www.schemastore.org/jsconfig.json",
"compilerOptions": { "compilerOptions": {
"lib": ["ES5", "ES2015"],
"target": "ES2015",
"module": "commonjs", "module": "commonjs",
"strict": true, "skipDefaultLibCheck": true,
"checkJs": true, "moduleResolution": "classic",
"composite": true,
"isolatedModules": true,
"lib": ["ES5", "ES2015"],
"incremental": true,
"target": "ES2015",
"skipLibCheck": true, "skipLibCheck": true,
"noImplicitAny": true, "rootDir": ".",
"esModuleInterop": true, "allowJs": true
"forceConsistentCasingInFileNames": true
} }
} }

6
package.json Normal file
View File

@@ -0,0 +1,6 @@
{
"dependencies": {},
"devDependencies": {
"oxlint": "^1.39.0"
}
}

View File

@@ -1,5 +1,6 @@
{ {
"block.kubejs.c4_target": "C4 Target Block", "block.kubejs.c4_target": "C4 Target Block",
"block.kubejs.c4": "C4", "block.kubejs.c4": "C4",
"item.kubejs.c4_item": "C4" "item.kubejs.c4_item": "C4",
"item.kubejs.c4_defuser": "C4 Defuser"
} }

View File

@@ -1,5 +1,6 @@
{ {
"block.kubejs.c4_target": "C4 Target Block", "block.kubejs.c4_target": "C4 Target Block",
"block.kubejs.c4": "C4", "block.kubejs.c4": "C4",
"item.kubejs.c4_item": "C4" "item.kubejs.c4_item": "C4",
"item.kubejs.c4_defuser": "C4 Defuser"
} }

View File

@@ -0,0 +1,18 @@
let isFirstTime = true;
ClientEvents.tick((event) => {
if (!isFirstTime) return;
const player = event.player;
const lookAngle = player.lookAngle;
console.log(`Player Pos: ${player.x}, ${player.y}, ${player.z}`);
// console.log(
// `LookAngle(property): ${lookAngle.x}, ${lookAngle.y}, ${lookAngle.z}`,
// );
console.log(
`LookAngle(method): ${lookAngle.x()}, ${lookAngle.y()}, ${lookAngle.z()}`,
);
console.log(
`LookAngle(get method): ${lookAngle.get("x")}, ${lookAngle.get("y")}, ${lookAngle.get("z")}`,
);
isFirstTime = false;
});

View File

@@ -1,11 +1,19 @@
{ {
"$schema": "https://www.schemastore.org/jsconfig.json", "$schema": "https://www.schemastore.org/jsconfig.json",
"extends": "../../jsconfig.json", "extends": "../../jsconfig.json",
"compilerOptions": {}, "compilerOptions": {
"include": [ "types": [
"./**/*", "../../types/probe/client/packages",
"../../types/*.d.ts", "../../types/probe/client/global",
"../../types/probe/shared/*.d.ts", "../../types/probe/shared"
"../../types/probe/client/**/*.d.ts" ],
"paths": {
"packages/*": [
"../../types/probe/client/packages/*",
"../../types/probe/shared/*"
] ]
} }
},
"include": ["./**/*.js", "../../types/*.d.ts"],
"exclude": []
}

234
src/server_scripts/C4.js Normal file
View File

@@ -0,0 +1,234 @@
/**
* C4 Server Scripts
* Handles C4 block break event to cancel explosion
* Handles C4 use started and activated events
*/
// ==================== Block Break Event Handler ====================
BlockEvents.broken((event) => {
const { block, server } = event;
// Check if the broken block is a C4
if (block.id !== "kubejs:c4") {
return;
}
// Get the toExplosionC4Map from global
/** @type {{[key:string]: boolean | null}} */
const toExplosionC4Map = /** @type {any} */ (global["toExplosionC4Map"]);
if (toExplosionC4Map === undefined || toExplosionC4Map === null) {
console.warn("C4 Server: toExplosionC4Map is not available");
return;
}
// Get the block position string
const blockPosString = block.pos.toShortString();
// Check if this C4 is in the explosion map
if (toExplosionC4Map[blockPosString] === true) {
// Set to null to cancel the explosion
// The explosion timer checks for === null to skip explosion
toExplosionC4Map[blockPosString] = null;
// Notify players that C4 has been defused
if (server !== null) {
server.players.forEach((player) => {
player.tell(
/** @type {any} */ (
Component.literal("§aC4已被拆除爆炸已取消")
),
);
});
} else {
console.warn("C4 Server: Server is null");
}
}
});
// ==================== C4 Event Handlers ====================
/**
* @param {{player: Internal.Player}} event
*/
function handleC4UseStarted(event) {
const server = Utils.getServer();
if (server === null) {
console.error("C4 Handler: Server is not available");
return;
}
// Get shared variables from global
/** @type {typeof shouldActivateC4} */
const shouldActivateC4 = /** @type {any} */ (global["shouldActivateC4"]);
/** @type {typeof shouldStartUseC4} */
const shouldStartUseC4 = /** @type {any} */ (global["shouldStartUseC4"]);
/** @type {{ [key: string]: any }} */
const lastPlayerInfoMap = /** @type {any} */ (global["lastPlayerInfoMap"]);
/** @type {number} */
const C4_USE_TIME = /** @type {any} */ (global["C4_USE_TIME"]);
if (
shouldActivateC4 === undefined ||
shouldStartUseC4 === undefined ||
lastPlayerInfoMap === undefined ||
C4_USE_TIME === undefined
) {
console.error("C4 Handler: Required global variables not available");
return;
}
const player = server.getPlayerList().getPlayer(event.player.uuid);
const level = player.level;
const startTime = level.levelData.gameTime;
const originalItemstack = player.mainHandItem;
server.scheduleRepeatingInTicks(2, (event) => {
const itemstack = player.getMainHandItem();
if (
!shouldActivateC4(
itemstack,
player.level,
/** @type {any} */ (player),
)
) {
player.stopUsingItem();
player.addItemCooldown(originalItemstack.item, 20);
originalItemstack.releaseUsing(
level,
/** @type {any} */ (player),
originalItemstack.count,
);
event.clear();
return;
}
// Get remaining ticks for this use
const remainingTicks =
C4_USE_TIME - (level.levelData.gameTime - startTime);
if (remainingTicks <= 0) {
originalItemstack.finishUsingItem(
level,
/** @type {any} */ (player),
);
delete lastPlayerInfoMap[player.uuid.toString()];
event.clear();
return;
}
itemstack.setHoverName(
/** @type {any} */ (
Component.literal(`C4 - ${(remainingTicks / 20.0).toFixed(1)}s`)
),
);
});
}
/**
* Handle C4 activation event
* @param {C4ActivatedEvent} event
*/
function handleC4Activated(event) {
const server = Utils.getServer();
if (server === null) {
console.error("C4 Handler: Server is not available");
return;
}
const { level, player, explosionTime, explosionPower } = event;
// Get shared variables from global
/** @type {{[key:string]: boolean | null}} */
const toExplosionC4Map = /** @type {any} */ (global["toExplosionC4Map"]);
if (toExplosionC4Map === undefined || toExplosionC4Map === null) {
console.error("C4 Handler: toExplosionC4Map is not available");
return;
}
// Place C4 at player's feet
const c4BlockPos = {
x: Math.floor(player.x),
y: Math.floor(player.y),
z: Math.floor(player.z),
};
const newBlock = level.getBlock(c4BlockPos.x, c4BlockPos.y, c4BlockPos.z);
newBlock.set(/** @type {any} */ ("kubejs:c4"));
// Add record
const newBlockPosString = newBlock.pos.toShortString();
toExplosionC4Map[newBlockPosString] = true;
/**
* TODO: It should use reschedule to replace several schedules
* But reschedule not work at current time.
* Relative Issue: https://github.com/KubeJS-Mods/KubeJS/issues/763
*/
let remainingSeconds = explosionTime / 20;
server.scheduleRepeatingInTicks(20, (scheduledEvent) => {
// Assert C4 exsiting
if (toExplosionC4Map[newBlockPosString] === null) {
scheduledEvent.clear();
return;
}
remainingSeconds -= 1;
if (remainingSeconds <= 0) {
scheduledEvent.clear();
return;
}
server.players.forEach((p) => {
p.tell(
/** @type {any} */ (
Component.literal(`C4还剩 ${remainingSeconds} 秒爆炸`)
),
);
});
});
// Create explosion after countdown
server.scheduleInTicks(explosionTime, (_) => {
// Assert C4 exsiting
if (toExplosionC4Map[newBlockPosString] === null) return;
level.explode(
/** @type {any} */ (null),
c4BlockPos.x + 0.5,
c4BlockPos.y + 0.5,
c4BlockPos.z + 0.5,
explosionPower,
"block",
);
});
}
// ==================== Server Initialization ====================
ServerEvents.loaded((event) => {
/**
* WARNING: Must Do!!!
* Because Kubejs scheduler is not stable
* And need to fire once at first time
* Relative Issue: https://github.com/KubeJS-Mods/KubeJS/issues/763
*/
event.server.scheduleInTicks(1, (_) => {
console.log("Init Scheduler");
});
/** @type {EventBus} */
const eventBus = /** @type {any} */ (global["eventBus"]);
if (eventBus === null) {
console.error("C4 Handler: eventBus is not available");
return;
}
eventBus.register("C4Activated", handleC4Activated);
eventBus.register("C4UseStarted", handleC4UseStarted);
console.log("C4 Handler: Registered C4Activated event handler");
});

View File

@@ -1,10 +1,19 @@
{ {
"$schema": "https://www.schemastore.org/jsconfig.json", "$schema": "https://www.schemastore.org/jsconfig.json",
"extends": "../../jsconfig.json", "extends": "../../jsconfig.json",
"include": [ "compilerOptions": {
"./**/*", "types": [
"../../types/*.d.ts", "../../types/probe/server/packages",
"../../types/probe/shared/*.d.ts", "../../types/probe/server/global",
"../../types/probe/server/**/*.d.ts" "../../types/probe/shared"
],
"paths": {
"packages/*": [
"../../types/probe/server/packages/*",
"../../types/probe/shared/*"
] ]
} }
},
"include": ["./**/*.js", "../../types/*.d.ts"],
"exclude": []
}

View File

@@ -1,16 +1,16 @@
/** @type {JClass_<$TickEvent$PlayerTickEvent_>} */
const $TickEvent$PlayerTickEvent = Java.loadClass( const $TickEvent$PlayerTickEvent = Java.loadClass(
"net.minecraftforge.event.TickEvent$PlayerTickEvent", "net.minecraftforge.event.TickEvent$PlayerTickEvent",
); );
const $ServerStartedEvent = Java.loadClass( const C4_EXPLOSION_TIME = 10 * 20; // 7 seconds in ticks
"net.minecraftforge.event.server.ServerStartedEvent",
);
const C4_EXPLOSION_TIME = 3 * 20; // 3 seconds in ticks
const C4_EXPLOSION_POWER = 128; // Explosion power (TNT is 4) const C4_EXPLOSION_POWER = 128; // Explosion power (TNT is 4)
const C4_USE_TIME = 5 * 20; // 5 seconds in ticks const C4_USE_TIME = 5 * 20; // 5 seconds in ticks
// Export constants for server scripts
global["C4_EXPLOSION_TIME"] = C4_EXPLOSION_TIME;
global["C4_EXPLOSION_POWER"] = C4_EXPLOSION_POWER;
global["C4_USE_TIME"] = C4_USE_TIME;
// Tolerance for floating point comparison // Tolerance for floating point comparison
const ANGLE_TOLERANCE = 0.001; const ANGLE_TOLERANCE = 0.001;
const POS_TOLERANCE = 0.01; const POS_TOLERANCE = 0.01;
@@ -29,6 +29,15 @@ let operationKeyMapping;
*/ */
const lastPlayerInfoMap = {}; const lastPlayerInfoMap = {};
// Export for server scripts
global["lastPlayerInfoMap"] = lastPlayerInfoMap;
/**
* @type {{[key:string]: boolean}}
*/
const toExplosionC4Map = {};
global["toExplosionC4Map"] = toExplosionC4Map;
/** /**
* Helper function to compare floating point numbers with tolerance * Helper function to compare floating point numbers with tolerance
* @param {number} a * @param {number} a
@@ -109,6 +118,9 @@ function shouldActivateC4(itemstack, level, player) {
); );
} }
// Export for server scripts
global["shouldActivateC4"] = shouldActivateC4;
/** /**
* @param {Internal.Player} player * @param {Internal.Player} player
* @param {Internal.Level} level * @param {Internal.Level} level
@@ -145,6 +157,9 @@ function shouldStartUseC4(player, level) {
return true; return true;
} }
// Export for server scripts
global["shouldStartUseC4"] = shouldStartUseC4;
// ==================== Block Registration ==================== // ==================== Block Registration ====================
StartupEvents.registry("block", (event) => { StartupEvents.registry("block", (event) => {
@@ -153,13 +168,13 @@ StartupEvents.registry("block", (event) => {
.soundType(SoundType.WOOD) // Set a material (affects the sounds and some properties) .soundType(SoundType.WOOD) // Set a material (affects the sounds and some properties)
.unbreakable() .unbreakable()
.textureAll("minecraft:block/target_top"); .textureAll("minecraft:block/target_top");
});
StartupEvents.registry("block", (event) => {
event event
.create("c4") // Create a new block .create("c4") // Create a new block
.soundType(SoundType.GRASS) // Set a material (affects the sounds and some properties) .soundType(SoundType.GRASS) // Set a material (affects the sounds and some properties)
.hardness(1) // Set hardness (affects mining time) .hardness(1) // Set hardness (affects mining time)
.requiresTool(true)
.tagBlock("minecraft:mineable/axe") //can be mined faster with an axe
.resistance(1) // Set resistance (to explosions, etc) .resistance(1) // Set resistance (to explosions, etc)
.noItem() // Player cannot hold or place the item .noItem() // Player cannot hold or place the item
.noDrops() .noDrops()
@@ -224,6 +239,8 @@ StartupEvents.registry("item", (event) => {
if (!entity.isPlayer() || entity.uuid === undefined) return; if (!entity.isPlayer() || entity.uuid === undefined) return;
delete lastPlayerInfoMap[entity.uuid.toString()]; delete lastPlayerInfoMap[entity.uuid.toString()];
}); });
event.create("c4_defuser", "axe").attackDamageBaseline(0).maxDamage(0);
}); });
// ==================== Client Side Logic ==================== // ==================== Client Side Logic ====================
@@ -256,7 +273,7 @@ ClientEvents.init(() => {
ForgeEvents.onEvent($TickEvent$PlayerTickEvent, (event) => { ForgeEvents.onEvent($TickEvent$PlayerTickEvent, (event) => {
if (operationKeyMapping === undefined) { if (operationKeyMapping === undefined) {
console.warn("Not in client platform"); console.warn("Not in client platform");
return; return event;
} }
while (operationKeyMapping.consumeClick()) { while (operationKeyMapping.consumeClick()) {
@@ -273,142 +290,3 @@ ForgeEvents.onEvent($TickEvent$PlayerTickEvent, (event) => {
} }
} }
}); });
// ==================== Server Side Logic ====================
/**
* @param {{player: Internal.Player}} event
*/
function handleC4UseStarted(event) {
const server = Utils.getServer();
if (server === null) {
console.error("C4 Handler: Server is not available");
return;
}
const player = server.getPlayerList().getPlayer(event.player.uuid);
const level = player.level;
const startTime = level.levelData.gameTime;
const originalItemstack = player.mainHandItem;
server.scheduleRepeatingInTicks(2, (event) => {
const itemstack = player.getMainHandItem();
if (
!shouldActivateC4(
itemstack,
player.level,
/** @type {any} */ (player),
)
) {
player.stopUsingItem();
player.addItemCooldown(originalItemstack.item, 20);
originalItemstack.releaseUsing(
level,
/** @type {any} */ (player),
originalItemstack.count,
);
event.clear();
return;
}
// Get remaining ticks for this use
const remainingTicks =
C4_USE_TIME - (level.levelData.gameTime - startTime);
if (remainingTicks <= 0) {
originalItemstack.finishUsingItem(
level,
/** @type {any} */ (player),
);
delete lastPlayerInfoMap[player.uuid.toString()];
event.clear();
return;
}
itemstack.setHoverName(
/** @type {any} */ (
Component.literal(`C4 - ${(remainingTicks / 20.0).toFixed(1)}s`)
),
);
});
}
/**
* Handle C4 activation event
* @param {C4ActivatedEvent} event
*/
function handleC4Activated(event) {
const server = Utils.getServer();
if (server === null) {
console.error("C4 Handler: Server is not available");
return;
}
const { level, player, explosionTime, explosionPower } = event;
// Place C4 at player's feet
const c4BlockPos = {
x: Math.floor(player.x),
y: Math.floor(player.y),
z: Math.floor(player.z),
};
const newBlock = level.getBlock(c4BlockPos.x, c4BlockPos.y, c4BlockPos.z);
newBlock.set(/** @type {any} */ ("kubejs:c4"));
/**
* TODO: It should use reschedule to replace several schedules
* But reschedule not work at current time.
* Relative Issue: https://github.com/KubeJS-Mods/KubeJS/issues/763
*/
for (let i = 0; i < explosionTime; i += 20) {
server.scheduleInTicks(i, (scheduledEvent) => {
const remainingSeconds =
(explosionTime - scheduledEvent.timer) / 20;
server.players.forEach((p) => {
p.tell(
/** @type {any} */ (
Component.literal(`C4还剩 ${remainingSeconds} 秒爆炸`)
),
);
});
});
}
// Create explosion after countdown
server.scheduleInTicks(explosionTime, (_) => {
level.explode(
/** @type {any} */ (null),
c4BlockPos.x + 0.5,
c4BlockPos.y + 0.5,
c4BlockPos.z + 0.5,
explosionPower,
"block",
);
});
}
ForgeEvents.onEvent($ServerStartedEvent, (event) => {
/**
* WARNING: Must Do!!!
* Because Kubejs scheduler is not stable
* And need to fire once at first time
* Relative Issue: https://github.com/KubeJS-Mods/KubeJS/issues/763
*/
event.server.scheduleInTicks(1, (_) => {
console.log("Init Scheduler");
});
/** @type {EventBus} */
const eventBus = /** @type {any} */ (global["eventBus"]);
if (eventBus === null) {
console.error("C4 Handler: eventBus is not available");
return;
}
eventBus.register("C4Activated", handleC4Activated);
eventBus.register("C4UseStarted", handleC4UseStarted);
console.log("C4 Handler: Registered C4Activated event handler");
});

View File

@@ -2,7 +2,11 @@
"$schema": "https://www.schemastore.org/jsconfig.json", "$schema": "https://www.schemastore.org/jsconfig.json",
"extends": "../../jsconfig.json", "extends": "../../jsconfig.json",
"compilerOptions": { "compilerOptions": {
"typeRoots": ["../../types/probe/startup/"], "types": [
"../../types/probe/startup/packages",
"../../types/probe/startup/global",
"../../types/probe/shared"
],
"paths": { "paths": {
"packages/*": [ "packages/*": [
"../../types/probe/startup/packages/*", "../../types/probe/startup/packages/*",
@@ -10,11 +14,6 @@
] ]
} }
}, },
"include": ["./**/*", "../../types/*.d.ts", "../../types/probe/**/*.d.ts"], "include": ["./**/*.js", "../../types/*.d.ts"],
"exclude": [ "exclude": []
"../../types/probe/client/global/*.d.ts",
"../../types/probe/server/global/*.d.ts",
"../../types/probe/client/**/*.d.ts",
"../../types/probe/server/**/*.d.ts"
]
} }

16
types/C4.d.ts vendored Normal file
View File

@@ -0,0 +1,16 @@
/**
* Event data for C4 use started events.
*/
interface C4UseStartedEvent {
player: Internal.Player;
}
/**
* Event data for C4 activation events.
*/
interface C4ActivatedEvent {
level: Internal.Level;
player: Internal.Player;
explosionTime: number;
explosionPower: number;
}

17
types/EventBus.d.ts vendored
View File

@@ -1,20 +1,3 @@
/**
* Event data for C4 use started events.
*/
interface C4UseStartedEvent {
player: Internal.Player;
}
/**
* Event data for C4 activation events.
*/
interface C4ActivatedEvent {
level: Internal.Level;
player: Internal.Player;
explosionTime: number;
explosionPower: number;
}
/** /**
* Mapping of event names to their corresponding event types. * Mapping of event names to their corresponding event types.
*/ */

8
types/global.d.ts vendored Normal file
View File

@@ -0,0 +1,8 @@
export {}; // Mark the file as a module, do not remove unless there are other import/exports!
// Override the global type
declare global {
export type ProbeJS$$ResolvedGlobal = {
eventBus: EventBus;
toExplosionC4Map: { [key: string]: boolean };
};
}