Jump to content

Recommended Posts

Posted

Hello everyone, i'm new in minecraft modding and i write mod where i need custom player inventory. Because of this i follow next tutorial https://github.com/coolAlias/Forge_Tutorials/blob/master/CustomPlayerInventory.java(thanks alot this guy for make this tutorial) and updating it to match my minecraft version and forge version(forge-1.10.2-12.18.1.2011-mdk). Of course everything can't be easy and i got this error when i press my custom key...

[spoiler=Error log]

[09:03:04] [server thread/INFO]: Saving and pausing game...
[09:03:04] [server thread/INFO]: Saving chunks for level 'New World'/Overworld
[09:03:04] [server thread/INFO]: Saving chunks for level 'New World'/Nether
[09:03:04] [server thread/INFO]: Saving chunks for level 'New World'/The End
[09:03:06] [server thread/INFO] [sTDOUT]: [fdsatrew.network.handlers.PlayerInventoryPacketHandler$1:run:21]: Received gui packet with id 0 from Player297
[09:03:06] [server thread/FATAL]: Error executing task
java.util.concurrent.ExecutionException: java.lang.ClassCastException: net.minecraftforge.common.capabilities.Capability cannot be cast to fdsatrew.capability.api.IPlayerCapability
at java.util.concurrent.FutureTask.report(Unknown Source) ~[?:1.8.0_102]
at java.util.concurrent.FutureTask.get(Unknown Source) ~[?:1.8.0_102]
at net.minecraft.util.Util.runTask(Util.java:26) [util.class:?]
at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:742) [MinecraftServer.class:?]
at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:687) [MinecraftServer.class:?]
at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:156) [integratedServer.class:?]
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:536) [MinecraftServer.class:?]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_102]
Caused by: java.lang.ClassCastException: net.minecraftforge.common.capabilities.Capability cannot be cast to fdsatrew.capability.api.IPlayerCapability
at fdsatrew.GuiHandler.getServerGuiElement(GuiHandler.java:20) ~[GuiHandler.class:?]
at net.minecraftforge.fml.common.network.NetworkRegistry.getRemoteGuiContainer(NetworkRegistry.java:251) ~[NetworkRegistry.class:?]
at net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.openGui(FMLNetworkHandler.java:87) ~[FMLNetworkHandler.class:?]
at net.minecraft.entity.player.EntityPlayer.openGui(EntityPlayer.java:2723) ~[EntityPlayer.class:?]
at fdsatrew.network.handlers.PlayerInventoryPacketHandler$1.run(PlayerInventoryPacketHandler.java:22) ~[PlayerInventoryPacketHandler$1.class:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:1.8.0_102]
at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:1.8.0_102]
at net.minecraft.util.Util.runTask(Util.java:25) ~[util.class:?]
... 5 more

 

 

Here is my code:

[spoiler=Main mod init & attach capability event]

    @EventHandler
    public void preInit(FMLPreInitializationEvent event) {
    	MinecraftForge.EVENT_BUS.register(this);
        proxy.preInit(event);
        NetworkRegistry.INSTANCE.registerGuiHandler(this, new GuiHandler());
        network = NetworkRegistry.INSTANCE.newSimpleChannel("fdsatrew");
    	network.registerMessage(PlayerInventoryPacketHandler.class, PlayerInventoryPacket.class, 0, Side.SERVER);
    }

    @SubscribeEvent
public void AttachCapability(AttachCapabilitiesEvent.Entity e)
{
	if(!e.getEntity().hasCapability(PlayerProvider.PLAYER_CAPABILITY, null) && e.getEntity() instanceof EntityPlayer)
		e.addCapability(Capabilities.PLAYER_CAPABILITY_ID, new PlayerProvider());
}

 

[spoiler=Client & Server Proxy]

public class CommonProxy {
    public void preInit(FMLPreInitializationEvent e) {
        Blocks.init();
        Items.init();
        Capabilities.init();
    }

    public void init(FMLInitializationEvent e) {

    }

    public void postInit(FMLPostInitializationEvent e) {

    }
}

public class ClientProxy extends CommonProxy {

@Override
    public void preInit(FMLPreInitializationEvent e) {
        super.preInit(e);
        Render.init();
    	MinecraftForge.EVENT_BUS.register(new KeyHandler());
    }
}
public class ServerProxy extends CommonProxy {

}

 

[spoiler=Key Handler]

public class KeyHandler {

public static KeyBinding openInventoryKey = new KeyBinding("fdsatrew.key.inventory", Keyboard.KEY_H, "key.categories.fdsatrew");

public KeyHandler()
{
	ClientRegistry.registerKeyBinding(openInventoryKey);
}	

    @SubscribeEvent
    public void onKey(KeyInputEvent evt) {
        if (openInventoryKey.isPressed()) {
            Main.network.sendToServer(new PlayerInventoryPacket(Main.GUI_CUSTOM_INV));
        }
    }
}

 

[spoiler=Gui Handler]

public class GuiHandler implements IGuiHandler {

private static int guiIndex = 0;
public static final int guiCustomInv = guiIndex++;

@Override
public Object getServerGuiElement(int guiId, EntityPlayer player, World world, int x, int y, int z)
{
	if(player.hasCapability(PlayerProvider.PLAYER_CAPABILITY, null)) {
		IPlayerCapability playerCapability = player.getCapability(PlayerProvider.PLAYER_CAPABILITY, null);
		if (guiId == guiCustomInv) {
			returnpackage fdsatrew;

import fdsatrew.capability.PlayerProvider;
import fdsatrew.capability.api.IPlayerCapability;
import fdsatrew.player.gui.GuiCustomPlayerInventory;
import fdsatrew.player.inventory.ContainerCustomPlayer;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.IGuiHandler;

public class GuiHandler implements IGuiHandler {

@Override
public Object getServerGuiElement(int guiId, EntityPlayer player, World world, int x, int y, int z) {
	if (player.hasCapability(PlayerProvider.PLAYER_CAPABILITY, null)) {
		IPlayerCapability playerCapability = player.getCapability(PlayerProvider.PLAYER_CAPABILITY, null);
		if (guiId == Main.GUI_CUSTOM_INV) {
			return new ContainerCustomPlayer(player, player.inventory, playerCapability.inventory);
		} else {
			return null;
		}
	}
	return null;
}

@Override
public Object getClientGuiElement(int guiId, EntityPlayer player, World world, int x, int y, int z) {
	if (player.hasCapability(PlayerProvider.PLAYER_CAPABILITY, null)) {
		IPlayerCapability playerCapability = player.getCapability(PlayerProvider.PLAYER_CAPABILITY, null);
		if (guiId == Main.GUI_CUSTOM_INV) {
			return new GuiCustomPlayerInventory(player, player.inventory, playerCapability.inventory);
		} else {
			return null;
		}
	}
	return null;
}
}

 

[spoiler=Capability register?]

public class Capabilities {

public static ResourceLocation PLAYER_CAPABILITY_ID = new ResourceLocation(Main.MODID, "IPlayerCapability");

public static void init() {
	CapabilityManager.INSTANCE.register(IPlayerCapability.class, PlayerCapability.PlayerStorage.playerStorage, PlayerCapability.class);
}
}

 

[spoiler=Capability code itself]

public class PlayerCapability implements IPlayerCapability {

public static class PlayerStorage implements IStorage<IPlayerCapability> {

	public static final PlayerStorage playerStorage = new PlayerStorage();
    
	@Override
    public NBTBase writeNBT(Capability<IPlayerCapability> capability, IPlayerCapability instance, EnumFacing side) {
		NBTTagCompound nbt = new NBTTagCompound();
	    NBTTagList list = new NBTTagList();
	    for (int i = 0; i < inventory.getSizeInventory(); ++i) {
	        if (inventory.getStackInSlot(i) != null) {
	            NBTTagCompound stackTag = new NBTTagCompound();
	            stackTag.setByte("Slot", (byte) i);
	            inventory.getStackInSlot(i).writeToNBT(stackTag);
	            list.appendTag(stackTag);
	        }
	    }
	    nbt.setTag("Items", list);
		return nbt;
    }

    @Override
    public void readNBT(Capability<IPlayerCapability> capability, IPlayerCapability instance, EnumFacing side, NBTBase nbt) {
    	NBTTagCompound compound = (NBTTagCompound)nbt;
    	NBTTagList list = compound.getTagList("Items", 10);
	    for (int i = 0; i < list.tagCount(); ++i) {
	        NBTTagCompound stackTag = list.getCompoundTagAt(i);
	        int slot = stackTag.getByte("Slot") & 255;
	        inventory.setInventorySlotContents(slot, ItemStack.loadItemStackFromNBT(stackTag));
	    }
    }
 }
}
public class PlayerProvider implements ICapabilityProvider, INBTSerializable {

@CapabilityInject(IPlayerCapability.class)
public static final Capability<IPlayerCapability> PLAYER_CAPABILITY = null;

private IPlayerCapability playerCapability = PLAYER_CAPABILITY.getDefaultInstance();

@Override
public NBTBase serializeNBT() {
	return PLAYER_CAPABILITY.getStorage().writeNBT(PLAYER_CAPABILITY, playerCapability, null);
}

@Override
public void deserializeNBT(NBTBase nbt) {
	PLAYER_CAPABILITY.getStorage().readNBT(PLAYER_CAPABILITY, playerCapability, null, nbt);
}

@Override
public boolean hasCapability(Capability<?> capability, EnumFacing facing) {
	return PLAYER_CAPABILITY != null && capability == PLAYER_CAPABILITY;
}

@Override
public <T> T getCapability(Capability<T> capability, EnumFacing facing) {
        if (PLAYER_CAPABILITY != null && capability == PLAYER_CAPABILITY) return (T)PLAYER_CAPABILITY;
        return null;
}
}
public interface IPlayerCapability {

static InventoryCustomPlayer inventory = new InventoryCustomPlayer();

}

 

[spoiler=Packet & handler]

public class PlayerInventoryPacket implements IMessage {
    
public int id;

    public PlayerInventoryPacket() { }

    public PlayerInventoryPacket(int id) {
        this.id = id;
    }

    @Override
    public void fromBytes(ByteBuf buf) {
    	id = ByteBufUtils.readVarInt(buf, 1);
    }

    @Override
    public void toBytes(ByteBuf buf) {
        ByteBufUtils.writeVarInt(buf, id, 1);
    }
}
public class PlayerInventoryPacketHandler implements IMessageHandler<PlayerInventoryPacket, IMessage> {

        @Override
        public IMessage onMessage(final PlayerInventoryPacket message, final MessageContext ctx) {
            IThreadListener mainThread = (WorldServer) ctx.getServerHandler().playerEntity.worldObj; // or Minecraft.getMinecraft() on the client
            mainThread.addScheduledTask(new Runnable() {
                @Override
                public void run() {
                    EntityPlayerMP player = ctx.getServerHandler().playerEntity;
                    System.out.println(String.format("Received gui packet with id %s from %s", message.id, player.getName()));
                    player.openGui(Main.instance, message.id, player.worldObj, (int)player.posX, (int)player.posY, (int)player.posZ);
                }
            });
            return null; // no response in this case
        }
}

 

If you could help me with this issue, that would be nice and appreciated.

P.S. I want make multiplayer mod as you can see.

Posted

PlayerCapability cannot be cast to IPlayerCapabilty....

IPlayerCapability is your own class

I remove cast to my class and got same error:

[spoiler=Error]

09:42:26] [server thread/FATAL]: Error executing task
java.util.concurrent.ExecutionException: java.lang.ClassCastException: net.minecraftforge.common.capabilities.Capability cannot be cast to fdsatrew.capability.api.IPlayerCapability
at java.util.concurrent.FutureTask.report(Unknown Source) ~[?:1.8.0_102]
at java.util.concurrent.FutureTask.get(Unknown Source) ~[?:1.8.0_102]
at net.minecraft.util.Util.runTask(Util.java:26) [util.class:?]
at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:742) [MinecraftServer.class:?]
at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:687) [MinecraftServer.class:?]
at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:156) [integratedServer.class:?]
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:536) [MinecraftServer.class:?]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_102]
Caused by: java.lang.ClassCastException: net.minecraftforge.common.capabilities.Capability cannot be cast to fdsatrew.capability.api.IPlayerCapability
at fdsatrew.GuiHandler.getServerGuiElement(GuiHandler.java:17) ~[GuiHandler.class:?]
at net.minecraftforge.fml.common.network.NetworkRegistry.getRemoteGuiContainer(NetworkRegistry.java:251) ~[NetworkRegistry.class:?]
at net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.openGui(FMLNetworkHandler.java:87) ~[FMLNetworkHandler.class:?]
at net.minecraft.entity.player.EntityPlayer.openGui(EntityPlayer.java:2723) ~[EntityPlayer.class:?]
at fdsatrew.network.handlers.PlayerInventoryPacketHandler$1.run(PlayerInventoryPacketHandler.java:27) ~[PlayerInventoryPacketHandler$1.class:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:1.8.0_102]
at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:1.8.0_102]
at net.minecraft.util.Util.runTask(Util.java:25) ~[util.class:?]
... 5 more

 

[spoiler=Gui Handler]

package fdsatrew;

import fdsatrew.capability.PlayerProvider;
import fdsatrew.player.gui.GuiCustomPlayerInventory;
import fdsatrew.player.inventory.ContainerCustomPlayer;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.IGuiHandler;

public class GuiHandler implements IGuiHandler {

@Override
public Object getServerGuiElement(int guiId, EntityPlayer player, World world, int x, int y, int z) {
	if (player.hasCapability(PlayerProvider.PLAYER_CAPABILITY, null)) {
		if (guiId == Main.GUI_CUSTOM_INV) {
			return new ContainerCustomPlayer(player, player.inventory,
					player.getCapability(PlayerProvider.PLAYER_CAPABILITY, null).inventory);
		} else {
			return null;
		}
	}
	return null;
}

@Override
public Object getClientGuiElement(int guiId, EntityPlayer player, World world, int x, int y, int z) {
	if (player.hasCapability(PlayerProvider.PLAYER_CAPABILITY, null)) {
		if (guiId == Main.GUI_CUSTOM_INV) {
			return new GuiCustomPlayerInventory(player, player.inventory,
					player.getCapability(PlayerProvider.PLAYER_CAPABILITY, null).inventory);
		} else {
			return null;
		}
	}
	return null;
}
}

 

Posted

In your Container and GUi you require IPlayerCapability and it will auto cast to that to try and give it that.

What you mean? I use my capability now just for saving/loading slots in my inventory

[spoiler=Container]

public class ContainerCustomPlayer extends Container
{
/** Avoid magic numbers! This will greatly reduce the chance of you making errors in 'transferStackInSlot' method */
private static final int ARMOR_START = InventoryCustomPlayer.INV_SIZE, ARMOR_END = ARMOR_START+3,
		INV_START = ARMOR_END+1, INV_END = INV_START+26, HOTBAR_START = INV_END+1,
		HOTBAR_END = HOTBAR_START+8;

public ContainerCustomPlayer(EntityPlayer player, InventoryPlayer inventoryPlayer, InventoryCustomPlayer inventoryCustom)
{
	int i;

	// Add CUSTOM slots - we'll just add two for now, both of the same type.
	// Make a new Slot class for each different item type you want to add
	this.addSlotToContainer(new SlotCustom(inventoryCustom, 0, 80, );
	this.addSlotToContainer(new SlotCustom(inventoryCustom, 1, 80, 26));

	// Add ARMOR slots; note you need to make a public version of SlotArmor
	// just copy and paste the vanilla code into a new class and change what you need
	this.addSlotToContainer(new SlotArmor(player, inventoryPlayer, inventoryPlayer.getSizeInventory() - 1, 8, 8, EntityEquipmentSlot.HEAD));
	this.addSlotToContainer(new SlotArmor(player, inventoryPlayer, inventoryPlayer.getSizeInventory() - 2, 8, 26, EntityEquipmentSlot.CHEST));
	this.addSlotToContainer(new SlotArmor(player, inventoryPlayer, inventoryPlayer.getSizeInventory() - 3, 8, 44, EntityEquipmentSlot.LEGS));
	this.addSlotToContainer(new SlotArmor(player, inventoryPlayer, inventoryPlayer.getSizeInventory() - 4, 8, 62, EntityEquipmentSlot.FEET));
	// Add vanilla PLAYER INVENTORY - just copied/pasted from vanilla classes
	for (i = 0; i < 3; ++i)
	{
		for (int j = 0; j < 9; ++j)
		{
			this.addSlotToContainer(new Slot(inventoryPlayer, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
		}
	}

	// Add ACTION BAR - just copied/pasted from vanilla classes
	for (i = 0; i < 9; ++i)
	{
		this.addSlotToContainer(new Slot(inventoryPlayer, i, 8 + i * 18, 142));
	}
}

/**
 * This should always return true, since custom inventory can be accessed from anywhere
 */
@Override
public boolean canInteractWith(EntityPlayer player)
{
	return true;
}

int convertEntityEquipmentSlot(EntityEquipmentSlot es) {
	switch(es) {
	case HEAD:
		return 3;
	case CHEST:
		return 2;
	case LEGS:
		return 1;
	case FEET:
		return 0;
	default:
		return 0;
	}
}
/**
 * Called when a player shift-clicks on a slot. You must override this or you will crash when someone does that.
 * Basically the same as every other container I make, since I define the same constant indices for all of them 
 */
public ItemStack transferStackInSlot(EntityPlayer player, int par2)
{
	ItemStack itemstack = null;
	Slot slot = (Slot) this.inventorySlots.get(par2);

	if (slot != null && slot.getHasStack())
	{
		ItemStack itemstack1 = slot.getStack();
		itemstack = itemstack1.copy();

		// Either armor slot or custom item slot was clicked
		if (par2 < INV_START)
		{
			// try to place in player inventory / action bar
			if (!this.mergeItemStack(itemstack1, INV_START, HOTBAR_END + 1, true))
			{
				return null;
			}

			slot.onSlotChange(itemstack1, itemstack);
		}
		// Item is in inventory / hotbar, try to place either in custom or armor slots
		else
		{
			// if item is our custom item
			if (itemstack1.getItem() instanceof BaseItem)
			{
				if (!this.mergeItemStack(itemstack1, 0, InventoryCustomPlayer.INV_SIZE, false))
				{
					return null;
				}
			}
			// if item is armor
			else if (itemstack1.getItem() instanceof ItemArmor)
			{
				int type = convertEntityEquipmentSlot(((ItemArmor) itemstack1.getItem()).armorType);
				if (!this.mergeItemStack(itemstack1, ARMOR_START + type, ARMOR_START + type + 1, false))
				{
					return null;
				}
			}
			// item in player's inventory, but not in action bar
			else if (par2 >= INV_START && par2 < HOTBAR_START)
			{
				// place in action bar
				if (!this.mergeItemStack(itemstack1, HOTBAR_START, HOTBAR_START + 1, false))
				{
					return null;
				}
			}
			// item in action bar - place in player inventory
			else if (par2 >= HOTBAR_START && par2 < HOTBAR_END + 1)
			{
				if (!this.mergeItemStack(itemstack1, INV_START, INV_END + 1, false))
				{
					return null;
				}
			}
		}

		if (itemstack1.stackSize == 0)
		{
			slot.putStack((ItemStack) null);
		}
		else
		{
			slot.onSlotChanged();
		}

		if (itemstack1.stackSize == itemstack.stackSize)
		{
			return null;
		}

		slot.onPickupFromSlot(player, itemstack1);
	}

	return itemstack;
}
}

 

[spoiler=Gui]

public class GuiCustomPlayerInventory extends GuiContainer
{
/** x size of the inventory window in pixels. Defined as float, passed as int */
private float xSize_lo;

/** y size of the inventory window in pixels. Defined as float, passed as int. */
private float ySize_lo;

/** Normally I use '(ModInfo.MOD_ID, "textures/...")', but it can be done this way as well */
private static final ResourceLocation iconLocation = new ResourceLocation("tutorial:textures/gui/custom_inventory.png");

/** Could use IInventory type to be more generic, but this way will save an import... */
private final InventoryCustomPlayer inventory;
    /** The old x position of the mouse pointer */
    private float oldMouseX;
    /** The old y position of the mouse pointer */
    private float oldMouseY;
    public GuiCustomPlayerInventory(EntityPlayer player, InventoryPlayer inventoryPlayer, InventoryCustomPlayer inventoryCustom)
{
	super(new ContainerCustomPlayer(player, inventoryPlayer, inventoryCustom));
	this.inventory = inventoryCustom;
	// if you need the player for something later on, store it in a local variable here as well
}

    /**
     * Draw the foreground layer for the GuiContainer (everything in front of the items)
     */
    protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY)
    {
        this.fontRendererObj.drawString(I18n.format("container.crafting", new Object[0]), 97, 8, 4210752);
    }

    /**
     * Draws the screen and all the components in it.
     */
    public void drawScreen(int mouseX, int mouseY, float partialTicks)
    {
        super.drawScreen(mouseX, mouseY, partialTicks);
        this.oldMouseX = (float)mouseX;
        this.oldMouseY = (float)mouseY;
    }

    /**
     * Draws the background layer of this container (behind the items).
     */
    protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
    {
        GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
        this.mc.getTextureManager().bindTexture(INVENTORY_BACKGROUND);
        int i = this.guiLeft;
        int j = this.guiTop;
        this.drawTexturedModalRect(i, j, 0, 0, this.xSize, this.ySize);
        drawEntityOnScreen(i + 51, j + 75, 30, (float)(i + 51) - this.oldMouseX, (float)(j + 75 - 50) - this.oldMouseY, this.mc.thePlayer);
    }

    /**
     * Draws an entity on the screen looking toward the cursor.
     */
    public static void drawEntityOnScreen(int posX, int posY, int scale, float mouseX, float mouseY, EntityLivingBase ent)
    {
        GlStateManager.enableColorMaterial();
        GlStateManager.pushMatrix();
        GlStateManager.translate((float)posX, (float)posY, 50.0F);
        GlStateManager.scale((float)(-scale), (float)scale, (float)scale);
        GlStateManager.rotate(180.0F, 0.0F, 0.0F, 1.0F);
        float f = ent.renderYawOffset;
        float f1 = ent.rotationYaw;
        float f2 = ent.rotationPitch;
        float f3 = ent.prevRotationYawHead;
        float f4 = ent.rotationYawHead;
        GlStateManager.rotate(135.0F, 0.0F, 1.0F, 0.0F);
        RenderHelper.enableStandardItemLighting();
        GlStateManager.rotate(-135.0F, 0.0F, 1.0F, 0.0F);
        GlStateManager.rotate(-((float)Math.atan((double)(mouseY / 40.0F))) * 20.0F, 1.0F, 0.0F, 0.0F);
        ent.renderYawOffset = (float)Math.atan((double)(mouseX / 40.0F)) * 20.0F;
        ent.rotationYaw = (float)Math.atan((double)(mouseX / 40.0F)) * 40.0F;
        ent.rotationPitch = -((float)Math.atan((double)(mouseY / 40.0F))) * 20.0F;
        ent.rotationYawHead = ent.rotationYaw;
        ent.prevRotationYawHead = ent.rotationYaw;
        GlStateManager.translate(0.0F, 0.0F, 0.0F);
        RenderManager rendermanager = Minecraft.getMinecraft().getRenderManager();
        rendermanager.setPlayerViewY(180.0F);
        rendermanager.setRenderShadow(false);
        rendermanager.doRenderEntity(ent, 0.0D, 0.0D, 0.0D, 0.0F, 1.0F, false);
        rendermanager.setRenderShadow(true);
        ent.renderYawOffset = f;
        ent.rotationYaw = f1;
        ent.rotationPitch = f2;
        ent.prevRotationYawHead = f3;
        ent.rotationYawHead = f4;
        GlStateManager.popMatrix();
        RenderHelper.disableStandardItemLighting();
        GlStateManager.disableRescaleNormal();
        GlStateManager.setActiveTexture(OpenGlHelper.lightmapTexUnit);
        GlStateManager.disableTexture2D();
        GlStateManager.setActiveTexture(OpenGlHelper.defaultTexUnit);
    }
}

 

[spoiler=Inventory]


public class InventoryCustomPlayer implements IInventory
{
/** The name your custom inventory will display in the GUI, possibly just "Inventory" */
private final String name = "Custom Inventory";

/** The key used to store and retrieve the inventory from NBT */
private final String tagName = "CustomInvTag";

/** Define the inventory size here for easy reference */
// This is also the place to define which slot is which if you have different types,
// for example SLOT_SHIELD = 0, SLOT_AMULET = 1;
public static final int INV_SIZE = 2;

/** Inventory's size must be same as number of slots you add to the Container class */
private ItemStack[] inventory = new ItemStack[iNV_SIZE];

public InventoryCustomPlayer()
{
	// don't need anything here!
}

@Override
public int getSizeInventory()
{
	return inventory.length;
}

@Override
public ItemStack getStackInSlot(int slot)
{
	return inventory[slot];
}

@Override
public ItemStack decrStackSize(int slot, int amount)
{
	ItemStack stack = getStackInSlot(slot);
	if (stack != null)
	{
		if (stack.stackSize > amount)
		{
			stack = stack.splitStack(amount);
			this.markDirty();
		}
		else
		{
			setInventorySlotContents(slot, null);
		}
	}
	return stack;
}

@Override
public void setInventorySlotContents(int slot, ItemStack itemstack)
{
	if(slot < 0 || slot >= getSizeInventory()) return;
	this.inventory[slot] = itemstack;

	if (itemstack != null && itemstack.stackSize > this.getInventoryStackLimit())
	{
		itemstack.stackSize = this.getInventoryStackLimit();
	}

	this.markDirty();
}

/**
 * Our custom slots are similar to armor - only one item per slot
 */
@Override
public int getInventoryStackLimit()
{
	return 1;
}

@Override
public boolean isUseableByPlayer(EntityPlayer entityplayer)
{
	return true;
}

/**
 * This method doesn't seem to do what it claims to do, as
 * items can still be left-clicked and placed in the inventory
 * even when this returns false
 */
@Override
public boolean isItemValidForSlot(int slot, ItemStack itemstack)
{
	// If you have different kinds of slots, then check them here:
	// if (slot == SLOT_SHIELD && itemstack.getItem() instanceof ItemShield) return true;

	// For now, only ItemUseMana items can be stored in these slots
	return itemstack.getItem() instanceof BaseItem;
}

@Override
public String getName() {
	// TODO Auto-generated method stub
	return name;
}

@Override
public boolean hasCustomName() {
	// TODO Auto-generated method stub
	return name.length() > 0;	
}

@Override
public ITextComponent getDisplayName() {
        return (ITextComponent)(this.hasCustomName() ? new TextComponentString(this.getName()) : new TextComponentTranslation(this.getName(), new Object[0]));
}

@Override
public ItemStack removeStackFromSlot(int index)
    {
        if (inventory[index] != null)
        {
            ItemStack itemstack = inventory[index];
            inventory[index] = null;
            return itemstack;
        }
        else
        {
            return null;
        }
    }

@Override
public void markDirty() {
	for (int i = 0; i < getSizeInventory(); ++i)
	{
		if (getStackInSlot(i) != null && getStackInSlot(i).stackSize == 0) {
			inventory[i] = null;
		}
	}
}

@Override
public void openInventory(EntityPlayer player) {}

@Override
public void closeInventory(EntityPlayer player) {}


@Override
public int getField(int id) {
	return 0;
}

@Override
public void setField(int id, int value) {}

@Override
public int getFieldCount() {
	return 0;
}

@Override
public void clear() {
        for (int i = 0; i < getSizeInventory(); ++i)
        {
        	inventory[i] = null;
        }
}
}

 

P.S. Alot of code here are placeholder until i solve my error

Posted

What is PlayerProvider?

You can see PlayerProvider code at first post under "Capability code itself". I don't know how to name it correct because i see alot of threads here and in other forums when i learn capability system...

Posted

In your GuiHandler do an instanceof check to see if the Capability you are getting is IPlayerCapability one.

[11:15:45] [server thread/INFO] [sTDOUT]: [fdsatrew.GuiHandler:getServerGuiElement:18]: IPlayerCapability false

	@Override
public Object getServerGuiElement(int guiId, EntityPlayer player, World world, int x, int y, int z) {
	if (player.getCapability(PlayerProvider.PLAYER_CAPABILITY, null) instanceof IPlayerCapability) {
		System.out.println("IPlayerCapability true");
	} else {
		System.out.println("IPlayerCapability false");
	}
	if (player.hasCapability(PlayerProvider.PLAYER_CAPABILITY, null)) {
		if (guiId == Main.GUI_CUSTOM_INV) {
			return new ContainerCustomPlayer(player, player.inventory,
					player.getCapability(PlayerProvider.PLAYER_CAPABILITY, null).inventory);
		} else {
			return null;
		}
	}
	return null;
}

I think we found error, but how attach capability correct?

Posted

Mainly

player.hasCapability(PlayerProvider.PLAYER_CAPABILITY, null)

So you don't have to do stupid isntanceof checks or null checks.  If it does not have the capability, don't try to get it.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Mainly

player.hasCapability(PlayerProvider.PLAYER_CAPABILITY, null)

So you don't have to do stupid isntanceof checks or null checks.  If it does not have the capability, don't try to get it.

Ok. I change my code to next, but error keep same because nothing globally changes...

 

public class GuiHandler implements IGuiHandler {

@Override
public Object getServerGuiElement(int guiId, EntityPlayer player, World world, int x, int y, int z) {
	if (guiId == Main.GUI_CUSTOM_INV) {
		return new ContainerCustomPlayer(player, player.inventory,
				player.getCapability(PlayerProvider.PLAYER_CAPABILITY, null).inventory);
	} else {
		return null;
	}
}

@Override
public Object getClientGuiElement(int guiId, EntityPlayer player, World world, int x, int y, int z) {
	if (guiId == Main.GUI_CUSTOM_INV) {
		return new GuiCustomPlayerInventory(player, player.inventory,
				player.getCapability(PlayerProvider.PLAYER_CAPABILITY, null).inventory);
	} else {
		return null;
	}
}
}

 

Maybe error in my events? Docs says i need PlayerClone event too, but it's for saving capability data after player respawn...

	@SubscribeEvent
public void AttachCapability(AttachCapabilitiesEvent.Entity e) {
	if (!e.getEntity().hasCapability(PlayerProvider.PLAYER_CAPABILITY, null)
			&& e.getEntity() instanceof EntityPlayer) {
		e.addCapability(Capabilities.PLAYER_CAPABILITY_ID, new PlayerProvider());
	}
}

Here is the documentation on Capabilities provided by forge.

http://mcforge.readthedocs.io/en/latest/datastorage/capabilities/

I read this docs and i don't see any errors in my code.

Update:

I add debug message to my attachcapability event and it's works...

	@SubscribeEvent
public void AttachCapability(AttachCapabilitiesEvent.Entity e) {
	if (!e.getEntity().hasCapability(PlayerProvider.PLAYER_CAPABILITY, null)
			&& e.getEntity() instanceof EntityPlayer) {
		e.addCapability(Capabilities.PLAYER_CAPABILITY_ID, new PlayerProvider());
		System.out.println("Attach Capability");
	}
}

[21:38:46] [Client thread/INFO] [sTDOUT]: [fdsatrew.Main:AttachCapability:66]: Attach Capability

Posted

Does this ever get called?

public static void init() {
	CapabilityManager.INSTANCE.register(IPlayerCapability.class, PlayerCapability.PlayerStorage.playerStorage, PlayerCapability.class);
}

I didn't see anything like this in your code.

private static class Factory implements Callable<IExampleCapability> {

  @Override
  public IExampleCapability call() throws Exception {
    return new Implementation();
  }
}

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted

Does this ever get called?

public static void init() {
	CapabilityManager.INSTANCE.register(IPlayerCapability.class, PlayerCapability.PlayerStorage.playerStorage, PlayerCapability.class);
}

I didn't see anything like this in your code.

private static class Factory implements Callable<IExampleCapability> {

  @Override
  public IExampleCapability call() throws Exception {
    return new Implementation();
  }
}

It's called in CommonProxy because if remove this method body game crash with NPE. If i try to follow docs with creating and passing this class as argument to my capability registration i got compile error "The method register(Class<T>, Capability.IStorage<T>, Class<? extends T>) in the type CapabilityManager is not applicable for the arguments (Class<IPlayerCapability>, PlayerCapability.PlayerStorage, Class<PlayerFactory>)"

import java.util.concurrent.Callable;

import fdsatrew.capability.api.IPlayerCapability;

class PlayerFactory implements Callable<IPlayerCapability> {

@Override
public IPlayerCapability call() throws Exception {
	return new PlayerCapability();
}
}

If i change my "PlayerFactory" class body to

import java.util.concurrent.Callable;

import fdsatrew.capability.api.IPlayerCapability;

public class PlayerFactory implements Callable<IPlayerCapability>, IPlayerCapability {

@Override
public IPlayerCapability call() throws Exception {
	return new PlayerCapability();
}
}

Compile error are gone, but if i press my custom key same error appear

[spoiler=Error]

[17:12:27] [server thread/FATAL]: Error executing task
java.util.concurrent.ExecutionException: java.lang.ClassCastException: net.minecraftforge.common.capabilities.Capability cannot be cast to fdsatrew.capability.api.IPlayerCapability
at java.util.concurrent.FutureTask.report(Unknown Source) ~[?:1.8.0_102]
at java.util.concurrent.FutureTask.get(Unknown Source) ~[?:1.8.0_102]
at net.minecraft.util.Util.runTask(Util.java:26) [util.class:?]
at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:742) [MinecraftServer.class:?]
at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:687) [MinecraftServer.class:?]
at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:156) [integratedServer.class:?]
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:536) [MinecraftServer.class:?]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_102]
Caused by: java.lang.ClassCastException: net.minecraftforge.common.capabilities.Capability cannot be cast to fdsatrew.capability.api.IPlayerCapability
at fdsatrew.GuiHandler.getServerGuiElement(GuiHandler.java:16) ~[GuiHandler.class:?]
at net.minecraftforge.fml.common.network.NetworkRegistry.getRemoteGuiContainer(NetworkRegistry.java:251) ~[NetworkRegistry.class:?]
at net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.openGui(FMLNetworkHandler.java:87) ~[FMLNetworkHandler.class:?]
at net.minecraft.entity.player.EntityPlayer.openGui(EntityPlayer.java:2723) ~[EntityPlayer.class:?]
at fdsatrew.network.handlers.PlayerInventoryPacketHandler$1.run(PlayerInventoryPacketHandler.java:27) ~[PlayerInventoryPacketHandler$1.class:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:1.8.0_102]
at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:1.8.0_102]
at net.minecraft.util.Util.runTask(Util.java:25) ~[util.class:?]
... 5 more

 

Posted

Forge itself has several capability examples, look at the usages of

CapabilityManager.register

in your IDE. There's also a test mod here.

 

I have some examples here: API, implementation

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Posted

Forge itself has several capability examples, look at the usages of

CapabilityManager.register

in your IDE. There's also a test mod here.

 

I have some examples here: API, implementation

Thanks you alot. Now my capability work without cast exception.

Solution: use implementation link as example.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.