Собственные чары#
В игре имеется большое кол-во разнообразных чар, которые позволяют улучшить инструменты и броню. В данной статье мы поговорим о создании собственных чар.
Создание чар#
Создадим чары, которые будут накладывать отравление на сущность, если её ударить.
package ru.mcmodding.tutorial.common.enchantment;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnumEnchantmentType;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
public class PoisonBladeEnchantment extends Enchantment {
public PoisonBladeEnchantment() {
super(70, 3, EnumEnchantmentType.weapon);
setName("poison_blade");
addToBookList(this);
}
/**
* Дополнительная обработка при атаке сущности.
*
* @param attacker атакующий.
* @param victim цель атакующего или его жертва.
* @param level уровень чар
*/
@Override
public void func_151368_a(EntityLivingBase attacker, Entity victim, int level) {
if (victim instanceof EntityLivingBase) {
((EntityLivingBase) victim).addPotionEffect(new PotionEffect(Potion.poison.id, 200 * level));
}
}
/**
* Максимальный уровень чар.
*
* @return Возвращает максимальный уровень для зачаривания.
*/
@Override
public int getMaxLevel() {
return 5;
}
}
Конструктор класса Enchantment принимает три параметра:
enchantId- уникальный идентификатор чар. Должен быть уникальным, чтобы избежать конфликта с ванильными или модовыми чарами.weight- "вес" чар, влияет на стоимость зачаривания в наковальне, а также вероятность появления в генерации лута и у жителей в торговле.type- применимость чар к предметам.
Обратите внимание!
Всего в игре может быть 256 чар(таблицу имеющихся чар и их идентификаторы можно посмотреть в таблице, в конце статьи), не забывайте про существование модов и хорошим тоном будет считаться вынос идентификатора чар в конфиг, чтобы избежать пересечения с другими модами и возможностью изменить идентификатор. Вы можете расширить самостоятельно массив чар с помощью рефлексии или использовать моды, которые уже это делают.
Применимость чар определяется с помощью перечисления EnumEnchantmentType:
| Название | Описание |
|---|---|
| all | Все предметы |
| armor | Броня |
| armor_feet | Ботинки |
| armor_legs | Штаны |
| armor_torso | Нагрудник |
| armor_head | Шлем |
| weapon | Оружие |
| digger | Инструмент |
| fishing_rod | Удочка |
| breakable | Предмет имеющий прочность |
| bow | Лук |
Также вы могли заметить вызов метода Enchantment#addToBookList(Enchantment), данный метод добавляет в список книг с чарами
наши новосозданные чары. Если вы не хотите, чтобы была книга с вашими чарами, то просто удалите вызов.
Вы также можете переопределить в своей реализации чар такие методы:
Enchantment#getMinLevel- возвращает минимальный уровень чар.Enchantment#getMaxLevel- возвращает максимальный уровень чар.Enchantment#getMinEnchantability(Integer)- минимальный уровень зачаровываемости, рассчитывается по формуле:1 + level * 10.Enchantment#getMaxEnchantability(Integer)- максимальный уровень зачаровываемости, рассчитывается по формуле:Enchantment#getMinEnchantability(Integer) + 5.Enchantment#calcModifierDamage(Integer, DamageSource)- расчёт модификатора урона по уровню иDamageSource.Enchantment#func_152376_a(Integer, EnumCreatureAttribute)- расчёт дополнительного урона по уровню иEnumCreatureAttribute.Enchantment#canApplyTogether(Enchantment)- возможность совмещать текущие чары с другими.Enchantment#setName(String)- задаёт имя чар с шаблономenchantment.*name*.Enchantment#canApply(ItemStack)- возможность накладывать чары на предмет.Enchantment#func_151368_a(EntityLivingBase, Entity, int)- дополнительная обработка при атаке сущности. Метод принимает аргументы:атакующий,его цельиуровень чар.Enchantment#func_151367_b(EntityLivingBase, Entity, int)- дополнительная обработка для защиты при нападении. Метод принимает аргументы:атакующий,его цельиуровень чар.Enchantment#canApplyAtEnchantingTable(ItemStack)- возможность получения чар через стол зачарования.Enchantment#isAllowedOnBooks- возможность накладывать текущие чары на книгу через стол зачарования.
Подсказка
Если положить обычную книгу в стол зачарования, то можно получить книгу с чарами.
Приступим к регистрации.
package ru.mcmodding.tutorial.common.handler;
import net.minecraft.enchantment.Enchantment;
import ru.mcmodding.tutorial.common.enchantment.PoisonBladeEnchantment;
public class ModEnchantments {
public static Enchantment poisonBlade;
public static void register() {
poisonBlade = new PoisonBladeEnchantment();
}
}
И вызовем метод ModEnchantments#register в CommonProxy#preInit:
package ru.mcmodding.tutorial.common;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import ru.mcmodding.tutorial.common.handler.*;
public class CommonProxy {
public void preInit(FMLPreInitializationEvent event) {
// ...
ModEnchantments.register();
}
}
Зайдём в игру и проверим то, что у нас получилось.



Чары плавления блоков#
Создадим по предыдущей части чары для плавления, но теперь нам понадобится событие BlockEvent.HarvestDropsEvent.
package ru.mcmodding.tutorial.common.enchantment;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnumEnchantmentType;
public class MeltingEnchantment extends Enchantment {
public MeltingEnchantment() {
super(71, 4, EnumEnchantmentType.digger);
setName("melting");
addToBookList(this);
}
}
Перейдём в класс с Forge событиями и добавим обработку события BlockEvent.HarvestDropsEvent:
package ru.mcmodding.tutorial.common.handler;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.FurnaceRecipes;
import net.minecraftforge.event.world.BlockEvent;
import java.util.LinkedList;
import java.util.List;
public class ForgeEventListener {
@SubscribeEvent
public void onHarvest(BlockEvent.HarvestDropsEvent event) {
ItemStack inHand = event.harvester.getHeldItem();
if (inHand == null || EnchantmentHelper.getEnchantmentLevel(ModEnchantments.melting.effectId, inHand) <= 0) {
return;
}
List<ItemStack> smeltedDrop = new LinkedList<>();
event.drops.removeIf(drop -> {
// Получаем результат плавления дропа
ItemStack result = FurnaceRecipes.smelting().getSmeltingResult(drop);
if (result != null) {
smeltedDrop.add(result.copy());
return true;
}
return false;
});
event.drops.addAll(smeltedDrop);
}
}
Вы могли заметить, что в примере используется класс-хелпер EnchantmentHelper.
Доступные методы:
EnchantmentHelper#getEnchantmentLevel(Integer, ItemStack)- возвращает уровень чар наложенных на предмет. Параметры метода:идентификатор чар,стек предмета.EnchantmentHelper#getEnchantments(ItemStack)- возвращает карту всех чар наложенных на предмет. Возвращаемая карта:Map<Integer, Integer>, первым идёт идентификатор чар, вторым уровень чар.EnchantmentHelper#setEnchantments(Map<Integer, Integer>, ItemStack)- задаёт новую карту чар для предмета(или удаляет чары, если предмет был зачарован).EnchantmentHelper#getMaxEnchantmentLevel(Integer, ItemStack[])- возвращает самый большой уровень заклинания в переданном массиве стеков предметов. Параметры метода:идентификатор чар,массив стеков предметов.EnchantmentHelper#getEnchantmentModifierDamage(ItemStack[], DamageSource)- возвращает модификатор защитных чар на доспехах, установленных на игроке. Параметры метода:массив стеков брони,источник урона.EnchantmentHelper#getEnchantmentModifierLiving(EntityLivingBase, EntityLivingBase)- возвращает модификатор урона по сущности. Параметры метода:атакующий,цель атакующего.EnchantmentHelper#func_152377_a(ItemStack, EnumCreatureAttribute)- аналогичноEnchantmentHelper#getEnchantmentModifierLiving.EnchantmentHelper#func_151384_a(EntityLivingBase, Entity)- дополнительная обработка для защиты при нападении.EnchantmentHelper#func_151385_b(EntityLivingBase, Entity)- дополнительная обработка при атаке сущности.EnchantmentHelper#getKnockbackModifier(EntityLivingBase, EntityLivingBase)- возвращает уровень чар "Отдача" для текущего предмета в руке.EnchantmentHelper#getFireAspectModifier(EntityLivingBase)- возвращает уровень чар "Заговор огня" для текущего предмета в руке.EnchantmentHelper#getRespiration(EntityLivingBase)- возвращает уровень чар "Подводное дыхание" для текущего предмета в руке.EnchantmentHelper#getEfficiencyModifier(EntityLivingBase)- возвращает уровень чар "Эффективность" для текущего предмета в руке.EnchantmentHelper#getSilkTouchModifier(EntityLivingBase)- содержит ли предмет в руке чары "Шёлковое касание".EnchantmentHelper#getFortuneModifier(EntityLivingBase)- возвращает уровень чар "Удача" для текущего предмета в руке.EnchantmentHelper#func_151386_g(EntityLivingBase)- возвращает уровень чар "Морская удача" для текущего предмета в руке.EnchantmentHelper#func_151387_h(EntityLivingBase)- возвращает уровень чар "Приманка" для текущего предмета в руке.EnchantmentHelper#getLootingModifier(EntityLivingBase)- возвращает уровень чар "Добыча" для текущего предмета в руке.EnchantmentHelper#getAquaAffinityModifier(EntityLivingBase)- возвращает уровень чар "Подводник (Родство с водой)" для текущего предмета в руке.EnchantmentHelper#func_92099_a(Enchantment, EntityLivingBase)- возвращает стек предмета, который содержит передаваемые чары в параметре метода.EnchantmentHelper#calcItemStackEnchantability(Random, Integer, Integer, ItemStack)- возвращает расчёт зачаровываемости предмета. Параметры метода:рандом,формула обработки(0, 1 или 2 принимается),сила зачаривания(максимум 15),стек предмета.EnchantmentHelper#addRandomEnchantment(Random, ItemStack, Integer)- добавляет случайные чары на предмет. Параметры метода:рандом,стек предмета,уровень зачароваемости.EnchantmentHelper#buildEnchantmentList(Random, ItemStack, Integer)- создаёт список случайных данных о зачаровании, которые могут быть добавлены вместе в ItemStack, 3-й параметр - это общий уровень зачаровываемости.EnchantmentHelper#mapEnchantmentData(Integer, ItemStack)- создает карту данных о зачаровании по пройденным уровням зачаровываемости, которую можно добавить в ItemStack.
Таблица чар#
Идентификаторы указанные в таблице уже являются занятыми, поэтому вам необходимо их избегать при создании собственных чар.
| Идентификатор | Название | Описание | Макс. уровень |
|---|---|---|---|
| 0 | protection | Защита | 4 |
| 1 | fireProtection | Защита от огня | 4 |
| 2 | featherFalling | Защита от падения | 4 |
| 3 | blastProtection | Защита от взрывов | 4 |
| 4 | projectileProtection | Защита от снарядов | 4 |
| 5 | respiration | Подводное дыхание | 3 |
| 6 | aquaAffinity | Подводник (Родство с водой) | 1 |
| 7 | thorns | Шипы | 3 |
| 16 | sharpness | Острота | 5 |
| 17 | smite | Небесная кара | 5 |
| 18 | baneOfArthropods | Бич членистоногих (Гибель насекомых) | 5 |
| 19 | knockback | Отдача (Отбрасывание) | 2 |
| 20 | fireAspect | Заговор огня | 2 |
| 21 | looting | Добыча | 3 |
| 32 | efficiency | Эффективность | 5 |
| 33 | silkTouch | Шёлковое касание | 1 |
| 34 | unbreaking | Прочность | 3 |
| 35 | fortune | Удача | 3 |
| 48 | power | Сила | 5 |
| 49 | punch | Отбрасывание стрелами | 2 |
| 50 | flame | Горящая стрела | 1 |
| 51 | infinity | Бесконечность | 1 |
| 61 | field_151370_z | Морская удача (Увеличенный бонус при рыбалке) | 3 |
| 62 | field_151369_A | Приманка | 3 |