aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCraftyOldMiner <85420839+CraftyOldMiner@users.noreply.github.com>2022-03-07 21:44:17 -0600
committerGitHub <noreply@github.com>2022-03-07 22:44:17 -0500
commit73fad7064fb47d9d79ccdb3bab5988df1b9eea6f (patch)
tree8b192d2304de3823339f238653e6d55dcfdfd04a /src
parent8b630cb7c39e73346d43b1e083b62b30fc3cde8f (diff)
downloadNotEnoughUpdates-73fad7064fb47d9d79ccdb3bab5988df1b9eea6f.tar.gz
NotEnoughUpdates-73fad7064fb47d9d79ccdb3bab5988df1b9eea6f.tar.bz2
NotEnoughUpdates-73fad7064fb47d9d79ccdb3bab5988df1b9eea6f.zip
Wishing Compass Solver, Metal Detector Solver improvements, add /neudiag, other misc changes (#90)
Diffstat (limited to 'src')
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java90
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/util/Line.java90
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java439
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java329
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinNetHandlerPlayClient.java5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java32
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/customtypes/NEUDebugFlag.java12
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java8
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/overlays/CrystalHollowOverlay.java54
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java167
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/NEUDebugLogger.java30
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java34
17 files changed, 1095 insertions, 204 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
index 5ad82d56..0ed68e06 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
@@ -25,6 +25,7 @@ import io.github.moulberry.notenoughupdates.listener.ItemTooltipListener;
import io.github.moulberry.notenoughupdates.listener.NEUEventListener;
import io.github.moulberry.notenoughupdates.listener.RenderListener;
import io.github.moulberry.notenoughupdates.miscfeatures.CrystalOverlay;
+import io.github.moulberry.notenoughupdates.miscfeatures.CrystalWishingCompassSolver;
import io.github.moulberry.notenoughupdates.miscfeatures.CustomItemEffects;
import io.github.moulberry.notenoughupdates.miscfeatures.DwarvenMinesWaypoints;
import io.github.moulberry.notenoughupdates.miscfeatures.EnchantingSolvers;
@@ -226,6 +227,7 @@ public class NotEnoughUpdates {
MinecraftForge.EVENT_BUS.register(InventoryStorageSelector.getInstance());
MinecraftForge.EVENT_BUS.register(SlotLocking.getInstance());
MinecraftForge.EVENT_BUS.register(FishingHelper.getInstance());
+ MinecraftForge.EVENT_BUS.register(CrystalWishingCompassSolver.getInstance());
MinecraftForge.EVENT_BUS.register(new DwarvenMinesTextures());
MinecraftForge.EVENT_BUS.register(CustomBiomes.INSTANCE);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java
index de017cb5..5c2bf5c0 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java
@@ -40,6 +40,7 @@ public class Commands {
ClientCommandHandler.instance.registerCommand(new StatsCommand());
ClientCommandHandler.instance.registerCommand(new DevTestCommand());
ClientCommandHandler.instance.registerCommand(new NullzeeSphereCommand());
+ ClientCommandHandler.instance.registerCommand(new DiagCommand());
// Repo Commands
ClientCommandHandler.instance.registerCommand(new ResetRepoCommand());
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java
index 7caf09cb..53a7894b 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java
@@ -24,7 +24,7 @@ import java.util.List;
public class DevTestCommand extends ClientCommandBase {
private static final List<String> DEV_TESTERS =
- Arrays.asList("moulberry", "lucycoconut", "ironm00n", "ariyio", "throwpo", "lrg89", "dediamondpro", "lulonaut");
+ Arrays.asList("moulberry", "lucycoconut", "ironm00n", "ariyio", "throwpo", "lrg89", "dediamondpro", "lulonaut", "craftyoldminer");
private static final String[] DEV_FAIL_STRINGS = {
"No.",
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java
new file mode 100644
index 00000000..88264538
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java
@@ -0,0 +1,90 @@
+package io.github.moulberry.notenoughupdates.commands.dev;
+
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.commands.ClientCommandBase;
+import io.github.moulberry.notenoughupdates.miscfeatures.CrystalMetalDetectorSolver;
+import io.github.moulberry.notenoughupdates.miscfeatures.CrystalWishingCompassSolver;
+import io.github.moulberry.notenoughupdates.options.customtypes.NEUDebugFlag;
+import net.minecraft.command.CommandException;
+import net.minecraft.command.ICommandSender;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.EnumChatFormatting;
+
+public class DiagCommand extends ClientCommandBase {
+ public DiagCommand() {
+ super("neudiag");
+ }
+
+ private static final String USAGE_TEXT = EnumChatFormatting.WHITE +
+ "Usage: /neudiag <metal | wishing | debug>\n\n" +
+ "/neudiag metal Metal Detector Solver diagnostics\n" +
+ "/neudiag wishing Wishing Compass Solver diagnostics\n" +
+ "/neudiag debug\n" +
+ " <no sub-command> Show current flags\n" +
+ " <enable | disable> <flag> Enable/disable flag\n";
+
+ private void showUsage(ICommandSender sender) {
+ sender.addChatMessage(new ChatComponentText(USAGE_TEXT));
+ }
+
+ @Override
+ public void processCommand(ICommandSender sender, String[] args) throws CommandException {
+ if (args.length == 0) {
+ showUsage(sender);
+ return;
+ }
+
+ String command = args[0].toLowerCase();
+ switch (command) {
+ case "metal":
+ CrystalMetalDetectorSolver.logDiagnosticData(true);
+ break;
+ case "wishing":
+ CrystalWishingCompassSolver.getInstance().logDiagnosticData(true);
+ break;
+ case "debug":
+ if (args.length > 1) {
+ boolean enablingFlag = true;
+ String action = args[1];
+ switch (action) {
+ case "disable":
+ enablingFlag = false;
+ // falls through
+ case "enable":
+ if (args.length != 3) {
+ sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
+ "You must specify a flag:\n" +
+ NEUDebugFlag.FLAG_LIST));
+ return;
+ }
+
+ String flagName = args[2].toUpperCase();
+ try {
+ NEUDebugFlag debugFlag = NEUDebugFlag.valueOf(flagName);
+ if (enablingFlag) {
+ NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.add(debugFlag);
+ } else {
+ NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.remove(debugFlag);
+ }
+ } catch (IllegalArgumentException e) {
+ sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
+ flagName + " is invalid. Valid flags are:\n" +
+ NEUDebugFlag.FLAG_LIST));
+ return;
+ }
+ break;
+ default:
+ showUsage(sender);
+ return;
+ }
+ }
+
+ sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Effective debug flags: " +
+ NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.toString()));
+ break;
+ default:
+ showUsage(sender);
+ return;
+ }
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/Line.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/Line.java
new file mode 100644
index 00000000..fb134e85
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/Line.java
@@ -0,0 +1,90 @@
+package io.github.moulberry.notenoughupdates.core.util;
+
+import net.minecraft.util.Vec3;
+
+/**
+ * Represents a line using two points along the line or a segment with endpoints.
+ */
+public class Line {
+ private static final double DOUBLE_EPSILON = 4.94065645841247E-324;
+ public Vec3 point1;
+ public Vec3 point2;
+
+ public Line(Vec3 first, Vec3 second) {
+ point1 = first;
+ point2 = second;
+ }
+
+ public Vec3 getMidpoint() {
+ return new Vec3((point1.xCoord + point2.xCoord) / 2.0,
+ (point1.yCoord + point2.yCoord) / 2.0,
+ (point1.zCoord + point2.zCoord) / 2.0);
+ }
+
+ /**
+ * Calculates the intersection line segment between 2 lines
+ * Based on http://paulbourke.net/geometry/pointlineplane/calclineline.cs
+ *
+ * @return The intersection {@link Line} or {@code null} if no solution found
+ */
+ public Line getIntersectionLineSegment(Line other)
+ {
+ Vec3 p1 = this.point1;
+ Vec3 p2 = this.point2;
+ Vec3 p3 = other.point1;
+ Vec3 p4 = other.point2;
+ Vec3 p13 = p1.subtract(p3);
+ Vec3 p43 = p4.subtract(p3);
+
+ if (lengthSquared(p43) < DOUBLE_EPSILON) {
+ return null;
+ }
+
+ Vec3 p21 = p2.subtract(p1);
+ if (lengthSquared(p21) < DOUBLE_EPSILON) {
+ return null;
+ }
+
+ double d1343 = p13.xCoord * p43.xCoord + p13.yCoord * p43.yCoord + p13.zCoord * p43.zCoord;
+ double d4321 = p43.xCoord * p21.xCoord + p43.yCoord * p21.yCoord + p43.zCoord * p21.zCoord;
+ double d1321 = p13.xCoord * p21.xCoord + p13.yCoord * p21.yCoord + p13.zCoord * p21.zCoord;
+ double d4343 = p43.xCoord * p43.xCoord + p43.yCoord * p43.yCoord + p43.zCoord * p43.zCoord;
+ double d2121 = p21.xCoord * p21.xCoord + p21.yCoord * p21.yCoord + p21.zCoord * p21.zCoord;
+
+ double denom = d2121 * d4343 - d4321 * d4321;
+ if (Math.abs(denom) < DOUBLE_EPSILON) {
+ return null;
+ }
+ double numer = d1343 * d4321 - d1321 * d4343;
+
+ double mua = numer / denom;
+ double mub = (d1343 + d4321 * (mua)) / d4343;
+
+ Line resultSegment = new Line(
+ new Vec3 (
+ (float)(p1.xCoord + mua * p21.xCoord),
+ (float)(p1.yCoord + mua * p21.yCoord),
+ (float)(p1.zCoord + mua * p21.zCoord)),
+ new Vec3 (
+ (float)(p3.xCoord + mub * p43.xCoord),
+ (float)(p3.yCoord + mub * p43.yCoord),
+ (float)(p3.zCoord + mub * p43.zCoord)));
+
+ return resultSegment;
+ }
+
+ public Line getImmutable() {
+ return new Line(point1, point2);
+ }
+
+ private static double lengthSquared(Vec3 vec) {
+ return vec.dotProduct(vec);
+ }
+
+ public String toString() {
+ return String.format("point1 = %s, point2 = %s, midpoint = %s",
+ point1 == null ? "NULL" : point1.toString(),
+ point2 == null ? "NULL" : point2.toString(),
+ (point1 == null || point2 == null) ? "NULL" : getMidpoint());
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java
index 633cd80f..ebb537dc 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java
@@ -209,7 +209,7 @@ public class ChatListener {
}
if (unformatted.startsWith("You found ") && SBInfo.getInstance().getLocation() != null &&
SBInfo.getInstance().getLocation().equals("crystal_hollows")) {
- CrystalMetalDetectorSolver.reset(true);
+ CrystalMetalDetectorSolver.resetSolution(true);
}
if (unformatted.startsWith("[NPC] Keeper of ") | unformatted.startsWith("[NPC] Professor Robot: ") ||
unformatted.startsWith(" ") || unformatted.startsWith("✦") || unformatted.equals(
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java
index ffebdd6b..eeb80abd 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java
@@ -140,7 +140,7 @@ public class NEUEventListener {
@SubscribeEvent
public void onWorldLoad(WorldEvent.Unload event) {
NotEnoughUpdates.INSTANCE.saveConfig();
- CrystalMetalDetectorSolver.reset(false);
+ CrystalMetalDetectorSolver.initWorld();
}
@SubscribeEvent
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java
index 4586d190..27c334ad 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java
@@ -2,31 +2,119 @@ 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.customtypes.NEUDebugFlag;
+import io.github.moulberry.notenoughupdates.util.NEUDebugLogger;
import io.github.moulberry.notenoughupdates.util.SBInfo;
import net.minecraft.client.Minecraft;
-import net.minecraft.util.*;
+import net.minecraft.entity.item.EntityArmorStand;
+import net.minecraft.util.BlockPos;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.IChatComponent;
+import net.minecraft.util.Vec3;
+import net.minecraft.util.Vec3i;
-import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
+import java.util.stream.Collectors;
public class CrystalMetalDetectorSolver {
private static final Minecraft mc = Minecraft.getMinecraft();
+
private static BlockPos prevPlayerPos;
private static double prevDistToTreasure = 0;
- private static List<BlockPos> possibleBlocks = new ArrayList<>();
- private static final List<BlockPos> locations = new ArrayList<>();
-
+ private static HashSet<BlockPos> possibleBlocks = new HashSet<>();
+ private static final HashMap<BlockPos, Double> evaluatedPlayerPositions = new HashMap<>();
+ private static BlockPos blockPosIfLastSolutionInvalid;
private static Boolean chestRecentlyFound = false;
private static long chestLastFoundMillis = 0;
+ private static final HashSet<BlockPos> openedChestPositions = new HashSet<>();
+
+ // Keeper and Mines of Divan center location info
+ private static Vec3i minesCenter;
+ private static boolean visitKeeperMessagePrinted = false;
+ private static String KEEPER_OF_STRING = "Keeper of ";
+ private static String DIAMOND_STRING = "diamond";
+ private static String LAPIS_STRING = "lapis";
+ private static String EMERALD_STRING = "emerald";
+ private static String GOLD_STRING = "gold";
+ private static final HashMap<String, Vec3i> keeperOffsets = new HashMap<String, Vec3i>() {{
+ put(DIAMOND_STRING, new Vec3i(33,0,3));
+ put(LAPIS_STRING, new Vec3i(-33,0,-3));
+ put(EMERALD_STRING, new Vec3i(-3,0,33));
+ put(GOLD_STRING, new Vec3i(3,0,-33));
+ }};
+
+ // Chest offsets from center
+ private static final HashSet<Long> knownChestOffsets = new HashSet<>(Arrays.asList(
+ -10171958951910L, // x=-38, y=-22, z=26
+ 10718829084646L, // x=38, y=-22, z=-26
+ -10721714765806L, // x=-40, y=-22, z=18
+ -10996458455018L, // x=-41, y=-20, z=22
+ -1100920913904L, // x=-5, y=-21, z=16
+ 11268584898530L, // x=40, y=-22, z=-30
+ -11271269253148L, // x=-42, y=-20, z=-28
+ -11546281377832L, // x=-43, y=-22, z=-40
+ 11818542038999L, // x=42, y=-19, z=-41
+ 12093285728240L, // x=43, y=-21, z=-16
+ -1409286164L, // x=-1, y=-22, z=-20
+ 1922736062492L, // x=6, y=-21, z=28
+ 2197613969419L, // x=7, y=-21, z=11
+ 2197613969430L, // x=7, y=-21, z=22
+ -3024999153708L, // x=-12, y=-21, z=-44
+ 3571936395295L, // x=12, y=-22, z=31
+ 3572003504106L, // x=12, y=-22, z=-22
+ 3572003504135L, // x=12, y=-21, z=7
+ 3572070612949L, // x=12, y=-21, z=-43
+ -3574822076373L, // x=-14, y=-21, z=43
+ -3574822076394L, // x=-14, y=-21, z=22
+ -4399455797228L, // x=-17, y=-21, z=20
+ -5224156626944L, // x=-20, y=-22, z=0
+ 548346527764L, // x=1, y=-21, z=20
+ 5496081743901L, // x=19, y=-22, z=29
+ 5770959650816L, // x=20, y=-22, z=0
+ 5771093868518L, // x=20, y=-21, z=-26
+ -6048790347736L, // x=-23, y=-22, z=40
+ 6320849682418L, // x=22, y=-21, z=-14
+ -6323668254708L, // x=-24, y=-22, z=12
+ 6595593371674L, // x=23, y=-22, z=26
+ 6595660480473L, // x=23, y=-22, z=-39
+ 6870471278619L, // x=24, y=-22, z=27
+ 7145349185553L, // x=25, y=-22, z=17
+ 8244995030996L, // x=29, y=-21, z=-44
+ -8247679385612L, // x=-31, y=-21, z=-12
+ -8247679385640L, // x=-31, y=-21, z=-40
+ 8519872937959L, // x=30, y=-21, z=-25
+ -8522557292584L, // x=-32, y=-21, z=-40
+ -9622068920278L, // x=-36, y=-20, z=42
+ -9896946827278L, // x=-37, y=-21, z=-14
+ -9896946827286L // x=-37, y=-21, z=-22
+ ));
public static void process(IChatComponent message) {
+ if (SBInfo.getInstance().getLocation() == null ||
+ !NotEnoughUpdates.INSTANCE.config.mining.metalDetectorEnabled ||
+ !SBInfo.getInstance().getLocation().equals("crystal_hollows") ||
+ !message.getUnformattedText().contains("TREASURE: ")) {
+ return;
+ }
+
+ locateMinesCenterIfNeeded();
+
+ double distToTreasure = Double.parseDouble(message
+ .getUnformattedText()
+ .split("TREASURE: ")[1].split("m")[0].replaceAll("(?!\\.)\\D", ""));
+
// Delay to keep old chest location from being treated as the new chest location
if (chestRecentlyFound) {
long currentTimeMillis = System.currentTimeMillis();
if (chestLastFoundMillis == 0) {
chestLastFoundMillis = currentTimeMillis;
return;
- } else if (currentTimeMillis - chestLastFoundMillis < 1000) {
+ } else if (currentTimeMillis - chestLastFoundMillis < 1000 && distToTreasure < 5.0) {
return;
}
@@ -34,80 +122,239 @@ public class CrystalMetalDetectorSolver {
chestRecentlyFound = false;
}
- if (SBInfo.getInstance().getLocation() != null && SBInfo.getInstance().getLocation().equals("crystal_hollows")
- && message.getUnformattedText().contains("TREASURE: ")) {
- double distToTreasure = Double.parseDouble(message
- .getUnformattedText()
- .split("TREASURE: ")[1].split("m")[0].replaceAll("(?!\\.)\\D", ""));
- if (NotEnoughUpdates.INSTANCE.config.mining.metalDetectorEnabled && prevDistToTreasure == distToTreasure &&
- prevPlayerPos.getX() == mc.thePlayer.getPosition().getX() &&
- prevPlayerPos.getY() == mc.thePlayer.getPosition().getY() &&
- prevPlayerPos.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(-distToTreasure); zOffset <= Math.ceil(distToTreasure); zOffset++) {
- for (int y = 65; y <= 75; y++) {
- double calculatedDist = 0;
- int xOffset = 0;
- while (calculatedDist < distToTreasure) {
- BlockPos pos = new BlockPos(Math.floor(mc.thePlayer.posX) + xOffset,
- y, Math.floor(mc.thePlayer.posZ) + zOffset
- );
- calculatedDist = getPlayerPos().distanceTo(new Vec3(pos).addVector(0D, 1D, 0D));
- if (round(calculatedDist, 1) == distToTreasure && !possibleBlocks.contains(pos) &&
- treasureAllowed(pos) && mc.theWorld.
- getBlockState(pos.add(0, 1, 0)).getBlock().getRegistryName().equals("minecraft:air")) {
- possibleBlocks.add(pos);
- }
- xOffset++;
- }
- xOffset = 0;
- calculatedDist = 0;
- while (calculatedDist < distToTreasure) {
- BlockPos pos = new BlockPos(Math.floor(mc.thePlayer.posX) - xOffset,
- y, Math.floor(mc.thePlayer.posZ) + zOffset
- );
- calculatedDist = getPlayerPos().distanceTo(new Vec3(pos).addVector(0D, 1D, 0D));
- if (round(calculatedDist, 1) == distToTreasure && !possibleBlocks.contains(pos) &&
- treasureAllowed(pos) && mc.theWorld.
- getBlockState(pos.add(0, 1, 0)).getBlock().getRegistryName().equals("minecraft:air")) {
- possibleBlocks.add(pos);
- }
- xOffset++;
+ if (prevDistToTreasure == distToTreasure &&
+ prevPlayerPos.equals(mc.thePlayer.getPosition()) &&
+ !evaluatedPlayerPositions.keySet().contains(mc.thePlayer.getPosition())) {
+ if (possibleBlocks.size() == 0) {
+ evaluatedPlayerPositions.put(mc.thePlayer.getPosition(), distToTreasure);
+ for (int zOffset = (int) Math.floor(-distToTreasure); zOffset <= Math.ceil(distToTreasure); zOffset++) {
+ for (int y = 65; y <= 75; y++) {
+ double calculatedDist = 0;
+ int xOffset = 0;
+ while (calculatedDist < distToTreasure) {
+ BlockPos pos = new BlockPos(Math.floor(mc.thePlayer.posX) + xOffset,
+ y, Math.floor(mc.thePlayer.posZ) + zOffset);
+ calculatedDist = getPlayerPos().distanceTo(new Vec3(pos).addVector(0D, 1D, 0D));
+ if (round(calculatedDist, 1) == distToTreasure && treasureAllowed(pos)) {
+ 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) == distToTreasure) {
- temp.add(pos);
+ xOffset = 0;
+ calculatedDist = 0;
+ while (calculatedDist < distToTreasure) {
+ BlockPos pos = new BlockPos(Math.floor(mc.thePlayer.posX) - xOffset,
+ y, Math.floor(mc.thePlayer.posZ) + zOffset);
+ calculatedDist = getPlayerPos().distanceTo(new Vec3(pos).addVector(0D, 1D, 0D));
+ if (round(calculatedDist, 1) == distToTreasure && treasureAllowed(pos)) {
+ possibleBlocks.add(pos);
+ }
+ xOffset++;
}
}
- possibleBlocks = temp;
- sendMessage();
- } else {
- BlockPos pos = possibleBlocks.get(0);
- if (Math.abs(distToTreasure - (getPlayerPos().distanceTo(new Vec3(pos)))) > 5) {
- mc.thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.RED + "[NEU] Previous solution is invalid."));
- reset(false);
+ }
+
+ checkAndDisplaySolutionState();
+ } else if (possibleBlocks.size() != 1) {
+ evaluatedPlayerPositions.put(mc.thePlayer.getPosition().getImmutable(), distToTreasure);
+ HashSet<BlockPos> temp = new HashSet<>();
+ for (BlockPos pos : possibleBlocks) {
+ if (round(getPlayerPos().distanceTo(new Vec3(pos).addVector(0D, 1D, 0D)), 1) == distToTreasure) {
+ temp.add(pos);
}
}
+ possibleBlocks = temp;
+ checkAndDisplaySolutionState();
+ } else {
+ BlockPos pos = possibleBlocks.iterator().next();
+ if (Math.abs(distToTreasure - (getPlayerPos().distanceTo(new Vec3(pos)))) > 5) {
+ mc.thePlayer.addChatMessage(new ChatComponentText(
+ EnumChatFormatting.RED + "[NEU] Previous solution is invalid."));
+ blockPosIfLastSolutionInvalid = pos.getImmutable();
+ logDiagnosticData(false);
+ resetSolution(false);
+ }
}
+ }
+
+ prevPlayerPos = mc.thePlayer.getPosition().getImmutable();
+ prevDistToTreasure = distToTreasure;
+ }
+
+ private static void checkForSingleKnownLocationMatch() {
+ if (minesCenter == BlockPos.NULL_VECTOR || possibleBlocks.size() < 2) {
+ return;
+ }
- prevPlayerPos = mc.thePlayer.getPosition();
- prevDistToTreasure = distToTreasure;
+ HashSet<BlockPos> temp = possibleBlocks.stream()
+ .filter(block -> knownChestOffsets.contains(block.subtract(minesCenter).toLong()))
+ .collect(Collectors.toCollection(HashSet::new));
+ if (temp.size() == 1) {
+ possibleBlocks = temp;
+ NEUDebugLogger.log(NEUDebugFlag.METAL, "Known location identified.");
+ } else if (temp.size() > 1) {
+ NEUDebugLogger.log(NEUDebugFlag.METAL, temp.size() + " known locations identified:");
}
}
- public static void reset(Boolean chestFound) {
+ private static String getFriendlyBlockPositions(Collection<BlockPos> positions) {
+ if (!NEUDebugLogger.isFlagEnabled(NEUDebugFlag.METAL) || positions.size() == 0) {
+ return "";
+ }
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("\n");
+ for (BlockPos blockPos : positions) {
+ sb.append("Absolute: " + blockPos.toString());
+ if (minesCenter != Vec3i.NULL_VECTOR) {
+ BlockPos relativeOffset = blockPos.subtract(minesCenter);
+ sb.append(", Relative: " + relativeOffset.toString() + " (" + relativeOffset.toLong() + ")");
+ }
+ sb.append("\n");
+ }
+
+ return sb.toString();
+ }
+
+ private static String getFriendlyEvaluatedPositions(HashMap<BlockPos, Double> positions) {
+ if (!NEUDebugLogger.isFlagEnabled(NEUDebugFlag.METAL) || positions.size() == 0) {
+ return "";
+ }
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("\n");
+ for (BlockPos blockPos : positions.keySet()) {
+ sb.append("Absolute: " + blockPos.toString());
+ if (minesCenter != Vec3i.NULL_VECTOR) {
+ BlockPos relativeOffset = blockPos.subtract(minesCenter);
+ sb.append(", Relative: " + relativeOffset.toString() + " (" + relativeOffset.toLong() + ")");
+ }
+
+ sb.append(" Distance: ");
+ sb.append(positions.get(blockPos));
+
+ sb.append("\n");
+ }
+
+ return sb.toString();
+ }
+
+ public static void logDiagnosticData(boolean outputAlways) {
+ if (SBInfo.getInstance().getLocation() == null) {
+ mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
+ "[NEU] This command is not available outside SkyBlock"));
+ return;
+ }
+
+ if (!NotEnoughUpdates.INSTANCE.config.mining.metalDetectorEnabled)
+ {
+ mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
+ "[NEU] Metal Detector Solver is not enabled."));
+ return;
+ }
+
+ if (!outputAlways && !NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.contains(NEUDebugFlag.METAL)) {
+ return;
+ }
+
+ boolean originalDebugFlag = !NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.add(NEUDebugFlag.METAL);
+
+ StringBuilder diagsMessage = new StringBuilder();
+
+ diagsMessage.append(EnumChatFormatting.AQUA);
+ diagsMessage.append("Mines Center: ");
+ diagsMessage.append(EnumChatFormatting.WHITE);
+ diagsMessage.append((minesCenter == Vec3i.NULL_VECTOR) ? "<NOT DISCOVERED>" : minesCenter.toString());
+ diagsMessage.append("\n");
+
+ diagsMessage.append("\n");
+ diagsMessage.append(EnumChatFormatting.AQUA);
+ diagsMessage.append("Previous Player Position: ");
+ diagsMessage.append(EnumChatFormatting.WHITE);
+ diagsMessage.append((prevPlayerPos == null) ? "<NONE>" : prevPlayerPos.toString());
+ diagsMessage.append("\n");
+
+ diagsMessage.append(EnumChatFormatting.AQUA);
+ diagsMessage.append("Previous Distance To Treasure: ");
+ diagsMessage.append(EnumChatFormatting.WHITE);
+ diagsMessage.append((prevDistToTreasure == 0) ? "<NONE>" : prevDistToTreasure);
+ diagsMessage.append("\n");
+
+ diagsMessage.append(EnumChatFormatting.AQUA);
+ diagsMessage.append("Last Solution Invalid Position: ");
+ diagsMessage.append(EnumChatFormatting.WHITE);
+ diagsMessage.append((blockPosIfLastSolutionInvalid == null) ? "<NONE>" : blockPosIfLastSolutionInvalid.toString());
+ diagsMessage.append("\n");
+
+ diagsMessage.append(EnumChatFormatting.AQUA);
+ diagsMessage.append("Current Possible Blocks: ");
+ diagsMessage.append(EnumChatFormatting.WHITE);
+ diagsMessage.append(possibleBlocks.size());
+ diagsMessage.append(getFriendlyBlockPositions(possibleBlocks));
+ diagsMessage.append("\n");
+
+ diagsMessage.append(EnumChatFormatting.AQUA);
+ diagsMessage.append("Evaluated player positions: ");
+ diagsMessage.append(EnumChatFormatting.WHITE);
+ diagsMessage.append(evaluatedPlayerPositions.size());
+ diagsMessage.append(getFriendlyEvaluatedPositions(evaluatedPlayerPositions));
+ diagsMessage.append("\n");
+
+ diagsMessage.append(EnumChatFormatting.AQUA);
+ diagsMessage.append("Chest locations not on known list:\n");
+ diagsMessage.append(EnumChatFormatting.WHITE);
+ if (minesCenter != Vec3i.NULL_VECTOR) {
+ HashSet<BlockPos> locationsNotOnKnownList = openedChestPositions
+ .stream()
+ .filter(block -> !knownChestOffsets.contains(block.subtract(minesCenter).toLong()))
+ .map(block -> block.subtract(minesCenter))
+ .collect(Collectors.toCollection(HashSet::new));
+ if (locationsNotOnKnownList.size() > 0) {
+ for (BlockPos blockPos : locationsNotOnKnownList) {
+ diagsMessage.append(String.format(
+ "%dL,\t\t// x=%d, y=%d, z=%d",
+ blockPos.toLong(),
+ blockPos.getX(),
+ blockPos.getY(),
+ blockPos.getZ()
+ ));
+ }
+ }
+ } else {
+ diagsMessage.append("<REQUIRES MINES CENTER>");
+ }
+
+ NEUDebugLogger.log(NEUDebugFlag.METAL, diagsMessage.toString());
+
+ if (!originalDebugFlag) {
+ NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.remove(NEUDebugFlag.METAL);
+ }
+ }
+
+ public static void resetSolution(Boolean chestFound) {
+ if (chestFound) {
+ blockPosIfLastSolutionInvalid = null;
+ prevPlayerPos = null;
+ prevDistToTreasure = 0;
+ if (possibleBlocks.size() == 1) {
+ openedChestPositions.add(possibleBlocks.iterator().next().getImmutable());<