aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de')
-rw-r--r--src/main/java/de/hysky/skyblocker/SkyblockerMod.java5
-rw-r--r--src/main/java/de/hysky/skyblocker/config/ConfigNullFieldsFix.java63
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java16
-rw-r--r--src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java6
-rw-r--r--src/main/java/de/hysky/skyblocker/config/configs/QuickNavigationConfig.java15
-rw-r--r--src/main/java/de/hysky/skyblocker/debug/Debug.java26
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/ChestValue.java3
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/CroesusProfit.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/puzzle/waterboard/Waterboard.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java117
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java36
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/Room.java46
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/garden/VisitorHelper.java8
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/PlayerHeadHashCache.java11
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemData.java40
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java8
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipInfoType.java7
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipManager.java14
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/EstimatedItemValueTooltip.java38
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/TrueHexDyeScreenDisplay.java53
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/profileviewer/inventory/Inventory.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/profileviewer/inventory/PlayerInventory.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/profileviewer/skills/SkillsPage.java3
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/special/DungeonsSpecialEffects.java70
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/special/DyeSpecialEffects.java58
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/special/SpecialEffects.java70
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/ItemUtils.java40
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/networth/NetworthCalculator.java26
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/networth/NetworthDataSuppliers.java33
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/networth/SkyblockItemMetadataRetriever.java42
30 files changed, 638 insertions, 226 deletions
diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
index 4e110e15..5e573598 100644
--- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
+++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
@@ -2,6 +2,8 @@ package de.hysky.skyblocker;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
+
+import de.hysky.skyblocker.config.ConfigNullFieldsFix;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.config.datafixer.ConfigDataFixer;
import de.hysky.skyblocker.debug.Debug;
@@ -109,13 +111,14 @@ public class SkyblockerMod implements ClientModInitializer {
ConfigDataFixer.apply();
Utils.init();
SkyblockerConfigManager.init();
+ ConfigNullFieldsFix.init(); //DO NOT INIT ANY CLASS THAT USES CONFIG FIELDS BEFORE THIS!
SkyblockerScreen.initClass();
ProfileViewerScreen.initClass();
Tips.init();
NEURepoManager.init();
//ImageRepoLoader.init();
ItemRepository.init();
- PlayerHeadHashCache.init();
+ SkyblockItemData.init();
HotbarSlotLock.init();
ItemTooltip.init();
AccessoriesHelper.init();
diff --git a/src/main/java/de/hysky/skyblocker/config/ConfigNullFieldsFix.java b/src/main/java/de/hysky/skyblocker/config/ConfigNullFieldsFix.java
new file mode 100644
index 00000000..a16b3359
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/config/ConfigNullFieldsFix.java
@@ -0,0 +1,63 @@
+package de.hysky.skyblocker.config;
+
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.Map;
+
+import org.slf4j.Logger;
+
+import com.mojang.logging.LogUtils;
+
+import dev.isxander.yacl3.config.v2.api.SerialEntry;
+
+/**
+ * While this sounds like a data fixer it isn't. - It's the only reasonable solution to deal with the mine field
+ * that is YACL's null handling.
+ */
+public class ConfigNullFieldsFix {
+ private static final Logger LOGGER = LogUtils.getLogger();
+ private static final String CONFIGS_PACKAGE = "de.hysky.skyblocker.config.configs";
+
+ public static void init() {
+ SkyblockerConfig current = SkyblockerConfigManager.get();
+ SkyblockerConfig clean = new SkyblockerConfig();
+
+ try {
+ fixNullFields(current, clean);
+ SkyblockerConfigManager.save();
+ } catch (Exception e) {
+ LOGGER.error("[Skyblocker Config Null Fields Fixer] Failed to ensure that the config has no null fields! You may encounter crashes :(", e);
+ }
+ }
+
+ /**
+ * Traverse through every config field to ensure that is isn't null, if it is then reset the value.
+ */
+ private static void fixNullFields(Object target, Object source) throws Exception {
+ for (Field field : target.getClass().getDeclaredFields()) {
+ if (field.isAnnotationPresent(SerialEntry.class)) {
+ field.setAccessible(true);
+
+ Object targetValue = field.get(target);
+ Object sourceValue = field.get(source);
+
+ if (targetValue == null && sourceValue != null) {
+ field.set(target, sourceValue);
+ } else if (targetValue != null && sourceValue != null && isFixable(field.getType())) {
+ fixNullFields(targetValue, sourceValue);
+ }
+ }
+ }
+ }
+
+ private static boolean isFixable(Class<?> clazz) {
+ return !clazz.isPrimitive()
+ && !clazz.isEnum()
+ && !clazz.isRecord()
+ && !clazz.equals(String.class)
+ && !Number.class.isAssignableFrom(clazz)
+ && !Map.class.isAssignableFrom(clazz)
+ && !Collection.class.isAssignableFrom(clazz)
+ && clazz.getPackageName().startsWith(CONFIGS_PACKAGE);
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java
index bea570e5..ff089432 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java
@@ -229,6 +229,14 @@ public class GeneralCategory {
newValue -> config.general.itemTooltip.showEssenceCost = newValue)
.controller(ConfigUtils::createBooleanController)
.build())
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("skyblocker.config.general.itemTooltip.enableEstimatedItemValue"))
+ .description(OptionDescription.of(Text.translatable("skyblocker.config.general.itemTooltip.enableEstimatedItemValue.@Tooltip")))
+ .binding(defaults.general.itemTooltip.enableEstimatedItemValue,
+ () -> config.general.itemTooltip.enableEstimatedItemValue,
+ newValue -> config.general.itemTooltip.enableEstimatedItemValue = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
.build())
//Item Info Display
@@ -326,6 +334,14 @@ public class GeneralCategory {
newValue -> config.general.specialEffects.rareDungeonDropEffects = newValue)
.controller(ConfigUtils::createBooleanController)
.build())
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("skyblocker.config.general.specialEffects.rareDyeDropEffects"))
+ .description(OptionDescription.of(Text.translatable("skyblocker.config.general.specialEffects.rareDyeDropEffects.@Tooltip")))
+ .binding(defaults.general.specialEffects.rareDyeDropEffects,
+ () -> config.general.specialEffects.rareDyeDropEffects,
+ newValue -> config.general.specialEffects.rareDyeDropEffects = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
.build())
//Hitboxes
diff --git a/src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java
index 61386452..92206c49 100644
--- a/src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java
+++ b/src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java
@@ -135,6 +135,9 @@ public class GeneralConfig {
@SerialEntry
public boolean showEssenceCost = false;
+
+ @SerialEntry
+ public boolean enableEstimatedItemValue = true;
}
public enum Average {
@@ -241,6 +244,9 @@ public class GeneralConfig {
public static class SpecialEffects {
@SerialEntry
public boolean rareDungeonDropEffects = true;
+
+ @SerialEntry
+ public boolean rareDyeDropEffects = true;
}
public static class Hitbox {
diff --git a/src/main/java/de/hysky/skyblocker/config/configs/QuickNavigationConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/QuickNavigationConfig.java
index fd7c30f3..ac3e5a72 100644
--- a/src/main/java/de/hysky/skyblocker/config/configs/QuickNavigationConfig.java
+++ b/src/main/java/de/hysky/skyblocker/config/configs/QuickNavigationConfig.java
@@ -65,6 +65,15 @@ public class QuickNavigationConfig {
public QuickNavItem button14 = new QuickNavItem(new ItemData(Items.CRAFTING_TABLE), "Craft Item", "/craft", "Crafting Table");
public static class QuickNavItem {
+ /**
+ * Default constructor or else gson skips initialization.
+ */
+ private QuickNavItem() {}
+
+ public QuickNavItem(ItemData itemData, String clickEvent, String tooltip) {
+ this(itemData, "none", clickEvent, tooltip);
+ }
+
public QuickNavItem(ItemData itemData, @Language("RegExp") String uiTitle, String clickEvent, String tooltip) {
this.itemData = itemData;
this.uiTitle = uiTitle;
@@ -72,10 +81,6 @@ public class QuickNavigationConfig {
this.tooltip = tooltip;
}
- public QuickNavItem(ItemData itemData, String clickEvent, String tooltip) {
- this(itemData, "none", clickEvent, tooltip);
- }
-
@SerialEntry
public boolean render = true;
@@ -86,7 +91,7 @@ public class QuickNavigationConfig {
public String uiTitle;
@SerialEntry
- public String tooltip;
+ public String tooltip = "";
@SerialEntry
public String clickEvent;
diff --git a/src/main/java/de/hysky/skyblocker/debug/Debug.java b/src/main/java/de/hysky/skyblocker/debug/Debug.java
index f1240a1c..fff12619 100644
--- a/src/main/java/de/hysky/skyblocker/debug/Debug.java
+++ b/src/main/java/de/hysky/skyblocker/debug/Debug.java
@@ -8,11 +8,14 @@ import de.hysky.skyblocker.mixins.accessors.HandledScreenAccessor;
import de.hysky.skyblocker.utils.Constants;
import de.hysky.skyblocker.utils.ItemUtils;
import de.hysky.skyblocker.utils.datafixer.ItemStackComponentizationFixer;
+import de.hysky.skyblocker.utils.networth.NetworthCalculator;
+import net.azureaaron.networth.Calculation;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
import net.fabricmc.fabric.api.client.screen.v1.ScreenKeyboardEvents;
import net.fabricmc.loader.api.FabricLoader;
+import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.entity.decoration.ArmorStandEntity;
import net.minecraft.item.ItemStack;
@@ -49,20 +52,25 @@ public class Debug {
ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(literal(SkyblockerMod.NAMESPACE).then(literal("debug")
.then(dumpPlayersCommand())
.then(ItemUtils.dumpHeldItemCommand())
+ .then(ItemUtils.dumpHeldItemNetworthCalculationsCommand())
.then(toggleShowingInvisibleArmorStands())
.then(dumpArmorStandHeadTextures())
.then(toggleWebSocketDebug())
)));
ScreenEvents.BEFORE_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
if (screen instanceof HandledScreen<?> handledScreen) {
- ScreenKeyboardEvents.afterKeyPress(screen).register((_screen, key, scancode, modifier) -> {
- Slot focusedSlot = ((HandledScreenAccessor) handledScreen).getFocusedSlot();
- if (key == GLFW.GLFW_KEY_U && client.player != null && focusedSlot != null && focusedSlot.hasStack()) {
- client.player.sendMessage(Text.literal("[Skyblocker Debug] Hovered Item: " + SkyblockerMod.GSON_COMPACT.toJson(ItemStack.CODEC.encodeStart(ItemStackComponentizationFixer.getRegistryLookup().getOps(JsonOps.INSTANCE), focusedSlot.getStack()).getOrThrow())));
- }
- });
- }
- });
+ ScreenKeyboardEvents.afterKeyPress(screen).register((_screen, key, scancode, modifier) -> {
+ Slot focusedSlot = ((HandledScreenAccessor) handledScreen).getFocusedSlot();
+ if (key == GLFW.GLFW_KEY_U && client.player != null && focusedSlot != null && focusedSlot.hasStack()) {
+ if (!Screen.hasShiftDown()) {
+ client.player.sendMessage(Text.literal("[Skyblocker Debug] Hovered Item: " + SkyblockerMod.GSON_COMPACT.toJson(ItemStack.CODEC.encodeStart(ItemStackComponentizationFixer.getRegistryLookup().getOps(JsonOps.INSTANCE), focusedSlot.getStack()).getOrThrow())));
+ } else {
+ client.player.sendMessage(Text.literal("[Skyblocker Debug] Held Item NW Calcs: " + SkyblockerMod.GSON_COMPACT.toJson(Calculation.LIST_CODEC.encodeStart(JsonOps.INSTANCE, NetworthCalculator.getItemNetworth(focusedSlot.getStack()).calculations()).getOrThrow())));
+ }
+ }
+ });
+ }
+ });
}
}
@@ -108,4 +116,4 @@ public class Debug {
return Command.SINGLE_SUCCESS;
});
}
-}
+} \ No newline at end of file
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/ChestValue.java b/src/main/java/de/hysky/skyblocker/skyblock/ChestValue.java
index 67928b07..0b188a37 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/ChestValue.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/ChestValue.java
@@ -7,6 +7,7 @@ import de.hysky.skyblocker.mixins.accessors.HandledScreenAccessor;
import de.hysky.skyblocker.mixins.accessors.ScreenAccessor;
import de.hysky.skyblocker.utils.ItemUtils;
import de.hysky.skyblocker.utils.Utils;
+import de.hysky.skyblocker.utils.networth.NetworthCalculator;
import it.unimi.dsi.fastutil.doubles.DoubleBooleanPair;
import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
import net.fabricmc.fabric.api.client.screen.v1.Screens;
@@ -192,7 +193,7 @@ public class ChestValue {
if (!priceData.rightBoolean()) hasIncompleteData = true;
- value += priceData.leftDouble() * stack.getCount();
+ value += NetworthCalculator.getItemNetworth(stack).price();
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CroesusProfit.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CroesusProfit.java
index 12954118..db91996a 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CroesusProfit.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CroesusProfit.java
@@ -20,7 +20,7 @@ import java.util.regex.Pattern;
public class CroesusProfit extends SimpleContainerSolver {
private static final Pattern ESSENCE_PATTERN = Pattern.compile("(?<type>[A-Za-z]+) Essence x(?<amount>\\d+)");
public CroesusProfit() {
- super(".*Catacombs - Floor.*");
+ super(".*The Catacombs - Flo.*");
}
@Override
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/puzzle/waterboard/Waterboard.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/puzzle/waterboard/Waterboard.java
index 511827b9..f81fae0c 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/puzzle/waterboard/Waterboard.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/puzzle/waterboard/Waterboard.java
@@ -282,13 +282,13 @@ public class Waterboard extends DungeonPuzzle {
// Check if left down is in range and is closer than right down.
// Note 1: The yarn name "getFlowSpeed" is incorrect as it actually returns the maximum distance that water will check for a hole to flow towards.
// Note 2: Skyblock's maximum offset is 5 instead of 4 for some reason.
- if (-leftFlowDownOffset <= ((WaterFluid) Fluids.WATER).getFlowSpeed(null) + 1 && -leftFlowDownOffset < rightFlowDownOffset) {
+ if (-leftFlowDownOffset <= ((WaterFluid) Fluids.WATER).getMaxFlowDistance(null) + 1 && -leftFlowDownOffset < rightFlowDownOffset) {
result.putPath(water, leftFlowDownOffset);
water.add(leftFlowDownOffset, 1);
continue;
}
// Check if right down is in range and closer than left down.
- if (rightFlowDownOffset <= ((WaterFluid) Fluids.WATER).getFlowSpeed(null) + 1 && rightFlowDownOffset < -leftFlowDownOffset) {
+ if (rightFlowDownOffset <= ((WaterFluid) Fluids.WATER).getMaxFlowDistance(null) + 1 && rightFlowDownOffset < -leftFlowDownOffset) {
result.putPath(water, rightFlowDownOffset);
water.add(rightFlowDownOffset, 1);
continue;
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java
index 11f31f34..fbe99909 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java
@@ -22,6 +22,7 @@ import de.hysky.skyblocker.utils.Tickable;
import de.hysky.skyblocker.utils.Utils;
import de.hysky.skyblocker.utils.command.argumenttypes.blockpos.ClientBlockPosArgumentType;
import de.hysky.skyblocker.utils.command.argumenttypes.blockpos.ClientPosArgument;
+import de.hysky.skyblocker.utils.render.RenderHelper;
import de.hysky.skyblocker.utils.scheduler.Scheduler;
import it.unimi.dsi.fastutil.objects.Object2ByteMap;
import it.unimi.dsi.fastutil.objects.Object2ByteMaps;
@@ -41,7 +42,6 @@ import net.minecraft.command.CommandRegistryAccess;
import net.minecraft.command.CommandSource;
import net.minecraft.command.argument.TextArgumentType;
import net.minecraft.component.DataComponentTypes;
-import net.minecraft.entity.Entity;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.mob.AmbientEntity;
@@ -59,12 +59,14 @@ import net.minecraft.util.Identifier;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.World;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.joml.Vector2i;
import org.joml.Vector2ic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -77,11 +79,11 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.concurrent.CompletableFuture;
-import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import java.util.zip.InflaterInputStream;
+import static de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonMapUtils.*;
import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument;
import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;
@@ -89,7 +91,11 @@ public class DungeonManager {
protected static final Logger LOGGER = LoggerFactory.getLogger(DungeonManager.class);
private static final String DUNGEONS_PATH = "dungeons";
private static Path CUSTOM_WAYPOINTS_DIR;
- private static final Pattern KEY_FOUND = Pattern.compile("^(?:\\[.+] )?(?<name>\\w+) has obtained (?<type>Wither|Blood) Key!$");
+ private static final Pattern KEY_FOUND = Pattern.compile("^RIGHT CLICK on (?:the BLOOD DOOR|a WITHER door) to open it. This key can only be used to open 1 door!$");
+ private static final Pattern WITHER_DOOR_OPENED = Pattern.compile("^\\w+ opened a WITHER door!$");
+ private static final String BLOOD_DOOR_OPENED = "The BLOOD DOOR has been opened!";
+ protected static final float[] RED_COLOR_COMPONENTS = {1, 0, 0};
+ protected static final float[] GREEN_COLOR_COMPONENTS = {0, 1, 0};
/**
* Maps the block identifier string to a custom numeric block id used in dungeon rooms data.
*
@@ -152,6 +158,10 @@ public class DungeonManager {
private static Room currentRoom;
@NotNull
private static DungeonBoss boss = DungeonBoss.NONE;
+ @Nullable
+ private static Box bloodRushDoorBox;
+ private static boolean bloodOpened;
+ private static boolean hasKey;
public static boolean isRoomsLoaded() {
return roomsLoaded != null && roomsLoaded.isDone();
@@ -551,6 +561,8 @@ public class DungeonManager {
LOGGER.info("[Skyblocker Dungeon Secrets] Started dungeon with map room size {}, map entrance pos {}, player pos {}, and physical entrance pos {}", mapRoomSize, mapEntrancePos, client.player.getPos(), physicalEntrancePos);
}
+ getBloodRushDoorPos(map);
+
Vector2ic physicalPos = DungeonMapUtils.getPhysicalRoomPos(client.player.getPos());
Vector2ic mapPos = DungeonMapUtils.getMapPosFromPhysical(physicalEntrancePos, mapEntrancePos, mapRoomSize, physicalPos);
Room room = rooms.get(physicalPos);
@@ -565,12 +577,6 @@ public class DungeonManager {
}
}
if (room != null && currentRoom != room) {
- if (currentRoom != null && room.getType() == Room.Type.FAIRY) {
- currentRoom.nextRoom = room;
- if (currentRoom.keyFound) {
- room.keyFound = true;
- }
- }
currentRoom = room;
}
currentRoom.tick(client);
@@ -604,14 +610,24 @@ public class DungeonManager {
if (shouldProcess() && currentRoom != null) {
currentRoom.render(context);
}
+
+ if (bloodRushDoorBox != null && !bloodOpened && SkyblockerConfigManager.get().dungeons.doorHighlight.enableDoorHighlight) {
+ float[] colorComponents = hasKey ? GREEN_COLOR_COMPONENTS : RED_COLOR_COMPONENTS;
+ switch (SkyblockerConfigManager.get().dungeons.doorHighlight.doorHighlightType) {
+ case HIGHLIGHT -> RenderHelper.renderFilled(context, bloodRushDoorBox, colorComponents, 0.5f, true);
+ case OUTLINED_HIGHLIGHT -> {
+ RenderHelper.renderFilled(context, bloodRushDoorBox, colorComponents, 0.5f, true);
+ RenderHelper.renderOutline(context, bloodRushDoorBox, colorComponents, 5, true);
+ }
+ case OUTLINE -> RenderHelper.renderOutline(context, bloodRushDoorBox, colorComponents, 5, true);
+ }
+ }
}
/**
* Calls {@link Room#onChatMessage(String)} on {@link #currentRoom} if the message is an overlay message and {@link #isCurrentRoomMatched()} and processes key obtained messages.
* <p>Used to detect when all secrets in a room are found and detect when a wither or blood door is unlocked.
* To process key obtained messages, this method checks if door highlight is enabled and if the message matches a key obtained message.
- * Then, it calls {@link Room#keyFound()} on {@link #currentRoom} if the client's player is the one who obtained the key.
- * Otherwise, it calls {@link Room#keyFound()} on the room the player who obtained the key is in.
*/
private static void onChatMessage(Text text, boolean overlay) {
if (!shouldProcess()) {
@@ -625,30 +641,17 @@ public class DungeonManager {
}
// Process key found messages for door highlight
- if (SkyblockerConfigManager.get().dungeons.doorHighlight.enableDoorHighlight) {
- Matcher matcher = KEY_FOUND.matcher(message);
- if (matcher.matches()) {
- String name = matcher.group("name");
- MinecraftClient client = MinecraftClient.getInstance();
- if (client.player != null && client.player.getGameProfile().getName().equals(name)) {
- if (currentRoom != null) {
- currentRoom.keyFound();
- } else {
- LOGGER.warn("[Skyblocker Dungeon Door] The current room at the current player {} does not exist", name);
- }
- } else if (client.world != null) {
- Optional<Vec3d> posOptional = client.world.getPlayers().stream().filter(player -> player.getGameProfile().getName().equals(name)).findAny().map(Entity::getPos);
- if (posOptional.isPresent()) {
- Room room = getRoomAtPhysical(posOptional.get());
- if (room != null) {
- room.keyFound();
- } else {
- LOGGER.warn("[Skyblocker Dungeon Door] Failed to find room at player {} with position {}", name, posOptional.get());
- }
- } else {
- LOGGER.warn("[Skyblocker Dungeon Door] Failed to find player {}", name);
- }
- }
+ if (SkyblockerConfigManager.get().dungeons.doorHighlight.enableDoorHighlight && !bloodOpened) {
+ if (BLOOD_DOOR_OPENED.equals(message)) {
+ bloodOpened = true;
+ }
+
+ if (KEY_FOUND.matcher(message).matches()) {
+ hasKey = true;
+ }
+
+ if (WITHER_DOOR_OPENED.matcher(message).matches()) {
+ hasKey = false;
}
}
@@ -770,5 +773,49 @@ public class DungeonManager {
rooms.clear();
currentRoom = null;
boss = DungeonBoss.NONE;
+ bloodRushDoorBox = null;
+ bloodOpened = false;
+ hasKey = false;
+ }
+
+ /**
+ * Determines where the current door of interest is
+ *
+ * @implNote Relies on the minimap to check for doors
+ */
+ private static void getBloodRushDoorPos(@NotNull MapState map) {
+ if (mapEntrancePos == null || mapRoomSize == 0) {
+ LOGGER.error("[Skyblocker Dungeon Secrets] Dungeon map info missing with map entrance pos {} and map room size {}", mapEntrancePos, mapRoomSize);
+ return;
+ }
+
+ Vector2i nWMostRoom = getMapPosForNWMostRoom(mapEntrancePos, mapRoomSize);
+
+ for (int x = nWMostRoom.x + mapRoomSize / 2; x < 128; x += mapRoomSize + 4) {
+ for (int y = nWMostRoom.y + mapRoomSize; y < 128; y += mapRoomSize + 4) {
+ byte color = getColor(map, x, y);
+
+ // 119 is the black found on wither doors on the map, 18 is the blood door red
+ if (color == 119 || color == 18) {
+ Vector2ic doorPos = getPhysicalPosFromMap(mapEntrancePos, mapRoomSize, physicalEntrancePos, new Vector2i(x - mapRoomSize / 2, y - mapRoomSize));
+ bloodRushDoorBox = new Box(doorPos.x() + 14, 69, doorPos.y() + 30, doorPos.x() + 17, 73, doorPos.y() + 33);
+
+ return;
+ }
+ }
+ }
+
+ for (int x = nWMostRoom.x + mapRoomSize; x < 128; x += mapRoomSize + 4) {
+ for (int y = nWMostRoom.y + mapRoomSize / 2; y < 128; y += mapRoomSize + 4) {
+ byte color = getColor(map, x, y);
+
+ if (color == 119 || color == 18) {
+ Vector2ic doorPos = getPhysicalPosFromMap(mapEntrancePos, mapRoomSize, physicalEntrancePos, new Vector2i(x - mapRoomSize, y - mapRoomSize / 2));
+ bloodRushDoorBox = new Box(doorPos.x() + 30, 69, doorPos.y() + 14, doorPos.x() + 33, 73, doorPos.y() + 17);
+
+ return;
+ }
+ }
+ }
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java
index 5474224a..ca63d971 100644
--- a/