aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java148
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java27
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorDraggableList.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDraggableList.java16
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/util/Vec3Comparable.java129
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionBINWarning.java30
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java450
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java942
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java54
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ProfileViewer.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BingoPage.java16
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java82
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/NEUDebugLogger.java10
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java14
-rw-r--r--src/test/java/io/github/moulberry/notenoughupdates/core/util/Vec3ComparableTest.java193
-rw-r--r--src/test/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolverTest.java204
-rw-r--r--src/test/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolverTest.java1206
-rw-r--r--src/test/resources/log4j2-test.xml16
20 files changed, 522 insertions, 3022 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
index 951e7335..0ed68e06 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
@@ -1,5 +1,17 @@
package io.github.moulberry.notenoughupdates;
+import java.awt.Color;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Set;
+
import com.google.common.collect.Sets;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@@ -12,9 +24,22 @@ import io.github.moulberry.notenoughupdates.listener.ChatListener;
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.*;
+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;
+import io.github.moulberry.notenoughupdates.miscfeatures.FairySouls;
+import io.github.moulberry.notenoughupdates.miscfeatures.FishingHelper;
+import io.github.moulberry.notenoughupdates.miscfeatures.ItemCooldowns;
+import io.github.moulberry.notenoughupdates.miscfeatures.ItemCustomizeManager;
+import io.github.moulberry.notenoughupdates.miscfeatures.MiningStuff;
+import io.github.moulberry.notenoughupdates.miscfeatures.NullzeeSphere;
+import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay;
+import io.github.moulberry.notenoughupdates.miscfeatures.SlotLocking;
+import io.github.moulberry.notenoughupdates.miscfeatures.StorageManager;
+import io.github.moulberry.notenoughupdates.miscfeatures.SunTzu;
import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBiomes;
-import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBlockSounds;
import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.DwarvenMinesTextures;
import io.github.moulberry.notenoughupdates.miscgui.CalendarOverlay;
import io.github.moulberry.notenoughupdates.miscgui.InventoryStorageSelector;
@@ -28,14 +53,17 @@ import io.github.moulberry.notenoughupdates.util.Utils;
import io.github.moulberry.notenoughupdates.util.XPInformation;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
-import net.minecraft.client.resources.IReloadableResourceManager;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.event.ClickEvent;
import net.minecraft.scoreboard.ScoreObjective;
import net.minecraft.scoreboard.Scoreboard;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
-import net.minecraft.world.biome.*;
+import net.minecraft.world.biome.BiomeGenBase;
+import net.minecraft.world.biome.BiomeGenHell;
+import net.minecraft.world.biome.BiomeGenJungle;
+import net.minecraft.world.biome.BiomeGenMesa;
+import net.minecraft.world.biome.BiomeGenSnow;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.Mod;
@@ -44,12 +72,6 @@ import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
-import java.awt.*;
-import java.io.*;
-import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.Set;
-
@Mod(modid = NotEnoughUpdates.MODID, version = NotEnoughUpdates.VERSION, clientSideOnly = true)
public class NotEnoughUpdates {
public static final String MODID = "notenoughupdates";
@@ -57,6 +79,60 @@ public class NotEnoughUpdates {
public static final String PRE_VERSION = "0.0";
public static final int VERSION_ID = 20100;
public static final int PRE_VERSION_ID = 0;
+
+ public static NotEnoughUpdates INSTANCE = null;
+
+ public NEUManager manager;
+ public NEUOverlay overlay;
+ public NEUConfig config;
+
+ private File configFile;
+
+ public File getConfigFile() {
+ return this.configFile;
+ }
+
+ public void newConfigFile() {
+ this.configFile = new File(NotEnoughUpdates.INSTANCE.getNeuDir(), "configNew.json");
+ }
+
+ private static final long CHAT_MSG_COOLDOWN = 200;
+ private long lastChatMessage = 0;
+ private long secondLastChatMessage = 0;
+ private String currChatMessage = null;
+
+ //Stolen from Biscut and used for detecting whether in skyblock
+ private static final Set<String> SKYBLOCK_IN_ALL_LANGUAGES =
+ Sets.newHashSet("SKYBLOCK", "\u7A7A\u5C9B\u751F\u5B58", "\u7A7A\u5CF6\u751F\u5B58");
+
+ public GuiScreen openGui = null;
+ public long lastOpenedGui = 0;
+
+ public Commands commands;
+
+ public static HashMap<String, String> petRarityToColourMap = new HashMap<String, String>() {{
+ put("UNKNOWN", EnumChatFormatting.RED.toString());
+ put("COMMON", EnumChatFormatting.WHITE.toString());
+ put("UNCOMMON", EnumChatFormatting.GREEN.toString());
+ put("RARE", EnumChatFormatting.BLUE.toString());
+ put("EPIC", EnumChatFormatting.DARK_PURPLE.toString());
+ put("LEGENDARY", EnumChatFormatting.GOLD.toString());
+ put("MYTHIC", EnumChatFormatting.LIGHT_PURPLE.toString());
+ }};
+
+ public static ProfileViewer profileViewer;
+
+ public boolean packDevEnabled = false;
+
+ private final Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().create();
+ private File neuDir;
+
+ public File getNeuDir() {
+ return this.neuDir;
+ }
+
+ public Color[][] colourMap = null;
+
/**
* Registers the biomes for the crystal hollows here so optifine knows they exists
*/
@@ -90,48 +166,6 @@ public class NotEnoughUpdates {
.setBiomeName("NeuCrystalHollowsCrystalNucleus")
.setFillerBlockMetadata(5470985)
.setTemperatureRainfall(0.95F, 0.9F);
- private static final long CHAT_MSG_COOLDOWN = 200;
- //Stolen from Biscut and used for detecting whether in skyblock
- private static final Set<String> SKYBLOCK_IN_ALL_LANGUAGES =
- Sets.newHashSet("SKYBLOCK", "\u7A7A\u5C9B\u751F\u5B58", "\u7A7A\u5CF6\u751F\u5B58");
- public static NotEnoughUpdates INSTANCE = null;
- public static HashMap<String, String> petRarityToColourMap = new HashMap<String, String>() {{
- put("UNKNOWN", EnumChatFormatting.RED.toString());
- put("COMMON", EnumChatFormatting.WHITE.toString());
- put("UNCOMMON", EnumChatFormatting.GREEN.toString());
- put("RARE", EnumChatFormatting.BLUE.toString());
- put("EPIC", EnumChatFormatting.DARK_PURPLE.toString());
- put("LEGENDARY", EnumChatFormatting.GOLD.toString());
- put("MYTHIC", EnumChatFormatting.LIGHT_PURPLE.toString());
- }};
- public static ProfileViewer profileViewer;
- private final Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().create();
- public NEUManager manager;
- public NEUOverlay overlay;
- public NEUConfig config;
- public GuiScreen openGui = null;
- public long lastOpenedGui = 0;
- public Commands commands;
- public boolean packDevEnabled = false;
- public Color[][] colourMap = null;
- private File configFile;
- private long lastChatMessage = 0;
- private long secondLastChatMessage = 0;
- private String currChatMessage = null;
- private File neuDir;
- private boolean hasSkyblockScoreboard;
-
- public File getConfigFile() {
- return this.configFile;
- }
-
- public void newConfigFile() {
- this.configFile = new File(NotEnoughUpdates.INSTANCE.getNeuDir(), "configNew.json");
- }
-
- public File getNeuDir() {
- return this.neuDir;
- }
/**
* Instantiates NEUIo, NEUManager and NEUOverlay instances. Registers keybinds and adds a shutdown hook to clear tmp folder.
@@ -215,14 +249,6 @@ public class NotEnoughUpdates {
MinecraftForge.EVENT_BUS.register(new CrystalOverlay());
MinecraftForge.EVENT_BUS.register(new ItemCooldowns());
- if (Minecraft.getMinecraft().getResourceManager() instanceof IReloadableResourceManager) {
- IReloadableResourceManager manager = (IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager();
- manager.registerReloadListener(CustomSkulls.getInstance());
- manager.registerReloadListener(NPCRetexturing.getInstance());
- manager.registerReloadListener(new ItemCustomizeManager.ReloadListener());
- manager.registerReloadListener(new CustomBlockSounds.ReloaderListener());
- }
-
this.commands = new Commands();
BackgroundBlur.registerListener();
@@ -384,6 +410,8 @@ public class NotEnoughUpdates {
return hasSkyblockScoreboard();
}
+ private boolean hasSkyblockScoreboard;
+
public boolean hasSkyblockScoreboard() {
return hasSkyblockScoreboard;
}
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
index dab99698..88264538 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java
@@ -17,10 +17,8 @@ public class DiagCommand extends ClientCommandBase {
private static final String USAGE_TEXT = EnumChatFormatting.WHITE +
"Usage: /neudiag <metal | wishing | debug>\n\n" +
- "/neudiag metal Metal Detector Solver diagnostics\n" +
- " <no sub-command> Show current solution diags\n" +
- " center=<off | on> Disable / enable using center\n" +
- "/neudiag wishing Wishing Compass Solver diagnostics\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";
@@ -39,26 +37,7 @@ public class DiagCommand extends ClientCommandBase {
String command = args[0].toLowerCase();
switch (command) {
case "metal":
- if (args.length == 1) {
- CrystalMetalDetectorSolver.logDiagnosticData(true);
- return;
- }
-
- String subCommand = args[1].toLowerCase();
- if (subCommand.equals("center=off")) {
- CrystalMetalDetectorSolver.setDebugDoNotUseCenter(true);
- sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
- "Center coordinates-based solutions disabled"));
- }
- else if (subCommand.equals("center=on")) {
- CrystalMetalDetectorSolver.setDebugDoNotUseCenter(false);
- sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
- "Center coordinates-based solutions enabled"));
- } else {
- showUsage(sender);
- return;
- }
-
+ CrystalMetalDetectorSolver.logDiagnosticData(true);
break;
case "wishing":
CrystalWishingCompassSolver.getInstance().logDiagnosticData(true);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorDraggableList.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorDraggableList.java
index 5063d543..61e923f5 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorDraggableList.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorDraggableList.java
@@ -9,5 +9,5 @@ import java.lang.annotation.Target;
@Target(ElementType.FIELD)
public @interface ConfigEditorDraggableList {
String[] exampleText();
- boolean allowRemovingElements() default true;
+ boolean allowDeleting() default true;
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDraggableList.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDraggableList.java
index df373dbf..4dbde24b 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDraggableList.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDraggableList.java
@@ -24,7 +24,7 @@ public class GuiOptionEditorDraggableList extends GuiOptionEditor {
private static final ResourceLocation DELETE = new ResourceLocation("notenoughupdates:core/delete.png");
private final String[] exampleText;
- private final boolean allowRemovingElements;
+ private final boolean enableDeleting;
private final List<Integer> activeText;
private int currentDragging = -1;
private int dragStartIndex = -1;
@@ -39,11 +39,11 @@ public class GuiOptionEditorDraggableList extends GuiOptionEditor {
public GuiOptionEditorDraggableList(
ConfigProcessor.ProcessedOption option,
String[] exampleText,
- boolean allowRemovingElements
+ boolean disableDeleting
) {
super(option);
- this.allowRemovingElements = allowRemovingElements;
+ this.enableDeleting = disableDeleting;
this.exampleText = exampleText;
this.activeText = (List<Integer>) option.get();
}
@@ -84,7 +84,7 @@ public class GuiOptionEditorDraggableList extends GuiOptionEditor {
GlStateManager.color(1, greenBlue, greenBlue, 1);
}
- if (allowRemovingElements) {
+ if (enableDeleting) {
Minecraft.getMinecraft().getTextureManager().bindTexture(DELETE);
Utils.drawTexturedRect(x + width / 6 + 27, y + 45 - 7 - 13, 11, 14, GL11.GL_NEAREST);
}
@@ -215,7 +215,7 @@ public class GuiOptionEditorDraggableList extends GuiOptionEditor {
dragStartIndex >= 0 && Mouse.getEventButton() == 0 &&
mouseX >= x + width / 6 + 27 - 3 && mouseX <= x + width / 6 + 27 + 11 + 3 &&
mouseY >= y + 45 - 7 - 13 - 3 && mouseY <= y + 45 - 7 - 13 + 14 + 3) {
- if (allowRemovingElements) {
+ if (enableDeleting) {
activeText.remove(dragStartIndex);
}
currentDragging = -1;
@@ -226,13 +226,13 @@ public class GuiOptionEditorDraggableList extends GuiOptionEditor {
if (!Mouse.isButtonDown(0) || dropdownOpen) {
currentDragging = -1;
dragStartIndex = -1;
- if (trashHoverTime > 0 && allowRemovingElements) trashHoverTime = -System.currentTimeMillis();
+ if (trashHoverTime > 0 && enableDeleting) trashHoverTime = -System.currentTimeMillis();
} else if (currentDragging >= 0 &&
mouseX >= x + width / 6 + 27 - 3 && mouseX <= x + width / 6 + 27 + 11 + 3 &&
mouseY >= y + 45 - 7 - 13 - 3 && mouseY <= y + 45 - 7 - 13 + 14 + 3) {
- if (trashHoverTime < 0 && allowRemovingElements) trashHoverTime = System.currentTimeMillis();
+ if (trashHoverTime < 0 && enableDeleting) trashHoverTime = System.currentTimeMillis();
} else {
- if (trashHoverTime > 0 && allowRemovingElements) trashHoverTime = -System.currentTimeMillis();
+ if (trashHoverTime > 0 && enableDeleting) trashHoverTime = -System.currentTimeMillis();
}
if (Mouse.getEventButtonState()) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java
index 3eb8a2d1..0d06980a 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java
@@ -147,7 +147,7 @@ public class ConfigProcessor {
if (optionField.isAnnotationPresent(ConfigEditorDraggableList.class)) {
ConfigEditorDraggableList configEditorAnnotation =
optionField.getAnnotation(ConfigEditorDraggableList.class);
- editor = new GuiOptionEditorDraggableList(option, configEditorAnnotation.exampleText(), configEditorAnnotation.allowRemovingElements());
+ editor = new GuiOptionEditorDraggableList(option, configEditorAnnotation.exampleText(), configEditorAnnotation.allowDeleting());
}
}
if (optionType.isAssignableFrom(String.class)) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/Vec3Comparable.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/Vec3Comparable.java
deleted file mode 100644
index cd144c21..00000000
--- a/src/main/java/io/github/moulberry/notenoughupdates/core/util/Vec3Comparable.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package io.github.moulberry.notenoughupdates.core.util;
-
-import net.minecraft.util.BlockPos;
-import net.minecraft.util.Vec3;
-import net.minecraft.util.Vec3i;
-
-public class Vec3Comparable extends Vec3 implements Comparable<Vec3Comparable> {
- public static final Vec3Comparable NULL_VECTOR = new Vec3Comparable(0.0, 0.0, 0.0);
-
- public Vec3Comparable(double x, double y, double z) {
- super(x, y, z);
- }
-
- public Vec3Comparable(Vec3i sourceVec) {
- super(sourceVec);
- }
-
- public Vec3Comparable(Vec3 source) {
- super(source.xCoord, source.yCoord, source.zCoord);
- }
-
- public Vec3Comparable(BlockPos source) {
-
- super(source.getX(), source.getY(), source.getZ());
- }
-
- public Vec3Comparable(Vec3Comparable source) {
- super(source.xCoord, source.yCoord, source.zCoord);
- }
-
- @Override
- public Vec3Comparable subtractReverse(Vec3 vec) {
- return new Vec3Comparable(super.subtractReverse(vec));
- }
-
- @Override
- public Vec3Comparable normalize() {
- return new Vec3Comparable(super.normalize());
- }
-
- @Override
- public Vec3Comparable crossProduct(Vec3 vec) {
- return new Vec3Comparable(super.crossProduct(vec));
- }
-
- @Override
- public Vec3Comparable subtract(Vec3 vec) {
- return new Vec3Comparable(super.subtract(vec));
- }
-
- @Override
- public Vec3Comparable subtract(double x, double y, double z) {
- return new Vec3Comparable(super.subtract(x, y, z));
- }
-
- @Override
- public Vec3Comparable add(Vec3 other) {
- return new Vec3Comparable(super.add(other));
- }
-
- @Override
- public Vec3Comparable addVector(double x, double y, double z) {
- return new Vec3Comparable(super.addVector(x, y, z));
- }
-
- @Override
- public Vec3Comparable getIntermediateWithXValue(Vec3 vec, double x) {
- return new Vec3Comparable(super.getIntermediateWithXValue(vec, x));
- }
-
- @Override
- public Vec3Comparable getIntermediateWithYValue(Vec3 vec, double y) {
- return new Vec3Comparable(super.getIntermediateWithYValue(vec, y));
- }
-
- @Override
- public Vec3Comparable getIntermediateWithZValue(Vec3 vec, double z) {
- return new Vec3Comparable(super.getIntermediateWithZValue(vec, z));
- }
-
- @Override
- public Vec3Comparable rotatePitch(float pitch) {
- return new Vec3Comparable(super.rotatePitch(pitch));
- }
-
- @Override
- public Vec3Comparable rotateYaw(float yaw) {
- return new Vec3Comparable(super.rotateYaw(yaw));
- }
-
- @Override
- public boolean equals(Object other) {
- if (this == other) {
- return true;
- } else if (!(other instanceof Vec3Comparable)) {
- return false;
- } else {
- Vec3Comparable vec3c = (Vec3Comparable) other;
- return this.xCoord == vec3c.xCoord && this.yCoord == vec3c.yCoord && this.zCoord == vec3c.zCoord;
- }
- }
-
- @Override
- public int hashCode() {
- long bits = 1L;
- bits = 31L * bits + doubleToLongBits(xCoord);
- bits = 31L * bits + doubleToLongBits(yCoord);
- bits = 31L * bits + doubleToLongBits(zCoord);
- return (int) (bits ^ (bits >> 32));
- }
-
- public int compareTo(Vec3Comparable other) {
- return this.yCoord == other.yCoord ?
- (this.zCoord == other.zCoord ?
- (int)(this.xCoord - other.xCoord)
- : (int)(this.zCoord - other.zCoord))
- : (int)(this.yCoord - other.yCoord);
- }
-
- public boolean signumEquals(Vec3 other) {
- return Math.signum(xCoord) == Math.signum(other.xCoord) &&
- Math.signum(yCoord) == Math.signum(other.yCoord) &&
- Math.signum(zCoord) == Math.signum(other.zCoord);
- }
-
- private static long doubleToLongBits(double d) {
- return d == 0.0 ? 0L : Double.doubleToLongBits(d);
- }
-}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionBINWarning.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionBINWarning.java
index c7bcc0e1..a787ca99 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionBINWarning.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionBINWarning.java
@@ -37,7 +37,9 @@ public class AuctionBINWarning extends GuiElement {
private String sellingName;
private int sellingPrice;
private int lowestPrice;
+ private int buyPercentage;
private int sellStackAmount;
+ private boolean isALoss = true;
private boolean shouldPerformCheck() {
if (!NotEnoughUpdates.INSTANCE.config.ahTweaks.enableBINWarning ||
@@ -110,14 +112,13 @@ public class AuctionBINWarning extends GuiElement {
float undercutFactor = 1 - NotEnoughUpdates.INSTANCE.config.ahTweaks.warningThreshold / 100;
if (undercutFactor < 0) undercutFactor = 0;
if (undercutFactor > 1) undercutFactor = 1;
- float overcutFactor = 1 + NotEnoughUpdates.INSTANCE.config.ahTweaks.overcutWarningThreshold / 100;
+ float overcutFactor = 1 - NotEnoughUpdates.INSTANCE.config.ahTweaks.overcutWarningThreshold / 100;
if (overcutFactor < 0) overcutFactor = 0;
+ if (overcutFactor > 1) overcutFactor = 1;
- if (
- (sellingPrice > 0 && lowestPrice > 0 &&
- ((sellingPrice > sellStackAmount * lowestPrice * overcutFactor) ||
- sellingPrice < sellStackAmount * lowestPrice * undercutFactor))
- || lowestPrice == -1) {
+ if ((sellingPrice > 0 && lowestPrice > 0 && sellingPrice < sellStackAmount * lowestPrice * undercutFactor)
+ || (sellingPrice > 0 && lowestPrice > 0 && sellingPrice > sellStackAmount * lowestPrice * (overcutFactor + 1))
+ || lowestPrice == -1) {
showWarning = true;
return true;
} else {
@@ -180,9 +181,7 @@ public class AuctionBINWarning extends GuiElement {
width / 2, height / 2 - 45 + 25, false, 170, 0xffffffff
);
TextRenderUtils.drawStringCenteredScaledMaxWidth(
- (lowestPrice > 0
- ? "has a lowest BIN of \u00a76" + lowestPriceStr + "\u00a7r coins"
- : "\u00a7cWarning: No lowest BIN found!"),
+ (lowestPrice > 0 ? "has a lowest BIN of \u00a76" + lowestPriceStr + "\u00a7r coins" : "\u00a7cWarning: No lowest BIN found!"),
Minecraft.getMinecraft().fontRendererObj,
width / 2,
height / 2 - 45 + 34,
@@ -191,16 +190,16 @@ public class AuctionBINWarning extends GuiElement {
0xffa0a0a0
);
- boolean isALoss = false;
- int buyPercentage = 0;
if (sellingPrice > lowestPrice * sellStackAmount) {
- buyPercentage = sellingPrice * 100 / (lowestPrice * sellStackAmount) - 100;
+ buyPercentage = sellingPrice * 100 / (lowestPrice * sellStackAmount);
isALoss = false;
} else if (sellingPrice < lowestPrice * sellStackAmount) {
- buyPercentage = 100 - sellingPrice * 100 / (lowestPrice * sellStackAmount);
+ buyPercentage = 100 - sellingPrice * 100 / (lowestPrice * sellStackAmount);
+ if (buyPercentage <= 0) buyPercentage = 1;
isALoss = true;
}
+
TextRenderUtils.drawStringCenteredScaledMaxWidth(
"Continue selling it for",
Minecraft.getMinecraft().fontRendererObj,
@@ -211,10 +210,7 @@ public class AuctionBINWarning extends GuiElement {
0xffa0a0a0
);
TextRenderUtils.drawStringCenteredScaledMaxWidth(
- "\u00a76" + sellingPriceStr + "\u00a7r coins?" +
- ((lowestPrice > 0 && buyPercentage > 0)
- ? "(\u00a7" + (isALoss ? "c-" : "a+") + buyPercentage + "%\u00a7r)"
- : ""),
+ "\u00a76" + sellingPriceStr + "\u00a7r coins?" + (lowestPrice > 0 ? "(\u00a7" + (isALoss ? "c-" : "a+") + buyPercentage + "%\u00a7r)" : ""),
Minecraft.getMinecraft().fontRendererObj,
width / 2,
height / 2 - 45 + 59,
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 f43ebda2..27c334ad 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java
@@ -1,7 +1,6 @@
package io.github.moulberry.notenoughupdates.miscfeatures;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
-import io.github.moulberry.notenoughupdates.core.util.Vec3Comparable;
import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils;
import io.github.moulberry.notenoughupdates.options.customtypes.NEUDebugFlag;
import io.github.moulberry.notenoughupdates.util.NEUDebugLogger;
@@ -12,6 +11,7 @@ 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.Arrays;
@@ -22,35 +22,25 @@ import java.util.List;
import java.util.stream.Collectors;
public class CrystalMetalDetectorSolver {
- enum SolutionState {
- NOT_STARTED,
- MULTIPLE,
- MULTIPLE_KNOWN,
- FOUND,
- FOUND_KNOWN,
- FAILED,
- INVALID,
- }
-
private static final Minecraft mc = Minecraft.getMinecraft();
- private static Vec3Comparable prevPlayerPos;
- private static double prevDistToTreasure;
+ private static BlockPos prevPlayerPos;
+ private static double prevDistToTreasure = 0;
private static HashSet<BlockPos> possibleBlocks = new HashSet<>();
- private static final HashMap<Vec3Comparable, Double> evaluatedPlayerPositions = new HashMap<>();
- private static boolean chestRecentlyFound;
- private static long chestLastFoundMillis;
+ 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 debugDoNotUseCenter = false;
- private static boolean visitKeeperMessagePrinted;
- private static final String KEEPER_OF_STRING = "Keeper of ";
- private static final String DIAMOND_STRING = "diamond";
- private static final String LAPIS_STRING = "lapis";
- private static final String EMERALD_STRING = "emerald";
- private static final String GOLD_STRING = "gold";
+ 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));
@@ -104,14 +94,6 @@ public class CrystalMetalDetectorSolver {
-9896946827286L // x=-37, y=-21, z=-22
));
- static Predicate<BlockPos> treasureAllowedPredicate = CrystalMetalDetectorSolver::treasureAllowed;
- static SolutionState currentState = SolutionState.NOT_STARTED;
- static SolutionState previousState = SolutionState.NOT_STARTED;
-
- public interface Predicate<BlockPos> {
- boolean check(BlockPos blockPos);
- }
-
public static void process(IChatComponent message) {
if (SBInfo.getInstance().getLocation() == null ||
!NotEnoughUpdates.INSTANCE.config.mining.metalDetectorEnabled ||
@@ -120,7 +102,7 @@ public class CrystalMetalDetectorSolver {
return;
}
- boolean centerNewlyDiscovered = locateMinesCenterIfNeeded();
+ locateMinesCenterIfNeeded();
double distToTreasure = Double.parseDouble(message
.getUnformattedText()
@@ -140,64 +122,20 @@ public class CrystalMetalDetectorSolver {
chestRecentlyFound = false;
}
- SolutionState originalState = currentState;
- int originalCount = possibleBlocks.size();
- Vec3Comparable adjustedPlayerPos = getPlayerPosAdjustedForEyeHeight();
- findPossibleSolutions(distToTreasure, adjustedPlayerPos, centerNewlyDiscovered);
- if (currentState != originalState || originalCount != possibleBlocks.size()) {
- switch (currentState) {
- case FOUND_KNOWN:
- NEUDebugLogger.log(NEUDebugFlag.METAL, "Known location identified.");
- // falls through
- case FOUND:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "[NEU] Found solution."));
- if (NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.contains(NEUDebugFlag.METAL) &&
- (previousState == SolutionState.INVALID || previousState == SolutionState.FAILED)) {
- NEUDebugLogger.log(NEUDebugFlag.METAL,
- EnumChatFormatting.AQUA + "Solution coordinates: " +
- EnumChatFormatting.WHITE + possibleBlocks.iterator().next().toString());
- }
- break;
- case INVALID:
- mc.thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.RED + "[NEU] Previous solution is invalid."));
- logDiagnosticData(false);
- resetSolution(false);
- break;
- case FAILED:
- mc.thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.RED + "[NEU] Failed to find a solution."));
- logDiagnosticData(false);
- resetSolution(false);
- break;
- case MULTIPLE_KNOWN:
- NEUDebugLogger.log(NEUDebugFlag.METAL, "Multiple known locations identified:");
- // falls through
- case MULTIPLE:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
- "[NEU] Need another position to find solution. Possible blocks: " + possibleBlocks.size()));
- break;
- default:
- throw new IllegalStateException("Metal detector is in invalid state");
- }
- }
- }
-
- static void findPossibleSolutions(double distToTreasure, Vec3Comparable playerPos, boolean centerNewlyDiscovered) {
- if (prevDistToTreasure == distToTreasure && prevPlayerPos.equals(playerPos) &&
- !evaluatedPlayerPositions.containsKey(playerPos)) {
- evaluatedPlayerPositions.put(playerPos, distToTreasure);
+ 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(playerPos.xCoord) + xOffset,
- y, Math.floor(playerPos.zCoord) + zOffset
- );
- calculatedDist = playerPos.distanceTo(new Vec3Comparable(pos).addVector(0D, 1D, 0D));
- if (round(calculatedDist, 1) == distToTreasure && treasureAllowedPredicate.check(pos)) {
+ 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++;
@@ -205,11 +143,10 @@ public class CrystalMetalDetectorSolver {
xOffset = 0;
calculatedDist = 0;
while (calculatedDist < distToTreasure) {
- BlockPos pos = new BlockPos(Math.floor(playerPos.xCoord) - xOffset,
- y, Math.floor(playerPos.zCoord) + zOffset
- );
- calculatedDist = playerPos.distanceTo(new Vec3Comparable(pos).addVector(0D, 1D, 0D));
- if (round(calculatedDist, 1) == distToTreasure && treasureAllowedPredicate.check(pos)) {
+ 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++;
@@ -217,33 +154,48 @@ public class CrystalMetalDetectorSolver {
}
}
- updateSolutionState();
+ checkAndDisplaySolutionState();
} else if (possibleBlocks.size() != 1) {
+ evaluatedPlayerPositions.put(mc.thePlayer.getPosition().getImmutable(), distToTreasure);
HashSet<BlockPos> temp = new HashSet<>();
for (BlockPos pos : possibleBlocks) {
- if (round(playerPos.distanceTo(new Vec3Comparable(pos).addVector(0D, 1D, 0D)), 1) == distToTreasure) {
+ if (round(getPlayerPos().distanceTo(new Vec3(pos).addVector(0D, 1D, 0D)), 1) == distToTreasure) {
temp.add(pos);
}
}
possibleBlocks = temp;
- updateSolutionState();
+ checkAndDisplaySolutionState();
} else {
BlockPos pos = possibleBlocks.iterator().next();
- if (Math.abs(distToTreasure - (playerPos.distanceTo(new Vec3Comparable(pos)))) > 5) {
- currentState = SolutionState.INVALID;
+ 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);
}
}
- } else if (centerNewlyDiscovered && possibleBlocks.size() > 1) {
- updateSolutionState();
}
- prevPlayerPos = playerPos;
+ prevPlayerPos = mc.thePlayer.getPosition().getImmutable();
prevDistToTreasure = distToTreasure;
}
- public static void setDebugDoNotUseCenter(boolean val) {
- debugDoNotUseCenter = val;
+ private static void checkForSingleKnownLocationMatch() {
+ if (minesCenter == BlockPos.NULL_VECTOR || possibleBlocks.size() < 2) {
+ return;
+ }
+
+ 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:");
+ }
}
private static String getFriendlyBlockPositions(Collection<BlockPos> positions) {
@@ -254,13 +206,10 @@ public class CrystalMetalDetectorSolver {
StringBuilder sb = new StringBuilder();
sb.append("\n");
for (BlockPos blockPos : positions) {
- sb.append("Absolute: ");
- sb.append(blockPos.toString());
+ sb.append("Absolute: " + blockPos.toString());
if (minesCenter != Vec3i.NULL_VECTOR) {
BlockPos relativeOffset = blockPos.subtract(minesCenter);
- sb.append(", Relative: ");
- sb.append(relativeOffset.toString() );
- sb.append(" (" + relativeOffset.toLong() + ")");
+ sb.append(", Relative: " + relativeOffset.toString() + " (" + relativeOffset.toLong() + ")");
}
sb.append("\n");
}
@@ -268,23 +217,22 @@ public class CrystalMetalDetectorSolver {
return sb.toString();
}
- private static String getFriendlyEvaluatedPositions() {
- if (!NEUDebugLogger.isFlagEnabled(NEUDebugFlag.METAL) || evaluatedPlayerPositions.size() == 0) {
+ 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 (Vec3Comparable vec : evaluatedPlayerPositions.keySet()) {
- sb.append("Absolute: " + vec.toString());
+ for (BlockPos blockPos : positions.keySet()) {
+ sb.append("Absolute: " + blockPos.toString());
if (minesCenter != Vec3i.NULL_VECTOR) {
- BlockPos positionBlockPos = new BlockPos(vec);
- BlockPos relativeOffset = positionBlockPos.subtract(minesCenter);
+ BlockPos relativeOffset = blockPos.subtract(minesCenter);
sb.append(", Relative: " + relativeOffset.toString() + " (" + relativeOffset.toLong() + ")");
}
sb.append(" Distance: ");
- sb.append(evaluatedPlayerPositions.get(vec));
+ sb.append(positions.get(blockPos));
sb.append("\n");
}
@@ -292,8 +240,101 @@ public class CrystalMetalDetectorSolver {
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) {
@@ -304,18 +345,15 @@ public class CrystalMetalDetectorSolver {
chestRecentlyFound = chestFound;
possibleBlocks.clear();
evaluatedPlayerPositions.clear();
- previousState = currentState;
- currentState = SolutionState.NOT_STARTED;
}
public static void initWorld() {
minesCenter = Vec3i.NULL_VECTOR;
visitKeeperMessagePrinted = false;
+ blockPosIfLastSolutionInvalid = null;
openedChestPositions.clear();
- chestLastFoundMillis = 0;
prevDistToTreasure = 0;
prevPlayerPos = null;
- currentState = SolutionState.NOT_STARTED;
resetSolution(false);
}
@@ -339,14 +377,15 @@ public class CrystalMetalDetectorSolver {
}
}
- private static boolean locateMinesCenterIfNeeded() {
+ private static void locateMinesCenterIfNeeded() {
if (minesCenter != Vec3i.NULL_VECTOR) {
- return false;
+ return;
}
List<EntityArmorStand> keeperEntities = mc.theWorld.getEntities(EntityArmorStand.class, (entity) -> {
if (!entity.hasCustomName()) return false;
- return entity.getCustomNameTag().contains(KEEPER_OF_STRING);
+ if (entity.getCustomNameTag().contains(KEEPER_OF_STRING)) return true;
+ return false;
});
if (keeperEntities.size() == 0) {
@@ -355,7 +394,7 @@ public class CrystalMetalDetectorSolver {
"[NEU] Approach a Keeper while holding the metal detector to enable faster treasure hunting."));
visitKeeperMessagePrinted = true;
}
- return false;
+ return;
}
EntityArmorStand keeperEntity = keeperEntities.get(0);
@@ -368,11 +407,6 @@ public class CrystalMetalDetectorSolver {
EnumChatFormatting.WHITE + minesCenter.toString());
mc.thePlayer.addChatMessage(new ChatComponentText(
EnumChatFormatting.YELLOW + "[NEU] Faster treasure hunting is now enabled based on Keeper location."));
- return true;
- }
-
- public static void setMinesCenter(BlockPos center) {
- minesCenter = center;
}
private static double round(double value, int precision) {
@@ -380,174 +414,42 @@ public class CrystalMetalDetectorSolver {
return (double) Math.round(value * scale) / scale;
}
- private static void updateSolutionState() {
- previousState = currentState;
-
+ private static void checkAndDisplaySolutionState() {
if (possibleBlocks.size() == 0) {
- currentState = SolutionState.FAILED;
- return;
- }
-
- if (possibleBlocks.size() == 1) {
- currentState = SolutionState.FOUND;
+ mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "[NEU] Failed to find a solution."));
+ logDiagnosticData(false);
+ resetSolution(false);
return;
}
- // Narrow solutions using known locations if the mines center is known
- if (minesCenter.equals(BlockPos.NULL_VECTOR) || debugDoNotUseCenter) {
- currentState = SolutionState.MULTIPLE;
- return;
- }
-
- HashSet<BlockPos> temp =
- possibleBlocks.stream()
- .filter(block -> knownChestOffsets.contains(block.subtract(minesCenter).toLong()))
- .collect(Collectors.toCollection(HashSet::new));
- if (temp.size() == 0) {
- currentState = SolutionState.MULTIPLE;
- return;
- }
-
- if (temp.size() == 1) {
- possibleBlocks = temp;
- currentState = SolutionState.FOUND_KNOWN;
- return;
-
- }
-
- currentState = SolutionState.MULTIPLE_KNOWN;
- }
-
- public static BlockPos getSolution() {
- if (CrystalMetalDetectorSolver.possibleBlocks.size() != 1) {
- return BlockPos.ORIGIN;
+ checkForSingleKnownLocationMatch();
+ if (possibleBlocks.size() > 1) {
+ mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
+ "[NEU] Need another position to find solution. Possible blocks: " + possibleBlocks.size()));
+ } else {
+ mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "[NEU] Found solution."));
}
-
- return CrystalMetalDetectorSolver.possibleBlocks.stream().iterator().next();
}
- private static Vec3Comparable getPlayerPosAdjustedForEyeHeight() {
- return new Vec3Comparable(
+ private static Vec3 getPlayerPos() {
+ return new Vec3(
mc.thePlayer.posX,
mc.thePlayer.posY + (mc.thePlayer.getEyeHeight() - mc.thePlayer.getDefaultEyeHeight()),
mc.thePlayer.posZ
);
}
- static boolean isKnownOffset(BlockPos pos) {
- return knownChestOffsets.contains(pos.subtract(minesCenter).toLong());
- }
-
- static boolean isAllowedBlockType(BlockPos pos) {
- return mc.theWorld.getBlockState(pos).getBlock().getRegistryName().equals("minecraft:gold_block") ||
+ private static boolean treasureAllowed(BlockPos pos) {
+ boolean airAbove = mc.theWorld.
+ getBlockState(pos.add(0, 1, 0)).getBlock().getRegistryName().equals("minecraft:air");
+ boolean allowedBlockType = 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");
- }
-
- static boolean isAirAbove(BlockPos pos) {
- return mc.theWorld.
- getBlockState(pos.add(0, 1, 0)).getBlock().getRegistryName().equals("minecraft:air");
- }
-
- private static boolean treasureAllowed(BlockPos pos) {
- boolean airAbove = isAirAbove(pos);
- boolean allowedBlockType = isAllowedBlockType(pos);
- return isKnownOffset(pos) || (airAbove && allowedBlockType);
- }
-
- static private String getDiagnosticMessage() {
- StringBuilder diagsMessage = new StringBuilder();
-
- diagsMessage.append(EnumChatFormatting.AQUA);
- diagsMessage.append("Mines Center: ");
- diagsMessage.append(EnumChatFormatting.WHITE);
- diagsMessage.append((minesCenter.equals(Vec3i.NULL_VECTOR)) ? "<NOT DISCOVERED>" : minesCenter.toString());
- diagsMessage.append("\n");
-
- diagsMessage.append(EnumChatFormatting.AQUA);
- diagsMessage.append("Current Solution State: ");
- diagsMessage.append(EnumChatFormatting.WHITE);
- diagsMessage.append(currentState.name());
- diagsMessage.append("\n");
-
- diagsMessage.append(EnumChatFormatting.AQUA);
- diagsMessage.append("Previous Solution State: ");
- diagsMessage.append(EnumChatFormatting.WHITE);
- diagsMessage.append(previousState.name());
- 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("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());
- 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>");
- }
-
- return diagsMessage.toString();
- }
-
- public static void logDiagnosticData(boolean outputAlways) {
- if (!SBInfo.getInstance().checkForSkyblockLocation()) {
- return;
- }
-
- if (!NotEnoughUpdates.INSTANCE.config.mining.metalDetectorEnabled)
- {
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "[NEU] Metal Detector Solver is not enabled."));
- return;
- }
-
- boolean metalDebugFlagSet = NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.contains(NEUDebugFlag.METAL);
- if (outputAlways || metalDebugFlagSet) {
- NEUDebugLogger.logAlways(getDiagnosticMessage());
- }
+ boolean knownOffset = knownChestOffsets.contains(pos.subtract(minesCenter).toLong());
+ return airAbove & (knownOffset | allowedBlockType);
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java
index 9a950e7f..25f39c3a 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java
@@ -2,67 +2,27 @@ package io.github.moulberry.notenoughupdates.miscfeatures;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.core.util.Line;
-import io.github.moulberry.notenoughupdates.core.util.Vec3Comparable;
-import io.github.moulberry.notenoughupdates.options.NEUConfig;
import io.github.moulberry.notenoughupdates.options.customtypes.NEUDebugFlag;
import io.github.moulberry.notenoughupdates.util.NEUDebugLogger;
import io.github.moulberry.notenoughupdates.util.SBInfo;
-import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
import net.minecraft.event.ClickEvent;
+import net.minecraft.event.HoverEvent;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.BlockPos;
import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.ChatStyle;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.EnumParticleTypes;
-import net.minecraft.util.Vec3i;
-import net.minecraftforge.client.ClientCommandHandler;
+import net.minecraft.util.Vec3;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
-import java.util.ArrayList;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.function.BooleanSupplier;
-import java.util.function.LongSupplier;
-
public class CrystalWishingCompassSolver {
- enum SolverState {
- NOT_STARTED,
- PROCESSING_FIRST_USE,
- NEED_SECOND_COMPASS,
- PROCESSING_SECOND_USE,
- SOLVED,
- FAILED_EXCEPTION,
- FAILED_TIMEOUT_NO_REPEATING,
- FAILED_TIMEOUT_NO_PARTICLES,
- FAILED_INTERSECTION_CALCULATION,
- FAILED_INVALID_SOLUTION,
- }
-
- enum CompassTarget {
- GOBLIN_QUEEN,
- GOBLIN_KING,
- BAL,
- JUNGLE_TEMPLE,
- ODAWA,
- PRECURSOR_CITY,
- MINES_OF_DIVAN,
- CRYSTAL_NUCLEUS,
- }
-
- enum Crystal {
- AMBER,
- AMETHYST,
- JADE,
- SAPPHIRE,
- TOPAZ,
- }
-
private static final CrystalWishingCompassSolver INSTANCE = new CrystalWishingCompassSolver();
public static CrystalWishingCompassSolver getInstance() {
return INSTANCE;
@@ -71,72 +31,40 @@ public class CrystalWishingCompassSolver {
private static final Minecraft mc = Minecraft.getMinecraft();
private static boolean isSkytilsPresent = false;
- // NOTE: There is a small set of breakable blocks above the nucleus at Y > 181. While this zone is reported
- // as the Crystal Nucleus by Hypixel, for wishing compass purposes it is in the appropriate quadrant.
- private static final AxisAlignedBB NUCLEUS_BB = new AxisAlignedBB(462, 63, 461, 564, 181, 565);
- private static final AxisAlignedBB HOLLOWS_BB = new AxisAlignedBB(201, 30, 201, 824, 189, 824);
- private static final AxisAlignedBB PRECURSOR_REMNANTS_BB = new AxisAlignedBB(513, 64, 513, 824, 189, 824);
- private static final AxisAlignedBB MITHRIL_DEPOSITS_BB = new AxisAlignedBB(513, 64, 201, 824, 189, 512);
- private static final AxisAlignedBB GOBLIN_HOLDOUT_BB = new AxisAlignedBB(201, 64, 513, 512, 189, 824);
- private static final AxisAlignedBB JUNGLE_BB = new AxisAlignedBB(201, 64, 201, 512, 189, 512);
- private static final AxisAlignedBB MAGMA_FIELDS_BB = new AxisAlignedBB(201, 30, 201, 824, 63, 824);
- private static final double MAX_DISTANCE_BETWEEN_PARTICLES = 0.6;
- private static final double MAX_DISTANCE_FROM_USE_TO_FIRST_PARTICLE = 9.0;
-
- // 64.0 is an arbitrary value but seems to work well
- private static final double MINIMUM_DISTANCE_SQ_BETWEEN_COMPASSES = 64.0;
-
- // All particles typically arrive in < 3500, so 5000 should be enough buffer
- public static final long ALL_PARTICLES_MAX_MILLIS = 5000L;
-
- public LongSupplier currentTimeMillis = System::currentTimeMillis;
- public BooleanSupplier kingsScentPresent = this::isKingsScentPresent;
- public BooleanSupplier keyInInventory = this::isKeyInInventory;
- public interface CrystalEnumSetSupplier {
- EnumSet<Crystal> getAsCrystalEnumSet();
- }
- public CrystalEnumSetSupplier foundCrystals = this::getFoundCrystals;
-
- private SolverState solverState;
- private Compass firstCompass;
- private Compass secondCompass;
- private Line solutionIntersectionLine;
- private EnumSet<CompassTarget> possibleTargets;
- private Vec3Comparable solution;
- private Vec3Comparable originalSolution;
- private EnumSet<CompassTarget> solutionPossibleTargets;
-
- public SolverState getSolverState() {
- return solverState;
- }
-
- public Vec3i getSolutionCoords() {
- return new Vec3i(solution.xCoord, solution.yCoord, solution.zCoord);
- }
-
- public EnumSet<CompassTarget> getPossibleTargets() {
- return possibleTargets;
+ // Crystal Nucleus unbreakable blocks, area coordinates reported by Hypixel server are slightly different
+ private static final AxisAlignedBB NUCLEUS_BB = new AxisAlignedBB(463, 63, 460, 563, 181, 564);
+ private static final double MAX_COMPASS_PARTICLE_SPREAD = 16;
+
+ private static BlockPos prevPlayerPos;
+ private long compassUsedMillis = 0;
+ private Vec3 firstParticle = null;
+ private Vec3 lastParticle = null;
+ private double lastParticleDistanceFromFirst = 0;
+ private Line firstCompassLine = null;
+ private Line secondCompassLine = null;
+ private Vec3 solution = null;
+ private Line solutionIntersectionLine = null;
+
+ private void resetForNewCompass() {
+ compassUsedMillis = 0;
+ firstParticle = null;
+ lastParticle = null;
+ lastParticleDistanceFromFirst = 0;
}
private void resetForNewTarget() {
NEUDebugLogger.log(NEUDebugFlag.WISHING,"Resetting for new target");
- solverState = SolverState.NOT_STARTED;
- firstCompass = null;
- secondCompass = null;
+ resetForNewCompass();
+ firstCompassLine = null;
+ secondCompassLine = null;
solutionIntersectionLine = null;
- possibleTargets = null;
+ prevPlayerPos = null;
solution = null;
- originalSolution = null;
- solutionPossibleTargets = null;
- }
-
- public void initWorld() {
- resetForNewTarget();
}
@SubscribeEvent
public void onWorldLoad(WorldEvent.Unload event) {
- initWorld();
+ resetForNewTarget();
isSkytilsPresent = Loader.isModLoaded("skytils");
}
@@ -162,101 +90,28 @@ public class CrystalWishingCompassSolver {
return;
}
- BlockPos playerPos = mc.thePlayer.getPosition().getImmutable();
-
try {
- HandleCompassResult result = handleCompassUse(playerPos);
- switch (result) {
- case SUCCESS:
- return;
- case STILL_PROCESSING_PRIOR_USE:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
- "[NEU] Wait a little longer before using the wishing compass again."));
- event.setCanceled(true);
- break;
- case LOCATION_TOO_CLOSE:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
- "[NEU] Move a little further before using the wishing compass again."));
- event.setCanceled(true);
- break;
- case POSSIBLE_TARGETS_CHANGED:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
- "[NEU] Possible wishing compass targets have changed. Solver has been reset."));
- event.setCanceled(true);
- break;
- case NO_PARTICLES_FOR_PREVIOUS_COMPASS:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
- "[NEU] No particles detected for prior compass use. Need another position to solve."));
- break;
- case PLAYER_IN_NUCLEUS:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
- "[NEU] Wishing compass must be used outside the nucleus for accurate results."));
- event.setCanceled(true);
- break;
- default:
- throw new IllegalStateException("Unexpected wishing compass solver state: \n" + getDiagnosticMessage());
+ if (isSolved()) {
+ resetForNewTarget();
+ }
+
+ // 64.0 is an arbitrary value but seems to work well
+ if (prevPlayerPos != null && prevPlayerPos.distanceSq(mc.thePlayer.getPosition()) < 64.0) {
+ mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
+ "[NEU] Move a little further before using the wishing compass again."));
+ event.setCanceled(true);
+ return;
}
+
+ prevPlayerPos = mc.thePlayer.getPosition().getImmutable();
+ compassUsedMillis = System.currentTimeMillis();
} catch (Exception e) {
mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
"[NEU] Error processing wishing compass action - see log for details"));
e.printStackTrace();
- event.setCanceled(true);
- solverState = SolverState.FAILED_EXCEPTION;
}
}
- public HandleCompassResult handleCompassUse(BlockPos playerPos) {
- long lastCompassUsedMillis = 0;
- switch (solverState) {
- case PROCESSING_SECOND_USE:
- if (secondCompass != null) {
- lastCompassUsedMillis = secondCompass.whenUsedMillis;
- }
- case PROCESSING_FIRST_USE:
- if (lastCompassUsedMillis == 0 && firstCompass != null) {
- lastCompassUsedMillis = firstCompass.whenUsedMillis;
- }
- if (lastCompassUsedMillis != 0 &&
- (currentTimeMillis.getAsLong() > lastCompassUsedMillis + ALL_PARTICLES_MAX_MILLIS)) {
- return HandleCompassResult.NO_PARTICLES_FOR_PREVIOUS_COMPASS;
- }
-
- return HandleCompassResult.STILL_PROCESSING_PRIOR_USE;
- case SOLVED:
- case FAILED_EXCEPTION:
- case FAILED_TIMEOUT_NO_REPEATING:
- case FAILED_TIMEOUT_NO_PARTICLES:
- case FAILED_INTERSECTION_CALCULATION:
- case FAILED_INVALID_SOLUTION:
- resetForNewTarget();
- // falls through, NOT_STARTED is the state when resetForNewTarget returns
- case NOT_STARTED:
- if (NUCLEUS_BB.isVecInside(new Vec3Comparable(playerPos.getX(), playerPos.getY(), playerPos.getZ()))) {
- return HandleCompassResult.PLAYER_IN_NUCLEUS;
- }
-
- firstCompass = new Compass(playerPos, currentTimeMillis.getAsLong());
- solverState = SolverState.PROCESSING_FIRST_USE;
- possibleTargets = calculatePossibleTargets(playerPos);
- return HandleCompassResult.SUCCESS;
- case NEED_SECOND_COMPASS:
- if (firstCompass.whereUsed.distanceSq(playerPos) < MINIMUM_DISTANCE_SQ_BETWEEN_COMPASSES) {
- return HandleCompassResult.LOCATION_TOO_CLOSE;
- }
-
- if (!possibleTargets.equals(calculatePossibleTargets(playerPos))) {
- resetForNewTarget();
- return HandleCompassResult.POSSIBLE_TARGETS_CHANGED;
- }
-
- secondCompass = new Compass(playerPos, currentTimeMillis.getAsLong());
- solverState = SolverState.PROCESSING_SECOND_USE;
- return HandleCompassResult.SUCCESS;
- }
-
- throw new IllegalStateException("Unexpected compass state" );
- }
-
/*
* Processes particles if the wishing compass was used within the last 5 seconds.
*
@@ -287,701 +142,188 @@ public class CrystalWishingCompassSolver {
) {
if (!NotEnoughUpdates.INSTANCE.config.mining.wishingCompassSolver ||
particleType != EnumParticleTypes.VILLAGER_HAPPY ||
- !SBInfo.getInstance().getLocation().equals("crystal_hollows")) {
+ !SBInfo.getInstance().getLocation().equals("crystal_hollows") ||
+ isSolved() ||
+ System.currentTimeMillis() - compassUsedMillis > 5000) {
return;
}
try {
- SolverState originalSolverState = solverState;
- solveUsingParticle(x, y, z, currentTimeMillis.getAsLong());
- if (solverState != originalSolverState) {
- switch (solverState) {
- case SOLVED:
- showSolution();
- break;
- case FAILED_EXCEPTION:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "[NEU] Unable to determine wishing compass target."));
- logDiagnosticData(false);
- break;
- case FAILED_TIMEOUT_NO_REPEATING:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "[NEU] Timed out waiting for repeat set of compass particles."));
- logDiagnosticData(false);
- break;
- case FAILED_TIMEOUT_NO_PARTICLES:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "[NEU] Timed out waiting for compass particles."));
- logDiagnosticData(false);
- break;
- case FAILED_INTERSECTION_CALCULATION:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "[NEU] Unable to determine intersection of wishing compasses."));
- logDiagnosticData(false);
- break;
- case FAILED_INVALID_SOLUTION:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "[NEU] Failed to find solution."));
- logDiagnosticData(false);
- break;
- case NEED_SECOND_COMPASS:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
- "[NEU] Need another position to determine wishing compass target."));
- break;
- }
- }
- } catch (Exception e) {
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "[NEU] Exception while calculating wishing compass solution - see log for details"));
- e.printStackTrace();
- }
- }
-
- /**
- *
- * @param x Particle x coordinate
- * @param y Particle y coordinate
- * @param z Particle z coordinate
- */
- public void solveUsingParticle(double x, double y, double z, long currentTimeMillis) {
- Compass currentCompass;
- switch (solverState) {
- case PROCESSING_FIRST_USE:
- currentCompass = firstCompass;
- break;
- case PROCESSING_SECOND_USE:
- currentCompass = secondCompass;
- break;
- default:
- return;
- }
-
- currentCompass.processParticle(x, y, z, currentTimeMillis);
- switch (currentCompass.compassState) {
- case FAILED_TIMEOUT_NO_PARTICLES:
- solverState = SolverState.FAILED_TIMEOUT_NO_PARTICLES;
+ Vec3 particleVec = new Vec3(x, y, z);
+ if (firstParticle == null) {
+ firstParticle = particleVec;
return;
- case FAILED_TIMEOUT_NO_REPEATING:
- solverState = SolverState.FAILED_TIMEOUT_NO_REPEATING;
- return;
- case WAITING_FOR_FIRST_PARTICLE:
- case COMPUTING_LAST_PARTICLE:
- return;
- case COMPLETED:
- if (solverState == SolverState.NEED_SECOND_COMPASS) {
- return;
- }
- if (solverState == SolverState.PROCESSING_FIRST_USE) {
- solverState = SolverState.NEED_SECOND_COMPASS;
- return;
- }
- break;
- }
-
- // First and Second compasses have completed
- solutionIntersectionLine = firstCompass.line.getIntersectionLineSegment(secondCompass.line);
-
- if (solutionIntersectionLine == null) {
- solverState = SolverState.FAILED_INTERSECTION_CALCULATION;
- return;
- }
-
- solution = new Vec3Comparable(solutionIntersectionLine.getMidpoint());
-
- Vec3Comparable firstDirection = firstCompass.getDirection();
- Vec3Comparable firstSolutionDirection = firstCompass.getDirectionTo(solution);
- Vec3Comparable secondDirection = secondCompass.getDirection();
- Vec3Comparable secondSolutionDirection = secondCompass.getDirectionTo(solution);
- if (!firstDirection.signumEquals(firstSolutionDirection) ||
- !secondDirection.signumEquals(secondSolutionDirection) ||
- !HOLLOWS_BB.isVecInside(solution)) {
- solverState = SolverState.FAILED_INVALID_SOLUTION;
- return;
- }
-
- solutionPossibleTargets = getSolutionTargets(possibleTargets, solution);
-
- // Adjust the Jungle Temple solution coordinates
- if (solutionPossibleTargets.size() == 1 &&
- solutionPossibleTargets.contains(CompassTarget.JUNGLE_TEMPLE)) {
- originalSolution = solution;
- solution = solution.addVector(-57, 36, -21);
- }
-
- solverState = SolverState.SOLVED;
- }
-
- private boolean isKeyInInventory()
- {
- for (ItemStack item : mc.thePlayer.inventory.mainInventory){
- if (item != null && item.getDisplayName().contains("Jungle Key")) {
- return true;
}
- }
- return false;
- }
-
- private boolean isKingsScentPresent()
- {
- return SBInfo.getInstance().footer.getUnformattedText().contains("King's Scent I");
- }
-
- private EnumSet<Crystal> getFoundCrystals() {
- EnumSet<Crystal> foundCrystals = EnumSet.noneOf(Crystal.class);
- NEUConfig.HiddenProfileSpecific perProfileConfig = NotEnoughUpdates.INSTANCE.config.getProfileSpecific();
- if (perProfileConfig == null) return foundCrystals;
- HashMap<String, Integer> crystals = perProfileConfig.crystals;
- for (String crystalName : crystals.keySet()) {
- Integer crystalState = crystals.get(crystalName);
- if (crystalState != null && crystalState > 0) {
- foundCrystals.add(Crystal.valueOf(crystalName.toUpperCase()));
- }
- }
-
- return foundCrystals;
- }
-
- // Returns candidates based on seen Y coordinates and quadrants that
- // are not adjacent to the solution's quadrant. If the solution is
- // the nucleus then a copy of the original possible targets is
- // returned.
- //
- // NOTE: Adjacent quadrant filtering could be improved based on
- // structure sizes in the future to only allow a certain
- // distance into the adjacent quadrant.
- //
- // |----------|------------|
- // | Jungle | Mithril |
- // | | Deposits |
- // |----------|----------- |
- // | Goblin | Precursor |
- // | Holdout | Deposits |
- // |----------|------------|
- static public EnumSet<CompassTarget> getSolutionTargets(
- EnumSet<CompassTarget> possibleTargets,
- Vec3Comparable solution) {
- EnumSet<CompassTarget> solutionPossibleTargets;
- solutionPossibleTargets = possibleTargets.clone();
-
- if (NUCLEUS_BB.isVecInside(solution)) {
- return solutionPossibleTargets;
- }
-
- solutionPossibleTargets.remove(CompassTarget.CRYSTAL_NUCLEUS);
-
- // Eliminate non-adjacent zones first
- if (MITHRIL_DEPOSITS_BB.isVecInside(solution)) {
- solutionPossibleTargets.remove(CompassTarget.GOBLIN_KING);
- solutionPossibleTargets.remove(CompassTarget.GOBLIN_QUEEN);
- } else if (PRECURSOR_REMNANTS_BB.isVecInside(solution)) {
- solutionPossibleTargets.remove(CompassTarget.ODAWA);
- solutionPossibleTargets.remove(CompassTarget.JUNGLE_TEMPLE);
- } else if (GOBLIN_HOLDOUT_BB.isVecInside(solution)) {
- solutionPossibleTargets.remove(CompassTarget.MINES_OF_DIVAN);
- } else if (JUNGLE_BB.isVecInside(solution)) {
- solutionPossibleTargets.remove(CompassTarget.PRECURSOR_CITY);
- }
- // If there's only 1 possible target then don't remove based
- // on Y coordinates since assumptions about Y coordinates could
- // be wrong.
- if (solutionPossibleTargets.size() > 1) {
- // Y coordinates are 43-70 from 11 samples
- if (solutionPossibleTargets.contains(CompassTarget.BAL) &&
- solution.yCoord > 72) {
- solutionPossibleTargets.remove(CompassTarget.BAL);
+ double distanceFromFirst = particleVec.distanceTo(firstParticle);
+ if (distanceFromFirst > MAX_COMPASS_PARTICLE_SPREAD) {
+ return;
}
- // Y coordinates are 93-157 from 10 samples, may be able to filter
- // more based on the offset of the King within the structure
- if (solutionPossibleTargets.contains(CompassTarget.GOBLIN_KING) &&
- solution.yCoord < 64) {
- solutionPossibleTargets.remove(CompassTarget.GOBLIN_KING);
+ if (distanceFromFirst >= lastParticleDistanceFromFirst) {
+ lastParticleDistanceFromFirst = distanceFromFirst;
+ lastParticle = particleVec;
+ return;
}
- // Y coordinates are 129-139 from 10 samples
- if (solutionPossibleTargets.contains(CompassTarget.GOBLIN_QUEEN) &&
- (solution.yCoord < 127 || solution.yCoord > 141)) {
- solutionPossibleTargets.remove(CompassTarget.GOBLIN_QUEEN);
+ // We get here when the second repetition of particles begins.
+ // Since the second repetition overlaps with the last few particles
+ // of the first repetition, the last particle we capture isn't truly the last.
+ // But that's OK since subsequent particles will be on the same line.
+ Line line = new Line(firstParticle, lastParticle);
+ if (firstCompassLine == null) {
+ firstCompassLine = line;
+ resetForNewCompass();
+ mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
+ "[NEU] Need another position to determine wishing compass target."));
+ return;
}
- // Y coordinates are 72-80 from 10 samples
- if (solutionPossibleTargets.contains(CompassTarget.JUNGLE_TEMPLE) &&
- (solution.yCoord < 70 || solution.yCoord > 82)) {
- solutionPossibleTargets.remove(CompassTarget.JUNGLE_TEMPLE);
+ secondCompassLine = line;
+ solutionIntersectionLine = firstCompassLine.getIntersectionLineSegment(secondCompassLine);
+ if (solutionIntersectionLine == null) {
+ mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
+ "[NEU] Unable to determine wishing compass target."));
+ logDiagnosticData(false);
+ return;
}
- // Y coordinates are 110-128 from 3 samples, not enough data to use
- if (solutionPossibleTargets.contains(CompassTarget.ODAWA) &&
- solution.yCoord < 64) {
- solutionPossibleTargets.remove(CompassTarget.ODAWA);
- }
+ solution = solutionIntersectionLine.getMidpoint();
- // Y coordinates are 122-129 from 8 samples
- if (solutionPossibleTargets.contains(CompassTarget.PRECURSOR_CITY) &&
- (solution.yCoord < 119 || solution.yCoord > 132)) {
- solutionPossibleTargets.remove(CompassTarget.PRECURSOR_CITY);
+ if (solution.distanceTo(firstParticle) < 8) {
+ mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
+ "[NEU] WARNING: Solution is likely incorrect."));
+ logDiagnosticData(false);
+ return;
}
- // Y coordinates are 98-102 from 15 samples
- if (solutionPossibleTargets.contains(CompassTarget.MINES_OF_DIVAN) &&
- (solution.yCoord < 96 || solution.yCoord > 104)) {
- solutionPossibleTargets.remove(CompassTarget.MINES_OF_DIVAN);
- }
+ showSolution();
+ } catch (Exception e) {
+ mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
+ "[NEU] Exception while calculating wishing compass solution - see log for details"));
+ e.printStackTrace();
}
-
- return solutionPossibleTargets;
}
- private EnumSet<CompassTarget> calculatePossibleTargets(BlockPos playerPos) {
- boolean targetsBasedOnZoneWithoutCrystal = false;
- EnumSet<CompassTarget> candidateTargets = EnumSet.allOf(CompassTarget.class);
- EnumSet<Crystal> foundCrystals = this.foundCrystals.getAsCrystalEnumSet();
- Vec3Comparable playerPosVec = new Vec3Comparable(playerPos);
-
- // If the current zone's crystal hasn't been found then remove all non-nucleus candidates other
- // than the ones in the current zone. The one exception is that the king is kept when in the jungle
- // since the compass can point to the king if odawa is missing (which often happens).
- // The nucleus is kept since it can be returned if the structure for the current zone is missing.
- if (GOBLIN_HOLDOUT_BB.isVecInside(playerPosVec) && !foundCrystals.contains(Crystal.AMBER)) {
- candidateTargets.clear();
- candidateTargets.add(CompassTarget.CRYSTAL_NUCLEUS);
- candidateTargets.add(CompassTarget.GOBLIN_KING);
- candidateTargets.add(CompassTarget.GOBLIN_QUEEN);
- targetsBasedOnZoneWithoutCrystal = true;
- }
-
- if (JUNGLE_BB.isVecInside(playerPosVec) && !foundCrystals.contains(Crystal.AMETHYST)) {
- candidateTargets.clear();
- candidateTargets.add(CompassTarget.CRYSTAL_NUCLEUS);
- candidateTargets.add(CompassTarget.ODAWA);
- candidateTargets.add(CompassTarget.JUNGLE_TEMPLE);
- if (!keyInInventory.getAsBoolean() && !kingsScentPresent.getAsBoolean()) {
- // If Odawa is missing then the king may be returned
- candidateTargets.add(CompassTarget.GOBLIN_KING);
- }
- targetsBasedOnZoneWithoutCrystal = true;
- }
-
- if (MITHRIL_DEPOSITS_BB.isVecInside(playerPosVec) && !foundCrystals.contains(Crystal.JADE)) {
- candidateTargets.clear();
- candidateTargets.add(CompassTarget.CRYSTAL_NUCLEUS);
- candidateTargets.add(CompassTarget.MINES_OF_DIVAN);
- targetsBasedOnZoneWithoutCrystal = true;
- }
-
- if (PRECURSOR_REMNANTS_BB.isVecInside(playerPosVec) && !foundCrystals.contains(Crystal.SAPPHIRE)) {
- candidateTargets.clear();
- candidateTargets.add(CompassTarget.CRYSTAL_NUCLEUS);
- candidateTargets.add(CompassTarget.PRECURSOR_CITY);
- targetsBasedOnZoneWithoutCrystal = true;
- }
-
- if (MAGMA_FIELDS_BB.isVecInside(playerPosVec) && !foundCrystals.contains(Crystal.TOPAZ)) {
- candidateTargets.clear();
- candidateTargets.add(CompassTarget.CRYSTAL_NUCLEUS);
- candidateTargets.add(CompassTarget.BAL);
- targetsBasedOnZoneWithoutCrystal = true;
- }
-
- if (!targetsBasedOnZoneWithoutCrystal) {
- // Filter out crystal-based targets outside the current zone
- if (foundCrystals.contains(Crystal.AMBER)) {
- candidateTargets.remove(CompassTarget.GOBLIN_KING);
- candidateTargets.remove(CompassTarget.GOBLIN_QUEEN);
- }
-
- if (foundCrystals.contains(Crystal.AMETHYST)) {
- candidateTargets.remove(CompassTarget.ODAWA);
- candidateTargets.remove(CompassTarget.JUNGLE_TEMPLE);
- }
-
- if (foundCrystals.contains(Crystal.JADE)) {
- candidateTargets.remove(CompassTarget.MINES_OF_DIVAN);
- }
-
- if (foundCrystals.contains(Crystal.TOPAZ)) {
- candidateTargets.remove(CompassTarget.BAL);
- }
-
- if (foundCrystals.contains(Crystal.SAPPHIRE)) {
- candidateTargets.remove(CompassTarget.PRECURSOR_CITY);
- }
- }
-
- candidateTargets.remove(kingsScentPresent.getAsBoolean() ? CompassTarget.GOBLIN_KING : CompassTarget.GOBLIN_QUEEN);
- candidateTargets.remove(keyInInventory.getAsBoolean() ? CompassTarget.ODAWA : CompassTarget.JUNGLE_TEMPLE);
-
- return candidateTargets;
+ private boolean isSolved() {
+ return solution != null;
}
- private String getFriendlyNameForCompassTarget(CompassTarget compassTarget) {
- switch (compassTarget) {
- case BAL: return EnumChatFormatting.RED + "Bal";
- case ODAWA: return EnumChatFormatting.GREEN + "Odawa";
- case JUNGLE_TEMPLE: return EnumChatFormatting.AQUA + "the " +
- EnumChatFormatting.GREEN + "Jungle Temple";
- case GOBLIN_KING: return EnumChatFormatting.GOLD + "King Yolkar";
- case GOBLIN_QUEEN: return EnumChatFormatting.AQUA + "the " +
- EnumChatFormatting.YELLOW + "Goblin Queen";
- case PRECURSOR_CITY: return EnumChatFormatting.AQUA + "the " +
- EnumChatFormatting.WHITE + "Precursor City";
- case MINES_OF_DIVAN: return EnumChatFormatting.AQUA + "the " +
- EnumChatFormatting.BLUE + "Mines of Divan";
- default: return EnumChatFormatting.WHITE + "an undetermined location";
- }
- }
+ private void showSolution() {
+ if (solution == null) return;
+ String description = "[NEU] Wishing compass target: ";
+ String coordsText = String.format("%.0f %.0f %.0f",
+ solution.xCoord,
+ solution.yCoord,
+ solution.zCoord);
- private String getNameForCompassTarget(CompassTarget compassTarget) {
- boolean useSkytilsNames = (NotEnoughUpdates.INSTANCE.config.mining.wishingCompassWaypointNameType == 1);
- switch (compassTarget) {
- case BAL: return useSkytilsNames ? "internal_bal" : "Bal";
- case ODAWA: return "Odawa";
- case JUNGLE_TEMPLE: return useSkytilsNames ? "internal_temple" : "Temple";
- case GOBLIN_KING: return useSkytilsNames ? "internal_king" : "King";
- case GOBLIN_QUEEN: return useSkytilsNames ? "internal_den" : "Queen";
- case PRECURSOR_CITY: return useSkytilsNames ? "internal_city" : "City";
- case MINES_OF_DIVAN: return useSkytilsNames ? "internal_mines" : "Mines";
- default: return "WishingTarget";
+ if (NUCLEUS_BB.isVecInside(solution)) {
+ description += "Crystal Nucleus (" + coordsText + ")";
+ } else {
+ description += coordsText;
}
- }
- private String getSolutionCoordsText() {
- return solution == null ? "" :
- String.format("%.0f %.0f %.0f", solution.xCoord, solution.yCoord, solution.zCoord);
- }
+ ChatComponentText message = new ChatComponentText(EnumChatFormatting.YELLOW + description);
- private String getWishingCompassDestinationsMessage() {
- StringBuilder sb = new StringBuilder();
- sb.append(EnumChatFormatting.YELLOW);
- sb.append("[NEU] ");
- sb.append(EnumChatFormatting.AQUA);
- sb.append("Wishing compass points to ");
- int index = 1;
- for (CompassTarget target : solutionPossibleTargets) {
- if (index > 1) {
- sb.append(EnumChatFormatting.AQUA);
- if (index == solutionPossibleTargets.size()) {
- sb.append(" or ");
- } else {
- sb.append(", ");
- }
- }
- sb.append(getFriendlyNameForCompassTarget(target));
- index++;
+ if (isSkytilsPresent) {
+ ChatStyle clickEvent = new ChatStyle().setChatClickEvent(
+ new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/sthw add WishingTarget " + coordsText));
+ clickEvent.setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ChatComponentText(
+ EnumChatFormatting.YELLOW +
+ "Add Skytils hollows waypoint")));
+ message.setChatStyle(clickEvent);
}
- sb.append(EnumChatFormatting.AQUA);
- sb.append(" (");
- sb.append(getSolutionCoordsText());
- sb.append(")");
- return sb.toString();
+ Minecraft.getMinecraft().thePlayer.addChatMessage(message);
}
- private void showSolution() {
- if (solution == null) return;
-
- if (NUCLEUS_BB.isVecInside(solution)) {
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "[NEU] " +
- EnumChatFormatting.AQUA + "Wishing compass target is the Crystal Nucleus"));
+ public 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;
}
- String destinationMessage = getWishingCompassDestinationsMessage();
-
- if (!isSkytilsPresent) {
- mc.thePlayer.addChatMessage(new ChatComponentText(destinationMessage));
+ if (!NotEnoughUpdates.INSTANCE.config.mining.wishingCompassSolver)
+ {
+ mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
+ "[NEU] Wishing Compass Solver is not enabled."));
return;
}
- String targetNameForSkytils = solutionPossibleTargets.size() == 1 ?
- getNameForCompassTarget(solutionPossibleTargets.iterator().next()) :
- "WishingTarget";
- String skytilsCommand = String.format("/sthw add %s %s", targetNameForSkytils, getSolutionCoordsText());
- if (NotEnoughUpdates.INSTANCE.config.mining.wishingCompassAutocreateKnownWaypoints &&
- solutionPossibleTargets.size() == 1) {
- mc.thePlayer.addChatMessage(new ChatComponentText(destinationMessage));
- int commandResult = ClientCommandHandler.instance.executeCommand(mc.thePlayer, skytilsCommand);
- if (commandResult == 1)
- {
- return;
- }
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "[NEU] Failed to automatically run /sthw"));
+ if (!outputAlways && !NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.contains(NEUDebugFlag.WISHING)) {
+ return;
}
- destinationMessage += EnumChatFormatting.YELLOW + " [Add Skytils Waypoint]";
- ChatComponentText chatMessage = new ChatComponentText(destinationMessage);
- chatMessage.setChatStyle(Utils.createClickStyle(ClickEvent.Action.RUN_COMMAND,
- skytilsCommand,
- EnumChatFormatting.YELLOW + "Set waypoint for wishing target\n"));
- mc.thePlayer.addChatMessage(chatMessage);
- }
+ boolean originalDebugFlag = !NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.add(NEUDebugFlag.WISHING);
- private String getDiagnosticMessage() {
StringBuilder diagsMessage = new StringBuilder();
+ diagsMessage.append("\n");
diagsMessage.append(EnumChatFormatting.AQUA);
- diagsMessage.append("Solver State: ");
+ diagsMessage.append("Skytils Present: ");
diagsMessage.append(EnumChatFormatting.WHITE);
- diagsMessage.append(solverState.name());
+ diagsMessage.append(isSkytilsPresent);
diagsMessage.append("\n");
- if (firstCompass == null) {
- diagsMessage.append(EnumChatFormatting.AQUA);
- diagsMessage.append("First Compass: ");
- diagsMessage.append(EnumChatFormatting.WHITE);
- diagsMessage.append("<NONE>");
- diagsMessage.append("\n");
- } else {
- firstCompass.appendCompassDiagnostics(diagsMessage, "First Compass");
- }
-
- if (secondCompass == null) {
- diagsMessage.append(EnumChatFormatting.AQUA);
- diagsMessage.append("Second Compass: ");
- diagsMessage.append(EnumChatFormatting.WHITE);
- diagsMessage.append("<NONE>");
- diagsMessage.append("\n");
- } else {
- secondCompass.appendCompassDiagnostics(diagsMessage, "Second Compass");
- }
-
diagsMessage.append(EnumChatFormatting.AQUA);
- diagsMessage.append("Intersection Line: ");
+ diagsMessage.append("Compass Used Millis: ");
diagsMessage.append(EnumChatFormatting.WHITE);
- diagsMessage.append((solutionIntersectionLine == null) ? "<NONE>" : solutionIntersectionLine);
+ diagsMessage.append(compassUsedMillis);
diagsMessage.append("\n");
diagsMessage.append(EnumChatFormatting.AQUA);
- diagsMessage.append("Jungle Key in Inventory: ");
+ diagsMessage.append("Compass Used Position: ");
diagsMessage.append(EnumChatFormatting.WHITE);
- diagsMessage.append(isKeyInInventory());
+ diagsMessage.append((prevPlayerPos == null) ? "<NONE>" : prevPlayerPos.toString());
diagsMessage.append("\n");
diagsMessage.append(EnumChatFormatting.AQUA);
- diagsMessage.append("King's Scent Present: ");
+ diagsMessage.append("First Particle: ");
diagsMessage.append(EnumChatFormatting.WHITE);
- diagsMessage.append(isKingsScentPresent());
+ diagsMessage.append((firstParticle == null) ? "<NONE>" : firstParticle.toString());
diagsMessage.append("\n");
diagsMessage.append(EnumChatFormatting.AQUA);
- diagsMessage.append("First Compass Targets: ");
+ diagsMessage.append("Last Particle: ");
diagsMessage.append(EnumChatFormatting.WHITE);
- diagsMessage.append(possibleTargets == null ? "<NONE>" : possibleTargets.toString());
+ diagsMessage.append((lastParticle == null) ? "<NONE>" : lastParticle.toString());
diagsMessage.append("\n");
diagsMessage.append(EnumChatFormatting.AQUA);
- diagsMessage.append("Current Calculated Targets: ");
+ diagsMessage.append("Last Particle Distance From First: ");
diagsMessage.append(EnumChatFormatting.WHITE);
- diagsMessage.append(calculatePossibleTargets(mc.thePlayer.getPosition()));
+ diagsMessage.append(lastParticleDistanceFromFirst);
diagsMessage.append("\n");
diagsMessage.append(EnumChatFormatting.AQUA);
- diagsMessage.append("Found Crystals: ");
+ diagsMessage.append("First Compass Line: ");
diagsMessage.append(EnumChatFormatting.WHITE);
- diagsMessage.append(getFoundCrystals());
+ diagsMessage.append((firstCompassLine == null) ? "<NONE>" : firstCompassLine.toString());
diagsMessage.append("\n");
- if (originalSolution != null) {
- diagsMessage.append(EnumChatFormatting.AQUA);
- diagsMessage.append("Original Solution: ");
- diagsMessage.append(EnumChatFormatting.WHITE);
- diagsMessage.append(originalSolution);
- diagsMessage.append("\n");
- }
-
diagsMessage.append(EnumChatFormatting.AQUA);
- diagsMessage.append("Solution: ");
+ diagsMessage.append("Second Compass Line: ");
diagsMessage.append(EnumChatFormatting.WHITE);
- diagsMessage.append((solution == null) ? "<NONE>" : solution.toString());
+ diagsMessage.append((secondCompassLine == null) ? "<NONE>" : secondCompassLine.toString());
diagsMessage.append("\n");
diagsMessage.append(EnumChatFormatting.AQUA);
- diagsMessage.append("Solution Targets: ");
+ diagsMessage.append("Intersection Line: ");
diagsMessage.append(EnumChatFormatting.WHITE);
- diagsMessage.append((solutionPossibleTargets == null) ? "<NONE>" : solutionPossibleTargets.toString());
+ diagsMessage.append((secondCompassLine == null) ? "<NONE>" : solutionIntersectionLine);
diagsMessage.append("\n");
- return diagsMessage.toString();
- }
-
- public void logDiagnosticData(boolean outputAlways) {
- if (!SBInfo.getInstance().checkForSkyblockLocation()) {
- return;
- }
-
- if (!NotEnoughUpdates.INSTANCE.config.mining.wishingCompassSolver)
- {
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "[NEU] Wishing Compass Solver is not enabled."));
- return;
- }
-
- boolean wishingDebugFlagSet = NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.contains(NEUDebugFlag.WISHING);
- if (outputAlways || wishingDebugFlagSet) {
- NEUDebugLogger.logAlways(getDiagnosticMessage());
- }
- }
-
- enum CompassState {
- WAITING_FOR_FIRST_PARTICLE,
- COMPUTING_LAST_PARTICLE,
- COMPLETED,
- FAILED_TIMEOUT_NO_REPEATING,
- FAILED_TIMEOUT_NO_PARTICLES,
- }
-
- enum HandleCompassResult {
- SUCCESS,
- LOCATION_TOO_CLOSE,
- STILL_PROCESSING_PRIOR_USE,
- POSSIBLE_TARGETS_CHANGED,
- NO_PARTICLES_FOR_PREVIOUS_COMPASS,
- PLAYER_IN_NUCLEUS
- }
-
- static class Compass {
- public CompassState compassState;
- public Line line = null;
-
- private final BlockPos whereUsed;
- private final long whenUsedMillis;
- private Vec3Comparable firstParticle = null;
- private Vec3Comparable previousParticle = null;
- private Vec3Comparable lastParticle = null;
- private final ArrayList<ProcessedParticle> processedParticles;
-
- Compass(BlockPos whereUsed, long whenUsedMillis) {
- this.whereUsed = whereUsed;
- this.whenUsedMillis = whenUsedMillis;
- compassState = CompassState.WAITING_FOR_FIRST_PARTICLE;
- processedParticles = new ArrayList<>();
- }
-
- public Vec3Comparable getDirection() {
- if (firstParticle == null || lastParticle == null) {
- return null;
- }
-
- return new Vec3Comparable(firstParticle.subtractReverse(lastParticle).normalize());
- }
-
- public Vec3Comparable getDirectionTo(Vec3Comparable target) {
- if (firstParticle == null || target == null) {
- return null;
- }
-
- return new Vec3Comparable(firstParticle.subtractReverse(target).normalize());
- }
-
- public double particleSpread() {
- if (firstParticle == null || lastParticle == null) {
- return 0.0;
- }
- return firstParticle.distanceTo(lastParticle);
- }
-
- public void processParticle(double x, double y, double z, long particleTimeMillis) {
- if (compassState == CompassState.FAILED_TIMEOUT_NO_REPEATING ||
- compassState == CompassState.FAILED_TIMEOUT_NO_PARTICLES ||
- compassState == CompassState.COMPLETED) {
- throw new UnsupportedOperationException("processParticle should not be called in a failed or completed state");
- }
-
- if (particleTimeMillis - this.whenUsedMillis > ALL_PARTICLES_MAX_MILLIS) {
- // Assume we have failed if we're still trying to process particles
- compassState = CompassState.FAILED_TIMEOUT_NO_REPEATING;
- return;
- }
-
- Vec3Comparable currentParticle = new Vec3Comparable(x, y, z);
- if (compassState == CompassState.WAITING_FOR_FIRST_PARTICLE) {
- if (currentParticle.distanceTo(new Vec3Comparable(whereUsed)) < MAX_DISTANCE_FROM_USE_TO_FIRST_PARTICLE) {
- processedParticles.add(new ProcessedParticle(currentParticle, particleTimeMillis));
- firstParticle = currentParticle;
- previousParticle = currentParticle;
- compassState = CompassState.COMPUTING_LAST_PARTICLE;
- }
- return;
- }
-
- // State is COMPUTING_LAST_PARTICLE, keep updating the previousParticle until
- // the first particle in the second sequence is seen.
- if (currentParticle.distanceTo(previousParticle) <= MAX_DISTANCE_BETWEEN_PARTICLES) {
- processedParticles.add(new ProcessedParticle(currentParticle, particleTimeMillis));
- previousParticle = currentParticle;
- return;
- }
-
- if (currentParticle.distanceTo(firstParticle) > MAX_DISTANCE_BETWEEN_PARTICLES) {
- return;
- }
-
- // It's a repeating particle
- processedParticles.add(new ProcessedParticle(currentParticle, particleTimeMillis));
- lastParticle = previousParticle;
- line = new Line(firstParticle, lastParticle);
- compassState = CompassState.COMPLETED;
- }
-
- public void appendCompassDiagnostics(StringBuilder diagsMessage, String compassName) {
- diagsMessage.append(EnumChatFormatting.AQUA);
- diagsMessage.append("Compass State: ");
- diagsMessage.append(EnumChatFormatting.WHITE);
- diagsMessage.append(compassState.name());
- diagsMessage.append("\n");
-
- diagsMessage.append(EnumChatFormatting.AQUA);
- diagsMessage.append(compassName);
- diagsMessage.append(" Used Millis: ");
- diagsMessage.append(EnumChatFormatting.WHITE);
- diagsMessage.append(whenUsedMillis);
- diagsMessage.append("\n");
-
- diagsMessage.append(EnumChatFormatting.AQUA);
- diagsMessage.append(compassName);
- diagsMessage.append(" Used Position: ");
- diagsMessage.append(EnumChatFormatting.WHITE);
- diagsMessage.append((whereUsed == null) ? "<NONE>" : whereUsed.toString());
- diagsMessage.append("\n");
-
- diagsMessage.append(EnumChatFormatting.AQUA);
- diagsMessage.append(compassName);
- diagsMessage.append(" All Seen Particles: \n");
- diagsMessage.append(EnumChatFormatting.WHITE);
- for (ProcessedParticle particle : processedParticles) {
- diagsMessage.append(particle.toString());
- diagsMessage.append("\n");
- }
-
- diagsMessage.append(EnumChatFormatting.AQUA);
- diagsMessage.append(compassName);
- diagsMessage.append(" Particle Spread: ");
- diagsMessage.append(EnumChatFormatting.WHITE);
- diagsMessage.append(particleSpread());
- diagsMessage.append("\n");
-
- diagsMessage.append(EnumChatFormatting.AQUA);
- diagsMessage.append(compassName);
- diagsMessage.append(" Compass Line: ");
- diagsMessage.append(EnumChatFormatting.WHITE);
- diagsMessage.append((line == null) ? "<NONE>" : line.toString());
- diagsMessage.append("\n");
- }
-
- static class ProcessedParticle {
- Vec3Comparable coords;
- long particleTimeMillis;
+ diagsMessage.append(EnumChatFormatting.AQUA);
+ diagsMessage.append("Solution: ");
+ diagsMessage.append(EnumChatFormatting.WHITE);
+ diagsMessage.append((solution == null) ? "<NONE>" : solution.toString());
+ diagsMessage.append("\n");
- ProcessedParticle(Vec3Comparable coords, long particleTimeMillis) {
- this.coords = coords;
- this.particleTimeMillis = particleTimeMillis;
- }
+ NEUDebugLogger.log(NEUDebugFlag.WISHING, diagsMessage.toString());
- @Override
- public String toString() {
- return coords.toString() + " " + particleTimeMillis;
- }
+ if (!originalDebugFlag) {
+ NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.remove(NEUDebugFlag.WISHING);
}
}
}
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 f793baf0..6cfb8c04 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
@@ -641,42 +641,6 @@ public class Mining {
@ConfigAccordionId(id = 6)
public int crystalHollowNoneColor = 12;
- @ConfigOption(
- name = "Wishing Compass Solver",
- desc = ""
- )
- @ConfigEditorAccordion(id = 7)
- public boolean wishingCompassSolverAccordion = false;
-
- @Expose
- @ConfigOption(
- name = "Enable Solver",
- desc = "Show wishing compass target coordinates based on two samples"
- )
- @ConfigAccordionId(id = 7)
- @ConfigEditorBoolean
- public boolean wishingCompassSolver = true;
-
- @Expose
- @ConfigOption(
- name = "Skytils Waypoints",
- desc = "Automatically create Skytils waypoints for well-known targets"
- )
- @ConfigAccordionId(id = 7)
- @ConfigEditorBoolean
- public boolean wishingCompassAutocreateKnownWaypoints = false;
-
- @Expose
- @ConfigOption(
- name = "Waypoint Type",
- desc = "Skytils Waypoint name type. Skytils Built-in will be overwritten by Skytils when the waypoint is nearby."
- )
- @ConfigAccordionId(id = 7)
- @ConfigEditorDropdown(
- values = {"NEU", "Skytils"}
- )
- public int wishingCompassWaypointNameType = 0;
-
@Expose
@ConfigOption(
name = "Puzzler Solver",
@@ -701,11 +665,19 @@ public class Mining {
@ConfigEditorBoolean
public boolean titaniumAlertMustBeVisible = false;
+ @Expose
+ @ConfigOption(
+ name = "Wishing Compass Solver",
+ desc = "Show wishing compass target coordinates based on two samples"
+ )
+ @ConfigEditorBoolean
+ public boolean wishingCompassSolver = true;
+
@ConfigOption(
name = "Custom Textures",
desc = ""
)
- @ConfigEditorAccordion(id = 8)
+ @ConfigEditorAccordion(id = 7)
public boolean texturesAccordion = false;
@Expose
@@ -713,7 +685,7 @@ public class Mining {
name = "Dwarven Mines Textures",
desc = "Allows texture packs to retexture blocks in the Dwarven Mines. If you don't have a texture pack that does this, you should leave this off"
)
- @ConfigAccordionId(id = 8)
+ @ConfigAccordionId(id = 7)
@ConfigEditorBoolean
public boolean dwarvenTextures = false;
@Expose
@@ -721,7 +693,7 @@ public class Mining {
name = "Crystal Hollows Textures",
desc = "Allows texture packs to retexture blocks in the Crystal Hollows. If you don't have a texture pack that does this, you should leave this off"
)
- @ConfigAccordionId(id = 8)
+ @ConfigAccordionId(id = 7)
@ConfigEditorBoolean
public boolean crystalHollowTextures = false;
@@ -730,7 +702,7 @@ public class Mining {
name = "Replace Gemstone sounds",
desc = "Replace the break sounds of crystals in the Crystal Hollows. Requires a texture pack with this feature"
)
- @ConfigAccordionId(id = 8)
+ @ConfigAccordionId(id = 7)
@ConfigEditorBoolean
public boolean gemstoneSounds = false;
@@ -739,7 +711,7 @@ public class Mining {
name = "Replace Mithril sounds",
desc = "Replace the break sounds of mithril and titanium in the Dwarven mines. Requires a texture pack with this feature"
)
- @ConfigAccordionId(id = 8)
+ @ConfigAccordionId(id = 7)
@ConfigEditorBoolean
public boolean mithrilSounds = false;
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java
index dafbe202..48410404 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java
@@ -107,6 +107,7 @@ public class Misc {
@Expose
@ConfigOption(
+
name = "Edit Enchant Colours",
desc = "Change the colours of certain skyblock enchants (/neuec)"
)
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ProfileViewer.java
index 2e1d0619..04fe6e6b 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ProfileViewer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ProfileViewer.java
@@ -49,7 +49,7 @@ public class ProfileViewer {
"\u00a7eMining",
"\u00a7eBingo",
},
- allowRemovingElements = false
+ allowDeleting = false
)
public List<Integer> pageLayout = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7));
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BingoPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BingoPage.java
index 60d1e513..6108901c 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BingoPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BingoPage.java
@@ -298,12 +298,14 @@ public class BingoPage {
NotEnoughUpdates.INSTANCE.manager.hypixelApi.getHypixelApiAsync(
NotEnoughUpdates.INSTANCE.config.apiKey.apiKey,
"resources/skyblock/bingo",
- args
- ).thenAccept(jsonObject -> {
- if (jsonObject.has("success") && jsonObject.get("success").getAsBoolean()) {
- bingoGoals = jsonArrayToJsonObjectList(jsonObject.get("goals").getAsJsonArray());
- currentEventId = jsonObject.get("id").getAsInt();
- }
- });
+ args,
+ jsonObject -> {
+ if (jsonObject.has("success") && jsonObject.get("success").getAsBoolean()) {
+ bingoGoals = jsonArrayToJsonObjectList(jsonObject.get("goals").getAsJsonArray());
+ currentEventId = jsonObject.get("id").getAsInt();
+ }
+ },
+ () -> {}
+ );
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
index 898f9e11..11c10ea0 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
@@ -67,6 +67,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
import java.util.TimeZone;
import java.util.TreeMap;
@@ -1956,6 +1957,12 @@ public class GuiProfileViewer extends GuiScreen {
}
}
+ NBTTagCompound nbt = new NBTTagCompound(); //Adding NBT Data for Custom Resource Packs
+ NBTTagCompound display = new NBTTagCompound();
+ display.setString("Name", skillName);
+ nbt.setTag("display", display);
+ stack.setTagCompound(nbt);
+
GL11.glTranslatef((x), (y - 6f), 0);
GL11.glScalef(0.7f, 0.7f, 1);
Utils.drawItemStackLinear(stack, 0, 0);
@@ -1964,11 +1971,32 @@ public class GuiProfileViewer extends GuiScreen {
}
private ItemStack getQuestionmarkSkull() {
- return Utils.createSkull(
- EnumChatFormatting.RED + "Unknown Pet",
- "Unknown Pet",
- "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYmM4ZWExZjUxZjI1M2ZmNTE0MmNhMTFhZTQ1MTkzYTRhZDhjM2FiNWU5YzZlZWM4YmE3YTRmY2I3YmFjNDAifX19"
- );
+ String textureLink = "bc8ea1f51f253ff5142ca11ae45193a4ad8c3ab5e9c6eec8ba7a4fcb7bac40";
+
+ String b64Decoded =
+ "{\"textures\":{\"SKIN\":{\"url\":\"http://textures.minecraft.net/texture/" + textureLink + "\"}}}";
+ String b64Encoded = new String(Base64.getEncoder().encode(b64Decoded.getBytes()));
+
+ ItemStack stack = new ItemStack(Items.skull, 1, 3);
+ NBTTagCompound nbt = new NBTTagCompound();
+ NBTTagCompound skullOwner = new NBTTagCompound();
+ NBTTagCompound properties = new NBTTagCompound();
+ NBTTagList textures = new NBTTagList();
+ NBTTagCompound textures_0 = new NBTTagCompound();
+
+ String uuid = UUID.nameUUIDFromBytes(b64Encoded.getBytes()).toString();
+ skullOwner.setString("Id", uuid);
+ skullOwner.setString("Name", uuid);
+
+ textures_0.setString("Value", b64Encoded);
+ textures.appendTag(textures_0);
+
+ properties.setTag("textures", textures);
+ skullOwner.setTag("Properties", properties);
+ nbt.setTag("SkullOwner", skullOwner);
+ stack.setTagCompound(nbt);
+ stack.setStackDisplayName(EnumChatFormatting.RED + "Unknown Pet");
+ return stack;
}
private void drawPetsPage(int mouseX, int mouseY, float partialTicks) {
@@ -5303,24 +5331,37 @@ public class GuiProfileViewer extends GuiScreen {
}
public enum ProfileViewerPage {
- LOADING(-1, null),
- INVALID_NAME(-1, null),
- NO_SKYBLOCK(-1, null),
- BASIC(0, new ItemStack(Items.paper)),
- DUNGEON(1, new ItemStack(Item.getItemFromBlock(Blocks.deadbush))),
- EXTRA(2, new ItemStack(Items.book)),
- INVENTORIES(3, new ItemStack(Item.getItemFromBlock(Blocks.ender_chest))),
- COLLECTIONS(4, new ItemStack(Items.painting)),
- PETS(5, new ItemStack(Items.bone)),
- MINING(6, new ItemStack(Items.iron_pickaxe)),
- BINGO(7, new ItemStack(Items.filled_map));
+ LOADING(),
+ INVALID_NAME(),
+ NO_SKYBLOCK(),
+ BASIC(0, Items.paper, "Your Skills"),
+ DUNGEON(1, Item.getItemFromBlock(Blocks.deadbush), "Dungeoneering"),
+ EXTRA(2, Items.book, "Profile Stats"),
+ INVENTORIES(3, Item.getItemFromBlock(Blocks.ender_chest), "Storage"),
+ COLLECTIONS(4, Items.painting, "Collections"),
+ PETS(5, Items.bone, "Pets"),
+ MINING(6, Items.iron_pickaxe, "Heart of the Mountain"),
+ BINGO(7, Items.filled_map, "Bingo");
public final ItemStack stack;
public final int id;
- ProfileViewerPage(int id, ItemStack stack) {
+ ProfileViewerPage() {
+ this(-1, null, null);
+ }
+
+ ProfileViewerPage(int id, Item item, String name) {
this.id = id;
- this.stack = stack;
+ if (item == null) {
+ stack = null;
+ } else {
+ stack = new ItemStack(item);
+ NBTTagCompound nbt = new NBTTagCompound(); //Adding NBT Data for Custom Resource Packs
+ NBTTagCompound display = new NBTTagCompound();
+ display.setString("Name", name);
+ nbt.setTag("display", display);
+ stack.setTagCompound(nbt);
+ }
}
public static ProfileViewerPage getById(int id) {
@@ -5331,6 +5372,11 @@ public class GuiProfileViewer extends GuiScreen {
}
return null;
}
+
+ public Optional<ItemStack> getItem() {
+ return Optional.ofNullable(stack);
+ }
+
}
public static class PetLevel {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/NEUDebugLogger.java b/src/main/java/io/github/moulberry/notenoughupdates/util/NEUDebugLogger.java
index 827a3e97..d662a872 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/NEUDebugLogger.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/NEUDebugLogger.java
@@ -13,8 +13,6 @@ import java.util.function.Consumer;
public class NEUDebugLogger {
private static final Minecraft mc = Minecraft.getMinecraft();
public static Consumer<String> logMethod = NEUDebugLogger::chatLogger;
- // Used to prevent accessing NEUConfig in unit tests
- public static boolean allFlagsEnabled = false;
private static void chatLogger(String message) {
mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "[NEU DEBUG] " + message));
@@ -25,13 +23,7 @@ public class NEUDebugLogger {
}
public static void log(NEUDebugFlag flag, String message) {
- if (logMethod != null && (allFlagsEnabled || isFlagEnabled(flag))) {
- logAlways(message);
- }
- }
-
- public static void logAlways(String message) {
- if (logMethod != null) {
+ if (logMethod != null && isFlagEnabled(flag)) {
logMethod.accept(message);
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java
index a557eb12..5b7bd055 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java
@@ -18,8 +18,6 @@ import net.minecraft.scoreboard.Score;
import net.minecraft.scoreboard.ScoreObjective;
import net.minecraft.scoreboard.ScorePlayerTeam;
import net.minecraft.scoreboard.Scoreboard;
-import net.minecraft.util.ChatComponentText;
-import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IChatComponent;
import net.minecraftforge.client.event.ClientChatReceivedEvent;
import net.minecraftforge.client.event.GuiOpenEvent;
@@ -59,7 +57,7 @@ public class SBInfo {
public String slayer = "";
public boolean stranded = false;
- public String mode = null;
+ public String mode = "";
public Date currentTimeDate = null;
@@ -122,16 +120,6 @@ public class SBInfo {
}
}
- public boolean checkForSkyblockLocation() {
- if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() || getLocation() == null) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "[NEU] This command is not available outside SkyBlock"));
- return false;
- }
-
- return true;
- }
-
private static final Pattern PROFILE_PATTERN =
Pattern.compile("(?<type>(♲ Ironman)|(☀ Stranded)|()) *Profile: (?<name>[^ ]+)");
diff --git a/src/test/java/io/github/moulberry/notenoughupdates/core/util/Vec3ComparableTest.java b/src/test/java/io/github/moulberry/notenoughupdates/core/util/Vec3ComparableTest.java
deleted file mode 100644
index c0b451e3..00000000
--- a/src/test/java/io/github/moulberry/notenoughupdates/core/util/Vec3ComparableTest.java
+++ /dev/null
@@ -1,193 +0,0 @@
-package io.github.moulberry.notenoughupdates.core.util;
-
-import net.minecraft.util.BlockPos;
-import net.minecraft.util.Vec3;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertNotEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-class Vec3ComparableTest {
- @Test
- void equals_false_when_null() {
- // Arrange
- Vec3Comparable vec3c = new Vec3Comparable(1.0, 2.0, 3.0);
-
- // Act
- boolean areEqual = vec3c.equals(null);
-
- // Assert
- assertFalse(areEqual);
- }
-
- @Test
- void equals_true_when_same_object() {
- // Arrange
- Vec3Comparable vec3c = new Vec3Comparable(1.0, 2.0, 3.0);
-
- // Act
- boolean areEqual = vec3c.equals(vec3c);
-
- // Assert
- assertTrue(areEqual);
- }
-
- @Test
- void equals_true_when_same_value() {
- // Arrange
- Vec3Comparable vec3c1 = new Vec3Comparable(1.0, 2.0, 3.0);
- Vec3Comparable vec3c2 = new Vec3Comparable(1.0, 2.0, 3.0);
-
- // Act
- boolean areEqual = vec3c1.equals(vec3c2);
-
- // Assert
- assertTrue(areEqual);
- }
-
- @Test
- void equals_false_when_vec3_equals() {
- // Arrange
- Vec3Comparable vec3c1 = new Vec3Comparable(1.0, 2.0, 3.0);
- Vec3 vec3c2 = new Vec3(1.0, 2.0, 3.0);
-
- // Act
- boolean areEqual = vec3c1.equals(vec3c2);
-
- // Assert
- assertFalse(areEqual);
- }
-
- @Test
- void equals_false_when_different_object_type() {
- // Arrange
- Vec3Comparable vec3c1 = new Vec3Comparable(1.0, 2.0, 3.0);
- BlockPos blockPos = new BlockPos(1.0, 2.0, 3.0);
-
- // Act
- boolean areEqual = vec3c1.equals(blockPos);
-
- // Assert
- assertFalse(areEqual);
- }
-
- @Test
- void equals_false_when_different_value() {
- // Arrange
- Vec3Comparable vec3c1 = new Vec3Comparable(1.0, 2.0, 3.0);
- Vec3Comparable vec3c2 = new Vec3Comparable(3.0, 2.0, 1.0);
-
- // Act
- boolean areEqual = vec3c1.equals(vec3c2);
-
- // Assert
- assertFalse(areEqual);
- }
-
- @Test
- void hashCode_same_when_same_value() {
- // Arrange
- Vec3Comparable vec3c1 = new Vec3Comparable(1.0, 2.0, 3.0);
- Vec3Comparable vec3c2 = new Vec3Comparable(1.0, 2.0, 3.0);
-
- // Act
- double vec3c1Hash = vec3c1.hashCode();
- double vec3c2Hash = vec3c2.hashCode();
-
- // Assert
- assertEquals(vec3c1Hash, vec3c2Hash);
- }
-
- @Test
- void hashCode_different_when_different_value() {
- // Arrange
- Vec3Comparable vec3c1 = new Vec3Comparable(1.0, 2.0, 3.0);
- Vec3Comparable vec3c2 = new Vec3Comparable(3.0, 2.0, 1.0);
-
- // Act
- double vec3c1Hash = vec3c1.hashCode();
- double vec3c2Hash = vec3c2.hashCode();
-
- // Assert
- assertNotEquals(vec3c1Hash, vec3c2Hash);
- }
-
- @Test
- void compareTo_zero_when_equal() {
- // Arrange
- Vec3Comparable vec3c1 = new Vec3Comparable(1.0, 2.0, 3.0);
- Vec3Comparable vec3c2 = new Vec3Comparable(1.0, 2.0, 3.0);
-
- // Act
- int result = vec3c1.compareTo(vec3c2);
-
- // Assert
- assertEquals(0, result);
- }
-
- @Test
- void compareTo_negative_when_lower() {
- // Arrange
- Vec3Comparable vec3c1 = new Vec3Comparable(0.0, 2.0, 3.0);
- Vec3Comparable vec3c2 = new Vec3Comparable(1.0, 2.0, 3.0);
-
- // Act
- int result = vec3c1.compareTo(vec3c2);
-
- // Assert
- assertTrue(result < 0);
- }
-
- @Test
- void compareTo_positive_when_x_y_or_z_is_higher() {
- // Arrange
- Vec3Comparable vec3c1x = new Vec3Comparable(2.0, 2.0, 3.0);
- Vec3Comparable vec3c2x = new Vec3Comparable(1.0, 2.0, 3.0);
- Vec3Comparable vec3c1y = new Vec3Comparable(1.0, 3.0, 3.0);
- Vec3Comparable vec3c2y = new Vec3Comparable(1.0, 2.0, 3.0);
- Vec3Comparable vec3c1z = new Vec3Comparable(1.0, 2.0, 4.0);
- Vec3Comparable vec3c2z = new Vec3Comparable(1.0, 2.0, 3.0);
-
- // Act
- int resultX = vec3c1x.compareTo(vec3c2x);
- int resultY = vec3c1y.compareTo(vec3c2y);
- int resultZ = vec3c1z.compareTo(vec3c2z);
-
- // Assert
- assertTrue(resultX > 0);
- assertTrue(resultY > 0);
- assertTrue(resultZ > 0);
- }
-
- @Test
- void compareTo_throws_on_null() {
- // Arrange
- Vec3Comparable vec3c = new Vec3Comparable(1.0, 2.0, 3.0);
-
- // Act & Assert
- Assertions.assertThrows(NullPointerException.class, () -> {
- vec3c.compareTo(null);
- });
- }
-
- @Test
- void signumEquals_is_true_when_all_signums_match() {
- Vec3Comparable first = new Vec3Comparable(-1.0, 1.0, 0);
- Vec3 second = new Vec3(-1.0, 1.0, 0);
- Assertions.assertTrue(first.signumEquals(second));
- }
-
- @Test
- void signumEquals_is_false_when_any_signum_differs() {
- Vec3Comparable first = new Vec3Comparable(-1.0, 1.0, 0);
- Vec3 second = new Vec3(-1.0, 1.0, 1.0);
- Vec3 third = new Vec3(-1.0, -1.0, 0);
- Vec3 fourth = new Vec3(1.0, 1.0, 1.0);
- Assertions.assertFalse(first.signumEquals(second));
- Assertions.assertFalse(first.signumEquals(third));
- Assertions.assertFalse(first.signumEquals(fourth));
- }
-}
diff --git a/src/test/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolverTest.java b/src/test/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolverTest.java
deleted file mode 100644
index 58233410..00000000
--- a/src/test/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolverTest.java
+++ /dev/null
@@ -1,204 +0,0 @@
-package io.github.moulberry.notenoughupdates.miscfeatures;
-
-import io.github.moulberry.notenoughupdates.core.util.Vec3Comparable;
-import io.github.moulberry.notenoughupdates.miscfeatures.CrystalMetalDetectorSolver.SolutionState;
-import io.github.moulberry.notenoughupdates.util.NEUDebugLogger;
-import net.minecraft.util.BlockPos;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.Assertions;
-
-import java.util.ArrayList;
-
-class CrystalMetalDetectorSolverTest {
- class Location {
- double distance;
- Vec3Comparable playerPosition;
- SolutionState expectedState;
- boolean centerKnown;
-
- public Location(double distance,
- Vec3Comparable playerPosition,
- SolutionState expectedState,
- boolean centerKnown) {
- this.distance = distance;
- this.playerPosition = playerPosition;
- this.expectedState = expectedState;
- this.centerKnown = centerKnown;
- }
- }
-
- class Solution {
- ArrayList<Location> locations = new ArrayList<>();
- BlockPos center = BlockPos.ORIGIN;
- BlockPos expectedSolution = BlockPos.ORIGIN;
- }
-
- @BeforeEach
- void setUp() {
- CrystalMetalDetectorSolver.initWorld();
- CrystalMetalDetectorSolver.treasureAllowedPredicate = blockPos -> true;
- NEUDebugLogger.logMethod = CrystalMetalDetectorSolverTest::neuDebugLog;
- NEUDebugLogger.allFlagsEnabled = true;
- }
-
- private void findPossibleSolutionsTwice(Location loc, boolean centerNewlyDiscovered) {
- // Each location has to be received twice to be valid
- CrystalMetalDetectorSolver.findPossibleSolutions(loc.distance, loc.playerPosition, centerNewlyDiscovered);
- CrystalMetalDetectorSolver.findPossibleSolutions(loc.distance, loc.playerPosition, false);
- }
-
- private void checkSolution(Solution solution) {
- boolean centerSet = false;
- int index = 0;
- for (Location loc : solution.locations) {
- if (loc.centerKnown && !centerSet && !solution.center.equals(BlockPos.ORIGIN)) {
- CrystalMetalDetectorSolver.setMinesCenter(solution.center);
- centerSet = true;
- findPossibleSolutionsTwice(loc, true);
- } else {
- findPossibleSolutionsTwice(loc, false);
- }
- Assertions.assertEquals(loc.expectedState,
- CrystalMetalDetectorSolver.currentState,
- "Location index " + index);
- index++;
- }
-
- Assertions.assertEquals(solution.expectedSolution, CrystalMetalDetectorSolver.getSolution());
- }
-
- @Test
- void findPossibleSolutions_single_location_sample_is_ignored() {
- Location location = new Location(37.3,
- new Vec3Comparable(779.1057116115207, 70.5, 502.2997937667801),
- SolutionState.MULTIPLE,
- false);
-
- CrystalMetalDetectorSolver.findPossibleSolutions(location.distance, location.playerPosition, false);
- Assertions.assertEquals(SolutionState.NOT_STARTED, CrystalMetalDetectorSolver.previousState,
- "Previous state");
- Assertions.assertEquals(SolutionState.NOT_STARTED, CrystalMetalDetectorSolver.currentState,
- "Current state");
- }
-
- @Test
- void findPossibleSolutions_currentState_becomes_previousState() {
- Location location = new Location(37.3,
- new Vec3Comparable(779.1057116115207, 70.5, 502.2997937667801),
- SolutionState.MULTIPLE,
- false);
-
- findPossibleSolutionsTwice(location, false);
- Assertions.assertEquals(SolutionState.NOT_STARTED, CrystalMetalDetectorSolver.previousState,
- "Previous state");
- Assertions.assertEquals(location.expectedState, CrystalMetalDetectorSolver.currentState,
- "Current state");
- }
-
- @Test
- void findPossibleSolutions_state_is_invalid_when_solution_and_distance_mismatch() {
- Solution solution = new Solution();
- solution.center = new BlockPos(736, 88, 547);
- solution.expectedSolution = new BlockPos(722, 67, 590);
- solution.locations.add(new Location(67.5,
- new Vec3Comparable(757.8235166144441, 68.0, 532.8037800566217),
- SolutionState.FOUND_KNOWN,
- true));
- // slightly different player position with invalid distance
- solution.locations.add(new Location(4.0,
- new Vec3Comparable(757.8235166144441, 69.0, 532.8037800566217),
- SolutionState.INVALID,
- true));
- checkSolution(solution);
- }
-
- @Test
- void findPossibleSolutions_state_is_failed_when_second_location_eliminates_all_blocks() {
- Solution solution = new Solution();
- solution.center = new BlockPos(736, 88, 547);
- solution.locations.add(new Location(29.4,
- new Vec3Comparable(721.5979761606153, 68.0, 590.9056839507032),
- SolutionState.MULTIPLE_KNOWN,
- true));
- solution.locations.add(new Location(4.0, // actual distance should be 38.2
- new Vec3Comparable(711.858759313838, 67.0, 590.3583935310772),
- SolutionState.FAILED,
- true));
- checkSolution(solution);
- }
-
- @Test
- void findPossibleSolutions_state_is_found_known_when_center_found_after_location() {
- Solution solution = new Solution();
- solution.center = new BlockPos(736, 88, 547);
- solution.locations.add(new Location(67.5,
- new Vec3Comparable(757.8235166144441, 68.0, 532.8037800566217),
- SolutionState.MULTIPLE,
- false));
- checkSolution(solution);
-
- solution.locations.get(0).centerKnown = true;
- solution.locations.get(0).expectedState = SolutionState.FOUND_KNOWN;
- solution.expectedSolution = new BlockPos(722, 67, 590);
- checkSolution(solution);
- }
-
- @Test
- void findPossibleSolutions_state_is_found_when_single_known_location() {
- Solution solution = new Solution();
- solution.center = new BlockPos(736, 88, 547);
- solution.expectedSolution = new BlockPos(722, 67, 590);
- solution.locations.add(new Location(67.5,
- new Vec3Comparable(757.8235166144441, 68.0, 532.8037800566217),
- SolutionState.FOUND_KNOWN,
- true));
- checkSolution(solution);
- }
-
- @Test
- void findPossibleSolutions_states_are_correct_using_multiple_locations_with_unknown_center() {
- Solution solution = new Solution();
- solution.locations.add(new Location(37.3,
- new Vec3Comparable(779.1057116115207, 70.5, 502.2997937667801),
- SolutionState.MULTIPLE,
- false));
- solution.locations.add(new Location(34.8,
- new Vec3Comparable(782.6999999880791, 71.0, 508.69999998807907),
- SolutionState.FOUND,
- false));
- solution.expectedSolution = new BlockPos(758, 67, 533);
-
- checkSolution(solution);
- }
-
- @Test
- void findPossibleSolutions_states_are_correct_when_multiple_known_locations_found() {
- Solution solution = new Solution();
-
- // First, validate that the solution doesn't work without the center
- solution.locations.add(new Location(29.4,
- new Vec3Comparable(721.5979761606153, 68.0, 590.9056839507032),
- SolutionState.MULTIPLE,
- false));
- solution.locations.add(new Location(38.2,
- new Vec3Comparable(711.858759313838, 67.0, 590.3583935310772),
- SolutionState.MULTIPLE,
- false));
- checkSolution(solution);
-
- // Now validate that the solution works with the center
- CrystalMetalDetectorSolver.resetSolution(false);
- solution.locations.get(0).expectedState = SolutionState.MULTIPLE_KNOWN;
- solution.locations.get(0).centerKnown = true;
- solution.locations.get(1).expectedState = SolutionState.FOUND_KNOWN;
- solution.locations.get(1).centerKnown = true;
- solution.expectedSolution = new BlockPos(748, 66, 578);
- solution.center = new BlockPos(736, 88, 547);
- checkSolution(solution);
- }
-
- private static void neuDebugLog(String message) {
- System.out.println(message);
- }
-}
diff --git a/src/test/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolverTest.java b/src/test/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolverTest.java
deleted file mode 100644
index ed39a505..00000000
--- a/src/test/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolverTest.java
+++ /dev/null
@@ -1,1206 +0,0 @@
-package io.github.moulberry.notenoughupdates.miscfeatures;
-
-import io.github.moulberry.notenoughupdates.core.util.Vec3Comparable;
-import io.github.moulberry.notenoughupdates.miscfeatures.CrystalWishingCompassSolver.CompassTarget;
-import io.github.moulberry.notenoughupdates.miscfeatures.CrystalWishingCompassSolver.HandleCompassResult;
-import io.github.moulberry.notenoughupdates.miscfeatures.CrystalWishingCompassSolver.SolverState;
-import io.github.moulberry.notenoughupdates.util.NEUDebugLogger;
-import net.minecraft.util.BlockPos;
-import net.minecraft.util.Vec3;
-import net.minecraft.util.Vec3i;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.EnumSet;
-
-import static io.github.moulberry.notenoughupdates.miscfeatures.CrystalWishingCompassSolver.*;
-
-class CrystalWishingCompassSolverTest {
- private static final CrystalWishingCompassSolver solver = getInstance();
- long systemTimeMillis;
- private final long DELAY_AFTER_FIRST_COMPASS_LAST_PARTICLE = 500L;
-
- private final CompassUse minesOfDivanCompassUse1 = new CompassUse(
- 1647528732979L,
- new BlockPos(754, 137, 239),
- new ArrayList<>(Arrays.asList(
- new ParticleSpawn(new Vec3Comparable(754.358459, 138.536407, 239.200928), 137),
- new ParticleSpawn(new Vec3Comparable(754.315735, 138.444351, 239.690521), 45),
- new ParticleSpawn(new Vec3Comparable(754.272278, 138.352051, 240.180008), 51),
- new ParticleSpawn(new Vec3Comparable(754.228760, 138.259750, 240.669479), 49),
- new ParticleSpawn(new Vec3Comparable(754.185303, 138.167435, 241.158966), 57),
- new ParticleSpawn(new Vec3Comparable(754.141846, 138.075134, 241.648438), 50),
- new ParticleSpawn(new Vec3Comparable(754.098328, 137.982819, 242.137909), 51),
- new ParticleSpawn(new Vec3Comparable(754.054871, 137.890518, 242.627396), 57),
- new ParticleSpawn(new Vec3Comparable(754.011353, 137.798203, 243.116867), 44),
- new ParticleSpawn(new Vec3Comparable(753.967896, 137.705887, 243.606354), 59),
- new ParticleSpawn(new Vec3Comparable(753.924438, 137.613586, 244.095825), 35),
- new ParticleSpawn(new Vec3Comparable(753.880920, 137.521271, 244.585297), 48),
- new ParticleSpawn(new Vec3Comparable(753.837463, 137.428970, 245.074783), 70),
- new ParticleSpawn(new Vec3Comparable(753.793945, 137.336655, 245.564255), 33),
- new ParticleSpawn(new Vec3Comparable(753.750488, 137.244354, 246.053741), 55),
- new ParticleSpawn(new Vec3Comparable(753.707031, 137.152039, 246.543213), 42),
- new ParticleSpawn(new Vec3Comparable(753.663513, 137.059738, 247.032700), 56),
- new ParticleSpawn(new Vec3Comparable(753.620056, 136.967422, 247.522171), 48),
- new ParticleSpawn(new Vec3Comparable(753.576538, 136.875122, 248.011642), 56),
- new ParticleSpawn(new Vec3Comparable(754.333618, 138.527710, 239.197800), 55)
- )),
- HandleCompassResult.SUCCESS,
- SolverState.NEED_SECOND_COMPASS);
-
- private final CompassUse minesOfDivanCompassUse2 = new CompassUse(
- DELAY_AFTER_FIRST_COMPASS_LAST_PARTICLE,
- new BlockPos(760, 134, 266),
- new ArrayList<>(Arrays.asList(
- new ParticleSpawn(new Vec3Comparable(759.686951, 135.524994, 266.190704), 129),
- new ParticleSpawn(new Vec3Comparable(759.625183, 135.427887, 266.677277), 69),
- new ParticleSpawn(new Vec3Comparable(759.561707, 135.330704, 267.163635), 31),
- new ParticleSpawn(new Vec3Comparable(759.498230, 135.233536, 267.649963), 115),
- new ParticleSpawn(new Vec3Comparable(759.434753, 135.136368, 268.136322), 0),
- new ParticleSpawn(new Vec3Comparable(759.371277, 135.039200, 268.622650), 46),
- new ParticleSpawn(new Vec3Comparable(759.307800, 134.942017, 269.109009), 49),
- new ParticleSpawn(new Vec3Comparable(759.244324, 134.844849, 269.595337), 59),
- new ParticleSpawn(new Vec3Comparable(759.180847, 134.747681, 270.081696), 45),
- new ParticleSpawn(new Vec3Comparable(759.117371, 134.650513, 270.568024), 39),
- new ParticleSpawn(new Vec3Comparable(759.053894, 134.553329, 271.054352), 67),
- new ParticleSpawn(new Vec3Comparable(758.990356, 134.456161, 271.540710), 49),
- new ParticleSpawn(new Vec3Comparable(758.926880, 134.358994, 272.027039), 32),
- new ParticleSpawn(new Vec3Comparable(758.863403, 134.261826, 272.513397), 61),
- new ParticleSpawn(new Vec3Comparable(758.799927, 134.164642, 272.999725), 44),
- new ParticleSpawn(new Vec3Comparable(758.736450, 134.067474, 273.486084), 48),
- new ParticleSpawn(new Vec3Comparable(758.672974, 133.970306, 273.972412), 57),
- new ParticleSpawn(new Vec3Comparable(758.609497, 133.873138, 274.458740), 55),
- new ParticleSpawn(new Vec3Comparable(758.546021, 133.775955, 274.945099), 59),
- new ParticleSpawn(new Vec3Comparable(758.482544, 133.678787, 275.431427), 38),
- new ParticleSpawn(new Vec3Comparable(759.636658, 135.522827, 266.186371), 0)
- )),
- HandleCompassResult.SUCCESS,
- SolverState.SOLVED);
-
- Vec3i minesOfDivanSolution = new Vec3i(735, 98, 451);
-
- private final CompassUse goblinHoldoutCompassUse1 = new CompassUse(
- 1647776326763L,
- new BlockPos(454, 87, 776),
- new ArrayList<>(Arrays.asList(
- new ParticleSpawn(new Vec3Comparable(454.171722, 88.616852, 775.807190), 188),
- new ParticleSpawn(new Vec3Comparable(454.010315, 88.613464, 775.333984), 44),
- new ParticleSpawn(new Vec3Comparable(453.849243, 88.610069, 774.860657), 61),
- new ParticleSpawn(new Vec3Comparable(453.688141, 88.606674, 774.387329), 51),
- new ParticleSpawn(new Vec3Comparable(453.527069, 88.603271, 773.914001), 40),
- new ParticleSpawn(new Vec3Comparable(453.365997, 88.599876, 773.440674), 57),
- new ParticleSpawn(new Vec3Comparable(453.204926, 88.596481, 772.967346), 45),
- new ParticleSpawn(new Vec3Comparable(453.043854, 88.593086, 772.494019), 49),
- new ParticleSpawn(new Vec3Comparable(452.882782, 88.589691, 772.020691), 46),
- new ParticleSpawn(new Vec3Comparable(452.721710, 88.586288, 771.547302), 65),
- new ParticleSpawn(new Vec3Comparable(452.560638, 88.582893, 771.073975), 43),
- new ParticleSpawn(new Vec3Comparable(452.399567, 88.579498, 770.600647), 50),
- new ParticleSpawn(new Vec3Comparable(452.238495, 88.576103, 770.127319), 48),
- new ParticleSpawn(new Vec3Comparable(452.077423, 88.572701, 769.653992), 47),
- new ParticleSpawn(new Vec3Comparable(451.916351, 88.569305, 769.180664), 60),
- new ParticleSpawn(new Vec3Comparable(451.755280, 88.565910, 768.707336), 40),
- new ParticleSpawn(new Vec3Comparable(451.594208, 88.562515, 768.234009), 69),
- new ParticleSpawn(new Vec3Comparable(451.433136, 88.559120, 767.760681), 40),
- new ParticleSpawn(new Vec3Comparable(451.272064, 88.555717, 767.287354), 42),
- new ParticleSpawn(new Vec3Comparable(454.183441, 88.616600, 775.803040), 54)
- )),
- HandleCompassResult.SUCCESS,
- SolverState.NEED_SECOND_COMPASS);
-
- private final CompassUse goblinHoldoutCompassUse2 = new CompassUse(
- DELAY_AFTER_FIRST_COMPASS_LAST_PARTICLE,
- new BlockPos(439, 85, 777),
- new ArrayList<>(Arrays.asList(
- new ParticleSpawn(new Vec3Comparable(439.068848, 86.624870, 776.043701), 136),
- new ParticleSpawn(new Vec3Comparable(438.936066, 86.625786, 775.561646), 46),
- new ParticleSpawn(new Vec3Comparable(438.804352, 86.626595, 775.079346), 65),
- new ParticleSpawn(new Vec3Comparable(438.672699, 86.627396, 774.596985), 40),
- new ParticleSpawn(new Vec3Comparable(438.541016, 86.628197, 774.114624), 51),
- new ParticleSpawn(new Vec3Comparable(438.409332, 86.628998, 773.632263), 50),
- new ParticleSpawn(new Vec3Comparable(438.277679, 86.629799, 773.149902), 50),
- new ParticleSpawn(new Vec3Comparable(438.145996, 86.630608, 772.667603), 56),
- new ParticleSpawn(new Vec3Comparable(438.014343, 86.631409, 772.185242), 40),
- new ParticleSpawn(new Vec3Comparable(437.882660, 86.632210, 771.702881), 65),
- new ParticleSpawn(new Vec3Comparable(437.751007, 86.633011, 771.220520), 45),
- new ParticleSpawn(new Vec3Comparable(437.619324, 86.633812, 770.738159), 42),
- new ParticleSpawn(new Vec3Comparable(437.487671, 86.634613, 770.255798), 60),
- new ParticleSpawn(new Vec3Comparable(437.355988, 86.635414, 769.773499), 51),
- new ParticleSpawn(new Vec3Comparable(437.224335, 86.636215, 769.291138), 44),
- new ParticleSpawn(new Vec3Comparable(437.092651, 86.637024, 768.808777), 56),
- new ParticleSpawn(new Vec3Comparable(436.960999, 86.637825, 768.326416), 56),
- new ParticleSpawn(new Vec3Comparable(436.829315, 86.638626, 767.844055), 40),
- new ParticleSpawn(new Vec3Comparable(436.697632, 86.639427, 767.361694), 50),
- new ParticleSpawn(new Vec3Comparable(436.565979, 86.640228, 766.879395), 46),
- new ParticleSpawn(new Vec3Comparable(439.108551, 86.620811, 776.031067), 0)
- )),
- HandleCompassResult.SUCCESS,
- SolverState.SOLVED);
-
- Vec3i goblinHoldoutKingSolution = new Vec3i(377, 87, 550);
- Vec3i goblinHoldoutQueenSolution = new Vec3i(322, 139, 769);
-
- private final CompassUse precursorCityCompassUse1 = new CompassUse(
- 1647744920365L,
- new BlockPos(570, 120, 565),
- new ArrayList<>(Arrays.asList(
- new ParticleSpawn(new Vec3Comparable(570.428955, 121.630745, 565.674500), 192),
- new ParticleSpawn(new Vec3Comparable(570.572998, 121.642563, 566.153137), 52),
- new ParticleSpawn(new Vec3Comparable(570.714233, 121.654442, 566.632629), 45),
- new ParticleSpawn(new Vec3Comparable(570.855286, 121.666321, 567.112183), 51),
- new ParticleSpawn(new Vec3Comparable(570.996338, 121.678200, 567.591736), 0),
- new ParticleSpawn(new Vec3Comparable(571.137390, 121.690079, 568.071289), 111),
- new ParticleSpawn(new Vec3Comparable(571.278442, 121.701958, 568.550781), 38),
- new ParticleSpawn(new Vec3Comparable(571.419495, 121.713844, 569.030334), 51),
- new ParticleSpawn(new Vec3Comparable(571.560547, 121.725723, 569.509888), 49),
- new ParticleSpawn(new Vec3Comparable(571.701599, 121.737602, 569.989441), 0),
- new ParticleSpawn(new Vec3Comparable(571.842651, 121.749481, 570.468994), 101),
- new ParticleSpawn(new Vec3Comparable(571.983704, 121.761360, 570.948547), 53),
- new ParticleSpawn(new Vec3Comparable(572.124756, 121.773239, 571.428101), 47),
- new ParticleSpawn(new Vec3Comparable(572.265747, 121.785118, 571.907654), 49),
- new ParticleSpawn(new Vec3Comparable(572.406799, 121.796997, 572.387207), 49),
- new ParticleSpawn(new Vec3Comparable(572.547852, 121.808876, 572.866699), 51),
- new ParticleSpawn(new Vec3Comparable(572.688904, 121.820755, 573.346252), 57),
- new ParticleSpawn(new Vec3Comparable(572.829956, 121.832634, 573.825806), 42),
- new ParticleSpawn(new Vec3Comparable(572.971008, 121.844513, 574.305359), 50),
- new ParticleSpawn(new Vec3Comparable(573.112061, 121.856392, 574.784912), 52),
- new ParticleSpawn(new Vec3Comparable(570.372192, 121.631874, 565.694946), 0)
- )),
- HandleCompassResult.SUCCESS,
- SolverState.NEED_SECOND_COMPASS);
-
- private final CompassUse precursorCityCompassUse2 = new CompassUse(
- DELAY_AFTER_FIRST_COMPASS_LAST_PARTICLE,
- new BlockPos(591, 136, 579),
- new ArrayList<>(Arrays.asList(
- new ParticleSpawn(new Vec3Comparable(590.847961, 137.589584, 579.776672), 192),
- new ParticleSpawn(new Vec3Comparable(590.918945, 137.528259, 580.267761), 50),
- new ParticleSpawn(new Vec3Comparable(590.985229, 137.465118, 580.759338), 56),
- new ParticleSpawn(new Vec3Comparable(591.051147, 137.401855, 581.250916), 47),
- new ParticleSpawn(new Vec3Comparable(591.117126, 137.338593, 581.742493), 47),
- new ParticleSpawn(new Vec3Comparable(591.183044, 137.275330, 582.234070), 49),
- new ParticleSpawn(new Vec3Comparable(591.249023, 137.212067, 582.725647), 60),
- new ParticleSpawn(new Vec3Comparable(591.314941, 137.148804, 583.217224), 55),
- new ParticleSpawn(new Vec3Comparable(591.380920, 137.085541, 583.708801), 47),
- new ParticleSpawn(new Vec3Comparable(591.446838, 137.022263, 584.200378), 50),
- new ParticleSpawn(new Vec3Comparable(591.512817, 136.959000, 584.691956), 39),
- new ParticleSpawn(new Vec3Comparable(591.578735, 136.895737, 585.183533), 53),
- new ParticleSpawn(new Vec3Comparable(591.644714, 136.832474, 585.675110), 53),
- new ParticleSpawn(new Vec3Comparable(591.710632, 136.769211, 586.166687), 45),
- new ParticleSpawn(new Vec3Comparable(591.776611, 136.705948, 586.658264), 79),
- new ParticleSpawn(new Vec3Comparable(591.842529, 136.642685, 587.149841), 20),
- new ParticleSpawn(new Vec3Comparable(591.908508, 136.579407, 587.641418), 62),
- new ParticleSpawn(new Vec3Comparable(591.974426, 136.516144, 588.132996), 48),
- new ParticleSpawn(new Vec3Comparable(592.040344, 136.452881, 588.624573), 40),
- new ParticleSpawn(new Vec3Comparable(592.106323, 136.389618, 589.116150), 51),
- new ParticleSpawn(new Vec3Comparable(590.766357, 137.556885, 579.791565), 0)
- )),
- HandleCompassResult.SUCCESS,
- SolverState.SOLVED);
-
- Vec3i precursorCitySolution = new Vec3i(604, 124, 681);
-
- private final CompassUse jungleCompassUse1 = new CompassUse(
- 1647744980313L,
- new BlockPos(454, 122, 459),
- new ArrayList<>(Arrays.asList(
- new ParticleSpawn(new Vec3Comparable(453.954895, 122.958122, 458.687866), 141),
- new ParticleSpawn(new Vec3Comparable(453.515991, 122.760010, 458.553314), 59),
- new ParticleSpawn(new Vec3Comparable(453.078156, 122.560112, 458.417877), 41),
- new ParticleSpawn(new Vec3Comparable(452.640381, 122.360123, 458.282349), 50),
- new ParticleSpawn(new Vec3Comparable(452.202606, 122.160133, 458.146851), 66),
- new ParticleSpawn(new Vec3Comparable(451.764832, 121.960136, 458.011353), 35),
- new ParticleSpawn(new Vec3Comparable(451.327057, 121.760147, 457.875854), 49),
- new ParticleSpawn(new Vec3Comparable(450.889313, 121.560150, 457.740356), 50),
- new ParticleSpawn(new Vec3Comparable(450.451538, 121.360161, 457.604858), 49),
- new ParticleSpawn(new Vec3Comparable(450.013763, 121.160172, 457.469330), 51),
- new ParticleSpawn(new Vec3Comparable(449.575989, 120.960175, 457.333832), 59),
- new ParticleSpawn(new Vec3Comparable(449.138214, 120.760185, 457.198334), 41),
- new ParticleSpawn(new Vec3Comparable(448.700439, 120.560196, 457.062836), 55),
- new ParticleSpawn(new Vec3Comparable(448.262695, 120.360199, 456.927338), 50),
- new ParticleSpawn(new Vec3Comparable(447.824921, 120.160210, 456.791840), 49),
- new ParticleSpawn(new Vec3Comparable(447.387146, 119.960213, 456.656311), 53),
- new ParticleSpawn(new Vec3Comparable(446.949371, 119.760223, 456.520813), 43),
- new ParticleSpawn(new Vec3Comparable(446.511597, 119.560234, 456.385315), 51),
- new ParticleSpawn(new Vec3Comparable(446.073853, 119.360237, 456.249817), 49),
- new ParticleSpawn(new Vec3Comparable(445.636078, 119.160248, 456.114319), 56),
- new ParticleSpawn(new Vec3Comparable(453.975647, 122.920158, 458.668488), 0)
- )),
- HandleCompassResult.SUCCESS,
- SolverState.NEED_SECOND_COMPASS);
-
- private final CompassUse jungleCompassUse2 = new CompassUse(
- DELAY_AFTER_FIRST_COMPASS_LAST_PARTICLE,
- new BlockPos(438, 126, 468),
- new ArrayList<>(Arrays.asList(
- new ParticleSpawn(new Vec3Comparable(437.701721, 127.395279, 467.455048), 139),
- new ParticleSpawn(new Vec3Comparable(437.297852, 127.161415, 467.275604), 35),
- new ParticleSpawn(new Vec3Comparable(436.895813, 126.927208, 467.092529), 68),
- new ParticleSpawn(new Vec3Comparable(436.493896, 126.692986, 466.909241), 41),
- new ParticleSpawn(new Vec3Comparable(436.091980, 126.458763, 466.725952), 54),
- new ParticleSpawn(new Vec3Comparable(435.690033, 126.224533, 466.542664), 39),
- new ParticleSpawn(new Vec3Comparable(435.288116, 125.990311, 466.359375), 52),
- new ParticleSpawn(new Vec3Comparable(434.886200, 125.756088, 466.176086), 66),
- new ParticleSpawn(new Vec3Comparable(434.484283, 125.521866, 465.992767), 40),
- new ParticleSpawn(new Vec3Comparable(434.082367, 125.287636, 465.809479), 41),
- new ParticleSpawn(new Vec3Comparable(433.680420, 125.053413, 465.626190), 50),
- new ParticleSpawn(new Vec3Comparable(433.278503, 124.819191, 465.442902), 59),
- new ParticleSpawn(new Vec3Comparable(432.876587, 124.584969, 465.259613), 54),
- new ParticleSpawn(new Vec3Comparable(432.474670, 124.350746, 465.076294), 38),
- new ParticleSpawn(new Vec3Comparable(432.072723, 124.116516, 464.893005), 63),
- new ParticleSpawn(new Vec3Comparable(431.670807, 123.882294, 464.709717), 36),
- new ParticleSpawn(new Vec3Comparable(431.268890, 123.648071, 464.526428), 64),
- new ParticleSpawn(new Vec3Comparable(430.866974, 123.413849, 464.343140), 48),
- new ParticleSpawn(new Vec3Comparable(430.465057, 123.179619, 464.159821), 53),
- new ParticleSpawn(new Vec3Comparable(430.063110, 122.945396, 463.976532), 46),
- new ParticleSpawn(new Vec3Comparable(437.732666, 127.385803, 467.381592), 1)
- )),
- HandleCompassResult.SUCCESS,
- SolverState.SOLVED);
-
- Vec3i jungleSolution = new Vec3i(343, 72, 424);
- Vec3i jungleSolutionTempleDoor = new Vec3i(
- jungleSolution.getX() - 57,
- jungleSolution.getY() + 36,
- jungleSolution.getZ() -21);
-
- private final CompassUse magmaCompassUse1 = new CompassUse(
- 1647745029814L,
- new BlockPos(462, 58, 550),
- new ArrayList<>(Arrays.asList(
- new ParticleSpawn(new Vec3Comparable(462.226898, 59.614380, 550.032654), 160),
- new ParticleSpawn(new Vec3Comparable(462.693848, 59.609089, 549.853943), 47),
- new ParticleSpawn(new Vec3Comparable(463.160706, 59.603809, 549.674988), 48),
- new ParticleSpawn(new Vec3Comparable(463.627533, 59.598526, 549.496033), 136),
- new ParticleSpawn(new Vec3Comparable(464.094391, 59.593246, 549.317017), 0),
- new ParticleSpawn(new Vec3Comparable(464.561218, 59.587963, 549.138062), 0),
- new ParticleSpawn(new Vec3Comparable(465.028076, 59.582684, 548.959106), 53),
- new ParticleSpawn(new Vec3Comparable(465.494904, 59.577400, 548.780090), 48),
- new ParticleSpawn(new Vec3Comparable(465.961761, 59.572117, 548.601135), 55),
- new ParticleSpawn(new Vec3Comparable(466.428589, 59.566837, 548.422180), 47),
- new ParticleSpawn(new Vec3Comparable(466.895416, 59.561554, 548.243164), 46),
- new ParticleSpawn(new Vec3Comparable(467.362274, 59.556274, 548.064209), 53),
- new ParticleSpawn(new Vec3Comparable(467.829102, 59.550991, 547.885254), 50),
- new ParticleSpawn(new Vec3Comparable(468.295959, 59.545712, 547.706238), 54),
- new ParticleSpawn(new Vec3Comparable(468.762787, 59.540428, 547.527283), 52),
- new ParticleSpawn(new Vec3Comparable(469.229645, 59.535145, 547.348328), 105),
- new ParticleSpawn(new Vec3Comparable(469.696472, 59.529865, 547.169312), 1),
- new ParticleSpawn(new Vec3Comparable(470.163300, 59.524582, 546.990356), 51),
- new ParticleSpawn(new Vec3Comparable(470.630157, 59.519302, 546.811401), 40),
- new ParticleSpawn(new Vec3Comparable(471.096985, 59.514019, 546.632385), 49),
- new ParticleSpawn(new Vec3Comparable(462.221954, 59.614719, 550.019165), 0)
- )),
- HandleCompassResult.SUCCESS,
- SolverState.NEED_SECOND_COMPASS);
-
- private final CompassUse magmaCompassUse2 = new CompassUse(
- DELAY_AFTER_FIRST_COMPASS_LAST_PARTICLE,
- new BlockPos(449, 53, 556),
- new ArrayList<>(Arrays.asList(
- new ParticleSpawn(new Vec3Comparable(449.120911, 54.624340, 556.108948), 204),
- new ParticleSpawn(new Vec3Comparable(449.587433, 54.627399, 555.929138), 102),
- new ParticleSpawn(new Vec3Comparable(450.053741, 54.630432, 555.748657), 0),
- new ParticleSpawn(new Vec3Comparable(450.520020, 54.633465, 555.568237), 62),
- new ParticleSpawn(new Vec3Comparable(450.986298, 54.636497, 555.387756), 38),
- new ParticleSpawn(new Vec3Comparable(451.452606, 54.639530, 555.207275), 48),
- new ParticleSpawn(new Vec3Comparable(451.918884, 54.642563, 555.026794), 63),
- new ParticleSpawn(new Vec3Comparable(452.385162, 54.645596, 554.846375), 52),
- new ParticleSpawn(new Vec3Comparable(452.851471, 54.648628, 554.665894), 35),
- new ParticleSpawn(new Vec3Comparable(453.317749, 54.651661, 554.485413), 53),
- new ParticleSpawn(new Vec3Comparable(453.784027, 54.654694, 554.304993), 54),
- new ParticleSpawn(new Vec3Comparable(454.250305, 54.657726, 554.124512), 50),
- new ParticleSpawn(new Vec3Comparable(454.716614, 54.660759, 553.944031), 55),
- new ParticleSpawn(new Vec3Comparable(455.182892, 54.663792, 553.763550), 49),
- new ParticleSpawn(new Vec3Comparable(455.649170, 54.666824, 553.583130), 41),
- new ParticleSpawn(new Vec3Comparable(456.115479, 54.669857, 553.402649), 48),
- new ParticleSpawn(new Vec3Comparable(456.581757, 54.672890, 553.222168), 54),
- new ParticleSpawn(new Vec3Comparable(457.048035, 54.675922, 553.041687), 45),
- new ParticleSpawn(new Vec3Comparable(457.514313, 54.678959, 552.861267), 55),
- new ParticleSpawn(new Vec3Comparable(449.110443, 54.623035, 556.079163), 49)
- )),
- HandleCompassResult.SUCCESS,
- SolverState.SOLVED);
-
- Vec3i magmaSolution = new Vec3i(737, 56, 444);
-
- Vec3Comparable kingMinesOrNucleusCoordsInRemnants = new Vec3Comparable(604, 100, 681);
- Vec3Comparable odawaSolution = new Vec3Comparable(349, 110, 390);
-
- private final CompassUse nucleusCompass = new CompassUse(
- 1647745029814L,
- new BlockPos(512, 106, 512),
- null,
- HandleCompassResult.PLAYER_IN_NUCLEUS,
- SolverState.NOT_STARTED);
-
- private void resetSolverState() {
- solver.initWorld();
- systemTimeMillis = 0;
- solver.currentTimeMillis = () -> (systemTimeMillis);
- // These must be overridden for all test cases or an exception will be thrown when
- // data that is only present when running in the context of Minecraft is accessed.
- solver.keyInInventory = () -> false;
- solver.kingsScentPresent = () -> false;
- solver.foundCrystals = () -> EnumSet.noneOf(Crystal.class);
- }
-
- @BeforeEach
- void setUp() {
- NEUDebugLogger.logMethod = CrystalWishingCompassSolverTest::neuDebugLog;
- NEUDebugLogger.allFlagsEnabled = true;
- resetSolverState();
- }
-
- private void checkSolution(Solution solution) {
- int index = 0;
- for (CompassUse compassUse : solution.compassUses) {
- systemTimeMillis += compassUse.timeIncrementMillis;
- HandleCompassResult handleCompassResult = solver.handleCompassUse(compassUse.playerPos);
- Assertions.assertEquals(compassUse.expectedHandleCompassUseResult,
- handleCompassResult,
- "CompassUse index " + index);
-
- for (ParticleSpawn particle : compassUse.particles) {
- systemTimeMillis += particle.timeIncrementMillis;
- solver.solveUsingParticle(
- particle.spawnLocation.xCoord,
- particle.spawnLocation.yCoord,
- particle.spawnLocation.zCoord,
- systemTimeMillis);
- }
-
- Assertions.assertEquals(compassUse.expectedSolverState,
- solver.getSolverState(),
- "CompassUse index " + index);
- if (compassUse.expectedSolverState == SolverState.SOLVED) {
- Assertions.assertEquals(solution.expectedSolutionCoords,
- solver.getSolutionCoords());
- }
-
- index++;
- }
- }
-
- @Test
- void first_compass_without_particles_sets_solver_state_to_processing_first_use() {
- // Arrange
- CompassUse compassUse = new CompassUse(minesOfDivanCompassUse1);
- compassUse.particles.clear();
- compassUse.expectedSolverState = SolverState.PROCESSING_FIRST_USE;
-
- Solution solution = new Solution(
- new ArrayList<>(Collections.singletonList(compassUse)),
- Vec3i.NULL_VECTOR);
-
- // Act & Assert
- checkSolution(solution);
- }
-
- @Test
- void new_compass_resets_processing_first_use_state_after_timeout() {
- // Arrange
- CompassUse processingFirstUseCompassUse = new CompassUse(minesOfDivanCompassUse1);
- processingFirstUseCompassUse.particles.clear();
- processingFirstUseCompassUse.expectedSolverState = SolverState.PROCESSING_FIRST_USE;
- Solution processingFirstUseSolution = new Solution(
- new ArrayList<>(Collections.singletonList(processingFirstUseCompassUse)),
- Vec3i.NULL_VECTOR);
- checkSolution(processingFirstUseSolution);
- Assertions.assertEquals(SolverState.PROCESSING_FIRST_USE, solver.getSolverState());
-
- CompassUse resetStateCompassUse = new CompassUse(jungleCompassUse1);
- resetStateCompassUse.timeIncrementMillis = ALL_PARTICLES_MAX_MILLIS + 1;
- resetStateCompassUse.expectedHandleCompassUseResult = HandleCompassResult.NO_PARTICLES_FOR_PREVIOUS_COMPASS;
- resetStateCompassUse.expectedSolverState = SolverState.FAILED_TIMEOUT_NO_REPEATING;
- Solution goodSolution = new Solution(
- new ArrayList<>(Collections.singletonList(resetStateCompassUse)),
- Vec3i.NULL_VECTOR);
-
- // Act & Assert
- checkSolution(goodSolution);
- }
-
- @Test
- void first_compass_with_repeating_particles_sets_state_to_need_second_compass() {
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Collections.singletonList(minesOfDivanCompassUse1)),
- Vec3i.NULL_VECTOR);
-
- // Act & Assert
- checkSolution(solution);
- }
-
- @Test
- void first_compass_in_nucleus_sets_state_to_player_in_nucleus() {
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Collections.singletonList(nucleusCompass)),
- Vec3i.NULL_VECTOR);
-
- // Act & Assert
- checkSolution(solution);
- }
-
- @Test
- void use_while_handling_previous_returns_still_processing_first_use() {
- // Arrange
- CompassUse compassUse1 = new CompassUse(
- 1647528732979L,
- new BlockPos(754, 137, 239),
- new ArrayList<>(Collections.singletonList(
- new ParticleSpawn(new Vec3Comparable(754.358459, 138.536407, 239.200928), 137)
- )),
- HandleCompassResult.SUCCESS,
- SolverState.PROCESSING_FIRST_USE);
-
- // STILL_PROCESSING_FIRST_USE is expected instead of LOCATION_TOO_CLOSE since the solver
- // isn't ready for the second compass use, which includes the location check
- CompassUse compassUse2 = new CompassUse(compassUse1);
- compassUse2.expectedHandleCompassUseResult = HandleCompassResult.STILL_PROCESSING_PRIOR_USE;
- compassUse2.timeIncrementMillis = 500;
-
- Solution solution = new Solution(
- new ArrayList<>(Arrays.asList(compassUse1, compassUse2)),
- Vec3i.NULL_VECTOR);
-
- // Act & Assert
- checkSolution(solution);
- }
-
- @Test
- void missing_repeating_particles_sets_state_to_failed_timeout_no_repeating() {
- CompassUse compassUse = new CompassUse(minesOfDivanCompassUse1);
- compassUse.particles.remove(compassUse.particles.size()-1);
- compassUse.particles.get(compassUse.particles.size()-1).timeIncrementMillis += ALL_PARTICLES_MAX_MILLIS;
- compassUse.expectedSolverState = SolverState.FAILED_TIMEOUT_NO_REPEATING;
-
- Solution solution = new Solution(
- new ArrayList<>(Collections.singletonList(compassUse)),
- Vec3i.NULL_VECTOR);
-
- // Act & Assert
- checkSolution(solution);
- }
-
- @Test
- void compasses_too_close_returns_location_too_close_and_solver_state_is_still_need_second_compass() {
- // Arrange
- CompassUse secondCompassUse = new CompassUse(
- DELAY_AFTER_FIRST_COMPASS_LAST_PARTICLE,
- minesOfDivanCompassUse1.playerPos.add(2, 2, 2),
- null,
- HandleCompassResult.LOCATION_TOO_CLOSE,
- SolverState.NEED_SECOND_COMPASS
- );
-
- Solution solution = new Solution(
- new ArrayList<>(Arrays.asList(minesOfDivanCompassUse1, secondCompassUse)),
- Vec3i.NULL_VECTOR);
-
- // Act & Assert
- checkSolution(solution);
- }
-
- @Test
- void second_compass_sets_solver_state_to_processing_second_use() {
- // Arrange
- CompassUse secondCompassUse = new CompassUse(minesOfDivanCompassUse2);
- secondCompassUse.expectedSolverState = SolverState.PROCESSING_SECOND_USE;
- secondCompassUse.particles.clear();
-
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Arrays.asList(minesOfDivanCompassUse1, minesOfDivanCompassUse2)),
- minesOfDivanSolution
- );
-
- // Act & Assert
- checkSolution(solution);
- }
-
- @Test
- void second_compass_with_repeating_particles_sets_state_to_solved() {
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Arrays.asList(minesOfDivanCompassUse1, minesOfDivanCompassUse2)),
- minesOfDivanSolution
- );
-
- // Act & Assert
- checkSolution(solution);
- }
-
- @Test
- void particles_from_first_compass_are_ignored_by_second_compass() {
- // Arrange
- CompassUse compassUse2 = new CompassUse(minesOfDivanCompassUse2);
- compassUse2.particles.add(0, minesOfDivanCompassUse1.particles.get(0));
- Solution solution = new Solution(
- new ArrayList<>(Arrays.asList(minesOfDivanCompassUse1, compassUse2)),
- minesOfDivanSolution
- );
-
- // Act & Assert
- checkSolution(solution);
- }
-
- private void execInvalidParticlesInvalidSolution() {
- // Arrange
- CompassUse compassUse2 = new CompassUse(minesOfDivanCompassUse2);
-
- // reverse the direction of the particles, moving the repeat particle
- // to "new" end
- compassUse2.particles.remove(compassUse2.particles.size()-1);
- Collections.reverse(compassUse2.particles);
- // add a new repeat particle
- compassUse2.particles.add(new ParticleSpawn(compassUse2.particles.get(0)));
-
- // Adjust the player position
- compassUse2.playerPos = new BlockPos(compassUse2.particles.get(0).spawnLocation);
- compassUse2.expectedSolverState = SolverState.FAILED_INVALID_SOLUTION;
- Solution solution = new Solution(
- new ArrayList<>(Arrays.asList(minesOfDivanCompassUse1, compassUse2)),
- Vec3i.NULL_VECTOR);
-
- // Act & Assert
- checkSolution(solution);
- }
-
- @Test
- void second_compass_with_inverted_particles_sets_state_to_invalid_solution() {
- // Arrange, Act, and Assert
- execInvalidParticlesInvalidSolution();
- }
-
- @Test
- void solution_outside_hollows_sets_state_to_invalid_solution() {
- // Arrange
- CompassUse compassUse1 = new CompassUse(minesOfDivanCompassUse1);
- CompassUse compassUse2 = new CompassUse(minesOfDivanCompassUse2);
- Vec3 offset = new Vec3(0.0, 200.0, 0.0);
-
- compassUse1.playerPos = compassUse1.playerPos.add(offset.xCoord, offset.yCoord, offset.zCoord);
- for (ParticleSpawn particle : compassUse1.particles) {
- particle.spawnLocation = particle.spawnLocation.add(offset);
- }
-
- compassUse2.playerPos = compassUse2.playerPos.add(offset.xCoord, offset.yCoord, offset.zCoord);
- for (ParticleSpawn particle : compassUse2.particles) {
- particle.spawnLocation = particle.spawnLocation.add(offset);
- }
- compassUse2.expectedSolverState = SolverState.FAILED_INVALID_SOLUTION;
-
- Solution solution = new Solution(
- new ArrayList<>(Arrays.asList(compassUse1, compassUse2)),
- Vec3i.NULL_VECTOR);
-
- // Act & Assert
- checkSolution(solution);
- }
-
- @Test
- void second_solution_can_be_solved_after_state_is_solved() {
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Arrays.asList(minesOfDivanCompassUse1, minesOfDivanCompassUse2)),
- minesOfDivanSolution
- );
- checkSolution(solution);
-
- Solution solution2 = new Solution(
- new ArrayList<>(Arrays.asList(precursorCityCompassUse1, precursorCityCompassUse2)),
- precursorCitySolution
- );
-
- // Act & Assert
- checkSolution(solution2);
- }
-
- @Test
- void second_solution_can_be_solved_after_state_is_failed() {
- // Arrange
- execInvalidParticlesInvalidSolution();
- Assertions.assertEquals(solver.getSolverState(), SolverState.FAILED_INVALID_SOLUTION);
-
- Solution solution2 = new Solution(
- new ArrayList<>(Arrays.asList(precursorCityCompassUse1, precursorCityCompassUse2)),
- precursorCitySolution
- );
-
- // Act & Assert
- checkSolution(solution2);
- }
-
- @Test
- void distant_particles_are_ignored() {
- // Arrange
- CompassUse compassUse = new CompassUse(minesOfDivanCompassUse1);
- compassUse.particles.get(2).spawnLocation.addVector(100.0, 100.0, 100.0);
- Solution solution = new Solution(
- new ArrayList<>(Collections.singletonList(minesOfDivanCompassUse1)),
- Vec3i.NULL_VECTOR);
-
- // Act & Assert
- checkSolution(solution);
- }
-
- @Test
- void possible_targets_includes_queen_and_excludes_king_when_kings_scent_is_present() {
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Collections.singletonList(goblinHoldoutCompassUse1)),
- Vec3i.NULL_VECTOR);
- solver.kingsScentPresent = () -> true;
-
- // Act
- checkSolution(solution);
- EnumSet<CompassTarget> targets = solver.getPossibleTargets();
-
- // Assert
- Assertions.assertTrue(targets.contains(CompassTarget.GOBLIN_QUEEN));
- Assertions.assertFalse(targets.contains(CompassTarget.GOBLIN_KING));
- }
-
- @Test
- void possible_targets_excludes_king_and_includes_queen_when_kings_scent_is_not_present() {
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Collections.singletonList(goblinHoldoutCompassUse1)),
- Vec3i.NULL_VECTOR);
- solver.kingsScentPresent = () -> false;
-
- // Act
- checkSolution(solution);
- EnumSet<CompassTarget> targets = solver.getPossibleTargets();
-
- // Assert
- Assertions.assertFalse(targets.contains(CompassTarget.GOBLIN_QUEEN));
- Assertions.assertTrue(targets.contains(CompassTarget.GOBLIN_KING));
- }
-
- @Test
- void possible_targets_excludes_odawa_and_includes_temple_when_key_in_inventory() {
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Collections.singletonList(jungleCompassUse1)),
- Vec3i.NULL_VECTOR);
- solver.keyInInventory = () -> true;
-
- // Act
- checkSolution(solution);
- EnumSet<CompassTarget> targets = solver.getPossibleTargets();
-
- // Assert
- Assertions.assertFalse(targets.contains(CompassTarget.ODAWA));
- Assertions.assertTrue(targets.contains(CompassTarget.JUNGLE_TEMPLE));
- }
-
- @Test
- void possible_targets_includes_odawa_and_excludes_temple_when_key_not_in_inventory() {
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Collections.singletonList(jungleCompassUse1)),
- Vec3i.NULL_VECTOR);
- solver.keyInInventory = () -> false;
-
- // Act
- checkSolution(solution);
- EnumSet<CompassTarget> targets = solver.getPossibleTargets();
-
- // Assert
- Assertions.assertTrue(targets.contains(CompassTarget.ODAWA));
- Assertions.assertFalse(targets.contains(CompassTarget.JUNGLE_TEMPLE));
- }
-
- @Test
- void possible_targets_only_contains_city_and_nucleus_when_in_remnants_without_sapphire_crystal() {
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Collections.singletonList(precursorCityCompassUse1)),
- Vec3i.NULL_VECTOR);
-
- // Act
- checkSolution(solution);
- EnumSet<CompassTarget> targets = solver.getPossibleTargets();
-
- // Assert
- Assertions.assertTrue(targets.contains(CompassTarget.PRECURSOR_CITY));
- Assertions.assertTrue(targets.contains(CompassTarget.CRYSTAL_NUCLEUS));
- Assertions.assertEquals(2, targets.size());
- }
-
- @Test
- void possible_targets_only_contains_mines_and_nucleus_when_in_deposits_without_jade_crystal() {
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Collections.singletonList(minesOfDivanCompassUse1)),
- Vec3i.NULL_VECTOR);
-
- // Act
- checkSolution(solution);
- EnumSet<CompassTarget> targets = solver.getPossibleTargets();
-
- // Assert
- Assertions.assertTrue(targets.contains(CompassTarget.MINES_OF_DIVAN));
- Assertions.assertTrue(targets.contains(CompassTarget.CRYSTAL_NUCLEUS));
- Assertions.assertEquals(2, targets.size());
- }
-
- @Test
- void possible_targets_only_contains_king_or_queen_and_nucleus_when_in_holdout_without_crystal() {
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Collections.singletonList(goblinHoldoutCompassUse1)),
- Vec3i.NULL_VECTOR);
-
- // Act
- checkSolution(solution);
- EnumSet<CompassTarget> targets = solver.getPossibleTargets();
-
- // Assert
- Assertions.assertTrue(targets.contains(CompassTarget.GOBLIN_KING) ||
- targets.contains(CompassTarget.GOBLIN_QUEEN));
- Assertions.assertTrue(targets.contains(CompassTarget.CRYSTAL_NUCLEUS));
- Assertions.assertEquals(2, targets.size());
- }
-
- @Test
- void possible_targets_only_contains_king_and_odawa_and_nucleus_when_in_jungle_without_crystal_or_key() {
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Collections.singletonList(jungleCompassUse1)),
- Vec3i.NULL_VECTOR);
-
- // Act
- checkSolution(solution);
- EnumSet<CompassTarget> targets = solver.getPossibleTargets();
-
- // Assert
- Assertions.assertTrue(targets.contains(CompassTarget.GOBLIN_KING));
- Assertions.assertTrue(targets.contains(CompassTarget.ODAWA));
- Assertions.assertTrue(targets.contains(CompassTarget.CRYSTAL_NUCLEUS));
- Assertions.assertEquals(3, targets.size());
- }
-
- @Test
- void possible_targets_only_contains_bal_and_nucleus_when_in_magma_fields_without_crystal() {
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Collections.singletonList(magmaCompassUse1)),
- Vec3i.NULL_VECTOR);
-
- // Act
- checkSolution(solution);
- EnumSet<CompassTarget> targets = solver.getPossibleTargets();
-
- // Assert
- Assertions.assertTrue(targets.contains(CompassTarget.BAL));
- Assertions.assertTrue(targets.contains(CompassTarget.CRYSTAL_NUCLEUS));
- Assertions.assertEquals(2, targets.size());
- }
-
- private void CheckExcludedTargetsForCrystals(
- CompassUse compassUseToExecute,
- ArrayList<CompassTarget> excludedTargets,
- EnumSet<Crystal> foundCrystals) {
- // Arrange
- EnumSet<CompassTarget> targets;
- Solution solution = new Solution(
- new ArrayList<>(Collections.singletonList(compassUseToExecute)),
- Vec3i.NULL_VECTOR);
-
- // Act
- checkSolution(solution);
- targets = solver.getPossibleTargets();
- boolean targetFound = false;
- for (CompassTarget target : excludedTargets) {
- if (targets.contains(target)) {
- targetFound = true;
- break;
- }
- }
- Assertions.assertTrue(targetFound);
-
- resetSolverState();
- solver.foundCrystals = () -> foundCrystals;
- checkSolution(solution);
- targets = solver.getPossibleTargets();
-
- // Assert
- for (CompassTarget target : excludedTargets) {
- Assertions.assertFalse(targets.contains(target));
- }
- }
-
- @Test
- void possible_targets_excludes_king_and_queen_when_amber_crystal_found() {
- ArrayList<CompassTarget> excludedTargets = new ArrayList<>(Arrays.asList(
- CompassTarget.GOBLIN_KING,
- CompassTarget.GOBLIN_QUEEN
- ));
- CheckExcludedTargetsForCrystals(goblinHoldoutCompassUse1, excludedTargets, EnumSet.of(Crystal.AMBER));
- }
-
- @Test
- void possible_targets_excludes_odawa_and_temple_when_amethyst_crystal_found() {
- ArrayList<CompassTarget> excludedTargets = new ArrayList<>(Arrays.asList(
- CompassTarget.ODAWA,
- CompassTarget.JUNGLE_TEMPLE));
- CheckExcludedTargetsForCrystals(jungleCompassUse1, excludedTargets, EnumSet.of(Crystal.AMETHYST));
- }
-
- @Test
- void possible_targets_excludes_mines_when_jade_crystal_found() {
- ArrayList<CompassTarget> excludedTargets = new ArrayList<>(Collections.singletonList(
- CompassTarget.MINES_OF_DIVAN));
- CheckExcludedTargetsForCrystals(minesOfDivanCompassUse1, excludedTargets, EnumSet.of(Crystal.JADE));
- }
-
- @Test
- void possible_targets_excludes_city_when_sapphire_crystal_found() {
- ArrayList<CompassTarget> excludedTargets = new ArrayList<>(Collections.singletonList(
- CompassTarget.PRECURSOR_CITY));
- CheckExcludedTargetsForCrystals(precursorCityCompassUse1, excludedTargets, EnumSet.of(Crystal.SAPPHIRE));
- }
-
- @Test
- void possible_targets_excludes_bal_when_topaz_crystal_found() {
- ArrayList<CompassTarget> excludedTargets = new ArrayList<>(Collections.singletonList(
- CompassTarget.BAL));
- CheckExcludedTargetsForCrystals(magmaCompassUse1, excludedTargets, EnumSet.of(Crystal.TOPAZ));
- }
-
- @Test
- void solver_resets_when_possible_targets_change_based_on_found_crystals() {
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Collections.singletonList(minesOfDivanCompassUse1)),
- Vec3i.NULL_VECTOR);
-
- // Act
- checkSolution(solution);
- systemTimeMillis += minesOfDivanCompassUse2.timeIncrementMillis;
- solver.foundCrystals = () -> EnumSet.of(Crystal.JADE);
- HandleCompassResult handleCompassResult = solver.handleCompassUse(minesOfDivanCompassUse2.playerPos);
-
- // Assert
- Assertions.assertEquals(HandleCompassResult.POSSIBLE_TARGETS_CHANGED, handleCompassResult);
- Assertions.assertEquals(SolverState.NOT_STARTED, solver.getSolverState());
- }
-
- @Test
- void solver_resets_when_possible_targets_change_based_on_location() {
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Collections.singletonList(minesOfDivanCompassUse1)),
- Vec3i.NULL_VECTOR);
-
- // Act
- checkSolution(solution);
- systemTimeMillis += minesOfDivanCompassUse2.timeIncrementMillis;
- BlockPos newLocation = minesOfDivanCompassUse2.playerPos.add(-400, 0 ,0);
- HandleCompassResult handleCompassResult = solver.handleCompassUse(newLocation);
-
- // Assert
- Assertions.assertEquals(HandleCompassResult.POSSIBLE_TARGETS_CHANGED, handleCompassResult);
- Assertions.assertEquals(SolverState.NOT_STARTED, solver.getSolverState());
- }
-
- @Test
- void mines_of_divan_solution_is_solved() {
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Arrays.asList(minesOfDivanCompassUse1, minesOfDivanCompassUse2)),
- minesOfDivanSolution
- );
-
- // Act & Assert
- checkSolution(solution);
- }
-
- @Test
- void jungle_temple_solution_with_key_in_inventory_is_solved() {
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Arrays.asList(jungleCompassUse1, jungleCompassUse2)),
- jungleSolutionTempleDoor
- );
- solver.keyInInventory = () -> true;
-
- // Act & Assert
- checkSolution(solution);
- }
-
- @Test
- void jungle_temple_solution_is_solved() {
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Arrays.asList(jungleCompassUse1, jungleCompassUse2)),
- jungleSolution
- );
-
- // Act & Assert
- checkSolution(solution);
- }
-
- @Test
- void precursor_city_solution_is_solved() {
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Arrays.asList(precursorCityCompassUse1, precursorCityCompassUse2)),
- precursorCitySolution
- );
-
- // Act & Assert
- checkSolution(solution);
- }
-
- @Test
- void goblin_king_solution_is_solved() {
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Arrays.asList(goblinHoldoutCompassUse1, goblinHoldoutCompassUse2)),
- goblinHoldoutKingSolution
- );
-
- // Act & Assert
- checkSolution(solution);
- }
-
- @Test
- void bal_solution_is_solved() {
- // Arrange
- Solution solution = new Solution(
- new ArrayList<>(Arrays.asList(magmaCompassUse1, magmaCompassUse2)),
- magmaSolution
- );
-
- // Act & Assert
- checkSolution(solution);
- }
-
- EnumSet<CompassTarget> GetSolutionTargetsHelper(
- EnumSet<CompassTarget> possibleTargets,
- Vec3Comparable solutionCoords,
- int expectedSolutionCount) {
- EnumSet<CompassTarget> solutionTargets =
- CrystalWishingCompassSolver.getSolutionTargets(possibleTargets, solutionCoords);
- Assertions.assertEquals(expectedSolutionCount, solutionTargets.size());
- return solutionTargets;
- }
-
- @Test
- void solutionPossibleTargets_removes_nucleus_when_coords_not_in_nucleus() {
- // Arrange & Act
- EnumSet<CompassTarget> solutionTargets = GetSolutionTargetsHelper(
- EnumSet.allOf(CompassTarget.class),
- new Vec3Comparable(minesOfDivanSolution),
- 2);
-
- //Assert
- Assertions.assertFalse(solutionTargets.contains(CompassTarget.CRYSTAL_NUCLEUS));
- }
-
- @Test
- void solutionPossibleTargets_includes_adjacent_zones() {
- // Arrange & Act
- EnumSet<CompassTarget> solutionTargets = GetSolutionTargetsHelper(
- EnumSet.allOf(CompassTarget.class),
- kingMinesOrNucleusCoordsInRemnants,
- 2);
-
- //Assert
- Assertions.assertTrue(solutionTargets.contains(CompassTarget.GOBLIN_KING));
- Assertions.assertTrue(solutionTargets.contains(CompassTarget.MINES_OF_DIVAN));
- }
-
- @Test
- void solutionPossibleTargets_skips_y_filtering_when_single_possible_target() {
- // Arrange & Act
- EnumSet<CompassTarget> solutionTargets = GetSolutionTargetsHelper(
- EnumSet.of(CompassTarget.GOBLIN_QUEEN),
- new Vec3Comparable(goblinHoldoutKingSolution), // Coords not valid for queen
- 1);
-
- //Assert
- Assertions.assertTrue(solutionTargets.contains(CompassTarget.GOBLIN_QUEEN));
- }
-
- @Test
- void solutionPossibleTargets_still_filters_non_adjacent_when_single_possible_target() {
- // Arrange, Act and Assert
- GetSolutionTargetsHelper(
- EnumSet.of(CompassTarget.ODAWA),
- kingMinesOrNucleusCoordsInRemnants,
- 0);
- }
-
- @Test
- void solutionPossibleTargets_includes_king_based_on_y_coordinate() {
- // Arrange & Act
- EnumSet<CompassTarget> possibleTargets = EnumSet.allOf(CompassTarget.class);
- possibleTargets.remove(CompassTarget.ODAWA);
- EnumSet<CompassTarget> solutionTargets = GetSolutionTargetsHelper(
- possibleTargets,
- new Vec3Comparable(goblinHoldoutKingSolution),
- 1);
-
- //Assert
- Assertions.assertTrue(solutionTargets.contains(CompassTarget.GOBLIN_KING));
- }
-
- @Test
- void solutionPossibleTargets_includes_odawa_based_on_y_coordinate() {
- // Arrange & Act
- // Arrange & Act
- EnumSet<CompassTarget> possibleTargets = EnumSet.allOf(CompassTarget.class);
- possibleTargets.remove(CompassTarget.GOBLIN_KING);
- EnumSet<CompassTarget> solutionTargets = GetSolutionTargetsHelper(
- possibleTargets,
- new Vec3Comparable(odawaSolution),
- 1);
-
- //Assert
- Assertions.assertTrue(solutionTargets.contains(CompassTarget.ODAWA));
- }
-
- @Test
- void solutionPossibleTargets_includes_mines_based_on_y_coordinate() {
- // Arrange & Act
- EnumSet<CompassTarget> possibleTargets = EnumSet.allOf(CompassTarget.class);
- possibleTargets.remove(CompassTarget.ODAWA);
- EnumSet<CompassTarget> solutionTargets = GetSolutionTargetsHelper(
- possibleTargets,
- new Vec3Comparable(minesOfDivanSolution),
- 1);
-
- //Assert
- Assertions.assertTrue(solutionTargets.contains(CompassTarget.MINES_OF_DIVAN));
- }
-
- @Test
- void solutionPossibleTargets_includes_temple_based_on_y_coordinate() {
- // Arrange & Act
- EnumSet<CompassTarget> possibleTargets = EnumSet.allOf(CompassTarget.class);
- possibleTargets.remove(CompassTarget.BAL);
- possibleTargets.remove(CompassTarget.ODAWA);
- possibleTargets.remove(CompassTarget.GOBLIN_KING);
- EnumSet<CompassTarget> solutionTargets = GetSolutionTargetsHelper(
- possibleTargets,
- new Vec3Comparable(jungleSolution),
- 1);
-
- //Assert
- Assertions.assertTrue(solutionTargets.contains(CompassTarget.JUNGLE_TEMPLE));
- }
-
- @Test
- void solutionPossibleTargets_includes_queen_based_on_y_coordinate() {
- // Arrange & Act
- EnumSet<CompassTarget> possibleTargets = EnumSet.allOf(CompassTarget.class);
- possibleTargets.remove(CompassTarget.GOBLIN_KING);
- possibleTargets.remove(CompassTarget.ODAWA);
- EnumSet<CompassTarget> solutionTargets = GetSolutionTargetsHelper(
- possibleTargets,
- new Vec3Comparable(goblinHoldoutQueenSolution),
- 1);
-
- //Assert
- Assertions.assertTrue(solutionTargets.contains(CompassTarget.GOBLIN_QUEEN));
- }
-
- @Test
- void solutionPossibleTargets_includes_city_based_on_y_coordinate() {
- // Arrange & Act
- EnumSet<CompassTarget> possibleTargets = EnumSet.allOf(CompassTarget.class);
- possibleTargets.remove(CompassTarget.GOBLIN_KING);
- EnumSet<CompassTarget> solutionTargets = GetSolutionTargetsHelper(
- possibleTargets,
- new Vec3Comparable(precursorCitySolution),
- 1);
-
- //Assert
- Assertions.assertTrue(solutionTargets.contains(CompassTarget.PRECURSOR_CITY));
- }
-
- @Test
- void solutionPossibleTargets_includes_bal_based_on_y_coordinate() {
- // Arrange & Act
- EnumSet<CompassTarget> solutionTargets = GetSolutionTargetsHelper(
- EnumSet.allOf(CompassTarget.class),
- new Vec3Comparable(magmaSolution),
- 1);
-
- //Assert
- Assertions.assertTrue(solutionTargets.contains(CompassTarget.BAL));
- }
-
- // Represents a particle spawn, including:
- // - Milliseconds to increment the "system time" prior to spawn.
- // - The particle spawn location.
- static class ParticleSpawn {
- long timeIncrementMillis;
- Vec3Comparable spawnLocation;
-
- ParticleSpawn(Vec3Comparable spawnLocation, long timeIncrementMillis) {
- this.timeIncrementMillis = timeIncrementMillis;
- this.spawnLocation = spawnLocation;
- }
-
- ParticleSpawn(ParticleSpawn source) {
- timeIncrementMillis = source.timeIncrementMillis;
- spawnLocation = new Vec3Comparable(source.spawnLocation);
- }
- }
-
- // Represents a use of the wishing compass, including:
- // - Milliseconds to increment the "system time" prior to use.
- // - The player's position when the compass is used.
- // - The resulting set of particles
- // - The expected state of the wishing compass solver after this compass is used
- static class CompassUse {
- long timeIncrementMillis;
- BlockPos playerPos;
- ArrayList<ParticleSpawn> particles;
- HandleCompassResult expectedHandleCompassUseResult;
- SolverState expectedSolverState;
-
- CompassUse(long timeIncrementMillis,
- BlockPos playerPos,
- ArrayList<ParticleSpawn> particles,
- HandleCompassResult expectedHandleCompassUseResult,
- SolverState expectedState) {
- this.timeIncrementMillis = timeIncrementMillis;
- this.playerPos = playerPos;
- this.particles = particles != null ? particles : new ArrayList<>();
- this.expectedHandleCompassUseResult = expectedHandleCompassUseResult;
- this.expectedSolverState = expectedState;
- }
-
- CompassUse(CompassUse source) {
- this.timeIncrementMillis = source.timeIncrementMillis;
- this.playerPos = new BlockPos(source.playerPos);
- this.particles = new ArrayList<>(source.particles);
- this.expectedHandleCompassUseResult = source.expectedHandleCompassUseResult;
- this.expectedSolverState = source.expectedSolverState;
- }
- }
-
- static class Solution {
- ArrayList<CompassUse> compassUses;
- Vec3i expectedSolutionCoords;
-
- Solution(ArrayList<CompassUse> compassUses, Vec3i expectedSolutionCoords) {
- this.compassUses = compassUses;
- this.expectedSolutionCoords = new Vec3i(expectedSolutionCoords.getX(), expectedSolutionCoords.getY(), expectedSolutionCoords.getZ());
- }
- }
-
- private static void neuDebugLog(String message) {
- System.out.println(message);
- }
-}
diff --git a/src/test/resources/log4j2-test.xml b/src/test/resources/log4j2-test.xml
deleted file mode 100644
index 25209eae..00000000
--- a/src/test/resources/log4j2-test.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="WARN">
- <Appenders>
- <Console name="SysOut" target="SYSTEM_OUT">
- <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg{nolookups}%n" />
- </Console>
- </Appenders>
- <Loggers>
- <Root level="info">
- <filters>
- <MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL" />
- </filters>
- <AppenderRef ref="SysOut"/>
- </Root>
- </Loggers>
-</Configuration>