From ee300d371a670e5483f5bf983e43eff20f64e90d Mon Sep 17 00:00:00 2001 From: olim Date: Sun, 16 Jun 2024 21:35:39 +0100 Subject: replace crystal waypoints with mining lebels replace the use of crystal waypoints with mining labels so they can be read from the hole of the hollows --- .../skyblocker/skyblock/dwarven/CrystalsHud.java | 16 ++-- .../skyblock/dwarven/CrystalsLocationsManager.java | 28 +++---- .../skyblock/dwarven/CrystalsWaypoint.java | 98 ---------------------- .../skyblocker/skyblock/dwarven/MetalDetector.java | 13 ++- .../skyblock/dwarven/MiningLocationLabel.java | 61 ++++++++++++++ 5 files changed, 92 insertions(+), 124 deletions(-) delete mode 100644 src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsWaypoint.java (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsHud.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsHud.java index 7f4dbdbf..01d83b88 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsHud.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsHud.java @@ -72,19 +72,19 @@ public class CrystalsHud { //if enabled add waypoint locations to map if (SkyblockerConfigManager.get().mining.crystalsHud.showLocations) { - Map ActiveWaypoints = CrystalsLocationsManager.activeWaypoints; + Map ActiveWaypoints = CrystalsLocationsManager.activeWaypoints; - for (CrystalsWaypoint waypoint : ActiveWaypoints.values()) { - Color waypointColor = waypoint.category.color; - Vector2ic renderPos = transformLocation(waypoint.pos.getX(), waypoint.pos.getZ()); + for (MiningLocationLabel waypoint : ActiveWaypoints.values()) { + int waypointColor = waypoint.category().getColor(); + Vector2ic renderPos = transformLocation(waypoint.centerPos().getX(), waypoint.centerPos().getZ()); int locationSize = SkyblockerConfigManager.get().mining.crystalsHud.locationSize; - if (SMALL_LOCATIONS.contains(waypoint.name.getString())) {//if small location half the location size + if (SMALL_LOCATIONS.contains(waypoint.category().getName())) {//if small location half the location size locationSize /= 2; } //fill square of size locationSize around the coordinates of the location - context.fill(renderPos.x() - locationSize / 2, renderPos.y() - locationSize / 2, renderPos.x() + locationSize / 2, renderPos.y() + locationSize / 2, waypointColor.getRGB()); + context.fill(renderPos.x() - locationSize / 2, renderPos.y() - locationSize / 2, renderPos.x() + locationSize / 2, renderPos.y() + locationSize / 2, waypointColor); } } @@ -92,7 +92,7 @@ public class CrystalsHud { if (CLIENT.player == null || CLIENT.getNetworkHandler() == null) { return; } - + //get player location double playerX = CLIENT.player.getX(); double playerZ = CLIENT.player.getZ(); @@ -109,8 +109,6 @@ public class CrystalsHud { //draw marker on map context.drawTexture(MAP_ICON, 0, 0, 2, 0, 5, 7, 8, 8); - - //todo add direction (can not work out how to rotate) matrices.pop(); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java index 83167c18..9bed7d50 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java @@ -25,6 +25,7 @@ import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.util.Formatting; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; import org.slf4j.Logger; import java.awt.*; @@ -52,12 +53,12 @@ public class CrystalsLocationsManager { private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); /** - * A look-up table to convert between location names and waypoint in the {@link CrystalsWaypoint.Category} values. + * A look-up table to convert between location names and waypoint in the {@link MiningLocationLabel.CrystalHollowsLocationsCategory} values. */ - private static final Map WAYPOINT_LOCATIONS = Arrays.stream(CrystalsWaypoint.Category.values()).collect(Collectors.toMap(CrystalsWaypoint.Category::toString, Function.identity())); + private static final Map WAYPOINT_LOCATIONS = Arrays.stream(MiningLocationLabel.CrystalHollowsLocationsCategory.values()).collect(Collectors.toMap(MiningLocationLabel.CrystalHollowsLocationsCategory::getName, Function.identity())); private static final Pattern TEXT_CWORDS_PATTERN = Pattern.compile("([0-9][0-9][0-9]) ([0-9][0-9][0-9]?) ([0-9][0-9][0-9])"); - protected static Map activeWaypoints = new HashMap<>(); + protected static Map activeWaypoints = new HashMap<>(); public static void init() { // Crystal Hollows Waypoints @@ -141,8 +142,8 @@ public class CrystalsLocationsManager { protected static Text getSetLocationMessage(String location, BlockPos blockPos) { MutableText text = Constants.PREFIX.get(); text.append(Text.literal("Added waypoint for ")); - Color locationColor = WAYPOINT_LOCATIONS.get(location).color; - text.append(Text.literal(location).withColor(locationColor.getRGB())); + int locationColor = WAYPOINT_LOCATIONS.get(location).getColor(); + text.append(Text.literal(location).withColor(locationColor)); text.append(Text.literal(" at : " + blockPos.getX() + " " + blockPos.getY() + " " + blockPos.getZ() + ".")); return text; @@ -152,8 +153,8 @@ public class CrystalsLocationsManager { MutableText text = Constants.PREFIX.get(); for (String waypointLocation : WAYPOINT_LOCATIONS.keySet()) { - Color locationColor = WAYPOINT_LOCATIONS.get(waypointLocation).color; - text.append(Text.literal("[" + waypointLocation + "]").withColor(locationColor.getRGB()).styled(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/skyblocker crystalWaypoints " + location + " " + waypointLocation)))); + int locationColor = WAYPOINT_LOCATIONS.get(waypointLocation).getColor(); + text.append(Text.literal("[" + waypointLocation + "]").withColor(locationColor).styled(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/skyblocker crystalWaypoints " + location + " " + waypointLocation)))); } return text; @@ -178,7 +179,7 @@ public class CrystalsLocationsManager { public static int shareWaypoint(String place) { if (activeWaypoints.containsKey(place)) { - BlockPos pos = activeWaypoints.get(place).pos; + Vec3d pos = activeWaypoints.get(place).centerPos(); MessageScheduler.INSTANCE.sendMessageAfterCooldown(Constants.PREFIX.get().getString() + " " + place + ": " + pos.getX() + ", " + pos.getY() + ", " + pos.getZ()); } else { //send fail message @@ -193,17 +194,16 @@ public class CrystalsLocationsManager { private static void addCustomWaypoint(String waypointName, BlockPos pos) { - CrystalsWaypoint.Category category = WAYPOINT_LOCATIONS.get(waypointName); - CrystalsWaypoint waypoint = new CrystalsWaypoint(category, Text.literal(waypointName), pos); + MiningLocationLabel.CrystalHollowsLocationsCategory category = WAYPOINT_LOCATIONS.get(waypointName); + MiningLocationLabel waypoint = new MiningLocationLabel(category, pos); activeWaypoints.put(waypointName, waypoint); } public static void render(WorldRenderContext context) { if (SkyblockerConfigManager.get().mining.crystalsWaypoints.enabled) { - for (CrystalsWaypoint crystalsWaypoint : activeWaypoints.values()) { - if (crystalsWaypoint.shouldRender()) { - crystalsWaypoint.render(context); - } + for (MiningLocationLabel crystalsWaypoint : activeWaypoints.values()) { + crystalsWaypoint.render(context); + } } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsWaypoint.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsWaypoint.java deleted file mode 100644 index dc40f82c..00000000 --- a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsWaypoint.java +++ /dev/null @@ -1,98 +0,0 @@ -package de.hysky.skyblocker.skyblock.dwarven; - -import de.hysky.skyblocker.config.SkyblockerConfigManager; -import de.hysky.skyblocker.config.configs.UIAndVisualsConfig; -import de.hysky.skyblocker.utils.render.RenderHelper; -import de.hysky.skyblocker.utils.waypoint.Waypoint; -import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; -import net.minecraft.client.MinecraftClient; -import net.minecraft.entity.Entity; -import net.minecraft.text.Text; -import net.minecraft.util.DyeColor; -import net.minecraft.util.Formatting; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; - -import java.awt.*; -import java.util.function.Predicate; -import java.util.function.Supplier; -import java.util.function.ToDoubleFunction; - -public class CrystalsWaypoint extends Waypoint { - private static final Supplier CONFIG = () -> SkyblockerConfigManager.get().uiAndVisuals.waypoints; - private static final Supplier TYPE_SUPPLIER = () -> CONFIG.get().waypointType; - final Category category; - final Text name; - private final Vec3d centerPos; - - CrystalsWaypoint(Category category, Text name, BlockPos pos) { - super(pos, TYPE_SUPPLIER, category.colorComponents); - this.category = category; - this.name = name; - this.centerPos = pos.toCenterPos(); - } - - static ToDoubleFunction getSquaredDistanceToFunction(Entity entity) { - return crystalsWaypoint -> entity.squaredDistanceTo(crystalsWaypoint.centerPos); - } - - static Predicate getRangePredicate(Entity entity) { - return crystalsWaypoint -> entity.squaredDistanceTo(crystalsWaypoint.centerPos) <= 36D; - } - - @Override - public boolean shouldRender() { - return super.shouldRender(); - } - - @Override - public boolean equals(Object obj) { - return super.equals(obj) || obj instanceof CrystalsWaypoint other && category == other.category && name.equals(other.name) && pos.equals(other.pos); - } - - /** - * Renders the secret waypoint, including a waypoint through {@link Waypoint#render(WorldRenderContext)}, the name, and the distance from the player. - */ - @Override - public void render(WorldRenderContext context) { - super.render(context); - - Vec3d posUp = centerPos.add(0, 1, 0); - RenderHelper.renderText(context, name, posUp, true); - double distance = context.camera().getPos().distanceTo(centerPos); - RenderHelper.renderText(context, Text.literal(Math.round(distance) + "m").formatted(Formatting.YELLOW), posUp, 1, MinecraftClient.getInstance().textRenderer.fontHeight + 1, true); - - } - - /** - * enum for the different waypoints used int the crystals hud each with a {@link Category#name} and associated {@link Category#color} - */ - enum Category { - JUNGLE_TEMPLE("Jungle Temple", new Color(DyeColor.PURPLE.getSignColor())), - MINES_OF_DIVAN("Mines of Divan", Color.GREEN), - GOBLIN_QUEENS_DEN("Goblin Queen's Den", new Color(DyeColor.ORANGE.getSignColor())), - LOST_PRECURSOR_CITY("Lost Precursor City", Color.CYAN), - KHAZAD_DUM("Khazad-dûm", Color.YELLOW), - FAIRY_GROTTO("Fairy Grotto", Color.PINK), - DRAGONS_LAIR("Dragon's Lair", Color.BLACK), - CORLEONE("Corleone", Color.WHITE), - KING_YOLKAR("King Yolkar", Color.RED), - ODAWA("Odawa", Color.MAGENTA), - KEY_GUARDIAN("Key Guardian", Color.LIGHT_GRAY); - - public final Color color; - private final String name; - private final float[] colorComponents; - - Category(String name, Color color) { - this.name = name; - this.color = color; - this.colorComponents = color.getColorComponents(null); - } - - @Override - public String toString() { - return name; - } - } -} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MetalDetector.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MetalDetector.java index 294b2c3d..9de636cc 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MetalDetector.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MetalDetector.java @@ -4,6 +4,7 @@ import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.utils.Constants; import de.hysky.skyblocker.utils.Utils; import de.hysky.skyblocker.utils.render.RenderHelper; +import de.hysky.skyblocker.utils.waypoint.Waypoint; import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; @@ -17,6 +18,7 @@ import net.minecraft.util.math.Box; import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3i; +import java.awt.*; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -26,7 +28,7 @@ import java.util.regex.Pattern; public class MetalDetector { private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); - private static final float[] LIGHT_GRAY = { 192 / 255f, 192 / 255f, 192 / 255f }; + private static final float[] LIGHT_GRAY = {192 / 255f, 192 / 255f, 192 / 255f}; private static final Pattern TREASURE_PATTERN = Pattern.compile("(§3§lTREASURE: §b)(\\d+\\.?\\d?)m"); private static final Pattern KEEPER_PATTERN = Pattern.compile("Keeper of (\\w+)"); private static final Map keeperOffsets = Map.of( @@ -242,15 +244,20 @@ public class MetalDetector { //only one location render just that and guiding line to it if (possibleBlocks.size() == 1) { Vec3i block = possibleBlocks.getFirst().add(0, -1, 0); //the block you are taken to is one block above the chest - CrystalsWaypoint waypoint = new CrystalsWaypoint(CrystalsWaypoint.Category.CORLEONE, Text.translatable("skyblocker.dwarvenMines.metalDetectorHelper.treasure"), new BlockPos(block.getX(), block.getY(), block.getZ())); + Waypoint waypoint = new Waypoint(new BlockPos(block.getX(), block.getY(), block.getZ()), SkyblockerConfigManager.get().uiAndVisuals.waypoints.waypointType, Color.yellow.getColorComponents(null)); + MiningLocationLabel label = new MiningLocationLabel(MiningLocationLabel.CrystalHollowsOtherCategory.TREASURE, new Vec3d(block.getX() + 0.5, block.getY() + 1, block.getZ() + 0.5)); waypoint.render(context); + label.render(context); RenderHelper.renderLineFromCursor(context, Vec3d.ofCenter(block), LIGHT_GRAY, 1f, 5f); return; } for (Vec3i block : possibleBlocks) { - CrystalsWaypoint waypoint = new CrystalsWaypoint(CrystalsWaypoint.Category.CORLEONE, Text.translatable("skyblocker.dwarvenMines.metalDetectorHelper.possible"), new BlockPos(block.getX(), block.getY(), block.getZ())); + + Waypoint waypoint = new Waypoint(new BlockPos(block.getX(), block.getY(), block.getZ()), SkyblockerConfigManager.get().uiAndVisuals.waypoints.waypointType, Color.white.getColorComponents(null)); + MiningLocationLabel label = new MiningLocationLabel(MiningLocationLabel.CrystalHollowsOtherCategory.POSSIBLE_TREASURE, new Vec3d(block.getX() + 0.5, block.getY() + 1, block.getZ() + 0.5)); waypoint.render(context); + label.render(context); } } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MiningLocationLabel.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MiningLocationLabel.java index 1f373b55..6cf5edcc 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MiningLocationLabel.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MiningLocationLabel.java @@ -6,10 +6,13 @@ import de.hysky.skyblocker.utils.render.Renderable; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; import net.minecraft.client.MinecraftClient; import net.minecraft.text.Text; +import net.minecraft.util.DyeColor; import net.minecraft.util.Formatting; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; +import java.awt.*; + public record MiningLocationLabel(Category category, Vec3d centerPos) implements Renderable { public MiningLocationLabel(Category category, BlockPos pos) { this(category, pos.toCenterPos()); @@ -154,4 +157,62 @@ public record MiningLocationLabel(Category category, Vec3d centerPos) implements return color; } } + + /** + * enum for the different waypoints used int the crystals hud each with a {@link CrystalHollowsLocationsCategory#name} and associated {@link CrystalHollowsLocationsCategory#color} + */ + enum CrystalHollowsLocationsCategory implements Category { + JUNGLE_TEMPLE("Jungle Temple", new Color(DyeColor.PURPLE.getSignColor())), + MINES_OF_DIVAN("Mines of Divan", Color.GREEN), + GOBLIN_QUEENS_DEN("Goblin Queen's Den", new Color(DyeColor.ORANGE.getSignColor())), + LOST_PRECURSOR_CITY("Lost Precursor City", Color.CYAN), + KHAZAD_DUM("Khazad-dûm", Color.YELLOW), + FAIRY_GROTTO("Fairy Grotto", Color.PINK), + DRAGONS_LAIR("Dragon's Lair", Color.BLACK), + CORLEONE("Corleone", Color.WHITE), + KING_YOLKAR("King Yolkar", Color.RED), + ODAWA("Odawa", Color.MAGENTA), + KEY_GUARDIAN("Key Guardian", Color.LIGHT_GRAY); + + public final Color color; + private final String name; + + CrystalHollowsLocationsCategory(String name, Color color) { + this.name = name; + this.color = color; + } + + @Override + public String getName() { + return name; + } + + @Override + public int getColor() { + return this.color.getRGB(); + } + } + + enum CrystalHollowsOtherCategory implements Category { + TREASURE(Text.translatable("skyblocker.dwarvenMines.metalDetectorHelper.treasure") , Color.YELLOW), + POSSIBLE_TREASURE(Text.translatable("skyblocker.dwarvenMines.metalDetectorHelper.possible"), Color.WHITE); + + public final Color color; + private final String name; + + CrystalHollowsOtherCategory(Text name, Color color) { + this.name = name.getString(); + this.color = color; + } + + @Override + public String getName() { + return name; + } + + @Override + public int getColor() { + return this.color.getRGB(); + } + } } -- cgit From 42503766d848ca814f44537882b8a291ea63d496 Mon Sep 17 00:00:00 2001 From: olim Date: Sun, 16 Jun 2024 22:12:37 +0100 Subject: improve cword parssing take more location formats and partial matches for names --- .../skyblock/dwarven/CrystalsLocationsManager.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java index 9bed7d50..91f6de3d 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java @@ -56,7 +56,7 @@ public class CrystalsLocationsManager { * A look-up table to convert between location names and waypoint in the {@link MiningLocationLabel.CrystalHollowsLocationsCategory} values. */ private static final Map WAYPOINT_LOCATIONS = Arrays.stream(MiningLocationLabel.CrystalHollowsLocationsCategory.values()).collect(Collectors.toMap(MiningLocationLabel.CrystalHollowsLocationsCategory::getName, Function.identity())); - private static final Pattern TEXT_CWORDS_PATTERN = Pattern.compile("([0-9][0-9][0-9]) ([0-9][0-9][0-9]?) ([0-9][0-9][0-9])"); + private static final Pattern TEXT_CWORDS_PATTERN = Pattern.compile("([0-9][0-9][0-9]).*([0-9][0-9][0-9]?).*([0-9][0-9][0-9])"); protected static Map activeWaypoints = new HashMap<>(); @@ -73,7 +73,7 @@ public class CrystalsLocationsManager { } private static void extractLocationFromMessage(Text message, Boolean overlay) { - if (!SkyblockerConfigManager.get().mining.crystalsWaypoints.findInChat || !Utils.isInCrystalHollows()) { + if (!SkyblockerConfigManager.get().mining.crystalsWaypoints.findInChat || !Utils.isInCrystalHollows() || overlay) { return; } @@ -83,10 +83,8 @@ public class CrystalsLocationsManager { Matcher matcher = TEXT_CWORDS_PATTERN.matcher(value); //if there are coordinates in the message try to get them and what they are talking about if (matcher.find()) { - String location = matcher.group(); - int[] coordinates = Arrays.stream(location.split(" ", 3)).mapToInt(Integer::parseInt).toArray(); - BlockPos blockPos = new BlockPos(coordinates[0], coordinates[1], coordinates[2]); - + BlockPos blockPos = new BlockPos(Integer.parseInt(matcher.group(1)), Integer.parseInt(matcher.group(2)), Integer.parseInt(matcher.group(3))); + String location = blockPos.getX() + " " + blockPos.getY() + " " + blockPos.getZ(); //if position is not in the hollows do not add it if (!checkInCrystals(blockPos)) { return; @@ -94,7 +92,7 @@ public class CrystalsLocationsManager { //see if there is a name of a location to add to this for (String waypointLocation : WAYPOINT_LOCATIONS.keySet()) { - if (value.toLowerCase().contains(waypointLocation.toLowerCase())) { //todo be more lenient + if (Arrays.stream(waypointLocation.toLowerCase().split(" ")).anyMatch(word -> value.toLowerCase().contains(word)) ) { //check if contains a word of location //all data found to create waypoint addCustomWaypoint(waypointLocation, blockPos); return; -- cgit From cfb861de647e551a19096483a5d60fd10d676a63 Mon Sep 17 00:00:00 2001 From: olim Date: Mon, 17 Jun 2024 11:07:45 +0100 Subject: use named way-point for metal detector --- .../skyblocker/skyblock/dwarven/MetalDetector.java | 10 +++------- .../skyblock/dwarven/MiningLocationLabel.java | 22 ---------------------- 2 files changed, 3 insertions(+), 29 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MetalDetector.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MetalDetector.java index 9de636cc..ae45ff0b 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MetalDetector.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MetalDetector.java @@ -4,6 +4,7 @@ import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.utils.Constants; import de.hysky.skyblocker.utils.Utils; import de.hysky.skyblocker.utils.render.RenderHelper; +import de.hysky.skyblocker.utils.waypoint.NamedWaypoint; import de.hysky.skyblocker.utils.waypoint.Waypoint; import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; @@ -244,20 +245,15 @@ public class MetalDetector { //only one location render just that and guiding line to it if (possibleBlocks.size() == 1) { Vec3i block = possibleBlocks.getFirst().add(0, -1, 0); //the block you are taken to is one block above the chest - Waypoint waypoint = new Waypoint(new BlockPos(block.getX(), block.getY(), block.getZ()), SkyblockerConfigManager.get().uiAndVisuals.waypoints.waypointType, Color.yellow.getColorComponents(null)); - MiningLocationLabel label = new MiningLocationLabel(MiningLocationLabel.CrystalHollowsOtherCategory.TREASURE, new Vec3d(block.getX() + 0.5, block.getY() + 1, block.getZ() + 0.5)); + NamedWaypoint waypoint = new NamedWaypoint(new BlockPos(block.getX(), block.getY(), block.getZ()), Text.translatable("skyblocker.dwarvenMines.metalDetectorHelper.treasure").getString(), Color.yellow.getColorComponents(null)); waypoint.render(context); - label.render(context); RenderHelper.renderLineFromCursor(context, Vec3d.ofCenter(block), LIGHT_GRAY, 1f, 5f); return; } for (Vec3i block : possibleBlocks) { - - Waypoint waypoint = new Waypoint(new BlockPos(block.getX(), block.getY(), block.getZ()), SkyblockerConfigManager.get().uiAndVisuals.waypoints.waypointType, Color.white.getColorComponents(null)); - MiningLocationLabel label = new MiningLocationLabel(MiningLocationLabel.CrystalHollowsOtherCategory.POSSIBLE_TREASURE, new Vec3d(block.getX() + 0.5, block.getY() + 1, block.getZ() + 0.5)); + NamedWaypoint waypoint = new NamedWaypoint(new BlockPos(block.getX(), block.getY(), block.getZ()), Text.translatable("skyblocker.dwarvenMines.metalDetectorHelper.possible").getString(), Color.white.getColorComponents(null)); waypoint.render(context); - label.render(context); } } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MiningLocationLabel.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MiningLocationLabel.java index 6cf5edcc..30f33aa2 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MiningLocationLabel.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MiningLocationLabel.java @@ -193,26 +193,4 @@ public record MiningLocationLabel(Category category, Vec3d centerPos) implements } } - enum CrystalHollowsOtherCategory implements Category { - TREASURE(Text.translatable("skyblocker.dwarvenMines.metalDetectorHelper.treasure") , Color.YELLOW), - POSSIBLE_TREASURE(Text.translatable("skyblocker.dwarvenMines.metalDetectorHelper.possible"), Color.WHITE); - - public final Color color; - private final String name; - - CrystalHollowsOtherCategory(Text name, Color color) { - this.name = name.getString(); - this.color = color; - } - - @Override - public String getName() { - return name; - } - - @Override - public int getColor() { - return this.color.getRGB(); - } - } } -- cgit From 7b2efe7c86908ad87df36f296d057b70e7be1427 Mon Sep 17 00:00:00 2001 From: olim Date: Mon, 17 Jun 2024 17:42:13 +0100 Subject: add scanning for location chat scan for messages to improve locations and auto add King. also fix bugs just introduced --- .../skyblock/dwarven/CrystalsLocationsManager.java | 26 +++++++++++------- .../skyblock/dwarven/MiningLocationLabel.java | 31 +++++++++++++--------- 2 files changed, 36 insertions(+), 21 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java index 91f6de3d..aa72007a 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java @@ -28,10 +28,10 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import org.slf4j.Logger; -import java.awt.*; import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.function.Function; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -56,7 +56,7 @@ public class CrystalsLocationsManager { * A look-up table to convert between location names and waypoint in the {@link MiningLocationLabel.CrystalHollowsLocationsCategory} values. */ private static final Map WAYPOINT_LOCATIONS = Arrays.stream(MiningLocationLabel.CrystalHollowsLocationsCategory.values()).collect(Collectors.toMap(MiningLocationLabel.CrystalHollowsLocationsCategory::getName, Function.identity())); - private static final Pattern TEXT_CWORDS_PATTERN = Pattern.compile("([0-9][0-9][0-9]).*([0-9][0-9][0-9]?).*([0-9][0-9][0-9])"); + private static final Pattern TEXT_CWORDS_PATTERN = Pattern.compile("([0-9][0-9][0-9])\\D*([0-9][0-9][0-9]?)\\D*([0-9][0-9][0-9])"); protected static Map activeWaypoints = new HashMap<>(); @@ -73,14 +73,13 @@ public class CrystalsLocationsManager { } private static void extractLocationFromMessage(Text message, Boolean overlay) { - if (!SkyblockerConfigManager.get().mining.crystalsWaypoints.findInChat || !Utils.isInCrystalHollows() || overlay) { + String text = Formatting.strip(message.getString()); + if (!SkyblockerConfigManager.get().mining.crystalsWaypoints.findInChat || !Utils.isInCrystalHollows() || overlay || text == null) { return; } - try { //get the message text - String value = message.getString(); - Matcher matcher = TEXT_CWORDS_PATTERN.matcher(value); + Matcher matcher = TEXT_CWORDS_PATTERN.matcher(text); //if there are coordinates in the message try to get them and what they are talking about if (matcher.find()) { BlockPos blockPos = new BlockPos(Integer.parseInt(matcher.group(1)), Integer.parseInt(matcher.group(2)), Integer.parseInt(matcher.group(3))); @@ -92,7 +91,7 @@ public class CrystalsLocationsManager { //see if there is a name of a location to add to this for (String waypointLocation : WAYPOINT_LOCATIONS.keySet()) { - if (Arrays.stream(waypointLocation.toLowerCase().split(" ")).anyMatch(word -> value.toLowerCase().contains(word)) ) { //check if contains a word of location + if (Arrays.stream(waypointLocation.toLowerCase().split(" ")).anyMatch(word -> text.toLowerCase().contains(word))) { //check if contains a word of location //all data found to create waypoint addCustomWaypoint(waypointLocation, blockPos); return; @@ -109,6 +108,16 @@ public class CrystalsLocationsManager { } catch (Exception e) { LOGGER.error("[Skyblocker Crystals Locations Manager] Encountered an exception while extracing a location from a chat message!", e); } + + //move waypoint to be more accurate based on locational chat messages + if (CLIENT.player != null) { + for (MiningLocationLabel.CrystalHollowsLocationsCategory waypointLocation : WAYPOINT_LOCATIONS.values()) { + String waypointLinkedMessage = waypointLocation.getLinkedMessage(); + if (waypointLinkedMessage != null && text.contains(waypointLinkedMessage)) { + addCustomWaypoint(waypointLocation.getName(), CLIENT.player.getBlockPos()); + } + } + } } protected static Boolean checkInCrystals(BlockPos pos) { @@ -178,7 +187,7 @@ public class CrystalsLocationsManager { public static int shareWaypoint(String place) { if (activeWaypoints.containsKey(place)) { Vec3d pos = activeWaypoints.get(place).centerPos(); - MessageScheduler.INSTANCE.sendMessageAfterCooldown(Constants.PREFIX.get().getString() + " " + place + ": " + pos.getX() + ", " + pos.getY() + ", " + pos.getZ()); + MessageScheduler.INSTANCE.sendMessageAfterCooldown(Constants.PREFIX.get().getString() + " " + place + ": " + (int) pos.getX() + ", " + (int) pos.getY() + ", " + (int) pos.getZ()); } else { //send fail message if (CLIENT.player == null || CLIENT.getNetworkHandler() == null) { @@ -201,7 +210,6 @@ public class CrystalsLocationsManager { if (SkyblockerConfigManager.get().mining.crystalsWaypoints.enabled) { for (MiningLocationLabel crystalsWaypoint : activeWaypoints.values()) { crystalsWaypoint.render(context); - } } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MiningLocationLabel.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MiningLocationLabel.java index 30f33aa2..0fc0c64f 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MiningLocationLabel.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MiningLocationLabel.java @@ -27,6 +27,7 @@ public record MiningLocationLabel(Category category, Vec3d centerPos) implements /** * Renders the name and distance to the label scaled so can be seen at a distance + * * @param context render context */ @Override @@ -162,24 +163,26 @@ public record MiningLocationLabel(Category category, Vec3d centerPos) implements * enum for the different waypoints used int the crystals hud each with a {@link CrystalHollowsLocationsCategory#name} and associated {@link CrystalHollowsLocationsCategory#color} */ enum CrystalHollowsLocationsCategory implements Category { - JUNGLE_TEMPLE("Jungle Temple", new Color(DyeColor.PURPLE.getSignColor())), - MINES_OF_DIVAN("Mines of Divan", Color.GREEN), - GOBLIN_QUEENS_DEN("Goblin Queen's Den", new Color(DyeColor.ORANGE.getSignColor())), - LOST_PRECURSOR_CITY("Lost Precursor City", Color.CYAN), - KHAZAD_DUM("Khazad-dûm", Color.YELLOW), - FAIRY_GROTTO("Fairy Grotto", Color.PINK), - DRAGONS_LAIR("Dragon's Lair", Color.BLACK), - CORLEONE("Corleone", Color.WHITE), - KING_YOLKAR("King Yolkar", Color.RED), - ODAWA("Odawa", Color.MAGENTA), - KEY_GUARDIAN("Key Guardian", Color.LIGHT_GRAY); + JUNGLE_TEMPLE("Jungle Temple", new Color(DyeColor.PURPLE.getSignColor()), "[NPC] Kalhuiki Door Guardian:"), + MINES_OF_DIVAN("Mines of Divan", Color.GREEN, " Jade Crystal"), + GOBLIN_QUEENS_DEN("Goblin Queen's Den", new Color(DyeColor.ORANGE.getSignColor()), " Amber Crystal"), + LOST_PRECURSOR_CITY("Lost Precursor City", Color.CYAN, " Sapphire Crystal"), + KHAZAD_DUM("Khazad-dûm", Color.YELLOW, " Topaz Crystal"), + FAIRY_GROTTO("Fairy Grotto", Color.PINK, null), + DRAGONS_LAIR("Dragon's Lair", Color.BLACK, null), + CORLEONE("Corleone", Color.WHITE, null), + KING_YOLKAR("King Yolkar", Color.RED, "[NPC] King Yolkar:"), + ODAWA("Odawa", Color.MAGENTA, "[NPC] Odawa:"), + KEY_GUARDIAN("Key Guardian", Color.LIGHT_GRAY, null); public final Color color; private final String name; + private final String linkedMessage; - CrystalHollowsLocationsCategory(String name, Color color) { + CrystalHollowsLocationsCategory(String name, Color color, String linkedMessage) { this.name = name; this.color = color; + this.linkedMessage = linkedMessage; } @Override @@ -191,6 +194,10 @@ public record MiningLocationLabel(Category category, Vec3d centerPos) implements public int getColor() { return this.color.getRGB(); } + + public String getLinkedMessage() { + return this.linkedMessage; + } } } -- cgit From 8fa21f0ec183da2e626cbe0ad2f95226308c9b9a Mon Sep 17 00:00:00 2001 From: olim Date: Wed, 19 Jun 2024 13:39:56 +0100 Subject: add wishing compass solver --- .../java/de/hysky/skyblocker/SkyblockerMod.java | 1 + .../mixins/ClientPlayNetworkHandlerMixin.java | 2 + .../skyblocker/mixins/PlayerListHudMixin.java | 6 + .../skyblock/dwarven/MiningLocationLabel.java | 1 + .../skyblock/dwarven/WishingCompassSolver.java | 357 +++++++++++++++++++++ 5 files changed, 367 insertions(+) create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/dwarven/WishingCompassSolver.java (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java index 8dd1419d..5cc96b42 100644 --- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java +++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java @@ -136,6 +136,7 @@ public class SkyblockerMod implements ClientModInitializer { FarmingHud.init(); LowerSensitivity.init(); CrystalsLocationsManager.init(); + WishingCompassSolver.init(); MetalDetector.init(); ChatMessageListener.init(); Shortcuts.init(); diff --git a/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java b/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java index 7bbbac81..c0cd8b7b 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java @@ -9,6 +9,7 @@ import de.hysky.skyblocker.skyblock.chocolatefactory.EggFinder; import de.hysky.skyblocker.skyblock.crimson.dojo.DojoManager; import de.hysky.skyblocker.skyblock.dungeon.DungeonScore; import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonManager; +import de.hysky.skyblocker.skyblock.dwarven.WishingCompassSolver; import de.hysky.skyblocker.skyblock.end.BeaconHighlighter; import de.hysky.skyblocker.skyblock.end.EnderNodes; import de.hysky.skyblocker.skyblock.end.TheEnd; @@ -100,6 +101,7 @@ public abstract class ClientPlayNetworkHandlerMixin { MythologicalRitual.onParticle(packet); DojoManager.onParticle(packet); EnderNodes.onParticle(packet); + WishingCompassSolver.onParticle(packet); } @ModifyExpressionValue(method = "onEntityStatus", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/s2c/play/EntityStatusS2CPacket;getEntity(Lnet/minecraft/world/World;)Lnet/minecraft/entity/Entity;")) diff --git a/src/main/java/de/hysky/skyblocker/mixins/PlayerListHudMixin.java b/src/main/java/de/hysky/skyblocker/mixins/PlayerListHudMixin.java index a96a7727..038d4e4f 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/PlayerListHudMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/PlayerListHudMixin.java @@ -12,6 +12,7 @@ import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.hud.PlayerListHud; import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.text.Text; +import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -54,4 +55,9 @@ public class PlayerListHudMixin { } } + @Inject(at = @At("HEAD"), method = "setFooter") + public void skblocker$updateFooter(@Nullable Text footer, CallbackInfo info) { + PlayerListMgr.updateFooter(footer); + } + } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MiningLocationLabel.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MiningLocationLabel.java index 0fc0c64f..964b6cce 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MiningLocationLabel.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MiningLocationLabel.java @@ -163,6 +163,7 @@ public record MiningLocationLabel(Category category, Vec3d centerPos) implements * enum for the different waypoints used int the crystals hud each with a {@link CrystalHollowsLocationsCategory#name} and associated {@link CrystalHollowsLocationsCategory#color} */ enum CrystalHollowsLocationsCategory implements Category { + UNKNOWN("Unknown", Color.WHITE, null), //used when a location is known but what's at the location is not known JUNGLE_TEMPLE("Jungle Temple", new Color(DyeColor.PURPLE.getSignColor()), "[NPC] Kalhuiki Door Guardian:"), MINES_OF_DIVAN("Mines of Divan", Color.GREEN, " Jade Crystal"), GOBLIN_QUEENS_DEN("Goblin Queen's Den", new Color(DyeColor.ORANGE.getSignColor()), " Amber Crystal"), diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/WishingCompassSolver.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/WishingCompassSolver.java new file mode 100644 index 00000000..48ceeb74 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/WishingCompassSolver.java @@ -0,0 +1,357 @@ +package de.hysky.skyblocker.skyblock.dwarven; + +import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr; +import de.hysky.skyblocker.utils.Constants; +import de.hysky.skyblocker.utils.Utils; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; +import net.fabricmc.fabric.api.event.player.UseBlockCallback; +import net.fabricmc.fabric.api.event.player.UseItemCallback; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.network.PlayerListEntry; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.network.packet.s2c.play.ParticleS2CPacket; +import net.minecraft.particle.ParticleTypes; +import net.minecraft.text.Text; +import net.minecraft.util.*; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.Box; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Stream; + +public class WishingCompassSolver { + private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); + + enum SolverStates { + NOT_STARTED, + PROCESSING_FIRST_USE, + WAITING_FOR_SECOND, + PROCESSING_SECOND_USE, + } + + enum ZONE { + CRYSTAL_NUCLEUS, + JUNGLE, + MITHRIL_DEPOSITS, + GOBLIN_HOLDOUT, + PRECURSOR_REMNANTS, + MAGMA_FIELDS, + } + + private static final HashMap ZONE_BOUNDING_BOXES = Util.make(new HashMap<>(), map -> { + map.put(ZONE.CRYSTAL_NUCLEUS, new Box(462, 63, 461, 564, 181, 565)); + map.put(ZONE.JUNGLE, new Box(201, 63, 201, 513, 189, 513)); + map.put(ZONE.MITHRIL_DEPOSITS, new Box(512, 63, 201, 824, 189, 513)); + map.put(ZONE.GOBLIN_HOLDOUT, new Box(201, 63, 512, 513, 189, 824)); + map.put(ZONE.PRECURSOR_REMNANTS, new Box(512, 63, 512, 824, 189, 824)); + map.put(ZONE.MAGMA_FIELDS, new Box(201, 30, 201, 824, 64, 824)); + }); + private static final Vec3d JUNGLE_TEMPLE_DOOR_OFFSET = new Vec3d(-57, 36, -21); + /** + * how many particles to use to get direction of a line + */ + private static final long PARTICLES_PER_LINE = 25; + /** + * the amount of milliseconds to wait for the next particle until assumed failed + */ + private static final long PARTICLES_MAX_DELAY = 500; + /** + * the distance the player has to be from where they used the first compass to where they use the second + */ + private static final long DISTANCE_BETWEEN_USES = 32; + + private static SolverStates currentState = SolverStates.NOT_STARTED; + private static Vec3d startPosOne = Vec3d.ZERO; + private static Vec3d startPosTwo = Vec3d.ZERO; + private static Vec3d directionOne = Vec3d.ZERO; + private static Vec3d directionTwo = Vec3d.ZERO; + private static long particleUsedCountOne = 0; + private static long particleUsedCountTwo = 0; + private static long particleLastUpdate = System.currentTimeMillis(); + + + public static void init() { + UseItemCallback.EVENT.register(WishingCompassSolver::onItemInteract); + UseBlockCallback.EVENT.register(WishingCompassSolver::onBlockInteract); + ClientPlayConnectionEvents.JOIN.register((_handler, _sender, _client) -> reset()); + } + + private static void reset() { + currentState = SolverStates.NOT_STARTED; + startPosOne = Vec3d.ZERO; + startPosTwo = Vec3d.ZERO; + directionOne = Vec3d.ZERO; + directionTwo = Vec3d.ZERO; + particleUsedCountOne = 0; + particleUsedCountTwo = 0; + particleLastUpdate = System.currentTimeMillis(); + } + + private static boolean isKingsScentPresent() { + String footer = PlayerListMgr.getFooter(); + if (footer == null) { + return false; + } + return footer.contains("King's Scent I"); + } + + private static boolean isKeyInInventory() { + if (CLIENT.player == null) { + return false; + } + for (ItemStack item : CLIENT.player.getInventory().main) { + if (item != null && Objects.equals(item.getSkyblockId(), "JUNGLE_KEY")) { + return true; + } + } + return false; + } + + private static ZONE getZoneOfLocation(Vec3d location) { + for (Map.Entry zone : ZONE_BOUNDING_BOXES.entrySet()) { + if (zone.getValue().contains(location)) { + return zone.getKey(); + } + } + + //default to nucleus if somehow not in another zone + return ZONE.CRYSTAL_NUCLEUS; + } + + private static Boolean isZoneComplete(ZONE zone) { + if (CLIENT.getNetworkHandler() == null || CLIENT.player == null) { + return false; + } + //creates cleaned stream of all the entry's in tab list + Stream playerListStream = CLIENT.getNetworkHandler().getPlayerList().stream(); + Stream displayNameStream = playerListStream.map(PlayerListEntry::getDisplayName).filter(Objects::nonNull).map(Text::getString).map(String::strip); + + //make sure the data is in tab and if not tell the user + if (displayNameStream.noneMatch(entry -> entry.equals("Crystals:"))) { + CLIENT.player.sendMessage(Constants.PREFIX.get().append(Text.literal("Enable crystals in /tab so the compass can know what has been found")), false); + return false; + } + + //return if the crystal for a zone is found + playerListStream = CLIENT.getNetworkHandler().getPlayerList().stream(); + displayNameStream = playerListStream.map(PlayerListEntry::getDisplayName).filter(Objects::nonNull).map(Text::getString).map(String::strip); + return switch (zone) { + case JUNGLE -> displayNameStream.noneMatch(entry -> entry.equals("Amethyst: ✖ Not Found")); + case MITHRIL_DEPOSITS -> displayNameStream.noneMatch(entry -> entry.equals("Jade: ✖ Not Found")); + case GOBLIN_HOLDOUT -> displayNameStream.noneMatch(entry -> entry.equals("Amber: ✖ Not Found")); + case PRECURSOR_REMNANTS -> displayNameStream.noneMatch(entry -> entry.equals("Sapphire: ✖ Not Found")); + case MAGMA_FIELDS -> displayNameStream.noneMatch(entry -> entry.equals("Topaz: ✖ Not Found")); + default -> false; + }; + } + + private static MiningLocationLabel.CrystalHollowsLocationsCategory getTargetLocation(ZONE startingZone) { + //if the zone is complete return null + if (isZoneComplete(startingZone)) { + return MiningLocationLabel.CrystalHollowsLocationsCategory.UNKNOWN; + } + return switch (startingZone) { + case JUNGLE -> + isKeyInInventory() ? MiningLocationLabel.CrystalHollowsLocationsCategory.JUNGLE_TEMPLE : MiningLocationLabel.CrystalHollowsLocationsCategory.ODAWA; + case MITHRIL_DEPOSITS -> MiningLocationLabel.CrystalHollowsLocationsCategory.MINES_OF_DIVAN; + case GOBLIN_HOLDOUT -> + isKingsScentPresent() ? MiningLocationLabel.CrystalHollowsLocationsCategory.GOBLIN_QUEENS_DEN : MiningLocationLabel.CrystalHollowsLocationsCategory.KING_YOLKAR; + case PRECURSOR_REMNANTS -> MiningLocationLabel.CrystalHollowsLocationsCategory.LOST_PRECURSOR_CITY; + case MAGMA_FIELDS -> MiningLocationLabel.CrystalHollowsLocationsCategory.KHAZAD_DUM; + default -> MiningLocationLabel.CrystalHollowsLocationsCategory.UNKNOWN; + }; + } + + + public static void onParticle(ParticleS2CPacket packet) { + if (!Utils.isInCrystalHollows() || !ParticleTypes.HAPPY_VILLAGER.equals(packet.getParameters().getType())) { + return; + } + //get location of particle + Vec3d particlePos = new Vec3d(packet.getX(), packet.getY(), packet.getZ()); + //update particle used time + particleLastUpdate = System.currentTimeMillis(); + + switch (currentState) { + case PROCESSING_FIRST_USE -> { + Vec3d particleDirection = particlePos.subtract(startPosOne).normalize(); + //move direction to fit with particle + directionOne = directionOne.add(particleDirection.multiply((double) 1 / PARTICLES_PER_LINE)); + particleUsedCountOne += 1; + //if used enough particle go to next state + if (particleUsedCountOne >= PARTICLES_PER_LINE) { + currentState = SolverStates.WAITING_FOR_SECOND; + if (CLIENT.player != null) { + CLIENT.player.sendMessage(Constants.PREFIX.get().append(Text.literal("Wishing compass used. Move to another location and use another compass to triangulate target").formatted(Formatting.GREEN)), false); + } + } + } + case PROCESSING_SECOND_USE -> { + Vec3d particleDirection = particlePos.subtract(startPosTwo).normalize(); + //move direction to fit with particle + directionTwo = directionTwo.add(particleDirection.multiply((double) 1 / PARTICLES_PER_LINE)); + particleUsedCountTwo += 1; + //if used enough particle go to next state + if (particleUsedCountTwo >= PARTICLES_PER_LINE) { + processSolution(); + } + } + } + } + + private static void processSolution() { + if (CLIENT.player == null) { + reset(); + return; + } + Vec3d targetLocation = solve(startPosOne, startPosTwo, directionOne, directionTwo); + if (targetLocation == null) { + CLIENT.player.sendMessage(Constants.PREFIX.get().append(Text.literal("Something went wrong. lines do not cross. please try again").formatted(Formatting.RED)), false); + } else { + //send message to player with location and name + MiningLocationLabel.CrystalHollowsLocationsCategory location = getTargetLocation(getZoneOfLocation(startPosOne)); + //offset the jungle location to its doors + if (location == MiningLocationLabel.CrystalHollowsLocationsCategory.JUNGLE_TEMPLE) { + targetLocation = targetLocation.add(JUNGLE_TEMPLE_DOOR_OFFSET); + } + + CLIENT.player.sendMessage(Constants.PREFIX.get() + .append(Text.literal("Wishing compass solver found ").formatted(Formatting.GREEN)) + .append(Text.literal(location.getName()).withColor(location.getColor())) + .append(Text.literal(": " + (int) targetLocation.getX() + " " + (int) targetLocation.getY() + " " + (int) targetLocation.getZ())), + false); + } + + //reset ready for another go + reset(); + } + + /** + * using the stating locations and line direction solve for where the location must be + */ + protected static Vec3d solve(Vec3d startPosOne, Vec3d startPosTwo, Vec3d directionOne, Vec3d directionTwo) { + Vec3d crossProduct = directionOne.crossProduct(directionTwo); + if (crossProduct.equals(Vec3d.ZERO)) { + //lines are parallel or coincident + return null; + } + // Calculate the difference vector between startPosTwo and startPosOne + Vec3d diff = startPosTwo.subtract(startPosOne); + // projecting 'diff' onto the plane defined by 'directionTwo' and 'crossProduct'. then scaling by the inverse squared length of 'crossProduct' + double intersectionScalar = diff.dotProduct(directionTwo.crossProduct(crossProduct)) / crossProduct.lengthSquared(); + // if intersectionScalar is a negative number the lines are meeting in the opposite direction and giving incorrect cords + if (intersectionScalar < 0) { + return null; + } + //get final target location + return startPosOne.add(directionOne.multiply(intersectionScalar)); + } + + private static ActionResult onBlockInteract(PlayerEntity playerEntity, World world, Hand hand, BlockHitResult blockHitResult) { + if (CLIENT.player == null) { + return null; + } + ItemStack stack = CLIENT.player.getStackInHand(hand); + //make sure the user is in the crystal hollows and holding the wishing compass + if (!Utils.isInCrystalHollows() || !Objects.equals(stack.getSkyblockId(), "WISHING_COMPASS")) { + return ActionResult.PASS; + } + if (useCompass()) { + return ActionResult.FAIL; + } + + return ActionResult.PASS; + } + + private static TypedActionResult onItemInteract(PlayerEntity playerEntity, World world, Hand hand) { + if (CLIENT.player == null) { + return null; + } + ItemStack stack = CLIENT.player.getStackInHand(hand); + //make sure the user is in the crystal hollows and holding the wishing compass + if (!Utils.isInCrystalHollows() || !Objects.equals(stack.getSkyblockId(), "WISHING_COMPASS")) { + return TypedActionResult.pass(stack); + } + if (useCompass()) { + return TypedActionResult.fail(stack); + } + + return TypedActionResult.pass(stack); + } + + /** + * Computes what to do next when a compass is used. + * + * @return if the use event should be canceled + */ + private static boolean useCompass() { + if (CLIENT.player == null) { + return true; + } + Vec3d playerPos = CLIENT.player.getEyePos(); + ZONE currentZone = getZoneOfLocation(playerPos); + + switch (currentState) { + case NOT_STARTED -> { + //do not start if the player is in nucleus as this does not work well + if (currentZone == ZONE.CRYSTAL_NUCLEUS) { + CLIENT.player.sendMessage(Constants.PREFIX.get().append(Text.literal("Use compass outside of nucleus for better results")), false); + return true; + } + startNewState(SolverStates.PROCESSING_FIRST_USE); + } + + case WAITING_FOR_SECOND -> { + //only continue if the player is far enough away from the first position to get a better reading + if (startPosOne.distanceTo(playerPos) < DISTANCE_BETWEEN_USES) { + CLIENT.player.sendMessage(Constants.PREFIX.get().append(Text.literal("Move further away from the first use before using again")), false); + return true; + } else { + //make sure the player is in the same zone as they used to first or restart + if (currentZone != getZoneOfLocation(startPosOne)) { + CLIENT.player.sendMessage(Constants.PREFIX.get().append(Text.literal("Changed zone. Restarting...")), false); + startNewState(SolverStates.PROCESSING_FIRST_USE); + } else { + startNewState(SolverStates.PROCESSING_SECOND_USE); + } + } + } + + case PROCESSING_FIRST_USE, PROCESSING_SECOND_USE -> { + //if still looking for particles for line tell the user to wait + //else tell the use something went wrong and its starting again + if (System.currentTimeMillis() - particleLastUpdate < PARTICLES_MAX_DELAY) { + CLIENT.player.sendMessage(Constants.PREFIX.get().append(Text.literal("Wait a little before using another wishing compass").formatted(Formatting.RED)), false); + return true; + } else { + CLIENT.player.sendMessage(Constants.PREFIX.get().append(Text.literal("Could not detect last use. Restarting...").formatted(Formatting.RED)), false); + startNewState(SolverStates.PROCESSING_FIRST_USE); + } + } + } + + return false; + } + + private static void startNewState(SolverStates newState) { + if (CLIENT.player == null) { + return; + } + Vec3d playerPos = CLIENT.player.getEyePos(); + + if (newState == SolverStates.PROCESSING_FIRST_USE) { + currentState = SolverStates.PROCESSING_FIRST_USE; + startPosOne = playerPos; + particleLastUpdate = System.currentTimeMillis(); + } else if (newState == SolverStates.PROCESSING_SECOND_USE) { + currentState = SolverStates.PROCESSING_SECOND_USE; + startPosTwo = playerPos; + particleLastUpdate = System.currentTimeMillis(); + } + } +} -- cgit From b3aa88019789eeec86627afd7e25e2edcd1dd675 Mon Sep 17 00:00:00 2001 From: olim Date: Wed, 19 Jun 2024 20:14:36 +0100 Subject: clean up some unwanted cwords being passed --- .../skyblock/dwarven/CrystalsLocationsManager.java | 50 ++++++++++++---------- .../skyblock/dwarven/WishingCompassSolver.java | 4 ++ 2 files changed, 32 insertions(+), 22 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java index aa72007a..0a3d6641 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java @@ -78,33 +78,39 @@ public class CrystalsLocationsManager { return; } try { - //get the message text - Matcher matcher = TEXT_CWORDS_PATTERN.matcher(text); - //if there are coordinates in the message try to get them and what they are talking about - if (matcher.find()) { - BlockPos blockPos = new BlockPos(Integer.parseInt(matcher.group(1)), Integer.parseInt(matcher.group(2)), Integer.parseInt(matcher.group(3))); - String location = blockPos.getX() + " " + blockPos.getY() + " " + blockPos.getZ(); - //if position is not in the hollows do not add it - if (!checkInCrystals(blockPos)) { - return; - } + //make sure that it is only reading user messages and not from skyblocker + if (text.contains(":") && !text.startsWith(Constants.PREFIX.get().getString())) { + String userMessage = text.split(":",2)[1]; + + //get the message text + Matcher matcher = TEXT_CWORDS_PATTERN.matcher(userMessage); + //if there are coordinates in the message try to get them and what they are talking about + if (matcher.find()) { + BlockPos blockPos = new BlockPos(Integer.parseInt(matcher.group(1)), Integer.parseInt(matcher.group(2)), Integer.parseInt(matcher.group(3))); + String location = blockPos.getX() + " " + blockPos.getY() + " " + blockPos.getZ(); + //if position is not in the hollows do not add it + if (!checkInCrystals(blockPos)) { + return; + } + + //see if there is a name of a location to add to this + for (String waypointLocation : WAYPOINT_LOCATIONS.keySet()) { + if (Arrays.stream(waypointLocation.toLowerCase().split(" ")).anyMatch(word -> userMessage.toLowerCase().contains(word))) { //check if contains a word of location + //all data found to create waypoint + addCustomWaypoint(waypointLocation, blockPos); + return; + } + } - //see if there is a name of a location to add to this - for (String waypointLocation : WAYPOINT_LOCATIONS.keySet()) { - if (Arrays.stream(waypointLocation.toLowerCase().split(" ")).anyMatch(word -> text.toLowerCase().contains(word))) { //check if contains a word of location - //all data found to create waypoint - addCustomWaypoint(waypointLocation, blockPos); + //if the location is not found ask the user for the location (could have been in a previous chat message) + if (CLIENT.player == null || CLIENT.getNetworkHandler() == null) { return; } - } - //if the location is not found ask the user for the location (could have been in a previous chat message) - if (CLIENT.player == null || CLIENT.getNetworkHandler() == null) { - return; + CLIENT.player.sendMessage(getLocationInputText(location), false); } - - CLIENT.player.sendMessage(getLocationInputText(location), false); } + } catch (Exception e) { LOGGER.error("[Skyblocker Crystals Locations Manager] Encountered an exception while extracing a location from a chat message!", e); } @@ -200,7 +206,7 @@ public class CrystalsLocationsManager { } - private static void addCustomWaypoint(String waypointName, BlockPos pos) { + protected static void addCustomWaypoint(String waypointName, BlockPos pos) { MiningLocationLabel.CrystalHollowsLocationsCategory category = WAYPOINT_LOCATIONS.get(waypointName); MiningLocationLabel waypoint = new MiningLocationLabel(category, pos); activeWaypoints.put(waypointName, waypoint); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/WishingCompassSolver.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/WishingCompassSolver.java index 48ceeb74..930bdad8 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/WishingCompassSolver.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/WishingCompassSolver.java @@ -15,6 +15,7 @@ import net.minecraft.particle.ParticleTypes; import net.minecraft.text.Text; import net.minecraft.util.*; import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; @@ -225,6 +226,9 @@ public class WishingCompassSolver { .append(Text.literal(location.getName()).withColor(location.getColor())) .append(Text.literal(": " + (int) targetLocation.getX() + " " + (int) targetLocation.getY() + " " + (int) targetLocation.getZ())), false); + + //add waypoint + CrystalsLocationsManager.addCustomWaypoint(location.getName(), BlockPos.ofFloored(targetLocation)); } //reset ready for another go -- cgit From e30367c9b7b2370850e839e994d3c0bf95b3b9ad Mon Sep 17 00:00:00 2001 From: olim Date: Wed, 19 Jun 2024 20:47:38 +0100 Subject: add remove command and co