944 words
5 minutes
15 一个可以给方块添加附魔的刷子
15 一个可以给方块添加附魔的刷子
这次我们搞的是一个可以给指定的方块上附魔的刷子,可以将刷子的附魔附魔到方块上,也可以清除方块的附魔
@SubscribeEvent
public static void onPlayerAttack(PlayerInteractEvent.LeftClickBlock event) {
// 订阅玩家左键点击方块事件
// 当玩家左键点击方块时,会触发这个方法
BlockPos startPos = null;
// 用于记录第一次点击方块的位置,以便计算出需要操作的方块范围
Player player = event.getEntity(); // 获取事件中的玩家
Level world = event.getLevel(); // 获取玩家所在的世界
InteractionHand hand = event.getHand(); // 获取玩家使用的手
BlockPos pos = event.getPos(); // 获取玩家点击的方块位置
if(!world.isClientSide) { // 判断是否在服务器端执行
Iterable<ItemStack> handItemStacks = player.getAllSlots(); // 获取玩家所有物品栏中的物品
for (ItemStack itemstack : handItemStacks) {
if (itemstack.is(Items.BRUSH)) { // 判断物品是否是刷子
if (itemstack.isEnchanted()) {// 如果刷子有附魔
if (startPos == null) {
startPos = pos ; // 记录第一次点击的位置
} else {
brushAllBlocks(world,startPos, pos, itemstack); // 调用函数,对范围内的方块进行附魔
startPos = null; // 重置起始位置
}
} else {// 如果刷子没有附魔
if (startPos == null) {
startPos = pos;
} else {
clearAllBlocks(world,startPos, pos); // 调用函数,清除范围内的方块附魔
startPos = null;
}
}
}
}
}
}
这个方法还是比较简单的,我们使用玩家左键的事件,然后判断是否是刷子
// 定义一个方法,对给定位置之间的所有方块进行附魔处理
private static void brushAllBlocks(Level world, BlockPos startPos, BlockPos pos, ItemStack itemStack) {
// 获取两个位置的X、Y、Z坐标中的最小值和最大值,确定立方体区域
int minX = Math.min(startPos.getX(), pos.getX());
int minY = Math.min(startPos.getY(), pos.getY());
int minZ = Math.min(startPos.getZ(), pos.getZ());
int maxX = Math.max(startPos.getX(), pos.getX());
int maxY = Math.max(startPos.getY(), pos.getY());
int maxZ = Math.max(startPos.getZ(), pos.getZ());
// 遍历立方体区域内的所有方块
for (int x = minX; x <= maxX; x++) {
for (int y = minY; y <= maxY; y++) {
for (int z = minZ; z <= maxZ; z++) {
// 获取当前遍历到的方块位置
BlockPos currentPos = new BlockPos(x, y, z);
// 获取当前位置的方块状态(BlockState)
BlockState blockState = world.getBlockState(currentPos);
// 如果当前方块是空气、水、岩浆,则跳过处理
if (blockState.is(Blocks.AIR) ||
blockState.is(Blocks.WATER) ||
blockState.is(Blocks.LAVA)) {
continue;
}
// 获取刷子的附魔数据
ItemEnchantments itemEnchantments = itemStack.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY);
// 创建一个NBT列表用于存储附魔数据
ListTag enchantmentNbtList = new ListTag();
// 获取所有附魔的数据条目
Set<Object2IntMap.Entry<Holder<Enchantment>>> entries = itemEnchantments.entrySet();
for (Object2IntMap.Entry<Holder<Enchantment>> entry : entries) {
// 获取附魔的类型(key)和等级(value)
Holder<Enchantment> key = entry.getKey();
int intValue = entry.getIntValue();
// 创建一个新的NBT标签,用于存储单个附魔的数据
CompoundTag enchantmentNbt = new CompoundTag();
enchantmentNbt.putString("id", String.valueOf(key.getKey()));
enchantmentNbt.putInt("lvl", intValue);
// 将附魔数据添加到附魔列表中
enchantmentNbtList.add(enchantmentNbt);
}
// 将附魔应用到当前方块
BlockEnchantmentStorage.addBlockEnchantment(currentPos, enchantmentNbtList);
}
}
}
}
清除对应的附魔
// 定义一个方法,对给定位置之间的所有方块清除附魔
private static void clearAllBlocks(Level world, BlockPos startPos, BlockPos pos) {
// 获取两个位置的X、Y、Z坐标中的最小值和最大值,确定立方体区域
int minX = Math.min(startPos.getX(), pos.getX());
int minY = Math.min(startPos.getY(), pos.getY());
int minZ = Math.min(startPos.getZ(), pos.getZ());
int maxX = Math.max(startPos.getX(), pos.getX());
int maxY = Math.max(startPos.getY(), pos.getY());
int maxZ = Math.max(startPos.getZ(), pos.getZ());
// 遍历立方体区域内的所有方块
for (int x = minX; x <= maxX; x++) {
for (int y = minY; y <= maxY; y++) {
for (int z = minZ; z <= maxZ; z++) {
// 获取当前遍历到的方块位置
BlockPos currentPos = new BlockPos(x, y, z);
// 获取当前位置的方块状态(BlockState)
BlockState blockState = world.getBlockState(currentPos);
// 清除当前方块的附魔
BlockEnchantmentStorage.removeBlockEnchantment(currentPos);
// 如果需要日志输出,可以记录清除的方块信息
// ExampleMod.LOGGER.info("Found block: " + blockState.getBlock().getTranslationKey() + " at " + currentPos);
}
}
}
}
15 一个可以给方块添加附魔的刷子
https://fuwari.vercel.app/posts/minecraft1_21_0/15_一个可以给方块添加附魔的刷子/