diff options
5 files changed, 266 insertions, 82 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java index 610d6931..2e108d21 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java @@ -170,6 +170,7 @@ public class NEUEventListener { @SubscribeEvent public void onWorldLoad(WorldEvent.Unload event) { NotEnoughUpdates.INSTANCE.saveConfig(); + CrystalMetalDetectorSolver.reset(); } private static long notificationDisplayMillis = 0; @@ -787,6 +788,7 @@ public class NEUEventListener { @SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true) public void onGuiChat(ClientChatReceivedEvent e) { if(e.type == 2) { + CrystalMetalDetectorSolver.process(e.message); e.message = processChatComponent(e.message); return; } @@ -834,6 +836,9 @@ public class NEUEventListener { e.message = new ChatComponentText(m2); } } + if (unformatted.startsWith("You found ") && SBInfo.getInstance().getLocation() != null && SBInfo.getInstance().getLocation().equals("crystal_hollows")){ + CrystalMetalDetectorSolver.reset(); + } } public static boolean drawingGuiScreen = false; @@ -2446,4 +2451,9 @@ public class NEUEventListener { } } } + + @SubscribeEvent + public void onRenderLast(RenderWorldLastEvent event){ + CrystalMetalDetectorSolver.render(event.partialTicks); + } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java index a43eb0e6..b63831ac 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java @@ -2,6 +2,7 @@ package io.github.moulberry.notenoughupdates.core.util.render; import io.github.moulberry.notenoughupdates.core.BackgroundBlur; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.GlStateManager; @@ -9,8 +10,12 @@ import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.entity.Entity; +import net.minecraft.util.BlockPos; +import net.minecraft.util.EnumChatFormatting; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL14; +import org.lwjgl.util.vector.Vector3f; public class RenderUtils { @@ -141,4 +146,84 @@ public class RenderUtils { GlStateManager.enableTexture2D(); } + public static void renderWayPoint(String str, BlockPos loc, float partialTicks) { + renderWayPoint(str, new Vector3f(loc.getX(), loc.getY(), loc.getZ()), partialTicks); + } + public static void renderWayPoint(String str, Vector3f loc, float partialTicks) { + GlStateManager.alphaFunc(516, 0.1F); + + GlStateManager.pushMatrix(); + + Entity viewer = Minecraft.getMinecraft().getRenderViewEntity(); + double viewerX = viewer.lastTickPosX + (viewer.posX - viewer.lastTickPosX) * partialTicks; + double viewerY = viewer.lastTickPosY + (viewer.posY - viewer.lastTickPosY) * partialTicks; + double viewerZ = viewer.lastTickPosZ + (viewer.posZ - viewer.lastTickPosZ) * partialTicks; + + double x = loc.x-viewerX+0.5f; + double y = loc.y-viewerY-viewer.getEyeHeight(); + double z = loc.z-viewerZ+0.5f; + + double distSq = x*x + y*y + z*z; + double dist = Math.sqrt(distSq); + if(distSq > 144) { + x *= 12/dist; + y *= 12/dist; + z *= 12/dist; + } + GlStateManager.translate(x, y, z); + GlStateManager.translate(0, viewer.getEyeHeight(), 0); + + renderNametag(str); + + GlStateManager.rotate(-Minecraft.getMinecraft().getRenderManager().playerViewY, 0.0F, 1.0F, 0.0F); + GlStateManager.rotate(Minecraft.getMinecraft().getRenderManager().playerViewX, 1.0F, 0.0F, 0.0F); + GlStateManager.translate(0, -0.25f, 0); + GlStateManager.rotate(-Minecraft.getMinecraft().getRenderManager().playerViewX, 1.0F, 0.0F, 0.0F); + GlStateManager.rotate(Minecraft.getMinecraft().getRenderManager().playerViewY, 0.0F, 1.0F, 0.0F); + + renderNametag(EnumChatFormatting.YELLOW.toString()+Math.round(dist)+"m"); + + GlStateManager.popMatrix(); + + GlStateManager.disableLighting(); + } + + public static void renderNametag(String str) { + FontRenderer fontrenderer = Minecraft.getMinecraft().fontRendererObj; + float f = 1.6F; + float f1 = 0.016666668F * f; + GlStateManager.pushMatrix(); + GL11.glNormal3f(0.0F, 1.0F, 0.0F); + GlStateManager.rotate(-Minecraft.getMinecraft().getRenderManager().playerViewY, 0.0F, 1.0F, 0.0F); + GlStateManager.rotate(Minecraft.getMinecraft().getRenderManager().playerViewX, 1.0F, 0.0F, 0.0F); + GlStateManager.scale(-f1, -f1, f1); + GlStateManager.disableLighting(); + GlStateManager.depthMask(false); + GlStateManager.disableDepth(); + GlStateManager.enableBlend(); + GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer worldrenderer = tessellator.getWorldRenderer(); + int i = 0; + + int j = fontrenderer.getStringWidth(str) / 2; + GlStateManager.disableTexture2D(); + worldrenderer.begin(7, DefaultVertexFormats.POSITION_COLOR); + worldrenderer.pos((double)(-j - 1), (double)(-1 + i), 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex(); + worldrenderer.pos((double)(-j - 1), (double)(8 + i), 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex(); + worldrenderer.pos((double)(j + 1), (double)(8 + i), 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex(); + worldrenderer.pos((double)(j + 1), (double)(-1 + i), 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex(); + tessellator.draw(); + GlStateManager.enableTexture2D(); + fontrenderer.drawString(str, -fontrenderer.getStringWidth(str) / 2, i, 553648127); + GlStateManager.depthMask(true); + + fontrenderer.drawString(str, -fontrenderer.getStringWidth(str) / 2, i, -1); + + GlStateManager.enableDepth(); + GlStateManager.enableBlend(); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GlStateManager.popMatrix(); + } + } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java new file mode 100644 index 00000000..c6ad2ef1 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java @@ -0,0 +1,139 @@ +package io.github.moulberry.notenoughupdates.miscfeatures; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; +import io.github.moulberry.notenoughupdates.util.SBInfo; +import net.minecraft.client.Minecraft; +import net.minecraft.util.*; + +import java.util.ArrayList; +import java.util.List; + +public class CrystalMetalDetectorSolver { + private static final Minecraft mc = Minecraft.getMinecraft(); + private static BlockPos prevPos; + private static double prevDist = 0; + private static List<BlockPos> possibleBlocks = new ArrayList<>(); + private static final List<BlockPos> locations = new ArrayList<>(); + + public static void process(IChatComponent message) { + if (SBInfo.getInstance().getLocation() != null && SBInfo.getInstance().getLocation().equals("crystal_hollows") + && message.getUnformattedText().contains("TREASURE: ")) { + double dist = Double.parseDouble(message.getUnformattedText().split("TREASURE: ")[1].split("m")[0].replaceAll("(?!\\.)\\D", "")); + if (NotEnoughUpdates.INSTANCE.config.mining.metalDetectorEnabled && prevDist == dist && prevPos.getX() == mc.thePlayer.getPosition().getX() && + prevPos.getY() == mc.thePlayer.getPosition().getY() && + prevPos.getZ() == mc.thePlayer.getPosition().getZ() && !locations.contains(mc.thePlayer.getPosition())) { + if (possibleBlocks.size() == 0) { + locations.add(mc.thePlayer.getPosition()); + for (int zOffset = (int) Math.floor(-dist); zOffset <= Math.ceil(dist); zOffset++) { + for (int y = 65; y <= 75; y++) { + double calculatedDist = 0; + int xOffset = 0; + while (calculatedDist < dist) { + BlockPos pos = new BlockPos(Math.floor(mc.thePlayer.posX) + xOffset, + y, Math.floor(mc.thePlayer.posZ) + zOffset); + BlockPos above = new BlockPos(Math.floor(mc.thePlayer.posX) + xOffset, + y + 1, Math.floor(mc.thePlayer.posZ) + zOffset); + xOffset++; + calculatedDist = getPlayerPos().distanceTo(new Vec3(pos).addVector(0D,1D,0D)); + if (inRange(calculatedDist, dist) && treasureAllowed(pos) && !possibleBlocks.contains(pos) && + mc.theWorld.getBlockState(above).getBlock().getRegistryName().equals("minecraft:air")) { + possibleBlocks.add(pos); + } + xOffset++; + } + xOffset = 0; + calculatedDist = 0; + while (calculatedDist < dist) { + BlockPos pos = new BlockPos(Math.floor(mc.thePlayer.posX) - xOffset, + y, Math.floor(mc.thePlayer.posZ) + zOffset); + BlockPos above = new BlockPos(Math.floor(mc.thePlayer.posX) - xOffset, + y + 1, Math.floor(mc.thePlayer.posZ) + zOffset); + calculatedDist = getPlayerPos().distanceTo(new Vec3(pos).addVector(0D,1D,0D)); + if (inRange(calculatedDist, dist) && treasureAllowed(pos) && !possibleBlocks.contains(pos) && + mc.theWorld.getBlockState(above).getBlock().getRegistryName().equals("minecraft:air")) { + possibleBlocks.add(pos); + } + xOffset++; + } + } + } + sendMessage(); + } else if (possibleBlocks.size() != 1) { + locations.add(mc.thePlayer.getPosition()); + List<BlockPos> temp = new ArrayList<>(); + for (BlockPos pos : possibleBlocks) { + if (round(getPlayerPos().distanceTo(new Vec3(pos).addVector(0D,1D,0D)), 1) + == dist) { + temp.add(pos); + } + } + if (temp.size() == 0) { + for (BlockPos pos : possibleBlocks) { + if (inRange(getPlayerPos().distanceTo(new Vec3(pos).addVector(0D,1D,0D)), dist)) { + temp.add(pos); + } + } + } + possibleBlocks = temp; + sendMessage(); + } + } + prevPos = mc.thePlayer.getPosition(); + prevDist = dist; + } + } + + public static void reset() { + possibleBlocks.clear(); + locations.clear(); + } + + public static void render(float partialTicks) { + if (SBInfo.getInstance().getLocation() != null && SBInfo.getInstance().getLocation().equals("crystal_hollows")) { + if (possibleBlocks.size() == 1) { + RenderUtils.renderWayPoint("Treasure", possibleBlocks.get(0).add(0, 2.5, 0), partialTicks); + } else if (possibleBlocks.size() > 1 && NotEnoughUpdates.INSTANCE.config.mining.metalDetectorShowPossible) { + for (BlockPos block : possibleBlocks) { + RenderUtils.renderWayPoint("Possible Treasure Location", block.add(0, 2.5, 0), partialTicks); + } + } + } + } + + private static double round(double value, int precision) { + int scale = (int) Math.pow(10, precision); + return (double) Math.round(value * scale) / scale; + } + + private static boolean treasureAllowed(BlockPos pos) { + return mc.theWorld.getBlockState(pos).getBlock().getRegistryName().equals("minecraft:gold_block") || + mc.theWorld.getBlockState(pos).getBlock().getRegistryName().equals("minecraft:prismarine") || + mc.theWorld.getBlockState(pos).getBlock().getRegistryName().equals("minecraft:chest") || + mc.theWorld.getBlockState(pos).getBlock().getRegistryName().equals("minecraft:stained_glass") || + mc.theWorld.getBlockState(pos).getBlock().getRegistryName().equals("minecraft:stained_glass_pane") || + mc.theWorld.getBlockState(pos).getBlock().getRegistryName().equals("minecraft:wool") || + mc.theWorld.getBlockState(pos).getBlock().getRegistryName().equals("minecraft:stained_hardened_clay"); + } + + private static void sendMessage() { + if (possibleBlocks.size() > 1) { + mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "[NEU] Need another position to find solution. Possible blocks: " + + possibleBlocks.size())); + } else if (possibleBlocks.size() == 0) { + mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "[NEU] Failed to find solution.")); + reset(); + } else { + mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "[NEU] Found solution.")); + } + } + + + private static boolean inRange(double number, double dist) { + return dist + 0.1D >= number && dist - 0.1D <= number; + } + + private static Vec3 getPlayerPos() { + return new Vec3(mc.thePlayer.posX, mc.thePlayer.posY + (mc.thePlayer.getEyeHeight() - mc.thePlayer.getDefaultEyeHeight()), mc.thePlayer.posZ); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesWaypoints.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesWaypoints.java index 96f86c36..5c4fb61d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesWaypoints.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesWaypoints.java @@ -1,6 +1,7 @@ package io.github.moulberry.notenoughupdates.miscfeatures; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; import io.github.moulberry.notenoughupdates.options.NEUConfig; import io.github.moulberry.notenoughupdates.overlays.MiningOverlay; import io.github.moulberry.notenoughupdates.util.SBInfo; @@ -197,7 +198,7 @@ public class DwarvenMinesWaypoints { System.currentTimeMillis() - dynamicMillis < 30*1000) { for(Map.Entry<String, Vector3f> entry : waypointsMap.entrySet()) { if(entry.getKey().equals(dynamicLocation)) { - renderWayPoint(dynamicName, new Vector3f(entry.getValue()).translate(0, 15, 0), event.partialTicks); + RenderUtils.renderWayPoint(dynamicName, new Vector3f(entry.getValue()).translate(0, 15, 0), event.partialTicks); break; } } @@ -206,14 +207,14 @@ public class DwarvenMinesWaypoints { if(locWaypoint >= 1) { for(Map.Entry<String, Vector3f> entry : waypointsMap.entrySet()) { if(locWaypoint >= 2) { - renderWayPoint(EnumChatFormatting.AQUA+entry.getKey(), entry.getValue(), event.partialTicks); + RenderUtils.renderWayPoint(EnumChatFormatting.AQUA+entry.getKey(), entry.getValue(), event.partialTicks); } else { for(String commissionName : MiningOverlay.commissionProgress.keySet()) { if(commissionName.toLowerCase().contains(entry.getKey().toLowerCase())) { if(commissionName.contains("Titanium")) { - renderWayPoint(EnumChatFormatting.WHITE+entry.getKey(), entry.getValue(), event.partialTicks); + RenderUtils.renderWayPoint(EnumChatFormatting.WHITE+entry.getKey(), entry.getValue(), event.partialTicks); } else { - renderWayPoint(EnumChatFormatting.AQUA+entry.getKey(), entry.getValue(), event.partialTicks); + RenderUtils.renderWayPoint(EnumChatFormatting.AQUA+entry.getKey(), entry.getValue(), event.partialTicks); } } } @@ -247,7 +248,7 @@ public class DwarvenMinesWaypoints { double distSq = dX*dX + dY*dY + dZ*dZ; if(distSq >= 12*12) { - renderWayPoint(EnumChatFormatting.GOLD+emissary.name, + RenderUtils.renderWayPoint(EnumChatFormatting.GOLD+emissary.name, new Vector3f(emissary.loc).translate(0.5f, 2.488f, 0.5f), event.partialTicks); } @@ -258,81 +259,4 @@ public class DwarvenMinesWaypoints { } } - private void renderWayPoint(String str, Vector3f loc, float partialTicks) { - GlStateManager.alphaFunc(516, 0.1F); - - GlStateManager.pushMatrix(); - - Entity viewer = Minecraft.getMinecraft().getRenderViewEntity(); - double viewerX = viewer.lastTickPosX + (viewer.posX - viewer.lastTickPosX) * partialTicks; - double viewerY = viewer.lastTickPosY + (viewer.posY - viewer.lastTickPosY) * partialTicks; - double viewerZ = viewer.lastTickPosZ + (viewer.posZ - viewer.lastTickPosZ) * partialTicks; - - double x = loc.x-viewerX+0.5f; - double y = loc.y-viewerY-viewer.getEyeHeight(); - double z = loc.z-viewerZ+0.5f; - - double distSq = x*x + y*y + z*z; - double dist = Math.sqrt(distSq); - if(distSq > 144) { - x *= 12/dist; - y *= 12/dist; - z *= 12/dist; - } - GlStateManager.translate(x, y, z); - GlStateManager.translate(0, viewer.getEyeHeight(), 0); - - renderNametag(str); - - GlStateManager.rotate(-Minecraft.getMinecraft().getRenderManager().playerViewY, 0.0F, 1.0F, 0.0F); - GlStateManager.rotate(Minecraft.getMinecraft().getRenderManager().playerViewX, 1.0F, 0.0F, 0.0F); - GlStateManager.translate(0, -0.25f, 0); - GlStateManager.rotate(-Minecraft.getMinecraft().getRenderManager().playerViewX, 1.0F, 0.0F, 0.0F); - GlStateManager.rotate(Minecraft.getMinecraft().getRenderManager().playerViewY, 0.0F, 1.0F, 0.0F); - - renderNametag(EnumChatFormatting.YELLOW.toString()+Math.round(dist)+"m"); - - GlStateManager.popMatrix(); - - GlStateManager.disableLighting(); - } - - private void renderNametag(String str) { - FontRenderer fontrenderer = Minecraft.getMinecraft().fontRendererObj; - float f = 1.6F; - float f1 = 0.016666668F * f; - GlStateManager.pushMatrix(); - GL11.glNormal3f(0.0F, 1.0F, 0.0F); - GlStateManager.rotate(-Minecraft.getMinecraft().getRenderManager().playerViewY, 0.0F, 1.0F, 0.0F); - GlStateManager.rotate(Minecraft.getMinecraft().getRenderManager().playerViewX, 1.0F, 0.0F, 0.0F); - GlStateManager.scale(-f1, -f1, f1); - GlStateManager.disableLighting(); - GlStateManager.depthMask(false); - GlStateManager.disableDepth(); - GlStateManager.enableBlend(); - GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); - Tessellator tessellator = Tessellator.getInstance(); - WorldRenderer worldrenderer = tessellator.getWorldRenderer(); - int i = 0; - - int j = fontrenderer.getStringWidth(str) / 2; - GlStateManager.disableTexture2D(); - worldrenderer.begin(7, DefaultVertexFormats.POSITION_COLOR); - worldrenderer.pos((double)(-j - 1), (double)(-1 + i), 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex(); - worldrenderer.pos((double)(-j - 1), (double)(8 + i), 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex(); - worldrenderer.pos((double)(j + 1), (double)(8 + i), 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex(); - worldrenderer.pos((double)(j + 1), (double)(-1 + i), 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex(); - tessellator.draw(); - GlStateManager.enableTexture2D(); - fontrenderer.drawString(str, -fontrenderer.getStringWidth(str) / 2, i, 553648127); - GlStateManager.depthMask(true); - - fontrenderer.drawString(str, -fontrenderer.getStringWidth(str) / 2, i, -1); - - GlStateManager.enableDepth(); - GlStateManager.enableBlend(); - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - GlStateManager.popMatrix(); - } - } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java index 157da202..2c05b462 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java @@ -139,6 +139,32 @@ public class Mining { @ConfigAccordionId(id = 2)
public int overlayStyle = 0;
+ @ConfigOption(
+ name = "Metal Detector Solver",
+ desc = ""
+ )
+ @ConfigEditorAccordion(id = 3)
+ public boolean metalDetectorSolverAccordion = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Enabled",
+ desc = "Enabled the metal detector solver for Mines of Divan, to use this stand still to calculate possible blocks and then if required stand" +
+ " still on another block."
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 3)
+ public boolean metalDetectorEnabled = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Show Possible Blocks",
+ desc = "Show waypoints on possible locations when NEU isn't sure about what block the treasure is."
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 3)
+ public boolean metalDetectorShowPossible = false;
+
@Expose
@ConfigOption(
name = "Puzzler Solver",
|