Создаём мод с StoryTeam Help

Наш первый предмет

Мы продолжаем наш цикл статей, сегодня мы создадим наш первый предмет. С вами RedGuy и мы начинаем!

Важно!

Перед началом работы вам необходимо изучить основы синтаксиса языка Java! Для их изучения мы рекомендуем использовать Codecademy или METANIT.

Подготовка

Раз уж мы с вами решили работать прямо как в сюжете, то нам нужно установить библиотеку HammerLib, которая позволит упростить разработку модов.

Установка HammerLib

  1. Чтобы скачать эту библиотеку, нам нужно добавить репозиторий в наш проект. Для этого откройте файл build.gradle и добавьте следующий код в блок repositories:

    repositories { maven { name = "Zeitheron Maven" url = "https://maven.zeith.org/" } }
  2. После этого нам нужно указать нашему проекту, что мы хотим использовать эту библиотеку. Для этого добавьте 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") }
  3. Дальше нам нужно перезагрузить проект, для этого нажмите на кнопку Gradle на правой панели и Reload.

    gradleReload.png

Создаём интерфейс для предметов

  1. Теперь нам нужно создать пакет в котором будет идти регистрация контента мода. Для этого нажмите правой кнопкой мыши на папку ru.storyteam.mylittlestory и выберите New -> Package.

    createPackage.png
  2. И дописываем в конце init и нажимаем Enter.

    createPackageInit.png
  3. Дальше открываем окно создания класса в котором будет происходить регистрация предметов.

    createClass.png
  4. Создаём интерфейс StoryItems в котором будет происходить регистрация предметов.

    createInterface.png

    У нас получается файл с таким содержанием.

    package ru.storyteam.mylittlestory.init; public interface StoryItems { }
  5. Теперь необходимо обозначить, что этот интерфейс будет использоваться для регистрации предметов, для этого надо добавить аннотацию @SimplyRegister

    package ru.storyteam.mylittlestory.init; import org.zeith.hammerlib.annotations.SimplyRegister; @SimplyRegister public interface StoryItems { }

Создаём класс предмета

У модовых предметов может быть своя логика использования. Как она создаётся и хранится? Представим, что мы – охотники на оборотней и создадим серебряный меч! Теперь создадим класс для нашего предмета!

  1. Для этого нам нужно создать пакет в котором будет храниться все эти классы. Это пакет content внутри которого находится пакет предметов items. Для создания вложенных пакетов мы можем перечислить их через точку: content.items

    createPackageItems.png
  2. Внутри этого пакета мы создаём класс SilverSwordItem.

    createItemClass.png

    У нас создаётся такой файл.

    package ru.storyteam.mylittlestory.content.items; public class SilverSwordItem { }
  3. Дальше нам нужно указать что этот класс является предметом, в частности мечом. Для этого мы указываем что он наследуется от SwordItem.

    package ru.storyteam.mylittlestory.content.items; public class SilverSwordItem extends SwordItem { }
  4. Но когда вы это сделаете, IDEA покажет что этот класс содержит ошибку, как на скриншоте ниже.

    error.png

    Чтобы это исправить, мы нажимаем на кнопочку 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. Так что давайте реализуем его!

  1. Уже по отработанной механике создаём 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; } }
  2. В предложенной реализации для нас важна 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 узнал о нашем предмете, мы должны его зарегистрировать.

  1. Для того, чтобы зарегистрировать наш предмет, мы возвращаемся к нашему 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()); }
  2. Но как сообщить игре о нашем предмете? Для этого мы воспользуемся HammerLib! Добавим аннотацию @RegistryName

    package 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

sword.png

Текстурируем наш предмет

Немного не этого вы ждали, куб, да ещё и некрасивый… Давайте добавим текстуру нашему мечу!

  1. Ищем папку resources.

  2. В этой папке создаём папку assets.

  3. Внутри папки assets создаём папку с названием мода, в нашем случае mylittlestory.

  4. Внутри папки mylittlestory создаём папку textures.

  5. Внутри папки textures создаём папку item.

  6. И уже внутри этой папки мы размещаем нашу текстуру, обратите внимание, что её название должно совпадать с названием предмета которое мы установили внутри @RegistryName Специально для вас и нашего маленького гайда, художественный отдел команды ST нарисовал этот красивый меч!

    silver_sword.png
  7. Но чтобы игра знала, как отрисовывать нашу текстуру, нам необходимо создать модель предмета. Для этого внутри папки mylittlestory создайте папку models.

  8. Внутри папки models создайте папку item.

  9. Внутри папки item создаём файл silver_sword.json

  10. Так как в игре уже есть предметы-спрайты, которые держатся в руке, мы можем использовать их модель, для этого мы указываем parent модель.

    { "parent": "item/handheld", "textures" : { "layer0": "mylittlestory:item/silver_sword" } }

    В этом коде мы указали что наш предмет использует базовую модель для предмета который держится в руке и в качестве текстуры использует файл из мода mylittlestory из папки item c названием silver_sword

Перезапускаем игру и смотрим на результат!

swordWithTexure.png

Красота!

Локализация

Но есть один нюанс...

wrongLocale.png
  1. Для того, чтобы в удобном формате писать файлы локализации мы опять воспользуемся HammerLib! Открываем главный класс нашего мода MyLittleStory.

  2. Изначально наш класс будет засорён ненужными строчками и аннотациями, давайте подчистим его.

    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); } }
  3. Теперь нам нужно создать файл со строками локализации, для этого в папке mylittlestory создайте папку langs.

  4. Внутри папки langs создайте файл с названием нужного языка (ru_ru.lang или en_us.lang). > *.lang файл - это файл локализации, в котором хранятся все строки, которые используются в моде. Это позволяет переводить мод на другие языки.

  5. И внутри этого файла указываете нужное название для предмета в формате:

    item.mylittlestory.silver_sword=Серебряный меч

Перезапускаем игру и смотрим что получилось.

correctLocale.png

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

Оставайтесь с нами!

Last modified: 03 декабря 2023