- 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;
}
}