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

Как создавать свои зачарования на Forge 1.20.1?


GenkaMistikCoder

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

В теме 1 сообщение

Привет!

Каждый мод креатор хотя бы раз задумывался: «Как сделать зачарование?» Да, на эту тему есть множество гайдов, но мне они показались слишком водными. Сегодня я покажу, как создать зачарование на конкретном примере.

Начало

Создадим проект (пакеты и классы), на примере я покажу свой мод "More enchantments".

Настроем проект -

moreenchantments -
---init
------MoreEnchantmentsModEnchantments.java <- Главный класс для создание зачарований
---enchantment
------ExampleEnchantment.java <- Зачарование
---procedure
------ExampleEnchantmentProcedure.java <- Работа зачарования
---MoreEnchantmentsMod.java <- главный класс

Создав это все давайте зарегистрируем MoreEnchantmentsModEnchantments.java в главном классе -

import com.example.moreenchantments.init.MoreEnchantmentsModEnchantments; // Наш MoreEnchantmentsModEnchantments файл

// В методе MoreEnchantmentsMod мы добавим эту строчку
MoreEnchantmentsModEnchantments.REGISTRY.register(bus); // Или другоеназвание файла

И в файле MoreEnchantmentsModEnchantments напишем это -

package com.example.moreenchantments.init;

import net.minecraftforge.registries.RegistryObject;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.DeferredRegister;

import net.minecraft.world.item.enchantment.Enchantment;

import com.example.moreenchantments.MoreEnchantmentsMod;

public class MoreEnchantmentsModEnchantments {
	public static final DeferredRegister<Enchantment> REGISTRY = DeferredRegister.create(ForgeRegistries.ENCHANTMENTS, MoreEnchantmentsMod.MODID);
    // Тут будут все зачарования
}

В файле ExampleEnchantment.java мы создадим такой код (в комментариях будет написано что за что отвечает) -

package com.example.moreenchantments.enchantment;

import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraft.world.item.enchantment.EnchantmentCategory;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.entity.EquipmentSlot;

import java.util.List;

public class ExampleEnchantmentEnchantment extends Enchantment {
	public ExampleEnchantmentEnchantment(EquipmentSlot... slots) {
		super(Enchantment.Rarity.COMMON, EnchantmentCategory.BREAKABLE, slots); // редкость - Enchantment.Rarity, категория - EnchantmentCategory (например BREAKABLE)
	}

	@Override
	public int getMaxLevel() {
		return 2; // Максимальное кол-во уровней зачарования
	}

	@Override
	protected boolean checkCompatibility(Enchantment ench) {
		return List.of(Enchantments.ALL_DAMAGE_PROTECTION).contains(ench); // Допустимые комбинации зачарования
	}

	@Override
	public boolean canApplyAtEnchantingTable(ItemStack itemstack) {
		return Ingredient.of(new ItemStack(Items.WOODEN_PICKAXE)).test(itemstack); // На что может распростронятся
	}

	@Override
	public boolean isTreasureOnly() {
		return true; // зачарование сокровище (true/false)
	}

	@Override
	public boolean isCurse() {
		return true; // зачарование проклятье (true/false)
	}

	@Override
	public boolean isAllowedOnBooks() {
		return false; // может быть в книгах (true/false)
	}

	@Override
	public boolean isDiscoverable() {
		return false; // зачарование можнет появится в качестве лута? (true/false)
	}

	@Override
	public boolean isTradeable() {
		return false; // зачарование можно купить у жителей (true/false)
	}
}

Зарегистрируем его в MoreEnchantmentsModEnchantments -

import com.example.moreenchantments.enchantment.ExampleEnchantmentEnchantment;

// Добавим в класс
public static final RegistryObject<Enchantment> EXAMPLE_ENCHANTMENT = REGISTRY.register("example_enchantment", () -> new ExampleEnchantmentEnchantment());

Но сейчас он является пустышкой, но давайте мы добавим функционал - с шансом 20-50% кирка выпадет из инвентаря -

package com.example.moreenchantments.procedures;

import net.minecraft.world.item.ItemStack;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.util.RandomSource;
import net.minecraftforge.event.level.BlockEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.common.Mod;

import javax.annotation.Nullable;

import com.example.moreenchantments.init.MoreEnchantmentsModEnchantments;

@Mod.EventBusSubscriber
public class CurseOfTheSlipperyHandleProcedureProcedure {
    
    private static final float BASE_DROP_CHANCE = 0.2f; // 20% базовый шанс
    private static final float CHANCE_PER_LEVEL = 0.1f; // +10% за каждый уровень

    @SubscribeEvent
    public static void onBlockBreak(BlockEvent.BreakEvent event) {
        execute(event, event.getPlayer());
    }

    @SubscribeEvent
    public static void onItemUse(PlayerInteractEvent.RightClickItem event) {
        execute(event, event.getEntity());
    }

    @SubscribeEvent
    public static void onBlockInteract(PlayerInteractEvent.RightClickBlock event) {
        execute(event, event.getEntity());
    }

    public static void execute() {
        execute(null, null);
    }

    private static void execute(@Nullable Event event, @Nullable Player player) {
        if (player == null || player.level().isClientSide()) return;
        
        ItemStack mainHandItem = player.getItemBySlot(EquipmentSlot.MAINHAND);
        if (mainHandItem.isEmpty()) return;
        
        int enchantmentLevel = EnchantmentHelper.getItemEnchantmentLevel(
            MoreEnchantmentsModEnchantments.EXAMPLE_ENCHANTMENT.get(), 
            mainHandItem
        );
        
        if (enchantmentLevel <= 0) return;
        
        RandomSource random = player.getRandom();
        float dropChance = BASE_DROP_CHANCE + (CHANCE_PER_LEVEL * (enchantmentLevel - 1));
        
        if (random.nextFloat() < dropChance) {
            // Выбрасываем предмет из руки игрока
            player.drop(mainHandItem, false, true);
            player.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY);
            
            // Отменяем событие, если оно было передано
            if (event != null && event.isCancelable()) {
                event.setCanceled(true);
            }
        }
    }
}

Если вы хотите другой функционал то просто залейте в нейронку, но у неё обычно не всегда получается это сделать (2-3 попытки).

Удачной разработки!🙃

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

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

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

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

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

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

Войти

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

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

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