Наш первый предмет
Мы продолжаем наш цикл статей, сегодня мы создадим наш первый предмет. С вами RedGuy и мы начинаем!
Важно!
Перед началом работы вам необходимо изучить основы синтаксиса языка Java! Для их изучения мы рекомендуем использовать Codecademy или METANIT.
Подготовка
Раз уж мы с вами решили работать прямо как в сюжете, то нам нужно установить библиотеку HammerLib, которая позволит упростить разработку модов.
Установка HammerLib
Чтобы скачать эту библиотеку, нам нужно добавить репозиторий в наш проект. Для этого откройте файл
build.gradleи добавьте следующий код в блокrepositories:repositories { maven { name = "Zeitheron Maven" url = "https://maven.zeith.org/" } }После этого нам нужно указать нашему проекту, что мы хотим использовать эту библиотеку. Для этого добавьте
implementationв блокdependencies:dependencies { minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" annotationProcessor 'org.spongepowered:mixin:0.8.5:processor' implementation fg.deobf("org.zeith.hammerlib:HammerLib-1.19.2:19.3.73") }Дальше нам нужно перезагрузить проект, для этого нажмите на кнопку
Gradleна правой панели иReload.
Создаём интерфейс для предметов
Теперь нам нужно создать пакет в котором будет идти регистрация контента мода. Для этого нажмите правой кнопкой мыши на папку
ru.storyteam.mylittlestoryи выберитеNew -> Package.
И дописываем в конце
initи нажимаемEnter.
Дальше открываем окно создания класса в котором будет происходить регистрация предметов.

Создаём интерфейс
StoryItemsв котором будет происходить регистрация предметов.
У нас получается файл с таким содержанием.
package ru.storyteam.mylittlestory.init; public interface StoryItems { }Теперь необходимо обозначить, что этот интерфейс будет использоваться для регистрации предметов, для этого надо добавить аннотацию
@SimplyRegisterpackage ru.storyteam.mylittlestory.init; import org.zeith.hammerlib.annotations.SimplyRegister; @SimplyRegister public interface StoryItems { }
Создаём класс предмета
У модовых предметов может быть своя логика использования. Как она создаётся и хранится? Представим, что мы – охотники на оборотней и создадим серебряный меч! Теперь создадим класс для нашего предмета!
Для этого нам нужно создать пакет в котором будет храниться все эти классы. Это пакет
contentвнутри которого находится пакет предметовitems. Для создания вложенных пакетов мы можем перечислить их через точку:content.items
Внутри этого пакета мы создаём класс
SilverSwordItem.
У нас создаётся такой файл.
package ru.storyteam.mylittlestory.content.items; public class SilverSwordItem { }Дальше нам нужно указать что этот класс является предметом, в частности мечом. Для этого мы указываем что он наследуется от
SwordItem.package ru.storyteam.mylittlestory.content.items; public class SilverSwordItem extends SwordItem { }Но когда вы это сделаете, IDEA покажет что этот класс содержит ошибку, как на скриншоте ниже.

Чтобы это исправить, мы нажимаем на кнопочку
Create constructor matching super. После чего IDEA автоматически исправляет ошибку, создавая нужный конструктор.package ru.storyteam.mylittlestory.content.items; import net.minecraft.world.item.SwordItem; import net.minecraft.world.item.Tier; public class SilverSwordItem extends SwordItem { public SilverSwordItem(Tier p_43269_, int p_43270_, float p_43271_, Properties p_43272_) { super(p_43269_, p_43270_, p_43271_, p_43272_); } }Пока мы оставим этот класс в покое, но обязательно вернёмся к нему позже!
Создаём уровень для меча
Чтобы описать характеристики инструмента по его материалу, Minecraft использует интерфейс Tier. Так что давайте реализуем его!
Уже по отработанной механике создаём enum
StoryTiersв пакетеinit. Чтобы не растягивать этот пост, я даю вам готовую реализацию этого енама.package ru.storyteam.mylittlestory.init; import net.minecraft.world.item.Items; import net.minecraft.world.item.Tier; import net.minecraft.world.item.crafting.Ingredient; public enum StoryTiers implements Tier { SILVER(200, 6.0F, 2.0F, 2,14, Ingredient.of(Items.IRON_INGOT)); private final int uses; private final float speed; private final float attackDamageBonus; private final int level; private final int enchantmentValue; private final Ingredient repairIngredient; SwordTiers(int uses, float speed, float attackDamageBonus, int level, int enchantmentValue, Ingredient repairIngredient) { this.uses = uses; this.speed = speed; this.attackDamageBonus = attackDamageBonus; this.level = level; this.enchantmentValue = enchantmentValue; this.repairIngredient = repairIngredient; } @Override public int getUses() { return uses; } @Override public float getSpeed() { return speed; } @Override public float getAttackDamageBonus() { return attackDamageBonus; } @Override public int getLevel() { return level; } @Override public int getEnchantmentValue() { return enchantmentValue; } @Override public Ingredient getRepairIngredient() { return repairIngredient; } }В предложенной реализации для нас важна 1 строка. Это строка, в которой мы создаём наш материал, из которого будет сделан наш меч.
SILVER(200, 6.0F, 2.0F, 2,14, Ingredient.of(Items.IRON_INGOT));SILVER - Техническое название нашего материала которое мы будем использовать в коде.
200 - Прочность инструментов которые созданы из этого материала.
6.0F - Модификатор скорости предметов из этого материала (как быстро копает/бьёт).
2.0F - Базовый урон предметов из этого материала.
2 - Уровень добычи предмета, через который определятся какие блоки можно добывать этим инструментом. Например, кирка с уровнем 2 аналогична железной кирке, а кирка с уровнем 3 аналогична алмазной.
14 - Уровень зачаравательности этого предмета.
Представьте, что вы хотите зачаровать предмет в игре. Уровень зачарования, который вы получите, зависит от нескольких случайных факторов и свойства вашего предмета, называемого “enchantability”. Сначала игра берет свойство “enchantability” вашего предмета и использует его для генерации случайного числа. Это число будет находиться в диапазоне от 1 до половины вашего “enchantability”, плюс еще один. Например, если “enchantability” вашего предмета равно 4, то игра выберет случайное число от 1 до 3. Затем игра добавляет это случайное число к уровню зачарования, который вы выбрали. Таким образом, чем выше “enchantability” вашего предмета, тем выше может быть итоговый уровень зачарования. Но это еще не все. Игра также добавляет случайный бонус к вашему уровню зачарования. Этот бонус будет находиться в диапазоне от 0.85 до 1.15. Таким образом, ваш итоговый уровень зачарования может быть немного выше или ниже, чем вы ожидали. Наконец, если после всех этих шагов ваш итоговый уровень зачарования оказывается меньше 1, игра устанавливает его равным 1. Таким образом, процесс выбора уровня зачарования в игре включает в себя элемент случайности, но также зависит от свойства “enchantability” вашего предмета. Чем выше это свойство, тем выше может быть ваш итоговый уровень зачарования.Ingredient.of(Items.IRON_INGOT) - Предмет, который используется для починки инструментов из этого материала.
Регистрируем предмет
Чтобы Forge узнал о нашем предмете, мы должны его зарегистрировать.
Для того, чтобы зарегистрировать наш предмет, мы возвращаемся к нашему
StoryItemsи создаём переменную с нашим предметом, используя наш класс.package ru.storyteam.mylittlestory.init; import net.minecraft.world.item.Item; import org.zeith.hammerlib.annotations.SimplyRegister; import ru.storyteam.mylittlestory.content.items.SilverSwordItem; @SimplyRegister public interface StoryItems { SilverSwordItem SILVER_SWORD = new SilverSwordItem(StoryTiers.SILVER, 3, -2.4F, new Item.Properties()); }Но как сообщить игре о нашем предмете? Для этого мы воспользуемся HammerLib! Добавим аннотацию
@RegistryNamepackage ru.storyteam.mylittlestory.init; import net.minecraft.world.item.Item; import org.zeith.hammerlib.annotations.RegistryName; import org.zeith.hammerlib.annotations.SimplyRegister; import ru.storyteam.mylittlestory.content.items.SilverSwordItem; @SimplyRegister public interface StoryItems { @RegistryName("silver_sword") SilverSwordItem SILVER_SWORD = new SilverSwordItem(StoryTiers.SILVER, 3, -2.4F, new Item.Properties()); }
Ну что же, охотники, давайте запустим игру и посмотрим на наш меч!
Выдаём его через команду /give Dev mylittlestory:silver_sword

Текстурируем наш предмет
Немного не этого вы ждали, куб, да ещё и некрасивый… Давайте добавим текстуру нашему мечу!
Ищем папку
resources.В этой папке создаём папку
assets.Внутри папки
assetsсоздаём папку с названием мода, в нашем случаеmylittlestory.Внутри папки
mylittlestoryсоздаём папкуtextures.Внутри папки
texturesсоздаём папкуitem.И уже внутри этой папки мы размещаем нашу текстуру, обратите внимание, что её название должно совпадать с названием предмета которое мы установили внутри
@RegistryNameСпециально для вас и нашего маленького гайда, художественный отдел команды ST нарисовал этот красивый меч!
Но чтобы игра знала, как отрисовывать нашу текстуру, нам необходимо создать модель предмета. Для этого внутри папки
mylittlestoryсоздайте папкуmodels.Внутри папки
modelsсоздайте папкуitem.Внутри папки
itemсоздаём файлsilver_sword.jsonТак как в игре уже есть предметы-спрайты, которые держатся в руке, мы можем использовать их модель, для этого мы указываем parent модель.
{ "parent": "item/handheld", "textures" : { "layer0": "mylittlestory:item/silver_sword" } }В этом коде мы указали что наш предмет использует базовую модель для предмета который держится в руке и в качестве текстуры использует файл из мода
mylittlestoryиз папкиitemc названиемsilver_sword
Перезапускаем игру и смотрим на результат!

Красота!
Локализация
Но есть один нюанс...

Для того, чтобы в удобном формате писать файлы локализации мы опять воспользуемся HammerLib! Открываем главный класс нашего мода
MyLittleStory.Изначально наш класс будет засорён ненужными строчками и аннотациями, давайте подчистим его.
package ru.storyteam.mylittlestory; import com.mojang.logging.LogUtils; import net.minecraftforge.fml.common.Mod; import org.slf4j.Logger; // @Mod(MyLittleStory.MODID) public class MyLittleStory { public static final String MODID = "mylittlestory"; public static final Logger LOGGER = LogUtils.getLogger(); public MyLittleStory() { LanguageAdapter.registerMod(MODID); } }Теперь нам нужно создать файл со строками локализации, для этого в папке
mylittlestoryсоздайте папкуlangs.Внутри папки
langsсоздайте файл с названием нужного языка (ru_ru.langилиen_us.lang). > *.lang файл - это файл локализации, в котором хранятся все строки, которые используются в моде. Это позволяет переводить мод на другие языки.И внутри этого файла указываете нужное название для предмета в формате:
item.mylittlestory.silver_sword=Серебряный меч
Перезапускаем игру и смотрим что получилось.

Красота! На этом наша сегодняшняя статья кончается. Пишите в комментариях на Boosty ваше мнение и что вы хотите видеть дальше!
Оставайтесь с нами!