diff --git a/src/main/java/io/github/skyblockcore/Dungeons.java b/src/main/java/io/github/skyblockcore/Dungeons.java new file mode 100644 index 0000000..f3974f8 --- /dev/null +++ b/src/main/java/io/github/skyblockcore/Dungeons.java @@ -0,0 +1,48 @@ +package io.github.skyblockcore; + +import java.util.HashMap; +import java.util.Map; + +public class Dungeons { + public enum DUNGEON_FLOORS { UNDEFINED("UNDEFINED"), E("E"), F1("F1"), F2("F2"), F3("F3"), F4("F4"), F5("F5"), F6("F6"), F7("F7"), M1("M1"), M2("M2"), M3("M3"), M4("M4"), M5("M5"), M6("M6"), M7("M7"); + private static final Map map = new HashMap<>(); + private final String text; + + static { + for(DUNGEON_FLOORS floor : DUNGEON_FLOORS.values()) { + map.put(floor.text, floor); + } + } + + DUNGEON_FLOORS(String text) { + this.text = text; + } + + public static DUNGEON_FLOORS fromString(String text) { + return map.get(text); + } + + public DUNGEON_BOSSES getBoss() { + switch(this) { + case F1, M1: return DUNGEON_BOSSES.BONZO; + case F2, M2: return DUNGEON_BOSSES.SCARF; + case F3, M3: return DUNGEON_BOSSES.THE_PROFESSOR; + case F4, M4: return DUNGEON_BOSSES.THORN; + case F5, M5: return DUNGEON_BOSSES.LIVID; + case F6, M6: return DUNGEON_BOSSES.SADAN; + case F7, M7: return DUNGEON_BOSSES.WITHER_LORDS; + default: return DUNGEON_BOSSES.UNDEFINED; + } + } + } + public enum DUNGEON_BOSSES { UNDEFINED, BONZO, SCARF, THE_PROFESSOR, THORN, LIVID, SADAN, WITHER_LORDS } + public enum DUNGEON_CLASSES { HEALER, MAGE, BERSERK, ARCHER, TANK } + + private static DUNGEON_FLOORS DUNGEON_FLOOR = null; + private static DUNGEON_BOSSES DUNGEON_BOSS = null; + + public static DUNGEON_FLOORS getDungeonFloor() {return DUNGEON_FLOOR;} + public static void setDungeonFloor(DUNGEON_FLOORS floor) {DUNGEON_FLOOR = floor;} + public static DUNGEON_BOSSES getDungeonBoss() {return DUNGEON_BOSS;} + public static void setDungeonBoss(DUNGEON_BOSSES boss) {DUNGEON_BOSS = boss;} +} \ No newline at end of file diff --git a/src/main/java/io/github/skyblockcore/SkyBlockCore.java b/src/main/java/io/github/skyblockcore/SkyBlockCore.java index 74be4e1..3666c25 100644 --- a/src/main/java/io/github/skyblockcore/SkyBlockCore.java +++ b/src/main/java/io/github/skyblockcore/SkyBlockCore.java @@ -19,6 +19,7 @@ import com.mojang.brigadier.CommandDispatcher; import io.github.skyblockcore.command.SkyBlockCoreCommand; import io.github.skyblockcore.event.*; +import io.github.skyblockcore.event.dungeons.*; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; @@ -40,18 +41,26 @@ public class SkyBlockCore implements ClientModInitializer { public static final String SKYBLOCK_SCOREBOARD = "SBScoreboard"; public static final String HEALTH_SCOREBOARD = "health"; private static boolean ON_SKYBLOCK = false; + private static String LOCATION; + public static String getLocation() { + return LOCATION; + } + public static final Logger LOGGER = LoggerFactory.getLogger(ModID); + + // Dungeons + private static boolean IN_DUNGEON = false; + private static boolean DUNGEON_ACTIVE = false; + public static boolean ENTERED_BOSSFIGHT = false; + public static Dungeons.DUNGEON_CLASSES DUNGEON_CLASS = Dungeons.DUNGEON_CLASSES.HEALER; public static boolean isOnSkyblock() { return ON_SKYBLOCK; } - - public static String getLocation() { - return LOCATION; + public static boolean isInDungeon() {return IN_DUNGEON;} + public static boolean isDungeonActive() { + return DUNGEON_ACTIVE; } - private static String LOCATION; - public static final Logger LOGGER = LoggerFactory.getLogger(ModID); - public static final KeyBinding copyBinding = KeyBindingHelper.registerKeyBinding(new KeyBinding( "skyblockcore.dev.nbtcopy", InputUtil.Type.KEYSYM, @@ -90,6 +99,46 @@ public void onInitializeClient() { return ActionResult.PASS; })); + // Dungeons + EnterDungeonCallback.EVENT.register(() -> { + IN_DUNGEON = true; + ENTERED_BOSSFIGHT = false; + return ActionResult.PASS; + }); + DungeonStartedCallback.EVENT.register((dungeonClass) -> { + DUNGEON_ACTIVE = true; + return ActionResult.PASS; + }); + WitherKeyObtainedCallback.EVENT.register((obtainerUsername) -> { + if(obtainerUsername == null) return ActionResult.FAIL; + return ActionResult.PASS; + }); + WitherDoorOpenedCallback.EVENT.register((openerUsername) -> { + if(openerUsername == null) return ActionResult.FAIL; + return ActionResult.PASS; + }); + BloodKeyObtainedCallback.EVENT.register((obtainerUsername) -> { + if(obtainerUsername == null) return ActionResult.FAIL; + return ActionResult.PASS; + }); + BloodDoorOpenedCallback.EVENT.register(() -> { + return ActionResult.PASS; + }); + EnteredBossfightCallback.EVENT.register((boss) -> { + if(boss == null) return ActionResult.FAIL; + return ActionResult.PASS; + }); + DungeonEndedCallback.EVENT.register((score) -> { + DUNGEON_ACTIVE = false; + return ActionResult.PASS; + }); + LeaveDungeonCallback.EVENT.register(() -> { + IN_DUNGEON = false; + DUNGEON_ACTIVE = false; + ENTERED_BOSSFIGHT = false; + Dungeons.setDungeonBoss(null); + return ActionResult.PASS; + }); } public static void registerCommands(CommandDispatcher dispatcher, CommandRegistryAccess registryAccess) { diff --git a/src/main/java/io/github/skyblockcore/event/dungeons/BloodDoorOpenedCallback.java b/src/main/java/io/github/skyblockcore/event/dungeons/BloodDoorOpenedCallback.java new file mode 100644 index 0000000..c691375 --- /dev/null +++ b/src/main/java/io/github/skyblockcore/event/dungeons/BloodDoorOpenedCallback.java @@ -0,0 +1,19 @@ +package io.github.skyblockcore.event.dungeons; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.util.ActionResult; + +public interface BloodDoorOpenedCallback { + Event EVENT = EventFactory.createArrayBacked(BloodDoorOpenedCallback.class, + (listeners) -> () -> { + for (BloodDoorOpenedCallback listener : listeners) { + ActionResult result = listener.interact(); + + if (result != ActionResult.PASS) return result; + } + return ActionResult.PASS; + }); + + ActionResult interact(); +} \ No newline at end of file diff --git a/src/main/java/io/github/skyblockcore/event/dungeons/BloodKeyObtainedCallback.java b/src/main/java/io/github/skyblockcore/event/dungeons/BloodKeyObtainedCallback.java new file mode 100644 index 0000000..bcb0b7c --- /dev/null +++ b/src/main/java/io/github/skyblockcore/event/dungeons/BloodKeyObtainedCallback.java @@ -0,0 +1,19 @@ +package io.github.skyblockcore.event.dungeons; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.util.ActionResult; + +public interface BloodKeyObtainedCallback { + Event EVENT = EventFactory.createArrayBacked(BloodKeyObtainedCallback.class, + (listeners) -> (obtainerUsername) -> { + for (BloodKeyObtainedCallback listener : listeners) { + ActionResult result = listener.interact(obtainerUsername); + + if (result != ActionResult.PASS) return result; + } + return ActionResult.PASS; + }); + + ActionResult interact(String obtainerUsername); +} diff --git a/src/main/java/io/github/skyblockcore/event/dungeons/DungeonEndedCallback.java b/src/main/java/io/github/skyblockcore/event/dungeons/DungeonEndedCallback.java new file mode 100644 index 0000000..ed8c189 --- /dev/null +++ b/src/main/java/io/github/skyblockcore/event/dungeons/DungeonEndedCallback.java @@ -0,0 +1,19 @@ +package io.github.skyblockcore.event.dungeons; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.util.ActionResult; + +public interface DungeonEndedCallback { + Event EVENT = EventFactory.createArrayBacked(DungeonEndedCallback.class, + (listeners) -> (score) -> { + for (DungeonEndedCallback listener : listeners) { + ActionResult result = listener.interact(score); + + if (result != ActionResult.PASS) return result; + } + return ActionResult.PASS; + }); + + ActionResult interact(int score); +} diff --git a/src/main/java/io/github/skyblockcore/event/dungeons/DungeonStartedCallback.java b/src/main/java/io/github/skyblockcore/event/dungeons/DungeonStartedCallback.java new file mode 100644 index 0000000..c8d8981 --- /dev/null +++ b/src/main/java/io/github/skyblockcore/event/dungeons/DungeonStartedCallback.java @@ -0,0 +1,20 @@ +package io.github.skyblockcore.event.dungeons; + +import io.github.skyblockcore.Dungeons; +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.util.ActionResult; + +public interface DungeonStartedCallback { + Event EVENT = EventFactory.createArrayBacked(DungeonStartedCallback.class, + (listeners) -> (dungeonClass) -> { + for (DungeonStartedCallback listener : listeners) { + ActionResult result = listener.interact(dungeonClass); + + if (result != ActionResult.PASS) return result; + } + return ActionResult.PASS; + }); + + ActionResult interact(Dungeons.DUNGEON_CLASSES dungeonClass); +} \ No newline at end of file diff --git a/src/main/java/io/github/skyblockcore/event/dungeons/EnterDungeonCallback.java b/src/main/java/io/github/skyblockcore/event/dungeons/EnterDungeonCallback.java new file mode 100644 index 0000000..d6a5ee6 --- /dev/null +++ b/src/main/java/io/github/skyblockcore/event/dungeons/EnterDungeonCallback.java @@ -0,0 +1,19 @@ +package io.github.skyblockcore.event.dungeons; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.util.ActionResult; + +public interface EnterDungeonCallback { + Event EVENT = EventFactory.createArrayBacked(EnterDungeonCallback.class, + (listeners) -> () -> { + for (EnterDungeonCallback listener : listeners) { + ActionResult result = listener.interact(); + + if (result != ActionResult.PASS) return result; + } + return ActionResult.PASS; + }); + + ActionResult interact(); +} diff --git a/src/main/java/io/github/skyblockcore/event/dungeons/EnteredBossfightCallback.java b/src/main/java/io/github/skyblockcore/event/dungeons/EnteredBossfightCallback.java new file mode 100644 index 0000000..5d4e5e7 --- /dev/null +++ b/src/main/java/io/github/skyblockcore/event/dungeons/EnteredBossfightCallback.java @@ -0,0 +1,20 @@ +package io.github.skyblockcore.event.dungeons; + +import io.github.skyblockcore.Dungeons; +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.util.ActionResult; + +public interface EnteredBossfightCallback { + Event EVENT = EventFactory.createArrayBacked(EnteredBossfightCallback.class, + (listeners) -> (boss) -> { + for (EnteredBossfightCallback listener : listeners) { + ActionResult result = listener.interact(boss); + + if (result != ActionResult.PASS) return result; + } + return ActionResult.PASS; + }); + + ActionResult interact(Dungeons.DUNGEON_BOSSES boss); +} diff --git a/src/main/java/io/github/skyblockcore/event/dungeons/LeaveDungeonCallback.java b/src/main/java/io/github/skyblockcore/event/dungeons/LeaveDungeonCallback.java new file mode 100644 index 0000000..38dc96c --- /dev/null +++ b/src/main/java/io/github/skyblockcore/event/dungeons/LeaveDungeonCallback.java @@ -0,0 +1,19 @@ +package io.github.skyblockcore.event.dungeons; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.util.ActionResult; + +public interface LeaveDungeonCallback { + Event EVENT = EventFactory.createArrayBacked(LeaveDungeonCallback.class, + (listeners) -> () -> { + for (LeaveDungeonCallback listener : listeners) { + ActionResult result = listener.interact(); + + if (result != ActionResult.PASS) return result; + } + return ActionResult.PASS; + }); + + ActionResult interact(); +} diff --git a/src/main/java/io/github/skyblockcore/event/dungeons/WitherDoorOpenedCallback.java b/src/main/java/io/github/skyblockcore/event/dungeons/WitherDoorOpenedCallback.java new file mode 100644 index 0000000..f92b9a0 --- /dev/null +++ b/src/main/java/io/github/skyblockcore/event/dungeons/WitherDoorOpenedCallback.java @@ -0,0 +1,19 @@ +package io.github.skyblockcore.event.dungeons; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.util.ActionResult; + +public interface WitherDoorOpenedCallback { + Event EVENT = EventFactory.createArrayBacked(WitherDoorOpenedCallback.class, + (listeners) -> (openerUsername) -> { + for (WitherDoorOpenedCallback listener : listeners) { + ActionResult result = listener.interact(openerUsername); + + if (result != ActionResult.PASS) return result; + } + return ActionResult.PASS; + }); + + ActionResult interact(String openerUsername); +} diff --git a/src/main/java/io/github/skyblockcore/event/dungeons/WitherKeyObtainedCallback.java b/src/main/java/io/github/skyblockcore/event/dungeons/WitherKeyObtainedCallback.java new file mode 100644 index 0000000..3eb575c --- /dev/null +++ b/src/main/java/io/github/skyblockcore/event/dungeons/WitherKeyObtainedCallback.java @@ -0,0 +1,19 @@ +package io.github.skyblockcore.event.dungeons; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.util.ActionResult; + +public interface WitherKeyObtainedCallback { + Event EVENT = EventFactory.createArrayBacked(WitherKeyObtainedCallback.class, + (listeners) -> (obtainerUsername) -> { + for (WitherKeyObtainedCallback listener : listeners) { + ActionResult result = listener.interact(obtainerUsername); + + if (result != ActionResult.PASS) return result; + } + return ActionResult.PASS; + }); + + ActionResult interact(String obtainerUsername); +} diff --git a/src/main/java/io/github/skyblockcore/mixin/MessageHandlerMixin.java b/src/main/java/io/github/skyblockcore/mixin/MessageHandlerMixin.java new file mode 100644 index 0000000..b98978c --- /dev/null +++ b/src/main/java/io/github/skyblockcore/mixin/MessageHandlerMixin.java @@ -0,0 +1,109 @@ +package io.github.skyblockcore.mixin; + +import io.github.skyblockcore.Dungeons; +import io.github.skyblockcore.event.dungeons.*; +import io.github.skyblockcore.util.TextUtils; +import net.minecraft.client.network.message.MessageHandler; +import net.minecraft.text.Text; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static io.github.skyblockcore.SkyBlockCore.*; + +@Mixin(MessageHandler.class) +public class MessageHandlerMixin { + @Inject(method = "onGameMessage", at = @At("HEAD")) + void onGameMessage(Text messageText, boolean overlay, CallbackInfo ci) { + String message = TextUtils.stripColorCodes(messageText.getString()); + + // Dungeons + if(isInDungeon()) { + if(message.contains("[Healer] Ghost Healing Aura Healing")) { + DUNGEON_CLASS = Dungeons.DUNGEON_CLASSES.HEALER; + LOGGER.info(TITLE + " Dungeon Started! Class: " + DUNGEON_CLASS); + DungeonStartedCallback.EVENT.invoker().interact(DUNGEON_CLASS); + } else if(message.contains("[Mage] Intelligence")) { + DUNGEON_CLASS = Dungeons.DUNGEON_CLASSES.MAGE; + LOGGER.info(TITLE + " Dungeon Started! Class: " + DUNGEON_CLASS); + DungeonStartedCallback.EVENT.invoker().interact(DUNGEON_CLASS); + } else if(message.contains("[Berserk] Lust For Blood Damage Increase Per Hit")) { + DUNGEON_CLASS = Dungeons.DUNGEON_CLASSES.BERSERK; + LOGGER.info(TITLE + " Dungeon Started! Class: " + DUNGEON_CLASS); + DungeonStartedCallback.EVENT.invoker().interact(DUNGEON_CLASS); + } else if(message.contains("[Archer] Extra Arrow Chance")) { + DUNGEON_CLASS = Dungeons.DUNGEON_CLASSES.ARCHER; + LOGGER.info(TITLE + " Dungeon Started! Class: " + DUNGEON_CLASS); + DungeonStartedCallback.EVENT.invoker().interact(DUNGEON_CLASS); + } else if(message.contains("[Tank] Absorption Shield Health Required")) { + DUNGEON_CLASS = Dungeons.DUNGEON_CLASSES.TANK; + LOGGER.info(TITLE + " Dungeon Started! Class: " + DUNGEON_CLASS); + DungeonStartedCallback.EVENT.invoker().interact(DUNGEON_CLASS); + } + + // Dungeon Ended + Pattern pattern = Pattern.compile("Team Score: (\\d+)"); + Matcher matcher = pattern.matcher(message); + if (matcher.find()) { + int score = Integer.parseInt(matcher.group(1)); + LOGGER.info(TITLE + " Dungeon Ended! Score: " + score); + DungeonEndedCallback.EVENT.invoker().interact(score); + } + + // Wither Key Obtained + if (message.contains(" has obtained Wither Key!")) { + Pattern pattern2 = Pattern.compile("(?:\\[(\\w+\\+*\\]*)\\s*)?(\\w+)\\s+has"); + Matcher matcher2 = pattern2.matcher(message); + if (matcher2.find()) { + String username = matcher2.group(2); + LOGGER.info(TITLE + " Wither Key Obtained By " + username + "!"); + WitherKeyObtainedCallback.EVENT.invoker().interact(username); + } else { + LOGGER.info(TITLE + " Wither Key Obtained! (But The Username of the Obtainer Is Not Found)"); + WitherKeyObtainedCallback.EVENT.invoker().interact(null); + } + } + + // Wither Door Opened + if (message.contains(" opened a WITHER door!")) { + Pattern pattern3 = Pattern.compile("(?:\\[(\\w+\\+*\\]*)\\s*)?(\\w+)\\s+opened"); + Matcher matcher3 = pattern3.matcher(message); + if (matcher3.find()) { + String username = matcher3.group(2); + LOGGER.info(TITLE + " Wither Door Opened By " + username + "!"); + WitherDoorOpenedCallback.EVENT.invoker().interact(username); + } + } + + // Blood Key Obtained + if (message.contains(" has obtained Blood Key!")) { + Pattern pattern4 = Pattern.compile("(?:\\[(\\w+\\+*\\]*)\\s*)?(\\w+)\\s+has"); + Matcher matcher4 = pattern4.matcher(message); + if (matcher4.find()) { + String username = matcher4.group(2); + LOGGER.info(TITLE + " Blood Key Obtained By " + username + "!"); + BloodKeyObtainedCallback.EVENT.invoker().interact(username); + } + } + + // Blood Door Opened + if (message.contains("The BLOOD DOOR has been opened!")) { + LOGGER.info(TITLE + " Blood Door Opened!"); + BloodDoorOpenedCallback.EVENT.invoker().interact(); + } + + if (message.contains("[BOSS] ") && !message.contains("[BOSS] The Watcher:")) { + Dungeons.DUNGEON_BOSSES boss = Dungeons.getDungeonFloor().getBoss(); + if(!ENTERED_BOSSFIGHT) { + EnteredBossfightCallback.EVENT.invoker().interact(boss); + LOGGER.info(TITLE + " Entered Boss Fight! Boss: " + boss); + ENTERED_BOSSFIGHT = true; + } + } + } + } +} \ No newline at end of file diff --git a/src/main/java/io/github/skyblockcore/mixin/PlayNetworkHandlerMixin.java b/src/main/java/io/github/skyblockcore/mixin/PlayNetworkHandlerMixin.java index c09e947..d8b4c63 100644 --- a/src/main/java/io/github/skyblockcore/mixin/PlayNetworkHandlerMixin.java +++ b/src/main/java/io/github/skyblockcore/mixin/PlayNetworkHandlerMixin.java @@ -5,6 +5,8 @@ import io.github.skyblockcore.event.JoinSkyblockCallback; import io.github.skyblockcore.event.LeaveSkyblockCallback; import io.github.skyblockcore.event.LocationChangedCallback; +import io.github.skyblockcore.event.dungeons.*; +import io.github.skyblockcore.Dungeons; import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.network.packet.s2c.play.ScoreboardDisplayS2CPacket; import net.minecraft.network.packet.s2c.play.TeamS2CPacket; @@ -13,17 +15,20 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import static io.github.skyblockcore.SkyBlockCore.*; @Mixin(ClientPlayNetworkHandler.class) public class PlayNetworkHandlerMixin { - - @Inject(method = "onTeam", at = @At("TAIL")) void onTeam(TeamS2CPacket packet, CallbackInfo ci) { // Check that the player is actually on Skyblock before processing team update if (!SkyBlockCore.isOnSkyblock()) return; + boolean inDungeon = isInDungeon(); + // SkyBlock represents lines on the scoreboard as teams if (packet.getTeam().isEmpty()) { // Team is empty, has no data for us to use. @@ -35,9 +40,34 @@ void onTeam(TeamS2CPacket packet, CallbackInfo ci) { String scoreboardLine = (team.getPrefix().getString() + team.getSuffix().getString()).strip(); if (scoreboardLine.length() > 0 && scoreboardLine.charAt(0) == '\u23E3') { // This is a location line - String location = scoreboardLine.split("\u23E3 ")[1]; - if (location.equals(SkyBlockCore.getLocation())) return; // Location didn't change - LocationChangedCallback.EVENT.invoker().interact(SkyBlockCore.getLocation(), location); + String newLocation = scoreboardLine.split("\u23E3 ")[1]; + if (newLocation.equals(SkyBlockCore.getLocation())) return; // Location didn't change + String oldLocation = SkyBlockCore.getLocation(); + LocationChangedCallback.EVENT.invoker().interact(oldLocation, newLocation); + + // If player is currently in a dungeon + if(newLocation.contains("The Catacombs") || newLocation.contains("Master Mode Catacombs")) { + // If they just entered the dungeon + if(!inDungeon) { + String floor = "UNDEFINED"; + + // Get the current dungeon floor + Pattern pattern = Pattern.compile("\\(([^)]+)\\)"); + Matcher matcher = pattern.matcher(newLocation); + if(matcher.find()) { + floor = matcher.group(1); + } + Dungeons.setDungeonFloor(Dungeons.DUNGEON_FLOORS.fromString(floor)); + EnterDungeonCallback.EVENT.invoker().interact(); + LOGGER.info(TITLE + " Joined Dungeon (" + floor + ")"); + } + } else { + // When starting dungeon and going into boss fight, the location changes to "The Catac", then back to "The Catacombs" + if(inDungeon && !oldLocation.equals("The Catac") && !newLocation.equals("The Catac")) { + LOGGER.info(TITLE + " Left Dungeon"); + LeaveDungeonCallback.EVENT.invoker().interact(); + } + } } } diff --git a/src/main/resources/skyblockcore.mixins.json b/src/main/resources/skyblockcore.mixins.json index 82952c8..698da91 100644 --- a/src/main/resources/skyblockcore.mixins.json +++ b/src/main/resources/skyblockcore.mixins.json @@ -9,6 +9,7 @@ "client": [ "HandledScreenFocusedSlotAccessor", "HandledScreenMixin", + "MessageHandlerMixin", "PlayNetworkHandlerMixin" ], "injectors": {