Перейти к содержанию
Если у вас техническая проблема с модом или их сборкой, то создавайте тему в разделе "Технические проблемы".
В разделе "Моды" запрещено набирать игроков на свой сервер и искать друзей для игры.

Нужна помощь с изменением скорости лодок на NeoForge 1.21.1


GenkaMistikCoder

Рекомендуемые сообщения

В теме 2 сообщения

Спойлер

Прошу не использовать нейронку так как она тут бессильна(

Добрый день уважаемые программисты и создатели модов, у меня тут случилась сложная проблема.

Проще говоря мне надо с помощью зачарования изменить скорость лодки (и так чтоб она сохранилась при ломании лодки), и тут возникла одна противная штучка - майнкрафт даже обновляя nbt тега не дает мне изменить скорость, вот код -

package com.genamistik.neoforgemods.mhutilites;

import net.minecraft.core.component.DataComponents;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.ItemEnchantments;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.item.ItemEntity;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.neoforge.event.entity.EntityJoinLevelEvent;
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;
import net.neoforged.neoforge.event.entity.player.AttackEntityEvent;
import net.neoforged.neoforge.event.tick.EntityTickEvent;


import java.util.HashMap;
import java.util.Map;

public class BoatEnchantmentHandler {
    private static ItemStack lastUsedBoat = ItemStack.EMPTY;
    private static final Map<Boat, Double> boatSpeedMultipliers = new HashMap<>();

    @SubscribeEvent
    public void onItemUse(PlayerInteractEvent.RightClickItem event) {
        ItemStack stack = event.getItemStack();
        if (isBoatItem(stack)) {
            lastUsedBoat = stack.copy();
        }
    }

    @SubscribeEvent
    public void onBoatSpawn(EntityJoinLevelEvent event) {
        if (!(event.getEntity() instanceof Boat boat)) return;
        if (event.getLevel().isClientSide()) return;

        if (!boat.getPersistentData().contains("speedCounterManedgerRange")) {
            int enchantLevel = 0;
            
            if (!lastUsedBoat.isEmpty()) {
                var enchantments = lastUsedBoat.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY);
                var enchantmentRegistry = boat.level().registryAccess().registryOrThrow(Registries.ENCHANTMENT);
                var hydroboost = enchantmentRegistry.get(ResourceLocation.fromNamespaceAndPath("mhutilites", "hydroboost"));
                
                if (hydroboost != null) {
                    enchantLevel = enchantments.getLevel(enchantmentRegistry.wrapAsHolder(hydroboost));
                    enchantLevel = Math.min(Math.max(enchantLevel, 0), 3);
                }
                lastUsedBoat = ItemStack.EMPTY;
            }
            
            boat.getPersistentData().putInt("speedCounterManedgerRange", enchantLevel);
            
            System.out.println("Boat spawned with speed level: " + enchantLevel);
        }
    }

    @SubscribeEvent
    public void onBoatTick(EntityTickEvent.Post event) {
        if (!(event.getEntity() instanceof Boat boat)) return;
        if (boat.level().isClientSide()) return;
        
        int speedLevel = boat.getPersistentData().getInt("speedCounterManedgerRange");
        if (speedLevel > 0 && boat.isVehicle()) {
            var motion = boat.getDeltaMovement();
            
            // Применяем ускорение к любому движению
            if (Math.abs(motion.x) > 0.001 || Math.abs(motion.z) > 0.001) {
                double multiplier = switch (speedLevel) {
                    case 1 -> 2.0;
                    case 2 -> 3.0;
                    case 3 -> 5.0;
                    default -> 1.0;
                };
                
                boat.setDeltaMovement(motion.x * multiplier, motion.y, motion.z * multiplier);
            }
        }
    }

    @SubscribeEvent
    public void onBoatAttack(AttackEntityEvent event) {
        if (!(event.getTarget() instanceof Boat boat)) return;
        if (boat.level().isClientSide() || event.getEntity().isCreative()) return;
        
        int speedLevel = boat.getPersistentData().getInt("speedCounterManedgerRange");
        
        if (speedLevel > 0) {
            event.setCanceled(true);
            
            ItemStack boatStack = new ItemStack(boat.getDropItem());
            var enchantmentRegistry = boat.level().registryAccess().registryOrThrow(Registries.ENCHANTMENT);
            var hydroboost = enchantmentRegistry.get(ResourceLocation.fromNamespaceAndPath("mhutilites", "hydroboost"));
            
            if (hydroboost != null) {
                ItemEnchantments.Mutable enchantments = new ItemEnchantments.Mutable(
                    boatStack.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY)
                );
                enchantments.set(enchantmentRegistry.wrapAsHolder(hydroboost), speedLevel);
                boatStack.set(DataComponents.ENCHANTMENTS, enchantments.toImmutable());
                
                ItemEntity itemEntity = new ItemEntity(boat.level(), boat.getX(), boat.getY(), boat.getZ(), boatStack);
                boat.level().addFreshEntity(itemEntity);
            }
            
            boat.discard();
            boatSpeedMultipliers.remove(boat);
        }
    }

    public static double getSpeedMultiplier(Boat boat) {
        return boatSpeedMultipliers.getOrDefault(boat, 1.0);
    }

    private boolean isBoatItem(ItemStack stack) {
        return stack.getItem().toString().contains("boat");
    }
}

И вот его mixin -

package com.genamistik.neoforgemods.mhutilites.mixin;

import net.minecraft.world.entity.vehicle.Boat;
import org.spongepowered.asm.mixin.Mixin;

@Mixin(Boat.class)
public class BoatMixin {
}

Прошу помочь в ситуации, напишите в дс - gennadiishulkov

Ссылка на комментарий
Поделиться на другие сайты

тебе по идеи достаточно 2 миксина

1 миксин для самой лодки 
тебе нужны методы controlBoat для изменения скорости и getPickResult для выпадаемого предмета
реализуй так же поле что-то типо speedMultiplier для скорости и методы set и get к нему

2 метод для предмета лодки BoatItem, в нём перед спавном лодки нужно вызвать созданый ранее сеттер (тут нужен будет ещё интерфейс, чтобы методы были доступны вне миксина)
 

57 минут назад, GenkaMistikCoder сказал:

Прошу не использовать нейронку так как она тут бессильна(

grok и chat gpt могут хорошо генерировать код, но они не могут "угадывать" что тебе нужно сгенерировать,
декомпилируй код майнкрафта (нормальные ide это делают автоматически при открытии класса), давай нейронке и говори конкретно что тебе надо сделать

за ивенты не шарю, не пользуюсь, гайды по миксинам есть в документации fabric и ещё более подробная их работа в официальном репозитории от spongepower

Ссылка на комментарий
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...