Jump to content

[1.9.4] Using GUIs


oneofthem999

Recommended Posts

I'm not entirely sure where to put this post, so I'll do it here.  I've been trying to search for a good tutorial on how to create GUI's for my custom blocks, but the tutorials I keep finding, either out of my own incompetence or just the sheer lack of tutorials online, are out of date.  Since I cannot find them by searching myself, I've come here. Does anyone know where I could find some GUI tutorials for 1.9.4?

Link to comment
Share on other sites

Gui stuff has barely changed in a long time. Old tutorials will be fine if you know what you are doing and can adapt the minor changes needed.

 

So I took your advice on it, and decided to look into some online gui tutorials that were not completely up-to-date, but still relatively recent.  However I ran into some trouble spots.  No gui is shown when the block in question is right-clicked, and I tried to debug the code, but unfortunately, I'm still lost.  One aspect that particularly confused me what this tutorials instance on using IInventory, in spite of the use of capabilities.  It was my understanding that the use of capabilities, specifically the ItemStackHandler capability, made the implementation of IInventory outdated, though again, I really do have a superficial understanding, so I'm not quite certain.

 

Here's the code, in this order.  Please note that the code still has system.out.println statements that print out "checkpoints," a result of my debugging attempt, and I'm sorry if they make the code difficult to follow. The BlockRedChest class, the ChestGuiHandler class, the ContainerChestTileEntity class, the GuiChestTileEntity class, the TileEntityRedChest class, and the Chest (Main) class:

 

http://pastebin.com/cXUjshQ6

 

http://pastebin.com/EJuFSpi1

 

http://pastebin.com/vsh882mx

 

http://pastebin.com/6VtTwmUW

 

http://pastebin.com/WucCAgcy

 

http://pastebin.com/BgSudHca

 

 

Also, for those interested, here's the tutorial I was looking at, though I'm not sure if it will help:

 

http://bedrockminer.jimdo.com/modding-tutorials/advanced-modding/tile-entity-with-inventory/

 

http://bedrockminer.jimdo.com/modding-tutorials/advanced-modding/gui-handler/

 

http://bedrockminer.jimdo.com/modding-tutorials/advanced-modding/gui-container/

 

 

Link to comment
Share on other sites

You aren't using the correct onBlockActivated method.  Look at the Gui Handler tutorial again.

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

You aren't using the correct onBlockActivated method.  Look at the Gui Handler tutorial again.

 

I'm not quite I see the error.  Here's the code tutorial for what the onBlockActivated method should be

 

@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumFacing side, float hitX, float hitY, float hitZ) 
{
    if (!world.isRemote) 
    {
        player.openGui(Main.instance, ModGuiHandler.MOD_TILE_ENTITY_GUI, world, pos.getX(), pos.getY(), pos.getZ());
    }
    return true;
}

 

Now, in my code, the onBlockActivated method has two additional parameters: hand, which is of type EnumHand, and heldItem, which is of type ItemStack.  These additions were added in the 1.9 edition of Forge, and I am currently using 1.9.4.  The "Main" file is called Chest, the "ModGuiHandler" file is instead called "ChestGuiHandler", and the variable in the ModGuiHandler class, MOD_TILE_ENTITY_GUI is renamed CHEST_TILE_ENTITY_GUI, and comes from the "ChestGuiHandler" class.  Bearing these changes in mind (as well as removing the unnessary system.out.println statements, which again, were there from debugging), we get the following code.

 

    @Override
    public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand,
                                    ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ)
    {
        if (!world.isRemote)
        {
            player.openGui(Chest.instance, ChestGuiHandler.CHEST_TILE_ENTITY_GUI, world, pos.getX(), pos.getY(), pos.getZ());
        }
        return true;
    }
}

 

...which is what is in my code currently.

Link to comment
Share on other sites

Server should return Container.

Client should return GuiContainer that takes/creates corresponding Container within.

 

Thanks for the tip!  The code works now; it produces a transparent GUI. 

 

Here's the code, in this order.  Please note that the code still has system.out.println statements that print out "checkpoints," a result of my debugging attempt, and I'm sorry if they make the code difficult to follow. The BlockRedChest class, the ChestGuiHandler class, the ContainerChestTileEntity class, the GuiChestTileEntity class, the TileEntityRedChest class, and the Chest (Main) class:

 

http://pastebin.com/cXUjshQ6

 

http://pastebin.com/EJuFSpi1

 

http://pastebin.com/vsh882mx

 

http://pastebin.com/6VtTwmUW

 

http://pastebin.com/WucCAgcy

 

http://pastebin.com/BgSudHca

Link to comment
Share on other sites

* Block - fine (aside from totally redundant overrides like destroyBlock).

 

* IGuiHandler:

1. ChestGuiHandler - there is one IGuiHandler per mod, kinda bad name for something that will likely do more things than that.

2. Your docs are quite false.

- getServerGuiElement - returns Container or null

- getClientGuiElement - returns GuiScreen or GuiContainer, were it (GuiContainer) should only be returned when corresponding server's ID also returns Container of same type.

 

* ContainerChestTileEntity - fine (I didn't check transfering and merging stacks, too hard to do without testing, make sure it works tho).

 

* GuiChestTileEntity - fine.

Notes: If you would override initGui() - remember to call super.

As to rendering things, you can learn some GL (now VertexBuffer, old "tesselator") from Gui.class. I wouldn't really use it directly but rewrite it to static util class (in this case tho, I think GuiContainer extends Gui, so...). For future - remember that vertexes should be added anti-clockwise.

 

* TileEntityRedChest - fine (no "deep" checks).

 

* Main - fine.

 

To be honest this is one of the better formatted sources I've seen here (tho the topic is not that hard) - god bless you for not posting mashed potatoes like some of ppl do.

 

#anotherUselssPost #iWasExpectingSomeMistakes

1.7.10 is no longer supported by forge, you are on your own.

Link to comment
Share on other sites

* GuiChestTileEntity - fine.

Notes: If you would override initGui() - remember to call super.

As to rendering things, you can learn some GL (now VertexBuffer, old "tesselator") from Gui.class. I wouldn't really use it directly but rewrite it to static util class (in this case tho, I think GuiContainer extends Gui, so...). For future - remember that vertexes should be added anti-clockwise.

 

Actually, I was wondering if I could get some help on that.  I updated my code in my GuiChestTileEntity class, so as to draw the background layer of the gui.  However, it doesn't seem to work.  Here's the code for that class:

 

public class GuiChestTileEntity extends GuiContainer
{
    private IInventory playerInv;
    private TileEntityRedChest te;

    public GuiChestTileEntity(IInventory playerInv, TileEntityRedChest te)
    {
        super(new ContainerChestTileEntity(playerInv, te));

        this.playerInv = playerInv;
        this.te = te;

        this.xSize = 176;
        this.ySize = 166;
    }

    @Override
    protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
    {
        GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
        this.drawRect(this.guiLeft, this.guiTop, 256, 256, 16777215);
        //this.mc.getTextureManager().bindTexture(new ResourceLocation("ChestsMod:textures/gui/chestSlots.png"));
        //this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize);
    }

    @Override
    protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY)
    {
        String s = "Chest";
        this.fontRendererObj.drawString(s, 88 - this.fontRendererObj.getStringWidth(s) / 2, 6, 4210752);            //#404040
        this.fontRendererObj.drawString(this.playerInv.getDisplayName().getUnformattedText(), 8, 72, 4210752);      //#404040
    }
}

 

Note that the foreground works just fine.

 

Link to comment
Share on other sites

You aren't using the correct onBlockActivated method.  Look at the Gui Handler tutorial again.

 

I'm not quite I see the error.

 

I apologize, I didn't realize your main class was named "Chest."

What I saw was the openGui command that vanilla uses to open chests, not the mod-specific openGui.

You should refactor -> rename your main class so it's some like "MoreChests" or better still "MoreChestsBase" or "MoreChestsMain" so it's clear that it's your base or main mod class file.

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

1. Minecraft colors and static GL modes are converted to integers e.g:

0xFFFFFF = white = 16777215 (MC)

Or

GL11.GL_QUADS = quads = 7 (MC)

 

For your and clarity of your code's sake I'd recommend using left approach.

 

2. Lookup Gui#drawRect

It takes left, top, right, bottom - those are positions of sides. So e.g right will be this.guiLeft + 256 (in your case).

1.7.10 is no longer supported by forge, you are on your own.

Link to comment
Share on other sites

1. Minecraft colors and static GL modes are converted to integers e.g:...

 

2. Lookup Gui#drawRect

It takes left, top, right, bottom - those are positions of sides. So e.g right will be this.guiLeft + 256 (in your case).

 

I've taken your advise, but unfortunately, the Gui is still transparent for me, expect for the foreground text. 

 

Here's the code:

 

public class GuiChestTileEntity extends GuiContainer
{
    private IInventory playerInv;
    private TileEntityRedChest te;

    public GuiChestTileEntity(IInventory playerInv, TileEntityRedChest te)
    {
        super(new ContainerChestTileEntity(playerInv, te));

        this.playerInv = playerInv;
        this.te = te;

        this.xSize = 176;
        this.ySize = 166;
    }

    @Override
    protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
    {
        GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
        this.drawRect(this.guiLeft, this.guiTop, this.guiLeft + 256, this.guiTop + 256 , 0xFFFFFF);
        //this.mc.getTextureManager().bindTexture(new ResourceLocation("chestsmod:textures/gui/chestSlots.png"));
        //this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.guiLeft + this.xSize, this.guiTop + this.ySize);
    }

    @Override
    protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY)
    {
        String s = "Chest";
        this.fontRendererObj.drawString(s, 88 - this.fontRendererObj.getStringWidth(s) / 2, 6, 4210752);            //#404040
        this.fontRendererObj.drawString(this.playerInv.getDisplayName().getUnformattedText(), 8, 72, 4210752);      //#404040
    }
}

 

I tried putting the drawRect method in the foreground, to see what would happen, but nothing occurred; the gui was still transparent.

 

On another note, I'm trying a different approach of using a PNG image as a backdrop, but I have a question for that.  Assuming that the PNG has the following location:

 

assets/ChestsMod/textures/gui/chestSlots.png

 

How would I set up the new ResourceLocation?  I've tried it myself, but it seems I'm not fully understanding something...

Link to comment
Share on other sites

new ResourceLocation(ModID, "textures/gui/chestSlots.png"); // make it global static!

 

Does this work? (background)

this.mc.getTextureManager().bindTexture(your resource location);
this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize);

 

As to drawRect - try different color, the format is 0xAARRGGBB.

1.7.10 is no longer supported by forge, you are on your own.

Link to comment
Share on other sites

Does this work? (background)

this.mc.getTextureManager().bindTexture(your resource location);
this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize);

 

I tried it, but it doesn't seem to work.  Instead, it gives me a black and purple background for the gui.

 

Here's the code for the GuiChestTileEntity class:

 

public class GuiChestTileEntity extends GuiContainer
{
    private IInventory playerInv;
    private TileEntityRedChest te;
    private static ResourceLocation location = new ResourceLocation("chestsmod", "textures/gui/chestSlots.png");

    public GuiChestTileEntity(IInventory playerInv, TileEntityRedChest te)
    {
        super(new ContainerChestTileEntity(playerInv, te));

        this.playerInv = playerInv;
        this.te = te;

        this.xSize = 176;
        this.ySize = 166;
        this.width = 1920;
        this.height = 1080;
    }

    @Override
    protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
    {
        GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
        this.mc.getTextureManager().bindTexture(location);
        this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize);
    }

    @Override
    protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY)
    {
        String s = "Chest";
        this.fontRendererObj.drawString(s, 88 - this.fontRendererObj.getStringWidth(s) / 2, 6, 4210752);            //#404040
        this.fontRendererObj.drawString(this.playerInv.getDisplayName().getUnformattedText(), 8, 72, 4210752);      //#404040
    }
}

 

And here's the code for the Chests (Main) class:

 

@Mod(modid = Chest.MODID, version = Chest.VERSION)
public class Chest
{
    public static final String MODID = "chestsmod";
    public static final String VERSION = "1.0";
    public static Block redChest;

    @Mod.Instance("chestsmod")
    public static Chest instance = new Chest();

    @Mod.EventHandler
    public static void init(FMLInitializationEvent event)
    {
        redChest = new BlockRedChest();

        GameRegistry.registerBlock(redChest, "redChest");
        GameRegistry.registerTileEntity(TileEntityRedChest.class, "redChestTileEntity");

        //Register GUI
        NetworkRegistry.INSTANCE.registerGuiHandler(instance, new ChestGuiHandler());
    }
}

Link to comment
Share on other sites

Oh, right:

 

Golden rule - modid should be always lowercase. And by always I mean everywhere - including assets.

 

Thanks for the tip.  I'll be doing that from now on.  Unfortunately, the gui still has a black and purple background...

 

Here's the code for the GuiChestTileEntity class:

 

http://pastebin.com/6VtTwmUW

 

And here's the code for the Chest (Main) class:

 

http://pastebin.com/BgSudHca

Link to comment
Share on other sites

I figured out what was the problem.  IntelliJ was registering the modID, "chestsmod", as a typo, and was therefore not compiling it.  Once I changed the modID to chest-mod, a gui starting appearing, based on the PNG image in the assets/chest-mod/textures/gui/ file. 

 

There's is still one last problem: the gui is not scaling properly.  That is, the PNG image is 256 x 256 pixels, but I want the gui to be 176 x 166 in size, and the code so far does not resize the image down to 176 X 166 for the gui.  How do I properly scale the image down to size?  I tried using a PNG image of 176 x 166 pixels, but the problem still occurred...

 

Here's the code for the GuiChestTileEntity class:

 

public class GuiChestTileEntity extends GuiContainer
{
    private IInventory playerInv;
    private TileEntityRedChest te;
    private static ResourceLocation location = new ResourceLocation("chest-mod","textures/gui/chest-slots.png");

    public GuiChestTileEntity(IInventory playerInv, TileEntityRedChest te)
    {
        super(new ContainerChestTileEntity(playerInv, te));

        this.playerInv = playerInv;
        this.te = te;

        this.xSize = 176;
        this.ySize = 166;
    }

    @Override
    protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
    {
        GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
        this.mc.getTextureManager().bindTexture(location);
        this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize);
    }

    @Override
    protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY)
    {

    }
}

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.