Событие при экипировании брони

Версия Minecraft
1.7.10
37
1
9
Есть ли какое-то событие/вохможность добавить колбэк/переопределить метод экипирования брони?
 
Решение
Моё решение (используется [Гайд][Легко][1.6+] Модификация чужого кода при запуске (трансфомеры)):
Java:
@Hook
public static void onUpdate(EntityPlayer player) {
    ItemStack[] itemStacks = getPrevEquipment(player);
    for (int j = 0; j < 5; ++j) {
        ItemStack itemstack = itemStacks[j];
        ItemStack equipment = player.getEquipmentInSlot(j);
        if (!ItemStack.areItemStacksEqual(equipment, itemstack)) {
            itemStacks[j] = equipment == null ? null : equipment.copy();
            //YOUR CODE HERE
        }
    }
}
Небольшое пояснение: метод getPrevEquipment возвращает предыдущую броню игрока. Это поле в EntityLivingBase называется field_82180_bT. У меня она получается через трастед лукап и...
37
1
9
Решение:
Проблема, в общем, оказалась в том, что майнкрафт напрямую юзает метод сета брони только в случае, если эта броня надета через ЛКМ. Спрашивается WTF, но ладно.
В общем, добавил хук на onUpdate у EntityPlayer + заюзал previousArmor от EntityLivingBase.
Код скину в эту же тему завтра, вдруг кому-то надо будет
 
7,099
324
1,510
37
1
9
Моё решение (используется [Гайд][Легко][1.6+] Модификация чужого кода при запуске (трансфомеры)):
Java:
@Hook
public static void onUpdate(EntityPlayer player) {
    ItemStack[] itemStacks = getPrevEquipment(player);
    for (int j = 0; j < 5; ++j) {
        ItemStack itemstack = itemStacks[j];
        ItemStack equipment = player.getEquipmentInSlot(j);
        if (!ItemStack.areItemStacksEqual(equipment, itemstack)) {
            itemStacks[j] = equipment == null ? null : equipment.copy();
            //YOUR CODE HERE
        }
    }
}
Небольшое пояснение: метод getPrevEquipment возвращает предыдущую броню игрока. Это поле в EntityLivingBase называется field_82180_bT. У меня она получается через трастед лукап и лямбдаметафактории. Вы же можете получать просто через рефлексию.
 

tox1cozZ

aka Agravaine
8,455
598
2,892
А можно просто хукнуться в EntityLivingBase#onUpdate после вызова func_151247_a. Через @LocalVariable в хуке взять нужные переменные и получить универсальный метод обновления экипировки вообще у всех мобов.
Для игрока же просто запилить проверку.
1615540024245.png

P.S Зная твою любовь к "оптимизациям", один instanceof будет работать в разы быстрее чем твой цикл, дополнительная проверка ItemStack.areItemStacksEqual и лукапы/рефлексии.
 
37
1
9
Ещё раз повторю, что игрок переопределяет метод onUpdate и не вызывает родительский(

По поводу LocalVarible: я думал, что это локали внутри метода, а не поля класса

Для игрока же просто запилить проверку.
А какую проверку? Я не придумал более оптимального решения, чем это

P.S Зная твою любовь к "оптимизациям", один instanceof будет работать в разы быстрее чем твой цикл, дополнительная проверка ItemStack.areItemStacksEqual и лукапы/рефлексии.
Вызов скомпилированной лямбды занимает столько же, сколько и прямой вызов метода так-то...
 

tox1cozZ

aka Agravaine
8,455
598
2,892
Ещё раз повторю, что игрок переопределяет метод onUpdate и не вызывает родительский(
EntityPlayer, открываем глазоньки :3
1615545685795.png

По поводу LocalVarible: я думал, что это локали внутри метода, а не поля класса
Ну да, тебе же стаки нужно передать в хук (предыдущий и текущий, который обновился). А они идут как локальные переменные в методе (itemstack и itemstack1).

А какую проверку? Я не придумал более оптимального решения, чем это
instanceof в хуке, ну. Ты же хукаешься в EntityLivingBase, а нужно выполнять код для игрока.
 
Сверху