From c48d82d06f375139f1e0a0a32ffd6d2f4aa98546 Mon Sep 17 00:00:00 2001 From: J10a1n15 <45315647+j10a1n15@users.noreply.github.com> Date: Wed, 11 Sep 2024 13:56:56 +0200 Subject: Feature: Pet Nametag (#1880) Co-authored-by: Empa <42304516+ItsEmpa@users.noreply.github.com> Co-authored-by: Cal Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com> Co-authored-by: CalMWolfs <94038482+CalMWolfs@users.noreply.github.com> --- .../config/features/misc/pets/PetConfig.java | 5 + .../features/misc/pets/PetNametagConfig.java | 19 +++ .../skyhanni/features/misc/CurrentPetDisplay.kt | 98 ---------------- .../skyhanni/features/misc/PetCandyUsedDisplay.kt | 43 ------- .../skyhanni/features/misc/PetExpTooltip.kt | 127 --------------------- .../skyhanni/features/misc/PetItemDisplay.kt | 32 ------ .../features/misc/pets/CurrentPetDisplay.kt | 98 ++++++++++++++++ .../features/misc/pets/PetCandyUsedDisplay.kt | 43 +++++++ .../skyhanni/features/misc/pets/PetExpTooltip.kt | 127 +++++++++++++++++++++ .../skyhanni/features/misc/pets/PetItemDisplay.kt | 32 ++++++ .../skyhanni/features/misc/pets/PetNametag.kt | 56 +++++++++ 11 files changed, 380 insertions(+), 300 deletions(-) create mode 100644 src/main/java/at/hannibal2/skyhanni/config/features/misc/pets/PetNametagConfig.java delete mode 100644 src/main/java/at/hannibal2/skyhanni/features/misc/CurrentPetDisplay.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/features/misc/PetCandyUsedDisplay.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/features/misc/PetExpTooltip.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/features/misc/PetItemDisplay.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/misc/pets/CurrentPetDisplay.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/misc/pets/PetCandyUsedDisplay.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/misc/pets/PetExpTooltip.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/misc/pets/PetItemDisplay.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/misc/pets/PetNametag.kt diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/pets/PetConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/pets/PetConfig.java index 8cd295249..02c2b2ed4 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/misc/pets/PetConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/pets/PetConfig.java @@ -30,6 +30,11 @@ public class PetConfig { @Accordion public PetExperienceToolTipConfig petExperienceToolTip = new PetExperienceToolTipConfig(); + @Expose + @ConfigOption(name = "Pet Nametag", desc = "") + @Accordion + public PetNametagConfig nametag = new PetNametagConfig(); + @Expose @ConfigOption(name = "Hide Autopet Messages", desc = "Hide the autopet messages from chat.\n" + "§eRequires the display to be enabled.") diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/pets/PetNametagConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/pets/PetNametagConfig.java new file mode 100644 index 000000000..4da1b8160 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/pets/PetNametagConfig.java @@ -0,0 +1,19 @@ +package at.hannibal2.skyhanni.config.features.misc.pets; + +import com.google.gson.annotations.Expose; +import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorBoolean; +import io.github.notenoughupdates.moulconfig.annotations.ConfigOption; + +public class PetNametagConfig { + + @Expose + @ConfigOption(name = "Hide Pet Level", desc = "Hide the pet level above the pet.") + @ConfigEditorBoolean + public boolean hidePetLevel = false; + + @Expose + @ConfigOption(name = "Hide Max Pet Level", desc = "Hide the pet level above the pet if it is max level.") + @ConfigEditorBoolean + public boolean hideMaxPetLevel = false; + +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/CurrentPetDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/CurrentPetDisplay.kt deleted file mode 100644 index 1c93d6b3c..000000000 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/CurrentPetDisplay.kt +++ /dev/null @@ -1,98 +0,0 @@ -package at.hannibal2.skyhanni.features.misc - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator -import at.hannibal2.skyhanni.data.PetAPI -import at.hannibal2.skyhanni.events.GuiRenderEvent -import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.features.rift.RiftAPI -import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule -import at.hannibal2.skyhanni.utils.ItemUtils.getLore -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.RegexUtils.matchFirst -import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher -import at.hannibal2.skyhanni.utils.RegexUtils.matches -import at.hannibal2.skyhanni.utils.RenderUtils.renderString -import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -@SkyHanniModule -object CurrentPetDisplay { - - private val config get() = SkyHanniMod.feature.misc.pets - - private val patternGroup = RepoPattern.group("misc.currentpet") - private val inventorySelectedPetPattern by patternGroup.pattern( - "inventory.selected", - "§7§7Selected pet: (?.*)" - ) - private val chatSpawnPattern by patternGroup.pattern( - "chat.spawn", - "§aYou summoned your §r(?.*)§r§a!" - ) - private val chatDespawnPattern by patternGroup.pattern( - "chat.despawn", - "§aYou despawned your §r.*§r§a!" - ) - - /** - * REGEX-TEST: §cAutopet §eequipped your §7[Lvl 100] §6Griffin§4 ✦§e! §a§lVIEW RULE - * REGEX-TEST: §cAutopet §eequipped your §7[Lvl 100] §6Elephant§e! §a§lVIEW RULE - */ - private val chatPetRulePattern by patternGroup.pattern( - "chat.rule", - "§cAutopet §eequipped your §7\\[Lvl .*] (?.*)§e! §a§lVIEW RULE" - ) - - @SubscribeEvent - fun onChat(event: LorenzChatEvent) { - findPetInChat(event.message)?.let { - PetAPI.currentPet = it - if (config.hideAutopet) { - event.blockedReason = "pets" - } - } - } - - private fun findPetInChat(message: String): String? { - chatSpawnPattern.matchMatcher(message) { - return group("pet") - } - if (chatDespawnPattern.matches(message)) { - return "" - } - chatPetRulePattern.matchMatcher(message) { - return group("pet") - } - - return null - } - - @SubscribeEvent - fun onInventoryOpen(event: InventoryFullyOpenedEvent) { - if (!PetAPI.isPetMenu(event.inventoryName)) return - - val lore = event.inventoryItems[4]?.getLore() ?: return - lore.matchFirst(inventorySelectedPetPattern) { - val newPet = group("pet") - PetAPI.currentPet = if (newPet != "§cNone") newPet else "" - } - } - - @SubscribeEvent - fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) { - if (!LorenzUtils.inSkyBlock) return - if (RiftAPI.inRift()) return - - if (!config.display) return - - config.displayPos.renderString(PetAPI.currentPet, posLabel = "Current Pet") - } - - @SubscribeEvent - fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { - event.move(3, "misc.petDisplay", "misc.pets.display") - event.move(9, "misc.petDisplayPos", "misc.pets.displayPos") - } -} diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/PetCandyUsedDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/PetCandyUsedDisplay.kt deleted file mode 100644 index c80c30f09..000000000 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/PetCandyUsedDisplay.kt +++ /dev/null @@ -1,43 +0,0 @@ -package at.hannibal2.skyhanni.features.misc - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator -import at.hannibal2.skyhanni.events.GuiRenderItemEvent -import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.RenderUtils.drawSlotText -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getMaxPetLevel -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getPetCandyUsed -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getPetLevel -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -@SkyHanniModule -object PetCandyUsedDisplay { - - private val config get() = SkyHanniMod.feature.misc.petCandy - - @SubscribeEvent - fun onRenderItemOverlayPost(event: GuiRenderItemEvent.RenderOverlayEvent.GuiRenderItemPost) { - val stack = event.stack ?: return - if (!LorenzUtils.inSkyBlock || stack.stackSize != 1) return - if (!config.showCandy) return - - if (config.hideOnMaxed) { - if (stack.getPetLevel() == stack.getMaxPetLevel()) return - } - - val petCandyUsed = stack.getPetCandyUsed() ?: return - if (petCandyUsed == 0) return - - val stackTip = "§c$petCandyUsed" - val x = event.x + 13 - val y = event.y + 1 - - event.drawSlotText(x, y, stackTip, .9f) - } - - @SubscribeEvent - fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { - event.move(22, "misc.petCandyUsed", "misc.petCandy.showCandy") - } -} diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/PetExpTooltip.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/PetExpTooltip.kt deleted file mode 100644 index 3a7cf784a..000000000 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/PetExpTooltip.kt +++ /dev/null @@ -1,127 +0,0 @@ -package at.hannibal2.skyhanni.features.misc - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator -import at.hannibal2.skyhanni.events.LorenzToolTipEvent -import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule -import at.hannibal2.skyhanni.test.command.ErrorManager -import at.hannibal2.skyhanni.utils.ItemUtils.getItemRarityOrNull -import at.hannibal2.skyhanni.utils.ItemUtils.getLore -import at.hannibal2.skyhanni.utils.ItemUtils.name -import at.hannibal2.skyhanni.utils.KeyboardManager -import at.hannibal2.skyhanni.utils.LorenzRarity -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzUtils.round -import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators -import at.hannibal2.skyhanni.utils.NumberUtil.shortFormat -import at.hannibal2.skyhanni.utils.ReflectionUtils.makeAccessible -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getPetExp -import at.hannibal2.skyhanni.utils.StringUtils -import io.github.moulberry.notenoughupdates.NotEnoughUpdates -import net.minecraftforge.fml.common.eventhandler.EventPriority -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -@SkyHanniModule -object PetExpTooltip { - - private val config get() = SkyHanniMod.feature.misc.pets.petExperienceToolTip - private const val LEVEL_100_COMMON = 5_624_785 - private const val LEVEL_100_LEGENDARY = 25_353_230 - private const val LEVEL_200_LEGENDARY = 210_255_385 - - @SubscribeEvent(priority = EventPriority.LOWEST) - fun onItemTooltipLow(event: LorenzToolTipEvent) { - if (!LorenzUtils.inSkyBlock) return - if (!config.petDisplay) return - if (!KeyboardManager.isShiftKeyDown() && !config.showAlways) return - - val itemStack = event.itemStack - val petExperience = itemStack.getPetExp()?.round(1) ?: return - val name = itemStack.name - try { - - val index = findIndex(event.toolTip) ?: return - - val (maxLevel, maxXp) = getMaxValues(name, petExperience) - - val percentage = petExperience / maxXp - val percentageFormat = LorenzUtils.formatPercentage(percentage) - - if (percentage < 1) { - event.toolTip.add(index, " ") - val progressBar = StringUtils.progressBar(percentage) - val isBelowLegendary = itemStack.getItemRarityOrNull()?.let { it < LorenzRarity.LEGENDARY } ?: false - val addLegendaryColor = if (isBelowLegendary) "§6" else "" - event.toolTip.add( - index, - "$progressBar §e${petExperience.addSeparators()}§6/§e${maxXp.shortFormat()}" - ) - event.toolTip.add(index, "§7Progress to ${addLegendaryColor}Level $maxLevel: §e$percentageFormat") - } - } catch (e: Exception) { - ErrorManager.logErrorWithData( - e, "Could not add pet exp tooltip", - "itemStack" to itemStack, - "item name" to name, - "petExperience" to petExperience, - "toolTip" to event.toolTip, - "index" to findIndex(event.toolTip), - "getLore" to itemStack.getLore(), - ) - } - } - - private fun findIndex(toolTip: List): Int? { - var index = toolTip.indexOfFirst { it.contains("MAX LEVEL") } - if (index != -1) { - return index + 2 - } - - index = toolTip.indexOfFirst { it.contains("Progress to Level") } - if (index != -1) { - - val offset = if (isNeuExtendedExpEnabled) 4 else 3 - return index + offset - } - - return null - } - - private val isNeuExtendedExpEnabled get() = fieldPetExtendExp.get(objectNeuTooltipTweaks) as Boolean - - private val objectNeuTooltipTweaks by lazy { - val field = NotEnoughUpdates.INSTANCE.config.javaClass.getDeclaredField("tooltipTweaks") - field.makeAccessible().get(NotEnoughUpdates.INSTANCE.config) - } - - private val fieldPetExtendExp by lazy { - objectNeuTooltipTweaks.javaClass.getDeclaredField("petExtendExp").makeAccessible() - } - - private fun getMaxValues(petName: String, petExperience: Double): Pair { - val useGoldenDragonLevels = - petName.contains("Golden Dragon") && (!config.showGoldenDragonEgg || petExperience >= LEVEL_100_LEGENDARY) - - val maxLevel = if (useGoldenDragonLevels) 200 else 100 - - val maxXp = when { - useGoldenDragonLevels -> LEVEL_200_LEGENDARY // lvl 200 legendary - petName.contains("Bingo") -> LEVEL_100_COMMON - - else -> LEVEL_100_LEGENDARY - } - - return Pair(maxLevel, maxXp) - } - - @SubscribeEvent - fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { - event.move(3, "misc.petExperienceToolTip.petDisplay", "misc.pets.petExperienceToolTip.petDisplay") - event.move(3, "misc.petExperienceToolTip.showAlways", "misc.pets.petExperienceToolTip.showAlways") - event.move( - 3, - "misc.petExperienceToolTip.showGoldenDragonEgg", - "misc.pets.petExperienceToolTip.showGoldenDragonEgg" - ) - } -} diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/PetItemDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/PetItemDisplay.kt deleted file mode 100644 index 12e82a893..000000000 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/PetItemDisplay.kt +++ /dev/null @@ -1,32 +0,0 @@ -package at.hannibal2.skyhanni.features.misc - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.GuiRenderItemEvent -import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.RenderUtils.drawSlotText -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getPetItem -import net.minecraft.client.Minecraft -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -@SkyHanniModule -object PetItemDisplay { - - private val config get() = SkyHanniMod.feature.misc.pets - - @SubscribeEvent - fun onRenderItemOverlayPost(event: GuiRenderItemEvent.RenderOverlayEvent.GuiRenderItemPost) { - val stack = event.stack ?: return - if (!LorenzUtils.inSkyBlock || stack.stackSize != 1) return - if (config.petItemDisplay.isEmpty()) return - - val petItem = stack.getPetItem() ?: return - val icon = config.petItemDisplay.firstOrNull { it.item == petItem }?.icon ?: return - - val width = (Minecraft.getMinecraft().fontRendererObj.getStringWidth(icon) * config.petItemDisplayScale).toInt() - val x = event.x + 22 - width - val y = event.y - 1 - - event.drawSlotText(x, y, icon, config.petItemDisplayScale) - } -} diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/pets/CurrentPetDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/pets/CurrentPetDisplay.kt new file mode 100644 index 000000000..6f74f353d --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/pets/CurrentPetDisplay.kt @@ -0,0 +1,98 @@ +package at.hannibal2.skyhanni.features.misc.pets + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator +import at.hannibal2.skyhanni.data.PetAPI +import at.hannibal2.skyhanni.events.GuiRenderEvent +import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.features.rift.RiftAPI +import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule +import at.hannibal2.skyhanni.utils.ItemUtils.getLore +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.RegexUtils.matchFirst +import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher +import at.hannibal2.skyhanni.utils.RegexUtils.matches +import at.hannibal2.skyhanni.utils.RenderUtils.renderString +import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +@SkyHanniModule +object CurrentPetDisplay { + + private val config get() = SkyHanniMod.feature.misc.pets + + private val patternGroup = RepoPattern.group("misc.currentpet") + private val inventorySelectedPetPattern by patternGroup.pattern( + "inventory.selected", + "§7§7Selected pet: (?.*)" + ) + private val chatSpawnPattern by patternGroup.pattern( + "chat.spawn", + "§aYou summoned your §r(?.*)§r§a!" + ) + private val chatDespawnPattern by patternGroup.pattern( + "chat.despawn", + "§aYou despawned your §r.*§r§a!" + ) + + /** + * REGEX-TEST: §cAutopet §eequipped your §7[Lvl 100] §6Griffin§4 ✦§e! §a§lVIEW RULE + * REGEX-TEST: §cAutopet §eequipped your §7[Lvl 100] §6Elephant§e! §a§lVIEW RULE + */ + private val chatPetRulePattern by patternGroup.pattern( + "chat.rule", + "§cAutopet §eequipped your §7\\[Lvl .*] (?.*)§e! §a§lVIEW RULE" + ) + + @SubscribeEvent + fun onChat(event: LorenzChatEvent) { + findPetInChat(event.message)?.let { + PetAPI.currentPet = it + if (config.hideAutopet) { + event.blockedReason = "pets" + } + } + } + + private fun findPetInChat(message: String): String? { + chatSpawnPattern.matchMatcher(message) { + return group("pet") + } + if (chatDespawnPattern.matches(message)) { + return "" + } + chatPetRulePattern.matchMatcher(message) { + return group("pet") + } + + return null + } + + @SubscribeEvent + fun onInventoryOpen(event: InventoryFullyOpenedEvent) { + if (!PetAPI.isPetMenu(event.inventoryName)) return + + val lore = event.inventoryItems[4]?.getLore() ?: return + lore.matchFirst(inventorySelectedPetPattern) { + val newPet = group("pet") + PetAPI.currentPet = if (newPet != "§cNone") newPet else "" + } + } + + @SubscribeEvent + fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) { + if (!LorenzUtils.inSkyBlock) return + if (RiftAPI.inRift()) return + + if (!config.display) return + + config.displayPos.renderString(PetAPI.currentPet, posLabel = "Current Pet") + } + + @SubscribeEvent + fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { + event.move(3, "misc.petDisplay", "misc.pets.display") + event.move(9, "misc.petDisplayPos", "misc.pets.displayPos") + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/pets/PetCandyUsedDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/pets/PetCandyUsedDisplay.kt new file mode 100644 index 000000000..e331e6c75 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/pets/PetCandyUsedDisplay.kt @@ -0,0 +1,43 @@ +package at.hannibal2.skyhanni.features.misc.pets + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator +import at.hannibal2.skyhanni.events.GuiRenderItemEvent +import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.RenderUtils.drawSlotText +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getMaxPetLevel +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getPetCandyUsed +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getPetLevel +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +@SkyHanniModule +object PetCandyUsedDisplay { + + private val config get() = SkyHanniMod.feature.misc.petCandy + + @SubscribeEvent + fun onRenderItemOverlayPost(event: GuiRenderItemEvent.RenderOverlayEvent.GuiRenderItemPost) { + val stack = event.stack ?: return + if (!LorenzUtils.inSkyBlock || stack.stackSize != 1) return + if (!config.showCandy) return + + if (config.hideOnMaxed) { + if (stack.getPetLevel() == stack.getMaxPetLevel()) return + } + + val petCandyUsed = stack.getPetCandyUsed() ?: return + if (petCandyUsed == 0) return + + val stackTip = "§c$petCandyUsed" + val x = event.x + 13 + val y = event.y + 1 + + event.drawSlotText(x, y, stackTip, .9f) + } + + @SubscribeEvent + fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { + event.move(22, "misc.petCandyUsed", "misc.petCandy.showCandy") + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/pets/PetExpTooltip.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/pets/PetExpTooltip.kt new file mode 100644 index 000000000..8e544a3df --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/pets/PetExpTooltip.kt @@ -0,0 +1,127 @@ +package at.hannibal2.skyhanni.features.misc.pets + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator +import at.hannibal2.skyhanni.events.LorenzToolTipEvent +import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule +import at.hannibal2.skyhanni.test.command.ErrorManager +import at.hannibal2.skyhanni.utils.ItemUtils.getItemRarityOrNull +import at.hannibal2.skyhanni.utils.ItemUtils.getLore +import at.hannibal2.skyhanni.utils.ItemUtils.name +import at.hannibal2.skyhanni.utils.KeyboardManager +import at.hannibal2.skyhanni.utils.LorenzRarity +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.round +import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators +import at.hannibal2.skyhanni.utils.NumberUtil.shortFormat +import at.hannibal2.skyhanni.utils.ReflectionUtils.makeAccessible +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getPetExp +import at.hannibal2.skyhanni.utils.StringUtils +import io.github.moulberry.notenoughupdates.NotEnoughUpdates +import net.minecraftforge.fml.common.eventhandler.EventPriority +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +@SkyHanniModule +object PetExpTooltip { + + private val config get() = SkyHanniMod.feature.misc.pets.petExperienceToolTip + private const val LEVEL_100_COMMON = 5_624_785 + private const val LEVEL_100_LEGENDARY = 25_353_230 + private const val LEVEL_200_LEGENDARY = 210_255_385 + + @SubscribeEvent(priority = EventPriority.LOWEST) + fun onItemTooltipLow(event: LorenzToolTipEvent) { + if (!LorenzUtils.inSkyBlock) return + if (!config.petDisplay) return + if (!KeyboardManager.isShiftKeyDown() && !config.showAlways) return + + val itemStack = event.itemStack + val petExperience = itemStack.getPetExp()?.round(1) ?: return + val name = itemStack.name + try { + + val index = findIndex(event.toolTip) ?: return + + val (maxLevel, maxXp) = getMaxValues(name, petExperience) + + val percentage = petExperience / maxXp + val percentageFormat = LorenzUtils.formatPercentage(percentage) + + if (percentage < 1) { + event.toolTip.add(index, " ") + val progressBar = StringUtils.progressBar(percentage) + val isBelowLegendary = itemStack.getItemRarityOrNull()?.let { it < LorenzRarity.LEGENDARY } ?: false + val addLegendaryColor = if (isBelowLegendary) "§6" else "" + event.toolTip.add( + index, + "$progressBar §e${petExperience.addSeparators()}§6/§e${maxXp.shortFormat()}" + ) + event.toolTip.add(index, "§7Progress to ${addLegendaryColor}Level $maxLevel: §e$percentageFormat") + } + } catch (e: Exception) { + ErrorManager.logErrorWithData( + e, "Could not add pet exp tooltip", + "itemStack" to itemStack, + "item name" to name, + "petExperience" to petExperience, + "toolTip" to event.toolTip, + "index" to findIndex(event.toolTip), + "getLore" to itemStack.getLore(), + ) + } + } + + private fun findIndex(toolTip: List): Int? { + var index = toolTip.indexOfFirst { it.contains("MAX LEVEL") } + if (index != -1) { + return index + 2 + } + + index = toolTip.indexOfFirst { it.contains("Progress to Level") } + if (index != -1) { + + val offset = if (isNeuExtendedExpEnabled) 4 else 3 + return index + offset + } + + return null + } + + private val isNeuExtendedExpEnabled get() = fieldPetExtendExp.get(objectNeuTooltipTweaks) as Boolean + + private val objectNeuTooltipTweaks by lazy { + val field = NotEnoughUpdates.INSTANCE.config.javaClass.getDeclaredField("tooltipTweaks") + field.makeAccessible().get(NotEnoughUpdates.INSTANCE.config) + } + + private val fieldPetExtendExp by lazy { + objectNeuTooltipTweaks.javaClass.getDeclaredField("petExtendExp").makeAccessible() + } + + private fun getMaxValues(petName: String, petExperience: Double): Pair { + val useGoldenDragonLevels = + petName.contains("Golden Dragon") && (!config.showGoldenDragonEgg || petExperience >= LEVEL_100_LEGENDARY) + + val maxLevel = if (useGoldenDragonLevels) 200 else 100 + + val maxXp = when { + useGoldenDragonLevels -> LEVEL_200_LEGENDARY // lvl 200 legendary + petName.contains("Bingo") -> LEVEL_100_COMMON + + else -> LEVEL_100_LEGENDARY + } + + return Pair(maxLevel, maxXp) + } + + @SubscribeEvent + fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { + event.move(3, "misc.petExperienceToolTip.petDisplay", "misc.pets.petExperienceToolTip.petDisplay") + event.move(3, "misc.petExperienceToolTip.showAlways", "misc.pets.petExperienceToolTip.showAlways") + event.move( + 3, + "misc.petExperienceToolTip.showGoldenDragonEgg", + "misc.pets.petExperienceToolTip.showGoldenDragonEgg" + ) + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/pets/PetItemDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/pets/PetItemDisplay.kt new file mode 100644 index 000000000..9d3349c5b --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/pets/PetItemDisplay.kt @@ -0,0 +1,32 @@ +package at.hannibal2.skyhanni.features.misc.pets + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.GuiRenderItemEvent +import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.RenderUtils.drawSlotText +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getPetItem +import net.minecraft.client.Minecraft +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +@SkyHanniModule +object PetItemDisplay { + + private val config get() = SkyHanniMod.feature.misc.pets + + @SubscribeEvent + fun onRenderItemOverlayPost(event: GuiRenderItemEvent.RenderOverlayEvent.GuiRenderItemPost) { + val stack = event.stack ?: return + if (!LorenzUtils.inSkyBlock || stack.stackSize != 1) return + if (config.petItemDisplay.isEmpty()) return + + val petItem = stack.getPetItem() ?: return + val icon = config.petItemDisplay.firstOrNull { it.item == petItem }?.icon ?: return + + val width = (Minecraft.getMinecraft().fontRendererObj.getStringWidth(icon) * config.petItemDisplayScale).toInt() + val x = event.x + 22 - width + val y = event.y - 1 + + event.drawSlotText(x, y, icon, config.petItemDisplayScale) + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/pets/PetNametag.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/pets/PetNametag.kt new file mode 100644 index 000000000..f3b16069e --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/pets/PetNametag.kt @@ -0,0 +1,56 @@ +package at.hannibal2.skyhanni.features.misc.pets + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.entity.EntityDisplayNameEvent +import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.NumberUtil.formatInt +import at.hannibal2.skyhanni.utils.RegexUtils.groupOrNull +import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher +import at.hannibal2.skyhanni.utils.chat.Text.asComponent +import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern +import net.minecraft.entity.item.EntityArmorStand +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +@SkyHanniModule +object PetNametag { + + private val config get() = SkyHanniMod.feature.misc.pets.nametag + + /** + * REGEX-TEST: §8[§7Lv99§8] Ammonite + * REGEX-TEST: §8[§7Lv100§8] Endermite§5 ✦ + */ + private val petNametagPattern by RepoPattern.pattern( + "pet.nametag", + "(?§8\\[§7Lv(?\\d+)§8]) (?§.)(?[\\w\\s]+)(?§. ✦)?", + ) + + @SubscribeEvent + fun onNameTagRender(event: EntityDisplayNameEvent) { + if (!isEnabled()) return + if (event.entity !is EntityArmorStand) return + + petNametagPattern.matchMatcher(event.chatComponent.unformattedText) { + val start = group("start") + val lvl = group("lvl").formatInt() + val rarity = group("rarity") + val pet = group("pet") + val skin = groupOrNull("skin") ?: "" + + val hideLevel = config.hidePetLevel + val hideMaxLevel = config.hideMaxPetLevel && (lvl == 100 || lvl == 200) + + val text = buildString { + if (!hideLevel && !hideMaxLevel) { + append(start) + } + append(rarity + pet + skin) + } + + event.chatComponent = text.asComponent() + } + } + + private fun isEnabled() = LorenzUtils.inSkyBlock && (config.hidePetLevel || config.hideMaxPetLevel) +} -- cgit