aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/label-merge-conflict.yml4
-rw-r--r--CHANGELOG.md299
-rw-r--r--CONTRIBUTING.md2
-rw-r--r--FEATURES.md19
-rw-r--r--README.md6
-rw-r--r--build.gradle.kts10
-rw-r--r--gradle/libs.versions.toml4
-rw-r--r--src/main/java/SkyHanniInstallerFrame.java30
-rw-r--r--src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt58
-rw-r--r--src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt200
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt85
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/Features.java114
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/Storage.java131
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt65
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/commands/SimpleCommand.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/core/config/Position.java16
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/ChatConfig.java212
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/CombatConfig.java721
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/CommandsConfig.java115
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/CrimsonIsleConfig.java151
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/DevConfig.java220
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/DungeonConfig.java256
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/EventConfig.java379
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/FishingConfig.java290
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/GUIConfig.java146
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/GardenConfig.java1433
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/InventoryConfig.java442
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/ItemAbilityConfig.java74
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/MiningConfig.java114
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/MinionsConfig.java96
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/MiscConfig.java827
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/OldHidden.java118
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/RiftConfig.java720
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/SlayerConfig.java523
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/bazaar/BazaarConfig.java (renamed from src/main/java/at/hannibal2/skyhanni/config/features/BazaarConfig.java)2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/chat/ChatConfig.java91
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/chat/ChatSymbols.java24
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/chat/CompactPotionConfig.java20
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/chat/FilterTypesConfig.java83
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/chat/PlayerMessagesConfig.java21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/chroma/ChromaConfig.java (renamed from src/main/java/at/hannibal2/skyhanni/config/features/ChromaConfig.java)2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/combat/BestiaryConfig.java48
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/combat/CombatConfig.java47
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/combat/EnderNodeConfig.java64
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/combat/MobsConfig.java94
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/combat/SummoningsConfig.java38
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/combat/damageindicator/DamageIndicatorConfig.java102
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/combat/damageindicator/EnderSlayerConfig.java18
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/combat/damageindicator/VampireSlayerConfig.java23
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/GhostCounterConfig.java96
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/BestiaryFormattingConfig.java41
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/ETAFormattingConfig.java42
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/KillHourFormattingConfig.java24
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/TextFormattingConfig.java148
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/XPHourFormattingConfig.java26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/commands/CommandsConfig.java39
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/commands/FandomWikiCommandConfig.java27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/commands/TabCompleteConfig.java61
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/CrimsonIsleConfig.java34
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/ReputationHelperConfig.java38
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/ashfang/AshfangConfig.java50
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/ashfang/BlazingSoulsColor.java21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/ashfang/GravityOrbsConfig.java21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/ashfang/HideAshfangConfig.java27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/dev/DebugConfig.java88
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/dev/DevConfig.java52
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/dev/WaypointsConfig.java26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/dev/minecraftconsole/ConsoleFiltersConfig.java53
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/dev/minecraftconsole/MinecraftConsoleConfig.java40
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/dungeon/CleanEndConfig.java21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/dungeon/DungeonConfig.java102
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/dungeon/DungeonCopilotConfig.java18
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/dungeon/LividFinderConfig.java20
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/dungeon/MessageFilterConfig.java14
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/dungeon/ObjectHiderConfig.java65
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/dungeon/PartyFinderConfig.java44
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/dungeon/TabListConfig.java15
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/event/CenturyConfig.java24
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/event/CityProjectConfig.java31
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/event/EventConfig.java51
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/event/GreatSpookConfig.java44
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/event/HalloweenBasketConfig.java25
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/event/MayorJerryConfig.java16
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoCardConfig.java45
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoConfig.java30
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/CompactChatConfig.java27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/event/diana/DianaConfig.java60
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/event/diana/IgnoredWarpsConfig.java19
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/event/diana/InquisitorSharingConfig.java37
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/event/winter/FrozenTreasureConfig.java72
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/event/winter/WinterConfig.java26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/fishing/BarnTimerConfig.java62
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/fishing/ChumBucketHiderConfig.java26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishedItemNameConfig.java21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingBaitWarningsConfig.java20
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingConfig.java76
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingHookDisplayConfig.java27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/fishing/RareCatchesConfig.java32
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/fishing/ThunderSparkConfig.java20
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/fishing/trophyfishing/ChatMessagesConfig.java56
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/fishing/trophyfishing/TrophyFishingConfig.java27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/AnitaShopConfig.java30
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/CropStartLocationConfig.java16
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/DicerCounterConfig.java24
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/EliteFarmingWeightConfig.java54
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/FarmingArmorDropsConfig.java24
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/FarmingFortuneConfig.java27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenConfig.java211
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenLevelConfig.java18
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/KeyBindConfig.java87
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/MoneyPerHourConfig.java126
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/NextJacobContestConfig.java59
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/NumbersConfig.java32
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/PlotIconConfig.java24
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/SkyMartConfig.java29
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/TooltipTweaksConfig.java47
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/YawPitchDisplayConfig.java64
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/composter/ComposterConfig.java108
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/composter/NotifyLowConfig.java38
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/CropMilestonesConfig.java101
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/MushroomPetPerkConfig.java43
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/NextConfig.java66
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/optimalspeed/CustomSpeedConfig.java79
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/optimalspeed/OptimalSpeedConfig.java39
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/DropsStatisticsConfig.java78
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/InventoryConfig.java37
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/NeedsConfig.java40
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/RewardWarningConfig.java62
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/TimerConfig.java37
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/VisitorConfig.java118
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/gui/GUIConfig.java74
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/gui/InGameDateConfig.java63
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/gui/ModifyWordsConfig.java28
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/gui/TextBoxConfig.java26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/inventory/ChestValueConfig.java88
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/inventory/HideNotClickableConfig.java43
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java127
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/inventory/JacobFarmingContestConfig.java32
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/inventory/RngMeterConfig.java26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/inventory/SackDisplayConfig.java84
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/inventory/StatsTuningConfig.java32
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/inventory/helper/HarpConfigKeyBinds.java37
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/inventory/helper/HelperConfig.java37
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/inventory/helper/TiaRelayConfig.java32
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/itemability/ChickenHeadConfig.java25
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/itemability/FireVeilWandConfig.java21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/itemability/ItemAbilityConfig.java38
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/markedplayer/MarkedPlayerConfig.java (renamed from src/main/java/at/hannibal2/skyhanni/config/features/MarkedPlayerConfig.java)2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/mining/KingTalismanConfig.java25
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/mining/MiningConfig.java32
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/mining/PowderTrackerConfig.java84
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/minion/EmptiedTimeConfig.java27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/minion/LastClickedMinionConfig.java36
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/minion/MinionsConfig.java46
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/DiscordRPCConfig.java97
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/EstimatedItemValueConfig.java52
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/GlowingDroppedItemsConfig.java26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/HideArmorConfig.java20
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/HighlightPartyMembersConfig.java25
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/KickDurationConfig.java34
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/MiscConfig.java216
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/ParticleHiderConfig.java50
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/PocketSackInASackConfig.java21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/PotionEffectsConfig.java24
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/QuickModMenuSwitchConfig.java29
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/TeleportPadConfig.java21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/TrevorTheTrapperConfig.java110
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/compacttablist/AdvancedPlayerListConfig.java73
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/compacttablist/CompactTabListConfig.java27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/cosmetic/ArrowTrailConfig.java46
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/cosmetic/CosmeticConfig.java18
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/cosmetic/FollowingLineConfig.java37
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/pets/PetConfig.java24
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/pets/PetExperienceToolTipConfig.java27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/CruxTalismanDisplayConfig.java30
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/EnigmaSoulConfig.java22
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/MotesOrbsConfig.java28
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/RiftConfig.java53
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/RiftTimerConfig.java30
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/RiftAreasConfig.java60
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/colosseum/ColosseumConfig.java15
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/dreadfarm/DreadfarmConfig.java26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/dreadfarm/VoltCruxConfig.java33
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/dreadfarm/WiltedBerberisConfig.java26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/livingcave/DefenseBlockConfig.java29
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/livingcave/LivingCaveConfig.java23
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/livingcave/LivingCaveLivingMetalConfig.java22
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/livingcave/LivingMetalSuitProgressConfig.java24
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/LavaMazeConfig.java39
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/MirrorVerseConfig.java29
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/TubulatorConfig.java44
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/UpsideDownParkourConfig.java44
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/danceroomhelper/DanceRoomHelperConfig.java48
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/danceroomhelper/danceroomformatting/ColorConfig.java42
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/danceroomhelper/danceroomformatting/DanceRoomFormattingConfig.java29
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/stillgorechateau/EffigiesConfig.java37
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/stillgorechateau/StillgoreChateauConfig.java14
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/westvillage/KloonHackingConfig.java27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/westvillage/WestVillageConfig.java13
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/wyldwoods/LarvasConfig.java22
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/wyldwoods/OdonataConfig.java23
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/area/wyldwoods/WyldWoodsConfig.java27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/motes/InventoryValueConfig.java25
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/rift/motes/MotesConfig.java27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/slayer/ItemProfitTrackerConfig.java50
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/slayer/ItemsOnGroundConfig.java21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/slayer/RngMeterDisplayConfig.java30
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/slayer/SlayerBossWarningConfig.java26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/slayer/SlayerConfig.java77
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/slayer/blaze/BlazeConfig.java32
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/slayer/blaze/BlazeHellionConfig.java45
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/slayer/endermen/EndermanBeaconConfig.java46
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/slayer/endermen/EndermanConfig.java31
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/BloodIchorConfig.java38
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/CoopBossHighlightConfig.java44
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/KillerSpringConfig.java31
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/OthersBossConfig.java39
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/OwnBossConfig.java39
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/VampireConfig.java80
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/CropAccessoryData.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/FriendAPI.kt62
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/GardenComposterUpgradesData.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestonesCommunityFix.kt177
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/GardenCropUpgrades.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/GuiEditManager.kt27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt22
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/IslandType.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/LocationFixData.kt33
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/MinecraftData.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/OwnInventoryData.kt105
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/PartyAPI.kt11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/PetAPI.kt11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/ProfileStorageData.kt98
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/PurseAPI.kt13
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/RenderData.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/SlayerAPI.kt25
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/model/ComposterUpgrade.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/repo/RepoManager.kt24
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/EntityEquipmentChangeEvent.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/FishingBobberCastEvent.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/PurseChangeEvent.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/RenderEntityOutlineEvent.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/entity/ItemAddInInventoryEvent.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarCancelledBuyOrderClipboard.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardDisplay.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/BingoNextStepHelper.kt29
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/CompactBingoChat.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/MinionCraftHelper.kt1
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilterGui.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/chat/CompactBestiaryChatMessage.kt18
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/chat/PlayerDeathMessages.kt10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/chat/WatchdogHider.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatFilter.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaFontRenderer.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaShader.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/DamageIndicatorManager.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/combat/endernodetracker/EnderNodeTracker.kt125
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostCounter.kt48
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostData.kt36
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostUtil.kt14
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/combat/mobs/AreaMiniBossFeatures.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/combat/mobs/SpawnTimers.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/commands/WikiManager.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/cosmetics/ArrowTrail.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/cosmetics/CosmeticFollowingLine.kt10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCleanEnd.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCopilot.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonDeathCounter.kt9
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonFinderFeatures.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonHideItems.kt13
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonLividFinder.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonMilestonesDisplay.kt9
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonTeammateOutlines.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/anniversary/Year300RaffleEvent.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/diana/BurrowType.kt10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/diana/BurrowWarpHelper.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/diana/DianaAPI.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/diana/GriffinBurrowParticleFinder.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/diana/GriffinPetWarning.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/diana/InquisitorWaypointShare.kt14
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/diana/SoopyGuessBurrow.kt28
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/jerry/frozentreasure/FrozenTreasureTracker.kt92
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/spook/TheGreatSpook.kt58
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fame/AccountUpgradeReminder.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fame/CityProjectFeatures.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/FishingAPI.kt42
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/FishingBaitWarnings.kt89
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/FishingHookDisplay.kt24
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureManager.kt1
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureMessageShortener.kt11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/SharkFishCounter.kt18
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/ShowFishingItemName.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/OdgerWaypoint.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/TrophyFishManager.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/TrophyFishMessages.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt165
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt28
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneFix.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropTimeCommand.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenLevelDisplay.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt42
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenPlotBorders.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterAPI.kt10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterDisplay.kt24
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterOverlay.kt26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/composter/GardenComposterInventoryFeatures.kt14
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/contest/ContestBracket.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/contest/FarmingContestAPI.kt50
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestFFNeededDisplay.kt29
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestStatsSummary.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestTimeNeeded.kt47
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobFarmingContestsInventory.kt46
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/ArmorDropTracker.kt (renamed from src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingArmorDrops.kt)103
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropMoneyDisplay.kt10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropSpeedMeter.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/DicerDropTracker.kt (renamed from src/main/java/at/hannibal2/skyhanni/features/garden/farming/DicerRngDropCounter.kt)116
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt58
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropMilestoneDisplay.kt14
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropSpeed.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenStartLocation.kt21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/WildStrawberryDyeNotification.kt14
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/WrongFungiCutterWarning.kt28
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CaptureFarmingGear.kt45
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFGuideGUI.kt18
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFStats.kt29
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneStats.kt15
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneUpgrades.kt43
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/CropPage.kt31
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/OverviewPage.kt140
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/UpgradePage.kt77
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/inventory/AnitaExtraFarmingFortune.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenCropMilestoneInventory.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenNextPlotPrice.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenPlotIcon.kt16
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/inventory/SkyMartCopperPrice.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorColorNames.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorDropStatistics.kt170
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorFeatures.kt66
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorTimer.kt108
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/visitor/HighlightVisitorsOutsideOfGarden.kt106
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorAPI.kt41
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorListener.kt37
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorReward.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorTooltipParser.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/inventory/ChestValue.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt66
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/inventory/HideNotClickableItems.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/inventory/ItemDisplayOverlayFeatures.kt26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/inventory/tiarelay/TiaRelayHelper.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/itemabilities/FireVeilWandParticles.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/itemabilities/abilitycooldown/ItemAbilityCooldown.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/mining/HighlightMiningCommissionMobs.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/mining/KingTalismanHelper.kt75
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/mining/crystalhollows/CrystalHollowsNamesInCore.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/mining/powdertracker/PowderTracker.kt153
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/minion/MinionCollectLogic.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/BrewingStandOverlay.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/CollectionTracker.kt20
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/CurrentPetDisplay.kt58
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/FandomWikiFromMenus.kt11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/FixNEUHeavyPearls.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/InGameDateDisplay.kt46
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/JoinCrystalHollows.kt10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/LimboTimeTracker.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/LockMouseLook.kt85
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/MarkedPlayerManager.kt10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/MiscFeatures.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/NonGodPotEffectDisplay.kt1
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/PetCandyUsedDisplay.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/PetExpTooltip.kt57
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/PlayerChatSymbols.kt16
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/QuickModMenuSwitch.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/SkyBlockKickDuration.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/SuperpairsClicksAlert.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/TimeFeatures.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/AdvancedPlayerList.kt23
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/TabListReader.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordRPCManager.kt16
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordStatus.kt10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValue.kt725
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValueCalculator.kt699
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedWardrobePrice.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/massconfiguration/DefaultConfigFeatures.kt35
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorFeatures.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorTracker.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/update/GuiOptionEditorUpdateCheck.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/update/UpdateManager.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/visualwords/VisualWordGui.kt243
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/PabloHelper.kt41
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/QuestItemHelper.kt32
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazes.kt25
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazingSouls.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangFreezeCooldown.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangGravityOrbs.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHideDamageIndicator.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangNextResetCooldown.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/CrimsonIsleReputationHelper.kt10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailykuudra/DailyKuudraBossHelper.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/DailyQuestHelper.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/QuestLoader.kt19
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/DailyMiniBossHelper.kt18
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/RiftAPI.kt10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/colosseum/BlobbercystsHighlight.kt10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/RiftAgaricusCap.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/RiftWiltedBerberisHelper.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/VoltHighlighter.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/livingcave/LivingCaveDefenseBlocks.kt14
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/livingcave/LivingCaveLivingMetalHelper.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/livingcave/LivingMetalSuitProgress.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/DanceRoomHelper.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/RiftLavaMazeParkour.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/RiftUpsideDownParkour.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/TubulatorParkour.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/stillgorechateau/RiftBloodEffigies.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/westvillage/KloonHacking.kt16
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/wyldwoods/RiftLarva.kt (renamed from src/main/java/at/hannibal2/skyhanni/features/rift/area/RiftLarva.kt)6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/wyldwoods/RiftOdonata.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/wyldwoods/ShyCruxWarnings.kt10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/EnigmaSoulWaypoints.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/RiftHorsezookaHider.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/motes/RiftMotesOrb.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/motes/ShowMotesNpcSellPrice.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerBossSpawnSoon.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemsOnGround.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt (renamed from src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemProfitTracker.kt)267
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerQuestWarning.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerRngMeterDisplay.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerType.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/VampireSlayerFeatures.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/blaze/BlazeSlayerDaggerHelper.kt103
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/blaze/BlazeSlayerFirePitsWarning.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/enderman/EndermanSlayerFeatures.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningMobManager.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningSoulsName.kt11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/mixins/hooks/FontRendererHook.kt18
-rw-r--r--src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinFontRenderer.java4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/mixins/transformers/gui/MixinGuiContainer.java12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/mixins/transformers/renderer/MixinRendererLivingEntity.java4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/HotSwapDetection.kt50
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/SkyHanniConfigSearchResetCommand.kt10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt57
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/TestBingo.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/TestCopyBestiaryValues.kt14
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/TestExportTools.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/command/CopyItemCommand.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/command/CopyNearbyEntitiesCommand.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/command/CopyNearbyParticlesCommand.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/command/CopyScoreboardCommand.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/command/CopyTabListCommand.kt27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/command/ErrorManager.kt63
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/command/TestChatCommand.kt9
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt14
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/BlockUtils.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/CachedItemData.kt29
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/CombatUtils.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt24
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt23
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt23
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/LocationUtils.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/LorenzLogger.kt38
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/LorenzRarity.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt181
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/MinecraftConsoleFilter.kt26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt16
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/NEUVersionCheck.kt22
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/ParkourHelper.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt32
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt9
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/SoundUtils.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt20
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/TabListData.kt46
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt14
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/Timer.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ContributorListJson.java3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/GardenJson.java30
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/JacobContestsJson.java13
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/KnownFeaturesJson.java12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/LocationFixJson.java27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/MayorJson.java16
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SeaCreatureJson.java3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/TabListJson.java11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/shader/Shader.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderHelper.kt70
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderManager.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/shader/Uniform.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt133
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/tracker/TrackerData.kt5
-rw-r--r--src/main/resources/mcmod.info32
-rw-r--r--src/test/java/at/hannibal2/skyhanni/test/ItemUtilsTest.kt26
-rw-r--r--src/test/java/at/hannibal2/skyhanni/test/garden/VisitorToolTipParserTest.kt22
505 files changed, 13699 insertions, 10393 deletions
diff --git a/.github/workflows/label-merge-conflict.yml b/.github/workflows/label-merge-conflict.yml
index d4e693f7b..6c0268d6c 100644
--- a/.github/workflows/label-merge-conflict.yml
+++ b/.github/workflows/label-merge-conflict.yml
@@ -22,5 +22,5 @@ jobs:
dirtyLabel: "Merge Conflicts"
#removeOnDirtyLabel: "PR: ready to ship"
repoToken: "${{ secrets.GITHUB_TOKEN }}"
- commentOnDirty: "This pull request has conflicts with the base branch. Please resolve those so we can evaluate the pull request."
- commentOnClean: "Conflicts have been resolved! 🎉 A maintainer will review the pull request shortly."
+ commentOnDirty: "This pull request has conflicts with the base branch \"beta\". Please resolve those so we can test out your changes."
+ commentOnClean: "Conflicts have been resolved! 🎉"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4e86f8588..884017ef6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,12 +1,121 @@
# SkyHanni - Change Log
-## Version 0.21 (unreleased)
+## Version 0.21.1
### New Features
++ Organised the config into sub categories. - nea & walker
++ Wrong crop milestone step detection. - hannibal2
+ + When opening the crop milestone menu, a chat message is sent if Hypixel's crops per milestone level data is
+ different from SkyHanni's.
+ + 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.
+
+### Changes
+
+#### Garden Changes
+
++ Added mythic/Maeve visitor support. - walker & hannibal2
++ Added option to use custom Blocks per Second value in some Garden GUIs instead of the real one. - hannibal2
++ Added option to change the item scale of SkyMart Coins per Copper list. - hannibal2
++ Added support for Sunder 6 in /ff upgrades. - hannibal2
++ Added support for mythic in Visitor Drop Statistics. - hannibal2
++ Use the crop fortune from tab in Farming Fortune HUD. - alexia
++ Shows the last saved ff value in gray while switching tools instead of the question mark. - hannibal2
++ Removed chat message that your crop milestone data is correct. - hannibal2
++ Removed the message when crop milestones look different in the menu than stored SkyHanni data. - hannibal2
+ + We already have the correct data now, and Hypixel rounds the numbers in the menu poorly.
+ + Only show the Total Crop Milestone info in crop milestone inventory when below tier 20. - hannibal2
+ + Hypixel now has their own line for the same information for tier 20+
++ Make the FF Display only visible while holding a farming tool in hand. - hannibal2
++ Hide in crop milestone display the line with time remaining entirely when the milestone is maxed. - hannibal2
+
+#### Other Changes
+
++ Added guess seconds to the Visitor Timer when the tab list doesn't show seconds. - hannibal2
++ Add option to hide the chat message when toggling /shmouselock. - hannibal2
++ Reminds to use the GUI Position Editor hotkey. - hannibal2
+ + Reminds every 30 minutes after using /sh gui or clicking the GUI edit button.
++ Added Bookworm Book to the Estimated Item Value feature. - jani
+
+### Fixes
+
+#### Garden Fixes
+
++ Fixed new visitor alerts triggering wrongly and constantly. - Cad
++ Fixed visitor timer. - hannibal2
++ Fixed wrong Fungi Cutter mode warning not working. - walker
++ Fixed Maximum FF Needed display not showing in Jacob NPC menu. - hannibal2
++ Fixed calendar contest detection failing. - hannibal2
++ Fixed plot borders flickering and consistency errors when pressing the keybind - hannibal2
++ Fixed wrong ff needed values in Time Needed for Gold Medal GUI. - hannibal2
++ Fixed Farming Contest Medal Icons in Inventory not showing. - hannibal2
++ Fixed /ff not detecting collection analyst fortune. - hannibal2
++ Fixed Mushroom Cow Perk display not working. - hannibal2
++ Fixed visitor timer error if the visitors aren't unlocked yet. - hannibal2
++ Fixed farming weight no longer updating on block breaking. - hannibal2
++ Added cooldown to prevent spam clicking on farming weight buttons to open many web pages. - hannibal2
++ Fixed clickable farming weight GUI no longer opens #1000 in lb website. - hannibal2
++ Fixed /ff upgrade suggests updating bustling reforge even when no farming armor is found. - hannibal2
++ Fixed maxed sunder fortune in the /ff stats breakdown. - alexia
++ Fixed the farming contest summary not showing when the crop is buffed by Anita Talisman/Ring/Artifact. - hannibal2
++ Fixed Farming Fortune Display not showing for non crop-specific tools. - hannibal2
++ Fixed green thumb fortune in /ff to include Maeve. - hannibal2
++ Fixed crops per second and time remaining not using the 100 base ff in their formula. - alexia
+
+#### Other Fixes
+
++ Fixed showing "slayer boss spawn soon" message outside the correct slayer area. - hannibal2
++ Fixed blocking clicks on bazaar with player name "wiki". - hannibal2
++ Fixed highlighting some mobs in the dungeon wrongly as area mini bosses. - hannibal2
++ Fixed opening the Pet menu no longer updating the current pet display. - hannibal2
++ Fixed Archfiend Dice and High Class Archfiend Dice counting as slayer drops when rolled. - hannibal2
++ Fixed dice roll profit counting as Mob Kill Coins in Slayer Tracker. - hannibal2
++ Fixed Sack Display sometimes not formatting a million correctly. - Hize
++ Fixed Estimated Item Value getting shown in stats breakdown menu. - hannibal2
++ Fixed a bug with the ender chest and SkyHanni GUI editor. - hannibal2
++ Fixed crimson isle faction icon in tab list showing twice and not going away fully when enabling the "hide faction"
+ option of advanced player list. - hannibal2
+
+### Technical Details
+
++ Updated to a newer version of MoulConfig. - nea & walker
+ + This includes support for the new sub category part in the config.
++ Added TimeUtils.getDuration and deprecated TimeUtils.getMillis. - hannibal2
++ Created PetAPI and deprecated String.matchRegex(). - hannibal2
++ Extracted sacks, friends, known features and Jacob contests in to their separate files. - CalMWolfs
++ Add log clearing. - CalMWolfs
++ Add auto-prefix to chat message methods. - walker
++ Added support for extra data in error manager. - hannibal2
++ Added /readcropmilestonefromclipboard. - hannibal2
+ + This command reads the clipboard content, in the format of users sending crop milestone step data.
+ + The new data gets compared to the currently saved data, differences are getting replaced and the result gets put
+ into the clipboard. The clipboard context can be used to update the repo content.
+
+### Removed Features
+
++ Removed 100 Farming Fortune from "Show As Drop Multiplier" from all displays (also known as "base ff"). - hannibal2
+ + This can cause some numbers to show 100 FF too much. Simply update the values to fix it.
+ + Those "base FF" values were never really part of your farming fortune stats. They are just a result of looking at
+ the crop drop formula. SkyHanni used those values to be more comparable with other Discord Bots and spreadsheets.
+ This also caused confusion, so we have removed it entirely now.
+
+## Version 0.21
+
+### New Features
+
+#### Inventory
+
+ Added Quick Craft Confirmation. - Cad
+ Require Ctrl+Click to craft items that aren't often quick crafted (e.g. armor, weapons, accessories).
+ Sack items can be crafted normally.
++ Added Shift Click Equipment. - Thunderblade73
+ + This removes the need to shift-click to swap the equipment items, without the annoying "pick up animation".
++ Added option to highlight items that are full in the sack inventory.
+
+#### GUI
+
+ Added **Compact Tab List**.
+ Compacts the tablist to make it look much nicer (old SBA feature, but fewer bugs). - CalMWolfs
+ Option to hide Hypixel advertisment banners. - CalMWolfs
@@ -16,21 +125,21 @@
party/friends/guild
+ Option to hide different parts of the player list: Player skins/icons, Hypixel rank color, Emblems, SkyBlock
level
-+ Added Kick Duration. - hannibal2
- + Show in the Hypixel lobby since when you were last kicked from SkyBlock.
- + Useful if you get blocked because of 'You were kicked while joining that server!'.
- + Send a warning and sound after a custom amount of seconds.
-+ Added Time In Limbo. - hannibal2
- + Show the time since you entered limbo.
- + Show a chat message for how long you were in limbo once you leave it.
-+ Added Highlight Party Members. - Cad
- + Marking party members with a bright outline to better find them in the world.
-+ Added Shift Click Equipment. - Thunderblade73
- + This removes the need to shift-click to swap the equipment items, without the annoying "pick up animation".
++ Added AFK time to Discord RPC. - NetheriteMiner
+
+#### Chat
+
+ Adds chat symbols such as iron man/bingo/nether faction like SBA had/has. - CalMWolfs
+ Will not break with emblems.
+ Optional if left or right side of name.
+ Should not break with other mods.
++ Added Chat **Translator** - NetheriteMiner
+ + After enabling, click on any chat message sent by another player to translate it to English.
+
+#### Rendering
+
++ Added Highlight Party Members. - Cad
+ + Marking party members with a bright outline to better find them in the world.
+ Porting SBA's **chroma** into SkyHanni with many more options and chroma everything. - VixidDev
+ Options to change speed, size, saturation and direction.
+ Added Modify Visual Words (command /shwords). - CalMWolfs
@@ -39,38 +148,48 @@
+ Added In-Game Date display. - Erymanthus
+ Show the in-game date of SkyBlock (like in Apec, but with mild delays).
+ Includes the SkyBlock year.
++ Added **Arrow Trail Cosmetic** - Thunderblade73
+ + Draw a colored line behind the arrows in the air.
+ + Options to change the color of the line, to only show own arrows or every arrow, to have own arrows in a different
+ color, to change the time alive, and the line width.
+
+#### Crimson Isle
+
+ Added Quest Item Helper. - NetheriteMiner
+ When you open the fetch item quest in the town board, it shows a clickable chat message that will grab the items
needed from the sacks.
++ Added Crimson Isle **Pablo NPC Helper**. - NetheriteMiner
+ + Similar to Quest Item Helper, shows a clickable message that grabs the flower needed from sacks.
+
+##### Fishing
+
+ Added alerts when the player catches a Legendary Sea Creature. - Cad
++ Added **Fishing Bait Warnings.** - cimbraien
+ + Option to warn when no bait is used.
+ + Option to warn when used bait is changed.
+
+#### Dungeon
+
+ Added Soulweaver Skull Hider to the Dungeon Object Hider. - nea
+ Hide the annoying soulweaver skulls that float around you if you have the soulweaver gloves equipped.
-+ Added /shmouselock command to lock mouse rotation for farming. - Cad
+ Added **Dungeon party finder** QOL improvements - Cad
+ Floor stack size.
+ Mark Paid Carries red.
+ Mark Low-Class levels orange.
+ Mark groups you can't join dark red.
+ Mark groups without your current classes green.
-+ Added shortcuts for **Party commands** and smart **tab complete**. - CalMWolfs
- + /pw -> party warp
- + /pk -> party kick
- + /pt -> party transfer
- + /pp -> party promote
- + /pko -> party kickoffline
+ Added working **Livid Finder** (should work 100% of the time). - hannibal2
+ Option to hide other/wrong/fake Livids (try this out and see if you really want this, it can be counter-productive
in some cases).
-+ Added AFK time to Discord RPC. - NetheriteMiner
-+ Added option to highlight items that are full in the sack inventory.
-+ Added **Arrow Trail cosmetic** - Thunderblade73
- + Draw a colored line behind the arrows in the air.
- + Options to change the color of the line, to only show own arrows or every arrow, to have own arrows in a different
- color, to change the time alive, and the line width.
-+ Added the option to change Hypixel Wiki to the fandom Wiki in more areas than just the /wiki command. - Erymanthus
- + E.g. inside the SkyBlock leveling guide.
-+ Added Chat **Translator** - NetheriteMiner
- + After enabling, click on any chat message sent by another player to translate it to English.
+
+#### Garden
+
++ Added /shmouselock command to lock mouse rotation for farming. - Cad
++ Added Highlight Visitors in SkyBlock. - nea
+ + Highlights Visitors outside the Garden.
++ Block Interacting with Visitors. - nea
+ + Blocks you from interacting with / unlocking Visitors to allow for Dedication Cycling.
++ Added Auto-Detection of Expired Pumpkin farming fortune. - CalMWolfs
#### Events
@@ -82,7 +201,32 @@
+ Help with the 2023 Halloween visitor challenge (ephemeral dingsibumsi or something) - nea
+ New Visitor Ping: Pings you when you are less than 10 seconds away from getting a new visitor.
+ 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
+#### Commands
+
++ Added shortcuts for **Party commands** and smart **tab complete**. - CalMWolfs
+ + /pw -> party warp
+ + /pk -> party kick
+ + /pt -> party transfer
+ + /pp -> party promote
+ + /pko -> party kickoffline
++ Added the option to change Hypixel Wiki to the fandom Wiki in more areas than just the /wiki command. - Erymanthus
+ + E.g. inside the SkyBlock leveling guide.
++ Added command **/shpumpkin** to toggle include/exclude Expired Pumpkin farming fortune in the /ff GUI and in the true
+ ff
+ display. - CalMWolfs
+
+#### Misc
+
++ Added Kick Duration. - hannibal2
+ + Show in the Hypixel lobby since when you were last kicked from SkyBlock.
+ + Useful if you get blocked because of 'You were kicked while joining that server!'.
+ + Send a warning and sound after a custom amount of seconds.
++ Added Time In Limbo. - hannibal2
+ + Show the time since you entered limbo.
+ + Show a chat message for how long you were in limbo once you leave it.
### Changes
@@ -93,8 +237,8 @@
+ Made Fatal Tempo same as Chimera in Estimated Item Value. - jani
+ Added debug options for fishing hook display. - hannibal2
+ This should help find values that the fishing hook display works 100% with.
-+ Changed the color for the tab list Special Persons Mark.
-+ Mark SkyHanni Devs in the tab list special.
++ Changed the color for the tab list Special Persons Mark. - hannibal2
++ Mark SkyHanni Devs in the tab list special. - hannibal2
+ Added buttons to change the format of the price and the number in the sack display. - HiZe
+ Made Smoldering same as Fatal Tempo and Chimera in Estimated Item Value. - jani
+ Added an option to change where to get the items from in the composter overlay: from the bazaar or from sacks. - HiZe
@@ -119,9 +263,11 @@
+ Only items with recipes are tab completed.
+ Added option to set the size of highlighted motes orbs in rift and make them smaller by default. - cimbraien
+ Disabled clicks on SkyHanni GUIs while inside NEU's or Skytils profile viewer. - hannibal2
-+ Removed armor stand checks for Trevor Solver. This fixes or nerfs the feature to not highlight mobs behind blocks sometimes. - hannibal2
++ Removed armor stand checks for Trevor Solver. This fixes or nerfs the feature to not highlight mobs behind blocks
+ sometimes. - hannibal2
+ Added diamond and gold essence support to PowderTracker. - walker
-+ Change the fandom wiki search engine (under the /wiki command) from Google to the fandom wiki's built-in search engine - Erymanthus
++ Change the fandom wiki search engine (under the /wiki command) from Google to the fandom wiki's built-in search
+ engine - Erymanthus
+ Added option to hide Chest Value while the Estimated Item Value display is showing. - hannibal2
+ No longer merging same items with different prices in Chest Value together. - hannibal2
+ Adding Great Spook support for Non God Pot Effect display. - hannibal2
@@ -129,6 +275,32 @@
+ Added support for detecting refreshed farming fortune century cake effect. - alexia
+ Show key to press below burrow warp. - hannibal2
+ Makes the Compact Potion message open the Potion effects menu on click. - jani
++ Added option to show King Talisman Helper outside Dwarven Mines. - hannibal2
++ In-Game Date: Adds support for reading the in-game scoreboard, and also allow sun/moon symbol customization. -
+ Erymanthus
++ Added Estimated Item Value support to NEU Profile Viewer - hannibal2
++ Added support to import SBE Visual Words into SkyHanni. - HiZe
++ Add custom keybinds for Harp Helper. - Thunderblade73
++ Show the custom hotkey name in the Harp inventory. - hannibal2
++ Added a GUI element to remind you while /shmouselock is enabled. - CalMWolfs
++ Make Crimson Isle Quest Item Helper only get amount needed. - NetheriteMiner
++ Change config order to alphabetical. - walker
++ Added commands /shresetpowdertracker and /shresetdicertracker to reset the Powder Tracker and Dicer Drop Tracker -
+ hannibal2
++ Added current session/total session switch for Dicer Drop Tracker. - hannibal2
++ Added a button to reset the local session for Dicer Drop Tracker and for Powder Tracker. - hannibal2
++ Added more features for Ender Node Tracker and Armor Drop Tracker. - hannibal2
+ + Added session/display mode support, added a button to reset the current session, and added the commands
+ /shresetendernodetracker and /shresetarmordroptracker to reset the full data.
++ Added support for different current sessions per profile for all new trackers: Ender Node, Armor Drop, Dicer Drop,
+ Powder and Slayer Profit Tracker
++ Added the option to change the Blaze Slayer Dagger GUI positions. - hannibal2
++ Added more features to the Frozen Treasure Tracker. - hannibal2
+ + Added session/display mode support, added a button to reset the current session, and added the commands
+ /shresetfrozentreasuretracker to reset the full data.
++ Added Slayer Profit Tracker support for loot from area mini-bosses. - hannibal2
++ No longer opening the empty /shdefaultoptions GUI. - walker
++ Added the SkyHanni icon and a link to the GitHub page for MC launchers like Prism to display. - hannibal2
### Bug Fixes
@@ -191,6 +363,38 @@
+ SkyHanni Keybinds no longer work inside SkyHanni config. - hannibal2
+ Fixed Great Spook potion not working in Non God Pot Effect feature. - jani
+ Fixed wrong Rhys (Deep Caverns NPC) items needed for Dwarven Mines unlock in Bingo Step Helper. - ReyMaratov
++ Fixed King Talisman Helper once again. - hannibal2
++ Made the ESC -> Mod Options -> SkyHanni -> Config button not crash you. - hannibal2
++ Disabled Diana Warp key and Inquis Share key while inside any GUI. - hannibal2
++ Removed Diana warp data on world switch. - hannibal2
++ Reset mouse sensitivity back to 100% if you log off with lock mouse look enabled. - hannibal2
++ Fixed mouse sensitivity stuck after restarting by storing old sensitivity. - CalMWolfs
++ Fixed tool fortune. - CalMWolfs
++ Fixed Item Ability Cooldown display not activating for Sword of Bad Health. - hannibal2
++ Fixed the crop name gets replaced to internal name in /shwords. - hannibal2
++ Show obfuscated fish as bait instead of caught item. - cimbraien
++ Fixed Estimated Item Value that renders twice inside NEU PV, by not rendering anything when the cursor is exactly in
+ between two items. - hannibal2
++ fixed more error messages with The Great Spook data getting stored in the Reputation Helper quest config
+ accidentally. - hannibal2
++ Hopefully fixed resets of Visitor Drops stats. - hannibal2
++ Fixed typo in The Art Of Peace. - walker
++ Fixed compatibility problems with ChatTriggers that caused flickering in the Estimated Item Value while inside the NEU
+ Profile Viewer. - hannibal2
++ Fixed Quest Item Helper showing negative numbers. - hannibal2
++ Fixed YouTuber and Admin ranks getting lost in the tab list. - walker
++ Added a cooldown to the current session tracker reset button to fix the chat spam. - hannibal2
++ Changed the color of the "Slayer boss soon!" warning from red to yellow. - hannibal2
++ Fixed a bug where some items were counted twice in the Slayer Profit Tracker. - hannibal2
++ Fixed item rarity errors in the museum. - hannibal2
++ Fixed mob highlighting problems with Blaze Slayer and Skytils. - hannibal2
++ Pablo Helper: Fixed some messages not showing the "get from sack" clickable message. - hannibal2
++ Fixed scoreboard date number suffixes are missing sometimes. - Erymanthus
++ Fixed the leftStronghold area not getting detected. - hannibal2
++ Fixed error message with Ashfang Blazes. - hannibal2
++ Fixed crash with pet exp tooltip. - hannibal2
++ Fixed dungeoneering showing as 0 in the skill menu. - hannibal2
++ Fixed showing minion level as 101 in some menus. - hannibal2
#### Config
@@ -202,7 +406,7 @@
+ Removed **Duplicate Hider**.
+ Hypixel now fixed the bug themselves and hides duplicate farming contests in the Jacob inventory.
-#### Internal Changes
+#### Technical Details
+ Add Repo TODOs to regex patterns. - walker
+ Moved many patterns from function scope to members. - hannibal2
@@ -216,6 +420,33 @@
java config files (names, description, orderings and stuff).
+ Adding 100 lines to MobFinder.kt and making it better readable in the process. - walker
+ Making ChatFiler.kt way better, storing regex objects for reuse and preparing future repo support. - walker
++ Added command /shkingfix to reset the internal King Talisman Helper offset. - hannibal2
++ Updated dependency version of junixsocket in DiscordIPC so that antivirus websites no longer show false positives. -
+ NetheriteMiner
++ Changed wrong/missing neu version message to show NEU version 2.1.1-Pre-4 instead of beta versions. - CalMWolfs
++ Deleting the old "hidden" part of the config. - hannibal2
++ This will reset parts of the config for users with 7-month-old SkyHanni versions that want to migrate into the
+ present.
++ Added a workaround for the NEU Profile Viewer bug where the ItemTooltipEvent gets called for two items when hovering
+ over the border between two items. - hannibal2
++ Using visitorDrops.visitorRarities directly from the config instead of accessing the local field. Hopefully this will
+ prevent partial config resets in the future. - hannibal2
++ Added a tracker API that can be used for all features in SkyHanni that currently track stuff that the user collects. -
+ hannibal2
++ Added the slayer profit tracker logic (command to reset, toggle between total view and session view, and button to
+ delete session) to powder tracker and Dicer Drop Tracker. - hannibal2
++ Added support for migrating parts of the player or session storage. - nea
++ Changed the config format for dicerRngDrops/dicerDropsTracker. - hannibal2
++ Created SkyHanniTracker, the core API for working with tracker stuff. This should be used everywhere someday in the
+ future. - hannibal2
++ Used SkyHanniTracker in FrozenTreasureTracker. - hannibal2
++ Added /shdebugwaypoint as a test/debug command. - hannibal2
++ Added debug messages to detect hot swaps. - hannibal2
++ Added /shdebugtablist
++ Set your clipboard as a fake tab list. - hannibal2
++ /shversion now copies the SkyHanni version into the clipboard as well. - hannibal2
++ Moved location fixes to the repo. - hannibal2
++ Added debug information for PetExpTooltip crash. - hannibal2
## Version 0.20
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 50fb6b668..25124fffa 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -131,7 +131,7 @@ folder for how to properly do this. You also may have to disable repo auto updat
### Discord IPC
DiscordIPC is a service that SkyHanni uses to send information from SkyBlock to Discord in Rich Presence. <br>
-Specifically, we use [TirelessTraveler's Fork](https://github.com/ILikePlayingGames/DiscordIPC) of a fork of a fork of
+Specifically, we use [NetheriteMiner's Fork](https://github.com/NetheriteMiner/DiscordIPC) of a fork of a fork of a fork of
the [original](https://github.com/jagrosh/DiscordIPC).
For info on usage, look
at [DiscordRPCManager.kt](https://github.com/hannibal002/SkyHanni/blob/beta/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordRPCManager.kt)
diff --git a/FEATURES.md b/FEATURES.md
index 459ac958a..b354e160d 100644
--- a/FEATURES.md
+++ b/FEATURES.md
@@ -224,6 +224,10 @@ Use `/sh` or `/skyhanni` to open the SkyHanni config in game.
+ Display the Hypixel timer until the fishing hook can be pulled out of the water/lava, only bigger and on your
screen.
+ Alerts when the player catches a Legendary Sea Creature. - Cad
++ **Fishing Bait Warnings.** - cimbraien
+ + Option to warn when no bait is used.
+ + Option to warn when used bait is changed.
+
</details>
<details open><summary>
@@ -480,6 +484,17 @@ Use `/sh` or `/skyhanni` to open the SkyHanni config in game.
+ **Visual garden plot borders** - VixidDev
+ Press F3 + G to enable/disable the view.
+ /shmouselock command to lock mouse rotation for farming. - Cad
++ Added Highlight Visitors in SkyBlock. - nea
+ + Highlights Visitors outside the Garden.
++ Block Interacting with Visitors. - nea
+ + Blocks you from interacting with / unlocking Visitors to allow for Dedication Cycling.
++ Wrong crop milestone step detection. - hannibal2
+ + When opening the crop milestone menu, a chat message is sent if Hypixel's crops per milestone level data is
+ different from SkyHanni's.
+ + 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.
+
</details>
<details open><summary>
@@ -582,6 +597,8 @@ Use `/sh` or `/skyhanni` to open the SkyHanni config in game.
+ Help with the 2023 Halloween visitor challenge (ephemeral dingsibumsi or something) - nea
+ New Visitor Ping: Pings you when you are less than 10 seconds away from getting a new visitor.
+ 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
</details>
<details open><summary>
@@ -624,6 +641,8 @@ Use `/sh` or `/skyhanni` to open the SkyHanni config in game.
+ Quest Item Helper. (Crimson Isle) - NetheriteMiner
+ When you open the fetch item quest in the town board, it shows a clickable chat message that will grab the items
needed from the sacks.
++ Crimson Isle **Pablo NPC Helper**. - NetheriteMiner
+ + Similar to Quest Item Helper, shows a clickable message that grabs the flower needed from sacks.
+ Red Scoreboard Numbers - Hides the red numbers in the scoreboard sidebar on the right side of the screen.
+ **Tia Relay Waypoint** - Show the next Relay waypoint for Tia The Fairy, where maintenance for the abiphone network
needs to be done.
diff --git a/README.md b/README.md
index b026a076a..ca6c1f486 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,5 @@
+
+
<h1 align = "center">
SkyHanni: Mod for Hypixel SkyBlock
</h1>
@@ -24,4 +26,6 @@ For bug reports, feature requests, and other feedback, please visit
our [Discord](https://discord.gg/skyhanni-997079228510117908).
If you are interested in the technical side of SkyHanni, read
-the [Contributing Guide](https://github.com/hannibal002/SkyHanni/blob/beta/CONTRIBUTING.md). \ No newline at end of file
+the [Contributing Guide](https://github.com/hannibal002/SkyHanni/blob/beta/CONTRIBUTING.md).
+
+*Check out some other really cool 1.8.9 mods [here](https://sbmw.ca/mod-lists/skyblock-mod-list/)*
diff --git a/build.gradle.kts b/build.gradle.kts
index cc4fdc04b..5abe8290f 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -11,7 +11,7 @@ plugins {
}
group = "at.hannibal2.skyhanni"
-version = "0.21.Beta.16"
+version = "0.21.1"
// Toolchains:
java {
@@ -57,7 +57,7 @@ dependencies {
forge("net.minecraftforge:forge:1.8.9-11.15.1.2318-1.8.9")
// Discord RPC client
- shadowImpl("com.github.ILikePlayingGames:DiscordIPC:f91ed4b") {
+ shadowImpl("com.github.NetheriteMiner:DiscordIPC:3106be5") {
exclude(module = "log4j")
because("Different version conflicts with Minecraft's Log4J")
exclude(module = "gson")
@@ -81,7 +81,7 @@ dependencies {
exclude(module = "unspecified")
isTransitive = false
}
- devenvMod("com.github.NotEnoughUpdates:NotEnoughUpdates:v2.1.1-alpha22:all") {
+ devenvMod("com.github.NotEnoughUpdates:NotEnoughUpdates:v2.1.1-pre4:all") {
exclude(module = "unspecified")
isTransitive = false
}
@@ -93,7 +93,7 @@ dependencies {
shadowImpl("org.jetbrains.kotlin:kotlin-reflect:1.9.0")
// testImplementation(kotlin("test"))
- testImplementation("com.github.NotEnoughUpdates:NotEnoughUpdates:v2.1.1-alpha22:all") {
+ testImplementation("com.github.NotEnoughUpdates:NotEnoughUpdates:v2.1.1-pre4:all") {
exclude(module = "unspecified")
isTransitive = false
}
@@ -188,7 +188,7 @@ tasks.shadowJar {
}
}
exclude("META-INF/versions/**")
-
+ mergeServiceFiles()
relocate("io.github.moulberry.moulconfig", "at.hannibal2.skyhanni.deps.moulconfig")
relocate("moe.nea.libautoupdate", "at.hannibal2.skyhanni.deps.libautoupdate")
}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index fe51b0357..0bdf7b127 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,7 +1,7 @@
[versions]
libautoupdate = "1.0.3"
-moulconfig = "1.3.0"
+moulconfig = "2.4.3"
[libraries]
-moulconfig = { module = "org.notenoughupdates.moulconfig:MoulConfig", version.ref = "moulconfig" }
+moulconfig = { module = "org.notenoughupdates.moulconfig:legacy", version.ref = "moulconfig" }
libautoupdate = { module = "moe.nea:libautoupdate", version.ref = "libautoupdate" }
diff --git a/src/main/java/SkyHanniInstallerFrame.java b/src/main/java/SkyHanniInstallerFrame.java
index ee94729ef..a1c0e3e50 100644
--- a/src/main/java/SkyHanniInstallerFrame.java
+++ b/src/main/java/SkyHanniInstallerFrame.java
@@ -166,8 +166,8 @@ public class SkyHanniInstallerFrame extends JFrame implements ActionListener, Mo
margin = 5;
BufferedImage myPicture = ImageIO.read(Objects.requireNonNull(getClass()
- .getClassLoader()
- .getResourceAsStream("assets/skyhanni/logo.png"), "Logo not found."));
+ .getClassLoader()
+ .getResourceAsStream("assets/skyhanni/logo.png"), "Logo not found."));
Image scaled = myPicture.getScaledInstance(w - margin * 2, h - margin, Image.SCALE_SMOOTH);
logo = new JLabel(new ImageIcon(scaled));
logo.setName("Logo");
@@ -222,8 +222,8 @@ public class SkyHanniInstallerFrame extends JFrame implements ActionListener, Mo
descriptionText.setOpaque(false);
descriptionText.setPreferredSize(new Dimension(w - margin * 2, h - margin));
descriptionText.setText(
- "This installer will copy SkyHanni into your forge mods folder for you, and replace any old versions that already exist. " +
- "Close this if you prefer to do this yourself!");
+ "This installer will copy SkyHanni into your forge mods folder for you, and replace any old versions that already exist. " +
+ "Close this if you prefer to do this yourself!");
descriptionText.setWrapStyleWord(true);
y += h;
@@ -251,7 +251,7 @@ public class SkyHanniInstallerFrame extends JFrame implements ActionListener, Mo
forgeDescriptionText.setOpaque(false);
forgeDescriptionText.setPreferredSize(new Dimension(w - margin * 2, h - margin));
forgeDescriptionText.setText(
- "However, you still need to install Forge client in order to be able to run this mod. Click here to visit the download page for Forge 1.8.9!");
+ "However, you still need to install Forge client in order to be able to run this mod. Click here to visit the download page for Forge 1.8.9!");
forgeDescriptionText.setForeground(Color.BLUE.darker());
forgeDescriptionText.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
forgeDescriptionText.setWrapStyleWord(true);
@@ -315,8 +315,8 @@ public class SkyHanniInstallerFrame extends JFrame implements ActionListener, Mo
try {
BufferedImage myPicture = ImageIO.read(Objects.requireNonNull(getClass()
- .getClassLoader()
- .getResourceAsStream("assets/skyhanni/folder.png"), "Folder icon not found."));
+ .getClassLoader()
+ .getResourceAsStream("assets/skyhanni/folder.png"), "Folder icon not found."));
Image scaled = myPicture.getScaledInstance(w - 8, h - 6, Image.SCALE_SMOOTH);
buttonChooseFolder = new JButton(new ImageIcon(scaled));
buttonChooseFolder.setName("ButtonFolder");
@@ -519,10 +519,10 @@ public class SkyHanniInstallerFrame extends JFrame implements ActionListener, Mo
} catch (Exception ex) {
ex.printStackTrace();
showErrorMessage("Was not able to delete the other SkyHanni files found in your mods folder!" +
- System.lineSeparator() +
- "Please make sure that your minecraft is currently closed and try again, or feel" +
- System.lineSeparator() +
- "free to open your mods folder and delete those files manually.");
+ System.lineSeparator() +
+ "Please make sure that your minecraft is currently closed and try again, or feel" +
+ System.lineSeparator() +
+ "free to open your mods folder and delete those files manually.");
return true;
}
continue;
@@ -667,10 +667,10 @@ public class SkyHanniInstallerFrame extends JFrame implements ActionListener, Mo
private File getThisFile() {
try {
return new File(SkyHanniInstallerFrame.class
- .getProtectionDomain()
- .getCodeSource()
- .getLocation()
- .toURI());
+ .getProtectionDomain()
+ .getCodeSource()
+ .getLocation()
+ .toURI());
} catch (URISyntaxException ex) {
showErrorPopup(ex);
}
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt
index 8a0805a77..f974d3d1d 100644
--- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt
+++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni
import at.hannibal2.skyhanni.api.CollectionAPI
+import at.hannibal2.skyhanni.config.ConfigFileType
import at.hannibal2.skyhanni.config.ConfigManager
import at.hannibal2.skyhanni.config.Features
import at.hannibal2.skyhanni.config.SackData
@@ -15,6 +16,7 @@ import at.hannibal2.skyhanni.data.EntityMovementData
import at.hannibal2.skyhanni.data.FriendAPI
import at.hannibal2.skyhanni.data.GardenComposterUpgradesData
import at.hannibal2.skyhanni.data.GardenCropMilestones
+import at.hannibal2.skyhanni.data.GardenCropMilestonesCommunityFix
import at.hannibal2.skyhanni.data.GardenCropUpgrades
import at.hannibal2.skyhanni.data.GuiEditManager
import at.hannibal2.skyhanni.data.GuildAPI
@@ -22,6 +24,7 @@ import at.hannibal2.skyhanni.data.HypixelData
import at.hannibal2.skyhanni.data.ItemClickData
import at.hannibal2.skyhanni.data.ItemRenderBackground
import at.hannibal2.skyhanni.data.ItemTipHelper
+import at.hannibal2.skyhanni.data.LocationFixData
import at.hannibal2.skyhanni.data.MayorElection
import at.hannibal2.skyhanni.data.MinecraftData
import at.hannibal2.skyhanni.data.OtherInventoryData
@@ -102,9 +105,12 @@ import at.hannibal2.skyhanni.features.event.diana.InquisitorWaypointShare
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.fame.AccountUpgradeReminder
import at.hannibal2.skyhanni.features.fame.CityProjectFeatures
import at.hannibal2.skyhanni.features.fishing.ChumBucketHider
+import at.hannibal2.skyhanni.features.fishing.FishingAPI
+import at.hannibal2.skyhanni.features.fishing.FishingBaitWarnings
import at.hannibal2.skyhanni.features.fishing.FishingHookDisplay
import at.hannibal2.skyhanni.features.fishing.FishingTimer
import at.hannibal2.skyhanni.features.fishing.SeaCreatureFeatures
@@ -136,10 +142,10 @@ import at.hannibal2.skyhanni.features.garden.contest.JacobContestFFNeededDisplay
import at.hannibal2.skyhanni.features.garden.contest.JacobContestStatsSummary
import at.hannibal2.skyhanni.features.garden.contest.JacobContestTimeNeeded
import at.hannibal2.skyhanni.features.garden.contest.JacobFarmingContestsInventory
+import at.hannibal2.skyhanni.features.garden.farming.ArmorDropTracker
import at.hannibal2.skyhanni.features.garden.farming.CropMoneyDisplay
import at.hannibal2.skyhanni.features.garden.farming.CropSpeedMeter
-import at.hannibal2.skyhanni.features.garden.farming.DicerRngDropCounter
-import at.hannibal2.skyhanni.features.garden.farming.FarmingArmorDrops
+import at.hannibal2.skyhanni.features.garden.farming.DicerDropTracker
import at.hannibal2.skyhanni.features.garden.farming.FarmingWeightDisplay
import at.hannibal2.skyhanni.features.garden.farming.GardenBurrowingSporesNotifier
import at.hannibal2.skyhanni.features.garden.farming.GardenCropMilestoneDisplay
@@ -160,6 +166,7 @@ import at.hannibal2.skyhanni.features.garden.visitor.GardenVisitorColorNames
import at.hannibal2.skyhanni.features.garden.visitor.GardenVisitorDropStatistics
import at.hannibal2.skyhanni.features.garden.visitor.GardenVisitorFeatures
import at.hannibal2.skyhanni.features.garden.visitor.GardenVisitorTimer
+import at.hannibal2.skyhanni.features.garden.visitor.HighlightVisitorsOutsideOfGarden
import at.hannibal2.skyhanni.features.garden.visitor.VisitorListener
import at.hannibal2.skyhanni.features.inventory.AuctionsHighlighter
import at.hannibal2.skyhanni.features.inventory.ChestValue
@@ -233,6 +240,7 @@ import at.hannibal2.skyhanni.features.misc.trevor.TrevorSolver
import at.hannibal2.skyhanni.features.misc.trevor.TrevorTracker
import at.hannibal2.skyhanni.features.misc.update.UpdateManager
import at.hannibal2.skyhanni.features.misc.visualwords.ModifyVisualWords
+import at.hannibal2.skyhanni.features.nether.PabloHelper
import at.hannibal2.skyhanni.features.nether.QuestItemHelper
import at.hannibal2.skyhanni.features.nether.ashfang.AshfangBlazes
import at.hannibal2.skyhanni.features.nether.ashfang.AshfangBlazingSouls
@@ -243,7 +251,6 @@ import at.hannibal2.skyhanni.features.nether.ashfang.AshfangHideParticles
import at.hannibal2.skyhanni.features.nether.ashfang.AshfangNextResetCooldown
import at.hannibal2.skyhanni.features.nether.reputationhelper.CrimsonIsleReputationHelper
import at.hannibal2.skyhanni.features.rift.RiftAPI
-import at.hannibal2.skyhanni.features.rift.area.RiftLarva
import at.hannibal2.skyhanni.features.rift.area.colosseum.BlobbercystsHighlight
import at.hannibal2.skyhanni.features.rift.area.dreadfarm.RiftAgaricusCap
import at.hannibal2.skyhanni.features.rift.area.dreadfarm.RiftWiltedBerberisHelper
@@ -257,6 +264,7 @@ import at.hannibal2.skyhanni.features.rift.area.mirrorverse.RiftUpsideDownParkou
import at.hannibal2.skyhanni.features.rift.area.mirrorverse.TubulatorParkour
import at.hannibal2.skyhanni.features.rift.area.stillgorechateau.RiftBloodEffigies
import at.hannibal2.skyhanni.features.rift.area.westvillage.KloonHacking
+import at.hannibal2.skyhanni.features.rift.area.wyldwoods.RiftLarva
import at.hannibal2.skyhanni.features.rift.area.wyldwoods.RiftOdonata
import at.hannibal2.skyhanni.features.rift.area.wyldwoods.ShyCruxWarnings
import at.hannibal2.skyhanni.features.rift.everywhere.CruxTalismanDisplay
@@ -268,9 +276,9 @@ import at.hannibal2.skyhanni.features.rift.everywhere.motes.RiftMotesOrb
import at.hannibal2.skyhanni.features.rift.everywhere.motes.ShowMotesNpcSellPrice
import at.hannibal2.skyhanni.features.slayer.HideMobNames
import at.hannibal2.skyhanni.features.slayer.SlayerBossSpawnSoon
-import at.hannibal2.skyhanni.features.slayer.SlayerItemProfitTracker
import at.hannibal2.skyhanni.features.slayer.SlayerItemsOnGround
import at.hannibal2.skyhanni.features.slayer.SlayerMiniBossFeatures
+import at.hannibal2.skyhanni.features.slayer.SlayerProfitTracker
import at.hannibal2.skyhanni.features.slayer.SlayerQuestWarning
import at.hannibal2.skyhanni.features.slayer.SlayerRngMeterDisplay
import at.hannibal2.skyhanni.features.slayer.VampireSlayerFeatures
@@ -284,6 +292,7 @@ import at.hannibal2.skyhanni.features.summonings.SummoningMobManager
import at.hannibal2.skyhanni.features.summonings.SummoningSoulsName
import at.hannibal2.skyhanni.mixins.hooks.RenderLivingEntityHelper
import at.hannibal2.skyhanni.test.HighlightMissingRepoItems
+import at.hannibal2.skyhanni.test.HotSwapDetection
import at.hannibal2.skyhanni.test.PacketTest
import at.hannibal2.skyhanni.test.ParkourWaypointSaver
import at.hannibal2.skyhanni.test.ShowItemUuid
@@ -299,6 +308,9 @@ 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
@@ -320,7 +332,7 @@ import org.apache.logging.log4j.Logger
clientSideOnly = true,
useMetadata = true,
guiFactory = "at.hannibal2.skyhanni.config.ConfigGuiForgeInterop",
- version = "0.21.Beta.16",
+ version = "0.21.1",
)
class SkyHanniMod {
@Mod.EventHandler
@@ -331,6 +343,7 @@ class SkyHanniMod {
loadModule(this)
loadModule(ChatManager)
loadModule(HypixelData())
+ loadModule(LocationFixData)
loadModule(DungeonAPI())
loadModule(ScoreboardData())
loadModule(SeaCreatureFeatures())
@@ -350,10 +363,12 @@ class SkyHanniMod {
loadModule(TabListData())
loadModule(RenderData())
loadModule(GardenCropMilestones)
+ loadModule(GardenCropMilestonesCommunityFix)
loadModule(GardenCropUpgrades())
loadModule(VisitorListener())
loadModule(OwnInventoryData())
loadModule(ToolTipData())
+ loadModule(HighlightVisitorsOutsideOfGarden())
loadModule(GuiEditManager())
loadModule(UpdateManager)
loadModule(CropAccessoryData())
@@ -375,7 +390,7 @@ class SkyHanniMod {
loadModule(GardenAPI)
loadModule(CollectionAPI())
loadModule(FarmingContestAPI)
- loadModule(FriendAPI())
+ loadModule(FriendAPI)
loadModule(PartyAPI)
loadModule(GuildAPI)
loadModule(SlayerAPI)
@@ -383,6 +398,7 @@ class SkyHanniMod {
loadModule(RiftAPI)
loadModule(SackAPI)
loadModule(BingoAPI)
+ loadModule(FishingAPI)
// features
loadModule(BazaarOrderHelper())
@@ -455,6 +471,7 @@ class SkyHanniMod {
loadModule(NonGodPotEffectDisplay())
loadModule(SoopyGuessBurrow())
loadModule(HighlightJerries())
+ loadModule(TheGreatSpook())
loadModule(GriffinBurrowHelper)
loadModule(GriffinBurrowParticleFinder())
loadModule(BurrowWarpHelper())
@@ -492,12 +509,12 @@ class SkyHanniMod {
loadModule(GardenDeskInSBMenu())
loadModule(GardenLevelDisplay())
loadModule(FarmingWeightDisplay())
- loadModule(DicerRngDropCounter())
+ loadModule(DicerDropTracker)
loadModule(CropMoneyDisplay)
loadModule(JacobFarmingContestsInventory())
loadModule(GardenNextJacobContest)
loadModule(WrongFungiCutterWarning())
- loadModule(FarmingArmorDrops())
+ loadModule(ArmorDropTracker)
loadModule(JoinCrystalHollows())
loadModule(CrystalHollowsNamesInCore())
loadModule(GardenVisitorColorNames)
@@ -546,13 +563,13 @@ class SkyHanniMod {
loadModule(WarpTabComplete)
loadModule(PlayerTabComplete)
loadModule(GetFromSacksTabComplete)
- loadModule(SlayerItemProfitTracker)
+ loadModule(SlayerProfitTracker)
loadModule(SlayerItemsOnGround())
loadModule(RestorePieceOfWizardPortalLore())
loadModule(QuickModMenuSwitch)
loadModule(ArachneChatMessageHider())
loadModule(ShowItemUuid())
- loadModule(FrozenTreasureTracker())
+ loadModule(FrozenTreasureTracker)
loadModule(SlayerRngMeterDisplay())
loadModule(GhostCounter)
loadModule(RiftTimer())
@@ -587,8 +604,8 @@ class SkyHanniMod {
loadModule(GriffinPetWarning())
loadModule(BestiaryData)
loadModule(KingTalismanHelper())
- loadModule(HarpFeatures())
- loadModule(EnderNodeTracker())
+ loadModule(HarpFeatures)
+ loadModule(EnderNodeTracker)
loadModule(CompactBestiaryChatMessage())
loadModule(WatchdogHider())
loadModule(AccountUpgradeReminder())
@@ -597,7 +614,7 @@ class SkyHanniMod {
loadModule(GardenPlotBorders())
loadModule(CosmeticFollowingLine())
loadModule(SuperpairsClicksAlert())
- loadModule(PowderTracker())
+ loadModule(PowderTracker)
loadModule(ModifyVisualWords)
loadModule(TabListReader)
loadModule(TabListRenderer)
@@ -615,6 +632,8 @@ class SkyHanniMod {
loadModule(ShiftClickEquipment())
loadModule(LockMouseLook)
loadModule(DungeonFinderFeatures())
+ loadModule(PabloHelper())
+ loadModule(FishingBaitWarnings())
init()
@@ -629,6 +648,8 @@ class SkyHanniMod {
loadModule(HighlightMissingRepoItems())
loadModule(ParkourWaypointSaver())
loadModule(TestShowSlotNumber())
+ loadModule(SkyHanniDebugsAndTests)
+ loadModule(HotSwapDetection)
}
@Mod.EventHandler
@@ -637,9 +658,9 @@ class SkyHanniMod {
configManager.firstLoad()
initLogging()
Runtime.getRuntime().addShutdownHook(Thread {
- configManager.saveConfig("shutdown-hook")
+ configManager.saveConfig(ConfigFileType.FEATURES, "shutdown-hook")
})
- repo = RepoManager(configManager.configDirectory)
+ repo = RepoManager(ConfigManager.configDirectory)
try {
repo.loadRepoInformation()
} catch (e: Exception) {
@@ -657,6 +678,7 @@ class SkyHanniMod {
if (screenToOpen != null) {
screenTicks++
if (screenTicks == 5) {
+ Minecraft.getMinecraft().thePlayer.closeScreen()
Minecraft.getMinecraft().displayGuiScreen(screenToOpen)
screenTicks = 0
screenToOpen = null
@@ -674,6 +696,10 @@ class SkyHanniMod {
@JvmStatic
val feature: Features get() = configManager.features
val sackData: SackData get() = configManager.sackData
+ val friendsData: FriendsJson get() = configManager.friendsData
+ val knownFeaturesData: KnownFeaturesJson get() = configManager.knownFeaturesData
+ val jacobContestsData: JacobContestsJson get() = configManager.jacobContestData
+
lateinit var repo: RepoManager
lateinit var configManager: ConfigManager
val logger: Logger = LogManager.getLogger("SkyHanni")
@@ -682,7 +708,7 @@ class SkyHanniMod {
}
val modules: MutableList<Any> = ArrayList()
- val globalJob: Job = Job(null)
+ private val globalJob: Job = Job(null)
val coroutineScope = CoroutineScope(
CoroutineName("SkyHanni") + SupervisorJob(globalJob)
)
diff --git a/src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt b/src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt
index 2476cbe73..cd7fa0c59 100644
--- a/src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt
@@ -3,6 +3,7 @@ package at.hannibal2.skyhanni.api
import at.hannibal2.skyhanni.events.CollectionUpdateEvent
import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
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
@@ -11,6 +12,7 @@ import at.hannibal2.skyhanni.utils.NEUInternalName
import at.hannibal2.skyhanni.utils.NEUItems
import at.hannibal2.skyhanni.utils.NEUItems.getItemStackOrNull
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
+import at.hannibal2.skyhanni.utils.StringUtils.matches
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
@@ -66,22 +68,24 @@ class CollectionAPI {
}
}
+ @SubscribeEvent
+ fun onItemAdd(event: ItemAddInInventoryEvent) {
+ // TODO add support for replenish (higher collection than actual items in inv)
+ val internalName = event.internalName
+ if (internalName.getItemStackOrNull() == null) {
+ LorenzUtils.debug("CollectionAPI.addFromInventory: item is null for '$internalName'")
+ return
+ }
+ collectionValue.addOrPut(internalName, event.amount.toLong())
+ }
+
companion object {
// TODO USE SH-REPO
val collectionValue = mutableMapOf<NEUInternalName, Long>()
private val collectionTier0Pattern = "§7Progress to .* I: .*".toPattern()
- fun isCollectionTier0(lore: List<String>) = lore.map { collectionTier0Pattern.matcher(it) }.any { it.matches() }
+ fun isCollectionTier0(lore: List<String>) = lore.any { collectionTier0Pattern.matches(it) }
fun getCollectionCounter(internalName: NEUInternalName): Long? = collectionValue[internalName]
-
- // TODO add support for replenish (higher collection than actual items in inv)
- fun addFromInventory(internalName: NEUInternalName, amount: Int) {
- if (internalName.getItemStackOrNull() == null) {
- LorenzUtils.debug("CollectionAPI.addFromInventory: item is null for '$internalName'")
- return
- }
- collectionValue.addOrPut(internalName, amount.toLong())
- }
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt b/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt
index bfbeb08df..ddd51b18f 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt
@@ -1,8 +1,8 @@
package at.hannibal2.skyhanni.config
import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.features.fishing.trophy.TrophyRarity
-import at.hannibal2.skyhanni.features.garden.CropType
import at.hannibal2.skyhanni.features.misc.update.UpdateManager
import at.hannibal2.skyhanni.utils.LorenzLogger
import at.hannibal2.skyhanni.utils.LorenzRarity
@@ -10,6 +10,9 @@ 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 com.google.gson.GsonBuilder
import com.google.gson.JsonObject
import com.google.gson.TypeAdapter
@@ -93,142 +96,121 @@ class ConfigManager {
}
override fun read(reader: JsonReader): LorenzRarity {
- return LorenzRarity.valueOf(reader.nextString())
+ return LorenzRarity.valueOf(reader.nextString().uppercase())
+ }
+ }.nullSafe())
+ .registerTypeAdapter(IslandType::class.java, object : TypeAdapter<IslandType>() {
+ override fun write(out: JsonWriter, value: IslandType) {
+ out.value(value.name)
+ }
+
+ override fun read(reader: JsonReader): IslandType {
+ return IslandType.valueOf(reader.nextString().uppercase())
}
}.nullSafe())
.enableComplexMapKeySerialization()
.create()
+
+ var configDirectory = File("config/skyhanni")
}
- lateinit var features: Features
- lateinit var sackData: SackData
- private set
+ val features get() = jsonHolder[ConfigFileType.FEATURES] as Features
+ val sackData get() = jsonHolder[ConfigFileType.SACKS] as SackData
+ val friendsData get() = jsonHolder[ConfigFileType.FRIENDS] as FriendsJson
+ val knownFeaturesData get() = jsonHolder[ConfigFileType.KNOWN_FEATURES] as KnownFeaturesJson
+ val jacobContestData get() = jsonHolder[ConfigFileType.JACOB_CONTESTS] as JacobContestsJson
+
private val logger = LorenzLogger("config_manager")
- var configDirectory = File("config/skyhanni")
- private var configFile: File? = null
- private var sackFile: File? = null
+ private val jsonHolder = mutableMapOf<ConfigFileType, Any>()
+
lateinit var processor: MoulConfigProcessor<Features>
private var disableSaving = false
fun firstLoad() {
- if (::features.isInitialized) {
+ if (jsonHolder.isNotEmpty()) {
logger.log("Loading config despite config being already loaded?")
}
- configDirectory.mkdir()
+ configDirectory.mkdirs()
- configFile = File(configDirectory, "config.json")
- sackFile = File(configDirectory, "sacks.json")
- logger.log("Trying to load config from $configFile")
+ for (fileType in ConfigFileType.entries) {
+ jsonHolder[fileType] = firstLoadFile(fileType.file, fileType, fileType.clazz.newInstance())
+ }
- if (configFile!!.exists()) {
+ fixedRateTimer(name = "skyhanni-config-auto-save", period = 60_000L, initialDelay = 60_000L) {
+ saveConfig(ConfigFileType.FEATURES, "auto-save-60s")
+ }
+
+ val features = SkyHanniMod.feature
+ processor = MoulConfigProcessor(SkyHanniMod.feature)
+ BuiltinMoulConfigGuis.addProcessors(processor)
+ UpdateManager.injectConfigProcessor(processor)
+ ConfigProcessorDriver.processConfig(
+ features.javaClass,
+ features,
+ processor
+ )
+ }
+
+ private fun firstLoadFile(file: File?, fileType: ConfigFileType, defaultValue: Any): Any {
+ val fileName = fileType.fileName
+ logger.log("Trying to load $fileName from $file")
+ var output: Any = defaultValue
+
+ if (file!!.exists()) {
try {
- val inputStreamReader = InputStreamReader(FileInputStream(configFile!!), StandardCharsets.UTF_8)
+ val inputStreamReader = InputStreamReader(FileInputStream(file), StandardCharsets.UTF_8)
val bufferedReader = BufferedReader(inputStreamReader)
- val builder = StringBuilder()
- for (line in bufferedReader.lines()) {
- val result = fixConfig(line)
- builder.append(result)
- builder.append("\n")
- }
+ logger.log("load-$fileName-now")
- logger.log("load-config-now")
- val jsonObject = gson.fromJson(builder.toString(), JsonObject::class.java)
- val newJsonObject = ConfigUpdaterMigrator.fixConfig(jsonObject)
- features = gson.fromJson(
- newJsonObject,
- Features::class.java
- )
- logger.log("Loaded config from file")
+ output = if (fileType == ConfigFileType.FEATURES) {
+ val jsonObject = gson.fromJson(bufferedReader.readText(), JsonObject::class.java)
+ val newJsonObject = ConfigUpdaterMigrator.fixConfig(jsonObject)
+ gson.fromJson(newJsonObject, defaultValue.javaClass)
+ } else {
+ gson.fromJson(bufferedReader.readText(), defaultValue.javaClass)
+ }
+
+ logger.log("Loaded $fileName from file")
} catch (error: Exception) {
error.printStackTrace()
- val backupFile = configFile!!.resolveSibling("config-${System.currentTimeMillis()}-backup.json")
- logger.log("Exception while reading $configFile. Will load blank config and save backup to $backupFile")
+ val backupFile = file.resolveSibling("$fileName-${System.currentTimeMillis()}-backup.json")
+ logger.log("Exception while reading $file. Will load blank $fileName and save backup to $backupFile")
logger.log("Exception was $error")
try {
- configFile!!.copyTo(backupFile)
+ file.copyTo(backupFile)
} catch (e: Exception) {
- logger.log("Could not create backup for config file")
+ logger.log("Could not create backup for $fileName file")
e.printStackTrace()
}
}
}
- if (sackFile!!.exists()) {
- try {
- val inputStreamReader = InputStreamReader(FileInputStream(sackFile!!), StandardCharsets.UTF_8)
- val bufferedReader = BufferedReader(inputStreamReader)
- val builder = StringBuilder()
- for (line in bufferedReader.lines()) {
- builder.append(line)
- builder.append("\n")
- }
-
-
- logger.log("load-sacks-now")
- sackData = gson.fromJson(
- builder.toString(),
- SackData::class.java
- )
- logger.log("Loaded sacks from file")
- } catch (error: Exception) {
- error.printStackTrace()
- }
- }
-
- if (!::features.isInitialized) {
- logger.log("Creating blank config and saving to file")
- features = Features()
- saveConfig("blank config")
- }
-
- fixedRateTimer(name = "skyhanni-config-auto-save", period = 60_000L, initialDelay = 60_000L) {
- saveConfig("auto-save-60s")
- }
-
- if (!::sackData.isInitialized) {
- logger.log("Creating blank sack data and saving")
- sackData = SackData()
- saveSackData("blank config")
+ if (output == defaultValue) {
+ logger.log("Setting $fileName to be blank as it did not exist. It will be saved once something is written to it")
}
- val features = SkyHanniMod.feature
- processor = MoulConfigProcessor(SkyHanniMod.feature)
- BuiltinMoulConfigGuis.addProcessors(processor)
- UpdateManager.injectConfigProcessor(processor)
- ConfigProcessorDriver.processConfig(
- features.javaClass,
- features,
- processor
- )
+ return output
}
- private fun fixConfig(line: String): String {
- var result = line
- for (type in CropType.entries) {
- val normal = "\"${type.cropName}\""
- val enumName = "\"${type.name}\""
- while (result.contains(normal)) {
- result = result.replace(normal, enumName)
- }
- }
- return result
+ fun saveConfig(fileType: ConfigFileType, reason: String) {
+ val json = jsonHolder[fileType] ?: error("Could not find json object for $fileType")
+ saveFile(fileType.file, fileType.fileName, json, reason)
}
- fun saveConfig(reason: String) {
+ private fun saveFile(file: File?, fileName: String, data: Any, reason: String) {
if (disableSaving) return
logger.log("saveConfig: $reason")
- val file = configFile ?: throw Error("Can not save config, configFile is null!")
+ if (file == null) throw Error("Can not save $fileName, ${fileName}File is null!")
try {
- logger.log("Saving config file")
+ logger.log("Saving $fileName file")
file.parentFile.mkdirs()
- val unit = file.parentFile.resolve("config.json.write")
+ val unit = file.parentFile.resolve("$fileName.json.write")
unit.createNewFile()
BufferedWriter(OutputStreamWriter(FileOutputStream(unit), StandardCharsets.UTF_8)).use { writer ->
- // TODO remove old "hidden" area
- writer.write(gson.toJson(SkyHanniMod.feature))
+ writer.write(gson.toJson(data))
}
// Perform move — which is atomic, unlike writing — after writing is done.
Files.move(
@@ -238,24 +220,7 @@ class ConfigManager {
StandardCopyOption.ATOMIC_MOVE
)
} catch (e: IOException) {
- logger.log("Could not save config file to $file")
- e.printStackTrace()
- }
- }
-
- fun saveSackData(reason: String) {
- if (disableSaving) return
- logger.log("saveSackData: $reason")
- val file = sackFile ?: throw Error("Can not save sacks, sackFile is null!")
- try {
- logger.log("Saving sack file")
- file.parentFile.mkdirs()
- file.createNewFile()
- BufferedWriter(OutputStreamWriter(FileOutputStream(file), StandardCharsets.UTF_8)).use { writer ->
- writer.write(gson.toJson(SkyHanniMod.sackData))
- }
- } catch (e: IOException) {
- logger.log("Could not save sacks file to $file")
+ logger.log("Could not save $fileName file to $file")
e.printStackTrace()
}
}
@@ -264,3 +229,14 @@ class ConfigManager {
disableSaving = true
}
}
+
+enum class ConfigFileType(val fileName: String, val clazz: Class<*>) {
+ FEATURES("config", Features::class.java),
+ SACKS("sacks", SackData::class.java),
+ FRIENDS("friends", FriendsJson::class.java),
+ KNOWN_FEATURES("known_features", KnownFeaturesJson::class.java),
+ JACOB_CONTESTS("jacob_contests", JacobContestsJson::class.java),
+ ;
+
+ val file by lazy { File(ConfigManager.configDirectory, "$fileName.json") }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt b/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt
index 69a77d6df..0db542e12 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")
- val configVersion = 6
+ const val CONFIG_VERSION = 9
fun JsonElement.at(chain: List<String>, init: Boolean): JsonElement? {
if (chain.isEmpty()) return this
if (this !is JsonObject) return null
@@ -26,14 +26,21 @@ object ConfigUpdaterMigrator {
val new: JsonObject,
val oldVersion: Int,
var movesPerformed: Int,
+ val dynamicPrefix: Map<String, List<String>>,
) : LorenzEvent() {
+ init {
+ dynamicPrefix.entries.filter { it.value.isEmpty() }.forEach {
+ logger.log("Dynamic prefix ${it.key} does not resolve to anything.")
+ }
+ }
+
fun move(since: Int, oldPath: String, newPath: String, transform: (JsonElement) -> JsonElement = { it }) {
if (since <= oldVersion) {
logger.log("Skipping move from $oldPath to $newPath ($since <= $oldVersion)")
return
}
- if (since > configVersion) {
- error("Illegally new version $since > $configVersion")
+ if (since > CONFIG_VERSION) {
+ error("Illegally new version $since > $CONFIG_VERSION")
}
if (since > oldVersion + 1) {
logger.log("Skipping move from $oldPath to $newPath (will be done in another pass)")
@@ -41,51 +48,81 @@ object ConfigUpdaterMigrator {
}
val op = oldPath.split(".")
val np = newPath.split(".")
+ if (op.first().startsWith("#")) {
+ require(np.first() == op.first())
+ val realPrefixes = dynamicPrefix[op.first()]
+ if (realPrefixes == null) {
+ logger.log("Could not resolve dynamic prefix $oldPath")
+ return
+ }
+ for (realPrefix in realPrefixes) {
+ move(
+ since,
+ "$realPrefix.${oldPath.substringAfter('.')}",
+ "$realPrefix.${newPath.substringAfter('.')}", transform
+ )
+ return
+ }
+ }
val oldElem = old.at(op, false)
if (oldElem == null) {
logger.log("Skipping move from $oldPath to $newPath ($oldPath not present)")
return
}
- val x = new.at(np.dropLast(1), true)
- if (x !is JsonObject) {
+ val newParentElement = new.at(np.dropLast(1), true)
+ if (newParentElement !is JsonObject) {
logger.log("Catastrophic: element at path $old could not be relocated to $new, since another element already inhabits that path")
return
}
movesPerformed++
- x.add(np.last(), transform(oldElem))
+ newParentElement.add(np.last(), transform(oldElem))
logger.log("Moved element from $oldPath to $newPath")
}
}
- fun merge(a: JsonObject, b: JsonObject): Int {
- var c = 0
- b.entrySet().forEach {
- val e = a.get(it.key)
- val n = it.value
- if (e is JsonObject && n is JsonObject) {
- c += merge(e, n)
+ private fun merge(originalObject: JsonObject, overrideObject: JsonObject): Int {
+ var count = 0
+ overrideObject.entrySet().forEach {
+ val element = originalObject.get(it.key)
+ val newElement = it.value
+ if (element is JsonObject && newElement is JsonObject) {
+ count += merge(element, newElement)
} else {
- if (e != null) {
- logger.log("Encountered destructive merge. Erasing $e in favour of $n.")
- c++
+ if (element != null) {
+ logger.log("Encountered destructive merge. Erasing $element in favour of $newElement.")
+ count++
}
- a.add(it.key, n)
+ originalObject.add(it.key, newElement)
}
}
- return c
+ return count
}
fun fixConfig(config: JsonObject): JsonObject {
- val lV = (config.get("lastVersion") as? JsonPrimitive)?.asIntOrNull ?: -1
- if (lV > configVersion) {
+ val lastVersion = (config.get("lastVersion") as? JsonPrimitive)?.asIntOrNull ?: -1
+ if (lastVersion > CONFIG_VERSION) {
error("Cannot downgrade config")
}
- if (lV == configVersion) return config
- return (lV until configVersion).fold(config) { acc, i ->
+ if (lastVersion == CONFIG_VERSION) return config
+ return (lastVersion until CONFIG_VERSION).fold(config) { accumulator, i ->
logger.log("Starting config transformation from $i to ${i + 1}")
- val migration = ConfigFixEvent(acc, JsonObject().also {
+ val storage = accumulator.get("storage")?.asJsonObject
+ val dynamicPrefix: Map<String, List<String>> = mapOf(
+ "#profile" to
+ (storage?.get("players")?.asJsonObject?.entrySet()
+ ?.flatMap { player ->
+ player.value.asJsonObject.get("profiles")?.asJsonObject?.entrySet()?.map {
+ "storage.players.${player.key}.profiles.${it.key}"
+ } ?: listOf()
+ }
+ ?: listOf()),
+ "#player" to
+ (storage?.get("players")?.asJsonObject?.entrySet()?.map { "storage.players.${it.key}" }
+ ?: listOf()),
+ )
+ val migration = ConfigFixEvent(accumulator, JsonObject().also {
it.add("lastVersion", JsonPrimitive(i + 1))
- }, i, 0).also { it.postAndCatch() }
+ }, i, 0, dynamicPrefix).also { it.postAndCatch() }
logger.log("Transformations scheduled: ${migration.new}")
val mergesPerformed = merge(migration.old, migration.new)
logger.log("Migration done with $mergesPerformed merges and ${migration.movesPerformed} moves performed")
diff --git a/src/main/java/at/hannibal2/skyhanni/config/Features.java b/src/main/java/at/hannibal2/skyhanni/config/Features.java
index f5916cda8..bb0861e83 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/Features.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/Features.java
@@ -2,27 +2,26 @@ package at.hannibal2.skyhanni.config;
import at.hannibal2.skyhanni.SkyHanniMod;
import at.hannibal2.skyhanni.config.features.About;
-import at.hannibal2.skyhanni.config.features.BazaarConfig;
-import at.hannibal2.skyhanni.config.features.ChatConfig;
-import at.hannibal2.skyhanni.config.features.ChromaConfig;
-import at.hannibal2.skyhanni.config.features.CombatConfig;
-import at.hannibal2.skyhanni.config.features.CommandsConfig;
-import at.hannibal2.skyhanni.config.features.CrimsonIsleConfig;
-import at.hannibal2.skyhanni.config.features.DevConfig;
-import at.hannibal2.skyhanni.config.features.DungeonConfig;
-import at.hannibal2.skyhanni.config.features.EventConfig;
-import at.hannibal2.skyhanni.config.features.FishingConfig;
-import at.hannibal2.skyhanni.config.features.GUIConfig;
-import at.hannibal2.skyhanni.config.features.GardenConfig;
-import at.hannibal2.skyhanni.config.features.InventoryConfig;
-import at.hannibal2.skyhanni.config.features.ItemAbilityConfig;
-import at.hannibal2.skyhanni.config.features.MarkedPlayerConfig;
-import at.hannibal2.skyhanni.config.features.MiningConfig;
-import at.hannibal2.skyhanni.config.features.MinionsConfig;
-import at.hannibal2.skyhanni.config.features.MiscConfig;
-import at.hannibal2.skyhanni.config.features.OldHidden;
-import at.hannibal2.skyhanni.config.features.RiftConfig;
-import at.hannibal2.skyhanni.config.features.SlayerConfig;
+import at.hannibal2.skyhanni.config.features.bazaar.BazaarConfig;
+import at.hannibal2.skyhanni.config.features.chat.ChatConfig;
+import at.hannibal2.skyhanni.config.features.chroma.ChromaConfig;
+import at.hannibal2.skyhanni.config.features.combat.CombatConfig;
+import at.hannibal2.skyhanni.config.features.commands.CommandsConfig;
+import at.hannibal2.skyhanni.config.features.crimsonisle.CrimsonIsleConfig;
+import at.hannibal2.skyhanni.config.features.dev.DevConfig;
+import at.hannibal2.skyhanni.config.features.dungeon.DungeonConfig;
+import at.hannibal2.skyhanni.config.features.event.EventConfig;
+import at.hannibal2.skyhanni.config.features.fishing.FishingConfig;
+import at.hannibal2.skyhanni.config.features.gui.GUIConfig;
+import at.hannibal2.skyhanni.config.features.garden.GardenConfig;
+import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig;
+import at.hannibal2.skyhanni.config.features.itemability.ItemAbilityConfig;
+import at.hannibal2.skyhanni.config.features.markedplayer.MarkedPlayerConfig;
+import at.hannibal2.skyhanni.config.features.mining.MiningConfig;
+import at.hannibal2.skyhanni.config.features.minion.MinionsConfig;
+import at.hannibal2.skyhanni.config.features.misc.MiscConfig;
+import at.hannibal2.skyhanni.config.features.rift.RiftConfig;
+import at.hannibal2.skyhanni.config.features.slayer.SlayerConfig;
import com.google.gson.annotations.Expose;
import io.github.moulberry.moulconfig.Config;
import io.github.moulberry.moulconfig.Social;
@@ -45,14 +44,14 @@ public class Features extends Config {
@Override
public List<Social> getSocials() {
return Arrays.asList(
- Social.forLink("Join our Discord", DISCORD, "https://discord.com/invite/skyhanni-997079228510117908"),
- Social.forLink("Look at the code", GITHUB, "https://github.com/hannibal002/SkyHanni")
+ Social.forLink("Join our Discord", DISCORD, "https://discord.com/invite/skyhanni-997079228510117908"),
+ Social.forLink("Look at the code", GITHUB, "https://github.com/hannibal002/SkyHanni")
);
}
@Override
public void saveNow() {
- SkyHanniMod.configManager.saveConfig("close-gui");
+ SkyHanniMod.configManager.saveConfig(ConfigFileType.FEATURES, "close-gui");
}
@Override
@@ -60,77 +59,83 @@ public class Features extends Config {
return "SkyHanni " + SkyHanniMod.getVersion() + " by §channibal2§r, config by §5Moulberry §rand §5nea89";
}
+ /*
+ * If you are adding a new category, please insert it alphabetically
+ * The only exceptions to this are About and GUI, which are pinned to the top
+ * and Misc and Dev, which are to be at the bottom. Thanks!
+ */
+
@Expose
- @Category(name = "About", desc = "Information about SkyHanni and updates")
+ @Category(name = "About", desc = "Information about SkyHanni and updates.")
public About about = new About();
@Expose
- @Category(name = "GUI", desc = "Change the locations of GUI elements. (§e/sh gui§7)")
+ @Category(name = "GUI", desc = "Change the locations of GUI elements (§e/sh gui§7).")
public GUIConfig gui = new GUIConfig();
@Expose
- @Category(name = "Chroma", desc = "Settings for Chroma text. (Credit to SBA)")
- public ChromaConfig chroma = new ChromaConfig();
+ @Category(name = "Bazaar", desc = "Bazaar settings.")
+ public BazaarConfig bazaar = new BazaarConfig();
@Expose
@Category(name = "Chat", desc = "Change how the chat looks.")
public ChatConfig chat = new ChatConfig();
@Expose
- @Category(name = "Dungeon", desc = "Features that change the Dungeons experience in The Catacombs.")
- public DungeonConfig dungeon = new DungeonConfig();
+ @Category(name = "Chroma", desc = "Settings for Chroma text (Credit to SBA).")
+ public ChromaConfig chroma = new ChromaConfig();
@Expose
- @Category(name = "Inventory", desc = "Change the behavior of items and the inventory.")
- public InventoryConfig inventory = new InventoryConfig();
+ @Category(name = "Combat", desc = "Everything combat and PvE related.")
+ public CombatConfig combat = new CombatConfig();
@Expose
- @Category(name = "Item Abilities", desc = "Stuff about item abilities.")
- public ItemAbilityConfig itemAbilities = new ItemAbilityConfig();
+ @Category(name = "Commands", desc = "Enable or disable commands.")
+ public CommandsConfig commands = new CommandsConfig();
@Expose
@Category(name = "Crimson Isle", desc = "Things to do on the Crimson Isle/Nether island.")
public CrimsonIsleConfig crimsonIsle = new CrimsonIsleConfig();
@Expose
- @Category(name = "Minion", desc = "The minions on your private island.")
- public MinionsConfig minions = new MinionsConfig();
+ @Category(name = "Dungeon", desc = "Features that change the Dungeons experience in The Catacombs.")
+ public DungeonConfig dungeon = new DungeonConfig();
@Expose
- @Category(name = "Bazaar", desc = "Bazaar settings.")
- public BazaarConfig bazaar = new BazaarConfig();
+ @Category(name = "Events", desc = "Stuff that is not always available.")
+ public EventConfig event = new EventConfig();
@Expose
@Category(name = "Fishing", desc = "Fishing stuff.")
public FishingConfig fishing = new FishingConfig();
@Expose
- @Category(name = "Combat", desc = "Everything combat and PvE related.")
- public CombatConfig combat = new CombatConfig();
-
- @Expose
- @Category(name = "Slayer", desc = "Slayer features.")
- public SlayerConfig slayer = new SlayerConfig();
+ @Category(name = "Garden", desc = "Features for the Garden island.")
+ public GardenConfig garden = new GardenConfig();
@Expose
- @Category(name = "Mining", desc = "Features that help you break blocks.")
- public MiningConfig mining = new MiningConfig();
+ @Category(name = "Inventory", desc = "Change the behavior of items and the inventory.")
+ public InventoryConfig inventory = new InventoryConfig();
@Expose
- @Category(name = "Commands", desc = "Enable or disable commands.")
- public CommandsConfig commands = new CommandsConfig();
+ @Category(name = "Item Abilities", desc = "Stuff about item abilities.")
+ public ItemAbilityConfig itemAbilities = new ItemAbilityConfig();
@Expose
@Category(name = "Marked Players", desc = "Players that got marked with §e/shmarkplayer§7.")
public MarkedPlayerConfig markedPlayers = new MarkedPlayerConfig();
@Expose
- @Category(name = "Events", desc = "Stuff that is not always available.")
- public EventConfig event = new EventConfig();
+ @Category(name = "Minions", desc = "The minions on your private island.")
+ public MinionsConfig minions = new MinionsConfig();
@Expose
- @Category(name = "Garden", desc = "Features for the Garden island.")
- public GardenConfig garden = new GardenConfig();
+ @Category(name = "Mining", desc = "Features that help you break blocks.")
+ public MiningConfig mining = new MiningConfig();
+
+ @Expose
+ @Category(name = "Slayer", desc = "Slayer features.")
+ public SlayerConfig slayer = new SlayerConfig();
@Expose
@Category(name = "The Rift", desc = "Features for The Rift dimension.")
@@ -145,12 +150,9 @@ public class Features extends Config {
public DevConfig dev = new DevConfig();
@Expose
- public OldHidden hidden = new OldHidden();
-
- @Expose
public Storage storage = new Storage();
@Expose
- public int lastVersion = ConfigUpdaterMigrator.INSTANCE.getConfigVersion();
+ public int lastVersion = ConfigUpdaterMigrator.CONFIG_VERSION;
}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/Storage.java b/src/main/java/at/hannibal2/skyhanni/config/Storage.java
index 21ed83b00..b21361b6f 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/Storage.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/Storage.java
@@ -1,20 +1,22 @@
package at.hannibal2.skyhanni.config;
import at.hannibal2.skyhanni.data.model.ComposterUpgrade;
+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.trophy.TrophyRarity;
import at.hannibal2.skyhanni.features.garden.CropAccessory;
import at.hannibal2.skyhanni.features.garden.CropType;
-import at.hannibal2.skyhanni.features.garden.farming.FarmingArmorDrops;
+import at.hannibal2.skyhanni.features.garden.farming.ArmorDropTracker;
+import at.hannibal2.skyhanni.features.garden.farming.DicerDropTracker;
import at.hannibal2.skyhanni.features.garden.fortuneguide.FarmingItems;
import at.hannibal2.skyhanni.features.garden.visitor.VisitorReward;
-import at.hannibal2.skyhanni.features.combat.endernodetracker.EnderNode;
-import at.hannibal2.skyhanni.features.event.jerry.frozentreasure.FrozenTreasure;
-import at.hannibal2.skyhanni.features.combat.ghostcounter.GhostData;
-import at.hannibal2.skyhanni.features.mining.powdertracker.PowderChestReward;
+import at.hannibal2.skyhanni.features.mining.powdertracker.PowderTracker;
import at.hannibal2.skyhanni.features.misc.trevor.TrevorTracker;
import at.hannibal2.skyhanni.features.misc.visualwords.VisualWord;
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 com.google.gson.annotations.Expose;
@@ -32,15 +34,19 @@ public class Storage {
public boolean hasPlayedBefore = false;
@Expose
- public Map<String, List<String>> knownFeatureToggles = new HashMap<>();
+ public Float savedMouseSensitivity = .5f;
+ @Deprecated
@Expose
- public Map<Long, List<CropType>> gardenJacobFarmingContestTimes = new HashMap<>();
+ public Map<String, List<String>> knownFeatureToggles = new HashMap<>();
@Expose
public List<VisualWord> modifiedWords = new ArrayList<>();
@Expose
+ public boolean visualWordsImported = false;
+
+ @Expose
public Boolean contestSendingAsked = false;
@Expose
@@ -86,9 +92,9 @@ public class Storage {
@Override
public String toString() {
return "MinionConfig{" +
- "displayName='" + displayName + '\'' +
- ", lastClicked=" + lastClicked +
- '}';
+ "displayName='" + displayName + '\'' +
+ ", lastClicked=" + lastClicked +
+ '}';
}
}
@@ -137,7 +143,7 @@ public class Storage {
public CropAccessory savedCropAccessory = null;
@Expose
- public Map<String, Integer> dicerRngDrops = new HashMap<>();
+ public DicerDropTracker.Data dicerDropTracker = new DicerDropTracker.Data();
@Expose
public long informedAboutLowMatter = 0;
@@ -152,7 +158,7 @@ public class Storage {
public long nextSixthVisitorArrival = 0;
@Expose
- public Map<FarmingArmorDrops.ArmorDropType, Integer> farmArmorDrops = new HashMap<>();
+ public ArmorDropTracker.Data armorDropTracker = new ArmorDropTracker.Data();
@Expose
public Map<ComposterUpgrade, Integer> composterUpgrades = new HashMap<>();
@@ -245,6 +251,9 @@ public class Storage {
public boolean carrotFortune = false;
@Expose
+ public boolean pumpkinFortune = false;
+
+ @Expose
public Map<FarmingItems, ItemStack> farmingItems = new HashMap<>();
}
@@ -293,43 +302,13 @@ public class Storage {
}
@Expose
- public Map<Integer, PowderTracker> powderTracker = new HashMap<>();
-
- public static class PowderTracker {
- @Expose
- public int totalChestPicked = 0;
-
- @Expose
- public Map<PowderChestReward, Long> rewards = new HashMap<>();
- }
+ public PowderTracker.Data powderTracker = new PowderTracker.Data();
@Expose
- public FrozenTreasureTracker frozenTreasureTracker = new FrozenTreasureTracker();
-
- public static class FrozenTreasureTracker {
- @Expose
- public int treasuresMined = 0;
-
- @Expose
- public int compactProcs = 0;
-
- @Expose
- public Map<FrozenTreasure, Integer> treasureCount = new HashMap<>();
- }
+ public FrozenTreasureTracker.Data frozenTreasureTracker = new FrozenTreasureTracker.Data();
@Expose
- public EnderNodeTracker enderNodeTracker = new EnderNodeTracker();
-
- public static class EnderNodeTracker {
- @Expose
- public int totalNodesMined = 0;
-
- @Expose
- public int totalEndermiteNests = 0;
-
- @Expose
- public Map<EnderNode, Integer> lootCount = new HashMap<>();
- }
+ public EnderNodeTracker.Data enderNodeTracker = new EnderNodeTracker.Data();
@Expose
public RiftStorage rift = new RiftStorage();
@@ -342,53 +321,7 @@ public class Storage {
}
@Expose
- public Map<String, SlayerProfitList> slayerProfitData = new HashMap<>();
-
- public static class SlayerProfitList {
-
- @Expose
- public Map<NEUInternalName, SlayerItemProfit> items = new HashMap<>();
-
- @Expose
- public long mobKillCoins = 0;
-
- @Expose
- public long slayerSpawnCost = 0;
-
- @Expose
- public int slayerCompletedCount = 0;
-
- public static class SlayerItemProfit {
- @Expose
- public NEUInternalName internalName;
- @Expose
- public long timesDropped;
- @Expose
- public long totalAmount;
- @Expose
- public boolean hidden;
-
- @Override
- public String toString() {
- return "SlayerItemProfit{" +
- "internalName='" + internalName + '\'' +
- ", timesDropped=" + timesDropped +
- ", totalAmount=" + totalAmount +
- ", hidden=" + hidden +
- '}';
- }
- }
-
- @Override
- public String toString() {
- return "SlayerProfitList{" +
- "items=" + items +
- ", mobKillCoins=" + mobKillCoins +
- ", slayerSpawnCost=" + slayerSpawnCost +
- ", slayerCompletedCount=" + slayerCompletedCount +
- '}';
- }
- }
+ public Map<String, SlayerProfitTracker.Data> slayerProfitData = new HashMap<>();
@Expose
public Map<String, SlayerRngMeterStorage> slayerRngMeter = new HashMap<>();
@@ -410,11 +343,11 @@ public class Storage {
@Override
public String toString() {
return "SlayerRngMeterStorage{" +
- "currentMeter=" + currentMeter +
- ", gainPerBoss=" + gainPerBoss +
- ", goalNeeded=" + goalNeeded +
- ", itemGoal='" + itemGoal + '\'' +
- '}';
+ "currentMeter=" + currentMeter +
+ ", gainPerBoss=" + gainPerBoss +
+ ", goalNeeded=" + goalNeeded +
+ ", itemGoal='" + itemGoal + '\'' +
+ '}';
}
}
@@ -445,7 +378,7 @@ public class Storage {
public int selfKillingAnimals;
@Expose
- public Map<TrevorTracker.TrapperMobRarity, Integer> animalRarities= new HashMap<>();
+ public Map<TrevorTracker.TrapperMobRarity, Integer> animalRarities = new HashMap<>();
}
@Expose
@@ -457,4 +390,4 @@ public class Storage {
public Map<DungeonAPI.DungeonFloor, Integer> bosses = new HashMap<>();
}
}
-} \ No newline at end of file
+}
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 1e32ff718..8e4791901 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt
+++ b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt
@@ -1,29 +1,37 @@
package at.hannibal2.skyhanni.config.commands
import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.config.ConfigFileType
import at.hannibal2.skyhanni.config.ConfigGuiManager
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.chat.Translator
+import at.hannibal2.skyhanni.features.combat.endernodetracker.EnderNodeTracker
import at.hannibal2.skyhanni.features.combat.ghostcounter.GhostUtil
import at.hannibal2.skyhanni.features.commands.PartyCommands
import at.hannibal2.skyhanni.features.event.diana.BurrowWarpHelper
import at.hannibal2.skyhanni.features.event.diana.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.garden.GardenAPI
import at.hannibal2.skyhanni.features.garden.GardenCropTimeCommand
import at.hannibal2.skyhanni.features.garden.GardenNextJacobContest
import at.hannibal2.skyhanni.features.garden.composter.ComposterOverlay
+import at.hannibal2.skyhanni.features.garden.farming.ArmorDropTracker
import at.hannibal2.skyhanni.features.garden.farming.CropMoneyDisplay
import at.hannibal2.skyhanni.features.garden.farming.CropSpeedMeter
+import at.hannibal2.skyhanni.features.garden.farming.DicerDropTracker
import at.hannibal2.skyhanni.features.garden.farming.FarmingWeightDisplay
import at.hannibal2.skyhanni.features.garden.farming.GardenStartLocation
import at.hannibal2.skyhanni.features.garden.fortuneguide.CaptureFarmingGear
import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI
+import at.hannibal2.skyhanni.features.mining.KingTalismanHelper
+import at.hannibal2.skyhanni.features.mining.powdertracker.PowderTracker
import at.hannibal2.skyhanni.features.minion.MinionFeatures
import at.hannibal2.skyhanni.features.misc.CollectionTracker
import at.hannibal2.skyhanni.features.misc.LockMouseLook
@@ -31,7 +39,7 @@ import at.hannibal2.skyhanni.features.misc.MarkedPlayerManager
import at.hannibal2.skyhanni.features.misc.discordrpc.DiscordRPCManager
import at.hannibal2.skyhanni.features.misc.massconfiguration.DefaultConfigFeatures
import at.hannibal2.skyhanni.features.misc.visualwords.VisualWordGui
-import at.hannibal2.skyhanni.features.slayer.SlayerItemProfitTracker
+import at.hannibal2.skyhanni.features.slayer.SlayerProfitTracker
import at.hannibal2.skyhanni.test.PacketTest
import at.hannibal2.skyhanni.test.SkyHanniConfigSearchResetCommand
import at.hannibal2.skyhanni.test.SkyHanniDebugsAndTests
@@ -40,12 +48,12 @@ import at.hannibal2.skyhanni.test.command.CopyItemCommand
import at.hannibal2.skyhanni.test.command.CopyNearbyEntitiesCommand
import at.hannibal2.skyhanni.test.command.CopyNearbyParticlesCommand
import at.hannibal2.skyhanni.test.command.CopyScoreboardCommand
-import at.hannibal2.skyhanni.test.command.CopyTabListCommand
import at.hannibal2.skyhanni.test.command.ErrorManager
import at.hannibal2.skyhanni.test.command.TestChatCommand
import at.hannibal2.skyhanni.utils.APIUtil
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.SoundUtils
+import at.hannibal2.skyhanni.utils.TabListData
import net.minecraft.client.Minecraft
import net.minecraft.command.ICommandSender
import net.minecraft.event.ClickEvent
@@ -59,7 +67,7 @@ object Commands {
private val openMainMenu: (Array<String>) -> Unit = {
if (it.isNotEmpty()) {
if (it[0].lowercase() == "gui") {
- GuiEditManager.openGuiPositionEditor()
+ GuiEditManager.openGuiPositionEditor(hotkeyReminder = true)
} else {
ConfigGuiManager.openConfigGui(it.joinToString(" "))
}
@@ -148,7 +156,7 @@ object Commands {
registerCommand(
"shclearslayerprofits",
"Clearing the total slayer profit for the current slayer type"
- ) { SlayerItemProfitTracker.clearProfitCommand(it) }
+ ) { SlayerProfitTracker.clearProfitCommand(it) }
registerCommand(
"shimportghostcounterdata",
"Manually importing the ghost counter data from GhostCounterV3"
@@ -157,7 +165,15 @@ object Commands {
"shclearfarmingitems",
"Clear farming items saved for the Farming Fortune Guide"
) { clearFarmingItems() }
- registerCommand("shresetghostcounter", "Resets the ghost counter stats") { GhostUtil.reset() }
+ registerCommand("shresetghostcounter", "Resets the ghost counter") { GhostUtil.reset() }
+ registerCommand("shresetpowdertracker", "Resets the Powder Tracker") { PowderTracker.resetCommand(it) }
+ registerCommand("shresetdicertracker", "Resets the Dicer Drop Tracker") { DicerDropTracker.resetCommand(it) }
+ registerCommand(
+ "shresetendernodetracker",
+ "Resets the Ender Node Tracker"
+ ) { EnderNodeTracker.resetCommand(it) }
+ registerCommand("shresetarmordroptracker", "Resets the Armor Drop Tracker") { ArmorDropTracker.resetCommand(it) }
+ registerCommand("shresetfrozentreasuretracker", "Resets the Frozen Treasure Tracker") { FrozenTreasureTracker.resetCommand(it) }
registerCommand("shbingotoggle", "Toggle the bingo card display mode") { BingoCardDisplay.toggleCommand() }
registerCommand(
"shfarmingprofile",
@@ -166,9 +182,9 @@ object Commands {
registerCommand(
"shcopytranslation",
"<language code (2 letters)> <messsage to translate>\n" +
- "Requires the Chat > Translator feature to be enabled.\n" +
- "Copies the translation for a given message to your clipboard. " +
- "Language codes are at the end of the translation when you click on a message."
+ "Requires the Chat > Translator feature to be enabled.\n" +
+ "Copies the translation for a given message to your clipboard. " +
+ "Language codes are at the end of the translation when you click on a message."
) { Translator.fromEnglish(it) }
registerCommand(
"shmouselock",
@@ -215,9 +231,17 @@ object Commands {
"Toggles receiving the 12 fortune from carrots"
) { CaptureFarmingGear.reverseCarrotFortune() }
registerCommand(
+ "shpumpkin",
+ "Toggles receiving the 12 fortune from pumpkins"
+ ) { CaptureFarmingGear.reversePumpkinFortune() }
+ registerCommand(
"shrepostatus",
"Shows the status of all the mods constants"
) { SkyHanniMod.repo.displayRepoStatus(false) }
+ registerCommand(
+ "shkingfix",
+ "Reseting the local King Talisman Helper offset."
+ ) { KingTalismanHelper.kingFix() }
}
private fun developersDebugFeatures() {
@@ -232,11 +256,13 @@ object Commands {
registerCommand(
"shconfigsave",
"Manually saving the config"
- ) { SkyHanniMod.configManager.saveConfig("manual-command") }
+ ) { SkyHanniMod.configManager.saveConfig(ConfigFileType.FEATURES, "manual-command") }
}
private fun developersCodingHelp() {
registerCommand("shtest", "Unused test command.") { SkyHanniDebugsAndTests.testCommand(it) }
+ registerCommand("shdebugwaypoint", "Mark a waypoint on that location") { SkyHanniDebugsAndTests.waypoint(it) }
+ registerCommand("shdebugtablist", "Set your clipboard as a fake tab list.") { TabListData.toggleDebugCommand() }
registerCommand("shreloadlocalrepo", "Reloading the local repo data") { SkyHanniMod.repo.reloadLocalRepo() }
registerCommand("shchathistory", "Show the unfiltered chat history") { ChatManager.openChatFilterGUI() }
registerCommand(
@@ -255,7 +281,7 @@ object Commands {
"shcopyentities",
"Copies entities in the specified radius around the player to the clipboard"
) { CopyNearbyEntitiesCommand.command(it) }
- registerCommand("shcopytablist", "Copies the tab list data to the clipboard") { CopyTabListCommand.command(it) }
+ registerCommand("shcopytablist", "Copies the tab list data to the clipboard") { TabListData.copyCommand(it) }
registerCommand(
"shcopyscoreboard",
"Copies the scoreboard data to the clipboard"
@@ -289,6 +315,10 @@ object Commands {
"shconfigmanagerreset",
"Reloads the config manager and rendering processors of MoulConfig. This §cWILL RESET §7your config, but also updating the java config files (names, description, orderings and stuff)."
) { SkyHanniDebugsAndTests.configManagerResetCommand(it) }
+ registerCommand(
+ "readcropmilestonefromclipboard",
+ "Read crop milestone from clipboard. This helps fixing wrong crop milestone data"
+ ) { GardenCropMilestonesCommunityFix.readDataFromClipboard() }
}
private fun internalCommands() {
@@ -351,7 +381,7 @@ object Commands {
@JvmStatic
fun openFortuneGuide() {
if (!LorenzUtils.inSkyBlock) {
- LorenzUtils.chat("§cJoin SkyBlock to open the fortune guide!")
+ LorenzUtils.chat("§cJoin SkyBlock to open the fortune guide!", false)
} else {
CaptureFarmingGear.captureFarmingGear()
SkyHanniMod.screenToOpen = FFGuideGUI()
@@ -361,17 +391,18 @@ object Commands {
@JvmStatic
fun openVisualWords() {
if (!LorenzUtils.onHypixel) {
- LorenzUtils.chat("§cYou need to join Hypixel to use this feature!")
+ LorenzUtils.chat("§cYou need to join Hypixel to use this feature!", false)
} else {
+ if (VisualWordGui.sbeConfigPath.exists()) VisualWordGui.drawImport = true
SkyHanniMod.screenToOpen = VisualWordGui()
}
}
private fun clearFarmingItems() {
- val config = GardenAPI.config?.fortune ?: return
- LorenzUtils.chat("§e[SkyHanni] clearing farming items")
- config.farmingItems.clear()
- config.outdatedItems.clear()
+ val storage = GardenAPI.storage?.fortune ?: return
+ LorenzUtils.chat("clearing farming items")
+ storage.farmingItems.clear()
+ storage.outdatedItems.clear()
}
private fun registerCommand(name: String, description: String, function: (Array<String>) -> Unit) {
@@ -383,7 +414,7 @@ object Commands {
name: String,
description: String,
function: (Array<String>) -> Unit,
- autoComplete: ((Array<String>) -> List<String>) = { listOf() }
+ autoComplete: ((Array<String>) -> List<String>) = { listOf() },
) {
val command = SimpleCommand(
name,
diff --git a/src/main/java/at/hannibal2/skyhanni/config/commands/SimpleCommand.kt b/src/main/java/at/hannibal2/skyhanni/config/commands/SimpleCommand.kt
index 764f1243d..bca46dbd6 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/commands/SimpleCommand.kt
+++ b/src/main/java/at/hannibal2/skyhanni/config/commands/SimpleCommand.kt
@@ -39,10 +39,10 @@ class SimpleCommand : CommandBase {
try {
runnable.processCommand(sender, args)
} catch (e: Throwable) {
- ErrorManager.logError(e, "Error while running command /$commandName")
+ ErrorManager.logErrorWithData(e, "Error while running command /$commandName")
}
}
override fun addTabCompletionOptions(sender: ICommandSender, args: Array<String>, pos: BlockPos) =
if (tabRunnable != null) tabRunnable!!.tabComplete(sender, args, pos) else null
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/core/config/Position.java b/src/main/java/at/hannibal2/skyhanni/config/core/config/Position.java
index 329bcd028..d8b2a7a99 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/core/config/Position.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/core/config/Position.java
@@ -31,6 +31,8 @@ public class Position {
private int y;
@Expose
private float scale = 1F;
+ @Expose
+ private boolean center = false;
@Expose
private boolean centerX;
@@ -52,6 +54,15 @@ public class Position {
this.scale = scale;
}
+ public Position(int x, int y, float scale, boolean center) {
+ this.x = x;
+ this.y = y;
+ this.centerX = false;
+ this.centerY = true;
+ this.scale = scale;
+ this.center = center;
+ }
+
public Position(int x, int y, boolean centerX, boolean centerY) {
this.x = x;
this.y = y;
@@ -65,6 +76,7 @@ public class Position {
this.centerX = other.centerX;
this.centerY = other.centerY;
this.scale = other.getScale();
+ this.center = other.isCenter();
}
public float getEffectiveScale() {
@@ -76,6 +88,10 @@ public class Position {
return scale;
}
+ public boolean isCenter() {
+ return center;
+ }
+
public void setScale(float newScale) {
scale = Math.max(Math.min(10F, newScale), 0.1f);
}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/ChatConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/ChatConfig.java
deleted file mode 100644
index 9ce9cc5a3..000000000
--- a/src/main/java/at/hannibal2/skyhanni/config/features/ChatConfig.java
+++ /dev/null
@@ -1,212 +0,0 @@
-package at.hannibal2.skyhanni.config.features;
-
-import at.hannibal2.skyhanni.config.FeatureToggle;
-import com.google.gson.annotations.Expose;
-import io.github.moulberry.moulconfig.annotations.Accordion;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind;
-import io.github.moulberry.moulconfig.annotations.ConfigOption;
-import org.lwjgl.input.Keyboard;
-
-public class ChatConfig {
-
- @Expose
- @ConfigOption(name = "Peek Chat", desc = "Hold this key to keep the chat open.")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_Z)
- public int peekChat = Keyboard.KEY_Z;
-
- @Expose
- @ConfigOption(name = "Chat Filter Types", desc = "")
- @Accordion
- public FilterTypesConfig filterType = new FilterTypesConfig();
-
- public static class FilterTypesConfig {
- @Expose
- @ConfigOption(name = "Hypixel Hub", desc = "Block messages outside SkyBlock in the Hypixel lobby: player joins, loot boxes, prototype lobby messages, radiating generosity and Hypixel tournaments.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hypixelHub = true;
-
- @Expose
- @ConfigOption(name = "Empty", desc = "Hide all the empty messages from the chat.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean empty = true;
-
- @Expose
- @ConfigOption(name = "Warping", desc = "Block 'Sending request to join...' and 'Warping...' messages.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean warping = true;
-
- @Expose
- @ConfigOption(name = "Welcome", desc = "Hide the 'Welcome to SkyBlock' message.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean welcome = true;
-
- @Expose
- @ConfigOption(name = "Guild Exp", desc = "Hide Guild EXP messages.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean guildExp = true;
-
- @Expose
- @ConfigOption(name = "Friend Join Left", desc = "Hide friend join/left messages.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean friendJoinLeft = false;
-
- @Expose
- @ConfigOption(name = "Winter Gifts", desc = "Hide useless Winter Gift messages.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean winterGift = false;
-
- @Expose
- @ConfigOption(name = "Powder Mining", desc = "Hide messages while opening chests in the Crystal Hollows. " +
- "(Except powder numbers over 1k, essence numbers over 2, Prehistoric Eggs, and Automaton Parts)")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean powderMining = true;
-
- @Expose
- @ConfigOption(name = "Kill Combo", desc = "Hide messages about the current Kill Combo from the Grandma Wolf Pet.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean killCombo = false;
-
- @Expose
- @ConfigOption(name = "Watchdog", desc = "Hide the message where Hypixel is flexing how many players they have banned over the last week.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean watchDog = true;
-
- @Expose
- @ConfigOption(name = "Profile Join", desc = "Hide 'You are playing on profile' and 'Profile ID' chat messages.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean profileJoin = true;
-
- //TODO remove
- @Expose
- @ConfigOption(name = "Others", desc = "Hide other annoying messages.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean others = false;
- }
-
- @Expose
- @ConfigOption(name = "Player Messages", desc = "")
- @Accordion
- public PlayerMessagesConfig playerMessage = new PlayerMessagesConfig();
-
- public static class PlayerMessagesConfig {
- @Expose
- @ConfigOption(name = "Player Rank Hider", desc = "Hide player ranks in all chat messages.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean playerRankHider = false;
-
- @Expose
- @ConfigOption(name = "Chat Filter", desc = "Scan messages sent by players for blacklisted words and gray out the message if any are found.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean chatFilter = false;
- }
-
- @Expose
- @ConfigOption(name = "Player Chat Symbols", desc = "")
- @Accordion
- public ChatSymbols chatSymbols = new ChatSymbols();
-
- public static class ChatSymbols {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Adds extra symbols to the chat such as those from ironman, " +
- "stranded, bingo or nether factions and places them next to your regular player emblems. " +
- "§cDoes not work with hide rank hider!")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Chat Symbol Location", desc = "Determines where the symbols should go in chat in relation to the " +
- "player's name. Hidden will hide all emblems from the chat. §eRequires above setting to be on to hide the symbols.")
- @ConfigEditorDropdown(values = {"Left", "Right", "Hidden"})
- public int symbolLocation = 0;
- }
-
- @Expose
- @ConfigOption(name = "Dungeon Filter", desc = "Hide annoying messages in Dungeons.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean dungeonMessages = true;
-
- @Expose
- @ConfigOption(name = "Dungeon Boss Messages", desc = "Hide messages from the Watcher and bosses in the Dungeon.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean dungeonBossMessages = false;
-
- @Expose
- @ConfigOption(name = "Hide Far Deaths", desc = "Hide other players' death messages, " +
- "except for players who are nearby or during Dungeons/a Kuudra fight.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideFarDeathMessages = false;
- //TODO jawbus + thunder
-
- @Expose
- @ConfigOption(name = "Compact Potion Messages", desc = "")
- @Accordion
- public CompactPotionConfig compactPotionMessages = new CompactPotionConfig();
-
- public static class CompactPotionConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Shorten chat messages about player potion effects.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Clickable Chat Message", desc = "Makes the Compact Potion message open the Potion effects menu on click.")
- @ConfigEditorBoolean
- public boolean clickableChatMessage = true;
- }
-
- @Expose
- @ConfigOption(name = "Compact Bestiary Message", desc = "Shorten the Bestiary level up message, showing additional information when hovering.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean compactBestiaryMessage = true;
-
- @Expose
- @ConfigOption(name = "Arachne Hider", desc = "Hide chat messages about the Arachne Fight while outside of §eArachne's Sanctuary§7.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideArachneMessages = false;
-
- @Expose
- @ConfigOption(
- name = "Sacks Hider",
- desc = "Hide the chat's sack change message with this, " +
- "not in Hypixel settings, for mods to access sack data in new features."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideSacksChange = false;
-
- @Expose
- @ConfigOption(
- name = "Translator",
- desc = "Click on a message to translate it into English. " +
- "Use §e/shcopytranslation§7 to get the translation from English. " +
- "§cTranslation is not guaranteed to be 100% accurate."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean translator = false;
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/CombatConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/CombatConfig.java
deleted file mode 100644
index d0d69afba..000000000
--- a/src/main/java/at/hannibal2/skyhanni/config/features/CombatConfig.java
+++ /dev/null
@@ -1,721 +0,0 @@
-package at.hannibal2.skyhanni.config.features;
-
-import at.hannibal2.skyhanni.config.FeatureToggle;
-import at.hannibal2.skyhanni.config.core.config.Position;
-import at.hannibal2.skyhanni.features.combat.ghostcounter.GhostFormatting;
-import at.hannibal2.skyhanni.features.combat.ghostcounter.GhostUtil;
-import com.google.gson.annotations.Expose;
-import io.github.moulberry.moulconfig.annotations.Accordion;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorButton;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorDraggableList;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorInfoText;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorText;
-import io.github.moulberry.moulconfig.annotations.ConfigOption;
-import io.github.moulberry.moulconfig.observer.Property;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-public class CombatConfig {
-
- @Expose
- @ConfigOption(name = "Damage Indicator", desc = "")
- @Accordion
- public DamageIndicatorConfig damageIndicator = new DamageIndicatorConfig();
-
- public static class DamageIndicatorConfig {
-
- @Expose
- @ConfigOption(name = "Damage Indicator Enabled", desc = "Show the boss' remaining health.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Healing Chat Message", desc = "Sends a chat message when a boss heals themself.")
- @ConfigEditorBoolean
- public boolean healingMessage = false;
-
- @Expose
- @ConfigOption(
- name = "Boss Name",
- desc = "Change how the boss name should be displayed.")
- @ConfigEditorDropdown(values = {"Hidden", "Full Name", "Short Name"})
- public int bossName = 1;
-
- @Expose
- @ConfigOption(
- 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"
- }
- )
- //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));
-
- @Expose
- @ConfigOption(name = "Hide Damage Splash", desc = "Hiding damage splashes near the damage indicator.")
- @ConfigEditorBoolean
- public boolean hideDamageSplash = false;
-
- @Expose
- @ConfigOption(name = "Damage Over Time", desc = "Show damage and health over time below the damage indicator.")
- @ConfigEditorBoolean
- public boolean showDamageOverTime = false;
-
- @Expose
- @ConfigOption(name = "Hide Nametag", desc = "Hide the vanilla nametag of damage indicator bosses.")
- @ConfigEditorBoolean
- public boolean hideVanillaNametag = false;
-
- @Expose
- @ConfigOption(name = "Time to Kill", desc = "Show the time it takes to kill the slayer boss.")
- @ConfigEditorBoolean
- public boolean timeToKillSlayer = true;
-
-
- @Expose
- @ConfigOption(name = "Ender Slayer", desc = "")
- @Accordion
- public EnderSlayerConfig enderSlayer = new EnderSlayerConfig();
-
- public static class EnderSlayerConfig {
-
- @Expose
- @ConfigOption(name = "Laser Phase Timer", desc = "Show a timer when the laser phase will end.")
- @ConfigEditorBoolean
- public boolean laserPhaseTimer = false;
-
- @Expose
- @ConfigOption(name = "Health During Laser", desc = "Show the health of Voidgloom Seraph 4 during the laser phase.")
- @ConfigEditorBoolean
- public boolean showHealthDuringLaser = false;
- }
-
- @Expose
- @ConfigOption(name = "Vampire Slayer", desc = "")
- @Accordion
- public VampireSlayerConfig vampireSlayer = new VampireSlayerConfig();
-
- public static class VampireSlayerConfig {
- @Expose
- @ConfigOption(name = "HP Until Steak", desc = "Show the amount of HP missing until the Steak can be used on the Vampire Slayer on top of the boss.")
- @ConfigEditorBoolean
- public boolean hpTillSteak = false;
-
- @Expose
- @ConfigOption(name = "Mania Circles", desc = "Show a timer until the boss leaves the invincible Mania Circles state.")
- @ConfigEditorBoolean
- public boolean maniaCircles = false;
-
- @Expose
- @ConfigOption(name = "Percentage HP", desc = "Show the percentage of HP next to the HP.")
- @ConfigEditorBoolean
- public boolean percentage = false;
- }
- }
-
- @Expose
- @ConfigOption(name = "Ghost Counter", desc = "")
- @Accordion
- public GhostCounterConfig ghostCounter = new GhostCounterConfig();
-
- public static class GhostCounterConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Enable the ghost counter (invisible creepers in the Dwarven Mines The Mist area).")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(
- 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"
- }
- )
- public List<Integer> ghostDisplayText = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 9, 10, 11, 12));
-
- @ConfigOption(name = "Text Formatting", desc = "")
- @Accordion
- @Expose
- public TextFormattingConfig textFormatting = new TextFormattingConfig();
-
- public static class TextFormattingConfig {
-
- @ConfigOption(name = "§eText Formatting Info", desc = "§e%session% §ris §e§lalways §rreplaced with\n" +
- "§7the count for your current session.\n" +
- "§7Reset when restarting the game.\n" +
- "§7You can use §e&Z §7color code to use SBA chroma.")
- @ConfigEditorInfoText
- public boolean formatInfo = false;
-
- @ConfigOption(name = "Reset Formatting", desc = "Reset formatting to default text.")
- @ConfigEditorButton(buttonText = "Reset")
- public Runnable resetFormatting = GhostFormatting.INSTANCE::reset;
-
- @ConfigOption(name = "Export Formatting", desc = "Export current formatting to clipboard.")
- @ConfigEditorButton(buttonText = "Export")
- public Runnable exportFormatting = GhostFormatting.INSTANCE::export;
-
- @ConfigOption(name = "Import Formatting", desc = "Import formatting from clipboard.")
- @ConfigEditorButton(buttonText = "Import")
- public Runnable importFormatting = GhostFormatting.INSTANCE::importFormat;
-
- @Expose
- @ConfigOption(name = "Title", desc = "Title Line.")
- @ConfigEditorText
- 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")
- @ConfigEditorText
- public String ghostKilledFormat = " &6Ghost Killed: &b%value% &7(%session%)";
-
- @Expose
- @ConfigOption(name = "Sorrows", desc = "Sorrows drop line.\n" +
- "§e%value% §7is replaced with\nsorrows dropped.")
- @ConfigEditorText
- public String sorrowsFormat = " &6Sorrow: &b%value% &7(%session%)";
-
- @Expose
- @ConfigOption(name = "Ghost Since Sorrow", desc = "Ghost Since Sorrow line.\n" +
- "§e%value% §7is replaced with\nGhost since last sorrow drop.")
- @ConfigEditorText
- public String ghostSinceSorrowFormat = " &6Ghost since Sorrow: &b%value%";
-
- @Expose
- @ConfigOption(name = "Ghost Kill Per Sorrow", desc = "Ghost Kill Per Sorrow line.\n" +
- "§e%value% §7is replaced with\naverage ghost kill per sorrow drop.")
- @ConfigEditorText
- public String ghostKillPerSorrowFormat = " &6Ghosts/Sorrow: &b%value%";
-
- @Expose
- @ConfigOption(name = "Voltas", desc = "Voltas drop line.\n" +
- "§e%value% §7is replaced with\nvoltas dropped.")
- @ConfigEditorText
- public String voltasFormat = " &6Voltas: &b%value% &7(%session%)";
-
- @Expose
- @ConfigOption(name = "Plasmas", desc = "Plasmas drop line.\n" +
- "§e%value% §7is replaced with\nplasmas dropped.")
- @ConfigEditorText
- public String plasmasFormat = " &6Plasmas: &b%value% &7(%session%)";
-
- @Expose
- @ConfigOption(name = "Ghostly Boots", desc = "Ghostly Boots drop line.\n" +
- "§e%value% §7is replaced with\nGhostly Boots dropped.")
- @ConfigEditorText
- public String ghostlyBootsFormat = " &6Ghostly Boots: &b%value% &7(%session%)";
-
- @Expose
- @ConfigOption(name = "Bag Of Cash", desc = "Bag Of Cash drop line.\n" +
- "§e%value% §7is replaced with\nBag Of Cash dropped.")
- @ConfigEditorText
- public String bagOfCashFormat = " &6Bag Of Cash: &b%value% &7(%session%)";
-
- @Expose
- @ConfigOption(name = "Average Magic Find", desc = "Average Magic Find line.\n" +
- "§e%value% §7is replaced with\nAverage Magic Find.")
- @ConfigEditorText
- public String avgMagicFindFormat = " &6Avg Magic Find: &b%value%";
-
- @Expose
- @ConfigOption(name = "Scavenger Coins", desc = "Scavenger Coins line.\n" +
- "§e%value% §7is replaced with\nCoins earned from kill ghosts.\nInclude: Scavenger Enchant, Scavenger Talismans, Kill Combo.")
- @ConfigEditorText
- public String scavengerCoinsFormat = " &6Scavenger Coins: &b%value% &7(%session%)";
-
- @Expose
- @ConfigOption(name = "Kill Combo", desc = "Kill Combo line.\n" +
- "§e%value% §7is replaced with\nYour current kill combo.")
- @ConfigEditorText
- public String killComboFormat = " &6Kill Combo: &b%value%";
-
- @Expose
- @ConfigOption(name = "Highest Kill Combo", desc = "Highest Kill Combo line.\n" +
- "§e%value% §7is replaced with\nYour current highest kill combo.")
- @ConfigEditorText
- public String highestKillComboFormat = " &6Highest Kill Combo: &b%value% &7(%session%)";
-
- @Expose
- @ConfigOption(name = "Skill XP Gained", desc = "Skill XP Gained line.\n" +
- "§e%value% §7is replaced with\nSkill XP Gained from killing Ghosts.")
- @ConfigEditorText
- public String skillXPGainFormat = " &6Skill XP Gained: &b%value% &7(%session%)";
-
- @ConfigOption(name = "Bestiary Formatting", desc = "")
- @Accordion
- @Expose
- public BestiaryFormattingConfig bestiaryFormatting = new BestiaryFormattingConfig();
-
- public static class BestiaryFormattingConfig {
-
- @Expose
- @ConfigOption(name = "Bestiary", desc = "Bestiary Progress line.\n§e%value% §7is replaced with\n" +
- "Your current progress to next level.\n" +
- "§e%currentLevel% &7is replaced with your current bestiary level\n" +
- "§e%nextLevel% §7is replaced with your current bestiary level +1.\n" +
- "§e%value% §7is replaced with one of the text below.")
- @ConfigEditorText
- public String base = " &6Bestiary %display%: &b%value%";
-
- @Expose
- @ConfigOption(name = "No Data", desc = "Text to show when you need to open the\nBestiary Menu to gather data.")
- @ConfigEditorText
- public String openMenu = "§cOpen Bestiary Menu !";
-
- @Expose
- @ConfigOption(name = "Maxed", desc = "Text to show when your bestiary for ghost is at max level.\n" +
- "§e%currentKill% §7is replaced with your current total kill.")
- @ConfigEditorText
- public String maxed = "%currentKill% (&c&lMaxed!)";
-
- @Expose
- @ConfigOption(name = "Progress to Max", desc = "Text to show progress when the §eMaxed Bestiary §7option is §aON\n" +
- "§e%currentKill% §7is replaced with your current total kill.")
- @ConfigEditorText
- public String showMax_progress = "%currentKill%/250k (%percentNumber%%)";
-
- @Expose
- @ConfigOption(name = "Progress", desc = "Text to show progress when the §eMaxed Bestiary§7 option is §cOFF\n" +
- "§e%currentKill% §7is replaced with how many kill you have to the next level.\n" +
- "§e%killNeeded% §7is replaced with how many kill you need to reach the next level.")
- @ConfigEditorText
- public String progress = "%currentKill%/%killNeeded%";
- }
-
-
- @ConfigOption(name = "XP Per Hour Formatting", desc = "")
- @Accordion
- @Expose
- public XPHourFormattingConfig xpHourFormatting = new XPHourFormattingConfig();
-
- public static class XPHourFormattingConfig {
-
- @Expose
- @ConfigOption(name = "XP/h", desc = "XP Per Hour line.\n" +
- "§e%value% §7is replaced with one of the text below.")
- @ConfigEditorText
- public String base = " &6XP/h: &b%value%";
-
- @Expose
- @ConfigOption(name = "No Data", desc = "XP Per Hour line.\n§e%value% §7is replaced with\nEstimated amount of combat xp you gain per hour.")
- @ConfigEditorText
- public String noData = "&bN/A";
-
- @Expose
- @ConfigOption(name = "Paused", desc = "Text displayed next to the time \n" +
- "when you are doing nothing for a given amount of seconds")
- @ConfigEditorText
- public String paused = "&c(PAUSED)";
- }
-
-
- @ConfigOption(name = "ETA Formatting", desc = "")
- @Accordion
- @Expose
- public ETAFormattingConfig etaFormatting = new ETAFormattingConfig();
-
- public static class ETAFormattingConfig {
- @Expose
- @ConfigOption(name = "ETA to next level", desc = "ETA To Next Level Line.\n" +
- "§e%value% §7is replaced with one of the text below.")
- @ConfigEditorText
- public String base = " &6ETA: &b%value%";
-
- @Expose
- @ConfigOption(name = "Maxed!", desc = "So you really maxed ghost bestiary ?")
- @ConfigEditorText
- public String maxed = "&c&lMAXED!";
-
- @Expose
- @ConfigOption(name = "No Data", desc = "Start killing some ghosts !")
- @ConfigEditorText
- public String noData = "&bN/A";
-
- @Expose
- @ConfigOption(name = "Progress", desc = "Text to show progress to next level.")
- @ConfigEditorText
- public String progress = "&b%value%";
-
- @Expose
- @ConfigOption(name = "Paused", desc = "Text displayed next to the time \n" +
- "when you are doing nothing for a given amount of seconds")
- @ConfigEditorText
- public String paused = "&c(PAUSED)";
-
- @Expose
- @ConfigOption(name = "Time", desc = "§e%days% §7is replaced with days remaining.\n" +
- "§e%hours% §7is replaced with hours remaining.\n" +
- "§e%minutes% §7is replaced with minutes remaining.\n" +
- "§e%seconds% §7is replaced with seconds remaining.")
- @ConfigEditorText
- public String time = "&6%days%%hours%%minutes%%seconds%";
- }
-
- @ConfigOption(name = "Kill Per Hour Formatting", desc = "")
- @Expose
- @Accordion
- public KillHourFormattingConfig killHourFormatting = new KillHourFormattingConfig();
-
- public static class KillHourFormattingConfig {
- @Expose
- @ConfigOption(name = "Kill/h", desc = "Kill Per Hour line.\n§e%value% §7is replaced with\nEstimated kills per hour you get.")
- @ConfigEditorText
- public String base = " &6Kill/h: &b%value%";
-
- @Expose
- @ConfigOption(name = "No Data", desc = "Start killing some ghosts !")
- @ConfigEditorText
- public String noData = "&bN/A";
-
- @Expose
- @ConfigOption(name = "Paused", desc = "Text displayed next to the time \n" +
- "when you are doing nothing for a given amount of seconds")
- @ConfigEditorText
- public String paused = "&c(PAUSED)";
- }
-
-
- @Expose
- @ConfigOption(name = "Money Per Hour", desc = "Money Per Hour.\n§e%value% §7is replaced with\nEstimated money you get per hour\n" +
- "Calculated with your kill per hour and your average magic find.")
- @ConfigEditorText
- public String moneyHourFormat = " &6$/h: &b%value%";
-
- @Expose
- @ConfigOption(name = "Money made", desc = "Calculate the money you made.\nInclude §eSorrow§7, §ePlasma§7, §eVolta§7, §e1M coins drop\n" +
- "§eGhostly Boots§7, §eScavenger coins.\n" +
- "§cUsing current Sell Offer value.")
- @ConfigEditorText
- public String moneyMadeFormat = " &6Money made: &b%value%";
- }
-
- @Expose
- @ConfigOption(name = "Extra space", desc = "Space between each line of text.")
- @ConfigEditorSlider(
- minValue = -5,
- maxValue = 10,
- minStep = 1)
- public int extraSpace = 1;
-
- @Expose
- @ConfigOption(name = "Pause Timer", desc = "How many seconds does it wait before pausing.")
- @ConfigEditorSlider(
- minValue = 1,
- maxValue = 20,
- minStep = 1
- )
- public int pauseTimer = 3;
-
- @Expose
- @ConfigOption(name = "Show only in The Mist", desc = "Show the overlay only when you are in The Mist.")
- @ConfigEditorBoolean
- public boolean onlyOnMist = true;
-
- @Expose
- @ConfigOption(name = "Maxed Bestiary", desc = "Show progress to max bestiary instead of next level.")
- @ConfigEditorBoolean
- public boolean showMax = false;
-
- @ConfigOption(name = "Reset", desc = "Reset the counter.")
- @ConfigEditorButton(buttonText = "Reset")
- public Runnable resetCounter = GhostUtil.INSTANCE::reset;
-
- @Expose
- public Position position = new Position(50, 50, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Summonings", desc = "")
- @Accordion
- public SummoningsConfig summonings = new SummoningsConfig();
-
- public static class SummoningsConfig {
-
- @Expose
- @ConfigOption(name = "Summoning Soul Display", desc = "Show the name of dropped Summoning Souls laying on the ground. " +
- "§cNot working in Dungeons if Skytils' 'Hide Non-Starred Mobs Nametags' feature is enabled!")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean summoningSoulDisplay = false;
-
- @Expose
- @ConfigOption(name = "Summoning Mob Display", desc = "Show the health of your spawned summons.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean summoningMobDisplay = false;
-
- @Expose
- public Position summoningMobDisplayPos = new Position(10, 10, false, true);
-
- @Expose
- @ConfigOption(name = "Summoning Mob Nametag", desc = "Hide the nametag of your spawned summons.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean summoningMobHideNametag = false;
-
- @Expose
- @ConfigOption(name = "Summoning Mob Color", desc = "Marks own summons green.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean summoningMobColored = false;
- }
-
- @Expose
- @ConfigOption(name = "Mobs", desc = "")
- @Accordion
- public MobsConfig mobs = new MobsConfig();
-
- public static 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
- @FeatureToggle
- public boolean areaBossHighlight = true;
-
- @Expose
- @ConfigOption(name = "Arachne Keeper", desc = "Highlight the Arachne Keeper in the Spider's Den in purple color.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean arachneKeeperHighlight = true;
-
- @Expose
- @ConfigOption(name = "Corleone", desc = "Highlight Boss Corleone in the Crystal Hollows.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean corleoneHighlighter = true;
-
- @Expose
- @ConfigOption(name = "Zealot", desc = "Highlight Zealots and Bruisers in The End.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean zealotBruiserHighlighter = false;
-
- @Expose
- @ConfigOption(
- name = "Special Zealots",
- desc = "Highlight Special Zealots (the ones that drop Summoning Eyes) in the End."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean specialZealotHighlighter = true;
-
- @Expose
- @ConfigOption(name = "Corrupted Mob", desc = "Highlight corrupted mobs in purple color.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean corruptedMobHighlight = false;
-
- @Expose
- @ConfigOption(name = "Arachne Boss", desc = "Highlight the Arachne boss in red and mini-bosses in orange.")
- @ConfigEditorBoolean
- @FeatureToggle
- 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. " +
- "§cSometimes it takes 20-30 seconds to calibrate correctly."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean areaBossRespawnTimer = false;
-
- @Expose
- @ConfigOption(
- name = "Arachne Spawn Timer",
- desc = "Show a timer when Arachne fragments or crystals are placed to indicate how long " +
- "until the boss will spawn. §cTimer may be 1-2 seconds off."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean showArachneSpawnTimer = true;
-
- @Expose
- @ConfigOption(name = "Enderman TP Hider", desc = "Stops the Enderman Teleportation animation.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean endermanTeleportationHider = true;
-
- @Expose
- @ConfigOption(name = "Arachne Minis Hider", desc = "Hides the nametag above Arachne minis.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideNameTagArachneMinis = true;
- }
-
- @Expose
- @ConfigOption(name = "Bestiary", desc = "")
- @Accordion
- public BestiaryConfig bestiary = new BestiaryConfig();
-
- public static class BestiaryConfig {
- @Expose
- @ConfigOption(name = "Enable", desc = "Show Bestiary Data overlay in the Bestiary menu.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Number format", desc = "Short: 1.1k\nLong: 1.100")
- @ConfigEditorDropdown(values = {"Short", "Long"})
- public int numberFormat = 0;
-
- @Expose
- @ConfigOption(name = "Display type", desc = "Choose what the display should show")
- @ConfigEditorDropdown(values = {
- "Global to max",
- "Global to next tier",
- "Lowest total kills",
- "Highest total kills",
- "Lowest kills needed to max",
- "Highest kills needed to max",
- "Lowest kills needed to next tier",
- "Highest kills needed to next tier"
- })
- public int displayType = 0;
-
- @Expose
- @ConfigOption(name = "Hide maxed", desc = "Hide maxed mobs.")
- @ConfigEditorBoolean
- public boolean hideMaxed = false;
-
- @Expose
- @ConfigOption(name = "Replace Romans", desc = "Replace Roman numerals (IX) with regular numbers (9)")
- @ConfigEditorBoolean
- public boolean replaceRoman = false;
-
- @Expose
- public Position position = new Position(100, 100, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Ender Node Tracker", desc = "")
- @Accordion
- public EnderNodeConfig enderNodeTracker = new EnderNodeConfig();
-
- public static class EnderNodeConfig {
- @Expose
- @ConfigOption(
- name = "Enabled",
- desc = "Tracks all of your drops from mining Ender Nodes in the End.\n" +
- "Also tracks drops from Endermen."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(
- 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",
- " "
- }
- )
- 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)));
-
- @Expose
- public Position position = new Position(10, 80, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Hide Damage Splash", desc = "Hide all damage splashes anywhere in SkyBlock.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideDamageSplash = false;
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/CommandsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/CommandsConfig.java
deleted file mode 100644
index cb127dc11..000000000
--- a/src/main/java/at/hannibal2/skyhanni/config/features/CommandsConfig.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package at.hannibal2.skyhanni.config.features;
-
-import at.hannibal2.skyhanni.config.FeatureToggle;
-import com.google.gson.annotations.Expose;
-import io.github.moulberry.moulconfig.annotations.Accordion;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind;
-import io.github.moulberry.moulconfig.annotations.ConfigOption;
-import org.lwjgl.input.Keyboard;
-
-public class CommandsConfig {
-
- @ConfigOption(name = "Tab Complete", desc = "")
- @Accordion
- @Expose
- public TabCompleteConfig tabComplete = new TabCompleteConfig();
-
- public static class TabCompleteConfig {
-
- @Expose
- @ConfigOption(name = "Warps", desc = "Tab complete the warp-point names when typing §e/warp <TAB>§7.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean warps = true;
-
- @Expose
- @ConfigOption(name = "Island Players", desc = "Tab complete other players on the same island.")
- public boolean islandPlayers = true;
-
- @Expose
- @ConfigOption(name = "Friends", desc = "Tab complete friends from your friends list.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean friends = true;
-
- @Expose
- @ConfigOption(name = "Only Best Friends", desc = "Only Tab Complete best friends.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean onlyBestFriends = false;
-
- @Expose
- @ConfigOption(name = "Party", desc = "Tab complete Party Members.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean party = true;
-
- @Expose
- @ConfigOption(name = "VIP Visits", desc = "Tab complete the visit to special users with cake souls on it.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean vipVisits = true;
-
- @Expose
- @ConfigOption(name = "/gfs Sack", desc = "Tab complete §e/gfs §7sack items.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean gfsSack = true;
-
- @Expose
- @ConfigOption(name = "Party Commands", desc = "Tab complete commonly used party commands.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean partyCommands = true;
-
- @Expose
- @ConfigOption(name = "View Recipe", desc = "Tab complete item IDs in the the Hypixel command §e/viewrecipe§7. Only items with recipes are tab completed.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean viewrecipeItems = true;
- }
-
- @ConfigOption(name = "Fandom Wiki for §e/wiki", desc = "")
- @Accordion
- @Expose
- public FandomWikiCommmandConfig fandomWiki = new FandomWikiCommmandConfig();
-
- public static class FandomWikiCommmandConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Use Fandom Wiki (§ehypixel-skyblock.fandom.com§7) instead of the Hypixel wiki (§ewiki.hypixel.net§7) in most wiki-related chat messages.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Skip Chat", desc = "Directly opens the Fandom Wiki instead of sending the §e\"Click to search for this thing on the Fandom Wiki\"§7 message beforehand.")
- @ConfigEditorBoolean
- public boolean skipWikiChat = false;
-
- @Expose
- @ConfigOption(name = "Fandom Wiki Key", desc = "Search for an item on Fandom Wiki with this keybind.\n§4For optimal experiences, do §lNOT§r §4bind this to a mouse button.")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
- public int fandomWikiKeybind = Keyboard.KEY_NONE;
- }
-
- @ConfigOption(name = "Party Commands", desc = "Shortens party commands and allows tab-completing for them. " +
- "\n§eCommands: /pt /pp /pko /pk §7SkyBlock command §e/pt §7to check the play time still works.")
- @Expose
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean shortCommands = true;
-
- @Expose
- @ConfigOption(name = "Replace Warp Is", desc = "Adds §e/warp is §7alongside §e/is§7. Idk why. Ask §cKaeso")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean replaceWarpIs = false;
-
- @Expose
- @ConfigOption(name = "/viewrecipe Lower Case", desc = "Adds support for lower case item IDs to the Hypixel command §e/viewrecipe§7.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean viewRecipeLowerCase = true;
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/CrimsonIsleConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/CrimsonIsleConfig.java
deleted file mode 100644
index b9d00f8cd..000000000
--- a/src/main/java/at/hannibal2/skyhanni/config/features/CrimsonIsleConfig.java
+++ /dev/null
@@ -1,151 +0,0 @@
-package at.hannibal2.skyhanni.config.features;
-
-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.Accordion;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorColour;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind;
-import io.github.moulberry.moulconfig.annotations.ConfigOption;
-import org.lwjgl.input.Keyboard;
-
-public class CrimsonIsleConfig {
-
- @ConfigOption(name = "Ashfang", desc = "")
- @Accordion
- @Expose
- public AshfangConfig ashfang = new AshfangConfig();
-
- public static class AshfangConfig {
-
- @ConfigOption(name = "Gravity Orbs", desc = "")
- @Accordion
- @Expose
- public GravityOrbsConfig gravityOrbs = new GravityOrbsConfig();
-
- public static class GravityOrbsConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Shows the Gravity Orbs more clearly.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Color", desc = "Color of the Gravity Orbs.")
- @ConfigEditorColour
- public String color = "0:120:255:85:85";
- }
-
- @ConfigOption(name = "Blazing Souls", desc = "")
- @Accordion
- @Expose
- public BlazingSoulsColor blazingSouls = new BlazingSoulsColor();
-
- public static class BlazingSoulsColor {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Shows the Blazing Souls more clearly.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Souls Color", desc = "Color of the Blazing Souls.")
- @ConfigEditorColour
- public String color = "0:245:85:255:85";
- }
-
- @ConfigOption(name = "Hide Stuff", desc = "")
- @Accordion
- @Expose
- public HideAshfangConfig hide = new HideAshfangConfig();
-
- public static class HideAshfangConfig {
-
- @Expose
- @ConfigOption(name = "Hide Particles", desc = "Hide particles around the Ashfang boss.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean particles = false;
-
- @Expose
- @ConfigOption(name = "Hide Full Names", desc = "Hide the names of full health blazes around Ashfang (only useful when highlight blazes is enabled)")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean fullNames = false;
-
- @Expose
- @ConfigOption(name = "Hide Damage Splash", desc = "Hide damage splashes around Ashfang.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean damageSplash = false;
- }
-
- @Expose
- @ConfigOption(name = "Highlight Blazes", desc = "Highlight the different blazes in their respective colors.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlightBlazes = false;
-
- @Expose
- @ConfigOption(name = "Freeze Cooldown", desc = "Show the cooldown for how long Ashfang blocks your abilities.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean freezeCooldown = false;
-
- @Expose
- public Position freezeCooldownPos = new Position(10, 10, false, true);
-
- @Expose
- @ConfigOption(name = "Reset Time", desc = "Show the cooldown until Ashfang pulls his underlings back.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean nextResetCooldown = false;
-
- @Expose
- public Position nextResetCooldownPos = new Position(10, 10, false, true);
- }
-
- @ConfigOption(name = "Reputation Helper", desc = "")
- @Accordion
- @Expose
- public ReputationHelperConfig reputationHelper = new ReputationHelperConfig();
-
- public static class ReputationHelperConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Enable features around Reputation features in the Crimson Isle.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Use Hotkey", desc = "Only show the Reputation Helper while pressing the hotkey.")
- @ConfigEditorBoolean
- public boolean useHotkey = false;
-
- @Expose
- @ConfigOption(name = "Hotkey", desc = "Press this hotkey to show the Reputation Helper.")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
- public int hotkey = Keyboard.KEY_NONE;
-
-
- @Expose
- public Position position = new Position(10, 10, false, true);
-
- @Expose
- @ConfigOption(name = "Show Locations", desc = "Crimson Isles waypoints for locations to get reputation.")
- @ConfigEditorDropdown(values = {"Always", "Only With Hotkey", "Never"})
- public int showLocation = 1;
- }
-
- @Expose
- @ConfigOption(name = "Quest Item Helper", desc = "When you open the fetch item quest in the town board, " +
- "it shows a clickable chat message that will grab the items needed from the sacks.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean questItemHelper = false;
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/DevConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/DevConfig.java
deleted file mode 100644
index be43a7526..000000000
--- a/src/main/java/at/hannibal2/skyhanni/config/features/DevConfig.java
+++ /dev/null
@@ -1,220 +0,0 @@
-package at.hannibal2.skyhanni.config.features;
-
-import at.hannibal2.skyhanni.config.core.config.Position;
-import com.google.gson.annotations.Expose;
-import io.github.moulberry.moulconfig.annotations.Accordion;
-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 DevConfig {
-
- @Expose
- @ConfigOption(name = "Repo Auto Update", desc = "Update the repository on every startup.\n" +
- "§cOnly disable this if you know what you are doing!")
- @ConfigEditorBoolean
- public boolean repoAutoUpdate = true;
-
- @Expose
- @ConfigOption(name = "Debug", desc = "")
- @Accordion
- public DebugConfig debug = new DebugConfig();
-
- public static class DebugConfig {
- @Expose
- @ConfigOption(name = "Enable Debug", desc = "Enable Test logic")
- @ConfigEditorBoolean
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Command Logging", desc = "Logs stack trace information into the console when a command gets sent to Hypixel. (by any mod or the player)")
- @ConfigEditorBoolean
- public boolean commandLogs = false;
-
- @Expose
- @ConfigOption(
- name = "Mod Menu Log",
- desc = "Enables debug messages when the currently opened GUI changes, with the path to the gui class. " +
- "Useful for adding more mods to quick mod menu switch."
- )
- @ConfigEditorBoolean
- public boolean modMenuLog = false;
-
- @Expose
- @ConfigOption(name = "Show Internal Name", desc = "Show internal names in item lore.")
- @ConfigEditorBoolean
- public boolean showInternalName = false;
-
- @Expose
- @ConfigOption(name = "Show Empty Internal Names", desc = "Shows internal name even for items with none.")
- @ConfigEditorBoolean
- public boolean showEmptyNames = false;
-
- @Expose
- @ConfigOption(name = "Show Item Rarity", desc = "Show item rarities in item lore.")
- @ConfigEditorBoolean
- public boolean showItemRarity = false;
-
- @Expose
- @ConfigOption(name = "Copy Internal Name", desc = "Copies the internal name of an item on key press in the clipboard.")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
- public int copyInternalName = Keyboard.KEY_NONE;
-
- @Expose
- @ConfigOption(name = "Show NPC Price", desc = "Show NPC price in item lore.")
- @ConfigEditorBoolean
- public boolean showNpcPrice = false;
-
- @Expose
- @ConfigOption(name = "Show Item UUID", desc = "Show the Unique Identifier of items in the lore.")
- @ConfigEditorBoolean
- public boolean showItemUuid = false;
-
- @Expose
- @ConfigOption(name = "Copy Item Data", desc = "Copies item NBT data on key press in a GUI to clipboard.")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
- public int copyItemData = Keyboard.KEY_NONE;
-
- @Expose
- @ConfigOption(name = "Copy Compressed Item Data", desc = "Copies compressed item NBT data on key press in a GUI to clipboard.")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
- public int copyItemDataCompressed = Keyboard.KEY_NONE;
-
- @Expose
- @ConfigOption(name = "Copy RNG Meter", desc = "Copies internal names and maxed XP needed from RNG meter inventories as json to clipboard.")
- @ConfigEditorBoolean
- public boolean copyRngMeter = false;
-
- @Expose
- @ConfigOption(name = "Copy Bestiary Data", desc = "Copies the bestiary data from the inventory as json to clipboard.")
- @ConfigEditorBoolean
- public boolean copyBestiaryData = false;
-
- @Expose
- @ConfigOption(name = "Highlight Missing Repo Items", desc = "Highlights each item in the current inventory that is not in your current NEU repo.")
- @ConfigEditorBoolean
- public boolean highlightMissingRepo = false;
- }
-
- @Expose
- @ConfigOption(name = "Slot Number", desc = "Show slot number in inventory while pressing this key.")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
- public int showSlotNumberKey = Keyboard.KEY_NONE;
-
- @ConfigOption(name = "Parkour Waypoints", desc = "")
- @Accordion
- @Expose
- public WaypointsConfig waypoint = new WaypointsConfig();
-
- public static class WaypointsConfig {
-
- @Expose
- @ConfigOption(name = "Save Hotkey", desc = "Saves block location to a temporarily parkour and copies everything to your clipboard.")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
- public int saveKey = Keyboard.KEY_NONE;
-
- @Expose
- @ConfigOption(name = "Delete Hotkey", desc = "Deletes the last saved location for when you make a mistake.")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
- public int deleteKey = Keyboard.KEY_NONE;
-
- @Expose
- @ConfigOption(name = "Show Platform Number", desc = "Show the index number over the platform for every parkour.")
- @ConfigEditorBoolean
- public boolean showPlatformNumber = false;
-
- }
-
- @Expose
- public Position debugPos = new Position(10, 10, false, true);
-
- @Expose
- public Position debugLocationPos = new Position(1, 160, false, true);
-
- @Expose
- @ConfigOption(name = "Minecraft Console", desc = "")
- @Accordion
- public MinecraftConsoleConfig minecraftConsoles = new MinecraftConsoleConfig();
-
- public static class MinecraftConsoleConfig {
- @Expose
- @ConfigOption(name = "Unfiltered Debug", desc = "Print the debug information for unfiltered console messages.")
- @ConfigEditorBoolean
- public boolean printUnfilteredDebugs = false;
-
- @Expose
- @ConfigOption(name = "Unfiltered Debug File", desc = "Print the debug information into log files instead of into the console for unfiltered console messages.")
- @ConfigEditorBoolean
- public boolean logUnfilteredFile = false;
-
- @Expose
- @ConfigOption(
- name = "Outside SkyBlock",
- desc = "Print the debug information for unfiltered console messages outside SkyBlock too."
- )
- @ConfigEditorBoolean
- public boolean printUnfilteredDebugsOutsideSkyBlock = false;
-
- @Expose
- @ConfigOption(
- name = "Log Filtered",
- desc = "Log the filtered messages into the console."
- )
- @ConfigEditorBoolean
- public boolean printFilteredReason = false;
-
- @Expose
- @ConfigOption(name = "Console Filters", desc = "")
- @Accordion
- public ConsoleFiltersConfig consoleFilter = new ConsoleFiltersConfig();
-
- public static class ConsoleFiltersConfig {
- @Expose
- @ConfigOption(name = "Filter Chat", desc = "Filter chat messages.")
- @ConfigEditorBoolean
- public boolean filterChat = false;
-
- @Expose
- @ConfigOption(name = "Filter Grow Buffer", desc = "Filter 'Needed to grow BufferBuilder buffer:'")
- @ConfigEditorBoolean
- public boolean filterGrowBuffer = true;
-
- @Expose
- @ConfigOption(name = "Filter Sound Error", desc = "Filter 'Unable to play unknown soundEvent'.")
- @ConfigEditorBoolean
- public boolean filterUnknownSound = true;
-
- @Expose
- @ConfigOption(name = "Filter Scoreboard Errors", desc = "Filter error messages with Scoreboard: removeTeam, createTeam, " +
- "removeObjective and 'scoreboard team already exists'.")
- @ConfigEditorBoolean
- public boolean filterScoreboardErrors = true;
-
- @Expose
- @ConfigOption(name = "Filter Particle", desc = "Filter message 'Could not spawn particle effect VILLAGER_HAPPY'.")
- @ConfigEditorBoolean
- public boolean filterParticleVillagerHappy = true;
-
- @Expose
- @ConfigOption(name = "Filter OptiFine", desc = "Filter OptiFine messages CustomItems and ConnectedTextures during loading.")
- @ConfigEditorBoolean
- public boolean filterOptiFine = true;
-
- @Expose
- @ConfigOption(name = "Filter AsmHelper Transformer", desc = "Filter messages when AsmHelper is Transforming a class during loading.")
- @ConfigEditorBoolean
- public boolean filterAmsHelperTransformer = true;
-
- @Expose
- @ConfigOption(name = "Filter Applying AsmWriter", desc = "Filter messages when AsmHelper is applying AsmWriter ModifyWriter.")
- @ConfigEditorBoolean
- public boolean filterAsmHelperApplying = true;
-
- @Expose
- @ConfigOption(name = "Filter Biome ID Bounds", desc = "Filter message 'Biome ID is out of bounds'.")
- @ConfigEditorBoolean
- public boolean filterBiomeIdBounds = true;
- }
- }
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/DungeonConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/DungeonConfig.java
deleted file mode 100644
index 90eee882a..000000000
--- a/src/main/java/at/hannibal2/skyhanni/config/features/DungeonConfig.java
+++ /dev/null
@@ -1,256 +0,0 @@
-package at.hannibal2.skyhanni.config.features;
-
-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.Accordion;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
-import io.github.moulberry.moulconfig.annotations.ConfigOption;
-
-public class DungeonConfig {
-
- @Expose
- @ConfigOption(name = "Clicked Blocks", desc = "Highlight levers, chests, and Wither Essence when clicked in Dungeons.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlightClickedBlocks = false;
-
- @Expose
- @ConfigOption(name = "Milestones Display", desc = "Show the current milestone in Dungeons.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean showMilestonesDisplay = false;
-
- @Expose
- public Position showMileStonesDisplayPos = new Position(10, 10, false, true);
-
- @Expose
- @ConfigOption(name = "Death Counter Display", desc = "Display the total amount of deaths in the current Dungeon.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean deathCounterDisplay = false;
-
- @Expose
- public Position deathCounterPos = new Position(10, 10, false, true);
-
- @Expose
- @ConfigOption(name = "Clean End", desc = "")
- @Accordion
- public CleanEndConfig cleanEnd = new CleanEndConfig();
- public static class CleanEndConfig {
- @Expose
- @ConfigOption(name = "Enabled", desc = "After the last Dungeon boss has died, all entities and " +
- "particles are no longer displayed and the music stops playing, but the loot chests are still displayed.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Ignore Guardians", desc = "Ignore F3 and M3 Guardians from the clean end feature when " +
- "sneaking. Makes it easier to kill them after the boss died already. Thanks Hypixel.")
- @ConfigEditorBoolean
- public boolean F3IgnoreGuardians = false;
- }
-
- @Expose
- @ConfigOption(name = "Boss Damage Splash", desc = "Hides damage splashes while inside the boss room (fixes a Skytils feature).")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean damageSplashBoss = false;
-
- @Expose
- @ConfigOption(name = "Highlight Deathmites", desc = "Highlight Deathmites in Dungeons in red color.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlightDeathmites = true;
-
- @Expose
- @ConfigOption(name = "Highlight Teammates", desc = "Highlight Dungeon teammates with a glowing outline.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlightTeammates = true;
-
-
- @Expose
- @ConfigOption(name = "Object Hider", desc = "Hide various things in Dungeons.")
- @Accordion
- public ObjectHiderConfig objectHider = new ObjectHiderConfig();
- public static class ObjectHiderConfig {
- @Expose
- @ConfigOption(name = "Hide Superboom TNT", desc = "Hide Superboom TNT laying around in Dungeons.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideSuperboomTNT = false;
-
- @Expose
- @ConfigOption(name = "Hide Blessings", desc = "Hide Blessings laying around in Dungeons.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideBlessing = false;
-
- @Expose
- @ConfigOption(name = "Hide Revive Stones", desc = "Hide Revive Stones laying around in Dungeons.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideReviveStone = false;
-
- @Expose
- @ConfigOption(name = "Hide Premium Flesh", desc = "Hide Premium Flesh laying around in Dungeons.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hidePremiumFlesh = false;
-
- @Expose
- @ConfigOption(name = "Hide Journal Entry", desc = "Hide Journal Entry pages laying around in Dungeons.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideJournalEntry = false;
-
- @Expose
- @ConfigOption(name = "Hide Skeleton Skull", desc = "Hide Skeleton Skulls laying around in Dungeons.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideSkeletonSkull = true;
-
- @Expose
- @ConfigOption(name = "Hide Healer Orbs", desc = "Hides the damage, ability damage and defensive orbs that spawn when the Healer kills mobs.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideHealerOrbs = false;
-
- @Expose
- @ConfigOption(name = "Hide Healer Fairy", desc = "Hide the Golden Fairy that follows the Healer in Dungeons.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideHealerFairy = false;
-
- @Expose
- @ConfigOption(
- name = "Hide Soulweaver Skulls",
- desc = "Hide the annoying soulweaver skulls that float around you if you have the soulweaver gloves equipped.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideSoulweaverSkulls = false;
-
- }
-
- @Expose
- @ConfigOption(name = "Message Filter", desc = "")
- @Accordion
- public MessageFilterConfig messageFilter = new MessageFilterConfig();
-
- public static class MessageFilterConfig{
- @Expose
- @ConfigOption(name = "Keys and Doors", desc = "Hides the chat message when picking up keys or opening doors in Dungeons.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean keysAndDoors = false;
- }
-
- @Expose
- @ConfigOption(name = "Dungeon Copilot", desc = "")
- @Accordion
- public DungeonCopilotConfig dungeonCopilot = new DungeonCopilotConfig();
-
- public static class DungeonCopilotConfig{
- @Expose
- @ConfigOption(name = "Copilot Enabled", desc = "Suggests what to do next in Dungeons.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- public Position pos = new Position(10, 10, false, true);
- }
-
-
- @Expose
- @ConfigOption(name = "Party Finder", desc = "")
- @Accordion
- public PartyFinderConfig partyFinder = new PartyFinderConfig();
-
- public static class PartyFinderConfig {
- @Expose
- @ConfigOption(name = "Colored Class Level", desc = "Color class levels in Party Finder.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean coloredClassLevel = true;
-
- @Expose
- @ConfigOption(name = "Floor Stack Size", desc = "Display the party finder floor as the item stack size.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean floorAsStackSize = true;
-
- @Expose
- @ConfigOption(name = "Mark Paid Carries", desc = "Highlight paid carries with a red background to make them easier to find/skip.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean markPaidCarries = true;
-
- @Expose
- @ConfigOption(name = "Mark Low Levels", desc = "Highlight groups with players at or below the specified class level to make them easier to find/skip.")
- @ConfigEditorSlider(minValue = 0, maxValue = 50, minStep = 1)
- public int markBelowClassLevel = 0;
-
- @Expose
- @ConfigOption(name = "Mark Ineligible Groups", desc = "Highlight groups with requirements that you do not meet.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean markIneligibleGroups = true;
-
- @Expose
- @ConfigOption(name = "Mark Missing Class", desc = "Highlight groups that don't currently have any members of your selected dungeon class.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean markMissingClass = true;
- }
-
- @Expose
- @ConfigOption(name = "Tab List", desc = "")
- @Accordion
- public TabListConfig tabList = new TabListConfig();
-
- public static class TabListConfig {
-
- @Expose
- @ConfigOption(name = "Colored Class Level", desc = "Color class levels in tab list. (Also hides rank colors and emblems, because who needs that in Dungeons anyway?)")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean coloredClassLevel = true;
- }
-
- @Expose
- @ConfigOption(name = "Livid Finder", desc = "")
- @Accordion
- public LividFinderConfig lividFinder = new LividFinderConfig();
-
- public static class LividFinderConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Helps find the correct livid in F5 and in M5.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Hide Wrong Livids", desc = "Hide wrong livids entirely.")
- @ConfigEditorBoolean
- public boolean hideWrong = false;
- }
-
- @Expose
- @ConfigOption(name = "Moving Skeleton Skulls", desc = "Highlight Skeleton Skulls when combining into an " +
- "orange Skeletor (not useful when combined with feature Hide Skeleton Skull).")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlightSkeletonSkull = true;
-
- @Expose
- @ConfigOption(name = "Croesus Chest", desc = "Adds a visual highlight to the Croesus inventory that " +
- "shows unopened chests.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean croesusUnopenedChestTracker = true;
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/EventConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/EventConfig.java
deleted file mode 100644
index 7b4d0211f..000000000
--- a/src/main/java/at/hannibal2/skyhanni/config/features/EventConfig.java
+++ /dev/null
@@ -1,379 +0,0 @@
-package at.hannibal2.skyhanni.config.features;
-
-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.Accordion;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorDraggableList;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind;
-import io.github.moulberry.moulconfig.annotations.ConfigOption;
-import io.github.moulberry.moulconfig.observer.Property;
-import org.lwjgl.input.Keyboard;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-public class EventConfig {
-
- @ConfigOption(name = "Monthly Bingo", desc = "")
- @Accordion
- @Expose
- public BingoConfig bingo = new BingoConfig();
-
- public static class BingoConfig {
-
- @Expose
- @ConfigOption(name = "Bingo Card", desc = "")
- @Accordion
- public BingoCardConfig bingoCard = new BingoCardConfig();
-
- public static class BingoCardConfig {
- @Expose
- @ConfigOption(name = "Enable", desc = "Displays the Bingo Card.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
- @Expose
- @ConfigOption(name = "Quick Toggle", desc = "Quickly toggle the Bingo Card or the step helper by sneaking with SkyBlock Menu in hand.")
- @ConfigEditorBoolean
- public boolean quickToggle = true;
-
- @Expose
- @ConfigOption(name = "Bingo Steps", desc = "Show help with the next step in Bingo instead of the Bingo Card. " +
- "§cThis feature is in early development. Expect bugs and missing goals.")
- @ConfigEditorBoolean
- public boolean stepHelper = false;
-
- @Expose
- @ConfigOption(name = "Hide Community Goals", desc = "Hide Community Goals from the Bingo Card display.")
- @ConfigEditorBoolean
- public Property<Boolean> hideCommunityGoals = Property.of(false);
-
- @Expose
- @ConfigOption(
- name = "Show Guide",
- desc = "Show tips and difficulty for bingo goals inside the Bingo Card inventory.\n" +
- "These tips are made from inspirations and guides from the community,\n"+
- "aiming to help you to complete the bingo card."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean bingoSplashGuide = true;
-
- @Expose
- public Position bingoCardPos = new Position(10, 10, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Compact Chat Messages", desc = "")
- @Accordion
- public CompactChatConfig compactChat = new CompactChatConfig();
-
- public static class CompactChatConfig {
-
- @Expose
- @ConfigOption(name = "Enable", desc = "Shortens chat messages about skill level ups, collection gains, " +
- "new area discoveries and SkyBlock level up messages while on Bingo.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Hide Border", desc = "Hide the border messages before and after the compact level up messages.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideBorder = true;
-
- @Expose
- @ConfigOption(name = "Outside Bingo", desc = "Compact the level up chat messages outside of an Bingo profile as well.")
- @ConfigEditorBoolean
- public boolean outsideBingo = false;
- }
-
- @Expose
- @ConfigOption(name = "Minion Craft Helper", desc = "Show how many more items you need to upgrade the minion in your inventory. Especially useful for Bingo.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean minionCraftHelperEnabled = true;
-
- @Expose
- public Position minionCraftHelperPos = new Position(10, 10, false, true);
- }
-
- @ConfigOption(name = "Diana's Mythological Burrows", desc = "")
- @Accordion
- @Expose
- public DianaConfig diana = new DianaConfig();
-
- public static class DianaConfig {
-
-
- @Expose
- @ConfigOption(name = "Soopy Guess", desc = "Uses §eSoopy's Guess Logic §7to find the next burrow. Does not require SoopyV2 or ChatTriggers to be installed.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean burrowsSoopyGuess = false;
-
- @Expose
- @ConfigOption(name = "Nearby Detection", desc = "Show burrows near you.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean burrowsNearbyDetection = false;
-
- @Expose
- @ConfigOption(name = "Smooth Transition", desc = "Show the way from one burrow to another smoothly.")
- @ConfigEditorBoolean
- public boolean burrowSmoothTransition = false;
-
- @Expose
- @ConfigOption(name = "Nearest Warp", desc = "Warps to the nearest warp point on the hub, if closer to the next burrow.")
- @ConfigEditorBoolean
- public boolean burrowNearestWarp = false;
-
- @Expose
- @ConfigOption(name = "Warp Key", desc = "Press this key to warp to nearest burrow waypoint.")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
- public int keyBindWarp = Keyboard.KEY_NONE;
-
- @Expose
- @ConfigOption(name = "Ignored Warps", desc = "")
- @Accordion
- public IgnoredWarpsConfig ignoredWarps = new IgnoredWarpsConfig();
-
- public static class IgnoredWarpsConfig {
-
- @Expose
- @ConfigOption(name = "Crypt", desc = "Ignore the Crypt warp point (Because it takes a long time to leave).")
- @ConfigEditorBoolean
- public boolean crypt = false;
-
- @Expose
- @ConfigOption(name = "Wizard", desc = "Ignore the Wizard Tower warp point (Because it is easy to fall into the rift).")
- @ConfigEditorBoolean
- public boolean wizard = false;
-
- }
-
- @Expose
- @ConfigOption(name = "Inquisitor Waypoint Sharing", desc = "")
- @Accordion
- public InquisitorSharingConfig inquisitorSharing = new InquisitorSharingConfig();
-
- public static class InquisitorSharingConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Shares your Inquisitor and receiving other Inquisitors via Party Chat.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Focus", desc = "Hide other waypoints when your Party finds an Inquisitor.")
- @ConfigEditorBoolean
- public boolean focusInquisitor = false;
-
- @Expose
- @ConfigOption(name = "Instant Share", desc = "Share the waypoint as soon as you find an Inquisitor. As an alternative, you can share it only via key press.")
- @ConfigEditorBoolean
- public boolean instantShare = true;
-
- @Expose
- @ConfigOption(name = "Share Key", desc = "Press this key to share your Inquisitor Waypoint.")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_Y)
- public int keyBindShare = Keyboard.KEY_Y;
-
- @Expose
- @ConfigOption(name = "Show Despawn Time", desc = "Show the time until the shared Inquisitor will despawn.")
- @ConfigEditorBoolean
- public boolean showDespawnTime = true;
- }
-
- @Expose
- @ConfigOption(name = "Griffin Pet Warning", desc = "Warn when holding an Ancestral Spade if a Griffin Pet is not equipped.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean petWarning = true;
-
- @Expose
- @ConfigOption(name = "Always Diana", desc = "Forcefully set the Diana event to be active. This is useful if the auto mayor detection fails.")
- @ConfigEditorBoolean
- public boolean alwaysDiana = false;
- }
-
- @ConfigOption(name = "Winter Season on Jerry's Island", desc = "")
- @Accordion
- @Expose
- public WinterConfig winter = new WinterConfig();
-
- public static class WinterConfig {
-
- @Expose
- @ConfigOption(name = "Frozen Treasure Tracker", desc = "")
- @Accordion
- public FrozenTreasureConfig frozenTreasureTracker = new FrozenTreasureConfig();
-
- public static class FrozenTreasureConfig {
-
- @Expose
- @ConfigOption(
- name = "Enabled",
- desc = "Tracks all of your drops from Frozen Treasure in the Glacial Caves.\n" +
- "§eIce calculations are an estimate but are relatively accurate."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(
- 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",
- " ",
- }
- )
- public List<Integer> textFormat = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 14, 15));
-
- @Expose
- @ConfigOption(name = "Only in Glacial Cave", desc = "Only shows the overlay while in the Glacial Cave.")
- @ConfigEditorBoolean
- public boolean onlyInCave = true;
-
- @Expose
- @ConfigOption(name = "Show as Drops", desc = "Multiplies the numbers on the display by the base drop. \n" +
- "E.g. 3 Ice Bait -> 48 Ice Bait")
- @ConfigEditorBoolean
- public boolean showAsDrops = false;
-
- @Expose
- @ConfigOption(name = "Hide Chat Messages", desc = "Hides the chat messages from Frozen Treasures.")
- @ConfigEditorBoolean
- public boolean hideMessages = false;
-
- @Expose
- public Position position = new Position(10, 80, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Island Close Time", desc = "While on the Winter Island, show a timer until Jerry's Workshop closes.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean islandCloseTime = true;
-
- @Expose
- public Position islandCloseTimePosition = new Position(10, 10, false, true);
-
- }
-
- @ConfigOption(name = "City Project", desc = "")
- @Accordion
- @Expose
- public CityProjectConfig cityProject = new CityProjectConfig();
-
- public static class CityProjectConfig {
-
- @Expose
- @ConfigOption(name = "Show Materials", desc = "Show materials needed for contributing to the City Project.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean showMaterials = true;
-
- @Expose
- @ConfigOption(name = "Show Ready", desc = "Mark contributions that are ready to participate.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean showReady = true;
-
- @Expose
- @ConfigOption(name = "Daily Reminder", desc = "Remind every 24 hours to participate.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean dailyReminder = true;
-
- @Expose
- public Position pos = new Position(150, 150, false, true);
- }
-
- @ConfigOption(name = "Mayor Jerry's Jerrypocalypse", desc = "")
- @Accordion
- @Expose
- public MayorJerryConfig jerry = new MayorJerryConfig();
-
- public static class MayorJerryConfig {
-
- @Expose
- @ConfigOption(name = "Highlight Jerries", desc = "Highlights Jerries found from the Jerrypocalypse perk. Highlight color is based on color of the Jerry.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlightJerries = true;
-
- }
-
- // comment in if the event is needed again
-// @ConfigOption(name = "300þ Anniversary Celebration", desc = "Features for the 300þ year of SkyBlock")
- @Accordion
- @Expose
- public CenturyConfig century = new CenturyConfig();
-
- public static class CenturyConfig {
-
- @ConfigOption(name = "Enable Active Player Timer", desc = "Show a HUD telling you how much longer you have to wait to be eligible for another free ticket.")
- @Expose
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enableActiveTimer = true;
-
- @Expose
- public Position activeTimerPosition = new Position(100, 100, false, true);
-
- @ConfigOption(name = "Enable Active Player Alert", desc = "Loudly proclaim when it is time to break some wheat.")
- @Expose
- @ConfigEditorBoolean
- public boolean enableActiveAlert = false;
- }
-
- @Expose
- @ConfigOption(name = "Main Lobby Halloween Basket Waypoints", desc = "")
- @Accordion
- public halloweenBasketConfig halloweenBasket = new halloweenBasketConfig();
-
- public static class halloweenBasketConfig {
-
- @Expose
- @ConfigOption(name = "Basket Waypoints", desc = "Show all Halloween Basket waypoints.\nShoutout to §bTobbbb §7for the coordinates.\n(AS OF 2023)")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean allWaypoints = false;
-
- @Expose
- @ConfigOption(name = "Entrance Waypoints", desc = "Show helper waypoints to Baskets #23, #24, and #25. Coordinates by §bErymanthus§7.")
- @ConfigEditorBoolean
- public boolean allEntranceWaypoints = false;
-
- @Expose
- @ConfigOption(name = "Only Closest", desc = "Only show the closest waypoint")
- @ConfigEditorBoolean
- public boolean onlyClosest = true;
- }
-
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/FishingConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/FishingConfig.java
deleted file mode 100644
index 6b47c6025..000000000
--- a/src/main/java/at/hannibal2/skyhanni/config/features/FishingConfig.java
+++ /dev/null
@@ -1,290 +0,0 @@
-package at.hannibal2.skyhanni.config.features;
-
-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.Accordion;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorColour;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
-import io.github.moulberry.moulconfig.annotations.ConfigOption;
-import io.github.moulberry.moulconfig.observer.Property;
-import org.lwjgl.input.Keyboard;
-
-public class FishingConfig {
-
- @Expose
- @ConfigOption(name = "Trophy Fishing", desc = "")
- @Accordion
- public TrophyFishingConfig trophyFishing = new TrophyFishingConfig();
-
- public static class TrophyFishingConfig {
-
- @Expose
- @ConfigOption(name = "Trophy Fishing Chat Messages", desc = "")
- @Accordion
- public ChatMessagesConfig chatMessages = new ChatMessagesConfig();
-
- public static class ChatMessagesConfig {
-
- @Expose
- @ConfigOption(
- name = "Trophy Counter",
- desc = "Counts Trophy messages from chat and tells you how many you have found."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(
- name = "Trophy Counter Design",
- desc = "§fStyle 1: §72. §6§lGOLD §5Moldfin\n" +
- "§fStyle 2: §bYou caught a §5Moldfin §6§lGOLD§b. §7(2)\n" +
- "§fStyle 3: §bYou caught your 2nd §6§lGOLD §5Moldfin§b."
- )
- @ConfigEditorDropdown(values = {"Style 1", "Style 2", "Style 3"})
- public int design = 0;
-
- @Expose
- @ConfigOption(name = "Show Total Amount", desc = "Show total amount of all rarities at the end of the chat message.")
- @ConfigEditorBoolean
- public boolean totalAmount = false;
-
- @Expose
- @ConfigOption(name = "Trophy Fish Info", desc = "Show information and stats about a Trophy Fish when hovering over a catch message in chat.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean tooltip = true;
-
- @Expose
- @ConfigOption(name = "Hide Repeated Catches", desc = "Delete past catches of the same Trophy Fish from chat.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean duplicateHider = false;
-
- @Expose
- @ConfigOption(name = "Bronze Duplicates", desc = "Hide duplicate messages for bronze Trophy Fishes from chat.")
- @ConfigEditorBoolean
- public boolean bronzeHider = false;
-
- @Expose
- @ConfigOption(name = "Silver Duplicates", desc = "Hide duplicate messages for silver Trophy Fishes from chat.")
- @ConfigEditorBoolean
- public boolean silverHider = false;
- }
-
- @Expose
- @ConfigOption(name = "Fillet Tooltip", desc = "Show fillet value of Trophy Fish in tooltip.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean filletTooltip = true;
-
- @Expose
- @ConfigOption(name = "Odger Waypoint", desc = "Show the Odger waypoint when Trophy Fishes are in the inventory and no lava rod in hand.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean odgerLocation = true;
- }
-
- @Expose
- @ConfigOption(name = "Thunder Spark", desc = "")
- @Accordion
- public ThunderSparkConfig thunderSpark = new ThunderSparkConfig();
-
- public static class ThunderSparkConfig {
- @Expose
- @ConfigOption(name = "Thunder Spark Highlight", desc = "Highlight Thunder Sparks after killing a Thunder.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlight = false;
-
- @Expose
- @ConfigOption(name = "Thunder Spark Color", desc = "Color of the Thunder Sparks.")
- @ConfigEditorColour
- public String color = "0:255:255:255:255";
- }
-
- @Expose
- @ConfigOption(name = "Barn Fishing Timer", desc = "")
- @Accordion
- public BarnTimerConfig barnTimer = new BarnTimerConfig();
-
- public static class BarnTimerConfig {
- @Expose
- @ConfigOption(
- name = "Barn Fishing Timer",
- desc = "Show the time and amount of sea creatures while fishing on the barn via hub."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(
- name = "Worm Fishing",
- desc = "Show the Barn Fishing Timer even for worms or other sea creatures in the Crystal Hollows."
- )
- @ConfigEditorBoolean
- public boolean crystalHollows = true;
-
- @Expose
- @ConfigOption(
- name = "Stranded Fishing",
- desc = "Show the Barn Fishing Timer even on all the different islands Stranded players can visit."
- )
- @ConfigEditorBoolean
- public boolean forStranded = true;
-
- @Expose
- @ConfigOption(
- name = "Worm Cap Alert",
- desc = "Alerts you with title and sound if you hit the Worm Sea Creature limit of 60."
- )
- @ConfigEditorBoolean
- public boolean wormLimitAlert = true;
-
- @Expose
- @ConfigOption(name = "Reset Timer Hotkey", desc = "Press this key to reset the timer manualy")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
- public int manualResetTimer = Keyboard.KEY_NONE;
-
- @Expose
- @ConfigOption(name = "Fishing Timer Alert", desc = "Change the amount of time in seconds until the timer dings.")
- @ConfigEditorSlider(
- minValue = 240,
- maxValue = 360,
- minStep = 10
- )
- public int alertTime = 330;
-
- @Expose
- public Position pos = new Position(10, 10, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Chum/Chumcap Bucket Hider", desc = "")
- @Accordion
- public ChumBucketHiderConfig chumBucketHider = new ChumBucketHiderConfig();
-
- public static class ChumBucketHiderConfig {
-
- @Expose
- @ConfigOption(name = "Enable", desc = "Hide the Chum/Chumcap Bucket name tags for other players.")
- @ConfigEditorBoolean
- @FeatureToggle
- public Property<Boolean> enabled = Property.of(true);
-
- @Expose
- @ConfigOption(name = "Hide Bucket", desc = "Hide the Chum/Chumcap Bucket.")
- @ConfigEditorBoolean
- public Property<Boolean> hideBucket = Property.of(false);
-
- @Expose
- @ConfigOption(name = "Hide Own", desc = "Hides your own Chum/Chumcap Bucket.")
- @ConfigEditorBoolean
- public Property<Boolean> hideOwn = Property.of(false);
- }
-
- @Expose
- @ConfigOption(name = "Fished Item Name", desc = "")
- @Accordion
- public FishedItemNameConfig fishedItemName = new FishedItemNameConfig();
-
- public static class FishedItemNameConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Show the fished item name above the item when fishing.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Show Bait", desc = "Also show the name of the consumed bait.")
- @ConfigEditorBoolean
- public boolean showBaits = false;
-
- }
-
- @Expose
- @ConfigOption(name = "Fishing Hook Display", desc = "")
- @Accordion
- public FishingHookDisplayConfig fishingHookDisplay = new FishingHookDisplayConfig();
-
- public static class FishingHookDisplayConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Display the Hypixel timer until the fishing hook can be pulled out of the water/lava, only bigger and on your screen.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(
- name = "Hide Armor Stand",
- desc = "Hide the original armor stand from Hypixel when the SkyHanni display is enabled."
- )
- @ConfigEditorBoolean
- public boolean hideArmorStand = true;
-
- @Expose
- public Position position = new Position(460, -240, 3.4f);
- }
-
- @Expose
- @ConfigOption(name = "Rare Sea Creatures", desc = "")
- @Accordion
- public RareCatches rareCatches = new RareCatches();
-
- public static class RareCatches {
-
- @Expose
- @ConfigOption(name = "Alert (Own Sea Creatures)", desc = "Show an alert on screen when you catch a rare sea creature.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean alertOwnCatches = true;
-
- @Expose
- @ConfigOption(name = "Alert (Other Sea Creatures)", desc = "Show an alert on screen when other players nearby catch a rare sea creature.")
- @ConfigEditorBoolean
- public boolean alertOtherCatches = false;
-
- @Expose
- @ConfigOption(name = "Play Sound Alert", desc = "Play a sound effect when rare sea creature alerts are displayed.")
- @ConfigEditorBoolean
- public boolean playSound = true;
-
- @Expose
- @ConfigOption(name = "Highlight", desc = "Highlight nearby rare sea creatures.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlight = false;
-
- }
-
- @Expose
- @ConfigOption(
- name = "Shark Fish Counter",
- desc = "Counts how many Sharks have been caught."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean sharkFishCounter = false;
-
- @Expose
- public Position sharkFishCounterPos = new Position(10, 10, false, true);
-
- @Expose
- @ConfigOption(name = "Shorten Fishing Message", desc = "Shortens the chat message that says what type of Sea Creature you have fished.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean shortenFishingMessage = false;
-
- @Expose
- @ConfigOption(name = "Compact Double Hook", desc = "Adds Double Hook to the Sea Creature chat message instead of in a previous line.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean compactDoubleHook = true;
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/GUIConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/GUIConfig.java
deleted file mode 100644
index d7fd4625d..000000000
--- a/src/main/java/at/hannibal2/skyhanni/config/features/GUIConfig.java
+++ /dev/null
@@ -1,146 +0,0 @@
-package at.hannibal2.skyhanni.config.features;
-
-import at.hannibal2.skyhanni.config.FeatureToggle;
-import at.hannibal2.skyhanni.config.commands.Commands;
-import at.hannibal2.skyhanni.config.core.config.Position;
-import at.hannibal2.skyhanni.data.GuiEditManager;
-import com.google.gson.annotations.Expose;
-import io.github.moulberry.moulconfig.annotations.Accordion;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorButton;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorText;
-import io.github.moulberry.moulconfig.annotations.ConfigOption;
-import io.github.moulberry.moulconfig.observer.Property;
-import org.lwjgl.input.Keyboard;
-
-public class GUIConfig {
-
- @ConfigOption(name = "Edit GUI Locations", desc = "Change the position of SkyHanni's overlays.")
- @ConfigEditorButton(buttonText = "Edit")
- public Runnable positions = GuiEditManager::openGuiPositionEditor;
-
- @Expose
- @ConfigOption(name = "Open Hotkey", desc = "Press this key to open the GUI Editor.")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
- public int keyBindOpen = Keyboard.KEY_NONE;
-
- @Expose
- @ConfigOption(name = "Global GUI Scale", desc = "Globally scale all SkyHanni GUIs.")
- @ConfigEditorSlider(minValue = 0.1F, maxValue = 10, minStep = 0.05F)
- public float globalScale = 1F;
-
-
- @Expose
- @ConfigOption(name = "Modify Visual Words", desc = "")
- @Accordion
- public ModifyWords modifyWords = new ModifyWords();
-
- public static class ModifyWords {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Enables replacing all instances of a word or phrase with another word or phrase.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Work Outside SkyBlock", desc = "Allows modifying visual words anywhere on Hypixel.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean workOutside = false;
-
- @ConfigOption(name = "Open Config", desc = "Opens the menu to setup the visual words.\n§eCommand: /shwords")
- @ConfigEditorButton(buttonText = "Open")
- public Runnable open = Commands::openVisualWords;
-
- }
-
- @Expose
- @ConfigOption(name = "Custom Text Box", desc = "")
- @Accordion
- public TextBoxConfig customTextBox = new TextBoxConfig();
-
- public static class TextBoxConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Enables showing the textbox while in SkyBlock.")
- @ConfigEditorBoolean
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Text", desc = "Enter text you want to display here.\n" +
- "§eUse '&' as the colour code character.\n" +
- "§eUse '\\n' as the line break character.")
- @ConfigEditorText
- public Property<String> text = Property.of("&aYour Text Here\\n&bYour new line here");
-
- @Expose
- public Position position = new Position(10, 80, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Real Time", desc = "Display the current computer time, a handy feature when playing in full-screen mode.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean realTime = false;
-
- @Expose
- @ConfigOption(name = "Real Time 12h Format", desc = "Display the current computer time in 12hr Format rather than 24h Format.")
- @ConfigEditorBoolean
- public boolean realTimeFormatToggle = false;
-
- @Expose
- public Position realTimePosition = new Position(10, 10, false, true);
-
-
- @Expose
- @ConfigOption(name = "In-Game Date", desc = "")
- @Accordion
- public InGameDateConfig inGameDateConfig = new InGameDateConfig();
-
- public static class InGameDateConfig {
-
- @Expose
- @ConfigOption(
- name = "Enabled",
- desc = "Show the in-game date of SkyBlock (like in Apec, §ebut with mild delays§7).\n" +
- "(Though this one includes the SkyBlock year!)"
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- public Position position = new Position(10, 10, false, true);
-
- @Expose
- @ConfigOption(
- name = "Refresh Rate",
- desc = "Change the time in seconds you would like to refresh the In-Game Date Display."
- )
- @ConfigEditorSlider(
- minValue = 1,
- maxValue = 60,
- minStep = 1
- )
- public int RefreshSeconds = 10;
- }
-
-
- @Expose
- @ConfigOption(name = "TPS Display", desc = "Show the TPS of the current server, like in Soopy.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean tpsDisplay = false;
-
- @Expose
- public Position tpsDisplayPosition = new Position(10, 10, false, true);
-
- @Expose
- @ConfigOption(name = "Config Button", desc = "Add a button to the pause menu to configure SkyHanni.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean configButtonOnPause = true;
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/GardenConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/GardenConfig.java
deleted file mode 100644
index d550d3f72..000000000
--- a/src/main/java/at/hannibal2/skyhanni/config/features/GardenConfig.java
+++ /dev/null
@@ -1,1433 +0,0 @@
-package at.hannibal2.skyhanni.config.features;
-
-import at.hannibal2.skyhanni.config.FeatureToggle;
-import at.hannibal2.skyhanni.config.commands.Commands;
-import at.hannibal2.skyhanni.config.core.config.Position;
-import at.hannibal2.skyhanni.features.garden.inventory.GardenPlotIcon;
-import at.hannibal2.skyhanni.utils.LorenzUtils;
-import com.google.gson.annotations.Expose;
-import io.github.moulberry.moulconfig.annotations.Accordion;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorButton;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorDraggableList;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorText;
-import io.github.moulberry.moulconfig.annotations.ConfigOption;
-import io.github.moulberry.moulconfig.observer.Property;
-import net.minecraft.client.Minecraft;
-import org.lwjgl.input.Keyboard;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-public class GardenConfig {
-
- @Expose
- @ConfigOption(name = "SkyMart", desc = "")
- @Accordion
- public SkyMartConfig skyMart = new SkyMartConfig();
-
- public static class SkyMartConfig {
- @Expose
- @ConfigOption(name = "Copper Price", desc = "Show copper to coin prices inside the SkyMart inventory.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean copperPrice = true;
-
- @Expose
- @ConfigOption(name = "Advanced Stats", desc = "Show the BIN price and copper price for every item.")
- @ConfigEditorBoolean
- public boolean copperPriceAdvancedStats = false;
-
- @Expose
- public Position copperPricePos = new Position(211, 132, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Visitor", desc = "")
- @Accordion
- public VisitorConfig visitors = new VisitorConfig();
-
- public static class VisitorConfig {
- @Expose
- @ConfigOption(name = "Visitor Timer", desc = "")
- @Accordion
- public TimerConfig timer = new TimerConfig();
-
- public static class TimerConfig {
- @Expose
- @ConfigOption(name = "Visitor Timer", desc = "Timer when the next visitor will appear, " +
- "and a number for how many visitors are already waiting.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Sixth Visitor Estimate", desc = "Estimate when the sixth visitor in the queue will arrive. " +
- "May be inaccurate with co-op members farming simultaneously.")
- @ConfigEditorBoolean
- public boolean sixthVisitorEnabled = true;
-
- @Expose
- @ConfigOption(name = "Sixth Visitor Warning", desc = "Notifies when it is believed that the sixth visitor has arrived. " +
- "May be inaccurate with co-op members farming simultaneously.")
- @ConfigEditorBoolean
- public boolean sixthVisitorWarning = true;
-
- @Expose
- @ConfigOption(name = "New Visitor Ping", desc = "Pings you when you are less than 10 seconds away from getting a new visitor. " +
- "§eUseful for getting Ephemeral Gratitudes during the 2023 Halloween event.")
- @ConfigEditorBoolean
- public boolean newVisitorPing = false;
-
- @Expose
- public Position pos = new Position(390, 65, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Visitor Items Needed", desc = "")
- @Accordion
- public NeedsConfig needs = new NeedsConfig();
-
- public static class NeedsConfig {
- @Expose
- @ConfigOption(name = "Items Needed", desc = "Show all items needed for the visitors.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean display = true;
-
- @Expose
- public Position pos = new Position(180, 170, false, true);
-
- @Expose
- @ConfigOption(name = "Only when Close", desc = "Only show the needed items when close to the visitors.")
- @ConfigEditorBoolean
- public boolean onlyWhenClose = false;
-
- @Expose
- @ConfigOption(name = "Bazaar Alley", desc = "Show the Visitor Items List while inside the Bazaar Alley in the Hub. " +
- "This helps buying the correct amount when not having a Booster Cookie Buff active.")
- @ConfigEditorBoolean
- public boolean inBazaarAlley = true;
-
- @Expose
- @ConfigOption(name = "Show Price", desc = "Show the coin price in the items needed list.")
- @ConfigEditorBoolean
- public boolean showPrice = true;
-
- @Expose
- @ConfigOption(name = "Item Preview", desc = "Show the base type for the required items next to new visitors. §cNote that some visitors may require any crop.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean itemPreview = true;
- }
-
- @Expose
- @ConfigOption(name = "Visitor Inventory", desc = "")
- @Accordion
- public InventoryConfig inventory = new InventoryConfig();
-
- public static class InventoryConfig {
- @Expose
- @ConfigOption(name = "Visitor Price", desc = "Show the Bazaar price of the items required for the visitors, like in NEU.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean showPrice = false;
-
- @Expose
- @ConfigOption(name = "Amount and Time", desc = "Show the exact item amount and the remaining time when farmed manually. Especially useful for Ironman.")
- @ConfigEditorBoolean
- public boolean exactAmountAndTime = true;
-
- @Expose
- @ConfigOption(name = "Copper Price", desc = "Show the price per copper inside the visitor GUI.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean copperPrice = true;
-
- @Expose
- @ConfigOption(name = "Copper Time", desc = "Show the time required per copper inside the visitor GUI.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean copperTime = false;
-
- @Expose
- @ConfigOption(name = "Garden Exp Price", desc = "Show the price per garden experience inside the visitor GUI.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean experiencePrice = false;
- }
-
- @Expose
- @ConfigOption(name = "Visitor Reward Warning", desc = "")
- @Accordion
- public RewardWarningConfig rewardWarning = new RewardWarningConfig();
-
- public static class RewardWarningConfig {
-
- @Expose
- @ConfigOption(name = "Notify in Chat", desc = "Send a chat message once you talk to a visitor with reward.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean notifyInChat = true;
-
- @Expose
- @ConfigOption(name = "Show over Name", desc = "Show the reward name above the visitor name.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean showOverName = true;
-
- @Expose
- @ConfigOption(name = "Prevent Refusing", desc = "Prevent the refusal of a visitor with reward.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean preventRefusing = true;
-
- @Expose
- @ConfigOption(name = "Bypass Key", desc = "Hold that key to bypass the Prevent Refusing feature.")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
- 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."
- )
- @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));
- }
-
- @Expose
- @ConfigOption(name = "Notification Chat", desc = "Show in chat when a new visitor is visiting your island.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean notificationChat = true;
-
- @Expose
- @ConfigOption(name = "Notification Title", desc = "Show a title when a new visitor is visiting your island.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean notificationTitle = true;
-
- @Expose
- @ConfigOption(name = "Highlight Status", desc = "Highlight the status for visitors with a text above or with color.")
- @ConfigEditorDropdown(values = {"Color Only", "Name Only", "Both", "Disabled"})
- public int highlightStatus = 2;
-
- @Expose
- @ConfigOption(name = "Colored Name", desc = "Show the visitor name in the color of the rarity.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean coloredName = true;
-
- @Expose
- @ConfigOption(name = "Hypixel Message", desc = "Hide the chat message from Hypixel that a new visitor has arrived at your garden.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hypixelArrivedMessage = true;
-
- @Expose
- @ConfigOption(name = "Hide Chat", desc = "Hide chat messages from the visitors in garden. (Except Beth and Spaceman)")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideChat = true;
-
- @Expose
- @ConfigOption(name = "Visitor Drops Statistics Counter", desc = "")
- @Accordion
- public DropsStatisticsConfig dropsStatistics = new DropsStatisticsConfig();
-
- public static class DropsStatisticsConfig {
-
- @Expose
- @ConfigOption(
- name = "Enabled",
- desc = "Tallies up statistic about visitors and the rewards you have received from them."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(
- 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",
- }
- )
- public List<Integer> textFormat = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12));
-
-
- @Expose
- @ConfigOption(name = "Display Numbers First", desc = "Determines whether the number or drop name displays first. " +
- "§eNote: Will not update the preview above!")
- @ConfigEditorBoolean
- public boolean displayNumbersFirst = true;
-
- @Expose
- @ConfigOption(name = "Display Icons", desc = "Replaces the drop names with icons. " +
- "§eNote: Will not update the preview above!")
- @ConfigEditorBoolean
- public boolean displayIcons = false;
-
- @Expose
- @ConfigOption(name = "Only on Barn Plot", desc = "Only shows the overlay while on the Barn plot.")
- @ConfigEditorBoolean
- public boolean onlyOnBarn = true;
-
- @Expose
- public Position pos = new Position(5, 20, false, true);
- }
-
- @Expose
- @ConfigOption(
- name = "Accept Hotkey",
- desc = "Accept a visitor when you press this keybind while in the visitor GUI. " +
- "§eUseful for getting Ephemeral Gratitudes during the 2023 Halloween event."
- )
- @ConfigEditorKeybind(
- defaultKey = Keyboard.KEY_NONE
- )
- public int acceptHotkey = Keyboard.KEY_NONE;
- }
-
- @Expose
- @ConfigOption(name = "Numbers", desc = "")
- @Accordion
- public NumbersConfig number = new NumbersConfig();
-
- public static class NumbersConfig {
- @Expose
- @ConfigOption(name = "Crop Milestone", desc = "Show the number of crop milestones in the inventory.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean cropMilestone = true;
-
- @Expose
- @ConfigOption(name = "Average Milestone", desc = "Show the average crop milestone in the crop milestone inventory.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean averageCropMilestone = true;
-
- @Expose
- @ConfigOption(name = "Crop Upgrades", desc = "Show the number of upgrades in the crop upgrades inventory.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean cropUpgrades = true;
-
- @Expose
- @ConfigOption(name = "Composter Upgrades", desc = "Show the number of upgrades in the Composter upgrades inventory.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean composterUpgrades = true;
- }
-
- @Expose
- @ConfigOption(name = "Crop Milestones", desc = "")
- @Accordion
- public CropMilestonesConfig cropMilestones = new CropMilestonesConfig();
-
- public static class CropMilestonesConfig {
- @Expose
- @ConfigOption(
- name = "Progress Display",
- desc = "Shows the progress and ETA until the next crop milestone is reached and the current crops/minute value. " +
- "§eRequires a tool with either a counter or Cultivating enchantment for full accuracy."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean progress = true;
-
- @Expose
- @ConfigOption(
- name = "Warn When Close",
- desc = "Warn with title and sound when the next crop milestone upgrade happens in 5 seconds. " +
- "Useful for switching to a different pet for leveling.")
- @ConfigEditorBoolean
- public boolean warnClose = false;
-
- @Expose
- @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);
-
- @Expose
- @ConfigOption(
- name = "Maxed Milestone",
- desc = "Calculate the progress and ETA till maxed milestone (46) instead of next milestone.")
- @ConfigEditorBoolean
- public Property<Boolean> bestShowMaxedNeeded = Property.of(false);
-
- @Expose
- @ConfigOption(
- name = "Milestone Text",
- 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%",
- }
- )
- public List<Integer> text = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5));
-
- @Expose
- @ConfigOption(name = "Block Broken Precision", desc = "The amount of decimals displayed in blocks/second.")
- @ConfigEditorSlider(
- minValue = 0,
- maxValue = 6,
- minStep = 1
- )
- public int blocksBrokenPrecision = 2;
-
- @Expose
- @ConfigOption(name = "Seconds Before Reset", desc = "How many seconds of not farming until blocks/second resets.")
- @ConfigEditorSlider(
- minValue = 2,
- maxValue = 60,
- minStep = 1
- )
- public int blocksBrokenResetTime = 5;
-
- @Expose
- public Position progressDisplayPos = new Position(-400, -200, false, true);
-
- @Expose
- @ConfigOption(name = "Best Crop", desc = "")
- @Accordion
- public NextConfig next = new NextConfig();
-
- // TODO moulconfig runnable support
- public static class NextConfig {
- @Expose
- @ConfigOption(
- name = "Best Display",
- desc = "Lists all crops and their ETA till next milestone. Sorts for best crop for getting garden or SkyBlock levels.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean bestDisplay = true;
-
- // TODO moulconfig runnable support
- @Expose
- @ConfigOption(name = "Sort Type", desc = "Sort the crops by either garden or SkyBlock EXP.")
- @ConfigEditorDropdown(values = {"Garden Exp", "SkyBlock Exp"})
- public int bestType = 0;
-
- // TODO moulconfig runnable support
- @Expose
- @ConfigOption(name = "Only Show Top", desc = "Only show the top # crops.")
- @ConfigEditorSlider(
- minValue = 1,
- maxValue = 10,
- minStep = 1
- )
- public int showOnlyBest = 10;
-
- @Expose
- @ConfigOption(name = "Extend Top List", desc = "Add current crop to the list if its lower ranked than the set limit by extending the list.")
- @ConfigEditorBoolean
- public boolean showCurrent = true;
-
- // TODO moulconfig runnable support
- @Expose
- @ConfigOption(
- name = "Always On",
- desc = "Show the Best Display always while on the garden.")
- @ConfigEditorBoolean
- public boolean bestAlwaysOn = false;
-
- @Expose
- @ConfigOption(
- name = "Compact Display",
- desc = "A more compact best crop time: Removing the crop name and exp, hide the # number and using a more compact time format.")
- @ConfigEditorBoolean
- public boolean bestCompact = false;
-
- @Expose
- @ConfigOption(
- name = "Hide Title",
- desc = "Hides the 'Best Crop Time' line entirely.")
- @ConfigEditorBoolean
- public boolean bestHideTitle = false;
-
-
- @Expose
- public Position displayPos = new Position(-200, -200, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Mushroom Pet Perk", desc = "")
- @Accordion
- public MushroomPetPerkConfig mushroomPetPerk = new MushroomPetPerkConfig();
-
- // TODO moulconfig runnable support
- public static class MushroomPetPerkConfig {
- @Expose
- @ConfigOption(
- name = "Display Enabled",
- desc = "Show the progress and ETA for mushroom crops when farming other crops because of the Mooshroom Cow perk.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(
- name = "Mushroom Text",
- 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%",
- }
- )
- public List<Integer> text = new ArrayList<>(Arrays.asList(0, 1, 2, 3));
-
- @Expose
- public Position pos = new Position(-112, -143, false, true);
- }
- }
-
- // TODO moulconfig runnable support
- @Expose
- @ConfigOption(name = "Custom Keybinds", desc = "")
- @Accordion
- public KeyBindConfig keyBind = new KeyBindConfig();
-
- public static class KeyBindConfig {
- @Expose
- @ConfigOption(name = "Enabled", desc = "Use custom keybinds while holding a farming tool or Daedalus Axe in the hand.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @ConfigOption(name = "Disable All", desc = "Disable all keys.")
- @ConfigEditorButton(buttonText = "Disable")
- public Runnable presetDisable = () -> {
- attack = Keyboard.KEY_NONE;
- useItem = Keyboard.KEY_NONE;
- left = Keyboard.KEY_NONE;
- right = Keyboard.KEY_NONE;
- forward = Keyboard.KEY_NONE;
- back = Keyboard.KEY_NONE;
- jump = Keyboard.KEY_NONE;
- sneak = Keyboard.KEY_NONE;
-
- Minecraft.getMinecraft().thePlayer.closeScreen();
- };
-
- @ConfigOption(name = "Set Default", desc = "Reset all keys to default.")
- @ConfigEditorButton(buttonText = "Default")
- public Runnable presetDefault = () -> {
- attack = -100;
- useItem = -99;
- left = Keyboard.KEY_A;
- right = Keyboard.KEY_D;
- forward = Keyboard.KEY_W;
- back = Keyboard.KEY_S;
- jump = Keyboard.KEY_SPACE;
- sneak = Keyboard.KEY_LSHIFT;
- Minecraft.getMinecraft().thePlayer.closeScreen();
- };
-
- @Expose
- @ConfigOption(name = "Attack", desc = "")
- @ConfigEditorKeybind(defaultKey = -100)
- public int attack = -100;
-
- @Expose
- @ConfigOption(name = "Use Item", desc = "")
- @ConfigEditorKeybind(defaultKey = -99)
- public int useItem = -99;
-
- @Expose
- @ConfigOption(name = "Move Left", desc = "")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_A)
- public int left = Keyboard.KEY_A;
-
- @Expose
- @ConfigOption(name = "Move Right", desc = "")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_D)
- public int right = Keyboard.KEY_D;
-
- @Expose
- @ConfigOption(name = "Move Forward", desc = "")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_W)
- public int forward = Keyboard.KEY_W;
-
- @Expose
- @ConfigOption(name = "Move Back", desc = "")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_S)
- public int back = Keyboard.KEY_S;
-
- @Expose
- @ConfigOption(name = "Jump", desc = "")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_SPACE)
- public int jump = Keyboard.KEY_SPACE;
-
- @Expose
- @ConfigOption(name = "Sneak", desc = "")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_LSHIFT)
- public int sneak = Keyboard.KEY_LSHIFT;
- }
-
- @Expose
- @ConfigOption(name = "Optimal Speed", desc = "")
- @Accordion
- public OptimalSpeedConfig optimalSpeeds = new OptimalSpeedConfig();
-
- public static class OptimalSpeedConfig {
- @Expose
- @ConfigOption(name = "Enabled", desc = "Show the optimal speed for your current tool in the hand.\n" +
- "(Thanks MelonKingDE for the default values).")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Warning Title", desc = "Warn via title when you don't have the optimal speed.")
- @ConfigEditorBoolean
- public boolean warning = false;
-
- @Expose
- @ConfigOption(name = "Rancher Boots", desc = "Allows you to set the optimal speed in the Rancher Boots overlay by clicking on the presets.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean signEnabled = true;
-
- @Expose
- public Position signPosition = new Position(20, -195, false, true);
-
- @Expose
- @ConfigOption(name = "Custom Speed", desc = "Change the exact speed for every single crop.")
- @Accordion
- public CustomSpeedConfig customSpeed = new CustomSpeedConfig();
-
- public static class CustomSpeedConfig {
-
- @Expose
- @ConfigOption(name = "Wheat", desc = "Suggested farm speed:\n" +
- "§e5 Blocks§7: §f✦ 93 speed\n" +
- "§e4 Blocks§7: §f✦ 116 speed")
- @ConfigEditorSlider(minValue = 1, maxValue = 400, minStep = 1)
- public int wheat = 93;
-
- @Expose
- @ConfigOption(name = "Carrot", desc = "Suggested farm speed:\n" +
- "§e5 Blocks§7: §f✦ 93 speed\n" +
- "§e4 Blocks§7: §f✦ 116 speed")
- @ConfigEditorSlider(minValue = 1, maxValue = 400, minStep = 1)
- public int carrot = 93;
-
- @Expose
- @ConfigOption(name = "Potato", desc = "Suggested farm speed:\n" +
- "§e5 Blocks§7: §f✦ 93 speed\n" +
- "§e4 Blocks§7: §f✦ 116 speed")
- @ConfigEditorSlider(minValue = 1, maxValue = 400, minStep = 1)
- public int potato = 93;
-
- @Expose
- @ConfigOption(name = "Nether Wart", desc = "Suggested farm speed:\n" +
- "§e5 Blocks§7: §f✦ 93 speed\n" +
- "§e4 Blocks§7: §f✦ 116 speed")
- @ConfigEditorSlider(minValue = 1, maxValue = 400, minStep = 1)
- public int netherWart = 93;
-
- @Expose
- @ConfigOption(name = "Pumpkin", desc = "Suggested farm speed:\n" +
- "§e3 Blocks§7: §f✦ 155 speed\n" +
- "§e2 Blocks§7: §f✦ 265 §7or §f400 speed")
- @ConfigEditorSlider(minValue = 1, maxValue = 400, minStep = 1)
- public int pumpkin = 155;
-
- @Expose
- @ConfigOption(name = "Melon", desc = "Suggested farm speed:\n" +
- "§e3 Blocks§7: §f✦ 155 speed\n" +
- "§e2 Blocks§7: §f✦ 265 or 400 speed")
- @ConfigEditorSlider(minValue = 1, maxValue = 400, minStep = 1)
- public int melon = 155;
-
- @Expose
- @ConfigOption(name = "Cocoa Beans", desc = "Suggested farm speed:\n" +
- "§e3 Blocks§7: §f✦ 155 speed\n" +
- "§e4 Blocks§7: §f✦ 116 speed")
- @ConfigEditorSlider(minValue = 1, maxValue = 400, minStep = 1)
- public int cocoaBeans = 155;
-
- // TODO does other speed settings exist?
- @Expose
- @ConfigOption(name = "Sugar Cane", desc = "Suggested farm speed:\n" +
- "§eYaw 45§7: §f✦ 328 speed")
- @ConfigEditorSlider(minValue = 1, maxValue = 400, minStep = 1)
- public int sugarCane = 328;
-
- @Expose
- @ConfigOption(name = "Cactus", desc = "Suggested farm speed:\n" +
- "§eNormal§7: §f✦ 400 speed\n" +
- "§eRacing Helmet§7: §f✦ 464 speed\n" +
- "§eBlack Cat§7: §f✦ 464 speed")
- @ConfigEditorSlider(minValue = 1, maxValue = 500, minStep = 1)
- public int cactus = 400;
-
- // TODO does other speed settings exist?
- @Expose
- @ConfigOption(name = "Mushroom", desc = "Suggested farm speed:\n" +
- "§eYaw 60§7: §f✦ 233 speed")
- @ConfigEditorSlider(minValue = 1, maxValue = 400, minStep = 1)
- public int mushroom = 233;
- }
-
- @Expose
- public Position pos = new Position(5, -200, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Garden Level", desc = "")
- @Accordion
- public GardenLevelConfig gardenLevels = new GardenLevelConfig();
-
- public static class GardenLevelConfig {
- @Expose
- @ConfigOption(name = "Display", desc = "Show the current Garden level and progress to the next level.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean display = true;
-
- @Expose
- public Position pos = new Position(390, 40, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Farming Weight", desc = "")
- @Accordion
- public EliteFarmingWeightConfig eliteFarmingWeights = new EliteFarmingWeightConfig();
-
- public static class EliteFarmingWeightConfig {
- @Expose
- @ConfigOption(name = "Display", desc = "Display your farming weight on screen. " +
- "The calculation and API is provided by The Elite SkyBlock farmers. " +
- "See §ehttps://elitebot.dev/info §7for more info.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean display = true;
-
- @Expose
- public Position pos = new Position(180, 10, false, true);
-
- @Expose
- @ConfigOption(name = "Leaderboard Ranking", desc = "Show your position in the farming weight leaderboard. " +
- "Only if your farming weight is high enough! Updates every 10 minutes.")
- @ConfigEditorBoolean
- public boolean leaderboard = true;
-
- @Expose
- @ConfigOption(name = "Overtake ETA", desc = "Show a timer estimating when you'll move up a spot in the leaderboard! " +
- "Will show an ETA to rank #10,000 if you're not on the leaderboard yet.")
- @ConfigEditorBoolean
- public boolean overtakeETA = false;
-
- @Expose
- @ConfigOption(name = "Offscreen Drop Message", desc = "Show a chat message when joining Garden how many spots you have dropped since last Garden join.")
- @ConfigEditorBoolean
- public boolean offScreenDropMessage = true;
-
- @Expose
- @ConfigOption(name = "Always ETA", desc = "Show the Overtake ETA always, even when not farming at the moment.")
- @ConfigEditorBoolean
- public boolean overtakeETAAlways = true;
-
- @Expose
- @ConfigOption(name = "ETA Goal", desc = "Override the Overtake ETA to show when you'll reach the specified rank (if not there yet). (Default: \"10,000\")")
- @ConfigEditorText
- public String ETAGoalRank = "10000";
-
- @Expose
- @ConfigOption(name = "Show below 200", desc = "Show the farming weight data even if you are below 200 weight.")
- @ConfigEditorBoolean
- public boolean ignoreLow = false;
- }
-
- @Expose
- @ConfigOption(name = "Dicer Counter", desc = "")
- @Accordion
- public DicerCounterConfig dicerCounters = new DicerCounterConfig();
-
- public static class DicerCounterConfig {
- @Expose
- @ConfigOption(name = "RNG Drop Counter", desc = "Count RNG drops for Melon Dicer and Pumpkin Dicer.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean display = true;
-
- @Expose
- @ConfigOption(name = "Hide Chat", desc = "Hide the chat message when dropping a RNG Dicer drop.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideChat = false;
-
- @Expose
- public Position pos = new Position(16, -232, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Money per Hour", desc = "")
- @Accordion
- public MoneyPerHourConfig moneyPerHours = new MoneyPerHourConfig();
-
- public static class MoneyPerHourConfig {
- @Expose
- @ConfigOption(name = "Show Money per Hour",
- desc = "Displays the money per hour YOU get with YOUR crop/minute value when selling the item to bazaar. " +
- "Supports Bountiful, Mushroom Cow Perk, Armor Crops and Dicer Drops. Their toggles are below.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean display = true;
-
- // TODO moulconfig runnable support
- @Expose
- @ConfigOption(name = "Only Show Top", desc = "Only show the best # items.")
- @ConfigEditorSlider(
- minValue = 1,
- maxValue = 25,
- minStep = 1
- )
- public int showOnlyBest = 5;
-
- @Expose
- @ConfigOption(name = "Extend Top List", desc = "Add current crop to the list if its lower ranked than the set limit by extending the list.")
- @ConfigEditorBoolean
- public boolean showCurrent = true;
-
- // TODO moulconfig runnable support
- @Expose
- @ConfigOption(
- name = "Always On",
- desc = "Always show the money/hour Display while on the garden.")
- @ConfigEditorBoolean
- public boolean alwaysOn = false;
-
- @Expose
- @ConfigOption(
- name = "Compact Mode",
- desc = "Hide the item name and the position number.")
- @ConfigEditorBoolean
- public boolean compact = false;
-
- @Expose
- @ConfigOption(
- name = "Compact Price",
- desc = "Show the price more compact.")
- @ConfigEditorBoolean
- public boolean compactPrice = false;
-
- @Expose
- @ConfigOption(
- name = "Use Custom",
- desc = "Use the custom format below instead of classic ➜ §eSell Offer §7and other profiles ➜ §eNPC Price.")
- @ConfigEditorBoolean
- public boolean useCustomFormat = false;
-
- @Expose
- @ConfigOption(
- 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));
-
- @Expose
- @ConfigOption(
- name = "Merge Seeds",
- desc = "Merge the seeds price with the wheat price.")
- @ConfigEditorBoolean
- public boolean mergeSeeds = true;
-
- @Expose
- @ConfigOption(
- name = "Include Bountiful",
- desc = "Includes the coins from Bountiful in the calculation.")
- @ConfigEditorBoolean
- public boolean bountiful = true;
-
- @Expose
- @ConfigOption(
- name = "Include Mooshroom Cow",
- desc = "Includes the coins you get from selling the mushrooms from your Mooshroom Cow pet.")
- @ConfigEditorBoolean
- public boolean mooshroom = true;
-
- @Expose
- @ConfigOption(
- name = "Include Armor Drops",
- desc = "Includes the average coins/hr from your armor.")
- @ConfigEditorBoolean
- public boolean armor = true;
-
- @Expose
- @ConfigOption(
- name = "Include Dicer Drops",
- desc = "Includes the average coins/hr from your melon or pumpkin dicer.")
- @ConfigEditorBoolean
- public boolean dicer = true;
-
- @Expose
- @ConfigOption(
- name = "Hide Title",
- desc = "Hides the first line of 'Money Per Hour' entirely.")
- @ConfigEditorBoolean
- public boolean hideTitle = false;
-
- @Expose
- public Position pos = new Position(-330, 170, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Next Jacob's Contest", desc = "")
- @Accordion
- public NextJacobContestConfig nextJacobContests = new NextJacobContestConfig();
-
- public static class NextJacobContestConfig {
- @Expose
- @ConfigOption(name = "Show Jacob's Contest", desc = "Show the current or next Jacob's farming contest time and crops.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean display = true;
-
- @Expose
- @ConfigOption(name = "Outside Garden", desc = "Show the timer not only in Garden but everywhere in SkyBlock.")
- @ConfigEditorBoolean
- public boolean everywhere = false;
-
- @Expose
- @ConfigOption(name = "In Other Guis", desc = "Mark the current or next Farming Contest crops in other farming GUIs as underlined.")
- @ConfigEditorBoolean
- public boolean otherGuis = false;
-
- @Expose
- @ConfigOption(name = "Fetch Contests", desc = "Automatically fetch Contests from elitebot.dev for the current year if they're uploaded already.")
- @ConfigEditorBoolean
- public boolean fetchAutomatically = true;
-
- @Expose
- @ConfigOption(name = "Share Contests", desc = "Share the list of upcoming Contests to elitebot.dev for everyone else to then fetch automatically.")
- @ConfigEditorDropdown(values = {"Ask When Needed", "Share Automatically", "Disabled"})
- public int shareAutomatically = 0;
-
- @Expose
- @ConfigOption(name = "Warning", desc = "Show a warning shortly before a new Jacob's Contest starts.")
- @ConfigEditorBoolean
- public boolean warn = false;
-
- @Expose
- @ConfigOption(name = "Warning Time", desc = "Set the warning time in seconds before a Jacob's Contest begins.")
- @ConfigEditorSlider(
- minValue = 10,
- maxValue = 60 * 5,
- minStep = 1
- )
- public int warnTime = 60 * 2;
-
- @Expose
- @ConfigOption(name = "Popup Warning", desc = "Opens a popup when the warning time is reached and Minecraft is not in focus.")
- @ConfigEditorBoolean
- public boolean warnPopup = false;
-
- @Expose
- public Position pos = new Position(-200, 10, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Farming Armor Drops", desc = "")
-
- @Accordion
- public FarmingArmorDropsConfig farmingArmorDrop = new FarmingArmorDropsConfig();
-
- public static class FarmingArmorDropsConfig {
- @Expose
- @ConfigOption(name = "Show Counter", desc = "Count all §9Cropie§7, §5Squash §7and §6Fermento §7dropped.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Hide Chat", desc = "Hide the chat message when receiving a farming armor drop.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideChat = false;
-
- @Expose
- public Position pos = new Position(16, -232, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Anita Shop", desc = "")
- @Accordion
- public AnitaShopConfig anitaShop = new AnitaShopConfig();
-
- public static class AnitaShopConfig {
- @Expose
- @ConfigOption(
- name = "Medal Prices",
- desc = "Helps to identify profitable items to buy at the Anita item shop " +
- "and potential profit from selling the item in the Auction House."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean medalProfitEnabled = true;
-
- @Expose
- @ConfigOption(
- name = "Extra Farming Fortune",
- desc = "Show current tier and cost to max out in the item tooltip.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean extraFarmingFortune = true;
-
- @Expose
- public Position medalProfitPos = new Position(206, 158, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Composter", desc = "")
- @Accordion
- public ComposterConfig composters = new ComposterConfig();
-
- public static class ComposterConfig {
- @Expose
- @ConfigOption(
- name = "Composter Overlay",
- desc = "Show organic matter, fuel, and profit prices while inside the Composter Inventory."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean overlay = true;
-
- @Expose
- @ConfigOption(name = "Overlay Price", desc = "Toggle for Bazaar 'buy order' vs 'instant buy' price in composter overlay.")
- @ConfigEditorDropdown(values = {"Instant Buy", "Buy Order"})
- public int overlayPriceType = 0;
-
- @Expose
- @ConfigOption(name = "Retrieve From", desc = "Change where to retrieve the materials from in the composter overlay: The Bazaar or Sacks.")
- @ConfigEditorDropdown(values = {"Bazaar", "Sacks"})
- public int retrieveFrom = 0;
-
- @Expose
- public Position overlayOrganicMatterPos = new Position(140, 152, false, true);
-
- @Expose
- public Position overlayFuelExtrasPos = new Position(-320, 152, false, true);
-
- @Expose
- @ConfigOption(
- name = "Display Element",
- desc = "Displays the Compost data from the tab list as GUI element."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean displayEnabled = true;
-
- @Expose
- @ConfigOption(
- name = "Outside Garden",
- desc = "Show Time till Composter is empty outside Garden"
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean displayOutsideGarden = false;
-
- @Expose
- @ConfigOption(
- name = "Composter Warning",
- desc = "Warn when the Composter gets close to empty, even outside Garden."
- )
- @ConfigEditorBoolean
- public boolean warnAlmostClose = false;
-
- @Expose
- @ConfigOption(
- name = "Upgrade Price",
- desc = "Show the price for the Composter Upgrade in the lore."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean upgradePrice = true;
-
- @Expose
- @ConfigOption(
- name = "Round Amount Needed",
- desc = "Rounds the amount needed to fill your Composter down so that you don't overspend."
- )
- @ConfigEditorBoolean
- public boolean roundDown = true;
-
- @Expose
- @ConfigOption(
- name = "Highlight Upgrade",
- desc = "Highlight Upgrades that can be bought right now."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlightUpgrade = true;
-
- @Expose
- @ConfigOption(
- name = "Inventory Numbers",
- desc = "Show the amount of Organic Matter, Fuel and Composts Available while inside the Composter Inventory."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean inventoryNumbers = true;
-
- @Expose
- @ConfigOption(name = "Notification When Low Composter", desc = "")
- @Accordion
- public NotifyLowConfig notifyLow = new NotifyLowConfig();
-
- public static class NotifyLowConfig {
- @Expose
- @ConfigOption(name = "Enable", desc = "Show a notification when Organic Matter or Fuel runs low in your Composter.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Show Title", desc = "Send a title to notify.")
- @ConfigEditorBoolean
- public boolean title = false;
-
- @Expose
- @ConfigOption(name = "Min Organic Matter", desc = "Warn when Organic Matter is below this value.")
- @ConfigEditorSlider(
- minValue = 1_000,
- maxValue = 80_000,
- minStep = 1
- )
- public int organicMatter = 20_000;
-
- @Expose
- @ConfigOption(name = "Min Fuel Cap", desc = "Warn when Fuel is below this value.")
- @ConfigEditorSlider(
- minValue = 500,
- maxValue = 40_000,
- minStep = 1
- )
- public int fuel = 10_000;
- }
-
- @Expose
- public Position displayPos = new Position(-390, 10, false, true);
-
- @Expose
- public Position outsideGardenPos = new Position(-363, 13, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Farming Fortune Display", desc = "")
- @Accordion
- public FarmingFortuneConfig farmingFortunes = new FarmingFortuneConfig();
-
- public static class FarmingFortuneConfig {
- @Expose
- @ConfigOption(
- name = "FF Display",
- desc = "Displays the true Farming Fortune for the current crop, including all crop-specific and hidden bonuses."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean display = true;
-
- @Expose
- @ConfigOption(
- name = "Show As Drop Multiplier",
- desc = "Adds 100 to the displayed Farming Fortune so that it represents a drop multiplier rather than" +
- " the chance for bonus drops. "
- )
- @ConfigEditorBoolean
- public boolean dropMultiplier = true;
-
- @ConfigOption(name = "Farming Fortune Guide", desc = "Opens a guide that breaks down your Farming Fortune.\n§eCommand: /ff")
- @ConfigEditorButton(buttonText = "Open")
- public Runnable open = Commands::openFortuneGuide;
-
- @Expose
- public Position pos = new Position(5, -180, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Tooltip Tweaks", desc = "")
- @Accordion
- public TooltipTweaksConfig tooltipTweak = new TooltipTweaksConfig();
-
- public static class TooltipTweaksConfig {
- @Expose
- @ConfigOption(
- name = "Compact Descriptions",
- desc = "Hides redundant parts of reforge descriptions, generic counter description, and Farmhand perk explanation."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean compactToolTooltips = false;
-
- @Expose
- @ConfigOption(
- name = "Breakdown Hotkey",
- desc = "When the keybind is pressed, show a breakdown of all fortune sources on a tool."
- )
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_LSHIFT)
- public int fortuneTooltipKeybind = Keyboard.KEY_LSHIFT;
-
- @Expose
- @ConfigOption(
- name = "Tooltip Format",
- desc = "Show crop-specific Farming Fortune in tooltip.\n" +
- "§fShow: §7Crop-specific Fortune indicated as §6[+196]\n" +
- "§fReplace: §7Edits the total Fortune to include crop-specific Fortune."
- )
- @ConfigEditorDropdown(values = {"Default", "Show", "Replace"})
- public int cropTooltipFortune = 1;
-
- @Expose
- @ConfigOption(
- name = "Total Crop Milestone",
- desc = "Shows the progress bar till maxed crop milestone in the crop milestone inventory."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean cropMilestoneTotalProgress = true;
- }
-
- @Expose
- @ConfigOption(name = "Yaw and Pitch", desc = "")
- @Accordion
- public YawPitchDisplayConfig yawPitchDisplay = new YawPitchDisplayConfig();
-
- public static class YawPitchDisplayConfig {
-
- @Expose
- @ConfigOption(name = "Enable", desc = "Displays yaw and pitch while holding a farming tool. Automatically fades out if there is no movement.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Yaw Precision", desc = "Yaw precision up to specified decimal.")
- @ConfigEditorSlider(
- minValue = 1,
- maxValue = 10,
- minStep = 1
- )
- public int yawPrecision = 4;
-
- @Expose
- @ConfigOption(name = "Pitch Precision", desc = "Pitch precision up to specified decimal.")
- @ConfigEditorSlider(
- minValue = 1,
- maxValue = 10,
- minStep = 1
- )
- public int pitchPrecision = 4;
-
- @Expose
- @ConfigOption(name = "Display Timeout", desc = "Duration in seconds for which the overlay is being displayed after moving.")
- @ConfigEditorSlider(
- minValue = 1,
- maxValue = 20,
- minStep = 1
- )
- public int timeout = 5;
-
- @Expose
- @ConfigOption(name = "Show Without Tool", desc = "Does not require you to hold a tool for the overlay to show.")
- @ConfigEditorBoolean
- public boolean showWithoutTool = false;
-
- @Expose
- @ConfigOption(name = "Show Outside Garden", desc = "The overlay will work outside of the Garden.")
- @ConfigEditorBoolean
- public boolean showEverywhere = false;
-
- @Expose
- @ConfigOption(name = "Ignore Timeout", desc = "Ignore the timeout after not moving mouse.")
- @ConfigEditorBoolean
- public boolean showAlways = false;
-
- @Expose
- public Position pos = new Position(445, 225, false, true);
- @Expose
- public Position posOutside = new Position(445, 225, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Crop Start Location", desc = "")
- @Accordion
- public CropStartLocationConfig cropStartLocation = new CropStartLocationConfig();
-
- public static class CropStartLocationConfig {
-
- @Expose
- @ConfigOption(name = "Enable", desc = "Show the start waypoint for your farm with the currently holding tool.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- }
-
- @Expose
- @ConfigOption(name = "Garden Plot Icon", desc = "")
- @Accordion
- public PlotIconConfig plotIcon = new PlotIconConfig();
-
- public static class PlotIconConfig {
- @Expose
- @ConfigOption(name = "Enable", desc = "Enable icon replacement in the Configure Plots menu.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @ConfigOption(name = "Hard Reset", desc = "Reset every slot to its original item.")
- @ConfigEditorButton(buttonText = "Reset")
- public Runnable hardReset = () -> {
- GardenPlotIcon.INSTANCE.setHardReset(true);
- LorenzUtils.INSTANCE.sendCommandToServer("desk");
- };
- }
-
- @Expose
- @ConfigOption(name = "Plot Price", desc = "Show the price of the plot in coins when inside the Configure Plots inventory.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean plotPrice = true;
-
- @Expose
- @ConfigOption(name = "Desk in Menu", desc = "Show a Desk button in the SkyBlock Menu. Opens the /desk command on click.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean deskInSkyBlockMenu = true;
-
-
- @Expose
- @ConfigOption(name = "Fungi Cutter Warning", desc = "Warn when breaking mushroom with the wrong Fungi Cutter mode.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean fungiCutterWarn = true;
-
- @Expose
- @ConfigOption(name = "Burrowing Spores", desc = "Show a notification when a Burrowing Spores spawns while farming mushrooms.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean burrowingSporesNotification = true;
-
- @Expose
- @ConfigOption(name = "Wild Strawberry", desc = "Show a notification when a Wild Strawberry Dye drops while farming.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean wildStrawberryDyeNotification = true;
-
- @Expose
- @ConfigOption(
- name = "FF for Contest",
- desc = "Show the minimum needed Farming Fortune for reaching each medal in Jacob's Farming Contest inventory."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean farmingFortuneForContest = true;
-
- @Expose
- public Position farmingFortuneForContestPos = new Position(180, 156, false, true);
-
- @Expose
- @ConfigOption(
- name = "Contest Time Needed",
- desc = "Show the time and missing FF for every crop inside Jacob's Farming Contest inventory."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean jacobContextTimes = true;
-
- @Expose
- public Position jacobContextTimesPos = new Position(-359, 149, false, true);
-
- @Expose
- @ConfigOption(
- name = "Contest Summary",
- desc = "Show the average Blocks Per Second and blocks clicked at the end of a Jacob Farming Contest in chat."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean jacobContestSummary = true;
-
- @Expose
- @ConfigOption(name = "Always Finnegan", desc = "Forcefully set the Finnegan Farming Simulator perk to be active. This is useful if the auto mayor detection fails.")
- @ConfigEditorBoolean
- public boolean forcefullyEnabledAlwaysFinnegan = false;
-
- @Expose
- public Position cropSpeedMeterPos = new Position(278, -236, false, true);
-
- @Expose
- @ConfigOption(name = "Enable Plot Borders", desc = "Enable the use of F3 + G hotkey to show Garden plot borders. Similar to how later Minecraft version render chunk borders.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean plotBorders = true;
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/InventoryConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/InventoryConfig.java
deleted file mode 100644
index c0906d512..000000000
--- a/src/main/java/at/hannibal2/skyhanni/config/features/InventoryConfig.java
+++ /dev/null
@@ -1,442 +0,0 @@
-package at.hannibal2.skyhanni.config.features;
-
-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.Accordion;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorColour;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorDraggableList;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
-import io.github.moulberry.moulconfig.annotations.ConfigOption;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-public class InventoryConfig {
-
- @Expose
- @ConfigOption(name = "Not Clickable Items", desc = "")
- @Accordion
- public HideNotClickableConfig hideNotClickable = new HideNotClickableConfig();
-
- public static class HideNotClickableConfig {
- @Expose
- @ConfigOption(name = "Enabled", desc = "Hide items that are not clickable in the current inventory: ah, bz, accessory bag, etc.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean items = false;
-
- @Expose
- @ConfigOption(name = "Block Clicks", desc = "Block the clicks on these items.")
- @ConfigEditorBoolean
- public boolean itemsBlockClicks = true;
-
- @Expose
- @ConfigOption(
- name = "Opacity",
- desc = "How strong should the items be grayed out?"
- )
- @ConfigEditorSlider(
- minValue = 0,
- maxValue = 255,
- minStep = 5
- )
- public int opacity = 180;
-
- @Expose
- @ConfigOption(name = "Bypass With Control", desc = "Adds the ability to bypass not clickable items when holding the control key.")
- @ConfigEditorBoolean
- public boolean itemsBypass = true;
-
- @Expose
- @ConfigOption(name = "Green Line", desc = "Adds green line around items that are clickable.")
- @ConfigEditorBoolean
- public boolean itemsGreenLine = true;
-
- }
-
- @Expose
- @ConfigOption(name = "RNG Meter", desc = "")
- @Accordion
- public RngMeterConfig rngMeter = new RngMeterConfig();
-
- public static class RngMeterConfig {
- @Expose
- @ConfigOption(name = "Floor Names", desc = "Show the Floor names in the Catacombs RNG Meter inventory.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean floorName = false;
-
- @Expose
- @ConfigOption(name = "No Drop", desc = "Highlight floors without a drop selected in the Catacombs RNG Meter inventory.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean noDrop = false;
-
- @Expose
- @ConfigOption(name = "Selected Drop", desc = "Highlight the selected drop in the Catacombs or Slayer RNG Meter inventory.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean selectedDrop = false;
- }
-
- @Expose
- @ConfigOption(name = "Stats Tuning", desc = "")
- @Accordion
- public StatsTuningConfig statsTuning = new StatsTuningConfig();
-
- public static class StatsTuningConfig {
- @Expose
- @ConfigOption(name = "Selected Stats", desc = "Show the tuning stats in the Thaumaturgy inventory.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean selectedStats = true;
-
- @Expose
- @ConfigOption(name = "Tuning Points", desc = "Show the amount of selected Tuning Points in the Stats Tuning inventory.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean points = true;
-
- @Expose
- @ConfigOption(name = "Selected Template", desc = "Highlight the selected template in the Stats Tuning inventory.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean selectedTemplate = true;
-
- @Expose
- @ConfigOption(name = "Template Stats", desc = "Show the type of stats for the Tuning Point templates.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean templateStats = true;
- }
-
- @Expose
- @ConfigOption(name = "Jacob Farming Contest", desc = "")
- @Accordion
- public JacobFarmingContestConfig jacobFarmingContests = new JacobFarmingContestConfig();
-
- public static class JacobFarmingContestConfig {
- @Expose
- @ConfigOption(name = "Unclaimed Rewards", desc = "Highlight contests with unclaimed rewards in the Jacob inventory.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlightRewards = true;
-
- @Expose
- @ConfigOption(name = "Contest Time", desc = "Adds the real time format to the Contest description.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean realTime = true;
-
- @Expose
- @ConfigOption(name = "Medal Icon", desc = "Adds a symbol that shows what medal you received in this Contest. " +
- "§eIf you use a texture pack this may cause conflicting icons.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean medalIcon = true;
-
- @Expose
- @ConfigOption(name = "Finnegan Icon", desc = "Uses a different indicator for when the Contest happened during Mayor Finnegan.")
- @ConfigEditorBoolean
- public boolean finneganIcon = true;
- }
-
-
- @Expose
- @ConfigOption(name = "Sack Items Display", desc = "")
- @Accordion
- public SackDisplayConfig sackDisplay = new SackDisplayConfig();
-
- public static class SackDisplayConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Show contained items inside a sack inventory.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(
- name = "Highlight Full",
- desc = "Highlight items that are full in red.\n" +
- "§eDoes not need the option above to be enabled."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlightFull = true;
-
- @Expose
- @ConfigOption(name = "Number Format", desc = "Either show Default, Formatted or Unformatted numbers.\n" +
- "§eDefault: §72,240/2.2k\n" +
- "§eFormatted: §72.2k/2.2k\n" +
- "§eUnformatted: §72,240/2,200")
- @ConfigEditorDropdown(values = {"Default", "Formatted", "Unformatted"})
- public int numberFormat = 1;
-
- @Expose
- @ConfigOption(name = "Extra space", desc = "Space between each line of text.")
- @ConfigEditorSlider(
- minValue = 0,
- maxValue = 10,
- minStep = 1)
- public int extraSpace = 1;
-
- @Expose
- @ConfigOption(name = "Sorting Type", desc = "Sorting type of items in sack.")
- @ConfigEditorDropdown(values = {"Descending (Stored)", "Ascending (Stored)", "Descending (Price)", "Ascending (Price)"})
- public int sortingType = 0;
-
- @Expose
- @ConfigOption(name = "Item To Show", desc = "Choose how many items are displayed. (Some sacks have too many items to fit\n" +
- "in larger GUI scales, like the nether sack.)")
- @ConfigEditorSlider(
- minValue = 0,
- maxValue = 45,
- minStep = 1
- )
- public int itemToShow = 15;
-
- @Expose
- @ConfigOption(name = "Show Empty Item", desc = "Show empty item quantity in the display.")
- @ConfigEditorBoolean
- public boolean showEmpty = true;
-
- @Expose
- @ConfigOption(name = "Show Price", desc = "Show price for each item in sack.")
- @ConfigEditorBoolean
- public boolean showPrice = true;
-
- @Expose
- @ConfigOption(name = "Price Format", desc = "Format of the price displayed.\n" +
- "§eFormatted: §7(12k)\n" +
- "§eUnformatted: §7(12,421)")
- @ConfigEditorDropdown(values = {"Formatted", "Unformatted"})
- public int priceFormat = 0;
-
- @Expose
- @ConfigOption(name = "Show Price From", desc = "Show price from Bazaar or NPC.")
- @ConfigEditorDropdown(values = {"Bazaar", "NPC"})
- public int priceFrom = 0;
-
- @Expose
- public Position position = new Position(144, 139, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Chest Value", desc = "")
- @Accordion
- public ChestValueConfig chestValueConfig = new ChestValueConfig();
-
- public static class ChestValueConfig {
- @Expose
- @ConfigOption(name = "Enabled", desc = "Enable estimated value of chest.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Enabled in dungeons", desc = "Enable the feature in dungeons.")
- @ConfigEditorBoolean
- public boolean enableInDungeons = false;
-
- @Expose
- @ConfigOption(name = "Enable during Item Value", desc = "Show this display even if the Estimated Item Value is visible.")
- @ConfigEditorBoolean
- public boolean showDuringEstimatedItemValue = false;
-
- @Expose
- @ConfigOption(name = "Show Stacks", desc = "Show the item icon before name.")
- @ConfigEditorBoolean
- public boolean showStacks = true;
-
- @Expose
- @ConfigOption(name = "Display Type", desc = "Try to align everything to look nicer.")
- @ConfigEditorBoolean
- public boolean alignedDisplay = true;
-
- @Expose
- @ConfigOption(name = "Name Length", desc = "Reduce item name length to gain extra space on screen.\n§cCalculated in pixels!")
- @ConfigEditorSlider(minStep = 1, minValue = 100, maxValue = 150)
- public int nameLength = 100;
-
- @Expose
- @ConfigOption(name = "Highlight Slot", desc = "Highlight slot where the item is when you hover over it in the display.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enableHighlight = true;
-
- @Expose
- @ConfigOption(name = "Highlight Color", desc = "Choose the highlight color.")
- @ConfigEditorColour
- public String highlightColor = "0:249:0:255:88";
-
- @Expose
- @ConfigOption(name = "Sorting Type", desc = "Price sorting type.")
- @ConfigEditorDropdown(values = {"Descending", "Ascending"})
- public int sortingType = 0;
-
- @Expose
- @ConfigOption(name = "Value formatting Type", desc = "Format of the price.")
- @ConfigEditorDropdown(values = {"Short", "Long"})
- public int formatType = 0;
-
- @Expose
- @ConfigOption(name = "Item To Show", desc = "Choose how many items are displayed.\n" +
- "All items in the chest are still counted for the total value.")
- @ConfigEditorSlider(
- minValue = 0,
- maxValue = 54,
- minStep = 1
- )
- public int itemToShow = 15;
-
- @Expose
- @ConfigOption(name = "Hide below", desc = "Item item value below configured amount.\n" +
- "Items are still counted for the total value.")
- @ConfigEditorSlider(
- minValue = 50_000,
- maxValue = 10_000_000,
- minStep = 50_000
- )
- public int hideBelow = 100_000;
-
-
- @Expose
- public Position position = new Position(107, 141, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Helper", desc = "")
- @Accordion
- public HelperConfig helper = new HelperConfig();
-
- public static class HelperConfig {
- @Expose
- @ConfigOption(name = "Melody's Hair Harp", desc = "")
- @Accordion
- public HarpConfig harp = new HarpConfig();
-
- public static class HarpConfig {
- @Expose
- @ConfigOption(name = "Use Keybinds", desc = "In the Harp, press buttons with your number row on the keyboard instead of clicking.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean keybinds = false;
-
- @Expose
- @ConfigOption(name = "Show Numbers", desc = "In the Harp, show buttons as stack size (intended to be used with the Keybinds).")
- @ConfigEditorBoolean
- public boolean showNumbers = false;
- }
-
- @Expose
- @ConfigOption(name = "Tia Relay Abiphone Network Maintenance", desc = "")
- @Accordion
- public TiaRelayConfig tiaRelay = new TiaRelayConfig();
-
- public static class TiaRelayConfig {
-
- @Expose
- @ConfigOption(name = "Sound Puzzle Helper", desc = "Helps with solving the sound puzzle for Tia (The 9 Operator Chips to do maintainance for the Abiphone Network).")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean soundHelper = true;
-
- @Expose
- @ConfigOption(name = "Next Waypoint", desc = "Show the next relay waypoint for Tia the Fairy, where maintenance for the Abiphone network needs to be done.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean nextWaypoint = true;
-
- @Expose
- @ConfigOption(name = "All Waypoints", desc = "Show all relay waypoints at once (intended for debugging).")
- @ConfigEditorBoolean
- public boolean allWaypoints = false;
-
- @Expose
- @ConfigOption(name = "Mute Sound", desc = "Mutes the sound when close to the relay.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean tiaRelayMute = true;
- }
- }
-
- @Expose
- @ConfigOption(
- 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"
- }
- )
- public List<Integer> itemNumberAsStackSize = new ArrayList<>(Arrays.asList(3, 9, 11, 12));
-
- @Expose
- @ConfigOption(
- name = "Quick Craft Confirmation",
- desc = "Require Ctrl+Click to craft items that aren't often quick crafted " +
- "(e.g. armor, weapons, accessories). Sack items can be crafted normally."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean quickCraftingConfirmation = false;
-
- @Expose
- @ConfigOption(name = "Sack Name", desc = "Show an abbreviation of the sack name.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean displaySackName = false;
-
- @Expose
- @ConfigOption(name = "Anvil Combine Helper", desc = "Suggests the same item in the inventory when trying to combine two items in the anvil.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean anvilCombineHelper = false;
-
- @Expose
- @ConfigOption(name = "Item Stars",
- desc = "Show a compact star count in the item name for all items.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean itemStars = false;
-
- @Expose
- @ConfigOption(name = "Missing Tasks",
- desc = "Highlight missing tasks in the SkyBlock Level Guide inventory.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlightMissingSkyBlockLevelGuide = true;
-
- @Expose
- @ConfigOption(name = "Highlight Auctions",
- desc = "Highlight own items that are sold in green and that are expired in red.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlightAuctions = true;
-
- @Expose
- @ConfigOption(name = "Shift Click Equipment", desc = "Makes normal clicks to shift clicks in equipment inventory")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean shiftClickForEquipment = false;
-
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/ItemAbilityConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/ItemAbilityConfig.java
deleted file mode 100644
index 30ba1227f..000000000
--- a/src/main/java/at/hannibal2/skyhanni/config/features/ItemAbilityConfig.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package at.hannibal2.skyhanni.config.features;
-
-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.Accordion;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorColour;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown;
-import io.github.moulberry.moulconfig.annotations.ConfigOption;
-
-public class ItemAbilityConfig {
-
- @Expose
- @ConfigOption(name = "Ability Cooldown", desc = "Show the cooldown of item abilities.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean itemAbilityCooldown = false;
-
- @Expose
- @ConfigOption(name = "Ability Cooldown Background", desc = "Show the cooldown color of item abilities in the background.")
- @ConfigEditorBoolean
- public boolean itemAbilityCooldownBackground = false;
-
- @Expose
- @ConfigOption(name = "Fire Veil", desc = "")
- @Accordion
- public FireVeilWandConfig fireVeilWands = new FireVeilWandConfig();
-
- public static class FireVeilWandConfig {
- @Expose
- @ConfigOption(name = "Fire Veil Design", desc = "Changes the flame particles of the Fire Veil Wand ability.")
- @ConfigEditorDropdown(values = {"Particles", "Line", "Off"})
- public int display = 0;
-
- @Expose
- @ConfigOption(
- name = "Line Color",
- desc = "Changes the color of the Fire Veil Wand line."
- )
- @ConfigEditorColour
- public String displayColor = "0:245:255:85:85";
- }
-
- @ConfigOption(name = "Chicken Head", desc = "")
- @Accordion
- @Expose
- public ChickenHeadConfig chickenHead = new ChickenHeadConfig();
-
- public static class ChickenHeadConfig {
-
- @Expose
- @ConfigOption(name = "Checken Head Timer", desc = "Show the cooldown until the next time you can lay an egg with the Chicken Head.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean displayTimer = false;
-
- @Expose
- public Position position = new Position(-372, 73, false, true);
-
- @Expose
- @ConfigOption(name = "Hide Chat", desc = "Hide the 'You laid an egg!' chat message.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideChat = true;
- }
-
- @Expose
- @ConfigOption(name = "Depleted Bonzo's Masks",
- desc = "Highlights used Bonzo's Masks and Spirit Masks with a background.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean depletedBonzosMasks = false;
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/MiningConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/MiningConfig.java
deleted file mode 100644
index 840096cac..000000000
--- a/src/main/java/at/hannibal2/skyhanni/config/features/MiningConfig.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package at.hannibal2.skyhanni.config.features;
-
-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.Accordion;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorDraggableList;
-import io.github.moulberry.moulconfig.annotations.ConfigOption;
-import io.github.moulberry.moulconfig.observer.Property;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-public class MiningConfig {
-
- @Expose
- @ConfigOption(name = "Powder Tracker", desc = "")
- @Accordion
- public PowderTrackerConfig powderTracker = new PowderTrackerConfig();
-
- public static class PowderTrackerConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Enable the Powder Tracker overlay for mining.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Only when Grinding", desc = "Only show the overlay when powder grinding.")
- @ConfigEditorBoolean
- public boolean onlyWhenPowderGrinding = false;
-
- @Expose
- @ConfigOption(name = "Great Explorer", desc = "Enable this if your Great Explorer perk is maxed.")
- @ConfigEditorBoolean
- public boolean greatExplorerMaxed = false;
-
- @Expose
- @ConfigOption(
- 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"
- }
- )
- 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)));
-
- @Expose
- public Position position = new Position(-274, 0, false, true);
-
- }
-
- @Expose
- @ConfigOption(name = "Highlight Commission Mobs", desc = "Highlight Mobs that are part of active commissions.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlightCommissionMobs = false;
-
- @Expose
- @ConfigOption(name = "King Talisman Helper", desc = "Show kings you have not talked to yet, and when the next missing king will appear.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean kingTalismanHelper = false;
-
- @Expose
- public Position kingTalismanHelperPos = new Position(-400, 220, false, true);
-
- @Expose
- @ConfigOption(name = "Names in Core", desc = "Show the names of the 4 areas while in the center of the Crystal Hollows.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean crystalHollowsNamesInCore = false;
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/MinionsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/MinionsConfig.java
deleted file mode 100644
index a05b913dc..000000000
--- a/src/main/java/at/hannibal2/skyhanni/config/features/MinionsConfig.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package at.hannibal2.skyhanni.config.features;
-
-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.Accordion;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorColour;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
-import io.github.moulberry.moulconfig.annotations.ConfigOption;
-
-public class MinionsConfig {
-
- @Expose
- @ConfigOption(name = "Name Display", desc = "Show the minion name and tier over the minion.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean nameDisplay = true;
-
- @Expose
- @ConfigOption(name = "Only Tier", desc = "Show only the tier number over the minion. (Useful for Bingo)")
- @ConfigEditorBoolean
- public boolean nameOnlyTier = false;
-
- @Expose
- @ConfigOption(name = "Last Clicked", desc = "")
- @Accordion
- public LastClickedMinionConfig lastClickedMinion = new LastClickedMinionConfig();
-
- public static class LastClickedMinionConfig {
- @Expose
- @ConfigOption(name = "Last Minion Display", desc = "Marks the location of the last clicked minion, even through walls.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean display = false;
-
- @Expose
- @ConfigOption(
- name = "Last Minion Color",
- desc = "The color in which the last minion should be displayed."
- )
- @ConfigEditorColour
- public String color = "0:245:85:255:85";
-
- @Expose
- @ConfigOption(
- name = "Last Minion Time",
- desc = "Time in seconds how long the last minion should be displayed."
- )
- @ConfigEditorSlider(
- minValue = 3,
- maxValue = 120,
- minStep = 1
- )
- public int time = 20;
- }
-
- @Expose
- @ConfigOption(name = "Emptied Time", desc = "")
- @Accordion
- public EmptiedTimeConfig emptiedTime = new EmptiedTimeConfig();
-
- public static class EmptiedTimeConfig {
- @Expose
- @ConfigOption(name = "Emptied Time Display", desc = "Show the time when the hopper in the minion was last emptied.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean display = false;
-
- @Expose
- @ConfigOption(
- name = "Distance",
- desc = "Maximum distance to display minion data."
- )
- @ConfigEditorSlider(
- minValue = 3,
- maxValue = 30,
- minStep = 1
- )
- public int distance = 10;
- }
-
- @Expose
- @ConfigOption(name = "Hopper Profit Display", desc = "Use the hopper's held coins and the last empty time to calculate the coins per day.")
- @ConfigEditorBoolean
- public boolean hopperProfitDisplay = true;
-
- @Expose
- public Position hopperProfitPos = new Position(360, 90, false, true);
-
- @Expose
- @ConfigOption(name = "Hide Mob Nametag", desc = "Hiding the nametag of mobs close to minions.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideMobsNametagNearby = false;
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/MiscConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/MiscConfig.java
deleted file mode 100644
index 86f60a8f7..000000000
--- a/src/main/java/at/hannibal2/skyhanni/config/features/MiscConfig.java
+++ /dev/null
@@ -1,827 +0,0 @@
-package at.hannibal2.skyhanni.config.features;
-
-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.Accordion;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorColour;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorDraggableList;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorText;
-import io.github.moulberry.moulconfig.annotations.ConfigOption;
-import io.github.moulberry.moulconfig.observer.Property;
-import org.lwjgl.input.Keyboard;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-public class MiscConfig {
-
- @Expose
- @ConfigOption(name = "Pet", desc = "")
- @Accordion
- public PetConfig pets = new PetConfig();
- public static class PetConfig {
- @Expose
- @ConfigOption(name = "Pet Display", desc = "Show the currently active pet.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean display = false;
-
- @Expose
- @ConfigOption(name = "Pet Experience Tooltip", desc = "")
- @Accordion
- public PetExperienceToolTipConfig petExperienceToolTip = new PetExperienceToolTipConfig();
-
- public static class PetExperienceToolTipConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Show the full pet exp and the progress to level 100 (ignoring rarity) when hovering over a pet while pressing shift key.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean petDisplay = true;
-
- @Expose
- @ConfigOption(name = "Show Always", desc = "Show this info always, even if not pressing shift key.")
- @ConfigEditorBoolean
- public boolean showAlways = false;
-
- @Expose
- @ConfigOption(name = "Dragon Egg", desc = "For a Golden Dragon Egg, show progress to level 100 instead of 200.")
- @ConfigEditorBoolean
- public boolean showGoldenDragonEgg = true;
-
- }
- }
-
- @Expose
- public Position petDisplayPos = new Position(-330, -15, false, true);
-
- @ConfigOption(name = "Hide Armor", desc = "")
- @Accordion
- @Expose
- public HideArmor hideArmor2 = new HideArmor();
-
- public static class HideArmor {
-
- @Expose
- @ConfigOption(name = "Mode", desc = "Hide the armor of players.")
- @ConfigEditorDropdown(values = {"All", "Own Armor", "Other's Armor", "Off"})
- public int mode = 3;
-
- @Expose
- @ConfigOption(name = "Only Helmet", desc = "Only hide the helmet.")
- @ConfigEditorBoolean()
- public Boolean onlyHelmet = false;
-
- }
-
- @Expose
- @ConfigOption(name = "Potion Effects", desc = "")
- @Accordion
- public PotionEffectsConfig potionEffect = new PotionEffectsConfig();
- public static class PotionEffectsConfig {
- @Expose
- @ConfigOption(name = "Non God Pot Effects", desc = "Display the active potion effects that are not part of the God Pot.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean nonGodPotEffectDisplay = false;
-
- @Expose
- @ConfigOption(name = "Show Mixins", desc = "Include God Pot mixins in the Non God Pot Effects display.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean nonGodPotEffectShowMixins = false;
-
- @Expose
- public Position nonGodPotEffectPos = new Position(10, 10, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Particle Hider", desc = "")
- @Accordion
- public ParticleHiderConfig particleHiders = new ParticleHiderConfig();
- public static class ParticleHiderConfig {
- @Expose
- @ConfigOption(name = "Blaze Particles", desc = "Hide Blaze particles.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideBlazeParticles = false;
-
- @Expose
- @ConfigOption(name = "Enderman Particles", desc = "Hide Enderman particles.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideEndermanParticles = false;
-
- @Expose
- @ConfigOption(name = "Fireball Particles", desc = "Hide fireball particles.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideFireballParticles = true;
-
- @Expose
- @ConfigOption(name = "Fire Particles", desc = "Hide particles from the fire block.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideFireBlockParticles = true;
-
- @Expose
- @ConfigOption(name = "Smoke Particles", desc = "Hide smoke particles.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideSmokeParticles = false;
-
- @Expose
- @ConfigOption(name = "Far Particles", desc = "Hide particles that are more than 40 blocks away.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideFarParticles = true;
-
- @Expose
- @ConfigOption(name = "Close Redstone Particles", desc = "Hide Redstone particles around the player (appear for some potion effects).")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideCloseRedstoneParticles = true;
- }
-
- @Expose
- @ConfigOption(name = "Estimated Item Value", desc = "(Prices for Enchantments, Reforge Stones, Gemstones, Drill Parts and more)")
- @Accordion
- public EstimatedItemValueConfig estimatedItemValues = new EstimatedItemValueConfig();
- public static class EstimatedItemValueConfig {
- @Expose
- @ConfigOption(name = "Enable Estimated Price", desc = "Displays an Estimated Item Value for the item you hover over.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Hotkey", desc = "Press this key to show the Estimated Item Value.")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
- public int hotkey = Keyboard.KEY_NONE;
-
- @Expose
- @ConfigOption(name = "Show Always", desc = "Ignore the hotkey and always display the item value.")
- @ConfigEditorBoolean
- public boolean alwaysEnabled = true;
-
- @Expose
- @ConfigOption(name = "Enchantments Cap", desc = "Only show the top # most expensive enchantments.")
- @ConfigEditorSlider(
- minValue = 1,
- maxValue = 30,
- minStep = 1
- )
- public Property<Integer> enchantmentsCap = Property.of(7);
-
- @Expose
- @ConfigOption(name = "Show Exact Price", desc = "Show the exact total price instead of the compact number.")
- @ConfigEditorBoolean
- public boolean exactPrice = false;
-
- @Expose
- @ConfigOption(name = "Show Armor Value", desc = "Show the value of the full armor set in the Wardrobe inventory.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean armor = true;
-
- @Expose
- public Position itemPriceDataPos = new Position(140, 90, false, true);
- }
-
- @ConfigOption(name = "Discord Rich Presence", desc = "")
- @Accordion
- @Expose
- public DiscordRPC discordRPC = new DiscordRPC();
-
- public static class DiscordRPC {
-
- @Expose
- @ConfigOption(name = "Enable Discord RPC", desc = "Details about your SkyBlock session displayed through Discord.")
- @ConfigEditorBoolean
- @FeatureToggle
- public Property<Boolean> enabled = Property.of(false);
-
- @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);
-
- @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);
-
- @Expose
- @ConfigOption(name = "Custom", desc = "What should be displayed if you select \"Custom\" above.")
- @ConfigEditorText
- public Property<String> customText = Property.of("");
-
- @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"
- }
- )
- 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);
- }
-
- @ConfigOption(name = "Trevor The Trapper", desc = "")
- @Accordion
- @Expose
- public TrevorTheTrapper trevorTheTrapper = new TrevorTheTrapper();
-
- public static class TrevorTheTrapper {
-
- @Expose
- @ConfigOption(
- name = "Enable Data Tracker",
- desc = "Tracks all of your data from doing Trevor Quests.\n" +
- "Shows based on the setting below."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean dataTracker = true;
-
- @Expose
- @ConfigOption(
- name = "Show Between Quests",
- desc = "Shows the tracker during and between quests otherwise it will only show during them." +
- "Will show in the Trapper's Den regardless. §cToggle 'Enable Data Tracker' above."
- )
- @ConfigEditorBoolean
- public boolean displayType = true;
-
- @Expose
- @ConfigOption(
- 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"
- }
- )
- public List<Integer> textFormat = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11));
-
- @Expose
- public Position position = new Position(10, 80, false, true);
-
- @Expose
- @ConfigOption(name = "Trapper Solver", desc = "Assists you in finding Trevor's mobs. §eNote: May not always work as expected. " +
- "§cWill not help you to find rabbits or sheep in the Oasis!")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean trapperSolver = true;
-
- @Expose
- @ConfigOption(name = "Mob Dead Warning", desc = "Show a message when Trevor's mob dies.")
- @ConfigEditorBoolean
- public boolean trapperMobDiedMessage = true;
-
- @Expose
- @ConfigOption(name = "Warp to Trapper", desc = "Warp to Trevor's Den. Works only inside the Farming Islands.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean warpToTrapper = false;
-
- @Expose
- @ConfigOption(name = "Accept Trapper Quest", desc = "Click this key after the chat prompt to accept Trevor's quest.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean acceptQuest = false;
-
- @Expose
- @ConfigOption(name = "Trapper Hotkey", desc = "Press this key to warp to Trevor's Den or to accept the quest. " +
- "§eRequires the relevant above settings to be toggled")
- @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
- public int keyBindWarpTrapper = Keyboard.KEY_NONE;
-
-
- @Expose
- @ConfigOption(name = "Trapper Cooldown", desc = "Change the color of Trevor and adds a cooldown over his head.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean trapperTalkCooldown = true;
-
- @Expose
- @ConfigOption(
- name = "Trapper Cooldown GUI",
- desc = "Show the cooldown on screen in an overlay (intended for Abiphone users)."
- )
- @ConfigEditorBoolean
- public boolean trapperCooldownGui = false;
-
- @Expose
- public Position trapperCooldownPos = new Position(10, 10, false, true);
- }
-
- @ConfigOption(name = "Teleport Pads On Private Island", desc = "")
- @Accordion
- @Expose
- public TeleportPad teleportPad = new TeleportPad();
-
- public static class TeleportPad {
-
- @Expose
- @ConfigOption(name = "Compact Name", desc = "Hide the 'Warp to' and 'No Destination' texts over teleport pads.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean compactName = false;
-
- @Expose
- @ConfigOption(name = "Inventory Numbers", desc = "Show the number of the teleport pads inside the 'Change Destination' inventory as stack size.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean inventoryNumbers = false;
- }
-
- @ConfigOption(name = "Pocket Sack-In-A-Sack", desc = "")
- @Accordion
- @Expose
- public PocketSackInASack pocketSackInASack = new PocketSackInASack();
-
- public static class PocketSackInASack {
-
- @Expose
- @ConfigOption(name = "Show in Overlay", desc = "Show the number of Pocket Sack-In-A-Sack applied on a sack icon as an overlay.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean showOverlay = false;
-
- @Expose
- @ConfigOption(name = "Replace In Lore", desc = "Replace how text is displayed in lore.\nShow §eis stitched with 2/3...\n§7Instead of §eis stitched with two...")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean replaceLore = true;
- }
-
- @ConfigOption(name = "Quick Mod Menu Switch", desc = "")
- @Accordion
- @Expose
- public QuickModMenuSwitch quickModMenuSwitch = new QuickModMenuSwitch();
-
- public static class QuickModMenuSwitch {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Adding a mod list, allowing to quickly switch between different mod menus.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Inside Escape Menu", desc = "Show the mod list while inside the Escape menu.")
- @ConfigEditorBoolean
- public boolean insideEscapeMenu = true;
-
- @Expose
- @ConfigOption(name = "Inside Inventory", desc = "Show the mod list while inside the player inventory (no chest inventory).")
- @ConfigEditorBoolean
- public boolean insidePlayerInventory = false;
-
- @Expose
- public Position pos = new Position(-178, 143, false, true);
- }
-
- @Expose
- @ConfigOption(name = "Cosmetic", desc = "")
- @Accordion
- public CosmeticConfig cosmeticConfig = new CosmeticConfig();
-
- public static class CosmeticConfig {
-
- @Expose
- @ConfigOption(name = "Following Line", desc = "")
- @Accordion
- public FollowingLineConfig followingLineConfig = new FollowingLineConfig();
-
- public static class FollowingLineConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Draw a colored line behind the player.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Line Color", desc = "Color of the line.")
- @ConfigEditorColour
- public String lineColor = "0:255:255:255:255";
-
- @Expose
- @ConfigOption(name = "Time Alive", desc = "Time in seconds until the line fades out.")
- @ConfigEditorSlider(minStep = 1, minValue = 1, maxValue = 30)
- public int secondsAlive = 3;
-
- @Expose
- @ConfigOption(name = "Max Line Width", desc = "Max width of the line.")
- @ConfigEditorSlider(minStep = 1, minValue = 1, maxValue = 10)
- public int lineWidth = 4;
-
- @Expose
- @ConfigOption(name = "Behind Blocks", desc = "Show behind blocks.")
- @ConfigEditorBoolean
- public boolean behindBlocks = false;
- }
-
- @Expose
- @ConfigOption(name = "Arrow Trail", desc = "")
- @Accordion
- public ArrowTrailConfig arrowTrailConfig = new ArrowTrailConfig();
-
- public static class ArrowTrailConfig {
- @Expose
- @ConfigOption(name = "Enabled", desc = "Draw a colored line behind arrows in the air.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Hide Nonplayer Arrows", desc = "Only shows for arrows the player has shot.")
- @ConfigEditorBoolean
- public boolean hideOtherArrows = true;
-
- @Expose
- @ConfigOption(name = "Arrow Color", desc = "Color of the line.")
- @ConfigEditorColour
- public String arrowColor = "0:200:85:255:85";
-
- @Expose
- @ConfigOption(name = "Player Arrows", desc = "Different color for the line of arrows that you have shot.")
- @ConfigEditorBoolean
- public boolean handlePlayerArrowsDifferently = false;
-
- @Expose
- @ConfigOption(name = "Player Arrow Color", desc = "Color of the line of your own arrows.")
- @ConfigEditorColour
- public String playerArrowColor = "0:200:85:255:255";
-
- @Expose
- @ConfigOption(name = "Time Alive", desc = "Time in seconds until the trail fades out.")
- @ConfigEditorSlider(minStep = 0.1f, minValue = 0.1f, maxValue = 10)
- public float secondsAlive = 0.5f;
-
- @Expose
- @ConfigOption(name = "Line Width", desc = "Width of the line.")
- @ConfigEditorSlider(minStep = 1, minValue = 1, maxValue = 10)
- public int lineWidth = 4;
- }
- }
-
-
- @Expose
- @ConfigOption(name = "Glowing Dropped Items", desc = "")
- @Accordion
- public GlowingDroppedItems glowingDroppedItems = new GlowingDroppedItems();
-
- public static class GlowingDroppedItems {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Draws a glowing outline around all dropped items on the ground.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Highlight Showcase Items", desc = "Draws a glowing outline around showcase items.")
- @ConfigEditorBoolean
- public boolean highlightShowcase = false;
-
- @Expose
- @ConfigOption(name = "Highlight Fishing Bait", desc = "Draws a glowing outline around fishing bait.")
- @ConfigEditorBoolean
- public boolean highlightFishingBait = false;
-
- }
-
-
- @Expose
- @ConfigOption(name = "Highlight Party Members", desc = "")
- @Accordion
- public HighlightPartyMembers highlightPartyMembers = new HighlightPartyMembers();
-
- public static class HighlightPartyMembers {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Marking party members with a bright outline to better find them in the world.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(
- name = "Outline Color",
- desc = "The color to outline party members in."
- )
- @ConfigEditorColour
- public String outlineColor = "0:245:85:255:85";
-
- }
-
-
- @Expose
- @ConfigOption(name = "Compact Tab List", desc = "")
- @Accordion
- public CompactTabListConfig compactTabList = new CompactTabListConfig();
-
- public static class CompactTabListConfig {
- @Expose
- @ConfigOption(name = "Enabled", desc = "Compacts the tablist to make it look much nicer like SBA did. Also " +
- "doesn't break god-pot detection and shortens some other lines.")
- //made tablist one word here so both searches will pick it up
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Hide Hypixel Adverts", desc = "Hides text from advertising the Hypixel server or store in the tablist.")
- @ConfigEditorBoolean
- public boolean hideAdverts = false;
-
- @Expose
- @ConfigOption(name = "Advanced Player List", desc = "")
- @Accordion
- public AdvancedPlayerList advancedPlayerList = new AdvancedPlayerList();
-
- public static class AdvancedPlayerList {
-
- @Expose
- @ConfigOption(name = "Player Sort", desc = "Change the sort order of player names in the tab list.")
- @ConfigEditorDropdown(values = {"Rank (Default)", "SB Level", "Name (Abc)", "Ironman/Bingo", "Party/Friends/Guild", "Random"})
- public int playerSortOrder = 0;
-
- @Expose
- @ConfigOption(name = "Invert Sort", desc = "Flip the player list order on its head (also works with default rank).")
- @ConfigEditorBoolean
- public boolean reverseSort = false;
-
- @Expose
- @ConfigOption(name = "Hide Player Icons", desc = "Hide the icons/skins of player in the tab list.")
- @ConfigEditorBoolean
- public boolean hidePlayerIcons = false;
-
- @Expose
- @ConfigOption(name = "Hide Rank Color", desc = "Hide the player rank color.")
- @ConfigEditorBoolean
- public boolean hideRankColor = false;
-
- @Expose
- @ConfigOption(name = "Hide Emblems", desc = "Hide the emblems behind the player name.")
- @ConfigEditorBoolean
- public boolean hideEmblem = false;
-
- @Expose
- @ConfigOption(name = "Hide Level", desc = "Hide the SkyBlock level numbers.")
- @ConfigEditorBoolean
- public boolean hideLevel = false;
-
- @Expose
- @ConfigOption(name = "Hide Level Brackets", desc = "Hide the gray brackets in front of and behind the level numbers.")
- @ConfigEditorBoolean
- public boolean hideLevelBrackets = false;
-
- @Expose
- @ConfigOption(name = "Level Color As Name", desc = "Use the color of the SkyBlock level for the player color.")
- @ConfigEditorBoolean
- public boolean useLevelColorForName = false;
-
- @Expose
- @ConfigOption(name = "Bingo Rank Number", desc = "Show the number of the bingo rank next to the icon. Useful if you are not so familar with bingo.")
- @ConfigEditorBoolean
- public boolean showBingoRankNumber = false;
-
- @Expose
- @ConfigOption(name = "Hide Factions", desc = "Hide the icon of the Crimson Isle Faction in the tab list.")
- @ConfigEditorBoolean
- public boolean hideFactions = false;
-
- @Expose
- @ConfigOption(name = "Mark Special Persons", desc = "Show speical icons behind the name of guild members, party members, friends, and marked players.")
- @ConfigEditorBoolean
- public boolean markSpecialPersons = false;
-
- @Expose
- @ConfigOption(
- name = "Mark SkyHanni Devs",
- desc = "Adds a §c:O §7behind the tablist name of §cSkyHanni's contributors§7. " +
- "§eThose are the folks that coded the mod for you for free :)"
- )
- @ConfigEditorBoolean
- public boolean markSkyHanniContributors = false;
- }
- }
-
- @Expose
- @ConfigOption(name = "Kick Duration", desc = "")
- @Accordion
- public KickDurationConfig kickDuration = new KickDurationConfig();
-
- public static class KickDurationConfig {
-
- @Expose
- @ConfigOption(
- name = "Enabled",
- desc = "Show in the Hypixel lobby since when you were last kicked from SkyBlock (" +
- "useful if you get blocked because of '§cYou were kicked while joining that server!§7')."
- )
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Warn Time", desc = "Send warning and sound this seconds after a SkyBlock kick.")
- @ConfigEditorSlider(
- minValue = 5,
- maxValue = 300,
- minStep = 1
- )
- public Property<Integer> warnTime = Property.of(60);
-
- @Expose
- public Position position = new Position(400, 200, 1.3f);
- }
-
- @Expose
- @ConfigOption(name = "Exp Bottles", desc = "Hides all the experience orbs lying on the ground.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideExpBottles = false;
-
- @Expose
- public Position collectionCounterPos = new Position(10, 10, false, true);
-
- @Expose
- @ConfigOption(name = "Brewing Stand Overlay", desc = "Display the Item names directly inside the Brewing Stand.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean brewingStandOverlay = true;
-
- @Expose
- @ConfigOption(name = "Red Scoreboard Numbers", desc = "Hide the red scoreboard numbers on the right side of the screen.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideScoreboardNumbers = false;
-
- @Expose
- @ConfigOption(name = "Hide Piggy", desc = "Replacing 'Piggy' with 'Purse' in the Scoreboard.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hidePiggyScoreboard = true;
-
- @Expose
- @ConfigOption(name = "Explosions Hider", desc = "Hide explosions.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideExplosions = false;
-
- @Expose
- @ConfigOption(name = "CH Join", desc = "Helps buy a Pass for accessing the Crystal Hollows if needed.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean crystalHollowsJoin = true;
-
- @Expose
- @ConfigOption(name = "Fire Overlay Hider", desc = "Hide the fire overlay (Like in Skytils).")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideFireOverlay = false;
-
- @Expose
- @ConfigOption(name = "Paste Into Signs", desc = "Allows you to paste the clipboard into signs when you press Ctrl + V.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean pasteIntoSigns = true;
-
- @Expose
- @ConfigOption(name = "Movement Speed", desc = "Show the player movement speed in blocks per second.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean playerMovementSpeed = false;
-
- @Expose
- public Position playerMovementSpeedPos = new Position(394, 124, false, true);
-
- @Expose
- @ConfigOption(name = "Pet Candy Used", desc = "Show the number of Pet Candy used on a pet.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean petCandyUsed = true;
-
- @Expose
- @ConfigOption(name = "Server Restart Title", desc = "Show a title with seconds remaining until the server restarts after a Game Update or Scheduled Restart.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean serverRestartTitle = true;
-
- @Expose
- @ConfigOption(name = "Piece Of Wizard Portal", desc = "Restore the Earned By lore line on bought Piece Of Wizard Portal.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean restorePieceOfWizardPortalLore = true;
-
- @Expose
- @ConfigOption(name = "Patcher Coords Waypoint", desc = "Highlight the coordinates sent by Patcher.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean patcherSendCoordWaypoint = false;
-
-
- @Expose
- @ConfigOption(name = "Account Upgrade Reminder", desc = "Remind you to claim account upgrades when complete.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean accountUpgradeReminder = true;
-
- @Expose
- @ConfigOption(name = "Superpairs Clicks Alert", desc = "Display an alert when you reach the maximum clicks gained from Chronomatron or Ultrasequencer.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean superpairsClicksAlert = false;
-
- @Expose
- @ConfigOption(name = "NEU Heavy Pearls", desc = "Fixing NEU Heavy Pearl detection.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean fixNeuHeavyPearls = true;
-
- @Expose
- @ConfigOption(
- name = "Time In Limbo",
- desc = "Show the time since you entered the limbo.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean showTimeInLimbo = true;
-
- @Expose
- public Position showTimeInLimboPosition = new Position(400, 200, 1.3f);
-
- @Expose
- public Position inventoryLoadPos = new Position(394, 124, false, true);
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/OldHidden.java b/src/main/java/at/hannibal2/skyhanni/config/features/OldHidden.java
deleted file mode 100644
index a2694210f..000000000
--- a/src/main/java/at/hannibal2/skyhanni/config/features/OldHidden.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package at.hannibal2.skyhanni.config.features;
-
-import at.hannibal2.skyhanni.data.model.ComposterUpgrade;
-import at.hannibal2.skyhanni.features.garden.CropAccessory;
-import at.hannibal2.skyhanni.features.garden.CropType;
-import at.hannibal2.skyhanni.features.garden.farming.FarmingArmorDrops;
-import at.hannibal2.skyhanni.features.garden.visitor.VisitorReward;
-import com.google.gson.annotations.Expose;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class OldHidden {
-
- @Expose
- public String currentPet = "";
-
- @Expose
- public Map<String, Long> minionLastClick = new HashMap<>();
-
- @Expose
- public Map<String, String> minionName = new HashMap<>();
-
- @Expose
- public List<String> crimsonIsleQuests = new ArrayList<>();
-
- @Expose
- public List<String> crimsonIsleMiniBossesDoneToday = new ArrayList<>();
-
- @Expose
- public List<String> crimsonIsleKuudraTiersDone = new ArrayList<>();
-
- @Expose
- public Map<CropType, Long> gardenCropCounter = new HashMap<>();
-
- @Expose
- public Map<CropType, Integer> gardenCropUpgrades = new HashMap<>();
-
- @Expose
- public Map<CropType, Integer> gardenCropsPerSecond = new HashMap<>();
-
- @Expose
- public Map<CropType, Double> gardenLatestBlocksPerSecond = new HashMap<>();
-
- @Expose
- public Map<CropType, Double> gardenLatestTrueFarmingFortune = new HashMap<>();
-
- @Expose
- public int gardenExp = -1;
-
- @Expose
- public CropAccessory savedCropAccessory = null;
-
- @Expose
- public Map<String, Integer> gardenDicerRngDrops = new HashMap<>();
-
- @Expose
- public long informedAboutLowMatter = 0;
-
- @Expose
- public long informedAboutLowFuel = 0;
-
- @Expose
- public long visitorInterval = 15 * 60_000L;
-
- @Expose
- public long nextSixthVisitorArrival = 0;
-
- @Expose
- public Map<Long, List<CropType>> gardenJacobFarmingContestTimes = new HashMap<>();
-
- @Expose
- public Map<FarmingArmorDrops.ArmorDropType, Integer> gardenFarmingArmorDrops = new HashMap<>();
-
- @Expose
- public Map<ComposterUpgrade, Integer> gardenComposterUpgrades = new HashMap<>();
-
- @Expose
- public Map<CropType, Boolean> gardenToolHasBountiful = new HashMap<>();
-
- @Expose
- public String gardenComposterCurrentOrganicMatterItem = "";
-
- @Expose
- public String gardenComposterCurrentFuelItem = "";
-
-
- @Expose
- public VisitorDrops visitorDrops = new VisitorDrops();
-
- public static class VisitorDrops {
- @Expose
- public int acceptedVisitors = 0;
-
- @Expose
- public int deniedVisitors = 0;
-
- @Expose
- public List<Long> visitorRarities = new ArrayList<>();
-
- @Expose
- public int copper = 0;
-
- @Expose
- public long farmingExp = 0;
-
- @Expose
- public long coinsSpent = 0;
-
- @Expose
- public Map<VisitorReward, Integer> rewardsCount = new HashMap<>();
- }
-
- @Expose
- public boolean isMigrated = false;
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/RiftConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/RiftConfig.java
deleted file mode 100644
index 9021ec9be..000000000
--- a/src/main/java/at/hannibal2/skyhanni/config/features/RiftConfig.java
+++ /dev/null
@@ -1,720 +0,0 @@
-package at.hannibal2.skyhanni.config.features;
-
-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.Accordion;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorColour;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorText;
-import io.github.moulberry.moulconfig.annotations.ConfigOption;
-import io.github.moulberry.moulconfig.observer.Property;
-
-public class RiftConfig {
-
- @ConfigOption(name = "Rift Timer", desc = "")
- @Accordion
- @Expose
- public RiftTimerConfig timer = new RiftTimerConfig();
-
- public static class RiftTimerConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Show the remaining rift time, max time, percentage, and extra time changes.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Max Time", desc = "Show max time.")
- @ConfigEditorBoolean
- public boolean maxTime = true;
-
- @Expose
- @ConfigOption(name = "Percentage", desc = "Show percentage.")
- @ConfigEditorBoolean
- public boolean percentage = true;
-
- @Expose
- public Position timerPosition = new Position(10, 10, false, true);
-
- }
-
- @ConfigOption(name = "Crux Talisman Progress", desc = "")
- @Accordion
- @Expose
- public CruxTalismanDisplayConfig cruxTalisman = new CruxTalismanDisplayConfig();
-
- public static class CruxTalismanDisplayConfig {
- @Expose
- @ConfigOption(name = "Crux Talisman Display", desc = "Display progress of the Crux Talisman on screen.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Compact", desc = "Show a compacted version of the overlay when the talisman is maxed.")
- @ConfigEditorBoolean
- public boolean compactWhenMaxed = false;
-
- @Expose
- @ConfigOption(name = "Show Bonuses", desc = "Show bonuses you get from the talisman.")
- @ConfigEditorBoolean
- @FeatureToggle
- public Property<Boolean> showBonuses = Property.of(true);
-
- @Expose
- public Position position = new Position(144, 139, false, true);
- }
-
- @ConfigOption(name = "Enigma Soul Waypoints", desc = "")
- @Accordion
- @Expose
- public EnigmaSoulConfig enigmaSoulWaypoints = new EnigmaSoulConfig();
-
- public static class EnigmaSoulConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Click on Enigma Souls in Rift Guides to highlight their location.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Color", desc = "Color of the Enigma Souls.")
- @ConfigEditorColour
- public String color = "0:120:13:49:255";
-
- }
-
- @ConfigOption(name = "Rift Areas", desc = "")
- @Accordion
- @Expose
- public RiftAreasConfig area = new RiftAreasConfig();
-
- public static class RiftAreasConfig {
-
- @ConfigOption(name = "Wyld Woods", desc = "")
- @Accordion
- @Expose
- public WyldWoodsConfig wyldWoodsConfig = new WyldWoodsConfig();
-
- public static class WyldWoodsConfig {
-
- @Expose
- @ConfigOption(name = "Shy Crux Warning", desc = "Shows a warning when a Shy Crux is going to steal your time. " +
- "Useful if you play without volume.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean shyWarning = true;
-
- @ConfigOption(name = "Larvas", desc = "")
- @Accordion
- @Expose
- public LarvasConfig larvas = new LarvasConfig();
-
- public static class LarvasConfig {
-
- @Expose
- @ConfigOption(name = "Highlight", desc = "Highlight §cLarvas on trees §7while holding a §eLarva Hook §7in the hand.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlight = true;
-
- @Expose
- @ConfigOption(name = "Color", desc = "Color of the Larvas.")
- @ConfigEditorColour
- public String highlightColor = "0:120:13:49:255";
-
- }
-
- @ConfigOption(name = "Odonatas", desc = "")
- @Accordion
- @Expose
- public OdonataConfig odonata = new OdonataConfig();
-
- public static class OdonataConfig {
-
- @Expose
- @ConfigOption(name = "Highlight", desc = "Highlight the small §cOdonatas §7flying around the trees while holding an " +
- "§eEmpty Odonata Bottle §7in the hand.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlight = true;
-
- @Expose
- @ConfigOption(name = "Color", desc = "Color of the Odonatas.")
- @ConfigEditorColour
- public String highlightColor = "0:120:13:49:255";
-
- }
- }
-
- @ConfigOption(name = "West Village", desc = "")
- @Accordion
- @Expose
- public WestVillageConfig westVillageConfig = new WestVillageConfig();
-
- public static class WestVillageConfig {
-
- @ConfigOption(name = "Kloon Hacking", desc = "")
- @Accordion
- @Expose
- public KloonHackingConfig hacking = new KloonHackingConfig();
-
- public static class KloonHackingConfig {
-
- @Expose
- @ConfigOption(name = "Hacking Solver", desc = "Highlights the correct button to click in the hacking inventory.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean solver = true;
-
- @Expose
- @ConfigOption(name = "Color Guide", desc = "Tells you which color to pick.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean colour = true;
-
- @Expose
- @ConfigOption(name = "Terminal Waypoints", desc = "While wearing the helmet, waypoints will appear at each terminal location.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean waypoints = true;
- }
- }
-
- @Expose
- @ConfigOption(name = "Dreadfarm", desc = "")
- @Accordion
- public DreadfarmConfig dreadfarmConfig = new DreadfarmConfig();
-
- public static class DreadfarmConfig {
- @Expose
- @ConfigOption(name = "Agaricus Cap", desc = "Counts down the time until §eAgaricus Cap (Mushroom) " +
- "§7changes color from brown to red and is breakable.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean agaricusCap = true;
-
- @ConfigOption(name = "Volt Crux", desc = "")
- @Accordion
- @Expose
- public VoltCruxConfig voltCrux = new VoltCruxConfig();
-
- public static class VoltCruxConfig {
-
- @Expose
- @ConfigOption(name = "Volt Warning", desc = "Shows a warning while a Volt is discharging lightning.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean voltWarning = true;
-
- @Expose
- @ConfigOption(name = "Volt Range Highlighter", desc = "Shows the area in which a Volt might strike lightning.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean voltRange = true;
-
- @Expose
- @ConfigOption(name = "Volt Range Highlighter Color", desc = "In which color should the Volt range be highlighted?")
- @ConfigEditorColour
- public String voltColour = "0:60:0:0:255";
-
- @Expose
- @ConfigOption(name = "Volt Mood Color", desc = "Change the color of the Volt enemy depending on their mood.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean voltMoodMeter = false;
- }
-
- @ConfigOption(name = "Wilted Berberis", desc = "")
- @Accordion
- @Expose
- public WiltedBerberisConfig wiltedBerberis = new WiltedBerberisConfig();
-
- public static class WiltedBerberisConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Show Wilted Berberis helper.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Only on Farmland", desc = "Only show the helper while standing on Farmland blocks.")
- @ConfigEditorBoolean
- public boolean onlyOnFarmland = false;
-
- @Expose
- @ConfigOption(name = "Hide Particles", desc = "Hide the Wilted Berberis particles.")
- @ConfigEditorBoolean
- public boolean hideparticles = false;
-
- }
- }
-
- @ConfigOption(name = "Mirrorverse", desc = "")
- @Accordion
- @Expose
- public MirrorVerseConfig mirrorVerseConfig = new MirrorVerseConfig();
-
- public static class MirrorVerseConfig {
-
- @ConfigOption(name = "Lava Maze", desc = "")
- @Accordion
- @Expose
- public LavaMazeConfig lavaMazeConfig = new LavaMazeConfig();
-
- public static class LavaMazeConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Helps solving the lava maze in the Mirrorverse by showing the correct way.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Look Ahead", desc = "Change how many platforms should be shown in front of you.")
- @ConfigEditorSlider(minStep = 1, maxValue = 30, minValue = 1)
- public Property<Integer> lookAhead = Property.of(3);
-
- @Expose
- @ConfigOption(name = "Rainbow Color", desc = "Show the rainbow color effect instead of a boring monochrome.")
- @ConfigEditorBoolean
- public Property<Boolean> rainbowColor = Property.of(true);
-
- @Expose
- @ConfigOption(name = "Monochrome Color", desc = "Set a boring monochrome color for the parkour platforms.")
- @ConfigEditorColour
- public Property<String> monochromeColor = Property.of("0:60:0:0:255");
-
- @Expose
- @ConfigOption(name = "Hide Others Players", desc = "Hide other players while doing the lava maze.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hidePlayers = false;
- }
-
-
- @ConfigOption(name = "Upside Down Parkour", desc = "")
- @Accordion
- @Expose
- public UpsideDownParkourConfig upsideDownParkour = new UpsideDownParkourConfig();
-
- public static class UpsideDownParkourConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Helps solving the upside down parkour in the Mirrorverse by showing the correct way.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Look Ahead", desc = "Change how many platforms should be shown in front of you.")
- @ConfigEditorSlider(minStep = 1, maxValue = 9, minValue = 1)
- public Property<Integer> lookAhead = Property.of(3);
-
- @Expose
- @ConfigOption(name = "Outline", desc = "Outlines the top edge of the platforms.")
- @ConfigEditorBoolean
- public boolean outline = true;
-
- @Expose
- @ConfigOption(name = "Rainbow Color", desc = "Show the rainbow color effect instead of a boring monochrome.")
- @ConfigEditorBoolean
- public Property<Boolean> rainbowColor = Property.of(true);
-
- @Expose
- @ConfigOption(name = "Monochrome Color", desc = "Set a boring monochrome color for the parkour platforms.")
- @ConfigEditorColour
- public Property<String> monochromeColor = Property.of("0:60:0:0:255");
-
- @Expose
- @ConfigOption(name = "Hide Others Players", desc = "Hide other players while doing the upside down parkour.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hidePlayers = false;
- }
-
-
- @ConfigOption(name = "Dance Room Helper", desc = "")
- @Accordion
- @Expose
- public DanceRoomHelperConfig danceRoomHelper = new DanceRoomHelperConfig();
-
- public static class DanceRoomHelperConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Helps to solve the dance room in the Mirrorverse by showing multiple tasks at once.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Lines to Show", desc = "How many tasks you should see.")
- @ConfigEditorSlider(minStep = 1, maxValue = 49, minValue = 1)
- public int lineToShow = 3;
-
- @Expose
- @ConfigOption(name = "Space", desc = "Change the space between each line.")
- @ConfigEditorSlider(minStep = 1, maxValue = 10, minValue = -5)
- public int extraSpace = 0;
-
- @Expose
- @ConfigOption(name = "Hide Other Players", desc = "Hide other players inside the dance room.")
- @ConfigEditorBoolean
- public boolean hidePlayers = false;
-
- @Expose
- @ConfigOption(name = "Hide Title", desc = "Hide Instructions, \"§aIt's happening!\" §7and \"§aKeep it up!\" §7titles.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideOriginalTitle = false;
-
- @Expose
- @ConfigOption(name = "Formatting", desc = "")
- @Accordion
- public DanceRoomFormattingConfig danceRoomFormatting = new DanceRoomFormattingConfig();
-
- public static class DanceRoomFormattingConfig {
-
- @Expose
- @ConfigOption(name = "Now", desc = "Formatting for \"Now:\"")
- @ConfigEditorText
- public String now = "&7Now:";
-
- @Expose
- @ConfigOption(name = "Next", desc = "Formatting for \"Next:\"")
- @ConfigEditorText
- public String next = "&7Next:";
-
- @Expose
- @ConfigOption(name = "Later", desc = "Formatting for \"Later:\"")
- @ConfigEditorText
- public String later = "&7Later:";
-
- @Expose
- @ConfigOption(name = "Color Option", desc = "")
- @Accordion
- public ColorConfig color = new ColorConfig();
-
- public static class ColorConfig {
- @Expose
- @ConfigOption(name = "Move", desc = "Color for the Move instruction")
- @ConfigEditorText
- public String move = "&e";
-
- @Expose
- @ConfigOption(name = "Stand", desc = "Color for the Stand instruction")
- @ConfigEditorText
- public String stand = "&e";
-
- @Expose
- @ConfigOption(name = "Sneak", desc = "Color for the Sneak instruction")
- @ConfigEditorText
- public String sneak = "&5";
-
- @Expose
- @ConfigOption(name = "Jump", desc = "Color for the Jump instruction")
- @ConfigEditorText
- public String jump = "&b";
-
- @Expose
- @ConfigOption(name = "Punch", desc = "Color for the Punch instruction")
- @ConfigEditorText
- public String punch = "&d";
-
- @Expose
- @ConfigOption(name = "Countdown", desc = "Color for the Countdown")
- @ConfigEditorText
- public String countdown = "&f";
-
- @Expose
- @ConfigOption(name = "Default", desc = "Fallback color")
- @ConfigEditorText
- public String fallback = "&f";
- }
- }
-
- @Expose
- public Position position = new Position(442, 239, false, true);
- }
-
-
- @ConfigOption(name = "Tubulator", desc = "")
- @Accordion
- @Expose
- public TubulatorConfig tubulatorConfig = new TubulatorConfig();
-
- public static class TubulatorConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Highlights the location of the invisible Tubulator blocks (Laser Parkour).")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Look Ahead", desc = "Change how many platforms should be shown in front of you.")
- @ConfigEditorSlider(minStep = 1, maxValue = 30, minValue = 1)
- public Property<Integer> lookAhead = Property.of(2);
-
- @Expose
- @ConfigOption(name = "Outline", desc = "Outlines the top edge of the platforms.")
- @ConfigEditorBoolean
- public boolean outline = true;
-
- @Expose
- @ConfigOption(name = "Rainbow Color", desc = "Show the rainbow color effect instead of a boring monochrome.")
- @ConfigEditorBoolean
- public Property<Boolean> rainbowColor = Property.of(true);
-
- @Expose
- @ConfigOption(name = "Monochrome Color", desc = "Set a boring monochrome color for the parkour platforms.")
- @ConfigEditorColour
- public Property<String> monochromeColor = Property.of("0:60:0:0:255");
-
- @Expose
- @ConfigOption(name = "Hide Other Players", desc = "Hide other players while doing the lava maze.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hidePlayers = false;
- }
- }
-
-// @Expose
-// @ConfigOption(name = "Village Plaza", desc = "")
-// @Accordion
-// public VillagePlazaConfig villagePlazaConfig = new VillagePlazaConfig();
-//
-// public static class VillagePlazaConfig {
-//
-// }
-
- @Expose
- @ConfigOption(name = "Living Cave", desc = "")
- @Accordion
- public LivingCaveConfig livingCaveConfig = new LivingCaveConfig();
-
- public static class LivingCaveConfig {
-
- @Expose
- @ConfigOption(name = "Living Metal Suit Progress", desc = "")
- @Accordion
- public LivingMetalSuitProgressConfig livingMetalSuitProgress = new LivingMetalSuitProgressConfig();
-
- public static class LivingMetalSuitProgressConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Display Living Metal Suit progress.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Compact", desc = "Show a compacted version of the overlay when the set is maxed.")
- @ConfigEditorBoolean
- public boolean compactWhenMaxed = false;
-
- @Expose
- public Position position = new Position(100, 100);
- }
-
- @Expose
- @ConfigOption(name = "Defense Blocks", desc = "")
- @Accordion
- public DefenseBlockConfig defenseBlockConfig = new DefenseBlockConfig();
-
- public static class DefenseBlockConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Show a line between Defense blocks and the mob and highlight the blocks.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Hide Particles", desc = "Hide particles around Defense Blocks.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideParticles = false;
-
- @Expose
- @ConfigOption(name = "Color", desc = "Set the color of the lines, blocks and the entity.")
- @ConfigEditorColour
- public Property<String> color = Property.of("0:255:77:104:255");
-
- }
-
- @Expose
- @ConfigOption(name = "Living Metal Helper", desc = "")
- @Accordion
- public LivingCaveLivingMetalConfig livingCaveLivingMetalConfig = new LivingCaveLivingMetalConfig();
-
- public static class LivingCaveLivingMetalConfig {
-
- @Expose
- @ConfigOption(name = "Living Metal", desc = "Show a moving animation between Living Metal and the next block.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Hide Particles", desc = "Hide Living Metal particles.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideParticles = false;
-
- }
- }
-
- @Expose
- @ConfigOption(name = "Colosseum", desc = "")
- @Accordion
- public ColosseumConfig colosseumConfig = new ColosseumConfig();
-
- public static class ColosseumConfig {
-
- @Expose
- @ConfigOption(name = "Highlight Blobbercysts", desc = "Highlight Blobbercysts in Bacte fight.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlightBlobbercysts = true;
- }
-
- @Expose
- @ConfigOption(name = "Stillgore Chateau", desc = "")
- @Accordion
- public StillgoreChateauConfig stillgoreChateauConfig = new StillgoreChateauConfig();
-
- public static class StillgoreChateauConfig {
-
- @Expose
- @ConfigOption(name = "Blood Effigies", desc = "")
- @Accordion
- public EffigiesConfig bloodEffigies = new EffigiesConfig();
-
- public static class EffigiesConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Show locations of inactive Blood Effigies.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Respawning Soon", desc = "Show effigies that are about to respawn.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean respawningSoon = false;
-
- @Expose
- @ConfigOption(name = "Respawning Time", desc = "Time before effigies respawn to show.")
- @ConfigEditorSlider(
- minValue = 1,
- maxValue = 15,
- minStep = 1
- )
- public int respwningSoonTime = 3;
-
- @Expose
- @ConfigOption(name = "Unknown Times", desc = "Show effigies without known time.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean unknownTime = false;
- }
- }
-
-// @Expose
-// @ConfigOption(name = "Mountaintop", desc = "")
-// @Accordion
-// public MountaintopConfig mountaintopConfig = new MountaintopConfig();
-//
-// public static class MountaintopConfig {
-//
-// }
-
- }
-
- @Expose
- @ConfigOption(name = "Motes Sell Price", desc = "")
- @Accordion
- public MotesConfig motes = new MotesConfig();
-
- public static class MotesConfig {
-
- @Expose
- @ConfigOption(name = "Show Motes Price", desc = "Show the Motes NPC price in the item lore.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean showPrice = true;
-
- @Expose
- @ConfigOption(name = "Burger Stacks", desc = "Set your McGrubber's burger stacks.")
- @ConfigEditorSlider(minStep = 1, minValue = 0, maxValue = 5)
- public int burgerStacks = 0;
-
- @Expose
- @ConfigOption(name = "Inventory Value", desc = "")
- @Accordion
- public InventoryValueConfig inventoryValue = new InventoryValueConfig();
-
- public static class InventoryValueConfig {
- @Expose
- @ConfigOption(name = "Inventory Value", desc = "Show total Motes NPC price for the current opened inventory.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Number Format Type", desc = "Short: 1.2M\n" +
- "Long: 1,200,000")
- @ConfigEditorDropdown(values = {"Short", "Long"})
- public int formatType = 0;
-
- @Expose
- public Position position = new Position(126, 156, false, true);
- }
- }
-
- @Expose
- @ConfigOption(name = "Motes Orbs", desc = "")
- @Accordion
- public MotesOrbsConfig motesOrbsConfig = new MotesOrbsConfig();
-
- public static class MotesOrbsConfig {
-
- @Expose
- @ConfigOption(name = "Highlight Motes Orbs", desc = "Highlight flying Motes Orbs.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Highlight Size", desc = "Set render size for highlighted Motes Orbs.")
- @ConfigEditorSlider(minStep = 1, minValue = 1, maxValue = 5)
- public int size = 3;
-
- @Expose
- @ConfigOption(name = "Hide Particles", desc = "Hide normal Motes Orbs particles.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideParticles = false;
-
- }
-
- @Expose
- @ConfigOption(name = "Highlight Guide", desc = "Highlight things to do in the Rift Guide.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlightGuide = true;
-
- @Expose
- @ConfigOption(name = "Horsezooka Hider", desc = "Hide horses while holding the Horsezooka in the hand.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean horsezookaHider = false;
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/SlayerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/SlayerConfig.java
deleted file mode 100644
index 6ca5ec984..000000000
--- a/src/main/java/at/hannibal2/skyhanni/config/features/SlayerConfig.java
+++ /dev/null
@@ -1,523 +0,0 @@
-package at.hannibal2.skyhanni.config.features;
-
-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.Accordion;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorColour;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorText;
-import io.github.moulberry.moulconfig.annotations.ConfigOption;
-
-public class SlayerConfig {
-
- @Expose
- @ConfigOption(name = "Enderman Slayer Features", desc = "")
- @Accordion
- public EndermanConfig endermen = new EndermanConfig();
-
- public static class EndermanConfig {
- @Expose
- @ConfigOption(name = "Yang Glyph (beacon)", desc = "")
- @Accordion
- public EndermanBeaconConfig endermanBeaconConfig = new EndermanBeaconConfig();
-
- public static class EndermanBeaconConfig {
-
- @Expose
- @ConfigOption(name = "Highlight Beacon",
- desc = "Highlight the Enderman Slayer Yang Glyph (beacon) in red color and added a timer for when he explodes. " +
- "Supports beacon in hand and beacon flying.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlightBeacon = true;
-
- @Expose
- @ConfigOption(name = "Beacon Color", desc = "Color of the beacon.")
- @ConfigEditorColour
- public String beaconColor = "0:255:255:0:88";
-
- @Expose
- @ConfigOption(name = "Show Warning", desc = "Displays a warning mid-screen when the Enderman Slayer throws a Yang Glyph (beacon).")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean showWarning = false;
-
- @Expose
- @ConfigOption(name = "Show Line", desc = "Draw a line starting at your crosshair to the beacon.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean showLine = false;
-
- @Expose
- @ConfigOption(name = "Line Color", desc = "Color of the line.")
- @ConfigEditorColour
- public String lineColor = "0:255:255:0:88";
-
- @Expose
- @ConfigOption(name = "Line Width", desc = "Width of the line.")
- @ConfigEditorSlider(minStep = 1, minValue = 1, maxValue = 10)
- public int lineWidth = 3;
- }
-
- @Expose
- @ConfigOption(name = "Highlight Nukekubi Skulls", desc = "Highlights the Enderman Slayer Nukekubi Skulls (Eyes).")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlightNukekebi = false;
-
- @Expose
- @ConfigOption(name = "Phase Display", desc = "Show the current phase of the Enderman Slayer in damage indcator.")
- @ConfigEditorBoolean
- public boolean phaseDisplay = false;
-
- @Expose
- @ConfigOption(name = "Hide Particles", desc = "Hide particles around Enderman Slayer bosses and Mini-Bosses.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideParticles = false;
- }
-
-
- @Expose
- @ConfigOption(name = "Blaze", desc = "")
- @Accordion
- public BlazeConfig blazes = new BlazeConfig();
-
- public static class BlazeConfig {
- @Expose
- @ConfigOption(name = "Hellion Shields", desc = "")
- @Accordion
- public BlazeHellionConfig hellion = new BlazeHellionConfig();
-
- public static class BlazeHellionConfig {
- @Expose
- @ConfigOption(name = "Colored Mobs", desc = "Color the Blaze Slayer boss and the demons in the right hellion shield color.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean coloredMobs = false;
-
- @Expose
- @ConfigOption(name = "Blaze Daggers", desc = "Faster and permanent display for the Blaze Slayer daggers.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean daggers = false;
-
- @Expose
- @ConfigOption(name = "Right Dagger", desc = "Mark the right dagger to use for Blaze Slayer in the dagger overlay.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean markRightHellionShield = false;
-
- @Expose
- @ConfigOption(name = "First Dagger", desc = "Select the first, left sided dagger for the display.")
- @ConfigEditorDropdown(values = {"Spirit/Crystal", "Ashen/Auric"})
- public int firstDagger = 0;
-
- @Expose
- @ConfigOption(name = "Hide Chat", desc = "Remove the wrong Blaze Slayer dagger messages from chat.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideDaggerWarning = false;
- }
-
-
- @Expose
- @ConfigOption(name = "Fire Pits", desc = "Warning when the fire pit phase starts for the Blaze Slayer tier 3 and 4.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean firePitsWarning = false;
-
- @Expose
- @ConfigOption(name = "Phase Display", desc = "Show the current phase of the Blaze Slayer boss.")
- @ConfigEditorBoolean
- public boolean phaseDisplay = false;
-
- @Expose
- @ConfigOption(name = "Clear View", desc = "Hide particles and fireballs near Blaze Slayer bosses and demons.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean clearView = false;
- }
-
-
- @Expose
- @ConfigOption(name = "Vampire Slayer Features", desc = "")
- @Accordion
- public VampireSlayerConfig vampireSlayerConfig = new VampireSlayerConfig();
-
- public static class VampireSlayerConfig {
-
- @Expose
- @ConfigOption(name = "Your Boss", desc = "")
- @Accordion
- public OwnBossConfig ownBoss = new OwnBossConfig();
-
- public static class OwnBossConfig {
-
- @Expose
- @ConfigOption(name = "Highlight Your Boss", desc = "Highlight your own Vampire Slayer boss.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlight = true;
-
- @Expose
- @ConfigOption(name = "Highlight Color", desc = "What color to highlight the boss in.")
- @ConfigEditorColour
- public String highlightColor = "0:249:0:255:88";
-
- @Expose
- @ConfigOption(name = "Steak Alert", desc = "Show a title when you can steak your boss.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean steakAlert = true;
-
- @Expose
- @ConfigOption(name = "Twinclaws Title", desc = "Send a title when Twinclaws is about to happen.\nWork on others highlighted people boss.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean twinClawsTitle = true;
-
- @Expose
- @ConfigOption(name = "Twinclaws Sound", desc = "Play a sound when Twinclaws is about to happen.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean twinClawsSound = true;
- }
-
- @Expose
- @ConfigOption(name = "Others Boss", desc = "")
- @Accordion
- public OthersBossConfig othersBoss = new OthersBossConfig();
-
- public static class OthersBossConfig {
-
- @Expose
- @ConfigOption(name = "Highlight Others Boss", desc = "Highlight others players boss.\nYou need to hit them first.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlight = true;
-
- @Expose
- @ConfigOption(name = "Highlight Color", desc = "What color to highlight the boss in.")
- @ConfigEditorColour
- public String highlightColor = "0:249:0:255:88";
-
- @Expose
- @ConfigOption(name = "Steak Alert", desc = "Show a title when you can steak the boss.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean steakAlert = true;
-
- @Expose
- @ConfigOption(name = "Twinclaws Title", desc = "Send a title when Twinclaws is about to happen.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean twinClawsTitle = true;
-
- @Expose
- @ConfigOption(name = "Twinclaws Sound", desc = "Play a sound when Twinclaws is about to happen.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean twinClawsSound = true;
- }
-
- @Expose
- @ConfigOption(name = "Co-op Boss", desc = "")
- @Accordion
- public CoopBossHighlightConfig coopBoss = new CoopBossHighlightConfig();
-
- public static class CoopBossHighlightConfig {
- @Expose
- @ConfigOption(name = "Highlight Co-op Boss", desc = "Highlight boss of your co-op member.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlight = true;
-
- @Expose
- @ConfigOption(name = "Highlight Color", desc = "What color to highlight the boss in.")
- @ConfigEditorColour
- public String highlightColor = "0:249:0:255:88";
-
- @Expose
- @ConfigOption(name = "Co-op Members", desc = "Add your co-op member here.\n§eFormat: §7Name1,Name2,Name3")
- @ConfigEditorText
- public String coopMembers = "";
-
- @Expose
- @ConfigOption(name = "Steak Alert", desc = "Show a title when you can steak the boss.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean steakAlert = true;
-
- @Expose
- @ConfigOption(name = "Twinclaws Title", desc = "Send a title when Twinclaws is about to happen.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean twinClawsTitle = true;
-
- @Expose
- @ConfigOption(name = "Twinclaws Sound", desc = "Play a sound when Twinclaws is about to happen.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean twinClawsSound = true;
- }
-
- @Expose
- @ConfigOption(name = "Transparency", desc = "Choose the transparency of the color.")
- @ConfigEditorSlider(minStep = 1, minValue = 1, maxValue = 250)
- public int withAlpha = 80;
-
- @Expose
- @ConfigOption(name = "See Through Blocks", desc = "Highlight even when behind others mobs/players.")
- @ConfigEditorBoolean
- public boolean seeThrough = false;
-
- @Expose
- @ConfigOption(name = "Low Health", desc = "Change color when the boss is below 20% health.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean changeColorWhenCanSteak = true;
-
- @Expose
- @ConfigOption(name = "Can use Steak Color", desc = "Color when the boss is below 20% health.")
- @ConfigEditorColour
- public String steakColor = "0:255:255:0:88";
-
- @Expose
- @ConfigOption(name = "Twinclaws", desc = "Delay the sound and title of Twinclaws alert for a given amount in milliseconds.")
- @ConfigEditorSlider(minStep = 1, minValue = 0, maxValue = 1000)
- public int twinclawsDelay = 0;
-
- @Expose
- @ConfigOption(name = "Draw Line", desc = "Draw a line starting at your crosshair to the boss head.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean drawLine = false;
-
- @Expose
- @ConfigOption(name = "Line Color", desc = "Color of the line.")
- @ConfigEditorColour
- public String lineColor = "0:255:255:0:88";
-
- @Expose
- @ConfigOption(name = "Line Width", desc = "Width of the line.")
- @ConfigEditorSlider(minStep = 1, minValue = 1, maxValue = 10)
- public int lineWidth = 1;
-
-
- @Expose
- @ConfigOption(name = "Blood Ichor", desc = "")
- @Accordion
- public BloodIchorConfig bloodIchor = new BloodIchorConfig();
-
- public static class BloodIchorConfig {
- @Expose
- @ConfigOption(name = "Highlight Blood Ichor", desc = "Highlight the Blood Ichor.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlight = false;
-
- @Expose
- @ConfigOption(name = "Beacon Beam", desc = "Render a beacon beam where the Blood Ichor is.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean renderBeam = true;
-
- @Expose
- @ConfigOption(name = "Color", desc = "Highlight color.")
- @ConfigEditorColour
- public String color = "0:199:100:0:88";
-
- @Expose
- @ConfigOption(name = "Show Lines", desc = "Draw lines that start from the head of the boss and end on the Blood Ichor.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean showLines = false;
-
- @Expose
- @ConfigOption(name = "Lines Start Color", desc = "Starting color of the lines.")
- @ConfigEditorColour
- public String linesColor = "0:255:255:13:0";
-
- }
-
- @Expose
- @ConfigOption(name = "Killer Spring", desc = "")
- @Accordion
- public KillerSpringConfig killerSpring = new KillerSpringConfig();
-
- public static class KillerSpringConfig {
- @Expose
- @ConfigOption(name = "Highlight Killer Spring", desc = "Highlight the Killer Spring tower.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean highlight = false;
-
- @Expose
- @ConfigOption(name = "Color", desc = "Highlight color.")
- @ConfigEditorColour
- public String color = "0:199:100:0:88";
-
- @Expose
- @ConfigOption(name = "Show Lines", desc = "Draw lines that start from the head of the boss and end on the Killer Spring tower.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean showLines = false;
-
- @Expose
- @ConfigOption(name = "Lines Start Color", desc = "Starting color of the lines.")
- @ConfigEditorColour
- public String linesColor = "0:255:255:13:0";
- }
- }
-
- @Expose
- @ConfigOption(name = "Item Profit Tracker", desc = "")
- @Accordion
- public ItemProfitTrackerConfig itemProfitTracker = new ItemProfitTrackerConfig();
-
- public static class ItemProfitTrackerConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Count all items you pick up while doing slayer, " +
- "keep track of how much you pay for starting slayers and calculating the overall profit.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- public Position pos = new Position(20, 20, false, true);
-
- @Expose
- @ConfigOption(name = "Price in Chat", desc = "Show an extra chat message when you pick up an item. " +
- "(This contains name, amount and price)")
- @ConfigEditorBoolean
- @FeatureToggle
- 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;
-
- @Expose
- @ConfigOption(name = "Title Warning", desc = "Show a title for expensive item pickups.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean titleWarning = false;
-
- @Expose
- @ConfigOption(name = "Title Price", desc = "Items above this price will show up as a title.")
- @ConfigEditorSlider(minValue = 1, maxValue = 20_000_000, minStep = 1)
- public int minimumPriceWarning = 500_000;
- }
-
- @Expose
- @ConfigOption(name = "Items on Ground", desc = "")
- @Accordion
- public ItemsOnGroundConfig itemsOnGround = new ItemsOnGroundConfig();
-
- public static class ItemsOnGroundConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Show the name and price of items laying on the ground. §cOnly in slayer areas!")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Minimum Price", desc = "Items below this price will be ignored.")
- @ConfigEditorSlider(minValue = 1, maxValue = 1_000_000, minStep = 1)
- public int minimumPrice = 50_000;
- }
-
- @Expose
- @ConfigOption(name = "RNG Meter Display", desc = "")
- @Accordion
- public RngMeterDisplayConfig rngMeterDisplay = new RngMeterDisplayConfig();
-
- public static class RngMeterDisplayConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Display amount of bosses needed until next RNG meter drop.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = true;
-
- @Expose
- @ConfigOption(name = "Warn Empty", desc = "Warn when no item is set in the RNG Meter.")
- @ConfigEditorBoolean
- public boolean warnEmpty = false;
-
- @Expose
- @ConfigOption(name = "Hide Chat", desc = "Hide the RNG meter message from chat if current item is selected.")
- @ConfigEditorBoolean
- public boolean hideChat = true;
-
- @Expose
- public Position pos = new Position(410, 110, false, true);
-
- }
-
- @Expose
- @ConfigOption(name = "Boss Spawn Warning", desc = "")
- @Accordion
- public SlayerBossWarningConfig slayerBossWarning = new SlayerBossWarningConfig();
-
- public static class SlayerBossWarningConfig {
-
- @Expose
- @ConfigOption(name = "Enabled", desc = "Send a title when your boss is about to spawn.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean enabled = false;
-
- @Expose
- @ConfigOption(name = "Percent", desc = "The percentage at which the title and sound should be sent.")
- @ConfigEditorSlider(minStep = 1, minValue = 50, maxValue = 90)
- public int percent = 80;
-
- @Expose
- @ConfigOption(name = "Repeat", desc = "Resend the title and sound on every kill after reaching the configured percent value.")
- @ConfigEditorBoolean
- public boolean repeat = false;
- }
-
- @Expose
- @ConfigOption(name = "Miniboss Highlight", desc = "Highlight Slayer Mini-Boss in blue color.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean slayerMinibossHighlight = false;
-
- @Expose
- @ConfigOption(name = "Line to Miniboss", desc = "Adds a line to every Slayer Mini-Boss around you.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean slayerMinibossLine = false;
-
- @Expose
- @ConfigOption(name = "Hide Mob Names", desc = "Hide the name of the mobs you need to kill in order for the Slayer boss to spawn. Exclude mobs that are damaged, corrupted, runic or semi rare.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean hideMobNames = false;
-
- @Expose
- @ConfigOption(name = "Quest Warning", desc = "Warning when wrong Slayer quest is selected, or killing mobs for the wrong Slayer.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean questWarning = true;
-
- @Expose
- @ConfigOption(name = "Quest Warning Title", desc = "Sends a title when warning.")
- @ConfigEditorBoolean
- @FeatureToggle
- public boolean questWarningTitle = true;
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/BazaarConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/bazaar/BazaarConfig.java
index b02c0ef40..515255e4b 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/BazaarConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/bazaar/BazaarConfig.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.config.features;
+package at.hannibal2.skyhanni.config.features.bazaar;
import at.hannibal2.skyhanni.config.FeatureToggle;
import at.hannibal2.skyhanni.config.core.config.Position;
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/chat/ChatConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/chat/ChatConfig.java
new file mode 100644
index 000000000..09df4f5e7
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/chat/ChatConfig.java
@@ -0,0 +1,91 @@
+package at.hannibal2.skyhanni.config.features.chat;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import org.lwjgl.input.Keyboard;
+
+public class ChatConfig {
+
+ @Expose
+ @ConfigOption(name = "Peek Chat", desc = "Hold this key to keep the chat open.")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_Z)
+ public int peekChat = Keyboard.KEY_Z;
+
+ @Expose
+ @ConfigOption(name = "Chat Filter Types", desc = "")
+ @Accordion
+ public FilterTypesConfig filterType = new FilterTypesConfig();
+
+
+ @Expose
+ @ConfigOption(name = "Player Messages", desc = "")
+ @Accordion
+ public PlayerMessagesConfig playerMessage = new PlayerMessagesConfig();
+
+ @Expose
+ @ConfigOption(name = "Player Chat Symbols", desc = "")
+ @Accordion
+ public ChatSymbols chatSymbols = new ChatSymbols();
+
+ @Expose
+ @ConfigOption(name = "Dungeon Filter", desc = "Hide annoying messages in Dungeons.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean dungeonMessages = true;
+
+ @Expose
+ @ConfigOption(name = "Dungeon Boss Messages", desc = "Hide messages from the Watcher and bosses in the Dungeon.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean dungeonBossMessages = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Far Deaths", desc = "Hide other players' death messages, " +
+ "except for players who are nearby or during Dungeons/a Kuudra fight.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideFarDeathMessages = false;
+ //TODO jawbus + thunder
+
+ @Expose
+ @ConfigOption(name = "Compact Potion Messages", desc = "")
+ @Accordion
+ public CompactPotionConfig compactPotionMessages = new CompactPotionConfig();
+
+ @Expose
+ @ConfigOption(name = "Compact Bestiary Message", desc = "Shorten the Bestiary level up message, showing additional information when hovering.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean compactBestiaryMessage = true;
+
+ @Expose
+ @ConfigOption(name = "Arachne Hider", desc = "Hide chat messages about the Arachne Fight while outside of §eArachne's Sanctuary§7.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideArachneMessages = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Sacks Hider",
+ desc = "Hide the chat's sack change message with this, " +
+ "not in Hypixel settings, for mods to access sack data in new features."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideSacksChange = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Translator",
+ desc = "Click on a message to translate it into English. " +
+ "Use §e/shcopytranslation§7 to get the translation from English. " +
+ "§cTranslation is not guaranteed to be 100% accurate."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean translator = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/chat/ChatSymbols.java b/src/main/java/at/hannibal2/skyhanni/config/features/chat/ChatSymbols.java
new file mode 100644
index 000000000..c8ea29aee
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/chat/ChatSymbols.java
@@ -0,0 +1,24 @@
+package at.hannibal2.skyhanni.config.features.chat;
+
+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 ChatSymbols {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Adds extra symbols to the chat such as those from ironman, " +
+ "stranded, bingo or nether factions and places them next to your regular player emblems. " +
+ "§cDoes not work with hide rank hider!")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Chat Symbol Location", desc = "Determines where the symbols should go in chat in relation to the " +
+ "player's name. Hidden will hide all emblems from the chat. §eRequires above setting to be on to hide the symbols.")
+ @ConfigEditorDropdown(values = {"Left", "Right", "Hidden"})
+ public int symbolLocation = 0;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/chat/CompactPotionConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/chat/CompactPotionConfig.java
new file mode 100644
index 000000000..c06244b90
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/chat/CompactPotionConfig.java
@@ -0,0 +1,20 @@
+package at.hannibal2.skyhanni.config.features.chat;
+
+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 CompactPotionConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Shorten chat messages about player potion effects.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Clickable Chat Message", desc = "Makes the Compact Potion message open the Potion effects menu on click.")
+ @ConfigEditorBoolean
+ public boolean clickableChatMessage = true;
+}
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
new file mode 100644
index 000000000..42cca5b59
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/chat/FilterTypesConfig.java
@@ -0,0 +1,83 @@
+package at.hannibal2.skyhanni.config.features.chat;
+
+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 FilterTypesConfig {
+
+ @Expose
+ @ConfigOption(name = "Hypixel Hub", desc = "Block messages outside SkyBlock in the Hypixel lobby: player joins, loot boxes, prototype lobby messages, radiating generosity and Hypixel tournaments.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hypixelHub = true;
+
+ @Expose
+ @ConfigOption(name = "Empty", desc = "Hide all the empty messages from the chat.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean empty = true;
+
+ @Expose
+ @ConfigOption(name = "Warping", desc = "Block 'Sending request to join...' and 'Warping...' messages.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean warping = true;
+
+ @Expose
+ @ConfigOption(name = "Welcome", desc = "Hide the 'Welcome to SkyBlock' message.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean welcome = true;
+
+ @Expose
+ @ConfigOption(name = "Guild Exp", desc = "Hide Guild EXP messages.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean guildExp = true;
+
+ @Expose
+ @ConfigOption(name = "Friend Join Left", desc = "Hide friend join/left messages.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean friendJoinLeft = false;
+
+ @Expose
+ @ConfigOption(name = "Winter Gifts", desc = "Hide useless Winter Gift messages.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean winterGift = false;
+
+ @Expose
+ @ConfigOption(name = "Powder Mining", desc = "Hide messages while opening chests in the Crystal Hollows. " +
+ "(Except powder numbers over 1k, essence numbers over 2, Prehistoric Eggs, and Automaton Parts)")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean powderMining = true;
+
+ @Expose
+ @ConfigOption(name = "Kill Combo", desc = "Hide messages about the current Kill Combo from the Grandma Wolf Pet.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean killCombo = false;
+
+ @Expose
+ @ConfigOption(name = "Watchdog", desc = "Hide the message where Hypixel is flexing how many players they have banned over the last week.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean watchDog = true;
+
+ @Expose
+ @ConfigOption(name = "Profile Join", desc = "Hide 'You are playing on profile' and 'Profile ID' chat messages.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean profileJoin = true;
+
+ //TODO remove
+ @Expose
+ @ConfigOption(name = "Others", desc = "Hide other annoying messages.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean others = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/chat/PlayerMessagesConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/chat/PlayerMessagesConfig.java
new file mode 100644
index 000000000..93c22adab
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/chat/PlayerMessagesConfig.java
@@ -0,0 +1,21 @@
+package at.hannibal2.skyhanni.config.features.chat;
+
+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 PlayerMessagesConfig {
+
+ @Expose
+ @ConfigOption(name = "Player Rank Hider", desc = "Hide player ranks in all chat messages.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean playerRankHider = false;
+
+ @Expose
+ @ConfigOption(name = "Chat Filter", desc = "Scan messages sent by players for blacklisted words and gray out the message if any are found.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean chatFilter = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/ChromaConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/chroma/ChromaConfig.java
index 80c40cd98..81e3b26df 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/ChromaConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/chroma/ChromaConfig.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.config.features;
+package at.hannibal2.skyhanni.config.features.chroma;
import at.hannibal2.skyhanni.SkyHanniMod;
import at.hannibal2.skyhanni.config.FeatureToggle;
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/combat/BestiaryConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/combat/BestiaryConfig.java
new file mode 100644
index 000000000..97c41da3d
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/BestiaryConfig.java
@@ -0,0 +1,48 @@
+package at.hannibal2.skyhanni.config.features.combat;
+
+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.ConfigOption;
+
+public class BestiaryConfig {
+ @Expose
+ @ConfigOption(name = "Enable", desc = "Show Bestiary Data overlay in the Bestiary menu.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Number format", desc = "Short: 1.1k\nLong: 1.100")
+ @ConfigEditorDropdown(values = {"Short", "Long"})
+ public int numberFormat = 0;
+
+ @Expose
+ @ConfigOption(name = "Display type", desc = "Choose what the display should show")
+ @ConfigEditorDropdown(values = {
+ "Global to max",
+ "Global to next tier",
+ "Lowest total kills",
+ "Highest total kills",
+ "Lowest kills needed to max",
+ "Highest kills needed to max",
+ "Lowest kills needed to next tier",
+ "Highest kills needed to next tier"
+ })
+ public int displayType = 0;
+
+ @Expose
+ @ConfigOption(name = "Hide maxed", desc = "Hide maxed mobs.")
+ @ConfigEditorBoolean
+ public boolean hideMaxed = false;
+
+ @Expose
+ @ConfigOption(name = "Replace Romans", desc = "Replace Roman numerals (IX) with regular numbers (9)")
+ @ConfigEditorBoolean
+ public boolean replaceRoman = false;
+
+ @Expose
+ public Position position = new Position(100, 100, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/combat/CombatConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/combat/CombatConfig.java
new file mode 100644
index 000000000..94780f9dd
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/CombatConfig.java
@@ -0,0 +1,47 @@
+package at.hannibal2.skyhanni.config.features.combat;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig;
+import at.hannibal2.skyhanni.config.features.combat.ghostcounter.GhostCounterConfig;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.Category;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class CombatConfig {
+
+ @Expose
+ @Category(name = "Damage Indicator", desc = "Damage Indicator settings")
+ public DamageIndicatorConfig damageIndicator = new DamageIndicatorConfig();
+
+ @Expose
+ @Category(name = "Ghost Counter", desc = "Ghost counter settings")
+ public GhostCounterConfig ghostCounter = new GhostCounterConfig();
+
+ @Expose
+ @ConfigOption(name = "Summonings", desc = "")
+ @Accordion
+ public SummoningsConfig summonings = new SummoningsConfig();
+
+ @Expose
+ @ConfigOption(name = "Mobs", desc = "")
+ @Accordion
+ public MobsConfig mobs = new MobsConfig();
+
+ @Expose
+ @ConfigOption(name = "Bestiary", desc = "")
+ @Accordion
+ public BestiaryConfig bestiary = new BestiaryConfig();
+
+ @Expose
+ @ConfigOption(name = "Ender Node Tracker", desc = "")
+ @Accordion
+ public EnderNodeConfig enderNodeTracker = new EnderNodeConfig();
+
+ @Expose
+ @ConfigOption(name = "Hide Damage Splash", desc = "Hide all damage splashes anywhere in SkyBlock.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideDamageSplash = false;
+}
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
new file mode 100644
index 000000000..0fd962084
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/EnderNodeConfig.java
@@ -0,0 +1,64 @@
+package at.hannibal2.skyhanni.config.features.combat;
+
+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.ConfigEditorDraggableList;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import io.github.moulberry.moulconfig.observer.Property;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class EnderNodeConfig {
+ @Expose
+ @ConfigOption(
+ name = "Enabled",
+ desc = "Tracks all of your drops from mining Ender Nodes in the End.\n" +
+ "Also tracks drops from Endermen."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(
+ 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",
+ " "
+ }
+ )
+ 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)));
+
+ @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
new file mode 100644
index 000000000..77731d854
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/MobsConfig.java
@@ -0,0 +1,94 @@
+package at.hannibal2.skyhanni.config.features.combat;
+
+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 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
+ @FeatureToggle
+ public boolean areaBossHighlight = true;
+
+ @Expose
+ @ConfigOption(name = "Arachne Keeper", desc = "Highlight the Arachne Keeper in the Spider's Den in purple color.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean arachneKeeperHighlight = true;
+
+ @Expose
+ @ConfigOption(name = "Corleone", desc = "Highlight Boss Corleone in the Crystal Hollows.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean corleoneHighlighter = true;
+
+ @Expose
+ @ConfigOption(name = "Zealot", desc = "Highlight Zealots and Bruisers in The End.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean zealotBruiserHighlighter = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Special Zealots",
+ desc = "Highlight Special Zealots (the ones that drop Summoning Eyes) in the End."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean specialZealotHighlighter = true;
+
+ @Expose
+ @ConfigOption(name = "Corrupted Mob", desc = "Highlight corrupted mobs in purple color.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean corruptedMobHighlight = false;
+
+ @Expose
+ @ConfigOption(name = "Arachne Boss", desc = "Highlight the Arachne boss in red and mini-bosses in orange.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ 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. " +
+ "§cSometimes it takes 20-30 seconds to calibrate correctly."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean areaBossRespawnTimer = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Arachne Spawn Timer",
+ desc = "Show a timer when Arachne fragments or crystals are placed to indicate how long " +
+ "until the boss will spawn. §cTimer may be 1-2 seconds off."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean showArachneSpawnTimer = true;
+
+ @Expose
+ @ConfigOption(name = "Enderman TP Hider", desc = "Stops the Enderman Teleportation animation.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean endermanTeleportationHider = true;
+
+ @Expose
+ @ConfigOption(name = "Arachne Minis Hider", desc = "Hides the nametag above Arachne minis.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideNameTagArachneMinis = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/combat/SummoningsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/combat/SummoningsConfig.java
new file mode 100644
index 000000000..9abe2bf8d
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/SummoningsConfig.java
@@ -0,0 +1,38 @@
+package at.hannibal2.skyhanni.config.features.combat;
+
+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 SummoningsConfig {
+
+ @Expose
+ @ConfigOption(name = "Summoning Soul Display", desc = "Show the name of dropped Summoning Souls laying on the ground. " +
+ "§cNot working in Dungeons if Skytils' 'Hide Non-Starred Mobs Nametags' feature is enabled!")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean summoningSoulDisplay = false;
+
+ @Expose
+ @ConfigOption(name = "Summoning Mob Display", desc = "Show the health of your spawned summons.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean summoningMobDisplay = false;
+
+ @Expose
+ public Position summoningMobDisplayPos = new Position(10, 10, false, true);
+
+ @Expose
+ @ConfigOption(name = "Summoning Mob Nametag", desc = "Hide the nametag of your spawned summons.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean summoningMobHideNametag = false;
+
+ @Expose
+ @ConfigOption(name = "Summoning Mob Color", desc = "Marks own summons green.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean summoningMobColored = false;
+}
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
new file mode 100644
index 000000000..c77e5f3f0
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/damageindicator/DamageIndicatorConfig.java
@@ -0,0 +1,102 @@
+package at.hannibal2.skyhanni.config.features.combat.damageindicator;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorDraggableList;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class DamageIndicatorConfig {
+
+ @Expose
+ @ConfigOption(name = "Damage Indicator Enabled", desc = "Show the boss' remaining health.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Healing Chat Message", desc = "Sends a chat message when a boss heals themself.")
+ @ConfigEditorBoolean
+ public boolean healingMessage = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Boss Name",
+ desc = "Change how the boss name should be displayed.")
+ @ConfigEditorDropdown(values = {"Hidden", "Full Name", "Short Name"})
+ public int bossName = 1;
+
+ @Expose
+ @ConfigOption(
+ 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"
+ }
+ )
+ //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));
+
+ @Expose
+ @ConfigOption(name = "Hide Damage Splash", desc = "Hiding damage splashes near the damage indicator.")
+ @ConfigEditorBoolean
+ public boolean hideDamageSplash = false;
+
+ @Expose
+ @ConfigOption(name = "Damage Over Time", desc = "Show damage and health over time below the damage indicator.")
+ @ConfigEditorBoolean
+ public boolean showDamageOverTime = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Nametag", desc = "Hide the vanilla nametag of damage indicator bosses.")
+ @ConfigEditorBoolean
+ public boolean hideVanillaNametag = false;
+
+ @Expose
+ @ConfigOption(name = "Time to Kill", desc = "Show the time it takes to kill the slayer boss.")
+ @ConfigEditorBoolean
+ public boolean timeToKillSlayer = true;
+
+
+ @Expose
+ @ConfigOption(name = "Ender Slayer", desc = "")
+ @Accordion
+ public EnderSlayerConfig enderSlayer = new EnderSlayerConfig();
+
+ @Expose
+ @ConfigOption(name = "Vampire Slayer", desc = "")
+ @Accordion
+ public VampireSlayerConfig vampireSlayer = new VampireSlayerConfig();
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/combat/damageindicator/EnderSlayerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/combat/damageindicator/EnderSlayerConfig.java
new file mode 100644
index 000000000..392505686
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/damageindicator/EnderSlayerConfig.java
@@ -0,0 +1,18 @@
+package at.hannibal2.skyhanni.config.features.combat.damageindicator;
+
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class EnderSlayerConfig {
+
+ @Expose
+ @ConfigOption(name = "Laser Phase Timer", desc = "Show a timer when the laser phase will end.")
+ @ConfigEditorBoolean
+ public boolean laserPhaseTimer = false;
+
+ @Expose
+ @ConfigOption(name = "Health During Laser", desc = "Show the health of Voidgloom Seraph 4 during the laser phase.")
+ @ConfigEditorBoolean
+ public boolean showHealthDuringLaser = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/combat/damageindicator/VampireSlayerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/combat/damageindicator/VampireSlayerConfig.java
new file mode 100644
index 000000000..ec1d07b92
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/damageindicator/VampireSlayerConfig.java
@@ -0,0 +1,23 @@
+package at.hannibal2.skyhanni.config.features.combat.damageindicator;
+
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class VampireSlayerConfig {
+
+ @Expose
+ @ConfigOption(name = "HP Until Steak", desc = "Show the amount of HP missing until the Steak can be used on the Vampire Slayer on top of the boss.")
+ @ConfigEditorBoolean
+ public boolean hpTillSteak = false;
+
+ @Expose
+ @ConfigOption(name = "Mania Circles", desc = "Show a timer until the boss leaves the invincible Mania Circles state.")
+ @ConfigEditorBoolean
+ public boolean maniaCircles = false;
+
+ @Expose
+ @ConfigOption(name = "Percentage HP", desc = "Show the percentage of HP next to the HP.")
+ @ConfigEditorBoolean
+ public boolean percentage = false;
+}
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
new file mode 100644
index 000000000..783c4cda5
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/GhostCounterConfig.java
@@ -0,0 +1,96 @@
+package at.hannibal2.skyhanni.config.features.combat.ghostcounter;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+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;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorButton;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorDraggableList;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class GhostCounterConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Enable the ghost counter (invisible creepers in the Dwarven Mines The Mist area).")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(
+ 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"
+ }
+ )
+ public List<Integer> ghostDisplayText = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 9, 10, 11, 12));
+
+ @ConfigOption(name = "Text Formatting", desc = "")
+ @Accordion
+ @Expose
+ public TextFormattingConfig textFormatting = new TextFormattingConfig();
+
+ @Expose
+ @ConfigOption(name = "Extra space", desc = "Space between each line of text.")
+ @ConfigEditorSlider(
+ minValue = -5,
+ maxValue = 10,
+ minStep = 1)
+ public int extraSpace = 1;
+
+ @Expose
+ @ConfigOption(name = "Pause Timer", desc = "How many seconds does it wait before pausing.")
+ @ConfigEditorSlider(
+ minValue = 1,
+ maxValue = 20,
+ minStep = 1
+ )
+ public int pauseTimer = 3;
+
+ @Expose
+ @ConfigOption(name = "Show only in The Mist", desc = "Show the overlay only when you are in The Mist.")
+ @ConfigEditorBoolean
+ public boolean onlyOnMist = true;
+
+ @Expose
+ @ConfigOption(name = "Maxed Bestiary", desc = "Show progress to max bestiary instead of next level.")
+ @ConfigEditorBoolean
+ public boolean showMax = false;
+
+ @ConfigOption(name = "Reset", desc = "Reset the counter.")
+ @ConfigEditorButton(buttonText = "Reset")
+ public Runnable resetCounter = GhostUtil.INSTANCE::reset;
+
+ @Expose
+ public Position position = new Position(50, 50, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/BestiaryFormattingConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/BestiaryFormattingConfig.java
new file mode 100644
index 000000000..c41b23fe1
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/BestiaryFormattingConfig.java
@@ -0,0 +1,41 @@
+package at.hannibal2.skyhanni.config.features.combat.ghostcounter.textformatting;
+
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorText;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class BestiaryFormattingConfig {
+
+ @Expose
+ @ConfigOption(name = "Bestiary", desc = "Bestiary Progress line.\n§e%value% §7is replaced with\n" +
+ "Your current progress to next level.\n" +
+ "§e%currentLevel% &7is replaced with your current bestiary level\n" +
+ "§e%nextLevel% §7is replaced with your current bestiary level +1.\n" +
+ "§e%value% §7is replaced with one of the text below.")
+ @ConfigEditorText
+ public String base = " &6Bestiary %display%: &b%value%";
+
+ @Expose
+ @ConfigOption(name = "No Data", desc = "Text to show when you need to open the\nBestiary Menu to gather data.")
+ @ConfigEditorText
+ public String openMenu = "§cOpen Bestiary Menu !";
+
+ @Expose
+ @ConfigOption(name = "Maxed", desc = "Text to show when your bestiary for ghost is at max level.\n" +
+ "§e%currentKill% §7is replaced with your current total kill.")
+ @ConfigEditorText
+ public String maxed = "%currentKill% (&c&lMaxed!)";
+
+ @Expose
+ @ConfigOption(name = "Progress to Max", desc = "Text to show progress when the §eMaxed Bestiary §7option is §aON\n" +
+ "§e%currentKill% §7is replaced with your current total kill.")
+ @ConfigEditorText
+ public String showMax_progress = "%currentKill%/250k (%percentNumber%%)";
+
+ @Expose
+ @ConfigOption(name = "Progress", desc = "Text to show progress when the §eMaxed Bestiary§7 option is §cOFF\n" +
+ "§e%currentKill% §7is replaced with how many kill you have to the next level.\n" +
+ "§e%killNeeded% §7is replaced with how many kill you need to reach the next level.")
+ @ConfigEditorText
+ public String progress = "%currentKill%/%killNeeded%";
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/ETAFormattingConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/ETAFormattingConfig.java
new file mode 100644
index 000000000..146b56811
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/ETAFormattingConfig.java
@@ -0,0 +1,42 @@
+package at.hannibal2.skyhanni.config.features.combat.ghostcounter.textformatting;
+
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorText;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class ETAFormattingConfig {
+ @Expose
+ @ConfigOption(name = "ETA to next level", desc = "ETA To Next Level Line.\n" +
+ "§e%value% §7is replaced with one of the text below.")
+ @ConfigEditorText
+ public String base = " &6ETA: &b%value%";
+
+ @Expose
+ @ConfigOption(name = "Maxed!", desc = "So you really maxed ghost bestiary ?")
+ @ConfigEditorText
+ public String maxed = "&c&lMAXED!";
+
+ @Expose
+ @ConfigOption(name = "No Data", desc = "Start killing some ghosts !")
+ @ConfigEditorText
+ public String noData = "&bN/A";
+
+ @Expose
+ @ConfigOption(name = "Progress", desc = "Text to show progress to next level.")
+ @ConfigEditorText
+ public String progress = "&b%value%";
+
+ @Expose
+ @ConfigOption(name = "Paused", desc = "Text displayed next to the time \n" +
+ "when you are doing nothing for a given amount of seconds")
+ @ConfigEditorText
+ public String paused = "&c(PAUSED)";
+
+ @Expose
+ @ConfigOption(name = "Time", desc = "§e%days% §7is replaced with days remaining.\n" +
+ "§e%hours% §7is replaced with hours remaining.\n" +
+ "§e%minutes% §7is replaced with minutes remaining.\n" +
+ "§e%seconds% §7is replaced with seconds remaining.")
+ @ConfigEditorText
+ public String time = "&6%days%%hours%%minutes%%seconds%";
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/KillHourFormattingConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/KillHourFormattingConfig.java
new file mode 100644
index 000000000..41cf0dcdd
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/KillHourFormattingConfig.java
@@ -0,0 +1,24 @@
+package at.hannibal2.skyhanni.config.features.combat.ghostcounter.textformatting;
+
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorText;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class KillHourFormattingConfig {
+ @Expose
+ @ConfigOption(name = "Kill/h", desc = "Kill Per Hour line.\n§e%value% §7is replaced with\nEstimated kills per hour you get.")
+ @ConfigEditorText
+ public String base = " &6Kill/h: &b%value%";
+
+ @Expose
+ @ConfigOption(name = "No Data", desc = "Start killing some ghosts !")
+ @ConfigEditorText
+ public String noData = "&bN/A";
+
+ @Expose
+ @ConfigOption(name = "Paused", desc = "Text displayed next to the time \n" +
+ "when you are doing nothing for a given amount of seconds")
+ @ConfigEditorText
+ public String paused = "&c(PAUSED)";
+}
+
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
new file mode 100644
index 000000000..750b3ae2c
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/TextFormattingConfig.java
@@ -0,0 +1,148 @@
+package at.hannibal2.skyhanni.config.features.combat.ghostcounter.textformatting;
+
+import at.hannibal2.skyhanni.features.combat.ghostcounter.GhostFormatting;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorButton;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorInfoText;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorText;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class TextFormattingConfig {
+
+ @ConfigOption(name = "§eText Formatting Info", desc = "§e%session% §ris §e§lalways §rreplaced with\n" +
+ "§7the count for your current session.\n" +
+ "§7Reset when restarting the game.\n" +
+ "§7You can use §e&Z §7color code to use SBA chroma.")
+ @ConfigEditorInfoText
+ public boolean formatInfo = false;
+
+ @ConfigOption(name = "Reset Formatting", desc = "Reset formatting to default text.")
+ @ConfigEditorButton(buttonText = "Reset")
+ public Runnable resetFormatting = GhostFormatting.INSTANCE::reset;
+
+ @ConfigOption(name = "Export Formatting", desc = "Export current formatting to clipboard.")
+ @ConfigEditorButton(buttonText = "Export")
+ public Runnable exportFormatting = GhostFormatting.INSTANCE::export;
+
+ @ConfigOption(name = "Import Formatting", desc = "Import formatting from clipboard.")
+ @ConfigEditorButton(buttonText = "Import")
+ public Runnable importFormatting = GhostFormatting.INSTANCE::importFormat;
+
+ @Expose
+ @ConfigOption(name = "Title", desc = "Title Line.")
+ @ConfigEditorText
+ 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")
+ @ConfigEditorText
+ public String ghostKilledFormat = " &6Ghost Killed: &b%value% &7(%session%)";
+
+ @Expose
+ @ConfigOption(name = "Sorrows", desc = "Sorrows drop line.\n" +
+ "§e%value% §7is replaced with\nsorrows dropped.")
+ @ConfigEditorText
+ public String sorrowsFormat = " &6Sorrow: &b%value% &7(%session%)";
+
+ @Expose
+ @ConfigOption(name = "Ghost Since Sorrow", desc = "Ghost Since Sorrow line.\n" +
+ "§e%value% §7is replaced with\nGhost since last sorrow drop.")
+ @ConfigEditorText
+ public String ghostSinceSorrowFormat = " &6Ghost since Sorrow: &b%value%";
+
+ @Expose
+ @ConfigOption(name = "Ghost Kill Per Sorrow", desc = "Ghost Kill Per Sorrow line.\n" +
+ "§e%value% §7is replaced with\naverage ghost kill per sorrow drop.")
+ @ConfigEditorText
+ public String ghostKillPerSorrowFormat = " &6Ghosts/Sorrow: &b%value%";
+
+ @Expose
+ @ConfigOption(name = "Voltas", desc = "Voltas drop line.\n" +
+ "§e%value% §7is replaced with\nvoltas dropped.")
+ @ConfigEditorText
+ public String voltasFormat = " &6Voltas: &b%value% &7(%session%)";
+
+ @Expose
+ @ConfigOption(name = "Plasmas", desc = "Plasmas drop line.\n" +
+ "§e%value% §7is replaced with\nplasmas dropped.")
+ @ConfigEditorText
+ public String plasmasFormat = " &6Plasmas: &b%value% &7(%session%)";
+
+ @Expose
+ @ConfigOption(name = "Ghostly Boots", desc = "Ghostly Boots drop line.\n" +
+ "§e%value% §7is replaced with\nGhostly Boots dropped.")
+ @ConfigEditorText
+ public String ghostlyBootsFormat = " &6Ghostly Boots: &b%value% &7(%session%)";
+
+ @Expose
+ @ConfigOption(name = "Bag Of Cash", desc = "Bag Of Cash drop line.\n" +
+ "§e%value% §7is replaced with\nBag Of Cash dropped.")
+ @ConfigEditorText
+ public String bagOfCashFormat = " &6Bag Of Cash: &b%value% &7(%session%)";
+
+ @Expose
+ @ConfigOption(name = "Average Magic Find", desc = "Average Magic Find line.\n" +
+ "§e%value% §7is replaced with\nAverage Magic Find.")
+ @ConfigEditorText
+ public String avgMagicFindFormat = " &6Avg Magic Find: &b%value%";
+
+ @Expose
+ @ConfigOption(name = "Scavenger Coins", desc = "Scavenger Coins line.\n" +
+ "§e%value% §7is replaced with\nCoins earned from kill ghosts.\nInclude: Scavenger Enchant, Scavenger Talismans, Kill Combo.")
+ @ConfigEditorText
+ public String scavengerCoinsFormat = " &6Scavenger Coins: &b%value% &7(%session%)";
+
+ @Expose
+ @ConfigOption(name = "Kill Combo", desc = "Kill Combo line.\n" +
+ "§e%value% §7is replaced with\nYour current kill combo.")
+ @ConfigEditorText
+ public String killComboFormat = " &6Kill Combo: &b%value%";
+
+ @Expose
+ @ConfigOption(name = "Highest Kill Combo", desc = "Highest Kill Combo line.\n" +
+ "§e%value% §7is replaced with\nYour current highest kill combo.")
+ @ConfigEditorText
+ public String highestKillComboFormat = " &6Highest Kill Combo: &b%value% &7(%session%)";
+
+ @Expose
+ @ConfigOption(name = "Skill XP Gained", desc = "Skill XP Gained line.\n" +
+ "§e%value% §7is replaced with\nSkill XP Gained from killing Ghosts.")
+ @ConfigEditorText
+ public String skillXPGainFormat = " &6Skill XP Gained: &b%value% &7(%session%)";
+
+ @ConfigOption(name = "Bestiary Formatting", desc = "")
+ @Accordion
+ @Expose
+ public BestiaryFormattingConfig bestiaryFormatting = new BestiaryFormattingConfig();
+
+ @ConfigOption(name = "XP Per Hour Formatting", desc = "")
+ @Accordion
+ @Expose
+ public XPHourFormattingConfig xpHourFormatting = new XPHourFormattingConfig();
+
+ @ConfigOption(name = "ETA Formatting", desc = "")
+ @Accordion
+ @Expose
+ public ETAFormattingConfig etaFormatting = new ETAFormattingConfig();
+
+ @ConfigOption(name = "Kill Per Hour Formatting", desc = "")
+ @Expose
+ @Accordion
+ public KillHourFormattingConfig killHourFormatting = new KillHourFormattingConfig();
+
+ @Expose
+ @ConfigOption(name = "Money Per Hour", desc = "Money Per Hour.\n§e%value% §7is replaced with\nEstimated money you get per hour\n" +
+ "Calculated with your kill per hour and your average magic find.")
+ @ConfigEditorText
+ public String moneyHourFormat = " &6$/h: &b%value%";
+
+ @Expose
+ @ConfigOption(name = "Money made", desc = "Calculate the money you made.\nInclude §eSorrow§7, §ePlasma§7, §eVolta§7, §e1M coins drop\n" +
+ "§eGhostly Boots§7, §eScavenger coins.\n" +
+ "§cUsing current Sell Offer value.")
+ @ConfigEditorText
+ public String moneyMadeFormat = " &6Money made: &b%value%";
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/XPHourFormattingConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/XPHourFormattingConfig.java
new file mode 100644
index 000000000..d04f4942a
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/XPHourFormattingConfig.java
@@ -0,0 +1,26 @@
+package at.hannibal2.skyhanni.config.features.combat.ghostcounter.textformatting;
+
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorText;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class XPHourFormattingConfig {
+
+ @Expose
+ @ConfigOption(name = "XP/h", desc = "XP Per Hour line.\n" +
+ "§e%value% §7is replaced with one of the text below.")
+ @ConfigEditorText
+ public String base = " &6XP/h: &b%value%";
+
+ @Expose
+ @ConfigOption(name = "No Data", desc = "XP Per Hour line.\n§e%value% §7is replaced with\nEstimated amount of combat xp you gain per hour.")
+ @ConfigEditorText
+ public String noData = "&bN/A";
+
+ @Expose
+ @ConfigOption(name = "Paused", desc = "Text displayed next to the time \n" +
+ "when you are doing nothing for a given amount of seconds")
+ @ConfigEditorText
+ public String paused = "&c(PAUSED)";
+}
+
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/commands/CommandsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/commands/CommandsConfig.java
new file mode 100644
index 000000000..777d543a3
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/commands/CommandsConfig.java
@@ -0,0 +1,39 @@
+package at.hannibal2.skyhanni.config.features.commands;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class CommandsConfig {
+
+ @ConfigOption(name = "Tab Complete", desc = "")
+ @Accordion
+ @Expose
+ public TabCompleteConfig tabComplete = new TabCompleteConfig();
+
+ @ConfigOption(name = "Fandom Wiki for §e/wiki", desc = "")
+ @Accordion
+ @Expose
+ public FandomWikiCommandConfig fandomWiki = new FandomWikiCommandConfig();
+
+ @ConfigOption(name = "Party Commands", desc = "Shortens party commands and allows tab-completing for them. " +
+ "\n§eCommands: /pt /pp /pko /pk §7SkyBlock command §e/pt §7to check the play time still works.")
+ @Expose
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean shortCommands = true;
+
+ @Expose
+ @ConfigOption(name = "Replace Warp Is", desc = "Adds §e/warp is §7alongside §e/is§7. Idk why. Ask §cKaeso")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean replaceWarpIs = false;
+
+ @Expose
+ @ConfigOption(name = "/viewrecipe Lower Case", desc = "Adds support for lower case item IDs to the Hypixel command §e/viewrecipe§7.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean viewRecipeLowerCase = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/commands/FandomWikiCommandConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/commands/FandomWikiCommandConfig.java
new file mode 100644
index 000000000..c8a25a204
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/commands/FandomWikiCommandConfig.java
@@ -0,0 +1,27 @@
+package at.hannibal2.skyhanni.config.features.commands;
+
+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 FandomWikiCommandConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Use Fandom Wiki (§ehypixel-skyblock.fandom.com§7) instead of the Hypixel wiki (§ewiki.hypixel.net§7) in most wiki-related chat messages.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Skip Chat", desc = "Directly opens the Fandom Wiki instead of sending the §e\"Click to search for this thing on the Fandom Wiki\"§7 message beforehand.")
+ @ConfigEditorBoolean
+ public boolean skipWikiChat = false;
+
+ @Expose
+ @ConfigOption(name = "Fandom Wiki Key", desc = "Search for an item on Fandom Wiki with this keybind.\n§4For optimal experiences, do §lNOT§r §4bind this to a mouse button.")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
+ public int fandomWikiKeybind = Keyboard.KEY_NONE;
+}
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
new file mode 100644
index 000000000..6e3420a59
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/commands/TabCompleteConfig.java
@@ -0,0 +1,61 @@
+package at.hannibal2.skyhanni.config.features.commands;
+
+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 TabCompleteConfig {
+
+ @Expose
+ @ConfigOption(name = "Warps", desc = "Tab complete the warp-point names when typing §e/warp <TAB>§7.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean warps = true;
+
+ @Expose
+ @ConfigOption(name = "Island Players", desc = "Tab complete other players on the same island.")
+ public boolean islandPlayers = true;
+
+ @Expose
+ @ConfigOption(name = "Friends", desc = "Tab complete friends from your friends list.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean friends = true;
+
+ @Expose
+ @ConfigOption(name = "Only Best Friends", desc = "Only Tab Complete best friends.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean onlyBestFriends = false;
+
+ @Expose
+ @ConfigOption(name = "Party", desc = "Tab complete Party Members.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean party = true;
+
+ @Expose
+ @ConfigOption(name = "VIP Visits", desc = "Tab complete the visit to special users with cake souls on it.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean vipVisits = true;
+
+ @Expose
+ @ConfigOption(name = "/gfs Sack", desc = "Tab complete §e/gfs §7sack items.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean gfsSack = true;
+
+ @Expose
+ @ConfigOption(name = "Party Commands", desc = "Tab complete commonly used party commands.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean partyCommands = true;
+
+ @Expose
+ @ConfigOption(name = "View Recipe", desc = "Tab complete item IDs in the the Hypixel command §e/viewrecipe§7. Only items with recipes are tab completed.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean viewrecipeItems = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/CrimsonIsleConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/CrimsonIsleConfig.java
new file mode 100644
index 000000000..7dd530bc4
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/CrimsonIsleConfig.java
@@ -0,0 +1,34 @@
+package at.hannibal2.skyhanni.config.features.crimsonisle;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.features.crimsonisle.ashfang.AshfangConfig;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.Category;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class CrimsonIsleConfig {
+
+ @Category(name = "Ashfang", desc = "Ashfang settings")
+ @Expose
+ public AshfangConfig ashfang = new AshfangConfig();
+
+ @ConfigOption(name = "Reputation Helper", desc = "")
+ @Accordion
+ @Expose
+ public ReputationHelperConfig reputationHelper = new ReputationHelperConfig();
+
+ @Expose
+ @ConfigOption(name = "Quest Item Helper", desc = "When you open the fetch item quest in the town board, " +
+ "it shows a clickable chat message that will grab the items needed from the sacks.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean questItemHelper = false;
+
+ @Expose
+ @ConfigOption(name = "Pablo NPC Helper", desc = "Similar to Quest Item Helper, shows a clickable message that grabs the flower needed from sacks.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean pabloHelper = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/ReputationHelperConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/ReputationHelperConfig.java
new file mode 100644
index 000000000..cddce2228
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/ReputationHelperConfig.java
@@ -0,0 +1,38 @@
+package at.hannibal2.skyhanni.config.features.crimsonisle;
+
+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.ConfigEditorKeybind;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import org.lwjgl.input.Keyboard;
+
+public class ReputationHelperConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Enable features around Reputation features in the Crimson Isle.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Use Hotkey", desc = "Only show the Reputation Helper while pressing the hotkey.")
+ @ConfigEditorBoolean
+ public boolean useHotkey = false;
+
+ @Expose
+ @ConfigOption(name = "Hotkey", desc = "Press this hotkey to show the Reputation Helper.")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
+ public int hotkey = Keyboard.KEY_NONE;
+
+
+ @Expose
+ public Position position = new Position(10, 10, false, true);
+
+ @Expose
+ @ConfigOption(name = "Show Locations", desc = "Crimson Isles waypoints for locations to get reputation.")
+ @ConfigEditorDropdown(values = {"Always", "Only With Hotkey", "Never"})
+ public int showLocation = 1;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/ashfang/AshfangConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/ashfang/AshfangConfig.java
new file mode 100644
index 000000000..6e983e440
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/ashfang/AshfangConfig.java
@@ -0,0 +1,50 @@
+package at.hannibal2.skyhanni.config.features.crimsonisle.ashfang;
+
+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.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class AshfangConfig {
+
+ @ConfigOption(name = "Gravity Orbs", desc = "")
+ @Accordion
+ @Expose
+ public GravityOrbsConfig gravityOrbs = new GravityOrbsConfig();
+
+ @ConfigOption(name = "Blazing Souls", desc = "")
+ @Accordion
+ @Expose
+ public BlazingSoulsColor blazingSouls = new BlazingSoulsColor();
+
+ @ConfigOption(name = "Hide Stuff", desc = "")
+ @Accordion
+ @Expose
+ public HideAshfangConfig hide = new HideAshfangConfig();
+
+ @Expose
+ @ConfigOption(name = "Highlight Blazes", desc = "Highlight the different blazes in their respective colors.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlightBlazes = false;
+
+ @Expose
+ @ConfigOption(name = "Freeze Cooldown", desc = "Show the cooldown for how long Ashfang blocks your abilities.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean freezeCooldown = false;
+
+ @Expose
+ public Position freezeCooldownPos = new Position(10, 10, false, true);
+
+ @Expose
+ @ConfigOption(name = "Reset Time", desc = "Show the cooldown until Ashfang pulls his underlings back.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean nextResetCooldown = false;
+
+ @Expose
+ public Position nextResetCooldownPos = new Position(10, 10, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/ashfang/BlazingSoulsColor.java b/src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/ashfang/BlazingSoulsColor.java
new file mode 100644
index 000000000..6af0547d8
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/ashfang/BlazingSoulsColor.java
@@ -0,0 +1,21 @@
+package at.hannibal2.skyhanni.config.features.crimsonisle.ashfang;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class BlazingSoulsColor {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Shows the Blazing Souls more clearly.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Souls Color", desc = "Color of the Blazing Souls.")
+ @ConfigEditorColour
+ public String color = "0:245:85:255:85";
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/ashfang/GravityOrbsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/ashfang/GravityOrbsConfig.java
new file mode 100644
index 000000000..a9e1fddf5
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/ashfang/GravityOrbsConfig.java
@@ -0,0 +1,21 @@
+package at.hannibal2.skyhanni.config.features.crimsonisle.ashfang;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class GravityOrbsConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Shows the Gravity Orbs more clearly.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Color", desc = "Color of the Gravity Orbs.")
+ @ConfigEditorColour
+ public String color = "0:120:255:85:85";
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/ashfang/HideAshfangConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/ashfang/HideAshfangConfig.java
new file mode 100644
index 000000000..1160988e5
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/crimsonisle/ashfang/HideAshfangConfig.java
@@ -0,0 +1,27 @@
+package at.hannibal2.skyhanni.config.features.crimsonisle.ashfang;
+
+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 HideAshfangConfig {
+
+ @Expose
+ @ConfigOption(name = "Hide Particles", desc = "Hide particles around the Ashfang boss.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean particles = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Full Names", desc = "Hide the names of full health blazes around Ashfang (only useful when highlight blazes is enabled)")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean fullNames = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Damage Splash", desc = "Hide damage splashes around Ashfang.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean damageSplash = false;
+}
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
new file mode 100644
index 000000000..7f7b9af63
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/dev/DebugConfig.java
@@ -0,0 +1,88 @@
+package at.hannibal2.skyhanni.config.features.dev;
+
+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 DebugConfig {
+ @Expose
+ @ConfigOption(name = "Enable Debug", desc = "Enable Test logic")
+ @ConfigEditorBoolean
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Command Logging", desc = "Logs stack trace information into the console when a command gets sent to Hypixel. (by any mod or the player)")
+ @ConfigEditorBoolean
+ public boolean commandLogs = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Mod Menu Log",
+ desc = "Enables debug messages when the currently opened GUI changes, with the path to the gui class. " +
+ "Useful for adding more mods to quick mod menu switch."
+ )
+ @ConfigEditorBoolean
+ public boolean modMenuLog = false;
+
+ @Expose
+ @ConfigOption(name = "Show Internal Name", desc = "Show internal names in item lore.")
+ @ConfigEditorBoolean
+ public boolean showInternalName = false;
+
+ @Expose
+ @ConfigOption(name = "Show Empty Internal Names", desc = "Shows internal name even for items with none.")
+ @ConfigEditorBoolean
+ public boolean showEmptyNames = false;
+
+ @Expose
+ @ConfigOption(name = "Show Item Rarity", desc = "Show item rarities in item lore.")
+ @ConfigEditorBoolean
+ public boolean showItemRarity = false;
+
+ @Expose
+ @ConfigOption(name = "Copy Internal Name", desc = "Copies the internal name of an item on key press in the clipboard.")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
+ public int copyInternalName = Keyboard.KEY_NONE;
+
+ @Expose
+ @ConfigOption(name = "Show NPC Price", desc = "Show NPC price in item lore.")
+ @ConfigEditorBoolean
+ public boolean showNpcPrice = false;
+
+ @Expose
+ @ConfigOption(name = "Show Item UUID", desc = "Show the Unique Identifier of items in the lore.")
+ @ConfigEditorBoolean
+ public boolean showItemUuid = false;
+
+ @Expose
+ @ConfigOption(name = "Copy Item Data", desc = "Copies item NBT data on key press in a GUI to clipboard.")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
+ public int copyItemData = Keyboard.KEY_NONE;
+
+ @Expose
+ @ConfigOption(name = "Copy Compressed Item Data", desc = "Copies compressed item NBT data on key press in a GUI to clipboard.")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
+ public int copyItemDataCompressed = Keyboard.KEY_NONE;
+
+ @Expose
+ @ConfigOption(name = "Copy RNG Meter", desc = "Copies internal names and maxed XP needed from RNG meter inventories as json to clipboard.")
+ @ConfigEditorBoolean
+ public boolean copyRngMeter = false;
+
+ @Expose
+ @ConfigOption(name = "Copy Bestiary Data", desc = "Copies the bestiary data from the inventory as json to clipboard.")
+ @ConfigEditorBoolean
+ public boolean copyBestiaryData = false;
+
+ @Expose
+ @ConfigOption(name = "Highlight Missing Repo Items", desc = "Highlights each item in the current inventory that is not in your current NEU repo.")
+ @ConfigEditorBoolean
+ public boolean highlightMissingRepo = false;
+
+ @Expose
+ @ConfigOption(name = "Hot Swap Detection", desc = "Show chat messages when Hot Swap starts and ends.")
+ @ConfigEditorBoolean
+ public boolean hotSwapDetection = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/dev/DevConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/dev/DevConfig.java
new file mode 100644
index 000000000..0c1fc01ed
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/dev/DevConfig.java
@@ -0,0 +1,52 @@
+package at.hannibal2.skyhanni.config.features.dev;
+
+import at.hannibal2.skyhanni.config.core.config.Position;
+import at.hannibal2.skyhanni.config.features.dev.minecraftconsole.MinecraftConsoleConfig;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.Category;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import org.lwjgl.input.Keyboard;
+
+public class DevConfig {
+
+ @Expose
+ @ConfigOption(name = "Repo Auto Update", desc = "Update the repository on every startup.\n" +
+ "§cOnly disable this if you know what you are doing!")
+ @ConfigEditorBoolean
+ public boolean repoAutoUpdate = true;
+
+ @Expose
+ @ConfigOption(name = "Log Expiry Time", desc = "Deletes your SkyHanni logs after this time period in days.")
+ @ConfigEditorSlider(minValue = 1, maxValue = 30, minStep = 1)
+ public int logExpiryTime = 14;
+
+ @Expose
+ @ConfigOption(name = "Debug", desc = "")
+ @Accordion
+ public DebugConfig debug = new DebugConfig();
+
+ @Expose
+ @ConfigOption(name = "Slot Number", desc = "Show slot number in inventory while pressing this key.")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
+ public int showSlotNumberKey = Keyboard.KEY_NONE;
+
+ @ConfigOption(name = "Parkour Waypoints", desc = "")
+ @Accordion
+ @Expose
+ public WaypointsConfig waypoint = new WaypointsConfig();
+
+ @Expose
+ public Position debugPos = new Position(10, 10, false, true);
+
+ @Expose
+ public Position debugLocationPos = new Position(1, 160, false, true);
+
+ @Expose
+ @Category(name = "Minecraft Console", desc = "Minecraft Console Settings")
+ public MinecraftConsoleConfig minecraftConsoles = new MinecraftConsoleConfig();
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/dev/WaypointsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/dev/WaypointsConfig.java
new file mode 100644
index 000000000..863f91476
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/dev/WaypointsConfig.java
@@ -0,0 +1,26 @@
+package at.hannibal2.skyhanni.config.features.dev;
+
+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 WaypointsConfig {
+
+ @Expose
+ @ConfigOption(name = "Save Hotkey", desc = "Saves block location to a temporarily parkour and copies everything to your clipboard.")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
+ public int saveKey = Keyboard.KEY_NONE;
+
+ @Expose
+ @ConfigOption(name = "Delete Hotkey", desc = "Deletes the last saved location for when you make a mistake.")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
+ public int deleteKey = Keyboard.KEY_NONE;
+
+ @Expose
+ @ConfigOption(name = "Show Platform Number", desc = "Show the index number over the platform for every parkour.")
+ @ConfigEditorBoolean
+ public boolean showPlatformNumber = false;
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/dev/minecraftconsole/ConsoleFiltersConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/dev/minecraftconsole/ConsoleFiltersConfig.java
new file mode 100644
index 000000000..6f537f300
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/dev/minecraftconsole/ConsoleFiltersConfig.java
@@ -0,0 +1,53 @@
+package at.hannibal2.skyhanni.config.features.dev.minecraftconsole;
+
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class ConsoleFiltersConfig {
+ @Expose
+ @ConfigOption(name = "Filter Chat", desc = "Filter chat messages.")
+ @ConfigEditorBoolean
+ public boolean filterChat = false;
+
+ @Expose
+ @ConfigOption(name = "Filter Grow Buffer", desc = "Filter 'Needed to grow BufferBuilder buffer:'")
+ @ConfigEditorBoolean
+ public boolean filterGrowBuffer = true;
+
+ @Expose
+ @ConfigOption(name = "Filter Sound Error", desc = "Filter 'Unable to play unknown soundEvent'.")
+ @ConfigEditorBoolean
+ public boolean filterUnknownSound = true;
+
+ @Expose
+ @ConfigOption(name = "Filter Scoreboard Errors", desc = "Filter error messages with Scoreboard: removeTeam, createTeam, " +
+ "removeObjective and 'scoreboard team already exists'.")
+ @ConfigEditorBoolean
+ public boolean filterScoreboardErrors = true;
+
+ @Expose
+ @ConfigOption(name = "Filter Particle", desc = "Filter message 'Could not spawn particle effect VILLAGER_HAPPY'.")
+ @ConfigEditorBoolean
+ public boolean filterParticleVillagerHappy = true;
+
+ @Expose
+ @ConfigOption(name = "Filter OptiFine", desc = "Filter OptiFine messages CustomItems and ConnectedTextures during loading.")
+ @ConfigEditorBoolean
+ public boolean filterOptiFine = true;
+
+ @Expose
+ @ConfigOption(name = "Filter AsmHelper Transformer", desc = "Filter messages when AsmHelper is Transforming a class during loading.")
+ @ConfigEditorBoolean
+ public boolean filterAmsHelperTransformer = true;
+
+ @Expose
+ @ConfigOption(name = "Filter Applying AsmWriter", desc = "Filter messages when AsmHelper is applying AsmWriter ModifyWriter.")
+ @ConfigEditorBoolean
+ public boolean filterAsmHelperApplying = true;
+
+ @Expose
+ @ConfigOption(name = "Filter Biome ID Bounds", desc = "Filter message 'Biome ID is out of bounds'.")
+ @ConfigEditorBoolean
+ public boolean filterBiomeIdBounds = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/dev/minecraftconsole/MinecraftConsoleConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/dev/minecraftconsole/MinecraftConsoleConfig.java
new file mode 100644
index 000000000..bdca34590
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/dev/minecraftconsole/MinecraftConsoleConfig.java
@@ -0,0 +1,40 @@
+package at.hannibal2.skyhanni.config.features.dev.minecraftconsole;
+
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class MinecraftConsoleConfig {
+ @Expose
+ @ConfigOption(name = "Unfiltered Debug", desc = "Print the debug information for unfiltered console messages.")
+ @ConfigEditorBoolean
+ public boolean printUnfilteredDebugs = false;
+
+ @Expose
+ @ConfigOption(name = "Unfiltered Debug File", desc = "Print the debug information into log files instead of into the console for unfiltered console messages.")
+ @ConfigEditorBoolean
+ public boolean logUnfilteredFile = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Outside SkyBlock",
+ desc = "Print the debug information for unfiltered console messages outside SkyBlock too."
+ )
+ @ConfigEditorBoolean
+ public boolean printUnfilteredDebugsOutsideSkyBlock = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Log Filtered",
+ desc = "Log the filtered messages into the console."
+ )
+ @ConfigEditorBoolean
+ public boolean printFilteredReason = false;
+
+ @Expose
+ @ConfigOption(name = "Console Filters", desc = "")
+ @Accordion
+ public ConsoleFiltersConfig consoleFilter = new ConsoleFiltersConfig();
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/CleanEndConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/CleanEndConfig.java
new file mode 100644
index 000000000..4dcdc6d7f
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/CleanEndConfig.java
@@ -0,0 +1,21 @@
+package at.hannibal2.skyhanni.config.features.dungeon;
+
+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 CleanEndConfig {
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "After the last Dungeon boss has died, all entities and " +
+ "particles are no longer displayed and the music stops playing, but the loot chests are still displayed.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Ignore Guardians", desc = "Ignore F3 and M3 Guardians from the clean end feature when " +
+ "sneaking. Makes it easier to kill them after the boss died already. Thanks Hypixel.")
+ @ConfigEditorBoolean
+ public boolean F3IgnoreGuardians = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/DungeonConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/DungeonConfig.java
new file mode 100644
index 000000000..84cba4de7
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/DungeonConfig.java
@@ -0,0 +1,102 @@
+package at.hannibal2.skyhanni.config.features.dungeon;
+
+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.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class DungeonConfig {
+
+ @Expose
+ @ConfigOption(name = "Clicked Blocks", desc = "Highlight levers, chests, and Wither Essence when clicked in Dungeons.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlightClickedBlocks = false;
+
+ @Expose
+ @ConfigOption(name = "Milestones Display", desc = "Show the current milestone in Dungeons.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean showMilestonesDisplay = false;
+
+ @Expose
+ public Position showMileStonesDisplayPos = new Position(10, 10, false, true);
+
+ @Expose
+ @ConfigOption(name = "Death Counter Display", desc = "Display the total amount of deaths in the current Dungeon.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean deathCounterDisplay = false;
+
+ @Expose
+ public Position deathCounterPos = new Position(10, 10, false, true);
+
+ @Expose
+ @ConfigOption(name = "Clean End", desc = "")
+ @Accordion
+ public CleanEndConfig cleanEnd = new CleanEndConfig();
+
+ @Expose
+ @ConfigOption(name = "Boss Damage Splash", desc = "Hides damage splashes while inside the boss room (fixes a Skytils feature).")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean damageSplashBoss = false;
+
+ @Expose
+ @ConfigOption(name = "Highlight Deathmites", desc = "Highlight Deathmites in Dungeons in red color.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlightDeathmites = true;
+
+ @Expose
+ @ConfigOption(name = "Highlight Teammates", desc = "Highlight Dungeon teammates with a glowing outline.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlightTeammates = true;
+
+ @Expose
+ @ConfigOption(name = "Object Hider", desc = "Hide various things in Dungeons.")
+ @Accordion
+ public ObjectHiderConfig objectHider = new ObjectHiderConfig();
+
+ @Expose
+ @ConfigOption(name = "Message Filter", desc = "")
+ @Accordion
+ public MessageFilterConfig messageFilter = new MessageFilterConfig();
+
+ @Expose
+ @ConfigOption(name = "Dungeon Copilot", desc = "")
+ @Accordion
+ public DungeonCopilotConfig dungeonCopilot = new DungeonCopilotConfig();
+
+ @Expose
+ @ConfigOption(name = "Party Finder", desc = "")
+ @Accordion
+ public PartyFinderConfig partyFinder = new PartyFinderConfig();
+
+ @Expose
+ @ConfigOption(name = "Tab List", desc = "")
+ @Accordion
+ public TabListConfig tabList = new TabListConfig();
+
+ @Expose
+ @ConfigOption(name = "Livid Finder", desc = "")
+ @Accordion
+ public LividFinderConfig lividFinder = new LividFinderConfig();
+
+ @Expose
+ @ConfigOption(name = "Moving Skeleton Skulls", desc = "Highlight Skeleton Skulls when combining into an " +
+ "orange Skeletor (not useful when combined with feature Hide Skeleton Skull).")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlightSkeletonSkull = true;
+
+ @Expose
+ @ConfigOption(name = "Croesus Chest", desc = "Adds a visual highlight to the Croesus inventory that " +
+ "shows unopened chests.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean croesusUnopenedChestTracker = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/DungeonCopilotConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/DungeonCopilotConfig.java
new file mode 100644
index 000000000..e285fd951
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/DungeonCopilotConfig.java
@@ -0,0 +1,18 @@
+package at.hannibal2.skyhanni.config.features.dungeon;
+
+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 DungeonCopilotConfig {
+ @Expose
+ @ConfigOption(name = "Copilot Enabled", desc = "Suggests what to do next in Dungeons.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ public Position pos = new Position(10, 10, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/LividFinderConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/LividFinderConfig.java
new file mode 100644
index 000000000..4525d1c31
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/LividFinderConfig.java
@@ -0,0 +1,20 @@
+package at.hannibal2.skyhanni.config.features.dungeon;
+
+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 LividFinderConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Helps find the correct livid in F5 and in M5.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Wrong Livids", desc = "Hide wrong livids entirely.")
+ @ConfigEditorBoolean
+ public boolean hideWrong = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/MessageFilterConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/MessageFilterConfig.java
new file mode 100644
index 000000000..5455ab0f5
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/MessageFilterConfig.java
@@ -0,0 +1,14 @@
+package at.hannibal2.skyhanni.config.features.dungeon;
+
+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 MessageFilterConfig {
+ @Expose
+ @ConfigOption(name = "Keys and Doors", desc = "Hides the chat message when picking up keys or opening doors in Dungeons.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean keysAndDoors = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/ObjectHiderConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/ObjectHiderConfig.java
new file mode 100644
index 000000000..690d09249
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/ObjectHiderConfig.java
@@ -0,0 +1,65 @@
+package at.hannibal2.skyhanni.config.features.dungeon;
+
+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 ObjectHiderConfig {
+ @Expose
+ @ConfigOption(name = "Hide Superboom TNT", desc = "Hide Superboom TNT laying around in Dungeons.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideSuperboomTNT = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Blessings", desc = "Hide Blessings laying around in Dungeons.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideBlessing = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Revive Stones", desc = "Hide Revive Stones laying around in Dungeons.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideReviveStone = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Premium Flesh", desc = "Hide Premium Flesh laying around in Dungeons.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hidePremiumFlesh = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Journal Entry", desc = "Hide Journal Entry pages laying around in Dungeons.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideJournalEntry = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Skeleton Skull", desc = "Hide Skeleton Skulls laying around in Dungeons.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideSkeletonSkull = true;
+
+ @Expose
+ @ConfigOption(name = "Hide Healer Orbs", desc = "Hides the damage, ability damage and defensive orbs that spawn when the Healer kills mobs.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideHealerOrbs = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Healer Fairy", desc = "Hide the Golden Fairy that follows the Healer in Dungeons.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideHealerFairy = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Hide Soulweaver Skulls",
+ desc = "Hide the annoying soulweaver skulls that float around you if you have the soulweaver gloves equipped.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideSoulweaverSkulls = false;
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/PartyFinderConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/PartyFinderConfig.java
new file mode 100644
index 000000000..2abb3ec22
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/PartyFinderConfig.java
@@ -0,0 +1,44 @@
+package at.hannibal2.skyhanni.config.features.dungeon;
+
+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.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class PartyFinderConfig {
+ @Expose
+ @ConfigOption(name = "Colored Class Level", desc = "Color class levels in Party Finder.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean coloredClassLevel = true;
+
+ @Expose
+ @ConfigOption(name = "Floor Stack Size", desc = "Display the party finder floor as the item stack size.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean floorAsStackSize = true;
+
+ @Expose
+ @ConfigOption(name = "Mark Paid Carries", desc = "Highlight paid carries with a red background to make them easier to find/skip.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean markPaidCarries = true;
+
+ @Expose
+ @ConfigOption(name = "Mark Low Levels", desc = "Highlight groups with players at or below the specified class level to make them easier to find/skip.")
+ @ConfigEditorSlider(minValue = 0, maxValue = 50, minStep = 1)
+ public int markBelowClassLevel = 0;
+
+ @Expose
+ @ConfigOption(name = "Mark Ineligible Groups", desc = "Highlight groups with requirements that you do not meet.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean markIneligibleGroups = true;
+
+ @Expose
+ @ConfigOption(name = "Mark Missing Class", desc = "Highlight groups that don't currently have any members of your selected dungeon class.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean markMissingClass = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/TabListConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/TabListConfig.java
new file mode 100644
index 000000000..221cf4651
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/TabListConfig.java
@@ -0,0 +1,15 @@
+package at.hannibal2.skyhanni.config.features.dungeon;
+
+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 TabListConfig {
+
+ @Expose
+ @ConfigOption(name = "Colored Class Level", desc = "Color class levels in tab list. (Also hides rank colors and emblems, because who needs that in Dungeons anyway?)")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean coloredClassLevel = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/CenturyConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/CenturyConfig.java
new file mode 100644
index 000000000..d5636117d
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/CenturyConfig.java
@@ -0,0 +1,24 @@
+package at.hannibal2.skyhanni.config.features.event;
+
+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 CenturyConfig {
+
+ @ConfigOption(name = "Enable Active Player Timer", desc = "Show a HUD telling you how much longer you have to wait to be eligible for another free ticket.")
+ @Expose
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enableActiveTimer = true;
+
+ @Expose
+ public Position activeTimerPosition = new Position(100, 100, false, true);
+
+ @ConfigOption(name = "Enable Active Player Alert", desc = "Loudly proclaim when it is time to break some wheat.")
+ @Expose
+ @ConfigEditorBoolean
+ public boolean enableActiveAlert = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/CityProjectConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/CityProjectConfig.java
new file mode 100644
index 000000000..ec0b853bb
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/CityProjectConfig.java
@@ -0,0 +1,31 @@
+package at.hannibal2.skyhanni.config.features.event;
+
+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 CityProjectConfig {
+
+ @Expose
+ @ConfigOption(name = "Show Materials", desc = "Show materials needed for contributing to the City Project.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean showMaterials = true;
+
+ @Expose
+ @ConfigOption(name = "Show Ready", desc = "Mark contributions that are ready to participate.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean showReady = true;
+
+ @Expose
+ @ConfigOption(name = "Daily Reminder", desc = "Remind every 24 hours to participate.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean dailyReminder = true;
+
+ @Expose
+ public Position pos = new Position(150, 150, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/EventConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/EventConfig.java
new file mode 100644
index 000000000..ef27a42bd
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/EventConfig.java
@@ -0,0 +1,51 @@
+package at.hannibal2.skyhanni.config.features.event;
+
+import at.hannibal2.skyhanni.config.features.event.bingo.BingoConfig;
+import at.hannibal2.skyhanni.config.features.event.diana.DianaConfig;
+import at.hannibal2.skyhanni.config.features.event.winter.WinterConfig;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.Category;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class EventConfig {
+
+ @Category(name = "Bingo", desc = "Monthly Bingo Event settings")
+ @Expose
+ public BingoConfig bingo = new BingoConfig();
+
+ @Category(name = "Diana", desc = "Diana's Mythological Burrows")
+ @Expose
+ public DianaConfig diana = new DianaConfig();
+
+ @Category(name = "Winter", desc = "Winter Season on Jerry's Island")
+ @Expose
+ public WinterConfig winter = new WinterConfig();
+
+ @ConfigOption(name = "City Project", desc = "")
+ @Accordion
+ @Expose
+ public CityProjectConfig cityProject = new CityProjectConfig();
+
+ @ConfigOption(name = "Mayor Jerry's Jerrypocalypse", desc = "")
+ @Accordion
+ @Expose
+ public MayorJerryConfig jerry = new MayorJerryConfig();
+
+ @ConfigOption(name = "The Great Spook", desc = "")
+ @Accordion
+ @Expose
+ public GreatSpookConfig spook = new GreatSpookConfig();
+
+ // comment in if the event is needed again
+// @ConfigOption(name = "300þ Anniversary Celebration", desc = "Features for the 300þ year of SkyBlock")
+ @Accordion
+ @Expose
+ public CenturyConfig century = new CenturyConfig();
+
+ @Expose
+ @ConfigOption(name = "Main Lobby Halloween Basket Waypoints", desc = "")
+ @Accordion
+ public HalloweenBasketConfig halloweenBasket = new HalloweenBasketConfig();
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/GreatSpookConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/GreatSpookConfig.java
new file mode 100644
index 000000000..69eb0ae06
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/GreatSpookConfig.java
@@ -0,0 +1,44 @@
+package at.hannibal2.skyhanni.config.features.event;
+
+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 GreatSpookConfig {
+
+ @Expose
+ @ConfigOption(name = "Primal Fear Timer", desc = "Shows cooldown timer for next primal fear.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean primalFearTimer = false;
+
+ @Expose
+ @ConfigOption(name = "Primal Fear Notify", desc = "Plays a notification sound when the next primal fear can spawn.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean primalFearNotification = false;
+
+ @Expose
+ public Position positionTimer = new Position(20, 20, false, true);
+
+ @Expose
+ @ConfigOption(name = "Fear Stat Display", desc = "Shows your current Fear stat value.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean fearStatDisplay = false;
+
+ @Expose
+ public Position positionFear = new Position(30, 30, false, true);
+
+ @Expose
+ @ConfigOption(name = "IRL Time Left", desc = "Shows the IRL time left before The Great Spook ends.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean greatSpookTimeLeft = false;
+
+ @Expose
+ public Position positionTimeLeft = new Position(40, 40, false, true);
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/HalloweenBasketConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/HalloweenBasketConfig.java
new file mode 100644
index 000000000..5cb2bfef4
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/HalloweenBasketConfig.java
@@ -0,0 +1,25 @@
+package at.hannibal2.skyhanni.config.features.event;
+
+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 HalloweenBasketConfig {
+
+ @Expose
+ @ConfigOption(name = "Basket Waypoints", desc = "Show all Halloween Basket waypoints.\nShoutout to §bTobbbb §7for the coordinates.\n(AS OF 2023)")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean allWaypoints = false;
+
+ @Expose
+ @ConfigOption(name = "Entrance Waypoints", desc = "Show helper waypoints to Baskets #23, #24, and #25. Coordinates by §bErymanthus§7.")
+ @ConfigEditorBoolean
+ public boolean allEntranceWaypoints = false;
+
+ @Expose
+ @ConfigOption(name = "Only Closest", desc = "Only show the closest waypoint")
+ @ConfigEditorBoolean
+ public boolean onlyClosest = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/MayorJerryConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/MayorJerryConfig.java
new file mode 100644
index 000000000..b3afe6c1a
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/MayorJerryConfig.java
@@ -0,0 +1,16 @@
+package at.hannibal2.skyhanni.config.features.event;
+
+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 MayorJerryConfig {
+
+ @Expose
+ @ConfigOption(name = "Highlight Jerries", desc = "Highlights Jerries found from the Jerrypocalypse perk. Highlight color is based on color of the Jerry.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlightJerries = true;
+
+}
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
new file mode 100644
index 000000000..44dd23ec4
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoCardConfig.java
@@ -0,0 +1,45 @@
+package at.hannibal2.skyhanni.config.features.event.bingo;
+
+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;
+import io.github.moulberry.moulconfig.observer.Property;
+
+public class BingoCardConfig {
+ @Expose
+ @ConfigOption(name = "Enable", desc = "Displays the Bingo Card.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+ @Expose
+ @ConfigOption(name = "Quick Toggle", desc = "Quickly toggle the Bingo Card or the step helper by sneaking with SkyBlock Menu in hand.")
+ @ConfigEditorBoolean
+ public boolean quickToggle = true;
+
+ @Expose
+ @ConfigOption(name = "Bingo Steps", desc = "Show help with the next step in Bingo instead of the Bingo Card. " +
+ "§cThis feature is in early development. Expect bugs and missing goals.")
+ @ConfigEditorBoolean
+ public boolean stepHelper = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Community Goals", desc = "Hide Community Goals from the Bingo Card display.")
+ @ConfigEditorBoolean
+ public Property<Boolean> hideCommunityGoals = Property.of(false);
+
+ @Expose
+ @ConfigOption(
+ name = "Show Guide",
+ desc = "Show tips and difficulty for bingo goals inside the Bingo Card inventory.\n" +
+ "These tips are made from inspirations and guides from the community,\n" +
+ "aiming to help you to complete the bingo card."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean bingoSplashGuide = true;
+
+ @Expose
+ public Position bingoCardPos = new Position(10, 10, false, 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
new file mode 100644
index 000000000..816f8a194
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoConfig.java
@@ -0,0 +1,30 @@
+package at.hannibal2.skyhanni.config.features.event.bingo;
+
+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.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class BingoConfig {
+
+ @Expose
+ @ConfigOption(name = "Bingo Card", desc = "")
+ @Accordion
+ public BingoCardConfig bingoCard = new BingoCardConfig();
+
+ @Expose
+ @ConfigOption(name = "Compact Chat Messages", desc = "")
+ @Accordion
+ public CompactChatConfig compactChat = new CompactChatConfig();
+
+ @Expose
+ @ConfigOption(name = "Minion Craft Helper", desc = "Show how many more items you need to upgrade the minion in your inventory. Especially useful for Bingo.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean minionCraftHelperEnabled = true;
+
+ @Expose
+ public Position minionCraftHelperPos = new Position(10, 10, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/CompactChatConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/CompactChatConfig.java
new file mode 100644
index 000000000..bbf737646
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/CompactChatConfig.java
@@ -0,0 +1,27 @@
+package at.hannibal2.skyhanni.config.features.event.bingo;
+
+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 CompactChatConfig {
+
+ @Expose
+ @ConfigOption(name = "Enable", desc = "Shortens chat messages about skill level ups, collection gains, " +
+ "new area discoveries and SkyBlock level up messages while on Bingo.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Hide Border", desc = "Hide the border messages before and after the compact level up messages.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideBorder = true;
+
+ @Expose
+ @ConfigOption(name = "Outside Bingo", desc = "Compact the level up chat messages outside of an Bingo profile as well.")
+ @ConfigEditorBoolean
+ public boolean outsideBingo = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/diana/DianaConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/diana/DianaConfig.java
new file mode 100644
index 000000000..b5d21bade
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/diana/DianaConfig.java
@@ -0,0 +1,60 @@
+package at.hannibal2.skyhanni.config.features.event.diana;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import org.lwjgl.input.Keyboard;
+
+public class DianaConfig {
+
+ @Expose
+ @ConfigOption(name = "Soopy Guess", desc = "Uses §eSoopy's Guess Logic §7to find the next burrow. Does not require SoopyV2 or ChatTriggers to be installed.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean burrowsSoopyGuess = false;
+
+ @Expose
+ @ConfigOption(name = "Nearby Detection", desc = "Show burrows near you.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean burrowsNearbyDetection = false;
+
+ @Expose
+ @ConfigOption(name = "Smooth Transition", desc = "Show the way from one burrow to another smoothly.")
+ @ConfigEditorBoolean
+ public boolean burrowSmoothTransition = false;
+
+ @Expose
+ @ConfigOption(name = "Nearest Warp", desc = "Warps to the nearest warp point on the hub, if closer to the next burrow.")
+ @ConfigEditorBoolean
+ public boolean burrowNearestWarp = false;
+
+ @Expose
+ @ConfigOption(name = "Warp Key", desc = "Press this key to warp to nearest burrow waypoint.")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
+ public int keyBindWarp = Keyboard.KEY_NONE;
+
+ @Expose
+ @ConfigOption(name = "Ignored Warps", desc = "")
+ @Accordion
+ public IgnoredWarpsConfig ignoredWarps = new IgnoredWarpsConfig();
+
+ @Expose
+ @ConfigOption(name = "Inquisitor Waypoint Sharing", desc = "")
+ @Accordion
+ public InquisitorSharingConfig inquisitorSharing = new InquisitorSharingConfig();
+
+ @Expose
+ @ConfigOption(name = "Griffin Pet Warning", desc = "Warn when holding an Ancestral Spade if a Griffin Pet is not equipped.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean petWarning = true;
+
+ @Expose
+ @ConfigOption(name = "Always Diana", desc = "Forcefully set the Diana event to be active. This is useful if the auto mayor detection fails.")
+ @ConfigEditorBoolean
+ public boolean alwaysDiana = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/diana/IgnoredWarpsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/diana/IgnoredWarpsConfig.java
new file mode 100644
index 000000000..2cef22331
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/diana/IgnoredWarpsConfig.java
@@ -0,0 +1,19 @@
+package at.hannibal2.skyhanni.config.features.event.diana;
+
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class IgnoredWarpsConfig {
+
+ @Expose
+ @ConfigOption(name = "Crypt", desc = "Ignore the Crypt warp point (Because it takes a long time to leave).")
+ @ConfigEditorBoolean
+ public boolean crypt = false;
+
+ @Expose
+ @ConfigOption(name = "Wizard", desc = "Ignore the Wizard Tower warp point (Because it is easy to fall into the rift).")
+ @ConfigEditorBoolean
+ public boolean wizard = false;
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/diana/InquisitorSharingConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/diana/InquisitorSharingConfig.java
new file mode 100644
index 000000000..c719a7101
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/diana/InquisitorSharingConfig.java
@@ -0,0 +1,37 @@
+package at.hannibal2.skyhanni.config.features.event.diana;
+
+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 InquisitorSharingConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Shares your Inquisitor and receiving other Inquisitors via Party Chat.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Focus", desc = "Hide other waypoints when your Party finds an Inquisitor.")
+ @ConfigEditorBoolean
+ public boolean focusInquisitor = false;
+
+ @Expose
+ @ConfigOption(name = "Instant Share", desc = "Share the waypoint as soon as you find an Inquisitor. As an alternative, you can share it only via key press.")
+ @ConfigEditorBoolean
+ public boolean instantShare = true;
+
+ @Expose
+ @ConfigOption(name = "Share Key", desc = "Press this key to share your Inquisitor Waypoint.")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_Y)
+ public int keyBindShare = Keyboard.KEY_Y;
+
+ @Expose
+ @ConfigOption(name = "Show Despawn Time", desc = "Show the time until the shared Inquisitor will despawn.")
+ @ConfigEditorBoolean
+ public boolean showDespawnTime = 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
new file mode 100644
index 000000000..2b41265a6
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/FrozenTreasureConfig.java
@@ -0,0 +1,72 @@
+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.ConfigEditorDraggableList;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class FrozenTreasureConfig {
+
+ @Expose
+ @ConfigOption(
+ name = "Enabled",
+ desc = "Tracks all of your drops from Frozen Treasure in the Glacial Caves.\n" +
+ "§eIce calculations are an estimate but are relatively accurate."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(
+ 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",
+ " ",
+ }
+ )
+ public List<Integer> textFormat = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 14, 15));
+
+ @Expose
+ @ConfigOption(name = "Only in Glacial Cave", desc = "Only shows the overlay while in the Glacial Cave.")
+ @ConfigEditorBoolean
+ public boolean onlyInCave = true;
+
+ @Expose
+ @ConfigOption(name = "Show as Drops", desc = "Multiplies the numbers on the display by the base drop. \n" +
+ "E.g. 3 Ice Bait -> 48 Ice Bait")
+ @ConfigEditorBoolean
+ public boolean showAsDrops = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Chat Messages", desc = "Hides the chat messages from Frozen Treasures.")
+ @ConfigEditorBoolean
+ public boolean hideMessages = false;
+
+ @Expose
+ public Position position = new Position(10, 80, 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
new file mode 100644
index 000000000..8af9472b1
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/WinterConfig.java
@@ -0,0 +1,26 @@
+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.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class WinterConfig {
+
+ @Expose
+ @ConfigOption(name = "Frozen Treasure Tracker", desc = "")
+ @Accordion
+ public FrozenTreasureConfig frozenTreasureTracker = new FrozenTreasureConfig();
+
+ @Expose
+ @ConfigOption(name = "Island Close Time", desc = "While on the Winter Island, show a timer until Jerry's Workshop closes.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean islandCloseTime = true;
+
+ @Expose
+ public Position islandCloseTimePosition = new Position(10, 10, false, true);
+
+}
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
new file mode 100644
index 000000000..eb0577135
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/BarnTimerConfig.java
@@ -0,0 +1,62 @@
+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.ConfigEditorKeybind;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import org.lwjgl.input.Keyboard;
+
+public class BarnTimerConfig {
+ @Expose
+ @ConfigOption(
+ name = "Barn Fishing Timer",
+ desc = "Show the time and amount of sea creatures while fishing on the barn via hub."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Worm Fishing",
+ desc = "Show the Barn Fishing Timer even for worms or other sea creatures in the Crystal Hollows."
+ )
+ @ConfigEditorBoolean
+ public boolean crystalHollows = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Stranded Fishing",
+ desc = "Show the Barn Fishing Timer even on all the different islands Stranded players can visit."
+ )
+ @ConfigEditorBoolean
+ public boolean forStranded = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Worm Cap Alert",
+ desc = "Alerts you with title and sound if you hit the Worm Sea Creature limit of 60."
+ )
+ @ConfigEditorBoolean
+ public boolean wormLimitAlert = true;
+
+ @Expose
+ @ConfigOption(name = "Reset Timer Hotkey", desc = "Press this key to reset the timer manualy")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
+ public int manualResetTimer = Keyboard.KEY_NONE;
+
+ @Expose
+ @ConfigOption(name = "Fishing Timer Alert", desc = "Change the amount of time in seconds until the timer dings.")
+ @ConfigEditorSlider(
+ minValue = 240,
+ maxValue = 360,
+ minStep = 10
+ )
+ public int alertTime = 330;
+
+ @Expose
+ public Position pos = new Position(10, 10, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/ChumBucketHiderConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/ChumBucketHiderConfig.java
new file mode 100644
index 000000000..aaf8a891e
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/ChumBucketHiderConfig.java
@@ -0,0 +1,26 @@
+package at.hannibal2.skyhanni.config.features.fishing;
+
+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;
+import io.github.moulberry.moulconfig.observer.Property;
+
+public class ChumBucketHiderConfig {
+
+ @Expose
+ @ConfigOption(name = "Enable", desc = "Hide the Chum/Chumcap Bucket name tags for other players.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public Property<Boolean> enabled = Property.of(true);
+
+ @Expose
+ @ConfigOption(name = "Hide Bucket", desc = "Hide the Chum/Chumcap Bucket.")
+ @ConfigEditorBoolean
+ public Property<Boolean> hideBucket = Property.of(false);
+
+ @Expose
+ @ConfigOption(name = "Hide Own", desc = "Hides your own Chum/Chumcap Bucket.")
+ @ConfigEditorBoolean
+ public Property<Boolean> hideOwn = Property.of(false);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishedItemNameConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishedItemNameConfig.java
new file mode 100644
index 000000000..51c37e5ea
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishedItemNameConfig.java
@@ -0,0 +1,21 @@
+package at.hannibal2.skyhanni.config.features.fishing;
+
+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 FishedItemNameConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Show the fished item name above the item when fishing.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Show Bait", desc = "Also show the name of the consumed bait.")
+ @ConfigEditorBoolean
+ public boolean showBaits = false;
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingBaitWarningsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingBaitWarningsConfig.java
new file mode 100644
index 000000000..ae2dd9c9b
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingBaitWarningsConfig.java
@@ -0,0 +1,20 @@
+package at.hannibal2.skyhanni.config.features.fishing;
+
+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 FishingBaitWarningsConfig {
+ @Expose
+ @ConfigOption(name = "Bait Change Warning", desc = "Show warning when fishing bait is changed")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean baitChangeWarning = false;
+
+ @Expose
+ @ConfigOption(name = "No Bait Warning", desc = "Show warning when no bait is used")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean noBaitWarning = false;
+}
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
new file mode 100644
index 000000000..13ef30f84
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingConfig.java
@@ -0,0 +1,76 @@
+package at.hannibal2.skyhanni.config.features.fishing;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.core.config.Position;
+import at.hannibal2.skyhanni.config.features.fishing.trophyfishing.TrophyFishingConfig;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.Category;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class FishingConfig {
+
+ @Expose
+ @Category(name = "Trophy Fishing", desc = "Trophy Fishing Settings")
+ public TrophyFishingConfig trophyFishing = new TrophyFishingConfig();
+
+ @Expose
+ @ConfigOption(name = "Thunder Spark", desc = "")
+ @Accordion
+ public ThunderSparkConfig thunderSpark = new ThunderSparkConfig();
+
+ @Expose
+ @ConfigOption(name = "Barn Fishing Timer", desc = "")
+ @Accordion
+ public BarnTimerConfig barnTimer = new BarnTimerConfig();
+
+ @Expose
+ @ConfigOption(name = "Chum/Chumcap Bucket Hider", desc = "")
+ @Accordion
+ public ChumBucketHiderConfig chumBucketHider = new ChumBucketHiderConfig();
+
+ @Expose
+ @ConfigOption(name = "Fished Item Name", desc = "")
+ @Accordion
+ public FishedItemNameConfig fishedItemName = new FishedItemNameConfig();
+
+ @Expose
+ @ConfigOption(name = "Fishing Hook Display", desc = "")
+ @Accordion
+ public FishingHookDisplayConfig fishingHookDisplay = new FishingHookDisplayConfig();
+
+ @Expose
+ @ConfigOption(name = "Bait Warnings", desc = "")
+ @Accordion
+ public FishingBaitWarningsConfig fishingBaitWarnings = new FishingBaitWarningsConfig();
+
+ @Expose
+ @ConfigOption(name = "Rare Sea Creatures", desc = "")
+ @Accordion
+ public RareCatchesConfig rareCatches = new RareCatchesConfig();
+
+ @Expose
+ @ConfigOption(
+ name = "Shark Fish Counter",
+ desc = "Counts how many Sharks have been caught."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean sharkFishCounter = false;
+
+ @Expose
+ public Position sharkFishCounterPos = new Position(10, 10, false, true);
+
+ @Expose
+ @ConfigOption(name = "Shorten Fishing Message", desc = "Shortens the chat message that says what type of Sea Creature you have fished.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean shortenFishingMessage = false;
+
+ @Expose
+ @ConfigOption(name = "Compact Double Hook", desc = "Adds Double Hook to the Sea Creature chat message instead of in a previous line.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean compactDoubleHook = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingHookDisplayConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingHookDisplayConfig.java
new file mode 100644
index 000000000..e2cfdfa05
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingHookDisplayConfig.java
@@ -0,0 +1,27 @@
+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 FishingHookDisplayConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Display the Hypixel timer until the fishing hook can be pulled out of the water/lava, only bigger and on your screen.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Hide Armor Stand",
+ desc = "Hide the original armor stand from Hypixel when the SkyHanni display is enabled."
+ )
+ @ConfigEditorBoolean
+ public boolean hideArmorStand = true;
+
+ @Expose
+ public Position position = new Position(460, -240, 3.4f);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/RareCatchesConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/RareCatchesConfig.java
new file mode 100644
index 000000000..b89347c65
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/RareCatchesConfig.java
@@ -0,0 +1,32 @@
+package at.hannibal2.skyhanni.config.features.fishing;
+
+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 RareCatchesConfig {
+
+ @Expose
+ @ConfigOption(name = "Alert (Own Sea Creatures)", desc = "Show an alert on screen when you catch a rare sea creature.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean alertOwnCatches = true;
+
+ @Expose
+ @ConfigOption(name = "Alert (Other Sea Creatures)", desc = "Show an alert on screen when other players nearby catch a rare sea creature.")
+ @ConfigEditorBoolean
+ public boolean alertOtherCatches = false;
+
+ @Expose
+ @ConfigOption(name = "Play Sound Alert", desc = "Play a sound effect when rare sea creature alerts are displayed.")
+ @ConfigEditorBoolean
+ public boolean playSound = true;
+
+ @Expose
+ @ConfigOption(name = "Highlight", desc = "Highlight nearby rare sea creatures.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlight = false;
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/ThunderSparkConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/ThunderSparkConfig.java
new file mode 100644
index 000000000..78e75f6c4
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/ThunderSparkConfig.java
@@ -0,0 +1,20 @@
+package at.hannibal2.skyhanni.config.features.fishing;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class ThunderSparkConfig {
+ @Expose
+ @ConfigOption(name = "Thunder Spark Highlight", desc = "Highlight Thunder Sparks after killing a Thunder.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlight = false;
+
+ @Expose
+ @ConfigOption(name = "Thunder Spark Color", desc = "Color of the Thunder Sparks.")
+ @ConfigEditorColour
+ public String color = "0:255:255:255:255";
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/trophyfishing/ChatMessagesConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/trophyfishing/ChatMessagesConfig.java
new file mode 100644
index 000000000..f19fc0d86
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/trophyfishing/ChatMessagesConfig.java
@@ -0,0 +1,56 @@
+package at.hannibal2.skyhanni.config.features.fishing.trophyfishing;
+
+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 ChatMessagesConfig {
+
+ @Expose
+ @ConfigOption(
+ name = "Trophy Counter",
+ desc = "Counts Trophy messages from chat and tells you how many you have found."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Trophy Counter Design",
+ desc = "§fStyle 1: §72. §6§lGOLD §5Moldfin\n" +
+ "§fStyle 2: §bYou caught a §5Moldfin §6§lGOLD§b. §7(2)\n" +
+ "§fStyle 3: §bYou caught your 2nd §6§lGOLD §5Moldfin§b."
+ )
+ @ConfigEditorDropdown(values = {"Style 1", "Style 2", "Style 3"})
+ public int design = 0;
+
+ @Expose
+ @ConfigOption(name = "Show Total Amount", desc = "Show total amount of all rarities at the end of the chat message.")
+ @ConfigEditorBoolean
+ public boolean totalAmount = false;
+
+ @Expose
+ @ConfigOption(name = "Trophy Fish Info", desc = "Show information and stats about a Trophy Fish when hovering over a catch message in chat.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean tooltip = true;
+
+ @Expose
+ @ConfigOption(name = "Hide Repeated Catches", desc = "Delete past catches of the same Trophy Fish from chat.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean duplicateHider = false;
+
+ @Expose
+ @ConfigOption(name = "Bronze Duplicates", desc = "Hide duplicate messages for bronze Trophy Fishes from chat.")
+ @ConfigEditorBoolean
+ public boolean bronzeHider = false;
+
+ @Expose
+ @ConfigOption(name = "Silver Duplicates", desc = "Hide duplicate messages for silver Trophy Fishes from chat.")
+ @ConfigEditorBoolean
+ public boolean silverHider = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/trophyfishing/TrophyFishingConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/trophyfishing/TrophyFishingConfig.java
new file mode 100644
index 000000000..ce774a72f
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/trophyfishing/TrophyFishingConfig.java
@@ -0,0 +1,27 @@
+package at.hannibal2.skyhanni.config.features.fishing.trophyfishing;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class TrophyFishingConfig {
+
+ @Expose
+ @ConfigOption(name = "Trophy Fishing Chat Messages", desc = "")
+ @Accordion
+ public ChatMessagesConfig chatMessages = new ChatMessagesConfig();
+
+ @Expose
+ @ConfigOption(name = "Fillet Tooltip", desc = "Show fillet value of Trophy Fish in tooltip.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean filletTooltip = true;
+
+ @Expose
+ @ConfigOption(name = "Odger Waypoint", desc = "Show the Odger waypoint when Trophy Fishes are in the inventory and no lava rod in hand.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean odgerLocation = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/AnitaShopConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/AnitaShopConfig.java
new file mode 100644
index 000000000..f45f8cbc1
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/AnitaShopConfig.java
@@ -0,0 +1,30 @@
+package at.hannibal2.skyhanni.config.features.garden;
+
+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 AnitaShopConfig {
+ @Expose
+ @ConfigOption(
+ name = "Medal Prices",
+ desc = "Helps to identify profitable items to buy at the Anita item shop " +
+ "and potential profit from selling the item in the Auction House."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean medalProfitEnabled = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Extra Farming Fortune",
+ desc = "Show current tier and cost to max out in the item tooltip.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean extraFarmingFortune = true;
+
+ @Expose
+ public Position medalProfitPos = new Position(206, 158, false, 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
new file mode 100644
index 000000000..33a797bcb
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/CropStartLocationConfig.java
@@ -0,0 +1,16 @@
+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.ConfigOption;
+
+public class CropStartLocationConfig {
+
+ @Expose
+ @ConfigOption(name = "Enable", desc = "Show the start waypoint for your farm with the currently holding tool.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/DicerCounterConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/DicerCounterConfig.java
new file mode 100644
index 000000000..63087dab1
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/DicerCounterConfig.java
@@ -0,0 +1,24 @@
+package at.hannibal2.skyhanni.config.features.garden;
+
+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 DicerCounterConfig {
+ @Expose
+ @ConfigOption(name = "RNG Drop Counter", desc = "Count RNG drops for Melon Dicer and Pumpkin Dicer.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean display = true;
+
+ @Expose
+ @ConfigOption(name = "Hide Chat", desc = "Hide the chat message when dropping a RNG Dicer drop.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideChat = false;
+
+ @Expose
+ public Position pos = new Position(16, -232, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/EliteFarmingWeightConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/EliteFarmingWeightConfig.java
new file mode 100644
index 000000000..caf56c195
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/EliteFarmingWeightConfig.java
@@ -0,0 +1,54 @@
+package at.hannibal2.skyhanni.config.features.garden;
+
+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.ConfigEditorText;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class EliteFarmingWeightConfig {
+ @Expose
+ @ConfigOption(name = "Display", desc = "Display your farming weight on screen. " +
+ "The calculation and API is provided by The Elite SkyBlock farmers. " +
+ "See §ehttps://elitebot.dev/info §7for more info.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean display = true;
+
+ @Expose
+ public Position pos = new Position(180, 10, false, true);
+
+ @Expose
+ @ConfigOption(name = "Leaderboard Ranking", desc = "Show your position in the farming weight leaderboard. " +
+ "Only if your farming weight is high enough! Updates every 10 minutes.")
+ @ConfigEditorBoolean
+ public boolean leaderboard = true;
+
+ @Expose
+ @ConfigOption(name = "Overtake ETA", desc = "Show a timer estimating when you'll move up a spot in the leaderboard! " +
+ "Will show an ETA to rank #10,000 if you're not on the leaderboard yet.")
+ @ConfigEditorBoolean
+ public boolean overtakeETA = false;
+
+ @Expose
+ @ConfigOption(name = "Show LB Change", desc = "Show the change of your position in the farming weight leaderboard while you were offline.")
+ @ConfigEditorBoolean
+ // TODO migrate
+ public boolean offScreenDropMessage = true;
+
+ @Expose
+ @ConfigOption(name = "Always ETA", desc = "Show the Overtake ETA always, even when not farming at the moment.")
+ @ConfigEditorBoolean
+ public boolean overtakeETAAlways = true;
+
+ @Expose
+ @ConfigOption(name = "ETA Goal", desc = "Override the Overtake ETA to show when you'll reach the specified rank (if not there yet). (Default: \"10,000\")")
+ @ConfigEditorText
+ public String ETAGoalRank = "10000";
+
+ @Expose
+ @ConfigOption(name = "Show below 200", desc = "Show the farming weight data even if you are below 200 weight.")
+ @ConfigEditorBoolean
+ public boolean ignoreLow = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/FarmingArmorDropsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/FarmingArmorDropsConfig.java
new file mode 100644
index 000000000..64d04f932
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/FarmingArmorDropsConfig.java
@@ -0,0 +1,24 @@
+package at.hannibal2.skyhanni.config.features.garden;
+
+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 FarmingArmorDropsConfig {
+ @Expose
+ @ConfigOption(name = "Show Counter", desc = "Count all §9Cropie§7, §5Squash §7and §6Fermento §7dropped.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Hide Chat", desc = "Hide the chat message when receiving a farming armor drop.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideChat = false;
+
+ @Expose
+ public Position pos = new Position(16, -232, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/FarmingFortuneConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/FarmingFortuneConfig.java
new file mode 100644
index 000000000..ff5f6c62d
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/FarmingFortuneConfig.java
@@ -0,0 +1,27 @@
+package at.hannibal2.skyhanni.config.features.garden;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.commands.Commands;
+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.ConfigEditorButton;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class FarmingFortuneConfig {
+ @Expose
+ @ConfigOption(
+ name = "FF Display",
+ desc = "Displays the true Farming Fortune for the current crop, including all crop-specific and hidden bonuses."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean display = true;
+
+ @ConfigOption(name = "Farming Fortune Guide", desc = "Opens a guide that breaks down your Farming Fortune.\n§eCommand: /ff")
+ @ConfigEditorButton(buttonText = "Open")
+ public Runnable open = Commands::openFortuneGuide;
+
+ @Expose
+ public Position pos = new Position(5, -180, false, true);
+}
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
new file mode 100644
index 000000000..7553f2f2a
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenConfig.java
@@ -0,0 +1,211 @@
+package at.hannibal2.skyhanni.config.features.garden;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+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.visitor.VisitorConfig;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.Category;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class GardenConfig {
+
+ @Expose
+ @ConfigOption(name = "SkyMart", desc = "")
+ @Accordion
+ public SkyMartConfig skyMart = new SkyMartConfig();
+
+ @Expose
+ @Category(name = "Visitor", desc = "Visitor Settings")
+ public VisitorConfig visitors = new VisitorConfig();
+
+ @Expose
+ @ConfigOption(name = "Numbers", desc = "")
+ @Accordion
+ public NumbersConfig number = new NumbersConfig();
+
+ @Expose
+ @Category(name = "Crop Milestones", desc = "Crop Milestones Settings")
+ public CropMilestonesConfig cropMilestones = new CropMilestonesConfig();
+
+ // TODO moulconfig runnable support
+ @Expose
+ @ConfigOption(name = "Custom Keybinds", desc = "")
+ @Accordion
+ public KeyBindConfig keyBind = new KeyBindConfig();
+
+ @Expose
+ @Category(name = "Optimal Speed", desc = "Optimal Speed Settings")
+ public OptimalSpeedConfig optimalSpeeds = new OptimalSpeedConfig();
+
+ @Expose
+ @ConfigOption(name = "Garden Level", desc = "")
+ @Accordion
+ public GardenLevelConfig gardenLevels = new GardenLevelConfig();
+
+ @Expose
+ @ConfigOption(name = "Farming Weight", desc = "")
+ @Accordion
+ public EliteFarmingWeightConfig eliteFarmingWeights = new EliteFarmingWeightConfig();
+
+ @Expose
+ @ConfigOption(name = "Dicer Counter", desc = "")
+ @Accordion
+ public DicerCounterConfig dicerCounters = new DicerCounterConfig();
+
+ @Expose
+ @ConfigOption(name = "Money per Hour", desc = "")
+ @Accordion
+ public MoneyPerHourConfig moneyPerHours = new MoneyPerHourConfig();
+
+ @Expose
+ @ConfigOption(name = "Next Jacob's Contest", desc = "")
+ @Accordion
+ public NextJacobContestConfig nextJacobContests = new NextJacobContestConfig();
+
+ @Expose
+ @ConfigOption(name = "Farming Armor Drops", desc = "")
+
+ @Accordion
+ public FarmingArmorDropsConfig farmingArmorDrop = new FarmingArmorDropsConfig();
+
+ @Expose
+ @ConfigOption(name = "Anita Shop", desc = "")
+ @Accordion
+ public AnitaShopConfig anitaShop = new AnitaShopConfig();
+
+ @Expose
+ @Category(name = "Composter", desc = "Composter Settings")
+ public ComposterConfig composters = new ComposterConfig();
+
+ @Expose
+ @ConfigOption(name = "Farming Fortune Display", desc = "")
+ @Accordion
+ public FarmingFortuneConfig farmingFortunes = new FarmingFortuneConfig();
+
+ @Expose
+ @ConfigOption(name = "Tooltip Tweaks", desc = "")
+ @Accordion
+ public TooltipTweaksConfig tooltipTweak = new TooltipTweaksConfig();
+
+ @Expose
+ @ConfigOption(name = "Yaw and Pitch", desc = "")
+ @Accordion
+ public YawPitchDisplayConfig yawPitchDisplay = new YawPitchDisplayConfig();
+
+ @Expose
+ @ConfigOption(name = "Crop Start Location", desc = "")
+ @Accordion
+ public CropStartLocationConfig cropStartLocation = new CropStartLocationConfig();
+
+ @Expose
+ @ConfigOption(name = "Garden Plot Icon", desc = "")
+ @Accordion
+ public PlotIconConfig plotIcon = new PlotIconConfig();
+
+ @Expose
+ @ConfigOption(name = "Plot Price", desc = "Show the price of the plot in coins when inside the Configure Plots inventory.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean plotPrice = true;
+
+ @Expose
+ @ConfigOption(name = "Desk in Menu", desc = "Show a Desk button in the SkyBlock Menu. Opens the /desk command on click.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean deskInSkyBlockMenu = true;
+
+ @Expose
+ @ConfigOption(name = "Fungi Cutter Warning", desc = "Warn when breaking mushroom with the wrong Fungi Cutter mode.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean fungiCutterWarn = true;
+
+ @Expose
+ @ConfigOption(name = "Burrowing Spores", desc = "Show a notification when a Burrowing Spores spawns while farming mushrooms.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean burrowingSporesNotification = true;
+
+ @Expose
+ @ConfigOption(name = "Wild Strawberry", desc = "Show a notification when a Wild Strawberry Dye drops while farming.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean wildStrawberryDyeNotification = true;
+
+ @Expose
+ @ConfigOption(
+ name = "FF for Contest",
+ desc = "Show the minimum needed Farming Fortune for reaching each medal in Jacob's Farming Contest inventory."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean farmingFortuneForContest = true;
+
+ @Expose
+ public Position farmingFortuneForContestPos = new Position(180, 156, false, true);
+
+ @Expose
+ @ConfigOption(
+ name = "Contest Time Needed",
+ desc = "Show the time and missing FF for every crop inside Jacob's Farming Contest inventory."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean jacobContextTimes = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Custom BPS",
+ desc = "Use custom Blocks per Second value in some GUIs instead of the real one."
+ )
+ @ConfigEditorBoolean
+ public boolean jacobContestCustomBps = true;
+
+ // TODO moulconfig runnable support
+ @Expose
+ @ConfigOption(name = "Custom BPS Value", desc = "Set a custom Blocks per Second value.")
+ @ConfigEditorSlider(
+ minValue = 15,
+ maxValue = 20,
+ minStep = 0.1f
+ )
+ public double jacobContestCustomBpsValue = 19.9;
+
+ @Expose
+ public Position jacobContextTimesPos = new Position(-359, 149, false, true);
+
+ @Expose
+ @ConfigOption(
+ name = "Contest Summary",
+ desc = "Show the average Blocks Per Second and blocks clicked at the end of a Jacob Farming Contest in chat."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean jacobContestSummary = true;
+
+ @Expose
+ @ConfigOption(name = "Always Finnegan", desc = "Forcefully set the Finnegan Farming Simulator perk to be active. This is useful if the auto mayor detection fails.")
+ @ConfigEditorBoolean
+ public boolean forcefullyEnabledAlwaysFinnegan = false;
+
+ @Expose
+ public Position cropSpeedMeterPos = new Position(278, -236, false, true);
+
+ @Expose
+ @ConfigOption(name = "Enable Plot Borders", desc = "Enable the use of F3 + G hotkey to show Garden plot borders. Similar to how later Minecraft version render chunk borders.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean plotBorders = 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
+ public boolean copyMilestoneData = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenLevelConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenLevelConfig.java
new file mode 100644
index 000000000..07f330dcd
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenLevelConfig.java
@@ -0,0 +1,18 @@
+package at.hannibal2.skyhanni.config.features.garden;
+
+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 GardenLevelConfig {
+ @Expose
+ @ConfigOption(name = "Display", desc = "Show the current Garden level and progress to the next level.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean display = true;
+
+ @Expose
+ public Position pos = new Position(390, 40, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/KeyBindConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/KeyBindConfig.java
new file mode 100644
index 000000000..c016cac7c
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/KeyBindConfig.java
@@ -0,0 +1,87 @@
+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.ConfigEditorButton;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import net.minecraft.client.Minecraft;
+import org.lwjgl.input.Keyboard;
+
+public class KeyBindConfig {
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Use custom keybinds while holding a farming tool or Daedalus Axe in the hand.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @ConfigOption(name = "Disable All", desc = "Disable all keys.")
+ @ConfigEditorButton(buttonText = "Disable")
+ public Runnable presetDisable = () -> {
+ attack = Keyboard.KEY_NONE;
+ useItem = Keyboard.KEY_NONE;
+ left = Keyboard.KEY_NONE;
+ right = Keyboard.KEY_NONE;
+ forward = Keyboard.KEY_NONE;
+ back = Keyboard.KEY_NONE;
+ jump = Keyboard.KEY_NONE;
+ sneak = Keyboard.KEY_NONE;
+
+ Minecraft.getMinecraft().thePlayer.closeScreen();
+ };
+
+ @ConfigOption(name = "Set Default", desc = "Reset all keys to default.")
+ @ConfigEditorButton(buttonText = "Default")
+ public Runnable presetDefault = () -> {
+ attack = -100;
+ useItem = -99;
+ left = Keyboard.KEY_A;
+ right = Keyboard.KEY_D;
+ forward = Keyboard.KEY_W;
+ back = Keyboard.KEY_S;
+ jump = Keyboard.KEY_SPACE;
+ sneak = Keyboard.KEY_LSHIFT;
+ Minecraft.getMinecraft().thePlayer.closeScreen();
+ };
+
+ @Expose
+ @ConfigOption(name = "Attack", desc = "")
+ @ConfigEditorKeybind(defaultKey = -100)
+ public int attack = -100;
+
+ @Expose
+ @ConfigOption(name = "Use Item", desc = "")
+ @ConfigEditorKeybind(defaultKey = -99)
+ public int useItem = -99;
+
+ @Expose
+ @ConfigOption(name = "Move Left", desc = "")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_A)
+ public int left = Keyboard.KEY_A;
+
+ @Expose
+ @ConfigOption(name = "Move Right", desc = "")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_D)
+ public int right = Keyboard.KEY_D;
+
+ @Expose
+ @ConfigOption(name = "Move Forward", desc = "")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_W)
+ public int forward = Keyboard.KEY_W;
+
+ @Expose
+ @ConfigOption(name = "Move Back", desc = "")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_S)
+ public int back = Keyboard.KEY_S;
+
+ @Expose
+ @ConfigOption(name = "Jump", desc = "")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_SPACE)
+ public int jump = Keyboard.KEY_SPACE;
+
+ @Expose
+ @ConfigOption(name = "Sneak", desc = "")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_LSHIFT)
+ public int sneak = Keyboard.KEY_LSHIFT;
+}
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
new file mode 100644
index 000000000..5606e5e3d
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/MoneyPerHourConfig.java
@@ -0,0 +1,126 @@
+package at.hannibal2.skyhanni.config.features.garden;
+
+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.ConfigEditorDraggableList;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class MoneyPerHourConfig {
+ @Expose
+ @ConfigOption(name = "Show Money per Hour",
+ desc = "Displays the money per hour YOU get with YOUR crop/minute value when selling the item to bazaar. " +
+ "Supports Bountiful, Mushroom Cow Perk, Armor Crops and Dicer Drops. Their toggles are below.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean display = true;
+
+ // TODO moulconfig runnable support
+ @Expose
+ @ConfigOption(name = "Only Show Top", desc = "Only show the best # items.")
+ @ConfigEditorSlider(
+ minValue = 1,
+ maxValue = 25,
+ minStep = 1
+ )
+ public int showOnlyBest = 5;
+
+ @Expose
+ @ConfigOption(name = "Extend Top List", desc = "Add current crop to the list if its lower ranked than the set limit by extending the list.")
+ @ConfigEditorBoolean
+ public boolean showCurrent = true;
+
+ // TODO moulconfig runnable support
+ @Expose
+ @ConfigOption(
+ name = "Always On",
+ desc = "Always show the money/hour Display while on the garden.")
+ @ConfigEditorBoolean
+ public boolean alwaysOn = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Compact Mode",
+ desc = "Hide the item name and the position number.")
+ @ConfigEditorBoolean
+ public boolean compact = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Compact Price",
+ desc = "Show the price more compact.")
+ @ConfigEditorBoolean
+ public boolean compactPrice = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Use Custom",
+ desc = "Use the custom format below instead of classic ➜ §eSell Offer §7and other profiles ➜ §eNPC Price.")
+ @ConfigEditorBoolean
+ public boolean useCustomFormat = false;
+
+ @Expose
+ @ConfigOption(
+ 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));
+
+ @Expose
+ @ConfigOption(
+ name = "Merge Seeds",
+ desc = "Merge the seeds price with the wheat price.")
+ @ConfigEditorBoolean
+ public boolean mergeSeeds = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Include Bountiful",
+ desc = "Includes the coins from Bountiful in the calculation.")
+ @ConfigEditorBoolean
+ public boolean bountiful = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Include Mooshroom Cow",
+ desc = "Includes the coins you get from selling the mushrooms from your Mooshroom Cow pet.")
+ @ConfigEditorBoolean
+ public boolean mooshroom = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Include Armor Drops",
+ desc = "Includes the average coins/hr from your armor.")
+ @ConfigEditorBoolean
+ public boolean armor = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Include Dicer Drops",
+ desc = "Includes the average coins/hr from your melon or pumpkin dicer.")
+ @ConfigEditorBoolean
+ public boolean dicer = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Hide Title",
+ desc = "Hides the first line of 'Money Per Hour' entirely.")
+ @ConfigEditorBoolean
+ public boolean hideTitle = false;
+
+ @Expose
+ public Position pos = new Position(-330, 170, false, true);
+}
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
new file mode 100644
index 000000000..f9b0f80e4
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/NextJacobContestConfig.java
@@ -0,0 +1,59 @@
+package at.hannibal2.skyhanni.config.features.garden;
+
+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;
+
+public class NextJacobContestConfig {
+ @Expose
+ @ConfigOption(name = "Show Jacob's Contest", desc = "Show the current or next Jacob's farming contest time and crops.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean display = true;
+
+ @Expose
+ @ConfigOption(name = "Outside Garden", desc = "Show the timer not only in Garden but everywhere in SkyBlock.")
+ @ConfigEditorBoolean
+ public boolean everywhere = false;
+
+ @Expose
+ @ConfigOption(name = "In Other Guis", desc = "Mark the current or next Farming Contest crops in other farming GUIs as underlined.")
+ @ConfigEditorBoolean
+ public boolean otherGuis = false;
+
+ @Expose
+ @ConfigOption(name = "Fetch Contests", desc = "Automatically fetch Contests from elitebot.dev for the current year if they're uploaded already.")
+ @ConfigEditorBoolean
+ public boolean fetchAutomatically = true;
+
+ @Expose
+ @ConfigOption(name = "Share Contests", desc = "Share the list of upcoming Contests to elitebot.dev for everyone else to then fetch automatically.")
+ @ConfigEditorDropdown(values = {"Ask When Needed", "Share Automatically", "Disabled"})
+ public int shareAutomatically = 0;
+
+ @Expose
+ @ConfigOption(name = "Warning", desc = "Show a warning shortly before a new Jacob's Contest starts.")
+ @ConfigEditorBoolean
+ public boolean warn = false;
+
+ @Expose
+ @ConfigOption(name = "Warning Time", desc = "Set the warning time in seconds before a Jacob's Contest begins.")
+ @ConfigEditorSlider(
+ minValue = 10,
+ maxValue = 60 * 5,
+ minStep = 1
+ )
+ public int warnTime = 60 * 2;
+
+ @Expose
+ @ConfigOption(name = "Popup Warning", desc = "Opens a popup when the warning time is reached and Minecraft is not in focus.")
+ @ConfigEditorBoolean
+ public boolean warnPopup = false;
+
+ @Expose
+ public Position pos = new Position(-200, 10, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/NumbersConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/NumbersConfig.java
new file mode 100644
index 000000000..106af45c8
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/NumbersConfig.java
@@ -0,0 +1,32 @@
+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.ConfigOption;
+
+public class NumbersConfig {
+ @Expose
+ @ConfigOption(name = "Crop Milestone", desc = "Show the number of crop milestones in the inventory.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean cropMilestone = true;
+
+ @Expose
+ @ConfigOption(name = "Average Milestone", desc = "Show the average crop milestone in the crop milestone inventory.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean averageCropMilestone = true;
+
+ @Expose
+ @ConfigOption(name = "Crop Upgrades", desc = "Show the number of upgrades in the crop upgrades inventory.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean cropUpgrades = true;
+
+ @Expose
+ @ConfigOption(name = "Composter Upgrades", desc = "Show the number of upgrades in the Composter upgrades inventory.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean composterUpgrades = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/PlotIconConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/PlotIconConfig.java
new file mode 100644
index 000000000..cb47862a2
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/PlotIconConfig.java
@@ -0,0 +1,24 @@
+package at.hannibal2.skyhanni.config.features.garden;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.features.garden.inventory.GardenPlotIcon;
+import at.hannibal2.skyhanni.utils.LorenzUtils;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorButton;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class PlotIconConfig {
+ @Expose
+ @ConfigOption(name = "Enable", desc = "Enable icon replacement in the Configure Plots menu.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @ConfigOption(name = "Hard Reset", desc = "Reset every slot to its original item.")
+ @ConfigEditorButton(buttonText = "Reset")
+ public Runnable hardReset = () -> {
+ GardenPlotIcon.INSTANCE.setHardReset(true);
+ LorenzUtils.INSTANCE.sendCommandToServer("desk");
+ };
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/SkyMartConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/SkyMartConfig.java
new file mode 100644
index 000000000..65eeea93e
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/SkyMartConfig.java
@@ -0,0 +1,29 @@
+package at.hannibal2.skyhanni.config.features.garden;
+
+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.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class SkyMartConfig {
+ @Expose
+ @ConfigOption(name = "Copper Price", desc = "Show copper to coin prices inside the SkyMart inventory.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean copperPrice = true;
+
+ @Expose
+ @ConfigOption(name = "Advanced Stats", desc = "Show the BIN price and copper price for every item.")
+ @ConfigEditorBoolean
+ public boolean copperPriceAdvancedStats = false;
+
+ @Expose
+ @ConfigOption(name = "Item Scale", desc = "Change the size of the items.")
+ @ConfigEditorSlider(minValue = 0.3f, maxValue = 5, minStep = 0.1f)
+ public double itemScale = 1.7;
+
+ @Expose
+ public Position copperPricePos = new Position(211, 132, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/TooltipTweaksConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/TooltipTweaksConfig.java
new file mode 100644
index 000000000..560fcaaa7
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/TooltipTweaksConfig.java
@@ -0,0 +1,47 @@
+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.ConfigEditorDropdown;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import org.lwjgl.input.Keyboard;
+
+public class TooltipTweaksConfig {
+ @Expose
+ @ConfigOption(
+ name = "Compact Descriptions",
+ desc = "Hides redundant parts of reforge descriptions, generic counter description, and Farmhand perk explanation."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean compactToolTooltips = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Breakdown Hotkey",
+ desc = "When the keybind is pressed, show a breakdown of all fortune sources on a tool."
+ )
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_LSHIFT)
+ public int fortuneTooltipKeybind = Keyboard.KEY_LSHIFT;
+
+ @Expose
+ @ConfigOption(
+ name = "Tooltip Format",
+ desc = "Show crop-specific Farming Fortune in tooltip.\n" +
+ "§fShow: §7Crop-specific Fortune indicated as §6[+196]\n" +
+ "§fReplace: §7Edits the total Fortune to include crop-specific Fortune."
+ )
+ @ConfigEditorDropdown(values = {"Default", "Show", "Replace"})
+ public int cropTooltipFortune = 1;
+
+ @Expose
+ @ConfigOption(
+ name = "Total Crop Milestone",
+ desc = "Shows the progress bar till maxed crop milestone in the crop milestone inventory."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean cropMilestoneTotalProgress = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/YawPitchDisplayConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/YawPitchDisplayConfig.java
new file mode 100644
index 000000000..dd7997fba
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/YawPitchDisplayConfig.java
@@ -0,0 +1,64 @@
+package at.hannibal2.skyhanni.config.features.garden;
+
+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.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class YawPitchDisplayConfig {
+
+ @Expose
+ @ConfigOption(name = "Enable", desc = "Displays yaw and pitch while holding a farming tool. Automatically fades out if there is no movement.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Yaw Precision", desc = "Yaw precision up to specified decimal.")
+ @ConfigEditorSlider(
+ minValue = 1,
+ maxValue = 10,
+ minStep = 1
+ )
+ public int yawPrecision = 4;
+
+ @Expose
+ @ConfigOption(name = "Pitch Precision", desc = "Pitch precision up to specified decimal.")
+ @ConfigEditorSlider(
+ minValue = 1,
+ maxValue = 10,
+ minStep = 1
+ )
+ public int pitchPrecision = 4;
+
+ @Expose
+ @ConfigOption(name = "Display Timeout", desc = "Duration in seconds for which the overlay is being displayed after moving.")
+ @ConfigEditorSlider(
+ minValue = 1,
+ maxValue = 20,
+ minStep = 1
+ )
+ public int timeout = 5;
+
+ @Expose
+ @ConfigOption(name = "Show Without Tool", desc = "Does not require you to hold a tool for the overlay to show.")
+ @ConfigEditorBoolean
+ public boolean showWithoutTool = false;
+
+ @Expose
+ @ConfigOption(name = "Show Outside Garden", desc = "The overlay will work outside of the Garden.")
+ @ConfigEditorBoolean
+ public boolean showEverywhere = false;
+
+ @Expose
+ @ConfigOption(name = "Ignore Timeout", desc = "Ignore the timeout after not moving mouse.")
+ @ConfigEditorBoolean
+ public boolean showAlways = false;
+
+ @Expose
+ public Position pos = new Position(445, 225, false, true);
+ @Expose
+ public Position posOutside = new Position(445, 225, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/composter/ComposterConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/composter/ComposterConfig.java
new file mode 100644
index 000000000..700c4fc49
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/composter/ComposterConfig.java
@@ -0,0 +1,108 @@
+package at.hannibal2.skyhanni.config.features.garden.composter;
+
+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.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class ComposterConfig {
+ @Expose
+ @ConfigOption(
+ name = "Composter Overlay",
+ desc = "Show organic matter, fuel, and profit prices while inside the Composter Inventory."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean overlay = true;
+
+ @Expose
+ @ConfigOption(name = "Overlay Price", desc = "Toggle for Bazaar 'buy order' vs 'instant buy' price in composter overlay.")
+ @ConfigEditorDropdown(values = {"Instant Buy", "Buy Order"})
+ public int overlayPriceType = 0;
+
+ @Expose
+ @ConfigOption(name = "Retrieve From", desc = "Change where to retrieve the materials from in the composter overlay: The Bazaar or Sacks.")
+ @ConfigEditorDropdown(values = {"Bazaar", "Sacks"})
+ public int retrieveFrom = 0;
+
+ @Expose
+ public Position overlayOrganicMatterPos = new Position(140, 152, false, true);
+
+ @Expose
+ public Position overlayFuelExtrasPos = new Position(-320, 152, false, true);
+
+ @Expose
+ @ConfigOption(
+ name = "Display Element",
+ desc = "Displays the Compost data from the tab list as GUI element."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean displayEnabled = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Outside Garden",
+ desc = "Show Time till Composter is empty outside Garden"
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean displayOutsideGarden = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Composter Warning",
+ desc = "Warn when the Composter gets close to empty, even outside Garden."
+ )
+ @ConfigEditorBoolean
+ public boolean warnAlmostClose = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Upgrade Price",
+ desc = "Show the price for the Composter Upgrade in the lore."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean upgradePrice = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Round Amount Needed",
+ desc = "Rounds the amount needed to fill your Composter down so that you don't overspend."
+ )
+ @ConfigEditorBoolean
+ public boolean roundDown = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Highlight Upgrade",
+ desc = "Highlight Upgrades that can be bought right now."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlightUpgrade = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Inventory Numbers",
+ desc = "Show the amount of Organic Matter, Fuel and Composts Available while inside the Composter Inventory."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean inventoryNumbers = true;
+
+ @Expose
+ @ConfigOption(name = "Notification When Low Composter", desc = "")
+ @Accordion
+ public NotifyLowConfig notifyLow = new NotifyLowConfig();
+
+ @Expose
+ public Position displayPos = new Position(-390, 10, false, true);
+
+ @Expose
+ public Position outsideGardenPos = new Position(-363, 13, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/composter/NotifyLowConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/composter/NotifyLowConfig.java
new file mode 100644
index 000000000..a854fa6a9
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/composter/NotifyLowConfig.java
@@ -0,0 +1,38 @@
+package at.hannibal2.skyhanni.config.features.garden.composter;
+
+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.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class NotifyLowConfig {
+ @Expose
+ @ConfigOption(name = "Enable", desc = "Show a notification when Organic Matter or Fuel runs low in your Composter.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Show Title", desc = "Send a title to notify.")
+ @ConfigEditorBoolean
+ public boolean title = false;
+
+ @Expose
+ @ConfigOption(name = "Min Organic Matter", desc = "Warn when Organic Matter is below this value.")
+ @ConfigEditorSlider(
+ minValue = 1_000,
+ maxValue = 80_000,
+ minStep = 1
+ )
+ public int organicMatter = 20_000;
+
+ @Expose
+ @ConfigOption(name = "Min Fuel Cap", desc = "Warn when Fuel is below this value.")
+ @ConfigEditorSlider(
+ minValue = 500,
+ maxValue = 40_000,
+ minStep = 1
+ )
+ public int fuel = 10_000;
+}
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
new file mode 100644
index 000000000..053ffe900
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/CropMilestonesConfig.java
@@ -0,0 +1,101 @@
+package at.hannibal2.skyhanni.config.features.garden.cropmilestones;
+
+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.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorDraggableList;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import io.github.moulberry.moulconfig.observer.Property;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class CropMilestonesConfig {
+ @Expose
+ @ConfigOption(
+ name = "Progress Display",
+ desc = "Shows the progress and ETA until the next crop milestone is reached and the current crops/minute value. " +
+ "§eRequires a tool with either a counter or Cultivating enchantment for full accuracy."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean progress = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Warn When Close",
+ desc = "Warn with title and sound when the next crop milestone upgrade happens in 5 seconds. " +
+ "Useful for switching to a different pet for leveling.")
+ @ConfigEditorBoolean
+ public boolean warnClose = false;
+
+ @Expose
+ @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);
+
+ @Expose
+ @ConfigOption(
+ name = "Maxed Milestone",
+ desc = "Calculate the progress and ETA till maxed milestone (46) instead of next milestone.")
+ @ConfigEditorBoolean
+ public Property<Boolean> bestShowMaxedNeeded = Property.of(false);
+
+ @Expose
+ @ConfigOption(
+ name = "Milestone Text",
+ 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%",
+ }
+ )
+ public List<Integer> text = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5));
+
+ @Expose
+ @ConfigOption(name = "Block Broken Precision", desc = "The amount of decimals displayed in blocks/second.")
+ @ConfigEditorSlider(
+ minValue = 0,
+ maxValue = 6,
+ minStep = 1
+ )
+ public int blocksBrokenPrecision = 2;
+
+ @Expose
+ @ConfigOption(name = "Seconds Before Reset", desc = "How many seconds of not farming until blocks/second resets.")
+ @ConfigEditorSlider(
+ minValue = 2,
+ maxValue = 60,
+ minStep = 1
+ )
+ public int blocksBrokenResetTime = 5;
+
+ @Expose
+ public Position progressDisplayPos = new Position(-400, -200, false, true);
+
+ @Expose
+ @ConfigOption(name = "Best Crop", desc = "")
+ @Accordion
+ public NextConfig next = new NextConfig();
+
+ @Expose
+ @ConfigOption(name = "Mushroom Pet Perk", desc = "")
+ @Accordion
+ public MushroomPetPerkConfig mushroomPetPerk = new MushroomPetPerkConfig();
+
+}
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
new file mode 100644
index 000000000..66ef83a4c
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/MushroomPetPerkConfig.java
@@ -0,0 +1,43 @@
+package at.hannibal2.skyhanni.config.features.garden.cropmilestones;
+
+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.ConfigEditorDraggableList;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+// TODO moulconfig runnable support
+public class MushroomPetPerkConfig {
+ @Expose
+ @ConfigOption(
+ name = "Display Enabled",
+ desc = "Show the progress and ETA for mushroom crops when farming other crops because of the Mooshroom Cow perk.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Mushroom Text",
+ 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%",
+ }
+ )
+ public List<Integer> text = new ArrayList<>(Arrays.asList(0, 1, 2, 3));
+
+ @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
new file mode 100644
index 000000000..6dcd047a9
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/NextConfig.java
@@ -0,0 +1,66 @@
+package at.hannibal2.skyhanni.config.features.garden.cropmilestones;
+
+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;
+
+// TODO moulconfig runnable support
+public class NextConfig {
+ @Expose
+ @ConfigOption(
+ name = "Best Display",
+ desc = "Lists all crops and their ETA till next milestone. Sorts for best crop for getting garden or SkyBlock levels.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean bestDisplay = true;
+
+ // TODO moulconfig runnable support
+ @Expose
+ @ConfigOption(name = "Sort Type", desc = "Sort the crops by either garden or SkyBlock EXP.")
+ @ConfigEditorDropdown(values = {"Garden Exp", "SkyBlock Exp"})
+ public int bestType = 0;
+
+ // TODO moulconfig runnable support
+ @Expose
+ @ConfigOption(name = "Only Show Top", desc = "Only show the top # crops.")
+ @ConfigEditorSlider(
+ minValue = 1,
+ maxValue = 10,
+ minStep = 1
+ )
+ public int showOnlyBest = 10;
+
+ @Expose
+ @ConfigOption(name = "Extend Top List", desc = "Add current crop to the list if its lower ranked than the set limit by extending the list.")
+ @ConfigEditorBoolean
+ public boolean showCurrent = true;
+
+ // TODO moulconfig runnable support
+ @Expose
+ @ConfigOption(
+ name = "Always On",
+ desc = "Show the Best Display always while on the garden.")
+ @ConfigEditorBoolean
+ public boolean bestAlwaysOn = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Compact Display",
+ desc = "A more compact best crop time: Removing the crop name and exp, hide the # number and using a more compact time format.")
+ @ConfigEditorBoolean
+ public boolean bestCompact = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Hide Title",
+ desc = "Hides the 'Best Crop Time' line entirely.")
+ @ConfigEditorBoolean
+ public boolean bestHideTitle = false;
+
+ @Expose
+ public Position displayPos = new Position(-200, -200, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/optimalspeed/CustomSpeedConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/optimalspeed/CustomSpeedConfig.java
new file mode 100644
index 000000000..615883c96
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/optimalspeed/CustomSpeedConfig.java
@@ -0,0 +1,79 @@
+package at.hannibal2.skyhanni.config.features.garden.optimalspeed;
+
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class CustomSpeedConfig {
+
+ @Expose
+ @ConfigOption(name = "Wheat", desc = "Suggested farm speed:\n" +
+ "§e5 Blocks§7: §f✦ 93 speed\n" +
+ "§e4 Blocks§7: §f✦ 116 speed")
+ @ConfigEditorSlider(minValue = 1, maxValue = 400, minStep = 1)
+ public int wheat = 93;
+
+ @Expose
+ @ConfigOption(name = "Carrot", desc = "Suggested farm speed:\n" +
+ "§e5 Blocks§7: §f✦ 93 speed\n" +
+ "§e4 Blocks§7: §f✦ 116 speed")
+ @ConfigEditorSlider(minValue = 1, maxValue = 400, minStep = 1)
+ public int carrot = 93;
+
+ @Expose
+ @ConfigOption(name = "Potato", desc = "Suggested farm speed:\n" +
+ "§e5 Blocks§7: §f✦ 93 speed\n" +
+ "§e4 Blocks§7: §f✦ 116 speed")
+ @ConfigEditorSlider(minValue = 1, maxValue = 400, minStep = 1)
+ public int potato = 93;
+
+ @Expose
+ @ConfigOption(name = "Nether Wart", desc = "Suggested farm speed:\n" +
+ "§e5 Blocks§7: §f✦ 93 speed\n" +
+ "§e4 Blocks§7: §f✦ 116 speed")
+ @ConfigEditorSlider(minValue = 1, maxValue = 400, minStep = 1)
+ public int netherWart = 93;
+
+ @Expose
+ @ConfigOption(name = "Pumpkin", desc = "Suggested farm speed:\n" +
+ "§e3 Blocks§7: §f✦ 155 speed\n" +
+ "§e2 Blocks§7: §f✦ 265 §7or §f400 speed")
+ @ConfigEditorSlider(minValue = 1, maxValue = 400, minStep = 1)
+ public int pumpkin = 155;
+
+ @Expose
+ @ConfigOption(name = "Melon", desc = "Suggested farm speed:\n" +
+ "§e3 Blocks§7: §f✦ 155 speed\n" +
+ "§e2 Blocks§7: §f✦ 265 or 400 speed")
+ @ConfigEditorSlider(minValue = 1, maxValue = 400, minStep = 1)
+ public int melon = 155;
+
+ @Expose
+ @ConfigOption(name = "Cocoa Beans", desc = "Suggested farm speed:\n" +
+ "§e3 Blocks§7: §f✦ 155 speed\n" +
+ "§e4 Blocks§7: §f✦ 116 speed")
+ @ConfigEditorSlider(minValue = 1, maxValue = 400, minStep = 1)
+ public int cocoaBeans = 155;
+
+ // TODO does other speed settings exist?
+ @Expose
+ @ConfigOption(name = "Sugar Cane", desc = "Suggested farm speed:\n" +
+ "§eYaw 45§7: §f✦ 328 speed")
+ @ConfigEditorSlider(minValue = 1, maxValue = 400, minStep = 1)
+ public int sugarCane = 328;
+
+ @Expose
+ @ConfigOption(name = "Cactus", desc = "Suggested farm speed:\n" +
+ "§eNormal§7: §f✦ 400 speed\n" +
+ "§eRacing Helmet§7: §f✦ 464 speed\n" +
+ "§eBlack Cat§7: §f✦ 464 speed")
+ @ConfigEditorSlider(minValue = 1, maxValue = 500, minStep = 1)
+ public int cactus = 400;
+
+ // TODO does other speed settings exist?
+ @Expose
+ @ConfigOption(name = "Mushroom", desc = "Suggested farm speed:\n" +
+ "§eYaw 60§7: §f✦ 233 speed")
+ @ConfigEditorSlider(minValue = 1, maxValue = 400, minStep = 1)
+ public int mushroom = 233;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/optimalspeed/OptimalSpeedConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/optimalspeed/OptimalSpeedConfig.java
new file mode 100644
index 000000000..385d7907f
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/optimalspeed/OptimalSpeedConfig.java
@@ -0,0 +1,39 @@
+package at.hannibal2.skyhanni.config.features.garden.optimalspeed;
+
+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.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class OptimalSpeedConfig {
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Show the optimal speed for your current tool in the hand.\n" +
+ "(Thanks MelonKingDE for the default values).")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Warning Title", desc = "Warn via title when you don't have the optimal speed.")
+ @ConfigEditorBoolean
+ public boolean warning = false;
+
+ @Expose
+ @ConfigOption(name = "Rancher Boots", desc = "Allows you to set the optimal speed in the Rancher Boots overlay by clicking on the presets.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean signEnabled = true;
+
+ @Expose
+ public Position signPosition = new Position(20, -195, false, true);
+
+ @Expose
+ @ConfigOption(name = "Custom Speed", desc = "Change the exact speed for every single crop.")
+ @Accordion
+ public CustomSpeedConfig customSpeed = new CustomSpeedConfig();
+
+ @Expose
+ public Position pos = new Position(5, -200, false, true);
+}
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
new file mode 100644
index 000000000..7fd332d25
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/DropsStatisticsConfig.java
@@ -0,0 +1,78 @@
+package at.hannibal2.skyhanni.config.features.garden.visitor;
+
+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.ConfigEditorDraggableList;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class DropsStatisticsConfig {
+
+ @Expose
+ @ConfigOption(
+ name = "Enabled",
+ desc = "Tallies up statistic about visitors and the rewards you have received from them."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(
+ 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",
+ }
+ )
+ public List<Integer> textFormat = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12));
+
+
+ @Expose
+ @ConfigOption(name = "Display Numbers First", desc = "Determines whether the number or drop name displays first. " +
+ "§eNote: Will not update the preview above!")
+ @ConfigEditorBoolean
+ public boolean displayNumbersFirst = true;
+
+ @Expose
+ @ConfigOption(name = "Display Icons", desc = "Replaces the drop names with icons. " +
+ "§eNote: Will not update the preview above!")
+ @ConfigEditorBoolean
+ public boolean displayIcons = false;
+
+ @Expose
+ @ConfigOption(name = "Only on Barn Plot", desc = "Only shows the overlay while on the Barn plot.")
+ @ConfigEditorBoolean
+ public boolean onlyOnBarn = true;
+
+ @Expose
+ public Position pos = new Position(5, 20, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/InventoryConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/InventoryConfig.java
new file mode 100644
index 000000000..5c671d4e7
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/InventoryConfig.java
@@ -0,0 +1,37 @@
+package at.hannibal2.skyhanni.config.features.garden.visitor;
+
+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 InventoryConfig {
+ @Expose
+ @ConfigOption(name = "Visitor Price", desc = "Show the Bazaar price of the items required for the visitors, like in NEU.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean showPrice = false;
+
+ @Expose
+ @ConfigOption(name = "Amount and Time", desc = "Show the exact item amount and the remaining time when farmed manually. Especially useful for Ironman.")
+ @ConfigEditorBoolean
+ public boolean exactAmountAndTime = true;
+
+ @Expose
+ @ConfigOption(name = "Copper Price", desc = "Show the price per copper inside the visitor GUI.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean copperPrice = true;
+
+ @Expose
+ @ConfigOption(name = "Copper Time", desc = "Show the time required per copper inside the visitor GUI.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean copperTime = false;
+
+ @Expose
+ @ConfigOption(name = "Garden Exp Price", desc = "Show the price per garden experience inside the visitor GUI.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean experiencePrice = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/NeedsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/NeedsConfig.java
new file mode 100644
index 000000000..b60b6207f
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/NeedsConfig.java
@@ -0,0 +1,40 @@
+package at.hannibal2.skyhanni.config.features.garden.visitor;
+
+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 NeedsConfig {
+ @Expose
+ @ConfigOption(name = "Items Needed", desc = "Show all items needed for the visitors.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean display = true;
+
+ @Expose
+ public Position pos = new Position(180, 170, false, true);
+
+ @Expose
+ @ConfigOption(name = "Only when Close", desc = "Only show the needed items when close to the visitors.")
+ @ConfigEditorBoolean
+ public boolean onlyWhenClose = false;
+
+ @Expose
+ @ConfigOption(name = "Bazaar Alley", desc = "Show the Visitor Items List while inside the Bazaar Alley in the Hub. " +
+ "This helps buying the correct amount when not having a Booster Cookie Buff active.")
+ @ConfigEditorBoolean
+ public boolean inBazaarAlley = true;
+
+ @Expose
+ @ConfigOption(name = "Show Price", desc = "Show the coin price in the items needed list.")
+ @ConfigEditorBoolean
+ public boolean showPrice = true;
+
+ @Expose
+ @ConfigOption(name = "Item Preview", desc = "Show the base type for the required items next to new visitors. §cNote that some visitors may require any crop.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean itemPreview = true;
+}
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
new file mode 100644
index 000000000..f83fc5518
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/RewardWarningConfig.java
@@ -0,0 +1,62 @@
+package at.hannibal2.skyhanni.config.features.garden.visitor;
+
+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.ConfigEditorDraggableList;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import org.lwjgl.input.Keyboard;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class RewardWarningConfig {
+
+ @Expose
+ @ConfigOption(name = "Notify in Chat", desc = "Send a chat message once you talk to a visitor with reward.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean notifyInChat = true;
+
+ @Expose
+ @ConfigOption(name = "Show over Name", desc = "Show the reward name above the visitor name.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean showOverName = true;
+
+ @Expose
+ @ConfigOption(name = "Prevent Refusing", desc = "Prevent the refusal of a visitor with reward.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean preventRefusing = true;
+
+ @Expose
+ @ConfigOption(name = "Bypass Key", desc = "Hold that key to bypass the Prevent Refusing feature.")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
+ 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."
+ )
+ @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));
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/TimerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/TimerConfig.java
new file mode 100644
index 000000000..d85f7d048
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/TimerConfig.java
@@ -0,0 +1,37 @@
+package at.hannibal2.skyhanni.config.features.garden.visitor;
+
+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 TimerConfig {
+ @Expose
+ @ConfigOption(name = "Visitor Timer", desc = "Timer when the next visitor will appear, " +
+ "and a number for how many visitors are already waiting.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Sixth Visitor Estimate", desc = "Estimate when the sixth visitor in the queue will arrive. " +
+ "May be inaccurate with co-op members farming simultaneously.")
+ @ConfigEditorBoolean
+ public boolean sixthVisitorEnabled = true;
+
+ @Expose
+ @ConfigOption(name = "Sixth Visitor Warning", desc = "Notifies when it is believed that the sixth visitor has arrived. " +
+ "May be inaccurate with co-op members farming simultaneously.")
+ @ConfigEditorBoolean
+ public boolean sixthVisitorWarning = true;
+
+ @Expose
+ @ConfigOption(name = "New Visitor Ping", desc = "Pings you when you are less than 10 seconds away from getting a new visitor. " +
+ "§eUseful for getting Ephemeral Gratitudes during the 2023 Halloween event.")
+ @ConfigEditorBoolean
+ public boolean newVisitorPing = false;
+
+ @Expose
+ public Position pos = new Position(390, 65, false, true);
+}
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
new file mode 100644
index 000000000..d010b11d3
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/VisitorConfig.java
@@ -0,0 +1,118 @@
+package at.hannibal2.skyhanni.config.features.garden.visitor;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import org.lwjgl.input.Keyboard;
+
+public class VisitorConfig {
+ @Expose
+ @ConfigOption(name = "Visitor Timer", desc = "")
+ @Accordion
+ public TimerConfig timer = new TimerConfig();
+
+ @Expose
+ @ConfigOption(name = "Visitor Items Needed", desc = "")
+ @Accordion
+ public NeedsConfig needs = new NeedsConfig();
+
+ @Expose
+ @ConfigOption(name = "Visitor Inventory", desc = "")
+ @Accordion
+ public InventoryConfig inventory = new InventoryConfig();
+
+ @Expose
+ @ConfigOption(name = "Visitor Reward Warning", desc = "")
+ @Accordion
+ public RewardWarningConfig rewardWarning = new RewardWarningConfig();
+
+ @Expose
+ @ConfigOption(name = "Notification Chat", desc = "Show in chat when a new visitor is visiting your island.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean notificationChat = true;
+
+ @Expose
+ @ConfigOption(name = "Notification Title", desc = "Show a title when a new visitor is visiting your island.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean notificationTitle = true;
+
+ @Expose
+ @ConfigOption(name = "Highlight Status", desc = "Highlight the status for visitors with a text above or with color.")
+ @ConfigEditorDropdown(values = {"Color Only", "Name Only", "Both", "Disabled"})
+ public int highlightStatus = 2;
+
+ @Expose
+ @ConfigOption(name = "Colored Name", desc = "Show the visitor name in the color of the rarity.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean coloredName = true;
+
+ @Expose
+ @ConfigOption(name = "Hypixel Message", desc = "Hide the chat message from Hypixel that a new visitor has arrived at your garden.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hypixelArrivedMessage = true;
+
+ @Expose
+ @ConfigOption(name = "Hide Chat", desc = "Hide chat messages from the visitors in garden. (Except Beth and Spaceman)")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideChat = true;
+
+ @Expose
+ @ConfigOption(name = "Visitor Drops Statistics Counter", desc = "")
+ @Accordion
+ public DropsStatisticsConfig dropsStatistics = new DropsStatisticsConfig();
+
+ @Expose
+ @ConfigOption(
+ name = "Accept Hotkey",
+ desc = "Accept a visitor when you press this keybind while in the visitor GUI. " +
+ "§eUseful for getting Ephemeral Gratitudes during the 2023 Halloween event."
+ )
+ @ConfigEditorKeybind(
+ defaultKey = Keyboard.KEY_NONE
+ )
+ public int acceptHotkey = Keyboard.KEY_NONE;
+
+
+ @Expose
+ @ConfigOption(
+ name = "Highlight Visitors in SkyBlock",
+ desc = "Highlights Visitors outside of the Garden"
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlightVisitors = false;
+
+
+ @Expose
+ @ConfigOption(
+ name = "Block Interacting with Visitors",
+ desc = "Blocks you from interacting with / unlocking Visitors to allow for Dedication Cycling"
+ )
+ @ConfigEditorDropdown
+ public VisitorBlockBehaviour blockInteracting = VisitorBlockBehaviour.ONLY_ON_BINGO;
+
+ public enum VisitorBlockBehaviour {
+ DONT("Don't"), ALWAYS("Always"), ONLY_ON_BINGO("Only on Bingo");
+
+ final String str;
+
+ VisitorBlockBehaviour(String str) {
+ this.str = str;
+ }
+
+ @Override
+ public String toString() {
+ return str;
+ }
+ }
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/gui/GUIConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/gui/GUIConfig.java
new file mode 100644
index 000000000..4eeadf221
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/gui/GUIConfig.java
@@ -0,0 +1,74 @@
+package at.hannibal2.skyhanni.config.features.gui;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.core.config.Position;
+import at.hannibal2.skyhanni.data.GuiEditManager;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorButton;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import org.lwjgl.input.Keyboard;
+
+public class GUIConfig {
+
+ @ConfigOption(name = "Edit GUI Locations", desc = "Change the position of SkyHanni's overlays.")
+ @ConfigEditorButton(buttonText = "Edit")
+ public Runnable positions = () -> GuiEditManager.openGuiPositionEditor(true);
+
+ @Expose
+ @ConfigOption(name = "Open Hotkey", desc = "Press this key to open the GUI Editor.")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
+ public int keyBindOpen = Keyboard.KEY_NONE;
+
+ @Expose
+ @ConfigOption(name = "Global GUI Scale", desc = "Globally scale all SkyHanni GUIs.")
+ @ConfigEditorSlider(minValue = 0.1F, maxValue = 10, minStep = 0.05F)
+ public float globalScale = 1F;
+
+ @Expose
+ @ConfigOption(name = "Modify Visual Words", desc = "")
+ @Accordion
+ public ModifyWordsConfig modifyWords = new ModifyWordsConfig();
+
+ @Expose
+ @ConfigOption(name = "Custom Text Box", desc = "")
+ @Accordion
+ public TextBoxConfig customTextBox = new TextBoxConfig();
+
+ @Expose
+ @ConfigOption(name = "Real Time", desc = "Display the current computer time, a handy feature when playing in full-screen mode.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean realTime = false;
+
+ @Expose
+ @ConfigOption(name = "Real Time 12h Format", desc = "Display the current computer time in 12hr Format rather than 24h Format.")
+ @ConfigEditorBoolean
+ public boolean realTimeFormatToggle = false;
+
+ @Expose
+ public Position realTimePosition = new Position(10, 10, false, true);
+
+ @Expose
+ @ConfigOption(name = "In-Game Date", desc = "")
+ @Accordion
+ public InGameDateConfig inGameDate = new InGameDateConfig();
+
+ @Expose
+ @ConfigOption(name = "TPS Display", desc = "Show the TPS of the current server, like in Soopy.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean tpsDisplay = false;
+
+ @Expose
+ public Position tpsDisplayPosition = new Position(10, 10, false, true);
+
+ @Expose
+ @ConfigOption(name = "Config Button", desc = "Add a button to the pause menu to configure SkyHanni.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean configButtonOnPause = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/gui/InGameDateConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/gui/InGameDateConfig.java
new file mode 100644
index 000000000..5985e5131
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/gui/InGameDateConfig.java
@@ -0,0 +1,63 @@
+package at.hannibal2.skyhanni.config.features.gui;
+
+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.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class InGameDateConfig {
+
+ @Expose
+ @ConfigOption(
+ name = "Enabled",
+ desc = "Show the in-game date of SkyBlock (like in Apec, §ebut with mild delays§7).\n" +
+ "(Though this one includes the SkyBlock year!)"
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ public Position position = new Position(10, 10, false, true);
+
+ @Expose
+ @ConfigOption(
+ name = "Use Scoreboard for Date",
+ desc = "Uses the scoreboard instead to find the current month, date, and time. Greater \"accuracy\", depending on who's asking."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean useScoreboard = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Show Sun/Moon",
+ desc = "Show the sun or moon symbol seen on the scoreboard."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean includeSunMoon = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Show Date Ordinal",
+ desc = "Show the date's ordinal suffix. Ex: (1st <-> 1, 22nd <-> 22, 23rd <-> 3, 24th <-> 24, etc.)"
+ )
+ @ConfigEditorBoolean
+ public boolean includeOrdinal = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Refresh Rate",
+ desc = "Change the time in seconds you would like to refresh the In-Game Date Display." +
+ "\n§eNOTE: If \"Use Scoreboard for Date\" is enabled, this setting is ignored."
+ )
+ @ConfigEditorSlider(
+ minValue = 1,
+ maxValue = 60,
+ minStep = 1
+ )
+ public int refreshSeconds = 30;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/gui/ModifyWordsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/gui/ModifyWordsConfig.java
new file mode 100644
index 000000000..498dba83d
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/gui/ModifyWordsConfig.java
@@ -0,0 +1,28 @@
+package at.hannibal2.skyhanni.config.features.gui;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.commands.Commands;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorButton;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class ModifyWordsConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Enables replacing all instances of a word or phrase with another word or phrase.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Work Outside SkyBlock", desc = "Allows modifying visual words anywhere on Hypixel.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean workOutside = false;
+
+ @ConfigOption(name = "Open Config", desc = "Opens the menu to setup the visual words.\n§eCommand: /shwords")
+ @ConfigEditorButton(buttonText = "Open")
+ public Runnable open = Commands::openVisualWords;
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/gui/TextBoxConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/gui/TextBoxConfig.java
new file mode 100644
index 000000000..134732465
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/gui/TextBoxConfig.java
@@ -0,0 +1,26 @@
+package at.hannibal2.skyhanni.config.features.gui;
+
+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.ConfigEditorText;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import io.github.moulberry.moulconfig.observer.Property;
+
+public class TextBoxConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Enables showing the textbox while in SkyBlock.")
+ @ConfigEditorBoolean
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Text", desc = "Enter text you want to display here.\n" +
+ "§eUse '&' as the colour code character.\n" +
+ "§eUse '\\n' as the line break character.")
+ @ConfigEditorText
+ public Property<String> text = Property.of("&aYour Text Here\\n&bYour new line here");
+
+ @Expose
+ public Position position = new Position(10, 80, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/ChestValueConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/ChestValueConfig.java
new file mode 100644
index 000000000..62eb30385
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/ChestValueConfig.java
@@ -0,0 +1,88 @@
+package at.hannibal2.skyhanni.config.features.inventory;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class ChestValueConfig {
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Enable estimated value of chest.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Enabled in dungeons", desc = "Enable the feature in dungeons.")
+ @ConfigEditorBoolean
+ public boolean enableInDungeons = false;
+
+ @Expose
+ @ConfigOption(name = "Enable during Item Value", desc = "Show this display even if the Estimated Item Value is visible.")
+ @ConfigEditorBoolean
+ public boolean showDuringEstimatedItemValue = false;
+
+ @Expose
+ @ConfigOption(name = "Show Stacks", desc = "Show the item icon before name.")
+ @ConfigEditorBoolean
+ public boolean showStacks = true;
+
+ @Expose
+ @ConfigOption(name = "Display Type", desc = "Try to align everything to look nicer.")
+ @ConfigEditorBoolean
+ public boolean alignedDisplay = true;
+
+ @Expose
+ @ConfigOption(name = "Name Length", desc = "Reduce item name length to gain extra space on screen.\n§cCalculated in pixels!")
+ @ConfigEditorSlider(minStep = 1, minValue = 100, maxValue = 150)
+ public int nameLength = 100;
+
+ @Expose
+ @ConfigOption(name = "Highlight Slot", desc = "Highlight slot where the item is when you hover over it in the display.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enableHighlight = true;
+
+ @Expose
+ @ConfigOption(name = "Highlight Color", desc = "Choose the highlight color.")
+ @ConfigEditorColour
+ public String highlightColor = "0:249:0:255:88";
+
+ @Expose
+ @ConfigOption(name = "Sorting Type", desc = "Price sorting type.")
+ @ConfigEditorDropdown(values = {"Descending", "Ascending"})
+ public int sortingType = 0;
+
+ @Expose
+ @ConfigOption(name = "Value formatting Type", desc = "Format of the price.")
+ @ConfigEditorDropdown(values = {"Short", "Long"})
+ public int formatType = 0;
+
+ @Expose
+ @ConfigOption(name = "Item To Show", desc = "Choose how many items are displayed.\n" +
+ "All items in the chest are still counted for the total value.")
+ @ConfigEditorSlider(
+ minValue = 0,
+ maxValue = 54,
+ minStep = 1
+ )
+ public int itemToShow = 15;
+
+ @Expose
+ @ConfigOption(name = "Hide below", desc = "Item item value below configured amount.\n" +
+ "Items are still counted for the total value.")
+ @ConfigEditorSlider(
+ minValue = 50_000,
+ maxValue = 10_000_000,
+ minStep = 50_000
+ )
+ public int hideBelow = 100_000;
+
+
+ @Expose
+ public Position position = new Position(107, 141, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/HideNotClickableConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/HideNotClickableConfig.java
new file mode 100644
index 000000000..9c0c01602
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/HideNotClickableConfig.java
@@ -0,0 +1,43 @@
+package at.hannibal2.skyhanni.config.features.inventory;
+
+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.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class HideNotClickableConfig {
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Hide items that are not clickable in the current inventory: ah, bz, accessory bag, etc.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean items = false;
+
+ @Expose
+ @ConfigOption(name = "Block Clicks", desc = "Block the clicks on these items.")
+ @ConfigEditorBoolean
+ public boolean itemsBlockClicks = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Opacity",
+ desc = "How strong should the items be grayed out?"
+ )
+ @ConfigEditorSlider(
+ minValue = 0,
+ maxValue = 255,
+ minStep = 5
+ )
+ public int opacity = 180;
+
+ @Expose
+ @ConfigOption(name = "Bypass With Control", desc = "Adds the ability to bypass not clickable items when holding the control key.")
+ @ConfigEditorBoolean
+ public boolean itemsBypass = true;
+
+ @Expose
+ @ConfigOption(name = "Green Line", desc = "Adds green line around items that are clickable.")
+ @ConfigEditorBoolean
+ public boolean itemsGreenLine = true;
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java
new file mode 100644
index 000000000..1794a20d0
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java
@@ -0,0 +1,127 @@
+package at.hannibal2.skyhanni.config.features.inventory;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.features.inventory.helper.HelperConfig;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.Category;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorDraggableList;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class InventoryConfig {
+
+ @Expose
+ @ConfigOption(name = "Not Clickable Items", desc = "")
+ @Accordion
+ public HideNotClickableConfig hideNotClickable = new HideNotClickableConfig();
+
+ @Expose
+ @ConfigOption(name = "RNG Meter", desc = "")
+ @Accordion
+ public RngMeterConfig rngMeter = new RngMeterConfig();
+
+ @Expose
+ @ConfigOption(name = "Stats Tuning", desc = "")
+ @Accordion
+ public StatsTuningConfig statsTuning = new StatsTuningConfig();
+
+ @Expose
+ @ConfigOption(name = "Jacob Farming Contest", desc = "")
+ @Accordion
+ public JacobFarmingContestConfig jacobFarmingContests = new JacobFarmingContestConfig();
+
+
+ @Expose
+ @ConfigOption(name = "Sack Items Display", desc = "")
+ @Accordion
+ public SackDisplayConfig sackDisplay = new SackDisplayConfig();
+
+ @Expose
+ @ConfigOption(name = "Chest Value", desc = "")
+ @Accordion
+ public ChestValueConfig chestValueConfig = new ChestValueConfig();
+
+ @Expose
+ @Category(name = "Helpers", desc = "Settings for Helpers")
+ public HelperConfig helper = new HelperConfig();
+
+ @Expose
+ @ConfigOption(
+ 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"
+ }
+ )
+ public List<Integer> itemNumberAsStackSize = new ArrayList<>(Arrays.asList(3, 9, 11, 12));
+
+ @Expose
+ @ConfigOption(
+ name = "Quick Craft Confirmation",
+ desc = "Require Ctrl+Click to craft items that aren't often quick crafted " +
+ "(e.g. armor, weapons, accessories). Sack items can be crafted normally."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean quickCraftingConfirmation = false;
+
+ @Expose
+ @ConfigOption(name = "Sack Name", desc = "Show an abbreviation of the sack name.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean displaySackName = false;
+
+ @Expose
+ @ConfigOption(name = "Anvil Combine Helper", desc = "Suggests the same item in the inventory when trying to combine two items in the anvil.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean anvilCombineHelper = false;
+
+ @Expose
+ @ConfigOption(name = "Item Stars",
+ desc = "Show a compact star count in the item name for all items.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean itemStars = false;
+
+ @Expose
+ @ConfigOption(name = "Missing Tasks",
+ desc = "Highlight missing tasks in the SkyBlock Level Guide inventory.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlightMissingSkyBlockLevelGuide = true;
+
+ @Expose
+ @ConfigOption(name = "Highlight Auctions",
+ desc = "Highlight own items that are sold in green and that are expired in red.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlightAuctions = true;
+
+ @Expose
+ @ConfigOption(name = "Shift Click Equipment", desc = "Makes normal clicks to shift clicks in equipment inventory")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean shiftClickForEquipment = false;
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/JacobFarmingContestConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/JacobFarmingContestConfig.java
new file mode 100644
index 000000000..dc18bd29d
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/JacobFarmingContestConfig.java
@@ -0,0 +1,32 @@
+package at.hannibal2.skyhanni.config.features.inventory;
+
+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 JacobFarmingContestConfig {
+ @Expose
+ @ConfigOption(name = "Unclaimed Rewards", desc = "Highlight contests with unclaimed rewards in the Jacob inventory.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlightRewards = true;
+
+ @Expose
+ @ConfigOption(name = "Contest Time", desc = "Adds the real time format to the Contest description.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean realTime = true;
+
+ @Expose
+ @ConfigOption(name = "Medal Icon", desc = "Adds a symbol that shows what medal you received in this Contest. " +
+ "§eIf you use a texture pack this may cause conflicting icons.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean medalIcon = true;
+
+ @Expose
+ @ConfigOption(name = "Finnegan Icon", desc = "Uses a different indicator for when the Contest happened during Mayor Finnegan.")
+ @ConfigEditorBoolean
+ public boolean finneganIcon = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/RngMeterConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/RngMeterConfig.java
new file mode 100644
index 000000000..e57e95b5c
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/RngMeterConfig.java
@@ -0,0 +1,26 @@
+package at.hannibal2.skyhanni.config.features.inventory;
+
+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 RngMeterConfig {
+ @Expose
+ @ConfigOption(name = "Floor Names", desc = "Show the Floor names in the Catacombs RNG Meter inventory.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean floorName = false;
+
+ @Expose
+ @ConfigOption(name = "No Drop", desc = "Highlight floors without a drop selected in the Catacombs RNG Meter inventory.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean noDrop = false;
+
+ @Expose
+ @ConfigOption(name = "Selected Drop", desc = "Highlight the selected drop in the Catacombs or Slayer RNG Meter inventory.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean selectedDrop = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/SackDisplayConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/SackDisplayConfig.java
new file mode 100644
index 000000000..37eab2be3
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/SackDisplayConfig.java
@@ -0,0 +1,84 @@
+package at.hannibal2.skyhanni.config.features.inventory;
+
+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;
+
+public class SackDisplayConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Show contained items inside a sack inventory.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Highlight Full",
+ desc = "Highlight items that are full in red.\n" +
+ "§eDoes not need the option above to be enabled."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlightFull = true;
+
+ @Expose
+ @ConfigOption(name = "Number Format", desc = "Either show Default, Formatted or Unformatted numbers.\n" +
+ "§eDefault: §72,240/2.2k\n" +
+ "§eFormatted: §72.2k/2.2k\n" +
+ "§eUnformatted: §72,240/2,200")
+ @ConfigEditorDropdown(values = {"Default", "Formatted", "Unformatted"})
+ public int numberFormat = 1;
+
+ @Expose
+ @ConfigOption(name = "Extra space", desc = "Space between each line of text.")
+ @ConfigEditorSlider(
+ minValue = 0,
+ maxValue = 10,
+ minStep = 1)
+ public int extraSpace = 1;
+
+ @Expose
+ @ConfigOption(name = "Sorting Type", desc = "Sorting type of items in sack.")
+ @ConfigEditorDropdown(values = {"Descending (Stored)", "Ascending (Stored)", "Descending (Price)", "Ascending (Price)"})
+ public int sortingType = 0;
+
+ @Expose
+ @ConfigOption(name = "Item To Show", desc = "Choose how many items are displayed. (Some sacks have too many items to fit\n" +
+ "in larger GUI scales, like the nether sack.)")
+ @ConfigEditorSlider(
+ minValue = 0,
+ maxValue = 45,
+ minStep = 1
+ )
+ public int itemToShow = 15;
+
+ @Expose
+ @ConfigOption(name = "Show Empty Item", desc = "Show empty item quantity in the display.")
+ @ConfigEditorBoolean
+ public boolean showEmpty = true;
+
+ @Expose
+ @ConfigOption(name = "Show Price", desc = "Show price for each item in sack.")
+ @ConfigEditorBoolean
+ public boolean showPrice = true;
+
+ @Expose
+ @ConfigOption(name = "Price Format", desc = "Format of the price displayed.\n" +
+ "§eFormatted: §7(12k)\n" +
+ "§eUnformatted: §7(12,421)")
+ @ConfigEditorDropdown(values = {"Formatted", "Unformatted"})
+ public int priceFormat = 0;
+
+ @Expose
+ @ConfigOption(name = "Show Price From", desc = "Show price from Bazaar or NPC.")
+ @ConfigEditorDropdown(values = {"Bazaar", "NPC"})
+ public int priceFrom = 0;
+
+ @Expose
+ public Position position = new Position(144, 139, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/StatsTuningConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/StatsTuningConfig.java
new file mode 100644
index 000000000..2f6111fee
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/StatsTuningConfig.java
@@ -0,0 +1,32 @@
+package at.hannibal2.skyhanni.config.features.inventory;
+
+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 StatsTuningConfig {
+ @Expose
+ @ConfigOption(name = "Selected Stats", desc = "Show the tuning stats in the Thaumaturgy inventory.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean selectedStats = true;
+
+ @Expose
+ @ConfigOption(name = "Tuning Points", desc = "Show the amount of selected Tuning Points in the Stats Tuning inventory.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean points = true;
+
+ @Expose
+ @ConfigOption(name = "Selected Template", desc = "Highlight the selected template in the Stats Tuning inventory.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean selectedTemplate = true;
+
+ @Expose
+ @ConfigOption(name = "Template Stats", desc = "Show the type of stats for the Tuning Point templates.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean templateStats = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/helper/HarpConfigKeyBinds.java b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/helper/HarpConfigKeyBinds.java
new file mode 100644
index 000000000..fcdac1d57
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/helper/HarpConfigKeyBinds.java
@@ -0,0 +1,37 @@
+package at.hannibal2.skyhanni.config.features.inventory.helper;
+
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import org.lwjgl.input.Keyboard;
+
+public class HarpConfigKeyBinds {
+ @Expose
+ @ConfigOption(name = "Key 1", desc = "Key for the first Node")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_1)
+ public int key1 = Keyboard.KEY_1;
+ @Expose
+ @ConfigOption(name = "Key 2", desc = "Key for the second Node")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_2)
+ public int key2 = Keyboard.KEY_2;
+ @Expose
+ @ConfigOption(name = "Key 3", desc = "Key for the third Node")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_3)
+ public int key3 = Keyboard.KEY_3;
+ @Expose
+ @ConfigOption(name = "Key 4", desc = "Key for the fourth Node")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_4)
+ public int key4 = Keyboard.KEY_4;
+ @Expose
+ @ConfigOption(name = "Key 5", desc = "Key for the fifth Node")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_5)
+ public int key5 = Keyboard.KEY_5;
+ @Expose
+ @ConfigOption(name = "Key 6", desc = "Key for the sixth Node")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_6)
+ public int key6 = Keyboard.KEY_6;
+ @Expose
+ @ConfigOption(name = "Key 7", desc = "Key for the seventh Node")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_7)
+ public int key7 = Keyboard.KEY_7;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/helper/HelperConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/helper/HelperConfig.java
new file mode 100644
index 000000000..02c06f39a
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/helper/HelperConfig.java
@@ -0,0 +1,37 @@
+package at.hannibal2.skyhanni.config.features.inventory.helper;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class HelperConfig {
+ @Expose
+ @ConfigOption(name = "Melody's Hair Harp", desc = "")
+ @Accordion
+ public HarpConfig harp = new HarpConfig();
+
+ public static class HarpConfig {
+ @Expose
+ @ConfigOption(name = "Use Keybinds", desc = "In the Harp, press buttons with your number row on the keyboard instead of clicking.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean keybinds = false;
+
+ @Expose
+ @ConfigOption(name = "Show Numbers", desc = "In the Harp, show buttons as stack size (intended to be used with the Keybinds).")
+ @ConfigEditorBoolean
+ public boolean showNumbers = false;
+
+ @Expose
+ @ConfigOption(name = "Keybinds", desc = "")
+ @Accordion
+ public HarpConfigKeyBinds harpKeybinds = new HarpConfigKeyBinds();
+ }
+
+ @Expose
+ @ConfigOption(name = "Tia Relay Abiphone Network Maintenance", desc = "")
+ @Accordion
+ public TiaRelayConfig tiaRelay = new TiaRelayConfig();
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/helper/TiaRelayConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/helper/TiaRelayConfig.java
new file mode 100644
index 000000000..78480b4df
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/helper/TiaRelayConfig.java
@@ -0,0 +1,32 @@
+package at.hannibal2.skyhanni.config.features.inventory.helper;
+
+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 TiaRelayConfig {
+
+ @Expose
+ @ConfigOption(name = "Sound Puzzle Helper", desc = "Helps with solving the sound puzzle for Tia (The 9 Operator Chips to do maintainance for the Abiphone Network).")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean soundHelper = true;
+
+ @Expose
+ @ConfigOption(name = "Next Waypoint", desc = "Show the next relay waypoint for Tia the Fairy, where maintenance for the Abiphone network needs to be done.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean nextWaypoint = true;
+
+ @Expose
+ @ConfigOption(name = "All Waypoints", desc = "Show all relay waypoints at once (intended for debugging).")
+ @ConfigEditorBoolean
+ public boolean allWaypoints = false;
+
+ @Expose
+ @ConfigOption(name = "Mute Sound", desc = "Mutes the sound when close to the relay.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean tiaRelayMute = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/itemability/ChickenHeadConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/itemability/ChickenHeadConfig.java
new file mode 100644
index 000000000..49c803cd5
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/itemability/ChickenHeadConfig.java
@@ -0,0 +1,25 @@
+package at.hannibal2.skyhanni.config.features.itemability;
+
+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 ChickenHeadConfig {
+
+ @Expose
+ @ConfigOption(name = "Checken Head Timer", desc = "Show the cooldown until the next time you can lay an egg with the Chicken Head.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean displayTimer = false;
+
+ @Expose
+ public Position position = new Position(-372, 73, false, true);
+
+ @Expose
+ @ConfigOption(name = "Hide Chat", desc = "Hide the 'You laid an egg!' chat message.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideChat = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/itemability/FireVeilWandConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/itemability/FireVeilWandConfig.java
new file mode 100644
index 000000000..a05558d94
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/itemability/FireVeilWandConfig.java
@@ -0,0 +1,21 @@
+package at.hannibal2.skyhanni.config.features.itemability;
+
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class FireVeilWandConfig {
+ @Expose
+ @ConfigOption(name = "Fire Veil Design", desc = "Changes the flame particles of the Fire Veil Wand ability.")
+ @ConfigEditorDropdown(values = {"Particles", "Line", "Off"})
+ public int display = 0;
+
+ @Expose
+ @ConfigOption(
+ name = "Line Color",
+ desc = "Changes the color of the Fire Veil Wand line."
+ )
+ @ConfigEditorColour
+ public String displayColor = "0:245:255:85:85";
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/itemability/ItemAbilityConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/itemability/ItemAbilityConfig.java
new file mode 100644
index 000000000..a53075016
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/itemability/ItemAbilityConfig.java
@@ -0,0 +1,38 @@
+package at.hannibal2.skyhanni.config.features.itemability;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class ItemAbilityConfig {
+
+ @Expose
+ @ConfigOption(name = "Ability Cooldown", desc = "Show the cooldown of item abilities.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean itemAbilityCooldown = false;
+
+ @Expose
+ @ConfigOption(name = "Ability Cooldown Background", desc = "Show the cooldown color of item abilities in the background.")
+ @ConfigEditorBoolean
+ public boolean itemAbilityCooldownBackground = false;
+
+ @Expose
+ @ConfigOption(name = "Fire Veil", desc = "")
+ @Accordion
+ public FireVeilWandConfig fireVeilWands = new FireVeilWandConfig();
+
+ @ConfigOption(name = "Chicken Head", desc = "")
+ @Accordion
+ @Expose
+ public ChickenHeadConfig chickenHead = new ChickenHeadConfig();
+
+ @Expose
+ @ConfigOption(name = "Depleted Bonzo's Masks",
+ desc = "Highlights used Bonzo's Masks and Spirit Masks with a background.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean depletedBonzosMasks = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/MarkedPlayerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/markedplayer/MarkedPlayerConfig.java
index e199f7c55..431e5f29c 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/MarkedPlayerConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/markedplayer/MarkedPlayerConfig.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.config.features;
+package at.hannibal2.skyhanni.config.features.markedplayer;
import com.google.gson.annotations.Expose;
import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/mining/KingTalismanConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/mining/KingTalismanConfig.java
new file mode 100644
index 000000000..e98ae5740
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/mining/KingTalismanConfig.java
@@ -0,0 +1,25 @@
+package at.hannibal2.skyhanni.config.features.mining;
+
+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 KingTalismanConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Show kings you have not talked to yet, and when the next missing king will appear.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Outside Mines", desc = "Show the display even while outside the Dwarven Mines.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean outsideMines = false;
+
+ @Expose
+ public Position position = new Position(-400, 220, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/mining/MiningConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/mining/MiningConfig.java
new file mode 100644
index 000000000..feeb465ab
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/mining/MiningConfig.java
@@ -0,0 +1,32 @@
+package at.hannibal2.skyhanni.config.features.mining;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class MiningConfig {
+
+ @Expose
+ @ConfigOption(name = "Powder Tracker", desc = "")
+ @Accordion
+ public PowderTrackerConfig powderTracker = new PowderTrackerConfig();
+
+ @Expose
+ @ConfigOption(name = "King Talisman", desc = "")
+ @Accordion
+ public KingTalismanConfig kingTalisman = new KingTalismanConfig();
+
+ @Expose
+ @ConfigOption(name = "Highlight Commission Mobs", desc = "Highlight Mobs that are part of active commissions.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlightCommissionMobs = false;
+
+ @Expose
+ @ConfigOption(name = "Names in Core", desc = "Show the names of the 4 areas while in the center of the Crystal Hollows.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean crystalHollowsNamesInCore = false;
+}
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
new file mode 100644
index 000000000..50bff2a9b
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/mining/PowderTrackerConfig.java
@@ -0,0 +1,84 @@
+package at.hannibal2.skyhanni.config.features.mining;
+
+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.ConfigEditorDraggableList;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import io.github.moulberry.moulconfig.observer.Property;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class PowderTrackerConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Enable the Powder Tracker overlay for mining.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Only when Grinding", desc = "Only show the overlay when powder grinding.")
+ @ConfigEditorBoolean
+ public boolean onlyWhenPowderGrinding = false;
+
+ @Expose
+ @ConfigOption(name = "Great Explorer", desc = "Enable this if your Great Explorer perk is maxed.")
+ @ConfigEditorBoolean
+ public boolean greatExplorerMaxed = false;
+
+ @Expose
+ @ConfigOption(
+ 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"
+ }
+ )
+ 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)));
+
+ @Expose
+ public Position position = new Position(-274, 0, false, true);
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/minion/EmptiedTimeConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/minion/EmptiedTimeConfig.java
new file mode 100644
index 000000000..53f324e00
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/minion/EmptiedTimeConfig.java
@@ -0,0 +1,27 @@
+package at.hannibal2.skyhanni.config.features.minion;
+
+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.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class EmptiedTimeConfig {
+ @Expose
+ @ConfigOption(name = "Emptied Time Display", desc = "Show the time when the hopper in the minion was last emptied.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean display = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Distance",
+ desc = "Maximum distance to display minion data."
+ )
+ @ConfigEditorSlider(
+ minValue = 3,
+ maxValue = 30,
+ minStep = 1
+ )
+ public int distance = 10;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/minion/LastClickedMinionConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/minion/LastClickedMinionConfig.java
new file mode 100644
index 000000000..391a10468
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/minion/LastClickedMinionConfig.java
@@ -0,0 +1,36 @@
+package at.hannibal2.skyhanni.config.features.minion;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class LastClickedMinionConfig {
+ @Expose
+ @ConfigOption(name = "Last Minion Display", desc = "Marks the location of the last clicked minion, even through walls.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean display = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Last Minion Color",
+ desc = "The color in which the last minion should be displayed."
+ )
+ @ConfigEditorColour
+ public String color = "0:245:85:255:85";
+
+ @Expose
+ @ConfigOption(
+ name = "Last Minion Time",
+ desc = "Time in seconds how long the last minion should be displayed."
+ )
+ @ConfigEditorSlider(
+ minValue = 3,
+ maxValue = 120,
+ minStep = 1
+ )
+ public int time = 20;
+}
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
new file mode 100644
index 000000000..d54e3d464
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/minion/MinionsConfig.java
@@ -0,0 +1,46 @@
+package at.hannibal2.skyhanni.config.features.minion;
+
+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.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class MinionsConfig {
+
+ @Expose
+ @ConfigOption(name = "Name Display", desc = "Show the minion name and tier over the minion.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean nameDisplay = true;
+
+ @Expose
+ @ConfigOption(name = "Only Tier", desc = "Show only the tier number over the minion. (Useful for Bingo)")
+ @ConfigEditorBoolean
+ public boolean nameOnlyTier = false;
+
+ @Expose
+ @ConfigOption(name = "Last Clicked", desc = "")
+ @Accordion
+ public LastClickedMinionConfig lastClickedMinion = new LastClickedMinionConfig();
+
+ @Expose
+ @ConfigOption(name = "Emptied Time", desc = "")
+ @Accordion
+ public EmptiedTimeConfig emptiedTime = new EmptiedTimeConfig();
+
+ @Expose
+ @ConfigOption(name = "Hopper Profit Display", desc = "Use the hopper's held coins and the last empty time to calculate the coins per day.")
+ @ConfigEditorBoolean
+ public boolean hopperProfitDisplay = true;
+
+ @Expose
+ public Position hopperProfitPos = new Position(360, 90, false, true);
+
+ @Expose
+ @ConfigOption(name = "Hide Mob Nametag", desc = "Hiding the nametag of mobs close to minions.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideMobsNametagNearby = false;
+}
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
new file mode 100644
index 000000000..ab4a18d47
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/DiscordRPCConfig.java
@@ -0,0 +1,97 @@
+package at.hannibal2.skyhanni.config.features.misc;
+
+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.ConfigEditorDraggableList;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorText;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import io.github.moulberry.moulconfig.observer.Property;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class DiscordRPCConfig {
+
+ @Expose
+ @ConfigOption(name = "Enable Discord RPC", desc = "Details about your SkyBlock session displayed through Discord.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public Property<Boolean> enabled = Property.of(false);
+
+ @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);
+
+ @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);
+
+ @Expose
+ @ConfigOption(name = "Custom", desc = "What should be displayed if you select \"Custom\" above.")
+ @ConfigEditorText
+ public Property<String> customText = Property.of("");
+
+ @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"
+ }
+ )
+ 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);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/EstimatedItemValueConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/EstimatedItemValueConfig.java
new file mode 100644
index 000000000..2513cd66b
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/EstimatedItemValueConfig.java
@@ -0,0 +1,52 @@
+package at.hannibal2.skyhanni.config.features.misc;
+
+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.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import io.github.moulberry.moulconfig.observer.Property;
+import org.lwjgl.input.Keyboard;
+
+public class EstimatedItemValueConfig {
+ @Expose
+ @ConfigOption(name = "Enable Estimated Price", desc = "Displays an Estimated Item Value for the item you hover over.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Hotkey", desc = "Press this key to show the Estimated Item Value.")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
+ public int hotkey = Keyboard.KEY_NONE;
+
+ @Expose
+ @ConfigOption(name = "Show Always", desc = "Ignore the hotkey and always display the item value.")
+ @ConfigEditorBoolean
+ public boolean alwaysEnabled = true;
+
+ @Expose
+ @ConfigOption(name = "Enchantments Cap", desc = "Only show the top # most expensive enchantments.")
+ @ConfigEditorSlider(
+ minValue = 1,
+ maxValue = 30,
+ minStep = 1
+ )
+ public Property<Integer> enchantmentsCap = Property.of(7);
+
+ @Expose
+ @ConfigOption(name = "Show Exact Price", desc = "Show the exact total price instead of the compact number.")
+ @ConfigEditorBoolean
+ public boolean exactPrice = false;
+
+ @Expose
+ @ConfigOption(name = "Show Armor Value", desc = "Show the value of the full armor set in the Wardrobe inventory.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean armor = true;
+
+ @Expose
+ public Position itemPriceDataPos = new Position(140, 90, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/GlowingDroppedItemsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/GlowingDroppedItemsConfig.java
new file mode 100644
index 000000000..4b5a260a1
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/GlowingDroppedItemsConfig.java
@@ -0,0 +1,26 @@
+package at.hannibal2.skyhanni.config.features.misc;
+
+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 GlowingDroppedItemsConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Draws a glowing outline around all dropped items on the ground.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Highlight Showcase Items", desc = "Draws a glowing outline around showcase items.")
+ @ConfigEditorBoolean
+ public boolean highlightShowcase = false;
+
+ @Expose
+ @ConfigOption(name = "Highlight Fishing Bait", desc = "Draws a glowing outline around fishing bait.")
+ @ConfigEditorBoolean
+ public boolean highlightFishingBait = false;
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/HideArmorConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/HideArmorConfig.java
new file mode 100644
index 000000000..286249061
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/HideArmorConfig.java
@@ -0,0 +1,20 @@
+package at.hannibal2.skyhanni.config.features.misc;
+
+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 HideArmorConfig {
+
+ @Expose
+ @ConfigOption(name = "Mode", desc = "Hide the armor of players.")
+ @ConfigEditorDropdown(values = {"All", "Own Armor", "Other's Armor", "Off"})
+ public int mode = 3;
+
+ @Expose
+ @ConfigOption(name = "Only Helmet", desc = "Only hide the helmet.")
+ @ConfigEditorBoolean()
+ public Boolean onlyHelmet = false;
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/HighlightPartyMembersConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/HighlightPartyMembersConfig.java
new file mode 100644
index 000000000..8dc4d7c02
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/HighlightPartyMembersConfig.java
@@ -0,0 +1,25 @@
+package at.hannibal2.skyhanni.config.features.misc;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class HighlightPartyMembersConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Marking party members with a bright outline to better find them in the world.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Outline Color",
+ desc = "The color to outline party members in."
+ )
+ @ConfigEditorColour
+ public String outlineColor = "0:245:85:255:85";
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/KickDurationConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/KickDurationConfig.java
new file mode 100644
index 000000000..0d5af9046
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/KickDurationConfig.java
@@ -0,0 +1,34 @@
+package at.hannibal2.skyhanni.config.features.misc;
+
+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.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import io.github.moulberry.moulconfig.observer.Property;
+
+public class KickDurationConfig {
+
+ @Expose
+ @ConfigOption(
+ name = "Enabled",
+ desc = "Show in the Hypixel lobby since when you were last kicked from SkyBlock (" +
+ "useful if you get blocked because of '§cYou were kicked while joining that server!§7')."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Warn Time", desc = "Send warning and sound this seconds after a SkyBlock kick.")
+ @ConfigEditorSlider(
+ minValue = 5,
+ maxValue = 300,
+ minStep = 1
+ )
+ public Property<Integer> warnTime = Property.of(60);
+
+ @Expose
+ public Position position = new Position(400, 200, 1.3f);
+}
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
new file mode 100644
index 000000000..1ac453a8d
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/MiscConfig.java
@@ -0,0 +1,216 @@
+package at.hannibal2.skyhanni.config.features.misc;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.core.config.Position;
+import at.hannibal2.skyhanni.config.features.misc.compacttablist.CompactTabListConfig;
+import at.hannibal2.skyhanni.config.features.misc.cosmetic.CosmeticConfig;
+import at.hannibal2.skyhanni.config.features.misc.pets.PetConfig;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.Category;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class MiscConfig {
+
+ @Expose
+ @Category(name = "Pets", desc = "Pets Settings")
+ public PetConfig pets = new PetConfig();
+
+ @ConfigOption(name = "Hide Armor", desc = "")
+ @Accordion
+ @Expose
+ public HideArmorConfig hideArmor2 = new HideArmorConfig();
+
+ @Expose
+ @ConfigOption(name = "Potion Effects", desc = "")
+ @Accordion
+ public PotionEffectsConfig potionEffect = new PotionEffectsConfig();
+
+ @Expose
+ @ConfigOption(name = "Particle Hider", desc = "")
+ @Accordion
+ public ParticleHiderConfig particleHiders = new ParticleHiderConfig();
+
+ @Expose
+ @ConfigOption(name = "Estimated Item Value", desc = "(Prices for Enchantments, Reforge Stones, Gemstones, Drill Parts and more)")
+ @Accordion
+ public EstimatedItemValueConfig estimatedItemValues = new EstimatedItemValueConfig();
+
+ @ConfigOption(name = "Discord Rich Presence", desc = "")
+ @Accordion
+ @Expose
+ public DiscordRPCConfig discordRPC = new DiscordRPCConfig();
+
+ @ConfigOption(name = "Trevor The Trapper", desc = "")
+ @Accordion
+ @Expose
+ public TrevorTheTrapperConfig trevorTheTrapper = new TrevorTheTrapperConfig();
+
+ @ConfigOption(name = "Teleport Pads On Private Island", desc = "")
+ @Accordion
+ @Expose
+ public TeleportPadConfig teleportPad = new TeleportPadConfig();
+
+ @ConfigOption(name = "Pocket Sack-In-A-Sack", desc = "")
+ @Accordion
+ @Expose
+ public PocketSackInASackConfig pocketSackInASack = new PocketSackInASackConfig();
+
+ @ConfigOption(name = "Quick Mod Menu Switch", desc = "")
+ @Accordion
+ @Expose
+ public QuickModMenuSwitchConfig quickModMenuSwitch = new QuickModMenuSwitchConfig();
+
+ @Expose
+ @Category(name = "Cosmetic", desc = "Cosmetics Settings")
+ public CosmeticConfig cosmetic = new CosmeticConfig();
+
+
+ @Expose
+ @ConfigOption(name = "Glowing Dropped Items", desc = "")
+ @Accordion
+ public GlowingDroppedItemsConfig glowingDroppedItems = new GlowingDroppedItemsConfig();
+
+ @Expose
+ @ConfigOption(name = "Highlight Party Members", desc = "")
+ @Accordion
+ public HighlightPartyMembersConfig highlightPartyMembers = new HighlightPartyMembersConfig();
+
+ @Expose
+ @Category(name = "Compact Tab List", desc = "Compact Tab List Settings")
+ @Accordion
+ public CompactTabListConfig compactTabList = new CompactTabListConfig();
+
+ @Expose
+ @ConfigOption(name = "Kick Duration", desc = "")
+ @Accordion
+ public KickDurationConfig kickDuration = new KickDurationConfig();
+
+ @Expose
+ @ConfigOption(name = "Exp Bottles", desc = "Hides all the experience orbs lying on the ground.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideExpBottles = false;
+
+ @Expose
+ public Position collectionCounterPos = new Position(10, 10, false, true);
+
+ @Expose
+ @ConfigOption(name = "Brewing Stand Overlay", desc = "Display the Item names directly inside the Brewing Stand.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean brewingStandOverlay = true;
+
+ @Expose
+ @ConfigOption(name = "Red Scoreboard Numbers", desc = "Hide the red scoreboard numbers on the right side of the screen.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideScoreboardNumbers = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Piggy", desc = "Replacing 'Piggy' with 'Purse' in the Scoreboard.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hidePiggyScoreboard = true;
+
+ @Expose
+ @ConfigOption(name = "Explosions Hider", desc = "Hide explosions.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideExplosions = false;
+
+ @Expose
+ @ConfigOption(name = "CH Join", desc = "Helps buy a Pass for accessing the Crystal Hollows if needed.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean crystalHollowsJoin = true;
+
+ @Expose
+ @ConfigOption(name = "Fire Overlay Hider", desc = "Hide the fire overlay (Like in Skytils).")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideFireOverlay = false;
+
+ @Expose
+ @ConfigOption(name = "Paste Into Signs", desc = "Allows you to paste the clipboard into signs when you press Ctrl + V.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean pasteIntoSigns = true;
+
+ @Expose
+ @ConfigOption(name = "Movement Speed", desc = "Show the player movement speed in blocks per second.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean playerMovementSpeed = false;
+
+ @Expose
+ public Position playerMovementSpeedPos = new Position(394, 124, false, true);
+
+ @Expose
+ @ConfigOption(name = "Pet Candy Used", desc = "Show the number of Pet Candy used on a pet.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean petCandyUsed = true;
+
+ @Expose
+ @ConfigOption(name = "Server Restart Title", desc = "Show a title with seconds remaining until the server restarts after a Game Update or Scheduled Restart.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean serverRestartTitle = true;
+
+ @Expose
+ @ConfigOption(name = "Piece Of Wizard Portal", desc = "Restore the Earned By lore line on bought Piece Of Wizard Portal.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean restorePieceOfWizardPortalLore = true;
+
+ @Expose
+ @ConfigOption(name = "Patcher Coords Waypoint", desc = "Highlight the coordinates sent by Patcher.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean patcherSendCoordWaypoint = false;
+
+
+ @Expose
+ @ConfigOption(name = "Account Upgrade Reminder", desc = "Remind you to claim account upgrades when complete.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean accountUpgradeReminder = true;
+
+ @Expose
+ @ConfigOption(name = "Superpairs Clicks Alert", desc = "Display an alert when you reach the maximum clicks gained from Chronomatron or Ultrasequencer.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean superpairsClicksAlert = false;
+
+ @Expose
+ @ConfigOption(name = "NEU Heavy Pearls", desc = "Fixing NEU Heavy Pearl detection.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean fixNeuHeavyPearls = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Time In Limbo",
+ desc = "Show the time since you entered the limbo.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean showTimeInLimbo = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Lock Mouse Message",
+ desc = "Show a message in chat when toggling the /shmouselock.")
+ @ConfigEditorBoolean
+ public boolean lockMouseLookChatMessage = true;
+
+ @Expose
+ public Position showTimeInLimboPosition = new Position(400, 200, 1.3f);
+
+ @Expose
+ public Position lockedMouseDisplay = new Position(400, 200, 0.8f);
+
+ @Expose
+ public Position inventoryLoadPos = new Position(394, 124, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/ParticleHiderConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/ParticleHiderConfig.java
new file mode 100644
index 000000000..45f7c445e
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/ParticleHiderConfig.java
@@ -0,0 +1,50 @@
+package at.hannibal2.skyhanni.config.features.misc;
+
+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 ParticleHiderConfig {
+ @Expose
+ @ConfigOption(name = "Blaze Particles", desc = "Hide Blaze particles.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideBlazeParticles = false;
+
+ @Expose
+ @ConfigOption(name = "Enderman Particles", desc = "Hide Enderman particles.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideEndermanParticles = false;
+
+ @Expose
+ @ConfigOption(name = "Fireball Particles", desc = "Hide fireball particles.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideFireballParticles = true;
+
+ @Expose
+ @ConfigOption(name = "Fire Particles", desc = "Hide particles from the fire block.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideFireBlockParticles = true;
+
+ @Expose
+ @ConfigOption(name = "Smoke Particles", desc = "Hide smoke particles.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideSmokeParticles = false;
+
+ @Expose
+ @ConfigOption(name = "Far Particles", desc = "Hide particles that are more than 40 blocks away.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideFarParticles = true;
+
+ @Expose
+ @ConfigOption(name = "Close Redstone Particles", desc = "Hide Redstone particles around the player (appear for some potion effects).")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideCloseRedstoneParticles = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/PocketSackInASackConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/PocketSackInASackConfig.java
new file mode 100644
index 000000000..c3a57d993
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/PocketSackInASackConfig.java
@@ -0,0 +1,21 @@
+package at.hannibal2.skyhanni.config.features.misc;
+
+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 PocketSackInASackConfig {
+
+ @Expose
+ @ConfigOption(name = "Show in Overlay", desc = "Show the number of Pocket Sack-In-A-Sack applied on a sack icon as an overlay.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean showOverlay = false;
+
+ @Expose
+ @ConfigOption(name = "Replace In Lore", desc = "Replace how text is displayed in lore.\nShow §eis stitched with 2/3...\n§7Instead of §eis stitched with two...")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean replaceLore = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/PotionEffectsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/PotionEffectsConfig.java
new file mode 100644
index 000000000..19711ffdb
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/PotionEffectsConfig.java
@@ -0,0 +1,24 @@
+package at.hannibal2.skyhanni.config.features.misc;
+
+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 PotionEffectsConfig {
+ @Expose
+ @ConfigOption(name = "Non God Pot Effects", desc = "Display the active potion effects that are not part of the God Pot.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean nonGodPotEffectDisplay = false;
+
+ @Expose
+ @ConfigOption(name = "Show Mixins", desc = "Include God Pot mixins in the Non God Pot Effects display.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean nonGodPotEffectShowMixins = false;
+
+ @Expose
+ public Position nonGodPotEffectPos = new Position(10, 10, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/QuickModMenuSwitchConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/QuickModMenuSwitchConfig.java
new file mode 100644
index 000000000..a1361d4a2
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/QuickModMenuSwitchConfig.java
@@ -0,0 +1,29 @@
+package at.hannibal2.skyhanni.config.features.misc;
+
+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 QuickModMenuSwitchConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Adding a mod list, allowing to quickly switch between different mod menus.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Inside Escape Menu", desc = "Show the mod list while inside the Escape menu.")
+ @ConfigEditorBoolean
+ public boolean insideEscapeMenu = true;
+
+ @Expose
+ @ConfigOption(name = "Inside Inventory", desc = "Show the mod list while inside the player inventory (no chest inventory).")
+ @ConfigEditorBoolean
+ public boolean insidePlayerInventory = false;
+
+ @Expose
+ public Position pos = new Position(-178, 143, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/TeleportPadConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/TeleportPadConfig.java
new file mode 100644
index 000000000..f16165547
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/TeleportPadConfig.java
@@ -0,0 +1,21 @@
+package at.hannibal2.skyhanni.config.features.misc;
+
+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 TeleportPadConfig {
+
+ @Expose
+ @ConfigOption(name = "Compact Name", desc = "Hide the 'Warp to' and 'No Destination' texts over teleport pads.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean compactName = false;
+
+ @Expose
+ @ConfigOption(name = "Inventory Numbers", desc = "Show the number of the teleport pads inside the 'Change Destination' inventory as stack size.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean inventoryNumbers = 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
new file mode 100644
index 000000000..0c4226034
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/TrevorTheTrapperConfig.java
@@ -0,0 +1,110 @@
+package at.hannibal2.skyhanni.config.features.misc;
+
+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.ConfigEditorDraggableList;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import org.lwjgl.input.Keyboard;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class TrevorTheTrapperConfig {
+
+ @Expose
+ @ConfigOption(
+ name = "Enable Data Tracker",
+ desc = "Tracks all of your data from doing Trevor Quests.\n" +
+ "Shows based on the setting below."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean dataTracker = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Show Between Quests",
+ desc = "Shows the tracker during and between quests otherwise it will only show during them." +
+ "Will show in the Trapper's Den regardless. §cToggle 'Enable Data Tracker' above."
+ )
+ @ConfigEditorBoolean
+ public boolean displayType = true;
+
+ @Expose
+ @ConfigOption(
+ 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"
+ }
+ )
+ public List<Integer> textFormat = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11));
+
+ @Expose
+ public Position position = new Position(10, 80, false, true);
+
+ @Expose
+ @ConfigOption(name = "Trapper Solver", desc = "Assists you in finding Trevor's mobs. §eNote: May not always work as expected. " +
+ "§cWill not help you to find rabbits or sheep in the Oasis!")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean trapperSolver = true;
+
+ @Expose
+ @ConfigOption(name = "Mob Dead Warning", desc = "Show a message when Trevor's mob dies.")
+ @ConfigEditorBoolean
+ public boolean trapperMobDiedMessage = true;
+
+ @Expose
+ @ConfigOption(name = "Warp to Trapper", desc = "Warp to Trevor's Den. Works only inside the Farming Islands.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean warpToTrapper = false;
+
+ @Expose
+ @ConfigOption(name = "Accept Trapper Quest", desc = "Click this key after the chat prompt to accept Trevor's quest.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean acceptQuest = false;
+
+ @Expose
+ @ConfigOption(name = "Trapper Hotkey", desc = "Press this key to warp to Trevor's Den or to accept the quest. " +
+ "§eRequires the relevant above settings to be toggled")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
+ public int keyBindWarpTrapper = Keyboard.KEY_NONE;
+
+
+ @Expose
+ @ConfigOption(name = "Trapper Cooldown", desc = "Change the color of Trevor and adds a cooldown over his head.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean trapperTalkCooldown = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Trapper Cooldown GUI",
+ desc = "Show the cooldown on screen in an overlay (intended for Abiphone users)."
+ )
+ @ConfigEditorBoolean
+ public boolean trapperCooldownGui = false;
+
+ @Expose
+ public Position trapperCooldownPos = new Position(10, 10, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/compacttablist/AdvancedPlayerListConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/compacttablist/AdvancedPlayerListConfig.java
new file mode 100644
index 000000000..0bd6360d6
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/compacttablist/AdvancedPlayerListConfig.java
@@ -0,0 +1,73 @@
+package at.hannibal2.skyhanni.config.features.misc.compacttablist;
+
+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 AdvancedPlayerListConfig {
+
+ @Expose
+ @ConfigOption(name = "Player Sort", desc = "Change the sort order of player names in the tab list.")
+ @ConfigEditorDropdown(values = {"Rank (Default)", "SB Level", "Name (Abc)", "Ironman/Bingo", "Party/Friends/Guild", "Random"})
+ public int playerSortOrder = 0;
+
+ @Expose
+ @ConfigOption(name = "Invert Sort", desc = "Flip the player list order on its head (also works with default rank).")
+ @ConfigEditorBoolean
+ public boolean reverseSort = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Player Icons", desc = "Hide the icons/skins of player in the tab list.")
+ @ConfigEditorBoolean
+ public boolean hidePlayerIcons = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Rank Color", desc = "Hide the player rank color.")
+ @ConfigEditorBoolean
+ public boolean hideRankColor = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Emblems", desc = "Hide the emblems behind the player name.")
+ @ConfigEditorBoolean
+ public boolean hideEmblem = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Level", desc = "Hide the SkyBlock level numbers.")
+ @ConfigEditorBoolean
+ public boolean hideLevel = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Level Brackets", desc = "Hide the gray brackets in front of and behind the level numbers.")
+ @ConfigEditorBoolean
+ public boolean hideLevelBrackets = false;
+
+ @Expose
+ @ConfigOption(name = "Level Color As Name", desc = "Use the color of the SkyBlock level for the player color.")
+ @ConfigEditorBoolean
+ public boolean useLevelColorForName = false;
+
+ @Expose
+ @ConfigOption(name = "Bingo Rank Number", desc = "Show the number of the bingo rank next to the icon. Useful if you are not so familar with bingo.")
+ @ConfigEditorBoolean
+ public boolean showBingoRankNumber = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Factions", desc = "Hide the icon of the Crimson Isle Faction in the tab list.")
+ @ConfigEditorBoolean
+ public boolean hideFactions = false;
+
+ @Expose
+ @ConfigOption(name = "Mark Special Persons", desc = "Show special icons behind the name of guild members, party members, friends, and marked players.")
+ @ConfigEditorBoolean
+ public boolean markSpecialPersons = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Mark SkyHanni Devs",
+ desc = "Adds a §c:O §7behind the tablist name of §cSkyHanni's contributors§7. " +
+ "§eThose are the folks that coded the mod for you for free :)"
+ )
+ @ConfigEditorBoolean
+ public boolean markSkyHanniContributors = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/compacttablist/CompactTabListConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/compacttablist/CompactTabListConfig.java
new file mode 100644
index 000000000..2236d886b
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/compacttablist/CompactTabListConfig.java
@@ -0,0 +1,27 @@
+package at.hannibal2.skyhanni.config.features.misc.compacttablist;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class CompactTabListConfig {
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Compacts the tablist to make it look much nicer like SBA did. Also " +
+ "doesn't break god-pot detection and shortens some other lines.")
+ //made tablist one word here so both searches will pick it up
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Hypixel Adverts", desc = "Hides text from advertising the Hypixel server or store in the tablist.")
+ @ConfigEditorBoolean
+ public boolean hideAdverts = false;
+
+ @Expose
+ @ConfigOption(name = "Advanced Player List", desc = "")
+ @Accordion
+ public AdvancedPlayerListConfig advancedPlayerList = new AdvancedPlayerListConfig();
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/cosmetic/ArrowTrailConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/cosmetic/ArrowTrailConfig.java
new file mode 100644
index 000000000..7f8a044ed
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/cosmetic/ArrowTrailConfig.java
@@ -0,0 +1,46 @@
+package at.hannibal2.skyhanni.config.features.misc.cosmetic;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class ArrowTrailConfig {
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Draw a colored line behind arrows in the air.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Nonplayer Arrows", desc = "Only shows for arrows the player has shot.")
+ @ConfigEditorBoolean
+ public boolean hideOtherArrows = true;
+
+ @Expose
+ @ConfigOption(name = "Arrow Color", desc = "Color of the line.")
+ @ConfigEditorColour
+ public String arrowColor = "0:200:85:255:85";
+
+ @Expose
+ @ConfigOption(name = "Player Arrows", desc = "Different color for the line of arrows that you have shot.")
+ @ConfigEditorBoolean
+ public boolean handlePlayerArrowsDifferently = false;
+
+ @Expose
+ @ConfigOption(name = "Player Arrow Color", desc = "Color of the line of your own arrows.")
+ @ConfigEditorColour
+ public String playerArrowColor = "0:200:85:255:255";
+
+ @Expose
+ @ConfigOption(name = "Time Alive", desc = "Time in seconds until the trail fades out.")
+ @ConfigEditorSlider(minStep = 0.1f, minValue = 0.1f, maxValue = 10)
+ public float secondsAlive = 0.5f;
+
+ @Expose
+ @ConfigOption(name = "Line Width", desc = "Width of the line.")
+ @ConfigEditorSlider(minStep = 1, minValue = 1, maxValue = 10)
+ public int lineWidth = 4;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/cosmetic/CosmeticConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/cosmetic/CosmeticConfig.java
new file mode 100644
index 000000000..80b5c6043
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/cosmetic/CosmeticConfig.java
@@ -0,0 +1,18 @@
+package at.hannibal2.skyhanni.config.features.misc.cosmetic;
+
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class CosmeticConfig {
+
+ @Expose
+ @ConfigOption(name = "Following Line", desc = "")
+ @Accordion
+ public FollowingLineConfig followingLine = new FollowingLineConfig();
+
+ @Expose
+ @ConfigOption(name = "Arrow Trail", desc = "")
+ @Accordion
+ public ArrowTrailConfig arrowTrail = new ArrowTrailConfig();
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/cosmetic/FollowingLineConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/cosmetic/FollowingLineConfig.java
new file mode 100644
index 000000000..87f846e71
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/cosmetic/FollowingLineConfig.java
@@ -0,0 +1,37 @@
+package at.hannibal2.skyhanni.config.features.misc.cosmetic;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class FollowingLineConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Draw a colored line behind the player.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Line Color", desc = "Color of the line.")
+ @ConfigEditorColour
+ public String lineColor = "0:255:255:255:255";
+
+ @Expose
+ @ConfigOption(name = "Time Alive", desc = "Time in seconds until the line fades out.")
+ @ConfigEditorSlider(minStep = 1, minValue = 1, maxValue = 30)
+ public int secondsAlive = 3;
+
+ @Expose
+ @ConfigOption(name = "Max Line Width", desc = "Max width of the line.")
+ @ConfigEditorSlider(minStep = 1, minValue = 1, maxValue = 10)
+ public int lineWidth = 4;
+
+ @Expose
+ @ConfigOption(name = "Behind Blocks", desc = "Show behind blocks.")
+ @ConfigEditorBoolean
+ public boolean behindBlocks = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/pets/PetConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/pets/PetConfig.java
new file mode 100644
index 000000000..c6a32cee9
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/pets/PetConfig.java
@@ -0,0 +1,24 @@
+package at.hannibal2.skyhanni.config.features.misc.pets;
+
+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.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class PetConfig {
+ @Expose
+ @ConfigOption(name = "Pet Display", desc = "Show the currently active pet.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean display = false;
+
+ @Expose
+ public Position displayPos = new Position(-330, -15, false, true);
+
+ @Expose
+ @ConfigOption(name = "Pet Experience Tooltip", desc = "")
+ @Accordion
+ public PetExperienceToolTipConfig petExperienceToolTip = new PetExperienceToolTipConfig();
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/pets/PetExperienceToolTipConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/pets/PetExperienceToolTipConfig.java
new file mode 100644
index 000000000..71ad44ba3
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/pets/PetExperienceToolTipConfig.java
@@ -0,0 +1,27 @@
+package at.hannibal2.skyhanni.config.features.misc.pets;
+
+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 PetExperienceToolTipConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Show the full pet exp and the progress to level 100 (ignoring rarity) when hovering over a pet while pressing shift key.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean petDisplay = true;
+
+
+ @Expose
+ @ConfigOption(name = "Show Always", desc = "Show this info always, even if not pressing shift key.")
+ @ConfigEditorBoolean
+ public boolean showAlways = false;
+
+ @Expose
+ @ConfigOption(name = "Dragon Egg", desc = "For a Golden Dragon Egg, show progress to level 100 instead of 200.")
+ @ConfigEditorBoolean
+ public boolean showGoldenDragonEgg = true;
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/CruxTalismanDisplayConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/CruxTalismanDisplayConfig.java
new file mode 100644
index 000000000..fc69df292
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/CruxTalismanDisplayConfig.java
@@ -0,0 +1,30 @@
+package at.hannibal2.skyhanni.config.features.rift;
+
+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;
+import io.github.moulberry.moulconfig.observer.Property;
+
+public class CruxTalismanDisplayConfig {
+ @Expose
+ @ConfigOption(name = "Crux Talisman Display", desc = "Display progress of the Crux Talisman on screen.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Compact", desc = "Show a compacted version of the overlay when the talisman is maxed.")
+ @ConfigEditorBoolean
+ public boolean compactWhenMaxed = false;
+
+ @Expose
+ @ConfigOption(name = "Show Bonuses", desc = "Show bonuses you get from the talisman.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public Property<Boolean> showBonuses = Property.of(true);
+
+ @Expose
+ public Position position = new Position(144, 139, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/EnigmaSoulConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/EnigmaSoulConfig.java
new file mode 100644
index 000000000..9b80b718d
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/EnigmaSoulConfig.java
@@ -0,0 +1,22 @@
+package at.hannibal2.skyhanni.config.features.rift;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class EnigmaSoulConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Click on Enigma Souls in Rift Guides to highlight their location.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Color", desc = "Color of the Enigma Souls.")
+ @ConfigEditorColour
+ public String color = "0:120:13:49:255";
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/MotesOrbsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/MotesOrbsConfig.java
new file mode 100644
index 000000000..ebcdb2e57
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/MotesOrbsConfig.java
@@ -0,0 +1,28 @@
+package at.hannibal2.skyhanni.config.features.rift;
+
+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.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class MotesOrbsConfig {
+
+ @Expose
+ @ConfigOption(name = "Highlight Motes Orbs", desc = "Highlight flying Motes Orbs.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Highlight Size", desc = "Set render size for highlighted Motes Orbs.")
+ @ConfigEditorSlider(minStep = 1, minValue = 1, maxValue = 5)
+ public int size = 3;
+
+ @Expose
+ @ConfigOption(name = "Hide Particles", desc = "Hide normal Motes Orbs particles.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideParticles = false;
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/RiftConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/RiftConfig.java
new file mode 100644
index 000000000..ca20e01f9
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/RiftConfig.java
@@ -0,0 +1,53 @@
+package at.hannibal2.skyhanni.config.features.rift;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.features.rift.area.RiftAreasConfig;
+import at.hannibal2.skyhanni.config.features.rift.motes.MotesConfig;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.Category;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class RiftConfig {
+
+ @ConfigOption(name = "Rift Timer", desc = "")
+ @Accordion
+ @Expose
+ public RiftTimerConfig timer = new RiftTimerConfig();
+
+ @ConfigOption(name = "Crux Talisman Progress", desc = "")
+ @Accordion
+ @Expose
+ public CruxTalismanDisplayConfig cruxTalisman = new CruxTalismanDisplayConfig();
+
+ @ConfigOption(name = "Enigma Soul Waypoints", desc = "")
+ @Accordion
+ @Expose
+ public EnigmaSoulConfig enigmaSoulWaypoints = new EnigmaSoulConfig();
+
+ @Category(name = "Rift Areas", desc = "Rift Area Settings")
+ @Expose
+ public RiftAreasConfig area = new RiftAreasConfig();
+
+ @Expose
+ @Category(name = "Motes", desc = "Motes Sell Price")
+ public MotesConfig motes = new MotesConfig();
+
+ @Expose
+ @ConfigOption(name = "Motes Orbs", desc = "")
+ @Accordion
+ public MotesOrbsConfig motesOrbs = new MotesOrbsConfig();
+
+ @Expose
+ @ConfigOption(name = "Highlight Guide", desc = "Highlight things to do in the Rift Guide.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlightGuide = true;
+
+ @Expose
+ @ConfigOption(name = "Horsezooka Hider", desc = "Hide horses while holding the Horsezooka in the hand.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean horsezookaHider = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/RiftTimerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/RiftTimerConfig.java
new file mode 100644
index 000000000..f1c7f32dd
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/RiftTimerConfig.java
@@ -0,0 +1,30 @@
+package at.hannibal2.skyhanni.config.features.rift;
+
+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 RiftTimerConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Show the remaining rift time, max time, percentage, and extra time changes.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Max Time", desc = "Show max time.")
+ @ConfigEditorBoolean
+ public boolean maxTime = true;
+
+ @Expose
+ @ConfigOption(name = "Percentage", desc = "Show percentage.")
+ @ConfigEditorBoolean
+ public boolean percentage = true;
+
+ @Expose
+ public Position timerPosition = new Position(10, 10, false, true);
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/RiftAreasConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/RiftAreasConfig.java
new file mode 100644
index 000000000..397eb2b90
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/RiftAreasConfig.java
@@ -0,0 +1,60 @@
+package at.hannibal2.skyhanni.config.features.rift.area;
+
+import at.hannibal2.skyhanni.config.features.rift.area.colosseum.ColosseumConfig;
+import at.hannibal2.skyhanni.config.features.rift.area.dreadfarm.DreadfarmConfig;
+import at.hannibal2.skyhanni.config.features.rift.area.livingcave.LivingCaveConfig;
+import at.hannibal2.skyhanni.config.features.rift.area.mirrorverse.MirrorVerseConfig;
+import at.hannibal2.skyhanni.config.features.rift.area.stillgorechateau.StillgoreChateauConfig;
+import at.hannibal2.skyhanni.config.features.rift.area.westvillage.WestVillageConfig;
+import at.hannibal2.skyhanni.config.features.rift.area.wyldwoods.WyldWoodsConfig;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class RiftAreasConfig {
+
+ @ConfigOption(name = "Wyld Woods", desc = "")
+ @Accordion
+ @Expose
+ public WyldWoodsConfig wyldWoods = new WyldWoodsConfig();
+
+ @ConfigOption(name = "West Village", desc = "")
+ @Accordion
+ @Expose
+ public WestVillageConfig westVillage = new WestVillageConfig();
+
+ @Expose
+ @ConfigOption(name = "Dreadfarm", desc = "")
+ @Accordion
+ public DreadfarmConfig dreadfarm = new DreadfarmConfig();
+
+ @ConfigOption(name = "Mirrorverse", desc = "")
+ @Accordion
+ @Expose
+ public MirrorVerseConfig mirrorverse = new MirrorVerseConfig();
+
+// @Expose
+// @ConfigOption(name = "Village Plaza", desc = "")
+// @Accordion
+// public VillagePlazaConfig villagePlaza = new VillagePlazaConfig();
+
+ @Expose
+ @ConfigOption(name = "Living Cave", desc = "")
+ @Accordion
+ public LivingCaveConfig livingCave = new LivingCaveConfig();
+
+ @Expose
+ @ConfigOption(name = "Colosseum", desc = "")
+ @Accordion
+ public ColosseumConfig colosseum = new ColosseumConfig();
+
+ @Expose
+ @ConfigOption(name = "Stillgore Chateau", desc = "")
+ @Accordion
+ public StillgoreChateauConfig stillgoreChateau = new StillgoreChateauConfig();
+
+// @Expose
+// @ConfigOption(name = "Mountaintop", desc = "")
+// @Accordion
+// public MountaintopConfig mountaintop = new MountaintopConfig();
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/colosseum/ColosseumConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/colosseum/ColosseumConfig.java
new file mode 100644
index 000000000..d9a662f0d
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/colosseum/ColosseumConfig.java
@@ -0,0 +1,15 @@
+package at.hannibal2.skyhanni.config.features.rift.area.colosseum;
+
+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 ColosseumConfig {
+
+ @Expose
+ @ConfigOption(name = "Highlight Blobbercysts", desc = "Highlight Blobbercysts in Bacte fight.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlightBlobbercysts = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/dreadfarm/DreadfarmConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/dreadfarm/DreadfarmConfig.java
new file mode 100644
index 000000000..9a17c70b8
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/dreadfarm/DreadfarmConfig.java
@@ -0,0 +1,26 @@
+package at.hannibal2.skyhanni.config.features.rift.area.dreadfarm;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class DreadfarmConfig {
+ @Expose
+ @ConfigOption(name = "Agaricus Cap", desc = "Counts down the time until §eAgaricus Cap (Mushroom) " +
+ "§7changes color from brown to red and is breakable.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean agaricusCap = true;
+
+ @ConfigOption(name = "Volt Crux", desc = "")
+ @Accordion
+ @Expose
+ public VoltCruxConfig voltCrux = new VoltCruxConfig();
+
+ @ConfigOption(name = "Wilted Berberis", desc = "")
+ @Accordion
+ @Expose
+ public WiltedBerberisConfig wiltedBerberis = new WiltedBerberisConfig();
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/dreadfarm/VoltCruxConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/dreadfarm/VoltCruxConfig.java
new file mode 100644
index 000000000..307e57d45
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/dreadfarm/VoltCruxConfig.java
@@ -0,0 +1,33 @@
+package at.hannibal2.skyhanni.config.features.rift.area.dreadfarm;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class VoltCruxConfig {
+
+ @Expose
+ @ConfigOption(name = "Volt Warning", desc = "Shows a warning while a Volt is discharging lightning.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean voltWarning = true;
+
+ @Expose
+ @ConfigOption(name = "Volt Range Highlighter", desc = "Shows the area in which a Volt might strike lightning.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean voltRange = true;
+
+ @Expose
+ @ConfigOption(name = "Volt Range Highlighter Color", desc = "In which color should the Volt range be highlighted?")
+ @ConfigEditorColour
+ public String voltColour = "0:60:0:0:255";
+
+ @Expose
+ @ConfigOption(name = "Volt Mood Color", desc = "Change the color of the Volt enemy depending on their mood.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean voltMoodMeter = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/dreadfarm/WiltedBerberisConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/dreadfarm/WiltedBerberisConfig.java
new file mode 100644
index 000000000..9cad5a475
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/dreadfarm/WiltedBerberisConfig.java
@@ -0,0 +1,26 @@
+package at.hannibal2.skyhanni.config.features.rift.area.dreadfarm;
+
+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 WiltedBerberisConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Show Wilted Berberis helper.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Only on Farmland", desc = "Only show the helper while standing on Farmland blocks.")
+ @ConfigEditorBoolean
+ public boolean onlyOnFarmland = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Particles", desc = "Hide the Wilted Berberis particles.")
+ @ConfigEditorBoolean
+ public boolean hideparticles = false;
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/livingcave/DefenseBlockConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/livingcave/DefenseBlockConfig.java
new file mode 100644
index 000000000..1754afb1e
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/livingcave/DefenseBlockConfig.java
@@ -0,0 +1,29 @@
+package at.hannibal2.skyhanni.config.features.rift.area.livingcave;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import io.github.moulberry.moulconfig.observer.Property;
+
+public class DefenseBlockConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Show a line between Defense blocks and the mob and highlight the blocks.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Hide Particles", desc = "Hide particles around Defense Blocks.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideParticles = false;
+
+ @Expose
+ @ConfigOption(name = "Color", desc = "Set the color of the lines, blocks and the entity.")
+ @ConfigEditorColour
+ public Property<String> color = Property.of("0:255:77:104:255");
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/livingcave/LivingCaveConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/livingcave/LivingCaveConfig.java
new file mode 100644
index 000000000..620238538
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/livingcave/LivingCaveConfig.java
@@ -0,0 +1,23 @@
+package at.hannibal2.skyhanni.config.features.rift.area.livingcave;
+
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class LivingCaveConfig {
+
+ @Expose
+ @ConfigOption(name = "Living Metal Suit Progress", desc = "")
+ @Accordion
+ public LivingMetalSuitProgressConfig livingMetalSuitProgress = new LivingMetalSuitProgressConfig();
+
+ @Expose
+ @ConfigOption(name = "Defense Blocks", desc = "")
+ @Accordion
+ public DefenseBlockConfig defenseBlockConfig = new DefenseBlockConfig();
+
+ @Expose
+ @ConfigOption(name = "Living Metal Helper", desc = "")
+ @Accordion
+ public LivingCaveLivingMetalConfig livingCaveLivingMetalConfig = new LivingCaveLivingMetalConfig();
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/livingcave/LivingCaveLivingMetalConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/livingcave/LivingCaveLivingMetalConfig.java
new file mode 100644
index 000000000..aab75d571
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/livingcave/LivingCaveLivingMetalConfig.java
@@ -0,0 +1,22 @@
+package at.hannibal2.skyhanni.config.features.rift.area.livingcave;
+
+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 LivingCaveLivingMetalConfig {
+
+ @Expose
+ @ConfigOption(name = "Living Metal", desc = "Show a moving animation between Living Metal and the next block.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Hide Particles", desc = "Hide Living Metal particles.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideParticles = false;
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/livingcave/LivingMetalSuitProgressConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/livingcave/LivingMetalSuitProgressConfig.java
new file mode 100644
index 000000000..d24520dc1
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/livingcave/LivingMetalSuitProgressConfig.java
@@ -0,0 +1,24 @@
+package at.hannibal2.skyhanni.config.features.rift.area.livingcave;
+
+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 LivingMetalSuitProgressConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Display Living Metal Suit progress.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Compact", desc = "Show a compacted version of the overlay when the set is maxed.")
+ @ConfigEditorBoolean
+ public boolean compactWhenMaxed = false;
+
+ @Expose
+ public Position position = new Position(100, 100);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/LavaMazeConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/LavaMazeConfig.java
new file mode 100644
index 000000000..b3198cc4c
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/LavaMazeConfig.java
@@ -0,0 +1,39 @@
+package at.hannibal2.skyhanni.config.features.rift.area.mirrorverse;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import io.github.moulberry.moulconfig.observer.Property;
+
+public class LavaMazeConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Helps solving the lava maze in the Mirrorverse by showing the correct way.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Look Ahead", desc = "Change how many platforms should be shown in front of you.")
+ @ConfigEditorSlider(minStep = 1, maxValue = 30, minValue = 1)
+ public Property<Integer> lookAhead = Property.of(3);
+
+ @Expose
+ @ConfigOption(name = "Rainbow Color", desc = "Show the rainbow color effect instead of a boring monochrome.")
+ @ConfigEditorBoolean
+ public Property<Boolean> rainbowColor = Property.of(true);
+
+ @Expose
+ @ConfigOption(name = "Monochrome Color", desc = "Set a boring monochrome color for the parkour platforms.")
+ @ConfigEditorColour
+ public Property<String> monochromeColor = Property.of("0:60:0:0:255");
+
+ @Expose
+ @ConfigOption(name = "Hide Others Players", desc = "Hide other players while doing the lava maze.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hidePlayers = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/MirrorVerseConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/MirrorVerseConfig.java
new file mode 100644
index 000000000..e93324972
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/MirrorVerseConfig.java
@@ -0,0 +1,29 @@
+package at.hannibal2.skyhanni.config.features.rift.area.mirrorverse;
+
+import at.hannibal2.skyhanni.config.features.rift.area.mirrorverse.danceroomhelper.DanceRoomHelperConfig;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class MirrorVerseConfig {
+
+ @ConfigOption(name = "Lava Maze", desc = "")
+ @Accordion
+ @Expose
+ public LavaMazeConfig lavaMazeConfig = new LavaMazeConfig();
+
+ @ConfigOption(name = "Upside Down Parkour", desc = "")
+ @Accordion
+ @Expose
+ public UpsideDownParkourConfig upsideDownParkour = new UpsideDownParkourConfig();
+
+ @ConfigOption(name = "Dance Room Helper", desc = "")
+ @Accordion
+ @Expose
+ public DanceRoomHelperConfig danceRoomHelper = new DanceRoomHelperConfig();
+
+ @ConfigOption(name = "Tubulator", desc = "")
+ @Accordion
+ @Expose
+ public TubulatorConfig tubulatorConfig = new TubulatorConfig();
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/TubulatorConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/TubulatorConfig.java
new file mode 100644
index 000000000..586ce2f4e
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/TubulatorConfig.java
@@ -0,0 +1,44 @@
+package at.hannibal2.skyhanni.config.features.rift.area.mirrorverse;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import io.github.moulberry.moulconfig.observer.Property;
+
+public class TubulatorConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Highlights the location of the invisible Tubulator blocks (Laser Parkour).")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Look Ahead", desc = "Change how many platforms should be shown in front of you.")
+ @ConfigEditorSlider(minStep = 1, maxValue = 30, minValue = 1)
+ public Property<Integer> lookAhead = Property.of(2);
+
+ @Expose
+ @ConfigOption(name = "Outline", desc = "Outlines the top edge of the platforms.")
+ @ConfigEditorBoolean
+ public boolean outline = true;
+
+ @Expose
+ @ConfigOption(name = "Rainbow Color", desc = "Show the rainbow color effect instead of a boring monochrome.")
+ @ConfigEditorBoolean
+ public Property<Boolean> rainbowColor = Property.of(true);
+
+ @Expose
+ @ConfigOption(name = "Monochrome Color", desc = "Set a boring monochrome color for the parkour platforms.")
+ @ConfigEditorColour
+ public Property<String> monochromeColor = Property.of("0:60:0:0:255");
+
+ @Expose
+ @ConfigOption(name = "Hide Other Players", desc = "Hide other players while doing the lava maze.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hidePlayers = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/UpsideDownParkourConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/UpsideDownParkourConfig.java
new file mode 100644
index 000000000..e8712f310
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/UpsideDownParkourConfig.java
@@ -0,0 +1,44 @@
+package at.hannibal2.skyhanni.config.features.rift.area.mirrorverse;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import io.github.moulberry.moulconfig.observer.Property;
+
+public class UpsideDownParkourConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Helps solving the upside down parkour in the Mirrorverse by showing the correct way.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Look Ahead", desc = "Change how many platforms should be shown in front of you.")
+ @ConfigEditorSlider(minStep = 1, maxValue = 9, minValue = 1)
+ public Property<Integer> lookAhead = Property.of(3);
+
+ @Expose
+ @ConfigOption(name = "Outline", desc = "Outlines the top edge of the platforms.")
+ @ConfigEditorBoolean
+ public boolean outline = true;
+
+ @Expose
+ @ConfigOption(name = "Rainbow Color", desc = "Show the rainbow color effect instead of a boring monochrome.")
+ @ConfigEditorBoolean
+ public Property<Boolean> rainbowColor = Property.of(true);
+
+ @Expose
+ @ConfigOption(name = "Monochrome Color", desc = "Set a boring monochrome color for the parkour platforms.")
+ @ConfigEditorColour
+ public Property<String> monochromeColor = Property.of("0:60:0:0:255");
+
+ @Expose
+ @ConfigOption(name = "Hide Others Players", desc = "Hide other players while doing the upside down parkour.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hidePlayers = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/danceroomhelper/DanceRoomHelperConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/danceroomhelper/DanceRoomHelperConfig.java
new file mode 100644
index 000000000..a5b61aee8
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/danceroomhelper/DanceRoomHelperConfig.java
@@ -0,0 +1,48 @@
+package at.hannibal2.skyhanni.config.features.rift.area.mirrorverse.danceroomhelper;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.core.config.Position;
+import at.hannibal2.skyhanni.config.features.rift.area.mirrorverse.danceroomhelper.danceroomformatting.DanceRoomFormattingConfig;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class DanceRoomHelperConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Helps to solve the dance room in the Mirrorverse by showing multiple tasks at once.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Lines to Show", desc = "How many tasks you should see.")
+ @ConfigEditorSlider(minStep = 1, maxValue = 49, minValue = 1)
+ public int lineToShow = 3;
+
+ @Expose
+ @ConfigOption(name = "Space", desc = "Change the space between each line.")
+ @ConfigEditorSlider(minStep = 1, maxValue = 10, minValue = -5)
+ public int extraSpace = 0;
+
+ @Expose
+ @ConfigOption(name = "Hide Other Players", desc = "Hide other players inside the dance room.")
+ @ConfigEditorBoolean
+ public boolean hidePlayers = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Title", desc = "Hide Instructions, \"§aIt's happening!\" §7and \"§aKeep it up!\" §7titles.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideOriginalTitle = false;
+
+ @Expose
+ @ConfigOption(name = "Formatting", desc = "")
+ @Accordion
+ public DanceRoomFormattingConfig danceRoomFormatting = new DanceRoomFormattingConfig();
+
+ @Expose
+ public Position position = new Position(442, 239, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/danceroomhelper/danceroomformatting/ColorConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/danceroomhelper/danceroomformatting/ColorConfig.java
new file mode 100644
index 000000000..71f3013a6
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/danceroomhelper/danceroomformatting/ColorConfig.java
@@ -0,0 +1,42 @@
+package at.hannibal2.skyhanni.config.features.rift.area.mirrorverse.danceroomhelper.danceroomformatting;
+
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorText;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class ColorConfig {
+ @Expose
+ @ConfigOption(name = "Move", desc = "Color for the Move instruction")
+ @ConfigEditorText
+ public String move = "&e";
+
+ @Expose
+ @ConfigOption(name = "Stand", desc = "Color for the Stand instruction")
+ @ConfigEditorText
+ public String stand = "&e";
+
+ @Expose
+ @ConfigOption(name = "Sneak", desc = "Color for the Sneak instruction")
+ @ConfigEditorText
+ public String sneak = "&5";
+
+ @Expose
+ @ConfigOption(name = "Jump", desc = "Color for the Jump instruction")
+ @ConfigEditorText
+ public String jump = "&b";
+
+ @Expose
+ @ConfigOption(name = "Punch", desc = "Color for the Punch instruction")
+ @ConfigEditorText
+ public String punch = "&d";
+
+ @Expose
+ @ConfigOption(name = "Countdown", desc = "Color for the Countdown")
+ @ConfigEditorText
+ public String countdown = "&f";
+
+ @Expose
+ @ConfigOption(name = "Default", desc = "Fallback color")
+ @ConfigEditorText
+ public String fallback = "&f";
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/danceroomhelper/danceroomformatting/DanceRoomFormattingConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/danceroomhelper/danceroomformatting/DanceRoomFormattingConfig.java
new file mode 100644
index 000000000..1c35a3924
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/mirrorverse/danceroomhelper/danceroomformatting/DanceRoomFormattingConfig.java
@@ -0,0 +1,29 @@
+package at.hannibal2.skyhanni.config.features.rift.area.mirrorverse.danceroomhelper.danceroomformatting;
+
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorText;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class DanceRoomFormattingConfig {
+
+ @Expose
+ @ConfigOption(name = "Now", desc = "Formatting for \"Now:\"")
+ @ConfigEditorText
+ public String now = "&7Now:";
+
+ @Expose
+ @ConfigOption(name = "Next", desc = "Formatting for \"Next:\"")
+ @ConfigEditorText
+ public String next = "&7Next:";
+
+ @Expose
+ @ConfigOption(name = "Later", desc = "Formatting for \"Later:\"")
+ @ConfigEditorText
+ public String later = "&7Later:";
+
+ @Expose
+ @ConfigOption(name = "Color Option", desc = "")
+ @Accordion
+ public ColorConfig color = new ColorConfig();
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/stillgorechateau/EffigiesConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/stillgorechateau/EffigiesConfig.java
new file mode 100644
index 000000000..62a20c0e0
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/stillgorechateau/EffigiesConfig.java
@@ -0,0 +1,37 @@
+package at.hannibal2.skyhanni.config.features.rift.area.stillgorechateau;
+
+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.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class EffigiesConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Show locations of inactive Blood Effigies.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Respawning Soon", desc = "Show effigies that are about to respawn.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean respawningSoon = false;
+
+ @Expose
+ @ConfigOption(name = "Respawning Time", desc = "Time before effigies respawn to show.")
+ @ConfigEditorSlider(
+ minValue = 1,
+ maxValue = 15,
+ minStep = 1
+ )
+ public int respwningSoonTime = 3;
+
+ @Expose
+ @ConfigOption(name = "Unknown Times", desc = "Show effigies without known time.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean unknownTime = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/stillgorechateau/StillgoreChateauConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/stillgorechateau/StillgoreChateauConfig.java
new file mode 100644
index 000000000..761b7c1d2
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/stillgorechateau/StillgoreChateauConfig.java
@@ -0,0 +1,14 @@
+package at.hannibal2.skyhanni.config.features.rift.area.stillgorechateau;
+
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class StillgoreChateauConfig {
+
+ @Expose
+ @ConfigOption(name = "Blood Effigies", desc = "")
+ @Accordion
+ public EffigiesConfig bloodEffigies = new EffigiesConfig();
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/westvillage/KloonHackingConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/westvillage/KloonHackingConfig.java
new file mode 100644
index 000000000..346747aab
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/westvillage/KloonHackingConfig.java
@@ -0,0 +1,27 @@
+package at.hannibal2.skyhanni.config.features.rift.area.westvillage;
+
+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 KloonHackingConfig {
+
+ @Expose
+ @ConfigOption(name = "Hacking Solver", desc = "Highlights the correct button to click in the hacking inventory.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean solver = true;
+
+ @Expose
+ @ConfigOption(name = "Color Guide", desc = "Tells you which color to pick.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean colour = true;
+
+ @Expose
+ @ConfigOption(name = "Terminal Waypoints", desc = "While wearing the helmet, waypoints will appear at each terminal location.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean waypoints = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/westvillage/WestVillageConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/westvillage/WestVillageConfig.java
new file mode 100644
index 000000000..273080489
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/westvillage/WestVillageConfig.java
@@ -0,0 +1,13 @@
+package at.hannibal2.skyhanni.config.features.rift.area.westvillage;
+
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class WestVillageConfig {
+
+ @ConfigOption(name = "Kloon Hacking", desc = "")
+ @Accordion
+ @Expose
+ public KloonHackingConfig hacking = new KloonHackingConfig();
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/wyldwoods/LarvasConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/wyldwoods/LarvasConfig.java
new file mode 100644
index 000000000..b7a7aa240
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/wyldwoods/LarvasConfig.java
@@ -0,0 +1,22 @@
+package at.hannibal2.skyhanni.config.features.rift.area.wyldwoods;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class LarvasConfig {
+
+ @Expose
+ @ConfigOption(name = "Highlight", desc = "Highlight §cLarvas on trees §7while holding a §eLarva Hook §7in the hand.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlight = true;
+
+ @Expose
+ @ConfigOption(name = "Color", desc = "Color of the Larvas.")
+ @ConfigEditorColour
+ public String highlightColor = "0:120:13:49:255";
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/wyldwoods/OdonataConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/wyldwoods/OdonataConfig.java
new file mode 100644
index 000000000..e32e9e01b
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/wyldwoods/OdonataConfig.java
@@ -0,0 +1,23 @@
+package at.hannibal2.skyhanni.config.features.rift.area.wyldwoods;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class OdonataConfig {
+
+ @Expose
+ @ConfigOption(name = "Highlight", desc = "Highlight the small §cOdonatas §7flying around the trees while holding an " +
+ "§eEmpty Odonata Bottle §7in the hand.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlight = true;
+
+ @Expose
+ @ConfigOption(name = "Color", desc = "Color of the Odonatas.")
+ @ConfigEditorColour
+ public String highlightColor = "0:120:13:49:255";
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/wyldwoods/WyldWoodsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/wyldwoods/WyldWoodsConfig.java
new file mode 100644
index 000000000..3eae50fb5
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/area/wyldwoods/WyldWoodsConfig.java
@@ -0,0 +1,27 @@
+package at.hannibal2.skyhanni.config.features.rift.area.wyldwoods;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class WyldWoodsConfig {
+
+ @Expose
+ @ConfigOption(name = "Shy Crux Warning", desc = "Shows a warning when a Shy Crux is going to steal your time. " +
+ "Useful if you play without volume.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean shyWarning = true;
+
+ @ConfigOption(name = "Larvas", desc = "")
+ @Accordion
+ @Expose
+ public LarvasConfig larvas = new LarvasConfig();
+
+ @ConfigOption(name = "Odonatas", desc = "")
+ @Accordion
+ @Expose
+ public OdonataConfig odonata = new OdonataConfig();
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/motes/InventoryValueConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/motes/InventoryValueConfig.java
new file mode 100644
index 000000000..297a83a1c
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/motes/InventoryValueConfig.java
@@ -0,0 +1,25 @@
+package at.hannibal2.skyhanni.config.features.rift.motes;
+
+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.ConfigOption;
+
+public class InventoryValueConfig {
+ @Expose
+ @ConfigOption(name = "Inventory Value", desc = "Show total Motes NPC price for the current opened inventory.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Number Format Type", desc = "Short: 1.2M\n" +
+ "Long: 1,200,000")
+ @ConfigEditorDropdown(values = {"Short", "Long"})
+ public int formatType = 0;
+
+ @Expose
+ public Position position = new Position(126, 156, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/rift/motes/MotesConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/rift/motes/MotesConfig.java
new file mode 100644
index 000000000..2a65a6652
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/rift/motes/MotesConfig.java
@@ -0,0 +1,27 @@
+package at.hannibal2.skyhanni.config.features.rift.motes;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class MotesConfig {
+
+ @Expose
+ @ConfigOption(name = "Show Motes Price", desc = "Show the Motes NPC price in the item lore.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean showPrice = true;
+
+ @Expose
+ @ConfigOption(name = "Burger Stacks", desc = "Set your McGrubber's burger stacks.")
+ @ConfigEditorSlider(minStep = 1, minValue = 0, maxValue = 5)
+ public int burgerStacks = 0;
+
+ @Expose
+ @ConfigOption(name = "Inventory Value", desc = "")
+ @Accordion
+ public InventoryValueConfig inventoryValue = new InventoryValueConfig();
+}
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
new file mode 100644
index 000000000..a7bc636db
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/ItemProfitTrackerConfig.java
@@ -0,0 +1,50 @@
+package at.hannibal2.skyhanni.config.features.slayer;
+
+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;
+
+public class ItemProfitTrackerConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Count all items you pick up while doing slayer, " +
+ "keep track of how much you pay for starting slayers and calculating the overall profit.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ public Position pos = new Position(20, 20, false, true);
+
+ @Expose
+ @ConfigOption(name = "Price in Chat", desc = "Show an extra chat message when you pick up an item. " +
+ "(This contains name, amount and price)")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ 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;
+
+ @Expose
+ @ConfigOption(name = "Title Warning", desc = "Show a title for expensive item pickups.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean titleWarning = false;
+
+ @Expose
+ @ConfigOption(name = "Title Price", desc = "Items above this price will show up as a title.")
+ @ConfigEditorSlider(minValue = 1, maxValue = 20_000_000, minStep = 1)
+ public int minimumPriceWarning = 500_000;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/ItemsOnGroundConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/ItemsOnGroundConfig.java
new file mode 100644
index 000000000..4f3e2428d
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/ItemsOnGroundConfig.java
@@ -0,0 +1,21 @@
+package at.hannibal2.skyhanni.config.features.slayer;
+
+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.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class ItemsOnGroundConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Show the name and price of items laying on the ground. §cOnly in slayer areas!")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Minimum Price", desc = "Items below this price will be ignored.")
+ @ConfigEditorSlider(minValue = 1, maxValue = 1_000_000, minStep = 1)
+ public int minimumPrice = 50_000;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/RngMeterDisplayConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/RngMeterDisplayConfig.java
new file mode 100644
index 000000000..04b6c6704
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/RngMeterDisplayConfig.java
@@ -0,0 +1,30 @@
+package at.hannibal2.skyhanni.config.features.slayer;
+
+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 RngMeterDisplayConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Display amount of bosses needed until next RNG meter drop.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Warn Empty", desc = "Warn when no item is set in the RNG Meter.")
+ @ConfigEditorBoolean
+ public boolean warnEmpty = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Chat", desc = "Hide the RNG meter message from chat if current item is selected.")
+ @ConfigEditorBoolean
+ public boolean hideChat = true;
+
+ @Expose
+ public Position pos = new Position(410, 110, false, true);
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/SlayerBossWarningConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/SlayerBossWarningConfig.java
new file mode 100644
index 000000000..1376a29a2
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/SlayerBossWarningConfig.java
@@ -0,0 +1,26 @@
+package at.hannibal2.skyhanni.config.features.slayer;
+
+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.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class SlayerBossWarningConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Send a title when your boss is about to spawn.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(name = "Percent", desc = "The percentage at which the title and sound should be sent.")
+ @ConfigEditorSlider(minStep = 1, minValue = 50, maxValue = 90)
+ public int percent = 80;
+
+ @Expose
+ @ConfigOption(name = "Repeat", desc = "Resend the title and sound on every kill after reaching the configured percent value.")
+ @ConfigEditorBoolean
+ public boolean repeat = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/SlayerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/SlayerConfig.java
new file mode 100644
index 000000000..89128e7ff
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/SlayerConfig.java
@@ -0,0 +1,77 @@
+package at.hannibal2.skyhanni.config.features.slayer;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.features.slayer.blaze.BlazeConfig;
+import at.hannibal2.skyhanni.config.features.slayer.endermen.EndermanConfig;
+import at.hannibal2.skyhanni.config.features.slayer.vampire.VampireConfig;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.Category;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class SlayerConfig {
+
+ @Expose
+ @Category(name = "Endermen", desc = "Endermen Slayer Feature")
+ @Accordion
+ public EndermanConfig endermen = new EndermanConfig();
+
+ @Expose
+ @Category(name = "Blaze", desc = "Blaze Slayer Features")
+ public BlazeConfig blazes = new BlazeConfig();
+
+ @Expose
+ @Category(name = "Vampire", desc = "Vampire Slayer Features")
+ public VampireConfig vampire = new VampireConfig();
+
+ @Expose
+ @ConfigOption(name = "Item Profit Tracker", desc = "")
+ @Accordion
+ public ItemProfitTrackerConfig itemProfitTracker = new ItemProfitTrackerConfig();
+
+ @Expose
+ @ConfigOption(name = "Items on Ground", desc = "")
+ @Accordion
+ public ItemsOnGroundConfig itemsOnGround = new ItemsOnGroundConfig();
+
+ @Expose
+ @ConfigOption(name = "RNG Meter Display", desc = "")
+ @Accordion
+ public RngMeterDisplayConfig rngMeterDisplay = new RngMeterDisplayConfig();
+
+ @Expose
+ @ConfigOption(name = "Boss Spawn Warning", desc = "")
+ @Accordion
+ public SlayerBossWarningConfig slayerBossWarning = new SlayerBossWarningConfig();
+
+ @Expose
+ @ConfigOption(name = "Miniboss Highlight", desc = "Highlight Slayer Mini-Boss in blue color.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean slayerMinibossHighlight = false;
+
+ @Expose
+ @ConfigOption(name = "Line to Miniboss", desc = "Adds a line to every Slayer Mini-Boss around you.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean slayerMinibossLine = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Mob Names", desc = "Hide the name of the mobs you need to kill in order for the Slayer boss to spawn. Exclude mobs that are damaged, corrupted, runic or semi rare.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideMobNames = false;
+
+ @Expose
+ @ConfigOption(name = "Quest Warning", desc = "Warning when wrong Slayer quest is selected, or killing mobs for the wrong Slayer.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean questWarning = true;
+
+ @Expose
+ @ConfigOption(name = "Quest Warning Title", desc = "Sends a title when warning.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean questWarningTitle = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/blaze/BlazeConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/blaze/BlazeConfig.java
new file mode 100644
index 000000000..c631b10f8
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/blaze/BlazeConfig.java
@@ -0,0 +1,32 @@
+package at.hannibal2.skyhanni.config.features.slayer.blaze;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class BlazeConfig {
+ @Expose
+ @ConfigOption(name = "Hellion Shields", desc = "")
+ @Accordion
+ public BlazeHellionConfig hellion = new BlazeHellionConfig();
+
+
+ @Expose
+ @ConfigOption(name = "Fire Pits", desc = "Warning when the fire pit phase starts for the Blaze Slayer tier 3 and 4.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean firePitsWarning = false;
+
+ @Expose
+ @ConfigOption(name = "Phase Display", desc = "Show the current phase of the Blaze Slayer boss.")
+ @ConfigEditorBoolean
+ public boolean phaseDisplay = false;
+
+ @Expose
+ @ConfigOption(name = "Clear View", desc = "Hide particles and fireballs near Blaze Slayer bosses and demons.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean clearView = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/blaze/BlazeHellionConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/blaze/BlazeHellionConfig.java
new file mode 100644
index 000000000..4a5e4af8c
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/blaze/BlazeHellionConfig.java
@@ -0,0 +1,45 @@
+package at.hannibal2.skyhanni.config.features.slayer.blaze;
+
+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.ConfigOption;
+
+public class BlazeHellionConfig {
+ @Expose
+ @ConfigOption(name = "Colored Mobs", desc = "Color the Blaze Slayer boss and the demons in the right hellion shield color.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean coloredMobs = false;
+
+ @Expose
+ @ConfigOption(name = "Blaze Daggers", desc = "Faster and permanent display for the Blaze Slayer daggers.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean daggers = false;
+
+ @Expose
+ @ConfigOption(name = "Right Dagger", desc = "Mark the right dagger to use for Blaze Slayer in the dagger overlay.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean markRightHellionShield = false;
+
+ @Expose
+ @ConfigOption(name = "First Dagger", desc = "Select the first, left sided dagger for the display.")
+ @ConfigEditorDropdown(values = {"Spirit/Crystal", "Ashen/Auric"})
+ public int firstDagger = 0;
+
+ @Expose
+ @ConfigOption(name = "Hide Chat", desc = "Remove the wrong Blaze Slayer dagger messages from chat.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideDaggerWarning = false;
+
+ @Expose
+ public Position positionTop = new Position(-475, 173, 4.4f, true);
+
+ @Expose
+ public Position positionBottom = new Position(-475, 230, 3.2f, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/endermen/EndermanBeaconConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/endermen/EndermanBeaconConfig.java
new file mode 100644
index 000000000..32592e4b9
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/endermen/EndermanBeaconConfig.java
@@ -0,0 +1,46 @@
+package at.hannibal2.skyhanni.config.features.slayer.endermen;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class EndermanBeaconConfig {
+
+ @Expose
+ @ConfigOption(name = "Highlight Beacon",
+ desc = "Highlight the Enderman Slayer Yang Glyph (beacon) in red color and added a timer for when he explodes. " +
+ "Supports beacon in hand and beacon flying.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlightBeacon = true;
+
+ @Expose
+ @ConfigOption(name = "Beacon Color", desc = "Color of the beacon.")
+ @ConfigEditorColour
+ public String beaconColor = "0:255:255:0:88";
+
+ @Expose
+ @ConfigOption(name = "Show Warning", desc = "Displays a warning mid-screen when the Enderman Slayer throws a Yang Glyph (beacon).")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean showWarning = false;
+
+ @Expose
+ @ConfigOption(name = "Show Line", desc = "Draw a line starting at your crosshair to the beacon.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean showLine = false;
+
+ @Expose
+ @ConfigOption(name = "Line Color", desc = "Color of the line.")
+ @ConfigEditorColour
+ public String lineColor = "0:255:255:0:88";
+
+ @Expose
+ @ConfigOption(name = "Line Width", desc = "Width of the line.")
+ @ConfigEditorSlider(minStep = 1, minValue = 1, maxValue = 10)
+ public int lineWidth = 3;
+}
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
new file mode 100644
index 000000000..7b5ce353e
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/endermen/EndermanConfig.java
@@ -0,0 +1,31 @@
+package at.hannibal2.skyhanni.config.features.slayer.endermen;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class EndermanConfig {
+ @Expose
+ @ConfigOption(name = "Yang Glyph (beacon)", desc = "")
+ @Accordion
+ public EndermanBeaconConfig beacon = new EndermanBeaconConfig();
+
+ @Expose
+ @ConfigOption(name = "Highlight Nukekubi Skulls", desc = "Highlights the Enderman Slayer Nukekubi Skulls (Eyes).")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlightNukekebi = false;
+
+ @Expose
+ @ConfigOption(name = "Phase Display", desc = "Show the current phase of the Enderman Slayer in damage indcator.")
+ @ConfigEditorBoolean
+ public boolean phaseDisplay = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Particles", desc = "Hide particles around Enderman Slayer bosses and Mini-Bosses.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean hideParticles = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/BloodIchorConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/BloodIchorConfig.java
new file mode 100644
index 000000000..7daca5ea3
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/BloodIchorConfig.java
@@ -0,0 +1,38 @@
+package at.hannibal2.skyhanni.config.features.slayer.vampire;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class BloodIchorConfig {
+ @Expose
+ @ConfigOption(name = "Highlight Blood Ichor", desc = "Highlight the Blood Ichor.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlight = false;
+
+ @Expose
+ @ConfigOption(name = "Beacon Beam", desc = "Render a beacon beam where the Blood Ichor is.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean renderBeam = true;
+
+ @Expose
+ @ConfigOption(name = "Color", desc = "Highlight color.")
+ @ConfigEditorColour
+ public String color = "0:199:100:0:88";
+
+ @Expose
+ @ConfigOption(name = "Show Lines", desc = "Draw lines that start from the head of the boss and end on the Blood Ichor.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean showLines = false;
+
+ @Expose
+ @ConfigOption(name = "Lines Start Color", desc = "Starting color of the lines.")
+ @ConfigEditorColour
+ public String linesColor = "0:255:255:13:0";
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/CoopBossHighlightConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/CoopBossHighlightConfig.java
new file mode 100644
index 000000000..5c91c41a9
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/CoopBossHighlightConfig.java
@@ -0,0 +1,44 @@
+package at.hannibal2.skyhanni.config.features.slayer.vampire;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorText;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class CoopBossHighlightConfig {
+ @Expose
+ @ConfigOption(name = "Highlight Co-op Boss", desc = "Highlight boss of your co-op member.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlight = true;
+
+ @Expose
+ @ConfigOption(name = "Highlight Color", desc = "What color to highlight the boss in.")
+ @ConfigEditorColour
+ public String highlightColor = "0:249:0:255:88";
+
+ @Expose
+ @ConfigOption(name = "Co-op Members", desc = "Add your co-op member here.\n§eFormat: §7Name1,Name2,Name3")
+ @ConfigEditorText
+ public String coopMembers = "";
+
+ @Expose
+ @ConfigOption(name = "Steak Alert", desc = "Show a title when you can steak the boss.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean steakAlert = true;
+
+ @Expose
+ @ConfigOption(name = "Twinclaws Title", desc = "Send a title when Twinclaws is about to happen.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean twinClawsTitle = true;
+
+ @Expose
+ @ConfigOption(name = "Twinclaws Sound", desc = "Play a sound when Twinclaws is about to happen.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean twinClawsSound = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/KillerSpringConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/KillerSpringConfig.java
new file mode 100644
index 000000000..1d38c7ce7
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/KillerSpringConfig.java
@@ -0,0 +1,31 @@
+package at.hannibal2.skyhanni.config.features.slayer.vampire;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class KillerSpringConfig {
+ @Expose
+ @ConfigOption(name = "Highlight Killer Spring", desc = "Highlight the Killer Spring tower.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlight = false;
+
+ @Expose
+ @ConfigOption(name = "Color", desc = "Highlight color.")
+ @ConfigEditorColour
+ public String color = "0:199:100:0:88";
+
+ @Expose
+ @ConfigOption(name = "Show Lines", desc = "Draw lines that start from the head of the boss and end on the Killer Spring tower.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean showLines = false;
+
+ @Expose
+ @ConfigOption(name = "Lines Start Color", desc = "Starting color of the lines.")
+ @ConfigEditorColour
+ public String linesColor = "0:255:255:13:0";
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/OthersBossConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/OthersBossConfig.java
new file mode 100644
index 000000000..6a89c9f77
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/OthersBossConfig.java
@@ -0,0 +1,39 @@
+package at.hannibal2.skyhanni.config.features.slayer.vampire;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class OthersBossConfig {
+
+ @Expose
+ @ConfigOption(name = "Highlight Others Boss", desc = "Highlight others players boss.\nYou need to hit them first.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlight = true;
+
+ @Expose
+ @ConfigOption(name = "Highlight Color", desc = "What color to highlight the boss in.")
+ @ConfigEditorColour
+ public String highlightColor = "0:249:0:255:88";
+
+ @Expose
+ @ConfigOption(name = "Steak Alert", desc = "Show a title when you can steak the boss.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean steakAlert = true;
+
+ @Expose
+ @ConfigOption(name = "Twinclaws Title", desc = "Send a title when Twinclaws is about to happen.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean twinClawsTitle = true;
+
+ @Expose
+ @ConfigOption(name = "Twinclaws Sound", desc = "Play a sound when Twinclaws is about to happen.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean twinClawsSound = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/OwnBossConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/OwnBossConfig.java
new file mode 100644
index 000000000..481576242
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/OwnBossConfig.java
@@ -0,0 +1,39 @@
+package at.hannibal2.skyhanni.config.features.slayer.vampire;
+
+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.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class OwnBossConfig {
+
+ @Expose
+ @ConfigOption(name = "Highlight Your Boss", desc = "Highlight your own Vampire Slayer boss.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean highlight = true;
+
+ @Expose
+ @ConfigOption(name = "Highlight Color", desc = "What color to highlight the boss in.")
+ @ConfigEditorColour
+ public String highlightColor = "0:249:0:255:88";
+
+ @Expose
+ @ConfigOption(name = "Steak Alert", desc = "Show a title when you can steak your boss.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean steakAlert = true;
+
+ @Expose
+ @ConfigOption(name = "Twinclaws Title", desc = "Send a title when Twinclaws is about to happen.\nWork on others highlighted people boss.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean twinClawsTitle = true;
+
+ @Expose
+ @ConfigOption(name = "Twinclaws Sound", desc = "Play a sound when Twinclaws is about to happen.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean twinClawsSound = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/VampireConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/VampireConfig.java
new file mode 100644
index 000000000..4a068878b
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/vampire/VampireConfig.java
@@ -0,0 +1,80 @@
+package at.hannibal2.skyhanni.config.features.slayer.vampire;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorColour;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class VampireConfig {
+
+ @Expose
+ @ConfigOption(name = "Your Boss", desc = "")
+ @Accordion
+ public OwnBossConfig ownBoss = new OwnBossConfig();
+
+ @Expose
+ @ConfigOption(name = "Others Boss", desc = "")
+ @Accordion
+ public OthersBossConfig othersBoss = new OthersBossConfig();
+
+ @Expose
+ @ConfigOption(name = "Co-op Boss", desc = "")
+ @Accordion
+ public CoopBossHighlightConfig coopBoss = new CoopBossHighlightConfig();
+
+ @Expose
+ @ConfigOption(name = "Transparency", desc = "Choose the transparency of the color.")
+ @ConfigEditorSlider(minStep = 1, minValue = 1, maxValue = 250)
+ public int withAlpha = 80;
+
+ @Expose
+ @ConfigOption(name = "See Through Blocks", desc = "Highlight even when behind others mobs/players.")
+ @ConfigEditorBoolean
+ public boolean seeThrough = false;
+
+ @Expose
+ @ConfigOption(name = "Low Health", desc = "Change color when the boss is below 20% health.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean changeColorWhenCanSteak = true;
+
+ @Expose
+ @ConfigOption(name = "Can use Steak Color", desc = "Color when the boss is below 20% health.")
+ @ConfigEditorColour
+ public String steakColor = "0:255:255:0:88";
+
+ @Expose
+ @ConfigOption(name = "Twinclaws", desc = "Delay the sound and title of Twinclaws alert for a given amount in milliseconds.")
+ @ConfigEditorSlider(minStep = 1, minValue = 0, maxValue = 1000)
+ public int twinclawsDelay = 0;
+
+ @Expose
+ @ConfigOption(name = "Draw Line", desc = "Draw a line starting at your crosshair to the boss head.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean drawLine = false;
+
+ @Expose
+ @ConfigOption(name = "Line Color", desc = "Color of the line.")
+ @ConfigEditorColour
+ public String lineColor = "0:255:255:0:88";
+
+ @Expose
+ @ConfigOption(name = "Line Width", desc = "Width of the line.")
+ @ConfigEditorSlider(minStep = 1, minValue = 1, maxValue = 10)
+ public int lineWidth = 1;
+
+
+ @Expose
+ @ConfigOption(name = "Blood Ichor", desc = "")
+ @Accordion
+ public BloodIchorConfig bloodIchor = new BloodIchorConfig();
+
+ @Expose
+ @ConfigOption(name = "Killer Spring", desc = "")
+ @Accordion
+ public KillerSpringConfig killerSpring = new KillerSpringConfig();
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/CropAccessoryData.kt b/src/main/java/at/hannibal2/skyhanni/data/CropAccessoryData.kt
index 021e59b91..79202ffa2 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/CropAccessoryData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/CropAccessoryData.kt
@@ -104,9 +104,9 @@ class CropAccessoryData {
val pagesLoaded get() = accessoryPage.size
var cropAccessory: CropAccessory?
- get() = GardenAPI.config?.savedCropAccessory
+ get() = GardenAPI.storage?.savedCropAccessory
private set(accessory) {
- GardenAPI.config?.savedCropAccessory = accessory
+ GardenAPI.storage?.savedCropAccessory = accessory
}
// Derived partially from NotEnoughUpdates/NotEnoughUpdates, ProfileViewer.Profile#getInventoryInfo
diff --git a/src/main/java/at/hannibal2/skyhanni/data/FriendAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/FriendAPI.kt
index bca06d18c..f6c9b4e56 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/FriendAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/FriendAPI.kt
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.data
-import at.hannibal2.skyhanni.config.ConfigManager
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.config.ConfigFileType
import at.hannibal2.skyhanni.events.HypixelJoinEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.test.command.ErrorManager
@@ -11,56 +12,40 @@ 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.io.File
-import java.io.FileReader
import java.util.UUID
-class FriendAPI {
- private val file = File("config/skyhanni/friends.json")
-
+object FriendAPI {
// TODO USE SH-REPO
private val removedFriendPattern =
".*\n§r§eYou removed §r(?<name>.*)§e from your friends list!§r§9§m\n.*".toPattern()
private val addedFriendPattern = "§aYou are now friends with (?<name>.*)".toPattern()
private val noBestFriendPattern = ".*\n§r(?<name>.*)§e is no longer a best friend!§r§9§m\n.*".toPattern()
private val bestFriendPattern = ".*\n(?<name>.*)§a is now a best friend!§r§9§m\n.*".toPattern()
+ private val readFriendListPattern = "/viewprofile (?<uuid>.*)".toPattern()
- companion object {
-
- private var friendsJson: FriendsJson? = null
-
- private fun getFriends(): MutableMap<UUID, Friend> {
- val friendsJson = friendsJson ?: error("savedFriends not loaded yet!")
- return friendsJson.players.getOrPut(LorenzUtils.getRawPlayerUuid()) {
- FriendsJson.PlayerFriends().also { it.friends = mutableMapOf() }
- }.friends
- }
-
- private val tempFriends = mutableListOf<Friend>()
+ private val tempFriends = mutableListOf<Friend>()
- fun getAllFriends(): List<Friend> {
- val list = mutableListOf<Friend>()
- list.addAll(getFriends().values)
- list.addAll(tempFriends)
- return list
- }
- }
+ private fun getFriends() = SkyHanniMod.friendsData.players.getOrPut(LorenzUtils.getRawPlayerUuid()) {
+ FriendsJson.PlayerFriends().also { it.friends = mutableMapOf() }
+ }.friends
@SubscribeEvent
fun onHypixelJoin(event: HypixelJoinEvent) {
- if (file.isFile) {
- friendsJson = ConfigManager.gson.fromJson(FileReader(file), FriendsJson::class.java)
- }
- if (friendsJson == null) {
- file.parentFile.mkdirs()
- file.createNewFile()
- friendsJson = FriendsJson().also { it.players = mutableMapOf() }
+ if (SkyHanniMod.friendsData.players == null) {
+ SkyHanniMod.friendsData.players = mutableMapOf()
saveConfig()
}
}
+ fun getAllFriends(): List<Friend> {
+ val list = mutableListOf<Friend>()
+ list.addAll(getFriends().values)
+ list.addAll(tempFriends)
+ return list
+ }
+
fun saveConfig() {
- file.writeText(ConfigManager.gson.toJson(friendsJson))
+ SkyHanniMod.configManager.saveConfig(ConfigFileType.FRIENDS, "Save file")
}
@SubscribeEvent
@@ -111,12 +96,19 @@ class FriendAPI {
val value = chatStyle.chatClickEvent?.value ?: continue
if (!value.startsWith("/viewprofile")) continue
- val uuid = "/viewprofile (?<uuid>.*)".toPattern().matchMatcher(value) {
+ val uuid = readFriendListPattern.matchMatcher(value) {
group("uuid")?.let {
try {
UUID.fromString(it)
} catch (e: IllegalArgumentException) {
- ErrorManager.logError(e, "Error reading friend list.")
+ ErrorManager.logErrorWithData(
+ e, "Error reading friend list.",
+ "raw uuid" to it,
+ "value" to value,
+ "chatStyle" to chatStyle,
+ "event.chatComponent" to event.chatComponent,
+ "event.message" to event.message,
+ )
return
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/GardenComposterUpgradesData.kt b/src/main/java/at/hannibal2/skyhanni/data/GardenComposterUpgradesData.kt
index 14651f900..6b6d343aa 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/GardenComposterUpgradesData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/GardenComposterUpgradesData.kt
@@ -6,6 +6,7 @@ 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.StringUtils.matchMatcher
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class GardenComposterUpgradesData {
@@ -16,15 +17,12 @@ class GardenComposterUpgradesData {
if (event.inventoryName != "Composter Upgrades") return
for (item in event.inventoryItems.values) {
val itemName = item.name ?: continue
- val matcher = ComposterUpgrade.regex.matcher(itemName)
- if (!matcher.matches()) continue
-
- if (matcher.groupCount() != 0) {
- val name = matcher.group("name")
- val level = matcher.group("level")?.romanToDecimalIfNeeded() ?: 0
+ ComposterUpgrade.regex.matchMatcher(itemName) {
+ val name = group("name")
+ val level = group("level")?.romanToDecimalIfNeeded() ?: 0
val composterUpgrade = ComposterUpgrade.getByName(name)!!
ComposterAPI.composterUpgrades?.put(composterUpgrade, level)
}
}
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt b/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt
index ecbaee591..610393906 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt
@@ -6,6 +6,7 @@ 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.NumberUtil.formatNumber
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.jsonobjects.GardenJson
import net.minecraft.item.ItemStack
@@ -14,7 +15,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
object GardenCropMilestones {
// TODO USE SH-REPO
private val cropPattern = "§7Harvest §f(?<name>.*) §7on .*".toPattern()
- private val totalPattern = "§7Total: §a(?<name>.*)".toPattern()
+ val totalPattern = "§7Total: §a(?<name>.*)".toPattern()
fun getCropTypeByLore(itemStack: ItemStack): CropType? {
for (line in itemStack.getLore()) {
@@ -34,17 +35,18 @@ object GardenCropMilestones {
val crop = getCropTypeByLore(stack) ?: continue
for (line in stack.getLore()) {
totalPattern.matchMatcher(line) {
- val amount = group("name").replace(",", "").toLong()
+ val amount = group("name").formatNumber()
crop.setCounter(amount)
}
}
}
CropMilestoneUpdateEvent().postAndCatch()
+ GardenCropMilestonesCommunityFix.openInventory(event.inventoryItems)
}
- private var cropMilestoneData: Map<CropType, List<Int>> = emptyMap()
+ var cropMilestoneData: Map<CropType, List<Int>> = emptyMap()
- val cropCounter: MutableMap<CropType, Long>? get() = GardenAPI.config?.cropCounter
+ val cropCounter: MutableMap<CropType, Long>? get() = GardenAPI.storage?.cropCounter
// TODO make nullable
fun CropType.getCounter() = cropCounter?.get(this) ?: 0
@@ -54,6 +56,7 @@ object GardenCropMilestones {
}
fun CropType.isMaxed(): Boolean {
+ // TODO change 1b
val maxValue = cropMilestoneData[this]?.sum() ?: 1_000_000_000 // 1 bil for now
return getCounter() >= maxValue
}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestonesCommunityFix.kt b/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestonesCommunityFix.kt
new file mode 100644
index 000000000..f9990685d
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestonesCommunityFix.kt
@@ -0,0 +1,177 @@
+package at.hannibal2.skyhanni.data
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.config.ConfigManager
+import at.hannibal2.skyhanni.events.RepositoryReloadEvent
+import at.hannibal2.skyhanni.features.garden.CropType
+import at.hannibal2.skyhanni.utils.ItemUtils.getLore
+import at.hannibal2.skyhanni.utils.ItemUtils.name
+import at.hannibal2.skyhanni.utils.LorenzUtils
+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.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
+
+object GardenCropMilestonesCommunityFix {
+ private val pattern = ".*§e(?<having>.*)§6/§e(?<max>.*)".toPattern()
+ private var showWrongData = false
+ private var showWhenAllCorrect = false
+
+ @SubscribeEvent
+ fun onRepoReload(event: RepositoryReloadEvent) {
+ val data = event.getConstant<GardenJson>("Garden")
+ val map = data.crop_milestone_community_help ?: return
+ for ((key, value) in map) {
+ if (key == "show_wrong_data") {
+ showWrongData = value
+ }
+ if (key == "show_when_all_correct") {
+ showWhenAllCorrect = value
+ }
+ }
+ }
+
+ fun openInventory(inventoryItems: Map<Int, ItemStack>) {
+ if (!showWrongData) return
+ if (!SkyHanniMod.feature.garden.copyMilestoneData) return
+ fixForWrongData(inventoryItems)
+ }
+
+ private fun fixForWrongData(inventoryItems: Map<Int, ItemStack>) {
+ val data = mutableListOf<String>()
+ for ((_, stack) in inventoryItems) {
+ val crop = GardenCropMilestones.getCropTypeByLore(stack) ?: continue
+ checkForWrongData(stack, crop, data)
+ }
+
+ if (data.isNotEmpty()) {
+ LorenzUtils.chat(
+ "Found §c${data.size} §ewrong crop milestone steps in the menu! " +
+ "Correct data got put into clipboard. " +
+ "Please share it on the §bSkyHanni Discord §ein the channel §b#share-data§e."
+ )
+ OSUtils.copyToClipboard("```${data.joinToString("\n")}```")
+ } else {
+ if (showWhenAllCorrect) {
+ LorenzUtils.chat("No wrong crop milestone steps found!")
+ }
+ }
+ }
+
+ private fun checkForWrongData(
+ stack: ItemStack,
+ crop: CropType,
+ wrongData: MutableList<String>
+ ) {
+ val name = stack.name ?: return
+ val rawNumber = name.removeColor().replace(crop.cropName, "").trim()
+ val realTier = if (rawNumber == "") 0 else rawNumber.romanToDecimalIfNeeded()
+
+ val lore = stack.getLore()
+ val next = lore.nextAfter({ GardenCropMilestones.totalPattern.matches(it) }, 3) ?: return
+ val total = lore.nextAfter({ GardenCropMilestones.totalPattern.matches(it) }, 6) ?: return
+
+// debug(" ")
+// debug("crop: $crop")
+// debug("realTier: $realTier")
+
+ val guessNextMax = GardenCropMilestones.getCropsForTier(
+ realTier + 1,
+ crop
+ ) - GardenCropMilestones.getCropsForTier(realTier, crop)
+// debug("guessNextMax: ${guessNextMax.addSeparators()}")
+ val nextMax = pattern.matchMatcher(next) {
+ group("max").formatNumber()
+ } ?: return
+// debug("nextMax real: ${nextMax.addSeparators()}")
+ if (nextMax != guessNextMax) {
+// debug("wrong, add to list")
+ wrongData.add("$crop:$realTier:${nextMax.addSeparators()}")
+ }
+
+ val guessTotalMax = GardenCropMilestones.getCropsForTier(46, crop)
+// println("guessTotalMax: ${guessTotalMax.addSeparators()}")
+ val totalMax = pattern.matchMatcher(total) {
+ group("max").formatNumber()
+ } ?: return
+// println("totalMax real: ${totalMax.addSeparators()}")
+ val totalOffBy = guessTotalMax - totalMax
+// debug("$crop total offf by: ${totalOffBy.addSeparators()}")
+ }
+
+// fun debug(message: String) {
+// if (SkyHanniMod.feature.dev.debug.enabled) {
+// println(message)
+// }
+// }
+
+ /**
+ * This helps to fix wrong crop milestone data
+ * This command reads the clipboard content,
+ * in the format of users sending crop milestone step data.
+ *
+ * The new data will be compared to the currently saved data,
+ * differences are getting replaced, and the result gets put into the clipboard.
+ * The clipboard context can be used to update the repo content.
+ */
+ fun readDataFromClipboard() {
+ SkyHanniMod.coroutineScope.launch {
+ OSUtils.readFromClipboard()?.let {
+ handleInput(it)
+ }
+ }
+ }
+
+ private var totalFixedValues = 0
+
+ private fun handleInput(input: String) {
+ println(" ")
+ var fixed = 0
+ var alreadyCorrect = 0
+ for (line in input.lines()) {
+ val split = line.replace("```", "").replace(".", ",").split(":")
+ if (split.size != 3) continue
+ val (rawCrop, tier, amount) = split
+ val crop = LorenzUtils.enumValueOf<CropType>(rawCrop)
+
+ if (tryFix(crop, tier.toInt(), amount.formatNumber().toInt())) {
+ fixed++
+ } else {
+ alreadyCorrect++
+ }
+ }
+ totalFixedValues += fixed
+ LorenzUtils.chat("Fixed: $fixed/$alreadyCorrect, total fixes: $totalFixedValues")
+ val s = ConfigManager.gson.toJsonTree(GardenCropMilestones.cropMilestoneData).toString()
+ OSUtils.copyToClipboard("\"crop_milestones\":$s,")
+ }
+
+ private fun tryFix(crop: CropType, tier: Int, amount: Int): Boolean {
+ val guessNextMax = GardenCropMilestones.getCropsForTier(tier + 1, crop) - GardenCropMilestones.getCropsForTier(
+ tier,
+ crop
+ )
+ if (guessNextMax.toInt() == amount) {
+ return false
+ }
+ GardenCropMilestones.cropMilestoneData = GardenCropMilestones.cropMilestoneData.editCopy {
+ fix(crop, this, tier, amount)
+ }
+ return true
+ }
+
+ private fun fix(crop: CropType, map: MutableMap<CropType, List<Int>>, tier: Int, amount: Int) {
+ map[crop] = map[crop]!!.editCopy {
+ this[tier] = amount
+ }
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/GardenCropUpgrades.kt b/src/main/java/at/hannibal2/skyhanni/data/GardenCropUpgrades.kt
index 15a18ca26..1ea0871ee 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/GardenCropUpgrades.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/GardenCropUpgrades.kt
@@ -39,7 +39,7 @@ class GardenCropUpgrades {
}
companion object {
- private val cropUpgrades: MutableMap<CropType, Int>? get() = GardenAPI.config?.cropUpgrades
+ private val cropUpgrades: MutableMap<CropType, Int>? get() = GardenAPI.storage?.cropUpgrades
fun CropType.getUpgradeLevel() = cropUpgrades?.get(this)
diff --git a/src/main/java/at/hannibal2/skyhanni/data/GuiEditManager.kt b/src/main/java/at/hannibal2/skyhanni/data/GuiEditManager.kt
index 4f3110789..29a344b18 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/GuiEditManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/GuiEditManager.kt
@@ -9,6 +9,8 @@ import at.hannibal2.skyhanni.test.SkyHanniDebugsAndTests
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.isRancherSign
import at.hannibal2.skyhanni.utils.NEUItems
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
+import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.inventory.GuiChest
import net.minecraft.client.gui.inventory.GuiEditSign
@@ -17,8 +19,13 @@ import net.minecraft.client.renderer.GlStateManager
import net.minecraftforge.fml.common.eventhandler.EventPriority
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import java.util.UUID
+import kotlin.time.Duration.Companion.milliseconds
+import kotlin.time.Duration.Companion.minutes
class GuiEditManager {
+
+ private var lastHotkeyPressed = SimpleTimeMark.farPast()
+
@SubscribeEvent
fun onKeyClick(event: LorenzKeyPressEvent) {
if (!LorenzUtils.inSkyBlock) return
@@ -26,13 +33,15 @@ class GuiEditManager {
if (isInGui()) return
Minecraft.getMinecraft().currentScreen?.let {
- if (it !is GuiInventory && it !is GuiChest && it !is GuiEditSign) return
+ if (it !is GuiInventory && it !is GuiChest && it !is GuiEditSign && it !is GuiProfileViewer) return
if (it is GuiEditSign && !it.isRancherSign()) return
}
+ if (lastHotkeyPressed.passedSince() < 500.milliseconds) return
if (NEUItems.neuHasFocus()) return
+ lastHotkeyPressed = SimpleTimeMark.now()
- openGuiPositionEditor()
+ openGuiPositionEditor(hotkeyReminder = false)
}
@SubscribeEvent(priority = EventPriority.LOWEST)
@@ -59,9 +68,19 @@ class GuiEditManager {
}
}
+ private var lastHotkeyReminded = SimpleTimeMark.farPast()
+
@JvmStatic
- fun openGuiPositionEditor() {
+ fun openGuiPositionEditor(hotkeyReminder: Boolean) {
SkyHanniMod.screenToOpen = GuiPositionEditor(latestPositions.values.toList(), 2)
+ if (hotkeyReminder && lastHotkeyReminded.passedSince() > 30.minutes) {
+ lastHotkeyReminded = SimpleTimeMark.now()
+ LorenzUtils.chat(
+ "§eTo edit hidden GUI elements:\n" +
+ " §7- §e1. Set a key in /sh edit.\n" +
+ " §7- §e2. Click that key while the GUI element is visible."
+ )
+ }
}
@JvmStatic
@@ -95,4 +114,4 @@ class GuiEditManager {
}
}
-class Vector2i(val x: Int, val y: Int) \ No newline at end of file
+class Vector2i(val x: Int, val y: Int)
diff --git a/src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt b/src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt
index 31bb7c047..aa78bec09 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt
@@ -7,24 +7,18 @@ 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.utils.LocationUtils.isPlayerInside
import at.hannibal2.skyhanni.utils.LorenzLogger
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import at.hannibal2.skyhanni.utils.TabListData
import net.minecraft.client.Minecraft
-import net.minecraft.util.AxisAlignedBB
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import net.minecraftforge.fml.common.network.FMLNetworkEvent
class HypixelData {
// TODO USE SH-REPO
private val tabListProfilePattern = "§e§lProfile: §r§a(?<profile>.*)".toPattern()
- private val westVillageFarmArea = AxisAlignedBB(-54.0, 69.0, -115.0, -40.0, 75.0, -127.0)
- private val howlingCaveArea = AxisAlignedBB(-401.0, 50.0, -104.0, -337.0, 90.0, 36.0)
- private val fakeZealotBruiserHideoutArea = AxisAlignedBB(-520.0, 66.0, -332.0, -558.0, 85.0, -280.0)
- private val realZealotBruiserHideoutArea = AxisAlignedBB(-552.0, 50.0, -245.0, -580.0, 72.0, -209.0)
companion object {
var hypixelLive = false
@@ -85,15 +79,7 @@ class HypixelData {
.firstOrNull { it.startsWith(" §7⏣ ") || it.startsWith(" §5ф ") }
?.substring(5)?.removeColor()
?: "?"
-
- skyBlockArea = when {
- skyBlockIsland == IslandType.THE_RIFT && westVillageFarmArea.isPlayerInside() -> "Dreadfarm"
- skyBlockIsland == IslandType.THE_PARK && howlingCaveArea.isPlayerInside() -> "Howling Cave"
- skyBlockIsland == IslandType.THE_END && fakeZealotBruiserHideoutArea.isPlayerInside() -> "The End"
- skyBlockIsland == IslandType.THE_END && realZealotBruiserHideoutArea.isPlayerInside() -> "Zealot Bruiser Hideout"
-
- else -> originalLocation
- }
+ skyBlockArea = LocationFixData.fixLocation(skyBlockIsland) ?: originalLocation
checkProfileName()
}
@@ -188,7 +174,7 @@ class HypixelData {
}
private fun getIslandType(newIsland: String, guesting: Boolean): IslandType {
- val islandType = IslandType.getBySidebarName(newIsland)
+ val islandType = IslandType.getByNameOrUnknown(newIsland)
if (guesting) {
if (islandType == IslandType.PRIVATE_ISLAND) return IslandType.PRIVATE_ISLAND_GUEST
if (islandType == IslandType.GARDEN) return IslandType.GARDEN_GUEST
@@ -204,6 +190,6 @@ class HypixelData {
val displayName = objective.displayName
val scoreboardTitle = displayName.removeColor()
return scoreboardTitle.contains("SKYBLOCK") ||
- scoreboardTitle.contains("SKIBLOCK") // April 1st jokes are so funny
+ scoreboardTitle.contains("SKIBLOCK") // April 1st jokes are so funny
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/IslandType.kt b/src/main/java/at/hannibal2/skyhanni/data/IslandType.kt
index 15195dec4..3ab213025 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/IslandType.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/IslandType.kt
@@ -28,8 +28,9 @@ enum class IslandType(val displayName: String, val apiName: String = "null") {
;
companion object {
- fun getBySidebarName(name: String): IslandType {
- return entries.firstOrNull { it.displayName == name } ?: UNKNOWN
- }
+ fun getByNameOrUnknown(name: String) = getByNameOrNull(name) ?: UNKNOWN
+ fun getByName(name: String) = getByNameOrNull(name) ?: error("IslandType not found: '$name'")
+
+ fun getByNameOrNull(name: String) = entries.firstOrNull { it.displayName == name }
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/LocationFixData.kt b/src/main/java/at/hannibal2/skyhanni/data/LocationFixData.kt
new file mode 100644
index 000000000..2bd6a9dcb
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/data/LocationFixData.kt
@@ -0,0 +1,33 @@
+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 net.minecraft.util.AxisAlignedBB
+import net.minecraftforge.fml.common.eventhandler.EventPriority
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+object LocationFixData {
+ private var locationFixes = mutableListOf<LocationFix>()
+
+ class LocationFix(val island: IslandType, val area: AxisAlignedBB, val realLocation: String)
+
+ // priority set to low so that IslandType can load their island names from repo earlier
+ @SubscribeEvent(priority = EventPriority.LOW)
+ fun onRepoReload(event: RepositoryReloadEvent) {
+ val data = event.getConstant<LocationFixJson>("LocationFix")
+ locationFixes.clear()
+
+ for (fix in data.locationFixes.values) {
+ val island = IslandType.getByName(fix.island_name)
+ val area = fix.a.axisAlignedTo(fix.b)
+ val realLocation = fix.real_location
+
+ locationFixes.add(LocationFix(island, area, realLocation))
+ }
+ }
+
+ fun fixLocation(skyBlockIsland: IslandType) = locationFixes
+ .firstOrNull { skyBlockIsland == it.island && it.area.isPlayerInside() }
+ ?.realLocation
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/MinecraftData.kt b/src/main/java/at/hannibal2/skyhanni/data/MinecraftData.kt
index da9497d08..bfcc8df5f 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/MinecraftData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/MinecraftData.kt
@@ -95,4 +95,4 @@ object MinecraftData {
InventoryUtils.itemInHandId = NEUInternalName.NONE
InventoryUtils.recentItemsInHand.clear()
}
-} \ 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 7e2032077..4c6058b26 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/OwnInventoryData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/OwnInventoryData.kt
@@ -1,30 +1,40 @@
package at.hannibal2.skyhanni.data
-import at.hannibal2.skyhanni.api.CollectionAPI
import at.hannibal2.skyhanni.events.InventoryCloseEvent
+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.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.NEUInternalName
+import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy
import at.hannibal2.skyhanni.utils.NEUItems
import net.minecraft.item.ItemStack
+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
-class OwnInventoryData {
+typealias SlotNumber = Int
+typealias ItemName = String
+typealias ItemData = Pair<ItemName, Int>
- private var itemNames = mutableMapOf<Int, String>()
- private var itemAmount = mutableMapOf<Int, Int>()
+class OwnInventoryData {
+ private var items = mapOf<SlotNumber, ItemData>()
+ private var dirty = false
@SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true)
fun onChatPacket(event: PacketEvent.ReceiveEvent) {
if (!LorenzUtils.inSkyBlock) return
val packet = event.packet
+ if (packet is S2FPacketSetSlot || packet is S0DPacketCollectItem) {
+ dirty = true
+ }
if (packet is S2FPacketSetSlot) {
val windowId = packet.func_149175_c()
if (windowId == 0) {
@@ -32,29 +42,58 @@ class OwnInventoryData {
OwnInventoryItemUpdateEvent(item).postAndCatch()
}
}
- if (packet is S2FPacketSetSlot) {
- val windowId = packet.func_149175_c()
- val item = packet.func_149174_e()
- val slot = packet.func_149173_d()
- if (windowId != 0) return
- val name = item?.name ?: "null"
-
- val oldItem = itemNames.getOrDefault(slot, "null")
- val oldAmount = itemAmount.getOrDefault(slot, 0)
-
- val amount = item?.stackSize ?: 0
- if (name == oldItem) {
- val diff = amount - oldAmount
- if (amount > oldAmount) {
- add(item, diff)
- }
- } else {
- if (name != "null") {
- add(item, amount)
- }
+ }
+
+ @SubscribeEvent
+ fun onTick(event: LorenzTickEvent) {
+ if (!LorenzUtils.inSkyBlock) return
+ if (items.isEmpty()) {
+ initInventory()
+ }
+
+ 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)
}
- itemNames[slot] = name
- itemAmount[slot] = amount
+ }
+ }
+
+ private fun initInventory() {
+ items = items.editCopy {
+ for ((slot, itemStack) in InventoryUtils.getItemsInOwnInventoryWithNull().withIndex()) {
+ this[slot] = itemStack.itemToPair()
+ }
+ }
+ }
+
+ @SubscribeEvent
+ fun onWorldChange(event: LorenzWorldChangeEvent) {
+ items = emptyMap()
+ }
+
+ private fun ItemStack?.itemToPair(): ItemData = this?.let { (name ?: "null") to stackSize } ?: Pair("null", 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
}
}
@@ -66,9 +105,8 @@ class OwnInventoryData {
private var lastClose = 0L
- private fun add(item: ItemStack?, add: Int) {
- if (item == null) return
-
+ private fun add(item_: ItemStack?, add: Int) {
+ val item = item_ ?: return
val diffClose = System.currentTimeMillis() - lastClose
if (diffClose < 500) return
@@ -92,10 +130,7 @@ class OwnInventoryData {
val (_, amount) = NEUItems.getMultiplier(internalName)
if (amount > 1) return
- addMultiplier(internalName, add)
+ ItemAddInInventoryEvent(internalName, add).postAndCatch()
}
- private fun addMultiplier(internalName: NEUInternalName, amount: Int) {
- CollectionAPI.addFromInventory(internalName, amount)
- }
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/PartyAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/PartyAPI.kt
index 08344c51b..90fe4783e 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/PartyAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/PartyAPI.kt
@@ -8,7 +8,6 @@ import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import at.hannibal2.skyhanni.utils.StringUtils.removeResets
import at.hannibal2.skyhanni.utils.StringUtils.trimWhiteSpaceAndResets
-import net.minecraft.client.Minecraft
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.random.Random
@@ -33,17 +32,17 @@ object PartyAPI {
fun listMembers() {
val size = partyMembers.size
if (size == 0) {
- LorenzUtils.chat("§e[SkyHanni] No tracked party members!")
+ LorenzUtils.chat("No tracked party members!")
return
}
- LorenzUtils.chat("§a[SkyHanni] Tracked party members §7($size) §f:")
+ LorenzUtils.chat("Tracked party members §7($size) §f:", prefixColor = "§a")
for (member in partyMembers) {
- LorenzUtils.chat(" §a- §7$member")
+ LorenzUtils.chat(" §a- §7$member", false)
}
if (Random.nextDouble() < 0.1) {
OSUtils.openBrowser("https://www.youtube.com/watch?v=iANP7ib7CPA")
- LorenzUtils.hoverableChat("§7Are You Ready To Party?", listOf("§b~Spongebob"))
+ LorenzUtils.hoverableChat("§7Are You Ready To Party?", listOf("§b~Spongebob"), prefix = false)
}
}
@@ -112,7 +111,7 @@ object PartyAPI {
partyMemberListPattern.matchMatcher(message.removeColor()) {
for (name in group("names").split(" ● ")) {
val playerName = name.replace(" ●", "").cleanPlayerName()
- if (playerName == Minecraft.getMinecraft().thePlayer.name) continue
+ if (playerName == LorenzUtils.getPlayerName()) continue
if (!partyMembers.contains(playerName)) partyMembers.add(playerName)
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/PetAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/PetAPI.kt
new file mode 100644
index 000000000..9c5eac610
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/data/PetAPI.kt
@@ -0,0 +1,11 @@
+package at.hannibal2.skyhanni.data
+
+object PetAPI {
+
+ // Contains color code + name and for older SkyHanni users maybe also the pet level
+ var currentPet: String?
+ get() = ProfileStorageData.profileSpecific?.currentPet
+ set(value) {
+ ProfileStorageData.profileSpecific?.currentPet = value
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/ProfileStorageData.kt b/src/main/java/at/hannibal2/skyhanni/data/ProfileStorageData.kt
index 63f77f2d2..8e6f9bb7d 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/ProfileStorageData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/ProfileStorageData.kt
@@ -12,7 +12,6 @@ import at.hannibal2.skyhanni.events.PreProfileSwitchEvent
import at.hannibal2.skyhanni.events.ProfileJoinEvent
import at.hannibal2.skyhanni.events.TabListUpdateEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.LorenzVec
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import net.minecraftforge.fml.common.eventhandler.EventPriority
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
@@ -25,14 +24,15 @@ object ProfileStorageData {
private var nextProfile: String? = null
+ // TODO USE SH-REPO
+ private val profileSwitchPattern = "§7Switching to profile (?<name>.*)\\.\\.\\.".toPattern()
private var sackPlayers: SackData.PlayerSpecific? = null
var sackProfiles: SackData.ProfileSpecific? = null
@SubscribeEvent(priority = EventPriority.HIGHEST)
fun onChat(event: LorenzChatEvent) {
- // TODO USE SH-REPO
- "§7Switching to profile (?<name>.*)\\.\\.\\.".toPattern().matchMatcher(event.message) {
+ profileSwitchPattern.matchMatcher(event.message) {
nextProfile = group("name").lowercase()
loaded = false
PreProfileSwitchEvent().postAndCatch()
@@ -54,7 +54,7 @@ object ProfileStorageData {
LorenzUtils.error("sackPlayers after profile swap can not be set: sackPlayers is null!")
return
}
- loadProfileSpecific(playerSpecific, sackPlayers, profileName, "profile swap (chat message)")
+ loadProfileSpecific(playerSpecific, sackPlayers, profileName)
ConfigLoadEvent().postAndCatch()
}
@@ -73,7 +73,7 @@ object ProfileStorageData {
if (profileSpecific == null) {
val profileName = event.name
- loadProfileSpecific(playerSpecific, sackPlayers, profileName, "first join (chat message)")
+ loadProfileSpecific(playerSpecific, sackPlayers, profileName)
}
}
@@ -86,7 +86,7 @@ object ProfileStorageData {
val pattern = "§e§lProfile: §r§a(?<name>.*)".toPattern()
pattern.matchMatcher(line) {
val profileName = group("name").lowercase()
- loadProfileSpecific(playerSpecific, sackPlayers, profileName, "tab list")
+ loadProfileSpecific(playerSpecific, sackPlayers, profileName)
nextProfile = null
return
}
@@ -105,17 +105,20 @@ object ProfileStorageData {
if (System.currentTimeMillis() > noTabListTime + 3_000) {
noTabListTime = System.currentTimeMillis()
LorenzUtils.chat(
- "§c[SkyHanni] Extra Information from Tab list not found! " +
- "Enable it: SkyBlock Menu ➜ Settings ➜ Personal ➜ User Interface ➜ Player List Info"
+ "Extra Information from Tab list not found! " +
+ "Enable it: SkyBlock Menu ➜ Settings ➜ Personal ➜ User Interface ➜ Player List Info"
)
}
}
- private fun loadProfileSpecific(playerSpecific: Storage.PlayerSpecific, sackProfile: SackData.PlayerSpecific, profileName: String, reason: String) {
+ private fun loadProfileSpecific(
+ playerSpecific: Storage.PlayerSpecific,
+ sackProfile: SackData.PlayerSpecific,
+ profileName: String
+ ) {
noTabListTime = -1
profileSpecific = playerSpecific.profiles.getOrPut(profileName) { Storage.ProfileSpecific() }
sackProfiles = sackProfile.profiles.getOrPut(profileName) { SackData.ProfileSpecific() }
- tryMigrateProfileSpecific()
loaded = true
ConfigLoadEvent().postAndCatch()
}
@@ -125,79 +128,6 @@ object ProfileStorageData {
val playerUuid = LorenzUtils.getRawPlayerUuid()
playerSpecific = SkyHanniMod.feature.storage.players.getOrPut(playerUuid) { Storage.PlayerSpecific() }
sackPlayers = SkyHanniMod.sackData.players.getOrPut(playerUuid) { SackData.PlayerSpecific() }
- migratePlayerSpecific()
ConfigLoadEvent().postAndCatch()
}
-
- private fun migratePlayerSpecific() {
- val oldHidden = SkyHanniMod.feature.hidden
- if (oldHidden.isMigrated) return
-
- SkyHanniMod.feature.storage?.let {
- it.gardenJacobFarmingContestTimes = oldHidden.gardenJacobFarmingContestTimes
- }
- }
-
- private fun tryMigrateProfileSpecific() {
- val oldHidden = SkyHanniMod.feature.hidden
- if (oldHidden.isMigrated) return
-
- profileSpecific?.let {
- it.currentPet = oldHidden.currentPet
-
- for ((rawLocation, minionName) in oldHidden.minionName) {
- val lastClick = oldHidden.minionLastClick[rawLocation] ?: -1
- val location = LorenzVec.decodeFromString(rawLocation)
- val minionConfig = Storage.ProfileSpecific.MinionConfig()
- minionConfig.displayName = minionName
- minionConfig.lastClicked = lastClick
- it.minions[location] = minionConfig
- }
- }
-
- profileSpecific?.crimsonIsle?.let {
- it.quests = oldHidden.crimsonIsleQuests
- it.miniBossesDoneToday = oldHidden.crimsonIsleMiniBossesDoneToday
- it.kuudraTiersDone = oldHidden.crimsonIsleKuudraTiersDone
- }
-
- profileSpecific?.garden?.let {
- it.experience = oldHidden.gardenExp.toLong()
- it.cropCounter = oldHidden.gardenCropCounter
- it.cropUpgrades = oldHidden.gardenCropUpgrades
-
- for ((crop, speed) in oldHidden.gardenCropsPerSecond) {
- if (speed != -1) {
- it.cropsPerSecond[crop] = speed
- }
- }
-
- it.latestBlocksPerSecond = oldHidden.gardenLatestBlocksPerSecond
- it.latestTrueFarmingFortune = oldHidden.gardenLatestTrueFarmingFortune
- it.savedCropAccessory = oldHidden.savedCropAccessory
- it.dicerRngDrops = oldHidden.gardenDicerRngDrops
- it.informedAboutLowMatter = oldHidden.informedAboutLowMatter
- it.informedAboutLowFuel = oldHidden.informedAboutLowFuel
- it.visitorInterval = oldHidden.visitorInterval
- it.nextSixthVisitorArrival = oldHidden.nextSixthVisitorArrival
- it.farmArmorDrops = oldHidden.gardenFarmingArmorDrops
- it.composterUpgrades = oldHidden.gardenComposterUpgrades
- it.toolWithBountiful = oldHidden.gardenToolHasBountiful
- it.composterCurrentOrganicMatterItem = oldHidden.gardenComposterCurrentOrganicMatterItem
- it.composterCurrentFuelItem = oldHidden.gardenComposterCurrentFuelItem
- }
-
- profileSpecific?.garden?.visitorDrops?.let {
- val old = oldHidden.visitorDrops
- it.acceptedVisitors = old.acceptedVisitors
- it.deniedVisitors = old.deniedVisitors
- it.visitorRarities = old.visitorRarities
- it.copper = old.copper
- it.farmingExp = old.farmingExp
- it.coinsSpent = old.coinsSpent
- it.rewardsCount = old.rewardsCount
- }
-
- oldHidden.isMigrated = true
- }
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/PurseAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/PurseAPI.kt
index cb3b21031..0deb53164 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/PurseAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/PurseAPI.kt
@@ -5,6 +5,7 @@ import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.PurseChangeCause
import at.hannibal2.skyhanni.events.PurseChangeEvent
import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber
+import at.hannibal2.skyhanni.utils.NumberUtil.milion
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import net.minecraft.client.Minecraft
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
@@ -41,12 +42,16 @@ class PurseAPI {
if (diff == 1.0) {
return PurseChangeCause.GAIN_TALISMAN_OF_COINS
}
+
+ if (diff == 15.milion || diff == 100.milion) {
+ return PurseChangeCause.GAIN_DICE_ROLL
+ }
+
if (Minecraft.getMinecraft().currentScreen == null) {
val timeDiff = System.currentTimeMillis() - inventoryCloseTime
if (timeDiff > 2_000) {
return PurseChangeCause.GAIN_MOB_KILL
}
-
}
return PurseChangeCause.GAIN_UNKNOWN
} else {
@@ -55,7 +60,11 @@ class PurseAPI {
return PurseChangeCause.LOSE_SLAYER_QUEST_STARTED
}
+ if (diff == -6_666_666.0 || diff == -666_666.0) {
+ return PurseChangeCause.LOSE_DICE_ROLL_COST
+ }
+
return PurseChangeCause.LOSE_UNKNOWN
}
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/RenderData.kt b/src/main/java/at/hannibal2/skyhanni/data/RenderData.kt
index f109ea01b..9a57f87cc 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/RenderData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/RenderData.kt
@@ -48,4 +48,4 @@ class RenderData {
if (!SkyHanniDebugsAndTests.globalRender) return
LorenzRenderWorldEvent(event.partialTicks).postAndCatch()
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt
index 59d250b0a..7079ae6fd 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.data
import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.config.ConfigFileType
import at.hannibal2.skyhanni.events.InventoryCloseEvent
import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
@@ -21,6 +22,7 @@ import at.hannibal2.skyhanni.utils.NEUItems.getNpcPriceOrNull
import at.hannibal2.skyhanni.utils.NEUItems.getPrice
import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
+import at.hannibal2.skyhanni.utils.StringUtils.matches
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import com.google.gson.annotations.Expose
import net.minecraft.item.ItemStack
@@ -32,6 +34,7 @@ object SackAPI {
private var lastOpenedInventory = ""
var inSackInventory = false
+
// TODO USE SH-REPO
private val sackPattern = "^(.* Sack|Enchanted .* Sack)$".toPattern()
private val numPattern =
@@ -66,7 +69,7 @@ object SackAPI {
val inventoryName = event.inventoryName
val isNewInventory = inventoryName != lastOpenedInventory
lastOpenedInventory = inventoryName
- val match = sackPattern.matcher(inventoryName).matches()
+ val match = sackPattern.matches(inventoryName)
if (!match) return
val stacks = event.inventoryItems
isRuneSack = inventoryName == "Runes Sack"
@@ -301,7 +304,7 @@ object SackAPI {
private fun saveSackData() {
ProfileStorageData.sackProfiles?.sackContents = sackData
- SkyHanniMod.configManager.saveSackData("saving-data")
+ SkyHanniMod.configManager.saveConfig(ConfigFileType.SACKS, "saving-data")
}
data class SackGemstone(
diff --git a/src/main/java/at/hannibal2/skyhanni/data/SlayerAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/SlayerAPI.kt
index f3c23700d..2a6b99297 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/SlayerAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/SlayerAPI.kt
@@ -15,7 +15,6 @@ import at.hannibal2.skyhanni.utils.NEUItems.getNpcPriceOrNull
import at.hannibal2.skyhanni.utils.NEUItems.getPrice
import at.hannibal2.skyhanni.utils.NumberUtil
import at.hannibal2.skyhanni.utils.RecalculatingValue
-import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import com.google.common.cache.CacheBuilder
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import java.util.concurrent.TimeUnit
@@ -29,6 +28,7 @@ object SlayerAPI {
var questStartTime = 0L
var isInCorrectArea = false
+ var isInAnyArea = false
var latestSlayerCategory = ""
private var latestProgressChangeTime = 0L
var latestWrongAreaWarning = 0L
@@ -40,22 +40,6 @@ object SlayerAPI {
System.currentTimeMillis()
} else latestProgressChangeTime
-
- // TODO use repo
- fun ignoreSlayerDrop(name: String) = when (name.removeColor()) {
- // maybe everywhere?
- "Stone" -> true
- "Head" -> true
-
- // Spider
- "Cobweb" -> true
-
- // Blaze
- "Water Bottle" -> true
-
- else -> false
- }
-
fun getItemNameAndPrice(internalName: NEUInternalName, amount: Int): Pair<String, Double> {
val key = internalName to amount
nameCache.getIfPresent(key)?.let {
@@ -139,9 +123,12 @@ object SlayerAPI {
if (event.isMod(5)) {
isInCorrectArea = if (LorenzUtils.isStrandedProfile) {
+ isInAnyArea = true
true
} else {
- getSlayerTypeForCurrentArea() == getActiveSlayer()
+ val slayerTypeForCurrentArea = getSlayerTypeForCurrentArea()
+ isInAnyArea = slayerTypeForCurrentArea != null
+ slayerTypeForCurrentArea == getActiveSlayer() && slayerTypeForCurrentArea != null
}
}
}
@@ -178,4 +165,4 @@ object SlayerAPI {
else -> null
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/model/ComposterUpgrade.kt b/src/main/java/at/hannibal2/skyhanni/data/model/ComposterUpgrade.kt
index 4712689dc..627bfdef7 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/model/ComposterUpgrade.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/model/ComposterUpgrade.kt
@@ -10,9 +10,10 @@ enum class ComposterUpgrade(val displayName: String, val slotNumber: Int) {
companion object {
private fun regexValues() = entries.joinToString("|") { it.displayName }
+
// TODO USE SH-REPO
val regex = "§a(?<name>${regexValues()})(?: (?<level>.*))?".toPattern()
fun getByName(name: String) = entries.firstOrNull { it.displayName == name }
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/repo/RepoManager.kt b/src/main/java/at/hannibal2/skyhanni/data/repo/RepoManager.kt
index 593d9a652..9dcba5e8f 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/repo/RepoManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/repo/RepoManager.kt
@@ -83,7 +83,7 @@ class RepoManager(private val configLocation: File) {
if (unsuccessfulConstants.isEmpty()) {
if (command) {
- LorenzUtils.chat("§e[SkyHanni] §7The repo is already up to date!")
+ LorenzUtils.chat("§7The repo is already up to date!")
atomicShouldManuallyReload.set(false)
}
return@supplyAsync false
@@ -156,12 +156,13 @@ class RepoManager(private val configLocation: File) {
}
comp.complete(null)
if (answerMessage.isNotEmpty() && !error) {
- LorenzUtils.chat("§e[SkyHanni] §a$answerMessage")
+ LorenzUtils.chat("§a$answerMessage")
}
if (error) {
LorenzUtils.clickableChat(
- "§e[SkyHanni] Error with the repo detected, try /shupdaterepo to fix it!",
- "shupdaterepo"
+ "Error with the repo detected, try /shupdaterepo to fix it!",
+ "shupdaterepo",
+ prefixColor = "§c"
)
if (unsuccessfulConstants.isEmpty()) {
unsuccessfulConstants.add("All Constants")
@@ -174,9 +175,12 @@ class RepoManager(private val configLocation: File) {
fun displayRepoStatus(joinEvent: Boolean) {
if (joinEvent) {
if (unsuccessfulConstants.isNotEmpty()) {
- LorenzUtils.chat("§c[SkyHanni] §7Repo Issue! Some features may not work. Please report this error on the Discord!")
- LorenzUtils.chat("§7Repo Auto Update Value: §c${SkyHanniMod.feature.dev.repoAutoUpdate}")
- LorenzUtils.chat("§7If you have Repo Auto Update turned off, please try turning that on.\n§cUnsuccessful Constants §7(${unsuccessfulConstants.size}):")
+ LorenzUtils.error(
+ "§7Repo Issue! Some features may not work. Please report this error on the Discord!\n"
+ + "§7Repo Auto Update Value: §c${SkyHanniMod.feature.dev.repoAutoUpdate}\n"
+ + "§7If you have Repo Auto Update turned off, please try turning that on.\n"
+ + "§cUnsuccessful Constants §7(${unsuccessfulConstants.size}):"
+ )
for (constant in unsuccessfulConstants) {
LorenzUtils.chat(" §e- §7$constant")
}
@@ -184,14 +188,14 @@ class RepoManager(private val configLocation: File) {
return
}
if (unsuccessfulConstants.isEmpty() && successfulConstants.isNotEmpty()) {
- LorenzUtils.chat("§a[SkyHanni] Repo working fine!")
+ LorenzUtils.chat("Repo working fine!", prefixColor = "§a")
return
}
- if (successfulConstants.isNotEmpty()) LorenzUtils.chat("§a[SkyHanni] Successful Constants §7(${successfulConstants.size}):")
+ if (successfulConstants.isNotEmpty()) LorenzUtils.chat("Successful Constants §7(${successfulConstants.size}):", prefixColor = "§a")
for (constant in successfulConstants) {
LorenzUtils.chat(" §a- §7$constant")
}
- LorenzUtils.chat("§c[SkyHanni] Unsuccessful Constants §7(${unsuccessfulConstants.size}):")
+ LorenzUtils.chat("Unsuccessful Constants §7(${unsuccessfulConstants.size}):")
for (constant in unsuccessfulConstants) {
LorenzUtils.chat(" §e- §7$constant")
}
diff --git a/src/main/java/at/hannibal2/skyhanni/events/EntityEquipmentChangeEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/EntityEquipmentChangeEvent.kt
index 26705ab5e..eecc132ca 100644
--- a/src/main/java/at/hannibal2/skyhanni/events/EntityEquipmentChangeEvent.kt
+++ b/src/main/java/at/hannibal2/skyhanni/events/EntityEquipmentChangeEvent.kt
@@ -9,6 +9,10 @@ data class EntityEquipmentChangeEvent(
val newItemStack: ItemStack?
) : LorenzEvent() {
val isHead get() = equipmentSlot == EQUIPMENT_SLOT_HEAD
+ val isChest get() = equipmentSlot == EQUIPMENT_SLOT_CHEST
+ val isLeggings get() = equipmentSlot == EQUIPMENT_SLOT_LEGGINGS
+ val isFeet get() = equipmentSlot == EQUIPMENT_SLOT_FEET
+ val isHand get() = equipmentSlot == EQUIPMENT_SLOT_HAND
companion object {
const val EQUIPMENT_SLOT_HEAD = 4
@@ -17,4 +21,4 @@ data class EntityEquipmentChangeEvent(
const val EQUIPMENT_SLOT_FEET = 1
const val EQUIPMENT_SLOT_HAND = 0
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/events/FishingBobberCastEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/FishingBobberCastEvent.kt
new file mode 100644
index 000000000..01ea0222e
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/events/FishingBobberCastEvent.kt
@@ -0,0 +1,5 @@
+package at.hannibal2.skyhanni.events
+
+import net.minecraft.entity.projectile.EntityFishHook
+
+class FishingBobberCastEvent(val bobber: EntityFishHook) : LorenzEvent()
diff --git a/src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt
index 2f39e381d..21f9d07e8 100644
--- a/src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt
+++ b/src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt
@@ -40,7 +40,7 @@ abstract class LorenzEvent : Event() {
}
if (errors > visibleErrors) {
val hiddenErrors = errors - visibleErrors
- LorenzUtils.chat("§c[SkyHanni] $hiddenErrors more errors in $eventName are hidden!")
+ LorenzUtils.error("$hiddenErrors more errors in $eventName are hidden!")
}
return if (isCancelable) isCanceled else false
}
diff --git a/src/main/java/at/hannibal2/skyhanni/events/PurseChangeEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/PurseChangeEvent.kt
index 50343a7d9..d776fe32b 100644
--- a/src/main/java/at/hannibal2/skyhanni/events/PurseChangeEvent.kt
+++ b/src/main/java/at/hannibal2/skyhanni/events/PurseChangeEvent.kt
@@ -5,8 +5,10 @@ class PurseChangeEvent(val coins: Double, val reason: PurseChangeCause) : Lorenz
enum class PurseChangeCause {
GAIN_MOB_KILL,
GAIN_TALISMAN_OF_COINS,
+ GAIN_DICE_ROLL,
GAIN_UNKNOWN,
LOSE_SLAYER_QUEST_STARTED,
+ LOSE_DICE_ROLL_COST,
LOSE_UNKNOWN,
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/events/RenderEntityOutlineEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/RenderEntityOutlineEvent.kt
index 21e18bd6c..6a197de6c 100644
--- a/src/main/java/at/hannibal2/skyhanni/events/RenderEntityOutlineEvent.kt
+++ b/src/main/java/at/hannibal2/skyhanni/events/RenderEntityOutlineEvent.kt
@@ -7,7 +7,7 @@ import net.minecraft.entity.item.EntityItemFrame
import java.util.function.Consumer
class RenderEntityOutlineEvent(theType: Type?, potentialEntities: HashSet<Entity>?) :
- LorenzEvent() {
+ LorenzEvent() {
/**
* The phase of the event (see [Type]
@@ -115,4 +115,4 @@ class RenderEntityOutlineEvent(theType: Type?, potentialEntities: HashSet<Entity
NO_XRAY
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/events/entity/ItemAddInInventoryEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/entity/ItemAddInInventoryEvent.kt
new file mode 100644
index 000000000..6b9747adf
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/events/entity/ItemAddInInventoryEvent.kt
@@ -0,0 +1,6 @@
+package at.hannibal2.skyhanni.events.entity
+
+import at.hannibal2.skyhanni.events.LorenzEvent
+import at.hannibal2.skyhanni.utils.NEUInternalName
+
+class ItemAddInInventoryEvent(val internalName: NEUInternalName, val amount: Int) : LorenzEvent()
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarCancelledBuyOrderClipboard.kt b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarCancelledBuyOrderClipboard.kt
index 3fce3b4d3..38e012128 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarCancelledBuyOrderClipboard.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarCancelledBuyOrderClipboard.kt
@@ -42,7 +42,7 @@ class BazaarCancelledBuyOrderClipboard {
patternCancelledMessage.matchMatcher(event.message) {
event.blockedReason = "bazaar cancelled buy order clipbaord"
val coins = group("coins")
- LorenzUtils.chat("§e[SkyHanni] Bazaar buy order cancelled. $latestAmount saved to clipboard. ($coins coins)")
+ LorenzUtils.chat("Bazaar buy order cancelled. $latestAmount saved to clipboard. ($coins coins)")
latestAmount?.let { OSUtils.copyToClipboard(it.replace(",", "")) }
latestAmount = null
@@ -50,4 +50,4 @@ class BazaarCancelledBuyOrderClipboard {
}
fun isEnabled() = LorenzUtils.inSkyBlock && SkyHanniMod.feature.bazaar.cancelledBuyOrderClipboard
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardDisplay.kt
index 0badd1e57..ee1fc5874 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardDisplay.kt
@@ -24,6 +24,7 @@ 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()
@@ -51,11 +52,11 @@ class BingoCardDisplay {
fun toggleCommand() {
if (!LorenzUtils.isBingoProfile) {
- LorenzUtils.chat("§cThis command only works on a bingo profile!")
+ LorenzUtils.userError("This command only works on a bingo profile!")
return
}
if (!config.enabled) {
- LorenzUtils.chat("§cBingo Card is disabled in the config!")
+ LorenzUtils.userError("Bingo Card is disabled in the config!")
return
}
toggleMode()
@@ -189,4 +190,4 @@ class BingoCardDisplay {
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
event.move(2, "bingo", "event.bingo")
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoNextStepHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoNextStepHelper.kt
index fd077824b..2960b2d22 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoNextStepHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoNextStepHelper.kt
@@ -28,6 +28,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class BingoNextStepHelper {
private val config get() = SkyHanniMod.feature.event.bingo.bingoCard
private var dirty = true
+
// TODO USE SH-REPO
private val crystalObtainedPattern = " *§r§e(?<crystalName>Topaz|Sapphire|Jade|Amethyst|Amber) Crystal".toPattern()
private val itemIslandRequired = mutableMapOf<String, IslandVisitStep>()
@@ -85,7 +86,7 @@ class BingoNextStepHelper {
}
if (!step.done && !parentDone && requirementsToDo == 0 && !currentSteps.contains(step)) {
- currentSteps = currentSteps.editCopy { add(step) }
+ currentSteps = currentSteps.editCopy { add(step) }
}
}
@@ -200,7 +201,7 @@ class BingoNextStepHelper {
done = true
updateResult()
if (!silent && config.stepHelper) {
- LorenzUtils.chat("§e[SkyHanni] A bingo goal step is done! ($displayName)")
+ LorenzUtils.chat("A bingo goal step is done! ($displayName)")
}
}
@@ -248,22 +249,22 @@ class BingoNextStepHelper {
if (description == "Craft an Emerald Ring.") {
return CraftStep("Emerald Ring") requires (
- ItemsStep(
- "32x Enchanted Emerald",
- "Emerald",
- 160 * 32,
- mapOf("Emerald" to 1, "Enchanted Emerald" to 160)
- ) requires IslandType.DWARVEN_MINES.getStep())
+ ItemsStep(
+ "32x Enchanted Emerald",
+ "Emerald",
+ 160 * 32,
+ mapOf("Emerald" to 1, "Enchanted Emerald" to 160)
+ ) requires IslandType.DWARVEN_MINES.getStep())
}
if (description == "Obtain a Mathematical Hoe Blueprint.") {
return CraftStep("Mathematical Hoe Blueprint") requires (
- ItemsStep(
- "32x Jacob's Ticket",
- "Jacob's Ticket",
- 32,
- mapOf("Jacob's Ticket" to 1)
- ).addItemRequirements() requires IslandType.GARDEN.getStep())
+ ItemsStep(
+ "32x Jacob's Ticket",
+ "Jacob's Ticket",
+ 32,
+ mapOf("Jacob's Ticket" to 1)
+ ).addItemRequirements() requires IslandType.GARDEN.getStep())
}
crystalPattern.matchMatcher(description) {
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 5f49d40ce..e686191aa 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/CompactBingoChat.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/CompactBingoChat.kt
@@ -93,7 +93,7 @@ class CompactBingoChat {
if (message.contains("Trade") || message.contains("Recipe")) {
val text = message.removeColor().replace(" ", "")
if (text == "Trade" || text == "Recipe") {
- collectionLevelUpLastLine?.let { LorenzUtils.chat(it) }
+ collectionLevelUpLastLine?.let { LorenzUtils.chat(it, false) }
}
} else {
collectionLevelUpLastLine = message
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 0dc99f595..8657f76ee 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/MinionCraftHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/MinionCraftHelper.kt
@@ -23,6 +23,7 @@ import kotlin.time.Duration.Companion.seconds
class MinionCraftHelper {
private val config get() = SkyHanniMod.feature.event.bingo
+
// TODO USE SH-REPO
private var minionNamePattern = "(?<name>.*) Minion (?<number>.*)".toPattern()
private var display = emptyList<String>()
diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilterGui.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilterGui.kt
index 05a3ba456..b9a9a6e0b 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilterGui.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilterGui.kt
@@ -61,11 +61,11 @@ class ChatFilterGui(private val history: List<ChatManager.MessageFilteringResult
if (mouseX in 0..w && mouseY in 0..(size * 10) && (isMouseButtonDown && !wasMouseButtonDown)) {
if (KeyboardManager.isShiftKeyDown()) {
OSUtils.copyToClipboard(IChatComponent.Serializer.componentToJson(msg.message))
- LorenzUtils.chat("Copied structured chat line to clipboard")
+ LorenzUtils.chat("Copied structured chat line to clipboard", false)
} else {
val message = LorenzUtils.stripVanillaMessage(msg.message.formattedText)
OSUtils.copyToClipboard(message)
- LorenzUtils.chat("Copied chat line to clipboard")
+ LorenzUtils.chat("Copied chat line to clipboard", false)
}
}
mouseY -= size * 10
@@ -76,7 +76,7 @@ class ChatFilterGui(private val history: List<ChatManager.MessageFilteringResult
GlStateManager.color(1f, 1f, 1f, 1f)
}
- fun splitLine(comp: IChatComponent): List<IChatComponent> {
+ private fun splitLine(comp: IChatComponent): List<IChatComponent> {
return GuiUtilRenderComponents.splitText(
comp,
w - (ChatManager.ActionKind.maxLength + reasonMaxLength + 10 + 10),
@@ -93,11 +93,11 @@ class ChatFilterGui(private val history: List<ChatManager.MessageFilteringResult
}
}
- fun setScroll(newScroll: Double) {
+ private fun setScroll(newScroll: Double) {
this.scroll = newScroll.coerceAtMost(historySize - h + 10.0).coerceAtLeast(0.0)
}
- fun drawMultiLineText(comp: IChatComponent, xPos: Int): Int {
+ private fun drawMultiLineText(comp: IChatComponent, xPos: Int): Int {
val modifiedSplitText = splitLine(comp)
for (line in modifiedSplitText) {
drawString(
@@ -118,4 +118,4 @@ class ChatFilterGui(private val history: List<ChatManager.MessageFilteringResult
setScroll(scroll - Mouse.getEventDWheel())
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/CompactBestiaryChatMessage.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/CompactBestiaryChatMessage.kt
index 192e51297..fa2dfaa06 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/chat/CompactBestiaryChatMessage.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/chat/CompactBestiaryChatMessage.kt
@@ -9,18 +9,18 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class CompactBestiaryChatMessage {
- var inBestiary = false
- var bestiaryDescription = mutableListOf<String>()
- var acceptMoreDescription = true
+ private var inBestiary = false
+ private var bestiaryDescription = mutableListOf<String>()
+ private var acceptMoreDescription = true
var command = ""
private var blockedLines = 0
- var lastBorder: IChatComponent? = null
- var lastEmpty: IChatComponent? = null
+ private var lastBorder: IChatComponent? = null
+ private var lastEmpty: IChatComponent? = null
- var milestoneMessage: String? = null
+ private var milestoneMessage: String? = null
- val milestonePattern = "^.+(§8\\d{1,3}➡§e\\d{1,3})$".toRegex()
+ private val milestonePattern = "^.+(§8\\d{1,3}➡§e\\d{1,3})$".toRegex()
@SubscribeEvent
fun onChatMessage(event: LorenzChatEvent) {
@@ -66,13 +66,13 @@ class CompactBestiaryChatMessage {
inBestiary = false
val title = bestiaryDescription[1]
- LorenzUtils.hoverableChat("§6§lBESTIARY §r$title", bestiaryDescription.dropLast(1), command)
+ LorenzUtils.hoverableChat("§6§lBESTIARY §r$title", bestiaryDescription.dropLast(1), command, false)
bestiaryDescription.clear()
acceptMoreDescription = true
} else {
milestoneMessage?.let {
- LorenzUtils.chat("§6§lBESTIARY MILESTONE $it")
+ LorenzUtils.chat("§6§lBESTIARY MILESTONE $it", false)
milestoneMessage = null
}
milestonePattern.matchEntire(message)?.let {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/PlayerDeathMessages.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/PlayerDeathMessages.kt
index 943490a55..8448627f5 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/chat/PlayerDeathMessages.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/chat/PlayerDeathMessages.kt
@@ -37,15 +37,17 @@ class PlayerDeathMessages {
val message = event.message
deathMessagePattern.matchMatcher(message) {
val name = group("name")
- if (SkyHanniMod.feature.markedPlayers.highlightInChat && !LorenzUtils.inDungeons && !LorenzUtils.inKuudraFight && MarkedPlayerManager.isMarkedPlayer(name)) {
+ if (SkyHanniMod.feature.markedPlayers.highlightInChat &&
+ !LorenzUtils.inDungeons && !LorenzUtils.inKuudraFight && MarkedPlayerManager.isMarkedPlayer(name)
+ ) {
val reason = group("reason").removeColor()
- LorenzUtils.chat(" §c☠ §e$name §7$reason")
+ LorenzUtils.chat(" §c☠ §e$name §7$reason", false)
event.blockedReason = "marked_player_death"
return
}
-
- if (isHideFarDeathsEnabled() && System.currentTimeMillis() > lastTimePlayerSeen.getOrDefault(name, 0) + 30_000) {
+ val time = System.currentTimeMillis() > lastTimePlayerSeen.getOrDefault(name, 0) + 30_000
+ if (isHideFarDeathsEnabled() && time) {
event.blockedReason = "far_away_player_death"
}
}
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 6105d762a..2cfdb5dc9 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt
@@ -144,15 +144,15 @@ class Translator {
coroutineScope.launch {
val translation = getTranslationToEnglish(message)
- if (translation == "Unable to translate!") LorenzUtils.chat("§c[SkyHanni] Unable to translate message :( (is it in English?)")
- else LorenzUtils.chat("§e[SkyHanni] Found translation: §f$translation")
+ if (translation == "Unable to translate!") LorenzUtils.userError("Unable to translate message :( (is it in English?)")
+ else LorenzUtils.chat("Found translation: §f$translation")
}
}
fun fromEnglish(args: Array<String>) {
if (!isEnabled()) return
if (args.size < 2 || args[0].length != 2) { // args[0] is the language code
- LorenzUtils.chat("§cUsage: /shcopytranslation <two letter language code (at the end of a translation)> <message>")
+ LorenzUtils.userError("Usage: /shcopytranslation <two letter language code (at the end of a translation)> <message>")
return
}
val language = args[0]
@@ -163,7 +163,7 @@ class Translator {
coroutineScope.launch {
val translation = getTranslationFromEnglish(message, language)
- LorenzUtils.chat("§e[SkyHanni] Copied translation to clipboard: $translation")
+ LorenzUtils.chat("Copied translation to clipboard: $translation")
OSUtils.copyToClipboard(translation)
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/WatchdogHider.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/WatchdogHider.kt
index 739eaa123..c5eefc603 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/chat/WatchdogHider.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/chat/WatchdogHider.kt
@@ -23,11 +23,13 @@ class WatchdogHider {
startLineComponent = event.chatComponent
blockedLines = 0
}
+
watchdogAnnouncementLine -> {
ChatManager.retractMessage(startLineComponent, "watchdog")
startLineComponent = null
inWatchdog = true
}
+
watchdogEndLine -> {
event.blockedReason = "watchdog"
inWatchdog = false
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 9501b9d49..ed1a256d5 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
@@ -1,7 +1,6 @@
package at.hannibal2.skyhanni.features.chat.playerchat
import at.hannibal2.skyhanni.events.RepositoryReloadEvent
-import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.MultiFilter
import at.hannibal2.skyhanni.utils.jsonobjects.PlayerChatFilterJson
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
@@ -40,6 +39,5 @@ class PlayerChatFilter {
countCategories++
countFilters += filter.count()
}
- LorenzUtils.debug("Loaded $countFilters filters in $countCategories categories from repo")
}
}
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 981b7b33a..469fc2f3c 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaFontRenderer.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaFontRenderer.kt
@@ -36,7 +36,7 @@ class ChromaFontRenderer(private val baseColor: Int) {
}
}
- fun newChromaEnv() : ChromaFontRenderer {
+ fun newChromaEnv(): ChromaFontRenderer {
if (ShaderHelper.areShadersSupported()) {
ChromaShaderManager.begin()
GlStateManager.shadeModel(GL11.GL_SMOOTH)
@@ -44,7 +44,7 @@ class ChromaFontRenderer(private val baseColor: Int) {
return this
}
- fun bindActualColor() : ChromaFontRenderer {
+ fun bindActualColor(): ChromaFontRenderer {
GlStateManager.color(
ColorUtils.getRed(baseColor).toFloat() / 255f,
ColorUtils.getGreen(baseColor).toFloat() / 255f,
@@ -54,7 +54,7 @@ class ChromaFontRenderer(private val baseColor: Int) {
return this
}
- fun endChromaEnv() : ChromaFontRenderer {
+ fun endChromaEnv(): ChromaFontRenderer {
if (ShaderHelper.areShadersSupported()) {
ChromaShaderManager.end()
GlStateManager.shadeModel(GL11.GL_FLAT)
@@ -63,4 +63,4 @@ class ChromaFontRenderer(private val baseColor: Int) {
}
fun getChromaState() = chromaOn
-} \ No newline at end of file
+}
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 00215b032..e7bedbdcd 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaShader.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaShader.kt
@@ -22,7 +22,8 @@ object ChromaShader : Shader("chroma", "chroma") {
SkyHanniMod.feature.chroma.chromaSize * (Minecraft.getMinecraft().displayWidth / 100f)
}
registerUniform(Uniform.UniformType.FLOAT, "timeOffset") {
- var ticks = (MinecraftData.totalTicks / 2) + (Minecraft.getMinecraft() as AccessorMinecraft).timer.renderPartialTicks
+ var ticks =
+ (MinecraftData.totalTicks / 2) + (Minecraft.getMinecraft() as AccessorMinecraft).timer.renderPartialTicks
ticks = when (SkyHanniMod.feature.chroma.chromaDirection) {
0, 2 -> ticks
@@ -44,4 +45,4 @@ object ChromaShader : Shader("chroma", "chroma") {
}
}
}
-} \ 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 4f202fc62..ebe6e9397 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
@@ -361,7 +361,10 @@ class DamageIndicatorManager {
entityData.timeLastTick = System.currentTimeMillis()
return entity.uniqueID to entityData
} catch (e: Throwable) {
- ErrorManager.logError(e, "Error checking damage indicator entity $entity")
+ ErrorManager.logErrorWithData(
+ e, "Error checking damage indicator entity",
+ "entity" to entity,
+ )
return 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 7fb000766..b65021067 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,7 +2,6 @@ package at.hannibal2.skyhanni.features.combat.endernodetracker
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-import at.hannibal2.skyhanni.config.Storage
import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.data.ProfileStorageData
import at.hannibal2.skyhanni.events.ConfigLoadEvent
@@ -14,29 +13,51 @@ import at.hannibal2.skyhanni.events.SackChangeEvent
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalNameOrNull
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
+import at.hannibal2.skyhanni.utils.LorenzUtils.addOrPut
import at.hannibal2.skyhanni.utils.LorenzUtils.afterChange
-import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy
import at.hannibal2.skyhanni.utils.NEUItems.getNpcPriceOrNull
import at.hannibal2.skyhanni.utils.NEUItems.getPriceOrNull
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.NumberUtil.format
-import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
+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
-class EnderNodeTracker {
+object EnderNodeTracker {
private val config get() = SkyHanniMod.feature.combat.enderNodeTracker
- private val storage get() = ProfileStorageData.profileSpecific?.enderNodeTracker
- private var totalEnderArmor = 0
private var miteGelInInventory = 0
- private var display = emptyList<List<Any>>()
- private var lootProfit = mapOf<EnderNode, Double>()
private val enderNodeRegex = Regex("""ENDER NODE!.+You found (\d+x )?§r(.+)§r§f!""")
private val endermanRegex = Regex("""(RARE|PET) DROP! §r(.+) §r§b\(""")
+ private val tracker = SkyHanniTracker("Ender Node Tracker", { Data() }, { it.enderNodeTracker }) {
+ formatDisplay(
+ drawDisplay(it)
+ )
+ }
+
+ class Data : TrackerData() {
+
+ override fun reset() {
+ totalNodesMined = 0
+ totalEndermiteNests = 0
+ lootCount.clear()
+ }
+
+ @Expose
+ var totalNodesMined = 0
+
+ @Expose
+ var totalEndermiteNests = 0
+
+ @Expose
+ var lootCount: MutableMap<EnderNode, Int> = mutableMapOf()
+ }
+
@SubscribeEvent
fun onChat(event: LorenzChatEvent) {
if (!config.enabled) return
@@ -47,11 +68,12 @@ class EnderNodeTracker {
val message = event.message.trim()
var item: String? = null
var amount = 1
- val storage = storage ?: return
// check whether the loot is from an ender node or an enderman
enderNodeRegex.find(message)?.let {
- storage.totalNodesMined++
+ tracker.modify { storage ->
+ storage.totalNodesMined++
+ }
amount = it.groups[1]?.value?.substringBefore("x")?.toIntOrNull() ?: 1
item = it.groups[2]?.value
} ?: endermanRegex.find(message)?.let {
@@ -61,20 +83,19 @@ class EnderNodeTracker {
when {
item == null -> return
- isEnderArmor(item) -> totalEnderArmor++
item == "§cEndermite Nest" -> {
- storage.totalEndermiteNests++
+ tracker.modify { storage ->
+ storage.totalEndermiteNests++
+ }
}
}
// increment the count of the specific item found
EnderNode.entries.find { it.displayName == item }?.let {
- val old = storage.lootCount[it] ?: 0
- storage.lootCount = storage.lootCount.editCopy {
- this[it] = old + amount
+ tracker.modify { storage ->
+ storage.lootCount.addOrPut(it, amount)
}
}
- update()
}
@SubscribeEvent
@@ -91,16 +112,14 @@ class EnderNodeTracker {
if (!config.enabled) return
if (!ProfileStorageData.loaded) return
if (!isInTheEnd()) return
- val storage = storage ?: return
val change = event.sackChanges
.firstOrNull { it.internalName == EnderNode.MITE_GEL.internalName && it.delta > 0 }
?: return
- val old = storage.lootCount[EnderNode.MITE_GEL] ?: 0
- storage.lootCount = storage.lootCount.editCopy {
- this[EnderNode.MITE_GEL] = old + change.delta
+
+ tracker.modify { storage ->
+ storage.lootCount.addOrPut(EnderNode.MITE_GEL, change.delta)
}
- update()
}
@SubscribeEvent
@@ -108,7 +127,6 @@ class EnderNodeTracker {
if (!config.enabled) return
if (!isInTheEnd()) return
if (!ProfileStorageData.loaded) return
- val storage = storage ?: return
MinecraftExecutor.OnThread.execute {
val newMiteGelInInventory = Minecraft.getMinecraft().thePlayer.inventory.mainInventory
@@ -116,34 +134,28 @@ class EnderNodeTracker {
.sumOf { it.stackSize }
val change = newMiteGelInInventory - miteGelInInventory
if (change > 0) {
- val old = storage.lootCount[EnderNode.MITE_GEL] ?: 0
- storage.lootCount = storage.lootCount.editCopy {
- this[EnderNode.MITE_GEL] = old + change
+ tracker.modify { storage ->
+ storage.lootCount.addOrPut(EnderNode.MITE_GEL, change)
}
- update()
}
miteGelInInventory = newMiteGelInInventory
}
}
@SubscribeEvent
- fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
+ fun onRenderOverlay(event: GuiRenderEvent) {
if (!config.enabled) return
if (!isInTheEnd()) return
- config.position.renderStringsAndItems(display, posLabel = "Ender Node Tracker")
+
+ tracker.renderDisplay(config.position)
}
@SubscribeEvent
fun onConfigLoad(event: ConfigLoadEvent) {
config.textFormat.afterChange {
- update()
+ tracker.update()
}
- val storage = storage ?: return
-
- totalEnderArmor = storage.lootCount.filter { isEnderArmor(it.key.displayName) }
- .map { it.value }
- .sum()
- update()
+ tracker.update()
}
@SubscribeEvent
@@ -151,12 +163,12 @@ class EnderNodeTracker {
event.move(2, "misc.enderNodeTracker", "combat.enderNodeTracker")
}
- private fun calculateProfit(storage: Storage.ProfileSpecific.EnderNodeTracker): Map<EnderNode, Double> {
+ private fun calculateProfit(storage: Data): Map<EnderNode, Double> {
if (!ProfileStorageData.loaded) return emptyMap()
val newProfit = mutableMapOf<EnderNode, Double>()
storage.lootCount.forEach { (item, amount) ->
- val price = if (isEnderArmor(item.displayName)) {
+ val price = if (isEnderArmor(item)) {
10_000.0
} else {
(if (!LorenzUtils.noTradeMode) item.internalName.getPriceOrNull() else 0.0)
@@ -169,21 +181,15 @@ class EnderNodeTracker {
return newProfit
}
- private fun update() {
- val storage = storage ?: return
- lootProfit = calculateProfit(storage)
- display = formatDisplay(drawDisplay(storage))
- }
-
private fun isInTheEnd() = LorenzUtils.skyBlockArea == "The End"
- private fun isEnderArmor(displayName: String?) = when (displayName) {
- EnderNode.END_HELMET.displayName,
- EnderNode.END_CHESTPLATE.displayName,
- EnderNode.END_LEGGINGS.displayName,
- EnderNode.END_BOOTS.displayName,
- EnderNode.ENDER_NECKLACE.displayName,
- EnderNode.ENDER_GAUNTLET.displayName -> true
+ private fun isEnderArmor(displayName: EnderNode) = when (displayName) {
+ EnderNode.END_HELMET,
+ EnderNode.END_CHESTPLATE,
+ EnderNode.END_LEGGINGS,
+ EnderNode.END_BOOTS,
+ EnderNode.ENDER_NECKLACE,
+ EnderNode.ENDER_GAUNTLET -> true
else -> false
}
@@ -197,8 +203,8 @@ class EnderNodeTracker {
else -> null
}
- private fun drawDisplay(storage: Storage.ProfileSpecific.EnderNodeTracker) = buildList<List<Any>> {
- if (!ProfileStorageData.loaded) return emptyList<List<Any>>()
+ private fun drawDisplay(storage: Data) = buildList<List<Any>> {
+ val lootProfit = calculateProfit(storage)
addAsSingletonList("§5§lEnder Node Tracker")
addAsSingletonList("§d${storage.totalNodesMined.addSeparators()} Ender Nodes mined")
@@ -212,9 +218,11 @@ class EnderNodeTracker {
addAsSingletonList("§b$count ${item.displayName} §7(§6$profit§7)")
}
addAsSingletonList(" ")
+
+ val totalEnderArmor = calculateEnderArmor(storage)
addAsSingletonList(
"§b${totalEnderArmor.addSeparators()} §5Ender Armor " +
- "§7(§6${format(totalEnderArmor * 10_000)}§7)"
+ "§7(§6${format(totalEnderArmor * 10_000)}§7)"
)
for (item in EnderNode.entries.subList(11, 16)) {
val count = (storage.lootCount[item] ?: 0).addSeparators()
@@ -227,6 +235,11 @@ class EnderNodeTracker {
addAsSingletonList("§f$c§7-§a$u§7-§9$r§7-§5$e§7-§6$l §fEnderman Pet §7(§6$profit§7)")
}
+ private fun calculateEnderArmor(storage: Data) =
+ storage.lootCount.filter { isEnderArmor(it.key) }
+ .map { it.value }
+ .sum()
+
private fun formatDisplay(map: List<List<Any>>): List<List<Any>> {
if (!ProfileStorageData.loaded) return emptyList()
@@ -236,4 +249,8 @@ class EnderNodeTracker {
}
return newList
}
-} \ No newline at end of file
+
+ fun resetCommand(args: Array<String>) {
+ tracker.resetCommand(args, "shresetendernodetracker")
+ }
+}
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 959a303e8..56e70437c 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
@@ -39,6 +39,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
import at.hannibal2.skyhanni.utils.LorenzUtils.chat
import at.hannibal2.skyhanni.utils.LorenzUtils.clickableChat
+import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland
import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber
@@ -61,7 +62,7 @@ import kotlin.math.roundToLong
object GhostCounter {
val config get() = SkyHanniMod.feature.combat.ghostCounter
- val hidden get() = ProfileStorageData.profileSpecific?.ghostCounter
+ val storage get() = ProfileStorageData.profileSpecific?.ghostCounter
private var display = emptyList<List<Any>>()
var ghostCounterV3File =
File("." + File.separator + "config" + File.separator + "ChatTriggers" + File.separator + "modules" + File.separator + "GhostCounterV3" + File.separator + ".persistantData.json")
@@ -127,7 +128,7 @@ object GhostCounter {
}
val avgMagicFind = when (Option.TOTALDROPS.get()) {
0.0 -> "0"
- else -> "${((((hidden?.totalMF!! / Option.TOTALDROPS.get()) + Math.ulp(1.0)) * 100) / 100).roundToPrecision(2)}"
+ else -> "${((((storage?.totalMF!! / Option.TOTALDROPS.get()) + Math.ulp(1.0)) * 100) / 100).roundToPrecision(2)}"
}
val xpHourFormatting = textFormatting.xpHourFormatting
@@ -151,9 +152,9 @@ object GhostCounter {
}
val bestiaryFormatting = textFormatting.bestiaryFormatting
- val currentKill = hidden?.bestiaryCurrentKill?.toInt() ?: 0
- val killNeeded = hidden?.bestiaryKillNeeded?.toInt() ?: 0
- val nextLevel = hidden?.bestiaryNextLevel?.toInt() ?: -1
+ val currentKill = storage?.bestiaryCurrentKill?.toInt() ?: 0
+ val killNeeded = storage?.bestiaryKillNeeded?.toInt() ?: 0
+ val nextLevel = storage?.bestiaryNextLevel?.toInt() ?: -1
val bestiary = if (config.showMax) {
when (nextLevel) {
26 -> bestiaryFormatting.maxed.replace("%currentKill%", currentKill.addSeparators())
@@ -283,7 +284,7 @@ object GhostCounter {
Option.KILLCOMBO.add(num)
Option.SKILLXPGAINED.add(gained * num.roundToLong())
Option.SKILLXPGAINED.add(gained * num.roundToLong(), true)
- hidden?.bestiaryCurrentKill = hidden?.bestiaryCurrentKill?.plus(num) ?: num
+ storage?.bestiaryCurrentKill = storage?.bestiaryCurrentKill?.plus(num) ?: num
}
lastXp = res
}
@@ -292,8 +293,9 @@ object GhostCounter {
notifyCTModule = false
if (isUsingCTGhostCounter()) {
clickableChat(
- "§6[SkyHanni] GhostCounterV3 ChatTriggers module has been detected, do you want to import saved data ? Click here to import data",
- "shimportghostcounterdata"
+ "GhostCounterV3 ChatTriggers module has been detected, do you want to import saved data ? Click here to import data",
+ "shimportghostcounterdata",
+ prefixColor = "§6",
)
}
}
@@ -385,7 +387,7 @@ object GhostCounter {
Option.SORROWCOUNT, Option.VOLTACOUNT, Option.PLASMACOUNT, Option.GHOSTLYBOOTS -> {
opt.add(1.0)
opt.add(1.0, true)
- hidden?.totalMF = hidden?.totalMF?.plus(group("mf").substring(4).toDouble())
+ storage?.totalMF = storage?.totalMF?.plus(group("mf").substring(4).toDouble())
?: group("mf").substring(4).toDouble()
Option.TOTALDROPS.add(1.0)
if (opt == Option.SORROWCOUNT)
@@ -424,16 +426,16 @@ object GhostCounter {
val currentLevel = group("nextLevel").toInt()
when (val nextLevel = if (currentLevel >= 25) 26 else currentLevel + 1) {
26 -> {
- hidden?.bestiaryNextLevel = 26.0
- hidden?.bestiaryCurrentKill = 250_000.0
- hidden?.bestiaryKillNeeded = 0.0
+ storage?.bestiaryNextLevel = 26.0
+ storage?.bestiaryCurrentKill = 250_000.0
+ storage?.bestiaryKillNeeded = 0.0
}
else -> {
val killNeeded: Int = bestiaryData[nextLevel] ?: -1
- hidden?.bestiaryNextLevel = nextLevel.toDouble()
- hidden?.bestiaryCurrentKill = 0.0
- hidden?.bestiaryKillNeeded = killNeeded.toDouble()
+ storage?.bestiaryNextLevel = nextLevel.toDouble()
+ storage?.bestiaryCurrentKill = 0.0
+ storage?.bestiaryKillNeeded = killNeeded.toDouble()
}
}
update()
@@ -459,7 +461,7 @@ object GhostCounter {
val bestiaryNextLevel =
if ("§\\wGhost".toRegex().matches(ghostStack.displayName)) 1 else ghostStack.displayName.substring(8)
.romanToDecimal() + 1
- hidden?.bestiaryNextLevel = bestiaryNextLevel.toDouble()
+ storage?.bestiaryNextLevel = bestiaryNextLevel.toDouble()
var kills = 0.0
for (line in ghostStack.getLore()) {
val l = line.removeColor().trim()
@@ -467,8 +469,8 @@ object GhostCounter {
kills = "Kills: (.*)".toRegex().find(l)?.groupValues?.get(1)?.formatNumber()?.toDouble() ?: 0.0
}
ghostXPPattern.matchMatcher(line.removeColor().trim()) {
- hidden?.bestiaryCurrentKill = if (kills > 0) kills else group("current").formatNumber().toDouble()
- hidden?.bestiaryKillNeeded = group("total").formatNumber().toDouble()
+ storage?.bestiaryCurrentKill = if (kills > 0) kills else group("current").formatNumber().toDouble()
+ storage?.bestiaryKillNeeded = group("total").formatNumber().toDouble()
}
}
update()
@@ -476,10 +478,10 @@ object GhostCounter {
@SubscribeEvent
fun onConfigLoad(event: ConfigLoadEvent) {
- if (hidden?.configUpdateVersion == 0) {
+ if (storage?.configUpdateVersion == 0) {
config.textFormatting.bestiaryFormatting.base = " &6Bestiary %display%: &b%value%"
- chat("§e[SkyHanni] Your GhostCounter config has been automatically adjusted.")
- hidden?.configUpdateVersion = CONFIG_VALUE_VERSION
+ chat("Your GhostCounter config has been automatically adjusted.")
+ storage?.configUpdateVersion = CONFIG_VALUE_VERSION
}
}
@@ -488,7 +490,5 @@ object GhostCounter {
event.move(2, "ghostCounter", "combat.ghostCounter")
}
- fun isEnabled(): Boolean {
- return LorenzUtils.inSkyBlock && config.enabled && LorenzUtils.skyBlockIsland == IslandType.DWARVEN_MINES
- }
+ fun isEnabled() = config.enabled && IslandType.DWARVEN_MINES.isInIsland()
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostData.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostData.kt
index 70832980c..abcf2dbba 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostData.kt
@@ -6,16 +6,16 @@ import kotlin.math.roundToInt
object GhostData {
private var session = mutableMapOf(
- Option.KILLS to 0.0,
- Option.SORROWCOUNT to 0.0,
- Option.VOLTACOUNT to 0.0,
- Option.PLASMACOUNT to 0.0,
- Option.GHOSTLYBOOTS to 0.0,
- Option.BAGOFCASH to 0.0,
- Option.TOTALDROPS to 0.0,
- Option.SCAVENGERCOINS to 0.0,
- Option.MAXKILLCOMBO to 0.0,
- Option.SKILLXPGAINED to 0.0
+ Option.KILLS to 0.0,
+ Option.SORROWCOUNT to 0.0,
+ Option.VOLTACOUNT to 0.0,
+ Option.PLASMACOUNT to 0.0,
+ Option.GHOSTLYBOOTS to 0.0,
+ Option.BAGOFCASH to 0.0,
+ Option.TOTALDROPS to 0.0,
+ Option.SCAVENGERCOINS to 0.0,
+ Option.MAXKILLCOMBO to 0.0,
+ Option.SKILLXPGAINED to 0.0
)
val bestiaryData = mutableMapOf<Int, Int>().apply {
@@ -34,11 +34,11 @@ object GhostData {
11 -> 750
12 -> 1_500
13 -> 2_000
- 14,15,16,17 -> 2_500
+ 14, 15, 16, 17 -> 2_500
18 -> 3_000
- 19,20 -> 3_500
+ 19, 20 -> 3_500
21 -> 25_000
- 22,23,24,25 -> 50_000
+ 22, 23, 24, 25 -> 50_000
else -> 0
}
}
@@ -63,28 +63,28 @@ object GhostData {
if (s)
session[this] = session[this]?.plus(i) ?: i
else
- GhostCounter.hidden?.data?.set(this, GhostCounter.hidden?.data?.get(this)?.plus(i) ?: i)
+ GhostCounter.storage?.data?.set(this, GhostCounter.storage?.data?.get(this)?.plus(i) ?: i)
}
fun set(i: Double, s: Boolean = false) {
if (s)
session[this] = i
else
- GhostCounter.hidden?.data?.set(this, i)
+ GhostCounter.storage?.data?.set(this, i)
}
fun getInt(s: Boolean = false): Int {
return if (s)
session[this]?.roundToInt() ?: 0
else
- GhostCounter.hidden?.data?.get(this)?.roundToInt() ?: 0
+ GhostCounter.storage?.data?.get(this)?.roundToInt() ?: 0
}
fun get(s: Boolean = false): Double {
return if (s)
session[this] ?: 0.0
else
- GhostCounter.hidden?.data?.get(this) ?: 0.0
+ GhostCounter.storage?.data?.get(this) ?: 0.0
}
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostUtil.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostUtil.kt
index 6dffc62fc..9c5de8c43 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostUtil.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostUtil.kt
@@ -17,7 +17,7 @@ object GhostUtil {
opt.set(0.0)
opt.set(0.0, true)
}
- GhostCounter.hidden?.totalMF = 0.0
+ GhostCounter.storage?.totalMF = 0.0
GhostCounter.update()
}
@@ -65,7 +65,7 @@ object GhostUtil {
val c = ProfileStorageData.profileSpecific?.ghostCounter ?: return
if (isUsingCTGhostCounter()) {
if (c.ctDataImported) {
- LorenzUtils.chat("§e[SkyHanni] §cYou already imported GhostCounterV3 data!")
+ LorenzUtils.userError("You already imported GhostCounterV3 data!")
return
}
val json = ConfigManager.gson.fromJson(
@@ -79,13 +79,13 @@ object GhostUtil {
GhostData.Option.VOLTACOUNT.add(json["VoltaCount"].asDouble)
GhostData.Option.GHOSTLYBOOTS.add(json["GhostlyBootsCount"].asDouble)
GhostData.Option.KILLS.add(json["ghostsKilled"].asDouble)
- GhostCounter.hidden?.totalMF = GhostCounter.hidden?.totalMF?.plus(json["TotalMF"].asDouble)
+ GhostCounter.storage?.totalMF = GhostCounter.storage?.totalMF?.plus(json["TotalMF"].asDouble)
?: json["TotalMF"].asDouble
GhostData.Option.TOTALDROPS.add(json["TotalDrops"].asDouble)
c.ctDataImported = true
- LorenzUtils.chat("§e[SkyHanni] §aImported data successfully!")
+ LorenzUtils.chat("§aImported data successfully!")
} else
- LorenzUtils.chat("§e[SkyHanni] §cGhostCounterV3 ChatTriggers module not found!")
+ LorenzUtils.error("GhostCounterV3 ChatTriggers module not found!")
}
fun String.formatText(option: GhostData.Option) = formatText(option.getInt(), option.getInt(true))
@@ -120,7 +120,7 @@ object GhostUtil {
)
fun String.formatBestiary(currentKill: Int, killNeeded: Int): String {
- val bestiaryNextLevel = GhostCounter.hidden?.bestiaryNextLevel
+ val bestiaryNextLevel = GhostCounter.storage?.bestiaryNextLevel
val currentLevel =
bestiaryNextLevel?.let { if (it.toInt() < 0) "25" else "${it.toInt() - 1}" } ?: "§cNo Bestiary Level Data!"
val nextLevel = bestiaryNextLevel?.let { if (GhostCounter.config.showMax) "25" else "${it.toInt()}" }
@@ -141,4 +141,4 @@ object GhostUtil {
private fun percent(number: Double) =
100.0.coerceAtMost(((number / 250_000) * 100).roundToPrecision(4)).toString()
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/mobs/AreaMiniBossFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/mobs/AreaMiniBossFeatures.kt
index e63119a11..97d891020 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/combat/mobs/AreaMiniBossFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/combat/mobs/AreaMiniBossFeatures.kt
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.features.combat.mobs
import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.SlayerAPI
import at.hannibal2.skyhanni.events.EntityMaxHealthUpdateEvent
import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
@@ -47,8 +48,8 @@ class AreaMiniBossFeatures {
if (config.areaBossHighlight) {
val color = bossType.color.toColor().withAlpha(bossType.colorOpacity)
RenderLivingEntityHelper.setEntityColor(entity, color)
- { config.areaBossHighlight }
- RenderLivingEntityHelper.setNoHurtTime(entity) { config.areaBossHighlight }
+ { config.areaBossHighlight && SlayerAPI.isInAnyArea }
+ RenderLivingEntityHelper.setNoHurtTime(entity) { config.areaBossHighlight && SlayerAPI.isInAnyArea }
}
// TODO add sound
@@ -118,4 +119,4 @@ class AreaMiniBossFeatures {
),
;
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/mobs/SpawnTimers.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/mobs/SpawnTimers.kt
index 966f8ad06..81426c90f 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/combat/mobs/SpawnTimers.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/combat/mobs/SpawnTimers.kt
@@ -11,6 +11,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland
import at.hannibal2.skyhanni.utils.LorenzVec
import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText
import at.hannibal2.skyhanni.utils.SimpleTimeMark
+import at.hannibal2.skyhanni.utils.StringUtils.matches
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import at.hannibal2.skyhanni.utils.TimeUtils.format
import at.hannibal2.skyhanni.utils.toLorenzVec
@@ -25,8 +26,8 @@ class SpawnTimers {
private val arachneAltarLocation = LorenzVec(-283f, 51f, -179f)
private var arachneSpawnTime = SimpleTimeMark.farPast()
- private val arachneFragmentMessage = "^☄ [a-z0-9_]{2,22} placed an arachne's calling! something is awakening! \\(4/4\\)\$".toRegex()
- private val arachneCrystalMessage = "^☄ [a-z0-9_]{2,22} placed an arachne crystal! something is awakening!$".toRegex()
+ private val arachneFragmentMessage = "^☄ [a-z0-9_]{2,22} placed an arachne's calling! something is awakening! \\(4/4\\)\$".toPattern()
+ private val arachneCrystalMessage = "^☄ [a-z0-9_]{2,22} placed an arachne crystal! something is awakening!$".toPattern()
private var saveNextTickParticles = false
private var particleCounter = 0
private var tickTime: Long = 0
@@ -95,4 +96,4 @@ class SpawnTimers {
}
fun isEnabled() = IslandType.SPIDER_DEN.isInIsland() && LorenzUtils.skyBlockArea == "Arachne's Sanctuary" && config.showArachneSpawnTimer
-} \ 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 c515cb7f0..de7cc4408 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/commands/WikiManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/commands/WikiManager.kt
@@ -43,7 +43,7 @@ class WikiManager {
if (!(message.startsWith("/wiki"))) return
event.isCanceled = true
if (message == "/wiki") {
- LorenzUtils.chat("§e[SkyHanni] Opening the Fandom 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")) {
@@ -51,7 +51,7 @@ class WikiManager {
wikiTheItem(itemInHand)
} else {
val search = packet.message.split("/wiki ").last()
- LorenzUtils.chat("§e[SkyHanni] Searching the Fandom Wiki for §a$search")
+ LorenzUtils.chat("Searching the Fandom Wiki for §a$search")
val wikiUrlCustom = "$urlSearchPrefix$search&scope=internal"
OSUtils.openBrowser(wikiUrlCustom.replace(' ', '+'))
}
@@ -73,7 +73,7 @@ class WikiManager {
private fun wikiTheItem(item: ItemStack) {
val itemDisplayName = (item.nameWithEnchantment ?: return).replace("§a✔ ", "").replace("§c✖ ", "")
val internalName = item.getInternalName().asString()
- LorenzUtils.chat("§e[SkyHanni] Searching the Fandom Wiki for §a$itemDisplayName")
+ LorenzUtils.chat("Searching the Fandom Wiki for §a$itemDisplayName")
val wikiUrlSearch = if (internalName != "NONE") "$urlSearchPrefix$internalName&scope=internal"
else "$urlSearchPrefix${itemDisplayName.removeColor()}&scope=internal"
OSUtils.openBrowser(wikiUrlSearch.replace(' ', '+'))
diff --git a/src/main/java/at/hannibal2/skyhanni/features/cosmetics/ArrowTrail.kt b/src/main/java/at/hannibal2/skyhanni/features/cosmetics/ArrowTrail.kt
index f7a28d78d..da18e8d28 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/cosmetics/ArrowTrail.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/cosmetics/ArrowTrail.kt
@@ -21,7 +21,7 @@ import kotlin.time.toDuration
class ArrowTrail {
- private val config get() = SkyHanniMod.feature.misc.cosmeticConfig.arrowTrailConfig
+ private val config get() = SkyHanniMod.feature.misc.cosmetic.arrowTrail
private data class Line(val start: LorenzVec, val end: LorenzVec, val deathTime: SimpleTimeMark)
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 5dda13876..662ad68a0 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/cosmetics/CosmeticFollowingLine.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/cosmetics/CosmeticFollowingLine.kt
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.features.cosmetics
import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
@@ -19,7 +20,7 @@ import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds
class CosmeticFollowingLine {
- private val config get() = SkyHanniMod.feature.misc.cosmeticConfig.followingLineConfig
+ private val config get() = SkyHanniMod.feature.misc.cosmetic.followingLine
private var locations = mapOf<LorenzVec, LocationSpot>()
private var latestLocations = mapOf<LorenzVec, LocationSpot>()
@@ -120,4 +121,11 @@ class CosmeticFollowingLine {
}
}
}
+
+ @SubscribeEvent
+ fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
+ event.move(9, "misc.cosmeticConfig", "misc.cosmetic")
+ event.move(9, "misc.cosmeticConfig.followingLineConfig", "misc.cosmetic.followingLine")
+ event.move(9, "misc.cosmeticConfig.arrowTrailConfig", "misc.cosmetic.arrowTrail")
+ }
}
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 701ef74ee..6e5fc27bd 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCleanEnd.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCleanEnd.kt
@@ -73,7 +73,7 @@ class DungeonCleanEnd {
if (event.health <= 0.5) {
val dungeonFloor = DungeonAPI.dungeonFloor
- LorenzUtils.chat("§eFloor $dungeonFloor done!")
+ LorenzUtils.chat("§eFloor $dungeonFloor done!", false)
bossDone = true
}
}
@@ -90,7 +90,8 @@ class DungeonCleanEnd {
&& DungeonAPI.isOneOf("F3", "M3")
&& entity is EntityGuardian
&& entity.entityId != lastBossId
- && Minecraft.getMinecraft().thePlayer.isSneaking) {
+ && Minecraft.getMinecraft().thePlayer.isSneaking
+ ) {
return
}
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 834cd8fd6..8119535fd 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCopilot.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCopilot.kt
@@ -17,8 +17,8 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class DungeonCopilot {
- var nextStep = ""
- var searchForKey = false
+ private var nextStep = ""
+ private var searchForKey = false
@SubscribeEvent
fun onChatMessage(event: LorenzChatEvent) {
@@ -142,4 +142,4 @@ class DungeonCopilot {
event.move(3, "dungeon.copilotEnabled", "dungeon.dungeonCopilot.enabled")
event.move(3, "dungeon.copilotPos", "dungeon.dungeonCopilot.pos")
}
-} \ No newline at end of file
+}
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 b1db55502..36788e4b3 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonDeathCounter.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonDeathCounter.kt
@@ -53,7 +53,7 @@ class DungeonDeathCounter {
if (isDeathMessage(event.message)) {
deaths++
- LorenzUtils.chat("§c§l$deaths. DEATH!")
+ LorenzUtils.chat("§c§l$deaths. DEATH!", false)
update()
}
}
@@ -88,10 +88,13 @@ class DungeonDeathCounter {
fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
if (!isEnabled()) return
- SkyHanniMod.feature.dungeon.deathCounterPos.renderString(DungeonMilestonesDisplay.color + display, posLabel = "Dungeon Death Counter")
+ SkyHanniMod.feature.dungeon.deathCounterPos.renderString(
+ DungeonMilestonesDisplay.color + display,
+ posLabel = "Dungeon Death Counter"
+ )
}
private fun isEnabled(): Boolean {
return LorenzUtils.inDungeons && SkyHanniMod.feature.dungeon.deathCounterDisplay
}
-} \ No newline at end of file
+}
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 eceb28ad1..b824bc6a5 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonFinderFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonFinderFeatures.kt
@@ -26,7 +26,8 @@ class DungeonFinderFeatures {
private val pricePattern = "([0-9]{2,3}K|[0-9]{1,3}M|[0-9]+\\.[0-9]M|[0-9] ?mil)".toRegex(RegexOption.IGNORE_CASE)
private val carryPattern = "(carry|cary|carries|caries|comp|to cata [0-9]{2})".toRegex(RegexOption.IGNORE_CASE)
private val memberPattern = "^ §.*?§.: §.([A-Z]+)§. \\(§.([0-9]+)§.\\)".toRegex(RegexOption.IGNORE_CASE)
- private val ineligiblePattern = "^§c(Requires .*$|You don't meet the requirement!|Complete previous floor first!$)".toRegex()
+ private val ineligiblePattern =
+ "^§c(Requires .*$|You don't meet the requirement!|Complete previous floor first!$)".toRegex()
private val classLevelPattern = " §.(?<playerName>.*)§f: §e(?<className>.*)§b \\(§e(?<level>.*)§b\\)".toPattern()
private val notePattern = "^(§7§7Note: |§f[^§])".toRegex()
@@ -81,7 +82,7 @@ class DungeonFinderFeatures {
if (!LorenzUtils.inSkyBlock || LorenzUtils.skyBlockArea != "Dungeon Hub") return
if (event.inventoryName != "Catacombs Gate") return
- val lore = event.inventoryItems[45]?.getLore() ?: return
+ val lore = event.inventoryItems[45]?.getLore() ?: return
if (lore[0] == "§7View and select a dungeon class.") {
selectedClass = lore[2].split(" ").last().removeColor()
@@ -111,7 +112,7 @@ class DungeonFinderFeatures {
}
if (config.markPaidCarries) {
- val note = slot.stack.getLore().filter { notePattern.containsMatchIn(it) }.joinToString(" ") ?: ""
+ val note = slot.stack.getLore().filter { notePattern.containsMatchIn(it) }.joinToString(" ")
if (pricePattern.containsMatchIn(note) && carryPattern.containsMatchIn(note)) {
slot highlight LorenzColor.RED
diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonHideItems.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonHideItems.kt
index c1f8826b4..801b28ab4 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonHideItems.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonHideItems.kt
@@ -27,6 +27,8 @@ class DungeonHideItems {
private val hideParticles = mutableMapOf<EntityArmorStand, Long>()
private val movingSkeletonSkulls = mutableMapOf<EntityArmorStand, Long>()
+ // TODO put in skull data repo part
+
private val soulWeaverHider =
"eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMmYyNGVkNjg3NTMwNGZhNGExZjBjNzg1YjJjYjZhNmE3MjU2M2U5ZjNlMjRlYTU1ZTE4MTc4NDUyMTE5YWE2NiJ9fX0="
private val blessingTexture =
@@ -50,11 +52,7 @@ class DungeonHideItems {
private fun isSkeletonSkull(entity: EntityArmorStand): Boolean {
val itemStack = entity.inventory[4]
- if (itemStack != null && itemStack.cleanName() == "Skeleton Skull") {
- return true
- }
-
- return false
+ return itemStack != null && itemStack.cleanName() == "Skeleton Skull"
}
@SubscribeEvent
@@ -83,8 +81,7 @@ class DungeonHideItems {
event.isCanceled = true
}
- val itemStack = head
- if (itemStack != null && itemStack.cleanName() == "Superboom TNT") {
+ if (head != null && head.cleanName() == "Superboom TNT") {
event.isCanceled = true
hideParticles[entity] = System.currentTimeMillis()
}
@@ -241,4 +238,4 @@ class DungeonHideItems {
event.move(3, "dungeon.hideHealerOrbs", "dungeon.objectHider.hideHealerOrbs")
event.move(3, "dungeon.hideHealerFairy", "dungeon.objectHider.hideHealerFairy")
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonLividFinder.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonLividFinder.kt
index 48a0a9925..0c5b4fc52 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonLividFinder.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonLividFinder.kt
@@ -80,7 +80,7 @@ object DungeonLividFinder {
RenderLivingEntityHelper.setNoHurtTime(newLivid) { shouldHighlight() }
}
- fun shouldHighlight() = getLividAlive() != null && config.enabled
+ private fun shouldHighlight() = getLividAlive() != null && config.enabled
private fun getLividAlive() = lividEntity?.let {
if (!it.isDead && it.health > 0.5) it else null
@@ -132,7 +132,7 @@ object DungeonLividFinder {
gotBlinded = false
}
- fun inDungeon(): Boolean {
+ private fun inDungeon(): Boolean {
if (!LorenzUtils.inDungeons) return false
if (!DungeonAPI.inBossRoom) return false
if (!DungeonAPI.isOneOf("F5", "M5")) return false
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 69b06c0ce..b3a6a1f59 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonMilestonesDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonMilestonesDisplay.kt
@@ -12,6 +12,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.concurrent.fixedRateTimer
class DungeonMilestonesDisplay {
+ private val config get() = SkyHanniMod.feature.dungeon
companion object {
private var display = ""
@@ -83,10 +84,8 @@ class DungeonMilestonesDisplay {
fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
if (!isEnabled()) return
- SkyHanniMod.feature.dungeon.showMileStonesDisplayPos.renderString(color + display, posLabel = "Dungeon Milestone")
+ config.showMileStonesDisplayPos.renderString(color + display, posLabel = "Dungeon Milestone")
}
- private fun isEnabled(): Boolean {
- return LorenzUtils.inDungeons && SkyHanniMod.feature.dungeon.showMilestonesDisplay
- }
-} \ No newline at end of file
+ private fun isEnabled() = LorenzUtils.inDungeons && config.showMilestonesDisplay
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonTeammateOutlines.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonTeammateOutlines.kt
index de2ca07e2..445b9676f 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonTeammateOutlines.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonTeammateOutlines.kt
@@ -32,8 +32,8 @@ class DungeonTeammateOutlines {
val colorFormat = FontRenderer.getFormatFromString(team.colorPrefix)
return if (colorFormat.length >= 2)
- Minecraft.getMinecraft().fontRendererObj.getColorCode(colorFormat[1]);
+ Minecraft.getMinecraft().fontRendererObj.getColorCode(colorFormat[1])
else null
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/anniversary/Year300RaffleEvent.kt b/src/main/java/at/hannibal2/skyhanni/features/event/anniversary/Year300RaffleEvent.kt
index 8395b02da..71d8040f3 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/event/anniversary/Year300RaffleEvent.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/event/anniversary/Year300RaffleEvent.kt
@@ -36,10 +36,8 @@ object Year300RaffleEvent {
}
}
- fun isEnabled() = config.enableActiveTimer &&
- Instant.now().isBefore(SkyBlockTime(301).toInstant()) &&
- LorenzUtils.inSkyBlock
-
+ fun isEnabled() = LorenzUtils.inSkyBlock && config.enableActiveTimer &&
+ Instant.now().isBefore(SkyBlockTime(301).toInstant())
@SubscribeEvent
fun onRender(event: GuiRenderEvent.GuiOverlayRenderEvent) {
@@ -70,4 +68,4 @@ object Year300RaffleEvent {
Renderable.string("§eTime Left: ${timeLeft.format()}")
)
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/diana/BurrowType.kt b/src/main/java/at/hannibal2/skyhanni/features/event/diana/BurrowType.kt
index b7d589440..ac52c5617 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/event/diana/BurrowType.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/event/diana/BurrowType.kt
@@ -3,8 +3,8 @@ package at.hannibal2.skyhanni.features.event.diana
import at.hannibal2.skyhanni.utils.LorenzColor
enum class BurrowType(val text: String, val color: LorenzColor) {
- START("§aStart",LorenzColor.GREEN),
- MOB("§cMob",LorenzColor.RED),
- TREASURE("§6Treasure",LorenzColor.GOLD),
- UNKNOWN("§fUnknown?!",LorenzColor.WHITE),
-} \ No newline at end of file
+ START("§aStart", LorenzColor.GREEN),
+ MOB("§cMob", LorenzColor.RED),
+ TREASURE("§6Treasure", LorenzColor.GOLD),
+ UNKNOWN("§fUnknown?!", LorenzColor.WHITE),
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/diana/BurrowWarpHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/event/diana/BurrowWarpHelper.kt
index fdb41a87a..3c1486467 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/event/diana/BurrowWarpHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/event/diana/BurrowWarpHelper.kt
@@ -43,10 +43,8 @@ class BurrowWarpHelper {
if (lastWarpTime.passedSince() < 1.seconds) {
lastWarp?.let {
it.unlocked = false
- LorenzUtils.chat(
- "§e[SkyHanni] Detected not having access to warp point §b${it.displayName}§e!\n" +
- "§e[SkyHanni] Use §c/shresetburrowwarps §eonce you have activated this travel scroll."
- )
+ LorenzUtils.chat("Detected not having access to warp point §b${it.displayName}§e!")
+ LorenzUtils.chat("Use §c/shresetburrowwarps §eonce you have activated this travel scroll.")
lastWarp = null
currentWarp = null
}
@@ -84,7 +82,7 @@ class BurrowWarpHelper {
fun resetDisabledWarps() {
WarpPoint.entries.forEach { it.unlocked = true }
- LorenzUtils.chat("§e[SkyHanni] Reset disabled burrow warps.")
+ LorenzUtils.chat("Reset disabled burrow warps.")
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/diana/DianaAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/event/diana/DianaAPI.kt
index 28cc33e1b..8c01d0141 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/event/diana/DianaAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/event/diana/DianaAPI.kt
@@ -3,7 +3,7 @@ package at.hannibal2.skyhanni.features.event.diana
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.data.MayorElection
-import at.hannibal2.skyhanni.data.ProfileStorageData
+import at.hannibal2.skyhanni.data.PetAPI
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland
import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
@@ -15,9 +15,9 @@ object DianaAPI {
fun hasSpadeInHand() = InventoryUtils.itemInHandId == spade
private fun isRitualActive() = MayorElection.isPerkActive("Diana", "Mythological Ritual") ||
- MayorElection.isPerkActive("Jerry", "Perkpocalypse") || SkyHanniMod.feature.event.diana.alwaysDiana
+ MayorElection.isPerkActive("Jerry", "Perkpocalypse") || SkyHanniMod.feature.event.diana.alwaysDiana
- fun hasGriffinPet() = ProfileStorageData.profileSpecific?.currentPet?.contains("Griffin") ?: false
+ fun hasGriffinPet() = PetAPI.currentPet?.contains("Griffin") ?: false
fun featuresEnabled() = IslandType.HUB.isInIsland() && isRitualActive()
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/diana/GriffinBurrowParticleFinder.kt b/src/main/java/at/hannibal2/skyhanni/features/event/diana/GriffinBurrowParticleFinder.kt
index 486a19d80..1b23bb1de 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/event/diana/GriffinBurrowParticleFinder.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/event/diana/GriffinBurrowParticleFinder.kt
@@ -22,7 +22,7 @@ class GriffinBurrowParticleFinder {
private val recentlyDugParticleBurrows = mutableListOf<LorenzVec>()
private val burrows = mutableMapOf<LorenzVec, Burrow>()
- var lastDugParticleBurrow: LorenzVec? = null
+ private var lastDugParticleBurrow: LorenzVec? = null
@SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true)
fun onChatPacket(event: PacketEvent.ReceiveEvent) {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/diana/GriffinPetWarning.kt b/src/main/java/at/hannibal2/skyhanni/features/event/diana/GriffinPetWarning.kt
index b7637624c..a756f208b 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/event/diana/GriffinPetWarning.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/event/diana/GriffinPetWarning.kt
@@ -20,7 +20,7 @@ class GriffinPetWarning {
if (!DianaAPI.hasGriffinPet() && lastWarnTime.passedSince() > 30.seconds) {
lastWarnTime = SimpleTimeMark.now()
LorenzUtils.sendTitle("§cGriffin Pet!", 3.seconds)
- LorenzUtils.chat("§e[SkyHanni] Reminder to use a Griffin pet for Mythological Ritual!")
+ LorenzUtils.chat("Reminder to use a Griffin pet for Mythological Ritual!")
}
}
}
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 0c4e031f9..c4f12a993 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
@@ -20,6 +20,7 @@ import at.hannibal2.skyhanni.utils.SoundUtils
import at.hannibal2.skyhanni.utils.StringUtils.cleanPlayerName
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.getLorenzVec
+import net.minecraft.client.Minecraft
import net.minecraft.client.entity.EntityOtherPlayerMP
import net.minecraft.network.play.server.S02PacketChat
import net.minecraftforge.event.entity.EntityJoinWorldEvent
@@ -52,7 +53,7 @@ object InquisitorWaypointShare {
fun test() {
test = !test
- LorenzUtils.chat("§e[SkyHanni] Inquisitor Test " + if (test) "Enabled" else "Disabled")
+ LorenzUtils.chat("Inquisitor Test " + if (test) "Enabled" else "Disabled")
}
@SubscribeEvent
@@ -143,7 +144,7 @@ object InquisitorWaypointShare {
} else {
val keyName = KeyboardManager.getKeyName(config.keyBindShare)
val message =
- "§e[SkyHanni] §l§bYou found a Inquisitor! Press §l§chere §l§bor §c$keyName to share the location!"
+ "§l§bYou found a Inquisitor! Press §l§chere §l§bor §c$keyName to share the location!"
LorenzUtils.clickableChat(message, "shshareinquis")
}
}
@@ -165,6 +166,7 @@ object InquisitorWaypointShare {
@SubscribeEvent
fun onKeyClick(event: LorenzKeyPressEvent) {
if (!isEnabled()) return
+ if (Minecraft.getMinecraft().currentScreen != null) return
if (event.keyCode == config.keyBindShare) sendInquisitor()
}
@@ -187,7 +189,7 @@ object InquisitorWaypointShare {
lastShareTime = System.currentTimeMillis()
if (inquisitor == -1) {
- LorenzUtils.chat("§c[SkyHanni] No Inquisitor Found!")
+ LorenzUtils.error("No Inquisitor Found!")
return
}
@@ -198,7 +200,7 @@ object InquisitorWaypointShare {
}
if (inquisitor.isDead) {
- LorenzUtils.chat("§cInquisitor is ded")
+ LorenzUtils.chat("§cInquisitor is dead")
return
}
val location = inquisitor.getLorenzVec()
@@ -227,7 +229,7 @@ object InquisitorWaypointShare {
val cleanName = playerName.cleanPlayerName()
if (!waypoints.containsKey(cleanName)) {
- LorenzUtils.chat("§e[SkyHanni] $playerName §l§efound an inquisitor at §l§c$x $y $z!")
+ 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)
SoundUtils.playBeepSound()
@@ -254,7 +256,7 @@ object InquisitorWaypointShare {
fun maybeRemove(playerName: String) {
if (inquisitorsNearby.isEmpty()) {
waypoints = waypoints.editCopy { remove(playerName) }
- LorenzUtils.chat("§e[SkyHanni] Inquisitor from $playerName not found, deleting.")
+ LorenzUtils.chat("Inquisitor from $playerName not found, deleting.")
}
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/diana/SoopyGuessBurrow.kt b/src/main/java/at/hannibal2/skyhanni/features/event/diana/SoopyGuessBurrow.kt
index ec0a1e2ae..a0b34e328 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/event/diana/SoopyGuessBurrow.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/event/diana/SoopyGuessBurrow.kt
@@ -23,23 +23,23 @@ import kotlin.math.sin
*/
class SoopyGuessBurrow {
- var dingIndex = 0
- var lastDing = 0L
- var lastDingPitch = 0f
- var firstPitch = 0f
- var lastParticlePoint: LorenzVec? = null
- var lastParticlePoint2: LorenzVec? = null
- var firstParticlePoint: LorenzVec? = null
- var particlePoint: LorenzVec? = null
- var guessPoint: LorenzVec? = null
+ private var dingIndex = 0
+ private var lastDing = 0L
+ private var lastDingPitch = 0f
+ private var firstPitch = 0f
+ private var lastParticlePoint: LorenzVec? = null
+ private var lastParticlePoint2: LorenzVec? = null
+ private var firstParticlePoint: LorenzVec? = null
+ private var particlePoint: LorenzVec? = null
+ private var guessPoint: LorenzVec? = null
- var lastSoundPoint: LorenzVec? = null
- var locs = mutableListOf<LorenzVec>()
+ private var lastSoundPoint: LorenzVec? = null
+ private var locs = mutableListOf<LorenzVec>()
- var dingSlope = mutableListOf<Float>()
+ private var dingSlope = mutableListOf<Float>()
var distance: Double? = null
- var distance2: Double? = null
+ private var distance2: Double? = null
@SubscribeEvent
fun onWorldChange(event: LorenzWorldChangeEvent) {
@@ -280,4 +280,4 @@ class SoopyGuessBurrow {
}
private fun isEnabled() = DianaAPI.featuresEnabled() && SkyHanniMod.feature.event.diana.burrowsSoopyGuess
-} \ No newline at end of file
+}
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 034761654..bfae2a7d8 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,34 +2,35 @@ package at.hannibal2.skyhanni.features.event.jerry.frozentreasure
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-import at.hannibal2.skyhanni.config.Storage
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.events.PreProfileSwitchEvent
-import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
-import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy
+import at.hannibal2.skyhanni.utils.LorenzUtils.addOrPut
+import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland
import at.hannibal2.skyhanni.utils.NumberUtil
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
-import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
+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 kotlin.concurrent.fixedRateTimer
-class FrozenTreasureTracker {
+object FrozenTreasureTracker {
private val config get() = SkyHanniMod.feature.event.winter.frozenTreasureTracker
- private var display = emptyList<List<Any>>()
private var estimatedIce = 0L
private var lastEstimatedIce = 0L
private var icePerSecond = mutableListOf<Long>()
private var icePerHour = 0
private var stoppedChecks = 0
private var compactPattern = "COMPACT! You found an Enchanted Ice!".toPattern()
+ private val tracker = SkyHanniTracker("Frozen Treasure Tracker", { Data() }, { it.frozenTreasureTracker })
+ { formatDisplay(drawDisplay(it)) }
init {
fixedRateTimer(name = "skyhanni-frozen-treasure-tracker", period = 1000) {
@@ -38,12 +39,30 @@ class FrozenTreasureTracker {
}
}
+ class Data : TrackerData() {
+
+ override fun reset() {
+ treasureCount.clear()
+ treasuresMined = 0
+ compactProcs = 0
+ }
+
+ @Expose
+ var treasuresMined = 0
+
+ @Expose
+ var compactProcs = 0
+
+ @Expose
+ var treasureCount: MutableMap<FrozenTreasure, Int> = mutableMapOf()
+ }
+
@SubscribeEvent
fun onWorldChange(event: LorenzWorldChangeEvent) {
icePerHour = 0
stoppedChecks = 0
icePerSecond = mutableListOf()
- saveAndUpdate()
+ tracker.update()
}
private fun calculateIcePerHour() {
@@ -88,40 +107,36 @@ class FrozenTreasureTracker {
if (!onJerryWorkshop()) return
val message = event.message.removeColor().trim()
- val storage = ProfileStorageData.profileSpecific?.frozenTreasureTracker ?: return
compactPattern.matchMatcher(message) {
- storage.compactProcs += 1
- saveAndUpdate()
+ tracker.modify {
+ it.compactProcs += 1
+ }
if (config.hideMessages) event.blockedReason = "frozen treasure tracker"
}
for (treasure in FrozenTreasure.entries) {
if ("FROZEN TREASURE! You found ${treasure.displayName.removeColor()}!".toRegex().matches(message)) {
- storage.treasuresMined += 1
- val old = storage.treasureCount[treasure] ?: 0
- storage.treasureCount = storage.treasureCount.editCopy { this[treasure] = old + 1 }
- saveAndUpdate()
+ tracker.modify {
+ it.treasuresMined += 1
+ it.treasureCount.addOrPut(treasure, 1)
+ }
if (config.hideMessages) event.blockedReason = "frozen treasure tracker"
}
}
}
- @SubscribeEvent
- fun onPreProfileSwitch(event: PreProfileSwitchEvent) {
- display = emptyList()
- }
-
- private fun drawTreasureDisplay(storage: Storage.ProfileSpecific.FrozenTreasureTracker) = buildList<List<Any>> {
+ private fun drawDisplay(data: Data) = buildList<List<Any>> {
+ calculateIce(data)
addAsSingletonList("§1§lFrozen Treasure Tracker")
- addAsSingletonList("§6${formatNumber(storage.treasuresMined)} Treasures Mined")
+ addAsSingletonList("§6${formatNumber(data.treasuresMined)} Treasures Mined")
addAsSingletonList("§3${formatNumber(estimatedIce)} Total Ice")
addAsSingletonList("§3${formatNumber(icePerHour)} Ice/hr")
- addAsSingletonList("§8${formatNumber(storage.treasuresMined)} Compact Procs")
+ addAsSingletonList("§8${formatNumber(data.treasuresMined)} Compact Procs")
addAsSingletonList("")
for (treasure in FrozenTreasure.entries) {
- val count = (storage.treasureCount[treasure] ?: 0) * if (config.showAsDrops) treasure.defaultAmount else 1
+ val count = (data.treasureCount[treasure] ?: 0) * if (config.showAsDrops) treasure.defaultAmount else 1
addAsSingletonList("§b${formatNumber(count)} ${treasure.displayName}")
}
addAsSingletonList("")
@@ -133,27 +148,21 @@ class FrozenTreasureTracker {
return "$amount"
}
- private fun saveAndUpdate() {
- val storage = ProfileStorageData.profileSpecific?.frozenTreasureTracker ?: return
- calculateIce(storage)
- display = formatDisplay(drawTreasureDisplay(storage))
- }
-
- private fun calculateIce(storage: Storage.ProfileSpecific.FrozenTreasureTracker) {
- estimatedIce = 0
- estimatedIce += storage.compactProcs * 160
+ private fun calculateIce(data: Data) {
+ estimatedIce = data.compactProcs * 160L
for (treasure in FrozenTreasure.entries) {
- val amount = storage.treasureCount[treasure] ?: 0
+ val amount = data.treasureCount[treasure] ?: 0
estimatedIce += amount * treasure.defaultAmount * treasure.iceMultiplier
}
}
@SubscribeEvent
- fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
+ fun onRenderOverlay(event: GuiRenderEvent) {
if (!config.enabled) return
if (!onJerryWorkshop()) return
if (config.onlyInCave && !inGlacialCave()) return
- config.position.renderStringsAndItems(display, posLabel = "Frozen Treasure Tracker")
+
+ tracker.renderDisplay(config.position)
}
@SubscribeEvent
@@ -161,7 +170,12 @@ class FrozenTreasureTracker {
event.move(2, "misc.frozenTreasureTracker", "event.winter.frozenTreasureTracker")
}
- private fun onJerryWorkshop() = LorenzUtils.inIsland(IslandType.WINTER)
+ private fun onJerryWorkshop() = IslandType.WINTER.isInIsland()
- private fun inGlacialCave() = onJerryWorkshop() && ScoreboardData.sidebarLinesFormatted.contains(" §7⏣ §3Glacial Cave")
-} \ No newline at end of file
+ private fun inGlacialCave() =
+ onJerryWorkshop() && ScoreboardData.sidebarLinesFormatted.contains(" §7⏣ §3Glacial Cave")
+
+ fun resetCommand(args: Array<String>) {
+ tracker.resetCommand(args, "shresetfrozentreasuretracker")
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/spook/TheGreatSpook.kt b/src/main/java/at/hannibal2/skyhanni/features/event/spook/TheGreatSpook.kt
new file mode 100644
index 000000000..f0334549e
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/event/spook/TheGreatSpook.kt
@@ -0,0 +1,58 @@
+package at.hannibal2.skyhanni.features.event.spook
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.events.GuiRenderEvent
+import at.hannibal2.skyhanni.events.LorenzTickEvent
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.RenderUtils.renderString
+import at.hannibal2.skyhanni.utils.SoundUtils
+import at.hannibal2.skyhanni.utils.TabListData
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+class TheGreatSpook {
+// §r§cPrimal Fears§r§7: §r§6§lREADY!!
+ private val config get() = SkyHanniMod.feature.event.spook
+ private var displayTimer = ""
+ private var displayFearStat = ""
+ private var displayTimeLeft = ""
+ private var notificationSeconds = 0
+
+ @SubscribeEvent
+ fun onTick(event: LorenzTickEvent) {
+ if (isAllDisabled()) return
+ if (!event.repeatSeconds(1)) return
+
+ if (isTimerEnabled() || isNotificationEnabled()) displayTimer = checkTabList(" §r§cPrimal Fears§r§7: ")
+ if (isFearStatEnabled()) displayFearStat = checkTabList(" §r§5Fear: ")
+ if (isTimeLeftEnabled()) displayTimeLeft = checkTabList(" §r§dEnds In§r§7: ")
+ if (isNotificationEnabled()) {
+ if (displayTimer.endsWith("READY!!")) {
+ if (notificationSeconds > 0) {
+ SoundUtils.playBeepSound()
+ notificationSeconds--
+ }
+ } else if (displayTimer.isNotEmpty()) {
+ notificationSeconds = 5
+ }
+ }
+ }
+
+ private fun checkTabList(matchString: String): String {
+ return (TabListData.getTabList().find { it.contains(matchString) } ?: "").trim()
+ }
+ @SubscribeEvent
+ fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
+ if (isTimerEnabled()) config.positionTimer.renderString(displayTimer, posLabel = "Primal Fear Timer")
+ if (isFearStatEnabled()) config.positionFear.renderString(displayFearStat, posLabel = "Fear Stat Display")
+ if (isTimeLeftEnabled()) config.positionTimeLeft.renderString(displayTimeLeft, posLabel = "Time Left Display")
+ }
+
+ private fun isTimerEnabled(): Boolean = LorenzUtils.inSkyBlock && config.primalFearTimer
+
+ private fun isNotificationEnabled(): Boolean = LorenzUtils.inSkyBlock && config.primalFearNotification
+ private fun isFearStatEnabled(): Boolean = LorenzUtils.inSkyBlock && config.fearStatDisplay
+ private fun isTimeLeftEnabled(): Boolean = LorenzUtils.inSkyBlock && config.greatSpookTimeLeft
+
+ private fun isAllDisabled(): Boolean = !isTimeLeftEnabled() && !isTimerEnabled() && !isFearStatEnabled() &&
+ !isNotificationEnabled()
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/fame/AccountUpgradeReminder.kt b/src/main/java/at/hannibal2/skyhanni/features/fame/AccountUpgradeReminder.kt
index 436cf7b8f..6d010fae7 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/fame/AccountUpgradeReminder.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/fame/AccountUpgradeReminder.kt
@@ -54,7 +54,7 @@ class AccountUpgradeReminder {
lastReminderSend = SimpleTimeMark.now()
LorenzUtils.clickableChat(
- "§e[SkyHanni] The §a$upgrade §eupgrade has completed! §c(Click to disable these reminders)",
+ "The §a$upgrade §eupgrade has completed! §c(Click to disable these reminders)",
"shstopaccountupgradereminder"
)
}
@@ -117,4 +117,4 @@ class AccountUpgradeReminder {
SkyHanniMod.feature.misc.accountUpgradeReminder = false
}
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/fame/CityProjectFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/fame/CityProjectFeatures.kt
index 0d6f1cd75..d47e32981 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/fame/CityProjectFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/fame/CityProjectFeatures.kt
@@ -42,7 +42,7 @@ class CityProjectFeatures {
private val config get() = SkyHanniMod.feature.event.cityProject
fun disable() {
config.dailyReminder = false
- LorenzUtils.chat("§c[SkyHanni] Disabled city project reminder messages!")
+ LorenzUtils.chat("Disabled city project reminder messages!")
}
}
@@ -68,7 +68,7 @@ class CityProjectFeatures {
lastReminderSend = System.currentTimeMillis()
LorenzUtils.clickableChat(
- "§e[SkyHanni] Daily City Project Reminder! (Click here to disable this reminder)",
+ "Daily City Project Reminder! (Click here to disable this reminder)",
"shstopcityprojectreminder"
)
}
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 973d7ac1e..550388893 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingAPI.kt
@@ -1,7 +1,45 @@
package at.hannibal2.skyhanni.features.fishing
+import at.hannibal2.skyhanni.events.FishingBobberCastEvent
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.SimpleTimeMark
+import at.hannibal2.skyhanni.utils.StringUtils.removeColor
+import net.minecraft.client.Minecraft
+import net.minecraft.entity.projectile.EntityFishHook
+import net.minecraft.init.Blocks
+import net.minecraft.item.ItemStack
+import net.minecraftforge.event.entity.EntityJoinWorldEvent
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
object FishingAPI {
- fun hasFishingRodInHand() = InventoryUtils.itemInHandId.toString().contains("ROD")
-} \ No newline at end of file
+ private val lavaBlocks = listOf(Blocks.lava, Blocks.flowing_lava)
+ private val waterBlocks = listOf(Blocks.water, Blocks.flowing_water)
+
+ var lastCastTime = SimpleTimeMark.farPast()
+
+ @SubscribeEvent
+ fun onJoinWorld(event: EntityJoinWorldEvent) {
+ if (!LorenzUtils.inSkyBlock || !hasFishingRodInHand()) return
+ val entity = event.entity ?: return
+ if (entity !is EntityFishHook) return
+ if (entity.angler != Minecraft.getMinecraft().thePlayer) return
+
+ lastCastTime = SimpleTimeMark.now()
+ FishingBobberCastEvent(entity).postAndCatch()
+ }
+
+ fun hasFishingRodInHand() = InventoryUtils.itemInHandId.asString().contains("ROD")
+
+ fun ItemStack.isBait(): Boolean {
+ val name = name ?: return false
+ return stackSize == 1 && (name.removeColor().startsWith("Obfuscated") || name.endsWith(" Bait"))
+ }
+
+ fun isLavaRod() = InventoryUtils.getItemInHand()?.getLore()?.any { it.contains("Lava Rod") } ?: false
+
+ fun getAllowedBlocks() = if (isLavaRod()) lavaBlocks else waterBlocks
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingBaitWarnings.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingBaitWarnings.kt
new file mode 100644
index 000000000..7688a7f98
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingBaitWarnings.kt
@@ -0,0 +1,89 @@
+package at.hannibal2.skyhanni.features.fishing
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.events.FishingBobberCastEvent
+import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
+import at.hannibal2.skyhanni.events.LorenzTickEvent
+import at.hannibal2.skyhanni.features.fishing.FishingAPI.isBait
+import at.hannibal2.skyhanni.utils.BlockUtils.getBlockAt
+import at.hannibal2.skyhanni.utils.EntityUtils
+import at.hannibal2.skyhanni.utils.ItemUtils.name
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.SoundUtils
+import at.hannibal2.skyhanni.utils.StringUtils.removeColor
+import at.hannibal2.skyhanni.utils.getLorenzVec
+import net.minecraft.entity.item.EntityItem
+import net.minecraft.entity.projectile.EntityFishHook
+import net.minecraft.item.ItemStack
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import kotlin.time.Duration.Companion.seconds
+
+class FishingBaitWarnings {
+ private val config get() = SkyHanniMod.feature.fishing.fishingBaitWarnings
+ private var bobber: EntityFishHook? = null
+ private var lastBait: String? = null
+ private var isUsingBait: Boolean = false
+
+ @SubscribeEvent
+ fun onBobberThrow(event: FishingBobberCastEvent) {
+ bobber = event.bobber
+ isUsingBait = false
+ }
+
+ @SubscribeEvent
+ fun onTick(event: LorenzTickEvent) {
+ if (!isEnabled()) return
+ val bobber = bobber ?: return
+ if (bobber.isDead) {
+ this.bobber = null
+ return
+ }
+ if (!event.isMod(5)) return
+ if (FishingAPI.lastCastTime.passedSince() < 1.seconds) return
+
+ val block = bobber.getLorenzVec().getBlockAt()
+ if (block !in FishingAPI.getAllowedBlocks()) return
+
+ if (!isUsingBait && config.noBaitWarning) showNoBaitWarning()
+ reset()
+ }
+
+ fun reset() {
+ bobber = null
+ isUsingBait = false
+ }
+
+ @SubscribeEvent
+ fun onRenderWorld(event: LorenzRenderWorldEvent) {
+ if (!isEnabled() || !config.baitChangeWarning) return
+ val bobber = bobber ?: return
+ EntityUtils.getEntitiesNearby<EntityItem>(bobber.getLorenzVec(), 1.5)
+ .forEach { onBaitDetection(it.entityItem) }
+ }
+
+ private fun onBaitDetection(itemStack: ItemStack) {
+ if (!itemStack.isBait()) return
+ val name = itemStack.name?.removeColor() ?: return
+
+ isUsingBait = true
+ lastBait?.let {
+ if (name == it) return
+ showBaitChangeWarning(it, name)
+ }
+ lastBait = name
+ }
+
+ private fun showBaitChangeWarning(before: String, after: String) {
+ SoundUtils.playClickSound()
+ LorenzUtils.sendTitle("§eBait changed!", 2.seconds)
+ LorenzUtils.chat("Fishing Bait changed: $before -> $after")
+ }
+
+ private fun showNoBaitWarning() {
+ SoundUtils.playErrorSound()
+ LorenzUtils.sendTitle("§cNo bait is used!", 2.seconds)
+ LorenzUtils.chat("You do not use any fishing baits!")
+ }
+
+ private fun isEnabled() = LorenzUtils.inSkyBlock && FishingAPI.hasFishingRodInHand()
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingHookDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingHookDisplay.kt
index c05ffcc80..be076222f 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingHookDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingHookDisplay.kt
@@ -2,30 +2,30 @@ package at.hannibal2.skyhanni.features.fishing
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.CheckRenderEntityEvent
+import at.hannibal2.skyhanni.events.FishingBobberCastEvent
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
-import at.hannibal2.skyhanni.utils.EntityUtils
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.RenderUtils.renderString
-import net.minecraft.client.entity.EntityPlayerSP
import net.minecraft.entity.item.EntityArmorStand
-import net.minecraft.entity.projectile.EntityFishHook
import net.minecraftforge.event.entity.EntityJoinWorldEvent
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class FishingHookDisplay {
private val config get() = SkyHanniMod.feature.fishing.fishingHookDisplay
- private var bobber: EntityFishHook? = null
private var armorStand: EntityArmorStand? = null
private val potentionArmorStands = mutableListOf<EntityArmorStand>()
private val pattern = "§e§l(\\d+(\\.\\d+)?)".toPattern()
@SubscribeEvent
fun onWorldChange(event: LorenzWorldChangeEvent) {
- bobber = null
- armorStand = null
- potentionArmorStands.clear()
+ reset()
+ }
+
+ @SubscribeEvent
+ fun onBobberThrow(event: FishingBobberCastEvent) {
+ reset()
}
@SubscribeEvent
@@ -38,16 +38,6 @@ class FishingHookDisplay {
armorStand = filter[0]
}
}
-
- if (event.isMod(5)) {
- val entities = EntityUtils.getEntities<EntityFishHook>()
- val foundBobber = entities.firstOrNull { it.angler is EntityPlayerSP }
- if (foundBobber != bobber) {
- bobber = foundBobber
- reset()
- }
- }
-
}
private fun reset() {
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 c41129c5f..f0a3c54b1 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureManager.kt
@@ -53,7 +53,6 @@ class SeaCreatureManager {
}
}
SeaCreatureManager.allFishingMobs = allFishingMobs
- LorenzUtils.debug("Loaded $counter sea creatures from repo")
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureMessageShortener.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureMessageShortener.kt
index f9cb0d861..0525031c0 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureMessageShortener.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureMessageShortener.kt
@@ -15,17 +15,14 @@ class SeaCreatureMessageShortener {
val seaCreature = event.seaCreature
event.chatEvent.blockedReason = "sea_creature_caught"
- var message = if (config.shortenFishingMessage) {
+ val doubleHookPrefix = if (config.compactDoubleHook && event.doubleHook) "§e§lDOUBLE HOOK! " else ""
+ val message = doubleHookPrefix + if (config.shortenFishingMessage) {
"§9You caught a ${seaCreature.displayName}§9!"
} else event.chatEvent.message
-
- if (config.compactDoubleHook && event.doubleHook) {
- message = "§e§lDOUBLE HOOK! $message"
- }
- LorenzUtils.chat(message)
+ LorenzUtils.chat(message, false)
if (seaCreature.fishingExperience == 0) {
LorenzUtils.debug("no fishing exp set for " + seaCreature.name)
}
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/SharkFishCounter.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/SharkFishCounter.kt
index c592e72a4..bc9cb9724 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/fishing/SharkFishCounter.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/SharkFishCounter.kt
@@ -5,9 +5,6 @@ import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.SeaCreatureFishEvent
-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.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.RenderUtils.renderString
@@ -51,21 +48,12 @@ class SharkFishCounter {
counter < 350 -> "Like a pro!"
else -> "How???"
}
- LorenzUtils.chat("§e[SkyHanni] You caught ${counter.addSeparators()} sharks during this fishing contest. $funnyComment")
+ LorenzUtils.chat("You caught ${counter.addSeparators()} sharks during this fishing contest. $funnyComment")
counter = 0
}
}
- private fun isWaterFishingRod(): Boolean {
- val heldItem = InventoryUtils.getItemInHand() ?: return false
- val isRod = heldItem.name?.contains("Rod") ?: return false
- if (!isRod) return false
-
- val isLavaRod = heldItem.getLore().any { it.contains("Lava Rod") }
- if (isLavaRod) return false
-
- return true
- }
+ private fun isWaterFishingRod() = FishingAPI.hasFishingRodInHand() && !FishingAPI.isLavaRod()
@SubscribeEvent
fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
@@ -75,4 +63,4 @@ class SharkFishCounter {
SkyHanniMod.feature.fishing.sharkFishCounterPos.renderString(display, posLabel = "Shark Fish Counter")
}
-} \ No newline at end of file
+}
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 179b6af20..a64d3da77 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/fishing/ShowFishingItemName.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/ShowFishingItemName.kt
@@ -3,6 +3,7 @@ package at.hannibal2.skyhanni.features.fishing
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
+import at.hannibal2.skyhanni.features.fishing.FishingAPI.isBait
import at.hannibal2.skyhanni.utils.EntityUtils
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.name
@@ -55,8 +56,7 @@ class ShowFishingItemName {
if (name.removeColor() == "Stone") continue
val size = itemStack.stackSize
- val isBait = name.endsWith(" Bait") && size == 1
- val prefix = if (!isBait) {
+ val prefix = if (!itemStack.isBait()) {
"§a§l+"
} else {
if (!config.showBaits) continue
diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/OdgerWaypoint.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/OdgerWaypoint.kt
index b3b002c24..99b8240a6 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/OdgerWaypoint.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/OdgerWaypoint.kt
@@ -58,4 +58,4 @@ class OdgerWaypoint {
}
fun isEnabled() = IslandType.CRIMSON_ISLE.isInIsland() && config.odgerLocation
-} \ No newline at end of file
+}
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 6617b31b2..5f576ae46 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
@@ -36,7 +36,12 @@ object TrophyFishManager {
fun TrophyFishInfo.getFilletValue(rarity: TrophyRarity): Int {
if (fillet == null) {
- ErrorManager.logError(Error("fillet is null for '$displayName'"), "Error trying to read trophy fish info")
+ ErrorManager.logErrorStateWithData(
+ "Error trying to read trophy fish info",
+ "fillet in TrophyFishInfo is null",
+ "displayName" to displayName,
+ "TrophyFishInfo" to this,
+ )
return -1
}
return fillet.getOrDefault(rarity, -1)
diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/TrophyFishMessages.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/TrophyFishMessages.kt
index 7723617a9..b1abdc2d5 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/TrophyFishMessages.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/TrophyFishMessages.kt
@@ -43,7 +43,7 @@ class TrophyFishMessages {
event.blockedReason = "trophy_fish"
if (config.enabled && config.design == 0 && amount == 1) {
- LorenzUtils.chat("§6§lTROPHY FISH! §c§lFIRST §r$displayRarity $displayName")
+ LorenzUtils.chat("§6§lTROPHY FISH! §c§lFIRST §r$displayRarity $displayName", prefix = false)
return
}
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 d5c279fc9..7d5c04d5f 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt
@@ -6,6 +6,8 @@ import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.InventoryCloseEvent
import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
import at.hannibal2.skyhanni.features.garden.visitor.VisitorAPI
+import at.hannibal2.skyhanni.test.command.ErrorManager
+import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
@@ -56,8 +58,12 @@ class AnitaMedalProfit {
try {
readItem(item, table)
} catch (e: Throwable) {
- LorenzUtils.error("Error in AnitaMedalProfit while reading item '$item'")
- e.printStackTrace()
+ ErrorManager.logErrorWithData(
+ e, "Error in AnitaMedalProfit while reading item '${item.nameWithEnchantment}'",
+ "item" to item,
+ "name" to item.nameWithEnchantment,
+ "inventory name" to InventoryUtils.openInventoryName(),
+ )
}
}
@@ -99,7 +105,7 @@ class AnitaMedalProfit {
for (rawItemName in requiredItems) {
val pair = ItemUtils.readItemAmount(rawItemName)
if (pair == null) {
- LorenzUtils.error("§c[SkyHanni] Could not read item '$rawItemName'")
+ LorenzUtils.error("Could not read item '$rawItemName'")
continue
}
@@ -109,8 +115,7 @@ class AnitaMedalProfit {
val bronze = medal.factorBronze * amount
bronze * jacobTicketPrice
} else {
- val internalName = NEUItems.getRawInternalName(name)
- NEUItems.getPrice(internalName) * amount
+ NEUInternalName.fromItemName(name).getPrice() * amount
}
}
return otherItemsPrice
@@ -150,7 +155,7 @@ class AnitaMedalProfit {
@SubscribeEvent
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
- event.move(3,"garden.anitaMedalProfitEnabled", "garden.anitaShop.medalProfitEnabled")
- event.move(3,"garden.anitaMedalProfitPos", "garden.anitaShop.medalProfitPos")
+ event.move(3, "garden.anitaMedalProfitEnabled", "garden.anitaShop.medalProfitEnabled")
+ event.move(3, "garden.anitaMedalProfitPos", "garden.anitaShop.medalProfitPos")
}
-} \ No newline at end of file
+}
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 a684e7bac..423bdaed1 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt
@@ -17,7 +17,14 @@ enum class CropType(
WHEAT("Wheat", "THEORETICAL_HOE_WHEAT", "CROPIE", 1.0, { ItemStack(Items.wheat) }),
CARROT("Carrot", "THEORETICAL_HOE_CARROT", "CROPIE", 3.0, { ItemStack(Items.carrot) }, replenish = true),
POTATO("Potato", "THEORETICAL_HOE_POTATO", "CROPIE", 3.0, { ItemStack(Items.potato) }, replenish = true),
- NETHER_WART("Nether Wart", "THEORETICAL_HOE_WARTS", "FERMENTO", 2.5, { ItemStack(Items.nether_wart) }, replenish = true),
+ NETHER_WART(
+ "Nether Wart",
+ "THEORETICAL_HOE_WARTS",
+ "FERMENTO",
+ 2.5,
+ { ItemStack(Items.nether_wart) },
+ replenish = true
+ ),
PUMPKIN("Pumpkin", "PUMPKIN_DICER", "SQUASH", 1.0, { ItemStack(Blocks.pumpkin) }),
MELON("Melon", "MELON_DICER", "SQUASH", 5.0, { ItemStack(Items.melon) }),
COCOA_BEANS(
@@ -69,4 +76,4 @@ enum class CropType(
}
}
}
-} \ No newline at end of file
+}
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 9b57e1fe1..3e57bb199 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt
@@ -6,41 +6,42 @@ import at.hannibal2.skyhanni.data.CropAccessoryData
import at.hannibal2.skyhanni.data.GardenCropMilestones
import at.hannibal2.skyhanni.data.GardenCropMilestones.getCounter
import at.hannibal2.skyhanni.data.GardenCropUpgrades.Companion.getUpgradeLevel
-import at.hannibal2.skyhanni.events.CropClickEvent
import at.hannibal2.skyhanni.events.GardenToolChangeEvent
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
-import at.hannibal2.skyhanni.events.OwnInventoryItemUpdateEvent
import at.hannibal2.skyhanni.events.PreProfileSwitchEvent
import at.hannibal2.skyhanni.events.TabListUpdateEvent
import at.hannibal2.skyhanni.features.garden.CropType.Companion.getTurboCrop
import at.hannibal2.skyhanni.features.garden.GardenAPI.addCropIcon
-import at.hannibal2.skyhanni.features.garden.GardenAPI.getCropType
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.LorenzUtils.addAsSingletonList
+import at.hannibal2.skyhanni.utils.LorenzUtils.nextAfter
import at.hannibal2.skyhanni.utils.NEUInternalName
+import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.RenderUtils.renderString
import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getEnchantments
import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getFarmingForDummiesCount
import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getHoeCounter
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import net.minecraft.item.ItemStack
-import net.minecraftforge.fml.common.eventhandler.EventPriority
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.math.floor
import kotlin.math.log10
+import kotlin.time.Duration.Companion.seconds
class FarmingFortuneDisplay {
- private val tabFortunePattern = " Farming Fortune: §r§6☘(\\d+)".toRegex()
+ private val tabFortuneUniversalPattern = " Farming Fortune: §r§6☘(?<fortune>\\d+)".toPattern()
+ private val tabFortuneCropPattern = " (?<crop>Wheat|Carrot|Potato|Pumpkin|Sugar Cane|Melon|Cactus|Cocoa Beans|Mushroom|Nether Wart) Fortune: §r§6☘(?<fortune>\\d+)".toPattern()
private var display = emptyList<List<Any>>()
private var accessoryProgressDisplay = ""
- private var lastToolSwitch: Long = 0
+ private var lastToolSwitch = SimpleTimeMark.farPast()
@SubscribeEvent
fun onPreProfileSwitch(event: PreProfileSwitchEvent) {
@@ -51,36 +52,27 @@ class FarmingFortuneDisplay {
@SubscribeEvent
fun onTabListUpdate(event: TabListUpdateEvent) {
if (!GardenAPI.inGarden()) return
- tabFortune = event.tabList.firstNotNullOfOrNull {
- tabFortunePattern.matchEntire(it)?.groups?.get(1)?.value?.toDoubleOrNull()
- } ?: tabFortune
- }
-
- @SubscribeEvent(priority = EventPriority.LOW)
- fun onInventoryUpdate(event: OwnInventoryItemUpdateEvent) {
- if (!GardenAPI.inGarden()) return
- if (event.itemStack.getCropType() == null) return
- updateToolFortune(event.itemStack)
- }
-
- @SubscribeEvent
- fun onBlockBreak(event: CropClickEvent) {
- val cropBroken = event.crop
- if (cropBroken != currentCrop) {
- updateToolFortune(event.itemInHand)
+ event.tabList.firstNotNullOfOrNull {
+ tabFortuneUniversalPattern.matchMatcher(it) {
+ tabFortuneUniversal = group("fortune").toDouble()
+ }
+ tabFortuneCropPattern.matchMatcher(it) {
+ currentCrop = CropType.getByName(group("crop"))
+ tabFortuneCrop = group("fortune").toDouble()
+ }
}
}
@SubscribeEvent
fun onGardenToolChange(event: GardenToolChangeEvent) {
- lastToolSwitch = System.currentTimeMillis()
- updateToolFortune(event.toolItem)
+ lastToolSwitch = SimpleTimeMark.now()
}
@SubscribeEvent
fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
if (!isEnabled()) return
if (GardenAPI.hideExtraGuis()) return
+ if (GardenAPI.toolInHand == null) return
config.pos.renderStringsAndItems(display, posLabel = "True Farming Fortune")
}
@@ -97,22 +89,46 @@ class FarmingFortuneDisplay {
@SubscribeEvent
fun onTick(event: LorenzTickEvent) {
if (!event.isMod(5)) return
- val displayCrop = currentCrop ?: return
+ val currentCrop = currentCrop ?: return
+
+ val displayCrop = GardenAPI.cropInHand ?: currentCrop
+ var wrongTabCrop: Boolean
+ var farmingFortune: Double
val updatedDisplay = mutableListOf<List<Any>>()
- updatedDisplay.add(mutableListOf<Any>().also {
- it.addCropIcon(displayCrop)
- val recentlySwitchedTool = System.currentTimeMillis() < lastToolSwitch + 1000
- it.add(
- "§6Farming Fortune§7: §e" + if (!recentlySwitchedTool) {
- LorenzUtils.formatDouble(getCurrentFarmingFortune(), 0)
- } else "?"
+ updatedDisplay.add(mutableListOf<Any>().also { list ->
+ list.addCropIcon(displayCrop)
+
+ var recentlySwitchedTool = lastToolSwitch.passedSince() < 1.5.seconds
+ wrongTabCrop = GardenAPI.cropInHand != null && GardenAPI.cropInHand != currentCrop
+
+ if (wrongTabCrop) {
+ farmingFortune = displayCrop.getLatestTrueFarmingFortune() ?: -1.0
+ recentlySwitchedTool = false
+ } else {
+ farmingFortune = getCurrentFarmingFortune()
+ }
+
+ list.add(
+ "§6Farming Fortune§7: §e" + if (!recentlySwitchedTool && farmingFortune != -1.0) {
+ LorenzUtils.formatDouble(farmingFortune, 0)
+ } else "§7" + (displayCrop.getLatestTrueFarmingFortune()?.addSeparators() ?: "?")
)
- if (GardenAPI.toolInHand != null) {
- latestFF?.put(displayCrop, getCurrentFarmingFortune(true))
+
+ if (GardenAPI.cropInHand == currentCrop) {
+ if (!recentlySwitchedTool) {
+ latestFF?.put(currentCrop, getCurrentFarmingFortune())
+ }
}
})
+ if (wrongTabCrop) {
+ var text = "§cBreak §e${GardenAPI.cropInHand?.cropName}§c to see"
+ if (farmingFortune != -1.0) text += " latest"
+ text += " fortune!"
+
+ updatedDisplay.addAsSingletonList(text)
+ }
if (upgradeFortune == null) {
updatedDisplay.addAsSingletonList("§cOpen §e/cropupgrades§c for more exact data!")
}
@@ -129,34 +145,23 @@ class FarmingFortuneDisplay {
display = updatedDisplay
}
- private fun updateToolFortune(tool: ItemStack?) {
- val cropMatchesTool = currentCrop == tool?.getCropType()
- val toolCounterFortune = if (cropMatchesTool) {
- getToolFortune(tool) + getCounterFortune(tool) + getCollectionFortune(tool)
- } else 0.0
- toolFortune =
- toolCounterFortune + getTurboCropFortune(tool, currentCrop) + getDedicationFortune(tool, currentCrop)
- }
-
private fun isEnabled(): Boolean = GardenAPI.inGarden() && config.display
-
companion object {
private val config get() = SkyHanniMod.feature.garden.farmingFortunes
- private val latestFF: MutableMap<CropType, Double>? get() = GardenAPI.config?.latestTrueFarmingFortune
+ private val latestFF: MutableMap<CropType, Double>? get() = GardenAPI.storage?.latestTrueFarmingFortune
- private val currentCrop get() = GardenAPI.getCurrentlyFarmedCrop()
+ private var currentCrop: CropType? = null
- private var tabFortune: Double = 0.0
- private var toolFortune: Double = 0.0
- private val baseFortune: Double get() = if (config.dropMultiplier) 100.0 else 0.0
+ private var tabFortuneUniversal: Double = 0.0
+ private var tabFortuneCrop: Double = 0.0
private val upgradeFortune: Double? get() = currentCrop?.getUpgradeLevel()?.let { it * 5.0 }
private val accessoryFortune: Double?
get() = currentCrop?.let {
CropAccessoryData.cropAccessory?.getFortune(it)
}
- private val collectionPattern = "§7You have §6\\+([\\d]{1,3})☘ Farming Fortune".toRegex()
+ private val collectionPattern = "§7You have §6\\+(?<ff>\\d{1,3})☘ .*".toPattern()
private val tooltipFortunePattern =
"^§7Farming Fortune: §a\\+([\\d.]+)(?: §2\\(\\+\\d\\))?(?: §9\\(\\+(\\d+)\\))?$".toRegex()
private val armorAbilityPattern = "Tiered Bonus: .* [(](?<pieces>.*)/4[)]".toPattern()
@@ -173,8 +178,8 @@ class FarmingFortuneDisplay {
return 0.0
}
return if (internalName.startsWith("THEORETICAL_HOE")) {
- listOf(10.0, 25.0, 50.0)[internalName.toString().last().digitToInt() - 1]
- } else when (internalName.toString()) {
+ listOf(10.0, 25.0, 50.0)[internalName.asString().last().digitToInt() - 1]
+ } else when (internalName.asString()) {
"FUNGI_CUTTER" -> 30.0
"COCO_CHOPPER" -> 20.0
else -> 0.0
@@ -187,14 +192,8 @@ class FarmingFortuneDisplay {
}
fun getCollectionFortune(tool: ItemStack?): Double {
- val lore = tool?.getLore() ?: return 0.0
- var hasCollectionAbility = false
- return lore.firstNotNullOfOrNull {
- if (hasCollectionAbility || it == "§6Collection Analysis") {
- hasCollectionAbility = true
- collectionPattern.matchEntire(it)?.groups?.get(1)?.value?.toDoubleOrNull()
- } else null
- } ?: 0.0
+ val string = tool?.getLore()?.nextAfter("§6Collection Analysis", 3) ?: return 0.0
+ return collectionPattern.matchMatcher(string) { group("ff").toDoubleOrNull() } ?: 0.0
}
fun getCounterFortune(tool: ItemStack?): Double {
@@ -251,42 +250,32 @@ class FarmingFortuneDisplay {
itemBaseFortune = 0.0
greenThumbFortune = 0.0
for (line in tool?.getLore()!!) {
- val match = tooltipFortunePattern.matchEntire(line)?.groups
- if (match != null) {
- displayedFortune = match[1]!!.value.toDouble()
- reforgeFortune = match[2]?.value?.toDouble() ?: 0.0
-
- itemBaseFortune = if (tool.getInternalName().contains("LOTUS")) 5.0
- else displayedFortune - reforgeFortune - enchantmentFortune - (tool.getFarmingForDummiesCount() ?: 0 ) * 1.0
- greenThumbFortune = if (tool.getInternalName().contains("LOTUS")) {
- displayedFortune - reforgeFortune - itemBaseFortune
- } else 0.0
- }
- }
- }
-
- fun getCurrentFarmingFortune(alwaysBaseFortune: Boolean = false): Double {
- val upgradeFortune = upgradeFortune ?: 0.0
- val accessoryFortune = accessoryFortune ?: 0.0
+ val match = tooltipFortunePattern.matchEntire(line)?.groups ?: continue
- val baseFortune = if (alwaysBaseFortune) 100.0 else baseFortune
- var carrotFortune = 0.0
+ displayedFortune = match[1]!!.value.toDouble()
+ reforgeFortune = match[2]?.value?.toDouble() ?: 0.0
- if (currentCrop == CropType.CARROT) {
- GardenAPI.config?.fortune?.let {
- if (it.carrotFortune) carrotFortune = 12.0
+ itemBaseFortune = if (tool.getInternalName().contains("LOTUS")) {
+ 5.0
+ } else {
+ val dummiesFF = (tool.getFarmingForDummiesCount() ?: 0) * 1.0
+ displayedFortune - reforgeFortune - enchantmentFortune - dummiesFF
}
+ greenThumbFortune = if (tool.getInternalName().contains("LOTUS")) {
+ displayedFortune - reforgeFortune - itemBaseFortune
+ } else 0.0
}
- return baseFortune + upgradeFortune + tabFortune + toolFortune + accessoryFortune + carrotFortune
}
+ fun getCurrentFarmingFortune() = tabFortuneUniversal + tabFortuneCrop
+
fun CropType.getLatestTrueFarmingFortune() = latestFF?.get(this)
}
@SubscribeEvent
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
- event.move(3,"garden.farmingFortuneDisplay", "garden.farmingFortunes.display")
- event.move(3,"garden.farmingFortuneDropMultiplier", "garden.farmingFortunes.dropMultiplier")
- event.move(3,"garden.farmingFortunePos", "garden.farmingFortunes.pos")
+ event.move(3, "garden.farmingFortuneDisplay", "garden.farmingFortunes.display")
+ event.move(3, "garden.farmingFortuneDropMultiplier", "garden.farmingFortunes.dropMultiplier")
+ event.move(3, "garden.farmingFortunePos", "garden.farmingFortunes.pos")
}
-} \ No newline at end of file
+}
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 49eae1427..8998903d5 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt
@@ -2,6 +2,7 @@ package at.hannibal2.skyhanni.features.garden
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.events.BlockClickEvent
import at.hannibal2.skyhanni.events.ConfigLoadEvent
@@ -12,7 +13,6 @@ import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
import at.hannibal2.skyhanni.events.PacketEvent
import at.hannibal2.skyhanni.events.RepositoryReloadEvent
-import at.hannibal2.skyhanni.events.TabListUpdateEvent
import at.hannibal2.skyhanni.features.garden.CropType.Companion.getCropType
import at.hannibal2.skyhanni.features.garden.composter.ComposterOverlay
import at.hannibal2.skyhanni.features.garden.contest.FarmingContestAPI
@@ -26,6 +26,7 @@ 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
@@ -46,15 +47,16 @@ object GardenAPI {
var toolInHand: String? = null
var itemInHand: ItemStack? = null
var cropInHand: CropType? = null
- var mushroomCowPet = false
+ val mushroomCowPet get() = PetAPI.currentPet?.contains("Mooshroom Cow") ?: false
private var inBarn = false
val onBarnPlot get() = inBarn && inGarden()
- val config get() = ProfileStorageData.profileSpecific?.garden
+ val storage get() = ProfileStorageData.profileSpecific?.garden
+ var totalAmountVisitorsExisting = 0
var gardenExp: Long?
- get() = config?.experience
+ get() = storage?.experience
set(value) {
value?.let {
- config?.experience = it
+ storage?.experience = it
}
}
@@ -86,13 +88,6 @@ object GardenAPI {
}
@SubscribeEvent
- fun onTabListUpdate(event: TabListUpdateEvent) {
- if (inGarden()) {
- mushroomCowPet = event.tabList.any { it.startsWith(" Strength: §r§c❁") }
- }
- }
-
- @SubscribeEvent
fun onWorldChange(event: LorenzWorldChangeEvent) {
SkyHanniMod.coroutineScope.launch {
delay(2.seconds)
@@ -143,7 +138,7 @@ object GardenAPI {
return false
}
- fun inGarden() = LorenzUtils.inSkyBlock && LorenzUtils.skyBlockIsland == IslandType.GARDEN
+ fun inGarden() = IslandType.GARDEN.isInIsland()
fun ItemStack.getCropType(): CropType? {
val internalName = getInternalName()
@@ -161,13 +156,13 @@ object GardenAPI {
}
fun hideExtraGuis() = ComposterOverlay.inInventory || AnitaMedalProfit.inInventory ||
- SkyMartCopperPrice.inInventory || FarmingContestAPI.inInventory || VisitorAPI.inInventory || FFGuideGUI.isInGui()
+ SkyMartCopperPrice.inInventory || FarmingContestAPI.inInventory || VisitorAPI.inInventory || FFGuideGUI.isInGui()
fun clearCropSpeed() {
- config?.cropsPerSecond?.clear()
+ storage?.cropsPerSecond?.clear()
GardenBestCropTime.reset()
updateGardenTool()
- LorenzUtils.chat("§e[SkyHanni] Manually reset all crop speed data!")
+ LorenzUtils.chat("Manually reset all crop speed data!")
}
@SubscribeEvent
@@ -245,6 +240,7 @@ object GardenAPI {
fun onRepoReload(event: RepositoryReloadEvent) {
val data = event.getConstant<GardenJson>("Garden")
gardenExperience = data.garden_exp
+ totalAmountVisitorsExisting = data.visitors.size
}
private var gardenExperience = listOf<Int>()
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 c60fd5086..f6c235cc1 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneFix.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneFix.kt
@@ -82,7 +82,7 @@ class GardenCropMilestoneFix {
crop.setCounter(tabListValue)
GardenCropMilestoneDisplay.update()
if (!loadedCrops.contains(crop)) {
- LorenzUtils.chat("§e[SkyHanni] Loaded ${crop.cropName} milestone data from $source!")
+ LorenzUtils.chat("Loaded ${crop.cropName} milestone data from $source!")
loadedCrops.add(crop)
}
} else if (diff >= minDiff) {
@@ -91,4 +91,4 @@ class GardenCropMilestoneFix {
GardenCropMilestoneDisplay.update()
}
}
-} \ No newline at end of file
+}
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 228f133e9..92a01c7fb 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropTimeCommand.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropTimeCommand.kt
@@ -16,12 +16,12 @@ object GardenCropTimeCommand {
fun onCommand(args: Array<String>) {
if (!config.display) {
- LorenzUtils.chat("§c[SkyHanni] §cshcroptime requires 'Show money per Hour' feature to be enabled to work!")
+ LorenzUtils.userError("shcroptime requires 'Show money per Hour' feature to be enabled to work!")
return
}
if (args.size < 2) {
- LorenzUtils.chat("§cUsage: /shcroptime <amount> <item>")
+ LorenzUtils.userError("Usage: /shcroptime <amount> <item>")
return
}
@@ -29,7 +29,7 @@ object GardenCropTimeCommand {
val amount = try {
rawAmount.toInt()
} catch (e: NumberFormatException) {
- LorenzUtils.chat("§cNot a valid number: '$rawAmount'")
+ LorenzUtils.userError("Not a valid number: '$rawAmount'")
return
}
@@ -64,10 +64,10 @@ object GardenCropTimeCommand {
}
if (map.isEmpty()) {
- LorenzUtils.chat("§c[SkyHanni] §cNo crop item found for '$rawSearchName'")
+ LorenzUtils.error("No crop item found for '$rawSearchName'.")
return
}
- LorenzUtils.chat("§e[SkyHanni] Crop Speed for ${map.size} items:\n" + map.sorted().keys.joinToString("\n"))
+ LorenzUtils.chat("Crop Speed for ${map.size} items:\n" + map.sorted().keys.joinToString("\n"))
}
-} \ No newline at end of file
+}
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 d033255d2..50cf6b758 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenLevelDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenLevelDisplay.kt
@@ -49,7 +49,8 @@ class GardenLevelDisplay {
LorenzUtils.clickableChat(
" \n§b§lGARDEN LEVEL UP §8$oldLevel ➜ §b$newLevel\n" +
" §8+§aRespect from Elite Farmers and SkyHanni members :)\n ",
- "/gardenlevels"
+ "/gardenlevels",
+ false
)
}
}
@@ -118,4 +119,4 @@ class GardenLevelDisplay {
event.move(3, "garden.gardenLevelDisplay", "garden.gardenLevels.display")
event.move(3, "garden.gardenLevelPos", "garden.gardenLevels.pos")
}
-} \ No newline at end of file
+}
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 3254e685b..c058e9fe6 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.features.garden
import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.config.ConfigFileType
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.ConfigLoadEvent
import at.hannibal2.skyhanni.events.GuiRenderEvent
@@ -44,7 +45,7 @@ object GardenNextJacobContest {
private var inCalendar = false
private val patternDay = "§aDay (?<day>.*)".toPattern()
private val patternMonth = "(?<month>.*), Year (?<year>.*)".toPattern()
- private val patternCrop = "§e○ §7(?<crop>.*)".toPattern()
+ private val patternCrop = "§(e○|6☘) §7(?<crop>.*)".toPattern()
private const val maxContestsPerYear = 124
private const val contestDuration = 1_000 * 60 * 20
@@ -146,17 +147,13 @@ object GardenNextJacobContest {
if (!lore.any { it.contains("§6§eJacob's Farming Contest") }) continue
val name = item.name ?: continue
- val matcherDay = patternDay.matcher(name)
- if (!matcherDay.matches()) continue
+ val day = patternDay.matchMatcher(name) { group("day").toInt() } ?: continue
- val day = matcherDay.group("day").toInt()
val startTime = SkyBlockTime(year, month, day).toMillis()
val crops = mutableListOf<CropType>()
for (line in lore) {
- val matcherCrop = patternCrop.matcher(line)
- if (!matcherCrop.matches()) continue
- crops.add(CropType.getByName(matcherCrop.group("crop")))
+ patternCrop.matchMatcher(line) { crops.add(CropType.getByName(group("crop"))) }
}
contests[startTime] = FarmingContest(startTime + contestDuration, crops)
@@ -171,7 +168,7 @@ object GardenNextJacobContest {
sendContests()
} else {
LorenzUtils.clickableChat(
- "§e[SkyHanni] §2Click here to submit this years farming contests, thank you for helping everyone out!",
+ "§2Click here to submit this years farming contests, thank you for helping everyone out!",
"shsendcontests"
)
}
@@ -182,7 +179,7 @@ object GardenNextJacobContest {
}
private fun saveConfig() {
- val map = SkyHanniMod.feature.storage.gardenJacobFarmingContestTimes
+ val map = SkyHanniMod.jacobContestsData.contestTimes
map.clear()
val currentYear = SkyBlockTime.now().year
@@ -193,11 +190,12 @@ object GardenNextJacobContest {
map[contest.endTime] = contest.crops
}
+ SkyHanniMod.configManager.saveConfig(ConfigFileType.JACOB_CONTESTS, "Save contests")
}
@SubscribeEvent
fun onConfigLoad(event: ConfigLoadEvent) {
- val savedContests = SkyHanniMod.feature.storage.gardenJacobFarmingContestTimes
+ val savedContests = SkyHanniMod.jacobContestsData.contestTimes
val year = savedContests.firstNotNullOfOrNull {
val endTime = it.key
@@ -219,7 +217,7 @@ object GardenNextJacobContest {
if (array[0] == "enable") {
config.shareAutomatically = 1
SkyHanniMod.feature.storage.contestSendingAsked = true
- LorenzUtils.chat("§e[SkyHanni] §2Enabled automatic sharing of future contests!")
+ LorenzUtils.chat("§2Enabled automatic sharing of future contests!")
}
return
}
@@ -228,7 +226,7 @@ object GardenNextJacobContest {
}
if (!SkyHanniMod.feature.storage.contestSendingAsked && config.shareAutomatically == 0) {
LorenzUtils.clickableChat(
- "§e[SkyHanni] §2Click here to automatically share future contests!",
+ "§2Click here to automatically share future contests!",
"shsendcontests enable"
)
}
@@ -320,7 +318,7 @@ object GardenNextJacobContest {
lastWarningTime = System.currentTimeMillis() + 60_000 * 40
val cropText = crops.joinToString("§7, ") { "§a${it.cropName}" }
- LorenzUtils.chat("§e[SkyHanni] Next farming contest: $cropText")
+ LorenzUtils.chat("Next farming contest: $cropText")
LorenzUtils.sendTitle("§eFarming Contest!", 5.seconds)
SoundUtils.playBeepSound()
@@ -328,7 +326,7 @@ object GardenNextJacobContest {
SkyHanniMod.coroutineScope.launch {
openPopupWindow(
"Farming Contest soon!\n" +
- "Crops: ${cropText.removeColor()}"
+ "Crops: ${cropText.removeColor()}"
)
}
}
@@ -397,7 +395,7 @@ object GardenNextJacobContest {
}
private fun isEnabled() = LorenzUtils.inSkyBlock && config.display
- && (GardenAPI.inGarden() || config.everywhere)
+ && (GardenAPI.inGarden() || config.everywhere)
private fun isFetchEnabled() = isEnabled() && config.fetchAutomatically
private fun isSendEnabled() = isFetchEnabled() && config.shareAutomatically != 2 // 2 = Disabled
@@ -441,11 +439,11 @@ object GardenNextJacobContest {
newContests[timestamp + contestDuration] = FarmingContest(timestamp + contestDuration, crops)
}
} else {
- LorenzUtils.chat("§e[SkyHanni] This years contests aren't available to fetch automatically yet, please load them from your calender or wait 10 minutes!")
+ LorenzUtils.chat("This years contests aren't available to fetch automatically yet, please load them from your calender or wait 10 minutes!")
}
if (newContests.count() == maxContestsPerYear) {
- LorenzUtils.chat("§e[SkyHanni] Successfully loaded this year's contests from elitebot.dev automatically!")
+ LorenzUtils.chat("Successfully loaded this year's contests from elitebot.dev automatically!")
contests = newContests
fetchedFromElite = true
@@ -456,7 +454,7 @@ object GardenNextJacobContest {
}
} catch (e: Exception) {
e.printStackTrace()
- LorenzUtils.error("[SkyHanni] Failed to fetch upcoming contests. Please report this error if it continues to occur.")
+ LorenzUtils.error("Failed to fetch upcoming contests. Please report this error if it continues to occur.")
}
}
@@ -486,13 +484,13 @@ object GardenNextJacobContest {
val result = withContext(dispatcher) { APIUtil.postJSONIsSuccessful(url, body) }
if (result) {
- LorenzUtils.chat("§e[SkyHanni] Successfully submitted this years upcoming contests, thank you for helping everyone out!")
+ LorenzUtils.chat("Successfully submitted this years upcoming contests, thank you for helping everyone out!")
} else {
- LorenzUtils.error("[SkyHanni] Something went wrong submitting upcoming contests!")
+ LorenzUtils.error("Something went wrong submitting upcoming contests!")
}
} catch (e: Exception) {
e.printStackTrace()
- LorenzUtils.error("[SkyHanni] Failed to submit upcoming contests. Please report this error if it continues to occur.")
+ LorenzUtils.error("Failed to submit upcoming contests. Please report this error if it continues to occur.")
null
}
@@ -513,4 +511,4 @@ object GardenNextJacobContest {
event.move(3, "garden.nextJacobContestWarnPopup", "garden.nextJacobContests.warnPopup")
event.move(3, "garden.nextJacobContestPos", "garden.nextJacobContests.pos")
}
-} \ No newline at end of file
+}
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 bff6d4b0e..967368915 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt
@@ -105,7 +105,7 @@ class GardenOptimalSpeed {
lastWarnTime = System.currentTimeMillis()
LorenzUtils.sendTitle("§cWrong speed!", 3.seconds)
cropInHand?.let {
- LorenzUtils.chat("§e[SkyHanni] Wrong speed for ${it.cropName}: §f$currentSpeed §e(§f$optimalSpeed §eis optimal)")
+ LorenzUtils.chat("Wrong speed for ${it.cropName}: §f$currentSpeed §e(§f$optimalSpeed §eis optimal)")
}
}
@@ -130,4 +130,4 @@ class GardenOptimalSpeed {
event.move(3, "garden.optimalSpeedCustom.cactus", "garden.optimalSpeeds.customSpeed.cactus")
event.move(3, "garden.optimalSpeedCustom.mushroom", "garden.optimalSpeeds.customSpeed.mushroom")
}
-} \ No newline at end of file
+}
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 c7d27d873..d5d00d509 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenPlotBorders.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenPlotBorders.kt
@@ -6,15 +6,18 @@ import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
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 {
private val config get() = SkyHanniMod.feature.garden.plotBorders
+ private var timeLastSaved = SimpleTimeMark.farPast()
private var showBorders = false
private val LINE_COLOR = LorenzColor.YELLOW.toColor()
@@ -25,10 +28,14 @@ class GardenPlotBorders {
@SubscribeEvent
fun onKeyClick(event: LorenzKeyPressEvent) {
if (!isEnabled()) return
+ if (timeLastSaved.passedSince() < 250.milliseconds) return
+
if (event.keyCode == Keyboard.KEY_G && Keyboard.isKeyDown(Keyboard.KEY_F3)) {
+ timeLastSaved = SimpleTimeMark.now()
showBorders = !showBorders
}
if (event.keyCode == Keyboard.KEY_F3 && Keyboard.isKeyDown(Keyboard.KEY_G)) {
+ timeLastSaved = SimpleTimeMark.now()
showBorders = !showBorders
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterAPI.kt
index 3a22e5d39..50efa9e42 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterAPI.kt
@@ -9,15 +9,17 @@ import kotlin.time.Duration.Companion.minutes
object ComposterAPI {
var tabListData = mapOf<ComposterDisplay.DataType, String>()
- val composterUpgrades: MutableMap<ComposterUpgrade, Int>? get() = GardenAPI.config?.composterUpgrades
+ val composterUpgrades: MutableMap<ComposterUpgrade, Int>? get() = GardenAPI.storage?.composterUpgrades
- fun ComposterUpgrade.getLevel(addOne: ComposterUpgrade?) = (composterUpgrades?.get(this) ?: 0) + if (addOne == this) 1 else 0
+ fun ComposterUpgrade.getLevel(addOne: ComposterUpgrade?) =
+ (composterUpgrades?.get(this) ?: 0) + if (addOne == this) 1 else 0
fun getFuel() = tabListData[ComposterDisplay.DataType.FUEL]?.removeColor()?.formatNumber() ?: 0
fun getOrganicMatter() = tabListData[ComposterDisplay.DataType.ORGANIC_MATTER]?.removeColor()?.formatNumber() ?: 0
- fun maxOrganicMatter(addOne: ComposterUpgrade?) = 40_000 + ComposterUpgrade.ORGANIC_MATTER_CAP.getLevel(addOne) * 20_000
+ fun maxOrganicMatter(addOne: ComposterUpgrade?) =
+ 40_000 + ComposterUpgrade.ORGANIC_MATTER_CAP.getLevel(addOne) * 20_000
fun multiDropChance(addOne: ComposterUpgrade?) = ComposterUpgrade.MULTI_DROP.getLevel(addOne) * 0.03
@@ -41,4 +43,4 @@ object ComposterAPI {
val costFactor = 1.0 - costReduction.toDouble() / 100
return 2_000.0 * costFactor
}
-} \ 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 5139d8a95..2e089364c 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
@@ -20,7 +20,7 @@ import kotlin.time.DurationUnit
class ComposterDisplay {
private val config get() = SkyHanniMod.feature.garden.composters
- private val hidden get() = GardenAPI.config
+ private val storage get() = GardenAPI.storage
private var display = emptyList<List<Any>>()
private var composterEmptyTime: Duration? = null
@@ -100,7 +100,7 @@ class ComposterDisplay {
private fun addComposterEmptyTime(emptyTime: Duration?): List<Any> {
return if (emptyTime != null) {
val millis = emptyTime.toDouble(DurationUnit.MILLISECONDS).toLong()
- GardenAPI.config?.composterEmptyTime = System.currentTimeMillis() + millis
+ GardenAPI.storage?.composterEmptyTime = System.currentTimeMillis() + millis
val format = TimeUtils.formatDuration(millis, maxUnits = 2)
listOf(NEUItems.getItemStack("BUCKET"), "§b$format")
} else {
@@ -139,24 +139,24 @@ class ComposterDisplay {
private fun sendNotify() {
if (!config.notifyLow.enabled) return
- val hidden = hidden ?: return
+ val storage = storage ?: return
- if (ComposterAPI.getOrganicMatter() <= config.notifyLow.organicMatter && System.currentTimeMillis() >= hidden.informedAboutLowMatter) {
+ if (ComposterAPI.getOrganicMatter() <= config.notifyLow.organicMatter && System.currentTimeMillis() >= storage.informedAboutLowMatter) {
if (config.notifyLow.title) {
LorenzUtils.sendTitle("§cYour Organic Matter is low", 4.seconds)
}
- LorenzUtils.chat("§e[SkyHanni] §cYour Organic Matter is low!")
- hidden.informedAboutLowMatter = System.currentTimeMillis() + 60_000 * 5
+ LorenzUtils.chat("§cYour Organic Matter is low!")
+ storage.informedAboutLowMatter = System.currentTimeMillis() + 60_000 * 5
}
if (ComposterAPI.getFuel() <= config.notifyLow.fuel &&
- System.currentTimeMillis() >= hidden.informedAboutLowFuel
+ System.currentTimeMillis() >= storage.informedAboutLowFuel
) {
if (config.notifyLow.title) {
LorenzUtils.sendTitle("§cYour Fuel is low", 4.seconds)
}
- LorenzUtils.chat("§e[SkyHanni] §cYour Fuel is low!")
- hidden.informedAboutLowFuel = System.currentTimeMillis() + 60_000 * 5
+ LorenzUtils.chat("§cYour Fuel is low!")
+ storage.informedAboutLowFuel = System.currentTimeMillis() + 60_000 * 5
}
}
@@ -172,7 +172,7 @@ class ComposterDisplay {
}
private fun checkWarningsAndOutsideGarden() {
- val storage = GardenAPI.config ?: return
+ val storage = GardenAPI.storage ?: return
val format = if (storage.composterEmptyTime != 0L) {
val duration = storage.composterEmptyTime - System.currentTimeMillis()
@@ -195,14 +195,14 @@ class ComposterDisplay {
private fun warn(warningMessage: String) {
if (!config.warnAlmostClose) return
- val storage = GardenAPI.config ?: return
+ val storage = GardenAPI.storage ?: return
if (LorenzUtils.inDungeons) return
if (LorenzUtils.inKuudraFight) return
if (System.currentTimeMillis() < storage.lastComposterEmptyWarningTime + 1000 * 60 * 2) return
storage.lastComposterEmptyWarningTime = System.currentTimeMillis()
- LorenzUtils.chat("§e[SkyHanni] $warningMessage")
+ LorenzUtils.chat(warningMessage)
LorenzUtils.sendTitle("§eComposter Warning!", 3.seconds)
}
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 72845cc63..b99f059da 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
@@ -74,24 +74,24 @@ object ComposterOverlay {
private var testOffset = 0
var currentOrganicMatterItem: String?
- get() = GardenAPI.config?.composterCurrentOrganicMatterItem
+ get() = GardenAPI.storage?.composterCurrentOrganicMatterItem
private set(value) {
- GardenAPI.config?.composterCurrentOrganicMatterItem = value
+ GardenAPI.storage?.composterCurrentOrganicMatterItem = value
}
var currentFuelItem: String?
- get() = GardenAPI.config?.composterCurrentFuelItem
+ get() = GardenAPI.storage?.composterCurrentFuelItem
private set(value) {
- GardenAPI.config?.composterCurrentFuelItem = value
+ GardenAPI.storage?.composterCurrentFuelItem = value
}
fun onCommand(args: Array<String>) {
if (args.size != 1) {
- LorenzUtils.chat("§cUsage: /shtestcomposter <offset>")
+ LorenzUtils.userError("Usage: /shtestcomposter <offset>")
return
}
testOffset = args[0].toInt()
- LorenzUtils.chat("§e[SkyHanni] Composter test offset set to $testOffset.")
+ LorenzUtils.chat("Composter test offset set to $testOffset.")
}
@SubscribeEvent
@@ -382,7 +382,7 @@ object ComposterOverlay {
}
val testOffset = if (testOffset_ > map.size) {
- LorenzUtils.chat("§cSkyHanni] Invalid Composter Overlay Offset! $testOffset cannot be greater than ${map.size}!")
+ LorenzUtils.error("Invalid Composter Overlay Offset! $testOffset cannot be greater than ${map.size}!")
ComposterOverlay.testOffset = 0
0
} else testOffset_
@@ -449,7 +449,7 @@ object ComposterOverlay {
}
val having = InventoryUtils.countItemsInLowerInventory { it.getInternalName_old() == internalName }
if (having >= itemsNeeded) {
- LorenzUtils.chat("§e[SkyHanni] $itemName §8x${itemsNeeded} §ealready found in inventory!")
+ LorenzUtils.chat("$itemName §8x${itemsNeeded} §ealready found in inventory!")
return
}
@@ -463,16 +463,16 @@ object ComposterOverlay {
val sackType = if (internalName == "VOLTA" || internalName == "OIL_BARREL") "Mining"
else "Enchanted Agronomy"
LorenzUtils.clickableChat(
- "§e[SkyHanni] Sacks could not be loaded. Click here and open your §9$sackType Sack §eto update the data!",
+ "Sacks could not be loaded. Click here and open your §9$sackType Sack §eto update the data!",
"sax"
)
return
} else if (amountInSacks == 0L) {
SoundUtils.playErrorSound()
if (LorenzUtils.noTradeMode) {
- LorenzUtils.chat("§e[SkyHanni] No $itemName §efound in sacks.")
+ LorenzUtils.chat("No $itemName §efound in sacks.")
} else {
- LorenzUtils.chat("§e[SkyHanni] No $itemName §efound in sacks. Opening Bazaar.")
+ LorenzUtils.chat("No $itemName §efound in sacks. Opening Bazaar.")
BazaarApi.searchForBazaarItem(itemName, itemsNeeded)
}
return
@@ -481,10 +481,10 @@ object ComposterOverlay {
LorenzUtils.sendCommandToServer("gfs $internalName ${itemsNeeded - having}")
if (amountInSacks <= itemsNeeded - having) {
if (LorenzUtils.noTradeMode) {
- LorenzUtils.chat("§e[SkyHanni] You're out of $itemName §ein your sacks!")
+ LorenzUtils.chat("You're out of $itemName §ein your sacks!")
} else {
LorenzUtils.clickableChat(
- "§e[SkyHanni] You're out of $itemName §ein your sacks! Click here to buy more on the Bazaar!",
+ "You're out of $itemName §ein your sacks! Click here to buy more on the Bazaar!",
"bz ${itemName.removeColor()}"
)
}
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 695092598..397231258 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
@@ -46,17 +46,15 @@ class GardenComposterInventoryFeatures {
if (next) {
if (line.endsWith(" Copper")) continue
if (line == "") break
- val pair = ItemUtils.readItemAmount(line)
- if (pair == null) {
- LorenzUtils.error("§c[SkyHanni] Could not read item '$line'")
+ val (itemName, amount) = ItemUtils.readItemAmount(line) ?: run {
+ LorenzUtils.error("Could not read item '$line'")
continue
}
- val (itemName, amount) = pair
val internalName = NEUItems.getInternalNameOrNull(itemName)
if (internalName == null) {
- LorenzUtils.chat(
- "§c[SkyHanni] Error reading internal name for item '$itemName§c' " +
- "(in GardenComposterInventoryFeatures)"
+ LorenzUtils.error(
+ "Error reading internal name for item '$itemName§c' " +
+ "(in GardenComposterInventoryFeatures)"
)
continue
}
@@ -102,4 +100,4 @@ class GardenComposterInventoryFeatures {
event.move(3, "garden.composterUpgradePrice", "garden.composters.upgradePrice")
event.move(3, "garden.composterHighLightUpgrade", "garden.composters.highlightUpgrade")
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/ContestBracket.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/ContestBracket.kt
index 4218f0e41..9ee04d3fc 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/ContestBracket.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/ContestBracket.kt
@@ -1,11 +1,13 @@
package at.hannibal2.skyhanni.features.garden.contest
enum class ContestBracket(val color: String) {
+ DIAMOND("b"),
+ PLATINUM("3"),
GOLD("6"),
SILVER("f"),
BRONZE("c"),
;
val displayName = "§$color§l$name"
- val pattern = "$displayName §7\\(§bTop \\d{1,2}%§7\\): §$color(?<amount>.*)".toPattern()
-} \ No newline at end of file
+ val pattern = "$displayName §7\\(§bTop \\d{1,2}%§7\\): §6(?<amount>.*)".toPattern()
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/FarmingContestAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/FarmingContestAPI.kt
index 50985ecfe..d2d866f36 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/FarmingContestAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/FarmingContestAPI.kt
@@ -10,6 +10,8 @@ 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.LorenzUtils
+import at.hannibal2.skyhanni.utils.LorenzUtils.addOrPut
+import at.hannibal2.skyhanni.utils.LorenzUtils.nextAfter
import at.hannibal2.skyhanni.utils.LorenzUtils.sortedDesc
import at.hannibal2.skyhanni.utils.SimpleTimeMark
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
@@ -25,7 +27,7 @@ object FarmingContestAPI {
var inContest = false
var contestCrop: CropType? = null
private var startTime = SimpleTimeMark.farPast()
- private val sidebarCropPattern = "§e○ §f(?<crop>.*) §a.*".toPattern()
+ private val sidebarCropPattern = "(?:§e○|§6☘) §f(?<crop>.*) §a.*".toPattern()
var inInventory = false
@@ -68,20 +70,10 @@ object FarmingContestAPI {
}
private fun readCurrentCrop(): CropType? {
- var next = false
- for (line in ScoreboardData.sidebarLinesFormatted) {
- if (line == "§eJacob's Contest") {
- next = true
- continue
- }
- if (next) {
- sidebarCropPattern.matchMatcher(line) {
- return CropType.getByName(group("crop"))
- }
- }
+ val line = ScoreboardData.sidebarLinesFormatted.nextAfter("§eJacob's Contest") ?: return null
+ return sidebarCropPattern.matchMatcher(line) {
+ CropType.getByName(group("crop"))
}
-
- return null
}
@SubscribeEvent
@@ -120,12 +112,15 @@ object FarmingContestAPI {
cropPattern.matchMatcher(it) { CropType.getByName(group("crop")) }
} ?: error("Crop not found in lore!")
- val brackets = ContestBracket.entries.associateWith { bracket ->
- lore.firstNotNullOfOrNull {
- bracket.pattern.matchMatcher(it) {
- group("amount").replace(",", "").toInt()
- }
- } ?: error("Farming contest bracket not found in lore!")
+ val brackets = buildMap {
+ for (bracket in ContestBracket.entries) {
+ val amount = lore.firstNotNullOfOrNull {
+ bracket.pattern.matchMatcher(it) {
+ group("amount").replace(",", "").toInt()
+ }
+ } ?: continue
+ put(bracket, amount)
+ }
}
return FarmingContest(time, crop, brackets)
@@ -137,15 +132,18 @@ object FarmingContestAPI {
fun calculateAverages(crop: CropType): Pair<Int, Map<ContestBracket, Int>> {
var amount = 0
- val map = mutableMapOf<ContestBracket, Int>()
+ val crops = mutableMapOf<ContestBracket, Int>()
+ val contests = mutableMapOf<ContestBracket, Int>()
for (contest in getContestsOfType(crop).associateWith { it.time }.sortedDesc().keys) {
amount++
- for ((bracket, count) in contest.brackets) {
- val old = map.getOrDefault(bracket, 0)
- map[bracket] = count + old
+ val brackets = contest.brackets
+ for ((bracket, count) in brackets) {
+ val old = crops.getOrDefault(bracket, 0)
+ crops[bracket] = count + old
+ contests.addOrPut(bracket, 1)
}
if (amount == 10) break
}
- return Pair(amount, map.mapValues { (_, counter) -> counter / amount })
+ return Pair(amount, crops.mapValues { (bracket, counter) -> counter / contests[bracket]!! })
}
-} \ No newline at end of file
+}
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 e02b358b9..3f03cbe4b 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
@@ -81,10 +81,6 @@ class JacobContestFFNeededDisplay {
add(listOf("§cThis is too low, showing 19.9 Blocks/second instead!"))
blocksPerSecond = 19.9
}
- if (blocksPerSecond < 1) {
- addAsSingletonList("§cLow blocks per second!")
- addAsSingletonList("§cFarm this crop for couple more seconds!")
- }
}
addAsSingletonList("")
@@ -96,27 +92,18 @@ class JacobContestFFNeededDisplay {
add(listOf("§6Your ", crop.icon, "§6FF: $farmingFortune"))
}
addAsSingletonList("")
- if (blocksPerSecond == null || trueFF == null) {
- add(listOf("§cMissing data from above!"))
- } else {
- val predictedScore = (trueFF * blocksPerSecond * crop.baseDrops * 20 * 60 / 100).toInt().addSeparators()
- add(listOf("§6Predicted ", crop.icon, "§6crops: $predictedScore"))
- }
- }
-
- private fun formatFarmingFortune(farmingFortune: Double): String {
- var ff = farmingFortune
- if (!config.farmingFortunes.dropMultiplier) {
- ff -= 100
- if (ff < 100) {
- ff = 0.0
- }
+ if (blocksPerSecond == null || trueFF == null) {
+ add(listOf("§cMissing data from above!"))
+ } else {
+ val predictedScore = (trueFF * blocksPerSecond * crop.baseDrops * 20 * 60 / 100).toInt().addSeparators()
+ add(listOf("§6Predicted ", crop.icon, "§6crops: $predictedScore"))
}
- return ceil(ff).addSeparators()
}
+ private fun formatFarmingFortune(farmingFortune: Double) = ceil(farmingFortune).addSeparators()
+
private fun getLine(bracket: ContestBracket, map: Map<ContestBracket, Int>, crop: CropType): String {
- val counter = map[bracket]!!
+ val counter = map[bracket] ?: return " ${bracket.displayName}§f: §8Not found!"
val blocksPerSecond = crop.getRealBlocksPerSecond()
val cropsPerSecond = counter.toDouble() / blocksPerSecond / 60
val farmingFortune = formatFarmingFortune(cropsPerSecond * 100 / 20 / crop.baseDrops)
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 50a46b1e2..faa2ed534 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
@@ -32,7 +32,7 @@ class JacobContestStatsSummary {
when (event.phase) {
FarmingContestPhase.START -> {
- LorenzUtils.chat("§e[SkyHanni] Started tracking your Jacob Contest Blocks Per Second!")
+ LorenzUtils.chat("Started tracking your Jacob Contest Blocks Per Second!")
startTime = System.currentTimeMillis()
}
@@ -41,16 +41,16 @@ class JacobContestStatsSummary {
val durationInSeconds = duration.toDouble() / 1000
val blocksPerSecond = (blocksBroken.toDouble() / durationInSeconds).round(2)
val cropName = event.crop.cropName
- LorenzUtils.chat("§e[SkyHanni] Stats for $cropName Contest:")
+ LorenzUtils.chat("Stats for $cropName Contest:")
val time = TimeUtils.formatDuration(duration - 999)
- LorenzUtils.chat("§e[SkyHanni] §7Blocks Broken in total: §e${blocksBroken.addSeparators()}")
+ LorenzUtils.chat("§7Blocks Broken in total: §e${blocksBroken.addSeparators()}")
val color = getBlocksPerSecondColor(blocksPerSecond)
- LorenzUtils.chat("§e[SkyHanni] §7Average Blocks Per Second: $color$blocksPerSecond")
- LorenzUtils.chat("§e[SkyHanni] §7Participated for §b$time")
+ LorenzUtils.chat("§7Average Blocks Per Second: $color$blocksPerSecond")
+ LorenzUtils.chat("§7Participated for §b$time")
}
FarmingContestPhase.CHANGE -> {
- LorenzUtils.chat("§e[SkyHanni] You changed the crop during the contest, resetting the Blocks Per Second calculation..")
+ LorenzUtils.chat("You changed the crop during the contest, resetting the Blocks Per Second calculation..")
startTime = System.currentTimeMillis()
}
}
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 c02835270..4d9e035cd 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
@@ -6,7 +6,6 @@ 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.farming.GardenCropSpeed.getLatestBlocksPerSecond
-import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed.getSpeed
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
import at.hannibal2.skyhanni.utils.LorenzUtils.addSelector
@@ -63,8 +62,9 @@ class JacobContestTimeNeeded {
sorted: MutableMap<CropType, Double>,
map: MutableMap<CropType, Renderable>
) {
- val speed = crop.getSpeed()
- if (speed == null) {
+
+ val bps = crop.getBps()
+ if (bps == null) {
sorted[crop] = Double.MAX_VALUE
map[crop] = Renderable.hoverTips(
"§9${crop.cropName} §cNo speed data!",
@@ -72,6 +72,15 @@ class JacobContestTimeNeeded {
)
return
}
+ val ff = crop.getLatestTrueFarmingFortune()
+ if (ff == null) {
+ sorted[crop] = Double.MAX_VALUE
+ map[crop] = Renderable.hoverTips(
+ "§9${crop.cropName} §cNo Farming Fortune data!",
+ listOf("§cHold a ${crop.cropName} specific", "§cfarming tool in hand to show data!")
+ )
+ return
+ }
val averages = FarmingContestAPI.calculateAverages(crop).second
if (averages.isEmpty()) {
@@ -86,6 +95,8 @@ class JacobContestTimeNeeded {
return
}
+ val speed = (ff * crop.baseDrops * bps / 100).round(1).toInt()
+
renderCrop(speed, crop, averages, sorted, map)
}
@@ -98,7 +109,7 @@ class JacobContestTimeNeeded {
) {
var lowBPSWarning = listOf<String>()
val rawSpeed = speed.toDouble()
- val speedForFormular = crop.getLatestBlocksPerSecond()?.let {
+ val speedForFormular = crop.getBps()?.let {
if (it < 15) {
val v = rawSpeed / it
(v * 19.9).toInt()
@@ -106,13 +117,18 @@ class JacobContestTimeNeeded {
} ?: speed
var showLine = ""
val brackets = mutableListOf<String>()
- for ((bracket, amount) in averages) {
+ for (bracket in ContestBracket.entries) {
+ val amount = averages[bracket]
+ if (amount == null) {
+ brackets.add("${bracket.displayName} §cNo contest data found!")
+ continue
+ }
val timeInMinutes = amount.toDouble() / speedForFormular / 60
val formatDuration = TimeUtils.formatDuration((timeInMinutes * 60 * 1000).toLong())
val color = if (timeInMinutes < 20) "§b" else "§c"
var marking = ""
var bracketText = "${bracket.displayName} $color$formatDuration"
- var blocksPerSecond = crop.getLatestBlocksPerSecond()
+ var blocksPerSecond = crop.getBps()
if (blocksPerSecond == null) {
marking += "§0§l !" //hoping this never shows
blocksPerSecond = 19.9
@@ -125,18 +141,17 @@ class JacobContestTimeNeeded {
listOf("§cYour Blocks/second is too low,", "§cshowing 19.9 Blocks/second instead!")
} else {
marking += " "
- lowBPSWarning = listOf("§aYour Blocks/second is good :)")
}
}
val line = if (timeInMinutes < 20) {
- "§9${crop.cropName} §b$formatDuration" + marking
+ "§9${crop.cropName} §7in §b$formatDuration" + marking
} else {
val cropFF = crop.getLatestTrueFarmingFortune() ?: 0.0
val cropsPerSecond = amount.toDouble() / blocksPerSecond / 60
val ffNeeded = cropsPerSecond * 100 / 20 / crop.baseDrops
val missing = (ffNeeded - cropFF).toInt()
- bracketText += " §7(${missing.addSeparators()} more FF needed!)"
- "§9${crop.cropName} §cNo ${currentBracket.displayName} §cMedal possible!" + marking
+ bracketText += " §7(Need ${missing.addSeparators()} FF more)"
+ "§9${crop.cropName} §cNo ${currentBracket.displayName} §cmedal possible!" + marking
}
brackets.add(bracketText)
if (bracket == currentBracket) {
@@ -150,12 +165,18 @@ class JacobContestTimeNeeded {
add("")
val latestFF = crop.getLatestTrueFarmingFortune() ?: 0.0
add("§7Latest FF: §e${(latestFF).addSeparators()}")
- val bps = crop.getLatestBlocksPerSecond()?.round(1) ?: 0
- add("§7Blocks/Second: §e${bps.addSeparators()}")
+ val bps = crop.getBps()?.round(1) ?: 0
+ add("§7${addBpsTitle()}§e${bps.addSeparators()}")
addAll(lowBPSWarning)
})
}
+ private fun addBpsTitle() = if (config.jacobContestCustomBps) "Custom Blocks/Second: " else "Your Blocks/Second: "
+
+ private fun CropType.getBps() = if (config.jacobContestCustomBps) {
+ config.jacobContestCustomBpsValue
+ } else getLatestBlocksPerSecond()
+
@SubscribeEvent
fun onRenderOverlay(event: GuiRenderEvent.ChestGuiOverlayRenderEvent) {
if (!isEnabled()) return
@@ -164,4 +185,4 @@ class JacobContestTimeNeeded {
}
fun isEnabled() = LorenzUtils.inSkyBlock && config.jacobContextTimes
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobFarmingContestsInventory.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobFarmingContestsInventory.kt
index 6150d60fc..dfc83e404 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobFarmingContestsInventory.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobFarmingContestsInventory.kt
@@ -14,6 +14,8 @@ import at.hannibal2.skyhanni.utils.LorenzColor
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.RenderUtils.drawSlotText
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
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
@@ -29,7 +31,7 @@ class JacobFarmingContestsInventory {
// Render the contests a tick delayed to feel smoother
private var hideEverything = true
- private val contestEarnedPattern = "§7You earned a §(?<medalColour>.*)§l.* §7medal!".toPattern()
+ private val medalPattern = "§7§7You placed in the (?<medal>.*)".toPattern()
@SubscribeEvent
fun onInventoryClose(event: InventoryCloseEvent) {
@@ -50,10 +52,7 @@ class JacobFarmingContestsInventory {
val name = item.name!!
- if (foundEvents.contains(name)) {
- } else {
- foundEvents.add(name)
- }
+ foundEvents.add(name)
val time = FarmingContestAPI.getSbTimeFor(name) ?: continue
FarmingContestAPI.addContest(time, item)
if (config.realTime) {
@@ -121,32 +120,35 @@ class JacobFarmingContestsInventory {
for (line in stack.getLore()) {
if (line.contains("Contest boosted by Finnegan!")) finneganContest = true
- val matcher = contestEarnedPattern.matcher(line)
- if (matcher.matches()) {
- val medalEarned = ContestBracket.entries.find { it.color == matcher.group("medalColour") } ?: return
-
- var stackTip = "§${medalEarned.color}✦"
- var x = event.x + 9
- var y = event.y + 1
- var scale = .7f
+ val name = medalPattern.matchMatcher(line) { group("medal").removeColor() } ?: continue
+ val medal = LorenzUtils.enumValueOfOrNull<ContestBracket>(name) ?: return
- if (finneganContest && config.finneganIcon) {
- stackTip = "§${medalEarned.color}▲"
- x = event.x + 5
- y = event.y - 2
- scale = 1.3f
- }
+ var stackTip = "§${medal.color}✦"
+ var x = event.x + 9
+ var y = event.y + 1
+ var scale = .7f
- event.drawSlotText(x, y, stackTip, scale)
+ if (finneganContest && config.finneganIcon) {
+ stackTip = "§${medal.color}▲"
+ x = event.x + 5
+ y = event.y - 2
+ scale = 1.3f
}
+
+ event.drawSlotText(x, y, stackTip, scale)
}
}
+
@SubscribeEvent
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
- event.move(3, "inventory.jacobFarmingContestHighlightRewards", "inventory.jacobFarmingContests.highlightRewards")
+ event.move(
+ 3,
+ "inventory.jacobFarmingContestHighlightRewards",
+ "inventory.jacobFarmingContests.highlightRewards"
+ )
event.move(3, "inventory.jacobFarmingContestHideDuplicates", "inventory.jacobFarmingContests.hideDuplicates")
event.move(3, "inventory.jacobFarmingContestRealTime", "inventory.jacobFarmingContests.realTime")
event.move(3, "inventory.jacobFarmingContestFinneganIcon", "inventory.jacobFarmingContests.finneganIcon")
event.move(3, "inventory.jacobFarmingContestMedalIcon", "inventory.jacobFarmingContests.medalIcon")
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingArmorDrops.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/ArmorDropTracker.kt
index 8092ff476..21c271e49 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingArmorDrops.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/ArmorDropTracker.kt
@@ -2,7 +2,6 @@ package at.hannibal2.skyhanni.features.garden.farming
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.LorenzChatEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
@@ -12,23 +11,38 @@ import at.hannibal2.skyhanni.features.garden.CropType
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.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.RenderUtils.renderStrings
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
+import com.google.gson.annotations.Expose
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.time.Duration.Companion.seconds
-class FarmingArmorDrops {
- private var display = emptyList<String>()
- private val storage get() = GardenAPI.config
+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 tracker = SkyHanniTracker("Armor Drop Tracker", { Data() }, { it.garden.armorDropTracker })
+ { drawDisplay(it) }
+
+ class Data : TrackerData() {
+ override fun reset() {
+ drops.clear()
+ }
+
+ @Expose
+ var drops: MutableMap<ArmorDropType, Int> = mutableMapOf()
+ }
+
enum class ArmorDropType(val dropName: String, val chatMessage: String) {
CROPIE("§9Cropie", "§6§lRARE CROP! §r§f§r§9Cropie §r§b(Armor Set Bonus)"),
SQUASH("§5Squash", "§6§lRARE CROP! §r§f§r§5Squash §r§b(Armor Set Bonus)"),
@@ -37,7 +51,6 @@ class FarmingArmorDrops {
@SubscribeEvent
fun onPreProfileSwitch(event: PreProfileSwitchEvent) {
- display = emptyList()
hasArmor = false
}
@@ -54,38 +67,26 @@ class FarmingArmorDrops {
}
private fun addDrop(drop: ArmorDropType) {
- val drops = storage?.farmArmorDrops ?: return
- val old = drops[drop] ?: 0
- drops[drop] = old + 1
- update()
- }
-
- private fun update() {
- display = drawDisplay()
+ tracker.modify {
+ it.drops.addOrPut(drop, 1)
+ }
}
- private fun drawDisplay() = buildList {
- val drops = storage?.farmArmorDrops ?: return@buildList
-
- add("§7RNG Drops for Farming Armor:")
- for ((drop, amount) in drops.sortedDesc()) {
+ private fun drawDisplay(data: Data): List<List<Any>> = buildList {
+ addAsSingletonList("§7Armor Drop Tracker:")
+ for ((drop, amount) in data.drops.sortedDesc()) {
val dropName = drop.dropName
- add(" §7- §e${amount.addSeparators()}x $dropName")
+ addAsSingletonList(" §7- §e${amount.addSeparators()}x $dropName")
}
}
@SubscribeEvent
- fun onConfigLoad(event: ConfigLoadEvent) {
- update()
- }
-
- @SubscribeEvent
- fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
+ fun onRenderOverlay(event: GuiRenderEvent) {
if (!GardenAPI.inGarden()) return
if (!config.enabled) return
if (!hasArmor) return
- config.pos.renderStrings(display, posLabel = "Farming Armor Drops")
+ tracker.renderDisplay(config.pos)
}
@SubscribeEvent
@@ -111,32 +112,30 @@ class FarmingArmorDrops {
armorDropInfo = data.special_crops
}
- companion object {
- var armorDropInfo = mapOf<String, DropInfo>()
- private var currentArmorDropChance = 0.0
- private var lastCalculationTime = SimpleTimeMark.farPast()
+ private var armorDropInfo = mapOf<String, DropInfo>()
+ private var currentArmorDropChance = 0.0
+ private var lastCalculationTime = SimpleTimeMark.farPast()
- fun getDropsPerHour(crop: CropType?): Double {
- if (crop == null) return 0.0
+ fun getDropsPerHour(crop: CropType?): Double {
+ if (crop == null) return 0.0
- if (lastCalculationTime.passedSince() > 5.seconds) {
- lastCalculationTime = SimpleTimeMark.now()
+ if (lastCalculationTime.passedSince() > 5.seconds) {
+ lastCalculationTime = SimpleTimeMark.now()
- val armorDropName = crop.specialDropType
- val armorName = armorDropInfo[armorDropName]?.armor_type ?: return 0.0
- val pieceCount = InventoryUtils.getArmor()
- .mapNotNull { it?.getInternalName()?.asString() }
- .count { it.contains(armorName) || it.contains("FERMENTO") }
+ val armorDropName = crop.specialDropType
+ val armorName = armorDropInfo[armorDropName]?.armor_type ?: return 0.0
+ val pieceCount = InventoryUtils.getArmor()
+ .mapNotNull { it?.getInternalName()?.asString() }
+ .count { it.contains(armorName) || it.contains("FERMENTO") }
- val dropRates = armorDropInfo[armorDropName]?.chance ?: return 0.0
- var dropRate = 0.0
- if (pieceCount > 0 && dropRates.size >= pieceCount) {
- dropRate = dropRates[pieceCount - 1]
- }
- currentArmorDropChance = (dropRate * 60 * 60.0) / 100
+ val dropRates = armorDropInfo[armorDropName]?.chance ?: return 0.0
+ var dropRate = 0.0
+ if (pieceCount > 0 && dropRates.size >= pieceCount) {
+ dropRate = dropRates[pieceCount - 1]
}
- return currentArmorDropChance
+ currentArmorDropChance = (dropRate * 60 * 60.0) / 100
}
+ return currentArmorDropChance
}
@SubscribeEvent
@@ -144,5 +143,15 @@ class FarmingArmorDrops {
event.move(3, "garden.farmingArmorDropsEnabled", "garden.farmingArmorDrop.enabled")
event.move(3, "garden.farmingArmorDropsHideChat", "garden.farmingArmorDrop.hideChat")
event.move(3, "garden.farmingArmorDropsPos", "garden.farmingArmorDrop.pos")
+
+ event.move(8, "#profile.garden.farmArmorDrops", "#profile.garden.armorDropTracker") { old ->
+ val new = JsonObject()
+ new.add("drops", old)
+ new
+ }
+ }
+
+ fun resetCommand(args: Array<String>) {
+ tracker.resetCommand(args, "shresetarmordroptracker")
}
}
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 ff65011c6..b780bbc0e 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
@@ -45,7 +45,7 @@ object CropMoneyDisplay {
fun toggleShowCalculation() {
showCalculation = !showCalculation
- LorenzUtils.chat("§e[SkyHanni] Show crop money calculation: " + if (showCalculation) "enabled" else "disabled")
+ LorenzUtils.chat("Show crop money calculation: " + if (showCalculation) "enabled" else "disabled")
update()
}
@@ -54,7 +54,7 @@ object CropMoneyDisplay {
private var loaded = false
private var ready = false
private val cropNames = mutableMapOf<NEUInternalName, CropType>()
- private val toolHasBountiful get() = GardenAPI.config?.toolWithBountiful
+ private val toolHasBountiful get() = GardenAPI.storage?.toolWithBountiful
@SubscribeEvent
fun onPreProfileSwitch(event: PreProfileSwitchEvent) {
@@ -155,7 +155,7 @@ object CropMoneyDisplay {
if (config.armor) {
val amountPerHour =
- it.multiplier * GardenCropSpeed.getRecentBPS() * FarmingArmorDrops.getDropsPerHour(it)
+ it.multiplier * GardenCropSpeed.getRecentBPS() * ArmorDropTracker.getDropsPerHour(it)
extraArmorCoins = amountPerHour * it.specialDropType.asInternalName().getNpcPrice()
}
}
@@ -276,8 +276,8 @@ object CropMoneyDisplay {
val onlyNpcPrice =
(!config.useCustomFormat && LorenzUtils.noTradeMode) ||
- (config.useCustomFormat && config.customFormat.size == 1 &&
- config.customFormat[0] == 2)
+ (config.useCustomFormat && config.customFormat.size == 1 &&
+ config.customFormat[0] == 2)
for ((internalName, amount) in multipliers.moveEntryToTop { isSeeds(it.key) }) {
val crop = cropNames[internalName]!!
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 8abe65ccf..fd337a361 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
@@ -118,7 +118,7 @@ class CropSpeedMeter {
fun toggle() {
enabled = !enabled
- LorenzUtils.chat("§e[SkyHanni] Crop Speed Meter " + if (enabled) "§aEnabled" else "§cDisabled")
+ LorenzUtils.chat("Crop Speed Meter " + if (enabled) "§aEnabled" else "§cDisabled")
startCrops = emptyMap()
}
@@ -132,4 +132,4 @@ class CropSpeedMeter {
}
fun isEnabled() = enabled && GardenAPI.inGarden()
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/DicerRngDropCounter.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/DicerDropTracker.kt
index 040ab1710..24f55672b 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/DicerRngDropCounter.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/DicerDropTracker.kt
@@ -1,28 +1,39 @@
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.ConfigLoadEvent
import at.hannibal2.skyhanni.events.GardenToolChangeEvent
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
-import at.hannibal2.skyhanni.events.PreProfileSwitchEvent
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.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.RenderUtils.renderStrings
+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
-class DicerRngDropCounter {
- private var display = emptyList<String>()
- private val drops = mutableMapOf<CropType, MutableMap<DropRarity, Int>>()
+object DicerDropTracker {
private val itemDrops = mutableListOf<ItemDrop>()
private val config get() = SkyHanniMod.feature.garden.dicerCounters
+ private val tracker = SkyHanniTracker("Dicer Drop Tracker", { Data() }, { it.garden.dicerDropTracker })
+ { drawDisplay(it) }
+
+ class Data : TrackerData() {
+ override fun reset() {
+ drops.clear()
+ }
+
+ @Expose
+ var drops: MutableMap<CropType, MutableMap<DropRarity, Int>> = mutableMapOf()
+ }
init {
- initDrops()
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()))
@@ -34,11 +45,6 @@ class DicerRngDropCounter {
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()))
}
- private fun initDrops() {
- drops[CropType.MELON] = mutableMapOf()
- drops[CropType.PUMPKIN] = mutableMapOf()
- }
-
enum class DropRarity(val displayName: String) {
UNCOMMON("§a§lUNCOMMON DROP"),
RARE("§9§lRARE DROP"),
@@ -47,13 +53,6 @@ class DicerRngDropCounter {
}
@SubscribeEvent
- fun onPreProfileSwitch(event: PreProfileSwitchEvent) {
- display = emptyList()
- drops.clear()
- initDrops()
- }
-
- @SubscribeEvent
fun onChat(event: LorenzChatEvent) {
if (!GardenAPI.inGarden()) return
if (!config.hideChat && !config.display) return
@@ -62,30 +61,23 @@ class DicerRngDropCounter {
for (drop in itemDrops) {
if (drop.pattern.matches(message)) {
addDrop(drop.crop, drop.rarity)
- saveConfig()
- update()
if (config.hideChat) {
- event.blockedReason = "dicer_rng_drop_counter"
+ event.blockedReason = "dicer_drop_tracker"
}
return
}
}
}
- private fun update() {
- display = drawDisplay()
- }
-
- private fun drawDisplay(): List<String> {
- val help = mutableListOf<String>()
- val items = drops[cropInHand] ?: return help
- help.add("§7RNG Drops for $toolName§7:")
+ private fun drawDisplay(storage: Data) = buildList<List<Any>> {
+ val cropInHand = cropInHand ?: return@buildList
+ val items = storage.drops.getOrPut(cropInHand) { mutableMapOf() }
+ addAsSingletonList("§7Dicer Drop Tracker for $toolName§7:")
for ((rarity, amount) in items.sortedDesc()) {
val displayName = rarity.displayName
- help.add(" §7- §e${amount.addSeparators()}x $displayName")
+ addAsSingletonList(" §7- §e${amount.addSeparators()}x $displayName")
}
- return help
}
private var cropInHand: CropType? = null
@@ -98,46 +90,24 @@ class DicerRngDropCounter {
if (cropInHand != null) {
toolName = event.toolItem!!.name!!
}
- update()
+ tracker.update()
}
private fun addDrop(crop: CropType, rarity: DropRarity) {
- val map = drops[crop]!!
- val old = map[rarity] ?: 0
- map[rarity] = old + 1
- }
-
- @SubscribeEvent
- fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
- if (isEnabled()) {
- config.pos.renderStrings(display, posLabel = "Dicer Counter")
+ tracker.modify {
+ val map = it.drops.getOrPut(crop) { mutableMapOf() }
+ map.addOrPut(rarity, 1)
}
}
- class ItemDrop(val crop: CropType, val rarity: DropRarity, val pattern: Regex)
+ @SubscribeEvent
+ fun onRenderOverlay(event: GuiRenderEvent) {
+ if (!isEnabled()) return
- private fun saveConfig() {
- val map = GardenAPI.config?.dicerRngDrops ?: return
- map.clear()
- for (drop in drops) {
- val crop = drop.key
- for ((rarity, amount) in drop.value) {
- map[crop.cropName + "." + rarity.name] = amount
- }
- }
+ tracker.renderDisplay(config.pos)
}
- @SubscribeEvent
- fun onConfigLoad(event: ConfigLoadEvent) {
- val map = GardenAPI.config?.dicerRngDrops ?: return
- for ((internalName, amount) in map) {
- val split = internalName.split(".")
- val crop = CropType.getByName(split[0])
- val rarityName = split[1]
- val rarity = DropRarity.valueOf(rarityName)
- drops[crop]!![rarity] = amount
- }
- }
+ class ItemDrop(val crop: CropType, val rarity: DropRarity, val pattern: Regex)
fun isEnabled() = GardenAPI.inGarden() && config.display
@@ -146,5 +116,23 @@ class DicerRngDropCounter {
event.move(3, "garden.dicerCounterDisplay", "garden.dicerCounters.display")
event.move(3, "garden.dicerCounterHideChat", "garden.dicerCounters.hideChat")
event.move(3, "garden.dicerCounterPos", "garden.dicerCounters.pos")
+
+ event.move(7, "#profile.garden.dicerRngDrops", "#profile.garden.dicerDropTracker.drops") { old ->
+ val items: MutableMap<CropType, MutableMap<DropRarity, Int>> = mutableMapOf()
+ val oldItems = ConfigManager.gson.fromJson<Map<String, Int>>(old, Map::class.java)
+ for ((internalName, amount) in oldItems) {
+ val split = internalName.split(".")
+ val crop = CropType.getByName(split[0])
+ val rarityName = split[1]
+ val rarity = DropRarity.valueOf(rarityName)
+ items.getOrPut(crop) { mutableMapOf() }[rarity] = amount
+ }
+
+ ConfigManager.gson.toJsonTree(items)
+ }
+ }
+
+ fun resetCommand(args: Array<String>) {
+ tracker.resetCommand(args, "shresetdicertracker")
}
-} \ No newline at end of file
+}
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 41976bf07..fb9bdfaac 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
@@ -17,6 +17,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.OSUtils
import at.hannibal2.skyhanni.utils.RenderUtils.renderRenderables
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
import at.hannibal2.skyhanni.utils.StringUtils
import at.hannibal2.skyhanni.utils.TimeUtils
import at.hannibal2.skyhanni.utils.renderables.Renderable
@@ -24,6 +25,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import kotlin.time.Duration.Companion.seconds
class FarmingWeightDisplay {
@@ -136,6 +138,8 @@ class FarmingWeightDisplay {
)
}
+ private var lastOpenWebsite = SimpleTimeMark.farPast()
+
private fun update() {
if (!GardenAPI.inGarden()) return
if (apiError) {
@@ -224,8 +228,11 @@ class FarmingWeightDisplay {
// Check that the provided string is valid
val parsed = value.toIntOrNull() ?: 0
if (parsed < 1 || parsed > goal) {
- LorenzUtils.error("[SkyHanni] Invalid Farming Weight Overtake Goal!")
- LorenzUtils.chat("§eEdit the Overtake Goal config value with a valid number [1-10000] to use this feature!")
+ LorenzUtils.error("Invalid Farming Weight Overtake Goal!")
+ LorenzUtils.chat(
+ "§eEdit the Overtake Goal config value with a valid number [1-10000] to use this feature!",
+ false
+ )
config.ETAGoalRank = goal.toString()
} else {
goal = parsed
@@ -247,15 +254,16 @@ class FarmingWeightDisplay {
listOf("§eClick here to load new data right now!"),
onClick = recalculate
)
+ val showRankGoal = leaderboardPosition == -1 || leaderboardPosition > rankGoal
var nextName =
- if (leaderboardPosition == -1 || leaderboardPosition > rankGoal) "#$rankGoal" else nextPlayer.name
+ if (showRankGoal) "#$rankGoal" else nextPlayer.name
val totalWeight = (localWeight + weight)
var weightUntilOvertake = nextPlayer.weight - totalWeight
if (weightUntilOvertake < 0) {
if (weightPerSecond > 0) {
- farmingChatMessage("§e[SkyHanni] You passed §b$nextName §ein the Farming Weight Leaderboard!")
+ farmingChatMessage("You passed §b$nextName §ein the Farming Weight Leaderboard!")
}
// Lower leaderboard position
@@ -291,11 +299,16 @@ class FarmingWeightDisplay {
} else ""
val weightFormat = LorenzUtils.formatDouble(weightUntilOvertake, 2)
- return Renderable.clickAndHover(
- "§e$weightFormat$timeFormat §7behind §b$nextName",
- listOf("§eClick to open the Farming Profile of §b$nextName.")
- ) {
- openWebsite(nextName)
+ val text = "§e$weightFormat$timeFormat §7behind §b$nextName"
+ return if (showRankGoal) {
+ Renderable.string(text)
+ } else {
+ Renderable.clickAndHover(
+ text,
+ listOf("§eClick to open the Farming Profile of §b$nextName.")
+ ) {
+ openWebsite(nextName)
+ }
}
}
@@ -378,15 +391,15 @@ class FarmingWeightDisplay {
if (diff == 0) return
if (diff > 0) {
- chatOffScreenChange("§cdropped ${StringUtils.optionalPlural(diff, "place", "places")}", oldPosition)
+ showLbChange("§cdropped ${StringUtils.optionalPlural(diff, "place", "places")}", oldPosition)
} else {
- chatOffScreenChange("§arisen ${StringUtils.optionalPlural(-diff, "place", "places")}", oldPosition)
+ showLbChange("§arisen ${StringUtils.optionalPlural(-diff, "place", "places")}", oldPosition)
}
}
- private fun chatOffScreenChange(direction: String, oldPosition: Int) {
+ private fun showLbChange(direction: String, oldPosition: Int) {
farmingChatMessage(
- "§e[SkyHanni] §7Since your last visit to the §aGarden§7, " +
+ "§7Since your last visit to the §aGarden§7, " +
"you have $direction §7on the §dFarming Leaderboard§7. " +
"§7(§e#${oldPosition.addSeparators()} §7-> §e#${leaderboardPosition.addSeparators()}§7)"
)
@@ -463,8 +476,11 @@ class FarmingWeightDisplay {
private fun error() {
apiError = true
- LorenzUtils.error("[SkyHanni] Loading the farming weight data from elitebot.dev failed!")
- LorenzUtils.chat("§eYou can re-enter the garden to try to fix the problem. If this message repeats, please report it on Discord!")
+ LorenzUtils.error(
+ "Loading the farming weight data from elitebot.dev failed!\n"
+ + "§eYou can re-enter the garden to try to fix the problem.\n" +
+ "§cIf this message repeats, please report it on Discord!",
+ )
}
private fun calculateCollectionWeight(): MutableMap<CropType, Double> {
@@ -500,12 +516,18 @@ class FarmingWeightDisplay {
fun lookUpCommand(it: Array<String>) {
val name = if (it.size == 1) it[0] else LorenzUtils.getPlayerName()
- openWebsite(name)
+ openWebsite(name, ignoreCooldown = true)
}
- private fun openWebsite(name: String?) {
+ private var lastName = ""
+
+ private fun openWebsite(name: String, ignoreCooldown: Boolean = false) {
+ if (!ignoreCooldown && lastOpenWebsite.passedSince() < 5.seconds && name == lastName) return
+ lastOpenWebsite = SimpleTimeMark.now()
+ lastName = name
+
OSUtils.openBrowser("https://elitebot.dev/@$name/")
- LorenzUtils.chat("§e[SkyHanni] Opening Farming Profile of player §b$name")
+ LorenzUtils.chat("Opening Farming Profile of player §b$name")
}
private val factorPerCrop = mutableMapOf<CropType, Double>()
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 d2948b105..76647517d 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
@@ -17,6 +17,7 @@ import at.hannibal2.skyhanni.features.garden.GardenAPI
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.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
import at.hannibal2.skyhanni.utils.LorenzUtils.round
@@ -100,6 +101,8 @@ object GardenCropMilestoneDisplay {
val addedCounter = (counter - old).toInt()
FarmingWeightDisplay.addCrop(crop, addedCounter)
update()
+ // Farming Simulator: There is a 25% chance for Mathematical Hoes and the Cultivating Enchantment to count twice.
+ // 0.8 = 1 / 1.25
crop.setCounter(
crop.getCounter() + if (GardenCropSpeed.finneganPerkActive()) {
(addedCounter.toDouble() * 0.8).toInt()
@@ -108,8 +111,7 @@ object GardenCropMilestoneDisplay {
}
cultivatingData[crop] = counter
} catch (e: Throwable) {
- LorenzUtils.error("[SkyHanni] Error in OwnInventoryItemUpdateEvent")
- e.printStackTrace()
+ ErrorManager.logError(e, "Updating crop counter by reading farming tool nbt data.")
}
}
@@ -163,15 +165,13 @@ object GardenCropMilestoneDisplay {
Collections.singletonList("§e$haveFormat§8/§e$needFormat")
}
- val farmingFortune = FarmingFortuneDisplay.getCurrentFarmingFortune(true)
+ val farmingFortune = FarmingFortuneDisplay.getCurrentFarmingFortune()
val speed = GardenCropSpeed.averageBlocksPerSecond
- val farmingFortuneSpeed = (farmingFortune * crop.baseDrops * speed / 100).round(1).toInt()
+ val farmingFortuneSpeed = ((100.0 + farmingFortune) * crop.baseDrops * speed / 100).round(1).toInt()
if (farmingFortuneSpeed > 0) {
crop.setSpeed(farmingFortuneSpeed)
- if (crop.isMaxed()) {
- lineMap[3] = listOf("§7In §bMaxed")
- } else {
+ if (!crop.isMaxed()) {
val missing = need - have
val missingTimeSeconds = missing / farmingFortuneSpeed
val millis = missingTimeSeconds * 1000
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 a9a2066bd..0f10ed883 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
@@ -22,8 +22,8 @@ import kotlin.concurrent.fixedRateTimer
object GardenCropSpeed {
private val config get() = SkyHanniMod.feature.garden
- private val cropsPerSecond: MutableMap<CropType, Int>? get() = GardenAPI.config?.cropsPerSecond
- private val latestBlocksPerSecond: MutableMap<CropType, Double>? get() = GardenAPI.config?.latestBlocksPerSecond
+ private val cropsPerSecond: MutableMap<CropType, Int>? get() = GardenAPI.storage?.cropsPerSecond
+ private val latestBlocksPerSecond: MutableMap<CropType, Double>? get() = GardenAPI.storage?.latestBlocksPerSecond
var lastBrokenCrop: CropType? = null
var lastBrokenTime = 0L
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 6ad3ce910..3384af51e 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
@@ -15,50 +15,51 @@ object GardenStartLocation {
fun setLocationCommand() {
if (!GardenAPI.inGarden()) {
- LorenzUtils.chat("§c[SkyHanni] This Command only works in the garden!")
+ LorenzUtils.userError("This Command only works in the garden!")
return
}
if (!SkyHanniMod.feature.garden.cropStartLocation.enabled) {
LorenzUtils.clickableChat(
- "§c[SkyHanni] This feature is disabled. Enable it in the config: §e/sh crop start location",
- "sh crop start location"
+ "This feature is disabled. Enable it in the config: §e/sh crop start location",
+ "sh crop start location",
+ prefixColor = "§c"
)
return
}
- val startLocations = GardenAPI.config?.cropStartLocations
+ val startLocations = GardenAPI.storage?.cropStartLocations
if (startLocations == null) {
- LorenzUtils.chat("§c[SkyHanni] The config is not yet loaded, retry in a second.")
+ LorenzUtils.userError("The config is not yet loaded, retry in a second.")
return
}
val crop = GardenAPI.getCurrentlyFarmedCrop()
if (crop == null) {
- LorenzUtils.chat("§c[SkyHanni] Hold a crop specific farming tool in the hand!")
+ LorenzUtils.userError("Hold a crop specific farming tool in the hand!")
return
}
startLocations[crop] = LocationUtils.playerLocation()
- LorenzUtils.chat("§e[SkyHanni] You changed your Crop Start Location for ${crop.cropName}!")
+ LorenzUtils.chat("You changed your Crop Start Location for ${crop.cropName}!")
}
@SubscribeEvent
fun onBlockClick(event: CropClickEvent) {
if (!isEnabled()) return
- val startLocations = GardenAPI.config?.cropStartLocations ?: return
+ val startLocations = GardenAPI.storage?.cropStartLocations ?: return
val crop = GardenAPI.getCurrentlyFarmedCrop() ?: return
if (crop != GardenCropSpeed.lastBrokenCrop) return
if (!startLocations.contains(crop)) {
startLocations[crop] = LocationUtils.playerLocation()
- LorenzUtils.chat("§e[SkyHanni] Auto updated your Crop Start Location for ${crop.cropName}")
+ LorenzUtils.chat("Auto updated your Crop Start Location for ${crop.cropName}")
}
}
@SubscribeEvent
fun onRenderWorld(event: LorenzRenderWorldEvent) {
if (!isEnabled()) return
- val startLocations = GardenAPI.config?.cropStartLocations ?: return
+ val startLocations = GardenAPI.storage?.cropStartLocations ?: return
val crop = GardenAPI.cropInHand ?: return
val location = startLocations[crop]?.add(-0.5, 0.5, -0.5) ?: return
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 2f65a9906..d923efb6d 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
@@ -9,14 +9,13 @@ import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
-import at.hannibal2.skyhanni.utils.NEUItems
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
class WildStrawberryDyeNotification {
- var lastCloseTime = 0L
+ private var lastCloseTime = 0L
val item by lazy { "DYE_WILD_STRAWBERRY".asInternalName() }
@@ -30,20 +29,21 @@ class WildStrawberryDyeNotification {
if (!GardenAPI.inGarden()) return
if (!SkyHanniMod.feature.garden.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 = event.itemStack.getInternalName()
+ val internalName = itemStack.getInternalName()
if (internalName == item) {
- val name = event.itemStack.name!!
+ val name = itemStack.name!!
LorenzUtils.sendTitle(name, 5.seconds)
- LorenzUtils.chat("§e[SkyHanni] You found a $name§e!")
+ LorenzUtils.chat("You found a $name§e!")
SoundUtils.playBeepSound()
- ItemBlink.setBlink(NEUItems.getItemStackOrNull("DYE_WILD_STRAWBERRY"), 5_000)
+ ItemBlink.setBlink(itemStack, 5_000)
}
}
}
-} \ No newline at end of file
+}
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 46936a7bb..e7bdce1db 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
@@ -6,8 +6,9 @@ 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.utils.ItemUtils.getLore
+import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getFungiCutterMode
import at.hannibal2.skyhanni.utils.SoundUtils
import net.minecraft.item.ItemStack
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
@@ -23,7 +24,7 @@ class WrongFungiCutterWarning {
if (message == "§eFungi Cutter Mode: §r§cRed Mushrooms") {
mode = FungiMode.RED
}
- if (message == "§eFungi Cutter Mode: §r§cBrown Mushrooms") {
+ if (message == "§eFungi Cutter Mode: §r§6Brown Mushrooms") {
mode = FungiMode.BROWN
}
}
@@ -55,27 +56,26 @@ class WrongFungiCutterWarning {
@SubscribeEvent
fun onGardenToolChange(event: GardenToolChangeEvent) {
if (event.crop == CropType.MUSHROOM) {
- readItem(event.toolItem!!)
+ readItem(event.toolItem ?: error("Tool item is null"))
} else {
mode = FungiMode.UNKNOWN
}
}
private fun readItem(item: ItemStack) {
- for (line in item.getLore()) {
- if (line == "§eMode: §cRed Mushrooms") {
- mode = FungiMode.RED
- }
-
- if (line == "§eMode: §cBrown Mushrooms") {
- mode = FungiMode.BROWN
- }
- }
+ val rawMode = item.getFungiCutterMode() ?: error("Tool without fungi cutter mode: '${item.name}'")
+ mode = FungiMode.getOrNull(rawMode)
}
enum class FungiMode {
RED,
BROWN,
- UNKNOWN
+ UNKNOWN,
+ ;
+
+ companion object {
+ fun getOrNull(mode: String) =
+ entries.firstOrNull { it.name == mode } ?: error("Unknown fungi mode: '$mode'")
+ }
}
-} \ No newline at end of file
+}
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 3a4844f2d..483cce5a5 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
@@ -23,8 +23,8 @@ import kotlin.math.round
import kotlin.time.Duration.Companion.days
class CaptureFarmingGear {
- private val farmingItems get() = GardenAPI.config?.fortune?.farmingItems
- private val outdatedItems get() = GardenAPI.config?.fortune?.outdatedItems
+ private val farmingItems get() = GardenAPI.storage?.fortune?.farmingItems
+ private val outdatedItems get() = GardenAPI.storage?.fortune?.outdatedItems
// TODO USE SH-REPO
private val farmingLevelUpPattern = "SKILL LEVEL UP Farming .*➜(?<level>.*)".toPattern()
@@ -43,7 +43,7 @@ class CaptureFarmingGear {
"FERMENTO", "SQUASH", "CROPIE", "MELON", "FARM",
"RANCHERS", "FARMER", "RABBIT"
)
- private val farmingItems get() = GardenAPI.config?.fortune?.farmingItems
+ private val farmingItems get() = GardenAPI.storage?.fortune?.farmingItems
fun captureFarmingGear() {
val farmingItems = farmingItems ?: return
@@ -74,15 +74,21 @@ class CaptureFarmingGear {
}
for (line in TabListData.getTabList()) {
strengthPattern.matchMatcher(line) {
- GardenAPI.config?.fortune?.farmingStrength = group("strength").toInt()
+ GardenAPI.storage?.fortune?.farmingStrength = group("strength").toInt()
}
}
}
fun reverseCarrotFortune() {
- val hidden = GardenAPI.config?.fortune ?: return
- hidden.carrotFortune = !hidden.carrotFortune
- LorenzUtils.chat("§2Toggled exportable carrot fortune to: ${hidden.carrotFortune}")
+ val storage = GardenAPI.storage?.fortune ?: return
+ storage.carrotFortune = !storage.carrotFortune
+ LorenzUtils.chat("Toggled exportable carrot fortune to: ${storage.carrotFortune}")
+ }
+
+ fun reversePumpkinFortune() {
+ val storage = GardenAPI.storage?.fortune ?: return
+ storage.pumpkinFortune = !storage.pumpkinFortune
+ LorenzUtils.chat("Toggled expired pumpkin fortune to: ${storage.pumpkinFortune}")
}
}
@@ -94,7 +100,7 @@ class CaptureFarmingGear {
@SubscribeEvent
fun onInventoryOpen(event: InventoryFullyOpenedEvent) {
if (!LorenzUtils.inSkyBlock) return
- val hidden = GardenAPI.config?.fortune ?: return
+ val storage = GardenAPI.storage?.fortune ?: return
val farmingItems = farmingItems ?: return
val outdatedItems = outdatedItems ?: return
if (event.inventoryName == "Your Equipment and Stats") {
@@ -111,7 +117,7 @@ class CaptureFarmingGear {
val enchantments = slot.getEnchantments() ?: emptyMap()
val greenThumbLvl = (enchantments["green_thumb"] ?: continue)
val visitors = FarmingFortuneDisplay.greenThumbFortune / (greenThumbLvl * 0.05)
- GardenAPI.config?.uniqueVisitors = round(visitors).toInt()
+ GardenAPI.storage?.uniqueVisitors = round(visitors).toInt()
}
}
}
@@ -164,7 +170,7 @@ class CaptureFarmingGear {
if (event.inventoryName.contains("Your Skills")) {
for ((_, item) in event.inventoryItems) {
if (item.displayName.contains("Farming ")) {
- hidden.farmingLevel = item.displayName.split(" ").last().romanToDecimalIfNeeded()
+ storage.farmingLevel = item.displayName.split(" ").last().romanToDecimalIfNeeded()
}
}
}
@@ -188,7 +194,7 @@ class CaptureFarmingGear {
plotsUnlocked -= 1
}
}
- hidden.plotsUnlocked = plotsUnlocked
+ storage.plotsUnlocked = plotsUnlocked
}
if (event.inventoryName.contains("Anita")) {
var level = -1
@@ -203,9 +209,9 @@ class CaptureFarmingGear {
}
}
if (level == -1) {
- hidden.anitaUpgrade = 15
+ storage.anitaUpgrade = 15
} else {
- hidden.anitaUpgrade = level
+ storage.anitaUpgrade = level
}
}
}
@@ -213,17 +219,17 @@ class CaptureFarmingGear {
@SubscribeEvent
fun onChat(event: LorenzChatEvent) {
if (!LorenzUtils.inSkyBlock) return
- val hidden = GardenAPI.config?.fortune ?: return
+ val storage = GardenAPI.storage?.fortune ?: return
val outdatedItems = outdatedItems ?: return
val msg = event.message.removeColor().trim()
fortuneUpgradePattern.matchMatcher(msg) {
ProfileStorageData.playerSpecific?.gardenCommunityUpgrade = group("level").romanToDecimal()
}
farmingLevelUpPattern.matchMatcher(msg) {
- hidden.farmingLevel = group("level").romanToDecimalIfNeeded()
+ storage.farmingLevel = group("level").romanToDecimalIfNeeded()
}
anitaBuffPattern.matchMatcher(msg) {
- hidden.anitaUpgrade = group("level").toInt() / 4
+ storage.anitaUpgrade = group("level").toInt() / 4
}
lotusUpgradePattern.matchMatcher(msg) {
val piece = group("piece").uppercase()
@@ -242,10 +248,13 @@ class CaptureFarmingGear {
}
}
cakePattern.matchMatcher(msg) {
- hidden.cakeExpiring = System.currentTimeMillis() + 2.days.inWholeMilliseconds
+ storage.cakeExpiring = System.currentTimeMillis() + 2.days.inWholeMilliseconds
}
if (msg == "CARROTS EXPORTATION COMPLETE!") {
- hidden.carrotFortune = true
+ storage.carrotFortune = true
+ }
+ if (msg == "PUMPKINS EXPORTATION COMPLETE!") {
+ storage.pumpkinFortune = true
}
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFGuideGUI.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFGuideGUI.kt
index b7e103be1..d93dfd36a 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFGuideGUI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFGuideGUI.kt
@@ -6,6 +6,7 @@ import at.hannibal2.skyhanni.features.garden.fortuneguide.pages.CropPage
import at.hannibal2.skyhanni.features.garden.fortuneguide.pages.OverviewPage
import at.hannibal2.skyhanni.features.garden.fortuneguide.pages.UpgradePage
import at.hannibal2.skyhanni.utils.GuiRenderUtils
+import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.SoundUtils
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.GuiScreen
@@ -46,7 +47,7 @@ open class FFGuideGUI : GuiScreen() {
fun isInGui() = Minecraft.getMinecraft().currentScreen is FFGuideGUI
fun FarmingItems.getItem(): ItemStack {
- val fortune = GardenAPI.config?.fortune ?: return getFallbackItem(this)
+ val fortune = GardenAPI.storage?.fortune ?: return getFallbackItem(this)
val farmingItems = fortune.farmingItems
farmingItems[this]?.let { return it }
@@ -56,8 +57,14 @@ open class FFGuideGUI : GuiScreen() {
return fallbackItem
}
- fun getFallbackItem(item: FarmingItems): ItemStack =
- ItemStack(Blocks.barrier).setStackDisplayName("§cNo saved ${item.name.lowercase().replace("_", " ")}")
+ private val fallbackItems = mutableMapOf<FarmingItems, ItemStack>()
+
+ fun getFallbackItem(item: FarmingItems) = fallbackItems.getOrPut(item) {
+ val name = "§cNo saved ${item.name.lowercase().replace("_", " ")}"
+ ItemStack(Blocks.barrier).setStackDisplayName(name)
+ }
+
+ fun isFallbackItem(item: ItemStack) = item.name!!.startsWith("§cNo saved ")
}
init {
@@ -294,7 +301,8 @@ open class FFGuideGUI : GuiScreen() {
x = guiLeft - 28
y = guiTop + 15
if (isMouseIn(x, y, 28, 25) &&
- selectedPage != FortuneGuidePage.CROP && selectedPage != FortuneGuidePage.OVERVIEW) {
+ selectedPage != FortuneGuidePage.CROP && selectedPage != FortuneGuidePage.OVERVIEW
+ ) {
SoundUtils.playClickSound()
selectedPage = if (currentCrop == null) {
FortuneGuidePage.OVERVIEW
@@ -467,4 +475,4 @@ open class FFGuideGUI : GuiScreen() {
abstract class FFGuidePage {
abstract fun drawPage(mouseX: Int, mouseY: Int, partialTicks: Float)
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFStats.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFStats.kt
index 7e9c9399a..051e6ae3a 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFStats.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFStats.kt
@@ -15,7 +15,7 @@ import net.minecraft.item.ItemStack
import kotlin.math.floor
object FFStats {
- private val toolHasBountiful get() = GardenAPI.config?.toolWithBountiful
+ private val toolHasBountiful get() = GardenAPI.storage?.toolWithBountiful
private val mathCrops =
listOf(CropType.WHEAT, CropType.CARROT, CropType.POTATO, CropType.SUGAR_CANE, CropType.NETHER_WART)
@@ -51,7 +51,7 @@ object FFStats {
val cropPage = mutableMapOf<FortuneStats, Pair<Double, Double>>()
fun loadFFData() {
- cakeExpireTime = GardenAPI.config?.fortune?.cakeExpiring ?: -1L
+ cakeExpireTime = GardenAPI.storage?.fortune?.cakeExpiring ?: -1L
getEquipmentFFData(FarmingItems.NECKLACE.getItem(), necklaceFF)
getEquipmentFFData(FarmingItems.CLOAK.getItem(), cloakFF)
@@ -111,7 +111,7 @@ object FFStats {
}
in dicerCrops -> {
- cropPage[FortuneStats.SUNDER] = Pair(FarmingFortuneDisplay.getSunderFortune(tool), 62.5)
+ cropPage[FortuneStats.SUNDER] = Pair(FarmingFortuneDisplay.getSunderFortune(tool), 75.0)
if (toolHasBountiful?.get(crop) == true) {
cropPage[FortuneStats.REFORGE] = Pair(FarmingFortuneDisplay.reforgeFortune, 10.0)
} else {
@@ -131,7 +131,7 @@ object FFStats {
CropType.COCOA_BEANS -> {
cropPage[FortuneStats.BASE_TOOL] = Pair(FarmingFortuneDisplay.getToolFortune(tool), 20.0)
- cropPage[FortuneStats.SUNDER] = Pair(FarmingFortuneDisplay.getSunderFortune(tool), 62.5)
+ cropPage[FortuneStats.SUNDER] = Pair(FarmingFortuneDisplay.getSunderFortune(tool), 75.0)
if (toolHasBountiful?.get(crop) == true) {
cropPage[FortuneStats.REFORGE] = Pair(FarmingFortuneDisplay.reforgeFortune, 7.0)
} else {
@@ -151,10 +151,15 @@ object FFStats {
else -> {}
}
if (crop == CropType.CARROT) {
- val hidden = GardenAPI.config?.fortune ?: return
- val carrotFortune = if (hidden.carrotFortune) 12.0 else 0.0
+ val storage = GardenAPI.storage?.fortune ?: return
+ val carrotFortune = if (storage.carrotFortune) 12.0 else 0.0
cropPage[FortuneStats.EXPORTED_CARROT] = Pair(carrotFortune, 12.0)
}
+ if (crop == CropType.PUMPKIN) {
+ val storage = GardenAPI.storage?.fortune ?: return
+ val pumpkinFortune = if (storage.pumpkinFortune) 12.0 else 0.0
+ cropPage[FortuneStats.EXPIRED_PUMPKIN] = Pair(pumpkinFortune, 12.0)
+ }
cropPage[FortuneStats.CROP_TOTAL] = Pair(
cropPage.toList().sumOf { it.second.first },
@@ -194,13 +199,13 @@ object FFStats {
}
private fun getGenericFF(out: MutableMap<FFTypes, Double>) {
- val savedStats = GardenAPI.config?.fortune ?: return
+ val storage = GardenAPI.storage?.fortune ?: return
out[FFTypes.TOTAL] = 0.0
out[FFTypes.BASE_FF] = 100.0
- out[FFTypes.FARMING_LVL] = savedStats.farmingLevel.toDouble() * 4
+ out[FFTypes.FARMING_LVL] = storage.farmingLevel.toDouble() * 4
out[FFTypes.COMMUNITY_SHOP] = (ProfileStorageData.playerSpecific?.gardenCommunityUpgrade ?: -1).toDouble() * 4
- out[FFTypes.PLOTS] = savedStats.plotsUnlocked.toDouble() * 3
- out[FFTypes.ANITA] = savedStats.anitaUpgrade.toDouble() * 4
+ out[FFTypes.PLOTS] = storage.plotsUnlocked.toDouble() * 3
+ out[FFTypes.ANITA] = storage.anitaUpgrade.toDouble() * 4
if (cakeExpireTime - System.currentTimeMillis() > 0 || cakeExpireTime == -1L) {
out[FFTypes.CAKE] = 5.0
} else {
@@ -240,7 +245,7 @@ object FFStats {
private fun getPetFF(pet: ItemStack): Double {
val petLevel = pet.getPetLevel()
- val strength = (GardenAPI.config?.fortune?.farmingStrength)
+ val strength = (GardenAPI.storage?.fortune?.farmingStrength)
if (strength != null) {
val rawInternalName = pet.getInternalName()
return when {
@@ -257,4 +262,4 @@ object FFStats {
}
return 0.0
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneStats.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneStats.kt
index 77c275973..af02f7577 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneStats.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneStats.kt
@@ -4,7 +4,7 @@ enum class FortuneStats(val label: String, val tooltip: String) {
BASE(
"§2Universal Farming Fortune",
"§7§2Farming fortune in that is\n§2applied to every crop\n§eNot the same as tab FF\n" +
- "§eSee on the grass block page"
+ "§eSee on the grass block page"
),
CROP_TOTAL("§6Crop Farming Fortune", "§7§2Farming fortune for this crop"),
ACCESSORY("§2Talisman Bonus", "§7§2Fortune from your talisman\n§2You get 10☘ per talisman tier"),
@@ -19,5 +19,14 @@ enum class FortuneStats(val label: String, val tooltip: String) {
CULTIVATING("§2Cultivating Enchantment", "§7§2Fortune for each enchantment level\n§2You get 2☘ per level"),
TURBO("§2Turbo-Crop Enchantment", "§7§2Fortune for each enchantment level\n§2You get 5☘ per level"),
DEDICATION("§2Dedication Enchantment", "§7§2Fortune for each enchantment level\n§2and crop milestone"),
- EXPORTED_CARROT("§2Exported Carrot", "§7§2Gain 12☘ from exporting Carrots in the Rift!\n§eRun /shcarrot to toggle the stat")
-} \ No newline at end of file
+ EXPORTED_CARROT(
+ "§2Exported Carrot",
+ "§7§2Gain 12☘ from exporting Carrots in the Rift!\n" +
+ "§eRun /shcarrot to toggle the stat"
+ ),
+ EXPIRED_PUMPKIN(
+ "§2Expired Pumpkin",
+ "§7§2Gain 12☘ from letting Pumpkins expire!\n" +
+ "§eRun /shpumpkin to toggle the stat"
+ )
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneUpgrades.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneUpgrades.kt
index 7e79235ff..c7ff7275a 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneUpgrades.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneUpgrades.kt
@@ -31,22 +31,22 @@ object FortuneUpgrades {
val cropSpecificUpgrades = mutableListOf<FortuneUpgrade>()
fun generateGenericUpgrades() {
- val hidden = GardenAPI.config?.fortune ?: return
+ val storage = GardenAPI.storage?.fortune ?: return
genericUpgrades.clear()
- if (hidden.plotsUnlocked != -1 && hidden.plotsUnlocked != 24) {
+ if (storage.plotsUnlocked != -1 && storage.plotsUnlocked != 24) {
genericUpgrades.add(
FortuneUpgrade(
- "§7Unlock your ${(hidden.plotsUnlocked + 1).addSuffix()} §7plot",
- null, "COMPOST", compostNeeded[hidden.plotsUnlocked], 3.0
+ "§7Unlock your ${(storage.plotsUnlocked + 1).addSuffix()} §7plot",
+ null, "COMPOST", compostNeeded[storage.plotsUnlocked], 3.0
)
)
}
- if (hidden.anitaUpgrade != -1 && hidden.anitaUpgrade != 15) {
+ if (storage.anitaUpgrade != -1 && storage.anitaUpgrade != 15) {
genericUpgrades.add(
FortuneUpgrade(
- "§7Upgrade Anita bonus to level ${hidden.anitaUpgrade + 1}",
- null, "JACOBS_TICKET", anitaTicketsNeeded[hidden.anitaUpgrade], 4.0
+ "§7Upgrade Anita bonus to level ${storage.anitaUpgrade + 1}",
+ null, "JACOBS_TICKET", anitaTicketsNeeded[storage.anitaUpgrade], 4.0
)
)
}
@@ -91,7 +91,7 @@ object FortuneUpgrades {
}
private fun getEquipmentUpgrades() {
- val visitors = GardenAPI.config?.uniqueVisitors?.toDouble() ?: 0.0
+ val visitors = GardenAPI.storage?.uniqueVisitors?.toDouble() ?: 0.0
for (piece in equipment) {
val item = piece.getItem()
//todo tell them to buy the missing item
@@ -126,6 +126,8 @@ object FortuneUpgrades {
val item = piece.getItem()
//todo skip if it doesnt exist -> tell them to buy it later
+ if (FFGuideGUI.isFallbackItem(item)) return
+
recombobulateItem(item, genericUpgrades)
when (item.getReforgeName()) {
"mossy" -> {}
@@ -168,13 +170,20 @@ object FortuneUpgrades {
val farmingForDummiesCount = tool.getFarmingForDummiesCount() ?: 0
if (crop in axeCrops) {
val sunderLvl = enchantments["sunder"] ?: 0
- if (sunderLvl != 5) {
+ if (sunderLvl < 5) {
cropSpecificUpgrades.add(
FortuneUpgrade(
"§7Enchant your ${tool.displayName} §7with Sunder ${sunderLvl + 1}",
10, "SUNDER;1", getNeededBooks(sunderLvl), 12.5
)
)
+ } else if (sunderLvl == 5) {
+ cropSpecificUpgrades.add(
+ FortuneUpgrade(
+ "§7Enchant your ${tool.displayName} §7with Sunder 6",
+ 10, "SUNDER;6", 1, 12.5
+ )
+ )
}
} else {
val harvestingLvl = enchantments["harvesting"] ?: 0
@@ -276,14 +285,12 @@ object FortuneUpgrades {
)
}
- private fun getNeededBooks(currentLvl: Int): Int {
- return when (currentLvl) {
- 0 -> 1
- 1 -> 1
- 2 -> 2
- 3 -> 4
- else -> 8
- }
+ private fun getNeededBooks(currentLvl: Int) = when (currentLvl) {
+ 0 -> 1
+ 1 -> 1
+ 2 -> 2
+ 3 -> 4
+ else -> 8
}
private val cropUpgrades = listOf(5, 10, 20, 50, 100, 500, 1000, 5000, 10000)
@@ -296,4 +303,4 @@ object FortuneUpgrades {
// no support for people with 5% discount
private val anitaTicketsNeeded = listOf(0, 50, 50, 100, 100, 150, 150, 200, 200, 250, 300, 350, 400, 450, 1000)
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/CropPage.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/CropPage.kt
index cb20cc86a..d9558cd2f 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/CropPage.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/CropPage.kt
@@ -1,4 +1,5 @@
package at.hannibal2.skyhanni.features.garden.fortuneguide.pages
+
import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI
import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI.Companion.getItem
import at.hannibal2.skyhanni.features.garden.fortuneguide.FFStats
@@ -7,12 +8,19 @@ import at.hannibal2.skyhanni.features.garden.fortuneguide.FortuneStats
import at.hannibal2.skyhanni.utils.GuiRenderUtils
import at.hannibal2.skyhanni.utils.StringUtils.firstLetterUppercase
-class CropPage: FFGuideGUI.FFGuidePage() {
+class CropPage : FFGuideGUI.FFGuidePage() {
override fun drawPage(mouseX: Int, mouseY: Int, partialTicks: Float) {
for (item in FarmingItems.entries) {
if (item.name == FFGuideGUI.currentCrop?.name) {
- GuiRenderUtils.renderItemAndTip(FFGuideGUI.tooltipToDisplay, item.getItem(), FFGuideGUI.guiLeft + 172, FFGuideGUI.guiTop + 60, mouseX, mouseY)
+ GuiRenderUtils.renderItemAndTip(
+ FFGuideGUI.tooltipToDisplay,
+ item.getItem(),
+ FFGuideGUI.guiLeft + 172,
+ FFGuideGUI.guiTop + 60,
+ mouseX,
+ mouseY
+ )
}
}
@@ -21,9 +29,12 @@ class CropPage: FFGuideGUI.FFGuidePage() {
var i = 0
FFStats.cropPage.forEach { (key, value) ->
if (key == FortuneStats.CROP_TOTAL) {
- val newLine = key.label.replace("Crop", FFGuideGUI.currentCrop?.name?.replace("_", " ")?.firstLetterUppercase()!!)
- GuiRenderUtils.drawFarmingBar(newLine, key.tooltip, value.first, value.second, FFGuideGUI.guiLeft + 135,
- FFGuideGUI.guiTop + 5, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay)
+ val newLine =
+ key.label.replace("Crop", FFGuideGUI.currentCrop?.name?.replace("_", " ")?.firstLetterUppercase()!!)
+ GuiRenderUtils.drawFarmingBar(
+ newLine, key.tooltip, value.first, value.second, FFGuideGUI.guiLeft + 135,
+ FFGuideGUI.guiTop + 5, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ )
} else {
if (i % 2 == 0) {
x = FFGuideGUI.guiLeft + 15
@@ -31,10 +42,12 @@ class CropPage: FFGuideGUI.FFGuidePage() {
} else {
x = FFGuideGUI.guiLeft + 255
}
- i ++
- GuiRenderUtils.drawFarmingBar(key.label, key.tooltip, value.first, value.second, x, y,
- 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay)
+ i++
+ GuiRenderUtils.drawFarmingBar(
+ key.label, key.tooltip, value.first, value.second, x, y,
+ 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ )
}
}
}
-} \ No newline at end of file
+}
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 4e06ee1cb..2fe623c74 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
@@ -1,5 +1,6 @@
package at.hannibal2.skyhanni.features.garden.fortuneguide.pages
+import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI
import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI.Companion.currentArmor
import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI.Companion.currentEquipment
@@ -10,37 +11,49 @@ import at.hannibal2.skyhanni.features.garden.fortuneguide.FarmingItems
import at.hannibal2.skyhanni.utils.GuiRenderUtils
import at.hannibal2.skyhanni.utils.TimeUtils
-class OverviewPage: FFGuideGUI.FFGuidePage() {
+class OverviewPage : FFGuideGUI.FFGuidePage() {
private var equipmentFF = mutableMapOf<FFTypes, Double>()
private var armorFF = mutableMapOf<FFTypes, Double>()
override fun drawPage(mouseX: Int, mouseY: Int, partialTicks: Float) {
val timeUntilCakes = TimeUtils.formatDuration(FFStats.cakeExpireTime - System.currentTimeMillis())
- GuiRenderUtils.drawFarmingBar("§6Universal Farming Fortune",
+ GuiRenderUtils.drawFarmingBar(
+ "§6Universal Farming Fortune",
"§7§2Farming fortune in that is\n§2applied to every crop\n§eNot the same as tab FF\n" +
- "§eSee on the grass block page", FFStats.totalBaseFF[FFTypes.TOTAL] ?: 0, 1277,
- FFGuideGUI.guiLeft + 15, FFGuideGUI.guiTop + 5, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay)
+ "§eSee on the grass block page", FFStats.totalBaseFF[FFTypes.TOTAL] ?: 0, 1277,
+ FFGuideGUI.guiLeft + 15, FFGuideGUI.guiTop + 5, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ )
var line = if (FFStats.baseFF[FFTypes.ANITA]!! < 0.0) "§cAnita buff not saved\n§eVisit Anita to set it!"
else "§7§2Fortune for levelling your Anita extra crops\n§2You get 4☘ per buff level"
- GuiRenderUtils.drawFarmingBar("§2Anita Buff", line, FFStats.baseFF[FFTypes.ANITA] ?: 0.0, 60, FFGuideGUI.guiLeft + 15,
- FFGuideGUI.guiTop + 30, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay)
+ GuiRenderUtils.drawFarmingBar(
+ "§2Anita Buff", line, FFStats.baseFF[FFTypes.ANITA] ?: 0.0, 60, FFGuideGUI.guiLeft + 15,
+ FFGuideGUI.guiTop + 30, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ )
line = if (FFStats.baseFF[FFTypes.FARMING_LVL]!! < 0.0) "§cFarming level not saved\n§eOpen /skills to set it!"
else "§7§2Fortune for levelling your farming skill\n§2You get 4☘ per farming level"
- GuiRenderUtils.drawFarmingBar("§2Farming Level", line, FFStats.baseFF[FFTypes.FARMING_LVL] ?: 0.0, 240, FFGuideGUI.guiLeft + 15,
- FFGuideGUI.guiTop + 55, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay)
+ GuiRenderUtils.drawFarmingBar(
+ "§2Farming Level", line, FFStats.baseFF[FFTypes.FARMING_LVL] ?: 0.0, 240, FFGuideGUI.guiLeft + 15,
+ FFGuideGUI.guiTop + 55, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ )
- line = if (FFStats.baseFF[FFTypes.COMMUNITY_SHOP]!! < 0.0) "§cCommunity upgrade level not saved\n§eVisit Elizabeth to set it!"
- else "§7§2Fortune for community shop upgrades\n§2You get 4☘ per upgrade tier"
- GuiRenderUtils.drawFarmingBar("§2Community upgrades", line, FFStats.baseFF[FFTypes.COMMUNITY_SHOP] ?: 0.0,
- 40, FFGuideGUI.guiLeft + 15, FFGuideGUI.guiTop + 80, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay)
+ line =
+ if (FFStats.baseFF[FFTypes.COMMUNITY_SHOP]!! < 0.0) "§cCommunity upgrade level not saved\n§eVisit Elizabeth to set it!"
+ else "§7§2Fortune for community shop upgrades\n§2You get 4☘ per upgrade tier"
+ GuiRenderUtils.drawFarmingBar(
+ "§2Community upgrades", line, FFStats.baseFF[FFTypes.COMMUNITY_SHOP] ?: 0.0,
+ 40, FFGuideGUI.guiLeft + 15, FFGuideGUI.guiTop + 80, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ )
- line = if (FFStats.baseFF[FFTypes.PLOTS]!! < 0.0) "§cUnlocked plot count not saved\n§eOpen /desk and view your plots to set it!"
- else "§7§2Fortune for unlocking garden plots\n§2You get 3☘ per plot unlocked"
- GuiRenderUtils.drawFarmingBar("§2Garden Plots", line, FFStats.baseFF[FFTypes.PLOTS] ?: 0.0, 72, FFGuideGUI.guiLeft + 15,
- FFGuideGUI.guiTop + 105, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay)
+ line =
+ if (FFStats.baseFF[FFTypes.PLOTS]!! < 0.0) "§cUnlocked plot count not saved\n§eOpen /desk and view your plots to set it!"
+ else "§7§2Fortune for unlocking garden plots\n§2You get 3☘ per plot unlocked"
+ GuiRenderUtils.drawFarmingBar(
+ "§2Garden Plots", line, FFStats.baseFF[FFTypes.PLOTS] ?: 0.0, 72, FFGuideGUI.guiLeft + 15,
+ FFGuideGUI.guiTop + 105, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ )
line = when (FFStats.cakeExpireTime) {
-1L -> "§eYou have not eaten a cake since\n§edownloading this update, assuming the\n§ebuff is active!"
@@ -49,8 +62,10 @@ class OverviewPage: FFGuideGUI.FFGuidePage() {
if (FFStats.cakeExpireTime - System.currentTimeMillis() < 0 && FFStats.cakeExpireTime != -1L) {
line = "§cYour cake buff has run out\nGo eat some cake!"
}
- GuiRenderUtils.drawFarmingBar("§2Cake Buff", line, FFStats.baseFF[FFTypes.CAKE] ?: 0.0, 5, FFGuideGUI.guiLeft + 15,
- FFGuideGUI.guiTop + 130, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay)
+ GuiRenderUtils.drawFarmingBar(
+ "§2Cake Buff", line, FFStats.baseFF[FFTypes.CAKE] ?: 0.0, 5, FFGuideGUI.guiLeft + 15,
+ FFGuideGUI.guiTop + 130, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ )
val armorItem = when (currentArmor) {
1 -> FarmingItems.HELMET
@@ -86,8 +101,10 @@ class OverviewPage: FFGuideGUI.FFGuidePage() {
else -> 78.75
}
}
- GuiRenderUtils.drawFarmingBar("§2Total $word Fortune", line, armorFF[FFTypes.TOTAL] ?: 0, value,
- FFGuideGUI.guiLeft + 135, FFGuideGUI.guiTop + 30, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay)
+ GuiRenderUtils.drawFarmingBar(
+ "§2Total $word Fortune", line, armorFF[FFTypes.TOTAL] ?: 0, value,
+ FFGuideGUI.guiLeft + 135, FFGuideGUI.guiTop + 30, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ )
line = if (currentArmor == 0) "§7§2The base fortune from your armor\n§2Select a piece for more info"
else "§7§2Base fortune from your\n${armorItem.getItem().displayName}"
@@ -98,9 +115,11 @@ class OverviewPage: FFGuideGUI.FFGuidePage() {
3 -> 35
else -> if (FFStats.usingSpeedBoots) 60 else 30
}
- GuiRenderUtils.drawFarmingBar("§2Base $word Fortune", line, armorFF[FFTypes.BASE] ?: 0,
+ GuiRenderUtils.drawFarmingBar(
+ "§2Base $word Fortune", line, armorFF[FFTypes.BASE] ?: 0,
value, FFGuideGUI.guiLeft + 135,
- FFGuideGUI.guiTop + 55, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay)
+ FFGuideGUI.guiTop + 55, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ )
line = if (currentArmor == 0) "§7§2The fortune from your armor's ability\n§2Select a piece for more info"
else "§7§2Ability fortune from your\n${armorItem.getItem().displayName}"
@@ -117,9 +136,11 @@ class OverviewPage: FFGuideGUI.FFGuidePage() {
}
}
- GuiRenderUtils.drawFarmingBar("§2$word Ability", line, armorFF[FFTypes.ABILITY] ?: 0,
+ GuiRenderUtils.drawFarmingBar(
+ "§2$word Ability", line, armorFF[FFTypes.ABILITY] ?: 0,
value, FFGuideGUI.guiLeft + 135,
- FFGuideGUI.guiTop + 80, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay)
+ FFGuideGUI.guiTop + 80, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ )
line = if (currentArmor == 0) "§7§2The fortune from your armor's reforge\n§2Select a piece for more info"
else "§7§2Total fortune from your\n${armorItem.getItem().displayName}"
@@ -128,9 +149,11 @@ class OverviewPage: FFGuideGUI.FFGuidePage() {
} else if (currentArmor == 4) {
if (FFStats.usingSpeedBoots) 25 else 30
} else 30
- GuiRenderUtils.drawFarmingBar("§2$word Reforge", line, armorFF[FFTypes.REFORGE] ?: 0,
+ GuiRenderUtils.drawFarmingBar(
+ "§2$word Reforge", line, armorFF[FFTypes.REFORGE] ?: 0,
value, FFGuideGUI.guiLeft + 135,
- FFGuideGUI.guiTop + 105, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay)
+ FFGuideGUI.guiTop + 105, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ )
var currentPet = FFStats.rabbitFF
var petMaxFF = 60
@@ -139,20 +162,25 @@ class OverviewPage: FFGuideGUI.FFGuidePage() {
currentPet = FFStats.elephantFF
petMaxFF = 210
}
+
FarmingItems.MOOSHROOM_COW -> {
currentPet = FFStats.mooshroomFF
petMaxFF = 217
}
+
FarmingItems.BEE -> {
currentPet = FFStats.beeFF
petMaxFF = 90
}
+
else -> {}
}
- GuiRenderUtils.drawFarmingBar("§2Total Pet Fortune", "§7§2The total fortune from your pet and its item",
+ GuiRenderUtils.drawFarmingBar(
+ "§2Total Pet Fortune", "§7§2The total fortune from your pet and its item",
currentPet[FFTypes.TOTAL] ?: 0, petMaxFF, FFGuideGUI.guiLeft + 105,
- FFGuideGUI.guiTop + 155, 70, mouseX, mouseY, FFGuideGUI.tooltipToDisplay)
+ FFGuideGUI.guiTop + 155, 70, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ )
line = when (FFStats.currentPetItem) {
"GREEN_BANDANA" -> "§7§2The fortune from your pet's item\n§2Grants 4☘ per garden level"
@@ -160,8 +188,10 @@ class OverviewPage: FFGuideGUI.FFGuidePage() {
"MINOS_RELIC" -> "§cGreen Bandana is better for fortune than minos relic!"
else -> "No fortune boosting pet item"
}
- GuiRenderUtils.drawFarmingBar("§2Pet Item", line, currentPet[FFTypes.PET_ITEM] ?: 0, 60, FFGuideGUI.guiLeft + 185,
- FFGuideGUI.guiTop + 155, 70, mouseX, mouseY, FFGuideGUI.tooltipToDisplay)
+ GuiRenderUtils.drawFarmingBar(
+ "§2Pet Item", line, currentPet[FFTypes.PET_ITEM] ?: 0, 60, FFGuideGUI.guiLeft + 185,
+ FFGuideGUI.guiTop + 155, 70, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ )
word = if (currentEquipment == 0) "Equipment" else "Piece"
@@ -182,32 +212,46 @@ class OverviewPage: FFGuideGUI.FFGuidePage() {
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,
+ GuiRenderUtils.drawFarmingBar(
+ "§2Total $word Fortune", line, equipmentFF[FFTypes.TOTAL] ?: 0,
if (currentEquipment == 0) 218 else 54.5,
- FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 30, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay)
+ FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 30, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ )
line = if (currentEquipment == 0) "§7§2The base fortune from all your equipment\n§2Select a piece for more info"
else "§7§2Total base fortune from your\n${equipmentItem.getItem().displayName}"
- GuiRenderUtils.drawFarmingBar("§2$word Base Fortune", line, equipmentFF[FFTypes.BASE] ?: 0,
+ GuiRenderUtils.drawFarmingBar(
+ "§2$word Base Fortune", line, equipmentFF[FFTypes.BASE] ?: 0,
if (currentEquipment == 0) 20 else 5,
- FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 55, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay)
+ FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 55, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ )
- line = if (currentEquipment == 0) "§7§2The fortune from all of your equipment's abilities\n§2Select a piece for more info"
- else "§7§2Total ability fortune from your\n${equipmentItem.getItem().displayName}"
- GuiRenderUtils.drawFarmingBar("§2$word Ability", line, equipmentFF[FFTypes.ABILITY] ?: 0,
+ line =
+ if (currentEquipment == 0) "§7§2The fortune from all of your equipment's abilities\n§2Select a piece for more info"
+ 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,
- FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 80, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay)
+ FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 80, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ )
- line = if (currentEquipment == 0) "§7§2The fortune from all of your equipment's reforges\n§2Select a piece for more info"
- else "§7§2Total reforge fortune from your\n${equipmentItem.getItem().displayName}"
- GuiRenderUtils.drawFarmingBar("§2$word Reforge", line, equipmentFF[FFTypes.REFORGE] ?: 0,
+ line =
+ if (currentEquipment == 0) "§7§2The fortune from all of your equipment's reforges\n§2Select a piece for more info"
+ 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,
- FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 105, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay)
+ FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 105, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ )
- 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}"
- GuiRenderUtils.drawFarmingBar("§2$word Enchantment", line, equipmentFF[FFTypes.GREEN_THUMB] ?: 0,
- if (currentEquipment == 0) 78 else 19.5,
- FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 130, 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}"
+ GuiRenderUtils.drawFarmingBar(
+ "§2$word Enchantment", line, equipmentFF[FFTypes.GREEN_THUMB] ?: 0,
+ if (currentEquipment == 0) maxGreenThumbFortune * 4 else maxGreenThumbFortune,
+ FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 130, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ )
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/UpgradePage.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/UpgradePage.kt
index 6076efd21..dd6664bc7 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/UpgradePage.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/UpgradePage.kt
@@ -11,7 +11,7 @@ import net.minecraft.client.renderer.GlStateManager
import net.minecraft.util.MathHelper
import java.text.DecimalFormat
-class UpgradePage: FFGuideGUI.FFGuidePage() {
+class UpgradePage : FFGuideGUI.FFGuidePage() {
private var pageScroll = 0
private var scrollVelocity = 0.0
private val maxNoInputFrames = 100
@@ -21,14 +21,36 @@ class UpgradePage: FFGuideGUI.FFGuidePage() {
val adjustedY = FFGuideGUI.guiTop + 20 + pageScroll
val inverseScale = 1 / 0.75f
+ // TODO fix duplicate drawString lines, add guiLeft, guiTop and inverseScale
GlStateManager.scale(0.75f, 0.75f, 1f)
- GuiRenderUtils.drawString("Upgrade", (FFGuideGUI.guiLeft + 45) * inverseScale, (FFGuideGUI.guiTop + 5) * inverseScale)
- GuiRenderUtils.drawString("Item", (FFGuideGUI.guiLeft + 190) * inverseScale, (FFGuideGUI.guiTop + 5) * inverseScale)
- GuiRenderUtils.drawString("FF increase", (FFGuideGUI.guiLeft + 240) * inverseScale, (FFGuideGUI.guiTop + 5) * inverseScale)
- GuiRenderUtils.drawString("Cost/FF", (FFGuideGUI.guiLeft + 290) * inverseScale, (FFGuideGUI.guiTop + 5) * inverseScale)
- GuiRenderUtils.drawString("Total", (FFGuideGUI.guiLeft + 330) * inverseScale, (FFGuideGUI.guiTop + 5) * inverseScale)
+ GuiRenderUtils.drawString(
+ "Upgrade",
+ (FFGuideGUI.guiLeft + 45) * inverseScale,
+ (FFGuideGUI.guiTop + 5) * inverseScale
+ )
+ GuiRenderUtils.drawString(
+ "Item",
+ (FFGuideGUI.guiLeft + 190) * inverseScale,
+ (FFGuideGUI.guiTop + 5) * inverseScale
+ )
+ GuiRenderUtils.drawString(
+ "FF increase",
+ (FFGuideGUI.guiLeft + 240) * inverseScale,
+ (FFGuideGUI.guiTop + 5) * inverseScale
+ )
+ GuiRenderUtils.drawString(
+ "Cost/FF",
+ (FFGuideGUI.guiLeft + 290) * inverseScale,
+ (FFGuideGUI.guiTop + 5) * inverseScale
+ )
+ GuiRenderUtils.drawString(
+ "Total",
+ (FFGuideGUI.guiLeft + 330) * inverseScale,
+ (FFGuideGUI.guiTop + 5) * inverseScale
+ )
- val upgradeList = if (FFGuideGUI.currentCrop == null) FortuneUpgrades.genericUpgrades else FortuneUpgrades.cropSpecificUpgrades
+ val upgradeList =
+ if (FFGuideGUI.currentCrop == null) FortuneUpgrades.genericUpgrades else FortuneUpgrades.cropSpecificUpgrades
listLength = upgradeList.size
for ((index, upgrade) in upgradeList.withIndex()) {
if (adjustedY + 25 * index < FFGuideGUI.guiTop + 20) continue
@@ -42,13 +64,40 @@ class UpgradePage: FFGuideGUI.FFGuidePage() {
if (upgrade.itemQuantity != 1) {
formattedUpgrade = "$formattedUpgrade §fx${upgrade.itemQuantity}"
}
- GuiRenderUtils.drawTwoLineString(upgrade.description, (FFGuideGUI.guiLeft + 15) * inverseScale, (adjustedY + 25 * index) * inverseScale)
- GuiRenderUtils.renderItemAndTip(FFGuideGUI.tooltipToDisplay, upgradeItem, (FFGuideGUI.guiLeft + 155) * inverseScale, (adjustedY + 25 * index - 5) * inverseScale,
- mouseX * inverseScale, mouseY * inverseScale, 0x00FFFFFF)
- GuiRenderUtils.drawString(formattedUpgrade, (FFGuideGUI.guiLeft + 180) * inverseScale, (adjustedY + 25 * index) * inverseScale)
- GuiRenderUtils.drawString("§a${DecimalFormat("0.##").format(upgrade.fortuneIncrease)}", (FFGuideGUI.guiLeft + 270) * inverseScale, (adjustedY + 25 * index) * inverseScale)
- GuiRenderUtils.drawString("§6" + upgrade.costPerFF?.let { NumberUtil.format(it) }, (FFGuideGUI.guiLeft + 300) * inverseScale, (adjustedY + 25 * index) * inverseScale)
- GuiRenderUtils.drawString(("§6" + upgrade.cost?.let { NumberUtil.format(it) }), (FFGuideGUI.guiLeft + 335) * inverseScale, (adjustedY + 25 * index) * inverseScale)
+ GuiRenderUtils.drawTwoLineString(
+ upgrade.description,
+ (FFGuideGUI.guiLeft + 15) * inverseScale,
+ (adjustedY + 25 * index) * inverseScale
+ )
+ GuiRenderUtils.renderItemAndTip(
+ FFGuideGUI.tooltipToDisplay,
+ upgradeItem,
+ (FFGuideGUI.guiLeft + 155) * inverseScale,
+ (adjustedY + 25 * index - 5) * inverseScale,
+ mouseX * inverseScale,
+ mouseY * inverseScale,
+ 0x00FFFFFF
+ )
+ GuiRenderUtils.drawString(
+ formattedUpgrade,
+ (FFGuideGUI.guiLeft + 180) * inverseScale,
+ (adjustedY + 25 * index) * inverseScale
+ )
+ GuiRenderUtils.drawString(
+ "§a${DecimalFormat("0.##").format(upgrade.fortuneIncrease)}",
+ (FFGuideGUI.guiLeft + 270) * inverseScale,
+ (adjustedY + 25 * index) * inverseScale
+ )
+ GuiRenderUtils.drawString(
+ "§6" + upgrade.costPerFF?.let { NumberUtil.format(it) },
+ (FFGuideGUI.guiLeft + 300) * inverseScale,
+ (adjustedY + 25 * index) * inverseScale
+ )
+ GuiRenderUtils.drawString(
+ ("§6" + upgrade.cost?.let { NumberUtil.format(it) }),
+ (FFGuideGUI.guiLeft + 335) * inverseScale,
+ (adjustedY + 25 * index) * inverseScale
+ )
}
GlStateManager.scale(inverseScale, inverseScale, 1f)
scrollScreen()
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 904ec9bb4..2af928a30 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
@@ -31,7 +31,7 @@ class AnitaExtraFarmingFortune {
if (!stack.displayName.contains("Extra Farming Fortune")) return
- val anitaUpgrade = GardenAPI.config?.fortune?.anitaUpgrade ?: return
+ val anitaUpgrade = GardenAPI.storage?.fortune?.anitaUpgrade ?: return
var contributionFactor = 1.0
val baseAmount = levelPrice[anitaUpgrade + 1]?.jacob_tickets ?: return
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 495696a3e..cb236050b 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
@@ -58,6 +58,8 @@ class GardenCropMilestoneInventory {
val itemStack = event.itemStack ?: return
val crop = GardenCropMilestones.getCropTypeByLore(itemStack) ?: return
+ val tier = GardenCropMilestones.getTierForCropCount(crop.getCounter(), crop)
+ if (tier > 20) return
val maxTier = GardenCropMilestones.getMaxTier()
val maxCounter = GardenCropMilestones.getCropsForTier(maxTier, crop)
@@ -81,4 +83,4 @@ class GardenCropMilestoneInventory {
event.move(3, "garden.numberAverageCropMilestone", "garden.number.averageCropMilestone")
event.move(3, "garden.cropMilestoneTotalProgress", "garden.tooltipTweak.cropMilestoneTotalProgress")
}
-} \ No newline at end of file
+}
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 5ad1f9769..64d176bcd 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
@@ -35,17 +35,18 @@ class GardenNextPlotPrice {
}
if (next) {
- ItemUtils.readItemAmount(line)?.let {
+ val readItemAmount = ItemUtils.readItemAmount(line)
+ readItemAmount?.let {
val (itemName, amount) = it
val lowestBin = NEUItems.getPrice(NEUItems.getRawInternalName(itemName))
val price = lowestBin * amount
val format = NumberUtil.format(price)
list[i] = list[i] + " §7(§6$format§7)"
} ?: {
- LorenzUtils.error("§c[SkyHanni] Could not read item '$line'")
+ LorenzUtils.error("Could not read item '$line'")
}
break
}
}
}
-} \ No newline at end of file
+}
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 11318553c..cdd5d4358 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
@@ -8,7 +7,7 @@ import at.hannibal2.skyhanni.events.LorenzToolTipEvent
import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
-import at.hannibal2.skyhanni.utils.LorenzUtils.chat
+import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.NEUItems.getItemStack
import io.github.moulberry.notenoughupdates.events.ReplaceItemEvent
import io.github.moulberry.notenoughupdates.events.SlotClickEvent
@@ -22,7 +21,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
object GardenPlotIcon {
private val config get() = SkyHanniMod.feature.garden.plotIcon
- private val plotList get() = GardenAPI.config?.plotIcon?.plotList
+ private val plotList get() = GardenAPI.storage?.plotIcon?.plotList
private var inInventory = false
private var copyStack: ItemStack? = null
private var editMode = 0 // 0 = off, 1 = on, 2 = reset
@@ -30,7 +29,8 @@ object GardenPlotIcon {
private var originalStack = mutableMapOf<Int, ItemStack>()
private var cachedStack = mutableMapOf<Int, ItemStack>()
private val editStack = ItemStack(Items.wooden_axe)
- private val whitelistedSlot = listOf(2, 3, 4, 5, 6, 11, 12, 13, 14, 15, 20, 21, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42)
+ private val whitelistedSlot =
+ listOf(2, 3, 4, 5, 6, 11, 12, 13, 14, 15, 20, 21, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42)
var hardReset = false
@@ -104,9 +104,9 @@ object GardenPlotIcon {
if (editMode != 0) {
if (event.slotId in 54..89) {
event.isCanceled = true
- if (event.slot.stack == null) return
- copyStack = event.slot.stack
- chat("§6§lClick an item in the desk menu to replace it with that item!")
+ copyStack = event.slot.stack ?: return
+ // TODO different format, not bold or show not in chat at all.
+ LorenzUtils.chat("§6§lClick an item in the desk menu to replace it with that item!")
return
}
if (event.slotId != 53) {
@@ -152,4 +152,4 @@ object GardenPlotIcon {
}
}
}
-} \ No newline at end of file
+}
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 ffd2dfa51..a70ca7f96 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
@@ -73,7 +73,7 @@ class SkyMartCopperPrice {
config.copperPricePos.renderStringsAndItems(
display,
extraSpace = 5,
- itemScale = 1.7,
+ itemScale = config.itemScale,
posLabel = "SkyMart Copper Price"
)
}
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 8096b747c..9fa465a47 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
@@ -16,7 +16,8 @@ object GardenVisitorColorNames {
visitorColours.clear()
visitorItems.clear()
for ((visitor, visitorData) in data.visitors) {
- visitorColours[visitor] = getColor(visitorData.rarity)
+ val rarity = visitorData.new_rarity ?: visitorData.rarity
+ visitorColours[visitor] = rarity.color.getChatColor()
visitorItems[visitor] = visitorData.need_items
}
}
@@ -28,13 +29,4 @@ object GardenVisitorColorNames {
val color = visitorColours[cleanName] ?: return name
return color + cleanName
}
-
- private fun getColor(rarity: String) = when (rarity) {
- "uncommon" -> "§a"
- "rare" -> "§9"
- "legendary" -> "§6"
- "special" -> "§c"
-
- else -> throw RuntimeException("Unknown rarity for '$rarity'")
- }
}
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 c4b7fc0a3..6ddabd2f5 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
@@ -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.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
import at.hannibal2.skyhanni.utils.LorenzUtils.addOrPut
import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy
@@ -29,7 +30,6 @@ object GardenVisitorDropStatistics {
private var acceptedVisitors = 0
var deniedVisitors = 0
private var totalVisitors = 0
- private var visitorRarities = mutableListOf<Long>()
var coinsSpent = 0L
var lastAccept = 0L
@@ -72,68 +72,73 @@ object GardenVisitorDropStatistics {
fun onChat(event: LorenzChatEvent) {
if (!GardenAPI.onBarnPlot) return
if (!ProfileStorageData.loaded) return
- if (lastAccept - System.currentTimeMillis() <= 0 && lastAccept - System.currentTimeMillis() > -1000) {
- val message = event.message.removeColor().trim()
- val hidden = GardenAPI.config?.visitorDrops ?: return
-
- copperPattern.matchMatcher(message) {
- val amount = group("amount").formatNumber().toInt()
- hidden.copper += amount
- saveAndUpdate()
- }
- farmingExpPattern.matchMatcher(message) {
- val amount = group("amount").formatNumber()
- hidden.farmingExp += amount
- saveAndUpdate()
- }
- gardenExpPattern.matchMatcher(message) {
- val amount = group("amount").formatNumber().toInt()
- if (amount > 80) return // some of the low visitor milestones will get through but will be minimal
- hidden.gardenExp += amount
- saveAndUpdate()
- }
- bitsPattern.matchMatcher(message) {
- val amount = group("amount").formatNumber().toInt()
- hidden.bits += amount
- saveAndUpdate()
- }
- mithrilPowderPattern.matchMatcher(message) {
- val amount = group("amount").formatNumber().toInt()
- hidden.mithrilPowder += amount
- saveAndUpdate()
- }
- gemstonePowderPattern.matchMatcher(message) {
- val amount = group("amount").formatNumber().toInt()
- hidden.gemstonePowder += amount
- saveAndUpdate()
- }
- acceptPattern.matchMatcher(message) {
- setRarities(group("rarity"))
- saveAndUpdate()
- }
+ if (lastAccept - System.currentTimeMillis() > 0 || lastAccept - System.currentTimeMillis() <= -1000) return
+
+ val message = event.message.removeColor().trim()
+ val storage = GardenAPI.storage?.visitorDrops ?: return
+
+ copperPattern.matchMatcher(message) {
+ val amount = group("amount").formatNumber().toInt()
+ storage.copper += amount
+ saveAndUpdate()
+ }
+ farmingExpPattern.matchMatcher(message) {
+ val amount = group("amount").formatNumber()
+ storage.farmingExp += amount
+ saveAndUpdate()
+ }
+ gardenExpPattern.matchMatcher(message) {
+ val amount = group("amount").formatNumber().toInt()
+ if (amount > 80) return // some of the low visitor milestones will get through but will be minimal
+ storage.gardenExp += amount
+ saveAndUpdate()
+ }
+ bitsPattern.matchMatcher(message) {
+ val amount = group("amount").formatNumber().toInt()
+ storage.bits += amount
+ saveAndUpdate()
+ }
+ mithrilPowderPattern.matchMatcher(message) {
+ val amount = group("amount").formatNumber().toInt()
+ storage.mithrilPowder += amount
+ saveAndUpdate()
+ }
+ gemstonePowderPattern.matchMatcher(message) {
+ val amount = group("amount").formatNumber().toInt()
+ storage.gemstonePowder += amount
+ saveAndUpdate()
+ }
+ acceptPattern.matchMatcher(message) {
+ setRarities(group("rarity"))
+ saveAndUpdate()
}
}
private fun setRarities(rarity: String) {
acceptedVisitors += 1
- val currentRarity = VisitorRarity.valueOf(rarity)
+ val currentRarity = LorenzUtils.enumValueOf<VisitorRarity>(rarity)
+ val visitorRarities = GardenAPI.storage?.visitorDrops?.visitorRarities ?: return
+ fixRaritiesSize(visitorRarities)
val temp = visitorRarities[currentRarity.ordinal] + 1
visitorRarities[currentRarity.ordinal] = temp
saveAndUpdate()
}
- private fun drawDisplay(hidden: Storage.ProfileSpecific.GardenStorage.VisitorDrops) = buildList<List<Any>> {
+ 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()) {
addAsSingletonList(
"§a${visitorRarities[0].addSeparators()}§f-" +
- "§9${visitorRarities[1].addSeparators()}§f-" +
- "§6${visitorRarities[2].addSeparators()}§f-" +
- "§c${visitorRarities[3].addSeparators()}"
+ "§9${visitorRarities[1].addSeparators()}§f-" +
+ "§6${visitorRarities[2].addSeparators()}§f-" +
+ "§d${visitorRarities[3].addSeparators()}§f-" +
+ "§c${visitorRarities[4].addSeparators()}"
)
} else {
addAsSingletonList("§c?")
@@ -149,9 +154,9 @@ object GardenVisitorDropStatistics {
//5
addAsSingletonList("")
//6
- addAsSingletonList(format(hidden.copper, "Copper", "§c", ""))
+ addAsSingletonList(format(storage.copper, "Copper", "§c", ""))
//7
- addAsSingletonList(format(hidden.farmingExp, "Farming EXP", "§3", "§7"))
+ addAsSingletonList(format(storage.farmingExp, "Farming EXP", "§3", "§7"))
//8
addAsSingletonList(format(coinsSpent, "Coins Spent", "§6", ""))
@@ -170,13 +175,22 @@ object GardenVisitorDropStatistics {
//17
addAsSingletonList("")
//18
- addAsSingletonList(format(hidden.gardenExp, "Garden EXP", "§2", "§7"))
+ addAsSingletonList(format(storage.gardenExp, "Garden EXP", "§2", "§7"))
//19
- addAsSingletonList(format(hidden.bits, "Bits", "§b", "§b"))
+ addAsSingletonList(format(storage.bits, "Bits", "§b", "§b"))
//20
- addAsSingletonList(format(hidden.mithrilPowder, "Mithril Powder", "§2", "§2"))
+ addAsSingletonList(format(storage.mithrilPowder, "Mithril Powder", "§2", "§2"))
//21
- addAsSingletonList(format(hidden.gemstonePowder, "Gemstone Powder", "§d", "§d"))
+ addAsSingletonList(format(storage.gemstonePowder, "Gemstone Powder", "§d", "§d"))
+ }
+
+ // Adding the mythic rarity between legendary and special, if missing
+ private fun fixRaritiesSize(list: MutableList<Long>) {
+ if (list.size == 4) {
+ val special = list.last()
+ list[3] = 0L
+ list.add(special)
+ }
}
fun format(amount: Number, name: String, color: String, amountColor: String = color) =
@@ -193,31 +207,31 @@ object GardenVisitorDropStatistics {
fun saveAndUpdate() {
if (!GardenAPI.inGarden()) return
- val hidden = GardenAPI.config?.visitorDrops ?: return
- hidden.acceptedVisitors = acceptedVisitors
- hidden.deniedVisitors = deniedVisitors
+ val storage = GardenAPI.storage?.visitorDrops ?: return
+ storage.acceptedVisitors = acceptedVisitors
+ storage.deniedVisitors = deniedVisitors
totalVisitors = acceptedVisitors + deniedVisitors
- hidden.visitorRarities = visitorRarities
- hidden.coinsSpent = coinsSpent
- hidden.rewardsCount = rewardsCount
- display = formatDisplay(drawDisplay(hidden))
+ storage.coinsSpent = coinsSpent
+ storage.rewardsCount = rewardsCount
+ display = formatDisplay(drawDisplay(storage))
}
@SubscribeEvent
fun onConfigLoad(event: ConfigLoadEvent) {
- val hidden = GardenAPI.config?.visitorDrops ?: return
- if (hidden.visitorRarities.size == 0) {
- hidden.visitorRarities.add(0)
- hidden.visitorRarities.add(0)
- hidden.visitorRarities.add(0)
- hidden.visitorRarities.add(0)
+ val storage = GardenAPI.storage?.visitorDrops ?: return
+ val visitorRarities = storage.visitorRarities
+ if (visitorRarities.size == 0) {
+ visitorRarities.add(0)
+ visitorRarities.add(0)
+ visitorRarities.add(0)
+ visitorRarities.add(0)
+ visitorRarities.add(0)
}
- acceptedVisitors = hidden.acceptedVisitors
- deniedVisitors = hidden.deniedVisitors
+ acceptedVisitors = storage.acceptedVisitors
+ deniedVisitors = storage.deniedVisitors
totalVisitors = acceptedVisitors + deniedVisitors
- visitorRarities = hidden.visitorRarities
- coinsSpent = hidden.coinsSpent
- rewardsCount = hidden.rewardsCount
+ coinsSpent = storage.coinsSpent
+ rewardsCount = storage.rewardsCount
saveAndUpdate()
}
@@ -232,15 +246,17 @@ object GardenVisitorDropStatistics {
@SubscribeEvent
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
- event.move(3, "garden.visitorDropsStatistics.enabled", "garden.visitors.dropsStatistics.enabled")
- event.move(3, "garden.visitorDropsStatistics.textFormat", "garden.visitors.dropsStatistics.textFormat")
- event.move(3, "garden.visitorDropsStatistics.displayNumbersFirst", "garden.visitors.dropsStatistics.displayNumbersFirst")
- event.move(3, "garden.visitorDropsStatistics.displayIcons", "garden.visitors.dropsStatistics.displayIcons")
- event.move(3, "garden.visitorDropsStatistics.onlyOnBarn", "garden.visitors.dropsStatistics.onlyOnBarn")
- event.move(3, "garden.visitorDropsStatistics.visitorDropPos", "garden.visitors.dropsStatistics.pos")
+ val originalPrefix = "garden.visitorDropsStatistics."
+ val newPrefix = "garden.visitors.dropsStatistics."
+ event.move(3, "${originalPrefix}enabled", "${newPrefix}enabled")
+ event.move(3, "${originalPrefix}textFormat", "${newPrefix}textFormat")
+ event.move(3, "${originalPrefix}displayNumbersFirst", "${newPrefix}displayNumbersFirst")
+ event.move(3, "${originalPrefix}displayIcons", "${newPrefix}displayIcons")
+ event.move(3, "${originalPrefix}onlyOnBarn", "${newPrefix}onlyOnBarn")
+ event.move(3, "${originalPrefix}visitorDropPos", "${newPrefix}pos")
}
}
enum class VisitorRarity {
- UNCOMMON, RARE, LEGENDARY, SPECIAL,
-} \ No newline at end of file
+ UNCOMMON, RARE, LEGENDARY, MYTHIC, SPECIAL,
+}
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 f77a27107..4995decc8 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
@@ -19,6 +19,7 @@ import at.hannibal2.skyhanni.features.garden.CropType.Companion.getByNameOrNull
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.EntityUtils
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemBlink
@@ -31,6 +32,7 @@ import at.hannibal2.skyhanni.utils.ItemUtils.name
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.isInIsland
import at.hannibal2.skyhanni.utils.NEUInternalName
import at.hannibal2.skyhanni.utils.NEUItems
import at.hannibal2.skyhanni.utils.NEUItems.getItemStack
@@ -79,13 +81,20 @@ class GardenVisitorFeatures {
val visitor = event.visitor
val offerItem = visitor.offer!!.offerItem
- for (line in offerItem.getLore()) {
+ val lore = offerItem.getLore()
+ for (line in lore) {
if (line == "§7Items Required:") continue
if (line.isEmpty()) break
val pair = ItemUtils.readItemAmount(line)
if (pair == null) {
- LorenzUtils.error("§c[SkyHanni] Could not read item '$line'")
+ ErrorManager.logErrorStateWithData(
+ "Could not read items required in Visitor Inventory", "ItemUtils.readItemAmount returns null",
+ "line" to line,
+ "offerItem" to offerItem,
+ "lore" to lore,
+ "visitor" to visitor
+ )
continue
}
val (itemName, amount) = pair
@@ -96,7 +105,7 @@ class GardenVisitorFeatures {
readToolTip(visitor, offerItem)
if (visitor.status == VisitorAPI.VisitorStatus.NEW) {
- val alreadyReady = offerItem.getLore().any { it == "§eClick to give!" } == true
+ val alreadyReady = offerItem.getLore().any { it == "§eClick to give!" }
if (alreadyReady) {
VisitorAPI.changeStatus(visitor, VisitorAPI.VisitorStatus.READY, "inSacks")
visitor.inSacks = true
@@ -112,10 +121,15 @@ class GardenVisitorFeatures {
display = drawDisplay()
}
- private fun drawDisplay(): List<List<Any>> {
- val newDisplay = mutableListOf<List<Any>>()
- if (!config.needs.display) return newDisplay
+ private fun drawDisplay() = buildList {
+ if (!config.needs.display) return@buildList
+ val (requiredItems, newVisitors) = prepareDrawingData()
+ drawRequiredItems(requiredItems)
+ drawVisitors(newVisitors, requiredItems)
+ }
+
+ private fun prepareDrawingData(): Pair<MutableMap<NEUInternalName, Int>, MutableList<String>> {
val requiredItems = mutableMapOf<NEUInternalName, Int>()
val newVisitors = mutableListOf<String>()
for ((visitorName, visitor) in VisitorAPI.getVisitorsMap()) {
@@ -130,9 +144,13 @@ class GardenVisitorFeatures {
requiredItems[internalName] = old + amount
}
}
+ return requiredItems to newVisitors
+ }
+
+ private fun MutableList<List<Any>>.drawRequiredItems(requiredItems: MutableMap<NEUInternalName, Int>) {
if (requiredItems.isNotEmpty()) {
var totalPrice = 0.0
- newDisplay.addAsSingletonList("§7Visitor items needed:")
+ addAsSingletonList("§7Visitor items needed:")
for ((internalName, amount) in requiredItems) {
val name = internalName.getItemName()
val itemStack = internalName.getItemStack()
@@ -156,20 +174,26 @@ class GardenVisitorFeatures {
list.add(" §7(§6$format§7)")
}
- newDisplay.add(list)
+ add(list)
}
if (totalPrice > 0) {
val format = NumberUtil.format(totalPrice)
- newDisplay[0] = listOf("§7Visitor items needed: §7(§6$format§7)")
+ this[0] = listOf("§7Visitor items needed: §7(§6$format§7)")
}
}
+ }
+
+ private fun MutableList<List<Any>>.drawVisitors(
+ newVisitors: MutableList<String>,
+ requiredItems: MutableMap<NEUInternalName, Int>
+ ) {
if (newVisitors.isNotEmpty()) {
if (requiredItems.isNotEmpty()) {
- newDisplay.addAsSingletonList("")
+ addAsSingletonList("")
}
val amount = newVisitors.size
val visitorLabel = if (amount == 1) "visitor" else "visitors"
- newDisplay.addAsSingletonList("§e$amount §7new $visitorLabel:")
+ addAsSingletonList("§e$amount §7new $visitorLabel:")
for (visitor in newVisitors) {
val displayName = GardenVisitorColorNames.getColoredName(visitor)
@@ -200,11 +224,9 @@ class GardenVisitorFeatures {
}
}
- newDisplay.add(list)
+ add(list)
}
}
-
- return newDisplay
}
@SubscribeEvent
@@ -256,7 +278,6 @@ class GardenVisitorFeatures {
if (visitor.lastLore.isEmpty()) {
readToolTip(visitor, event.itemStack)
- LorenzUtils.chat("§e[SkyHanni] Reloaded the visitor data of that inventory, this should not happen.")
}
toolTip.addAll(visitor.lastLore)
@@ -297,7 +318,7 @@ class GardenVisitorFeatures {
if (wasEmpty) {
visitor.hasReward()?.let { reward ->
if (config.rewardWarning.notifyInChat) {
- LorenzUtils.chat("§e[SkyHanni] Found Visitor Reward ${reward.displayName}§e!")
+ LorenzUtils.chat("Found Visitor Reward ${reward.displayName}§e!")
}
}
}
@@ -387,7 +408,7 @@ class GardenVisitorFeatures {
}
if (config.notificationChat) {
val displayName = GardenVisitorColorNames.getColoredName(name)
- LorenzUtils.chat("§e[SkyHanni] $displayName §eis visiting your garden!")
+ LorenzUtils.chat("$displayName §eis visiting your garden!")
}
if (System.currentTimeMillis() > LorenzUtils.lastWorldSwitch + 2_000) {
@@ -439,7 +460,8 @@ class GardenVisitorFeatures {
if (!visitor.inSacks) {
val status = visitor.status
if (status == VisitorAPI.VisitorStatus.WAITING || status == VisitorAPI.VisitorStatus.READY) {
- val newStatus = if (hasItemsInInventory(visitor)) VisitorAPI.VisitorStatus.READY else VisitorAPI.VisitorStatus.WAITING
+ val newStatus =
+ if (hasItemsInInventory(visitor)) VisitorAPI.VisitorStatus.READY else VisitorAPI.VisitorStatus.WAITING
VisitorAPI.changeStatus(visitor, newStatus, "hasItemsInInventory")
}
}
@@ -532,7 +554,7 @@ class GardenVisitorFeatures {
}
private fun showGui(): Boolean {
- if (config.needs.inBazaarAlley && LorenzUtils.skyBlockIsland == IslandType.HUB && LorenzUtils.skyBlockArea == "Bazaar Alley") {
+ if (config.needs.inBazaarAlley && IslandType.HUB.isInIsland() && LorenzUtils.skyBlockArea == "Bazaar Alley") {
return true
}
@@ -571,7 +593,11 @@ class GardenVisitorFeatures {
event.move(3, "garden.visitorExperiencePrice", "garden.visitors.inventory.experiencePrice")
event.move(3, "garden.visitorRewardWarning.notifyInChat", "garden.visitors.rewardWarning.notifyInChat")
event.move(3, "garden.visitorRewardWarning.showOverName", "garden.visitors.rewardWarning.showOverName")
- event.move(3, "garden.visitorRewardWarning.preventRefusing", "garden.visitors.rewardWarning.preventRefusing")
+ event.move(
+ 3,
+ "garden.visitorRewardWarning.preventRefusing",
+ "garden.visitors.rewardWarning.preventRefusing"
+ )
event.move(3, "garden.visitorRewardWarning.bypassKey", "garden.visitors.rewardWarning.bypassKey")
event.move(3, "garden.visitorRewardWarning.drops", "garden.visitors.rewardWarning.drops")
event.move(3, "garden.visitorNotificationChat", "garden.visitors.notificationChat")
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 d397d6a86..1bd9290e2 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
@@ -11,32 +11,40 @@ import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.test.command.ErrorManager
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.RenderUtils.renderString
+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 at.hannibal2.skyhanni.utils.TimeUtils.format
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.concurrent.fixedRateTimer
-import kotlin.math.roundToLong
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.milliseconds
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 patternNextVisitor = " Next Visitor: §r§b(?<time>.*)".toPattern()
- private val patternVisitors = "§b§lVisitors: §r§f\\((?<amount>\\d)\\)".toPattern()
+ private val pattern = "§b§lVisitors: §r§f\\((?<time>.*)\\)".toPattern()
private var render = ""
- private var lastMillis = 0L
- private var sixthVisitorArrivalTime: Long = 0
+ private var lastMillis = 0.seconds
+ private var sixthVisitorArrivalTime = SimpleTimeMark.farPast()
private var visitorJustArrived = false
private var sixthVisitorReady = false
+ private var lastTimerValue = ""
+ private var lastTimerUpdate = SimpleTimeMark.farPast()
//TODO nea?
// private val visitorInterval by dynamic(GardenAPI::config, Storage.ProfileSpecific.GardenStorage::visitorInterval)
- private var visitorInterval: Long?
- get() = GardenAPI.config?.visitorInterval
+ private var visitorInterval: Duration?
+ get() = GardenAPI.storage?.visitorInterval?.toDuration(DurationUnit.MILLISECONDS)
set(value) {
value?.let {
- GardenAPI.config?.visitorInterval = it
+ GardenAPI.storage?.visitorInterval = it.inWholeMilliseconds
}
}
@@ -66,8 +74,8 @@ class GardenVisitorTimer {
@SubscribeEvent
fun onPreProfileSwitch(event: PreProfileSwitchEvent) {
render = ""
- lastMillis = 0
- sixthVisitorArrivalTime = 0
+ lastMillis = 0.seconds
+ sixthVisitorArrivalTime = SimpleTimeMark.farPast()
visitorJustArrived = false
sixthVisitorReady = false
}
@@ -75,31 +83,34 @@ class GardenVisitorTimer {
private fun updateVisitorDisplay() {
if (!isEnabled()) return
- var visitorsAmount = 0
+ var visitorsAmount = VisitorAPI.visitorsInTabList(TabListData.getTabList()).size
var visitorInterval = visitorInterval ?: return
var millis = visitorInterval
var queueFull = false
for (line in TabListData.getTabList()) {
- val matcher = patternNextVisitor.matcher(line)
- if (matcher.matches()) {
- val rawTime = matcher.group("time")
- millis = TimeUtils.getMillis(rawTime)
- } else if (line == " Next Visitor: §r§c§lQueue Full!") {
+ if (line == "§b§lVisitors: §r§f(§r§c§lQueue Full!§r§f)") {
queueFull = true
- } else if (line == " Next Visitor: §r§cNot Unlocked!") {
+ continue
+ }
+ if (line == "§b§lVisitors: §r§f(§r§cNot Unlocked!§r§f)") {
render = ""
return
}
- patternVisitors.matchMatcher(line) {
- visitorsAmount = group("amount").toInt()
+ pattern.matchMatcher(line) {
+ val rawTime = group("time").removeColor()
+ if (lastTimerValue != rawTime) {
+ lastTimerUpdate = SimpleTimeMark.now()
+ lastTimerValue = rawTime
+ }
+ millis = TimeUtils.getDuration(rawTime)
}
}
if (lastVisitors != -1 && visitorsAmount - lastVisitors == 1) {
if (!queueFull) {
- visitorInterval = ((millis - 1) / 60_000L + 1) * 60_000L
- GardenAPI.config?.visitorInterval = visitorInterval
+ visitorInterval = millis
+ this.visitorInterval = visitorInterval
} else {
updateSixthVisitorArrivalTime()
}
@@ -111,10 +122,11 @@ class GardenVisitorTimer {
visitorJustArrived = false
sixthVisitorReady = false
}
- millis = sixthVisitorArrivalTime - System.currentTimeMillis()
- GardenAPI.config?.nextSixthVisitorArrival =
- System.currentTimeMillis() + millis + (5 - visitorsAmount) * visitorInterval
- if (isSixthVisitorEnabled() && millis < 0) {
+ millis = sixthVisitorArrivalTime.timeUntil()
+
+ val nextSixthVisitorArrival = SimpleTimeMark.now() + millis + (visitorInterval * (5 - visitorsAmount))
+ GardenAPI.storage?.nextSixthVisitorArrival = nextSixthVisitorArrival.toMillis()
+ if (isSixthVisitorEnabled() && millis.isNegative()) {
visitorsAmount++
if (!sixthVisitorReady) {
LorenzUtils.sendTitle("§a6th Visitor Ready", 5.seconds)
@@ -123,23 +135,41 @@ class GardenVisitorTimer {
}
}
}
+ val sinceLastTimerUpdate = lastTimerUpdate.passedSince() - 100.milliseconds
+ val guessTime = visitorsAmount < 5 && sinceLastTimerUpdate in 500.milliseconds..60.seconds
+ if (guessTime) {
+ millis -= sinceLastTimerUpdate
+ }
+
+ if (lastMillis == Duration.INFINITE) {
+ ErrorManager.logErrorStateWithData(
+ "Found Visitor Timer bug, reset value", "lastMillis was infinite",
+ "lastMillis" to lastMillis
+ )
+ lastMillis = 0.seconds
+ }
val diff = lastMillis - millis
- if (diff == 0L && visitorsAmount == lastVisitors) return
+ if (diff == 0.seconds && visitorsAmount == lastVisitors) return
lastMillis = millis
lastVisitors = visitorsAmount
- val formatColor = if (queueFull) "6" else "e"
+ val formatColor = when {
+ queueFull -> "6"
+ else -> "e"
+ }
- val extraSpeed = if (diff in 2000..10_000) {
- val factor = diff / 1000.0
- "§7/§$formatColor" + TimeUtils.formatDuration((millis / factor).roundToLong())
+ val extraSpeed = if (diff in 2.seconds..10.seconds) {
+ val factor = diff.inWholeSeconds.toDouble()
+ val duration = millis / factor
+ "§7/§$formatColor" + duration.format()
} else ""
- if (config.newVisitorPing && millis < 10000){
+ if (config.newVisitorPing && millis < 10.seconds) {
SoundUtils.playBeepSound()
}
+
val formatDuration = TimeUtils.formatDuration(millis)
- val next = if (queueFull && (!isSixthVisitorEnabled() || millis < 0)) "§cQueue Full!" else {
+ val next = if (queueFull && (!isSixthVisitorEnabled() || millis.isNegative())) "§cQueue Full!" else {
"Next in §$formatColor$formatDuration$extraSpeed"
}
val visitorLabel = if (visitorsAmount == 1) "visitor" else "visitors"
@@ -156,22 +186,26 @@ class GardenVisitorTimer {
@SubscribeEvent
fun onWorldChange(event: LorenzWorldChangeEvent) {
lastVisitors = -1
- GardenAPI.config?.nextSixthVisitorArrival?.let {
- sixthVisitorArrivalTime = it
+ GardenAPI.storage?.nextSixthVisitorArrival?.let {
+ val badTime = Duration.INFINITE.inWholeMilliseconds
+ if (it != badTime && it != -9223370336633802065) {
+ sixthVisitorArrivalTime = it.asTimeMark()
+ }
}
sixthVisitorReady = false
- lastMillis = sixthVisitorArrivalTime - System.currentTimeMillis()
+ lastMillis = sixthVisitorArrivalTime.timeUntil()
}
@SubscribeEvent
fun onBlockBreak(event: CropClickEvent) {
if (!isEnabled()) return
- sixthVisitorArrivalTime -= 100
+ sixthVisitorArrivalTime -= 100.milliseconds
+ lastTimerUpdate -= 100.milliseconds
}
private fun updateSixthVisitorArrivalTime() {
visitorInterval?.let {
- sixthVisitorArrivalTime = System.currentTimeMillis() + it
+ sixthVisitorArrivalTime = SimpleTimeMark.now() + it
}
}
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
new file mode 100644
index 000000000..a4d370e62
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/HighlightVisitorsOutsideOfGarden.kt
@@ -0,0 +1,106 @@
+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.events.LorenzTickEvent
+import at.hannibal2.skyhanni.events.PacketEvent
+import at.hannibal2.skyhanni.events.RepositoryReloadEvent
+import at.hannibal2.skyhanni.events.withAlpha
+import at.hannibal2.skyhanni.mixins.hooks.RenderLivingEntityHelper
+import at.hannibal2.skyhanni.utils.EntityUtils
+import at.hannibal2.skyhanni.utils.EntityUtils.getSkinTexture
+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
+import net.minecraft.entity.Entity
+import net.minecraft.entity.EntityLivingBase
+import net.minecraft.entity.item.EntityArmorStand
+import net.minecraft.entity.player.EntityPlayer
+import net.minecraft.network.play.client.C02PacketUseEntity
+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
+
+ @SubscribeEvent
+ fun onRepoReload(event: RepositoryReloadEvent) {
+ visitorJson = event.getConstant<GardenJson>(
+ "Garden", GardenJson::class.java
+ ).visitors.values.groupBy {
+ it.mode
+ }
+ for (list in visitorJson.values) {
+ for (visitor in list) {
+ visitor.skinOrType = visitor.skinOrType?.replace("\\n", "")?.replace("\n", "")
+ }
+ }
+ }
+
+ private fun getSkinOrTypeFor(entity: Entity): String {
+ if (entity is EntityPlayer) {
+ return entity.getSkinTexture() ?: "no skin"
+ }
+ return entity.javaClass.simpleName
+ }
+
+ private fun isVisitor(entity: Entity): Boolean {
+ val mode = SBInfo.getInstance().getLocation()
+ val possibleJsons = visitorJson[mode] ?: return false
+ val skinOrType = getSkinOrTypeFor(entity)
+ return possibleJsons.any {
+ (it.position == null || it.position!!.distance(entity.position.toLorenzVec()) < 1)
+ && it.skinOrType == skinOrType
+ }
+ }
+
+ @SubscribeEvent
+ fun onTick(event: LorenzTickEvent) {
+ if (!config.highlightVisitors) return
+ if (!event.repeatSeconds(1)) return
+ EntityUtils.getEntities<EntityLivingBase>()
+ .filter { it !is EntityArmorStand && isVisitor(it) }
+ .forEach {
+ RenderLivingEntityHelper.setEntityColor(
+ it,
+ LorenzColor.DARK_RED.toColor().withAlpha(50)
+ ) { config.highlightVisitors }
+ }
+ }
+
+ private val shouldBlock
+ get() = when (config.blockInteracting) {
+ VisitorBlockBehaviour.DONT -> false
+ VisitorBlockBehaviour.ALWAYS -> true
+ VisitorBlockBehaviour.ONLY_ON_BINGO -> LorenzUtils.isBingoProfile
+ null -> false
+ }
+
+ private fun isVisitorNearby(location: LorenzVec) =
+ EntityUtils.getEntitiesNearby<EntityLivingBase>(location, 2.0).any { isVisitor(it) }
+
+ @SubscribeEvent
+ fun onClickEntity(event: PacketEvent.SendEvent) {
+ if (!shouldBlock) return
+ val world = Minecraft.getMinecraft().theWorld ?: return
+ val player = Minecraft.getMinecraft().thePlayer ?: return
+ if (player.isSneaking) return
+ val packet = event.packet as? C02PacketUseEntity ?: return
+ val entity = packet.getEntityFromWorld(world) ?: return
+ if (isVisitor(entity) || (entity is EntityArmorStand && isVisitorNearby(entity.getLorenzVec()))) {
+ event.isCanceled = true
+ if (packet.action == C02PacketUseEntity.Action.INTERACT) {
+ LorenzUtils.clickableChat(
+ "Blocked you from interacting with a visitor. Sneak to bypass or click here to change settings.",
+ "/sh block interacting with visitors"
+ )
+ }
+ }
+ }
+}
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 66b0ce39c..f71ab6883 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
@@ -60,11 +60,11 @@ object VisitorAPI {
if (visitor != null) return visitor
- println("visitors: $visitors")
- println("name: $name")
- ErrorManager.logErrorState(
+ ErrorManager.logErrorStateWithData(
"Error finding the visitor `$name§c`. Try to reopen the inventory",
- "visitor is null! name='$name', visitors=`$visitors`"
+ "Visitor is null while opening visitor inventory",
+ "name" to name,
+ "visitors" to visitors,
)
return null
}
@@ -138,4 +138,37 @@ object VisitorAPI {
ACCEPTED("§7Accepted", LorenzColor.DARK_GRAY.toColor().withAlpha(80)),
REFUSED("§cRefused", LorenzColor.RED.toColor().withAlpha(60)),
}
+
+ fun visitorsInTabList(tabList: List<String>): MutableList<String> {
+ var found = false
+ val visitorsInTab = mutableListOf<String>()
+ for (line in tabList) {
+ if (line.startsWith("§b§lVisitors:")) {
+ found = true
+ continue
+ }
+ if (!found) continue
+
+ if (line.isEmpty() || line.contains("Account Info")) {
+ found = false
+ continue
+ }
+ val name = fromHypixelName(line)
+
+ // Hide hypixel watchdog entries
+ if (name.contains("§c") && !name.contains("Spaceman") && !name.contains("Grandma Wolf")) {
+ logger.log("Ignore wrong red name: '$name'")
+ continue
+ }
+
+ //hide own player name
+ if (name.contains(LorenzUtils.getPlayerName())) {
+ logger.log("Ignore wrong own name: '$name'")
+ continue
+ }
+
+ visitorsInTab.add(name)
+ }
+ return visitorsInTab
+ }
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorListener.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorListener.kt
index 85aef6868..55323ef57 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorListener.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorListener.kt
@@ -66,35 +66,7 @@ class VisitorListener {
@SubscribeEvent
fun onTabListUpdate(event: TabListUpdateEvent) {
if (!GardenAPI.inGarden()) return
- var found = false
- val visitorsInTab = mutableListOf<String>()
- for (line in event.tabList) {
- if (line.startsWith("§b§lVisitors:")) {
- found = true
- continue
- }
- if (!found) continue
-
- if (line.isEmpty()) {
- found = false
- continue
- }
- val name = VisitorAPI.fromHypixelName(line)
-
- // Hide hypixel watchdog entries
- if (name.contains("§c") && !name.contains("Spaceman") && !name.contains("Grandma Wolf")) {
- logger.log("Ignore wrong red name: '$name'")
- continue
- }
-
- //hide own player name
- if (name.contains(LorenzUtils.getPlayerName())) {
- logger.log("Ignore wrong own name: '$name'")
- continue
- }
-
- visitorsInTab.add(name)
- }
+ val visitorsInTab = VisitorAPI.visitorsInTabList(event.tabList)
VisitorAPI.getVisitors().forEach {
val name = it.visitorName
@@ -165,15 +137,16 @@ class VisitorListener {
visitor.hasReward()?.let {
if (config.rewardWarning.preventRefusing) {
if (config.rewardWarning.bypassKey.isKeyHeld()) {
- LorenzUtils.chat("§e[SkyHanni] §cBypassed blocking refusal of visitor ${visitor.visitorName} §7(${it.displayName}§7)")
+ LorenzUtils.chat("§cBypassed blocking refusal of visitor ${visitor.visitorName} §7(${it.displayName}§7)")
return
}
event.isCanceled = true
- LorenzUtils.chat("§e[SkyHanni] §cBlocked refusing visitor ${visitor.visitorName} §7(${it.displayName}§7)")
+ LorenzUtils.chat("§cBlocked refusing visitor ${visitor.visitorName} §7(${it.displayName}§7)")
if (config.rewardWarning.bypassKey == Keyboard.KEY_NONE) {
LorenzUtils.clickableChat(
"§eIf you want to deny this visitor, set a keybind in §e/sh bypass",
- "sh bypass"
+ "sh bypass",
+ false
)
}
Minecraft.getMinecraft().thePlayer.closeScreen()
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 d21ffebe7..d6aabd3b5 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
@@ -18,9 +18,9 @@ enum class VisitorReward(private val rawInternalName: String) {
private val internalName by lazy { rawInternalName.asInternalName() }
val itemStack by lazy { internalName.getItemStack() }
- val displayName by lazy { itemStack.nameWithEnchantment ?: internalName.toString() }
+ val displayName by lazy { itemStack.nameWithEnchantment ?: internalName.asString() }
companion object {
fun getByInternalName(internalName: NEUInternalName) = entries.firstOrNull { it.internalName == internalName }
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorTooltipParser.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorTooltipParser.kt
index 5d6e7ee26..851c5ece7 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorTooltipParser.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorTooltipParser.kt
@@ -1,13 +1,13 @@
package at.hannibal2.skyhanni.features.garden.visitor
-import at.hannibal2.skyhanni.config.features.GardenConfig
+import at.hannibal2.skyhanni.config.features.garden.GardenConfig
import at.hannibal2.skyhanni.utils.ItemUtils
class VisitorTooltipParser {
class ParsedTooltip(
- val itemsNeeded: MutableMap<String, Int>,
- val rewards: MutableMap<String, Int>,
- val config: GardenConfig,
+ val itemsNeeded: MutableMap<String, Int>,
+ val rewards: MutableMap<String, Int>,
+ val config: GardenConfig,
)
enum class ParsingSection {
@@ -36,7 +36,7 @@ class VisitorTooltipParser {
}
}
- return parsedData;
+ return parsedData
}
}
-} \ No newline at end of file
+}
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 b7b8ae7f6..42b22741b 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/inventory/ChestValue.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/ChestValue.kt
@@ -8,11 +8,13 @@ import at.hannibal2.skyhanni.events.InventoryCloseEvent
import at.hannibal2.skyhanni.events.InventoryOpenEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.features.misc.items.EstimatedItemValue
+import at.hannibal2.skyhanni.features.misc.items.EstimatedItemValueCalculator
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalNameOrNull
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.LorenzUtils.isInIsland
import at.hannibal2.skyhanni.utils.NEUItems.getItemStackOrNull
import at.hannibal2.skyhanni.utils.NumberUtil
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
@@ -190,7 +192,7 @@ class ChestValue {
val internalName = stack.getInternalNameOrNull() ?: continue
if (internalName.getItemStackOrNull() == null) continue
val list = mutableListOf<String>()
- val pair = EstimatedItemValue.getEstimatedItemPrice(stack, list)
+ val pair = EstimatedItemValueCalculator.calculate(stack, list)
var (total, _) = pair
val key = "$internalName+$total"
if (stack.item == Items.enchanted_book)
@@ -242,8 +244,7 @@ class ChestValue {
return true
}
- val inMinion = name.contains("Minion") && !name.contains("Recipe") &&
- LorenzUtils.skyBlockIsland == IslandType.PRIVATE_ISLAND
+ val inMinion = name.contains("Minion") && !name.contains("Recipe") && IslandType.PRIVATE_ISLAND.isInIsland()
return name == "Chest" || name == "Large Chest" || inMinion || name == "Personal Vault"
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt
index e793cd615..0f8c3fe4a 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/HarpFeatures.kt
@@ -4,6 +4,7 @@ import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.RenderItemTipEvent
import at.hannibal2.skyhanni.utils.InventoryUtils.openInventoryName
+import at.hannibal2.skyhanni.utils.KeyboardManager
import at.hannibal2.skyhanni.utils.KeyboardManager.isKeyHeld
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.SimpleTimeMark
@@ -12,23 +13,22 @@ import net.minecraft.client.gui.inventory.GuiChest
import net.minecraft.item.Item
import net.minecraftforge.client.event.GuiScreenEvent
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-import org.lwjgl.input.Keyboard
import kotlin.time.Duration.Companion.milliseconds
// Delaying key presses by 300ms comes from NotEnoughUpdates
-class HarpFeatures {
+object HarpFeatures {
private val config get() = SkyHanniMod.feature.inventory.helper.harp
private var lastClick = SimpleTimeMark.farPast()
- private val keys = listOf(
- Keyboard.KEY_1,
- Keyboard.KEY_2,
- Keyboard.KEY_3,
- Keyboard.KEY_4,
- Keyboard.KEY_5,
- Keyboard.KEY_6,
- Keyboard.KEY_7
- )
+ private object KeyIterable : Iterable<Int> {
+ override fun iterator() = object : Iterator<Int> {
+ private var currentIndex = 0
+
+ override fun hasNext() = currentIndex < 7
+
+ override fun next() = getKey(currentIndex++) ?: throw NoSuchElementException("currentIndex: $currentIndex")
+ }
+ }
private val buttonColors = listOf('d', 'e', 'a', '2', '5', '9', 'b')
@@ -39,23 +39,34 @@ class HarpFeatures {
if (!openInventoryName().startsWith("Harp")) return
val chest = event.gui as? GuiChest ?: return
- for (key in keys) {
- if (key.isKeyHeld()) {
- if (lastClick.passedSince() > 200.milliseconds) {
- Minecraft.getMinecraft().playerController.windowClick(
- chest.inventorySlots.windowId,
- 35 + key,
- 2,
- 3,
- Minecraft.getMinecraft().thePlayer
- ) // middle clicks > left clicks
- lastClick = SimpleTimeMark.now()
- }
- break
- }
+ for ((index, key) in KeyIterable.withIndex()) {
+ if (!key.isKeyHeld()) continue
+ if (lastClick.passedSince() < 200.milliseconds) break
+
+ Minecraft.getMinecraft().playerController.windowClick(
+ chest.inventorySlots.windowId,
+ 37 + index,
+ 2,
+ 3,
+ Minecraft.getMinecraft().thePlayer
+ ) // middle clicks > left clicks
+ lastClick = SimpleTimeMark.now()
+ break
}
}
+ fun getKey(index: Int) = when (index) {
+ 0 -> config.harpKeybinds.key1
+ 1 -> config.harpKeybinds.key2
+ 2 -> config.harpKeybinds.key3
+ 3 -> config.harpKeybinds.key4
+ 4 -> config.harpKeybinds.key5
+ 5 -> config.harpKeybinds.key6
+ 6 -> config.harpKeybinds.key7
+
+ else -> null
+ }
+
@SubscribeEvent
fun onRenderItemTip(event: RenderItemTipEvent) {
if (!LorenzUtils.inSkyBlock) return
@@ -67,7 +78,8 @@ class HarpFeatures {
val index = buttonColors.indexOfFirst { it == event.stack.displayName[1] }
if (index == -1) return // this should never happen unless there's an update
- event.stackTip = (index + 1).toString()
+ val keyCode = getKey(index) ?: return
+ event.stackTip = KeyboardManager.getKeyName(keyCode)
}
@SubscribeEvent
@@ -75,4 +87,4 @@ class HarpFeatures {
event.move(2, "misc.harpKeybinds", "inventory.helper.harp.keybinds")
event.move(2, "misc.harpNumbers", "inventory.helper.harp.showNumbers")
}
-} \ No newline at end of file
+}
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 ddb4645d6..a8880aefd 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/inventory/HideNotClickableItems.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/HideNotClickableItems.kt
@@ -127,7 +127,7 @@ class HideNotClickableItems {
event.toolTip.add("")
if (hideReason == "") {
event.toolTip.add("§4No hide reason!")
- LorenzUtils.warning("No hide reason for not clickable item!")
+ LorenzUtils.error("No hide reason for not clickable item!")
} else {
event.toolTip.add("§c$hideReason")
if (config.itemsBypass) {
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 31c606d55..aa3a46ed2 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemDisplayOverlayFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemDisplayOverlayFeatures.kt
@@ -73,7 +73,9 @@ class ItemDisplayOverlayFeatures {
}
}
- if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(5) && itemName.contains(" Minion ") && item.getLore().any { it.contains("Place this minion") }) {
+ if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(5) && itemName.contains(" Minion ") &&
+ !itemName.contains("Recipe") && item.getLore().any { it.contains("Place this minion") }
+ ) {
val array = itemName.split(" ")
val last = array[array.size - 1]
return last.romanToDecimal().toString()
@@ -95,27 +97,29 @@ class ItemDisplayOverlayFeatures {
}
}
- if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(9) && InventoryUtils.openInventoryName() == "Your Skills" && item.getLore().any { it.contains("Click to view!") }) {
+ if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(9) &&
+ InventoryUtils.openInventoryName() == "Your Skills" &&
+ item.getLore().any { it.contains("Click to view!") }) {
if (CollectionAPI.isCollectionTier0(item.getLore())) return "0"
val split = itemName.split(" ")
- if (split.size < 2) return "0"
if (!itemName.contains("Dungeon")) {
val text = split.last()
+ if (split.size < 2) return "0"
return "" + text.romanToDecimalIfNeeded()
}
}
if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(10) && 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()
- }
+ 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()
}
}
+ }
}
if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(11) && itemName.contains("Rancher's Boots")) {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/tiarelay/TiaRelayHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/tiarelay/TiaRelayHelper.kt
index 7c50ec1a0..4d648c16c 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/inventory/tiarelay/TiaRelayHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/tiarelay/TiaRelayHelper.kt
@@ -71,7 +71,7 @@ class TiaRelayHelper {
val name = sounds.values.first().name
for (sound in sounds.toMutableMap()) {
if (sound.value.name != name) {
- LorenzUtils.chat("§c[SkyHanni] Tia Relay Helper error: Too much background noise! Please try again.")
+ LorenzUtils.error("Tia Relay Helper error: Too much background noise! Please try again.")
sounds.clear()
return
}
@@ -143,4 +143,4 @@ class TiaRelayHelper {
}
class Sound(val name: String, val pitch: Float)
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/itemabilities/FireVeilWandParticles.kt b/src/main/java/at/hannibal2/skyhanni/features/itemabilities/FireVeilWandParticles.kt
index 455efcef0..abb0c0f4c 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/itemabilities/FireVeilWandParticles.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/itemabilities/FireVeilWandParticles.kt
@@ -18,7 +18,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class FireVeilWandParticles {
private val config get() = SkyHanniMod.feature.itemAbilities.fireVeilWands
- var lastClick = 0L
+ private var lastClick = 0L
val item by lazy { "FIRE_VEIL_WAND".asInternalName() }
diff --git a/src/main/java/at/hannibal2/skyhanni/features/itemabilities/abilitycooldown/ItemAbilityCooldown.kt b/src/main/java/at/hannibal2/skyhanni/features/itemabilities/abilitycooldown/ItemAbilityCooldown.kt
index 4bf1d38ff..a547c14b4 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/itemabilities/abilitycooldown/ItemAbilityCooldown.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/itemabilities/abilitycooldown/ItemAbilityCooldown.kt
@@ -35,6 +35,7 @@ class ItemAbilityCooldown {
private var items = mapOf<ItemStack, List<ItemText>>()
private var abilityItems = mapOf<ItemStack, MutableList<ItemAbility>>()
private val youAlignedOthersPattern = "§eYou aligned §r§a.* §r§eother player(s)?!".toPattern()
+ private val youBuffedYourselfPattern = "§aYou buffed yourself for §r§c\\+\\d+❁ Strength".toPattern()
private val WEIRD_TUBA = "WEIRD_TUBA".asInternalName()
private val WEIRDER_TUBA = "WEIRDER_TUBA".asInternalName()
private val VOODOO_DOLL_WILTED = "VOODOO_DOLL_WILTED".asInternalName()
@@ -185,11 +186,13 @@ class ItemAbilityCooldown {
ItemAbility.RAGNAROCK_AXE.activate(LorenzColor.WHITE, 3_000)
}
}
+
message.contains("§lCASTING") -> {
if (ItemAbility.RAGNAROCK_AXE.specialColor != LorenzColor.DARK_PURPLE) {
ItemAbility.RAGNAROCK_AXE.activate(LorenzColor.DARK_PURPLE, 10_000)
}
}
+
message.contains("§c§lCANCELLED") -> {
ItemAbility.RAGNAROCK_AXE.activate(null, 17_000)
}
@@ -273,7 +276,7 @@ class ItemAbilityCooldown {
val guiOpen = Minecraft.getMinecraft().currentScreen != null
val uuid = stack.getIdentifier() ?: return
val list = items.filter { (it.key.getIdentifier()) == uuid }
- .firstNotNullOfOrNull { it.value } ?: return
+ .firstNotNullOfOrNull { it.value } ?: return
for (itemText in list) {
if (guiOpen && !itemText.onCooldown) continue
@@ -324,6 +327,9 @@ class ItemAbilityCooldown {
if (message == "§cRagnarock was cancelled due to being hit!") {
ItemAbility.RAGNAROCK_AXE.activate(null, 17_000)
}
+ youBuffedYourselfPattern.matchMatcher(message) {
+ ItemAbility.SWORD_OF_BAD_HEALTH.activate()
+ }
}
private fun hasAbility(stack: ItemStack): MutableList<ItemAbility> {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/mining/HighlightMiningCommissionMobs.kt b/src/main/java/at/hannibal2/skyhanni/features/mining/HighlightMiningCommissionMobs.kt
index 9b46318de..94726c640 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/mining/HighlightMiningCommissionMobs.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/mining/HighlightMiningCommissionMobs.kt
@@ -93,5 +93,5 @@ class HighlightMiningCommissionMobs {
}
fun isEnabled() = config.highlightCommissionMobs &&
- (IslandType.DWARVEN_MINES.isInIsland() || IslandType.CRYSTAL_HOLLOWS.isInIsland())
+ (IslandType.DWARVEN_MINES.isInIsland() || IslandType.CRYSTAL_HOLLOWS.isInIsland())
}
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 af6a7dbfd..501ae420e 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/mining/KingTalismanHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/mining/KingTalismanHelper.kt
@@ -6,6 +6,7 @@ import at.hannibal2.skyhanni.data.ProfileStorageData
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
+import at.hannibal2.skyhanni.utils.EntityUtils
import at.hannibal2.skyhanni.utils.LocationUtils.distanceToPlayer
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland
@@ -13,13 +14,32 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.sorted
import at.hannibal2.skyhanni.utils.LorenzUtils.sortedDesc
import at.hannibal2.skyhanni.utils.LorenzVec
import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.TimeUtils
import io.github.moulberry.notenoughupdates.util.SkyBlockTime
+import net.minecraft.entity.item.EntityArmorStand
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import java.util.Collections
class KingTalismanHelper {
- private val config get() = SkyHanniMod.feature.mining
+ private val config get() = SkyHanniMod.feature.mining.kingTalisman
+
+ companion object {
+ private var currentOffset: Int? = null
+ private var skyblockYear = 0
+
+ private fun getCurrentOffset(): Int? {
+ if (SkyBlockTime.now().year != skyblockYear) {
+ return null
+ }
+ return currentOffset
+ }
+
+ fun kingFix() {
+ currentOffset = null
+ LorenzUtils.chat("Reset internal offset of King Talisman Helper.")
+ }
+ }
private val kingLocation = LorenzVec(129.6, 196.5, 194.1)
private val kingCircles = listOf(
@@ -36,27 +56,52 @@ class KingTalismanHelper {
private var farDisplay = ""
private var display = emptyList<String>()
- fun isNearby() = LorenzUtils.skyBlockArea == "Royal Palace" && kingLocation.distanceToPlayer() < 10
+ private fun isNearby() = IslandType.DWARVEN_MINES.isInIsland() && LorenzUtils.skyBlockArea == "Royal Palace" &&
+ kingLocation.distanceToPlayer() < 10
@SubscribeEvent
fun onTick(event: LorenzTickEvent) {
if (!event.isMod(20)) return
+ if (!isEnabled()) return
+ val profileSpecific = ProfileStorageData.profileSpecific ?: return
- if (!isEnabled()) {
- display = emptyList()
+ val nearby = isNearby()
+ if (nearby && getCurrentOffset() == null) {
+ checkOffset()
+ }
+
+ val kingsTalkedTo = profileSpecific.mining.kingsTalkedTo
+ if (getCurrentOffset() == null) {
+ val allKings = kingsTalkedTo.size == kingCircles.size
+ display = if (allKings) emptyList() else listOf("§cVisit the king to sync up.")
return
}
- update()
- display = if (isNearby()) allKingsDisplay else Collections.singletonList(farDisplay)
+ update(kingsTalkedTo)
+ display = if (nearby) allKingsDisplay else Collections.singletonList(farDisplay)
+ }
+
+ private fun checkOffset() {
+ val king = EntityUtils.getEntitiesNearby<EntityArmorStand>(LorenzVec(129.6, 196.0, 196.7), 2.0)
+ .filter { it.name.startsWith("§6§lKing ") }.first()
+ val foundKing = "§6§lKing (?<name>.*)".toPattern().matchMatcher(king.name) {
+ group("name")
+ } ?: return
+
+ val currentId = kingCircles.indexOf(getCurrentKing())
+ val foundId = kingCircles.indexOf(foundKing)
+ currentOffset = currentId - foundId
+ skyblockYear = SkyBlockTime.now().year
}
- fun isEnabled() = config.kingTalismanHelper && IslandType.DWARVEN_MINES.isInIsland()
+ fun isEnabled() = config.enabled && LorenzUtils.inSkyBlock
+ && (IslandType.DWARVEN_MINES.isInIsland() || config.outsideMines)
@SubscribeEvent
fun onInventoryOpen(event: InventoryFullyOpenedEvent) {
if (event.inventoryName != "Commissions") return
if (!isEnabled()) return
+ if (getCurrentOffset() == null) return
if (!isNearby()) return
val profileSpecific = ProfileStorageData.profileSpecific ?: return
@@ -65,14 +110,12 @@ class KingTalismanHelper {
if (currentKing !in kingsTalkedTo) {
LorenzUtils.debug("Found new king!")
kingsTalkedTo.add(currentKing)
- update()
+ update(kingsTalkedTo)
display = allKingsDisplay
}
}
- private fun update() {
- val profileSpecific = ProfileStorageData.profileSpecific ?: return
- val kingsTalkedTo = profileSpecific.mining.kingsTalkedTo
+ private fun update(kingsTalkedTo: MutableList<String>) {
if (kingsTalkedTo.size == kingCircles.size) {
allKingsDisplay = Collections.singletonList("§eAll Kings found.")
farDisplay = ""
@@ -120,12 +163,14 @@ class KingTalismanHelper {
}
private fun getKingTimes(): MutableMap<String, Long> {
+ val currentOffset = getCurrentOffset() ?: 0
val oneSbDay = 1000 * 60 * 20
val oneCircleTime = oneSbDay * kingCircles.size
val kingTime = mutableMapOf<String, Long>()
for ((index, king) in kingCircles.withIndex()) {
-
- val startTime = SkyBlockTime(day = index + 2 - kingCircles.size)
+// val startTime = SkyBlockTime(day = index + 2 - kingCircles.size)
+// val startTime = SkyBlockTime(day = index - kingCircles.size)
+ val startTime = SkyBlockTime(day = index + currentOffset - kingCircles.size)
var timeNext = startTime.toMillis()
while (timeNext < System.currentTimeMillis()) {
timeNext += oneCircleTime
@@ -140,8 +185,8 @@ class KingTalismanHelper {
@SubscribeEvent
fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
- if (!config.kingTalismanHelper) return
+ if (!isEnabled()) return
- config.kingTalismanHelperPos.renderStrings(display, posLabel = "King Talisman Helper")
+ config.position.renderStrings(display, posLabel = "King Talisman Helper")
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/mining/crystalhollows/CrystalHollowsNamesInCore.kt b/src/main/java/at/hannibal2/skyhanni/features/mining/crystalhollows/CrystalHollowsNamesInCore.kt
index af4d3abf9..b1682baad 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/mining/crystalhollows/CrystalHollowsNamesInCore.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/mining/crystalhollows/CrystalHollowsNamesInCore.kt
@@ -12,7 +12,7 @@ import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class CrystalHollowsNamesInCore {
- val config get() = SkyHanniMod.feature.mining
+ private val config get() = SkyHanniMod.feature.mining
private val coreLocations = mapOf(
LorenzVec(550, 116, 550) to "§8Precursor City",
LorenzVec(552, 116, 474) to "§bMithril Deposits",
@@ -20,7 +20,7 @@ class CrystalHollowsNamesInCore {
LorenzVec(474, 116, 554) to "§6Goblin Hideout"
)
- var showWaypoints = false
+ private var showWaypoints = false
@SubscribeEvent
fun onTick(event: LorenzTickEvent) {
@@ -44,4 +44,4 @@ class CrystalHollowsNamesInCore {
}
fun isEnabled() = IslandType.CRYSTAL_HOLLOWS.isInIsland() && config.crystalHollowsNamesInCore
-} \ No newline at end of file
+}
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 9db8553aa..fd4ad8962 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,32 +2,28 @@ package at.hannibal2.skyhanni.features.mining.powdertracker
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-import at.hannibal2.skyhanni.config.Storage
import at.hannibal2.skyhanni.data.IslandType
-import at.hannibal2.skyhanni.data.ProfileStorageData
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.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
-import at.hannibal2.skyhanni.utils.LorenzUtils.addSelector
import at.hannibal2.skyhanni.utils.LorenzUtils.afterChange
+import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber
-import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
-import net.minecraft.client.Minecraft
-import net.minecraft.client.gui.inventory.GuiInventory
+import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker
+import at.hannibal2.skyhanni.utils.tracker.TrackerData
+import com.google.gson.annotations.Expose
import net.minecraft.entity.boss.BossStatus
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.concurrent.fixedRateTimer
-class PowderTracker {
+object PowderTracker {
private val config get() = SkyHanniMod.feature.mining.powderTracker
- private var display = emptyList<List<Any>>()
private val picked = "§6You have successfully picked the lock on this chest!".toPattern()
private val uncovered = "§aYou uncovered a treasure chest!".toPattern()
private val powderEvent = ".*§r§b§l2X POWDER STARTED!.*".toPattern()
@@ -42,9 +38,6 @@ class PowderTracker {
private val chestInfo = ResourceInfo(0L, 0L, 0, 0.0, mutableListOf())
private var doublePowder = false
private var powderTimer = ""
- private var currentDisplayMode = DisplayMode.TOTAL
- private var inventoryOpen = false
- private var currentSessionData = mutableMapOf<Int, Storage.ProfileSpecific.PowderTracker>()
private val gemstones = listOf(
"Ruby" to "§c",
"Sapphire" to "§b",
@@ -65,33 +58,39 @@ class PowderTracker {
}
}
+ private val tracker = SkyHanniTracker("Powder Tracker", { Data() }, { it.powderTracker })
+ { formatDisplay(drawDisplay(it)) }
+
+ class Data : TrackerData() {
+ override fun reset() {
+ rewards.clear()
+ totalChestPicked = 0
+ }
+
+ @Expose
+ var totalChestPicked = 0
+
+ @Expose
+ var rewards: MutableMap<PowderChestReward, Long> = mutableMapOf()
+ }
+
@SubscribeEvent
fun onRenderOverlay(event: GuiRenderEvent) {
if (!isEnabled()) return
- val currentlyOpen = Minecraft.getMinecraft().currentScreen is GuiInventory
- if (inventoryOpen != currentlyOpen) {
- inventoryOpen = currentlyOpen
- saveAndUpdate()
- }
-
if (config.onlyWhenPowderGrinding && !isGrinding) return
- config.position.renderStringsAndItems(
- display,
- posLabel = "Powder Chest Tracker"
- )
+ tracker.renderDisplay(config.position)
}
@SubscribeEvent
fun onChat(event: LorenzChatEvent) {
if (!isEnabled()) return
val msg = event.message
- val both = currentLog() ?: return
if (config.greatExplorerMaxed) {
uncovered.matchMatcher(msg) {
- both.modify {
+ tracker.modify {
it.totalChestPicked += 1
}
isGrinding = true
@@ -100,7 +99,7 @@ class PowderTracker {
}
picked.matchMatcher(msg) {
- both.modify {
+ tracker.modify {
it.totalChestPicked += 1
}
isGrinding = true
@@ -112,7 +111,7 @@ class PowderTracker {
for (reward in PowderChestReward.entries) {
reward.pattern.matchMatcher(msg) {
- both.modify {
+ tracker.modify {
val count = it.rewards[reward] ?: 0
var amount = group("amount").formatNumber()
if ((reward == PowderChestReward.MITHRIL_POWDER || reward == PowderChestReward.GEMSTONE_POWDER) && doublePowder)
@@ -121,7 +120,7 @@ class PowderTracker {
}
}
}
- saveAndUpdate()
+ tracker.update()
}
@SubscribeEvent
@@ -133,7 +132,7 @@ class PowderTracker {
powderTimer = group("time")
doublePowder = powderTimer != "00:00"
- saveAndUpdate()
+ tracker.update()
}
}
if (System.currentTimeMillis() - lastChestPicked > 60_000) {
@@ -143,7 +142,9 @@ class PowderTracker {
@SubscribeEvent
fun onConfigLoad(event: ConfigLoadEvent) {
- config.textFormat.afterChange { saveAndUpdate() }
+ config.textFormat.afterChange {
+ tracker.update()
+ }
}
@SubscribeEvent
@@ -165,21 +166,16 @@ class PowderTracker {
chestInfo.stoppedChecks = 0
chestInfo.perMin.clear()
doublePowder = false
- saveAndUpdate()
+ tracker.update()
}
@SubscribeEvent
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
event.move(2, "misc.powderTrackerConfig", "mining.powderTracker")
- }
- private fun saveAndUpdate() {
- calculate(gemstoneInfo, PowderChestReward.GEMSTONE_POWDER)
- calculate(mithrilInfo, PowderChestReward.MITHRIL_POWDER)
- calculate(diamondEssenceInfo, PowderChestReward.DIAMOND_ESSENCE)
- calculate(goldEssenceInfo, PowderChestReward.GOLD_ESSENCE)
- calculateChest()
- display = formatDisplay(drawDisplay())
+ event.move(8, "#profile.powderTracker", "#profile.powderTracker") { old ->
+ old.asJsonObject.get("0")
+ }
}
private fun formatDisplay(map: List<List<Any>>) = buildList {
@@ -189,31 +185,25 @@ class PowderTracker {
}
}
- private fun drawDisplay() = buildList<List<Any>> {
+ private fun drawDisplay(data: Data): List<List<Any>> = buildList {
+ calculate(data, gemstoneInfo, PowderChestReward.GEMSTONE_POWDER)
+ calculate(data, mithrilInfo, PowderChestReward.MITHRIL_POWDER)
+ calculate(data, diamondEssenceInfo, PowderChestReward.DIAMOND_ESSENCE)
+ calculate(data, goldEssenceInfo, PowderChestReward.GOLD_ESSENCE)
+ calculateChest(data)
+
addAsSingletonList("§b§lPowder Tracker")
- if (inventoryOpen) {
- addSelector<DisplayMode>(
- "§7Display Mode: ",
- getName = { type -> type.displayName },
- isCurrent = { it == currentDisplayMode },
- onChange = {
- currentDisplayMode = it
- saveAndUpdate()
- }
- )
- } else {
+
+ if (!tracker.isInventoryOpen()) {
addAsSingletonList("")
}
- val both = currentLog() ?: return@buildList
- val display = both.get(currentDisplayMode)
-
val chestPerHour = format(chestInfo.perHour)
- addAsSingletonList("§d${display.totalChestPicked.addSeparators()} Total Chests Picked §7($chestPerHour/h)")
+ addAsSingletonList("§d${data.totalChestPicked.addSeparators()} Total Chests Picked §7($chestPerHour/h)")
addAsSingletonList("§bDouble Powder: ${if (doublePowder) "§aActive! §7($powderTimer)" else "§cInactive!"}")
val entries = PowderChestReward.entries
- val rewards = display.rewards
+ val rewards = data.rewards
addPerHour(rewards, entries[0], mithrilInfo)
addPerHour(rewards, entries[1], gemstoneInfo)
addAsSingletonList("")
@@ -262,13 +252,13 @@ class PowderTracker {
val count = rewards.getOrDefault(reward, 0).addSeparators()
addAsSingletonList("§b$count ${reward.displayName}")
}
-
}
private fun MutableList<List<Any>>.addPerHour(
map: MutableMap<PowderChestReward, Long>,
reward: PowderChestReward,
- info: ResourceInfo) {
+ info: ResourceInfo
+ ) {
val mithrilCount = map.getOrDefault(reward, 0).addSeparators()
val mithrilPerHour = format(info.perHour)
addAsSingletonList("§b$mithrilCount ${reward.displayName} §7($mithrilPerHour/h)")
@@ -300,19 +290,12 @@ class PowderTracker {
resourceInfo.stoppedChecks = 0
}
- private fun calculate(info: ResourceInfo, reward: PowderChestReward) {
- val both = currentLog() ?: return
- val display = both.get(currentDisplayMode)
- val rewards = display.rewards
- info.estimated = 0
- info.estimated += rewards.getOrDefault(reward, 0)
+ private fun calculate(display: Data, info: ResourceInfo, reward: PowderChestReward) {
+ info.estimated = display.rewards.getOrDefault(reward, 0)
}
- private fun calculateChest() {
- val both = currentLog() ?: return
- val display = both.get(currentDisplayMode)
- chestInfo.estimated = 0
- chestInfo.estimated += display.totalChestPicked
+ private fun calculateChest(data: Data) {
+ chestInfo.estimated = data.totalChestPicked.toLong()
}
private fun convert(roughCount: Long): Gem {
@@ -342,37 +325,9 @@ class PowderTracker {
val perMin: MutableList<Long>
)
- enum class DisplayMode(val displayName: String) {
- TOTAL("Total"),
- CURRENT("This Session"),
- ;
- }
+ private fun isEnabled() = IslandType.CRYSTAL_HOLLOWS.isInIsland() && config.enabled
- private fun currentLog(): AbstractPowderTracker? {
- val profileSpecific = ProfileStorageData.profileSpecific ?: return null
-
- return AbstractPowderTracker(
- profileSpecific.powderTracker.getOrPut(0) { Storage.ProfileSpecific.PowderTracker() },
- currentSessionData.getOrPut(0) { Storage.ProfileSpecific.PowderTracker() }
- )
+ fun resetCommand(args: Array<String>) {
+ tracker.resetCommand(args, "shresetpowdertracker")
}
-
- class AbstractPowderTracker(
- private val total: Storage.ProfileSpecific.PowderTracker,
- private val currentSession: Storage.ProfileSpecific.PowderTracker,
- ) {
-
- fun modify(modifyFunction: (Storage.ProfileSpecific.PowderTracker) -> Unit) {
- modifyFunction(total)
- modifyFunction(currentSession)
- }
-
- fun get(displayMode: DisplayMode) = when (displayMode) {
- DisplayMode.TOTAL -> total
- DisplayMode.CURRENT -> currentSession
- }
- }
-
- private fun isEnabled() =
- LorenzUtils.inSkyBlock && LorenzUtils.skyBlockIsland == IslandType.CRYSTAL_HOLLOWS && config.enabled
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/minion/MinionCollectLogic.kt b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionCollectLogic.kt
index 1615838ae..091197b53 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/minion/MinionCollectLogic.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionCollectLogic.kt
@@ -1,8 +1,8 @@
package at.hannibal2.skyhanni.features.minion
-import at.hannibal2.skyhanni.api.CollectionAPI
import at.hannibal2.skyhanni.events.GuiContainerEvent
import at.hannibal2.skyhanni.events.MinionOpenEvent
+import at.hannibal2.skyhanni.events.entity.ItemAddInInventoryEvent
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.NEUInternalName
@@ -43,10 +43,10 @@ class MinionCollectLogic {
val diff = amount - old
if (diff > 0) {
- CollectionAPI.addFromInventory(internalId, diff)
+ ItemAddInInventoryEvent(internalId, diff).postAndCatch()
}
}
oldMap = emptyMap()
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt
index f4853961c..9eab0fdde 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt
@@ -336,7 +336,7 @@ class MinionFeatures {
fun clearMinionData() {
minions = mutableMapOf()
- LorenzUtils.chat("§e[SkyHanni] Manually reset all private island minion location data!")
+ LorenzUtils.chat("Manually reset all private island minion location data!")
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/BrewingStandOverlay.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/BrewingStandOverlay.kt
index d7bee2948..cbcb52db7 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/BrewingStandOverlay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/BrewingStandOverlay.kt
@@ -36,8 +36,8 @@ class BrewingStandOverlay {
if (name.contains(" or ")) return
event.stackTip = name
- event.offsetX = event.offsetX + 3
+ event.offsetX += 3
event.offsetY = -5
event.alignLeft = false
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/CollectionTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/CollectionTracker.kt
index ebc00c989..e05571b6a 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/CollectionTracker.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/CollectionTracker.kt
@@ -39,32 +39,32 @@ class CollectionTracker {
fun command(args: Array<String>) {
if (args.isEmpty()) {
if (internalName == null) {
- LorenzUtils.chat("§c/shtrackcollection <item name>")
+ LorenzUtils.userError("/shtrackcollection <item name>")
return
}
- LorenzUtils.chat("§e[SkyHanni] Stopped collection tracker.")
+ LorenzUtils.chat("Stopped collection tracker.")
resetData()
return
}
val rawName = fixTypo(args.joinToString(" ").lowercase().replace("_", " "))
if (rawName == "gemstone") {
- LorenzUtils.chat("§c[SkyHanni] Gemstone collection is not supported!")
+ LorenzUtils.userError("Gemstone collection is not supported!")
return
} else if (rawName == "mushroom") {
- LorenzUtils.chat("§c[SkyHanni] Mushroom collection is not supported!")
+ LorenzUtils.userError("Mushroom collection is not supported!")
return
}
val foundInternalName = NEUItems.getInternalNameOrNullIgnoreCase(rawName)
if (foundInternalName == null) {
- LorenzUtils.chat("§c[SkyHanni] Item '$rawName' does not exist!")
+ LorenzUtils.error("Item '$rawName' does not exist!")
return
}
val stack = foundInternalName.getItemStackOrNull()
if (stack == null) {
- LorenzUtils.chat("§c[SkyHanni] Item '$rawName' does not exist!")
+ LorenzUtils.error("Item '$rawName' does not exist!")
return
}
setNewCollection(foundInternalName, stack.name!!.removeColor())
@@ -97,7 +97,7 @@ class CollectionTracker {
private fun setNewCollection(internalName: NEUInternalName, name: String) {
val foundAmount = CollectionAPI.getCollectionCounter(internalName)
if (foundAmount == null) {
- LorenzUtils.chat("§c[SkyHanni] $name collection not found. Try to open the collection inventory!")
+ LorenzUtils.userError("$name collection not found. Try to open the collection inventory!")
return
}
this.internalName = internalName
@@ -106,7 +106,7 @@ class CollectionTracker {
lastAmountInInventory = countCurrentlyInInventory()
updateDisplay()
- LorenzUtils.chat("§e[SkyHanni] Started tracking $itemName §ecollection.")
+ LorenzUtils.chat("Started tracking $itemName §ecollection.")
}
private fun resetData() {
@@ -170,7 +170,7 @@ class CollectionTracker {
val currentlyInInventory = countCurrentlyInInventory()
val diff = currentlyInInventory - lastAmountInInventory
if (diff != 0 && diff > 0) {
- gainItems(diff)
+ gainItems(diff)
}
lastAmountInInventory = currentlyInInventory
@@ -201,4 +201,4 @@ class CollectionTracker {
SkyHanniMod.feature.misc.collectionCounterPos.renderStringsAndItems(display, posLabel = "Collection Tracker")
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/CurrentPetDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/CurrentPetDisplay.kt
index e4b962281..128e9a126 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/CurrentPetDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/CurrentPetDisplay.kt
@@ -2,61 +2,61 @@ package at.hannibal2.skyhanni.features.misc
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-import at.hannibal2.skyhanni.data.ProfileStorageData
+import at.hannibal2.skyhanni.data.PetAPI
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.features.rift.RiftAPI
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.LorenzUtils.between
import at.hannibal2.skyhanni.utils.RenderUtils.renderString
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
-import at.hannibal2.skyhanni.utils.StringUtils.matchRegex
+import at.hannibal2.skyhanni.utils.StringUtils.matches
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class CurrentPetDisplay {
+ private val config get() = SkyHanniMod.feature.misc.pets
// TODO USE SH-REPO
- private val inventoryNamePattern = "(?:\\(\\d+/\\d+\\))? Pets".toPattern()
+ private val inventoryNamePattern = "Pets( \\(\\d+/\\d+\\) )?".toPattern()
+ private val inventorySelectedPetPattern = "§7§7Selected pet: (?<pet>.*)".toPattern()
+ private val chatSpawnPattern = "§aYou summoned your §r(?<pet>.*)§r§a!".toPattern()
+ private val chatDespawnPattern = "§aYou despawned your §r.*§r§a!".toPattern()
+ private val chatPetRulePattern = "§cAutopet §eequipped your §7\\[Lvl .*] (?<pet>.*)! §a§lVIEW RULE".toPattern()
@SubscribeEvent
fun onChatMessage(event: LorenzChatEvent) {
- val message = event.message
- val config = ProfileStorageData.profileSpecific ?: return
- var blocked = false
- if (message.matchRegex("§cAutopet §eequipped your §7(.*)§e! §a§lVIEW RULE")) {
- config.currentPet = message.between("] ", "§e!")
- blocked = true
+ findPetInChat(event.message)?.let {
+ PetAPI.currentPet = it
+ if (config.display) {
+ event.blockedReason = "pets"
+ }
}
+ }
- if (!LorenzUtils.inSkyBlock) return
-
- if (message.matchRegex("§aYou summoned your §r(.*)§r§a!")) {
- config.currentPet = message.between("your §r", "§r§a")
- blocked = true
+ private fun findPetInChat(message: String): String? {
+ chatSpawnPattern.matchMatcher(message) {
+ return group("pet")
}
- if (message.matchRegex("§aYou despawned your §r(.*)§r§a!")) {
- config.currentPet = ""
- blocked = true
+ if (chatDespawnPattern.matches(message)) {
+ return ""
}
-
- if (blocked && SkyHanniMod.feature.misc.pets.display) {
- event.blockedReason = "pets"
+ chatPetRulePattern.matchMatcher(message) {
+ return group("pet")
}
+
+ return null
}
@SubscribeEvent
fun onInventoryOpen(event: InventoryFullyOpenedEvent) {
- val config = ProfileStorageData.profileSpecific ?: return
- if (!inventoryNamePattern.matcher(event.inventoryName).matches()) return
+ if (!inventoryNamePattern.matches(event.inventoryName)) return
val lore = event.inventoryItems[4]?.getLore() ?: return
- val selectedPetPattern = "§7§7Selected pet: (?<pet>.*)".toPattern()
for (line in lore) {
- selectedPetPattern.matchMatcher(line) {
+ inventorySelectedPetPattern.matchMatcher(line) {
val newPet = group("pet")
- config.currentPet = if (newPet != "§cNone") newPet else ""
+ PetAPI.currentPet = if (newPet != "§cNone") newPet else ""
}
}
}
@@ -66,14 +66,14 @@ class CurrentPetDisplay {
if (!LorenzUtils.inSkyBlock) return
if (RiftAPI.inRift()) return
- if (!SkyHanniMod.feature.misc.pets.display) return
- val config = ProfileStorageData.profileSpecific ?: return
+ if (!config.display) return
- SkyHanniMod.feature.misc.petDisplayPos.renderString(config.currentPet, posLabel = "Current Pet")
+ config.displayPos.renderString(PetAPI.currentPet, posLabel = "Current Pet")
}
@SubscribeEvent
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
event.move(3, "misc.petDisplay", "misc.pets.display")
+ event.move(9, "misc.petDisplayPos", "misc.pets.displayPos")
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/FandomWikiFromMenus.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/FandomWikiFromMenus.kt
index 44d4b94ed..dbc3725bf 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/FandomWikiFromMenus.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/FandomWikiFromMenus.kt
@@ -8,7 +8,6 @@ import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.ItemUtils.nameWithEnchantment
import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.LorenzUtils.anyContains
import at.hannibal2.skyhanni.utils.OSUtils
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import io.github.moulberry.notenoughupdates.events.SlotClickEvent
@@ -43,7 +42,7 @@ class FandomWikiFromMenus {
val inWikiInventory = // TODO better name for this inventory
event.slotId == 11 && itemClickedName.contains("Wiki Command") && chestName.contains("Wiki")
if ((itemInHandName == "") || inWikiInventory) {
- LorenzUtils.clickableChat("§e[SkyHanni] Click here to visit the Hypixel Skyblock Fandom Wiki!", "wiki")
+ LorenzUtils.clickableChat("Click here to visit the Hypixel Skyblock Fandom Wiki!", "wiki")
return
}
@@ -56,8 +55,8 @@ class FandomWikiFromMenus {
} else {
//.lowercase() to match "Wiki!" and ".*wiki.*" lore lines in one fell swoop
val inThirdWikiInventory = // TODO better name for this inventory
- (itemClickedStack.getLore().anyContains("Wiki") || itemClickedStack.getLore().anyContains("wiki"))
- && !itemClickedStack.getLore().anyContains("wikipedia")
+ (itemClickedStack.getLore()
+ .let { it.any { line -> line == "§7§eClick to view on the SkyBlock" } && it.last() == "§eWiki!" })
if (inThirdWikiInventory) {
wikiDisplayName = itemClickedName.removeColor().replace("✔ ", "").replace("✖ ", "")
wikiInternalName = wikiDisplayName
@@ -66,11 +65,11 @@ class FandomWikiFromMenus {
if (!config.skipWikiChat) {
LorenzUtils.clickableChat(
- "§e[SkyHanni] Click here to search for $wikiDisplayName §eon the Hypixel Skyblock Fandom Wiki!",
+ "Click here to search for $wikiDisplayName §eon the Hypixel Skyblock Fandom Wiki!",
"wiki $wikiInternalName"
)
} else {
- LorenzUtils.chat("§e[SkyHanni] Searching the Fandom Wiki for §a$wikiDisplayName")
+ LorenzUtils.chat("Searching the Fandom Wiki for §a$wikiDisplayName")
val wikiUrlCustom = "${WikiManager.urlSearchPrefix}$wikiInternalName&scope=internal"
OSUtils.openBrowser(wikiUrlCustom.replace(' ', '+'))
}
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 7afbf475c..8f3920844 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/FixNEUHeavyPearls.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/FixNEUHeavyPearls.kt
@@ -20,7 +20,7 @@ class FixNEUHeavyPearls {
if (change.internalName == heavyPearl && change.delta == 3) {
val specific = NotEnoughUpdates.INSTANCE.config.getProfileSpecific()
if (System.currentTimeMillis() > specific.dailyHeavyPearlCompleted + 1.hours.inWholeMilliseconds) {
- LorenzUtils.chat("§e[SkyHanni] Mark NEU Heavy Pearls as done.")
+ 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 028b0edbc..5bacfd047 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/InGameDateDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/InGameDateDisplay.kt
@@ -1,30 +1,70 @@
package at.hannibal2.skyhanni.features.misc
import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.ScoreboardData
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
+import at.hannibal2.skyhanni.events.RepositoryReloadEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
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 io.github.moulberry.notenoughupdates.util.SkyBlockTime
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class InGameDateDisplay {
- private val config get() = SkyHanniMod.feature.gui.inGameDateConfig
+ private val config get() = SkyHanniMod.feature.gui.inGameDate
+ private val monthAndDatePattern =
+ ".*((Early|Late) )?(Winter|Spring|Summer|Autumn) [0-9]{1,2}(nd|rd|th|st)?.*".toPattern()
private var display = ""
+ // sun, moon, spooky
+ private var sunMoonIcons = emptyList<String>()
+
+ @SubscribeEvent
+ fun onRepoReload(event: RepositoryReloadEvent) {
+ sunMoonIcons = event.getConstant<TabListJson>("TabList").sun_moon_symbols
+ }
+
@SubscribeEvent
fun onTick(event: LorenzTickEvent) {
if (!isEnabled()) return
- if (!event.repeatSeconds(config.RefreshSeconds)) return
+ if (!config.useScoreboard && !event.repeatSeconds(config.refreshSeconds)) return
+ if (config.useScoreboard && !event.repeatSeconds(1)) return
checkDate()
}
private fun checkDate() {
- display = SkyBlockTime.now().formatted()
+ val date = SkyBlockTime.now()
+ var theBaseString: String
+ if (config.useScoreboard) {
+ val list = ScoreboardData.sidebarLinesFormatted //we need this to grab the moon/sun symbol
+ val year = "Year ${date.year}"
+ var monthAndDate = (list.find { monthAndDatePattern.matches(it) } ?: "??").trim()
+ if (monthAndDate.last().isDigit()) {
+ monthAndDate = "${monthAndDate}${SkyBlockTime.daySuffix(monthAndDate.takeLast(2).trim().toInt())}"
+ }
+ val time = list.find { it.lowercase().contains("am ") || it.lowercase().contains("pm ") } ?: "??"
+ theBaseString = "$monthAndDate, $year ${time.trim()}".removeColor()
+ if (!config.includeSunMoon) {
+ sunMoonIcons.forEach { theBaseString = theBaseString.replace(it, "") }
+ }
+ } else {
+ theBaseString = date.formatted()
+ if (config.includeSunMoon) {
+ theBaseString = if ((date.hour >= 6) && (date.hour < 17)) "$theBaseString ☀"
+ else "$theBaseString ☽"
+ }
+ }
+ if (!config.includeOrdinal) theBaseString = theBaseString.removeOrdinal()
+ display = theBaseString
}
+ private fun String.removeOrdinal() = replace("nd", "").replace("rd", "").replace("st", "").replace("th", "")
+
@SubscribeEvent
fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
if (!isEnabled()) return
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/JoinCrystalHollows.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/JoinCrystalHollows.kt
index 8b7114127..4064ed341 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/JoinCrystalHollows.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/JoinCrystalHollows.kt
@@ -24,13 +24,13 @@ class JoinCrystalHollows {
if (message == "§cYou do not have an active Crystal Hollows pass!") {
lastWrongPassTime = System.currentTimeMillis()
if (LorenzUtils.skyBlockIsland != IslandType.DWARVEN_MINES) {
- LorenzUtils.clickableChat("§e[SkyHanni] Click here to warp to Dwarven Mines!", "warp mines")
+ LorenzUtils.clickableChat("Click here to warp to Dwarven Mines!", "warp mines")
} else {
- LorenzUtils.chat("§e[SkyHanni] Buy a §2Crystal Hollows Pass §efrom §5Gwendolyn")
+ LorenzUtils.chat("Buy a §2Crystal Hollows Pass §efrom §5Gwendolyn")
}
}
if (message == "§e[NPC] §5Gwendolyn§f: §rGreat! Now hop on into the Minecart and I'll get you on your way!" && inTime()) {
- LorenzUtils.clickableChat("§e[SkyHanni] Click here to warp to Crystal Hollows!", "warp ch")
+ LorenzUtils.clickableChat("Click here to warp to Crystal Hollows!", "warp ch")
}
}
@@ -39,7 +39,7 @@ class JoinCrystalHollows {
if (!isEnabled()) return
if (event.newIsland == IslandType.DWARVEN_MINES && inTime()) {
- LorenzUtils.chat("§e[SkyHanni] Buy a §2Crystal Hollows Pass §efrom §5Gwendolyn§e!")
+ LorenzUtils.chat("Buy a §2Crystal Hollows Pass §efrom §5Gwendolyn§e!")
}
if (event.newIsland == IslandType.CRYSTAL_HOLLOWS) {
lastWrongPassTime = 0
@@ -62,4 +62,4 @@ class JoinCrystalHollows {
private fun inTime() = lastWrongPassTime + 1000 * 60 * 2 > System.currentTimeMillis()
fun isEnabled() = SkyHanniMod.feature.misc.crystalHollowsJoin
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/LimboTimeTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/LimboTimeTracker.kt
index 4aed71557..cc88ae4d1 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/LimboTimeTracker.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/LimboTimeTracker.kt
@@ -49,8 +49,8 @@ class LimboTimeTracker {
if (!isEnabled()) return
val passedSince = limboJoinTime.passedSince()
val duration = passedSince.format()
- LorenzUtils.run { chat("§e[SkyHanni] You left the limbo after §b$duration") }
+ LorenzUtils.run { chat("You left the limbo after §b$duration") }
}
fun isEnabled() = config.showTimeInLimbo
-} \ No newline at end of file
+}
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 8873c7402..14b430d19 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/LockMouseLook.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/LockMouseLook.kt
@@ -1,36 +1,49 @@
-package at.hannibal2.skyhanni.features.misc
-
-import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import net.minecraft.client.Minecraft
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-
-object LockMouseLook {
- private var lockedMouse = false
- private var oldSensitivity = 0F
- private val lockedPosition = -1F / 3F
-
- @SubscribeEvent
- fun onWorldChange(event: LorenzWorldChangeEvent) {
- if (lockedMouse) toggleLock()
- val gameSettings = Minecraft.getMinecraft().gameSettings
- if (gameSettings.mouseSensitivity == lockedPosition) {
- gameSettings.mouseSensitivity = 0.5f
- LorenzUtils.chat("§e[SkyHanni] §bReset your mouse sensitivity to 100%.")
- }
- }
-
- fun toggleLock() {
- lockedMouse = !lockedMouse
-
- val gameSettings = Minecraft.getMinecraft().gameSettings
- if (lockedMouse) {
- oldSensitivity = gameSettings.mouseSensitivity
- gameSettings.mouseSensitivity = lockedPosition
- LorenzUtils.chat("§e[SkyHanni] §bMouse rotation is now locked. Type /shmouselock to unlock your rotation")
- } else {
- gameSettings.mouseSensitivity = oldSensitivity
- LorenzUtils.chat("§e[SkyHanni] §bMouse rotation is now unlocked.")
- }
- }
-}
+package at.hannibal2.skyhanni.features.misc
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.events.GuiRenderEvent
+import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.RenderUtils.renderString
+import net.minecraft.client.Minecraft
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+object LockMouseLook {
+ private val config get() = SkyHanniMod.feature.misc
+ private var lockedMouse = false
+ private const val lockedPosition = -1F / 3F
+
+ @SubscribeEvent
+ fun onWorldChange(event: LorenzWorldChangeEvent) {
+ if (lockedMouse) toggleLock()
+ val gameSettings = Minecraft.getMinecraft().gameSettings
+ if (gameSettings.mouseSensitivity == lockedPosition) {
+ gameSettings.mouseSensitivity = SkyHanniMod.feature.storage.savedMouseSensitivity
+ LorenzUtils.chat("§bMouse rotation is now unlocked because you left it locked.")
+ }
+ }
+
+ fun toggleLock() {
+ val gameSettings = Minecraft.getMinecraft().gameSettings ?: return
+ lockedMouse = !lockedMouse
+
+ if (lockedMouse) {
+ SkyHanniMod.feature.storage.savedMouseSensitivity = gameSettings.mouseSensitivity
+ gameSettings.mouseSensitivity = lockedPosition
+ if (config.lockMouseLookChatMessage) {
+ LorenzUtils.chat("§bMouse rotation is now locked. Type /shmouselock to unlock your rotation")
+ }
+ } else {
+ gameSettings.mouseSensitivity = SkyHanniMod.feature.storage.savedMouseSensitivity
+ if (config.lockMouseLookChatMessage) {
+ LorenzUtils.chat("§bMouse rotation is now unlocked.")
+ }
+ }
+ }
+
+ @SubscribeEvent
+ fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
+ if (!lockedMouse) return
+ config.lockedMouseDisplay.renderString("§eMouse Locked", posLabel = "Mouse Locked")
+ }
+}
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 94ba46efd..66e379747 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/MarkedPlayerManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/MarkedPlayerManager.kt
@@ -22,7 +22,7 @@ class MarkedPlayerManager {
fun command(args: Array<String>) {
if (args.size != 1) {
- LorenzUtils.chat("§cUsage: /shmarkplayer <name>")
+ LorenzUtils.userError("Usage: /shmarkplayer <name>")
return
}
@@ -31,18 +31,18 @@ class MarkedPlayerManager {
if (name == LorenzUtils.getPlayerName().lowercase()) {
- LorenzUtils.chat("§c[SkyHanni] You can't add or remove yourself this way! Go to the settings and toggle 'Mark your own name'.")
+ LorenzUtils.userError("You can't add or remove yourself this way! Go to the settings and toggle 'Mark your own name'.")
return
}
if (name !in playerNamesToMark) {
playerNamesToMark.add(name)
findPlayers()
- LorenzUtils.chat("§e[SkyHanni] §aMarked §eplayer §b$displayName§e!")
+ LorenzUtils.chat("§aMarked §eplayer §b$displayName§e!")
} else {
playerNamesToMark.remove(name)
markedPlayers.remove(name)
- LorenzUtils.chat("§e[SkyHanni] §cUnmarked §eplayer §b$displayName§e!")
+ LorenzUtils.chat("§cUnmarked §eplayer §b$displayName§e!")
}
}
@@ -119,4 +119,4 @@ class MarkedPlayerManager {
}
}
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/MiscFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/MiscFeatures.kt
index 0d164b477..3b52ee478 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/MiscFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/MiscFeatures.kt
@@ -11,7 +11,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
/**
* I need these features in my dev env
- */
+ */
class MiscFeatures {
@SubscribeEvent
@@ -32,6 +32,7 @@ class MiscFeatures {
EnumParticleTypes.EXPLOSION_HUGE,
EnumParticleTypes.EXPLOSION_NORMAL,
-> event.isCanceled = true
+
else -> {}
}
}
@@ -50,4 +51,4 @@ class MiscFeatures {
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
event.move(2, "mobs", "combat.mobs")
}
-} \ No newline at end of file
+}
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 f4ce726f4..80c3b870d 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/NonGodPotEffectDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/NonGodPotEffectDisplay.kt
@@ -58,6 +58,7 @@ class NonGodPotEffectDisplay {
GREAT_SPOOK("§fGreat Spook I", inventoryItemName = "§fGreat Spook Potion"),
;
}
+
// TODO USE SH-REPO
private var patternEffectsCount = "§7You have §e(?<name>\\d+) §7non-god effects\\.".toPattern()
private var totalEffectsCount = 0
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/PetCandyUsedDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/PetCandyUsedDisplay.kt
index 351e3123d..87def5df3 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/PetCandyUsedDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/PetCandyUsedDisplay.kt
@@ -15,7 +15,6 @@ class PetCandyUsedDisplay {
if (!LorenzUtils.inSkyBlock || stack.stackSize != 1) return
if (!SkyHanniMod.feature.misc.petCandyUsed) return
-
val petCandyUsed = stack.getPetCandyUsed() ?: return
if (petCandyUsed == 0) return
@@ -25,4 +24,4 @@ class PetCandyUsedDisplay {
event.drawSlotText(x, y, stackTip, .9f)
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/PetExpTooltip.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/PetExpTooltip.kt
index 010b2530d..cfb679c30 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/PetExpTooltip.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/PetExpTooltip.kt
@@ -2,7 +2,9 @@ package at.hannibal2.skyhanni.features.misc
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
+import at.hannibal2.skyhanni.test.command.ErrorManager
import at.hannibal2.skyhanni.utils.ItemUtils.getItemRarityOrNull
+import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.KeyboardManager
import at.hannibal2.skyhanni.utils.LorenzRarity
@@ -33,23 +35,38 @@ class PetExpTooltip {
val itemStack = event.itemStack ?: return
val petExperience = itemStack.getPetExp()?.round(1) ?: return
val name = itemStack.name ?: return
-
- val index = findIndex(event.toolTip) ?: return
-
- val (maxLevel, maxXp) = getMaxValues(name, petExperience)
-
- val percentage = petExperience / maxXp
- val percentageFormat = LorenzUtils.formatPercentage(percentage)
-
- event.toolTip.add(index, " ")
- if (percentage >= 1) {
- event.toolTip.add(index, "§7Total experience: §e${NumberUtil.format(petExperience)}")
- } else {
- val progressBar = StringUtils.progressBar(percentage)
- val isBelowLegendary = itemStack.getItemRarityOrNull()?.let { it < LorenzRarity.LEGENDARY } ?: false
- val addLegendaryColor = if (isBelowLegendary) "§6" else ""
- event.toolTip.add(index, "$progressBar §e${petExperience.addSeparators()}§6/§e${NumberUtil.format(maxXp)}")
- event.toolTip.add(index, "§7Progress to ${addLegendaryColor}Level $maxLevel: §e$percentageFormat")
+ try {
+
+ val index = findIndex(event.toolTip) ?: return
+
+ val (maxLevel, maxXp) = getMaxValues(name, petExperience)
+
+ val percentage = petExperience / maxXp
+ val percentageFormat = LorenzUtils.formatPercentage(percentage)
+
+ event.toolTip.add(index, " ")
+ if (percentage >= 1) {
+ event.toolTip.add(index, "§7Total experience: §e${NumberUtil.format(petExperience)}")
+ } else {
+ val progressBar = StringUtils.progressBar(percentage)
+ val isBelowLegendary = itemStack.getItemRarityOrNull()?.let { it < LorenzRarity.LEGENDARY } ?: false
+ val addLegendaryColor = if (isBelowLegendary) "§6" else ""
+ event.toolTip.add(
+ index,
+ "$progressBar §e${petExperience.addSeparators()}§6/§e${NumberUtil.format(maxXp)}"
+ )
+ event.toolTip.add(index, "§7Progress to ${addLegendaryColor}Level $maxLevel: §e$percentageFormat")
+ }
+ } catch (e: Exception) {
+ ErrorManager.logErrorWithData(
+ e, "Could not add pet exp tooltip",
+ "itemStack" to itemStack,
+ "item name" to name,
+ "petExperience" to petExperience,
+ "toolTip" to event.toolTip,
+ "index" to findIndex(event.toolTip),
+ "getLore" to itemStack.getLore(),
+ )
}
}
@@ -100,6 +117,10 @@ class PetExpTooltip {
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
event.move(3, "misc.petExperienceToolTip.petDisplay", "misc.pets.petExperienceToolTip.petDisplay")
event.move(3, "misc.petExperienceToolTip.showAlways", "misc.pets.petExperienceToolTip.showAlways")
- event.move(3, "misc.petExperienceToolTip.showGoldenDragonEgg", "misc.pets.petExperienceToolTip.showGoldenDragonEgg")
+ event.move(
+ 3,
+ "misc.petExperienceToolTip.showGoldenDragonEgg",
+ "misc.pets.petExperienceToolTip.showGoldenDragonEgg"
+ )
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/PlayerChatSymbols.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/PlayerChatSymbols.kt
index c3d45ccee..5133e65be 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/PlayerChatSymbols.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/PlayerChatSymbols.kt
@@ -72,13 +72,15 @@ class PlayerChatSymbols {
if (!component.text_skyhanni().contains(rankAndName)) return false
val oldText = component.text_skyhanni()
- component.setText_skyhanni(component.text_skyhanni().replace(oldText, getNewText(emblemText, oldText, rankAndName)))
+ val newText = getNewText(emblemText, oldText, rankAndName)
+ component.setText_skyhanni(component.text_skyhanni().replace(oldText, newText))
return true
}
- private fun getNewText(emblemText: String, oldText: String, rankAndName: String): String = when (config.symbolLocation) {
- 0 -> oldText.replace(rankAndName, "$emblemText $rankAndName")
- 1 -> oldText.replace(rankAndName, "$rankAndName $emblemText ")
- else -> oldText
- }
-} \ No newline at end of file
+ private fun getNewText(emblemText: String, oldText: String, rankAndName: String): String =
+ when (config.symbolLocation) {
+ 0 -> oldText.replace(rankAndName, "$emblemText $rankAndName")
+ 1 -> oldText.replace(rankAndName, "$rankAndName $emblemText ")
+ else -> oldText
+ }
+}
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 2890e8593..9b6987fad 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/QuickModMenuSwitch.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/QuickModMenuSwitch.kt
@@ -52,7 +52,7 @@ object QuickModMenuSwitch {
}
}
- class Mod(val name: String, val description: List<String>, val command: String, val guiPath: List<String>) {
+ class Mod(val name: String, val description: List<String>, val command: String, private val guiPath: List<String>) {
fun isInGui() = guiPath.any { latestGuiPath.startsWith(it) }
}
@@ -152,7 +152,7 @@ object QuickModMenuSwitch {
} catch (_: Exception) {
}
}
- LorenzUtils.chat("§c[SkyHanni] Error trying to open the gui for mod " + mod.name + "!")
+ LorenzUtils.error("Error trying to open the gui for mod " + mod.name + "!")
}
"hytil" -> {
@@ -168,7 +168,7 @@ object QuickModMenuSwitch {
} catch (_: Exception) {
}
}
- LorenzUtils.chat("§c[SkyHanni] Error trying to open the gui for mod " + mod.name + "!")
+ LorenzUtils.chat("Error trying to open the gui for mod " + mod.name + "!")
}
else -> {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/SkyBlockKickDuration.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/SkyBlockKickDuration.kt
index d536b8f53..7ca34eafb 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/SkyBlockKickDuration.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/SkyBlockKickDuration.kt
@@ -16,10 +16,10 @@ import kotlin.time.Duration.Companion.seconds
class SkyBlockKickDuration {
private val config get() = SkyHanniMod.feature.misc.kickDuration
- var kickMessage = false
- var showTime = false
- var lastKickTime = SimpleTimeMark.farPast()
- var hasWarned = false
+ private var kickMessage = false
+ private var showTime = false
+ private var lastKickTime = SimpleTimeMark.farPast()
+ private var hasWarned = false
@SubscribeEvent
fun onChat(event: LorenzChatEvent) {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/SuperpairsClicksAlert.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/SuperpairsClicksAlert.kt
index c8882a1b8..6ca018c9f 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/SuperpairsClicksAlert.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/SuperpairsClicksAlert.kt
@@ -43,17 +43,17 @@ class SuperpairsClicksAlert {
if ( // checks if we have succeeded in either minigame
(event.inventoryName.contains("Chronomatron")
- && ((event.inventoryItems[4]?.displayName?.removeColor()
+ && ((event.inventoryItems[4]?.displayName?.removeColor()
?.let { currentRoundRegex.find(it) }
?.groups?.get(1)?.value?.toInt() ?: -1) > roundsNeeded))
|| (event.inventoryName.contains("Ultrasequencer")
- && event.inventoryItems.entries
+ && event.inventoryItems.entries
.filter { it.key < 45 }
.any { it.value.stackSize > roundsNeeded })
) {
SoundUtils.playBeepSound()
- LorenzUtils.chat("§e[SkyHanni] You have reached the maximum possible clicks!")
+ LorenzUtils.chat("You have reached the maximum possible clicks!")
roundsNeeded = -1
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/TimeFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/TimeFeatures.kt
index bcee7863f..4298edf21 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/TimeFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/TimeFeatures.kt
@@ -32,7 +32,8 @@ class TimeFeatures {
if (!LorenzUtils.inSkyBlock) return
if (config.realTime) {
- val currentTime = (if (config.realTimeFormatToggle) timeFormat12h else timeFormat24h).format(System.currentTimeMillis())
+ val currentTime =
+ (if (config.realTimeFormatToggle) timeFormat12h else timeFormat24h).format(System.currentTimeMillis())
config.realTimePosition.renderString(currentTime, posLabel = "Real Time")
}
@@ -56,4 +57,4 @@ class TimeFeatures {
event.move(2, "misc.timeConfigs.realTime", "gui.realTime")
event.move(2, "misc.timeConfigs.realTimePos", "gui.realTimePosition")
}
-} \ No newline at end of file
+}
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 05cb64605..7c96f4efa 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
@@ -24,7 +24,7 @@ object AdvancedPlayerList {
private val config get() = SkyHanniMod.feature.misc.compactTabList.advancedPlayerList
// TODO USE SH-REPO
- private val pattern = ".*\\[(?<level>.*)] (?<name>.*)".toPattern()
+ private val pattern = ".*\\[(?<level>.*)] §r(?<name>.*)".toPattern()
private var playerDatas = mutableMapOf<String, PlayerData>()
@@ -59,15 +59,21 @@ object AdvancedPlayerList {
val playerData = PlayerData(removeColor.toInt())
currentData[line] = playerData
+ var index = 0
val fullName = group("name")
+ if (fullName.contains("[")) index++
val name = fullName.split(" ")
- val coloredName = name[0]
- playerData.coloredName = coloredName
+ val coloredName = name[index]
+ if (index == 1) {
+ playerData.coloredName = name[0] + " " + coloredName
+ } else {
+ playerData.coloredName = coloredName
+ }
playerData.name = coloredName.removeColor()
playerData.levelText = levelText
- if (name.size > 1) {
- val nameSuffix = name.drop(1).joinToString(" ")
- playerData.nameSuffix = nameSuffix
+ index++
+ if (name.size > index) {
+ var nameSuffix = name.drop(index).joinToString(" ")
if (nameSuffix.contains("♲")) {
playerData.ironman = true
} else {
@@ -75,13 +81,16 @@ object AdvancedPlayerList {
}
if (IslandType.CRIMSON_ISLE.isInIsland()) {
playerData.faction = if (line.contains("§c⚒")) {
+ nameSuffix = nameSuffix.replace("§c⚒", "")
CrimsonIsleFaction.BARBARIAN
} else if (line.contains("§5ቾ")) {
+ nameSuffix = nameSuffix.replace("§5ቾ", "")
CrimsonIsleFaction.MAGE
} else {
CrimsonIsleFaction.NONE
}
}
+ playerData.nameSuffix = nameSuffix
} else {
playerData.nameSuffix = ""
}
@@ -161,7 +170,7 @@ object AdvancedPlayerList {
suffix += " " + getSocialScoreIcon(score)
}
if (config.markSkyHanniContributors && data.name in contributors) {
- suffix += " §c:O"
+ suffix += "§c:O"
}
if (IslandType.CRIMSON_ISLE.isInIsland() && !config.hideFactions) {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/TabListReader.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/TabListReader.kt
index 3f7f537ed..a81205ce7 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/TabListReader.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/TabListReader.kt
@@ -13,6 +13,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
// heavily inspired by SBA code
object TabListReader {
private val config get() = SkyHanniMod.feature.misc.compactTabList
+
// TODO USE SH-REPO
var hypixelAdvertisingString = "HYPIXEL.NET"
private val godPotPattern = "You have a God Potion active! (?<timer>[\\w ]+)".toPattern()
@@ -221,4 +222,4 @@ object TabListReader {
}
}
}
-} \ No newline at end of file
+}
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 31ad1cef8..e358b3f28 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
@@ -9,6 +9,7 @@ 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.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.onToggle
import at.hannibal2.skyhanni.utils.SimpleTimeMark
@@ -58,11 +59,11 @@ object DiscordRPCManager : IPCListener {
try {
client?.connect()
- if (fromCommand) LorenzUtils.chat("§a[SkyHanni] Successfully started Rich Presence!") // confirm that /shrpcstart worked
+ if (fromCommand) LorenzUtils.chat("Successfully started Rich Presence!", prefixColor = "§a") // confirm that /shrpcstart worked
} catch (ex: Exception) {
consoleLog("Warn: Failed to connect to RPC!")
consoleLog(ex.toString())
- LorenzUtils.clickableChat("§e[SkyHanni] Discord Rich Presence was unable to start! " +
+ LorenzUtils.clickableChat("Discord Rich Presence was unable to start! " +
"This usually happens when you join SkyBlock when Discord is not started. " +
"Please run /shrpcstart to retry once you have launched Discord.", "shrpcstart")
}
@@ -183,20 +184,23 @@ object DiscordRPCManager : IPCListener {
fun startCommand() {
if (!config.enabled.get()) {
- LorenzUtils.chat("§c[SkyHanni] Discord Rich Presence is disabled. Enable it in the config §e/sh discord")
+ LorenzUtils.userError("Discord Rich Presence is disabled. Enable it in the config §e/sh discord")
return
}
if (isActive()) {
- LorenzUtils.chat("§e[SkyHanni] Discord Rich Presence is already active!")
+ LorenzUtils.userError("Discord Rich Presence is already active!")
return
}
- LorenzUtils.chat("§e[SkyHanni] Attempting to start Discord Rich Presence...")
+ LorenzUtils.chat("Attempting to start Discord Rich Presence...")
try {
start(true)
} catch (e: Exception) {
- LorenzUtils.chat("§c[SkyHanni] Unable to start Discord Rich Presence! Please report this on Discord and ping @netheriteminer.")
+ ErrorManager.logError(
+ e,
+ "Unable to start Discord Rich Presence! Please report this on Discord and ping @netheriteminer."
+ )
}
}
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 9937ff288..141870585 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
@@ -10,7 +10,7 @@ import at.hannibal2.skyhanni.data.GardenCropMilestones.isMaxed
import at.hannibal2.skyhanni.data.GardenCropMilestones.progressToNextLevel
import at.hannibal2.skyhanni.data.HypixelData
import at.hannibal2.skyhanni.data.IslandType
-import at.hannibal2.skyhanni.data.ProfileStorageData
+import at.hannibal2.skyhanni.data.PetAPI
import at.hannibal2.skyhanni.data.ScoreboardData
import at.hannibal2.skyhanni.features.dungeon.DungeonAPI
import at.hannibal2.skyhanni.features.garden.GardenAPI.getCropType
@@ -289,7 +289,7 @@ enum class DiscordStatus(private val displayMessageSupplier: Supplier<String>?)
}),
PETS({
- ProfileStorageData.profileSpecific?.currentPet?.let {
+ PetAPI.currentPet?.let {
val colorCode = it.substring(1..2).first()
val petName = it.substring(2)
val petLevel = getCurrentPet()?.petLevel?.currentLevel ?: "?"
@@ -371,8 +371,10 @@ enum class DiscordStatus(private val displayMessageSupplier: Supplier<String>?)
}),
AFK({
- if (beenAfkFor.passedSince() > 5.minutes) "AFK for ${beenAfkFor.passedSince().format(maxUnits = 1, longName = true)}"
- else AutoStatus.AFK.placeholderText
+ if (beenAfkFor.passedSince() > 5.minutes) {
+ val format = beenAfkFor.passedSince().format(maxUnits = 1, longName = true)
+ "AFK for $format"
+ } else AutoStatus.AFK.placeholderText
})
;
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 5671822cb..a4fe36fdc 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
@@ -7,69 +7,29 @@ import at.hannibal2.skyhanni.events.ConfigLoadEvent
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.InventoryCloseEvent
import at.hannibal2.skyhanni.events.RenderItemTooltipEvent
-import at.hannibal2.skyhanni.test.command.ErrorManager
-import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
+import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalNameOrNull
-import at.hannibal2.skyhanni.utils.ItemUtils.getItemName
-import at.hannibal2.skyhanni.utils.ItemUtils.getItemNameOrNull
-import at.hannibal2.skyhanni.utils.ItemUtils.getItemRarityOrNull
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.ItemUtils.name
-import at.hannibal2.skyhanni.utils.ItemUtils.nameWithEnchantment
import at.hannibal2.skyhanni.utils.KeyboardManager.isKeyHeld
-import at.hannibal2.skyhanni.utils.LorenzRarity
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
import at.hannibal2.skyhanni.utils.LorenzUtils.onToggle
-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.getItemStackOrNull
-import at.hannibal2.skyhanni.utils.NEUItems.getPrice
-import at.hannibal2.skyhanni.utils.NEUItems.getPriceOrNull
import at.hannibal2.skyhanni.utils.NEUItems.manager
import at.hannibal2.skyhanni.utils.NumberUtil
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.GemstoneSlotType
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getAbilityScrolls
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getArmorDye
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getAttributes
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getDrillUpgrades
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getDungeonStarCount
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getEnchantments
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getEnrichment
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getExtraAttributes
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getFarmingForDummiesCount
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getGemstones
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getHelmetSkin
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getHotPotatoCount
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getManaDisintegrators
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getPolarvoidBookCount
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getPowerScroll
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getReforgeName
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getRune
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getSilexCount
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getTransmissionTunerCount
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasArtOfPeace
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasArtOfWar
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasBookOfStats
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasEtherwarp
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasJalapenoBook
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasWoodSingularity
-import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.isRecombobulated
-import at.hannibal2.skyhanni.utils.StringUtils.firstLetterUppercase
-import at.hannibal2.skyhanni.utils.StringUtils.removeColor
-import com.google.gson.JsonObject
import com.google.gson.reflect.TypeToken
import io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent
-import io.github.moulberry.notenoughupdates.recipes.Ingredient
-import io.github.moulberry.notenoughupdates.util.Constants
+import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer
+import net.minecraft.client.Minecraft
import net.minecraft.init.Items
import net.minecraft.item.ItemStack
+import net.minecraftforge.event.entity.player.ItemTooltipEvent
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import java.io.File
-import java.util.Locale
import kotlin.math.roundToLong
object EstimatedItemValue {
@@ -77,7 +37,7 @@ object EstimatedItemValue {
private var display = emptyList<List<Any>>()
private val cache = mutableMapOf<ItemStack, List<List<Any>>>()
private var lastToolTipTime = 0L
- private var gemstoneUnlockCosts = HashMap<NEUInternalName, HashMap<String, List<String>>>()
+ var gemstoneUnlockCosts = HashMap<NEUInternalName, HashMap<String, List<String>>>()
var currentlyShowing = false
@SubscribeEvent
@@ -92,17 +52,48 @@ object EstimatedItemValue {
object : TypeToken<HashMap<NEUInternalName, HashMap<String, List<String>>>>() {}.type
)
else
- LorenzUtils.error("Gemstone Slot Unlock Costs failed to load")
+ LorenzUtils.error("Gemstone Slot Unlock Costs failed to load!")
}
@SubscribeEvent
- fun onRenderOverlay(event: GuiRenderEvent.ChestGuiOverlayRenderEvent) {
+ fun onTooltip(event: ItemTooltipEvent) {
+ if (!LorenzUtils.inSkyBlock) return
+ if (!config.enabled) return
+
+ if (Minecraft.getMinecraft().currentScreen is GuiProfileViewer) {
+ if (renderedItems == 0) {
+ updateItem(event.itemStack)
+ }
+ tryRendering()
+ renderedItems++
+ }
+ }
+
+ /**
+ * Workaround for NEU Profile Viewer bug where the ItemTooltipEvent gets called for two items when hovering
+ * over the border between two items.
+ * Also fixes complications with ChatTriggers where they call the stack.getToolTips() method that causes the
+ * ItemTooltipEvent to getting triggered multiple times per frame.
+ */
+ private var renderedItems = 0
+
+ @SubscribeEvent
+ fun onRenderOverlayGui(event: GuiRenderEvent.GuiOverlayRenderEvent) {
+ renderedItems = 0
+ }
+
+ private fun tryRendering() {
currentlyShowing = checkCurrentlyVisible()
if (!currentlyShowing) return
config.itemPriceDataPos.renderStringsAndItems(display, posLabel = "Estimated Item Value")
}
+ @SubscribeEvent
+ fun onRenderOverlay(event: GuiRenderEvent.ChestGuiOverlayRenderEvent) {
+ tryRendering()
+ }
+
private fun checkCurrentlyVisible(): Boolean {
if (!LorenzUtils.inSkyBlock) return false
if (!config.enabled) return false
@@ -119,7 +110,6 @@ object EstimatedItemValue {
cache.clear()
}
-
@SubscribeEvent
fun onConfigLoad(event: ConfigLoadEvent) {
config.enchantmentsCap.onToggle {
@@ -132,7 +122,10 @@ object EstimatedItemValue {
if (!LorenzUtils.inSkyBlock) return
if (!config.enabled) return
- val item = event.stack
+ updateItem(event.stack)
+ }
+
+ private fun updateItem(item: ItemStack) {
val oldData = cache[item]
if (oldData != null) {
display = oldData
@@ -140,6 +133,17 @@ object EstimatedItemValue {
return
}
+ if (InventoryUtils.openInventoryName().startsWith("Museum ")) {
+ if (item.getLore().any { it.contains("Armor Set") }) {
+ return
+ }
+ }
+
+ // 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) {
@@ -176,7 +180,7 @@ object EstimatedItemValue {
val list = mutableListOf<String>()
list.add("§aEstimated Item Value:")
- val pair = getEstimatedItemPrice(stack, list)
+ val pair = EstimatedItemValueCalculator.calculate(stack, list)
val (totalPrice, basePrice) = pair
if (basePrice == totalPrice) return listOf()
@@ -195,625 +199,6 @@ object EstimatedItemValue {
return newDisplay
}
- fun getEstimatedItemPrice(stack: ItemStack, list: MutableList<String>): Pair<Double, Double> {
- var totalPrice = 0.0
- val basePrice = addBaseItem(stack, list)
- totalPrice += basePrice
-
- totalPrice += addAttributeCost(stack, list)
-
- totalPrice += addReforgeStone(stack, list)
-
- // once
- totalPrice += addRecomb(stack, list)
- totalPrice += addArtOfWar(stack, list)
- totalPrice += addArtOfPiece(stack, list)
- totalPrice += addEtherwarp(stack, list)
- totalPrice += addPowerScrolls(stack, list)
- totalPrice += addWoodSingularity(stack, list)
- totalPrice += addJalapenoBook(stack, list)
- totalPrice += addStatsBook(stack, list)
- totalPrice += addEnrichment(stack, list)
-
- // counted
- totalPrice += addMasterStars(stack, list)
- totalPrice += addHotPotatoBooks(stack, list)
- totalPrice += addFarmingForDummies(stack, list)
- totalPrice += addSilex(stack, list)
- totalPrice += addTransmissionTuners(stack, list)
- totalPrice += addManaDisintegrators(stack, list)
- totalPrice += addPolarvoidBook(stack, list)
-
- // cosmetic
- totalPrice += addHelmetSkin(stack, list)
- totalPrice += addArmorDye(stack, list)
- totalPrice += addRune(stack, list)
-
- // dynamic
- totalPrice += addAbilityScrolls(stack, list)
- totalPrice += addDrillUpgrades(stack, list)
- totalPrice += addGemstoneSlotUnlockCost(stack, list)
- totalPrice += addGemstones(stack, list)
- totalPrice += addEnchantments(stack, list)
- return Pair(totalPrice, basePrice)
- }
-
- private fun addAttributeCost(stack: ItemStack, list: MutableList<String>): Double {
- val attributes = stack.getAttributes() ?: return 0.0
- var internalName = stack.getInternalName().asString().removePrefix("VANQUISHED_")
- val kuudraSets = listOf("AURORA", "CRIMSON", "TERROR", "HOLLOW")
- var genericName = internalName
- if (kuudraSets.any { internalName.contains(it) }
- && listOf("CHESTPLATE", "LEGGINGS", "HELMET", "BOOTS").any { internalName.endsWith(it) }) {
- for (prefix in listOf("HOT_", "BURNING_", "FIERY_", "INFERNAL_")) {
- internalName = internalName.removePrefix(prefix)
- }
- genericName = kuudraSets.fold(internalName) { acc, part -> acc.replace(part, "GENERIC_KUUDRA") }
- }
- if (internalName == "ATTRIBUTE_SHARD" && attributes.size == 1) {
- val price =
- getPriceOrCompositePriceForAttribute(
- "ATTRIBUTE_SHARD+ATTRIBUTE_" + attributes[0].first,
- attributes[0].second
- )
- if (price != null) {
- list.add(
- "§7Attribute §9${
- attributes[0].first.fixMending().split("_").joinToString(" ") { it.firstLetterUppercase() }
- } ${attributes[0].second}§7: (§6${NumberUtil.format(price)}§7)"
- )
- return price
- }
- }
- if (attributes.size != 2) return 0.0
- val basePrice = internalName.asInternalName().getPriceOrNull() ?: 0.0
- var subTotal = 0.0
- val combo = ("$internalName+ATTRIBUTE_${attributes[0].first}+ATTRIBUTE_${attributes[1].first}").asInternalName()
- val comboPrice = combo.getPriceOrNull()
- if (comboPrice != null && comboPrice > basePrice) {
- list.add("§7Attribute Combo: (§6${NumberUtil.format(comboPrice)}§7)")
- subTotal += comboPrice - basePrice
- } else {
- list.add("§7Attributes:")
- }
- for (attr in attributes) {
- val price =
- getPriceOrCompositePriceForAttribute("$genericName+ATTRIBUTE_${attr.first}", attr.second)
- if (price != null) {
- subTotal += price
- }
- val displayName = attr.first.fixMending()
- list.add(
- " §9${
- displayName.split("_").joinToString(" ") { it.firstLetterUppercase() }
- } ${attr.second}§7: §6${if (price != null) NumberUtil.format(price) else "Unknown"}"
- )
- }
- return subTotal
- }
-
- private fun String.fixMending() = if (this == "MENDING") "VITALITY" else this
-
- private fun getPriceOrCompositePriceForAttribute(attributeName: String, level: Int): Double? {
- return (1..10).mapNotNull { lowerLevel ->
- "$attributeName;$lowerLevel".asInternalName().getPriceOrNull()
- ?.let { it / (1 shl lowerLevel) * (1 shl level).toDouble() }
- }.minOrNull()
- }
-
- private fun addReforgeStone(stack: ItemStack, list: MutableList<String>): Double {
- val rawReforgeName = stack.getReforgeName() ?: return 0.0
-
- for ((rawInternalName, values) in Constants.REFORGESTONES.entrySet()) {
- val stoneJson = values.asJsonObject
- val reforgeName = stoneJson.get("reforgeName").asString
- if (rawReforgeName == reforgeName.lowercase() || rawReforgeName == rawInternalName.lowercase()) {
- val internalName = rawInternalName.asInternalName()
- val reforgeStonePrice = internalName.getPrice()
- val reforgeStoneName = internalName.getItemName()
-
- val reforgeCosts = stoneJson.get("reforgeCosts").asJsonObject
- val applyCost = getReforgeStoneApplyCost(stack, reforgeCosts, internalName) ?: return 0.0
-
- list.add("§7Reforge: §9$reforgeName")
- list.add(" §7Stone $reforgeStoneName §7(§6" + NumberUtil.format(reforgeStonePrice) + "§7)")
- list.add(" §7Apply cost: (§6" + NumberUtil.format(applyCost) + "§7)")
- return reforgeStonePrice + applyCost
- }
- }
-
- return 0.0
- }
-
- private fun getReforgeStoneApplyCost(
- stack: ItemStack,
- reforgeCosts: JsonObject,
- reforgeStone: NEUInternalName
- ): Int? {
- var itemRarity = stack.getItemRarityOrNull() ?: return null
-
- // Catch cases of special or very special
- if (itemRarity > LorenzRarity.MYTHIC) {
- itemRarity = LorenzRarity.LEGENDARY
- } else {
- if (stack.isRecombobulated()) {
- val oneBelow = itemRarity.oneBelow()
- if (oneBelow == null) {
- ErrorManager.logErrorState(
- "Wrong item rarity detected in estimated item value for item ${stack.name}",
- "Recombobulated item is common: ${stack.getInternalName()}, name:${stack.name}"
- )
- return null
- }
- itemRarity = oneBelow
- }
- }
- val rarityName = itemRarity.name
- if (!reforgeCosts.has(rarityName)) {
- val reforgesFound = reforgeCosts.entrySet().map { it.key }
- ErrorManager.logErrorState(
- "Can not calculate reforge cost for item ${stack.name}",
- "item rarity '$itemRarity' is not in NEU repo reforge cost for reforge stone$reforgeStone ($reforgesFound)"
- )
- return null
- }
-
- return reforgeCosts[rarityName].asInt
- }
-
- private fun addRecomb(stack: ItemStack, list: MutableList<String>): Double {
- if (!stack.isRecombobulated()) return 0.0
-
- val price = "RECOMBOBULATOR_3000".asInternalName().getPrice()
- list.add("§7Recombobulated: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
- return price
- }
-
- private fun addJalapenoBook(stack: ItemStack, list: MutableList<String>): Double {
- if (!stack.hasJalapenoBook()) return 0.0
-
- val price = "JALAPENO_BOOK".asInternalName().getPrice()
- list.add("§7Jalapeno Book: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
- return price
- }
-
- private fun addEtherwarp(stack: ItemStack, list: MutableList<String>): Double {
- if (!stack.hasEtherwarp()) return 0.0
-
- val wtfHardcodedConduit = "ETHERWARP_CONDUIT".asInternalName()
- val wtfHardcodedMerger = "ETHERWARP_MERGER".asInternalName()
- val price = wtfHardcodedConduit.getPrice() + wtfHardcodedMerger.getPrice()
- list.add("§7Etherwarp: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
- return price
- }
-
- private fun addWoodSingularity(stack: ItemStack, list: MutableList<String>): Double {
- if (!stack.hasWoodSingularity()) return 0.0
-
- val price = "WOOD_SINGULARITY".asInternalName().getPrice()
- list.add("§7Wood Singularity: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
- return price
- }
-
- private fun addArtOfWar(stack: ItemStack, list: MutableList<String>): Double {
- if (!stack.hasArtOfWar()) return 0.0
-
- val price = "THE_ART_OF_WAR".asInternalName().getPrice()
- list.add("§7The Art of War: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
- return price
- }
-
- private fun addStatsBook(stack: ItemStack, list: MutableList<String>): Double {
- if (!stack.hasBookOfStats()) return 0.0
-
- val price = "BOOK_OF_STATS".asInternalName().getPrice()
- list.add("§7Book of Stats: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
- return price
- }
-
- // TODO untested
- private fun addArtOfPiece(stack: ItemStack, list: MutableList<String>): Double {
- if (!stack.hasArtOfPeace()) return 0.0
-
- val price = "THE_ART_OF_PEACE".asInternalName().getPrice()
- list.add("§7The Art Of Piece: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
- return price
- }
-
- private fun addHotPotatoBooks(stack: ItemStack, list: MutableList<String>): Double {
- val count = stack.getHotPotatoCount() ?: return 0.0
-
- val hpb: Int
- val fuming: Int
- if (count <= 10) {
- hpb = count
- fuming = 0
- } else {
- hpb = 10
- fuming = count - 10
- }
-
- var totalPrice = 0.0
-
- val wtfHardcodedHpb = "HOT_POTATO_BOOK".asInternalName()
- val hpbPrice = wtfHardcodedHpb.getPrice() * hpb
- list.add("§7HPB's: §e$hpb§7/§e10 §7(§6" + NumberUtil.format(hpbPrice) + "§7)")
- totalPrice += hpbPrice
-
- if (fuming > 0) {
- val wtfHardcodedFuming = "FUMING_POTATO_BOOK".asInternalName()
- val fumingPrice = wtfHardcodedFuming.getPrice() * fuming
- list.add("§7Fuming: §e$fuming§7/§e5 §7(§6" + NumberUtil.format(fumingPrice) + "§7)")
- totalPrice += fumingPrice
- }
-
- return totalPrice
- }
-
- private fun addFarmingForDummies(stack: ItemStack, list: MutableList<String>): Double {
- val count = stack.getFarmingForDummiesCount() ?: return 0.0
-
- val wtfHardcodedDumbFarmers = "FARMING_FOR_DUMMIES".asInternalName()
- val price = wtfHardcodedDumbFarmers.getPrice() * count
- list.add("§7Farming for Dummies: §e$count§7/§e5 §7(§6" + NumberUtil.format(price) + "§7)")
- return price
- }
-
- private fun addPolarvoidBook(stack: ItemStack, list: MutableList<String>): Double {
- val count = stack.getPolarvoidBookCount() ?: return 0.0
-
- val broDilloMiningSoBad = "POLARVOID_BOOK".asInternalName()
- val price = broDilloMiningSoBad.getPrice() * count
- list.add("§7Polarvoid: §e$count§7/§e5 §7(§6" + NumberUtil.format(price) + "§7)")
- return price
- }
-
- private fun addSilex(stack: ItemStack, list: MutableList<String>): Double {
- val tier = stack.getSilexCount() ?: return 0.0
-
- val internalName = stack.getInternalName()
- val maxTier = if (internalName == "STONK_PICKAXE".asInternalName()) 4 else 5
-
- val wtfHardcodedSilex = "SIL_EX".asInternalName()
- val price = wtfHardcodedSilex.getPrice() * tier
- list.add("§7Silex: §e$tier§7/§e$maxTier §7(§6" + NumberUtil.format(price) + "§7)")
- return price
- }
-
- private fun addTransmissionTuners(stack: ItemStack, list: MutableList<String>): Double {
- val count = stack.getTransmissionTunerCount() ?: return 0.0
-
- val wtfHardcodedTuner = "TRANSMISSION_TUNER".asInternalName()
- val price = wtfHardcodedTuner.getPrice() * count
- list.add("§7Transmission Tuners: §e$count§7/§e4 §7(§6" + NumberUtil.format(price) + "§7)")
- return price
- }
-
- private fun addManaDisintegrators(stack: ItemStack, list: MutableList<String>): Double {
- val count = stack.getManaDisintegrators() ?: return 0.0
-
- val wtfHardcodedTuner = "MANA_DISINTEGRATOR".asInternalName()
- val price = wtfHardcodedTuner.getPrice() * count
- list.add("§7Mana Disintegrators: §e$count§7/§e10 §7(§6" + NumberUtil.format(price) + "§7)")
- return price
- }
-
- private fun addMasterStars(stack: ItemStack, list: MutableList<String>): Double {
- val totalStars = stack.getDungeonStarCount() ?: return 0.0
-
- val masterStars = totalStars - 5
- if (masterStars < 1) return 0.0
-
- var price = 0.0
-
- val stars = mapOf(
- "FIRST" to 1,
- "SECOND" to 2,
- "THIRD" to 3,
- "FOURTH" to 4,
- "FIFTH" to 5,
- )
-
- for ((prefix, number) in stars) {
- if (masterStars >= number) {
- price += "${prefix}_MASTER_STAR".asInternalName().getPrice()
- }
- }
-
- list.add("§7Master Stars: §e$masterStars§7/§e5 §7(§6" + NumberUtil.format(price) + "§7)")
- return price
- }
-
- private fun addDrillUpgrades(stack: ItemStack, list: MutableList<String>): Double {
- val drillUpgrades = stack.getDrillUpgrades() ?: return 0.0
-
- var totalPrice = 0.0
- val map = mutableMapOf<String, Double>()
- for (internalName in drillUpgrades) {
- val name = internalName.getItemName()
- val price = internalName.getPriceOrNull() ?: continue
-
- totalPrice += price
- val format = NumberUtil.format(price)
- map[" $name §7(§6$format§7)"] = price
- }
- if (map.isNotEmpty()) {
- list.add("§7Drill upgrades: §6" + NumberUtil.format(totalPrice))
- list += map.sortedDesc().keys
- }
- return totalPrice
- }
-
- private fun addPowerScrolls(stack: ItemStack, list: MutableList<String>): Double {
- val internalName = stack.getPowerScroll() ?: return 0.0
-
- val price = internalName.getPrice()
- val name = internalName.getItemName().removeColor()
- list.add("§7$name: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
- return price
- }
-
- private fun addHelmetSkin(stack: ItemStack, list: MutableList<String>): Double {
- val internalName = stack.getHelmetSkin() ?: return 0.0
-
- val price = internalName.getPrice()
- val name = internalName.getNameOrRepoError()
- val displayname = name ?: "§c${internalName.asString()}"
- list.add("§7Skin: $displayname §7(§6" + NumberUtil.format(price) + "§7)")
- if (name == null) {
- list.add(" §8(Not yet in NEU Repo)")
- }
- return price
- }
-
- private fun addArmorDye(stack: ItemStack, list: MutableList<String>): Double {
- val internalName = stack.getArmorDye() ?: return 0.0
-
- val price = internalName.getPrice()
- val name = internalName.getNameOrRepoError()
- val displayname = name ?: "§c${internalName.asString()}"
- list.add("§7Dye: $displayname §7(§6" + NumberUtil.format(price) + "§7)")
- if (name == null) {
- list.add(" §8(Not yet in NEU Repo)")
- }
- return price
- }
-
- private fun addEnrichment(stack: ItemStack, list: MutableList<String>): Double {
-
- val enrichmentName = stack.getEnrichment() ?: return 0.0
- val internalName = "TALISMAN_ENRICHMENT_$enrichmentName".asInternalName()
-
-
- val price = internalName.getPrice()
- val name = internalName.getItemName()
- list.add("§7Enrichment: $name §7(§6" + NumberUtil.format(price) + "§7)")
- return price
- }
-
- private fun addRune(stack: ItemStack, list: MutableList<String>): Double {
- val internalName = stack.getRune() ?: return 0.0
-
- val price = internalName.getPrice()
- val name = internalName.getItemNameOrNull()
- val displayname = name ?: "§c${internalName.asString()}"
- list.add("§7Rune: $displayname §7(§6" + NumberUtil.format(price) + "§7)")
- if (name == null) {
- list.add(" §8(Not yet in NEU Repo)")
- }
- return price
- }
-
- private fun NEUInternalName.getNameOrRepoError(): String? {
- val stack = getItemStackOrNull() ?: return null
- return stack.nameWithEnchantment ?: "§cItem Name Error"
- }
-
- private fun addAbilityScrolls(stack: ItemStack, list: MutableList<String>): Double {
- val abilityScrolls = stack.getAbilityScrolls() ?: return 0.0
-
- var totalPrice = 0.0
- val map = mutableMapOf<String, Double>()
- for (internalName in abilityScrolls) {
- val name = internalName.getItemName()
- val price = internalName.getPriceOrNull() ?: continue
-
- totalPrice += price
- val format = NumberUtil.format(price)
- map[" $name §7(§6$format§7)"] = price
- }
- if (map.isNotEmpty()) {
- list.add("§7Ability Scrolls: §6" + NumberUtil.format(totalPrice))
- list += map.sortedDesc().keys
- }
- return totalPrice
- }
-
- private fun addBaseItem(stack: ItemStack, list: MutableList<String>): Double {
- val internalName = stack.getInternalName()
- var price = internalName.getPrice()
- if (price == -1.0) {
- price = 0.0
- }
-
- val name = internalName.getItemName()
- if (internalName.startsWith("ENCHANTED_BOOK_BUNDLE_")) {
- list.add("§7Base item: $name")
- return 0.0
- }
-
- list.add("§7Base item: $name §7(§6" + NumberUtil.format(price) + "§7)")
- return price
- }
-
- val hasAlwaysScavenger = listOf(
- "CRYPT_DREADLORD_SWORD".asInternalName(),
- "ZOMBIE_SOLDIER_CUTLASS".asInternalName(),
- "CONJURING_SWORD".asInternalName(),
- "EARTH_SHARD".asInternalName(),
- "ZOMBIE_KNIGHT_SWORD".asInternalName(),
- "SILENT_DEATH".asInternalName(),
- "ZOMBIE_COMMANDER_WHIP".asInternalName(),
- )
-
- private fun addEnchantments(stack: ItemStack, list: MutableList<String>): Double {
- val enchantments = stack.getEnchantments() ?: return 0.0
-
- var totalPrice = 0.0
- val map = mutableMapOf<String, Double>()
-
- val tieredEnchants = listOf("compact", "cultivating", "champion", "expertise", "hecatomb")
-
- val internalName = stack.getInternalName()
- for ((rawName, rawLevel) in enchantments) {
- // efficiency 1-5 is cheap, 6-10 is handled by silex
- if (rawName == "efficiency") continue
-
- if (rawName == "scavenger" && rawLevel == 5 && internalName in hasAlwaysScavenger) {
- continue
- }
-
- var level = rawLevel
- var multiplier = 1
- if (rawName == "ultimate_chimera" || rawName == "ultimate_fatal_tempo" || rawName == "smoldering") {
-
- when (rawLevel) {
- 2 -> multiplier = 2
- 3 -> multiplier = 4
- 4 -> multiplier = 8
- 5 -> multiplier = 16
- }
- level = 1
-
- }
- if (internalName.startsWith("ENCHANTED_BOOK_BUNDLE_")) {
- multiplier = 5
- }
- if (rawName in tieredEnchants) level = 1
-
- val enchantmentName = "$rawName;$level".uppercase().asInternalName()
- val itemStack = enchantmentName.getItemStackOrNull() ?: continue
- val singlePrice = enchantmentName.getPriceOrNull() ?: continue
-
-
- var name = itemStack.getLore()[0]
- if (multiplier > 1) {
- name = "§8${multiplier}x $name"
- }
- val price = singlePrice * multiplier
-
- totalPrice += price
- val format = NumberUtil.format(price)
-
-
- map[" $name §7(§6$format§7)"] = price
- }
- val enchantmentsCap: Int = config.enchantmentsCap.get().toInt()
- if (map.isNotEmpty()) {
- list.add("§7Enchantments: §6" + NumberUtil.format(totalPrice))
- var i = 0
- for (entry in map.sortedDesc().keys) {
- if (i == enchantmentsCap) {
- val missing = map.size - enchantmentsCap
- list.add(" §7§o$missing more enchantments..")
- break
- }
- list.add(entry)
- i++
- }
- }
- return totalPrice
- }
-
- private fun addGemstones(stack: ItemStack, list: MutableList<String>): Double {
- val gemstones = stack.getGemstones() ?: return 0.0
-
- var totalPrice = 0.0
- val counterMap = mutableMapOf<NEUInternalName, Int>()
- for (gemstone in gemstones) {
- val internalName = gemstone.getInternalName()
- val old = counterMap[internalName] ?: 0
- counterMap[internalName] = old + 1
- }
-
- val priceMap = mutableMapOf<String, Double>()
- for ((internalName, amount) in counterMap) {
-
- val name = internalName.getItemName()
- val price = internalName.getPrice() * amount
-
- totalPrice += price
- val format = NumberUtil.format(price)
-
- val text = if (amount == 1) {
- " $name §7(§6$format§7)"
- } else {
- " §8${amount}x $name §7(§6$format§7)"
- }
- priceMap[text] = price
- }
-
- if (priceMap.isNotEmpty()) {
- list.add("§7Gemstones: §6" + NumberUtil.format(totalPrice))
- list += priceMap.sortedDesc().keys
- }
- return totalPrice
- }
-
- private fun addGemstoneSlotUnlockCost(stack: ItemStack, list: MutableList<String>): Double {
- val internalName = stack.getInternalName()
-
- // item have to contains gems.unlocked_slots NBT array for unlocked slot detection
- val unlockedSlots =
- stack.getExtraAttributes()?.getCompoundTag("gems")?.getTag("unlocked_slots")?.toString() ?: return 0.0
-
- // TODO detection for old items which doesnt have gems.unlocked_slots NBT array
-// if (unlockedSlots == "null") return 0.0
-
- val priceMap = mutableMapOf<String, Double>()
- if (gemstoneUnlockCosts.isEmpty()) return 0.0
-
- if (internalName !in gemstoneUnlockCosts) {
- ErrorManager.logErrorState(
- "Could not find gemstone slot price for ${stack.name}",
- "EstimatedItemValue has no gemstoneUnlockCosts for $internalName"
- )
- return 0.0
- }
-
- var totalPrice = 0.0
- val slots = gemstoneUnlockCosts[internalName] ?: return 0.0
- for (slot in slots) {
- if (!unlockedSlots.contains(slot.key)) continue
-
- val previousTotal = totalPrice
- for (ingredients in slot.value) {
- val ingredient = Ingredient(manager, ingredients)
-
- totalPrice += if (ingredient.isCoins) {
- ingredient.count
- } else {
- getPrice(ingredient.internalItemId) * ingredient.count
- }
- }
-
- val splitSlot = slot.key.split("_") // eg. SAPPHIRE_1
- val colorCode = GemstoneSlotType.getColorCode(splitSlot[0])
- val formattedPrice = NumberUtil.format(totalPrice - previousTotal)
-
- // eg. SAPPHIRE_1 -> Sapphire Slot 2
- val displayName = splitSlot[0].lowercase(Locale.ENGLISH).replaceFirstChar(Char::uppercase) + " Slot" +
- // If the slot index is 0, we don't need to specify
- if (splitSlot[1] != "0") " " + (splitSlot[1].toInt() + 1) else ""
-
- priceMap[" §$colorCode $displayName §7(§6$formattedPrice§7)"] = totalPrice - previousTotal
- }
-
- list.add("§7Gemstone Slot Unlock Cost: §6" + NumberUtil.format(totalPrice))
- list += priceMap.sortedDesc().keys
- return totalPrice
- }
-
@SubscribeEvent
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
event.move(3, "misc.estimatedIemValueEnabled", "misc.estimatedItemValues.enabled")
@@ -821,6 +206,6 @@ object EstimatedItemValue {
event.move(3, "misc.estimatedIemValueAlwaysEnabled", "misc.estimatedItemValues.alwaysEnabled")
event.move(3, "misc.estimatedIemValueEnchantmentsCap", "misc.estimatedItemValues.enchantmentsCap")
event.move(3, "misc.estimatedIemValueExactPrice", "misc.estimatedItemValues.exactPrice")
- event.move(3,"misc.itemPriceDataPos", "misc.estimatedItemValues.itemPriceDataPos")
+ event.move(3, "misc.itemPriceDataPos", "misc.estimatedItemValues.itemPriceDataPos")
}
}
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
new file mode 100644
index 000000000..f3e27957d
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValueCalculator.kt
@@ -0,0 +1,699 @@
+package at.hannibal2.skyhanni.features.misc.items
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.test.command.ErrorManager
+import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
+import at.hannibal2.skyhanni.utils.ItemUtils.getItemName
+import at.hannibal2.skyhanni.utils.ItemUtils.getItemNameOrNull
+import at.hannibal2.skyhanni.utils.ItemUtils.getItemRarityOrNull
+import at.hannibal2.skyhanni.utils.ItemUtils.getLore
+import at.hannibal2.skyhanni.utils.ItemUtils.name
+import at.hannibal2.skyhanni.utils.ItemUtils.nameWithEnchantment
+import at.hannibal2.skyhanni.utils.LorenzRarity
+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
+import at.hannibal2.skyhanni.utils.NEUItems.getItemStackOrNull
+import at.hannibal2.skyhanni.utils.NEUItems.getPrice
+import at.hannibal2.skyhanni.utils.NEUItems.getPriceOrNull
+import at.hannibal2.skyhanni.utils.NumberUtil
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getAbilityScrolls
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getArmorDye
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getAttributes
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getBookwormBookCount
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getDrillUpgrades
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getDungeonStarCount
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getEnchantments
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getEnrichment
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getExtraAttributes
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getFarmingForDummiesCount
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getGemstones
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getHelmetSkin
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getHotPotatoCount
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getManaDisintegrators
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getPolarvoidBookCount
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getPowerScroll
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getReforgeName
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getRune
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getSilexCount
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getTransmissionTunerCount
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasArtOfPeace
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasArtOfWar
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasBookOfStats
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasEtherwarp
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasJalapenoBook
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasWoodSingularity
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.isRecombobulated
+import at.hannibal2.skyhanni.utils.StringUtils.firstLetterUppercase
+import at.hannibal2.skyhanni.utils.StringUtils.removeColor
+import com.google.gson.JsonObject
+import io.github.moulberry.notenoughupdates.recipes.Ingredient
+import io.github.moulberry.notenoughupdates.util.Constants
+import net.minecraft.item.ItemStack
+import java.util.Locale
+
+object EstimatedItemValueCalculator {
+ private val config get() = SkyHanniMod.feature.misc.estimatedItemValues
+
+ fun calculate(stack: ItemStack, list: MutableList<String>): Pair<Double, Double> {
+ var totalPrice = 0.0
+ val basePrice = addBaseItem(stack, list)
+ totalPrice += basePrice
+
+ totalPrice += addAttributeCost(stack, list)
+
+ totalPrice += addReforgeStone(stack, list)
+
+ // once
+ totalPrice += addRecomb(stack, list)
+ totalPrice += addArtOfWar(stack, list)
+ totalPrice += addArtOfPeace(stack, list)
+ totalPrice += addEtherwarp(stack, list)
+ totalPrice += addPowerScrolls(stack, list)
+ totalPrice += addWoodSingularity(stack, list)
+ totalPrice += addJalapenoBook(stack, list)
+ totalPrice += addStatsBook(stack, list)
+ totalPrice += addEnrichment(stack, list)
+
+ // counted
+ totalPrice += addMasterStars(stack, list)
+ totalPrice += addHotPotatoBooks(stack, list)
+ totalPrice += addFarmingForDummies(stack, list)
+ totalPrice += addSilex(stack, list)
+ totalPrice += addTransmissionTuners(stack, list)
+ totalPrice += addManaDisintegrators(stack, list)
+ totalPrice += addPolarvoidBook(stack, list)
+ totalPrice += addBookwormBook(stack, list)
+
+ // cosmetic
+ totalPrice += addHelmetSkin(stack, list)
+ totalPrice += addArmorDye(stack, list)
+ totalPrice += addRune(stack, list)
+
+ // dynamic
+ totalPrice += addAbilityScrolls(stack, list)
+ totalPrice += addDrillUpgrades(stack, list)
+ totalPrice += addGemstoneSlotUnlockCost(stack, list)
+ totalPrice += addGemstones(stack, list)
+ totalPrice += addEnchantments(stack, list)
+ return Pair(totalPrice, basePrice)
+ }
+
+ private fun addAttributeCost(stack: ItemStack, list: MutableList<String>): Double {
+ val attributes = stack.getAttributes() ?: return 0.0
+ var internalName = stack.getInternalName().asString().removePrefix("VANQUISHED_")
+ val kuudraSets = listOf("AURORA", "CRIMSON", "TERROR", "HOLLOW")
+ var genericName = internalName
+ if (kuudraSets.any { internalName.contains(it) }
+ && listOf("CHESTPLATE", "LEGGINGS", "HELMET", "BOOTS").any { internalName.endsWith(it) }) {
+ for (prefix in listOf("HOT_", "BURNING_", "FIERY_", "INFERNAL_")) {
+ internalName = internalName.removePrefix(prefix)
+ }
+ genericName = kuudraSets.fold(internalName) { acc, part -> acc.replace(part, "GENERIC_KUUDRA") }
+ }
+ if (internalName == "ATTRIBUTE_SHARD" && attributes.size == 1) {
+ val price =
+ getPriceOrCompositePriceForAttribute(
+ "ATTRIBUTE_SHARD+ATTRIBUTE_" + attributes[0].first,
+ attributes[0].second
+ )
+ if (price != null) {
+ list.add(
+ "§7Attribute §9${
+ attributes[0].first.fixMending().split("_").joinToString(" ") { it.firstLetterUppercase() }
+ } ${attributes[0].second}§7: (§6${NumberUtil.format(price)}§7)"
+ )
+ return price
+ }
+ }
+ if (attributes.size != 2) return 0.0
+ val basePrice = internalName.asInternalName().getPriceOrNull() ?: 0.0
+ var subTotal = 0.0
+ val combo = ("$internalName+ATTRIBUTE_${attributes[0].first}+ATTRIBUTE_${attributes[1].first}").asInternalName()
+ val comboPrice = combo.getPriceOrNull()
+ if (comboPrice != null && comboPrice > basePrice) {
+ list.add("§7Attribute Combo: (§6${NumberUtil.format(comboPrice)}§7)")
+ subTotal += comboPrice - basePrice
+ } else {
+ list.add("§7Attributes:")
+ }
+ for (attr in attributes) {
+ val price =
+ getPriceOrCompositePriceForAttribute("$genericName+ATTRIBUTE_${attr.first}", attr.second)
+ if (price != null) {
+ subTotal += price
+ }
+ val displayName = attr.first.fixMending()
+ list.add(
+ " §9${
+ displayName.split("_").joinToString(" ") { it.firstLetterUppercase() }
+ } ${attr.second}§7: §6${if (price != null) NumberUtil.format(price) else "Unknown"}"
+ )
+ }
+ return subTotal
+ }
+
+ private fun String.fixMending() = if (this == "MENDING") "VITALITY" else this
+
+ private fun getPriceOrCompositePriceForAttribute(attributeName: String, level: Int): Double? {
+ return (1..10).mapNotNull { lowerLevel ->
+ "$attributeName;$lowerLevel".asInternalName().getPriceOrNull()
+ ?.let { it / (1 shl lowerLevel) * (1 shl level).toDouble() }
+ }.minOrNull()
+ }
+
+ private fun addReforgeStone(stack: ItemStack, list: MutableList<String>): Double {
+ val rawReforgeName = stack.getReforgeName() ?: return 0.0
+
+ for ((rawInternalName, values) in Constants.REFORGESTONES.entrySet()) {
+ val stoneJson = values.asJsonObject
+ val reforgeName = stoneJson.get("reforgeName").asString
+ if (rawReforgeName == reforgeName.lowercase() || rawReforgeName == rawInternalName.lowercase()) {
+ val internalName = rawInternalName.asInternalName()
+ val reforgeStonePrice = internalName.getPrice()
+ val reforgeStoneName = internalName.getItemName()
+
+ val reforgeCosts = stoneJson.get("reforgeCosts").asJsonObject
+ val applyCost = getReforgeStoneApplyCost(stack, reforgeCosts, internalName) ?: return 0.0
+
+ list.add("§7Reforge: §9$reforgeName")
+ list.add(" §7Stone $reforgeStoneName §7(§6" + NumberUtil.format(reforgeStonePrice) + "§7)")
+ list.add(" §7Apply cost: (§6" + NumberUtil.format(applyCost) + "§7)")
+ return reforgeStonePrice + applyCost
+ }
+ }
+
+ return 0.0
+ }
+
+ private fun getReforgeStoneApplyCost(
+ stack: ItemStack,
+ reforgeCosts: JsonObject,
+ reforgeStone: NEUInternalName
+ ): Int? {
+ var itemRarity = stack.getItemRarityOrNull() ?: return null
+
+ // Catch cases of special or very special
+ if (itemRarity > LorenzRarity.MYTHIC) {
+ itemRarity = LorenzRarity.LEGENDARY
+ } else {
+ if (stack.isRecombobulated()) {
+ val oneBelow = itemRarity.oneBelow(logError = false)
+ if (oneBelow == null) {
+ ErrorManager.logErrorStateWithData(
+ "Wrong item rarity detected in estimated item value for item ${stack.name}",
+ "Recombobulated item is common",
+ "internal name" to stack.getInternalName(),
+ "itemRarity" to itemRarity,
+ "item name" to stack.name,
+ )
+ return null
+ }
+ itemRarity = oneBelow
+ }
+ }
+ val rarityName = itemRarity.name
+ if (!reforgeCosts.has(rarityName)) {
+ val reforgesFound = reforgeCosts.entrySet().map { it.key }
+ ErrorManager.logErrorStateWithData(
+ "Could not calculate reforge cost for item ${stack.name}",
+ "Item not in NEU repo reforge cost",
+ "rarityName" to rarityName,
+ "reforgeCosts" to reforgeCosts,
+ "itemRarity" to itemRarity,
+ "reforgesFound" to reforgesFound,
+ "internal name" to stack.getInternalName(),
+ "item name" to stack.name,
+ "reforgeStone" to reforgeStone,
+ )
+ return null
+ }
+
+ return reforgeCosts[rarityName].asInt
+ }
+
+ private fun addRecomb(stack: ItemStack, list: MutableList<String>): Double {
+ if (!stack.isRecombobulated()) return 0.0
+
+ val price = "RECOMBOBULATOR_3000".asInternalName().getPrice()
+ list.add("§7Recombobulated: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addJalapenoBook(stack: ItemStack, list: MutableList<String>): Double {
+ if (!stack.hasJalapenoBook()) return 0.0
+
+ val price = "JALAPENO_BOOK".asInternalName().getPrice()
+ list.add("§7Jalapeno Book: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addEtherwarp(stack: ItemStack, list: MutableList<String>): Double {
+ if (!stack.hasEtherwarp()) return 0.0
+
+ val wtfHardcodedConduit = "ETHERWARP_CONDUIT".asInternalName()
+ val wtfHardcodedMerger = "ETHERWARP_MERGER".asInternalName()
+ val price = wtfHardcodedConduit.getPrice() + wtfHardcodedMerger.getPrice()
+ list.add("§7Etherwarp: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addWoodSingularity(stack: ItemStack, list: MutableList<String>): Double {
+ if (!stack.hasWoodSingularity()) return 0.0
+
+ val price = "WOOD_SINGULARITY".asInternalName().getPrice()
+ list.add("§7Wood Singularity: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addArtOfWar(stack: ItemStack, list: MutableList<String>): Double {
+ if (!stack.hasArtOfWar()) return 0.0
+
+ val price = "THE_ART_OF_WAR".asInternalName().getPrice()
+ list.add("§7The Art of War: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addStatsBook(stack: ItemStack, list: MutableList<String>): Double {
+ if (!stack.hasBookOfStats()) return 0.0
+
+ val price = "BOOK_OF_STATS".asInternalName().getPrice()
+ list.add("§7Book of Stats: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ // TODO untested
+ private fun addArtOfPeace(stack: ItemStack, list: MutableList<String>): Double {
+ if (!stack.hasArtOfPeace()) return 0.0
+
+ val price = "THE_ART_OF_PEACE".asInternalName().getPrice()
+ list.add("§7The Art Of Peace: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addHotPotatoBooks(stack: ItemStack, list: MutableList<String>): Double {
+ val count = stack.getHotPotatoCount() ?: return 0.0
+
+ val hpb: Int
+ val fuming: Int
+ if (count <= 10) {
+ hpb = count
+ fuming = 0
+ } else {
+ hpb = 10
+ fuming = count - 10
+ }
+
+ var totalPrice = 0.0
+
+ val wtfHardcodedHpb = "HOT_POTATO_BOOK".asInternalName()
+ val hpbPrice = wtfHardcodedHpb.getPrice() * hpb
+ list.add("§7HPB's: §e$hpb§7/§e10 §7(§6" + NumberUtil.format(hpbPrice) + "§7)")
+ totalPrice += hpbPrice
+
+ if (fuming > 0) {
+ val wtfHardcodedFuming = "FUMING_POTATO_BOOK".asInternalName()
+ val fumingPrice = wtfHardcodedFuming.getPrice() * fuming
+ list.add("§7Fuming: §e$fuming§7/§e5 §7(§6" + NumberUtil.format(fumingPrice) + "§7)")
+ totalPrice += fumingPrice
+ }
+
+ return totalPrice
+ }
+
+ private fun addFarmingForDummies(stack: ItemStack, list: MutableList<String>): Double {
+ val count = stack.getFarmingForDummiesCount() ?: return 0.0
+
+ val wtfHardcodedDumbFarmers = "FARMING_FOR_DUMMIES".asInternalName()
+ val price = wtfHardcodedDumbFarmers.getPrice() * count
+ list.add("§7Farming for Dummies: §e$count§7/§e5 §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addPolarvoidBook(stack: ItemStack, list: MutableList<String>): Double {
+ val count = stack.getPolarvoidBookCount() ?: return 0.0
+
+ val broDilloMiningSoBad = "POLARVOID_BOOK".asInternalName()
+ val price = broDilloMiningSoBad.getPrice() * count
+ list.add("§7Polarvoid: §e$count§7/§e5 §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addBookwormBook(stack: ItemStack, list: MutableList<String>): Double {
+ val count = stack.getBookwormBookCount() ?: return 0.0
+
+ val tfHardcodedItemAgain = "BOOKWORM_BOOK".asInternalName()
+ val price = tfHardcodedItemAgain.getPrice() * count
+ list.add("§7Bookworm's Favorite Book: §e$count§7/§e5 §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addSilex(stack: ItemStack, list: MutableList<String>): Double {
+ val tier = stack.getSilexCount() ?: return 0.0
+
+ val internalName = stack.getInternalName()
+ val maxTier = if (internalName == "STONK_PICKAXE".asInternalName()) 4 else 5
+
+ val wtfHardcodedSilex = "SIL_EX".asInternalName()
+ val price = wtfHardcodedSilex.getPrice() * tier
+ list.add("§7Silex: §e$tier§7/§e$maxTier §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addTransmissionTuners(stack: ItemStack, list: MutableList<String>): Double {
+ val count = stack.getTransmissionTunerCount() ?: return 0.0
+
+ val wtfHardcodedTuner = "TRANSMISSION_TUNER".asInternalName()
+ val price = wtfHardcodedTuner.getPrice() * count
+ list.add("§7Transmission Tuners: §e$count§7/§e4 §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addManaDisintegrators(stack: ItemStack, list: MutableList<String>): Double {
+ val count = stack.getManaDisintegrators() ?: return 0.0
+
+ val wtfHardcodedTuner = "MANA_DISINTEGRATOR".asInternalName()
+ val price = wtfHardcodedTuner.getPrice() * count
+ list.add("§7Mana Disintegrators: §e$count§7/§e10 §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addMasterStars(stack: ItemStack, list: MutableList<String>): Double {
+ val totalStars = stack.getDungeonStarCount() ?: return 0.0
+
+ val masterStars = totalStars - 5
+ if (masterStars < 1) return 0.0
+
+ var price = 0.0
+
+ val stars = mapOf(
+ "FIRST" to 1,
+ "SECOND" to 2,
+ "THIRD" to 3,
+ "FOURTH" to 4,
+ "FIFTH" to 5,
+ )
+
+ for ((prefix, number) in stars) {
+ if (masterStars >= number) {
+ price += "${prefix}_MASTER_STAR".asInternalName().getPrice()
+ }
+ }
+
+ list.add("§7Master Stars: §e$masterStars§7/§e5 §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addDrillUpgrades(stack: ItemStack, list: MutableList<String>): Double {
+ val drillUpgrades = stack.getDrillUpgrades() ?: return 0.0
+
+ var totalPrice = 0.0
+ val map = mutableMapOf<String, Double>()
+ for (internalName in drillUpgrades) {
+ val name = internalName.getItemName()
+ val price = internalName.getPriceOrNull() ?: continue
+
+ totalPrice += price
+ val format = NumberUtil.format(price)
+ map[" $name §7(§6$format§7)"] = price
+ }
+ if (map.isNotEmpty()) {
+ list.add("§7Drill upgrades: §6" + NumberUtil.format(totalPrice))
+ list += map.sortedDesc().keys
+ }
+ return totalPrice
+ }
+
+ private fun addPowerScrolls(stack: ItemStack, list: MutableList<String>): Double {
+ val internalName = stack.getPowerScroll() ?: return 0.0
+
+ val price = internalName.getPrice()
+ val name = internalName.getItemName().removeColor()
+ list.add("§7$name: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addHelmetSkin(stack: ItemStack, list: MutableList<String>): Double {
+ val internalName = stack.getHelmetSkin() ?: return 0.0
+
+ val price = internalName.getPrice()
+ val name = internalName.getNameOrRepoError()
+ val displayname = name ?: "§c${internalName.asString()}"
+ list.add("§7Skin: $displayname §7(§6" + NumberUtil.format(price) + "§7)")
+ if (name == null) {
+ list.add(" §8(Not yet in NEU Repo)")
+ }
+ return price
+ }
+
+ private fun addArmorDye(stack: ItemStack, list: MutableList<String>): Double {
+ val internalName = stack.getArmorDye() ?: return 0.0
+
+ val price = internalName.getPrice()
+ val name = internalName.getNameOrRepoError()
+ val displayname = name ?: "§c${internalName.asString()}"
+ list.add("§7Dye: $displayname §7(§6" + NumberUtil.format(price) + "§7)")
+ if (name == null) {
+ list.add(" §8(Not yet in NEU Repo)")
+ }
+ return price
+ }
+
+ private fun addEnrichment(stack: ItemStack, list: MutableList<String>): Double {
+
+ val enrichmentName = stack.getEnrichment() ?: return 0.0
+ val internalName = "TALISMAN_ENRICHMENT_$enrichmentName".asInternalName()
+
+ val price = internalName.getPrice()
+ val name = internalName.getItemName()
+ list.add("§7Enrichment: $name §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addRune(stack: ItemStack, list: MutableList<String>): Double {
+ val internalName = stack.getRune() ?: return 0.0
+
+ val price = internalName.getPrice()
+ val name = internalName.getItemNameOrNull()
+ val displayname = name ?: "§c${internalName.asString()}"
+ list.add("§7Rune: $displayname §7(§6" + NumberUtil.format(price) + "§7)")
+ if (name == null) {
+ list.add(" §8(Not yet in NEU Repo)")
+ }
+ return price
+ }
+
+ private fun NEUInternalName.getNameOrRepoError(): String? {
+ val stack = getItemStackOrNull() ?: return null
+ return stack.nameWithEnchantment ?: "§cItem Name Error"
+ }
+
+ private fun addAbilityScrolls(stack: ItemStack, list: MutableList<String>): Double {
+ val abilityScrolls = stack.getAbilityScrolls() ?: return 0.0
+
+ var totalPrice = 0.0
+ val map = mutableMapOf<String, Double>()
+ for (internalName in abilityScrolls) {
+ val name = internalName.getItemName()
+ val price = internalName.getPriceOrNull() ?: continue
+
+ totalPrice += price
+ val format = NumberUtil.format(price)
+ map[" $name §7(§6$format§7)"] = price
+ }
+ if (map.isNotEmpty()) {
+ list.add("§7Ability Scrolls: §6" + NumberUtil.format(totalPrice))
+ list += map.sortedDesc().keys
+ }
+ return totalPrice
+ }
+
+ private fun addBaseItem(stack: ItemStack, list: MutableList<String>): Double {
+ val internalName = stack.getInternalName()
+ var price = internalName.getPrice()
+ if (price == -1.0) {
+ price = 0.0
+ }
+
+ val name = internalName.getItemName()
+ if (internalName.startsWith("ENCHANTED_BOOK_BUNDLE_")) {
+ list.add("§7Base item: $name")
+ return 0.0
+ }
+
+ list.add("§7Base item: $name §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private val hasAlwaysScavenger = listOf(
+ "CRYPT_DREADLORD_SWORD".asInternalName(),
+ "ZOMBIE_SOLDIER_CUTLASS".asInternalName(),
+ "CONJURING_SWORD".asInternalName(),
+ "EARTH_SHARD".asInternalName(),
+ "ZOMBIE_KNIGHT_SWORD".asInternalName(),
+ "SILENT_DEATH".asInternalName(),
+ "ZOMBIE_COMMANDER_WHIP".asInternalName(),
+ )
+
+ private fun addEnchantments(stack: ItemStack, list: MutableList<String>): Double {
+ val enchantments = stack.getEnchantments() ?: return 0.0
+
+ var totalPrice = 0.0
+ val map = mutableMapOf<String, Double>()
+
+ val tieredEnchants = listOf("compact", "cultivating", "champion", "expertise", "hecatomb")
+
+ val internalName = stack.getInternalName()
+ for ((rawName, rawLevel) in enchantments) {
+ // efficiency 1-5 is cheap, 6-10 is handled by silex
+ if (rawName == "efficiency") continue
+
+ if (rawName == "scavenger" && rawLevel == 5 && internalName in hasAlwaysScavenger) {
+ continue
+ }
+
+ var level = rawLevel
+ var multiplier = 1
+ if (rawName == "ultimate_chimera" || rawName == "ultimate_fatal_tempo" || rawName == "smoldering") {
+
+ when (rawLevel) {
+ 2 -> multiplier = 2
+ 3 -> multiplier = 4
+ 4 -> multiplier = 8
+ 5 -> multiplier = 16
+ }
+ level = 1
+
+ }
+ if (internalName.startsWith("ENCHANTED_BOOK_BUNDLE_")) {
+ multiplier = 5
+ }
+ if (rawName in tieredEnchants) level = 1
+
+ val enchantmentName = "$rawName;$level".uppercase().asInternalName()
+ val itemStack = enchantmentName.getItemStackOrNull() ?: continue
+ val singlePrice = enchantmentName.getPriceOrNull() ?: continue
+
+ var name = itemStack.getLore()[0]
+ if (multiplier > 1) {
+ name = "§8${multiplier}x $name"
+ }
+ val price = singlePrice * multiplier
+
+ totalPrice += price
+ val format = NumberUtil.format(price)
+
+
+ map[" $name §7(§6$format§7)"] = price
+ }
+ val enchantmentsCap: Int = config.enchantmentsCap.get()
+ if (map.isNotEmpty()) {
+ list.add("§7Enchantments: §6" + NumberUtil.format(totalPrice))
+ var i = 0
+ for (entry in map.sortedDesc().keys) {
+ if (i == enchantmentsCap) {
+ val missing = map.size - enchantmentsCap
+ list.add(" §7§o$missing more enchantments..")
+ break
+ }
+ list.add(entry)
+ i++
+ }
+ }
+ return totalPrice
+ }
+
+ private fun addGemstones(stack: ItemStack, list: MutableList<String>): Double {
+ val gemstones = stack.getGemstones() ?: return 0.0
+
+ var totalPrice = 0.0
+ val counterMap = mutableMapOf<NEUInternalName, Int>()
+ for (gemstone in gemstones) {
+ val internalName = gemstone.getInternalName()
+ val old = counterMap[internalName] ?: 0
+ counterMap[internalName] = old + 1
+ }
+
+ val priceMap = mutableMapOf<String, Double>()
+ for ((internalName, amount) in counterMap) {
+
+ val name = internalName.getItemName()
+ val price = internalName.getPrice() * amount
+
+ totalPrice += price
+ val format = NumberUtil.format(price)
+
+ val text = if (amount == 1) {
+ " $name §7(§6$format§7)"
+ } else {
+ " §8${amount}x $name §7(§6$format§7)"
+ }
+ priceMap[text] = price
+ }
+
+ if (priceMap.isNotEmpty()) {
+ list.add("§7Gemstones: §6" + NumberUtil.format(totalPrice))
+ list += priceMap.sortedDesc().keys
+ }
+ return totalPrice
+ }
+
+ private fun addGemstoneSlotUnlockCost(stack: ItemStack, list: MutableList<String>): Double {
+ val internalName = stack.getInternalName()
+
+ // item have to contains gems.unlocked_slots NBT array for unlocked slot detection
+ val unlockedSlots =
+ stack.getExtraAttributes()?.getCompoundTag("gems")?.getTag("unlocked_slots")?.toString() ?: return 0.0
+
+ // TODO detection for old items which doesnt have gems.unlocked_slots NBT array
+// if (unlockedSlots == "null") return 0.0
+
+ val priceMap = mutableMapOf<String, Double>()
+ if (EstimatedItemValue.gemstoneUnlockCosts.isEmpty()) return 0.0
+
+ if (internalName !in EstimatedItemValue.gemstoneUnlockCosts) {
+ ErrorManager.logErrorStateWithData(
+ "Could not find gemstone slot price for ${stack.name}",
+ "EstimatedItemValue has no gemstoneUnlockCosts for $internalName",
+ "internal name" to internalName,
+ "gemstoneUnlockCosts" to EstimatedItemValue.gemstoneUnlockCosts,
+ "item name" to stack.name,
+ )
+ return 0.0
+ }
+
+ var totalPrice = 0.0
+ val slots = EstimatedItemValue.gemstoneUnlockCosts[internalName] ?: return 0.0
+ for (slot in slots) {
+ if (!unlockedSlots.contains(slot.key)) continue
+
+ val previousTotal = totalPrice
+ for (ingredients in slot.value) {
+ val ingredient = Ingredient(NEUItems.manager, ingredients)
+
+ totalPrice += if (ingredient.isCoins) {
+ ingredient.count
+ } else {
+ getPrice(ingredient.internalItemId) * ingredient.count
+ }
+ }
+
+ val splitSlot = slot.key.split("_") // eg. SAPPHIRE_1
+ val colorCode = SkyBlockItemModifierUtils.GemstoneSlotType.getColorCode(splitSlot[0])
+ val formattedPrice = NumberUtil.format(totalPrice - previousTotal)
+
+ // eg. SAPPHIRE_1 -> Sapphire Slot 2
+ val displayName = splitSlot[0].lowercase(Locale.ENGLISH).replaceFirstChar(Char::uppercase) + " Slot" +
+ // If the slot index is 0, we don't need to specify
+ if (splitSlot[1] != "0") " " + (splitSlot[1].toInt() + 1) else ""
+
+ priceMap[" §$colorCode $displayName §7(§6$formattedPrice§7)"] = totalPrice - previousTotal
+ }
+
+ list.add("§7Gemstone Slot Unlock Cost: §6" + NumberUtil.format(totalPrice))
+ list += priceMap.sortedDesc().keys
+ return totalPrice
+ }
+}
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 dd1f9d236..6655d71cd 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
@@ -37,7 +37,7 @@ class EstimatedWardrobePrice {
var totalPrice = 0.0
for (item in items) {
val name = item.name
- val price = EstimatedItemValue.getEstimatedItemPrice(item, mutableListOf()).first
+ val price = EstimatedItemValueCalculator.calculate(item, mutableListOf()).first
totalPrice += price
toolTip.add(index++, " §7- $name: §6${NumberUtil.format(price)}")
@@ -55,7 +55,7 @@ class EstimatedWardrobePrice {
for ((slot, item) in event.inventoryItems) {
item.getInternalNameOrNull() ?: continue
- val price = EstimatedItemValue.getEstimatedItemPrice(item, mutableListOf()).first
+ val price = EstimatedItemValueCalculator.calculate(item, mutableListOf()).first
if (price == 0.0) continue
val id = slot % 9
val list = map.getOrPut(id) { mutableListOf() }
@@ -68,4 +68,4 @@ class EstimatedWardrobePrice {
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
event.move(3, "misc.estimatedIemValueArmor", "misc.estimatedItemValues.armor")
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/massconfiguration/DefaultConfigFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/massconfiguration/DefaultConfigFeatures.kt
index ef9bd1e75..1f153ed69 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/massconfiguration/DefaultConfigFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/massconfiguration/DefaultConfigFeatures.kt
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.features.misc.massconfiguration
import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.config.ConfigFileType
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
import io.github.moulberry.moulconfig.processor.ConfigProcessorDriver
@@ -17,25 +18,30 @@ object DefaultConfigFeatures {
Minecraft.getMinecraft().thePlayer ?: return
didNotifyOnce = true
- val knownToggles = SkyHanniMod.feature.storage.knownFeatureToggles
+ val oldToggles = SkyHanniMod.feature.storage.knownFeatureToggles
+ if (oldToggles.isNotEmpty()) {
+ SkyHanniMod.knownFeaturesData.knownFeatures = oldToggles
+ SkyHanniMod.feature.storage.knownFeatureToggles = emptyMap()
+ }
+
+ val knownToggles = SkyHanniMod.knownFeaturesData.knownFeatures
val updated = SkyHanniMod.version !in knownToggles
val processor = FeatureToggleProcessor()
ConfigProcessorDriver.processConfig(SkyHanniMod.feature.javaClass, SkyHanniMod.feature, processor)
knownToggles[SkyHanniMod.version] = processor.allOptions.map { it.path }
- SkyHanniMod.configManager.saveConfig("Updated known feature flags")
+ SkyHanniMod.configManager.saveConfig(ConfigFileType.KNOWN_FEATURES, "Updated known feature flags")
if (!SkyHanniMod.feature.storage.hasPlayedBefore) {
SkyHanniMod.feature.storage.hasPlayedBefore = true
LorenzUtils.clickableChat(
- "§e[SkyHanni] Looks like this is the first time you are using SkyHanni. " +
- "Click here to configure default options, or run /shdefaultoptions.",
+ "Looks like this is the first time you are using SkyHanni. " +
+ "Click here to configure default options, or run /shdefaultoptions.",
"shdefaultoptions"
)
} else if (updated) {
- val mostFeatureFulOldVersion =
- knownToggles.maxByOrNull { if (it.key != SkyHanniMod.version) it.value.size else -1 }
- val command = "/shdefaultoptions ${mostFeatureFulOldVersion?.key} ${SkyHanniMod.version}"
+ val lastVersion = knownToggles.keys.last { it != SkyHanniMod.version }
+ val command = "/shdefaultoptions $lastVersion ${SkyHanniMod.version}"
LorenzUtils.clickableChat(
- "§e[SkyHanni] Looks like you updated SkyHanni. " +
+ "Looks like you updated SkyHanni. " +
"Click here to configure the newly introduced options, or run $command.",
command
)
@@ -46,15 +52,15 @@ object DefaultConfigFeatures {
val processor = FeatureToggleProcessor()
ConfigProcessorDriver.processConfig(SkyHanniMod.feature.javaClass, SkyHanniMod.feature, processor)
var optionList = processor.orderedOptions
- val knownToggles = SkyHanniMod.feature.storage.knownFeatureToggles
+ val knownToggles = SkyHanniMod.knownFeaturesData.knownFeatures
val togglesInNewVersion = knownToggles[new]
if (new != "null" && togglesInNewVersion == null) {
- LorenzUtils.chat("§e[SkyHanni] Unknown version $new")
+ LorenzUtils.chat("Unknown version $new")
return
}
val togglesInOldVersion = knownToggles[old]
if (old != "null" && togglesInOldVersion == null) {
- LorenzUtils.chat("§e[SkyHanni] Unknown version $old")
+ LorenzUtils.chat("Unknown version $old")
return
}
optionList = optionList
@@ -65,7 +71,10 @@ object DefaultConfigFeatures {
}
}
.filter { (_, filteredOptions) -> filteredOptions.isNotEmpty() }
-
+ if (optionList.isEmpty()) {
+ LorenzUtils.chat("There are no new options to configure between $old and $new")
+ return
+ }
SkyHanniMod.screenToOpen = DefaultConfigOptionGui(optionList, old, new)
}
@@ -92,7 +101,7 @@ object DefaultConfigFeatures {
if (strings.size <= 2)
return CommandBase.getListOfStringsMatchingLastWord(
strings,
- SkyHanniMod.feature.storage.knownFeatureToggles.keys + listOf("null")
+ SkyHanniMod.knownFeaturesData.knownFeatures.keys + listOf("null")
)
return listOf()
}
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 c6b6e3749..318d4c1f0 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
@@ -18,6 +18,7 @@ import at.hannibal2.skyhanni.utils.EntityUtils
import at.hannibal2.skyhanni.utils.LocationUtils.distanceToPlayer
import at.hannibal2.skyhanni.utils.LorenzColor
import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland
import at.hannibal2.skyhanni.utils.LorenzVec
import at.hannibal2.skyhanni.utils.NEUItems
import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText
@@ -231,7 +232,9 @@ object TrevorFeatures {
location = LorenzVec(location.x, TrevorSolver.averageHeight, location.z)
}
if (TrevorSolver.mobLocation == CurrentMobArea.FOUND) {
- val displayName = if (TrevorSolver.currentMob == null) "Mob Location" else TrevorSolver.currentMob!!.mobName
+ val displayName = if (TrevorSolver.currentMob == null) "Mob Location" else {
+ 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)
@@ -296,8 +299,7 @@ object TrevorFeatures {
val colorCode = baseColor.getChatColor()
}
- fun onFarmingIsland() =
- LorenzUtils.inSkyBlock && LorenzUtils.skyBlockIsland == IslandType.THE_FARMING_ISLANDS
+ fun onFarmingIsland() = IslandType.THE_FARMING_ISLANDS.isInIsland()
fun inTrapperDen() = ScoreboardData.sidebarLinesFormatted.contains(" §7⏣ §bTrapper's Den")
}
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 f2e36db59..59d44b1b7 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
@@ -17,7 +17,8 @@ object TrevorTracker {
private val config get() = SkyHanniMod.feature.misc.trevorTheTrapper
// TODO USE SH-REPO
- private val selfKillMobPattern = "§aYour mob died randomly, you are rewarded §r§5(?<pelts>.*) pelts§r§a.".toPattern()
+ private val selfKillMobPattern =
+ "§aYour mob died randomly, you are rewarded §r§5(?<pelts>.*) pelts§r§a.".toPattern()
private val killMobPattern = "§aKilling the animal rewarded you §r§5(?<pelts>.*) pelts§r§a.".toPattern()
private var display = emptyList<List<Any>>()
@@ -78,7 +79,7 @@ object TrevorTracker {
if (matcher.matches()) {
val pelts = matcher.group("pelts").toInt()
storage.peltsGained += pelts
- storage.selfKillingAnimals += 1
+ storage.selfKillingAnimals += 1
saveAndUpdate()
}
matcher = killMobPattern.matcher(event.message)
@@ -94,7 +95,7 @@ object TrevorTracker {
val storage = ProfileStorageData.profileSpecific?.trapperData ?: return
storage.questsDone += 1
val rarity = matcher.group("rarity")
- val foundRarity = TrapperMobRarity.values().firstOrNull { it.formattedName == rarity } ?: return
+ 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()
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/update/GuiOptionEditorUpdateCheck.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/update/GuiOptionEditorUpdateCheck.kt
index 9d68aebde..b4e517734 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/update/GuiOptionEditorUpdateCheck.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/update/GuiOptionEditorUpdateCheck.kt
@@ -47,7 +47,7 @@ class GuiOptionEditorUpdateCheck(option: ProcessedOption) : GuiOptionEditor(opti
val sameVersion = currentVersion.equals(nextVersion, true)
TextRenderUtils.drawStringCenteredScaledMaxWidth(
"${if (UpdateManager.updateState == UpdateManager.UpdateState.NONE) GREEN else RED}$currentVersion" +
- if (nextVersion != null && !sameVersion) "➜ ${GREEN}${nextVersion}" else "",
+ if (nextVersion != null && !sameVersion) "➜ ${GREEN}${nextVersion}" else "",
fr,
widthRemaining / 4F,
10F,
@@ -59,7 +59,7 @@ class GuiOptionEditorUpdateCheck(option: ProcessedOption) : GuiOptionEditor(opti
GlStateManager.popMatrix()
}
- fun getButtonPosition(width: Int) = width - button.width
+ private fun getButtonPosition(width: Int) = width - button.width
override fun getHeight(): Int {
return 55
}
@@ -85,4 +85,4 @@ class GuiOptionEditorUpdateCheck(option: ProcessedOption) : GuiOptionEditor(opti
override fun fulfillsSearch(word: String): Boolean {
return super.fulfillsSearch(word) || word in "download" || word in "update"
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/update/UpdateManager.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/update/UpdateManager.kt
index 84362576c..2a35519e9 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/update/UpdateManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/update/UpdateManager.kt
@@ -62,11 +62,11 @@ object UpdateManager {
}
}
- fun isBetaRelease(): Boolean {
+ fun isCurrentlyBeta(): Boolean {
return getCurrentVersion().contains("beta", ignoreCase = true)
}
- val config get() = SkyHanniMod.feature.about
+ private val config get() = SkyHanniMod.feature.about
fun reset() {
updateState = UpdateState.NONE
@@ -82,7 +82,7 @@ object UpdateManager {
}
logger.log("Starting update check")
var updateStream = config.updateStream.get()
- if (updateStream == About.UpdateStream.RELEASES && isBetaRelease()) {
+ if (updateStream == About.UpdateStream.RELEASES && isCurrentlyBeta()) {
updateStream = About.UpdateStream.BETA
}
activePromise = context.checkUpdate(updateStream.stream)
@@ -96,7 +96,7 @@ object UpdateManager {
if (it.isUpdateAvailable) {
updateState = UpdateState.AVAILABLE
LorenzUtils.clickableChat(
- "§e[SkyHanni] §aSkyHanni found a new update: ${it.update.versionName}. " +
+ "§aSkyHanni found a new update: ${it.update.versionName}. " +
"Check §b/sh download update §afor more info.",
"sh"
)
@@ -119,7 +119,7 @@ object UpdateManager {
}, MinecraftExecutor.OnThread)
}
- val context = UpdateContext(
+ private val context = UpdateContext(
UpdateSource.githubUpdateSource("hannibal002", "SkyHanni"),
UpdateTarget.deleteAndSaveInTheSameFolder(UpdateManager::class.java),
CurrentVersion.ofTag(SkyHanniMod.version),
@@ -137,5 +137,5 @@ object UpdateManager {
NONE
}
- var potentialUpdate: PotentialUpdate? = null
+ private var potentialUpdate: PotentialUpdate? = null
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/visualwords/VisualWordGui.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/visualwords/VisualWordGui.kt
index 6e9ef14cc..a996d7277 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/visualwords/VisualWordGui.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/visualwords/VisualWordGui.kt
@@ -1,8 +1,13 @@
package at.hannibal2.skyhanni.features.misc.visualwords
import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.config.ConfigManager
+import at.hannibal2.skyhanni.test.command.ErrorManager
import at.hannibal2.skyhanni.utils.*
+import at.hannibal2.skyhanni.utils.LorenzUtils.chat
import at.hannibal2.skyhanni.utils.StringUtils.convertToFormatted
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
+import com.google.gson.JsonObject
import kotlinx.coroutines.launch
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.GuiScreen
@@ -12,6 +17,8 @@ import net.minecraft.item.ItemStack
import net.minecraft.util.MathHelper
import org.lwjgl.input.Keyboard
import org.lwjgl.input.Mouse
+import java.io.File
+import java.io.FileReader
import java.io.IOException
open class VisualWordGui : GuiScreen() {
@@ -44,8 +51,31 @@ open class VisualWordGui : GuiScreen() {
private var modifiedWords = mutableListOf<VisualWord>()
+ private val shouldDrawImport get() = drawImport && !SkyHanniMod.feature.storage.visualWordsImported
+
companion object {
fun isInGui() = Minecraft.getMinecraft().currentScreen is VisualWordGui
+ var sbeConfigPath = File("." + File.separator + "config" + File.separator + "SkyblockExtras.cfg")
+ var drawImport = false
+
+ val itemUp by lazy {
+ ItemUtils.createSkull(
+ "§§Up",
+ "7f68dd73-1ff6-4193-b246-820975d6fab1",
+ "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzczMzRjZGRmY" +
+ "WI0NWQ3NWFkMjhlMWE0N2JmOGNmNTAxN2QyZjA5ODJmNjczN2RhMjJkNDk3Mjk1MjUxMDY2MSJ9fX0="
+ )
+ }
+
+ val itemDown by lazy {
+ ItemUtils.createSkull(
+ "§§Down",
+ "e4ace6de-0629-4719-aea3-3e113314dd3f",
+ "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZTc3NDIwMz" +
+ "RmNTlkYjg5MGM4MDA0MTU2YjcyN2M3N2NhNjk1YzQzOTlkOGUwZGE1Y2U5MjI3Y2Y4MzZiYjhlMiJ9fX0="
+ )
+ }
+
}
override fun drawScreen(unusedX: Int, unusedY: Int, partialTicks: Float) {
@@ -63,6 +93,8 @@ open class VisualWordGui : GuiScreen() {
val scale = 0.75f
val inverseScale = 1 / scale
+ val colorA = 0x50828282
+ val colorB = 0x50303030
if (!currentlyEditing) {
val adjustedY = guiTop + 30 + pageScroll
var toRemove: VisualWord? = null
@@ -71,10 +103,17 @@ open class VisualWordGui : GuiScreen() {
val y = guiTop + 170
drawUnmodifiedStringCentered("§aAdd New", x, y)
- val colour =
- if (GuiRenderUtils.isPointInRect(mouseX, mouseY, x - 30, y - 10, 60, 20)) 0x50828282 else 0x50303030
+ val colour = if (isPointInMousePos(x - 30, y - 10, 60, 20)) colorA else colorB
drawRect(x - 30, y - 10, x + 30, y + 10, colour)
+ if (shouldDrawImport) {
+ val importX = guiLeft + sizeX - 45
+ val importY = guiTop + sizeY - 10
+ GuiRenderUtils.drawStringCentered("§aImport from SBE", importX, importY)
+ val importColor = if (isPointInMousePos(importX - 45, importY - 10, 90, 20)) colorA else colorB
+ drawRect(importX - 45, importY - 10, importX + 45, importY + 10, importColor)
+ }
+
GlStateManager.scale(scale, scale, 1f)
drawUnmodifiedStringCentered(
@@ -94,31 +133,36 @@ open class VisualWordGui : GuiScreen() {
}
var inBox = false
- if (GuiRenderUtils.isPointInRect(mouseX, mouseY, guiLeft, adjustedY + 30 * index, sizeX, 30)) inBox = true
+ if (isPointInMousePos(guiLeft, adjustedY + 30 * index, sizeX, 30)) {
+ inBox = true
+ }
- drawUnmodifiedString("${index + 1}.", (guiLeft + 5) * inverseScale, (adjustedY + 10 + 30 * index) * inverseScale)
+ drawUnmodifiedString(
+ "${index + 1}.",
+ (guiLeft + 5) * inverseScale,
+ (adjustedY + 10 + 30 * index) * inverseScale
+ )
- if (GuiRenderUtils.isPointInRect(lastClickedWidth, lastClickedHeight, guiLeft + 335, adjustedY + 30 * index + 7, 16, 16)) {
+ val top = adjustedY + 30 * index + 7
+ if (isPointInLastClicked(guiLeft + 335, top, 16, 16)) {
lastClickedWidth = 0
lastClickedHeight = 0
phrase.enabled = !phrase.enabled
saveChanges()
SoundUtils.playClickSound()
- } else if (GuiRenderUtils.isPointInRect(lastClickedWidth, lastClickedHeight, guiLeft + 295,
- adjustedY + 30 * index + 7, 16, 16) && index != 0) {
+ } else if (isPointInLastClicked(guiLeft + 295, top, 16, 16) && index != 0) {
lastClickedWidth = 0
lastClickedHeight = 0
SoundUtils.playClickSound()
changedIndex = index
changedAction = ActionType.UP
- } else if (GuiRenderUtils.isPointInRect(lastClickedWidth, lastClickedHeight, guiLeft + 315,
- adjustedY + 30 * index + 7, 16, 16) && index != modifiedWords.size - 1) {
+ } else if (isPointInLastClicked(guiLeft + 315, top, 16, 16) && index != modifiedWords.size - 1) {
lastClickedWidth = 0
lastClickedHeight = 0
SoundUtils.playClickSound()
changedIndex = index
changedAction = ActionType.DOWN
- } else if (GuiRenderUtils.isPointInRect(lastClickedWidth, lastClickedHeight, guiLeft, adjustedY + 30 * index, sizeX, 30)) {
+ } else if (isPointInLastClicked(guiLeft, adjustedY + 30 * index, sizeX, 30)) {
lastClickedWidth = 0
lastClickedHeight = 0
SoundUtils.playClickSound()
@@ -127,7 +171,14 @@ open class VisualWordGui : GuiScreen() {
}
if (inBox) {
- GuiRenderUtils.drawScaledRec(guiLeft, adjustedY + 30 * index, guiLeft + sizeX, adjustedY + 30 * index + 30, 0x50303030, inverseScale)
+ GuiRenderUtils.drawScaledRec(
+ guiLeft,
+ adjustedY + 30 * index,
+ guiLeft + sizeX,
+ adjustedY + 30 * index + 30,
+ colorB,
+ inverseScale
+ )
}
val statusBlock = if (phrase.enabled) {
@@ -139,24 +190,38 @@ open class VisualWordGui : GuiScreen() {
GlStateManager.scale(inverseScale, inverseScale, 1f)
if (index != 0) {
- val skullItem = ItemUtils.createSkull("§§Up", "7f68dd73-1ff6-4193-b246-820975d6fab1", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzczMzRjZGRmYWI0NWQ3NWFkMjhlMWE0N2JmOGNmNTAxN2QyZjA5ODJmNjczN2RhMjJkNDk3Mjk1MjUxMDY2MSJ9fX0=")
- GuiRenderUtils.renderItemAndBackground(skullItem, guiLeft + 295, adjustedY + 30 * index + 7, 0x50828282)
+ GuiRenderUtils.renderItemAndBackground(itemUp, guiLeft + 295, top, colorA)
}
if (index != modifiedWords.size - 1) {
- val skullItem = ItemUtils.createSkull("§§Down", "e4ace6de-0629-4719-aea3-3e113314dd3f", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZTc3NDIwMzRmNTlkYjg5MGM4MDA0MTU2YjcyN2M3N2NhNjk1YzQzOTlkOGUwZGE1Y2U5MjI3Y2Y4MzZiYjhlMiJ9fX0=")
- GuiRenderUtils.renderItemAndBackground(skullItem, guiLeft + 315, adjustedY + 30 * index + 7, 0x50828282)
+ GuiRenderUtils.renderItemAndBackground(itemDown, guiLeft + 315, top, colorA)
}
- GuiRenderUtils.renderItemAndBackground(statusBlock, guiLeft + 335, adjustedY + 30 * index + 7, 0x50828282)
+ GuiRenderUtils.renderItemAndBackground(statusBlock, guiLeft + 335, top, colorA)
GlStateManager.scale(scale, scale, 1f)
if (inBox) {
- drawUnmodifiedString(phrase.phrase, (guiLeft + 15) * inverseScale, (adjustedY + 5 + 30 * index) * inverseScale)
- drawUnmodifiedString(phrase.replacement, (guiLeft + 15) * inverseScale, (adjustedY + 15 + 30 * index) * inverseScale)
+ drawUnmodifiedString(
+ phrase.phrase,
+ (guiLeft + 15) * inverseScale,
+ (adjustedY + 5 + 30 * index) * inverseScale
+ )
+ drawUnmodifiedString(
+ phrase.replacement,
+ (guiLeft + 15) * inverseScale,
+ (adjustedY + 15 + 30 * index) * inverseScale
+ )
} else {
- drawUnmodifiedString(phrase.phrase.convertToFormatted(), (guiLeft + 15) * inverseScale, (adjustedY + 5 + 30 * index) * inverseScale)
- drawUnmodifiedString(phrase.replacement.convertToFormatted(), (guiLeft + 15) * inverseScale, (adjustedY + 15 + 30 * index) * inverseScale)
+ drawUnmodifiedString(
+ phrase.phrase.convertToFormatted(),
+ (guiLeft + 15) * inverseScale,
+ (adjustedY + 5 + 30 * index) * inverseScale
+ )
+ drawUnmodifiedString(
+ phrase.replacement.convertToFormatted(),
+ (guiLeft + 15) * inverseScale,
+ (adjustedY + 15 + 30 * index) * inverseScale
+ )
}
}
@@ -172,16 +237,15 @@ open class VisualWordGui : GuiScreen() {
GlStateManager.scale(inverseScale, inverseScale, 1f)
scrollScreen()
- }
- else {
+ } else {
var x = guiLeft + 180
var y = guiTop + 140
drawUnmodifiedStringCentered("§cDelete", x, y)
- var colour = if (GuiRenderUtils.isPointInRect(mouseX, mouseY, x - 30, y - 10, 60, 20)) 0x50828282 else 0x50303030
+ var colour = if (isPointInMousePos(x - 30, y - 10, 60, 20)) colorA else colorB
drawRect(x - 30, y - 10, x + 30, y + 10, colour)
y += 30
drawUnmodifiedStringCentered("§eBack", x, y)
- colour = if (GuiRenderUtils.isPointInRect(mouseX, mouseY, x - 30, y - 10, 60, 20)) 0x50828282 else 0x50303030
+ colour = if (isPointInMousePos(x - 30, y - 10, 60, 20)) colorA else colorB
drawRect(x - 30, y - 10, x + 30, y + 10, colour)
if (currentIndex < modifiedWords.size && currentIndex != -1) {
@@ -191,45 +255,74 @@ open class VisualWordGui : GuiScreen() {
drawUnmodifiedStringCentered("§bReplacement Enabled", x, y - 20)
var status = if (currentPhrase.enabled) "§2Enabled" else "§4Disabled"
drawUnmodifiedStringCentered(status, x, y)
- colour = if (GuiRenderUtils.isPointInRect(mouseX, mouseY, x - 30, y - 10, 60, 20)) 0x50828282 else 0x50303030
+ colour = if (isPointInMousePos(x - 30, y - 10, 60, 20)) colorA else colorB
drawRect(x - 30, y - 10, x + 30, y + 10, colour)
x += 200
drawUnmodifiedStringCentered("§bCase Sensitive", x, y - 20)
status = if (!currentPhrase.isCaseSensitive()) "§2True" else "§4False"
drawUnmodifiedStringCentered(status, x, y)
- colour = if (GuiRenderUtils.isPointInRect(mouseX, mouseY, x - 30, y - 10, 60, 20)) 0x50828282 else 0x50303030
+ colour = if (isPointInMousePos(x - 30, y - 10, 60, 20)) colorA else colorB
drawRect(x - 30, y - 10, x + 30, y + 10, colour)
drawUnmodifiedString("§bIs replaced by:", guiLeft + 30, guiTop + 75)
- if (GuiRenderUtils.isPointInRect(mouseX, mouseY, guiLeft, guiTop + 35, sizeX, 30)) {
- drawRect(guiLeft, guiTop + 35, guiLeft + sizeX, guiTop + 35 + 30, 0x50303030)
+ if (isPointInMousePos(guiLeft, guiTop + 35, sizeX, 30)) {
+ drawRect(guiLeft, guiTop + 35, guiLeft + sizeX, guiTop + 35 + 30, colorB)
}
if (currentTextBox == SelectedTextBox.PHRASE) {
- drawRect(guiLeft, guiTop + 35, guiLeft + sizeX, guiTop + 35 + 30, 0x50828282)
+ drawRect(guiLeft, guiTop + 35, guiLeft + sizeX, guiTop + 35 + 30, colorA)
}
- if (GuiRenderUtils.isPointInRect(mouseX, mouseY, guiLeft, guiTop + 90, sizeX, 30)) {
- drawRect(guiLeft, guiTop + 90, guiLeft + sizeX, guiTop + 90 + 30, 0x50303030)
+ if (isPointInMousePos(guiLeft, guiTop + 90, sizeX, 30)) {
+ drawRect(guiLeft, guiTop + 90, guiLeft + sizeX, guiTop + 90 + 30, colorB)
}
if (currentTextBox == SelectedTextBox.REPLACEMENT) {
- drawRect(guiLeft, guiTop + 90, guiLeft + sizeX, guiTop + 90 + 30, 0x50828282)
+ drawRect(guiLeft, guiTop + 90, guiLeft + sizeX, guiTop + 90 + 30, colorA)
}
GlStateManager.scale(0.75f, 0.75f, 1f)
- drawUnmodifiedString("§bThe top line of each section", (guiLeft + 10) * inverseScale, (guiTop + 12) * inverseScale)
- drawUnmodifiedString("§bis the preview of the bottom text", (guiLeft + 10) * inverseScale, (guiTop + 22) * inverseScale)
-
- drawUnmodifiedString("§bTo get the Minecraft", (guiLeft + 220) * inverseScale, (guiTop + 12) * inverseScale)
- drawUnmodifiedString("§b formatting character use \"&&\"", (guiLeft + 220) * inverseScale, (guiTop + 22) * inverseScale)
-
- drawUnmodifiedString(currentPhrase.phrase.convertToFormatted(), (guiLeft + 30) * inverseScale, (guiTop + 40) * inverseScale)
+ // TODO remove more code duplication
+ drawUnmodifiedString(
+ "§bThe top line of each section",
+ (guiLeft + 10) * inverseScale,
+ (guiTop + 12) * inverseScale
+ )
+ drawUnmodifiedString(
+ "§bis the preview of the bottom text",
+ (guiLeft + 10) * inverseScale,
+ (guiTop + 22) * inverseScale
+ )
+
+ drawUnmodifiedString(
+ "§bTo get the Minecraft",
+ (guiLeft + 220) * inverseScale,
+ (guiTop + 12) * inverseScale
+ )
+ drawUnmodifiedString(
+ "§b formatting character use \"&&\"",
+ (guiLeft + 220) * inverseScale,
+ (guiTop + 22) * inverseScale
+ )
+
+ drawUnmodifiedString(
+ currentPhrase.phrase.convertToFormatted(),
+ (guiLeft + 30) * inverseScale,
+ (guiTop + 40) * inverseScale
+ )
drawUnmodifiedString(currentPhrase.phrase, (guiLeft + 30) * inverseScale, (guiTop + 55) * inverseScale)
- drawUnmodifiedString(currentPhrase.replacement.convertToFormatted(), (guiLeft + 30) * inverseScale, (guiTop + 95) * inverseScale)
- drawUnmodifiedString(currentPhrase.replacement, (guiLeft + 30) * inverseScale, (guiTop + 110) * inverseScale)
+ drawUnmodifiedString(
+ currentPhrase.replacement.convertToFormatted(),
+ (guiLeft + 30) * inverseScale,
+ (guiTop + 95) * inverseScale
+ )
+ drawUnmodifiedString(
+ currentPhrase.replacement,
+ (guiLeft + 30) * inverseScale,
+ (guiTop + 110) * inverseScale
+ )
GlStateManager.scale(inverseScale, inverseScale, 1f)
}
@@ -242,8 +335,7 @@ open class VisualWordGui : GuiScreen() {
modifiedWords[changedIndex] = modifiedWords[changedIndex - 1]
modifiedWords[changedIndex - 1] = temp
}
- }
- else if (changedAction == ActionType.DOWN) {
+ } else if (changedAction == ActionType.DOWN) {
if (changedIndex < modifiedWords.size - 1) {
val temp = modifiedWords[changedIndex]
modifiedWords[changedIndex] = modifiedWords[changedIndex + 1]
@@ -259,6 +351,12 @@ open class VisualWordGui : GuiScreen() {
GlStateManager.popMatrix()
}
+ private fun isPointInMousePos(left: Int, top: Int, width: Int, height: Int) =
+ GuiRenderUtils.isPointInRect(mouseX, mouseY, left, top, width, height)
+
+ private fun isPointInLastClicked(left: Int, top: Int, width: Int, height: Int) =
+ GuiRenderUtils.isPointInRect(lastClickedWidth, lastClickedHeight, left, top, width, height)
+
override fun handleMouseInput() {
super.handleMouseInput()
@@ -276,7 +374,7 @@ open class VisualWordGui : GuiScreen() {
@Throws(IOException::class)
fun mouseClickEvent() {
if (!currentlyEditing) {
- if (GuiRenderUtils.isPointInRect(mouseX, mouseY, guiLeft, guiTop, sizeX, sizeY - 25)) {
+ if (isPointInMousePos(guiLeft, guiTop, sizeX, sizeY - 25)) {
lastClickedWidth = mouseX
lastClickedHeight = mouseY
}
@@ -284,7 +382,7 @@ open class VisualWordGui : GuiScreen() {
var x = guiLeft + 180
var y = guiTop + 140
if (currentlyEditing) {
- if (GuiRenderUtils.isPointInRect(mouseX, mouseY, x - 30, y - 10, 60, 20)) {
+ if (isPointInMousePos(x - 30, y - 10, 60, 20)) {
SoundUtils.playClickSound()
currentlyEditing = false
modifiedWords.removeAt(currentIndex)
@@ -295,21 +393,21 @@ open class VisualWordGui : GuiScreen() {
if (currentIndex < modifiedWords.size && currentIndex != -1) {
x -= 100
y += 30
- if (GuiRenderUtils.isPointInRect(mouseX, mouseY, x - 30, y - 10, 60, 20)) {
+ if (isPointInMousePos(x - 30, y - 10, 60, 20)) {
SoundUtils.playClickSound()
modifiedWords[currentIndex].enabled = !modifiedWords[currentIndex].enabled
saveChanges()
}
x += 200
- if (GuiRenderUtils.isPointInRect(mouseX, mouseY, x - 30, y - 10, 60, 20)) {
+ if (isPointInMousePos(x - 30, y - 10, 60, 20)) {
SoundUtils.playClickSound()
modifiedWords[currentIndex].setCaseSensitive(!modifiedWords[currentIndex].isCaseSensitive())
saveChanges()
- } else if (GuiRenderUtils.isPointInRect(mouseX, mouseY, guiLeft, guiTop + 35, sizeX, 30)) {
+ } else if (isPointInMousePos(guiLeft, guiTop + 35, sizeX, 30)) {
SoundUtils.playClickSound()
currentTextBox = SelectedTextBox.PHRASE
currentText = modifiedWords[currentIndex].phrase
- } else if (GuiRenderUtils.isPointInRect(mouseX, mouseY, guiLeft, guiTop + 90, sizeX, 30)) {
+ } else if (isPointInMousePos(guiLeft, guiTop + 90, sizeX, 30)) {
SoundUtils.playClickSound()
currentTextBox = SelectedTextBox.REPLACEMENT
currentText = modifiedWords[currentIndex].replacement
@@ -323,7 +421,7 @@ open class VisualWordGui : GuiScreen() {
}
y = guiTop + 170
x = guiLeft + 180
- if (GuiRenderUtils.isPointInRect(mouseX, mouseY, x - 30, y - 10, 60, 20)) {
+ if (isPointInMousePos(x - 30, y - 10, 60, 20)) {
SoundUtils.playClickSound()
if (currentlyEditing) {
val currentVisualWord = modifiedWords.elementAt(currentIndex)
@@ -336,7 +434,7 @@ open class VisualWordGui : GuiScreen() {
currentIndex = -1
currentTextBox = SelectedTextBox.NONE
} else {
- modifiedWords.add(VisualWord("", "", true, false))
+ modifiedWords.add(VisualWord("", "", true, caseSensitive = false))
currentTextBox = SelectedTextBox.PHRASE
currentText = ""
currentIndex = modifiedWords.size - 1
@@ -346,6 +444,14 @@ open class VisualWordGui : GuiScreen() {
}
currentlyEditing = !currentlyEditing
}
+ if (shouldDrawImport) {
+ val importX = guiLeft + sizeX - 45
+ val importY = guiTop + sizeY - 10
+ if (isPointInMousePos(importX - 45, importY - 10, 90, 20)) {
+ SoundUtils.playClickSound()
+ tryImportFromSBE()
+ }
+ }
}
@Throws(IOException::class)
@@ -452,6 +558,39 @@ open class VisualWordGui : GuiScreen() {
SkyHanniMod.feature.storage.modifiedWords = modifiedWords
}
+ private fun tryImportFromSBE() {
+ if (!drawImport) return
+ try {
+ val json = ConfigManager.gson.fromJson(FileReader(sbeConfigPath), JsonObject::class.java)
+ var importedWords = 0
+ var skippedWords = 0
+ val lists = json["custom"].asJsonObject["visualWords"].asJsonArray
+ val pattern = "(?<from>.*)@-(?<to>.*)@:-(?<state>false|true)".toPattern()
+ loop@ for (line in lists) {
+ pattern.matchMatcher(line.asString) {
+ val from = group("from").replace("&", "&&")
+ val to = group("to").replace("&", "&&")
+ val state = group("state").toBoolean()
+
+ if (modifiedWords.any { it.phrase == from }) {
+ skippedWords++
+ continue@loop
+ }
+
+ modifiedWords.add(VisualWord(from, to, state, false))
+ importedWords++
+ }
+ }
+ if (importedWords > 0 || skippedWords > 0) {
+ chat("§aSuccessfully imported §e$importedWords §aand skipped §e$skippedWords §aVisualWords from SkyBlockExtras !")
+ SkyHanniMod.feature.storage.visualWordsImported = true
+ drawImport = false
+ }
+ } catch (t: Throwable) {
+ ErrorManager.logError(t, "Failed to load visual words from SBE")
+ }
+ }
+
private fun drawUnmodifiedString(str: String, x: Float, y: Float) {
GuiRenderUtils.drawString("§§$str", x, y)
}
@@ -479,4 +618,4 @@ private enum class SelectedTextBox {
PHRASE,
REPLACEMENT,
NONE
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/PabloHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/PabloHelper.kt
new file mode 100644
index 000000000..a2e4d30ac
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/PabloHelper.kt
@@ -0,0 +1,41 @@
+package at.hannibal2.skyhanni.features.nether
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.IslandType
+import at.hannibal2.skyhanni.events.LorenzChatEvent
+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.isInIsland
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatchers
+import at.hannibal2.skyhanni.utils.StringUtils.removeColor
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import kotlin.time.Duration.Companion.minutes
+
+// https://wiki.hypixel.net/Pablo
+class PabloHelper {
+ private val config get() = SkyHanniMod.feature.crimsonIsle
+
+ private val patterns = listOf(
+ "\\[NPC] Pablo: Could you bring me an (?<flower>[\\w ]+).*".toPattern(),
+ "\\[NPC] Pablo: Bring me that (?<flower>[\\w ]+) as soon as you can!".toPattern()
+ )
+ private var lastSentMessage = SimpleTimeMark.farPast()
+
+ @SubscribeEvent
+ fun onChat(event: LorenzChatEvent) {
+ if (!isEnabled()) return
+ if (lastSentMessage.passedSince() < 5.minutes) return
+ val itemName = patterns.matchMatchers(event.message.removeColor()) {
+ group("flower")
+ } ?: return
+
+ if (InventoryUtils.countItemsInLowerInventory { it.name?.contains(itemName) == true } > 0) return
+
+ LorenzUtils.clickableChat("Click here to grab an $itemName from sacks!", "gfs $itemName 1")
+ lastSentMessage = SimpleTimeMark.now()
+ }
+
+ fun isEnabled() = IslandType.CRIMSON_ISLE.isInIsland() && config.pabloHelper
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/QuestItemHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/QuestItemHelper.kt
index 9c23ce8e3..40439571b 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/nether/QuestItemHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/QuestItemHelper.kt
@@ -3,6 +3,8 @@ package at.hannibal2.skyhanni.features.nether
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
+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.isInIsland
import at.hannibal2.skyhanni.utils.SimpleTimeMark
@@ -15,8 +17,6 @@ class QuestItemHelper {
private val config get() = SkyHanniMod.feature.crimsonIsle
private val itemCollectionPattern = ". (?<name>[\\w ]+) x(?<amount>\\d+)".toPattern()
- private var questItem = ""
- private var questAmount = 0
private var lastSentMessage = SimpleTimeMark.farPast()
@SubscribeEvent
@@ -24,18 +24,22 @@ class QuestItemHelper {
if (!isEnabled()) return
if (event.inventoryName != "Fetch") return
if (lastSentMessage.passedSince() < 1.hours) return
- items@ for ((_, item) in event.inventoryItems) {
- itemCollectionPattern.matchMatcher(item.displayName.removeColor()) {
- if (!matches()) continue@items
- questItem = group("name")
- questAmount = group("amount").toInt()
- LorenzUtils.clickableChat(
- "§e[SkyHanni] Click here to grab x$questAmount $questItem from sacks!",
- "gfs $questItem $questAmount"
- )
- lastSentMessage = SimpleTimeMark.now()
- break@items
- }
+
+ for ((_, item) in event.inventoryItems) {
+ val (questItem, need) = itemCollectionPattern.matchMatcher(item.displayName.removeColor()) {
+ group("name") to group("amount").toInt()
+ } ?: continue
+
+ val have = InventoryUtils.countItemsInLowerInventory { it.name?.contains(questItem) == true }
+ if (have >= need) break
+
+ val missingAmount = need - have
+ LorenzUtils.clickableChat(
+ "Click here to grab x$missingAmount $questItem from sacks!",
+ "gfs $questItem $missingAmount"
+ )
+ lastSentMessage = SimpleTimeMark.now()
+ break
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazes.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazes.kt
index 28ff6f7df..b5aff0bf4 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazes.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazes.kt
@@ -14,6 +14,7 @@ import at.hannibal2.skyhanni.utils.EntityUtils
import at.hannibal2.skyhanni.utils.EntityUtils.getAllNameTagsWith
import at.hannibal2.skyhanni.utils.LorenzColor
import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy
import net.minecraft.entity.EntityLivingBase
import net.minecraft.entity.item.EntityArmorStand
import net.minecraft.entity.monster.EntityBlaze
@@ -25,9 +26,9 @@ class AshfangBlazes {
private val config get() = SkyHanniMod.feature.crimsonIsle.ashfang
private val blazeColor = mutableMapOf<EntityBlaze, LorenzColor>()
- private val blazeArmorStand = mutableMapOf<EntityBlaze, EntityArmorStand>()
+ private var blazeArmorStand = mapOf<EntityBlaze, EntityArmorStand>()
- var nearAshfang = false
+ private var nearAshfang = false
@SubscribeEvent
fun onTick(event: LorenzTickEvent) {
@@ -43,19 +44,21 @@ class AshfangBlazes {
val list = entity.getAllNameTagsWith(2, "Ashfang")
if (list.size == 1) {
val armorStand = list[0]
- blazeArmorStand[entity] = armorStand
val color = when {
armorStand.name.contains("Ashfang Follower") -> LorenzColor.DARK_GRAY
armorStand.name.contains("Ashfang Underling") -> LorenzColor.RED
armorStand.name.contains("Ashfang Acolyte") -> LorenzColor.BLUE
else -> {
- blazeArmorStand.remove(entity)
- null
+ blazeArmorStand = blazeArmorStand.editCopy {
+ remove(entity)
+ }
+ continue
}
}
- color?.let {
- blazeColor[entity] = it
+ blazeArmorStand = blazeArmorStand.editCopy {
+ this[entity] = armorStand
}
+ blazeColor[entity] = color
}
}
}
@@ -69,7 +72,9 @@ class AshfangBlazes {
if (entityId !in blazeArmorStand.keys.map { it.entityId }) return
if (event.health % 10_000_000 != 0) {
- blazeArmorStand.keys.removeIf { it.entityId == entityId }
+ blazeArmorStand = blazeArmorStand.editCopy {
+ keys.removeIf { it.entityId == entityId }
+ }
}
}
@@ -112,7 +117,7 @@ class AshfangBlazes {
@SubscribeEvent
fun onWorldChange(event: LorenzWorldChangeEvent) {
blazeColor.clear()
- blazeArmorStand.clear()
+ blazeArmorStand = emptyMap()
}
@SubscribeEvent
@@ -125,4 +130,4 @@ class AshfangBlazes {
private fun isEnabled(): Boolean {
return LorenzUtils.inSkyBlock && DamageIndicatorManager.isBossSpawned(BossType.NETHER_ASHFANG)
}
-} \ No newline at end of file
+}
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 74b94c0c9..8d7507e12 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
@@ -65,5 +65,5 @@ class AshfangBlazingSouls {
}
private fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled &&
- DamageIndicatorManager.isBossSpawned(BossType.NETHER_ASHFANG)
-} \ No newline at end of file
+ DamageIndicatorManager.isBossSpawned(BossType.NETHER_ASHFANG)
+}
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 161df6a8c..5fd7a3b77 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
@@ -51,6 +51,6 @@ class AshfangFreezeCooldown {
private fun isEnabled(): Boolean {
return LorenzUtils.inSkyBlock && config.freezeCooldown &&
- DamageIndicatorManager.isBossSpawned(BossType.NETHER_ASHFANG)
+ DamageIndicatorManager.isBossSpawned(BossType.NETHER_ASHFANG)
}
-} \ No newline at end of file
+}
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 68837bad4..5b3fc60de 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
@@ -23,7 +23,7 @@ class AshfangGravityOrbs {
private val config get() = SkyHanniMod.feature.crimsonIsle.ashfang.gravityOrbs
private val texture = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV" +
- "0L3RleHR1cmUvMWE2OWNjZjdhZDkwNGM5YTg1MmVhMmZmM2Y1YjRlMjNhZGViZjcyZWQxMmQ1ZjI0Yjc4Y2UyZDQ0YjRhMiJ9fX0="
+ "0L3RleHR1cmUvMWE2OWNjZjdhZDkwNGM5YTg1MmVhMmZmM2Y1YjRlMjNhZGViZjcyZWQxMmQ1ZjI0Yjc4Y2UyZDQ0YjRhMiJ9fX0="
private val orbs = mutableListOf<EntityArmorStand>()
@SubscribeEvent
@@ -68,5 +68,5 @@ class AshfangGravityOrbs {
}
private fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled &&
- DamageIndicatorManager.isBossSpawned(BossType.NETHER_ASHFANG)
-} \ No newline at end of file
+ DamageIndicatorManager.isBossSpawned(BossType.NETHER_ASHFANG)
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHideDamageIndicator.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHideDamageIndicator.kt
index 99351747f..157c260fa 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHideDamageIndicator.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHideDamageIndicator.kt
@@ -28,5 +28,5 @@ class AshfangHideDamageIndicator {
private fun isEnabled() =
LorenzUtils.inSkyBlock && SkyHanniMod.feature.crimsonIsle.ashfang.hide.damageSplash &&
- DamageIndicatorManager.isBossSpawned(BossType.NETHER_ASHFANG)
-} \ No newline at end of file
+ DamageIndicatorManager.isBossSpawned(BossType.NETHER_ASHFANG)
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangNextResetCooldown.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangNextResetCooldown.kt
index 42d98cdbb..68c3d9382 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangNextResetCooldown.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangNextResetCooldown.kt
@@ -60,6 +60,6 @@ class AshfangNextResetCooldown {
private fun isEnabled(): Boolean {
return LorenzUtils.inSkyBlock && config.nextResetCooldown &&
- DamageIndicatorManager.isBossSpawned(BossType.NETHER_ASHFANG)
+ DamageIndicatorManager.isBossSpawned(BossType.NETHER_ASHFANG)
}
-} \ No newline at end of file
+}
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 c689aadc2..ec03ad514 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
@@ -15,6 +15,7 @@ import at.hannibal2.skyhanni.features.nether.reputationhelper.miniboss.DailyMini
import at.hannibal2.skyhanni.utils.KeyboardManager.isKeyHeld
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
+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
@@ -66,8 +67,7 @@ class CrimsonIsleReputationHelper(skyHanniMod: SkyHanniMod) {
@SubscribeEvent
fun onTick(event: LorenzTickEvent) {
- if (!LorenzUtils.inSkyBlock) return
- if (LorenzUtils.skyBlockIsland != IslandType.CRIMSON_ISLE) return
+ if (!IslandType.CRIMSON_ISLE.isInIsland()) return
if (!config.enabled) return
if (!dirty && display.isEmpty()) {
dirty = true
@@ -111,9 +111,7 @@ class CrimsonIsleReputationHelper(skyHanniMod: SkyHanniMod) {
@SubscribeEvent(priority = EventPriority.LOWEST)
fun renderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
if (!config.enabled) return
-
- if (!LorenzUtils.inSkyBlock) return
- if (LorenzUtils.skyBlockIsland != IslandType.CRIMSON_ISLE) return
+ if (!IslandType.CRIMSON_ISLE.isInIsland()) return
if (config.useHotkey && !config.hotkey.isKeyHeld()) {
return
@@ -145,7 +143,7 @@ class CrimsonIsleReputationHelper(skyHanniMod: SkyHanniMod) {
}
fun reset() {
- LorenzUtils.chat("§e[SkyHanni] Reset Reputation Helper.")
+ LorenzUtils.chat("Reset Reputation Helper.")
questHelper.reset()
miniBossHelper.reset()
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 39e888ade..a14da5859 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
@@ -46,8 +46,8 @@ class DailyKuudraBossHelper(private val reputationHelper: CrimsonIsleReputationH
if (!message.contains("KUUDRA DOWN!") || message.contains(":")) return
for (line in ScoreboardData.sidebarLines) {
- if(line.contains("Kuudra's") && line.contains("Hollow") && line.contains("(")){
- val tier = line.substringAfter("(T").substring(0,1).toInt()
+ if (line.contains("Kuudra's") && line.contains("Hollow") && line.contains("(")) {
+ val tier = line.substringAfter("(T").substring(0, 1).toInt()
val kuudraTier = getByTier(tier)!!
finished(kuudraTier)
return
@@ -129,4 +129,4 @@ class DailyKuudraBossHelper(private val reputationHelper: CrimsonIsleReputationH
private fun getByDisplayName(name: String) = kuudraTiers.firstOrNull { it.name == name }
private fun getByTier(number: Int) = kuudraTiers.firstOrNull { it.tierNumber == number }
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/DailyQuestHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/DailyQuestHelper.kt
index 2090d77e4..2b2de9187 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/DailyQuestHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/DailyQuestHelper.kt
@@ -181,7 +181,7 @@ class DailyQuestHelper(val reputationHelper: CrimsonIsleReputationHelper) {
count = needAmount
}
if (quest.haveAmount == count) return
- LorenzUtils.chat("§e[SkyHanni] ${quest.displayName} progress: $count/$needAmount")
+ LorenzUtils.chat("${quest.displayName} progress: $count/$needAmount")
quest.haveAmount = count
quest.state = if (count == needAmount) QuestState.READY_TO_COLLECT else QuestState.ACCEPTED
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 41ac1a9c7..6184fd51e 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
@@ -122,7 +122,7 @@ class QuestLoader(private val dailyQuestHelper: DailyQuestHelper) {
"DOJO" -> return DojoQuest(questName, location, displayItem, dojoGoal, state)
}
}
- LorenzUtils.chat("§c[SkyHanni] Unknown Crimson Isle quest: '$name'")
+ LorenzUtils.error("Unknown Crimson Isle quest: '$name'")
return UnknownQuest(name)
}
@@ -157,11 +157,9 @@ class QuestLoader(private val dailyQuestHelper: DailyQuestHelper) {
fun loadConfig(storage: Storage.ProfileSpecific.CrimsonIsleStorage) {
if (dailyQuestHelper.greatSpook) return
- for (text in storage.quests.toList()) {
- if (text.contains("The Great Spook")) {
- dailyQuestHelper.greatSpook = true
- return
- }
+ if (storage.quests.toList().any { hasGreatSpookLine(it) }) {
+ dailyQuestHelper.greatSpook = true
+ return
}
for (text in storage.quests.toList()) {
val split = text.split(":")
@@ -182,6 +180,15 @@ class QuestLoader(private val dailyQuestHelper: DailyQuestHelper) {
}
}
+ private fun hasGreatSpookLine(text: String) = when {
+ text.contains("The Great Spook") -> true
+ text.contains(" Days") -> true
+ text.contains("Fear: §r") -> true
+ text.contains("Primal Fears") -> true
+
+ else -> false
+ }
+
private fun addQuest(element: Quest) {
dailyQuestHelper.quests.add(element)
if (dailyQuestHelper.quests.size > 5) {
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 10eae5816..52f5c23f4 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
@@ -13,7 +13,7 @@ import at.hannibal2.skyhanni.utils.LocationUtils
import at.hannibal2.skyhanni.utils.LorenzColor
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
-import at.hannibal2.skyhanni.utils.NEUItems
+import at.hannibal2.skyhanni.utils.NEUItems.getItemStack
import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.jsonobjects.CrimsonIsleReputationJson.ReputationQuest
@@ -55,14 +55,10 @@ class DailyMiniBossHelper(private val reputationHelper: CrimsonIsleReputationHel
}
}
- private fun needMiniBossQuest(miniBoss: CrimsonMiniBoss): Boolean {
- val bossQuest = reputationHelper.questHelper.getQuest<MiniBossQuest>()
- if (bossQuest != null && bossQuest.miniBoss == miniBoss && bossQuest.state == QuestState.ACCEPTED) {
- return true
- }
-
- return false
- }
+ private fun needMiniBossQuest(miniBoss: CrimsonMiniBoss) =
+ reputationHelper.questHelper.getQuest<MiniBossQuest>()?.let {
+ it.miniBoss == miniBoss && it.state == QuestState.ACCEPTED
+ } ?: false
private fun finished(miniBoss: CrimsonMiniBoss) {
reputationHelper.questHelper.finishMiniBoss(miniBoss)
@@ -84,7 +80,7 @@ class DailyMiniBossHelper(private val reputationHelper: CrimsonIsleReputationHel
} else {
val lineList = mutableListOf<Any>()
lineList.add(" ")
- lineList.add(NEUItems.getItemStack(displayItem))
+ lineList.add(getItemStack(displayItem))
lineList.add("§5$displayName§7: $result")
display.add(lineList)
}
@@ -123,4 +119,4 @@ class DailyMiniBossHelper(private val reputationHelper: CrimsonIsleReputationHel
}
private fun getByDisplayName(name: String) = miniBosses.firstOrNull { it.displayName == name }
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/RiftAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/RiftAPI.kt
index 3a37cc435..ab3fa40c1 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/RiftAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/RiftAPI.kt
@@ -1,16 +1,17 @@
package at.hannibal2.skyhanni.features.rift
import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.config.features.RiftConfig
+import at.hannibal2.skyhanni.config.features.rift.RiftConfig
import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland
import at.hannibal2.skyhanni.utils.NEUInternalName
import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
import net.minecraft.item.ItemStack
object RiftAPI {
- fun inRift() = LorenzUtils.inIsland(IslandType.THE_RIFT)
+ fun inRift() = IslandType.THE_RIFT.isInIsland()
val config: RiftConfig get() = SkyHanniMod.feature.rift
@@ -28,6 +29,7 @@ object RiftAPI {
fun inLivingCave() = LorenzUtils.skyBlockArea == "Living Cave"
fun inLivingStillness() = LorenzUtils.skyBlockArea == "Living Stillness"
- fun inStillgoreChateau() = LorenzUtils.skyBlockArea == "Stillgore Château" || LorenzUtils.skyBlockArea == "Oubliette"
+ fun inStillgoreChateau() = LorenzUtils.skyBlockArea.let { it == "Stillgore Château" || it == "Oubliette" }
+
fun inDreadfarm() = LorenzUtils.skyBlockArea == "Dreadfarm"
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/colosseum/BlobbercystsHighlight.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/colosseum/BlobbercystsHighlight.kt
index ceb8b5931..9fad9e999 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/colosseum/BlobbercystsHighlight.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/colosseum/BlobbercystsHighlight.kt
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.features.rift.area.colosseum
import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
import at.hannibal2.skyhanni.events.withAlpha
@@ -15,7 +16,7 @@ import java.awt.Color
class BlobbercystsHighlight {
- private val config get() = SkyHanniMod.feature.rift.area.colosseumConfig
+ private val config get() = SkyHanniMod.feature.rift.area.colosseum
private val entityList = mutableListOf<EntityOtherPlayerMP>()
private val blobberName = "Blobbercyst "
@@ -47,4 +48,9 @@ class BlobbercystsHighlight {
}
fun isEnabled() = RiftAPI.inRift() && config.highlightBlobbercysts && LorenzUtils.skyBlockArea == "Colosseum"
-} \ No newline at end of file
+
+ @SubscribeEvent
+ fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
+ event.move(9, "rift.area.colosseumConfig", "rift.area.colosseum")
+ }
+}
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 fb37bfabe..5ef56976f 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
@@ -1,5 +1,6 @@
package at.hannibal2.skyhanni.features.rift.area.dreadfarm
+import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.features.rift.RiftAPI
@@ -14,7 +15,7 @@ import at.hannibal2.skyhanni.utils.TimeUtils
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class RiftAgaricusCap {
- private val config get() = RiftAPI.config.area.dreadfarmConfig
+ private val config get() = RiftAPI.config.area.dreadfarm
private var startTime = 0L
private var location: LorenzVec? = null
@@ -71,4 +72,9 @@ class RiftAgaricusCap {
}
fun isEnabled() = RiftAPI.inRift() && config.agaricusCap
+
+ @SubscribeEvent
+ fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
+ event.move(9, "rift.area.dreadfarmConfig", "rift.area.dreadfarm")
+ }
}
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 0058971ef..e17bd32ed 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
@@ -21,7 +21,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import java.awt.Color
class RiftWiltedBerberisHelper {
- private val config get() = RiftAPI.config.area.dreadfarmConfig.wiltedBerberis
+ private val config get() = RiftAPI.config.area.dreadfarm.wiltedBerberis
private var isOnFarmland = false
private var hasFarmingToolInHand = false
private var list = listOf<WiltedBerberis>()
@@ -49,9 +49,9 @@ class RiftWiltedBerberisHelper {
}
}
- fun nearestBerberis(location: LorenzVec): WiltedBerberis? {
+ private fun nearestBerberis(location: LorenzVec): WiltedBerberis? {
return list.filter { it.currentParticles.distanceSq(location) < 8 }
- .sortedBy { it.currentParticles.distanceSq(location) }.firstOrNull()
+ .minByOrNull { it.currentParticles.distanceSq(location) }
}
@SubscribeEvent
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 f7f14a55d..6cf37e285 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
@@ -25,7 +25,7 @@ import kotlin.time.Duration.Companion.seconds
class VoltHighlighter {
- private val config get() = RiftAPI.config.area.dreadfarmConfig.voltCrux
+ private val config get() = RiftAPI.config.area.dreadfarm.voltCrux
private val LIGHTNING_DISTANCE = 7F
private val ARMOR_SLOT_HEAD = 3
@@ -116,4 +116,4 @@ class VoltHighlighter {
val helmet = entity.getCurrentArmor(ARMOR_SLOT_HEAD) ?: return VoltState.NO_VOLT
return getVoltState(helmet)
}
-} \ No newline at end of file
+}
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 0b314d7e9..88b2939c8 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
@@ -1,5 +1,6 @@
package at.hannibal2.skyhanni.features.rift.area.livingcave
+import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.ReceiveParticleEvent
@@ -22,7 +23,7 @@ import net.minecraft.util.EnumParticleTypes
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class LivingCaveDefenseBlocks {
- private val config get() = RiftAPI.config.area.livingCaveConfig.defenseBlockConfig
+ private val config get() = RiftAPI.config.area.livingCave.defenseBlockConfig
private var movingBlocks = mapOf<DefenseBlock, Long>()
private var staticBlocks = emptyList<DefenseBlock>()
@@ -76,9 +77,9 @@ class LivingCaveDefenseBlocks {
// read new entity data
val compareLocation = event.location.add(-0.5, -1.5, -0.5)
entity = EntityUtils.getEntitiesNearby<EntityOtherPlayerMP>(compareLocation, 2.0)
- .filter { isCorrectMob(it.name) }
- .filter { !it.isAtFullHealth() }
- .minByOrNull { it.distanceTo(compareLocation) }
+ .filter { isCorrectMob(it.name) }
+ .filter { !it.isAtFullHealth() }
+ .minByOrNull { it.distanceTo(compareLocation) }
}
val defenseBlock = entity?.let { DefenseBlock(it, location) } ?: return
@@ -172,4 +173,9 @@ class LivingCaveDefenseBlocks {
val color get() = config.color.get().toChromaColor()
fun isEnabled() = RiftAPI.inRift() && config.enabled && RiftAPI.inLivingCave()
+
+ @SubscribeEvent
+ fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
+ event.move(9, "rift.area.livingCaveConfig", "rift.area.livingCave")
+ }
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/livingcave/LivingCaveLivingMetalHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/livingcave/LivingCaveLivingMetalHelper.kt
index 73a007a4a..cc237c6c5 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/livingcave/LivingCaveLivingMetalHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/livingcave/LivingCaveLivingMetalHelper.kt
@@ -14,7 +14,7 @@ import at.hannibal2.skyhanni.utils.LorenzVec
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class LivingCaveLivingMetalHelper {
- private val config get() = RiftAPI.config.area.livingCaveConfig.livingCaveLivingMetalConfig
+ private val config get() = RiftAPI.config.area.livingCave.livingCaveLivingMetalConfig
private var lastClicked: LorenzVec? = null
private var pair: Pair<LorenzVec, LorenzVec>? = null
private var startTime = 0L
@@ -67,7 +67,11 @@ class LivingCaveLivingMetalHelper {
val percentage = diff.toDouble() / maxTime
a.slope(b, 1 - percentage)
} else b
- event.drawWaypointFilled(location, LorenzColor.AQUA.toColor(), seeThroughBlocks = location.distanceToPlayer() < 10)
+ event.drawWaypointFilled(
+ location,
+ LorenzColor.AQUA.toColor(),
+ seeThroughBlocks = location.distanceToPlayer() < 10
+ )
}
@SubscribeEvent
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/livingcave/LivingMetalSuitProgress.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/livingcave/LivingMetalSuitProgress.kt
index 025803ce1..1deb2b64c 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/livingcave/LivingMetalSuitProgress.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/livingcave/LivingMetalSuitProgress.kt
@@ -14,7 +14,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class LivingMetalSuitProgress {
- private val config get() = RiftAPI.config.area.livingCaveConfig.livingMetalSuitProgress
+ private val config get() = RiftAPI.config.area.livingCave.livingMetalSuitProgress
private var display = emptyList<List<Any>>()
private var progressMap = mapOf<ItemStack, Double?>()
@@ -92,4 +92,4 @@ class LivingMetalSuitProgress {
}
fun isEnabled() = RiftAPI.inRift() && config.enabled
-} \ No newline at end of file
+}
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 ec503bcfd..524e1b354 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/DanceRoomHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/DanceRoomHelper.kt
@@ -1,5 +1,6 @@
package at.hannibal2.skyhanni.features.rift.area.mirrorverse
+import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.CheckRenderEntityEvent
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
@@ -25,7 +26,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
object DanceRoomHelper {
private var display = emptyList<String>()
- private val config get() = RiftAPI.config.area.mirrorVerseConfig.danceRoomHelper
+ private val config get() = RiftAPI.config.area.mirrorverse.danceRoomHelper
private var index = 0
private var found = false
private val danceRoom = AxisAlignedBB(-260.0, 32.0, -110.0, -267.0, 40.0, -102.0)
@@ -179,4 +180,9 @@ object DanceRoomHelper {
}
fun isEnabled() = RiftAPI.inRift() && config.enabled
+
+ @SubscribeEvent
+ fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
+ event.move(9, "rift.area.mirrorVerseConfig", "rift.area.mirrorverse")
+ }
}
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 12bebc3ee..efaf77163 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
@@ -13,7 +13,7 @@ import at.hannibal2.skyhanni.utils.jsonobjects.ParkourJson
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class RiftLavaMazeParkour {
- private val config get() = RiftAPI.config.area.mirrorVerseConfig.lavaMazeConfig
+ private val config get() = RiftAPI.config.area.mirrorverse.lavaMazeConfig
private var parkourHelper: ParkourHelper? = null
@SubscribeEvent
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 136c956cf..18a09709d 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
@@ -13,7 +13,7 @@ import at.hannibal2.skyhanni.utils.jsonobjects.ParkourJson
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class RiftUpsideDownParkour {
- private val config get() = RiftAPI.config.area.mirrorVerseConfig.upsideDownParkour
+ private val config get() = RiftAPI.config.area.mirrorverse.upsideDownParkour
private var parkourHelper: ParkourHelper? = null
@SubscribeEvent
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 fcd880b3d..567f2bf2e 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
@@ -14,7 +14,7 @@ import net.minecraft.util.AxisAlignedBB
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class TubulatorParkour {
- private val config get() = RiftAPI.config.area.mirrorVerseConfig.tubulatorConfig
+ private val config get() = RiftAPI.config.area.mirrorverse.tubulatorConfig
private var parkourHelper: ParkourHelper? = null
private val puzzleRoom = AxisAlignedBB(-298.0, 0.0, -112.0, -309.0, 63.0, -101.0)
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 f6a4a607b..d10aac4ca 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
@@ -1,5 +1,6 @@
package at.hannibal2.skyhanni.features.rift.area.stillgorechateau
+import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
@@ -23,7 +24,7 @@ import net.minecraft.entity.item.EntityArmorStand
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class RiftBloodEffigies {
- private val config get() = RiftAPI.config.area.stillgoreChateauConfig.bloodEffigies
+ private val config get() = RiftAPI.config.area.stillgoreChateau.bloodEffigies
private var locations: List<LorenzVec> = emptyList()
private var effigiesTimes = mapOf(
0 to -1L,
@@ -74,12 +75,12 @@ class RiftBloodEffigies {
if (diff < 0L) {
if (s == "7") {
if (time != 0L) {
- LorenzUtils.chat("§e[SkyHanni] Effigy #${index + 1} respawned!")
+ LorenzUtils.chat("Effigy #${index + 1} respawned!")
effigiesTimes = effigiesTimes.editCopy { this[index] = 0L }
}
} else {
if (time != -1L) {
- LorenzUtils.chat("§e[SkyHanni] Effigy #${index + 1} is broken!")
+ LorenzUtils.chat("Effigy #${index + 1} is broken!")
val endTime = System.currentTimeMillis() + 1_000 * 60 * 20
effigiesTimes = effigiesTimes.editCopy { this[index] = endTime }
}
@@ -142,4 +143,9 @@ class RiftBloodEffigies {
}
fun isEnabled() = RiftAPI.inRift() && RiftAPI.inStillgoreChateau() && config.enabled
+
+ @SubscribeEvent
+ fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
+ event.move(9, "rift.area.stillgoreChateauConfig", "rift.area.stillgoreChateau")
+ }
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/westvillage/KloonHacking.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/westvillage/KloonHacking.kt
index 3aaafc42a..57eb0ead2 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/westvillage/KloonHacking.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/westvillage/KloonHacking.kt
@@ -1,5 +1,6 @@
package at.hannibal2.skyhanni.features.rift.area.westvillage
+import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.data.ProfileStorageData
import at.hannibal2.skyhanni.events.GuiContainerEvent
import at.hannibal2.skyhanni.events.InventoryCloseEvent
@@ -23,7 +24,7 @@ import net.minecraftforge.fml.common.eventhandler.EventPriority
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class KloonHacking {
- private val config get() = RiftAPI.config.area.westVillageConfig.hacking
+ private val config get() = RiftAPI.config.area.westVillage.hacking
// TODO USE SH-REPO
val pattern = "You've set the color of this terminal to (?<colour>.*)!".toPattern()
@@ -115,9 +116,9 @@ class KloonHacking {
if (!RiftAPI.inRift()) return
if (!config.waypoints) return
if (!wearingHelmet) return
- val hidden = ProfileStorageData.profileSpecific?.rift ?: return
+ val storage = ProfileStorageData.profileSpecific?.rift ?: return
for (terminal in KloonTerminal.entries) {
- if (terminal !in hidden.completedKloonTerminals) {
+ if (terminal !in storage.completedKloonTerminals) {
event.drawWaypointFilled(terminal.location, LorenzColor.DARK_RED.toColor(), true, true)
}
}
@@ -128,11 +129,11 @@ class KloonHacking {
if (!RiftAPI.inRift()) return
if (!wearingHelmet) return
pattern.matchMatcher(event.message.removeColor()) {
- val hidden = ProfileStorageData.profileSpecific?.rift ?: return
+ val storage = ProfileStorageData.profileSpecific?.rift ?: return
val colour = group("colour")
val completedTerminal = KloonTerminal.entries.firstOrNull { it.name == colour } ?: return
if (completedTerminal != nearestTerminal) return
- hidden.completedKloonTerminals.add(completedTerminal)
+ storage.completedKloonTerminals.add(completedTerminal)
}
}
@@ -162,4 +163,9 @@ class KloonHacking {
nearestTerminal = closestTerminal
return closestTerminal
}
+
+ @SubscribeEvent
+ fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
+ event.move(9, "rift.area.westVillageConfig", "rift.area.westVillage")
+ }
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/RiftLarva.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/wyldwoods/RiftLarva.kt
index c68e6d2f5..5629972ea 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/RiftLarva.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/wyldwoods/RiftLarva.kt
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.features.rift.area
+package at.hannibal2.skyhanni.features.rift.area.wyldwoods
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.withAlpha
@@ -13,9 +13,9 @@ import net.minecraft.entity.item.EntityArmorStand
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class RiftLarva {
- private val config get() = RiftAPI.config.area.wyldWoodsConfig.larvas
+ private val config get() = RiftAPI.config.area.wyldWoods.larvas
private var hasHookInHand = false
- val larvaSkullTexture =
+ private val larvaSkullTexture =
"eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOTgzYjMwZTlkMTM1YjA1MTkwZWVhMmMzYWM2MWUyYWI1NWEyZDgxZTFhNThkYmIyNjk4M2ExNDA4MjY2NCJ9fX0="
@SubscribeEvent
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/wyldwoods/RiftOdonata.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/wyldwoods/RiftOdonata.kt
index ded7de44c..7d1e9b9ba 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/wyldwoods/RiftOdonata.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/wyldwoods/RiftOdonata.kt
@@ -14,9 +14,9 @@ import net.minecraft.entity.item.EntityArmorStand
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class RiftOdonata {
- private val config get() = RiftAPI.config.area.wyldWoodsConfig.odonata
+ private val config get() = RiftAPI.config.area.wyldWoods.odonata
private var hasBottleInHand = false
- val odonataSkullTexture =
+ private val odonataSkullTexture =
"eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOWZkODA2ZGVmZGZkZjU5YjFmMjYwOWM4ZWUzNjQ2NjZkZTY2MTI3YTYyMzQxNWI1NDMwYzkzNThjNjAxZWY3YyJ9fX0="
private val emptyBottle by lazy { "EMPTY_ODONATA_BOTTLE".asInternalName() }
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/wyldwoods/ShyCruxWarnings.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/wyldwoods/ShyCruxWarnings.kt
index 7ac4d1ed6..2b21d9dad 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/wyldwoods/ShyCruxWarnings.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/wyldwoods/ShyCruxWarnings.kt
@@ -1,5 +1,6 @@
package at.hannibal2.skyhanni.features.rift.area.wyldwoods
+import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.features.rift.RiftAPI
import at.hannibal2.skyhanni.utils.EntityUtils
@@ -9,7 +10,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.time.Duration.Companion.milliseconds
class ShyCruxWarnings {
- private val config get() = RiftAPI.config.area.wyldWoodsConfig
+ private val config get() = RiftAPI.config.area.wyldWoods
private val shyNames = arrayOf("I'm ugly! :(", "Eek!", "Don't look at me!", "Look away!")
@SubscribeEvent
@@ -25,4 +26,9 @@ class ShyCruxWarnings {
LorenzUtils.sendTitle("§eLook away!", 150.milliseconds)
}
}
-} \ No newline at end of file
+
+ @SubscribeEvent
+ fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
+ event.move(9, "rift.area.wyldWoodsConfig", "rift.area.wyldWoods")
+ }
+}
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 de2b117d4..983df0d88 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
@@ -98,11 +98,11 @@ object EnigmaSoulWaypoints {
event.usePickblockInstead()
if (soulLocations.contains(split.last())) {
if (!trackedSouls.contains(split.last())) {
- LorenzUtils.chat("§5Tracking the ${split.last()} Enigma Soul!")
+ LorenzUtils.chat("§5Tracking the ${split.last()} Enigma Soul!", prefixColor = "§5")
trackedSouls.add(split.last())
} else {
trackedSouls.remove(split.last())
- LorenzUtils.chat("§5No longer tracking the ${split.last()} Enigma Soul!")
+ LorenzUtils.chat("§5No longer tracking the ${split.last()} Enigma Soul!", prefixColor = "§5")
}
}
}
@@ -176,7 +176,7 @@ object EnigmaSoulWaypoints {
}
if (closestSoul in trackedSouls) {
trackedSouls.remove(closestSoul)
- LorenzUtils.chat("§5Found the $closestSoul Enigma Soul!")
+ LorenzUtils.chat("§5Found the $closestSoul Enigma Soul!", prefixColor = "§5")
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/RiftHorsezookaHider.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/RiftHorsezookaHider.kt
index 04c4ba332..b908f49f8 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/RiftHorsezookaHider.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/RiftHorsezookaHider.kt
@@ -15,7 +15,7 @@ class RiftHorsezookaHider {
if (!SkyHanniMod.feature.rift.horsezookaHider) return
if (event.entity is EntityHorse && InventoryUtils.itemInHandId.equals("HORSEZOOKA")) {
- event.isCanceled = true
+ event.isCanceled = true
}
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/motes/RiftMotesOrb.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/motes/RiftMotesOrb.kt
index aca97f9e0..f62ad2c7a 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/motes/RiftMotesOrb.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/motes/RiftMotesOrb.kt
@@ -1,5 +1,6 @@
package at.hannibal2.skyhanni.features.rift.everywhere.motes
+import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
import at.hannibal2.skyhanni.events.ReceiveParticleEvent
@@ -16,7 +17,7 @@ import net.minecraft.util.EnumParticleTypes
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class RiftMotesOrb {
- private val config get() = RiftAPI.config.motesOrbsConfig
+ private val config get() = RiftAPI.config.motesOrbs
// TODO USE SH-REPO
private val pattern = "§5§lORB! §r§dPicked up §r§5+.* Motes§r§d.*".toPattern()
@@ -90,4 +91,9 @@ class RiftMotesOrb {
}
fun isEnabled() = RiftAPI.inRift() && config.enabled
+
+ @SubscribeEvent
+ fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
+ event.move(9, "rift.area.motesOrbsConfig", "rift.area.motesOrbs")
+ }
}
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 364ef77a2..53b7b56f9 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
@@ -130,7 +130,7 @@ class ShowMotesNpcSellPrice {
if (!RiftAPI.inRift()) return
pattern.matchMatcher(event.message) {
config.burgerStacks = group("amount").toInt()
- chat("§6[SkyHanni] Set your McGrubber's burger stacks to ${group("amount")}.")
+ chat("Set your McGrubber's burger stacks to ${group("amount")}.")
}
}
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 7c71632e2..2bfdf640f 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerBossSpawnSoon.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerBossSpawnSoon.kt
@@ -21,6 +21,7 @@ class SlayerBossSpawnSoon {
@SubscribeEvent
fun onSlayerProgressChange(event: SlayerProgressChangeEvent) {
if (!isEnabled()) return
+ if (!SlayerAPI.isInCorrectArea) return
val completion = pattern.matchMatcher(event.newProgress.removeColor()) {
group("progress").formatNumber().toFloat() / group("total").formatNumber().toFloat()
@@ -29,7 +30,7 @@ class SlayerBossSpawnSoon {
if (completion > config.percent / 100.0) {
if (!warned || (config.repeat && completion != lastCompletion)) {
SoundUtils.playBeepSound()
- LorenzUtils.sendTitle("§cSlayer boss soon!", 2.seconds)
+ LorenzUtils.sendTitle("§eSlayer boss soon!", 2.seconds)
warned = true
}
} else {
@@ -39,4 +40,4 @@ class SlayerBossSpawnSoon {
}
fun isEnabled() = config.enabled && SlayerAPI.hasActiveSlayerQuest()
-} \ No newline at end of file
+}
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 0c80973c4..0cb129c7d 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemsOnGround.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemsOnGround.kt
@@ -5,7 +5,6 @@ import at.hannibal2.skyhanni.data.SlayerAPI
import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
import at.hannibal2.skyhanni.utils.EntityUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
-import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LocationUtils
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzVec
@@ -37,8 +36,6 @@ class SlayerItemsOnGround {
if (location.distance(LocationUtils.playerLocation()) > 15) continue
val itemStack = entityItem.entityItem
- val name = itemStack.name ?: continue
- if (SlayerAPI.ignoreSlayerDrop(name)) continue
// happens in spiders den sometimes
if (itemStack.item == Items.spawn_egg) continue
if (itemStack.getInternalName().equals("")) continue // TODO remove, should never happen
@@ -54,4 +51,4 @@ class SlayerItemsOnGround {
event.drawString(location, text)
}
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemProfitTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt
index 2aebe7e57..c05839ba6 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemProfitTracker.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt
@@ -1,22 +1,19 @@
package at.hannibal2.skyhanni.features.slayer
import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.config.Storage.ProfileSpecific.SlayerProfitList
-import at.hannibal2.skyhanni.data.ProfileStorageData
+import at.hannibal2.skyhanni.config.Storage
import at.hannibal2.skyhanni.data.SlayerAPI
import at.hannibal2.skyhanni.events.GuiRenderEvent
-import at.hannibal2.skyhanni.events.PacketEvent
+import at.hannibal2.skyhanni.events.LorenzChatEvent
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.EntityUtils
-import at.hannibal2.skyhanni.utils.ItemUtils.getInternalNameOrNull
-import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.KeyboardManager
import at.hannibal2.skyhanni.utils.LorenzLogger
import at.hannibal2.skyhanni.utils.LorenzUtils
@@ -24,44 +21,92 @@ 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.RenderUtils.renderStringsAndItems
+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.utils.renderables.Renderable
-import com.google.common.cache.CacheBuilder
-import net.minecraft.client.Minecraft
-import net.minecraft.client.gui.inventory.GuiInventory
-import net.minecraft.entity.item.EntityItem
-import net.minecraft.network.play.server.S0DPacketCollectItem
-import net.minecraftforge.fml.common.eventhandler.EventPriority
+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.concurrent.TimeUnit
+import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds
-object SlayerItemProfitTracker {
+object SlayerProfitTracker {
private val config get() = SkyHanniMod.feature.slayer.itemProfitTracker
- private var collectedCache = CacheBuilder.newBuilder().expireAfterWrite(2, TimeUnit.SECONDS).build<Int, Unit>()
+
+ 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 var display = emptyList<List<Any>>()
- private val logger = LorenzLogger("slayer/item_profit_tracker")
- private var inventoryOpen = false
+ private val logger = LorenzLogger("slayer/profit_tracker")
private var lastClickDelay = 0L
- private var currentDisplayMode = DisplayMode.TOTAL
- private var currentSessionData = mutableMapOf<String, SlayerProfitList>()
+ private val trackers = mutableMapOf<String, SkyHanniTracker<Data>>()
+
+ class Data : TrackerData() {
+ override fun reset() {
+ items.clear()
+ mobKillCoins = 0
+ 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
+
+ @Expose
+ var totalAmount: Long = 0
+
+ @Expose
+ var hidden = false
+
+ override fun toString() = "SlayerItem{" +
+ "internalName='" + internalName + '\'' +
+ ", timesDropped=" + timesDropped +
+ ", totalAmount=" + totalAmount +
+ ", hidden=" + hidden +
+ '}'
+ }
+
+ override fun toString() = "SlayerProfitTracker.Data{" +
+ "items=" + items +
+ ", mobKillCoins=" + mobKillCoins +
+ ", slayerSpawnCost=" + slayerSpawnCost +
+ ", slayerCompletedCount=" + slayerCompletedCount +
+ '}'
+ }
private fun addSlayerCosts(price: Int) {
- val itemLog = currentLog() ?: return
- itemLog.modify {
+ getTracker()?.modify {
it.slayerSpawnCost += price
}
- update()
}
private var allowedItems = mapOf<String, List<NEUInternalName>>()
@@ -90,51 +135,42 @@ object SlayerItemProfitTracker {
val newSlayer = event.newSlayer
itemLogCategory = newSlayer.removeColor()
baseSlayerType = itemLogCategory.substringBeforeLast(" ")
- update()
+ getTracker()?.update()
}
private fun addMobKillCoins(coins: Int) {
- val itemLog = currentLog() ?: return
-
- itemLog.modify {
+ getTracker()?.modify {
it.mobKillCoins += coins
}
- update()
}
private fun addItemPickup(internalName: NEUInternalName, stackSize: Int) {
- val itemLog = currentLog() ?: return
+ getTracker()?.modify {
+ val slayerItem = it.items.getOrPut(internalName) { Data.SlayerItem() }
- itemLog.modify {
- val slayerItemProfit = it.items.getOrPut(internalName) { SlayerProfitList.SlayerItemProfit() }
-
- slayerItemProfit.timesDropped++
- slayerItemProfit.totalAmount += stackSize
+ slayerItem.timesDropped++
+ slayerItem.totalAmount += stackSize
}
-
- update()
}
- private fun currentLog(): AbstractSlayerProfitList? {
+ private fun getTracker(): SkyHanniTracker<Data>? {
if (itemLogCategory == "") return null
- val profileSpecific = ProfileStorageData.profileSpecific ?: return null
-
- return AbstractSlayerProfitList(
- profileSpecific.slayerProfitData.getOrPut(itemLogCategory) { SlayerProfitList() },
- currentSessionData.getOrPut(itemLogCategory) { SlayerProfitList() }
- )
+ return trackers.getOrPut(itemLogCategory) {
+ val getStorage: (Storage.ProfileSpecific) -> Data = {
+ it.slayerProfitData.getOrPut(
+ itemLogCategory
+ ) { Data() }
+ }
+ SkyHanniTracker("$itemLogCategory Profit Tracker", { Data() }, getStorage) { drawDisplay(it) }
+ }
}
@SubscribeEvent
fun onQuestComplete(event: SlayerQuestCompleteEvent) {
- val itemLog = currentLog() ?: return
-
- itemLog.modify {
+ getTracker()?.modify {
it.slayerCompletedCount++
}
-
- update()
}
@SubscribeEvent
@@ -152,27 +188,29 @@ object SlayerItemProfitTracker {
}
}
- @SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true)
- fun onChatPacket(event: PacketEvent.ReceiveEvent) {
+ @SubscribeEvent
+ fun onItemAdd(event: ItemAddInInventoryEvent) {
if (!isEnabled()) return
if (!SlayerAPI.isInCorrectArea) return
if (!SlayerAPI.hasActiveSlayerQuest()) return
- val packet = event.packet
- if (packet !is S0DPacketCollectItem) return
+ val internalName = event.internalName
+ if (internalName == ARCHFIEND_DICE || internalName == HIGH_CLASS_ARCHFIEND_DICE) {
+ if (lastDiceRoll.passedSince() < 500.milliseconds) {
+ return
+ }
+ }
- val entityID = packet.collectedItemEntityID
- val item = EntityUtils.getEntityByID(entityID) ?: return
- if (item !is EntityItem) return
+ addItem(internalName, event.amount)
+ }
- if (collectedCache.getIfPresent(entityID) != null) return
- collectedCache.put(entityID, Unit)
+ private var lastDiceRoll = SimpleTimeMark.farPast()
- val itemStack = item.entityItem
- val name = itemStack.name ?: return
- if (SlayerAPI.ignoreSlayerDrop(name)) return
- val internalName = itemStack.getInternalNameOrNull() ?: return
- addItem(internalName, itemStack.stackSize)
+ @SubscribeEvent
+ fun onChat(event: LorenzChatEvent) {
+ if (diceRollChatPattern.matches(event.message)) {
+ lastDiceRoll = SimpleTimeMark.now()
+ }
}
private fun addItem(internalName: NEUInternalName, amount: Int) {
@@ -185,7 +223,7 @@ object SlayerItemProfitTracker {
addItemPickup(internalName, amount)
logger.log("Coins gained for picking up an item ($itemName) ${price.addSeparators()}")
if (config.priceInChat && price > config.minimumPrice) {
- LorenzUtils.chat("§e[SkyHanni] §a+Slayer Drop§7: §r$itemName")
+ LorenzUtils.chat("§a+Slayer Drop§7: §r$itemName")
}
if (config.titleWarning && price > config.minimumPriceWarning) {
LorenzUtils.sendTitle("§a+ $itemName", 5.seconds)
@@ -197,26 +235,9 @@ object SlayerItemProfitTracker {
return internalName in allowedList
}
- fun update() {
- display = drawDisplay()
- }
-
- private fun drawDisplay() = buildList<List<Any>> {
- val both = currentLog() ?: return@buildList
- val itemLog = both.get(currentDisplayMode)
-
+ private fun drawDisplay(itemLog: Data) = buildList<List<Any>> {
+ val tracker = getTracker() ?: return@buildList
addAsSingletonList("§e§l$itemLogCategory Profit Tracker")
- if (inventoryOpen) {
- addSelector<DisplayMode>(
- "§7Display Mode: ",
- getName = { type -> type.displayName },
- isCurrent = { it == currentDisplayMode },
- onChange = {
- currentDisplayMode = it
- update()
- }
- )
- }
var profit = 0.0
val map = mutableMapOf<Renderable, Long>()
@@ -241,7 +262,7 @@ object SlayerItemProfitTracker {
val percentage = timesDropped.toDouble() / itemLog.slayerCompletedCount
val perBoss = LorenzUtils.formatPercentage(percentage.coerceAtMost(1.0))
- val renderable = if (inventoryOpen) Renderable.clickAndHover(
+ val renderable = if (tracker.isInventoryOpen()) Renderable.clickAndHover(
text, listOf(
"§7Dropped §e${timesDropped.addSeparators()} §7times.",
"§7Your drop rate: §c$perBoss",
@@ -254,16 +275,16 @@ object SlayerItemProfitTracker {
if (KeyboardManager.isControlKeyDown()) {
itemLog.items.remove(internalName)
- LorenzUtils.chat("§e[SkyHanni] Removed $cleanName §efrom slayer profit display.")
+ LorenzUtils.chat("Removed $cleanName §efrom slayer profit display.")
lastClickDelay = System.currentTimeMillis() + 500
} else {
itemProfit.hidden = !hidden
lastClickDelay = System.currentTimeMillis()
}
- update()
+ tracker.update()
}
} else Renderable.string(text)
- if (inventoryOpen || !hidden) {
+ if (tracker.isInventoryOpen() || !hidden) {
map[renderable] = price
}
profit += price
@@ -311,36 +332,17 @@ object SlayerItemProfitTracker {
val text = "§eTotal Profit: $profitPrefix$profitFormat"
addAsSingletonList(Renderable.hoverTips(text, listOf("§7Profit per boss: $profitPrefix$profitPerBossFormat")))
- if (inventoryOpen) {
+ if (tracker.isInventoryOpen()) {
addSelector<PriceSource>(
"",
getName = { type -> type.displayName },
isCurrent = { it.ordinal == config.priceFrom },
onChange = {
config.priceFrom = it.ordinal
- update()
+ tracker.update()
}
)
}
- if (inventoryOpen && currentDisplayMode == DisplayMode.CURRENT) {
- addAsSingletonList(
- Renderable.clickAndHover(
- "§cReset session!",
- listOf("§cThis will reset your", "§ccurrent session for", "§c$itemLogCategory"),
- ) {
- resetData(DisplayMode.CURRENT)
- update()
- })
- }
- }
-
- private fun resetData(displayMode: DisplayMode) {
- val currentLog = currentLog() ?: return
- val list = currentLog.get(displayMode)
- list.items.clear()
- list.mobKillCoins = 0
- list.slayerSpawnCost = 0
- list.slayerCompletedCount = 0
}
private fun getPrice(internalName: NEUInternalName) = when (config.priceFrom) {
@@ -355,59 +357,20 @@ object SlayerItemProfitTracker {
if (!isEnabled()) return
if (!SlayerAPI.isInCorrectArea) return
- val currentlyOpen = Minecraft.getMinecraft().currentScreen is GuiInventory
- if (inventoryOpen != currentlyOpen) {
- inventoryOpen = currentlyOpen
- update()
- }
-
-
- config.pos.renderStringsAndItems(display, posLabel = "Slayer Item Profit Tracker")
- }
-
- enum class DisplayMode(val displayName: String) {
- TOTAL("Total"),
- CURRENT("This Session"),
- ;
- }
-
- class AbstractSlayerProfitList(
- private val total: SlayerProfitList,
- private val currentSession: SlayerProfitList,
- ) {
-
- fun modify(modifyFunction: (SlayerProfitList) -> Unit) {
- modifyFunction(total)
- modifyFunction(currentSession)
- }
-
- fun get(displayMode: DisplayMode) = when (displayMode) {
- DisplayMode.TOTAL -> total
- DisplayMode.CURRENT -> currentSession
- }
+ getTracker()?.renderDisplay(config.pos)
}
fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled
fun clearProfitCommand(args: Array<String>) {
if (itemLogCategory == "") {
- LorenzUtils.chat(
- "§c[SkyHanni] No current slayer data found. " +
- "Go to a slayer area and start the specific slayer type you want to reset the data of."
+ LorenzUtils.userError(
+ "No current slayer data found! " +
+ "§eGo to a slayer area and start the specific slayer type you want to reset the data of.",
)
return
}
- if (args.size == 1 && args[0].lowercase() == "confirm") {
- resetData(DisplayMode.TOTAL)
- update()
- LorenzUtils.chat("§e[SkyHanni] You reset your $itemLogCategory slayer data!")
- return
- }
-
- LorenzUtils.clickableChat(
- "§e[SkyHanni] Are you sure you want to reset all your $itemLogCategory slayer data? Click here to confirm.",
- "shclearslayerprofits confirm"
- )
+ getTracker()?.resetCommand(args, "shclearslayerprofits")
}
}
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 e1cc10b6b..728896e22 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerQuestWarning.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerQuestWarning.kt
@@ -131,7 +131,7 @@ class SlayerQuestWarning {
if (lastWarning + 10_000 > System.currentTimeMillis()) return
lastWarning = System.currentTimeMillis()
- LorenzUtils.chat("§e[SkyHanni] $chatMessage")
+ LorenzUtils.chat(chatMessage)
if (config.questWarningTitle) {
LorenzUtils.sendTitle("§e$titleMessage", 2.seconds)
@@ -168,4 +168,4 @@ class SlayerQuestWarning {
return slayerType.clazz.isInstance(entity)
}
-} \ No newline at end of file
+}
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 0b98116a2..b26fd4c09 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerRngMeterDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerRngMeterDisplay.kt
@@ -70,7 +70,7 @@ class SlayerRngMeterDisplay {
val item = storage.itemGoal
val hasItemSelected = item != "" && item != "?"
if (!hasItemSelected && config.warnEmpty) {
- LorenzUtils.warning("§c[SkyHanni] No Slayer RNG Meter Item selected!")
+ LorenzUtils.userError("No Slayer RNG Meter Item selected!")
LorenzUtils.sendTitle("§cNo RNG Meter Item!", 3.seconds)
}
var blockChat = config.hideChat && hasItemSelected
@@ -86,7 +86,7 @@ class SlayerRngMeterDisplay {
var rawPercentage = old.toDouble() / storage.goalNeeded
if (rawPercentage > 1) rawPercentage = 1.0
val percentage = LorenzUtils.formatPercentage(rawPercentage)
- LorenzUtils.chat("§e[SkyHanni] §dRNG Meter §7dropped at §e$percentage §7XP ($from/${to}§7)")
+ LorenzUtils.chat("§dRNG Meter §7dropped at §e$percentage §7XP ($from/${to}§7)")
lastItemDroppedTime = System.currentTimeMillis()
}
if (blockChat) {
@@ -116,7 +116,8 @@ class SlayerRngMeterDisplay {
val storage = getStorage() ?: return
- val selectedItem = event.inventoryItems.values.find { item -> item.getLore().any { it.contains("§a§lSELECTED") } }
+ val selectedItem =
+ event.inventoryItems.values.find { item -> item.getLore().any { it.contains("§a§lSELECTED") } }
if (selectedItem == null) {
storage.itemGoal = ""
storage.goalNeeded = -1
diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerType.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerType.kt
index 4d5d9fa34..44937dd7f 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerType.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerType.kt
@@ -15,7 +15,4 @@ enum class SlayerType(val displayName: String, val clazz: Class<*>) {
INFERNO("Inferno Demonlord", EntityBlaze::class.java),
VAMPIRE("Riftstalker Bloodfiend", EntityOtherPlayerMP::class.java)
;
-
- companion object {
- }
-} \ No newline at end of file
+}
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 a60d1e51a..59ca5b075 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/slayer/VampireSlayerFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/VampireSlayerFeatures.kt
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.features.slayer
import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.data.ClickType
import at.hannibal2.skyhanni.events.EntityClickEvent
import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
@@ -49,7 +50,7 @@ import kotlin.time.Duration.Companion.milliseconds
object VampireSlayerFeatures {
- private val config get() = SkyHanniMod.feature.slayer.vampireSlayerConfig
+ private val config get() = SkyHanniMod.feature.slayer.vampire
private val configOwnBoss get() = config.ownBoss
private val configOtherBoss get() = config.othersBoss
private val configCoopBoss get() = config.coopBoss
@@ -378,5 +379,10 @@ object VampireSlayerFeatures {
}
}
+ @SubscribeEvent
+ fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
+ event.move(9, "slayer.vampireSlayerConfig", "slayer.vampire")
+ }
+
fun isEnabled() = RiftAPI.inRift() && RiftAPI.inStillgoreChateau()
}
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 ce892f31f..0e9b9f8ae 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
@@ -2,6 +2,7 @@ package at.hannibal2.skyhanni.features.slayer.blaze
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
+import at.hannibal2.skyhanni.config.core.config.gui.GuiPositionEditor
import at.hannibal2.skyhanni.data.ClickType
import at.hannibal2.skyhanni.events.BlockClickEvent
import at.hannibal2.skyhanni.events.GuiRenderEvent
@@ -12,23 +13,19 @@ import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LocationUtils
import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.NumberUtil.roundToPrecision
+import at.hannibal2.skyhanni.utils.RenderUtils.renderString
import at.hannibal2.skyhanni.utils.StringUtils.matchRegex
import at.hannibal2.skyhanni.utils.getLorenzVec
-import io.github.moulberry.moulconfig.internal.TextRenderUtils
import net.minecraft.client.Minecraft
-import net.minecraft.client.gui.ScaledResolution
-import net.minecraft.client.renderer.GlStateManager
import net.minecraft.item.ItemStack
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class BlazeSlayerDaggerHelper {
+ private val config get() = SkyHanniMod.feature.slayer.blazes.hellion
private var clientSideClicked = false
- private var textTopLeft = ""
- private var textTopRight = ""
- private var textBottomLeft = ""
- private var textBottomRight = ""
+ private var textTop = ""
+ private var textBottom = ""
private var lastDaggerCheck = 0L
private var lastNearestCheck = 0L
@@ -58,10 +55,8 @@ class BlazeSlayerDaggerHelper {
return
}
- textTopLeft = ""
- textTopRight = ""
- textBottomLeft = ""
- textBottomRight = ""
+ textTop = ""
+ textBottom = ""
}
private fun setDaggerText(holding: Dagger) {
@@ -71,10 +66,8 @@ class BlazeSlayerDaggerHelper {
val first = Dagger.entries[SkyHanniMod.feature.slayer.blazes.hellion.firstDagger]
val second = first.other()
- textTopLeft = format(holding, true, first)
- textTopRight = format(holding, true, second)
- textBottomLeft = format(holding, false, first)
- textBottomRight = format(holding, false, second)
+ textTop = format(holding, true, first) + " " + format(holding, true, second)
+ textBottom = format(holding, false, first) + " " + format(holding, false, second)
}
private fun findNearest(): HellionShield? {
@@ -194,7 +187,7 @@ class BlazeSlayerDaggerHelper {
}
private fun isEnabled(): Boolean {
- return LorenzUtils.inSkyBlock && SkyHanniMod.feature.slayer.blazes.hellion.daggers
+ return LorenzUtils.inSkyBlock && config.daggers
}
@SubscribeEvent
@@ -242,75 +235,13 @@ class BlazeSlayerDaggerHelper {
@SubscribeEvent
fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
if (!isEnabled()) return
- if (textTopLeft.isEmpty()) return
-
- if (Minecraft.getMinecraft().currentScreen != null) return
-
- val scaledResolution = ScaledResolution(Minecraft.getMinecraft())
- val width = scaledResolution.scaledWidth
- val height = scaledResolution.scaledHeight
-
- val sizeFactor = (width.toFloat() / 960f).roundToPrecision(3)
-
- GlStateManager.enableBlend()
- GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0)
- val renderer = Minecraft.getMinecraft().fontRendererObj
-
- GlStateManager.pushMatrix()
- GlStateManager.translate(((width / 2) / 1.18).toFloat(), (height / 3.8).toFloat(), 0.0f)
- GlStateManager.scale(4.0f, 4.0f, 4.0f)
- TextRenderUtils.drawStringCenteredScaledMaxWidth(
- textTopLeft,
- renderer,
- 0f,
- 0f,
- false,
- (60f * sizeFactor).toInt(),
- 0
- )
- GlStateManager.popMatrix()
-
- GlStateManager.pushMatrix()
- GlStateManager.translate(((width / 2) * 1.18).toFloat(), (height / 3.8).toFloat(), 0.0f)
- GlStateManager.scale(4.0f, 4.0f, 4.0f)
- TextRenderUtils.drawStringCenteredScaledMaxWidth(
- textTopRight,
- renderer,
- 0f,
- 0f,
- false,
- (60f * sizeFactor).toInt(),
- 0
- )
- GlStateManager.popMatrix()
-
- GlStateManager.pushMatrix()
- GlStateManager.translate(((width / 2) / 1.18).toFloat(), (height / 3.0).toFloat(), 0.0f)
- GlStateManager.scale(4.0f, 4.0f, 4.0f)
- TextRenderUtils.drawStringCenteredScaledMaxWidth(
- textBottomLeft,
- renderer,
- 0f,
- 0f,
- false,
- (20f * sizeFactor).toInt(),
- 0
- )
- GlStateManager.popMatrix()
-
- GlStateManager.pushMatrix()
- GlStateManager.translate(((width / 2) * 1.18).toFloat(), (height / 3.0).toFloat(), 0.0f)
- GlStateManager.scale(4.0f, 4.0f, 4.0f)
- TextRenderUtils.drawStringCenteredScaledMaxWidth(
- textBottomRight,
- renderer,
- 0f,
- 0f,
- false,
- (20f * sizeFactor).toInt(),
- 0
- )
- GlStateManager.popMatrix()
+
+ if (textTop == "") return
+ val currentScreen = Minecraft.getMinecraft().currentScreen
+ if (currentScreen != null && currentScreen !is GuiPositionEditor) return
+
+ config.positionTop.renderString(textTop, posLabel = "Blaze Slayer Dagger Top")
+ config.positionBottom.renderString(textBottom, posLabel = "Blaze Slayer Dagger Bottom")
}
@SubscribeEvent
diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/blaze/BlazeSlayerFirePitsWarning.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/blaze/BlazeSlayerFirePitsWarning.kt
index 4d1423880..74c15c271 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/slayer/blaze/BlazeSlayerFirePitsWarning.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/blaze/BlazeSlayerFirePitsWarning.kt
@@ -51,6 +51,7 @@ class BlazeSlayerFirePitsWarning {
-> {
fireFirePits()
}
+
else -> {}
}
}
@@ -70,4 +71,4 @@ class BlazeSlayerFirePitsWarning {
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
event.move(3, "slayer.firePitsWarning", "slayer.blazes.firePitsWarning")
}
-} \ No newline at end of file
+}
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 ae76d4c9b..42c50f00a 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
@@ -40,7 +40,7 @@ import kotlin.time.Duration.Companion.seconds
class EndermanSlayerFeatures {
private val config get() = SkyHanniMod.feature.slayer.endermen
- private val beaconConfig get() = config.endermanBeaconConfig
+ private val beaconConfig get() = config.beacon
private val endermenWithBeacons = mutableListOf<EntityEnderman>()
private var flyingBeacons = listOf<EntityArmorStand>()
private val nukekubiSkulls = mutableListOf<EntityArmorStand>()
@@ -227,5 +227,6 @@ class EndermanSlayerFeatures {
event.move(3, "slayer.endermanBeaconConfig.lneColor", "slayer.endermen.endermanBeaconConfig.lineColor")
event.move(3, "slayer.endermanBeaconConfig.lineWidth", "slayer.endermen.endermanBeaconConfig.lineWidth")
event.move(3, "slayer.endermanHighlightNukekebi", "slayer.endermen.highlightNukekebi")
+ event.move(9, "slayer.enderman.endermanBeaconConfig", "slayer.endermen.beacon")
}
}
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 99d854cef..6b4757e21 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningMobManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningMobManager.kt
@@ -88,7 +88,7 @@ class SummoningMobManager {
healthPattern.matchMatcher(name) {
val playerName = LorenzUtils.getPlayerName()
if (name.contains(playerName)) {
- summoningMobNametags.add(it as EntityArmorStand)
+ summoningMobNametags.add(it)
if (summoningMobNametags.size == summoningsSpawned) {
searchArmorStands = false
}
@@ -123,7 +123,7 @@ class SummoningMobManager {
val name = summoningMob.name
if (currentHealth == 0) {
summoningMobs.remove(entityLiving)
- LorenzUtils.chat("§e[SkyHanni] Your Summoning Mob just §cdied!")
+ LorenzUtils.chat("Your Summoning Mob just §cdied!")
continue
}
@@ -212,4 +212,4 @@ class SummoningMobManager {
var name: String = "",
var lastDisplayName: String = "",
)
-} \ No newline at end of file
+}
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 8f0825188..6d206bf17 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningSoulsName.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningSoulsName.kt
@@ -18,12 +18,13 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class SummoningSoulsName {
+ // TODO repo
private val texture =
"ewogICJ0aW1lc3RhbXAiIDogMTYwMTQ3OTI2NjczMywKICAicHJvZmlsZUlkIiA6ICJmMzA1ZjA5NDI0NTg0ZjU" +
- "4YmEyYjY0ZjAyZDcyNDYyYyIsCiAgInByb2ZpbGVOYW1lIiA6ICJqcm9ja2EzMyIsCiAgInNpZ25hdH" +
- "VyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgI" +
- "nVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS81YWY0MDM1ZWMwZGMx" +
- "NjkxNzc4ZDVlOTU4NDAxNzAyMjdlYjllM2UyOTQzYmVhODUzOTI5Y2U5MjNjNTk4OWFkIgogICAgfQogIH0KfQ"
+ "4YmEyYjY0ZjAyZDcyNDYyYyIsCiAgInByb2ZpbGVOYW1lIiA6ICJqcm9ja2EzMyIsCiAgInNpZ25hdH" +
+ "VyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgI" +
+ "nVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS81YWY0MDM1ZWMwZGMx" +
+ "NjkxNzc4ZDVlOTU4NDAxNzAyMjdlYjllM2UyOTQzYmVhODUzOTI5Y2U5MjNjNTk4OWFkIgogICAgfQogIH0KfQ"
private val souls = mutableMapOf<EntityArmorStand, String>()
private val mobsLastLocation = mutableMapOf<EntityLiving, LorenzVec>()
@@ -89,4 +90,4 @@ class SummoningSoulsName {
}
private fun isEnabled() = LorenzUtils.inSkyBlock && SkyHanniMod.feature.combat.summonings.summoningSoulDisplay
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/hooks/FontRendererHook.kt b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/FontRendererHook.kt
index a2fc3ad76..d8a4e8344 100644
--- a/src/main/java/at/hannibal2/skyhanni/mixins/hooks/FontRendererHook.kt
+++ b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/FontRendererHook.kt
@@ -44,7 +44,7 @@ object FontRendererHook {
* [FontRenderer#drawString()][net.minecraft.client.gui.FontRenderer.drawString] rather than a custom font renderer
*
*/
- fun setupChromaFont() {
+ private fun setupChromaFont() {
DRAW_CHROMA.startChroma()
DRAW_CHROMA_SHADOW.startChroma()
}
@@ -52,7 +52,7 @@ object FontRendererHook {
/**
* See [setupChromaFont]
*/
- fun endChromaFont() {
+ private fun endChromaFont() {
DRAW_CHROMA.endChroma()
DRAW_CHROMA_SHADOW.endChroma()
}
@@ -98,7 +98,7 @@ object FontRendererHook {
}
@JvmStatic
- fun forceWhiteColorCode(i1: Int) : Int {
+ fun forceWhiteColorCode(i1: Int): Int {
if (!LorenzUtils.inSkyBlock) return i1
if (!SkyHanniMod.feature.chroma.enabled) return i1
@@ -141,8 +141,16 @@ object FontRendererHook {
return if (LorenzUtils.inSkyBlock && !SkyHanniMod.feature.chroma.enabled) constant else "0123456789abcdefklmnorz"
}
+ // TODO add better parameter names
@JvmStatic
- fun toggleChromaCondition_shouldResetStyles(text: String, shadow: Boolean, ci: CallbackInfo, i: Int, c0: Char, i1: Int): Boolean {
+ fun toggleChromaCondition_shouldResetStyles(
+ text: String,
+ shadow: Boolean,
+ ci: CallbackInfo,
+ i: Int,
+ c0: Char,
+ i1: Int
+ ): Boolean {
if (!LorenzUtils.inSkyBlock) return false
if (!SkyHanniMod.feature.chroma.enabled) return false
if (i1 == 22) {
@@ -151,4 +159,4 @@ object FontRendererHook {
}
return false
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinFontRenderer.java b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinFontRenderer.java
index 2b3d87c5c..b8a759ed0 100644
--- a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinFontRenderer.java
+++ b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinFontRenderer.java
@@ -37,8 +37,8 @@ public abstract class MixinFontRenderer {
* Inject call to {@link FontRendererHook#restoreChromaState()} after 1st and 3rd fontrenderer.italicStyle = ___ call
*/
@Inject(method = "renderStringAtPos", at = {
- @At(value = "FIELD", opcode = Opcodes.PUTFIELD, target = "Lnet/minecraft/client/gui/FontRenderer;italicStyle:Z", ordinal = 0, shift = At.Shift.AFTER),
- @At(value = "FIELD", opcode = Opcodes.PUTFIELD, target = "Lnet/minecraft/client/gui/FontRenderer;italicStyle:Z", ordinal = 2, shift = At.Shift.AFTER)})
+ @At(value = "FIELD", opcode = Opcodes.PUTFIELD, target = "Lnet/minecraft/client/gui/FontRenderer;italicStyle:Z", ordinal = 0, shift = At.Shift.AFTER),
+ @At(value = "FIELD", opcode = Opcodes.PUTFIELD, target = "Lnet/minecraft/client/gui/FontRenderer;italicStyle:Z", ordinal = 2, shift = At.Shift.AFTER)})
public void insertRestoreChromaState(CallbackInfo ci) {
FontRendererHook.restoreChromaState();
}
diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/gui/MixinGuiContainer.java b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/gui/MixinGuiContainer.java
index ed106f6f1..57fd96a70 100644
--- a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/gui/MixinGuiContainer.java
+++ b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/gui/MixinGuiContainer.java
@@ -52,12 +52,12 @@ public abstract class MixinGuiContainer extends GuiScreen {
}
@Inject(method = "drawScreen",
- at = @At(
- value = "INVOKE",
- target = "Lnet/minecraft/entity/player/InventoryPlayer;getItemStack()Lnet/minecraft/item/ItemStack;",
- shift = At.Shift.BEFORE,
- ordinal = 1
- )
+ at = @At(
+ value = "INVOKE",
+ target = "Lnet/minecraft/entity/player/InventoryPlayer;getItemStack()Lnet/minecraft/item/ItemStack;",
+ shift = At.Shift.BEFORE,
+ ordinal = 1
+ )
)
public void drawScreen_after(int mouseX, int mouseY, float partialTicks, CallbackInfo ci) {
skyHanni$hook.onDrawScreenAfter(mouseX, mouseY, ci);
diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/renderer/MixinRendererLivingEntity.java b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/renderer/MixinRendererLivingEntity.java
index d01ecd8a4..b74905564 100644
--- a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/renderer/MixinRendererLivingEntity.java
+++ b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/renderer/MixinRendererLivingEntity.java
@@ -12,7 +12,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-@Mixin(RendererLivingEntity.class)
+@Mixin(value = RendererLivingEntity.class, priority = 1001)
public abstract class MixinRendererLivingEntity<T extends EntityLivingBase> extends Render<T> {
protected MixinRendererLivingEntity(RenderManager renderManager) {
@@ -28,4 +28,4 @@ public abstract class MixinRendererLivingEntity<T extends EntityLivingBase> exte
private int changeHurtTime(EntityLivingBase entity) {
return RenderLivingEntityHelper.Companion.changeHurtTime(entity);
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/test/HotSwapDetection.kt b/src/main/java/at/hannibal2/skyhanni/test/HotSwapDetection.kt
new file mode 100644
index 000000000..f1044057d
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/test/HotSwapDetection.kt
@@ -0,0 +1,50 @@
+package at.hannibal2.skyhanni.test
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.MinecraftData
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import net.minecraft.client.Minecraft
+import kotlin.concurrent.fixedRateTimer
+
+object HotSwapDetection {
+ private val config get() = SkyHanniMod.feature.dev.debug
+
+ private var latestTick = 0
+ private var beforeThatTick = 0
+ private var lastTps = 0
+ private var hotswap = false
+
+ init {
+ fixedRateTimer(name = "skyhanni-hot-swap-detection", period = 250) {
+ val currentTick = MinecraftData.totalTicks
+ val diff = currentTick - latestTick
+ latestTick = currentTick
+
+ // we count 2 client ticks per tick, we are bad
+ handleTps(diff * 2)
+ }
+ }
+
+ private fun handleTps(tps: Int) {
+ Minecraft.getMinecraft().theWorld ?: return
+ if (!config.hotSwapDetection) return
+
+ // ignore below one minute
+ if (latestTick < 20 * 60) return
+
+ if (!hotswap) {
+ if (tps < 5) {
+ if (beforeThatTick > 18) {
+ LorenzUtils.debug("Detected hotswap now!")
+ hotswap = true
+ }
+ }
+ } else {
+ if (tps > 15) {
+ hotswap = false
+ }
+ }
+ beforeThatTick = lastTps
+ lastTps = tps
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/test/SkyHanniConfigSearchResetCommand.kt b/src/main/java/at/hannibal2/skyhanni/test/SkyHanniConfigSearchResetCommand.kt
index bc5a6c25d..6f1bc9f64 100644
--- a/src/main/java/at/hannibal2/skyhanni/test/SkyHanniConfigSearchResetCommand.kt
+++ b/src/main/java/at/hannibal2/skyhanni/test/SkyHanniConfigSearchResetCommand.kt
@@ -16,20 +16,21 @@ import kotlinx.coroutines.launch
import java.lang.reflect.Field
import java.lang.reflect.Modifier
+// TODO in the future change something here
object SkyHanniConfigSearchResetCommand {
private var lastCommand = emptyArray<String>()
fun command(args: Array<String>) {
SkyHanniMod.coroutineScope.launch {
- LorenzUtils.chat(runCommand(args))
+ LorenzUtils.chat(runCommand(args), false)
}
lastCommand = args
}
private suspend fun runCommand(args: Array<String>): String {
if (args.isEmpty()) {
- return "§c[SkyHanni] This is a powerful config-edit command, only use it if you know what you are doing!"
+ return "§cThis is a powerful config-edit command, only use it if you know what you are doing!"
}
return when (args[0].lowercase()) {
@@ -181,7 +182,7 @@ object SkyHanniConfigSearchResetCommand {
if (!classFilter(className)) continue
val objectName = obj.getObjectName()
if (obj !is Runnable && objectName.startsWith(className) && (objectName.startsWith("at.hannibal2.skyhanni.config.features.") ||
- objectName.startsWith("at.hannibal2.skyhanni.config.Storage"))
+ objectName.startsWith("at.hannibal2.skyhanni.config.Storage"))
) {
"<category>"
} else {
@@ -243,8 +244,7 @@ object SkyHanniConfigSearchResetCommand {
if (this is Runnable) return "Runnable"
// we don't use javaClass.simpleName since we want to catch edge cases
- val name = javaClass.name
- return when (name) {
+ return when (val name = javaClass.name) {
"at.hannibal2.skyhanni.config.core.config.Position" -> "Position"
"java.lang.Boolean" -> "Boolean"
"java.lang.Integer" -> "Int"
diff --git a/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt b/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt
index 36042b977..635ea3351 100644
--- a/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt
+++ b/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.test
import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.config.ConfigFileType
import at.hannibal2.skyhanni.config.ConfigGuiManager
import at.hannibal2.skyhanni.config.ConfigManager
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
@@ -8,10 +9,12 @@ import at.hannibal2.skyhanni.data.HypixelData
import at.hannibal2.skyhanni.data.SlayerAPI
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
+import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
import at.hannibal2.skyhanni.events.PlaySoundEvent
import at.hannibal2.skyhanni.events.ReceiveParticleEvent
import at.hannibal2.skyhanni.features.dungeon.DungeonAPI
import at.hannibal2.skyhanni.features.garden.visitor.GardenVisitorColorNames
+import at.hannibal2.skyhanni.test.GriffinUtils.drawWaypointFilled
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalNameOrNull
@@ -19,15 +22,18 @@ import at.hannibal2.skyhanni.utils.ItemUtils.getItemRarityOrNull
import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.KeyboardManager.isKeyHeld
import at.hannibal2.skyhanni.utils.LocationUtils
+import at.hannibal2.skyhanni.utils.LorenzColor
import at.hannibal2.skyhanni.utils.LorenzDebug
import at.hannibal2.skyhanni.utils.LorenzLogger
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.makeAccessible
+import at.hannibal2.skyhanni.utils.LorenzVec
import at.hannibal2.skyhanni.utils.NEUInternalName
import at.hannibal2.skyhanni.utils.NEUItems
import at.hannibal2.skyhanni.utils.NEUItems.getNpcPriceOrNull
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.OSUtils
+import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText
import at.hannibal2.skyhanni.utils.RenderUtils.renderString
import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
import at.hannibal2.skyhanni.utils.SoundUtils
@@ -56,11 +62,11 @@ class SkyHanniDebugsAndTests {
val debugLogger = LorenzLogger("debug/test")
- fun runn(compound: NBTTagCompound, text: String) {
+ private fun run(compound: NBTTagCompound, text: String) {
print("$text'$compound'")
for (s in compound.keySet) {
val element = compound.getCompoundTag(s)
- runn(element, "$text ")
+ run(element, "$text ")
}
}
@@ -68,6 +74,31 @@ class SkyHanniDebugsAndTests {
LorenzDebug.log(text)
}
+ private var testLocation: LorenzVec? = null
+
+ @SubscribeEvent
+ fun onRenderWorld(event: LorenzRenderWorldEvent) {
+ testLocation?.let {
+ event.drawWaypointFilled(it, LorenzColor.WHITE.toColor())
+ event.drawDynamicText(it, "Test", 1.5)
+ }
+ }
+
+ fun waypoint(args: Array<String>) {
+ SoundUtils.playBeepSound()
+
+ if (args.isEmpty()) {
+ testLocation = null
+ LorenzUtils.chat("reset test waypoint")
+ }
+
+ val x = args[0].toDouble()
+ val y = args[1].toDouble()
+ val z = args[2].toDouble()
+ testLocation = LorenzVec(x, y, z)
+ LorenzUtils.chat("set test waypoint")
+ }
+
fun testCommand(args: Array<String>) {
SoundUtils.playBeepSound()
@@ -109,7 +140,8 @@ class SkyHanniDebugsAndTests {
LorenzUtils.clickableChat(
"§cTHIS WILL RESET YOUR SkyHanni CONFIG! Click here to procceed.",
- "shconfigmanagerreset confirm"
+ "shconfigmanagerreset confirm",
+ false
)
}
@@ -117,8 +149,8 @@ class SkyHanniDebugsAndTests {
// TODO make it so that it does not reset the config
// saving old config state
- SkyHanniMod.configManager.saveConfig("reload config manager")
- SkyHanniMod.configManager.saveSackData("reload config manager")
+ SkyHanniMod.configManager.saveConfig(ConfigFileType.FEATURES, "reload config manager")
+ SkyHanniMod.configManager.saveConfig(ConfigFileType.SACKS, "reload config manager")
Thread {
Thread.sleep(500)
SkyHanniMod.configManager.disableSaving()
@@ -131,7 +163,7 @@ class SkyHanniDebugsAndTests {
// resetting the MoulConfigProcessor in use
ConfigGuiManager.editor = null
- LorenzUtils.chat("§e[SkyHanni] Reset the config manager!")
+ LorenzUtils.chat("Reset the config manager!")
}.start()
}
@@ -204,7 +236,7 @@ class SkyHanniDebugsAndTests {
println("Skipped registering listener $simpleName")
}
}
- LorenzUtils.chat("§e[SkyHanni] reloaded ${modules.size} listener classes.")
+ LorenzUtils.chat("reloaded ${modules.size} listener classes.")
}
fun stopListeners() {
@@ -215,7 +247,7 @@ class SkyHanniDebugsAndTests {
MinecraftForge.EVENT_BUS.unregister(original)
println("Unregistered listener $simpleName")
}
- LorenzUtils.chat("§e[SkyHanni] stopped ${modules.size} listener classes.")
+ LorenzUtils.chat("stopped ${modules.size} listener classes.")
}
fun copyLocation(args: Array<String>) {
@@ -232,7 +264,9 @@ class SkyHanniDebugsAndTests {
}
fun debugVersion() {
- LorenzUtils.chat("§eYou are using SkyHanni ${SkyHanniMod.version}")
+ val name = "SkyHanni ${SkyHanniMod.version}"
+ LorenzUtils.chat("§eYou are using $name")
+ OSUtils.copyToClipboard(name)
}
fun debugData(args: Array<String>) {
@@ -290,6 +324,7 @@ class SkyHanniDebugsAndTests {
builder.append("Doing slayer!\n")
builder.append(" activeSlayer: ${SlayerAPI.getActiveSlayer()}\n")
builder.append(" isInCorrectArea: ${SlayerAPI.isInCorrectArea}\n")
+ builder.append(" isInAnyArea: ${SlayerAPI.isInAnyArea}\n")
}
}
@@ -319,9 +354,9 @@ class SkyHanniDebugsAndTests {
fun toggleRender() {
globalRender = !globalRender
if (globalRender) {
- LorenzUtils.chat("§e[SkyHanni] §aEnabled global renderer!")
+ LorenzUtils.chat("§aEnabled global renderer!")
} else {
- LorenzUtils.chat("§e[SkyHanni] §cDisabled global renderer! Run this command again to show SkyHanni rendering again.")
+ LorenzUtils.chat("§cDisabled global renderer! Run this command again to show SkyHanni rendering again.")
}
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/test/TestBingo.kt b/src/main/java/at/hannibal2/skyhanni/test/TestBingo.kt
index f2eda2892..95832ac46 100644
--- a/src/main/java/at/hannibal2/skyhanni/test/TestBingo.kt
+++ b/src/main/java/at/hannibal2/skyhanni/test/TestBingo.kt
@@ -7,6 +7,6 @@ object TestBingo {
fun toggle() {
testBingo = !testBingo
- LorenzUtils.chat("§e[SkyHanni] Test Bingo " + (if (testBingo) "enabled" else "disabled"))
+ LorenzUtils.chat("Test Bingo " + (if (testBingo) "enabled" else "disabled"))
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/test/TestCopyBestiaryValues.kt b/src/main/java/at/hannibal2/skyhanni/test/TestCopyBestiaryValues.kt
index 3e5072fac..24edae9cc 100644
--- a/src/main/java/at/hannibal2/skyhanni/test/TestCopyBestiaryValues.kt
+++ b/src/main/java/at/hannibal2/skyhanni/test/TestCopyBestiaryValues.kt
@@ -47,18 +47,12 @@ object TestCopyBestiaryValues {
if (!SkyHanniMod.feature.dev.debug.copyBestiaryData) return
SkyHanniDebugsAndTests.displayLine = ""
- val backItem = event.inventoryItems[3 + 9 * 5 + 3]
- if (backItem == null) {
- return
- }
+ val backItem = event.inventoryItems[3 + 9 * 5 + 3] ?: return
if (backItem.getLore().none { it.contains("Bestiary Milestone") }) {
return
}
- val rankingItem = event.inventoryItems[3 + 9 * 5 + 2]
- if (rankingItem == null) {
- return
- }
+ val rankingItem = event.inventoryItems[3 + 9 * 5 + 2] ?: return
if (rankingItem.getLore().none { it.contains("Ranking") }) {
return
}
@@ -71,7 +65,7 @@ object TestCopyBestiaryValues {
val name = titleItem.name ?: return
val titleName = name.split(" ").dropLast(1).joinToString(" ")
- val obj: BestiarityObject = BestiarityObject()
+ val obj = BestiarityObject()
obj.name = titleName
obj.texture = titleItem.getSkullTexture() ?: "no texture found"
obj.skullOwner = titleItem.getSkullOwner() ?: "no skullOwner found"
@@ -116,4 +110,4 @@ object TestCopyBestiaryValues {
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
event.move(3, "dev.copyBestiaryData", "dev.debug.copyBestiaryData")
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/test/TestExportTools.kt b/src/main/java/at/hannibal2/skyhanni/test/TestExportTools.kt
index a924da86d..b7c1a6f4b 100644
--- a/src/main/java/at/hannibal2/skyhanni/test/TestExportTools.kt
+++ b/src/main/java/at/hannibal2/skyhanni/test/TestExportTools.kt
@@ -40,7 +40,7 @@ object TestExportTools {
val data: JsonElement,
)
- fun <T> toJson(key: Key<T>, value: T): String {
+ private fun <T> toJson(key: Key<T>, value: T): String {
return gson.toJson(TestValue(key.name, gson.toJsonTree(value)))
}
@@ -61,10 +61,9 @@ object TestExportTools {
}
val json = toJson(Item, stack)
OSUtils.copyToClipboard(json)
- LorenzUtils.chat("§e[SkyHanni] Compressed item info copied into the clipboard!")
+ LorenzUtils.chat("Compressed item info copied into the clipboard!")
}
-
inline fun <reified T> getTestData(category: Key<T>, name: String): T {
val reader = InputStreamReader(javaClass.getResourceAsStream("/testdata/${category.name}/$name.json")!!)
return fromJson(category, reader)
@@ -76,4 +75,4 @@ object TestExportTools {
event.move(4, "dev.debug.copyNBTData", "dev.debug.copyItemData")
event.move(4, "dev.debug.copyNBTDataCompressed", "dev.debug.copyItemDataCompressed")
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/test/command/CopyItemCommand.kt b/src/main/java/at/hannibal2/skyhanni/test/command/CopyItemCommand.kt
index f0b2c8ae1..6a583b1e3 100644
--- a/src/main/java/at/hannibal2/skyhanni/test/command/CopyItemCommand.kt
+++ b/src/main/java/at/hannibal2/skyhanni/test/command/CopyItemCommand.kt
@@ -14,7 +14,7 @@ object CopyItemCommand {
fun command() {
val itemStack = InventoryUtils.getItemInHand()
if (itemStack == null) {
- LorenzUtils.chat("§c[SkyHanni] No item in hand!")
+ LorenzUtils.userError("No item in hand!")
return
}
copyItemToClipboard(itemStack)
@@ -53,6 +53,6 @@ object CopyItemCommand {
val string = resultList.joinToString("\n")
OSUtils.copyToClipboard(string)
- LorenzUtils.chat("§e[SkyHanni] Item info copied into the clipboard!")
+ LorenzUtils.chat("Item info copied into the clipboard!")
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/test/command/CopyNearbyEntitiesCommand.kt b/src/main/java/at/hannibal2/skyhanni/test/command/CopyNearbyEntitiesCommand.kt
index b7c4ae4a1..dae69775a 100644
--- a/src/main/java/at/hannibal2/skyhanni/test/command/CopyNearbyEntitiesCommand.kt
+++ b/src/main/java/at/hannibal2/skyhanni/test/command/CopyNearbyEntitiesCommand.kt
@@ -45,6 +45,7 @@ object CopyNearbyEntitiesCommand {
resultList.add("name: '" + entity.name + "'")
resultList.add("displayName: '${displayName.formattedText}'")
resultList.add("entityId: ${entity.entityId}")
+ resultList.add("uuid version: ${entity.uniqueID.version()} ${if(entity.uniqueID.version() != 4) "NPC " else ""}(${entity.uniqueID})")
resultList.add("location data:")
resultList.add("- vec: $vec")
resultList.add("- distance: $distance")
@@ -146,9 +147,9 @@ object CopyNearbyEntitiesCommand {
if (counter != 0) {
val string = resultList.joinToString("\n")
OSUtils.copyToClipboard(string)
- LorenzUtils.chat("§e[SkyHanni] $counter entities copied into the clipboard!")
+ LorenzUtils.chat("$counter entities copied into the clipboard!")
} else {
- LorenzUtils.chat("§e[SkyHanni] No entities found in a search radius of $searchRadius!")
+ LorenzUtils.chat("No entities found in a search radius of $searchRadius!")
}
}
@@ -167,4 +168,4 @@ object CopyNearbyEntitiesCommand {
resultList.add("- type: $type")
}
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/test/command/CopyNearbyParticlesCommand.kt b/src/main/java/at/hannibal2/skyhanni/test/command/CopyNearbyParticlesCommand.kt
index 88a6f7f5f..67b28f0aa 100644
--- a/src/main/java/at/hannibal2/skyhanni/test/command/CopyNearbyParticlesCommand.kt
+++ b/src/main/java/at/hannibal2/skyhanni/test/command/CopyNearbyParticlesCommand.kt
@@ -41,10 +41,10 @@ object CopyNearbyParticlesCommand {
if (resultList.isEmpty() && tickTime == 0L) tickTime = System.currentTimeMillis()
if (System.currentTimeMillis() > tickTime + 30) {
- if (counter == 0) LorenzUtils.chat("§e[SkyHanni] No particles found nearby, try a larger search radius") else {
+ if (counter == 0) LorenzUtils.chat("No particles found nearby, try a larger search radius") else {
val string = resultList.joinToString("\n")
OSUtils.copyToClipboard(string)
- LorenzUtils.chat("§e[SkyHanni] $counter particles copied into the clipboard!")
+ LorenzUtils.chat("$counter particles copied into the clipboard!")
}
saveNextTick = false
return
@@ -65,7 +65,7 @@ object CopyNearbyParticlesCommand {
resultList.add("particle arguments: ${packet.particleArgs.asList()}")
resultList.add("")
resultList.add("")
- counter ++
+ counter++
}
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/test/command/CopyScoreboardCommand.kt b/src/main/java/at/hannibal2/skyhanni/test/command/CopyScoreboardCommand.kt
index bcc0cfc35..b940d1948 100644
--- a/src/main/java/at/hannibal2/skyhanni/test/command/CopyScoreboardCommand.kt
+++ b/src/main/java/at/hannibal2/skyhanni/test/command/CopyScoreboardCommand.kt
@@ -11,16 +11,16 @@ object CopyScoreboardCommand {
val resultList = mutableListOf<String>()
val noColor = args.size == 1 && args[0] == "true"
resultList.add("Title:")
- resultList.add(ScoreboardData.objectiveTitle.transformIf({noColor}) { removeColor() })
+ resultList.add(ScoreboardData.objectiveTitle.transformIf({ noColor }) { removeColor() })
resultList.add("")
for (line in ScoreboardData.sidebarLinesFormatted) {
- val scoreboardLine = line.transformIf({noColor}) { removeColor() }
+ val scoreboardLine = line.transformIf({ noColor }) { removeColor() }
resultList.add("'$scoreboardLine'")
}
val string = resultList.joinToString("\n")
OSUtils.copyToClipboard(string)
- LorenzUtils.chat("§e[SkyHanni] scoreboard copied into your clipboard!")
+ LorenzUtils.chat("Scoreboard copied into your clipboard!")
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/test/command/CopyTabListCommand.kt b/src/main/java/at/hannibal2/skyhanni/test/command/CopyTabListCommand.kt
deleted file mode 100644
index a4f287e5b..000000000
--- a/src/main/java/at/hannibal2/skyhanni/test/command/CopyTabListCommand.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-package at.hannibal2.skyhanni.test.command
-
-import at.hannibal2.skyhanni.mixins.transformers.AccessorGuiPlayerTabOverlay
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.LorenzUtils.conditionalTransform
-import at.hannibal2.skyhanni.utils.LorenzUtils.transformIf
-import at.hannibal2.skyhanni.utils.OSUtils
-import at.hannibal2.skyhanni.utils.StringUtils.removeColor
-import at.hannibal2.skyhanni.utils.TabListData
-import net.minecraft.client.Minecraft
-
-object CopyTabListCommand {
- fun command(args: Array<String>) {
- val resultList = mutableListOf<String>()
- val noColor = args.size == 1 && args[0] == "true"
- for (line in TabListData.getTabList()) {
- val tabListLine = line.transformIf({ noColor }) { removeColor() }
- if (tabListLine != "") resultList.add("'$tabListLine'")
- }
- val tabList = Minecraft.getMinecraft().ingameGUI.tabList as AccessorGuiPlayerTabOverlay
- val tabHeader = tabList.header_skyhanni.conditionalTransform(noColor, { unformattedText }, { formattedText })
- val tabFooter = tabList.footer_skyhanni.conditionalTransform(noColor, { unformattedText }, { formattedText })
- val string = "Header:\n\n$tabHeader\n\nBody:\n\n${resultList.joinToString("\n")}\n\nFooter:\n\n$tabFooter"
- OSUtils.copyToClipboard(string)
- LorenzUtils.chat("§e[SkyHanni] Tab list copied into the clipboard!")
- }
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/test/command/ErrorManager.kt b/src/main/java/at/hannibal2/skyhanni/test/command/ErrorManager.kt
index c8cbf6a30..cc24fbd5b 100644
--- a/src/main/java/at/hannibal2/skyhanni/test/command/ErrorManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/test/command/ErrorManager.kt
@@ -29,7 +29,7 @@ object ErrorManager {
fun command(array: Array<String>) {
if (array.size != 1) {
- LorenzUtils.chat("§cUse /shcopyerror <error id>")
+ LorenzUtils.userError("Use /shcopyerror <error id>")
return
}
@@ -40,23 +40,37 @@ object ErrorManager {
} else {
errorMessages[id]
}
- val name = if (fullErrorMessage) "Ful error" else "Error"
+ val name = if (fullErrorMessage) "Full error" else "Error"
LorenzUtils.chat(errorMessage?.let {
OSUtils.copyToClipboard(it)
- "§e[SkyHanni] $name copied into the clipboard, please report it on the SkyHanni discord!"
- } ?: "§c[SkyHanni] Error id not found!")
+ "$name copied into the clipboard, please report it on the SkyHanni discord!"
+ } ?: "Error id not found!")
}
+ @Deprecated("Use data as well", ReplaceWith("logErrorStateWithData()"))
fun logErrorState(userMessage: String, internalMessage: String) {
- logError(IllegalStateException(internalMessage), userMessage)
+ logError(IllegalStateException(internalMessage), userMessage, false)
}
- // we love java
+ fun logErrorStateWithData(userMessage: String, internalMessage: String, vararg extraData: Pair<String, Any?>) {
+ logError(IllegalStateException(internalMessage), userMessage, false, *extraData)
+ }
+
+ @Deprecated("Use data as well", ReplaceWith("logErrorWithData()"))
fun logError(throwable: Throwable, message: String) {
logError(throwable, message, false)
}
- fun logError(throwable: Throwable, message: String, ignoreErrorCache: Boolean) {
+ fun logErrorWithData(throwable: Throwable, message: String, vararg extraData: Pair<String, Any?>) {
+ logError(throwable, message, false, *extraData)
+ }
+
+ fun logError(
+ throwable: Throwable,
+ message: String,
+ ignoreErrorCache: Boolean,
+ vararg extraData: Pair<String, Any?>
+ ) {
val error = Error(message, throwable)
error.printStackTrace()
Minecraft.getMinecraft().thePlayer ?: return
@@ -73,16 +87,41 @@ object ErrorManager {
val stackTrace = throwable.getCustomStackTrace(false).joinToString("\n").removeSpam()
val randomId = UUID.randomUUID().toString()
+ val extraDataString = buildExtraDataString(extraData)
val rawMessage = message.removeColor()
- errorMessages[randomId] = "```\nSkyHanni ${SkyHanniMod.version}: $rawMessage\n \n$stackTrace\n```"
+ errorMessages[randomId] =
+ "```\nSkyHanni ${SkyHanniMod.version}: $rawMessage\n \n$stackTrace\n$extraDataString```"
fullErrorMessages[randomId] =
- "```\nSkyHanni ${SkyHanniMod.version}: $rawMessage\n(full stack trace)\n \n$fullStackTrace\n```"
+ "```\nSkyHanni ${SkyHanniMod.version}: $rawMessage\n(full stack trace)\n \n$fullStackTrace\n$extraDataString```"
LorenzUtils.clickableChat(
- "§c[SkyHanni ${SkyHanniMod.version}]: $message§c. Click here to copy the error into the clipboard.",
- "shcopyerror $randomId"
+ "§c[SkyHanni-${SkyHanniMod.version}]: $message§c. Click here to copy the error into the clipboard.",
+ "shcopyerror $randomId",
+ false
)
}
+
+ private fun buildExtraDataString(extraData: Array<out Pair<String, Any?>>): String {
+ val extraDataString = if (extraData.isNotEmpty()) {
+ val builder = StringBuilder()
+ for ((key, value) in extraData) {
+ builder.append(key)
+ builder.append(": ")
+ if (value is Iterable<*>) {
+ builder.append("\n")
+ for (line in value) {
+ builder.append(" - '$line'")
+ builder.append("\n")
+ }
+ } else {
+ builder.append("'$value'")
+ }
+ builder.append("\n")
+ }
+ "\nExtra data:\n$builder"
+ } else ""
+ return extraDataString
+ }
}
private fun Throwable.getCustomStackTrace(full: Boolean, parent: List<String> = emptyList()): List<String> = buildList {
@@ -139,7 +178,7 @@ private fun String.removeSpam(): String {
"at net.minecraft.client.Minecraft.addScheduledTask(",
"at java.lang.reflect.",
"at at.hannibal2.skyhanni.config.commands.Commands\$",
- "CopyErrorCommand.logErrorState(CopyErrorCommand.kt:46)",
+ ".ErrorManager.logErrorState(ErrorManager.kt:51)",
"LorenzEvent.postWithoutCatch(LorenzEvent.kt:24)",
"LorenzEvent.postAndCatch(LorenzEvent.kt:15)",
"at net.minecraft.launchwrapper.",
diff --git a/src/main/java/at/hannibal2/skyhanni/test/command/TestChatCommand.kt b/src/main/java/at/hannibal2/skyhanni/test/command/TestChatCommand.kt
index 759cbd9e7..a60b0f0d2 100644
--- a/src/main/java/at/hannibal2/skyhanni/test/command/TestChatCommand.kt
+++ b/src/main/java/at/hannibal2/skyhanni/test/command/TestChatCommand.kt
@@ -8,15 +8,16 @@ import net.minecraftforge.common.MinecraftForge
object TestChatCommand {
fun command(args: Array<String>) {
if (args.isEmpty()) {
- LorenzUtils.chat("§c[SkyHanni] Specify a chat message to test")
+ LorenzUtils.userError("Specify a chat message to test!")
return
}
+
val hidden = args.last() == "-s"
var rawMessage = args.toList().joinToString(" ")
- if (!hidden) LorenzUtils.chat("§a[SkyHanni] testing message: §7$rawMessage")
+ if (!hidden) LorenzUtils.chat("Testing message: §7$rawMessage", prefixColor = "§a")
if (hidden) rawMessage = rawMessage.replace(" -s", "")
val formattedMessage = rawMessage.replace("&", "§")
- LorenzUtils.chat(formattedMessage)
+ LorenzUtils.chat(formattedMessage, false)
MinecraftForge.EVENT_BUS.post(ClientChatReceivedEvent(0, ChatComponentText(formattedMessage)))
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt b/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt
index c0116f57c..1801e7802 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt
@@ -41,9 +41,13 @@ object APIUtil {
.useSystemProperties()
fun getJSONResponse(urlString: String, silentError: Boolean = false) =
- getJSONResponseAsElement(urlString, silentError) as JsonObject
+ getJSONResponseAsElement(urlString, silentError) as JsonObject
- fun getJSONResponseAsElement(urlString: String, silentError: Boolean = false, apiName: String = "Hypixel API"): JsonElement {
+ fun getJSONResponseAsElement(
+ urlString: String,
+ silentError: Boolean = false,
+ apiName: String = "Hypixel API"
+ ): JsonElement {
val client = builder.build()
try {
client.execute(HttpGet(urlString)).use { response ->
@@ -60,7 +64,7 @@ object APIUtil {
} else if (retSrc.contains("<center><h1>502 Bad Gateway</h1></center>")) {
if (showApiErrors && apiName == "Hypixel API") {
LorenzUtils.clickableChat(
- "[SkyHanni] Problems with detecting the Hypixel API. §eClick here to hide this message for now.",
+ "Problems with detecting the Hypixel API. §eClick here to hide this message for now.",
"shtogglehypixelapierrors"
)
}
@@ -128,6 +132,6 @@ object APIUtil {
fun toggleApiErrorMessages() {
showApiErrors = !showApiErrors
- LorenzUtils.chat("§e[SkyHanni] Hypixel API error messages " + if (showApiErrors) "§chidden" else "§ashown")
+ LorenzUtils.chat("Hypixel API error messages " + if (showApiErrors) "§chidden" else "§ashown")
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/BlockUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/BlockUtils.kt
index 5a14cadf7..9bc353820 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/BlockUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/BlockUtils.kt
@@ -53,4 +53,4 @@ object BlockUtils {
Minecraft.getMinecraft().thePlayer.lookVec.toLorenzVec(),
duration
)
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/CachedItemData.kt b/src/main/java/at/hannibal2/skyhanni/utils/CachedItemData.kt
index 8f05d64ec..9d00958f2 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/CachedItemData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/CachedItemData.kt
@@ -1,11 +1,24 @@
package at.hannibal2.skyhanni.utils
data class CachedItemData(
- /** -1 = not loaded */ var petCandies: Int? = -1,
- /** "" = not loaded */ var heldItem: String? = "",
- /** -1 = not loaded */ var sackInASack: Int? = -1,
- /** null = not loaded */ var riftTransferable: Boolean? = null,
- /** null = not loaded */ var riftExportable: Boolean? = null,
- /** null = not loaded */ var itemRarityLastCheck: Long = 0L, // Cant use SimpleTimeMark here
- /** null = not loaded */ var itemRarity: LorenzRarity? = null,
-) \ No newline at end of file
+ // -1 = not loaded
+ var petCandies: Int? = -1,
+
+ // "" = not loaded
+ var heldItem: String? = "",
+
+ // -1 = not loaded
+ var sackInASack: Int? = -1,
+
+ // null = not loaded
+ var riftTransferable: Boolean? = null,
+
+ // null = not loaded
+ var riftExportable: Boolean? = null,
+
+ // null = not loaded
+ var itemRarityLastCheck: Long = 0L, // Cant use SimpleTimeMark here
+
+ // null = not loaded
+ var itemRarity: LorenzRarity? = null,
+)
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/CombatUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/CombatUtils.kt
index cbd39849d..b0af1d93e 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/CombatUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/CombatUtils.kt
@@ -72,8 +72,8 @@ object CombatUtils {
lastKillUpdate = System.currentTimeMillis()
killGainHourLast = killGainHour
- GhostCounter.hidden?.bestiaryNextLevel?.toInt()?.let { nextLevel ->
- GhostCounter.hidden?.bestiaryCurrentKill?.toInt()?.let { kill ->
+ GhostCounter.storage?.bestiaryNextLevel?.toInt()?.let { nextLevel ->
+ GhostCounter.storage?.bestiaryCurrentKill?.toInt()?.let { kill ->
val sum = GhostData.bestiaryData.filterKeys { it <= nextLevel - 1 }.values.sum()
val cKill = sum + kill
val totalKill = if (GhostCounter.config.showMax) GhostCounter.bestiaryCurrentKill else cKill
@@ -112,4 +112,4 @@ object CombatUtils {
return interp
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt b/src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt
index fbe2f1e96..28fc08807 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt
@@ -104,13 +104,13 @@ object EntityOutlineRenderer {
mc.renderManager.setRenderOutlines(true)
// Enable outline mode
- GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL13.GL_COMBINE);
- GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_COMBINE_RGB, GL11.GL_REPLACE);
- GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_SOURCE0_RGB, GL13.GL_CONSTANT);
- GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND0_RGB, GL11.GL_SRC_COLOR);
- GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_COMBINE_ALPHA, GL11.GL_REPLACE);
- GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_SOURCE0_ALPHA, GL11.GL_TEXTURE);
- GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND0_ALPHA, GL11.GL_SRC_ALPHA);
+ GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL13.GL_COMBINE)
+ GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_COMBINE_RGB, GL11.GL_REPLACE)
+ GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_SOURCE0_RGB, GL13.GL_CONSTANT)
+ GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND0_RGB, GL11.GL_SRC_COLOR)
+ GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_COMBINE_ALPHA, GL11.GL_REPLACE)
+ GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_SOURCE0_ALPHA, GL11.GL_TEXTURE)
+ GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND0_ALPHA, GL11.GL_SRC_ALPHA)
// Render x-ray outlines first, ignoring the depth buffer bit
if (!isXrayCacheEmpty()) {
@@ -293,7 +293,7 @@ object EntityOutlineRenderer {
// Only render the view entity when sleeping or in 3rd person mode
if (entity === mc.renderViewEntity &&
!(mc.renderViewEntity is EntityLivingBase && (mc.renderViewEntity as EntityLivingBase).isPlayerSleeping ||
- mc.gameSettings.thirdPersonView != 0)
+ mc.gameSettings.thirdPersonView != 0)
) {
false
} else mc.theWorld.isBlockLoaded(BlockPos(entity)) && (mc.renderManager.shouldRender(
@@ -339,7 +339,7 @@ object EntityOutlineRenderer {
}
}
- fun isCacheEmpty() = isXrayCacheEmpty() && isNoXrayCacheEmpty()
+ private fun isCacheEmpty() = isXrayCacheEmpty() && isNoXrayCacheEmpty()
private fun isXrayCacheEmpty() = entityRenderCache.xrayCache?.isEmpty() ?: true
private fun isNoXrayCacheEmpty() = entityRenderCache.noXrayCache?.isEmpty() ?: true
@@ -361,12 +361,12 @@ object EntityOutlineRenderer {
*/
@SubscribeEvent
fun onTick(event: LorenzTickEvent) {
- if (!(event.phase == EventPriority.NORMAL && isEnabled())) return;
+ if (!(event.phase == EventPriority.NORMAL && isEnabled())) return
val renderGlobal = try {
mc.renderGlobal as CustomRenderGlobal
} catch (e: NoClassDefFoundError) {
- ErrorManager.logError(e, "Unable to enable entity outlines, the required mixin is not loaded")
+ ErrorManager.logErrorWithData(e, "Unable to enable entity outlines, the required mixin is not loaded")
isMissingMixin = true
return
}
@@ -406,4 +406,4 @@ object EntityOutlineRenderer {
var noXrayCache: HashMap<Entity, Int>?,
var noOutlineCache: HashSet<Entity>?
)
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt
index 1269ec005..5e4a63452 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt
@@ -164,9 +164,8 @@ object GuiRenderUtils {
drawTooltip(textLines, mouseX, mouseY, screenHeight, Minecraft.getMinecraft().fontRendererObj)
}
- fun isPointInRect(x: Int, y: Int, left: Int, top: Int, width: Int, height: Int): Boolean {
- return left <= x && x < left + width && top <= y && y < top + height
- }
+ fun isPointInRect(x: Int, y: Int, left: Int, top: Int, width: Int, height: Int) =
+ left <= x && x < left + width && top <= y && y < top + height
fun drawProgressBar(x: Int, y: Int, barWidth: Int, progress: Float) {
GuiScreen.drawRect(x, y, x + barWidth, y + 6, 0xFF43464B.toInt())
@@ -181,7 +180,15 @@ object GuiRenderUtils {
)
}
- fun renderItemAndTip(list: MutableList<String>, item: ItemStack?, x: Int, y: Int, mouseX: Int, mouseY: Int, color: Int = 0xFF43464B.toInt()) {
+ fun renderItemAndTip(
+ list: MutableList<String>,
+ item: ItemStack?,
+ x: Int,
+ y: Int,
+ mouseX: Int,
+ mouseY: Int,
+ color: Int = 0xFF43464B.toInt()
+ ) {
GuiScreen.drawRect(x, y, x + 16, y + 16, color)
if (item != null) {
renderItemStack(item, x, y)
@@ -277,12 +284,14 @@ object GuiRenderUtils {
}
fun drawScaledRec(left: Int, top: Int, right: Int, bottom: Int, colour: Int, inverseScale: Float) {
- GuiScreen.drawRect((left * inverseScale).toInt(), (top * inverseScale).toInt(),
- (right * inverseScale).toInt(), (bottom * inverseScale).toInt(), colour)
+ GuiScreen.drawRect(
+ (left * inverseScale).toInt(), (top * inverseScale).toInt(),
+ (right * inverseScale).toInt(), (bottom * inverseScale).toInt(), colour
+ )
}
fun renderItemAndBackground(item: ItemStack, x: Int, y: Int, colour: Int) {
renderItemStack(item, x, y)
GuiScreen.drawRect(x, y, x + 16, y + 16, colour)
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt
index 4c60444c1..be29569a5 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt
@@ -1,14 +1,12 @@
package at.hannibal2.skyhanni.utils
-import at.hannibal2.skyhanni.config.ConfigManager
-import at.hannibal2.skyhanni.data.OtherMod
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.inventory.ContainerChest
import net.minecraft.inventory.Slot
import net.minecraft.item.ItemStack
-import java.io.File
import kotlin.time.Duration.Companion.seconds
object InventoryUtils {
@@ -40,13 +38,14 @@ object InventoryUtils {
fun ContainerChest.getInventoryName() = this.lowerChestInventory.displayName.unformattedText.trim()
fun getItemsInOwnInventory() = Minecraft.getMinecraft().thePlayer.inventory.mainInventory.filterNotNull()
+ fun getItemsInOwnInventoryWithNull() = Minecraft.getMinecraft().thePlayer.inventory.mainInventory
fun countItemsInLowerInventory(predicate: (ItemStack) -> Boolean) =
getItemsInOwnInventory().filter { predicate(it) }.sumOf { it.stackSize }
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
@@ -55,17 +54,16 @@ object InventoryUtils {
val isNeuStorageEnabled = RecalculatingValue(10.seconds) {
try {
- val configPath = OtherMod.NEU.configPath
- if (File(configPath).exists()) {
- val json = ConfigManager.gson.fromJson(
- APIUtil.readFile(File(configPath)),
- com.google.gson.JsonObject::class.java
- )
- json["storageGUI"].asJsonObject["enableStorageGUI3"].asBoolean
- } else false
- } catch (e: Exception) {
+ val config = NotEnoughUpdates.INSTANCE.config
+
+ val storageField = config.javaClass.getDeclaredField("storageGUI")
+ val storage = storageField.get(config)
+
+ val booleanField = storage.javaClass.getDeclaredField("enableStorageGUI3")
+ booleanField.get(storage) as Boolean
+ } catch (e: Throwable) {
ErrorManager.logError(e, "Could not read NEU config to determine if the neu storage is emabled.")
false
}
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt
index 2c5ab63d3..a1b7ed09f 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt
@@ -65,7 +65,7 @@ object ItemUtils {
val list: LinkedList<ItemStack> = LinkedList()
val player = Minecraft.getMinecraft().thePlayer
if (player == null) {
- LorenzUtils.warning("getItemsInInventoryWithSlots: player is null!")
+ LorenzUtils.error("getItemsInInventoryWithSlots: player is null!")
return list
}
for (slot in player.openContainer.inventorySlots) {
@@ -75,7 +75,7 @@ object ItemUtils {
}
if (withCursorItem && player.inventory != null && player.inventory.itemStack != null) {
- list.add(player.inventory.itemStack)
+ list.add(player.inventory.itemStack)
}
return list
}
@@ -84,7 +84,7 @@ object ItemUtils {
val map: LinkedHashMap<ItemStack, Int> = LinkedHashMap()
val player = Minecraft.getMinecraft().thePlayer
if (player == null) {
- LorenzUtils.warning("getItemsInInventoryWithSlots: player is null!")
+ LorenzUtils.error("getItemsInInventoryWithSlots: player is null!")
return map
}
for (slot in player.openContainer.inventorySlots) {
@@ -220,9 +220,13 @@ object ItemUtils {
val rarity = LorenzRarity.readItemRarity(this)
data.itemRarity = rarity
if (rarity == null && logError) {
- ErrorManager.logErrorState(
+ ErrorManager.logErrorStateWithData(
"Could not read rarity for item $name",
- "getItemRarityOrNull not found for: $internalName, name:'$name''"
+ "Failed to read rarity from item rarity via item lore",
+ "internal name" to internalName,
+ "item name" to name,
+ "inventory name" to InventoryUtils.openInventoryName(),
+ "lore" to getLore(),
)
}
return rarity
@@ -302,15 +306,18 @@ object ItemUtils {
return getItemStack().nameWithEnchantment ?: error("Could not find item name for $this")
}
-
private fun getPetRarity(pet: ItemStack): LorenzRarity? {
val rarityId = pet.getInternalName().asString().split(";").last().toInt()
val rarity = LorenzRarity.getById(rarityId)
val name = pet.name
if (rarity == null) {
- ErrorManager.logErrorState(
+ ErrorManager.logErrorStateWithData(
"Could not read rarity for pet $name",
- "getPetRarity not found for: ${pet.getInternalName()}, name:'$name'"
+ "Failed to read rarity from pet item via internal name",
+ "internal name" to pet.getInternalName(),
+ "item name" to name,
+ "rarity id" to rarityId,
+ "inventory name" to InventoryUtils.openInventoryName()
)
}
return rarity
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LocationUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/LocationUtils.kt
index fafb41c96..e6929d737 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/LocationUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/LocationUtils.kt
@@ -6,9 +6,8 @@ import net.minecraft.util.AxisAlignedBB
object LocationUtils {
- fun canSee(a: LorenzVec, b: LorenzVec): Boolean {
- return Minecraft.getMinecraft().theWorld.rayTraceBlocks(a.toVec3(), b.toVec3(), false, true, false) == null
- }
+ fun canSee(a: LorenzVec, b: LorenzVec) =
+ Minecraft.getMinecraft().theWorld.rayTraceBlocks(a.toVec3(), b.toVec3(), false, true, false) == null
fun playerLocation() = Minecraft.getMinecraft().thePlayer.getLorenzVec()
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzLogger.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzLogger.kt
index a382a5149..e949742cd 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzLogger.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzLogger.kt
@@ -1,20 +1,27 @@
package at.hannibal2.skyhanni.utils
+import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.utils.LorenzUtils.formatCurrentTime
+import kotlinx.coroutines.launch
import java.io.File
import java.io.IOException
+import java.nio.file.Files
+import java.nio.file.attribute.BasicFileAttributes
import java.text.SimpleDateFormat
import java.util.logging.FileHandler
import java.util.logging.Formatter
import java.util.logging.LogRecord
import java.util.logging.Logger
+import kotlin.time.Duration.Companion.days
class LorenzLogger(filePath: String) {
private val format = SimpleDateFormat("HH:mm:ss")
private val fileName = "$PREFIX_PATH$filePath.log"
companion object {
+ private var LOG_DIRECTORY = File("config/skyhanni/logs")
private var PREFIX_PATH: String
+ var hasDone = false
init {
val format = SimpleDateFormat("yyyy_MM_dd/HH_mm_ss").formatCurrentTime()
@@ -53,6 +60,37 @@ class LorenzLogger(filePath: String) {
} catch (e: IOException) {
e.printStackTrace()
}
+
+ if (!hasDone && LorenzUtils.onHypixel) {
+ hasDone = true
+ val directoryFiles = LOG_DIRECTORY.listFiles() ?: run {
+ println("log directory has no files")
+ return logger
+ }
+ SkyHanniMod.coroutineScope.launch {
+ val timeToDelete = SkyHanniMod.feature.dev.logExpiryTime.days
+
+ for (file in directoryFiles) {
+ val path = file.toPath()
+ try {
+ val attributes = Files.readAttributes(path, BasicFileAttributes::class.java)
+ val creationTime = attributes.creationTime().toMillis()
+ val timeSinceCreation = SimpleTimeMark(creationTime).passedSince()
+ if (timeSinceCreation > timeToDelete) {
+ if (!file.deleteRecursively()) {
+ println("failed to delete directory: ${file.name}")
+ }
+ }
+ } catch (e: SecurityException) {
+ e.printStackTrace()
+ } catch (e: IOException) {
+ e.printStackTrace()
+ println("Error: Unable to get creation date.")
+ }
+ }
+ }
+ }
+
return logger
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzRarity.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzRarity.kt
index d589df3ac..35868027f 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzRarity.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzRarity.kt
@@ -29,9 +29,10 @@ enum class LorenzRarity(val color: LorenzColor, val id: Int) {
fun oneBelow(logError: Boolean = true): LorenzRarity? {
val rarityBelow = getById(ordinal - 1)
if (rarityBelow == null && logError) {
- ErrorManager.logErrorState(
+ ErrorManager.logErrorStateWithData(
"Problem with item rarity detected.",
- "Trying to get an item rarity below common"
+ "Trying to get an item rarity below common",
+ "ordinal" to ordinal
)
}
return rarityBelow
@@ -40,9 +41,10 @@ enum class LorenzRarity(val color: LorenzColor, val id: Int) {
fun oneAbove(logError: Boolean = true): LorenzRarity? {
val rarityBelow = getById(ordinal + 1)
if (rarityBelow == null && logError) {
- ErrorManager.logErrorState(
+ ErrorManager.logErrorStateWithData(
"Problem with item rarity detected.",
- "Trying to get an item rarity above special"
+ "Trying to get an item rarity above special",
+ "ordinal" to ordinal
)
}
return rarityBelow
@@ -65,4 +67,4 @@ enum class LorenzRarity(val color: LorenzColor, val id: Int) {
}
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt
index 28afe3b4e..90970a315 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt
@@ -64,28 +64,78 @@ object LorenzUtils {
val lastWorldSwitch get() = HypixelData.joinedWorld
- const val DEBUG_PREFIX = "[SkyHanni Debug] §7"
+ // TODO log based on chat category (error, warning, debug, user error, normal)
private val log = LorenzLogger("chat/mod_sent")
var lastButtonClicked = 0L
+ private const val DEBUG_PREFIX = "[SkyHanni Debug] §7"
+ private const val USER_ERROR_PREFIX = "§c[SkyHanni] "
+ private val ERROR_PREFIX by lazy { "§c[SkyHanni-${SkyHanniMod.version}] " }
+ private const val CHAT_PREFIX = "[SkyHanni] "
+
+ /**
+ * Sends a debug message to the chat and the console.
+ * This is only sent if the debug feature is enabled.
+ *
+ * @param message The message to be sent
+ *
+ * @see DEBUG_PREFIX
+ */
fun debug(message: String) {
if (SkyHanniMod.feature.dev.debug.enabled && internalChat(DEBUG_PREFIX + message)) {
consoleLog("[Debug] $message")
}
}
- // TODO remove ig?
- fun warning(message: String) {
- internalChat("§cWarning! $message")
- }
-
+ /**
+ * Sends a message to the user that they did something incorrectly.
+ * We should tell them what to do instead as well.
+ *
+ * @param message The message to be sent
+ *
+ * @see USER_ERROR_PREFIX
+ */
+ fun userError(message: String) {
+ internalChat(USER_ERROR_PREFIX + message)
+ }
+
+ /**
+ * Sends a message to the user that an error occurred caused by something in the code.
+ * This should be used for errors that are not caused by the user.
+ *
+ * Why deprecate this? Even if this message is descriptive for the user and the developer,
+ * we don't want inconsitencies in errors, and we would need to search
+ * for the code line where this error gets printed any way.
+ * so it's better to use the stack trace still.
+ *
+ * @param message The message to be sent
+ * @param prefix Whether to prefix the message with the error prefix, default true
+ *
+ * @see ERROR_PREFIX
+ */
+ @Deprecated(
+ "Do not send the user a non clickable non stacktrace containing error message.",
+ ReplaceWith("ErrorManager")
+ )
fun error(message: String) {
println("error: '$message'")
- internalChat("§c$message")
- }
-
- fun chat(message: String) {
- internalChat(message)
+ internalChat(ERROR_PREFIX + message)
+ }
+
+ /**
+ * Sends a message to the user
+ * @param message The message to be sent
+ * @param prefix Whether to prefix the message with the chat prefix, default true
+ * @param prefixColor Color that the prefix should be, default yellow (§e)
+ *
+ * @see CHAT_PREFIX
+ */
+ fun chat(message: String, prefix: Boolean = true, prefixColor: String = "§e") {
+ if (prefix) {
+ internalChat(prefixColor + CHAT_PREFIX + message)
+ } else {
+ internalChat(message)
+ }
}
private fun internalChat(message: String): Boolean {
@@ -133,12 +183,13 @@ object LorenzUtils {
var multiplier = 1.0
repeat(decimals) { multiplier *= 10 }
val result = kotlin.math.round(this * multiplier) / multiplier
- val a = result.toString()
- val b = toString()
- return if (a.length > b.length) this else result.toFloat()
+ val a = result.toString().length
+ val b = toString().length
+ return if (a > b) this else result.toFloat()
}
// TODO replace all calls with regex
+ @Deprecated("Do not use complicated string operations", ReplaceWith("Regex"))
fun String.between(start: String, end: String): String = this.split(start, end)[1]
// TODO use derpy() on every use case
@@ -203,7 +254,7 @@ object LorenzUtils {
fun getRawPlayerUuid() = Minecraft.getMinecraft().thePlayer.uniqueID
- fun getPlayerName() = Minecraft.getMinecraft().thePlayer.name
+ fun getPlayerName(): String = Minecraft.getMinecraft().thePlayer.name
fun <E> MutableList<List<E>>.addAsSingletonList(text: E) {
add(Collections.singletonList(text))
@@ -243,8 +294,18 @@ object LorenzUtils {
lines[index] = ChatComponentText(text.capAtMinecraftLength(90))
}
- fun clickableChat(message: String, command: String) {
- val text = ChatComponentText(message)
+ /**
+ * Sends a message to the user that they can click and run a command
+ * @param message The message to be sent
+ * @param command The command to be executed when the message is clicked
+ * @param prefix Whether to prefix the message with the chat prefix, default true
+ * @param prefixColor Color that the prefix should be, default yellow (§e)
+ *
+ * @see CHAT_PREFIX
+ */
+ fun clickableChat(message: String, command: String, prefix: Boolean = true, prefixColor: String = "§e") {
+ val msgPrefix = if (prefix) prefixColor + CHAT_PREFIX else ""
+ val text = ChatComponentText(msgPrefix + message)
val fullCommand = "/" + command.removePrefix("/")
text.chatStyle.chatClickEvent = ClickEvent(ClickEvent.Action.RUN_COMMAND, fullCommand)
text.chatStyle.chatHoverEvent =
@@ -252,13 +313,30 @@ object LorenzUtils {
Minecraft.getMinecraft().thePlayer.addChatMessage(text)
}
- fun hoverableChat(message: String, hover: List<String>, command: String? = null) {
- val text = ChatComponentText(message)
+ /**
+ * Sends a message to the user that they can click and run a command
+ * @param message The message to be sent
+ * @param hover The message to be shown when the message is hovered
+ * @param command The command to be executed when the message is clicked
+ * @param prefix Whether to prefix the message with the chat prefix, default true
+ * @param prefixColor Color that the prefix should be, default yellow (§e)
+ *
+ * @see CHAT_PREFIX
+ */
+ fun hoverableChat(
+ message: String,
+ hover: List<String>,
+ command: String? = null,
+ prefix: Boolean = true,
+ prefixColor: String = "§e"
+ ) {
+ val msgPrefix = if (prefix) prefixColor + CHAT_PREFIX else ""
+ val text = ChatComponentText(msgPrefix + message)
text.chatStyle.chatHoverEvent =
HoverEvent(HoverEvent.Action.SHOW_TEXT, ChatComponentText(hover.joinToString("\n")))
- if (command != null) {
- text.chatStyle.chatClickEvent = ClickEvent(ClickEvent.Action.RUN_COMMAND, "/${command.removePrefix("/")}")
+ command?.let {
+ text.chatStyle.chatClickEvent = ClickEvent(ClickEvent.Action.RUN_COMMAND, "/${it.removePrefix("/")}")
}
Minecraft.getMinecraft().thePlayer.addChatMessage(text)
@@ -333,22 +411,29 @@ object LorenzUtils {
isCurrent: (T) -> Boolean,
crossinline onChange: (T) -> Unit,
) {
- add(buildList {
- add(prefix)
- for (entry in enumValues<T>()) {
- val display = getName(entry)
- if (isCurrent(entry)) {
- add("§a[$display]")
- } else {
- add("§e[")
- add(Renderable.link("§e$display") {
- onChange(entry)
- })
- add("§e]")
- }
- add(" ")
+ add(buildSelector<T>(prefix, getName, isCurrent, onChange))
+ }
+
+ inline fun <reified T : Enum<T>> buildSelector(
+ prefix: String,
+ getName: (T) -> String,
+ isCurrent: (T) -> Boolean,
+ crossinline onChange: (T) -> Unit
+ ) = buildList {
+ add(prefix)
+ for (entry in enumValues<T>()) {
+ val display = getName(entry)
+ if (isCurrent(entry)) {
+ add("§a[$display]")
+ } else {
+ add("§e[")
+ add(Renderable.link("§e$display") {
+ onChange(entry)
+ })
+ add("§e]")
}
- })
+ add(" ")
+ }
}
inline fun MutableList<List<Any>>.addButton(
@@ -404,10 +489,12 @@ object LorenzUtils {
}
}
- fun List<String>.nextAfter(after: String, skip: Int = 1): String? {
+ 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
for (line in this) {
- if (line == after) {
+ if (after(line)) {
missing = skip - 1
continue
}
@@ -426,13 +513,11 @@ object LorenzUtils {
val tileSign = (this as AccessorGuiEditSign).tileSign
return (tileSign.signText[1].unformattedText.removeColor() == "^^^^^^"
- && tileSign.signText[2].unformattedText.removeColor() == "Set your"
- && tileSign.signText[3].unformattedText.removeColor() == "speed cap!")
+ && tileSign.signText[2].unformattedText.removeColor() == "Set your"
+ && tileSign.signText[3].unformattedText.removeColor() == "speed cap!")
}
- fun inIsland(island: IslandType) = inSkyBlock && (skyBlockIsland == island || island == IslandType.CATACOMBS && inDungeons)
-
- fun IslandType.isInIsland() = inIsland(this)
+ fun IslandType.isInIsland() = inSkyBlock && (skyBlockIsland == this || this == IslandType.CATACOMBS && inDungeons)
fun <K> MutableMap<K, Int>.addOrPut(key: K, number: Int): Int {
val currentValue = this[key] ?: 0
@@ -529,5 +614,15 @@ object LorenzUtils {
TitleManager.sendTitle(text, duration, height)
}
+ @Deprecated("Dont use this approach at all. check with regex or equals instead.", ReplaceWith("Regex or equals"))
fun Iterable<String>.anyContains(element: String) = any { it.contains(element) }
+
+ inline fun <reified T : Enum<T>> enumValueOfOrNull(name: String): T? {
+ val enums = enumValues<T>()
+ return enums.firstOrNull { it.name == name }
+ }
+
+ 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'")
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt
index 339a16efc..fd38fd441 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt
@@ -130,6 +130,8 @@ data class LorenzVec(
return LorenzVec(scalar * x, scalar * y, scalar * z)
}
+ fun axisAlignedTo(other: LorenzVec) = AxisAlignedBB(x, y, z, other.x, other.y, other.z)
+
companion object {
fun getFromYawPitch(yaw: Double, pitch: Double): LorenzVec {
val yaw: Double = (yaw + 90) * Math.PI / 180
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/MinecraftConsoleFilter.kt b/src/main/java/at/hannibal2/skyhanni/utils/MinecraftConsoleFilter.kt
index ee373d6b1..3aa432cde 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/MinecraftConsoleFilter.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/MinecraftConsoleFilter.kt
@@ -73,9 +73,9 @@ class MinecraftConsoleFilter(private val loggerConfigName: String) : Filter {
}
}
if (loggerName == "AsmHelper" && filterConfig.filterAmsHelperTransformer) {
- if (formattedMessage.startsWith("Transforming class ")) {
- filterConsole("AsmHelper Transforming")
- return Filter.Result.DENY
+ if (formattedMessage.startsWith("Transforming class ")) {
+ filterConsole("AsmHelper Transforming")
+ return Filter.Result.DENY
}
if (filterConfig.filterAsmHelperApplying && formattedMessage.startsWith("Applying AsmWriter ModifyWriter")) {
filterConsole("AsmHelper Applying AsmWriter")
@@ -118,7 +118,7 @@ class MinecraftConsoleFilter(private val loggerConfigName: String) : Filter {
}
}
- if (thrown != null && filterConfig.filterScoreboardErrors) {
+ if (thrown != null && filterConfig.filterScoreboardErrors) {
val cause = thrown.cause
if (cause != null && cause.stackTrace.isNotEmpty()) {
val first = cause.stackTrace[0]
@@ -241,13 +241,25 @@ class MinecraftConsoleFilter(private val loggerConfigName: String) : Filter {
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
event.move(3, "dev.printUnfilteredDebugs", "dev.minecraftConsoles.printUnfilteredDebugs")
event.move(3, "dev.logUnfilteredFile", "dev.minecraftConsoles.logUnfilteredFile")
- event.move(3, "dev.printUnfilteredDebugsOutsideSkyBlock", "dev.minecraftConsoles.printUnfilteredDebugsOutsideSkyBlock")
+ event.move(
+ 3,
+ "dev.printUnfilteredDebugsOutsideSkyBlock",
+ "dev.minecraftConsoles.printUnfilteredDebugsOutsideSkyBlock"
+ )
event.move(3, "dev.printFilteredReason", "dev.minecraftConsoles.printFilteredReason")
event.move(3, "dev.filterChat", "dev.minecraftConsoles.consoleFilter.filterChat")
event.move(3, "dev.filterGrowBuffer", "dev.minecraftConsoles.consoleFilter.filterGrowBuffer")
event.move(3, "dev.filterUnknownSound", "dev.minecraftConsoles.consoleFilter.filterUnknownSound")
- event.move(3, "dev.filterParticleVillagerHappy", "dev.minecraftConsoles.consoleFilter.filterParticleVillagerHappy")
- event.move(3, "dev.filterAmsHelperTransformer", "dev.minecraftConsoles.consoleFilter.filterAmsHelperTransformer")
+ event.move(
+ 3,
+ "dev.filterParticleVillagerHappy",
+ "dev.minecraftConsoles.consoleFilter.filterParticleVillagerHappy"
+ )
+ event.move(
+ 3,
+ "dev.filterAmsHelperTransformer",
+ "dev.minecraftConsoles.consoleFilter.filterAmsHelperTransformer"
+ )
event.move(3, "dev.filterAsmHelperApplying", "dev.minecraftConsoles.consoleFilter.filterAsmHelperApplying")
event.move(3, "dev.filterBiomeIdBounds", "dev.minecraftConsoles.consoleFilter.filterBiomeIdBounds")
event.move(3, "dev.filterScoreboardErrors", "dev.minecraftConsoles.consoleFilter.filterScoreboardErrors")
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
index 3fa8a09ad..007d9f1d5 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
@@ -185,8 +185,8 @@ object NEUItems {
ErrorManager.logError(
IllegalStateException("Something went wrong!"),
"Encountered an error getting the item for §7$this§c. " +
- "This may be because your NEU repo is outdated. Please ask in the SkyHanni " +
- "Discord if this is the case"
+ "This may be because your NEU repo is outdated. Please ask in the SkyHanni " +
+ "Discord if this is the case"
)
fallbackItem
}
@@ -233,9 +233,11 @@ object NEUItems {
return multiplierCache[internalName]!!
}
if (tryCount == 10) {
- val message = "Error reading getMultiplier for item '$internalName'"
- Error(message).printStackTrace()
- LorenzUtils.error(message)
+ ErrorManager.logErrorStateWithData(
+ "Cound not load recipe data.",
+ "Failed to find item multiplier",
+ "internalName" to internalName
+ )
return Pair(internalName, 1)
}
for (recipe in getRecipes(internalName)) {
@@ -310,8 +312,8 @@ object NEUItems {
val name = group("name").trim { it <= ' ' }
val ultimate = group("format").lowercase().contains("§l")
((if (ultimate && name != "Ultimate Wise") "ULTIMATE_" else "")
- + turboCheck(name).replace(" ", "_").replace("-", "_").uppercase()
- + ";" + group("level").romanToDecimal())
+ + turboCheck(name).replace(" ", "_").replace("-", "_").uppercase()
+ + ";" + group("level").romanToDecimal())
}
//Uses NEU
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NEUVersionCheck.kt b/src/main/java/at/hannibal2/skyhanni/utils/NEUVersionCheck.kt
index a1a35b9d8..f05f4bd0b 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/NEUVersionCheck.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/NEUVersionCheck.kt
@@ -19,12 +19,10 @@ object NEUVersionCheck {
} catch (e: Throwable) {
neuWarning(
"NotEnoughUpdates is missing!\n" +
- "SkyHanni requires the latest version of NotEnoughUpdates to work.\n" +
- "You currently need NEU version 2.1.1-Alpha-19 or later.\n" +
- "NEU 2.1 is NOT the latest version.\n" +
- "It is ONLY in the #neu-alphas channel in the NEU discord\n" +
- "Or in the #neu-updates channel in the SkyHanni discord\n" +
- "Use these links to download the latest version:"
+ "SkyHanni requires the latest version of NotEnoughUpdates to work.\n" +
+ "You currently need NEU version 2.1.1-Pre-4 or later.\n" +
+ "NEU 2.1 is NOT the latest version.\n" +
+ "Use these links to download the latest version:"
)
return
}
@@ -39,12 +37,9 @@ object NEUVersionCheck {
}
neuWarning(
"NotEnoughUpdates is outdated!\n" +
- "You currently need NEU version 2.1.1-Alpha-19 or later.\n\n" +
- "NEU 2.1 is NOT the latest version.\n\n" +
- "NEU 2.1.1 is NOT on the NEU GitHub.\n\n" +
- "It is ONLY in the #neu-alphas channel in the NEU discord\n" +
- "Or in the #neu-updates channel in the SkyHanni discord\n" +
- "Use these links to download the latest version:"
+ "You currently need NEU version 2.1.1-Pre-4 or later.\n" +
+ "NEU 2.1 is NOT the latest version.\n" +
+ "Use these links to download the latest version:"
)
}
@@ -54,6 +49,7 @@ object NEUVersionCheck {
Pair("Join SkyHanni Discord", "https://discord.com/invite/skyhanni-997079228510117908"),
Pair("Open SkyHanni GitHub", "https://github.com/hannibal002/SkyHanni"),
Pair("Join NEU Discord", "https://discord.gg/moulberry"),
+ Pair("Download Pre-4", "https://github.com/NotEnoughUpdates/NotEnoughUpdates/releases/tag/v2.1.1-pre4"),
)
closeMinecraft()
}
@@ -117,4 +113,4 @@ object NEUVersionCheck {
FMLCommonHandler.instance().handleExit(-1)
FMLCommonHandler.instance().expectServerStopped()
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt b/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt
index 3ad9e2da7..41e5f4923 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt
@@ -163,12 +163,10 @@ object NumberUtil {
} else romanSymbols[l] + (this - l).toRoman()
}
- private fun processDecimal(decimal: Int, lastNumber: Int, lastDecimal: Int): Int {
- return if (lastNumber > decimal) {
- lastDecimal - decimal
- } else {
- lastDecimal + decimal
- }
+ private fun processDecimal(decimal: Int, lastNumber: Int, lastDecimal: Int) = if (lastNumber > decimal) {
+ lastDecimal - decimal
+ } else {
+ lastDecimal + decimal
}
val pattern = "^[0-9]*$".toPattern()
@@ -189,16 +187,23 @@ object NumberUtil {
}
fun String.formatNumber(): Long {
- var text = replace(",", "")
+ var text = lowercase().replace(",", "")
val multiplier = if (text.endsWith("k")) {
text = text.substring(0, text.length - 1)
- 1_000
+ 1_000.0
} else if (text.endsWith("m")) {
text = text.substring(0, text.length - 1)
- 1_000_000
- } else 1
+ 1.milion
+ } else if (text.endsWith("b")) {
+ text = text.substring(0, text.length - 1)
+ 1.bilion
+ } else 1.0
val d = text.toDouble()
return (d * multiplier).toLong()
}
-} \ No newline at end of file
+
+ val Int.milion get() = this * 1_000_000.0
+ private val Int.bilion get() = this * 1_000_000_000.0
+ val Double.milion get() = (this * 1_000_000.0).toLong()
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt
index b083b2d3b..1f28effae 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt
@@ -1,5 +1,6 @@
package at.hannibal2.skyhanni.utils
+import at.hannibal2.skyhanni.test.command.ErrorManager
import java.awt.Desktop
import java.io.IOException
import java.net.URI
@@ -12,12 +13,11 @@ object OSUtils {
try {
Desktop.getDesktop().browse(URI(url))
} catch (e: IOException) {
- e.printStackTrace()
- LorenzUtils.error("[SkyHanni] Error opening website: $url!")
+ ErrorManager.logError(e, "Error opening website: $url")
}
} else {
copyToClipboard(url)
- LorenzUtils.warning("[SkyHanni] Web browser is not supported! Copied url to clipboard.")
+ LorenzUtils.error("Web browser is not supported! Copied url to clipboard.")
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ParkourHelper.kt b/src/main/java/at/hannibal2/skyhanni/utils/ParkourHelper.kt
index c9903ffc2..68f7a0d49 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/ParkourHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/ParkourHelper.kt
@@ -53,7 +53,9 @@ class ParkourHelper(
if (visible) {
for ((index, location) in locations.withIndex()) {
- if (location.offsetCenter().distanceToPlayer() < detectionRange && Minecraft.getMinecraft().thePlayer.onGround) {
+ val onGround = Minecraft.getMinecraft().thePlayer.onGround
+ val closeEnough = location.offsetCenter().distanceToPlayer() < detectionRange
+ if (closeEnough && onGround) {
current = index
}
}
@@ -146,4 +148,4 @@ class ParkourHelper(
private fun colorForIndex(index: Int) = if (rainbowColor) {
RenderUtils.chromaColor(4.seconds, offset = -index / 12f, brightness = 0.7f)
} else monochromeColor
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt
index 4a5754b6c..03f552e7a 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt
@@ -303,7 +303,6 @@ object RenderUtils {
val z =
pos.z - player.lastTickPosZ + (pos.z - player.posZ - (pos.z - player.lastTickPosZ)) * partialTicks
-
//7 – 25
val translate = LorenzVec(x, y, z)
@@ -353,7 +352,6 @@ object RenderUtils {
return lastValue + (currentValue - lastValue) * multiplier
}
-
fun Position.transform(): Pair<Int, Int> {
GlStateManager.translate(getAbsX().toFloat(), getAbsY().toFloat(), 0F)
GlStateManager.scale(effectiveScale, effectiveScale, 1F)
@@ -365,22 +363,28 @@ object RenderUtils {
fun Position.renderString(string: String?, offsetX: Int = 0, offsetY: Int = 0, posLabel: String) {
if (string == null) return
if (string == "") return
- val x = renderString0(string, offsetX, offsetY)
+ val x = renderString0(string, offsetX, offsetY, isCenter)
GuiEditManager.add(this, posLabel, x, 10)
}
- private fun Position.renderString0(string: String?, offsetX: Int = 0, offsetY: Int = 0): Int {
+ private fun Position.renderString0(string: String?, offsetX: Int = 0, offsetY: Int = 0, centered: Boolean): Int {
val display = "§f$string"
GlStateManager.pushMatrix()
transform()
val minecraft = Minecraft.getMinecraft()
val renderer = minecraft.renderManager.fontRenderer
- val x = offsetX
- val y = offsetY
+ GlStateManager.translate(offsetX + 1.0, offsetY + 1.0, 0.0)
- GlStateManager.translate(x + 1.0, y + 1.0, 0.0)
- renderer.drawStringWithShadow(display, 0f, 0f, 0)
+ if (centered) {
+ val strLen: Int = renderer.getStringWidth(string)
+ val x2 = offsetX - strLen / 2f
+ GL11.glTranslatef(x2, 0f, 0f)
+ renderer.drawStringWithShadow(display, 0f, 0f, 0)
+ GL11.glTranslatef(-x2, 0f, 0f)
+ } else {
+ renderer.drawStringWithShadow(display, 0f, 0f, 0)
+ }
GlStateManager.popMatrix()
@@ -394,7 +398,7 @@ object RenderUtils {
var offsetY = 0
var longestX = 0
for (s in list) {
- val x = renderString0(s, offsetY = offsetY)
+ val x = renderString0(s, offsetY = offsetY, centered = false)
if (x > longestX) {
longestX = x
}
@@ -756,7 +760,6 @@ object RenderUtils {
return LorenzVec(x, y, z)
}
-
fun drawFilledBoundingBox(aabb: AxisAlignedBB, c: Color, alphaMultiplier: Float = 1f) {
GlStateManager.enableBlend()
GlStateManager.disableLighting()
@@ -927,7 +930,12 @@ object RenderUtils {
GlStateManager.disableBlend()
}
- fun LorenzRenderWorldEvent.outlineTopFace(boundingBox: AxisAlignedBB, lineWidth: Int, colour: Color, depth: Boolean) {
+ fun LorenzRenderWorldEvent.outlineTopFace(
+ boundingBox: AxisAlignedBB,
+ lineWidth: Int,
+ colour: Color,
+ depth: Boolean
+ ) {
val cornerOne = LorenzVec(boundingBox.minX, boundingBox.maxY, boundingBox.minZ)
val cornerTwo = LorenzVec(boundingBox.minX, boundingBox.maxY, boundingBox.maxZ)
val cornerThree = LorenzVec(boundingBox.maxX, boundingBox.maxY, boundingBox.maxZ)
@@ -1021,4 +1029,4 @@ object RenderUtils {
GlStateManager.enableLighting()
GlStateManager.enableDepth()
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt b/src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt
index e79599cae..3e30f300c 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt
@@ -7,18 +7,23 @@ import kotlin.time.Duration.Companion.milliseconds
@JvmInline
value class SimpleTimeMark(private val millis: Long) {
+
operator fun minus(other: SimpleTimeMark) =
(millis - other.millis).milliseconds
operator fun plus(other: Duration) =
SimpleTimeMark(millis + other.inWholeMilliseconds)
- fun passedSince() = if (millis == 0L) Duration.INFINITE else now() - this
+ operator fun minus(other: Duration) = plus(-other)
+
+ fun passedSince() = now() - this
fun timeUntil() = -passedSince()
fun isInPast() = timeUntil().isNegative()
+ fun isFarPast() = millis == 0L
+
override fun toString(): String {
if (millis == 0L) return "The Far Past"
return Instant.ofEpochMilli(millis).toString()
@@ -33,4 +38,4 @@ value class SimpleTimeMark(private val millis: Long) {
fun Long.asTimeMark() = SimpleTimeMark(this)
fun SkyBlockTime.asTimeMark() = SimpleTimeMark(toMillis())
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt
index 7f6cc7623..9f65a71f1 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt
@@ -26,6 +26,8 @@ object SkyBlockItemModifierUtils {
fun ItemStack.getPolarvoidBookCount() = getAttributeInt("polarvoid")
+ fun ItemStack.getBookwormBookCount() = getAttributeInt("bookworm_books")
+
fun ItemStack.getCultivatingCounter() = getAttributeLong("farmed_cultivating")
fun ItemStack.getHoeCounter() = getAttributeLong("mined_crops")
@@ -117,6 +119,8 @@ object SkyBlockItemModifierUtils {
fun ItemStack.getArmorDye() = getAttributeString("dye_item")?.asInternalName()
+ fun ItemStack.getFungiCutterMode() = getAttributeString("fungi_cutter_mode")
+
fun ItemStack.getRune(): NEUInternalName? {
val runesMap = getExtraAttributes()?.getCompoundTag("runes") ?: return null
val runesList = runesMap.keySet.associateWith { runesMap.getInteger(it) }.toList()
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/SoundUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/SoundUtils.kt
index d2403d4c6..c9892a9bf 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/SoundUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/SoundUtils.kt
@@ -9,7 +9,7 @@ import net.minecraft.util.ResourceLocation
object SoundUtils {
private val beepSound by lazy { createSound("random.orb", 1f) }
private val clickSound by lazy { createSound("gui.button.press", 1f) }
- private val errorSound by lazy {createSound("mob.endermen.portal", 0f)}
+ private val errorSound by lazy { createSound("mob.endermen.portal", 0f) }
val centuryActiveTimerAlert by lazy { createSound("skyhanni:centurytimer.active", 1f) }
fun ISound.playSound() {
@@ -58,7 +58,7 @@ object SoundUtils {
fun command(args: Array<String>) {
if (args.isEmpty()) {
- LorenzUtils.chat("§c[SkyHanni] Specify a sound effect to test")
+ LorenzUtils.userError("Specify a sound effect to test")
return
}
@@ -72,4 +72,4 @@ object SoundUtils {
fun playErrorSound() {
errorSound.playSound()
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt
index 66eb0faad..dd114d8fd 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt
@@ -2,6 +2,7 @@ package at.hannibal2.skyhanni.utils
import at.hannibal2.skyhanni.mixins.transformers.AccessorChatComponentText
import at.hannibal2.skyhanni.utils.GuiRenderUtils.darkenColor
+import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.GuiUtilRenderComponents
import net.minecraft.util.ChatComponentText
@@ -17,7 +18,8 @@ import java.util.regex.Pattern
object StringUtils {
// TODO USE SH-REPO
private val playerChatPattern = "(?<important>.*?)(?:§[f7r])*: .*".toPattern()
- private val chatUsernamePattern = "^(?:§\\w\\[§\\w\\d+§\\w] )?(?:(?:§\\w)+\\S )?(?<rankedName>(?:§\\w\\[\\w.+] )?(?:§\\w)?(?<username>\\w+))(?: (?:§\\w)?\\[.+?])?".toPattern()
+ private val chatUsernamePattern =
+ "^(?:§\\w\\[§\\w\\d+§\\w] )?(?:(?:§\\w)+\\S )?(?<rankedName>(?:§\\w\\[\\w.+] )?(?:§\\w)?(?<username>\\w+))(?: (?:§\\w)?\\[.+?])?".toPattern()
private val whiteSpaceResetPattern = "^(?:\\s|§r)*|(?:\\s|§r)*$".toPattern()
private val whiteSpacePattern = "^\\s*|\\s*$".toPattern()
private val resetPattern = "(?i)§R".toPattern()
@@ -71,6 +73,7 @@ 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 =
@@ -89,6 +92,15 @@ object StringUtils {
}
}
+ inline fun <T> List<Pattern>.matchMatchers(text: String, consumer: Matcher.() -> T): T? {
+ for (pattern in iterator()) {
+ pattern.matchMatcher<T>(text) {
+ return consumer()
+ }
+ }
+ return null
+ }
+
fun getColor(string: String, default: Int, darker: Boolean = true): Int {
val stringPattern = "§[0123456789abcdef].*".toPattern()
@@ -138,7 +150,7 @@ object StringUtils {
}
fun optionalPlural(number: Int, singular: String, plural: String) =
- "$number " + if (number == 1) singular else plural
+ "${number.addSeparators()} " + 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'
@@ -235,4 +247,6 @@ object StringUtils {
fun String.convertToFormatted(): String {
return this.replace("&&", "§")
}
-} \ No newline at end of file
+
+ fun Pattern.matches(string: String) = matcher(string).matches()
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/TabListData.kt b/src/main/java/at/hannibal2/skyhanni/utils/TabListData.kt
index 252d974ca..fe07509be 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/TabListData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/TabListData.kt
@@ -1,10 +1,16 @@
package at.hannibal2.skyhanni.utils
+import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.TabListUpdateEvent
import at.hannibal2.skyhanni.mixins.hooks.tabListGuard
+import at.hannibal2.skyhanni.mixins.transformers.AccessorGuiPlayerTabOverlay
+import at.hannibal2.skyhanni.utils.LorenzUtils.conditionalTransform
+import at.hannibal2.skyhanni.utils.LorenzUtils.transformIf
+import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import com.google.common.collect.ComparisonChain
import com.google.common.collect.Ordering
+import kotlinx.coroutines.launch
import net.minecraft.client.Minecraft
import net.minecraft.client.network.NetworkPlayerInfo
import net.minecraft.world.WorldSettings
@@ -16,9 +22,43 @@ class TabListData {
companion object {
private var cache = emptyList<String>()
+ private var debugCache: List<String>? = null
// TODO replace with TabListUpdateEvent
- fun getTabList() = cache
+ fun getTabList() = debugCache ?: cache
+
+ fun toggleDebugCommand() {
+ if (debugCache != null) {
+ LorenzUtils.chat("Disabled tab list debug.")
+ debugCache = null
+ return
+ }
+ SkyHanniMod.coroutineScope.launch {
+ val clipboard = OSUtils.readFromClipboard() ?: return@launch
+ debugCache = clipboard.lines()
+ LorenzUtils.chat("Enabled tab list debug with your clipboard.")
+ }
+ }
+
+ fun copyCommand(args: Array<String>) {
+ if (debugCache != null) {
+ LorenzUtils.clickableChat("Tab list debug is enabled!", "shdebugtablist")
+ return
+ }
+
+ val resultList = mutableListOf<String>()
+ val noColor = args.size == 1 && args[0] == "true"
+ for (line in getTabList()) {
+ val tabListLine = line.transformIf({ noColor }) { removeColor() }
+ if (tabListLine != "") resultList.add("'$tabListLine'")
+ }
+ val tabList = Minecraft.getMinecraft().ingameGUI.tabList as AccessorGuiPlayerTabOverlay
+ val tabHeader = tabList.header_skyhanni.conditionalTransform(noColor, { unformattedText }, { formattedText })
+ val tabFooter = tabList.footer_skyhanni.conditionalTransform(noColor, { unformattedText }, { formattedText })
+ val string = "Header:\n\n$tabHeader\n\nBody:\n\n${resultList.joinToString("\n")}\n\nFooter:\n\n$tabFooter"
+ OSUtils.copyToClipboard(string)
+ LorenzUtils.chat("Tab list copied into the clipboard!")
+ }
}
private val playerOrdering = Ordering.from(PlayerComparator())
@@ -60,7 +100,7 @@ class TabListData {
val tabList = readTabList() ?: return
if (cache != tabList) {
cache = tabList
- TabListUpdateEvent(cache).postAndCatch()
+ TabListUpdateEvent(getTabList()).postAndCatch()
}
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt
index 3a32b3de6..5bf6bfcf0 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt
@@ -4,6 +4,8 @@ import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import io.github.moulberry.notenoughupdates.util.SkyBlockTime
import kotlin.time.Duration
+import kotlin.time.DurationUnit
+import kotlin.time.toDuration
object TimeUtils {
private val pattern =
@@ -73,8 +75,10 @@ object TimeUtils {
return builder.toString().trim()
}
- // TODO: use kotlin Duration
- fun getMillis(string: String) = getMillis_(string.replace("m", "m ").replace(" ", " ").trim())
+ @Deprecated("Do no longer use long for time", ReplaceWith("getDuration()"))
+ fun getMillis(string: String) = getDuration(string).inWholeMilliseconds
+
+ fun getDuration(string: String) = getMillis_(string.replace("m", "m ").replace(" ", " ").trim())
private fun getMillis_(string: String) = pattern.matchMatcher(string.lowercase().trim()) {
val years = group("y")?.toLong() ?: 0L
@@ -90,10 +94,10 @@ object TimeUtils {
millis += days * 24 * 60 * 60 * 1000
millis += (years * 365.25 * 24 * 60 * 60 * 1000).toLong()
- millis
+ millis.toDuration(DurationUnit.MILLISECONDS)
} ?: tryAlternativeFormat(string)
- private fun tryAlternativeFormat(string: String): Long {
+ private fun tryAlternativeFormat(string: String): Duration {
val split = string.split(":")
return when (split.size) {
3 -> {
@@ -116,7 +120,7 @@ object TimeUtils {
else -> {
throw RuntimeException("Invalid format: '$string'")
}
- }.toLong()
+ }.toLong().toDuration(DurationUnit.MILLISECONDS)
}
fun SkyBlockTime.formatted(): String {
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/Timer.kt b/src/main/java/at/hannibal2/skyhanni/utils/Timer.kt
index 55ea90b52..2a6d1f5ab 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/Timer.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/Timer.kt
@@ -11,7 +11,7 @@ class Timer(
private var started: SimpleTimeMark = SimpleTimeMark.now(),
startPaused: Boolean = false
-): Comparable<Timer> {
+) : Comparable<Timer> {
@Expose
private var paused: SimpleTimeMark? = null
@@ -40,4 +40,4 @@ class Timer(
override fun compareTo(other: Timer): Int = remaining.compareTo(other.remaining)
-} \ 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/utils/jsonobjects/ContributorListJson.java
index 6ab663941..8e5648f5e 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ContributorListJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ContributorListJson.java
@@ -1,4 +1,5 @@
package at.hannibal2.skyhanni.utils.jsonobjects;
+
import com.google.gson.annotations.Expose;
import java.util.List;
@@ -6,4 +7,4 @@ import java.util.List;
public class ContributorListJson {
@Expose
public List<String> usernames;
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/GardenJson.java b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/GardenJson.java
index 87a80d391..7bc9cf7fa 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/GardenJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/GardenJson.java
@@ -1,7 +1,10 @@
package at.hannibal2.skyhanni.utils.jsonobjects;
import at.hannibal2.skyhanni.features.garden.CropType;
+import at.hannibal2.skyhanni.utils.LorenzRarity;
+import at.hannibal2.skyhanni.utils.LorenzVec;
import com.google.gson.annotations.Expose;
+import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
@@ -14,6 +17,9 @@ public class GardenJson {
public Map<CropType, List<Integer>> crop_milestones;
@Expose
+ public Map<String, Boolean> crop_milestone_community_help;
+
+ @Expose
public Map<String, GardenVisitor> visitors;
@Expose
@@ -24,9 +30,29 @@ public class GardenJson {
public static class GardenVisitor {
@Expose
- public String rarity;
+ public LorenzRarity rarity;
+
+ @Expose
+ public LorenzRarity new_rarity;
+
+ @Nullable
+ @Expose
+ public LorenzVec position;
+
+ /**
+ * Formatted as follows:
+ * - If this visitor is a player, get the encoded skin value
+ * - If this visitor is a mob, get their mob class name
+ */
+ @Nullable
+ @Expose
+ public String skinOrType;
+
+ @Nullable
+ @Expose
+ public String mode;
@Expose
public List<String> need_items;
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/JacobContestsJson.java b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/JacobContestsJson.java
new file mode 100644
index 000000000..87d1e9a22
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/JacobContestsJson.java
@@ -0,0 +1,13 @@
+package at.hannibal2.skyhanni.utils.jsonobjects;
+
+import at.hannibal2.skyhanni.features.garden.CropType;
+import com.google.gson.annotations.Expose;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class JacobContestsJson {
+ @Expose
+ public Map<Long, 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/utils/jsonobjects/KnownFeaturesJson.java
new file mode 100644
index 000000000..bd5048cfb
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/KnownFeaturesJson.java
@@ -0,0 +1,12 @@
+package at.hannibal2.skyhanni.utils.jsonobjects;
+
+import com.google.gson.annotations.Expose;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class KnownFeaturesJson {
+ @Expose
+ public Map<String, List<String>> knownFeatures = new HashMap<>();
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/LocationFixJson.java b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/LocationFixJson.java
new file mode 100644
index 000000000..802627e7a
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/LocationFixJson.java
@@ -0,0 +1,27 @@
+package at.hannibal2.skyhanni.utils.jsonobjects;
+
+import at.hannibal2.skyhanni.utils.LorenzVec;
+import com.google.gson.annotations.Expose;
+
+import java.util.Map;
+
+public class LocationFixJson {
+
+ @Expose
+ public Map<String, LocationFix> locationFixes;
+
+ public static class LocationFix {
+ @Expose
+ public LorenzVec a;
+
+ @Expose
+ public LorenzVec b;
+
+ @Expose
+ public String island_name;
+
+ @Expose
+ public String real_location;
+ }
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/MayorJson.java b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/MayorJson.java
index bc877658a..d2173c74b 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/MayorJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/MayorJson.java
@@ -27,11 +27,11 @@ public class MayorJson {
@Override
public String toString() {
return "Candidate{" +
- "key='" + key + '\'' +
- ", name='" + name + '\'' +
- ", perks=" + perks +
- ", votes=" + votes +
- '}';
+ "key='" + key + '\'' +
+ ", name='" + name + '\'' +
+ ", perks=" + perks +
+ ", votes=" + votes +
+ '}';
}
}
@@ -62,9 +62,9 @@ public class MayorJson {
@Override
public String toString() {
return "Perk{" +
- "name='" + name + '\'' +
- ", description='" + description + '\'' +
- '}';
+ "name='" + name + '\'' +
+ ", description='" + description + '\'' +
+ '}';
}
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SeaCreatureJson.java b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SeaCreatureJson.java
index 52ed7f636..8053e87cb 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SeaCreatureJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SeaCreatureJson.java
@@ -9,7 +9,8 @@ import java.util.Map;
public class SeaCreatureJson {
- public static Type TYPE = new TypeToken<Map<String, SeaCreatureJson.Variant>>(){}.getType();
+ public static Type TYPE = new TypeToken<Map<String, SeaCreatureJson.Variant>>() {
+ }.getType();
public static class Variant {
@Expose
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/TabListJson.java b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/TabListJson.java
new file mode 100644
index 000000000..03c256256
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/TabListJson.java
@@ -0,0 +1,11 @@
+package at.hannibal2.skyhanni.utils.jsonobjects;
+
+import com.google.gson.annotations.Expose;
+
+import java.util.List;
+
+public class TabListJson {
+
+ @Expose
+ public List<String> sun_moon_symbols;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt b/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt
index 2a3321abc..9367e5ee1 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt
@@ -21,7 +21,7 @@ interface Renderable {
val height: Int
fun isHovered(posX: Int, posY: Int) = currentRenderPassMousePosition?.let { (x, y) ->
x in (posX..posX + width)
- && y in (posY..posY + height) // TODO: adjust for variable height?
+ && y in (posY..posY + height) // TODO: adjust for variable height?
} ?: false
/**
@@ -35,7 +35,7 @@ interface Renderable {
val list = mutableMapOf<Pair<Int, Int>, List<Int>>()
var currentRenderPassMousePosition: Pair<Int, Int>? = null
- private set
+ set
fun <T> withMousePosition(posX: Int, posY: Int, block: () -> T): T {
val last = currentRenderPassMousePosition
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/shader/Shader.kt b/src/main/java/at/hannibal2/skyhanni/utils/shader/Shader.kt
index f198f7e7a..7fb13ab86 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/shader/Shader.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/shader/Shader.kt
@@ -30,7 +30,7 @@ abstract class Shader(vertex: String, fragment: String) {
if (linkStatus == GL11.GL_FALSE) {
LorenzUtils.consoleLog(
"Error occurred when linking program with Vertex Shader: $vertex and Fragment Shader: $fragment : " +
- StringUtils.trim(ShaderHelper.glGetProgramInfoLog(shaderProgram, 1024))
+ StringUtils.trim(ShaderHelper.glGetProgramInfoLog(shaderProgram, 1024))
)
}
@@ -52,4 +52,4 @@ abstract class Shader(vertex: String, fragment: String) {
fun <T> registerUniform(uniformType: Uniform.UniformType<T>, name: String, uniformValuesSupplier: Supplier<T>) {
uniforms.add(Uniform(this, uniformType, name, uniformValuesSupplier))
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderHelper.kt b/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderHelper.kt
index e554a4098..2576b4248 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderHelper.kt
@@ -1,7 +1,13 @@
package at.hannibal2.skyhanni.utils.shader
import at.hannibal2.skyhanni.utils.LorenzUtils
-import org.lwjgl.opengl.*
+import org.lwjgl.opengl.ARBFragmentShader
+import org.lwjgl.opengl.ARBShaderObjects
+import org.lwjgl.opengl.ARBVertexShader
+import org.lwjgl.opengl.ContextCapabilities
+import org.lwjgl.opengl.GL11
+import org.lwjgl.opengl.GL20
+import org.lwjgl.opengl.GLContext
/**
* Class to check shaders support, OpenGL capabilities, and shader helper functions
@@ -27,9 +33,9 @@ class ShaderHelper {
// Check OpenGL 2.0 Capabilities
val openGL20supported = capabilities.OpenGL20
SHADERS_SUPPORTED = openGL20supported ||
- capabilities.GL_ARB_vertex_shader &&
- capabilities.GL_ARB_fragment_shader &&
- capabilities.GL_ARB_shader_objects
+ capabilities.GL_ARB_vertex_shader &&
+ capabilities.GL_ARB_fragment_shader &&
+ capabilities.GL_ARB_shader_objects
var log = "Shaders are"
if (!SHADERS_SUPPORTED) log += " not"
@@ -67,12 +73,18 @@ class ShaderHelper {
if (USING_ARB_SHADERS) ARBShaderObjects.glLinkProgramARB(program) else GL20.glLinkProgram(program)
}
- fun glGetProgramInfoLog(program: Int, maxLength: Int) : String {
- return if (USING_ARB_SHADERS) ARBShaderObjects.glGetInfoLogARB(program, maxLength) else GL20.glGetProgramInfoLog(program, maxLength)
+ fun glGetProgramInfoLog(program: Int, maxLength: Int): String {
+ return if (USING_ARB_SHADERS) ARBShaderObjects.glGetInfoLogARB(
+ program,
+ maxLength
+ ) else GL20.glGetProgramInfoLog(program, maxLength)
}
- fun glGetProgrami(program: Int, pname: Int) : Int {
- return if (USING_ARB_SHADERS) ARBShaderObjects.glGetObjectParameteriARB(program, pname) else GL20.glGetProgrami(program, pname)
+ fun glGetProgrami(program: Int, pname: Int): Int {
+ return if (USING_ARB_SHADERS) ARBShaderObjects.glGetObjectParameteriARB(
+ program,
+ pname
+ ) else GL20.glGetProgrami(program, pname)
}
fun glUseProgram(program: Int) {
@@ -80,27 +92,39 @@ class ShaderHelper {
}
fun glAttachShader(program: Int, shaderIn: Int) {
- if (USING_ARB_SHADERS) ARBShaderObjects.glAttachObjectARB(program, shaderIn) else GL20.glAttachShader(program, shaderIn)
+ if (USING_ARB_SHADERS) ARBShaderObjects.glAttachObjectARB(program, shaderIn) else GL20.glAttachShader(
+ program,
+ shaderIn
+ )
}
- fun glCreateShader(type: Int) : Int {
+ fun glCreateShader(type: Int): Int {
return if (USING_ARB_SHADERS) ARBShaderObjects.glCreateShaderObjectARB(type) else GL20.glCreateShader(type)
}
fun glShaderSource(shader: Int, source: CharSequence) {
- if (USING_ARB_SHADERS) ARBShaderObjects.glShaderSourceARB(shader, source) else GL20.glShaderSource(shader, source)
+ if (USING_ARB_SHADERS) ARBShaderObjects.glShaderSourceARB(shader, source) else GL20.glShaderSource(
+ shader,
+ source
+ )
}
fun glCompileShader(shader: Int) {
if (USING_ARB_SHADERS) ARBShaderObjects.glCompileShaderARB(shader) else GL20.glCompileShader(shader)
}
- fun glGetShaderi(shader: Int, pname: Int) : Int {
- return if (USING_ARB_SHADERS) ARBShaderObjects.glGetObjectParameteriARB(shader, pname) else GL20.glGetShaderi(shader, pname)
+ fun glGetShaderi(shader: Int, pname: Int): Int {
+ return if (USING_ARB_SHADERS) ARBShaderObjects.glGetObjectParameteriARB(
+ shader,
+ pname
+ ) else GL20.glGetShaderi(shader, pname)
}
- fun glGetShaderInfoLog(shader: Int, maxLength: Int) : String {
- return if (USING_ARB_SHADERS) ARBShaderObjects.glGetInfoLogARB(shader, maxLength) else GL20.glGetShaderInfoLog(shader, maxLength)
+ fun glGetShaderInfoLog(shader: Int, maxLength: Int): String {
+ return if (USING_ARB_SHADERS) ARBShaderObjects.glGetInfoLogARB(
+ shader,
+ maxLength
+ ) else GL20.glGetShaderInfoLog(shader, maxLength)
}
fun glDeleteShader(shader: Int) {
@@ -112,13 +136,21 @@ class ShaderHelper {
}
fun glUniform3f(location: Int, v0: Float, v1: Float, v2: Float) {
- if (USING_ARB_SHADERS) ARBShaderObjects.glUniform3fARB(location, v0, v1, v2) else GL20.glUniform3f(location, v0, v1, v2)
+ if (USING_ARB_SHADERS) ARBShaderObjects.glUniform3fARB(location, v0, v1, v2) else GL20.glUniform3f(
+ location,
+ v0,
+ v1,
+ v2
+ )
}
- fun glGetUniformLocation(program: Int, name: CharSequence) : Int {
- return if (USING_ARB_SHADERS) ARBShaderObjects.glGetUniformLocationARB(program, name) else GL20.glGetUniformLocation(program, name)
+ fun glGetUniformLocation(program: Int, name: CharSequence): Int {
+ return if (USING_ARB_SHADERS) ARBShaderObjects.glGetUniformLocationARB(
+ program,
+ name
+ ) else GL20.glGetUniformLocation(program, name)
}
fun areShadersSupported() = SHADERS_SUPPORTED
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderManager.kt b/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderManager.kt
index e7eb48f11..3dbec3c6e 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderManager.kt
@@ -21,7 +21,7 @@ object ShaderManager {
CHROMA(ChromaShader.INSTANCE);
companion object {
- fun getShaderInstance(shaderName: String) : Shader? = when (shaderName) {
+ fun getShaderInstance(shaderName: String): Shader? = when (shaderName) {
"chroma" -> CHROMA.shader
else -> {
null
@@ -58,7 +58,7 @@ object ShaderManager {
activeShader = null
}
- fun loadShader(type: ShaderType, fileName: String) : Int {
+ fun loadShader(type: ShaderType, fileName: String): Int {
val resourceLocation = ResourceLocation("skyhanni:shaders/$fileName${type.extension}")
val source = StringBuilder()
@@ -73,8 +73,10 @@ object ShaderManager {
ShaderHelper.glCompileShader(shaderID)
if (ShaderHelper.glGetShaderi(shaderID, ShaderHelper.GL_COMPILE_STATUS) == 0) {
- LorenzUtils.consoleLog("Error occurred when compiling shader $fileName${type.extension} : " +
- StringUtils.trim(ShaderHelper.glGetShaderInfoLog(shaderID, 1024)))
+ LorenzUtils.consoleLog(
+ "Error occurred when compiling shader $fileName${type.extension} : " +
+ StringUtils.trim(ShaderHelper.glGetShaderInfoLog(shaderID, 1024))
+ )
}
return shaderID
@@ -84,4 +86,4 @@ object ShaderManager {
enum class ShaderType(val extension: String, val shaderType: Int) {
VERTEX(".vsh", ShaderHelper.GL_VERTEX_SHADER),
FRAGMENT(".fsh", ShaderHelper.GL_FRAGMENT_SHADER)
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/shader/Uniform.kt b/src/main/java/at/hannibal2/skyhanni/utils/shader/Uniform.kt
index e87ea3b22..d57398ea4 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/shader/Uniform.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/shader/Uniform.kt
@@ -37,9 +37,10 @@ class Uniform<T>(
val values = newUniformValue as FloatArray
ShaderHelper.glUniform3f(uniformID, values[0], values[1], values[2])
}
+
UniformType.BOOL -> ShaderHelper.glUniform1f(uniformID, if (newUniformValue as Boolean) 1f else 0f)
}
previousUniformValue = newUniformValue
}
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt
new file mode 100644
index 000000000..f882a268e
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt
@@ -0,0 +1,133 @@
+package at.hannibal2.skyhanni.utils.tracker
+
+import at.hannibal2.skyhanni.config.Storage
+import at.hannibal2.skyhanni.config.core.config.Position
+import at.hannibal2.skyhanni.data.ProfileStorageData
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
+import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
+import at.hannibal2.skyhanni.utils.renderables.Renderable
+import net.minecraft.client.Minecraft
+import net.minecraft.client.gui.inventory.GuiInventory
+import kotlin.time.Duration.Companion.seconds
+
+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 val currentSessions = mutableMapOf<Storage.ProfileSpecific, Data>()
+ private var display = emptyList<List<Any>>()
+ private var sessionResetTime = SimpleTimeMark.farPast()
+ private var dirty = false
+
+ fun isInventoryOpen() = inventoryOpen
+
+ fun resetCommand(args: Array<String>, command: String) {
+ if (args.size == 1 && args[0].lowercase() == "confirm") {
+ reset(DisplayMode.TOTAL, "Reset total $name!")
+ return
+ }
+
+ LorenzUtils.clickableChat(
+ "Are you sure you want to reset your total $name? Click here to confirm.",
+ "$command confirm"
+ )
+ }
+
+ fun modify(modifyFunction: (Data) -> Unit) {
+ getSharedTracker()?.let {
+ it.modify(modifyFunction)
+ update()
+ }
+ }
+
+ fun renderDisplay(position: Position) {
+ val currentlyOpen = Minecraft.getMinecraft().currentScreen is GuiInventory
+ if (inventoryOpen != currentlyOpen) {
+ inventoryOpen = currentlyOpen
+ update()
+ }
+
+ if (dirty) {
+ display = getSharedTracker()?.let {
+ buildFinalDisplay(drawDisplay(it.get(displayMode)))
+ } ?: emptyList()
+ dirty = false
+ }
+
+ position.renderStringsAndItems(display, posLabel = name)
+ }
+
+ fun update() {
+ dirty = true
+ }
+
+ private fun buildFinalDisplay(rawList: List<List<Any>>) = rawList.toMutableList().also {
+ if (it.isEmpty()) return@also
+ if (inventoryOpen) {
+ it.add(1, buildDisplayModeView())
+ }
+ if (inventoryOpen && displayMode == DisplayMode.SESSION) {
+ it.addAsSingletonList(buildSessionResetButton())
+ }
+ }
+
+ private fun buildSessionResetButton() = Renderable.clickAndHover(
+ "§cReset session!",
+ listOf(
+ "§cThis will reset your",
+ "§ccurrent session of",
+ "§c$name"
+ ),
+ ) {
+ if (sessionResetTime.passedSince() > 3.seconds) {
+ reset(DisplayMode.SESSION, "Reset this session of $name!")
+ sessionResetTime = SimpleTimeMark.now()
+ }
+ }
+
+ private fun buildDisplayModeView() = LorenzUtils.buildSelector<DisplayMode>(
+ "§7Display Mode: ",
+ getName = { type -> type.displayName },
+ isCurrent = { it == displayMode },
+ onChange = {
+ displayMode = it
+ update()
+ }
+ )
+
+ private fun getSharedTracker() = ProfileStorageData.profileSpecific?.let {
+ SharedTracker(getStorage(it), currentSessions.getOrPut(it) { createNewSession() })
+ }
+
+ private fun reset(displayMode: DisplayMode, message: String) {
+ getSharedTracker()?.let {
+ it.get(displayMode).reset()
+ LorenzUtils.chat(message)
+ update()
+ }
+ }
+
+ class SharedTracker<Data : TrackerData>(private val total: Data, private val currentSession: Data) {
+ fun modify(modifyFunction: (Data) -> Unit) {
+ modifyFunction(total)
+ modifyFunction(currentSession)
+ }
+
+ fun get(displayMode: DisplayMode) = when (displayMode) {
+ DisplayMode.TOTAL -> total
+ DisplayMode.SESSION -> currentSession
+ }
+ }
+
+ enum class DisplayMode(val displayName: String) {
+ TOTAL("Total"),
+ SESSION("This Session"),
+ ;
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/tracker/TrackerData.kt b/src/main/java/at/hannibal2/skyhanni/utils/tracker/TrackerData.kt
new file mode 100644
index 000000000..3c4a8bbd0
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/tracker/TrackerData.kt
@@ -0,0 +1,5 @@
+package at.hannibal2.skyhanni.utils.tracker
+
+abstract class TrackerData {
+ abstract fun reset()
+}
diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info
index d920128ae..0e135af9d 100644
--- a/src/main/resources/mcmod.info
+++ b/src/main/resources/mcmod.info
@@ -1,16 +1,20 @@
[
- {
- "modid": "skyhanni",
- "name": "SkyHanni",
- "description": "Hypixel SkyBlock Mod",
- "version": "${version}",
- "mcversion": "1.8.9",
- "url": "",
- "updateUrl": "",
- "authorList": ["hannibal2"],
- "credits": "Alea1337 & Eisengolem",
- "logoFile": "",
- "screenshots": [],
- "dependencies": ["NotEnoughUpdates"]
- }
+ {
+ "modid": "skyhanni",
+ "name": "SkyHanni",
+ "description": "Hypixel SkyBlock Mod",
+ "version": "${version}",
+ "mcversion": "1.8.9",
+ "url": "https://github.com/hannibal002/SkyHanni",
+ "updateUrl": "",
+ "authorList": [
+ "hannibal2"
+ ],
+ "credits": "https://github.com/hannibal002/SkyHanni/graphs/contributors",
+ "logoFile": "assets/skyhanni/logo.png",
+ "screenshots": [],
+ "dependencies": [
+ "NotEnoughUpdates"
+ ]
+ }
]
diff --git a/src/test/java/at/hannibal2/skyhanni/test/ItemUtilsTest.kt b/src/test/java/at/hannibal2/skyhanni/test/ItemUtilsTest.kt
index 0ac8cc8de..276e53159 100644
--- a/src/test/java/at/hannibal2/skyhanni/test/ItemUtilsTest.kt
+++ b/src/test/java/at/hannibal2/skyhanni/test/ItemUtilsTest.kt
@@ -5,18 +5,18 @@ import org.junit.jupiter.api.Test
class ItemUtilsTest {
- val items: MutableMap<String, Pair<String, Int>> = mutableMapOf(
- "§5Hoe of Greatest Tilling" to Pair("§5Hoe of Greatest Tilling", 1),
- "§fSilver medal §8x2" to Pair("§fSilver medal", 2),
- "§aJacob's Ticket §8x32" to Pair("§aJacob's Ticket", 32),
- "§9Delicate V" to Pair("§9Delicate V", 1),
- " §81x §9Enchanted Sugar Cane" to Pair("§9Enchanted Sugar Cane", 1),
- "§6Gold medal" to Pair("§6Gold medal", 1),
- " §8+§319k §7Farming XP" to Pair("§7Farming XP", 19_000),
- " §8+§215 §7Garden Experience" to Pair("§7Garden Experience", 15),
- " §8+§c21 Copper" to Pair("Copper", 21),
- " §8+§b10 Bits" to Pair("Bits", 10),
- " §8+§37.2k §7Farming XP" to Pair("§7Farming XP", 7_200),
+ private val items: MutableMap<String, Pair<String, Int>> = mutableMapOf(
+ "§5Hoe of Greatest Tilling" to Pair("§5Hoe of Greatest Tilling", 1),
+ "§fSilver medal §8x2" to Pair("§fSilver medal", 2),
+ "§aJacob's Ticket §8x32" to Pair("§aJacob's Ticket", 32),
+ "§9Delicate V" to Pair("§9Delicate V", 1),
+ " §81x §9Enchanted Sugar Cane" to Pair("§9Enchanted Sugar Cane", 1),
+ "§6Gold medal" to Pair("§6Gold medal", 1),
+ " §8+§319k §7Farming XP" to Pair("§7Farming XP", 19_000),
+ " §8+§215 §7Garden Experience" to Pair("§7Garden Experience", 15),
+ " §8+§c21 Copper" to Pair("Copper", 21),
+ " §8+§b10 Bits" to Pair("Bits", 10),
+ " §8+§37.2k §7Farming XP" to Pair("§7Farming XP", 7_200),
)
@Test
@@ -31,4 +31,4 @@ class ItemUtilsTest {
}
}
}
-} \ No newline at end of file
+}
diff --git a/src/test/java/at/hannibal2/skyhanni/test/garden/VisitorToolTipParserTest.kt b/src/test/java/at/hannibal2/skyhanni/test/garden/VisitorToolTipParserTest.kt
index 0f2ad1fee..cdb171aa6 100644
--- a/src/test/java/at/hannibal2/skyhanni/test/garden/VisitorToolTipParserTest.kt
+++ b/src/test/java/at/hannibal2/skyhanni/test/garden/VisitorToolTipParserTest.kt
@@ -1,6 +1,6 @@
package at.hannibal2.skyhanni.test.garden
-import at.hannibal2.skyhanni.config.features.GardenConfig
+import at.hannibal2.skyhanni.config.features.garden.GardenConfig
import at.hannibal2.skyhanni.features.garden.visitor.VisitorTooltipParser
import org.junit.jupiter.api.Test
@@ -22,18 +22,22 @@ class VisitorToolTipParserTest {
@Test
fun testParseItemsNeeded() {
- val parsedData = VisitorTooltipParser.parse(lore, GardenConfig())
+ val parsedData = VisitorTooltipParser.parse(lore,
+ GardenConfig()
+ )
assert(parsedData.itemsNeeded.isNotEmpty()) {
"Visitor items needed is ${parsedData.itemsNeeded.count()} instead of 1"
}
- assert(parsedData.itemsNeeded.get("§aEnchanted Hay Bale") == 28) {
+ assert(parsedData.itemsNeeded["§aEnchanted Hay Bale"] == 28) {
"Visitor items needed does not contain '§aEnchanted Hay Bale'"
}
}
@Test
fun testParseRewards() {
- val parsedData = VisitorTooltipParser.parse(lore, GardenConfig())
+ val parsedData = VisitorTooltipParser.parse(lore,
+ GardenConfig()
+ )
assert(parsedData.rewards.isNotEmpty()) {
"Visitor rewards is ${parsedData.rewards.count()} instead of 6"
}
@@ -48,7 +52,7 @@ class VisitorToolTipParserTest {
)
for ((itemName, amount) in assertions) {
- assert(parsedData.rewards.get(itemName) == amount) {
+ assert(parsedData.rewards[itemName] == amount) {
"Visitor rewards does not contain '$itemName' with amount '$amount'"
}
}
@@ -56,10 +60,12 @@ class VisitorToolTipParserTest {
@Test
fun testParseCopper() {
- val parsedData = VisitorTooltipParser.parse(lore, GardenConfig())
- val copper = parsedData.rewards.get("Copper")
+ val parsedData = VisitorTooltipParser.parse(lore,
+ GardenConfig()
+ )
+ val copper = parsedData.rewards["Copper"]
assert(copper == 23) {
"Visitor rewards does not contain 'Copper' with amount '23'"
}
}
-} \ No newline at end of file
+}