diff options
37 files changed, 842 insertions, 257 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 6968a28c5..009d5fef0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,10 @@ + Added farming armor drops counter. + Added **Colored Name** - Show the visitor name in the color of the rarity. + Added **Visitor Item Preview** - Show the base type for the required items next to new visitors (Note that some visitors may require any crop) ++ Added **Teleport Pad Compact Name** - Hide the 'Warp to' and 'No Destination' texts over teleport pads. ++ Added Money per Hour Advanced stats - Show not only Sell Offer price but also Instant Sell price and NPC Sell price (Suggestion: Enable Compact Price as well for this) ++ Added Anita Medal Profit - Helps to identify profitable items to buy at the Anita item shop and potential profit from selling the item at the auction house. ++ Added Composter Compact Display - Displays the compost data from the tab list in a compact form as gui element. ### Features from other Mods diff --git a/FEATURES.md b/FEATURES.md index 8d6b451b5..1720b90f5 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -49,7 +49,7 @@ - Set stack number for specific items (stars for crimson armor, minion tier, pet level, new year cake, for golden and diamond dungeon heads the floor number, the tier of master skull and master star, kuudra keys, skill level, and collection level) - Sack name (show short name of sacks) - Anvil Combine Helper (When putting an enchanted book into the first slot of the anvil, all items with the same enchantment are highlighted in the inventory) -- Added compact star counter on all items (not only on items with dungeon stars and master stars but also on crimson armors, cloaks and fishing rods) +- compact star counter on all items (not only on items with dungeon stars and master stars but also on crimson armors, cloaks and fishing rods) - RNG meter features (in the catacombs RNG meter inventory show the dungeon floor number and highlight floors without a drop selected and highlighting the selected drop in the RNG meter inventory for slayer or catacombs) + Show the tuning stats in the Thaumaturgy inventory. + Show the amount of selected tuning points in the stats tuning inventory. @@ -190,11 +190,15 @@ + Farming contest timer. + Wrong fungi cutter mode warning. + Show the price per garden experience inside the visitor gui. -+ Support for mushroom cow pet perk. (Counting and updating mushroom collection when breaking crops with mushroom blocks, added extra gui for time till crop milestones) ++ Support for mushroom cow pet perk. (Counting and updating mushroom collection when breaking crops with mushroom blocks, extra gui for time till crop milestones) + Blocks/Second display in crop milestone gui. + Farming armor drops counter + **Colored Name** - Show the visitor name in the color of the rarity. + **Visitor Item Preview** - Show the base type for the required items next to new visitors (Note that some visitors may require any crop) ++ **Teleport Pad Compact Name** - Hide the 'Warp to' and 'No Destination' texts over teleport pads. ++ **Money per Hour Advanced stats** - Show not only Sell Offer price but also Instant Sell price and NPC Sell price (Suggestion: Enable Compact Price as well for this) ++ **Anita Medal Profit** - Helps to identify profitable items to buy at the Anita item shop and potential profit from selling the item at the auction house. ++ **Composter Compact Display** - Displays the compost data from the tab list in a compact form as gui element. ## Commands - /wiki (using hypixel-skyblock.fandom.com instead of Hypixel wiki) diff --git a/build.gradle.kts b/build.gradle.kts index 51ee17fec..c020d8936 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "at.hannibal2.skyhanni" -version = "0.17.Beta.24" +version = "0.17.Beta.25" // Toolchains: java { diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java index 782ae6d4a..073c4e514 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java @@ -75,7 +75,7 @@ import java.util.List; public class SkyHanniMod { public static final String MODID = "skyhanni"; - public static final String VERSION = "0.17.Beta.24"; + public static final String VERSION = "0.17.Beta.25"; public static final String DEPENDENCIES = "after:notenoughupdates@[2.1.1,);"; @@ -215,7 +215,7 @@ public class SkyHanniMod { loadModule(new TpsCounter()); loadModule(new ParticleHider()); loadModule(new MiscFeatures()); - loadModule(new SkyMartBestProfit()); + loadModule(new SkyMartCopperPrice()); loadModule(new GardenVisitorFeatures()); loadModule(new GardenInventoryNumbers()); loadModule(new GardenVisitorTimer()); @@ -235,6 +235,9 @@ public class SkyHanniMod { loadModule(new FarmingArmorDrops()); loadModule(new JoinCrystalHollows()); loadModule(new GardenVisitorColorNames()); + loadModule(new GardenTeleportPadCompactName()); + loadModule(new AnitaMedalProfit()); + loadModule(new ComposterDisplay()); Commands.INSTANCE.init(); diff --git a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt index 2ef9f169b..638ec334f 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt +++ b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt @@ -5,6 +5,7 @@ import at.hannibal2.skyhanni.config.ConfigGuiManager import at.hannibal2.skyhanni.config.commands.SimpleCommand.ProcessCommandRunnable import at.hannibal2.skyhanni.data.ApiDataLoader import at.hannibal2.skyhanni.data.GuiEditManager +import at.hannibal2.skyhanni.features.bazaar.BazaarDataGrabber import at.hannibal2.skyhanni.features.bingo.BingoCardDisplay import at.hannibal2.skyhanni.features.bingo.BingoNextStepHelper import at.hannibal2.skyhanni.features.event.diana.BurrowWarpHelper @@ -51,6 +52,7 @@ object Commands { registerCommand("shprintbingohelper") { BingoNextStepHelper.command() } registerCommand("shsetapikey") { ApiDataLoader.command(it) } registerCommand("shtestgardenvisitors") { LorenzTest.testGardenVisitors() } + registerCommand("shresetitemnames") { BazaarDataGrabber.resetItemNames() } } private fun registerCommand(name: String, function: (Array<String>) -> Unit) { 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 26734ef00..67f0decca 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java @@ -33,7 +33,7 @@ public class Garden { // @ConfigOption(name = "Copper Price Position", desc = "") // @ConfigEditorButton(runnableId = "skyMartCopperPrice", buttonText = "Edit") // @ConfigAccordionId(id = 0) - public Position skyMartCopperPricePos = new Position(188, -105, false, true); + public Position skyMartCopperPricePos = new Position(211, 132, false, true); @Expose @ConfigOption(name = "Visitor", desc = "") @@ -530,6 +530,13 @@ public class Garden { @ConfigEditorBoolean @ConfigAccordionId(id = 13) public boolean moneyPerHourCompactPrice = false; + @Expose + @ConfigOption( + name = "Advanced stats", + desc = "Show not only Sell Offer price but also Instant Sell price and NPC Sell price.") + @ConfigEditorBoolean + @ConfigAccordionId(id = 13) + public boolean moneyPerHourAdvancedStats = false; @Expose // @ConfigOption(name = "Money per hour Position", desc = "") @@ -564,7 +571,7 @@ public class Garden { // @ConfigOption(name = "Jacob Contest Position", desc = "") // @ConfigEditorButton(runnableId = "nextJacobContest", buttonText = "Edit") // @ConfigAccordionId(id = 14) - public Position nextJacobContestPos = new Position(-113, -240, false, true); + public Position nextJacobContestPos = new Position(-278, 11, false, true); @Expose @ConfigOption(name = "Farming Armor Drops", desc = "") @@ -587,6 +594,52 @@ public class Garden { public Position farmingArmorDropsPos = new Position(16, -232, false, true); @Expose + @ConfigOption(name = "Teleport Pads", desc = "") + @ConfigEditorAccordion(id = 12) + 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) + public boolean teleportPadsCompactName = false; + + @Expose + @ConfigOption(name = "Anita Medal Profit", desc = "") + @ConfigEditorAccordion(id = 16) + public boolean anitaMedalProfit = false; + + @Expose + @ConfigOption( + name = "Show Prices", + desc = "Helps to identify profitable items to buy at the Anita item shop " + + "and potential profit from selling the item at the auction house." + ) + @ConfigEditorBoolean + @ConfigAccordionId(id = 16) + public boolean anitaMedalProfitEnabled = true; + + @Expose + public Position anitaMedalProfitPos = new Position(206, 158, false, true); + + @Expose + @ConfigOption(name = "Composter", desc = "") + @ConfigEditorAccordion(id = 16) + public boolean composter = false; + + @Expose + @ConfigOption( + name = "Compact Display", + desc = "Displays the compost data from the tab list in a compact form as gui element." + ) + @ConfigEditorBoolean + @ConfigAccordionId(id = 16) + public boolean composterDisplayEnabled = true; + + @Expose + public Position composterDisplayPos = new Position(-363, 13, false, true); + + @Expose @ConfigOption(name = "Plot Price", desc = "Show the price of the plot in coins when inside the Configure Plots inventory.") @ConfigEditorBoolean public boolean plotPrice = true; diff --git a/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt b/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt index 0e2ed1fef..5294d79a1 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt @@ -6,15 +6,12 @@ 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 at.hannibal2.skyhanni.utils.ItemUtils.name -import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded -import at.hannibal2.skyhanni.utils.StringUtils.removeColor import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import java.util.regex.Pattern class GardenCropMilestones { - private val overflowPattern = Pattern.compile("(?:.*) §e(.*)§6\\/(?:.*)") - private val nextTierPattern = Pattern.compile("§7Progress to Tier (.*): §e(?:.*)") + private val cropPattern = Pattern.compile("§7Harvest §f(.*) §7on .*") + private val totalPattern = Pattern.compile("§7Total: §a(.*)") // Add when api support is there // @SubscribeEvent @@ -43,31 +40,17 @@ class GardenCropMilestones { if (event.inventoryName != "Crop Milestones") return for ((_, stack) in event.inventoryItems) { - val cropName = stack.name?.removeColor() ?: continue - val crop = CropType.getByName(cropName) ?: continue - - val lore = stack.getLore() - var cropForTier = 0L - var next = false - for (line in lore) { - if (line.contains("Progress to Tier")) { - val matcher = nextTierPattern.matcher(line) - if (matcher.matches()) { - val nextTier = matcher.group(1).romanToDecimalIfNeeded() - val currentTier = nextTier - 1 - cropForTier = getCropsForTier(currentTier) - } - next = true - continue + var crop: CropType? = null + for (line in stack.getLore()) { + var matcher = cropPattern.matcher(line) + if (matcher.matches()) { + val name = matcher.group(1) + crop = CropType.getByName(name) ?: continue } - if (next) { - val matcher = overflowPattern.matcher(line) - if (matcher.matches()) { - val rawNumber = matcher.group(1) - val overflow = rawNumber.formatNumber() - crop.setCounter(cropForTier + overflow) - } - next = false + matcher = totalPattern.matcher(line) + if (matcher.matches()) { + val amount = matcher.group(1).replace(",", "").toLong() + crop?.setCounter(amount) } } } @@ -80,7 +63,9 @@ class GardenCropMilestones { fun CropType.getCounter() = cropCounter[this]!! - fun CropType.setCounter(counter: Long) { cropCounter[this] = counter } + fun CropType.setCounter(counter: Long) { + cropCounter[this] = counter + } fun getTierForCrops(crops: Long): Int { var tier = 0 diff --git a/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt b/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt index a2a22a865..fc68e1a52 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt @@ -2,12 +2,14 @@ package at.hannibal2.skyhanni.data import at.hannibal2.skyhanni.events.BlockClickEvent import at.hannibal2.skyhanni.events.EntityClickEvent +import at.hannibal2.skyhanni.events.ItemClickEvent import at.hannibal2.skyhanni.events.PacketEvent import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.toLorenzVec import net.minecraft.client.Minecraft import net.minecraft.network.play.client.C07PacketPlayerDigging import net.minecraft.network.play.client.C08PacketPlayerBlockPlacement +import net.minecraft.network.play.client.C0APacketAnimation import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import net.minecraftforge.fml.common.gameevent.InputEvent import org.lwjgl.input.Mouse @@ -21,11 +23,14 @@ 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 position = packet.position.toLorenzVec() - val itemInHand = Minecraft.getMinecraft().thePlayer.heldItem BlockClickEvent(ClickType.LEFT_CLICK, position, itemInHand).postAndCatch() } + if (packet is C0APacketAnimation) { + ItemClickEvent(itemInHand).postAndCatch() + } } @SubscribeEvent diff --git a/src/main/java/at/hannibal2/skyhanni/events/ItemClickEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/ItemClickEvent.kt new file mode 100644 index 000000000..7b12f60cb --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/events/ItemClickEvent.kt @@ -0,0 +1,8 @@ +package at.hannibal2.skyhanni.events + +import at.hannibal2.skyhanni.data.ClickType +import at.hannibal2.skyhanni.utils.BlockUtils.getBlockStateAt +import at.hannibal2.skyhanni.utils.LorenzVec +import net.minecraft.item.ItemStack + +class ItemClickEvent(val itemInHand: ItemStack?) : LorenzEvent()
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarData.kt b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarData.kt index b4f00f248..eb76ac18f 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarData.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarData.kt @@ -1,3 +1,11 @@ package at.hannibal2.skyhanni.features.bazaar -data class BazaarData(val apiName: String, val itemName: String, val sellPrice: Double, val buyPrice: Double, val buyMovingWeek: Int, val sellMovingWeek: Int)
\ No newline at end of file +data class BazaarData( + val apiName: String, + val itemName: String, + val sellPrice: Double, + val buyPrice: Double, + val npcPrice: Double, + val buyMovingWeek: Int, + val sellMovingWeek: Int, +)
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarDataGrabber.kt b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarDataGrabber.kt index 609801cd5..0bcaded93 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarDataGrabber.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarDataGrabber.kt @@ -14,9 +14,15 @@ internal class BazaarDataGrabber(private var bazaarMap: MutableMap<String, Bazaa companion object { private val itemNames = mutableMapOf<String, String>() + private val npcPrices = mutableMapOf<String, Double>() var lastTime = 0L var currentlyUpdating = false + + fun resetItemNames() { + LorenzUtils.chat("§e[SkyHanni] Reloading the hypixel item api..") + itemNames.clear() + } } private fun loadItemNames(): Boolean { @@ -28,6 +34,17 @@ internal class BazaarDataGrabber(private var bazaarMap: MutableMap<String, Bazaa val name = jsonObject["name"].asString val id = jsonObject["id"].asString itemNames[id] = name.removeColor() +// if (id.lowercase().contains("redstone")) { + if (jsonObject.has("npc_sell_price")) { +// println(" ") +// println("name: $name") +// println("id: $id") + val npcPrice = jsonObject["npc_sell_price"].asDouble +// println("npcPrice: $npcPrice") + npcPrices[id] = npcPrice + } +// println("jsonObject: $jsonObject") +// } } currentlyUpdating = false return true @@ -94,7 +111,8 @@ internal class BazaarDataGrabber(private var bazaarMap: MutableMap<String, Bazaa val itemName = getItemName(apiName) if (itemName == null) { - LorenzUtils.warning("§c[SkyHanni] bazaar item '$apiName' not found! Try restarting your minecraft to fix this.") + LorenzUtils.warning("§c[SkyHanni] bazaar item '$apiName' not found!") + resetItemNames() continue } @@ -109,7 +127,18 @@ internal class BazaarDataGrabber(private var bazaarMap: MutableMap<String, Bazaa apiName = text } - val data = BazaarData(apiName, itemName, sellPrice, buyPrice, buyMovingWeek, sellMovingWeek) + val npcPrice = npcPrices[apiName] ?: -1.0 +// if (npcPrice == -1.0) { +// if (apiName.lowercase().contains("carrot")) { +// println(" ") +// println("BazaarData") +// println("itemName: '$itemName'") +// println("apiName: '$apiName'") +// println("npc price: $npcPrice") +// } +// } + + val data = BazaarData(apiName, itemName, sellPrice, buyPrice, npcPrice, buyMovingWeek, sellMovingWeek) bazaarMap[itemName] = data } BazaarUpdateEvent(bazaarMap).postAndCatch() diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatModifier.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatModifier.kt index ba144e9db..15eff6a85 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatModifier.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatModifier.kt @@ -14,8 +14,8 @@ class PlayerChatModifier { init { patterns.add("§(?:a|b|6)\\[(?:VIP|MVP)(?:(?:§.|\\+)*)](?: {1,2})(?:§[7ab6])?(\\w{2,16})".toRegex()) // ranked player everywhere - patterns.add("§(?:7|a|b|6)((?:\\w+){2,16})§r(?!§7x)".toRegex()) // nons in notification message - patterns.add("(?:§7 )?§7((?:\\w+){2,16})§7§r".toRegex()) // nons user chat + patterns.add("§(?:7|a|b|6)((?:\\w){2,16})§r(?!§7x)".toRegex()) // nons in notification message + patterns.add("(?:§7 )?§7((?:\\w){2,16})§7§r".toRegex()) // nons user chat } @SubscribeEvent diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt new file mode 100644 index 000000000..fa6500bcb --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt @@ -0,0 +1,141 @@ +package at.hannibal2.skyhanni.features.garden + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.GuiRenderEvent +import at.hannibal2.skyhanni.events.InventoryCloseEvent +import at.hannibal2.skyhanni.events.InventoryOpenEvent +import at.hannibal2.skyhanni.utils.ItemUtils +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.NEUItems +import at.hannibal2.skyhanni.utils.NumberUtil +import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems +import net.minecraft.item.ItemStack +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class AnitaMedalProfit { + private val config get() = SkyHanniMod.feature.garden + private var display = listOf<List<Any>>() + + companion object { + var inInventory = false + } + + enum class MedalType(val displayName: String, val factorBronze: Int) { + GOLD("§6Gold medal", 8), + SILVER("§fSilver medal", 2), + BRONZE("§cBronze medal", 1), + ; + } + + private fun getMedal(name: String) = MedalType.values().firstOrNull { it.displayName == name } + + @SubscribeEvent + fun onInventoryClose(event: InventoryCloseEvent) { + inInventory = false + } + + @SubscribeEvent + fun onInventoryOpen(event: InventoryOpenEvent) { + if (!config.anitaMedalProfitEnabled) return + if (event.inventoryName != "Anita") return + + inInventory = true + + val table = mutableMapOf<Pair<String, String>, Pair<Double, String>>() + for ((_, item) in event.inventoryItems) { + readItem(item, table) + } + + val newList = mutableListOf<List<Any>>() + newList.addAsSingletonList("§eMedal Profit") + LorenzUtils.fillTable(newList, table) + display = newList + } + + private fun readItem(item: ItemStack, table: MutableMap<Pair<String, String>, Pair<Double, String>>) { + var itemName = item.name ?: return + if (itemName == " ") return + if (itemName.endsWith("Enchanted Book")) { + itemName = item.getLore()[0] + } + + val fullCost = getFullCost(getRequiredItems(item)) + if (fullCost < 0) return + + 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() + } + + val itemPrice = NEUItems.getPrice(internalName) * amount + if (itemPrice < 0) return + + val profit = itemPrice - fullCost + val format = NumberUtil.format(profit) + val color = if (profit > 0) "§6" else "§c" + table[Pair(itemName, "$color$format")] = Pair(profit, internalName) + } + + private fun getFullCost(requiredItems: MutableList<String>): Double { + val jacobTicketPrice = NEUItems.getPrice("JACOBS_TICKET") + var otherItemsPrice = 0.0 + for (rawItemName in requiredItems) { + val (name, amount) = ItemUtils.readItemAmount(rawItemName) + if (name == null) { + LorenzUtils.error("§c[SkyHanni] Could not read item '$rawItemName'") + continue + } + + val medal = getMedal(name) + otherItemsPrice += if (medal != null) { + val bronze = medal.factorBronze * amount + bronze * jacobTicketPrice + } else { + val internalName = NEUItems.getInternalName(name) + NEUItems.getPrice(internalName) * amount + } + } + return otherItemsPrice + } + + private fun getRequiredItems(item: ItemStack): MutableList<String> { + val items = mutableListOf<String>() + var next = false + for (line in item.getLore()) { + if (line == "§7Cost") { + next = true + continue + } + if (next) { + if (line == "") { + next = false + continue + } + + items.add(line.replace("§8 ", " §8")) + } + } + return items + } + + @SubscribeEvent + fun onBackgroundDraw(event: GuiRenderEvent.ChestBackgroundRenderEvent) { + if (inInventory) { + config.anitaMedalProfitPos.renderStringsAndItems( + display, + extraSpace = 5, + itemScale = 1.7, + posLabel = "Anita Medal Profit" + ) + } + } +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/ComposterDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/ComposterDisplay.kt new file mode 100644 index 000000000..57cf15aa9 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/ComposterDisplay.kt @@ -0,0 +1,80 @@ +package at.hannibal2.skyhanni.features.garden + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.GuiRenderEvent +import at.hannibal2.skyhanni.events.TabListUpdateEvent +import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList +import at.hannibal2.skyhanni.utils.NEUItems +import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.util.regex.Pattern + +class ComposterDisplay { + private val config get() = SkyHanniMod.feature.garden + private var display = listOf<List<Any>>() + + enum class DataType(val pattern: String, val icon: String) { + ORGANIC_MATTER(" Organic Matter: §r(.*)", "WHEAT"), + FUEL(" Fuel: §r(.*)", "OIL_BARREL"), + TIME_LEFT(" Time Left: §r(.*)", "WATCH"), + STORED_COMPOST(" Stored Compost: §r(.*)", "COMPOST"), + ; + + val displayItem by lazy { + NEUItems.getItemStack(icon) + } + + fun addToList(map: Map<DataType, String>): List<Any> { + return listOf(displayItem, map[this]!!) + } + } + + @SubscribeEvent + fun onTabListUpdate(event: TabListUpdateEvent) { + if (!isEnabled()) return + + var next = false + val data = mutableMapOf<DataType, String>() + + for (line in event.tabList) { + if (line == "§b§lComposter:") { + next = true + continue + } + if (next) { + if (line == "") break + for (type in DataType.values()) { + val pattern = Pattern.compile(type.pattern) + val matcher = pattern.matcher(line) + if (matcher.matches()) { + data[type] = matcher.group(1) + } + } + } + } + + val newList = mutableListOf<List<Any>>() + newList.addAsSingletonList("§bComposter") + + newList.add(DataType.TIME_LEFT.addToList(data)) + + val list = mutableListOf<Any>() + list.addAll(DataType.ORGANIC_MATTER.addToList(data)) + list.add(" ") + list.addAll(DataType.FUEL.addToList(data)) + newList.add(list) + + newList.add(DataType.STORED_COMPOST.addToList(data)) + + display = newList + } + + @SubscribeEvent + fun onRenderOverlay(event: GuiRenderEvent.GameOverlayRenderEvent) { + if (isEnabled()) { + config.composterDisplayPos.renderStringsAndItems(display, posLabel = "Composter Display") + } + } + + fun isEnabled() = config.composterDisplayEnabled && GardenAPI.inGarden() +}
\ No newline at end of file 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 d004befd8..bfc20a7cd 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/CropMoneyDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/CropMoneyDisplay.kt @@ -7,6 +7,7 @@ import at.hannibal2.skyhanni.features.bazaar.BazaarApi import at.hannibal2.skyhanni.features.garden.GardenAPI.Companion.getSpeed 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 @@ -16,7 +17,6 @@ import io.github.moulberry.notenoughupdates.NotEnoughUpdates import kotlinx.coroutines.launch import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import net.minecraftforge.fml.common.gameevent.TickEvent -import java.util.* class CropMoneyDisplay { private var display = mutableListOf<List<Any>>() @@ -60,20 +60,29 @@ class CropMoneyDisplay { val newDisplay = mutableListOf<List<Any>>() val title = if (config.moneyPerHourCompact) { - Collections.singletonList("§7Money/hour:") + "§7Money/hour:" } else { - Collections.singletonList("§7Money per hour when selling:") + "§7Money per hour when selling:" } if (!ready) { - newDisplay.add(title) - newDisplay.add(Collections.singletonList("§eLoading...")) + newDisplay.addAsSingletonList(title) + newDisplay.addAsSingletonList("§eLoading...") return newDisplay } if (!hasCropInHand && !config.moneyPerHourAlwaysOn) return newDisplay - newDisplay.add(title) + + newDisplay.addAsSingletonList( + if (config.moneyPerHourAdvancedStats) { + "$title §7(§eSell Offer§7/§eInstant Sell§7/§eNpc Price§7)" + } else if (LorenzUtils.noTradeMode) { + "$title §7(§eNpc Price§7)" + } else { + "$title §7(§eSell Offer§7)" + } + ) val moneyPerHourData = calculateMoneyPerHour() if (moneyPerHourData.isEmpty()) { @@ -81,17 +90,18 @@ class CropMoneyDisplay { val message = "money/hr empty but speed data not empty, retry" LorenzUtils.debug(message) println(message) - newDisplay.add(Collections.singletonList("§eStill Loading...")) + newDisplay.addAsSingletonList("§eStill Loading...") ready = false loaded = false return newDisplay } - newDisplay.add(Collections.singletonList("§cFarm crops to add them to this list!")) + newDisplay.addAsSingletonList("§cFarm crops to add them to this list!") return newDisplay } var number = 0 - for ((internalName, moneyPerHour) in moneyPerHourData.sortedDesc()) { + val help = moneyPerHourData.mapValues { (_, value) -> value.max() } + for (internalName in help.sortedDesc().keys) { number++ val cropName = cropNames[internalName]!! val isCurrent = cropName == GardenAPI.cropInHand @@ -115,13 +125,24 @@ class CropMoneyDisplay { list.add("$currentColor$contestFormat$itemName§7: ") } - - val format = if (config.moneyPerHourCompactPrice) { - NumberUtil.format(moneyPerHour) + val coinsColor = if (isCurrent && config.moneyPerHourCompact) "§e" else "§6" + val moneyArray = moneyPerHourData[internalName]!! + if (config.moneyPerHourAdvancedStats) { + for (price in moneyArray) { + val format = format(price) + list.add("$coinsColor$format") + list.add("§7/") + } + list.removeLast() + } else if (LorenzUtils.noTradeMode) { + // Show npc price + val format = format(moneyArray[2]) + list.add("$coinsColor$format") } else { - LorenzUtils.formatInteger(moneyPerHour.toLong()) + val format = format(moneyArray[0]) + list.add("$coinsColor$format") } - list.add("§6$format") + newDisplay.add(list) } @@ -129,22 +150,35 @@ class CropMoneyDisplay { return newDisplay } - private fun calculateMoneyPerHour(): Map<String, Double> { - val moneyPerHours = mutableMapOf<String, Double>() + private fun format(moneyPerHour: Double) = if (config.moneyPerHourCompactPrice) { + NumberUtil.format(moneyPerHour) + } else { + LorenzUtils.formatInteger(moneyPerHour.toLong()) + } + + // sell offer -> instant sell -> npc + private fun calculateMoneyPerHour(): Map<String, Array<Double>> { + val moneyPerHours = mutableMapOf<String, Array<Double>>() for ((internalName, amount) in multipliers) { - val price = NEUItems.getPrice(internalName) val crop = cropNames[internalName]!! val speed = crop.getSpeed() // No speed data for item in hand if (speed == -1) continue - // Price not found - if (price == -1.0) continue - val speedPerHr = speed.toDouble() * 60 * 60 val blocksPerHour = speedPerHr / amount.toDouble() - val moneyPerHour = price * blocksPerHour - moneyPerHours[internalName] = moneyPerHour + + val bazaarData = BazaarApi.getBazaarDataForInternalName(internalName) ?: continue + + val npcPrice = bazaarData.npcPrice * blocksPerHour +// if (LorenzUtils.noTradeMode) { +// moneyPerHours[internalName] = arrayOf(npcPrice) +// } else { + val sellOffer = bazaarData.buyPrice * blocksPerHour + val instantSell = bazaarData.sellPrice * blocksPerHour + moneyPerHours[internalName] = arrayOf(sellOffer, instantSell, npcPrice) +// } + } return moneyPerHours } @@ -182,4 +216,4 @@ class CropMoneyDisplay { } private fun isEnabled() = GardenAPI.inGarden() && config.moneyPerHourDisplay -}
\ 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 612bebfbc..b33c0150e 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/EliteFarmingWeight.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/EliteFarmingWeight.kt @@ -160,7 +160,8 @@ class EliteFarmingWeight { val weightUntilOvertake = nextPlayerWeight - totalWeight if (weightUntilOvertake < 0) { if (!hasPassedNext) { - if (weightPerSecond != -1.0) { + if (weightPerSecond > 0) { + LorenzUtils.debug("weightPerSecond: '$weightPerSecond'") LorenzUtils.chat("§e[SkyHanni] You passed §b$nextName §ein the Farming Weight Leaderboard!") } if (leaderboardPosition == -1) { @@ -270,7 +271,7 @@ class EliteFarmingWeight { var totalWeight = 0.0 for (crop in CropType.values()) { val weight = crop.getLocalCounter() / crop.getFactor() - val roundedWeight = weight.let { if (round) it.round(2) else it } + val roundedWeight = weight.let { if (round) it.round(2) else it } weightPerCrop[crop] = roundedWeight totalWeight += roundedWeight } 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 c12710a4b..1168b7f40 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,7 @@ package at.hannibal2.skyhanni.features.garden import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.data.IslandType -import at.hannibal2.skyhanni.events.GardenToolChangeEvent -import at.hannibal2.skyhanni.events.GuiContainerEvent -import at.hannibal2.skyhanni.events.PacketEvent -import at.hannibal2.skyhanni.events.ProfileJoinEvent +import at.hannibal2.skyhanni.events.* import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.NEUItems @@ -44,6 +41,13 @@ class GardenAPI { } } + @SubscribeEvent + fun onTabListUpdate(event: TabListUpdateEvent) { + if (inGarden()) { + mushroomCowPet = event.tabList.any { it.startsWith(" Strength: §r§c❁") } + } + } + private fun checkItemInHand() { val toolItem = Minecraft.getMinecraft().thePlayer.heldItem val crop = getCropTypeFromItem(toolItem) @@ -75,6 +79,7 @@ class GardenAPI { var toolInHand: String? = null private val cropsPerSecond: MutableMap<CropType, Int> get() = SkyHanniMod.feature.hidden.gardenCropsPerSecond var cropInHand: CropType? = null + var mushroomCowPet = false fun inGarden() = LorenzUtils.inSkyBlock && LorenzUtils.skyBlockIsland == IslandType.GARDEN @@ -111,7 +116,7 @@ class GardenAPI { setSpeed(-1) return -1 } - + fun CropType.setSpeed(speed: Int) { cropsPerSecond[this] = speed } diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenBestCropTime.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenBestCropTime.kt index cce6dd67f..139573899 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenBestCropTime.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenBestCropTime.kt @@ -4,9 +4,9 @@ import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.data.GardenCropMilestones import at.hannibal2.skyhanni.data.GardenCropMilestones.Companion.getCounter import at.hannibal2.skyhanni.features.garden.GardenAPI.Companion.getSpeed +import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList import at.hannibal2.skyhanni.utils.LorenzUtils.sorted import at.hannibal2.skyhanni.utils.TimeUtils -import java.util.* class GardenBestCropTime { var display = listOf<List<Any>>() @@ -34,10 +34,10 @@ class GardenBestCropTime { } val title = if (gardenExp) "§2Garden Experience" else "§bSkyBlock Level" - newList.add(Collections.singletonList("§eBest Crop Time §7($title§7)")) + newList.addAsSingletonList("§eBest Crop Time §7($title§7)") if (sorted.isEmpty()) { - newList.add(Collections.singletonList("§cFarm crops to add them to this list!")) + newList.addAsSingletonList("§cFarm crops to add them to this list!") return newList } 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 6da25ac8b..b1186f533 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneDisplay.kt @@ -9,6 +9,7 @@ import at.hannibal2.skyhanni.data.SendTitleHelper import at.hannibal2.skyhanni.events.* import at.hannibal2.skyhanni.features.garden.GardenAPI.Companion.setSpeed import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems import at.hannibal2.skyhanni.utils.SoundUtils.playSound import at.hannibal2.skyhanni.utils.TimeUtils @@ -45,6 +46,22 @@ class GardenCropMilestoneDisplay { private var needsInventory = false + private var mushroom_cow_nether_warts = true + + @SubscribeEvent + fun onRepoReload(event: RepositoryReloadEvent) { + try { + val constant = event.getConstant("DisabledFeatures") + mushroom_cow_nether_warts = if (constant != null) { + if (constant.has("mushroom_cow_nether_warts")) { + constant["mushroom_cow_nether_warts"].asBoolean + } else false + } else false + } catch (e: Exception) { + e.printStackTrace() + } + } + @SubscribeEvent fun onChatMessage(event: LorenzChatEvent) { if (!isEnabled()) return @@ -67,10 +84,16 @@ class GardenCropMilestoneDisplay { fun onRenderOverlay(event: GuiRenderEvent.GameOverlayRenderEvent) { if (!isEnabled()) return - config.cropMilestoneProgressDisplayPos.renderStringsAndItems(progressDisplay, posLabel = "Crop Milestone Progress") + config.cropMilestoneProgressDisplayPos.renderStringsAndItems( + progressDisplay, + posLabel = "Crop Milestone Progress" + ) if (config.cropMilestoneMushroomPetPerkEnabled) { - config.cropMilestoneMushroomPetPerkPos.renderStringsAndItems(mushroomCowPerkDisplay, posLabel = "Mushroom Cow Perk") + config.cropMilestoneMushroomPetPerkPos.renderStringsAndItems( + mushroomCowPerkDisplay, + posLabel = "Mushroom Cow Perk" + ) } if (config.cropMilestoneBestDisplay) { @@ -94,7 +117,8 @@ class GardenCropMilestoneDisplay { @SubscribeEvent fun onOwnInventoryItemUpdate(event: OwnInventorItemUpdateEvent) { - // TODO remove try catch + if (!GardenAPI.inGarden()) return + try { val item = event.itemStack val counter = GardenAPI.readCounter(item) @@ -136,7 +160,9 @@ class GardenCropMilestoneDisplay { if (event.clickType == ClickType.LEFT_CLICK) { val blockState = event.getBlockState - if (isFarmBlock(blockState)) { + val blocks = isFarmBlock(blockState) + if (blocks == 0) return + if (blocks == 1) { for (property in blockState.block.blockState.properties) { val name = property.name if (name == "age") { @@ -146,41 +172,29 @@ class GardenCropMilestoneDisplay { } } } - blocksBroken++ } + blocksBroken += blocks } } - private fun isFarmBlock(blockState: IBlockState): Boolean { + private fun isFarmBlock(blockState: IBlockState): Int { val block = blockState.block - if (block == Blocks.carrots) return true - if (block == Blocks.potatoes) return true - if (block == Blocks.wheat) { - for (property in block.blockState.properties) { - val name = property.name - if (name != "age") continue - if (property !is PropertyInteger) continue - - val age = blockState.getValue(property) - if (age == 0) { - return false - } - } - return true - } - if (block == Blocks.cocoa) return true // Cocoa Beans - if (block == Blocks.red_mushroom) return true - if (block == Blocks.brown_mushroom) return true - if (block == Blocks.cactus) return true - if (block == Blocks.reeds) return true // Sugar Cane - if (block == Blocks.nether_wart) return true - if (block == Blocks.melon_block) return true - if (block == Blocks.pumpkin) return true - - if (block == Blocks.dirt) return false - if (block == Blocks.farmland) return false - - return false + if (block == Blocks.carrots) return 1 + if (block == Blocks.potatoes) return 1 + if (block == Blocks.wheat) return 1 + if (block == Blocks.cocoa) return 1 // Cocoa Beans + if (block == Blocks.red_mushroom) return 1 + if (block == Blocks.brown_mushroom) return 1 + if (block == Blocks.cactus) return 2 + if (block == Blocks.reeds) return 2 // Sugar Cane + if (block == Blocks.nether_wart) return 1 + if (block == Blocks.melon_block) return 1 + if (block == Blocks.pumpkin) return 1 + + if (block == Blocks.dirt) return 0 + if (block == Blocks.farmland) return 0 + + return 0 } private var currentSpeed = 0 @@ -201,6 +215,10 @@ class GardenCropMilestoneDisplay { init { fixedRateTimer(name = "skyhanni-crop-milestone-speed", period = 1000L) { + if (GardenAPI.inGarden() && GardenAPI.mushroomCowPet) { + CropType.MUSHROOM.setCounter(CropType.MUSHROOM.getCounter() + blocksBroken) + update() + } if (isEnabled()) { checkSpeed() } @@ -219,14 +237,9 @@ class GardenCropMilestoneDisplay { currentSpeed = 0 lastBlocksPerSecond = blocksBroken - val hasMushroomCow = hasMushroomCow() - if (hasMushroomCow) { - CropType.MUSHROOM.setCounter(CropType.MUSHROOM.getCounter() + blocksBroken) - } blocksBroken = 0 } - private fun hasMushroomCow() = SkyHanniMod.feature.hidden.currentPet.contains("Mooshroom Cow") private fun calculateSpeed(addedCounter: Int) { currentSpeed += addedCounter @@ -311,9 +324,16 @@ class GardenCropMilestoneDisplay { val format = LorenzUtils.formatInteger(averageSpeedPerSecond * 60) lineMap[4] = Collections.singletonList("§7Crops/Minute§8: §e$format") lineMap[5] = Collections.singletonList("§7Blocks/Second§8: §e$lastBlocksPerSecond") + } - - if (hasMushroomCow() && crop != CropType.MUSHROOM) { + if (GardenAPI.mushroomCowPet && crop != CropType.MUSHROOM) { + if (mushroom_cow_nether_warts && crop == CropType.NETHER_WART) { + mushroomCowPerkDisplay = listOf( + listOf("§6Mooshroom Cow Perk"), + listOf("§cNether Warts don't give mushrooms."), + listOf("§7(Hypixel please fix this)") + ) + } else { addMushroomCowData() } } @@ -330,7 +350,7 @@ class GardenCropMilestoneDisplay { } if (needsInventory) { - newList.add(Collections.singletonList("§cOpen §e/cropmilestones §cto update!")) + newList.addAsSingletonList("§cOpen §e/cropmilestones §cto update!") } return newList @@ -354,8 +374,13 @@ class GardenCropMilestoneDisplay { val missing = need - have - // We assume perfect 20 blocks per second speed for this - val missingTimeSeconds = missing / 20 + // We assume perfect 20 blocks per seconds + val blocksPerSecond = when (currentCrop) { + CropType.CACTUS, CropType.SUGAR_CANE -> 40 + + else -> 20 + } + val missingTimeSeconds = missing / blocksPerSecond val millis = missingTimeSeconds * 1000 val duration = TimeUtils.formatDuration(millis) diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt index c35d5cd01..675b30220 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt @@ -1,14 +1,12 @@ package at.hannibal2.skyhanni.features.garden import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.ConfigLoadEvent -import at.hannibal2.skyhanni.events.GuiRenderEvent -import at.hannibal2.skyhanni.events.InventoryCloseEvent -import at.hannibal2.skyhanni.events.InventoryOpenEvent +import at.hannibal2.skyhanni.events.* 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.RenderUtils.renderSingleLineWithItems +import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings import at.hannibal2.skyhanni.utils.TimeUtils import io.github.moulberry.notenoughupdates.util.SkyBlockTime import net.minecraftforge.fml.common.eventhandler.SubscribeEvent @@ -18,6 +16,7 @@ import java.util.regex.Pattern class GardenNextJacobContest { private var display = listOf<Any>() + private var simpleDisplay = listOf<String>() private var tick = 0 private var contests = mutableMapOf<Long, FarmingContest>() private var inCalendar = false @@ -29,6 +28,27 @@ class GardenNextJacobContest { private val contestDuration = 1_000 * 60 * 20 @SubscribeEvent + fun onTabListUpdate(event: TabListUpdateEvent) { + var next = false + val newList = mutableListOf<String>() + for (line in event.tabList) { + if (line == "§e§lJacob's Contest:") { + newList.add(line) + next = true + continue + } + if (next) { + if (line == "") break + newList.add(line) + } + } + newList.add("§cOpen calendar for") + newList.add("§cmore exact data!") + + simpleDisplay = newList + } + + @SubscribeEvent fun onTick(event: TickEvent.ClientTickEvent) { if (!isEnabled()) return if (tick++ % (40) != 0) return @@ -137,8 +157,7 @@ class GardenNextJacobContest { } if (contests.isEmpty()) { - list.add("§cOpen calendar to read jacob contest times!") - return list + return emptyList() } val nextContest = @@ -182,7 +201,11 @@ class GardenNextJacobContest { fun onRenderOverlay(event: GuiRenderEvent.GameOverlayRenderEvent) { if (!isEnabled()) return - config.nextJacobContestPos.renderSingleLineWithItems(display, 1.7, posLabel = "Garden Next Jacob Contest") + if (display.isEmpty()) { + config.nextJacobContestPos.renderStrings(simpleDisplay, posLabel = "Garden Next Jacob Contest") + } else { + config.nextJacobContestPos.renderSingleLineWithItems(display, 1.7, posLabel = "Garden Next Jacob Contest") + } } @SubscribeEvent @@ -190,7 +213,9 @@ class GardenNextJacobContest { if (!config.nextJacobContestDisplay) return if (!inCalendar) return - config.nextJacobContestPos.renderSingleLineWithItems(display, posLabel = "Garden Next Jacob Contest") + if (!display.isEmpty()) { + config.nextJacobContestPos.renderSingleLineWithItems(display, posLabel = "Garden Next Jacob Contest") + } } private fun isEnabled() = LorenzUtils.inSkyBlock && config.nextJacobContestDisplay diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextPlotPrice.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextPlotPrice.kt index abea33203..85b61db60 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextPlotPrice.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextPlotPrice.kt @@ -1,11 +1,8 @@ package at.hannibal2.skyhanni.features.garden import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.utils.InventoryUtils -import at.hannibal2.skyhanni.utils.ItemUtils +import at.hannibal2.skyhanni.utils.* import at.hannibal2.skyhanni.utils.ItemUtils.name -import at.hannibal2.skyhanni.utils.NEUItems -import at.hannibal2.skyhanni.utils.NumberUtil import net.minecraftforge.event.entity.player.ItemTooltipEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent @@ -39,6 +36,8 @@ class GardenNextPlotPrice { val price = lowestBin * amount val format = NumberUtil.format(price) list[i] = list[i] + " §7(§6$format§7)" + } else { + LorenzUtils.error("§c[SkyHanni] Could not read item '$line'") } break } diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenTeleportPadCompactName.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenTeleportPadCompactName.kt new file mode 100644 index 000000000..95e50dff2 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenTeleportPadCompactName.kt @@ -0,0 +1,32 @@ +package at.hannibal2.skyhanni.features.garden + +import at.hannibal2.skyhanni.SkyHanniMod +import net.minecraft.entity.EntityLivingBase +import net.minecraft.entity.item.EntityArmorStand +import net.minecraftforge.client.event.RenderLivingEvent +import net.minecraftforge.fml.common.eventhandler.EventPriority +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.util.regex.Pattern + +class GardenTeleportPadCompactName { + private val patternName = Pattern.compile("§.✦ §aWarp To (.*)") + private val patternNoName = Pattern.compile("§.✦ §cNo Destination") + + @SubscribeEvent(priority = EventPriority.HIGH) + fun onRenderLivingB(event: RenderLivingEvent.Specials.Pre<EntityLivingBase>) { + if (!SkyHanniMod.feature.garden.teleportPadsCompactName) return + val entity = event.entity + if (entity !is EntityArmorStand) return + + val name = entity.name + + if (patternNoName.matcher(name).matches()) { + event.isCanceled = true + } + + val matcher = patternName.matcher(name) + if (matcher.matches()) { + entity.customNameTag = matcher.group(1) + } + } +}
\ 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 ecb3c541d..917b40b85 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt @@ -10,6 +10,7 @@ import at.hannibal2.skyhanni.utils.* 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.addAsSingletonList import at.hannibal2.skyhanni.utils.RenderUtils.drawString import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems import at.hannibal2.skyhanni.utils.StringUtils.removeColor @@ -25,7 +26,6 @@ import net.minecraftforge.event.entity.player.ItemTooltipEvent import net.minecraftforge.fml.common.eventhandler.EventPriority import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import net.minecraftforge.fml.common.gameevent.TickEvent -import java.util.* import java.util.regex.Pattern class GardenVisitorFeatures { @@ -77,12 +77,17 @@ class GardenVisitorFeatures { if (line.isEmpty()) break val (itemName, amount) = ItemUtils.readItemAmount(line) - if (itemName == null) continue + if (itemName == null) { + LorenzUtils.error("§c[SkyHanni] Could not read item '$line'") + continue + } val internalName = NEUItems.getInternalName(itemName) visitor.items[internalName] = amount } if (visitor.status == VisitorStatus.NEW) { + oldStatus(visitor) visitor.status = VisitorStatus.WAITING + statusChange(visitor) } update() @@ -111,7 +116,7 @@ class GardenVisitorFeatures { } } if (requiredItems.isNotEmpty()) { - newDisplay.add(Collections.singletonList("§7Visitor items needed:")) + newDisplay.addAsSingletonList("§7Visitor items needed:") for ((internalName, amount) in requiredItems) { val name = NEUItems.getItemStack(internalName).name!! val itemStack = NEUItems.getItemStack(internalName) @@ -132,11 +137,11 @@ class GardenVisitorFeatures { } if (newVisitors.isNotEmpty()) { if (requiredItems.isNotEmpty()) { - newDisplay.add(Collections.singletonList("")) + newDisplay.addAsSingletonList("") } val amount = newVisitors.size val visitorLabel = if (amount == 1) "visitor" else "visitors" - newDisplay.add(Collections.singletonList("§e$amount §7new $visitorLabel:")) + newDisplay.addAsSingletonList("§e$amount §7new $visitorLabel:") for (visitor in newVisitors) { val displayName = GardenVisitorColorNames.getColoredName(visitor) @@ -144,7 +149,12 @@ class GardenVisitorFeatures { list.add(" §7- $displayName") if (config.visitorItemPreview) { - val items = GardenVisitorColorNames.visitorItems[visitor.removeColor()]!! + val items = GardenVisitorColorNames.visitorItems[visitor.removeColor()] + if (items == null) { + LorenzUtils.debug("Visitor '$visitor' has no items in repo!") + list.add(" §7(§c?§7)") + continue + } list.add(" ") if (items.isEmpty()) { list.add("§7(§fAny§7)") @@ -173,7 +183,9 @@ class GardenVisitorFeatures { if (event.slotId != 33) return getVisitor(lastClickedNpc)?.let { + oldStatus(it) it.status = VisitorStatus.REFUSED + statusChange(it) update() } } @@ -278,6 +290,8 @@ class GardenVisitorFeatures { list.add(i + itemsWithSpeedCounter, " §7- $formatName($formatSpeed§7)") } } + } else { + LorenzUtils.error("§c[SkyHanni] Could not read item '$line'") } } @@ -343,7 +357,8 @@ class GardenVisitorFeatures { } for (name in visitorsInTab) { if (!visitors.containsKey(name)) { - visitors[name] = Visitor(status = VisitorStatus.NEW) + visitors[name] = Visitor(name, status = VisitorStatus.NEW) + LorenzUtils.debug("new visitor '$name'") if (config.visitorNotificationTitle) { SendTitleHelper.sendTitle("§eNew Visitor", 5_000) } @@ -364,7 +379,9 @@ class GardenVisitorFeatures { val visitorName = matcher.group(1) for (visitor in visitors) { if (visitor.key == visitorName) { + oldStatus(visitor.value) visitor.value.status = VisitorStatus.ACCEPTED + statusChange(visitor.value) update() } } @@ -386,7 +403,9 @@ class GardenVisitorFeatures { val status = visitor.status if (status == VisitorStatus.WAITING || status == VisitorStatus.READY) { + oldStatus(visitor) visitor.status = if (isReady(visitor)) VisitorStatus.READY else VisitorStatus.WAITING + statusChange(visitor) } if (config.visitorHighlightStatus == 0 || config.visitorHighlightStatus == 2) { @@ -405,6 +424,20 @@ class GardenVisitorFeatures { } } + val oldValue = mutableMapOf<Visitor, VisitorStatus>() + + private fun oldStatus(visitor: Visitor) { + oldValue[visitor] = visitor.status + } + + private fun statusChange(visitor: Visitor) { + val old = oldValue[visitor] + val new = visitor.status + if (old == new) return + val name = visitor.visitorName.removeColor() + LorenzUtils.debug("Visitor status change for $name: $old -> $new") + } + private fun Visitor.getEntity() = Minecraft.getMinecraft().theWorld.getEntityByID(entityId) private fun findEntity(nameTag: EntityArmorStand, visitor: Visitor) { @@ -497,6 +530,7 @@ class GardenVisitorFeatures { } class Visitor( + val visitorName: String, var entityId: Int = -1, var nameTagEntityId: Int = -1, var status: VisitorStatus, diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorTimer.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorTimer.kt index 820b819be..ea63fb54f 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorTimer.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorTimer.kt @@ -16,7 +16,7 @@ class GardenVisitorTimer { private var lastVisitors = 0 @SubscribeEvent - fun onTick(event: TabListUpdateEvent) { + fun onTabListUpdate(event: TabListUpdateEvent) { if (!isEnabled()) return var visitorsAmount = 0 diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/SkyMartBestProfit.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/SkyMartCopperPrice.kt index 790a7020f..7457224e6 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/SkyMartBestProfit.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/SkyMartCopperPrice.kt @@ -7,32 +7,30 @@ import at.hannibal2.skyhanni.events.InventoryOpenEvent 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.sortedDesc +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList import at.hannibal2.skyhanni.utils.NEUItems import at.hannibal2.skyhanni.utils.NumberUtil import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems -import at.hannibal2.skyhanni.utils.StringUtils.removeColor -import net.minecraft.client.Minecraft -import net.minecraft.item.ItemStack import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import java.util.* import java.util.regex.Pattern -class SkyMartBestProfit { - +class SkyMartCopperPrice { private val pattern = Pattern.compile("§c(.*) Copper") private var display = listOf<List<Any>>() private val config get() = SkyHanniMod.feature.garden + companion object { + var inInventory = false + } + @SubscribeEvent fun onInventoryOpen(event: InventoryOpenEvent) { if (!isEnabled()) return - if (event.inventoryName != "SkyMart") return - val priceMap = mutableMapOf<Pair<String, String>, Double>() - val iconMap = mutableMapOf<String, ItemStack>() - + inInventory = true + val table = mutableMapOf<Pair<String, String>, Pair<Double, String>>() for (stack in event.inventoryItems.values) { for (line in stack.getLore()) { val matcher = pattern.matcher(line) @@ -50,55 +48,37 @@ class SkyMartBestProfit { var name = stack.name!! if (name == "§fEnchanted Book") { - name = "§9Sunder I" + name = stack.getLore()[0] } - iconMap[name] = NEUItems.getItemStack(internalName) - val advancedStats = if (config.skyMartCopperPriceAdvancedStats) { " §7(§6$priceFormat §7/ §c$amountFormat Copper§7)" } else "" - val pair = Pair(name, "§6§l$perFormat$advancedStats") - priceMap[pair] = factor + val pair = Pair("$name§f:", "§6§l$perFormat$advancedStats") + table[pair] = Pair(factor, internalName) } } - display = drawDisplay(priceMap, iconMap) - } - - private fun drawDisplay( - priceMap: MutableMap<Pair<String, String>, Double>, - iconMap: MutableMap<String, ItemStack>, - ): MutableList<List<Any>> { val newList = mutableListOf<List<Any>>() - - newList.add(Collections.singletonList("Coins per §cCopper§f:")) - newList.add(Collections.singletonList("")) - - val keys = priceMap.sortedDesc().keys - val renderer = Minecraft.getMinecraft().fontRendererObj - val longest = keys.map { it.first }.maxOfOrNull { renderer.getStringWidth(it.removeColor()) } ?: 0 - - for ((name, second) in keys) { - val itemStack = iconMap[name]!! - var displayName = "$name§f:" - while (renderer.getStringWidth(displayName.removeColor()) < longest) { - displayName += " " - } - newList.add(listOf(itemStack, "$displayName $second")) - } - return newList + newList.addAsSingletonList("§eCoins per Copper§f:") + LorenzUtils.fillTable(newList, table) + display = newList } @SubscribeEvent fun onInventoryClose(event: InventoryCloseEvent) { - display = emptyList() + inInventory = false } @SubscribeEvent fun onBackgroundDraw(event: GuiRenderEvent.ChestBackgroundRenderEvent) { - if (isEnabled()) { - config.skyMartCopperPricePos.renderStringsAndItems(display, posLabel = "Sky Mart Copper Price") + if (inInventory) { + config.skyMartCopperPricePos.renderStringsAndItems( + display, + extraSpace = 5, + itemScale = 1.7, + posLabel = "Sky Mart Copper Price" + ) } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/HighlightBonzoMasks.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/HighlightBonzoMasks.kt index 371c0578d..ea1548117 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/HighlightBonzoMasks.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/HighlightBonzoMasks.kt @@ -5,15 +5,13 @@ import at.hannibal2.skyhanni.events.GuiContainerEvent import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName import at.hannibal2.skyhanni.utils.RenderUtils.highlight import at.hannibal2.skyhanni.utils.RenderUtils.interpolate +import net.minecraft.item.ItemStack import net.minecraftforge.client.event.ClientChatReceivedEvent import net.minecraftforge.event.world.WorldEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import java.awt.Color +import kotlin.time.* import kotlin.time.Duration.Companion.seconds -import kotlin.time.DurationUnit -import kotlin.time.ExperimentalTime -import kotlin.time.TimeMark -import kotlin.time.TimeSource /** * @author Linnea Gräf @@ -21,11 +19,14 @@ import kotlin.time.TimeSource @OptIn(ExperimentalTime::class) class HighlightBonzoMasks { - val bonzoMaskTimers = mutableMapOf<String, TimeMark>() + val maskTimers = mutableMapOf<String, CooldownTimer>() // Technically this timer is overestimating since the cooldown is affected by mage level, however I do not care. val bonzoMaskCooldown = 360.seconds - val bonzoMaskMessage = "Your (.*Bonzo's Mask) saved your life!".toRegex() + val bonzoMaskMessage = "^Your (.*Bonzo's Mask) saved your life!$".toRegex() + + val spiritMaskCooldown = 30.seconds + val spiritMaskMessage = "^Second Wind Activated! Your Spirit Mask saved your life!$".toRegex() val greenHue = Color.RGBtoHSB(0, 255, 0, null)[0].toDouble() val redHue = Color.RGBtoHSB(255, 0, 0, null)[0].toDouble() @@ -35,27 +36,47 @@ class HighlightBonzoMasks { if (!SkyHanniMod.feature.inventory.highlightDepletedBonzosMasks) return for (slot in event.gui.inventorySlots.inventorySlots) { val item = slot.stack ?: continue - val internalName = item.getInternalName() - if (!internalName.endsWith("BONZO_MASK")) continue - val timer = bonzoMaskTimers[internalName] ?: continue - if (timer.elapsedNow() < bonzoMaskCooldown) { - val progress = - timer.elapsedNow().toDouble(DurationUnit.SECONDS) / bonzoMaskCooldown.toDouble(DurationUnit.SECONDS) - val hue = interpolate(greenHue, redHue, progress.toFloat()) + val maskType = maskType(item) ?: continue + val timer = maskTimers[maskType] ?: continue + if (timer.isActive) { + val hue = interpolate(greenHue, redHue, timer.percentComplete.toFloat()) slot.highlight(Color(Color.HSBtoRGB(hue.toFloat(), 1F, 1F))) } } } + private fun maskType(item: ItemStack): String? { + return when (item.getInternalName()) { + "STARRED_BONZO_MASK" -> "BONZO_MASK" + "BONZO_MASK" -> "BONZO_MASK" + "SPIRIT_MASK" -> "SPIRIT_MASK" + else -> null + } + } + @SubscribeEvent fun onChatReceived(event: ClientChatReceivedEvent) { - val match = bonzoMaskMessage.matchEntire(event.message.unformattedText) ?: return - val bonzoId = if ("⚚" in match.groupValues[1]) "STARRED_BONZO_MASK" else "BONZO_MASK" - bonzoMaskTimers[bonzoId] = TimeSource.Monotonic.markNow() + val message = event.message.unformattedText + if (bonzoMaskMessage.matches(message)) { + maskTimers["BONZO_MASK"] = CooldownTimer(TimeSource.Monotonic.markNow(), bonzoMaskCooldown) + } else if (spiritMaskMessage.matches(message)) { + maskTimers["SPIRIT_MASK"] = CooldownTimer(TimeSource.Monotonic.markNow(), spiritMaskCooldown) + } } @SubscribeEvent fun onJoinWorld(ignored: WorldEvent.Load) { - bonzoMaskTimers.clear() + maskTimers.clear() } -}
\ No newline at end of file + + companion object { + data class CooldownTimer(val timeMark: TimeMark, val duration: Duration) { + val percentComplete: Double get() = + timeMark.elapsedNow().toDouble(DurationUnit.SECONDS) / duration.toDouble(DurationUnit.SECONDS) + + val isActive: Boolean get() = timeMark.elapsedNow() < duration + + } + } +} + diff --git a/src/main/java/at/hannibal2/skyhanni/features/itemabilities/abilitycooldown/ItemAbility.kt b/src/main/java/at/hannibal2/skyhanni/features/itemabilities/abilitycooldown/ItemAbility.kt index aca78fd0a..07745f573 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/itemabilities/abilitycooldown/ItemAbility.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/itemabilities/abilitycooldown/ItemAbility.kt @@ -17,35 +17,29 @@ enum class ItemAbility( GIANTS_SWORD(30), ICE_SPRAY_WAND(5), ATOMSPLIT_KATANA(4, "VORPAL_KATANA", "VOIDEDGE_KATANA"), - - - // TODO replace old logic - - HEAL_1("Small Heal", 7, "Wand of Healing"), - HEAL_2("Medium Heal", 7, "Wand of Mending"), - HEAL_3("Big Heal", 7, "Wand of Restoration"), - HEAL_4("Huge Heal", 7, "Wand of Atonement"), - - STAR_FALL("Starfall", 2, "Starlight Wand"), - VODOO_DOLL("Acupuncture", 5, "Voodoo Doll"), - INK_WAND("Ink Bomb", 30, "Ink Wand"), - GOLEM_SWORD("Iron Punch", 3, "Golem Sword"), - EMBER_ROD("Fire Blast", 30, "Ember Rod"), + RAGNAROCK_AXE(20), + WAND_OF_ATONEMENT(7, "WAND_OF_HEALING", "WAND_OF_MENDING", "WAND_OF_RESTORATION"), + + GOLEM_SWORD(3), + END_STONE_SWORD(5), + SOUL_ESOWARD(20), + PIGMAN_SWORD(5), + EMBER_ROD(30), + STAFF_OF_THE_VOLCANO(30), + STARLIGHT_WAND(2), + VOODOO_DOLL(5), + WEIRD_TUBA(20), + FIRE_FREEZE_STAFF(10), + SWORD_OF_BAD_HEALTH(5), + + // doesn't have a sound ENDER_BOW("Ender Warp", 30, "Ender Bow"), - LIVID_DAGGER("Throw", 5, "Livid Dagger"), - WEIRD_TUBA("Howl", 20, "Weird Tuba"), - - ENDSTONE_SWORD("Extreme Focus", 5, "End Stone Sword"), - PIGMAN_SWORD("Burning Souls", 5, "Pigman Sword"), - - SOULWARD("Soulward", 20, "Soul Esoward"), - ECHO("Echo", 3, "Ancestral Spade"), - FIRE_VEIL("Fire Veil", 5, "Fire Veil Wand"), - //TODO add new crimson isle weapons + INK_WAND("Ink Bomb", 30, "Ink Wand"), - ; + // doesn't have a consistent sound + ECHO("Echo", 3, "Ancestral Spade"); var newVariant = false var internalNames = mutableListOf<String>() diff --git a/src/main/java/at/hannibal2/skyhanni/features/itemabilities/abilitycooldown/ItemAbilityCooldown.kt b/src/main/java/at/hannibal2/skyhanni/features/itemabilities/abilitycooldown/ItemAbilityCooldown.kt index f96fce3f1..25858be8f 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/itemabilities/abilitycooldown/ItemAbilityCooldown.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/itemabilities/abilitycooldown/ItemAbilityCooldown.kt @@ -2,10 +2,7 @@ package at.hannibal2.skyhanni.features.itemabilities.abilitycooldown import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.data.ItemRenderBackground.Companion.background -import at.hannibal2.skyhanni.events.BlockClickEvent -import at.hannibal2.skyhanni.events.LorenzActionBarEvent -import at.hannibal2.skyhanni.events.PlaySoundEvent -import at.hannibal2.skyhanni.events.RenderItemTipEvent +import at.hannibal2.skyhanni.events.* import at.hannibal2.skyhanni.utils.ItemUtils import at.hannibal2.skyhanni.utils.ItemUtils.cleanName import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName @@ -13,6 +10,7 @@ import at.hannibal2.skyhanni.utils.LorenzColor import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.between import net.minecraft.client.Minecraft +import net.minecraft.item.Item import net.minecraft.item.ItemStack import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import net.minecraftforge.fml.common.gameevent.TickEvent @@ -50,15 +48,88 @@ class ItemAbilityCooldown { ItemAbility.ATOMSPLIT_KATANA.sound() } } + if (event.soundName == "random.click") { + if (event.pitch == 2.0f && event.volume == 0.55f) { + ItemAbility.RAGNAROCK_AXE.sound() + } + } + if (event.soundName == "liquid.lavapop") { + if (event.pitch == 0.7619048f && event.volume == 0.15f) { + ItemAbility.WAND_OF_ATONEMENT.sound() + } + } + if (event.soundName == "mob.bat.hurt") { + if (event.volume == 0.1f) { + ItemAbility.STARLIGHT_WAND.sound() + } + } + if (event.soundName == "mob.guardian.curse") { + if (event.volume == 0.2f) { + ItemAbility.VOODOO_DOLL.sound() + } + } + if (event.soundName == "random.explode") { + if (event.pitch == 4.047619f && event.volume == 0.2f) { + ItemAbility.GOLEM_SWORD.sound() + } + } + if (event.soundName == "mob.wolf.howl") { + if (event.volume == 0.5f) { + ItemAbility.WEIRD_TUBA.sound() + } + } + if (event.soundName == "mob.zombie.unfect") { + if (event.pitch == 2.0f && event.volume == 0.3f) { + ItemAbility.END_STONE_SWORD.sound() + } + } + if (event.soundName == "mob.wolf.panting") { + if (event.pitch == 1.3968254f && event.volume == 0.4f) { + ItemAbility.SOUL_ESOWARD.sound() + } + } + if (event.soundName == "mob.zombiepig.zpigangry") { + if (event.pitch == 2.0f && event.volume == 0.3f) { + ItemAbility.PIGMAN_SWORD.sound() + } + } + if (event.soundName == "mob.ghast.fireball") { + if (event.pitch == 1.0f && event.volume == 0.3f) { + ItemAbility.EMBER_ROD.sound() + } + } + if (event.soundName == "mob.guardian.elder.idle") { + if (event.pitch == 2.0f && event.volume == 0.2f) { + ItemAbility.FIRE_FREEZE_STAFF.sound() + } + } + if (event.soundName == "random.explode") { + if (event.pitch == 0.4920635f && event.volume == 0.5f) { + ItemAbility.STAFF_OF_THE_VOLCANO.sound() + } + } + if (event.soundName == "random.eat") { + if (event.pitch == 1.0f && event.volume == 1.0f) { + ItemAbility.STAFF_OF_THE_VOLCANO.sound() + } + } } @SubscribeEvent - fun onItemClickSend(event: BlockClickEvent) { - if (!LorenzUtils.inSkyBlock) return - val heldItem = event.itemInHand ?: return + fun onBlockClickSend(event: BlockClickEvent) { + handleItemClick(event.itemInHand) + } + + @SubscribeEvent + fun onItemClick(event: ItemClickEvent) { + handleItemClick(event.itemInHand) + } - val internalName = heldItem.getInternalName() - ItemAbility.getByInternalName(internalName)?.newClick() + private fun handleItemClick(itemInHand: ItemStack?) { + if (!LorenzUtils.inSkyBlock) return + itemInHand?.getInternalName()?.run { + ItemAbility.getByInternalName(this)?.newClick() + } } @SubscribeEvent diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/CrimsonIsleReputationHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/CrimsonIsleReputationHelper.kt index 2b79bbd42..ef9541d9f 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/CrimsonIsleReputationHelper.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/CrimsonIsleReputationHelper.kt @@ -8,6 +8,7 @@ import at.hannibal2.skyhanni.features.nether.reputationhelper.dailykuudra.DailyK import at.hannibal2.skyhanni.features.nether.reputationhelper.dailyquest.DailyQuestHelper import at.hannibal2.skyhanni.features.nether.reputationhelper.miniboss.DailyMiniBossHelper import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList import at.hannibal2.skyhanni.utils.LorenzVec import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems import at.hannibal2.skyhanni.utils.TabListData @@ -15,7 +16,6 @@ import com.google.gson.JsonObject import net.minecraftforge.fml.common.eventhandler.EventPriority import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import net.minecraftforge.fml.common.gameevent.TickEvent -import java.util.* class CrimsonIsleReputationHelper(skyHanniMod: SkyHanniMod) { @@ -79,7 +79,7 @@ class CrimsonIsleReputationHelper(skyHanniMod: SkyHanniMod) { //TODO test if (factionType == FactionType.NONE) return - newList.add(Collections.singletonList("Reputation Helper:")) + newList.addAsSingletonList("Reputation Helper:") questHelper.render(newList) miniBossHelper.render(newList) if (factionType == FactionType.MAGE) { diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailykuudra/DailyKuudraBossHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailykuudra/DailyKuudraBossHelper.kt index ce30ed3db..e8d69aa38 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailykuudra/DailyKuudraBossHelper.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailykuudra/DailyKuudraBossHelper.kt @@ -8,12 +8,12 @@ import at.hannibal2.skyhanni.features.nether.reputationhelper.CrimsonIsleReputat import at.hannibal2.skyhanni.test.GriffinUtils.drawWaypointFilled import at.hannibal2.skyhanni.utils.LorenzColor import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList import at.hannibal2.skyhanni.utils.LorenzVec import at.hannibal2.skyhanni.utils.NEUItems import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText import net.minecraftforge.client.event.RenderWorldLastEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import java.util.* import java.util.regex.Pattern class DailyKuudraBossHelper(private val reputationHelper: CrimsonIsleReputationHelper) { @@ -67,15 +67,15 @@ class DailyKuudraBossHelper(private val reputationHelper: CrimsonIsleReputationH fun render(display: MutableList<List<Any>>) { val done = kuudraTiers.count { it.doneToday } - display.add(Collections.singletonList("")) - display.add(Collections.singletonList("§7Daily Kuudra (§e$done§8/§e3 killed§7)")) + display.addAsSingletonList("") + display.addAsSingletonList("§7Daily Kuudra (§e$done§8/§e3 killed§7)") if (done != 2) { for (tier in kuudraTiers) { val result = if (tier.doneToday) "§7Done" else "§bTodo" val displayName = tier.getDisplayName() val displayItem = tier.displayItem if (displayItem == null) { - display.add(Collections.singletonList(" $displayName: $result")) + display.addAsSingletonList(" $displayName: $result") } else { val lineList = mutableListOf<Any>() lineList.add(" ") diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/DailyQuestHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/DailyQuestHelper.kt index 611330339..a6d06366a 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/DailyQuestHelper.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/DailyQuestHelper.kt @@ -13,6 +13,7 @@ import at.hannibal2.skyhanni.utils.* import at.hannibal2.skyhanni.utils.InventoryUtils.getInventoryName import at.hannibal2.skyhanni.utils.ItemUtils.getLore import at.hannibal2.skyhanni.utils.ItemUtils.name +import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText import at.hannibal2.skyhanni.utils.RenderUtils.highlight import net.minecraft.client.gui.inventory.GuiChest @@ -20,7 +21,6 @@ import net.minecraft.inventory.ContainerChest import net.minecraftforge.client.event.RenderWorldLastEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import net.minecraftforge.fml.common.gameevent.TickEvent -import java.util.* class DailyQuestHelper(val reputationHelper: CrimsonIsleReputationHelper) { @@ -223,8 +223,8 @@ class DailyQuestHelper(val reputationHelper: CrimsonIsleReputationHelper) { fun render(display: MutableList<List<Any>>) { val done = quests.count { it.state == QuestState.COLLECTED } - display.add(Collections.singletonList("")) - display.add(Collections.singletonList("§7Daily Quests (§e$done§8/§e5 collected§7)")) + display.addAsSingletonList("") + display.addAsSingletonList("§7Daily Quests (§e$done§8/§e5 collected§7)") if (done != 5) { quests.mapTo(display) { renderQuest(it) } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/DailyMiniBossHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/DailyMiniBossHelper.kt index 0eaa0be66..2e0673746 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/DailyMiniBossHelper.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/DailyMiniBossHelper.kt @@ -11,11 +11,11 @@ import at.hannibal2.skyhanni.test.GriffinUtils.drawWaypointFilled import at.hannibal2.skyhanni.utils.LocationUtils import at.hannibal2.skyhanni.utils.LorenzColor import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList import at.hannibal2.skyhanni.utils.NEUItems import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText import net.minecraftforge.client.event.RenderWorldLastEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import java.util.* import java.util.regex.Pattern class DailyMiniBossHelper(private val reputationHelper: CrimsonIsleReputationHelper) { @@ -75,15 +75,15 @@ class DailyMiniBossHelper(private val reputationHelper: CrimsonIsleReputationHel fun render(display: MutableList<List<Any>>) { val done = miniBosses.count { it.doneToday } - display.add(Collections.singletonList("")) - display.add(Collections.singletonList("§7Daily Bosses (§e$done§8/§e5 killed§7)")) + display.addAsSingletonList("") + display.addAsSingletonList("§7Daily Bosses (§e$done§8/§e5 killed§7)") if (done != 5) { for (miniBoss in miniBosses) { val result = if (miniBoss.doneToday) "§aDone" else "§bTodo" val displayName = miniBoss.displayName val displayItem = miniBoss.displayItem if (displayItem == null) { - display.add(Collections.singletonList(" $displayName: $result")) + display.addAsSingletonList(" $displayName: $result") } else { val lineList = mutableListOf<Any>() lineList.add(" ") diff --git a/src/main/java/at/hannibal2/skyhanni/test/LorenzTest.kt b/src/main/java/at/hannibal2/skyhanni/test/LorenzTest.kt index 9f78e5452..02feac91c 100644 --- a/src/main/java/at/hannibal2/skyhanni/test/LorenzTest.kt +++ b/src/main/java/at/hannibal2/skyhanni/test/LorenzTest.kt @@ -52,8 +52,8 @@ class LorenzTest { // SoundUtils.createSound(name, pitch).playSound() -// a = args[0].toDouble() -// b = args[1].toDouble() + a = args[0].toDouble() + b = args[1].toDouble() // c = args[2].toDouble() // for (line in (Minecraft.getMinecraft().ingameGUI.tabList as AccessorGuiPlayerTabOverlay).footer.unformattedText diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt index f11f45ee4..8e9b9de9e 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt @@ -14,6 +14,7 @@ import net.minecraft.util.ChatComponentText import java.text.DecimalFormat import java.text.NumberFormat import java.text.SimpleDateFormat +import java.util.* object LorenzUtils { @@ -166,4 +167,27 @@ object LorenzUtils { } fun getPlayerUuid() = Minecraft.getMinecraft().thePlayer.uniqueID.toDashlessUUID() + + fun <E> MutableList<List<E>>.addAsSingletonList(text: E) { + add(Collections.singletonList(text)) + } + + // (key -> value) -> (sorting value -> key item icon) + fun fillTable(list: MutableList<List<Any>>, data: MutableMap<Pair<String, String>, Pair<Double, String>>) { + val keys = data.mapValues { (_, v) -> v.first }.sortedDesc().keys + val renderer = Minecraft.getMinecraft().fontRendererObj + val longest = keys.map { it.first }.maxOfOrNull { renderer.getStringWidth(it.removeColor()) } ?: 0 + + for (pair in keys) { + val (name, second) = pair + var displayName = name + while (renderer.getStringWidth(displayName.removeColor()) < longest) { + displayName += " " + } + + NEUItems.getItemStackOrNull(data[pair]!!.second)?.let { + list.add(listOf(it, "$displayName $second")) + } + } + } }
\ 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 568ccbb87..1ce7c9e22 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt @@ -1,5 +1,6 @@ package at.hannibal2.skyhanni.utils +import at.hannibal2.skyhanni.features.bazaar.BazaarApi import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName import io.github.moulberry.notenoughupdates.NEUManager import io.github.moulberry.notenoughupdates.NotEnoughUpdates @@ -41,6 +42,17 @@ object NEUItems { } fun getPrice(internalName: String, useSellingPrice: Boolean = false): Double { + val bazaarData = BazaarApi.getBazaarDataForInternalName(internalName) + bazaarData?.let { + val buyPrice = it.buyPrice + if (buyPrice > 0) return buyPrice + + val sellPrice = it.sellPrice + if (sellPrice > 0) return sellPrice + + return it.npcPrice + } + val result = manager.auctionManager.getBazaarOrBin(internalName, useSellingPrice) // TODO remove workaround if (result == -1.0) { @@ -55,21 +67,26 @@ object NEUItems { return result } - fun getItemStack(internalName: String): ItemStack { + fun getItemStackOrNull(internalName: String): ItemStack? { if (itemCache.contains(internalName)) { return itemCache[internalName]!!.copy() } val itemStack = ItemResolutionQuery(manager) .withKnownInternalName(internalName) - .resolveToItemStack() - if (itemStack == null) { + .resolveToItemStack() ?: return null + itemCache[internalName] = itemStack + return itemStack.copy() + } + + fun getItemStack(internalName: String): ItemStack { + val stack = getItemStackOrNull(internalName) + if (stack == null) { val error = "ItemResolutionQuery returns null for internalName $internalName" LorenzUtils.error(error) throw RuntimeException(error) } - itemCache[internalName] = itemStack - return itemStack.copy() + return stack } fun isVanillaItem(item: ItemStack) = manager.auctionManager.isVanillaItem(item.getInternalName()) diff --git a/src/main/java/at/hannibal2/skyhanni/utils/SoundUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/SoundUtils.kt index 26f06df29..23d3fb603 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/SoundUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/SoundUtils.kt @@ -23,8 +23,9 @@ object SoundUtils { } } e.printStackTrace() + } finally { + gameSettings.setSoundLevel(SoundCategory.PLAYERS, oldLevel) } - gameSettings.setSoundLevel(SoundCategory.PLAYERS, oldLevel) } fun createSound(name: String, pitch: Float): ISound { diff --git a/src/main/java/at/hannibal2/skyhanni/utils/TabListData.kt b/src/main/java/at/hannibal2/skyhanni/utils/TabListData.kt index 1907d5f8f..1e42054ae 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/TabListData.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/TabListData.kt @@ -48,7 +48,7 @@ class TabListData { val name = Minecraft.getMinecraft().ingameGUI.tabList.getPlayerName(info) result.add(LorenzUtils.stripVanillaMessage(name)) } - return result + return result.dropLast(1) } private var ticks = 0 |