Jump to content

[SOLVED] GUI not working


Darki

Recommended Posts

At the moment I try to open a GUI when the Player joins the game but the GUI dont open. But why?

GUIHandler:

public class GuiHandler implements IGuiHandler {

public static final int GUI_ID_CB = 0;

@Override
public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
	return null;
}

@Override
public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
	if (ID == GUI_ID_CB)
        return new CharacterBuilder();
	return null;
}

}

My GUI:

public class CharacterBuilder extends GuiScreen{

private GuiButtonExt a;
private GuiSlider b;
private static int strength;

@Override
public void initGui() {
	buttonList.add(this.a = new GuiButtonExt(0, this.width / 2 - 50, this.height - 30, 100, 20, "Start"));
	buttonList.add(this.b = new GuiSlider(1, this.width / 4 - 75 , 30, 150, 20, "Strength: ", "", 0, 5, 0, false, true));
}

@Override
protected void actionPerformed(GuiButton button) throws IOException {
	if(button.id == a.id){
		strength = b.getValueInt();
		mc.displayGuiScreen((GuiScreen)null);
	}
	super.actionPerformed(button);
}

@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
	drawDefaultBackground();
	super.drawScreen(mouseX, mouseY, partialTicks);
}

@Override
public boolean doesGuiPauseGame() {
	return true;
}

public static int getStrength(){
	return strength;
}

}

My Main Class:

@Mod(modid = Main.MODID, version = Main.VERSION)
public class Main {

public static final String MODID = "ultrareal";
public static final String VERSION = "1.0";
private static Main INSTANCE;
public static Main getInstance(){return INSTANCE;}
public static String path = System.getProperty("user.dir");

@SidedProxy(clientSide = "me.darki.ultrareal.proxy.ClientProxy", serverSide = "me.darki.ultrareal.proxy.ServerProxy")
public static ServerProxy proxy;

public static HealPack healPack = new HealPack();

//------------------------------------------------------------------------------------------\\

@EventHandler
public void preInit(FMLPreInitializationEvent e){
	INSTANCE = this;
	registerItems();
	registerEvents();
}

@EventHandler
public void init(FMLInitializationEvent e){
	NetworkRegistry.INSTANCE.registerGuiHandler(INSTANCE, new GuiHandler());
	SoundsManager.registerSounds();
}

@EventHandler
public void postInit(FMLPostInitializationEvent e){
	proxy.registerClientStuff();
	io();
}

//------------------------------------------------------------------------------------------\\

private void io(){
	new File(path + "\\", "UltraReal").mkdirs();
	path = path + "\\" + "UltraReal";
	new File(path, "UltraReal.data");
}

private void registerItems(){
	GameRegistry.register(healPack);
}

private void registerEvents(){
	MinecraftForge.EVENT_BUS.register(new OverlayRenderEvents());
	MinecraftForge.EVENT_BUS.register(new WorldEvents());
	MinecraftForge.EVENT_BUS.register(new PlayerEvents());
	MinecraftForge.EVENT_BUS.register(new BlackScreen());
}
}

And my Event Class where I open the GUI:

	@SubscribeEvent
public void onJoin(EntityJoinWorldEvent e){
	if(e.getEntity() instanceof EntityPlayer && !shown){
		EntityPlayer player = (EntityPlayer) e.getEntity();
		player.openGui(Main.getInstance(), GuiHandler.GUI_ID_CB, e.getWorld(), player.getPosition().getX(), player.getPosition().getY(), player.getPosition().getZ());
		shown = true;
	}
}

private boolean shown = false;

Link to comment
Share on other sites

Calling

EntityPlayer#openGUI

on the logical server (when

World#isRemote

is

false

) will do nothing if

IGuiHandler#getServerGuiElement

returns

null

. For client-only GUIs with no

Container

, you need to call

EntityPlayer#openGUI

(or

Minecraft#displayGuiScreen

) on the logical client (when

World#isRemote

is

true

).

 

Having the

shown

field in your event handler is a bad idea and will almost certainly screw things up. The value won't be unique to a player (so only the first player to join a world will have the GUI shown) or save (so only the first save loaded by the physical client will have the GUI shown), and won't persist between reloads (so shutting down the physical client or server will reset it).

 

To store a single one-time flag per-player, you can use the

EntityPlayer.PERSISTED_NBT_TAG

sub-compound of

Entity#getEntityData

. Make sure you use a key unique to your mod, e.g. by prefixing it with your mod ID.

 

For anything that's more complex or used more than once, use Capabilities.

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

Link to comment
Share on other sites

Ok I am looking at this, but my GUI doesnt need a Container because it is a GUI Screen

 

Then open it on the client.

 

Note that you'll need to set the flag on the server, so you may only want to set it when the player has finished with the GUI rather than when they're first shown the GUI.

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

Link to comment
Share on other sites

How? :)

 

For client-only GUIs with no

Container

, you need to call

EntityPlayer#openGUI

(or

Minecraft#displayGuiScreen

) on the logical client (when

World#isRemote

is

true

).

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

Link to comment
Share on other sites

Now I changed it a little bit:

	private ConcurrentHashMap<EntityPlayer, Boolean> shown = new ConcurrentHashMap<EntityPlayer, Boolean>();

@SubscribeEvent
public void onJoin(EntityJoinWorldEvent e) {
	if (e.getEntity() instanceof EntityPlayer) {
		EntityPlayer player = (EntityPlayer) e.getEntity();
		shown.put(player, false);
		if (!(new File(Main.path + File.separator + "Datas" + File.separator + player.getName() + ".data").exists())) {
			if(!shown.get(player)){
				if(e.getWorld().isRemote){
					player.openGui(Main.getInstance(), GuiHandler.GUI_ID_CB, e.getWorld(), player.getPosition().getX(), player.getPosition().getY(), player.getPosition().getZ());
					shown.put(player, true);
				}
			}
		}else{
			shown.put(player, true);
		}
	}
}

Nothing happend

Link to comment
Share on other sites

This new code isn't much better.

 

Why are you storing data in a file in the OS user's home directory instead of using the data storage mechanisms provided by Minecraft/Forge (entity data or capabilities)?

 

There's no need for a

ConcurrentHashMap

if you only access it from one thread (the client thread). There's no need for any

Map

if you use the proper data storage mechanisms.

 

Since you're opening the GUI on the logical client, you should only do it if the player that joined the world is the client player (

Minecraft#thePlayer

).

 

I suggest you put a breakpoint in the

onJoin

method and step through it in the debugger to see why it's not working.

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

Link to comment
Share on other sites

It goes through all ifs but the gui doesnt screen anyway

 

So it reaches the

EntityPlayer#openGUI

call?

 

I suggest you set a breakpoint in

Minecraft#displayGuiScreen

to see whether your GUI is being opened and then instantly closed.

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

Link to comment
Share on other sites

Ok I did a Debug with Breakpoints and it says that it doesnt go through that:

if (entityPlayer instanceof EntityPlayerMP && !(entityPlayer instanceof FakePlayer))

 

That looks like it's a line from

FMLNetworkHandler.openGui

.

EntityPlayerMP

is the server-side player class, client-side players won't be instances of it. The client-side GUI opening is handled in one of the

else if

blocks lower in the method.

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

Link to comment
Share on other sites

Yeah I see it.....but through this line it goes:

else if (FMLCommonHandler.instance().getSide().equals(Side.CLIENT))

But after that, hm I dont know...after that there are only 2 Lines 1.

Object guiContainer = NetworkRegistry.INSTANCE.getLocalGuiContainer(mc, entityPlayer, modGuiId, world, x, y, z);

and 2.

FMLCommonHandler.instance().showGuiScreen(guiContainer);

Link to comment
Share on other sites

That's where FML opens the

GuiScreen

that was returned by

IGuiHandler#getClientGuiElement

.

 

Does it reach

Minecraft#displayGuiScreen

? Is

Minecraft#displayGuiScreen

called afterwards with a different

GuiScreen

(or

null

)?

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

Link to comment
Share on other sites

wait i used player.openGui and there wasnt a displayGuiScreen

 

EntityPlayer#openGui

indirectly calls

Minecraft#displayGuiScreen

on the client side through

FMLNetworkHandler.openGui

,

FMLCommonHandler#showGuiScreen

and

FMLClientHandler#showGuiScreen

.

 

Set a breakpoint in

Minecraft#displayGuiScreen

, is it ever called with your

GuiScreen

? Is it called after that with a different

GuiScreen

?

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

Link to comment
Share on other sites

Yeah it will be called. Something in this code is the Problem:

this.setIngameNotInFocus();
            KeyBinding.unPressAllKeys();

            while (Mouse.next())
            {
                ;
            }

            while (Keyboard.next())
            {
                ;
            }

            ScaledResolution scaledresolution = new ScaledResolution(this);
            int i = scaledresolution.getScaledWidth();
            int j = scaledresolution.getScaledHeight();
            ((GuiScreen)guiScreenIn).setWorldAndResolution(this, i, j);
            this.skipRenderWorld = false;

 

Link to comment
Share on other sites

Probably the while loops.  Like, their entire existence.

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

That's vanilla code, not the OP's code.

 

If

Minecraft#displayGuiScreen

is called with a different

GuiScreen

after your GUI is displayed, where is it called from? Look at the stack in the debugger.

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

Link to comment
Share on other sites

Ok I find it displayGuiScreen will be called from FMLClientHandler.showGuiScreen(GuiScreen) and that will be called from FMLCommonHandler.showGuiScreen(Object) and that will be called from FMLCommonHandler.showGuiScreen(Object) :

1.

net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.openGui(this, mod, modGuiId, world, x, y, z);

2.

FMLCommonHandler.instance().showGuiScreen(guiContainer);

3.

sidedDelegate.showGuiScreen(clientGuiElement);

4.

client.displayGuiScreen(gui);

Link to comment
Share on other sites

That's still your GUI.

 

What I suspect is happening is the following:

[*]You call

EntityPlayer#openGUI

from your event handler

[*]FML calls

Minecraft#displayGuiScreen

with your GUI to display it

[*]Something else calls

Minecraft#displayGuiScreen

with a different GUI, which replaces yours.

 

I want to know whether step 3 happens and if it does happen, where does it happen from?

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

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.