Не работает миксин для isItemValid

Версия Minecraft
1.12.2
API
Forge
51
8
5
Привет! Мне надо запретить игроку надевать или снимать мою броню вручную через GUI, для этого я сделал миксин для класса Slot.class, в нем я изменял два метода: isItemValid и canTakeStack. Возникла следующая проблема: броню действительно нельзя снять, как и задумывалось, за это отвечает canTakeStack, но её все равно можно надеть вручную, за это отвечает isItemValid, значит, с ним что-то не так. Снизу скину мой миксин и фрагмент из утилитарного класса с проверкой на мою броню, а также сам класс Slot.class для удобства. Помогите мне решить мою проблему, пожалуйста
Java:
package com.nymoo.afp.common.mixins.impl;

import com.nymoo.afp.common.utils.PowerArmorUtil;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Mixin(Slot.class)
public abstract class MixinSlot {

    @Shadow public IInventory inventory;
    @Shadow public int slotIndex;
    @Shadow public abstract ItemStack getStack();

    @Inject(method = "isItemValid", at = @At("HEAD"), cancellable = true)
    private void onIsItemValid(ItemStack stack, CallbackInfoReturnable<Boolean> cir) {
        if (!(this.inventory instanceof InventoryPlayer)) return;
        if (this.slotIndex < 36 || this.slotIndex > 39) return;

        if (!stack.isEmpty() && PowerArmorUtil.isPowerArmor(stack)) {
            cir.setReturnValue(false);
        }
    }

    @Inject(method = "canTakeStack", at = @At("HEAD"), cancellable = true)
    private void onCanTakeStack(CallbackInfoReturnable<Boolean> cir) {
        if (!(this.inventory instanceof InventoryPlayer)) return;
        if (this.slotIndex < 36 || this.slotIndex > 39) return;

        if (!this.getStack().isEmpty() && PowerArmorUtil.isPowerArmor(this.getStack())) {
            cir.setReturnValue(false);
        }
    }
}
Java:
    /**
     * Проверяет, является ли предмет силовой броней
     * @param stack Предмет для проверки
     */
    public static boolean isPowerArmor(ItemStack stack) {
        if (stack.isEmpty()) {
            return false;
        }
        ResourceLocation regName = stack.getItem().getRegistryName();
        if (regName == null) {
            return false;
        }
        String path = regName.getPath();
        return path.startsWith("x03_") ||
                path.startsWith("x02_") ||
                path.startsWith("x01_") ||
                path.startsWith("t60_") ||
                path.startsWith("t51_") ||
                path.startsWith("t45_") ||
                path.startsWith("exo_");
    }


Java:
package net.minecraft.inventory;

import javax.annotation.Nullable;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;

public class Slot
{
    /** The index of the slot in the inventory. */
    private final int slotIndex;

    /** The inventory we want to extract a slot from. */
    public final IInventory inventory;

    /** the id of the slot(also the index in the inventory arraylist) */
    public int slotNumber;

    /** display position of the inventory slot on the screen x axis */
    public int xPos;

    /** display position of the inventory slot on the screen y axis */
    public int yPos;

    public Slot(IInventory inventoryIn, int index, int xPosition, int yPosition)
    {
        this.inventory = inventoryIn;
        this.slotIndex = index;
        this.xPos = xPosition;
        this.yPos = yPosition;
    }

    /**
     * if par2 has more items than par1, onCrafting(item,countIncrease) is called
     */
    public void onSlotChange(ItemStack p_75220_1_, ItemStack p_75220_2_)
    {
        int i = p_75220_2_.getCount() - p_75220_1_.getCount();

        if (i > 0)
        {
            this.onCrafting(p_75220_2_, i);
        }
    }

    /**
     * the itemStack passed in is the output - ie, iron ingots, and pickaxes, not ore and wood. Typically increases an
     * internal count then calls onCrafting(item).
     */
    protected void onCrafting(ItemStack stack, int amount)
    {
    }

    protected void onSwapCraft(int p_190900_1_)
    {
    }

    /**
     * the itemStack passed in is the output - ie, iron ingots, and pickaxes, not ore and wood.
     */
    protected void onCrafting(ItemStack stack)
    {
    }

    public ItemStack onTake(EntityPlayer thePlayer, ItemStack stack)
    {
        this.onSlotChanged();
        return stack;
    }

    /**
     * Check if the stack is allowed to be placed in this slot, used for armor slots as well as furnace fuel.
     */
    public boolean isItemValid(ItemStack stack)
    {
        return true;
    }

    /**
     * Helper fnct to get the stack in the slot.
     */
    public ItemStack getStack()
    {
        return this.inventory.getStackInSlot(this.slotIndex);
    }

    /**
     * Returns if this slot contains a stack.
     */
    public boolean getHasStack()
    {
        return !this.getStack().isEmpty();
    }

    /**
     * Helper method to put a stack in the slot.
     */
    public void putStack(ItemStack stack)
    {
        this.inventory.setInventorySlotContents(this.slotIndex, stack);
        this.onSlotChanged();
    }

    /**
     * Called when the stack in a Slot changes
     */
    public void onSlotChanged()
    {
        this.inventory.markDirty();
    }

    /**
     * Returns the maximum stack size for a given slot (usually the same as getInventoryStackLimit(), but 1 in the case
     * of armor slots)
     */
    public int getSlotStackLimit()
    {
        return this.inventory.getInventoryStackLimit();
    }

    public int getItemStackLimit(ItemStack stack)
    {
        return this.getSlotStackLimit();
    }

    @Nullable
    public String getSlotTexture()
    {
        return null;
    }

    /**
     * Decrease the size of the stack in slot (first int arg) by the amount of the second int arg. Returns the new
     * stack.
     */
    public ItemStack decrStackSize(int amount)
    {
        return this.inventory.decrStackSize(this.slotIndex, amount);
    }

    /**
     * returns true if the slot exists in the given inventory and location
     */
    public boolean isHere(IInventory inv, int slotIn)
    {
        return inv == this.inventory && slotIn == this.slotIndex;
    }

    /**
     * Return whether this slot's stack can be taken from this slot.
     */
    public boolean canTakeStack(EntityPlayer playerIn)
    {
        return true;
    }

    /**
     * Actualy only call when we want to render the white square effect over the slots. Return always True, except for
     * the armor slot of the Donkey/Mule (we can't interact with the Undead and Skeleton horses)
     */
    public boolean isEnabled()
    {
        return true;
    }
}
 
Проверь вызывается ли миксин на isItemValid sout'ом каким нибудь, он по идее должен работать.
Так я понял почему, слоты брони это вот этот анонимный класс
Java:
new Slot(playerInventory, 36 + (3 - k), 8, 8 + k * 18)
            {
                public int getSlotStackLimit()
                {
                    return 1;
                }
                public boolean isItemValid(ItemStack stack)
                {
                    return stack.getItem().isValidArmor(stack, entityequipmentslot, player);
                }
                public boolean canTakeStack(EntityPlayer playerIn)
                {
                    ItemStack itemstack = this.getStack();
                    return !itemstack.isEmpty() && !playerIn.isCreative() && EnchantmentHelper.hasBindingCurse(itemstack) ? false : super.canTakeStack(playerIn);
                }
                @Nullable
                @SideOnly(Side.CLIENT)
                public String getSlotTexture()
                {
                    return ItemArmor.EMPTY_SLOT_NAMES[entityequipmentslot.getIndex()];
                }
            }
а ты миксинишь его родителя, как видишь в canTakeStack он обращается к родителю super.canTakeStack(playerIn);, по этому он работает.
А isItemValid он полностью переписывает и твоего замиксиненого кода там в итоге нет. Короче мажанги опять насрали.
Нужно миксинить этот анонимный класс как я не скажу.
P.S Он находится в ContainerPlayer и вроде как называется ContainerPlayer$1
 
Последнее редактирование:
Назад
Сверху