- Версия(и) Minecraft
- 1.6.4 - 1.7.10
В этом уроке я расскажу о том, как добавлять переменные к объекту с помощью Forge IExtendEntityProperties.
Что вам потребуется:
- Прямые руки
- Знание комбинаций Ctrl + C и Ctrl + V
- ПК со средой разработки и установленными компонентами для моддинга
- Знать, как настраивать и использовать Forge Events
- Готовность внимательно прочитать
Преступим..
Шаг 1. Создайте класс, который реализует IExtendedEntityProperties
Шаг 2. Регистрируем ExtendedPlayer в вашем EventHandler
В основном - все сделано. Теперь мы создадим предмет, который будет использовать эту ману.
Шаг 3. Создание предмета для использования маны.
НО! Внимание, если вы не зарегистрировали свой EventHandler, то у вас будет карш!
Поэтому мы зарегистрируем его в нашем главном классе!
Кхм, вроде все готово. Но давайте придадим мане хоть какую-то значимость.
Давайте сделаем что-то на подобии "Заклинания", которое будет предотвращать урон при падении с высоты, которой захотим. :з
Шаг 3.1 Заклинание "АтиПадалка"
(Шаг 1.3.2 Создание ГУИ, для отображения кол-ва маны на дисплее - в разработке. Постараюсь добавить на днях)
Результат выполнения наших действий (Включая шаг 1.3.2)
====
Гайд буду дописывать и включать новые "Плюшки",
Если вы захотите.
Если Вас устроил данный Туториал, то поставьте . Это мотивирует меня и дает знать, что гайд нужен и его нужно доделывать)
====
Гайд написан на основе дополнительного источника.
Что вам потребуется:
- Прямые руки
- Знание комбинаций Ctrl + C и Ctrl + V
- ПК со средой разработки и установленными компонентами для моддинга
- Знать, как настраивать и использовать Forge Events
- Готовность внимательно прочитать
Преступим..
Шаг 1. Создайте класс, который реализует IExtendedEntityProperties
Т.к. мы создаем переменную для ИГРОКА, т.е. EntityPlayer, то назовем класс ExtendedPlayer
Java:
public class ExtendedPlayer implements IExtendedEntityProperties
{
/*
Тут мы создаем константу EXT_PROP_NAME для этого класса.
ВНИМАНИЕ! Для каждого IExtendedEntityProperties нужна своя уникальная константа!
Вы делаете это ив верхней части каждого класса, поскольку константа позволяет
очень легко организовать и избежать опечаток.
Обратите внимание, что один объект может иметь несколько расширенных свойств, поэтому каждое
свойство должно иметь уникальное имя. Попытайтесь придумать что-то еще
уникальным, чем пример тут.
*/
public final static String EXT_PROP_NAME = "ExtendedPlayer";
/*
Создадим пустую переменную игрока, в которую будем как раз и задавать его,
*/
private final EntityPlayer player;
/*
Также добавим пустой метод инита, пустой т.к. пока он нам не пригодится, а нужен т.к. мы используем интерфейс.
*/
@Override
public void init(Entity entity, World world) {
}
/*
Объявим переменные, которые нам нужны еще.
Мы делаем ману, поэтому нам нужна "Текущая мана" (currentMana) и "Максимальная мана" (maxMana)
*/
private int currentMana, maxMana;
/*
По умолчанию конструктор не принимает аргументы, но я вставлю Entity, что бы
инициализировать вышеупомянутую переменную 'player'
*/
public ExtendedPlayer(EntityPlayer player)
{
this.player = player;
/*
Задаем максимальное кол-во маны.
Так же мы задаем его "Начальным", что бы при первом появлении маны у игрока
сразу был "Максимум"
*/
this.currentMana = this.maxMana = 50;
}
/**
Используется для регистрации этих полей для игрока во время события
EntityConstructing.
Используется ради удобства.
*/
public static final void register(EntityPlayer player)
{
player.registerExtendedProperties(ExtendedPlayer.EXT_PROP_NAME, new ExtendedPlayer(player));
}
/*
Возвращает свойства ExtendedPlayer для игрока.
Используется ради удобства.
*/
public static final ExtendedPlayer get(EntityPlayer player)
{
return (ExtendedPlayer) player.getExtendedProperties(EXT_PROP_NAME);
}
// Сохранение данных в NBT, для сохранения переменных.
@Override
public void saveNBTData(NBTTagCompound compound)
{
// Создаем новый состав тегов
NBTTagCompound properties = new NBTTagCompound();
// Нам нужно 2 тега. Используемая и Максимальная мана.
properties.setInteger("CurrentMana", this.currentMana);
properties.setInteger("MaxMana", this.maxMana);
// Добавляем наш тег в тег Имени игрока.
//Что бы при использовании маны у 1 игрока, она не использовалась у всех игроков на сервере.
compound.setTag(EXT_PROP_NAME, properties);
}
// Загружаем сохраненные данные
@Override
public void loadNBTData(NBTTagCompound compound)
{
// Здесь мы получаем уникальное соединение тегов, которое мы установили для этого класса
NBTTagCompound properties = (NBTTagCompound) compound.getTag(EXT_PROP_NAME);
// Получите наши данные из нашего тега
this.currentMana = properties.getInteger("CurrentMana");
this.maxMana = properties.getInteger("MaxMana");
// Что бы узнать, что это работает, мы сделаем вывод в консоль:
System.out.println("[TUT PROPS] Mana from NBT: " + this.currentMana + "/" + this.maxMana);
}
/*
Делаем геттер и ссетер.
Для потребления/пополнения маны.
*/
/**
Возвращает true, если количество маны было потреблено или false
если текущая маны игрока недостаточна
*/
public boolean consumeMana(int amount)
{
// У игрока достаточно маны?
boolean sufficient = amount <= this.currentMana;
// Потребляется в любом случае; Если необходимой маны меньше, чем есть у игрока,
// то мана сбрасывается на "0".
this.currentMana -= (amount < this.currentMana ? amount : this.currentMana);
//Если у игрока достаточно маны:
return sufficient;
}
/**
* Метод, "сбрасывающий" до максимума нашу ману.
*/
public void replenishMana()
{
this.currentMana = this.maxMana;
}
}
Шаг 2. Регистрируем ExtendedPlayer в вашем EventHandler
Java:
/ *
Чтобы получить доступ к нашим вновь созданным расширенным свойствам игрока, нам нужно
зарегистрируйте их для каждого экземпляра EntityPlayer. Это просто означает, что мы
создавая новый экземпляр класса, чтобы мы могли получить к нему доступ.
Регистрация IExtendedEntityProperties выполняется в событии EntityConstructing.
*/
public class TutEventHandler{
// Для 1.6.4: @ForgeSubscribe
@SubscribeEventpublic
void onEntityConstructing(EntityConstructing event){
/* Обязательно проверьте, является ли создаваемый объект правильным типом для
расширенных свойств, которые вы собираетесь добавить! Нулевая проверка может быть не нужна*/
if (event.entity instanceof EntityPlayer && ExtendedPlayer.get((EntityPlayer) event.entity) == null)
// Таким образом, расширенные свойства регистрируются с использованием нашего удобного метода
earlierExtendedPlayer.register((EntityPlayer) event.entity);
// Это вызовет конструктор, а также вызовет метод init ()
// для автоматического вызова
// Если вы не сделали два удобных метода раньше, ваш код будет
// намного уродливее:
if (event.entity instanceof EntityPlayer && event.entity.getExtendedProperties(ExtendedPlayer.EXT_PROP_NAME) == null)
event.entity.registerExtendedProperties(ExtendedPlayer.EXT_PROP_NAME, new ExtendedPlayer((EntityPlayer) event.entity));
}
}
В основном - все сделано. Теперь мы создадим предмет, который будет использовать эту ману.
Java:
public class ItemUseMana extends Item
{
public ItemUseMana() {
super();
}
@Override
public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer player)
{
if (!world.isRemote)
{
/*
Что бы код не был длинным, мы создадим локальную переменную
*/
ExtendedPlayer props = ExtendedPlayer.get(player);
/* Здесь мы будем использовать метод, который мы сделали, чтобы увидеть,
имеет ли игрок достаточно маны, чтобы что-то сделать мы будем печатать что-то на консоль
для отладки.
ВНИМАНИЕ!!! Тут Выполняются все действия, которые вы хотите сделать предметом, "Если у вас достаточно маны". Я же тут ТОЛЬКО вывожу в консоль, мол, "Да, у него достаточно маны" и снимаем 15 маны за использования :D
*/
if (props.consumeMana(15))
{
System.out.println("[Мана Пульятель] Да, маны достаточно!");
}
/*
Если маны недостоаточно, то мы пишем в консоль "НетУ маны, сорян" и откатываем ее до максимума.
*/
else
{
System.out.println("[Мана Пульятель] Маны не достаточно.");
props.replenishMana();
}
}
return itemstack;
}
Поэтому мы зарегистрируем его в нашем главном классе!
Java:
@EventHandler
public void load(FMLInitializationEvent event)
{
MinecraftForge.EVENT_BUS.register(new TutEventHandler());
}
Давайте сделаем что-то на подобии "Заклинания", которое будет предотвращать урон при падении с высоты, которой захотим. :з
Шаг 3.1 Заклинание "АтиПадалка"
Java:
// В класс [B]TutEventHandler[/B]
@SubscribeEvent
public void onLivingFallEvent(LivingFallEvent event)
{
// Мы добавили это только для Игрока, поэтому проверяем "Игрок ли это"
if (event.entity instanceof EntityPlayer)
{
ExtendedPlayer props = ExtendedPlayer.get((EntityPlayer) event.entity);
// Делаем так, что бы мана и игрока только кончалась, для предотвращения падения.
if (event.distance > 3.0F && props.getCurrentMana() > 0)
{
// Выводим некоторые данные в консоль, что бы наглядно видеть работу
System.out.println("[EVENT] Fall distance: " + event.distance);
System.out.println("[EVENT] Current mana: " + props.getCurrentMana());
// Нам нужно сделать локальную переменную для хранения суммы,
//чтобы уменьшить расстояние и ману
float reduceby = props.getCurrentMana() < (event.distance - 3.0F) ? props.getCurrentMana() : (event.distance - 3.0F);
event.distance -= reduceby;
// "Сдвигаем" наш параметр до "int", что бы соответствовать конструктору.
props.consumeMana((int) reduceby);
// Ну и наша любимая проверка
System.out.println("[EVENT] Adjusted fall distance: " + event.distance);
}
}
}
Результат выполнения наших действий (Включая шаг 1.3.2)
====
Гайд буду дописывать и включать новые "Плюшки",
Если вы захотите.
Если Вас устроил данный Туториал, то поставьте . Это мотивирует меня и дает знать, что гайд нужен и его нужно доделывать)
====
Гайд написан на основе дополнительного источника.
"недоработки" я как всегда не узнаю....