Привет. В прошлом уроке всё прошло гладко? Тогда время добавить в наш Fabric мод чего-то… Да хоть чего-то! По классике это будет предмет. Самый простой элемент в игре. Наш предмет будет тоже максимально простым, и делать пока с ним ничего не выйдет. Но он будет в творческой вкладке, и мы даже докинем для него несколько рецептов крафта. Погнали!
Добавляем предмет в наш Fabric мод
Код, пора писать код. Что у нас есть сейчас? Файлик мода и всё.
Добавим в папку first новую папку с именем items, а внутри неё файл ModItems.java. В нём добавим публичную статическую переменную типа Item с именем RUBY. Возьмем текстуру рубина, который потом стал изумрудом с Вики. Вернём было величие, скажем так.
1 |
public static Item RUBY = new Item(new Item.Settings().group(ItemGroup.MISC)); |
Разберём. Все предметы в игре — это объекты Item. При этом блоки в сумке – тоже предметы. И вообще, всё, что вы используете в инвентаре – предметы. А если они лежат на земле, то это уже сущности (наподобие мобов). А блоки это лишь то, что стоит в игровом мире. Как только мы его ломаем – получаем сущность на земле. Как только мы её подбираем – получаем предмет в инвентарь. Такая вот система. Но изначально всё исходит именно от Item. Так как даже та самая лежащая на земле предмет сущность-предмет получаем отображаемую модель только от Item, который она содержит. Вроде объяснил. Но это не точно. Блоки в мире, всё, что двигается — сущности, всё, что в сумке — предметы.
Дальше в конструктор Item мы передаём другой объект, который служит для настройки основных параметров предмета. Group отвечает за вкладку. Все доступные вкладки можно найти в файле net.minecraft.item.ItemGroup.java.
Ладно, вот что получили:
Регистрация предмета в игре при помощи Fabric
Добавим переменную с id мода, который мы указали в json файлике в прошлый раз. Чтобы избежать потенциальных ошибок и путаницы лучше всего создать статическую переменную с айдишником мода прямо в классе мода:
Отлично. Теперь снова к предмету, который вроде как уже существует… Но игра о нём ещё не знает. Для регистрации наших предметов, блоков и всего остального создадим файл в папке first и назовём его ModRegister.java.
В нём прописываем такую конструкцию:
1 2 3 |
public static void registerItems() { Registry.register(Registry.ITEM, new Identifier(MOD_ID, "ruby"), RUBY); } |
Вызываем Registry, который используется для регистрации предметов в игре. Указываем в первом параметре, что будем регистрировать предмет.
Потом создаём для него идентификатор. Вроде как в самом Minecraft, где мы пишем: minecraft:dirt, например. А вот рубин будет иметь идентификатор first_gs_mod:ruby. Это также очень спасает от конфликтов модов, в которых может быть много ruby.
Последним, третьим параметром тут стал сам предмет RUBY. В импортах вы можете увидеть, что именно его я и импортировал из файла ModItems.
Знает ли игра теперь о наших предметах? Нет, ведь функция не использована. И наконец настал звёздный час для класса мода ModMain, где была пустая функция с именем onInitialize, куда мы и прописываем вызов registerItems.
1 2 3 4 |
@Override public void onInitialize() { ModRegister.registerItems(); } |
Ну, а теперь то игра знает о предмете?! Ну, вообще-то да. Можно уже запустить и увидеть это чудовище, без текстуры и имени:
Но так ведь не прикольно?
Так что добавим ему модель и текстуру.
Ресурсы для предмета
За внешний вид предмета отвечает модель. Модель – специальный json файл, который должен быть расположен по такому пути: resources/assets/YOUR_MODID/models/item/YOUR_ITEM.json
Кстати, формат ресурсов не связан с Fabric, и аналогичен как для Forge, так и для датапаков. Так что если вы имели опыт с чем-то из озвученного, то вам будет куда легче 😉.
Для моего рубина он будет таким: resources/assets/first_gs_mod/models/item/ruby.json
Папка assets у вас уже есть, если вы добавили иконку моду, то и папка с id мода тоже есть. Остальное создаём.
При создании .json файла смотрите внимательно, чтобы не оставить .json.txt или вроде того. Такие модели игра читать не будет!!!
Модель предмета с генерируемой моделью будет выглядеть вот так:
1 2 3 4 5 6 |
{ "parent": "item/generated", "textures": { "layer0": "first_gs_mod:item/ruby" } } |
Как я и сказал, модель генерируемая, что и указано в родителе. Т.е. она будет создана в соответствии с текстурой и иметь толщину в один пиксель.
Имя необходимой текстуры тут layer0, и оно обязательное, но только для конкретно этого родителя. В разных моделях может быть разное количество текстур. К примеру булыжник, где будет всего одна или книжная полка, где их две, или верстак, где все стороны уникальны.
Имя текстуры указано в формате first_gs_mod:item/ruby, это сообщает игре где конкретно искать нужную текстуру. Подобным образом мы можем использовать и ресурсы из игры, к примеру: minecraft:item/stick.
Теперь нам нужно добавить саму текстуру. Путь к текстурам тоже фиксирован и должен быть таким: resources/assets/YOUR_MODID/textures/item/YOUR_ITEM.png. А для меня: resources/assets/first_gs_mod/textures/item/ruby.png
Текстуру я взял слегка кривую, конечно. Но работает. Всё же красота!
И давайте добавим локализацию, ведь приятно видеть именно свои названия, а не всякую тарабарщину.
Локализация
Знаете что дальше? Нужно добавить новую папку. В этот раз путь будет таким: src/main/resources/assets/MOD_ID/lang/. И сюда нам нужно добавить языковые json файлы. Для русского языка нам нужен файл ru_ru.json, а для английской (одной из них) en_us.json. Коды других языков можно посмотреть в ресурсах игры. Этот шаг тоже не связан с Fabric, и аналогичен как для Forge, так и для датапаков.
И пишем туда такой вот код:
1 2 3 |
{ "item.first_gs_mod.ruby": "Рубин" } |
Где имя объекта локализации будет состоять из: Тип.MOD_ID.ИмяПредмета. А значением и будет переведённое имя.
Вот для примера ещё английская версия:
1 2 3 |
{ "item.first_gs_mod.ruby": "Рубин" } |
Окей. Основные шаги выполнены, давайте запускать!
Ура! Вы прекрасны! На этом всё, спасибо за внимание!
Ах, да. Сверим файлы. У вас должно быть +- также: