Flandre923
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_一个可以给方块添加附魔的刷子/
Author
Flandre923
Published at
2024-08-24