mirror of
https://github.com/SikongJueluo/kubejs-utils.git
synced 2026-01-29 08:17:49 +08:00
Compare commits
5 Commits
8ffa4daa60
...
1e27eb7e8c
| Author | SHA1 | Date | |
|---|---|---|---|
|
1e27eb7e8c
|
|||
|
f996cfff58
|
|||
|
7586b628f0
|
|||
|
498022de1d
|
|||
|
670b7e14a8
|
30
bun.lock
Normal file
30
bun.lock
Normal 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=="],
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
6
package.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"dependencies": {},
|
||||||
|
"devDependencies": {
|
||||||
|
"oxlint": "^1.39.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||
18
src/client_scripts/Test.js
Normal file
18
src/client_scripts/Test.js
Normal 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;
|
||||||
|
});
|
||||||
@@ -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
234
src/server_scripts/C4.js
Normal 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");
|
||||||
|
});
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
|||||||
@@ -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");
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -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
16
types/C4.d.ts
vendored
Normal 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
17
types/EventBus.d.ts
vendored
@@ -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
8
types/global.d.ts
vendored
Normal 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 };
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user