diff options
50 files changed, 1360 insertions, 233 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index bc66c1f29..90cbd240b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ + Added **Hide Repeated Catches** - Delete past catches of the same trophy fish from chat. - (Thanks appable0) + Added **Trophy Counter Design** - Change the way trophy fish messages gets displayed in the chat. - (Thanks appable0) + Added **CH Join** - Helps buy a Pass for accessing the Crystal Hollows if needed. ++ Added **Estimated Item Value** - Displays an estimated item value for the item you hover over. ### Garden Features + Added **Copper Price** - Show copper to coin prices inside the Sky Mart inventory. diff --git a/FEATURES.md b/FEATURES.md index 1e393809d..aedf7ea42 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -230,4 +230,5 @@ + **Particle Hider** - Hide blaze particles, fire block particles, fireball particles, near redstone particles, far particles or smoke particles. + Chicken Head Timer. + **rancher boots** speed display. -+ **CH Join** - Helps buy a Pass for accessing the Crystal Hollows if needed.
\ No newline at end of file ++ **CH Join** - Helps buy a Pass for accessing the Crystal Hollows if needed. ++ **Estimated Item Value** - Displays an estimated item value for the item you hover over.
\ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index f62bc6d21..291d66a20 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "at.hannibal2.skyhanni" -version = "0.17.Beta.27" +version = "0.17.Beta.28" // Toolchains: java { diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java index 72fec9e44..5a1a92a4b 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java @@ -28,6 +28,7 @@ import at.hannibal2.skyhanni.features.garden.*; import at.hannibal2.skyhanni.features.inventory.*; import at.hannibal2.skyhanni.features.itemabilities.FireVeilWandParticles; import at.hannibal2.skyhanni.features.itemabilities.abilitycooldown.ItemAbilityCooldown; +import at.hannibal2.skyhanni.features.minion.MinionCollectLogic; import at.hannibal2.skyhanni.features.minion.MinionFeatures; import at.hannibal2.skyhanni.features.misc.*; import at.hannibal2.skyhanni.features.misc.tiarelay.TiaRelayHelper; @@ -74,7 +75,7 @@ import java.util.List; public class SkyHanniMod { public static final String MODID = "skyhanni"; - public static final String VERSION = "0.17.Beta.27"; + public static final String VERSION = "0.17.Beta.28"; public static final String DEPENDENCIES = "after:notenoughupdates@[2.1.1,);"; @@ -116,7 +117,7 @@ public class SkyHanniMod { loadModule(new ItemTipHelper()); loadModule(new RenderLivingEntityHelper()); loadModule(new SkillExperience()); - loadModule(new InventoryData()); + loadModule(new OtherInventoryData()); loadModule(new TabListData()); loadModule(new RenderGuiData()); loadModule(new GardenCropMilestones()); @@ -238,6 +239,9 @@ public class SkyHanniMod { loadModule(new AnitaMedalProfit()); loadModule(new ComposterDisplay()); loadModule(new GardenComposterInventoryFeatures()); + loadModule(new MinionCollectLogic()); + loadModule(new PasteIntoSigns()); + loadModule(new EstimatedItemValue()); Commands.INSTANCE.init(); diff --git a/src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt b/src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt index d8c5f35de..733e8709f 100644 --- a/src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt @@ -8,6 +8,7 @@ import at.hannibal2.skyhanni.features.bazaar.BazaarApi import at.hannibal2.skyhanni.utils.ItemUtils.getLore import at.hannibal2.skyhanni.utils.ItemUtils.name import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.NEUItems import at.hannibal2.skyhanni.utils.StringUtils.removeColor import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import java.util.regex.Pattern @@ -27,7 +28,7 @@ class CollectionAPI { @SubscribeEvent fun onProfileDataLoad(event: ProfileApiDataLoadedEvent) { val profileData = event.profileData - val jsonElement = profileData["collection"]?: return + val jsonElement = profileData["collection"] ?: return val asJsonObject = jsonElement.asJsonObject ?: return for ((rawName, rawCounter) in asJsonObject.entrySet()) { val counter = rawCounter.asLong @@ -116,5 +117,15 @@ class CollectionAPI { } return null } + + // TODO add support for replenish (higher collection than actual items in inv) + fun addFromInventory(internalName: String, amount: Int) { + val name = NEUItems.getItemStack(internalName).name?.removeColor() ?: return + + val oldValue = collectionValue[name] ?: return + + val newValue = oldValue + amount + collectionValue[name] = newValue + } } }
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt b/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt index 75e31ab2a..dd10d8482 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt @@ -2,6 +2,7 @@ package at.hannibal2.skyhanni.config import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.ConfigLoadEvent +import at.hannibal2.skyhanni.features.garden.CropType import com.google.gson.GsonBuilder import io.github.moulberry.moulconfig.observer.PropertyTypeAdapterFactory import io.github.moulberry.moulconfig.processor.BuiltinMoulConfigGuis @@ -36,14 +37,24 @@ class ConfigManager { if (configFile!!.exists()) { try { - BufferedReader(InputStreamReader(FileInputStream(configFile!!), StandardCharsets.UTF_8)).use { reader -> - SkyHanniMod.feature = gson.fromJson( - reader, - Features::class.java - ) + val inputStreamReader = InputStreamReader(FileInputStream(configFile!!), StandardCharsets.UTF_8) + val bufferedReader = BufferedReader(inputStreamReader) + val builder = StringBuilder() + for (line in bufferedReader.lines()) { + val result = fixConfig(line) + builder.append(result) + builder.append("\n") } + + + SkyHanniMod.feature = gson.fromJson( + builder.toString(), + Features::class.java + ) logger.info("Loaded config from file") } catch (e: Exception) { + println("config error") + e.printStackTrace() val backupFile = configFile!!.resolveSibling("config-${System.currentTimeMillis()}-backup.json") logger.error( "Exception while reading $configFile. Will load blank config and save backup to $backupFile", @@ -75,6 +86,18 @@ class ConfigManager { ) } + private fun fixConfig(line: String): String { + var result = line + for (type in CropType.values()) { + val normal = "\"${type.cropName}\"" + val enumName = "\"${type.name}\"" + while (result.contains(normal)) { + result = result.replace(normal, enumName) + } + } + return result + } + fun saveConfig() { try { logger.info("Saving config file") diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Diana.java b/src/main/java/at/hannibal2/skyhanni/config/features/Diana.java index deac9d9c3..37032d25b 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/Diana.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/Diana.java @@ -25,6 +25,7 @@ public class Diana { @Expose @ConfigOption(name = "Griffin Burrows", desc = "") + @ConfigEditorBoolean public boolean griffinBurrows = false; @Expose @@ -33,10 +34,7 @@ public class Diana { public boolean burrowNearestWarp = false; @Expose - @ConfigOption( - name = "Warp Key", - desc = "Press this key to warp to nearest burrow waypoint." - ) + @ConfigOption(name = "Warp Key", desc = "Press this key to warp to nearest burrow waypoint.") @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE) public int keyBindWarp = Keyboard.KEY_NONE; diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/GUI.java b/src/main/java/at/hannibal2/skyhanni/config/features/GUI.java index eba1feea8..957f12f8f 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/GUI.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/GUI.java @@ -9,20 +9,12 @@ import org.lwjgl.input.Keyboard; public class GUI { - @ConfigOption( - name = "Edit GUI Locations", - desc = "Change the position of SkyHanni's overlays" - ) - @ConfigEditorButton( - buttonText = "Edit" - ) + @ConfigOption(name = "Edit GUI Locations", desc = "Change the position of SkyHanni's overlays") + @ConfigEditorButton(buttonText = "Edit") public Runnable positions = GuiEditManager::openGuiEditor; @Expose - @ConfigOption( - name = "Open Hotkey", - desc = "Press this key to open the GUI Editor." - ) + @ConfigOption(name = "Open Hotkey", desc = "Press this key to open the GUI Editor.") @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE) public int keyBindOpen = Keyboard.KEY_NONE; } diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java b/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java index 2414d4c35..e48d0eee7 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java @@ -639,19 +639,20 @@ public class Garden { @Expose @ConfigOption(name = "Farming Armor Drops", desc = "") - @ConfigEditorAccordion(id = 12) + + @ConfigEditorAccordion(id = 18) public boolean farmingArmorDrops = false; @Expose @ConfigOption(name = "Show Counter", desc = "Count all §9Cropie§7, §5Squash §7and §6Fermento §7dropped.") @ConfigEditorBoolean - @ConfigAccordionId(id = 12) + @ConfigAccordionId(id = 18) public boolean farmingArmorDropsEnabled = true; @Expose @ConfigOption(name = "Hide Chat", desc = "Hide the chat message when receiving a farming armor drop.") @ConfigEditorBoolean - @ConfigAccordionId(id = 12) + @ConfigAccordionId(id = 18) public boolean farmingArmorDropsHideChat = false; @Expose @@ -659,13 +660,13 @@ public class Garden { @Expose @ConfigOption(name = "Teleport Pads", desc = "") - @ConfigEditorAccordion(id = 12) + @ConfigEditorAccordion(id = 19) public boolean teleportPads = false; @Expose @ConfigOption(name = "Compact Name", desc = "Hide the 'Warp to' and 'No Destination' texts over teleport pads.") @ConfigEditorBoolean - @ConfigAccordionId(id = 12) + @ConfigAccordionId(id = 19) public boolean teleportPadsCompactName = false; @Expose diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Minions.java b/src/main/java/at/hannibal2/skyhanni/config/features/Minions.java index ce09318e9..593a95ba9 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/Minions.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/Minions.java @@ -11,6 +11,11 @@ public class Minions { @ConfigEditorBoolean public boolean nameDisplay = true; + @Expose + @ConfigOption(name = "Only Tier", desc = "Show only the tier number over the minion. (Useful for bingo)") + @ConfigEditorBoolean + public boolean nameOnlyTier = false; + @ConfigOption(name = "Last Clicked", desc = "") @ConfigEditorAccordion(id = 0) public boolean lastClickedMinion = false; diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java b/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java index 54e63c904..8b9ea625a 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java @@ -2,11 +2,9 @@ package at.hannibal2.skyhanni.config.features; import at.hannibal2.skyhanni.config.core.config.Position; import com.google.gson.annotations.Expose; -import io.github.moulberry.moulconfig.annotations.ConfigAccordionId; -import io.github.moulberry.moulconfig.annotations.ConfigEditorAccordion; -import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; -import io.github.moulberry.moulconfig.annotations.ConfigOption; +import io.github.moulberry.moulconfig.annotations.*; import io.github.moulberry.moulconfig.observer.Property; +import org.lwjgl.input.Keyboard; public class Misc { @@ -211,6 +209,32 @@ public class Misc { public Position chickenHeadTimerPosition = new Position(-372, 73, false, true); @Expose + @ConfigOption(name = "Estimated Item Value", desc = "(Enchantments, reforging stone prices, gemstones, gemstones, drill parts and more)") + @ConfigEditorAccordion(id = 11) + public boolean estimatedItemValue = false; + + @Expose + @ConfigOption(name = "Enable Estimated Price", desc = "Displays an estimated item value for the item you hover over.") + @ConfigEditorBoolean + @ConfigAccordionId(id = 11) + public boolean estimatedIemValueEnabled = false; + + @Expose + @ConfigOption(name = "Hotkey", desc = "Press this key to show the estimated item value.") + @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE) + @ConfigAccordionId(id = 11) + public int estimatedItemValueHotkey = Keyboard.KEY_NONE; + + @Expose + @ConfigOption(name = "Show always", desc = "Ignore the hotkey and always display the item value.") + @ConfigEditorBoolean + @ConfigAccordionId(id = 11) + public boolean estimatedIemValueAlwaysEnabled = true; + + @Expose + public Position itemPriceDataPos = new Position(140, 90, false, true); + + @Expose @ConfigOption(name = "Exp Bottles", desc = "Hides all the experience orbs lying on the ground.") @ConfigEditorBoolean public boolean hideExpBottles = false; @@ -244,6 +268,11 @@ public class Misc { public boolean hideFireOverlay = false; @Expose + @ConfigOption(name = "Paste Into Signs", desc = "Allows you to paste the clipboard into Sings when you press Ctrl + V") + @ConfigEditorBoolean + public boolean pasteIntoSigns = true; + + @Expose @ConfigOption(name = "Config Button", desc = "Add a button to the pause menu to configure SkyHanni.") @ConfigEditorBoolean public boolean configButtonOnPause = true; diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Slayer.java b/src/main/java/at/hannibal2/skyhanni/config/features/Slayer.java index 0338f713c..eb9bd078a 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/Slayer.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/Slayer.java @@ -95,4 +95,9 @@ public class Slayer { @ConfigOption(name = "Quest Warning", desc = "Warning when wrong slayer quest is selected, or killing mobs for the wrong slayer.") @ConfigEditorBoolean public boolean questWarning = true; + + @Expose + @ConfigOption(name = "Quest Warning Title", desc = "Sends a Title when warning.") + @ConfigEditorBoolean + public boolean questWarningTitle = true; } diff --git a/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt b/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt index b55840b39..a21b9e133 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt @@ -7,7 +7,9 @@ import at.hannibal2.skyhanni.events.SeaCreatureFishEvent import at.hannibal2.skyhanni.features.fishing.SeaCreatureManager import at.hannibal2.skyhanni.utils.LorenzLogger import at.hannibal2.skyhanni.utils.LorenzUtils +import net.minecraft.event.HoverEvent import net.minecraft.network.play.server.S02PacketChat +import net.minecraft.util.IChatComponent import net.minecraftforge.client.event.ClientChatReceivedEvent import net.minecraftforge.fml.common.eventhandler.EventPriority import net.minecraftforge.fml.common.eventhandler.SubscribeEvent @@ -43,7 +45,7 @@ class ChatManager { if (message.startsWith("§f{\"server\":\"")) return val chatEvent = LorenzChatEvent(message, original) - if (!event.message.toString().contains("(held item preview from soopy using [hand])")) { + if (!isSoopyMessage(event.message)) { chatEvent.postAndCatch() } @@ -68,6 +70,36 @@ class ChatManager { } } + private fun isSoopyMessage(message: IChatComponent): Boolean { + for (sibling in message.siblings) { + if (isSoopyMessage(sibling)) return true + } + + val style = message.chatStyle ?: return false + val hoverEvent = style.chatHoverEvent ?: return false + if (hoverEvent.action != HoverEvent.Action.SHOW_TEXT) return false + val text = hoverEvent.value?.formattedText ?: return false + + val lines = text.split("\n") + if (lines.isEmpty()) return false + + val last = lines.last() + if (last.startsWith("§f§lCOMMON")) return true + if (last.startsWith("§f§lCOMMON")) return true + if (last.startsWith("§a§lUNCOMMON")) return true + if (last.startsWith("§9§lRARE")) return true + if (last.startsWith("§5§lEPIC")) return true + if (last.startsWith("§6§lLEGENDARY")) return true + if (last.startsWith("§c§lSPECIAL")) return true + + // TODO confirm this format is correct + if (last.startsWith("§c§lVERY SPECIAL")) return true + + if (last.startsWith("§d§lMYTHIC")) return true + + return false + } + @SubscribeEvent fun onChatMessage(chatEvent: LorenzChatEvent) { if (!LorenzUtils.inSkyBlock) return diff --git a/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt b/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt index 5294d79a1..5d9fb4713 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt @@ -3,9 +3,9 @@ package at.hannibal2.skyhanni.data import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.CropMilestoneUpdateEvent import at.hannibal2.skyhanni.events.InventoryOpenEvent -import at.hannibal2.skyhanni.events.ProfileJoinEvent import at.hannibal2.skyhanni.features.garden.CropType import at.hannibal2.skyhanni.utils.ItemUtils.getLore +import net.minecraftforge.event.world.WorldEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import java.util.regex.Pattern @@ -27,7 +27,7 @@ class GardenCropMilestones { // } @SubscribeEvent - fun onProfileJoin(event: ProfileJoinEvent) { + fun onWorldChange(event: WorldEvent.Load) { if (cropCounter.isEmpty()) { for (crop in CropType.values()) { crop.setCounter(0) diff --git a/src/main/java/at/hannibal2/skyhanni/data/GuiEditManager.kt b/src/main/java/at/hannibal2/skyhanni/data/GuiEditManager.kt index 7beaff605..cf4b0498e 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/GuiEditManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/GuiEditManager.kt @@ -6,6 +6,8 @@ import at.hannibal2.skyhanni.config.core.config.gui.GuiPositionEditor import at.hannibal2.skyhanni.events.GuiRenderEvent import at.hannibal2.skyhanni.utils.LorenzUtils import io.github.moulberry.notenoughupdates.NEUOverlay +import io.github.moulberry.notenoughupdates.overlays.AuctionSearchOverlay +import io.github.moulberry.notenoughupdates.overlays.BazaarSearchOverlay import net.minecraft.client.Minecraft import net.minecraft.client.gui.inventory.GuiChest import net.minecraft.client.gui.inventory.GuiEditSign @@ -30,11 +32,14 @@ class GuiEditManager { if (!Keyboard.getEventKeyState()) return val key = if (Keyboard.getEventKey() == 0) Keyboard.getEventCharacter().code + 256 else Keyboard.getEventKey() - if (SkyHanniMod.feature.gui.keyBindOpen == key) { - if (NEUOverlay.searchBarHasFocus) return - if (isInGui()) return - openGuiEditor() - } + if (SkyHanniMod.feature.gui.keyBindOpen != key) return + + if (NEUOverlay.searchBarHasFocus) return + if (AuctionSearchOverlay.shouldReplace()) return + if (BazaarSearchOverlay.shouldReplace()) return + + if (isInGui()) return + openGuiEditor() } @SubscribeEvent(priority = EventPriority.LOWEST) diff --git a/src/main/java/at/hannibal2/skyhanni/data/HyPixelData.kt b/src/main/java/at/hannibal2/skyhanni/data/HyPixelData.kt index 3d5232dff..2b5c3569f 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/HyPixelData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/HyPixelData.kt @@ -104,7 +104,7 @@ class HyPixelData { for (line in ScoreboardData.sidebarLinesFormatted) { when (line) { " §7Ⓑ §7Bingo", // No Rank - " §bⒷ §bBingo", // Rank 1 + " §aⒷ §aBingo", // Rank 1 " §9Ⓑ §9Bingo", // Rank 2 " §5Ⓑ §5Bingo", // Rank 3 " §6Ⓑ §6Bingo", // Rank 4 diff --git a/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt b/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt index fc68e1a52..eb6e20590 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt @@ -23,12 +23,13 @@ class ItemClickData { val position = packet.position.toLorenzVec() BlockClickEvent(ClickType.RIGHT_CLICK, position, packet.stack).postAndCatch() } - val itemInHand = Minecraft.getMinecraft().thePlayer.heldItem if (packet is C07PacketPlayerDigging && packet.status == C07PacketPlayerDigging.Action.START_DESTROY_BLOCK) { + val itemInHand = Minecraft.getMinecraft().thePlayer.heldItem val position = packet.position.toLorenzVec() BlockClickEvent(ClickType.LEFT_CLICK, position, itemInHand).postAndCatch() } if (packet is C0APacketAnimation) { + val itemInHand = Minecraft.getMinecraft().thePlayer.heldItem ItemClickEvent(itemInHand).postAndCatch() } } diff --git a/src/main/java/at/hannibal2/skyhanni/data/InventoryData.kt b/src/main/java/at/hannibal2/skyhanni/data/OtherInventoryData.kt index d3630c159..580383e0c 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/InventoryData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/OtherInventoryData.kt @@ -7,7 +7,7 @@ import net.minecraft.network.play.server.S2FPacketSetSlot import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import net.minecraftforge.fml.common.gameevent.TickEvent -class InventoryData { +class OtherInventoryData { private var currentInventory: Inventory? = null private var acceptItems = false private var lateEvent: LateInventoryOpenEvent? = null diff --git a/src/main/java/at/hannibal2/skyhanni/data/OwnInventoryData.kt b/src/main/java/at/hannibal2/skyhanni/data/OwnInventoryData.kt index 1572468d8..5bafff0ba 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/OwnInventoryData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/OwnInventoryData.kt @@ -1,19 +1,29 @@ package at.hannibal2.skyhanni.data +import at.hannibal2.skyhanni.api.CollectionAPI +import at.hannibal2.skyhanni.events.InventoryCloseEvent import at.hannibal2.skyhanni.events.OwnInventorItemUpdateEvent import at.hannibal2.skyhanni.events.PacketEvent +import at.hannibal2.skyhanni.features.bazaar.BazaarApi +import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName +import at.hannibal2.skyhanni.utils.ItemUtils.name +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.NEUItems +import net.minecraft.item.ItemStack import net.minecraft.network.play.server.S2FPacketSetSlot +import net.minecraftforge.event.world.WorldEvent import net.minecraftforge.fml.common.eventhandler.EventPriority import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class OwnInventoryData { -// private var itemNames = mutableMapOf<Int, String>() -// private var itemAmount = mutableMapOf<Int, Int>() -// private var counter = mutableMapOf<String, Int>() + private var itemNames = mutableMapOf<Int, String>() + private var itemAmount = mutableMapOf<Int, Int>() @SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true) fun onChatPacket(event: PacketEvent.ReceiveEvent) { + if (!LorenzUtils.inSkyBlock) return + val packet = event.packet if (packet is S2FPacketSetSlot) { val windowId = packet.func_149175_c() @@ -22,57 +32,68 @@ class OwnInventoryData { OwnInventorItemUpdateEvent(item).postAndCatch() } } -// if (packet is S2FPacketSetSlot) { -//// println("S2FPacketSetSlot") -// val windowId = packet.func_149175_c() -// val item = packet.func_149174_e() -// val slot = packet.func_149173_d() -// if (windowId != 0) return -// -// val name = item?.name ?: "null" -// -// val oldItem = itemNames.getOrDefault(slot, "null") -// val oldAmount = itemAmount.getOrDefault(slot, 0) -// -//// println(" ") -//// println("windowId: $windowId") -// val amount = item?.stackSize ?: 0 -// if (name == oldItem) { -// if (amount > oldAmount) { -// val diff = amount - oldAmount -//// println("added $diff $name") -// add(name, diff) -// } -// } else { -// if (name != "null") { -//// println("added new $amount $name") -// add(name, amount) -// } -// } -//// println("$slot $oldItem x$oldAmount -> $name x$amount") -// itemNames[slot] = name -// itemAmount[slot] = amount -// } + if (packet is S2FPacketSetSlot) { + val windowId = packet.func_149175_c() + val item = packet.func_149174_e() + val slot = packet.func_149173_d() + if (windowId != 0) return + val name = item?.name ?: "null" + + val oldItem = itemNames.getOrDefault(slot, "null") + val oldAmount = itemAmount.getOrDefault(slot, 0) + + val amount = item?.stackSize ?: 0 + if (name == oldItem) { + val diff = amount - oldAmount + if (amount > oldAmount) { + add(item, diff) + } + } else { + if (name != "null") { + add(item, amount) + } + } + itemNames[slot] = name + itemAmount[slot] = amount + } + } + + @SubscribeEvent + fun onInventoryClose(event: InventoryCloseEvent) { + BazaarApi.inBazaarInventory = false + lastClose = System.currentTimeMillis() + } + + @SubscribeEvent + fun onWorldLoad(event: WorldEvent.Load) { + lastWorldSwitch = System.currentTimeMillis() } -// private fun add(name: String, add: Int) { -// if (name == "§fHay Bale") return -// if (name == "§fSeeds") return -// if (name.contains("Hoe")) return -// -// // TODO remove later -// if (name.contains("Mushroom")) return -// -//// println("added $add $name") -// val old = counter.getOrDefault(name, 0) -//// if (name == "§fWheat") { -//// if (old == 1502) { -//// old = 2504173 -//// } -//// } -// val new = old + add -// val format = LorenzUtils.formatInteger(new) -// println("have $name $format") -// counter[name] = new -// } + private var lastClose = 0L + private var lastWorldSwitch = 0L + + private fun add(item: ItemStack?, add: Int) { + if (item == null) return + + val diffClose = System.currentTimeMillis() - lastClose + if (diffClose < 500) return + + val diffWorld = System.currentTimeMillis() - lastWorldSwitch + if (diffWorld < 3_000) return + + val internalName = item.getInternalName() + val (_, amount) = NEUItems.getMultiplier(internalName) + if (amount > 1) return + + if (internalName == "") { + LorenzUtils.debug("OwnInventoryData add is empty for: '$internalName'") + return + } + + addMultiplier(internalName, add) + } + + private fun addMultiplier(internalName: String, amount: Int) { + CollectionAPI.addFromInventory(internalName, amount) + } }
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/events/InventoryCloseEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/InventoryCloseEvent.kt index 8ff1f481b..2aa1ec65a 100644 --- a/src/main/java/at/hannibal2/skyhanni/events/InventoryCloseEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/events/InventoryCloseEvent.kt @@ -1,5 +1,11 @@ package at.hannibal2.skyhanni.events -import at.hannibal2.skyhanni.data.InventoryData +import at.hannibal2.skyhanni.data.OtherInventoryData +import net.minecraft.item.ItemStack -class InventoryCloseEvent(val inventory: InventoryData.Inventory): LorenzEvent()
\ No newline at end of file +class InventoryCloseEvent(val inventory: OtherInventoryData.Inventory): LorenzEvent() { + val inventoryId: Int by lazy { inventory.windowId } + val inventoryName: String by lazy {inventory.title } + val inventorySize: Int by lazy {inventory.slotCount } + val inventoryItems: MutableMap<Int, ItemStack> by lazy {inventory.items } +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/events/InventoryOpenEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/InventoryOpenEvent.kt index aec3e6542..3c95e4507 100644 --- a/src/main/java/at/hannibal2/skyhanni/events/InventoryOpenEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/events/InventoryOpenEvent.kt @@ -1,16 +1,16 @@ package at.hannibal2.skyhanni.events -import at.hannibal2.skyhanni.data.InventoryData +import at.hannibal2.skyhanni.data.OtherInventoryData import net.minecraft.item.ItemStack -open class BaseInventoryOpenEvent(inventory: InventoryData.Inventory): LorenzEvent() { +open class BaseInventoryOpenEvent(inventory: OtherInventoryData.Inventory): LorenzEvent() { val inventoryId: Int by lazy { inventory.windowId } val inventoryName: String by lazy {inventory.title } val inventorySize: Int by lazy {inventory.slotCount } val inventoryItems: MutableMap<Int, ItemStack> by lazy {inventory.items } } -class InventoryOpenEvent(inventory: InventoryData.Inventory): BaseInventoryOpenEvent(inventory) +class InventoryOpenEvent(inventory: OtherInventoryData.Inventory): BaseInventoryOpenEvent(inventory) // Firing with items that are added later -class LateInventoryOpenEvent(inventory: InventoryData.Inventory): BaseInventoryOpenEvent(inventory)
\ No newline at end of file +class LateInventoryOpenEvent(inventory: OtherInventoryData.Inventory): BaseInventoryOpenEvent(inventory)
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardDisplay.kt index eae5215ba..b00a7de19 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardDisplay.kt @@ -127,7 +127,7 @@ class BingoCardDisplay { private fun drawDisplay(): MutableList<String> { val newList = mutableListOf<String>() - newList.add("Community Goals") + newList.add("§6Community Goals:") if (communityGoals.isEmpty()) { newList.add("§cOpen the §e/bingo §ccard.") } else { @@ -136,7 +136,7 @@ class BingoCardDisplay { val todo = personalGoals.filter { !it.done } val done = MAX_PERSONAL_GOALS - todo.size newList.add(" ") - newList.add("Personal Goals: ($done/$MAX_PERSONAL_GOALS done)") + newList.add("§6Personal Goals: ($done/$MAX_PERSONAL_GOALS done)") todo.mapTo(newList) { " " + it.description } } return newList diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoNextStepHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoNextStepHelper.kt index af909605e..791680545 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoNextStepHelper.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoNextStepHelper.kt @@ -47,7 +47,7 @@ class BingoNextStepHelper { private fun drawDisplay(print: Boolean): MutableList<String> { val newCurrentHelp = mutableListOf<String>() - newCurrentHelp.add("Bingo Step Helper") + newCurrentHelp.add("§6Bingo Step Helper:") if (currentSteps.isEmpty()) { newCurrentHelp.add("§cOpen the §e/bingo §ccard.") diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/CompactBingoChat.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/CompactBingoChat.kt index db4989621..bb1721397 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/bingo/CompactBingoChat.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/CompactBingoChat.kt @@ -96,6 +96,8 @@ class CompactBingoChat { private fun onBestiarityUpgrade(event: LorenzChatEvent) { val message = event.message + if (message.contains("§r§6§lBESTIARY MILESTONE")) return + if (message.startsWith(" §r§3§lBESTIARY §b§l")) { blockedBestiarity = true return diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/MinionCraftHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/MinionCraftHelper.kt index 88d69a672..fca965c15 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/bingo/MinionCraftHelper.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/MinionCraftHelper.kt @@ -3,6 +3,7 @@ package at.hannibal2.skyhanni.features.bingo import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.data.SendTitleHelper import at.hannibal2.skyhanni.events.GuiRenderEvent +import at.hannibal2.skyhanni.events.InventoryOpenEvent import at.hannibal2.skyhanni.events.ProfileJoinEvent import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName import at.hannibal2.skyhanni.utils.ItemUtils.name @@ -21,7 +22,6 @@ import net.minecraftforge.fml.common.gameevent.TickEvent import java.util.regex.Pattern class MinionCraftHelper { - private var minionNamePattern = Pattern.compile("(.*) Minion (.*)") private var tick = 0 private var display = listOf<String>() @@ -267,4 +267,20 @@ class MinionCraftHelper { } private fun isMinionName(itemName: String) = itemName.contains(" Minion ") && !itemName.contains(" Minion Skin") + + @SubscribeEvent + fun onInventoryOpen(event: InventoryOpenEvent) { + if (!LorenzUtils.isBingoProfile) return + if (event.inventoryName != "Crafted Minions") return + + for ((_, b) in event.inventoryItems) { + val name = b.name?: continue + if (!name.startsWith("§e")) continue + + val internalName = NEUItems.getInternalName("$name I") + if (!tierOneMinionsDone.contains(internalName)) { + tierOneMinionsDone.add(internalName) + } + } + } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt index fa6500bcb..0f51e65aa 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt @@ -42,12 +42,18 @@ class AnitaMedalProfit { fun onInventoryOpen(event: InventoryOpenEvent) { if (!config.anitaMedalProfitEnabled) return if (event.inventoryName != "Anita") return + if (GardenVisitorFeatures.inVisitorInventory) return inInventory = true val table = mutableMapOf<Pair<String, String>, Pair<Double, String>>() for ((_, item) in event.inventoryItems) { - readItem(item, table) + try { + readItem(item, table) + } catch (e: Throwable) { + LorenzUtils.error("Error in AnitaMedalProfit while reading item '$item'") + e.printStackTrace() + } } val newList = mutableListOf<List<Any>>() @@ -59,6 +65,10 @@ class AnitaMedalProfit { private fun readItem(item: ItemStack, table: MutableMap<Pair<String, String>, Pair<Double, String>>) { var itemName = item.name ?: return if (itemName == " ") return + if (itemName == "§cClose") return + if (itemName == "§eUnique Gold Medals") return + if (itemName == "§aMedal Trades") return + if (itemName.endsWith("Enchanted Book")) { itemName = item.getLore()[0] } @@ -69,11 +79,9 @@ class AnitaMedalProfit { val (name, amount) = ItemUtils.readItemAmount(itemName) if (name == null) return - val internalName = try { - NEUItems.getInternalName(name) - } catch (e: Exception) { - // TODO make a better alternative - item.getInternalName() + var internalName = NEUItems.getInternalNameOrNull(name) + if (internalName == null) { + internalName = item.getInternalName() } val itemPrice = NEUItems.getPrice(internalName) * amount diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/ComposterDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/ComposterDisplay.kt index 57cf15aa9..7f37c6867 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/ComposterDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/ComposterDisplay.kt @@ -56,6 +56,10 @@ class ComposterDisplay { val newList = mutableListOf<List<Any>>() newList.addAsSingletonList("§bComposter") + for (type in DataType.values()) { + if (!data.containsKey(type)) return + } + newList.add(DataType.TIME_LEFT.addToList(data)) val list = mutableListOf<Any>() diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/CropMoneyDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/CropMoneyDisplay.kt index bfc20a7cd..a09102033 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/CropMoneyDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/CropMoneyDisplay.kt @@ -202,7 +202,7 @@ class CropMoneyDisplay { val (newId, amount) = NEUItems.getMultiplier(internalName) if (amount < 10) continue val itemName = NEUItems.getItemStack(newId).name?.removeColor() ?: continue - val crop = GardenAPI.itemNameToCropName(itemName) + val crop = CropType.getByItemName(itemName) crop?.let { multipliers[internalName] = amount cropNames[internalName] = it diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt index 1d71c8553..d83399c77 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt @@ -19,14 +19,19 @@ enum class CropType(val cropName: String, val toolName: String, iconSupplier: () ; val icon by lazy { iconSupplier() } - override fun toString(): String { - return cropName - } companion object { - fun getByName(name: String) = values().firstOrNull { it.cropName == name } + fun getByName(cropName: String) = values().firstOrNull { it.cropName == cropName } // TODO find better name for this method fun getByNameNoNull(name: String) = getByName(name) ?: throw RuntimeException("No valid crop type '$name'") + + + fun getByItemName(itemName: String): CropType? { + if (itemName == "Red Mushroom" || itemName == "Brown Mushroom") { + return MUSHROOM + } + return getByName(itemName) + } } }
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/EliteFarmingWeight.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/EliteFarmingWeight.kt index b5a7b0720..6b94e0707 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/EliteFarmingWeight.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/EliteFarmingWeight.kt @@ -53,6 +53,7 @@ class EliteFarmingWeight { @SubscribeEvent fun onTick(event: TickEvent.ClientTickEvent) { + if (!isEnabled()) return if (tick++ % 5 != 0) return update() } @@ -230,8 +231,7 @@ class EliteFarmingWeight { result["rank"].asInt } catch (e: Exception) { - apiError = true - LorenzUtils.error("[SkyHanni] Failed to load farming weight data from elitebot.dev! please report this on discord!") + error() e.printStackTrace() -1 } @@ -262,8 +262,13 @@ class EliteFarmingWeight { println("url: '$url'") e.printStackTrace() } + error() + } + + private fun error() { apiError = true - LorenzUtils.error("[SkyHanni] Failed to load farming weight data from elitebot.dev! please report this on discord!") + LorenzUtils.error("[SkyHanni] Loading the farming weight data from elitebot.dev failed!") + LorenzUtils.chat("§eYou can re-enter the garden to try to fix the problem. If this message repeats itself, please report it on Discord!") } private fun calculateCollectionWeight(round: Boolean = true): MutableMap<CropType, Double> { diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt index 67b543c03..534c88ac4 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt @@ -2,10 +2,10 @@ package at.hannibal2.skyhanni.features.garden import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.data.IslandType +import at.hannibal2.skyhanni.data.ScoreboardData import at.hannibal2.skyhanni.events.* import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.NEUItems import net.minecraft.client.Minecraft import net.minecraft.item.ItemStack import net.minecraft.network.play.client.C09PacketHeldItemChange @@ -35,6 +35,8 @@ class GardenAPI { if (!inGarden()) return tick++ if (tick % 10 == 0) { + onBarnPlot = ScoreboardData.sidebarLinesFormatted.contains(" §7⏣ §aThe Garden") + // We ignore random hypixel moments Minecraft.getMinecraft().currentScreen ?: return checkItemInHand() @@ -80,6 +82,7 @@ class GardenAPI { private val cropsPerSecond: MutableMap<CropType, Int> get() = SkyHanniMod.feature.hidden.gardenCropsPerSecond var cropInHand: CropType? = null var mushroomCowPet = false + var onBarnPlot = false fun inGarden() = LorenzUtils.inSkyBlock && LorenzUtils.skyBlockIsland == IslandType.GARDEN @@ -121,13 +124,6 @@ class GardenAPI { cropsPerSecond[this] = speed } - fun itemNameToCropName(itemName: String): CropType? { - if (itemName == "Red Mushroom" || itemName == "Brown Mushroom") { - return CropType.MUSHROOM - } - return CropType.getByName(itemName) - } - fun addGardenCropToList(crop: CropType, list: MutableList<Any>) { try { list.add(crop.icon) diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneDisplay.kt index b1186f533..ca118f665 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneDisplay.kt @@ -316,7 +316,7 @@ class GardenCropMilestoneDisplay { lastPlaySoundTime = System.currentTimeMillis() sound.playSound() } - SendTitleHelper.sendTitle("§b$crop $nextTier in $duration", 1_500) + SendTitleHelper.sendTitle("§b${crop.cropName} $nextTier in $duration", 1_500) } } lineMap[3] = Collections.singletonList("§7In §b$duration") diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenInventoryNumbers.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenInventoryNumbers.kt index 76770e182..708a50be9 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenInventoryNumbers.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenInventoryNumbers.kt @@ -12,7 +12,7 @@ import java.util.regex.Pattern class GardenInventoryNumbers { private var patternTierProgress = Pattern.compile("§7Progress to Tier (.*): §e(?:.*)") - private var patternUpgradeTier = Pattern.compile("§7Current Tier: §e(.*)§7/§a.*") + private var patternUpgradeTier = Pattern.compile("§7Current Tier: §[ea](.*)§7/§a.*") private val patternComposterUpgrades = Pattern.compile("§a(?:Composter Speed|Multi Drop|Fuel Cap|Organic Matter Cap|Cost Reduction) ?(.*)?") diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt index 2a1f8b4dc..5c1b83610 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt @@ -13,7 +13,6 @@ import at.hannibal2.skyhanni.utils.renderables.Renderable import io.github.moulberry.notenoughupdates.mixins.AccessorGuiEditSign import net.minecraft.client.Minecraft import net.minecraft.client.gui.inventory.GuiEditSign -import net.minecraft.util.ChatComponentText import net.minecraftforge.client.event.GuiOpenEvent import net.minecraftforge.client.event.GuiScreenEvent.DrawScreenEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent @@ -39,15 +38,11 @@ class GardenOptimalSpeed { } } - @SubscribeEvent fun onGuiOpen(event: GuiOpenEvent) { rancherOverlayList = CropType.values().map { crop -> listOf(crop.icon, Renderable.link("${crop.cropName} - ${crop.getOptimalSpeed()}") { - val gui = Minecraft.getMinecraft().currentScreen - if (gui !is GuiEditSign) return@link - gui as AccessorGuiEditSign - gui.tileSign.signText[0] = ChatComponentText("${crop.getOptimalSpeed()}") + LorenzUtils.setTextIntoSign("${crop.getOptimalSpeed()}") }) } } @@ -92,27 +87,31 @@ class GardenOptimalSpeed { @SubscribeEvent fun onRenderOverlay(event: GuiRenderEvent.GameOverlayRenderEvent) { if (!isEnabled()) return - if (!Minecraft.getMinecraft().thePlayer.onGround) return if (optimalSpeed == -1) return val text = "Optimal Speed: §f$optimalSpeed" if (optimalSpeed != currentSpeed) { config.optimalSpeedPos.renderString("§c$text", posLabel = "Garden Optimal Speed") - if (config.optimalSpeedWarning) { - if (System.currentTimeMillis() > lastWarnTime + 20_000) { - lastWarnTime = System.currentTimeMillis() - SendTitleHelper.sendTitle("§cWrong speed!", 3_000) - cropInHand?.let { - LorenzUtils.chat("§e[SkyHanni] Wrong speed for $it: §f$currentSpeed §e(§f$optimalSpeed §eis optimal)") - } - } - } + warn() } else { config.optimalSpeedPos.renderString("§a$text", posLabel = "Garden Optimal Speed") } } + private fun warn() { + if (!config.optimalSpeedWarning) return + if (!Minecraft.getMinecraft().thePlayer.onGround) return + if (GardenAPI.onBarnPlot) return + if (System.currentTimeMillis() < lastWarnTime + 20_000) return + + lastWarnTime = System.currentTimeMillis() + SendTitleHelper.sendTitle("§cWrong speed!", 3_000) + cropInHand?.let { + LorenzUtils.chat("§e[SkyHanni] Wrong speed for ${it.cropName}: §f$currentSpeed §e(§f$optimalSpeed §eis optimal)") + } + } + private fun isRancherOverlayEnabled() = GardenAPI.inGarden() && config.optimalSpeedSignEnabled private fun isEnabled() = GardenAPI.inGarden() && config.optimalSpeedEnabled }
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt index 917b40b85..25495a596 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt @@ -1,7 +1,6 @@ package at.hannibal2.skyhanni.features.garden import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.data.ScoreboardData.Companion.sidebarLinesFormatted import at.hannibal2.skyhanni.data.SendTitleHelper import at.hannibal2.skyhanni.events.* import at.hannibal2.skyhanni.features.garden.GardenAPI.Companion.getSpeed @@ -29,11 +28,9 @@ import net.minecraftforge.fml.common.gameevent.TickEvent import java.util.regex.Pattern class GardenVisitorFeatures { - private val visitors = mutableMapOf<String, Visitor>() private var display = listOf<List<Any>>() private var lastClickedNpc = 0 - private var onBarnPlot = false private var tick = 0 private val copperPattern = Pattern.compile(" §8\\+§c(.*) Copper") private val gardenExperiencePattern = Pattern.compile(" §8\\+§2(.*) §7Garden Experience") @@ -180,6 +177,7 @@ class GardenVisitorFeatures { @SubscribeEvent(priority = EventPriority.HIGH) fun onStackClick(event: SlotClickEvent) { if (!inVisitorInventory) return + if (event.slot.stack?.name != "§cRefuse Offer") return if (event.slotId != 33) return getVisitor(lastClickedNpc)?.let { @@ -195,7 +193,7 @@ class GardenVisitorFeatures { @SubscribeEvent fun onCheckRender(event: CheckRenderEntityEvent<*>) { if (!GardenAPI.inGarden()) return - if (!onBarnPlot) return + if (!GardenAPI.onBarnPlot) return if (config.visitorHighlightStatus != 1 && config.visitorHighlightStatus != 2) return val entity = event.entity @@ -209,7 +207,7 @@ class GardenVisitorFeatures { @SubscribeEvent fun onRenderWorld(event: RenderWorldLastEvent) { if (!GardenAPI.inGarden()) return - if (!onBarnPlot) return + if (!GardenAPI.onBarnPlot) return if (config.visitorHighlightStatus != 1 && config.visitorHighlightStatus != 2) return for (visitor in visitors.values) { @@ -274,7 +272,7 @@ class GardenVisitorFeatures { if (config.visitorExactAmountAndTime) { val multiplier = NEUItems.getMultiplier(internalName) val rawName = NEUItems.getItemStack(multiplier.first).name?.removeColor() ?: continue - CropType.getByName(rawName)?.let { + CropType.getByItemName(rawName)?.let { val speed = it.getSpeed() val cropAmount = multiplier.second.toLong() * amount val formatAmount = LorenzUtils.formatInteger(cropAmount) @@ -318,11 +316,9 @@ class GardenVisitorFeatures { fun onTick(event: TickEvent.ClientTickEvent) { if (!GardenAPI.inGarden()) return if (!config.visitorNeedsDisplay && config.visitorHighlightStatus == 3) return - if (tick++ % 30 != 0) return - - onBarnPlot = sidebarLinesFormatted.contains(" §7⏣ §aThe Garden") + if (tick++ % 10 != 0) return - if (onBarnPlot && config.visitorHighlightStatus != 3) { + if (GardenAPI.onBarnPlot && config.visitorHighlightStatus != 3) { checkVisitorsReady() } } @@ -510,10 +506,7 @@ class GardenVisitorFeatures { if (!GardenAPI.inGarden()) return if (!config.visitorNeedsDisplay) return - if (config.visitorNeedsOnlyWhenClose) { - //TODO check if on barn plot (sidebar) - if (!onBarnPlot) return - } + if (config.visitorNeedsOnlyWhenClose && !GardenAPI.onBarnPlot) return config.visitorNeedsPos.renderStringsAndItems(display, posLabel = "Visitor Items Needed") } diff --git a/src/main/java/at/hannibal2/skyhanni/features/minion/MinionCollectLogic.kt b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionCollectLogic.kt new file mode 100644 index 000000000..d6f971ec3 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionCollectLogic.kt @@ -0,0 +1,66 @@ +package at.hannibal2.skyhanni.features.minion + +import at.hannibal2.skyhanni.api.CollectionAPI +import at.hannibal2.skyhanni.data.IslandType +import at.hannibal2.skyhanni.events.GuiContainerEvent +import at.hannibal2.skyhanni.events.InventoryOpenEvent +import at.hannibal2.skyhanni.utils.InventoryUtils +import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName +import at.hannibal2.skyhanni.utils.ItemUtils.name +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.NEUItems +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class MinionCollectLogic { + private var oldMap = mapOf<String, Int>() + + @SubscribeEvent + fun onInventoryOpen(event: InventoryOpenEvent) { + if (!LorenzUtils.inSkyBlock) return + if (LorenzUtils.skyBlockIsland != IslandType.PRIVATE_ISLAND) return + if (!event.inventoryName.contains(" Minion ")) return + + event.inventoryItems[48]?.let { + if ("§aCollect All" == it.name) { + openMinion() + } + } + } + + private fun openMinion() { + if (oldMap.isNotEmpty()) return + oldMap = count() + } + + private fun count(): MutableMap<String, Int> { + val map = mutableMapOf<String, Int>() + for (stack in InventoryUtils.getItemsInOwnInventory()) { + val internalName = stack.getInternalName() + val (newId, amount) = NEUItems.getMultiplier(internalName) + val old = map[newId] ?: 0 + map[newId] = old + amount * stack.stackSize + } + return map + } + + // hypixel opens a new inventory after clicking on an item in minion inventory, InventoryCloseEvent is not usable here + @SubscribeEvent + fun onCloseWindow(event: GuiContainerEvent.CloseWindowEvent) { + closeMinion() + } + + private fun closeMinion() { + if (oldMap.isEmpty()) return + + for ((internalId, amount) in count()) { + val old = oldMap[internalId] ?: 0 + val diff = amount - old + + if (diff > 0) { + CollectionAPI.addFromInventory(internalId, diff) + } + } + + oldMap = emptyMap() + } +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/minion/MinionData.kt b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionData.kt index 02ee25b51..e05e56544 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/minion/MinionData.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionData.kt @@ -2,4 +2,4 @@ package at.hannibal2.skyhanni.features.minion import scala.Serializable -class MinionData(var name: String,var lastClicked: Long) : Serializable
\ No newline at end of file +class MinionData(var displayName: String, var lastClicked: Long) : Serializable
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt index b6daa011f..e17e54263 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt @@ -10,6 +10,7 @@ import at.hannibal2.skyhanni.utils.ItemUtils.getLore import at.hannibal2.skyhanni.utils.ItemUtils.name import at.hannibal2.skyhanni.utils.LorenzUtils.formatInteger import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimal +import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded import at.hannibal2.skyhanni.utils.RenderUtils.drawString import at.hannibal2.skyhanni.utils.RenderUtils.renderString import at.hannibal2.skyhanni.utils.StringUtils.matchRegex @@ -26,9 +27,10 @@ import net.minecraftforge.fml.common.gameevent.InputEvent import net.minecraftforge.fml.common.gameevent.TickEvent import org.lwjgl.input.Mouse import java.awt.Color +import java.util.regex.Pattern class MinionFeatures { - + private val config get() = SkyHanniMod.feature.minions private var lastClickedEntity: LorenzVec? = null private var lastMinion: LorenzVec? = null private var lastMinionOpened = 0L @@ -38,6 +40,7 @@ class MinionFeatures { private var lastMinionPickedUp = 0L private val minions = mutableMapOf<LorenzVec, MinionData>() private var coinsPerDay = "" + private val minionUpgradePattern = Pattern.compile("§aYou have upgraded your Minion to Tier (.*)") @SubscribeEvent fun onConfigLoad(event: ConfigLoadEvent) { @@ -69,14 +72,14 @@ class MinionFeatures { fun onRenderLastClickedMinion(event: RenderWorldLastEvent) { if (!LorenzUtils.inSkyBlock) return if (LorenzUtils.skyBlockIsland != IslandType.PRIVATE_ISLAND) return - if (!SkyHanniMod.feature.minions.lastClickedMinionDisplay) return + if (!config.lastClickedMinionDisplay) return - val special = SkyHanniMod.feature.minions.lastOpenedMinionColor + val special = config.lastOpenedMinionColor val color = Color(SpecialColour.specialToChromaRGB(special), true) val loc = lastMinion if (loc != null) { - val time = SkyHanniMod.feature.minions.lastOpenedMinionTime * 1_000 + val time = config.lastOpenedMinionTime * 1_000 if (lastMinionOpened + time > System.currentTimeMillis()) { event.drawWaypointFilled( loc.add(-0.5, 0.0, -0.5), @@ -102,8 +105,8 @@ class MinionFeatures { minions[it] = MinionData(name, 0) saveConfig() } else { - if (minions[it]!!.name != name) { - minions[it]!!.name = name + if (minions[it]!!.displayName != name) { + minions[it]!!.displayName = name saveConfig() } } @@ -136,19 +139,17 @@ class MinionFeatures { } } - if (SkyHanniMod.feature.minions.hopperProfitDisplay) { + if (config.hopperProfitDisplay) { coinsPerDay = if (minionInventoryOpen) { updateCoinsPerDay() - } else { - "" - } + } else "" } } - private fun getMinionName(inventoryName: String): String { - var list = inventoryName.split(" ").toList() + private fun getMinionName(oldName: String, newTier: Int = 0): String { + var list = oldName.split(" ").toList() val last = list.last() - val number = last.romanToDecimal() + val number = if (newTier != 0) newTier else last.romanToDecimal() list = list.dropLast(1) return list.joinToString(" ") + " $number" @@ -189,7 +190,7 @@ class MinionFeatures { val coordinates = minion.key.encodeToString() val data = minion.value minionConfig[coordinates] = data.lastClicked - minionName[coordinates] = data.name + minionName[coordinates] = data.displayName } } @@ -206,12 +207,23 @@ class MinionFeatures { if (!LorenzUtils.inSkyBlock) return if (LorenzUtils.skyBlockIsland != IslandType.PRIVATE_ISLAND) return - if (event.message.matchRegex("§aYou received §r§6(.*) coins§r§a!")) { + val message = event.message + if (message.matchRegex("§aYou received §r§6(.*) coins§r§a!")) { lastCoinsRecived = System.currentTimeMillis() } - if (event.message.startsWith("§aYou picked up a minion!")) { + if (message.startsWith("§aYou picked up a minion!")) { lastMinionPickedUp = System.currentTimeMillis() } + + val matcher = minionUpgradePattern.matcher(message) + if (matcher.matches()) { + val newTier = matcher.group(1).romanToDecimalIfNeeded() + minions[lastMinion]?.let { + val minionName = getMinionName(it.displayName, newTier) + it.displayName = minionName + saveConfig() + } + } } @SubscribeEvent @@ -223,23 +235,25 @@ class MinionFeatures { val playerEyeLocation = LocationUtils.playerEyeLocation() for (minion in minions) { val location = minion.key.add(0.0, 1.0, 0.0) - if (LocationUtils.canSee(playerEyeLocation, location)) { - val lastEmptied = minion.value.lastClicked - if (playerLocation.distance(location) < SkyHanniMod.feature.minions.distance) { + if (!LocationUtils.canSee(playerEyeLocation, location)) continue - if (SkyHanniMod.feature.minions.nameDisplay) { - val name = "§9" + minion.value.name - event.drawString(location.add(0.0, 0.65, 0.0), name, true) - } + val lastEmptied = minion.value.lastClicked + if (playerLocation.distance(location) >= config.distance) continue - if (SkyHanniMod.feature.minions.emptiedTimeDisplay) { - if (lastEmptied != 0L) { - val duration = System.currentTimeMillis() - lastEmptied - val format = TimeUtils.formatDuration(duration, longName = true) + " ago" - val text = "§eHopper Emptied: $format" - event.drawString(location.add(0.0, 1.15, 0.0), text, true) - } - } + if (config.nameDisplay) { + val displayName = minion.value.displayName + val name = "§6" + if (config.nameOnlyTier) { + displayName.split(" ").last() + } else displayName + event.drawString(location.add(0.0, 0.65, 0.0), name, true) + } + + if (config.emptiedTimeDisplay) { + if (lastEmptied != 0L) { + val duration = System.currentTimeMillis() - lastEmptied + val format = TimeUtils.formatDuration(duration, longName = true) + " ago" + val text = "§eHopper Emptied: $format" + event.drawString(location.add(0.0, 1.15, 0.0), text, true) } } } @@ -249,7 +263,7 @@ class MinionFeatures { fun onRenderLiving(event: RenderLivingEvent.Specials.Pre<EntityLivingBase>) { if (!LorenzUtils.inSkyBlock) return if (LorenzUtils.skyBlockIsland != IslandType.PRIVATE_ISLAND) return - if (!SkyHanniMod.feature.minions.hideMobsNametagNearby) return + if (!config.hideMobsNametagNearby) return val entity = event.entity if (entity !is EntityArmorStand) return @@ -266,8 +280,8 @@ class MinionFeatures { @SubscribeEvent(priority = EventPriority.LOWEST) fun renderOverlay(event: GuiScreenEvent.BackgroundDrawnEvent) { - if (SkyHanniMod.feature.minions.hopperProfitDisplay) { - SkyHanniMod.feature.minions.hopperProfitPos.renderString(coinsPerDay, posLabel = "Minion Coins Per Day") + if (config.hopperProfitDisplay) { + config.hopperProfitPos.renderString(coinsPerDay, posLabel = "Minion Coins Per Day") } } }
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/EstimatedItemValue.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/EstimatedItemValue.kt new file mode 100644 index 000000000..a92dcf231 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/EstimatedItemValue.kt @@ -0,0 +1,527 @@ +package at.hannibal2.skyhanni.features.misc + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.GuiRenderEvent +import at.hannibal2.skyhanni.events.InventoryCloseEvent +import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName +import at.hannibal2.skyhanni.utils.ItemUtils.getLore +import at.hannibal2.skyhanni.utils.ItemUtils.name +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList +import at.hannibal2.skyhanni.utils.LorenzUtils.sortedDesc +import at.hannibal2.skyhanni.utils.NEUItems +import at.hannibal2.skyhanni.utils.NumberUtil +import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getAbilityScrolls +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getDrillUpgrades +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getEnchantments +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getFarmingForDummiesCount +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getGemstones +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getHotPotatoCount +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getManaDisintegrators +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getMasterStars +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getPowerScroll +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getReforgeName +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getSilexCount +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getTransmissionTunerCount +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasArtOfPiece +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasArtOfWar +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasBookOfStats +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasEtherwarp +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasJalapenoBook +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasWoodSingularity +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.isRecombobulated +import at.hannibal2.skyhanni.utils.StringUtils.removeColor +import io.github.moulberry.moulconfig.internal.KeybindHelper +import io.github.moulberry.notenoughupdates.util.Constants +import net.minecraft.init.Items +import net.minecraft.item.ItemStack +import net.minecraftforge.event.entity.player.ItemTooltipEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class EstimatedItemValue { + private val config get() = SkyHanniMod.feature.misc + private var display = listOf<List<Any>>() + private val cache = mutableMapOf<ItemStack, List<List<Any>>>() + private var lastToolTipTime = 0L + + @SubscribeEvent + fun onRenderOverlay(event: GuiRenderEvent.ChestBackgroundRenderEvent) { + if (!LorenzUtils.inSkyBlock) return + if (!config.estimatedIemValueEnabled) return + if (!KeybindHelper.isKeyDown(config.estimatedItemValueHotkey) && !config.estimatedIemValueAlwaysEnabled) return + if (System.currentTimeMillis() > lastToolTipTime + 200) return + + config.itemPriceDataPos.renderStringsAndItems(display, posLabel = "Estimated Item Value") + } + + @SubscribeEvent + fun onInventoryClose(event: InventoryCloseEvent) { + cache.clear() + } + + @SubscribeEvent + fun onItemTooltipLow(event: ItemTooltipEvent) { + if (!LorenzUtils.inSkyBlock) return + if (!config.estimatedIemValueEnabled) return + + val item = event.itemStack + val oldData = cache[item] + if (oldData != null) { + display = oldData + lastToolTipTime = System.currentTimeMillis() + return + } + + val newDisplay = try { + draw(item) + } catch (e: Exception) { + LorenzUtils.debug("Estimated Item Value error: ${e.message}") + e.printStackTrace() + listOf() + } + + cache[item] = newDisplay + display = newDisplay + lastToolTipTime = System.currentTimeMillis() + } + + private fun draw(stack: ItemStack): MutableList<List<Any>> { + val list = mutableListOf<String>() + list.add("§aEstimated Item Value:") + + val internalName = stack.getInternalName() + if (internalName == "") return mutableListOf() + + //FIX neu item list + if (internalName.startsWith("ULTIMATE_ULTIMATE_")) return mutableListOf() + if (stack.item == Items.enchanted_book) return mutableListOf() + + var totalPrice = 0.0 + val basePrice = addBaseItem(stack, list) + totalPrice += basePrice + totalPrice += addReforgeStone(stack, list) + + // once + totalPrice += addRecomb(stack, list) + totalPrice += addArtOfWar(stack, list) + totalPrice += addArtOfPiece(stack, list) + totalPrice += addEtherwarp(stack, list) + totalPrice += addPowerScrolls(stack, list) + totalPrice += addWoodSingularity(stack, list) + totalPrice += addJalapenoBook(stack, list) + + // counted + totalPrice += addMasterStars(stack, list) + totalPrice += addHotPotatoBooks(stack, list) + totalPrice += addFarmingForDummies(stack, list) + totalPrice += addSilex(stack, list) + totalPrice += addStatsBook(stack, list) + totalPrice += addTransmissionTuners(stack, list) + totalPrice += addManaDisintegrators(stack, list) + + // dynamic + totalPrice += addAbilityScrolls(stack, list) + totalPrice += addDrillUpgrades(stack, list) + totalPrice += addGemstones(stack, list) + totalPrice += addEnchantments(stack, list) + + if (basePrice == totalPrice) return mutableListOf() + + list.add("§aTotal: §6§l" + NumberUtil.format(totalPrice)) + + val newDisplay = mutableListOf<List<Any>>() + for (line in list) { + newDisplay.addAsSingletonList(line) + } + return newDisplay + } + + private fun addReforgeStone(stack: ItemStack, list: MutableList<String>): Double { + val rawReforgeName = stack.getReforgeName() ?: return 0.0 + + for ((internalName, values) in Constants.REFORGESTONES.entrySet()) { + val stone = values.asJsonObject + val reforgeName = stone.get("reforgeName").asString + if (rawReforgeName == reforgeName.lowercase()) { + val price = NEUItems.getPrice(internalName) + val name = NEUItems.getItemStack(internalName).name + list.add("§7Reforge: §9$reforgeName") + list.add(" §7($name §6" + NumberUtil.format(price) + "§7)") + return price + } + } + + return 0.0 + } + + private fun addRecomb(stack: ItemStack, list: MutableList<String>): Double { + if (stack.isRecombobulated()) { + val wtfHardcodedRecomb = "RECOMBOBULATOR_3000" + val price = NEUItems.getPrice(wtfHardcodedRecomb) + list.add("§7Recombobulated: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + return 0.0 + } + + private fun addJalapenoBook(stack: ItemStack, list: MutableList<String>): Double { + if (stack.hasJalapenoBook()) { + val wtfHardcodedJalapeno = "JALAPENO_BOOK" + + val price = NEUItems.getPrice(wtfHardcodedJalapeno) + list.add("§7Jalapeno Book: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + return 0.0 + } + + private fun addEtherwarp(stack: ItemStack, list: MutableList<String>): Double { + if (stack.hasEtherwarp()) { + val wtfHardcodedConduit = "ETHERWARP_CONDUIT" + val wtfHardcodedMerger = "ETHERWARP_MERGER" + val price = NEUItems.getPrice(wtfHardcodedConduit) + NEUItems.getPrice(wtfHardcodedMerger) + list.add("§7Etherwarp: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + return 0.0 + } + + private fun addWoodSingularity(stack: ItemStack, list: MutableList<String>): Double { + if (stack.hasWoodSingularity()) { + val wtfHardcodedSingularity = "WOOD_SINGULARITY" + val price = NEUItems.getPrice(wtfHardcodedSingularity) + list.add("§7Wood Singularity: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + return 0.0 + } + + private fun addArtOfWar(stack: ItemStack, list: MutableList<String>): Double { + if (stack.hasArtOfWar()) { + val ripTechno = "THE_ART_OF_WAR" + val price = NEUItems.getPrice(ripTechno) + list.add("§7The Art of War: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + return 0.0 + } + + private fun addStatsBook(stack: ItemStack, list: MutableList<String>): Double { + if (stack.hasBookOfStats()) { + val ripTechno = "BOOK_OF_STATS" + val price = NEUItems.getPrice(ripTechno) + list.add("§7Book of Stats: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + return 0.0 + } + + // TODO untested + private fun addArtOfPiece(stack: ItemStack, list: MutableList<String>): Double { + if (stack.hasArtOfPiece()) { + val ripTechno = "THE_ART_OF_PEACE" + val price = NEUItems.getPrice(ripTechno) + list.add("§7The Art Of Piece: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + return 0.0 + } + + private fun addHotPotatoBooks(stack: ItemStack, list: MutableList<String>): Double { + val count = stack.getHotPotatoCount() + if (count == 0) return 0.0 + + val hpb: Int + val fuming: Int + if (count <= 10) { + hpb = count + fuming = 0 + } else { + hpb = 10 + fuming = count - 10 + } + + var totalPrice = 0.0 + + val wtfHardcodedHpb = "HOT_POTATO_BOOK" + val hpbPrice = NEUItems.getPrice(wtfHardcodedHpb) * hpb + list.add("§7HPB's: §e$hpb§7/§e10 §7(§6" + NumberUtil.format(hpbPrice) + "§7)") + totalPrice += hpbPrice + + if (fuming > 0) { + val wtfHardcodedFuming = "FUMING_POTATO_BOOK" + val fumingPrice = NEUItems.getPrice(wtfHardcodedFuming) * fuming + list.add("§7Fuming: §e$fuming§7/§e5 §7(§6" + NumberUtil.format(fumingPrice) + "§7)") + totalPrice += fumingPrice + } + + return totalPrice + } + + private fun addFarmingForDummies(stack: ItemStack, list: MutableList<String>): Double { + val count = stack.getFarmingForDummiesCount() + if (count == 0) return 0.0 + + val wtfHardcodedDumbFarmers = "FARMING_FOR_DUMMIES" + val price = NEUItems.getPrice(wtfHardcodedDumbFarmers) * count + list.add("§7Farming for Dummies: §e$count§7/§e5 §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addSilex(stack: ItemStack, list: MutableList<String>): Double { + val tier = stack.getSilexCount() + if (tier == 0) return 0.0 + + val internalName = stack.getInternalName() + val maxTier = if (internalName == "STONK_PICKAXE") 4 else 5 + + val wtfHardcodedSilex = "SIL_EX" + val price = NEUItems.getPrice(wtfHardcodedSilex) * tier + list.add("§7Silex: §e$tier§7/§e$maxTier §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addTransmissionTuners(stack: ItemStack, list: MutableList<String>): Double { + val count = stack.getTransmissionTunerCount() + if (count == 0) return 0.0 + + val wtfHardcodedTuner = "TRANSMISSION_TUNER" + val price = NEUItems.getPrice(wtfHardcodedTuner) * count + list.add("§7Transmission Tuners: §e$count§7/§e4 §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addManaDisintegrators(stack: ItemStack, list: MutableList<String>): Double { + val count = stack.getManaDisintegrators() + if (count == 0) return 0.0 + + val wtfHardcodedTuner = "MANA_DISINTEGRATOR" + val price = NEUItems.getPrice(wtfHardcodedTuner) * count + list.add("§7Mana Disintegrators: §e$count§7/§e10 §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addMasterStars(stack: ItemStack, list: MutableList<String>): Double { + val masterStars = stack.getMasterStars() + if (masterStars == 0) return 0.0 + + var price = 0.0 + + val stars = mapOf( + "FIRST" to 1, + "SECOND" to 2, + "THIRD" to 3, + "FOURTH" to 4, + "FIFTH" to 5, + ) + + for ((prefix, number) in stars) { + if (masterStars >= number) { + val internalName = "${prefix}_MASTER_STAR" + price += NEUItems.getPrice(internalName) + } + } + + list.add("§7Master Stars: §e$masterStars§7/§e5 §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addDrillUpgrades(stack: ItemStack, list: MutableList<String>): Double { + var totalPrice = 0.0 + val map = mutableMapOf<String, Double>() + for (internalName in stack.getDrillUpgrades()) { + val name = NEUItems.getItemStackOrNull(internalName)!!.name + val price = NEUItems.getPriceOrNull(internalName) ?: continue + + totalPrice += price + val format = NumberUtil.format(price) + map[" $name §7(§6$format§7)"] = price + } + if (map.isNotEmpty()) { + list.add("§7Drill upgrades: §6" + NumberUtil.format(totalPrice)) + list += map.sortedDesc().keys + } + return totalPrice + } + + private fun addPowerScrolls(stack: ItemStack, list: MutableList<String>): Double { + val internalName = stack.getPowerScroll() ?: return 0.0 + + val price = NEUItems.getPrice(internalName) + val name = NEUItems.getItemStack(internalName).name!!.removeColor() + list.add("§7$name: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addAbilityScrolls(stack: ItemStack, list: MutableList<String>): Double { + var totalPrice = 0.0 + val map = mutableMapOf<String, Double>() + for (internalName in stack.getAbilityScrolls()) { + val name = NEUItems.getItemStackOrNull(internalName)!!.name + val price = NEUItems.getPriceOrNull(internalName) ?: continue + + totalPrice += price + val format = NumberUtil.format(price) + map[" $name §7(§6$format§7)"] = price + } + if (map.isNotEmpty()) { + list.add("§7Ability Scrolls: §6" + NumberUtil.format(totalPrice)) + list += map.sortedDesc().keys + } + return totalPrice + } + + private fun addBaseItem(stack: ItemStack, list: MutableList<String>): Double { + val internalName = stack.getInternalName() + var price = NEUItems.getPrice(internalName) + if (price == -1.0) { + price = 0.0 + } + + val name = NEUItems.getItemStack(internalName).name + if (internalName.startsWith("ENCHANTED_BOOK_BUNDLE_")) { + list.add("§7Base item: $name") + return 0.0 + } + + list.add("§7Base item: $name §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addEnchantments(stack: ItemStack, list: MutableList<String>): Double { + var totalPrice = 0.0 + val map = mutableMapOf<String, Double>() + + val tieredEnchants = listOf("compact", "cultivating", "champion", "expertise", "hecatomb") + val hasAlwaysScavenger = listOf( + "CRYPT_DREADLORD_SWORD", + "ZOMBIE_SOLDIER_CUTLASS", + "CONJURING_SWORD", + "EARTH_SHARD", + "ZOMBIE_KNIGHT_SWORD", + "SILENT_DEATH", + "ZOMBIE_COMMANDER_WHIP", + ) + + val internalName = stack.getInternalName() + for ((rawName, rawLevel) in stack.getEnchantments()) { + // efficiency 1-5 is cheap, 6-10 is handled by silex + if (rawName == "efficiency") continue + + if (rawName == "scavenger" && rawLevel == 5) { + if (internalName in hasAlwaysScavenger) continue + } + + var level = rawLevel + if (rawName in tieredEnchants) level = 1 + + val enchantmentName = "$rawName;$level".uppercase() + val itemStack = NEUItems.getItemStackOrNull(enchantmentName) ?: continue + var name = itemStack.getLore()[0] + val singlePrice = NEUItems.getPriceOrNull(enchantmentName) ?: continue + val multiplier = if (internalName.startsWith("ENCHANTED_BOOK_BUNDLE_")) { + name = "§85x $name" + 5 + } else 1 + val price = singlePrice * multiplier + + totalPrice += price + val format = NumberUtil.format(price) + + + map[" $name §7(§6$format§7)"] = price + } + if (map.isNotEmpty()) { + list.add("§7Enchantments: §6" + NumberUtil.format(totalPrice)) + var i = 0 + val size = map.size + for (entry in map.sortedDesc().keys) { + if (i == 7) { + val missing = size - i + list.add(" §7§o$missing more enchantments..") + break + } + list.add(entry) + i++ + } + } + return totalPrice + } + + private fun addGemstones(stack: ItemStack, list: MutableList<String>): Double { + val gemstones = stack.getGemstones() + if (gemstones.isEmpty()) return 0.0 + + var totalPrice = 0.0 + val counterMap = mutableMapOf<String, Int>() + for (gemstone in gemstones) { + val internalName = gemstone.getInternalName() + val old = counterMap[internalName] ?: 0 + counterMap[internalName] = old + 1 + } + + val priceMap = mutableMapOf<String, Double>() + for ((internalName, amount) in counterMap) { + + val name = NEUItems.getItemStack(internalName).name + val price = NEUItems.getPrice(internalName) * amount + + totalPrice += price + val format = NumberUtil.format(price) + + val text = if (amount == 1) { + " $name §7(§6$format§7)" + } else { + " §8${amount}x $name §7(§6$format§7)" + } + priceMap[text] = price + } + + if (priceMap.isNotEmpty()) { + list.add("§7Gemstones: §6" + NumberUtil.format(totalPrice)) + list += priceMap.sortedDesc().keys + } + return totalPrice + } + + class GemstoneSlot(val type: GemstoneType, val tier: GemstoneTier) { + fun getInternalName() = "${tier}_${type}_GEM" + } + + enum class GemstoneTier(val displayName: String) { + ROUGH("Rough"), + FLAWED("Flawed"), + FINE("Fine"), + FLAWLESS("Flawless"), + PERFECT("Perfect"), + ; + + companion object { + fun getByName(name: String) = GemstoneTier.values().firstOrNull { it.name == name } + } + } + + enum class GemstoneType(val displayName: String) { + JADE("Jade"), + AMBER("Amber"), + TOPAZ("Topaz"), + SAPPHIRE("Sapphire"), + AMETHYST("Amethyst"), + JASPER("Jasper"), + RUBY("Ruby"), + OPAL("Opal"), + ; + + companion object { + fun getByName(name: String) = values().firstOrNull { it.name == name } + } + } +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/PasteIntoSigns.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/PasteIntoSigns.kt new file mode 100644 index 000000000..e77db7969 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/PasteIntoSigns.kt @@ -0,0 +1,23 @@ +package at.hannibal2.skyhanni.features.misc + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.data.HyPixelData +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.OSUtils +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent +import org.lwjgl.input.Keyboard + +class PasteIntoSigns { + + @SubscribeEvent + fun onTick(event: TickEvent.ClientTickEvent) { + if (!HyPixelData.hypixel) return + if (!SkyHanniMod.feature.misc.pasteIntoSigns) return + + if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) && Keyboard.isKeyDown(Keyboard.KEY_V)) { + val clipboard = OSUtils.readFromClipboard() ?: return + LorenzUtils.setTextIntoSign(clipboard.take(15)) + } + } +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerQuestWarning.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerQuestWarning.kt index 16ae900a5..d699b04e1 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerQuestWarning.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerQuestWarning.kt @@ -16,7 +16,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import net.minecraftforge.fml.common.gameevent.TickEvent class SlayerQuestWarning { - + private val config get() = SkyHanniMod.feature.slayer private var needSlayerQuest = false private var lastWarning = 0L private var currentReason = "" @@ -118,7 +118,7 @@ class SlayerQuestWarning { @SubscribeEvent fun onWorldChange(event: WorldEvent.Load) { - if (!SkyHanniMod.feature.slayer.questWarning) return + if (!config.questWarning) return if (!needSlayerQuest) { dirtySidebar = true @@ -135,7 +135,10 @@ class SlayerQuestWarning { lastWarning = System.currentTimeMillis() LorenzUtils.chat("§e[SkyHanni] $chatMessage") - SendTitleHelper.sendTitle("§e$titleMessage", 2_000) + + if (config.questWarningTitle) { + SendTitleHelper.sendTitle("§e$titleMessage", 2_000) + } } @SubscribeEvent @@ -170,6 +173,6 @@ class SlayerQuestWarning { } private fun isEnabled(): Boolean { - return LorenzUtils.inSkyBlock && SkyHanniMod.feature.slayer.questWarning + return LorenzUtils.inSkyBlock && config.questWarning } }
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/test/LorenzTest.kt b/src/main/java/at/hannibal2/skyhanni/test/LorenzTest.kt index 02feac91c..45748339c 100644 --- a/src/main/java/at/hannibal2/skyhanni/test/LorenzTest.kt +++ b/src/main/java/at/hannibal2/skyhanni/test/LorenzTest.kt @@ -92,7 +92,7 @@ class LorenzTest { try { val internalName = NEUItems.getInternalName(itemName) list.add(NEUItems.getItemStack(internalName)) - } catch (e: Exception) { + } catch (e: Error) { LorenzUtils.debug("itemName '$itemName' is invalid for visitor '$name'") errors++ } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt b/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt index 41da163b0..91f54e6a3 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt @@ -45,7 +45,7 @@ object APIUtil { return parser.parse(retSrc) as JsonObject } catch (e: JsonSyntaxException) { if (retSrc.contains("<center><h1>502 Bad Gateway</h1></center>")) { - LorenzUtils.error("[SkyHanni] HyPixel API is down :(") + LorenzUtils.error("[SkyHanni] Hypixel API is down :(") } else { println("JsonSyntaxException at getJSONResponse '$urlString'") LorenzUtils.error("[SkyHanni] JsonSyntaxException at getJSONResponse!") diff --git a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt index 53e39e575..c05b9e0cd 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt @@ -40,20 +40,25 @@ object InventoryUtils { val chestName = if (guiChest is GuiChest) { val chest = guiChest.inventorySlots as ContainerChest chest.getInventoryName() - } else { - "" - } + } else "" return chestName } - fun ContainerChest.getInventoryName(): String { - return this.lowerChestInventory.displayName.unformattedText.trim() + fun ContainerChest.getInventoryName() = this.lowerChestInventory.displayName.unformattedText.trim() + + fun getItemsInOwnInventory(): MutableList<ItemStack> { + val list = mutableListOf<ItemStack>() + for (itemStack in Minecraft.getMinecraft().thePlayer.inventory.mainInventory) { + itemStack?.let { + list.add(it) + } + } + + return list } fun countItemsInLowerInventory(predicate: (ItemStack) -> Boolean) = - Minecraft.getMinecraft().thePlayer.inventory.mainInventory - .filter { it != null && predicate(it) } - .sumOf { it.stackSize } + getItemsInOwnInventory().filter { predicate(it) }.sumOf { it.stackSize } fun getArmor(): Array<ItemStack?> = Minecraft.getMinecraft().thePlayer.inventory.armorInventory diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt index 43799dc50..049caf3d1 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt @@ -1,5 +1,6 @@ package at.hannibal2.skyhanni.utils +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.isRecombobulated import at.hannibal2.skyhanni.utils.StringUtils.matchRegex import at.hannibal2.skyhanni.utils.StringUtils.removeColor import com.google.gson.GsonBuilder @@ -28,15 +29,17 @@ object ItemUtils { return list } + // TODO change else janni is sad fun isCoopSoulBound(stack: ItemStack): Boolean = stack.getLore().any { it == "§8§l* §8Co-op Soulbound §8§l*" || it == "§8§l* §8Soulbound §8§l*" } + // TODO change else janni is sad fun isSoulBound(stack: ItemStack): Boolean = stack.getLore().any { it == "§8§l* §8Soulbound §8§l*" } - fun isRecombobulated(stack: ItemStack): Boolean = stack.getLore().any { it.contains("§k") }//TODO use item api + fun isRecombobulated(stack: ItemStack) = stack.isRecombobulated() fun isPet(name: String): Boolean = name.matchRegex("\\[Lvl (.*)] (.*)") && !listOf( "Archer", @@ -152,7 +155,7 @@ object ItemUtils { val itemName = matcher.group("name") if (!itemName.contains("§8x")) { val amount = matcher.group("amount")?.replace(",", "")?.toInt() ?: 1 - val pair = Pair(itemName, amount) + val pair = Pair(itemName.trim(), amount) itemAmountCache[input] = pair return pair } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt index 921229e05..938a0326f 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt @@ -6,8 +6,10 @@ import at.hannibal2.skyhanni.data.IslandType import at.hannibal2.skyhanni.features.dungeon.DungeonData import at.hannibal2.skyhanni.utils.StringUtils.removeColor import at.hannibal2.skyhanni.utils.StringUtils.toDashlessUUID +import io.github.moulberry.notenoughupdates.mixins.AccessorGuiEditSign import io.github.moulberry.notenoughupdates.util.SkyBlockTime import net.minecraft.client.Minecraft +import net.minecraft.client.gui.inventory.GuiEditSign import net.minecraft.entity.EntityLivingBase import net.minecraft.entity.SharedMonsterAttributes import net.minecraft.util.ChatComponentText @@ -51,8 +53,6 @@ object LorenzUtils { if (internalChat(DEBUG_PREFIX + message)) { consoleLog("[Debug] $message") } - } else { - consoleLog("[Debug] $message") } } @@ -191,4 +191,11 @@ object LorenzUtils { } } } + + fun setTextIntoSign(text: String) { + val gui = Minecraft.getMinecraft().currentScreen + if (gui !is GuiEditSign) return + gui as AccessorGuiEditSign + gui.tileSign.signText[0] = ChatComponentText(text) + } }
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt index 1ce7c9e22..25d67bb07 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt @@ -21,15 +21,21 @@ object NEUItems { private val recipesCache = mutableMapOf<String, Set<NeuRecipe>>() fun getInternalName(itemName: String): String { + return getInternalNameOrNull(itemName) ?: throw Error("getInternalName is null for '$itemName'") + } + + fun getInternalNameOrNull(itemName: String): String? { if (itemNameCache.containsKey(itemName)) { return itemNameCache[itemName]!! } - var internalName = ItemResolutionQuery.findInternalNameByDisplayName(itemName, false) + var internalName = ItemResolutionQuery.findInternalNameByDisplayName(itemName, false) ?: return null + // This fixes a NEU bug with §9Hay Bale (cosmetic item) // TODO remove workaround when this is fixed in neu if (internalName == "HAY_BALE") { internalName = "HAY_BLOCK" } + itemNameCache[itemName] = internalName return internalName } @@ -41,6 +47,14 @@ object NEUItems { .resolveInternalName() ?: "" } + fun getPriceOrNull(internalName: String, useSellingPrice: Boolean = false): Double? { + val price = getPrice(internalName, useSellingPrice) + if (price == -1.0) { + return null + } + return price + } + fun getPrice(internalName: String, useSellingPrice: Boolean = false): Double { val bazaarData = BazaarApi.getBazaarDataForInternalName(internalName) bazaarData?.let { @@ -82,7 +96,7 @@ object NEUItems { fun getItemStack(internalName: String): ItemStack { val stack = getItemStackOrNull(internalName) if (stack == null) { - val error = "ItemResolutionQuery returns null for internalName $internalName" + val error = "ItemResolutionQuery returns null for internalName '$internalName'" LorenzUtils.error(error) throw RuntimeException(error) } @@ -120,17 +134,17 @@ object NEUItems { GlStateManager.popMatrix() } - fun getMultiplier(rawId: String, tryCount: Int = 0): Pair<String, Int> { - if (multiplierCache.contains(rawId)) { - return multiplierCache[rawId]!! + fun getMultiplier(internalName: String, tryCount: Int = 0): Pair<String, Int> { + if (multiplierCache.contains(internalName)) { + return multiplierCache[internalName]!! } if (tryCount == 10) { - val message = "Error reading getMultiplier for item '$rawId'" + val message = "Error reading getMultiplier for item '$internalName'" Error(message).printStackTrace() LorenzUtils.error(message) - return Pair(rawId, 1) + return Pair(internalName, 1) } - for (recipe in getRecipes(rawId)) { + for (recipe in getRecipes(internalName)) { if (recipe !is CraftingRecipe) continue val map = mutableMapOf<String, Int>() @@ -138,26 +152,33 @@ object NEUItems { val count = ingredient.count.toInt() var internalItemId = ingredient.internalItemId // ignore cactus green - if (rawId == "ENCHANTED_CACTUS_GREEN") { + if (internalName == "ENCHANTED_CACTUS_GREEN") { if (internalItemId == "INK_SACK-2") { internalItemId = "CACTUS" } } // ignore wheat in enchanted cookie - if (rawId == "ENCHANTED_COOKIE") { + if (internalName == "ENCHANTED_COOKIE") { if (internalItemId == "WHEAT") { continue } } // ignore golden carrot in enchanted golden carrot - if (rawId == "ENCHANTED_GOLDEN_CARROT") { + if (internalName == "ENCHANTED_GOLDEN_CARROT") { if (internalItemId == "GOLDEN_CARROT") { continue } } + // ignore rabbit hide in leather + if (internalName == "LEATHER") { + if (internalItemId == "RABBIT_HIDE") { + continue + } + } + // println("") // println("rawId: $rawId") // println("internalItemId: $internalItemId") @@ -171,15 +192,15 @@ object NEUItems { return if (current.second > 1) { val child = getMultiplier(id, tryCount + 1) val result = Pair(child.first, child.second * current.second) - multiplierCache[rawId] = result + multiplierCache[internalName] = result result } else { - Pair(rawId, 1) + Pair(internalName, 1) } } - val result = Pair(rawId, 1) - multiplierCache[rawId] = result + val result = Pair(internalName, 1) + multiplierCache[internalName] = result return result } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt b/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt index 397613f40..a3c86c0f4 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.utils -import at.hannibal2.skyhanni.utils.NumberUtil.addSuffix import java.text.NumberFormat import java.util.* import java.util.regex.Pattern @@ -51,7 +50,8 @@ object NumberUtil { if (value < 1000) return value.toString() //deal with easy case val (divideBy, suffix) = suffixes.floorEntry(value) val truncated = value / (divideBy / 10) //the number part of the output times 10 - val hasDecimal = truncated < 100 && truncated / 10.0 != (truncated / 10).toDouble() + val truncatedAt = if (suffix == "M") 1000 else 100 + val hasDecimal = truncated < truncatedAt && truncated / 10.0 != (truncated / 10).toDouble() return if (hasDecimal) (truncated / 10.0).toString() + suffix else (truncated / 10).toString() + suffix } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt index 3819573c3..5089b4d82 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt @@ -4,7 +4,9 @@ import net.minecraft.client.settings.KeyBinding import org.lwjgl.input.Keyboard import java.awt.Desktop import java.awt.Toolkit +import java.awt.datatransfer.DataFlavor import java.awt.datatransfer.StringSelection +import java.awt.datatransfer.UnsupportedFlavorException import java.io.IOException import java.net.URI @@ -27,6 +29,16 @@ object OSUtils { Toolkit.getDefaultToolkit().systemClipboard.setContents(StringSelection(text), null) } + fun readFromClipboard(): String? { + val systemClipboard = Toolkit.getDefaultToolkit().systemClipboard ?: return null + try { + val data = systemClipboard.getData(DataFlavor.stringFlavor) ?: return null + return data.toString() + } catch (e: UnsupportedFlavorException) { + return null + } + } + fun KeyBinding.isActive() : Boolean { if (!Keyboard.isCreated()) return false try { diff --git a/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt new file mode 100644 index 000000000..4229a80df --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt @@ -0,0 +1,283 @@ +package at.hannibal2.skyhanni.utils + +import at.hannibal2.skyhanni.features.misc.EstimatedItemValue +import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName +import at.hannibal2.skyhanni.utils.ItemUtils.name +import net.minecraft.item.ItemStack + +object SkyBlockItemModifierUtils { + private val drillPartTypes = listOf("drill_part_upgrade_module", "drill_part_engine", "drill_part_fuel_tank") + + fun ItemStack.getHotPotatoCount(): Int { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + for (attributes in extraAttributes.keySet) { + if (attributes != "hot_potato_count") continue + return extraAttributes.getInteger(attributes) + } + } + return 0 + } + + fun ItemStack.getFarmingForDummiesCount(): Int { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + for (attributes in extraAttributes.keySet) { + if (attributes != "farming_for_dummies_count") continue + return extraAttributes.getInteger(attributes) + } + } + return 0 + } + + fun ItemStack.getSilexCount(): Int { + var silexTier = 0 + for ((name, amount) in getEnchantments()) { + if (name == "efficiency") { + if (amount > 5) { + silexTier = amount - 5 + } + } + } + + if (getInternalName() == "STONK_PICKAXE") { + silexTier-- + } + + return silexTier + } + + fun ItemStack.getTransmissionTunerCount(): Int { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + for (attributes in extraAttributes.keySet) { + if (attributes != "tuned_transmission") continue + return extraAttributes.getInteger(attributes) + } + } + return 0 + } + + fun ItemStack.getManaDisintegrators(): Int { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + for (attributes in extraAttributes.keySet) { + if (attributes != "mana_disintegrator_count") continue + return extraAttributes.getInteger(attributes) + } + } + return 0 + } + + fun ItemStack.getMasterStars(): Int { + val stars = mapOf( + "➊" to 1, + "➋" to 2, + "➌" to 3, + "➍" to 4, + "➎" to 5, + ) + val itemName = name!! + for ((icon, number) in stars) { + if (itemName.endsWith(icon)) { + return number + } + } + + return 0 + } + + fun ItemStack.getDrillUpgrades(): List<String> { + val list = mutableListOf<String>() + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + for (attributes in extraAttributes.keySet) { + if (attributes in drillPartTypes) { + val upgradeItem = extraAttributes.getString(attributes) + list.add(upgradeItem.uppercase()) + } + } + } + + return list + } + + fun ItemStack.getPowerScroll(): String? { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + for (attributes in extraAttributes.keySet) { + if (attributes == "power_ability_scroll") { + return extraAttributes.getString(attributes) + } + } + } + + return null + } + + fun ItemStack.getAbilityScrolls(): List<String> { + val list = mutableListOf<String>() + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + for (attributes in extraAttributes.keySet) { + if (attributes == "ability_scroll") { + + val tagList = extraAttributes.getTagList(attributes, 8) + for (i in 0..3) { + val text = tagList.get(i).toString() + if (text == "END") break + var internalName = text.replace("\"", "") + list.add(internalName) + } + } + } + } + + return list + } + + fun ItemStack.getReforgeName(): String? { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + for (attributes in extraAttributes.keySet) { + if (attributes != "modifier") continue + return extraAttributes.getString(attributes) + } + } + return null + } + + fun ItemStack.isRecombobulated(): Boolean { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + return extraAttributes.hasKey("rarity_upgrades") + } + + return false + } + + fun ItemStack.hasJalapenoBook(): Boolean { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + return extraAttributes.hasKey("jalapeno_count") + } + + return false + } + + fun ItemStack.hasEtherwarp(): Boolean { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + return extraAttributes.hasKey("ethermerge") + } + + return false + } + + fun ItemStack.hasWoodSingularity(): Boolean { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + return extraAttributes.hasKey("wood_singularity_count") + } + + return false + } + + fun ItemStack.hasArtOfWar(): Boolean { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + return extraAttributes.hasKey("art_of_war_count") + } + + return false + } + + // TODO untested + fun ItemStack.hasBookOfStats(): Boolean { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + return extraAttributes.hasKey("stats_book") + } + + return false + } + + fun ItemStack.hasArtOfPiece(): Boolean { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + return extraAttributes.hasKey("artOfPeaceApplied") + } + + return false + } + + fun ItemStack.getEnchantments(): Map<String, Int> { + val map = mutableMapOf<String, Int>() + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + for (attributes in extraAttributes.keySet) { + if (attributes != "enchantments") continue + val enchantments = extraAttributes.getCompoundTag(attributes) + for (key in enchantments.keySet) { + map[key] = enchantments.getInteger(key) + } + } + } + return map + } + + fun ItemStack.getGemstones(): List<EstimatedItemValue.GemstoneSlot> { + val list = mutableListOf<EstimatedItemValue.GemstoneSlot>() + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + for (attributes in extraAttributes.keySet) { + if (attributes != "gems") continue + val gemstones = extraAttributes.getCompoundTag(attributes) + for (key in gemstones.keySet) { + if (key.endsWith("_gem")) continue + if (key == "unlocked_slots") continue + val value = gemstones.getString(key) + if (value == "") continue + + val rawType = key.split("_")[0] + val type = EstimatedItemValue.GemstoneType.getByName(rawType) + + val tier = EstimatedItemValue.GemstoneTier.getByName(value) + if (tier == null) { + LorenzUtils.debug("Gemstone tier is null for item $name: ('$key' = '$value')") + continue + } + if (type != null) { + list.add(EstimatedItemValue.GemstoneSlot(type, tier)) + } else { + val newKey = gemstones.getString(key + "_gem") + val newType = EstimatedItemValue.GemstoneType.getByName(newKey) + if (newType == null) { + LorenzUtils.debug("Gemstone type is null for item $name: ('$newKey' with '$key' = '$value')") + continue + } + list.add(EstimatedItemValue.GemstoneSlot(newType, tier)) + } + } + } + } + return list + } +}
\ No newline at end of file |