diff options
332 files changed, 6275 insertions, 2305 deletions
diff --git a/.editorconfig b/.editorconfig index 28d8209de..8354a021e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -23,8 +23,10 @@ max_line_length = 120 # Java files should not use wildcard imports ij_java_names_count_to_use_import_on_demand = 999 ij_java_class_count_to_use_import_on_demand = 999 +ij_java_packages_to_use_import_on_demand = [*.kt] # Kotlin files should not use wildcard imports ij_kotlin_name_count_to_use_star_import = 999 ij_kotlin_name_count_to_use_star_import_for_members = 999 +ij_kotlin_packages_to_use_import_on_demand = diff --git a/.github/workflows/label-merge-conflict.yml b/.github/workflows/label-merge-conflict.yml index 6c0268d6c..19e88ede7 100644 --- a/.github/workflows/label-merge-conflict.yml +++ b/.github/workflows/label-merge-conflict.yml @@ -4,7 +4,7 @@ on: push: branches: [ beta ] # So that the `dirtyLabel` is removed if conflicts are resolve - # We recommend `pull_request_target` so that github secrets are available. + # We recommend `pull_request_target` so that GitHub secrets are available. # In `pull_request` we wouldn't be able to change labels of fork PRs pull_request_target: types: [ opened, synchronize ] diff --git a/.github/workflows/remove-labels-on-pr-close.yml b/.github/workflows/remove-labels-on-pr-close.yml new file mode 100644 index 000000000..fd73b7aab --- /dev/null +++ b/.github/workflows/remove-labels-on-pr-close.yml @@ -0,0 +1,16 @@ +# https://github.com/marketplace/actions/label-remover + +name: "Remove All Labels" + +on: + pull_request_target: + types: [closed] + +jobs: + remove_very_soon: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: rogerluan/label-remover@v1.0.1 + with: + github_token: ${{ secrets.github_token }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 884017ef6..75ecc9cb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,184 @@ # SkyHanni - Change Log +## Version 0.22 (Unreleased) + +### New Features + +#### Garden Features + ++ Added Garden Vacuum Pests in Pest bag to item number as stack size. - hannibal2 + + Enable via /sh vacuum. ++ Added Pests to Damage Indicator. - hannibal2 + + Enable Damage Indicator and select Garden Pests. ++ Change how the pest spawn chat message should be formatted. - hannibal2 + + Unchanged, compact or hide the message entirely. ++ Show a Title when a pest spawns. - hannibal2 ++ Show the time since the last pest spawned in your garden. - hannibal2 + + Option to only show the time while holding vacuum in the hand. ++ Show the pests that are attracted when changing the selected material of the Sprayanator. - hannibal2 ++ Added Garden only commands /home, /barn and /tp, and hotkeys. - hannibal2 ++ Showing a better plot name in the scoreboard. Updates faster and doesn't hide when pests are spawned. - hannibal2 ++ Show a display with all known pest locations. - hannibal2 + + Click to warp to the plot. + + Option to only show the time while holding vacuum in the hand. ++ Mark the plots with pests on them in the world. - hannibal2 ++ Press the key to warp to the nearest plot with pests on it. - hannibal2 ++ Draw plot borders when holding the Sprayonator. - HiZe + +#### Fishing Features + ++ Added Barn Fishing Timer to Jerry's Workshop and Crimson Isle. - martimavocado ++ Added Fishing Tracker and changed trackers in general. - hannibal2 + + This tracker GUI behaves the same way as the Slayer Tracker: Allows for single item remove or hide + + Counts coin drops from chat. + + Mark the amount in green when recently gained the item. + + Option to hide the Fishing Tracker while moving. + + Option to hide all Trackers while Estimated Item Value is visible. + + Option to change the default display mode for all trackers. + + The hidden flag for items in Item Trackers is now shared between total view and session view. + + Option to exclude hidden items in the total price calculation. + + Option to change the display mode that gets shown on default: Total, Current or remember last. + +#### Winter Features + ++ Added Unique Gifting Opportunities. - nea + + Highlight players who you haven't given gifts to yet. + + Only highlight ungifted players while holding a gift. + + Make use of armor stands to stop highlighting players. This is a bit inaccurate, but it can help with people you gifted before this feature was used. ++ Added Unique Gifted users counter. - hannibal2 + + Show in a display how many unique players you have given gifts to in the winter 2023 event. + + Run command /opengenerowmenu to sync up. + +#### Bingo Features + ++ Show the duration until the next hidden bingo goal tip gets revealed. - hannibal2 ++ Added support for tips in hidden bingo card display. - hannibal2 ++ Added support for 'found by' info in bingo card. - hannibal2 ++ Added Bingo Goal Rank as stack size in Bingo Card. - Erymanthus ++ Added the option to only show tier 1 Minion Crafts in the Helper display when their items needed are fully collected. - hannibal2 ++ Added the option to click in the bingo card viewer on goals to mark them as highlighted. - hannibal2 + + If at least one goal is highlighted, non-highlighted goals will be hidden. + +#### Inventory Features + ++ Added bottle of Jyrre time overlay in stack size feature. - HiZe ++ Added show special edition number as stack size when below 1k. - hannibal2 + +#### Minion Features + ++ Shows how much skill experience you will get when picking up items from the minion storage. - Thunderblade73 + +#### Chat Features + ++ Hide the repeating fire sale reminder chat messages. - hannibal2 + +### Changes + +#### Garden Changes + ++ Added option to enable/disable the vacuum bag item number being capped to 40. - hannibal2 ++ Automatic unlocking /shmouselock when teleporting in the garden. - hannibal2 ++ Don't hide messages from Jacob. - alexia + + This is a workaround for wrongly hidden Jakob messages. ++ Show the hint to open Configure Plot only if the pest display is incorrect. - hannibal2 ++ Added the "plot" word to the sidebar again (only if there are no pests in garden). - hannibal2 ++ Hide the Composter Overlay in composter inventory while the Estimated Item Value is visible. - hannibal2 ++ Made the wording of "no pest spawned yet" message more clear. - hannibal2 ++ Not only show the waypoint for infested plots, also show their waypoints in the world. - hannibal2 ++ Use different colors in the tab list depending on the pest count. - alexia ++ Highlight the boosted crop contest in all Jacob's Contest displays. - alexia ++ Added Delicate 5 to visitor drop counter and visitor block refuse and highlighter. - hannibal2 ++ Block visitor interaction for dedication cycling is now disabled by default. - hannibal2 + +#### Fishing Changes + ++ Show the fishing tracker for a couple of seconds after catching something even while moving. - hannibal2 + +#### Winter Changes + ++ Hiding Unique Gifted Players Highlighting for ironman and bingo while not on those modes. - Thunderblade73 + +#### Chat Changes + ++ Added fire sale messages in the hub to the chat message filter. - hannibal2 ++ Added compact potion message support for splash messages and for Poisoned Candy I. - walker + +#### Bingo Changes + ++ Option to remove the background difficulty color in the bingo card inventory when the goal is done. - hannibal2 ++ Mark the background difficulty gray for unknown goals. - hannibal2 + + This is no longer needed as all 20 hidden goals are known now, but we now have this support for the next extreme bingo with hidden goals. + +### Fixes + +#### Garden Fixes + ++ Fixed pest damage indicator not working for some pests. - hannibal2 ++ Fixed pest kill detection. - hannibal2 ++ Fixed /tp <plot name> not working with uppercase characters. - hannibal2 ++ Fixed total equipment fortune in /ff. - alexia ++ Fixed Locust pest not getting detected in damage indicator. - hannibal2 ++ Fixed Pest Spray Display showing outside the garden. - hannibal2 ++ Fixed pest detection when more than 3 pests are spawned at once. - hannibal2 ++ Fixed showing on the scoreboard "garden outside" immediately after teleporting to a plot. - hannibal2 ++ Fixed visitor timer counting down too fast sometimes. - hannibal2 ++ Fixed Mooshroom cow Perk display not showing when maxed. - hannibal2 ++ Show a text around the new year that the calendar is not loaded for the next Jacob Contest. - hannibal2 ++ Fixed visitor reward item refuse inconsistencies. - hannibal2 + +#### Bingo Fixes + ++ Hide the long hint line in the Bingo Goal Display. - hannibal2 ++ Show community goals in the Bingo Display correctly. - hannibal2 ++ Hide enchanted tools in Minion Craft Helper. - hannibal2 + +#### Minion Fixes + ++ Fixed Minion XP display not showing sometimes. - Thunderblade73 ++ Updating the Minion XP display when the minion picks up a new item while inside the inventory. - hannibal2 ++ Fixed minion features disappear inside the minion inventory when picking up an item. - hannibal2 + +#### Misc Fixes + ++ Fixed Item Tracker not ignoring manual sack movements. - hannibal2 ++ Fixed showing yourself green with Unique Gifting Opportunities. - hannibal2 ++ Fixed NPC messages getting detected as player messages. - CalMWolfs ++ Hide Scavenger 5 on an Ice Spray Wand and Replenish on an Advanced Gardening Hoe/Axe for the Estimated Item Value. - hannibal2 ++ Fixed an error when the king talisman helper does not find the king in range. - hannibal2 + +#### Config Fixes + ++ Fixed a typo in config. - walker + +### Technical Details + ++ Code cleanup in many files. - walker & hannibal2 ++ Moved the JSON object files into another package. - walker ++ Replaced SkyHanniMod.feature.garden with GardenAPI.config. - hannibal2 ++ Added MessageSendToServerEvent. - hannibal2 ++ Added GardenPlotAPI, support for detecting the current slot of the player. - hannibal2 ++ Updated .editorconfig file to better support imports. - Thunderblade73 ++ Migrate Integer to Enums in Config. - walker ++ Using a broken config no longer resets the config in dev env. - hannibal2 ++ Auto-removing all labels of PRs on merging/closing. - hannibal2 ++ Changed OwnInventoryItemUpdateEvent to be called synced to the main thread. - hannibal2 ++ romanToDecimalIfNeeded -> romanToDecimalIfNecessary. - hannibal2 + + For more context: https://chat.openai.com/share/502571b5-8851-4047-b343-3b1475ca8a88 ++ Added the debug feature SkyHanni Event Counter. - hannibal2 ++ Fix Consecutive Spaces in RegEx. - walker ++ No longer creating new regex pattern elements each time in DungeonDeathCounter. - walker ++ Changed DungeonChatFilter to use lists of patterns. - walker ++ Code cleanup in DungeonMilestoneDisplay. - walker ++ Code cleanup and removed .matchRegex() - walker ++ Misc pattern optimizations. - walker ++ Moving the bingo goal list into BingoAPI. - hannibal2 ++ Created BingoGoalReachedEvent. - hannibal2 ++ Created Matcher.groupOrNull. - walker ++ cleanPlayerName respects playerRankHider option now. - hannibal2 ++ Replaced ItemWarnEntry with VisitorReward. This should fix some errors. - hannibal2 ++ GardenNextJacobContest now uses SimpleTimeMark. SimpleTimeMark is storable in the config and comparable - hannibal2 ++ No longer sending contest data to elite close to new year. - hannibal2 + ## Version 0.21.1 ### New Features @@ -14,6 +193,26 @@ ### Changes ++ /shtrackcollection now supports sack messages. - hannibal2 ++ Changed formatting of coin value to be more consistent over multiple features. - hannibal2 ++ Made skill level as item number no longer default enabled. - hannibal2 + +### Fixes + ++ Fixed the wrong colouring of hidden items in Slayer Profit Tracker. - hannibal2 ++ Added support for NEU Heavy Pearl TO-DO fix working without nether sacks as well. - hannibal2 ++ Fixed Estimated Item Value getting shown in pet rule creation wardrobe slot pick menu. - hannibal2 + +### Technical Details + ++ Added /shwhereami command to show the current island. - martimavocado ++ Tons of code clean-ups over the whole project. - walker & hannibal2 + + Added ItemAddEvent. - hannibal2 ++ Gets called when the user collects an item into inventory or sacks. ++ Created SkyHanniItemTracker. - hannibal2 + + This is a Special variant of SkyHanniTracker, that has item specific functions (hide or remove) and different price variants. ++ Migrated slayer profit data into SkyHanniTracker format. - hannibal2 + #### Garden Changes + Added mythic/Maeve visitor support. - walker & hannibal2 @@ -926,7 +1125,7 @@ ### Fixes + Fixed Pocket Sack-In-A-Sack Replace in lore -+ Fixed possible crash with broken neu repo when opening the desk inventory in garden (Contributed by CalMWolfs) ++ Fixed possible crash with broken neu repo when opening the desk inventory in the garden (Contributed by CalMWolfs) + Fixed frozen treasures per hour display being inaccurate (Contributed by CalMWolfs) + Fixed bug with ghost counter sometimes not detecting new kills (Contributed by CalMWolfs) + Fixed **Ghost Counter** - HiZe & ksipli @@ -1239,7 +1438,7 @@ and show a preview how these stats change when hovering over an upgrade + Hide crop money display, crop milestone display and garden visitor list while inside anita show, SkyMart or the composter inventory -+ Hide chat messages from the visitors in garden. (Except Beth and Spaceman) ++ Hide chat messages from the visitors in the garden. (Except Beth and Spaceman) + Introduced a new command '/shcroptime <amount> <item>' that displays the estimated time it will take to gather the requested quantity of a particular item based on the current crop speed. + Show the average crop milestone in the crop milestone inventory. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 25124fffa..fb5a7e1e6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -56,7 +56,7 @@ You can write in the description of the pr the wording for the changelog as well - All new classes should be written in Kotlin, with a few exceptions: - Config files in `at.hannibal2.skyhanni.config.features` - Mixin classes in `at.hannibal2.skyhanni.mixins.transformers` - - Java classes that represent JSON data objects in `at.hannibal2.skyhanni.utils.jsonobjects` + - Java classes that represent JSON data objects in `at.hannibal2.skyhanni.data.jsonobjects` - Please use the existing event system, or expand on it. Do not use Forge events. - (We inject the calls with Mixin) - Please use existing utils methods. @@ -125,7 +125,8 @@ SkyHanni uses a repo system to easily change static variables without the need f The repo is located at https://github.com/hannibal002/SkyHanni-REPO. A copy of all json files is stored on the computer under `.minecraft\config\skyhanni\repo`. On every game start, the copy gets updated (if outdated and if not manually disabled). -If you add stuff to the repo make sure it gets serialised. See the [jsonobjects](src/main/java/at/hannibal2/skyhanni/utils/jsonobjects) +If you add stuff to the repo make sure it gets serialised. See +the [jsonobjects](src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo) folder for how to properly do this. You also may have to disable repo auto update in game. ### Discord IPC diff --git a/DISCORD_FAQ.md b/DISCORD_FAQ.md index 68fb338d1..997389a48 100644 --- a/DISCORD_FAQ.md +++ b/DISCORD_FAQ.md @@ -25,8 +25,9 @@ _Frequently Asked Questions_ > No, the barn fishing timer is not supported in the Crimson Isle in Hypixel Skyblock because it would disrupt other fishers due to competition for the maximum sea creature cap, potentially leading to conflicts and stealing of sea creatures. > **8: My Jacob Contest Display crops are wrong, how do I fix this?** -> 1. Run the command `/shconfig reset config.storage.gardenJacobFarmingContestTimes` -> 2. Restart the game +> 1. Close your minecraft. +> 2. Delete ".minecraft\config\skyhanni\jacob_contests.json". +> 3. Open minecraft. -*This FAQ was last updated on October 17th, 2023. -If you believe there's something that should be added to this list, please tell us, so we can add it.*
\ No newline at end of file +*This FAQ was last updated on december 05th, 2023. +If you believe there's something that should be added to this list, please tell us, so we can add it.* diff --git a/FEATURES.md b/FEATURES.md index b354e160d..1005bd1be 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -28,6 +28,7 @@ Use `/sh` or `/skyhanni` to open the SkyHanni config in game. + Will not break with emblems. + Optional if left or right side of name. + Should not break with other mods. ++ Hide the repeating fire sale reminder chat messages. - hannibal2 #### Chat Filter @@ -174,6 +175,7 @@ Use `/sh` or `/skyhanni` to open the SkyHanni config in game. - Minion name display with minion tier. - **Minion Craft Helper** - Show how many more items you need to upgrade the minion in your inventory. Especially useful for bingo. ++ Shows how much skill experience you will get when picking up items from the minion storage. - Thunderblade73 </details> <details open><summary> @@ -245,6 +247,7 @@ Use `/sh` or `/skyhanni` to open the SkyHanni config in game. - Option to show the health of Voidgloom Seraph 4 during the laser phase (useful when trying to phase skip) - Show when Revenant Horror 5 is about to BOOM. - Hide the vanilla nametag of damage indicator bosses. +- Garden Pests in Damage Indicator - **Time to Kill** - Show the time it takes to kill the Slayer boss. @@ -339,6 +342,14 @@ Use `/sh` or `/skyhanni` to open the SkyHanni config in game. + Shortens chat messages about skill level ups, collection gains and new area discoveries while on bingo. + Bingo Card ++ Show the duration until the next hidden bingo goal tip gets revealed. - hannibal2 ++ Support for tips in hidden bingo card display. - hannibal2 ++ Support for 'found by' info in bingo card. - hannibal2 ++ Bingo Goal Rank as stack size in Bingo Card. - Erymanthus ++ Option to only show tier 1 Minion Crafts in the Helper display when their items needed are fully collected. - hannibal2 ++ Added the option to click in the bingo card viewer on goals to mark them as highlighted. - hannibal2 + + If at least one goal is highlighted, non-highlighted goals will be hidden. + </details> <details open><summary> @@ -440,7 +451,7 @@ Use `/sh` or `/skyhanni` to open the SkyHanni config in game. is empty when fully filled and show a preview how these stats change when hovering over an upgrade + Hide crop money display, crop milestone display and garden visitor list while inside anita show, SkyMart or the composter inventory -+ Hide chat messages from the visitors in garden. (Except Beth and Spaceman) ++ Hide chat messages from the visitors in the garden. (Except Beth, Jacob and Spaceman) + Show the average crop milestone in the crop milestone inventory. + **FF for Contest** - Show the minimum needed Farming Fortune for reaching a medal in the Jacob's Farming Contest inventory. @@ -494,6 +505,29 @@ Use `/sh` or `/skyhanni` to open the SkyHanni config in game. + You can use this to share your hypixel data with SkyHanni via the discord. + This will allow us to fix the crop milestone features quicker, as we currently do not have accurate data for this. + If you don't want to share anything, you can disable the chat message in the config with /sh copy milestone data. ++ Garden Vacuum Pests in Pest bag to item number as stack size. - hannibal2 + + Enable via /sh vacuum. + +### Garden Pests + ++ Added Garden Vacuum Pests in Pest bag to item number as stack size. - hannibal2 + + Enable via /sh vacuum. ++ Added Pests to Damage Indicator. - hannibal2 + + Enable Damage Indicator and select Garden Pests. ++ Change how the pest spawn chat message should be formatted. - hannibal2 + + Unchanged, compact or hide the message entirely. ++ Show a Title when a pest spawns. - hannibal2 ++ Show the time since the last pest spawned in your garden. - hannibal2 + + Option to only show the time while holding vacuum in the hand. ++ Show the pests that are attracted when changing the selected material of the Sprayanator. - hannibal2 ++ Added Garden only commands /home, /barn and /tp, and hotkeys. - hannibal2 ++ Showing a better plot name in the scoreboard. Updates faster and doesn't hide when pests are spawned. - hannibal2 ++ Show a display with all known pest locations. - hannibal2 + + Click to warp to the plot. + + Option to only show the time while holding vacuum in the hand. ++ Mark the plots with pests on them in the world. - hannibal2 ++ Press the key to warp to the nearest plot with pests on it. - hannibal2 ++ Draw plot borders when holding the Sprayonator. - HiZe </details> <details open><summary> @@ -599,6 +633,13 @@ Use `/sh` or `/skyhanni` to open the SkyHanni config in game. + Accept Hotkey: Accept a visitor when you press this keybind while in the visitor GUI. + Added support for showing the primal fear data from tab list as GUI elements. - Erymanthus + Play warning sound when the next Primal Fear can spawn. - thunderblade73 ++ Unique Gifting Opportunities. - nea + + Highlight players who you haven't given gifts to yet. + + Only highlight ungifted players while holding a gift. + + Make use of armor stands to stop highlighting players. This is a bit inaccurate, but it can help with people you gifted before this feature was used. ++ Unique Gifted users counter. - hannibal2 + + Show in a display how many unique players you have given gifts to in the winter 2023 event. + + Run command /opengenerowmenu to sync up. </details> <details open><summary> @@ -13,7 +13,7 @@ SkyHanni is a Forge mod for Minecraft 1.8.9. It adds many features to Hypixel SkyBlock. The mod is filled with GUIs, extra chat messages, reminders, message hiders and entity highlighters. -The majority of these features are centered on the Garden, Slayer, Bingo, Diana, and Rift. +The majority of these features are centered in the Garden, Slayer, Bingo, Diana, and Rift. We have a [tutorial](https://github.com/hannibal002/SkyHanni/blob/beta/INSTALLING.md) for how to download and install the mod. diff --git a/build.gradle.kts b/build.gradle.kts index 5abe8290f..694ef15b2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,7 +11,7 @@ plugins { } group = "at.hannibal2.skyhanni" -version = "0.21.1" +version = "0.22.Beta.8" // Toolchains: java { @@ -87,8 +87,6 @@ dependencies { } shadowModImpl(libs.moulconfig) - devenvMod(variantOf(libs.moulconfig) { classifier("test") }) - shadowImpl(libs.libautoupdate) shadowImpl("org.jetbrains.kotlin:kotlin-reflect:1.9.0") @@ -124,6 +122,7 @@ loom { property("mixin.debug", "true") property("asmhelper.verbose", "true") arg("--tweakClass", "org.spongepowered.asm.launch.MixinTweaker") + arg("--tweakClass", "io.github.moulberry.moulconfig.tweaker.DevelopmentResourceTweaker") arg("--mods", devenvMod.resolve().joinToString(",") { it.relativeTo(file("run")).path }) } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0bdf7b127..e29f8e72b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] libautoupdate = "1.0.3" -moulconfig = "2.4.3" +moulconfig = "2.5.0" [libraries] moulconfig = { module = "org.notenoughupdates.moulconfig:legacy", version.ref = "moulconfig" } diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt index f974d3d1d..3aaa809d2 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt @@ -1,13 +1,13 @@ package at.hannibal2.skyhanni import at.hannibal2.skyhanni.api.CollectionAPI +import at.hannibal2.skyhanni.api.DataWatcherAPI import at.hannibal2.skyhanni.config.ConfigFileType import at.hannibal2.skyhanni.config.ConfigManager import at.hannibal2.skyhanni.config.Features import at.hannibal2.skyhanni.config.SackData import at.hannibal2.skyhanni.config.commands.Commands.init import at.hannibal2.skyhanni.data.ActionBarStatsData -import at.hannibal2.skyhanni.data.BingoAPI import at.hannibal2.skyhanni.data.BlockData import at.hannibal2.skyhanni.data.ChatManager import at.hannibal2.skyhanni.data.CropAccessoryData @@ -21,6 +21,7 @@ import at.hannibal2.skyhanni.data.GardenCropUpgrades import at.hannibal2.skyhanni.data.GuiEditManager import at.hannibal2.skyhanni.data.GuildAPI import at.hannibal2.skyhanni.data.HypixelData +import at.hannibal2.skyhanni.data.ItemAddManager import at.hannibal2.skyhanni.data.ItemClickData import at.hannibal2.skyhanni.data.ItemRenderBackground import at.hannibal2.skyhanni.data.ItemTipHelper @@ -40,6 +41,9 @@ import at.hannibal2.skyhanni.data.SlayerAPI import at.hannibal2.skyhanni.data.TitleData import at.hannibal2.skyhanni.data.TitleManager import at.hannibal2.skyhanni.data.ToolTipData +import at.hannibal2.skyhanni.data.jsonobjects.local.FriendsJson +import at.hannibal2.skyhanni.data.jsonobjects.local.JacobContestsJson +import at.hannibal2.skyhanni.data.jsonobjects.local.KnownFeaturesJson import at.hannibal2.skyhanni.data.repo.RepoManager import at.hannibal2.skyhanni.events.LorenzTickEvent import at.hannibal2.skyhanni.features.anvil.AnvilCombineHelper @@ -48,11 +52,13 @@ import at.hannibal2.skyhanni.features.bazaar.BazaarBestSellMethod import at.hannibal2.skyhanni.features.bazaar.BazaarCancelledBuyOrderClipboard import at.hannibal2.skyhanni.features.bazaar.BazaarOpenPriceWebsite import at.hannibal2.skyhanni.features.bazaar.BazaarOrderHelper -import at.hannibal2.skyhanni.features.bingo.BingoCardDisplay -import at.hannibal2.skyhanni.features.bingo.BingoCardTips -import at.hannibal2.skyhanni.features.bingo.BingoNextStepHelper +import at.hannibal2.skyhanni.features.bingo.BingoAPI import at.hannibal2.skyhanni.features.bingo.CompactBingoChat import at.hannibal2.skyhanni.features.bingo.MinionCraftHelper +import at.hannibal2.skyhanni.features.bingo.card.BingoCardDisplay +import at.hannibal2.skyhanni.features.bingo.card.BingoCardReader +import at.hannibal2.skyhanni.features.bingo.card.BingoCardTips +import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.BingoNextStepHelper import at.hannibal2.skyhanni.features.chat.ArachneChatMessageHider import at.hannibal2.skyhanni.features.chat.ChatFilter import at.hannibal2.skyhanni.features.chat.CompactBestiaryChatMessage @@ -97,6 +103,7 @@ import at.hannibal2.skyhanni.features.dungeon.DungeonMilestonesDisplay import at.hannibal2.skyhanni.features.dungeon.DungeonRankTabListColor import at.hannibal2.skyhanni.features.dungeon.DungeonTeammateOutlines import at.hannibal2.skyhanni.features.dungeon.HighlightDungeonDeathmite +import at.hannibal2.skyhanni.features.event.UniqueGiftingOpportunitiesFeatures import at.hannibal2.skyhanni.features.event.diana.BurrowWarpHelper import at.hannibal2.skyhanni.features.event.diana.GriffinBurrowHelper import at.hannibal2.skyhanni.features.event.diana.GriffinBurrowParticleFinder @@ -106,6 +113,7 @@ import at.hannibal2.skyhanni.features.event.diana.SoopyGuessBurrow import at.hannibal2.skyhanni.features.event.jerry.HighlightJerries import at.hannibal2.skyhanni.features.event.jerry.frozentreasure.FrozenTreasureTracker import at.hannibal2.skyhanni.features.event.spook.TheGreatSpook +import at.hannibal2.skyhanni.features.event.winter.UniqueGiftCounter import at.hannibal2.skyhanni.features.fame.AccountUpgradeReminder import at.hannibal2.skyhanni.features.fame.CityProjectFeatures import at.hannibal2.skyhanni.features.fishing.ChumBucketHider @@ -119,6 +127,9 @@ import at.hannibal2.skyhanni.features.fishing.SeaCreatureMessageShortener import at.hannibal2.skyhanni.features.fishing.SharkFishCounter import at.hannibal2.skyhanni.features.fishing.ShowFishingItemName import at.hannibal2.skyhanni.features.fishing.ThunderSparksHighlight +import at.hannibal2.skyhanni.features.fishing.tracker.FishingProfitPlayerMoving +import at.hannibal2.skyhanni.features.fishing.tracker.FishingProfitTracker +import at.hannibal2.skyhanni.features.fishing.tracker.FishingTrackerCategoryManager import at.hannibal2.skyhanni.features.fishing.trophy.OdgerWaypoint import at.hannibal2.skyhanni.features.fishing.trophy.TrophyFishFillet import at.hannibal2.skyhanni.features.fishing.trophy.TrophyFishManager @@ -130,7 +141,9 @@ import at.hannibal2.skyhanni.features.garden.GardenCropMilestoneFix import at.hannibal2.skyhanni.features.garden.GardenLevelDisplay import at.hannibal2.skyhanni.features.garden.GardenNextJacobContest import at.hannibal2.skyhanni.features.garden.GardenOptimalSpeed +import at.hannibal2.skyhanni.features.garden.GardenPlotAPI import at.hannibal2.skyhanni.features.garden.GardenPlotBorders +import at.hannibal2.skyhanni.features.garden.GardenWarpCommands import at.hannibal2.skyhanni.features.garden.GardenYawAndPitch import at.hannibal2.skyhanni.features.garden.ToolTooltipTweaks import at.hannibal2.skyhanni.features.garden.composter.ComposterDisplay @@ -162,6 +175,10 @@ import at.hannibal2.skyhanni.features.garden.inventory.GardenInventoryNumbers import at.hannibal2.skyhanni.features.garden.inventory.GardenNextPlotPrice import at.hannibal2.skyhanni.features.garden.inventory.GardenPlotIcon import at.hannibal2.skyhanni.features.garden.inventory.SkyMartCopperPrice +import at.hannibal2.skyhanni.features.garden.pests.PestFinder +import at.hannibal2.skyhanni.features.garden.pests.PestSpawn +import at.hannibal2.skyhanni.features.garden.pests.PestSpawnTimer +import at.hannibal2.skyhanni.features.garden.pests.SprayFeatures import at.hannibal2.skyhanni.features.garden.visitor.GardenVisitorColorNames import at.hannibal2.skyhanni.features.garden.visitor.GardenVisitorDropStatistics import at.hannibal2.skyhanni.features.garden.visitor.GardenVisitorFeatures @@ -193,6 +210,7 @@ import at.hannibal2.skyhanni.features.mining.crystalhollows.CrystalHollowsNamesI import at.hannibal2.skyhanni.features.mining.powdertracker.PowderTracker import at.hannibal2.skyhanni.features.minion.MinionCollectLogic import at.hannibal2.skyhanni.features.minion.MinionFeatures +import at.hannibal2.skyhanni.features.minion.MinionXp import at.hannibal2.skyhanni.features.misc.BrewingStandOverlay import at.hannibal2.skyhanni.features.misc.ButtonOnPause import at.hannibal2.skyhanni.features.misc.CollectionTracker @@ -308,9 +326,6 @@ import at.hannibal2.skyhanni.utils.KeyboardManager import at.hannibal2.skyhanni.utils.MinecraftConsoleFilter.Companion.initLogging import at.hannibal2.skyhanni.utils.NEUVersionCheck.checkIfNeuIsLoaded import at.hannibal2.skyhanni.utils.TabListData -import at.hannibal2.skyhanni.utils.jsonobjects.FriendsJson -import at.hannibal2.skyhanni.utils.jsonobjects.JacobContestsJson -import at.hannibal2.skyhanni.utils.jsonobjects.KnownFeaturesJson import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job @@ -332,7 +347,7 @@ import org.apache.logging.log4j.Logger clientSideOnly = true, useMetadata = true, guiFactory = "at.hannibal2.skyhanni.config.ConfigGuiForgeInterop", - version = "0.21.1", + version = "0.22.Beta.8", ) class SkyHanniMod { @Mod.EventHandler @@ -377,6 +392,7 @@ class SkyHanniMod { loadModule(ActionBarStatsData) loadModule(GardenCropMilestoneInventory()) loadModule(GardenCropSpeed) + loadModule(GardenWarpCommands()) loadModule(ProfileStorageData) loadModule(TitleData()) loadModule(BlockData()) @@ -384,10 +400,14 @@ class SkyHanniMod { loadModule(EntityOutlineRenderer) loadModule(KeyboardManager) loadModule(AdvancedPlayerList) + loadModule(ItemAddManager()) + loadModule(BingoCardReader()) // APIs loadModule(BazaarApi()) loadModule(GardenAPI) + loadModule(GardenPlotAPI) + loadModule(DataWatcherAPI()) loadModule(CollectionAPI()) loadModule(FarmingContestAPI) loadModule(FriendAPI) @@ -407,7 +427,7 @@ class SkyHanniMod { loadModule(PlayerChatModifier()) loadModule(DungeonChatFilter()) loadModule(HideNotClickableItems()) - loadModule(ItemDisplayOverlayFeatures()) + loadModule(ItemDisplayOverlayFeatures) loadModule(CurrentPetDisplay()) loadModule(ExpOrbsOnGroundHider()) loadModule(FandomWikiFromMenus()) @@ -419,6 +439,8 @@ class SkyHanniMod { loadModule(DungeonCleanEnd()) loadModule(DungeonBossMessages()) loadModule(DungeonBossHideDamageSplash()) + loadModule(UniqueGiftingOpportunitiesFeatures) + loadModule(UniqueGiftCounter) loadModule(TrophyFishManager) loadModule(TrophyFishFillet()) loadModule(TrophyFishMessages()) @@ -501,6 +523,7 @@ class SkyHanniMod { loadModule(GardenVisitorFeatures()) loadModule(GardenInventoryNumbers()) loadModule(GardenVisitorTimer()) + loadModule(MinionXp()) loadModule(GardenNextPlotPrice()) loadModule(GardenCropMilestoneDisplay) loadModule(GardenCustomKeybinds) @@ -564,6 +587,9 @@ class SkyHanniMod { loadModule(PlayerTabComplete) loadModule(GetFromSacksTabComplete) loadModule(SlayerProfitTracker) + loadModule(FishingProfitTracker) + loadModule(FishingTrackerCategoryManager) + loadModule(FishingProfitPlayerMoving) loadModule(SlayerItemsOnGround()) loadModule(RestorePieceOfWizardPortalLore()) loadModule(QuickModMenuSwitch) @@ -611,7 +637,7 @@ class SkyHanniMod { loadModule(AccountUpgradeReminder()) loadModule(PetExpTooltip()) loadModule(Translator()) - loadModule(GardenPlotBorders()) + loadModule(GardenPlotBorders) loadModule(CosmeticFollowingLine()) loadModule(SuperpairsClicksAlert()) loadModule(PowderTracker) @@ -634,6 +660,10 @@ class SkyHanniMod { loadModule(DungeonFinderFeatures()) loadModule(PabloHelper()) loadModule(FishingBaitWarnings()) + loadModule(PestSpawn()) + loadModule(PestSpawnTimer) + loadModule(PestFinder()) + loadModule(SprayFeatures()) init() diff --git a/src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt b/src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt index cd7fa0c59..3336fcae3 100644 --- a/src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt @@ -2,8 +2,8 @@ package at.hannibal2.skyhanni.api import at.hannibal2.skyhanni.events.CollectionUpdateEvent import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent +import at.hannibal2.skyhanni.events.ItemAddEvent import at.hannibal2.skyhanni.events.ProfileJoinEvent -import at.hannibal2.skyhanni.events.entity.ItemAddInInventoryEvent import at.hannibal2.skyhanni.utils.ItemUtils.getLore import at.hannibal2.skyhanni.utils.ItemUtils.name import at.hannibal2.skyhanni.utils.LorenzUtils @@ -18,7 +18,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class CollectionAPI { // TODO USE SH-REPO - private val counterPattern = "(?:.*) §e(?<amount>.*)§6\\/(?:.*)".toPattern() + private val counterPattern = ".* §e(?<amount>.*)§6/.*".toPattern() private val singleCounterPattern = "§7Total Collected: §e(?<amount>.*)".toPattern() @SubscribeEvent @@ -69,9 +69,12 @@ class CollectionAPI { } @SubscribeEvent - fun onItemAdd(event: ItemAddInInventoryEvent) { - // TODO add support for replenish (higher collection than actual items in inv) + fun onItemAdd(event: ItemAddEvent) { val internalName = event.internalName + val (_, amount) = NEUItems.getMultiplier(internalName) + if (amount > 1) return + + // TODO add support for replenish (higher collection than actual items in inv) if (internalName.getItemStackOrNull() == null) { LorenzUtils.debug("CollectionAPI.addFromInventory: item is null for '$internalName'") return diff --git a/src/main/java/at/hannibal2/skyhanni/api/DataWatcherAPI.kt b/src/main/java/at/hannibal2/skyhanni/api/DataWatcherAPI.kt new file mode 100644 index 000000000..4eb107554 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/api/DataWatcherAPI.kt @@ -0,0 +1,21 @@ +package at.hannibal2.skyhanni.api + +import at.hannibal2.skyhanni.events.DataWatcherUpdatedEvent +import at.hannibal2.skyhanni.events.EntityCustomNameUpdateEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class DataWatcherAPI { + + private val DATA_VALUE_CUSTOM_NAME = 2 + + @SubscribeEvent + fun onDataWatcherUpdate(event: DataWatcherUpdatedEvent) { + for (updatedEntry in event.updatedEntries) { + if (updatedEntry.dataValueId == DATA_VALUE_CUSTOM_NAME) { + EntityCustomNameUpdateEvent(event.entity.customNameTag, event.entity).postAndCatch() + } + } + } + + // TODO move EntityHealthUpdateEvent logic from EntityData in here +} diff --git a/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt b/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt index ddd51b18f..04e01b565 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt @@ -2,17 +2,21 @@ package at.hannibal2.skyhanni.config import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.data.IslandType +import at.hannibal2.skyhanni.data.jsonobjects.local.FriendsJson +import at.hannibal2.skyhanni.data.jsonobjects.local.JacobContestsJson +import at.hannibal2.skyhanni.data.jsonobjects.local.KnownFeaturesJson import at.hannibal2.skyhanni.features.fishing.trophy.TrophyRarity import at.hannibal2.skyhanni.features.misc.update.UpdateManager import at.hannibal2.skyhanni.utils.LorenzLogger import at.hannibal2.skyhanni.utils.LorenzRarity +import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzVec import at.hannibal2.skyhanni.utils.NEUInternalName import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName import at.hannibal2.skyhanni.utils.NEUItems -import at.hannibal2.skyhanni.utils.jsonobjects.FriendsJson -import at.hannibal2.skyhanni.utils.jsonobjects.JacobContestsJson -import at.hannibal2.skyhanni.utils.jsonobjects.KnownFeaturesJson +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import at.hannibal2.skyhanni.utils.SimpleTimeMark.Companion.asTimeMark +import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker import com.google.gson.GsonBuilder import com.google.gson.JsonObject import com.google.gson.TypeAdapter @@ -37,6 +41,8 @@ import java.nio.file.StandardCopyOption import java.util.UUID import kotlin.concurrent.fixedRateTimer +typealias TrackerDisplayMode = SkyHanniTracker.DefaultDisplayMode + class ConfigManager { companion object { val gson = GsonBuilder().setPrettyPrinting() @@ -108,6 +114,24 @@ class ConfigManager { return IslandType.valueOf(reader.nextString().uppercase()) } }.nullSafe()) + .registerTypeAdapter(TrackerDisplayMode::class.java, object : TypeAdapter<TrackerDisplayMode>() { + override fun write(out: JsonWriter, value: TrackerDisplayMode) { + out.value(value.name) + } + + override fun read(reader: JsonReader): TrackerDisplayMode { + return TrackerDisplayMode.valueOf(reader.nextString()) + } + }.nullSafe()) + .registerTypeAdapter(SimpleTimeMark::class.java, object : TypeAdapter<SimpleTimeMark>() { + override fun write(out: JsonWriter, value: SimpleTimeMark) { + out.value(value.toMillis()) + } + + override fun read(reader: JsonReader): SimpleTimeMark { + return reader.nextString().toLong().asTimeMark() + } + }.nullSafe()) .enableComplexMapKeySerialization() .create() @@ -168,7 +192,17 @@ class ConfigManager { output = if (fileType == ConfigFileType.FEATURES) { val jsonObject = gson.fromJson(bufferedReader.readText(), JsonObject::class.java) val newJsonObject = ConfigUpdaterMigrator.fixConfig(jsonObject) - gson.fromJson(newJsonObject, defaultValue.javaClass) + val run = { gson.fromJson(newJsonObject, defaultValue.javaClass) } + if (LorenzUtils.isInDevEnviromen()) { + try { + run() + } catch (e: Throwable) { + e.printStackTrace() + LorenzUtils.shutdownMinecraft("Config is corrupt inside developement enviroment.") + } + } else { + run() + } } else { gson.fromJson(bufferedReader.readText(), defaultValue.javaClass) } diff --git a/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt b/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt index 0db542e12..0f638e22b 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt +++ b/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt @@ -9,7 +9,7 @@ import com.google.gson.JsonPrimitive object ConfigUpdaterMigrator { val logger = LorenzLogger("ConfigMigration") - const val CONFIG_VERSION = 9 + const val CONFIG_VERSION = 12 fun JsonElement.at(chain: List<String>, init: Boolean): JsonElement? { if (chain.isEmpty()) return this if (this !is JsonObject) return null @@ -34,7 +34,7 @@ object ConfigUpdaterMigrator { } } - fun move(since: Int, oldPath: String, newPath: String, transform: (JsonElement) -> JsonElement = { it }) { + fun move(since: Int, oldPath: String, newPath: String = oldPath, transform: (JsonElement) -> JsonElement = { it }) { if (since <= oldVersion) { logger.log("Skipping move from $oldPath to $newPath ($since <= $oldVersion)") return diff --git a/src/main/java/at/hannibal2/skyhanni/config/HasLegacyId.java b/src/main/java/at/hannibal2/skyhanni/config/HasLegacyId.java new file mode 100644 index 000000000..a867cb570 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/HasLegacyId.java @@ -0,0 +1,26 @@ +package at.hannibal2.skyhanni.config; + +/** + * The interface HasLegacyId. + * To be used for config elements that are being migrated from ArrayLists to Enums. + * A legacyId is not needed for new elements. + */ +public interface HasLegacyId { + + /** + * Gets display string. + * + * @return the display string + */ + String toString(); + + /** + * Gets legacy id. This is used for legacy configs that are being migrated to enums. + * New elements do not need a legacyId, and should return -1 + * + * @return the legacy id + */ + default int getLegacyId() { + return -1; + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/config/Storage.java b/src/main/java/at/hannibal2/skyhanni/config/Storage.java index b21361b6f..52f10c40e 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/Storage.java +++ b/src/main/java/at/hannibal2/skyhanni/config/Storage.java @@ -5,9 +5,11 @@ import at.hannibal2.skyhanni.features.combat.endernodetracker.EnderNodeTracker; import at.hannibal2.skyhanni.features.combat.ghostcounter.GhostData; import at.hannibal2.skyhanni.features.dungeon.DungeonAPI; import at.hannibal2.skyhanni.features.event.jerry.frozentreasure.FrozenTreasureTracker; +import at.hannibal2.skyhanni.features.fishing.tracker.FishingProfitTracker; import at.hannibal2.skyhanni.features.fishing.trophy.TrophyRarity; import at.hannibal2.skyhanni.features.garden.CropAccessory; import at.hannibal2.skyhanni.features.garden.CropType; +import at.hannibal2.skyhanni.features.garden.GardenPlotAPI; import at.hannibal2.skyhanni.features.garden.farming.ArmorDropTracker; import at.hannibal2.skyhanni.features.garden.farming.DicerDropTracker; import at.hannibal2.skyhanni.features.garden.fortuneguide.FarmingItems; @@ -19,13 +21,16 @@ import at.hannibal2.skyhanni.features.rift.area.westvillage.KloonTerminal; import at.hannibal2.skyhanni.features.slayer.SlayerProfitTracker; import at.hannibal2.skyhanni.utils.LorenzVec; import at.hannibal2.skyhanni.utils.NEUInternalName; +import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker; import com.google.gson.annotations.Expose; import net.minecraft.item.ItemStack; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.UUID; public class Storage { @@ -50,6 +55,9 @@ public class Storage { public Boolean contestSendingAsked = false; @Expose + public Map<String, SkyHanniTracker.DisplayMode> trackerDisplayModes = new HashMap<>(); + + @Expose public Map<UUID, PlayerSpecific> players = new HashMap<>(); public static class PlayerSpecific { @@ -71,6 +79,19 @@ public class Storage { @Expose public List<String> guildMembers = new ArrayList<>(); + + @Expose + public WinterStorage winter = new WinterStorage(); + + public static class WinterStorage { + + @Expose + public Set<String> playersThatHaveBeenGifted = new HashSet<>(); + + @Expose + public int amountGifted = 0; + } + } public static class ProfileSpecific { @@ -222,6 +243,9 @@ public class Storage { } @Expose + public Map<Integer, GardenPlotAPI.PlotData> plotData = new HashMap<>(); + + @Expose public Map<CropType, LorenzVec> cropStartLocations = new HashMap<>(); @Expose @@ -389,5 +413,15 @@ public class Storage { @Expose public Map<DungeonAPI.DungeonFloor, Integer> bosses = new HashMap<>(); } + + @Expose + public FishingStorage fishing = new FishingStorage(); + + public static class FishingStorage { + + @Expose + public FishingProfitTracker.Data fishingProfitTracker = new FishingProfitTracker.Data(); + + } } } 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 8e4791901..1a0b41629 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt +++ b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt @@ -7,8 +7,8 @@ import at.hannibal2.skyhanni.data.ChatManager import at.hannibal2.skyhanni.data.GardenCropMilestonesCommunityFix import at.hannibal2.skyhanni.data.GuiEditManager import at.hannibal2.skyhanni.data.PartyAPI -import at.hannibal2.skyhanni.features.bingo.BingoCardDisplay -import at.hannibal2.skyhanni.features.bingo.BingoNextStepHelper +import at.hannibal2.skyhanni.features.bingo.card.BingoCardDisplay +import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.BingoNextStepHelper import at.hannibal2.skyhanni.features.chat.Translator import at.hannibal2.skyhanni.features.combat.endernodetracker.EnderNodeTracker import at.hannibal2.skyhanni.features.combat.ghostcounter.GhostUtil @@ -18,6 +18,7 @@ import at.hannibal2.skyhanni.features.event.diana.InquisitorWaypointShare import at.hannibal2.skyhanni.features.event.jerry.frozentreasure.FrozenTreasureTracker import at.hannibal2.skyhanni.features.fame.AccountUpgradeReminder import at.hannibal2.skyhanni.features.fame.CityProjectFeatures +import at.hannibal2.skyhanni.features.fishing.tracker.FishingProfitTracker import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.features.garden.GardenCropTimeCommand import at.hannibal2.skyhanni.features.garden.GardenNextJacobContest @@ -72,7 +73,6 @@ object Commands { ConfigGuiManager.openConfigGui(it.joinToString(" ")) } } else { - val arr = mutableListOf<String>() ConfigGuiManager.openConfigGui() } } @@ -174,6 +174,7 @@ object Commands { ) { EnderNodeTracker.resetCommand(it) } registerCommand("shresetarmordroptracker", "Resets the Armor Drop Tracker") { ArmorDropTracker.resetCommand(it) } registerCommand("shresetfrozentreasuretracker", "Resets the Frozen Treasure Tracker") { FrozenTreasureTracker.resetCommand(it) } + registerCommand("shresetfishingtracker", "Resets the Frozen Treasure Tracker") { FishingProfitTracker.resetCommand(it) } registerCommand("shbingotoggle", "Toggle the bingo card display mode") { BingoCardDisplay.toggleCommand() } registerCommand( "shfarmingprofile", @@ -211,6 +212,10 @@ object Commands { "Reset data about minion profit and the name display on the private island" ) { MinionFeatures.clearMinionData() } registerCommand( + "shwhereami", + "Print current island in chat" + ) { SkyHanniDebugsAndTests.whereami() } + registerCommand( "shconfig", "Search or reset config elements §c(warning, dangerous!)" ) { SkyHanniConfigSearchResetCommand.command(it) } @@ -381,7 +386,7 @@ object Commands { @JvmStatic fun openFortuneGuide() { if (!LorenzUtils.inSkyBlock) { - LorenzUtils.chat("§cJoin SkyBlock to open the fortune guide!", false) + LorenzUtils.userError("Join SkyBlock to open the fortune guide!") } else { CaptureFarmingGear.captureFarmingGear() SkyHanniMod.screenToOpen = FFGuideGUI() @@ -391,7 +396,7 @@ object Commands { @JvmStatic fun openVisualWords() { if (!LorenzUtils.onHypixel) { - LorenzUtils.chat("§cYou need to join Hypixel to use this feature!", false) + LorenzUtils.userError("You need to join Hypixel to use this feature!") } else { if (VisualWordGui.sbeConfigPath.exists()) VisualWordGui.drawImport = true SkyHanniMod.screenToOpen = VisualWordGui() diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/chat/FilterTypesConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/chat/FilterTypesConfig.java index 42cca5b59..f37e66705 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/chat/FilterTypesConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/chat/FilterTypesConfig.java @@ -74,6 +74,12 @@ public class FilterTypesConfig { @FeatureToggle public boolean profileJoin = true; + @Expose + @ConfigOption(name = "Fire Sale", desc = "Hide the repeating fire sale reminder chat messages.") + @ConfigEditorBoolean + @FeatureToggle + public boolean fireSale = true; + //TODO remove @Expose @ConfigOption(name = "Others", desc = "Hide other annoying messages.") diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/combat/EnderNodeConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/combat/EnderNodeConfig.java index 0fd962084..37f6cdfb8 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/combat/EnderNodeConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/EnderNodeConfig.java @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.config.features.combat; import at.hannibal2.skyhanni.config.FeatureToggle; +import at.hannibal2.skyhanni.config.HasLegacyId; import at.hannibal2.skyhanni.config.core.config.Position; import com.google.gson.annotations.Expose; import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; @@ -12,6 +13,23 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.COINS_MADE; +import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.ENCHANTED_ENDER_PEARL; +import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.ENCHANTED_END_STONE; +import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.ENCHANTED_OBSIDIAN; +import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.ENDERMAN_PET; +import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.ENDERMITE_NEST; +import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.ENDER_ARMOR; +import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.GRAND_XP_BOTTLE; +import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.MAGICAL_RUNE_I; +import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.MITE_GEL; +import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.NODES_MINED; +import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.SHRIMP_THE_FISH; +import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.SPACER_1; +import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.SPACER_2; +import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.TITANIC_XP_BOTTLE; +import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.TITLE; + public class EnderNodeConfig { @Expose @ConfigOption( @@ -28,36 +46,76 @@ public class EnderNodeConfig { name = "Text Format", desc = "Drag text to change the appearance of the overlay." ) - @ConfigEditorDraggableList( - exampleText = { - "§5§lEnder Node Tracker", - "§d1,303 Ender Nodes Mined", - "§615.3M Coins Made", - " ", - "§b123 §cEndermite Nest", - "§b832 §aEnchanted End Stone", - "§b230 §aEnchanted Obsidian", - "§b1630 §aEnchanted Ender Pearl", - "§b85 §aGrand Experience Bottle", - "§b4 §9Titanic Experience Bottle", - "§b15 §9End Stone Shulker", - "§b53 §9End Stone Geode", - "§b10 §d◆ Magical Rune I", - "§b24 §5Ender Gauntlet", - "§b357 §5Mite Gel", - "§b2 §cShrimp The Fish", - " ", - "§b200 §5Ender Armor", - "§b24 §5Ender Helmet", - "§b24 §5Ender Chestplate", - "§b24 §5Ender Leggings", - "§b24 §5Ender Boots", - "§b24 §5Ender Necklace", - "§f10§7-§a8§7-§93§7-§52§7-§61 §fEnderman Pet", - " " + @ConfigEditorDraggableList() + public Property<List<EnderNodeDisplayEntry>> textFormat = Property.of(new ArrayList<>(Arrays.asList( + TITLE, + NODES_MINED, + COINS_MADE, + SPACER_1, + ENDERMITE_NEST, + ENCHANTED_END_STONE, + ENCHANTED_OBSIDIAN, + ENCHANTED_ENDER_PEARL, + GRAND_XP_BOTTLE, + TITANIC_XP_BOTTLE, + MAGICAL_RUNE_I, + MITE_GEL, + SHRIMP_THE_FISH, + SPACER_2, + ENDER_ARMOR, + ENDERMAN_PET) + )); + + public enum EnderNodeDisplayEntry implements HasLegacyId { + TITLE("§5§lEnder Node Tracker", 0), + NODES_MINED("§d1,303 Ender Nodes Mined", 1), + COINS_MADE("§615.3M Coins Made", 2), + SPACER_1(" ", 3), + ENDERMITE_NEST("§b123 §cEndermite Nest", 4), + ENCHANTED_END_STONE("§b832 §aEnchanted End Stone", 5), + ENCHANTED_OBSIDIAN("§b230 §aEnchanted Obsidian", 6), + ENCHANTED_ENDER_PEARL("§b1630 §aEnchanted Ender Pearl", 7), + GRAND_XP_BOTTLE("§b85 §aGrand Experience Bottle", 8), + TITANIC_XP_BOTTLE("§b4 §9Titanic Experience Bottle", 9), + END_STONE_SHULKER("§b15 §9End Stone Shulker", 10), + END_STONE_GEODE("§b53 §9End Stone Geode", 11), + MAGICAL_RUNE_I("§b10 §d◆ Magical Rune I", 12), + ENDER_GAUNTLET("§b24 §5Ender Gauntlet", 13), + MITE_GEL("§b357 §5Mite Gel", 14), + SHRIMP_THE_FISH("§b2 §cShrimp The Fish", 15), + SPACER_2(" ", 16), + ENDER_ARMOR("§b200 §5Ender Armor", 17), + ENDER_HELMET("§b24 §5Ender Helmet", 18), + ENDER_CHESTPLATE("§b24 §5Ender Chestplate", 19), + ENDER_LEGGINGS("§b24 §5Ender Leggings", 20), + ENDER_BOOTS("§b24 §5Ender Boots", 21), + ENDER_NECKLACE("§b24 §5Ender Necklace", 22), + ENDERMAN_PET("§f10§7-§a8§7-§93§7-§52§7-§61 §fEnderman Pet", 23), + ; + + private final String str; + private final int legacyId; + + EnderNodeDisplayEntry(String str, int legacyId) { + this.str = str; + this.legacyId = legacyId; } - ) - public Property<List<Integer>> textFormat = Property.of(new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 14, 15, 16, 17, 23))); + + // Constructor if new enum elements are added post-migration + EnderNodeDisplayEntry(String str) { + this(str, -1); + } + + @Override + public int getLegacyId() { + return legacyId; + } + + @Override + public String toString() { + return str; + } + } @Expose public Position position = new Position(10, 80, false, true); diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/combat/MobsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/combat/MobsConfig.java index 77731d854..3514c6729 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/combat/MobsConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/MobsConfig.java @@ -6,11 +6,6 @@ import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; import io.github.moulberry.moulconfig.annotations.ConfigOption; public class MobsConfig { - - @Expose - @ConfigOption(name = "Highlighters", desc = "") - public boolean highlighters = false; - @Expose @ConfigOption(name = "Area Boss", desc = "Highlight Golden Ghoul, Old Wolf, Voidling Extremist and Millenia-Aged Blaze.") @ConfigEditorBoolean @@ -57,10 +52,6 @@ public class MobsConfig { public boolean arachneBossHighlighter = true; @Expose - @ConfigOption(name = "Respawn Timers", desc = "") - public boolean timers = false; - - @Expose @ConfigOption( name = "Area Boss", desc = "Show a timer when Golden Ghoul, Old Wolf, Voidling Extremist or Millenia-Aged Blaze respawns. " + diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/combat/damageindicator/DamageIndicatorConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/combat/damageindicator/DamageIndicatorConfig.java index c77e5f3f0..6986d706c 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/combat/damageindicator/DamageIndicatorConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/damageindicator/DamageIndicatorConfig.java @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.config.features.combat.damageindicator; import at.hannibal2.skyhanni.config.FeatureToggle; +import at.hannibal2.skyhanni.config.HasLegacyId; import com.google.gson.annotations.Expose; import io.github.moulberry.moulconfig.annotations.Accordion; import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; @@ -12,6 +13,22 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.ARACHNE; +import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.DIANA_MOBS; +import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.DUNGEON_ALL; +import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.GARDEN_PESTS; +import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.INFERNO_DEMONLORD; +import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.NETHER_MINI_BOSSES; +import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.REINDRAKE; +import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.REVENANT_HORROR; +import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.RIFTSTALKER_BLOODFIEND; +import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.SEA_CREATURES; +import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.SVEN_PACKMASTER; +import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.TARANTULA_BROODFATHER; +import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.THE_RIFT_BOSSES; +import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.VANQUISHER; +import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.VOIDGLOOM_SERAPH; + public class DamageIndicatorConfig { @Expose @@ -37,38 +54,79 @@ public class DamageIndicatorConfig { name = "Select Boss", desc = "Change what type of boss you want the damage indicator be enabled for." ) - @ConfigEditorDraggableList( - exampleText = { - "§bDungeon All", - "§bNether Mini Bosses", - "§bVanquisher", - "§bEndstone Protector (not tested)", - "§bEnder Dragon (not finished)", - "§bRevenant Horror", - "§bTarantula Broodfather", - "§bSven Packmaster", - "§bVoidgloom Seraph", - "§bInferno Demonlord", - "§bHeadless Horseman (bugged)", - "§bDungeon Floor 1", - "§bDungeon Floor 2", - "§bDungeon Floor 3", - "§bDungeon Floor 4", - "§bDungeon Floor 5", - "§bDungeon Floor 6", - "§bDungeon Floor 7", - "§bDiana Mobs", - "§bSea Creatures", - "Dummy", - "§bArachne", - "§bThe Rift Bosses", - "§bRiftstalker Bloodfiend", - "§6Reindrake" - } - ) + @ConfigEditorDraggableList() //TODO only show currently working and tested features - public List<Integer> bossesToShow = new ArrayList<>(Arrays.asList(0, 1, 2, 5, 6, 7, 8, 9, 18, 19, 21, 22, 23, 24)); + public List<DamageIndicatorBossEntry> bossesToShow = new ArrayList<>(Arrays.asList( + DUNGEON_ALL, + NETHER_MINI_BOSSES, + VANQUISHER, + REVENANT_HORROR, + TARANTULA_BROODFATHER, + SVEN_PACKMASTER, + VOIDGLOOM_SERAPH, + INFERNO_DEMONLORD, + DIANA_MOBS, + SEA_CREATURES, + ARACHNE, + THE_RIFT_BOSSES, + RIFTSTALKER_BLOODFIEND, + REINDRAKE, + GARDEN_PESTS + + )); + public enum DamageIndicatorBossEntry implements HasLegacyId { + DUNGEON_ALL("§bDungeon All", 0), + NETHER_MINI_BOSSES("§bNether Mini Bosses", 1), + VANQUISHER("§bVanquisher", 2), + ENDERSTONE_PROTECTOR("§bEndstone Protector (not tested)", 3), + ENDER_DRAGON("§bEnder Dragon (not finished)", 4), + REVENANT_HORROR("§bRevenant Horror", 5), + TARANTULA_BROODFATHER("§bTarantula Broodfather", 6), + SVEN_PACKMASTER("§bSven Packmaster", 7), + VOIDGLOOM_SERAPH("§bVoidgloom Seraph", 8), + INFERNO_DEMONLORD("§bInferno Demonlord", 9), + HEADLESS_HORSEMAN("§bHeadless Horseman (bugged)", 10), + DUNGEON_FLOOR_1("§bDungeon Floor 1", 11), + DUNGEON_FLOOR_2("§bDungeon Floor 2", 12), + DUNGEON_FLOOR_3("§bDungeon Floor 3", 13), + DUNGEON_FLOOR_4("§bDungeon Floor 4", 14), + DUNGEON_FLOOR_5("§bDungeon Floor 5", 15), + DUNGEON_FLOOR_6("§bDungeon Floor 6", 16), + DUNGEON_FLOOR_7("§bDungeon Floor 7", 17), + DIANA_MOBS("§bDiana Mobs", 18), + SEA_CREATURES("§bSea Creatures", 19), + DUMMY("Dummy", 20), + ARACHNE("§bArachne", 21), + THE_RIFT_BOSSES("§bThe Rift Bosses", 22), + RIFTSTALKER_BLOODFIEND("§bRiftstalker Bloodfiend", 23), + REINDRAKE("§6Reindrake", 24), + GARDEN_PESTS("§aGarden Pests", 25), + ; + + private final String str; + private final int legacyId; + + DamageIndicatorBossEntry(String str, int legacyId) { + this.str = str; + this.legacyId = legacyId; + } + + // Constructor if new enum elements are added post-migration + DamageIndicatorBossEntry(String str) { + this(str, -1); + } + + @Override + public int getLegacyId() { + return legacyId; + } + + @Override + public String toString() { + return str; + } + } @Expose @ConfigOption(name = "Hide Damage Splash", desc = "Hiding damage splashes near the damage indicator.") @ConfigEditorBoolean diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/GhostCounterConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/GhostCounterConfig.java index 783c4cda5..6bc8ee48d 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/GhostCounterConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/GhostCounterConfig.java @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.config.features.combat.ghostcounter; import at.hannibal2.skyhanni.config.FeatureToggle; +import at.hannibal2.skyhanni.config.HasLegacyId; import at.hannibal2.skyhanni.config.core.config.Position; import at.hannibal2.skyhanni.config.features.combat.ghostcounter.textformatting.TextFormattingConfig; import at.hannibal2.skyhanni.features.combat.ghostcounter.GhostUtil; @@ -16,6 +17,16 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import static at.hannibal2.skyhanni.config.features.combat.ghostcounter.GhostCounterConfig.GhostDisplayEntry.AVG_MAGIC_FIND; +import static at.hannibal2.skyhanni.config.features.combat.ghostcounter.GhostCounterConfig.GhostDisplayEntry.GHOSTS_KILLED; +import static at.hannibal2.skyhanni.config.features.combat.ghostcounter.GhostCounterConfig.GhostDisplayEntry.GHOST_PER_SORROW; +import static at.hannibal2.skyhanni.config.features.combat.ghostcounter.GhostCounterConfig.GhostDisplayEntry.GHOST_SINCE_SORROW; +import static at.hannibal2.skyhanni.config.features.combat.ghostcounter.GhostCounterConfig.GhostDisplayEntry.HIGHEST_KILL_COMBO; +import static at.hannibal2.skyhanni.config.features.combat.ghostcounter.GhostCounterConfig.GhostDisplayEntry.KILL_COMBO; +import static at.hannibal2.skyhanni.config.features.combat.ghostcounter.GhostCounterConfig.GhostDisplayEntry.SCAVENGER_COINS; +import static at.hannibal2.skyhanni.config.features.combat.ghostcounter.GhostCounterConfig.GhostDisplayEntry.SORROW; +import static at.hannibal2.skyhanni.config.features.combat.ghostcounter.GhostCounterConfig.GhostDisplayEntry.TITLE; + public class GhostCounterConfig { @Expose @@ -29,31 +40,65 @@ public class GhostCounterConfig { name = "Display Text", desc = "Drag text to change the appearance of the overlay." ) - @ConfigEditorDraggableList( - exampleText = { - "§6Ghosts Counter", - " §bGhost Killed: 42", - " §bSorrow: 6", - " §bGhost since Sorrow: 1", - " §bGhosts/Sorrow: 5", - " §bVolta: 6", - " §bPlasma: 8", - " §bGhostly Boots: 1", - " §bBag Of Cash: 4", - " §bAvg Magic Find: 271", - " §bScavenger Coins: 15,000", - " §bKill Combo: 14", - " §bHighest Kill Combo: 96", - " §bSkill XP Gained: 145,648", - " §bBestiary 1: 0/10", - " §bXP/h: 810,410", - " §bKills/h: 420", - " §bETA: 14d", - " §bMoney/h: 13,420,069", - " §bMoney made: 14B" + @ConfigEditorDraggableList() + public List<GhostDisplayEntry> ghostDisplayText = new ArrayList<>(Arrays.asList( + TITLE, + GHOSTS_KILLED, + SORROW, + GHOST_SINCE_SORROW, + GHOST_PER_SORROW, + AVG_MAGIC_FIND, + SCAVENGER_COINS, + KILL_COMBO, + HIGHEST_KILL_COMBO + )); + + public enum GhostDisplayEntry implements HasLegacyId { + TITLE("§6Ghosts Counter", 0), + GHOSTS_KILLED(" §bGhost Killed: 42", 1), + SORROW(" §bSorrow: 6", 2), + GHOST_SINCE_SORROW(" §bGhost since Sorrow: 1", 3), + GHOST_PER_SORROW(" §bGhosts/Sorrow: 5", 4), + VOLTA(" §bVolta: 6", 5), + PLASMA(" §bPlasma: 8", 6), + GHOSTLY_BOOTS(" §bGhostly Boots: 1", 7), + BAG_OF_CASH(" §bBag Of Cash: 4", 8), + AVG_MAGIC_FIND(" §bAvg Magic Find: 271", 9), + SCAVENGER_COINS(" §bScavenger Coins: 15,000", 10), + KILL_COMBO(" §bKill Combo: 14", 11), + HIGHEST_KILL_COMBO(" §bHighest Kill Combo: 96", 12), + SKILL_XP_GAINED(" §bSkill XP Gained: 145,648", 13), + BESTIARY(" §bBestiary 1: 0/10", 14), + XP_PER_HOUR(" §bXP/h: 810,410", 15), + KILLS_PER_HOUR(" §bKills/h: 420", 16), + ETA(" §bETA: 14d", 17), + MONEY_PER_HOUR(" §bMoney/h: 13,420,069", 18), + MONEY_MADE(" §bMoney made: 14B", 19), + ; + + private final String str; + private final int legacyId; + + GhostDisplayEntry(String str, int legacyId) { + this.str = str; + this.legacyId = legacyId; } - ) - public List<Integer> ghostDisplayText = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 9, 10, 11, 12)); + + // Constructor if new enum elements are added post-migration + GhostDisplayEntry(String str) { + this(str, -1); + } + + @Override + public int getLegacyId() { + return legacyId; + } + + @Override + public String toString() { + return str; + } + } @ConfigOption(name = "Text Formatting", desc = "") @Accordion diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/TextFormattingConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/TextFormattingConfig.java index 750b3ae2c..1414a986d 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/TextFormattingConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/TextFormattingConfig.java @@ -35,11 +35,11 @@ public class TextFormattingConfig { public String titleFormat = "&6Ghost Counter"; @Expose - @ConfigOption(name = "Ghost Killed", desc = "Ghost Killed line.\n§e%value% §ris replaced with\n" + - "Ghost Killed.\n" + - "§e%session% §7is replaced with Ghost killed") + @ConfigOption(name = "Ghosts Killed", desc = "Ghosts Killed line.\n§e%value% §ris replaced with\n" + + "Ghosts Killed.\n" + + "§e%session% §7is replaced with Ghosts killed") @ConfigEditorText - public String ghostKilledFormat = " &6Ghost Killed: &b%value% &7(%session%)"; + public String ghostKilledFormat = " &6Ghosts Killed: &b%value% &7(%session%)"; @Expose @ConfigOption(name = "Sorrows", desc = "Sorrows drop line.\n" + diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/commands/TabCompleteConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/commands/TabCompleteConfig.java index 6e3420a59..b7edd0e07 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/commands/TabCompleteConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/commands/TabCompleteConfig.java @@ -15,6 +15,7 @@ public class TabCompleteConfig { @Expose @ConfigOption(name = "Island Players", desc = "Tab complete other players on the same island.") + @ConfigEditorBoolean public boolean islandPlayers = true; @Expose diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/dev/DebugConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/dev/DebugConfig.java index 7f7b9af63..bdce11628 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/dev/DebugConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/dev/DebugConfig.java @@ -85,4 +85,10 @@ public class DebugConfig { @ConfigOption(name = "Hot Swap Detection", desc = "Show chat messages when Hot Swap starts and ends.") @ConfigEditorBoolean public boolean hotSwapDetection = false; + + @Expose + @ConfigOption(name = "SkyHanni Event Counter", desc = "Count once per second how many skyhanni events gets triggered, " + + "show the total amount in console output.") + @ConfigEditorBoolean + public boolean eventCounter = false; } diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoCardConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoCardConfig.java index 44dd23ec4..ae382d25d 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoCardConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoCardConfig.java @@ -42,4 +42,14 @@ public class BingoCardConfig { @Expose public Position bingoCardPos = new Position(10, 10, false, true); + + @Expose + @ConfigOption(name = "Next Tip Duration", desc = "Show the duration until the next hidden personal goal gets a tip revealed.") + @ConfigEditorBoolean + public Property<Boolean> nextTipDuration = Property.of(true); + + @Expose + @ConfigOption(name = "Hide Difficulty When Done", desc = "Remove the background difficulty color in the bingo card inventory when the goal is done.") + @ConfigEditorBoolean + public boolean hideDoneDifficulty = true; } diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoConfig.java index 816f8a194..24fdf9732 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoConfig.java @@ -26,5 +26,11 @@ public class BingoConfig { public boolean minionCraftHelperEnabled = true; @Expose + @ConfigOption(name = "Show Progress to T1", desc = "Show tier 1 Minion Crafts in the Helper display even if needed items are not fully collected.") + @ConfigEditorBoolean + @FeatureToggle + public boolean minionCraftHelperProgressFirst = false; + + @Expose public Position minionCraftHelperPos = new Position(10, 10, false, true); } diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/FrozenTreasureConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/FrozenTreasureConfig.java index 2b41265a6..a1f378d08 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/FrozenTreasureConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/FrozenTreasureConfig.java @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.config.features.event.winter; import at.hannibal2.skyhanni.config.FeatureToggle; +import at.hannibal2.skyhanni.config.HasLegacyId; import at.hannibal2.skyhanni.config.core.config.Position; import com.google.gson.annotations.Expose; import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; @@ -11,6 +12,20 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.COMPACT_PROCS; +import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.ENCHANTED_ICE; +import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.ENCHANTED_PACKED_ICE; +import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.GLACIAL_FRAGMENT; +import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.GLACIAL_TALISMAN; +import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.GREEN_GIFT; +import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.ICE_PER_HOUR; +import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.RED_GIFT; +import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.SPACER_1; +import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.TITLE; +import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.TOTAL_ICE; +import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.TREASURES_MINED; +import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.WHITE_GIFT; + public class FrozenTreasureConfig { @Expose @@ -28,28 +43,65 @@ public class FrozenTreasureConfig { name = "Text Format", desc = "Drag text to change the appearance of the overlay." ) - @ConfigEditorDraggableList( - exampleText = { - "§1§lFrozen Treasure Tracker", - "§61,636 Treasures Mined", - "§33.2m Total Ice", - "§3342,192 Ice/hr", - "§81,002 Compact Procs", - " ", - "§b182 §fWhite Gift", - "§b94 §aGreen Gift", - "§b17 §9§cRed Gift", - "§b328 §fPacked Ice", - "§b80 §aEnchanted Ice", - "§b4 §9Enchanted Packed Ice", - "§b182 §aIce Bait", - "§b3 §aGlowy Chum Bait", - "§b36 §5Glacial Fragment", - "§b6 §fGlacial Talisman", - " ", + @ConfigEditorDraggableList() + public List<FrozenTreasureDisplayEntry> textFormat = new ArrayList<>(Arrays.asList( + TITLE, + TREASURES_MINED, + TOTAL_ICE, + ICE_PER_HOUR, + COMPACT_PROCS, + SPACER_1, + WHITE_GIFT, + GREEN_GIFT, + RED_GIFT, + ENCHANTED_ICE, + ENCHANTED_PACKED_ICE, + GLACIAL_FRAGMENT, + GLACIAL_TALISMAN + )); + + public enum FrozenTreasureDisplayEntry implements HasLegacyId { + TITLE("§1§lFrozen Treasure Tracker", 0), + TREASURES_MINED("§61,636 Treasures Mined", 1), + TOTAL_ICE("§33.2m Total Ice", 2), + ICE_PER_HOUR("§3342,192 Ice/hr", 3), + COMPACT_PROCS("§81,002 Compact Procs", 4), + SPACER_1(" ", 5), + WHITE_GIFT("§b182 §fWhite Gift", 6), + GREEN_GIFT("§b94 §aGreen Gift", 7), + RED_GIFT("§b17 §9§cRed Gift", 8), + PACKED_ICE("§b328 §fPacked Ice", 9), + ENCHANTED_ICE("§b80 §aEnchanted Ice", 10), + ENCHANTED_PACKED_ICE("§b4 §9Enchanted Packed Ice", 11), + ICE_BAIT("§b182 §aIce Bait", 12), + GLOWY_CHUM_BAIT("§b3 §aGlowy Chum Bait", 13), + GLACIAL_FRAGMENT("§b36 §5Glacial Fragment", 14), + GLACIAL_TALISMAN("§b6 §fGlacial Talisman", 15), + SPACER_2(" ", 16); + + private final String str; + private final int legacyId; + + FrozenTreasureDisplayEntry(String str, int legacyId) { + this.str = str; + this.legacyId = legacyId; } - ) - public List<Integer> textFormat = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 14, 15)); + + // Constructor if new enum elements are added post-migration + FrozenTreasureDisplayEntry(String str) { + this(str, -1); + } + + @Override + public int getLegacyId() { + return legacyId; + } + + @Override + public String toString() { + return str; + } + } @Expose @ConfigOption(name = "Only in Glacial Cave", desc = "Only shows the overlay while in the Glacial Cave.") diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/GiftingOpportunitiesConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/GiftingOpportunitiesConfig.java new file mode 100644 index 000000000..f303099b4 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/GiftingOpportunitiesConfig.java @@ -0,0 +1,27 @@ +package at.hannibal2.skyhanni.config.features.event.winter; + +import at.hannibal2.skyhanni.config.FeatureToggle; +import com.google.gson.annotations.Expose; +import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; +import io.github.moulberry.moulconfig.annotations.ConfigOption; + +public class GiftingOpportunitiesConfig { + @Expose + @ConfigOption(name = "Enabled", desc = "Highlight players who you haven't given gifts to yet.") + @ConfigEditorBoolean + @FeatureToggle + public boolean enabled = true; + + @Expose + @ConfigOption(name = "Only While Holding Gift", desc = "Only highlight ungifted players while holding a gift.") + @ConfigEditorBoolean + public boolean highlighWithGiftOnly = true; + + + @Expose + @ConfigOption(name = "Use Armor Stands", desc = "Make use of armor stands to stop highlighting players. " + + "This is a bit inaccurate, but it can help with people you gifted before this feature was used.") + @ConfigEditorBoolean + public boolean useArmorStandDetection = false; + +} diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/UniqueGiftConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/UniqueGiftConfig.java new file mode 100644 index 000000000..5ccc823c5 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/UniqueGiftConfig.java @@ -0,0 +1,19 @@ +package at.hannibal2.skyhanni.config.features.event.winter; + +import at.hannibal2.skyhanni.config.FeatureToggle; +import at.hannibal2.skyhanni.config.core.config.Position; +import com.google.gson.annotations.Expose; +import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; +import io.github.moulberry.moulconfig.annotations.ConfigOption; + +public class UniqueGiftConfig { + @Expose + @ConfigOption(name = "Enabled", desc = "Show in a display how many unique players you have given gifts to in the winter 2023 event." + + " Open §e/opengenerowmenu §7to sync up!") + @ConfigEditorBoolean + @FeatureToggle + public boolean enabled = true; + + @Expose + public Position position = new Position(100, 100, false, true); +} diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/WinterConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/WinterConfig.java index 8af9472b1..79ac983c2 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/WinterConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/WinterConfig.java @@ -14,6 +14,16 @@ public class WinterConfig { @Accordion public FrozenTreasureConfig frozenTreasureTracker = new FrozenTreasureConfig(); + @Accordion + @Expose + @ConfigOption(name = "Unique Gifting Opportunities", desc = "Highlight players who you haven't given gifts to yet.") + public GiftingOpportunitiesConfig giftingOpportunities = new GiftingOpportunitiesConfig(); + + @Accordion + @Expose + @ConfigOption(name = "Unique Gift Counter", desc = "Keep track how many unique players you have given gifts to.") + public UniqueGiftConfig uniqueGiftCounter = new UniqueGiftConfig(); + @Expose @ConfigOption(name = "Island Close Time", desc = "While on the Winter Island, show a timer until Jerry's Workshop closes.") @ConfigEditorBoolean diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/BarnTimerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/BarnTimerConfig.java index eb0577135..bf2609ed0 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/BarnTimerConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/BarnTimerConfig.java @@ -22,15 +22,31 @@ public class BarnTimerConfig { @Expose @ConfigOption( name = "Worm Fishing", - desc = "Show the Barn Fishing Timer even for worms or other sea creatures in the Crystal Hollows." + desc = "Show the Barn Fishing Timer in the Crystal Hollows." ) @ConfigEditorBoolean public boolean crystalHollows = true; @Expose @ConfigOption( + name = "Lava Fishing", + desc = "Show the Barn Fishing Timer in the Crimson Isle." + ) + @ConfigEditorBoolean + public boolean crimsonIsle = true; + + @Expose + @ConfigOption( + name = "Winter Fishing", + desc = "Show the Barn Fishing Timer on the Jerry's Workshop." + ) + @ConfigEditorBoolean + public boolean winterIsland = true; + + @Expose + @ConfigOption( name = "Stranded Fishing", - desc = "Show the Barn Fishing Timer even on all the different islands Stranded players can visit." + desc = "Show the Barn Fishing Timer on all the different islands that Stranded players can visit." ) @ConfigEditorBoolean public boolean forStranded = true; diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingConfig.java index 13ef30f84..349f4882e 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingConfig.java @@ -51,6 +51,11 @@ public class FishingConfig { public RareCatchesConfig rareCatches = new RareCatchesConfig(); @Expose + @ConfigOption(name = "Fishing Profit Tracker", desc = "") + @Accordion + public FishingProfitTrackerConfig fishingProfitTracker = new FishingProfitTrackerConfig(); + + @Expose @ConfigOption( name = "Shark Fish Counter", desc = "Counts how many Sharks have been caught." diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingProfitTrackerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingProfitTrackerConfig.java new file mode 100644 index 000000000..4090e12dd --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingProfitTrackerConfig.java @@ -0,0 +1,29 @@ +package at.hannibal2.skyhanni.config.features.fishing; + +import at.hannibal2.skyhanni.config.FeatureToggle; +import at.hannibal2.skyhanni.config.core.config.Position; +import com.google.gson.annotations.Expose; +import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; +import io.github.moulberry.moulconfig.annotations.ConfigOption; + +public class FishingProfitTrackerConfig { + + @Expose + @ConfigOption(name = "Enabled", desc = "Count all items you pick up while fishing.") + @ConfigEditorBoolean + @FeatureToggle + public boolean enabled = false; + + @Expose + public Position position = new Position(20, 20, false, true); + + @Expose + @ConfigOption(name = "Hide Moving", desc = "Hide the Fishing Profit Tracker while moving.") + @ConfigEditorBoolean + public boolean hideMoving = true; + + @Expose + @ConfigOption(name = "Show When Pickup", desc = "Show the fishing tracker for a couple of seconds after catching something even while moving.") + @ConfigEditorBoolean + public boolean showWhenPickup = true; +} diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/CropStartLocationConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/CropStartLocationConfig.java index 33a797bcb..721c5757f 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/garden/CropStartLocationConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/CropStartLocationConfig.java @@ -8,7 +8,7 @@ import io.github.moulberry.moulconfig.annotations.ConfigOption; public class CropStartLocationConfig { @Expose - @ConfigOption(name = "Enable", desc = "Show the start waypoint for your farm with the currently holding tool.") + @ConfigOption(name = "Enable", desc = "Show the start waypoint for the farm of your current tool in hand. Do §e/shcropstartlocation §7to change the waypoint again.") @ConfigEditorBoolean @FeatureToggle public boolean enabled = false; diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenCommandsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenCommandsConfig.java new file mode 100644 index 000000000..5f7d28b2e --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenCommandsConfig.java @@ -0,0 +1,31 @@ +package at.hannibal2.skyhanni.config.features.garden; + +import at.hannibal2.skyhanni.config.FeatureToggle; +import com.google.gson.annotations.Expose; +import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; +import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind; +import io.github.moulberry.moulconfig.annotations.ConfigOption; +import org.lwjgl.input.Keyboard; + +public class GardenCommandsConfig { + @Expose + @ConfigOption(name = "Warp Commands", desc = "Enable commands §e/home§7, §e/barn §7and §e/tp <plot>§7. §cOnly works while in the garden.") + @ConfigEditorBoolean + @FeatureToggle + public boolean warpCommands = true; + + @Expose + @ConfigOption(name = "Home Hotkey", desc = "Press this key to teleport you to your Garden home. §cOnly works while in the garden.") + @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE) + public int homeHotkey = Keyboard.KEY_NONE; + + @Expose + @ConfigOption(name = "Sethome Hotkey", desc = "Press this key to set your Garden home. §cOnly works while in the garden.") + @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE) + public int sethomeHotkey = Keyboard.KEY_NONE; + + @Expose + @ConfigOption(name = "Barn Hotkey", desc = "Press this key to teleport you to the Garden barn. §cOnly works while in the garden.") + @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE) + public int barnHotkey = Keyboard.KEY_NONE; +} diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenConfig.java index 7553f2f2a..77e497b5e 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenConfig.java @@ -5,6 +5,7 @@ import at.hannibal2.skyhanni.config.core.config.Position; import at.hannibal2.skyhanni.config.features.garden.composter.ComposterConfig; import at.hannibal2.skyhanni.config.features.garden.cropmilestones.CropMilestonesConfig; import at.hannibal2.skyhanni.config.features.garden.optimalspeed.OptimalSpeedConfig; +import at.hannibal2.skyhanni.config.features.garden.pests.PestsConfig; import at.hannibal2.skyhanni.config.features.garden.visitor.VisitorConfig; import com.google.gson.annotations.Expose; import io.github.moulberry.moulconfig.annotations.Accordion; @@ -84,6 +85,10 @@ public class GardenConfig { public ComposterConfig composters = new ComposterConfig(); @Expose + @Category(name = "Pests", desc = "Pests Settings") + public PestsConfig pests = new PestsConfig(); + + @Expose @ConfigOption(name = "Farming Fortune Display", desc = "") @Accordion public FarmingFortuneConfig farmingFortunes = new FarmingFortuneConfig(); @@ -109,6 +114,11 @@ public class GardenConfig { public PlotIconConfig plotIcon = new PlotIconConfig(); @Expose + @ConfigOption(name = "Garden Commands", desc = "") + @Accordion + public GardenCommandsConfig gardenCommands = new GardenCommandsConfig(); + + @Expose @ConfigOption(name = "Plot Price", desc = "Show the price of the plot in coins when inside the Configure Plots inventory.") @ConfigEditorBoolean @FeatureToggle @@ -204,6 +214,12 @@ public class GardenConfig { public boolean plotBorders = true; @Expose + @ConfigOption(name = "Plot Name in Scoreboard", desc = "Showing a more compact plot name in scoreboard. Updates faster and doesnt hide when pests are spawned.") + @ConfigEditorBoolean + @FeatureToggle + public boolean plotNameInScoreboard = true; + + @Expose @ConfigOption(name = "Copy Milestone Data", desc = "Copy wrong crop milestone data in clipboard when opening the crop milestone menu. Please share this data in SkyHanni discord.") @ConfigEditorBoolean @FeatureToggle diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/MoneyPerHourConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/MoneyPerHourConfig.java index 5606e5e3d..77c9eddc2 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/garden/MoneyPerHourConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/MoneyPerHourConfig.java @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.config.features.garden; import at.hannibal2.skyhanni.config.FeatureToggle; +import at.hannibal2.skyhanni.config.HasLegacyId; import at.hannibal2.skyhanni.config.core.config.Position; import com.google.gson.annotations.Expose; import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; @@ -12,6 +13,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import static at.hannibal2.skyhanni.config.features.garden.MoneyPerHourConfig.CustomFormatEntry.INSTANT_SELL; +import static at.hannibal2.skyhanni.config.features.garden.MoneyPerHourConfig.CustomFormatEntry.NPC_PRICE; +import static at.hannibal2.skyhanni.config.features.garden.MoneyPerHourConfig.CustomFormatEntry.SELL_OFFER; + public class MoneyPerHourConfig { @Expose @ConfigOption(name = "Show Money per Hour", @@ -40,7 +45,7 @@ public class MoneyPerHourConfig { @Expose @ConfigOption( name = "Always On", - desc = "Always show the money/hour Display while on the garden.") + desc = "Always show the money/hour Display while in the garden.") @ConfigEditorBoolean public boolean alwaysOn = false; @@ -70,14 +75,43 @@ public class MoneyPerHourConfig { name = "Custom Format", desc = "Set what prices to show") @ConfigEditorDraggableList( - exampleText = { - "§eSell Offer", - "§eInstant Sell", - "§eNPC Price" - }, requireNonEmpty = true ) - public List<Integer> customFormat = new ArrayList<>(Arrays.asList(0, 1, 2)); + public List<CustomFormatEntry> customFormat = new ArrayList<>(Arrays.asList( + SELL_OFFER, + INSTANT_SELL, + NPC_PRICE + )); + + public enum CustomFormatEntry implements HasLegacyId { + SELL_OFFER("§eSell Offer", 0), + INSTANT_SELL("§eInstant Sell", 1), + NPC_PRICE("§eNPC Price", 2), + ; + + private final String str; + private final int legacyId; + + CustomFormatEntry(String str, int legacyId) { + this.str = str; + this.legacyId = legacyId; + } + + // Constructor if new enum elements are added post-migration + CustomFormatEntry(String str) { + this(str, -1); + } + + @Override + public int getLegacyId() { + return legacyId; + } + + @Override + public String toString() { + return str; + } + } @Expose @ConfigOption( diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/NextJacobContestConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/NextJacobContestConfig.java index f9b0f80e4..b17f31279 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/garden/NextJacobContestConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/NextJacobContestConfig.java @@ -16,7 +16,7 @@ public class NextJacobContestConfig { public boolean display = true; @Expose - @ConfigOption(name = "Outside Garden", desc = "Show the timer not only in Garden but everywhere in SkyBlock.") + @ConfigOption(name = "Outside Garden", desc = "Show the timer not only in the Garden but everywhere in SkyBlock.") @ConfigEditorBoolean public boolean everywhere = false; diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/CropMilestonesConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/CropMilestonesConfig.java index 053ffe900..8f2d5a450 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/CropMilestonesConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/CropMilestonesConfig.java @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.config.features.garden.cropmilestones; import at.hannibal2.skyhanni.config.FeatureToggle; +import at.hannibal2.skyhanni.config.HasLegacyId; import at.hannibal2.skyhanni.config.core.config.Position; import com.google.gson.annotations.Expose; import io.github.moulberry.moulconfig.annotations.Accordion; @@ -15,6 +16,14 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.CropMilestonesConfig.MilestoneTextEntry.BLOCKS_PER_SECOND; +import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.CropMilestonesConfig.MilestoneTextEntry.CROPS_PER_MINUTE; +import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.CropMilestonesConfig.MilestoneTextEntry.MILESTONE_TIER; +import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.CropMilestonesConfig.MilestoneTextEntry.NUMBER_OUT_OF_TOTAL; +import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.CropMilestonesConfig.MilestoneTextEntry.TIME; +import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.CropMilestonesConfig.MilestoneTextEntry.TITLE; +import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.CropMilestonesConfig.TimeFormatEntry.YEAR; + public class CropMilestonesConfig { @Expose @ConfigOption( @@ -38,8 +47,40 @@ public class CropMilestonesConfig { @ConfigOption( name = "Time Format", desc = "Change the highest time unit to show (1h30m vs 90min)") - @ConfigEditorDropdown(values = {"Year", "Day", "Hour", "Minute", "Second"}) - public Property<Integer> highestTimeFormat = Property.of(0); + @ConfigEditorDropdown() + public Property<TimeFormatEntry> highestTimeFormat = Property.of(YEAR); + + public enum TimeFormatEntry implements HasLegacyId { + YEAR("Year", 0), + DAY("Day", 1), + HOUR("Hour", 2), + MINUTE("Minute", 3), + SECOND("Second", 4), + ; + + private final String str; + private final int legacyId; + + TimeFormatEntry(String str, int legacyId) { + this.str = str; + this.legacyId = legacyId; + } + + // Constructor if new enum elements are added post-migration + TimeFormatEntry(String str) { + this(str, -1); + } + + @Override + public int getLegacyId() { + return legacyId; + } + + @Override + public String toString() { + return str; + } + } @Expose @ConfigOption( @@ -54,18 +95,49 @@ public class CropMilestonesConfig { desc = "Drag text to change the appearance of the overlay.\n" + "Hold a farming tool to show the overlay." ) - @ConfigEditorDraggableList( - exampleText = { - "§6Crop Milestones", - "§7Pumpkin Tier 22", - "§e12,300§8/§e100,000", - "§7In §b12m 34s", - "§7Crops/Minute§8: §e12,345", - "§7Blocks/Second§8: §e19.85", - "§7Percentage: §e12.34%", + @ConfigEditorDraggableList() + public List<MilestoneTextEntry> text = new ArrayList<>(Arrays.asList( + TITLE, + MILESTONE_TIER, + NUMBER_OUT_OF_TOTAL, + TIME, + CROPS_PER_MINUTE, + BLOCKS_PER_SECOND + )); + + public enum MilestoneTextEntry implements HasLegacyId { + TITLE("§6Crop Milestones", 0), + MILESTONE_TIER("§7Pumpkin Tier 22", 1), + NUMBER_OUT_OF_TOTAL("§e12,300§8/§e100,000", 2), + TIME("§7In §b12m 34s", 3), + CROPS_PER_MINUTE("§7Crops/Minute§8: §e12,345", 4), + BLOCKS_PER_SECOND("§7Blocks/Second§8: §e19.85", 5), + PERCENTAGE("§7Percentage: §e12.34%", 6), + ; + + private final String str; + private final int legacyId; + + MilestoneTextEntry(String str, int legacyId) { + this.str = str; + this.legacyId = legacyId; } - ) - public List<Integer> text = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5)); + + // Constructor if new enum elements are added post-migration + MilestoneTextEntry(String str) { + this(str, -1); + } + + @Override + public int getLegacyId() { + return legacyId; + } + + @Override + public String toString() { + return str; + } + } @Expose @ConfigOption(name = "Block Broken Precision", desc = "The amount of decimals displayed in blocks/second.") diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/MushroomPetPerkConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/MushroomPetPerkConfig.java index 66ef83a4c..2cd4cd911 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/MushroomPetPerkConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/MushroomPetPerkConfig.java @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.config.features.garden.cropmilestones; import at.hannibal2.skyhanni.config.FeatureToggle; +import at.hannibal2.skyhanni.config.HasLegacyId; import at.hannibal2.skyhanni.config.core.config.Position; import com.google.gson.annotations.Expose; import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; @@ -11,6 +12,11 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.MushroomPetPerkConfig.MushroomTextEntry.MUSHROOM_TIER; +import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.MushroomPetPerkConfig.MushroomTextEntry.NUMBER_OUT_OF_TOTAL; +import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.MushroomPetPerkConfig.MushroomTextEntry.TIME; +import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.MushroomPetPerkConfig.MushroomTextEntry.TITLE; + // TODO moulconfig runnable support public class MushroomPetPerkConfig { @Expose @@ -27,16 +33,45 @@ public class MushroomPetPerkConfig { desc = "Drag text to change the appearance of the overlay.\n" + "Hold a farming tool to show the overlay." ) - @ConfigEditorDraggableList( - exampleText = { - "§6Mooshroom Cow Perk", - "§7Mushroom Tier 8", - "§e6,700§8/§e15,000", - "§7In §b12m 34s", - "§7Percentage: §e12.34%", + @ConfigEditorDraggableList() + public List<MushroomTextEntry> text = new ArrayList<>(Arrays.asList( + TITLE, + MUSHROOM_TIER, + NUMBER_OUT_OF_TOTAL, + TIME + )); + + public enum MushroomTextEntry implements HasLegacyId { + TITLE("§6Mooshroom Cow Perk", 0), + MUSHROOM_TIER("§7Mushroom Tier 8", 1), + NUMBER_OUT_OF_TOTAL("§e6,700§8/§e15,000", 2), + TIME("§7In §b12m 34s", 3), + PERCENTAGE("§7Percentage: §e12.34%", 4), + ; + + private final String str; + private final int legacyId; + + MushroomTextEntry(String str, int legacyId) { + this.str = str; + this.legacyId = legacyId; } - ) - public List<Integer> text = new ArrayList<>(Arrays.asList(0, 1, 2, 3)); + + // Constructor if new enum elements are added post-migration + MushroomTextEntry(String str) { + this(str, -1); + } + + @Override + public int getLegacyId() { + return legacyId; + } + + @Override + public String toString() { + return str; + } + } @Expose public Position pos = new Position(-112, -143, false, true); diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/NextConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/NextConfig.java index 6dcd047a9..188848e48 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/NextConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/NextConfig.java @@ -43,7 +43,7 @@ public class NextConfig { @Expose @ConfigOption( name = "Always On", - desc = "Show the Best Display always while on the garden.") + desc = "Show the Best Display always while in the garden.") @ConfigEditorBoolean public boolean bestAlwaysOn = false; diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestFinderConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestFinderConfig.java new file mode 100644 index 000000000..9f4b69d12 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestFinderConfig.java @@ -0,0 +1,46 @@ +package at.hannibal2.skyhanni.config.features.garden.pests; + +import at.hannibal2.skyhanni.config.FeatureToggle; +import at.hannibal2.skyhanni.config.core.config.Position; +import com.google.gson.annotations.Expose; +import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; +import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind; +import io.github.moulberry.moulconfig.annotations.ConfigOption; +import org.lwjgl.input.Keyboard; + +public class PestFinderConfig { + + @Expose + @ConfigOption( + name = "Display", + desc = "Show a display with all know pest locations." + ) + @ConfigEditorBoolean + @FeatureToggle + public boolean showDisplay = true; + + @Expose + @ConfigOption( + name = "Show Plot in World", + desc = "Mark infected plot names and world border in the world." + ) + @ConfigEditorBoolean + @FeatureToggle + public boolean showPlotInWorld = true; + + @Expose + @ConfigOption( + name = "Only With Vacuum", + desc = "Only show the pest display and waypoints while holding a vacuum in the hand." + ) + @ConfigEditorBoolean + public boolean onlyWithVacuum = true; + + @Expose + public Position position = new Position(-350, 200, 1.3f); + + @Expose + @ConfigOption(name = "Teleport Hotkey", desc = "Press this key to warp to the nearest plot with pests on it.") + @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE) + public int teleportHotkey = Keyboard.KEY_NONE; +} diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestSpawnConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestSpawnConfig.java new file mode 100644 index 000000000..ba723acfa --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestSpawnConfig.java @@ -0,0 +1,26 @@ +package at.hannibal2.skyhanni.config.features.garden.pests; + +import at.hannibal2.skyhanni.config.FeatureToggle; +import com.google.gson.annotations.Expose; +import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; +import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown; +import io.github.moulberry.moulconfig.annotations.ConfigOption; + +public class PestSpawnConfig { + + @Expose + @ConfigOption( + name = "Chat Message Format", + desc = "Change how the pest spawn chat message should be formatted.") + @ConfigEditorDropdown(values = {"Hypixel Style", "Compact", "Disabled"}) + public int chatMessageFormat = 0; + + @Expose + @ConfigOption( + name = "Show Title", + desc = "Show a Title when a pest spawns." + ) + @ConfigEditorBoolean + @FeatureToggle + public boolean showTitle = true; +} diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestTimerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestTimerConfig.java new file mode 100644 index 000000000..43b69b2ef --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestTimerConfig.java @@ -0,0 +1,30 @@ +package at.hannibal2.skyhanni.config.features.garden.pests; + +import at.hannibal2.skyhanni.config.FeatureToggle; +import at.hannibal2.skyhanni.config.core.config.Position; +import com.google.gson.annotations.Expose; +import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; +import io.github.moulberry.moulconfig.annotations.ConfigOption; + +public class PestTimerConfig { + + @Expose + @ConfigOption( + name = "Enabled", + desc = "Show the time since the last pest spawned in your garden." + ) + @ConfigEditorBoolean + @FeatureToggle + public boolean enabled = true; + + @Expose + @ConfigOption( + name = "Only With Vacuum", + desc = "Only show the time while holding a vacuum in the hand." + ) + @ConfigEditorBoolean + public boolean onlyWithVacuum = true; + + @Expose + public Position position = new Position(390, 65, false, true); +} diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestsConfig.java new file mode 100644 index 000000000..94e972dfe --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestsConfig.java @@ -0,0 +1,28 @@ +package at.hannibal2.skyhanni.config.features.garden.pests; + +import com.google.gson.annotations.Expose; +import io.github.moulberry.moulconfig.annotations.Accordion; +import io.github.moulberry.moulconfig.annotations.ConfigOption; + +public class PestsConfig { + + @Expose + @ConfigOption(name = "Pest Spawn", desc = "") + @Accordion + public PestSpawnConfig pestSpawn = new PestSpawnConfig(); + + @Expose + @ConfigOption(name = "Pest Finder", desc = "") + @Accordion + public PestFinderConfig pestFinder = new PestFinderConfig(); + + @Expose + @ConfigOption(name = "Pest Timer", desc = "") + @Accordion + public PestTimerConfig pestTimer = new PestTimerConfig(); + + @Expose + @ConfigOption(name = "Spray", desc = "") + @Accordion + public SprayConfig spray = new SprayConfig(); +} diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/SprayConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/SprayConfig.java new file mode 100644 index 000000000..da715712f --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/SprayConfig.java @@ -0,0 +1,28 @@ +package at.hannibal2.skyhanni.config.features.garden.pests; + +import at.hannibal2.skyhanni.config.FeatureToggle; +import at.hannibal2.skyhanni.config.core.config.Position; +import com.google.gson.annotations.Expose; +import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; +import io.github.moulberry.moulconfig.annotations.ConfigOption; + +public class SprayConfig { + + @Expose + @ConfigOption( + name = "Pest Spray Selector", + desc = "Show the pests that are attracted when changing the selected material of the §aSprayonator§7." + ) + @ConfigEditorBoolean + @FeatureToggle + public boolean pestWhenSelector = true; + + @Expose + @ConfigOption(name = "Draw Plot Border", desc = "Draw plots border when holding the Sprayonator.") + @ConfigEditorBoolean + @FeatureToggle + public boolean drawPlotsBorderWhenInHands = true; + + @Expose + public Position position = new Position(315, -200, 2.3f); +} diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/DropsStatisticsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/DropsStatisticsConfig.java index 7fd332d25..eb6f6b0fe 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/DropsStatisticsConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/DropsStatisticsConfig.java @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.config.features.garden.visitor; import at.hannibal2.skyhanni.config.FeatureToggle; +import at.hannibal2.skyhanni.config.HasLegacyId; import at.hannibal2.skyhanni.config.core.config.Position; import com.google.gson.annotations.Expose; import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; @@ -11,6 +12,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import static at.hannibal2.skyhanni.config.features.garden.visitor.DropsStatisticsConfig.DropsStatisticsTextEntry.*; + public class DropsStatisticsConfig { @Expose @@ -27,34 +30,78 @@ public class DropsStatisticsConfig { name = "Text Format", desc = "Drag text to change the appearance of the overlay." ) - @ConfigEditorDraggableList( - exampleText = { - "§e§lVisitor Statistics", - "§e1,636 Total", - "§a1,172§f-§9382§f-§681§f-§c1", - "§21,382 Accepted", - "§c254 Denied", - " ", - "§c62,072 Copper", - "§33.2m Farming EXP", - "§647.2m Coins Spent", - "§b23 §9Flowering Bouquet", - "§b4 §9Overgrown Grass", - "§b2 §5Green Bandana", - "§b1 §9Dedication IV", - "§b6 §b◆ Music Rune I", - "§b1 §cSpace Helmet", - "§b1 §9Cultivating I", - "§b1 §9Replenish I", - " ", // If they want another empty row - "§212,600 Garden EXP", - "§b4.2k Bits", - "§220k Mithril Powder", - "§d18k Gemstone Powder", + @ConfigEditorDraggableList() + public List<DropsStatisticsTextEntry> textFormat = new ArrayList<>(Arrays.asList( + TITLE, + TOTAL_VISITORS, + VISITORS_BY_RARITY, + ACCEPTED, + DENIED, + SPACER_1, + COPPER, + FARMING_EXP, + COINS_SPENT, + OVERGROWN_GRASS, + GREEN_BANDANA, + DEDICATION_IV + )); + + /** + * Do not change the order of the enums added to that list! New items are to be synced up with the implementation in GardenVisitorDropStatistics.drawDisplay. + * Generic non VisitorReward stuff belongs in front of the first VisitorReward. + */ + public enum DropsStatisticsTextEntry implements HasLegacyId { + // generic stuff + TITLE("§e§lVisitor Statistics", 0), + TOTAL_VISITORS("§e1,636 Total", 1), + VISITORS_BY_RARITY("§a1,172§f-§9382§f-§681§f-§d2§f-§c1", 2), + ACCEPTED("§21,382 Accepted", 3), + DENIED("§c254 Denied", 4), + SPACER_1(" ", 5), + COPPER("§c62,072 Copper", 6), + FARMING_EXP("§33.2m Farming EXP", 7), + COINS_SPENT("§647.2m Coins Spent", 8), + SPACER_2(" ", 17), + GARDEN_EXP("§212,600 Garden EXP", 18), + BITS("§b4.2k Bits", 19), + MITHRIL_POWDER("§220k Mithril Powder", 20), + GEMSTONE_POWDER("§d18k Gemstone Powder", 21), + + // VisitorReward items + FLOWERING_BOUQUET("§b23 §9Flowering Bouquet", 9), + OVERGROWN_GRASS("§b4 §9Overgrown Grass", 10), + GREEN_BANDANA("§b2 §5Green Bandana", 11), + DEDICATION_IV("§b1 §9Dedication IV", 12), + MUSIC_RUNE_I("§b6 §b◆ Music Rune I", 13), + SPACE_HELMET("§b1 §cSpace Helmet", 14), + CULTIVATING_I("§b1 §9Cultivating I", 15), + REPLENISH_I("§b1 §9Replenish I", 16), + DELICATE("§9Delicate V"), + ; + + private final String str; + private final int legacyId; + + DropsStatisticsTextEntry(String str, int legacyId) { + this.str = str; + this.legacyId = legacyId; } - ) - public List<Integer> textFormat = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12)); + // Constructor if new enum elements are added post-migration + DropsStatisticsTextEntry(String str) { + this(str, -1); + } + + @Override + public int getLegacyId() { + return legacyId; + } + + @Override + public String toString() { + return str; + } + } @Expose @ConfigOption(name = "Display Numbers First", desc = "Determines whether the number or drop name displays first. " + diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/RewardWarningConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/RewardWarningConfig.java index f83fc5518..ee6ce50b1 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/RewardWarningConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/RewardWarningConfig.java @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.config.features.garden.visitor; import at.hannibal2.skyhanni.config.FeatureToggle; +import at.hannibal2.skyhanni.features.garden.visitor.VisitorReward; import com.google.gson.annotations.Expose; import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; import io.github.moulberry.moulconfig.annotations.ConfigEditorDraggableList; @@ -38,25 +39,20 @@ public class RewardWarningConfig { public int bypassKey = Keyboard.KEY_NONE; - /** - * Sync up with {at.hannibal2.skyhanni.features.garden.visitor.VisitorReward} - */ @Expose @ConfigOption( name = "Items", - desc = "Warn for these reward items." + desc = "Warn for these reward item visitor drops." ) - @ConfigEditorDraggableList( - exampleText = { - "§9Flowering Bouquet", - "§9Overgrown Grass", - "§9Green Bandana", - "§9Dedication IV", - "§9Music Rune", - "§cSpace Helmet", - "§9Cultivating I", - "§9Replenish I", - } - ) - public List<Integer> drops = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6)); + @ConfigEditorDraggableList + public List<VisitorReward> drops = new ArrayList<>(Arrays.asList( + VisitorReward.OVERGROWN_GRASS, + VisitorReward.GREEN_BANDANA, + VisitorReward.DEDICATION, + VisitorReward.MUSIC_RUNE, + VisitorReward.SPACE_HELMET, + VisitorReward.CULTIVATING, + VisitorReward.REPLENISH + )); + } diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/VisitorConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/VisitorConfig.java index d010b11d3..ff8e09432 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/VisitorConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/VisitorConfig.java @@ -60,7 +60,7 @@ public class VisitorConfig { public boolean hypixelArrivedMessage = true; @Expose - @ConfigOption(name = "Hide Chat", desc = "Hide chat messages from the visitors in garden. (Except Beth and Spaceman)") + @ConfigOption(name = "Hide Chat", desc = "Hide chat messages from the visitors in the garden. (Except Beth, Jacob and Spaceman)") @ConfigEditorBoolean @FeatureToggle public boolean hideChat = true; @@ -98,7 +98,7 @@ public class VisitorConfig { desc = "Blocks you from interacting with / unlocking Visitors to allow for Dedication Cycling" ) @ConfigEditorDropdown - public VisitorBlockBehaviour blockInteracting = VisitorBlockBehaviour.ONLY_ON_BINGO; + public VisitorBlockBehaviour blockInteracting = VisitorBlockBehaviour.DONT; public enum VisitorBlockBehaviour { DONT("Don't"), ALWAYS("Always"), ONLY_ON_BINGO("Only on Bingo"); 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 1794a20d0..60cc0e405 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 @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.config.features.inventory; import at.hannibal2.skyhanni.config.FeatureToggle; +import at.hannibal2.skyhanni.config.HasLegacyId; import at.hannibal2.skyhanni.config.features.inventory.helper.HelperConfig; import com.google.gson.annotations.Expose; import io.github.moulberry.moulconfig.annotations.Accordion; @@ -13,6 +14,11 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import static at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.LARVA_HOOK; +import static at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.NEW_YEAR_CAKE; +import static at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.RANCHERS_BOOTS_SPEED; +import static at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.VACUUM_GARDEN; + public class InventoryConfig { @Expose @@ -55,25 +61,63 @@ public class InventoryConfig { name = "Item Number", desc = "Showing the item number as a stack size for these items." ) - @ConfigEditorDraggableList( - exampleText = { - "§bMaster Star Tier", - "§bMaster Skull Tier", - "§bDungeon Head Floor Number", - "§bNew Year Cake", - "§bPet Level", - "§bMinion Tier", - "§bCrimson Armor", - "§7(Removed)", - "§bKuudra Key", - "§bSkill Level", - "§bCollection Level", - "§bRancher's Boots speed", - "§bLarva Hook", - "§bDungeon Potion Level" + @ConfigEditorDraggableList() + public List<ItemNumberEntry> itemNumberAsStackSize = new ArrayList<>(Arrays.asList( + NEW_YEAR_CAKE, + RANCHERS_BOOTS_SPEED, + LARVA_HOOK, + VACUUM_GARDEN + )); + + public enum ItemNumberEntry implements HasLegacyId { + MASTER_STAR_TIER("§bMaster Star Tier", 0), + MASTER_SKULL_TIER("§bMaster Skull Tier", 1), + DUNGEON_HEAD_FLOOR_NUMBER("§bDungeon Head Floor Number", 2), + NEW_YEAR_CAKE("§bNew Year Cake", 3), + PET_LEVEL("§bPet Level", 4), + MINION_TIER("§bMinion Tier", 5), + CRIMSON_ARMOR("§bCrimson Armor", 6), + REMOVED("§7(Removed)", 7), + KUUDRA_KEY("§bKuudra Key", 8), + SKILL_LEVEL("§bSkill Level", 9), + COLLECTION_LEVEL("§bCollection Level", 10), + RANCHERS_BOOTS_SPEED("§bRancher's Boots speed", 11), + LARVA_HOOK("§bLarva Hook", 12), + DUNGEON_POTION_LEVEL("§bDungeon Potion Level", 13), + VACUUM_GARDEN("§bVacuum (Garden)", 14), + BOTTLE_OF_JYRRE("§bBottle Of Jyrre", 15), + EDITION_NUMBER("§bEdition Number", 16), + BINGO_GOAL_RANK("§bBingo Goal Rank"), + ; + + private final String str; + private final int legacyId; + + ItemNumberEntry(String str, int legacyId) { + this.str = str; + this.legacyId = legacyId; } - ) - public List<Integer> itemNumberAsStackSize = new ArrayList<>(Arrays.asList(3, 9, 11, 12)); + + // Constructor if new enum elements are added post-migration + ItemNumberEntry(String str) { + this(str, -1); + } + + @Override + public int getLegacyId() { + return legacyId; + } + + @Override + public String toString() { + return str; + } + } + + @Expose + @ConfigOption(name = " Vacuum Bag Cap", desc = "Capping the Garden Vacuum Bag item number display to 40.") + @ConfigEditorBoolean + public boolean vacuumBagCap = true; @Expose @ConfigOption( diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/mining/PowderTrackerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/mining/PowderTrackerConfig.java index 50bff2a9b..1e658c5a2 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/mining/PowderTrackerConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/mining/PowderTrackerConfig.java @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.config.features.mining; import at.hannibal2.skyhanni.config.FeatureToggle; +import at.hannibal2.skyhanni.config.HasLegacyId; import at.hannibal2.skyhanni.config.core.config.Position; import com.google.gson.annotations.Expose; import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; @@ -12,6 +13,26 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.AMBER; +import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.AMETHYST; +import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.DIAMOND_ESSENCE; +import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.DISPLAY_MODE; +import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.DOUBLE_POWDER; +import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.ELECTRON; +import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.FTX; +import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.GEMSTONE_POWDER; +import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.GOLD_ESSENCE; +import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.JADE; +import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.MITHRIL_POWDER; +import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.ROBOTRON; +import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.RUBY; +import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.SAPPHIRE; +import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.SPACER_1; +import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.SPACER_2; +import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.TITLE; +import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.TOPAZ; +import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.TOTAL_CHESTS; + public class PowderTrackerConfig { @Expose @@ -35,48 +56,88 @@ public class PowderTrackerConfig { name = "Text Format", desc = "Drag text to change the appearance of the overlay." ) - @ConfigEditorDraggableList( - exampleText = { - "§b§lPowder Tracker", - "§7Display Mode: §a[Total] §e[This Session]", - "§d852 Total chests Picked §7(950/h)", - "§bx2 Powder: §aActive!", - "§b250,420 §aMithril Powder §7(350,000/h)", - "§b250,420 §dGemstone Powder §7(350,000/h)", - "", - "§b129 §bDiamond Essence §7(600/h)", - "§b234 §6Gold Essence §7(700/h)", - "", - "§50§7-§90§7-§a0§f-0 §cRuby Gemstone", - "§50§7-§90§7-§a0§f-0 §bSapphire Gemstone", - "§50§7-§90§7-§a0§f-0 §6Amber Gemstone", - "§50§7-§90§7-§a0§f-0 §5Amethyst Gemstone", - "§50§7-§90§7-§a0§f-0 §aJade Gemstone", - "§50§7-§90§7-§a0§f-0 §eTopaz Gemstone", - - "§b14 §9FTX 3070", - "§b14 §9Electron Transmitter", - "§b14 §9Robotron Reflector", - "§b14 §9Superlite Motor", - "§b14 §9Control Switch", - "§b14 §9Synthetic Heart", - "§b14 §9Total Robot Parts", - - "§90§7-§a0§7-§c0§f-§e0§f-§30 §fGoblin Egg", - - "§b12 §aWishing Compass", - - "§b320 §aSludge Juice", - "§b2 §9Ascension Rope", - "§b6 §5Treasurite", - "§b4 §6Jungle Heart", - "§b1 §5Pickonimbus 2000", - "§b14 §aYoggie", - "§b9 §fPrehistoric Egg", - "§b25 §aOil Barrel" + @ConfigEditorDraggableList() + public Property<List<PowderDisplayEntry>> textFormat = Property.of(new ArrayList<>(Arrays.asList( + TITLE, + DISPLAY_MODE, + TOTAL_CHESTS, + DOUBLE_POWDER, + MITHRIL_POWDER, + GEMSTONE_POWDER, + SPACER_1, + DIAMOND_ESSENCE, + GOLD_ESSENCE, + SPACER_2, + RUBY, + SAPPHIRE, + AMBER, + AMETHYST, + JADE, + TOPAZ, + FTX, + ELECTRON, + ROBOTRON + ))); + + public enum PowderDisplayEntry implements HasLegacyId { + TITLE("§b§lPowder Tracker", 0), + DISPLAY_MODE("§7Display Mode: §a[Total] §e[This Session]", 1), + TOTAL_CHESTS("§d852 Total chests Picked §7(950/h)", 2), + DOUBLE_POWDER("§bx2 Powder: §aActive!", 3), + MITHRIL_POWDER("§b250,420 §aMithril Powder §7(350,000/h)", 4), + GEMSTONE_POWDER("§b250,420 §dGemstone Powder §7(350,000/h)", 5), + SPACER_1("", 6), + DIAMOND_ESSENCE("§b129 §bDiamond Essence §7(600/h)", 7), + GOLD_ESSENCE("§b234 §6Gold Essence §7(700/h)", 8), + SPACER_2("", 9), + RUBY("§50§7-§90§7-§a0§f-0 §cRuby Gemstone", 10), + SAPPHIRE("§50§7-§90§7-§a0§f-0 §bSapphire Gemstone", 11), + AMBER("§50§7-§90§7-§a0§f-0 §6Amber Gemstone", 12), + AMETHYST("§50§7-§90§7-§a0§f-0 §5Amethyst Gemstone", 13), + JADE("§50§7-§90§7-§a0§f-0 §aJade Gemstone", 14), + TOPAZ("§50§7-§90§7-§a0§f-0 §eTopaz Gemstone", 15), + FTX("§b14 §9FTX 3070", 16), + ELECTRON("§b14 §9Electron Transmitter", 17), + ROBOTRON("§b14 §9Robotron Reflector", 18), + SUPERLITE("§b14 §9Superlite Motor", 19), + CONTROL_SWITCH("§b14 §9Control Switch", 20), + SYNTHETIC_HEART("§b14 §9Synthetic Heart", 21), + TOTAL_ROBOT_PARTS("§b14 §9Total Robot Parts", 22), + GOBLIN_EGGS("§90§7-§a0§7-§c0§f-§e0§f-§30 §fGoblin Egg", 23), + WISHING_COMPASS("§b12 §aWishing Compass", 24), + SLUDGE_JUICE("§b320 §aSludge Juice", 25), + ASCENSION_ROPE("§b2 §9Ascension Rope", 26), + TREASURITE("§b6 §5Treasurite", 27), + JUNGLE_HEART("§b4 §6Jungle Heart", 28), + PICKONIMBUS("§b1 §5Pickonimbus 2000", 29), + YOGGIE("§b14 §aYoggie", 30), + PREHISTORIC_EGG("§b9 §fPrehistoric Egg", 31), + OIL_BARREL("§b25 §aOil Barrel", 32), + ; + + private final String str; + private final int legacyId; + + PowderDisplayEntry(String str, int legacyId) { + this.str = str; + this.legacyId = legacyId; } - ) - public Property<List<Integer>> textFormat = Property.of(new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18))); + + // Constructor if new enum elements are added post-migration + PowderDisplayEntry(String str) { + this(str, -1); + } + + @Override + public int getLegacyId() { + return legacyId; + } + + @Override + public String toString() { + return str; + } + } @Expose public Position position = new Position(-274, 0, false, true); diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/minion/MinionsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/minion/MinionsConfig.java index d54e3d464..4f089ce9d 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/minion/MinionsConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/minion/MinionsConfig.java @@ -36,6 +36,12 @@ public class MinionsConfig { public boolean hopperProfitDisplay = true; @Expose + @ConfigOption(name = "Show Xp", desc = "Shows how much skill experience you will get when picking up items from the minion storage.") + @ConfigEditorBoolean + @FeatureToggle + public boolean xpDisplay = true; + + @Expose public Position hopperProfitPos = new Position(360, 90, false, true); @Expose diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/DiscordRPCConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/DiscordRPCConfig.java index ab4a18d47..aa7a1d4b7 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/misc/DiscordRPCConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/DiscordRPCConfig.java @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.config.features.misc; import at.hannibal2.skyhanni.config.FeatureToggle; +import at.hannibal2.skyhanni.config.HasLegacyId; import com.google.gson.annotations.Expose; import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; import io.github.moulberry.moulconfig.annotations.ConfigEditorDraggableList; @@ -13,6 +14,13 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import static at.hannibal2.skyhanni.config.features.misc.DiscordRPCConfig.LineEntry.NOTHING; +import static at.hannibal2.skyhanni.config.features.misc.DiscordRPCConfig.PriorityEntry.AFK; +import static at.hannibal2.skyhanni.config.features.misc.DiscordRPCConfig.PriorityEntry.CROP_MILESTONES; +import static at.hannibal2.skyhanni.config.features.misc.DiscordRPCConfig.PriorityEntry.DUNGEONS; +import static at.hannibal2.skyhanni.config.features.misc.DiscordRPCConfig.PriorityEntry.SLAYER; +import static at.hannibal2.skyhanni.config.features.misc.DiscordRPCConfig.PriorityEntry.STACKING_ENCHANT; + public class DiscordRPCConfig { @Expose @@ -23,41 +31,13 @@ public class DiscordRPCConfig { @Expose @ConfigOption(name = "First Line", desc = "Decide what to show in the first line.") - @ConfigEditorDropdown(values = { - "Nothing", - "Location", - "Purse", - "Bits", - "Stats", - "Held Item", - "SkyBlock Date", - "Profile", - "Slayer", - "Custom", - "Dynamic", - "Crop Milestone", - "Current Pet" - }) - public Property<Integer> firstLine = Property.of(0); + @ConfigEditorDropdown() + public Property<LineEntry> firstLine = Property.of(NOTHING); @Expose @ConfigOption(name = "Second Line", desc = "Decide what to show in the second line.") - @ConfigEditorDropdown(values = { - "Nothing", - "Location", - "Purse", - "Bits", - "Stats", - "Held Item", - "SkyBlock Date", - "Profile", - "Slayer", - "Custom", - "Dynamic", - "Crop Milestone", - "Current Pet" - }) - public Property<Integer> secondLine = Property.of(0); + @ConfigEditorDropdown() + public Property<LineEntry> secondLine = Property.of(NOTHING); @Expose @ConfigOption(name = "Custom", desc = "What should be displayed if you select \"Custom\" above.") @@ -66,32 +46,89 @@ public class DiscordRPCConfig { @Expose @ConfigOption(name = "Dynamic Priority", desc = "Disable certain dynamic statuses, or change the priority in case two are triggered at the same time (higher up means higher priority).") - @ConfigEditorDraggableList( - exampleText = { - "Crop Milestones", - "Slayer", - "Stacking Enchantment", - "Dungeon", - "AFK Indicator" + @ConfigEditorDraggableList() + public List<PriorityEntry> autoPriority = new ArrayList<>(Arrays.asList( + CROP_MILESTONES, + SLAYER, + STACKING_ENCHANT, + DUNGEONS, + AFK + )); + + public enum PriorityEntry implements HasLegacyId { + CROP_MILESTONES("Crop Milestones", 0), + SLAYER("Slayer", 1), + STACKING_ENCHANT("Stacking Enchantment", 2), + DUNGEONS("Dungeon", 3), + AFK("AFK Indicator", 4), + ; + + private final String str; + private final int legacyId; + + PriorityEntry(String str, int legacyId) { + this.str = str; + this.legacyId = legacyId; + } + + // Constructor if new enum elements are added post-migration + PriorityEntry(String str) { + this(str, -1); + } + + @Override + public int getLegacyId() { + return legacyId; + } + + @Override + public String toString() { + return str; } - ) - public List<Integer> autoPriority = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4)); + } @Expose @ConfigOption(name = "Dynamic Fallback", desc = "What to show when none of your \"Dynamic Priority\" statuses are active.") - @ConfigEditorDropdown(values = { - "Nothing", - "Location", - "Purse", - "Bits", - "Stats", - "Held Item", - "SkyBlock Date", - "Profile", - "Slayer", - "Custom", - "Crop Milestone", - "Current Pet" - }) - public Property<Integer> auto = Property.of(0); + @ConfigEditorDropdown() + public Property<LineEntry> auto = Property.of(NOTHING); + + public enum LineEntry implements HasLegacyId { + NOTHING("Nothing", 0), + LOCATION("Location", 1), + PURSE("Purse", 2), + BITS("Bits", 3), + STATS("Stats", 4), + HELD_ITEM("Held Item", 5), + SKYBLOCK_DATE("SkyBlock Date", 6), + PROFILE("Profile", 7), + SLAYER("Slayer", 8), + CUSTOM("Custom", 9), + DYNAMIC("Dynamic", 10), + CROP_MILESTONE("Crop Milestone", 11), + CURRENT_PET("Current Pet", 12), + ; + + private final String str; + private final int legacyId; + + LineEntry(String str, int legacyId) { + this.str = str; + this.legacyId = legacyId; + } + + // Constructor if new enum elements are added post-migration + LineEntry(String str) { + this(str, -1); + } + + @Override + public int getLegacyId() { + return legacyId; + } + + @Override + public String toString() { + return str; + } + } } 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 1ac453a8d..c9465ea2d 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 @@ -88,6 +88,11 @@ public class MiscConfig { public KickDurationConfig kickDuration = new KickDurationConfig(); @Expose + @ConfigOption(name = "Tracker", desc = "Tracker Config") + @Accordion + public TrackerConfig tracker = new TrackerConfig(); + + @Expose @ConfigOption(name = "Exp Bottles", desc = "Hides all the experience orbs lying on the ground.") @ConfigEditorBoolean @FeatureToggle diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/TrackerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/TrackerConfig.java new file mode 100644 index 000000000..613adde60 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/TrackerConfig.java @@ -0,0 +1,36 @@ +package at.hannibal2.skyhanni.config.features.misc; + +import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker; +import com.google.gson.annotations.Expose; +import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; +import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown; +import io.github.moulberry.moulconfig.annotations.ConfigOption; +import io.github.moulberry.moulconfig.observer.Property; + +public class TrackerConfig { + + @Expose + @ConfigOption(name = "Hide with Item Value", desc = "Hide all trackers while the Estimated Item Value is visible.") + @ConfigEditorBoolean + public boolean hideInEstimatedItemValue = true; + + @Expose + @ConfigOption(name = "Show Price From", desc = "Show price from Bazaar or NPC.") + @ConfigEditorDropdown(values = {"Instant Sell", "Sell Offer", "NPC"}) + public int priceFrom = 1; + + @Expose + @ConfigOption(name = "Default Display Mode", desc = "Change the display mode that gets shown on default.") + @ConfigEditorDropdown + public Property<SkyHanniTracker.DefaultDisplayMode> defaultDisplayMode = Property.of(SkyHanniTracker.DefaultDisplayMode.REMEMBER_LAST); + + @Expose + @ConfigOption(name = "Recent Drops", desc = "Highlight the amount in green on recently gained items.") + @ConfigEditorBoolean + public boolean showRecentDrops = true; + + @Expose + @ConfigOption(name = "Exclude Hidden", desc = "Exclude hidden items in the total price calculation.") + @ConfigEditorBoolean + public boolean excludeHiddenItemsInPrice = false; +} diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/TrevorTheTrapperConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/TrevorTheTrapperConfig.java index 0c4226034..025125c4f 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/misc/TrevorTheTrapperConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/TrevorTheTrapperConfig.java @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.config.features.misc; import at.hannibal2.skyhanni.config.FeatureToggle; +import at.hannibal2.skyhanni.config.HasLegacyId; import at.hannibal2.skyhanni.config.core.config.Position; import com.google.gson.annotations.Expose; import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; @@ -13,6 +14,18 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.ELUSIVE; +import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.ENDANGERED; +import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.KILLED; +import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.PELTS_PER_HOUR; +import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.QUESTS_STARTED; +import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.SPACER_1; +import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.TITLE; +import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.TOTAL_PELTS; +import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.TRACKABLE; +import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.UNDETECTED; +import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.UNTRACKABLE; + public class TrevorTheTrapperConfig { @Expose @@ -39,23 +52,59 @@ public class TrevorTheTrapperConfig { name = "Text Format", desc = "Drag text to change the appearance of the overlay." ) - @ConfigEditorDraggableList( - exampleText = { - "§b§lTrevor Data Tracker", - "§b1,428 §9Quests Started", - "§b11,281 §5Total Pelts Gained", - "§b2,448 §5Pelts Per Hour", - "", - "§b850 §cKilled Animals", - "§b153 §cSelf Killing Animals", - "§b788 §fTrackable Animals", - "§b239 §aUntrackable Animals", - "§b115 §9Undetected Animals", - "§b73 §5Endangered Animals", - "§b12 §6Elusive Animals" + @ConfigEditorDraggableList() + public List<TrackerEntry> textFormat = new ArrayList<>(Arrays.asList( + TITLE, + QUESTS_STARTED, + TOTAL_PELTS, + PELTS_PER_HOUR, + SPACER_1, + KILLED, + TRACKABLE, + UNTRACKABLE, + UNDETECTED, + ENDANGERED, + ELUSIVE + )); + + public enum TrackerEntry implements HasLegacyId { + TITLE("§b§lTrevor Data Tracker", 0), + QUESTS_STARTED("§b1,428 §9Quests Started", 1), + TOTAL_PELTS("§b11,281 §5Total Pelts Gained", 2), + PELTS_PER_HOUR("§b2,448 §5Pelts Per Hour", 3), + SPACER_1("", 4), + KILLED("§b850 §cKilled Animals", 5), + SELF_KILLING("§b153 §cSelf Killing Animals", 6), + TRACKABLE("§b788 §fTrackable Animals", 7), + UNTRACKABLE("§b239 §aUntrackable Animals", 8), + UNDETECTED("§b115 §9Undetected Animals", 9), + ENDANGERED("§b73 §5Endangered Animals", 10), + ELUSIVE("§b12 §6Elusive Animals", 11), + ; + + private final String str; + private final int legacyId; + + TrackerEntry(String str, int legacyId) { + this.str = str; + this.legacyId = legacyId; } - ) - public List<Integer> textFormat = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11)); + + // Constructor if new enum elements are added post-migration + TrackerEntry(String str) { + this(str, -1); + } + + @Override + public int getLegacyId() { + return legacyId; + } + + @Override + public String toString() { + return str; + } + } @Expose public Position position = new Position(10, 80, false, true); diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/ItemProfitTrackerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/ItemProfitTrackerConfig.java index a7bc636db..5fc67993b 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/ItemProfitTrackerConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/ItemProfitTrackerConfig.java @@ -4,7 +4,6 @@ import at.hannibal2.skyhanni.config.FeatureToggle; import at.hannibal2.skyhanni.config.core.config.Position; import com.google.gson.annotations.Expose; import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; -import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown; import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider; import io.github.moulberry.moulconfig.annotations.ConfigOption; @@ -28,11 +27,6 @@ public class ItemProfitTrackerConfig { public boolean priceInChat = false; @Expose - @ConfigOption(name = "Show Price From", desc = "Show price from Bazaar or NPC.") - @ConfigEditorDropdown(values = {"Instant Sell", "Sell Offer", "NPC"}) - public int priceFrom = 1; - - @Expose @ConfigOption(name = "Minimum Price", desc = "Items below this price will not show up in chat.") @ConfigEditorSlider(minValue = 1, maxValue = 5_000_000, minStep = 1) public int minimumPrice = 100_000; diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/endermen/EndermanConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/endermen/EndermanConfig.java index 7b5ce353e..a31d9f82a 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/endermen/EndermanConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/endermen/EndermanConfig.java @@ -8,7 +8,7 @@ import io.github.moulberry.moulconfig.annotations.ConfigOption; public class EndermanConfig { @Expose - @ConfigOption(name = "Yang Glyph (beacon)", desc = "") + @ConfigOption(name = "Yang Glyph (Beacon)", desc = "") @Accordion public EndermanBeaconConfig beacon = new EndermanBeaconConfig(); @@ -19,7 +19,7 @@ public class EndermanConfig { public boolean highlightNukekebi = false; @Expose - @ConfigOption(name = "Phase Display", desc = "Show the current phase of the Enderman Slayer in damage indcator.") + @ConfigOption(name = "Phase Display", desc = "Show the current phase of the Enderman Slayer in damage indicator.") @ConfigEditorBoolean public boolean phaseDisplay = false; diff --git a/src/main/java/at/hannibal2/skyhanni/data/BingoAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/BingoAPI.kt deleted file mode 100644 index 5b32a1d15..000000000 --- a/src/main/java/at/hannibal2/skyhanni/data/BingoAPI.kt +++ /dev/null @@ -1,19 +0,0 @@ -package at.hannibal2.skyhanni.data - -import at.hannibal2.skyhanni.events.RepositoryReloadEvent -import at.hannibal2.skyhanni.utils.jsonobjects.BingoRanksJson -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -object BingoAPI { - private var ranks = mapOf<String, Int>() - - @SubscribeEvent - fun onRepoReload(event: RepositoryReloadEvent) { - ranks = event.getConstant<BingoRanksJson>("BingoRanks").ranks - } - - fun getRank(text: String) = ranks.entries.find { text.contains(it.key) }?.value - - fun getIcon(searchRank: Int) = ranks.entries.find { it.value == searchRank }?.key - -} diff --git a/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt b/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt index c7ddf1777..c426f9666 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt @@ -3,6 +3,7 @@ package at.hannibal2.skyhanni.data import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.LorenzActionBarEvent import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.MessageSendToServerEvent import at.hannibal2.skyhanni.events.PacketEvent import at.hannibal2.skyhanni.features.chat.ChatFilterGui import at.hannibal2.skyhanni.utils.IdentityCharacteristics @@ -13,6 +14,7 @@ import net.minecraft.client.Minecraft import net.minecraft.client.gui.ChatLine import net.minecraft.client.gui.GuiNewChat import net.minecraft.event.HoverEvent +import net.minecraft.network.play.client.C01PacketChatMessage import net.minecraft.network.play.server.S02PacketChat import net.minecraft.util.EnumChatFormatting import net.minecraft.util.IChatComponent @@ -63,15 +65,23 @@ object ChatManager { @SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true) fun onActionBarPacket(event: PacketEvent.ReceiveEvent) { - val packet = event.packet - if (packet !is S02PacketChat) return - val messageComponent = packet.chatComponent + val packet = event.packet as? S02PacketChat ?: return + val messageComponent = packet.chatComponent val message = LorenzUtils.stripVanillaMessage(messageComponent.formattedText) if (packet.type.toInt() == 2) { val actionBarEvent = LorenzActionBarEvent(message) actionBarEvent.postAndCatch() } + + } + + @SubscribeEvent + fun onSendMessageToServerPacket(event: PacketEvent.SendEvent) { + val packet = event.packet as? C01PacketChatMessage ?: return + + val message = packet.message + event.isCanceled = MessageSendToServerEvent(message).postAndCatch() } @SubscribeEvent(receiveCanceled = true) @@ -164,4 +174,4 @@ object ChatManager { history.actionKind = ActionKind.RETRACTED history.actionReason = reason.uppercase() } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/data/CropAccessoryData.kt b/src/main/java/at/hannibal2/skyhanni/data/CropAccessoryData.kt index 79202ffa2..ad5d01d3c 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/CropAccessoryData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/CropAccessoryData.kt @@ -10,6 +10,7 @@ import at.hannibal2.skyhanni.utils.InventoryUtils import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.NEUItems +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import com.google.gson.JsonElement import net.minecraft.item.ItemStack import net.minecraft.nbt.CompressedStreamTools @@ -20,7 +21,7 @@ import java.util.Base64 class CropAccessoryData { // TODO USE SH-REPO - private val accessoryBagNamePattern = "Accessory Bag \\((\\d)/(\\d)\\)".toRegex() + private val accessoryBagNamePattern = "Accessory Bag \\((?<current>\\d)/(?<total>\\d)\\)".toPattern() private var loadedAccessoryThisProfile = false private var ticks = 0 private var accessoryInBag: CropAccessory? = null @@ -48,10 +49,11 @@ class CropAccessoryData { return } - val groups = accessoryBagNamePattern.matchEntire(event.inventoryName)?.groups ?: return - isLoadingAccessories = true - accessoryBagPageCount = groups[2]!!.value.toInt() - accessoryBagPageNumber = groups[1]!!.value.toInt() + accessoryBagNamePattern.matchMatcher(event.inventoryName) { + isLoadingAccessories = true + accessoryBagPageNumber = group("current").toInt() + accessoryBagPageCount = group("total").toInt() + } ?: return } @SubscribeEvent diff --git a/src/main/java/at/hannibal2/skyhanni/data/EntityMovementData.kt b/src/main/java/at/hannibal2/skyhanni/data/EntityMovementData.kt index d67ae4a63..dec06dc8e 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/EntityMovementData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/EntityMovementData.kt @@ -6,6 +6,7 @@ import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzVec import at.hannibal2.skyhanni.utils.getLorenzVec +import net.minecraft.client.Minecraft import net.minecraft.entity.Entity import net.minecraftforge.fml.common.eventhandler.SubscribeEvent @@ -24,6 +25,7 @@ class EntityMovementData { @SubscribeEvent fun onTick(event: LorenzTickEvent) { if (!LorenzUtils.inSkyBlock) return + addToTrack(Minecraft.getMinecraft().thePlayer) for (entity in entityLocation.keys) { if (entity.isDead) continue @@ -42,4 +44,4 @@ class EntityMovementData { fun onWorldChange(event: LorenzWorldChangeEvent) { entityLocation.clear() } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/data/EventCounter.kt b/src/main/java/at/hannibal2/skyhanni/data/EventCounter.kt new file mode 100644 index 000000000..70de5e436 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/data/EventCounter.kt @@ -0,0 +1,46 @@ +package at.hannibal2.skyhanni.data + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.addOrPut +import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import kotlin.time.Duration.Companion.seconds + +object EventCounter { + private val config get() = SkyHanniMod.feature.dev.debug + + private var map = mutableMapOf<String, Int>() + private var lastUpdate = SimpleTimeMark.farPast() + + fun count(eventName: String) { + if (!isEnabled()) return + + map.addOrPut(eventName, 1) + + if (lastUpdate == SimpleTimeMark.farPast()) { + lastUpdate = SimpleTimeMark.now() + } + + if (lastUpdate.passedSince() > 1.seconds) { + lastUpdate = SimpleTimeMark.now() + + print(map) + + map.clear() + } + } + + private fun print(map: MutableMap<String, Int>) { + println("") + var total = 0 + for ((name, amount) in map.entries.sortedBy { it.value }) { + println("$name (${amount.addSeparators()} times)") + total += amount + } + println("") + println("total: ${total.addSeparators()}") + } + + private fun isEnabled() = LorenzUtils.onHypixel && config.eventCounter +} diff --git a/src/main/java/at/hannibal2/skyhanni/data/FriendAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/FriendAPI.kt index f6c9b4e56..834ccaa55 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/FriendAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/FriendAPI.kt @@ -2,14 +2,14 @@ package at.hannibal2.skyhanni.data import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigFileType +import at.hannibal2.skyhanni.data.jsonobjects.local.FriendsJson +import at.hannibal2.skyhanni.data.jsonobjects.local.FriendsJson.PlayerFriends.Friend import at.hannibal2.skyhanni.events.HypixelJoinEvent import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.StringUtils.cleanPlayerName import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher -import at.hannibal2.skyhanni.utils.jsonobjects.FriendsJson -import at.hannibal2.skyhanni.utils.jsonobjects.FriendsJson.PlayerFriends.Friend import net.minecraft.util.ChatStyle import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import java.util.UUID diff --git a/src/main/java/at/hannibal2/skyhanni/data/GardenComposterUpgradesData.kt b/src/main/java/at/hannibal2/skyhanni/data/GardenComposterUpgradesData.kt index 6b6d343aa..138158ccb 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/GardenComposterUpgradesData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/GardenComposterUpgradesData.kt @@ -5,7 +5,7 @@ import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.features.garden.composter.ComposterAPI import at.hannibal2.skyhanni.utils.ItemUtils.name -import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded +import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import net.minecraftforge.fml.common.eventhandler.SubscribeEvent @@ -19,7 +19,7 @@ class GardenComposterUpgradesData { val itemName = item.name ?: continue ComposterUpgrade.regex.matchMatcher(itemName) { val name = group("name") - val level = group("level")?.romanToDecimalIfNeeded() ?: 0 + val level = group("level")?.romanToDecimalIfNecessary() ?: 0 val composterUpgrade = ComposterUpgrade.getByName(name)!! ComposterAPI.composterUpgrades?.put(composterUpgrade, level) } diff --git a/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt b/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt index 610393906..34baceb0b 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt @@ -8,7 +8,7 @@ import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.utils.ItemUtils.getLore import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher -import at.hannibal2.skyhanni.utils.jsonobjects.GardenJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.GardenJson import net.minecraft.item.ItemStack import net.minecraftforge.fml.common.eventhandler.SubscribeEvent diff --git a/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestonesCommunityFix.kt b/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestonesCommunityFix.kt index f9990685d..71398af27 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestonesCommunityFix.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestonesCommunityFix.kt @@ -2,8 +2,10 @@ package at.hannibal2.skyhanni.data import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigManager +import at.hannibal2.skyhanni.data.jsonobjects.repo.GardenJson import at.hannibal2.skyhanni.events.RepositoryReloadEvent import at.hannibal2.skyhanni.features.garden.CropType +import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.utils.ItemUtils.getLore import at.hannibal2.skyhanni.utils.ItemUtils.name import at.hannibal2.skyhanni.utils.LorenzUtils @@ -11,12 +13,11 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy import at.hannibal2.skyhanni.utils.LorenzUtils.nextAfter import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber -import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded +import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary import at.hannibal2.skyhanni.utils.OSUtils import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.StringUtils.matches import at.hannibal2.skyhanni.utils.StringUtils.removeColor -import at.hannibal2.skyhanni.utils.jsonobjects.GardenJson import kotlinx.coroutines.launch import net.minecraft.item.ItemStack import net.minecraftforge.fml.common.eventhandler.SubscribeEvent @@ -42,7 +43,7 @@ object GardenCropMilestonesCommunityFix { fun openInventory(inventoryItems: Map<Int, ItemStack>) { if (!showWrongData) return - if (!SkyHanniMod.feature.garden.copyMilestoneData) return + if (!GardenAPI.config.copyMilestoneData) return fixForWrongData(inventoryItems) } @@ -74,7 +75,7 @@ object GardenCropMilestonesCommunityFix { ) { val name = stack.name ?: return val rawNumber = name.removeColor().replace(crop.cropName, "").trim() - val realTier = if (rawNumber == "") 0 else rawNumber.romanToDecimalIfNeeded() + val realTier = if (rawNumber == "") 0 else rawNumber.romanToDecimalIfNecessary() val lore = stack.getLore() val next = lore.nextAfter({ GardenCropMilestones.totalPattern.matches(it) }, 3) ?: return diff --git a/src/main/java/at/hannibal2/skyhanni/data/GuildAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/GuildAPI.kt index cb8288e52..5a4fb4f99 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/GuildAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/GuildAPI.kt @@ -38,4 +38,4 @@ object GuildAPI { fun isInGuild(name: String) = ProfileStorageData.playerSpecific?.guildMembers?.let { name in it } ?: false -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt b/src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt index aa78bec09..1b0b46352 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt @@ -7,6 +7,7 @@ import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.LorenzTickEvent import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent import at.hannibal2.skyhanni.events.ProfileJoinEvent +import at.hannibal2.skyhanni.features.bingo.BingoAPI import at.hannibal2.skyhanni.utils.LorenzLogger import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher diff --git a/src/main/java/at/hannibal2/skyhanni/data/IslandType.kt b/src/main/java/at/hannibal2/skyhanni/data/IslandType.kt index 3ab213025..7e1ac4159 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/IslandType.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/IslandType.kt @@ -1,6 +1,6 @@ package at.hannibal2.skyhanni.data -enum class IslandType(val displayName: String, val apiName: String = "null") { +enum class IslandType(val displayName: String, val modeName: String = "null") { // TODO USE SH-REPO (for displayName only) PRIVATE_ISLAND("Private Island"), PRIVATE_ISLAND_GUEST("Private Island Guest"), diff --git a/src/main/java/at/hannibal2/skyhanni/data/ItemAddManager.kt b/src/main/java/at/hannibal2/skyhanni/data/ItemAddManager.kt new file mode 100644 index 000000000..3d4b8f067 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/data/ItemAddManager.kt @@ -0,0 +1,90 @@ +package at.hannibal2.skyhanni.data + +import at.hannibal2.skyhanni.events.GuiContainerEvent +import at.hannibal2.skyhanni.events.InventoryOpenEvent +import at.hannibal2.skyhanni.events.ItemAddEvent +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.SackChangeEvent +import at.hannibal2.skyhanni.events.entity.ItemAddInInventoryEvent +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.NEUInternalName +import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import at.hannibal2.skyhanni.utils.StringUtils.matches +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.seconds + +class ItemAddManager { + enum class Source { + ITEM_ADD, + SACKS, + ; + } + + private val ARCHFIEND_DICE = "ARCHFIEND_DICE".asInternalName() + private val HIGH_CLASS_ARCHFIEND_DICE = "HIGH_CLASS_ARCHFIEND_DICE".asInternalName() + + private val diceRollChatPattern = + "§eYour §r§(5|6High Class )Archfiend Dice §r§erolled a §r§.(?<number>.)§r§e! Bonus: §r§.(?<hearts>.*)❤".toPattern() + + private var inSackInventory = false + private var lastSackInventoryLeave = SimpleTimeMark.farPast() + + @SubscribeEvent + fun onInventoryOpen(event: InventoryOpenEvent) { + if (event.inventoryName.contains("Sack")) { + inSackInventory = true + } + } + + @SubscribeEvent + fun onInventoryClose(event: GuiContainerEvent.CloseWindowEvent) { + if (inSackInventory) { + inSackInventory = false + lastSackInventoryLeave = SimpleTimeMark.now() + } + } + + @SubscribeEvent + fun onSackChange(event: SackChangeEvent) { + if (!LorenzUtils.inSkyBlock) return + + if (inSackInventory || lastSackInventoryLeave.passedSince() < 10.seconds) return + + for (sackChange in event.sackChanges) { + val change = sackChange.delta + if (change > 0) { + val internalName = sackChange.internalName + Source.SACKS.addItem(internalName, change) + } + } + } + + @SubscribeEvent + fun onItemAdd(event: ItemAddInInventoryEvent) { + if (!LorenzUtils.inSkyBlock) return + + val internalName = event.internalName + if (internalName == ARCHFIEND_DICE || internalName == HIGH_CLASS_ARCHFIEND_DICE) { + if (lastDiceRoll.passedSince() < 500.milliseconds) { + return + } + } + + Source.ITEM_ADD.addItem(internalName, event.amount) + } + + private fun Source.addItem(internalName: NEUInternalName, amount: Int) { + ItemAddEvent(internalName, amount, this).postAndCatch() + } + + private var lastDiceRoll = SimpleTimeMark.farPast() + + @SubscribeEvent + fun onChat(event: LorenzChatEvent) { + if (diceRollChatPattern.matches(event.message)) { + lastDiceRoll = SimpleTimeMark.now() + } + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/data/LocationFixData.kt b/src/main/java/at/hannibal2/skyhanni/data/LocationFixData.kt index 2bd6a9dcb..f32256031 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/LocationFixData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/LocationFixData.kt @@ -2,7 +2,7 @@ package at.hannibal2.skyhanni.data import at.hannibal2.skyhanni.events.RepositoryReloadEvent import at.hannibal2.skyhanni.utils.LocationUtils.isPlayerInside -import at.hannibal2.skyhanni.utils.jsonobjects.LocationFixJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.LocationFixJson import net.minecraft.util.AxisAlignedBB import net.minecraftforge.fml.common.eventhandler.EventPriority import net.minecraftforge.fml.common.eventhandler.SubscribeEvent diff --git a/src/main/java/at/hannibal2/skyhanni/data/MayorElection.kt b/src/main/java/at/hannibal2/skyhanni/data/MayorElection.kt index d4ad57e2d..53ffdae71 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/MayorElection.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/MayorElection.kt @@ -6,7 +6,7 @@ import at.hannibal2.skyhanni.events.LorenzTickEvent import at.hannibal2.skyhanni.utils.APIUtil import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.put -import at.hannibal2.skyhanni.utils.jsonobjects.MayorJson +import at.hannibal2.skyhanni.data.jsonobjects.local.MayorJson import io.github.moulberry.notenoughupdates.util.SkyBlockTime import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -73,4 +73,4 @@ class MayorElection { private fun MayorJson.Election.getPairs() = year + 1 to candidates.bestCandidate() private fun List<MayorJson.Candidate>.bestCandidate() = maxBy { it.votes } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/data/MinecraftData.kt b/src/main/java/at/hannibal2/skyhanni/data/MinecraftData.kt index bfcc8df5f..2ec0ea667 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/MinecraftData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/MinecraftData.kt @@ -6,6 +6,7 @@ import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent import at.hannibal2.skyhanni.events.PacketEvent import at.hannibal2.skyhanni.events.PlaySoundEvent import at.hannibal2.skyhanni.events.ReceiveParticleEvent +import at.hannibal2.skyhanni.utils.DelayedRun import at.hannibal2.skyhanni.utils.InventoryUtils import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName import at.hannibal2.skyhanni.utils.LorenzUtils @@ -75,11 +76,12 @@ object MinecraftData { @SubscribeEvent fun onTick(event: LorenzTickEvent) { + DelayedRun.checkRuns() if (!LorenzUtils.inSkyBlock) return val hand = InventoryUtils.getItemInHand() val newItem = hand?.getInternalName() ?: NEUInternalName.NONE - if (newItem != InventoryUtils.itemInHandId) { - ItemInHandChangeEvent(newItem, hand).postAndCatch() + val oldItem = InventoryUtils.itemInHandId + if (newItem != oldItem) { InventoryUtils.recentItemsInHand.keys.removeIf { it + 30_000 > System.currentTimeMillis() } if (newItem != NEUInternalName.NONE) { @@ -87,6 +89,7 @@ object MinecraftData { } InventoryUtils.itemInHandId = newItem InventoryUtils.latestItemInHand = hand + ItemInHandChangeEvent(newItem, oldItem).postAndCatch() } } diff --git a/src/main/java/at/hannibal2/skyhanni/data/OtherInventoryData.kt b/src/main/java/at/hannibal2/skyhanni/data/OtherInventoryData.kt index 5950d5fb8..921d591b2 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/OtherInventoryData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/OtherInventoryData.kt @@ -22,9 +22,9 @@ object OtherInventoryData { close() } - fun close() { + fun close(reopenSameName: Boolean = false) { currentInventory?.let { - InventoryCloseEvent(it).postAndCatch() + InventoryCloseEvent(it, reopenSameName).postAndCatch() currentInventory = null } } @@ -49,7 +49,8 @@ object OtherInventoryData { val windowId = packet.windowId val title = packet.windowTitle.unformattedText val slotCount = packet.slotCount - close() + val reopenSameName = title == currentInventory?.title + close(reopenSameName) currentInventory = Inventory(windowId, title, slotCount) acceptItems = true @@ -104,4 +105,4 @@ object OtherInventoryData { val slotCount: Int, val items: MutableMap<Int, ItemStack> = mutableMapOf(), ) -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/data/OtherMod.kt b/src/main/java/at/hannibal2/skyhanni/data/OtherMod.kt deleted file mode 100644 index 391d66975..000000000 --- a/src/main/java/at/hannibal2/skyhanni/data/OtherMod.kt +++ /dev/null @@ -1,42 +0,0 @@ -package at.hannibal2.skyhanni.data - -import at.hannibal2.skyhanni.config.ConfigManager -import com.google.gson.JsonObject -import java.io.BufferedReader - -enum class OtherMod(val modName: String, val configPath: String, val readKey: (BufferedReader) -> (String)) { - NEU("Not Enough Updates", "config/notenoughupdates/configNew.json", { reader -> - getJson(reader)["apiData"].asJsonObject["apiKey"].asString - }), - COW("Cowlection", "config/cowlection/do-not-share-me-with-other-players.cfg", { reader -> - val lines = reader.readText().split(System.lineSeparator()) - val line = lines.find { it.startsWith(" S:moo=") }!! - line.split("=")[1] - }), - DSM("Dankers SkyBlock Mod", "config/Danker's Skyblock Mod.cfg", { reader -> - val lines = reader.readText().split(System.lineSeparator()) - val line = lines.find { it.startsWith(" S:APIKey=") }!! - line.split("=")[1] - }), - DG("Dungeons Guide", "config/dungeonsguide/config.json", { reader -> - getJson(reader)["partykicker.apikey"].asJsonObject["apikey"].asString - }), - SKYTILS("Skytils", "config/skytils/config.toml", { reader -> - val lines = reader.readText().split(System.lineSeparator()) - val line = lines.find { it.startsWith(" hypixel_api_key = \"") }!! - line.split("\"")[1] - }), - HYPIXEL_API_KEY_MANAGER("Hypixel API Key Manager", "HypixelApiKeyManager/localdata.json", { reader -> - getJson(reader)["key"].asString - }), - SOOPY("Soopy Addons", "soopyAddonsData/apikey.txt", { reader -> - reader.readText() - }), - SBE("SkyBlock Extras", "config/SkyblockExtras.cfg", { reader -> - getJson(reader)["values"].asJsonObject["apiKey"].asString - }), -} - -fun getJson(reader: BufferedReader): JsonObject { - return ConfigManager.gson.fromJson(reader, com.google.gson.JsonObject::class.java) -}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/data/OwnInventoryData.kt b/src/main/java/at/hannibal2/skyhanni/data/OwnInventoryData.kt index 4c6058b26..a7b31159b 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/OwnInventoryData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/OwnInventoryData.kt @@ -1,30 +1,28 @@ package at.hannibal2.skyhanni.data -import at.hannibal2.skyhanni.events.InventoryCloseEvent +import at.hannibal2.skyhanni.events.GuiContainerEvent import at.hannibal2.skyhanni.events.LorenzTickEvent import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent import at.hannibal2.skyhanni.events.OwnInventoryItemUpdateEvent import at.hannibal2.skyhanni.events.PacketEvent import at.hannibal2.skyhanni.events.entity.ItemAddInInventoryEvent -import at.hannibal2.skyhanni.features.bazaar.BazaarApi +import at.hannibal2.skyhanni.utils.DelayedRun import at.hannibal2.skyhanni.utils.InventoryUtils import at.hannibal2.skyhanni.utils.ItemUtils.getInternalNameOrNull -import at.hannibal2.skyhanni.utils.ItemUtils.name import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy -import at.hannibal2.skyhanni.utils.NEUItems -import net.minecraft.item.ItemStack +import at.hannibal2.skyhanni.utils.LorenzUtils.addOrPut +import at.hannibal2.skyhanni.utils.NEUInternalName +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import net.minecraft.client.Minecraft import net.minecraft.network.play.server.S0DPacketCollectItem import net.minecraft.network.play.server.S2FPacketSetSlot import net.minecraftforge.fml.common.eventhandler.EventPriority import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -typealias SlotNumber = Int -typealias ItemName = String -typealias ItemData = Pair<ItemName, Int> +import kotlin.time.Duration +import kotlin.time.Duration.Companion.milliseconds class OwnInventoryData { - private var items = mapOf<SlotNumber, ItemData>() + private var itemAmounts = mapOf<NEUInternalName, Int>() private var dirty = false @SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true) @@ -39,7 +37,9 @@ class OwnInventoryData { val windowId = packet.func_149175_c() if (windowId == 0) { val item = packet.func_149174_e() ?: return - OwnInventoryItemUpdateEvent(item).postAndCatch() + DelayedRun.runNextTick { + OwnInventoryItemUpdateEvent(item).postAndCatch() + } } } } @@ -47,90 +47,72 @@ class OwnInventoryData { @SubscribeEvent fun onTick(event: LorenzTickEvent) { if (!LorenzUtils.inSkyBlock) return - if (items.isEmpty()) { - initInventory() + if (itemAmounts.isEmpty()) { + itemAmounts = getCurrentItems() } if (!dirty) return - dirty = false - for ((slot, itemStack) in InventoryUtils.getItemsInOwnInventoryWithNull().withIndex()) { - val old = items[slot] - val new = itemStack.itemToPair() - if (old != new) { - item(slot, new, itemStack) - } + + val map = getCurrentItems() + for ((internalName, amount) in map) { + calculateDifference(internalName, amount) } + itemAmounts = map } - private fun initInventory() { - items = items.editCopy { - for ((slot, itemStack) in InventoryUtils.getItemsInOwnInventoryWithNull().withIndex()) { - this[slot] = itemStack.itemToPair() - } + private fun getCurrentItems(): MutableMap<NEUInternalName, Int> { + val map = mutableMapOf<NEUInternalName, Int>() + for (itemStack in InventoryUtils.getItemsInOwnInventory()) { + val internalName = itemStack.getInternalNameOrNull() ?: continue + map.addOrPut(internalName, itemStack.stackSize) } + return map } @SubscribeEvent fun onWorldChange(event: LorenzWorldChangeEvent) { - items = emptyMap() + itemAmounts = emptyMap() } - private fun ItemStack?.itemToPair(): ItemData = this?.let { (name ?: "null") to stackSize } ?: Pair("null", 0) + private fun calculateDifference(internalName: NEUInternalName, newAmount: Int) { + val oldAmount = itemAmounts[internalName] ?: 0 - private fun item(slot: SlotNumber, new: ItemData, itemStack: ItemStack?) { - val (oldItem, oldAmount) = items[slot] ?: Pair("null", 0) - val (name, amount) = new - - if (name == oldItem) { - val diff = amount - oldAmount - if (amount > oldAmount) { - add(itemStack, diff) - } - } else { - if (name != "null") { - add(itemStack!!, amount) - } - } - items = items.editCopy { - this[slot] = new + val diff = newAmount - oldAmount + if (diff > 0) { + addItem(internalName, diff) } } @SubscribeEvent - fun onInventoryClose(event: InventoryCloseEvent) { - BazaarApi.inBazaarInventory = false - lastClose = System.currentTimeMillis() + fun onInventoryClose(event: GuiContainerEvent.CloseWindowEvent) { + val item = Minecraft.getMinecraft().thePlayer.inventory.itemStack ?: return + val internalNameOrNull = item.getInternalNameOrNull() ?: return + ignoreItem(500.milliseconds) { it == internalNameOrNull } + } + + @SubscribeEvent + fun onSlotClick(event: GuiContainerEvent.SlotClickEvent) { + ignoreItem(500.milliseconds) { true } } - private var lastClose = 0L + private fun ignoreItem(duration: Duration, condition: (NEUInternalName) -> Boolean) { + ignoredItemsUntil.add(IgnoredItem(condition, SimpleTimeMark.now() + duration)) + } - private fun add(item_: ItemStack?, add: Int) { - val item = item_ ?: return - val diffClose = System.currentTimeMillis() - lastClose - if (diffClose < 500) return + private val ignoredItemsUntil = mutableListOf<IgnoredItem>() + class IgnoredItem(val condition: (NEUInternalName) -> Boolean, val blockedUntil: SimpleTimeMark) + + private fun addItem(internalName: NEUInternalName, add: Int) { val diffWorld = System.currentTimeMillis() - LorenzUtils.lastWorldSwitch if (diffWorld < 3_000) return - val internalName = item.getInternalNameOrNull() - - item.name?.let { - if (it == "§8Quiver Arrow") { - return - } - } + ignoredItemsUntil.removeIf { it.blockedUntil.isInPast() } + if (ignoredItemsUntil.any { it.condition(internalName) }) return - if (internalName == null) { - LorenzUtils.debug("OwnInventoryData add is empty for: '${item.name}'") - return - } if (internalName.startsWith("MAP-")) return - val (_, amount) = NEUItems.getMultiplier(internalName) - if (amount > 1) return - ItemAddInInventoryEvent(internalName, add).postAndCatch() } - } diff --git a/src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt index 7079ae6fd..3694bf672 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt @@ -6,12 +6,10 @@ import at.hannibal2.skyhanni.events.InventoryCloseEvent import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.SackChangeEvent -import at.hannibal2.skyhanni.features.fishing.trophy.TrophyFishManager -import at.hannibal2.skyhanni.features.fishing.trophy.TrophyFishManager.getFilletValue +import at.hannibal2.skyhanni.features.fishing.FishingAPI import at.hannibal2.skyhanni.features.fishing.trophy.TrophyRarity import at.hannibal2.skyhanni.features.inventory.SackDisplay import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName -import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName_old import at.hannibal2.skyhanni.utils.ItemUtils.getLore import at.hannibal2.skyhanni.utils.ItemUtils.name import at.hannibal2.skyhanni.utils.LorenzUtils @@ -161,13 +159,8 @@ object SackAPI { if (savingSacks) setSackItem(item.internalName, item.stored.formatNumber()) item.price = if (isTrophySack) { - val internal = stack.getInternalName_old() - val trophyFishName = internal.substringBeforeLast("_") - .replace("_", "").lowercase() - val trophyRarityName = internal.substringAfterLast("_") - val info = TrophyFishManager.getInfo(trophyFishName) - val rarity = TrophyRarity.getByName(trophyRarityName) ?: TrophyRarity.BRONZE - val filletValue = (info?.getFilletValue(rarity) ?: 0) * stored.formatNumber() + val filletPerTrophy = FishingAPI.getFilletPerTrophy(stack.getInternalName()) + val filletValue = filletPerTrophy * stored.formatNumber() item.magmaFish = filletValue "MAGMA_FISH".asInternalName().sackPrice(filletValue.toString()) } else { diff --git a/src/main/java/at/hannibal2/skyhanni/data/SkillExperience.kt b/src/main/java/at/hannibal2/skyhanni/data/SkillExperience.kt index 78c25e799..d2726c3aa 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/SkillExperience.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/SkillExperience.kt @@ -3,6 +3,7 @@ package at.hannibal2.skyhanni.data import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent import at.hannibal2.skyhanni.events.LorenzActionBarEvent import at.hannibal2.skyhanni.events.ProfileJoinEvent +import at.hannibal2.skyhanni.events.SkillExpGainEvent import at.hannibal2.skyhanni.utils.ItemUtils.getLore import at.hannibal2.skyhanni.utils.ItemUtils.name import at.hannibal2.skyhanni.utils.LorenzUtils @@ -16,6 +17,7 @@ class SkillExperience { // TODO USE SH-REPO private val actionBarPattern = ".*§3\\+.* (?<skill>.*) \\((?<overflow>.*)/(?<needed>.*)\\).*".toPattern() private val inventoryPattern = ".* §e(?<number>.*)§6/.*".toPattern() + private val actionBarLowLevelPattern = ".*§3+(?<add>.+) (?<skill>.*) \\((?<percentage>.*)%\\).*".toPattern() @SubscribeEvent fun onProfileJoin(event: ProfileJoinEvent) { @@ -32,7 +34,13 @@ class SkillExperience { val neededForNextLevel = group("needed").formatNumber() val nextLevel = getLevelForExpExactly(neededForNextLevel) val baseExp = getExpForLevel(nextLevel - 1) - skillExp[skill] = baseExp + overflow + val totalExp = baseExp + overflow + skillExp[skill] = totalExp + SkillExpGainEvent(skill).postAndCatch() + } + actionBarLowLevelPattern.matchMatcher(event.message) { + val skill = group("skill").lowercase() + SkillExpGainEvent(skill).postAndCatch() } } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/FriendsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/FriendsJson.java index 82482b6a6..d95cea3bd 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/FriendsJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/FriendsJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.local; import com.google.gson.annotations.Expose; diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/JacobContestsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/JacobContestsJson.java index 87d1e9a22..96b21ae6a 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/JacobContestsJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/JacobContestsJson.java @@ -1,6 +1,7 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.local; import at.hannibal2.skyhanni.features.garden.CropType; +import at.hannibal2.skyhanni.utils.SimpleTimeMark; import com.google.gson.annotations.Expose; import java.util.HashMap; @@ -9,5 +10,5 @@ import java.util.Map; public class JacobContestsJson { @Expose - public Map<Long, List<CropType>> contestTimes = new HashMap<>(); + public Map<SimpleTimeMark, List<CropType>> contestTimes = new HashMap<>(); } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/KnownFeaturesJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/KnownFeaturesJson.java index bd5048cfb..e72400c9e 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/KnownFeaturesJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/KnownFeaturesJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.local; import com.google.gson.annotations.Expose; diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/MayorJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/MayorJson.java index d2173c74b..6525e59d3 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/MayorJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/MayorJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.local; import com.google.gson.annotations.Expose; diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/AnitaUpgradeCostsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/AnitaUpgradeCostsJson.java index 09a2de7db..a1122eec3 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/AnitaUpgradeCostsJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/AnitaUpgradeCostsJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import com.google.gson.annotations.Expose; @@ -15,4 +15,4 @@ public class AnitaUpgradeCostsJson { @Expose public Integer jacob_tickets; } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ArmorDropsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ArmorDropsJson.java index 698bad3db..c8038c49f 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ArmorDropsJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ArmorDropsJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import com.google.gson.annotations.Expose; @@ -16,4 +16,4 @@ public class ArmorDropsJson { @Expose public List<Double> chance; } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/BingoJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/BingoJson.java index 810f6d3ab..babe7cc9e 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/BingoJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/BingoJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import com.google.gson.annotations.Expose; @@ -15,5 +15,7 @@ public class BingoJson { @Expose public List<String> note; + @Expose + public String found; } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/BingoRanksJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/BingoRanksJson.java index 49d7e662f..98f2a4695 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/BingoRanksJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/BingoRanksJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import com.google.gson.annotations.Expose; @@ -7,4 +7,4 @@ import java.util.Map; public class BingoRanksJson { @Expose public Map<String, Integer> ranks; -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ContributorListJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ContributorListJson.java index 8e5648f5e..dc2b4a5ac 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ContributorListJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ContributorListJson.java @@ -1,5 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; - +package at.hannibal2.skyhanni.data.jsonobjects.repo; import com.google.gson.annotations.Expose; import java.util.List; diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/CrimsonIsleReputationJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/CrimsonIsleReputationJson.java index 9235680fb..f349aef9a 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/CrimsonIsleReputationJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/CrimsonIsleReputationJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import com.google.gson.annotations.Expose; diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/DanceRoomInstructionsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/DanceRoomInstructionsJson.java index 9316d8671..e7c167e53 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/DanceRoomInstructionsJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/DanceRoomInstructionsJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import com.google.gson.annotations.Expose; @@ -7,4 +7,4 @@ import java.util.List; public class DanceRoomInstructionsJson { @Expose public List<String> instructions; -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/DicerDropsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/DicerDropsJson.java index 996a558ea..00a662768 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/DicerDropsJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/DicerDropsJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; @@ -28,4 +28,4 @@ public class DicerDropsJson { @Expose public List<Integer> amount; } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/DisabledFeaturesJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/DisabledFeaturesJson.java index 45abedfa3..1099cf782 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/DisabledFeaturesJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/DisabledFeaturesJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import com.google.gson.annotations.Expose; @@ -7,4 +7,4 @@ import java.util.Map; public class DisabledFeaturesJson { @Expose public Map<String, Boolean> features; -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/EnigmaSoulsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/EnigmaSoulsJson.java index 5769520f5..cd17d1744 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/EnigmaSoulsJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/EnigmaSoulsJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import at.hannibal2.skyhanni.utils.LorenzVec; import com.google.gson.annotations.Expose; @@ -17,4 +17,4 @@ public class EnigmaSoulsJson { @Expose public LorenzVec position; } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/FishingProfitItemsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/FishingProfitItemsJson.java new file mode 100644 index 000000000..47f7fc0bb --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/FishingProfitItemsJson.java @@ -0,0 +1,12 @@ +package at.hannibal2.skyhanni.data.jsonobjects.repo; + +import at.hannibal2.skyhanni.utils.NEUInternalName; +import com.google.gson.annotations.Expose; + +import java.util.List; +import java.util.Map; + +public class FishingProfitItemsJson { + @Expose + public Map<String, List<NEUInternalName>> categories; +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/GardenJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/GardenJson.java index 7bc9cf7fa..acb8e08ba 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/GardenJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/GardenJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import at.hannibal2.skyhanni.features.garden.CropType; import at.hannibal2.skyhanni.utils.LorenzRarity; diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/HideNotClickableItemsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/HideNotClickableItemsJson.java index d4ac9c52b..8877e596e 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/HideNotClickableItemsJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/HideNotClickableItemsJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import com.google.gson.annotations.Expose; @@ -27,4 +27,4 @@ public class HideNotClickableItemsJson { @Expose public List<String> items; } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ItemsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ItemsJson.java index f37671913..c6bfc90f3 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ItemsJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ItemsJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import com.google.gson.annotations.Expose; @@ -11,4 +11,4 @@ public class ItemsJson { @Expose public Map<String, Integer> crimson_tiers; -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/LocationFixJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/LocationFixJson.java index 802627e7a..0df76b4a9 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/LocationFixJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/LocationFixJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import at.hannibal2.skyhanni.utils.LorenzVec; import com.google.gson.annotations.Expose; diff --git a/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/MinionXPJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/MinionXPJson.java new file mode 100644 index 000000000..44f66b8b8 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/MinionXPJson.java @@ -0,0 +1,10 @@ +package at.hannibal2.skyhanni.data.jsonobjects.repo; + +import com.google.gson.annotations.Expose; + +import java.util.Map; + +public class MinionXPJson { + @Expose + public Map<String, Map<String, Double>> minion_xp; +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ModGuiSwitcherJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ModGuiSwitcherJson.java index 078b1f6ad..cf0b0656d 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ModGuiSwitcherJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ModGuiSwitcherJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import com.google.gson.annotations.Expose; @@ -22,4 +22,4 @@ public class ModGuiSwitcherJson { @Expose public List<String> guiPath = new ArrayList<>(); } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/MultiFilterJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/MultiFilterJson.java index 8704f91fb..0d0c0d6e1 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/MultiFilterJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/MultiFilterJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import com.google.gson.annotations.Expose; @@ -22,4 +22,4 @@ public class MultiFilterJson { @Expose public String description; -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ParkourJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ParkourJson.java index 5ae2d40ca..0dd511430 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ParkourJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ParkourJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import at.hannibal2.skyhanni.utils.LorenzVec; import com.google.gson.annotations.Expose; @@ -20,4 +20,4 @@ public class ParkourJson { @Expose public int to; } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/PlayerChatFilterJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/PlayerChatFilterJson.java index a65a2f8a1..708ac24e0 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/PlayerChatFilterJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/PlayerChatFilterJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import com.google.gson.annotations.Expose; @@ -7,4 +7,4 @@ import java.util.List; public class PlayerChatFilterJson { @Expose public List<MultiFilterJson> filters; -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/RiftEffigiesJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/RiftEffigiesJson.java index d914ef934..ad94c374d 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/RiftEffigiesJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/RiftEffigiesJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import at.hannibal2.skyhanni.utils.LorenzVec; import com.google.gson.annotations.Expose; @@ -8,4 +8,4 @@ import java.util.List; public class RiftEffigiesJson { @Expose public List<LorenzVec> locations; -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SacksJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/SacksJson.java index dfd2103ef..8a2765210 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SacksJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/SacksJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import com.google.gson.annotations.Expose; @@ -7,4 +7,4 @@ import java.util.List; public class SacksJson { @Expose public List<String> sackList; -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SeaCreatureJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/SeaCreatureJson.java index 8053e87cb..3f8449fb6 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SeaCreatureJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/SeaCreatureJson.java @@ -1,33 +1,33 @@ -package at.hannibal2.skyhanni.utils.jsonobjects;
-
-import at.hannibal2.skyhanni.utils.LorenzRarity;
-import com.google.gson.annotations.Expose;
-import com.google.gson.reflect.TypeToken;
-
-import java.lang.reflect.Type;
-import java.util.Map;
-
-public class SeaCreatureJson {
-
- public static Type TYPE = new TypeToken<Map<String, SeaCreatureJson.Variant>>() {
- }.getType();
-
- public static class Variant {
- @Expose
- public String chat_color;
- @Expose
- public Map<String, SeaCreature> sea_creatures;
- }
-
- public static class SeaCreature {
- @Expose
- public String chat_message;
- @Expose
- public int fishing_experience;
- @Expose
- public Boolean rare;
- @Expose
- public LorenzRarity rarity;
- }
-
-}
+package at.hannibal2.skyhanni.data.jsonobjects.repo; + +import at.hannibal2.skyhanni.utils.LorenzRarity; +import com.google.gson.annotations.Expose; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.Type; +import java.util.Map; + +public class SeaCreatureJson { + + public static Type TYPE = new TypeToken<Map<String, SeaCreatureJson.Variant>>() { + }.getType(); + + public static class Variant { + @Expose + public String chat_color; + @Expose + public Map<String, SeaCreature> sea_creatures; + } + + public static class SeaCreature { + @Expose + public String chat_message; + @Expose + public int fishing_experience; + @Expose + public Boolean rare; + @Expose + public LorenzRarity rarity; + } + +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SlayerProfitTrackerItemsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/SlayerProfitTrackerItemsJson.java index 377582200..f9c91bdfc 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SlayerProfitTrackerItemsJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/SlayerProfitTrackerItemsJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import at.hannibal2.skyhanni.utils.NEUInternalName; import com.google.gson.annotations.Expose; @@ -9,4 +9,4 @@ import java.util.Map; public class SlayerProfitTrackerItemsJson { @Expose public Map<String, List<NEUInternalName>> slayers; -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/TabListJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/TabListJson.java index 03c256256..2c475679e 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/TabListJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/TabListJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import com.google.gson.annotations.Expose; diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/TrophyFishJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/TrophyFishJson.java index 6303c16be..c15adf1b8 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/TrophyFishJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/TrophyFishJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import at.hannibal2.skyhanni.features.fishing.trophy.TrophyRarity; import com.google.gson.annotations.Expose; @@ -22,4 +22,4 @@ public class TrophyFishJson { @Expose public Map<TrophyRarity, Integer> fillet; } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/VipVisitsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/VipVisitsJson.java index c80f4953f..d2a4a0562 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/VipVisitsJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/VipVisitsJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import com.google.gson.annotations.Expose; @@ -7,4 +7,4 @@ import java.util.List; public class VipVisitsJson { @Expose public List<String> vipVisits; -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/WarpsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/WarpsJson.java index e09bf3c9d..ef81b052a 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/WarpsJson.java +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/WarpsJson.java @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.utils.jsonobjects; +package at.hannibal2.skyhanni.data.jsonobjects.repo; import com.google.gson.annotations.Expose; @@ -7,4 +7,4 @@ import java.util.List; public class WarpsJson { @Expose public List<String> warpCommands; -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/events/DamageIndicatorDeathEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/DamageIndicatorDeathEvent.kt new file mode 100644 index 000000000..141f293a3 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/events/DamageIndicatorDeathEvent.kt @@ -0,0 +1,6 @@ +package at.hannibal2.skyhanni.events + +import at.hannibal2.skyhanni.features.combat.damageindicator.EntityData +import net.minecraft.entity.EntityLivingBase + +class DamageIndicatorDeathEvent(val entity: EntityLivingBase, val data: EntityData) : LorenzEvent() diff --git a/src/main/java/at/hannibal2/skyhanni/events/DataWatcherUpdatedEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/DataWatcherUpdatedEvent.kt new file mode 100644 index 000000000..05389c2d7 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/events/DataWatcherUpdatedEvent.kt @@ -0,0 +1,9 @@ +package at.hannibal2.skyhanni.events + +import net.minecraft.entity.DataWatcher +import net.minecraft.entity.Entity + +data class DataWatcherUpdatedEvent( + val entity: Entity, + val updatedEntries: List<DataWatcher.WatchableObject>, +) : LorenzEvent() diff --git a/src/main/java/at/hannibal2/skyhanni/events/EntityCustomNameUpdateEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/EntityCustomNameUpdateEvent.kt new file mode 100644 index 000000000..4b4b075e3 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/events/EntityCustomNameUpdateEvent.kt @@ -0,0 +1,8 @@ +package at.hannibal2.skyhanni.events + +import net.minecraft.entity.Entity + +data class EntityCustomNameUpdateEvent( + val newName: String?, + val entity: Entity, +) : LorenzEvent() diff --git a/src/main/java/at/hannibal2/skyhanni/events/InventoryCloseEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/InventoryCloseEvent.kt index bf43a57f9..72630756a 100644 --- a/src/main/java/at/hannibal2/skyhanni/events/InventoryCloseEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/events/InventoryCloseEvent.kt @@ -3,9 +3,9 @@ package at.hannibal2.skyhanni.events import at.hannibal2.skyhanni.data.OtherInventoryData import net.minecraft.item.ItemStack -class InventoryCloseEvent(val inventory: OtherInventoryData.Inventory) : LorenzEvent() { +class InventoryCloseEvent(val inventory: OtherInventoryData.Inventory, val reopenSameName: Boolean) : LorenzEvent() { val inventoryId: Int by lazy { inventory.windowId } val inventoryName: String by lazy { inventory.title } val inventorySize: Int by lazy { inventory.slotCount } val inventoryItems: Map<Int, ItemStack> by lazy { inventory.items } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/events/ItemAddEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/ItemAddEvent.kt new file mode 100644 index 000000000..ad0c6355d --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/events/ItemAddEvent.kt @@ -0,0 +1,7 @@ +package at.hannibal2.skyhanni.events + +import at.hannibal2.skyhanni.data.ItemAddManager +import at.hannibal2.skyhanni.utils.NEUInternalName + +class ItemAddEvent(val internalName: NEUInternalName, val amount: Int, val source: ItemAddManager.Source) : + LorenzEvent() diff --git a/src/main/java/at/hannibal2/skyhanni/events/ItemInHandChangeEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/ItemInHandChangeEvent.kt index 3f5b94b3c..4ef39df43 100644 --- a/src/main/java/at/hannibal2/skyhanni/events/ItemInHandChangeEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/events/ItemInHandChangeEvent.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.events import at.hannibal2.skyhanni.utils.NEUInternalName -import net.minecraft.item.ItemStack -class ItemInHandChangeEvent(val internalName: NEUInternalName, val stack: ItemStack?) : LorenzEvent()
\ No newline at end of file +class ItemInHandChangeEvent(val newItem: NEUInternalName, val oldItem: NEUInternalName) : LorenzEvent() diff --git a/src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt index 21f9d07e8..766da4c14 100644 --- a/src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt @@ -1,5 +1,6 @@ package at.hannibal2.skyhanni.events +import at.hannibal2.skyhanni.data.EventCounter import at.hannibal2.skyhanni.mixins.transformers.AccessorEventBus import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.LorenzUtils @@ -10,7 +11,7 @@ import net.minecraftforge.fml.common.eventhandler.IEventListener abstract class LorenzEvent : Event() { private val eventName by lazy { - this::class.simpleName + this::class.simpleName!! } fun postAndCatch() = postAndCatchAndBlock {} @@ -21,6 +22,7 @@ abstract class LorenzEvent : Event() { ignoreErrorCache: Boolean = false, onError: (Throwable) -> Unit, ): Boolean { + EventCounter.count(eventName) val visibleErrors = 3 var errors = 0 for (listener in getListeners()) { diff --git a/src/main/java/at/hannibal2/skyhanni/events/MessageSendToServerEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/MessageSendToServerEvent.kt new file mode 100644 index 000000000..b6dff658e --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/events/MessageSendToServerEvent.kt @@ -0,0 +1,6 @@ +package at.hannibal2.skyhanni.events + +import net.minecraftforge.fml.common.eventhandler.Cancelable + +@Cancelable +class MessageSendToServerEvent(val message: String) : LorenzEvent() diff --git a/src/main/java/at/hannibal2/skyhanni/events/MinionOpenEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/MinionOpenEvent.kt index 5d577b6ee..bfe8649ba 100644 --- a/src/main/java/at/hannibal2/skyhanni/events/MinionOpenEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/events/MinionOpenEvent.kt @@ -1,5 +1,8 @@ package at.hannibal2.skyhanni.events +import at.hannibal2.skyhanni.utils.LorenzVec import net.minecraft.item.ItemStack -class MinionOpenEvent(val inventoryName: String, val inventoryItems: Map<Int, ItemStack>) : LorenzEvent()
\ No newline at end of file +class MinionOpenEvent(val inventoryName: String, val inventoryItems: Map<Int, ItemStack>) : LorenzEvent() +class MinionCloseEvent : LorenzEvent() +class MinionStorageOpenEvent(val position: LorenzVec?, val inventoryItems: Map<Int, ItemStack>) : LorenzEvent() diff --git a/src/main/java/at/hannibal2/skyhanni/events/OwnInventoryItemUpdateEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/OwnInventoryItemUpdateEvent.kt index a7a5ba491..32e19e751 100644 --- a/src/main/java/at/hannibal2/skyhanni/events/OwnInventoryItemUpdateEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/events/OwnInventoryItemUpdateEvent.kt @@ -2,7 +2,4 @@ package at.hannibal2.skyhanni.events import net.minecraft.item.ItemStack -/** - * Note: This event is async and may not be executed on the main minecraft thread. - */ -data class OwnInventoryItemUpdateEvent(val itemStack: ItemStack) : LorenzEvent()
\ No newline at end of file +data class OwnInventoryItemUpdateEvent(val itemStack: ItemStack) : LorenzEvent() diff --git a/src/main/java/at/hannibal2/skyhanni/events/SkillExpGainEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/SkillExpGainEvent.kt new file mode 100644 index 000000000..c6c7be5cc --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/events/SkillExpGainEvent.kt @@ -0,0 +1,4 @@ +package at.hannibal2.skyhanni.events + +// does not know how much exp is there, also gets called multiple times +class SkillExpGainEvent(val skill: String) : LorenzEvent() diff --git a/src/main/java/at/hannibal2/skyhanni/events/bingo/BingoCardUpdateEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/bingo/BingoCardUpdateEvent.kt new file mode 100644 index 000000000..f7406498b --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/events/bingo/BingoCardUpdateEvent.kt @@ -0,0 +1,5 @@ +package at.hannibal2.skyhanni.events.bingo + +import at.hannibal2.skyhanni.events.LorenzEvent + +class BingoCardUpdateEvent : LorenzEvent() diff --git a/src/main/java/at/hannibal2/skyhanni/events/bingo/BingoGoalReachedEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/bingo/BingoGoalReachedEvent.kt new file mode 100644 index 000000000..b091c24f3 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/events/bingo/BingoGoalReachedEvent.kt @@ -0,0 +1,6 @@ +package at.hannibal2.skyhanni.events.bingo + +import at.hannibal2.skyhanni.events.LorenzEvent +import at.hannibal2.skyhanni.features.bingo.card.goals.BingoGoal + +class BingoGoalReachedEvent(val goal: BingoGoal) : LorenzEvent() diff --git a/src/main/java/at/hannibal2/skyhanni/events/garden/pests/PestSpawnEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/garden/pests/PestSpawnEvent.kt new file mode 100644 index 000000000..20b80ff4a --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/events/garden/pests/PestSpawnEvent.kt @@ -0,0 +1,5 @@ +package at.hannibal2.skyhanni.events.garden.pests + +import at.hannibal2.skyhanni.events.LorenzEvent + +class PestSpawnEvent(val amountPests: Int, val plotName: String) : LorenzEvent() diff --git a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarApi.kt b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarApi.kt index 57e674976..0f14c98c3 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarApi.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarApi.kt @@ -16,6 +16,7 @@ import at.hannibal2.skyhanni.utils.NEUInternalName import at.hannibal2.skyhanni.utils.NEUItems import at.hannibal2.skyhanni.utils.OSUtils import at.hannibal2.skyhanni.utils.RenderUtils.highlight +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.StringUtils.removeColor import net.minecraft.client.gui.inventory.GuiChest import net.minecraft.inventory.ContainerChest @@ -109,11 +110,12 @@ class BazaarApi { @SubscribeEvent fun onChat(event: LorenzChatEvent) { - if ("\\[Bazaar] (Buy Order Setup!|Bought).*$currentSearchedItem.*".toRegex() - .matches(event.message.removeColor()) - ) { - currentSearchedItem = "" - } + if (!LorenzUtils.inSkyBlock) return + if (!inBazaarInventory) return + // TODO USE SH-REPO + // TODO remove dynamic pattern + "\\[Bazaar] (Buy Order Setup!|Bought).*$currentSearchedItem.*".toPattern() + .matchMatcher(event.message.removeColor()) { currentSearchedItem = "" } } private fun checkIfInBazaar(event: InventoryFullyOpenedEvent): Boolean { @@ -146,4 +148,4 @@ class BazaarApi { inBazaarInventory = false currentlyOpenedProduct = null } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoAPI.kt new file mode 100644 index 000000000..cc5dec6ff --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoAPI.kt @@ -0,0 +1,40 @@ +package at.hannibal2.skyhanni.features.bingo + +import at.hannibal2.skyhanni.data.jsonobjects.repo.BingoJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.BingoRanksJson +import at.hannibal2.skyhanni.events.RepositoryReloadEvent +import at.hannibal2.skyhanni.features.bingo.card.goals.BingoGoal +import at.hannibal2.skyhanni.features.bingo.card.goals.GoalType +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +object BingoAPI { + private var ranks = mapOf<String, Int>() + var tips: Map<String, BingoJson.BingoTip> = emptyMap() + // TODO save into storage + val bingoGoals = mutableListOf<BingoGoal>() + val personalGoals get() = bingoGoals.filter { it.type == GoalType.PERSONAL } + val communityGoals get() = bingoGoals.filter { it.type == GoalType.COMMUNITY } + var lastBingoCardOpenTime = SimpleTimeMark.farPast() + + @SubscribeEvent + fun onRepoReload(event: RepositoryReloadEvent) { + ranks = event.getConstant<BingoRanksJson>("BingoRanks").ranks + tips = event.getConstant<BingoJson>("Bingo").bingo_tips + } + + fun getRank(text: String) = ranks.entries.find { text.contains(it.key) }?.value + + fun getIcon(searchRank: Int) = ranks.entries.find { it.value == searchRank }?.key + + // We added the suffix (Community Goal) so that older skyhanni versions don't crash with the new repo data. + fun getTip(itemName: String) = + tips.filter { itemName.startsWith(it.key.split(" (Community Goal)")[0]) }.values.firstOrNull() + + fun BingoGoal.getTip(): BingoJson.BingoTip? = if (type == at.hannibal2.skyhanni.features.bingo.card.goals.GoalType.COMMUNITY) { + getTip(displayName) + } else { + tips[displayName] + } + +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardDisplay.kt deleted file mode 100644 index ee1fc5874..000000000 --- a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardDisplay.kt +++ /dev/null @@ -1,193 +0,0 @@ -package at.hannibal2.skyhanni.features.bingo - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator -import at.hannibal2.skyhanni.events.ConfigLoadEvent -import at.hannibal2.skyhanni.events.GuiRenderEvent -import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.features.bingo.card.CommunityGoal -import at.hannibal2.skyhanni.features.bingo.card.PersonalGoal -import at.hannibal2.skyhanni.utils.InventoryUtils -import at.hannibal2.skyhanni.utils.ItemUtils -import at.hannibal2.skyhanni.utils.ItemUtils.getLore -import at.hannibal2.skyhanni.utils.ItemUtils.name -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzUtils.onToggle -import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings -import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher -import at.hannibal2.skyhanni.utils.StringUtils.removeColor -import net.minecraft.client.Minecraft -import net.minecraft.client.gui.GuiChat -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class BingoCardDisplay { - - private var display = emptyList<String>() - - // TODO USE SH-REPO - private val goalCompletePattern = "§6§lBINGO GOAL COMPLETE! §r§e(?<name>.*)".toPattern() - - init { - update() - } - - companion object { - private const val MAX_PERSONAL_GOALS = 20 - private const val MAX_COMMUNITY_GOALS = 5 - - private val config get() = SkyHanniMod.feature.event.bingo.bingoCard - private var displayMode = 0 - val personalGoals = mutableListOf<PersonalGoal>() - private val communityGoals = mutableListOf<CommunityGoal>() - - fun command() { - reload() - } - - private fun reload() { - personalGoals.clear() - communityGoals.clear() - } - - fun toggleCommand() { - if (!LorenzUtils.isBingoProfile) { - LorenzUtils.userError("This command only works on a bingo profile!") - return - } - if (!config.enabled) { - LorenzUtils.userError("Bingo Card is disabled in the config!") - return - } - toggleMode() - } - - private fun toggleMode() { - displayMode++ - if (displayMode == 3) { - displayMode = 0 - } - } - } - - @SubscribeEvent - fun onInventoryOpen(event: InventoryFullyOpenedEvent) { - if (!LorenzUtils.isBingoProfile) return - if (!config.enabled) return - if (event.inventoryName != "Bingo Card") return - - personalGoals.clear() - communityGoals.clear() - for (stack in event.inventoryItems.values) { - val personalGoal = stack.getLore().any { it.endsWith("Personal Goal") } - val communityGoal = stack.getLore().any { it.endsWith("Community Goal") } - if (!personalGoal && !communityGoal) continue - val name = stack.name?.removeColor() ?: continue - val lore = stack.getLore() - var index = 0 - val builder = StringBuilder() - for (s in lore) { - if (index > 1) { - if (s == "") break - builder.append(s) - builder.append(" ") - } - index++ - } - var description = builder.toString() - if (description.endsWith(" ")) { - description = description.substring(0, description.length - 1) - } - if (description.startsWith("§7§7")) { - description = description.substring(2) - } - - val done = stack.getLore().any { it.contains("GOAL REACHED") } - if (personalGoal) { - personalGoals.add(PersonalGoal(name, description, done)) - } else { - communityGoals.add(CommunityGoal(name, description, done)) - } - } - - update() - } - - private fun update() { - display = drawDisplay() - } - - private fun drawDisplay(): MutableList<String> { - val newList = mutableListOf<String>() - - if (communityGoals.isEmpty()) { - newList.add("§6Bingo Goals:") - newList.add("§cOpen the §e/bingo §ccard.") - } else { - if (!config.hideCommunityGoals.get()) { - newList.add("§6Community Goals:") - communityGoals.mapTo(newList) { " " + it.description + if (it.done) " §aDONE" else "" } - newList.add(" ") - } - - val todo = personalGoals.filter { !it.done } - val done = MAX_PERSONAL_GOALS - todo.size - newList.add("§6Personal Goals: ($done/$MAX_PERSONAL_GOALS done)") - todo.mapTo(newList) { " " + it.description } - } - return newList - } - - private var lastSneak = false - - @SubscribeEvent - fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) { - if (!LorenzUtils.isBingoProfile) return - if (!config.enabled) return - - if (config.quickToggle && ItemUtils.isSkyBlockMenuItem(InventoryUtils.getItemInHand())) { - val sneaking = Minecraft.getMinecraft().thePlayer.isSneaking - if (lastSneak != sneaking) { - lastSneak = sneaking - if (sneaking) { - toggleMode() - } - } - } - if (!config.stepHelper && displayMode == 1) { - displayMode = 2 - } - if (displayMode == 0) { - if (Minecraft.getMinecraft().currentScreen !is GuiChat) { - config.bingoCardPos.renderStrings(display, posLabel = "Bingo Card") - } - } else if (displayMode == 1) { - config.bingoCardPos.renderStrings(BingoNextStepHelper.currentHelp, posLabel = "Bingo Card") - } - } - - @SubscribeEvent - fun onChat(event: LorenzChatEvent) { - if (!LorenzUtils.isBingoProfile) return - if (!config.enabled) return - - goalCompletePattern.matchMatcher(event.message) { - val name = group("name") - personalGoals.filter { it.displayName == name } - .forEach { - it.done = true - update() - } - } - } - - @SubscribeEvent - fun onConfigLoad(event: ConfigLoadEvent) { - config.hideCommunityGoals.onToggle { update() } - } - - @SubscribeEvent - fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { - event.move(2, "bingo", "event.bingo") - } -} diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardTips.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardTips.kt deleted file mode 100644 index 318888fec..000000000 --- a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardTips.kt +++ /dev/null @@ -1,77 +0,0 @@ -package at.hannibal2.skyhanni.features.bingo - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.GuiContainerEvent -import at.hannibal2.skyhanni.events.RepositoryReloadEvent -import at.hannibal2.skyhanni.utils.InventoryUtils -import at.hannibal2.skyhanni.utils.ItemUtils.name -import at.hannibal2.skyhanni.utils.LorenzColor -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.RenderUtils.highlight -import at.hannibal2.skyhanni.utils.StringUtils.removeColor -import at.hannibal2.skyhanni.utils.jsonobjects.BingoJson -import at.hannibal2.skyhanni.utils.jsonobjects.BingoJson.BingoTip -import net.minecraft.inventory.ContainerChest -import net.minecraftforge.event.entity.player.ItemTooltipEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class BingoCardTips { - private var tips: Map<String, BingoTip> = emptyMap() - - @SubscribeEvent - fun onRepoReload(event: RepositoryReloadEvent) { - tips = event.getConstant<BingoJson>("Bingo").bingo_tips - } - - @SubscribeEvent - fun onItemTooltipLow(event: ItemTooltipEvent) { - if (!isEnabled()) return - if (InventoryUtils.openInventoryName() != "Bingo Card") return - - val itemName = event.itemStack?.name ?: return - tips[itemName.removeColor()]?.let { - val difficulty = Difficulty.valueOf(it.difficulty.uppercase()) - event.toolTip[0] = event.toolTip[0] + " §7(" + difficulty.displayName + "§7)" - - var index = event.toolTip.indexOf("§5§o§7Reward") - 1 - event.toolTip.add(index++, "") - event.toolTip.add(index++, "§eGuide:") - for (line in it.note) { - event.toolTip.add(index++, line) - } - } - } - - @SubscribeEvent - fun onBackgroundDrawn(event: GuiContainerEvent.BackgroundDrawnEvent) { - if (!isEnabled()) return - if (InventoryUtils.openInventoryName() != "Bingo Card") return - - val guiChest = event.gui - val chest = guiChest.inventorySlots as ContainerChest - - for (slot in chest.inventorySlots) { - if (slot == null) continue - if (slot.slotNumber != slot.slotIndex) continue - if (slot.stack == null) continue - - val itemName = slot.stack.name ?: continue - - tips[itemName.removeColor()]?.let { - val difficulty = Difficulty.valueOf(it.difficulty.uppercase()) - slot highlight difficulty.color.addOpacity(120) - } - } - } - - fun isEnabled() = LorenzUtils.inSkyBlock && SkyHanniMod.feature.event.bingo.bingoCard.bingoSplashGuide - - enum class Difficulty(rawName: String, val color: LorenzColor) { - EASY("Easy", LorenzColor.GREEN), - MEDIUM("Medium", LorenzColor.YELLOW), - HARD("Hard", LorenzColor.RED), - ; - - val displayName = color.getChatColor() + rawName - } -} diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/CompactBingoChat.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/CompactBingoChat.kt index e686191aa..91e7a1745 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/bingo/CompactBingoChat.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/CompactBingoChat.kt @@ -15,8 +15,8 @@ class CompactBingoChat { private var inCollectionLevelUp = false private var collectionLevelUpLastLine: String? = null private var newArea = 0//0 = nothing, 1 = after first message, 2 = after second message - private val healthPattern = " §r§7§8\\+§a.* §c❤ Health".toPattern() - private val strengthPattern = " §r§7§8\\+§a. §c❁ Strength".toPattern() + private val healthPattern = " {3}§r§7§8\\+§a.* §c❤ Health".toPattern() + private val strengthPattern = " {3}§r§7§8\\+§a. §c❁ Strength".toPattern() // TODO USE SH-REPO @SubscribeEvent diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/MinionCraftHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/MinionCraftHelper.kt index 8657f76ee..4428fd072 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/bingo/MinionCraftHelper.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/MinionCraftHelper.kt @@ -7,10 +7,12 @@ import at.hannibal2.skyhanni.events.LorenzTickEvent import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent import at.hannibal2.skyhanni.events.ProfileJoinEvent import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName_old +import at.hannibal2.skyhanni.utils.ItemUtils.hasEnchantments import at.hannibal2.skyhanni.utils.ItemUtils.name import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.NEUItems -import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded +import at.hannibal2.skyhanni.utils.NEUItems.getCachedIngredients +import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.StringUtils.removeColor @@ -76,7 +78,7 @@ class MinionCraftHelper { for ((minionName, minionId) in minions) { minionNamePattern.matchMatcher(minionName) { val cleanName = group("name").removeColor() - val number = group("number").romanToDecimalIfNeeded() + val number = group("number").romanToDecimalIfNecessary() addMinion(cleanName, number, minionId, otherItems, newDisplay) } } @@ -107,6 +109,7 @@ class MinionCraftHelper { for (item in mainInventory) { val name = item?.name?.removeColor() ?: continue + if (item.hasEnchantments()) continue val rawId = item.getInternalName_old() if (!isMinionName(name)) { if (!allIngredients.contains(rawId)) continue @@ -128,7 +131,7 @@ class MinionCraftHelper { val recipes = NEUItems.getRecipes(minion) for (recipe in recipes) { - for (ingredient in recipe.ingredients) { + for (ingredient in recipe.getCachedIngredients()) { val ingredientInternalName = ingredient.internalItemId if (ingredientInternalName == internalName) return true @@ -159,7 +162,7 @@ class MinionCraftHelper { for (recipe in NEUItems.getRecipes(internalId)) { if (recipe !is CraftingRecipe) continue - for (ingredient in recipe.ingredients) { + for (ingredient in recipe.getCachedIngredients()) { val id = ingredient.internalItemId if (!id.contains("_GENERATOR_") && !allIngredients.contains(id)) { allIngredients.add(id) @@ -182,7 +185,7 @@ class MinionCraftHelper { for (minionId in tierOneMinionsFiltered) { for (recipe in NEUItems.getRecipes(minionId)) { if (recipe !is CraftingRecipe) continue - if (recipe.ingredients.any { help.contains(it.internalItemId) }) { + if (recipe.getCachedIngredients().any { help.contains(it.internalItemId) }) { val name = recipe.output.itemStack.name!!.removeColor() val abc = name.replace(" I", " 0") minions[abc] = minionId.replace("_1", "_0") @@ -223,11 +226,16 @@ class MinionCraftHelper { val have = otherItems.getOrDefault(itemId, 0) val percentage = have.toDouble() / needAmount val itemName = NEUItems.getItemStack(rawId).name ?: "§cName??§f" + val isTool = itemId.startsWith("WOOD_") if (percentage >= 1) { - val color = if (itemId.startsWith("WOOD_")) "§7" else "§a" + val color = if (isTool) "§7" else "§a" newDisplay.add(" $itemName§8: ${color}DONE") otherItems[itemId] = have - needAmount } else { + if (!config.minionCraftHelperProgressFirst && !isTool && minionId.endsWith("_0")) { + newDisplay.removeLast() + return + } val format = LorenzUtils.formatPercentage(percentage) val haveFormat = LorenzUtils.formatInteger(have) val needFormat = LorenzUtils.formatInteger(needAmount) diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoCardDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoCardDisplay.kt new file mode 100644 index 000000000..126212ba6 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoCardDisplay.kt @@ -0,0 +1,272 @@ +package at.hannibal2.skyhanni.features.bingo.card + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator +import at.hannibal2.skyhanni.events.ConfigLoadEvent +import at.hannibal2.skyhanni.events.GuiRenderEvent +import at.hannibal2.skyhanni.events.LorenzTickEvent +import at.hannibal2.skyhanni.events.bingo.BingoCardUpdateEvent +import at.hannibal2.skyhanni.features.bingo.BingoAPI +import at.hannibal2.skyhanni.features.bingo.card.goals.BingoGoal +import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.BingoNextStepHelper +import at.hannibal2.skyhanni.utils.InventoryUtils +import at.hannibal2.skyhanni.utils.ItemUtils +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.onToggle +import at.hannibal2.skyhanni.utils.RenderUtils.renderRenderables +import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import at.hannibal2.skyhanni.utils.StringUtils +import at.hannibal2.skyhanni.utils.StringUtils.removeColor +import at.hannibal2.skyhanni.utils.TimeUtils.format +import at.hannibal2.skyhanni.utils.renderables.Renderable +import net.minecraft.client.Minecraft +import net.minecraft.client.gui.GuiChat +import net.minecraft.client.gui.inventory.GuiInventory +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.time.Duration.Companion.days +import kotlin.time.Duration.Companion.milliseconds + +class BingoCardDisplay { + + private var display = emptyList<Renderable>() + + private var hasHiddenPersonalGoals = false + + init { + update() + } + + companion object { + private const val MAX_PERSONAL_GOALS = 20 + private const val MAX_COMMUNITY_GOALS = 5 + + private val config get() = SkyHanniMod.feature.event.bingo.bingoCard + private var displayMode = 0 + + fun command() { + reload() + } + + private fun reload() { + BingoAPI.bingoGoals.clear() + } + + fun toggleCommand() { + if (!LorenzUtils.isBingoProfile) { + LorenzUtils.userError("This command only works on a bingo profile!") + return + } + if (!config.enabled) { + LorenzUtils.userError("Bingo Card is disabled in the config!") + return + } + toggleMode() + } + + private fun toggleMode() { + displayMode++ + if (displayMode == 3) { + displayMode = 0 + } + } + } + + @SubscribeEvent + fun onTick(event: LorenzTickEvent) { + if (event.repeatSeconds(1)) { + if (hasHiddenPersonalGoals) { + update() + } + } + } + + private fun update() { + display = drawDisplay() + } + + private fun drawDisplay(): MutableList<Renderable> { + val newList = mutableListOf<Renderable>() + + if (BingoAPI.bingoGoals.isEmpty()) { + newList.add(Renderable.string("§6Bingo Goals:")) + newList.add(Renderable.clickAndHover("§cOpen the §e/bingo §ccard.", + listOf("Click to run §e/bingo"), + onClick = { + LorenzUtils.sendCommandToServer("bingo") + } + )) + } else { + if (!config.hideCommunityGoals.get()) { + newList.addCommunityGoals() + } + newList.addPersonalGoals() + } + return newList + } + + private var lastClick = SimpleTimeMark.farPast() + + private fun MutableList<Renderable>.addCommunityGoals() { + add(Renderable.string("§6Community Goals:")) + val goals = BingoAPI.communityGoals.toMutableList() + var hiddenGoals = 0 + for (goal in goals.toList()) { + if (goal.hiddenGoalData.unknownTip) { + hiddenGoals++ + goals.remove(goal) + } + } + + addGoals(goals) { it.description.removeColor() + if (it.done) " §aDONE" else " " } + + if (hiddenGoals > 0) { + val name = StringUtils.canBePlural(hiddenGoals, "goal", "goals") + add(Renderable.string("§7+ $hiddenGoals more §cunknown §7community $name.")) + } + add(Renderable.string(" ")) + } + + private fun MutableList<Renderable>.addPersonalGoals() { + val todo = BingoAPI.personalGoals.filter { !it.done }.toMutableList() + val done = MAX_PERSONAL_GOALS - todo.size + add(Renderable.string("§6Personal Goals: ($done/$MAX_PERSONAL_GOALS done)")) + + var hiddenGoals = 0 + var nextTip = 14.days + for (goal in todo.toList()) { + val hiddenGoalData = goal.hiddenGoalData + if (hiddenGoalData.unknownTip) { + hiddenGoals++ + todo.remove(goal) + hiddenGoalData.nextHintTime?.let { + if (it < nextTip) { + nextTip = it + } + } + } + } + + addGoals(todo) { it.description.removeColor() } + + if (hiddenGoals > 0) { + val name = StringUtils.canBePlural(hiddenGoals, "goal", "goals") + add(Renderable.string("§7+ $hiddenGoals more §cunknown §7$name.")) + } + hasHiddenPersonalGoals = config.nextTipDuration.get() && nextTip != 14.days + if (hasHiddenPersonalGoals) { + val nextTipTime = BingoAPI.lastBingoCardOpenTime + nextTip + if (nextTipTime.isInPast()) { + add(Renderable.string("§eThe next hint got unlocked already!")) + add(Renderable.string("§eOpen the bingo card to update!")) + } else { + val until = nextTipTime.timeUntil() + add(Renderable.string("§eThe next hint will unlock in §b${until.format(maxUnits = 2)}")) + } + } + } + + private fun MutableList<Renderable>.addGoals(goals: MutableList<BingoGoal>, format: (BingoGoal) -> String) { + val editDisplay = canEditDisplay() + val showOnlyHighlighted = goals.count { it.highlight } > 0 + + val filter = showOnlyHighlighted && !editDisplay + val finalGoal = if (filter) { + goals.filter { it.highlight } + } else goals + + finalGoal.mapTo(this) { + val currentlyHighlighted = it.highlight + val highlightColor = if (currentlyHighlighted && editDisplay) "§e" else "§7" + val display = " $highlightColor" + format(it) + + if (editDisplay) { + val clickName = if (currentlyHighlighted) "remove" else "add" + Renderable.clickAndHover( + display, + listOf( + "§a" + it.displayName, + "", + "§eClick to $clickName this goal as highlight!", + ), + onClick = { + if (lastClick.passedSince() < 300.milliseconds) return@clickAndHover + lastClick = SimpleTimeMark.now() + + it.highlight = !currentlyHighlighted + update() + } + ) + } else { + Renderable.string(display) + } + } + if (filter) { + val missing = goals.size - finalGoal.size + add(Renderable.string(" §8+ $missing not highlighted goals.")) + } + } + + private var highlightedMaps = mutableMapOf<String, Boolean>() + + var BingoGoal.highlight: Boolean + get() = highlightedMaps[displayName] ?: false + set(value) { + highlightedMaps[displayName] = value + } + + private var lastSneak = false + private var inventoryOpen = false + + @SubscribeEvent + fun onRenderOverlay(event: GuiRenderEvent) { + if (!LorenzUtils.isBingoProfile) return + if (!config.enabled) return + + val currentlyOpen = canEditDisplay() + if (inventoryOpen != currentlyOpen) { + inventoryOpen = currentlyOpen + update() + } + + if (config.quickToggle && ItemUtils.isSkyBlockMenuItem(InventoryUtils.getItemInHand())) { + val sneaking = Minecraft.getMinecraft().thePlayer.isSneaking + if (lastSneak != sneaking) { + lastSneak = sneaking + if (sneaking) { + toggleMode() + } + } + } + if (!config.stepHelper && displayMode == 1) { + displayMode = 2 + } + if (displayMode == 0) { + if (Minecraft.getMinecraft().currentScreen !is GuiChat) { + config.bingoCardPos.renderRenderables(display, posLabel = "Bingo Card") + } + } else if (displayMode == 1) { + config.bingoCardPos.renderStrings(BingoNextStepHelper.currentHelp, posLabel = "Bingo Card") + } + } + + private fun canEditDisplay() = + Minecraft.getMinecraft().currentScreen is GuiInventory || InventoryUtils.openInventoryName() == "Bingo Card" + + @SubscribeEvent + fun onBingoCardUpdate(event: BingoCardUpdateEvent) { + if (!config.enabled) return + update() + } + + @SubscribeEvent + fun onConfigLoad(event: ConfigLoadEvent) { + config.hideCommunityGoals.onToggle { update() } + config.nextTipDuration.onToggle { update() } + } + + @SubscribeEvent + fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { + event.move(2, "bingo", "event.bingo") + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoCardReader.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoCardReader.kt new file mode 100644 index 000000000..151cb145e --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoCardReader.kt @@ -0,0 +1,123 @@ +package at.hannibal2.skyhanni.features.bingo.card + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.data.jsonobjects.repo.BingoJson +import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.bingo.BingoCardUpdateEvent +import at.hannibal2.skyhanni.events.bingo.BingoGoalReachedEvent +import at.hannibal2.skyhanni.features.bingo.BingoAPI +import at.hannibal2.skyhanni.features.bingo.card.goals.BingoGoal +import at.hannibal2.skyhanni.features.bingo.card.goals.GoalType +import at.hannibal2.skyhanni.features.bingo.card.goals.HiddenGoalData +import at.hannibal2.skyhanni.utils.ItemUtils.getLore +import at.hannibal2.skyhanni.utils.ItemUtils.name +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher +import at.hannibal2.skyhanni.utils.StringUtils.removeColor +import at.hannibal2.skyhanni.utils.TimeUtils +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.time.Duration + +class BingoCardReader { + private val config get() = SkyHanniMod.feature.event.bingo.bingoCard + + // TODO USE SH-REPO + private val goalCompletePattern = "§6§lBINGO GOAL COMPLETE! §r§e(?<name>.*)".toPattern() + + private val personalHiddenGoalPattern = ".*§7§eThe next hint will unlock in (?<time>.*)".toPattern() + + @SubscribeEvent + fun onInventoryOpen(event: InventoryFullyOpenedEvent) { + if (!LorenzUtils.isBingoProfile) return + if (!config.enabled) return + if (event.inventoryName != "Bingo Card") return + + BingoAPI.bingoGoals.clear() + for ((slot, stack) in event.inventoryItems) { + val goalType = when { + stack.getLore().any { it.endsWith("Personal Goal") } -> GoalType.PERSONAL + stack.getLore().any { it.endsWith("Community Goal") } -> GoalType.COMMUNITY + else -> continue + } + val name = stack.name?.removeColor() ?: continue + val lore = stack.getLore() + var index = 0 + val builder = StringBuilder() + for (s in lore) { + if (index > 1) { + if (s == "") break + builder.append(s) + builder.append(" ") + } + index++ + } + var description = builder.toString() + if (description.endsWith(" ")) { + description = description.substring(0, description.length - 1) + } + if (description.startsWith("§7§7")) { + description = description.substring(2) + } + + val done = stack.getLore().any { it.contains("GOAL REACHED") } + + val hiddenGoalData = getHiddenGoalData(name, description, goalType) + val visualDescription = hiddenGoalData.tipNote + + val bingoGoal = BingoGoal(name, visualDescription, goalType, slot, done, hiddenGoalData) + BingoAPI.bingoGoals.add(bingoGoal) + } + BingoAPI.lastBingoCardOpenTime = SimpleTimeMark.now() + + BingoCardUpdateEvent().postAndCatch() + } + + private fun getHiddenGoalData( + name: String, + originalDescription: String, + goalType: GoalType, + ): HiddenGoalData { + var unknownTip = false + val nextHintTime: Duration? = when (goalType) { + GoalType.PERSONAL -> { + personalHiddenGoalPattern.matchMatcher(originalDescription) { + unknownTip = true + TimeUtils.getDuration(group("time").removeColor()) + } + } + + GoalType.COMMUNITY -> { + if (originalDescription == "§7This goal will be revealed §7when it hits Tier IV.") { + unknownTip = true + } + null + } + } + + val description = BingoAPI.getTip(name)?.getDescriptionLine() + val tipNote = description?.let { + unknownTip = false + it + } ?: originalDescription + return HiddenGoalData(unknownTip, nextHintTime, tipNote) + } + + @SubscribeEvent + fun onChat(event: LorenzChatEvent) { + if (!LorenzUtils.isBingoProfile) return + if (!config.enabled) return + + val name = goalCompletePattern.matchMatcher(event.message) { + group("name") + } ?: return + + val goal = BingoAPI.personalGoals.firstOrNull { it.displayName == name } ?: return + goal.done = true + BingoGoalReachedEvent(goal).postAndCatch() + BingoCardUpdateEvent().postAndCatch() + } + + private fun BingoJson.BingoTip.getDescriptionLine() = "§7" + note.joinToString(" ") +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoCardTips.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoCardTips.kt new file mode 100644 index 000000000..a8d62579c --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoCardTips.kt @@ -0,0 +1,84 @@ +package at.hannibal2.skyhanni.features.bingo.card + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.GuiContainerEvent +import at.hannibal2.skyhanni.features.bingo.BingoAPI +import at.hannibal2.skyhanni.features.bingo.BingoAPI.getTip +import at.hannibal2.skyhanni.features.bingo.card.goals.GoalType +import at.hannibal2.skyhanni.utils.InventoryUtils +import at.hannibal2.skyhanni.utils.LorenzColor +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.RenderUtils.highlight +import net.minecraft.client.Minecraft +import net.minecraft.client.gui.inventory.GuiContainer +import net.minecraft.inventory.ContainerChest +import net.minecraftforge.event.entity.player.ItemTooltipEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class BingoCardTips { + private val config get() = SkyHanniMod.feature.event.bingo.bingoCard + + @SubscribeEvent + fun onItemTooltipLow(event: ItemTooltipEvent) { + if (!isEnabled()) return + if (InventoryUtils.openInventoryName() != "Bingo Card") return + + val gui = Minecraft.getMinecraft().currentScreen as? GuiContainer ?: return + val slot = gui.slotUnderMouse + val goal = BingoAPI.bingoGoals.firstOrNull { it.slot == slot.slotNumber } ?: return + + val toolTip = event.toolTip ?: return + val bingoTip = goal.getTip() ?: return + val communityGoal = goal.type == GoalType.COMMUNITY + + val difficulty = Difficulty.valueOf(bingoTip.difficulty.uppercase()) + toolTip[0] = toolTip[0] + " §7(" + difficulty.displayName + "§7) ${goal.done}" + + var index = if (!communityGoal) { + toolTip.indexOf("§5§o§7Reward") + } else { + toolTip.indexOfFirst { it.startsWith("§5§o§7Contribution Rewards") } + } - 1 + + toolTip.add(index++, "") + toolTip.add(index++, "§eGuide:") + for (line in bingoTip.note) { + toolTip.add(index++, " $line") + } + bingoTip.found?.let { + toolTip.add(index++, "§7Found by: §e$it") + } + } + + @SubscribeEvent + fun onBackgroundDrawn(event: GuiContainerEvent.BackgroundDrawnEvent) { + if (!isEnabled()) return + if (InventoryUtils.openInventoryName() != "Bingo Card") return + + val guiChest = event.gui + val chest = guiChest.inventorySlots as ContainerChest + for (slot in chest.inventorySlots) { + if (slot == null) continue + + val goal = BingoAPI.bingoGoals.firstOrNull { it.slot == slot.slotNumber } ?: continue + if (config.hideDoneDifficulty && goal.done) continue + + val color = goal.getTip()?.let { + val difficulty = Difficulty.valueOf(it.difficulty.uppercase()) + difficulty.color + } ?: LorenzColor.GRAY + slot highlight color.addOpacity(120) + } + } + + fun isEnabled() = LorenzUtils.inSkyBlock && config.bingoSplashGuide + + enum class Difficulty(rawName: String, val color: LorenzColor) { + EASY("Easy", LorenzColor.GREEN), + MEDIUM("Medium", LorenzColor.YELLOW), + HARD("Hard", LorenzColor.RED), + ; + + val displayName = color.getChatColor() + rawName + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoGoals.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoGoals.kt deleted file mode 100644 index dbcb5bf35..000000000 --- a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoGoals.kt +++ /dev/null @@ -1,4 +0,0 @@ -package at.hannibal2.skyhanni.features.bingo.card - - -abstract class BingoGoals(val displayName: String, val description: String, var done: Boolean)
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/CommunityGoal.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/CommunityGoal.kt deleted file mode 100644 index 63e13eadc..000000000 --- a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/CommunityGoal.kt +++ /dev/null @@ -1,4 +0,0 @@ -package at.hannibal2.skyhanni.features.bingo.card - -class CommunityGoal(displayName: String, description: String, done: Boolean) : - BingoGoals(displayName, description, done)
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/PersonalGoal.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/PersonalGoal.kt deleted file mode 100644 index 981bb1a20..000000000 --- a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/PersonalGoal.kt +++ /dev/null @@ -1,3 +0,0 @@ -package at.hannibal2.skyhanni.features.bingo.card - -class PersonalGoal(displayName: String, description: String, done: Boolean) : BingoGoals(displayName, description, done)
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/goals/BingoGoal.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/goals/BingoGoal.kt new file mode 100644 index 000000000..31f01b335 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/goals/BingoGoal.kt @@ -0,0 +1,12 @@ +package at.hannibal2.skyhanni.features.bingo.card.goals + +class BingoGoal( + val displayName: String, + val description: String, + val type: GoalType, + val slot: Int, + var done: Boolean, + val hiddenGoalData: HiddenGoalData, +) { + override fun toString(): String = displayName +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/goals/GoalType.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/goals/GoalType.kt new file mode 100644 index 000000000..b2e4f6d8d --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/goals/GoalType.kt @@ -0,0 +1,7 @@ +package at.hannibal2.skyhanni.features.bingo.card.goals + +enum class GoalType { + COMMUNITY, + PERSONAL, + ; +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/goals/HiddenGoalData.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/goals/HiddenGoalData.kt new file mode 100644 index 000000000..b2ea441d3 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/goals/HiddenGoalData.kt @@ -0,0 +1,5 @@ +package at.hannibal2.skyhanni.features.bingo.card.goals + +import kotlin.time.Duration + +class HiddenGoalData(val unknownTip: Boolean, val nextHintTime: Duration?, val tipNote: String) diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoNextStepHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/BingoNextStepHelper.kt index 2960b2d22..0cd5df65a 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoNextStepHelper.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/BingoNextStepHelper.kt @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.features.bingo +package at.hannibal2.skyhanni.features.bingo.card.nextstephelper import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.api.CollectionAPI @@ -6,22 +6,22 @@ import at.hannibal2.skyhanni.data.IslandType import at.hannibal2.skyhanni.data.SkillExperience import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.LorenzTickEvent -import at.hannibal2.skyhanni.features.bingo.nextstep.ChatMessageStep -import at.hannibal2.skyhanni.features.bingo.nextstep.CollectionStep -import at.hannibal2.skyhanni.features.bingo.nextstep.CraftStep -import at.hannibal2.skyhanni.features.bingo.nextstep.IslandVisitStep -import at.hannibal2.skyhanni.features.bingo.nextstep.ItemsStep -import at.hannibal2.skyhanni.features.bingo.nextstep.NextStep -import at.hannibal2.skyhanni.features.bingo.nextstep.ObtainCrystalStep -import at.hannibal2.skyhanni.features.bingo.nextstep.PartialProgressItemsStep -import at.hannibal2.skyhanni.features.bingo.nextstep.ProgressionStep -import at.hannibal2.skyhanni.features.bingo.nextstep.SkillLevelStep +import at.hannibal2.skyhanni.features.bingo.BingoAPI +import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps.ChatMessageStep +import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps.CollectionStep +import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps.CraftStep +import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps.IslandVisitStep +import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps.ItemsStep +import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps.NextStep +import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps.ObtainCrystalStep +import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps.PartialProgressItemsStep +import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps.ProgressionStep +import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps.SkillLevelStep import at.hannibal2.skyhanni.utils.InventoryUtils import at.hannibal2.skyhanni.utils.ItemUtils.name import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher -import at.hannibal2.skyhanni.utils.StringUtils.matchRegex import at.hannibal2.skyhanni.utils.StringUtils.removeColor import net.minecraftforge.fml.common.eventhandler.SubscribeEvent @@ -37,6 +37,7 @@ class BingoNextStepHelper { private val collectionPattern = "Reach (?<amount>[0-9]+(?:,\\d+)*) (?<name>.*) Collection\\.".toPattern() private val crystalPattern = "Obtain a (?<name>\\w+) Crystal in the Crystal Hollows\\.".toPattern() private val skillPattern = "Obtain level (?<level>.*) in the (?<skill>.*) Skill.".toPattern() + private val crystalFoundPattern = " *§r§5§l✦ CRYSTAL FOUND §r§7\\(.§r§7/5§r§7\\)".toPattern() private val rhysTaskName = "30x Enchanted Minerals (Redstone, Lapis Lazuli, Coal) (for Rhys)" companion object { @@ -135,7 +136,7 @@ class BingoNextStepHelper { for (currentStep in currentSteps) { if (currentStep is ObtainCrystalStep) { - if (event.message.matchRegex(" *§r§5§l✦ CRYSTAL FOUND §r§7\\(.§r§7/5§r§7\\)")) { + crystalFoundPattern.matchMatcher(event.message) { nextMessageIsCrystal = true return } @@ -215,7 +216,7 @@ class BingoNextStepHelper { } private fun update() { - val personalGoals = BingoCardDisplay.personalGoals.filter { !it.done } + val personalGoals = BingoAPI.personalGoals.filter { !it.done } if (personalGoals.isEmpty()) { if (!dirty) { reset() @@ -228,9 +229,10 @@ class BingoNextStepHelper { dirty = false for (goal in personalGoals) { - val bingoCardStep = readDescription(goal.description.removeColor()) + val description = goal.description + val bingoCardStep = readDescription(description.removeColor()) if (bingoCardStep == null) { - println("Warning: Could not find bingo steps for ${goal.description}") +// println("Warning: Could not find bingo steps for $description") } else { finalSteps.add(bingoCardStep) } diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/ChatMessageStep.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/ChatMessageStep.kt index 021ef5f73..0da254a40 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/ChatMessageStep.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/ChatMessageStep.kt @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.features.bingo.nextstep +package at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps class ChatMessageStep(displayName: String) : NextStep(displayName) class ObtainCrystalStep(val crystalName: String) : NextStep("Obtain a $crystalName Crystal") diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/CollectionStep.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/CollectionStep.kt index 4e08b2ba4..e6bb7075b 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/CollectionStep.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/CollectionStep.kt @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.features.bingo.nextstep +package at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps import at.hannibal2.skyhanni.utils.NEUInternalName import at.hannibal2.skyhanni.utils.NumberUtil @@ -6,4 +6,4 @@ import at.hannibal2.skyhanni.utils.NumberUtil class CollectionStep(collectionName: String, amountNeeded: Int) : ProgressionStep(NumberUtil.format(amountNeeded) + " $collectionName Collection", amountNeeded.toLong()) { val internalName by lazy { NEUInternalName.fromItemName(if (collectionName == "Mushroom") "Red Mushroom" else collectionName) } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/CraftStep.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/CraftStep.kt new file mode 100644 index 000000000..4ae9a08c0 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/CraftStep.kt @@ -0,0 +1,3 @@ +package at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps + +class CraftStep(val itemName: String) : NextStep("Craft $itemName") diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/IslandVisitStep.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/IslandVisitStep.kt index c25c440bc..f2ae9cf01 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/IslandVisitStep.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/IslandVisitStep.kt @@ -1,5 +1,5 @@ -package at.hannibal2.skyhanni.features.bingo.nextstep +package at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps import at.hannibal2.skyhanni.data.IslandType -class IslandVisitStep(val island: IslandType) : NextStep("Visit ${island.displayName}")
\ No newline at end of file +class IslandVisitStep(val island: IslandType) : NextStep("Visit ${island.displayName}") diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/ItemsStep.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/ItemsStep.kt index c9e65b1b4..548318a20 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/ItemsStep.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/ItemsStep.kt @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.features.bingo.nextstep +package at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps open class ItemsStep(displayName: String, val itemName: String, amountNeeded: Long, val variants: Map<String, Int>) : ProgressionStep(displayName, amountNeeded) diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/NextStep.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/NextStep.kt index d5077478e..d0a73926a 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/NextStep.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/NextStep.kt @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.features.bingo.nextstep +package at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps abstract class NextStep( val displayName: String, diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/ProgressionStep.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/ProgressionStep.kt index 2d19438d5..26f7d6c4d 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/ProgressionStep.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/ProgressionStep.kt @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.features.bingo.nextstep +package at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps abstract class ProgressionStep(displayName: String, open val amountNeeded: Long, var amountHaving: Long = 0) : - NextStep(displayName)
\ No newline at end of file + NextStep(displayName) diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/SkillLevelStep.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/SkillLevelStep.kt index 48767e8d9..e93aa24b0 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/SkillLevelStep.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/SkillLevelStep.kt @@ -1,4 +1,4 @@ -package at.hannibal2.skyhanni.features.bingo.nextstep +package at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps import at.hannibal2.skyhanni.data.SkillExperience @@ -7,4 +7,4 @@ class SkillLevelStep( private val skillLevelNeeded: Int, skillExpNeeded: Long = SkillExperience.getExpForLevel(skillLevelNeeded) ) : - ProgressionStep("$skillName $skillLevelNeeded", skillExpNeeded)
\ No newline at end of file + ProgressionStep("$skillName $skillLevelNeeded", skillExpNeeded) diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/CraftStep.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/CraftStep.kt deleted file mode 100644 index 4c20494b0..000000000 --- a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/CraftStep.kt +++ /dev/null @@ -1,3 +0,0 @@ -package at.hannibal2.skyhanni.features.bingo.nextstep - -class CraftStep(val itemName: String) : NextStep("Craft $itemName")
\ No newline at end of file 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 33509b606..3c6614e1f 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilter.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilter.kt @@ -3,7 +3,7 @@ package at.hannibal2.skyhanni.features.chat import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher +import at.hannibal2.skyhanni.utils.StringUtils.matches import at.hannibal2.skyhanni.utils.StringUtils.removeColor import at.hannibal2.skyhanni.utils.StringUtils.trimWhiteSpaceAndResets import net.minecraftforge.fml.common.eventhandler.SubscribeEvent @@ -192,13 +192,13 @@ class ChatFilter { // Party private val partyMessages = listOf( - "§9§m-----------------------------------------------------" + "§9§m-----------------------------------------------------", ) // MONEY // Auction House private val auctionHouseMessages = listOf( - "§b-----------------------------------------------------", "§eVisit the Auction House to collect your item!" + "§b-----------------------------------------------------", "§eVisit the Auction House to collect your item!", ) // Bazaar @@ -206,12 +206,12 @@ class ChatFilter { "§eBuy Order Setup! §r§a(.*)§r§7x (.*) §r§7for §r§6(.*) coins§r§7.".toPattern(), "§eSell Offer Setup! §r§a(.*)§r§7x (.*) §r§7for §r§6(.*) coins§r§7.".toPattern(), "§cCancelled! §r§7Refunded §r§6(.*) coins §r§7from cancelling buy order!".toPattern(), - "§cCancelled! §r§7Refunded §r§a(.*)§r§7x (.*) §r§7from cancelling sell offer!".toPattern() + "§cCancelled! §r§7Refunded §r§a(.*)§r§7x (.*) §r§7from cancelling sell offer!".toPattern(), ) // Winter Island private val winterIslandPatterns = listOf( - "§r§f☃ §r§7§r(.*) §r§7mounted a §r§fSnow Cannon§r§7!".toPattern() + "§r§f☃ §r§7§r(.*) §r§7mounted a §r§fSnow Cannon§r§7!".toPattern(), ) // Useless Warning @@ -224,13 +224,13 @@ class ChatFilter { "§cPlace a Dungeon weapon or armor piece above the anvil to salvage it!", "§cWhoa! Slow down there!", "§cWait a moment before confirming!", - "§cYou cannot open the SkyBlock menu while in combat!" + "§cYou cannot open the SkyBlock menu while in combat!", ) // Annoying Spam private val annoyingSpamPatterns = listOf( "§7Your Implosion hit (.*) for §r§c(.*) §r§7damage.".toPattern(), - "§7Your Molten Wave hit (.*) for §r§c(.*) §r§7damage.".toPattern() + "§7Your Molten Wave hit (.*) for §r§c(.*) §r§7damage.".toPattern(), ) private val annoyingSpamMessages = listOf( "§cThere are blocks in the way!", @@ -242,7 +242,7 @@ class ChatFilter { "§6§lGOOD CATCH! §r§bYou found a §r§fDark Bait§r§b.", "§6§lGOOD CATCH! §r§bYou found a §r§fLight Bait§r§b.", "§6§lGOOD CATCH! §r§bYou found a §r§aHot Bait§r§b.", - "§6§lGOOD CATCH! §r§bYou found a §r§fSpooky Bait§r§b." + "§6§lGOOD CATCH! §r§bYou found a §r§fSpooky Bait§r§b.", ) // Winter Gift @@ -275,7 +275,7 @@ class ChatFilter { "§e§lSWEET! §r§5Snow Suit .* §r§egift with §r.*§r§e!".toPattern(), // winter gifts not your gifts - "§cThis gift is for §r.*§r§c, sorry!".toPattern() + "§cThis gift is for §r.*§r§c, sorry!".toPattern(), ) // Powder Mining @@ -289,7 +289,12 @@ class ChatFilter { // Useful, maybe in another chat "§aYou received §r§b\\+\\d{1,3} §r§a(Mithril|Gemstone) Powder.".toPattern(), - "§aYou received §r(§6|§b)\\+[1-2] (Diamond|Gold) Essence".toPattern() + "§aYou received §r(§6|§b)\\+[1-2] (Diamond|Gold) Essence".toPattern(), + ) + private val fireSalePatterns = listOf( + "§c♨ §eFire Sales for .* §eare starting soon!".toPattern(), + "§c {3}♨ .* Skin §e\\(.* §eleft\\)§c".toPattern(), + "§c♨ §eVisit the Community Shop in the next §c.* §eto grab yours! §a§l\\[WARP]".toPattern() ) private val powderMiningMessages = listOf( "§aYou uncovered a treasure chest!", @@ -298,7 +303,11 @@ class ChatFilter { // Jungle "§aYou received §r§f1 §r§aOil Barrel§r§a.", // Useful, maybe in another chat - "§6You have successfully picked the lock on this chest!" + "§6You have successfully picked the lock on this chest!", + ) + private val fireSaleMessages = listOf( + "§6§k§lA§r §c§lFIRE SALE §r§6§k§lA", + "§c♨ §eSelling multiple items for a limited time!", ) private val patternsMap: Map<String, List<Pattern>> = mapOf( @@ -314,7 +323,8 @@ class ChatFilter { "winter_island" to winterIslandPatterns, "annoying_spam" to annoyingSpamPatterns, "winter_gift" to winterGiftPatterns, - "powder_mining" to powderMiningPatterns + "powder_mining" to powderMiningPatterns, + "fire_sale" to fireSalePatterns, ) private val messagesMap: Map<String, List<String>> = mapOf( @@ -330,14 +340,15 @@ class ChatFilter { "money" to auctionHouseMessages, "useless_warning" to uselessWarningMessages, "annoying_spam" to annoyingSpamMessages, - "powder_mining" to powderMiningMessages + "powder_mining" to powderMiningMessages, + "fire_sale" to fireSaleMessages, ) private val messagesContainsMap: Map<String, List<String>> = mapOf( "lobby" to lobbyMessagesContains, ) private val messagesStartsWithMap: Map<String, List<String>> = mapOf( "slayer" to slayerMessageStartWith, - "profile_join" to profileJoinMessageStartsWith + "profile_join" to profileJoinMessageStartsWith, ) /// </editor-fold> @@ -367,6 +378,8 @@ class ChatFilter { config.winterGift && message.isPresent("winter_gift") -> "winter_gift" config.powderMining && message.isPresent("powder_mining") -> "powder_mining" + config.fireSale && message.isPresent("fire_sale") -> "fire_sale" + else -> "" } @@ -417,7 +430,7 @@ class ChatFilter { * @see messagesStartsWithMap */ private fun String.isPresent(key: String) = this in (messagesMap[key] ?: emptyList()) || - (patternsMap[key] ?: emptyList()).any { it.matchMatcher(this) { } != null } || + (patternsMap[key] ?: emptyList()).any { it.matches(this) } || (messagesContainsMap[key] ?: emptyList()).any { this.contains(it) } || (messagesStartsWithMap[key] ?: emptyList()).any { this.startsWith(it) } diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/CompactSplashPotionMessage.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/CompactSplashPotionMessage.kt index c823d83f0..e624af88c 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/chat/CompactSplashPotionMessage.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/chat/CompactSplashPotionMessage.kt @@ -3,49 +3,59 @@ package at.hannibal2.skyhanni.features.chat import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.groupOrNull +import at.hannibal2.skyhanni.utils.StringUtils.cleanPlayerName import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher -import at.hannibal2.skyhanni.utils.StringUtils.removeColor import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class CompactSplashPotionMessage { private val config get() = SkyHanniMod.feature.chat.compactPotionMessages - private val potionEffectPattern = - "§a§lBUFF! §fYou have gained §r(?<name>.*)§r§f! Press TAB or type /effects to view your active effects!".toPattern() - private val potionSplashEffectOthersPattern = - "§a§lBUFF! §fYou were splashed by (?<playerName>.*) §fwith §r(?<effectName>.*)§r§f! Press TAB or type /effects to view your active effects!".toPattern() - private val potionSplashEffectPattern = - "§a§lBUFF! §fYou splashed yourself with §r(?<name>.*)§r§f! Press TAB or type /effects to view your active effects!".toPattern() + private val potionEffectPatternList = listOf( + "§a§lBUFF! §fYou were splashed by (?<playerName>.*) §fwith §r(?<effectName>.*)§r§f! Press TAB or type /effects to view your active effects!".toPattern(), + "§a§lBUFF! §fYou have gained §r(?<effectName>.*)§r§f! Press TAB or type /effects to view your active effects!".toPattern(), + "§a§lBUFF! §fYou splashed yourself with §r(?<effectName>.*)§r§f! Press TAB or type /effects to view your active effects!".toPattern(), + + // Fix for Hypixel having a different message for Poisoned Candy. + // Did not make the first pattern optional to prevent conflicts with Dungeon Buffs/other things + "§a§lBUFF! §fYou have gained §r(?<effectName>§2Poisoned Candy I)§r§f!§r".toPattern(), + "§a§lBUFF! §fYou splashed yourself with §r(?<effectName>§2Poisoned Candy I)§r§f!§r".toPattern(), + "§a§lBUFF! §fYou were splashed by (?<playerName>.*) §fwith §r(?<effectName>§2Poisoned Candy I)§r§f!§r".toPattern() + ) @SubscribeEvent fun onChatMessage(event: LorenzChatEvent) { - if (!LorenzUtils.inSkyBlock || !config.enabled) return - - potionEffectPattern.matchMatcher(event.message) { - val name = group("name") - sendMessage("§a§lPotion Effect! §r$name") - event.blockedReason = "compact_potion_effect" - } - - potionSplashEffectOthersPattern.matchMatcher(event.message) { - val playerName = group("playerName").removeColor() - val effectName = group("effectName") - sendMessage("§a§lPotion Effect! §r$effectName by §b$playerName") - event.blockedReason = "compact_potion_effect" - } - - potionSplashEffectPattern.matchMatcher(event.message) { - val name = group("name") - sendMessage("§a§lPotion Effect! §r$name") - event.blockedReason = "compact_potion_effect" - } + if (!isEnabled()) return + if (!event.message.isPotionMessage()) return + event.blockedReason = "compact_potion_effect" } private fun sendMessage(message: String) { if (config.clickableChatMessage) { - LorenzUtils.hoverableChat(message, listOf("§eClick to view your potion effects."), "/effects") + LorenzUtils.hoverableChat( + message, + listOf("§eClick to view your potion effects."), + "/effects", + prefix = false + ) } else { - LorenzUtils.chat(message) + LorenzUtils.chat(message, prefix = false) } } + + private fun String.isPotionMessage(): Boolean { + return potionEffectPatternList.any { + it.matchMatcher(this) { + val effectName = group("effectName") + // If splashed by a player, append their name. + val byPlayer = groupOrNull("playerName")?.let { player -> + val displayName = player.cleanPlayerName(displayName = true) + " §aby $displayName" + } ?: "" + sendMessage("§a§lPotion Effect! §r$effectName$byPlayer") + } != null + } + } + + private fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled } diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt index 2cfdb5dc9..3cc67e617 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt @@ -25,7 +25,7 @@ class Translator { // Logic for listening for a user click on a chat message is from NotEnoughUpdates @SubscribeEvent(priority = EventPriority.LOWEST) - fun onGuiChat(event: LorenzChatEvent) { + fun onChat(event: LorenzChatEvent) { if (!isEnabled()) return val message = event.message diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatFilter.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatFilter.kt index ed1a256d5..4a80f8084 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatFilter.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatFilter.kt @@ -2,7 +2,7 @@ package at.hannibal2.skyhanni.features.chat.playerchat import at.hannibal2.skyhanni.events.RepositoryReloadEvent import at.hannibal2.skyhanni.utils.MultiFilter -import at.hannibal2.skyhanni.utils.jsonobjects.PlayerChatFilterJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.PlayerChatFilterJson import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class PlayerChatFilter { diff --git a/src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaFontRenderer.kt b/src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaFontRenderer.kt index 469fc2f3c..26dc45969 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaFontRenderer.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaFontRenderer.kt @@ -31,9 +31,7 @@ class ChromaFontRenderer(private val baseColor: Int) { } fun restoreChromaEnv() { - if (ShaderHelper.areShadersSupported()) { - if (!chromaOn) ChromaShaderManager.end() - } + if (ShaderHelper.areShadersSupported() && !chromaOn) ChromaShaderManager.end() } fun newChromaEnv(): ChromaFontRenderer { diff --git a/src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaShader.kt b/src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaShader.kt index e7bedbdcd..8afd758a7 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaShader.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaShader.kt @@ -13,32 +13,32 @@ import net.minecraft.client.Minecraft * Credit: [ChromaShader.java](https://github.com/BiscuitDevelopment/SkyblockAddons/blob/main/src/main/java/codes/biscuit/skyblockaddons/shader/chroma/ChromaShader.java) */ object ChromaShader : Shader("chroma", "chroma") { - + val config get() = SkyHanniMod.feature.chroma val INSTANCE: ChromaShader get() = this override fun registerUniforms() { registerUniform(Uniform.UniformType.FLOAT, "chromaSize") { - SkyHanniMod.feature.chroma.chromaSize * (Minecraft.getMinecraft().displayWidth / 100f) + config.chromaSize * (Minecraft.getMinecraft().displayWidth / 100f) } registerUniform(Uniform.UniformType.FLOAT, "timeOffset") { var ticks = (MinecraftData.totalTicks / 2) + (Minecraft.getMinecraft() as AccessorMinecraft).timer.renderPartialTicks - ticks = when (SkyHanniMod.feature.chroma.chromaDirection) { + ticks = when (config.chromaDirection) { 0, 2 -> ticks 1, 3 -> -ticks else -> ticks } - val chromaSpeed = SkyHanniMod.feature.chroma.chromaSpeed / 360f + val chromaSpeed = config.chromaSpeed / 360f ticks * chromaSpeed } registerUniform(Uniform.UniformType.FLOAT, "saturation") { - SkyHanniMod.feature.chroma.chromaSaturation + config.chromaSaturation } registerUniform(Uniform.UniformType.BOOL, "forwardDirection") { - when (SkyHanniMod.feature.chroma.chromaDirection) { + when (config.chromaDirection) { 0, 1 -> true 2, 3 -> false else -> true diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/BestiaryData.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/BestiaryData.kt index 5f0a4125e..daf5caddd 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/combat/BestiaryData.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/combat/BestiaryData.kt @@ -15,7 +15,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.addButton import at.hannibal2.skyhanni.utils.NumberUtil import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber -import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded +import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary import at.hannibal2.skyhanni.utils.NumberUtil.roundToPrecision import at.hannibal2.skyhanni.utils.NumberUtil.toRoman import at.hannibal2.skyhanni.utils.RenderUtils.highlight @@ -245,7 +245,7 @@ object BestiaryData { private fun getMobHover(mob: BestiaryMob) = listOf( "§6Name: §b${mob.name}", - "§6Level: §b${mob.level} ${if (!config.replaceRoman) "§7(${mob.level.romanToDecimalIfNeeded()})" else ""}", + "§6Level: §b${mob.level} ${if (!config.replaceRoman) "§7(${mob.level.romanToDecimalIfNecessary()})" else ""}", "§6Total Kills: §b${mob.actualRealTotalKill.formatNumber()}", "§6Kills needed to max: §b${mob.killNeededToMax().formatNumber()}", "§6Kills needed to next lvl: §b${mob.killNeededToNextLevel().formatNumber()}", @@ -459,7 +459,7 @@ object BestiaryData { } - private fun String.romanOrInt() = romanToDecimalIfNeeded().let { + private fun String.romanOrInt() = romanToDecimalIfNecessary().let { if (config.replaceRoman || it == 0) it.toString() else it.toRoman() } @@ -473,7 +473,7 @@ object BestiaryData { if (this == "0") { "I".romanOrInt() } else { - val intValue = romanToDecimalIfNeeded() + val intValue = romanToDecimalIfNecessary() (intValue + 1).toRoman().romanOrInt() } } @@ -486,4 +486,4 @@ object BestiaryData { private fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/BossType.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/BossType.kt index 664aa63d4..045eaaa78 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/BossType.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/BossType.kt @@ -1,94 +1,109 @@ package at.hannibal2.skyhanni.features.combat.damageindicator +import at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry + +typealias Type = DamageIndicatorBossEntry + enum class BossType( val fullName: String, - val bossTypeToggle: Int, + val bossTypeToggle: Type, val shortName: String = fullName, val showDeathTime: Boolean = false ) { - GENERIC_DUNGEON_BOSS("Generic Dungeon boss", 0),//TODO split into different bosses + GENERIC_DUNGEON_BOSS("Generic Dungeon boss", Type.DUNGEON_ALL),//TODO split into different bosses //Nether Mini Bosses - NETHER_BLADESOUL("§8Bladesoul", 1), - NETHER_MAGMA_BOSS("§4Magma Boss", 1), - NETHER_ASHFANG("§cAshfang", 1), - NETHER_BARBARIAN_DUKE("§eBarbarian Duke", 1), - NETHER_MAGE_OUTLAW("§5Mage Outlaw", 1), - - NETHER_VANQUISHER("§5Vanquisher", 2), - - END_ENDSTONE_PROTECTOR("§cEndstone Protector", 3), - END_ENDER_DRAGON("Ender Dragon", 4),//TODO fix totally - - SLAYER_ZOMBIE_1("§aRevenant Horror 1", 5, "§aRev 1", showDeathTime = true), - SLAYER_ZOMBIE_2("§eRevenant Horror 2", 5, "§eRev 2", showDeathTime = true), - SLAYER_ZOMBIE_3("§cRevenant Horror 3", 5, "§cRev 3", showDeathTime = true), - SLAYER_ZOMBIE_4("§4Revenant Horror 4", 5, "§4Rev 4", showDeathTime = true), - SLAYER_ZOMBIE_5("§5Revenant Horror 5", 5, "§5Rev 5", showDeathTime = true), - - SLAYER_SPIDER_1("§aTarantula Broodfather 1", 6, "§aTara 1", showDeathTime = true), - SLAYER_SPIDER_2("§eTarantula Broodfather 2", 6, "§eTara 2", showDeathTime = true), - SLAYER_SPIDER_3("§cTarantula Broodfather 3", 6, "§cTara 3", showDeathTime = true), - SLAYER_SPIDER_4("§4Tarantula Broodfather 4", 6, "§4Tara 4", showDeathTime = true), - - SLAYER_WOLF_1("§aSven Packmaster 1", 7, "§aSven 1", showDeathTime = true), - SLAYER_WOLF_2("§eSven Packmaster 2", 7, "§eSven 2", showDeathTime = true), - SLAYER_WOLF_3("§cSven Packmaster 3", 7, "§cSven 3", showDeathTime = true), - SLAYER_WOLF_4("§4Sven Packmaster 4", 7, "§4Sven 4", showDeathTime = true), - - SLAYER_ENDERMAN_1("§aVoidgloom Seraph 1", 8, "§aVoid 1", showDeathTime = true), - SLAYER_ENDERMAN_2("§eVoidgloom Seraph 2", 8, "§eVoid 2", showDeathTime = true), - SLAYER_ENDERMAN_3("§cVoidgloom Seraph 3", 8, "§cVoid 3", showDeathTime = true), - SLAYER_ENDERMAN_4("§4Voidgloom Seraph 4", 8, "§4Void 4", showDeathTime = true), - - SLAYER_BLAZE_1("§aInferno Demonlord 1", 9, "§aInferno 1", showDeathTime = true), - SLAYER_BLAZE_2("§aInferno Demonlord 2", 9, "§aInferno 2", showDeathTime = true), - SLAYER_BLAZE_3("§aInferno Demonlord 3", 9, "§aInferno 3", showDeathTime = true), - SLAYER_BLAZE_4("§aInferno Demonlord 4", 9, "§aInferno 4", showDeathTime = true), - - SLAYER_BLAZE_TYPHOEUS_1("§aInferno Typhoeus 1", 9, "§aTyphoeus 1"), - SLAYER_BLAZE_TYPHOEUS_2("§eInferno Typhoeus 2", 9, "§eTyphoeus 2"), - SLAYER_BLAZE_TYPHOEUS_3("§cInferno Typhoeus 3", 9, "§cTyphoeus 3"), - SLAYER_BLAZE_TYPHOEUS_4("§cInferno Typhoeus 4", 9, "§cTyphoeus 4"), - - SLAYER_BLAZE_QUAZII_1("§aInferno Quazii 1", 9, "§aQuazii 1"), - SLAYER_BLAZE_QUAZII_2("§eInferno Quazii 2", 9, "§eQuazii 2"), - SLAYER_BLAZE_QUAZII_3("§cInferno Quazii 3", 9, "§cQuazii 3"), - SLAYER_BLAZE_QUAZII_4("§cInferno Quazii 4", 9, "§cQuazii 4"), - - SLAYER_BLOODFIEND_1("§aRiftstalker Bloodfiend 1", 23, "§aBlood 1", showDeathTime = true), - SLAYER_BLOODFIEND_2("§6Riftstalker Bloodfiend 2", 23, "§6Blood 2", showDeathTime = true), - SLAYER_BLOODFIEND_3("§cRiftstalker Bloodfiend 3", 23, "§cBlood 3", showDeathTime = true), - SLAYER_BLOODFIEND_4("§4Riftstalker Bloodfiend 4", 23, "§4Blood 4", showDeathTime = true), - SLAYER_BLOODFIEND_5("§5Riftstalker Bloodfiend 5", 23, "§5Blood 5", showDeathTime = true), - - HUB_HEADLESS_HORSEMAN("§6Headless Horseman", 10), - - DUNGEON_F1("", 11), - DUNGEON_F2("", 12), - DUNGEON_F3("", 13), - DUNGEON_F4_THORN("§cThorn", 14), - DUNGEON_F5("§dLivid", 15), - DUNGEON_F("", 16), - DUNGEON_75("", 17), - - MINOS_INQUISITOR("§5Minos Inquisitor", 18), - MINOS_CHAMPION("§2Minos Champion", 18), - GAIA_CONSTURUCT("§2Gaia Construct", 18), - MINOTAUR("§2Minotaur", 18), - - THUNDER("§cThunder", 19), - LORD_JAWBUS("§cLord Jawbus", 19), - - DUMMY("Dummy", 20), - ARACHNE_SMALL("§cSmall Arachne", 21), - ARACHNE_BIG("§4Big Arachne", 21), + NETHER_BLADESOUL("§8Bladesoul", Type.NETHER_MINI_BOSSES), + NETHER_MAGMA_BOSS("§4Magma Boss", Type.NETHER_MINI_BOSSES), + NETHER_ASHFANG("§cAshfang", Type.NETHER_MINI_BOSSES), + NETHER_BARBARIAN_DUKE("§eBarbarian Duke", Type.NETHER_MINI_BOSSES), + NETHER_MAGE_OUTLAW("§5Mage Outlaw", Type.NETHER_MINI_BOSSES), + + NETHER_VANQUISHER("§5Vanquisher", Type.VANQUISHER), + + END_ENDSTONE_PROTECTOR("§cEndstone Protector", Type.ENDERSTONE_PROTECTOR), + END_ENDER_DRAGON("Ender Dragon", Type.ENDER_DRAGON),//TODO fix totally + + SLAYER_ZOMBIE_1("§aRevenant Horror 1", Type.REVENANT_HORROR, "§aRev 1", showDeathTime = true), + SLAYER_ZOMBIE_2("§eRevenant Horror 2", Type.REVENANT_HORROR, "§eRev 2", showDeathTime = true), + SLAYER_ZOMBIE_3("§cRevenant Horror 3", Type.REVENANT_HORROR, "§cRev 3", showDeathTime = true), + SLAYER_ZOMBIE_4("§4Revenant Horror 4", Type.REVENANT_HORROR, "§4Rev 4", showDeathTime = true), + SLAYER_ZOMBIE_5("§5Revenant Horror 5", Type.REVENANT_HORROR, "§5Rev 5", showDeathTime = true), + + SLAYER_SPIDER_1("§aTarantula Broodfather 1", Type.TARANTULA_BROODFATHER, "§aTara 1", showDeathTime = true), + SLAYER_SPIDER_2("§eTarantula Broodfather 2", Type.TARANTULA_BROODFATHER, "§eTara 2", showDeathTime = true), + SLAYER_SPIDER_3("§cTarantula Broodfather 3", Type.TARANTULA_BROODFATHER, "§cTara 3", showDeathTime = true), + SLAYER_SPIDER_4("§4Tarantula Broodfather 4", Type.TARANTULA_BROODFATHER, "§4Tara 4", showDeathTime = true), + + SLAYER_WOLF_1("§aSven Packmaster 1", Type.SVEN_PACKMASTER, "§aSven 1", showDeathTime = true), + SLAYER_WOLF_2("§eSven Packmaster 2", Type.SVEN_PACKMASTER, "§eSven 2", showDeathTime = true), + SLAYER_WOLF_3("§cSven Packmaster 3", Type.SVEN_PACKMASTER, "§cSven 3", showDeathTime = true), + SLAYER_WOLF_4("§4Sven Packmaster 4", Type.SVEN_PACKMASTER, "§4Sven 4", showDeathTime = true), + + SLAYER_ENDERMAN_1("§aVoidgloom Seraph 1", Type.VOIDGLOOM_SERAPH, "§aVoid 1", showDeathTime = true), + SLAYER_ENDERMAN_2("§eVoidgloom Seraph 2", Type.VOIDGLOOM_SERAPH, "§eVoid 2", showDeathTime = true), + SLAYER_ENDERMAN_3("§cVoidgloom Seraph 3", Type.VOIDGLOOM_SERAPH, "§cVoid 3", showDeathTime = true), + SLAYER_ENDERMAN_4("§4Voidgloom Seraph 4", Type.VOIDGLOOM_SERAPH, "§4Void 4", showDeathTime = true), + + SLAYER_BLAZE_1("§aInferno Demonlord 1", Type.INFERNO_DEMONLORD, "§aInferno 1", showDeathTime = true), + SLAYER_BLAZE_2("§aInferno Demonlord 2", Type.INFERNO_DEMONLORD, "§aInferno 2", showDeathTime = true), + SLAYER_BLAZE_3("§aInferno Demonlord 3", Type.INFERNO_DEMONLORD, "§aInferno 3", showDeathTime = true), + SLAYER_BLAZE_4("§aInferno Demonlord 4", Type.INFERNO_DEMONLORD, "§aInferno 4", showDeathTime = true), + + SLAYER_BLAZE_TYPHOEUS_1("§aInferno Typhoeus 1", Type.INFERNO_DEMONLORD, "§aTyphoeus 1"), + SLAYER_BLAZE_TYPHOEUS_2("§eInferno Typhoeus 2", Type.INFERNO_DEMONLORD, "§eTyphoeus 2"), + SLAYER_BLAZE_TYPHOEUS_3("§cInferno Typhoeus 3", Type.INFERNO_DEMONLORD, "§cTyphoeus 3"), + SLAYER_BLAZE_TYPHOEUS_4("§cInferno Typhoeus 4", Type.INFERNO_DEMONLORD, "§cTyphoeus 4"), + + SLAYER_BLAZE_QUAZII_1("§aInferno Quazii 1", Type.INFERNO_DEMONLORD, "§aQuazii 1"), + SLAYER_BLAZE_QUAZII_2("§eInferno Quazii 2", Type.INFERNO_DEMONLORD, "§eQuazii 2"), + SLAYER_BLAZE_QUAZII_3("§cInferno Quazii 3", Type.INFERNO_DEMONLORD, "§cQuazii 3"), + SLAYER_BLAZE_QUAZII_4("§cInferno Quazii 4", Type.INFERNO_DEMONLORD, "§cQuazii 4"), + + SLAYER_BLOODFIEND_1("§aRiftstalker Bloodfiend 1", Type.RIFTSTALKER_BLOODFIEND, "§aBlood 1", showDeathTime = true), + SLAYER_BLOODFIEND_2("§6Riftstalker Bloodfiend 2", Type.RIFTSTALKER_BLOODFIEND, "§6Blood 2", showDeathTime = true), + SLAYER_BLOODFIEND_3("§cRiftstalker Bloodfiend 3", Type.RIFTSTALKER_BLOODFIEND, "§cBlood 3", showDeathTime = true), + SLAYER_BLOODFIEND_4("§4Riftstalker Bloodfiend 4", Type.RIFTSTALKER_BLOODFIEND, "§4Blood 4", showDeathTime = true), + SLAYER_BLOODFIEND_5("§5Riftstalker Bloodfiend 5", Type.RIFTSTALKER_BLOODFIEND, "§5Blood 5", showDeathTime = true), + + HUB_HEADLESS_HORSEMAN("§6Headless Horseman", Type.HEADLESS_HORSEMAN), + + DUNGEON_F1("", Type.DUNGEON_FLOOR_1), + DUNGEON_F2("", Type.DUNGEON_FLOOR_2), + DUNGEON_F3("", Type.DUNGEON_FLOOR_3), + DUNGEON_F4_THORN("§cThorn", Type.DUNGEON_FLOOR_4), + DUNGEON_F5("§dLivid", Type.DUNGEON_FLOOR_5), + DUNGEON_F("", Type.DUNGEON_FLOOR_6), + DUNGEON_75("", Type.DUNGEON_FLOOR_7), + + MINOS_INQUISITOR("§5Minos Inquisitor", Type.DIANA_MOBS), + MINOS_CHAMPION("§2Minos Champion", Type.DIANA_MOBS), + GAIA_CONSTURUCT("§2Gaia Construct", Type.DIANA_MOBS), + MINOTAUR("§2Minotaur", Type.DIANA_MOBS), + + THUNDER("§cThunder", Type.SEA_CREATURES), + LORD_JAWBUS("§cLord Jawbus", Type.SEA_CREATURES), + + DUMMY("Dummy", Type.DUMMY), + ARACHNE_SMALL("§cSmall Arachne", Type.ARACHNE), + ARACHNE_BIG("§4Big Arachne", Type.ARACHNE), // The Rift - LEECH_SUPREME("§cLeech Supreme", 22), - BACTE("§aBacte", 22), - - WINTER_REINDRAKE("Reindrake", 24),//TODO fix totally + LEECH_SUPREME("§cLeech Supreme", Type.THE_RIFT_BOSSES), + BACTE("§aBacte", Type.THE_RIFT_BOSSES), + + WINTER_REINDRAKE("Reindrake", Type.REINDRAKE),//TODO fix totally + + GARDEN_PEST_BEETLE("§cBeetle", Type.GARDEN_PESTS), + GARDEN_PEST_CRICKET("§cCricket", Type.GARDEN_PESTS), + GARDEN_PEST_FLY("§cFly", Type.GARDEN_PESTS), + GARDEN_PEST_LOCUST("§cLocust", Type.GARDEN_PESTS), + GARDEN_PEST_MITE("§cMite", Type.GARDEN_PESTS), + GARDEN_PEST_MOSQUITO("§cMosquito", Type.GARDEN_PESTS), + GARDEN_PEST_MOTH("§cMoth", Type.GARDEN_PESTS), + GARDEN_PEST_RAT("§cRat", Type.GARDEN_PESTS), + GARDEN_PEST_SLUG("§cSlug", Type.GARDEN_PESTS), + GARDEN_PEST_EARTHWORM("§cEarthworm", Type.GARDEN_PESTS), //TODO arachne @@ -108,4 +123,4 @@ enum class BossType( */ //TODO diana mythological creatures -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/DamageIndicatorManager.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/DamageIndicatorManager.kt index ebe6e9397..b12f48cba 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/DamageIndicatorManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/DamageIndicatorManager.kt @@ -2,10 +2,13 @@ package at.hannibal2.skyhanni.features.combat.damageindicator import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator +import at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry import at.hannibal2.skyhanni.data.ScoreboardData import at.hannibal2.skyhanni.events.BossHealthChangeEvent +import at.hannibal2.skyhanni.events.DamageIndicatorDeathEvent import at.hannibal2.skyhanni.events.DamageIndicatorDetectedEvent import at.hannibal2.skyhanni.events.DamageIndicatorFinalBossEvent +import at.hannibal2.skyhanni.events.EntityHealthUpdateEvent import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent import at.hannibal2.skyhanni.events.LorenzTickEvent @@ -14,7 +17,9 @@ import at.hannibal2.skyhanni.features.dungeon.DungeonAPI import at.hannibal2.skyhanni.features.slayer.blaze.HellionShield import at.hannibal2.skyhanni.features.slayer.blaze.setHellionShield import at.hannibal2.skyhanni.test.command.ErrorManager +import at.hannibal2.skyhanni.utils.ConfigUtils import at.hannibal2.skyhanni.utils.EntityUtils +import at.hannibal2.skyhanni.utils.EntityUtils.canBeSeen import at.hannibal2.skyhanni.utils.EntityUtils.getNameTagWith import at.hannibal2.skyhanni.utils.EntityUtils.hasNameTagWith import at.hannibal2.skyhanni.utils.LocationUtils @@ -157,7 +162,7 @@ class DamageIndicatorManager { // data.ignoreBlocks = // data.bossType == BossType.END_ENDSTONE_PROTECTOR && Minecraft.getMinecraft().thePlayer.isSneaking - if (!data.ignoreBlocks && !player.canEntityBeSeen(data.entity)) continue + if (!data.ignoreBlocks && !data.entity.canBeSeen(70.0)) continue if (!data.isConfigEnabled()) continue val entity = data.entity @@ -852,10 +857,24 @@ class DamageIndicatorManager { } @SubscribeEvent + fun onEntityHealthUpdate(event: EntityHealthUpdateEvent) { + val data = data[event.entity.uniqueID] ?: return + if (event.health <= 1) { + if (!data.firstDeath) { + data.firstDeath = true + DamageIndicatorDeathEvent(event.entity, data).postAndCatch() + } + } + } + + @SubscribeEvent fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { event.move(2, "damageIndicator", "combat.damageIndicator") event.move(3, "slayer.endermanPhaseDisplay", "slayer.endermen.phaseDisplay") event.move(3, "slayer.blazePhaseDisplay", "slayer.blazes.phaseDisplay") + event.move(11, "combat.damageIndicator.bossesToShow", "combat.damageIndicator.bossesToShow") { element -> + ConfigUtils.migrateIntArrayListToEnumArrayList(element, DamageIndicatorBossEntry::class.java) + } } fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/EntityData.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/EntityData.kt index 970bdd0dd..50e5b4547 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/EntityData.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/EntityData.kt @@ -21,10 +21,11 @@ class EntityData( var nameSuffix: String = "", var nameAbove: String = "", var dead: Boolean = false, + var firstDeath: Boolean = false, // TODO this defines if hp is very low, replace dead with this later var deathLocation: LorenzVec? = null, ) { val timeToKill by lazy { val duration = System.currentTimeMillis() - foundTime "§e" + TimeUtils.formatDuration(duration, TimeUnit.SECOND, showMilliSeconds = true) } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/MobFinder.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/MobFinder.kt index 6cc9b4b85..0d39c0233 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/MobFinder.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/MobFinder.kt @@ -3,6 +3,8 @@ package at.hannibal2.skyhanni.features.combat.damageindicator import at.hannibal2.skyhanni.data.IslandType import at.hannibal2.skyhanni.features.dungeon.DungeonAPI import at.hannibal2.skyhanni.features.dungeon.DungeonLividFinder +import at.hannibal2.skyhanni.features.garden.GardenAPI +import at.hannibal2.skyhanni.features.garden.pests.PestType import at.hannibal2.skyhanni.features.rift.RiftAPI import at.hannibal2.skyhanni.utils.EntityUtils import at.hannibal2.skyhanni.utils.EntityUtils.hasBossHealth @@ -14,7 +16,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.baseMaxHealth import at.hannibal2.skyhanni.utils.LorenzUtils.derpy import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland import at.hannibal2.skyhanni.utils.LorenzVec -import at.hannibal2.skyhanni.utils.StringUtils.matchRegex +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.getLorenzVec import net.minecraft.client.entity.EntityOtherPlayerMP import net.minecraft.entity.Entity @@ -30,10 +32,12 @@ import net.minecraft.entity.monster.EntityGuardian import net.minecraft.entity.monster.EntityIronGolem import net.minecraft.entity.monster.EntityMagmaCube import net.minecraft.entity.monster.EntityPigZombie +import net.minecraft.entity.monster.EntitySilverfish import net.minecraft.entity.monster.EntitySkeleton import net.minecraft.entity.monster.EntitySlime import net.minecraft.entity.monster.EntitySpider import net.minecraft.entity.monster.EntityZombie +import net.minecraft.entity.passive.EntityBat import net.minecraft.entity.passive.EntityHorse import net.minecraft.entity.passive.EntityWolf import java.util.UUID @@ -67,6 +71,8 @@ class MobFinder { //F5 private var floor5lividEntity: EntityOtherPlayerMP? = null private var floor5lividEntitySpawnTime = 0L + private val correctLividPattern = + "§c\\[BOSS] (.*) Livid§r§f: Impossible! How did you figure out which one I was\\?!".toPattern() //F6 private var floor6Giants = false @@ -78,6 +84,7 @@ class MobFinder { internal fun tryAdd(entity: EntityLivingBase) = when { LorenzUtils.inDungeons -> tryAddDungeon(entity) RiftAPI.inRift() -> tryAddRift(entity) + GardenAPI.inGarden() -> tryAddGarden(entity) else -> { when (entity) { /* @@ -106,6 +113,22 @@ class MobFinder { } } + private fun tryAddGarden(entity: EntityLivingBase): EntityResult? { + if (entity is EntitySilverfish || entity is EntityBat) { + return tryAddGardenPest(entity) + } + + return null + } + + private fun tryAddGardenPest(entity: EntityLivingBase): EntityResult? { + if (!GardenAPI.inGarden()) return null + + return PestType.entries + .firstOrNull { entity.hasNameTagWith(3, it.displayName) } + ?.let { EntityResult(bossType = it.damageIndicatorBoss) } + } + private fun tryAddDungeon(entity: EntityLivingBase) = when { DungeonAPI.isOneOf("F1", "M1") -> tryAddDungeonF1(entity) DungeonAPI.isOneOf("F2", "M2") -> tryAddDungeonF2(entity) @@ -566,7 +589,7 @@ class MobFinder { } } - if (message.matchRegex("§c\\[BOSS] (.*) Livid§r§f: Impossible! How did you figure out which one I was\\?!")) { + correctLividPattern.matchMatcher(message) { floor5lividEntity = null } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/endernodetracker/EnderNodeTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/endernodetracker/EnderNodeTracker.kt index b65021067..51f9a7e8b 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/combat/endernodetracker/EnderNodeTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/combat/endernodetracker/EnderNodeTracker.kt @@ -2,6 +2,7 @@ package at.hannibal2.skyhanni.features.combat.endernodetracker import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator +import at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry import at.hannibal2.skyhanni.data.IslandType import at.hannibal2.skyhanni.data.ProfileStorageData import at.hannibal2.skyhanni.events.ConfigLoadEvent @@ -10,6 +11,7 @@ import at.hannibal2.skyhanni.events.IslandChangeEvent import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.OwnInventoryItemUpdateEvent import at.hannibal2.skyhanni.events.SackChangeEvent +import at.hannibal2.skyhanni.utils.ConfigUtils import at.hannibal2.skyhanni.utils.ItemUtils.getInternalNameOrNull import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList @@ -22,7 +24,6 @@ import at.hannibal2.skyhanni.utils.NumberUtil.format import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker import at.hannibal2.skyhanni.utils.tracker.TrackerData import com.google.gson.annotations.Expose -import io.github.moulberry.notenoughupdates.util.MinecraftExecutor import net.minecraft.client.Minecraft import net.minecraftforge.fml.common.eventhandler.SubscribeEvent @@ -128,18 +129,16 @@ object EnderNodeTracker { if (!isInTheEnd()) return if (!ProfileStorageData.loaded) return - MinecraftExecutor.OnThread.execute { - val newMiteGelInInventory = Minecraft.getMinecraft().thePlayer.inventory.mainInventory - .filter { it?.getInternalNameOrNull() == EnderNode.MITE_GEL.internalName } - .sumOf { it.stackSize } - val change = newMiteGelInInventory - miteGelInInventory - if (change > 0) { - tracker.modify { storage -> - storage.lootCount.addOrPut(EnderNode.MITE_GEL, change) - } + val newMiteGelInInventory = Minecraft.getMinecraft().thePlayer.inventory.mainInventory + .filter { it?.getInternalNameOrNull() == EnderNode.MITE_GEL.internalName } + .sumOf { it.stackSize } + val change = newMiteGelInInventory - miteGelInInventory + if (change > 0) { + tracker.modify { storage -> + storage.lootCount.addOrPut(EnderNode.MITE_GEL, change) } - miteGelInInventory = newMiteGelInInventory } + miteGelInInventory = newMiteGelInInventory } @SubscribeEvent @@ -161,6 +160,9 @@ object EnderNodeTracker { @SubscribeEvent fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { event.move(2, "misc.enderNodeTracker", "combat.enderNodeTracker") + event.move(11, "combat.enderNodeTracker.textFormat", "combat.enderNodeTracker.textFormat") { element -> + ConfigUtils.migrateIntArrayListToEnumArrayList(element, EnderNodeDisplayEntry::class.java) + } } private fun calculateProfit(storage: Data): Map<EnderNode, Double> { @@ -245,7 +247,8 @@ object EnderNodeTracker { val newList = mutableListOf<List<Any>>() for (index in config.textFormat.get()) { - newList.add(map[index]) + // TODO, change functionality to use enum rather than ordinals + newList.add(map[index.ordinal]) } return newList } diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostCounter.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostCounter.kt index 56e70437c..eb9b68643 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostCounter.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostCounter.kt @@ -2,6 +2,7 @@ package at.hannibal2.skyhanni.features.combat.ghostcounter import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator +import at.hannibal2.skyhanni.config.features.combat.ghostcounter.GhostCounterConfig.GhostDisplayEntry import at.hannibal2.skyhanni.data.IslandType import at.hannibal2.skyhanni.data.ProfileStorageData import at.hannibal2.skyhanni.data.SkillExperience @@ -34,6 +35,7 @@ import at.hannibal2.skyhanni.utils.CombatUtils.lastKillUpdate import at.hannibal2.skyhanni.utils.CombatUtils.lastUpdate import at.hannibal2.skyhanni.utils.CombatUtils.xpGainHour import at.hannibal2.skyhanni.utils.CombatUtils.xpGainHourLast +import at.hannibal2.skyhanni.utils.ConfigUtils import at.hannibal2.skyhanni.utils.ItemUtils.getLore import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList @@ -111,7 +113,8 @@ object GhostCounter { private fun formatDisplay(map: List<List<Any>>): List<List<Any>> { val newList = mutableListOf<List<Any>>() for (index in config.ghostDisplayText) { - newList.add(map[index]) + // TODO, change functionality to use enum rather than ordinals + newList.add(map[index.ordinal]) } return newList } @@ -488,6 +491,9 @@ object GhostCounter { @SubscribeEvent fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { event.move(2, "ghostCounter", "combat.ghostCounter") + event.move(11, "combat.ghostCounter.ghostDisplayText", "combat.ghostCounter.ghostDisplayText") { element -> + ConfigUtils.migrateIntArrayListToEnumArrayList(element, GhostDisplayEntry::class.java) + } } fun isEnabled() = config.enabled && IslandType.DWARVEN_MINES.isInIsland() diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostFormatting.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostFormatting.kt index 70f64de29..183753e51 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostFormatting.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostFormatting.kt @@ -138,7 +138,7 @@ object GhostFormatting { fun reset() { with(GhostCounter.config.textFormatting) { titleFormat = "&6Ghost Counter" - ghostKilledFormat = " &6Ghost Killed: &b%value% &7(%session%)" + ghostKilledFormat = " &6Ghosts Killed: &b%value% &7(%session%)" sorrowsFormat = " &6Sorrow: &b%value% &7(%session%)" ghostSinceSorrowFormat = " &6Ghost since Sorrow: &b%value%" ghostKillPerSorrowFormat = " &6Ghosts/Sorrow: &b%value%" @@ -179,4 +179,4 @@ object GhostFormatting { moneyMadeFormat = " &6Money made: &b%value%" } } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/commands/SendCoordinatedCommand.kt b/src/main/java/at/hannibal2/skyhanni/features/commands/SendCoordinatedCommand.kt index 8cc303fcf..a41547c68 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/commands/SendCoordinatedCommand.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/commands/SendCoordinatedCommand.kt @@ -1,26 +1,22 @@ package at.hannibal2.skyhanni.features.commands -import at.hannibal2.skyhanni.events.PacketEvent +import at.hannibal2.skyhanni.events.MessageSendToServerEvent import at.hannibal2.skyhanni.utils.LocationUtils import at.hannibal2.skyhanni.utils.LorenzUtils -import net.minecraft.network.play.client.C01PacketChatMessage import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class SendCoordinatedCommand { @SubscribeEvent - fun onSendPacket(event: PacketEvent.SendEvent) { - val packet = event.packet - if (packet is C01PacketChatMessage) { - val message = packet.message.lowercase() - if (message == "/sendcoords") { - event.isCanceled = true - LorenzUtils.sendMessageToServer(getCoordinates()) - } else if (message.startsWith("/sendcoords ")) { - event.isCanceled = true - val description = message.split(" ").drop(1).joinToString(" ") - LorenzUtils.sendMessageToServer("${getCoordinates()} $description") - } + fun onMessageSendToServer(event: MessageSendToServerEvent) { + val message = event.message + if (message == "/sendcoords") { + event.isCanceled = true + LorenzUtils.sendMessageToServer(getCoordinates()) + } else if (message.startsWith("/sendcoords ")) { + event.isCanceled = true + val description = message.split(" ").drop(1).joinToString(" ") + LorenzUtils.sendMessageToServer("${getCoordinates()} $description") } } @@ -32,5 +28,4 @@ class SendCoordinatedCommand { return "x: $x, y: $y, z: $z" } - -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/commands/ViewRecipeCommand.kt b/src/main/java/at/hannibal2/skyhanni/features/commands/ViewRecipeCommand.kt index 4464959e2..147775fed 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/commands/ViewRecipeCommand.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/commands/ViewRecipeCommand.kt @@ -1,26 +1,22 @@ package at.hannibal2.skyhanni.features.commands import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.PacketEvent +import at.hannibal2.skyhanni.events.MessageSendToServerEvent import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.NEUItems -import net.minecraft.network.play.client.C01PacketChatMessage import net.minecraftforge.fml.common.eventhandler.SubscribeEvent object ViewRecipeCommand { private val config get() = SkyHanniMod.feature.commands @SubscribeEvent - fun onSendPacket(event: PacketEvent.SendEvent) { + fun onMessageSendToServer(event: MessageSendToServerEvent) { if (!config.viewRecipeLowerCase) return - val packet = event.packet - if (packet is C01PacketChatMessage) { - val message = packet.message - if (message == message.uppercase()) return - if (message.startsWith("/viewrecipe ", ignoreCase = true)) { - event.isCanceled = true - LorenzUtils.sendMessageToServer(message.uppercase()) - } + val message = event.message + if (message == message.uppercase()) return + if (message.startsWith("/viewrecipe ", ignoreCase = true)) { + event.isCanceled = true + LorenzUtils.sendMessageToServer(message.uppercase()) } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/commands/WarpIsCommand.kt b/src/main/java/at/hannibal2/skyhanni/features/commands/WarpIsCommand.kt index eb9ea503e..4cb06b568 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/commands/WarpIsCommand.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/commands/WarpIsCommand.kt @@ -1,22 +1,20 @@ package at.hannibal2.skyhanni.features.commands import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.PacketEvent +import at.hannibal2.skyhanni.events.MessageSendToServerEvent import at.hannibal2.skyhanni.utils.LorenzUtils -import net.minecraft.network.play.client.C01PacketChatMessage import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class WarpIsCommand { @SubscribeEvent - fun onSendPacket(event: PacketEvent.SendEvent) { + fun onMessageSendToServer(event: MessageSendToServerEvent) { if (!LorenzUtils.inSkyBlock) return if (!SkyHanniMod.feature.commands.replaceWarpIs) return - val packet = event.packet - if (packet is C01PacketChatMessage && packet.message.lowercase() == "/warp is") { + if (event.message.lowercase() == "/warp is") { event.isCanceled = true LorenzUtils.sendMessageToServer("/is") } } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/commands/WikiManager.kt b/src/main/java/at/hannibal2/skyhanni/features/commands/WikiManager.kt index de7cc4408..b3bdbe42c 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/commands/WikiManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/commands/WikiManager.kt @@ -2,7 +2,7 @@ package at.hannibal2.skyhanni.features.commands import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator -import at.hannibal2.skyhanni.events.PacketEvent +import at.hannibal2.skyhanni.events.MessageSendToServerEvent import at.hannibal2.skyhanni.utils.InventoryUtils import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName import at.hannibal2.skyhanni.utils.ItemUtils.nameWithEnchantment @@ -13,7 +13,6 @@ import at.hannibal2.skyhanni.utils.OSUtils import at.hannibal2.skyhanni.utils.StringUtils.removeColor import net.minecraft.client.gui.inventory.GuiContainer import net.minecraft.item.ItemStack -import net.minecraft.network.play.client.C01PacketChatMessage import net.minecraftforge.client.event.GuiScreenEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent @@ -32,29 +31,25 @@ class WikiManager { } @SubscribeEvent - fun onSendPacket(event: PacketEvent.SendEvent) { + fun onMessageSendToServer(event: MessageSendToServerEvent) { if (!LorenzUtils.inSkyBlock) return if (!isEnabled()) return - val packet = event.packet - - if (packet is C01PacketChatMessage) { - val message = packet.message.lowercase() - if (!(message.startsWith("/wiki"))) return - event.isCanceled = true - if (message == "/wiki") { - LorenzUtils.chat("Opening the Fandom Wiki..") - OSUtils.openBrowser("${urlPrefix}Hypixel_SkyBlock_Wiki") - } else if (message.startsWith("/wiki ") || message == ("/wikithis")) { //conditional to see if we need Special:Search page - if (message == ("/wikithis")) { - val itemInHand = InventoryUtils.getItemInHand() ?: return - wikiTheItem(itemInHand) - } else { - val search = packet.message.split("/wiki ").last() - LorenzUtils.chat("Searching the Fandom Wiki for §a$search") - val wikiUrlCustom = "$urlSearchPrefix$search&scope=internal" - OSUtils.openBrowser(wikiUrlCustom.replace(' ', '+')) - } + val message = event.message.lowercase() + if (!(message.startsWith("/wiki"))) return + event.isCanceled = true + if (message == "/wiki") { + LorenzUtils.chat("Opening the Fandom Wiki..") + OSUtils.openBrowser("${urlPrefix}Hypixel_SkyBlock_Wiki") + } else if (message.startsWith("/wiki ") || message == ("/wikithis")) { //conditional to see if we need Special:Search page + if (message == ("/wikithis")) { + val itemInHand = InventoryUtils.getItemInHand() ?: return + wikiTheItem(itemInHand) + } else { + val search = event.message.split("/wiki ").last() + LorenzUtils.chat("Searching the Fandom Wiki for §a$search") + val wikiUrlCustom = "$urlSearchPrefix$search&scope=internal" + OSUtils.openBrowser(wikiUrlCustom.replace(' ', '+')) } } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/GetFromSacksTabComplete.kt b/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/GetFromSacksTabComplete.kt index 97a110508..f3738c6b4 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/GetFromSacksTabComplete.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/GetFromSacksTabComplete.kt @@ -1,11 +1,10 @@ package at.hannibal2.skyhanni.features.commands.tabcomplete import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.PacketEvent +import at.hannibal2.skyhanni.data.jsonobjects.repo.SacksJson +import at.hannibal2.skyhanni.events.MessageSendToServerEvent import at.hannibal2.skyhanni.events.RepositoryReloadEvent import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.jsonobjects.SacksJson -import net.minecraft.network.play.client.C01PacketChatMessage import net.minecraftforge.fml.common.eventhandler.SubscribeEvent object GetFromSacksTabComplete { @@ -26,19 +25,18 @@ object GetFromSacksTabComplete { } @SubscribeEvent - fun onSendPacket(event: PacketEvent.SendEvent) { + fun onMessageSendToServer(event: MessageSendToServerEvent) { if (!isEnabled()) return - val packet = event.packet as? C01PacketChatMessage ?: return - val message = packet.message - if (commands.any { message.startsWith("/$it ") }) { - val rawName = message.split(" ")[1] - val realName = rawName.replace("_", " ") - if (realName == rawName) return - if (realName !in sackList) return - event.isCanceled = true - LorenzUtils.sendMessageToServer(message.replace(rawName, realName)) - } + val message = event.message + if (!commands.any { message.startsWith("/$it ") }) return + + val rawName = message.split(" ")[1] + val realName = rawName.replace("_", " ") + if (realName == rawName) return + if (realName !in sackList) return + event.isCanceled = true + LorenzUtils.sendMessageToServer(message.replace(rawName, realName)) } fun isEnabled() = LorenzUtils.inSkyBlock && config.gfsSack diff --git a/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/PlayerTabComplete.kt b/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/PlayerTabComplete.kt index e6b2baaf8..9df128920 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/PlayerTabComplete.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/PlayerTabComplete.kt @@ -6,7 +6,7 @@ import at.hannibal2.skyhanni.data.FriendAPI import at.hannibal2.skyhanni.data.PartyAPI import at.hannibal2.skyhanni.events.RepositoryReloadEvent import at.hannibal2.skyhanni.utils.EntityUtils.isNPC -import at.hannibal2.skyhanni.utils.jsonobjects.VipVisitsJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.VipVisitsJson import net.minecraft.client.Minecraft import net.minecraft.client.entity.EntityOtherPlayerMP import net.minecraftforge.fml.common.eventhandler.SubscribeEvent diff --git a/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/WarpTabComplete.kt b/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/WarpTabComplete.kt index ea76e03ea..c5487fdb8 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/WarpTabComplete.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/WarpTabComplete.kt @@ -3,7 +3,7 @@ package at.hannibal2.skyhanni.features.commands.tabcomplete import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.RepositoryReloadEvent import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.jsonobjects.WarpsJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.WarpsJson import net.minecraftforge.fml.common.eventhandler.SubscribeEvent object WarpTabComplete { diff --git a/src/main/java/at/hannibal2/skyhanni/features/cosmetics/CosmeticFollowingLine.kt b/src/main/java/at/hannibal2/skyhanni/features/cosmetics/CosmeticFollowingLine.kt index 662ad68a0..022ec07b9 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/cosmetics/CosmeticFollowingLine.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/cosmetics/CosmeticFollowingLine.kt @@ -69,7 +69,7 @@ class CosmeticFollowingLine { } private fun updateClose(event: LorenzRenderWorldEvent) { - val playerLocation = event.exactLocation(Minecraft.getMinecraft().thePlayer).add(0.0, 0.3, 0.0) + val playerLocation = event.exactLocation(Minecraft.getMinecraft().thePlayer).add(y = 0.3) latestLocations = latestLocations.editCopy { val locationSpot = LocationSpot(SimpleTimeMark.now(), Minecraft.getMinecraft().thePlayer.onGround) @@ -110,7 +110,7 @@ class CosmeticFollowingLine { } if (event.isMod(2)) { - val playerLocation = LocationUtils.playerLocation().add(0.0, 0.3, 0.0) + val playerLocation = LocationUtils.playerLocation().add(y = 0.3) locations.keys.lastOrNull()?.let { if (it.distance(playerLocation) < 0.1) return diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonAPI.kt index 8bbf2a015..2840565df 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonAPI.kt @@ -16,7 +16,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.addOrPut import at.hannibal2.skyhanni.utils.LorenzUtils.equalsOneOf import at.hannibal2.skyhanni.utils.LorenzUtils.getOrNull import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber -import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded +import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.StringUtils.removeColor import at.hannibal2.skyhanni.utils.TabListData @@ -115,7 +115,7 @@ class DungeonAPI { DungeonClass.entries.forEach { if (playerTeam.contains("(${it.scoreboardName} ")) { - val level = playerTeam.split(" ").last().trimEnd(')').romanToDecimalIfNeeded() + val level = playerTeam.split(" ").last().trimEnd(')').romanToDecimalIfNecessary() playerClass = it playerClassLevel = level } diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonBossMessages.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonBossMessages.kt index b49839471..86d64b416 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonBossMessages.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonBossMessages.kt @@ -3,11 +3,46 @@ package at.hannibal2.skyhanni.features.dungeon import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.StringUtils.matchRegex +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class DungeonBossMessages { + private val config get() = SkyHanniMod.feature.chat + private val bossPattern = "§([cd4])\\[BOSS] (.*)".toPattern() + + private val excludedMessages = listOf( + "§c[BOSS] The Watcher§r§f: You have proven yourself. You may pass." + ) + + private val messageList = listOf( + //M7 – Dragons + "§cThe Crystal withers your soul as you hold it in your hands!", + "§cIt doesn't seem like that is supposed to go there." + ) + + private val messageContainsList = listOf( + " The Watcher§r§f: ", + " Bonzo§r§f: ", + " Scarf§r§f:", + "Professor§r§f", + " Livid§r§f: ", + " Enderman§r§f: ", + " Thorn§r§f: ", + " Sadan§r§f: ", + " Maxor§r§c: ", + " Storm§r§c: ", + " Goldor§r§c: ", + " Necron§r§c: ", + " §r§4§kWither King§r§c:" + ) + + private val messageEndsWithList = listOf( + " Necron§r§c: That is enough, fool!", + " Necron§r§c: Adventurers! Be careful of who you are messing with..", + " Necron§r§c: Before I have to deal with you myself." + ) + @SubscribeEvent fun onChatMessage(event: LorenzChatEvent) { if (!LorenzUtils.inDungeons) return @@ -15,40 +50,31 @@ class DungeonBossMessages { DungeonAPI.handleBossMessage(event.message) - if (SkyHanniMod.feature.chat.dungeonBossMessages) { + if (config.dungeonBossMessages) { event.blockedReason = "dungeon_boss" } } + /** + * Checks if the message is a boss message + * @return true if the message is a boss message + * @param message The message to check + * @see excludedMessages + * @see messageList + * @see messageContainsList + * @see messageEndsWithList + */ private fun isBoss(message: String): Boolean { - when { - message.matchRegex("§([cd4])\\[BOSS] (.*)") -> { - when { - message.contains(" The Watcher§r§f: ") -> - message != "§c[BOSS] The Watcher§r§f: You have proven yourself. You may pass." - - message.contains(" Bonzo§r§f: ") -> return true - message.contains(" Scarf§r§f:") -> return true - message.contains("Professor§r§f") -> return true - message.contains(" Livid§r§f: ") || message.contains(" Enderman§r§f: ") -> return true - message.contains(" Thorn§r§f: ") -> return true - message.contains(" Sadan§r§f: ") -> return true - message.contains(" Maxor§r§c: ") -> return true - message.contains(" Storm§r§c: ") -> return true - message.contains(" Goldor§r§c: ") -> return true - message.contains(" Necron§r§c: ") -> return true - message.contains(" §r§4§kWither King§r§c:") -> return true - - message.endsWith(" Necron§r§c: That is enough, fool!") -> return true - message.endsWith(" Necron§r§c: Adventurers! Be careful of who you are messing with..") -> return true - message.endsWith(" Necron§r§c: Before I have to deal with you myself.") -> return true - } - } - - //M7 – Dragons - message == "§cThe Crystal withers your soul as you hold it in your hands!" -> return true - message == "§cIt doesn't seem like that is supposed to go there." -> return true + // Cases that match below but should not be blocked + if (message in excludedMessages) return false + + // Exact Matches + if (message in messageList) return true + + // Matches Regex for Boss Prefix + bossPattern.matchMatcher(message) { + return messageContainsList.any { message.contains(it) } || messageEndsWithList.any { message.endsWith(it) } } return false } -}
\ No newline at end of file +} 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 5559ba14a..4bc4b3c46 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonChatFilter.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonChatFilter.kt @@ -3,18 +3,198 @@ package at.hannibal2.skyhanni.features.dungeon import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.StringUtils.matchRegex +import at.hannibal2.skyhanni.utils.StringUtils.matches import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.util.regex.Pattern class DungeonChatFilter { + private val config get() = SkyHanniMod.feature.chat + + /// <editor-fold desc="Patterns, Messages, and Maps"> + // TODO USE SH-REPO + private val endPatterns = listOf( + "(.*) §r§eunlocked §r§d(.*) Essence §r§8x(.*)§r§e!".toPattern(), + " {4}§r§d(.*) Essence §r§8x(.*)".toPattern() + ) + private val endMessagesEndWith = listOf( + " Experience §r§b(Team Bonus)" + ) + private val abilityPatterns = listOf( + "§7Your Guided Sheep hit §r§c(.*) §r§7enemy for §r§c(.*) §r§7damage.".toPattern(), + "§a§lBUFF! §fYou were splashed by (.*) §fwith §r§cHealing VIII§r§f!".toPattern(), + "§aYou were healed for (.*) health by (.*)§a!".toPattern(), + "§aYou gained (.*) HP worth of absorption for 3s from §r(.*)§r§a!".toPattern(), + "§c(.*) §r§epicked up your (.*) Orb!".toPattern(), + "§cThis ability is on cooldown for (.*)s.".toPattern(), + "§a§l(.*) healed you for (.*) health!".toPattern(), + "§eYour bone plating reduced the damage you took by §r§c(.*)§r§e!".toPattern(), + "(.*) §r§eformed a tether with you!".toPattern(), + "§eYour tether with (.*) §r§ehealed you for §r§a(.*) §r§ehealth.".toPattern(), + "§7Your Implosion hit §r§c(.*) §r§7enemy for §r§c(.*) §r§7damage.".toPattern(), + "§eYour §r§6Spirit Pet §r§ehealed (.*) §r§efor §r§a(.*) §r§ehealth!".toPattern(), + "§eYour §r§6Spirit Pet §r§ehit (.*) enemy for §r§c(.*) §r§edamage.".toPattern(), + "§cYou need at least (.*) mana to activate this!".toPattern(), + "§eYou were healed for §r§a(.*)§r§e health by §r(.*)§r§e's §r§9Healing Bow§r§e and gained §r§c\\+(.*) Strength§r§e for 10 seconds.".toPattern(), + "(.*)§r§a granted you §r§c(.*) §r§astrength for §r§e20 §r§aseconds!".toPattern(), + "§eYour fairy healed §r§ayourself §r§efor §r§a(.*) §r§ehealth!".toPattern(), + "§eYour fairy healed §r(.*) §r§efor §r§a(.*) §r§ehealth!".toPattern(), + "(.*) fairy healed you for §r§a(.*) §r§ehealth!".toPattern() + ) + private val abilityMessages = listOf( + "§a§r§6Guided Sheep §r§ais now available!", + "§dCreeper Veil §r§aActivated!", + "§dCreeper Veil §r§cDe-activated!", + "§6Rapid Fire§r§a is ready to use! Press §r§6§lDROP§r§a to activate it!", + "§6Castle of Stone§r§a is ready to use! Press §r§6§lDROP§r§a to activate it!", + "§6Ragnarok§r§a is ready to use! Press §r§6§lDROP§r§a to activate it!" + ) + private val damagePatterns = listOf( + "(.*) §r§aused §r(.*) §r§aon you!".toPattern(), + "§cThe (.*)§r§c struck you for (.*) damage!".toPattern(), + "§cThe (.*) hit you for (.*) damage!".toPattern(), + "§7(.*) struck you for §r§c(.*)§r§7 damage.".toPattern(), + "(.*) hit you for §r§c(.*)§r§7 damage.".toPattern(), + "(.*) hit you for §r§c(.*)§r§7 true damage.".toPattern(), + "§7(.*) exploded, hitting you for §r§c(.*)§r§7 damage.".toPattern(), + "(.*)§r§c hit you with §r(.*) §r§cfor (.*) damage!".toPattern(), + "(.*)§r§a struck you for §r§c(.*)§r§a damage!".toPattern(), + "(.*)§r§c struck you for (.*)!".toPattern(), + "§7The Mage's Magma burnt you for §r§c(.*)§r§7 true damage.".toPattern(), + "§7Your (.*) hit §r§c(.*) §r§7(enemy|enemies) for §r§c(.*) §r§7damage.".toPattern(), + ) + private val damageMessages = listOf( + "§cMute silenced you!" + ) + private val notPossibleMessages = listOf( + "§cYou cannot hit the silverfish while it's moving!", + "§cYou cannot move the silverfish in that direction!", + "§cThere are blocks in the way!", + "§cThis chest has already been searched!", + "§cThis lever has already been used.", + "§cYou cannot do that in this room!", + "§cYou do not have the key for this door!", + "§cYou have already opened this dungeon chest!", + "§cYou cannot use abilities in this room!", + "§cA mystical force in this room prevents you from using that ability!" + ) + private val buffPatterns = listOf( + "§6§lDUNGEON BUFF! (.*) §r§ffound a §r§dBlessing of (.*)§r§f!(.*)".toPattern(), + "§6§lDUNGEON BUFF! §r§fYou found a §r§dBlessing of (.*)§r§f!(.*)".toPattern(), + "§6§lDUNGEON BUFF! §r§fA §r§dBlessing of (.*)§r§f was found! (.*)".toPattern(), + "§eA §r§a§r§dBlessing of (.*)§r§e was picked up!".toPattern(), + "(.*) §r§ehas obtained §r§a§r§dBlessing of (.*)§r§e!".toPattern(), + " {5}§r§7Granted you §r§a§r§a(.*)§r§7 & §r§a(.*)x §r§c❁ Strength§r§7.".toPattern(), + " {5}§r§7Also granted you §r§a§r§a(.*)§r§7 & §r§a(.*)x §r§9☠ Crit Damage§r§7.".toPattern(), + " {5}§r§7(Grants|Granted) you §r§a(.*) Defense §r§7and §r§a+(.*) Damage§r§7.".toPattern(), + " {5}§r§7Granted you §r§a§r§a(.*)x HP §r§7and §r§a§r§a(.*)x §r§c❣ Health Regen§r§7.".toPattern(), + " {5}§r§7(Grants|Granted) you §r§a(.*) Intelligence §r§7and §r§a+(.*)? Speed§r§7.".toPattern(), + " {5}§r§7Granted you §r§a+(.*) HP§r§7, §r§a(.*) Defense§r§7, §r§a(.*) Intelligence§r§7, and §r§a(.*) Strength§r§7.".toPattern() + ) + private val buffMessages = listOf( + "§a§lBUFF! §fYou have gained §r§cHealing V§r§f!" + ) + private val puzzlePatterns = listOf( + "§a§lPUZZLE SOLVED! (.*) §r§ewasn't fooled by §r§c(.*)§r§e! §r§4G§r§co§r§6o§r§ed§r§a §r§2j§r§bo§r§3b§r§5!".toPattern(), + "§a§lPUZZLE SOLVED! (.*) §r§etied Tic Tac Toe! §r§4G§r§co§r§6o§r§ed§r§a §r§2j§r§bo§r§3b§r§5!".toPattern(), + "§4\\[STATUE] Oruo the Omniscient§r§f: §r(.*) §r§fthinks the answer is §r§6 . §r(.*)§r§f! §r§fLock in your party's answer in my Chamber!".toPattern(), + ) + private val puzzleMessages = listOf( + "§4[STATUE] Oruo the Omniscient§r§f: §r§fThough I sit stationary in this prison that is §r§cThe Catacombs§r§f, my knowledge knows no bounds.", + "§4[STATUE] Oruo the Omniscient§r§f: §r§fProve your knowledge by answering 3 questions and I shall reward you in ways that transcend time!", + "§4[STATUE] Oruo the Omniscient§r§f: §r§fAnswer incorrectly, and your moment of ineptitude will live on for generations.", + "§4[STATUE] Oruo the Omniscient§r§f: §r§f2 questions left... Then you will have proven your worth to me!", + "§4[STATUE] Oruo the Omniscient§r§f: §r§fOne more question!", + "§4[STATUE] Oruo the Omniscient§r§f: §r§fI bestow upon you all the power of a hundred years!", + "§4[STATUE] Oruo the Omniscient§r§f: §r§fYou've already proven enough to me! No need to press more of my buttons!", + "§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( + "§5A shiver runs down your spine..." + ) + private val reminderMessages = listOf( + "§e§lRIGHT CLICK §r§7on §r§7a §r§8WITHER §r§7door§r§7 to open it. This key can only be used to open §r§a1§r§7 door!", + "§e§lRIGHT CLICK §r§7on §r§7the §r§cBLOOD DOOR§r§7 to open it. This key can only be used to open §r§a1§r§7 door!" + ) + private val pickupPatterns = listOf( + "(.*) §r§ehas obtained §r§a§r§9Superboom TNT§r§e!".toPattern(), + "(.*) §r§ehas obtained §r§a§r§9Superboom TNT §r§8x2§r§e!".toPattern(), + "§6§lRARE DROP! §r§9Hunk of Blue Ice §r§b\\(+(.*)% Magic Find!\\)".toPattern(), + "(.*) §r§ehas obtained §r§a§r§6Revive Stone§r§e!".toPattern(), + "(.*) §r§ffound a §r§dWither Essence§r§f! Everyone gains an extra essence!".toPattern(), + "§d(.*) the Fairy§r§f: You killed me! Take this §r§6Revive Stone §r§fso that my death is not in vain!".toPattern(), + "§d(.*) the Fairy§r§f: You killed me! I'll revive you so that my death is not in vain!".toPattern(), + "§d(.*) the Fairy§r§f: You killed me! I'll revive your friend §r(.*) §r§fso that my death is not in vain!".toPattern(), + "§d(.*) the Fairy§r§f: Have a great life!".toPattern(), + "§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() + ) + private val pickupMessages = listOf( + "§fYou found a §r§dWither Essence§r§f! Everyone gains an extra essence!" + ) + private val startPatterns = listOf( + //§a[Berserk] §r§fMelee Damage §r§c48%§r§f -> §r§a88% + //§a[Berserk] §r§fWalk Speed §r§c38§r§f -> §r§a68 + "§a(.*) §r§f(.*) §r§c(.*)§r§f -> §r§a(.*)".toPattern() + ) + private val startMessages = listOf( + "§e[NPC] §bMort§f: §rHere, I found this map when I first entered the dungeon.", + "§e[NPC] §bMort§f: §rYou should find it useful if you get lost.", + "§e[NPC] §bMort§f: §rGood luck.", + "§e[NPC] §bMort§f: §rTalk to me to change your class and ready up." + ) + private val preparePatterns = listOf( + "(.*) has started the dungeon countdown. The dungeon will begin in 1 minute.".toPattern(), + "§e[NPC] §bMort§f: §rTalk to me to change your class and ready up.".toPattern(), + "(.*)§a is now ready!".toPattern(), + "§aDungeon starts in (.*) seconds.".toPattern(), + ) + private val prepareMessages = listOf( + "§aYour active Potion Effects have been paused and stored. They will be restored when you leave Dungeons! You are not allowed to use existing Potion Effects while in Dungeons.", + "§aDungeon starts in 1 second.", + "§aYou can no longer consume or splash any potions during the remainder of this Dungeon run!", + ) + + private val messagesMap: Map<String, List<String>> = 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<String, List<Pattern>> = 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<String, List<String>> = mapOf( + "end" to endMessagesEndWith, + ) + /// </editor-fold> + @SubscribeEvent fun onChatMessage(event: LorenzChatEvent) { - if (!LorenzUtils.onHypixel) return + if (!LorenzUtils.onHypixel || !config.dungeonMessages) 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 - if (!SkyHanniMod.feature.chat.dungeonMessages) return val blockReason = block(event.message) if (blockReason != "") { @@ -24,200 +204,39 @@ class DungeonChatFilter { private fun block(message: String): String { when { - isPrepare(message) -> return "prepare" - isStart(message) -> return "start" + message.isPresent("prepare") -> return "prepare" + message.isPresent("start") -> return "start" } if (!LorenzUtils.inDungeons) return "" return when { - isUnsortedBlockedMessage(message) -> "unsorted" - isPickup(message) -> "pickup" - isReminder(message) -> "reminder" - isBuff(message) -> "buff" - isNotPossible(message) -> "not_possible" - isDamage(message) -> "damage" - isAbility(message) -> "ability" - isPuzzle(message) -> "puzzle" - isEnd(message) -> "end" - + 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" else -> "" } } - private fun isEnd(message: String): Boolean = when { - message.matchRegex("(.*) §r§eunlocked §r§d(.*) Essence §r§8x(.*)§r§e!") -> true - message.matchRegex(" §r§d(.*) Essence §r§8x(.*)") -> true - message.endsWith(" Experience §r§b(Team Bonus)") -> true - else -> false - } - - private fun isAbility(message: String): Boolean = when { - message == "§a§r§6Guided Sheep §r§ais now available!" -> true - message.matchRegex("§7Your Guided Sheep hit §r§c(.*) §r§7enemy for §r§c(.*) §r§7damage.") -> true - message == "§6Rapid Fire§r§a is ready to use! Press §r§6§lDROP§r§a to activate it!" -> true - message == "§6Castle of Stone§r§a is ready to use! Press §r§6§lDROP§r§a to activate it!" -> true - message == "§6Ragnarok§r§a is ready to use! Press §r§6§lDROP§r§a to activate it!" -> true - - - message.matchRegex("§a§lBUFF! §fYou were splashed by (.*) §fwith §r§cHealing VIII§r§f!") -> true - message.matchRegex("§aYou were healed for (.*) health by (.*)§a!") -> true - message.matchRegex("§aYou gained (.*) HP worth of absorption for 3s from §r(.*)§r§a!") -> true - message.matchRegex("§c(.*) §r§epicked up your (.*) Orb!") -> true - message.matchRegex("§cThis ability is on cooldown for (.*)s.") -> true - message.matchRegex("§a§l(.*) healed you for (.*) health!") -> true - message.matchRegex("§eYour bone plating reduced the damage you took by §r§c(.*)§r§e!") -> true - message.matchRegex("(.*) §r§eformed a tether with you!") -> true - message.matchRegex("§eYour tether with (.*) §r§ehealed you for §r§a(.*) §r§ehealth.") -> true - message.matchRegex("§7Your Implosion hit §r§c(.*) §r§7enemy for §r§c(.*) §r§7damage.") -> true - - message.matchRegex("§eYour §r§6Spirit Pet §r§ehealed (.*) §r§efor §r§a(.*) §r§ehealth!") -> true - message.matchRegex("§eYour §r§6Spirit Pet §r§ehit (.*) enemy for §r§c(.*) §r§edamage.") -> true - - message == "§dCreeper Veil §r§aActivated!" -> true - message == "§dCreeper Veil §r§cDe-activated!" -> true - message.matchRegex("§cYou need at least (.*) mana to activate this!") -> true - - message.matchRegex( - "§eYou were healed for §r§a(.*)§r§e health by §r(.*)§r§e's §r§9Healing Bow§r§e and " + "gained §r§c\\+(.*) Strength§r§e for 10 seconds." - ) -> true - - message.matchRegex("(.*)§r§a granted you §r§c(.*) §r§astrength for §r§e20 §r§aseconds!") -> true - - message.matchRegex("§eYour fairy healed §r§ayourself §r§efor §r§a(.*) §r§ehealth!") -> true - message.matchRegex("§eYour fairy healed §r(.*) §r§efor §r§a(.*) §r§ehealth!") -> true - message.matchRegex("(.*) fairy healed you for §r§a(.*) §r§ehealth!") -> true - - else -> false - } - - private fun isDamage(message: String): Boolean = when { - message == "§cMute silenced you!" -> true - message.matchRegex("(.*) §r§aused §r(.*) §r§aon you!") -> true - message.matchRegex("§cThe (.*)§r§c struck you for (.*) damage!") -> true - message.matchRegex("§cThe (.*) hit you for (.*) damage!") -> true - message.matchRegex("§7(.*) struck you for §r§c(.*)§r§7 damage.") -> true - message.matchRegex("(.*) hit you for §r§c(.*)§r§7 damage.") -> true - message.matchRegex("(.*) hit you for §r§c(.*)§r§7 true damage.") -> true - message.matchRegex("§7(.*) exploded, hitting you for §r§c(.*)§r§7 damage.") -> true - message.matchRegex("(.*)§r§c hit you with §r(.*) §r§cfor (.*) damage!") -> true - message.matchRegex("(.*)§r§a struck you for §r§c(.*)§r§a damage!") -> true - message.matchRegex("(.*)§r§c struck you for (.*)!") -> true - - message.matchRegex("§7The Mage's Magma burnt you for §r§c(.*)§r§7 true damage.") -> true - - message.matchRegex("§7Your (.*) hit §r§c(.*) §r§7(enemy|enemies) for §r§c(.*) §r§7damage.") -> true - else -> false - } - - private fun isNotPossible(message: String): Boolean = when (message) { - "§cYou cannot hit the silverfish while it's moving!", - "§cYou cannot move the silverfish in that direction!", - "§cThere are blocks in the way!", - "§cThis chest has already been searched!", - "§cThis lever has already been used.", - "§cYou cannot do that in this room!", - "§cYou do not have the key for this door!", - "§cYou have already opened this dungeon chest!", - "§cYou cannot use abilities in this room!", - "§cA mystical force in this room prevents you from using that ability!" -> true - - else -> false - } - - private fun isBuff(message: String): Boolean = when { - message.matchRegex("§6§lDUNGEON BUFF! (.*) §r§ffound a §r§dBlessing of (.*)§r§f!(.*)") -> true - message.matchRegex("§6§lDUNGEON BUFF! §r§fYou found a §r§dBlessing of (.*)§r§f!(.*)") -> true - message.matchRegex("§6§lDUNGEON BUFF! §r§fA §r§dBlessing of (.*)§r§f was found! (.*)") -> true - message.matchRegex("§eA §r§a§r§dBlessing of (.*)§r§e was picked up!") -> true - message.matchRegex("(.*) §r§ehas obtained §r§a§r§dBlessing of (.*)§r§e!") -> true - message.matchRegex(" §r§7Granted you §r§a§r§a(.*)§r§7 & §r§a(.*)x §r§c❁ Strength§r§7.") -> true - message.matchRegex(" §r§7Also granted you §r§a§r§a(.*)§r§7 & §r§a(.*)x §r§9☠ Crit Damage§r§7.") -> true - message.matchRegex(" §r§7(Grants|Granted) you §r§a(.*) Defense §r§7and §r§a+(.*) Damage§r§7.") -> true - message.matchRegex(" §r§7Granted you §r§a§r§a(.*)x HP §r§7and §r§a§r§a(.*)x §r§c❣ Health Regen§r§7.") -> true - message.matchRegex(" §r§7(Grants|Granted) you §r§a(.*) Intelligence §r§7and §r§a+(.*)? Speed§r§7.") -> true - message.matchRegex(" §r§7Granted you §r§a+(.*) HP§r§7, §r§a(.*) Defense§r§7, §r§a(.*) Intelligence§r§7, and §r§a(.*) Strength§r§7.") -> true - message == "§a§lBUFF! §fYou have gained §r§cHealing V§r§f!" -> true - else -> false - } - - private fun isPuzzle(message: String): Boolean = when { - message.matchRegex("§a§lPUZZLE SOLVED! (.*) §r§ewasn't fooled by §r§c(.*)§r§e! §r§4G§r§co§r§6o§r§ed§r§a §r§2j§r§bo§r§3b§r§5!") -> true - message.matchRegex("§a§lPUZZLE SOLVED! (.*) §r§etied Tic Tac Toe! §r§4G§r§co§r§6o§r§ed§r§a §r§2j§r§bo§r§3b§r§5!") -> true - message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fThough I sit stationary in this prison that is §r§cThe Catacombs§r§f, my knowledge knows no bounds." -> true - message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fProve your knowledge by answering 3 questions and I shall reward you in ways that transcend time!" -> true - message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fAnswer incorrectly, and your moment of ineptitude will live on for generations." -> true - - message == "§4[STATUE] Oruo the Omniscient§r§f: §r§f2 questions left... Then you will have proven your worth to me!" -> true - - message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fOne more question!" -> true - message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fI bestow upon you all the power of a hundred years!" -> true - message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fYou've already proven enough to me! No need to press more of my buttons!" -> true - message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fI've had enough of you and your party fiddling with my buttons. Scram!" -> true - message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fEnough! My buttons are not to be pressed with such lack of grace!" -> true - message.matchRegex("§4\\[STATUE] Oruo the Omniscient§r§f: §r(.*) §r§fthinks the answer is §r§6 . §r(.*)§r§f! §r§fLock in your party's answer in my Chamber!") -> true - else -> false - } - - //TODO sort out and filter separately - private fun isUnsortedBlockedMessage(message: String): Boolean = when { - message.matchRegex("(.*) §r§ehas obtained §r§a§r§9Beating Heart§r§e!") -> true - message == "§5A shiver runs down your spine..." -> true - - else -> false - } - - private fun isReminder(message: String): Boolean = when (message) { - "§e§lRIGHT CLICK §r§7on §r§7a §r§8WITHER §r§7door§r§7 to open it. This key can only be used to open §r§a1§r§7 door!", - "§e§lRIGHT CLICK §r§7on §r§7the §r§cBLOOD DOOR§r§7 to open it. This key can only be used to open §r§a1§r§7 door!" -> true - - else -> false - } - - private fun isPickup(message: String): Boolean = when { - message.matchRegex("(.*) §r§ehas obtained §r§a§r§9Superboom TNT§r§e!") -> true - message.matchRegex("(.*) §r§ehas obtained §r§a§r§9Superboom TNT §r§8x2§r§e!") -> true - message.matchRegex("§6§lRARE DROP! §r§9Hunk of Blue Ice §r§b\\(+(.*)% Magic Find!\\)") -> true - message.matchRegex("(.*) §r§ehas obtained §r§a§r§6Revive Stone§r§e!") -> true - message.matchRegex("(.*) §r§ffound a §r§dWither Essence§r§f! Everyone gains an extra essence!") -> true - message == "§fYou found a §r§dWither Essence§r§f! Everyone gains an extra essence!" -> true - message.matchRegex("§d(.*) the Fairy§r§f: You killed me! Take this §r§6Revive Stone §r§fso that my death is not in vain!") -> true - message.matchRegex("§d(.*) the Fairy§r§f: You killed me! I'll revive you so that my death is not in vain!") -> true - message.matchRegex("§d(.*) the Fairy§r§f: You killed me! I'll revive your friend §r(.*) §r§fso that my death is not in vain!") -> true - message.matchRegex("§d(.*) the Fairy§r§f: Have a great life!") -> true - message.matchRegex( - "§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." - ) -> true - - message.matchRegex( - "§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." - ) -> true - - message.matchRegex("(.*) §r§ehas obtained §r§a§r§9Premium Flesh§r§e!") -> true - message.matchRegex("§6§lRARE DROP! §r§9Beating Heart §r§b(.*)") -> true - else -> false - } - - private fun isStart(message: String): Boolean = when { - message == "§e[NPC] §bMort§f: §rHere, I found this map when I first entered the dungeon." -> true - message == "§e[NPC] §bMort§f: §rYou should find it useful if you get lost." -> true - message == "§e[NPC] §bMort§f: §rGood luck." -> true - message == "§e[NPC] §bMort§f: §rTalk to me to change your class and ready up." -> true - - //§a[Berserk] §r§fMelee Damage §r§c48%§r§f -> §r§a88% - //§a[Berserk] §r§fWalk Speed §r§c38§r§f -> §r§a68 - message.matchRegex("§a(.*) §r§f(.*) §r§c(.*)§r§f -> §r§a(.*)") -> true - else -> false - } - - private fun isPrepare(message: String): Boolean = when { - message == "§aYour active Potion Effects have been paused and stored. They will be restored when you leave Dungeons! You are not allowed to use existing Potion Effects while in Dungeons." -> true - message.matchRegex("(.*) has started the dungeon countdown. The dungeon will begin in 1 minute.") -> true - message.matchRegex("§e[NPC] §bMort§f: §rTalk to me to change your class and ready up.") -> true - message.matchRegex("(.*)§a is now ready!") -> true - message.matchRegex("§aDungeon starts in (.*) seconds.") -> true - message == "§aDungeon starts in 1 second." -> true - message == "§aYou can no longer consume or splash any potions during the remainder of this Dungeon run!" -> true - else -> false + /** + * Checks if the message is present in the list of messages or patterns + * Checks against three maps that compare in different ways. + * @receiver The message to check + * @param key The key of the list to check + * @return True if the message is present in any of the maps + * @see messagesMap + * @see patternsMap + * @see messagesEndsWithMap + */ + private fun String.isPresent(key: String): Boolean { + return this in (messagesMap[key] ?: emptyList()) || + (patternsMap[key] ?: emptyList()).any { it.matches(this) } || + (messagesEndsWithMap[key] ?: emptyList()).any { this.endsWith(it) } } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCleanEnd.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCleanEnd.kt index 6e5fc27bd..8602b9282 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCleanEnd.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCleanEnd.kt @@ -10,7 +10,7 @@ import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent import at.hannibal2.skyhanni.events.PlaySoundEvent import at.hannibal2.skyhanni.events.ReceiveParticleEvent import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.StringUtils.matchRegex +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import net.minecraft.client.Minecraft import net.minecraft.client.entity.EntityOtherPlayerMP import net.minecraft.entity.item.EntityArmorStand @@ -20,6 +20,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class DungeonCleanEnd { private val config get() = SkyHanniMod.feature.dungeon.cleanEnd + private val catacombsPattern = "([ ]*)§r§c(The|Master Mode) Catacombs §r§8- §r§eFloor (.*)".toPattern() private var bossDone = false private var chestsSpawned = false @@ -32,7 +33,7 @@ class DungeonCleanEnd { val message = event.message - if (message.matchRegex("([ ]*)§r§c(The|Master Mode) Catacombs §r§8- §r§eFloor (.*)")) { + catacombsPattern.matchMatcher(message) { chestsSpawned = true } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCopilot.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCopilot.kt index 8119535fd..1dcc92dab 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCopilot.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCopilot.kt @@ -11,12 +11,23 @@ import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.RenderUtils.renderString -import at.hannibal2.skyhanni.utils.StringUtils.matchRegex +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import net.minecraft.entity.item.EntityArmorStand import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class DungeonCopilot { + private val config get() = SkyHanniMod.feature.dungeon.dungeonCopilot + + private val countdownPattern = + "(.*) has started the dungeon countdown. The dungeon will begin in 1 minute.".toPattern() + private val keyPatternsList = listOf( + "§eA §r§a§r§[6c]§r§[8c](?<key>Wither|Blood) Key§r§e was picked up!".toPattern(), + "(.*) §r§ehas obtained §r§a§r§[6c]§r§[8c](?<key>Wither|Blood) Key§r§e!".toPattern() + ) + private val witherDoorPattern = "(.*) opened a §r§8§lWITHER §r§adoor!".toPattern() + private val bloodDoorPattern = "§cThe §r§c§lBLOOD DOOR§r§c has been opened!".toPattern() + private var nextStep = "" private var searchForKey = false @@ -24,60 +35,50 @@ class DungeonCopilot { fun onChatMessage(event: LorenzChatEvent) { if (!isEnabled()) return - val message = event.message + copilot(event.message)?.let { + event.blockedReason = it + } + } - if (message.matchRegex("(.*) has started the dungeon countdown. The dungeon will begin in 1 minute.")) { + private fun copilot(message: String): String? { + countdownPattern.matchMatcher(message) { changeNextStep("Ready up") } - if (message.endsWith("§a is now ready!")) { - var name = LorenzUtils.getPlayerName() - if (message.contains(name)) { - changeNextStep("Wait for the dungeon to start!") - } + + if (message.endsWith("§a is now ready!") && message.contains(LorenzUtils.getPlayerName())) { + changeNextStep("Wait for the dungeon to start!") } + // Key Pickup var foundKeyOrDoor = false - - //key pickup - if (message.matchRegex("(.*) §r§ehas obtained §r§a§r§6§r§8Wither Key§r§e!") || - message == "§eA §r§a§r§6§r§8Wither Key§r§e was picked up!" - ) { - changeNextStep("Open Wither Door") - foundKeyOrDoor = true - - } - if (message.matchRegex("(.*) §r§ehas obtained §r§a§r§c§r§cBlood Key§r§e!") || - message == "§eA §r§a§r§c§r§cBlood Key§r§e was picked up!" - ) { - changeNextStep("Open Blood Door") - foundKeyOrDoor = true + keyPatternsList.any { + it.matchMatcher(message) { + val key = group("key") + changeNextStep("Open $key Door") + foundKeyOrDoor = true + } != null } - - if (message.matchRegex("(.*) opened a §r§8§lWITHER §r§adoor!")) { + witherDoorPattern.matchMatcher(message) { changeNextStep("Clear next room") searchForKey = true foundKeyOrDoor = true } - if (message == "§cThe §r§c§lBLOOD DOOR§r§c has been opened!") { + bloodDoorPattern.matchMatcher(message) { changeNextStep("Wait for Blood Room to fully spawn") foundKeyOrDoor = true } - if (foundKeyOrDoor && SkyHanniMod.feature.dungeon.messageFilter.keysAndDoors) { - event.blockedReason = "dungeon_keys_and_doors" - } - + if (foundKeyOrDoor && SkyHanniMod.feature.dungeon.messageFilter.keysAndDoors) return "dungeon_keys_and_doors" - if (message == "§c[BOSS] The Watcher§r§f: That will be enough for now.") { - changeNextStep("Clear Blood Room") - } + if (message == "§c[BOSS] The Watcher§r§f: That will be enough for now.") changeNextStep("Clear Blood Room") if (message == "§c[BOSS] The Watcher§r§f: You have proven yourself. You may pass.") { - event.blockedReason = "dungeon copilot" changeNextStep("Enter Boss Room") + return "dungeon_copilot" } + return null } private fun changeNextStep(step: String) { @@ -126,14 +127,14 @@ class DungeonCopilot { } private fun isEnabled(): Boolean { - return LorenzUtils.inDungeons && SkyHanniMod.feature.dungeon.dungeonCopilot.enabled + return LorenzUtils.inDungeons && config.enabled } @SubscribeEvent fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) { if (!isEnabled()) return - SkyHanniMod.feature.dungeon.dungeonCopilot.pos.renderString(nextStep, posLabel = "Dungeon Copilot") + config.pos.renderString(nextStep, posLabel = "Dungeon Copilot") } @SubscribeEvent diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonDeathCounter.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonDeathCounter.kt index 36788e4b3..794736954 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonDeathCounter.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonDeathCounter.kt @@ -7,7 +7,7 @@ import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.RenderUtils.renderString -import at.hannibal2.skyhanni.utils.StringUtils.matchRegex +import at.hannibal2.skyhanni.utils.StringUtils.matches import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class DungeonDeathCounter { @@ -15,37 +15,39 @@ class DungeonDeathCounter { private var display = "" private var deaths = 0 - private fun isDeathMessage(message: String): Boolean = when { - message.matchRegex("§c ☠ §r§7You were killed by (.*)§r§7 and became a ghost§r§7.") -> true - message.matchRegex("§c ☠ §r§7(.*) was killed by (.*) and became a ghost§r§7.") -> true + private val deathPatternsList = listOf( + // TODO USE SH-REPO + "§c ☠ §r§7You were killed by (.*)§r§7 and became a ghost§r§7.".toPattern(), + "§c ☠ §r§7(.*) was killed by (.*) and became a ghost§r§7.".toPattern(), - message.matchRegex("§c ☠ §r§7You were crushed and became a ghost§r§7.") -> true - message.matchRegex("§c ☠ §r§7§r(.*)§r§7 was crushed and became a ghost§r§7.") -> true + "§c ☠ §r§7You were crushed and became a ghost§r§7.".toPattern(), + "§c ☠ §r§7§r(.*)§r§7 was crushed and became a ghost§r§7.".toPattern(), - message.matchRegex("§c ☠ §r§7You died to a trap and became a ghost§r§7.") -> true - message.matchRegex("§c ☠ §r(.*)§r§7 died to a trap and became a ghost§r§7.") -> true + "§c ☠ §r§7You died to a trap and became a ghost§r§7.".toPattern(), + "§c ☠ §r(.*)§r§7 died to a trap and became a ghost§r§7.".toPattern(), - message.matchRegex("§c ☠ §r§7You burnt to death and became a ghost§r§7.") -> true - message.matchRegex("§c ☠ §r(.*)§r§7 burnt to death and became a ghost§r§7.") -> true + "§c ☠ §r§7You burnt to death and became a ghost§r§7.".toPattern(), + "§c ☠ §r(.*)§r§7 burnt to death and became a ghost§r§7.".toPattern(), - message.matchRegex("§c ☠ §r§7You died and became a ghost§r§7.") -> true - message.matchRegex("§c ☠ §r(.*)§r§7 died and became a ghost§r§7.") -> true + "§c ☠ §r§7You died and became a ghost§r§7.".toPattern(), + "§c ☠ §r(.*)§r§7 died and became a ghost§r§7.".toPattern(), - message.matchRegex("§c ☠ §r§7You suffocated and became a ghost§r§7.") -> true - message.matchRegex("§c ☠ §r§7§r(.*)§r§7 suffocated and became a ghost§r§7.") -> true + "§c ☠ §r§7You suffocated and became a ghost§r§7.".toPattern(), + "§c ☠ §r§7§r(.*)§r§7 suffocated and became a ghost§r§7.".toPattern(), - message.matchRegex("§c ☠ §r§7You died to a mob and became a ghost§r§7.") -> true - message.matchRegex("§c ☠ §r(.*)§7 died to a mob and became a ghost§r§7.") -> true + "§c ☠ §r§7You died to a mob and became a ghost§r§7.".toPattern(), + "§c ☠ §r(.*)§7 died to a mob and became a ghost§r§7.".toPattern(), - message.matchRegex("§c ☠ §r§7You fell into a deep hole and became a ghost§r§7.") -> true - message.matchRegex("§c ☠ §r(.*)§r§7 fell into a deep hole and became a ghost§r§7.") -> true + "§c ☠ §r§7You fell into a deep hole and became a ghost§r§7.".toPattern(), + "§c ☠ §r(.*)§r§7 fell into a deep hole and became a ghost§r§7.".toPattern(), - message.matchRegex("§c ☠ §r§(.*)§r§7 disconnected from the Dungeon and became a ghost§r§7.") -> true + "§c ☠ §r§(.*)§r§7 disconnected from the Dungeon and became a ghost§r§7.".toPattern(), - message.matchRegex("§c ☠ §r§7(.*)§r§7 fell to their death with help from §r(.*)§r§7 and became a ghost§r§7.") -> true + "§c ☠ §r§7(.*)§r§7 fell to their death with help from §r(.*)§r§7 and became a ghost§r§7.".toPattern() + ) - else -> false - } + private fun isDeathMessage(message: String): Boolean = + deathPatternsList.any { it.matches(message) } @SubscribeEvent(receiveCanceled = true) fun onChatPacket(event: LorenzChatEvent) { diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonFinderFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonFinderFeatures.kt index b824bc6a5..f21274a02 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonFinderFeatures.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonFinderFeatures.kt @@ -11,7 +11,7 @@ import at.hannibal2.skyhanni.utils.ItemUtils.getLore import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzColor
import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded
+import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary
import at.hannibal2.skyhanni.utils.RenderUtils.highlight
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
@@ -47,11 +47,11 @@ class DungeonFinderFeatures { } else if (itemName == "Entrance") {
event.stackTip = "E"
} else if (itemName.startsWith("Floor ")) {
- event.stackTip = itemName.split(' ').last().romanToDecimalIfNeeded().toString()
+ event.stackTip = itemName.split(' ').last().romanToDecimalIfNecessary().toString()
}
} else if (itemName.startsWith("The Catacombs - ") || itemName.startsWith("MM Catacombs -")) {
val floor = itemName.split(" - ").last().removeColor()
- val floorNum = floor.split(' ').last().romanToDecimalIfNeeded().toString()
+ val floorNum = floor.split(' ').last().romanToDecimalIfNecessary().toString()
val isMasterMode = itemName.contains("MM ")
event.stackTip = if (floor.contains("Entrance")) {
@@ -64,7 +64,7 @@ class DungeonFinderFeatures { } else if (itemName.endsWith("'s Party")) {
val floor = event.stack.getLore().find { it.startsWith("§7Floor: ") } ?: return
val dungeon = event.stack.getLore().find { it.startsWith("§7Dungeon: ") } ?: return
- val floorNum = floor.split(' ').last().romanToDecimalIfNeeded().toString()
+ val floorNum = floor.split(' ').last().romanToDecimalIfNecessary().toString()
val isMasterMode = dungeon.contains("Master Mode")
event.stackTip = if (floor.contains("Entrance")) {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonMilestonesDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonMilestonesDisplay.kt index b3a6a1f59..fc5462901 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonMilestonesDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonMilestonesDisplay.kt @@ -7,7 +7,7 @@ import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.RenderUtils.renderString -import at.hannibal2.skyhanni.utils.StringUtils.matchRegex +import at.hannibal2.skyhanni.utils.StringUtils.matches import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import kotlin.concurrent.fixedRateTimer @@ -15,25 +15,28 @@ class DungeonMilestonesDisplay { private val config get() = SkyHanniMod.feature.dungeon companion object { + + // TODO USE SH-REPO + private val milestonePatternList = listOf( + "§e§l(.*) Milestone §r§e.§r§7: You have dealt §r§c(.*)§r§7 Total Damage so far! §r§a(.*)".toPattern(), + "§e§lArcher Milestone §r§e.§r§7: You have dealt §r§c(.*)§r§7 Ranged Damage so far! §r§a(.*)".toPattern(), + "§e§lHealer Milestone §r§e.§r§7: You have healed §r§a(.*)§r§7 Damage so far! §r§a(.*)".toPattern(), + "§e§lTank Milestone §r§e.§r§7: You have tanked and dealt §r§c(.*)§r§7 Total Damage so far! §r§a(.*)s".toPattern() + ) + private var display = "" var color = "" var currentMilestone = 0 var timeReached = 0L - fun isMilestoneMessage(message: String): Boolean = when { - message.matchRegex("§e§l(.*) Milestone §r§e.§r§7: You have dealt §r§c(.*)§r§7 Total Damage so far! §r§a(.*)") -> true - message.matchRegex("§e§lArcher Milestone §r§e.§r§7: You have dealt §r§c(.*)§r§7 Ranged Damage so far! §r§a(.*)") -> true - message.matchRegex("§e§lHealer Milestone §r§e.§r§7: You have healed §r§a(.*)§r§7 Damage so far! §r§a(.*)") -> true - message.matchRegex("§e§lTank Milestone §r§e.§r§7: You have tanked and dealt §r§c(.*)§r§7 Total Damage so far! §r§a(.*)s") -> true - - else -> false - } + fun isMilestoneMessage(message: String): Boolean = milestonePatternList.any { it.matches(message) } } init { fixedRateTimer(name = "skyhanni-dungeon-milestone-display", period = 200) { - if (!isEnabled()) return@fixedRateTimer - checkVisibility() + if (isEnabled()) { + checkVisibility() + } } } @@ -84,7 +87,10 @@ class DungeonMilestonesDisplay { fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) { if (!isEnabled()) return - config.showMileStonesDisplayPos.renderString(color + display, posLabel = "Dungeon Milestone") + config.showMileStonesDisplayPos.renderString( + color + display, + posLabel = "Dungeon Milestone" + ) } private fun isEnabled() = LorenzUtils.inDungeons && config.showMilestonesDisplay diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonRankTabListColor.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonRankTabListColor.kt index 9a28dcc06..46e2e0514 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonRankTabListColor.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonRankTabListColor.kt @@ -20,13 +20,13 @@ class DungeonRankTabListColor { val playerName = group("playerName") val split = playerName.split(" ") val sbLevel = split[0] - val cleanName = split[1].cleanPlayerName() + val cleanName = split[1].cleanPlayerName(displayName = true) val className = group("className") val level = group("classLevel").romanToDecimal() val color = getColor(level) - event.text = "$sbLevel §b$cleanName §7(§e$className $color$level§7)" + event.text = "$sbLevel $cleanName §7(§e$className $color$level§7)" } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/UniqueGiftingOpportunitiesFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/event/UniqueGiftingOpportunitiesFeatures.kt new file mode 100644 index 000000000..d3b75780c --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/event/UniqueGiftingOpportunitiesFeatures.kt @@ -0,0 +1,90 @@ +package at.hannibal2.skyhanni.features.event + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.data.HypixelData +import at.hannibal2.skyhanni.data.ProfileStorageData +import at.hannibal2.skyhanni.events.EntityCustomNameUpdateEvent +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.RenderMobColoredEvent +import at.hannibal2.skyhanni.events.withAlpha +import at.hannibal2.skyhanni.features.event.winter.UniqueGiftCounter +import at.hannibal2.skyhanni.utils.EntityUtils +import at.hannibal2.skyhanni.utils.EntityUtils.isNPC +import at.hannibal2.skyhanni.utils.InventoryUtils +import at.hannibal2.skyhanni.utils.LorenzColor +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher +import at.hannibal2.skyhanni.utils.getLorenzVec +import net.minecraft.client.entity.EntityPlayerSP +import net.minecraft.entity.EntityLivingBase +import net.minecraft.entity.item.EntityArmorStand +import net.minecraft.entity.player.EntityPlayer +import net.minecraftforge.event.entity.EntityJoinWorldEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +object UniqueGiftingOpportunitiesFeatures { + private val playerList: MutableSet<String>? + get() = ProfileStorageData.playerSpecific?.winter?.playersThatHaveBeenGifted + + private val pattern = "§6\\+1 Unique Gift given! To ([^§]+)§r§6!".toPattern() + + private fun hasGiftedPlayer(player: EntityPlayer) = playerList?.contains(player.name) == true + + private fun addGiftedPlayer(playerName: String) { + playerList?.add(playerName) + } + + private val config get() = SkyHanniMod.feature.event.winter.giftingOpportunities + + private fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled && + (InventoryUtils.itemInHandId.endsWith("_GIFT") + || !config.highlighWithGiftOnly) + + private val hasNotGiftedNametag = "§a§lꤥ" + private val hasGiftedNametag = "§c§lꤥ" + + private fun analyzeArmorStand(entity: EntityArmorStand) { + if (!config.useArmorStandDetection) return + if (entity.name != hasGiftedNametag) return + + val matchedPlayer = EntityUtils.getEntitiesNearby<EntityPlayer>(entity.getLorenzVec(), 2.0) + .singleOrNull { !it.isNPC() } ?: return + addGiftedPlayer(matchedPlayer.name) + + } + + @SubscribeEvent + fun onEntityChangeName(event: EntityCustomNameUpdateEvent) { + val entity = event.entity as? EntityArmorStand ?: return + analyzeArmorStand(entity) + } + + @SubscribeEvent + fun onEntityJoinWorldEvent(event: EntityJoinWorldEvent) { + val entity = event.entity as? EntityArmorStand ?: return + analyzeArmorStand(entity) + } + + @SubscribeEvent + fun onRenderMobColored(event: RenderMobColoredEvent) { + if (!isEnabled()) return + val entity = event.entity + if (entity is EntityPlayerSP) return + if (entity is EntityPlayer && !entity.isNPC() && !isIronman(entity) && !isBingo(entity) && !hasGiftedPlayer(entity)) + event.color = LorenzColor.DARK_GREEN.toColor().withAlpha(127) + } + + private fun isBingo(entity: EntityLivingBase) = + !HypixelData.bingo && entity.displayName.formattedText.endsWith("Ⓑ§r") + + private fun isIronman(entity: EntityLivingBase) = + !LorenzUtils.noTradeMode && entity.displayName.formattedText.endsWith("♲§r") + + @SubscribeEvent + fun onChat(event: LorenzChatEvent) { + pattern.matchMatcher(event.message) { + addGiftedPlayer(group(1)) + UniqueGiftCounter.addUniqueGift() + } + } +} 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 df89ccd7f..14422e6b4 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 @@ -152,25 +152,24 @@ object GriffinBurrowHelper { val playerLocation = LocationUtils.playerLocation() if (config.inquisitorSharing.enabled) { for (inquis in InquisitorWaypointShare.waypoints.values) { - val playerName = inquis.fromPlayer val location = inquis.location event.drawColor(location, LorenzColor.LIGHT_PURPLE) val distance = location.distance(playerLocation) if (distance > 10) { val formattedDistance = LorenzUtils.formatInteger(distance.toInt()) - event.drawDynamicText(location.add(0, 1, 0), "§d§lInquisitor §e${formattedDistance}m", 1.7) + event.drawDynamicText(location.add(y = 1), "§d§lInquisitor §e${formattedDistance}m", 1.7) } else { - event.drawDynamicText(location.add(0, 1, 0), "§d§lInquisitor", 1.7) + event.drawDynamicText(location.add(y = 1), "§d§lInquisitor", 1.7) } if (distance < 5) { - InquisitorWaypointShare.maybeRemove(playerName) + InquisitorWaypointShare.maybeRemove(inquis) } - event.drawDynamicText(location.add(0, 1, 0), "§eFrom §b$playerName", 1.6, yOff = 9f) + event.drawDynamicText(location.add(y = 1), "§eFrom §b${inquis.displayName}", 1.6, yOff = 9f) if (config.inquisitorSharing.showDespawnTime) { val spawnTime = inquis.spawnTime val format = TimeUtils.formatDuration(75.seconds - spawnTime.passedSince()) - event.drawDynamicText(location.add(0, 1, 0), "§eDespawns in §b$format", 1.6, yOff = 18f) + event.drawDynamicText(location.add(y = 1), "§eDespawns in §b$format", 1.6, yOff = 18f) } } } @@ -185,7 +184,7 @@ object GriffinBurrowHelper { val distance = location.distance(playerLocation) val burrowType = burrow.value event.drawColor(location, burrowType.color, distance > 10) - event.drawDynamicText(location.add(0, 1, 0), burrowType.text, 1.5) + event.drawDynamicText(location.add(y = 1), burrowType.text, 1.5) } } @@ -194,10 +193,10 @@ object GriffinBurrowHelper { val guessLocation = findBlock(it) val distance = guessLocation.distance(playerLocation) event.drawColor(guessLocation, LorenzColor.WHITE, distance > 10) - event.drawDynamicText(guessLocation.add(0, 1, 0), "Guess", 1.5) + event.drawDynamicText(guessLocation.add(y = 1), "Guess", 1.5) if (distance > 5) { val formattedDistance = LorenzUtils.formatInteger(distance.toInt()) - event.drawDynamicText(guessLocation.add(0, 1, 0), "§e${formattedDistance}m", 1.7, yOff = 10f) + event.drawDynamicText(guessLocation.add(y = 1), "§e${formattedDistance}m", 1.7, yOff = 10f) } } } @@ -224,7 +223,7 @@ object GriffinBurrowHelper { if (config.burrowNearestWarp) { BurrowWarpHelper.currentWarp?.let { warp -> animationLocation?.let { - event.drawColor(it.add(0.0, 1.0, 0.0), LorenzColor.AQUA) + event.drawColor(it.add(y = 1), LorenzColor.AQUA) if (it.distanceToPlayer() < 10) { event.drawString(it.add(0.5, 1.5, 0.5), "§bWarp to " + warp.displayName, true) if (config.keyBindWarp != Keyboard.KEY_NONE) { diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/diana/InquisitorWaypointShare.kt b/src/main/java/at/hannibal2/skyhanni/features/event/diana/InquisitorWaypointShare.kt index c4f12a993..5532d70e9 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/diana/InquisitorWaypointShare.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/diana/InquisitorWaypointShare.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.event.diana - import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.EntityHealthUpdateEvent import at.hannibal2.skyhanni.events.LorenzChatEvent @@ -47,7 +46,12 @@ object InquisitorWaypointShare { var waypoints = mapOf<String, SharedInquisitor>() - class SharedInquisitor(val fromPlayer: String, val location: LorenzVec, val spawnTime: SimpleTimeMark) + class SharedInquisitor( + val fromPlayer: String, + val displayName: String, + val location: LorenzVec, + val spawnTime: SimpleTimeMark + ) private var test = false @@ -221,42 +225,45 @@ object InquisitorWaypointShare { if (packet.type.toInt() != 0) return partyPattern.matchMatcher(message) { - val playerName = group("playerName") + val rawName = group("playerName") val x = group("x").trim().toInt() val y = group("y").trim().toInt() val z = group("z").trim().toInt() val location = LorenzVec(x, y, z) - val cleanName = playerName.cleanPlayerName() - if (!waypoints.containsKey(cleanName)) { - LorenzUtils.chat("$playerName §l§efound an inquisitor at §l§c$x $y $z!") - if (cleanName != LorenzUtils.getPlayerName()) { - LorenzUtils.sendTitle("§dINQUISITOR §efrom §b$cleanName", 5.seconds) + val name = rawName.cleanPlayerName() + val displayName = rawName.cleanPlayerName(displayName = true) + if (!waypoints.containsKey(name)) { + LorenzUtils.chat("$displayName §l§efound an inquisitor at §l§c$x $y $z!") + if (name != LorenzUtils.getPlayerName()) { + LorenzUtils.sendTitle("§dINQUISITOR §efrom §b$displayName", 5.seconds) SoundUtils.playBeepSound() } } - val inquis = SharedInquisitor(cleanName, location, SimpleTimeMark.now()) - waypoints = waypoints.editCopy { this[cleanName] = inquis } + val inquis = SharedInquisitor(name, displayName, location, SimpleTimeMark.now()) + waypoints = waypoints.editCopy { this[name] = inquis } if (config.focusInquisitor) { - GriffinBurrowHelper.setTargetLocation(location.add(0, 1, 0)) + GriffinBurrowHelper.setTargetLocation(location.add(y = 1)) GriffinBurrowHelper.animationLocation = LocationUtils.playerLocation() } event.isCanceled = true } diedPattern.matchMatcher(message) { - val playerName = group("playerName").cleanPlayerName() - waypoints = waypoints.editCopy { remove(playerName) } - logger.log("Inquisitor died from '$playerName'") + val rawName = group("playerName") + val name = rawName.cleanPlayerName() + val displayName = rawName.cleanPlayerName(displayName = true) + waypoints = waypoints.editCopy { remove(name) } + logger.log("Inquisitor died from '$displayName'") } } fun isEnabled() = DianaAPI.featuresEnabled() && config.enabled - fun maybeRemove(playerName: String) { + fun maybeRemove(inquis: SharedInquisitor) { if (inquisitorsNearby.isEmpty()) { - waypoints = waypoints.editCopy { remove(playerName) } - LorenzUtils.chat("Inquisitor from $playerName not found, deleting.") + waypoints = waypoints.editCopy { remove(inquis.fromPlayer) } + LorenzUtils.chat("Inquisitor from ${inquis.displayName} not found, deleting.") } } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/jerry/frozentreasure/FrozenTreasureTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/event/jerry/frozentreasure/FrozenTreasureTracker.kt index bfae2a7d8..63ec4fbf2 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/jerry/frozentreasure/FrozenTreasureTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/jerry/frozentreasure/FrozenTreasureTracker.kt @@ -2,12 +2,14 @@ package at.hannibal2.skyhanni.features.event.jerry.frozentreasure import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator +import at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry import at.hannibal2.skyhanni.data.IslandType import at.hannibal2.skyhanni.data.ProfileStorageData import at.hannibal2.skyhanni.data.ScoreboardData import at.hannibal2.skyhanni.events.GuiRenderEvent import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent +import at.hannibal2.skyhanni.utils.ConfigUtils import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList import at.hannibal2.skyhanni.utils.LorenzUtils.addOrPut import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland @@ -96,7 +98,8 @@ object FrozenTreasureTracker { private fun formatDisplay(map: List<List<Any>>): List<List<Any>> { val newList = mutableListOf<List<Any>>() for (index in config.textFormat) { - newList.add(map[index]) + // TODO, change functionality to use enum rather than ordinals + newList.add(map[index.ordinal]) } return newList } @@ -168,6 +171,13 @@ object FrozenTreasureTracker { @SubscribeEvent fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { event.move(2, "misc.frozenTreasureTracker", "event.winter.frozenTreasureTracker") + event.move( + 11, + "event.winter.frozenTreasureTracker.textFormat", + "event.winter.frozenTreasureTracker.textFormat" + ) { element -> + ConfigUtils.migrateIntArrayListToEnumArrayList(element, FrozenTreasureDisplayEntry::class.java) + } } private fun onJerryWorkshop() = IslandType.WINTER.isInIsland() diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/winter/UniqueGiftCounter.kt b/src/main/java/at/hannibal2/skyhanni/features/event/winter/UniqueGiftCounter.kt new file mode 100644 index 000000000..10b52745a --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/event/winter/UniqueGiftCounter.kt @@ -0,0 +1,74 @@ +package at.hannibal2.skyhanni.features.event.winter + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.data.ProfileStorageData +import at.hannibal2.skyhanni.events.GuiRenderEvent +import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent +import at.hannibal2.skyhanni.events.IslandChangeEvent +import at.hannibal2.skyhanni.utils.InventoryUtils +import at.hannibal2.skyhanni.utils.ItemUtils.getLore +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber +import at.hannibal2.skyhanni.utils.RenderUtils.renderString +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +object UniqueGiftCounter { + + private val config get() = SkyHanniMod.feature.event.winter.uniqueGiftCounter + private val storage get() = ProfileStorageData.playerSpecific?.winter + + private val pattern = "§7Unique Players Gifted: §a(?<amount>.*)".toPattern() + + private var display = "" + + @SubscribeEvent + fun onInventoryOpen(event: InventoryFullyOpenedEvent) { + if (event.inventoryName != "Generow") return + val item = event.inventoryItems[40] ?: return + + val storage = storage ?: return + + for (line in item.getLore()) { + pattern.matchMatcher(line) { + val amount = group("amount").formatNumber().toInt() + storage.amountGifted = amount + update() + return + } + } + } + + @SubscribeEvent + fun onIslandChange(event: IslandChangeEvent) { + update() + } + + fun addUniqueGift() { + val storage = storage ?: return + storage.amountGifted++ + update() + } + + private fun update() { + val storage = storage ?: return + + val amountGifted = storage.amountGifted + val max = 600 + val hasMax = amountGifted >= max + val color = if (hasMax) "§a" else "§e" + display = "§7Unique Players Gifted: $color$amountGifted/$max" + } + + @SubscribeEvent + fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) { + if (!isEnabled()) return + + config.position.renderString( + display, + posLabel = "Unique Gift Counter" + ) + } + + private fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled && InventoryUtils.itemInHandId.endsWith("_GIFT") +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingAPI.kt index 550388893..027a4b6d0 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingAPI.kt @@ -1,10 +1,18 @@ package at.hannibal2.skyhanni.features.fishing import at.hannibal2.skyhanni.events.FishingBobberCastEvent +import at.hannibal2.skyhanni.events.ItemInHandChangeEvent +import at.hannibal2.skyhanni.events.SkillExpGainEvent +import at.hannibal2.skyhanni.features.fishing.tracker.FishingProfitTracker +import at.hannibal2.skyhanni.features.fishing.trophy.TrophyFishManager +import at.hannibal2.skyhanni.features.fishing.trophy.TrophyFishManager.getFilletValue +import at.hannibal2.skyhanni.features.fishing.trophy.TrophyRarity +import at.hannibal2.skyhanni.utils.DelayedRun import at.hannibal2.skyhanni.utils.InventoryUtils import at.hannibal2.skyhanni.utils.ItemUtils.getLore import at.hannibal2.skyhanni.utils.ItemUtils.name import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.NEUInternalName import at.hannibal2.skyhanni.utils.SimpleTimeMark import at.hannibal2.skyhanni.utils.StringUtils.removeColor import net.minecraft.client.Minecraft @@ -13,12 +21,14 @@ import net.minecraft.init.Blocks import net.minecraft.item.ItemStack import net.minecraftforge.event.entity.EntityJoinWorldEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.time.Duration.Companion.seconds object FishingAPI { private val lavaBlocks = listOf(Blocks.lava, Blocks.flowing_lava) private val waterBlocks = listOf(Blocks.water, Blocks.flowing_water) var lastCastTime = SimpleTimeMark.farPast() + var lastActiveFishingTime = SimpleTimeMark.farPast() @SubscribeEvent fun onJoinWorld(event: EntityJoinWorldEvent) { @@ -31,7 +41,31 @@ object FishingAPI { FishingBobberCastEvent(entity).postAndCatch() } - fun hasFishingRodInHand() = InventoryUtils.itemInHandId.asString().contains("ROD") + @SubscribeEvent + fun onItemInHandChange(event: ItemInHandChangeEvent) { + if (event.oldItem.isFishingRod()) { + lastActiveFishingTime = SimpleTimeMark.now() + } + if (event.newItem.isFishingRod()) { + DelayedRun.runDelayed(1.seconds) { + lastActiveFishingTime = SimpleTimeMark.now() + } + } + } + + @SubscribeEvent + fun onSkillExpGain(event: SkillExpGainEvent) { + val skill = event.skill + if (FishingProfitTracker.isEnabled()) { + if (skill != "fishing") { + lastActiveFishingTime = SimpleTimeMark.farPast() + } + } + } + + fun hasFishingRodInHand() = InventoryUtils.itemInHandId.isFishingRod() + + fun NEUInternalName.isFishingRod() = contains("ROD") fun ItemStack.isBait(): Boolean { val name = name ?: return false @@ -42,4 +76,14 @@ object FishingAPI { fun getAllowedBlocks() = if (isLavaRod()) lavaBlocks else waterBlocks + fun getFilletPerTrophy(internalName: NEUInternalName): Int { + val internal = internalName.asString() + val trophyFishName = internal.substringBeforeLast("_") + .replace("_", "").lowercase() + val trophyRarityName = internal.substringAfterLast("_") + val info = TrophyFishManager.getInfo(trophyFishName) + val rarity = TrophyRarity.getByName(trophyRarityName) ?: TrophyRarity.BRONZE + return info?.getFilletValue(rarity) ?: 0 + } + } diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingTimer.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingTimer.kt index fa2b9b824..501b217f4 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingTimer.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingTimer.kt @@ -92,6 +92,10 @@ class FishingTimer { return true } + if (config.crimsonIsle && IslandType.CRIMSON_ISLE.isInIsland()) return true + + if (config.winterIsland && IslandType.WINTER.isInIsland()) return true + if (!IslandType.THE_FARMING_ISLANDS.isInIsland()) { return LocationUtils.playerLocation().distance(barnLocation) < 50 } diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureManager.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureManager.kt index f0a3c54b1..b3e0670fe 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureManager.kt @@ -5,7 +5,7 @@ import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.RepositoryReloadEvent import at.hannibal2.skyhanni.events.SeaCreatureFishEvent import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.jsonobjects.SeaCreatureJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.SeaCreatureJson import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class SeaCreatureManager { diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/ShowFishingItemName.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/ShowFishingItemName.kt index a64d3da77..4a41b332c 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/fishing/ShowFishingItemName.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/ShowFishingItemName.kt @@ -47,7 +47,7 @@ class ShowFishingItemName { if (!isEnabled()) return if (hasRodInHand) { for (entityItem in EntityUtils.getEntities<EntityItem>()) { - val location = event.exactLocation(entityItem).add(0.0, 0.8, 0.0) + val location = event.exactLocation(entityItem).add(y = 0.8) if (location.distance(LocationUtils.playerLocation()) > 15) continue val itemStack = entityItem.entityItem var name = itemStack.name ?: continue diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/ThunderSparksHighlight.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/ThunderSparksHighlight.kt index bab0d5ae1..e49e8e3f8 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/fishing/ThunderSparksHighlight.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/ThunderSparksHighlight.kt @@ -55,7 +55,7 @@ class ThunderSparksHighlight { sparkLocation.add(-0.5, 0.0, -0.5), color, extraSize = -0.25, seeThroughBlocks = seeThroughBlocks ) if (sparkLocation.distance(playerLocation) < 10) { - event.drawString(sparkLocation.add(0.0, 1.5, 0.0), "Thunder Spark", seeThroughBlocks = seeThroughBlocks) + event.drawString(sparkLocation.add(y = 1.5), "Thunder Spark", seeThroughBlocks = seeThroughBlocks) } } } @@ -74,4 +74,4 @@ class ThunderSparksHighlight { event.move(3, "fishing.thunderSparkHighlight", "fishing.thunderSpark.highlight") event.move(3, "fishing.thunderSparkColor", "fishing.thunderSpark.color") } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingProfitPlayerMoving.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingProfitPlayerMoving.kt new file mode 100644 index 000000000..ee19bab84 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingProfitPlayerMoving.kt @@ -0,0 +1,43 @@ +package at.hannibal2.skyhanni.features.fishing.tracker + +import at.hannibal2.skyhanni.events.EntityMoveEvent +import at.hannibal2.skyhanni.events.FishingBobberCastEvent +import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent +import net.minecraft.client.Minecraft +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +object FishingProfitPlayerMoving { + + private val lastSteps = mutableListOf<Double>() + var isMoving = true + + @SubscribeEvent + fun onEntityMove(event: EntityMoveEvent) { + if (!FishingProfitTracker.isEnabled() || !FishingProfitTracker.config.hideMoving) return + if (event.entity != Minecraft.getMinecraft().thePlayer) return + + val distance = event.newLocation.distanceIgnoreY(event.oldLocation) + if (distance < 0.1) { + lastSteps.clear() + return + } + lastSteps.add(distance) + if (lastSteps.size > 20) { + lastSteps.removeAt(0) + } + val total = lastSteps.sum() + if (total > 3) { + isMoving = true + } + } + + @SubscribeEvent + fun onBobberThrow(event: FishingBobberCastEvent) { + isMoving = false + } + + @SubscribeEvent + fun onWorldChange(event: LorenzWorldChangeEvent) { + isMoving = true + } +} 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 new file mode 100644 index 000000000..8d3da8564 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingProfitTracker.kt @@ -0,0 +1,224 @@ +package at.hannibal2.skyhanni.features.fishing.tracker + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.FishingBobberCastEvent +import at.hannibal2.skyhanni.events.GuiRenderEvent +import at.hannibal2.skyhanni.events.ItemAddEvent +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent +import at.hannibal2.skyhanni.features.fishing.FishingAPI +import at.hannibal2.skyhanni.utils.DelayedRun +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList +import at.hannibal2.skyhanni.utils.LorenzUtils.addButton +import at.hannibal2.skyhanni.utils.NEUInternalName +import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName +import at.hannibal2.skyhanni.utils.NumberUtil +import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators +import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher +import at.hannibal2.skyhanni.utils.renderables.Renderable +import at.hannibal2.skyhanni.utils.tracker.ItemTrackerData +import at.hannibal2.skyhanni.utils.tracker.SkyHanniItemTracker +import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker +import com.google.gson.annotations.Expose +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.minutes +import kotlin.time.Duration.Companion.seconds + +typealias CategoryName = String + +object FishingProfitTracker { + val config get() = SkyHanniMod.feature.fishing.fishingProfitTracker + + private val coinsChatPattern = ".* CATCH! §r§bYou found §r§6(?<coins>.*) Coins§r§b\\.".toPattern() + + private var lastCatchTime = SimpleTimeMark.farPast() + private val tracker = SkyHanniItemTracker( + "Fishing Profit Tracker", + { Data() }, + { it.fishing.fishingProfitTracker }) { drawDisplay(it) } + + class Data : ItemTrackerData() { + override fun resetItems() { + totalCatchAmount = 0 + } + + override fun getDescription(timesCaught: Long): List<String> { + val percentage = timesCaught.toDouble() / totalCatchAmount + val catchRate = LorenzUtils.formatPercentage(percentage.coerceAtMost(1.0)) + + return listOf( + "§7Caught §e${timesCaught.addSeparators()} §7times.", + "§7Your catch rate: §c$catchRate" + ) + } + + override fun getCoinName(item: TrackedItem) = "§6Fished Coins" + + override fun getCoinDescription(item: TrackedItem): List<String> { + val mobKillCoinsFormat = NumberUtil.format(item.totalAmount) + return listOf( + "§7You fished up §6$mobKillCoinsFormat coins §7already." + ) + } + + override fun getCustomPricePer(internalName: NEUInternalName): Double { + // TODO find better way to tell if the item is a trophy + val neuInternalNames = itemCategories["Trophy Fish"]!! + + return if (internalName in neuInternalNames) { + SkyHanniTracker.getPricePer(MAGMA_FISH) * FishingAPI.getFilletPerTrophy(internalName) + } else super.getCustomPricePer(internalName) + } + + @Expose + var totalCatchAmount = 0L + } + + private val ItemTrackerData.TrackedItem.timesCaught get() = timesGained + + private val MAGMA_FISH by lazy { "MAGMA_FISH".asInternalName() } + + private val nameAll: CategoryName = "All" + private var currentCategory: CategoryName = nameAll + + private fun getCurrentCategories(data: Data): Map<CategoryName, Int> { + val map = mutableMapOf<CategoryName, Int>() + map[nameAll] = data.items.size + for ((name, items) in itemCategories) { + val amount = items.count { it in data.items } + if (amount > 0) { + map[name] = amount + } + } + + return map + } + + private fun drawDisplay(data: Data): List<List<Any>> = buildList { + addAsSingletonList("§e§lFishing Profit Tracker") + val filter: (NEUInternalName) -> Boolean = addCategories(data) + + val profit = tracker.drawItems(data, filter, this) + + val fishedCount = data.totalCatchAmount + addAsSingletonList( + Renderable.hoverTips( + "§7Times fished: §e${fishedCount.addSeparators()}", + listOf("§7You catched §e${fishedCount.addSeparators()} §7times something.") + ) + ) + + val profitFormat = NumberUtil.format(profit) + 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"))) + + tracker.addPriceFromButton(this) + } + + private fun MutableList<List<Any>>.addCategories(data: Data): (NEUInternalName) -> Boolean { + val amounts = getCurrentCategories(data) + val list = amounts.keys.toList() + if (currentCategory !in list) { + currentCategory = nameAll + } + + if (tracker.isInventoryOpen()) { + addButton( + prefix = "§7Category: ", + getName = currentCategory + " §7(" + amounts[currentCategory] + ")", + onChange = { + val id = list.indexOf(currentCategory) + currentCategory = list[(id + 1) % list.size] + tracker.update() + } + ) + } + + val filter: (NEUInternalName) -> Boolean = if (currentCategory == nameAll) { + { true } + } else { + val items = itemCategories[currentCategory]!! + { it in items } + } + return filter + } + + @SubscribeEvent + fun onItemAdd(event: ItemAddEvent) { + if (!isEnabled()) return + DelayedRun.runDelayed(500.milliseconds) { + maybeAddItem(event.internalName, event.amount) + } + } + + @SubscribeEvent + fun onChat(event: LorenzChatEvent) { + coinsChatPattern.matchMatcher(event.message) { + val coins = group("coins").formatNumber() + tracker.addCoins(coins.toInt()) + addCatch() + } + } + + private fun addCatch() { + tracker.modify { + it.totalCatchAmount++ + } + lastCatchTime = SimpleTimeMark.now() + } + + @SubscribeEvent + fun onRenderOverlay(event: GuiRenderEvent) { + if (!isEnabled()) return + + val recentPickup = config.showWhenPickup && lastCatchTime.passedSince() < 3.seconds + if (!recentPickup) { + if (!FishingAPI.hasFishingRodInHand()) return + // TODO remove hide moving chech, replace with last cast location + radius + if (FishingProfitPlayerMoving.isMoving && config.hideMoving) return + } + + tracker.renderDisplay(config.position) + } + + @SubscribeEvent + fun onWorldChange(event: LorenzWorldChangeEvent) { + lastCatchTime = SimpleTimeMark.farPast() + } + + private fun maybeAddItem(internalName: NEUInternalName, amount: Int) { + if (FishingAPI.lastActiveFishingTime.passedSince() > 10.minutes) return + + if (!isAllowedItem(internalName)) { + LorenzUtils.debug("Ignored non-fishing item pickup: $internalName'") + return + } + + tracker.addItem(internalName, amount) + addCatch() + } + + private val itemCategories get() = FishingTrackerCategoryManager.itemCategories + + private fun isAllowedItem(internalName: NEUInternalName) = itemCategories.any { internalName in it.value } + + @SubscribeEvent + fun onBobberThrow(event: FishingBobberCastEvent) { + tracker.firstUpdate() + } + + fun resetCommand(args: Array<String>) { + tracker.resetCommand(args, "shresetfishingtracker") + } + + fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingTrackerCategoryManager.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingTrackerCategoryManager.kt new file mode 100644 index 000000000..2006975ad --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingTrackerCategoryManager.kt @@ -0,0 +1,72 @@ +package at.hannibal2.skyhanni.features.fishing.tracker + +import at.hannibal2.skyhanni.data.jsonobjects.repo.FishingProfitItemsJson +import at.hannibal2.skyhanni.events.RepositoryReloadEvent +import at.hannibal2.skyhanni.utils.NEUInternalName +import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName +import io.github.moulberry.notenoughupdates.NotEnoughUpdates +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +object FishingTrackerCategoryManager { + + var itemCategories = mapOf<String, List<NEUInternalName>>() + + private var shItemCategories = mapOf<String, List<NEUInternalName>>() + private var neuItemCategories = mapOf<String, List<NEUInternalName>>() + + @SubscribeEvent + fun onRepoReload(event: RepositoryReloadEvent) { + shItemCategories = event.getConstant<FishingProfitItemsJson>("FishingProfitItems").categories + updateItemCategories() + } + + private fun updateItemCategories() { + itemCategories = shItemCategories + neuItemCategories + } + + @SubscribeEvent + fun onNeuRepoReload(event: io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent) { + val totalDrops = mutableListOf<String>() + val dropCategories = mutableMapOf<String, MutableList<NEUInternalName>>() + for ((seaCreature, data) in NotEnoughUpdates.INSTANCE.manager.itemInformation.filter { it.key.endsWith("_SC") }) { + val asJsonObject = data.getAsJsonArray("recipes")[0].asJsonObject + val drops = asJsonObject.getAsJsonArray("drops") + .map { it.asJsonObject.get("id").asString }.map { it.split(":").first() } + val asJsonArray = asJsonObject.get("extra") + val extra = asJsonArray?.let { + asJsonArray.asJsonArray.toList() + .map { it.toString() } + .filter { !it.contains("Fishing Skill") && !it.contains("Requirements:") && !it.contains("Fished from water") } + .joinToString(" + ") + } ?: "null" + val category = if (extra.contains("Fishing Festival")) { + "Fishing Festival" + } else if (extra.contains("Spooky Festival")) { + "Spooky Festival" + } else if (extra.contains("Jerry's Workshop")) { + "Jerry's Workshop" + } else if (extra.contains("Oasis")) { + "Oasis" + } else if (extra.contains("Magma Fields") || extra.contains("Precursor Remnants") || + extra.contains("Goblin Holdout") + ) { + "Crystal Hollows" + } else if (extra.contains("Crimson Isle Lava")) { + "Crimson Isle Lava" + } else { + if (extra.isNotEmpty()) { + println("unknown extra: $extra = $seaCreature ($drops)") + } + "Water" + } + " Sea Creatures" + for (drop in drops) { + if (drop !in totalDrops) { + totalDrops.add(drop) + dropCategories.getOrPut(category) { mutableListOf() }.add(drop.asInternalName()) + } + } + } + neuItemCategories = dropCategories + updateItemCategories() + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/TrophyFishManager.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/TrophyFishManager.kt index 5f576ae46..6be896fb3 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/TrophyFishManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/TrophyFishManager.kt @@ -5,8 +5,8 @@ import at.hannibal2.skyhanni.events.RepositoryReloadEvent import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators import at.hannibal2.skyhanni.utils.StringUtils.splitLines -import at.hannibal2.skyhanni.utils.jsonobjects.TrophyFishJson -import at.hannibal2.skyhanni.utils.jsonobjects.TrophyFishJson.TrophyFishInfo +import at.hannibal2.skyhanni.data.jsonobjects.repo.TrophyFishJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.TrophyFishJson.TrophyFishInfo import net.minecraft.event.HoverEvent import net.minecraft.util.ChatComponentText import net.minecraft.util.ChatStyle diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt index 7d5c04d5f..e92fda526 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.events.GuiRenderEvent import at.hannibal2.skyhanni.events.InventoryCloseEvent @@ -24,7 +23,7 @@ import net.minecraft.item.ItemStack import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class AnitaMedalProfit { - private val config get() = SkyHanniMod.feature.garden.anitaShop + private val config get() = GardenAPI.config.anitaShop private var display = emptyList<List<Any>>() companion object { diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt index 423bdaed1..41ef944ea 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt @@ -59,8 +59,7 @@ enum class CropType( Blocks.melon_block -> MELON Blocks.cactus -> CACTUS Blocks.cocoa -> COCOA_BEANS - Blocks.red_mushroom -> MUSHROOM - Blocks.brown_mushroom -> MUSHROOM + Blocks.red_mushroom, Blocks.brown_mushroom -> MUSHROOM Blocks.nether_wart -> NETHER_WART else -> null } 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 3e57bb199..9fa7d7257 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt @@ -148,7 +148,7 @@ class FarmingFortuneDisplay { private fun isEnabled(): Boolean = GardenAPI.inGarden() && config.display companion object { - private val config get() = SkyHanniMod.feature.garden.farmingFortunes + private val config get() = GardenAPI.config.farmingFortunes private val latestFF: MutableMap<CropType, Double>? get() = GardenAPI.storage?.latestTrueFarmingFortune private var currentCrop: CropType? = null diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt index 8998903d5..6ef4800dc 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt @@ -4,6 +4,7 @@ import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.data.IslandType import at.hannibal2.skyhanni.data.PetAPI import at.hannibal2.skyhanni.data.ProfileStorageData +import at.hannibal2.skyhanni.data.jsonobjects.repo.GardenJson import at.hannibal2.skyhanni.events.BlockClickEvent import at.hannibal2.skyhanni.events.ConfigLoadEvent import at.hannibal2.skyhanni.events.CropClickEvent @@ -22,21 +23,18 @@ import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI import at.hannibal2.skyhanni.features.garden.inventory.SkyMartCopperPrice import at.hannibal2.skyhanni.features.garden.visitor.VisitorAPI import at.hannibal2.skyhanni.utils.BlockUtils.isBabyCrop +import at.hannibal2.skyhanni.utils.DelayedRun import at.hannibal2.skyhanni.utils.InventoryUtils import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName import at.hannibal2.skyhanni.utils.LocationUtils.isPlayerInside import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland import at.hannibal2.skyhanni.utils.LorenzVec -import at.hannibal2.skyhanni.utils.MinecraftDispatcher import at.hannibal2.skyhanni.utils.NEUInternalName import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getCultivatingCounter import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getHoeCounter -import at.hannibal2.skyhanni.utils.jsonobjects.GardenJson -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import net.minecraft.client.Minecraft +import net.minecraft.enchantment.Enchantment import net.minecraft.item.ItemStack import net.minecraft.network.play.client.C09PacketHeldItemChange import net.minecraft.util.AxisAlignedBB @@ -51,6 +49,7 @@ object GardenAPI { private var inBarn = false val onBarnPlot get() = inBarn && inGarden() val storage get() = ProfileStorageData.profileSpecific?.garden + val config get() = SkyHanniMod.feature.garden var totalAmountVisitorsExisting = 0 var gardenExp: Long? get() = storage?.experience @@ -62,6 +61,17 @@ object GardenAPI { private val barnArea = AxisAlignedBB(35.5, 70.0, -4.5, -32.5, 100.0, -46.5) + // TODO USE SH-REPO + private val otherToolsList = listOf( + "DAEDALUS_AXE", + "BASIC_GARDENING_HOE", + "ADVANCED_GARDENING_AXE", + "BASIC_GARDENING_AXE", + "ADVANCED_GARDENING_HOE", + "ROOKIE_HOE", + "BINGHOE" + ) + @SubscribeEvent fun onSendPacket(event: PacketEvent.SendEvent) { if (!inGarden()) return @@ -87,14 +97,12 @@ object GardenAPI { } } + // TODO use IslandChangeEvent @SubscribeEvent fun onWorldChange(event: LorenzWorldChangeEvent) { - SkyHanniMod.coroutineScope.launch { - delay(2.seconds) - withContext(MinecraftDispatcher) { - if (inGarden()) { - checkItemInHand() - } + DelayedRun.runDelayed(2.seconds) { + if (inGarden()) { + checkItemInHand() } } } @@ -123,19 +131,7 @@ object GardenAPI { } private fun isOtherTool(internalName: NEUInternalName): Boolean { - if (internalName.startsWith("DAEDALUS_AXE")) return true - - if (internalName.startsWith("BASIC_GARDENING_HOE")) return true - if (internalName.startsWith("ADVANCED_GARDENING_AXE")) return true - - if (internalName.startsWith("BASIC_GARDENING_AXE")) return true - if (internalName.startsWith("ADVANCED_GARDENING_HOE")) return true - - if (internalName.startsWith("ROOKIE_HOE")) return true - - if (internalName.startsWith("BINGHOE")) return true - - return false + return internalName.asString() in otherToolsList } fun inGarden() = IslandType.GARDEN.isInIsland() @@ -147,9 +143,14 @@ object GardenAPI { fun readCounter(itemStack: ItemStack): Long = itemStack.getHoeCounter() ?: itemStack.getCultivatingCounter() ?: -1L - fun MutableList<Any>.addCropIcon(crop: CropType) { + fun MutableList<Any>.addCropIcon(crop: CropType, highlight: Boolean = false) { try { - add(crop.icon) + var icon = crop.icon.copy() + if (highlight) { + // Hack to add enchant glint, like Hypixel does it + icon.addEnchantment(Enchantment.protection, 0) + } + add(icon) } catch (e: NullPointerException) { e.printStackTrace() } @@ -185,7 +186,6 @@ object GardenAPI { val cropBroken = blockState.getCropType() ?: return if (cropBroken.multiplier == 1 && blockState.isBabyCrop()) return - val position = event.position if (lastLocation == position) { return diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneFix.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneFix.kt index f6c235cc1..fa273ebb3 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneFix.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneFix.kt @@ -9,14 +9,14 @@ import at.hannibal2.skyhanni.events.TabListUpdateEvent import at.hannibal2.skyhanni.features.garden.farming.GardenCropMilestoneDisplay import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators -import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded +import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import java.util.regex.Pattern class GardenCropMilestoneFix { private val tabListPattern = " Milestone: §r§a(?<crop>.*) (?<tier>.*): §r§3(?<percentage>.*)%".toPattern() - private val levelUpPattern = Pattern.compile(" §r§b§lGARDEN MILESTONE §3(?<crop>.*) §8(?:.*)➜§3(?<tier>.*)") + private val levelUpPattern = Pattern.compile(" {2}§r§b§lGARDEN MILESTONE §3(?<crop>.*) §8(?:.*)➜§3(?<tier>.*)") private val tabListCropProgress = mutableMapOf<CropType, Long>() @@ -26,7 +26,7 @@ class GardenCropMilestoneFix { val cropName = group("crop") val crop = CropType.getByNameOrNull(cropName) ?: return - val tier = group("tier").romanToDecimalIfNeeded() + val tier = group("tier").romanToDecimalIfNecessary() val crops = GardenCropMilestones.getCropsForTier(tier, crop) changedValue(crop, crops, "level up chat message", 0) diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropTimeCommand.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropTimeCommand.kt index 92a01c7fb..bc1993c96 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropTimeCommand.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropTimeCommand.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.features.garden.farming.CropMoneyDisplay import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed.getSpeed import at.hannibal2.skyhanni.utils.ItemUtils.getItemName @@ -12,7 +11,7 @@ import at.hannibal2.skyhanni.utils.StringUtils.removeColor import at.hannibal2.skyhanni.utils.TimeUtils object GardenCropTimeCommand { - private val config get() = SkyHanniMod.feature.garden.moneyPerHours + private val config get() = GardenAPI.config.moneyPerHours fun onCommand(args: Array<String>) { if (!config.display) { diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenLevelDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenLevelDisplay.kt index 50cf6b758..fe4df931b 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenLevelDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenLevelDisplay.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.events.GuiRenderEvent import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent @@ -9,7 +8,7 @@ import at.hannibal2.skyhanni.events.ProfileJoinEvent import at.hannibal2.skyhanni.utils.ItemUtils.getLore import at.hannibal2.skyhanni.utils.ItemUtils.name import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded +import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary import at.hannibal2.skyhanni.utils.RenderUtils.renderString import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.StringUtils.removeColor @@ -18,7 +17,7 @@ import kotlin.math.roundToLong import kotlin.time.Duration.Companion.milliseconds class GardenLevelDisplay { - private val config get() = SkyHanniMod.feature.garden.gardenLevels + private val config get() = GardenAPI.config.gardenLevels private val expToNextLevelPattern = ".* §e(?<nextLevelExp>.*)§6/.*".toPattern() private val overflowPattern = ".*§r §6(?<overflow>.*) XP".toPattern() private val namePattern = "Garden Level (?<currentLevel>.*)".toPattern() @@ -64,7 +63,7 @@ class GardenLevelDisplay { val item = event.inventoryItems[4]!! namePattern.matchMatcher(item.name!!.removeColor()) { - val currentLevel = group("currentLevel").romanToDecimalIfNeeded() + val currentLevel = group("currentLevel").romanToDecimalIfNecessary() var nextLevelExp = 0L for (line in item.getLore()) { expToNextLevelPattern.matchMatcher(line) { 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 c058e9fe6..2baa27ffa 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt @@ -16,9 +16,12 @@ import at.hannibal2.skyhanni.utils.ItemUtils.name import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.RenderUtils.renderSingleLineWithItems import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import at.hannibal2.skyhanni.utils.SimpleTimeMark.Companion.asTimeMark import at.hannibal2.skyhanni.utils.SoundUtils 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.TimeUtils import com.google.gson.Gson import io.github.moulberry.notenoughupdates.util.SkyBlockTime @@ -30,25 +33,30 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import org.lwjgl.opengl.Display import java.awt.event.MouseAdapter import java.awt.event.MouseEvent -import java.time.Instant import javax.swing.JButton import javax.swing.JFrame import javax.swing.JOptionPane import javax.swing.UIManager +import kotlin.time.Duration +import kotlin.time.Duration.Companion.days +import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.seconds object GardenNextJacobContest { private var dispatcher = Dispatchers.IO private var display = emptyList<Any>() private var simpleDisplay = emptyList<String>() - private var contests = mutableMapOf<Long, FarmingContest>() + private var contests = mutableMapOf<SimpleTimeMark, FarmingContest>() private var inCalendar = false + private val patternDay = "§aDay (?<day>.*)".toPattern() private val patternMonth = "(?<month>.*), Year (?<year>.*)".toPattern() private val patternCrop = "§(e○|6☘) §7(?<crop>.*)".toPattern() + private val closeToNewYear = "§7Close to new SB year!" private const val maxContestsPerYear = 124 - private const val contestDuration = 1_000 * 60 * 20 + private val contestDuration = 20.minutes + private var lastWarningTime = 0L private var loadedContestsYear = -1 private var nextContestsAvailableAt = -1L @@ -76,12 +84,27 @@ object GardenNextJacobContest { if (counter == 4) break } } - newList.add("§cOpen calendar for") - newList.add("§cmore exact data!") + + if (isCloseToNewYear()) { + newList.add(closeToNewYear) + } else { + newList.add("§cOpen calendar for") + newList.add("§cmore exact data!") + } simpleDisplay = newList } + private fun isCloseToNewYear(): Boolean { + val now = SkyBlockTime.now() + val newYear = SkyBlockTime(year = now.year) + val nextYear = SkyBlockTime(year = now.year + 1) + val diffA = now.asTimeMark() - newYear.asTimeMark() + val diffB = nextYear.asTimeMark() - now.asTimeMark() + + return diffA < 30.minutes || diffB < 30.minutes + } + @SubscribeEvent fun onTick(event: LorenzTickEvent) { if (!isEnabled()) return @@ -123,7 +146,7 @@ object GardenNextJacobContest { private fun readCalendar(items: Collection<ItemStack>, year: Int, month: Int) { if (contests.isNotEmpty() && loadedContestsYear != year) { val endTime = contests.values.first().endTime - val lastYear = SkyBlockTime.fromInstant(Instant.ofEpochMilli(endTime)).year + val lastYear = endTime.toSkyBlockTime().year if (year != lastYear) { contests.clear() } @@ -149,7 +172,7 @@ object GardenNextJacobContest { val name = item.name ?: continue val day = patternDay.matchMatcher(name) { group("day").toInt() } ?: continue - val startTime = SkyBlockTime(year, month, day).toMillis() + val startTime = SkyBlockTime(year, month, day).asTimeMark() val crops = mutableListOf<CropType>() for (line in lore) { @@ -184,7 +207,7 @@ object GardenNextJacobContest { val currentYear = SkyBlockTime.now().year for (contest in contests.values) { - val contestYear = (SkyBlockTime.fromInstant(Instant.ofEpochMilli(contest.endTime))).year + val contestYear = (contest.endTime.toSkyBlockTime()).year // Ensure all stored contests are really from the current year if (contestYear != currentYear) continue @@ -199,7 +222,7 @@ object GardenNextJacobContest { val year = savedContests.firstNotNullOfOrNull { val endTime = it.key - SkyBlockTime.fromInstant(Instant.ofEpochMilli(endTime)).year + endTime.toSkyBlockTime().year } // Clear contests if from previous year @@ -232,7 +255,7 @@ object GardenNextJacobContest { } } - class FarmingContest(val endTime: Long, val crops: List<CropType>) + class FarmingContest(val endTime: SimpleTimeMark, val crops: List<CropType>) private fun update() { nextContestCrops.clear() @@ -265,18 +288,22 @@ object GardenNextJacobContest { } if (contests.isEmpty()) { - list.add("§cOpen calendar to read jacob contest times!") + if (isCloseToNewYear()) { + list.add(closeToNewYear) + } else { + list.add("§cOpen calendar to read jacob contest times!") + } return list } val nextContest = - contests.filter { it.value.endTime > System.currentTimeMillis() }.toSortedMap() + contests.filter { !it.value.endTime.isInPast() }.toSortedMap() .firstNotNullOfOrNull { it.value } // Show next contest if (nextContest != null) return drawNextContest(nextContest, list) - if (contests.size == maxContestsPerYear) { - list.add("§cNew SkyBlock Year! Open calendar again!") + if (isCloseToNewYear()) { + list.add(closeToNewYear) } else { list.add("§cOpen calendar to read jacob contest times!") } @@ -291,17 +318,24 @@ object GardenNextJacobContest { nextContest: FarmingContest, list: MutableList<Any>, ): MutableList<Any> { - var duration = nextContest.endTime - System.currentTimeMillis() + var duration = nextContest.endTime.timeUntil() + if (duration > 4.days) { + list.add(closeToNewYear) + return list + } + + val boostedCrop = calculateBoostedCrop(nextContest) + if (duration < contestDuration) { list.add("§aActive: ") } else { list.add("§eNext: ") duration -= contestDuration - warn(duration, nextContest.crops) + warn(duration, nextContest.crops, boostedCrop) } for (crop in nextContest.crops) { list.add(" ") - list.addCropIcon(crop) + list.addCropIcon(crop, highlight = (crop == boostedCrop)) nextContestCrops.add(crop) } val format = TimeUtils.formatDuration(duration) @@ -310,23 +344,39 @@ object GardenNextJacobContest { return list } - private fun warn(timeInMillis: Long, crops: List<CropType>) { + private fun calculateBoostedCrop(nextContest: FarmingContest): CropType? { + for (line in TabListData.getTabList()) { + val lineStripped = line.removeColor().trim() + if (!lineStripped.startsWith("☘ ")) continue + for (crop in nextContest.crops) { + if (line.removeColor().trim() == "☘ ${crop.cropName}") { + return crop + } + } + } + + return null + } + + private fun warn(duration: Duration, crops: List<CropType>, boostedCrop: CropType?) { if (!config.warn) return - if (config.warnTime <= timeInMillis / 1000) return + if (config.warnTime.seconds <= duration) return if (System.currentTimeMillis() < lastWarningTime) return lastWarningTime = System.currentTimeMillis() + 60_000 * 40 - val cropText = crops.joinToString("§7, ") { "§a${it.cropName}" } + val cropText = crops.joinToString("§7, ") { (if (it == boostedCrop) "§6" else "§a") + it.cropName } LorenzUtils.chat("Next farming contest: $cropText") LorenzUtils.sendTitle("§eFarming Contest!", 5.seconds) SoundUtils.playBeepSound() + val cropTextNoColor = + crops.joinToString(", ") { if (it == boostedCrop) "<b>${it.cropName}</b>" else it.cropName } if (config.warnPopup && !Display.isActive()) { SkyHanniMod.coroutineScope.launch { openPopupWindow( - "Farming Contest soon!\n" + - "Crops: ${cropText.removeColor()}" + "<html>Farming Contest soon!<br />" + + "Crops: ${cropTextNoColor}</html>" ) } } @@ -422,12 +472,13 @@ object GardenNextJacobContest { val url = "https://api.elitebot.dev/contests/at/now" val result = withContext(dispatcher) { APIUtil.getJSONResponse(url) }.asJsonObject - val newContests = mutableMapOf<Long, FarmingContest>() + val newContests = mutableMapOf<SimpleTimeMark, FarmingContest>() val complete = result["complete"].asBoolean if (complete) { for (entry in result["contests"].asJsonObject.entrySet()) { var timestamp = entry.key.toLongOrNull() ?: continue + val timeMark = (timestamp * 1000).asTimeMark() timestamp *= 1_000 // Seconds to milliseconds val crops = entry.value.asJsonArray.map { @@ -436,7 +487,7 @@ object GardenNextJacobContest { if (crops.size != 3) continue - newContests[timestamp + contestDuration] = FarmingContest(timestamp + contestDuration, crops) + 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!") @@ -459,7 +510,7 @@ object GardenNextJacobContest { } private fun sendContests() { - if (isSendingContests || contests.size != maxContestsPerYear) return + if (isSendingContests || contests.size != maxContestsPerYear || isCloseToNewYear()) return isSendingContests = true @@ -473,7 +524,7 @@ object GardenNextJacobContest { val formatted = mutableMapOf<Long, List<String>>() for ((endTime, contest) in contests) { - formatted[endTime / 1000] = contest.crops.map { + formatted[endTime.toMillis() / 1000] = contest.crops.map { it.cropName } } @@ -494,7 +545,7 @@ object GardenNextJacobContest { null } - private val config get() = SkyHanniMod.feature.garden.nextJacobContests + private val config get() = GardenAPI.config.nextJacobContests private val nextContestCrops = mutableListOf<CropType>() fun isNextCrop(cropName: CropType) = nextContestCrops.contains(cropName) && config.otherGuis diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt index 967368915..201b1bc7e 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.events.GardenToolChangeEvent import at.hannibal2.skyhanni.events.GuiRenderEvent @@ -19,7 +18,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import kotlin.time.Duration.Companion.seconds class GardenOptimalSpeed { - private val config get() = SkyHanniMod.feature.garden.optimalSpeeds + private val config get() = GardenAPI.config.optimalSpeeds private val configCustomSpeed get() = config.customSpeed private var currentSpeed = 100 private var optimalSpeed = -1 diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenPlotAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenPlotAPI.kt new file mode 100644 index 000000000..64308abf1 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenPlotAPI.kt @@ -0,0 +1,185 @@ +package at.hannibal2.skyhanni.features.garden + +import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent +import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent +import at.hannibal2.skyhanni.features.misc.LockMouseLook +import at.hannibal2.skyhanni.utils.ItemUtils.name +import at.hannibal2.skyhanni.utils.LocationUtils.isPlayerInside +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzVec +import at.hannibal2.skyhanni.utils.RenderUtils.draw3DLine +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher +import com.google.gson.annotations.Expose +import net.minecraft.util.AxisAlignedBB +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.awt.Color +import kotlin.math.floor + +object GardenPlotAPI { + + private val pestNamePattern = "§aPlot §7- §b(?<name>.*)".toPattern() + + var plots = listOf<Plot>() + + fun getCurrentPlot(): Plot? { + return plots.firstOrNull { it.isPlayerInside() } + } + + class Plot(val id: Int, var inventorySlot: Int, val box: AxisAlignedBB, val middle: LorenzVec) + + class PlotData( + @Expose + val id: Int, + + @Expose + var name: String, + + @Expose + var pests: Int + ) + + private fun Plot.getData() = GardenAPI.storage?.plotData?.getOrPut(id) { PlotData(id, "$id", 0) } + + var Plot.name: String + get() = getData()?.name ?: "$id" + set(value) { + getData()?.name = value + } + + var Plot.pests: Int + get() = getData()?.pests ?: 0 + set(value) { + getData()?.pests = value + } + + fun Plot.isBarn() = id == -1 + + fun Plot.isPlayerInside() = box.isPlayerInside() + + fun Plot.sendTeleportTo() { + LorenzUtils.sendCommandToServer("tptoplot $name") + LockMouseLook.autoDisable() + } + + init { + val plotMap = listOf( + listOf(21, 13, 9, 14, 22), + listOf(15, 5, 1, 6, 16), + listOf(10, 2, -1, 3, 11), + listOf(17, 7, 4, 8, 18), + listOf(23, 19, 12, 20, 24), + ) + val list = mutableListOf<Plot>() + var slot = 2 + for ((y, rows) in plotMap.withIndex()) { + for ((x, id) in rows.withIndex()) { + val minX = ((x - 2) * 96 - 48).toDouble() + val minY = ((y - 2) * 96 - 48).toDouble() + val maxX = ((x - 2) * 96 + 48).toDouble() + val maxY = ((y - 2) * 96 + 48).toDouble() + val a = LorenzVec(minX, 0.0, minY) + val b = LorenzVec(maxX, 256.0, maxY) + val middle = a.interpolate(b, 0.5).copy(y = 10.0) + val box = a.axisAlignedTo(b).expand(0.0001, 0.0, 0.0001) + list.add(Plot(id, slot, box, middle)) + slot++ + } + slot += 4 + } + plots = list + } + + @SubscribeEvent + fun onInventoryOpen(event: InventoryFullyOpenedEvent) { + if (!GardenAPI.inGarden()) return + if (event.inventoryName != "Configure Plots") return + + for (plot in plots) { + val itemName = event.inventoryItems[plot.inventorySlot]?.name ?: continue + pestNamePattern.matchMatcher(itemName) { + plot.name = group("name") + } + } + } + + fun getPlotByName(plotName: String) = plots.firstOrNull { it.name == plotName } + + fun LorenzRenderWorldEvent.renderPlot(plot: GardenPlotAPI.Plot, lineColor: Color, cornerColor: Color) { + + // These don't refer to Minecraft chunks but rather garden plots, but I use + // the word chunk as the logic closely represents how chunk borders are rendered in latter mc versions + val plotSize = 96 + val chunkX = floor((plot.middle.x + 48) / plotSize).toInt() + val chunkZ = floor((plot.middle.z + 48) / plotSize).toInt() + val chunkMinX = (chunkX * plotSize) - 48 + val chunkMinZ = (chunkZ * plotSize) - 48 + + // Lowest point in the garden + val minHeight = 66 + val maxHeight = 256 + + // Render 4 vertical corners + for (i in 0..plotSize step plotSize) { + for (j in 0..plotSize step plotSize) { + val start = LorenzVec(chunkMinX + i, minHeight, chunkMinZ + j) + val end = LorenzVec(chunkMinX + i, maxHeight, chunkMinZ + j) + tryDraw3DLine(start, end, cornerColor, 2, true) + } + } + + // Render vertical on X-Axis + for (x in 4..<plotSize step 4) { + val start = LorenzVec(chunkMinX + x, minHeight, chunkMinZ) + val end = LorenzVec(chunkMinX + x, maxHeight, chunkMinZ) + // Front lines + tryDraw3DLine(start, end, lineColor, 1, true) + // Back lines + tryDraw3DLine(start.add(z = plotSize), end.add(z = plotSize), lineColor, 1, true) + } + + // Render vertical on Z-Axis + for (z in 4..<plotSize step 4) { + val start = LorenzVec(chunkMinX, minHeight, chunkMinZ + z) + val end = LorenzVec(chunkMinX, maxHeight, chunkMinZ + z) + // Left lines + tryDraw3DLine(start, end, lineColor, 1, true) + // Right lines + tryDraw3DLine(start.add(x = plotSize), end.add(x = plotSize), lineColor, 1, true) + } + + // Render horizontal + for (y in minHeight..maxHeight step 4) { + val start = LorenzVec(chunkMinX, y, chunkMinZ) + // (minX, minZ) -> (minX, minZ + 96) + tryDraw3DLine(start, start.add(z = plotSize), lineColor, 1, true) + // (minX, minZ + 96) -> (minX + 96, minZ + 96) + tryDraw3DLine(start.add(z = plotSize), start.add(x = plotSize, z = plotSize), lineColor, 1, true) + // (minX + 96, minZ + 96) -> (minX + 96, minZ) + tryDraw3DLine(start.add(x = plotSize, z = plotSize), start.add(x = plotSize), lineColor, 1, true) + // (minX + 96, minZ) -> (minX, minZ) + tryDraw3DLine(start.add(x = plotSize), start, lineColor, 1, true) + } + } + + private fun LorenzRenderWorldEvent.tryDraw3DLine( + p1: LorenzVec, + p2: LorenzVec, + color: Color, + lineWidth: Int, + depth: Boolean + ) { + if (isOutOfBorders(p1)) return + if (isOutOfBorders(p2)) return + draw3DLine(p1, p2, color, lineWidth, depth) + } + + private fun isOutOfBorders(location: LorenzVec) = when { + location.x > 240 -> true + location.x < -240 -> true + location.z > 240 -> true + location.z < -240 -> true + + else -> false + } + +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenPlotBorders.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenPlotBorders.kt index d5d00d509..893e31cbf 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenPlotBorders.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenPlotBorders.kt @@ -1,29 +1,19 @@ package at.hannibal2.skyhanni.features.garden -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.LorenzKeyPressEvent import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent +import at.hannibal2.skyhanni.features.garden.GardenPlotAPI.renderPlot import at.hannibal2.skyhanni.utils.LorenzColor -import at.hannibal2.skyhanni.utils.LorenzVec -import at.hannibal2.skyhanni.utils.RenderUtils.draw3DLine import at.hannibal2.skyhanni.utils.SimpleTimeMark -import net.minecraft.client.Minecraft import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import org.lwjgl.input.Keyboard -import java.awt.Color -import kotlin.math.floor import kotlin.time.Duration.Companion.milliseconds -class GardenPlotBorders { +object GardenPlotBorders { - private val config get() = SkyHanniMod.feature.garden.plotBorders + private val config get() = GardenAPI.config.plotBorders private var timeLastSaved = SimpleTimeMark.farPast() private var showBorders = false - private val LINE_COLOR = LorenzColor.YELLOW.toColor() - - private fun LorenzVec.addX(x: Int) = add(x, 0, 0) - private fun LorenzVec.addZ(z: Int) = add(0, 0, z) - private fun LorenzVec.addXZ(x: Int, z: Int) = add(x, 0, z) @SubscribeEvent fun onKeyClick(event: LorenzKeyPressEvent) { @@ -44,84 +34,10 @@ class GardenPlotBorders { fun render(event: LorenzRenderWorldEvent) { if (!isEnabled()) return if (!showBorders) return - - val entity = Minecraft.getMinecraft().renderViewEntity - - // Lowest point in garden - val minHeight = 66 - val maxHeight = 256 - - // These don't refer to Minecraft chunks but rather garden plots, but I use - // the word chunk as the logic closely represents how chunk borders are rendered in latter mc versions - val chunkX = floor((entity.posX + 48) / 96).toInt() - val chunkZ = floor((entity.posZ + 48) / 96).toInt() - val chunkMinX = (chunkX * 96) - 48 - val chunkMinZ = (chunkZ * 96) - 48 - - // Render 4 vertical corners - for (i in 0..96 step 96) { - for (j in 0..96 step 96) { - val start = LorenzVec(chunkMinX + i, minHeight, chunkMinZ + j) - val end = LorenzVec(chunkMinX + i, maxHeight, chunkMinZ + j) - event.tryDraw3DLine(start, end, LorenzColor.DARK_BLUE.toColor(), 2, true) - } - } - - // Render vertical on X-Axis - for (x in 4..<96 step 4) { - val start = LorenzVec(chunkMinX + x, minHeight, chunkMinZ) - val end = LorenzVec(chunkMinX + x, maxHeight, chunkMinZ) - // Front lines - event.tryDraw3DLine(start, end, LINE_COLOR, 1, true) - // Back lines - event.tryDraw3DLine(start.addZ(96), end.addZ(96), LINE_COLOR, 1, true) - } - - // Render vertical on Z-Axis - for (z in 4..<96 step 4) { - val start = LorenzVec(chunkMinX, minHeight, chunkMinZ + z) - val end = LorenzVec(chunkMinX, maxHeight, chunkMinZ + z) - // Left lines - event.tryDraw3DLine(start, end, LINE_COLOR, 1, true) - // Right lines - event.tryDraw3DLine(start.addX(96), end.addX(96), LINE_COLOR, 1, true) - } - - // Render horizontal - for (y in minHeight..maxHeight step 4) { - val start = LorenzVec(chunkMinX, y, chunkMinZ) - // (minX, minZ) -> (minX, minZ + 96) - event.tryDraw3DLine(start, start.addZ(96), LINE_COLOR, 1, true) - // (minX, minZ + 96) -> (minX + 96, minZ + 96) - event.tryDraw3DLine(start.addZ(96), start.addXZ(96, 96), LINE_COLOR, 1, true) - // (minX + 96, minZ + 96) -> (minX + 96, minZ) - event.tryDraw3DLine(start.addXZ(96, 96), start.addX(96), LINE_COLOR, 1, true) - // (minX + 96, minZ) -> (minX, minZ) - event.tryDraw3DLine(start.addX(96), start, LINE_COLOR, 1, true) - } - } - - private fun LorenzRenderWorldEvent.tryDraw3DLine( - p1: LorenzVec, - p2: LorenzVec, - color: Color, - lineWidth: Int, - depth: Boolean - ) { - if (isOutOfBorders(p1)) return - if (isOutOfBorders(p2)) return - draw3DLine(p1, p2, color, lineWidth, depth) + val plot = GardenPlotAPI.getCurrentPlot() ?: return + event.renderPlot(plot, LorenzColor.YELLOW.toColor(), LorenzColor.DARK_BLUE.toColor()) } - private fun isOutOfBorders(location: LorenzVec) = when { - location.x > 240 -> true - location.x < -240 -> true - location.z > 240 -> true - location.z < -240 -> true - - else -> false - } - fun isEnabled() = GardenAPI.inGarden() && config } diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenWarpCommands.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenWarpCommands.kt new file mode 100644 index 000000000..a25949350 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenWarpCommands.kt @@ -0,0 +1,63 @@ +package at.hannibal2.skyhanni.features.garden + +import at.hannibal2.skyhanni.events.LorenzKeyPressEvent +import at.hannibal2.skyhanni.events.MessageSendToServerEvent +import at.hannibal2.skyhanni.features.misc.LockMouseLook +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.NEUItems +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher +import net.minecraft.client.Minecraft +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class GardenWarpCommands { + private val config get() = GardenAPI.config.gardenCommands + + // TODO repo + private val tpPlotPattern = "/tp (?<plot>.*)".toPattern() + + @SubscribeEvent + fun onMessageSendToServer(event: MessageSendToServerEvent) { + if (!config.warpCommands) return + if (!GardenAPI.inGarden()) return + + val message = event.message.lowercase() + + if (message == "/home") { + event.isCanceled = true + LorenzUtils.sendCommandToServer("warp garden") + LorenzUtils.chat("§aTeleported you to the spawn location!", prefix = false) + } + + if (message == "/barn") { + event.isCanceled = true + LorenzUtils.sendCommandToServer("tptoplot barn") + LockMouseLook.autoDisable() + } + + tpPlotPattern.matchMatcher(event.message) { + event.isCanceled = true + val plotName = group("plot") + LorenzUtils.sendCommandToServer("tptoplot $plotName") + LockMouseLook.autoDisable() + } + } + + @SubscribeEvent + fun onKeyClick(event: LorenzKeyPressEvent) { + if (!GardenAPI.inGarden()) return + if (Minecraft.getMinecraft().currentScreen != null) return + if (NEUItems.neuHasFocus()) return + + val command = when (event.keyCode) { + config.homeHotkey -> "warp garden" + config.sethomeHotkey -> "sethome" + config.barnHotkey -> "tptoplot barn" + + else -> return + } + if (command == "tptoplot barn") { + LockMouseLook.autoDisable() + } + LorenzUtils.sendCommandToServer(command) + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenYawAndPitch.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenYawAndPitch.kt index 2a09754cd..d053a4ede 100755 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenYawAndPitch.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenYawAndPitch.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.GardenToolChangeEvent import at.hannibal2.skyhanni.events.GuiRenderEvent import at.hannibal2.skyhanni.utils.LorenzUtils @@ -12,7 +11,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import kotlin.time.Duration.Companion.seconds class GardenYawAndPitch { - private val config get() = SkyHanniMod.feature.garden.yawPitchDisplay + private val config get() = GardenAPI.config.yawPitchDisplay private var lastChange = SimpleTimeMark.farPast() private var lastYaw = 0f private var lastPitch = 0f @@ -57,4 +56,4 @@ class GardenYawAndPitch { fun onGardenToolChange(event: GardenToolChangeEvent) { lastChange = SimpleTimeMark.farPast() } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/ToolTooltipTweaks.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/ToolTooltipTweaks.kt index 58371a771..bebeb71f8 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/ToolTooltipTweaks.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/ToolTooltipTweaks.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.events.LorenzToolTipEvent import at.hannibal2.skyhanni.features.garden.FarmingFortuneDisplay.Companion.getAbilityFortune @@ -19,7 +18,7 @@ import java.text.DecimalFormat import kotlin.math.roundToInt class ToolTooltipTweaks { - private val config get() = SkyHanniMod.feature.garden.tooltipTweak + private val config get() = GardenAPI.config.tooltipTweak private val tooltipFortunePattern = "^§5§o§7Farming Fortune: §a\\+([\\d.]+)(?: §2\\(\\+\\d\\))?(?: §9\\(\\+(\\d+)\\))?$".toRegex() private val counterStartLine = setOf("§5§o§6Logarithmic Counter", "§5§o§6Collection Analysis") @@ -160,4 +159,4 @@ class ToolTooltipTweaks { event.move(3, "garden.fortuneTooltipKeybind", "garden.tooltipTweak.fortuneTooltipKeybind") event.move(3, "garden.cropTooltipFortune", "garden.tooltipTweak.cropTooltipFortune") } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterDisplay.kt index 2e089364c..cf06da7f6 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterDisplay.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden.composter -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.events.GuiRenderEvent import at.hannibal2.skyhanni.events.TabListUpdateEvent @@ -19,7 +18,7 @@ import kotlin.time.Duration.Companion.seconds import kotlin.time.DurationUnit class ComposterDisplay { - private val config get() = SkyHanniMod.feature.garden.composters + private val config get() = GardenAPI.config.composters private val storage get() = GardenAPI.storage private var display = emptyList<List<Any>>() private var composterEmptyTime: Duration? = null diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterInventoryNumbers.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterInventoryNumbers.kt index e344699c7..2bbfc27a6 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterInventoryNumbers.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterInventoryNumbers.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden.composter -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.events.RenderInventoryItemTipEvent import at.hannibal2.skyhanni.features.garden.GardenAPI @@ -18,7 +17,7 @@ class ComposterInventoryNumbers { @SubscribeEvent fun onRenderItemTip(event: RenderInventoryItemTipEvent) { if (!GardenAPI.inGarden()) return - if (!SkyHanniMod.feature.garden.composters.inventoryNumbers) return + if (!GardenAPI.config.composters.inventoryNumbers) return if (event.inventoryName != "Composter") return @@ -72,4 +71,4 @@ class ComposterInventoryNumbers { fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { event.move(3, "garden.composterInventoryNumbers", "garden.composters.inventoryNumbers") } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterOverlay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterOverlay.kt index b99f059da..f65e02107 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterOverlay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterOverlay.kt @@ -1,9 +1,9 @@ package at.hannibal2.skyhanni.features.garden.composter -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.data.SackAPI import at.hannibal2.skyhanni.data.SackStatus +import at.hannibal2.skyhanni.data.jsonobjects.repo.GardenJson import at.hannibal2.skyhanni.data.model.ComposterUpgrade import at.hannibal2.skyhanni.events.GuiRenderEvent import at.hannibal2.skyhanni.events.InventoryCloseEvent @@ -14,6 +14,7 @@ import at.hannibal2.skyhanni.events.TabListUpdateEvent import at.hannibal2.skyhanni.features.bazaar.BazaarApi import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.features.garden.composter.ComposterAPI.getLevel +import at.hannibal2.skyhanni.features.misc.items.EstimatedItemValue import at.hannibal2.skyhanni.utils.InventoryUtils import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName_old import at.hannibal2.skyhanni.utils.ItemUtils.name @@ -27,14 +28,13 @@ import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName import at.hannibal2.skyhanni.utils.NEUItems import at.hannibal2.skyhanni.utils.NumberUtil import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators -import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded +import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems import at.hannibal2.skyhanni.utils.SimpleTimeMark import at.hannibal2.skyhanni.utils.SoundUtils import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.StringUtils.removeColor import at.hannibal2.skyhanni.utils.TimeUtils -import at.hannibal2.skyhanni.utils.jsonobjects.GardenJson import at.hannibal2.skyhanni.utils.renderables.Renderable import io.github.moulberry.notenoughupdates.NotEnoughUpdates import net.minecraftforge.event.entity.player.ItemTooltipEvent @@ -52,7 +52,7 @@ object ComposterOverlay { private var fuelFactors: Map<String, Double> = emptyMap() private var organicMatter: Map<String, Double> = emptyMap() - private val config get() = SkyHanniMod.feature.garden.composters + private val config get() = GardenAPI.config.composters private var organicMatterDisplay = emptyList<List<Any>>() private var fuelExtraDisplay = emptyList<List<Any>>() @@ -135,7 +135,7 @@ object ComposterOverlay { event.itemStack?.name?.let { if (it.contains(upgrade.displayName)) { maxLevel = ComposterUpgrade.regex.matchMatcher(it) { - group("level")?.romanToDecimalIfNeeded() ?: 0 + group("level")?.romanToDecimalIfNecessary() ?: 0 } == 25 extraComposterUpgrade = upgrade update() @@ -550,6 +550,8 @@ object ComposterOverlay { @SubscribeEvent fun onBackgroundDraw(event: GuiRenderEvent.ChestGuiOverlayRenderEvent) { + if (EstimatedItemValue.isCurrentlyShowing()) return + if (inInventory) { config.overlayOrganicMatterPos.renderStringsAndItems( organicMatterDisplay, diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/GardenComposterInventoryFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/GardenComposterInventoryFeatures.kt index 397231258..3a1f9cf5e 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/GardenComposterInventoryFeatures.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/GardenComposterInventoryFeatures.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden.composter -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.events.GuiContainerEvent import at.hannibal2.skyhanni.features.garden.GardenAPI @@ -19,7 +18,7 @@ import net.minecraftforge.event.entity.player.ItemTooltipEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class GardenComposterInventoryFeatures { - private val config get() = SkyHanniMod.feature.garden.composters + private val config get() = GardenAPI.config.composters @SubscribeEvent fun onTooltip(event: ItemTooltipEvent) { diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestFFNeededDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestFFNeededDisplay.kt index 3f03cbe4b..e52a1b343 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestFFNeededDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestFFNeededDisplay.kt @@ -1,11 +1,11 @@ package at.hannibal2.skyhanni.features.garden.contest -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.GuiRenderEvent import at.hannibal2.skyhanni.events.InventoryCloseEvent import at.hannibal2.skyhanni.events.RenderItemTooltipEvent import at.hannibal2.skyhanni.features.garden.CropType import at.hannibal2.skyhanni.features.garden.FarmingFortuneDisplay.Companion.getLatestTrueFarmingFortune +import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed.getLatestBlocksPerSecond import at.hannibal2.skyhanni.utils.InventoryUtils import at.hannibal2.skyhanni.utils.ItemUtils.name @@ -19,7 +19,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import kotlin.math.ceil class JacobContestFFNeededDisplay { - private val config get() = SkyHanniMod.feature.garden + private val config get() = GardenAPI.config private var display = emptyList<List<Any>>() private var lastToolTipTime = 0L private val cache = mutableMapOf<ItemStack, List<List<Any>>>() diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestStatsSummary.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestStatsSummary.kt index faa2ed534..72dc37621 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestStatsSummary.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestStatsSummary.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden.contest -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.data.ClickType import at.hannibal2.skyhanni.events.CropClickEvent import at.hannibal2.skyhanni.events.FarmingContestEvent @@ -12,7 +11,7 @@ import at.hannibal2.skyhanni.utils.TimeUtils import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class JacobContestStatsSummary { - private val config get() = SkyHanniMod.feature.garden + private val config get() = GardenAPI.config private var blocksBroken = 0 private var startTime = 0L diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestTimeNeeded.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestTimeNeeded.kt index 4d9e035cd..3ce6178ad 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestTimeNeeded.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestTimeNeeded.kt @@ -1,10 +1,10 @@ package at.hannibal2.skyhanni.features.garden.contest -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.GuiRenderEvent import at.hannibal2.skyhanni.events.InventoryUpdatedEvent import at.hannibal2.skyhanni.features.garden.CropType import at.hannibal2.skyhanni.features.garden.FarmingFortuneDisplay.Companion.getLatestTrueFarmingFortune +import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed.getLatestBlocksPerSecond import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList @@ -19,7 +19,7 @@ import net.minecraftforge.fml.common.eventhandler.EventPriority import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class JacobContestTimeNeeded { - private val config get() = SkyHanniMod.feature.garden + private val config get() = GardenAPI.config private var display = emptyList<List<Any>>() private var currentBracket = ContestBracket.GOLD diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/ArmorDropTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/ArmorDropTracker.kt index 21c271e49..f3fac8d2d 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/ArmorDropTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/ArmorDropTracker.kt @@ -1,7 +1,8 @@ package at.hannibal2.skyhanni.features.garden.farming -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator +import at.hannibal2.skyhanni.data.jsonobjects.repo.ArmorDropsJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.ArmorDropsJson.DropInfo import at.hannibal2.skyhanni.events.GuiRenderEvent import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.LorenzTickEvent @@ -16,8 +17,6 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.addOrPut import at.hannibal2.skyhanni.utils.LorenzUtils.sortedDesc import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators import at.hannibal2.skyhanni.utils.SimpleTimeMark -import at.hannibal2.skyhanni.utils.jsonobjects.ArmorDropsJson -import at.hannibal2.skyhanni.utils.jsonobjects.ArmorDropsJson.DropInfo import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker import at.hannibal2.skyhanni.utils.tracker.TrackerData import com.google.gson.JsonObject @@ -29,7 +28,7 @@ object ArmorDropTracker { private var hasArmor = false private val armorPattern = "(FERMENTO|CROPIE|SQUASH|MELON)_(LEGGINGS|CHESTPLATE|BOOTS|HELMET)".toPattern() - private val config get() = SkyHanniMod.feature.garden.farmingArmorDrop + private val config get() = GardenAPI.config.farmingArmorDrop private val tracker = SkyHanniTracker("Armor Drop Tracker", { Data() }, { it.garden.armorDropTracker }) { drawDisplay(it) } diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropMoneyDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropMoneyDisplay.kt index b780bbc0e..937a94a45 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropMoneyDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropMoneyDisplay.kt @@ -2,6 +2,7 @@ package at.hannibal2.skyhanni.features.garden.farming import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator +import at.hannibal2.skyhanni.config.features.garden.MoneyPerHourConfig.CustomFormatEntry import at.hannibal2.skyhanni.events.GardenToolChangeEvent import at.hannibal2.skyhanni.events.GuiRenderEvent import at.hannibal2.skyhanni.events.LorenzTickEvent @@ -16,6 +17,7 @@ import at.hannibal2.skyhanni.features.garden.GardenNextJacobContest import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed.getSpeed import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed.isSpeedDataEmpty import at.hannibal2.skyhanni.test.command.ErrorManager +import at.hannibal2.skyhanni.utils.ConfigUtils import at.hannibal2.skyhanni.utils.InventoryUtils import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName import at.hannibal2.skyhanni.utils.ItemUtils.getItemNameOrNull @@ -50,7 +52,7 @@ object CropMoneyDisplay { } private var display = emptyList<List<Any>>() - private val config get() = SkyHanniMod.feature.garden.moneyPerHours + private val config get() = GardenAPI.config.moneyPerHours private var loaded = false private var ready = false private val cropNames = mutableMapOf<NEUInternalName, CropType>() @@ -110,7 +112,7 @@ object CropMoneyDisplay { newDisplay.addAsSingletonList(fullTitle(title)) - if (!SkyHanniMod.feature.garden.cropMilestones.progress) { + if (!GardenAPI.config.cropMilestones.progress) { newDisplay.addAsSingletonList("§cCrop Milestone Progress Display is disabled!") return newDisplay } @@ -235,6 +237,7 @@ object CropMoneyDisplay { return if (config.hideTitle) newDisplay.drop(1) else newDisplay } + // TODO : Rewrite to not be index-reliant private fun fullTitle(title: String): String { val titleText: String val nameList = mutableListOf<String>() @@ -246,7 +249,8 @@ object CropMoneyDisplay { ) val list = mutableListOf<String>() for (index in config.customFormat) { - map[index]?.let { + // TODO, change functionality to use enum rather than ordinals + map[index.ordinal]?.let { list.add(it) } } @@ -276,8 +280,7 @@ object CropMoneyDisplay { val onlyNpcPrice = (!config.useCustomFormat && LorenzUtils.noTradeMode) || - (config.useCustomFormat && config.customFormat.size == 1 && - config.customFormat[0] == 2) + (config.useCustomFormat && config.customFormat.singleOrNull() == CustomFormatEntry.NPC_PRICE) for ((internalName, amount) in multipliers.moveEntryToTop { isSeeds(it.key) }) { val crop = cropNames[internalName]!! @@ -364,6 +367,7 @@ object CropMoneyDisplay { private fun isSeeds(internalName: NEUInternalName) = internalName.equals("ENCHANTED_SEEDS") || internalName.equals("SEEDS") + // TODO : Rewrite to not be index-reliant private fun formatNumbers(sellOffer: Double, instantSell: Double, npcPrice: Double): Array<Double> { return if (config.useCustomFormat) { val map = mapOf( @@ -373,7 +377,8 @@ object CropMoneyDisplay { ) val newList = mutableListOf<Double>() for (index in config.customFormat) { - map[index]?.let { + // TODO, change functionality to use enum rather than ordinals + map[index.ordinal]?.let { newList.add(it) } } @@ -436,5 +441,8 @@ object CropMoneyDisplay { event.move(3, "garden.moneyPerHourDicer", "garden.moneyPerHours.dicer") event.move(3, "garden.moneyPerHourHideTitle", "garden.moneyPerHours.hideTitle") event.move(3, "garden.moneyPerHourPos", "garden.moneyPerHours.pos") + event.move(11, "garden.moneyPerHours.customFormat") { element -> + ConfigUtils.migrateIntArrayListToEnumArrayList(element, CustomFormatEntry::class.java) + } } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropSpeedMeter.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropSpeedMeter.kt index fd337a361..2d1580974 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropSpeedMeter.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropSpeedMeter.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden.farming -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.data.GardenCropMilestones.getCounter import at.hannibal2.skyhanni.events.CropClickEvent import at.hannibal2.skyhanni.events.CropMilestoneUpdateEvent @@ -128,7 +127,7 @@ class CropSpeedMeter { fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) { if (!isEnabled()) return - SkyHanniMod.feature.garden.cropSpeedMeterPos.renderStrings(display, posLabel = "Crop Speed Meter") + GardenAPI.config.cropSpeedMeterPos.renderStrings(display, posLabel = "Crop Speed Meter") } fun isEnabled() = enabled && GardenAPI.inGarden() diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/DicerDropTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/DicerDropTracker.kt index 24f55672b..b347d6dfe 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/DicerDropTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/DicerDropTracker.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden.farming -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigManager import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.events.GardenToolChangeEvent @@ -13,14 +12,16 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList import at.hannibal2.skyhanni.utils.LorenzUtils.addOrPut import at.hannibal2.skyhanni.utils.LorenzUtils.sortedDesc import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker import at.hannibal2.skyhanni.utils.tracker.TrackerData import com.google.gson.annotations.Expose import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.util.regex.Pattern object DicerDropTracker { private val itemDrops = mutableListOf<ItemDrop>() - private val config get() = SkyHanniMod.feature.garden.dicerCounters + private val config get() = GardenAPI.config.dicerCounters private val tracker = SkyHanniTracker("Dicer Drop Tracker", { Data() }, { it.garden.dicerDropTracker }) { drawDisplay(it) } @@ -33,16 +34,35 @@ object DicerDropTracker { var drops: MutableMap<CropType, MutableMap<DropRarity, Int>> = mutableMapOf() } + // TODO USE SH-REPO + private val melonUncommonDropPattern = + "§a§lUNCOMMON DROP! §r§eDicer dropped §r§a(\\d+)x §r§aEnchanted Melon§r§e!".toPattern() + private val melonRareDropPattern = + "§9§lRARE DROP! §r§eDicer dropped §r§a(\\d+)x §r§aEnchanted Melon§r§e!".toPattern() + private val melonCrazyRareDropPattern = + "§d§lCRAZY RARE DROP! §r§eDicer dropped §r§[a|9](\\d+)x §r§[a|9]Enchanted Melon(?: Block)?§r§e!".toPattern() + private val melonRngesusDropPattern = + "§5§lPRAY TO RNGESUS DROP! §r§eDicer dropped §r§9(\\d+)x §r§9Enchanted Melon Block§r§e!".toPattern() + + private val pumpkinUncommonDropPattern = + "§a§lUNCOMMON DROP! §r§eDicer dropped §r§a(\\d+)x §r§aEnchanted Pumpkin§r§e!".toPattern() + private val pumpkinRareDropPattern = + "§9§lRARE DROP! §r§eDicer dropped §r§a(\\d+)x §r§aEnchanted Pumpkin§r§e!".toPattern() + private val pumpkinCrazyRareDropPattern = + "§d§lCRAZY RARE DROP! §r§eDicer dropped §r§a(\\d+)x §r§aEnchanted Pumpkin§r§e!".toPattern() + private val pumpkinRngesusDropPattern = + "§5§lPRAY TO RNGESUS DROP! §r§eDicer dropped §r§[a|9](\\d+)x §r§(aEnchanted|9Polished) Pumpkin§r§e!".toPattern() + init { - itemDrops.add(ItemDrop(CropType.MELON, DropRarity.UNCOMMON, "§a§lUNCOMMON DROP! §r§eDicer dropped §r§a(\\d+)x §r§aEnchanted Melon§r§e!".toRegex())) - itemDrops.add(ItemDrop(CropType.MELON, DropRarity.RARE, "§9§lRARE DROP! §r§eDicer dropped §r§a(\\d+)x §r§aEnchanted Melon§r§e!".toRegex())) - itemDrops.add(ItemDrop(CropType.MELON, DropRarity.CRAZY_RARE, "§d§lCRAZY RARE DROP! §r§eDicer dropped §r§[a|9](\\d+)x §r§[a|9]Enchanted Melon(?: Block)?§r§e!".toRegex())) - itemDrops.add(ItemDrop(CropType.MELON, DropRarity.PRAY_TO_RNGESUS, "§5§lPRAY TO RNGESUS DROP! §r§eDicer dropped §r§9(\\d+)x §r§9Enchanted Melon Block§r§e!".toRegex())) - - itemDrops.add(ItemDrop(CropType.PUMPKIN, DropRarity.UNCOMMON, "§a§lUNCOMMON DROP! §r§eDicer dropped §r§a(\\d+)x §r§aEnchanted Pumpkin§r§e!".toRegex())) - itemDrops.add(ItemDrop(CropType.PUMPKIN, DropRarity.RARE, "§9§lRARE DROP! §r§eDicer dropped §r§a(\\d+)x §r§aEnchanted Pumpkin§r§e!".toRegex())) - itemDrops.add(ItemDrop(CropType.PUMPKIN, DropRarity.CRAZY_RARE, "§d§lCRAZY RARE DROP! §r§eDicer dropped §r§a(\\d+)x §r§aEnchanted Pumpkin§r§e!".toRegex())) - itemDrops.add(ItemDrop(CropType.PUMPKIN, DropRarity.PRAY_TO_RNGESUS, "§5§lPRAY TO RNGESUS DROP! §r§eDicer dropped §r§[a|9](\\d+)x §r§(aEnchanted|9Polished) Pumpkin§r§e!".toRegex())) + itemDrops.add(ItemDrop(CropType.MELON, DropRarity.UNCOMMON, melonUncommonDropPattern)) + itemDrops.add(ItemDrop(CropType.MELON, DropRarity.RARE, melonRareDropPattern)) + itemDrops.add(ItemDrop(CropType.MELON, DropRarity.CRAZY_RARE, melonCrazyRareDropPattern)) + itemDrops.add(ItemDrop(CropType.MELON, DropRarity.PRAY_TO_RNGESUS, melonRngesusDropPattern)) + + itemDrops.add(ItemDrop(CropType.PUMPKIN, DropRarity.UNCOMMON, pumpkinUncommonDropPattern)) + itemDrops.add(ItemDrop(CropType.PUMPKIN, DropRarity.RARE, pumpkinRareDropPattern)) + itemDrops.add(ItemDrop(CropType.PUMPKIN, DropRarity.CRAZY_RARE, pumpkinCrazyRareDropPattern)) + itemDrops.add(ItemDrop(CropType.PUMPKIN, DropRarity.PRAY_TO_RNGESUS, pumpkinRngesusDropPattern)) } enum class DropRarity(val displayName: String) { @@ -59,7 +79,7 @@ object DicerDropTracker { val message = event.message for (drop in itemDrops) { - if (drop.pattern.matches(message)) { + drop.pattern.matchMatcher(message) { addDrop(drop.crop, drop.rarity) if (config.hideChat) { event.blockedReason = "dicer_drop_tracker" @@ -107,7 +127,7 @@ object DicerDropTracker { tracker.renderDisplay(config.pos) } - class ItemDrop(val crop: CropType, val rarity: DropRarity, val pattern: Regex) + class ItemDrop(val crop: CropType, val rarity: DropRarity, val pattern: Pattern) fun isEnabled() = GardenAPI.inGarden() && config.display diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt index fb9bdfaac..4b478c28f 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt @@ -90,7 +90,7 @@ class FarmingWeightDisplay { } companion object { - private val config get() = SkyHanniMod.feature.garden.eliteFarmingWeights + private val config get() = GardenAPI.config.eliteFarmingWeights private val localCounter = mutableMapOf<CropType, Long>() private var dispatcher = Dispatchers.IO diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBestCropTime.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBestCropTime.kt index 0ef03d090..6190bc27b 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBestCropTime.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBestCropTime.kt @@ -1,11 +1,11 @@ package at.hannibal2.skyhanni.features.garden.farming -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.data.GardenCropMilestones import at.hannibal2.skyhanni.data.GardenCropMilestones.getCounter import at.hannibal2.skyhanni.data.GardenCropMilestones.isMaxed import at.hannibal2.skyhanni.features.garden.CropType +import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.features.garden.GardenAPI.addCropIcon import at.hannibal2.skyhanni.features.garden.GardenNextJacobContest import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed.getSpeed @@ -19,7 +19,7 @@ class GardenBestCropTime { var display = emptyList<List<Any>>() companion object { - private val config get() = SkyHanniMod.feature.garden.cropMilestones + private val config get() = GardenAPI.config.cropMilestones val timeTillNextCrop = mutableMapOf<CropType, Long>() fun reset() { @@ -95,7 +95,8 @@ class GardenBestCropTime { for (crop in sorted.keys) { if (crop.isMaxed()) continue val millis = timeTillNextCrop[crop]!! - val biggestUnit = TimeUnit.entries[config.highestTimeFormat.get()] + // TODO, change functionality to use enum rather than ordinals + val biggestUnit = TimeUnit.entries[config.highestTimeFormat.get().ordinal] val duration = TimeUtils.formatDuration(millis, biggestUnit, maxUnits = 2) val isCurrent = crop == currentCrop number++ @@ -136,4 +137,4 @@ class GardenBestCropTime { event.move(3, "garden.cropMilestoneBestCompact", "garden.cropMilestones.next.bestCompact") event.move(3, "garden.cropMilestoneBestHideTitle", "garden.cropMilestones.next.bestHideTitle") } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBurrowingSporesNotifier.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBurrowingSporesNotifier.kt index 93387ac32..33036b52a 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBurrowingSporesNotifier.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBurrowingSporesNotifier.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden.farming -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.utils.LorenzUtils @@ -12,7 +11,7 @@ class GardenBurrowingSporesNotifier { @SubscribeEvent fun onChat(event: LorenzChatEvent) { if (!GardenAPI.inGarden()) return - if (!SkyHanniMod.feature.garden.burrowingSporesNotification) return + if (!GardenAPI.config.burrowingSporesNotification) return if (event.message.endsWith("§6§lVERY RARE CROP! §r§f§r§9Burrowing Spores")) { LorenzUtils.sendTitle("§9Burrowing Spores!", 5.seconds) @@ -20,4 +19,4 @@ class GardenBurrowingSporesNotifier { // ItemBlink.setBlink(NEUItems.getItemStackOrNull("BURROWING_SPORES"), 5_000) } } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropMilestoneDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropMilestoneDisplay.kt index 76647517d..adfe0518d 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropMilestoneDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropMilestoneDisplay.kt @@ -1,7 +1,9 @@ package at.hannibal2.skyhanni.features.garden.farming -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator +import at.hannibal2.skyhanni.config.features.garden.cropmilestones.CropMilestonesConfig.MilestoneTextEntry +import at.hannibal2.skyhanni.config.features.garden.cropmilestones.CropMilestonesConfig.TimeFormatEntry +import at.hannibal2.skyhanni.config.features.garden.cropmilestones.MushroomPetPerkConfig.MushroomTextEntry import at.hannibal2.skyhanni.data.GardenCropMilestones import at.hannibal2.skyhanni.data.GardenCropMilestones.getCounter import at.hannibal2.skyhanni.data.GardenCropMilestones.isMaxed @@ -18,6 +20,7 @@ import at.hannibal2.skyhanni.features.garden.GardenAPI.addCropIcon import at.hannibal2.skyhanni.features.garden.GardenAPI.getCropType import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed.setSpeed import at.hannibal2.skyhanni.test.command.ErrorManager +import at.hannibal2.skyhanni.utils.ConfigUtils import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList import at.hannibal2.skyhanni.utils.LorenzUtils.round @@ -34,7 +37,7 @@ object GardenCropMilestoneDisplay { private var progressDisplay = emptyList<List<Any>>() private var mushroomCowPerkDisplay = emptyList<List<Any>>() private val cultivatingData = mutableMapOf<CropType, Long>() - private val config get() = SkyHanniMod.feature.garden.cropMilestones + private val config get() = GardenAPI.config.cropMilestones private val bestCropTime = GardenBestCropTime() private var lastPlaySoundTime = 0L @@ -176,7 +179,8 @@ object GardenCropMilestoneDisplay { val missingTimeSeconds = missing / farmingFortuneSpeed val millis = missingTimeSeconds * 1000 GardenBestCropTime.timeTillNextCrop[crop] = millis - val biggestUnit = TimeUnit.entries[config.highestTimeFormat.get()] + // TODO, change functionality to use enum rather than ordinals + val biggestUnit = TimeUnit.entries[config.highestTimeFormat.get().ordinal] val duration = TimeUtils.formatDuration(millis, biggestUnit) tryWarn(millis, "§b${crop.cropName} $nextTier in $duration") val speedText = "§7In §b$duration" @@ -225,7 +229,8 @@ object GardenCropMilestoneDisplay { private fun formatDisplay(lineMap: HashMap<Int, List<Any>>): MutableList<List<Any>> { val newList = mutableListOf<List<Any>>() for (index in config.text) { - lineMap[index]?.let { + // TODO, change functionality to use enum rather than ordinals + lineMap[index.ordinal]?.let { newList.add(it) } } @@ -238,14 +243,23 @@ object GardenCropMilestoneDisplay { } private fun addMushroomCowData() { + val mushroom = CropType.MUSHROOM + if (mushroom.isMaxed()) { + mushroomCowPerkDisplay = listOf( + listOf("§6Mooshroom Cow Perk"), + listOf("§eMushroom crop is maxed!"), + ) + return + } + val lineMap = HashMap<Int, List<Any>>() - val counter = CropType.MUSHROOM.getCounter() + val counter = mushroom.getCounter() - val currentTier = GardenCropMilestones.getTierForCropCount(counter, CropType.MUSHROOM) + val currentTier = GardenCropMilestones.getTierForCropCount(counter, mushroom) val nextTier = currentTier + 1 - val cropsForCurrentTier = GardenCropMilestones.getCropsForTier(currentTier, CropType.MUSHROOM) - val cropsForNextTier = GardenCropMilestones.getCropsForTier(nextTier, CropType.MUSHROOM) + val cropsForCurrentTier = GardenCropMilestones.getCropsForTier(currentTier, mushroom) + val cropsForNextTier = GardenCropMilestones.getCropsForTier(nextTier, mushroom) val have = counter - cropsForCurrentTier val need = cropsForNextTier - cropsForCurrentTier @@ -258,7 +272,7 @@ object GardenCropMilestoneDisplay { lineMap[0] = Collections.singletonList("§6Mooshroom Cow Perk") val list = mutableListOf<Any>() - list.addCropIcon(CropType.MUSHROOM) + list.addCropIcon(mushroom) list.add("§7Mushroom Tier $nextTier") lineMap[1] = list @@ -270,7 +284,8 @@ object GardenCropMilestoneDisplay { val missingTimeSeconds = missing / blocksPerSecond val millis = missingTimeSeconds * 1000 - val biggestUnit = TimeUnit.entries[config.highestTimeFormat.get()] + // TODO, change functionality to use enum rather than ordinals + val biggestUnit = TimeUnit.entries[config.highestTimeFormat.get().ordinal] val duration = TimeUtils.formatDuration(millis.toLong(), biggestUnit) lineMap[3] = Collections.singletonList("§7In §b$duration") } @@ -280,7 +295,8 @@ object GardenCropMilestoneDisplay { val newList = mutableListOf<List<Any>>() for (index in config.mushroomPetPerk.text) { - lineMap[index]?.let { + // TODO, change functionality to use enum rather than ordinals + lineMap[index.ordinal]?.let { newList.add(it) } } @@ -304,5 +320,26 @@ object GardenCropMilestoneDisplay { event.move(3, "garden.cropMilestoneMushroomPetPerkEnabled", "garden.cropMilestones.mushroomPetPerk.enabled") event.move(3, "garden.cropMilestoneMushroomPetPerkText", "garden.cropMilestones.mushroomPetPerk.text") event.move(3, "garden.cropMilestoneMushroomPetPerkPos", "garden.cropMilestones.mushroomPetPerk.pos") + event.move( + 11, + "garden.cropMilestones.highestTimeFormat", + "garden.cropMilestones.highestTimeFormat" + ) { element -> + ConfigUtils.migrateIntToEnum(element, TimeFormatEntry::class.java) + } + event.move( + 11, + "garden.cropMilestones.text", + "garden.cropMilestones.text" + ) { element -> + ConfigUtils.migrateIntArrayListToEnumArrayList(element, MilestoneTextEntry::class.java) + } + event.move( + 11, + "garden.cropMilestones.mushroomPetPerk.text", + "garden.cropMilestones.mushroomPetPerk.text" + ) { element -> + ConfigUtils.migrateIntArrayListToEnumArrayList(element, MushroomTextEntry::class.java) + } } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropSpeed.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropSpeed.kt index 0f10ed883..a21f57698 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropSpeed.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropSpeed.kt @@ -1,11 +1,12 @@ package at.hannibal2.skyhanni.features.garden.farming -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.data.ClickType import at.hannibal2.skyhanni.data.GardenCropMilestones.getCounter import at.hannibal2.skyhanni.data.GardenCropMilestones.setCounter import at.hannibal2.skyhanni.data.MayorElection +import at.hannibal2.skyhanni.data.jsonobjects.repo.DicerDropsJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.DicerDropsJson.DicerType import at.hannibal2.skyhanni.events.CropClickEvent import at.hannibal2.skyhanni.events.GardenToolChangeEvent import at.hannibal2.skyhanni.events.PreProfileSwitchEvent @@ -15,13 +16,11 @@ import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.utils.InventoryUtils import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy -import at.hannibal2.skyhanni.utils.jsonobjects.DicerDropsJson -import at.hannibal2.skyhanni.utils.jsonobjects.DicerDropsJson.DicerType import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import kotlin.concurrent.fixedRateTimer object GardenCropSpeed { - private val config get() = SkyHanniMod.feature.garden + private val config get() = GardenAPI.config private val cropsPerSecond: MutableMap<CropType, Int>? get() = GardenAPI.storage?.cropsPerSecond private val latestBlocksPerSecond: MutableMap<CropType, Double>? get() = GardenAPI.storage?.latestBlocksPerSecond diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCustomKeybinds.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCustomKeybinds.kt index 6b30cf3af..6bbde660f 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCustomKeybinds.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCustomKeybinds.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden.farming -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.mixins.transformers.AccessorKeyBinding @@ -14,24 +13,24 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable import java.util.IdentityHashMap object GardenCustomKeybinds { - private val shConfig get() = SkyHanniMod.feature.garden.keyBind + private val config get() = GardenAPI.config.keyBind private val mcSettings get() = Minecraft.getMinecraft().gameSettings private val map: MutableMap<KeyBinding, () -> Int> = IdentityHashMap() private var lastWindowOpenTime = 0L init { - map[mcSettings.keyBindAttack] = { shConfig.attack } - map[mcSettings.keyBindUseItem] = { shConfig.useItem } - map[mcSettings.keyBindLeft] = { shConfig.left } - map[mcSettings.keyBindRight] = { shConfig.right } - map[mcSettings.keyBindForward] = { shConfig.forward } - map[mcSettings.keyBindBack] = { shConfig.back } - map[mcSettings.keyBindJump] = { shConfig.jump } - map[mcSettings.keyBindSneak] = { shConfig.sneak } + map[mcSettings.keyBindAttack] = { config.attack } + map[mcSettings.keyBindUseItem] = { config.useItem } + map[mcSettings.keyBindLeft] = { config.left } + map[mcSettings.keyBindRight] = { config.right } + map[mcSettings.keyBindForward] = { config.forward } + map[mcSettings.keyBindBack] = { config.back } + map[mcSettings.keyBindJump] = { config.jump } + map[mcSettings.keyBindSneak] = { config.sneak } } - private fun isEnabled() = GardenAPI.inGarden() && shConfig.enabled + private fun isEnabled() = GardenAPI.inGarden() && config.enabled private fun isActive(): Boolean { if (!isEnabled()) return false @@ -80,4 +79,4 @@ object GardenCustomKeybinds { event.move(3, "garden.keyBindJump", "garden.keyBind.jump") event.move(3, "garden.keyBindSneak", "garden.keyBind.sneak") } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenStartLocation.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenStartLocation.kt index 3384af51e..f1fdd112a 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenStartLocation.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenStartLocation.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden.farming -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.CropClickEvent import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent import at.hannibal2.skyhanni.features.garden.GardenAPI @@ -12,13 +11,14 @@ import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText import net.minecraftforge.fml.common.eventhandler.SubscribeEvent object GardenStartLocation { + private val config get() = GardenAPI.config.cropStartLocation fun setLocationCommand() { if (!GardenAPI.inGarden()) { LorenzUtils.userError("This Command only works in the garden!") return } - if (!SkyHanniMod.feature.garden.cropStartLocation.enabled) { + if (!config.enabled) { LorenzUtils.clickableChat( "This feature is disabled. Enable it in the config: §e/sh crop start location", "sh crop start location", @@ -67,5 +67,5 @@ object GardenStartLocation { event.drawDynamicText(location, crop.cropName, 1.5) } - fun isEnabled() = GardenAPI.inGarden() && SkyHanniMod.feature.garden.cropStartLocation.enabled + fun isEnabled() = GardenAPI.inGarden() && config.enabled } diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/WildStrawberryDyeNotification.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/WildStrawberryDyeNotification.kt index d923efb6d..aaa1a734c 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/WildStrawberryDyeNotification.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/WildStrawberryDyeNotification.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden.farming -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.GuiContainerEvent import at.hannibal2.skyhanni.events.OwnInventoryItemUpdateEvent import at.hannibal2.skyhanni.features.garden.GardenAPI @@ -10,7 +9,6 @@ import at.hannibal2.skyhanni.utils.ItemUtils.name import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName import at.hannibal2.skyhanni.utils.SoundUtils -import io.github.moulberry.notenoughupdates.util.MinecraftExecutor import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import kotlin.time.Duration.Companion.seconds @@ -27,23 +25,21 @@ class WildStrawberryDyeNotification { @SubscribeEvent fun onOwnInventoryItemUpdate(event: OwnInventoryItemUpdateEvent) { if (!GardenAPI.inGarden()) return - if (!SkyHanniMod.feature.garden.wildStrawberryDyeNotification) return + if (!GardenAPI.config.wildStrawberryDyeNotification) return val itemStack = event.itemStack - MinecraftExecutor.OnThread.execute { - - // Prevent false positives when buying the item in ah or moving it from a storage - val diff = System.currentTimeMillis() - lastCloseTime - if (diff < 1_000) return@execute - - val internalName = itemStack.getInternalName() - if (internalName == item) { - val name = itemStack.name!! - LorenzUtils.sendTitle(name, 5.seconds) - LorenzUtils.chat("You found a $name§e!") - SoundUtils.playBeepSound() - ItemBlink.setBlink(itemStack, 5_000) - } + + // Prevent false positives when buying the item in ah or moving it from a storage + val diff = System.currentTimeMillis() - lastCloseTime + if (diff < 1_000) return + + val internalName = itemStack.getInternalName() + if (internalName == item) { + val name = itemStack.name!! + LorenzUtils.sendTitle(name, 5.seconds) + LorenzUtils.chat("You found a $name§e!") + SoundUtils.playBeepSound() + ItemBlink.setBlink(itemStack, 5_000) } } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/WrongFungiCutterWarning.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/WrongFungiCutterWarning.kt index e7bdce1db..dc31789a9 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/WrongFungiCutterWarning.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/WrongFungiCutterWarning.kt @@ -1,11 +1,11 @@ package at.hannibal2.skyhanni.features.garden.farming -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.data.ClickType import at.hannibal2.skyhanni.events.CropClickEvent import at.hannibal2.skyhanni.events.GardenToolChangeEvent import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.features.garden.CropType +import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.utils.ItemUtils.name import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getFungiCutterMode @@ -44,7 +44,7 @@ class WrongFungiCutterWarning { } private fun notifyWrong() { - if (!SkyHanniMod.feature.garden.fungiCutterWarn) return + if (!GardenAPI.config.fungiCutterWarn) return LorenzUtils.sendTitle("§cWrong Fungi Cutter Mode!", 2.seconds) if (System.currentTimeMillis() > lastPlaySoundTime + 3_00) { 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 483cce5a5..04fc38a6e 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 @@ -13,7 +13,7 @@ import at.hannibal2.skyhanni.utils.ItemUtils.getItemRarityOrNull import at.hannibal2.skyhanni.utils.ItemUtils.getLore import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimal -import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded +import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getEnchantments import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.StringUtils.removeColor @@ -170,7 +170,7 @@ class CaptureFarmingGear { if (event.inventoryName.contains("Your Skills")) { for ((_, item) in event.inventoryItems) { if (item.displayName.contains("Farming ")) { - storage.farmingLevel = item.displayName.split(" ").last().romanToDecimalIfNeeded() + storage.farmingLevel = item.displayName.split(" ").last().romanToDecimalIfNecessary() } } } @@ -226,7 +226,7 @@ class CaptureFarmingGear { ProfileStorageData.playerSpecific?.gardenCommunityUpgrade = group("level").romanToDecimal() } farmingLevelUpPattern.matchMatcher(msg) { - storage.farmingLevel = group("level").romanToDecimalIfNeeded() + storage.farmingLevel = group("level").romanToDecimalIfNecessary() } anitaBuffPattern.matchMatcher(msg) { storage.anitaUpgrade = group("level").toInt() / 4 diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/OverviewPage.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/OverviewPage.kt index 2fe623c74..670756832 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/OverviewPage.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/OverviewPage.kt @@ -210,11 +210,19 @@ class OverviewPage : FFGuideGUI.FFGuidePage() { else -> FFStats.equipmentTotalFF } + val maxEquipmentBaseFortune = 5.0 + val maxEquipmentAbilityFortune = 15.0 + val maxEquipmentReforgeFortune = 15.0 + val maxGreenThumbFortune = GardenAPI.totalAmountVisitorsExisting.toDouble() / 4 + + val maxFortunePerPiece = maxEquipmentBaseFortune + maxEquipmentAbilityFortune + maxEquipmentReforgeFortune + maxGreenThumbFortune + line = if (currentEquipment == 0) "§7§2Total fortune from all your equipment\n§2Select a piece for more info" else "§7§2Total fortune from your\n${equipmentItem.getItem().displayName}" GuiRenderUtils.drawFarmingBar( "§2Total $word Fortune", line, equipmentFF[FFTypes.TOTAL] ?: 0, - if (currentEquipment == 0) 218 else 54.5, + if (currentEquipment == 0) maxFortunePerPiece * 4 else maxFortunePerPiece, + FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 30, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay ) @@ -222,7 +230,7 @@ class OverviewPage : FFGuideGUI.FFGuidePage() { else "§7§2Total base fortune from your\n${equipmentItem.getItem().displayName}" GuiRenderUtils.drawFarmingBar( "§2$word Base Fortune", line, equipmentFF[FFTypes.BASE] ?: 0, - if (currentEquipment == 0) 20 else 5, + if (currentEquipment == 0) maxEquipmentBaseFortune * 4 else maxEquipmentBaseFortune, FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 55, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay ) @@ -231,7 +239,7 @@ class OverviewPage : FFGuideGUI.FFGuidePage() { else "§7§2Total ability fortune from your\n${equipmentItem.getItem().displayName}" GuiRenderUtils.drawFarmingBar( "§2$word Ability", line, equipmentFF[FFTypes.ABILITY] ?: 0, - if (currentEquipment == 0) 60 else 15, + if (currentEquipment == 0) maxEquipmentAbilityFortune * 4 else maxEquipmentAbilityFortune, FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 80, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay ) @@ -240,11 +248,10 @@ class OverviewPage : FFGuideGUI.FFGuidePage() { else "§7§2Total reforge fortune from your\n${equipmentItem.getItem().displayName}" GuiRenderUtils.drawFarmingBar( "§2$word Reforge", line, equipmentFF[FFTypes.REFORGE] ?: 0, - if (currentEquipment == 0) 60 else 15, + if (currentEquipment == 0) maxEquipmentReforgeFortune * 4 else maxEquipmentReforgeFortune, FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 105, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay ) - val maxGreenThumbFortune = GardenAPI.totalAmountVisitorsExisting.toDouble() / 4 line = if (currentEquipment == 0) "§7§2The fortune from all of your equipment's enchantments\n§2Select a piece for more info" else "§7§2Total enchantment fortune from your\n${equipmentItem.getItem().displayName}" diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/AnitaExtraFarmingFortune.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/AnitaExtraFarmingFortune.kt index 2af928a30..683834419 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/AnitaExtraFarmingFortune.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/AnitaExtraFarmingFortune.kt @@ -1,7 +1,8 @@ package at.hannibal2.skyhanni.features.garden.inventory -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator +import at.hannibal2.skyhanni.data.jsonobjects.repo.AnitaUpgradeCostsJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.AnitaUpgradeCostsJson.Price import at.hannibal2.skyhanni.events.RepositoryReloadEvent import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.utils.InventoryUtils @@ -12,13 +13,11 @@ import at.hannibal2.skyhanni.utils.NumberUtil import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher -import at.hannibal2.skyhanni.utils.jsonobjects.AnitaUpgradeCostsJson -import at.hannibal2.skyhanni.utils.jsonobjects.AnitaUpgradeCostsJson.Price import net.minecraftforge.event.entity.player.ItemTooltipEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class AnitaExtraFarmingFortune { - private val config get() = SkyHanniMod.feature.garden.anitaShop + private val config get() = GardenAPI.config.anitaShop private var levelPrice = mapOf<Int, Price>() @SubscribeEvent diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenCropMilestoneInventory.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenCropMilestoneInventory.kt index cb236050b..6a37862a9 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenCropMilestoneInventory.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenCropMilestoneInventory.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden.inventory -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.data.GardenCropMilestones import at.hannibal2.skyhanni.data.GardenCropMilestones.getCounter @@ -8,6 +7,7 @@ import at.hannibal2.skyhanni.events.CropMilestoneUpdateEvent import at.hannibal2.skyhanni.events.InventoryCloseEvent import at.hannibal2.skyhanni.events.RenderInventoryItemTipEvent import at.hannibal2.skyhanni.features.garden.CropType +import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.indexOfFirst import at.hannibal2.skyhanni.utils.LorenzUtils.round @@ -19,7 +19,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class GardenCropMilestoneInventory { private var average = -1.0 - private val config get() = SkyHanniMod.feature.garden + private val config get() = GardenAPI.config @SubscribeEvent fun onCropMilestoneUpdate(event: CropMilestoneUpdateEvent) { diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenDeskInSBMenu.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenDeskInSBMenu.kt index a3f72ac4c..bc20b44a3 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenDeskInSBMenu.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenDeskInSBMenu.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden.inventory -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.InventoryCloseEvent import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent import at.hannibal2.skyhanni.features.garden.GardenAPI @@ -15,7 +14,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class GardenDeskInSBMenu { - private val config get() = SkyHanniMod.feature.garden + private val config get() = GardenAPI.config private var showItem = false private val item by lazy { diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenInventoryNumbers.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenInventoryNumbers.kt index fe3d690a3..7ace9f0db 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenInventoryNumbers.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenInventoryNumbers.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden.inventory -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.data.GardenCropMilestones import at.hannibal2.skyhanni.data.GardenCropMilestones.getCounter @@ -10,12 +9,12 @@ import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.utils.InventoryUtils import at.hannibal2.skyhanni.utils.ItemUtils.getLore import at.hannibal2.skyhanni.utils.ItemUtils.name -import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded +import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class GardenInventoryNumbers { - private val config get() = SkyHanniMod.feature.garden.number + private val config get() = GardenAPI.config.number private var patternUpgradeTier = "§7Current Tier: §[ea](?<tier>.*)§7/§a.*".toPattern() @@ -47,7 +46,7 @@ class GardenInventoryNumbers { event.stack.name?.let { ComposterUpgrade.regex.matchMatcher(it) { - val level = group("level")?.romanToDecimalIfNeeded() ?: 0 + val level = group("level")?.romanToDecimalIfNecessary() ?: 0 event.stackTip = "$level" } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenNextPlotPrice.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenNextPlotPrice.kt index 64d176bcd..bd2a3b5a3 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenNextPlotPrice.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenNextPlotPrice.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden.inventory -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.utils.InventoryUtils import at.hannibal2.skyhanni.utils.ItemUtils @@ -16,7 +15,7 @@ class GardenNextPlotPrice { @SubscribeEvent fun onTooltip(event: ItemTooltipEvent) { if (!GardenAPI.inGarden()) return - if (!SkyHanniMod.feature.garden.plotPrice) return + if (!GardenAPI.config.plotPrice) return if (InventoryUtils.openInventoryName() != "Configure Plots") return diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenPlotIcon.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenPlotIcon.kt index cdd5d4358..c7ff13dc6 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenPlotIcon.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenPlotIcon.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden.inventory -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.InventoryCloseEvent import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent import at.hannibal2.skyhanni.events.LorenzToolTipEvent @@ -20,7 +19,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent object GardenPlotIcon { - private val config get() = SkyHanniMod.feature.garden.plotIcon + private val config get() = GardenAPI.config.plotIcon private val plotList get() = GardenAPI.storage?.plotIcon?.plotList private var inInventory = false private var copyStack: ItemStack? = null diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/SkyMartCopperPrice.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/SkyMartCopperPrice.kt index a70ca7f96..e2b15c49c 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/SkyMartCopperPrice.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/SkyMartCopperPrice.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden.inventory -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.events.GuiRenderEvent import at.hannibal2.skyhanni.events.InventoryCloseEvent @@ -21,7 +20,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class SkyMartCopperPrice { private val pattern = "§c(?<amount>.*) Copper".toPattern() private var display = emptyList<List<Any>>() - private val config get() = SkyHanniMod.feature.garden.skyMart + private val config get() = GardenAPI.config.skyMart companion object { var inInventory = false diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestAPI.kt new file mode 100644 index 000000000..5609b61b8 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestAPI.kt @@ -0,0 +1,21 @@ +package at.hannibal2.skyhanni.features.garden.pests + +import at.hannibal2.skyhanni.features.garden.GardenAPI +import at.hannibal2.skyhanni.utils.InventoryUtils +import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName + +object PestAPI { + val config get() = GardenAPI.config.pests + + val vacuumVariants = listOf( + "SKYMART_VACUUM".asInternalName(), + "SKYMART_TURBO_VACUUM".asInternalName(), + "SKYMART_HYPER_VACUUM".asInternalName(), + "INFINI_VACUUM".asInternalName(), + "INFINI_VACUUM_HOOVERIUS".asInternalName(), + ) + + fun hasVacuumInHand() = InventoryUtils.itemInHandId in vacuumVariants + + fun SprayType.getPests() = PestType.entries.filter { it.spray == this } +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestFinder.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestFinder.kt new file mode 100644 index 000000000..dfe34c56c --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestFinder.kt @@ -0,0 +1,226 @@ +package at.hannibal2.skyhanni.features.garden.pests + +import at.hannibal2.skyhanni.events.GuiRenderEvent +import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent +import at.hannibal2.skyhanni.events.IslandChangeEvent +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.LorenzKeyPressEvent +import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent +import at.hannibal2.skyhanni.events.ScoreboardChangeEvent +import at.hannibal2.skyhanni.events.garden.pests.PestSpawnEvent +import at.hannibal2.skyhanni.features.garden.GardenAPI +import at.hannibal2.skyhanni.features.garden.GardenPlotAPI +import at.hannibal2.skyhanni.features.garden.GardenPlotAPI.isPlayerInside +import at.hannibal2.skyhanni.features.garden.GardenPlotAPI.name +import at.hannibal2.skyhanni.features.garden.GardenPlotAPI.pests +import at.hannibal2.skyhanni.features.garden.GardenPlotAPI.renderPlot +import at.hannibal2.skyhanni.features.garden.GardenPlotAPI.sendTeleportTo +import at.hannibal2.skyhanni.test.GriffinUtils.drawWaypointFilled +import at.hannibal2.skyhanni.utils.ItemUtils.getLore +import at.hannibal2.skyhanni.utils.LocationUtils.distanceSqToPlayer +import at.hannibal2.skyhanni.utils.LorenzColor +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.NEUItems +import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber +import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText +import at.hannibal2.skyhanni.utils.RenderUtils.exactPlayerEyeLocation +import at.hannibal2.skyhanni.utils.RenderUtils.renderRenderables +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import at.hannibal2.skyhanni.utils.StringUtils +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher +import at.hannibal2.skyhanni.utils.renderables.Renderable +import net.minecraft.client.Minecraft +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.time.Duration.Companion.seconds + +class PestFinder { + + private val config get() = PestAPI.config.pestFinder + + private val pestsInScoreboardPattern = " §7⏣ §[ac]The Garden §4§lൠ§7 x(?<pests>.*)".toPattern() + + private var display = emptyList<Renderable>() + private var scoreboardPests = 0 + + @SubscribeEvent + fun onPestSpawn(event: PestSpawnEvent) { + if (!isEnabled()) return + PestSpawnTimer.lastSpawnTime = SimpleTimeMark.now() + val plot = GardenPlotAPI.getPlotByName(event.plotName) + if (plot == null) { + LorenzUtils.userError("Open Desk to load plot names and pest locations!") + return + } + plot.pests += event.amountPests + update() + } + + @SubscribeEvent + fun onInventoryOpen(event: InventoryFullyOpenedEvent) { + if (!isEnabled()) return + if (event.inventoryName != "Configure Plots") return + + val pestInventoryPattern = "§4§lൠ §cThis plot has §6(?<amount>\\d) Pests?§c!".toPattern() + + for (plot in GardenPlotAPI.plots) { + plot.pests = 0 + val item = event.inventoryItems[plot.inventorySlot] ?: continue + for (line in item.getLore()) { + pestInventoryPattern.matchMatcher(line) { + plot.pests = group("amount").formatNumber().toInt() + } + } + } + update() + + } + + private fun update() { + display = drawDisplay() + } + + private fun drawDisplay() = buildList { + val totalAmount = getPlotsWithPests().sumOf { it.pests } + if (totalAmount != scoreboardPests) { + add(Renderable.string("§cIncorrect pest amount!")) + add(Renderable.string("§eOpen Configure Plots Menu!")) + return@buildList + } + + add(Renderable.string("§eTotal pests in garden: §c${totalAmount}§7/§c8")) + + for (plot in getPlotsWithPests()) { + val pests = plot.pests + val plotName = plot.name + val pestsName = StringUtils.optionalPlural(pests, "pest", "pests") + val renderable = Renderable.clickAndHover( + "§c$pestsName §7in §b$plotName", + listOf( + "§7Pests Found: §e$pests", + "§7In plot §b$plotName", + "", + "§eClick here to warp!" + ), + onClick = { + plot.sendTeleportTo() + } + ) + add(renderable) + } + } + + @SubscribeEvent + fun onIslandChange(event: IslandChangeEvent) { + update() + } + + @SubscribeEvent + fun onChat(event: LorenzChatEvent) { + if (!isEnabled()) return + if (event.message == "§cThere are no pests in your Garden right now! Keep farming!") { + GardenPlotAPI.plots.forEach { + it.pests = 0 + } + update() + } + } + + @SubscribeEvent + fun onScoreboardChange(event: ScoreboardChangeEvent) { + if (!isEnabled()) return + + var newPests = 0 + for (line in event.newList) { + pestsInScoreboardPattern.matchMatcher(line) { + newPests = group("pests").formatNumber().toInt() + } + } + + if (newPests == scoreboardPests) return + + removePests(scoreboardPests - newPests) + scoreboardPests = newPests + update() + } + + private fun removePests(removedPests: Int) { + if (removedPests < 1) return + repeat(removedPests) { + removeNearestPest() + } + } + + private fun getNearestInfectedPest() = getPlotsWithPests().minByOrNull { it.middle.distanceSqToPlayer() } + + private fun removeNearestPest() { + val plot = getNearestInfectedPest() ?: run { + LorenzUtils.error("Can not remove nearest pest: No infected plots detected.") + return + } + plot.pests-- + } + + @SubscribeEvent + fun onRenderOverlay(event: GuiRenderEvent) { + if (!isEnabled()) return + if (!config.showDisplay) return + if (config.onlyWithVacuum && !PestAPI.hasVacuumInHand()) return + + if (GardenAPI.inGarden() && config.showDisplay) { + config.position.renderRenderables(display, posLabel = "Pest Finder") + } + } + + private fun getPlotsWithPests() = GardenPlotAPI.plots.filter { it.pests > 0 } + + @SubscribeEvent + fun onRenderWorld(event: LorenzRenderWorldEvent) { + if (!isEnabled()) return + if (!config.showPlotInWorld) return + if (config.onlyWithVacuum && !PestAPI.hasVacuumInHand()) return + + val playerLocation = event.exactPlayerEyeLocation() + for (plot in getPlotsWithPests()) { + if (plot.isPlayerInside()) { + event.renderPlot(plot, LorenzColor.RED.toColor(), LorenzColor.DARK_RED.toColor()) + continue + } + event.renderPlot(plot, LorenzColor.GOLD.toColor(), LorenzColor.RED.toColor()) + + val pestsName = StringUtils.optionalPlural(plot.pests, "pest", "pests") + val plotName = plot.name + val middle = plot.middle + val location = playerLocation.copy(x = middle.x, z = middle.z) + event.drawWaypointFilled(location, LorenzColor.RED.toColor()) + event.drawDynamicText(location, "§c$pestsName §7in §b$plotName", 1.5) + + } + } + + private var lastKeyPress = SimpleTimeMark.farPast() + + @SubscribeEvent + fun onKeyClick(event: LorenzKeyPressEvent) { + if (!GardenAPI.inGarden()) return + if (Minecraft.getMinecraft().currentScreen != null) return + if (NEUItems.neuHasFocus()) return + + if (event.keyCode != config.teleportHotkey) return + if (lastKeyPress.passedSince() < 2.seconds) return + lastKeyPress = SimpleTimeMark.now() + + val plot = getNearestInfectedPest() ?: run { + LorenzUtils.userError("No infected plots detected to warp to!") + return + } + + if (plot.isPlayerInside()) { + LorenzUtils.userError("You stand already on the infected plot!") + return + } + + plot.sendTeleportTo() + } + + fun isEnabled() = GardenAPI.inGarden() && (config.showDisplay || config.showPlotInWorld) +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestSpawn.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestSpawn.kt new file mode 100644 index 000000000..934a73ef2 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestSpawn.kt @@ -0,0 +1,57 @@ +package at.hannibal2.skyhanni.features.garden.pests + +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.garden.pests.PestSpawnEvent +import at.hannibal2.skyhanni.features.garden.GardenAPI +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.time.Duration.Companion.seconds + +class PestSpawn { + private val config get() = PestAPI.config.pestSpawn + + private val patternOnePest = "§6§l.*! §7A §6Pest §7has appeared in §aPlot §7- §b(?<plot>.*)§7!".toPattern() + private val patternMultiplePests = + "§6§l.*! §6(?<amount>\\d) Pests §7have spawned in §aPlot §7- §b(?<plot>.*)§7!".toPattern() + + @SubscribeEvent + fun onChat(event: LorenzChatEvent) { + if (!GardenAPI.inGarden()) return + + var blocked = false + + patternOnePest.matchMatcher(event.message) { + pestSpawn(1, group("plot")) + blocked = true + } + patternMultiplePests.matchMatcher(event.message) { + pestSpawn(group("amount").toInt(), group("plot")) + blocked = true + } + if (event.message == " §r§e§lCLICK HERE §eto teleport to the plot!") { + if (PestSpawnTimer.lastSpawnTime.passedSince() < 1.seconds) { + blocked = true + } + } + + if (blocked && config.chatMessageFormat != 0) { + event.blockedReason = "pests_spawn" + } + } + + private fun pestSpawn(amount: Int, plotName: String) { + PestSpawnEvent(amount, plotName).postAndCatch() + + if (config.showTitle) { + LorenzUtils.sendTitle("§aPest Spawn! §e$amount §ain §b$plotName§a!", 7.seconds) + } + + if (config.chatMessageFormat == 1) { + LorenzUtils.clickableChat( + "§aPest Spawn! §e$amount §ain §b$plotName§a!", + "tptoplot $plotName" + ) + } + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestSpawnTimer.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestSpawnTimer.kt new file mode 100644 index 000000000..726032591 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestSpawnTimer.kt @@ -0,0 +1,37 @@ +package at.hannibal2.skyhanni.features.garden.pests + +import at.hannibal2.skyhanni.events.GuiRenderEvent +import at.hannibal2.skyhanni.events.garden.pests.PestSpawnEvent +import at.hannibal2.skyhanni.features.garden.GardenAPI +import at.hannibal2.skyhanni.utils.RenderUtils.renderString +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import at.hannibal2.skyhanni.utils.TimeUtils.format +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +object PestSpawnTimer { + private val config get() = PestAPI.config.pestTimer + + var lastSpawnTime = SimpleTimeMark.farPast() + + @SubscribeEvent + fun onPestSpawn(event: PestSpawnEvent) { + lastSpawnTime = SimpleTimeMark.now() + } + + @SubscribeEvent + fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) { + if (!isEnabled()) return + if (config.onlyWithVacuum && !PestAPI.hasVacuumInHand()) return + + val display = if (lastSpawnTime.isFarPast()) { + "§cNo pest spawned since joining." + } else { + val timeSinceLastPest = lastSpawnTime.passedSince().format() + "§eLast pest spawned §b$timeSinceLastPest ago" + } + + config.position.renderString(display, posLabel = "Pest Spawn Timer") + } + + fun isEnabled() = GardenAPI.inGarden() && config.enabled +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestType.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestType.kt new file mode 100644 index 000000000..946a37c4a --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestType.kt @@ -0,0 +1,16 @@ +package at.hannibal2.skyhanni.features.garden.pests + +import at.hannibal2.skyhanni.features.combat.damageindicator.BossType + +enum class PestType(val displayName: String, val damageIndicatorBoss: BossType, val spray: SprayType) { + BEETLE("Beetle", BossType.GARDEN_PEST_BEETLE, SprayType.DUNG), + CRICKET("Cricket", BossType.GARDEN_PEST_CRICKET, SprayType.HONEY_JAR), + EARTHWORM("Earthworm", BossType.GARDEN_PEST_EARTHWORM, SprayType.COMPOST), + FLY("Fly", BossType.GARDEN_PEST_FLY, SprayType.DUNG), + LOCUST("Locust", BossType.GARDEN_PEST_LOCUST, SprayType.PLANT_MATTER), + MITE("Mite", BossType.GARDEN_PEST_MITE, SprayType.TASTY_CHEESE), + MOSQUITO("Mosquito", BossType.GARDEN_PEST_MOSQUITO, SprayType.COMPOST), + MOTH("Moth", BossType.GARDEN_PEST_MOTH, SprayType.HONEY_JAR), + RAT("Rat", BossType.GARDEN_PEST_RAT, SprayType.TASTY_CHEESE), + SLUG("Slug", BossType.GARDEN_PEST_SLUG, SprayType.PLANT_MATTER), +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/pests/SprayFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/SprayFeatures.kt new file mode 100644 index 000000000..04501d1f4 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/SprayFeatures.kt @@ -0,0 +1,76 @@ +package at.hannibal2.skyhanni.features.garden.pests + +import at.hannibal2.skyhanni.events.GuiRenderEvent +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent +import at.hannibal2.skyhanni.features.garden.GardenPlotAPI +import at.hannibal2.skyhanni.features.garden.GardenPlotAPI.renderPlot +import at.hannibal2.skyhanni.features.garden.pests.PestAPI.getPests +import at.hannibal2.skyhanni.test.command.ErrorManager +import at.hannibal2.skyhanni.utils.InventoryUtils +import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName +import at.hannibal2.skyhanni.utils.LorenzColor +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName +import at.hannibal2.skyhanni.utils.RenderUtils.renderString +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.time.Duration.Companion.seconds + +class SprayFeatures { + private val config get() = PestAPI.config.spray + + private var display: String? = null + private var lastChangeTime = SimpleTimeMark.farPast() + + // TODO repo + private val pattern = "§a§lSPRAYONATOR! §r§7Your selected material is now §r§a(?<spray>.*)§r§7!".toPattern() + + @SubscribeEvent + fun onChat(event: LorenzChatEvent) { + if (!config.pestWhenSelector) return + + val type = pattern.matchMatcher(event.message) { + val sprayName = group("spray") + SprayType.getByName(sprayName) ?: run { + ErrorManager.logErrorStateWithData( + "Error reading spray material", "SprayType is null", + "sprayName" to sprayName, + "event.message" to event.message, + ) + return + } + } ?: return + + val pests = type.getPests().joinToString("§7, §6") { it.displayName } + display = "§a${type.displayName} §7(§6$pests§7)" + + lastChangeTime = SimpleTimeMark.now() + + } + + @SubscribeEvent + fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) { + if (!isEnabled()) return + + val display = display ?: return + + if (lastChangeTime.passedSince() > 5.seconds) { + this.display = null + return + } + + config.position.renderString(display, posLabel = "Pest Spray Selector") + } + + @SubscribeEvent + fun onWorldRender(event: LorenzRenderWorldEvent) { + if (!config.drawPlotsBorderWhenInHands) return + if (!InventoryUtils.itemInHandId.equals("SPRAYONATOR")) return + val plot = GardenPlotAPI.getCurrentPlot() ?: return + event.renderPlot(plot, LorenzColor.YELLOW.toColor(), LorenzColor.DARK_BLUE.toColor()) + } + + fun isEnabled() = LorenzUtils.inSkyBlock && config.pestWhenSelector +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/pests/SprayType.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/SprayType.kt new file mode 100644 index 000000000..eec073cf3 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/SprayType.kt @@ -0,0 +1,14 @@ +package at.hannibal2.skyhanni.features.garden.pests + +enum class SprayType(val displayName: String) { + COMPOST("Compost"), + PLANT_MATTER("Plant Matter"), + DUNG("Dung"), + HONEY_JAR("Honey Jar"), + TASTY_CHEESE("Tasty Cheese"), + ; + + companion object { + fun getByName(name: String) = entries.firstOrNull {it.displayName == name} + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorColorNames.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorColorNames.kt index 9fa465a47..c35b2d78a 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorColorNames.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorColorNames.kt @@ -1,9 +1,9 @@ package at.hannibal2.skyhanni.features.garden.visitor -import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.data.jsonobjects.repo.GardenJson import at.hannibal2.skyhanni.events.RepositoryReloadEvent +import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.utils.StringUtils.removeColor -import at.hannibal2.skyhanni.utils.jsonobjects.GardenJson import net.minecraftforge.fml.common.eventhandler.SubscribeEvent object GardenVisitorColorNames { @@ -23,7 +23,7 @@ object GardenVisitorColorNames { } fun getColoredName(name: String): String { - if (!SkyHanniMod.feature.garden.visitors.coloredName) return name + if (!GardenAPI.config.visitors.coloredName) return name val cleanName = name.removeColor() val color = visitorColours[cleanName] ?: return name diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorDropStatistics.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorDropStatistics.kt index 6ddabd2f5..59db979be 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorDropStatistics.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorDropStatistics.kt @@ -1,8 +1,8 @@ package at.hannibal2.skyhanni.features.garden.visitor -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.config.Storage +import at.hannibal2.skyhanni.config.features.garden.visitor.DropsStatisticsConfig.DropsStatisticsTextEntry import at.hannibal2.skyhanni.data.ProfileStorageData import at.hannibal2.skyhanni.events.ConfigLoadEvent import at.hannibal2.skyhanni.events.GuiRenderEvent @@ -11,6 +11,7 @@ import at.hannibal2.skyhanni.events.PreProfileSwitchEvent import at.hannibal2.skyhanni.events.garden.visitor.VisitorAcceptEvent import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.test.command.ErrorManager +import at.hannibal2.skyhanni.utils.ConfigUtils import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList import at.hannibal2.skyhanni.utils.LorenzUtils.addOrPut @@ -24,7 +25,7 @@ import at.hannibal2.skyhanni.utils.StringUtils.removeColor import net.minecraftforge.fml.common.eventhandler.SubscribeEvent object GardenVisitorDropStatistics { - private val config get() = SkyHanniMod.feature.garden.visitors.dropsStatistics + private val config get() = GardenAPI.config.visitors.dropsStatistics private var display = emptyList<List<Any>>() private var acceptedVisitors = 0 @@ -46,7 +47,8 @@ object GardenVisitorDropStatistics { private fun formatDisplay(map: List<List<Any>>): List<List<Any>> { val newList = mutableListOf<List<Any>>() for (index in config.textFormat) { - newList.add(map[index]) + // We need to use the ordinal here, can't change this. + newList.add(map[index.ordinal]) } return newList } @@ -119,17 +121,18 @@ object GardenVisitorDropStatistics { val currentRarity = LorenzUtils.enumValueOf<VisitorRarity>(rarity) val visitorRarities = GardenAPI.storage?.visitorDrops?.visitorRarities ?: return fixRaritiesSize(visitorRarities) + // TODO, change functionality to use enum rather than ordinals val temp = visitorRarities[currentRarity.ordinal] + 1 visitorRarities[currentRarity.ordinal] = temp saveAndUpdate() } + /** + * Do not change the order of the elements getting added to the list. See DropsStatisticsTextEntry for the order. + */ private fun drawDisplay(storage: Storage.ProfileSpecific.GardenStorage.VisitorDrops) = buildList<List<Any>> { - //0 addAsSingletonList("§e§lVisitor Statistics") - //1 addAsSingletonList(format(totalVisitors, "Total", "§e", "")) - //2 val visitorRarities = storage.visitorRarities fixRaritiesSize(visitorRarities) if (visitorRarities.isNotEmpty()) { @@ -147,20 +150,19 @@ object GardenVisitorDropStatistics { "Error rendering visitor drop statistics" ) } - //3 addAsSingletonList(format(acceptedVisitors, "Accepted", "§2", "")) - //4 addAsSingletonList(format(deniedVisitors, "Denied", "§c", "")) - //5 addAsSingletonList("") - //6 addAsSingletonList(format(storage.copper, "Copper", "§c", "")) - //7 addAsSingletonList(format(storage.farmingExp, "Farming EXP", "§3", "§7")) - //8 addAsSingletonList(format(coinsSpent, "Coins Spent", "§6", "")) - //9 – 16 + addAsSingletonList("") + addAsSingletonList(format(storage.gardenExp, "Garden EXP", "§2", "§7")) + addAsSingletonList(format(storage.bits, "Bits", "§b", "§b")) + addAsSingletonList(format(storage.mithrilPowder, "Mithril Powder", "§2", "§2")) + addAsSingletonList(format(storage.gemstonePowder, "Gemstone Powder", "§d", "§d")) + for (reward in VisitorReward.entries) { val count = rewardsCount[reward] ?: 0 if (config.displayIcons) {// Icons @@ -172,16 +174,6 @@ object GardenVisitorDropStatistics { addAsSingletonList(format(count, reward.displayName, "§b")) } } - //17 - addAsSingletonList("") - //18 - addAsSingletonList(format(storage.gardenExp, "Garden EXP", "§2", "§7")) - //19 - addAsSingletonList(format(storage.bits, "Bits", "§b", "§b")) - //20 - addAsSingletonList(format(storage.mithrilPowder, "Mithril Powder", "§2", "§2")) - //21 - addAsSingletonList(format(storage.gemstonePowder, "Gemstone Powder", "§d", "§d")) } // Adding the mythic rarity between legendary and special, if missing @@ -254,6 +246,10 @@ object GardenVisitorDropStatistics { event.move(3, "${originalPrefix}displayIcons", "${newPrefix}displayIcons") event.move(3, "${originalPrefix}onlyOnBarn", "${newPrefix}onlyOnBarn") event.move(3, "${originalPrefix}visitorDropPos", "${newPrefix}pos") + + event.move(11, "${newPrefix}textFormat", "${newPrefix}textFormat") { element -> + ConfigUtils.migrateIntArrayListToEnumArrayList(element, DropsStatisticsTextEntry::class.java) + } } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorFeatures.kt index 4995decc8..22a53c388 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorFeatures.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorFeatures.kt @@ -20,6 +20,7 @@ import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed.getSpeed import at.hannibal2.skyhanni.mixins.hooks.RenderLivingEntityHelper import at.hannibal2.skyhanni.test.command.ErrorManager +import at.hannibal2.skyhanni.utils.ConfigUtils import at.hannibal2.skyhanni.utils.EntityUtils import at.hannibal2.skyhanni.utils.InventoryUtils import at.hannibal2.skyhanni.utils.ItemBlink @@ -46,7 +47,8 @@ import at.hannibal2.skyhanni.utils.StringUtils.removeColor import at.hannibal2.skyhanni.utils.TimeUtils import at.hannibal2.skyhanni.utils.getLorenzVec import at.hannibal2.skyhanni.utils.renderables.Renderable -import io.github.moulberry.notenoughupdates.util.MinecraftExecutor +import com.google.gson.JsonArray +import com.google.gson.JsonPrimitive import net.minecraft.client.Minecraft import net.minecraft.client.gui.inventory.GuiEditSign import net.minecraft.entity.EntityLivingBase @@ -232,9 +234,7 @@ class GardenVisitorFeatures { @SubscribeEvent fun onOwnInventoryItemUpdate(event: OwnInventoryItemUpdateEvent) { if (GardenAPI.onBarnPlot) { - MinecraftExecutor.OnThread.execute { - update() - } + update() } } @@ -258,12 +258,12 @@ class GardenVisitorFeatures { val visitor = event.visitor val text = visitor.status.displayName val location = event.location - event.parent.drawString(location.add(0.0, 2.23, 0.0), text) + event.parent.drawString(location.add(y = 2.23), text) if (config.rewardWarning.showOverName) { visitor.hasReward()?.let { reward -> val name = reward.displayName - event.parent.drawString(location.add(0.0, 2.73, 0.0), "§c!$name§c!") + event.parent.drawString(location.add(y = 2.73), "§c!$name§c!") } } } @@ -436,6 +436,7 @@ class GardenVisitorFeatures { private fun hideVisitorMessage(message: String) = visitorChatMessagePattern.matchMatcher(message) { val name = group("name") + if (name == "Jacob") return false if (name == "Spaceman") return false if (name == "Beth") return false @@ -606,6 +607,23 @@ class GardenVisitorFeatures { event.move(3, "garden.visitorColoredName", "garden.visitors.coloredName") event.move(3, "garden.visitorHypixelArrivedMessage", "garden.visitors.hypixelArrivedMessage") event.move(3, "garden.visitorHideChat", "garden.visitors.hideChat") + event.move(11, "garden.visitors.rewardWarning.drops", "garden.visitors.rewardWarning.drops") { element -> + ConfigUtils.migrateIntArrayListToEnumArrayList(element, VisitorReward::class.java) + } + event.move(12, "garden.visitors.rewardWarning.drops", "garden.visitors.rewardWarning.drops") { element -> + val drops = JsonArray() + for (jsonElement in element.asJsonArray) { + val old = jsonElement.asString + val new = VisitorReward.entries.firstOrNull { old.startsWith(it.name) } + if (new == null) { + println("error with migrating old VisitorReward entity: '$old'") + continue + } + drops.add(JsonPrimitive(new.name)) + } + + drops + } } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorTimer.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorTimer.kt index 1bd9290e2..f7bed5ef6 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorTimer.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorTimer.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.features.garden.visitor -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.events.CropClickEvent import at.hannibal2.skyhanni.events.GuiRenderEvent @@ -23,14 +22,15 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import kotlin.concurrent.fixedRateTimer import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.seconds import kotlin.time.DurationUnit import kotlin.time.toDuration class GardenVisitorTimer { - private val config get() = SkyHanniMod.feature.garden.visitors.timer + private val config get() = GardenAPI.config.visitors.timer private val pattern = "§b§lVisitors: §r§f\\((?<time>.*)\\)".toPattern() - private var render = "" + private var display = "" private var lastMillis = 0.seconds private var sixthVisitorArrivalTime = SimpleTimeMark.farPast() private var visitorJustArrived = false @@ -73,7 +73,7 @@ class GardenVisitorTimer { @SubscribeEvent fun onPreProfileSwitch(event: PreProfileSwitchEvent) { - render = "" + display = "" lastMillis = 0.seconds sixthVisitorArrivalTime = SimpleTimeMark.farPast() visitorJustArrived = false @@ -93,7 +93,7 @@ class GardenVisitorTimer { continue } if (line == "§b§lVisitors: §r§f(§r§cNot Unlocked!§r§f)") { - render = "" + display = "" return } @@ -173,14 +173,14 @@ class GardenVisitorTimer { "Next in §$formatColor$formatDuration$extraSpeed" } val visitorLabel = if (visitorsAmount == 1) "visitor" else "visitors" - render = "§b$visitorsAmount $visitorLabel §7($next§7)" + display = "§b$visitorsAmount $visitorLabel §7($next§7)" } @SubscribeEvent fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) { if (!isEnabled()) return - config.pos.renderString(render, posLabel = "Garden Visitor Timer") + config.pos.renderString(display, posLabel = "Garden Visitor Timer") } @SubscribeEvent @@ -200,7 +200,11 @@ class GardenVisitorTimer { fun onBlockBreak(event: CropClickEvent) { if (!isEnabled()) return sixthVisitorArrivalTime -= 100.milliseconds - lastTimerUpdate -= 100.milliseconds + + // We only need manually retracting the time when hypixel shows 6 minutes or above + if (lastMillis > 5.minutes) { + lastTimerUpdate -= 100.milliseconds + } } private fun updateSixthVisitorArrivalTime() { diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/HighlightVisitorsOutsideOfGarden.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/HighlightVisitorsOutsideOfGarden.kt index a4d370e62..bd0fe5704 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/HighlightVisitorsOutsideOfGarden.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/HighlightVisitorsOutsideOfGarden.kt @@ -1,11 +1,12 @@ package at.hannibal2.skyhanni.features.garden.visitor -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.features.garden.visitor.VisitorConfig.VisitorBlockBehaviour +import at.hannibal2.skyhanni.data.jsonobjects.repo.GardenJson import at.hannibal2.skyhanni.events.LorenzTickEvent import at.hannibal2.skyhanni.events.PacketEvent import at.hannibal2.skyhanni.events.RepositoryReloadEvent import at.hannibal2.skyhanni.events.withAlpha +import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.mixins.hooks.RenderLivingEntityHelper import at.hannibal2.skyhanni.utils.EntityUtils import at.hannibal2.skyhanni.utils.EntityUtils.getSkinTexture @@ -13,7 +14,6 @@ import at.hannibal2.skyhanni.utils.LorenzColor import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzVec import at.hannibal2.skyhanni.utils.getLorenzVec -import at.hannibal2.skyhanni.utils.jsonobjects.GardenJson import at.hannibal2.skyhanni.utils.toLorenzVec import io.github.moulberry.notenoughupdates.util.SBInfo import net.minecraft.client.Minecraft @@ -27,7 +27,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class HighlightVisitorsOutsideOfGarden { private var visitorJson = mapOf<String?, List<GardenJson.GardenVisitor>>() - private val config get() = SkyHanniMod.feature.garden.visitors + private val config get() = GardenAPI.config.visitors @SubscribeEvent fun onRepoReload(event: RepositoryReloadEvent) { diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorAPI.kt index f71ab6883..a74793fbe 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorAPI.kt @@ -1,11 +1,11 @@ package at.hannibal2.skyhanni.features.garden.visitor -import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.events.garden.visitor.VisitorAcceptedEvent import at.hannibal2.skyhanni.events.garden.visitor.VisitorArrivalEvent import at.hannibal2.skyhanni.events.garden.visitor.VisitorLeftEvent import at.hannibal2.skyhanni.events.garden.visitor.VisitorRefusedEvent import at.hannibal2.skyhanni.events.withAlpha +import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.EntityUtils import at.hannibal2.skyhanni.utils.LorenzColor @@ -18,7 +18,7 @@ import net.minecraft.item.ItemStack object VisitorAPI { private var visitors = mapOf<String, Visitor>() var inInventory = false - val config get() = SkyHanniMod.feature.garden.visitors + val config get() = GardenAPI.config.visitors private val logger = LorenzLogger("garden/visitors/api") fun getVisitorsMap() = visitors @@ -121,8 +121,7 @@ object VisitorAPI { fun hasReward(): VisitorReward? { for (internalName in allRewards) { val reward = VisitorReward.getByInternalName(internalName) ?: continue - - if (config.rewardWarning.drops.contains(reward.ordinal)) { + if (reward in config.rewardWarning.drops) { return reward } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorReward.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorReward.kt index d6aabd3b5..3f5f5eb17 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorReward.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorReward.kt @@ -1,26 +1,36 @@ package at.hannibal2.skyhanni.features.garden.visitor -import at.hannibal2.skyhanni.utils.ItemUtils.nameWithEnchantment +import at.hannibal2.skyhanni.config.HasLegacyId import at.hannibal2.skyhanni.utils.NEUInternalName import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName import at.hannibal2.skyhanni.utils.NEUItems.getItemStack -enum class VisitorReward(private val rawInternalName: String) { - FLOWERING_BOUQUET("FLOWERING_BOUQUET"), - OVERGROWN_GRASS("OVERGROWN_GRASS"), - GREEN_BANDANA("GREEN_BANDANA"), - DEDICATION("DEDICATION;4"), - MUSIC_RUNE("MUSIC_RUNE;1"), - SPACE_HELMET("DCTR_SPACE_HELM"), - CULTIVATING("CULTIVATING;1"), - REPLENISH("REPLENISH;1"), +enum class VisitorReward(private val rawInternalName: String, val displayName: String, private val legacyId: Int = -1) : HasLegacyId { + FLOWERING_BOUQUET("FLOWERING_BOUQUET", "§9Flowering Bouquet", legacyId = 0), + OVERGROWN_GRASS("OVERGROWN_GRASS", "§9Overgrown Grass", legacyId = 1), + GREEN_BANDANA("GREEN_BANDANA", "§9Green Bandana", legacyId = 2), + DEDICATION("DEDICATION;4", "§9Dedication IV", legacyId = 3), + MUSIC_RUNE("MUSIC_RUNE;1", "§9Music Rune", legacyId = 4), + SPACE_HELMET("DCTR_SPACE_HELM", "§cSpace Helmet", legacyId = 5), + CULTIVATING("CULTIVATING;1", "§9Cultivating I", legacyId = 6), + REPLENISH("REPLENISH;1", "§9Replenish I", legacyId = 7), + DELICATE("DELICATE;5", "§9Delicate V"), ; private val internalName by lazy { rawInternalName.asInternalName() } val itemStack by lazy { internalName.getItemStack() } - val displayName by lazy { itemStack.nameWithEnchantment ?: internalName.asString() } + // TODO use this instead of hard coded item names once moulconfig no longer calls toString before the neu repo gets loaded +// val displayName by lazy { itemStack.nameWithEnchantment ?: internalName.asString() } companion object { fun getByInternalName(internalName: NEUInternalName) = entries.firstOrNull { it.internalName == internalName } } + + override fun getLegacyId(): Int { + return legacyId + } + + override fun toString(): String { + return displayName + } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/ChestValue.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/ChestValue.kt index 42b22741b..f8817b43b 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/ChestValue.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/ChestValue.kt @@ -45,7 +45,7 @@ class ChestValue { if (InventoryUtils.openInventoryName() == "") return if (!config.showDuringEstimatedItemValue) { - if (EstimatedItemValue.currentlyShowing) return + if (EstimatedItemValue.isCurrentlyShowing()) return } if (inInventory) { @@ -126,11 +126,11 @@ class ChestValue { val textAmount = " §7x$amount:" val width = Minecraft.getMinecraft().fontRendererObj.getStringWidth(textAmount) val name = "${stack.displayName.reduceStringLength((config.nameLength - width), ' ')} $textAmount" - val price = "§b${(total).formatPrice()}" + val price = "§6${(total).formatPrice()}" val text = if (config.alignedDisplay) "$name $price" else - "${stack.displayName} §7x$amount: §b${total.formatPrice()}" + "${stack.displayName} §7x$amount: §6${total.formatPrice()}" newDisplay.add(buildList { val renderable = Renderable.hoverTips( text, @@ -144,7 +144,7 @@ class ChestValue { }) rendered++ } - newDisplay.addAsSingletonList("§6Total value : §b${totalPrice.formatPrice()}") + newDisplay.addAsSingletonList("§aTotal value: §6${totalPrice.formatPrice()} coins") } private fun sortedList() = when (config.sortingType) { @@ -197,7 +197,7 @@ class ChestValue { val key = "$internalName+$total" if (stack.item == Items.enchanted_book) total /= 2 - list.add("§aTotal: §6§l${total.formatPrice()}") + list.add("§aTotal: §6§l${total.formatPrice()} coins") if (total == 0.0) continue val item = chestItems.getOrPut(key) { Item(mutableListOf(), 0, stack, 0.0, list) 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 a8880aefd..d0c6d91f8 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/HideNotClickableItems.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/HideNotClickableItems.kt @@ -27,9 +27,9 @@ import at.hannibal2.skyhanni.utils.MultiFilter import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.isRiftExportable import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.isRiftTransferable import at.hannibal2.skyhanni.utils.StringUtils.removeColor -import at.hannibal2.skyhanni.utils.jsonobjects.HideNotClickableItemsJson -import at.hannibal2.skyhanni.utils.jsonobjects.HideNotClickableItemsJson.SalvageFilter -import at.hannibal2.skyhanni.utils.jsonobjects.MultiFilterJson +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 net.minecraft.client.Minecraft import net.minecraft.client.gui.inventory.GuiChest import net.minecraft.inventory.ContainerChest diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemDisplayOverlayFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemDisplayOverlayFeatures.kt index aa3a46ed2..db4443677 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemDisplayOverlayFeatures.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemDisplayOverlayFeatures.kt @@ -2,24 +2,60 @@ package at.hannibal2.skyhanni.features.inventory import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.api.CollectionAPI +import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator +import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry +import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.BINGO_GOAL_RANK +import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.BOTTLE_OF_JYRRE +import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.COLLECTION_LEVEL +import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.DUNGEON_HEAD_FLOOR_NUMBER +import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.DUNGEON_POTION_LEVEL +import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.EDITION_NUMBER +import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.KUUDRA_KEY +import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.LARVA_HOOK +import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.MASTER_SKULL_TIER +import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.MASTER_STAR_TIER +import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.MINION_TIER +import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.NEW_YEAR_CAKE +import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.PET_LEVEL +import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.RANCHERS_BOOTS_SPEED +import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.SKILL_LEVEL +import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.VACUUM_GARDEN import at.hannibal2.skyhanni.events.RenderItemTipEvent +import at.hannibal2.skyhanni.features.garden.pests.PestAPI +import at.hannibal2.skyhanni.utils.ConfigUtils import at.hannibal2.skyhanni.utils.InventoryUtils import at.hannibal2.skyhanni.utils.ItemUtils import at.hannibal2.skyhanni.utils.ItemUtils.cleanName +import at.hannibal2.skyhanni.utils.ItemUtils.getInternalNameOrNull import at.hannibal2.skyhanni.utils.ItemUtils.getLore import at.hannibal2.skyhanni.utils.ItemUtils.name import at.hannibal2.skyhanni.utils.LorenzUtils.between +import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName +import at.hannibal2.skyhanni.utils.NumberUtil +import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimal -import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded +import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getBottleOfJyrreSeconds +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getEdition import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher -import at.hannibal2.skyhanni.utils.StringUtils.matchRegex import at.hannibal2.skyhanni.utils.StringUtils.removeColor import net.minecraft.item.ItemStack import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -class ItemDisplayOverlayFeatures { +object ItemDisplayOverlayFeatures { + // TODO USE SH-REPO + private val config get() = SkyHanniMod.feature.inventory + + // TODO repo private val rancherBootsSpeedCapPattern = "§7Current Speed Cap: §a(?<cap>.*)".toPattern() private val petLevelPattern = "\\[Lvl (?<level>.*)] .*".toPattern() + private val masterSkullPattern = "(.*)Master Skull - Tier .".toPattern() + private val gardenVacuumPatterm = "§7Vacuum Bag: §6(?<amount>\\d*) Pests?".toPattern() + private val harvestPattern = "§7§7You may harvest §6(?<amount>.).*".toPattern() + private val dungeonPotionPattern = "Dungeon (?<level>.*) Potion".toPattern() + private val bingoGoalRankPattern = "(§.)*You were the (§.)*(?<rank>[\\w]+)(?<ordinal>(st|nd|rd|th)) (§.)*to".toPattern() + + private val bottleOfJyrre = "NEW_BOTTLE_OF_JYRRE".asInternalName() @SubscribeEvent fun onRenderItemTip(event: RenderItemTipEvent) { @@ -28,8 +64,9 @@ class ItemDisplayOverlayFeatures { private fun getStackTip(item: ItemStack): String { val itemName = item.cleanName() + val chestName = InventoryUtils.openInventoryName() - if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(0)) { + if (MASTER_STAR_TIER.isSelected()) { when (itemName) { "First Master Star" -> return "1" "Second Master Star" -> return "2" @@ -39,11 +76,13 @@ class ItemDisplayOverlayFeatures { } } - if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(1) && itemName.matchRegex("(.*)Master Skull - Tier .")) { - return itemName.substring(itemName.length - 1) + if (MASTER_SKULL_TIER.isSelected()) { + masterSkullPattern.matchMatcher(itemName) { + return itemName.substring(itemName.length - 1) + } } - if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(2) && (itemName.contains("Golden ") || itemName.contains("Diamond "))) { + if (DUNGEON_HEAD_FLOOR_NUMBER.isSelected() && (itemName.contains("Golden ") || itemName.contains("Diamond "))) { when { itemName.contains("Bonzo") -> return "1" itemName.contains("Scarf") -> return "2" @@ -55,11 +94,11 @@ class ItemDisplayOverlayFeatures { } } - if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(3) && itemName.startsWith("New Year Cake (")) { + if (NEW_YEAR_CAKE.isSelected() && itemName.startsWith("New Year Cake (")) { return "§b" + itemName.between("(Year ", ")") } - if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(4)) { + if (PET_LEVEL.isSelected()) { val chestName = InventoryUtils.openInventoryName() if (!chestName.endsWith("Sea Creature Guide") && ItemUtils.isPet(itemName)) { petLevelPattern.matchMatcher(itemName) { @@ -73,7 +112,7 @@ class ItemDisplayOverlayFeatures { } } - if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(5) && itemName.contains(" Minion ") && + if (MINION_TIER.isSelected() && itemName.contains(" Minion ") && !itemName.contains("Recipe") && item.getLore().any { it.contains("Place this minion") } ) { val array = itemName.split(" ") @@ -81,12 +120,12 @@ class ItemDisplayOverlayFeatures { return last.romanToDecimal().toString() } - if (SkyHanniMod.feature.inventory.displaySackName && ItemUtils.isSack(item)) { + if (config.displaySackName && ItemUtils.isSack(item)) { val sackName = grabSackName(itemName) return (if (itemName.contains("Enchanted")) "§5" else "") + sackName.substring(0, 2) } - if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(8) && itemName.contains("Kuudra Key")) { + if (KUUDRA_KEY.isSelected() && itemName.contains("Kuudra Key")) { return when (itemName) { "Kuudra Key" -> "§a1" "Hot Kuudra Key" -> "§22" @@ -97,32 +136,33 @@ class ItemDisplayOverlayFeatures { } } - if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(9) && + if (SKILL_LEVEL.isSelected() && InventoryUtils.openInventoryName() == "Your Skills" && - item.getLore().any { it.contains("Click to view!") }) { + item.getLore().any { it.contains("Click to view!") } + ) { if (CollectionAPI.isCollectionTier0(item.getLore())) return "0" val split = itemName.split(" ") if (!itemName.contains("Dungeon")) { val text = split.last() if (split.size < 2) return "0" - return "" + text.romanToDecimalIfNeeded() + return "" + text.romanToDecimalIfNecessary() } } - if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(10) && InventoryUtils.openInventoryName().endsWith(" Collections")) { + if (COLLECTION_LEVEL.isSelected() && InventoryUtils.openInventoryName().endsWith(" Collections")) { val lore = item.getLore() if (lore.any { it.contains("Click to view!") }) { if (CollectionAPI.isCollectionTier0(lore)) return "0" item.name?.let { if (it.startsWith("§e")) { val text = it.split(" ").last() - return "" + text.romanToDecimalIfNeeded() + return "" + text.romanToDecimalIfNecessary() } } } } - if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(11) && itemName.contains("Rancher's Boots")) { + if (RANCHERS_BOOTS_SPEED.isSelected() && itemName.contains("Rancher's Boots")) { for (line in item.getLore()) { rancherBootsSpeedCapPattern.matchMatcher(line) { return group("cap") @@ -130,9 +170,9 @@ class ItemDisplayOverlayFeatures { } } - if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(12) && itemName.contains("Larva Hook")) { + if (LARVA_HOOK.isSelected() && itemName.contains("Larva Hook")) { for (line in item.getLore()) { - "§7§7You may harvest §6(?<amount>.).*".toPattern().matchMatcher(line) { + harvestPattern.matchMatcher(line) { val amount = group("amount").toInt() return when { amount > 4 -> "§a$amount" @@ -143,9 +183,9 @@ class ItemDisplayOverlayFeatures { } } - if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(13) && itemName.startsWith("Dungeon ") && itemName.contains(" Potion")) { + if (DUNGEON_POTION_LEVEL.isSelected() && itemName.startsWith("Dungeon ") && itemName.contains(" Potion")) { item.name?.let { - "Dungeon (?<level>.*) Potion".toPattern().matchMatcher(it.removeColor()) { + dungeonPotionPattern.matchMatcher(it.removeColor()) { return when (val level = group("level").romanToDecimal()) { in 1..2 -> "§f$level" in 3..4 -> "§a$level" @@ -156,6 +196,46 @@ class ItemDisplayOverlayFeatures { } } + if (VACUUM_GARDEN.isSelected() && item.getInternalNameOrNull() in PestAPI.vacuumVariants) { + for (line in item.getLore()) { + gardenVacuumPatterm.matchMatcher(line) { + val pests = group("amount").formatNumber() + return if (config.vacuumBagCap) { + if (pests > 39) "§640" else "$pests" + } else { + when { + pests < 40 -> "$pests" + pests < 1_000 -> "§6$pests" + pests < 100_000 -> "§c${pests / 1000}k" + else -> "§c${pests / 100_000 / 10.0}m" + } + } + } + } + } + + if (BOTTLE_OF_JYRRE.isSelected() && item.getInternalNameOrNull() == bottleOfJyrre) { + val seconds = item.getBottleOfJyrreSeconds() ?: 0 + return "§a${(seconds / 3600)}" + } + + if (EDITION_NUMBER.isSelected()) { + item.getEdition()?.let { edition -> + if (edition < 1_000) { + return "§6$edition" + } + } + } + + if (BINGO_GOAL_RANK.isSelected() && chestName == "Bingo Card" && item.getLore().lastOrNull() == "§aGOAL REACHED") { + for (line in item.getLore()) { + bingoGoalRankPattern.matchMatcher(line) { + val rank = group("rank").formatNumber() + if (rank < 10000) return "§6${NumberUtil.format(rank)}" + } + } + } + return "" } @@ -169,4 +249,13 @@ class ItemDisplayOverlayFeatures { } return text } + + @SubscribeEvent + fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { + event.move(11, "inventory.itemNumberAsStackSize", "inventory.itemNumberAsStackSize") { element -> + ConfigUtils.migrateIntArrayListToEnumArrayList(element, ItemNumberEntry::class.java) + } + } + + fun ItemNumberEntry.isSelected() = config.itemNumberAsStackSize.contains(this) } diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemStars.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemStars.kt index f8dd111b2..bbd302009 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemStars.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemStars.kt @@ -1,36 +1,40 @@ package at.hannibal2.skyhanni.features.inventory import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.CRIMSON_ARMOR +import at.hannibal2.skyhanni.data.jsonobjects.repo.ItemsJson import at.hannibal2.skyhanni.events.RenderItemTipEvent import at.hannibal2.skyhanni.events.RepositoryReloadEvent +import at.hannibal2.skyhanni.features.inventory.ItemDisplayOverlayFeatures.isSelected import at.hannibal2.skyhanni.utils.ItemUtils.name import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.jsonobjects.ItemsJson +import at.hannibal2.skyhanni.utils.StringUtils.matches import net.minecraftforge.event.entity.player.ItemTooltipEvent import net.minecraftforge.fml.common.eventhandler.EventPriority import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class ItemStars { + private val config get() = SkyHanniMod.feature.inventory + private val armorNames = mutableListOf<String>() private val tiers = mutableMapOf<String, Int>() - private val STAR_FIND_PATCHER = "(.*)§.✪(.*)".toPattern() + private val starFindPattern = "(.*)§.✪(.*)".toPattern() private val armorParts = listOf("Helmet", "Chestplate", "Leggings", "Boots") @SubscribeEvent(priority = EventPriority.LOW) fun onTooltip(event: ItemTooltipEvent) { - if (!LorenzUtils.inSkyBlock) return - + if (!isEnabled()) return val stack = event.itemStack ?: return if (stack.stackSize != 1) return - if (!SkyHanniMod.feature.inventory.itemStars) return + val itemName = stack.name ?: return val stars = getStars(itemName) if (stars > 0) { var name = itemName - while (STAR_FIND_PATCHER.matcher(name).matches()) { + while (starFindPattern.matches(name)) { name = name.replaceFirst("§.✪".toRegex(), "") } name = name.trim() @@ -51,7 +55,7 @@ class ItemStars { @SubscribeEvent fun onRenderItemTip(event: RenderItemTipEvent) { - if (!SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(6)) return + if (!CRIMSON_ARMOR.isSelected()) return val stack = event.stack val number = getCrimsonStars(stack.name ?: return) if (number != -1) { @@ -120,4 +124,6 @@ class ItemStars { return -1 } + + private fun isEnabled() = LorenzUtils.inSkyBlock && config.itemStars } diff --git a/src/main/java/at/hannibal2/skyhanni/features/mining/KingTalismanHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/mining/KingTalismanHelper.kt index 501ae420e..93e12cc6f 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/mining/KingTalismanHelper.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/mining/KingTalismanHelper.kt @@ -83,7 +83,7 @@ class KingTalismanHelper { private fun checkOffset() { val king = EntityUtils.getEntitiesNearby<EntityArmorStand>(LorenzVec(129.6, 196.0, 196.7), 2.0) - .filter { it.name.startsWith("§6§lKing ") }.first() + .filter { it.name.startsWith("§6§lKing ") }.firstOrNull() ?: return val foundKing = "§6§lKing (?<name>.*)".toPattern().matchMatcher(king.name) { group("name") } ?: return diff --git a/src/main/java/at/hannibal2/skyhanni/features/mining/powdertracker/PowderTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/mining/powdertracker/PowderTracker.kt index fd4ad8962..63ae5763e 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/mining/powdertracker/PowderTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/mining/powdertracker/PowderTracker.kt @@ -2,12 +2,14 @@ package at.hannibal2.skyhanni.features.mining.powdertracker import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator +import at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry import at.hannibal2.skyhanni.data.IslandType import at.hannibal2.skyhanni.events.ConfigLoadEvent import at.hannibal2.skyhanni.events.GuiRenderEvent import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.LorenzTickEvent import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent +import at.hannibal2.skyhanni.utils.ConfigUtils import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList import at.hannibal2.skyhanni.utils.LorenzUtils.afterChange import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland @@ -176,12 +178,16 @@ object PowderTracker { event.move(8, "#profile.powderTracker", "#profile.powderTracker") { old -> old.asJsonObject.get("0") } + event.move(11, "mining.powderTracker.textFormat", "mining.powderTracker.textFormat") { element -> + ConfigUtils.migrateIntArrayListToEnumArrayList(element, PowderDisplayEntry::class.java) + } } private fun formatDisplay(map: List<List<Any>>) = buildList { if (map.isEmpty()) return@buildList for (index in config.textFormat.get()) { - add(map[index]) + // TODO, change functionality to use enum rather than ordinals + add(map[index.ordinal]) } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt index 9eab0fdde..881c5c215 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt @@ -7,11 +7,14 @@ import at.hannibal2.skyhanni.data.IslandType import at.hannibal2.skyhanni.data.ProfileStorageData import at.hannibal2.skyhanni.events.InventoryCloseEvent import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent +import at.hannibal2.skyhanni.events.InventoryUpdatedEvent import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent import at.hannibal2.skyhanni.events.LorenzTickEvent import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent +import at.hannibal2.skyhanni.events.MinionCloseEvent import at.hannibal2.skyhanni.events.MinionOpenEvent +import at.hannibal2.skyhanni.events.MinionStorageOpenEvent import at.hannibal2.skyhanni.test.GriffinUtils.drawWaypointFilled import at.hannibal2.skyhanni.utils.BlockUtils.getBlockStateAt import at.hannibal2.skyhanni.utils.InventoryUtils @@ -25,12 +28,12 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy import at.hannibal2.skyhanni.utils.LorenzUtils.formatInteger import at.hannibal2.skyhanni.utils.LorenzVec import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimal -import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded +import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary import at.hannibal2.skyhanni.utils.RenderUtils.drawString import at.hannibal2.skyhanni.utils.RenderUtils.renderString import at.hannibal2.skyhanni.utils.SpecialColour import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher -import at.hannibal2.skyhanni.utils.StringUtils.matchRegex +import at.hannibal2.skyhanni.utils.StringUtils.matches import at.hannibal2.skyhanni.utils.TimeUtils import at.hannibal2.skyhanni.utils.getLorenzVec import at.hannibal2.skyhanni.utils.toLorenzVec @@ -51,15 +54,14 @@ import java.awt.Color class MinionFeatures { private val config get() = SkyHanniMod.feature.minions private var lastClickedEntity: LorenzVec? = null - private var lastMinion: LorenzVec? = null private var newMinion: LorenzVec? = null private var newMinionName: String? = null private var lastMinionOpened = 0L - private var minionInventoryOpen = false private var lastInventoryClosed = 0L private var coinsPerDay = "" private val minionUpgradePattern = "§aYou have upgraded your Minion to Tier (?<tier>.*)".toPattern() + private val minionCoinPattern = "§aYou received §r§6(.*) coins§r§a!".toPattern() @SubscribeEvent fun onPlayerInteract(event: PlayerInteractEvent) { @@ -91,6 +93,10 @@ class MinionFeatures { val entity = minecraft.pointedEntity if (entity != null) { lastClickedEntity = entity.getLorenzVec() + return + } + minecraft.thePlayer.rayTrace(16.0, 1.0f)?.let { + lastStorage = it.blockPos.toLorenzVec() } } @@ -123,13 +129,24 @@ class MinionFeatures { fun onInventoryOpen(event: InventoryFullyOpenedEvent) { if (!LorenzUtils.inSkyBlock) return if (LorenzUtils.skyBlockIsland != IslandType.PRIVATE_ISLAND) return - if (!event.inventoryName.contains(" Minion ")) return + if (!event.inventoryName.contains("Minion ")) return event.inventoryItems[48]?.let { if ("§aCollect All" == it.name) { MinionOpenEvent(event.inventoryName, event.inventoryItems).postAndCatch() + return } } + + MinionStorageOpenEvent(lastStorage, event.inventoryItems).postAndCatch() + minionStorageInventoryOpen = true + } + + @SubscribeEvent + fun onInventoryUpdated(event: InventoryUpdatedEvent) { + if (minionInventoryOpen) { + MinionOpenEvent(event.inventoryName, event.inventoryItems).postAndCatch() + } } @SubscribeEvent @@ -159,6 +176,9 @@ class MinionFeatures { @SubscribeEvent fun onInventoryClose(event: InventoryCloseEvent) { + if (event.reopenSameName) return + + minionStorageInventoryOpen = false if (!minionInventoryOpen) return val minions = minions ?: return @@ -172,6 +192,7 @@ class MinionFeatures { if (location !in minions) { minions[location]!!.lastClicked = 0 } + MinionCloseEvent().postAndCatch() } @SubscribeEvent @@ -224,6 +245,7 @@ class MinionFeatures { lastMinion = null lastMinionOpened = 0L minionInventoryOpen = false + minionStorageInventoryOpen = false } @SubscribeEvent @@ -232,11 +254,10 @@ class MinionFeatures { if (LorenzUtils.skyBlockIsland != IslandType.PRIVATE_ISLAND) return val message = event.message - if (message.matchRegex("§aYou received §r§6(.*) coins§r§a!") && System.currentTimeMillis() - lastInventoryClosed < 2_000) { + if (minionCoinPattern.matches(message) && System.currentTimeMillis() - lastInventoryClosed < 2_000) { minions?.get(lastMinion)?.let { it.lastClicked = System.currentTimeMillis() } - } if (message.startsWith("§aYou picked up a minion!") && lastMinion != null) { minions = minions?.editCopy { remove(lastMinion) } @@ -256,7 +277,7 @@ class MinionFeatures { } minionUpgradePattern.matchMatcher(message) { - val newTier = group("tier").romanToDecimalIfNeeded() + val newTier = group("tier").romanToDecimalIfNecessary() minions?.get(lastMinion)?.let { val minionName = getMinionName(it.displayName, newTier) it.displayName = minionName @@ -272,7 +293,7 @@ class MinionFeatures { val playerLocation = LocationUtils.playerLocation() val minions = minions ?: return for (minion in minions) { - val location = minion.key.add(0.0, 1.0, 0.0) + val location = minion.key.add(y = 1.0) if (!location.canBeSeen()) continue val lastEmptied = minion.value.lastClicked @@ -283,14 +304,14 @@ class MinionFeatures { val name = "§6" + if (config.nameOnlyTier) { displayName.split(" ").last() } else displayName - event.drawString(location.add(0.0, 0.65, 0.0), name, true) + event.drawString(location.add(y = 0.65), name, true) } if (config.emptiedTime.display && lastEmptied != 0L) { val duration = System.currentTimeMillis() - lastEmptied val format = TimeUtils.formatDuration(duration, longName = true) + " ago" val text = "§eHopper Emptied: $format" - event.drawString(location.add(0.0, 1.15, 0.0), text, true) + event.drawString(location.add(y = 1.15), text, true) } } } @@ -326,6 +347,12 @@ class MinionFeatures { } companion object { + + var lastMinion: LorenzVec? = null + var lastStorage: LorenzVec? = null + var minionInventoryOpen = false + var minionStorageInventoryOpen = false + private var minions: Map<LorenzVec, Storage.ProfileSpecific.MinionConfig>? get() { return ProfileStorageData.profileSpecific?.minions diff --git a/src/main/java/at/hannibal2/skyhanni/features/minion/MinionXp.kt b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionXp.kt new file mode 100644 index 000000000..787cbe059 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionXp.kt @@ -0,0 +1,195 @@ +package at.hannibal2.skyhanni.features.minion + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.data.jsonobjects.repo.MinionXPJson +import at.hannibal2.skyhanni.events.IslandChangeEvent +import at.hannibal2.skyhanni.events.MinionCloseEvent +import at.hannibal2.skyhanni.events.MinionOpenEvent +import at.hannibal2.skyhanni.events.MinionStorageOpenEvent +import at.hannibal2.skyhanni.events.RepositoryReloadEvent +import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName +import at.hannibal2.skyhanni.utils.ItemUtils.getLore +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzVec +import at.hannibal2.skyhanni.utils.NEUInternalName +import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName +import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import net.minecraft.block.BlockChest +import net.minecraft.client.Minecraft +import net.minecraft.item.Item +import net.minecraft.item.ItemStack +import net.minecraftforge.event.entity.player.ItemTooltipEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.util.EnumMap + +class MinionXp { + + private val config get() = SkyHanniMod.feature.minions + + private val xpItemMap: MutableMap<PrimitiveItemStack, String> = mutableMapOf() + private val collectItemXpList: MutableList<String> = mutableListOf() + + private var collectItem: Item? = null + + private val minionStorages = mutableListOf<MinionStorage>() + + private var xpInfoMap: Map<NEUInternalName, XpInfo> = hashMapOf() + + data class XpInfo(val type: XpType, val amount: Double) + + private data class MinionStorage(val position: LorenzVec, val xpList: EnumMap<XpType, Double>) { + val timestamp: SimpleTimeMark = SimpleTimeMark.now() + } + + // TODO move to some other spot. This can be used at other features as well + private data class PrimitiveItemStack(val name: NEUInternalName, val stackSize: Int) + + private fun toPrimitiveItemStack(itemStack: ItemStack) = + PrimitiveItemStack(itemStack.getInternalName(), itemStack.stackSize) + + // TODO use upper case names, created a function to get type by lowercase name + // TODO maybe: rename to SkillType, move somewhere else + enum class XpType { + Farming, + Mining, + Combat, + Foraging, + Fishing, + Alchemy + } + + @SubscribeEvent + fun onMinionOpen(event: MinionOpenEvent) { + if (!config.xpDisplay) return + + collectItem = event.inventoryItems[48]?.item + collectItemXpList.clear() + + val xpTotal = handleItems(event.inventoryItems, true) + + val missesStorage = MinionFeatures.lastMinion?.let { minionPosition -> + getStorageXpAndUpdateTotal(minionPosition, xpTotal) + } ?: false + + collectItemXpList.addAll(xpTotal.map { (type, amount) -> collectMessage(type, amount) }) + if (missesStorage) { + collectItemXpList.add("") + collectItemXpList.add("§cError: No Minion Storage Data") + collectItemXpList.add("§eOpen Storage to get Correct Value") + } + collectItemXpList.add("") + } + + private fun getStorageXpAndUpdateTotal( + minionPosition: LorenzVec, + xpTotal: EnumMap<XpType, Double>, + ): Boolean { + if (!getHasStorage(minionPosition)) return false + val storage = minionStorages.firstOrNull { + it.position.distanceSq(minionPosition) <= 2.5 && it.timestamp.passedSince().inWholeMinutes < 20 + } + + return if (storage != null) { + storage.xpList.forEach { (type, amount) -> + xpTotal.compute(type) { _, currentAmount -> (currentAmount ?: 0.0) + amount } + } + false + } else { + true + } + + } + + private fun handleItems(inventoryItems: Map<Int, ItemStack>, isMinion: Boolean): EnumMap<XpType, Double> { + val xpTotal = EnumMap<XpType, Double>(XpType::class.java) + inventoryItems.filter { + it.value.getLore().isNotEmpty() && (!isMinion || it.key in listOf(21..26, 30..35, 39..44).flatten()) + }.forEach { (_, itemStack) -> + val item = toPrimitiveItemStack(itemStack) + val name = item.name + val xp = xpInfoMap[name] ?: return@forEach + + // TODO add wisdom and Derpy to calculation and random extra Exp Events + val xpAmount = xp.amount * item.stackSize + + xpItemMap[item] = collectMessage(xp.type, xpAmount) + xpTotal.compute(xp.type) { _, currentAmount -> (currentAmount ?: 0.0) + xpAmount } + } + return xpTotal + } + + @SubscribeEvent + fun onMinionStorageOpen(event: MinionStorageOpenEvent) { + if (!config.xpDisplay) return + + val xpTotal = handleItems(event.inventoryItems, false) + + if (event.position == null) return + minionStorages.removeIf { it.position == event.position } + minionStorages.add(MinionStorage(event.position, xpTotal)) + } + + private fun collectMessage(type: XpType, amount: Double) = + "§7Collect to get: §b${amount.addSeparators()} §e${type.name} XP" + + private fun getHasStorage(minionPosition: LorenzVec): Boolean { + val positionsToCheck = listOf( + LorenzVec(1, 0, 0), LorenzVec(0, 0, 1), + LorenzVec(-1, 0, 0), LorenzVec(0, 0, -1) + ) + + return positionsToCheck.any { position -> + val pos = minionPosition.add(position).toBlocPos() + val block = Minecraft.getMinecraft().theWorld.getBlockState(pos).block + block is BlockChest + } + } + + @SubscribeEvent + fun onItemTooltipEvent(event: ItemTooltipEvent) { + if (!LorenzUtils.inSkyBlock) return + if (!config.xpDisplay) return + when { + MinionFeatures.minionInventoryOpen -> { + addXpInfoToTooltip(event) + if (collectItem == event.itemStack.item) { + collectItemXpList.forEachIndexed { i, it -> + event.toolTip.add(i + 1, it) + } + } + } + + MinionFeatures.minionStorageInventoryOpen -> { + addXpInfoToTooltip(event) + } + } + } + + private fun addXpInfoToTooltip(event: ItemTooltipEvent) { + xpItemMap[toPrimitiveItemStack(event.itemStack)]?.let { + event.toolTip.add("") + event.toolTip.add(it) + } + } + + @SubscribeEvent + fun onIslandChangeEvent(event: IslandChangeEvent) { + minionStorages.clear() + xpItemMap.clear() + collectItemXpList.clear() + } + + @SubscribeEvent + fun onMinionClose(event: MinionCloseEvent) { + xpItemMap.clear() + collectItemXpList.clear() + } + + @SubscribeEvent + fun onRepoReload(event: RepositoryReloadEvent) { + xpInfoMap = event.getConstant<MinionXPJson>("MinionXP").minion_xp.mapNotNull { xpType -> + xpType.value.mapNotNull { it.key.asInternalName() to XpInfo(XpType.valueOf(xpType.key), it.value) } + }.flatten().toMap() + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/FixNEUHeavyPearls.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/FixNEUHeavyPearls.kt index 8f3920844..b5ce08ba7 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/FixNEUHeavyPearls.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/FixNEUHeavyPearls.kt @@ -1,7 +1,7 @@ package at.hannibal2.skyhanni.features.misc import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.SackChangeEvent +import at.hannibal2.skyhanni.events.ItemAddEvent import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName import io.github.moulberry.notenoughupdates.NotEnoughUpdates @@ -13,16 +13,14 @@ class FixNEUHeavyPearls { private val heavyPearl = "HEAVY_PEARL".asInternalName() @SubscribeEvent - fun onSackChange(event: SackChangeEvent) { + fun onSackChange(event: ItemAddEvent) { if (!isEnabled()) return - for (change in event.sackChanges) { - if (change.internalName == heavyPearl && change.delta == 3) { - val specific = NotEnoughUpdates.INSTANCE.config.getProfileSpecific() - if (System.currentTimeMillis() > specific.dailyHeavyPearlCompleted + 1.hours.inWholeMilliseconds) { - LorenzUtils.chat("Mark NEU Heavy Pearls as done.") - specific.dailyHeavyPearlCompleted = System.currentTimeMillis() - } + if (event.internalName == heavyPearl && event.amount == 3) { + val specific = NotEnoughUpdates.INSTANCE.config.getProfileSpecific() + if (System.currentTimeMillis() > specific.dailyHeavyPearlCompleted + 1.hours.inWholeMilliseconds) { + LorenzUtils.chat("Mark NEU Heavy Pearls as done.") + specific.dailyHeavyPearlCompleted = System.currentTimeMillis() } } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/InGameDateDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/InGameDateDisplay.kt index 5bacfd047..0d87bb767 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/InGameDateDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/InGameDateDisplay.kt @@ -10,7 +10,7 @@ import at.hannibal2.skyhanni.utils.RenderUtils.renderString import at.hannibal2.skyhanni.utils.StringUtils.matches import at.hannibal2.skyhanni.utils.StringUtils.removeColor import at.hannibal2.skyhanni.utils.TimeUtils.formatted -import at.hannibal2.skyhanni.utils.jsonobjects.TabListJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.TabListJson import io.github.moulberry.notenoughupdates.util.SkyBlockTime import net.minecraftforge.fml.common.eventhandler.SubscribeEvent diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/LockMouseLook.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/LockMouseLook.kt index 14b430d19..4025c32e2 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/LockMouseLook.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/LockMouseLook.kt @@ -46,4 +46,10 @@ object LockMouseLook { if (!lockedMouse) return config.lockedMouseDisplay.renderString("§eMouse Locked", posLabel = "Mouse Locked") } + + fun autoDisable() { + if (lockedMouse) { + toggleLock() + } + } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/MarkedPlayerManager.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/MarkedPlayerManager.kt index 66e379747..5409d956a 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/MarkedPlayerManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/MarkedPlayerManager.kt @@ -16,6 +16,8 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class MarkedPlayerManager { + private val config get() = SkyHanniMod.feature.markedPlayers + companion object { val playerNamesToMark = mutableListOf<String>() private val markedPlayers = mutableMapOf<String, EntityOtherPlayerMP>() @@ -64,7 +66,7 @@ class MarkedPlayerManager { @SubscribeEvent fun onConfigLoad(event: ConfigLoadEvent) { - SkyHanniMod.feature.markedPlayers.markOwnName.whenChanged { _, new -> + config.markOwnName.whenChanged { _, new -> val name = LorenzUtils.getPlayerName() if (new) { if (!playerNamesToMark.contains(name)) { @@ -87,8 +89,7 @@ class MarkedPlayerManager { @SubscribeEvent fun onRenderMobColored(event: RenderMobColoredEvent) { - if (!LorenzUtils.inSkyBlock) return - if (!SkyHanniMod.feature.markedPlayers.highlightInWorld) return + if (!isEnabled()) return val entity = event.entity if (entity in markedPlayers.values) { @@ -98,8 +99,7 @@ class MarkedPlayerManager { @SubscribeEvent fun onResetEntityHurtTime(event: ResetEntityHurtEvent) { - if (!LorenzUtils.inSkyBlock) return - if (!SkyHanniMod.feature.markedPlayers.highlightInWorld) return + if (!isEnabled()) return val entity = event.entity if (entity in markedPlayers.values) { @@ -112,11 +112,13 @@ class MarkedPlayerManager { if (Minecraft.getMinecraft().thePlayer == null) return markedPlayers.clear() - if (SkyHanniMod.feature.markedPlayers.markOwnName.get()) { + if (config.markOwnName.get()) { val name = LorenzUtils.getPlayerName() if (!playerNamesToMark.contains(name)) { playerNamesToMark.add(name) } } } + + private fun isEnabled() = LorenzUtils.inSkyBlock && config.highlightInWorld } diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/NonGodPotEffectDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/NonGodPotEffectDisplay.kt index 80c3b870d..d08dd888a 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/NonGodPotEffectDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/NonGodPotEffectDisplay.kt @@ -63,6 +63,7 @@ class NonGodPotEffectDisplay { private var patternEffectsCount = "§7You have §e(?<name>\\d+) §7non-god effects\\.".toPattern() private var totalEffectsCount = 0 + // todo : cleanup and add support for poison candy I, and add support for splash / other formats @SubscribeEvent fun onChatMessage(event: LorenzChatEvent) { if (event.message == "§aYou cleared all of your active effects!") { @@ -95,6 +96,7 @@ class NonGodPotEffectDisplay { effectDuration[NonGodPotEffect.GOBLIN] = Timer(20.minutes) update() } + if (event.message == "§cThe Goblin King's §r§afoul stench §r§chas dissipated!") { effectDuration.remove(NonGodPotEffect.GOBLIN) update() diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/QuickModMenuSwitch.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/QuickModMenuSwitch.kt index 9b6987fad..fceb8563e 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/QuickModMenuSwitch.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/QuickModMenuSwitch.kt @@ -8,7 +8,7 @@ import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.makeAccessible import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems -import at.hannibal2.skyhanni.utils.jsonobjects.ModGuiSwitcherJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.ModGuiSwitcherJson import at.hannibal2.skyhanni.utils.renderables.Renderable import net.minecraft.client.Minecraft import net.minecraft.client.renderer.GlStateManager diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/AdvancedPlayerList.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/AdvancedPlayerList.kt index 7c96f4efa..2eac62d1f 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/AdvancedPlayerList.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/AdvancedPlayerList.kt @@ -1,12 +1,13 @@ package at.hannibal2.skyhanni.features.misc.compacttablist import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.data.BingoAPI import at.hannibal2.skyhanni.data.FriendAPI import at.hannibal2.skyhanni.data.GuildAPI import at.hannibal2.skyhanni.data.IslandType import at.hannibal2.skyhanni.data.PartyAPI +import at.hannibal2.skyhanni.data.jsonobjects.repo.ContributorListJson import at.hannibal2.skyhanni.events.RepositoryReloadEvent +import at.hannibal2.skyhanni.features.bingo.BingoAPI import at.hannibal2.skyhanni.features.misc.MarkedPlayerManager import at.hannibal2.skyhanni.test.SkyHanniDebugsAndTests import at.hannibal2.skyhanni.utils.KeyboardManager @@ -14,7 +15,6 @@ import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.StringUtils.removeColor -import at.hannibal2.skyhanni.utils.jsonobjects.ContributorListJson import com.google.common.cache.CacheBuilder import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import java.util.concurrent.TimeUnit diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordRPCManager.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordRPCManager.kt index e358b3f28..96123826e 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordRPCManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordRPCManager.kt @@ -5,11 +5,15 @@ package at.hannibal2.skyhanni.features.misc.discordrpc import at.hannibal2.skyhanni.SkyHanniMod.Companion.consoleLog import at.hannibal2.skyhanni.SkyHanniMod.Companion.coroutineScope import at.hannibal2.skyhanni.SkyHanniMod.Companion.feature +import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator +import at.hannibal2.skyhanni.config.features.misc.DiscordRPCConfig.LineEntry +import at.hannibal2.skyhanni.config.features.misc.DiscordRPCConfig.PriorityEntry import at.hannibal2.skyhanni.events.ConfigLoadEvent import at.hannibal2.skyhanni.events.LorenzKeyPressEvent import at.hannibal2.skyhanni.events.LorenzTickEvent import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent import at.hannibal2.skyhanni.test.command.ErrorManager +import at.hannibal2.skyhanni.utils.ConfigUtils import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.onToggle import at.hannibal2.skyhanni.utils.SimpleTimeMark @@ -50,9 +54,9 @@ object DiscordRPCManager : IPCListener { return@launch } consoleLog("Starting Discord RPC...") - - firstLine = getStatusByConfigId(config.firstLine.get()) - secondLine = getStatusByConfigId(config.secondLine.get()) + // TODO, change functionality to use enum rather than ordinals + firstLine = getStatusByConfigId(config.firstLine.get().ordinal) + secondLine = getStatusByConfigId(config.secondLine.get().ordinal) startTimestamp = System.currentTimeMillis() client = IPCClient(applicationID) client?.setListener(this@DiscordRPCManager) @@ -106,9 +110,9 @@ object DiscordRPCManager : IPCListener { fun updatePresence() { val location = DiscordStatus.LOCATION.getDisplayString() val discordIconKey = DiscordLocationKey.getDiscordIconKey(location) - - secondLine = getStatusByConfigId(config.secondLine.get()) - firstLine = getStatusByConfigId(config.firstLine.get()) + // TODO, change functionality to use enum rather than ordinals + secondLine = getStatusByConfigId(config.secondLine.get().ordinal) + firstLine = getStatusByConfigId(config.firstLine.get().ordinal) val presence: RichPresence = RichPresence.Builder() .setDetails(firstLine.getDisplayString()) .setState(secondLine.getDisplayString()) @@ -207,7 +211,25 @@ object DiscordRPCManager : IPCListener { // Events that change things in DiscordStatus @SubscribeEvent fun onKeybind(event: LorenzKeyPressEvent) { - if (!isEnabled() || !feature.misc.discordRPC.autoPriority.contains(4)) return // autoPriority 4 is dynamic afk + if (!isEnabled() || !PriorityEntry.AFK.isSelected()) return // autoPriority 4 is dynamic afk beenAfkFor = SimpleTimeMark.now() } + + @SubscribeEvent + fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { + event.move(11, "misc.discordRPC.firstLine", "misc.discordRPC.firstLine") { element -> + ConfigUtils.migrateIntToEnum(element, LineEntry::class.java) + } + event.move(11, "misc.discordRPC.secondLine", "misc.discordRPC.secondLine") { element -> + ConfigUtils.migrateIntToEnum(element, LineEntry::class.java) + } + event.move(11, "misc.discordRPC.auto", "misc.discordRPC.auto") { element -> + ConfigUtils.migrateIntToEnum(element, LineEntry::class.java) + } + event.move(11, "misc.discordRPC.autoPriority", "misc.discordRPC.autoPriority") { element -> + ConfigUtils.migrateIntArrayListToEnumArrayList(element, PriorityEntry::class.java) + } + } + + private fun PriorityEntry.isSelected() = config.autoPriority.contains(this) } diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordStatus.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordStatus.kt index 141870585..cc2a09b9d 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordStatus.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordStatus.kt @@ -258,7 +258,8 @@ enum class DiscordStatus(private val displayMessageSupplier: Supplier<String>?) AUTO({ var autoReturn = "" for (statusID in SkyHanniMod.feature.misc.discordRPC.autoPriority) { // for every dynamic that the user wants to see... - val autoStatus = AutoStatus.entries[statusID] + // TODO, change functionality to use enum rather than ordinals + val autoStatus = AutoStatus.entries[statusID.ordinal] val result = autoStatus.correspondingDiscordStatus.getDisplayString() // get what would happen if we were to display it if (result != autoStatus.placeholderText) { // if that value is useful, display it @@ -269,7 +270,7 @@ enum class DiscordStatus(private val displayMessageSupplier: Supplier<String>?) if (autoReturn == "") { // if we didn't find any useful information, display the fallback val statusNoAuto = DiscordStatus.entries.toMutableList() statusNoAuto.remove(AUTO) - autoReturn = statusNoAuto[SkyHanniMod.feature.misc.discordRPC.auto.get()].getDisplayString() + autoReturn = statusNoAuto[SkyHanniMod.feature.misc.discordRPC.auto.get().ordinal].getDisplayString() } autoReturn }), diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValue.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValue.kt index a4fe36fdc..cefac74a8 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValue.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValue.kt @@ -38,7 +38,9 @@ object EstimatedItemValue { private val cache = mutableMapOf<ItemStack, List<List<Any>>>() private var lastToolTipTime = 0L var gemstoneUnlockCosts = HashMap<NEUInternalName, HashMap<String, List<String>>>() - var currentlyShowing = false + private var currentlyShowing = false + + fun isCurrentlyShowing() = currentlyShowing && Minecraft.getMinecraft().currentScreen != null @SubscribeEvent fun onRepoReload(event: RepositoryReloadEvent) { @@ -139,11 +141,6 @@ object EstimatedItemValue { } } - // Stats Breakdown - val name = item.name ?: return - if (name == "§6☘ Category: Item Ability (Passive)") return - if (name.contains("Salesperson")) return - val newDisplay = try { draw(item) } catch (e: Exception) { @@ -160,6 +157,16 @@ object EstimatedItemValue { private fun draw(stack: ItemStack): List<List<Any>> { val internalName = stack.getInternalNameOrNull() ?: return listOf() + // Stats Breakdown + val name = stack.name ?: return listOf() + if (name == "§6☘ Category: Item Ability (Passive)") return listOf() + if (name.contains("Salesperson")) return listOf() + + // Autopet rule > Create Rule + if (!InventoryUtils.isSlotInPlayerInventory(stack)) { + if (InventoryUtils.openInventoryName() == "Choose a wardrobe slot") return listOf() + } + // FIX neu item list if (internalName.startsWith("ULTIMATE_ULTIMATE_")) return listOf() // We don't need this feature to work on books at all @@ -190,7 +197,7 @@ object EstimatedItemValue { } else { NumberUtil.format(totalPrice) } - list.add("§aTotal: §6§l$numberFormat") + list.add("§aTotal: §6§l$numberFormat coins") val newDisplay = mutableListOf<List<Any>>() for (line in list) { diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValueCalculator.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValueCalculator.kt index f3e27957d..5f726f544 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValueCalculator.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValueCalculator.kt @@ -527,6 +527,7 @@ object EstimatedItemValueCalculator { return price } + // TODO repo private val hasAlwaysScavenger = listOf( "CRYPT_DREADLORD_SWORD".asInternalName(), "ZOMBIE_SOLDIER_CUTLASS".asInternalName(), @@ -535,6 +536,12 @@ object EstimatedItemValueCalculator { "ZOMBIE_KNIGHT_SWORD".asInternalName(), "SILENT_DEATH".asInternalName(), "ZOMBIE_COMMANDER_WHIP".asInternalName(), + "ICE_SPRAY_WAND".asInternalName(), + ) + + private val hasAlwaysReplenish = listOf( + "ADVANCED_GARDENING_HOE".asInternalName(), + "ADVANCED_GARDENING_AXE".asInternalName(), ) private fun addEnchantments(stack: ItemStack, list: MutableList<String>): Double { @@ -554,6 +561,10 @@ object EstimatedItemValueCalculator { continue } + if (rawName == "replenish" && rawLevel == 1 && internalName in hasAlwaysReplenish) { + continue + } + var level = rawLevel var multiplier = 1 if (rawName == "ultimate_chimera" || rawName == "ultimate_fatal_tempo" || rawName == "smoldering") { diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedWardrobePrice.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedWardrobePrice.kt index 6655d71cd..3969372ff 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedWardrobePrice.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedWardrobePrice.kt @@ -42,7 +42,7 @@ class EstimatedWardrobePrice { toolTip.add(index++, " §7- $name: §6${NumberUtil.format(price)}") } - toolTip.add(index, " §aTotal Value: §6§l${NumberUtil.format(totalPrice)}") + toolTip.add(index, " §aTotal Value: §6§l${NumberUtil.format(totalPrice)} coins") } @SubscribeEvent diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorFeatures.kt index 318d4c1f0..b07c4dab6 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorFeatures.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorFeatures.kt @@ -1,6 +1,8 @@ package at.hannibal2.skyhanni.features.misc.trevor import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator +import at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry import at.hannibal2.skyhanni.data.IslandType import at.hannibal2.skyhanni.data.ScoreboardData import at.hannibal2.skyhanni.events.CheckRenderEntityEvent @@ -14,6 +16,7 @@ import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed import at.hannibal2.skyhanni.mixins.hooks.RenderLivingEntityHelper import at.hannibal2.skyhanni.test.GriffinUtils.drawWaypointFilled import at.hannibal2.skyhanni.test.command.ErrorManager +import at.hannibal2.skyhanni.utils.ConfigUtils import at.hannibal2.skyhanni.utils.EntityUtils import at.hannibal2.skyhanni.utils.LocationUtils.distanceToPlayer import at.hannibal2.skyhanni.utils.LorenzColor @@ -67,16 +70,16 @@ object TrevorFeatures { init { fixedRateTimer(name = "skyhanni-update-trapper", period = 1000L) { - Minecraft.getMinecraft().addScheduledTask { - try { - if (config.trapperSolver && onFarmingIsland()) { + if (onFarmingIsland() && config.trapperSolver) { + Minecraft.getMinecraft().addScheduledTask { + try { updateTrapper() - TrevorTracker.saveAndUpdate() + TrevorTracker.update() TrevorTracker.calculatePeltsPerHour() if (questActive) TrevorSolver.findMob() + } catch (error: Throwable) { + ErrorManager.logError(error, "Encountered an error when updating the trapper solver") } - } catch (error: Throwable) { - ErrorManager.logError(error, "Encountered an error when updating the trapper solver") } } } @@ -158,7 +161,6 @@ object TrevorFeatures { ) } - private fun updateTrapper() { timeUntilNextReady -= 1 if (trapperReady && timeUntilNextReady > 0) { @@ -220,7 +222,7 @@ object TrevorFeatures { { config.trapperTalkCooldown } entityTrapper.getLorenzVec().let { if (it.distanceToPlayer() < 15) { - event.drawString(it.add(0.0, 2.23, 0.0), currentLabel) + event.drawString(it.add(y = 2.23), currentLabel) } } } @@ -236,11 +238,11 @@ object TrevorFeatures { TrevorSolver.currentMob!!.mobName } location = TrevorSolver.mobCoordinates - event.drawWaypointFilled(location.add(0, -2, 0), LorenzColor.GREEN.toColor(), true, true) - event.drawDynamicText(location.add(0, 1, 0), displayName, 1.5) + event.drawWaypointFilled(location.add(y = -2), LorenzColor.GREEN.toColor(), true, true) + event.drawDynamicText(location.add(y = 1), displayName, 1.5) } else { event.drawWaypointFilled(location, LorenzColor.GOLD.toColor(), true, true) - event.drawDynamicText(location.add(0, 1, 0), TrevorSolver.mobLocation.location, 1.5) + event.drawDynamicText(location.add(y = 1), TrevorSolver.mobLocation.location, 1.5) } } } @@ -302,4 +304,11 @@ object TrevorFeatures { fun onFarmingIsland() = IslandType.THE_FARMING_ISLANDS.isInIsland() fun inTrapperDen() = ScoreboardData.sidebarLinesFormatted.contains(" §7⏣ §bTrapper's Den") + + @SubscribeEvent + fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { + event.move(11, "misc.trevorTheTrapper.textFormat", "misc.trevorTheTrapper.textFormat") { element -> + ConfigUtils.migrateIntArrayListToEnumArrayList(element, TrackerEntry::class.java) + } + } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorTracker.kt index 59d44b1b7..175d21903 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorTracker.kt @@ -59,13 +59,13 @@ object TrevorTracker { peltsPerSecond.clear() peltsPerHour = 0 stoppedChecks = 0 - saveAndUpdate() } private fun formatDisplay(map: List<List<Any>>): List<List<Any>> { val newList = mutableListOf<List<Any>>() for (index in config.textFormat) { - newList.add(map[index]) + // TODO, change functionality to use enum rather than ordinals + newList.add(map[index.ordinal]) } return newList } @@ -80,14 +80,14 @@ object TrevorTracker { val pelts = matcher.group("pelts").toInt() storage.peltsGained += pelts storage.selfKillingAnimals += 1 - saveAndUpdate() + update() } matcher = killMobPattern.matcher(event.message) if (matcher.matches()) { val pelts = matcher.group("pelts").toInt() storage.peltsGained += pelts storage.killedAnimals += 1 - saveAndUpdate() + update() } } @@ -98,10 +98,10 @@ object TrevorTracker { val foundRarity = TrapperMobRarity.entries.firstOrNull { it.formattedName == rarity } ?: return val old = storage.animalRarities[foundRarity] ?: 0 storage.animalRarities = storage.animalRarities.editCopy { this[foundRarity] = old + 1 } - saveAndUpdate() + update() } - fun saveAndUpdate() { + fun update() { val storage = ProfileStorageData.profileSpecific?.trapperData ?: return display = formatDisplay(drawTrapperDisplay(storage)) } diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazingSouls.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazingSouls.kt index 8d7507e12..03175e255 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazingSouls.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazingSouls.kt @@ -48,7 +48,7 @@ class AshfangBlazingSouls { event.drawWaypointFilled(orbLocation.add(-0.5, 1.25, -0.5), color, extraSize = -0.15) if (orbLocation.distance(playerLocation) < 10) { //TODO find way to dynamically change color - event.drawString(orbLocation.add(0.0, 2.5, 0.0), "§bBlazing Soul") + event.drawString(orbLocation.add(y = 2.5), "§bBlazing Soul") } } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangFreezeCooldown.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangFreezeCooldown.kt index 5fd7a3b77..447884c05 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangFreezeCooldown.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangFreezeCooldown.kt @@ -8,13 +8,16 @@ import at.hannibal2.skyhanni.features.combat.damageindicator.BossType import at.hannibal2.skyhanni.features.combat.damageindicator.DamageIndicatorManager import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.RenderUtils.renderString -import at.hannibal2.skyhanni.utils.StringUtils.matchRegex +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.TimeUtils import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class AshfangFreezeCooldown { private val config get() = SkyHanniMod.feature.crimsonIsle.ashfang + // TODO USE SH-REPO + private val cryogenicBlastPattern = "§cAshfang Follower's Cryogenic Blast hit you for (.*) damage!".toPattern() + private var lastHit = 0L @SubscribeEvent @@ -22,7 +25,7 @@ class AshfangFreezeCooldown { if (!isEnabled()) return val message = event.message - if (message.matchRegex("§cAshfang Follower's Cryogenic Blast hit you for (.*) damage!")) { + cryogenicBlastPattern.matchMatcher(message) { lastHit = System.currentTimeMillis() } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangGravityOrbs.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangGravityOrbs.kt index 5b3fc60de..bf9899e0c 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangGravityOrbs.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangGravityOrbs.kt @@ -49,7 +49,7 @@ class AshfangGravityOrbs { if (orbLocation.distance(playerLocation) < 15) { //TODO find way to dynamically change color - event.drawString(orbLocation.add(0.0, 2.5, 0.0), "§cGravity Orb") + event.drawString(orbLocation.add(y = 2.5), "§cGravity Orb") } } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/CrimsonIsleReputationHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/CrimsonIsleReputationHelper.kt index ec03ad514..d6f8d8e05 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/CrimsonIsleReputationHelper.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/CrimsonIsleReputationHelper.kt @@ -19,7 +19,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland import at.hannibal2.skyhanni.utils.LorenzVec import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems import at.hannibal2.skyhanni.utils.TabListData -import at.hannibal2.skyhanni.utils.jsonobjects.CrimsonIsleReputationJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.CrimsonIsleReputationJson import net.minecraftforge.fml.common.eventhandler.EventPriority import net.minecraftforge.fml.common.eventhandler.SubscribeEvent 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 a14da5859..bf88fb865 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 @@ -13,7 +13,7 @@ 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.utils.jsonobjects.CrimsonIsleReputationJson.ReputationQuest +import at.hannibal2.skyhanni.data.jsonobjects.repo.CrimsonIsleReputationJson.ReputationQuest import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class DailyKuudraBossHelper(private val reputationHelper: CrimsonIsleReputationHelper) { diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/QuestLoader.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/QuestLoader.kt index 6184fd51e..47a8716fd 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/QuestLoader.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/QuestLoader.kt @@ -15,7 +15,7 @@ import at.hannibal2.skyhanni.features.nether.reputationhelper.dailyquest.quest.U import at.hannibal2.skyhanni.utils.ItemUtils.getLore import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.TabListData -import at.hannibal2.skyhanni.utils.jsonobjects.CrimsonIsleReputationJson.ReputationQuest +import at.hannibal2.skyhanni.data.jsonobjects.repo.CrimsonIsleReputationJson.ReputationQuest class QuestLoader(private val dailyQuestHelper: DailyQuestHelper) { diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/DailyMiniBossHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/DailyMiniBossHelper.kt index 52f5c23f4..87ab3ae5f 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/DailyMiniBossHelper.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/DailyMiniBossHelper.kt @@ -16,7 +16,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList import at.hannibal2.skyhanni.utils.NEUItems.getItemStack import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher -import at.hannibal2.skyhanni.utils.jsonobjects.CrimsonIsleReputationJson.ReputationQuest +import at.hannibal2.skyhanni.data.jsonobjects.repo.CrimsonIsleReputationJson.ReputationQuest import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class DailyMiniBossHelper(private val reputationHelper: CrimsonIsleReputationHelper) { diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/RiftAgaricusCap.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/RiftAgaricusCap.kt index 5ef56976f..c1790a6cc 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/RiftAgaricusCap.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/RiftAgaricusCap.kt @@ -59,7 +59,7 @@ class RiftAgaricusCap { fun onRenderWorld(event: LorenzRenderWorldEvent) { if (!isEnabled()) return - val location = location?.add(0.0, 0.6, 0.0) ?: return + val location = location?.add(y = 0.6) ?: return if (startTime == -1L) { event.drawDynamicText(location, "§cClick!", 1.5) diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/RiftWiltedBerberisHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/RiftWiltedBerberisHelper.kt index e17bd32ed..aa1dafd55 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/RiftWiltedBerberisHelper.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/RiftWiltedBerberisHelper.kt @@ -43,7 +43,7 @@ class RiftWiltedBerberisHelper { hasFarmingToolInHand = InventoryUtils.getItemInHand()?.getInternalName() == RiftAPI.farmingTool if (Minecraft.getMinecraft().thePlayer.onGround) { - val block = LocationUtils.playerLocation().add(0, -1, 0).getBlockAt().toString() + val block = LocationUtils.playerLocation().add(y = -1).getBlockAt().toString() val currentY = LocationUtils.playerLocation().y isOnFarmland = block == "Block{minecraft:farmland}" && (currentY % 1 == 0.0) } @@ -115,7 +115,7 @@ class RiftWiltedBerberisHelper { val location = currentParticles.fixLocation(berberis) if (!moving) { event.drawFilledBoundingBox_nea(axisAlignedBB(location), Color.YELLOW, 0.7f) - event.drawDynamicText(location.add(0, 1, 0), "§eWilted Berberis", 1.5, ignoreBlocks = false) + event.drawDynamicText(location.add(y = 1), "§eWilted Berberis", 1.5, ignoreBlocks = false) } else { event.drawFilledBoundingBox_nea(axisAlignedBB(location), Color.WHITE, 0.5f) previous?.fixLocation(berberis)?.let { diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/VoltHighlighter.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/VoltHighlighter.kt index 6cf37e285..41d42f77b 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/VoltHighlighter.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/VoltHighlighter.kt @@ -75,7 +75,7 @@ class VoltHighlighter { val dischargeTimeLeft = CHARGE_TIME - dischargingSince.passedSince() if (dischargeTimeLeft > Duration.ZERO) { event.drawDynamicText( - event.exactLocation(entity).add(0.0, 2.5, 0.0), + event.exactLocation(entity).add(y = 2.5), "§eLightning: ${dischargeTimeLeft.format(showMilliSeconds = true)}", 2.5 ) diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/livingcave/LivingCaveDefenseBlocks.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/livingcave/LivingCaveDefenseBlocks.kt index 88b2939c8..071ec6e94 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/livingcave/LivingCaveDefenseBlocks.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/livingcave/LivingCaveDefenseBlocks.kt @@ -147,7 +147,7 @@ class LivingCaveDefenseBlocks { val location = block.location event.drawWaypointFilled(location, color) event.draw3DLine( - block.entity.getLorenzVec().add(0.0, 0.5, 0.0), + block.entity.getLorenzVec().add(y = 0.5), location.add(0.5, 0.5, 0.5), color, 1, @@ -161,7 +161,7 @@ class LivingCaveDefenseBlocks { event.drawWaypointFilled(location, color) event.draw3DLine( - block.entity.getLorenzVec().add(0.0, 0.5, 0.0), + block.entity.getLorenzVec().add(y = 0.5), location.add(0.5, 0.5, 0.5), color, 3, 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 524e1b354..a2b337668 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 @@ -12,7 +12,7 @@ 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.utils.jsonobjects.DanceRoomInstructionsJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.DanceRoomInstructionsJson import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/RiftLavaMazeParkour.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/RiftLavaMazeParkour.kt index efaf77163..2ffcb7928 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/RiftLavaMazeParkour.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/RiftLavaMazeParkour.kt @@ -9,7 +9,7 @@ import at.hannibal2.skyhanni.features.rift.RiftAPI import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.toChromaColor import at.hannibal2.skyhanni.utils.ParkourHelper -import at.hannibal2.skyhanni.utils.jsonobjects.ParkourJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.ParkourJson import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class RiftLavaMazeParkour { diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/RiftUpsideDownParkour.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/RiftUpsideDownParkour.kt index 18a09709d..1826a5e38 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/RiftUpsideDownParkour.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/RiftUpsideDownParkour.kt @@ -9,7 +9,7 @@ import at.hannibal2.skyhanni.features.rift.RiftAPI import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.toChromaColor import at.hannibal2.skyhanni.utils.ParkourHelper -import at.hannibal2.skyhanni.utils.jsonobjects.ParkourJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.ParkourJson import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class RiftUpsideDownParkour { diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/TubulatorParkour.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/TubulatorParkour.kt index 567f2bf2e..281643bfc 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/TubulatorParkour.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/TubulatorParkour.kt @@ -9,7 +9,7 @@ import at.hannibal2.skyhanni.utils.LocationUtils.isPlayerInside import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.toChromaColor import at.hannibal2.skyhanni.utils.ParkourHelper -import at.hannibal2.skyhanni.utils.jsonobjects.ParkourJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.ParkourJson import net.minecraft.util.AxisAlignedBB import net.minecraftforge.fml.common.eventhandler.SubscribeEvent diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/stillgorechateau/RiftBloodEffigies.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/stillgorechateau/RiftBloodEffigies.kt index d10aac4ca..9fc00b99a 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/stillgorechateau/RiftBloodEffigies.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/stillgorechateau/RiftBloodEffigies.kt @@ -19,7 +19,7 @@ import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.TimeUtils import at.hannibal2.skyhanni.utils.getLorenzVec -import at.hannibal2.skyhanni.utils.jsonobjects.RiftEffigiesJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.RiftEffigiesJson import net.minecraft.entity.item.EntityArmorStand import net.minecraftforge.fml.common.eventhandler.SubscribeEvent diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/EnigmaSoulWaypoints.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/EnigmaSoulWaypoints.kt index 983df0d88..f8ceaa833 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/EnigmaSoulWaypoints.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/EnigmaSoulWaypoints.kt @@ -1,5 +1,6 @@ package at.hannibal2.skyhanni.features.rift.everywhere +import at.hannibal2.skyhanni.data.jsonobjects.repo.EnigmaSoulsJson import at.hannibal2.skyhanni.events.GuiContainerEvent import at.hannibal2.skyhanni.events.InventoryCloseEvent import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent @@ -17,7 +18,6 @@ import at.hannibal2.skyhanni.utils.NEUItems import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText import at.hannibal2.skyhanni.utils.RenderUtils.highlight import at.hannibal2.skyhanni.utils.StringUtils.removeColor -import at.hannibal2.skyhanni.utils.jsonobjects.EnigmaSoulsJson import io.github.moulberry.notenoughupdates.events.ReplaceItemEvent import io.github.moulberry.notenoughupdates.events.SlotClickEvent import io.github.moulberry.notenoughupdates.util.Utils @@ -137,7 +137,7 @@ object EnigmaSoulWaypoints { for (soul in trackedSouls) { soulLocations[soul]?.let { event.drawWaypointFilled(it, LorenzColor.DARK_PURPLE.toColor(), seeThroughBlocks = true, beacon = true) - event.drawDynamicText(it.add(0, 1, 0), "§5$soul Soul", 1.5) + event.drawDynamicText(it.add(y = 1), "§5$soul Soul", 1.5) } } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/motes/ShowMotesNpcSellPrice.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/motes/ShowMotesNpcSellPrice.kt index 53b7b56f9..47c002c92 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/motes/ShowMotesNpcSellPrice.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/motes/ShowMotesNpcSellPrice.kt @@ -156,7 +156,7 @@ class ShowMotesNpcSellPrice { add("§6Value per: §d$valuePer Motes") add("§6Total in chest: §d${(value / valuePer).toInt()}") add("") - add("§6Total value: §d$price") + add("§6Total value: §d$price coins") } add(Renderable.hoverTips("§6${stack.displayName}: §b$price", tips, indexes = index, stack = stack)) }) diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/HideMobNames.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/HideMobNames.kt index 34a98bb43..eee256884 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/slayer/HideMobNames.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/HideMobNames.kt @@ -17,7 +17,7 @@ class HideMobNames { private val patterns = mutableListOf<Pattern>() init { - addMobToHide("Zombie") + // TODO USE SH-REPO addMobToHide("Zombie") addMobToHide("Zombie Villager") addMobToHide("Crypt Ghoul") @@ -84,4 +84,4 @@ class HideMobNames { return false } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerBossSpawnSoon.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerBossSpawnSoon.kt index 2bfdf640f..c5fd182db 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerBossSpawnSoon.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerBossSpawnSoon.kt @@ -14,7 +14,7 @@ import kotlin.time.Duration.Companion.seconds class SlayerBossSpawnSoon { private val config get() = SkyHanniMod.feature.slayer.slayerBossWarning - private val pattern = " \\(?(?<progress>[0-9.,k]+)\\/(?<total>[0-9.,k]+)\\)?.*".toPattern() + private val pattern = " \\(?(?<progress>[0-9.,k]+)/(?<total>[0-9.,k]+)\\)?.*".toPattern() private var lastCompletion = 0f private var warned = false diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemsOnGround.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemsOnGround.kt index 0cb129c7d..f0f80ace4 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemsOnGround.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemsOnGround.kt @@ -32,7 +32,7 @@ class SlayerItemsOnGround { if (!SlayerAPI.hasActiveSlayerQuest()) return for (entityItem in EntityUtils.getEntities<EntityItem>()) { - val location = event.exactLocation(entityItem).add(0.0, 0.8, 0.0) + val location = event.exactLocation(entityItem).add(y = 0.8) if (location.distance(LocationUtils.playerLocation()) > 15) continue val itemStack = entityItem.entityItem diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerMiniBossFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerMiniBossFeatures.kt index f45d352b5..e384b5de8 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerMiniBossFeatures.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerMiniBossFeatures.kt @@ -60,7 +60,7 @@ class SlayerMiniBossFeatures { event.draw3DLine( event.exactPlayerEyeLocation(), - mob.getLorenzVec().add(0, 1, 0), + mob.getLorenzVec().add(y = 1), LorenzColor.AQUA.toColor(), 3, true 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 c05839ba6..52e27d305 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt @@ -1,108 +1,76 @@ package at.hannibal2.skyhanni.features.slayer import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.config.Storage import at.hannibal2.skyhanni.data.SlayerAPI import at.hannibal2.skyhanni.events.GuiRenderEvent -import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.ItemAddEvent import at.hannibal2.skyhanni.events.PurseChangeCause import at.hannibal2.skyhanni.events.PurseChangeEvent import at.hannibal2.skyhanni.events.RepositoryReloadEvent -import at.hannibal2.skyhanni.events.SackChangeEvent import at.hannibal2.skyhanni.events.SlayerChangeEvent import at.hannibal2.skyhanni.events.SlayerQuestCompleteEvent -import at.hannibal2.skyhanni.events.entity.ItemAddInInventoryEvent -import at.hannibal2.skyhanni.features.bazaar.BazaarApi.Companion.getBazaarData -import at.hannibal2.skyhanni.test.PriceSource -import at.hannibal2.skyhanni.utils.KeyboardManager import at.hannibal2.skyhanni.utils.LorenzLogger import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList -import at.hannibal2.skyhanni.utils.LorenzUtils.addSelector -import at.hannibal2.skyhanni.utils.LorenzUtils.sortedDesc import at.hannibal2.skyhanni.utils.NEUInternalName -import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName -import at.hannibal2.skyhanni.utils.NEUItems.getNpcPriceOrNull -import at.hannibal2.skyhanni.utils.NEUItems.getPriceOrNull import at.hannibal2.skyhanni.utils.NumberUtil import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators -import at.hannibal2.skyhanni.utils.SimpleTimeMark -import at.hannibal2.skyhanni.utils.StringUtils -import at.hannibal2.skyhanni.utils.StringUtils.matches import at.hannibal2.skyhanni.utils.StringUtils.removeColor -import at.hannibal2.skyhanni.utils.jsonobjects.SlayerProfitTrackerItemsJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.SlayerProfitTrackerItemsJson import at.hannibal2.skyhanni.utils.renderables.Renderable -import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker -import at.hannibal2.skyhanni.utils.tracker.TrackerData +import at.hannibal2.skyhanni.utils.tracker.ItemTrackerData +import at.hannibal2.skyhanni.utils.tracker.SkyHanniItemTracker +import com.google.gson.JsonObject +import com.google.gson.JsonPrimitive import com.google.gson.annotations.Expose import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.seconds object SlayerProfitTracker { private val config get() = SkyHanniMod.feature.slayer.itemProfitTracker - private val diceRollChatPattern = - "§eYour §r§(5|6High Class )Archfiend Dice §r§erolled a §r§.(?<number>.)§r§e! Bonus: §r§.(?<hearts>.*)❤".toPattern() - - private val ARCHFIEND_DICE = "ARCHFIEND_DICE".asInternalName() - private val HIGH_CLASS_ARCHFIEND_DICE = "HIGH_CLASS_ARCHFIEND_DICE".asInternalName() - private var itemLogCategory = "" private var baseSlayerType = "" private val logger = LorenzLogger("slayer/profit_tracker") - private var lastClickDelay = 0L - private val trackers = mutableMapOf<String, SkyHanniTracker<Data>>() + private val trackers = mutableMapOf<String, SkyHanniItemTracker<Data>>() - class Data : TrackerData() { - override fun reset() { - items.clear() - mobKillCoins = 0 + class Data : ItemTrackerData() { + override fun resetItems() { slayerSpawnCost = 0 slayerCompletedCount = 0 } @Expose - var items: MutableMap<NEUInternalName, SlayerItem> = HashMap() - - @Expose - var mobKillCoins: Long = 0 - - @Expose var slayerSpawnCost: Long = 0 @Expose var slayerCompletedCount = 0 - class SlayerItem { - @Expose - var internalName: NEUInternalName? = null - - @Expose - var timesDropped: Long = 0 + override fun getDescription(timesDropped: Long): List<String> { + val percentage = timesDropped.toDouble() / slayerCompletedCount + val perBoss = LorenzUtils.formatPercentage(percentage.coerceAtMost(1.0)) - @Expose - var totalAmount: Long = 0 + return listOf( + "§7Dropped §e${timesDropped.addSeparators()} §7times.", + "§7Your drop rate: §c$perBoss", + ) + } - @Expose - var hidden = false + override fun getCoinName(item: TrackedItem) = "§6Mob Kill Coins" - override fun toString() = "SlayerItem{" + - "internalName='" + internalName + '\'' + - ", timesDropped=" + timesDropped + - ", totalAmount=" + totalAmount + - ", hidden=" + hidden + - '}' + override fun getCoinDescription(item: TrackedItem): List<String> { + val mobKillCoinsFormat = NumberUtil.format(item.totalAmount) + return listOf( + "§7Killing mobs gives you coins (more with scavenger).", + "§7You got §6$mobKillCoinsFormat coins §7way." + ) } - - override fun toString() = "SlayerProfitTracker.Data{" + - "items=" + items + - ", mobKillCoins=" + mobKillCoins + - ", slayerSpawnCost=" + slayerSpawnCost + - ", slayerCompletedCount=" + slayerCompletedCount + - '}' } + private val ItemTrackerData.TrackedItem.timesDropped get() = timesGained + private fun addSlayerCosts(price: Int) { getTracker()?.modify { it.slayerSpawnCost += price @@ -139,21 +107,14 @@ object SlayerProfitTracker { } private fun addMobKillCoins(coins: Int) { - getTracker()?.modify { - it.mobKillCoins += coins - } + getTracker()?.addCoins(coins) } private fun addItemPickup(internalName: NEUInternalName, stackSize: Int) { - getTracker()?.modify { - val slayerItem = it.items.getOrPut(internalName) { Data.SlayerItem() } - - slayerItem.timesDropped++ - slayerItem.totalAmount += stackSize - } + getTracker()?.addItem(internalName, stackSize) } - private fun getTracker(): SkyHanniTracker<Data>? { + private fun getTracker(): SkyHanniItemTracker<Data>? { if (itemLogCategory == "") return null return trackers.getOrPut(itemLogCategory) { @@ -162,7 +123,7 @@ object SlayerProfitTracker { itemLogCategory ) { Data() } } - SkyHanniTracker("$itemLogCategory Profit Tracker", { Data() }, getStorage) { drawDisplay(it) } + SkyHanniItemTracker("$itemLogCategory Profit Tracker", { Data() }, getStorage) { drawDisplay(it) } } } @@ -174,46 +135,14 @@ object SlayerProfitTracker { } @SubscribeEvent - fun onSackChange(event: SackChangeEvent) { - if (!isEnabled()) return - if (!SlayerAPI.isInCorrectArea) return - if (!SlayerAPI.hasActiveSlayerQuest()) return - - for (sackChange in event.sackChanges) { - val change = sackChange.delta - if (change > 0) { - val internalName = sackChange.internalName - addItem(internalName, change) - } - } - } - - @SubscribeEvent - fun onItemAdd(event: ItemAddInInventoryEvent) { + fun onItemAdd(event: ItemAddEvent) { if (!isEnabled()) return if (!SlayerAPI.isInCorrectArea) return if (!SlayerAPI.hasActiveSlayerQuest()) return val internalName = event.internalName - if (internalName == ARCHFIEND_DICE || internalName == HIGH_CLASS_ARCHFIEND_DICE) { - if (lastDiceRoll.passedSince() < 500.milliseconds) { - return - } - } - - addItem(internalName, event.amount) - } - - private var lastDiceRoll = SimpleTimeMark.farPast() - - @SubscribeEvent - fun onChat(event: LorenzChatEvent) { - if (diceRollChatPattern.matches(event.message)) { - lastDiceRoll = SimpleTimeMark.now() - } - } + val amount = event.amount - private fun addItem(internalName: NEUInternalName, amount: Int) { if (!isAllowedItem(internalName)) { LorenzUtils.debug("Ignored non-slayer item pickup: '$internalName' '$itemLogCategory'") return @@ -239,82 +168,19 @@ object SlayerProfitTracker { val tracker = getTracker() ?: return@buildList addAsSingletonList("§e§l$itemLogCategory Profit Tracker") - var profit = 0.0 - val map = mutableMapOf<Renderable, Long>() - for ((internalName, itemProfit) in itemLog.items) { - val amount = itemProfit.totalAmount - - val price = (getPrice(internalName) * amount).toLong() - - val cleanName = SlayerAPI.getNameWithEnchantmentFor(internalName) - var name = cleanName - val priceFormat = NumberUtil.format(price) - val hidden = itemProfit.hidden - if (hidden) { - while (name.startsWith("§f")) { - name = name.substring(2) - } - name = StringUtils.addFormat(name, "§m") - } - val text = " §7${amount.addSeparators()}x $name§7: §6$priceFormat" - - val timesDropped = itemProfit.timesDropped - val percentage = timesDropped.toDouble() / itemLog.slayerCompletedCount - val perBoss = LorenzUtils.formatPercentage(percentage.coerceAtMost(1.0)) - - val renderable = if (tracker.isInventoryOpen()) Renderable.clickAndHover( - text, listOf( - "§7Dropped §e${timesDropped.addSeparators()} §7times.", - "§7Your drop rate: §c$perBoss", - "", - "§eClick to " + (if (hidden) "show" else "hide") + "!", - "§eControl + Click to remove this item!", - ) - ) { - if (System.currentTimeMillis() > lastClickDelay + 150) { - - if (KeyboardManager.isControlKeyDown()) { - itemLog.items.remove(internalName) - LorenzUtils.chat("Removed $cleanName §efrom slayer profit display.") - lastClickDelay = System.currentTimeMillis() + 500 - } else { - itemProfit.hidden = !hidden - lastClickDelay = System.currentTimeMillis() - } - tracker.update() - } - } else Renderable.string(text) - if (tracker.isInventoryOpen() || !hidden) { - map[renderable] = price - } - profit += price - } - val mobKillCoins = itemLog.mobKillCoins - if (mobKillCoins != 0L) { - val mobKillCoinsFormat = NumberUtil.format(mobKillCoins) - map[Renderable.hoverTips( - " §7Mob kill coins: §6$mobKillCoinsFormat", - listOf( - "§7Killing mobs gives you coins (more with scavenger)", - "§7You got §e$mobKillCoinsFormat §7coins in total this way" - ) - )] = mobKillCoins - profit += mobKillCoins - } + var profit = tracker.drawItems(itemLog, { true }, this) val slayerSpawnCost = itemLog.slayerSpawnCost if (slayerSpawnCost != 0L) { val mobKillCoinsFormat = NumberUtil.format(slayerSpawnCost) - map[Renderable.hoverTips( - " §7Slayer Spawn Costs: §c$mobKillCoinsFormat", - listOf("§7You paid §c$mobKillCoinsFormat §7in total", "§7for starting the slayer quests.") - )] = slayerSpawnCost + addAsSingletonList( + Renderable.hoverTips( + " §7Slayer Spawn Costs: §c$mobKillCoinsFormat", + listOf("§7You paid §c$mobKillCoinsFormat §7in total", "§7for starting the slayer quests.") + ) + ) profit += slayerSpawnCost } - for (text in map.sortedDesc().keys) { - addAsSingletonList(text) - } - val slayerCompletedCount = itemLog.slayerCompletedCount addAsSingletonList( Renderable.hoverTips( @@ -329,27 +195,21 @@ object SlayerProfitTracker { val profitPerBoss = profit / itemLog.slayerCompletedCount val profitPerBossFormat = NumberUtil.format(profitPerBoss) - val text = "§eTotal Profit: $profitPrefix$profitFormat" + val text = "§eTotal Profit: $profitPrefix$profitFormat coins" addAsSingletonList(Renderable.hoverTips(text, listOf("§7Profit per boss: $profitPrefix$profitPerBossFormat"))) - if (tracker.isInventoryOpen()) { - addSelector<PriceSource>( - "", - getName = { type -> type.displayName }, - isCurrent = { it.ordinal == config.priceFrom }, - onChange = { - config.priceFrom = it.ordinal - tracker.update() - } - ) - } + tracker.addPriceFromButton(this) } - private fun getPrice(internalName: NEUInternalName) = when (config.priceFrom) { - 0 -> internalName.getBazaarData()?.sellPrice ?: internalName.getPriceOrNull() ?: 0.0 - 1 -> internalName.getBazaarData()?.buyPrice ?: internalName.getPriceOrNull() ?: 0.0 + val coinFormat: (ItemTrackerData.TrackedItem) -> Pair<String, List<String>> = { item -> + val mobKillCoinsFormat = NumberUtil.format(item.totalAmount) + val text = " §6Mob kill coins§7: §6$mobKillCoinsFormat" + val lore = listOf( + "§7Killing mobs gives you coins (more with scavenger)", + "§7You got §e$mobKillCoinsFormat §7coins in total this way" + ) - else -> internalName.getNpcPriceOrNull() ?: 0.0 + text to lore } @SubscribeEvent @@ -360,6 +220,29 @@ object SlayerProfitTracker { getTracker()?.renderDisplay(config.pos) } + @SubscribeEvent + fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { + event.move(10, "#profile.slayerProfitData", "#profile.slayerProfitData") { old -> + for (data in old.asJsonObject.entrySet().map { it.value.asJsonObject }) { + val items = data.get("items").asJsonObject + for (item in items.entrySet().map { it.value.asJsonObject }) { + val oldValue = item.get("timesDropped") + item.add("timesGained", oldValue) + } + + val coinAmount = data.get("mobKillCoins") + val coins = JsonObject() + coins.add("internalName", JsonPrimitive("SKYBLOCK_COIN")) + coins.add("timesDropped", JsonPrimitive(1)) + coins.add("totalAmount", coinAmount) + items.add("SKYBLOCK_COIN", coins) + } + + old + } + + } + fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled fun clearProfitCommand(args: Array<String>) { diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerQuestWarning.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerQuestWarning.kt index 728896e22..52eb9f806 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerQuestWarning.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerQuestWarning.kt @@ -9,7 +9,7 @@ import at.hannibal2.skyhanni.events.LorenzTickEvent import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent import at.hannibal2.skyhanni.utils.LocationUtils.distanceToPlayer import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.StringUtils.matchRegex +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.StringUtils.removeColor import at.hannibal2.skyhanni.utils.getLorenzVec import net.minecraft.entity.EntityLivingBase @@ -18,6 +18,7 @@ import kotlin.time.Duration.Companion.seconds class SlayerQuestWarning { private val config get() = SkyHanniMod.feature.slayer + private val talkToMaddoxPattern = " {3}§r§5§l» §r§7Talk to Maddox to claim your (.+) Slayer XP!".toPattern() private var needSlayerQuest = false private var lastWarning = 0L private var currentReason = "" @@ -43,7 +44,7 @@ class SlayerQuestWarning { } //no auto slayer - if (message.matchRegex(" §r§5§l» §r§7Talk to Maddox to claim your (.+) Slayer XP!")) { + talkToMaddoxPattern.matchMatcher(message) { needNewQuest("You have no Auto-Slayer active!") } if (message == " §r§a§lSLAYER QUEST COMPLETE!") { diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerRngMeterDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerRngMeterDisplay.kt index b26fd4c09..239935368 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerRngMeterDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerRngMeterDisplay.kt @@ -28,7 +28,7 @@ class SlayerRngMeterDisplay { private val config get() = SkyHanniMod.feature.slayer.rngMeterDisplay private var display = "" private val inventoryNamePattern = "(?<name>.*) RNG Meter".toPattern() - private val updatePattern = " §dRNG Meter §f- §d(?<exp>.*) Stored XP".toPattern() + private val updatePattern = " {3}§dRNG Meter §f- §d(?<exp>.*) Stored XP".toPattern() private val changedItemPattern = "§aYou set your §r.* RNG Meter §r§ato drop §r.*§a!".toPattern() private var lastItemDroppedTime = 0L 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 59ca5b075..e1f837a7b 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/slayer/VampireSlayerFeatures.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/VampireSlayerFeatures.kt @@ -12,6 +12,7 @@ import at.hannibal2.skyhanni.events.withAlpha import at.hannibal2.skyhanni.features.rift.RiftAPI import at.hannibal2.skyhanni.mixins.hooks.RenderLivingEntityHelper import at.hannibal2.skyhanni.test.GriffinUtils.drawWaypointFilled +import at.hannibal2.skyhanni.utils.DelayedRun import at.hannibal2.skyhanni.utils.EntityUtils import at.hannibal2.skyhanni.utils.EntityUtils.canBeSeen import at.hannibal2.skyhanni.utils.EntityUtils.getAllNameTagsInRadiusWith @@ -23,7 +24,6 @@ import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.baseMaxHealth import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy import at.hannibal2.skyhanni.utils.LorenzUtils.toChromaColor -import at.hannibal2.skyhanni.utils.MinecraftDispatcher import at.hannibal2.skyhanni.utils.RenderUtils.draw3DLine import at.hannibal2.skyhanni.utils.RenderUtils.drawColor import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText @@ -36,7 +36,6 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import net.minecraft.client.Minecraft import net.minecraft.client.entity.EntityOtherPlayerMP import net.minecraft.client.renderer.GlStateManager @@ -136,21 +135,18 @@ object VampireSlayerFeatures { else taggedEntityList.contains(this.entityId) && configOtherBoss.twinClawsSound if (shouldSendTitle || shouldSendSound) { - SkyHanniMod.coroutineScope.launch { - delay(config.twinclawsDelay.milliseconds) - withContext(MinecraftDispatcher) { - if (nextClawSend < System.currentTimeMillis()) { - if (shouldSendSound) - playTwinclawsSound() - if (shouldSendTitle) { - LorenzUtils.sendTitle( - "§6§lTWINCLAWS", - (1750 - config.twinclawsDelay).milliseconds, - 2.6 - ) - } - nextClawSend = System.currentTimeMillis() + 5_000 + DelayedRun.runDelayed(config.twinclawsDelay.milliseconds) { + if (nextClawSend < System.currentTimeMillis()) { + if (shouldSendSound) + playTwinclawsSound() + if (shouldSendTitle) { + LorenzUtils.sendTitle( + "§6§lTWINCLAWS", + (1750 - config.twinclawsDelay).milliseconds, + 2.6 + ) } + nextClawSend = System.currentTimeMillis() + 5_000 } } } @@ -295,7 +291,7 @@ object VampireSlayerFeatures { if (distance <= 15) { event.draw3DLine( event.exactPlayerEyeLocation(), - vec.add(0.0, 1.54, 0.0), + vec.add(y = 1.54), config.lineColor.toChromaColor(), config.lineWidth, true @@ -323,7 +319,7 @@ object VampireSlayerFeatures { (if (isIchor) configBloodIcor.linesColor else configKillerSpring.linesColor).toChromaColor() val text = if (isIchor) "§4Ichor" else "§4Spring" event.drawColor( - stand.position.toLorenzVec().add(0.0, 2.0, 0.0), + stand.position.toLorenzVec().add(y = 2.0), LorenzColor.DARK_RED, alpha = 1f ) @@ -336,8 +332,8 @@ object VampireSlayerFeatures { for ((player, stand2) in standList) { if ((configBloodIcor.showLines && isIchor) || (configKillerSpring.showLines && isSpring)) event.draw3DLine( - event.exactLocation(player).add(0.0, 1.5, 0.0), - event.exactLocation(stand2).add(0.0, 1.5, 0.0), + event.exactLocation(player).add(y = 1.5), + event.exactLocation(stand2).add(y = 1.5), // stand2.position.toLorenzVec().add(0.0, 1.5, 0.0), linesColorStart, 3, @@ -347,7 +343,7 @@ object VampireSlayerFeatures { } if (configBloodIcor.renderBeam && isIchor && stand.isEntityAlive) { event.drawWaypointFilled( - event.exactLocation(stand).add(0, -2, 0), + event.exactLocation(stand).add(0, y = -2, 0), configBloodIcor.color.toChromaColor(), beacon = true ) diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/blaze/BlazeSlayerDaggerHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/blaze/BlazeSlayerDaggerHelper.kt index 0e9b9f8ae..260d7d4d6 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/slayer/blaze/BlazeSlayerDaggerHelper.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/blaze/BlazeSlayerDaggerHelper.kt @@ -14,7 +14,7 @@ import at.hannibal2.skyhanni.utils.ItemUtils.name import at.hannibal2.skyhanni.utils.LocationUtils import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.RenderUtils.renderString -import at.hannibal2.skyhanni.utils.StringUtils.matchRegex +import at.hannibal2.skyhanni.utils.StringUtils.matches import at.hannibal2.skyhanni.utils.getLorenzVec import net.minecraft.client.Minecraft import net.minecraft.item.ItemStack @@ -22,6 +22,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class BlazeSlayerDaggerHelper { private val config get() = SkyHanniMod.feature.slayer.blazes.hellion + private val attunementPattern = "§cStrike using the §r(.+) §r§cattunement on your dagger!".toPattern() private var clientSideClicked = false private var textTop = "" @@ -34,12 +35,10 @@ class BlazeSlayerDaggerHelper { @SubscribeEvent fun onChatMessage(event: LorenzChatEvent) { if (!LorenzUtils.inSkyBlock) return - if (!SkyHanniMod.feature.slayer.blazes.hellion.hideDaggerWarning) return + if (!config.hideDaggerWarning) return val message = event.message - if (message.matchRegex("§cStrike using the §r(.+) §r§cattunement on your dagger!") || - message == "§cYour hit was reduced by Hellion Shield!" - ) { + if (attunementPattern.matches(message) || message == "§cYour hit was reduced by Hellion Shield!") { event.blockedReason = "blaze_slayer_dagger" } } @@ -63,7 +62,7 @@ class BlazeSlayerDaggerHelper { checkActiveDagger() lastNearest = findNearest() - val first = Dagger.entries[SkyHanniMod.feature.slayer.blazes.hellion.firstDagger] + val first = Dagger.entries[config.firstDagger] val second = first.other() textTop = format(holding, true, first) + " " + format(holding, true, second) @@ -71,7 +70,7 @@ class BlazeSlayerDaggerHelper { } private fun findNearest(): HellionShield? { - if (!SkyHanniMod.feature.slayer.blazes.hellion.markRightHellionShield) return null + if (!config.markRightHellionShield) return null if (lastNearestCheck + 100 > System.currentTimeMillis()) return lastNearest lastNearestCheck = System.currentTimeMillis() diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/enderman/EndermanSlayerFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/enderman/EndermanSlayerFeatures.kt index 42c50f00a..cd0de443e 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/slayer/enderman/EndermanSlayerFeatures.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/enderman/EndermanSlayerFeatures.kt @@ -129,14 +129,14 @@ class EndermanSlayerFeatures { val durationFormat = duration.format(showMilliSeconds = true) event.drawColor(location, beaconConfig.beaconColor.toChromaColor(), alpha = 1f) event.drawWaypointFilled(location, beaconConfig.beaconColor.toChromaColor(), true, true) - event.drawDynamicText(location.add(0, 1, 0), "§4Beacon §b$durationFormat", 1.8) + event.drawDynamicText(location.add(y = 1), "§4Beacon §b$durationFormat", 1.8) } } for (beacon in flyingBeacons) { if (beacon.isDead) continue if (beaconConfig.highlightBeacon) { val beaconLocation = event.exactLocation(beacon) - event.drawDynamicText(beaconLocation.add(0, 1, 0), "§4Beacon", 1.8) + event.drawDynamicText(beaconLocation.add(y = 1), "§4Beacon", 1.8) } if (beaconConfig.showLine) { diff --git a/src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningMobManager.kt b/src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningMobManager.kt index 6b4757e21..e1755f988 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningMobManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningMobManager.kt @@ -35,9 +35,10 @@ class SummoningMobManager { private var searchArmorStands = false private var searchMobs = false + // TODO repo //§aYou have spawned your Tank Zombie §r§asoul! §r§d(249 Mana) - private val spawnPatter = "§aYou have spawned your (.+) §r§asoul! §r§d\\((\\d+) Mana\\)".toPattern() - private val despawnPatter = "§cYou have despawned your (monster|monsters)!".toPattern() + private val spawnPattern = "§aYou have spawned your (.+) §r§asoul! §r§d\\((\\d+) Mana\\)".toPattern() + private val despawnPattern = "§cYou have despawned your (monster|monsters)!".toPattern() //§a§ohannibal2's Tank Zombie§r §a160k§c❤ private val healthPattern = "§a§o(.+)'s (.+)§r §[ae]([\\dkm]+)§c❤".toPattern() @@ -50,7 +51,7 @@ class SummoningMobManager { if (!LorenzUtils.inSkyBlock) return val message = event.message - spawnPatter.matchMatcher(message) { + spawnPattern.matchMatcher(message) { if (config.summoningMobDisplay) { event.blockedReason = "summoning_soul" } @@ -59,7 +60,7 @@ class SummoningMobManager { searchMobs = true } - if (despawnPatter.matcher(message).matches() || message.startsWith("§c ☠ §r§7You ")) { + if (despawnPattern.matcher(message).matches() || message.startsWith("§c ☠ §r§7You ")) { despawned() if (config.summoningMobDisplay && !message.contains("☠")) { event.blockedReason = "summoning_soul" diff --git a/src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningSoulsName.kt b/src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningSoulsName.kt index 6d206bf17..98752b04a 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningSoulsName.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningSoulsName.kt @@ -78,7 +78,7 @@ class SummoningSoulsName { for ((entity, name) in souls) { val vec = entity.getLorenzVec() - event.drawString(vec.add(0.0, 2.5, 0.0), name) + event.drawString(vec.add(y = 2.5), name) } } diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/hooks/GuiIngameHook.kt b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/GuiIngameHook.kt index 7fb80d4e0..896313d12 100644 --- a/src/main/java/at/hannibal2/skyhanni/mixins/hooks/GuiIngameHook.kt +++ b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/GuiIngameHook.kt @@ -1,6 +1,10 @@ package at.hannibal2.skyhanni.mixins.hooks import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.features.garden.GardenAPI +import at.hannibal2.skyhanni.features.garden.GardenPlotAPI +import at.hannibal2.skyhanni.features.garden.GardenPlotAPI.isBarn +import at.hannibal2.skyhanni.features.garden.GardenPlotAPI.name import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import net.minecraft.client.gui.FontRenderer @@ -13,16 +17,39 @@ fun drawString( x: Int, y: Int, color: Int, -): Int { +) = replaceString(text)?.let { + instance.drawString(it, x, y, color) +} ?: 0 + +private fun replaceString(text: String): String? { if (SkyHanniMod.feature.misc.hideScoreboardNumbers && text.startsWith("§c") && text.length <= 4) { - return 0 + return null } if (SkyHanniMod.feature.misc.hidePiggyScoreboard) { piggyPattern.matchMatcher(text) { val coins = group("coins") - return instance.drawString("Purse: $coins", x, y, color) + return "Purse: $coins" + } + } + + if (SkyHanniMod.feature.garden.plotNameInScoreboard && GardenAPI.inGarden()) { + if (text.contains("⏣")) { + val plot = GardenPlotAPI.getCurrentPlot() + val hasPests = text.contains("ൠ") + val pestSuffix = if (hasPests) { + val pests = text.last().digitToInt() + val color = if (pests >= 4) "§c" else "§6" + " §7(${color}${pests}ൠ§7)" + } else "" + val name = plot?.let { + if (it.isBarn()) "§aThe Barn" else { + val namePrefix = if (hasPests) "" else "§aPlot §7- " + "$namePrefix§b" + it.name + } + } ?: "§aGarden §coutside" + return " §7⏣ $name$pestSuffix" } } - return instance.drawString(text, x, y, color) + return text } diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/hooks/NetworkManagerHook.kt b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/NetworkManagerHook.kt index ca4c2e42b..71f6aaba9 100644 --- a/src/main/java/at/hannibal2/skyhanni/mixins/hooks/NetworkManagerHook.kt +++ b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/NetworkManagerHook.kt @@ -5,5 +5,5 @@ import net.minecraft.network.Packet import org.spongepowered.asm.mixin.injection.callback.CallbackInfo fun onReceivePacket(packet: Packet<*>, ci: CallbackInfo) { - if (packet != null && PacketEvent.ReceiveEvent(packet).postAndCatch()) ci.cancel() -}
\ No newline at end of file + if (PacketEvent.ReceiveEvent(packet).postAndCatch()) ci.cancel() +} diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/UpdateDataWatcherEventPatch.java b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/UpdateDataWatcherEventPatch.java new file mode 100644 index 000000000..bcc30f42d --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/UpdateDataWatcherEventPatch.java @@ -0,0 +1,25 @@ +package at.hannibal2.skyhanni.mixins.transformers; + +import at.hannibal2.skyhanni.events.DataWatcherUpdatedEvent; +import net.minecraft.entity.DataWatcher; +import net.minecraft.entity.Entity; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; + +@Mixin(DataWatcher.class) +public class UpdateDataWatcherEventPatch { + @Shadow + @Final + private Entity owner; + + @Inject(method = "updateWatchedObjectsFromList", at = @At("TAIL")) + public void onWhatever(List<DataWatcher.WatchableObject> list, CallbackInfo ci) { + new DataWatcherUpdatedEvent(owner, list).postAndCatch(); + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/test/HighlightMissingRepoItems.kt b/src/main/java/at/hannibal2/skyhanni/test/HighlightMissingRepoItems.kt index 28e657c1e..2419d6161 100644 --- a/src/main/java/at/hannibal2/skyhanni/test/HighlightMissingRepoItems.kt +++ b/src/main/java/at/hannibal2/skyhanni/test/HighlightMissingRepoItems.kt @@ -10,7 +10,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.MultiFilter import at.hannibal2.skyhanni.utils.NEUItems import at.hannibal2.skyhanni.utils.RenderUtils.highlight -import at.hannibal2.skyhanni.utils.jsonobjects.MultiFilterJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.MultiFilterJson import net.minecraft.client.Minecraft import net.minecraft.client.gui.inventory.GuiChest import net.minecraft.client.gui.inventory.GuiInventory diff --git a/src/main/java/at/hannibal2/skyhanni/test/PacketTest.kt b/src/main/java/at/hannibal2/skyhanni/test/PacketTest.kt index 454ce6afa..8ae9f0c5e 100644 --- a/src/main/java/at/hannibal2/skyhanni/test/PacketTest.kt +++ b/src/main/java/at/hannibal2/skyhanni/test/PacketTest.kt @@ -64,10 +64,10 @@ class PacketTest { @SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true) fun onChatPacket(event: PacketEvent.ReceiveEvent) { + if (!enabled) return val packet = event.packet val packetName = packet.javaClass.simpleName - if (!enabled) return // Keep alive if (packetName == "S00PacketKeepAlive") return diff --git a/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt b/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt index 635ea3351..1a53e8283 100644 --- a/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt +++ b/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt @@ -250,6 +250,14 @@ class SkyHanniDebugsAndTests { LorenzUtils.chat("stopped ${modules.size} listener classes.") } + fun whereami() { + if (LorenzUtils.inSkyBlock) { + LorenzUtils.chat("§eYou are currently in ${LorenzUtils.skyBlockIsland}.") + return + } + LorenzUtils.chat("§eYou are not in Skyblock.") + } + fun copyLocation(args: Array<String>) { val location = LocationUtils.playerLocation() val x = LorenzUtils.formatDouble(location.x + 0.001).replace(",", ".") @@ -336,13 +344,13 @@ class SkyHanniDebugsAndTests { fun copyItemInternalName() { val hand = InventoryUtils.getItemInHand() if (hand == null) { - LorenzUtils.chat("§cNo item in hand!") + LorenzUtils.userError("No item in hand!") return } val internalName = hand.getInternalNameOrNull() if (internalName == null) { - LorenzUtils.chat("§cInternal name is null for item ${hand.name}") + LorenzUtils.error("§cInternal name is null for item ${hand.name}") return } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/BlockUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/BlockUtils.kt index 9bc353820..5b8c8a0c0 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/BlockUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/BlockUtils.kt @@ -48,9 +48,9 @@ object BlockUtils { return result?.blockPos?.toLorenzVec() } - fun getBlockLookingAt(duration: Double = 10.0) = rayTrace( + fun getBlockLookingAt(distance: Double = 10.0) = rayTrace( LocationUtils.playerEyeLocation(), Minecraft.getMinecraft().thePlayer.lookVec.toLorenzVec(), - duration + distance ) } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ConfigUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ConfigUtils.kt new file mode 100644 index 000000000..99ed4b231 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/ConfigUtils.kt @@ -0,0 +1,63 @@ +package at.hannibal2.skyhanni.utils + +import at.hannibal2.skyhanni.config.HasLegacyId +import com.google.gson.JsonArray +import com.google.gson.JsonElement +import com.google.gson.JsonPrimitive + +object ConfigUtils { + + /** + * Migrates an Int ArrayList to an Enum ArrayList. + * The new enum class should implement HasLegacyId and have a getter for LegacyId + * + * @param element The JsonElement to migrate + * @param enumClass The enum class to migrate to + * @return The migrated JsonElement + */ + fun <T> migrateIntArrayListToEnumArrayList(element: JsonElement, enumClass: Class<T>): JsonElement + where T : Enum<T>, T : HasLegacyId { + require(element is JsonArray) { "Expected a JsonArray but got ${element.javaClass.simpleName}" } + + // An array of enum constants that are to be migrated + val migratedArray = element.mapNotNull { jsonElement -> + val index = jsonElement.asInt + getEnumConstantFromLegacyId(index, enumClass)?.name + }.map { JsonPrimitive(it) } + + // Return a JsonArray of the migrated enum constants + return JsonArray().apply { + migratedArray.forEach { add(it) } + } + } + + /** + * Gets an enum constant from a legacy id + * @param legacyId The legacy id to get the enum constant from + * @param enumClass The enum class to get the enum constant from + * @return The enum constant, or null if not found + */ + private fun <T> getEnumConstantFromLegacyId( + legacyId: Int, + enumClass: Class<T> + ): T? where T : Enum<T>, T : HasLegacyId { + for (enumConstant in enumClass.getEnumConstants()) { + if (enumConstant.legacyId == legacyId) return enumConstant + } + return null + } + + /** + * Migrates an Int to an Enum Constant. + * The new enum class should implement HasLegacyId and have a getter for LegacyId + * + * @param element The JsonElement to migrate + * @param enumClass The enum class to migrate to + * @return The migrated JsonElement + */ + fun <T> migrateIntToEnum(element: JsonElement, enumClass: Class<T>): JsonElement + where T : Enum<T>, T : HasLegacyId { + require(element is JsonPrimitive) { "Expected a JsonPrimitive but got ${element.javaClass.simpleName}" } + return JsonPrimitive(getEnumConstantFromLegacyId(element.asInt, enumClass)?.name) + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/DelayedRun.kt b/src/main/java/at/hannibal2/skyhanni/utils/DelayedRun.kt new file mode 100644 index 000000000..f90237588 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/DelayedRun.kt @@ -0,0 +1,34 @@ +package at.hannibal2.skyhanni.utils + +import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy +import kotlin.time.Duration + +// TODO find better sync bug fix than creating a new map for each use +object DelayedRun { + var map = mapOf<() -> Any, SimpleTimeMark>() + + fun runDelayed(duration: Duration, run: () -> Unit) { + map = map.editCopy { + this[run] = SimpleTimeMark.now() + duration + } + } + + fun runNextTick(run: () -> Unit) { + map = map.editCopy { + this[run] = SimpleTimeMark.now() + } + } + + fun checkRuns() { + if (map.isEmpty()) return + map = map.editCopy { + entries.removeIf { (runnable, time) -> + val inPast = time.isInPast() + if (inPast) { + runnable() + } + inPast + } + } + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt b/src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt index 28fc08807..ca4827291 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt @@ -77,9 +77,7 @@ object EntityOutlineRenderer { * * @param camera the current camera * @param partialTicks the progress to the next tick - * @param x the camera x position - * @param y the camera y position - * @param z the camera z position + * @param vector the camera position as Vector */ @JvmStatic fun renderEntityOutlines(camera: ICamera, partialTicks: Float, vector: LorenzVec): Boolean { @@ -284,9 +282,7 @@ object EntityOutlineRenderer { * * @param camera the current camera * @param entity the entity to render - * @param x the camera x position - * @param y the camera y position - * @param z the camera z position + * @param vector the camera position as Vector * @return whether the entity should be rendered */ private fun shouldRender(camera: ICamera, entity: Entity, vector: LorenzVec): Boolean = diff --git a/src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt index 7fe6e8efb..427d5e48b 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt @@ -34,7 +34,7 @@ object EntityUtils { inaccuracy: Double = 1.6, debugWrongEntity: Boolean = false, ): List<EntityArmorStand> { - val center = getLorenzVec().add(0, y, 0) + val center = getLorenzVec().add(y = y) val a = center.add(-inaccuracy, -inaccuracy - 3, -inaccuracy).toBlocPos() val b = center.add(inaccuracy, inaccuracy + 3, inaccuracy).toBlocPos() val alignedBB = AxisAlignedBB(a, b) @@ -58,7 +58,7 @@ object EntityUtils { contains: String, radius: Double = 3.0, ): List<EntityArmorStand> { - val center = getLorenzVec().add(0, 3, 0) + val center = getLorenzVec().add(y = 3) val a = center.add(-radius, -radius - 3, -radius).toBlocPos() val b = center.add(radius, radius + 3, radius).toBlocPos() val alignedBB = AxisAlignedBB(a, b) @@ -77,7 +77,7 @@ object EntityUtils { inaccuracy: Double = 1.6, debugWrongEntity: Boolean = false, ): EntityArmorStand? { - val center = getLorenzVec().add(0, y, 0) + val center = getLorenzVec().add(y = y) val a = center.add(-inaccuracy, -inaccuracy - 3, -inaccuracy).toBlocPos() val b = center.add(inaccuracy, inaccuracy + 3, inaccuracy).toBlocPos() val alignedBB = AxisAlignedBB(a, b) diff --git a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt index be29569a5..9ce83c23a 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt @@ -4,6 +4,8 @@ import at.hannibal2.skyhanni.test.command.ErrorManager import io.github.moulberry.notenoughupdates.NotEnoughUpdates import net.minecraft.client.Minecraft import net.minecraft.client.gui.inventory.GuiChest +import net.minecraft.client.gui.inventory.GuiContainer +import net.minecraft.entity.player.InventoryPlayer import net.minecraft.inventory.ContainerChest import net.minecraft.inventory.Slot import net.minecraft.item.ItemStack @@ -45,7 +47,7 @@ object InventoryUtils { fun inStorage() = openInventoryName().let { (it.contains("Storage") && !it.contains("Rift Storage")) - || it.contains("Ender Chest") || it.contains("Backpack") + || it.contains("Ender Chest") || it.contains("Backpack") } fun getItemInHand(): ItemStack? = Minecraft.getMinecraft().thePlayer.heldItem @@ -66,4 +68,9 @@ object InventoryUtils { false } } + + fun isSlotInPlayerInventory(itemStack: ItemStack): Boolean { + val screen = Minecraft.getMinecraft().currentScreen as? GuiContainer ?: return false + return screen.slotUnderMouse.inventory is InventoryPlayer && screen.slotUnderMouse.stack == itemStack + } } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt index a1b7ed09f..420f3decb 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt @@ -6,8 +6,9 @@ import at.hannibal2.skyhanni.utils.NEUItems.getItemStack import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber import at.hannibal2.skyhanni.utils.SimpleTimeMark.Companion.asTimeMark import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.cachedData +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getEnchantments import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.isRecombobulated -import at.hannibal2.skyhanni.utils.StringUtils.matchRegex +import at.hannibal2.skyhanni.utils.StringUtils.matches import at.hannibal2.skyhanni.utils.StringUtils.removeColor import com.google.gson.GsonBuilder import com.google.gson.JsonObject @@ -24,6 +25,20 @@ import kotlin.time.Duration.Companion.seconds object ItemUtils { + // TODO USE SH-REPO + private val patternInFront = "(?: *§8(\\+§\\w)?(?<amount>[\\d.km,]+)(x )?)?(?<name>.*)".toPattern() + private val patternBehind = "(?<name>(?:['\\w-]+ ?)+)(?:§8x(?<amount>[\\d,]+))?".toPattern() + private val petLevelPattern = "\\[Lvl (.*)] (.*)".toPattern() + + private val ignoredPetStrings = listOf( + "Archer", + "Berserk", + "Mage", + "Tank", + "Healer", + "➡", + ) + fun ItemStack.cleanName() = this.displayName.removeColor() fun isSack(stack: ItemStack) = stack.getInternalName().endsWith("_SACK") && stack.cleanName().endsWith(" Sack") @@ -50,14 +65,7 @@ object ItemUtils { fun isRecombobulated(stack: ItemStack) = stack.isRecombobulated() - fun isPet(name: String): Boolean = name.matchRegex("\\[Lvl (.*)] (.*)") && !listOf( - "Archer", - "Berserk", - "Mage", - "Tank", - "Healer", - "➡", - ).any { name.contains(it) } + fun isPet(name: String): Boolean = petLevelPattern.matches(name) && !ignoredPetStrings.any { name.contains(it) } fun maxPetLevel(name: String) = if (name.contains("Golden Dragon")) 200 else 100 @@ -133,8 +141,12 @@ object ItemUtils { fun ItemStack.isVanilla() = NEUItems.isVanillaItem(this) + // Checks for the enchantment glint as part of the minecraft enchantments fun ItemStack.isEnchanted() = isItemEnchanted + // Checks for hypixel enchantments in the attributes + fun ItemStack.hasEnchantments() = getEnchantments()?.isNotEmpty() ?: false + fun ItemStack.getSkullTexture(): String? { if (item != Items.skull) return null if (tagCompound == null) return null @@ -248,10 +260,6 @@ object ItemUtils { fun isSkyBlockMenuItem(stack: ItemStack?): Boolean = stack?.getInternalName()?.equals("SKYBLOCK_MENU") ?: false - // TODO USE SH-REPO - private val patternInFront = "(?: *§8(\\+§[\\d\\w])?(?<amount>[\\d\\.km,]+)(x )?)?(?<name>.*)".toPattern() - private val patternBehind = "(?<name>(?:['\\w-]+ ?)+)(?:§8x(?<amount>[\\d,]+))?".toPattern() - private val itemAmountCache = mutableMapOf<String, Pair<String, Int>>() fun readItemAmount(originalInput: String): Pair<String, Int>? { diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LocationUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/LocationUtils.kt index e6929d737..654974d5c 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LocationUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LocationUtils.kt @@ -24,12 +24,12 @@ object LocationUtils { fun playerEyeLocation(): LorenzVec { val player = Minecraft.getMinecraft().thePlayer val vec = player.getLorenzVec() - return vec.add(0.0, 0.0 + player.getEyeHeight(), 0.0) + return vec.add(y = player.getEyeHeight().toDouble()) } - fun AxisAlignedBB.isVecInside(vec: LorenzVec) = isVecInside(vec.toVec3()) + fun AxisAlignedBB.isInside(vec: LorenzVec) = isVecInside(vec.toVec3()) - fun AxisAlignedBB.isPlayerInside() = isVecInside(playerLocation()) + fun AxisAlignedBB.isPlayerInside() = isInside(playerLocation()) fun LorenzVec.canBeSeen(radius: Double = 150.0): Boolean { val a = playerEyeLocation() diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt index 90970a315..b468bc33d 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt @@ -23,7 +23,9 @@ import net.minecraft.entity.EntityLivingBase import net.minecraft.entity.SharedMonsterAttributes import net.minecraft.event.ClickEvent import net.minecraft.event.HoverEvent +import net.minecraft.launchwrapper.Launch import net.minecraft.util.ChatComponentText +import net.minecraftforge.fml.common.FMLCommonHandler import java.awt.Color import java.lang.reflect.Field import java.lang.reflect.Modifier @@ -33,6 +35,7 @@ import java.text.SimpleDateFormat import java.util.Collections import java.util.Timer import java.util.TimerTask +import java.util.regex.Matcher import kotlin.properties.ReadWriteProperty import kotlin.reflect.KMutableProperty1 import kotlin.reflect.KProperty @@ -359,7 +362,7 @@ object LorenzUtils { } fun sendMessageToServer(message: String) { - if (System.currentTimeMillis() > lastMessageSent + 2_000) { + if (System.currentTimeMillis() > lastMessageSent + 1_000) { lastMessageSent = System.currentTimeMillis() val thePlayer = Minecraft.getMinecraft().thePlayer thePlayer.sendChatMessage(message) @@ -489,7 +492,7 @@ object LorenzUtils { } } - fun List<String>.nextAfter(after: String, skip: Int = 1) = nextAfter({ it == after}, skip) + fun List<String>.nextAfter(after: String, skip: Int = 1) = nextAfter({ it == after }, skip) fun List<String>.nextAfter(after: (String) -> Boolean, skip: Int = 1): String? { var missing = -1 @@ -625,4 +628,22 @@ object LorenzUtils { inline fun <reified T : Enum<T>> enumValueOf(name: String) = enumValueOfOrNull<T>(name) ?: kotlin.error("Unknown enum constant for ${enumValues<T>().first().name.javaClass.simpleName}: '$name'") + + fun isInDevEnviromen() = Launch.blackboard.get("fml.deobfuscatedEnvironment") as Boolean + + fun shutdownMinecraft(reason: String? = null) { + System.err.println("SkyHanni-${SkyHanniMod.version} forced the game to shutdown.") + reason?.let { + System.err.println("Reason: $it") + } + FMLCommonHandler.instance().handleExit(-1) + } + + /** + * Get the group, otherwise, return null + * @param groupName The group name in the pattern + */ + fun Matcher.groupOrNull(groupName: String): String? { + return runCatching { this.group(groupName) }.getOrNull() + } } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt index fd38fd441..b3cd44032 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt @@ -50,7 +50,7 @@ data class LorenzVec( fun add(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0): LorenzVec = LorenzVec(this.x + x, this.y + y, this.z + z) - fun add(x: Int, y: Int, z: Int): LorenzVec = LorenzVec(this.x + x, this.y + y, this.z + z) + fun add(x: Int = 0, y: Int = 0, z: Int = 0): LorenzVec = LorenzVec(this.x + x, this.y + y, this.z + z) override fun toString() = "LorenzVec{x=$x, y=$y, z=$z}" @@ -132,6 +132,16 @@ data class LorenzVec( fun axisAlignedTo(other: LorenzVec) = AxisAlignedBB(x, y, z, other.x, other.y, other.z) + fun interpolate(other: LorenzVec, factor: Double): LorenzVec { + require(factor in 0.0..1.0) { "Percentage must be between 0 and 1: $factor" } + + val x = (1 - factor) * this.x + factor * other.x + val y = (1 - factor) * this.y + factor * other.y + val z = (1 - factor) * this.z + factor * other.z + + return LorenzVec(x, y, z) + } + companion object { fun getFromYawPitch(yaw: Double, pitch: Double): LorenzVec { val yaw: Double = (yaw + 90) * Math.PI / 180 @@ -149,7 +159,7 @@ data class LorenzVec( return LorenzVec(x, y, z) } - fun getBlockBelowPlayer() = LocationUtils.playerLocation().roundLocationToBlock().add(0.0, -1.0, 0.0) + fun getBlockBelowPlayer() = LocationUtils.playerLocation().roundLocationToBlock().add(y = -1.0) } } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/MultiFilter.kt b/src/main/java/at/hannibal2/skyhanni/utils/MultiFilter.kt index ab9817ef4..bc3b1789e 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/MultiFilter.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/MultiFilter.kt @@ -1,7 +1,7 @@ package at.hannibal2.skyhanni.utils import at.hannibal2.skyhanni.utils.StringUtils.trimWhiteSpace -import at.hannibal2.skyhanni.utils.jsonobjects.MultiFilterJson +import at.hannibal2.skyhanni.data.jsonobjects.repo.MultiFilterJson class MultiFilter { @@ -56,4 +56,4 @@ class MultiFilter { fun count(): Int { return equals.size + startsWith.size + endsWith.size + contains.size + containsWord.size } -}
\ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt index 007d9f1d5..7965a2ded 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt @@ -17,6 +17,7 @@ import io.github.moulberry.notenoughupdates.NotEnoughUpdates import io.github.moulberry.notenoughupdates.overlays.AuctionSearchOverlay import io.github.moulberry.notenoughupdates.overlays.BazaarSearchOverlay import io.github.moulberry.notenoughupdates.recipes.CraftingRecipe +import io.github.moulberry.notenoughupdates.recipes.Ingredient import io.github.moulberry.notenoughupdates.recipes.NeuRecipe import io.github.moulberry.notenoughupdates.util.ItemResolutionQuery import io.github.moulberry.notenoughupdates.util.Utils @@ -34,6 +35,7 @@ object NEUItems { private val itemNameCache = mutableMapOf<String, NEUInternalName>() // item name -> internal name private val multiplierCache = mutableMapOf<String, Pair<String, Int>>() private val recipesCache = mutableMapOf<String, Set<NeuRecipe>>() + private val ingredientsCache = mutableMapOf<NeuRecipe, Set<Ingredient>>() private val enchantmentNamePattern = Pattern.compile("^(?<format>(?:§.)+)(?<name>[^§]+) (?<level>[IVXL]+)$") var allItemsCache = mapOf<String, NEUInternalName>() // item name -> internal name var allInternalNames = mutableListOf<NEUInternalName>() @@ -244,7 +246,7 @@ object NEUItems { if (recipe !is CraftingRecipe) continue val map = mutableMapOf<String, Int>() - for (ingredient in recipe.ingredients) { + for (ingredient in recipe.getCachedIngredients()) { val count = ingredient.count.toInt() var internalItemId = ingredient.internalItemId // ignore cactus green @@ -297,6 +299,8 @@ object NEUItems { return recipes } + fun NeuRecipe.getCachedIngredients() = ingredientsCache.getOrPut(this) { ingredients } + fun neuHasFocus(): Boolean { if (AuctionSearchOverlay.shouldReplace()) return true if (BazaarSearchOverlay.shouldReplace()) return true diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt b/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt index 41e5f4923..31062b559 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt @@ -104,7 +104,7 @@ object NumberUtil { fun Number.addSeparators() = NumberFormat.getNumberInstance().format(this) - fun String.romanToDecimalIfNeeded() = toIntOrNull() ?: romanToDecimal() + fun String.romanToDecimalIfNecessary() = toIntOrNull() ?: romanToDecimal() /** * This code was converted to Kotlin and taken under CC BY-SA 3.0 license diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ParkourHelper.kt b/src/main/java/at/hannibal2/skyhanni/utils/ParkourHelper.kt index 68f7a0d49..e80aa7f62 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/ParkourHelper.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/ParkourHelper.kt @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.utils import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.data.jsonobjects.repo.ParkourJson.ShortCut import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.LocationUtils.distanceToPlayer @@ -11,7 +12,6 @@ import at.hannibal2.skyhanni.utils.RenderUtils.drawFilledBoundingBox_nea import at.hannibal2.skyhanni.utils.RenderUtils.drawString import at.hannibal2.skyhanni.utils.RenderUtils.expandBlock import at.hannibal2.skyhanni.utils.RenderUtils.outlineTopFace -import at.hannibal2.skyhanni.utils.jsonobjects.ParkourJson.ShortCut import net.minecraft.client.Minecraft import java.awt.Color import kotlin.time.Duration.Companion.seconds @@ -116,7 +116,7 @@ class ParkourHelper( if (outline) event.outlineTopFace(aabb, 2, Color.BLACK, true) } if (SkyHanniMod.feature.dev.waypoint.showPlatformNumber && !isMovingPlatform) { - event.drawString(location.offsetCenter().add(0, 1, 0), "§a§l$index", seeThroughBlocks = true) + event.drawString(location.offsetCenter().add(y = 1), "§a§l$index", seeThroughBlocks = true) } } } catch (e: Throwable) { diff --git a/src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt b/src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt index 3e30f300c..66629d11d 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt @@ -6,7 +6,7 @@ import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds @JvmInline -value class SimpleTimeMark(private val millis: Long) { +value class SimpleTimeMark(private val millis: Long) : Comparable<SimpleTimeMark> { operator fun minus(other: SimpleTimeMark) = (millis - other.millis).milliseconds @@ -24,6 +24,8 @@ value class SimpleTimeMark(private val millis: Long) { fun isFarPast() = millis == 0L + override fun compareTo(other: SimpleTimeMark): Int = millis.compareTo(other.millis) + override fun toString(): String { if (millis == 0L) return "The Far Past" return Instant.ofEpochMilli(millis).toString() @@ -31,6 +33,8 @@ value class SimpleTimeMark(private val millis: Long) { fun toMillis() = millis + fun toSkyBlockTime() = SkyBlockTime.fromInstant(Instant.ofEpochMilli(millis)) + companion object { fun now() = SimpleTimeMark(System.currentTimeMillis()) fun farPast() = SimpleTimeMark(0) diff --git a/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt index 9f65a71f1..9db592047 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt @@ -179,6 +179,10 @@ object SkyBlockItemModifierUtils { fun ItemStack.getLivingMetalProgress() = getAttributeInt("lm_evo") + fun ItemStack.getBottleOfJyrreSeconds() = getAttributeInt("bottle_of_jyrre_seconds") + + fun ItemStack.getEdition() = getAttributeInt("edition") + fun ItemStack.getEnchantments() = getExtraAttributes()?.takeIf { it.hasKey("enchantments") }?.run { val enchantments = this.getCompoundTag("enchantments") enchantments.keySet.associateWith { enchantments.getInteger(it) } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt index dd114d8fd..cb7a0fa23 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt @@ -1,5 +1,6 @@ package at.hannibal2.skyhanni.utils +import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.mixins.transformers.AccessorChatComponentText import at.hannibal2.skyhanni.utils.GuiRenderUtils.darkenColor import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators @@ -7,7 +8,6 @@ import net.minecraft.client.Minecraft import net.minecraft.client.gui.GuiUtilRenderComponents import net.minecraft.util.ChatComponentText import net.minecraft.util.IChatComponent -import org.intellij.lang.annotations.Language import java.util.Base64 import java.util.NavigableMap import java.util.UUID @@ -36,14 +36,18 @@ object StringUtils { return first + lowercase.substring(1) } - fun String.removeColor(): String { + private val formattingChars by lazy { "kmolnr".toCharArray() + "kmolnr".uppercase().toCharArray() } + + fun String.removeColor(keepFormatting: Boolean = false): String { val builder = StringBuilder(this.length) var counter = 0 while (counter < this.length) { if (this[counter] == '§') { - counter += 2 - continue + if (!keepFormatting || this[counter + 1] !in formattingChars) { + counter += 2 + continue + } } builder.append(this[counter]) counter++ @@ -73,17 +77,11 @@ object StringUtils { return toString().replace("-", "") } - @Deprecated("Do not create a regex pattern each time.", ReplaceWith("toPattern()")) - fun String.matchRegex(@Language("RegExp") regex: String): Boolean = regex.toRegex().matches(this) - - private fun String.removeAtBeginning(text: String): String = - if (this.startsWith(text)) substring(text.length) else this - // TODO find better name for this method inline fun <T> Pattern.matchMatcher(text: String, consumer: Matcher.() -> T) = matcher(text).let { if (it.matches()) consumer(it) else null } - fun String.cleanPlayerName(): String { + private fun String.internalCleanPlayerName(): String { val split = trim().split(" ") return if (split.size > 1) { split[1].removeColor() @@ -92,6 +90,16 @@ object StringUtils { } } + fun String.cleanPlayerName(displayName: Boolean = false): String { + return if (displayName) { + if (SkyHanniMod.feature.chat.playerMessage.playerRankHider) { + "§b" + internalCleanPlayerName() + } else this + } else { + internalCleanPlayerName() + } + } + inline fun <T> List<Pattern>.matchMatchers(text: String, consumer: Matcher.() -> T): T? { for (pattern in iterator()) { pattern.matchMatcher<T>(text) { @@ -132,7 +140,6 @@ object StringUtils { } } - fun String.removeWordsAtEnd(i: Int) = split(" ").dropLast(i).joinToString(" ") fun String.splitLines(width: Int): String { @@ -150,7 +157,10 @@ object StringUtils { } fun optionalPlural(number: Int, singular: String, plural: String) = - "${number.addSeparators()} " + if (number == 1) singular else plural + "${number.addSeparators()} " + canBePlural(number, singular, plural) + + fun canBePlural(number: Int, singular: String, plural: String) = + if (number == 1) singular else plural fun progressBar(percentage: Double, steps: Int = 24): Any { //'§5§o§2§l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §f§l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §r §e348,144.3§6/§e936k' @@ -233,6 +243,10 @@ object StringUtils { } if (username == "") return null + if (username.contains("[NPC]")) { + return null + } + if (username.contains(">")) { username = username.substring(username.indexOf('>') + 1).trim() } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/tracker/ItemTrackerData.kt b/src/main/java/at/hannibal2/skyhanni/utils/tracker/ItemTrackerData.kt new file mode 100644 index 000000000..7aa2cf4f9 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/tracker/ItemTrackerData.kt @@ -0,0 +1,53 @@ +package at.hannibal2.skyhanni.utils.tracker + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.utils.NEUInternalName +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import com.google.gson.annotations.Expose + +abstract class ItemTrackerData : TrackerData() { + + private val config get() = SkyHanniMod.feature.misc.tracker + + abstract fun resetItems() + + abstract fun getDescription(timesGained: Long): List<String> + + abstract fun getCoinName(item: TrackedItem): String + + abstract fun getCoinDescription(item: TrackedItem): List<String> + + open fun getCustomPricePer(internalName: NEUInternalName) = SkyHanniTracker.getPricePer(internalName) + + override fun reset() { + items.clear() + resetItems() + } + + fun additem(internalName: NEUInternalName, stackSize: Int) { + val item = items.getOrPut(internalName) { TrackedItem() } + + item.timesGained++ + item.totalAmount += stackSize + item.lastTimeUpdated = SimpleTimeMark.now() + } + + @Expose + var items: MutableMap<NEUInternalName, TrackedItem> = HashMap() + + class TrackedItem { + @Expose + var internalName: NEUInternalName? = null + + @Expose + var timesGained: Long = 0 + + @Expose + var totalAmount: Long = 0 + + @Expose + var hidden = false + + var lastTimeUpdated = SimpleTimeMark.farPast() + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniItemTracker.kt b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniItemTracker.kt new file mode 100644 index 000000000..7ea533166 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniItemTracker.kt @@ -0,0 +1,151 @@ +package at.hannibal2.skyhanni.utils.tracker + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.config.Storage +import at.hannibal2.skyhanni.test.PriceSource +import at.hannibal2.skyhanni.utils.ItemUtils.nameWithEnchantment +import at.hannibal2.skyhanni.utils.KeyboardManager +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList +import at.hannibal2.skyhanni.utils.LorenzUtils.addSelector +import at.hannibal2.skyhanni.utils.LorenzUtils.sortedDesc +import at.hannibal2.skyhanni.utils.NEUInternalName +import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName +import at.hannibal2.skyhanni.utils.NEUItems.getItemStack +import at.hannibal2.skyhanni.utils.NumberUtil +import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators +import at.hannibal2.skyhanni.utils.StringUtils.removeColor +import at.hannibal2.skyhanni.utils.renderables.Renderable +import kotlin.time.Duration.Companion.seconds + +class SkyHanniItemTracker<Data : ItemTrackerData>( + name: String, + createNewSession: () -> Data, + getStorage: (Storage.ProfileSpecific) -> Data, + drawDisplay: (Data) -> List<List<Any>>, +) : SkyHanniTracker<Data>(name, createNewSession, getStorage, drawDisplay) { + + companion object { + val SKYBLOCK_COIN by lazy { "SKYBLOCK_COIN".asInternalName() } + } + + private var lastClickDelay = 0L + + fun addCoins(coins: Int) { + addItem(SKYBLOCK_COIN, coins) + } + + fun addItem(internalName: NEUInternalName, stackSize: Int) { + modify { + it.additem(internalName, stackSize) + } + getSharedTracker()?.let { + val hidden = it.get(DisplayMode.TOTAL).items[internalName]!!.hidden + it.get(DisplayMode.SESSION).items[internalName]!!.hidden = hidden + } + + } + + fun addPriceFromButton(lists: MutableList<List<Any>>) { + if (isInventoryOpen()) { + lists.addSelector<PriceSource>( + "", + getName = { type -> type.displayName }, + isCurrent = { it.ordinal == config.priceFrom }, + onChange = { + config.priceFrom = it.ordinal + update() + } + ) + } + } + + fun drawItems( + data: Data, + filter: (NEUInternalName) -> Boolean, + lists: MutableList<List<Any>> + ): Double { + var profit = 0.0 + val items = mutableMapOf<Renderable, Long>() + for ((internalName, itemProfit) in data.items) { + if (!filter(internalName)) continue + + val amount = itemProfit.totalAmount + val pricePer = + if (internalName == SKYBLOCK_COIN) 1.0 else data.getCustomPricePer(internalName) + val price = (pricePer * amount).toLong() + val displayAmount = if (internalName == SKYBLOCK_COIN) itemProfit.timesGained else amount + + val cleanName = if (internalName == SKYBLOCK_COIN) { + data.getCoinName(itemProfit) + } else { + internalName.getItemStack().nameWithEnchantment ?: error("no name for $internalName") + } + + val priceFormat = NumberUtil.format(price) + val hidden = itemProfit.hidden + val newDrop = itemProfit.lastTimeUpdated.passedSince() < 10.seconds && config.showRecentDrops + val numberColor = if (newDrop) "§a§l" else "§7" + + var displayName = if (hidden) { + "§8§m" + cleanName.removeColor(keepFormatting = true).replace("§r", "") + } else cleanName + displayName = " $numberColor${displayAmount.addSeparators()}x $displayName§7: §6$priceFormat" + + val lore = buildLore(data, itemProfit, hidden, newDrop, internalName) + + val renderable = if (isInventoryOpen()) Renderable.clickAndHover(displayName, lore) { + if (System.currentTimeMillis() > lastClickDelay + 150) { + if (KeyboardManager.isControlKeyDown()) { + data.items.remove(internalName) + LorenzUtils.chat("Removed $cleanName §efrom Fishing Frofit Tracker.") + lastClickDelay = System.currentTimeMillis() + 500 + } else { + modify { + it.items[internalName]?.hidden = !hidden + } + lastClickDelay = System.currentTimeMillis() + } + update() + } + } else Renderable.string(displayName) + if (isInventoryOpen() || !hidden) { + items[renderable] = price + } + if (!hidden || !config.excludeHiddenItemsInPrice) { + profit += price + } + } + + for (text in items.sortedDesc().keys) { + lists.addAsSingletonList(text) + } + return profit + } + + private fun buildLore( + data: Data, + item: ItemTrackerData.TrackedItem, + hidden: Boolean, + newDrop: Boolean, + internalName: NEUInternalName + ) = buildList { + if (internalName == SKYBLOCK_COIN) { + addAll(data.getCoinDescription(item)) + } else { + addAll(data.getDescription(item.timesGained)) + } + add("") + if (newDrop) { + add("§aYou caught this item recently.") + add("") + } + add("§eClick to " + (if (hidden) "show" else "hide") + "!") + add("§eControl + Click to remove this item!") + if (SkyHanniMod.feature.dev.debug.enabled) { + add("") + add("§7${internalName}") + } + } + +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt index f882a268e..bc2db88e1 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt @@ -1,10 +1,16 @@ package at.hannibal2.skyhanni.utils.tracker +import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.Storage import at.hannibal2.skyhanni.config.core.config.Position import at.hannibal2.skyhanni.data.ProfileStorageData +import at.hannibal2.skyhanni.features.bazaar.BazaarApi.Companion.getBazaarData +import at.hannibal2.skyhanni.features.misc.items.EstimatedItemValue import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList +import at.hannibal2.skyhanni.utils.NEUInternalName +import at.hannibal2.skyhanni.utils.NEUItems.getNpcPriceOrNull +import at.hannibal2.skyhanni.utils.NEUItems.getPriceOrNull import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems import at.hannibal2.skyhanni.utils.SimpleTimeMark import at.hannibal2.skyhanni.utils.renderables.Renderable @@ -12,19 +18,31 @@ import net.minecraft.client.Minecraft import net.minecraft.client.gui.inventory.GuiInventory import kotlin.time.Duration.Companion.seconds -class SkyHanniTracker<Data : TrackerData>( +open class SkyHanniTracker<Data : TrackerData>( private val name: String, private val createNewSession: () -> Data, private val getStorage: (Storage.ProfileSpecific) -> Data, private val drawDisplay: (Data) -> List<List<Any>>, ) { private var inventoryOpen = false - private var displayMode = DisplayMode.TOTAL + private var displayMode: DisplayMode? = null private val currentSessions = mutableMapOf<Storage.ProfileSpecific, Data>() private var display = emptyList<List<Any>>() private var sessionResetTime = SimpleTimeMark.farPast() private var dirty = false + companion object { + val config get() = SkyHanniMod.feature.misc.tracker + private val storedTrackers get() = SkyHanniMod.feature.storage.trackerDisplayModes + + fun getPricePer(name: NEUInternalName) = when (config.priceFrom) { + 0 -> name.getBazaarData()?.sellPrice ?: name.getPriceOrNull() ?: 0.0 + 1 -> name.getBazaarData()?.buyPrice ?: name.getPriceOrNull() ?: 0.0 + + else -> name.getNpcPriceOrNull() ?: 0.0 + } + } + fun isInventoryOpen() = inventoryOpen fun resetCommand(args: Array<String>, command: String) { @@ -47,6 +65,8 @@ class SkyHanniTracker<Data : TrackerData>( } fun renderDisplay(position: Position) { + if (config.hideInEstimatedItemValue && EstimatedItemValue.isCurrentlyShowing()) return + val currentlyOpen = Minecraft.getMinecraft().currentScreen is GuiInventory if (inventoryOpen != currentlyOpen) { inventoryOpen = currentlyOpen @@ -55,7 +75,7 @@ class SkyHanniTracker<Data : TrackerData>( if (dirty) { display = getSharedTracker()?.let { - buildFinalDisplay(drawDisplay(it.get(displayMode))) + buildFinalDisplay(drawDisplay(it.get(getDisplayMode()))) } ?: emptyList() dirty = false } @@ -72,7 +92,7 @@ class SkyHanniTracker<Data : TrackerData>( if (inventoryOpen) { it.add(1, buildDisplayModeView()) } - if (inventoryOpen && displayMode == DisplayMode.SESSION) { + if (inventoryOpen && getDisplayMode() == DisplayMode.SESSION) { it.addAsSingletonList(buildSessionResetButton()) } } @@ -94,14 +114,15 @@ class SkyHanniTracker<Data : TrackerData>( private fun buildDisplayModeView() = LorenzUtils.buildSelector<DisplayMode>( "§7Display Mode: ", getName = { type -> type.displayName }, - isCurrent = { it == displayMode }, + isCurrent = { it == getDisplayMode() }, onChange = { displayMode = it + storedTrackers[name] = it update() } ) - private fun getSharedTracker() = ProfileStorageData.profileSpecific?.let { + protected fun getSharedTracker() = ProfileStorageData.profileSpecific?.let { SharedTracker(getStorage(it), currentSessions.getOrPut(it) { createNewSession() }) } @@ -113,6 +134,18 @@ class SkyHanniTracker<Data : TrackerData>( } } + private fun getDisplayMode() = displayMode ?: run { + val newValue = config.defaultDisplayMode.get().mode ?: storedTrackers[name] ?: DisplayMode.TOTAL + displayMode = newValue + newValue + } + + fun firstUpdate() { + if (display.isEmpty()) { + update() + } + } + class SharedTracker<Data : TrackerData>(private val total: Data, private val currentSession: Data) { fun modify(modifyFunction: (Data) -> Unit) { modifyFunction(total) @@ -130,4 +163,13 @@ class SkyHanniTracker<Data : TrackerData>( SESSION("This Session"), ; } + + enum class DefaultDisplayMode(val display: String, val mode: DisplayMode?) { + TOTAL("Total", DisplayMode.TOTAL), + SESSION("This Session", DisplayMode.SESSION), + REMEMBER_LAST("Remember Last", null), + ; + + override fun toString() = display + } } |