方块放置拦截¶
通过world.beforeEvents.playerPlaceBlock事件,脚本可以监听玩家的方块放置操作并选择性地阻止。这是实现地皮系统、领地保护等功能的基础机制。
基础用法¶
在前置方块放置事件中调用event.cancel = true即可阻止放置:
import { world } from "@minecraft/server";
world.beforeEvents.playerPlaceBlock.subscribe((event) => {
const { player, block, permutationBeingPlaced } = event;
const blockType = permutationBeingPlaced.type.id;
// 阻止放置TNT
if (blockType === "minecraft:tnt") {
event.cancel = true;
player.sendMessage("§c该区域禁止放置TNT!");
}
});
受限执行模式限制
world.beforeEvents.playerPlaceBlock是前置事件,回调内处于受限执行模式。若需要在阻止方块放置后执行修改世界状态的操作(如给玩家发送物品),需通过system.run()推迟执行。
按区域限制放置¶
结合方块坐标可以实现区域性保护:
import { world, system } from "@minecraft/server";
const PROTECTED_REGION = {
minX: -10, maxX: 10,
minY: 60, maxY: 80,
minZ: -10, maxZ: 10,
};
function isInProtectedRegion(pos) {
return (
pos.x >= PROTECTED_REGION.minX && pos.x <= PROTECTED_REGION.maxX &&
pos.y >= PROTECTED_REGION.minY && pos.y <= PROTECTED_REGION.maxY &&
pos.z >= PROTECTED_REGION.minZ && pos.z <= PROTECTED_REGION.maxZ
);
}
world.beforeEvents.playerPlaceBlock.subscribe((event) => {
if (isInProtectedRegion(event.block.location)) {
event.cancel = true;
const player = event.player;
system.run(() => {
player.sendMessage("§c该位置受到保护,无法放置方块。");
});
}
});
配合动态属性存储保护列表
若需要动态添加或移除受保护区域,可以将区域数据存储在世界的动态属性中,并在事件回调中读取。关于动态属性的用法,请参阅脚本核心功能页面。
按玩家标签限制放置¶
利用标签系统可以区分不同权限的玩家:
import { world } from "@minecraft/server";
world.beforeEvents.playerPlaceBlock.subscribe((event) => {
const { player } = event;
// 只有拥有"builder"标签的玩家才能放置方块
if (!player.hasTag("builder") && !player.isOp()) {
event.cancel = true;
}
});
与方块破坏事件配合
类似的机制也可用于方块破坏拦截,对应事件为world.beforeEvents.playerBreakBlock。