mirror of
https://github.com/SikongJueluo/kubejs-utils.git
synced 2025-11-18 19:37:50 +08:00
Compare commits
2 Commits
b6a958af58
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
125dbfc592 | ||
|
|
17987c0cec |
@@ -14,7 +14,7 @@ A powerful area management script that allows administrators to define a special
|
||||
- Automatically switches the game mode (e.g., from Survival to Adventure/Spectator) when a player enters/leaves the defined area.
|
||||
- Configurable whitelist to exempt certain players (like OPs) from the rules.
|
||||
- Sets a uniform item usage cooldown for all players within the zone.
|
||||
- Provides a rich set of in-game commands to configure the zone's center, radius, target game mode, and more in real-time.
|
||||
- Provides a rich set of in-game commands to configure the zone's boundaries, target game mode, and more in real-time.
|
||||
- **Design Philosophy**:
|
||||
- **High Performance**: Built with an event-driven architecture and a throttled checking mechanism to minimize impact on server performance.
|
||||
- **Persistence**: All configurations are saved automatically and persist through server restarts.
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
- 玩家进入/离开指定区域时,自动切换游戏模式(如冒险/旁观模式与生存模式的切换)。
|
||||
- 可配置的白名单,允许特定玩家(如OP)不受影响。
|
||||
- 为区域内玩家设置统一的物品使用冷却。
|
||||
- 提供丰富的游戏内命令,用于实时配置区域中心、半径、目标模式等。
|
||||
- 提供丰富的游戏内命令,用于实时配置区域边界、目标模式等。
|
||||
- **设计理念**:
|
||||
- **高性能**: 采用事件驱动和降频检查机制,最大限度地减少对服务器性能的影响。
|
||||
- **持久化**: 所有配置都会自动保存,服务器重启后不会丢失。
|
||||
|
||||
@@ -48,12 +48,15 @@ You can manage the script in-game using the `/areacontrol` command series. All c
|
||||
- `/areacontrol toggleCooldown`
|
||||
- **Function**: Enable or disable the item cooldown feature.
|
||||
|
||||
- `/areacontrol setcenter`
|
||||
- **Function**: Set your current position as the center of the zone.
|
||||
- `/areacontrol setCircularArea <radius>`
|
||||
- **Function**: Set your current position as the center of the zone and define its radius.
|
||||
- **Example**: `/areacontrol setCircularArea 100`
|
||||
|
||||
- `/areacontrol setradius <radius>`
|
||||
- **Function**: Set the radius of the zone.
|
||||
- **Example**: `/areacontrol setradius 100`
|
||||
- `/areacontrol setAreaPos1`
|
||||
- **Function**: Set the first corner of the area to your current position.
|
||||
|
||||
- `/areacontrol setAreaPos2`
|
||||
- **Function**: Set the second corner of the area to your current position, defining a rectangular zone.
|
||||
|
||||
- `/areacontrol setmode <adventure|spectator>`
|
||||
- **Function**: Set the game mode players will be switched to upon entering the zone.
|
||||
@@ -112,7 +115,7 @@ PlayerEvents.tick((event) => {
|
||||
#### State Caching and Boundary Detection
|
||||
To avoid unnecessary operations, the script uses state caching and fast boundary detection.
|
||||
|
||||
1. **Boundary Pre-calculation**: When `center` or `radius` changes, the script pre-calculates the area's `minX`, `maxX`, `minZ`, `maxZ` boundaries.
|
||||
1. **Boundary Pre-calculation**: When the area is defined (either as a circular zone with `setCircularArea` or a rectangular zone with `setAreaPos1`/`setAreaPos2`), the script pre-calculates the area's `minX`, `maxX`, `minZ`, `maxZ` boundaries.
|
||||
2. **Fast Detection**: When checking a player's position, it only needs to compare the player's X and Z coordinates with the pre-calculated boundaries, which is an efficient O(1) operation.
|
||||
3. **State Caching**: A global object named `playerStates` caches whether each player is inside the area (as a boolean). The core logic, like switching game modes, is executed only when the player's current state differs from the cached state (i.e., the player has crossed the area boundary). The cache is then updated.
|
||||
|
||||
|
||||
@@ -48,12 +48,15 @@
|
||||
- `/areacontrol toggleCooldown`
|
||||
- **功能**:启用或禁用物品冷却功能。
|
||||
|
||||
- `/areacontrol setcenter`
|
||||
- **功能**:将您当前的位置设置为区域的中心点。
|
||||
- `/areacontrol setCircularArea <半径>`
|
||||
- **功能**:将您当前的位置设置为区域的中心点,并定义其半径。
|
||||
- **示例**:`/areacontrol setCircularArea 100`
|
||||
|
||||
- `/areacontrol setradius <半径>`
|
||||
- **功能**:设置区域的半径。
|
||||
- **示例**:`/areacontrol setradius 100`
|
||||
- `/areacontrol setAreaPos1`
|
||||
- **功能**:将您当前的位置设置为区域的第一个角点。
|
||||
|
||||
- `/areacontrol setAreaPos2`
|
||||
- **功能**:将您当前的位置设置为区域的第二个角点,从而定义一个矩形区域。
|
||||
|
||||
- `/areacontrol setmode <adventure|spectator>`
|
||||
- **功能**:设置玩家进入区域后切换到的游戏模式。
|
||||
@@ -112,7 +115,7 @@ PlayerEvents.tick((event) => {
|
||||
#### 状态缓存与边界检测
|
||||
为避免不必要的操作,脚本采用状态缓存和快速边界检测。
|
||||
|
||||
1. **边界预计算**:当 `center` 或 `radius` 改变时,脚本会预先计算出区域的 `minX`, `maxX`, `minZ`, `maxZ` 边界。
|
||||
1. **边界预计算**:当区域被定义时(无论是通过 `setCircularArea` 定义的圆形区域,还是通过 `setAreaPos1`/`setAreaPos2` 定义的矩形区域),脚本会预先计算出区域的 `minX`, `maxX`, `minZ`, `maxZ` 边界。
|
||||
2. **快速检测**:在检查玩家位置时,只需将玩家的 X 和 Z 坐标与预计算的边界进行比较,这是一个 O(1) 的高效操作。
|
||||
3. **状态缓存**:一个名为 `playerStates` 的全局对象缓存着每个玩家是否在区域内的布尔值。只有当玩家的当前状态与缓存状态不一致时(即玩家穿越了区域边界),脚本才会执行游戏模式切换等核心逻辑,并更新缓存。
|
||||
|
||||
|
||||
@@ -3,19 +3,6 @@
|
||||
|
||||
// ==================== TYPE DEFINITIONS ====================
|
||||
|
||||
/**
|
||||
* @typedef {object} AreaControlConfig
|
||||
* @property {boolean} enabled
|
||||
* @property {boolean} isIncludingOPs
|
||||
* @property {boolean} enableCooldown
|
||||
* @property {{x: number, y: number, z: number}} center
|
||||
* @property {number} radius
|
||||
* @property {string[]} whitelist - Players protected from gamemode changes
|
||||
* @property {"adventure" | "spectator"} mode
|
||||
* @property {number} cooldownSecs
|
||||
* @property {number} checkFrequency
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {object} AreaBounds
|
||||
* @property {number} minX
|
||||
@@ -25,7 +12,15 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {typeof Internal.HashMap} HashMap
|
||||
* @typedef {object} AreaControlConfig
|
||||
* @property {boolean} enabled
|
||||
* @property {boolean} isIncludingOPs
|
||||
* @property {boolean} enableCooldown
|
||||
* @property {AreaBounds} areaBounds
|
||||
* @property {string[]} whitelist - Players protected from gamemode changes
|
||||
* @property {"adventure" | "spectator"} mode
|
||||
* @property {number} cooldownSecs
|
||||
* @property {number} checkFrequency
|
||||
*/
|
||||
|
||||
// ==================== GLOBAL CONSTANTS ====================
|
||||
@@ -48,23 +43,32 @@ let config = {
|
||||
enabled: true,
|
||||
isIncludingOPs: false,
|
||||
enableCooldown: true,
|
||||
center: { x: 0, y: 0, z: 0 },
|
||||
radius: 5,
|
||||
areaBounds: {
|
||||
minX: -50,
|
||||
maxX: 50,
|
||||
minZ: -50,
|
||||
maxZ: 50,
|
||||
},
|
||||
whitelist: [],
|
||||
mode: "adventure",
|
||||
cooldownSecs: 10 * SECOND_TICKS, // 60 seconds
|
||||
checkFrequency: 3 * SECOND_TICKS,
|
||||
};
|
||||
|
||||
/**
|
||||
* Pre-calculated bounds for O(1) area checking
|
||||
* @type {AreaBounds}
|
||||
/** Whether the player is changing position
|
||||
* @type {boolean}
|
||||
*/
|
||||
const bounds = {
|
||||
minX: -50,
|
||||
maxX: 50,
|
||||
minZ: -50,
|
||||
maxZ: 50,
|
||||
let isChangingPos = false;
|
||||
|
||||
/**
|
||||
* Temporary position storage
|
||||
* @type {{x1: number, x2: number, z1: number, z2: number}}
|
||||
*/
|
||||
const tempPos = {
|
||||
x1: 0,
|
||||
x2: 0,
|
||||
z1: 0,
|
||||
z2: 0,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -97,14 +101,29 @@ function isEventBus(obj) {
|
||||
* @param {number} radius
|
||||
* @returns {void}
|
||||
*/
|
||||
function updateBounds(center, radius) {
|
||||
bounds.minX = center.x - radius;
|
||||
bounds.maxX = center.x + radius;
|
||||
bounds.minZ = center.z - radius;
|
||||
bounds.maxZ = center.z + radius;
|
||||
function updateBoundsFromCircular(center, radius) {
|
||||
config.areaBounds.minX = center.x - radius;
|
||||
config.areaBounds.maxX = center.x + radius;
|
||||
config.areaBounds.minZ = center.z - radius;
|
||||
config.areaBounds.maxZ = center.z + radius;
|
||||
|
||||
console.log(
|
||||
`[AreaControl] Updated bounds: X(${bounds.minX} to ${bounds.maxX}), Z(${bounds.minZ} to ${bounds.maxZ})`,
|
||||
`[AreaControl] Updated bounds: X(${config.areaBounds.minX} to ${config.areaBounds.maxX}), Z(${config.areaBounds.minZ} to ${config.areaBounds.maxZ})`,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates area bounds based on temporary position
|
||||
* @param {{x1: number, x2: number, z1: number, z2: number}} pos
|
||||
*/
|
||||
function updateBoundsFromPos(pos) {
|
||||
config.areaBounds.minX = JavaMath.min(pos.x1, pos.x2);
|
||||
config.areaBounds.maxX = JavaMath.max(pos.x1, pos.x2);
|
||||
config.areaBounds.minZ = JavaMath.min(pos.z1, pos.z2);
|
||||
config.areaBounds.maxZ = JavaMath.max(pos.z1, pos.z2);
|
||||
|
||||
console.log(
|
||||
`[AreaControl] Updated bounds: X(${config.areaBounds.minX} to ${config.areaBounds.maxX}), Z(${config.areaBounds.minZ} to ${config.areaBounds.maxZ})`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -117,10 +136,10 @@ function updateBounds(center, radius) {
|
||||
*/
|
||||
function isPositionInArea(x, z) {
|
||||
return (
|
||||
x >= bounds.minX &&
|
||||
x <= bounds.maxX &&
|
||||
z >= bounds.minZ &&
|
||||
z <= bounds.maxZ
|
||||
x >= config.areaBounds.minX &&
|
||||
x <= config.areaBounds.maxX &&
|
||||
z >= config.areaBounds.minZ &&
|
||||
z <= config.areaBounds.maxZ
|
||||
);
|
||||
}
|
||||
|
||||
@@ -249,13 +268,11 @@ function loadConfiguration() {
|
||||
const savedData = server.persistentData.get(CONFIG_FILE);
|
||||
const loadedConfig = NBT.fromTag(savedData);
|
||||
config = Object.assign(config, loadedConfig);
|
||||
updateBounds(config.center, config.radius);
|
||||
console.log("[AreaControl] Configuration loaded from file");
|
||||
} else {
|
||||
console.warn(
|
||||
"[AreaControl] Failed to load configuration, using defaults",
|
||||
);
|
||||
updateBounds(config.center, config.radius);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,8 +307,9 @@ function registerEventHandlers() {
|
||||
*/
|
||||
PlayerEvents.loggedOut((event) => {
|
||||
const { player } = event;
|
||||
const playerId = player.stringUuid;
|
||||
|
||||
const playerId = player.stringUuid;
|
||||
Utils.server.getPlayer(playerId).setGameMode("survival");
|
||||
delete playerStates[playerId];
|
||||
delete playerCooldowns[playerId];
|
||||
|
||||
@@ -317,9 +335,7 @@ function registerEventHandlers() {
|
||||
console.warn("[AreaControl] EventBus is not defined");
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* @param {Internal.LivingEntityUseItemEvent$Finish} event
|
||||
*/
|
||||
|
||||
EventBus.register(
|
||||
"LivingEntityUseItemEvent$Finish",
|
||||
/**
|
||||
@@ -378,10 +394,9 @@ function registerCommands() {
|
||||
false,
|
||||
);
|
||||
source.sendSuccess(
|
||||
`§e- 中心点: (${config.center.x}, ${config.center.y}, ${config.center.z})`,
|
||||
`§e- 区域: (${config.areaBounds.minX}, ${config.areaBounds.minZ}) (${config.areaBounds.maxX}, ${config.areaBounds.maxZ})`,
|
||||
false,
|
||||
);
|
||||
source.sendSuccess(`§e- 半径: ${config.radius}`, false);
|
||||
source.sendSuccess(`§e- 模式: ${config.mode}`, false);
|
||||
source.sendSuccess(
|
||||
`§e- 白名单: ${config.whitelist.length} 名玩家`,
|
||||
@@ -434,18 +449,13 @@ function registerCommands() {
|
||||
* @param {any} ctx
|
||||
* @returns {number}
|
||||
*/
|
||||
const setCenterCommand = (ctx) => {
|
||||
const source = ctx.source;
|
||||
if (!source.player) {
|
||||
source.sendFailure("§c此命令必须由玩家执行");
|
||||
return 0;
|
||||
}
|
||||
const pos = source.player.blockPosition();
|
||||
config.center = { x: pos.x, y: pos.y, z: pos.z };
|
||||
updateBounds(config.center, config.radius);
|
||||
const toggleIncludingOPsCommand = (ctx) => {
|
||||
config.isIncludingOPs = !config.isIncludingOPs;
|
||||
saveConfiguration();
|
||||
source.sendSuccess(
|
||||
`§6[区域控制] §e中心点设置为 (${pos.x}, ${pos.y}, ${pos.z})`,
|
||||
ctx.source.sendSuccess(
|
||||
config.isIncludingOPs
|
||||
? "§6[区域控制] §a包含管理员"
|
||||
: "§6[区域控制] §c不包含管理员",
|
||||
true,
|
||||
);
|
||||
return 1;
|
||||
@@ -455,16 +465,104 @@ function registerCommands() {
|
||||
* @param {any} ctx
|
||||
* @returns {number}
|
||||
*/
|
||||
const setRadiusCommand = (ctx) => {
|
||||
const radius = Arguments.INTEGER.getResult(ctx, "radius");
|
||||
if (radius < 1 || radius > 8192) {
|
||||
ctx.source.sendFailure("§c半径必须在 1 到 8192 之间");
|
||||
const toggleCooldownCommand = (ctx) => {
|
||||
if (!isEventBus(EventBus)) {
|
||||
ctx.source.sendFailure("§c事件总线未注入,无法切换");
|
||||
return 0;
|
||||
}
|
||||
config.radius = radius;
|
||||
updateBounds(config.center, config.radius);
|
||||
config.enableCooldown = !config.enableCooldown;
|
||||
saveConfiguration();
|
||||
ctx.source.sendSuccess(`§6[区域控制] §e半径设置为 ${radius}`, true);
|
||||
ctx.source.sendSuccess(
|
||||
config.enableCooldown
|
||||
? "§6[区域控制] §a启用冷却"
|
||||
: "§6[区域控制] §c禁用冷却",
|
||||
true,
|
||||
);
|
||||
return 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {any} ctx
|
||||
* @returns {number}
|
||||
*/
|
||||
const setPos1Command = (ctx) => {
|
||||
const source = ctx.source;
|
||||
if (!source.player) {
|
||||
source.sendFailure("§c此命令必须由玩家执行");
|
||||
return 0;
|
||||
}
|
||||
const pos = source.player.blockPosition();
|
||||
|
||||
tempPos.x1 = pos.x;
|
||||
tempPos.z1 = pos.z;
|
||||
isChangingPos = true;
|
||||
ctx.source.sendSuccess(
|
||||
`§6[区域控制] §a已设置第一个位置: ${pos.x}, ${pos.z}`,
|
||||
true,
|
||||
);
|
||||
return 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {any} ctx
|
||||
* @returns {number}
|
||||
*/
|
||||
const setPos2Command = (ctx) => {
|
||||
const source = ctx.source;
|
||||
if (!source.player) {
|
||||
source.sendFailure("§c此命令必须由玩家执行");
|
||||
return 0;
|
||||
}
|
||||
if (!isChangingPos) {
|
||||
source.sendFailure("§c请先设置第一个位置");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const pos = source.player.blockPosition();
|
||||
tempPos.x2 = pos.x;
|
||||
tempPos.z2 = pos.z;
|
||||
isChangingPos = false;
|
||||
ctx.source.sendSuccess(
|
||||
`§6[区域控制] §a已设置第二个位置: ${pos.x}, ${pos.z}`,
|
||||
true,
|
||||
);
|
||||
|
||||
updateBoundsFromPos(tempPos);
|
||||
saveConfiguration();
|
||||
source.sendSuccess(
|
||||
`§e- 区域: (${config.areaBounds.minX}, ${config.areaBounds.minZ}) (${config.areaBounds.maxX}, ${config.areaBounds.maxZ})`,
|
||||
true,
|
||||
);
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {any} ctx
|
||||
* @returns {number}
|
||||
*/
|
||||
const setCircularAreaCommand = (ctx) => {
|
||||
const source = ctx.source;
|
||||
if (!source.player) {
|
||||
source.sendFailure("§c此命令必须由玩家执行");
|
||||
return 0;
|
||||
}
|
||||
const radius = Arguments.INTEGER.getResult(ctx, "radius");
|
||||
if (radius < 1 || radius > 8192) {
|
||||
source.sendFailure("§c半径必须在 1 到 8192 之间");
|
||||
return 0;
|
||||
}
|
||||
const pos = source.player.blockPosition();
|
||||
updateBoundsFromCircular({ x: pos.x, y: pos.y, z: pos.z }, radius);
|
||||
saveConfiguration();
|
||||
source.sendSuccess(
|
||||
`§6[区域控制] §e区域已设置:中心点 (${pos.x}, ${pos.y}, ${pos.z}),半径 ${radius}`,
|
||||
true,
|
||||
);
|
||||
source.sendSuccess(
|
||||
`§e- 区域: (${config.areaBounds.minX}, ${config.areaBounds.minZ}) (${config.areaBounds.maxX}, ${config.areaBounds.maxZ})`,
|
||||
true,
|
||||
);
|
||||
return 1;
|
||||
};
|
||||
|
||||
@@ -530,42 +628,6 @@ function registerCommands() {
|
||||
return 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {any} ctx
|
||||
* @returns {number}
|
||||
*/
|
||||
const toggleIncludingOPsCommand = (ctx) => {
|
||||
config.isIncludingOPs = !config.isIncludingOPs;
|
||||
saveConfiguration();
|
||||
ctx.source.sendSuccess(
|
||||
config.isIncludingOPs
|
||||
? "§6[区域控制] §a包含管理员"
|
||||
: "§6[区域控制] §c不包含管理员",
|
||||
true,
|
||||
);
|
||||
return 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {any} ctx
|
||||
* @returns {number}
|
||||
*/
|
||||
const toggleCooldownCommand = (ctx) => {
|
||||
if (!isEventBus(EventBus)) {
|
||||
ctx.source.sendFailure("§c事件总线未注入,无法切换");
|
||||
return 0;
|
||||
}
|
||||
config.enableCooldown = !config.enableCooldown;
|
||||
saveConfiguration();
|
||||
ctx.source.sendSuccess(
|
||||
config.enableCooldown
|
||||
? "§6[区域控制] §a启用冷却"
|
||||
: "§6[区域控制] §c禁用冷却",
|
||||
true,
|
||||
);
|
||||
return 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {any} ctx
|
||||
* @returns {number}
|
||||
@@ -669,10 +731,13 @@ function registerCommands() {
|
||||
"§e- /areacontrol toggleCooldown - 启用/禁用物品冷却",
|
||||
);
|
||||
source.sendFailure(
|
||||
"§e- /areacontrol setcenter - 将区域中心设置为当前位置",
|
||||
"§e- /areacontrol setCircularArea <radius> - 将区域中心设置为当前位置并设置半径",
|
||||
);
|
||||
source.sendFailure(
|
||||
"§e- /areacontrol setradius <radius> - 设置区域半径",
|
||||
"§e- /areacontrol setAreaPos1 - 将玩家位置设置为区域第一个位置",
|
||||
);
|
||||
source.sendFailure(
|
||||
"§e- /areacontrol setAreaPos2 - 将玩家位置设置为区域第二个位置",
|
||||
);
|
||||
source.sendFailure(
|
||||
"§e- /areacontrol setmode <adventure|spectator> - 设置区域游戏模式",
|
||||
@@ -708,17 +773,18 @@ function registerCommands() {
|
||||
.literal("toggleIncludingOPs")
|
||||
.executes(toggleIncludingOPsCommand),
|
||||
)
|
||||
.then(commands.literal("setcenter").executes(setCenterCommand))
|
||||
.then(commands.literal("setAreaPos1").executes(setPos1Command))
|
||||
.then(commands.literal("setAreaPos2").executes(setPos2Command))
|
||||
.then(
|
||||
commands
|
||||
.literal("setradius")
|
||||
.literal("setCircularArea")
|
||||
.then(
|
||||
commands
|
||||
.argument(
|
||||
"radius",
|
||||
Arguments.INTEGER.create(event),
|
||||
)
|
||||
.executes(setRadiusCommand),
|
||||
.executes(setCircularAreaCommand),
|
||||
),
|
||||
)
|
||||
.then(
|
||||
@@ -819,7 +885,7 @@ function initializeAreaControl() {
|
||||
|
||||
console.log("[AreaControl] System initialized successfully");
|
||||
console.log(
|
||||
`[AreaControl] Area: center(${config.center.x}, ${config.center.z}), radius: ${config.radius}`,
|
||||
`[AreaControl] Area: (${config.areaBounds.minX}, ${config.areaBounds.minZ}) (${config.areaBounds.maxX}, ${config.areaBounds.maxZ})`,
|
||||
);
|
||||
console.log(
|
||||
`[AreaControl] Mode: ${config.mode}, Enabled: ${config.enabled}`,
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
/**
|
||||
* @typedef {(
|
||||
* "PlayerItemFishedEvent" |
|
||||
* "LivingEntityUseItemEvent$Finish"
|
||||
* )} EventName
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {(
|
||||
* ((event: Internal.ItemFishedEvent) => any) |
|
||||
* ((event: Internal.LivingEntityUseItemEvent$Finish) => any)
|
||||
* )} EventCallback
|
||||
*/
|
||||
|
||||
/**
|
||||
* A simple event bus for handling custom events in KubeJS environment.
|
||||
* @namespace
|
||||
@@ -9,6 +23,13 @@ const eventBus = {
|
||||
*/
|
||||
eventMap: {},
|
||||
|
||||
/**
|
||||
* Registers a callback function for a specific event.
|
||||
* @overload
|
||||
* @param {"PlayerItemFishedEvent"} eventName - The name of the event to listen for.
|
||||
* @param {(event: Internal.ItemFishedEvent) => any} callback - The callback function.
|
||||
* @returns {void}
|
||||
*/
|
||||
/**
|
||||
* Registers a callback function for a specific event.
|
||||
* @overload
|
||||
@@ -18,14 +39,21 @@ const eventBus = {
|
||||
*/
|
||||
/**
|
||||
* Registers a callback function for a specific event.
|
||||
* @param {string} eventName - The name of the event to listen for.
|
||||
* @param {Function} callback - The callback function to execute when the event is emitted.
|
||||
* @param {EventName} eventName - The name of the event to listen for.
|
||||
* @param {EventCallback} callback - The callback function to execute when the event is emitted.
|
||||
* @returns {void}
|
||||
*/
|
||||
register: function (eventName, callback) {
|
||||
this.eventMap[eventName] = callback;
|
||||
},
|
||||
|
||||
/**
|
||||
* Registers a callback function for a specific event.
|
||||
* @overload
|
||||
* @param {"PlayerItemFishedEvent"} eventName - The name of the event to listen for.
|
||||
* @param {(event: Internal.ItemFishedEvent) => any} callback - The callback function.
|
||||
* @returns {void}
|
||||
*/
|
||||
/**
|
||||
* Emits an event, calling the registered callback function if it exists.
|
||||
* @overload
|
||||
@@ -59,3 +87,17 @@ ForgeEvents.onEvent(
|
||||
eventBus.emit("LivingEntityUseItemEvent$Finish", event);
|
||||
},
|
||||
);
|
||||
|
||||
ForgeEvents.onEvent(
|
||||
"net.minecraftforge.event.entity.player.ItemFishedEvent",
|
||||
(event) => {
|
||||
eventBus.emit("PlayerItemFishedEvent", event);
|
||||
},
|
||||
);
|
||||
|
||||
ForgeEvents.onEvent(
|
||||
"net.minecraftforge.event.entity.player.ItemFishedEvent",
|
||||
(event) => {
|
||||
eventBus.emit("PlayerItemFishedEvent", event);
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user