Posted December 2, 20178 yr So I basically have a mod that's supposed to draw an esp over every mob in the world (or at least within viewing distance) Main.java package prickles.insightsq.core; import java.util.ArrayList; import java.util.Arrays; import net.minecraft.client.Minecraft; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.Mod.Instance; import net.minecraftforge.fml.common.SidedProxy; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import prickles.insight.hud.HelmetHandler; import prickles.insight.hud.RenderOverlayHandler; import prickles.insightsq.core.proxies.CommonProxy; @Mod(modid = Reference.MODID, name = Reference.NAME, version = Reference.VERSION) public class Main { @Instance public static Main instance; @SidedProxy(clientSide = Reference.CLIENT, serverSide = Reference.COMMON) public static CommonProxy proxy; public static Minecraft mc; public static ArrayList<String> friendlyUsernames = new ArrayList<String>(); public static String[] friendlyNamesArr; @EventHandler public static void preInit(FMLPreInitializationEvent e) { proxy.preInit(e); } @EventHandler public static void init(FMLInitializationEvent e) { proxy.init(e); initialize(); MinecraftForge.EVENT_BUS.register(HelmetHandler.class); } @EventHandler public static void postInit(FMLPostInitializationEvent e) { proxy.postInit(e); MinecraftForge.EVENT_BUS.register(new RenderOverlayHandler(mc)); } public static void initialize() { mc = Minecraft.getMinecraft(); friendlyNamesArr = new String[] { "Pr1ckl3s", "DoubleBrackets", "UnderCoverChicken", "Cutout", "Generaltyler1", "EmeraldUpsilon" }; friendlyUsernames.addAll(Arrays.asList(friendlyNamesArr)); } } HelmetHandler.java package prickles.insight.hud; import java.util.Arrays; import java.util.Iterator; import java.util.List; import net.minecraft.client.entity.EntityOtherPlayerMP; import net.minecraft.entity.Entity; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.passive.EntityAnimal; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; import prickles.insight.hud.utils.RenderUtils; import prickles.insightsq.core.Main; public class HelmetHandler { public static boolean equipped; public static List<Entity> worldEntities; @SubscribeEvent public static void helmet(TickEvent.PlayerTickEvent event) { EntityPlayer p = event.player; if (p.inventory.armorItemInSlot(3).getItem() == Item.getItemById(314)) { equipped = true; } else { equipped = false; } if (Main.friendlyUsernames.contains(p.getName())) { Main.friendlyUsernames.remove(Arrays.binarySearch(Main.friendlyNamesArr, p.getName())); } } @SubscribeEvent public static void worldLoader(TickEvent.WorldTickEvent event) { worldEntities = event.world.loadedEntityList; } @SubscribeEvent public static void render(RenderWorldLastEvent event) { if (equipped) { if (worldEntities != null) { Iterator<Entity> iter = worldEntities.iterator(); while (iter.hasNext()) { Entity e = iter.next(); if (e instanceof EntityOtherPlayerMP) { if (Main.friendlyUsernames.contains(e.getName())) { RenderUtils.drawESP(event, e, 1f, 0, 255, 0); } else { RenderUtils.drawESP(event, e, 1f, 255, 0, 0); } } if (e instanceof EntityMob) { RenderUtils.drawESP(event, e, 1f, 255, 187, 0); } if (e instanceof EntityAnimal) { RenderUtils.drawESP(event, e, 1f, 0, 150, 255); } } } } } } RenderUtils.java package prickles.insight.hud.utils; import java.awt.Color; import org.lwjgl.opengl.GL11; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.entity.Entity; import net.minecraft.util.math.Vec3d; import net.minecraftforge.client.event.RenderWorldLastEvent; public class RenderUtils { public static void drawESP(RenderWorldLastEvent evt, Entity e, float lineWidth, int r, int g, int b) { double eX = e.lastTickPosX + (e.posX - e.lastTickPosX) * (double) evt.getPartialTicks(); double eY = e.lastTickPosY + (e.posY - e.lastTickPosY) * (double) evt.getPartialTicks(); double eZ = e.lastTickPosZ + (e.posZ - e.lastTickPosZ) * (double) evt.getPartialTicks(); Entity p = Minecraft.getMinecraft().getRenderViewEntity(); double pX = p.lastTickPosX + (p.posX - p.lastTickPosX) * (double) evt.getPartialTicks(); double pY = p.lastTickPosY + (p.posY - p.lastTickPosY) * (double) evt.getPartialTicks(); double pZ = p.lastTickPosZ + (p.posZ - p.lastTickPosZ) * (double) evt.getPartialTicks(); if (p.getDistanceSqToEntity(e) <= Minecraft.getMinecraft().gameSettings.renderDistanceChunks * 16) { Tessellator.getInstance().getBuffer().setTranslation(-pX, -pY, -pZ); renderESP(Tessellator.getInstance(), new Vec3d(eX, eY, eZ), new Vec3d(eX + 1, eY + 1, eZ + 1), r, g, b, lineWidth); Tessellator.getInstance().getBuffer().setTranslation(0, 0, 0); } } public static void BBP(BufferBuilder bufferBuilder, double x, double y, double z, Color c) { bufferBuilder.pos(x, y, z).color(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()).endVertex();; } public static void renderESP(Tessellator t, Vec3d posA, Vec3d posB, int r, int g, int b, float lineWidth) { GL11.glPushAttrib(GL11.GL_ENABLE_BIT); GL11.glDisable(GL11.GL_CULL_FACE); GL11.glDisable(GL11.GL_LIGHTING); GL11.glDisable(GL11.GL_TEXTURE_2D); GL11.glEnable(GL11.GL_BLEND); GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); Color c = new Color(r, g, b, 255); GL11.glColor3d(r, g, b); GL11.glLineWidth(lineWidth); GL11.glDepthMask(false); Tessellator tessellator = t.getInstance(); BufferBuilder bufferBuilder = tessellator.getBuffer(); bufferBuilder.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR); double dx = Math.abs(posA.x - posB.x); double dy = Math.abs(posA.y - posB.y); double dz = Math.abs(posA.z - posB.z); BBP(bufferBuilder, posA.x, posA.y, posA.z, c); BBP(bufferBuilder, posA.x, posA.y, posA.z + dz, c); BBP(bufferBuilder, posA.x, posA.y, posA.z + dz, c); BBP(bufferBuilder, posA.x + dx, posA.y, posA.z + dz, c); BBP(bufferBuilder, posA.x + dx, posA.y, posA.z + dz, c); BBP(bufferBuilder, posA.x + dx, posA.y, posA.z, c); BBP(bufferBuilder, posA.x + dx, posA.y, posA.z, c); BBP(bufferBuilder, posA.x, posA.y, posA.z, c); BBP(bufferBuilder, posA.x, posA.y + dy, posA.z, c); BBP(bufferBuilder, posA.x, posA.y + dy, posA.z + dz, c); BBP(bufferBuilder, posA.x, posA.y + dy, posA.z+dz, c); BBP(bufferBuilder, posA.x+dx, posA.y + dy, posA.z+dz, c); BBP(bufferBuilder, posA.x + dx, posA.y + dy, posA.z + dz, c); BBP(bufferBuilder, posA.x + dx, posA.y + dy, posA.z, c); BBP(bufferBuilder, posA.x + dx, posA.y + dy, posA.z, c); BBP(bufferBuilder, posA.x, posA.y + dy, posA.z, c); BBP(bufferBuilder, posA.x, posA.y, posA.z, c); BBP(bufferBuilder, posA.x, posA.y +dy, posA.z, c); BBP(bufferBuilder, posA.x, posA.y, posA.z + dz, c); BBP(bufferBuilder, posA.x, posA.y + dy, posA.z + dz, c); BBP(bufferBuilder, posA.x + dx, posA.y, posA.z + dz, c); BBP(bufferBuilder, posA.x + dx, posA.y + dy, posA.z + dz, c); BBP(bufferBuilder, posA.x + dx, posA.y, posA.z, c); BBP(bufferBuilder, posA.x + dx, posA.y + dy, posA.z, c); tessellator.draw(); GL11.glDepthMask(true); GL11.glPopAttrib(); } } This is just the way I'm drawing my boxes if it's necessary (Will be changed to look better) As far as I know, I need the RenderWorldLastEvent as a parameter for my drawESP method to render my boxes When I tried using Minecraft.getMinecraft().getRenderPartialTicks() instead, I would get this error: Spoiler java.lang.NullPointerException: Exception in server tick loop Currently, with the above code, I get the following error: Spoiler java.util.ConcurrentModificationException: null at java.util.ArrayList$Itr.checkForComodification(Unknown Source) ~[?:1.8.0_151] at java.util.ArrayList$Itr.next(Unknown Source) ~[?:1.8.0_151] at prickles.insight.hud.HelmetHandler.render(HelmetHandler.java:53) ~[HelmetHandler.class:?] at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_8_HelmetHandler_render_RenderWorldLastEvent.invoke(.dynamic) ~[?:?] at net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:90) ~[ASMEventHandler.class:?] at net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:179) ~[EventBus.class:?] at net.minecraftforge.client.ForgeHooksClient.dispatchRenderLast(ForgeHooksClient.java:160) ~[ForgeHooksClient.class:?] at net.minecraft.client.renderer.EntityRenderer.renderWorldPass(EntityRenderer.java:1483) ~[EntityRenderer.class:?] at net.minecraft.client.renderer.EntityRenderer.renderWorld(EntityRenderer.java:1312) ~[EntityRenderer.class:?] at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1115) ~[EntityRenderer.class:?] at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1192) ~[Minecraft.class:?] at net.minecraft.client.Minecraft.run(Minecraft.java:436) [Minecraft.class:?] at net.minecraft.client.main.Main.main(Main.java:118) [Main.class:?] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_151] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_151] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_151] at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_151] at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?] at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_151] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_151] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_151] at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_151] at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) [start/:?] at GradleStart.main(GradleStart.java:26) [start/:?] Any suggestions? Edited December 3, 20178 yr by Prickles
December 3, 20178 yr Author Alright I fixed it (Pretty shameful errors) Here's what I did New HelmetHandler class: package prickles.insight.hud; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; import net.minecraft.client.entity.EntityOtherPlayerMP; import net.minecraft.entity.Entity; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.passive.EntityAnimal; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; import prickles.insight.hud.utils.RenderUtils; import prickles.insightsq.core.Main; public class HelmetHandler { public static boolean equipped; public static List<Entity> worldEntities; @SubscribeEvent public static void helmet(TickEvent.PlayerTickEvent event) { EntityPlayer p = event.player; if (p.inventory.armorItemInSlot(3).getItem() == Item.getItemById(314)) { equipped = true; } else { equipped = false; } if (Main.friendlyUsernames.contains(p.getName())) { Main.friendlyUsernames.remove(Arrays.binarySearch(Main.friendlyNamesArr, p.getName())); } } @SubscribeEvent public static void worldLoader(TickEvent.WorldTickEvent event) { worldEntities = event.world.loadedEntityList; } @SubscribeEvent public static void render(RenderWorldLastEvent event) { if (equipped) { if (worldEntities != null) { for (int i = 0; i < worldEntities.size(); i++) { Entity e = worldEntities.get(i); if (e instanceof EntityOtherPlayerMP) { if (Main.friendlyUsernames.contains(e.getName())) { RenderUtils.drawESP(event, e, 1f, 0, 255, 0); } else { RenderUtils.drawESP(event, e, 1f, 255, 0, 0); } } if (e instanceof EntityMob) { RenderUtils.drawESP(event, e, 1f, 255, 187, 0); } if (e instanceof EntityAnimal) { RenderUtils.drawESP(event, e, 1f, 0, 150, 255); } } } } } } Edited December 3, 20178 yr by Prickles
December 3, 20178 yr I don't think you need to handle the world tick event at all. You're just using that to reference the world entity list but you can just access that directly when you need it. I would get rid of the static worldEntities list field and forget the world tick handler. You also probably don't need the player tick event either. The render event happens often enough (even more than the tick) so whether the player is wearing the helmet can be checked at the time of rendering, and the render event will only happen for the one player. So moving the player tick code to the render event will also help avoid the issues that diesieben07 is mentioning. If you put everything into the render event then you shouldn't has as much issue with "reaching across the sides" or issue with syncrhonization between the time the other events fire for other players. Check out my tutorials here: http://jabelarminecraft.blogspot.com/
December 4, 20178 yr Author Okay, so would this be any better?: @SubscribeEvent @SideOnly(Side.CLIENT) public static void helmet(RenderWorldLastEvent event) { Minecraft mc = Minecraft.getMinecraft(); EntityPlayer p = (EntityPlayer) mc.player; List<Entity> entities = mc.world.loadedEntityList; if (Main.friendlyUsernames.contains(p.getName())) { Main.friendlyUsernames.remove(Arrays.binarySearch(Main.friendlyNamesArr, p.getName())); } if (p.inventory.armorItemInSlot(3).getItem() == Item.getItemById(314)) { equipped = true; } else { equipped = false; } if (equipped) { for (Entity e : entities) { if(!(e instanceof EntityLiving)) { continue; } if (e instanceof EntityOtherPlayerMP) { if (Main.friendlyUsernames.contains(e.getName())) { RenderUtils.drawESP(event, e, 2f, 0, 255, 0); } else { RenderUtils.drawESP(event, e, 2f, 255, 0, 0); } } if (e instanceof EntityMob) { RenderUtils.drawESP(event, e, 2f, 255, 187, 0); } if (e instanceof EntityAnimal) { RenderUtils.drawESP(event, e, 2f, 0, 150, 255); } } } } Or would I need to use a packet system (IMessage example in the docs) and constantly get the server world and player to use instead of mc.player and mc.world? Edited December 4, 20178 yr by Prickles
December 4, 20178 yr Author This is more of a private mod, so I just made a list of the usernames of my friends and I, and that whole thing with Arrays.binarySearch is to remove the player's username from that list so he doesn't draw a box on himself. I guess I should use UUIDs tho lol. Any player not on that list gets a red esp and any player on it gets a green one. And I am using Arrays.asList I totally forgot about needing to sort that list and remembered a simple substitute search method I made haha Here's some new code: Spoiler Bottom of Main.java: public static void initialize() { friendlyUUIDArr = new String[] {"57037bd92cdd4b588d91e2d683fa468f", "5f9ef67d87be4b16a711dab015f33bd0", "802e7296b7c746748dad0c9067d6a457", "32ddd1968dda4c799742c2ffa5efdfe0", "c71047eb7daa4a0db6bb899143d7b92c", "6ec6981095984f388fe26c9bd44866d3" }; friendlyUUID.addAll(Arrays.asList(friendlyUUIDArr)); } public static int search(String str, ArrayList<String> list) { for(int i = 0; i < list.size(); i++) { if(str.equals(list.get(i))) { return i; } } return 0; } I know, the manual String[] input is messy but I'm lazy so it's staying lol HelmetHandler#helmet: @SubscribeEvent public static void helmet(RenderWorldLastEvent event) { Minecraft mc = Minecraft.getMinecraft(); EntityPlayer p = (EntityPlayer) mc.player; List<Entity> entities = mc.world.loadedEntityList; if (Main.friendlyUUID.contains(p.getUniqueID().toString())) { Main.friendlyUUID.remove(Main.search(p.getUniqueID().toString(), Main.friendlyUUID)); } if (p.inventory.armorItemInSlot(3).getItem() == Item.getItemById(314)) { equipped = true; } else { equipped = false; } if (equipped && esp) { for (Entity e : entities) { if(!(e instanceof EntityLiving)) { continue; } if (e instanceof EntityOtherPlayerMP) { if (Main.friendlyUUID.contains(e.getUniqueID().toString())) { RenderUtils.drawESP(event, e, 2f, 0, 255, 0); } else { RenderUtils.drawESP(event, e, 2f, 255, 0, 0); } } if (e instanceof EntityMob) { RenderUtils.drawESP(event, e, 2f, 255, 187, 0); } if (e instanceof EntityAnimal || e instanceof EntityAmbientCreature) { RenderUtils.drawESP(event, e, 2f, 0, 150, 255); } } } } Esp is just a new boolean I added for toggling through chat commands Equipped is just defined by whether or not the player is wearing a gold helmet I need to access it because I have a class called RenderOverlayHandler that has a RenderGameOverlayEvent method that renders an overlay if the player is wearing said helmet: Spoiler package prickles.insight.hud; import org.lwjgl.opengl.GL11; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.Tessellator; import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import prickles.insightsq.core.Reference; public class RenderOverlayHandler extends Gui { private final ResourceLocation hud = new ResourceLocation(Reference.MODID, "textures/gui/hud.png"); public Minecraft mc; public int w; public int h; public static boolean ro = true; public RenderOverlayHandler(Minecraft mc) { this.mc = mc; } @SubscribeEvent public void renderOverlay(RenderGameOverlayEvent.Post event) { if (event.getType() == ElementType.HOTBAR && ro) { if (HelmetHandler.equipped) { GL11.glPushAttrib(GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_ENABLE_BIT); GL11.glEnable(GL11.GL_BLEND); GL11.glDepthMask(false); w = mc.displayWidth; h = mc.displayHeight; ScaledResolution sr = new ScaledResolution(mc); mc.renderEngine.bindTexture(hud); drawScaledCustomSizeModalRect(0, 0, 0, 0, w, h, sr.getScaledWidth(), sr.getScaledHeight(), w, h); GL11.glDisable(GL11.GL_BLEND); GL11.glDepthMask(true); GL11.glPopAttrib(); } } } } I guess I could just combine the two classes but I don't think it would really make a difference
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.