feat(c4): add defuser item and improve C4 mechanics

This commit is contained in:
2026-01-18 12:48:46 +08:00
parent 498022de1d
commit 7586b628f0
5 changed files with 103 additions and 68 deletions

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
} }
} }

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

@@ -1 +1,45 @@
BlockEvents.broken((event) => {}); /**
* C4 Server Scripts
* Handles C4 block break event to cancel explosion
*/
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");
}
}
});

View File

@@ -6,7 +6,7 @@ const $ServerStartedEvent = Java.loadClass(
"net.minecraftforge.event.server.ServerStartedEvent", "net.minecraftforge.event.server.ServerStartedEvent",
); );
const C4_EXPLOSION_TIME = 7 * 20; // 7 seconds in ticks const C4_EXPLOSION_TIME = 10 * 20; // 7 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
@@ -158,13 +158,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()
@@ -229,6 +229,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 ====================
@@ -258,35 +260,26 @@ ClientEvents.init(() => {
}); });
// Send data to the server when the key is pressed // Send data to the server when the key is pressed
ForgeEvents.onEvent( ForgeEvents.onEvent($TickEvent$PlayerTickEvent, (event) => {
// @ts-ignore if (operationKeyMapping === undefined) {
$TickEvent$PlayerTickEvent, console.warn("Not in client platform");
/** return event;
* }
* @param {Internal.TickEvent$PlayerTickEvent} event
* @returns
*/
(event) => {
if (operationKeyMapping === undefined) {
console.warn("Not in client platform");
return event;
}
while (operationKeyMapping.consumeClick()) { while (operationKeyMapping.consumeClick()) {
const player = event.player; const player = event.player;
const level = player.level; const level = player.level;
if (!shouldStartUseC4(player, level)) continue; if (!shouldStartUseC4(player, level)) continue;
/** @type {EventBus} */ /** @type {EventBus} */
const eventBus = /** @type {any} */ (global["eventBus"]); const eventBus = /** @type {any} */ (global["eventBus"]);
if (eventBus !== null) { if (eventBus !== null) {
eventBus.emit("C4UseStarted", { player: player }); eventBus.emit("C4UseStarted", { player: player });
} else { } else {
console.warn("EventBus is not available"); console.warn("EventBus is not available");
}
} }
}, }
); });
// ==================== Server Side Logic ==================== // ==================== Server Side Logic ====================
@@ -383,12 +376,15 @@ function handleC4Activated(event) {
let remainingSeconds = explosionTime / 20; let remainingSeconds = explosionTime / 20;
server.scheduleRepeatingInTicks(20, (scheduledEvent) => { server.scheduleRepeatingInTicks(20, (scheduledEvent) => {
// Assert C4 exsiting // Assert C4 exsiting
if (toExplosionC4Map[newBlockPosString] === null) return; if (toExplosionC4Map[newBlockPosString] === null) {
scheduledEvent.clear();
return;
}
remainingSeconds -= 1; remainingSeconds -= 1;
if (remainingSeconds <= 0) { if (remainingSeconds <= 0) {
scheduledEvent.clear(); scheduledEvent.clear();
return scheduledEvent; return;
} }
server.players.forEach((p) => { server.players.forEach((p) => {
@@ -416,35 +412,26 @@ function handleC4Activated(event) {
}); });
} }
ForgeEvents.onEvent( ForgeEvents.onEvent($ServerStartedEvent, (event) => {
//@ts-ignore
$ServerStartedEvent,
/** /**
* * WARNING: Must Do!!!
* @param {Internal.ServerStartedEvent} event * Because Kubejs scheduler is not stable
* @returns * And need to fire once at first time
* Relative Issue: https://github.com/KubeJS-Mods/KubeJS/issues/763
*/ */
(event) => { event.server.scheduleInTicks(1, (_) => {
/** console.log("Init Scheduler");
* 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} */ /** @type {EventBus} */
const eventBus = /** @type {any} */ (global["eventBus"]); const eventBus = /** @type {any} */ (global["eventBus"]);
if (eventBus === null) { if (eventBus === null) {
console.error("C4 Handler: eventBus is not available"); console.error("C4 Handler: eventBus is not available");
return event; return event;
} }
eventBus.register("C4Activated", handleC4Activated); eventBus.register("C4Activated", handleC4Activated);
eventBus.register("C4UseStarted", handleC4UseStarted); eventBus.register("C4UseStarted", handleC4UseStarted);
console.log("C4 Handler: Registered C4Activated event handler"); console.log("C4 Handler: Registered C4Activated event handler");
}, });
);