Привет всем! Перевожу уроки с 1.15.2 на 1.16.1, и как это обычно бывает – начнём с предмета. В сравнении со старым гайдом суть осталась прежней, но есть обязательное изменение, без которого старый код выдаст ошибку. Но сами всё увидите, ведь для новых заинтересованных начнём всё с самого начала…
Итак. В этот раз мы создадим самый обычный предмет, который не будет иметь никакого функционала. Ещё одну палку, почему нет?
JAVA часть
Начинаем с пустым проектом. В первую очередь давайте добавим папку для предметов. Я предпочитаю создавать иерархию файлов максимально подобно оригинальной игре, а потому папка для предметов получает имя items.
В эту папку добавляем файл ModItems.java. Ну, или GSItems.java, MyItems.java и т.д. Имя не принципиально, короче :D.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package mod.astler.tutorial_mod_gs.item; import mod.astler.tutorial_mod_gs.TutorialGSMod; import net.minecraft.item.Item; import net.minecraftforge.fml.RegistryObject; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; public class ModItems { public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, TutorialGSMod.MODID); public static final RegistryObject<Item> STONE_STICK = ITEMS.register("stone_stick", () -> new Item(new Item.Properties())); } |
Те, кто видели версию для 1.15 – смогут найти то самое отличие, ну, а остальным оно и не нужно. Первая переменная — это регистр для предметов. Но он также регистр и для блоков, сущностей, структур. Всё зависит от указанного типа регистра. DeferredRegister, что в переводе буквально ОтложенныйРегистр, будет отвечать за своевременную регистрацию всего, что мы ему укажем. Очень удобный инструмент.
Вторая переменная тут – сам предмет. Вернее объект, который будет содержать все необходимые данные для создания нашего предмета при загрузке, а после содержать на него ссылку.
Уже неплохо, но теперь этот самый регистр нужно зарегистрировать. Это мы сделаем в родительском классе мода, в его конструкторе.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package mod.astler.tutorial_mod_gs; import mod.astler.tutorial_mod_gs.item.ModItems; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; @Mod(TutorialGSMod.MODID) @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) public class TutorialGSMod { public static final String MODID = "tutorial_mod_gs"; public TutorialGSMod() { IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); ModItems.ITEMS.register(bus); } } |
Ура! Предмет в игре!
Пришло время добавить ему текстуру и модель.
Ресурсы для предмета
За внешний вид предмета отвечает модель. Модель – специальный json файл, который должен быть расположен по такому пути: src/ main/ resources/ assets/ YOUR_MODID/ models/ item/ YOUR_MODEL.json
Для каменной палки в этом моде он будет таким: src/ main/ resources/ assets/ tutorial_mod_gs/ models/ item/ stone_stick.json
Вплоть до папки resources всё должно уже быть, а вот остальное нужно будет создать самому.
При создании .json файла смотрите внимательно, чтобы не оставить .json.txt или вроде того. Такие модели игра читать не будет.
Модель предмета с генерируемой моделью будет выглядеть вот так:
1 2 3 4 5 6 |
{ "parent": "item/generated", "textures": { "layer0": "tutorial_mod_gs:item/stone_stick" } } |
Как я и сказал, модель генерируемая, что и указано в родителе. Т.е. она будет создана в соответствии с текстурой и иметь толщину в один пиксель.
Имя необходимой текстуры тут layer0, и оно обязательное, но только для конкретно этого родителя. В разных моделях может быть разное количество текстур. К примеру булыжник, где будет всего одна или книжная полка, где их две, или верстак, где все стороны уникальны.
Имя текстуры указано в формате tutorial_mod_gs:item/stone_stick, это сообщает игре где конкретно искать нужную текстуру. Подобным образом мы можем использовать и ресурсы из игры, к примеру: minecraft:item/stick.
Теперь нам нужно добавить саму текстуру. Путь к текстурам тоже фиксирован и должен быть таким: resources/ assets/ tutorial_mod_gs/ textures/ item/ stone_stick.png. Я отредактировал текстуру обычной палки и получил что-то такое:
И давайте добавим локализацию, ведь приятно видеть именно свои названия, а не всякую тарабарщину.
Локализация
Как вы уже, возможно, привыкли: нужно снова создать новую папку. В этот раз путь будет таким: src/ main/ resources/ assets/ tutorial_mod_gs/ lang/. И сюда нам нужно добавить пару файлов, но можно и один. Для русского языка нам нужен файл ru_ru.json, а для английской (одной из них) en_us.json. Коды других языков можно посмотреть в ресурсах игры.
И пишем туда такой вот код:
1 2 3 |
{ "item.tutorial_mod_gs.stone_stick": "Каменная палка" } |
Где имя объекта локализации будет состоять из: Тип.Источник(Имя мода).ИмяПредмета. А значением и будет переведённое имя.
Вот для примера ещё английская версия:
1 2 3 |
{ "item.tutorial_mod_gs.stone_stick": "Stone Stick" } |
Окей. Основные шаги выполнены, давайте запускать! Предмет уже можно получить через команду.
Но согласитесь, что это не особо удобно. Для этого в креативе есть вкладки.
Добавляем вкладку
Наш предмет в игре есть, но командой его получать уж как-то совсем неудобно. Давайте добавим наш предмет в одну из существующих вкладок.
Для этого нужно дополнить свойства предмета в ModItems.java:
1 |
new Item.Properties() |
Этим:
1 |
new Item.Properties().group(ItemGroup.FOOD) |
И теперь палка попадёт к еде. Можно использовать любую из доступных вкладок:
BUILDING_BLOCKS
DECORATIONS
REDSTONE
TRANSPORTATION
MISC
TOOLS
COMBAT
BREWING
НО! Если в планах крупный мод, то лучше создать свою. Для этого добавим в папку предметов класс для новых вкладок (ModItemGroup.java).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
package mod.astler.tutorial_mod_gs.item; import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; import java.util.function.Supplier; public class ModItemGroup extends ItemGroup { private final Supplier<ItemStack> iconSupplier; public ModItemGroup(final String name, final Supplier<ItemStack> iconSupplier) { super(name); this.iconSupplier = iconSupplier; } @Override public ItemStack createIcon() { return iconSupplier.get(); } } |
И сюда же добавим ModItemGroups.java, где будем создавать все новые вкладки:
1 2 3 4 5 6 7 8 |
package mod.astler.tutorial_mod_gs.item; import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; public class ModItemGroups { public static final ItemGroup MOD_ITEMS_ITEM_GROUP = new ModItemGroup("tutorial_mod_gs_items", () -> new ItemStack(ModItems.STONE_STICK.get())); } |
Заменим вкладку для предмета:
1 |
new Item.Properties().group(ModItemGroups.MOD_ITEMS_ITEM_GROUP) |
И запускаем!
Отлично. Пользы от неё никакой, но это ведь палка, чего от неё ожидать? На этом сегодня всё, спасибо за внимание!
Пингбэк: Создание модов для Minecraft 1.15 – GeekStand
Пингбэк: [1.16.1] Добавляем новую еду – GeekStand
Пингбэк: [1.16.1] Новые инструменты – GeekStand