Создание пользовательских событий в Minecraft

published on 04 September 2024

Хотите добавить уникальные механики в Minecraft? Пользовательские события - ваш ключ к успеху! Вот краткое руководство:

  1. Спланируйте событие
  2. Напишите код класса события
  3. Создайте обработчик события
  4. Зарегистрируйте событие
  5. Протестируйте работу

Главное:

  • Наследуйте класс от Event
  • Используйте @SubscribeEvent для обработчиков
  • Регистрируйте через MinecraftForge.EVENT_BUS.register()
  • Запускайте событие через MinecraftForge.EVENT_BUS.post()

Пример простого события:

public class МоеСобытие extends Event {
  private final String сообщение;
  
  public МоеСобытие(String сообщение) {
    this.сообщение = сообщение;
  }

  public String getСообщение() {
    return сообщение;
  }
}

Создавайте, тестируйте, экспериментируйте! Пользовательские события откроют новые возможности для ваших модов Minecraft.

Что нужно перед началом работы

Перед созданием пользовательских событий вам понадобится:

Инструменты и ПО

"Для моддинга Minecraft нужен JDK версии 17" - из руководства по моддингу

Код модов несовместим между разными версиями игры.

Базовые навыки

  • Знание Java
  • Понимание механики Minecraft
  • Знакомство с API модлоадера (Forge или Fabric)
Модлоадер Особенности
Forge Сложнее, поддерживает масштабные моды
Fabric Легковесный, быстрее обновляется

"Fabric позволяет быстрее обновлять моды, Forge известен обширной библиотекой" - из сравнения модлоадеров

Для создания событий нужно работать с классом Event в Forge или создавать интерфейсы обратного вызова в Fabric.

Как работают события в Minecraft

Minecraft

События в Minecraft позволяют модам взаимодействовать с игрой. Forge использует систему шин событий:

  1. Игра генерирует событие (например, разрушение блока)
  2. Событие отправляется на шину MinecraftForge.EVENT_BUS
  3. Моды получают уведомление и реагируют

Пример обработчика:

public class MyEventHandler {
    @SubscribeEvent
    public void onBlockBreak(BlockEvent.BreakEvent event) {
        // Код при разрушении блока
    }
}

Регистрация: MinecraftForge.EVENT_BUS.register()

Некоторые события можно отменить (помечены @Cancelable).

Тип события Описание Пример
Отменяемые Можно отменить Предотвращение разрушения блоков
Неотменяемые Нельзя отменить Изменение урона игроку

"Система событий позволяет модам взаимодействовать без изменения кода игры" - из документации Forge

События делятся на:

  1. События Forge (состояние игры)
  2. События модов (состояние мода)

Планирование вашего события

При создании события важно определить его цели:

Когда создавать событие

  • Стандартные события не подходят
  • Нужна уникальная механика
  • Требуется отслеживать специфические действия

Постановка целей

Примеры целей:

Цель Описание Пример
Отслеживание Подсчет действий Подсчет размещенных блоков
Изменение механики Изменение поведения Изменение результата крафта
Новые возможности Расширение функционала Возрождение с эффектами

"Что является целью? Когда срабатывает? Что ожидаете от подписчиков?" - Choonster, разработчик модов

Учитывайте взаимодействие с другими модами при планировании.

Написание кода события

Создание класса события:

public class СобытиеКровавойЛуны extends Event {
    private final World мир;
    private final int продолжительность;

    public СобытиеКровавойЛуны(World мир, int продолжительность) {
        this.мир = мир;
        this.продолжительность = продолжительность;
    }

    public World getМир() {
        return мир;
    }

    public int getПродолжительность() {
        return продолжительность;
    }
}

Для отменяемых событий:

public class СобытиеКровавойЛуны extends Event implements Cancellable {
    private boolean отменено = false;

    @Override
    public boolean isCancelled() {
        return отменено;
    }

    @Override
    public void setCancelled(boolean отмена) {
        this.отменено = отмена;
    }
}

Добавьте HandlerList:

public class СобытиеКровавойЛуны extends Event {
    private static final HandlerList HANDLERS = new HandlerList();

    public static HandlerList getHandlerList() {
        return HANDLERS;
    }

    @Override
    public HandlerList getHandlers() {
        return HANDLERS;
    }
}

Создание обработчика события

Пример обработчика:

public class МойОбработчикСобытий {
    @SubscribeEvent
    public void обработатьСобытиеКровавойЛуны(СобытиеКровавойЛуны событие) {
        World мир = событие.getМир();
        int продолжительность = событие.getПродолжительность();

        мир.setDayTime(18000);

        for (Entity сущность : мир.getEntities()) {
            if (сущность instanceof Monster) {
                ((Monster) сущность).addPotionEffect(new EffectInstance(Effects.STRENGTH, продолжительность * 20, 1));
            }
        }

        for (ServerPlayerEntity игрок : мир.getPlayers()) {
            игрок.sendMessage(new StringTextComponent("Началась кровавая луна! Будьте осторожны!"), игрок.getUUID());
        }
    }
}

Регистрация:

MinecraftForge.EVENT_BUS.register(new МойОбработчикСобытий());

Для статических обработчиков:

@Mod.EventBusSubscriber(modid = "мой_мод")
public class СтатическийОбработчикСобытий {
    @SubscribeEvent
    public static void обработатьСобытие(СобытиеКровавойЛуны событие) {
        // Код обработки
    }
}
sbb-itb-b1cf51d

Регистрация вашего события

Регистрация обработчика:

MinecraftForge.EVENT_BUS.register(new МойОбработчикСобытий());

Для статических обработчиков:

MinecraftForge.EVENT_BUS.register(МойСтатическийОбработчикСобытий.class);

С аннотацией:

@Mod.EventBusSubscriber(modid = "мой_мод")
public class МойОбработчикСобытий {
    @SubscribeEvent
    public static void обработатьСобытие(МоеПользовательскоеСобытие событие) {
        // Код обработки
    }
}

Для событий жизненного цикла мода:

FMLJavaModLoadingContext.get().getModEventBus().register(new МойОбработчикСобытийМода());

Запуск вашего события

Запуск события:

МоеПользовательскоеСобытие событие = new МоеПользовательскоеСобытие(параметры);
MinecraftForge.EVENT_BUS.post(событие);

if (!событие.isCanceled()) {
    // Выполните действия
}

Пример запуска при разрушении спаунера:

@SubscribeEvent
public void onBlockBreak(BlockEvent.BreakEvent event) {
    if (event.getState().getBlock() == Blocks.MOB_SPAWNER) {
        МоеСобытиеРазрушенияСпаунера событие = new МоеСобытиеРазрушенияСпаунера(event.getPos(), event.getPlayer());
        MinecraftForge.EVENT_BUS.post(событие);

        if (!событие.isCanceled()) {
            event.getWorld().spawnEntity(new ItemEntity(event.getWorld(), event.getPos().getX(), event.getPos().getY(), event.getPos().getZ(), new ItemStack(Items.EXPERIENCE_BOTTLE)));
        }
    }
}

Тестирование вашего события

Способы тестирования:

  1. Консольные сообщения:
@SubscribeEvent
public void onМоеСобытие(МоеПользовательскоеСобытие событие) {
    System.out.println("Мое событие сработало!");
}
  1. Game Test Framework:
@GameTest
public static void тестМоегоСобытия(GameTestHelper helper) {
    helper.runAtTickTime(20, () -> {
        МоеПользовательскоеСобытие событие = new МоеПользовательскоеСобытие();
        MinecraftForge.EVENT_BUS.post(событие);
    });

    helper.succeedOnTickWhen(40, () -> {
        helper.assertBlock(new BlockPos(1, 1, 1), b -> b == Blocks.DIAMOND_BLOCK, "Блок не изменился на алмазный");
    });
}
  1. Отладка с точками останова

  2. Проверка отмены события:

@SubscribeEvent
public void onМоеСобытие(МоеПользовательскоеСобытие событие) {
    событие.setCanceled(true);
    System.out.println("Событие отменено");
}

// В месте вызова события
if (!событие.isCanceled()) {
    // Выполняем действия
} else {
    System.out.println("Событие было отменено");
}
  1. Тестовый мод:
@Mod("тестовый_мод")
public class ТестовыйМод {
    @SubscribeEvent
    public void onМоеСобытие(МоеПользовательскоеСобытие событие) {
        System.out.println("Тестовый мод обработал событие");
    }
}

Советы по созданию лучших событий

  1. Используйте подходящие базовые классы:
@SubscribeEvent
public void onAttackEntity(AttackEntityEvent event) {
    if (event.getTarget() instanceof Creeper) {
        // Код для атаки крипера
    }
}
  1. Обрабатывайте отмену событий:
@SubscribeEvent
public void onМоеСобытие(МоеПользовательскоеСобытие событие) {
    if (!событие.isCanceled()) {
        // Выполняем действия
    } else {
        System.out.println("Событие отменено");
    }
}
  1. Используйте приоритеты:
@SubscribeEvent(priority = EventPriority.HIGH)
public void onВысокийПриоритет(МоеСобытие событие) {
    // Код высокого приоритета
}
  1. Тщательно тестируйте

  2. Проверяйте совместимость с другими модами

  3. Документируйте код:

/**
 * Обрабатывает стрижку овцы.
 * @param player Игрок
 * @param sheep Овца
 * @return ActionResult.FAIL если отменено, иначе ActionResult.PASS
 */
SheepShearCallback.EVENT.register((player, sheep) -> {
    // Код
    return ActionResult.PASS;
});

Продвинутые функции событий

  1. Отменяемые события:
@Cancelable
public class МоеОтменяемоеСобытие extends Event implements Cancelable {
    private boolean отменено = false;

    @Override
    public boolean isCanceled() {
        return отменено;
    }

    @Override
    public void setCanceled(boolean cancel) {
        отменено = cancel;
    }
}
  1. Результаты событий:
public class СобытиеСРезультатом extends Event {
    private Event.Result результат = Event.Result.DEFAULT;

    public Event.Result getResult() {
        return результат;
    }

    public void setResult(Event.Result результат) {
        this.результат = результат;
    }
}
  1. Приоритеты обработчиков:
@SubscribeEvent(priority = EventPriority.HIGH)
public void onВысокийПриоритет(МоеСобытие событие) {
    // Код высокого приоритета
}

Работа с другими модами

  1. Используйте правильную шину событий:
Шина Использование
MinecraftForge.EVENT_BUS События состояния игры
FMLJavaModLoadingContext.get().getModEventBus() События состояния мода
  1. Проверяйте отменяемость событий

  2. Используйте InterModComms для взаимодействия между модами

  3. Устанавливайте приоритеты обработки

  4. Тестируйте совместимость

  5. Обрабатывайте отмененные события:

@SubscribeEvent(receiveCanceled = true)
public void onМоеСобытие(МоеСобытие событие) {
    if (событие.isCanceled()) {
        // Обработка отмененного события
    } else {
        // Обычная обработка
    }
}

Заключение

Создание пользовательских событий - мощный инструмент для модификации Minecraft. Ключевые шаги:

  1. Планирование
  2. Написание кода
  3. Создание обработчика
  4. Регистрация
  5. Тестирование

Советы:

  • Изучайте ресурсы сообщества
  • Присоединяйтесь к сообществу моддеров
  • Тестируйте совместимость

Помните, что моддинг - творческий процесс. Экспериментируйте и создавайте уникальный контент!

Related posts

Read more

Built on Unicorn Platform