diff --git a/CHANGELOG.md b/CHANGELOG.md index cfe6bc44e54e..a773164acb58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,21 @@ + Added Sea Creature Tracker. - hannibal2 + Allows to only show single variants, e.g. water or lava or winter. +#### Inventory Features + ++ Added Power Stone Guide features. - hannibal2 + + Highlight missing power stones, show their total bazaar price, and allows to open the bazaar when clicking on the + items in the Power Stone Guide. ++ Option to make normal clicks to shift clicks in equipment inventory. - Thunderblade73 + +#### Item Features + ++ Lesser Orb of Healing Hider. - jani + +#### Chat Features + ++ Add tab list fire sale advertisement hider. - nea + ### Changes #### Garden Changes @@ -29,6 +44,9 @@ + Don't count Bountiful as a max reforge fortune on tools. - alexia + /shcroptime now supports k, m and b numbers. - DylanBruner + Only show the Garden Vacuum Bag on your own vacuums. - alexia ++ Jacob Contest feature now has clickable calendar open command when Elite API is not ready yet. - alexia ++ Mark carrot/pumpkin fortune as completed when giving to Carrolyn after already done. - alexia ++ Added ability to get unique visitors served without Green Thumb. - alexia #### Rift Changes @@ -41,6 +59,7 @@ #### Fishing Changes + Odger highlight feature tells in description that it is only useful for users without abiphone. - hannibal2 ++ Added toggle to count double hook catches as two catches in Sea Creature Tracker. - hannibal2 #### Mining Changes @@ -60,6 +79,7 @@ #### Dungeon Changes + Changed the description of the Dungeon Chat Filter feature to be more descriptive. - Wambo ++ Added options to change exactly what part of the Dungeon Chat Filter should be used. - Wambo #### Chat Changes @@ -81,15 +101,21 @@ hannibal2 + Auto-fixing plots marked as pests when killing all pests without SkyHanni earlier. - hannibal2 + Fixed error message that nearest pests cannot get removed properly. - hannibal2 ++ Fixed grammar in Jacob Contest chat messages. - alexia ++ Fixed rarity error for items thrown around when using Sprayanator. - hannibal2 #### Combat Fixes + Fixed corrupted Kada Knight getting detected as Revenant Slayer mini boss. - hannibal2 ++ Fixed Daily Kuudra part of Crimson Isle Reputation Helper not detecting completed runs. - hannibal2 ++ Fixed wrong calculation when zero bosses killed in slayer profit trackers. - hannibal2 ++ Hide No Fishing Bait warning during Kuudra fight. - hannibal2 #### Mining Fixes + Fixed an error when showing all elements in Powder Tracker. - hannibal2 + Fixed powder tracker detecting gemstone chat messages. - CalMWolfs ++ Fixed Mining Chat Filter not hiding gemstone messages. - CalMWolfs #### Rift Fixes @@ -117,6 +143,10 @@ + Fixed poisoned candy potion chat message not getting compacted. - alexia +#### GUI Fixes + ++ Fixed items in SkyHanni GUI elements rendering over minecraft menus. - Thunderblade73 + #### Misc Fixes + Maybe fixed Tia Relay Helper. - Thunderblade73 @@ -138,6 +168,12 @@ + Moving minion craft helper fully over to neu internal names. - hannibal2 + Added information about trackers to the Discord FAQ. - j10a1n15 + Defined the way how dependent PRs should be written in contributing.md. - Thunderblade73 ++ Added debug command /shtestburrow. - hannibal2 ++ Using SkyHanniMod.coroutineScope instead of CoroutineScope(Dispatchers.Default). - CalMWolfs ++ Creating function addTotalProfit for item trackers. - hannibal2 ++ Tell people how to name a pattern variable. - CalMWolfs ++ Typo fixes in contributing md. - CalMWolfs ++ Make Repo Pattern keys more consistent for Farming Gear. - CalMWolfs ## Version 0.22 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 67d8e3c0b4c0..8df368ead409 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -71,14 +71,15 @@ format like "- #821" to illustrate the dependency. - See [this commit](https://github.com/hannibal002/SkyHanni/commit/3d748cb79f3a1afa7f1a9b7d0561e5d7bb284a9b) as an example. - Try to avoid using kotlin's `!!` (catch if not null) feature. - - Replace it with `?:` (ff null return this). - - This will most likely not be possible to avoid when working with obects from java. + - Replace it with `?:` (if null return this). + - This will most likely not be possible to avoid when working with objects from java. - Don't forget to add `@FeatureToggle` to new standalone features (not options to that feature) in the config. - Do not use `e.printStackTrace()`, use `CopyErrorCommand.logError(e, "explanation for users")` instead. - Do not use `MinecraftForge.EVENT_BUS.post(event)`, use `event.postAndCatch()` instead. - Do not use `toRegex()` or `toPattern()`, use `RepoPattern` instead. - See [RepoPattern.kt](https://github.com/walkerselby/SkyHanni/blob/beta/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPattern.kt) - for more information and usages. +for more information and usages. + - The pattern variables are named in the scheme `variableNamePattern` - Please use Regex instead of String comparison when it is likely Hypixel will change the message in the future. ## Software Used in SkyHanni @@ -116,8 +117,8 @@ For more information, see https://github.com/NotEnoughUpdates/MoulConfig SkyHanni utilizes the [Elite API](https://api.elitebot.dev/) (view the [public site here](https://elitebot.dev)) for some farming features. -This includes features relating to Farming Weight, as well as syncing jacob contests amongst players for conviencience. -All data sent is anonymonized and opt-in. +This includes features relating to Farming Weight, as well as syncing jacob contests amongst players for convenience. +All data sent is anonymized and opt-in. ### Mixin @@ -128,7 +129,7 @@ It allows to easily modify methods in Minecraft itself, without conflicting with For more information, see https://github.com/SpongePowered/Mixin or [our existing mixins](https://github.com/hannibal002/SkyHanni/tree/beta/src/main/java/at/hannibal2/skyhanni/mixins/transformers). -When creating new Mixins, try to keep the code inside of the mixin as small as possible, and calling a hook as soon as +When creating new Mixins, try to keep the code inside the mixin as small as possible, and calling a hook as soon as possible. ### Repo diff --git a/FEATURES.md b/FEATURES.md index 836aecfedff3..76a8ee2e16a7 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -30,6 +30,7 @@ Use `/sh` or `/skyhanni` to open the SkyHanni config in game. + Optional if left or right side of name. + Should not break with other mods. + Hide the repeating fire sale reminder chat messages. - hannibal2 ++ Add tab list fire sale advertisement hider. - nea #### Chat Filter @@ -132,6 +133,10 @@ Use `/sh` or `/skyhanni` to open the SkyHanni config in game. + This removes the need to shift-click to swap the equipment items, without the annoying "pick up animation". + Added Copy Underbid Price. - hannibal2 + Copies the price of an item in the "Create BIN Auction" minus 1 coin into the clipboard for faster under-bidding. ++ Added Power Stone Guide features. - hannibal2 + + Highlight missing power stones, show their total bazaar price, and allows to open the bazaar when clicking on the + items in the Power Stone Guide. ++ Option to make normal clicks to shift clicks in equipment inventory. - Thunderblade73
@@ -145,6 +150,7 @@ Use `/sh` or `/skyhanni` to open the SkyHanni config in game. + Supports dungeon mage cooldown reduction. - Cad + Hiding the flame particles when using the Fire Veil Wand ability. + Circle around the player when having the Fire Veil Wand ability active. ++ Lesser Orb of Healing Hider. - jani
diff --git a/build.gradle.kts b/build.gradle.kts index 23773b307343..e7f55fadd021 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ plugins { } group = "at.hannibal2.skyhanni" -version = "0.23.Beta.6" +version = "0.23.Beta.7" val gitHash by lazy { val baos = ByteArrayOutputStream() diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt index 218b2f88fd3d..a7d46b4ab740 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt @@ -205,10 +205,12 @@ import at.hannibal2.skyhanni.features.inventory.HideNotClickableItems import at.hannibal2.skyhanni.features.inventory.HighlightBonzoMasks import at.hannibal2.skyhanni.features.inventory.ItemDisplayOverlayFeatures import at.hannibal2.skyhanni.features.inventory.ItemStars +import at.hannibal2.skyhanni.features.inventory.PowerStoneGuideFeatures import at.hannibal2.skyhanni.features.inventory.QuickCraftFeatures import at.hannibal2.skyhanni.features.inventory.RngMeterInventory import at.hannibal2.skyhanni.features.inventory.SackDisplay import at.hannibal2.skyhanni.features.inventory.ShiftClickEquipment +import at.hannibal2.skyhanni.features.inventory.ShiftClickNPCSell import at.hannibal2.skyhanni.features.inventory.SkyBlockLevelGuideHelper import at.hannibal2.skyhanni.features.inventory.StatsTuning import at.hannibal2.skyhanni.features.inventory.tiarelay.TiaRelayHelper @@ -235,6 +237,7 @@ import at.hannibal2.skyhanni.features.misc.FixNEUHeavyPearls import at.hannibal2.skyhanni.features.misc.HideArmor import at.hannibal2.skyhanni.features.misc.InGameDateDisplay import at.hannibal2.skyhanni.features.misc.JoinCrystalHollows +import at.hannibal2.skyhanni.features.misc.LesserOrbHider import at.hannibal2.skyhanni.features.misc.LimboTimeTracker import at.hannibal2.skyhanni.features.misc.LockMouseLook import at.hannibal2.skyhanni.features.misc.MarkedPlayerManager @@ -365,7 +368,7 @@ import org.apache.logging.log4j.Logger clientSideOnly = true, useMetadata = true, guiFactory = "at.hannibal2.skyhanni.config.ConfigGuiForgeInterop", - version = "0.23.Beta.6", + version = "0.23.Beta.7", ) class SkyHanniMod { @Mod.EventHandler @@ -516,6 +519,7 @@ class SkyHanniMod { loadModule(SoopyGuessBurrow()) loadModule(DianaProfitTracker) loadModule(MythologicalCreatureTracker) + loadModule(ShiftClickNPCSell) loadModule(HighlightJerries()) loadModule(TheGreatSpook()) loadModule(GriffinBurrowHelper) @@ -529,10 +533,12 @@ class SkyHanniMod { loadModule(CompactBingoChat()) loadModule(BrewingStandOverlay()) loadModule(FishingTimer()) + loadModule(LesserOrbHider()) loadModule(FishingHookDisplay()) loadModule(CrimsonIsleReputationHelper(this)) loadModule(SharkFishCounter()) loadModule(SkyBlockLevelGuideHelper()) + loadModule(PowerStoneGuideFeatures()) loadModule(OdgerWaypoint()) loadModule(TiaRelayHelper()) loadModule(TiaRelayWaypoints()) 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 3c7aaaa12114..f3fce19846d9 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt +++ b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt @@ -16,6 +16,7 @@ import at.hannibal2.skyhanni.features.combat.ghostcounter.GhostUtil import at.hannibal2.skyhanni.features.commands.PartyCommands import at.hannibal2.skyhanni.features.event.diana.BurrowWarpHelper import at.hannibal2.skyhanni.features.event.diana.DianaProfitTracker +import at.hannibal2.skyhanni.features.event.diana.GriffinBurrowHelper import at.hannibal2.skyhanni.features.event.diana.InquisitorWaypointShare import at.hannibal2.skyhanni.features.event.diana.MythologicalCreatureTracker import at.hannibal2.skyhanni.features.event.jerry.frozentreasure.FrozenTreasureTracker @@ -317,6 +318,10 @@ object Commands { "shconfigsave", "Manually saving the config" ) { SkyHanniMod.configManager.saveConfig(ConfigFileType.FEATURES, "manual-command") } + registerCommand( + "shtestburrow", + "Sets a test burrow waypoint at your location" + ) { GriffinBurrowHelper.setTestBurrow(it) } } private fun developersCodingHelp() { diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/chat/ChatConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/chat/ChatConfig.java index 52ecc0aa3bc8..1784d916dcf9 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/chat/ChatConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/chat/ChatConfig.java @@ -4,10 +4,14 @@ import com.google.gson.annotations.Expose; import io.github.moulberry.moulconfig.annotations.Accordion; import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; +import io.github.moulberry.moulconfig.annotations.ConfigEditorDraggableList; import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind; import io.github.moulberry.moulconfig.annotations.ConfigOption; import org.lwjgl.input.Keyboard; +import java.util.ArrayList; +import java.util.List; + public class ChatConfig { @Expose @@ -32,10 +36,36 @@ public class ChatConfig { public ChatSymbols chatSymbols = new ChatSymbols(); @Expose - @ConfigOption(name = "Dungeon Filter", desc = "Hides pickup, reminder, buff, damage, ability, puzzle and end messages in Dungeons.") - @ConfigEditorBoolean - @FeatureToggle - public boolean dungeonMessages = true; + @ConfigOption(name = "Dungeon Filter", desc = "Hide specific message types in Dungeons.") + @ConfigEditorDraggableList + public List dungeonFilteredMessageTypes = new ArrayList<>(); + + + public enum DungeonMessageTypes { + PREPARE("§bPreparation"), + START("§aClass Buffs §r/ §cMort Dialogue"), + AMBIENCE("§bAmbience"), + PICKUP("§ePickup"), + REMINDER("§cReminder"), + BUFF("§dBlessings"), + NOT_POSSIBLE("§cNot possible"), + DAMAGE("§cDamage"), + ABILITY("§dAbilities"), + PUZZLE("§dPuzzle §r/ §cQuiz"), + END("§cEnd §a(End of run spam)"), + ; + + private final String name; + + DungeonMessageTypes(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } + } @Expose @ConfigOption(name = "Dungeon Boss Messages", desc = "Hide messages from the Watcher and bosses in the Dungeon.") diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/SeaCreatureTrackerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/SeaCreatureTrackerConfig.java index 91c26aa21108..4558e1413e35 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/SeaCreatureTrackerConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/SeaCreatureTrackerConfig.java @@ -27,4 +27,9 @@ public class SeaCreatureTrackerConfig { @ConfigOption(name = "Hide Chat", desc = "Hide the chat messages when catching a sea creature.") @ConfigEditorBoolean public boolean hideChat = false; + + @Expose + @ConfigOption(name = "Count Double", desc = "Count double hook catches as two catches.") + @ConfigEditorBoolean + public boolean countDouble = true; } diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java index 80ee5023312a..0aed8ec3f7c3 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java @@ -9,7 +9,6 @@ import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; import io.github.moulberry.moulconfig.annotations.ConfigEditorDraggableList; import io.github.moulberry.moulconfig.annotations.ConfigOption; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -155,6 +154,13 @@ public String toString() { @FeatureToggle public boolean highlightMissingSkyBlockLevelGuide = true; + @Expose + @ConfigOption(name = "Power Stone Guide", + desc = "Highlight missing power stones, show their total bazaar price, and allows to open the bazaar when clicking on the items in the Power Stone Guide.") + @ConfigEditorBoolean + @FeatureToggle + public boolean powerStoneGuide = true; + @Expose @ConfigOption(name = "Highlight Auctions", desc = "Highlight own items that are sold in green and that are expired in red.") @@ -177,9 +183,15 @@ public String toString() { public boolean copyUnderbidPrice = false; @Expose - @ConfigOption(name = "Shift Click Equipment", desc = "Makes normal clicks to shift clicks in equipment inventory") + @ConfigOption(name = "Shift Click Equipment", desc = "Makes normal clicks to shift clicks in equipment inventory.") @ConfigEditorBoolean @FeatureToggle public boolean shiftClickForEquipment = false; + @Expose + @ConfigOption(name = "Shift Click NPC sell", desc = "Makes normal clicks to shift clicks in npc inventory for selling.") + @ConfigEditorBoolean + @FeatureToggle + public boolean shiftClickNPCSell = false; + } diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/MiscConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/MiscConfig.java index 350f321f27c3..69db7f53d1b0 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/misc/MiscConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/MiscConfig.java @@ -203,6 +203,14 @@ public class MiscConfig { @FeatureToggle public boolean showTimeInLimbo = true; + @Expose + @ConfigOption( + name = "Lesser Orb of Healing Hider", + desc = "Hides the Lesser Orb of Healing.") + @ConfigEditorBoolean + @FeatureToggle + public boolean lesserOrbHider = false; + @Expose @ConfigOption( name = "Lock Mouse Message", diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/compacttablist/CompactTabListConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/compacttablist/CompactTabListConfig.java index 2236d886b6cf..4d5530ea39fc 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/misc/compacttablist/CompactTabListConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/compacttablist/CompactTabListConfig.java @@ -20,6 +20,11 @@ public class CompactTabListConfig { @ConfigEditorBoolean public boolean hideAdverts = false; + @Expose + @ConfigOption(name = "Hide Fire Sale Adverts", desc = "Hides fire sales from the tablist") + @ConfigEditorBoolean + public boolean hideFiresales = false; + @Expose @ConfigOption(name = "Advanced Player List", desc = "") @Accordion diff --git a/src/main/java/at/hannibal2/skyhanni/data/IslandType.kt b/src/main/java/at/hannibal2/skyhanni/data/IslandType.kt index aa942f5bc651..a3eef5dd9df5 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/IslandType.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/IslandType.kt @@ -5,7 +5,7 @@ enum class IslandType(val displayName: String, val modeName: String = "null") { PRIVATE_ISLAND("Private Island"), PRIVATE_ISLAND_GUEST("Private Island Guest"), THE_END("The End"), - KUUDRA_ARENA("Instanced"), + KUUDRA_ARENA("Kuudra"), CRIMSON_ISLE("Crimson Isle"), DWARVEN_MINES("Dwarven Mines"), DUNGEON_HUB("Dungeon Hub", "dungeon_hub"), diff --git a/src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt index 767643755893..90d68ed35a15 100644 --- a/src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt @@ -66,4 +66,9 @@ abstract class LorenzEvent : Event() { } fun postWithoutCatch() = MinecraftForge.EVENT_BUS.post(this) + + // TODO let walker use this function for all 101 other uses + fun cancel() { + isCanceled = true + } } diff --git a/src/main/java/at/hannibal2/skyhanni/events/SkipTabListLineEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/SkipTabListLineEvent.kt new file mode 100644 index 000000000000..0250b821f1f5 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/events/SkipTabListLineEvent.kt @@ -0,0 +1,11 @@ +package at.hannibal2.skyhanni.events + +import at.hannibal2.skyhanni.features.misc.compacttablist.TabLine +import net.minecraftforge.fml.common.eventhandler.Cancelable + +@Cancelable +data class SkipTabListLineEvent( + val line: TabLine, + val lastSubTitle: TabLine?, + val lastTitle: TabLine?, +) : LorenzEvent() diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilter.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilter.kt index a0037812c39a..48e1b0175732 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilter.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilter.kt @@ -281,8 +281,8 @@ class ChatFilter { // Powder Mining private val powderMiningPatterns = listOf( "§cYou need a stronger tool to mine (Amethyst|Ruby|Jade|Amber|Sapphire|Topaz) Gemstone Block§r§c.".toPattern(), - "§aYou received §r§f\\d* §r§f[❤❈☘⸕✎✧] §r§fRough (Ruby|Amethyst|Jade|Amber|Sapphire|Topaz) Gemstone§r§a\\.".toPattern(), - "§aYou received §r§f\\d §r§a[❤❈☘⸕✎✧] §r§aFlawed (Ruby|Amethyst|Jade|Amber|Sapphire|Topaz) Gemstone§r§a\\.".toPattern(), + "§aYou received §r§f\\d* §r§f[❤❈☘⸕✎✧] Rough (Ruby|Amethyst|Jade|Amber|Sapphire|Topaz) Gemstone§r§a\\.".toPattern(), + "§aYou received §r§f\\d §r§a[❤❈☘⸕✎✧] Flawed (Ruby|Amethyst|Jade|Amber|Sapphire|Topaz) Gemstone§r§a\\.".toPattern(), // Jungle "§aYou received §r§f\\d* §r§aSludge Juice§r§a\\.".toPattern(), diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonChatFilter.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonChatFilter.kt index 4bc4b3c46d39..3a29ac603288 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonChatFilter.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonChatFilter.kt @@ -1,12 +1,15 @@ package at.hannibal2.skyhanni.features.dungeon import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.config.features.chat.ChatConfig import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.StringUtils.matches import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import java.util.regex.Pattern +private typealias MessageTypes = ChatConfig.DungeonMessageTypes + class DungeonChatFilter { private val config get() = SkyHanniMod.feature.chat @@ -110,10 +113,7 @@ class DungeonChatFilter { "§4[STATUE] Oruo the Omniscient§r§f: §r§fI've had enough of you and your party fiddling with my buttons. Scram!", "§4[STATUE] Oruo the Omniscient§r§f: §r§fEnough! My buttons are not to be pressed with such lack of grace!" ) - private val unsortedBlockedPatterns = listOf( // TODO sort out and filter separately - "(.*) §r§ehas obtained §r§a§r§9Beating Heart§r§e!".toPattern() - ) - private val unsortedBlockedMessages = listOf( + private val ambienceMessages = listOf( "§5A shiver runs down your spine..." ) private val reminderMessages = listOf( @@ -133,7 +133,8 @@ class DungeonChatFilter { "§c(.*) §r§eYou picked up a Ability Damage Orb from (.*) §r§ehealing you for §r§c(.*) §r§eand granting you +§r§c(.*)% §r§eAbility Damage for §r§b10 §r§eseconds.".toPattern(), "§c(.*) §r§eYou picked up a Damage Orb from (.*) §r§ehealing you for §r§c(.*) §r§eand granting you +§r§c(.*)% §r§eDamage for §r§b10 §r§eseconds.".toPattern(), "(.*) §r§ehas obtained §r§a§r§9Premium Flesh§r§e!".toPattern(), - "§6§lRARE DROP! §r§9Beating Heart §r§b(.*)".toPattern() + "§6§lRARE DROP! §r§9Beating Heart §r§b(.*)".toPattern(), + "(.*) §r§ehas obtained §r§a§r§9Beating Heart§r§e!".toPattern() ) private val pickupMessages = listOf( "§fYou found a §r§dWither Essence§r§f! Everyone gains an extra essence!" @@ -161,37 +162,36 @@ class DungeonChatFilter { "§aYou can no longer consume or splash any potions during the remainder of this Dungeon run!", ) - private val messagesMap: Map> = mapOf( - "prepare" to prepareMessages, - "start" to startMessages, - "unsorted" to unsortedBlockedMessages, - "pickup" to pickupMessages, - "reminder" to reminderMessages, - "buff" to buffMessages, - "not_possible" to notPossibleMessages, - "damage" to damageMessages, - "ability" to abilityMessages, - "puzzle" to puzzleMessages, - ) - private val patternsMap: Map> = mapOf( - "prepare" to preparePatterns, - "start" to startPatterns, - "unsorted" to unsortedBlockedPatterns, - "pickup" to pickupPatterns, - "buff" to buffPatterns, - "damage" to damagePatterns, - "ability" to abilityPatterns, - "puzzle" to puzzlePatterns, - "end" to endPatterns, - ) - private val messagesEndsWithMap: Map> = mapOf( - "end" to endMessagesEndWith, + private val messagesMap: Map> = mapOf( + MessageTypes.PREPARE to prepareMessages, + MessageTypes.START to startMessages, + MessageTypes.AMBIENCE to ambienceMessages, + MessageTypes.PICKUP to pickupMessages, + MessageTypes.REMINDER to reminderMessages, + MessageTypes.BUFF to buffMessages, + MessageTypes.NOT_POSSIBLE to notPossibleMessages, + MessageTypes.DAMAGE to damageMessages, + MessageTypes.ABILITY to abilityMessages, + MessageTypes.PUZZLE to puzzleMessages, + ) + private val patternsMap: Map> = mapOf( + MessageTypes.PREPARE to preparePatterns, + MessageTypes.START to startPatterns, + MessageTypes.PICKUP to pickupPatterns, + MessageTypes.BUFF to buffPatterns, + MessageTypes.DAMAGE to damagePatterns, + MessageTypes.ABILITY to abilityPatterns, + MessageTypes.PUZZLE to puzzlePatterns, + MessageTypes.END to endPatterns, + ) + private val messagesEndsWithMap: Map> = mapOf( + MessageTypes.END to endMessagesEndWith, ) /// @SubscribeEvent fun onChatMessage(event: LorenzChatEvent) { - if (!LorenzUtils.onHypixel || !config.dungeonMessages) return + if (!LorenzUtils.onHypixel || config.dungeonFilteredMessageTypes.isEmpty()) return // Workaround since the potion message gets always sent at that moment when SkyBlock is set as false if (!LorenzUtils.inSkyBlock && !event.message.startsWith("§aYour active Potion Effects")) return @@ -204,26 +204,30 @@ class DungeonChatFilter { private fun block(message: String): String { when { - message.isPresent("prepare") -> return "prepare" - message.isPresent("start") -> return "start" + message.isFiltered(MessageTypes.PREPARE) -> return "prepare" + message.isFiltered(MessageTypes.START) -> return "start" } if (!LorenzUtils.inDungeons) return "" return when { - message.isPresent("unsorted") -> "unsorted" - message.isPresent("pickup") -> "pickup" - message.isPresent("reminder") -> "reminder" - message.isPresent("buff") -> "buff" - message.isPresent("not_possible") -> "not_possible" - message.isPresent("damage") -> "damage" - message.isPresent("ability") -> "ability" - message.isPresent("puzzle") -> "puzzle" - message.isPresent("end") -> "end" + message.isFiltered(MessageTypes.AMBIENCE) -> "ambience" + message.isFiltered(MessageTypes.PICKUP) -> "pickup" + message.isFiltered(MessageTypes.REMINDER) -> "reminder" + message.isFiltered(MessageTypes.BUFF) -> "buff" + message.isFiltered(MessageTypes.NOT_POSSIBLE) -> "not_possible" + message.isFiltered(MessageTypes.DAMAGE) -> "damage" + message.isFiltered(MessageTypes.ABILITY) -> "ability" + message.isFiltered(MessageTypes.PUZZLE) -> "puzzle" + message.isFiltered(MessageTypes.END) -> "end" else -> "" } } + private fun String.isFiltered(key: MessageTypes) : Boolean { + return config.dungeonFilteredMessageTypes.contains(key) && this.isPresent(key) + } + /** * Checks if the message is present in the list of messages or patterns * Checks against three maps that compare in different ways. @@ -234,7 +238,7 @@ class DungeonChatFilter { * @see patternsMap * @see messagesEndsWithMap */ - private fun String.isPresent(key: String): Boolean { + private fun String.isPresent(key: MessageTypes): Boolean { return this in (messagesMap[key] ?: emptyList()) || (patternsMap[key] ?: emptyList()).any { it.matches(this) } || (messagesEndsWithMap[key] ?: emptyList()).any { this.endsWith(it) } diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/diana/DianaProfitTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/event/diana/DianaProfitTracker.kt index 67468351f943..5b8776bec779 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/diana/DianaProfitTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/diana/DianaProfitTracker.kt @@ -81,19 +81,7 @@ object DianaProfitTracker { ) ) - val profitFormat = profit.addSeparators() - val profitPrefix = if (profit < 0) "§c" else "§6" - - val profitPerBurrow = profit / data.burrowsDug - val profitPerBurrowFormat = NumberUtil.format(profitPerBurrow) - - val text = "§eTotal Profit: $profitPrefix$profitFormat coins" - addAsSingletonList( - Renderable.hoverTips( - text, - listOf("§7Profit per burrow: $profitPrefix$profitPerBurrowFormat") - ) - ) + addAsSingletonList(tracker.addTotalProfit(profit, data.burrowsDug, "burrow")) tracker.addPriceFromButton(this) } diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/diana/GriffinBurrowHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/event/diana/GriffinBurrowHelper.kt index b611f77eef6d..da26ce43f9b9 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/diana/GriffinBurrowHelper.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/diana/GriffinBurrowHelper.kt @@ -3,6 +3,7 @@ package at.hannibal2.skyhanni.features.event.diana import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.data.EntityMovementData +import at.hannibal2.skyhanni.data.IslandType import at.hannibal2.skyhanni.events.BurrowDetectEvent import at.hannibal2.skyhanni.events.BurrowDugEvent import at.hannibal2.skyhanni.events.BurrowGuessEvent @@ -18,6 +19,7 @@ import at.hannibal2.skyhanni.utils.LocationUtils.distanceToPlayer import at.hannibal2.skyhanni.utils.LorenzColor import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy +import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland import at.hannibal2.skyhanni.utils.LorenzVec import at.hannibal2.skyhanni.utils.RenderUtils.draw3DLine import at.hannibal2.skyhanni.utils.RenderUtils.drawColor @@ -246,4 +248,46 @@ object GriffinBurrowHelper { } private fun isEnabled() = DianaAPI.isDoingDiana() + + fun setTestBurrow(strings: Array) { + if (!IslandType.HUB.isInIsland()) { + LorenzUtils.userError("You can only create test burrows on the hub island!") + return + } + + if (!isEnabled()) { + if (!config.alwaysDiana) { + LorenzUtils.clickableChat("§cEnable Always Diana in the config!", "sh always diana") + } else { + LorenzUtils.userError("Have an Ancestral Spade in the inventory!") + } + return + } + + if (strings.size != 1) { + LorenzUtils.userError("/shtestburrow ") + return + } + + val type: BurrowType = when (strings[0].lowercase()) { + "reset" -> { + particleBurrows = emptyMap() + update() + LorenzUtils.chat("Manually reset all burrow waypoints.") + return + } + "1", "start" -> BurrowType.START + "2", "mob" -> BurrowType.MOB + "3", "treasure" -> BurrowType.TREASURE + else -> { + LorenzUtils.userError("Unknown burrow type! Try 1-3 instead.") + return + } + } + + EntityMovementData.addToTrack(Minecraft.getMinecraft().thePlayer) + val location = LocationUtils.playerLocation().roundLocation() + particleBurrows = particleBurrows.editCopy { this[location] = type } + update() + } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingBaitWarnings.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingBaitWarnings.kt index 7688a7f9841b..7785da35649f 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingBaitWarnings.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingBaitWarnings.kt @@ -85,5 +85,5 @@ class FishingBaitWarnings { LorenzUtils.chat("You do not use any fishing baits!") } - private fun isEnabled() = LorenzUtils.inSkyBlock && FishingAPI.hasFishingRodInHand() + private fun isEnabled() = LorenzUtils.inSkyBlock && FishingAPI.hasFishingRodInHand() && !LorenzUtils.inKuudraFight } diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingProfitTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingProfitTracker.kt index 979fa845febf..1ccac83de993 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingProfitTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingProfitTracker.kt @@ -112,14 +112,7 @@ object FishingProfitTracker { ) ) - val profitFormat = profit.addSeparators() - val profitPrefix = if (profit < 0) "§c" else "§6" - - val profitPerCatch = profit / data.totalCatchAmount - val profitPerCatchFormat = NumberUtil.format(profitPerCatch) - - val text = "§eTotal Profit: $profitPrefix$profitFormat coins" - addAsSingletonList(Renderable.hoverTips(text, listOf("§7Profit per catch: $profitPrefix$profitPerCatchFormat"))) + addAsSingletonList(tracker.addTotalProfit(profit, data.totalCatchAmount, "catch")) tracker.addPriceFromButton(this) } diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/SeaCreatureTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/SeaCreatureTracker.kt index 6a1e1a382732..c9168c306dd5 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/SeaCreatureTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/SeaCreatureTracker.kt @@ -42,7 +42,7 @@ object SeaCreatureTracker { if (!isEnabled()) return tracker.modify { - val amount = if (event.doubleHook) 2 else 1 + val amount = if (event.doubleHook && config.countDouble) 2 else 1 it.amount.addOrPut(event.seaCreature.name, amount) } diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt index d40d02718b16..c7f05d807789 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt @@ -139,6 +139,12 @@ class FarmingFortuneDisplay { if (upgradeFortune == null) { updatedDisplay.addAsSingletonList("§cOpen §e/cropupgrades§c for more exact data!") } + + val uniqueVisitors = GardenAPI.storage?.uniqueVisitors?.toDouble() ?: 0.0 + if (uniqueVisitors == 0.0) { + updatedDisplay.addAsSingletonList("§cOpen §e/visitormilestones§c for more exact data!") + } + if (accessoryFortune == null) { updatedDisplay.addAsSingletonList("§cOpen Accessory Bag for more exact data!") if (CropAccessoryData.isLoadingAccessories) { 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 f6ece600ba5d..e2fa5b63f382 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt @@ -194,7 +194,7 @@ object GardenNextJacobContest { sendContests() } else { LorenzUtils.clickableChat( - "§2Click here to submit this years farming contests, thank you for helping everyone out!", + "§2Click here to submit this year's farming contests. Thank you for helping everyone out!", "shsendcontests" ) } @@ -294,7 +294,7 @@ object GardenNextJacobContest { if (isCloseToNewYear()) { list.add(closeToNewYear) } else { - list.add("§cOpen calendar to read jacob contest times!") + list.add("§cOpen calendar to read Jacob contest times!") } return list } @@ -308,7 +308,7 @@ object GardenNextJacobContest { if (isCloseToNewYear()) { list.add(closeToNewYear) } else { - list.add("§cOpen calendar to read jacob contest times!") + list.add("§cOpen calendar to read Jacob contest times!") } fetchedFromElite = false @@ -503,7 +503,8 @@ object GardenNextJacobContest { newContests[timeMark + contestDuration] = FarmingContest(timeMark + contestDuration, crops) } } else { - LorenzUtils.chat("This years contests aren't available to fetch automatically yet, please load them from your calender or wait 10 minutes!") + LorenzUtils.chat("This year's contests aren't available to fetch automatically yet, please load them from your calendar or wait 10 minutes.") + LorenzUtils.clickableChat("Click here to open your calendar!", "calendar") } if (newContests.count() == maxContestsPerYear) { diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CaptureFarmingGear.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CaptureFarmingGear.kt index f9cafd982ca5..dd457688ad74 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CaptureFarmingGear.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CaptureFarmingGear.kt @@ -1,5 +1,6 @@ package at.hannibal2.skyhanni.features.garden.fortuneguide +import at.hannibal2.skyhanni.config.Storage import at.hannibal2.skyhanni.data.ProfileStorageData import at.hannibal2.skyhanni.events.GardenToolChangeEvent import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent @@ -18,6 +19,8 @@ import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getEnchantments import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.StringUtils.removeColor import at.hannibal2.skyhanni.utils.TabListData +import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern +import net.minecraft.item.ItemStack import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import kotlin.math.round import kotlin.time.Duration.Companion.days @@ -37,6 +40,16 @@ class CaptureFarmingGear { private val cakePattern = "(?:Big )?Yum! You (?:gain|refresh) [+]5☘ Farming Fortune for 48 hours!".toPattern() + private val patternGroup = RepoPattern.group("garden.fortuneguide.capture") + private val tierPattern by patternGroup.pattern( + "uniquevisitors.tier", + "§7Progress to Tier (?\\d+):.*" + ) + private val tierProgressPattern by patternGroup.pattern( + "uniquevisitors.tierprogress", + ".* §e(?.*)§6/(?.*)" + ) + companion object { private val strengthPattern = " Strength: §r§c❁(?.*)".toPattern() private val farmingSets = arrayListOf( @@ -90,6 +103,16 @@ class CaptureFarmingGear { storage.pumpkinFortune = !storage.pumpkinFortune LorenzUtils.chat("Toggled expired pumpkin fortune to: ${storage.pumpkinFortune}") } + + private fun getUniqueVisitorsForTier(tier: Int): Int { + return when { + tier == 0 -> 0 + tier == 1 -> 1 + tier == 2 -> 5 + tier >= 3 -> 10 * (tier - 2) + else -> throw IllegalStateException("Unexpected unique visitors tier: $tier") + } + } } @SubscribeEvent @@ -103,115 +126,167 @@ class CaptureFarmingGear { val storage = GardenAPI.storage?.fortune ?: return val farmingItems = farmingItems ?: return val outdatedItems = outdatedItems ?: return - if (event.inventoryName == "Your Equipment and Stats") { - for ((_, slot) in event.inventoryItems) { - val split = slot.getInternalName().asString().split("_") - if (split.first() == "LOTUS") { - for (item in FarmingItems.entries) { - if (item.name == split.last()) { - farmingItems[item] = slot - outdatedItems[item] = false - } - } - FarmingFortuneDisplay.loadFortuneLineData(slot, 0.0) - val enchantments = slot.getEnchantments() ?: emptyMap() - val greenThumbLvl = (enchantments["green_thumb"] ?: continue) - val visitors = FarmingFortuneDisplay.greenThumbFortune / (greenThumbLvl * 0.05) - GardenAPI.storage?.uniqueVisitors = round(visitors).toInt() + val items = event.inventoryItems + when (event.inventoryName) { + "Your Equipment and Stats" -> equipmentAndStats(items, farmingItems, outdatedItems) + "Pets" -> pets(farmingItems, items, outdatedItems) + "Your Skills" -> skills(items, storage) + "Community Shop" -> communityShop(items) + "Configure Plots" -> configurePlots(items, storage) + "Anita" -> anita(items, storage) + "Visitor Milestones" -> visitorMilestones(items) + } + } + + private fun visitorMilestones(items: Map) { + for ((_, item) in items) { + if (item.displayName != "§aUnique Visitors Served") continue + + var tier = -1 + var tierProgress = -1 + for (line in item.getLore()) { + tierPattern.matchMatcher(line) { + tier = group("nextTier").toInt() - 1 } + tierProgressPattern.matchMatcher(line) { + tierProgress = group("having").toInt() + } + } + if (tier > -1 && tierProgress > -1) { + GardenAPI.storage?.uniqueVisitors = getUniqueVisitorsForTier(tier) + tierProgress } } - if (event.inventoryName.contains("Pets")) { - // If they've 2 of same pet, one will be overwritten - // optimize + } - for (pet in listOf( - FarmingItems.ELEPHANT, - FarmingItems.MOOSHROOM_COW, - FarmingItems.RABBIT, - FarmingItems.BEE - )) { - if (farmingItems[pet] == null) { - farmingItems[pet] = FFGuideGUI.getFallbackItem(pet) + private fun anita( + items: Map, + storage: Storage.ProfileSpecific.GardenStorage.Fortune + ) { + var level = -1 + for ((_, item) in items) { + if (item.displayName.contains("Extra Farming Fortune")) { + level = 0 + for (line in item.getLore()) { + anitaMenuPattern.matchMatcher(line) { + level = group("level").toInt() / 4 + } } } + } + if (level == -1) { + storage.anitaUpgrade = 15 + } else { + storage.anitaUpgrade = level + } + } - // setting to current saved level -1 to stop later pages saving low rarity pets - var highestElephantRarity = (farmingItems[FarmingItems.ELEPHANT]?.getItemRarityOrNull()?.id ?: -1) - 1 - var highestMooshroomRarity = (farmingItems[FarmingItems.MOOSHROOM_COW]?.getItemRarityOrNull()?.id ?: -1) - 1 - var highestRabbitRarity = (farmingItems[FarmingItems.RABBIT]?.getItemRarityOrNull()?.id ?: -1) - 1 - var highestBeeRarity = (farmingItems[FarmingItems.BEE]?.getItemRarityOrNull()?.id ?: -1) - 1 + private fun configurePlots( + items: Map, + storage: Storage.ProfileSpecific.GardenStorage.Fortune + ) { + var plotsUnlocked = 24 + for (slot in items) { + if (slot.value.getLore().contains("§7Cost:")) { + plotsUnlocked -= 1 + } + } + storage.plotsUnlocked = plotsUnlocked + } - for ((_, item) in event.inventoryItems) { - val split = item.getInternalName().asString().split(";") - if (split.first() == "ELEPHANT" && split.last().toInt() > highestElephantRarity) { - farmingItems[FarmingItems.ELEPHANT] = item - outdatedItems[FarmingItems.ELEPHANT] = false - highestElephantRarity = split.last().toInt() - } - if (split.first() == "MOOSHROOM_COW" && split.last().toInt() > highestMooshroomRarity) { - farmingItems[FarmingItems.MOOSHROOM_COW] = item - outdatedItems[FarmingItems.MOOSHROOM_COW] = false - highestMooshroomRarity = split.last().toInt() - } - if (split.first() == "RABBIT" && split.last().toInt() > highestRabbitRarity) { - farmingItems[FarmingItems.RABBIT] = item - outdatedItems[FarmingItems.RABBIT] = false - highestRabbitRarity = split.last().toInt() - } - if (split.first() == "BEE" && split.last().toInt() > highestBeeRarity) { - farmingItems[FarmingItems.BEE] = item - outdatedItems[FarmingItems.BEE] = false - highestBeeRarity = split.last().toInt() + private fun communityShop(items: Map) { + for ((_, item) in items) { + if (item.displayName.contains("Garden Farming Fortune")) { + if (item.getLore().contains("§aMaxed out!")) { + ProfileStorageData.playerSpecific?.gardenCommunityUpgrade = + item.displayName.split(" ").last().romanToDecimal() + } else { + ProfileStorageData.playerSpecific?.gardenCommunityUpgrade = + item.displayName.split(" ").last().romanToDecimal() - 1 } } } + } - if (event.inventoryName.contains("Your Skills")) { - for ((_, item) in event.inventoryItems) { - if (item.displayName.contains("Farming ")) { - storage.farmingLevel = item.displayName.split(" ").last().romanToDecimalIfNecessary() - } + private fun skills( + items: Map, + storage: Storage.ProfileSpecific.GardenStorage.Fortune + ) { + for ((_, item) in items) { + if (item.displayName.contains("Farming ")) { + storage.farmingLevel = item.displayName.split(" ").last().romanToDecimalIfNecessary() } } - if (event.inventoryName.contains("Community Shop")) { - for ((_, item) in event.inventoryItems) { - if (item.displayName.contains("Garden Farming Fortune")) { - if (item.getLore().contains("§aMaxed out!")) { - ProfileStorageData.playerSpecific?.gardenCommunityUpgrade = - item.displayName.split(" ").last().romanToDecimal() - } else { - ProfileStorageData.playerSpecific?.gardenCommunityUpgrade = - item.displayName.split(" ").last().romanToDecimal() - 1 - } - } + } + + private fun pets( + farmingItems: MutableMap, + items: Map, + outdatedItems: MutableMap + ) { + // If they've 2 of same pet, one will be overwritten + // optimize + + for (pet in listOf( + FarmingItems.ELEPHANT, + FarmingItems.MOOSHROOM_COW, + FarmingItems.RABBIT, + FarmingItems.BEE + )) { + if (farmingItems[pet] == null) { + farmingItems[pet] = FFGuideGUI.getFallbackItem(pet) } } - if (event.inventoryName.contains("Configure Plots")) { - var plotsUnlocked = 24 - for (slot in event.inventoryItems) { - if (slot.value.getLore().contains("§7Cost:")) { - plotsUnlocked -= 1 - } + + // setting to current saved level -1 to stop later pages saving low rarity pets + var highestElephantRarity = (farmingItems[FarmingItems.ELEPHANT]?.getItemRarityOrNull()?.id ?: -1) - 1 + var highestMooshroomRarity = (farmingItems[FarmingItems.MOOSHROOM_COW]?.getItemRarityOrNull()?.id ?: -1) - 1 + var highestRabbitRarity = (farmingItems[FarmingItems.RABBIT]?.getItemRarityOrNull()?.id ?: -1) - 1 + var highestBeeRarity = (farmingItems[FarmingItems.BEE]?.getItemRarityOrNull()?.id ?: -1) - 1 + + for ((_, item) in items) { + val split = item.getInternalName().asString().split(";") + if (split.first() == "ELEPHANT" && split.last().toInt() > highestElephantRarity) { + farmingItems[FarmingItems.ELEPHANT] = item + outdatedItems[FarmingItems.ELEPHANT] = false + highestElephantRarity = split.last().toInt() + } + if (split.first() == "MOOSHROOM_COW" && split.last().toInt() > highestMooshroomRarity) { + farmingItems[FarmingItems.MOOSHROOM_COW] = item + outdatedItems[FarmingItems.MOOSHROOM_COW] = false + highestMooshroomRarity = split.last().toInt() + } + if (split.first() == "RABBIT" && split.last().toInt() > highestRabbitRarity) { + farmingItems[FarmingItems.RABBIT] = item + outdatedItems[FarmingItems.RABBIT] = false + highestRabbitRarity = split.last().toInt() + } + if (split.first() == "BEE" && split.last().toInt() > highestBeeRarity) { + farmingItems[FarmingItems.BEE] = item + outdatedItems[FarmingItems.BEE] = false + highestBeeRarity = split.last().toInt() } - storage.plotsUnlocked = plotsUnlocked } - if (event.inventoryName.contains("Anita")) { - var level = -1 - for ((_, item) in event.inventoryItems) { - if (item.displayName.contains("Extra Farming Fortune")) { - level = 0 - for (line in item.getLore()) { - anitaMenuPattern.matchMatcher(line) { - level = group("level").toInt() / 4 - } + } + + private fun equipmentAndStats( + items: Map, + farmingItems: MutableMap, + outdatedItems: MutableMap + ) { + for ((_, slot) in items) { + val split = slot.getInternalName().asString().split("_") + if (split.first() == "LOTUS") { + for (item in FarmingItems.entries) { + if (item.name == split.last()) { + farmingItems[item] = slot + outdatedItems[item] = false } } - } - if (level == -1) { - storage.anitaUpgrade = 15 - } else { - storage.anitaUpgrade = level + FarmingFortuneDisplay.loadFortuneLineData(slot, 0.0) + val enchantments = slot.getEnchantments() ?: emptyMap() + val greenThumbLvl = (enchantments["green_thumb"] ?: continue) + val visitors = FarmingFortuneDisplay.greenThumbFortune / (greenThumbLvl * 0.05) + GardenAPI.storage?.uniqueVisitors = round(visitors).toInt() } } } @@ -256,5 +331,13 @@ class CaptureFarmingGear { if (msg == "PUMPKINS EXPORTATION COMPLETE!") { storage.pumpkinFortune = true } + if (msg == "[NPC] Carrolyn: Thank you for the carrots.") { + storage.carrotFortune = true + LorenzUtils.chat("§aYou have already given Carrolyn enough Exportable Carrots.") + } + if (msg == "[NPC] Carrolyn: Thank you for the pumpkins.") { + storage.pumpkinFortune = true + LorenzUtils.chat("§aYou have already given Carrolyn enough Expired Pumpkins.") + } } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt index 8f0c6be6aaad..f9962b5c80d8 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt @@ -33,9 +33,9 @@ object HarpFeatures { } private val buttonColors = listOf('d', 'e', 'a', '2', '5', '9', 'b') - private val inventoryTitleRegex by RepoPattern.pattern("harp.inventory", "^Harp.*") + private val inventoryTitlePattern by RepoPattern.pattern("harp.inventory", "^Harp.*") - private fun isHarpGui() = inventoryTitleRegex.matches(openInventoryName()) + private fun isHarpGui() = inventoryTitlePattern.matches(openInventoryName()) @SubscribeEvent fun onGui(event: GuiScreenEvent) { diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/HideNotClickableItems.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/HideNotClickableItems.kt index 5a563c254819..aa93dfd72aad 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/HideNotClickableItems.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/HideNotClickableItems.kt @@ -6,7 +6,6 @@ import at.hannibal2.skyhanni.data.ItemRenderBackground.Companion.background import at.hannibal2.skyhanni.data.ItemRenderBackground.Companion.borderLine import at.hannibal2.skyhanni.data.jsonobjects.repo.HideNotClickableItemsJson import at.hannibal2.skyhanni.data.jsonobjects.repo.HideNotClickableItemsJson.SalvageFilter -import at.hannibal2.skyhanni.data.jsonobjects.repo.MultiFilterJson import at.hannibal2.skyhanni.events.GuiContainerEvent import at.hannibal2.skyhanni.events.RepositoryReloadEvent import at.hannibal2.skyhanni.features.bazaar.BazaarApi @@ -49,16 +48,12 @@ class HideNotClickableItems { private val hideNpcSellFilter = MultiFilter() private val hideInStorageFilter = MultiFilter() - private val tradeNpcFilter = MultiFilter() private val itemsToSalvage = mutableListOf() private val hidePlayerTradeFilter = MultiFilter() private val notAuctionableFilter = MultiFilter() @SubscribeEvent fun onRepoReload(event: RepositoryReloadEvent) { - val data = event.getConstant("TradeNpcs") - tradeNpcFilter.load(data) - val hideNotClickable = event.getConstant("HideNotClickableItems") hideNpcSellFilter.load(hideNotClickable.hide_npc_sell) hideInStorageFilter.load(hideNotClickable.hide_in_storage) @@ -175,7 +170,7 @@ class HideNotClickableItems { reverseColor = false return when { - hideNpcSell(chestName, stack) -> true + hideNpcSell(stack) -> true hideInStorage(chestName, stack) -> true hideSalvage(chestName, stack) -> true hidePlayerTrade(chestName, stack) -> true @@ -260,7 +255,7 @@ class HideNotClickableItems { "BRACELET" ) for (type in list) { - if (stack.getLore().any { it.contains("§l") && it.contains(type) }) {//todo use item api + if (stack.getLore().any { it.contains("§l") && it.contains(type) }) {// todo use item api reverseColor = true return false } @@ -289,7 +284,7 @@ class HideNotClickableItems { private fun hidePrivateIslandChest(chestName: String, stack: ItemStack): Boolean { if (chestName != "Chest" && chestName != "Large Chest") return false - //TODO make check if player is on private island + // TODO make check if player is on private island if (!ItemUtils.isSoulBound(stack)) return false @@ -378,8 +373,8 @@ class HideNotClickableItems { return result } - private fun hideNpcSell(chestName: String, stack: ItemStack): Boolean { - if (!tradeNpcFilter.match(chestName)) return false + private fun hideNpcSell(stack: ItemStack): Boolean { + if (!ShiftClickNPCSell.inInventory) return false if (VisitorAPI.inInventory) return false reverseColor = true diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/PowerStoneGuideFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/PowerStoneGuideFeatures.kt new file mode 100644 index 000000000000..24972cde587a --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/PowerStoneGuideFeatures.kt @@ -0,0 +1,78 @@ +package at.hannibal2.skyhanni.features.inventory + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.GuiContainerEvent +import at.hannibal2.skyhanni.events.InventoryCloseEvent +import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent +import at.hannibal2.skyhanni.events.LorenzToolTipEvent +import at.hannibal2.skyhanni.features.bazaar.BazaarApi +import at.hannibal2.skyhanni.utils.ItemUtils.getItemName +import at.hannibal2.skyhanni.utils.ItemUtils.getLore +import at.hannibal2.skyhanni.utils.LorenzColor +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.nextAfter +import at.hannibal2.skyhanni.utils.NEUInternalName +import at.hannibal2.skyhanni.utils.NEUItems.getPrice +import at.hannibal2.skyhanni.utils.NumberUtil +import at.hannibal2.skyhanni.utils.RenderUtils.highlight +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class PowerStoneGuideFeatures { + + private var missing = mutableMapOf() + private var inInventory = false + + @SubscribeEvent + fun onInventoryOpen(event: InventoryFullyOpenedEvent) { + if (!isEnabled()) return + if (event.inventoryName != "Power Stones Guide") return + + inInventory = true + + for ((slot, item) in event.inventoryItems) { + val lore = item.getLore() + if (lore.contains("§7Learned: §cNot Yet ✖")) { + val rawName = lore.nextAfter("§7Power stone:") ?: continue + val name = NEUInternalName.fromItemName(rawName) + missing[slot] = name + } + } + } + + @SubscribeEvent + fun onInventoryClose(event: InventoryCloseEvent) { + inInventory = false + } + + @SubscribeEvent + fun onBackgroundDrawn(event: GuiContainerEvent.BackgroundDrawnEvent) { + if (!isEnabled()) return + if (!inInventory) return + + event.gui.inventorySlots.inventorySlots + .filter { missing.containsKey(it.slotNumber) } + .forEach { it highlight LorenzColor.RED } + } + + @SubscribeEvent + fun onSlotClick(event: GuiContainerEvent.SlotClickEvent) { + if (!isEnabled()) return + if (!inInventory) return + val internalName = missing[event.slotId] ?: return + + BazaarApi.searchForBazaarItem(internalName.getItemName(), 9) + } + + @SubscribeEvent + fun onTooltip(event: LorenzToolTipEvent) { + if (!isEnabled()) return + if (!inInventory) return + + val internalName = missing[event.slot.slotNumber] ?: return + val totalPrice = internalName.getPrice() * 9 + event.toolTip.add(5, "9x from Bazaar: §6${NumberUtil.format(totalPrice)}") + } + + fun isEnabled() = LorenzUtils.inSkyBlock && SkyHanniMod.feature.inventory.powerStoneGuide + +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/ShiftClickNPCSell.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/ShiftClickNPCSell.kt new file mode 100644 index 000000000000..db1375b75d1e --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/ShiftClickNPCSell.kt @@ -0,0 +1,54 @@ +package at.hannibal2.skyhanni.features.inventory + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.GuiContainerEvent +import at.hannibal2.skyhanni.events.InventoryCloseEvent +import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent +import at.hannibal2.skyhanni.utils.ItemUtils.getLore +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.StringUtils.matches +import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern +import net.minecraft.client.Minecraft +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +object ShiftClickNPCSell { + + private val config get() = SkyHanniMod.feature.inventory.shiftClickNPCSell + + private val sellSlot = 49 + private val lastLoreLineOfSellPattern by RepoPattern.pattern( + "inventory.npc.sell.lore", + "§7them to this Shop!|§eClick to buyback!" + ) + + var inInventory = false + private set + + fun isEnabled() = LorenzUtils.inSkyBlock && config + + @SubscribeEvent + fun onOpen(event: InventoryFullyOpenedEvent) { + if (!LorenzUtils.inSkyBlock) return + inInventory = lastLoreLineOfSellPattern.matches(event.inventoryItems[sellSlot]?.getLore()?.lastOrNull() ?: "") + } + + @SubscribeEvent + fun onClose(event: InventoryCloseEvent) { + inInventory = false + } + + @SubscribeEvent + fun onSlotClick(event: GuiContainerEvent.SlotClickEvent) { + if (!isEnabled()) return + if (!inInventory) return + + val slot = event.slot ?: return + + if (slot.slotNumber == slot.slotIndex) return + + event.isCanceled = true + Minecraft.getMinecraft().playerController.windowClick( + event.container.windowId, event.slot.slotNumber, event.clickedButton, 1, Minecraft.getMinecraft().thePlayer + ) + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/LesserOrbHider.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/LesserOrbHider.kt new file mode 100644 index 000000000000..000587afdbb3 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/LesserOrbHider.kt @@ -0,0 +1,54 @@ +package at.hannibal2.skyhanni.features.misc + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.CheckRenderEntityEvent +import at.hannibal2.skyhanni.events.EntityEquipmentChangeEvent +import at.hannibal2.skyhanni.events.ReceiveParticleEvent +import at.hannibal2.skyhanni.utils.ItemUtils.getSkullTexture +import at.hannibal2.skyhanni.utils.LocationUtils.distanceTo +import at.hannibal2.skyhanni.utils.LorenzUtils +import net.minecraft.entity.item.EntityArmorStand +import net.minecraft.util.EnumParticleTypes +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class LesserOrbHider { + private val config get() = SkyHanniMod.feature.misc + private val hiddenEntities = LorenzUtils.weakReferenceList() + + private val lesserTexture = + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZjgzMjM2NjM5NjA3MDM2YzFiYTM5MWMyYjQ2YTljN2IwZWZkNzYwYzhiZmEyOTk2YTYwNTU1ODJiNGRhNSJ9fX0=" + + @SubscribeEvent + fun onArmorChange(event: EntityEquipmentChangeEvent) { + val entity = event.entity + val itemStack = event.newItemStack ?: return + + if (entity is EntityArmorStand && event.isHand && itemStack.getSkullTexture() == lesserTexture) { + hiddenEntities.add(entity) + } + } + + @SubscribeEvent + fun onCheckRender(event: CheckRenderEntityEvent<*>) { + if (!isEnabled()) return + + if (event.entity in hiddenEntities) { + event.isCanceled = true + } + } + + @SubscribeEvent + fun onReceiveParticle(event: ReceiveParticleEvent) { + if (!isEnabled()) return + if (event.type != EnumParticleTypes.REDSTONE) return + + for (armorStand in hiddenEntities) { + val distance = armorStand.distanceTo(event.location) + if (distance < 4) { + event.isCanceled = true + } + } + } + + fun isEnabled() = LorenzUtils.inSkyBlock && config.lesserOrbHider +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/RenderColumn.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/RenderColumn.kt index 2ee1e3442870..894dee93ba27 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/RenderColumn.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/RenderColumn.kt @@ -1,8 +1,6 @@ package at.hannibal2.skyhanni.features.misc.compacttablist -class RenderColumn { - - val lines = mutableListOf() +class RenderColumn(val lines: MutableList = mutableListOf()) { fun size(): Int { return lines.size @@ -15,4 +13,4 @@ class RenderColumn { fun getMaxWidth(): Int { return lines.maxOfOrNull { it.getWidth() } ?: 0 } -} \ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/TabListRenderer.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/TabListRenderer.kt index d5cc7f8756bc..b42378e08717 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/TabListRenderer.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/TabListRenderer.kt @@ -1,8 +1,12 @@ package at.hannibal2.skyhanni.features.misc.compacttablist import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.SkipTabListLineEvent import at.hannibal2.skyhanni.mixins.transformers.AccessorGuiPlayerTabOverlay import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.filterToMutable +import at.hannibal2.skyhanni.utils.StringUtils.matches +import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern import net.minecraft.client.Minecraft import net.minecraft.client.gui.Gui import net.minecraft.client.gui.ScaledResolution @@ -91,9 +95,22 @@ object TabListRenderer { } var middleX = x - for (column in columns) { + var lastTitle: TabLine? = null + var lastSubTitle: TabLine? = null + for (originalColumn in columns) { var middleY = if (config.hideAdverts) headerY else headerY + padding + 2 + val column = originalColumn.lines.filterToMutable { tabLine -> + if (tabLine.type == TabStringType.TITLE) { + lastSubTitle = null + lastTitle = tabLine + } + if (tabLine.type == TabStringType.SUB_TITLE) { + lastSubTitle = tabLine + } + !SkipTabListLineEvent(tabLine, lastSubTitle, lastTitle).postAndCatch() + }.let(::RenderColumn) + Gui.drawRect( middleX - padding + 1, middleY - padding + 1, @@ -156,4 +173,14 @@ object TabListRenderer { } } } -} \ No newline at end of file + + private val fireSalePattern by RepoPattern.pattern("tablist.firesaletitle", "§b§lFire Sales: §r§f\\([0-9]+\\)") + + @SubscribeEvent + fun hideFireFromTheTabListBecauseWhoWantsThose(event: SkipTabListLineEvent) { + if (config.hideFiresales && event.lastSubTitle != null && fireSalePattern.matches(event.lastSubTitle.text)) { + event.cancel() + } + } + +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/items/GlowingDroppedItems.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/items/GlowingDroppedItems.kt index 11bf4655b7f3..3e5bf7989ec4 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/items/GlowingDroppedItems.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/items/GlowingDroppedItems.kt @@ -3,6 +3,7 @@ package at.hannibal2.skyhanni.features.misc.items import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.data.IslandType import at.hannibal2.skyhanni.events.RenderEntityOutlineEvent +import at.hannibal2.skyhanni.features.garden.pests.SprayType import at.hannibal2.skyhanni.utils.ItemUtils.getInternalNameOrNull import at.hannibal2.skyhanni.utils.ItemUtils.getItemRarityOrNull import at.hannibal2.skyhanni.utils.ItemUtils.name @@ -56,7 +57,9 @@ class GlowingDroppedItems { return null } - entityItem.getInternalNameOrNull() ?: return null + val internalName = entityItem.getInternalNameOrNull() ?: return null + val isSprayItem = LorenzUtils.enumValueOfOrNull(internalName.asString()) != null + if (isSprayItem) return null val rarity = entityItem.getItemRarityOrNull() return rarity?.color?.toColor()?.rgb } @@ -79,4 +82,4 @@ class GlowingDroppedItems { return false } -} \ No newline at end of file +} 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 bf88fb865008..d8f52a641f7c 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 @@ -3,6 +3,7 @@ package at.hannibal2.skyhanni.features.nether.reputationhelper.dailykuudra import at.hannibal2.skyhanni.config.Storage import at.hannibal2.skyhanni.data.IslandType import at.hannibal2.skyhanni.data.ScoreboardData +import at.hannibal2.skyhanni.data.jsonobjects.repo.CrimsonIsleReputationJson.ReputationQuest import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent import at.hannibal2.skyhanni.features.nether.reputationhelper.CrimsonIsleReputationHelper @@ -13,7 +14,6 @@ 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 at.hannibal2.skyhanni.data.jsonobjects.repo.CrimsonIsleReputationJson.ReputationQuest import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class DailyKuudraBossHelper(private val reputationHelper: CrimsonIsleReputationHelper) { @@ -38,8 +38,7 @@ class DailyKuudraBossHelper(private val reputationHelper: CrimsonIsleReputationH @SubscribeEvent fun onChat(event: LorenzChatEvent) { - if (!LorenzUtils.inSkyBlock) return - if (LorenzUtils.skyBlockIsland != IslandType.KUUDRA_ARENA) return + if (!LorenzUtils.inKuudraFight) return if (!reputationHelper.config.enabled) return val message = event.message diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/DanceRoomHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/DanceRoomHelper.kt index a2b337668734..5118bf25b528 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/DanceRoomHelper.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/DanceRoomHelper.kt @@ -1,6 +1,8 @@ package at.hannibal2.skyhanni.features.rift.area.mirrorverse +import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator +import at.hannibal2.skyhanni.data.jsonobjects.repo.DanceRoomInstructionsJson import at.hannibal2.skyhanni.events.CheckRenderEntityEvent import at.hannibal2.skyhanni.events.GuiRenderEvent import at.hannibal2.skyhanni.events.LorenzTickEvent @@ -12,10 +14,6 @@ import at.hannibal2.skyhanni.features.rift.RiftAPI import at.hannibal2.skyhanni.utils.LocationUtils.isPlayerInside import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings import at.hannibal2.skyhanni.utils.StringUtils.firstLetterUppercase -import at.hannibal2.skyhanni.data.jsonobjects.repo.DanceRoomInstructionsJson -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch @@ -142,7 +140,7 @@ object DanceRoomHelper { val countdownString = "%01d:%03d".format(seconds, milliseconds) countdown = countdownString - CoroutineScope(Dispatchers.Default).launch { + SkyHanniMod.coroutineScope.launch { delay(1) var updatedSeconds = seconds var updatedMilliseconds = milliseconds - 1 @@ -169,8 +167,8 @@ object DanceRoomHelper { instructions = event.getConstant("DanceRoomInstructions").instructions } - fun start(interval: Long): Job { - return CoroutineScope(Dispatchers.Default).launch { + fun start(interval: Long) { + SkyHanniMod.coroutineScope.launch { while (isActive && found) { index++ startCountdown(0, 500) diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt index 6ff20129bdbb..d0c374a8bf9a 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt @@ -43,7 +43,7 @@ object SlayerProfitTracker { var slayerSpawnCost: Long = 0 @Expose - var slayerCompletedCount = 0 + var slayerCompletedCount = 0L override fun getDescription(timesDropped: Long): List { val percentage = timesDropped.toDouble() / slayerCompletedCount @@ -168,14 +168,7 @@ object SlayerProfitTracker { ) ) - val profitFormat = profit.addSeparators() - val profitPrefix = if (profit < 0) "§c" else "§6" - - val profitPerBoss = profit / itemLog.slayerCompletedCount - val profitPerBossFormat = NumberUtil.format(profitPerBoss) - - val text = "§eTotal Profit: $profitPrefix$profitFormat coins" - addAsSingletonList(Renderable.hoverTips(text, listOf("§7Profit per boss: $profitPrefix$profitPerBossFormat"))) + addAsSingletonList(tracker.addTotalProfit(profit, itemLog.slayerCompletedCount, "boss")) tracker.addPriceFromButton(this) } diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/VampireSlayerFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/VampireSlayerFeatures.kt index e1f837a7b500..baf43b001682 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/slayer/VampireSlayerFeatures.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/VampireSlayerFeatures.kt @@ -32,8 +32,6 @@ import at.hannibal2.skyhanni.utils.RenderUtils.exactPlayerEyeLocation import at.hannibal2.skyhanni.utils.SoundUtils import at.hannibal2.skyhanni.utils.SoundUtils.playSound import at.hannibal2.skyhanni.utils.toLorenzVec -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch import net.minecraft.client.Minecraft @@ -208,7 +206,7 @@ object VampireSlayerFeatures { } private fun playTwinclawsSound() { - CoroutineScope(Dispatchers.Default).launch { + SkyHanniMod.coroutineScope.launch { repeat(15) { delay(50) SoundUtils.createSound("random.orb", 0.5f).playSound() diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt index ce3c07d907ff..bec3af2f1a01 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt @@ -27,6 +27,7 @@ import net.minecraft.launchwrapper.Launch import net.minecraft.util.ChatComponentText import net.minecraftforge.fml.common.FMLCommonHandler import java.awt.Color +import java.lang.reflect.Constructor import java.lang.reflect.Field import java.lang.reflect.Modifier import java.text.DecimalFormat @@ -35,6 +36,7 @@ import java.text.SimpleDateFormat import java.util.Collections import java.util.Timer import java.util.TimerTask +import java.util.WeakHashMap import java.util.regex.Matcher import kotlin.properties.ReadWriteProperty import kotlin.reflect.KMutableProperty1 @@ -62,7 +64,7 @@ object LorenzUtils { val skyBlockArea get() = if (inSkyBlock) HypixelData.skyBlockArea else "?" - val inKuudraFight get() = skyBlockIsland == IslandType.KUUDRA_ARENA + val inKuudraFight get() = IslandType.KUUDRA_ARENA.isInIsland() val noTradeMode get() = HypixelData.noTrade @@ -523,8 +525,8 @@ object LorenzUtils { val tileSign = (this as AccessorGuiEditSign).tileSign return (tileSign.signText[1].unformattedText.removeColor() == "^^^^^^" - && tileSign.signText[2].unformattedText.removeColor() == "Set your" - && tileSign.signText[3].unformattedText.removeColor() == "speed cap!") + && tileSign.signText[2].unformattedText.removeColor() == "Set your" + && tileSign.signText[3].unformattedText.removeColor() == "speed cap!") } fun IslandType.isInIsland() = inSkyBlock && skyBlockIsland == this @@ -577,6 +579,8 @@ object LorenzUtils { fun Field.makeAccessible() = also { isAccessible = true } + fun Constructor.makeAccessible() = also { isAccessible = true } + // Taken and modified from Skytils @JvmStatic fun T.equalsOneOf(vararg other: T): Boolean { @@ -655,4 +659,10 @@ object LorenzUtils { fun Matcher.groupOrNull(groupName: String): String? { return runCatching { this.group(groupName) }.getOrNull() } + + // Let garbage collector handle the removal of entries in this list + fun weakReferenceList(): MutableSet = Collections.newSetFromMap(WeakHashMap()) + + + fun MutableCollection.filterToMutable(predicate: (T) -> Boolean) = filterTo(mutableListOf(), predicate) } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt index ad2df542c1f0..8a909f15e7b7 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt @@ -22,12 +22,14 @@ import io.github.moulberry.notenoughupdates.recipes.NeuRecipe import io.github.moulberry.notenoughupdates.util.ItemResolutionQuery import io.github.moulberry.notenoughupdates.util.Utils import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.GLAllocation import net.minecraft.client.renderer.GlStateManager import net.minecraft.client.renderer.RenderHelper import net.minecraft.init.Blocks import net.minecraft.init.Items import net.minecraft.item.ItemStack import net.minecraft.nbt.NBTTagCompound +import org.lwjgl.opengl.GL11 import java.util.regex.Pattern object NEUItems { @@ -192,8 +194,8 @@ object NEUItems { ErrorManager.logError( IllegalStateException("Something went wrong!"), "Encountered an error getting the item for §7$this§c. " + - "This may be because your NEU repo is outdated. Please ask in the SkyHanni " + - "Discord if this is the case" + "This may be because your NEU repo is outdated. Please ask in the SkyHanni " + + "Discord if this is the case" ) fallbackItem } @@ -201,6 +203,7 @@ object NEUItems { fun isVanillaItem(item: ItemStack): Boolean = manager.auctionManager.isVanillaItem(item.getInternalName().asString()) + fun ItemStack.renderOnScreen(x: Float, y: Float, scaleMultiplier: Double = 1.0) { val item = checkBlinkItem() val isSkull = item.item === Items.skull @@ -221,16 +224,39 @@ object NEUItems { GlStateManager.pushMatrix() - GlStateManager.translate(translateX, translateY, 1F) - GlStateManager.scale(finalScale, finalScale, 1.0) + GlStateManager.translate(translateX, translateY, -19f) + GlStateManager.scale(finalScale, finalScale, 0.2) + GL11.glNormal3f(0f, 0f, 1f / 0.2f) // Compensate for z scaling RenderHelper.enableGUIStandardItemLighting() + + AdjustStandardItemLighting.adjust() // Compensate for z scaling + Minecraft.getMinecraft().renderItem.renderItemIntoGUI(item, 0, 0) RenderHelper.disableStandardItemLighting() GlStateManager.popMatrix() } + private object AdjustStandardItemLighting { + + private const val lightScaling = 2.47f // Adjust as needed + private const val g = 0.6f // Original Value taken from RenderHelper + private const val lightIntensity = lightScaling * g + private val itemLightBuffer = GLAllocation.createDirectFloatBuffer(16); + + init { + itemLightBuffer.clear() + itemLightBuffer.put(lightIntensity).put(lightIntensity).put(lightIntensity).put(1.0f) + itemLightBuffer.flip() + } + + fun adjust() { + GL11.glLight(16384, 4609, itemLightBuffer) + GL11.glLight(16385, 4609, itemLightBuffer) + } + } + fun allNeuRepoItems(): Map = NotEnoughUpdates.INSTANCE.manager.itemInformation fun getMultiplier(internalName: NEUInternalName, tryCount: Int = 0): Pair { @@ -326,11 +352,11 @@ object NEUItems { val name = group("name").trim { it <= ' ' } val ultimate = group("format").lowercase().contains("§l") ((if (ultimate && name != "Ultimate Wise") "ULTIMATE_" else "") - + turboCheck(name).replace(" ", "_").replace("-", "_").uppercase() - + ";" + group("level").romanToDecimal()) + + turboCheck(name).replace(" ", "_").replace("-", "_").uppercase() + + ";" + group("level").romanToDecimal()) } - //Uses NEU + // Uses NEU fun saveNBTData(item: ItemStack, removeLore: Boolean = true): String { val jsonObject = manager.getJsonForItem(item) if (!jsonObject.has("internalname")) { diff --git a/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt b/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt index 9367e5ee13bf..01f9941aa7c6 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt @@ -62,7 +62,7 @@ interface Renderable { text: String, onClick: () -> Unit, bypassChecks: Boolean = false, - condition: () -> Boolean = { true } + condition: () -> Boolean = { true }, ): Renderable = link(string(text), onClick, bypassChecks, condition) @@ -70,7 +70,7 @@ interface Renderable { renderable: Renderable, onClick: () -> Unit, bypassChecks: Boolean = false, - condition: () -> Boolean = { true } + condition: () -> Boolean = { true }, ): Renderable { return clickable( hoverable(underlined(renderable), renderable, bypassChecks, condition = condition), @@ -85,7 +85,7 @@ interface Renderable { text: String, tips: List, bypassChecks: Boolean = false, - onClick: () -> Unit + onClick: () -> Unit, ): Renderable { return clickable(hoverTips(text, tips, bypassChecks = bypassChecks), onClick, bypassChecks = bypassChecks) } @@ -95,7 +95,7 @@ interface Renderable { onClick: () -> Unit, button: Int = 0, bypassChecks: Boolean = false, - condition: () -> Boolean = { true } + condition: () -> Boolean = { true }, ) = object : Renderable { override val width: Int @@ -124,7 +124,7 @@ interface Renderable { indexes: List = listOf(), stack: ItemStack? = null, bypassChecks: Boolean = false, - condition: () -> Boolean = { true } + condition: () -> Boolean = { true }, ): Renderable { val render = string(text) @@ -211,7 +211,7 @@ interface Renderable { hovered: Renderable, unhovered: Renderable, bypassChecks: Boolean = false, - condition: () -> Boolean = { true } + condition: () -> Boolean = { true }, ) = object : Renderable { override val width: Int @@ -233,8 +233,8 @@ interface Renderable { override fun render(posX: Int, posY: Int) { GlStateManager.pushMatrix() - if (Minecraft.getMinecraft().currentScreen == null || Minecraft.getMinecraft().currentScreen is GuiChat) - GlStateManager.translate(0F, 0F, -145F) + if (Minecraft.getMinecraft().currentScreen is GuiChat) + GlStateManager.translate(0F, 0F, -3F) any.renderOnScreen(0F, 0F, scaleMultiplier = scale) GlStateManager.popMatrix() } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniItemTracker.kt b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniItemTracker.kt index 8dab120fa78a..b831ade3fa55 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniItemTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniItemTracker.kt @@ -172,4 +172,18 @@ class SkyHanniItemTracker( } } + fun addTotalProfit(profit: Double, totalAmount: Long, action: String): Renderable { + val profitFormat = profit.addSeparators() + val profitPrefix = if (profit < 0) "§c" else "§6" + + val tips = if (totalAmount > 0) { + val profitPerCatch = profit / totalAmount + val profitPerCatchFormat = NumberUtil.format(profitPerCatch) + listOf("§7Profit per $action: $profitPrefix$profitPerCatchFormat") + } else emptyList() + + val text = "§eTotal Profit: $profitPrefix$profitFormat coins" + return Renderable.hoverTips(text, tips) + } + }