Jump to content

[1.10.2][GUI][Containers]I don't know how to do GUI


Recommended Posts

Posted

I can't move items in the hotbar. I'm not even close to finish the GUI and the container, and I already ran into this problem...

 

This is a super class implementing some basics. As it is, the players hotbar is part of the rectangle drawn. I will move it out so some GUIs can choose not to display the hotbar. This class apparently works fine (the entire drawing process works as intended. What is not working is the interaction: to pick a hot bar item and put it somewhere else. Also, the inventory seems to be duplicating stacks)

public class GuiBasicContainer extends GuiContainer
{
/**
 * The {@code ResourceLocation} for the basic GUI elements
 */
    private static final ResourceLocation texture = new ResourceLocation(TheMod.MODID, "textures/gui/gui_01.png");
    
        private int windowX;
private int windowY;

public GuiBasicContainer(Container inventorySlotsIn)
{
	super(inventorySlotsIn);
}

@Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
{
	GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
                this.mc.getTextureManager().bindTexture(texture);
	windowX = (this.width - this.xSize) / 2;
	windowY = (this.height - this.ySize) / 2;
	this.drawTexturedModalRect(windowX, windowY, 0, 0, this.xSize, this.ySize);
}

protected void drawPlayerInventory(int relativeX, int relativeY)
{
	drawTexturedModalRect(windowX + relativeX, windowY + relativeY, 0, 166, 161, 53);
}
}

 

This is the GUI. As said before, it seems to work.

public class GuiExtractor extends GuiBasicContainer
{
    public GuiExtractor(ContainerExtractor inventorySlotsIn)
    {
        super(inventorySlotsIn);
    }

    @Override
    protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
    {
        super.drawGuiContainerBackgroundLayer(partialTicks, mouseX, mouseY);
        drawPlayerInventory(7, 83);
    }
}

 

Bellow is a class that is supposed to implement basic behaviours to be used by its derived classes.

 

public abstract class ContainerBasic extends Container
{	
    protected final EntityPlayer player;
    protected int inventorySize;
    
    public ContainerBasic(EntityPlayer player, int inventorySize)
    {
        this.inventorySize = inventorySize;
        this.player = player;
    }

    public EntityPlayer getPlayer()
    {
        return player;
    }
    
    protected void addHotBar(int x, int y)
    {
        for(int i = 0; i < 9; ++i)
        {
            this.addSlotToContainer(new Slot(player.inventory, i, x + i * 18, y));
        }
    }
    
    protected void addPlayerInventory(int x, int y)
    {
        for(int line = 0; line < 3; ++line)
        {
            for(int row = 0; row < 9; ++row)
            {
                int slotID = 9 + line * 9 + row;
                this.addSlotToContainer(new Slot(player.inventory, slotID, x + row * 18, y + line * 18));
            }
        }
    }
    
    //I believe this is the problem. I don't understand the new set of arguments of this method.
    @Override
    public ItemStack slotClick(int slotId, int dragType, ClickType clickTypeIn, EntityPlayer player)
    {
    	Slot slot;
    	if(slotId > 0)
    	{
    	    slot = (Slot) this.inventorySlots.get(slotId);
    	}
    	else
    	{
    	    slot = null;
    	}
if (slot instanceof SlotFake) 
{
    return slotClickFake(slot, dragType, clickTypeIn, player);
}
        return super.slotClick(slotId, dragType, clickTypeIn, player);
    }

    private ItemStack slotClickFake(Slot slot, int mouseButton, ClickType clickTypeIn, EntityPlayer player)
    {
        System.out.println("Clicked Fake Slot");
    	return null;
    }
}

 

I don't think this class is the problem:

public class ContainerExtractor extends ContainerBasic
{
private final TileExtractor extractor;
private final InventoryFake filter;

public ContainerExtractor(EntityPlayer player, TileExtractor extractor)
{
	super(player, 5);
	this.extractor = extractor;
	filter = extractor.getFilter();

	addHotBar(8, 142);
	addPlayerInventory(8, 84);

	this.addSlotToContainer(new SlotItemHandler(filter, 0, 44, 53));
	this.addSlotToContainer(new SlotItemHandler(filter, 1, 44 + 16, 53));
	this.addSlotToContainer(new SlotItemHandler(filter, 2, 44 + 32, 53));
	this.addSlotToContainer(new SlotItemHandler(filter, 3, 44 + 48, 53));
	this.addSlotToContainer(new SlotItemHandler(filter, 4, 44 + 64, 53));
}

@Override
public boolean canInteractWith(EntityPlayer playerIn)
{
	return extractor.isUsableByPlayer(playerIn);
}
}

 

The whole GUI is a mess, things disapear, things get dupped, the game crashes, things can't be moved. It's all broken.

Posted

You have literally overwritten the slotClick method. Do super.slotClick() before you do anything else i, so it's like this:'s like this:

//I believe this is the problem. I don't understand the new set of arguments of this method.
    @Override
    public ItemStack slotClick(int slotId, int dragType, ClickType clickTypeIn, EntityPlayer player)
    {
        super.slotClick(int slotId, int dragType, ClickType clickTypeIn, EntityPlayer player);
    	Slot slot;
    	if(slotId > 0)
    	{
    	    slot = (Slot) this.inventorySlots.get(slotId);
    	}
    	else
    	{
    	    slot = null;
    	}
if (slot instanceof SlotFake) 
{
    return slotClickFake(slot, dragType, clickTypeIn, player);
}
        return super.slotClick(slotId, dragType, clickTypeIn, player);
    }

Posted

You have literally overwritten the slotClick method. Do super.slotClick() before you do anything else i, so it's like this:'s like this:

//I believe this is the problem. I don't understand the new set of arguments of this method.
    @Override
    public ItemStack slotClick(int slotId, int dragType, ClickType clickTypeIn, EntityPlayer player)
    {
        super.slotClick(int slotId, int dragType, ClickType clickTypeIn, EntityPlayer player);
    	Slot slot;
    	if(slotId > 0)
    	{
    	    slot = (Slot) this.inventorySlots.get(slotId);
    	}
    	else
    	{
    	    slot = null;
    	}
if (slot instanceof SlotFake) 
{
    return slotClickFake(slot, dragType, clickTypeIn, player);
}
        return super.slotClick(slotId, dragType, clickTypeIn, player);
    }

 

That didn't help.

Posted

I learned a lot since I asked this question a couple of days ago. My GUI is almost working 100%. But I still feel I need to know exactly what each

dragMode

and

clickType

means and when

[s]Slot.slotClick[/s]

Container.slotClick

is invoked with what parameters.

 

For example, I notice the middle mouse buttom gives a

dragMode

of 2 and a

clickType

of

CLONE

, if you middle click a slot, but it gives a

dragMode

of 9 if you click and drag (with the same

clickType

of

CLONE

.

 

Right clicking:

dragMode

of 1 and

clickType

of

PICKUP

, but sometimes

dragMode

of 5 and

clickType

of

QUICK_CRAFT

.

 

I feel that if I knew what's going on with these parameters I would be able to implement my GUIs free of bugs. I can't be sure if my GUIs will always work as intended if I don't know this method's contract.

Posted

I learned a lot since I asked this question a couple of days ago. My GUI is almost working 100%. But I still feel I need to know exactly what each

dragMode

and

clickType

means and when

Slot.slotClick

is invoked with what parameters.

 

For example, I notice the middle mouse buttom gives a

dragMode

of 2 and a

clickType

of

CLONE

, if you middle click a slot, but it gives a

dragMode

of 9 if you click and drag (with the same

clickType

of

CLONE

.

 

Right clicking:

dragMode

of 1 and

clickType

of

PICKUP

, but sometimes

dragMode

of 5 and

clickType

of

QUICK_CRAFT

.

 

I feel that if I knew what's going on with these parameters I would be able to implement my GUIs free of bugs. I can't be sure if my GUIs will always work as intended if I don't know this method contract.

Look at Container#slotaclick(...) if you understand that code it will lead you to what they mean exactly. If you have some check you need to do like for a backpack. You shouldnt be able to pickup the backpack in the backpacks inventory, to do that you would just check which slotIndex you are clicking and if it is return null otherwise return super.

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

Look at Container#slotaclick(...) if you understand that code it will lead you to what they mean exactly. If you have some check you need to do like for a backpack. You shouldnt be able to pickup the backpack in the backpacks inventory, to do that you would just check which slotIndex you are clicking and if it is return null otherwise return super.

 

Container.slotClick

was what I meant to say. The method is too long and it has too many conditionals. I want to know the method's contract, meaning, what arguments the method expects and what are the results the caller can expect from the method: if the arguments set is A, invoking the method will have R as return and will cause S as a set of side effects.

 

If anyone could tell me what is

Container.slotClick

contract I would really appreciate it.

Posted

Look at Container#slotaclick(...) if you understand that code it will lead you to what they mean exactly. If you have some check you need to do like for a backpack. You shouldnt be able to pickup the backpack in the backpacks inventory, to do that you would just check which slotIndex you are clicking and if it is return null otherwise return super.

 

Container.slotClick

was what I meant to say. The method is too long and it has too many conditionals. I want to know the method's contract, meaning, what arguments the method expects and what are the results the caller can expect from the method: if the arguments set is A, invoking the method will have R as return and will cause S as a set of side effects.

 

If anyone could tell me what is

Container.slotClick

contract I would really appreciate it.

It is obviously called when a slot in the container is clicked. It expects the return to be an ItemStack. Correct me if I am wrong but I believe the returned stack is the Stack that is bound to the mouse? ClickType.CLONE is used for creative mode when you middle click a slot it returns a new ItemStack of the Item but with the stacksize of 64(or the max stacksize). Drag mode is if the player is binding it to the mouse or not(again subject to correction). ClickType.QUICK_CRAFT is clicking and dragging the item through slots. Any more questions do ask.

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

I was hoping for something way more exact than that...

 

Anyway, I have a somewhat satisfactory Container, but it still has an issue (look at the comment on top of

slotClickFake

method):

    @Override
    public ItemStack slotClick(int slotId, int dragType, ClickType clickTypeIn, EntityPlayer player)
    {
    	Slot slot= null;
    	ItemStack stack = null;
    	if(slotId > 0)
    	{
            slot = (Slot) this.inventorySlots.get(slotId);
            stack = slot.getStack();
    	}
    	else
    	{
            slot = null;
    	}
if (slot instanceof SlotFake) 
{
            return slotClickFake((SlotFake)slot, dragType, clickTypeIn, player);
}
        return super.slotClick(slotId, dragType, clickTypeIn, player);
    }

    //A SlotFake is basically a slot to mark things like filters (e.g only consider ItemStacks that are equal to the ItemStack in the fake slot).
    //when you are holding an ItemStack with your mouse, you set the fake slot to have a stack of 0 size equal to that item,
    //without affecting the ItemStack being held (You don't actually put anything in a SlotFake).
    //when you are not holding an ItemStack with your mouse, you pick up the zero sized ItemStack in the SlotFake (if the slot has one).
    //this 0 sized ItemStack is supposed to be valid for other SlotFakes, but, as it is, there is a minor nuissance:
    //you can put these 0 sized ItemStacks in your normal inventory. They disappear when clicked, but I wish this behaviour wouldn't exist.
    private ItemStack slotClickFake(SlotFake slot, int dragType, ClickType clickTypeIn, EntityPlayer player)
    {
        InventoryPlayer playerInv = player.inventory;
ItemStack itemInHand = playerInv.getItemStack();
ItemStack itemInSlot = slot.getStack();

ItemStack result = itemInSlot != null ? itemInSlot.copy() : null;

switch(clickTypeIn)
        {
            case CLONE:
	if(itemInSlot != null)
	{
	    if(player.capabilities.isCreativeMode)
                    {
                        if(itemInHand != null
		    && itemInHand.stackSize < itemInHand.getMaxStackSize()
		    && ItemHandlerHelper.canItemStacksStack(itemInHand, itemInHand))
		{
		    itemInHand.stackSize = itemInHand.getMaxStackSize();
		}
		else
		{
		    slot.putStack(null);
		}			
	    }
	    else
	    {
		slot.putStack(null);
                    }
                }
                break;
            case PICKUP:
            case PICKUP_ALL:
            case QUICK_CRAFT:
            case QUICK_MOVE:
                if(itemInHand != null && slot.isItemValid(itemInHand))
	{
                    ItemStack copy = itemInHand.copy();
                    slot.putStack(copy);
                    result = copy;
	}
	else if(itemInSlot != null)
	{
                    playerInv.setItemStack(itemInSlot);
                    slot.putStack(null);
                }
                break;
            case SWAP://I don't know what to do in these cases
	break;
            case THROW:
	break;
            default:
	break;
        }
        return result;
    }

Posted

I was hoping for something way more exact than that...

 

Anyway, I have a somewhat satisfactory Container, but it still has an issue (look at the comment on top of

slotClickFake

method):

    @Override
    public ItemStack slotClick(int slotId, int dragType, ClickType clickTypeIn, EntityPlayer player)
    {
    	Slot slot= null;
    	ItemStack stack = null;
    	if(slotId > 0)
    	{
            slot = (Slot) this.inventorySlots.get(slotId);
            stack = slot.getStack();
    	}
    	else
    	{
            slot = null;
    	}
if (slot instanceof SlotFake) 
{
            return slotClickFake((SlotFake)slot, dragType, clickTypeIn, player);
}
        return super.slotClick(slotId, dragType, clickTypeIn, player);
    }

    //A SlotFake is basically a slot to mark things like filters (e.g only consider ItemStacks that are equal to the ItemStack in the fake slot).
    //when you are holding an ItemStack with your mouse, you set the fake slot to have a stack of 0 size equal to that item,
    //without affecting the ItemStack being held (You don't actually put anything in a SlotFake).
    //when you are not holding an ItemStack with your mouse, you pick up the zero sized ItemStack in the SlotFake (if the slot has one).
    //this 0 sized ItemStack is supposed to be valid for other SlotFakes, but, as it is, there is a minor nuissance:
    //you can put these 0 sized ItemStacks in your normal inventory. They disappear when clicked, but I wish this behaviour wouldn't exist.
    private ItemStack slotClickFake(SlotFake slot, int dragType, ClickType clickTypeIn, EntityPlayer player)
    {
        InventoryPlayer playerInv = player.inventory;
ItemStack itemInHand = playerInv.getItemStack();
ItemStack itemInSlot = slot.getStack();

ItemStack result = itemInSlot != null ? itemInSlot.copy() : null;

switch(clickTypeIn)
        {
            case CLONE:
	if(itemInSlot != null)
	{
	    if(player.capabilities.isCreativeMode)
                    {
                        if(itemInHand != null
		    && itemInHand.stackSize < itemInHand.getMaxStackSize()
		    && ItemHandlerHelper.canItemStacksStack(itemInHand, itemInHand))
		{
		    itemInHand.stackSize = itemInHand.getMaxStackSize();
		}
		else
		{
		    slot.putStack(null);
		}			
	    }
	    else
	    {
		slot.putStack(null);
                    }
                }
                break;
            case PICKUP:
            case PICKUP_ALL:
            case QUICK_CRAFT:
            case QUICK_MOVE:
                if(itemInHand != null && slot.isItemValid(itemInHand))
	{
                    ItemStack copy = itemInHand.copy();
                    slot.putStack(copy);
                    result = copy;
	}
	else if(itemInSlot != null)
	{
                    playerInv.setItemStack(itemInSlot);
                    slot.putStack(null);
                }
                break;
            case SWAP://I don't know what to do in these cases
	break;
            case THROW:
	break;
            default:
	break;
        }
        return result;
    }

Instead return null.

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

I want to be able to grab the 0 sized stacks, I just don't want to be able to put them anywhere other than in a SlotFake.

Have every other slot that is not a SlotFake be a custom slot that overrides onSlotChanged and check if par2's stackSize is <= 0 if so set this slots ItemStack = null. (This may work I am not sure when this method is called. Be sure to check what happens when you click on a slot with another ItemStack in it).

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.

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Reach Out To Rapid Digital: What sapp Info: +1 41 4 80 7 14 85 Email INFO: rap iddi gita lrecov ery @ exe cs. com Hello, my name is Jayson, and I’m 35 years old from the United Kingdom. My family and I recently endured an incredibly challenging experience that I wouldn’t wish on anyone. We became victims of a cryptocurrency investment fraud scheme that saw us lose a staggering $807,000 in USDT and Bitcoins. The fraudsters had created a convincing facade, and we were lured into investing, only to discover later that the platform was a complete scam. We were left devastated, not just financially, but emotionally, as we had trusted these people and believed in the legitimacy of the investment. After the initial shock wore off, we desperately searched for ways to recover the lost funds. It seemed like an impossible task, and we felt as though there was no hope. That’s when, by sheer luck, we stumbled across a post about Rapid Digital Recovery, a cryptocurrency and funds recovery organization with a proven track record in cybersecurity and fraud recovery. We decided to reach out to them, and from the first interaction, we were impressed with their professionalism and transparency. They explained the recovery process in detail and reassured us that they had the skills and expertise to track down the perpetrators and recover our funds. This gave us a renewed sense of hope, something we hadn’t felt in months. What truly stood out during our experience with Rapid Digital Recovery was their dedication to the recovery process. The team went above and beyond, using sophisticated tracking tools and cyber forensics to gather critical information. Within a matter of weeks, they had successfully located the funds and traced the scam back to the fraudsters responsible. They worked with the authorities to ensure the criminals were held accountable for their actions. To our relief, the team at Rapid Digital Recovery was able to recover every single penny we had lost. The funds were returned in full, and the sense of closure we felt was invaluable. We couldn’t have imagined such a positive outcome in the early stages of our recovery journey, and we are deeply grateful for the work they did. If you ever find yourself in a similar situation, I highly recommend contacting Rapid Digital Recovery. Their expertise, transparency, and dedication to their clients make them the go-to choice for anyone seeking to recover lost cryptocurrency or funds. They truly gave us back our financial future.  
    • This is my first time modding anything, so maybe just skill issue. I'm using Forge 54.0.12 and Temurin 21.0.5+11-LTS I wanted to create a custom keybind and to check whether it works I'd like to send a chat message. I tried using Minecraft.getInstance().player.sendSystemMessage(Component.literal("test")); but IntelliJ couldnt resolve sendSystemMessage(...). Since I saw people using it in earlier versions, I tried the same thing with 1.20.6(- 50.1.0), where it works fine, now I can't figure out if this is intentional and whether there are other options for sending chat messages. On that note, is there more documentation than https://docs.minecraftforge.net/en/1.21.x/? It seems very incomplete compared to something like the Oracle Java docs
    • Hi, i'm having this error and I wanna fix it. we try: -Reload drivers -Eliminate .minecraft -Eliminate Java -Restart launcher -Verify if minecraft is using gpu -Mods  in .minecraft is empty -Install the latest and recomended version of forge idk what i have to do, help me pls. the lastest log is: https://mclo.gs/WAMao8x  
    • Read the FAQ, Rule #2. (https://forums.minecraftforge.net/topic/125488-rules-and-frequently-asked-questions-faq/)  
  • Topics

×
×
  • Create New...

Important Information

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