aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/me/Danker/features
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/me/Danker/features')
-rw-r--r--src/main/java/me/Danker/features/AutoDisplay.java73
-rw-r--r--src/main/java/me/Danker/features/AutoSwapToPickBlock.java51
-rw-r--r--src/main/java/me/Danker/features/BlockAbilities.java84
-rw-r--r--src/main/java/me/Danker/features/BlockWrongSlayer.java42
-rw-r--r--src/main/java/me/Danker/features/BonzoMaskTimer.java86
-rw-r--r--src/main/java/me/Danker/features/CakeTimer.java62
-rw-r--r--src/main/java/me/Danker/features/DungeonTimer.java79
-rw-r--r--src/main/java/me/Danker/features/ExpertiseLore.java40
-rw-r--r--src/main/java/me/Danker/features/FasterMaddoxCalling.java64
-rw-r--r--src/main/java/me/Danker/features/GoldenEnchants.java68
-rw-r--r--src/main/java/me/Danker/features/GolemSpawningAlert.java26
-rw-r--r--src/main/java/me/Danker/features/GpartyNotifications.java38
-rw-r--r--src/main/java/me/Danker/features/HideTooltipsInExperiments.java35
-rw-r--r--src/main/java/me/Danker/features/LowHealthNotifications.java36
-rw-r--r--src/main/java/me/Danker/features/NecronNotifications.java78
-rw-r--r--src/main/java/me/Danker/features/NoF3Coords.java33
-rw-r--r--src/main/java/me/Danker/features/NotifySlayerSlain.java88
-rw-r--r--src/main/java/me/Danker/features/PetColours.java69
-rw-r--r--src/main/java/me/Danker/features/Reparty.java143
-rw-r--r--src/main/java/me/Danker/features/Skill50Display.java77
-rw-r--r--src/main/java/me/Danker/features/SkillTracker.java208
-rw-r--r--src/main/java/me/Danker/features/SpamHider.java51
-rw-r--r--src/main/java/me/Danker/features/SpiritBearAlert.java24
-rw-r--r--src/main/java/me/Danker/features/StopSalvagingStarredItems.java34
-rw-r--r--src/main/java/me/Danker/features/UpdateChecker.java52
-rw-r--r--src/main/java/me/Danker/features/WatcherReadyAlert.java22
-rw-r--r--src/main/java/me/Danker/features/loot/LootDisplay.java905
-rw-r--r--src/main/java/me/Danker/features/loot/LootTracker.java1097
-rw-r--r--src/main/java/me/Danker/features/puzzlesolvers/ArrowTerminalSolver.java32
-rw-r--r--src/main/java/me/Danker/features/puzzlesolvers/BlazeSolver.java86
-rw-r--r--src/main/java/me/Danker/features/puzzlesolvers/BlockPlacingFlowers.java44
-rw-r--r--src/main/java/me/Danker/features/puzzlesolvers/BlockWrongTerminalClicks.java112
-rw-r--r--src/main/java/me/Danker/features/puzzlesolvers/BoulderSolver.java188
-rw-r--r--src/main/java/me/Danker/features/puzzlesolvers/ChronomatronSolver.java114
-rw-r--r--src/main/java/me/Danker/features/puzzlesolvers/ClickInOrderSolver.java107
-rw-r--r--src/main/java/me/Danker/features/puzzlesolvers/CreeperSolver.java86
-rw-r--r--src/main/java/me/Danker/features/puzzlesolvers/LividSolver.java89
-rw-r--r--src/main/java/me/Danker/features/puzzlesolvers/SelectAllColourSolver.java59
-rw-r--r--src/main/java/me/Danker/features/puzzlesolvers/StartsWithSolver.java31
-rw-r--r--src/main/java/me/Danker/features/puzzlesolvers/SuperpairsSolver.java150
-rw-r--r--src/main/java/me/Danker/features/puzzlesolvers/ThreeManSolver.java75
-rw-r--r--src/main/java/me/Danker/features/puzzlesolvers/TicTacToeSolver.java135
-rw-r--r--src/main/java/me/Danker/features/puzzlesolvers/TriviaSolver.java102
-rw-r--r--src/main/java/me/Danker/features/puzzlesolvers/UltrasequencerSolver.java112
-rw-r--r--src/main/java/me/Danker/features/puzzlesolvers/WaterSolver.java162
45 files changed, 5349 insertions, 0 deletions
diff --git a/src/main/java/me/Danker/features/AutoDisplay.java b/src/main/java/me/Danker/features/AutoDisplay.java
new file mode 100644
index 0000000..876fb6a
--- /dev/null
+++ b/src/main/java/me/Danker/features/AutoDisplay.java
@@ -0,0 +1,73 @@
+package me.Danker.features;
+
+import me.Danker.DankersSkyblockMod;
+import me.Danker.features.loot.LootDisplay;
+import me.Danker.handlers.ConfigHandler;
+import me.Danker.handlers.ScoreboardHandler;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.entity.EntityPlayerSP;
+import net.minecraft.item.ItemStack;
+import net.minecraft.world.World;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+
+import java.util.List;
+
+public class AutoDisplay {
+
+ @SubscribeEvent
+ public void onTick(TickEvent.ClientTickEvent event) {
+ if (event.phase != TickEvent.Phase.START) return;
+
+ Minecraft mc = Minecraft.getMinecraft();
+ World world = mc.theWorld;
+ EntityPlayerSP player = mc.thePlayer;
+ if (DankersSkyblockMod.tickAmount % 20 == 0) {
+ if (LootDisplay.auto && world != null && player != null) {
+ List<String> scoreboard = ScoreboardHandler.getSidebarLines();
+ boolean found = false;
+ for (String s : scoreboard) {
+ String sCleaned = ScoreboardHandler.cleanSB(s);
+ if (sCleaned.contains("Sven Packmaster")) {
+ LootDisplay.display = "wolf";
+ found = true;
+ } else if (sCleaned.contains("Tarantula Broodfather")) {
+ LootDisplay.display = "spider";
+ found = true;
+ } else if (sCleaned.contains("Revenant Horror")) {
+ LootDisplay.display = "zombie";
+ found = true;
+ } else if (sCleaned.contains("The Catacombs (")) {
+ if (sCleaned.contains("F1")) {
+ LootDisplay.display = "catacombs_floor_one";
+ } else if (sCleaned.contains("F2")) {
+ LootDisplay.display = "catacombs_floor_two";
+ } else if (sCleaned.contains("F3")) {
+ LootDisplay.display = "catacombs_floor_three";
+ } else if (sCleaned.contains("F4")) {
+ LootDisplay.display = "catacombs_floor_four";
+ } else if (sCleaned.contains("F5")) {
+ LootDisplay.display = "catacombs_floor_five";
+ } else if (sCleaned.contains("F6")) {
+ LootDisplay.display = "catacombs_floor_six";
+ } else if (sCleaned.contains("F7")) {
+ LootDisplay.display = "catacombs_floor_seven";
+ }
+ found = true;
+ }
+ }
+ for (int i = 0; i < 8; i++) {
+ ItemStack hotbarItem = player.inventory.getStackInSlot(i);
+ if (hotbarItem == null) continue;
+ if (hotbarItem.getDisplayName().contains("Ancestral Spade")) {
+ LootDisplay.display = "mythological";
+ found = true;
+ }
+ }
+ if (!found) LootDisplay.display = "off";
+ ConfigHandler.writeStringConfig("misc", "display", LootDisplay.display);
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/AutoSwapToPickBlock.java b/src/main/java/me/Danker/features/AutoSwapToPickBlock.java
new file mode 100644
index 0000000..ccabbce
--- /dev/null
+++ b/src/main/java/me/Danker/features/AutoSwapToPickBlock.java
@@ -0,0 +1,51 @@
+package me.Danker.features;
+
+import me.Danker.commands.ToggleCommand;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.inventory.GuiChest;
+import net.minecraft.client.settings.GameSettings;
+import net.minecraft.inventory.Container;
+import net.minecraft.inventory.ContainerChest;
+import net.minecraft.inventory.IInventory;
+import net.minecraftforge.client.event.GuiOpenEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+public class AutoSwapToPickBlock {
+
+ static int pickBlockBind;
+ static boolean pickBlockBindSwapped = false;
+
+ @SubscribeEvent
+ public void onGuiOpen(GuiOpenEvent event) {
+ Minecraft mc = Minecraft.getMinecraft();
+ GameSettings gameSettings = mc.gameSettings;
+ if (event.gui instanceof GuiChest) {
+ Container containerChest = ((GuiChest) event.gui).inventorySlots;
+ if (containerChest instanceof ContainerChest) {
+ IInventory inventory = ((ContainerChest) containerChest).getLowerChestInventory();
+ String inventoryName = inventory.getDisplayName().getUnformattedText();
+
+ if (ToggleCommand.swapToPickBlockToggled) {
+ if (inventoryName.startsWith("Chronomatron (") || inventoryName.startsWith("Superpairs (") || inventoryName.startsWith("Ultrasequencer (") || inventoryName.startsWith("What starts with:") || inventoryName.startsWith("Select all the") || inventoryName.startsWith("Navigate the maze!") || inventoryName.startsWith("Correct all the panes!") || inventoryName.startsWith("Click in order!") || inventoryName.startsWith("Harp -")) {
+ if (!pickBlockBindSwapped) {
+ pickBlockBind = gameSettings.keyBindPickBlock.getKeyCode();
+ gameSettings.keyBindPickBlock.setKeyCode(-100);
+ pickBlockBindSwapped = true;
+ }
+ } else {
+ if (pickBlockBindSwapped) {
+ gameSettings.keyBindPickBlock.setKeyCode(pickBlockBind);
+ pickBlockBindSwapped = false;
+ }
+ }
+ }
+ }
+ } else {
+ if (pickBlockBindSwapped) {
+ gameSettings.keyBindPickBlock.setKeyCode(pickBlockBind);
+ pickBlockBindSwapped = false;
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/BlockAbilities.java b/src/main/java/me/Danker/features/BlockAbilities.java
new file mode 100644
index 0000000..19a887c
--- /dev/null
+++ b/src/main/java/me/Danker/features/BlockAbilities.java
@@ -0,0 +1,84 @@
+package me.Danker.features;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.utils.Utils;
+import net.minecraft.block.Block;
+import net.minecraft.client.Minecraft;
+import net.minecraft.init.Blocks;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.event.entity.player.PlayerInteractEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class BlockAbilities {
+
+ @SubscribeEvent
+ public void onInteract(PlayerInteractEvent event) {
+ if (!Utils.inSkyblock || Minecraft.getMinecraft().thePlayer != event.entityPlayer) return;
+ ItemStack item = event.entityPlayer.getHeldItem();
+ if (item == null) return;
+
+ if (event.action == PlayerInteractEvent.Action.RIGHT_CLICK_AIR) {
+ if (ToggleCommand.aotdToggled && item.getDisplayName().contains("Aspect of the Dragons")) {
+ event.setCanceled(true);
+ }
+ if (ToggleCommand.lividDaggerToggled && item.getDisplayName().contains("Livid Dagger")) {
+ event.setCanceled(true);
+ }
+ } else if (event.action == PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK) {
+ Block block = Minecraft.getMinecraft().theWorld.getBlockState(event.pos).getBlock();
+
+ ArrayList<Block> interactables = new ArrayList<>(Arrays.asList(
+ Blocks.acacia_door,
+ Blocks.anvil,
+ Blocks.beacon,
+ Blocks.bed,
+ Blocks.birch_door,
+ Blocks.brewing_stand,
+ Blocks.command_block,
+ Blocks.crafting_table,
+ Blocks.chest,
+ Blocks.dark_oak_door,
+ Blocks.daylight_detector,
+ Blocks.daylight_detector_inverted,
+ Blocks.dispenser,
+ Blocks.dropper,
+ Blocks.enchanting_table,
+ Blocks.ender_chest,
+ Blocks.furnace,
+ Blocks.hopper,
+ Blocks.jungle_door,
+ Blocks.lever,
+ Blocks.noteblock,
+ Blocks.powered_comparator,
+ Blocks.unpowered_comparator,
+ Blocks.powered_repeater,
+ Blocks.unpowered_repeater,
+ Blocks.standing_sign,
+ Blocks.wall_sign,
+ Blocks.trapdoor,
+ Blocks.trapped_chest,
+ Blocks.wooden_button,
+ Blocks.stone_button,
+ Blocks.oak_door,
+ Blocks.skull
+ ));
+ if (Utils.inDungeons) {
+ interactables.add(Blocks.coal_block);
+ interactables.add(Blocks.stained_hardened_clay);
+ }
+
+ if (!interactables.contains(block)) {
+ if (ToggleCommand.aotdToggled && item.getDisplayName().contains("Aspect of the Dragons")) {
+ event.setCanceled(true);
+ }
+ if (ToggleCommand.lividDaggerToggled && item.getDisplayName().contains("Livid Dagger")) {
+ event.setCanceled(true);
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/BlockWrongSlayer.java b/src/main/java/me/Danker/features/BlockWrongSlayer.java
new file mode 100644
index 0000000..6da4798
--- /dev/null
+++ b/src/main/java/me/Danker/features/BlockWrongSlayer.java
@@ -0,0 +1,42 @@
+package me.Danker.features;
+
+import me.Danker.DankersSkyblockMod;
+import me.Danker.events.ChestSlotClickedEvent;
+import net.minecraft.client.Minecraft;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.ChatComponentText;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+public class BlockWrongSlayer {
+
+ public static String onlySlayerName = "";
+ public static String onlySlayerNumber = "";
+
+ @SubscribeEvent
+ public void onSlotClick(ChestSlotClickedEvent event) {
+ String inventoryName = event.inventoryName;
+ ItemStack item = event.item;
+ if (!onlySlayerName.equals("") && item != null) {
+ if (inventoryName.equals("Slayer")) {
+ if (!item.getDisplayName().contains("Revenant Horror") && !item.getDisplayName().contains("Tarantula Broodfather") && !item.getDisplayName().contains("Sven Packmaster"))
+ return;
+ if (!item.getDisplayName().contains(onlySlayerName)) {
+ Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(DankersSkyblockMod.ERROR_COLOUR + "Danker's Skyblock Mod has stopped you from starting this quest (Set to " + onlySlayerName + " " + onlySlayerNumber + ")"));
+ Minecraft.getMinecraft().thePlayer.playSound("note.bass", 1, (float) 0.5);
+ event.setCanceled(true);
+ }
+ } else if (inventoryName.equals("Revenant Horror") || inventoryName.equals("Tarantula Broodfather") || inventoryName.equals("Sven Packmaster")) {
+ if (item.getDisplayName().contains("Revenant Horror") || item.getDisplayName().contains("Tarantula Broodfather") || item.getDisplayName().contains("Sven Packmaster")) {
+ // Only check number as they passed the above check
+ String slayerNumber = item.getDisplayName().substring(item.getDisplayName().lastIndexOf(" ") + 1);
+ if (!slayerNumber.equals(onlySlayerNumber)) {
+ Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(DankersSkyblockMod.ERROR_COLOUR + "Danker's Skyblock Mod has stopped you from starting this quest (Set to " + onlySlayerName + " " + onlySlayerNumber + ")"));
+ Minecraft.getMinecraft().thePlayer.playSound("note.bass", 1, (float) 0.5);
+ event.setCanceled(true);
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/BonzoMaskTimer.java b/src/main/java/me/Danker/features/BonzoMaskTimer.java
new file mode 100644
index 0000000..e038786
--- /dev/null
+++ b/src/main/java/me/Danker/features/BonzoMaskTimer.java
@@ -0,0 +1,86 @@
+package me.Danker.features;
+
+import me.Danker.commands.MoveCommand;
+import me.Danker.commands.ScaleCommand;
+import me.Danker.commands.ToggleCommand;
+import me.Danker.events.RenderOverlay;
+import me.Danker.handlers.TextRenderer;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.entity.EntityPlayerSP;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.init.Items;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.event.world.WorldEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import org.lwjgl.opengl.GL11;
+
+public class BonzoMaskTimer {
+
+ public static double nextBonzoUse = 0;
+ public static String BONZO_COLOR;
+ public static final ResourceLocation BONZO_ICON = new ResourceLocation("dsm", "icons/bonzo.png");
+
+ @SubscribeEvent
+ public void onWorldChange(WorldEvent.Load event) {
+ nextBonzoUse = 0;
+ }
+
+ @SubscribeEvent
+ public void onChat(ClientChatReceivedEvent event) {
+ String message = StringUtils.stripControlCodes(event.message.getUnformattedText());
+
+ if (!Utils.inDungeons) return;
+
+ if (ToggleCommand.bonzoTimerToggled && message.contains("Bonzo's Mask") && message.contains("saved your life!")) {
+ double usedTime = System.currentTimeMillis() / 1000;
+ Minecraft mc = Minecraft.getMinecraft();
+ EntityPlayerSP player = mc.thePlayer;
+ ItemStack bonzoMask = player.getCurrentArmor(3);
+ if (bonzoMask != null && bonzoMask.getItem() == Items.skull) {
+ int cooldownSeconds = 0;
+ for (String line : Utils.getItemLore(bonzoMask)) {
+ String stripped = StringUtils.stripControlCodes(line);
+ if (stripped.startsWith("Cooldown: "))
+ cooldownSeconds = Integer.parseInt(stripped.replaceAll("[^\\d]", ""));
+ }
+ System.out.println("Parsed Bonzo Mask Cooldown: " + cooldownSeconds);
+ if (cooldownSeconds > 0)
+ nextBonzoUse = usedTime + cooldownSeconds;
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void renderPlayerInfo(RenderOverlay event) {
+ if (ToggleCommand.bonzoTimerToggled && Utils.inDungeons) {
+ Minecraft mc = Minecraft.getMinecraft();
+ ItemStack helmetSlot = mc.thePlayer.getCurrentArmor(3);
+ if ((helmetSlot != null && helmetSlot.getDisplayName().contains("Bonzo's Mask")) || nextBonzoUse > 0) {
+
+ double scale = ScaleCommand.bonzoTimerScale;
+ double scaleReset = Math.pow(scale, -1);
+ GL11.glScaled(scale, scale, scale);
+
+ double timeNow = System.currentTimeMillis() / 1000;
+ mc.getTextureManager().bindTexture(BONZO_ICON);
+ Gui.drawModalRectWithCustomSizedTexture(MoveCommand.bonzoTimerXY[0], MoveCommand.bonzoTimerXY[1], 0, 0, 16, 16, 16, 16);
+
+ String bonzoText;
+ if (nextBonzoUse - timeNow < 0) {
+ bonzoText = EnumChatFormatting.GREEN + "READY";
+ } else {
+ bonzoText = BONZO_COLOR + Utils.getTimeBetween(timeNow, nextBonzoUse);
+ }
+ new TextRenderer(mc, bonzoText, MoveCommand.bonzoTimerXY[0] + 20, MoveCommand.bonzoTimerXY[1] + 5, 1);
+
+ GL11.glScaled(scaleReset, scaleReset, scaleReset);
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/CakeTimer.java b/src/main/java/me/Danker/features/CakeTimer.java
new file mode 100644
index 0000000..ba6eb3d
--- /dev/null
+++ b/src/main/java/me/Danker/features/CakeTimer.java
@@ -0,0 +1,62 @@
+package me.Danker.features;
+
+import me.Danker.commands.MoveCommand;
+import me.Danker.commands.ScaleCommand;
+import me.Danker.commands.ToggleCommand;
+import me.Danker.events.RenderOverlay;
+import me.Danker.handlers.ConfigHandler;
+import me.Danker.handlers.TextRenderer;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import org.lwjgl.opengl.GL11;
+
+public class CakeTimer {
+
+ public static double cakeTime;
+ public static final ResourceLocation CAKE_ICON = new ResourceLocation("dsm", "icons/cake.png");
+ public static String CAKE_COLOUR;
+
+ @SubscribeEvent
+ public void onChat(ClientChatReceivedEvent event) {
+ String message = StringUtils.stripControlCodes(event.message.getUnformattedText());
+
+ if (!Utils.inSkyblock) return;
+ if (message.contains(":")) return;
+
+ if (message.contains("Yum! You gain +") && message.contains(" for 48 hours!")) {
+ cakeTime = System.currentTimeMillis() / 1000 + 172800; // Add 48 hours
+ ConfigHandler.writeDoubleConfig("misc", "cakeTime", cakeTime);
+ }
+ }
+
+ @SubscribeEvent
+ public void renderPlayerInfo(RenderOverlay event) {
+ if (ToggleCommand.cakeTimerToggled && Utils.inSkyblock) {
+ Minecraft mc = Minecraft.getMinecraft();
+ double scale = ScaleCommand.cakeTimerScale;
+ double scaleReset = Math.pow(scale, -1);
+ GL11.glScaled(scale, scale, scale);
+
+ double timeNow = System.currentTimeMillis() / 1000;
+ mc.getTextureManager().bindTexture(CAKE_ICON);
+ Gui.drawModalRectWithCustomSizedTexture(MoveCommand.cakeTimerXY[0], MoveCommand.cakeTimerXY[1], 0, 0, 16, 16, 16, 16);
+
+ String cakeText;
+ if (cakeTime - timeNow < 0) {
+ cakeText = EnumChatFormatting.RED + "NONE";
+ } else {
+ cakeText = CAKE_COLOUR + Utils.getTimeBetween(timeNow, cakeTime);
+ }
+ new TextRenderer(mc, cakeText, MoveCommand.cakeTimerXY[0] + 20, MoveCommand.cakeTimerXY[1] + 5, 1);
+
+ GL11.glScaled(scaleReset, scaleReset, scaleReset);
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/DungeonTimer.java b/src/main/java/me/Danker/features/DungeonTimer.java
new file mode 100644
index 0000000..5929f05
--- /dev/null
+++ b/src/main/java/me/Danker/features/DungeonTimer.java
@@ -0,0 +1,79 @@
+package me.Danker.features;
+
+import me.Danker.commands.MoveCommand;
+import me.Danker.commands.ScaleCommand;
+import me.Danker.commands.ToggleCommand;
+import me.Danker.events.RenderOverlay;
+import me.Danker.handlers.TextRenderer;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+public class DungeonTimer {
+
+ static double dungeonStartTime = 0;
+ static double bloodOpenTime = 0;
+ static double watcherClearTime = 0;
+ static double bossClearTime = 0;
+ static int witherDoors = 0;
+ static int dungeonDeaths = 0;
+ static int puzzleFails = 0;
+
+ @SubscribeEvent
+ public void onChat(ClientChatReceivedEvent event) {
+ String message = StringUtils.stripControlCodes(event.message.getUnformattedText());
+
+ if (!Utils.inDungeons) return;
+
+ if (message.contains("[BOSS] The Watcher: You have proven yourself. You may pass.")) {
+ watcherClearTime = System.currentTimeMillis() / 1000;
+ } else if (message.contains("PUZZLE FAIL! ") || message.contains("chose the wrong answer! I shall never forget this moment")) {
+ puzzleFails++;
+ }
+
+ if (message.contains(":")) return;
+
+ if (message.contains("Dungeon starts in 1 second.")) { // Dungeons Stuff
+ dungeonStartTime = System.currentTimeMillis() / 1000 + 1;
+ bloodOpenTime = dungeonStartTime;
+ watcherClearTime = dungeonStartTime;
+ bossClearTime = dungeonStartTime;
+ witherDoors = 0;
+ dungeonDeaths = 0;
+ puzzleFails = 0;
+ } else if (message.contains("The BLOOD DOOR has been opened!")) {
+ bloodOpenTime = System.currentTimeMillis() / 1000;
+ } else if (message.contains(" opened a WITHER door!")) {
+ witherDoors++;
+ } else if (message.contains(" and became a ghost.")) {
+ dungeonDeaths++;
+ } else if (message.contains(" Defeated ") && message.contains(" in ")) {
+ bossClearTime = System.currentTimeMillis() / 1000;
+ }
+ }
+
+ @SubscribeEvent
+ public void renderPlayerInfo(RenderOverlay event) {
+ if (ToggleCommand.dungeonTimerToggled && Utils.inDungeons) {
+ Minecraft mc = Minecraft.getMinecraft();
+ String dungeonTimerText = EnumChatFormatting.GRAY + "Wither Doors:\n" +
+ EnumChatFormatting.DARK_RED + "Blood Open:\n" +
+ EnumChatFormatting.RED + "Watcher Clear:\n" +
+ EnumChatFormatting.BLUE + "Boss Clear:\n" +
+ EnumChatFormatting.YELLOW + "Deaths:\n" +
+ EnumChatFormatting.YELLOW + "Puzzle Fails:";
+ String dungeonTimers = EnumChatFormatting.GRAY + "" + witherDoors + "\n" +
+ EnumChatFormatting.DARK_RED + Utils.getTimeBetween(dungeonStartTime, bloodOpenTime) + "\n" +
+ EnumChatFormatting.RED + Utils.getTimeBetween(dungeonStartTime, watcherClearTime) + "\n" +
+ EnumChatFormatting.BLUE + Utils.getTimeBetween(dungeonStartTime, bossClearTime) + "\n" +
+ EnumChatFormatting.YELLOW + dungeonDeaths + "\n" +
+ EnumChatFormatting.YELLOW + puzzleFails;
+ new TextRenderer(mc, dungeonTimerText, MoveCommand.dungeonTimerXY[0], MoveCommand.dungeonTimerXY[1], ScaleCommand.dungeonTimerScale);
+ new TextRenderer(mc, dungeonTimers, (int) (MoveCommand.dungeonTimerXY[0] + (80 * ScaleCommand.dungeonTimerScale)), MoveCommand.dungeonTimerXY[1], ScaleCommand.dungeonTimerScale);
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/ExpertiseLore.java b/src/main/java/me/Danker/features/ExpertiseLore.java
new file mode 100644
index 0000000..1eb998d
--- /dev/null
+++ b/src/main/java/me/Danker/features/ExpertiseLore.java
@@ -0,0 +1,40 @@
+package me.Danker.features;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraftforge.event.entity.player.ItemTooltipEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+public class ExpertiseLore {
+
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
+ public void onTooltip(ItemTooltipEvent event) {
+ if (!Utils.inSkyblock) return;
+ if (event.toolTip == null) return;
+
+ ItemStack item = event.itemStack;
+ if (ToggleCommand.expertiseLoreToggled) {
+ if (item.hasTagCompound()) {
+ NBTTagCompound tags = item.getSubCompound("ExtraAttributes", false);
+ if (tags != null) {
+ if (tags.hasKey("expertise_kills")) {
+ int index = 4;
+ if (!Minecraft.getMinecraft().gameSettings.advancedItemTooltips) index -= 2;
+
+ event.toolTip.add(event.toolTip.size() - index, "");
+ event.toolTip.add(event.toolTip.size() - index, "Expertise Kills: " + EnumChatFormatting.RED + tags.getInteger("expertise_kills"));
+ if (Utils.expertiseKillsLeft(tags.getInteger("expertise_kills")) != -1) {
+ event.toolTip.add(event.toolTip.size() - index, Utils.expertiseKillsLeft(tags.getInteger("expertise_kills")) + " kills to tier up!");
+ }
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/FasterMaddoxCalling.java b/src/main/java/me/Danker/features/FasterMaddoxCalling.java
new file mode 100644
index 0000000..fa8bcb5
--- /dev/null
+++ b/src/main/java/me/Danker/features/FasterMaddoxCalling.java
@@ -0,0 +1,64 @@
+package me.Danker.features;
+
+import me.Danker.DankersSkyblockMod;
+import me.Danker.commands.ToggleCommand;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.entity.EntityPlayerSP;
+import net.minecraft.client.gui.GuiChat;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.IChatComponent;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.client.event.GuiScreenEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.InputEvent;
+import org.lwjgl.input.Mouse;
+
+import java.util.List;
+
+public class FasterMaddoxCalling {
+
+ static String lastMaddoxCommand = "/cb placeholder";
+ static double lastMaddoxTime = 0;
+
+ @SubscribeEvent
+ public void onChat(ClientChatReceivedEvent event) {
+ String message = StringUtils.stripControlCodes(event.message.getUnformattedText());
+
+ if (!Utils.inSkyblock) return;
+ if (message.contains(":")) return;
+
+ if (message.contains("[OPEN MENU]")) {
+ List<IChatComponent> listOfSiblings = event.message.getSiblings();
+ for (IChatComponent sibling : listOfSiblings) {
+ if (sibling.getUnformattedText().contains("[OPEN MENU]")) {
+ lastMaddoxCommand = sibling.getChatStyle().getChatClickEvent().getValue();
+ lastMaddoxTime = System.currentTimeMillis() / 1000;
+ }
+ }
+ if (ToggleCommand.chatMaddoxToggled) Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(DankersSkyblockMod.MAIN_COLOUR + "Open chat then click anywhere on-screen to open Maddox"));
+ }
+ }
+
+ @SubscribeEvent
+ public void onMouseInputPost(GuiScreenEvent.MouseInputEvent.Post event) {
+ if (!Utils.inSkyblock) return;
+ if (Mouse.getEventButton() == 0 && event.gui instanceof GuiChat) {
+ if (ToggleCommand.chatMaddoxToggled && System.currentTimeMillis() / 1000 - lastMaddoxTime < 10) {
+ Minecraft.getMinecraft().thePlayer.sendChatMessage(lastMaddoxCommand);
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onKey(InputEvent.KeyInputEvent event) {
+ if (!Utils.inSkyblock) return;
+
+ EntityPlayerSP player = Minecraft.getMinecraft().thePlayer;
+ if (DankersSkyblockMod.keyBindings[0].isPressed()) {
+ player.sendChatMessage(lastMaddoxCommand);
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/GoldenEnchants.java b/src/main/java/me/Danker/features/GoldenEnchants.java
new file mode 100644
index 0000000..d633ec5
--- /dev/null
+++ b/src/main/java/me/Danker/features/GoldenEnchants.java
@@ -0,0 +1,68 @@
+package me.Danker.features;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.utils.Utils;
+import net.minecraftforge.event.entity.player.ItemTooltipEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+public class GoldenEnchants {
+
+ public static Map<String, String> t6Enchants = new HashMap<>();
+ public static Pattern t6EnchantPattern = Pattern.compile("");
+
+ public static void init() {
+ t6Enchants.put("9Angler VI", "6Angler VI");
+ t6Enchants.put("9Bane of Arthropods VI", "6Bane of Arthropods VI");
+ t6Enchants.put("9Caster VI", "6Caster VI");
+ t6Enchants.put("9Compact X", "6Compact X");
+ t6Enchants.put("9Critical VI", "6Critical VI");
+ t6Enchants.put("9Dragon Hunter V", "6Dragon Hunter V");
+ t6Enchants.put("9Efficiency VI", "6Efficiency VI");
+ t6Enchants.put("9Ender Slayer VI", "6Ender Slayer VI");
+ t6Enchants.put("9Experience IV", "6Experience IV");
+ t6Enchants.put("9Expertise X", "6Expertise X");
+ t6Enchants.put("9Feather Falling X", "6Feather Falling X");
+ t6Enchants.put("9Frail VI", "6Frail VI");
+ t6Enchants.put("9Giant Killer VI", "6Giant Killer VI");
+ t6Enchants.put("9Growth VI", "6Growth VI");
+ t6Enchants.put("9Infinite Quiver X", "6Infinite Quiver X");
+ t6Enchants.put("9Lethality VI", "6Lethality VI");
+ t6Enchants.put("9Life Steal IV", "6Life Steal IV");
+ t6Enchants.put("9Looting IV", "6Looting IV");
+ t6Enchants.put("9Luck VI", "6Luck VI");
+ t6Enchants.put("9Luck of the Sea VI", "6Luck of the Sea VI");
+ t6Enchants.put("9Lure VI", "6Lure VI");
+ t6Enchants.put("9Magnet VI", "6Magnet VI");
+ t6Enchants.put("9Overload V", "6Overload V");
+ t6Enchants.put("9Power VI", "6Power VI");
+ t6Enchants.put("9Protection VI", "6Protection VI");
+ t6Enchants.put("9Scavenger IV", "6Scavenger IV");
+ t6Enchants.put("9Scavenger V", "6Scavenger V");
+ t6Enchants.put("9Sharpness VI", "6Sharpness VI");
+ t6Enchants.put("9Smite VI", "6Smite VI");
+ t6Enchants.put("9Spiked Hook VI", "6Spiked Hook VI");
+ t6Enchants.put("9Thunderlord VI", "6Thunderlord VI");
+ t6Enchants.put("9Vampirism VI", "6Vampirism VI");
+
+ String patternString = "(" + String.join("|", t6Enchants.keySet()) + ")";
+ t6EnchantPattern = Pattern.compile(patternString);
+ }
+
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
+ public void onTooltip(ItemTooltipEvent event) {
+ if (!Utils.inSkyblock) return;
+ if (event.toolTip == null) return;
+
+ if (ToggleCommand.goldenToggled) {
+ for (int i = 0; i < event.toolTip.size(); i++) {
+ event.toolTip.set(i, Utils.returnGoldenEnchants(event.toolTip.get(i)));
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/GolemSpawningAlert.java b/src/main/java/me/Danker/features/GolemSpawningAlert.java
new file mode 100644
index 0000000..91b647e
--- /dev/null
+++ b/src/main/java/me/Danker/features/GolemSpawningAlert.java
@@ -0,0 +1,26 @@
+package me.Danker.features;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.utils.Utils;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+public class GolemSpawningAlert {
+
+ @SubscribeEvent
+ public void onChat(ClientChatReceivedEvent event) {
+ String message = StringUtils.stripControlCodes(event.message.getUnformattedText());
+
+ if (!Utils.inSkyblock) return;
+ if (message.contains(":")) return;
+
+ if (ToggleCommand.golemAlertToggled) {
+ if (message.contains("The ground begins to shake as an Endstone Protector rises from below!")) {
+ Utils.createTitle(EnumChatFormatting.RED + "GOLEM SPAWNING!", 3);
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/GpartyNotifications.java b/src/main/java/me/Danker/features/GpartyNotifications.java
new file mode 100644
index 0000000..f3aec69
--- /dev/null
+++ b/src/main/java/me/Danker/features/GpartyNotifications.java
@@ -0,0 +1,38 @@
+package me.Danker.features;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.utils.Utils;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import java.awt.*;
+
+public class GpartyNotifications {
+
+ @SubscribeEvent
+ public void onChat(ClientChatReceivedEvent event) {
+ String message = StringUtils.stripControlCodes(event.message.getUnformattedText());
+
+ if (!Utils.inSkyblock) return;
+ if (message.contains(":")) return;
+
+ if (ToggleCommand.gpartyToggled) {
+ if (message.contains(" has invited all members of ")) {
+ try {
+ final SystemTray tray = SystemTray.getSystemTray();
+ final Image image = Toolkit.getDefaultToolkit().createImage("icon.png");
+ final TrayIcon trayIcon = new TrayIcon(image, "Guild Party Notifier");
+ trayIcon.setImageAutoSize(true);
+ trayIcon.setToolTip("Guild Party Notifier");
+ tray.add(trayIcon);
+ trayIcon.displayMessage("Guild Party", message, TrayIcon.MessageType.INFO);
+ tray.remove(trayIcon);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/HideTooltipsInExperiments.java b/src/main/java/me/Danker/features/HideTooltipsInExperiments.java
new file mode 100644
index 0000000..5866fc8
--- /dev/null
+++ b/src/main/java/me/Danker/features/HideTooltipsInExperiments.java
@@ -0,0 +1,35 @@
+package me.Danker.features;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.entity.EntityPlayerSP;
+import net.minecraft.client.gui.inventory.GuiChest;
+import net.minecraft.inventory.ContainerChest;
+import net.minecraft.inventory.IInventory;
+import net.minecraftforge.event.entity.player.ItemTooltipEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+public class HideTooltipsInExperiments {
+
+ @SubscribeEvent(priority = EventPriority.LOW)
+ public void onTooltipLow(ItemTooltipEvent event) {
+ if (!Utils.inSkyblock) return;
+ if (event.toolTip == null) return;
+
+ Minecraft mc = Minecraft.getMinecraft();
+ EntityPlayerSP player = mc.thePlayer;
+
+ if (mc.currentScreen instanceof GuiChest) {
+ ContainerChest chest = (ContainerChest) player.openContainer;
+ IInventory inv = chest.getLowerChestInventory();
+ String chestName = inv.getDisplayName().getUnformattedText();
+
+ if (ToggleCommand.hideTooltipsInExperimentAddonsToggled && (chestName.startsWith("Ultrasequencer (") || chestName.startsWith("Chronomatron ("))) {
+ event.toolTip.clear();
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/LowHealthNotifications.java b/src/main/java/me/Danker/features/LowHealthNotifications.java
new file mode 100644
index 0000000..0bf2898
--- /dev/null
+++ b/src/main/java/me/Danker/features/LowHealthNotifications.java
@@ -0,0 +1,36 @@
+package me.Danker.features;
+
+import me.Danker.DankersSkyblockMod;
+import me.Danker.commands.ToggleCommand;
+import me.Danker.handlers.ScoreboardHandler;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.world.World;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+
+import java.util.List;
+
+public class LowHealthNotifications {
+
+ @SubscribeEvent
+ public void onTick(TickEvent.ClientTickEvent event) {
+ if (event.phase != TickEvent.Phase.START) return;
+
+ World world = Minecraft.getMinecraft().theWorld;
+ if (DankersSkyblockMod.tickAmount % 2 == 0) {
+ if (ToggleCommand.lowHealthNotifyToggled && Utils.inDungeons && world != null) {
+ List<String> scoreboard = ScoreboardHandler.getSidebarLines();
+ for (String score : scoreboard) {
+ if (score.endsWith("❤") && score.matches(".* §c\\d.*")) {
+ String name = score.substring(score.indexOf(" ") + 1);
+ Utils.createTitle(EnumChatFormatting.RED + "LOW HEALTH!\n" + name, 1);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/NecronNotifications.java b/src/main/java/me/Danker/features/NecronNotifications.java
new file mode 100644
index 0000000..a1d4d26
--- /dev/null
+++ b/src/main/java/me/Danker/features/NecronNotifications.java
@@ -0,0 +1,78 @@
+package me.Danker.features;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.utils.Utils;
+import net.minecraft.block.Block;
+import net.minecraft.block.state.IBlockState;
+import net.minecraft.client.Minecraft;
+import net.minecraft.entity.item.EntityArmorStand;
+import net.minecraft.init.Blocks;
+import net.minecraft.util.BlockPos;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StringUtils;
+import net.minecraft.world.World;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import java.util.List;
+
+public class NecronNotifications {
+
+ @SubscribeEvent
+ public void onChat(ClientChatReceivedEvent event) {
+ String message = StringUtils.stripControlCodes(event.message.getUnformattedText());
+
+ if (!Utils.inDungeons) return;
+
+ if (ToggleCommand.necronNotificationsToggled && message.contains("[BOSS] Necron:")) {
+ Minecraft mc = Minecraft.getMinecraft();
+ World world = mc.theWorld;
+ if (message.contains("You tricked me!") || message.contains("That beam, it hurts! IT HURTS!!")) {
+ Utils.createTitle(EnumChatFormatting.RED + "NECRON STUCK!", 2);
+ } else if (message.contains("STOP USING MY FACTORY AGAINST ME!") || message.contains("OOF") || message.contains("ANOTHER TRAP!! YOUR TRICKS ARE FUTILE!") || message.contains("SERIOUSLY? AGAIN?!") || message.contains("STOP!!!!!")) {
+ List<EntityArmorStand> necronLabels = world.getEntities(EntityArmorStand.class, (entity -> {
+ if (!entity.hasCustomName()) return false;
+ if (!entity.getCustomNameTag().contains("Necron")) return false;
+ return true;
+ }));
+ if (necronLabels.size() == 0) {
+ Utils.createTitle(EnumChatFormatting.WHITE + "NECRON STUNNED!", 2);
+ } else {
+ EntityArmorStand necron = necronLabels.get(0);
+ double x = necron.posX;
+ double z = necron.posZ;
+
+ BlockPos blockPos = new BlockPos(x, 168, z);
+
+ IBlockState blockState = world.getBlockState(blockPos);
+ Block block = blockState.getBlock();
+
+ if (block != Blocks.stained_hardened_clay) {
+ Utils.createTitle(EnumChatFormatting.WHITE + "NECRON STUNNED!", 2);
+ } else {
+ switch (block.getDamageValue(world, blockPos)) {
+ case 4:
+ Utils.createTitle(EnumChatFormatting.YELLOW + "YELLOW PILLAR!", 2);
+ break;
+ case 5:
+ Utils.createTitle(EnumChatFormatting.DARK_GREEN + "GREEN PILLAR!", 2);
+ break;
+ case 11:
+ Utils.createTitle(EnumChatFormatting.DARK_PURPLE + "PURPLE PILLAR!", 2);
+ break;
+ default:
+ Utils.createTitle(EnumChatFormatting.WHITE + "NECRON STUNNED!", 2);
+ }
+ }
+
+ }
+ } else if (message.contains("I'VE HAD ENOUGH! YOU'RE NOT HITTING ME WITH ANY MORE PILLARS!")) {
+ Utils.createTitle(EnumChatFormatting.RED + "RED PILLAR!", 2);
+ } else if (message.contains("ARGH!")) {
+ Utils.createTitle(EnumChatFormatting.RED + "EXPLOSION OVER!", 2);
+ }
+ }
+
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/NoF3Coords.java b/src/main/java/me/Danker/features/NoF3Coords.java
new file mode 100644
index 0000000..4f362e6
--- /dev/null
+++ b/src/main/java/me/Danker/features/NoF3Coords.java
@@ -0,0 +1,33 @@
+package me.Danker.features;
+
+import me.Danker.commands.MoveCommand;
+import me.Danker.commands.ScaleCommand;
+import me.Danker.commands.ToggleCommand;
+import me.Danker.events.RenderOverlay;
+import me.Danker.handlers.TextRenderer;
+import net.minecraft.client.Minecraft;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+public class NoF3Coords {
+
+ public static String COORDS_COLOUR;
+
+ @SubscribeEvent
+ public void renderPlayerInfo(RenderOverlay event) {
+ Minecraft mc = Minecraft.getMinecraft();
+
+ if (ToggleCommand.coordsToggled) {
+ EntityPlayer player = mc.thePlayer;
+
+ double xDir = (player.rotationYaw % 360 + 360) % 360;
+ if (xDir > 180) xDir -= 360;
+ xDir = (double) Math.round(xDir * 10d) / 10d;
+ double yDir = (double) Math.round(player.rotationPitch * 10d) / 10d;
+
+ String coordText = COORDS_COLOUR + (int) player.posX + " / " + (int) player.posY + " / " + (int) player.posZ + " (" + xDir + " / " + yDir + ")";
+ new TextRenderer(mc, coordText, MoveCommand.coordsXY[0], MoveCommand.coordsXY[1], ScaleCommand.coordsScale);
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/NotifySlayerSlain.java b/src/main/java/me/Danker/features/NotifySlayerSlain.java
new file mode 100644
index 0000000..ee0bc41
--- /dev/null
+++ b/src/main/java/me/Danker/features/NotifySlayerSlain.java
@@ -0,0 +1,88 @@
+package me.Danker.features;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.handlers.ScoreboardHandler;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.entity.monster.EntitySpider;
+import net.minecraft.entity.monster.EntityZombie;
+import net.minecraft.entity.passive.EntityWolf;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.event.entity.player.ArrowNockEvent;
+import net.minecraftforge.event.entity.player.AttackEntityEvent;
+import net.minecraftforge.event.entity.player.PlayerInteractEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class NotifySlayerSlain {
+
+ @SubscribeEvent
+ public void onInteract(PlayerInteractEvent event) {
+ if (!Utils.inSkyblock || Minecraft.getMinecraft().thePlayer != event.entityPlayer) return;
+ ItemStack item = event.entityPlayer.getHeldItem();
+ if (item == null) return;
+
+ if (event.action == PlayerInteractEvent.Action.RIGHT_CLICK_AIR) {
+ if (ToggleCommand.notifySlayerSlainToggled) {
+ if (ScoreboardHandler.getSidebarLines().stream().anyMatch(x -> ScoreboardHandler.cleanSB(x).contains("Boss slain!"))) {
+ if (ScoreboardHandler.getSidebarLines().stream().anyMatch(x -> {
+ String line = ScoreboardHandler.cleanSB(x);
+ return Arrays.stream(new String[]{"Howling Cave", "Ruins", "Graveyard", "Coal Mine", "Spider's Den"}).anyMatch(line::contains);
+ })) {
+ if (Utils.hasRightClickAbility(item)) {
+ List<String> lore = Utils.getItemLore(item);
+
+ int abilityLine = -1;
+ for (int i = 0; i < lore.size(); i++) {
+ String line = StringUtils.stripControlCodes(lore.get(i));
+ if (line.startsWith("Item Ability:")) abilityLine = i;
+ if (abilityLine != -1 && i > abilityLine) {
+ if (line.toLowerCase().contains("damage")) {
+ Utils.createTitle(EnumChatFormatting.RED + "Boss slain!", 2);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onArrowNock(ArrowNockEvent event) {
+ if (!Utils.inSkyblock || Minecraft.getMinecraft().thePlayer != event.entityPlayer) return;
+
+ if (ToggleCommand.notifySlayerSlainToggled) {
+ if (ScoreboardHandler.getSidebarLines().stream().anyMatch(x -> ScoreboardHandler.cleanSB(x).contains("Boss slain!"))) {
+ if (ScoreboardHandler.getSidebarLines().stream().anyMatch(x -> {
+ String line = ScoreboardHandler.cleanSB(x);
+ return Arrays.stream(new String[]{"Howling Cave", "Ruins", "Graveyard", "Coal Mine", "Spider's Den"}).anyMatch(line::contains);
+ })) {
+ Utils.createTitle(EnumChatFormatting.RED + "Boss slain!", 2);
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onAttackingEntity(AttackEntityEvent event) {
+ if (ToggleCommand.notifySlayerSlainToggled && (event.target instanceof EntityZombie || event.target instanceof EntitySpider || event.target instanceof EntityWolf)) {
+ List<String> scoreboard = ScoreboardHandler.getSidebarLines();
+
+ for (String line : scoreboard) {
+ String cleanedLine = ScoreboardHandler.cleanSB(line);
+ if (cleanedLine.contains("Boss slain!")) {
+ Utils.createTitle(EnumChatFormatting.RED + "Boss slain!", 2);
+ break;
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/PetColours.java b/src/main/java/me/Danker/features/PetColours.java
new file mode 100644
index 0000000..5889b12
--- /dev/null
+++ b/src/main/java/me/Danker/features/PetColours.java
@@ -0,0 +1,69 @@
+package me.Danker.features;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.events.GuiChestBackgroundDrawnEvent;
+import me.Danker.utils.Utils;
+import net.minecraft.inventory.Slot;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import java.util.regex.Pattern;
+
+public class PetColours {
+
+ static Pattern petPattern = Pattern.compile("\\[Lvl [\\d]{1,3}]");
+ public static int PET_1_TO_9;
+ public static int PET_10_TO_19;
+ public static int PET_20_TO_29;
+ public static int PET_30_TO_39;
+ public static int PET_40_TO_49;
+ public static int PET_50_TO_59;
+ public static int PET_60_TO_69;
+ public static int PET_70_TO_79;
+ public static int PET_80_TO_89;
+ public static int PET_90_TO_99;
+ public static int PET_100;
+
+ @SubscribeEvent
+ public void onGuiRender(GuiChestBackgroundDrawnEvent event) {
+ if (ToggleCommand.petColoursToggled) {
+ for (Slot slot : event.slots) {
+ ItemStack item = slot.getStack();
+ if (item == null) continue;
+ String name = item.getDisplayName();
+ if (petPattern.matcher(StringUtils.stripControlCodes(name)).find()) {
+ if (name.endsWith("aHealer") || name.endsWith("aMage") || name.endsWith("aBerserk") || name.endsWith("aArcher") || name.endsWith("aTank"))
+ continue;
+ int colour;
+ int petLevel = Integer.parseInt(item.getDisplayName().substring(item.getDisplayName().indexOf(" ") + 1, item.getDisplayName().indexOf("]")));
+ if (petLevel == 100) {
+ colour = PET_100;
+ } else if (petLevel >= 90) {
+ colour = PET_90_TO_99;
+ } else if (petLevel >= 80) {
+ colour = PET_80_TO_89;
+ } else if (petLevel >= 70) {
+ colour = PET_70_TO_79;
+ } else if (petLevel >= 60) {
+ colour = PET_60_TO_69;
+ } else if (petLevel >= 50) {
+ colour = PET_50_TO_59;
+ } else if (petLevel >= 40) {
+ colour = PET_40_TO_49;
+ } else if (petLevel >= 30) {
+ colour = PET_30_TO_39;
+ } else if (petLevel >= 20) {
+ colour = PET_20_TO_29;
+ } else if (petLevel >= 10) {
+ colour = PET_10_TO_19;
+ } else {
+ colour = PET_1_TO_9;
+ }
+ Utils.drawOnSlot(event.chestSize, slot.xDisplayPosition, slot.yDisplayPosition, colour + 0xBF000000);
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/Reparty.java b/src/main/java/me/Danker/features/Reparty.java
new file mode 100644
index 0000000..a404bf5
--- /dev/null
+++ b/src/main/java/me/Danker/features/Reparty.java
@@ -0,0 +1,143 @@
+package me.Danker.features;
+
+import me.Danker.DankersSkyblockMod;
+import me.Danker.commands.RepartyCommand;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.entity.EntityPlayerSP;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Reparty {
+
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
+ public void onChat(ClientChatReceivedEvent event) {
+ String message = StringUtils.stripControlCodes(event.message.getUnformattedText());
+
+ // Getting party
+ if (RepartyCommand.gettingParty) {
+ if (message.contains("-----")) {
+ switch(RepartyCommand.Delimiter) {
+ case 0:
+ System.out.println("Get Party Delimiter Cancelled");
+ RepartyCommand.Delimiter++;
+ event.setCanceled(true);
+ return;
+ case 1:
+ System.out.println("Done querying party");
+ RepartyCommand.gettingParty = false;
+ RepartyCommand.Delimiter = 0;
+ event.setCanceled(true);
+ return;
+ }
+ }else if (message.startsWith("Party M") || message.startsWith("Party Leader")){
+ EntityPlayerSP player = Minecraft.getMinecraft().thePlayer;
+
+ Pattern party_start_pattern = Pattern.compile("^Party Members \\((\\d+)\\)$");
+ Pattern leader_pattern = Pattern.compile("^Party Leader: (?:\\[.+?] )?(\\w+) ●$");
+ Pattern members_pattern = Pattern.compile(" (?:\\[.+?] )?(\\w+) ●");
+ Matcher party_start = party_start_pattern.matcher(message);
+ Matcher leader = leader_pattern.matcher(message);
+ Matcher members = members_pattern.matcher(message);
+
+ if (party_start.matches() && Integer.parseInt(party_start.group(1)) == 1) {
+ player.addChatMessage(new ChatComponentText(DankersSkyblockMod.ERROR_COLOUR + "You cannot reparty yourself."));
+ RepartyCommand.partyThread.interrupt();
+ } else if (leader.matches() && !(leader.group(1).equals(player.getName()))) {
+ player.addChatMessage(new ChatComponentText(DankersSkyblockMod.ERROR_COLOUR + "You are not party leader."));
+ RepartyCommand.partyThread.interrupt();
+ } else {
+ while (members.find()) {
+ String partyMember = members.group(1);
+ if (!partyMember.equals(player.getName())) {
+ RepartyCommand.party.add(partyMember);
+ System.out.println(partyMember);
+ }
+ }
+ }
+ event.setCanceled(true);
+ return;
+ }
+ }
+ // Disbanding party
+ if (RepartyCommand.disbanding) {
+ if (message.contains("-----")) {
+ switch (RepartyCommand.Delimiter) {
+ case 0:
+ System.out.println("Disband Delimiter Cancelled");
+ RepartyCommand.Delimiter++;
+ event.setCanceled(true);
+ return;
+ case 1:
+ System.out.println("Done disbanding");
+ RepartyCommand.disbanding = false;
+ RepartyCommand.Delimiter = 0;
+ event.setCanceled(true);
+ return;
+ }
+ } else if (message.endsWith("has disbanded the party!")) {
+ event.setCanceled(true);
+ return;
+ }
+ }
+ // Inviting
+ if (RepartyCommand.inviting) {
+ if (message.contains("-----")) {
+ switch (RepartyCommand.Delimiter) {
+ case 1:
+ event.setCanceled(true);
+ RepartyCommand.Delimiter = 0;
+ System.out.println("Player Invited!");
+ RepartyCommand.inviting = false;
+ return;
+ case 0:
+ RepartyCommand.Delimiter++;
+ event.setCanceled(true);
+ return;
+ }
+ } else if (message.endsWith(" to the party! They have 60 seconds to accept.")) {
+ Pattern invitePattern = Pattern.compile("(?:(?:\\[.+?] )?(?:\\w+) invited )(?:\\[.+?] )?(\\w+)");
+ Matcher invitee = invitePattern.matcher(message);
+ if (invitee.find()) {
+ System.out.println("" + invitee.group(1) + ": " + RepartyCommand.repartyFailList.remove(invitee.group(1)));
+ }
+ event.setCanceled(true);
+ return;
+ } else if (message.contains("Couldn't find a player") || message.contains("You cannot invite that player")) {
+ event.setCanceled(true);
+ return;
+ }
+ }
+ // Fail Inviting
+ if (RepartyCommand.failInviting) {
+ if (message.contains("-----")) {
+ switch (RepartyCommand.Delimiter) {
+ case 1:
+ event.setCanceled(true);
+ RepartyCommand.Delimiter = 0;
+ System.out.println("Player Invited!");
+ RepartyCommand.inviting = false;
+ return;
+ case 0:
+ RepartyCommand.Delimiter++;
+ event.setCanceled(true);
+ }
+ } else if (message.endsWith(" to the party! They have 60 seconds to accept.")) {
+ Pattern invitePattern = Pattern.compile("(?:(?:\\[.+?] )?(?:\\w+) invited )(?:\\[.+?] )?(\\w+)");
+ Matcher invitee = invitePattern.matcher(message);
+ if (invitee.find()) {
+ System.out.println("" + invitee.group(1) + ": " + RepartyCommand.repartyFailList.remove(invitee.group(1)));
+ }
+ event.setCanceled(true);
+ } else if (message.contains("Couldn't find a player") || message.contains("You cannot invite that player")) {
+ event.setCanceled(true);
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/Skill50Display.java b/src/main/java/me/Danker/features/Skill50Display.java
new file mode 100644
index 0000000..511bb16
--- /dev/null
+++ b/src/main/java/me/Danker/features/Skill50Display.java
@@ -0,0 +1,77 @@
+package me.Danker.features;
+
+import me.Danker.commands.MoveCommand;
+import me.Danker.commands.ScaleCommand;
+import me.Danker.commands.ToggleCommand;
+import me.Danker.events.RenderOverlay;
+import me.Danker.handlers.TextRenderer;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+
+import java.text.NumberFormat;
+import java.util.Locale;
+
+public class Skill50Display {
+
+ public static int SKILL_TIME;
+ public static int skillTimer = -1;
+ public static boolean showSkill = false;
+ public static String skillText = "";
+ public static String SKILL_50_COLOUR;
+
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
+ public void onChat(ClientChatReceivedEvent event) {
+ if (!Utils.inSkyblock || event.type != 2) return;
+
+ String[] actionBarSections = event.message.getUnformattedText().split(" {3,}");
+
+ for (String section : actionBarSections) {
+ if (section.contains("+") && section.contains("/") && section.contains("(")) {
+ if (ToggleCommand.skill50DisplayToggled && !section.contains("Runecrafting")) {
+ String xpGained = section.substring(section.indexOf("+"), section.indexOf("(") - 1);
+ double currentXp = Double.parseDouble(section.substring(section.indexOf("(") + 1, section.indexOf("/")).replace(",", ""));
+ int limit;
+ int totalXp;
+ if (section.contains("Farming") || section.contains("Enchanting") || section.contains("Mining")) {
+ limit = 60;
+ totalXp = 111672425;
+ } else {
+ limit = 50;
+ totalXp = 55172425;
+ }
+ int previousXp = Utils.getPastXpEarned(Integer.parseInt(section.substring(section.indexOf("/") + 1, section.indexOf(")")).replaceAll(",", "")), limit);
+ double percentage = Math.floor(((currentXp + previousXp) / totalXp) * 10000D) / 100D;
+
+ NumberFormat nf = NumberFormat.getNumberInstance(Locale.US);
+ skillTimer = SKILL_TIME;
+ showSkill = true;
+ skillText = SKILL_50_COLOUR + xpGained + " (" + nf.format(currentXp + previousXp) + "/" + nf.format(totalXp) + ") " + percentage + "%";
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onTick(TickEvent.ClientTickEvent event) {
+ if (event.phase != TickEvent.Phase.START) return;
+
+ if (skillTimer >= 0) {
+ if (skillTimer == 0) {
+ showSkill = false;
+ }
+ skillTimer--;
+ }
+ }
+
+ @SubscribeEvent
+ public void renderPlayerInfo(RenderOverlay event) {
+ if (showSkill) {
+ new TextRenderer(Minecraft.getMinecraft(), skillText, MoveCommand.skill50XY[0], MoveCommand.skill50XY[1], ScaleCommand.skill50Scale);
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/SkillTracker.java b/src/main/java/me/Danker/features/SkillTracker.java
new file mode 100644
index 0000000..15e9fdd
--- /dev/null
+++ b/src/main/java/me/Danker/features/SkillTracker.java
@@ -0,0 +1,208 @@
+package me.Danker.features;
+
+import me.Danker.DankersSkyblockMod;
+import me.Danker.commands.MoveCommand;
+import me.Danker.commands.ScaleCommand;
+import me.Danker.commands.ToggleCommand;
+import me.Danker.events.RenderOverlay;
+import me.Danker.handlers.TextRenderer;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.entity.EntityPlayerSP;
+import net.minecraft.client.gui.inventory.GuiChest;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.client.event.GuiOpenEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.InputEvent;
+import org.apache.commons.lang3.time.StopWatch;
+
+import java.text.NumberFormat;
+import java.util.Locale;
+
+public class SkillTracker {
+
+ static String lastSkill = "Farming";
+ public static boolean showSkillTracker;
+ public static StopWatch skillStopwatch = new StopWatch();
+ static double farmingXP = 0;
+ public static double farmingXPGained = 0;
+ static double miningXP = 0;
+ public static double miningXPGained = 0;
+ static double combatXP = 0;
+ public static double combatXPGained = 0;
+ static double foragingXP = 0;
+ public static double foragingXPGained = 0;
+ static double fishingXP = 0;
+ public static double fishingXPGained = 0;
+ static double enchantingXP = 0;
+ public static double enchantingXPGained = 0;
+ static double alchemyXP = 0;
+ public static double alchemyXPGained = 0;
+ static double xpLeft = 0;
+ static double timeSinceGained = 0;
+ public static String SKILL_TRACKER_COLOUR;
+
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
+ public void onChat(ClientChatReceivedEvent event) {
+ if (!Utils.inSkyblock || event.type != 2) return;
+
+ String[] actionBarSections = event.message.getUnformattedText().split(" {3,}");
+
+ for (String section : actionBarSections) {
+ if (section.contains("+") && section.contains("/") && section.contains("(")) {
+ if (!section.contains("Runecrafting") && !section.contains("Carpentry")) {
+ if (ToggleCommand.autoSkillTrackerToggled && System.currentTimeMillis() / 1000 - timeSinceGained <= 2) {
+ if (skillStopwatch.isStarted() && skillStopwatch.isSuspended()) {
+ skillStopwatch.resume();
+ } else if (!skillStopwatch.isStarted()) {
+ skillStopwatch.start();
+ }
+ }
+ timeSinceGained = System.currentTimeMillis() / 1000;
+
+ int limit = section.contains("Farming") || section.contains("Enchanting") || section.contains("Mining") ? 60 : 50;
+ double currentXP = Double.parseDouble(section.substring(section.indexOf("(") + 1, section.indexOf("/")).replace(",", ""));
+ int xpToLevelUp = Integer.parseInt(section.substring(section.indexOf("/") + 1, section.indexOf(")")).replaceAll(",", ""));
+ xpLeft = xpToLevelUp - currentXP;
+ int previousXP = Utils.getPastXpEarned(xpToLevelUp, limit);
+ double totalXP = currentXP + previousXP;
+
+ String skill = section.substring(section.indexOf(" ") + 1, section.lastIndexOf(" "));
+ switch (skill) {
+ case "Farming":
+ lastSkill = "Farming";
+ if (farmingXP != 0) {
+ if (skillStopwatch.isStarted() && !skillStopwatch.isSuspended()) farmingXPGained += totalXP - farmingXP;
+ }
+ farmingXP = totalXP;
+ break;
+ case "Mining":
+ lastSkill = "Mining";
+ if (miningXP != 0) {
+ if (skillStopwatch.isStarted() && !skillStopwatch.isSuspended()) miningXPGained += totalXP - miningXP;
+ }
+ miningXP = totalXP;
+ break;
+ case "Combat":
+ lastSkill = "Combat";
+ if (combatXP != 0) {
+ if (skillStopwatch.isStarted() && !skillStopwatch.isSuspended()) combatXPGained += totalXP - combatXP;
+ }
+ combatXP = totalXP;
+ break;
+ case "Foraging":
+ lastSkill = "Foraging";
+ if (foragingXP != 0) {
+ if (skillStopwatch.isStarted() && !skillStopwatch.isSuspended()) foragingXPGained += totalXP - foragingXP;
+ }
+ foragingXP = totalXP;
+ break;
+ case "Fishing":
+ lastSkill = "Fishing";
+ if (fishingXP != 0) {
+ if (skillStopwatch.isStarted() && !skillStopwatch.isSuspended()) fishingXPGained += totalXP - fishingXP;
+ }
+ fishingXP = totalXP;
+ break;
+ case "Enchanting":
+ lastSkill = "Enchanting";
+ if (enchantingXP != 0) {
+ if (skillStopwatch.isStarted() && !skillStopwatch.isSuspended()) enchantingXPGained += totalXP - enchantingXP;
+ }
+ enchantingXP = totalXP;
+ break;
+ case "Alchemy":
+ lastSkill = "Alchemy";
+ if (alchemyXP != 0) {
+ if (skillStopwatch.isStarted() && !skillStopwatch.isSuspended()) alchemyXPGained += totalXP - alchemyXP;
+ }
+ alchemyXP = totalXP;
+ break;
+ default:
+ System.err.println("Unknown skill.");
+ }
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void renderPlayerInfo(RenderOverlay event) {
+ if (showSkillTracker && Utils.inSkyblock) {
+ int xpPerHour;
+ double xpToShow = 0;
+ switch (lastSkill) {
+ case "Farming":
+ xpToShow = farmingXPGained;
+ break;
+ case "Mining":
+ xpToShow = miningXPGained;
+ break;
+ case "Combat":
+ xpToShow = combatXPGained;
+ break;
+ case "Foraging":
+ xpToShow = foragingXPGained;
+ break;
+ case "Fishing":
+ xpToShow = fishingXPGained;
+ break;
+ case "Enchanting":
+ xpToShow = enchantingXPGained;
+ break;
+ case "Alchemy":
+ xpToShow = alchemyXPGained;
+ break;
+ default:
+ System.err.println("Unknown skill in rendering.");
+ }
+ xpPerHour = (int) Math.round(xpToShow / ((skillStopwatch.getTime() + 1) / 3600000d));
+ String skillTrackerText = SKILL_TRACKER_COLOUR + lastSkill + " XP Earned: " + NumberFormat.getNumberInstance(Locale.US).format(xpToShow) + "\n" +
+ SKILL_TRACKER_COLOUR + "Time Elapsed: " + Utils.getTimeBetween(0, skillStopwatch.getTime() / 1000d) + "\n" +
+ SKILL_TRACKER_COLOUR + "XP Per Hour: " + NumberFormat.getIntegerInstance(Locale.US).format(xpPerHour);
+ if (xpLeft >= 0) {
+ String time = xpPerHour == 0 ? "Never" : Utils.getTimeBetween(0, xpLeft / (xpPerHour / 3600D));
+ skillTrackerText += "\n" + SKILL_TRACKER_COLOUR + "Time Until Next Level: " + time;
+ }
+ if (!skillStopwatch.isStarted() || skillStopwatch.isSuspended()) {
+ skillTrackerText += "\n" + EnumChatFormatting.RED + "PAUSED";
+ }
+
+ new TextRenderer(Minecraft.getMinecraft(), skillTrackerText, MoveCommand.skillTrackerXY[0], MoveCommand.skillTrackerXY[1], ScaleCommand.skillTrackerScale);
+ }
+ }
+
+ @SubscribeEvent
+ public void onKey(InputEvent.KeyInputEvent event) {
+ if (!Utils.inSkyblock) return;
+
+ EntityPlayerSP player = Minecraft.getMinecraft().thePlayer;
+ if (DankersSkyblockMod.keyBindings[2].isPressed()) {
+ if (skillStopwatch.isStarted() && skillStopwatch.isSuspended()) {
+ skillStopwatch.resume();
+ player.addChatMessage(new ChatComponentText(DankersSkyblockMod.MAIN_COLOUR + "Skill tracker started."));
+ } else if (!skillStopwatch.isStarted()) {
+ skillStopwatch.start();
+ player.addChatMessage(new ChatComponentText(DankersSkyblockMod.MAIN_COLOUR + "Skill tracker started."));
+ } else if (skillStopwatch.isStarted() && !skillStopwatch.isSuspended()) {
+ skillStopwatch.suspend();
+ player.addChatMessage(new ChatComponentText(DankersSkyblockMod.MAIN_COLOUR + "Skill tracker paused."));
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onGuiOpen(GuiOpenEvent event) {
+ if (event.gui instanceof GuiChest) {
+ if (ToggleCommand.autoSkillTrackerToggled) {
+ if (skillStopwatch.isStarted() && !skillStopwatch.isSuspended()) {
+ skillStopwatch.suspend();
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/SpamHider.java b/src/main/java/me/Danker/features/SpamHider.java
new file mode 100644
index 0000000..4b22f61
--- /dev/null
+++ b/src/main/java/me/Danker/features/SpamHider.java
@@ -0,0 +1,51 @@
+package me.Danker.features;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.utils.Utils;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+public class SpamHider {
+
+ @SubscribeEvent
+ public void onChat(ClientChatReceivedEvent event) {
+ String message = StringUtils.stripControlCodes(event.message.getUnformattedText());
+
+ if (!Utils.inSkyblock) return;
+ if (message.contains(":")) return;
+
+ // Spirit Sceptre
+ if (!ToggleCommand.sceptreMessages && message.contains("Your Spirit Sceptre hit ")) {
+ event.setCanceled(true);
+ return;
+ }
+ // Midas Staff
+ if (!ToggleCommand.midasStaffMessages && message.contains("Your Molten Wave hit ")) {
+ event.setCanceled(true);
+ return;
+ }
+ // Heals
+ if (!ToggleCommand.healMessages && message.contains(" health!") && (message.contains("You healed ") || message.contains(" healed you for "))) {
+ event.setCanceled(true);
+ return;
+ }
+ // Ability Cooldown
+ if (!ToggleCommand.cooldownMessages && message.contains("This ability is on cooldown for ")) {
+ event.setCanceled(true);
+ return;
+ }
+ // Out of mana messages
+ if (!ToggleCommand.manaMessages && message.contains("You do not have enough mana to do this!")) {
+ event.setCanceled(true);
+ return;
+ }
+ // Implosion
+ if (!ToggleCommand.implosionMessages) {
+ if (message.contains("Your Implosion hit ") || message.contains("There are blocks in the way")) {
+ event.setCanceled(true);
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/SpiritBearAlert.java b/src/main/java/me/Danker/features/SpiritBearAlert.java
new file mode 100644
index 0000000..604fdf3
--- /dev/null
+++ b/src/main/java/me/Danker/features/SpiritBearAlert.java
@@ -0,0 +1,24 @@
+package me.Danker.features;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.utils.Utils;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+public class SpiritBearAlert {
+
+ @SubscribeEvent
+ public void onChat(ClientChatReceivedEvent event) {
+ String message = StringUtils.stripControlCodes(event.message.getUnformattedText());
+
+ if (!Utils.inSkyblock) return;
+ if (message.contains(":")) return;
+
+ if (ToggleCommand.spiritBearAlerts && message.contains("The Spirit Bear has appeared!")) {
+ Utils.createTitle(EnumChatFormatting.DARK_PURPLE + "SPIRIT BEAR", 2);
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/StopSalvagingStarredItems.java b/src/main/java/me/Danker/features/StopSalvagingStarredItems.java
new file mode 100644
index 0000000..08d0c7a
--- /dev/null
+++ b/src/main/java/me/Danker/features/StopSalvagingStarredItems.java
@@ -0,0 +1,34 @@
+package me.Danker.features;
+
+import me.Danker.DankersSkyblockMod;
+import me.Danker.commands.ToggleCommand;
+import me.Danker.events.ChestSlotClickedEvent;
+import net.minecraft.client.Minecraft;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.ChatComponentText;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+public class StopSalvagingStarredItems {
+
+ @SubscribeEvent
+ public void onSlotClick(ChestSlotClickedEvent event) {
+ ItemStack item = event.item;
+ if (ToggleCommand.stopSalvageStarredToggled && event.inventoryName.startsWith("Salvage")) {
+ if (item == null) return;
+ boolean inSalvageGui = false;
+ if (item.getDisplayName().contains("Salvage") || item.getDisplayName().contains("Essence")) {
+ ItemStack salvageItem = event.inventory.getStackInSlot(13);
+ if (salvageItem == null) return;
+ item = salvageItem;
+ inSalvageGui = true;
+ }
+ if (item.getDisplayName().contains("✪") && (event.slot.slotNumber > 53 || inSalvageGui)) {
+ Minecraft.getMinecraft().thePlayer.playSound("note.bass", 1, 0.5f);
+ Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(DankersSkyblockMod.ERROR_COLOUR + "Danker's Skyblock Mod has stopped you from salvaging that item!"));
+ event.setCanceled(true);
+ return;
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/UpdateChecker.java b/src/main/java/me/Danker/features/UpdateChecker.java
new file mode 100644
index 0000000..747fe91
--- /dev/null
+++ b/src/main/java/me/Danker/features/UpdateChecker.java
@@ -0,0 +1,52 @@
+package me.Danker.features;
+
+import com.google.gson.JsonObject;
+import me.Danker.DankersSkyblockMod;
+import me.Danker.handlers.APIHandler;
+import net.minecraft.client.Minecraft;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.event.ClickEvent;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraftforge.event.entity.EntityJoinWorldEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.versioning.DefaultArtifactVersion;
+
+public class UpdateChecker {
+
+ static boolean updateChecked = false;
+
+ @SubscribeEvent
+ public void onJoin(EntityJoinWorldEvent event) {
+ if (!updateChecked) {
+ updateChecked = true;
+
+ // MULTI THREAD DRIFTING
+ new Thread(() -> {
+ EntityPlayer player = Minecraft.getMinecraft().thePlayer;
+
+ System.out.println("Checking for updates...");
+ JsonObject latestRelease = APIHandler.getResponse("https://api.github.com/repos/bowser0000/SkyblockMod/releases/latest");
+
+ String latestTag = latestRelease.get("tag_name").getAsString();
+ DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(DankersSkyblockMod.VERSION);
+ DefaultArtifactVersion latestVersion = new DefaultArtifactVersion(latestTag.substring(1));
+
+ if (currentVersion.compareTo(latestVersion) < 0) {
+ String releaseURL = latestRelease.get("html_url").getAsString();
+
+ ChatComponentText update = new ChatComponentText(EnumChatFormatting.GREEN + "" + EnumChatFormatting.BOLD + " [UPDATE] ");
+ update.setChatStyle(update.getChatStyle().setChatClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, releaseURL)));
+
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException ex) {
+ ex.printStackTrace();
+ }
+ player.addChatMessage(new ChatComponentText(DankersSkyblockMod.ERROR_COLOUR + DankersSkyblockMod.MODID + " is outdated. Please update to " + latestTag + ".\n").appendSibling(update));
+ }
+ }).start();
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/WatcherReadyAlert.java b/src/main/java/me/Danker/features/WatcherReadyAlert.java
new file mode 100644
index 0000000..b68ccc2
--- /dev/null
+++ b/src/main/java/me/Danker/features/WatcherReadyAlert.java
@@ -0,0 +1,22 @@
+package me.Danker.features;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.utils.Utils;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+public class WatcherReadyAlert {
+
+ @SubscribeEvent
+ public void onChat(ClientChatReceivedEvent event) {
+ String message = StringUtils.stripControlCodes(event.message.getUnformattedText());
+
+ if (!Utils.inDungeons) return;
+
+ if (message.contains("[BOSS] The Watcher: That will be enough for now.")) {
+ if (ToggleCommand.watcherReadyToggled) Utils.createTitle(EnumChatFormatting.RED + "WATCHER READY", 2);
+ }
+ }
+}
diff --git a/src/main/java/me/Danker/features/loot/LootDisplay.java b/src/main/java/me/Danker/features/loot/LootDisplay.java
new file mode 100644
index 0000000..363b70c
--- /dev/null
+++ b/src/main/java/me/Danker/features/loot/LootDisplay.java
@@ -0,0 +1,905 @@
+package me.Danker.features.loot;
+
+import me.Danker.commands.MoveCommand;
+import me.Danker.commands.ScaleCommand;
+import me.Danker.commands.ToggleCommand;
+import me.Danker.events.RenderOverlay;
+import me.Danker.handlers.ConfigHandler;
+import me.Danker.handlers.TextRenderer;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import java.text.NumberFormat;
+import java.util.Locale;
+
+public class LootDisplay {
+
+ public static String display;
+ public static boolean auto;
+
+ @SubscribeEvent
+ public void renderPlayerInfo(RenderOverlay event) {
+ if (!display.equals("off")) {
+ Minecraft mc = Minecraft.getMinecraft();
+ String dropsText = "";
+ String countText = "";
+ String dropsTextTwo;
+ String countTextTwo;
+ String timeBetween;
+ String bossesBetween;
+ String drop20;
+ double timeNow = System.currentTimeMillis() / 1000;
+ NumberFormat nf = NumberFormat.getIntegerInstance(Locale.US);
+
+ switch (display) {
+ case "wolf":
+ if (LootTracker.wolfTime == -1) {
+ timeBetween = "Never";
+ } else {
+ timeBetween = Utils.getTimeBetween(LootTracker.wolfTime, timeNow);
+ }
+ if (LootTracker.wolfBosses == -1) {
+ bossesBetween = "Never";
+ } else {
+ bossesBetween = nf.format(LootTracker.wolfBosses);
+ }
+ if (ToggleCommand.slayerCountTotal) {
+ drop20 = nf.format(LootTracker.wolfWheels);
+ } else {
+ drop20 = nf.format(LootTracker.wolfWheelsDrops) + " times";
+ }
+
+ dropsText = EnumChatFormatting.GOLD + "Svens Killed:\n" +
+ EnumChatFormatting.GREEN + "Wolf Teeth:\n" +
+ EnumChatFormatting.BLUE + "Hamster Wheels:\n" +
+ EnumChatFormatting.AQUA + "Spirit Runes:\n" +
+ EnumChatFormatting.WHITE + "Critical VI Books:\n" +
+ EnumChatFormatting.DARK_RED + "Red Claw Eggs:\n" +
+ EnumChatFormatting.GOLD + "Couture Runes:\n" +
+ EnumChatFormatting.AQUA + "Grizzly Baits:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Overfluxes:\n" +
+ EnumChatFormatting.AQUA + "Time Since RNG:\n" +
+ EnumChatFormatting.AQUA + "Bosses Since RNG:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.wolfSvens) + "\n" +
+ EnumChatFormatting.GREEN + nf.format(LootTracker.wolfTeeth) + "\n" +
+ EnumChatFormatting.BLUE + drop20 + "\n" +
+ EnumChatFormatting.AQUA + LootTracker.wolfSpirits + "\n" +
+ EnumChatFormatting.WHITE + LootTracker.wolfBooks + "\n" +
+ EnumChatFormatting.DARK_RED + LootTracker.wolfEggs + "\n" +
+ EnumChatFormatting.GOLD + LootTracker.wolfCoutures + "\n" +
+ EnumChatFormatting.AQUA + LootTracker.wolfBaits + "\n" +
+ EnumChatFormatting.DARK_PURPLE + LootTracker.wolfFluxes + "\n" +
+ EnumChatFormatting.AQUA + timeBetween + "\n" +
+ EnumChatFormatting.AQUA + bossesBetween;
+ break;
+ case "wolf_session":
+ if (LootTracker.wolfTimeSession == -1) {
+ timeBetween = "Never";
+ } else {
+ timeBetween = Utils.getTimeBetween(LootTracker.wolfTimeSession, timeNow);
+ }
+ if (LootTracker.wolfBossesSession == -1) {
+ bossesBetween = "Never";
+ } else {
+ bossesBetween = nf.format(LootTracker.wolfBossesSession);
+ }
+ if (ToggleCommand.slayerCountTotal) {
+ drop20 = nf.format(LootTracker.wolfWheelsSession);
+ } else {
+ drop20 = nf.format(LootTracker.wolfWheelsDropsSession) + " times";
+ }
+
+ dropsText = EnumChatFormatting.GOLD + "Svens Killed:\n" +
+ EnumChatFormatting.GREEN + "Wolf Teeth:\n" +
+ EnumChatFormatting.BLUE + "Hamster Wheels:\n" +
+ EnumChatFormatting.AQUA + "Spirit Runes:\n" +
+ EnumChatFormatting.WHITE + "Critical VI Books:\n" +
+ EnumChatFormatting.DARK_RED + "Red Claw Eggs:\n" +
+ EnumChatFormatting.GOLD + "Couture Runes:\n" +
+ EnumChatFormatting.AQUA + "Grizzly Baits:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Overfluxes:\n" +
+ EnumChatFormatting.AQUA + "Time Since RNG:\n" +
+ EnumChatFormatting.AQUA + "Bosses Since RNG:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.wolfSvensSession) + "\n" +
+ EnumChatFormatting.GREEN + nf.format(LootTracker.wolfTeethSession) + "\n" +
+ EnumChatFormatting.BLUE + drop20 + "\n" +
+ EnumChatFormatting.AQUA + LootTracker.wolfSpiritsSession + "\n" +
+ EnumChatFormatting.WHITE + LootTracker.wolfBooksSession + "\n" +
+ EnumChatFormatting.DARK_RED + LootTracker.wolfEggsSession + "\n" +
+ EnumChatFormatting.GOLD + LootTracker.wolfCouturesSession + "\n" +
+ EnumChatFormatting.AQUA + LootTracker.wolfBaitsSession + "\n" +
+ EnumChatFormatting.DARK_PURPLE + LootTracker.wolfFluxesSession + "\n" +
+ EnumChatFormatting.AQUA + timeBetween + "\n" +
+ EnumChatFormatting.AQUA + bossesBetween;
+ break;
+ case "spider":
+ if (LootTracker.spiderTime == -1) {
+ timeBetween = "Never";
+ } else {
+ timeBetween = Utils.getTimeBetween(LootTracker.spiderTime, timeNow);
+ }
+ if (LootTracker.spiderBosses == -1) {
+ bossesBetween = "Never";
+ } else {
+ bossesBetween = nf.format(LootTracker.spiderBosses);
+ }
+ if (ToggleCommand.slayerCountTotal) {
+ drop20 = nf.format(LootTracker.spiderTAP);
+ } else {
+ drop20 = nf.format(LootTracker.spiderTAPDrops) + " times";
+ }
+
+ dropsText = EnumChatFormatting.GOLD + "Tarantulas Killed:\n" +
+ EnumChatFormatting.GREEN + "Tarantula Webs:\n" +
+ EnumChatFormatting.DARK_GREEN + "Arrow Poison:\n" +
+ EnumChatFormatting.DARK_GRAY + "Bite Runes:\n" +
+ EnumChatFormatting.WHITE + "Bane VI Books:\n" +
+ EnumChatFormatting.AQUA + "Spider Catalysts:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Tarantula Talismans:\n" +
+ EnumChatFormatting.LIGHT_PURPLE + "Fly Swatters:\n" +
+ EnumChatFormatting.GOLD + "Digested Mosquitos:\n" +
+ EnumChatFormatting.AQUA + "Time Since RNG:\n" +
+ EnumChatFormatting.AQUA + "Bosses Since RNG:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.spiderTarantulas) + "\n" +
+ EnumChatFormatting.GREEN + nf.format(LootTracker.spiderWebs) + "\n" +
+ EnumChatFormatting.DARK_GREEN + drop20 + "\n" +
+ EnumChatFormatting.DARK_GRAY + LootTracker.spiderBites + "\n" +
+ EnumChatFormatting.WHITE + LootTracker.spiderBooks + "\n" +
+ EnumChatFormatting.AQUA + LootTracker.spiderCatalysts + "\n" +
+ EnumChatFormatting.DARK_PURPLE + LootTracker.spiderTalismans + "\n" +
+ EnumChatFormatting.LIGHT_PURPLE + LootTracker.spiderSwatters + "\n" +
+ EnumChatFormatting.GOLD + LootTracker.spiderMosquitos + "\n" +
+ EnumChatFormatting.AQUA + timeBetween + "\n" +
+ EnumChatFormatting.AQUA + bossesBetween;
+ break;
+ case "spider_session":
+ if (LootTracker.spiderTimeSession == -1) {
+ timeBetween = "Never";
+ } else {
+ timeBetween = Utils.getTimeBetween(LootTracker.spiderTimeSession, timeNow);
+ }
+ if (LootTracker.spiderBossesSession == -1) {
+ bossesBetween = "Never";
+ } else {
+ bossesBetween = nf.format(LootTracker.spiderBossesSession);
+ }
+ if (ToggleCommand.slayerCountTotal) {
+ drop20 = nf.format(LootTracker.spiderTAPSession);
+ } else {
+ drop20 = nf.format(LootTracker.spiderTAPDropsSession) + " times";
+ }
+
+ dropsText = EnumChatFormatting.GOLD + "Tarantulas Killed:\n" +
+ EnumChatFormatting.GREEN + "Tarantula Webs:\n" +
+ EnumChatFormatting.DARK_GREEN + "Arrow Poison:\n" +
+ EnumChatFormatting.DARK_GRAY + "Bite Runes:\n" +
+ EnumChatFormatting.WHITE + "Bane VI Books:\n" +
+ EnumChatFormatting.AQUA + "Spider Catalysts:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Tarantula Talismans:\n" +
+ EnumChatFormatting.LIGHT_PURPLE + "Fly Swatters:\n" +
+ EnumChatFormatting.GOLD + "Digested Mosquitos:\n" +
+ EnumChatFormatting.AQUA + "Time Since RNG:\n" +
+ EnumChatFormatting.AQUA + "Bosses Since RNG:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.spiderTarantulasSession) + "\n" +
+ EnumChatFormatting.GREEN + nf.format(LootTracker.spiderWebsSession) + "\n" +
+ EnumChatFormatting.DARK_GREEN + drop20 + "\n" +
+ EnumChatFormatting.DARK_GRAY + LootTracker.spiderBitesSession + "\n" +
+ EnumChatFormatting.WHITE + LootTracker.spiderBooksSession + "\n" +
+ EnumChatFormatting.AQUA + LootTracker.spiderCatalystsSession + "\n" +
+ EnumChatFormatting.DARK_PURPLE + LootTracker.spiderTalismansSession + "\n" +
+ EnumChatFormatting.LIGHT_PURPLE + LootTracker.spiderSwattersSession + "\n" +
+ EnumChatFormatting.GOLD + LootTracker.spiderMosquitosSession + "\n" +
+ EnumChatFormatting.AQUA + timeBetween + "\n" +
+ EnumChatFormatting.AQUA + bossesBetween;
+ break;
+ case "zombie":
+ if (LootTracker.zombieTime == -1) {
+ timeBetween = "Never";
+ } else {
+ timeBetween = Utils.getTimeBetween(LootTracker.zombieTime, timeNow);
+ }
+ if (LootTracker.zombieBosses == -1) {
+ bossesBetween = "Never";
+ } else {
+ bossesBetween = nf.format(LootTracker.zombieBosses);
+ }
+ if (ToggleCommand.slayerCountTotal) {
+ drop20 = nf.format(LootTracker.zombieFoulFlesh);
+ } else {
+ drop20 = nf.format(LootTracker.zombieFoulFleshDrops) + " times";
+ }
+
+ dropsText = EnumChatFormatting.GOLD + "Revs Killed:\n" +
+ EnumChatFormatting.GREEN + "Revenant Flesh:\n" +
+ EnumChatFormatting.BLUE + "Foul Flesh:\n" +
+ EnumChatFormatting.DARK_GREEN + "Pestilence Runes:\n" +
+ EnumChatFormatting.WHITE + "Smite VI Books:\n" +
+ EnumChatFormatting.AQUA + "Undead Catalysts:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Beheaded Horrors:\n" +
+ EnumChatFormatting.RED + "Revenant Catalysts:\n" +
+ EnumChatFormatting.DARK_GREEN + "Snake Runes:\n" +
+ EnumChatFormatting.GOLD + "Scythe Blades:\n" +
+ EnumChatFormatting.AQUA + "Time Since RNG:\n" +
+ EnumChatFormatting.AQUA + "Bosses Since RNG:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.zombieRevs) + "\n" +
+ EnumChatFormatting.GREEN + nf.format(LootTracker.zombieRevFlesh) + "\n" +
+ EnumChatFormatting.BLUE + drop20 + "\n" +
+ EnumChatFormatting.DARK_GREEN + LootTracker.zombiePestilences + "\n" +
+ EnumChatFormatting.WHITE + LootTracker.zombieBooks + "\n" +
+ EnumChatFormatting.AQUA + LootTracker.zombieUndeadCatas + "\n" +
+ EnumChatFormatting.DARK_PURPLE + LootTracker.zombieBeheadeds + "\n" +
+ EnumChatFormatting.RED + LootTracker.zombieRevCatas + "\n" +
+ EnumChatFormatting.DARK_GREEN + LootTracker.zombieSnakes + "\n" +
+ EnumChatFormatting.GOLD + LootTracker.zombieScythes + "\n" +
+ EnumChatFormatting.AQUA + timeBetween + "\n" +
+ EnumChatFormatting.AQUA + bossesBetween;
+ break;
+ case "zombie_session":
+ if (LootTracker.zombieTimeSession == -1) {
+ timeBetween = "Never";
+ } else {
+ timeBetween = Utils.getTimeBetween(LootTracker.zombieTimeSession, timeNow);
+ }
+ if (LootTracker.zombieBossesSession == -1) {
+ bossesBetween = "Never";
+ } else {
+ bossesBetween = nf.format(LootTracker.zombieBossesSession);
+ }
+ if (ToggleCommand.slayerCountTotal) {
+ drop20 = nf.format(LootTracker.zombieFoulFleshSession);
+ } else {
+ drop20 = nf.format(LootTracker.zombieFoulFleshDropsSession) + " times";
+ }
+
+ dropsText = EnumChatFormatting.GOLD + "Revs Killed:\n" +
+ EnumChatFormatting.GREEN + "Revenant Flesh:\n" +
+ EnumChatFormatting.BLUE + "Foul Flesh:\n" +
+ EnumChatFormatting.DARK_GREEN + "Pestilence Runes:\n" +
+ EnumChatFormatting.WHITE + "Smite VI Books:\n" +
+ EnumChatFormatting.AQUA + "Undead Catalysts:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Beheaded Horrors:\n" +
+ EnumChatFormatting.RED + "Revenant Catalysts:\n" +
+ EnumChatFormatting.DARK_GREEN + "Snake Runes:\n" +
+ EnumChatFormatting.GOLD + "Scythe Blades:\n" +
+ EnumChatFormatting.AQUA + "Time Since RNG:\n" +
+ EnumChatFormatting.AQUA + "Bosses Since RNG:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.zombieRevsSession) + "\n" +
+ EnumChatFormatting.GREEN + nf.format(LootTracker.zombieRevFleshSession) + "\n" +
+ EnumChatFormatting.BLUE + drop20 + "\n" +
+ EnumChatFormatting.DARK_GREEN + LootTracker.zombiePestilencesSession + "\n" +
+ EnumChatFormatting.WHITE + LootTracker.zombieBooksSession + "\n" +
+ EnumChatFormatting.AQUA + LootTracker.zombieUndeadCatasSession + "\n" +
+ EnumChatFormatting.DARK_PURPLE + LootTracker.zombieBeheadedsSession + "\n" +
+ EnumChatFormatting.RED + LootTracker.zombieRevCatasSession + "\n" +
+ EnumChatFormatting.DARK_GREEN + LootTracker.zombieSnakesSession + "\n" +
+ EnumChatFormatting.GOLD + LootTracker.zombieScythes + "\n" +
+ EnumChatFormatting.AQUA + timeBetween + "\n" +
+ EnumChatFormatting.AQUA + bossesBetween;
+ break;
+ case "fishing":
+ if (LootTracker.empTime == -1) {
+ timeBetween = "Never";
+ } else {
+ timeBetween = Utils.getTimeBetween(LootTracker.empTime, timeNow);
+ }
+ if (LootTracker.empSCs == -1) {
+ bossesBetween = "Never";
+ } else {
+ bossesBetween = nf.format(LootTracker.empSCs);
+ }
+
+ dropsText = EnumChatFormatting.AQUA + "Creatures Caught:\n" +
+ EnumChatFormatting.AQUA + "Fishing Milestone:\n" +
+ EnumChatFormatting.GOLD + "Good Catches:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Great Catches:\n" +
+ EnumChatFormatting.GRAY + "Squids:\n" +
+ EnumChatFormatting.GREEN + "Sea Walkers:\n" +
+ EnumChatFormatting.DARK_GRAY + "Night Squids:\n" +
+ EnumChatFormatting.DARK_AQUA + "Sea Guardians:\n" +
+ EnumChatFormatting.BLUE + "Sea Witches:\n" +
+ EnumChatFormatting.GREEN + "Sea Archers:";
+ countText = EnumChatFormatting.AQUA + nf.format(LootTracker.seaCreatures) + "\n" +
+ EnumChatFormatting.AQUA + nf.format(LootTracker.fishingMilestone) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.goodCatches) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.greatCatches) + "\n" +
+ EnumChatFormatting.GRAY + nf.format(LootTracker.squids) + "\n" +
+ EnumChatFormatting.GREEN + nf.format(LootTracker.seaWalkers) + "\n" +
+ EnumChatFormatting.DARK_GRAY + nf.format(LootTracker.nightSquids) + "\n" +
+ EnumChatFormatting.DARK_AQUA + nf.format(LootTracker.seaGuardians) + "\n" +
+ EnumChatFormatting.BLUE + nf.format(LootTracker.seaWitches) + "\n" +
+ EnumChatFormatting.GREEN + nf.format(LootTracker.seaArchers);
+ // Seperated to save vertical space
+ dropsTextTwo = EnumChatFormatting.GREEN + "Monster of Deeps:\n" +
+ EnumChatFormatting.YELLOW + "Catfishes:\n" +
+ EnumChatFormatting.GOLD + "Carrot Kings:\n" +
+ EnumChatFormatting.GRAY + "Sea Leeches:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Guardian Defenders:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Deep Sea Protectors:\n" +
+ EnumChatFormatting.GOLD + "Hydras:\n" +
+ EnumChatFormatting.GOLD + "Sea Emperors:\n" +
+ EnumChatFormatting.AQUA + "Time Since Emp:\n" +
+ EnumChatFormatting.AQUA + "Creatures Since Emp:";
+ countTextTwo = EnumChatFormatting.GREEN + nf.format(LootTracker.monsterOfTheDeeps) + "\n" +
+ EnumChatFormatting.YELLOW + nf.format(LootTracker.catfishes) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.carrotKings) + "\n" +
+ EnumChatFormatting.GRAY + nf.format(LootTracker.seaLeeches) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.guardianDefenders) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.deepSeaProtectors) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.hydras) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.seaEmperors) + "\n" +
+ EnumChatFormatting.AQUA + timeBetween + "\n" +
+ EnumChatFormatting.AQUA + bossesBetween;
+
+ if (ToggleCommand.splitFishing) {
+ new TextRenderer(mc, dropsTextTwo, (int) (MoveCommand.displayXY[0] + (160 * ScaleCommand.displayScale)), MoveCommand.displayXY[1], ScaleCommand.displayScale);
+ new TextRenderer(mc, countTextTwo, (int) (MoveCommand.displayXY[0] + (270 * ScaleCommand.displayScale)), MoveCommand.displayXY[1], ScaleCommand.displayScale);
+ } else {
+ dropsText += "\n" + dropsTextTwo;
+ countText += "\n" + countTextTwo;
+ }
+ break;
+ case "fishing_session":
+ if (LootTracker.empTimeSession == -1) {
+ timeBetween = "Never";
+ } else {
+ timeBetween = Utils.getTimeBetween(LootTracker.empTimeSession, timeNow);
+ }
+ if (LootTracker.empSCsSession == -1) {
+ bossesBetween = "Never";
+ } else {
+ bossesBetween = nf.format(LootTracker.empSCsSession);
+ }
+
+ dropsText = EnumChatFormatting.AQUA + "Creatures Caught:\n" +
+ EnumChatFormatting.AQUA + "Fishing Milestone:\n" +
+ EnumChatFormatting.GOLD + "Good Catches:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Great Catches:\n" +
+ EnumChatFormatting.GRAY + "Squids:\n" +
+ EnumChatFormatting.GREEN + "Sea Walkers:\n" +
+ EnumChatFormatting.DARK_GRAY + "Night Squids:\n" +
+ EnumChatFormatting.DARK_AQUA + "Sea Guardians:\n" +
+ EnumChatFormatting.BLUE + "Sea Witches:\n" +
+ EnumChatFormatting.GREEN + "Sea Archers:";
+ countText = EnumChatFormatting.AQUA + nf.format(LootTracker.seaCreaturesSession) + "\n" +
+ EnumChatFormatting.AQUA + nf.format(LootTracker.fishingMilestoneSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.goodCatchesSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.greatCatchesSession) + "\n" +
+ EnumChatFormatting.GRAY + nf.format(LootTracker.squidsSession) + "\n" +
+ EnumChatFormatting.GREEN + nf.format(LootTracker.seaWalkersSession) + "\n" +
+ EnumChatFormatting.DARK_GRAY + nf.format(LootTracker.nightSquidsSession) + "\n" +
+ EnumChatFormatting.DARK_AQUA + nf.format(LootTracker.seaGuardiansSession) + "\n" +
+ EnumChatFormatting.BLUE + nf.format(LootTracker.seaWitchesSession) + "\n" +
+ EnumChatFormatting.GREEN + nf.format(LootTracker.seaArchersSession);
+ // Seperated to save vertical space
+ dropsTextTwo = EnumChatFormatting.GREEN + "Monster of Deeps:\n" +
+ EnumChatFormatting.YELLOW + "Catfishes:\n" +
+ EnumChatFormatting.GOLD + "Carrot Kings:\n" +
+ EnumChatFormatting.GRAY + "Sea Leeches:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Guardian Defenders:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Deep Sea Protectors:\n" +
+ EnumChatFormatting.GOLD + "Hydras:\n" +
+ EnumChatFormatting.GOLD + "Sea Emperors:\n" +
+ EnumChatFormatting.AQUA + "Time Since Emp:\n" +
+ EnumChatFormatting.AQUA + "Creatures Since Emp:";
+ countTextTwo = EnumChatFormatting.GREEN + nf.format(LootTracker.monsterOfTheDeepsSession) + "\n" +
+ EnumChatFormatting.YELLOW + nf.format(LootTracker.catfishesSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.carrotKingsSession) + "\n" +
+ EnumChatFormatting.GRAY + nf.format(LootTracker.seaLeechesSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.guardianDefendersSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.deepSeaProtectorsSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.hydrasSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.seaEmperorsSession) + "\n" +
+ EnumChatFormatting.AQUA + timeBetween + "\n" +
+ EnumChatFormatting.AQUA + bossesBetween;
+
+ if (ToggleCommand.splitFishing) {
+ new TextRenderer(mc, dropsTextTwo, (int) (MoveCommand.displayXY[0] + (160 * ScaleCommand.displayScale)), MoveCommand.displayXY[1], ScaleCommand.displayScale);
+ new TextRenderer(mc, countTextTwo, (int) (MoveCommand.displayXY[0] + (270 * ScaleCommand.displayScale)), MoveCommand.displayXY[1], ScaleCommand.displayScale);
+ } else {
+ dropsText += "\n" + dropsTextTwo;
+ countText += "\n" + countTextTwo;
+ }
+ break;
+ case "fishing_winter":
+ if (LootTracker.yetiTime == -1) {
+ timeBetween = "Never";
+ } else {
+ timeBetween = Utils.getTimeBetween(LootTracker.yetiTime, timeNow);
+ }
+ if (LootTracker.yetiSCs == -1) {
+ bossesBetween = "Never";
+ } else {
+ bossesBetween = nf.format(LootTracker.yetiSCs);
+ }
+
+ dropsText = EnumChatFormatting.AQUA + "Creatures Caught:\n" +
+ EnumChatFormatting.AQUA + "Fishing Milestone:\n" +
+ EnumChatFormatting.GOLD + "Good Catches:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Great Catches:\n" +
+ EnumChatFormatting.AQUA + "Frozen Steves:\n" +
+ EnumChatFormatting.WHITE + "Snowmans:\n" +
+ EnumChatFormatting.DARK_GREEN + "Grinches:\n" +
+ EnumChatFormatting.GOLD + "Yetis:\n" +
+ EnumChatFormatting.AQUA + "Time Since Yeti:\n" +
+ EnumChatFormatting.AQUA + "Creatures Since Yeti:";
+ countText = EnumChatFormatting.AQUA + nf.format(LootTracker.seaCreatures) + "\n" +
+ EnumChatFormatting.AQUA + nf.format(LootTracker.fishingMilestone) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.goodCatches) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.greatCatches) + "\n" +
+ EnumChatFormatting.AQUA + nf.format(LootTracker.frozenSteves) + "\n" +
+ EnumChatFormatting.WHITE + nf.format(LootTracker.frostyTheSnowmans) + "\n" +
+ EnumChatFormatting.DARK_GREEN + nf.format(LootTracker.grinches) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.yetis) + "\n" +
+ EnumChatFormatting.AQUA + timeBetween + "\n" +
+ EnumChatFormatting.AQUA + bossesBetween;
+ break;
+ case "fishing_winter_session":
+ if (LootTracker.yetiTimeSession == -1) {
+ timeBetween = "Never";
+ } else {
+ timeBetween = Utils.getTimeBetween(LootTracker.yetiTimeSession, timeNow);
+ }
+ if (LootTracker.yetiSCsSession == -1) {
+ bossesBetween = "Never";
+ } else {
+ bossesBetween = nf.format(LootTracker.yetiSCsSession);
+ }
+
+ dropsText = EnumChatFormatting.AQUA + "Creatures Caught:\n" +
+ EnumChatFormatting.AQUA + "Fishing Milestone:\n" +
+ EnumChatFormatting.GOLD + "Good Catches:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Great Catches:\n" +
+ EnumChatFormatting.AQUA + "Frozen Steves:\n" +
+ EnumChatFormatting.WHITE + "Snowmans:\n" +
+ EnumChatFormatting.DARK_GREEN + "Grinches:\n" +
+ EnumChatFormatting.GOLD + "Yetis:\n" +
+ EnumChatFormatting.AQUA + "Time Since Yeti:\n" +
+ EnumChatFormatting.AQUA + "Creatures Since Yeti:";
+ countText = EnumChatFormatting.AQUA + nf.format(LootTracker.seaCreaturesSession) + "\n" +
+ EnumChatFormatting.AQUA + nf.format(LootTracker.fishingMilestoneSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.goodCatchesSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.greatCatchesSession) + "\n" +
+ EnumChatFormatting.AQUA + nf.format(LootTracker.frozenStevesSession) + "\n" +
+ EnumChatFormatting.WHITE + nf.format(LootTracker.frostyTheSnowmansSession) + "\n" +
+ EnumChatFormatting.DARK_GREEN + nf.format(LootTracker.grinchesSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.yetisSession) + "\n" +
+ EnumChatFormatting.AQUA + timeBetween + "\n" +
+ EnumChatFormatting.AQUA + bossesBetween;
+ break;
+ case "fishing_festival":
+ dropsText = EnumChatFormatting.AQUA + "Creatures Caught:\n" +
+ EnumChatFormatting.AQUA + "Fishing Milestone:\n" +
+ EnumChatFormatting.GOLD + "Good Catches:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Great Catches:\n" +
+ EnumChatFormatting.LIGHT_PURPLE + "Nurse Sharks:\n" +
+ EnumChatFormatting.BLUE + "Blue Sharks:\n" +
+ EnumChatFormatting.GOLD + "Tiger Sharks:\n" +
+ EnumChatFormatting.WHITE + "Great White Sharks:";
+ countText = EnumChatFormatting.AQUA + nf.format(LootTracker.seaCreatures) + "\n" +
+ EnumChatFormatting.AQUA + nf.format(LootTracker.fishingMilestone) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.goodCatches) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.greatCatches) + "\n" +
+ EnumChatFormatting.LIGHT_PURPLE + nf.format(LootTracker.nurseSharks) + "\n" +
+ EnumChatFormatting.BLUE + nf.format(LootTracker.blueSharks) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.tigerSharks) + "\n" +
+ EnumChatFormatting.WHITE + nf.format(LootTracker.greatWhiteSharks);
+ break;
+ case "fishing_festival_session":
+ dropsText = EnumChatFormatting.AQUA + "Creatures Caught:\n" +
+ EnumChatFormatting.AQUA + "Fishing Milestone:\n" +
+ EnumChatFormatting.GOLD + "Good Catches:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Great Catches:\n" +
+ EnumChatFormatting.LIGHT_PURPLE + "Nurse Sharks:\n" +
+ EnumChatFormatting.BLUE + "Blue Sharks:\n" +
+ EnumChatFormatting.GOLD + "Tiger Sharks:\n" +
+ EnumChatFormatting.WHITE + "Great White Sharks:";
+ countText = EnumChatFormatting.AQUA + nf.format(LootTracker.seaCreaturesSession) + "\n" +
+ EnumChatFormatting.AQUA + nf.format(LootTracker.fishingMilestoneSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.goodCatchesSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.greatCatchesSession) + "\n" +
+ EnumChatFormatting.LIGHT_PURPLE + nf.format(LootTracker.nurseSharksSession) + "\n" +
+ EnumChatFormatting.BLUE + nf.format(LootTracker.blueSharksSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.tigerSharksSession) + "\n" +
+ EnumChatFormatting.WHITE + nf.format(LootTracker.greatWhiteSharksSession);
+ break;
+ case "fishing_spooky":
+ dropsText = EnumChatFormatting.AQUA + "Creatures Caught:\n" +
+ EnumChatFormatting.AQUA + "Fishing Milestone:\n" +
+ EnumChatFormatting.GOLD + "Good Catches:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Great Catches:\n" +
+ EnumChatFormatting.BLUE + "Scarecrows:\n" +
+ EnumChatFormatting.GRAY + "Nightmares:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Werewolves:\n" +
+ EnumChatFormatting.GOLD + "Phantom Fishers:\n" +
+ EnumChatFormatting.GOLD + "Grim Reapers:";
+ countText = EnumChatFormatting.AQUA + nf.format(LootTracker.seaCreatures) + "\n" +
+ EnumChatFormatting.AQUA + nf.format(LootTracker.fishingMilestone) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.goodCatches) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.greatCatches) + "\n" +
+ EnumChatFormatting.BLUE + nf.format(LootTracker.scarecrows) + "\n" +
+ EnumChatFormatting.GRAY + nf.format(LootTracker.nightmares) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.werewolfs) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.phantomFishers) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.grimReapers);
+ break;
+ case "fishing_spooky_session":
+ dropsText = EnumChatFormatting.AQUA + "Creatures Caught:\n" +
+ EnumChatFormatting.AQUA + "Fishing Milestone:\n" +
+ EnumChatFormatting.GOLD + "Good Catches:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Great Catches:\n" +
+ EnumChatFormatting.BLUE + "Scarecrows:\n" +
+ EnumChatFormatting.GRAY + "Nightmares:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Werewolves:\n" +
+ EnumChatFormatting.GOLD + "Phantom Fishers:\n" +
+ EnumChatFormatting.GOLD + "Grim Reapers:";
+ countText = EnumChatFormatting.AQUA + nf.format(LootTracker.seaCreaturesSession) + "\n" +
+ EnumChatFormatting.AQUA + nf.format(LootTracker.fishingMilestoneSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.goodCatchesSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.greatCatchesSession) + "\n" +
+ EnumChatFormatting.BLUE + nf.format(LootTracker.scarecrowsSession) + "\n" +
+ EnumChatFormatting.GRAY + nf.format(LootTracker.nightmaresSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.werewolfsSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.phantomFishersSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.grimReapersSession);
+ break;
+ case "mythological":
+ dropsText = EnumChatFormatting.GOLD + "Coins:\n" +
+ EnumChatFormatting.WHITE + "Griffin Feathers:\n" +
+ EnumChatFormatting.GOLD + "Crown of Greeds:\n" +
+ EnumChatFormatting.AQUA + "Washed up Souvenirs:\n" +
+ EnumChatFormatting.RED + "Minos Hunters:\n" +
+ EnumChatFormatting.GRAY + "Siamese Lynxes:\n" +
+ EnumChatFormatting.RED + "Minotaurs:\n" +
+ EnumChatFormatting.WHITE + "Gaia Constructs:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Minos Champions:\n" +
+ EnumChatFormatting.GOLD + "Minos Inquisitors:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.mythCoins) + "\n" +
+ EnumChatFormatting.WHITE + nf.format(LootTracker.griffinFeathers) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.crownOfGreeds) + "\n" +
+ EnumChatFormatting.AQUA + nf.format(LootTracker.washedUpSouvenirs) + "\n" +
+ EnumChatFormatting.RED + nf.format(LootTracker.minosHunters) + "\n" +
+ EnumChatFormatting.GRAY + nf.format(LootTracker.siameseLynxes) + "\n" +
+ EnumChatFormatting.RED + nf.format(LootTracker.minotaurs) + "\n" +
+ EnumChatFormatting.WHITE + nf.format(LootTracker.gaiaConstructs) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.minosChampions) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.minosInquisitors);
+ break;
+ case "mythological_session":
+ dropsText = EnumChatFormatting.GOLD + "Coins:\n" +
+ EnumChatFormatting.WHITE + "Griffin Feathers:\n" +
+ EnumChatFormatting.GOLD + "Crown of Greeds:\n" +
+ EnumChatFormatting.AQUA + "Washed up Souvenirs:\n" +
+ EnumChatFormatting.RED + "Minos Hunters:\n" +
+ EnumChatFormatting.GRAY + "Siamese Lynxes:\n" +
+ EnumChatFormatting.RED + "Minotaurs:\n" +
+ EnumChatFormatting.WHITE + "Gaia Constructs:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Minos Champions:\n" +
+ EnumChatFormatting.GOLD + "Minos Inquisitors:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.mythCoinsSession) + "\n" +
+ EnumChatFormatting.WHITE + nf.format(LootTracker.griffinFeathersSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.crownOfGreedsSession) + "\n" +
+ EnumChatFormatting.AQUA + nf.format(LootTracker.washedUpSouvenirsSession) + "\n" +
+ EnumChatFormatting.RED + nf.format(LootTracker.minosHuntersSession) + "\n" +
+ EnumChatFormatting.GRAY + nf.format(LootTracker.siameseLynxesSession) + "\n" +
+ EnumChatFormatting.RED + nf.format(LootTracker.minotaursSession) + "\n" +
+ EnumChatFormatting.WHITE + nf.format(LootTracker.gaiaConstructsSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.minosChampionsSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.minosInquisitorsSession);
+ break;
+ case "catacombs_floor_one":
+ dropsText = EnumChatFormatting.GOLD + "Recombobulators:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Fuming Potato Books:\n" +
+ EnumChatFormatting.BLUE + "Bonzo's Staffs:\n" +
+ EnumChatFormatting.AQUA + "Coins Spent:\n" +
+ EnumChatFormatting.AQUA + "Time Spent:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.recombobulators) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.fumingPotatoBooks) + "\n" +
+ EnumChatFormatting.BLUE + nf.format(LootTracker.bonzoStaffs) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getMoneySpent(LootTracker.f1CoinsSpent) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getTimeBetween(0, LootTracker.f1TimeSpent);
+ break;
+ case "catacombs_floor_one_session":
+ dropsText = EnumChatFormatting.GOLD + "Recombobulators:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Fuming Potato Books:\n" +
+ EnumChatFormatting.BLUE + "Bonzo's Staffs:\n" +
+ EnumChatFormatting.AQUA + "Coins Spent:\n" +
+ EnumChatFormatting.AQUA + "Time Spent:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.recombobulatorsSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.fumingPotatoBooksSession) + "\n" +
+ EnumChatFormatting.BLUE + nf.format(LootTracker.bonzoStaffsSession) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getMoneySpent(LootTracker.f1CoinsSpentSession) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getTimeBetween(0, LootTracker.f1TimeSpentSession);
+ break;
+ case "catacombs_floor_two":
+ dropsText = EnumChatFormatting.GOLD + "Recombobulators:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Fuming Potato Books:\n" +
+ EnumChatFormatting.BLUE + "Scarf's Studies:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Adaptive Blades:\n" +
+ EnumChatFormatting.AQUA + "Coins Spent:\n" +
+ EnumChatFormatting.AQUA + "Time Spent:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.recombobulators) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.fumingPotatoBooks) + "\n" +
+ EnumChatFormatting.BLUE + nf.format(LootTracker.scarfStudies) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.adaptiveSwords) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getMoneySpent(LootTracker.f2CoinsSpent) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getTimeBetween(0, LootTracker.f2TimeSpent);
+ break;
+ case "catacombs_floor_two_session":
+ dropsText = EnumChatFormatting.GOLD + "Recombobulators:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Fuming Potato Books:\n" +
+ EnumChatFormatting.BLUE + "Scarf's Studies:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Adaptive Blades:\n" +
+ EnumChatFormatting.AQUA + "Coins Spent:\n" +
+ EnumChatFormatting.AQUA + "Time Spent:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.recombobulatorsSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.fumingPotatoBooksSession) + "\n" +
+ EnumChatFormatting.BLUE + nf.format(LootTracker.scarfStudiesSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.adaptiveSwordsSession) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getMoneySpent(LootTracker.f2CoinsSpentSession) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getTimeBetween(0, LootTracker.f2TimeSpentSession);
+ break;
+ case "catacombs_floor_three":
+ dropsText = EnumChatFormatting.GOLD + "Recombobulators:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Fuming Potato Books:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Adaptive Helmets:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Adaptive Chestplates:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Adaptive Leggings:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Adaptive Boots:\n" +
+ EnumChatFormatting.AQUA + "Coins Spent:\n" +
+ EnumChatFormatting.AQUA + "Time Spent:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.recombobulators) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.fumingPotatoBooks) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.adaptiveHelms) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.adaptiveChests) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.adaptiveLegs) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.adaptiveBoots) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getMoneySpent(LootTracker.f3CoinsSpent) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getTimeBetween(0, LootTracker.f3TimeSpent);
+ break;
+ case "catacombs_floor_three_session":
+ dropsText = EnumChatFormatting.GOLD + "Recombobulators:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Fuming Potato Books:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Adaptive Helmets:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Adaptive Chestplates:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Adaptive Leggings:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Adaptive Boots:\n" +
+ EnumChatFormatting.AQUA + "Coins Spent:\n" +
+ EnumChatFormatting.AQUA + "Time Spent:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.recombobulatorsSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.fumingPotatoBooksSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.adaptiveHelmsSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.adaptiveChestsSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.adaptiveLegsSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.adaptiveBootsSession) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getMoneySpent(LootTracker.f3CoinsSpentSession) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getTimeBetween(0, LootTracker.f3TimeSpentSession);
+ break;
+ case "catacombs_floor_four":
+ dropsText = EnumChatFormatting.GOLD + "Recombobulators:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Fuming Potato Books:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Spirit Wings:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Spirit Bones:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Spirit Boots:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Spirit Swords:\n" +
+ EnumChatFormatting.GOLD + "Spirit Bows:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Epic Spirit Pets:\n" +
+ EnumChatFormatting.GOLD + "Leg Spirit Pets:\n" +
+ EnumChatFormatting.AQUA + "Coins Spent:\n" +
+ EnumChatFormatting.AQUA + "Time Spent:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.recombobulators) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.fumingPotatoBooks) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.spiritWings) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.spiritBones) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.spiritBoots) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.spiritSwords) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.spiritBows) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.epicSpiritPets) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.legSpiritPets) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getMoneySpent(LootTracker.f4CoinsSpent) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getTimeBetween(0, LootTracker.f4TimeSpent);
+ break;
+ case "catacombs_floor_four_session":
+ dropsText = EnumChatFormatting.GOLD + "Recombobulators:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Fuming Potato Books:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Spirit Wings:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Spirit Bones:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Spirit Boots:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Spirit Swords:\n" +
+ EnumChatFormatting.GOLD + "Spirit Bows:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Epic Spirit Pets:\n" +
+ EnumChatFormatting.GOLD + "Leg Spirit Pets:\n" +
+ EnumChatFormatting.AQUA + "Coins Spent:\n" +
+ EnumChatFormatting.AQUA + "Time Spent:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.recombobulatorsSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.fumingPotatoBooksSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.spiritWingsSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.spiritBonesSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.spiritBootsSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.spiritSwordsSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.spiritBowsSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.epicSpiritPetsSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.legSpiritPetsSession) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getMoneySpent(LootTracker.f4CoinsSpentSession) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getTimeBetween(0, LootTracker.f4TimeSpentSession);
+ break;
+ case "catacombs_floor_five":
+ dropsText = EnumChatFormatting.GOLD + "Recombobulators:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Fuming Potato Books:\n" +
+ EnumChatFormatting.BLUE + "Warped Stones:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Shadow Helmets:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Shadow Chestplates:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Shadow Leggings:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Shadow Boots:\n" +
+ EnumChatFormatting.GOLD + "Last Breaths:\n" +
+ EnumChatFormatting.GOLD + "Livid Daggers:\n" +
+ EnumChatFormatting.GOLD + "Shadow Furys:\n" +
+ EnumChatFormatting.AQUA + "Coins Spent:\n" +
+ EnumChatFormatting.AQUA + "Time Spent:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.recombobulators) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.fumingPotatoBooks) + "\n" +
+ EnumChatFormatting.BLUE + nf.format(LootTracker.warpedStones) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.shadowAssHelms) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.shadowAssChests) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.shadowAssLegs) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.shadowAssBoots) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.lastBreaths) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.lividDaggers) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.shadowFurys) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getMoneySpent(LootTracker.f5CoinsSpent) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getTimeBetween(0, LootTracker.f5TimeSpent);
+ break;
+ case "catacombs_floor_five_session":
+ dropsText = EnumChatFormatting.GOLD + "Recombobulators:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Fuming Potato Books:\n" +
+ EnumChatFormatting.BLUE + "Warped Stones:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Shadow Helmets:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Shadow Chestplates:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Shadow Leggings:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Shadow Boots:\n" +
+ EnumChatFormatting.GOLD + "Last Breaths:\n" +
+ EnumChatFormatting.GOLD + "Livid Daggers:\n" +
+ EnumChatFormatting.GOLD + "Shadow Furys:\n" +
+ EnumChatFormatting.AQUA + "Coins Spent:\n" +
+ EnumChatFormatting.AQUA + "Time Spent:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.recombobulatorsSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.fumingPotatoBooksSession) + "\n" +
+ EnumChatFormatting.BLUE + nf.format(LootTracker.warpedStonesSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.shadowAssHelmsSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.shadowAssChestsSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.shadowAssLegsSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.shadowAssBootsSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.lastBreathsSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.lividDaggersSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.shadowFurysSession) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getMoneySpent(LootTracker.f5CoinsSpentSession) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getTimeBetween(0, LootTracker.f5TimeSpentSession);
+ break;
+ case "catacombs_floor_six":
+ dropsText = EnumChatFormatting.GOLD + "Recombobulators:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Fuming Potato Books:\n" +
+ EnumChatFormatting.BLUE + "Ancient Roses:\n" +
+ EnumChatFormatting.GOLD + "Precursor Eyes:\n" +
+ EnumChatFormatting.GOLD + "Giant's Swords:\n" +
+ EnumChatFormatting.GOLD + "Necro Lord Helmets:\n" +
+ EnumChatFormatting.GOLD + "Necro Lord Chests:\n" +
+ EnumChatFormatting.GOLD + "Necro Lord Leggings:\n" +
+ EnumChatFormatting.GOLD + "Necro Lord Boots:\n" +
+ EnumChatFormatting.GOLD + "Necro Swords:\n" +
+ EnumChatFormatting.AQUA + "Coins Spent:\n" +
+ EnumChatFormatting.AQUA + "Time Spent:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.recombobulators) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.fumingPotatoBooks) + "\n" +
+ EnumChatFormatting.BLUE + nf.format(LootTracker.ancientRoses) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.precursorEyes) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.giantsSwords) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.necroLordHelms) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.necroLordChests) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.necroLordLegs) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.necroLordBoots) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.necroSwords) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getMoneySpent(LootTracker.f6CoinsSpent) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getTimeBetween(0, LootTracker.f6TimeSpent);
+ break;
+ case "catacombs_floor_six_session":
+ dropsText = EnumChatFormatting.GOLD + "Recombobulators:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Fuming Potato Books:\n" +
+ EnumChatFormatting.BLUE + "Ancient Roses:\n" +
+ EnumChatFormatting.GOLD + "Precursor Eyes:\n" +
+ EnumChatFormatting.GOLD + "Giant's Swords:\n" +
+ EnumChatFormatting.GOLD + "Necro Lord Helmets:\n" +
+ EnumChatFormatting.GOLD + "Necro Lord Chests:\n" +
+ EnumChatFormatting.GOLD + "Necro Lord Leggings:\n" +
+ EnumChatFormatting.GOLD + "Necro Lord Boots:\n" +
+ EnumChatFormatting.GOLD + "Necro Swords:\n" +
+ EnumChatFormatting.AQUA + "Coins Spent:\n" +
+ EnumChatFormatting.AQUA + "Time Spent:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.recombobulatorsSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.fumingPotatoBooksSession) + "\n" +
+ EnumChatFormatting.BLUE + nf.format(LootTracker.ancientRosesSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.precursorEyesSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.giantsSwordsSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.necroLordHelmsSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.necroLordChestsSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.necroLordLegsSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.necroLordBootsSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.necroSwordsSession) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getMoneySpent(LootTracker.f6CoinsSpentSession) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getTimeBetween(0, LootTracker.f6TimeSpentSession);
+ break;
+ case "catacombs_floor_seven":
+ dropsText = EnumChatFormatting.GOLD + "Recombobulators:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Fuming Potato Books:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Wither Bloods:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Wither Cloaks:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Implosions:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Wither Shields:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Shadow Warps:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Necron's Handles:\n" +
+ EnumChatFormatting.GOLD + "Auto Recombobs:\n" +
+ EnumChatFormatting.GOLD + "Wither Helmets:\n" +
+ EnumChatFormatting.GOLD + "Wither Chests:\n" +
+ EnumChatFormatting.GOLD + "Wither Leggings:\n" +
+ EnumChatFormatting.GOLD + "Wither Boots:\n" +
+ EnumChatFormatting.AQUA + "Coins Spent:\n" +
+ EnumChatFormatting.AQUA + "Time Spent:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.recombobulators) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.fumingPotatoBooks) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.witherBloods) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.witherCloaks) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.implosions) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.witherShields) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.shadowWarps) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.necronsHandles) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.autoRecombs) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.witherHelms) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.witherChests) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.witherLegs) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.witherBoots) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getMoneySpent(LootTracker.f7CoinsSpent) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getTimeBetween(0, LootTracker.f7TimeSpent);
+ break;
+ case "catacombs_floor_seven_session":
+ dropsText = EnumChatFormatting.GOLD + "Recombobulators:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Fuming Potato Books:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Wither Bloods:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Wither Cloaks:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Implosions:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Wither Shields:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Shadow Warps:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Necron's Handles:\n" +
+ EnumChatFormatting.GOLD + "Auto Recombobulators:\n" +
+ EnumChatFormatting.GOLD + "Wither Helmets:\n" +
+ EnumChatFormatting.GOLD + "Wither Chests:\n" +
+ EnumChatFormatting.GOLD + "Wither Leggings:\n" +
+ EnumChatFormatting.GOLD + "Wither Boots:\n" +
+ EnumChatFormatting.AQUA + "Coins Spent:\n" +
+ EnumChatFormatting.AQUA + "Time Spent:";
+ countText = EnumChatFormatting.GOLD + nf.format(LootTracker.recombobulatorsSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.fumingPotatoBooksSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.witherBloodsSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.witherCloaksSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.implosionsSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.witherShieldsSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.shadowWarpsSession) + "\n" +
+ EnumChatFormatting.DARK_PURPLE + nf.format(LootTracker.necronsHandlesSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.autoRecombsSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.witherHelmsSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.witherChestsSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.witherLegsSession) + "\n" +
+ EnumChatFormatting.GOLD + nf.format(LootTracker.witherBootsSession) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getMoneySpent(LootTracker.f7CoinsSpentSession) + "\n" +
+ EnumChatFormatting.AQUA + Utils.getTimeBetween(0, LootTracker.f7TimeSpentSession);
+ break;
+ default:
+ System.out.println("Display was an unknown value, turning off.");
+ display = "off";
+ ConfigHandler.writeStringConfig("misc", "display", "off");
+ }
+ new TextRenderer(mc, dropsText, MoveCommand.displayXY[0], MoveCommand.displayXY[1], ScaleCommand.displayScale);
+ new TextRenderer(mc, countText, (int) (MoveCommand.displayXY[0] + (110 * ScaleCommand.displayScale)), MoveCommand.displayXY[1], ScaleCommand.displayScale);
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/loot/LootTracker.java b/src/main/java/me/Danker/features/loot/LootTracker.java
new file mode 100644
index 0000000..f7f7044
--- /dev/null
+++ b/src/main/java/me/Danker/features/loot/LootTracker.java
@@ -0,0 +1,1097 @@
+package me.Danker.features.loot;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.events.ChestSlotClickedEvent;
+import me.Danker.handlers.ConfigHandler;
+import me.Danker.handlers.ScoreboardHandler;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.client.event.sound.PlaySoundEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import java.util.List;
+
+public class LootTracker {
+
+ // Wolf
+ public static int wolfSvens;
+ public static int wolfTeeth;
+ public static int wolfWheels;
+ public static int wolfWheelsDrops;
+ public static int wolfSpirits;
+ public static int wolfBooks;
+ public static int wolfEggs;
+ public static int wolfCoutures;
+ public static int wolfBaits;
+ public static int wolfFluxes;
+ public static double wolfTime;
+ public static int wolfBosses;
+ // Spider
+ public static int spiderTarantulas;
+ public static int spiderWebs;
+ public static int spiderTAP;
+ public static int spiderTAPDrops;
+ public static int spiderBites;
+ public static int spiderCatalysts;
+ public static int spiderBooks;
+ public static int spiderSwatters;
+ public static int spiderTalismans;
+ public static int spiderMosquitos;
+ public static double spiderTime;
+ public static int spiderBosses;
+ // Zombie
+ public static int zombieRevs;
+ public static int zombieRevFlesh;
+ public static int zombieFoulFlesh;
+ public static int zombieFoulFleshDrops;
+ public static int zombiePestilences;
+ public static int zombieUndeadCatas;
+ public static int zombieBooks;
+ public static int zombieBeheadeds;
+ public static int zombieRevCatas;
+ public static int zombieSnakes;
+ public static int zombieScythes;
+ public static double zombieTime;
+ public static int zombieBosses;
+
+ // Fishing
+ public static int seaCreatures;
+ public static int goodCatches;
+ public static int greatCatches;
+ public static int squids;
+ public static int seaWalkers;
+ public static int nightSquids;
+ public static int seaGuardians;
+ public static int seaWitches;
+ public static int seaArchers;
+ public static int monsterOfTheDeeps;
+ public static int catfishes;
+ public static int carrotKings;
+ public static int seaLeeches;
+ public static int guardianDefenders;
+ public static int deepSeaProtectors;
+ public static int hydras;
+ public static int seaEmperors;
+ public static double empTime;
+ public static int empSCs;
+ public static int fishingMilestone;
+ // Fishing Winter
+ public static int frozenSteves;
+ public static int frostyTheSnowmans;
+ public static int grinches;
+ public static int yetis;
+ public static double yetiTime;
+ public static int yetiSCs;
+ // Fishing Festival
+ public static int nurseSharks;
+ public static int blueSharks;
+ public static int tigerSharks;
+ public static int greatWhiteSharks;
+ // Spooky Fishing
+ public static int scarecrows;
+ public static int nightmares;
+ public static int werewolfs;
+ public static int phantomFishers;
+ public static int grimReapers;
+
+ // Mythological
+ public static double mythCoins;
+ public static int griffinFeathers;
+ public static int crownOfGreeds;
+ public static int washedUpSouvenirs;
+ public static int minosHunters;
+ public static int siameseLynxes;
+ public static int minotaurs;
+ public static int gaiaConstructs;
+ public static int minosChampions;
+ public static int minosInquisitors;
+
+ // Catacombs Dungeons
+ public static int recombobulators;
+ public static int fumingPotatoBooks;
+ // F1
+ public static int bonzoStaffs;
+ public static double f1CoinsSpent;
+ public static double f1TimeSpent;
+ // F2
+ public static int scarfStudies;
+ public static int adaptiveSwords;
+ public static double f2CoinsSpent;
+ public static double f2TimeSpent;
+ // F3
+ public static int adaptiveHelms;
+ public static int adaptiveChests;
+ public static int adaptiveLegs;
+ public static int adaptiveBoots;
+ public static double f3CoinsSpent;
+ public static double f3TimeSpent;
+ // F4
+ public static int spiritWings;
+ public static int spiritBones;
+ public static int spiritBoots;
+ public static int spiritSwords;
+ public static int spiritBows;
+ public static int epicSpiritPets;
+ public static int legSpiritPets;
+ public static double f4CoinsSpent;
+ public static double f4TimeSpent;
+ // F5
+ public static int warpedStones;
+ public static int shadowAssHelms;
+ public static int shadowAssChests;
+ public static int shadowAssLegs;
+ public static int shadowAssBoots;
+ public static int lastBreaths;
+ public static int lividDaggers;
+ public static int shadowFurys;
+ public static double f5CoinsSpent;
+ public static double f5TimeSpent;
+ // F6
+ public static int ancientRoses;
+ public static int precursorEyes;
+ public static int giantsSwords;
+ public static int necroLordHelms;
+ public static int necroLordChests;
+ public static int necroLordLegs;
+ public static int necroLordBoots;
+ public static int necroSwords;
+ public static double f6CoinsSpent;
+ public static double f6TimeSpent;
+ // F7
+ public static int witherBloods;
+ public static int witherCloaks;
+ public static int implosions;
+ public static int witherShields;
+ public static int shadowWarps;
+ public static int necronsHandles;
+ public static int autoRecombs;
+ public static int witherHelms;
+ public static int witherChests;
+ public static int witherLegs;
+ public static int witherBoots;
+ public static double f7CoinsSpent;
+ public static double f7TimeSpent;
+
+ // Single sessions (No config saves)
+ // Wolf
+ public static int wolfSvensSession = 0;
+ public static int wolfTeethSession = 0;
+ public static int wolfWheelsSession = 0;
+ public static int wolfWheelsDropsSession = 0;
+ public static int wolfSpiritsSession = 0;
+ public static int wolfBooksSession = 0;
+ public static int wolfEggsSession = 0;
+ public static int wolfCouturesSession = 0;
+ public static int wolfBaitsSession = 0;
+ public static int wolfFluxesSession = 0;
+ public static double wolfTimeSession = -1;
+ public static int wolfBossesSession = -1;
+ // Spider
+ public static int spiderTarantulasSession = 0;
+ public static int spiderWebsSession = 0;
+ public static int spiderTAPSession = 0;
+ public static int spiderTAPDropsSession = 0;
+ public static int spiderBitesSession = 0;
+ public static int spiderCatalystsSession = 0;
+ public static int spiderBooksSession = 0;
+ public static int spiderSwattersSession = 0;
+ public static int spiderTalismansSession = 0;
+ public static int spiderMosquitosSession = 0;
+ public static double spiderTimeSession = -1;
+ public static int spiderBossesSession = -1;
+ // Zombie
+ public static int zombieRevsSession = 0;
+ public static int zombieRevFleshSession = 0;
+ public static int zombieFoulFleshSession = 0;
+ public static int zombieFoulFleshDropsSession = 0;
+ public static int zombiePestilencesSession = 0;
+ public static int zombieUndeadCatasSession = 0;
+ public static int zombieBooksSession = 0;
+ public static int zombieBeheadedsSession = 0;
+ public static int zombieRevCatasSession = 0;
+ public static int zombieSnakesSession = 0;
+ public static int zombieScythesSession = 0;
+ public static double zombieTimeSession = -1;
+ public static int zombieBossesSession = -1;
+
+ // Fishing
+ public static int seaCreaturesSession = 0;
+ public static int goodCatchesSession = 0;
+ public static int greatCatchesSession = 0;
+ public static int squidsSession = 0;
+ public static int seaWalkersSession = 0;
+ public static int nightSquidsSession = 0;
+ public static int seaGuardiansSession = 0;
+ public static int seaWitchesSession = 0;
+ public static int seaArchersSession = 0;
+ public static int monsterOfTheDeepsSession = 0;
+ public static int catfishesSession = 0;
+ public static int carrotKingsSession = 0;
+ public static int seaLeechesSession = 0;
+ public static int guardianDefendersSession = 0;
+ public static int deepSeaProtectorsSession = 0;
+ public static int hydrasSession = 0;
+ public static int seaEmperorsSession = 0;
+ public static double empTimeSession = -1;
+ public static int empSCsSession = -1;
+ public static int fishingMilestoneSession = 0;
+ // Fishing Winter
+ public static int frozenStevesSession = 0;
+ public static int frostyTheSnowmansSession = 0;
+ public static int grinchesSession = 0;
+ public static int yetisSession = 0;
+ public static double yetiTimeSession = -1;
+ public static int yetiSCsSession = -1;
+ // Fishing Festival
+ public static int nurseSharksSession = 0;
+ public static int blueSharksSession = 0;
+ public static int tigerSharksSession = 0;
+ public static int greatWhiteSharksSession = 0;
+ // Spooky Fishing
+ public static int scarecrowsSession = 0;
+ public static int nightmaresSession = 0;
+ public static int werewolfsSession = 0;
+ public static int phantomFishersSession = 0;
+ public static int grimReapersSession = 0;
+
+ // Mythological
+ public static double mythCoinsSession = 0;
+ public static int griffinFeathersSession = 0;
+ public static int crownOfGreedsSession = 0;
+ public static int washedUpSouvenirsSession = 0;
+ public static int minosHuntersSession = 0;
+ public static int siameseLynxesSession = 0;
+ public static int minotaursSession = 0;
+ public static int gaiaConstructsSession = 0;
+ public static int minosChampionsSession = 0;
+ public static int minosInquisitorsSession = 0;
+
+ // Catacombs Dungeons
+ public static int recombobulatorsSession = 0;
+ public static int fumingPotatoBooksSession = 0;
+ // F1
+ public static int bonzoStaffsSession = 0;
+ public static double f1CoinsSpentSession = 0;
+ public static double f1TimeSpentSession = 0;
+ // F2
+ public static int scarfStudiesSession = 0;
+ public static int adaptiveSwordsSession = 0;
+ public static double f2CoinsSpentSession = 0;
+ public static double f2TimeSpentSession = 0;
+ // F3
+ public static int adaptiveHelmsSession = 0;
+ public static int adaptiveChestsSession = 0;
+ public static int adaptiveLegsSession = 0;
+ public static int adaptiveBootsSession = 0;
+ public static double f3CoinsSpentSession = 0;
+ public static double f3TimeSpentSession = 0;
+ // F4
+ public static int spiritWingsSession = 0;
+ public static int spiritBonesSession = 0;
+ public static int spiritBootsSession = 0;
+ public static int spiritSwordsSession = 0;
+ public static int spiritBowsSession = 0;
+ public static int epicSpiritPetsSession = 0;
+ public static int legSpiritPetsSession = 0;
+ public static double f4CoinsSpentSession = 0;
+ public static double f4TimeSpentSession = 0;
+ // F5
+ public static int warpedStonesSession = 0;
+ public static int shadowAssHelmsSession = 0;
+ public static int shadowAssChestsSession = 0;
+ public static int shadowAssLegsSession = 0;
+ public static int shadowAssBootsSession = 0;
+ public static int lastBreathsSession = 0;
+ public static int lividDaggersSession = 0;
+ public static int shadowFurysSession = 0;
+ public static double f5CoinsSpentSession = 0;
+ public static double f5TimeSpentSession = 0;
+ // F6
+ public static int ancientRosesSession = 0;
+ public static int precursorEyesSession = 0;
+ public static int giantsSwordsSession = 0;
+ public static int necroLordHelmsSession = 0;
+ public static int necroLordChestsSession = 0;
+ public static int necroLordLegsSession = 0;
+ public static int necroLordBootsSession = 0;
+ public static int necroSwordsSession = 0;
+ public static double f6CoinsSpentSession = 0;
+ public static double f6TimeSpentSession = 0;
+ // F7
+ public static int witherBloodsSession = 0;
+ public static int witherCloaksSession = 0;
+ public static int implosionsSession = 0;
+ public static int witherShieldsSession = 0;
+ public static int shadowWarpsSession = 0;
+ public static int necronsHandlesSession = 0;
+ public static int autoRecombsSession = 0;
+ public static int witherHelmsSession = 0;
+ public static int witherChestsSession = 0;
+ public static int witherLegsSession = 0;
+ public static int witherBootsSession = 0;
+ public static double f7CoinsSpentSession = 0;
+ public static double f7TimeSpentSession = 0;
+
+ static double checkItemsNow = 0;
+ static double itemsChecked = 0;
+
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
+ public void onChat(ClientChatReceivedEvent event) {
+ String message = StringUtils.stripControlCodes(event.message.getUnformattedText());
+
+ if (!Utils.inSkyblock) return;
+ if (event.type == 2) return;
+ if (message.contains(":")) return;
+
+ boolean wolfRNG = false;
+ boolean spiderRNG = false;
+ boolean zombieRNG = false;
+
+ // Slayer tracker
+ // T6 books
+ if (message.contains("VERY RARE DROP! (Enchanted Book)") || message.contains("CRAZY RARE DROP! (Enchanted Book)")) {
+ // Loop through scoreboard to see what boss you're doing
+ List<String> scoreboard = ScoreboardHandler.getSidebarLines();
+ for (String s : scoreboard) {
+ String sCleaned = ScoreboardHandler.cleanSB(s);
+ if (sCleaned.contains("Sven Packmaster")) {
+ wolfBooks++;
+ ConfigHandler.writeIntConfig("wolf", "book", wolfBooks);
+ } else if (sCleaned.contains("Tarantula Broodfather")) {
+ spiderBooks++;
+ ConfigHandler.writeIntConfig("spider", "book", spiderBooks);
+ } else if (sCleaned.contains("Revenant Horror")) {
+ zombieBooks++;
+ ConfigHandler.writeIntConfig("zombie", "book", zombieBooks);
+ }
+ }
+ }
+
+ // Wolf
+ if (message.contains("Talk to Maddox to claim your Wolf Slayer XP!")) {
+ wolfSvens++;
+ wolfSvensSession++;
+ if (wolfBosses != -1) {
+ wolfBosses++;
+ }
+ if (wolfBossesSession != -1) {
+ wolfBossesSession++;
+ }
+ ConfigHandler.writeIntConfig("wolf", "svens", wolfSvens);
+ ConfigHandler.writeIntConfig("wolf", "bossRNG", wolfBosses);
+ } else if (message.contains("RARE DROP! (Hamster Wheel)")) {
+ wolfWheelsDrops++;
+ wolfWheelsDropsSession++;
+ ConfigHandler.writeIntConfig("wolf", "wheelDrops", wolfWheelsDrops);
+ } else if (message.contains("VERY RARE DROP! (") && message.contains(" Spirit Rune I)")) { // Removing the unicode here *should* fix rune drops not counting
+ wolfSpirits++;
+ wolfSpiritsSession++;
+ ConfigHandler.writeIntConfig("wolf", "spirit", wolfSpirits);
+ } else if (message.contains("CRAZY RARE DROP! (Red Claw Egg)")) {
+ wolfRNG = true;
+ wolfEggs++;
+ wolfEggsSession++;
+ ConfigHandler.writeIntConfig("wolf", "egg", wolfEggs);
+ if (ToggleCommand.rngesusAlerts) Utils.createTitle(EnumChatFormatting.DARK_RED + "RED CLAW EGG!", 3);
+ } else if (message.contains("CRAZY RARE DROP! (") && message.contains(" Couture Rune I)")) {
+ wolfRNG = true;
+ wolfCoutures++;
+ wolfCouturesSession++;
+ ConfigHandler.writeIntConfig("wolf", "couture", wolfCoutures);
+ if (ToggleCommand.rngesusAlerts) Utils.createTitle(EnumChatFormatting.GOLD + "COUTURE RUNE!", 3);
+ } else if (message.contains("CRAZY RARE DROP! (Grizzly Bait)") || message.contains("CRAZY RARE DROP! (Rename Me)")) { // How did Skyblock devs even manage to make this item Rename Me
+ wolfRNG = true;
+ wolfBaits++;
+ wolfBaitsSession++;
+ ConfigHandler.writeIntConfig("wolf", "bait", wolfBaits);
+ if (ToggleCommand.rngesusAlerts) Utils.createTitle(EnumChatFormatting.AQUA + "GRIZZLY BAIT!", 3);
+ } else if (message.contains("CRAZY RARE DROP! (Overflux Capacitor)")) {
+ wolfRNG = true;
+ wolfFluxes++;
+ wolfFluxesSession++;
+ ConfigHandler.writeIntConfig("wolf", "flux", wolfFluxes);
+ if (ToggleCommand.rngesusAlerts) Utils.createTitle(EnumChatFormatting.DARK_PURPLE + "OVERFLUX CAPACITOR!", 5);
+ } else if (message.contains("Talk to Maddox to claim your Spider Slayer XP!")) { // Spider
+ spiderTarantulas++;
+ spiderTarantulasSession++;
+ if (spiderBosses != -1) {
+ spiderBosses++;
+ }
+ if (spiderBossesSession != -1) {
+ spiderBossesSession++;
+ }
+ ConfigHandler.writeIntConfig("spider", "tarantulas", spiderTarantulas);
+ ConfigHandler.writeIntConfig("spider", "bossRNG", spiderBosses);
+ } else if (message.contains("RARE DROP! (Toxic Arrow Poison)")) {
+ spiderTAPDrops++;
+ spiderTAPDropsSession++;
+ ConfigHandler.writeIntConfig("spider", "tapDrops", spiderTAPDrops);
+ } else if (message.contains("VERY RARE DROP! (") && message.contains(" Bite Rune I)")) {
+ spiderBites++;
+ spiderBitesSession++;
+ ConfigHandler.writeIntConfig("spider", "bite", spiderBites);
+ } else if (message.contains("VERY RARE DROP! (Spider Catalyst)")) {
+ spiderCatalysts++;
+ spiderCatalystsSession++;
+ ConfigHandler.writeIntConfig("spider", "catalyst", spiderCatalysts);
+ } else if (message.contains("CRAZY RARE DROP! (Fly Swatter)")) {
+ spiderRNG = true;
+ spiderSwatters++;
+ spiderSwattersSession++;
+ ConfigHandler.writeIntConfig("spider", "swatter", spiderSwatters);
+ if (ToggleCommand.rngesusAlerts) Utils.createTitle(EnumChatFormatting.LIGHT_PURPLE + "FLY SWATTER!", 3);
+ } else if (message.contains("CRAZY RARE DROP! (Tarantula Talisman")) {
+ spiderRNG = true;
+ spiderTalismans++;
+ spiderTalismansSession++;
+ ConfigHandler.writeIntConfig("spider", "talisman", spiderTalismans);
+ if (ToggleCommand.rngesusAlerts) Utils.createTitle(EnumChatFormatting.DARK_PURPLE + "TARANTULA TALISMAN!", 3);
+ } else if (message.contains("CRAZY RARE DROP! (Digested Mosquito)")) {
+ spiderRNG = true;
+ spiderMosquitos++;
+ spiderMosquitosSession++;
+ ConfigHandler.writeIntConfig("spider", "mosquito", spiderMosquitos);
+ if (ToggleCommand.rngesusAlerts) Utils.createTitle(EnumChatFormatting.GOLD + "DIGESTED MOSQUITO!", 5);
+ } else if (message.contains("Talk to Maddox to claim your Zombie Slayer XP!")) { // Zombie
+ zombieRevs++;
+ zombieRevsSession++;
+ if (zombieBosses != -1) {
+ zombieBosses++;
+ }
+ if (zombieBossesSession != 1) {
+ zombieBossesSession++;
+ }
+ ConfigHandler.writeIntConfig("zombie", "revs", zombieRevs);
+ ConfigHandler.writeIntConfig("zombie", "bossRNG", zombieBosses);
+ } else if (message.contains("RARE DROP! (Foul Flesh)")) {
+ zombieFoulFleshDrops++;
+ zombieFoulFleshDropsSession++;
+ ConfigHandler.writeIntConfig("zombie", "foulFleshDrops", zombieFoulFleshDrops);
+ } else if (message.contains("VERY RARE DROP! (Revenant Catalyst)")) {
+ zombieRevCatas++;
+ zombieRevCatasSession++;
+ ConfigHandler.writeIntConfig("zombie", "revCatalyst", zombieRevCatas);
+ } else if (message.contains("VERY RARE DROP! (") && message.contains(" Pestilence Rune I)")) {
+ zombiePestilences++;
+ zombiePestilencesSession++;
+ ConfigHandler.writeIntConfig("zombie", "pestilence", zombiePestilences);
+ } else if (message.contains("VERY RARE DROP! (Undead Catalyst)")) {
+ zombieUndeadCatas++;
+ zombieUndeadCatasSession++;
+ ConfigHandler.writeIntConfig("zombie", "undeadCatalyst", zombieUndeadCatas);
+ } else if (message.contains("CRAZY RARE DROP! (Beheaded Horror)")) {
+ zombieRNG = true;
+ zombieBeheadeds++;
+ zombieBeheadedsSession++;
+ ConfigHandler.writeIntConfig("zombie", "beheaded", zombieBeheadeds);
+ if (ToggleCommand.rngesusAlerts) Utils.createTitle(EnumChatFormatting.DARK_PURPLE + "BEHEADED HORROR!", 3);
+ } else if (message.contains("CRAZY RARE DROP! (") && message.contains(" Snake Rune I)")) {
+ zombieRNG = true;
+ zombieSnakes++;
+ zombieSnakesSession++;
+ ConfigHandler.writeIntConfig("zombie", "snake", zombieSnakes);
+ if (ToggleCommand.rngesusAlerts) Utils.createTitle(EnumChatFormatting.DARK_GREEN + "SNAKE RUNE!", 3);
+ } else if (message.contains("CRAZY RARE DROP! (Scythe Blade)")) {
+ zombieRNG = true;
+ zombieScythes++;
+ zombieScythesSession++;
+ ConfigHandler.writeIntConfig("zombie", "scythe", zombieScythes);
+ if (ToggleCommand.rngesusAlerts) Utils.createTitle(EnumChatFormatting.GOLD + "SCYTHE BLADE!", 5);
+ }
+
+ if (wolfRNG) {
+ wolfTime = System.currentTimeMillis() / 1000;
+ wolfBosses = 0;
+ wolfTimeSession = System.currentTimeMillis() / 1000;
+ wolfBossesSession = 0;
+ ConfigHandler.writeDoubleConfig("wolf", "timeRNG", wolfTime);
+ ConfigHandler.writeIntConfig("wolf", "bossRNG", 0);
+ }
+ if (spiderRNG) {
+ spiderTime = System.currentTimeMillis() / 1000;
+ spiderBosses = 0;
+ spiderTimeSession = System.currentTimeMillis() / 1000;
+ spiderBossesSession = 0;
+ ConfigHandler.writeDoubleConfig("spider", "timeRNG", spiderTime);
+ ConfigHandler.writeIntConfig("spider", "bossRNG", 0);
+ }
+ if (zombieRNG) {
+ zombieTime = System.currentTimeMillis() / 1000;
+ zombieBosses = 0;
+ zombieTimeSession = System.currentTimeMillis() / 1000;
+ zombieBossesSession = 0;
+ ConfigHandler.writeDoubleConfig("zombie", "timeRNG", zombieTime);
+ ConfigHandler.writeIntConfig("zombie", "bossRNG", 0);
+ }
+
+ // Fishing tracker
+ if (message.contains("GOOD CATCH!")) {
+ goodCatches++;
+ goodCatchesSession++;
+ ConfigHandler.writeIntConfig("fishing", "goodCatch", goodCatches);
+ } else if (message.contains("GREAT CATCH!")) {
+ greatCatches++;
+ greatCatchesSession++;
+ ConfigHandler.writeIntConfig("fishing", "greatCatch", greatCatches);
+ } else if (message.contains("A Squid appeared")) {
+ squids++;
+ squidsSession++;
+ ConfigHandler.writeIntConfig("fishing", "squid", squids);
+ increaseSeaCreatures();
+ } else if (message.contains("You caught a Sea Walker")) {
+ seaWalkers++;
+ seaWalkersSession++;
+ ConfigHandler.writeIntConfig("fishing", "seaWalker", seaWalkers);
+ increaseSeaCreatures();
+ } else if (message.contains("Pitch darkness reveals a Night Squid")) {
+ nightSquids++;
+ nightSquidsSession++;
+ ConfigHandler.writeIntConfig("fishing", "nightSquid", nightSquids);
+ increaseSeaCreatures();
+ } else if (message.contains("You stumbled upon a Sea Guardian")) {
+ seaGuardians++;
+ seaGuardiansSession++;
+ ConfigHandler.writeIntConfig("fishing", "seaGuardian", seaGuardians);
+ increaseSeaCreatures();
+ } else if (message.contains("It looks like you've disrupted the Sea Witch's brewing session. Watch out, she's furious")) {
+ seaWitches++;
+ seaWitchesSession++;
+ ConfigHandler.writeIntConfig("fishing", "seaWitch", seaWitches);
+ increaseSeaCreatures();
+ } else if (message.contains("You reeled in a Sea Archer")) {
+ seaArchers++;
+ seaArchersSession++;
+ ConfigHandler.writeIntConfig("fishing", "seaArcher", seaArchers);
+ increaseSeaCreatures();
+ } else if (message.contains("The Monster of the Deep has emerged")) {
+ monsterOfTheDeeps++;
+ monsterOfTheDeepsSession++;
+ ConfigHandler.writeIntConfig("fishing", "monsterOfDeep", monsterOfTheDeeps);
+ increaseSeaCreatures();
+ } else if (message.contains("Huh? A Catfish")) {
+ catfishes++;
+ catfishesSession++;
+ ConfigHandler.writeIntConfig("fishing", "catfish", catfishes);
+ increaseSeaCreatures();
+ } else if (message.contains("Is this even a fish? It's the Carrot King")) {
+ carrotKings++;
+ carrotKingsSession++;
+ ConfigHandler.writeIntConfig("fishing", "carrotKing", carrotKings);
+ increaseSeaCreatures();
+ } else if (message.contains("Gross! A Sea Leech")) {
+ seaLeeches++;
+ seaLeechesSession++;
+ ConfigHandler.writeIntConfig("fishing", "seaLeech", seaLeeches);
+ increaseSeaCreatures();
+ } else if (message.contains("You've discovered a Guardian Defender of the sea")) {
+ guardianDefenders++;
+ guardianDefendersSession++;
+ ConfigHandler.writeIntConfig("fishing", "guardianDefender", guardianDefenders);
+ increaseSeaCreatures();
+ } else if (message.contains("You have awoken the Deep Sea Protector, prepare for a battle")) {
+ deepSeaProtectors++;
+ deepSeaProtectorsSession++;
+ ConfigHandler.writeIntConfig("fishing", "deepSeaProtector", deepSeaProtectors);
+ increaseSeaCreatures();
+ } else if (message.contains("The Water Hydra has come to test your strength")) {
+ hydras++;
+ hydrasSession++;
+ ConfigHandler.writeIntConfig("fishing", "hydra", hydras);
+ increaseSeaCreatures();
+ } else if (message.contains("The Sea Emperor arises from the depths")) {
+ increaseSeaCreatures();
+
+ seaEmperors++;
+ empTime = System.currentTimeMillis() / 1000;
+ empSCs = 0;
+ seaEmperorsSession++;
+ empTimeSession = System.currentTimeMillis() / 1000;
+ empSCsSession = 0;
+ ConfigHandler.writeIntConfig("fishing", "seaEmperor", seaEmperors);
+ ConfigHandler.writeDoubleConfig("fishing", "empTime", empTime);
+ ConfigHandler.writeIntConfig("fishing", "empSC", empSCs);
+ } else if (message.contains("Frozen Steve fell into the pond long ago")) { // Fishing Winter
+ frozenSteves++;
+ frozenStevesSession++;
+ ConfigHandler.writeIntConfig("fishing", "frozenSteve", frozenSteves);
+ increaseSeaCreatures();
+ } else if (message.contains("It's a snowman! He looks harmless")) {
+ frostyTheSnowmans++;
+ frostyTheSnowmansSession++;
+ ConfigHandler.writeIntConfig("fishing", "snowman", frostyTheSnowmans);
+ increaseSeaCreatures();
+ } else if (message.contains("stole Jerry's Gifts...get them back")) {
+ grinches++;
+ grinchesSession++;
+ ConfigHandler.writeIntConfig("fishing", "grinch", grinches);
+ increaseSeaCreatures();
+ } else if (message.contains("What is this creature")) {
+ yetis++;
+ yetiTime = System.currentTimeMillis() / 1000;
+ yetiSCs = 0;
+ yetisSession++;
+ yetiTimeSession = System.currentTimeMillis() / 1000;
+ yetiSCsSession = 0;
+ ConfigHandler.writeIntConfig("fishing", "yeti", yetis);
+ ConfigHandler.writeDoubleConfig("fishing", "yetiTime", yetiTime);
+ ConfigHandler.writeIntConfig("fishing", "yetiSC", yetiSCs);
+ increaseSeaCreatures();
+ } else if (message.contains("A tiny fin emerges from the water, you've caught a Nurse Shark")) { // Fishing Festival
+ nurseSharks++;
+ nurseSharksSession++;
+ ConfigHandler.writeIntConfig("fishing", "nurseShark", nurseSharks);
+ increaseSeaCreatures();
+ } else if (message.contains("You spot a fin as blue as the water it came from, it's a Blue Shark")) {
+ blueSharks++;
+ blueSharksSession++;
+ ConfigHandler.writeIntConfig("fishing", "blueShark", blueSharks);
+ increaseSeaCreatures();
+ } else if (message.contains("A striped beast bounds from the depths, the wild Tiger Shark")) {
+ tigerSharks++;
+ tigerSharksSession++;
+ ConfigHandler.writeIntConfig("fishing", "tigerShark", tigerSharks);
+ increaseSeaCreatures();
+ } else if (message.contains("Hide no longer, a Great White Shark has tracked your scent and thirsts for your blood")) {
+ greatWhiteSharks++;
+ greatWhiteSharksSession++;
+ ConfigHandler.writeIntConfig("fishing", "greatWhiteShark", greatWhiteSharks);
+ increaseSeaCreatures();
+ } else if (message.contains("Phew! It's only a Scarecrow")) {
+ scarecrows++;
+ scarecrowsSession++;
+ ConfigHandler.writeIntConfig("fishing", "scarecrow", scarecrows);
+ increaseSeaCreatures();
+ } else if (message.contains("You hear trotting from beneath the waves, you caught a Nightmare")) {
+ nightmares++;
+ nightmaresSession++;
+ ConfigHandler.writeIntConfig("fishing", "nightmare", nightmares);
+ increaseSeaCreatures();
+ } else if (message.contains("It must be a full moon, a Werewolf appears")) {
+ werewolfs++;
+ werewolfsSession++;
+ ConfigHandler.writeIntConfig("fishing", "werewolf", werewolfs);
+ increaseSeaCreatures();
+ } else if (message.contains("The spirit of a long lost Phantom Fisher has come to haunt you")) {
+ phantomFishers++;
+ phantomFishersSession++;
+ ConfigHandler.writeIntConfig("fishing", "phantomFisher", phantomFishers);
+ increaseSeaCreatures();
+ } else if (message.contains("This can't be! The manifestation of death himself")) {
+ grimReapers++;
+ grimReapersSession++;
+ ConfigHandler.writeIntConfig("fishing", "grimReaper", grimReapers);
+ increaseSeaCreatures();
+ }
+
+ // Dungeons tracker
+ if (message.contains(" ")) {
+ if (message.contains("Recombobulator 3000")) {
+ recombobulators++;
+ recombobulatorsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "recombobulator", recombobulators);
+ } else if (message.contains("Fuming Potato Book")) {
+ fumingPotatoBooks++;
+ fumingPotatoBooksSession++;
+ ConfigHandler.writeIntConfig("catacombs", "fumingBooks", fumingPotatoBooks);
+ } else if (message.contains("Bonzo's Staff")) { // F1
+ bonzoStaffs++;
+ bonzoStaffsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "bonzoStaff", bonzoStaffs);
+ } else if (message.contains("Scarf's Studies")) { // F2
+ scarfStudies++;
+ scarfStudiesSession++;
+ ConfigHandler.writeIntConfig("catacombs", "scarfStudies", scarfStudies);
+ } else if (message.contains("Adaptive Helmet")) { // F3
+ adaptiveHelms++;
+ adaptiveHelmsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "adaptiveHelm", adaptiveHelms);
+ } else if (message.contains("Adaptive Chestplate")) {
+ adaptiveChests++;
+ adaptiveChestsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "adaptiveChest", adaptiveChests);
+ } else if (message.contains("Adaptive Leggings")) {
+ adaptiveLegs++;
+ adaptiveLegsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "adaptiveLegging", adaptiveLegs);
+ } else if (message.contains("Adaptive Boots")) {
+ adaptiveBoots++;
+ adaptiveBootsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "adaptiveBoot", adaptiveBoots);
+ } else if (message.contains("Adaptive Blade")) {
+ adaptiveSwords++;
+ adaptiveSwordsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "adaptiveSword", adaptiveSwords);
+ } else if (message.contains("Spirit Wing")) { // F4
+ spiritWings++;
+ spiritWingsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "spiritWing", spiritWings);
+ } else if (message.contains("Spirit Bone")) {
+ spiritBones++;
+ spiritBonesSession++;
+ ConfigHandler.writeIntConfig("catacombs", "spiritBone", spiritBones);
+ } else if (message.contains("Spirit Boots")) {
+ spiritBoots++;
+ spiritBootsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "spiritBoot", spiritBoots);
+ } else if (message.contains("[Lvl 1] Spirit")) {
+ String formattedMessage = event.message.getFormattedText();
+ // Unicode colour code messes up here, just gonna remove the symbols
+ if (formattedMessage.contains("5Spirit")) {
+ epicSpiritPets++;
+ epicSpiritPetsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "spiritPetEpic", epicSpiritPets);
+ } else if (formattedMessage.contains("6Spirit")) {
+ legSpiritPets++;
+ legSpiritPetsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "spiritPetLeg", legSpiritPets);
+ }
+ } else if (message.contains("Spirit Sword")) {
+ spiritSwords++;
+ spiritSwordsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "spiritSword", spiritSwords);
+ } else if (message.contains("Spirit Bow")) {
+ spiritBows++;
+ spiritBowsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "spiritBow", spiritBows);
+ } else if (message.contains("Warped Stone")) { // F5
+ warpedStones++;
+ warpedStonesSession++;
+ ConfigHandler.writeIntConfig("catacombs", "warpedStone", warpedStones);
+ } else if (message.contains("Shadow Assassin Helmet")) {
+ shadowAssHelms++;
+ shadowAssHelmsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "shadowAssassinHelm", shadowAssHelms);
+ } else if (message.contains("Shadow Assassin Chestplate")) {
+ shadowAssChests++;
+ shadowAssChestsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "shadowAssassinChest", shadowAssChests);
+ } else if (message.contains("Shadow Assassin Leggings")) {
+ shadowAssLegs++;
+ shadowAssLegsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "shadowAssassinLegging", shadowAssLegs);
+ } else if (message.contains("Shadow Assassin Boots")) {
+ shadowAssBoots++;
+ shadowAssBootsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "shadowAssassinBoot", shadowAssBoots);
+ } else if (message.contains("Livid Dagger")) {
+ lividDaggers++;
+ lividDaggersSession++;
+ ConfigHandler.writeIntConfig("catacombs", "lividDagger", lividDaggers);
+ } else if (message.contains("Shadow Fury")) {
+ shadowFurys++;
+ shadowFurysSession++;
+ ConfigHandler.writeIntConfig("catacombs", "shadowFury", shadowFurys);
+ } else if (message.contains("Ancient Rose")) { // F6
+ ancientRoses++;
+ ancientRosesSession++;
+ ConfigHandler.writeIntConfig("catacombs", "ancientRose", ancientRoses);
+ } else if (message.contains("Precursor Eye")) {
+ precursorEyes++;
+ precursorEyesSession++;
+ ConfigHandler.writeIntConfig("catacombs", "precursorEye", precursorEyes);
+ } else if (message.contains("Giant's Sword")) {
+ giantsSwords++;
+ giantsSwordsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "giantsSword", giantsSwords);
+ } else if (message.contains("Necromancer Lord Helmet")) {
+ necroLordHelms++;
+ necroLordHelmsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "necroLordHelm", necroLordHelms);
+ } else if (message.contains("Necromancer Lord Chestplate")) {
+ necroLordChests++;
+ necroLordChestsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "necroLordChest", necroLordChests);
+ } else if (message.contains("Necromancer Lord Leggings")) {
+ necroLordLegs++;
+ necroLordLegsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "necroLordLegging", necroLordLegs);
+ } else if (message.contains("Necromancer Lord Boots")) {
+ necroLordBoots++;
+ necroLordBootsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "necroLordBoot", necroLordBoots);
+ } else if (message.contains("Necromancer Sword")) {
+ necroSwords++;
+ necroSwordsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "necroSword", necroSwords);
+ } else if (message.contains("Wither Blood")) { // F7
+ witherBloods++;
+ witherBloodsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "witherBlood", witherBloods);
+ } else if (message.contains("Wither Cloak")) {
+ witherCloaks++;
+ witherCloaksSession++;
+ ConfigHandler.writeIntConfig("catacombs", "witherCloak", witherCloaks);
+ } else if (message.contains("Implosion")) {
+ implosions++;
+ implosionsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "implosion", implosions);
+ } else if (message.contains("Wither Shield")) {
+ witherShields++;
+ witherShieldsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "witherShield", witherShields);
+ } else if (message.contains("Shadow Warp")) {
+ shadowWarps++;
+ shadowWarpsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "shadowWarp", shadowWarps);
+ } else if (message.contains("Necron's Handle")) {
+ necronsHandles++;
+ necronsHandlesSession++;
+ ConfigHandler.writeIntConfig("catacombs", "necronsHandle", necronsHandles);
+ } else if (message.contains("Auto Recombobulator")) {
+ autoRecombs++;
+ autoRecombsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "autoRecomb", autoRecombs);
+ } else if (message.contains("Wither Helmet")) {
+ witherHelms++;
+ witherHelmsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "witherHelm", witherHelms);
+ } else if (message.contains("Wither Chestplate")) {
+ witherChests++;
+ witherChestsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "witherChest", witherChests);
+ } else if (message.contains("Wither Leggings")) {
+ witherLegs++;
+ witherLegsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "witherLegging", witherLegs);
+ } else if (message.contains("Wither Boots")) {
+ witherBoots++;
+ witherBootsSession++;
+ ConfigHandler.writeIntConfig("catacombs", "witherBoot", witherBoots);
+ }
+ }
+
+ if (message.contains("EXTRA STATS ")) {
+ List<String> scoreboard = ScoreboardHandler.getSidebarLines();
+ int timeToAdd = 0;
+ for (String s : scoreboard) {
+ String sCleaned = ScoreboardHandler.cleanSB(s);
+ if (sCleaned.contains("The Catacombs (")) {
+ // Add time to floor
+ if (sCleaned.contains("F1")) {
+ f1TimeSpent = Math.floor(f1TimeSpent + timeToAdd);
+ f1TimeSpentSession = Math.floor(f1TimeSpentSession + timeToAdd);
+ ConfigHandler.writeDoubleConfig("catacombs", "floorOneTime", f1TimeSpent);
+ } else if (sCleaned.contains("F2")) {
+ f2TimeSpent = Math.floor(f2TimeSpent + timeToAdd);
+ f2TimeSpentSession = Math.floor(f2TimeSpentSession + timeToAdd);
+ ConfigHandler.writeDoubleConfig("catacombs", "floorTwoTime", f2TimeSpent);
+ } else if (sCleaned.contains("F3")) {
+ f3TimeSpent = Math.floor(f3TimeSpent + timeToAdd);
+ f3TimeSpentSession = Math.floor(f3TimeSpentSession + timeToAdd);
+ ConfigHandler.writeDoubleConfig("catacombs", "floorThreeTime", f3TimeSpent);
+ } else if (sCleaned.contains("F4")) {
+ f4TimeSpent = Math.floor(f4TimeSpent + timeToAdd);
+ f4TimeSpentSession = Math.floor(f4TimeSpentSession + timeToAdd);
+ ConfigHandler.writeDoubleConfig("catacombs", "floorFourTime", f4TimeSpent);
+ } else if (sCleaned.contains("F5")) {
+ f5TimeSpent = Math.floor(f5TimeSpent + timeToAdd);
+ f5TimeSpentSession = Math.floor(f5TimeSpentSession + timeToAdd);
+ ConfigHandler.writeDoubleConfig("catacombs", "floorFiveTime", f5TimeSpent);
+ } else if (sCleaned.contains("F6")) {
+ f6TimeSpent = Math.floor(f6TimeSpent + timeToAdd);
+ f6TimeSpentSession = Math.floor(f6TimeSpentSession + timeToAdd);
+ ConfigHandler.writeDoubleConfig("catacombs", "floorSixTime", f6TimeSpent);
+ } else if (sCleaned.contains("F7")) {
+ f7TimeSpent = Math.floor(f7TimeSpent + timeToAdd);
+ f7TimeSpentSession = Math.floor(f7TimeSpentSession + timeToAdd);
+ ConfigHandler.writeDoubleConfig("catacombs", "floorSevenTime", f7TimeSpent);
+ }
+ } else if (sCleaned.contains("Time Elapsed:")) {
+ // Get floor time
+ String time = sCleaned.substring(sCleaned.indexOf(":") + 2);
+ time = time.replaceAll("\\s", "");
+ int minutes = Integer.parseInt(time.substring(0, time.indexOf("m")));
+ int seconds = Integer.parseInt(time.substring(time.indexOf("m") + 1, time.indexOf("s")));
+ timeToAdd = (minutes * 60) + seconds;
+ }
+ }
+ }
+
+ // Mythological Tracker
+ if (message.contains("You dug out")) {
+ if (message.contains(" coins!")) {
+ double coinsEarned = Double.parseDouble(message.replaceAll("[^\\d]", ""));
+ mythCoins += coinsEarned;
+ mythCoinsSession += coinsEarned;
+ ConfigHandler.writeDoubleConfig("mythological", "coins", mythCoins);
+ } else if (message.contains("a Griffin Feather!")) {
+ griffinFeathers++;
+ griffinFeathersSession++;
+ ConfigHandler.writeIntConfig("mythological", "griffinFeather", griffinFeathers);
+ } else if (message.contains("a Crown of Greed!")) {
+ crownOfGreeds++;
+ crownOfGreedsSession++;
+ ConfigHandler.writeIntConfig("mythological", "crownOfGreed", crownOfGreeds);
+ } else if (message.contains("a Washed-up Souvenir!")) {
+ washedUpSouvenirs++;
+ washedUpSouvenirsSession++;
+ ConfigHandler.writeIntConfig("mythological", "washedUpSouvenir", washedUpSouvenirs);
+ } else if (message.contains("a Minos Hunter!")) {
+ minosHunters++;
+ minosHuntersSession++;
+ ConfigHandler.writeIntConfig("mythological", "minosHunter", minosHunters);
+ } else if (message.contains("Siamese Lynxes!")) {
+ siameseLynxes++;
+ siameseLynxesSession++;
+ ConfigHandler.writeIntConfig("mythological", "siameseLynx", siameseLynxes);
+ } else if (message.contains("a Minotaur!")) {
+ minotaurs++;
+ minotaursSession++;
+ ConfigHandler.writeIntConfig("mythological", "minotaur", minotaurs);
+ } else if (message.contains("a Gaia Construct!")) {
+ gaiaConstructs++;
+ gaiaConstructsSession++;
+ ConfigHandler.writeIntConfig("mythological", "gaiaConstruct", gaiaConstructs);
+ } else if (message.contains("a Minos Champion!")) {
+ minosChampions++;
+ minosChampionsSession++;
+ ConfigHandler.writeIntConfig("mythological", "minosChampion", minosChampions);
+ } else if (message.contains("a Minos Inquisitor!")) {
+ minosInquisitors++;
+ minosInquisitorsSession++;
+ ConfigHandler.writeIntConfig("mythological", "minosInquisitor", minosInquisitors);
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onSlotClick(ChestSlotClickedEvent event) {
+ ItemStack item = event.item;
+
+ if (event.inventoryName.endsWith(" Chest") && item != null && item.getDisplayName().contains("Open Reward Chest")) {
+ List<String> tooltip = item.getTooltip(Minecraft.getMinecraft().thePlayer, Minecraft.getMinecraft().gameSettings.advancedItemTooltips);
+ for (String lineUnclean : tooltip) {
+ String line = StringUtils.stripControlCodes(lineUnclean);
+ if (line.contains("FREE")) {
+ break;
+ } else if (line.contains(" Coins")) {
+ int coinsSpent = Integer.parseInt(line.substring(0, line.indexOf(" ")).replaceAll(",", ""));
+
+ List<String> scoreboard = ScoreboardHandler.getSidebarLines();
+ for (String s : scoreboard) {
+ String sCleaned = ScoreboardHandler.cleanSB(s);
+ if (sCleaned.contains("The Catacombs (")) {
+ if (sCleaned.contains("F1")) {
+ f1CoinsSpent += coinsSpent;
+ f1CoinsSpentSession += coinsSpent;
+ ConfigHandler.writeDoubleConfig("catacombs", "floorOneCoins", f1CoinsSpent);
+ } else if (sCleaned.contains("F2")) {
+ f2CoinsSpent += coinsSpent;
+ f2CoinsSpentSession += coinsSpent;
+ ConfigHandler.writeDoubleConfig("catacombs", "floorTwoCoins", f2CoinsSpent);
+ } else if (sCleaned.contains("F3")) {
+ f3CoinsSpent += coinsSpent;
+ f3CoinsSpentSession += coinsSpent;
+ ConfigHandler.writeDoubleConfig("catacombs", "floorThreeCoins", f3CoinsSpent);
+ } else if (sCleaned.contains("F4")) {
+ f4CoinsSpent += coinsSpent;
+ f4CoinsSpentSession += coinsSpent;
+ ConfigHandler.writeDoubleConfig("catacombs", "floorFourCoins", f4CoinsSpent);
+ } else if (sCleaned.contains("F5")) {
+ f5CoinsSpent += coinsSpent;
+ f5CoinsSpentSession += coinsSpent;
+ ConfigHandler.writeDoubleConfig("catacombs", "floorFiveCoins", f5CoinsSpent);
+ } else if (sCleaned.contains("F6")) {
+ f6CoinsSpent += coinsSpent;
+ f6CoinsSpentSession += coinsSpent;
+ ConfigHandler.writeDoubleConfig("catacombs", "floorSixCoins", f6CoinsSpent);
+ } else if (sCleaned.contains("F7")) {
+ f7CoinsSpent += coinsSpent;
+ f7CoinsSpentSession += coinsSpent;
+ ConfigHandler.writeDoubleConfig("catacombs", "floorSevenCoins", f7CoinsSpent);
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
+ public void onSound(PlaySoundEvent event) {
+ if (!Utils.inSkyblock) return;
+ if (event.name.equals("note.pling")) {
+ // Don't check twice within 3 seconds
+ checkItemsNow = System.currentTimeMillis() / 1000;
+ if (checkItemsNow - itemsChecked < 3) return;
+
+ List<String> scoreboard = ScoreboardHandler.getSidebarLines();
+
+ for (String line : scoreboard) {
+ String cleanedLine = ScoreboardHandler.cleanSB(line);
+ // If Hypixel lags and scoreboard doesn't update
+ if (cleanedLine.contains("Boss slain!") || cleanedLine.contains("Slay the boss!")) {
+ int itemTeeth = Utils.getItems("Wolf Tooth");
+ int itemWheels = Utils.getItems("Hamster Wheel");
+ int itemWebs = Utils.getItems("Tarantula Web");
+ int itemTAP = Utils.getItems("Toxic Arrow Poison");
+ int itemRev = Utils.getItems("Revenant Flesh");
+ int itemFoul = Utils.getItems("Foul Flesh");
+
+ // If no items, are detected, allow check again. Should fix items not being found
+ if (itemTeeth + itemWheels + itemWebs + itemTAP + itemRev + itemFoul > 0) {
+ itemsChecked = System.currentTimeMillis() / 1000;
+ wolfTeeth += itemTeeth;
+ wolfWheels += itemWheels;
+ spiderWebs += itemWebs;
+ spiderTAP += itemTAP;
+ zombieRevFlesh += itemRev;
+ zombieFoulFlesh += itemFoul;
+ wolfTeethSession += itemTeeth;
+ wolfWheelsSession += itemWheels;
+ spiderWebsSession += itemWebs;
+ spiderTAPSession += itemTAP;
+ zombieRevFleshSession += itemRev;
+ zombieFoulFleshSession += itemFoul;
+
+ ConfigHandler.writeIntConfig("wolf", "teeth", wolfTeeth);
+ ConfigHandler.writeIntConfig("wolf", "wheel", wolfWheels);
+ ConfigHandler.writeIntConfig("spider", "web", spiderWebs);
+ ConfigHandler.writeIntConfig("spider", "tap", spiderTAP);
+ ConfigHandler.writeIntConfig("zombie", "revFlesh", zombieRevFlesh);
+ ConfigHandler.writeIntConfig("zombie", "foulFlesh", zombieFoulFlesh);
+ }
+ }
+ }
+ }
+ }
+
+ public void increaseSeaCreatures() {
+ if (empSCs != -1) {
+ empSCs++;
+ }
+ if (empSCsSession != -1) {
+ empSCsSession++;
+ }
+ // Only increment Yetis when in Jerry's Workshop
+ List<String> scoreboard = ScoreboardHandler.getSidebarLines();
+ for (String s : scoreboard) {
+ String sCleaned = ScoreboardHandler.cleanSB(s);
+ if (sCleaned.contains("Jerry's Workshop") || sCleaned.contains("Jerry Pond")) {
+ if (yetiSCs != -1) {
+ yetiSCs++;
+ }
+ if (yetiSCsSession != -1) {
+ yetiSCsSession++;
+ }
+ }
+ }
+
+ seaCreatures++;
+ fishingMilestone++;
+ seaCreaturesSession++;
+ fishingMilestoneSession++;
+ ConfigHandler.writeIntConfig("fishing", "seaCreature", seaCreatures);
+ ConfigHandler.writeIntConfig("fishing", "milestone", fishingMilestone);
+ ConfigHandler.writeIntConfig("fishing", "empSC", empSCs);
+ ConfigHandler.writeIntConfig("fishing", "yetiSC", yetiSCs);
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/puzzlesolvers/ArrowTerminalSolver.java b/src/main/java/me/Danker/features/puzzlesolvers/ArrowTerminalSolver.java
new file mode 100644
index 0000000..35458f3
--- /dev/null
+++ b/src/main/java/me/Danker/features/puzzlesolvers/ArrowTerminalSolver.java
@@ -0,0 +1,32 @@
+package me.Danker.features.puzzlesolvers;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.entity.item.EntityItemFrame;
+import net.minecraft.init.Blocks;
+import net.minecraft.init.Items;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.BlockPos;
+import net.minecraftforge.event.entity.player.EntityInteractEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+public class ArrowTerminalSolver {
+
+ @SubscribeEvent
+ public void onEntityInteract(EntityInteractEvent event) {
+ Minecraft mc = Minecraft.getMinecraft();
+ if (mc.thePlayer != event.entityPlayer) return;
+
+ if (ToggleCommand.itemFrameOnSeaLanternsToggled && Utils.inDungeons && event.target instanceof EntityItemFrame) {
+ EntityItemFrame itemFrame = (EntityItemFrame) event.target;
+ ItemStack item = itemFrame.getDisplayedItem();
+ if (item == null || item.getItem() != Items.arrow) return;
+ BlockPos blockPos = Utils.getBlockUnderItemFrame(itemFrame);
+ if (mc.theWorld.getBlockState(blockPos).getBlock() == Blocks.sea_lantern) {
+ event.setCanceled(true);
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/puzzlesolvers/BlazeSolver.java b/src/main/java/me/Danker/features/puzzlesolvers/BlazeSolver.java
new file mode 100644
index 0000000..0910fc7
--- /dev/null
+++ b/src/main/java/me/Danker/features/puzzlesolvers/BlazeSolver.java
@@ -0,0 +1,86 @@
+package me.Danker.features.puzzlesolvers;
+
+import me.Danker.DankersSkyblockMod;
+import me.Danker.commands.ToggleCommand;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.entity.Entity;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.util.BlockPos;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StringUtils;
+import net.minecraft.world.World;
+import net.minecraftforge.client.event.RenderWorldLastEvent;
+import net.minecraftforge.event.world.WorldEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+
+import java.util.List;
+
+public class BlazeSolver {
+
+ static Entity highestBlaze = null;
+ static Entity lowestBlaze = null;
+ public static int LOWEST_BLAZE_COLOUR;
+ public static int HIGHEST_BLAZE_COLOUR;
+
+ @SubscribeEvent
+ public void onWorldChange(WorldEvent.Load event) {
+ lowestBlaze = null;
+ highestBlaze = null;
+ }
+
+ @SubscribeEvent
+ public void onTick(TickEvent.ClientTickEvent event) {
+ if (event.phase != TickEvent.Phase.START) return;
+
+ World world = Minecraft.getMinecraft().theWorld;
+ if (DankersSkyblockMod.tickAmount % 4 == 0) {
+ if (ToggleCommand.blazeToggled && Utils.inDungeons && world != null) {
+ List<Entity> entities = world.getLoadedEntityList();
+ int highestHealth = 0;
+ highestBlaze = null;
+ int lowestHealth = 99999999;
+ lowestBlaze = null;
+
+ for (Entity entity : entities) {
+ if (entity.getName().contains("Blaze") && entity.getName().contains("/")) {
+ String blazeName = StringUtils.stripControlCodes(entity.getName());
+ try {
+ int health = Integer.parseInt(blazeName.substring(blazeName.indexOf("/") + 1, blazeName.length() - 1));
+ if (health > highestHealth) {
+ highestHealth = health;
+ highestBlaze = entity;
+ }
+ if (health < lowestHealth) {
+ lowestHealth = health;
+ lowestBlaze = entity;
+ }
+ } catch (NumberFormatException ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onWorldRender(RenderWorldLastEvent event) {
+ if (ToggleCommand.blazeToggled && Utils.inDungeons) {
+ if (lowestBlaze != null) {
+ BlockPos stringPos = new BlockPos(lowestBlaze.posX, lowestBlaze.posY + 1, lowestBlaze.posZ);
+ Utils.draw3DString(stringPos, EnumChatFormatting.BOLD + "Smallest", LOWEST_BLAZE_COLOUR, event.partialTicks);
+ AxisAlignedBB aabb = new AxisAlignedBB(lowestBlaze.posX - 0.5, lowestBlaze.posY - 2, lowestBlaze.posZ - 0.5, lowestBlaze.posX + 0.5, lowestBlaze.posY, lowestBlaze.posZ + 0.5);
+ Utils.draw3DBox(aabb, LOWEST_BLAZE_COLOUR, event.partialTicks);
+ }
+ if (highestBlaze != null) {
+ BlockPos stringPos = new BlockPos(highestBlaze.posX, highestBlaze.posY + 1, highestBlaze.posZ);
+ Utils.draw3DString(stringPos, EnumChatFormatting.BOLD + "Biggest", HIGHEST_BLAZE_COLOUR, event.partialTicks);
+ AxisAlignedBB aabb = new AxisAlignedBB(highestBlaze.posX - 0.5, highestBlaze.posY - 2, highestBlaze.posZ - 0.5, highestBlaze.posX + 0.5, highestBlaze.posY, highestBlaze.posZ + 0.5);
+ Utils.draw3DBox(aabb, HIGHEST_BLAZE_COLOUR, event.partialTicks);
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/puzzlesolvers/BlockPlacingFlowers.java b/src/main/java/me/Danker/features/puzzlesolvers/BlockPlacingFlowers.java
new file mode 100644
index 0000000..fe89fef
--- /dev/null
+++ b/src/main/java/me/Danker/features/puzzlesolvers/BlockPlacingFlowers.java
@@ -0,0 +1,44 @@
+package me.Danker.features.puzzlesolvers;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.utils.Utils;
+import net.minecraft.block.Block;
+import net.minecraft.client.Minecraft;
+import net.minecraft.init.Blocks;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.event.entity.player.PlayerInteractEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class BlockPlacingFlowers {
+
+ @SubscribeEvent
+ public void onInteract(PlayerInteractEvent event) {
+ if (!Utils.inSkyblock || Minecraft.getMinecraft().thePlayer != event.entityPlayer) return;
+ ItemStack item = event.entityPlayer.getHeldItem();
+ if (item == null) return;
+
+ if (event.action == PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK) {
+ Block block = Minecraft.getMinecraft().theWorld.getBlockState(event.pos).getBlock();
+
+ ArrayList<Block> flowerPlaceable = new ArrayList<>(Arrays.asList(
+ Blocks.grass,
+ Blocks.dirt,
+ Blocks.flower_pot,
+ Blocks.tallgrass,
+ Blocks.double_plant
+ ));
+ if (flowerPlaceable.contains(block)) {
+ if (ToggleCommand.flowerWeaponsToggled && item.getDisplayName().contains("Flower of Truth")) {
+ event.setCanceled(true);
+ }
+ if (ToggleCommand.flowerWeaponsToggled && item.getDisplayName().contains("Spirit Sceptre")) {
+ event.setCanceled(true);
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/puzzlesolvers/BlockWrongTerminalClicks.java b/src/main/java/me/Danker/features/puzzlesolvers/BlockWrongTerminalClicks.java
new file mode 100644
index 0000000..e967623
--- /dev/null
+++ b/src/main/java/me/Danker/features/puzzlesolvers/BlockWrongTerminalClicks.java
@@ -0,0 +1,112 @@
+package me.Danker.features.puzzlesolvers;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.events.ChestSlotClickedEvent;
+import me.Danker.utils.Utils;
+import net.minecraft.init.Blocks;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.inventory.Slot;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import org.lwjgl.input.Keyboard;
+
+public class BlockWrongTerminalClicks {
+
+ @SubscribeEvent
+ public void onSlotClick(ChestSlotClickedEvent event) {
+ if (ToggleCommand.blockWrongTerminalClicksToggled && Utils.inDungeons) {
+ IInventory inventory = event.inventory;
+ String inventoryName = event.inventoryName;
+ Slot slot = event.slot;
+ ItemStack item = event.item;
+ boolean shouldCancel = false;
+
+ if (item == null) return;
+
+ //most of these are extra but who cares
+
+ switch (inventoryName) {
+ case "Correct all the panes!":
+ shouldCancel = !StringUtils.stripControlCodes(item.getDisplayName()).startsWith("Off");
+ break;
+ case "Navigate the maze!":
+ if (item.getItem() != Item.getItemFromBlock(Blocks.stained_glass_pane)) {
+ shouldCancel = true;
+ break;
+ }
+
+ if (item.getItemDamage() != 0) {
+ shouldCancel = true;
+ break;
+ }
+
+ boolean isValid = false;
+
+ int slotIndex = slot.getSlotIndex();
+
+ if (slotIndex % 9 != 8 && slotIndex != 53) {
+ ItemStack itemStack = inventory.getStackInSlot(slotIndex + 1);
+ if (itemStack != null && itemStack.getItemDamage() == 5) isValid = true;
+ }
+
+ if (!isValid && slotIndex % 9 != 0 && slotIndex != 0) {
+ ItemStack itemStack = inventory.getStackInSlot(slotIndex - 1);
+ if (itemStack != null && itemStack.getItemDamage() == 5) isValid = true;
+ }
+
+ if (!isValid && slotIndex <= 44) {
+ ItemStack itemStack = inventory.getStackInSlot(slotIndex + 9);
+ if (itemStack != null && itemStack.getItemDamage() == 5) isValid = true;
+ }
+
+ if (!isValid && slotIndex >= 9) {
+ ItemStack itemStack = inventory.getStackInSlot(slotIndex - 9);
+ if (itemStack != null && itemStack.getItemDamage() == 5) isValid = true;
+ }
+
+ shouldCancel = !isValid;
+
+ break;
+ case "Click in order!":
+
+ if (slot.getSlotIndex() > 35) {
+ break;
+ }
+
+ if ((item.getItem() != Item.getItemFromBlock(Blocks.stained_glass_pane))) {
+ shouldCancel = true;
+ break;
+ }
+ if (item.getItemDamage() != 14) {
+ shouldCancel = true;
+ break;
+ }
+ int needed = ClickInOrderSolver.terminalNumberNeeded[0];
+ if (needed == 0) break;
+ shouldCancel = needed != -1 && item.stackSize != needed;
+ break;
+ }
+
+ if (!shouldCancel) {
+ if (inventoryName.startsWith("What starts with:")) {
+ char letter = inventoryName.charAt(inventoryName.indexOf("'") + 1);
+ shouldCancel = !(StringUtils.stripControlCodes(item.getDisplayName()).charAt(0) == letter);
+ } else if (inventoryName.startsWith("Select all the")) {
+ if (SelectAllColourSolver.terminalColorNeeded == null) return;
+ String itemName = StringUtils.stripControlCodes(item.getDisplayName()).toUpperCase();
+ shouldCancel = !(itemName.contains(SelectAllColourSolver.terminalColorNeeded) ||
+ (SelectAllColourSolver.terminalColorNeeded.equals("SILVER") && itemName.contains("LIGHT GRAY")) ||
+ (SelectAllColourSolver.terminalColorNeeded.equals("WHITE") && (itemName.equals("WOOL") || itemName.equals("BONE MEAL"))) ||
+ (SelectAllColourSolver.terminalColorNeeded.equals("BLACK") && itemName.equals("INK SACK")) ||
+ (SelectAllColourSolver.terminalColorNeeded.equals("BLUE") && itemName.equals("LAPIS LAZULI")) ||
+ (SelectAllColourSolver.terminalColorNeeded.equals("BROWN") && itemName.equals("COCOA BEANS")));
+ }
+ }
+
+ event.setCanceled(shouldCancel && !Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) && !Keyboard.isKeyDown(Keyboard.KEY_RCONTROL));
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/puzzlesolvers/BoulderSolver.java b/src/main/java/me/Danker/features/puzzlesolvers/BoulderSolver.java
new file mode 100644
index 0000000..0089038
--- /dev/null
+++ b/src/main/java/me/Danker/features/puzzlesolvers/BoulderSolver.java
@@ -0,0 +1,188 @@
+package me.Danker.features.puzzlesolvers;
+
+import me.Danker.DankersSkyblockMod;
+import me.Danker.commands.ToggleCommand;
+import me.Danker.utils.BoulderUtils;
+import me.Danker.utils.Utils;
+import net.minecraft.block.Block;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.entity.EntityPlayerSP;
+import net.minecraft.init.Blocks;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.util.BlockPos;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.world.World;
+import net.minecraftforge.client.event.RenderWorldLastEvent;
+import net.minecraftforge.event.entity.player.PlayerInteractEvent;
+import net.minecraftforge.event.world.WorldEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class BoulderSolver {
+
+ static boolean prevInBoulderRoom = false;
+ static boolean inBoulderRoom = false;
+ static BlockPos chest = null;
+ static String boulderRoomDirection = null;
+ public static List<int[]> route = new ArrayList<>();
+ static int currentStep = 0;
+ public static int BOULDER_COLOUR;
+ public static int BOULDER_ARROW_COLOUR;
+
+ @SubscribeEvent
+ public void onWorldChange(WorldEvent.Load event) {
+ reset();
+ }
+
+ @SubscribeEvent
+ public void onTick(TickEvent.ClientTickEvent event) {
+ if (event.phase != TickEvent.Phase.START) return;
+
+ Minecraft mc = Minecraft.getMinecraft();
+ EntityPlayerSP player = mc.thePlayer;
+ World world = mc.theWorld;
+ if (DankersSkyblockMod.tickAmount % 20 == 0) {
+ if (ToggleCommand.boulderToggled && Utils.inDungeons && world != null && player != null) {
+ // multi thread block checking
+ new Thread(() -> {
+ prevInBoulderRoom = inBoulderRoom;
+ int quartzBlocksFound = 0;
+ int barriersFound = 0;
+ BlockPos plusPlusQuartz = null;
+ BlockPos minusMinusQuartz = null;
+ Iterable<BlockPos> blocks = BlockPos.getAllInBox(new BlockPos(player.posX - 25, 68, player.posZ - 25), new BlockPos(player.posX + 25, 68, player.posZ + 25));
+ // Detect boulder room
+ for (BlockPos blockPos : blocks) {
+ if (world.getBlockState(blockPos).getBlock() == Blocks.quartz_block) {
+ quartzBlocksFound++;
+ if (plusPlusQuartz == null || (blockPos.getX() >= plusPlusQuartz.getX() && blockPos.getZ() >= plusPlusQuartz.getZ())) {
+ plusPlusQuartz = blockPos;
+ }
+ if (minusMinusQuartz == null || (blockPos.getX() <= minusMinusQuartz.getX() && blockPos.getZ() <= minusMinusQuartz.getZ())) {
+ minusMinusQuartz = blockPos;
+ }
+ if (quartzBlocksFound == 8) {
+ break;
+ }
+ } else if (world.getBlockState(blockPos).getBlock() == Blocks.barrier) {
+ barriersFound++;
+ }
+ }
+
+ if (quartzBlocksFound == 8 && barriersFound >= 350) {
+ inBoulderRoom = true;
+ if (!prevInBoulderRoom) {
+ // Get boulder locations
+ char[][] board = new char[7][7];
+ for (int x = plusPlusQuartz.getX() - 1, iterationX = 0; iterationX < 7; x -= 3, iterationX++) {
+ for (int z = plusPlusQuartz.getZ() - 1, iterationZ = 0; iterationZ < 7; z -= 3, iterationZ++) {
+ BlockPos boulderPos = new BlockPos(x, 66, z);
+ if (world.getBlockState(boulderPos).getBlock() == Blocks.planks) {
+ board[iterationX][iterationZ] = 'X';
+ }
+ }
+ }
+
+ // Detect rotation of room
+ BlockPos northChest = minusMinusQuartz.add(11, -2, -2);
+ BlockPos eastChest = plusPlusQuartz.add(2, -2, -11);
+ BlockPos southChest = plusPlusQuartz.add(-11, -2, 2);
+ BlockPos westChest = minusMinusQuartz.add(-2, -2, 11);
+ if (world.getBlockState(northChest).getBlock() == Blocks.chest) {
+ boulderRoomDirection = "north";
+ chest = northChest;
+ board = BoulderUtils.flipVertically(BoulderUtils.rotateClockwise(board));
+ } else if (world.getBlockState(eastChest).getBlock() == Blocks.chest) {
+ boulderRoomDirection = "east";
+ chest = eastChest;
+ board = BoulderUtils.flipHorizontally(board);
+ } else if (world.getBlockState(southChest).getBlock() == Blocks.chest) {
+ boulderRoomDirection = "south";
+ chest = southChest;
+ board = BoulderUtils.flipHorizontally(BoulderUtils.rotateClockwise(board));
+ } else if (world.getBlockState(westChest).getBlock() == Blocks.chest) {
+ boulderRoomDirection = "west";
+ chest = westChest;
+ board = BoulderUtils.flipVertically(board);
+ } else {
+ player.addChatMessage(new ChatComponentText(DankersSkyblockMod.ERROR_COLOUR + "Could not determine orientation of boulder room."));
+ return;
+ }
+ board = BoulderUtils.removeFirstRow(board);
+ if (BoulderUtils.hasOpenPath(board)) return;
+
+ long startTime = System.currentTimeMillis();
+ reset();
+ int length = BoulderUtils.findSolution(board, 0, route);
+ long endTime = System.currentTimeMillis();
+ System.out.println("Time elapsed: " + (endTime - startTime) + "ms, " + BoulderUtils.iterations + " iterations.");
+ if (length == 10) {
+ player.addChatMessage(new ChatComponentText(DankersSkyblockMod.ERROR_COLOUR + "No solution to puzzle found, most likely puzzle failed."));
+ } else {
+ System.out.println("Solved " + boulderRoomDirection + " facing boulder room in " + length + " steps. Path:");
+ for (int[] block : route) {
+ System.out.println(Arrays.toString(block));
+ }
+ }
+ }
+ } else {
+ chest = null;
+ boulderRoomDirection = null;
+ inBoulderRoom = false;
+ }
+ }).start();
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onWorldRender(RenderWorldLastEvent event) {
+ if (ToggleCommand.boulderToggled && Utils.inDungeons && route.size() > 0 && currentStep < route.size() && chest != null) {
+ int[] currentBlockArray = route.get(currentStep);
+ AxisAlignedBB currentBoulder = BoulderUtils.getBoulder(currentBlockArray[0], currentBlockArray[1], chest, boulderRoomDirection);
+ if (currentBoulder == null) return;
+ Utils.drawFilled3DBox(currentBoulder, BOULDER_COLOUR, true, false, event.partialTicks);
+ char direction;
+ switch (currentBlockArray[2]) {
+ case 1:
+ direction = 'u';
+ break;
+ case 2:
+ direction = 'd';
+ break;
+ case 3:
+ direction = 'l';
+ break;
+ case 4:
+ direction = 'r';
+ break;
+ default:
+ return;
+ }
+ BoulderUtils.drawArrow(currentBoulder, boulderRoomDirection, direction, 0xFF000000 + BOULDER_ARROW_COLOUR, event.partialTicks);
+ }
+ }
+
+ @SubscribeEvent
+ public void onInteract(PlayerInteractEvent event) {
+ if (Minecraft.getMinecraft().thePlayer != event.entityPlayer || !inBoulderRoom || !ToggleCommand.boulderToggled) return;
+
+ if (event.action == PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK) {
+ Block block = Minecraft.getMinecraft().theWorld.getBlockState(event.pos).getBlock();
+ if (block == Blocks.stone_button) currentStep++;
+ }
+ }
+
+ static void reset() {
+ route.clear();
+ currentStep = 0;
+ BoulderUtils.seenBoardStates.clear();
+ BoulderUtils.iterations = 0;
+ BoulderUtils.fastestSolution = 10;
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/puzzlesolvers/ChronomatronSolver.java b/src/main/java/me/Danker/features/puzzlesolvers/ChronomatronSolver.java
new file mode 100644
index 0000000..7bbd25a
--- /dev/null
+++ b/src/main/java/me/Danker/features/puzzlesolvers/ChronomatronSolver.java
@@ -0,0 +1,114 @@
+package me.Danker.features.puzzlesolvers;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.events.ChestSlotClickedEvent;
+import me.Danker.events.GuiChestBackgroundDrawnEvent;
+import me.Danker.handlers.TextRenderer;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.init.Blocks;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.inventory.Slot;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.GuiOpenEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import org.lwjgl.input.Keyboard;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ChronomatronSolver {
+
+ static int lastChronomatronRound = 0;
+ static List<String> chronomatronPattern = new ArrayList<>();
+ static int chronomatronMouseClicks = 0;
+ public static int CHRONOMATRON_NEXT;
+ public static int CHRONOMATRON_NEXT_TO_NEXT;
+
+ @SubscribeEvent
+ public void onSlotClick(ChestSlotClickedEvent event) {
+ if (ToggleCommand.chronomatronToggled && event.inventoryName.startsWith("Chronomatron (")) {
+ IInventory inventory = event.inventory;
+ ItemStack item = event.item;
+ if (item == null) {
+ if (event.isCancelable() && !Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) && !Keyboard.isKeyDown(Keyboard.KEY_RCONTROL))
+ event.setCanceled(true);
+ return;
+ }
+ if (inventory.getStackInSlot(49).getDisplayName().startsWith("§7Timer: §a") && (item.getItem() == Item.getItemFromBlock(Blocks.stained_glass) || item.getItem() == Item.getItemFromBlock(Blocks.stained_hardened_clay))) {
+ if (chronomatronPattern.size() > chronomatronMouseClicks && !item.getDisplayName().equals(chronomatronPattern.get(chronomatronMouseClicks))) {
+ if (event.isCancelable() && !Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) && !Keyboard.isKeyDown(Keyboard.KEY_RCONTROL))
+ event.setCanceled(true);
+ return;
+ }
+ chronomatronMouseClicks++;
+ } else if (inventory.getStackInSlot(49).getDisplayName().startsWith("§aRemember the pattern!")) {
+ if (event.isCancelable()) event.setCanceled(true);
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onGuiRender(GuiChestBackgroundDrawnEvent event) {
+ if (ToggleCommand.chronomatronToggled && event.displayName.startsWith("Chronomatron (")) {
+ int chestSize = event.chestSize;
+ List<Slot> invSlots = event.slots;
+ if (invSlots.size() > 48 && invSlots.get(49).getStack() != null) {
+ if (invSlots.get(49).getStack().getDisplayName().startsWith("§7Timer: §a") && invSlots.get(4).getStack() != null) {
+ int round = invSlots.get(4).getStack().stackSize;
+ int timerSeconds = Integer.parseInt(StringUtils.stripControlCodes(invSlots.get(49).getStack().getDisplayName()).replaceAll("[^\\d]", ""));
+ if (round != lastChronomatronRound && timerSeconds == round + 2) {
+ lastChronomatronRound = round;
+ for (int i = 10; i <= 43; i++) {
+ ItemStack stack = invSlots.get(i).getStack();
+ if (stack == null) continue;
+ if (stack.getItem() == Item.getItemFromBlock(Blocks.stained_hardened_clay)) {
+ chronomatronPattern.add(stack.getDisplayName());
+ break;
+ }
+ }
+ }
+ if (chronomatronMouseClicks < chronomatronPattern.size()) {
+ for (int i = 10; i <= 43; i++) {
+ ItemStack glass = invSlots.get(i).getStack();
+ if (glass == null) continue;
+
+ Slot glassSlot = invSlots.get(i);
+
+ if (chronomatronMouseClicks + 1 < chronomatronPattern.size()) {
+ if (chronomatronPattern.get(chronomatronMouseClicks).equals(chronomatronPattern.get(chronomatronMouseClicks + 1))) {
+ if (glass.getDisplayName().equals(chronomatronPattern.get(chronomatronMouseClicks))) {
+ Utils.drawOnSlot(chestSize, glassSlot.xDisplayPosition, glassSlot.yDisplayPosition, CHRONOMATRON_NEXT + 0xE5000000);
+ }
+ } else if (glass.getDisplayName().equals(chronomatronPattern.get(chronomatronMouseClicks))) {
+ Utils.drawOnSlot(chestSize, glassSlot.xDisplayPosition, glassSlot.yDisplayPosition, CHRONOMATRON_NEXT + 0xE5000000);
+ } else if (glass.getDisplayName().equals(chronomatronPattern.get(chronomatronMouseClicks + 1))) {
+ Utils.drawOnSlot(chestSize, glassSlot.xDisplayPosition, glassSlot.yDisplayPosition, CHRONOMATRON_NEXT_TO_NEXT + 0XBE000000);
+ }
+ } else if (glass.getDisplayName().equals(chronomatronPattern.get(chronomatronMouseClicks))) {
+ Utils.drawOnSlot(chestSize, glassSlot.xDisplayPosition, glassSlot.yDisplayPosition, CHRONOMATRON_NEXT + 0xE5000000);
+ }
+ }
+ }
+ } else if (invSlots.get(49).getStack().getDisplayName().equals("§aRemember the pattern!")) {
+ chronomatronMouseClicks = 0;
+ }
+ }
+ Minecraft mc = Minecraft.getMinecraft();
+ ScaledResolution sr = new ScaledResolution(mc);
+ int guiLeft = (sr.getScaledWidth() - 176) / 2;
+ new TextRenderer(mc, String.join("\n", chronomatronPattern), (int) (guiLeft * 0.8), 10, 1);
+ }
+ }
+
+ @SubscribeEvent
+ public void onGuiOpen(GuiOpenEvent event) {
+ lastChronomatronRound = 0;
+ chronomatronPattern.clear();
+ chronomatronMouseClicks = 0;
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/puzzlesolvers/ClickInOrderSolver.java b/src/main/java/me/Danker/features/puzzlesolvers/ClickInOrderSolver.java
new file mode 100644
index 0000000..e503b37
--- /dev/null
+++ b/src/main/java/me/Danker/features/puzzlesolvers/ClickInOrderSolver.java
@@ -0,0 +1,107 @@
+package me.Danker.features.puzzlesolvers;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.events.GuiChestBackgroundDrawnEvent;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.entity.EntityPlayerSP;
+import net.minecraft.client.gui.inventory.GuiChest;
+import net.minecraft.init.Blocks;
+import net.minecraft.inventory.ContainerChest;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.inventory.Slot;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.client.event.GuiOpenEvent;
+import net.minecraftforge.event.entity.player.ItemTooltipEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+
+import java.util.List;
+
+public class ClickInOrderSolver {
+
+ static Slot[] clickInOrderSlots = new Slot[36];
+ static int[] terminalNumberNeeded = new int[4];
+ public static int CLICK_IN_ORDER_NEXT;
+ public static int CLICK_IN_ORDER_NEXT_TO_NEXT;
+
+ @SubscribeEvent(priority = EventPriority.LOW)
+ public void onTooltipLow(ItemTooltipEvent event) {
+ if (!Utils.inSkyblock) return;
+ if (event.toolTip == null) return;
+
+ Minecraft mc = Minecraft.getMinecraft();
+ EntityPlayerSP player = mc.thePlayer;
+
+ if (mc.currentScreen instanceof GuiChest) {
+ ContainerChest chest = (ContainerChest) player.openContainer;
+ IInventory inv = chest.getLowerChestInventory();
+ String chestName = inv.getDisplayName().getUnformattedText();
+
+ if (ToggleCommand.clickInOrderToggled && chestName.equals("Click in order!")) {
+ event.toolTip.clear();
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onTick(TickEvent.ClientTickEvent event) {
+ if (event.phase != TickEvent.Phase.START) return;
+
+ Minecraft mc = Minecraft.getMinecraft();
+ EntityPlayerSP player = mc.thePlayer;
+ if (mc.currentScreen instanceof GuiChest) {
+ if (player == null) return;
+ ContainerChest chest = (ContainerChest) player.openContainer;
+ List<Slot> invSlots = ((GuiChest) mc.currentScreen).inventorySlots.inventorySlots;
+ String chestName = chest.getLowerChestInventory().getDisplayName().getUnformattedText().trim();
+
+ if (ToggleCommand.clickInOrderToggled && chestName.equals("Click in order!")) {
+ if (terminalNumberNeeded[0] == 0) terminalNumberNeeded[0] = 15;
+ if (terminalNumberNeeded[2] == 0) terminalNumberNeeded[2] = 15;
+ for (int i = 10; i <= 25; i++) {
+ if (i == 17 || i == 18) continue;
+ ItemStack prevStack = invSlots.get(terminalNumberNeeded[1]).getStack();
+ if (prevStack == null) terminalNumberNeeded[0] = 15;
+ else if (prevStack.getItem() != Item.getItemFromBlock(Blocks.stained_glass_pane))
+ terminalNumberNeeded[0] = 15;
+ else if (prevStack.getItemDamage() == 5) terminalNumberNeeded[0] = 15;
+
+ ItemStack itemStack = invSlots.get(i).getStack();
+ if (itemStack == null) continue;
+ if (itemStack.getItem() != Item.getItemFromBlock(Blocks.stained_glass_pane)) continue;
+ if (itemStack.getItemDamage() != 14) continue;
+ if (itemStack.stackSize < terminalNumberNeeded[0]) {
+ terminalNumberNeeded[0] = itemStack.stackSize;
+ terminalNumberNeeded[1] = i;
+ } else if (itemStack.stackSize == terminalNumberNeeded[0] + 1) {
+ terminalNumberNeeded[2] = itemStack.stackSize;
+ terminalNumberNeeded[3] = i;
+ }
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onGuiRender(GuiChestBackgroundDrawnEvent event) {
+ if (ToggleCommand.clickInOrderToggled && event.displayName.equals("Click in order!")) {
+ int chestSize = event.chestSize;
+ List<Slot> invSlots = event.slots;
+ Slot slot = invSlots.get(terminalNumberNeeded[1]);
+ Utils.drawOnSlot(chestSize, slot.xDisplayPosition, slot.yDisplayPosition, CLICK_IN_ORDER_NEXT + 0xFF000000);
+ Slot nextSlot = invSlots.get(terminalNumberNeeded[3]);
+ if (nextSlot != slot && nextSlot.getSlotIndex() != 0) {
+ Utils.drawOnSlot(chestSize, nextSlot.xDisplayPosition, nextSlot.yDisplayPosition, CLICK_IN_ORDER_NEXT_TO_NEXT + 0xFF000000);
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onGuiOpen(GuiOpenEvent event) {
+ terminalNumberNeeded = new int[4];
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/puzzlesolvers/CreeperSolver.java b/src/main/java/me/Danker/features/puzzlesolvers/CreeperSolver.java
new file mode 100644
index 0000000..7ff7e7a
--- /dev/null
+++ b/src/main/java/me/Danker/features/puzzlesolvers/CreeperSolver.java
@@ -0,0 +1,86 @@
+package me.Danker.features.puzzlesolvers;
+
+import me.Danker.DankersSkyblockMod;
+import me.Danker.commands.ToggleCommand;
+import me.Danker.utils.Utils;
+import net.minecraft.block.Block;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.entity.EntityPlayerSP;
+import net.minecraft.entity.monster.EntityCreeper;
+import net.minecraft.init.Blocks;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.util.BlockPos;
+import net.minecraft.util.Vec3;
+import net.minecraft.world.World;
+import net.minecraftforge.client.event.RenderWorldLastEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CreeperSolver {
+
+ // Among Us colours
+ static final int[] CREEPER_COLOURS = {0x50EF39, 0xC51111, 0x132ED1, 0x117F2D, 0xED54BA, 0xEF7D0D, 0xF5F557, 0xD6E0F0, 0x6B2FBB, 0x39FEDC};
+ static boolean drawCreeperLines = false;
+ static Vec3 creeperLocation = new Vec3(0, 0, 0);
+ static List<Vec3[]> creeperLines = new ArrayList<>();
+
+ @SubscribeEvent
+ public void onTick(TickEvent.ClientTickEvent event) {
+ if (event.phase != TickEvent.Phase.START) return;
+
+ Minecraft mc = Minecraft.getMinecraft();
+ World world = mc.theWorld;
+ EntityPlayerSP player = mc.thePlayer;
+ if (DankersSkyblockMod.tickAmount % 20 == 0) {
+ if (ToggleCommand.creeperToggled && Utils.inDungeons && world != null && player != null) {
+ double x = player.posX;
+ double y = player.posY;
+ double z = player.posZ;
+ // Find creepers nearby
+ AxisAlignedBB creeperScan = new AxisAlignedBB(x - 14, y - 8, z - 13, x + 14, y + 8, z + 13); // 28x16x26 cube
+ List<EntityCreeper> creepers = world.getEntitiesWithinAABB(EntityCreeper.class, creeperScan);
+ // Check if creeper is nearby
+ if (creepers.size() > 0 && !creepers.get(0).isInvisible()) { // Don't show Wither Cloak creepers
+ EntityCreeper creeper = creepers.get(0);
+ // Start creeper line drawings
+ creeperLines.clear();
+ if (!drawCreeperLines) creeperLocation = new Vec3(creeper.posX, creeper.posY + 1, creeper.posZ);
+ drawCreeperLines = true;
+ // Search for nearby sea lanterns and prismarine blocks
+ BlockPos point1 = new BlockPos(creeper.posX - 14, creeper.posY - 7, creeper.posZ - 13);
+ BlockPos point2 = new BlockPos(creeper.posX + 14, creeper.posY + 10, creeper.posZ + 13);
+ Iterable<BlockPos> blocks = BlockPos.getAllInBox(point1, point2);
+ for (BlockPos blockPos : blocks) {
+ Block block = world.getBlockState(blockPos).getBlock();
+ if (block == Blocks.sea_lantern || block == Blocks.prismarine) {
+ // Connect block to nearest block on opposite side
+ Vec3 startBlock = new Vec3(blockPos.getX() + 0.5, blockPos.getY() + 0.5, blockPos.getZ() + 0.5);
+ BlockPos oppositeBlock = Utils.getFirstBlockPosAfterVectors(mc, startBlock, creeperLocation, 10, 20);
+ BlockPos endBlock = Utils.getNearbyBlock(mc, oppositeBlock, Blocks.sea_lantern, Blocks.prismarine);
+ if (endBlock != null && startBlock.yCoord > 68 && endBlock.getY() > 68) { // Don't create line underground
+ // Add to list for drawing
+ Vec3[] insertArray = {startBlock, new Vec3(endBlock.getX() + 0.5, endBlock.getY() + 0.5, endBlock.getZ() + 0.5)};
+ creeperLines.add(insertArray);
+ }
+ }
+ }
+ } else {
+ drawCreeperLines = false;
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onWorldRender(RenderWorldLastEvent event) {
+ if (ToggleCommand.creeperToggled && drawCreeperLines && !creeperLines.isEmpty()) {
+ for (int i = 0; i < creeperLines.size(); i++) {
+ Utils.draw3DLine(creeperLines.get(i)[0], creeperLines.get(i)[1], CREEPER_COLOURS[i % 10], 2, true, event.partialTicks);
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/puzzlesolvers/LividSolver.java b/src/main/java/me/Danker/features/puzzlesolvers/LividSolver.java
new file mode 100644
index 0000000..b537198
--- /dev/null
+++ b/src/main/java/me/Danker/features/puzzlesolvers/LividSolver.java
@@ -0,0 +1,89 @@
+package me.Danker.features.puzzlesolvers;
+
+import me.Danker.DankersSkyblockMod;
+import me.Danker.commands.MoveCommand;
+import me.Danker.commands.ScaleCommand;
+import me.Danker.commands.ToggleCommand;
+import me.Danker.events.RenderOverlay;
+import me.Danker.handlers.ScoreboardHandler;
+import me.Danker.handlers.TextRenderer;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.item.EntityArmorStand;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.world.World;
+import net.minecraftforge.client.event.RenderLivingEvent;
+import net.minecraftforge.event.world.WorldEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LividSolver {
+
+ static boolean foundLivid = false;
+ static Entity livid = null;
+
+ @SubscribeEvent
+ public void onWorldChange(WorldEvent.Load event) {
+ foundLivid = false;
+ livid = null;
+ }
+
+ @SubscribeEvent
+ public void onTick(TickEvent.ClientTickEvent event) {
+ if (event.phase != TickEvent.Phase.START) return;
+
+ World world = Minecraft.getMinecraft().theWorld;
+ if (DankersSkyblockMod.tickAmount % 20 == 0) {
+ if (ToggleCommand.lividSolverToggled && Utils.inDungeons && !foundLivid && world != null) {
+ boolean inF5 = false;
+
+ List<String> scoreboard = ScoreboardHandler.getSidebarLines();
+ for (String s : scoreboard) {
+ String sCleaned = ScoreboardHandler.cleanSB(s);
+ if (sCleaned.contains("The Catacombs (F5)")) {
+ inF5 = true;
+ break;
+ }
+ }
+
+ if (inF5) {
+ List<Entity> loadedLivids = new ArrayList<>();
+ List<Entity> entities = world.getLoadedEntityList();
+ for (Entity entity : entities) {
+ String name = entity.getName();
+ if (name.contains("Livid") && name.length() > 5 && name.charAt(1) == name.charAt(5) && !loadedLivids.contains(entity)) {
+ loadedLivids.add(entity);
+ }
+ }
+ if (loadedLivids.size() > 8) {
+ livid = loadedLivids.get(0);
+ foundLivid = true;
+ }
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void renderPlayerInfo(RenderOverlay event) {
+ if (ToggleCommand.lividSolverToggled && foundLivid && livid != null) {
+ new TextRenderer(Minecraft.getMinecraft(), livid.getName().replace("" + EnumChatFormatting.BOLD, ""), MoveCommand.lividHpXY[0], MoveCommand.lividHpXY[1], ScaleCommand.lividHpScale);
+ }
+ }
+
+ @SubscribeEvent
+ public void onRenderEntity(RenderLivingEvent.Pre event) {
+ Entity entity = event.entity;
+ String name = entity.getName();
+ if (entity instanceof EntityArmorStand) {
+ if (ToggleCommand.lividSolverToggled && !entity.isEntityEqual(livid) && name.contains("Livid") && name.length() > 5 && name.charAt(1) == name.charAt(5)) {
+ event.setCanceled(true);
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/puzzlesolvers/SelectAllColourSolver.java b/src/main/java/me/Danker/features/puzzlesolvers/SelectAllColourSolver.java
new file mode 100644
index 0000000..cce89d2
--- /dev/null
+++ b/src/main/java/me/Danker/features/puzzlesolvers/SelectAllColourSolver.java
@@ -0,0 +1,59 @@
+package me.Danker.features.puzzlesolvers;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.events.GuiChestBackgroundDrawnEvent;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.inventory.Slot;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.GuiOpenEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class SelectAllColourSolver {
+
+ static Pattern selectAllTerminalPattern = Pattern.compile("[A-Z]{2,}");
+ static String terminalColorNeeded;
+
+ @SubscribeEvent
+ public void onGuiRender(GuiChestBackgroundDrawnEvent event) {
+ String displayName = event.displayName;
+ if (ToggleCommand.selectAllToggled && Utils.inDungeons && displayName.startsWith("Select all the")) {
+ String colour;
+ List<String> colourParts = new ArrayList<>();
+ Matcher colourMatcher = selectAllTerminalPattern.matcher(displayName);
+ while (colourMatcher.find()) {
+ colourParts.add(colourMatcher.group());
+ }
+ colour = String.join(" ", colourParts);
+ terminalColorNeeded = colour;
+
+ for (Slot slot : event.slots) {
+ if (slot.inventory == Minecraft.getMinecraft().thePlayer.inventory) continue;
+ ItemStack item = slot.getStack();
+ if (item == null) continue;
+ if (item.isItemEnchanted()) continue;
+ String itemName = StringUtils.stripControlCodes(item.getDisplayName()).toUpperCase();
+ if (itemName.contains(terminalColorNeeded) ||
+ (terminalColorNeeded.equals("SILVER") && itemName.contains("LIGHT GRAY")) ||
+ (terminalColorNeeded.equals("WHITE") && (itemName.equals("WOOL") || itemName.equals("BONE MEAL"))) ||
+ (terminalColorNeeded.equals("BLACK") && itemName.equals("INK SACK")) ||
+ (terminalColorNeeded.equals("BLUE") && itemName.equals("LAPIS LAZULI")) ||
+ (terminalColorNeeded.equals("BROWN") && itemName.equals("COCOA BEANS"))) {
+ Utils.drawOnSlot(event.chestSize, slot.xDisplayPosition, slot.yDisplayPosition, 0xBF40FF40);
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onGuiOpen(GuiOpenEvent event) {
+ terminalColorNeeded = null;
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/puzzlesolvers/StartsWithSolver.java b/src/main/java/me/Danker/features/puzzlesolvers/StartsWithSolver.java
new file mode 100644
index 0000000..8f15fa7
--- /dev/null
+++ b/src/main/java/me/Danker/features/puzzlesolvers/StartsWithSolver.java
@@ -0,0 +1,31 @@
+package me.Danker.features.puzzlesolvers;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.events.GuiChestBackgroundDrawnEvent;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.inventory.Slot;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+public class StartsWithSolver {
+
+ @SubscribeEvent
+ public void onGuiRender(GuiChestBackgroundDrawnEvent event) {
+ String displayName = event.displayName;
+ if (ToggleCommand.startsWithToggled && Utils.inDungeons && displayName.startsWith("What starts with:")) {
+ char letter = displayName.charAt(displayName.indexOf("'") + 1);
+ for (Slot slot : event.slots) {
+ if (slot.inventory == Minecraft.getMinecraft().thePlayer.inventory) continue;
+ ItemStack item = slot.getStack();
+ if (item == null) continue;
+ if (item.isItemEnchanted()) continue;
+ if (StringUtils.stripControlCodes(item.getDisplayName()).charAt(0) == letter) {
+ Utils.drawOnSlot(event.chestSize, slot.xDisplayPosition, slot.yDisplayPosition, 0xBF40FF40);
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/puzzlesolvers/SuperpairsSolver.java b/src/main/java/me/Danker/features/puzzlesolvers/SuperpairsSolver.java
new file mode 100644
index 0000000..c6e1d76
--- /dev/null
+++ b/src/main/java/me/Danker/features/puzzlesolvers/SuperpairsSolver.java
@@ -0,0 +1,150 @@
+package me.Danker.features.puzzlesolvers;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.events.GuiChestBackgroundDrawnEvent;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.entity.EntityPlayerSP;
+import net.minecraft.client.gui.inventory.GuiChest;
+import net.minecraft.inventory.ContainerChest;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.inventory.Slot;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.GuiOpenEvent;
+import net.minecraftforge.event.entity.player.ItemTooltipEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+
+import java.awt.*;
+import java.util.List;
+import java.util.*;
+
+public class SuperpairsSolver {
+
+ static ItemStack[] experimentTableSlots = new ItemStack[54];
+
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
+ public void onTooltip(ItemTooltipEvent event) {
+ if (!Utils.inSkyblock) return;
+ if (event.toolTip == null) return;
+
+ ItemStack item = event.itemStack;
+ Minecraft mc = Minecraft.getMinecraft();
+ EntityPlayerSP player = mc.thePlayer;
+
+ if (mc.currentScreen instanceof GuiChest) {
+ ContainerChest chest = (ContainerChest) player.openContainer;
+ IInventory inv = chest.getLowerChestInventory();
+ String chestName = inv.getDisplayName().getUnformattedText();
+
+ if (ToggleCommand.superpairsToggled && chestName.contains("Superpairs (")) {
+ if (Item.getIdFromItem(item.getItem()) != 95) return;
+ if (item.getDisplayName().contains("Click any button") || item.getDisplayName().contains("Click a second button") || item.getDisplayName().contains("Next button is instantly rewarded") || item.getDisplayName().contains("Stained Glass")) {
+ Slot slot = ((GuiChest) mc.currentScreen).getSlotUnderMouse();
+ ItemStack itemStack = experimentTableSlots[slot.getSlotIndex()];
+ if (itemStack == null) return;
+ String itemName = itemStack.getDisplayName();
+
+ if (event.toolTip.stream().anyMatch(x -> StringUtils.stripControlCodes(x).equals(StringUtils.stripControlCodes(itemName))))
+ return;
+ event.toolTip.removeIf(x -> {
+ x = StringUtils.stripControlCodes(x);
+ if (x.equals("minecraft:stained_glass")) return true;
+ return x.startsWith("NBT: ");
+ });
+ event.toolTip.add(itemName);
+ event.toolTip.add(itemStack.getItem().getRegistryName());
+ }
+
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onTick(TickEvent.ClientTickEvent event) {
+ if (event.phase != TickEvent.Phase.START) return;
+
+ Minecraft mc = Minecraft.getMinecraft();
+ EntityPlayerSP player = mc.thePlayer;
+ if (mc.currentScreen instanceof GuiChest) {
+ if (player == null) return;
+ ContainerChest chest = (ContainerChest) player.openContainer;
+ List<Slot> invSlots = ((GuiChest) mc.currentScreen).inventorySlots.inventorySlots;
+ String chestName = chest.getLowerChestInventory().getDisplayName().getUnformattedText().trim();
+
+ if (ToggleCommand.superpairsToggled && chestName.startsWith("Superpairs (")) {
+ for (int i = 0; i < 53; i++) {
+ ItemStack itemStack = invSlots.get(i).getStack();
+ if (itemStack == null) continue;
+ String itemName = itemStack.getDisplayName();
+ if (Item.getIdFromItem(itemStack.getItem()) == 95 || Item.getIdFromItem(itemStack.getItem()) == 160) continue;
+ if (itemName.contains("Instant Find") || itemName.contains("Gained +")) continue;
+ if (itemName.contains("Enchanted Book")) {
+ itemName = itemStack.getTooltip(mc.thePlayer, false).get(3);
+ }
+ if (itemStack.stackSize > 1) {
+ itemName = itemStack.stackSize + " " + itemName;
+ }
+ if (experimentTableSlots[i] != null) continue;
+ experimentTableSlots[i] = itemStack.copy().setStackDisplayName(itemName);
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onGuiRender(GuiChestBackgroundDrawnEvent event) {
+ if (ToggleCommand.superpairsToggled && event.displayName.contains("Superpairs (")) {
+ HashMap<String, HashSet<Integer>> matches = new HashMap<>();
+ for (int i = 0; i < 53; i++) {
+ ItemStack itemStack = experimentTableSlots[i];
+ if (itemStack == null) continue;
+
+ //Utils.renderItem(itemStack, x, y, -100);
+
+ String itemName = itemStack.getDisplayName();
+ String keyName = itemName + itemStack.getUnlocalizedName();
+ matches.computeIfAbsent(keyName, k -> new HashSet<>());
+ matches.get(keyName).add(i);
+ }
+
+ Color[] colors = {
+ new Color(255, 0, 0, 100),
+ new Color(0, 0, 255, 100),
+ new Color(100, 179, 113, 100),
+ new Color(255, 114, 255, 100),
+ new Color(255, 199, 87, 100),
+ new Color(119, 105, 198, 100),
+ new Color(135, 199, 112, 100),
+ new Color(240, 37, 240, 100),
+ new Color(178, 132, 190, 100),
+ new Color(63, 135, 163, 100),
+ new Color(146, 74, 10, 100),
+ new Color(255, 255, 255, 100),
+ new Color(217, 252, 140, 100),
+ new Color(255, 82, 82, 100)
+ };
+
+ Iterator<Color> colorIterator = Arrays.stream(colors).iterator();
+
+ matches.forEach((itemName, slotSet) -> {
+ if (slotSet.size() < 2) return;
+ ArrayList<Slot> slots = new ArrayList<>();
+ slotSet.forEach(slotNum -> slots.add(event.slots.get(slotNum)));
+ Color color = colorIterator.next();
+ slots.forEach(slot -> {
+ Utils.drawOnSlot(event.chestSize, slot.xDisplayPosition, slot.yDisplayPosition, color.getRGB());
+ });
+ });
+ }
+ }
+
+ @SubscribeEvent
+ public void onGuiOpen(GuiOpenEvent event) {
+ experimentTableSlots = new ItemStack[54];
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/puzzlesolvers/ThreeManSolver.java b/src/main/java/me/Danker/features/puzzlesolvers/ThreeManSolver.java
new file mode 100644
index 0000000..8f7de95
--- /dev/null
+++ b/src/main/java/me/Danker/features/puzzlesolvers/ThreeManSolver.java
@@ -0,0 +1,75 @@
+package me.Danker.features.puzzlesolvers;
+
+import me.Danker.DankersSkyblockMod;
+import me.Danker.commands.ToggleCommand;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.entity.Entity;
+import net.minecraft.init.Blocks;
+import net.minecraft.util.*;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.client.event.RenderWorldLastEvent;
+import net.minecraftforge.event.world.WorldEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import java.util.List;
+
+public class ThreeManSolver {
+
+ static String[] riddleSolutions = {"The reward is not in my chest!", "At least one of them is lying, and the reward is not in",
+ "My chest doesn't have the reward. We are all telling the truth", "My chest has the reward and I'm telling the truth",
+ "The reward isn't in any of our chests", "Both of them are telling the truth."};
+ static BlockPos riddleChest = null;
+
+ @SubscribeEvent
+ public void onWorldChange(WorldEvent.Load event) {
+ riddleChest = null;
+ }
+
+ @SubscribeEvent
+ public void onChat(ClientChatReceivedEvent event) {
+ String message = StringUtils.stripControlCodes(event.message.getUnformattedText());
+
+ if (!Utils.inDungeons) return;
+
+ if (ToggleCommand.threeManToggled && message.contains("[NPC]")) {
+ for (String solution : riddleSolutions) {
+ if (message.contains(solution)) {
+ Minecraft mc = Minecraft.getMinecraft();
+ String npcName = message.substring(message.indexOf("]") + 2, message.indexOf(":"));
+ mc.thePlayer.addChatMessage(new ChatComponentText(DankersSkyblockMod.ANSWER_COLOUR + EnumChatFormatting.BOLD + StringUtils.stripControlCodes(npcName) + DankersSkyblockMod.MAIN_COLOUR + " has the blessing."));
+ if (riddleChest == null) {
+ List<Entity> entities = mc.theWorld.getLoadedEntityList();
+ for (Entity entity : entities) {
+ if (entity == null || !entity.hasCustomName()) continue;
+ if (entity.getCustomNameTag().contains(npcName)) {
+ BlockPos npcLocation = new BlockPos(entity.posX, 69, entity.posZ);
+ if (mc.theWorld.getBlockState(npcLocation.north()).getBlock() == Blocks.chest) {
+ riddleChest = npcLocation.north();
+ } else if (mc.theWorld.getBlockState(npcLocation.east()).getBlock() == Blocks.chest) {
+ riddleChest = npcLocation.east();
+ } else if (mc.theWorld.getBlockState(npcLocation.south()).getBlock() == Blocks.chest) {
+ riddleChest = npcLocation.south();
+ } else if (mc.theWorld.getBlockState(npcLocation.west()).getBlock() == Blocks.chest) {
+ riddleChest = npcLocation.west();
+ } else {
+ System.out.print("Could not find correct riddle chest.");
+ }
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onWorldRender(RenderWorldLastEvent event) {
+ if (ToggleCommand.threeManToggled && riddleChest != null) {
+ Utils.drawFilled3DBox(new AxisAlignedBB(riddleChest.getX() - 0.05, riddleChest.getY(), riddleChest.getZ() - 0.05, riddleChest.getX() + 1.05, riddleChest.getY() + 1, riddleChest.getZ() + 1.05), 0x197F19, true, true, event.partialTicks);
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/puzzlesolvers/TicTacToeSolver.java b/src/main/java/me/Danker/features/puzzlesolvers/TicTacToeSolver.java
new file mode 100644
index 0000000..1b4a2e1
--- /dev/null
+++ b/src/main/java/me/Danker/features/puzzlesolvers/TicTacToeSolver.java
@@ -0,0 +1,135 @@
+package me.Danker.features.puzzlesolvers;
+
+import me.Danker.DankersSkyblockMod;
+import me.Danker.commands.ToggleCommand;
+import me.Danker.utils.TicTacToeUtils;
+import me.Danker.utils.Utils;
+import net.minecraft.block.Block;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.entity.EntityPlayerSP;
+import net.minecraft.entity.item.EntityItemFrame;
+import net.minecraft.init.Blocks;
+import net.minecraft.item.ItemMap;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.util.BlockPos;
+import net.minecraft.util.EnumFacing;
+import net.minecraft.world.World;
+import net.minecraft.world.storage.MapData;
+import net.minecraftforge.client.event.RenderWorldLastEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class TicTacToeSolver {
+
+ static AxisAlignedBB correctTicTacToeButton = null;
+
+ @SubscribeEvent
+ public void onTick(TickEvent.ClientTickEvent event) {
+ if (event.phase != TickEvent.Phase.START) return;
+
+ Minecraft mc = Minecraft.getMinecraft();
+ World world = mc.theWorld;
+ EntityPlayerSP player = mc.thePlayer;
+ if (DankersSkyblockMod.tickAmount % 20 == 0) {
+ if (ToggleCommand.ticTacToeToggled && Utils.inDungeons && world != null && player != null) {
+ correctTicTacToeButton = null;
+ AxisAlignedBB aabb = new AxisAlignedBB(player.posX - 6, player.posY - 6, player.posZ - 6, player.posX + 6, player.posY + 6, player.posZ + 6);
+ List<EntityItemFrame> itemFrames = world.getEntitiesWithinAABB(EntityItemFrame.class, aabb);
+ List<EntityItemFrame> itemFramesWithMaps = new ArrayList<>();
+ // Find how many item frames have maps already placed
+ for (EntityItemFrame itemFrame : itemFrames) {
+ ItemStack item = itemFrame.getDisplayedItem();
+ if (item == null || !(item.getItem() instanceof ItemMap)) continue;
+ MapData mapData = ((ItemMap) item.getItem()).getMapData(item, world);
+ if (mapData == null) continue;
+
+ itemFramesWithMaps.add(itemFrame);
+ }
+
+ // Only run when it's your turn
+ if (itemFramesWithMaps.size() != 9 && itemFramesWithMaps.size() % 2 == 1) {
+ char[][] board = new char[3][3];
+ BlockPos leftmostRow = null;
+ int sign = 1;
+ char facing = 'X';
+ for (EntityItemFrame itemFrame : itemFramesWithMaps) {
+ ItemStack map = itemFrame.getDisplayedItem();
+ MapData mapData = ((ItemMap) map.getItem()).getMapData(map, world);
+
+ // Find position on board
+ // I mixed up row and column here and I'm too lazy to fix it
+ int row = 0;
+ int column;
+ sign = 1;
+
+ if (itemFrame.facingDirection == EnumFacing.SOUTH || itemFrame.facingDirection == EnumFacing.WEST) {
+ sign = -1;
+ }
+
+ BlockPos itemFramePos = new BlockPos(itemFrame.posX, Math.floor(itemFrame.posY), itemFrame.posZ);
+ for (int i = 2; i >= 0; i--) {
+ int realI = i * sign;
+ BlockPos blockPos = itemFramePos;
+ if (itemFrame.posX % 0.5 == 0) {
+ blockPos = itemFramePos.add(realI, 0, 0);
+ } else if (itemFrame.posZ % 0.5 == 0) {
+ blockPos = itemFramePos.add(0, 0, realI);
+ facing = 'Z';
+ }
+ Block block = world.getBlockState(blockPos).getBlock();
+ if (block == Blocks.air || block == Blocks.stone_button) {
+ leftmostRow = blockPos;
+ row = i;
+ break;
+ }
+ }
+
+ if (itemFrame.posY == 72.5) {
+ column = 0;
+ } else if (itemFrame.posY == 71.5) {
+ column = 1;
+ } else if (itemFrame.posY == 70.5) {
+ column = 2;
+ } else {
+ continue;
+ }
+
+ // Get colour
+ // Middle pixel = 64*128 + 64 = 8256
+ int colourInt = mapData.colors[8256] & 255;
+ if (colourInt == 114) {
+ board[column][row] = 'X';
+ } else if (colourInt == 33) {
+ board[column][row] = 'O';
+ }
+ }
+ System.out.println("Board: " + Arrays.deepToString(board));
+
+ // Draw best move
+ int bestMove = TicTacToeUtils.getBestMove(board) - 1;
+ System.out.println("Best move slot: " + bestMove);
+ if (leftmostRow != null) {
+ double drawX = facing == 'X' ? leftmostRow.getX() - sign * (bestMove % 3) : leftmostRow.getX();
+ double drawY = 72 - Math.floor(bestMove / 3);
+ double drawZ = facing == 'Z' ? leftmostRow.getZ() - sign * (bestMove % 3) : leftmostRow.getZ();
+
+ correctTicTacToeButton = new AxisAlignedBB(drawX, drawY, drawZ, drawX + 1, drawY + 1, drawZ + 1);
+ }
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onWorldRender(RenderWorldLastEvent event) {
+ if (ToggleCommand.ticTacToeToggled && correctTicTacToeButton != null) {
+ Utils.draw3DBox(correctTicTacToeButton, 0x40FF40, event.partialTicks);
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/puzzlesolvers/TriviaSolver.java b/src/main/java/me/Danker/features/puzzlesolvers/TriviaSolver.java
new file mode 100644
index 0000000..b769634
--- /dev/null
+++ b/src/main/java/me/Danker/features/puzzlesolvers/TriviaSolver.java
@@ -0,0 +1,102 @@
+package me.Danker.features.puzzlesolvers;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.utils.Utils;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class TriviaSolver {
+
+ static Map<String, String[]> triviaSolutions = new HashMap<>();
+ static String[] triviaAnswers = null;
+ public static String TRIVIA_WRONG_ANSWER_COLOUR;
+
+ public static void init() {
+ triviaSolutions.put("What is the status of The Watcher?", new String[]{"Stalker"});
+ triviaSolutions.put("What is the status of Bonzo?", new String[]{"New Necromancer"});
+ triviaSolutions.put("What is the status of Scarf?", new String[]{"Apprentice Necromancer"});
+ triviaSolutions.put("What is the status of The Professor?", new String[]{"Professor"});
+ triviaSolutions.put("What is the status of Thorn?", new String[]{"Shaman Necromancer"});
+ triviaSolutions.put("What is the status of Livid?", new String[]{"Master Necromancer"});
+ triviaSolutions.put("What is the status of Sadan?", new String[]{"Necromancer Lord"});
+ triviaSolutions.put("What is the status of Maxor?", new String[]{"Young Wither"});
+ triviaSolutions.put("What is the status of Goldor?", new String[]{"Wither Soldier"});
+ triviaSolutions.put("What is the status of Storm?", new String[]{"Elementalist"});
+ triviaSolutions.put("What is the status of Necron?", new String[]{"Wither Lord"});
+ triviaSolutions.put("How many total Fairy Souls are there?", new String[]{"220 Fairy Souls"});
+ triviaSolutions.put("How many Fairy Souls are there in Spider's Den?", new String[]{"17 Fairy Souls"});
+ triviaSolutions.put("How many Fairy Souls are there in The End?", new String[]{"12 Fairy Souls"});
+ triviaSolutions.put("How many Fairy Souls are there in The Barn?", new String[]{"7 Fairy Souls"});
+ triviaSolutions.put("How many Fairy Souls are there in Mushroom Desert?", new String[]{"8 Fairy Souls"});
+ triviaSolutions.put("How many Fairy Souls are there in Blazing Fortress?", new String[]{"19 Fairy Souls"});
+ triviaSolutions.put("How many Fairy Souls are there in The Park?", new String[]{"11 Fairy Souls"});
+ triviaSolutions.put("How many Fairy Souls are there in Jerry's Workshop?", new String[]{"5 Fairy Souls"});
+ triviaSolutions.put("How many Fairy Souls are there in Hub?", new String[]{"79 Fairy Souls"});
+ triviaSolutions.put("How many Fairy Souls are there in The Hub?", new String[]{"79 Fairy Souls"});
+ triviaSolutions.put("How many Fairy Souls are there in Deep Caverns?", new String[]{"21 Fairy Souls"});
+ triviaSolutions.put("How many Fairy Souls are there in Gold Mine?", new String[]{"12 Fairy Souls"});
+ triviaSolutions.put("How many Fairy Souls are there in Dungeon Hub?", new String[]{"7 Fairy Souls"});
+ triviaSolutions.put("Which brother is on the Spider's Den?", new String[]{"Rick"});
+ triviaSolutions.put("What is the name of Rick's brother?", new String[]{"Pat"});
+ triviaSolutions.put("What is the name of the Painter in the Hub?", new String[]{"Marco"});
+ triviaSolutions.put("What is the name of the person that upgrades pets?", new String[]{"Kat"});
+ triviaSolutions.put("What is the name of the lady of the Nether?", new String[]{"Elle"});
+ triviaSolutions.put("Which villager in the Village gives you a Rogue Sword?", new String[]{"Jamie"});
+ triviaSolutions.put("How many unique minions are there?", new String[]{"53 Minions"});
+ triviaSolutions.put("Which of these enemies does not spawn in the Spider's Den?", new String[]{"Zombie Spider", "Cave Spider", "Wither Skeleton",
+ "Dashing Spooder", "Broodfather", "Night Spider"});
+ triviaSolutions.put("Which of these monsters only spawns at night?", new String[]{"Zombie Villager", "Ghast"});
+ triviaSolutions.put("Which of these is not a dragon in The End?", new String[]{"Zoomer Dragon", "Weak Dragon", "Stonk Dragon", "Holy Dragon", "Boomer Dragon",
+ "Booger Dragon", "Older Dragon", "Elder Dragon", "Stable Dragon", "Professor Dragon"});
+ }
+
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
+ public void onChat(ClientChatReceivedEvent event) {
+ String message = StringUtils.stripControlCodes(event.message.getUnformattedText());
+
+ if (!Utils.inDungeons) return;
+ if (event.type == 2) return;
+
+ if (ToggleCommand.oruoToggled) {
+ if (message.contains("What SkyBlock year is it?")) {
+ double currentTime = System.currentTimeMillis() /1000L;
+
+ double diff = Math.floor(currentTime - 1560276000);
+
+ int year = (int) (diff / 446400 + 1);
+ triviaAnswers = new String[]{"Year " + year};
+ } else {
+ for (String question : triviaSolutions.keySet()) {
+ if (message.contains(question)) {
+ triviaAnswers = triviaSolutions.get(question);
+ break;
+ }
+ }
+ }
+
+ // Set wrong answers to red and remove click events
+ if (triviaAnswers != null && (message.contains("ⓐ") || message.contains("ⓑ") || message.contains("ⓒ"))) {
+ boolean isSolution = false;
+ for (String solution : triviaAnswers) {
+ if (message.contains(solution)) {
+ isSolution = true;
+ break;
+ }
+ }
+ if (!isSolution) {
+ char letter = message.charAt(5);
+ String option = message.substring(6);
+ event.message = new ChatComponentText(" " + EnumChatFormatting.GOLD + letter + TRIVIA_WRONG_ANSWER_COLOUR + option);
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/puzzlesolvers/UltrasequencerSolver.java b/src/main/java/me/Danker/features/puzzlesolvers/UltrasequencerSolver.java
new file mode 100644
index 0000000..87309fe
--- /dev/null
+++ b/src/main/java/me/Danker/features/puzzlesolvers/UltrasequencerSolver.java
@@ -0,0 +1,112 @@
+package me.Danker.features.puzzlesolvers;
+
+import me.Danker.commands.ToggleCommand;
+import me.Danker.events.ChestSlotClickedEvent;
+import me.Danker.events.GuiChestBackgroundDrawnEvent;
+import me.Danker.utils.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.entity.EntityPlayerSP;
+import net.minecraft.client.gui.inventory.GuiChest;
+import net.minecraft.inventory.ContainerChest;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.inventory.Slot;
+import net.minecraft.util.StringUtils;
+import net.minecraftforge.client.event.GuiOpenEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+import org.lwjgl.input.Keyboard;
+
+import java.util.List;
+
+public class UltrasequencerSolver {
+
+ static Slot[] clickInOrderSlots = new Slot[36];
+ static int lastUltraSequencerClicked = 0;
+ public static int ULTRASEQUENCER_NEXT;
+ public static int ULTRASEQUENCER_NEXT_TO_NEXT;
+
+ @SubscribeEvent
+ public void onTick(TickEvent.ClientTickEvent event) {
+ if (event.phase != TickEvent.Phase.START) return;
+
+ Minecraft mc = Minecraft.getMinecraft();
+ EntityPlayerSP player = mc.thePlayer;
+ if (mc.currentScreen instanceof GuiChest) {
+ if (player == null) return;
+ ContainerChest chest = (ContainerChest) player.openContainer;
+ List<Slot> invSlots = ((GuiChest) mc.currentScreen).inventorySlots.inventorySlots;
+ String chestName = chest.getLowerChestInventory().getDisplayName().getUnformattedText().trim();
+
+ if (ToggleCommand.ultrasequencerToggled && chestName.startsWith("Ultrasequencer (")) {
+ if (invSlots.get(49).getStack() != null && invSlots.get(49).getStack().getDisplayName().equals("§aRemember the pattern!")) {
+ for (int i = 9; i <= 44; i++) {
+ if (invSlots.get(i) == null || invSlots.get(i).getStack() == null) continue;
+ String itemName = StringUtils.stripControlCodes(invSlots.get(i).getStack().getDisplayName());
+ if (itemName.matches("\\d+")) {
+ int number = Integer.parseInt(itemName);
+ clickInOrderSlots[number - 1] = invSlots.get(i);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onSlotClick(ChestSlotClickedEvent event) {
+ if (ToggleCommand.ultrasequencerToggled && event.inventoryName.startsWith("Ultrasequencer (")) {
+ IInventory inventory = event.inventory;
+ if (event.item == null) {
+ if (event.isCancelable() && !Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) && !Keyboard.isKeyDown(Keyboard.KEY_RCONTROL))
+ event.setCanceled(true);
+ return;
+ }
+ if (inventory.getStackInSlot(49).getDisplayName().equals("§aRemember the pattern!")) {
+ if (event.isCancelable()) event.setCanceled(true);
+ return;
+ } else if (inventory.getStackInSlot(49).getDisplayName().startsWith("§7Timer: §a")) {
+ if (clickInOrderSlots[lastUltraSequencerClicked] != null && event.slot.getSlotIndex() != clickInOrderSlots[lastUltraSequencerClicked].getSlotIndex()) {
+ if (event.isCancelable() && !Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) && !Keyboard.isKeyDown(Keyboard.KEY_RCONTROL))
+ event.setCanceled(true);
+ return;
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onGuiRender(GuiChestBackgroundDrawnEvent event) {
+ if (ToggleCommand.ultrasequencerToggled && event.displayName.startsWith("Ultrasequencer (")) {
+ List<Slot> invSlots = event.slots;
+ if (invSlots.size() > 48 && invSlots.get(49).getStack() != null) {
+ if (invSlots.get(49).getStack().getDisplayName().startsWith("§7Timer: §a")) {
+ lastUltraSequencerClicked = 0;
+ for (Slot slot : clickInOrderSlots) {
+ if (slot != null && slot.getStack() != null && StringUtils.stripControlCodes(slot.getStack().getDisplayName()).matches("\\d+")) {
+ int number = Integer.parseInt(StringUtils.stripControlCodes(slot.getStack().getDisplayName()));
+ if (number > lastUltraSequencerClicked) {
+ lastUltraSequencerClicked = number;
+ }
+ }
+ }
+ if (clickInOrderSlots[lastUltraSequencerClicked] != null) {
+ Slot nextSlot = clickInOrderSlots[lastUltraSequencerClicked];
+ Utils.drawOnSlot(event.chestSize, nextSlot.xDisplayPosition, nextSlot.yDisplayPosition, ULTRASEQUENCER_NEXT + 0xE5000000);
+ }
+ if (lastUltraSequencerClicked + 1 < clickInOrderSlots.length) {
+ if (clickInOrderSlots[lastUltraSequencerClicked + 1] != null) {
+ Slot nextSlot = clickInOrderSlots[lastUltraSequencerClicked + 1];
+ Utils.drawOnSlot(event.chestSize, nextSlot.xDisplayPosition, nextSlot.yDisplayPosition, ULTRASEQUENCER_NEXT_TO_NEXT + 0xD7000000);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onGuiOpen(GuiOpenEvent event) {
+ clickInOrderSlots = new Slot[36];
+ }
+
+}
diff --git a/src/main/java/me/Danker/features/puzzlesolvers/WaterSolver.java b/src/main/java/me/Danker/features/puzzlesolvers/WaterSolver.java
new file mode 100644
index 0000000..2be92f9
--- /dev/null
+++ b/src/main/java/me/Danker/features/puzzlesolvers/WaterSolver.java
@@ -0,0 +1,162 @@
+package me.Danker.features.puzzlesolvers;
+
+import me.Danker.DankersSkyblockMod;
+import me.Danker.commands.MoveCommand;
+import me.Danker.commands.ScaleCommand;
+import me.Danker.commands.ToggleCommand;
+import me.Danker.events.RenderOverlay;
+import me.Danker.handlers.TextRenderer;
+import me.Danker.utils.Utils;
+import net.minecraft.block.Block;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.entity.EntityPlayerSP;
+import net.minecraft.init.Blocks;
+import net.minecraft.util.BlockPos;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.world.World;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+
+public class WaterSolver {
+
+ static boolean prevInWaterRoom = false;
+ static boolean inWaterRoom = false;
+ static String waterAnswers = null;
+
+ @SubscribeEvent
+ public void onTick(TickEvent.ClientTickEvent event) {
+ if (event.phase != TickEvent.Phase.START) return;
+
+ Minecraft mc = Minecraft.getMinecraft();
+ EntityPlayerSP player = mc.thePlayer;
+ World world = mc.theWorld;
+ if (DankersSkyblockMod.tickAmount % 20 == 0) {
+ if (ToggleCommand.waterToggled && Utils.inDungeons && world != null && player != null) {
+ // multi thread block checking
+ new Thread(() -> {
+ prevInWaterRoom = inWaterRoom;
+ inWaterRoom = false;
+ boolean foundPiston = false;
+ boolean done = false;
+ for (int x = (int) (player.posX - 13); x <= player.posX + 13; x++) {
+ for (int z = (int) (player.posZ - 13); z <= player.posZ + 13; z++) {
+ BlockPos blockPos = new BlockPos(x, 54, z);
+ if (world.getBlockState(blockPos).getBlock() == Blocks.sticky_piston) {
+ foundPiston = true;
+ break;
+ }
+ }
+ if (foundPiston) break;
+ }
+
+ if (foundPiston) {
+ for (int x = (int) (player.posX - 25); x <= player.posX + 25; x++) {
+ for (int z = (int) (player.posZ - 25); z <= player.posZ + 25; z++) {
+ BlockPos blockPos = new BlockPos(x, 82, z);
+ if (world.getBlockState(blockPos).getBlock() == Blocks.piston_head) {
+ inWaterRoom = true;
+ if (!prevInWaterRoom) {
+ boolean foundGold = false;
+ boolean foundClay = false;
+ boolean foundEmerald = false;
+ boolean foundQuartz = false;
+ boolean foundDiamond = false;
+
+ // Detect first blocks near water stream
+ BlockPos scan1 = new BlockPos(x + 1, 78, z + 1);
+ BlockPos scan2 = new BlockPos(x - 1, 77, z - 1);
+ Iterable<BlockPos> blocks = BlockPos.getAllInBox(scan1, scan2);
+ for (BlockPos puzzleBlockPos : blocks) {
+ Block block = world.getBlockState(puzzleBlockPos).getBlock();
+ if (block == Blocks.gold_block) {
+ foundGold = true;
+ } else if (block == Blocks.hardened_clay) {
+ foundClay = true;
+ } else if (block == Blocks.emerald_block) {
+ foundEmerald = true;
+ } else if (block == Blocks.quartz_block) {
+ foundQuartz = true;
+ } else if (block == Blocks.diamond_block) {
+ foundDiamond = true;
+ }
+ }
+
+ int variant = 0;
+ if (foundGold && foundClay) {
+ variant = 1;
+ } else if (foundEmerald && foundQuartz) {
+ variant = 2;
+ } else if (foundQuartz && foundDiamond) {
+ variant = 3;
+ } else if (foundGold && foundQuartz) {
+ variant = 4;
+ }
+
+ // Return solution
+ String purple;
+ String orange;
+ String blue;
+ String green;
+ String red;
+ switch (variant) {
+ case 1:
+ purple = EnumChatFormatting.WHITE + "Quartz, " + EnumChatFormatting.YELLOW + "Gold, " + EnumChatFormatting.AQUA + "Diamond, " + EnumChatFormatting.RED + "Clay";
+ orange = EnumChatFormatting.YELLOW + "Gold, " + EnumChatFormatting.DARK_GRAY + "Coal, " + EnumChatFormatting.GREEN + "Emerald";
+ blue = EnumChatFormatting.WHITE + "Quartz, " + EnumChatFormatting.YELLOW + "Gold, " + EnumChatFormatting.GREEN + "Emerald, " + EnumChatFormatting.RED + "Clay";
+ green = EnumChatFormatting.GREEN + "Emerald";
+ red = EnumChatFormatting.GRAY + "None";
+ break;
+ case 2:
+ purple = EnumChatFormatting.DARK_GRAY + "Coal";
+ orange = EnumChatFormatting.WHITE + "Quartz, " + EnumChatFormatting.YELLOW + "Gold, " + EnumChatFormatting.GREEN + "Emerald, " + EnumChatFormatting.RED + "Clay";
+ blue = EnumChatFormatting.WHITE + "Quartz, " + EnumChatFormatting.AQUA + "Diamond, " + EnumChatFormatting.GREEN + "Emerald";
+ green = EnumChatFormatting.WHITE + "Quartz, " + EnumChatFormatting.GREEN + "Emerald";
+ red = EnumChatFormatting.WHITE + "Quartz, " + EnumChatFormatting.DARK_GRAY + "Coal, " + EnumChatFormatting.GREEN + "Emerald";
+ break;
+ case 3:
+ purple = EnumChatFormatting.WHITE + "Quartz, " + EnumChatFormatting.YELLOW + "Gold, " + EnumChatFormatting.AQUA + "Diamond";
+ orange = EnumChatFormatting.GREEN + "Emerald";
+ blue = EnumChatFormatting.WHITE + "Quartz, " + EnumChatFormatting.AQUA + "Diamond";
+ green = EnumChatFormatting.GRAY + "None";
+ red = EnumChatFormatting.YELLOW + "Gold, " + EnumChatFormatting.GREEN + "Emerald";
+ break;
+ case 4:
+ purple = EnumChatFormatting.WHITE + "Quartz, " + EnumChatFormatting.YELLOW + "Gold, " + EnumChatFormatting.GREEN + "Emerald, " + EnumChatFormatting.RED + "Clay";
+ orange = EnumChatFormatting.YELLOW + "Gold, " + EnumChatFormatting.DARK_GRAY + "Coal";
+ blue = EnumChatFormatting.WHITE + "Quartz, " + EnumChatFormatting.YELLOW + "Gold, " + EnumChatFormatting.DARK_GRAY + "Coal, " + EnumChatFormatting.GREEN + "Emerald, " + EnumChatFormatting.RED + "Clay";
+ green = EnumChatFormatting.YELLOW + "Gold, " + EnumChatFormatting.GREEN + "Emerald";
+ red = EnumChatFormatting.YELLOW + "Gold, " + EnumChatFormatting.AQUA + "Diamond, " + EnumChatFormatting.GREEN + "Emerald, " + EnumChatFormatting.RED + "Clay";
+ break;
+ default:
+ purple = orange = blue = green = red = DankersSkyblockMod.ERROR_COLOUR + "Error detecting water puzzle variant.";
+ break;
+ }
+ waterAnswers = DankersSkyblockMod.MAIN_COLOUR + "The following levers must be down:\n" +
+ EnumChatFormatting.DARK_PURPLE + "Purple: " + purple + "\n" +
+ EnumChatFormatting.GOLD + "Orange: " + orange + "\n" +
+ EnumChatFormatting.BLUE + "Blue: " + blue + "\n" +
+ EnumChatFormatting.GREEN + "Green: " + green + "\n" +
+ EnumChatFormatting.RED + "Red: " + red;
+ done = true;
+ break;
+ }
+ }
+ }
+ if (done) break;
+ }
+ } else {
+ waterAnswers = null;
+ }
+ }).start();
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void renderPlayerInfo(RenderOverlay event) {
+ if (ToggleCommand.waterToggled && Utils.inDungeons && waterAnswers != null) {
+ new TextRenderer(Minecraft.getMinecraft(), waterAnswers, MoveCommand.waterAnswerXY[0], MoveCommand.waterAnswerXY[1], ScaleCommand.waterAnswerScale);
+ }
+ }
+
+}