Учёт других чар

Версия Minecraft
1.21.1
API
Fabric
Подскажите кто мастер в создании модов, проблема в том, что нужно чтобы эффект чара 3 на 3 на 3 при ломании блоков применял эффект шелкового касания и удачи на все ломаемые блоки, у меня возникли ошибки из-за версии 1.21.1, непонятно как это сделать в новой версии. Помоги
Вот код эффекта

Java:
public record ExcavationEnchantmentEffect(EnchantmentLevelBasedValue range) implements EnchantmentEntityEffect {
    public static final MapCodec<ExcavationEnchantmentEffect> CODEC = RecordCodecBuilder.mapCodec(
            instance -> instance.group(
                    EnchantmentLevelBasedValue.CODEC.fieldOf("range").forGetter(ExcavationEnchantmentEffect::range)
            ).apply(instance, ExcavationEnchantmentEffect::new)
    );

    @Override
    public void apply(ServerWorld world, int level, EnchantmentEffectContext context, Entity target, Vec3d pos) {
        if (target instanceof PlayerEntity player && context.stack() != null) {
            // Приведение координат к целым числам
            BlockPos origin = new BlockPos((int) Math.floor(pos.x), (int) Math.floor(pos.y), (int) Math.floor(pos.z));

            // Если игрок удерживает Shift, копаем только один блок
            if (player.isSneaking()) {
                breakSingleBlock(world, player, origin);
            } else {
                // Разрушаем область 3x3x3
                breakBlocksInArea(world, player, origin, context.stack());
            }
        }
    }

    private void breakBlocksInArea(ServerWorld world, PlayerEntity player, BlockPos origin, ItemStack tool) {
        for (int x = -1; x <= 1; x++) {
            for (int y = -1; y <= 1; y++) {
                for (int z = -1; z <= 1; z++) {
                    // Рассчитываем положение целевого блока
                    BlockPos targetPos = origin.add(x, y, z);

                    // Проверяем, подходит ли блок для разрушения
                    BlockState blockState = world.getBlockState(targetPos);
                    if (isBlockInWhitelist(blockState.getBlock()) && world.canPlayerModifyAt(player, targetPos)) {
                        // Разрушаем блок с учетом зачарований
                        breakBlockWithEnchantments(world, player, targetPos, blockState, tool);
                    }
                }
            }
        }
    }

    private void breakSingleBlock(ServerWorld world, PlayerEntity player, BlockPos pos) {
        BlockState blockState = world.getBlockState(pos);
        if (isBlockInWhitelist(blockState.getBlock()) && world.canPlayerModifyAt(player, pos)) {
            // Разрушаем только один блок с учетом зачарований
            breakBlockWithEnchantments(world, player, pos, blockState, player.getMainHandStack());
        }
    }


    public void breakBlockWithEnchantments(ServerWorld world, PlayerEntity player, BlockPos pos, BlockState blockState, ItemStack tool) {
        // Получаем уровень зачарования "Шёлковое касание"
        int silkTouchLevel = EnchantmentHelper.getLevel(Enchantments.SILK_TOUCH, tool);

        if (silkTouchLevel > 0) {
            // Если есть Шёлковое касание, блок не будет ломаться, а выпадет как есть
            Block dropBlock = blockState.getBlock();
            dropBlock.dropStack(world, pos, new ItemStack(dropBlock));
        } else {
            // Получаем уровень зачарования "Удача"
            int fortuneLevel = EnchantmentHelper.getLevel(Enchantments.FORTUNE, tool);

            // Если есть Удача, то увеличиваем шанс выпадения дополнительных предметов
            blockState.getBlock().dropStacks(blockState, world, pos);
        }

        // Проверка, что игрок может разрушить этот блок
        if (world.canPlayerModifyAt(player, pos)) {
            world.breakBlock(pos, false, player);
        } else {
            // Логируем ошибку, если игрок не может разрушить блок
            System.out.println("Player cannot modify the block at position: " + pos);
        }
    }



    private boolean isBlockInWhitelist(Block block) {
        // Создаём ключ тега для белого списка
        TagKey<Block> whitelistTag = TagKey.of(RegistryKeys.BLOCK, Identifier.of("tutorialmod", "excavation_whitelist"));
        return block.getRegistryEntry().isIn(whitelistTag);
    }

    @Override
    public MapCodec<? extends EnchantmentEntityEffect> getCodec() {
        return CODEC;
    }
}

Ошибки 'getLevel(net.minecraft.registry.entry.RegistryEntry<net.minecraft.enchantment.Enchantment>, net.minecraft.item.ItemStack)' in 'net.minecraft.enchantment.EnchantmentHelper' cannot be applied to '(net.minecraft.registry.RegistryKey<net.minecraft.enchantment.Enchantment>, net.minecraft.item.ItemStack)'
и то же самое со вторым чаром
 
Краш-лог
'getLevel(net.minecraft.registry.entry.RegistryEntry<net.minecraft.enchantment.Enchantment>, net.minecraft.item.ItemStack)' in 'net.minecraft.enchantment.EnchantmentHelper' cannot be applied to '(net.minecraft.registry.RegistryKey<net.minecraft.enchantment.Enchantment>, net.minecraft.item.ItemStack)'
Краш-лог:
'getLevel(net.minecraft.registry.entry.RegistryEntry<net.minecraft.enchantment.Enchantment>, net.minecraft.item.ItemStack)' in 'net.minecraft.enchantment.EnchantmentHelper' cannot be applied to '(net.minecraft.registry.RegistryKey<net.minecraft.enchantment.Enchantment>, net.minecraft.item.ItemStack)'
Последнее редактирование модератором:
Java:
public record ExcavationEnchantmentEffect(EnchantmentLevelBasedValue range) implements EnchantmentEntityEffect {
    public static final MapCodec<ExcavationEnchantmentEffect> CODEC = RecordCodecBuilder.mapCodec(
            instance -> instance.group(
                    EnchantmentLevelBasedValue.CODEC.fieldOf("range").forGetter(ExcavationEnchantmentEffect::range)
            ).apply(instance, ExcavationEnchantmentEffect::new)
    );

    @Override
    public void apply(ServerWorld world, int level, EnchantmentEffectContext context, Entity target, Vec3d pos) {
        if (target instanceof PlayerEntity player && context.stack() != null) {
            // Приведение координат к целым числам
            BlockPos origin = new BlockPos((int) Math.floor(pos.x), (int) Math.floor(pos.y), (int) Math.floor(pos.z));

            // Если игрок удерживает Shift, копаем только один блок
            if (player.isSneaking()) {
                breakSingleBlock(world, player, origin);
            } else {
                // Разрушаем область 3x3x3
                breakBlocksInArea(world, player, origin, context.stack());
            }
        }
    }

    private void breakBlocksInArea(ServerWorld world, PlayerEntity player, BlockPos origin, ItemStack tool) {
        for (int x = -1; x <= 1; x++) {
            for (int y = -1; y <= 1; y++) {
                for (int z = -1; z <= 1; z++) {
                    // Рассчитываем положение целевого блока
                    BlockPos targetPos = origin.add(x, y, z);

                    // Проверяем, подходит ли блок для разрушения
                    BlockState blockState = world.getBlockState(targetPos);
                    if (isBlockInWhitelist(blockState.getBlock()) && world.canPlayerModifyAt(player, targetPos)) {
                        // Разрушаем блок с учетом зачарований
                        breakBlockWithEnchantments(world, player, targetPos, blockState, tool);
                    }
                }
            }
        }
    }

    private void breakSingleBlock(ServerWorld world, PlayerEntity player, BlockPos pos) {
        BlockState blockState = world.getBlockState(pos);
        if (isBlockInWhitelist(blockState.getBlock()) && world.canPlayerModifyAt(player, pos)) {
            // Разрушаем только один блок с учетом зачарований
            breakBlockWithEnchantments(world, player, pos, blockState, player.getMainHandStack());
        }
    }


    public void breakBlockWithEnchantments(ServerWorld world, PlayerEntity player, BlockPos pos, BlockState blockState, ItemStack tool) {
        // Получаем уровень зачарования "Шёлковое касание"
        int silkTouchLevel = EnchantmentHelper.getLevel(Enchantments.SILK_TOUCH, tool);

        if (silkTouchLevel > 0) {
            // Если есть Шёлковое касание, блок не будет ломаться, а выпадет как есть
            Block dropBlock = blockState.getBlock();
            dropBlock.dropStack(world, pos, new ItemStack(dropBlock));
        } else {
            // Получаем уровень зачарования "Удача"
            int fortuneLevel = EnchantmentHelper.getLevel(Enchantments.FORTUNE, tool);

            // Если есть Удача, то увеличиваем шанс выпадения дополнительных предметов
            blockState.getBlock().dropStacks(blockState, world, pos);
        }

        // Проверка, что игрок может разрушить этот блок
        if (world.canPlayerModifyAt(player, pos)) {
            world.breakBlock(pos, false, player);
        } else {
            // Логируем ошибку, если игрок не может разрушить блок
            System.out.println("Player cannot modify the block at position: " + pos);
        }
    }



    private boolean isBlockInWhitelist(Block block) {
        // Создаём ключ тега для белого списка
        TagKey<Block> whitelistTag = TagKey.of(RegistryKeys.BLOCK, Identifier.of("tutorialmod", "excavation_whitelist"));
        return block.getRegistryEntry().isIn(whitelistTag);
    }

    @Override
    public MapCodec<? extends EnchantmentEntityEffect> getCodec() {
        return CODEC;
    }
}
Java:
public record ExcavationEnchantmentEffect(EnchantmentLevelBasedValue range) implements EnchantmentEntityEffect {
    public static final MapCodec<ExcavationEnchantmentEffect> CODEC = RecordCodecBuilder.mapCodec(
            instance -> instance.group(
                    EnchantmentLevelBasedValue.CODEC.fieldOf("range").forGetter(ExcavationEnchantmentEffect::range)
            ).apply(instance, ExcavationEnchantmentEffect::new)
    );

    @Override
    public void apply(ServerWorld world, int level, EnchantmentEffectContext context, Entity target, Vec3d pos) {
        if (target instanceof PlayerEntity player && context.stack() != null) {
            // Приведение координат к целым числам
            BlockPos origin = new BlockPos((int) Math.floor(pos.x), (int) Math.floor(pos.y), (int) Math.floor(pos.z));

            // Если игрок удерживает Shift, копаем только один блок
            if (player.isSneaking()) {
                breakSingleBlock(world, player, origin);
            } else {
                // Разрушаем область 3x3x3
                breakBlocksInArea(world, player, origin, context.stack());
            }
        }
    }

    private void breakBlocksInArea(ServerWorld world, PlayerEntity player, BlockPos origin, ItemStack tool) {
        for (int x = -1; x <= 1; x++) {
            for (int y = -1; y <= 1; y++) {
                for (int z = -1; z <= 1; z++) {
                    // Рассчитываем положение целевого блока
                    BlockPos targetPos = origin.add(x, y, z);

                    // Проверяем, подходит ли блок для разрушения
                    BlockState blockState = world.getBlockState(targetPos);
                    if (isBlockInWhitelist(blockState.getBlock()) && world.canPlayerModifyAt(player, targetPos)) {
                        // Разрушаем блок с учетом зачарований
                        breakBlockWithEnchantments(world, player, targetPos, blockState, tool);
                    }
                }
            }
        }
    }

    private void breakSingleBlock(ServerWorld world, PlayerEntity player, BlockPos pos) {
        BlockState blockState = world.getBlockState(pos);
        if (isBlockInWhitelist(blockState.getBlock()) && world.canPlayerModifyAt(player, pos)) {
            // Разрушаем только один блок с учетом зачарований
            breakBlockWithEnchantments(world, player, pos, blockState, player.getMainHandStack());
        }
    }


    public void breakBlockWithEnchantments(ServerWorld world, PlayerEntity player, BlockPos pos, BlockState blockState, ItemStack tool) {
        // Получаем уровень зачарования "Шёлковое касание"
        int silkTouchLevel = EnchantmentHelper.getLevel(Enchantments.SILK_TOUCH, tool);

        if (silkTouchLevel > 0) {
            // Если есть Шёлковое касание, блок не будет ломаться, а выпадет как есть
            Block dropBlock = blockState.getBlock();
            dropBlock.dropStack(world, pos, new ItemStack(dropBlock));
        } else {
            // Получаем уровень зачарования "Удача"
            int fortuneLevel = EnchantmentHelper.getLevel(Enchantments.FORTUNE, tool);

            // Если есть Удача, то увеличиваем шанс выпадения дополнительных предметов
            blockState.getBlock().dropStacks(blockState, world, pos);
        }

        // Проверка, что игрок может разрушить этот блок
        if (world.canPlayerModifyAt(player, pos)) {
            world.breakBlock(pos, false, player);
        } else {
            // Логируем ошибку, если игрок не может разрушить блок
            System.out.println("Player cannot modify the block at position: " + pos);
        }
    }



    private boolean isBlockInWhitelist(Block block) {
        // Создаём ключ тега для белого списка
        TagKey<Block> whitelistTag = TagKey.of(RegistryKeys.BLOCK, Identifier.of("tutorialmod", "excavation_whitelist"));
        return block.getRegistryEntry().isIn(whitelistTag);
    }

    @Override
    public MapCodec<? extends EnchantmentEntityEffect> getCodec() {
        return CODEC;
    }
}
 
Попробуй поменять второй параметр на true(он отвечает за выпадения дропов).
Java:
if (world.canPlayerModifyAt(player, pos)) {
    world.breakBlock(pos, false, player);
}

Либо то, что предлагал раньше.
Вместо breakBlockWithEnchantments попробуй использовать World#breakBlock(pos, true, player).
Настройки дропов(включая чары) пишутся в .json файлах, World#breakBlock получает необходимый .json
 
Назад
Сверху