Jump to content

[SOLVED] [1.10.2] Custom player inventory doesn't display GUI


Daeruin

Recommended Posts

I'm creating a custom player inventory. I'm attempting to give the player a 3x3 crafting grid by default, instead of 2x2. However, the vanilla GUI is appearing on the screen instead of mine. It  still shows the highlight slots from my GUI, and I can even put items where the slots should be.

 

I have a few other problems, like the crafting grid not producing a crafting result—do I need a custom crafting manager? Also, the creative player inventory is screwy (armor slots appearing in hot bar).

 

Common Proxy where I register my OpenGuiEvent and my GUI Handler:

 

public class CommonProxy
{
public void preInit(FMLPreInitializationEvent e)
{
	MinecraftForge.EVENT_BUS.register(new PrimalOpenGuiEvent());
}

public void init(FMLInitializationEvent e)
{
	NetworkRegistry.INSTANCE.registerGuiHandler(Primalcraft.instance, new PrimalGuiHandler());
}
}

 

 

My GUI Handler:

 

public class PrimalGuiHandler implements IGuiHandler
{
private static int modGuiIndex = 0;
public static final int GUI_PLAYER_INV = modGuiIndex++;
@Override
public Object getServerGuiElement(int guiID, EntityPlayer player, World world, int x, int y, int z)
{

	if (guiID == GUI_PLAYER_INV)
	{
		return new PrimalContainerPlayer(player, player.inventory, false);
	} 
	return null;
}
@Override
public Object getClientGuiElement(int guiID, EntityPlayer player, World world, int x, int y, int z)
{
	if (guiID == GUI_PLAYER_INV)
	{
		return new PrimalContainerPlayer(player, player.inventory, false);
	} 
	return null;
}
}

 

 

My GUI class:

 

public class PrimalGuiInventory extends GuiInventory {

private float oldMouseX;
private float oldMouseY;
    
public PrimalGuiInventory(EntityPlayer player) 
{
	super(player);
}
@Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
{
super.drawGuiContainerBackgroundLayer(partialTicks, mouseX, mouseY);
System.out.println("Drawing PrimalInv background");
        GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
        this.mc.getTextureManager().bindTexture(new ResourceLocation(Primalcraft.MODID, "textures/gui/primalinventory.png"));
        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.player);
    }
@Override
public void drawGuiContainerForegroundLayer(int mouseX, int mouseY)
{
	super.drawGuiContainerForegroundLayer(mouseX, mouseY);
	System.out.println("Drawing PrimalInv foreground");
}
}

 

 

Event for opening GUI and attaching player inventory (no, I'm not using Capabilities for this yet - advice on how to achieve that would be welcome):

 

public class PrimalOpenGuiEvent {

@SideOnly(Side.CLIENT)
@SubscribeEvent
public void onGuiOpen(GuiOpenEvent event)
{
	Gui gui = event.getGui();
	if (gui != null && gui.getClass() == net.minecraft.client.gui.inventory.GuiInventory.class && !(gui instanceof PrimalGuiInventory))
	{
		gui = new PrimalGuiInventory(Minecraft.getMinecraft().player);
	}
}

@SubscribeEvent
public void onEntityJoinWorld(EntityJoinWorldEvent event)
{
	if(event.getEntity() instanceof EntityPlayer)
	{
		EntityPlayer player = (EntityPlayer) event.getEntity();
		if(!(player.inventory instanceof PrimalInventoryPlayer))
		{
			player.inventory = new PrimalInventoryPlayer(player);
			player.inventoryContainer = new PrimalContainerPlayer(player, (PrimalInventoryPlayer) player.inventory, !player.world.isRemote);
			player.openContainer = player.inventoryContainer;
		}
	}
}
}

 

 

My player container:

 

public class PrimalContainerPlayer extends ContainerPlayer {

private static final EntityEquipmentSlot[] VALID_EQUIPMENT_SLOTS = new EntityEquipmentSlot[] {EntityEquipmentSlot.HEAD, EntityEquipmentSlot.CHEST, EntityEquipmentSlot.LEGS, EntityEquipmentSlot.FEET};
private static final int CRAFT_SIZE = 3;
public InventoryCrafting craftMatrix = new InventoryCrafting(this, CRAFT_SIZE, CRAFT_SIZE);
public IInventory craftResult = new InventoryCraftResult();

public PrimalContainerPlayer(final EntityPlayer player, InventoryPlayer playerInventory, boolean localWorld)
{
    	
super(playerInventory, localWorld, player);

this.addSlotToContainer(new SlotCrafting(playerInventory.player, this.craftMatrix, this.craftResult, 0, 151, 61));

// Add crafting grid - copied from vanilla but adjusted for 3x3 grid
        for (int i = 0; i < CRAFT_SIZE; ++i)
        {
            for (int j = 0; j < CRAFT_SIZE; ++j)
            {
                this.addSlotToContainer(new Slot(this.craftMatrix, j + i * CRAFT_SIZE, 97 + j * 18, 7 + i * 18));
            }
        }

        // Add the remaining vanilla slots - armor slots, inventory slots, and hot bar slots
        // Copied from vanilla
        for (int k = 0; k < 4; ++k)
        {
            final EntityEquipmentSlot entityequipmentslot = VALID_EQUIPMENT_SLOTS[k];
            this.addSlotToContainer(new Slot(playerInventory, 36 + (3 - k), 8, 8 + k * 18)
            {

                public int getSlotStackLimit()
                {
                    return 1;
                }

                public boolean isItemValid(@Nullable ItemStack stack)
                {
                    if (stack == null)
                    {
                        return false;
                    }
                    else
                    {
                        return stack.getItem().isValidArmor(stack, entityequipmentslot, player);
                    }
                }
                @Nullable
                @SideOnly(Side.CLIENT)
                public String getSlotTexture()
                {
                    return ItemArmor.EMPTY_SLOT_NAMES[entityequipmentslot.getIndex()];
                }
            });
        }

        for (int l = 0; l < 3; ++l)
        {
            for (int j1 = 0; j1 < 9; ++j1)
            {
                this.addSlotToContainer(new Slot(playerInventory, j1 + (l + 1) * 9, 8 + j1 * 18, 84 + l * 18));
            }
        }

        for (int i1 = 0; i1 < 9; ++i1)
        {
            this.addSlotToContainer(new Slot(playerInventory, i1, 8 + i1 * 18, 142));
        }

        this.addSlotToContainer(new Slot(playerInventory, 40, 77, 62)
        {
            public boolean isItemValid(@Nullable ItemStack stack)
            {
                return super.isItemValid(stack);
            }
            @Nullable
            @SideOnly(Side.CLIENT)
            public String getSlotTexture()
            {
                return "minecraft:items/empty_armor_slot_shield";
            }
        });
        this.onCraftMatrixChanged(this.craftMatrix);
}

@Override
public boolean canInteractWith(EntityPlayer playerIn) {
	return true;
}
}

 

 

My player inventory:

 

public class PrimalInventoryPlayer extends InventoryPlayer 
{
public PrimalInventoryPlayer(EntityPlayer playerIn) 
{
	super(playerIn);	
}

@Override
public NBTTagList writeToNBT(NBTTagList nbtTagListIn)
    {
	return super.writeToNBT(nbtTagListIn);
    }

@Override
public void readFromNBT(NBTTagList nbtTagListIn)
    {
	super.readFromNBT(nbtTagListIn);
    }

@Override
public void dropAllItems()
{
	super.dropAllItems(); 
}

@Override
public void setInventorySlotContents(int index, ItemStack stack)
    {
	super.setInventorySlotContents(index, stack);
    }
}

 

Link to comment
Share on other sites

You are extending the Gui class for the players inventory and then in the draw method you call the super.

 

As for Capability advice you need to create a new Capability (of course) and then you need to add it to the player using AttachCapabilityEvent, all of this you know. In your Capability you will store an IItemHandler instance for storing your ItemStacks.

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.

Link to comment
Share on other sites

		Gui gui = event.getGui();
	if (gui != null && gui.getClass() == net.minecraft.client.gui.inventory.GuiInventory.class && !(gui instanceof PrimalGuiInventory))
	{
		gui = new PrimalGuiInventory(Minecraft.getMinecraft().player);
	}

 

Congrats, you made a local variable equal your gui. The function returns, the local variable is popped off the stack, and no longer exists.  The event object is unchanged, the vanilla gui is displayed.

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.

Link to comment
Share on other sites

Sigh. Learning to program via Minecraft modding sometimes makes me question my sanity. I have fixed both the problems you pointed out. I now see my GUI. Here's the new code:

 

 

 

GuiOpenEvent now uses event.setGui to assign my GUI to the event:

 

	@SideOnly(Side.CLIENT)
@SubscribeEvent
public void onGuiOpen(GuiOpenEvent event)
{
	Gui gui = event.getGui();
	if (gui != null && gui.getClass() == net.minecraft.client.gui.inventory.GuiInventory.class && !(gui instanceof PrimalGuiInventory))
	{
		event.setGui(new PrimalGuiInventory(Minecraft.getMinecraft().player));
	}
}

Draw methods no longer call super:

 

	@Override
    protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
    {
        GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
        this.mc.getTextureManager().bindTexture(new ResourceLocation(Primalcraft.MODID, "textures/gui/primalinventory.png"));
        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.player);
    }

 

 

However, I'm still seeing the slot highlights from the original 2x2 crafting grid--they partially overlap my custom crafting grid slots. Where are they coming from?

 

There's weird crap going on in the creative inventory, too. It seems that maybe the slot IDs are all messed up, with the little armor icons appearing in hot bar slots, and items appearing in two slots at once depending on where they are placed, etc. Possibly because it's using my custom player inventory slot IDs? How do I fix that?

Link to comment
Share on other sites

Sigh. Learning to program via Minecraft modding sometimes makes me question my sanity. I have fixed both the problems you pointed out. I now see my GUI. Here's the new code:

 

 

 

GuiOpenEvent now uses event.setGui to assign my GUI to the event:

 

	@SideOnly(Side.CLIENT)
@SubscribeEvent
public void onGuiOpen(GuiOpenEvent event)
{
	Gui gui = event.getGui();
	if (gui != null && gui.getClass() == net.minecraft.client.gui.inventory.GuiInventory.class && !(gui instanceof PrimalGuiInventory))
	{
		event.setGui(new PrimalGuiInventory(Minecraft.getMinecraft().player));
	}
}

Draw methods no longer call super:

 

	@Override
    protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
    {
        GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
        this.mc.getTextureManager().bindTexture(new ResourceLocation(Primalcraft.MODID, "textures/gui/primalinventory.png"));
        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.player);
    }

 

 

However, I'm still seeing the slot highlights from the original 2x2 crafting grid--they partially overlap my custom crafting grid slots. Where are they coming from?

 

There's weird crap going on in the creative inventory, too. It seems that maybe the slot IDs are all messed up, with the little armor icons appearing in hot bar slots, and items appearing in two slots at once depending on where they are placed, etc. Possibly because it's using my custom player inventory slot IDs? How do I fix that?

Are you ever overriding the Container? If not just call player.openGui

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.

Link to comment
Share on other sites

Are you ever overriding the Container? If not just call player.openGui

Which question are you attempting to answer? Could you be more explicit? Overriding what Container?

 

I am extending the ContainerPlayer class and overriding some of the methods, if that's what you mean. And I'm replacing the regular player.inventoryContainer with my player container during the EntityJoinWorldEvent. But you could have seen that from the code I posted earlier, so maybe you meant something else?

Link to comment
Share on other sites

Are you ever overriding the Container? If not just call player.openGui

Which question are you attempting to answer? Could you be more explicit? Overriding what Container?

 

I am extending the ContainerPlayer class and overriding some of the methods, if that's what you mean. And I'm replacing the regular player.inventoryContainer with my player container during the EntityJoinWorldEvent. But you could have seen that from the code I posted earlier, so maybe you meant something else?

Oops, didn't catch that. The problem is that you call super in your Containers constructor so it adds all the slots that vanilla adds. Which is impossible to prevent. So you have to options.

[*]Override the slots by manually setting them in the inventorySlots field using List#set(int, Slot)

[*]Or switch to extending Container and adding the abilities/functions of the Players default container.

Note that overriding the Gui and Container may lead to incompatibility if done wrong.

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.

Link to comment
Share on other sites

Oh, I feel like such a dummy. I went with option 2. I realized I needed to override two of the methods anyway. Man, transferStackInSlot is nasty.

 

I'm still having the problem with the creative survival inventory tab. I think by adding five new slots to the player container, I have pushed all the slot indexes for that screen down by five. Vanilla does some weird crap in the GuiContainerInventory class to compensate for the missing crafting grid slots, and by adding five slots to the player container, I seem to have thrown that off. Any advice on how to deal with that?

Link to comment
Share on other sites

The creative inventory problem has been there since my very first post, so nothing I've done recently has caused it.

 

Does this screen shot work? https://screencast.com/t/ItbjCtAFi

 

See how the icons for the armor slots have all been pushed down into the regular inventory? I think because the creative inventory lacks a crafting grid, GuiContainerCreative#setCurrentCreativeTab manually adjusts for the missing slots by iterating through the player's inventoryContainer and moving the slots around based on their ID. For example, it sets slot ID 45 (the shield slot) to xPos=35 and yPos=20. Well, since I've added five slots to the player container, slot ID 45 is no longer the shield slot.

 

setCurrentCreativeTab is private, so I can't override it by extending GuiContainerCreative. I suppose I could rearrange what indexes I assign my new player inventory slots to, in order to leave all the vanilla slots in their original index positions. That would be a pain in the butt and make my transferStackInSlot method even more complicated than it already is. Maybe I could use OpenGuiEvent to intercept the creative inventory and replace it with a custom one, but that intimidates me because the creative inventory GUI is such a huge class.

Link to comment
Share on other sites

Alright, I did that and it seems to be working. It wasn't as annoying as I thought it would be, in large part because I had defined my indices with a set of constants with human-readable names. Here's what the finished player container looks like, for anyone who's interested.

 

 

public class PrimalContainerPlayer extends Container {

    private static final EntityEquipmentSlot[] VALID_EQUIPMENT_SLOTS = new EntityEquipmentSlot[] {EntityEquipmentSlot.HEAD, EntityEquipmentSlot.CHEST, EntityEquipmentSlot.LEGS, EntityEquipmentSlot.FEET};
    public InventoryCrafting craftMatrix = new InventoryCrafting(this, CRAFT_SIZE, CRAFT_SIZE); // 3x3 grid instead of vanilla 2x2
    public IInventory craftResult = new InventoryCraftResult();
    public boolean isLocalWorld;
    private final EntityPlayer player;
    private static final int 
    	CRAFTING_RESULT = 0,
    	MATRIX_START = 1, 
    	MATRIX_END = MATRIX_START + 3, // First 4 slots of crafting grid, to match up with vanilla's four slots
    	ARMOR_START = MATRIX_END + 1, 
    	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,
    	OFFHAND_SLOT = HOTBAR_END + 1,
    	MATRIX2_START = HOTBAR_END +1,
    	MATRIX2_END = MATRIX2_START + 4; // Last 5 slots of crafting grid
    private static final int CRAFT_SIZE = 3;

    public PrimalContainerPlayer(final EntityPlayer player, InventoryPlayer playerInventory, boolean localWorld)
{
    	
        this.isLocalWorld = localWorld;
        this.player = player;

	// Add slot for crafting result - Index: 0, Position: x=152, y=62
	this.addSlotToContainer(new SlotCrafting(playerInventory.player, this.craftMatrix, this.craftResult, 0, 152, 62));

	// Add crafting grid - copied from vanilla but adjusted for 3x3 grid
        // j+i*2 = First pass: i=0, j=0,1,2 = 0,1,2; Second pass: i=1, j=0,1,2 = 3,4,5; Third pass: i=2, j=0,1,2 = 6,7,8
        // Top left corner of crafting grid: x=98, y=8
	List<Slot> matrixSlots = new ArrayList<Slot>();

        for (int i = 0; i < CRAFT_SIZE; ++i)
        {
            for (int j = 0; j < CRAFT_SIZE; ++j)
            {
            	matrixSlots.add(new Slot(this.craftMatrix, j + i * CRAFT_SIZE, 98 + j * 18, 8 + i * 18));
                //this.addSlotToContainer(new Slot(this.craftMatrix, j + i * CRAFT_SIZE, 98 + j * 18, 8 + i * 18));
            }
        }

    	// Add enough of the crafting matrix slots to the player inventory container to match what vanilla does
    	// The rest will be added at the end, so they don't throw off the hard-coded re-ordering in GuiContainerCreative
    	for (int x = 0; x < 4; ++x)
    	{
    		this.addSlotToContainer(matrixSlots.get(x));
    	}


        // Copied from vanilla
        
        // Add armor slots
        for (int k = 0; k < 4; ++k)
        {
            final EntityEquipmentSlot entityequipmentslot = VALID_EQUIPMENT_SLOTS[k];
            this.addSlotToContainer(new Slot(playerInventory, 36 + (3 - k), 8, 8 + k * 18)
            {
                /**
                 * 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 1;
                }
                /**
                 * Check if the stack is allowed to be placed in this slot, used for armor slots as well as furnace
                 * fuel.
                 */
                public boolean isItemValid(@Nullable ItemStack stack)
                {
                    if (stack == null)
                    {
                        return false;
                    }
                    else
                    {
                        return stack.getItem().isValidArmor(stack, entityequipmentslot, player);
                    }
                }
                @Nullable
                @SideOnly(Side.CLIENT)
                public String getSlotTexture()
                {
                    return ItemArmor.EMPTY_SLOT_NAMES[entityequipmentslot.getIndex()];
                }
            });
        }

        // Add standard player inventory slots
        for (int l = 0; l < 3; ++l)
        {
            for (int j1 = 0; j1 < 9; ++j1)
            {
                this.addSlotToContainer(new Slot(playerInventory, j1 + (l + 1) * 9, 8 + j1 * 18, 84 + l * 18));
            }
        }

        // Add hot bar slots
        for (int i1 = 0; i1 < 9; ++i1)
        {
            this.addSlotToContainer(new Slot(playerInventory, i1, 8 + i1 * 18, 142));
        }

        // Add shield slot
        this.addSlotToContainer(new Slot(playerInventory, 40, 77, 62)
        {
            /**
             * Check if the stack is allowed to be placed in this slot, used for armor slots as well as furnace fuel.
             */
            public boolean isItemValid(@Nullable ItemStack stack)
            {
                return super.isItemValid(stack);
            }
            @Nullable
            @SideOnly(Side.CLIENT)
            public String getSlotTexture()
            {
                return "minecraft:items/empty_armor_slot_shield";
            }
        });
        this.onCraftMatrixChanged(this.craftMatrix);
        
        // Add the remaining crafting matrix slots
        
    	for (int x = 4; x < matrixSlots.size(); ++x)
    	{
    		this.addSlotToContainer(matrixSlots.get(x));
    	}


} // END OF CONSTRUCTOR


    /**
     * Callback for when the crafting matrix is changed.
     */
    public void onCraftMatrixChanged(IInventory inventoryIn)
    {
        this.craftResult.setInventorySlotContents(0, CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.player.world));
    }

    /**
     * Drops everything in the crafting grid out into the world when the container is closed.
     */
    public void onContainerClosed(EntityPlayer playerIn)
    {
        super.onContainerClosed(playerIn);

        for (int i = 0; i < 9; ++i)
        {
            ItemStack itemstack = this.craftMatrix.removeStackFromSlot(i);

            if (itemstack != null)
            {
                playerIn.dropItem(itemstack, false);
            }
        }

        this.craftResult.setInventorySlotContents(0, (ItemStack)null);
    }

    /**
     * Determines whether supplied player can use this container
     */
    public boolean canInteractWith(EntityPlayer playerIn)
    {
        return true;
    }

    /**
     * Take a stack from the specified inventory slot. Called when a player shift-clicks on a slot.
     */
    @Nullable
    public ItemStack transferStackInSlot(EntityPlayer playerIn, int index)
    {
        ItemStack itemstack = null;
        Slot slot = (Slot)this.inventorySlots.get(index);

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

         // If item is in crafting result slot - place in standard inventory or hot bar
            if (index == CRAFTING_RESULT) 
            {
                if (!this.mergeItemStack(itemstack1, INV_START, HOTBAR_END + 1, true)) // true -> starts trying with HOTBAR_END and goes to INV_START
                {
                    return null;
                }

                slot.onSlotChange(itemstack1, itemstack);
            }
         // If item is in crafting grid - place in standard inventory or hot bar
            else if ((index >= MATRIX_START && index <= MATRIX_END) || (index >= MATRIX2_START && index <= MATRIX2_END))
            {
                if (!this.mergeItemStack(itemstack1, INV_START, HOTBAR_END + 1, false))
                {
                    return null;
                }
            }
         // If item is in armor slots - place in standard inventory or hot bar
            else if (index >= ARMOR_START && index <= ARMOR_END)
            {
                if (!this.mergeItemStack(itemstack1, INV_START, HOTBAR_END + 1, false))
                {
                    return null;
                }
            }
         //  I think this means if the slot clicked contains armor, and the relevant armor slot is empty, add the armor to that slot
            else if (entityequipmentslot.getSlotType() == EntityEquipmentSlot.Type.ARMOR 
            		&& !((Slot)this.inventorySlots.get(ARMOR_END - entityequipmentslot.getIndex())).getHasStack())
            {
                int i = ARMOR_END - entityequipmentslot.getIndex();

                if (!this.mergeItemStack(itemstack1, i, i + 1, false))
                {
                    return null;
                }
            }
         //  I think this means if the slot  clicked contains an offhand item, and the offhand slot is empty, add the item to the offhand slot
            else if (entityequipmentslot == EntityEquipmentSlot.OFFHAND && !((Slot)this.inventorySlots.get(OFFHAND_SLOT)).getHasStack())
            {
                if (!this.mergeItemStack(itemstack1, OFFHAND_SLOT, OFFHAND_SLOT + 1, false))
                {
                    return null;
                }
            }
         // If item is in standard inventory slots - place in hotbar bar
            else if (index >= INV_START && index <= INV_END)
            {
                if (!this.mergeItemStack(itemstack1, HOTBAR_START, HOTBAR_END + 1, false))
                {
                    return null;
                }
            }
         // If item is in hotbar slots - place in standard inventory
            else if (index >= HOTBAR_START && index <= HOTBAR_END) 
            {
                if (!this.mergeItemStack(itemstack1, INV_START, INV_END + 1, false))
                {
                    return null;
                }
            }
            else if (!this.mergeItemStack(itemstack1, INV_START, HOTBAR_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(playerIn, itemstack1);
        }

        return itemstack;
    }

    /**
     * Called to determine if the current slot is valid for the stack merging (double-click) code. The stack passed in
     * is null for the initial slot that was double-clicked.
     */
    public boolean canMergeSlot(ItemStack stack, Slot slotIn)
    {
        return slotIn.inventory != this.craftResult && super.canMergeSlot(stack, slotIn);
    }
    
}

 

 

I have one final problem, which is that the items in the player's inventory disappear every time I log out. I need to convert the player container over to Capabilities still, and I'm hoping that will solve the problem.

Link to comment
Share on other sites

I haven't finished converting to Capabilities yet, but in the meantime I have noticed that the player model that displays in the inventory screen doesn't move around as I move the mouse. It's always looking at the top left corner of the screen. Any idea why? I copied that code directly from vanilla's GuiInventory class.

Link to comment
Share on other sites

I haven't finished converting to Capabilities yet, but in the meantime I have noticed that the player model that displays in the inventory screen doesn't move around as I move the mouse. It's always looking at the top left corner of the screen. Any idea why? I copied that code directly from vanilla's GuiInventory class.

Post the code you think does that.

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.

Link to comment
Share on other sites

I lied, I didn't copy that code. I'm already extending GuiInventory, so I'm just letting that class do the work by calling GuiInventory#drawEntityOnScreen.

 

Here's my container GUI:

 

public class PrimalGuiInventory extends GuiInventory {

private float oldMouseX;
private float oldMouseY;
    
public PrimalGuiInventory(EntityPlayer player) 
{
	super(player);
	this.allowUserInput = true;
}

@Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
{
	GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
	this.mc.getTextureManager().bindTexture(new ResourceLocation(Primalcraft.MODID, "textures/gui/primalinventory.png"));
	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.player);
}

// In vanilla, this prints "Crafting" on the screen - override to do nothing
@Override
public void drawGuiContainerForegroundLayer(int mouseX, int mouseY)
{
}

}

 

 

And here's GuiInventory#drawEntityOnScreen, which is supposed to animate the player model on the inventory screen:

 

    /**
     * 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);
    }

 

 

For some reason, it isn't doing its job, or I've done something wrong, so the player model is always stuck staring at the top left of the screen and does't follow the mouse's movement.

 

Also, I realized I don't need to use Capabilities just yet. I originally thought I needed to make changes to the player's inventory itself, but in the end I only needed to modify the player container, since the slots I'm adding are all in the crafting grid, and they aren't part of the player's permanent inventory. I can let the vanilla player inventory do all the work of saving and loading the items in the inventory. I have other ideas for adding more slots to the inventory, however, and may be asking for help later. I got a ways into adding the Capability and kept getting confused.

Link to comment
Share on other sites

Look at the names of the parameters in drawEntiryOnScreen specifically the ladt two floats.

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.

Link to comment
Share on other sites

You're talking about mouseX and mouseY, right? I don't see a problem. I'm not doing anything different from vanilla. drawEntityOnScreen is called from drawGuiContainerBackgroundLayer, which passes in a float parameter based on oldMouseX and oldMouseY and some other values. oldMouseX and oldMouseY get their values from the superclass drawScreen method from the mouseX and mouseY parameters.... all that is pure vanilla.

Link to comment
Share on other sites

You're talking about mouseX and mouseY, right? I don't see a problem. I'm not doing anything different from vanilla. drawEntityOnScreen is called from drawGuiContainerBackgroundLayer, which passes in a float parameter based on oldMouseX and oldMouseY and some other values. oldMouseX and oldMouseY get their values from the superclass drawScreen method from the mouseX and mouseY parameters.... all that is pure vanilla.

You never actually set oldMouseX or oldMouseY to anything after declaring them.

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.

Link to comment
Share on other sites

I guess I still don't have a full understanding of how subclassing works, but let me see if I understand now. I'm extending GuiInventory, which has two private variables (oldMouseX and oldMouseY) and a method (drawScreen) for setting those variables. I have extended that class, but I had to declare my own versions of the variables, because they were private in the superclass. So now I need my own method to set the variables, too. I'm still unclear if the real reason is because the variables are private, or because the superclass method uses the

[b]this[/b]

notation when setting the variables.

 

But yeah, once I copied drawScreen into my subclass and override it, everything works. Thanks for being patient with all my questions. I really appreciate all your help! I'm really pleased with how this feature of my mod has turned out.  :D

Link to comment
Share on other sites

Private variables only allow that instance to access them and they only exist within those bounds.

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.

Link to comment
Share on other sites

Right, but I had my own variables in my subclass. Why couldn't the superclass method set their values? Changing my subclass's variables to public didn't make a difference.

Because they are accessing their variables not yours.

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.

Link to comment
Share on other sites

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.