- 216
- 6
- 19
Очередной перевод зарубежного урока от менья.
На этот раз статья была взята с оф. вики форджа.
Информация, представленная в уроке проверенна на версию 1.7.10.
В версиях выше могут измениться названия методов.
На этот раз статья была взята с оф. вики форджа.
Оригинал статьи.
Моя основная тема.
Вопросы и предложения по переводу.
----------------------------------------------------------------------------
Условия для понимания туториала:Моя основная тема.
Вопросы и предложения по переводу.
----------------------------------------------------------------------------
- Знать основы Java
- Иметь представление о создании предметов
- Иметь немного свободного места в голове, чтобы запомнить написанное ниже
Информация, представленная в уроке проверенна на версию 1.7.10.
В версиях выше могут измениться названия методов.
Распространенная ошибка начинающих программистов - помещение, изменяемой в процессе игры, переменной в начале класса предмета. Это делать неправильно, т.к. каждый предмет создается и вызывается единожды. "Шо ты несешь?!". Предположим, у вас есть палочка, которая кастует заклинание и на кнопку F вы хотите сменить заклинание. Если ваша переменная с заклинанием помещена в начале класса предмета, то при нажатии кнопки, заклинание сменится у всех на сервере. Неплохо, правда? Не совсем... Как раз таки NBT дает возможность иметь разные заклинания на разных палочках.
NBT может содержать в себе множество базов типов данных. Так же он поддерживает некоторые структуры данных (например, List). NBT предмета - это NBTTagCompound, которое данные в HashMap в базе данных.
В этом примере мы сделаем предмет-ключ, который будет открывать дверь, если коды двери и предмета сходятся. Мы разберем только то, как в нашем случае надо работать в NBT в классе двери и в предмете.
Мы рассмотрим некоторые методы, которые взаимодействуют с NBT. Не буду перечислять все методы, их можно увидеть в классе net.minecraft.item.Item. Там вы увидите описание для каждого интересующего вас метода.
Вызывается, когда предмет используют (на ПКМ), возвращает true, если что-то происходит, false - если ничего не происходит.
Вызывается каждый тик (20 раз в секунду), пока предмет в инвентаре игрока.
Вызывается, когда предмет создается (крафтится, выплавляется).
Вызывается, когда игрок отпускает кнопку использования предмета. Аргументы: itemstack, world, entityplayer, itemInUseCount
Добавляет строки к описанию предмета (описание предмета высвечивается, когда наводишь на предмет в инвентаре).
Возвращает true, если игрок может взаимодействовать с миром (например, ставить блоки) с помощью предмета и false - если наоборот.
Вызывается, когда предмет начинают использовать (но перед тем, как что-либо происходит).
Теперь для нашего дверного ключа нам нужно генерировать каждый раз новый ключ при создании самого предмета.
Создаем NBT соединение выше.
Теперь нам нужно добавить пару строк в onCreate()
Мы добавили 2 NBT характеристики предмету - ключ и владелец.
Теперь давайте отобразим эту информацию в описании, для наглядности.
Проверка на null, очень важна, ибо метод onCreated вызывается один раз - при создании. И если вы предмет не создавали, значит у нашего дверного ключа нет ключа (да-да, тавтология). Далее мы проверяем, что дверной ключ, который игрок держит в руках, создам им, то делаем ключ зеленого цвета, в ином случае - красного с помощью EnumChatFormatitng.
Выглядит это так:
Теперь нужно создать метод, который будет вызываться из onBlockActivated, для проверки вашего ключа в классе вашей двери.
А вот сам метод onBlockActivated()
Да.. В этом туториале я не учел некоторые аспекты, к примеру, зачем игроку ключ, если он может открыть дверь рукой? Я хотел сделать пример использования NBT, а не разъяснения на тему создания мода на ключи. Воспользовавшись моим уроков вы можете сделать свой мод.
Мы рассмотрим некоторые методы, которые взаимодействуют с NBT. Не буду перечислять все методы, их можно увидеть в классе net.minecraft.item.Item. Там вы увидите описание для каждого интересующего вас метода.
Вызывается, когда предмет используют (на ПКМ), возвращает true, если что-то происходит, false - если ничего не происходит.
Код:
public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10)
Код:
public void onUpdate(ItemStack par1ItemStack, World par2World, Entity par3Entity, int par4, boolean par5) {}
Код:
public void onCreated(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) {}
Код:
public void onPlayerStoppedUsing(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer, int par4) {}
Код:
public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) {}
Код:
public boolean canItemEditBlocks()
- @param stack - Стак предмета
- @param player - Игрок, который использует предмет
- @param world - Нынешний мир
- @param x - Позиция X
- @param y - Позиция Y
- @param z - Позиция Z
- @param side - Сторона
- @return - Напишите return true для предотвращения любой обработки
Код:
public boolean onItemUseFirst(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ)
Код:
public void onCreated(ItemStack itemStack, World world, EntityPlayer player)
{
itemStack.stackTagCompound = new NBTTagCompound();
}
Теперь нам нужно добавить пару строк в onCreate()
Код:
itemStack.stackTagCompound.setString("owner", player.username); itemStack.stackTagCompound.setInteger("code", (int)(Math.random*Integer.MAX_VALUE));
Теперь давайте отобразим эту информацию в описании, для наглядности.
Код:
public void addInformation(ItemStack itemStack, EntityPlayer player, List list, boolean par4) {
if (itemStack.stackTagCompound != null) {
String owner = itemStack.stackTagCompound.getString("owner");
int code = itemStack.stackTagCompound.getInteger("code");
list.add("owner: " + owner);
if (owner.equals(player.username)) {
list.add(EnumChatFormatting.GREEN + "code: " + code);
} else {
list.add(EnumChatFormatting.RED + "code: " + EnumChatFormatting.OBFUSCATED + code);
}
}
}
Выглядит это так:
Код:
public static void int getCodeIfValid(EntityPlayer player){
ItemStack hold = player.inventory.getCurrentItem();
if(hold.itemID != MainMod.key.itemID){
return -1;
}
if(!hold.stackTagCompound.getString("owner").equals(player.username)){
return -1;
}
return hold.stackTagCompound.getInteger("code");
}
Код:
onBlockActivated(args){
if(ItemKey.getCodeIfValid(player) == ((TileEntityLockedDoor)world.getBlockTileEntity(x, y, z)).code){
//код открытия двери
}
}
Последнее редактирование: