GooberGunter Posted December 21, 2017 Posted December 21, 2017 (edited) So I’m trying to show a hud when the player is holding a certain item, but I don’t know how to achieve this Attempt 1: I thought of having the hud render only if the player’s held item is the same as the instance of the item that was registered. Using ItemStack#areItemsEqual (I don’t have it in front of me rn so I’m going off memory). But i don’t know how to get an instance of the player to test it. Also would I need packets? Is the test run on the client side since it is an event dependent on the player Edited December 22, 2017 by GooberGunter Quote
GooberGunter Posted December 22, 2017 Author Posted December 22, 2017 37 minutes ago, diesieben07 said: you can use Minecraft::player to get the player. I’ve seen this notation before but I’m not too sure what that translates to in code, what does the double colon mean? Quote
GooberGunter Posted December 22, 2017 Author Posted December 22, 2017 So to get an instance of Minecraft, I wouldn’t want to directly set an instance to Minecraft.getMinecraft would I? Would I need a packet for that or am I overthinking this Quote
GooberGunter Posted December 22, 2017 Author Posted December 22, 2017 Yeah, I'm overthinking this, I got that part working: @SubscribeEvent public static void onRenderGui(RenderGameOverlayEvent.Post e) { Minecraft mc = Minecraft.getMinecraft(); if(ItemStack.areItemsEqual(mc.player.getHeldItem(EnumHand.OFF_HAND), ModItems.arcanometer.getDefaultInstance())) { new GuiArcanometer(); } } and I've tested it with a logger, but I think there's a problem with the line new GuiArcanometer(); because it's not showing up. And I understand everything up until this point. Gui Class: Spoiler package com.GooberGunter.GrandSorcery.client.hud; import com.GooberGunter.GrandSorcery.GSReferences; import com.GooberGunter.GrandSorcery.common.utils.Util; import net.minecraft.client.gui.GuiScreen; import net.minecraft.util.ResourceLocation; public class GuiArcanometer extends GuiScreen{ int xSize; int ySize; public GuiArcanometer() { this.xSize=32; this.ySize=64; } @Override public void drawScreen(int mouseX, int mouseY, float partialTicks) { this.drawDefaultBackground(); this.mc.getTextureManager().bindTexture(new ResourceLocation(GSReferences.MODID+":textures/gui/arcanometer.png")); this.drawModalRectWithCustomSizedTexture(this.width-this.xSize, this.height-this.ySize, this.xSize, this.ySize, this.xSize, this.ySize, this.xSize, this.ySize); Util.logger.info("printed"); super.drawScreen(mouseX, mouseY, partialTicks); } @Override public boolean doesGuiPauseGame() { return false; } } Quote
GooberGunter Posted December 22, 2017 Author Posted December 22, 2017 OH! Thank makes a lot more sense, when I was looking at some examples I found, it looked like something was missing Quote
GooberGunter Posted December 22, 2017 Author Posted December 22, 2017 (edited) So, it seems that GuiScreen is treating the overlay as an actual gui, exposing the mouse. Am I using the wrong class? Edit: Ok, so it seems that I need to extend Gui not GuiScreen and I need to use the event to actually draw things with GL Edited December 22, 2017 by GooberGunter Quote
GooberGunter Posted December 22, 2017 Author Posted December 22, 2017 So I looked at some more examples and I managed this: GuiArcana: Spoiler package com.GooberGunter.GrandSorcery.client.hud; import com.GooberGunter.GrandSorcery.GSReferences; import com.GooberGunter.GrandSorcery.common.items.ModItems; import com.GooberGunter.GrandSorcery.common.utils.Util; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumHand; import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @Mod.EventBusSubscriber public class GuiArcanometer extends Gui{ static int xSize; static int ySize; static Minecraft mc; public GuiArcanometer(Minecraft mc) { this.xSize=32; this.ySize=64; this.mc = mc; } @SubscribeEvent public static void renderHud(RenderGameOverlayEvent.Post e) { mc = Minecraft.getMinecraft(); if(ItemStack.areItemsEqual(mc.player.getHeldItem(EnumHand.OFF_HAND), ModItems.arcanometer.getDefaultInstance())) { if(e.getType() != ElementType.EXPERIENCE) { Util.logger.info("nope: "+e.getType()); return; } Util.logger.info("test"); GlStateManager.pushAttrib(); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); GlStateManager.disableLighting(); // alpha test and blend needed due to vanilla or Forge rendering bug GlStateManager.enableAlpha(); GlStateManager.enableBlend(); mc.getTextureManager().bindTexture(new ResourceLocation(GSReferences.MODID+":textures/gui/arcanometer.png")); drawModalRectWithCustomSizedTexture(mc.displayWidth-xSize, 0, xSize, ySize, xSize, ySize, xSize, ySize); GlStateManager.popAttrib(); } } } The problem I'm having now is that it's not drawing Quote
GooberGunter Posted December 22, 2017 Author Posted December 22, 2017 "this" and the "mc" field were old code that I hadn't cleared out, I've simplified the class to this: Spoiler package com.GooberGunter.GrandSorcery.client.hud; import com.GooberGunter.GrandSorcery.GSReferences; import com.GooberGunter.GrandSorcery.common.items.ModItems; import com.GooberGunter.GrandSorcery.common.utils.Util; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumHand; import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @Mod.EventBusSubscriber public class GuiArcanometer extends Gui{ static int xSize; static int ySize; @SubscribeEvent public static void renderHud(RenderGameOverlayEvent.Post e) { Minecraft mc = Minecraft.getMinecraft(); if(ItemStack.areItemsEqual(mc.player.getHeldItem(EnumHand.OFF_HAND), ModItems.arcanometer.getDefaultInstance())) { if(e.getType() != ElementType.EXPERIENCE) { //Util.logger.info("nope: "+e.getType()); return; } Util.logger.info("test"); mc.getTextureManager().bindTexture(new ResourceLocation(GSReferences.MODID+":textures/gui/arcanometer.png")); drawModalRectWithCustomSizedTexture(mc.displayWidth-64, 0, 64, 32, 64, 32, 64, 32); } } } the if statements are working, the logger displaying "test" is being executed the the next two lines are not showing any signs of execution. I've gotten no errors about the resource location, and nothing is being displayed. Quote
GooberGunter Posted December 22, 2017 Author Posted December 22, 2017 (edited) what's the easiest way to accomplish that? Somehow, I missed the "choose files" and spent the next hour trying to upload my source code to github (I've been meaning to do it anyway), which was a fun labyrinthine experience, only to get a small version of the picture, then I saw the attachment option. Edited December 22, 2017 by GooberGunter Quote
GooberGunter Posted December 22, 2017 Author Posted December 22, 2017 (edited) Wow that took way too long to do *Sigh* i didn't even see the drag files here Edited December 22, 2017 by GooberGunter Quote
GooberGunter Posted December 22, 2017 Author Posted December 22, 2017 (edited) So something is wrong with using Minecraft.getminecraft().displaywidth, causing it not to render originally I had x=mc.displaywidth-(picture width) and it didn't work, when I replaced it with 0, it worked it might have something to do with the event being static but something tells me that's not the problem From what I can tell: Minecraft::displayWidth isn't the width in terms of pixels which is what the GUI goes off of, but some other unit. So if I had the length of a pixel on screen I could theoretically get the display width in terms of pixels but I'm sure there's an easier way Edited December 22, 2017 by GooberGunter Quote
GooberGunter Posted December 22, 2017 Author Posted December 22, 2017 (edited) The problem here is that the event has to be static in order to be registered, which greatly limits options here for things like drawing a string on the gui since that method is not static in the GUI class, or get the actual display width that is compatible with the Gui. I always see source code where the event isn't static, but every time I've done that it doesn't work so it's not really an option ...Unless, of course, I'm missing something Edited December 22, 2017 by GooberGunter Quote
GooberGunter Posted December 22, 2017 Author Posted December 22, 2017 (edited) 31 minutes ago, diesieben07 said: Not sure what you are talking about with the "static" stuff. What I meant was that you can’t make static references to non static fields or methods, it gives an error in the IDE. I tried to get the GUI scale from GuiScreen but since it’s not static I got an error. And that the event method has to be static for the event bus to register, unless the old registering method still works Edited December 22, 2017 by GooberGunter Quote
GooberGunter Posted December 22, 2017 Author Posted December 22, 2017 (edited) Oh, I changed it from a GuiScreen to a Gui because while the png would load, it would also expose the mouse and I couldn’t find the method to disable it. MouseHandler looked kind of promising but I only looked into it a little bit Edit: so I guess I have one question Would I extend GUI or GuiScreen for a game overlay? Edited December 22, 2017 by GooberGunter Quote
GooberGunter Posted December 22, 2017 Author Posted December 22, 2017 Ok, so I have a class that subscribes to a RenderGameOverlayEvent, which I’ve had. And if I don’t extend a GUI class, how to I draw the png along with 5 integers on the display? Quote
jabelar Posted December 22, 2017 Posted December 22, 2017 Just now, GooberGunter said: Ok, so I have a class that subscribes to a RenderGameOverlayEvent, which I’ve had. And if I don’t extend a GUI class, how to I draw the png along with 5 integers on the display? The rendering events are already in a GL11 rendering mode/matrix so you can use GL11 and related helper classes (like GlStateManager) to draw on the screen. You can look at the code for GUI draw methods to get ideas on what to do, or look for tutorials on making HUD mods. The RenderGameOverlayEvent is fired inside the GuiIngameForge#renderOverlay() method. The reason why you want to use the correct render event is that they are fired in certain orders and if you draw in the wrong one then it will be drawn under other things that are drawn (and you might not even then see what you've drawn). You can also do your own GUI, but I think for overlay it would require substituting your own version of the ingame GUI which in my opinion could be potentially less compatible with other mods. Quote Check out my tutorials here: http://jabelarminecraft.blogspot.com/
GooberGunter Posted December 22, 2017 Author Posted December 22, 2017 (edited) Ok, thanks for clearing that up So I checked the source code of some of the vanilla overlays and managed to get the overlay where I wanted, but I did my own gui: Spoiler @Mod.EventBusSubscriber public class GuiArcanometer extends Gui{ public static void render(Minecraft mc) { ScaledResolution scaledresolution = new ScaledResolution(mc); mc.getTextureManager().bindTexture(new ResourceLocation(GSReferences.MODID+":textures/gui/arcanometer.png")); drawModalRectWithCustomSizedTexture(scaledresolution.getScaledWidth()-64, 0, 64, 32, 64, 32, 64, 32); } @SubscribeEvent public static void renderHud(RenderGameOverlayEvent.Post e) { Minecraft mc = Minecraft.getMinecraft(); if(ItemStack.areItemsEqual(mc.player.getHeldItem(EnumHand.OFF_HAND), ModItems.arcanometer.getDefaultInstance())) { if(e.getType() != ElementType.EXPERIENCE) {return;} render(mc); Util.logger.info("Width: "+mc.displayWidth+" Height: "+mc.displayHeight); } } } 1 hour ago, jabelar said: You can also do your own GUI, but I think for overlay it would require substituting your own version of the ingame GUI which in my opinion could be potentially less compatible with other mods. If I use the Gl helper classes to draw in one location, couldn't another mod draw over it anyway or vice versa? What's the best way to ensure some level of compatibility? Edited December 22, 2017 by GooberGunter Quote
jabelar Posted December 22, 2017 Posted December 22, 2017 1 hour ago, GooberGunter said: Ok, thanks for clearing that up So I checked the source code of some of the vanilla overlays and managed to get the overlay where I wanted, but I did my own gui: Reveal hidden contents @Mod.EventBusSubscriber public class GuiArcanometer extends Gui{ public static void render(Minecraft mc) { ScaledResolution scaledresolution = new ScaledResolution(mc); mc.getTextureManager().bindTexture(new ResourceLocation(GSReferences.MODID+":textures/gui/arcanometer.png")); drawModalRectWithCustomSizedTexture(scaledresolution.getScaledWidth()-64, 0, 64, 32, 64, 32, 64, 32); } @SubscribeEvent public static void renderHud(RenderGameOverlayEvent.Post e) { Minecraft mc = Minecraft.getMinecraft(); if(ItemStack.areItemsEqual(mc.player.getHeldItem(EnumHand.OFF_HAND), ModItems.arcanometer.getDefaultInstance())) { if(e.getType() != ElementType.EXPERIENCE) {return;} render(mc); Util.logger.info("Width: "+mc.displayWidth+" Height: "+mc.displayHeight); } } } If I use the Gl helper classes to draw in one location, couldn't another mod draw over it anyway or vice versa? What's the best way to ensure some level of compatibility? Well the way you're using the GUI class isn't exactly the way GUI are generally used. For example usually they are opened explicitly and have a drawing update. You're just using it to have some helper classes, which is fine, but not the same as actually opening a GUI where you do your code within the screen update methods. There are different types of incompatibility. You can't avoid some other mod wanting to draw over top of your stuff, but you can do things to avoid the other mod from preventing your stuff from being drawn. For example, if you chose to make your own custom ingame GUI that extends and replaces the forge one then if someone else used the same technique then they would end up replacing yours (or you'd replace theirs depending on the order the mods load). However, if you both handle the overlay event then both of you will get to draw what you want. Do you see the difference? -- if you're replacing something then there is more chance of conflict. If you're adding something there is less chance. 1 Quote Check out my tutorials here: http://jabelarminecraft.blogspot.com/
GooberGunter Posted December 22, 2017 Author Posted December 22, 2017 26 minutes ago, jabelar said: For example, if you chose to make your own custom ingame GUI that extends and replaces the forge one then if someone else used the same technique then they would end up replacing yours (or you'd replace theirs depending on the order the mods load). Ok. I'm planning on having the overlay draw 5 integers read from a chunk capability, on top of a .png, which will require updates, would I then use ITickable and GL helper methods to avoid using a gui? Or is this not a case where extending gui will result in a greater chance of incompatibility Quote
jabelar Posted December 22, 2017 Posted December 22, 2017 (edited) 3 minutes ago, GooberGunter said: Ok. I'm planning on having the overlay draw 5 integers read from a chunk capability, on top of a .png, which will require updates, would I then use ITickable and GL helper methods to avoid using a gui? Or is this not a case where extending gui will result in a greater chance of incompatibility extending gui is fine the way you're doing it because you're not replacing any gui. My point was that one way people might do HUD is to actually replace the existing one, possibly extending it depending on how different they want to make it. You're not replacing a GUI so it is fine. Edited December 22, 2017 by jabelar 1 Quote Check out my tutorials here: http://jabelarminecraft.blogspot.com/
GooberGunter Posted December 22, 2017 Author Posted December 22, 2017 Oh, got it. Thank you so much for your help! Quote
Recommended Posts
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.