Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

How to make a custom gui?


Recommended Posts

There is already a tutorial for this and the full answer is too long to put in one post anyhow.

 

I too would like help with this, but I noticed that the tutorial you linked was intended for December 20, 2012. I'm sure forge has been massively changed since then, because literally copying and pasting those files yields errors. I'm finding it very difficult to learn how to program minecraft. I would know because I spent a while programming Runescape bots for RS Bot (which uses java). I know java fairly well.

Link to post
Share on other sites

I don't want to post entire class files, so I'll assume you know how to set up a basic block and tile entity. Ensure these methods are in your respective classes and tweak them from there.

 

Block:

//If you want your gui to have an inventory, have your block extend BlockContainer
//If not, have it extend Block and implement ITileEntityProvider

@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer playerEntity, int w, float px, float py, float pz)
{
                //the second parameter (0) is the gui ID and is used in the gui handler
                //for it to know which gui window to use - use a different ID for each gui window
	playerEntity.openGui(MainModClass.instance, 0, world, x, y, z);
	return false;
}

    public TileEntity createNewTileEntity(World world)
    {
    	return new TileEntityClass ();
    }

 

GuiHandler:

public class GuiHandler implements IGuiHandler
{
@Override
public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z)
{
                //I don't use any containers in my GUIs (GuiContainer), but if I did, I'd return them here.
                //You can only get away with what I'm doing here if your GUIs extend GuiScreen and not GuiContainer
                //Servers get containers - Clients get GUIs
	return null;
}

@Override
public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z)
{
	switch(ID)
	{
	case 0:
		return new BlockGuiWindow();
	//etc
	case 1:
		return new DialogGUI();
        //etc
	case 2:
                        return new QuestGUI();
                //etc
        case 3:
                        return new ShopGUI();
	}
	return null;
                //It is common Java convention to "break;" a switch case, but because all my cases end in returns, I don't need to
}
}

 

BlockGuiWindow:

@SideOnly(Side.CLIENT)
public class BlockGuiWindow extends GuiScreen //extend GuiContainer if you want your gui to have an inventory
{
final int xSizeOfTexture = 192
	   , ySizeOfTexture = 135
                   , white = Color.white.getRGB();
int posX
  , posY;

        //If you want your gui to change based on TileEntity values, reference the tile entity in the constructor
        //you must pass the tile entity using "return new BlockGuiWindow(world.getBlockTileEntity(x, y, z))" in the GuiHandler
        TileEntityClass te;

public BlockGuiWindow(TileEntityClass te)
{
	this.te = te;
}

        public void initGui()
{
	this.buttonList.clear();

	posX = (this.width - xSizeOfTexture) / 2;
	posY = (this.height - ySizeOfTexture) / 2;

	this.buttonList.add(new GuiButton(0, posX + 4, posY + 4, 20, 20, "ButtonText"));
                /*Parameters:
                 * button id used when checking what to do when a button is pressed
                 * The X position of the button
                 * The Y position of the button
                 * The width
                 * The height (keep this at 20 if you can)
                 * The text to be displayed on the button*/
        }

        public void actionPerformed(GuiButton button)
{
	switch(button.id)
	{
                     case 0:
                         //Do button stuff
                         break;
                }
        }

        @Override
public void drawScreen(int x, int y, float f)
{
	drawDefaultBackground();

	GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
	this.mc.renderEngine.bindTexture("path/to/the/background/texture");

	int posX = (this.width - xSizeOfTexture) / 2;
	int posY = (this.height - ySizeOfTexture) / 2;

	drawTexturedModalRect(posX, posY, 0, 0, xSizeOfTexture, ySizeOfTexture); //This draws the background
                //Make sure your background texture is a multiple of 256x256.
                //The xSizeOfTexture and ySizeOfTexture assume that the texture is 256x256. so 128 and 128 always reference half of the texture.
                //Look in the Gui class to see what else you can do here (like rendering textures and strings)
                this.drawString(fontRenderer, "Text", posX + 20, posY + 31, white); //this is where the white variable we set up at the beginning is used
                super.drawScreen(x, y, f);
                /*Here is a trick:
                   If you reset the texture after "super.drawScreen(x, y, f);" (this.mc.renderEngine.bindTexture("path/to/the/background/texture"),
                   you can draw on top of everything, including buttons.
                   Use this to texture buttons, if you don't want them to have text.*/
        }

 

MainModClass:

@Instance //The @Instance goes with the following line, nothing else
    public static MainModClass instance = new MainModClass();

GameRegistry.registerTileEntity(TileEntityClass.class, "TileEntityName");
NetworkRegistry.instance().registerGuiHandler(this, new GuiHandler());

 

Those are the major snippets of the code I use for my stuff (with the names changed.) I have specific needs and you'll need to change the code a bit to do what you want it to, mainly adding a Container class and referencing it in the GuiHandler if you need a GuiContainer. You also may want to change my parenthetical syntax. I'm a C# programmer and the java parenthetical syntax bugs me :P

width=336 height=83http://img836.imageshack.us/img836/1237/cooltext624963071.png[/img]

I make games, minecraft mods/plugins, and some graphic art.

 

Current Project: LoECraft - An industrial minecraft server with its own modpack and custom launcher.

Link to post
Share on other sites

I don't want to post entire class files, so I'll assume you know how to set up a basic block and tile entity. Ensure these methods are in your respective classes and tweak them from there.

 

Block:

//If you want your gui to have an inventory, have your block extend BlockContainer
//If not, have it extend Block and implement ITileEntityProvider

@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer playerEntity, int w, float px, float py, float pz)
{
                //the second parameter (0) is the gui ID and is used in the gui handler
                //for it to know which gui window to use - use a different ID for each gui window
	playerEntity.openGui(MainModClass.instance, 0, world, x, y, z);
	return false;
}

    public TileEntity createNewTileEntity(World world)
    {
    	return new TileEntityClass ();
    }

 

GuiHandler:

public class GuiHandler implements IGuiHandler
{
@Override
public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z)
{
                //I don't use any containers in my GUIs (GuiContainer), but if I did, I'd return them here.
                //You can only get away with what I'm doing here if your GUIs extend GuiScreen and not GuiContainer
                //Servers get containers - Clients get GUIs
	return null;
}

@Override
public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z)
{
	switch(ID)
	{
	case 0:
		return new BlockGuiWindow();
	//etc
	case 1:
		return new DialogGUI();
        //etc
	case 2:
                        return new QuestGUI();
                //etc
        case 3:
                        return new ShopGUI();
	}
	return null;
                //It is common Java convention to "break;" a switch case, but because all my cases end in returns, I don't need to
}
}

 

BlockGuiWindow:

@SideOnly(Side.CLIENT)
public class BlockGuiWindow extends GuiScreen //extend GuiContainer if you want your gui to have an inventory
{
final int xSizeOfTexture = 192
	   , ySizeOfTexture = 135
                   , white = Color.white.getRGB();
int posX
  , posY;

        //If you want your gui to change based on TileEntity values, reference the tile entity in the constructor
        //you must pass the tile entity using "return new BlockGuiWindow(world.getBlockTileEntity(x, y, z))" in the GuiHandler
        TileEntityClass te;

public BlockGuiWindow(TileEntityClass te)
{
	this.te = te;
}

        public void initGui()
{
	this.buttonList.clear();

	posX = (this.width - xSizeOfTexture) / 2;
	posY = (this.height - ySizeOfTexture) / 2;

	this.buttonList.add(new GuiButton(0, posX + 4, posY + 4, 20, 20, "ButtonText"));
                /*Parameters:
                 * button id used when checking what to do when a button is pressed
                 * The X position of the button
                 * The Y position of the button
                 * The width
                 * The height (keep this at 20 if you can)
                 * The text to be displayed on the button*/
        }

        public void actionPerformed(GuiButton button)
{
	switch(button.id)
	{
                     case 0:
                         //Do button stuff
                         break;
                }
        }

        @Override
public void drawScreen(int x, int y, float f)
{
	drawDefaultBackground();

	GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
	this.mc.renderEngine.bindTexture("path/to/the/background/texture");

	int posX = (this.width - xSizeOfTexture) / 2;
	int posY = (this.height - ySizeOfTexture) / 2;

	drawTexturedModalRect(posX, posY, 0, 0, xSizeOfTexture, ySizeOfTexture); //This draws the background
                //Make sure your background texture is a multiple of 256x256.
                //The xSizeOfTexture and ySizeOfTexture assume that the texture is 256x256. so 128 and 128 always reference half of the texture.
                //Look in the Gui class to see what else you can do here (like rendering textures and strings)
                this.drawString(fontRenderer, "Text", posX + 20, posY + 31, white); //this is where the white variable we set up at the beginning is used
                super.drawScreen(x, y, f);
                /*Here is a trick:
                   If you reset the texture after "super.drawScreen(x, y, f);" (this.mc.renderEngine.bindTexture("path/to/the/background/texture"),
                   you can draw on top of everything, including buttons.
                   Use this to texture buttons, if you don't want them to have text.*/
        }

 

MainModClass:

@Instance //The @Instance goes with the following line, nothing else
    public static MainModClass instance = new MainModClass();

GameRegistry.registerTileEntity(TileEntityClass.class, "TileEntityName");
NetworkRegistry.instance().registerGuiHandler(this, new GuiHandler());

 

Those are the major snippets of the code I use for my stuff (with the names changed.) I have specific needs and you'll need to change the code a bit to do what you want it to, mainly adding a Container class and referencing it in the GuiHandler if you need a GuiContainer. You also may want to change my parenthetical syntax. I'm a C# programmer and the java parenthetical syntax bugs me :P

width=336 height=83http://img836.imageshack.us/img836/1237/cooltext624963071.png[/img]

I make games, minecraft mods/plugins, and some graphic art.

 

Current Project: LoECraft - An industrial minecraft server with its own modpack and custom launcher.

Link to post
Share on other sites

When you click this is what initiates the gui, correct?

It's the onBlockActivated method in the Block class that opens the gui, so yes if I understood what you said correctly.

"MainModClass.instance"

 

What are you referencing with .instance?

I knew I was forgetting something!

I edited my post ;D

Look at the MainModClass definition again.

width=336 height=83http://img836.imageshack.us/img836/1237/cooltext624963071.png[/img]

I make games, minecraft mods/plugins, and some graphic art.

 

Current Project: LoECraft - An industrial minecraft server with its own modpack and custom launcher.

Link to post
Share on other sites

When you click this is what initiates the gui, correct?

It's the onBlockActivated method in the Block class that opens the gui, so yes if I understood what you said correctly.

"MainModClass.instance"

 

What are you referencing with .instance?

I knew I was forgetting something!

I edited my post ;D

Look at the MainModClass definition again.

width=336 height=83http://img836.imageshack.us/img836/1237/cooltext624963071.png[/img]

I make games, minecraft mods/plugins, and some graphic art.

 

Current Project: LoECraft - An industrial minecraft server with its own modpack and custom launcher.

Link to post
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.

Guest
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.



  • Recently Browsing

    No registered users viewing this page.

  • Posts

    • 1.12 is no longer supported on this forum. Please update to a modern version of Minecraft to receive support.
    • I am encountering an error on my modded item's onItemRightClick action, but only when the mod is built to a jar and run in normal minecraft. This error doesn't happen when running from the project in IntelliJ. The item works as intended. I am using the exact same forge version in both instances. (35.1.0) What might be the cause for an error 'in the field' which isn't produced in the IDE? Here is the class which causes the error: public class HookshotItem extends Item implements IVanishable { public HookshotItem(Item.Properties builder) { super(builder); } public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) { ItemStack itemstack = playerIn.getHeldItem(handIn); if (!worldIn.isRemote) { IHookshotIdentifier hookId = playerIn.getCapability(CapabilityHookshotIdentifier.HOOKSHOT_IDENTIFIER_CAPABILITY,null).orElse(null); HookshotHookEntity hookEntity = hookId.getHook(); if(hookEntity == null){ hookEntity = new HookshotHookEntity(ModEntityTypes.HOOKSHOT_HOOK.get(), playerIn, worldIn); worldIn.addEntity(hookEntity); }else{ hookEntity.reelCable(0.3f); } } return ActionResult.func_233538_a_(itemstack, worldIn.isRemote()); } public int getItemEnchantability() { return 0; } } and here is the portion of the log containing the crash: [22Apr2021 22:44:42.940] [Server thread/ERROR] [net.minecraft.server.MinecraftServer/]: Encountered an unexpected exception java.lang.ExceptionInInitializerError: null at com.trigonaut.mobilitymod.item.HookshotItem.func_77659_a(HookshotItem.java:32) ~[?:1.0] at net.minecraft.item.ItemStack.func_77957_a(ItemStack.java:214) ~[?:?] at net.minecraft.server.management.PlayerInteractionManager.func_187250_a(PlayerInteractionManager.java:287) ~[?:?] at net.minecraft.network.play.ServerPlayNetHandler.func_147346_a(ServerPlayNetHandler.java:982) ~[?:?] at net.minecraft.network.play.client.CPlayerTryUseItemPacket.func_148833_a(SourceFile:31) ~[?:?] at net.minecraft.network.play.client.CPlayerTryUseItemPacket.func_148833_a(SourceFile:9) ~[?:?] at net.minecraft.network.PacketThreadUtil.func_225383_a(SourceFile:21) ~[?:?] at net.minecraft.network.PacketThreadUtil$$Lambda$5774/1431595733.run(Unknown Source) ~[?:?] at net.minecraft.util.concurrent.TickDelayedTask.run(SourceFile:18) ~[?:?] at net.minecraft.util.concurrent.ThreadTaskExecutor.func_213166_h(SourceFile:144) ~[?:?] at net.minecraft.util.concurrent.RecursiveEventLoop.func_213166_h(SourceFile:23) ~[?:?] at net.minecraft.server.MinecraftServer.func_213166_h(MinecraftServer.java:733) ~[?:?] at net.minecraft.server.MinecraftServer.func_213166_h(MinecraftServer.java:159) ~[?:?] at net.minecraft.util.concurrent.ThreadTaskExecutor.func_213168_p(SourceFile:118) ~[?:?] at net.minecraft.server.MinecraftServer.func_213205_aW(MinecraftServer.java:716) ~[?:?] at net.minecraft.server.MinecraftServer.func_213168_p(MinecraftServer.java:710) ~[?:?] at net.minecraft.util.concurrent.ThreadTaskExecutor.func_213160_bf(SourceFile:103) ~[?:?] at net.minecraft.server.MinecraftServer.func_213202_o(MinecraftServer.java:695) ~[?:?] at net.minecraft.server.MinecraftServer.func_240802_v_(MinecraftServer.java:645) [?:?] at net.minecraft.server.MinecraftServer.lambda$startServer$0(MinecraftServer.java:232) [?:?] at net.minecraft.server.MinecraftServer$$Lambda$5064/1245825773.run(Unknown Source) [?:?] at java.lang.Thread.run(Thread.java:745) [?:1.8.0_51] Caused by: net.minecraftforge.fml.common.ObfuscationReflectionHelper$UnableToFindMethodException: java.lang.NoSuchMethodException: net.minecraft.entity.Entity.setFlag(int, boolean) at net.minecraftforge.fml.common.ObfuscationReflectionHelper.findMethod(ObfuscationReflectionHelper.java:166) ~[?:?] at com.trigonaut.mobilitymod.entity.HookshotHookEntity.<clinit>(HookshotHookEntity.java:41) ~[?:1.0] ... 22 more Caused by: java.lang.NoSuchMethodException: net.minecraft.entity.Entity.setFlag(int, boolean) at java.lang.Class.getDeclaredMethod(Class.java:2130) ~[?:1.8.0_51] at net.minecraftforge.fml.common.ObfuscationReflectionHelper.findMethod(ObfuscationReflectionHelper.java:160) ~[?:?] at com.trigonaut.mobilitymod.entity.HookshotHookEntity.<clinit>(HookshotHookEntity.java:41) ~[?:1.0] ... 22 more [22Apr2021 22:44:42.945] [Server thread/FATAL] [net.minecraftforge.common.ForgeMod/]: Preparing crash report with UUID a6fd1be1-e806-4d7e-8d84-ca7c4250b981 It looks like something to do with reflection, but I haven't used any reflection anywhere in this mod.
  • Topics

  • Who's Online (See full list)

×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.