aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de/hysky
diff options
context:
space:
mode:
authorAaron <51387595+AzureAaron@users.noreply.github.com>2024-02-04 12:49:53 -0500
committerGitHub <noreply@github.com>2024-02-04 12:49:53 -0500
commitfe1bc0589caef8ff9f2d616a3742e63e2668f00e (patch)
tree06e8e1b2ee3e3a9381dc042650f4fe6ac86582c5 /src/main/java/de/hysky
parentce90376c4a8a934cc4d2f8bc4dd0e5e1c71b3748 (diff)
parent71467890a61eb4e05793b1856f6303787216f2ec (diff)
downloadSkyblocker-fe1bc0589caef8ff9f2d616a3742e63e2668f00e.tar.gz
Skyblocker-fe1bc0589caef8ff9f2d616a3742e63e2668f00e.tar.bz2
Skyblocker-fe1bc0589caef8ff9f2d616a3742e63e2668f00e.zip
Merge pull request #523 from olim88/crystal-hollows-fetures
Crystal hollows fetures
Diffstat (limited to 'src/main/java/de/hysky')
-rw-r--r--src/main/java/de/hysky/skyblocker/SkyblockerMod.java6
-rw-r--r--src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java45
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/DwarvenMinesCategory.java82
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsHud.java164
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsHudConfigScreen.java69
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java195
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsWaypoint.java98
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHud.java181
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java36
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/hud/HudPowderWidget.java40
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/Utils.java11
11 files changed, 861 insertions, 66 deletions
diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
index 3fca09ce..c11e4c86 100644
--- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
+++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
@@ -13,6 +13,8 @@ import de.hysky.skyblocker.skyblock.dungeon.puzzle.TicTacToe;
import de.hysky.skyblocker.skyblock.dungeon.puzzle.waterboard.Waterboard;
import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonManager;
import de.hysky.skyblocker.skyblock.dungeon.secrets.SecretsTracker;
+import de.hysky.skyblocker.skyblock.dwarven.CrystalsHud;
+import de.hysky.skyblocker.skyblock.dwarven.CrystalsLocationsManager;
import de.hysky.skyblocker.skyblock.dwarven.DwarvenHud;
import de.hysky.skyblocker.skyblock.end.BeaconHighlighter;
import de.hysky.skyblocker.skyblock.item.*;
@@ -99,6 +101,8 @@ public class SkyblockerMod implements ClientModInitializer {
QuickNav.init();
ItemCooldowns.init();
DwarvenHud.init();
+ CrystalsHud.init();
+ CrystalsLocationsManager.init();
ChatMessageListener.init();
Shortcuts.init();
DiscordRPCManager.init();
@@ -142,6 +146,8 @@ public class SkyblockerMod implements ClientModInitializer {
Scheduler.INSTANCE.scheduleCyclic(LividColor::update, 10);
Scheduler.INSTANCE.scheduleCyclic(BackpackPreview::tick, 50);
Scheduler.INSTANCE.scheduleCyclic(DwarvenHud::update, 40);
+ Scheduler.INSTANCE.scheduleCyclic(CrystalsHud::update, 40);
+ Scheduler.INSTANCE.scheduleCyclic(CrystalsLocationsManager::update, 40);
Scheduler.INSTANCE.scheduleCyclic(PlayerListMgr::updateList, 20);
}
diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java
index a7569adb..4acb8064 100644
--- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java
+++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java
@@ -873,11 +873,20 @@ public class SkyblockerConfig {
@SerialEntry
public DwarvenHud dwarvenHud = new DwarvenHud();
+
+ @SerialEntry
+ public CrystalsHud crystalsHud = new CrystalsHud();
+
+ @SerialEntry
+ public CrystalsWaypoints crystalsWaypoints = new CrystalsWaypoints();
}
public static class DwarvenHud {
@SerialEntry
- public boolean enabled = true;
+ public boolean enabledCommissions = true;
+
+ @SerialEntry
+ public boolean enabledPowder = true;
@SerialEntry
public DwarvenHudStyle style = DwarvenHudStyle.SIMPLE;
@@ -890,6 +899,40 @@ public class SkyblockerConfig {
@SerialEntry
public int y = 10;
+
+ @SerialEntry
+ public int powderX = 10;
+
+ @SerialEntry
+ public int powderY = 70;
+ }
+
+ public static class CrystalsHud {
+ @SerialEntry
+ public boolean enabled = true;
+
+ @SerialEntry
+ public boolean showLocations = true;
+
+ @SerialEntry
+ public int locationSize = 8;
+
+ @SerialEntry
+ public int x = 10;
+
+ @SerialEntry
+ public int y = 130;
+
+ @SerialEntry
+ public float mapScaling = 1f;
+ }
+
+ public static class CrystalsWaypoints {
+ @SerialEntry
+ public boolean enabled = true;
+
+ @SerialEntry
+ public boolean findInChat = true;
}
public enum DwarvenHudStyle {
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/DwarvenMinesCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/DwarvenMinesCategory.java
index 80d6485b..97b48bc4 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/DwarvenMinesCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/DwarvenMinesCategory.java
@@ -2,12 +2,15 @@ package de.hysky.skyblocker.config.categories;
import de.hysky.skyblocker.config.ConfigUtils;
import de.hysky.skyblocker.config.SkyblockerConfig;
+import de.hysky.skyblocker.skyblock.dwarven.CrystalsHudConfigScreen;
import dev.isxander.yacl3.api.ButtonOption;
import dev.isxander.yacl3.api.ConfigCategory;
import dev.isxander.yacl3.api.Option;
import dev.isxander.yacl3.api.OptionDescription;
import dev.isxander.yacl3.api.OptionGroup;
import de.hysky.skyblocker.skyblock.dwarven.DwarvenHudConfigScreen;
+import dev.isxander.yacl3.api.controller.FloatFieldControllerBuilder;
+import dev.isxander.yacl3.api.controller.IntegerSliderControllerBuilder;
import net.minecraft.client.MinecraftClient;
import net.minecraft.text.Text;
@@ -45,15 +48,22 @@ public class DwarvenMinesCategory {
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.dwarvenHud"))
.collapsed(false)
.option(Option.<Boolean>createBuilder()
- .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.dwarvenHud.enabled"))
- .binding(defaults.locations.dwarvenMines.dwarvenHud.enabled,
- () -> config.locations.dwarvenMines.dwarvenHud.enabled,
- newValue -> config.locations.dwarvenMines.dwarvenHud.enabled = newValue)
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.dwarvenHud.enabledCommissions"))
+ .binding(defaults.locations.dwarvenMines.dwarvenHud.enabledCommissions,
+ () -> config.locations.dwarvenMines.dwarvenHud.enabledCommissions,
+ newValue -> config.locations.dwarvenMines.dwarvenHud.enabledCommissions = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.dwarvenHud.enabledPowder"))
+ .binding(defaults.locations.dwarvenMines.dwarvenHud.enabledPowder,
+ () -> config.locations.dwarvenMines.dwarvenHud.enabledPowder,
+ newValue -> config.locations.dwarvenMines.dwarvenHud.enabledPowder = newValue)
.controller(ConfigUtils::createBooleanController)
.build())
.option(Option.<SkyblockerConfig.DwarvenHudStyle>createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.dwarvenHud.style"))
- .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.dwarvenHud.style.@Tooltip[0]"),
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.dwarvenHud.style.@Tooltip[0]"),
Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.dwarvenHud.style.@Tooltip[1]"),
Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.dwarvenHud.style.@Tooltip[2]")))
.binding(defaults.locations.dwarvenMines.dwarvenHud.style,
@@ -74,6 +84,68 @@ public class DwarvenMinesCategory {
.controller(ConfigUtils::createBooleanController)
.build())
.build())
+ //crystal HUD
+ .group(OptionGroup.createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.crystalsHud"))
+ .collapsed(false)
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.crystalsHud.enabled"))
+ .binding(defaults.locations.dwarvenMines.crystalsHud.enabled,
+ () -> config.locations.dwarvenMines.crystalsHud.enabled,
+ newValue -> config.locations.dwarvenMines.crystalsHud.enabled = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(ButtonOption.createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.crystalsHud.screen"))
+ .text(Text.translatable("text.skyblocker.open"))
+ .action((screen, opt) -> MinecraftClient.getInstance().setScreen(new CrystalsHudConfigScreen(screen)))
+ .build())
+ .option(Option.<Float>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.crystalsHud.mapScaling"))
+ .binding(defaults.locations.dwarvenMines.crystalsHud.mapScaling,
+ () -> config.locations.dwarvenMines.crystalsHud.mapScaling,
+ newValue -> config.locations.dwarvenMines.crystalsHud.mapScaling = newValue)
+ .controller(FloatFieldControllerBuilder::create)
+ .build())
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.crystalsHud.showLocations"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.crystalsHud.showLocations.@Tooltip")))
+ .binding(defaults.locations.dwarvenMines.crystalsHud.showLocations,
+ () -> config.locations.dwarvenMines.crystalsHud.showLocations,
+ newValue -> config.locations.dwarvenMines.crystalsHud.showLocations = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Integer>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.crystalsHud.showLocations.locationSize"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.crystalsHud.showLocations.locationSize.@Tooltip")))
+ .binding(defaults.locations.dwarvenMines.crystalsHud.locationSize,
+ () -> config.locations.dwarvenMines.crystalsHud.locationSize,
+ newValue -> config.locations.dwarvenMines.crystalsHud.locationSize = newValue)
+ .controller(opt -> IntegerSliderControllerBuilder.create(opt).range(4, 12).step(2))
+ .build())
+ .build())
+ //crystals waypoints
+ .group(OptionGroup.createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.crystalsWaypoints"))
+ .collapsed(false)
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.crystalsWaypoints.enabled"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.crystalsWaypoints.enabled.@Tooltip")))
+ .binding(defaults.locations.dwarvenMines.crystalsWaypoints.enabled,
+ () -> config.locations.dwarvenMines.crystalsWaypoints.enabled,
+ newValue -> config.locations.dwarvenMines.crystalsWaypoints.enabled = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.crystalsWaypoints.findInChat"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.crystalsWaypoints.findInChat.@Tooltip")))
+ .binding(defaults.locations.dwarvenMines.crystalsWaypoints.findInChat,
+ () -> config.locations.dwarvenMines.crystalsWaypoints.findInChat,
+ newValue -> config.locations.dwarvenMines.crystalsWaypoints.findInChat = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+
+ .build())
.build();
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsHud.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsHud.java
new file mode 100644
index 00000000..7b15c61e
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsHud.java
@@ -0,0 +1,164 @@
+package de.hysky.skyblocker.skyblock.dwarven;
+
+import de.hysky.skyblocker.SkyblockerMod;
+import de.hysky.skyblocker.config.SkyblockerConfigManager;
+import de.hysky.skyblocker.utils.Utils;
+import de.hysky.skyblocker.utils.scheduler.Scheduler;
+import it.unimi.dsi.fastutil.ints.IntIntPair;
+import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager;
+import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
+import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.util.Identifier;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.math.RotationAxis;
+
+import java.awt.*;
+import java.util.Arrays;
+import java.util.Map;
+
+import org.joml.Vector2i;
+import org.joml.Vector2ic;
+
+public class CrystalsHud {
+ private static final MinecraftClient CLIENT = MinecraftClient.getInstance();
+ protected static final Identifier MAP_TEXTURE = new Identifier(SkyblockerMod.NAMESPACE, "textures/gui/crystals_map.png");
+ private static final Identifier MAP_ICON = new Identifier("textures/map/map_icons.png");
+ private static final String[] SMALL_LOCATIONS = { "Fairy Grotto", "King Yolkar", "Corleone", "Odawa", "Key Guardian" };
+
+ public static boolean visible = false;
+
+ public static void init() {
+ ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(ClientCommandManager.literal("skyblocker")
+ .then(ClientCommandManager.literal("hud")
+ .then(ClientCommandManager.literal("crystals")
+ .executes(Scheduler.queueOpenScreenCommand(CrystalsHudConfigScreen::new))))));
+
+ HudRenderCallback.EVENT.register((context, tickDelta) -> {
+ if (!SkyblockerConfigManager.get().locations.dwarvenMines.crystalsHud.enabled
+ || CLIENT.player == null
+ || !visible) {
+ return;
+ }
+ render(context, tickDelta, SkyblockerConfigManager.get().locations.dwarvenMines.crystalsHud.x,
+ SkyblockerConfigManager.get().locations.dwarvenMines.crystalsHud.y);
+ });
+ }
+
+ protected static IntIntPair getDimensionsForConfig() {
+ int size = (int) (62 * SkyblockerConfigManager.get().locations.dwarvenMines.crystalsHud.mapScaling);
+ return IntIntPair.of(size, size);
+ }
+
+
+ /**
+ * Renders the map to the players UI. renders the background image ({@link CrystalsHud#MAP_TEXTURE}) of the map then if enabled special locations on the map. then finally the player to the map.
+ *
+ * @param context DrawContext to draw map to
+ * @param tickDelta For interpolating the player's yaw for map marker
+ * @param hudX Top left X coordinate of the map
+ * @param hudY Top left Y coordinate of the map
+ */
+ private static void render(DrawContext context, float tickDelta, int hudX, int hudY) {
+ float scale = SkyblockerConfigManager.get().locations.dwarvenMines.crystalsHud.mapScaling;
+
+ //make sure the map renders infront of some stuff - improve this in the future with better layering (1.20.5?)
+ //and set position and scale
+ MatrixStack matrices = context.getMatrices();
+ matrices.push();
+ matrices.translate(hudX, hudY, 200f);
+ matrices.scale(scale, scale, 0f);
+
+ //draw map texture
+ context.drawTexture(MAP_TEXTURE, 0, 0, 0, 0, 62, 62, 62, 62);
+
+ //if enabled add waypoint locations to map
+ if (SkyblockerConfigManager.get().locations.dwarvenMines.crystalsHud.showLocations) {
+ Map<String,CrystalsWaypoint> ActiveWaypoints = CrystalsLocationsManager.activeWaypoints;
+
+ for (CrystalsWaypoint waypoint : ActiveWaypoints.values()) {
+ Color waypointColor = waypoint.category.color;
+ Vector2ic renderPos = transformLocation(waypoint.pos.getX(), waypoint.pos.getZ());
+ int locationSize = SkyblockerConfigManager.get().locations.dwarvenMines.crystalsHud.locationSize;
+
+ if (Arrays.asList(SMALL_LOCATIONS).contains(waypoint.name.getString())) {//if small location half the location size
+ locationSize = 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());
+ }
+ }
+
+ //draw player on map
+ if (CLIENT.player == null || CLIENT.getNetworkHandler() == null) {
+ return;
+ }
+
+ //get player location
+ double playerX = CLIENT.player.getX();
+ double playerZ = CLIENT.player.getZ();
+ float playerRotation = CLIENT.player.getYaw(); //TODO make the transitions more rough?
+ Vector2ic renderPos = transformLocation(playerX, playerZ);
+
+ int renderX = renderPos.x() - 2;
+ int renderY = renderPos.y() - 3;
+
+ //position, scale and rotate the player marker
+ matrices.translate(renderX, renderY, 0f);
+ matrices.scale(0.75f, 0.75f, 0f);
+ matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(yaw2Cardinal(playerRotation)), 2.5f, 3.5f, 0);
+
+ //draw marker on map
+ context.drawTexture(MAP_ICON, 0, 0, 2, 0, 5, 7, 128, 128);
+
+ //todo add direction (can not work out how to rotate)
+ matrices.pop();
+ }
+
+ /**
+ * Converts an X and Z coordinate in the crystal hollow to a X and Y coordinate on the map.
+ *
+ * @param x the world X coordinate
+ * @param z the world Z coordinate
+ * @return a vector representing the x and y values
+ */
+ protected static Vector2ic transformLocation(double x, double z) {
+ //converts an x and z to a location on the map
+ int transformedX = (int) ((x - 202) / 621 * 62);
+ int transformedY = (int) ((z - 202) / 621 * 62);
+ transformedX = MathHelper.clamp(transformedX, 0, 62);
+ transformedY = MathHelper.clamp(transformedY, 0, 62);
+
+ return new Vector2i(transformedX, transformedY);
+ }
+
+ /**
+ * Converts yaw to the cardinal directions that a player marker can be rotated towards on a map.
+ * The rotations of a marker follow this order: N, NNE, NE, ENE, E, ESE, SE, SSE, S, SSW, SW, WSW, W, WNW, NW, NNW.
+ * <br><br>
+ * Based off code from {@link net.minecraft.client.render.MapRenderer}
+ */
+ private static float yaw2Cardinal(float yaw) {
+ yaw += + 180; //flip direction
+ byte clipped = (byte) ((yaw += yaw < 0.0 ? -8.0 : 8.0) * 16.0 / 360.0);
+
+ return (clipped * 360f) / 16f;
+ }
+
+ /**
+ * Works out if the crystals map should be rendered and sets {@link CrystalsHud#visible} accordingly.
+ *
+ */
+ public static void update() {
+ if (CLIENT.player == null || CLIENT.getNetworkHandler() == null || !SkyblockerConfigManager.get().locations.dwarvenMines.crystalsHud.enabled) {
+ visible = false;
+ return;
+ }
+
+ //get if the player is in the crystals
+ visible = Utils.isInCrystalHollows();
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsHudConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsHudConfigScreen.java
new file mode 100644
index 00000000..b4e423e9
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsHudConfigScreen.java
@@ -0,0 +1,69 @@
+package de.hysky.skyblocker.skyblock.dwarven;
+
+import de.hysky.skyblocker.config.SkyblockerConfigManager;
+import de.hysky.skyblocker.utils.render.RenderHelper;
+import it.unimi.dsi.fastutil.ints.IntIntPair;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.text.Text;
+
+import java.awt.*;
+
+public class CrystalsHudConfigScreen extends Screen {
+
+ private int hudX = SkyblockerConfigManager.get().locations.dwarvenMines.crystalsHud.x;
+ private int hudY = SkyblockerConfigManager.get().locations.dwarvenMines.crystalsHud.y;
+ private final Screen parent;
+
+ protected CrystalsHudConfigScreen() {
+ this(null);
+ }
+
+ public CrystalsHudConfigScreen(Screen parent) {
+ super(Text.of("Crystals HUD Config"));
+ this.parent = parent;
+ }
+
+ @Override
+ public void render(DrawContext context, int mouseX, int mouseY, float delta) {
+ super.render(context, mouseX, mouseY, delta);
+ renderBackground(context, mouseX, mouseY, delta);
+ renderHUDMap(context, hudX, hudY);
+ context.drawCenteredTextWithShadow(textRenderer, "Right Click To Reset Position", width / 2, height / 2, Color.GRAY.getRGB());
+ }
+
+ @Override
+ public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
+ IntIntPair dims = CrystalsHud.getDimensionsForConfig();
+ if (RenderHelper.pointIsInArea(mouseX, mouseY, hudX, hudY, hudX + dims.leftInt(), hudY + dims.rightInt()) && button == 0) {
+ hudX = (int) Math.max(Math.min(mouseX - (double) dims.leftInt() / 2, this.width - dims.leftInt()), 0);
+ hudY = (int) Math.max(Math.min(mouseY - (double) dims.rightInt() / 2, this.height - dims.rightInt()), 0);
+ }
+ return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
+ }
+
+ @Override
+ public boolean mouseClicked(double mouseX, double mouseY, int button) {
+ if (button == 1) {
+ IntIntPair dims = CrystalsHud.getDimensionsForConfig();
+ hudX = this.width / 2 - dims.leftInt();
+ hudY = this.height / 2 - dims.rightInt();
+ }
+ return super.mouseClicked(mouseX, mouseY, button);
+ }
+
+ private void renderHUDMap(DrawContext context, int x, int y) {
+ float scaling = SkyblockerConfigManager.get().locations.dwarvenMines.crystalsHud.mapScaling;
+ int size = (int) (62 * scaling);
+ context.drawTexture(CrystalsHud.MAP_TEXTURE, x, y, 0, 0, size, size, size, size);
+ }
+
+ @Override
+ public void close() {
+ SkyblockerConfigManager.get().locations.dwarvenMines.crystalsHud.x = hudX;
+ SkyblockerConfigManager.get().locations.dwarvenMines.crystalsHud.y = hudY;
+ SkyblockerConfigManager.save();
+
+ client.setScreen(parent);
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java
new file mode 100644
index 00000000..0a4e4518
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java
@@ -0,0 +1,195 @@
+package de.hysky.skyblocker.skyblock.dwarven;
+
+import com.mojang.brigadier.Command;
+import com.mojang.brigadier.CommandDispatcher;
+import com.mojang.brigadier.arguments.StringArgumentType;
+import com.mojang.logging.LogUtils;
+
+import de.hysky.skyblocker.SkyblockerMod;
+import de.hysky.skyblocker.config.SkyblockerConfigManager;
+import de.hysky.skyblocker.utils.Constants;
+import de.hysky.skyblocker.utils.Utils;
+import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
+import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
+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;
+import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.command.CommandRegistryAccess;
+import net.minecraft.command.argument.BlockPosArgumentType;
+import net.minecraft.command.argument.PosArgument;
+import net.minecraft.server.command.ServerCommandSource;
+import net.minecraft.text.ClickEvent;
+import net.minecraft.text.MutableText;
+import net.minecraft.text.Text;
+import net.minecraft.util.math.BlockPos;
+
+import java.awt.*;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import org.slf4j.Logger;
+
+import static com.mojang.brigadier.arguments.StringArgumentType.getString;
+import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument;
+import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;
+
+public class CrystalsLocationsManager {
+ private static final Logger LOGGER = LogUtils.getLogger();
+ private static final MinecraftClient CLIENT = MinecraftClient.getInstance();
+
+ /**
+ * A look-up table to convert between location names and waypoint in the {@link CrystalsWaypoint.Category} values.
+ */
+ protected static final Map<String, CrystalsWaypoint.Category> WAYPOINT_LOCATIONS = Arrays.stream(CrystalsWaypoint.Category.values()).collect(Collectors.toMap(CrystalsWaypoint.Category::toString, 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<String, CrystalsWaypoint> activeWaypoints = new HashMap<>();
+
+ public static void init() {
+ WorldRenderEvents.AFTER_TRANSLUCENT.register(CrystalsLocationsManager::render);
+ ClientReceiveMessageEvents.GAME.register(CrystalsLocationsManager::extractLocationFromMessage);
+ ClientCommandRegistrationCallback.EVENT.register(CrystalsLocationsManager::registerWaypointLocationCommands);
+ ClientPlayConnectionEvents.JOIN.register((_handler, _sender, _client) -> reset());
+ }
+
+ private static void extractLocationFromMessage(Text message, Boolean overlay) {
+ if (!SkyblockerConfigManager.get().locations.dwarvenMines.crystalsWaypoints.findInChat || !Utils.isInCrystalHollows()) {
+ return;
+ }
+
+ try {
+ //get the message text
+ String value = message.getString();
+ 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]);
+
+ //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 (value.toLowerCase().contains(waypointLocation.toLowerCase())) { //todo be more lenient
+ //all data found to create waypoint
+ addCustomWaypoint(Text.of(waypointLocation),blockPos);
+ 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);
+ }
+ } catch (Exception e) {
+ LOGGER.error("[Skyblocker Crystals Locations Manager] Encountered an exception while extracing a location from a chat message!", e);
+ }
+ }
+ protected static Boolean checkInCrystals(BlockPos pos){
+ //checks if a location is inside crystal hollows bounds
+ return pos.getX() >= 202 && pos.getX() <= 823
+ && pos.getZ() >= 202 && pos.getZ() <= 823
+ && pos.getY() >= 31 && pos.getY() <= 188;
+ }
+
+ private static void registerWaypointLocationCommands(CommandDispatcher<FabricClientCommandSource> dispatcher, CommandRegistryAccess registryAccess) {
+ dispatcher.register(literal(SkyblockerMod.NAMESPACE)
+ .then(literal("crystalWaypoints")
+ .then(argument("pos", BlockPosArgumentType.blockPos())
+ .then(argument("place", StringArgumentType.greedyString())
+ .executes(context -> addWaypointFromCommand(context.getSource(), getString(context, "place"), context.getArgument("pos", PosArgument.class)))
+ )
+ )
+ )
+ );
+ }
+
+ 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()));
+ text.append(Text.literal(" at : " + blockPos.getX() + " " + blockPos.getY() + " " + blockPos.getZ() + "."));
+
+ return text;
+ }
+
+ private static Text getLocationInputText(String location) {
+ 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))));
+ }
+
+ return text;
+ }
+
+ public static int addWaypointFromCommand(FabricClientCommandSource source, String place, PosArgument location) {
+ // TODO Less hacky way with custom ClientBlockPosArgumentType
+ BlockPos blockPos = location.toAbsoluteBlockPos(new ServerCommandSource(null, source.getPosition(), source.getRotation(), null, 0, null, null, null, null));
+
+ if (WAYPOINT_LOCATIONS.containsKey(place)) {
+ addCustomWaypoint(Text.of(place), blockPos);
+
+ //tell the client it has done this
+ if (CLIENT.player == null || CLIENT.getNetworkHandler() == null) {
+ return 0;
+ }
+
+ CLIENT.player.sendMessage(getSetLocationMessage(place, blockPos), false);
+ }
+
+ return Command.SINGLE_SUCCESS;
+ }
+
+
+ private static void addCustomWaypoint( Text waypointName, BlockPos pos) {
+ CrystalsWaypoint.Category category = WAYPOINT_LOCATIONS.get(waypointName.getString());
+ CrystalsWaypoint waypoint = new CrystalsWaypoint(category, waypointName, pos);
+ activeWaypoints.put(waypointName.getString(), waypoint);
+ }
+
+ public static void render(WorldRenderContext context) {
+ if (SkyblockerConfigManager.get().locations.dwarvenMines.crystalsWaypoints.enabled) {
+ for (CrystalsWaypoint crystalsWaypoint : activeWaypoints.values()) {
+ if (crystalsWaypoint.shouldRender()) {
+ crystalsWaypoint.render(context);
+ }
+ }
+ }
+ }
+
+ private static void reset() {
+ activeWaypoints.clear();
+ }
+
+ public static void update() {
+ if (CLIENT.player == null || CLIENT.getNetworkHandler() == null || !SkyblockerConfigManager.get().locations.dwarvenMines.crystalsWaypoints.enabled || !Utils.isInCrystalHollows()) {
+ return;
+ }
+
+ //get if the player is in the crystals
+ String location = Utils.getIslandArea().replace("⏣ ", "");
+ //if new location and needs waypoint add waypoint
+ if (!location.equals("Unknown") && WAYPOINT_LOCATIONS.containsKey(location) && !activeWaypoints.containsKey(location)) {
+ //add waypoint at player location
+ BlockPos playerLocation = CLIENT.player.getBlockPos();
+ addCustomWaypoint(Text.of(location), playerLocation);
+ }
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsWaypoint.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsWaypoint.java
new file mode 100644
index 00000000..fbb43083
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsWaypoint.java
@@ -0,0 +1,98 @@
+package de.hysky.skyblocker.skyblock.dwarven;
+
+import de.hysky.skyblocker.config.SkyblockerConfig;
+import de.hysky.skyblocker.config.SkyblockerConfigManager;
+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<SkyblockerConfig.Waypoints> CONFIG = () -> SkyblockerConfigManager.get().general.waypoints;
+ private static final Supplier<Type> 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<CrystalsWaypoint> getSquaredDistanceToFunction(Entity entity) {
+ return crystalsWaypoint -> entity.squaredDistanceTo(crystalsWaypoint.centerPos);
+ }
+
+ static Predicate<CrystalsWaypoint> 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/DwarvenHud.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHud.java
index 6fa03816..4446c1a7 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHud.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHud.java
@@ -3,7 +3,10 @@ package de.hysky.skyblocker.skyblock.dwarven;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.skyblock.tabhud.util.Colors;
import de.hysky.skyblocker.skyblock.tabhud.widget.hud.HudCommsWidget;
+import de.hysky.skyblocker.skyblock.tabhud.widget.hud.HudPowderWidget;
+import de.hysky.skyblocker.utils.Utils;
import de.hysky.skyblocker.utils.scheduler.Scheduler;
+import it.unimi.dsi.fastutil.Pair;
import it.unimi.dsi.fastutil.ints.IntIntPair;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
@@ -25,6 +28,9 @@ public class DwarvenHud {
public static final MinecraftClient client = MinecraftClient.getInstance();
public static List<Commission> commissionList = new ArrayList<>();
+ public static String mithrilPowder = "0";
+ public static String gemStonePowder = "0";
+
public static final List<Pattern> COMMISSIONS = Stream.of(
"(?:Titanium|Mithril|Hard Stone) Miner",
"(?:Ice Walker|Golden Goblin|(?<!Golden )Goblin|Goblin Raid|Automaton|Sludge|Team Treasurite Member|Yog|Boss Corleone|Thyst) Slayer",
@@ -39,6 +45,8 @@ public class DwarvenHud {
"(?:Amber|Sapphire|Jade|Amethyst|Topaz) Crystal Hunter",
"Chest Looter").map(s -> Pattern.compile("^.*(" + s + "): (\\d+\\.?\\d*%|DONE)"))
.collect(Collectors.toList());
+ public static final Pattern MITHRIL_PATTERN = Pattern.compile("Mithril Powder: [0-9,]+");
+ public static final Pattern GEMSTONE_PATTERN = Pattern.compile("Gemstone Powder: [0-9,]+");
public static void init() {
ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(ClientCommandManager.literal("skyblocker")
@@ -47,94 +55,162 @@ public class DwarvenHud {
.executes(Scheduler.queueOpenScreenCommand(DwarvenHudConfigScreen::new))))));
HudRenderCallback.EVENT.register((context, tickDelta) -> {
- if (!SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.enabled
+ if ((!SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.enabledCommissions && !SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.enabledPowder)
|| client.options.playerListKey.isPressed()
|| client.player == null
- || commissionList.isEmpty()) {
+ || (!Utils.isInDwarvenMines() && !Utils.isInCrystalHollows())) {
return;
}
- render(HudCommsWidget.INSTANCE, context, SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.x,
- SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.y, commissionList);
+
+ render(HudCommsWidget.INSTANCE, HudPowderWidget.INSTANCE, context,
+ SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.x,
+ SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.y,
+ SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.powderX,
+ SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.powderY,
+ commissionList);
});
}
- public static IntIntPair getDimForConfig(List<Commission> commissions) {
+ /**
+ * Gets the dimensions (width, height) for the commissions hud and the powder hud
+ * @param commissions what commissions to get the dimensions for
+ * @return a {@link Pair} of {@link IntIntPair} with the first pair being for the commissions hud and the second pair being for the powder hud
+ */
+ public static Pair<IntIntPair,IntIntPair> getDimForConfig(List<Commission> commissions) {
return switch (SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.style) {
case SIMPLE -> {
HudCommsWidget.INSTANCE_CFG.updateData(commissions, false);
- yield IntIntPair.of(
- HudCommsWidget.INSTANCE_CFG.getWidth(),
- HudCommsWidget.INSTANCE_CFG.getHeight());
+ yield Pair.of(
+ IntIntPair.of(
+ HudCommsWidget.INSTANCE_CFG.getWidth(),
+ HudCommsWidget.INSTANCE_CFG.getHeight()),
+ IntIntPair.of(
+ HudPowderWidget.INSTANCE_CFG.getWidth(),
+ HudPowderWidget.INSTANCE_CFG.getHeight())
+ );
}
case FANCY -> {
HudCommsWidget.INSTANCE_CFG.updateData(commissions, true);
- yield IntIntPair.of(
- HudCommsWidget.INSTANCE_CFG.getWidth(),
- HudCommsWidget.INSTANCE_CFG.getHeight());
+ yield Pair.of(
+ IntIntPair.of(
+ HudCommsWidget.INSTANCE_CFG.getWidth(),
+ HudCommsWidget.INSTANCE_CFG.getHeight()),
+ IntIntPair.of(
+ HudPowderWidget.INSTANCE_CFG.getWidth(),
+ HudPowderWidget.INSTANCE_CFG.getHeight())
+ );
}
- default -> IntIntPair.of(200, 20 * commissions.size());
+ default -> Pair.of(
+ IntIntPair.of(
+ 200,
+ 20 * commissions.size()),
+ IntIntPair.of(
+ 200,
+ 40)
+ );
};
}
- public static void render(HudCommsWidget hcw, DrawContext context, int hudX, int hudY, List<Commission> commissions) {
+ public static void render(HudCommsWidget hcw, HudPowderWidget hpw, DrawContext context, int comHudX, int comHudY, int powderHudX, int powderHudY, List<Commission> commissions) {
switch (SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.style) {
- case SIMPLE -> renderSimple(hcw, context, hudX, hudY, commissions);
- case FANCY -> renderFancy(hcw, context, hudX, hudY, commissions);
- case CLASSIC -> renderClassic(context, hudX, hudY, commissions);
+ case SIMPLE -> renderSimple(hcw,hpw, context, comHudX, comHudY,powderHudX,powderHudY, commissions);
+ case FANCY -> renderFancy(hcw,hpw, context, comHudX, comHudY,powderHudX,powderHudY, commissions);
+ case CLASSIC -> renderClassic(context, comHudX, comHudY,powderHudX,powderHudY, commissions);
}
}
- public static void renderClassic(DrawContext context, int hudX, int hudY, List<Commission> commissions) {
+ /**
+ * Renders hud to window without using the widget rendering
+ * @param context DrawContext to draw the hud to
+ * @param comHudX X coordinate of the commissions hud
+ * @param comHudY Y coordinate of the commissions hud
+ * @param powderHudX X coordinate of the powder hud
+ * @param powderHudY Y coordinate of the powder hud
+ * @param commissions the commissions to render to the commissions hud
+ */
+ public static void renderClassic(DrawContext context, int comHudX, int comHudY, int powderHudX, int powderHudY, List<Commission> commissions) {
if (SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.enableBackground) {
- context.fill(hudX, hudY, hudX + 200, hudY + (20 * commissions.size()), 0x64000000);
+ context.fill(comHudX, comHudY, comHudX + 200, comHudY + (20 * commissions.size()), 0x64000000);
+ context.fill(powderHudX, powderHudY, powderHudX + 200, powderHudY + 40, 0x64000000);
}
+ if (SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.enabledCommissions) {
+ int y = 0;
+ for (Commission commission : commissions) {
+ float percentage;
+ if (!commission.progression().contains("DONE")) {
+ percentage = Float.parseFloat(commission.progression().substring(0, commission.progression().length() - 1));
+ } else {
+ percentage = 100f;
+ }
- int y = 0;
- for (Commission commission : commissions) {
- float percentage;
- if (!commission.progression().contains("DONE")) {
- percentage = Float.parseFloat(commission.progression().substring(0, commission.progression().length() - 1));
- } else {
- percentage = 100f;
+ context
+ .drawTextWithShadow(client.textRenderer,
+ Text.literal(commission.commission + ": ").formatted(Formatting.AQUA)
+ .append(Text.literal(commission.progression).formatted(Colors.hypixelProgressColor(percentage))),
+ comHudX + 5, comHudY + y + 5, 0xFFFFFFFF);
+ y += 20;
}
-
+ }
+ if(SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.enabledPowder) {
+ //render mithril powder then gemstone
+ context
+ .drawTextWithShadow(client.textRenderer,
+ Text.literal("Mithril: " + mithrilPowder).formatted(Formatting.AQUA),
+ powderHudX + 5, powderHudY + 5, 0xFFFFFFFF);
context
.drawTextWithShadow(client.textRenderer,
- Text.literal(commission.commission + ": ")
- .styled(style -> style.withColor(Formatting.AQUA))
- .append(Text.literal(commission.progression)
- .styled(style -> style.withColor(Colors.hypixelProgressColor(percentage)))),
- hudX + 5, hudY + y + 5, 0xFFFFFFFF);
- y += 20;
+ Text.literal("Gemstone: " + gemStonePowder).formatted(Formatting.DARK_PURPLE),
+ powderHudX + 5, powderHudY + 25, 0xFFFFFFFF);
}
}
- public static void renderSimple(HudCommsWidget hcw, DrawContext context, int hudX, int hudY, List<Commission> commissions) {
- hcw.updateData(commissions, false);
- hcw.update();
- hcw.setX(hudX);
- hcw.setY(hudY);
- hcw.render(context,
- SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.enableBackground);
+ public static void renderSimple(HudCommsWidget hcw, HudPowderWidget hpw, DrawContext context, int comHudX, int comHudY, int powderHudX, int powderHudY, List<Commission> commissions) {
+ if (SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.enabledCommissions) {
+ hcw.updateData(commissions, false);
+ hcw.update();
+ hcw.setX(comHudX);
+ hcw.setY(comHudY);
+ hcw.render(context,
+ SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.enableBackground);
+ }
+ if (SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.enabledPowder) {
+ hpw.update();
+ hpw.setX(powderHudX);
+ hpw.setY(powderHudY);
+ hpw.render(context,
+ SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.enableBackground);
+ }
}
- public static void renderFancy(HudCommsWidget hcw, DrawContext context, int hudX, int hudY, List<Commission> commissions) {
- hcw.updateData(commissions, true);
- hcw.update();
- hcw.setX(hudX);
- hcw.setY(hudY);
- hcw.render(context,
- SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.enableBackground);
+ public static void renderFancy(HudCommsWidget hcw, HudPowderWidget hpw, DrawContext context, int comHudX, int comHudY, int powderHudX, int powderHudY, List<Commission> commissions) {
+ if (SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.enabledCommissions) {
+ hcw.updateData(commissions, true);
+ hcw.update();
+ hcw.setX(comHudX);
+ hcw.setY(comHudY);
+ hcw.render(context,
+ SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.enableBackground);
+ }
+ if (SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.enabledPowder) {
+ hpw.update();
+ hpw.setX(powderHudX);
+ hpw.setY(powderHudY);
+ hpw.render(context,
+ SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.enableBackground);
+ }
}
public static void update() {
- commissionList = new ArrayList<>();
- if (client.player == null || client.getNetworkHandler() == null || !SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.enabled)
+ if (client.player == null || client.getNetworkHandler() == null || !SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.enabledCommissions || (!Utils.isInCrystalHollows()
+ && !Utils.isInDwarvenMines()))
return;
+ commissionList = new ArrayList<>();
+
client.getNetworkHandler().getPlayerList().forEach(playerListEntry -> {
if (playerListEntry.getDisplayName() != null) {
+ //find commissions
for (Pattern pattern : COMMISSIONS) {
Matcher matcher = pattern.matcher(playerListEntry.getDisplayName().getString());
if (matcher.find()) {
@@ -142,6 +218,15 @@ public class DwarvenHud {
}
}
+ //find powder
+ Matcher mithrilMatcher = MITHRIL_PATTERN.matcher(playerListEntry.getDisplayName().getString());
+ if (mithrilMatcher.find()){
+ mithrilPowder = mithrilMatcher.group(0).split(": ")[1];
+ }
+ Matcher gemstoneMatcher = GEMSTONE_PATTERN.matcher(playerListEntry.getDisplayName().getString());
+ if (gemstoneMatcher.find()){
+ gemStonePowder = gemstoneMatcher.group(0).split(": ")[1];
+ }
}
});
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java
index 6f281ba9..d5dc19f2 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java
@@ -3,7 +3,9 @@ package de.hysky.skyblocker.skyblock.dwarven;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.skyblock.dwarven.DwarvenHud.Commission;
import de.hysky.skyblocker.skyblock.tabhud.widget.hud.HudCommsWidget;
+import de.hysky.skyblocker.skyblock.tabhud.widget.hud.HudPowderWidget;
import de.hysky.skyblocker.utils.render.RenderHelper;
+import it.unimi.dsi.fastutil.Pair;
import it.unimi.dsi.fastutil.ints.IntIntPair;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
@@ -15,9 +17,11 @@ import java.util.List;
public class DwarvenHudConfigScreen extends Screen {
private static final List<DwarvenHud.Commission> CFG_COMMS = List.of(new Commission("Test Commission 1", "1%"), new DwarvenHud.Commission("Test Commission 2", "2%"));
+ private int commissionsHudX = SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.x;
+ private int commissionsHudY = SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.y;
- private int hudX = SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.x;
- private int hudY = SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.y;
+ private int powderHudX = SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.powderX;
+ private int powderHudY = SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.powderY;
private final Screen parent;
protected DwarvenHudConfigScreen() {
@@ -33,16 +37,20 @@ public class DwarvenHudConfigScreen extends Screen {
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
super.render(context, mouseX, mouseY, delta);
renderBackground(context, mouseX, mouseY, delta);
- DwarvenHud.render(HudCommsWidget.INSTANCE_CFG, context, hudX, hudY, List.of(new DwarvenHud.Commission("Test Commission 1", "1%"), new DwarvenHud.Commission("Test Commission 2", "2%")));
+ DwarvenHud.render(HudCommsWidget.INSTANCE_CFG, HudPowderWidget.INSTANCE_CFG, context, commissionsHudX, commissionsHudY, powderHudX, powderHudY, CFG_COMMS);
context.drawCenteredTextWithShadow(textRenderer, "Right Click To Reset Position", width / 2, height / 2, Color.GRAY.getRGB());
}
@Override
public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
- IntIntPair dims = DwarvenHud.getDimForConfig(CFG_COMMS);
- if (RenderHelper.pointIsInArea(mouseX, mouseY, hudX, hudY, hudX + 200, hudY + 40) && button == 0) {
- hudX = (int) Math.max(Math.min(mouseX - (double) dims.leftInt() / 2, this.width - dims.leftInt()), 0);
- hudY = (int) Math.max(Math.min(mouseY - (double) dims.rightInt() / 2, this.height - dims.rightInt()), 0);
+ Pair<IntIntPair,IntIntPair> dims = DwarvenHud.getDimForConfig(CFG_COMMS);
+ if (RenderHelper.pointIsInArea(mouseX, mouseY, commissionsHudX, commissionsHudY, commissionsHudX + 200, commissionsHudY + 40) && button == 0) {
+ commissionsHudX = (int) Math.max(Math.min(mouseX - (double) dims.first().leftInt() / 2, this.width - dims.first().leftInt()), 0);
+ commissionsHudY = (int) Math.max(Math.min(mouseY - (double) dims.first().rightInt() / 2, this.height - dims.first().rightInt()), 0);
+ }
+ if (RenderHelper.pointIsInArea(mouseX, mouseY, powderHudX, powderHudY, powderHudX + 200, powderHudY + 40) && button == 0) {
+ powderHudX = (int) Math.max(Math.min(mouseX - (double) dims.second().leftInt() / 2, this.width - dims.second().leftInt()), 0);
+ powderHudY = (int) Math.max(Math.min(mouseY - (double) dims.second().rightInt() / 2, this.height - dims.second().rightInt()), 0);
}
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
}
@@ -50,17 +58,21 @@ public class DwarvenHudConfigScreen extends Screen {
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (button == 1) {
- IntIntPair dims = DwarvenHud.getDimForConfig(CFG_COMMS);
- hudX = this.width / 2 - dims.leftInt();
- hudY = this.height / 2 - dims.rightInt();
+ Pair<IntIntPair,IntIntPair> dims = DwarvenHud.getDimForConfig(CFG_COMMS);
+ commissionsHudX = this.width / 2 - dims.left().leftInt();
+ commissionsHudY = this.height / 2 - dims.left().rightInt();
+ powderHudX = this.width / 2 - dims.right().leftInt();
+ powderHudY = this.height / 2 - dims.right().rightInt() + dims.left().rightInt(); //add this to make it bellow the other widget
}
return super.mouseClicked(mouseX, mouseY, button);
}
@Override
public void close() {
- SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.x = hudX;
- SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.y = hudY;
+ SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.x = commissionsHudX;
+ SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.y = commissionsHudY;
+ SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.powderX = powderHudX;
+ SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.powderY = powderHudY;
SkyblockerConfigManager.save();
client.setScreen(parent);
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/hud/HudPowderWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/hud/HudPowderWidget.java
new file mode 100644
index 00000000..1d11c2a6
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/hud/HudPowderWidget.java
@@ -0,0 +1,40 @@
+package de.hysky.skyblocker.skyblock.tabhud.widget.hud;
+
+import de.hysky.skyblocker.skyblock.tabhud.util.Ico;
+import de.hysky.skyblocker.skyblock.tabhud.widget.Widget;
+import net.minecraft.text.MutableText;
+import net.minecraft.text.Text;
+import net.minecraft.util.Formatting;
+
+// this widget shows the status of the king's commissions.
+// (dwarven mines and crystal hollows)
+// USE ONLY WITH THE DWARVEN HUD!
+
+public class HudPowderWidget extends Widget {
+
+ private static final MutableText TITLE = Text.literal("Powders").formatted(Formatting.DARK_AQUA,
+ Formatting.BOLD);
+
+
+ // disgusting hack to get around text renderer issues.
+ // the ctor eventually tries to get the font's height, which doesn't work
+ // when called before the client window is created (roughly).
+ // the rebdering god 2 from the fabricord explained that detail, thanks!
+ //coppied from the HodCommsWidget to be used in the same place
+ public static final HudPowderWidget INSTANCE = new HudPowderWidget();
+ public static final HudPowderWidget INSTANCE_CFG = new HudPowderWidget();
+
+ // another repulsive hack to make this widget-like hud element work with the new widget class
+ // DON'T USE WITH THE WIDGET SYSTEM, ONLY USE FOR DWARVENHUD!
+ public HudPowderWidget() {
+ super(TITLE, Formatting.DARK_AQUA.getColorValue());
+ }
+
+
+ @Override
+ public void updateContent() {
+ this.addSimpleIcoText(Ico.MITHRIL, "Mithril:", Formatting.AQUA, 46);
+ this.addSimpleIcoText(Ico.AMETHYST_SHARD, "Gemstone:", Formatting.DARK_PURPLE, 47);
+ }
+
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/Utils.java b/src/main/java/de/hysky/skyblocker/utils/Utils.java
index 3f07622c..b0c5bf45 100644
--- a/src/main/java/de/hysky/skyblocker/utils/Utils.java
+++ b/src/main/java/de/hysky/skyblocker/utils/Utils.java
@@ -36,6 +36,9 @@ public class Utils {
private static final Logger LOGGER = LoggerFactory.getLogger(Utils.class);
private static final String ALTERNATE_HYPIXEL_ADDRESS = System.getProperty("skyblocker.alternateHypixelAddress", "");
private static final String DUNGEONS_LOCATION = "dungeon";
+ private static final String CRYSTAL_HOLLOWS_LOCATION = "crystal_hollows";
+ private static final String DWARVEN_MINES_LOCATION = "mining_3";
+
private static final String PROFILE_PREFIX = "Profile: ";
private static boolean isOnHypixel = false;
private static boolean isOnSkyblock = false;
@@ -86,6 +89,14 @@ public class Utils {
return getLocationRaw().equals(DUNGEONS_LOCATION) || FabricLoader.getInstance().isDevelopmentEnvironment();
}
+ public static boolean isInCrystalHollows() {
+ return getLocationRaw().equals(CRYSTAL_HOLLOWS_LOCATION) || FabricLoader.getInstance().isDevelopmentEnvironment();
+ }
+
+ public static boolean isInDwarvenMines() {
+ return getLocationRaw().equals(DWARVEN_MINES_LOCATION) || FabricLoader.getInstance().isDevelopmentEnvironment();
+ }
+
public static boolean isInTheRift() {
return getLocationRaw().equals(TheRift.LOCATION);
}