aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.editorconfig2
-rw-r--r--.github/workflows/label-merge-conflict.yml2
-rw-r--r--.github/workflows/remove-labels-on-pr-close.yml16
-rw-r--r--CHANGELOG.md203
-rw-r--r--CONTRIBUTING.md5
-rw-r--r--DISCORD_FAQ.md9
-rw-r--r--FEATURES.md43
-rw-r--r--README.md2
-rw-r--r--build.gradle.kts5
-rw-r--r--gradle/libs.versions.toml2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt50
-rw-r--r--src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/api/DataWatcherAPI.kt21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt42
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/HasLegacyId.java26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/Storage.java34
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt15
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/chat/FilterTypesConfig.java6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/combat/EnderNodeConfig.java116
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/combat/MobsConfig.java9
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/combat/damageindicator/DamageIndicatorConfig.java118
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/GhostCounterConfig.java93
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/TextFormattingConfig.java8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/commands/TabCompleteConfig.java1
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/dev/DebugConfig.java6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoCardConfig.java10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoConfig.java6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/event/winter/FrozenTreasureConfig.java94
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/event/winter/GiftingOpportunitiesConfig.java27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/event/winter/UniqueGiftConfig.java19
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/event/winter/WinterConfig.java10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/fishing/BarnTimerConfig.java20
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingConfig.java5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingProfitTrackerConfig.java29
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/CropStartLocationConfig.java2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenCommandsConfig.java31
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenConfig.java16
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/MoneyPerHourConfig.java48
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/NextJacobContestConfig.java2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/CropMilestonesConfig.java98
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/MushroomPetPerkConfig.java53
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/NextConfig.java2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestFinderConfig.java46
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestSpawnConfig.java26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestTimerConfig.java30
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestsConfig.java28
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/SprayConfig.java28
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/DropsStatisticsConfig.java99
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/RewardWarningConfig.java30
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/VisitorConfig.java4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java80
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/mining/PowderTrackerConfig.java143
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/minion/MinionsConfig.java6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/DiscordRPCConfig.java149
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/MiscConfig.java5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/TrackerConfig.java36
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/TrevorTheTrapperConfig.java81
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/slayer/ItemProfitTrackerConfig.java6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/slayer/endermen/EndermanConfig.java4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/BingoAPI.kt19
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt18
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/CropAccessoryData.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/EntityMovementData.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/EventCounter.kt46
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/FriendAPI.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/GardenComposterUpgradesData.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestonesCommunityFix.kt9
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/GuildAPI.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt1
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/IslandType.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/ItemAddManager.kt90
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/LocationFixData.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/MayorElection.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/MinecraftData.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/OtherInventoryData.kt9
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/OtherMod.kt42
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/OwnInventoryData.kt116
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt13
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/SkillExperience.kt10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/FriendsJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/FriendsJson.java)2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/JacobContestsJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/JacobContestsJson.java)5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/KnownFeaturesJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/KnownFeaturesJson.java)2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/MayorJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/MayorJson.java)2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/AnitaUpgradeCostsJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/AnitaUpgradeCostsJson.java)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ArmorDropsJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ArmorDropsJson.java)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/BingoJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/BingoJson.java)6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/BingoRanksJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/BingoRanksJson.java)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ContributorListJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ContributorListJson.java)3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/CrimsonIsleReputationJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/CrimsonIsleReputationJson.java)2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/DanceRoomInstructionsJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/DanceRoomInstructionsJson.java)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/DicerDropsJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/DicerDropsJson.java)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/DisabledFeaturesJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/DisabledFeaturesJson.java)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/EnigmaSoulsJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/EnigmaSoulsJson.java)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/FishingProfitItemsJson.java12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/GardenJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/GardenJson.java)2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/HideNotClickableItemsJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/HideNotClickableItemsJson.java)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ItemsJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ItemsJson.java)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/LocationFixJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/LocationFixJson.java)2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/MinionXPJson.java10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ModGuiSwitcherJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ModGuiSwitcherJson.java)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/MultiFilterJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/MultiFilterJson.java)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ParkourJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ParkourJson.java)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/PlayerChatFilterJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/PlayerChatFilterJson.java)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/RiftEffigiesJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/RiftEffigiesJson.java)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/SacksJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SacksJson.java)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/SeaCreatureJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SeaCreatureJson.java)66
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/SlayerProfitTrackerItemsJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SlayerProfitTrackerItemsJson.java)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/TabListJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/TabListJson.java)2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/TrophyFishJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/TrophyFishJson.java)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/VipVisitsJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/VipVisitsJson.java)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/WarpsJson.java (renamed from src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/WarpsJson.java)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/DamageIndicatorDeathEvent.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/DataWatcherUpdatedEvent.kt9
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/EntityCustomNameUpdateEvent.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/InventoryCloseEvent.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/ItemAddEvent.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/ItemInHandChangeEvent.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/MessageSendToServerEvent.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/MinionOpenEvent.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/OwnInventoryItemUpdateEvent.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/SkillExpGainEvent.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/bingo/BingoCardUpdateEvent.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/bingo/BingoGoalReachedEvent.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/garden/pests/PestSpawnEvent.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarApi.kt14
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/BingoAPI.kt40
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardDisplay.kt193
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardTips.kt77
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/CompactBingoChat.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/MinionCraftHelper.kt20
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoCardDisplay.kt272
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoCardReader.kt123
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoCardTips.kt84
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoGoals.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/card/CommunityGoal.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/card/PersonalGoal.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/card/goals/BingoGoal.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/card/goals/GoalType.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/card/goals/HiddenGoalData.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/BingoNextStepHelper.kt (renamed from src/main/java/at/hannibal2/skyhanni/features/bingo/BingoNextStepHelper.kt)34
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/ChatMessageStep.kt (renamed from src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/ChatMessageStep.kt)2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/CollectionStep.kt (renamed from src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/CollectionStep.kt)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/CraftStep.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/IslandVisitStep.kt (renamed from src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/IslandVisitStep.kt)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/ItemsStep.kt (renamed from src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/ItemsStep.kt)2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/NextStep.kt (renamed from src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/NextStep.kt)2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/ProgressionStep.kt (renamed from src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/ProgressionStep.kt)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/SkillLevelStep.kt (renamed from src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/SkillLevelStep.kt)4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/CraftStep.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilter.kt43
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/chat/CompactSplashPotionMessage.kt68
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/chat/Translator.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.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaShader.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/combat/BestiaryData.kt10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/BossType.kt177
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/DamageIndicatorManager.kt21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/EntityData.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/MobFinder.kt27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/combat/endernodetracker/EnderNodeTracker.kt27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostCounter.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostFormatting.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/commands/SendCoordinatedCommand.kt27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/commands/ViewRecipeCommand.kt18
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/commands/WarpIsCommand.kt10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/commands/WikiManager.kt39
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/GetFromSacksTabComplete.kt26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/PlayerTabComplete.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/WarpTabComplete.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/cosmetics/CosmeticFollowingLine.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonAPI.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonBossMessages.kt86
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonChatFilter.kt399
-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.kt71
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonDeathCounter.kt46
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonFinderFeatures.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonMilestonesDisplay.kt30
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonRankTabListColor.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/UniqueGiftingOpportunitiesFeatures.kt90
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/diana/GriffinBurrowHelper.kt19
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/diana/InquisitorWaypointShare.kt41
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/jerry/frozentreasure/FrozenTreasureTracker.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/winter/UniqueGiftCounter.kt74
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/FishingAPI.kt46
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/FishingTimer.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureManager.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/ShowFishingItemName.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/ThunderSparksHighlight.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingProfitPlayerMoving.kt43
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingProfitTracker.kt224
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingTrackerCategoryManager.kt72
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/TrophyFishManager.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt54
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneFix.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropTimeCommand.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenLevelDisplay.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt105
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenPlotAPI.kt185
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenPlotBorders.kt94
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenWarpCommands.kt63
-rwxr-xr-xsrc/main/java/at/hannibal2/skyhanni/features/garden/GardenYawAndPitch.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/ToolTooltipTweaks.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterDisplay.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterInventoryNumbers.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterOverlay.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/composter/GardenComposterInventoryFeatures.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestFFNeededDisplay.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestStatsSummary.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestTimeNeeded.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/ArmorDropTracker.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropMoneyDisplay.kt20
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropSpeedMeter.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/DicerDropTracker.kt46
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBestCropTime.kt9
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBurrowingSporesNotifier.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropMilestoneDisplay.kt59
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropSpeed.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCustomKeybinds.kt23
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenStartLocation.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/WildStrawberryDyeNotification.kt30
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/WrongFungiCutterWarning.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CaptureFarmingGear.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/OverviewPage.kt17
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/inventory/AnitaExtraFarmingFortune.kt7
-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/GardenDeskInSBMenu.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenInventoryNumbers.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenNextPlotPrice.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenPlotIcon.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/inventory/SkyMartCopperPrice.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestAPI.kt21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestFinder.kt226
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestSpawn.kt57
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestSpawnTimer.kt37
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestType.kt16
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/pests/SprayFeatures.kt76
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/pests/SprayType.kt14
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorColorNames.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorDropStatistics.kt42
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorFeatures.kt30
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorTimer.kt20
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/visitor/HighlightVisitorsOutsideOfGarden.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorAPI.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorReward.kt32
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/inventory/ChestValue.kt10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/inventory/HideNotClickableItems.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/inventory/ItemDisplayOverlayFeatures.kt133
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/inventory/ItemStars.kt20
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/mining/KingTalismanHelper.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/mining/powdertracker/PowderTracker.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt49
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/minion/MinionXp.kt195
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/FixNEUHeavyPearls.kt16
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/InGameDateDisplay.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/LockMouseLook.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/MarkedPlayerManager.kt14
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/NonGodPotEffectDisplay.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/QuickModMenuSwitch.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/AdvancedPlayerList.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordRPCManager.kt36
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordStatus.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValue.kt21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValueCalculator.kt11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedWardrobePrice.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorFeatures.kt31
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorTracker.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazingSouls.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangFreezeCooldown.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangGravityOrbs.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/CrimsonIsleReputationHelper.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailykuudra/DailyKuudraBossHelper.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/QuestLoader.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/DailyMiniBossHelper.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/RiftAgaricusCap.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/RiftWiltedBerberisHelper.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/VoltHighlighter.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/livingcave/LivingCaveDefenseBlocks.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/DanceRoomHelper.kt2
-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.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/EnigmaSoulWaypoints.kt4
-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/HideMobNames.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerBossSpawnSoon.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemsOnGround.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerMiniBossFeatures.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt263
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerQuestWarning.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerRngMeterDisplay.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/VampireSlayerFeatures.kt38
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/blaze/BlazeSlayerDaggerHelper.kt13
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/enderman/EndermanSlayerFeatures.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningMobManager.kt9
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningSoulsName.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/mixins/hooks/GuiIngameHook.kt35
-rw-r--r--src/main/java/at/hannibal2/skyhanni/mixins/hooks/NetworkManagerHook.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/mixins/transformers/UpdateDataWatcherEventPatch.java25
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/HighlightMissingRepoItems.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/PacketTest.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/BlockUtils.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/ConfigUtils.kt63
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/DelayedRun.kt34
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt9
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt34
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/LocationUtils.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt25
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt14
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/MultiFilter.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/ParkourHelper.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt40
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/tracker/ItemTrackerData.kt53
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniItemTracker.kt151
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt54
332 files changed, 6275 insertions, 2305 deletions
diff --git a/.editorconfig b/.editorconfig
index 28d8209de..8354a021e 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -23,8 +23,10 @@ max_line_length = 120
# Java files should not use wildcard imports
ij_java_names_count_to_use_import_on_demand = 999
ij_java_class_count_to_use_import_on_demand = 999
+ij_java_packages_to_use_import_on_demand =
[*.kt]
# Kotlin files should not use wildcard imports
ij_kotlin_name_count_to_use_star_import = 999
ij_kotlin_name_count_to_use_star_import_for_members = 999
+ij_kotlin_packages_to_use_import_on_demand =
diff --git a/.github/workflows/label-merge-conflict.yml b/.github/workflows/label-merge-conflict.yml
index 6c0268d6c..19e88ede7 100644
--- a/.github/workflows/label-merge-conflict.yml
+++ b/.github/workflows/label-merge-conflict.yml
@@ -4,7 +4,7 @@ on:
push:
branches: [ beta ]
# So that the `dirtyLabel` is removed if conflicts are resolve
- # We recommend `pull_request_target` so that github secrets are available.
+ # We recommend `pull_request_target` so that GitHub secrets are available.
# In `pull_request` we wouldn't be able to change labels of fork PRs
pull_request_target:
types: [ opened, synchronize ]
diff --git a/.github/workflows/remove-labels-on-pr-close.yml b/.github/workflows/remove-labels-on-pr-close.yml
new file mode 100644
index 000000000..fd73b7aab
--- /dev/null
+++ b/.github/workflows/remove-labels-on-pr-close.yml
@@ -0,0 +1,16 @@
+# https://github.com/marketplace/actions/label-remover
+
+name: "Remove All Labels"
+
+on:
+ pull_request_target:
+ types: [closed]
+
+jobs:
+ remove_very_soon:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: rogerluan/label-remover@v1.0.1
+ with:
+ github_token: ${{ secrets.github_token }}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 884017ef6..75ecc9cb5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,184 @@
# SkyHanni - Change Log
+## Version 0.22 (Unreleased)
+
+### New Features
+
+#### Garden Features
+
++ Added Garden Vacuum Pests in Pest bag to item number as stack size. - hannibal2
+ + Enable via /sh vacuum.
++ Added Pests to Damage Indicator. - hannibal2
+ + Enable Damage Indicator and select Garden Pests.
++ Change how the pest spawn chat message should be formatted. - hannibal2
+ + Unchanged, compact or hide the message entirely.
++ Show a Title when a pest spawns. - hannibal2
++ Show the time since the last pest spawned in your garden. - hannibal2
+ + Option to only show the time while holding vacuum in the hand.
++ Show the pests that are attracted when changing the selected material of the Sprayanator. - hannibal2
++ Added Garden only commands /home, /barn and /tp, and hotkeys. - hannibal2
++ Showing a better plot name in the scoreboard. Updates faster and doesn't hide when pests are spawned. - hannibal2
++ Show a display with all known pest locations. - hannibal2
+ + Click to warp to the plot.
+ + Option to only show the time while holding vacuum in the hand.
++ Mark the plots with pests on them in the world. - hannibal2
++ Press the key to warp to the nearest plot with pests on it. - hannibal2
++ Draw plot borders when holding the Sprayonator. - HiZe
+
+#### Fishing Features
+
++ Added Barn Fishing Timer to Jerry's Workshop and Crimson Isle. - martimavocado
++ Added Fishing Tracker and changed trackers in general. - hannibal2
+ + This tracker GUI behaves the same way as the Slayer Tracker: Allows for single item remove or hide
+ + Counts coin drops from chat.
+ + Mark the amount in green when recently gained the item.
+ + Option to hide the Fishing Tracker while moving.
+ + Option to hide all Trackers while Estimated Item Value is visible.
+ + Option to change the default display mode for all trackers.
+ + The hidden flag for items in Item Trackers is now shared between total view and session view.
+ + Option to exclude hidden items in the total price calculation.
+ + Option to change the display mode that gets shown on default: Total, Current or remember last.
+
+#### Winter Features
+
++ Added Unique Gifting Opportunities. - nea
+ + Highlight players who you haven't given gifts to yet.
+ + Only highlight ungifted players while holding a gift.
+ + Make use of armor stands to stop highlighting players. This is a bit inaccurate, but it can help with people you gifted before this feature was used.
++ Added Unique Gifted users counter. - hannibal2
+ + Show in a display how many unique players you have given gifts to in the winter 2023 event.
+ + Run command /opengenerowmenu to sync up.
+
+#### Bingo Features
+
++ Show the duration until the next hidden bingo goal tip gets revealed. - hannibal2
++ Added support for tips in hidden bingo card display. - hannibal2
++ Added support for 'found by' info in bingo card. - hannibal2
++ Added Bingo Goal Rank as stack size in Bingo Card. - Erymanthus
++ Added the option to only show tier 1 Minion Crafts in the Helper display when their items needed are fully collected. - hannibal2
++ Added the option to click in the bingo card viewer on goals to mark them as highlighted. - hannibal2
+ + If at least one goal is highlighted, non-highlighted goals will be hidden.
+
+#### Inventory Features
+
++ Added bottle of Jyrre time overlay in stack size feature. - HiZe
++ Added show special edition number as stack size when below 1k. - hannibal2
+
+#### Minion Features
+
++ Shows how much skill experience you will get when picking up items from the minion storage. - Thunderblade73
+
+#### Chat Features
+
++ Hide the repeating fire sale reminder chat messages. - hannibal2
+
+### Changes
+
+#### Garden Changes
+
++ Added option to enable/disable the vacuum bag item number being capped to 40. - hannibal2
++ Automatic unlocking /shmouselock when teleporting in the garden. - hannibal2
++ Don't hide messages from Jacob. - alexia
+ + This is a workaround for wrongly hidden Jakob messages.
++ Show the hint to open Configure Plot only if the pest display is incorrect. - hannibal2
++ Added the "plot" word to the sidebar again (only if there are no pests in garden). - hannibal2
++ Hide the Composter Overlay in composter inventory while the Estimated Item Value is visible. - hannibal2
++ Made the wording of "no pest spawned yet" message more clear. - hannibal2
++ Not only show the waypoint for infested plots, also show their waypoints in the world. - hannibal2
++ Use different colors in the tab list depending on the pest count. - alexia
++ Highlight the boosted crop contest in all Jacob's Contest displays. - alexia
++ Added Delicate 5 to visitor drop counter and visitor block refuse and highlighter. - hannibal2
++ Block visitor interaction for dedication cycling is now disabled by default. - hannibal2
+
+#### Fishing Changes
+
++ Show the fishing tracker for a couple of seconds after catching something even while moving. - hannibal2
+
+#### Winter Changes
+
++ Hiding Unique Gifted Players Highlighting for ironman and bingo while not on those modes. - Thunderblade73
+
+#### Chat Changes
+
++ Added fire sale messages in the hub to the chat message filter. - hannibal2
++ Added compact potion message support for splash messages and for Poisoned Candy I. - walker
+
+#### Bingo Changes
+
++ Option to remove the background difficulty color in the bingo card inventory when the goal is done. - hannibal2
++ Mark the background difficulty gray for unknown goals. - hannibal2
+ + This is no longer needed as all 20 hidden goals are known now, but we now have this support for the next extreme bingo with hidden goals.
+
+### Fixes
+
+#### Garden Fixes
+
++ Fixed pest damage indicator not working for some pests. - hannibal2
++ Fixed pest kill detection. - hannibal2
++ Fixed /tp <plot name> not working with uppercase characters. - hannibal2
++ Fixed total equipment fortune in /ff. - alexia
++ Fixed Locust pest not getting detected in damage indicator. - hannibal2
++ Fixed Pest Spray Display showing outside the garden. - hannibal2
++ Fixed pest detection when more than 3 pests are spawned at once. - hannibal2
++ Fixed showing on the scoreboard "garden outside" immediately after teleporting to a plot. - hannibal2
++ Fixed visitor timer counting down too fast sometimes. - hannibal2
++ Fixed Mooshroom cow Perk display not showing when maxed. - hannibal2
++ Show a text around the new year that the calendar is not loaded for the next Jacob Contest. - hannibal2
++ Fixed visitor reward item refuse inconsistencies. - hannibal2
+
+#### Bingo Fixes
+
++ Hide the long hint line in the Bingo Goal Display. - hannibal2
++ Show community goals in the Bingo Display correctly. - hannibal2
++ Hide enchanted tools in Minion Craft Helper. - hannibal2
+
+#### Minion Fixes
+
++ Fixed Minion XP display not showing sometimes. - Thunderblade73
++ Updating the Minion XP display when the minion picks up a new item while inside the inventory. - hannibal2
++ Fixed minion features disappear inside the minion inventory when picking up an item. - hannibal2
+
+#### Misc Fixes
+
++ Fixed Item Tracker not ignoring manual sack movements. - hannibal2
++ Fixed showing yourself green with Unique Gifting Opportunities. - hannibal2
++ Fixed NPC messages getting detected as player messages. - CalMWolfs
++ Hide Scavenger 5 on an Ice Spray Wand and Replenish on an Advanced Gardening Hoe/Axe for the Estimated Item Value. - hannibal2
++ Fixed an error when the king talisman helper does not find the king in range. - hannibal2
+
+#### Config Fixes
+
++ Fixed a typo in config. - walker
+
+### Technical Details
+
++ Code cleanup in many files. - walker & hannibal2
++ Moved the JSON object files into another package. - walker
++ Replaced SkyHanniMod.feature.garden with GardenAPI.config. - hannibal2
++ Added MessageSendToServerEvent. - hannibal2
++ Added GardenPlotAPI, support for detecting the current slot of the player. - hannibal2
++ Updated .editorconfig file to better support imports. - Thunderblade73
++ Migrate Integer to Enums in Config. - walker
++ Using a broken config no longer resets the config in dev env. - hannibal2
++ Auto-removing all labels of PRs on merging/closing. - hannibal2
++ Changed OwnInventoryItemUpdateEvent to be called synced to the main thread. - hannibal2
++ romanToDecimalIfNeeded -> romanToDecimalIfNecessary. - hannibal2
+ + For more context: https://chat.openai.com/share/502571b5-8851-4047-b343-3b1475ca8a88
++ Added the debug feature SkyHanni Event Counter. - hannibal2
++ Fix Consecutive Spaces in RegEx. - walker
++ No longer creating new regex pattern elements each time in DungeonDeathCounter. - walker
++ Changed DungeonChatFilter to use lists of patterns. - walker
++ Code cleanup in DungeonMilestoneDisplay. - walker
++ Code cleanup and removed .matchRegex() - walker
++ Misc pattern optimizations. - walker
++ Moving the bingo goal list into BingoAPI. - hannibal2
++ Created BingoGoalReachedEvent. - hannibal2
++ Created Matcher.groupOrNull. - walker
++ cleanPlayerName respects playerRankHider option now. - hannibal2
++ Replaced ItemWarnEntry with VisitorReward. This should fix some errors. - hannibal2
++ GardenNextJacobContest now uses SimpleTimeMark. SimpleTimeMark is storable in the config and comparable - hannibal2
++ No longer sending contest data to elite close to new year. - hannibal2
+
## Version 0.21.1
### New Features
@@ -14,6 +193,26 @@
### Changes
++ /shtrackcollection now supports sack messages. - hannibal2
++ Changed formatting of coin value to be more consistent over multiple features. - hannibal2
++ Made skill level as item number no longer default enabled. - hannibal2
+
+### Fixes
+
++ Fixed the wrong colouring of hidden items in Slayer Profit Tracker. - hannibal2
++ Added support for NEU Heavy Pearl TO-DO fix working without nether sacks as well. - hannibal2
++ Fixed Estimated Item Value getting shown in pet rule creation wardrobe slot pick menu. - hannibal2
+
+### Technical Details
+
++ Added /shwhereami command to show the current island. - martimavocado
++ Tons of code clean-ups over the whole project. - walker & hannibal2
+ + Added ItemAddEvent. - hannibal2
++ Gets called when the user collects an item into inventory or sacks.
++ Created SkyHanniItemTracker. - hannibal2
+ + This is a Special variant of SkyHanniTracker, that has item specific functions (hide or remove) and different price variants.
++ Migrated slayer profit data into SkyHanniTracker format. - hannibal2
+
#### Garden Changes
+ Added mythic/Maeve visitor support. - walker & hannibal2
@@ -926,7 +1125,7 @@
### Fixes
+ Fixed Pocket Sack-In-A-Sack Replace in lore
-+ Fixed possible crash with broken neu repo when opening the desk inventory in garden (Contributed by CalMWolfs)
++ Fixed possible crash with broken neu repo when opening the desk inventory in the garden (Contributed by CalMWolfs)
+ Fixed frozen treasures per hour display being inaccurate (Contributed by CalMWolfs)
+ Fixed bug with ghost counter sometimes not detecting new kills (Contributed by CalMWolfs)
+ Fixed **Ghost Counter** - HiZe & ksipli
@@ -1239,7 +1438,7 @@
and show a preview how these stats change when hovering over an upgrade
+ Hide crop money display, crop milestone display and garden visitor list while inside anita show, SkyMart or the
composter inventory
-+ Hide chat messages from the visitors in garden. (Except Beth and Spaceman)
++ Hide chat messages from the visitors in the garden. (Except Beth and Spaceman)
+ Introduced a new command '/shcroptime <amount> <item>' that displays the estimated time it will take to gather the
requested quantity of a particular item based on the current crop speed.
+ Show the average crop milestone in the crop milestone inventory.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 25124fffa..fb5a7e1e6 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -56,7 +56,7 @@ You can write in the description of the pr the wording for the changelog as well
- All new classes should be written in Kotlin, with a few exceptions:
- Config files in `at.hannibal2.skyhanni.config.features`
- Mixin classes in `at.hannibal2.skyhanni.mixins.transformers`
- - Java classes that represent JSON data objects in `at.hannibal2.skyhanni.utils.jsonobjects`
+ - Java classes that represent JSON data objects in `at.hannibal2.skyhanni.data.jsonobjects`
- Please use the existing event system, or expand on it. Do not use Forge events.
- (We inject the calls with Mixin)
- Please use existing utils methods.
@@ -125,7 +125,8 @@ SkyHanni uses a repo system to easily change static variables without the need f
The repo is located at https://github.com/hannibal002/SkyHanni-REPO.
A copy of all json files is stored on the computer under `.minecraft\config\skyhanni\repo`.
On every game start, the copy gets updated (if outdated and if not manually disabled).
-If you add stuff to the repo make sure it gets serialised. See the [jsonobjects](src/main/java/at/hannibal2/skyhanni/utils/jsonobjects)
+If you add stuff to the repo make sure it gets serialised. See
+the [jsonobjects](src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo)
folder for how to properly do this. You also may have to disable repo auto update in game.
### Discord IPC
diff --git a/DISCORD_FAQ.md b/DISCORD_FAQ.md
index 68fb338d1..997389a48 100644
--- a/DISCORD_FAQ.md
+++ b/DISCORD_FAQ.md
@@ -25,8 +25,9 @@ _Frequently Asked Questions_
> No, the barn fishing timer is not supported in the Crimson Isle in Hypixel Skyblock because it would disrupt other fishers due to competition for the maximum sea creature cap, potentially leading to conflicts and stealing of sea creatures.
> **8: My Jacob Contest Display crops are wrong, how do I fix this?**
-> 1. Run the command `/shconfig reset config.storage.gardenJacobFarmingContestTimes`
-> 2. Restart the game
+> 1. Close your minecraft.
+> 2. Delete ".minecraft\config\skyhanni\jacob_contests.json".
+> 3. Open minecraft.
-*This FAQ was last updated on October 17th, 2023.
-If you believe there's something that should be added to this list, please tell us, so we can add it.* \ No newline at end of file
+*This FAQ was last updated on december 05th, 2023.
+If you believe there's something that should be added to this list, please tell us, so we can add it.*
diff --git a/FEATURES.md b/FEATURES.md
index b354e160d..1005bd1be 100644
--- a/FEATURES.md
+++ b/FEATURES.md
@@ -28,6 +28,7 @@ Use `/sh` or `/skyhanni` to open the SkyHanni config in game.
+ Will not break with emblems.
+ Optional if left or right side of name.
+ Should not break with other mods.
++ Hide the repeating fire sale reminder chat messages. - hannibal2
#### Chat Filter
@@ -174,6 +175,7 @@ Use `/sh` or `/skyhanni` to open the SkyHanni config in game.
- Minion name display with minion tier.
- **Minion Craft Helper** - Show how many more items you need to upgrade the minion in your inventory. Especially useful
for bingo.
++ Shows how much skill experience you will get when picking up items from the minion storage. - Thunderblade73
</details>
<details open><summary>
@@ -245,6 +247,7 @@ Use `/sh` or `/skyhanni` to open the SkyHanni config in game.
- Option to show the health of Voidgloom Seraph 4 during the laser phase (useful when trying to phase skip)
- Show when Revenant Horror 5 is about to BOOM.
- Hide the vanilla nametag of damage indicator bosses.
+- Garden Pests in Damage Indicator
- **Time to Kill**
- Show the time it takes to kill the Slayer boss.
@@ -339,6 +342,14 @@ Use `/sh` or `/skyhanni` to open the SkyHanni config in game.
+ Shortens chat messages about skill level ups, collection gains and new area discoveries while on bingo.
+ Bingo Card
++ Show the duration until the next hidden bingo goal tip gets revealed. - hannibal2
++ Support for tips in hidden bingo card display. - hannibal2
++ Support for 'found by' info in bingo card. - hannibal2
++ Bingo Goal Rank as stack size in Bingo Card. - Erymanthus
++ Option to only show tier 1 Minion Crafts in the Helper display when their items needed are fully collected. - hannibal2
++ Added the option to click in the bingo card viewer on goals to mark them as highlighted. - hannibal2
+ + If at least one goal is highlighted, non-highlighted goals will be hidden.
+
</details>
<details open><summary>
@@ -440,7 +451,7 @@ Use `/sh` or `/skyhanni` to open the SkyHanni config in game.
is empty when fully filled and show a preview how these stats change when hovering over an upgrade
+ Hide crop money display, crop milestone display and garden visitor list while inside anita show, SkyMart or the
composter inventory
-+ Hide chat messages from the visitors in garden. (Except Beth and Spaceman)
++ Hide chat messages from the visitors in the garden. (Except Beth, Jacob and Spaceman)
+ Show the average crop milestone in the crop milestone inventory.
+ **FF for Contest** - Show the minimum needed Farming Fortune for reaching a medal in the Jacob's Farming Contest
inventory.
@@ -494,6 +505,29 @@ Use `/sh` or `/skyhanni` to open the SkyHanni config in game.
+ You can use this to share your hypixel data with SkyHanni via the discord.
+ This will allow us to fix the crop milestone features quicker, as we currently do not have accurate data for this.
+ If you don't want to share anything, you can disable the chat message in the config with /sh copy milestone data.
++ Garden Vacuum Pests in Pest bag to item number as stack size. - hannibal2
+ + Enable via /sh vacuum.
+
+### Garden Pests
+
++ Added Garden Vacuum Pests in Pest bag to item number as stack size. - hannibal2
+ + Enable via /sh vacuum.
++ Added Pests to Damage Indicator. - hannibal2
+ + Enable Damage Indicator and select Garden Pests.
++ Change how the pest spawn chat message should be formatted. - hannibal2
+ + Unchanged, compact or hide the message entirely.
++ Show a Title when a pest spawns. - hannibal2
++ Show the time since the last pest spawned in your garden. - hannibal2
+ + Option to only show the time while holding vacuum in the hand.
++ Show the pests that are attracted when changing the selected material of the Sprayanator. - hannibal2
++ Added Garden only commands /home, /barn and /tp, and hotkeys. - hannibal2
++ Showing a better plot name in the scoreboard. Updates faster and doesn't hide when pests are spawned. - hannibal2
++ Show a display with all known pest locations. - hannibal2
+ + Click to warp to the plot.
+ + Option to only show the time while holding vacuum in the hand.
++ Mark the plots with pests on them in the world. - hannibal2
++ Press the key to warp to the nearest plot with pests on it. - hannibal2
++ Draw plot borders when holding the Sprayonator. - HiZe
</details>
<details open><summary>
@@ -599,6 +633,13 @@ Use `/sh` or `/skyhanni` to open the SkyHanni config in game.
+ Accept Hotkey: Accept a visitor when you press this keybind while in the visitor GUI.
+ Added support for showing the primal fear data from tab list as GUI elements. - Erymanthus
+ Play warning sound when the next Primal Fear can spawn. - thunderblade73
++ Unique Gifting Opportunities. - nea
+ + Highlight players who you haven't given gifts to yet.
+ + Only highlight ungifted players while holding a gift.
+ + Make use of armor stands to stop highlighting players. This is a bit inaccurate, but it can help with people you gifted before this feature was used.
++ Unique Gifted users counter. - hannibal2
+ + Show in a display how many unique players you have given gifts to in the winter 2023 event.
+ + Run command /opengenerowmenu to sync up.
</details>
<details open><summary>
diff --git a/README.md b/README.md
index ca6c1f486..6e1c95c8e 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@
SkyHanni is a Forge mod for Minecraft 1.8.9. It adds many features to Hypixel SkyBlock.
The mod is filled with GUIs, extra chat messages, reminders, message hiders and entity highlighters.
-The majority of these features are centered on the Garden, Slayer, Bingo, Diana, and Rift.
+The majority of these features are centered in the Garden, Slayer, Bingo, Diana, and Rift.
We have a [tutorial](https://github.com/hannibal002/SkyHanni/blob/beta/INSTALLING.md)
for how to download and install the mod.
diff --git a/build.gradle.kts b/build.gradle.kts
index 5abe8290f..694ef15b2 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -11,7 +11,7 @@ plugins {
}
group = "at.hannibal2.skyhanni"
-version = "0.21.1"
+version = "0.22.Beta.8"
// Toolchains:
java {
@@ -87,8 +87,6 @@ dependencies {
}
shadowModImpl(libs.moulconfig)
- devenvMod(variantOf(libs.moulconfig) { classifier("test") })
-
shadowImpl(libs.libautoupdate)
shadowImpl("org.jetbrains.kotlin:kotlin-reflect:1.9.0")
@@ -124,6 +122,7 @@ loom {
property("mixin.debug", "true")
property("asmhelper.verbose", "true")
arg("--tweakClass", "org.spongepowered.asm.launch.MixinTweaker")
+ arg("--tweakClass", "io.github.moulberry.moulconfig.tweaker.DevelopmentResourceTweaker")
arg("--mods", devenvMod.resolve().joinToString(",") { it.relativeTo(file("run")).path })
}
}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 0bdf7b127..e29f8e72b 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,6 +1,6 @@
[versions]
libautoupdate = "1.0.3"
-moulconfig = "2.4.3"
+moulconfig = "2.5.0"
[libraries]
moulconfig = { module = "org.notenoughupdates.moulconfig:legacy", version.ref = "moulconfig" }
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt
index f974d3d1d..3aaa809d2 100644
--- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt
+++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt
@@ -1,13 +1,13 @@
package at.hannibal2.skyhanni
import at.hannibal2.skyhanni.api.CollectionAPI
+import at.hannibal2.skyhanni.api.DataWatcherAPI
import at.hannibal2.skyhanni.config.ConfigFileType
import at.hannibal2.skyhanni.config.ConfigManager
import at.hannibal2.skyhanni.config.Features
import at.hannibal2.skyhanni.config.SackData
import at.hannibal2.skyhanni.config.commands.Commands.init
import at.hannibal2.skyhanni.data.ActionBarStatsData
-import at.hannibal2.skyhanni.data.BingoAPI
import at.hannibal2.skyhanni.data.BlockData
import at.hannibal2.skyhanni.data.ChatManager
import at.hannibal2.skyhanni.data.CropAccessoryData
@@ -21,6 +21,7 @@ import at.hannibal2.skyhanni.data.GardenCropUpgrades
import at.hannibal2.skyhanni.data.GuiEditManager
import at.hannibal2.skyhanni.data.GuildAPI
import at.hannibal2.skyhanni.data.HypixelData
+import at.hannibal2.skyhanni.data.ItemAddManager
import at.hannibal2.skyhanni.data.ItemClickData
import at.hannibal2.skyhanni.data.ItemRenderBackground
import at.hannibal2.skyhanni.data.ItemTipHelper
@@ -40,6 +41,9 @@ import at.hannibal2.skyhanni.data.SlayerAPI
import at.hannibal2.skyhanni.data.TitleData
import at.hannibal2.skyhanni.data.TitleManager
import at.hannibal2.skyhanni.data.ToolTipData
+import at.hannibal2.skyhanni.data.jsonobjects.local.FriendsJson
+import at.hannibal2.skyhanni.data.jsonobjects.local.JacobContestsJson
+import at.hannibal2.skyhanni.data.jsonobjects.local.KnownFeaturesJson
import at.hannibal2.skyhanni.data.repo.RepoManager
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.features.anvil.AnvilCombineHelper
@@ -48,11 +52,13 @@ import at.hannibal2.skyhanni.features.bazaar.BazaarBestSellMethod
import at.hannibal2.skyhanni.features.bazaar.BazaarCancelledBuyOrderClipboard
import at.hannibal2.skyhanni.features.bazaar.BazaarOpenPriceWebsite
import at.hannibal2.skyhanni.features.bazaar.BazaarOrderHelper
-import at.hannibal2.skyhanni.features.bingo.BingoCardDisplay
-import at.hannibal2.skyhanni.features.bingo.BingoCardTips
-import at.hannibal2.skyhanni.features.bingo.BingoNextStepHelper
+import at.hannibal2.skyhanni.features.bingo.BingoAPI
import at.hannibal2.skyhanni.features.bingo.CompactBingoChat
import at.hannibal2.skyhanni.features.bingo.MinionCraftHelper
+import at.hannibal2.skyhanni.features.bingo.card.BingoCardDisplay
+import at.hannibal2.skyhanni.features.bingo.card.BingoCardReader
+import at.hannibal2.skyhanni.features.bingo.card.BingoCardTips
+import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.BingoNextStepHelper
import at.hannibal2.skyhanni.features.chat.ArachneChatMessageHider
import at.hannibal2.skyhanni.features.chat.ChatFilter
import at.hannibal2.skyhanni.features.chat.CompactBestiaryChatMessage
@@ -97,6 +103,7 @@ import at.hannibal2.skyhanni.features.dungeon.DungeonMilestonesDisplay
import at.hannibal2.skyhanni.features.dungeon.DungeonRankTabListColor
import at.hannibal2.skyhanni.features.dungeon.DungeonTeammateOutlines
import at.hannibal2.skyhanni.features.dungeon.HighlightDungeonDeathmite
+import at.hannibal2.skyhanni.features.event.UniqueGiftingOpportunitiesFeatures
import at.hannibal2.skyhanni.features.event.diana.BurrowWarpHelper
import at.hannibal2.skyhanni.features.event.diana.GriffinBurrowHelper
import at.hannibal2.skyhanni.features.event.diana.GriffinBurrowParticleFinder
@@ -106,6 +113,7 @@ import at.hannibal2.skyhanni.features.event.diana.SoopyGuessBurrow
import at.hannibal2.skyhanni.features.event.jerry.HighlightJerries
import at.hannibal2.skyhanni.features.event.jerry.frozentreasure.FrozenTreasureTracker
import at.hannibal2.skyhanni.features.event.spook.TheGreatSpook
+import at.hannibal2.skyhanni.features.event.winter.UniqueGiftCounter
import at.hannibal2.skyhanni.features.fame.AccountUpgradeReminder
import at.hannibal2.skyhanni.features.fame.CityProjectFeatures
import at.hannibal2.skyhanni.features.fishing.ChumBucketHider
@@ -119,6 +127,9 @@ import at.hannibal2.skyhanni.features.fishing.SeaCreatureMessageShortener
import at.hannibal2.skyhanni.features.fishing.SharkFishCounter
import at.hannibal2.skyhanni.features.fishing.ShowFishingItemName
import at.hannibal2.skyhanni.features.fishing.ThunderSparksHighlight
+import at.hannibal2.skyhanni.features.fishing.tracker.FishingProfitPlayerMoving
+import at.hannibal2.skyhanni.features.fishing.tracker.FishingProfitTracker
+import at.hannibal2.skyhanni.features.fishing.tracker.FishingTrackerCategoryManager
import at.hannibal2.skyhanni.features.fishing.trophy.OdgerWaypoint
import at.hannibal2.skyhanni.features.fishing.trophy.TrophyFishFillet
import at.hannibal2.skyhanni.features.fishing.trophy.TrophyFishManager
@@ -130,7 +141,9 @@ import at.hannibal2.skyhanni.features.garden.GardenCropMilestoneFix
import at.hannibal2.skyhanni.features.garden.GardenLevelDisplay
import at.hannibal2.skyhanni.features.garden.GardenNextJacobContest
import at.hannibal2.skyhanni.features.garden.GardenOptimalSpeed
+import at.hannibal2.skyhanni.features.garden.GardenPlotAPI
import at.hannibal2.skyhanni.features.garden.GardenPlotBorders
+import at.hannibal2.skyhanni.features.garden.GardenWarpCommands
import at.hannibal2.skyhanni.features.garden.GardenYawAndPitch
import at.hannibal2.skyhanni.features.garden.ToolTooltipTweaks
import at.hannibal2.skyhanni.features.garden.composter.ComposterDisplay
@@ -162,6 +175,10 @@ import at.hannibal2.skyhanni.features.garden.inventory.GardenInventoryNumbers
import at.hannibal2.skyhanni.features.garden.inventory.GardenNextPlotPrice
import at.hannibal2.skyhanni.features.garden.inventory.GardenPlotIcon
import at.hannibal2.skyhanni.features.garden.inventory.SkyMartCopperPrice
+import at.hannibal2.skyhanni.features.garden.pests.PestFinder
+import at.hannibal2.skyhanni.features.garden.pests.PestSpawn
+import at.hannibal2.skyhanni.features.garden.pests.PestSpawnTimer
+import at.hannibal2.skyhanni.features.garden.pests.SprayFeatures
import at.hannibal2.skyhanni.features.garden.visitor.GardenVisitorColorNames
import at.hannibal2.skyhanni.features.garden.visitor.GardenVisitorDropStatistics
import at.hannibal2.skyhanni.features.garden.visitor.GardenVisitorFeatures
@@ -193,6 +210,7 @@ import at.hannibal2.skyhanni.features.mining.crystalhollows.CrystalHollowsNamesI
import at.hannibal2.skyhanni.features.mining.powdertracker.PowderTracker
import at.hannibal2.skyhanni.features.minion.MinionCollectLogic
import at.hannibal2.skyhanni.features.minion.MinionFeatures
+import at.hannibal2.skyhanni.features.minion.MinionXp
import at.hannibal2.skyhanni.features.misc.BrewingStandOverlay
import at.hannibal2.skyhanni.features.misc.ButtonOnPause
import at.hannibal2.skyhanni.features.misc.CollectionTracker
@@ -308,9 +326,6 @@ import at.hannibal2.skyhanni.utils.KeyboardManager
import at.hannibal2.skyhanni.utils.MinecraftConsoleFilter.Companion.initLogging
import at.hannibal2.skyhanni.utils.NEUVersionCheck.checkIfNeuIsLoaded
import at.hannibal2.skyhanni.utils.TabListData
-import at.hannibal2.skyhanni.utils.jsonobjects.FriendsJson
-import at.hannibal2.skyhanni.utils.jsonobjects.JacobContestsJson
-import at.hannibal2.skyhanni.utils.jsonobjects.KnownFeaturesJson
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
@@ -332,7 +347,7 @@ import org.apache.logging.log4j.Logger
clientSideOnly = true,
useMetadata = true,
guiFactory = "at.hannibal2.skyhanni.config.ConfigGuiForgeInterop",
- version = "0.21.1",
+ version = "0.22.Beta.8",
)
class SkyHanniMod {
@Mod.EventHandler
@@ -377,6 +392,7 @@ class SkyHanniMod {
loadModule(ActionBarStatsData)
loadModule(GardenCropMilestoneInventory())
loadModule(GardenCropSpeed)
+ loadModule(GardenWarpCommands())
loadModule(ProfileStorageData)
loadModule(TitleData())
loadModule(BlockData())
@@ -384,10 +400,14 @@ class SkyHanniMod {
loadModule(EntityOutlineRenderer)
loadModule(KeyboardManager)
loadModule(AdvancedPlayerList)
+ loadModule(ItemAddManager())
+ loadModule(BingoCardReader())
// APIs
loadModule(BazaarApi())
loadModule(GardenAPI)
+ loadModule(GardenPlotAPI)
+ loadModule(DataWatcherAPI())
loadModule(CollectionAPI())
loadModule(FarmingContestAPI)
loadModule(FriendAPI)
@@ -407,7 +427,7 @@ class SkyHanniMod {
loadModule(PlayerChatModifier())
loadModule(DungeonChatFilter())
loadModule(HideNotClickableItems())
- loadModule(ItemDisplayOverlayFeatures())
+ loadModule(ItemDisplayOverlayFeatures)
loadModule(CurrentPetDisplay())
loadModule(ExpOrbsOnGroundHider())
loadModule(FandomWikiFromMenus())
@@ -419,6 +439,8 @@ class SkyHanniMod {
loadModule(DungeonCleanEnd())
loadModule(DungeonBossMessages())
loadModule(DungeonBossHideDamageSplash())
+ loadModule(UniqueGiftingOpportunitiesFeatures)
+ loadModule(UniqueGiftCounter)
loadModule(TrophyFishManager)
loadModule(TrophyFishFillet())
loadModule(TrophyFishMessages())
@@ -501,6 +523,7 @@ class SkyHanniMod {
loadModule(GardenVisitorFeatures())
loadModule(GardenInventoryNumbers())
loadModule(GardenVisitorTimer())
+ loadModule(MinionXp())
loadModule(GardenNextPlotPrice())
loadModule(GardenCropMilestoneDisplay)
loadModule(GardenCustomKeybinds)
@@ -564,6 +587,9 @@ class SkyHanniMod {
loadModule(PlayerTabComplete)
loadModule(GetFromSacksTabComplete)
loadModule(SlayerProfitTracker)
+ loadModule(FishingProfitTracker)
+ loadModule(FishingTrackerCategoryManager)
+ loadModule(FishingProfitPlayerMoving)
loadModule(SlayerItemsOnGround())
loadModule(RestorePieceOfWizardPortalLore())
loadModule(QuickModMenuSwitch)
@@ -611,7 +637,7 @@ class SkyHanniMod {
loadModule(AccountUpgradeReminder())
loadModule(PetExpTooltip())
loadModule(Translator())
- loadModule(GardenPlotBorders())
+ loadModule(GardenPlotBorders)
loadModule(CosmeticFollowingLine())
loadModule(SuperpairsClicksAlert())
loadModule(PowderTracker)
@@ -634,6 +660,10 @@ class SkyHanniMod {
loadModule(DungeonFinderFeatures())
loadModule(PabloHelper())
loadModule(FishingBaitWarnings())
+ loadModule(PestSpawn())
+ loadModule(PestSpawnTimer)
+ loadModule(PestFinder())
+ loadModule(SprayFeatures())
init()
diff --git a/src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt b/src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt
index cd7fa0c59..3336fcae3 100644
--- a/src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt
@@ -2,8 +2,8 @@ package at.hannibal2.skyhanni.api
import at.hannibal2.skyhanni.events.CollectionUpdateEvent
import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
+import at.hannibal2.skyhanni.events.ItemAddEvent
import at.hannibal2.skyhanni.events.ProfileJoinEvent
-import at.hannibal2.skyhanni.events.entity.ItemAddInInventoryEvent
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzUtils
@@ -18,7 +18,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class CollectionAPI {
// TODO USE SH-REPO
- private val counterPattern = "(?:.*) §e(?<amount>.*)§6\\/(?:.*)".toPattern()
+ private val counterPattern = ".* §e(?<amount>.*)§6/.*".toPattern()
private val singleCounterPattern = "§7Total Collected: §e(?<amount>.*)".toPattern()
@SubscribeEvent
@@ -69,9 +69,12 @@ class CollectionAPI {
}
@SubscribeEvent
- fun onItemAdd(event: ItemAddInInventoryEvent) {
- // TODO add support for replenish (higher collection than actual items in inv)
+ fun onItemAdd(event: ItemAddEvent) {
val internalName = event.internalName
+ val (_, amount) = NEUItems.getMultiplier(internalName)
+ if (amount > 1) return
+
+ // TODO add support for replenish (higher collection than actual items in inv)
if (internalName.getItemStackOrNull() == null) {
LorenzUtils.debug("CollectionAPI.addFromInventory: item is null for '$internalName'")
return
diff --git a/src/main/java/at/hannibal2/skyhanni/api/DataWatcherAPI.kt b/src/main/java/at/hannibal2/skyhanni/api/DataWatcherAPI.kt
new file mode 100644
index 000000000..4eb107554
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/api/DataWatcherAPI.kt
@@ -0,0 +1,21 @@
+package at.hannibal2.skyhanni.api
+
+import at.hannibal2.skyhanni.events.DataWatcherUpdatedEvent
+import at.hannibal2.skyhanni.events.EntityCustomNameUpdateEvent
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+class DataWatcherAPI {
+
+ private val DATA_VALUE_CUSTOM_NAME = 2
+
+ @SubscribeEvent
+ fun onDataWatcherUpdate(event: DataWatcherUpdatedEvent) {
+ for (updatedEntry in event.updatedEntries) {
+ if (updatedEntry.dataValueId == DATA_VALUE_CUSTOM_NAME) {
+ EntityCustomNameUpdateEvent(event.entity.customNameTag, event.entity).postAndCatch()
+ }
+ }
+ }
+
+ // TODO move EntityHealthUpdateEvent logic from EntityData in here
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt b/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt
index ddd51b18f..04e01b565 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt
@@ -2,17 +2,21 @@ package at.hannibal2.skyhanni.config
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.data.IslandType
+import at.hannibal2.skyhanni.data.jsonobjects.local.FriendsJson
+import at.hannibal2.skyhanni.data.jsonobjects.local.JacobContestsJson
+import at.hannibal2.skyhanni.data.jsonobjects.local.KnownFeaturesJson
import at.hannibal2.skyhanni.features.fishing.trophy.TrophyRarity
import at.hannibal2.skyhanni.features.misc.update.UpdateManager
import at.hannibal2.skyhanni.utils.LorenzLogger
import at.hannibal2.skyhanni.utils.LorenzRarity
+import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzVec
import at.hannibal2.skyhanni.utils.NEUInternalName
import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
import at.hannibal2.skyhanni.utils.NEUItems
-import at.hannibal2.skyhanni.utils.jsonobjects.FriendsJson
-import at.hannibal2.skyhanni.utils.jsonobjects.JacobContestsJson
-import at.hannibal2.skyhanni.utils.jsonobjects.KnownFeaturesJson
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
+import at.hannibal2.skyhanni.utils.SimpleTimeMark.Companion.asTimeMark
+import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker
import com.google.gson.GsonBuilder
import com.google.gson.JsonObject
import com.google.gson.TypeAdapter
@@ -37,6 +41,8 @@ import java.nio.file.StandardCopyOption
import java.util.UUID
import kotlin.concurrent.fixedRateTimer
+typealias TrackerDisplayMode = SkyHanniTracker.DefaultDisplayMode
+
class ConfigManager {
companion object {
val gson = GsonBuilder().setPrettyPrinting()
@@ -108,6 +114,24 @@ class ConfigManager {
return IslandType.valueOf(reader.nextString().uppercase())
}
}.nullSafe())
+ .registerTypeAdapter(TrackerDisplayMode::class.java, object : TypeAdapter<TrackerDisplayMode>() {
+ override fun write(out: JsonWriter, value: TrackerDisplayMode) {
+ out.value(value.name)
+ }
+
+ override fun read(reader: JsonReader): TrackerDisplayMode {
+ return TrackerDisplayMode.valueOf(reader.nextString())
+ }
+ }.nullSafe())
+ .registerTypeAdapter(SimpleTimeMark::class.java, object : TypeAdapter<SimpleTimeMark>() {
+ override fun write(out: JsonWriter, value: SimpleTimeMark) {
+ out.value(value.toMillis())
+ }
+
+ override fun read(reader: JsonReader): SimpleTimeMark {
+ return reader.nextString().toLong().asTimeMark()
+ }
+ }.nullSafe())
.enableComplexMapKeySerialization()
.create()
@@ -168,7 +192,17 @@ class ConfigManager {
output = if (fileType == ConfigFileType.FEATURES) {
val jsonObject = gson.fromJson(bufferedReader.readText(), JsonObject::class.java)
val newJsonObject = ConfigUpdaterMigrator.fixConfig(jsonObject)
- gson.fromJson(newJsonObject, defaultValue.javaClass)
+ val run = { gson.fromJson(newJsonObject, defaultValue.javaClass) }
+ if (LorenzUtils.isInDevEnviromen()) {
+ try {
+ run()
+ } catch (e: Throwable) {
+ e.printStackTrace()
+ LorenzUtils.shutdownMinecraft("Config is corrupt inside developement enviroment.")
+ }
+ } else {
+ run()
+ }
} else {
gson.fromJson(bufferedReader.readText(), defaultValue.javaClass)
}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt b/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt
index 0db542e12..0f638e22b 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt
+++ b/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt
@@ -9,7 +9,7 @@ import com.google.gson.JsonPrimitive
object ConfigUpdaterMigrator {
val logger = LorenzLogger("ConfigMigration")
- const val CONFIG_VERSION = 9
+ const val CONFIG_VERSION = 12
fun JsonElement.at(chain: List<String>, init: Boolean): JsonElement? {
if (chain.isEmpty()) return this
if (this !is JsonObject) return null
@@ -34,7 +34,7 @@ object ConfigUpdaterMigrator {
}
}
- fun move(since: Int, oldPath: String, newPath: String, transform: (JsonElement) -> JsonElement = { it }) {
+ fun move(since: Int, oldPath: String, newPath: String = oldPath, transform: (JsonElement) -> JsonElement = { it }) {
if (since <= oldVersion) {
logger.log("Skipping move from $oldPath to $newPath ($since <= $oldVersion)")
return
diff --git a/src/main/java/at/hannibal2/skyhanni/config/HasLegacyId.java b/src/main/java/at/hannibal2/skyhanni/config/HasLegacyId.java
new file mode 100644
index 000000000..a867cb570
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/HasLegacyId.java
@@ -0,0 +1,26 @@
+package at.hannibal2.skyhanni.config;
+
+/**
+ * The interface HasLegacyId.
+ * To be used for config elements that are being migrated from ArrayLists to Enums.
+ * A legacyId is not needed for new elements.
+ */
+public interface HasLegacyId {
+
+ /**
+ * Gets display string.
+ *
+ * @return the display string
+ */
+ String toString();
+
+ /**
+ * Gets legacy id. This is used for legacy configs that are being migrated to enums.
+ * New elements do not need a legacyId, and should return -1
+ *
+ * @return the legacy id
+ */
+ default int getLegacyId() {
+ return -1;
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/Storage.java b/src/main/java/at/hannibal2/skyhanni/config/Storage.java
index b21361b6f..52f10c40e 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/Storage.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/Storage.java
@@ -5,9 +5,11 @@ import at.hannibal2.skyhanni.features.combat.endernodetracker.EnderNodeTracker;
import at.hannibal2.skyhanni.features.combat.ghostcounter.GhostData;
import at.hannibal2.skyhanni.features.dungeon.DungeonAPI;
import at.hannibal2.skyhanni.features.event.jerry.frozentreasure.FrozenTreasureTracker;
+import at.hannibal2.skyhanni.features.fishing.tracker.FishingProfitTracker;
import at.hannibal2.skyhanni.features.fishing.trophy.TrophyRarity;
import at.hannibal2.skyhanni.features.garden.CropAccessory;
import at.hannibal2.skyhanni.features.garden.CropType;
+import at.hannibal2.skyhanni.features.garden.GardenPlotAPI;
import at.hannibal2.skyhanni.features.garden.farming.ArmorDropTracker;
import at.hannibal2.skyhanni.features.garden.farming.DicerDropTracker;
import at.hannibal2.skyhanni.features.garden.fortuneguide.FarmingItems;
@@ -19,13 +21,16 @@ import at.hannibal2.skyhanni.features.rift.area.westvillage.KloonTerminal;
import at.hannibal2.skyhanni.features.slayer.SlayerProfitTracker;
import at.hannibal2.skyhanni.utils.LorenzVec;
import at.hannibal2.skyhanni.utils.NEUInternalName;
+import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker;
import com.google.gson.annotations.Expose;
import net.minecraft.item.ItemStack;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.UUID;
public class Storage {
@@ -50,6 +55,9 @@ public class Storage {
public Boolean contestSendingAsked = false;
@Expose
+ public Map<String, SkyHanniTracker.DisplayMode> trackerDisplayModes = new HashMap<>();
+
+ @Expose
public Map<UUID, PlayerSpecific> players = new HashMap<>();
public static class PlayerSpecific {
@@ -71,6 +79,19 @@ public class Storage {
@Expose
public List<String> guildMembers = new ArrayList<>();
+
+ @Expose
+ public WinterStorage winter = new WinterStorage();
+
+ public static class WinterStorage {
+
+ @Expose
+ public Set<String> playersThatHaveBeenGifted = new HashSet<>();
+
+ @Expose
+ public int amountGifted = 0;
+ }
+
}
public static class ProfileSpecific {
@@ -222,6 +243,9 @@ public class Storage {
}
@Expose
+ public Map<Integer, GardenPlotAPI.PlotData> plotData = new HashMap<>();
+
+ @Expose
public Map<CropType, LorenzVec> cropStartLocations = new HashMap<>();
@Expose
@@ -389,5 +413,15 @@ public class Storage {
@Expose
public Map<DungeonAPI.DungeonFloor, Integer> bosses = new HashMap<>();
}
+
+ @Expose
+ public FishingStorage fishing = new FishingStorage();
+
+ public static class FishingStorage {
+
+ @Expose
+ public FishingProfitTracker.Data fishingProfitTracker = new FishingProfitTracker.Data();
+
+ }
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt
index 8e4791901..1a0b41629 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt
+++ b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt
@@ -7,8 +7,8 @@ import at.hannibal2.skyhanni.data.ChatManager
import at.hannibal2.skyhanni.data.GardenCropMilestonesCommunityFix
import at.hannibal2.skyhanni.data.GuiEditManager
import at.hannibal2.skyhanni.data.PartyAPI
-import at.hannibal2.skyhanni.features.bingo.BingoCardDisplay
-import at.hannibal2.skyhanni.features.bingo.BingoNextStepHelper
+import at.hannibal2.skyhanni.features.bingo.card.BingoCardDisplay
+import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.BingoNextStepHelper
import at.hannibal2.skyhanni.features.chat.Translator
import at.hannibal2.skyhanni.features.combat.endernodetracker.EnderNodeTracker
import at.hannibal2.skyhanni.features.combat.ghostcounter.GhostUtil
@@ -18,6 +18,7 @@ import at.hannibal2.skyhanni.features.event.diana.InquisitorWaypointShare
import at.hannibal2.skyhanni.features.event.jerry.frozentreasure.FrozenTreasureTracker
import at.hannibal2.skyhanni.features.fame.AccountUpgradeReminder
import at.hannibal2.skyhanni.features.fame.CityProjectFeatures
+import at.hannibal2.skyhanni.features.fishing.tracker.FishingProfitTracker
import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.features.garden.GardenCropTimeCommand
import at.hannibal2.skyhanni.features.garden.GardenNextJacobContest
@@ -72,7 +73,6 @@ object Commands {
ConfigGuiManager.openConfigGui(it.joinToString(" "))
}
} else {
- val arr = mutableListOf<String>()
ConfigGuiManager.openConfigGui()
}
}
@@ -174,6 +174,7 @@ object Commands {
) { EnderNodeTracker.resetCommand(it) }
registerCommand("shresetarmordroptracker", "Resets the Armor Drop Tracker") { ArmorDropTracker.resetCommand(it) }
registerCommand("shresetfrozentreasuretracker", "Resets the Frozen Treasure Tracker") { FrozenTreasureTracker.resetCommand(it) }
+ registerCommand("shresetfishingtracker", "Resets the Frozen Treasure Tracker") { FishingProfitTracker.resetCommand(it) }
registerCommand("shbingotoggle", "Toggle the bingo card display mode") { BingoCardDisplay.toggleCommand() }
registerCommand(
"shfarmingprofile",
@@ -211,6 +212,10 @@ object Commands {
"Reset data about minion profit and the name display on the private island"
) { MinionFeatures.clearMinionData() }
registerCommand(
+ "shwhereami",
+ "Print current island in chat"
+ ) { SkyHanniDebugsAndTests.whereami() }
+ registerCommand(
"shconfig",
"Search or reset config elements §c(warning, dangerous!)"
) { SkyHanniConfigSearchResetCommand.command(it) }
@@ -381,7 +386,7 @@ object Commands {
@JvmStatic
fun openFortuneGuide() {
if (!LorenzUtils.inSkyBlock) {
- LorenzUtils.chat("§cJoin SkyBlock to open the fortune guide!", false)
+ LorenzUtils.userError("Join SkyBlock to open the fortune guide!")
} else {
CaptureFarmingGear.captureFarmingGear()
SkyHanniMod.screenToOpen = FFGuideGUI()
@@ -391,7 +396,7 @@ object Commands {
@JvmStatic
fun openVisualWords() {
if (!LorenzUtils.onHypixel) {
- LorenzUtils.chat("§cYou need to join Hypixel to use this feature!", false)
+ LorenzUtils.userError("You need to join Hypixel to use this feature!")
} else {
if (VisualWordGui.sbeConfigPath.exists()) VisualWordGui.drawImport = true
SkyHanniMod.screenToOpen = VisualWordGui()
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/chat/FilterTypesConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/chat/FilterTypesConfig.java
index 42cca5b59..f37e66705 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/chat/FilterTypesConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/chat/FilterTypesConfig.java
@@ -74,6 +74,12 @@ public class FilterTypesConfig {
@FeatureToggle
public boolean profileJoin = true;
+ @Expose
+ @ConfigOption(name = "Fire Sale", desc = "Hide the repeating fire sale reminder chat messages.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean fireSale = true;
+
//TODO remove
@Expose
@ConfigOption(name = "Others", desc = "Hide other annoying messages.")
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/combat/EnderNodeConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/combat/EnderNodeConfig.java
index 0fd962084..37f6cdfb8 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/combat/EnderNodeConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/EnderNodeConfig.java
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.config.features.combat;
import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.HasLegacyId;
import at.hannibal2.skyhanni.config.core.config.Position;
import com.google.gson.annotations.Expose;
import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
@@ -12,6 +13,23 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.COINS_MADE;
+import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.ENCHANTED_ENDER_PEARL;
+import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.ENCHANTED_END_STONE;
+import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.ENCHANTED_OBSIDIAN;
+import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.ENDERMAN_PET;
+import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.ENDERMITE_NEST;
+import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.ENDER_ARMOR;
+import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.GRAND_XP_BOTTLE;
+import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.MAGICAL_RUNE_I;
+import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.MITE_GEL;
+import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.NODES_MINED;
+import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.SHRIMP_THE_FISH;
+import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.SPACER_1;
+import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.SPACER_2;
+import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.TITANIC_XP_BOTTLE;
+import static at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry.TITLE;
+
public class EnderNodeConfig {
@Expose
@ConfigOption(
@@ -28,36 +46,76 @@ public class EnderNodeConfig {
name = "Text Format",
desc = "Drag text to change the appearance of the overlay."
)
- @ConfigEditorDraggableList(
- exampleText = {
- "§5§lEnder Node Tracker",
- "§d1,303 Ender Nodes Mined",
- "§615.3M Coins Made",
- " ",
- "§b123 §cEndermite Nest",
- "§b832 §aEnchanted End Stone",
- "§b230 §aEnchanted Obsidian",
- "§b1630 §aEnchanted Ender Pearl",
- "§b85 §aGrand Experience Bottle",
- "§b4 §9Titanic Experience Bottle",
- "§b15 §9End Stone Shulker",
- "§b53 §9End Stone Geode",
- "§b10 §d◆ Magical Rune I",
- "§b24 §5Ender Gauntlet",
- "§b357 §5Mite Gel",
- "§b2 §cShrimp The Fish",
- " ",
- "§b200 §5Ender Armor",
- "§b24 §5Ender Helmet",
- "§b24 §5Ender Chestplate",
- "§b24 §5Ender Leggings",
- "§b24 §5Ender Boots",
- "§b24 §5Ender Necklace",
- "§f10§7-§a8§7-§93§7-§52§7-§61 §fEnderman Pet",
- " "
+ @ConfigEditorDraggableList()
+ public Property<List<EnderNodeDisplayEntry>> textFormat = Property.of(new ArrayList<>(Arrays.asList(
+ TITLE,
+ NODES_MINED,
+ COINS_MADE,
+ SPACER_1,
+ ENDERMITE_NEST,
+ ENCHANTED_END_STONE,
+ ENCHANTED_OBSIDIAN,
+ ENCHANTED_ENDER_PEARL,
+ GRAND_XP_BOTTLE,
+ TITANIC_XP_BOTTLE,
+ MAGICAL_RUNE_I,
+ MITE_GEL,
+ SHRIMP_THE_FISH,
+ SPACER_2,
+ ENDER_ARMOR,
+ ENDERMAN_PET)
+ ));
+
+ public enum EnderNodeDisplayEntry implements HasLegacyId {
+ TITLE("§5§lEnder Node Tracker", 0),
+ NODES_MINED("§d1,303 Ender Nodes Mined", 1),
+ COINS_MADE("§615.3M Coins Made", 2),
+ SPACER_1(" ", 3),
+ ENDERMITE_NEST("§b123 §cEndermite Nest", 4),
+ ENCHANTED_END_STONE("§b832 §aEnchanted End Stone", 5),
+ ENCHANTED_OBSIDIAN("§b230 §aEnchanted Obsidian", 6),
+ ENCHANTED_ENDER_PEARL("§b1630 §aEnchanted Ender Pearl", 7),
+ GRAND_XP_BOTTLE("§b85 §aGrand Experience Bottle", 8),
+ TITANIC_XP_BOTTLE("§b4 §9Titanic Experience Bottle", 9),
+ END_STONE_SHULKER("§b15 §9End Stone Shulker", 10),
+ END_STONE_GEODE("§b53 §9End Stone Geode", 11),
+ MAGICAL_RUNE_I("§b10 §d◆ Magical Rune I", 12),
+ ENDER_GAUNTLET("§b24 §5Ender Gauntlet", 13),
+ MITE_GEL("§b357 §5Mite Gel", 14),
+ SHRIMP_THE_FISH("§b2 §cShrimp The Fish", 15),
+ SPACER_2(" ", 16),
+ ENDER_ARMOR("§b200 §5Ender Armor", 17),
+ ENDER_HELMET("§b24 §5Ender Helmet", 18),
+ ENDER_CHESTPLATE("§b24 §5Ender Chestplate", 19),
+ ENDER_LEGGINGS("§b24 §5Ender Leggings", 20),
+ ENDER_BOOTS("§b24 §5Ender Boots", 21),
+ ENDER_NECKLACE("§b24 §5Ender Necklace", 22),
+ ENDERMAN_PET("§f10§7-§a8§7-§93§7-§52§7-§61 §fEnderman Pet", 23),
+ ;
+
+ private final String str;
+ private final int legacyId;
+
+ EnderNodeDisplayEntry(String str, int legacyId) {
+ this.str = str;
+ this.legacyId = legacyId;
}
- )
- public Property<List<Integer>> textFormat = Property.of(new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 14, 15, 16, 17, 23)));
+
+ // Constructor if new enum elements are added post-migration
+ EnderNodeDisplayEntry(String str) {
+ this(str, -1);
+ }
+
+ @Override
+ public int getLegacyId() {
+ return legacyId;
+ }
+
+ @Override
+ public String toString() {
+ return str;
+ }
+ }
@Expose
public Position position = new Position(10, 80, false, true);
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/combat/MobsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/combat/MobsConfig.java
index 77731d854..3514c6729 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/combat/MobsConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/MobsConfig.java
@@ -6,11 +6,6 @@ import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
import io.github.moulberry.moulconfig.annotations.ConfigOption;
public class MobsConfig {
-
- @Expose
- @ConfigOption(name = "Highlighters", desc = "")
- public boolean highlighters = false;
-
@Expose
@ConfigOption(name = "Area Boss", desc = "Highlight Golden Ghoul, Old Wolf, Voidling Extremist and Millenia-Aged Blaze.")
@ConfigEditorBoolean
@@ -57,10 +52,6 @@ public class MobsConfig {
public boolean arachneBossHighlighter = true;
@Expose
- @ConfigOption(name = "Respawn Timers", desc = "")
- public boolean timers = false;
-
- @Expose
@ConfigOption(
name = "Area Boss",
desc = "Show a timer when Golden Ghoul, Old Wolf, Voidling Extremist or Millenia-Aged Blaze respawns. " +
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/combat/damageindicator/DamageIndicatorConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/combat/damageindicator/DamageIndicatorConfig.java
index c77e5f3f0..6986d706c 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/combat/damageindicator/DamageIndicatorConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/damageindicator/DamageIndicatorConfig.java
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.config.features.combat.damageindicator;
import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.HasLegacyId;
import com.google.gson.annotations.Expose;
import io.github.moulberry.moulconfig.annotations.Accordion;
import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
@@ -12,6 +13,22 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.ARACHNE;
+import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.DIANA_MOBS;
+import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.DUNGEON_ALL;
+import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.GARDEN_PESTS;
+import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.INFERNO_DEMONLORD;
+import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.NETHER_MINI_BOSSES;
+import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.REINDRAKE;
+import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.REVENANT_HORROR;
+import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.RIFTSTALKER_BLOODFIEND;
+import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.SEA_CREATURES;
+import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.SVEN_PACKMASTER;
+import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.TARANTULA_BROODFATHER;
+import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.THE_RIFT_BOSSES;
+import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.VANQUISHER;
+import static at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry.VOIDGLOOM_SERAPH;
+
public class DamageIndicatorConfig {
@Expose
@@ -37,38 +54,79 @@ public class DamageIndicatorConfig {
name = "Select Boss",
desc = "Change what type of boss you want the damage indicator be enabled for."
)
- @ConfigEditorDraggableList(
- exampleText = {
- "§bDungeon All",
- "§bNether Mini Bosses",
- "§bVanquisher",
- "§bEndstone Protector (not tested)",
- "§bEnder Dragon (not finished)",
- "§bRevenant Horror",
- "§bTarantula Broodfather",
- "§bSven Packmaster",
- "§bVoidgloom Seraph",
- "§bInferno Demonlord",
- "§bHeadless Horseman (bugged)",
- "§bDungeon Floor 1",
- "§bDungeon Floor 2",
- "§bDungeon Floor 3",
- "§bDungeon Floor 4",
- "§bDungeon Floor 5",
- "§bDungeon Floor 6",
- "§bDungeon Floor 7",
- "§bDiana Mobs",
- "§bSea Creatures",
- "Dummy",
- "§bArachne",
- "§bThe Rift Bosses",
- "§bRiftstalker Bloodfiend",
- "§6Reindrake"
- }
- )
+ @ConfigEditorDraggableList()
//TODO only show currently working and tested features
- public List<Integer> bossesToShow = new ArrayList<>(Arrays.asList(0, 1, 2, 5, 6, 7, 8, 9, 18, 19, 21, 22, 23, 24));
+ public List<DamageIndicatorBossEntry> bossesToShow = new ArrayList<>(Arrays.asList(
+ DUNGEON_ALL,
+ NETHER_MINI_BOSSES,
+ VANQUISHER,
+ REVENANT_HORROR,
+ TARANTULA_BROODFATHER,
+ SVEN_PACKMASTER,
+ VOIDGLOOM_SERAPH,
+ INFERNO_DEMONLORD,
+ DIANA_MOBS,
+ SEA_CREATURES,
+ ARACHNE,
+ THE_RIFT_BOSSES,
+ RIFTSTALKER_BLOODFIEND,
+ REINDRAKE,
+ GARDEN_PESTS
+
+ ));
+ public enum DamageIndicatorBossEntry implements HasLegacyId {
+ DUNGEON_ALL("§bDungeon All", 0),
+ NETHER_MINI_BOSSES("§bNether Mini Bosses", 1),
+ VANQUISHER("§bVanquisher", 2),
+ ENDERSTONE_PROTECTOR("§bEndstone Protector (not tested)", 3),
+ ENDER_DRAGON("§bEnder Dragon (not finished)", 4),
+ REVENANT_HORROR("§bRevenant Horror", 5),
+ TARANTULA_BROODFATHER("§bTarantula Broodfather", 6),
+ SVEN_PACKMASTER("§bSven Packmaster", 7),
+ VOIDGLOOM_SERAPH("§bVoidgloom Seraph", 8),
+ INFERNO_DEMONLORD("§bInferno Demonlord", 9),
+ HEADLESS_HORSEMAN("§bHeadless Horseman (bugged)", 10),
+ DUNGEON_FLOOR_1("§bDungeon Floor 1", 11),
+ DUNGEON_FLOOR_2("§bDungeon Floor 2", 12),
+ DUNGEON_FLOOR_3("§bDungeon Floor 3", 13),
+ DUNGEON_FLOOR_4("§bDungeon Floor 4", 14),
+ DUNGEON_FLOOR_5("§bDungeon Floor 5", 15),
+ DUNGEON_FLOOR_6("§bDungeon Floor 6", 16),
+ DUNGEON_FLOOR_7("§bDungeon Floor 7", 17),
+ DIANA_MOBS("§bDiana Mobs", 18),
+ SEA_CREATURES("§bSea Creatures", 19),
+ DUMMY("Dummy", 20),
+ ARACHNE("§bArachne", 21),
+ THE_RIFT_BOSSES("§bThe Rift Bosses", 22),
+ RIFTSTALKER_BLOODFIEND("§bRiftstalker Bloodfiend", 23),
+ REINDRAKE("§6Reindrake", 24),
+ GARDEN_PESTS("§aGarden Pests", 25),
+ ;
+
+ private final String str;
+ private final int legacyId;
+
+ DamageIndicatorBossEntry(String str, int legacyId) {
+ this.str = str;
+ this.legacyId = legacyId;
+ }
+
+ // Constructor if new enum elements are added post-migration
+ DamageIndicatorBossEntry(String str) {
+ this(str, -1);
+ }
+
+ @Override
+ public int getLegacyId() {
+ return legacyId;
+ }
+
+ @Override
+ public String toString() {
+ return str;
+ }
+ }
@Expose
@ConfigOption(name = "Hide Damage Splash", desc = "Hiding damage splashes near the damage indicator.")
@ConfigEditorBoolean
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/GhostCounterConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/GhostCounterConfig.java
index 783c4cda5..6bc8ee48d 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/GhostCounterConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/GhostCounterConfig.java
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.config.features.combat.ghostcounter;
import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.HasLegacyId;
import at.hannibal2.skyhanni.config.core.config.Position;
import at.hannibal2.skyhanni.config.features.combat.ghostcounter.textformatting.TextFormattingConfig;
import at.hannibal2.skyhanni.features.combat.ghostcounter.GhostUtil;
@@ -16,6 +17,16 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import static at.hannibal2.skyhanni.config.features.combat.ghostcounter.GhostCounterConfig.GhostDisplayEntry.AVG_MAGIC_FIND;
+import static at.hannibal2.skyhanni.config.features.combat.ghostcounter.GhostCounterConfig.GhostDisplayEntry.GHOSTS_KILLED;
+import static at.hannibal2.skyhanni.config.features.combat.ghostcounter.GhostCounterConfig.GhostDisplayEntry.GHOST_PER_SORROW;
+import static at.hannibal2.skyhanni.config.features.combat.ghostcounter.GhostCounterConfig.GhostDisplayEntry.GHOST_SINCE_SORROW;
+import static at.hannibal2.skyhanni.config.features.combat.ghostcounter.GhostCounterConfig.GhostDisplayEntry.HIGHEST_KILL_COMBO;
+import static at.hannibal2.skyhanni.config.features.combat.ghostcounter.GhostCounterConfig.GhostDisplayEntry.KILL_COMBO;
+import static at.hannibal2.skyhanni.config.features.combat.ghostcounter.GhostCounterConfig.GhostDisplayEntry.SCAVENGER_COINS;
+import static at.hannibal2.skyhanni.config.features.combat.ghostcounter.GhostCounterConfig.GhostDisplayEntry.SORROW;
+import static at.hannibal2.skyhanni.config.features.combat.ghostcounter.GhostCounterConfig.GhostDisplayEntry.TITLE;
+
public class GhostCounterConfig {
@Expose
@@ -29,31 +40,65 @@ public class GhostCounterConfig {
name = "Display Text",
desc = "Drag text to change the appearance of the overlay."
)
- @ConfigEditorDraggableList(
- exampleText = {
- "§6Ghosts Counter",
- " §bGhost Killed: 42",
- " §bSorrow: 6",
- " §bGhost since Sorrow: 1",
- " §bGhosts/Sorrow: 5",
- " §bVolta: 6",
- " §bPlasma: 8",
- " §bGhostly Boots: 1",
- " §bBag Of Cash: 4",
- " §bAvg Magic Find: 271",
- " §bScavenger Coins: 15,000",
- " §bKill Combo: 14",
- " §bHighest Kill Combo: 96",
- " §bSkill XP Gained: 145,648",
- " §bBestiary 1: 0/10",
- " §bXP/h: 810,410",
- " §bKills/h: 420",
- " §bETA: 14d",
- " §bMoney/h: 13,420,069",
- " §bMoney made: 14B"
+ @ConfigEditorDraggableList()
+ public List<GhostDisplayEntry> ghostDisplayText = new ArrayList<>(Arrays.asList(
+ TITLE,
+ GHOSTS_KILLED,
+ SORROW,
+ GHOST_SINCE_SORROW,
+ GHOST_PER_SORROW,
+ AVG_MAGIC_FIND,
+ SCAVENGER_COINS,
+ KILL_COMBO,
+ HIGHEST_KILL_COMBO
+ ));
+
+ public enum GhostDisplayEntry implements HasLegacyId {
+ TITLE("§6Ghosts Counter", 0),
+ GHOSTS_KILLED(" §bGhost Killed: 42", 1),
+ SORROW(" §bSorrow: 6", 2),
+ GHOST_SINCE_SORROW(" §bGhost since Sorrow: 1", 3),
+ GHOST_PER_SORROW(" §bGhosts/Sorrow: 5", 4),
+ VOLTA(" §bVolta: 6", 5),
+ PLASMA(" §bPlasma: 8", 6),
+ GHOSTLY_BOOTS(" §bGhostly Boots: 1", 7),
+ BAG_OF_CASH(" §bBag Of Cash: 4", 8),
+ AVG_MAGIC_FIND(" §bAvg Magic Find: 271", 9),
+ SCAVENGER_COINS(" §bScavenger Coins: 15,000", 10),
+ KILL_COMBO(" §bKill Combo: 14", 11),
+ HIGHEST_KILL_COMBO(" §bHighest Kill Combo: 96", 12),
+ SKILL_XP_GAINED(" §bSkill XP Gained: 145,648", 13),
+ BESTIARY(" §bBestiary 1: 0/10", 14),
+ XP_PER_HOUR(" §bXP/h: 810,410", 15),
+ KILLS_PER_HOUR(" §bKills/h: 420", 16),
+ ETA(" §bETA: 14d", 17),
+ MONEY_PER_HOUR(" §bMoney/h: 13,420,069", 18),
+ MONEY_MADE(" §bMoney made: 14B", 19),
+ ;
+
+ private final String str;
+ private final int legacyId;
+
+ GhostDisplayEntry(String str, int legacyId) {
+ this.str = str;
+ this.legacyId = legacyId;
}
- )
- public List<Integer> ghostDisplayText = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 9, 10, 11, 12));
+
+ // Constructor if new enum elements are added post-migration
+ GhostDisplayEntry(String str) {
+ this(str, -1);
+ }
+
+ @Override
+ public int getLegacyId() {
+ return legacyId;
+ }
+
+ @Override
+ public String toString() {
+ return str;
+ }
+ }
@ConfigOption(name = "Text Formatting", desc = "")
@Accordion
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/TextFormattingConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/TextFormattingConfig.java
index 750b3ae2c..1414a986d 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/TextFormattingConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/combat/ghostcounter/textformatting/TextFormattingConfig.java
@@ -35,11 +35,11 @@ public class TextFormattingConfig {
public String titleFormat = "&6Ghost Counter";
@Expose
- @ConfigOption(name = "Ghost Killed", desc = "Ghost Killed line.\n§e%value% §ris replaced with\n" +
- "Ghost Killed.\n" +
- "§e%session% §7is replaced with Ghost killed")
+ @ConfigOption(name = "Ghosts Killed", desc = "Ghosts Killed line.\n§e%value% §ris replaced with\n" +
+ "Ghosts Killed.\n" +
+ "§e%session% §7is replaced with Ghosts killed")
@ConfigEditorText
- public String ghostKilledFormat = " &6Ghost Killed: &b%value% &7(%session%)";
+ public String ghostKilledFormat = " &6Ghosts Killed: &b%value% &7(%session%)";
@Expose
@ConfigOption(name = "Sorrows", desc = "Sorrows drop line.\n" +
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/commands/TabCompleteConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/commands/TabCompleteConfig.java
index 6e3420a59..b7edd0e07 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/commands/TabCompleteConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/commands/TabCompleteConfig.java
@@ -15,6 +15,7 @@ public class TabCompleteConfig {
@Expose
@ConfigOption(name = "Island Players", desc = "Tab complete other players on the same island.")
+ @ConfigEditorBoolean
public boolean islandPlayers = true;
@Expose
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/dev/DebugConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/dev/DebugConfig.java
index 7f7b9af63..bdce11628 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/dev/DebugConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/dev/DebugConfig.java
@@ -85,4 +85,10 @@ public class DebugConfig {
@ConfigOption(name = "Hot Swap Detection", desc = "Show chat messages when Hot Swap starts and ends.")
@ConfigEditorBoolean
public boolean hotSwapDetection = false;
+
+ @Expose
+ @ConfigOption(name = "SkyHanni Event Counter", desc = "Count once per second how many skyhanni events gets triggered, " +
+ "show the total amount in console output.")
+ @ConfigEditorBoolean
+ public boolean eventCounter = false;
}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoCardConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoCardConfig.java
index 44dd23ec4..ae382d25d 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoCardConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoCardConfig.java
@@ -42,4 +42,14 @@ public class BingoCardConfig {
@Expose
public Position bingoCardPos = new Position(10, 10, false, true);
+
+ @Expose
+ @ConfigOption(name = "Next Tip Duration", desc = "Show the duration until the next hidden personal goal gets a tip revealed.")
+ @ConfigEditorBoolean
+ public Property<Boolean> nextTipDuration = Property.of(true);
+
+ @Expose
+ @ConfigOption(name = "Hide Difficulty When Done", desc = "Remove the background difficulty color in the bingo card inventory when the goal is done.")
+ @ConfigEditorBoolean
+ public boolean hideDoneDifficulty = true;
}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoConfig.java
index 816f8a194..24fdf9732 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/bingo/BingoConfig.java
@@ -26,5 +26,11 @@ public class BingoConfig {
public boolean minionCraftHelperEnabled = true;
@Expose
+ @ConfigOption(name = "Show Progress to T1", desc = "Show tier 1 Minion Crafts in the Helper display even if needed items are not fully collected.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean minionCraftHelperProgressFirst = false;
+
+ @Expose
public Position minionCraftHelperPos = new Position(10, 10, false, true);
}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/FrozenTreasureConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/FrozenTreasureConfig.java
index 2b41265a6..a1f378d08 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/FrozenTreasureConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/FrozenTreasureConfig.java
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.config.features.event.winter;
import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.HasLegacyId;
import at.hannibal2.skyhanni.config.core.config.Position;
import com.google.gson.annotations.Expose;
import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
@@ -11,6 +12,20 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.COMPACT_PROCS;
+import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.ENCHANTED_ICE;
+import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.ENCHANTED_PACKED_ICE;
+import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.GLACIAL_FRAGMENT;
+import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.GLACIAL_TALISMAN;
+import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.GREEN_GIFT;
+import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.ICE_PER_HOUR;
+import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.RED_GIFT;
+import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.SPACER_1;
+import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.TITLE;
+import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.TOTAL_ICE;
+import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.TREASURES_MINED;
+import static at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry.WHITE_GIFT;
+
public class FrozenTreasureConfig {
@Expose
@@ -28,28 +43,65 @@ public class FrozenTreasureConfig {
name = "Text Format",
desc = "Drag text to change the appearance of the overlay."
)
- @ConfigEditorDraggableList(
- exampleText = {
- "§1§lFrozen Treasure Tracker",
- "§61,636 Treasures Mined",
- "§33.2m Total Ice",
- "§3342,192 Ice/hr",
- "§81,002 Compact Procs",
- " ",
- "§b182 §fWhite Gift",
- "§b94 §aGreen Gift",
- "§b17 §9§cRed Gift",
- "§b328 §fPacked Ice",
- "§b80 §aEnchanted Ice",
- "§b4 §9Enchanted Packed Ice",
- "§b182 §aIce Bait",
- "§b3 §aGlowy Chum Bait",
- "§b36 §5Glacial Fragment",
- "§b6 §fGlacial Talisman",
- " ",
+ @ConfigEditorDraggableList()
+ public List<FrozenTreasureDisplayEntry> textFormat = new ArrayList<>(Arrays.asList(
+ TITLE,
+ TREASURES_MINED,
+ TOTAL_ICE,
+ ICE_PER_HOUR,
+ COMPACT_PROCS,
+ SPACER_1,
+ WHITE_GIFT,
+ GREEN_GIFT,
+ RED_GIFT,
+ ENCHANTED_ICE,
+ ENCHANTED_PACKED_ICE,
+ GLACIAL_FRAGMENT,
+ GLACIAL_TALISMAN
+ ));
+
+ public enum FrozenTreasureDisplayEntry implements HasLegacyId {
+ TITLE("§1§lFrozen Treasure Tracker", 0),
+ TREASURES_MINED("§61,636 Treasures Mined", 1),
+ TOTAL_ICE("§33.2m Total Ice", 2),
+ ICE_PER_HOUR("§3342,192 Ice/hr", 3),
+ COMPACT_PROCS("§81,002 Compact Procs", 4),
+ SPACER_1(" ", 5),
+ WHITE_GIFT("§b182 §fWhite Gift", 6),
+ GREEN_GIFT("§b94 §aGreen Gift", 7),
+ RED_GIFT("§b17 §9§cRed Gift", 8),
+ PACKED_ICE("§b328 §fPacked Ice", 9),
+ ENCHANTED_ICE("§b80 §aEnchanted Ice", 10),
+ ENCHANTED_PACKED_ICE("§b4 §9Enchanted Packed Ice", 11),
+ ICE_BAIT("§b182 §aIce Bait", 12),
+ GLOWY_CHUM_BAIT("§b3 §aGlowy Chum Bait", 13),
+ GLACIAL_FRAGMENT("§b36 §5Glacial Fragment", 14),
+ GLACIAL_TALISMAN("§b6 §fGlacial Talisman", 15),
+ SPACER_2(" ", 16);
+
+ private final String str;
+ private final int legacyId;
+
+ FrozenTreasureDisplayEntry(String str, int legacyId) {
+ this.str = str;
+ this.legacyId = legacyId;
}
- )
- public List<Integer> textFormat = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 14, 15));
+
+ // Constructor if new enum elements are added post-migration
+ FrozenTreasureDisplayEntry(String str) {
+ this(str, -1);
+ }
+
+ @Override
+ public int getLegacyId() {
+ return legacyId;
+ }
+
+ @Override
+ public String toString() {
+ return str;
+ }
+ }
@Expose
@ConfigOption(name = "Only in Glacial Cave", desc = "Only shows the overlay while in the Glacial Cave.")
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/GiftingOpportunitiesConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/GiftingOpportunitiesConfig.java
new file mode 100644
index 000000000..f303099b4
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/GiftingOpportunitiesConfig.java
@@ -0,0 +1,27 @@
+package at.hannibal2.skyhanni.config.features.event.winter;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class GiftingOpportunitiesConfig {
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Highlight players who you haven't given gifts to yet.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Only While Holding Gift", desc = "Only highlight ungifted players while holding a gift.")
+ @ConfigEditorBoolean
+ public boolean highlighWithGiftOnly = true;
+
+
+ @Expose
+ @ConfigOption(name = "Use Armor Stands", desc = "Make use of armor stands to stop highlighting players. " +
+ "This is a bit inaccurate, but it can help with people you gifted before this feature was used.")
+ @ConfigEditorBoolean
+ public boolean useArmorStandDetection = false;
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/UniqueGiftConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/UniqueGiftConfig.java
new file mode 100644
index 000000000..5ccc823c5
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/UniqueGiftConfig.java
@@ -0,0 +1,19 @@
+package at.hannibal2.skyhanni.config.features.event.winter;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.core.config.Position;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class UniqueGiftConfig {
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Show in a display how many unique players you have given gifts to in the winter 2023 event." +
+ " Open §e/opengenerowmenu §7to sync up!")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ public Position position = new Position(100, 100, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/WinterConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/WinterConfig.java
index 8af9472b1..79ac983c2 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/WinterConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/winter/WinterConfig.java
@@ -14,6 +14,16 @@ public class WinterConfig {
@Accordion
public FrozenTreasureConfig frozenTreasureTracker = new FrozenTreasureConfig();
+ @Accordion
+ @Expose
+ @ConfigOption(name = "Unique Gifting Opportunities", desc = "Highlight players who you haven't given gifts to yet.")
+ public GiftingOpportunitiesConfig giftingOpportunities = new GiftingOpportunitiesConfig();
+
+ @Accordion
+ @Expose
+ @ConfigOption(name = "Unique Gift Counter", desc = "Keep track how many unique players you have given gifts to.")
+ public UniqueGiftConfig uniqueGiftCounter = new UniqueGiftConfig();
+
@Expose
@ConfigOption(name = "Island Close Time", desc = "While on the Winter Island, show a timer until Jerry's Workshop closes.")
@ConfigEditorBoolean
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/BarnTimerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/BarnTimerConfig.java
index eb0577135..bf2609ed0 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/BarnTimerConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/BarnTimerConfig.java
@@ -22,15 +22,31 @@ public class BarnTimerConfig {
@Expose
@ConfigOption(
name = "Worm Fishing",
- desc = "Show the Barn Fishing Timer even for worms or other sea creatures in the Crystal Hollows."
+ desc = "Show the Barn Fishing Timer in the Crystal Hollows."
)
@ConfigEditorBoolean
public boolean crystalHollows = true;
@Expose
@ConfigOption(
+ name = "Lava Fishing",
+ desc = "Show the Barn Fishing Timer in the Crimson Isle."
+ )
+ @ConfigEditorBoolean
+ public boolean crimsonIsle = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Winter Fishing",
+ desc = "Show the Barn Fishing Timer on the Jerry's Workshop."
+ )
+ @ConfigEditorBoolean
+ public boolean winterIsland = true;
+
+ @Expose
+ @ConfigOption(
name = "Stranded Fishing",
- desc = "Show the Barn Fishing Timer even on all the different islands Stranded players can visit."
+ desc = "Show the Barn Fishing Timer on all the different islands that Stranded players can visit."
)
@ConfigEditorBoolean
public boolean forStranded = true;
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingConfig.java
index 13ef30f84..349f4882e 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingConfig.java
@@ -51,6 +51,11 @@ public class FishingConfig {
public RareCatchesConfig rareCatches = new RareCatchesConfig();
@Expose
+ @ConfigOption(name = "Fishing Profit Tracker", desc = "")
+ @Accordion
+ public FishingProfitTrackerConfig fishingProfitTracker = new FishingProfitTrackerConfig();
+
+ @Expose
@ConfigOption(
name = "Shark Fish Counter",
desc = "Counts how many Sharks have been caught."
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingProfitTrackerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingProfitTrackerConfig.java
new file mode 100644
index 000000000..4090e12dd
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingProfitTrackerConfig.java
@@ -0,0 +1,29 @@
+package at.hannibal2.skyhanni.config.features.fishing;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.core.config.Position;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class FishingProfitTrackerConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Count all items you pick up while fishing.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = false;
+
+ @Expose
+ public Position position = new Position(20, 20, false, true);
+
+ @Expose
+ @ConfigOption(name = "Hide Moving", desc = "Hide the Fishing Profit Tracker while moving.")
+ @ConfigEditorBoolean
+ public boolean hideMoving = true;
+
+ @Expose
+ @ConfigOption(name = "Show When Pickup", desc = "Show the fishing tracker for a couple of seconds after catching something even while moving.")
+ @ConfigEditorBoolean
+ public boolean showWhenPickup = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/CropStartLocationConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/CropStartLocationConfig.java
index 33a797bcb..721c5757f 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/garden/CropStartLocationConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/CropStartLocationConfig.java
@@ -8,7 +8,7 @@ import io.github.moulberry.moulconfig.annotations.ConfigOption;
public class CropStartLocationConfig {
@Expose
- @ConfigOption(name = "Enable", desc = "Show the start waypoint for your farm with the currently holding tool.")
+ @ConfigOption(name = "Enable", desc = "Show the start waypoint for the farm of your current tool in hand. Do §e/shcropstartlocation §7to change the waypoint again.")
@ConfigEditorBoolean
@FeatureToggle
public boolean enabled = false;
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenCommandsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenCommandsConfig.java
new file mode 100644
index 000000000..5f7d28b2e
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenCommandsConfig.java
@@ -0,0 +1,31 @@
+package at.hannibal2.skyhanni.config.features.garden;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import org.lwjgl.input.Keyboard;
+
+public class GardenCommandsConfig {
+ @Expose
+ @ConfigOption(name = "Warp Commands", desc = "Enable commands §e/home§7, §e/barn §7and §e/tp <plot>§7. §cOnly works while in the garden.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean warpCommands = true;
+
+ @Expose
+ @ConfigOption(name = "Home Hotkey", desc = "Press this key to teleport you to your Garden home. §cOnly works while in the garden.")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
+ public int homeHotkey = Keyboard.KEY_NONE;
+
+ @Expose
+ @ConfigOption(name = "Sethome Hotkey", desc = "Press this key to set your Garden home. §cOnly works while in the garden.")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
+ public int sethomeHotkey = Keyboard.KEY_NONE;
+
+ @Expose
+ @ConfigOption(name = "Barn Hotkey", desc = "Press this key to teleport you to the Garden barn. §cOnly works while in the garden.")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
+ public int barnHotkey = Keyboard.KEY_NONE;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenConfig.java
index 7553f2f2a..77e497b5e 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/GardenConfig.java
@@ -5,6 +5,7 @@ import at.hannibal2.skyhanni.config.core.config.Position;
import at.hannibal2.skyhanni.config.features.garden.composter.ComposterConfig;
import at.hannibal2.skyhanni.config.features.garden.cropmilestones.CropMilestonesConfig;
import at.hannibal2.skyhanni.config.features.garden.optimalspeed.OptimalSpeedConfig;
+import at.hannibal2.skyhanni.config.features.garden.pests.PestsConfig;
import at.hannibal2.skyhanni.config.features.garden.visitor.VisitorConfig;
import com.google.gson.annotations.Expose;
import io.github.moulberry.moulconfig.annotations.Accordion;
@@ -84,6 +85,10 @@ public class GardenConfig {
public ComposterConfig composters = new ComposterConfig();
@Expose
+ @Category(name = "Pests", desc = "Pests Settings")
+ public PestsConfig pests = new PestsConfig();
+
+ @Expose
@ConfigOption(name = "Farming Fortune Display", desc = "")
@Accordion
public FarmingFortuneConfig farmingFortunes = new FarmingFortuneConfig();
@@ -109,6 +114,11 @@ public class GardenConfig {
public PlotIconConfig plotIcon = new PlotIconConfig();
@Expose
+ @ConfigOption(name = "Garden Commands", desc = "")
+ @Accordion
+ public GardenCommandsConfig gardenCommands = new GardenCommandsConfig();
+
+ @Expose
@ConfigOption(name = "Plot Price", desc = "Show the price of the plot in coins when inside the Configure Plots inventory.")
@ConfigEditorBoolean
@FeatureToggle
@@ -204,6 +214,12 @@ public class GardenConfig {
public boolean plotBorders = true;
@Expose
+ @ConfigOption(name = "Plot Name in Scoreboard", desc = "Showing a more compact plot name in scoreboard. Updates faster and doesnt hide when pests are spawned.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean plotNameInScoreboard = true;
+
+ @Expose
@ConfigOption(name = "Copy Milestone Data", desc = "Copy wrong crop milestone data in clipboard when opening the crop milestone menu. Please share this data in SkyHanni discord.")
@ConfigEditorBoolean
@FeatureToggle
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/MoneyPerHourConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/MoneyPerHourConfig.java
index 5606e5e3d..77c9eddc2 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/garden/MoneyPerHourConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/MoneyPerHourConfig.java
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.config.features.garden;
import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.HasLegacyId;
import at.hannibal2.skyhanni.config.core.config.Position;
import com.google.gson.annotations.Expose;
import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
@@ -12,6 +13,10 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import static at.hannibal2.skyhanni.config.features.garden.MoneyPerHourConfig.CustomFormatEntry.INSTANT_SELL;
+import static at.hannibal2.skyhanni.config.features.garden.MoneyPerHourConfig.CustomFormatEntry.NPC_PRICE;
+import static at.hannibal2.skyhanni.config.features.garden.MoneyPerHourConfig.CustomFormatEntry.SELL_OFFER;
+
public class MoneyPerHourConfig {
@Expose
@ConfigOption(name = "Show Money per Hour",
@@ -40,7 +45,7 @@ public class MoneyPerHourConfig {
@Expose
@ConfigOption(
name = "Always On",
- desc = "Always show the money/hour Display while on the garden.")
+ desc = "Always show the money/hour Display while in the garden.")
@ConfigEditorBoolean
public boolean alwaysOn = false;
@@ -70,14 +75,43 @@ public class MoneyPerHourConfig {
name = "Custom Format",
desc = "Set what prices to show")
@ConfigEditorDraggableList(
- exampleText = {
- "§eSell Offer",
- "§eInstant Sell",
- "§eNPC Price"
- },
requireNonEmpty = true
)
- public List<Integer> customFormat = new ArrayList<>(Arrays.asList(0, 1, 2));
+ public List<CustomFormatEntry> customFormat = new ArrayList<>(Arrays.asList(
+ SELL_OFFER,
+ INSTANT_SELL,
+ NPC_PRICE
+ ));
+
+ public enum CustomFormatEntry implements HasLegacyId {
+ SELL_OFFER("§eSell Offer", 0),
+ INSTANT_SELL("§eInstant Sell", 1),
+ NPC_PRICE("§eNPC Price", 2),
+ ;
+
+ private final String str;
+ private final int legacyId;
+
+ CustomFormatEntry(String str, int legacyId) {
+ this.str = str;
+ this.legacyId = legacyId;
+ }
+
+ // Constructor if new enum elements are added post-migration
+ CustomFormatEntry(String str) {
+ this(str, -1);
+ }
+
+ @Override
+ public int getLegacyId() {
+ return legacyId;
+ }
+
+ @Override
+ public String toString() {
+ return str;
+ }
+ }
@Expose
@ConfigOption(
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/NextJacobContestConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/NextJacobContestConfig.java
index f9b0f80e4..b17f31279 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/garden/NextJacobContestConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/NextJacobContestConfig.java
@@ -16,7 +16,7 @@ public class NextJacobContestConfig {
public boolean display = true;
@Expose
- @ConfigOption(name = "Outside Garden", desc = "Show the timer not only in Garden but everywhere in SkyBlock.")
+ @ConfigOption(name = "Outside Garden", desc = "Show the timer not only in the Garden but everywhere in SkyBlock.")
@ConfigEditorBoolean
public boolean everywhere = false;
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/CropMilestonesConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/CropMilestonesConfig.java
index 053ffe900..8f2d5a450 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/CropMilestonesConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/CropMilestonesConfig.java
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.config.features.garden.cropmilestones;
import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.HasLegacyId;
import at.hannibal2.skyhanni.config.core.config.Position;
import com.google.gson.annotations.Expose;
import io.github.moulberry.moulconfig.annotations.Accordion;
@@ -15,6 +16,14 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.CropMilestonesConfig.MilestoneTextEntry.BLOCKS_PER_SECOND;
+import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.CropMilestonesConfig.MilestoneTextEntry.CROPS_PER_MINUTE;
+import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.CropMilestonesConfig.MilestoneTextEntry.MILESTONE_TIER;
+import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.CropMilestonesConfig.MilestoneTextEntry.NUMBER_OUT_OF_TOTAL;
+import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.CropMilestonesConfig.MilestoneTextEntry.TIME;
+import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.CropMilestonesConfig.MilestoneTextEntry.TITLE;
+import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.CropMilestonesConfig.TimeFormatEntry.YEAR;
+
public class CropMilestonesConfig {
@Expose
@ConfigOption(
@@ -38,8 +47,40 @@ public class CropMilestonesConfig {
@ConfigOption(
name = "Time Format",
desc = "Change the highest time unit to show (1h30m vs 90min)")
- @ConfigEditorDropdown(values = {"Year", "Day", "Hour", "Minute", "Second"})
- public Property<Integer> highestTimeFormat = Property.of(0);
+ @ConfigEditorDropdown()
+ public Property<TimeFormatEntry> highestTimeFormat = Property.of(YEAR);
+
+ public enum TimeFormatEntry implements HasLegacyId {
+ YEAR("Year", 0),
+ DAY("Day", 1),
+ HOUR("Hour", 2),
+ MINUTE("Minute", 3),
+ SECOND("Second", 4),
+ ;
+
+ private final String str;
+ private final int legacyId;
+
+ TimeFormatEntry(String str, int legacyId) {
+ this.str = str;
+ this.legacyId = legacyId;
+ }
+
+ // Constructor if new enum elements are added post-migration
+ TimeFormatEntry(String str) {
+ this(str, -1);
+ }
+
+ @Override
+ public int getLegacyId() {
+ return legacyId;
+ }
+
+ @Override
+ public String toString() {
+ return str;
+ }
+ }
@Expose
@ConfigOption(
@@ -54,18 +95,49 @@ public class CropMilestonesConfig {
desc = "Drag text to change the appearance of the overlay.\n" +
"Hold a farming tool to show the overlay."
)
- @ConfigEditorDraggableList(
- exampleText = {
- "§6Crop Milestones",
- "§7Pumpkin Tier 22",
- "§e12,300§8/§e100,000",
- "§7In §b12m 34s",
- "§7Crops/Minute§8: §e12,345",
- "§7Blocks/Second§8: §e19.85",
- "§7Percentage: §e12.34%",
+ @ConfigEditorDraggableList()
+ public List<MilestoneTextEntry> text = new ArrayList<>(Arrays.asList(
+ TITLE,
+ MILESTONE_TIER,
+ NUMBER_OUT_OF_TOTAL,
+ TIME,
+ CROPS_PER_MINUTE,
+ BLOCKS_PER_SECOND
+ ));
+
+ public enum MilestoneTextEntry implements HasLegacyId {
+ TITLE("§6Crop Milestones", 0),
+ MILESTONE_TIER("§7Pumpkin Tier 22", 1),
+ NUMBER_OUT_OF_TOTAL("§e12,300§8/§e100,000", 2),
+ TIME("§7In §b12m 34s", 3),
+ CROPS_PER_MINUTE("§7Crops/Minute§8: §e12,345", 4),
+ BLOCKS_PER_SECOND("§7Blocks/Second§8: §e19.85", 5),
+ PERCENTAGE("§7Percentage: §e12.34%", 6),
+ ;
+
+ private final String str;
+ private final int legacyId;
+
+ MilestoneTextEntry(String str, int legacyId) {
+ this.str = str;
+ this.legacyId = legacyId;
}
- )
- public List<Integer> text = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5));
+
+ // Constructor if new enum elements are added post-migration
+ MilestoneTextEntry(String str) {
+ this(str, -1);
+ }
+
+ @Override
+ public int getLegacyId() {
+ return legacyId;
+ }
+
+ @Override
+ public String toString() {
+ return str;
+ }
+ }
@Expose
@ConfigOption(name = "Block Broken Precision", desc = "The amount of decimals displayed in blocks/second.")
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/MushroomPetPerkConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/MushroomPetPerkConfig.java
index 66ef83a4c..2cd4cd911 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/MushroomPetPerkConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/MushroomPetPerkConfig.java
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.config.features.garden.cropmilestones;
import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.HasLegacyId;
import at.hannibal2.skyhanni.config.core.config.Position;
import com.google.gson.annotations.Expose;
import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
@@ -11,6 +12,11 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.MushroomPetPerkConfig.MushroomTextEntry.MUSHROOM_TIER;
+import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.MushroomPetPerkConfig.MushroomTextEntry.NUMBER_OUT_OF_TOTAL;
+import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.MushroomPetPerkConfig.MushroomTextEntry.TIME;
+import static at.hannibal2.skyhanni.config.features.garden.cropmilestones.MushroomPetPerkConfig.MushroomTextEntry.TITLE;
+
// TODO moulconfig runnable support
public class MushroomPetPerkConfig {
@Expose
@@ -27,16 +33,45 @@ public class MushroomPetPerkConfig {
desc = "Drag text to change the appearance of the overlay.\n" +
"Hold a farming tool to show the overlay."
)
- @ConfigEditorDraggableList(
- exampleText = {
- "§6Mooshroom Cow Perk",
- "§7Mushroom Tier 8",
- "§e6,700§8/§e15,000",
- "§7In §b12m 34s",
- "§7Percentage: §e12.34%",
+ @ConfigEditorDraggableList()
+ public List<MushroomTextEntry> text = new ArrayList<>(Arrays.asList(
+ TITLE,
+ MUSHROOM_TIER,
+ NUMBER_OUT_OF_TOTAL,
+ TIME
+ ));
+
+ public enum MushroomTextEntry implements HasLegacyId {
+ TITLE("§6Mooshroom Cow Perk", 0),
+ MUSHROOM_TIER("§7Mushroom Tier 8", 1),
+ NUMBER_OUT_OF_TOTAL("§e6,700§8/§e15,000", 2),
+ TIME("§7In §b12m 34s", 3),
+ PERCENTAGE("§7Percentage: §e12.34%", 4),
+ ;
+
+ private final String str;
+ private final int legacyId;
+
+ MushroomTextEntry(String str, int legacyId) {
+ this.str = str;
+ this.legacyId = legacyId;
}
- )
- public List<Integer> text = new ArrayList<>(Arrays.asList(0, 1, 2, 3));
+
+ // Constructor if new enum elements are added post-migration
+ MushroomTextEntry(String str) {
+ this(str, -1);
+ }
+
+ @Override
+ public int getLegacyId() {
+ return legacyId;
+ }
+
+ @Override
+ public String toString() {
+ return str;
+ }
+ }
@Expose
public Position pos = new Position(-112, -143, false, true);
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/NextConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/NextConfig.java
index 6dcd047a9..188848e48 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/NextConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/cropmilestones/NextConfig.java
@@ -43,7 +43,7 @@ public class NextConfig {
@Expose
@ConfigOption(
name = "Always On",
- desc = "Show the Best Display always while on the garden.")
+ desc = "Show the Best Display always while in the garden.")
@ConfigEditorBoolean
public boolean bestAlwaysOn = false;
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestFinderConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestFinderConfig.java
new file mode 100644
index 000000000..9f4b69d12
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestFinderConfig.java
@@ -0,0 +1,46 @@
+package at.hannibal2.skyhanni.config.features.garden.pests;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.core.config.Position;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorKeybind;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import org.lwjgl.input.Keyboard;
+
+public class PestFinderConfig {
+
+ @Expose
+ @ConfigOption(
+ name = "Display",
+ desc = "Show a display with all know pest locations."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean showDisplay = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Show Plot in World",
+ desc = "Mark infected plot names and world border in the world."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean showPlotInWorld = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Only With Vacuum",
+ desc = "Only show the pest display and waypoints while holding a vacuum in the hand."
+ )
+ @ConfigEditorBoolean
+ public boolean onlyWithVacuum = true;
+
+ @Expose
+ public Position position = new Position(-350, 200, 1.3f);
+
+ @Expose
+ @ConfigOption(name = "Teleport Hotkey", desc = "Press this key to warp to the nearest plot with pests on it.")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
+ public int teleportHotkey = Keyboard.KEY_NONE;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestSpawnConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestSpawnConfig.java
new file mode 100644
index 000000000..ba723acfa
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestSpawnConfig.java
@@ -0,0 +1,26 @@
+package at.hannibal2.skyhanni.config.features.garden.pests;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class PestSpawnConfig {
+
+ @Expose
+ @ConfigOption(
+ name = "Chat Message Format",
+ desc = "Change how the pest spawn chat message should be formatted.")
+ @ConfigEditorDropdown(values = {"Hypixel Style", "Compact", "Disabled"})
+ public int chatMessageFormat = 0;
+
+ @Expose
+ @ConfigOption(
+ name = "Show Title",
+ desc = "Show a Title when a pest spawns."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean showTitle = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestTimerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestTimerConfig.java
new file mode 100644
index 000000000..43b69b2ef
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestTimerConfig.java
@@ -0,0 +1,30 @@
+package at.hannibal2.skyhanni.config.features.garden.pests;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.core.config.Position;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class PestTimerConfig {
+
+ @Expose
+ @ConfigOption(
+ name = "Enabled",
+ desc = "Show the time since the last pest spawned in your garden."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Only With Vacuum",
+ desc = "Only show the time while holding a vacuum in the hand."
+ )
+ @ConfigEditorBoolean
+ public boolean onlyWithVacuum = true;
+
+ @Expose
+ public Position position = new Position(390, 65, false, true);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestsConfig.java
new file mode 100644
index 000000000..94e972dfe
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/PestsConfig.java
@@ -0,0 +1,28 @@
+package at.hannibal2.skyhanni.config.features.garden.pests;
+
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.Accordion;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class PestsConfig {
+
+ @Expose
+ @ConfigOption(name = "Pest Spawn", desc = "")
+ @Accordion
+ public PestSpawnConfig pestSpawn = new PestSpawnConfig();
+
+ @Expose
+ @ConfigOption(name = "Pest Finder", desc = "")
+ @Accordion
+ public PestFinderConfig pestFinder = new PestFinderConfig();
+
+ @Expose
+ @ConfigOption(name = "Pest Timer", desc = "")
+ @Accordion
+ public PestTimerConfig pestTimer = new PestTimerConfig();
+
+ @Expose
+ @ConfigOption(name = "Spray", desc = "")
+ @Accordion
+ public SprayConfig spray = new SprayConfig();
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/SprayConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/SprayConfig.java
new file mode 100644
index 000000000..da715712f
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/pests/SprayConfig.java
@@ -0,0 +1,28 @@
+package at.hannibal2.skyhanni.config.features.garden.pests;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.core.config.Position;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+
+public class SprayConfig {
+
+ @Expose
+ @ConfigOption(
+ name = "Pest Spray Selector",
+ desc = "Show the pests that are attracted when changing the selected material of the §aSprayonator§7."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean pestWhenSelector = true;
+
+ @Expose
+ @ConfigOption(name = "Draw Plot Border", desc = "Draw plots border when holding the Sprayonator.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean drawPlotsBorderWhenInHands = true;
+
+ @Expose
+ public Position position = new Position(315, -200, 2.3f);
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/DropsStatisticsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/DropsStatisticsConfig.java
index 7fd332d25..eb6f6b0fe 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/DropsStatisticsConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/DropsStatisticsConfig.java
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.config.features.garden.visitor;
import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.HasLegacyId;
import at.hannibal2.skyhanni.config.core.config.Position;
import com.google.gson.annotations.Expose;
import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
@@ -11,6 +12,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import static at.hannibal2.skyhanni.config.features.garden.visitor.DropsStatisticsConfig.DropsStatisticsTextEntry.*;
+
public class DropsStatisticsConfig {
@Expose
@@ -27,34 +30,78 @@ public class DropsStatisticsConfig {
name = "Text Format",
desc = "Drag text to change the appearance of the overlay."
)
- @ConfigEditorDraggableList(
- exampleText = {
- "§e§lVisitor Statistics",
- "§e1,636 Total",
- "§a1,172§f-§9382§f-§681§f-§c1",
- "§21,382 Accepted",
- "§c254 Denied",
- " ",
- "§c62,072 Copper",
- "§33.2m Farming EXP",
- "§647.2m Coins Spent",
- "§b23 §9Flowering Bouquet",
- "§b4 §9Overgrown Grass",
- "§b2 §5Green Bandana",
- "§b1 §9Dedication IV",
- "§b6 §b◆ Music Rune I",
- "§b1 §cSpace Helmet",
- "§b1 §9Cultivating I",
- "§b1 §9Replenish I",
- " ", // If they want another empty row
- "§212,600 Garden EXP",
- "§b4.2k Bits",
- "§220k Mithril Powder",
- "§d18k Gemstone Powder",
+ @ConfigEditorDraggableList()
+ public List<DropsStatisticsTextEntry> textFormat = new ArrayList<>(Arrays.asList(
+ TITLE,
+ TOTAL_VISITORS,
+ VISITORS_BY_RARITY,
+ ACCEPTED,
+ DENIED,
+ SPACER_1,
+ COPPER,
+ FARMING_EXP,
+ COINS_SPENT,
+ OVERGROWN_GRASS,
+ GREEN_BANDANA,
+ DEDICATION_IV
+ ));
+
+ /**
+ * Do not change the order of the enums added to that list! New items are to be synced up with the implementation in GardenVisitorDropStatistics.drawDisplay.
+ * Generic non VisitorReward stuff belongs in front of the first VisitorReward.
+ */
+ public enum DropsStatisticsTextEntry implements HasLegacyId {
+ // generic stuff
+ TITLE("§e§lVisitor Statistics", 0),
+ TOTAL_VISITORS("§e1,636 Total", 1),
+ VISITORS_BY_RARITY("§a1,172§f-§9382§f-§681§f-§d2§f-§c1", 2),
+ ACCEPTED("§21,382 Accepted", 3),
+ DENIED("§c254 Denied", 4),
+ SPACER_1(" ", 5),
+ COPPER("§c62,072 Copper", 6),
+ FARMING_EXP("§33.2m Farming EXP", 7),
+ COINS_SPENT("§647.2m Coins Spent", 8),
+ SPACER_2(" ", 17),
+ GARDEN_EXP("§212,600 Garden EXP", 18),
+ BITS("§b4.2k Bits", 19),
+ MITHRIL_POWDER("§220k Mithril Powder", 20),
+ GEMSTONE_POWDER("§d18k Gemstone Powder", 21),
+
+ // VisitorReward items
+ FLOWERING_BOUQUET("§b23 §9Flowering Bouquet", 9),
+ OVERGROWN_GRASS("§b4 §9Overgrown Grass", 10),
+ GREEN_BANDANA("§b2 §5Green Bandana", 11),
+ DEDICATION_IV("§b1 §9Dedication IV", 12),
+ MUSIC_RUNE_I("§b6 §b◆ Music Rune I", 13),
+ SPACE_HELMET("§b1 §cSpace Helmet", 14),
+ CULTIVATING_I("§b1 §9Cultivating I", 15),
+ REPLENISH_I("§b1 §9Replenish I", 16),
+ DELICATE("§9Delicate V"),
+ ;
+
+ private final String str;
+ private final int legacyId;
+
+ DropsStatisticsTextEntry(String str, int legacyId) {
+ this.str = str;
+ this.legacyId = legacyId;
}
- )
- public List<Integer> textFormat = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12));
+ // Constructor if new enum elements are added post-migration
+ DropsStatisticsTextEntry(String str) {
+ this(str, -1);
+ }
+
+ @Override
+ public int getLegacyId() {
+ return legacyId;
+ }
+
+ @Override
+ public String toString() {
+ return str;
+ }
+ }
@Expose
@ConfigOption(name = "Display Numbers First", desc = "Determines whether the number or drop name displays first. " +
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/RewardWarningConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/RewardWarningConfig.java
index f83fc5518..ee6ce50b1 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/RewardWarningConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/RewardWarningConfig.java
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.config.features.garden.visitor;
import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.features.garden.visitor.VisitorReward;
import com.google.gson.annotations.Expose;
import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
import io.github.moulberry.moulconfig.annotations.ConfigEditorDraggableList;
@@ -38,25 +39,20 @@ public class RewardWarningConfig {
public int bypassKey = Keyboard.KEY_NONE;
- /**
- * Sync up with {at.hannibal2.skyhanni.features.garden.visitor.VisitorReward}
- */
@Expose
@ConfigOption(
name = "Items",
- desc = "Warn for these reward items."
+ desc = "Warn for these reward item visitor drops."
)
- @ConfigEditorDraggableList(
- exampleText = {
- "§9Flowering Bouquet",
- "§9Overgrown Grass",
- "§9Green Bandana",
- "§9Dedication IV",
- "§9Music Rune",
- "§cSpace Helmet",
- "§9Cultivating I",
- "§9Replenish I",
- }
- )
- public List<Integer> drops = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6));
+ @ConfigEditorDraggableList
+ public List<VisitorReward> drops = new ArrayList<>(Arrays.asList(
+ VisitorReward.OVERGROWN_GRASS,
+ VisitorReward.GREEN_BANDANA,
+ VisitorReward.DEDICATION,
+ VisitorReward.MUSIC_RUNE,
+ VisitorReward.SPACE_HELMET,
+ VisitorReward.CULTIVATING,
+ VisitorReward.REPLENISH
+ ));
+
}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/VisitorConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/VisitorConfig.java
index d010b11d3..ff8e09432 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/VisitorConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/garden/visitor/VisitorConfig.java
@@ -60,7 +60,7 @@ public class VisitorConfig {
public boolean hypixelArrivedMessage = true;
@Expose
- @ConfigOption(name = "Hide Chat", desc = "Hide chat messages from the visitors in garden. (Except Beth and Spaceman)")
+ @ConfigOption(name = "Hide Chat", desc = "Hide chat messages from the visitors in the garden. (Except Beth, Jacob and Spaceman)")
@ConfigEditorBoolean
@FeatureToggle
public boolean hideChat = true;
@@ -98,7 +98,7 @@ public class VisitorConfig {
desc = "Blocks you from interacting with / unlocking Visitors to allow for Dedication Cycling"
)
@ConfigEditorDropdown
- public VisitorBlockBehaviour blockInteracting = VisitorBlockBehaviour.ONLY_ON_BINGO;
+ public VisitorBlockBehaviour blockInteracting = VisitorBlockBehaviour.DONT;
public enum VisitorBlockBehaviour {
DONT("Don't"), ALWAYS("Always"), ONLY_ON_BINGO("Only on Bingo");
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java
index 1794a20d0..60cc0e405 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.config.features.inventory;
import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.HasLegacyId;
import at.hannibal2.skyhanni.config.features.inventory.helper.HelperConfig;
import com.google.gson.annotations.Expose;
import io.github.moulberry.moulconfig.annotations.Accordion;
@@ -13,6 +14,11 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import static at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.LARVA_HOOK;
+import static at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.NEW_YEAR_CAKE;
+import static at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.RANCHERS_BOOTS_SPEED;
+import static at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.VACUUM_GARDEN;
+
public class InventoryConfig {
@Expose
@@ -55,25 +61,63 @@ public class InventoryConfig {
name = "Item Number",
desc = "Showing the item number as a stack size for these items."
)
- @ConfigEditorDraggableList(
- exampleText = {
- "§bMaster Star Tier",
- "§bMaster Skull Tier",
- "§bDungeon Head Floor Number",
- "§bNew Year Cake",
- "§bPet Level",
- "§bMinion Tier",
- "§bCrimson Armor",
- "§7(Removed)",
- "§bKuudra Key",
- "§bSkill Level",
- "§bCollection Level",
- "§bRancher's Boots speed",
- "§bLarva Hook",
- "§bDungeon Potion Level"
+ @ConfigEditorDraggableList()
+ public List<ItemNumberEntry> itemNumberAsStackSize = new ArrayList<>(Arrays.asList(
+ NEW_YEAR_CAKE,
+ RANCHERS_BOOTS_SPEED,
+ LARVA_HOOK,
+ VACUUM_GARDEN
+ ));
+
+ public enum ItemNumberEntry implements HasLegacyId {
+ MASTER_STAR_TIER("§bMaster Star Tier", 0),
+ MASTER_SKULL_TIER("§bMaster Skull Tier", 1),
+ DUNGEON_HEAD_FLOOR_NUMBER("§bDungeon Head Floor Number", 2),
+ NEW_YEAR_CAKE("§bNew Year Cake", 3),
+ PET_LEVEL("§bPet Level", 4),
+ MINION_TIER("§bMinion Tier", 5),
+ CRIMSON_ARMOR("§bCrimson Armor", 6),
+ REMOVED("§7(Removed)", 7),
+ KUUDRA_KEY("§bKuudra Key", 8),
+ SKILL_LEVEL("§bSkill Level", 9),
+ COLLECTION_LEVEL("§bCollection Level", 10),
+ RANCHERS_BOOTS_SPEED("§bRancher's Boots speed", 11),
+ LARVA_HOOK("§bLarva Hook", 12),
+ DUNGEON_POTION_LEVEL("§bDungeon Potion Level", 13),
+ VACUUM_GARDEN("§bVacuum (Garden)", 14),
+ BOTTLE_OF_JYRRE("§bBottle Of Jyrre", 15),
+ EDITION_NUMBER("§bEdition Number", 16),
+ BINGO_GOAL_RANK("§bBingo Goal Rank"),
+ ;
+
+ private final String str;
+ private final int legacyId;
+
+ ItemNumberEntry(String str, int legacyId) {
+ this.str = str;
+ this.legacyId = legacyId;
}
- )
- public List<Integer> itemNumberAsStackSize = new ArrayList<>(Arrays.asList(3, 9, 11, 12));
+
+ // Constructor if new enum elements are added post-migration
+ ItemNumberEntry(String str) {
+ this(str, -1);
+ }
+
+ @Override
+ public int getLegacyId() {
+ return legacyId;
+ }
+
+ @Override
+ public String toString() {
+ return str;
+ }
+ }
+
+ @Expose
+ @ConfigOption(name = " Vacuum Bag Cap", desc = "Capping the Garden Vacuum Bag item number display to 40.")
+ @ConfigEditorBoolean
+ public boolean vacuumBagCap = true;
@Expose
@ConfigOption(
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/mining/PowderTrackerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/mining/PowderTrackerConfig.java
index 50bff2a9b..1e658c5a2 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/mining/PowderTrackerConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/mining/PowderTrackerConfig.java
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.config.features.mining;
import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.HasLegacyId;
import at.hannibal2.skyhanni.config.core.config.Position;
import com.google.gson.annotations.Expose;
import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
@@ -12,6 +13,26 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.AMBER;
+import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.AMETHYST;
+import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.DIAMOND_ESSENCE;
+import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.DISPLAY_MODE;
+import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.DOUBLE_POWDER;
+import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.ELECTRON;
+import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.FTX;
+import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.GEMSTONE_POWDER;
+import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.GOLD_ESSENCE;
+import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.JADE;
+import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.MITHRIL_POWDER;
+import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.ROBOTRON;
+import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.RUBY;
+import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.SAPPHIRE;
+import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.SPACER_1;
+import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.SPACER_2;
+import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.TITLE;
+import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.TOPAZ;
+import static at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry.TOTAL_CHESTS;
+
public class PowderTrackerConfig {
@Expose
@@ -35,48 +56,88 @@ public class PowderTrackerConfig {
name = "Text Format",
desc = "Drag text to change the appearance of the overlay."
)
- @ConfigEditorDraggableList(
- exampleText = {
- "§b§lPowder Tracker",
- "§7Display Mode: §a[Total] §e[This Session]",
- "§d852 Total chests Picked §7(950/h)",
- "§bx2 Powder: §aActive!",
- "§b250,420 §aMithril Powder §7(350,000/h)",
- "§b250,420 §dGemstone Powder §7(350,000/h)",
- "",
- "§b129 §bDiamond Essence §7(600/h)",
- "§b234 §6Gold Essence §7(700/h)",
- "",
- "§50§7-§90§7-§a0§f-0 §cRuby Gemstone",
- "§50§7-§90§7-§a0§f-0 §bSapphire Gemstone",
- "§50§7-§90§7-§a0§f-0 §6Amber Gemstone",
- "§50§7-§90§7-§a0§f-0 §5Amethyst Gemstone",
- "§50§7-§90§7-§a0§f-0 §aJade Gemstone",
- "§50§7-§90§7-§a0§f-0 §eTopaz Gemstone",
-
- "§b14 §9FTX 3070",
- "§b14 §9Electron Transmitter",
- "§b14 §9Robotron Reflector",
- "§b14 §9Superlite Motor",
- "§b14 §9Control Switch",
- "§b14 §9Synthetic Heart",
- "§b14 §9Total Robot Parts",
-
- "§90§7-§a0§7-§c0§f-§e0§f-§30 §fGoblin Egg",
-
- "§b12 §aWishing Compass",
-
- "§b320 §aSludge Juice",
- "§b2 §9Ascension Rope",
- "§b6 §5Treasurite",
- "§b4 §6Jungle Heart",
- "§b1 §5Pickonimbus 2000",
- "§b14 §aYoggie",
- "§b9 §fPrehistoric Egg",
- "§b25 §aOil Barrel"
+ @ConfigEditorDraggableList()
+ public Property<List<PowderDisplayEntry>> textFormat = Property.of(new ArrayList<>(Arrays.asList(
+ TITLE,
+ DISPLAY_MODE,
+ TOTAL_CHESTS,
+ DOUBLE_POWDER,
+ MITHRIL_POWDER,
+ GEMSTONE_POWDER,
+ SPACER_1,
+ DIAMOND_ESSENCE,
+ GOLD_ESSENCE,
+ SPACER_2,
+ RUBY,
+ SAPPHIRE,
+ AMBER,
+ AMETHYST,
+ JADE,
+ TOPAZ,
+ FTX,
+ ELECTRON,
+ ROBOTRON
+ )));
+
+ public enum PowderDisplayEntry implements HasLegacyId {
+ TITLE("§b§lPowder Tracker", 0),
+ DISPLAY_MODE("§7Display Mode: §a[Total] §e[This Session]", 1),
+ TOTAL_CHESTS("§d852 Total chests Picked §7(950/h)", 2),
+ DOUBLE_POWDER("§bx2 Powder: §aActive!", 3),
+ MITHRIL_POWDER("§b250,420 §aMithril Powder §7(350,000/h)", 4),
+ GEMSTONE_POWDER("§b250,420 §dGemstone Powder §7(350,000/h)", 5),
+ SPACER_1("", 6),
+ DIAMOND_ESSENCE("§b129 §bDiamond Essence §7(600/h)", 7),
+ GOLD_ESSENCE("§b234 §6Gold Essence §7(700/h)", 8),
+ SPACER_2("", 9),
+ RUBY("§50§7-§90§7-§a0§f-0 §cRuby Gemstone", 10),
+ SAPPHIRE("§50§7-§90§7-§a0§f-0 §bSapphire Gemstone", 11),
+ AMBER("§50§7-§90§7-§a0§f-0 §6Amber Gemstone", 12),
+ AMETHYST("§50§7-§90§7-§a0§f-0 §5Amethyst Gemstone", 13),
+ JADE("§50§7-§90§7-§a0§f-0 §aJade Gemstone", 14),
+ TOPAZ("§50§7-§90§7-§a0§f-0 §eTopaz Gemstone", 15),
+ FTX("§b14 §9FTX 3070", 16),
+ ELECTRON("§b14 §9Electron Transmitter", 17),
+ ROBOTRON("§b14 §9Robotron Reflector", 18),
+ SUPERLITE("§b14 §9Superlite Motor", 19),
+ CONTROL_SWITCH("§b14 §9Control Switch", 20),
+ SYNTHETIC_HEART("§b14 §9Synthetic Heart", 21),
+ TOTAL_ROBOT_PARTS("§b14 §9Total Robot Parts", 22),
+ GOBLIN_EGGS("§90§7-§a0§7-§c0§f-§e0§f-§30 §fGoblin Egg", 23),
+ WISHING_COMPASS("§b12 §aWishing Compass", 24),
+ SLUDGE_JUICE("§b320 §aSludge Juice", 25),
+ ASCENSION_ROPE("§b2 §9Ascension Rope", 26),
+ TREASURITE("§b6 §5Treasurite", 27),
+ JUNGLE_HEART("§b4 §6Jungle Heart", 28),
+ PICKONIMBUS("§b1 §5Pickonimbus 2000", 29),
+ YOGGIE("§b14 §aYoggie", 30),
+ PREHISTORIC_EGG("§b9 §fPrehistoric Egg", 31),
+ OIL_BARREL("§b25 §aOil Barrel", 32),
+ ;
+
+ private final String str;
+ private final int legacyId;
+
+ PowderDisplayEntry(String str, int legacyId) {
+ this.str = str;
+ this.legacyId = legacyId;
}
- )
- public Property<List<Integer>> textFormat = Property.of(new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18)));
+
+ // Constructor if new enum elements are added post-migration
+ PowderDisplayEntry(String str) {
+ this(str, -1);
+ }
+
+ @Override
+ public int getLegacyId() {
+ return legacyId;
+ }
+
+ @Override
+ public String toString() {
+ return str;
+ }
+ }
@Expose
public Position position = new Position(-274, 0, false, true);
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/minion/MinionsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/minion/MinionsConfig.java
index d54e3d464..4f089ce9d 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/minion/MinionsConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/minion/MinionsConfig.java
@@ -36,6 +36,12 @@ public class MinionsConfig {
public boolean hopperProfitDisplay = true;
@Expose
+ @ConfigOption(name = "Show Xp", desc = "Shows how much skill experience you will get when picking up items from the minion storage.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean xpDisplay = true;
+
+ @Expose
public Position hopperProfitPos = new Position(360, 90, false, true);
@Expose
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/DiscordRPCConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/DiscordRPCConfig.java
index ab4a18d47..aa7a1d4b7 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/misc/DiscordRPCConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/DiscordRPCConfig.java
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.config.features.misc;
import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.HasLegacyId;
import com.google.gson.annotations.Expose;
import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
import io.github.moulberry.moulconfig.annotations.ConfigEditorDraggableList;
@@ -13,6 +14,13 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import static at.hannibal2.skyhanni.config.features.misc.DiscordRPCConfig.LineEntry.NOTHING;
+import static at.hannibal2.skyhanni.config.features.misc.DiscordRPCConfig.PriorityEntry.AFK;
+import static at.hannibal2.skyhanni.config.features.misc.DiscordRPCConfig.PriorityEntry.CROP_MILESTONES;
+import static at.hannibal2.skyhanni.config.features.misc.DiscordRPCConfig.PriorityEntry.DUNGEONS;
+import static at.hannibal2.skyhanni.config.features.misc.DiscordRPCConfig.PriorityEntry.SLAYER;
+import static at.hannibal2.skyhanni.config.features.misc.DiscordRPCConfig.PriorityEntry.STACKING_ENCHANT;
+
public class DiscordRPCConfig {
@Expose
@@ -23,41 +31,13 @@ public class DiscordRPCConfig {
@Expose
@ConfigOption(name = "First Line", desc = "Decide what to show in the first line.")
- @ConfigEditorDropdown(values = {
- "Nothing",
- "Location",
- "Purse",
- "Bits",
- "Stats",
- "Held Item",
- "SkyBlock Date",
- "Profile",
- "Slayer",
- "Custom",
- "Dynamic",
- "Crop Milestone",
- "Current Pet"
- })
- public Property<Integer> firstLine = Property.of(0);
+ @ConfigEditorDropdown()
+ public Property<LineEntry> firstLine = Property.of(NOTHING);
@Expose
@ConfigOption(name = "Second Line", desc = "Decide what to show in the second line.")
- @ConfigEditorDropdown(values = {
- "Nothing",
- "Location",
- "Purse",
- "Bits",
- "Stats",
- "Held Item",
- "SkyBlock Date",
- "Profile",
- "Slayer",
- "Custom",
- "Dynamic",
- "Crop Milestone",
- "Current Pet"
- })
- public Property<Integer> secondLine = Property.of(0);
+ @ConfigEditorDropdown()
+ public Property<LineEntry> secondLine = Property.of(NOTHING);
@Expose
@ConfigOption(name = "Custom", desc = "What should be displayed if you select \"Custom\" above.")
@@ -66,32 +46,89 @@ public class DiscordRPCConfig {
@Expose
@ConfigOption(name = "Dynamic Priority", desc = "Disable certain dynamic statuses, or change the priority in case two are triggered at the same time (higher up means higher priority).")
- @ConfigEditorDraggableList(
- exampleText = {
- "Crop Milestones",
- "Slayer",
- "Stacking Enchantment",
- "Dungeon",
- "AFK Indicator"
+ @ConfigEditorDraggableList()
+ public List<PriorityEntry> autoPriority = new ArrayList<>(Arrays.asList(
+ CROP_MILESTONES,
+ SLAYER,
+ STACKING_ENCHANT,
+ DUNGEONS,
+ AFK
+ ));
+
+ public enum PriorityEntry implements HasLegacyId {
+ CROP_MILESTONES("Crop Milestones", 0),
+ SLAYER("Slayer", 1),
+ STACKING_ENCHANT("Stacking Enchantment", 2),
+ DUNGEONS("Dungeon", 3),
+ AFK("AFK Indicator", 4),
+ ;
+
+ private final String str;
+ private final int legacyId;
+
+ PriorityEntry(String str, int legacyId) {
+ this.str = str;
+ this.legacyId = legacyId;
+ }
+
+ // Constructor if new enum elements are added post-migration
+ PriorityEntry(String str) {
+ this(str, -1);
+ }
+
+ @Override
+ public int getLegacyId() {
+ return legacyId;
+ }
+
+ @Override
+ public String toString() {
+ return str;
}
- )
- public List<Integer> autoPriority = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4));
+ }
@Expose
@ConfigOption(name = "Dynamic Fallback", desc = "What to show when none of your \"Dynamic Priority\" statuses are active.")
- @ConfigEditorDropdown(values = {
- "Nothing",
- "Location",
- "Purse",
- "Bits",
- "Stats",
- "Held Item",
- "SkyBlock Date",
- "Profile",
- "Slayer",
- "Custom",
- "Crop Milestone",
- "Current Pet"
- })
- public Property<Integer> auto = Property.of(0);
+ @ConfigEditorDropdown()
+ public Property<LineEntry> auto = Property.of(NOTHING);
+
+ public enum LineEntry implements HasLegacyId {
+ NOTHING("Nothing", 0),
+ LOCATION("Location", 1),
+ PURSE("Purse", 2),
+ BITS("Bits", 3),
+ STATS("Stats", 4),
+ HELD_ITEM("Held Item", 5),
+ SKYBLOCK_DATE("SkyBlock Date", 6),
+ PROFILE("Profile", 7),
+ SLAYER("Slayer", 8),
+ CUSTOM("Custom", 9),
+ DYNAMIC("Dynamic", 10),
+ CROP_MILESTONE("Crop Milestone", 11),
+ CURRENT_PET("Current Pet", 12),
+ ;
+
+ private final String str;
+ private final int legacyId;
+
+ LineEntry(String str, int legacyId) {
+ this.str = str;
+ this.legacyId = legacyId;
+ }
+
+ // Constructor if new enum elements are added post-migration
+ LineEntry(String str) {
+ this(str, -1);
+ }
+
+ @Override
+ public int getLegacyId() {
+ return legacyId;
+ }
+
+ @Override
+ public String toString() {
+ return str;
+ }
+ }
}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/MiscConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/MiscConfig.java
index 1ac453a8d..c9465ea2d 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/misc/MiscConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/MiscConfig.java
@@ -88,6 +88,11 @@ public class MiscConfig {
public KickDurationConfig kickDuration = new KickDurationConfig();
@Expose
+ @ConfigOption(name = "Tracker", desc = "Tracker Config")
+ @Accordion
+ public TrackerConfig tracker = new TrackerConfig();
+
+ @Expose
@ConfigOption(name = "Exp Bottles", desc = "Hides all the experience orbs lying on the ground.")
@ConfigEditorBoolean
@FeatureToggle
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/TrackerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/TrackerConfig.java
new file mode 100644
index 000000000..613adde60
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/TrackerConfig.java
@@ -0,0 +1,36 @@
+package at.hannibal2.skyhanni.config.features.misc;
+
+import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker;
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown;
+import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import io.github.moulberry.moulconfig.observer.Property;
+
+public class TrackerConfig {
+
+ @Expose
+ @ConfigOption(name = "Hide with Item Value", desc = "Hide all trackers while the Estimated Item Value is visible.")
+ @ConfigEditorBoolean
+ public boolean hideInEstimatedItemValue = true;
+
+ @Expose
+ @ConfigOption(name = "Show Price From", desc = "Show price from Bazaar or NPC.")
+ @ConfigEditorDropdown(values = {"Instant Sell", "Sell Offer", "NPC"})
+ public int priceFrom = 1;
+
+ @Expose
+ @ConfigOption(name = "Default Display Mode", desc = "Change the display mode that gets shown on default.")
+ @ConfigEditorDropdown
+ public Property<SkyHanniTracker.DefaultDisplayMode> defaultDisplayMode = Property.of(SkyHanniTracker.DefaultDisplayMode.REMEMBER_LAST);
+
+ @Expose
+ @ConfigOption(name = "Recent Drops", desc = "Highlight the amount in green on recently gained items.")
+ @ConfigEditorBoolean
+ public boolean showRecentDrops = true;
+
+ @Expose
+ @ConfigOption(name = "Exclude Hidden", desc = "Exclude hidden items in the total price calculation.")
+ @ConfigEditorBoolean
+ public boolean excludeHiddenItemsInPrice = false;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/TrevorTheTrapperConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/TrevorTheTrapperConfig.java
index 0c4226034..025125c4f 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/misc/TrevorTheTrapperConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/TrevorTheTrapperConfig.java
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.config.features.misc;
import at.hannibal2.skyhanni.config.FeatureToggle;
+import at.hannibal2.skyhanni.config.HasLegacyId;
import at.hannibal2.skyhanni.config.core.config.Position;
import com.google.gson.annotations.Expose;
import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
@@ -13,6 +14,18 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.ELUSIVE;
+import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.ENDANGERED;
+import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.KILLED;
+import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.PELTS_PER_HOUR;
+import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.QUESTS_STARTED;
+import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.SPACER_1;
+import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.TITLE;
+import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.TOTAL_PELTS;
+import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.TRACKABLE;
+import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.UNDETECTED;
+import static at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry.UNTRACKABLE;
+
public class TrevorTheTrapperConfig {
@Expose
@@ -39,23 +52,59 @@ public class TrevorTheTrapperConfig {
name = "Text Format",
desc = "Drag text to change the appearance of the overlay."
)
- @ConfigEditorDraggableList(
- exampleText = {
- "§b§lTrevor Data Tracker",
- "§b1,428 §9Quests Started",
- "§b11,281 §5Total Pelts Gained",
- "§b2,448 §5Pelts Per Hour",
- "",
- "§b850 §cKilled Animals",
- "§b153 §cSelf Killing Animals",
- "§b788 §fTrackable Animals",
- "§b239 §aUntrackable Animals",
- "§b115 §9Undetected Animals",
- "§b73 §5Endangered Animals",
- "§b12 §6Elusive Animals"
+ @ConfigEditorDraggableList()
+ public List<TrackerEntry> textFormat = new ArrayList<>(Arrays.asList(
+ TITLE,
+ QUESTS_STARTED,
+ TOTAL_PELTS,
+ PELTS_PER_HOUR,
+ SPACER_1,
+ KILLED,
+ TRACKABLE,
+ UNTRACKABLE,
+ UNDETECTED,
+ ENDANGERED,
+ ELUSIVE
+ ));
+
+ public enum TrackerEntry implements HasLegacyId {
+ TITLE("§b§lTrevor Data Tracker", 0),
+ QUESTS_STARTED("§b1,428 §9Quests Started", 1),
+ TOTAL_PELTS("§b11,281 §5Total Pelts Gained", 2),
+ PELTS_PER_HOUR("§b2,448 §5Pelts Per Hour", 3),
+ SPACER_1("", 4),
+ KILLED("§b850 §cKilled Animals", 5),
+ SELF_KILLING("§b153 §cSelf Killing Animals", 6),
+ TRACKABLE("§b788 §fTrackable Animals", 7),
+ UNTRACKABLE("§b239 §aUntrackable Animals", 8),
+ UNDETECTED("§b115 §9Undetected Animals", 9),
+ ENDANGERED("§b73 §5Endangered Animals", 10),
+ ELUSIVE("§b12 §6Elusive Animals", 11),
+ ;
+
+ private final String str;
+ private final int legacyId;
+
+ TrackerEntry(String str, int legacyId) {
+ this.str = str;
+ this.legacyId = legacyId;
}
- )
- public List<Integer> textFormat = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11));
+
+ // Constructor if new enum elements are added post-migration
+ TrackerEntry(String str) {
+ this(str, -1);
+ }
+
+ @Override
+ public int getLegacyId() {
+ return legacyId;
+ }
+
+ @Override
+ public String toString() {
+ return str;
+ }
+ }
@Expose
public Position position = new Position(10, 80, false, true);
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/ItemProfitTrackerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/ItemProfitTrackerConfig.java
index a7bc636db..5fc67993b 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/ItemProfitTrackerConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/ItemProfitTrackerConfig.java
@@ -4,7 +4,6 @@ import at.hannibal2.skyhanni.config.FeatureToggle;
import at.hannibal2.skyhanni.config.core.config.Position;
import com.google.gson.annotations.Expose;
import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown;
import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
import io.github.moulberry.moulconfig.annotations.ConfigOption;
@@ -28,11 +27,6 @@ public class ItemProfitTrackerConfig {
public boolean priceInChat = false;
@Expose
- @ConfigOption(name = "Show Price From", desc = "Show price from Bazaar or NPC.")
- @ConfigEditorDropdown(values = {"Instant Sell", "Sell Offer", "NPC"})
- public int priceFrom = 1;
-
- @Expose
@ConfigOption(name = "Minimum Price", desc = "Items below this price will not show up in chat.")
@ConfigEditorSlider(minValue = 1, maxValue = 5_000_000, minStep = 1)
public int minimumPrice = 100_000;
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/endermen/EndermanConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/endermen/EndermanConfig.java
index 7b5ce353e..a31d9f82a 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/endermen/EndermanConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/endermen/EndermanConfig.java
@@ -8,7 +8,7 @@ import io.github.moulberry.moulconfig.annotations.ConfigOption;
public class EndermanConfig {
@Expose
- @ConfigOption(name = "Yang Glyph (beacon)", desc = "")
+ @ConfigOption(name = "Yang Glyph (Beacon)", desc = "")
@Accordion
public EndermanBeaconConfig beacon = new EndermanBeaconConfig();
@@ -19,7 +19,7 @@ public class EndermanConfig {
public boolean highlightNukekebi = false;
@Expose
- @ConfigOption(name = "Phase Display", desc = "Show the current phase of the Enderman Slayer in damage indcator.")
+ @ConfigOption(name = "Phase Display", desc = "Show the current phase of the Enderman Slayer in damage indicator.")
@ConfigEditorBoolean
public boolean phaseDisplay = false;
diff --git a/src/main/java/at/hannibal2/skyhanni/data/BingoAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/BingoAPI.kt
deleted file mode 100644
index 5b32a1d15..000000000
--- a/src/main/java/at/hannibal2/skyhanni/data/BingoAPI.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package at.hannibal2.skyhanni.data
-
-import at.hannibal2.skyhanni.events.RepositoryReloadEvent
-import at.hannibal2.skyhanni.utils.jsonobjects.BingoRanksJson
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-
-object BingoAPI {
- private var ranks = mapOf<String, Int>()
-
- @SubscribeEvent
- fun onRepoReload(event: RepositoryReloadEvent) {
- ranks = event.getConstant<BingoRanksJson>("BingoRanks").ranks
- }
-
- fun getRank(text: String) = ranks.entries.find { text.contains(it.key) }?.value
-
- fun getIcon(searchRank: Int) = ranks.entries.find { it.value == searchRank }?.key
-
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt b/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt
index c7ddf1777..c426f9666 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt
@@ -3,6 +3,7 @@ package at.hannibal2.skyhanni.data
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.LorenzActionBarEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
+import at.hannibal2.skyhanni.events.MessageSendToServerEvent
import at.hannibal2.skyhanni.events.PacketEvent
import at.hannibal2.skyhanni.features.chat.ChatFilterGui
import at.hannibal2.skyhanni.utils.IdentityCharacteristics
@@ -13,6 +14,7 @@ import net.minecraft.client.Minecraft
import net.minecraft.client.gui.ChatLine
import net.minecraft.client.gui.GuiNewChat
import net.minecraft.event.HoverEvent
+import net.minecraft.network.play.client.C01PacketChatMessage
import net.minecraft.network.play.server.S02PacketChat
import net.minecraft.util.EnumChatFormatting
import net.minecraft.util.IChatComponent
@@ -63,15 +65,23 @@ object ChatManager {
@SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true)
fun onActionBarPacket(event: PacketEvent.ReceiveEvent) {
- val packet = event.packet
- if (packet !is S02PacketChat) return
- val messageComponent = packet.chatComponent
+ val packet = event.packet as? S02PacketChat ?: return
+ val messageComponent = packet.chatComponent
val message = LorenzUtils.stripVanillaMessage(messageComponent.formattedText)
if (packet.type.toInt() == 2) {
val actionBarEvent = LorenzActionBarEvent(message)
actionBarEvent.postAndCatch()
}
+
+ }
+
+ @SubscribeEvent
+ fun onSendMessageToServerPacket(event: PacketEvent.SendEvent) {
+ val packet = event.packet as? C01PacketChatMessage ?: return
+
+ val message = packet.message
+ event.isCanceled = MessageSendToServerEvent(message).postAndCatch()
}
@SubscribeEvent(receiveCanceled = true)
@@ -164,4 +174,4 @@ object ChatManager {
history.actionKind = ActionKind.RETRACTED
history.actionReason = reason.uppercase()
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/CropAccessoryData.kt b/src/main/java/at/hannibal2/skyhanni/data/CropAccessoryData.kt
index 79202ffa2..ad5d01d3c 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/CropAccessoryData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/CropAccessoryData.kt
@@ -10,6 +10,7 @@ import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.NEUItems
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import com.google.gson.JsonElement
import net.minecraft.item.ItemStack
import net.minecraft.nbt.CompressedStreamTools
@@ -20,7 +21,7 @@ import java.util.Base64
class CropAccessoryData {
// TODO USE SH-REPO
- private val accessoryBagNamePattern = "Accessory Bag \\((\\d)/(\\d)\\)".toRegex()
+ private val accessoryBagNamePattern = "Accessory Bag \\((?<current>\\d)/(?<total>\\d)\\)".toPattern()
private var loadedAccessoryThisProfile = false
private var ticks = 0
private var accessoryInBag: CropAccessory? = null
@@ -48,10 +49,11 @@ class CropAccessoryData {
return
}
- val groups = accessoryBagNamePattern.matchEntire(event.inventoryName)?.groups ?: return
- isLoadingAccessories = true
- accessoryBagPageCount = groups[2]!!.value.toInt()
- accessoryBagPageNumber = groups[1]!!.value.toInt()
+ accessoryBagNamePattern.matchMatcher(event.inventoryName) {
+ isLoadingAccessories = true
+ accessoryBagPageNumber = group("current").toInt()
+ accessoryBagPageCount = group("total").toInt()
+ } ?: return
}
@SubscribeEvent
diff --git a/src/main/java/at/hannibal2/skyhanni/data/EntityMovementData.kt b/src/main/java/at/hannibal2/skyhanni/data/EntityMovementData.kt
index d67ae4a63..dec06dc8e 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/EntityMovementData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/EntityMovementData.kt
@@ -6,6 +6,7 @@ import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzVec
import at.hannibal2.skyhanni.utils.getLorenzVec
+import net.minecraft.client.Minecraft
import net.minecraft.entity.Entity
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
@@ -24,6 +25,7 @@ class EntityMovementData {
@SubscribeEvent
fun onTick(event: LorenzTickEvent) {
if (!LorenzUtils.inSkyBlock) return
+ addToTrack(Minecraft.getMinecraft().thePlayer)
for (entity in entityLocation.keys) {
if (entity.isDead) continue
@@ -42,4 +44,4 @@ class EntityMovementData {
fun onWorldChange(event: LorenzWorldChangeEvent) {
entityLocation.clear()
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/EventCounter.kt b/src/main/java/at/hannibal2/skyhanni/data/EventCounter.kt
new file mode 100644
index 000000000..70de5e436
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/data/EventCounter.kt
@@ -0,0 +1,46 @@
+package at.hannibal2.skyhanni.data
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.LorenzUtils.addOrPut
+import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
+import kotlin.time.Duration.Companion.seconds
+
+object EventCounter {
+ private val config get() = SkyHanniMod.feature.dev.debug
+
+ private var map = mutableMapOf<String, Int>()
+ private var lastUpdate = SimpleTimeMark.farPast()
+
+ fun count(eventName: String) {
+ if (!isEnabled()) return
+
+ map.addOrPut(eventName, 1)
+
+ if (lastUpdate == SimpleTimeMark.farPast()) {
+ lastUpdate = SimpleTimeMark.now()
+ }
+
+ if (lastUpdate.passedSince() > 1.seconds) {
+ lastUpdate = SimpleTimeMark.now()
+
+ print(map)
+
+ map.clear()
+ }
+ }
+
+ private fun print(map: MutableMap<String, Int>) {
+ println("")
+ var total = 0
+ for ((name, amount) in map.entries.sortedBy { it.value }) {
+ println("$name (${amount.addSeparators()} times)")
+ total += amount
+ }
+ println("")
+ println("total: ${total.addSeparators()}")
+ }
+
+ private fun isEnabled() = LorenzUtils.onHypixel && config.eventCounter
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/FriendAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/FriendAPI.kt
index f6c9b4e56..834ccaa55 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/FriendAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/FriendAPI.kt
@@ -2,14 +2,14 @@ package at.hannibal2.skyhanni.data
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigFileType
+import at.hannibal2.skyhanni.data.jsonobjects.local.FriendsJson
+import at.hannibal2.skyhanni.data.jsonobjects.local.FriendsJson.PlayerFriends.Friend
import at.hannibal2.skyhanni.events.HypixelJoinEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.test.command.ErrorManager
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.StringUtils.cleanPlayerName
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
-import at.hannibal2.skyhanni.utils.jsonobjects.FriendsJson
-import at.hannibal2.skyhanni.utils.jsonobjects.FriendsJson.PlayerFriends.Friend
import net.minecraft.util.ChatStyle
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import java.util.UUID
diff --git a/src/main/java/at/hannibal2/skyhanni/data/GardenComposterUpgradesData.kt b/src/main/java/at/hannibal2/skyhanni/data/GardenComposterUpgradesData.kt
index 6b6d343aa..138158ccb 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/GardenComposterUpgradesData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/GardenComposterUpgradesData.kt
@@ -5,7 +5,7 @@ import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.features.garden.composter.ComposterAPI
import at.hannibal2.skyhanni.utils.ItemUtils.name
-import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded
+import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
@@ -19,7 +19,7 @@ class GardenComposterUpgradesData {
val itemName = item.name ?: continue
ComposterUpgrade.regex.matchMatcher(itemName) {
val name = group("name")
- val level = group("level")?.romanToDecimalIfNeeded() ?: 0
+ val level = group("level")?.romanToDecimalIfNecessary() ?: 0
val composterUpgrade = ComposterUpgrade.getByName(name)!!
ComposterAPI.composterUpgrades?.put(composterUpgrade, level)
}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt b/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt
index 610393906..34baceb0b 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt
@@ -8,7 +8,7 @@ import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
-import at.hannibal2.skyhanni.utils.jsonobjects.GardenJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.GardenJson
import net.minecraft.item.ItemStack
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
diff --git a/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestonesCommunityFix.kt b/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestonesCommunityFix.kt
index f9990685d..71398af27 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestonesCommunityFix.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestonesCommunityFix.kt
@@ -2,8 +2,10 @@ package at.hannibal2.skyhanni.data
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigManager
+import at.hannibal2.skyhanni.data.jsonobjects.repo.GardenJson
import at.hannibal2.skyhanni.events.RepositoryReloadEvent
import at.hannibal2.skyhanni.features.garden.CropType
+import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzUtils
@@ -11,12 +13,11 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy
import at.hannibal2.skyhanni.utils.LorenzUtils.nextAfter
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber
-import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded
+import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary
import at.hannibal2.skyhanni.utils.OSUtils
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.StringUtils.matches
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
-import at.hannibal2.skyhanni.utils.jsonobjects.GardenJson
import kotlinx.coroutines.launch
import net.minecraft.item.ItemStack
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
@@ -42,7 +43,7 @@ object GardenCropMilestonesCommunityFix {
fun openInventory(inventoryItems: Map<Int, ItemStack>) {
if (!showWrongData) return
- if (!SkyHanniMod.feature.garden.copyMilestoneData) return
+ if (!GardenAPI.config.copyMilestoneData) return
fixForWrongData(inventoryItems)
}
@@ -74,7 +75,7 @@ object GardenCropMilestonesCommunityFix {
) {
val name = stack.name ?: return
val rawNumber = name.removeColor().replace(crop.cropName, "").trim()
- val realTier = if (rawNumber == "") 0 else rawNumber.romanToDecimalIfNeeded()
+ val realTier = if (rawNumber == "") 0 else rawNumber.romanToDecimalIfNecessary()
val lore = stack.getLore()
val next = lore.nextAfter({ GardenCropMilestones.totalPattern.matches(it) }, 3) ?: return
diff --git a/src/main/java/at/hannibal2/skyhanni/data/GuildAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/GuildAPI.kt
index cb8288e52..5a4fb4f99 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/GuildAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/GuildAPI.kt
@@ -38,4 +38,4 @@ object GuildAPI {
fun isInGuild(name: String) = ProfileStorageData.playerSpecific?.guildMembers?.let {
name in it
} ?: false
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt b/src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt
index aa78bec09..1b0b46352 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt
@@ -7,6 +7,7 @@ import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
import at.hannibal2.skyhanni.events.ProfileJoinEvent
+import at.hannibal2.skyhanni.features.bingo.BingoAPI
import at.hannibal2.skyhanni.utils.LorenzLogger
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
diff --git a/src/main/java/at/hannibal2/skyhanni/data/IslandType.kt b/src/main/java/at/hannibal2/skyhanni/data/IslandType.kt
index 3ab213025..7e1ac4159 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/IslandType.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/IslandType.kt
@@ -1,6 +1,6 @@
package at.hannibal2.skyhanni.data
-enum class IslandType(val displayName: String, val apiName: String = "null") {
+enum class IslandType(val displayName: String, val modeName: String = "null") {
// TODO USE SH-REPO (for displayName only)
PRIVATE_ISLAND("Private Island"),
PRIVATE_ISLAND_GUEST("Private Island Guest"),
diff --git a/src/main/java/at/hannibal2/skyhanni/data/ItemAddManager.kt b/src/main/java/at/hannibal2/skyhanni/data/ItemAddManager.kt
new file mode 100644
index 000000000..3d4b8f067
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/data/ItemAddManager.kt
@@ -0,0 +1,90 @@
+package at.hannibal2.skyhanni.data
+
+import at.hannibal2.skyhanni.events.GuiContainerEvent
+import at.hannibal2.skyhanni.events.InventoryOpenEvent
+import at.hannibal2.skyhanni.events.ItemAddEvent
+import at.hannibal2.skyhanni.events.LorenzChatEvent
+import at.hannibal2.skyhanni.events.SackChangeEvent
+import at.hannibal2.skyhanni.events.entity.ItemAddInInventoryEvent
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.NEUInternalName
+import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
+import at.hannibal2.skyhanni.utils.StringUtils.matches
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import kotlin.time.Duration.Companion.milliseconds
+import kotlin.time.Duration.Companion.seconds
+
+class ItemAddManager {
+ enum class Source {
+ ITEM_ADD,
+ SACKS,
+ ;
+ }
+
+ private val ARCHFIEND_DICE = "ARCHFIEND_DICE".asInternalName()
+ private val HIGH_CLASS_ARCHFIEND_DICE = "HIGH_CLASS_ARCHFIEND_DICE".asInternalName()
+
+ private val diceRollChatPattern =
+ "§eYour §r§(5|6High Class )Archfiend Dice §r§erolled a §r§.(?<number>.)§r§e! Bonus: §r§.(?<hearts>.*)❤".toPattern()
+
+ private var inSackInventory = false
+ private var lastSackInventoryLeave = SimpleTimeMark.farPast()
+
+ @SubscribeEvent
+ fun onInventoryOpen(event: InventoryOpenEvent) {
+ if (event.inventoryName.contains("Sack")) {
+ inSackInventory = true
+ }
+ }
+
+ @SubscribeEvent
+ fun onInventoryClose(event: GuiContainerEvent.CloseWindowEvent) {
+ if (inSackInventory) {
+ inSackInventory = false
+ lastSackInventoryLeave = SimpleTimeMark.now()
+ }
+ }
+
+ @SubscribeEvent
+ fun onSackChange(event: SackChangeEvent) {
+ if (!LorenzUtils.inSkyBlock) return
+
+ if (inSackInventory || lastSackInventoryLeave.passedSince() < 10.seconds) return
+
+ for (sackChange in event.sackChanges) {
+ val change = sackChange.delta
+ if (change > 0) {
+ val internalName = sackChange.internalName
+ Source.SACKS.addItem(internalName, change)
+ }
+ }
+ }
+
+ @SubscribeEvent
+ fun onItemAdd(event: ItemAddInInventoryEvent) {
+ if (!LorenzUtils.inSkyBlock) return
+
+ val internalName = event.internalName
+ if (internalName == ARCHFIEND_DICE || internalName == HIGH_CLASS_ARCHFIEND_DICE) {
+ if (lastDiceRoll.passedSince() < 500.milliseconds) {
+ return
+ }
+ }
+
+ Source.ITEM_ADD.addItem(internalName, event.amount)
+ }
+
+ private fun Source.addItem(internalName: NEUInternalName, amount: Int) {
+ ItemAddEvent(internalName, amount, this).postAndCatch()
+ }
+
+ private var lastDiceRoll = SimpleTimeMark.farPast()
+
+ @SubscribeEvent
+ fun onChat(event: LorenzChatEvent) {
+ if (diceRollChatPattern.matches(event.message)) {
+ lastDiceRoll = SimpleTimeMark.now()
+ }
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/LocationFixData.kt b/src/main/java/at/hannibal2/skyhanni/data/LocationFixData.kt
index 2bd6a9dcb..f32256031 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/LocationFixData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/LocationFixData.kt
@@ -2,7 +2,7 @@ package at.hannibal2.skyhanni.data
import at.hannibal2.skyhanni.events.RepositoryReloadEvent
import at.hannibal2.skyhanni.utils.LocationUtils.isPlayerInside
-import at.hannibal2.skyhanni.utils.jsonobjects.LocationFixJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.LocationFixJson
import net.minecraft.util.AxisAlignedBB
import net.minecraftforge.fml.common.eventhandler.EventPriority
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
diff --git a/src/main/java/at/hannibal2/skyhanni/data/MayorElection.kt b/src/main/java/at/hannibal2/skyhanni/data/MayorElection.kt
index d4ad57e2d..53ffdae71 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/MayorElection.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/MayorElection.kt
@@ -6,7 +6,7 @@ import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.utils.APIUtil
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.put
-import at.hannibal2.skyhanni.utils.jsonobjects.MayorJson
+import at.hannibal2.skyhanni.data.jsonobjects.local.MayorJson
import io.github.moulberry.notenoughupdates.util.SkyBlockTime
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -73,4 +73,4 @@ class MayorElection {
private fun MayorJson.Election.getPairs() = year + 1 to candidates.bestCandidate()
private fun List<MayorJson.Candidate>.bestCandidate() = maxBy { it.votes }
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/MinecraftData.kt b/src/main/java/at/hannibal2/skyhanni/data/MinecraftData.kt
index bfcc8df5f..2ec0ea667 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/MinecraftData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/MinecraftData.kt
@@ -6,6 +6,7 @@ import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
import at.hannibal2.skyhanni.events.PacketEvent
import at.hannibal2.skyhanni.events.PlaySoundEvent
import at.hannibal2.skyhanni.events.ReceiveParticleEvent
+import at.hannibal2.skyhanni.utils.DelayedRun
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.LorenzUtils
@@ -75,11 +76,12 @@ object MinecraftData {
@SubscribeEvent
fun onTick(event: LorenzTickEvent) {
+ DelayedRun.checkRuns()
if (!LorenzUtils.inSkyBlock) return
val hand = InventoryUtils.getItemInHand()
val newItem = hand?.getInternalName() ?: NEUInternalName.NONE
- if (newItem != InventoryUtils.itemInHandId) {
- ItemInHandChangeEvent(newItem, hand).postAndCatch()
+ val oldItem = InventoryUtils.itemInHandId
+ if (newItem != oldItem) {
InventoryUtils.recentItemsInHand.keys.removeIf { it + 30_000 > System.currentTimeMillis() }
if (newItem != NEUInternalName.NONE) {
@@ -87,6 +89,7 @@ object MinecraftData {
}
InventoryUtils.itemInHandId = newItem
InventoryUtils.latestItemInHand = hand
+ ItemInHandChangeEvent(newItem, oldItem).postAndCatch()
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/OtherInventoryData.kt b/src/main/java/at/hannibal2/skyhanni/data/OtherInventoryData.kt
index 5950d5fb8..921d591b2 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/OtherInventoryData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/OtherInventoryData.kt
@@ -22,9 +22,9 @@ object OtherInventoryData {
close()
}
- fun close() {
+ fun close(reopenSameName: Boolean = false) {
currentInventory?.let {
- InventoryCloseEvent(it).postAndCatch()
+ InventoryCloseEvent(it, reopenSameName).postAndCatch()
currentInventory = null
}
}
@@ -49,7 +49,8 @@ object OtherInventoryData {
val windowId = packet.windowId
val title = packet.windowTitle.unformattedText
val slotCount = packet.slotCount
- close()
+ val reopenSameName = title == currentInventory?.title
+ close(reopenSameName)
currentInventory = Inventory(windowId, title, slotCount)
acceptItems = true
@@ -104,4 +105,4 @@ object OtherInventoryData {
val slotCount: Int,
val items: MutableMap<Int, ItemStack> = mutableMapOf(),
)
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/OtherMod.kt b/src/main/java/at/hannibal2/skyhanni/data/OtherMod.kt
deleted file mode 100644
index 391d66975..000000000
--- a/src/main/java/at/hannibal2/skyhanni/data/OtherMod.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-package at.hannibal2.skyhanni.data
-
-import at.hannibal2.skyhanni.config.ConfigManager
-import com.google.gson.JsonObject
-import java.io.BufferedReader
-
-enum class OtherMod(val modName: String, val configPath: String, val readKey: (BufferedReader) -> (String)) {
- NEU("Not Enough Updates", "config/notenoughupdates/configNew.json", { reader ->
- getJson(reader)["apiData"].asJsonObject["apiKey"].asString
- }),
- COW("Cowlection", "config/cowlection/do-not-share-me-with-other-players.cfg", { reader ->
- val lines = reader.readText().split(System.lineSeparator())
- val line = lines.find { it.startsWith(" S:moo=") }!!
- line.split("=")[1]
- }),
- DSM("Dankers SkyBlock Mod", "config/Danker's Skyblock Mod.cfg", { reader ->
- val lines = reader.readText().split(System.lineSeparator())
- val line = lines.find { it.startsWith(" S:APIKey=") }!!
- line.split("=")[1]
- }),
- DG("Dungeons Guide", "config/dungeonsguide/config.json", { reader ->
- getJson(reader)["partykicker.apikey"].asJsonObject["apikey"].asString
- }),
- SKYTILS("Skytils", "config/skytils/config.toml", { reader ->
- val lines = reader.readText().split(System.lineSeparator())
- val line = lines.find { it.startsWith(" hypixel_api_key = \"") }!!
- line.split("\"")[1]
- }),
- HYPIXEL_API_KEY_MANAGER("Hypixel API Key Manager", "HypixelApiKeyManager/localdata.json", { reader ->
- getJson(reader)["key"].asString
- }),
- SOOPY("Soopy Addons", "soopyAddonsData/apikey.txt", { reader ->
- reader.readText()
- }),
- SBE("SkyBlock Extras", "config/SkyblockExtras.cfg", { reader ->
- getJson(reader)["values"].asJsonObject["apiKey"].asString
- }),
-}
-
-fun getJson(reader: BufferedReader): JsonObject {
- return ConfigManager.gson.fromJson(reader, com.google.gson.JsonObject::class.java)
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/data/OwnInventoryData.kt b/src/main/java/at/hannibal2/skyhanni/data/OwnInventoryData.kt
index 4c6058b26..a7b31159b 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/OwnInventoryData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/OwnInventoryData.kt
@@ -1,30 +1,28 @@
package at.hannibal2.skyhanni.data
-import at.hannibal2.skyhanni.events.InventoryCloseEvent
+import at.hannibal2.skyhanni.events.GuiContainerEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
import at.hannibal2.skyhanni.events.OwnInventoryItemUpdateEvent
import at.hannibal2.skyhanni.events.PacketEvent
import at.hannibal2.skyhanni.events.entity.ItemAddInInventoryEvent
-import at.hannibal2.skyhanni.features.bazaar.BazaarApi
+import at.hannibal2.skyhanni.utils.DelayedRun
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalNameOrNull
-import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy
-import at.hannibal2.skyhanni.utils.NEUItems
-import net.minecraft.item.ItemStack
+import at.hannibal2.skyhanni.utils.LorenzUtils.addOrPut
+import at.hannibal2.skyhanni.utils.NEUInternalName
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
+import net.minecraft.client.Minecraft
import net.minecraft.network.play.server.S0DPacketCollectItem
import net.minecraft.network.play.server.S2FPacketSetSlot
import net.minecraftforge.fml.common.eventhandler.EventPriority
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-
-typealias SlotNumber = Int
-typealias ItemName = String
-typealias ItemData = Pair<ItemName, Int>
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.milliseconds
class OwnInventoryData {
- private var items = mapOf<SlotNumber, ItemData>()
+ private var itemAmounts = mapOf<NEUInternalName, Int>()
private var dirty = false
@SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true)
@@ -39,7 +37,9 @@ class OwnInventoryData {
val windowId = packet.func_149175_c()
if (windowId == 0) {
val item = packet.func_149174_e() ?: return
- OwnInventoryItemUpdateEvent(item).postAndCatch()
+ DelayedRun.runNextTick {
+ OwnInventoryItemUpdateEvent(item).postAndCatch()
+ }
}
}
}
@@ -47,90 +47,72 @@ class OwnInventoryData {
@SubscribeEvent
fun onTick(event: LorenzTickEvent) {
if (!LorenzUtils.inSkyBlock) return
- if (items.isEmpty()) {
- initInventory()
+ if (itemAmounts.isEmpty()) {
+ itemAmounts = getCurrentItems()
}
if (!dirty) return
-
dirty = false
- for ((slot, itemStack) in InventoryUtils.getItemsInOwnInventoryWithNull().withIndex()) {
- val old = items[slot]
- val new = itemStack.itemToPair()
- if (old != new) {
- item(slot, new, itemStack)
- }
+
+ val map = getCurrentItems()
+ for ((internalName, amount) in map) {
+ calculateDifference(internalName, amount)
}
+ itemAmounts = map
}
- private fun initInventory() {
- items = items.editCopy {
- for ((slot, itemStack) in InventoryUtils.getItemsInOwnInventoryWithNull().withIndex()) {
- this[slot] = itemStack.itemToPair()
- }
+ private fun getCurrentItems(): MutableMap<NEUInternalName, Int> {
+ val map = mutableMapOf<NEUInternalName, Int>()
+ for (itemStack in InventoryUtils.getItemsInOwnInventory()) {
+ val internalName = itemStack.getInternalNameOrNull() ?: continue
+ map.addOrPut(internalName, itemStack.stackSize)
}
+ return map
}
@SubscribeEvent
fun onWorldChange(event: LorenzWorldChangeEvent) {
- items = emptyMap()
+ itemAmounts = emptyMap()
}
- private fun ItemStack?.itemToPair(): ItemData = this?.let { (name ?: "null") to stackSize } ?: Pair("null", 0)
+ private fun calculateDifference(internalName: NEUInternalName, newAmount: Int) {
+ val oldAmount = itemAmounts[internalName] ?: 0
- private fun item(slot: SlotNumber, new: ItemData, itemStack: ItemStack?) {
- val (oldItem, oldAmount) = items[slot] ?: Pair("null", 0)
- val (name, amount) = new
-
- if (name == oldItem) {
- val diff = amount - oldAmount
- if (amount > oldAmount) {
- add(itemStack, diff)
- }
- } else {
- if (name != "null") {
- add(itemStack!!, amount)
- }
- }
- items = items.editCopy {
- this[slot] = new
+ val diff = newAmount - oldAmount
+ if (diff > 0) {
+ addItem(internalName, diff)
}
}
@SubscribeEvent
- fun onInventoryClose(event: InventoryCloseEvent) {
- BazaarApi.inBazaarInventory = false
- lastClose = System.currentTimeMillis()
+ fun onInventoryClose(event: GuiContainerEvent.CloseWindowEvent) {
+ val item = Minecraft.getMinecraft().thePlayer.inventory.itemStack ?: return
+ val internalNameOrNull = item.getInternalNameOrNull() ?: return
+ ignoreItem(500.milliseconds) { it == internalNameOrNull }
+ }
+
+ @SubscribeEvent
+ fun onSlotClick(event: GuiContainerEvent.SlotClickEvent) {
+ ignoreItem(500.milliseconds) { true }
}
- private var lastClose = 0L
+ private fun ignoreItem(duration: Duration, condition: (NEUInternalName) -> Boolean) {
+ ignoredItemsUntil.add(IgnoredItem(condition, SimpleTimeMark.now() + duration))
+ }
- private fun add(item_: ItemStack?, add: Int) {
- val item = item_ ?: return
- val diffClose = System.currentTimeMillis() - lastClose
- if (diffClose < 500) return
+ private val ignoredItemsUntil = mutableListOf<IgnoredItem>()
+ class IgnoredItem(val condition: (NEUInternalName) -> Boolean, val blockedUntil: SimpleTimeMark)
+
+ private fun addItem(internalName: NEUInternalName, add: Int) {
val diffWorld = System.currentTimeMillis() - LorenzUtils.lastWorldSwitch
if (diffWorld < 3_000) return
- val internalName = item.getInternalNameOrNull()
-
- item.name?.let {
- if (it == "§8Quiver Arrow") {
- return
- }
- }
+ ignoredItemsUntil.removeIf { it.blockedUntil.isInPast() }
+ if (ignoredItemsUntil.any { it.condition(internalName) }) return
- if (internalName == null) {
- LorenzUtils.debug("OwnInventoryData add is empty for: '${item.name}'")
- return
- }
if (internalName.startsWith("MAP-")) return
- val (_, amount) = NEUItems.getMultiplier(internalName)
- if (amount > 1) return
-
ItemAddInInventoryEvent(internalName, add).postAndCatch()
}
-
}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt
index 7079ae6fd..3694bf672 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt
@@ -6,12 +6,10 @@ import at.hannibal2.skyhanni.events.InventoryCloseEvent
import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.SackChangeEvent
-import at.hannibal2.skyhanni.features.fishing.trophy.TrophyFishManager
-import at.hannibal2.skyhanni.features.fishing.trophy.TrophyFishManager.getFilletValue
+import at.hannibal2.skyhanni.features.fishing.FishingAPI
import at.hannibal2.skyhanni.features.fishing.trophy.TrophyRarity
import at.hannibal2.skyhanni.features.inventory.SackDisplay
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
-import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName_old
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzUtils
@@ -161,13 +159,8 @@ object SackAPI {
if (savingSacks) setSackItem(item.internalName, item.stored.formatNumber())
item.price = if (isTrophySack) {
- val internal = stack.getInternalName_old()
- val trophyFishName = internal.substringBeforeLast("_")
- .replace("_", "").lowercase()
- val trophyRarityName = internal.substringAfterLast("_")
- val info = TrophyFishManager.getInfo(trophyFishName)
- val rarity = TrophyRarity.getByName(trophyRarityName) ?: TrophyRarity.BRONZE
- val filletValue = (info?.getFilletValue(rarity) ?: 0) * stored.formatNumber()
+ val filletPerTrophy = FishingAPI.getFilletPerTrophy(stack.getInternalName())
+ val filletValue = filletPerTrophy * stored.formatNumber()
item.magmaFish = filletValue
"MAGMA_FISH".asInternalName().sackPrice(filletValue.toString())
} else {
diff --git a/src/main/java/at/hannibal2/skyhanni/data/SkillExperience.kt b/src/main/java/at/hannibal2/skyhanni/data/SkillExperience.kt
index 78c25e799..d2726c3aa 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/SkillExperience.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/SkillExperience.kt
@@ -3,6 +3,7 @@ package at.hannibal2.skyhanni.data
import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
import at.hannibal2.skyhanni.events.LorenzActionBarEvent
import at.hannibal2.skyhanni.events.ProfileJoinEvent
+import at.hannibal2.skyhanni.events.SkillExpGainEvent
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzUtils
@@ -16,6 +17,7 @@ class SkillExperience {
// TODO USE SH-REPO
private val actionBarPattern = ".*§3\\+.* (?<skill>.*) \\((?<overflow>.*)/(?<needed>.*)\\).*".toPattern()
private val inventoryPattern = ".* §e(?<number>.*)§6/.*".toPattern()
+ private val actionBarLowLevelPattern = ".*§3+(?<add>.+) (?<skill>.*) \\((?<percentage>.*)%\\).*".toPattern()
@SubscribeEvent
fun onProfileJoin(event: ProfileJoinEvent) {
@@ -32,7 +34,13 @@ class SkillExperience {
val neededForNextLevel = group("needed").formatNumber()
val nextLevel = getLevelForExpExactly(neededForNextLevel)
val baseExp = getExpForLevel(nextLevel - 1)
- skillExp[skill] = baseExp + overflow
+ val totalExp = baseExp + overflow
+ skillExp[skill] = totalExp
+ SkillExpGainEvent(skill).postAndCatch()
+ }
+ actionBarLowLevelPattern.matchMatcher(event.message) {
+ val skill = group("skill").lowercase()
+ SkillExpGainEvent(skill).postAndCatch()
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/FriendsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/FriendsJson.java
index 82482b6a6..d95cea3bd 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/FriendsJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/FriendsJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.local;
import com.google.gson.annotations.Expose;
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/JacobContestsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/JacobContestsJson.java
index 87d1e9a22..96b21ae6a 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/JacobContestsJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/JacobContestsJson.java
@@ -1,6 +1,7 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.local;
import at.hannibal2.skyhanni.features.garden.CropType;
+import at.hannibal2.skyhanni.utils.SimpleTimeMark;
import com.google.gson.annotations.Expose;
import java.util.HashMap;
@@ -9,5 +10,5 @@ import java.util.Map;
public class JacobContestsJson {
@Expose
- public Map<Long, List<CropType>> contestTimes = new HashMap<>();
+ public Map<SimpleTimeMark, List<CropType>> contestTimes = new HashMap<>();
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/KnownFeaturesJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/KnownFeaturesJson.java
index bd5048cfb..e72400c9e 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/KnownFeaturesJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/KnownFeaturesJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.local;
import com.google.gson.annotations.Expose;
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/MayorJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/MayorJson.java
index d2173c74b..6525e59d3 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/MayorJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/local/MayorJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.local;
import com.google.gson.annotations.Expose;
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/AnitaUpgradeCostsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/AnitaUpgradeCostsJson.java
index 09a2de7db..a1122eec3 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/AnitaUpgradeCostsJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/AnitaUpgradeCostsJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import com.google.gson.annotations.Expose;
@@ -15,4 +15,4 @@ public class AnitaUpgradeCostsJson {
@Expose
public Integer jacob_tickets;
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ArmorDropsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ArmorDropsJson.java
index 698bad3db..c8038c49f 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ArmorDropsJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ArmorDropsJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import com.google.gson.annotations.Expose;
@@ -16,4 +16,4 @@ public class ArmorDropsJson {
@Expose
public List<Double> chance;
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/BingoJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/BingoJson.java
index 810f6d3ab..babe7cc9e 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/BingoJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/BingoJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import com.google.gson.annotations.Expose;
@@ -15,5 +15,7 @@ public class BingoJson {
@Expose
public List<String> note;
+ @Expose
+ public String found;
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/BingoRanksJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/BingoRanksJson.java
index 49d7e662f..98f2a4695 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/BingoRanksJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/BingoRanksJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import com.google.gson.annotations.Expose;
@@ -7,4 +7,4 @@ import java.util.Map;
public class BingoRanksJson {
@Expose
public Map<String, Integer> ranks;
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ContributorListJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ContributorListJson.java
index 8e5648f5e..dc2b4a5ac 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ContributorListJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ContributorListJson.java
@@ -1,5 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
-
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import com.google.gson.annotations.Expose;
import java.util.List;
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/CrimsonIsleReputationJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/CrimsonIsleReputationJson.java
index 9235680fb..f349aef9a 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/CrimsonIsleReputationJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/CrimsonIsleReputationJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import com.google.gson.annotations.Expose;
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/DanceRoomInstructionsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/DanceRoomInstructionsJson.java
index 9316d8671..e7c167e53 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/DanceRoomInstructionsJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/DanceRoomInstructionsJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import com.google.gson.annotations.Expose;
@@ -7,4 +7,4 @@ import java.util.List;
public class DanceRoomInstructionsJson {
@Expose
public List<String> instructions;
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/DicerDropsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/DicerDropsJson.java
index 996a558ea..00a662768 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/DicerDropsJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/DicerDropsJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
@@ -28,4 +28,4 @@ public class DicerDropsJson {
@Expose
public List<Integer> amount;
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/DisabledFeaturesJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/DisabledFeaturesJson.java
index 45abedfa3..1099cf782 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/DisabledFeaturesJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/DisabledFeaturesJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import com.google.gson.annotations.Expose;
@@ -7,4 +7,4 @@ import java.util.Map;
public class DisabledFeaturesJson {
@Expose
public Map<String, Boolean> features;
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/EnigmaSoulsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/EnigmaSoulsJson.java
index 5769520f5..cd17d1744 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/EnigmaSoulsJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/EnigmaSoulsJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import at.hannibal2.skyhanni.utils.LorenzVec;
import com.google.gson.annotations.Expose;
@@ -17,4 +17,4 @@ public class EnigmaSoulsJson {
@Expose
public LorenzVec position;
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/FishingProfitItemsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/FishingProfitItemsJson.java
new file mode 100644
index 000000000..47f7fc0bb
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/FishingProfitItemsJson.java
@@ -0,0 +1,12 @@
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
+
+import at.hannibal2.skyhanni.utils.NEUInternalName;
+import com.google.gson.annotations.Expose;
+
+import java.util.List;
+import java.util.Map;
+
+public class FishingProfitItemsJson {
+ @Expose
+ public Map<String, List<NEUInternalName>> categories;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/GardenJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/GardenJson.java
index 7bc9cf7fa..acb8e08ba 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/GardenJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/GardenJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import at.hannibal2.skyhanni.features.garden.CropType;
import at.hannibal2.skyhanni.utils.LorenzRarity;
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/HideNotClickableItemsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/HideNotClickableItemsJson.java
index d4ac9c52b..8877e596e 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/HideNotClickableItemsJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/HideNotClickableItemsJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import com.google.gson.annotations.Expose;
@@ -27,4 +27,4 @@ public class HideNotClickableItemsJson {
@Expose
public List<String> items;
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ItemsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ItemsJson.java
index f37671913..c6bfc90f3 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ItemsJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ItemsJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import com.google.gson.annotations.Expose;
@@ -11,4 +11,4 @@ public class ItemsJson {
@Expose
public Map<String, Integer> crimson_tiers;
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/LocationFixJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/LocationFixJson.java
index 802627e7a..0df76b4a9 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/LocationFixJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/LocationFixJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import at.hannibal2.skyhanni.utils.LorenzVec;
import com.google.gson.annotations.Expose;
diff --git a/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/MinionXPJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/MinionXPJson.java
new file mode 100644
index 000000000..44f66b8b8
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/MinionXPJson.java
@@ -0,0 +1,10 @@
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
+
+import com.google.gson.annotations.Expose;
+
+import java.util.Map;
+
+public class MinionXPJson {
+ @Expose
+ public Map<String, Map<String, Double>> minion_xp;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ModGuiSwitcherJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ModGuiSwitcherJson.java
index 078b1f6ad..cf0b0656d 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ModGuiSwitcherJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ModGuiSwitcherJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import com.google.gson.annotations.Expose;
@@ -22,4 +22,4 @@ public class ModGuiSwitcherJson {
@Expose
public List<String> guiPath = new ArrayList<>();
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/MultiFilterJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/MultiFilterJson.java
index 8704f91fb..0d0c0d6e1 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/MultiFilterJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/MultiFilterJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import com.google.gson.annotations.Expose;
@@ -22,4 +22,4 @@ public class MultiFilterJson {
@Expose
public String description;
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ParkourJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ParkourJson.java
index 5ae2d40ca..0dd511430 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/ParkourJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ParkourJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import at.hannibal2.skyhanni.utils.LorenzVec;
import com.google.gson.annotations.Expose;
@@ -20,4 +20,4 @@ public class ParkourJson {
@Expose
public int to;
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/PlayerChatFilterJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/PlayerChatFilterJson.java
index a65a2f8a1..708ac24e0 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/PlayerChatFilterJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/PlayerChatFilterJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import com.google.gson.annotations.Expose;
@@ -7,4 +7,4 @@ import java.util.List;
public class PlayerChatFilterJson {
@Expose
public List<MultiFilterJson> filters;
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/RiftEffigiesJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/RiftEffigiesJson.java
index d914ef934..ad94c374d 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/RiftEffigiesJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/RiftEffigiesJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import at.hannibal2.skyhanni.utils.LorenzVec;
import com.google.gson.annotations.Expose;
@@ -8,4 +8,4 @@ import java.util.List;
public class RiftEffigiesJson {
@Expose
public List<LorenzVec> locations;
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SacksJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/SacksJson.java
index dfd2103ef..8a2765210 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SacksJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/SacksJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import com.google.gson.annotations.Expose;
@@ -7,4 +7,4 @@ import java.util.List;
public class SacksJson {
@Expose
public List<String> sackList;
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SeaCreatureJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/SeaCreatureJson.java
index 8053e87cb..3f8449fb6 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SeaCreatureJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/SeaCreatureJson.java
@@ -1,33 +1,33 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
-
-import at.hannibal2.skyhanni.utils.LorenzRarity;
-import com.google.gson.annotations.Expose;
-import com.google.gson.reflect.TypeToken;
-
-import java.lang.reflect.Type;
-import java.util.Map;
-
-public class SeaCreatureJson {
-
- public static Type TYPE = new TypeToken<Map<String, SeaCreatureJson.Variant>>() {
- }.getType();
-
- public static class Variant {
- @Expose
- public String chat_color;
- @Expose
- public Map<String, SeaCreature> sea_creatures;
- }
-
- public static class SeaCreature {
- @Expose
- public String chat_message;
- @Expose
- public int fishing_experience;
- @Expose
- public Boolean rare;
- @Expose
- public LorenzRarity rarity;
- }
-
-}
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
+
+import at.hannibal2.skyhanni.utils.LorenzRarity;
+import com.google.gson.annotations.Expose;
+import com.google.gson.reflect.TypeToken;
+
+import java.lang.reflect.Type;
+import java.util.Map;
+
+public class SeaCreatureJson {
+
+ public static Type TYPE = new TypeToken<Map<String, SeaCreatureJson.Variant>>() {
+ }.getType();
+
+ public static class Variant {
+ @Expose
+ public String chat_color;
+ @Expose
+ public Map<String, SeaCreature> sea_creatures;
+ }
+
+ public static class SeaCreature {
+ @Expose
+ public String chat_message;
+ @Expose
+ public int fishing_experience;
+ @Expose
+ public Boolean rare;
+ @Expose
+ public LorenzRarity rarity;
+ }
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SlayerProfitTrackerItemsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/SlayerProfitTrackerItemsJson.java
index 377582200..f9c91bdfc 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/SlayerProfitTrackerItemsJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/SlayerProfitTrackerItemsJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import at.hannibal2.skyhanni.utils.NEUInternalName;
import com.google.gson.annotations.Expose;
@@ -9,4 +9,4 @@ import java.util.Map;
public class SlayerProfitTrackerItemsJson {
@Expose
public Map<String, List<NEUInternalName>> slayers;
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/TabListJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/TabListJson.java
index 03c256256..2c475679e 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/TabListJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/TabListJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import com.google.gson.annotations.Expose;
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/TrophyFishJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/TrophyFishJson.java
index 6303c16be..c15adf1b8 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/TrophyFishJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/TrophyFishJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import at.hannibal2.skyhanni.features.fishing.trophy.TrophyRarity;
import com.google.gson.annotations.Expose;
@@ -22,4 +22,4 @@ public class TrophyFishJson {
@Expose
public Map<TrophyRarity, Integer> fillet;
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/VipVisitsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/VipVisitsJson.java
index c80f4953f..d2a4a0562 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/VipVisitsJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/VipVisitsJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import com.google.gson.annotations.Expose;
@@ -7,4 +7,4 @@ import java.util.List;
public class VipVisitsJson {
@Expose
public List<String> vipVisits;
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/WarpsJson.java b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/WarpsJson.java
index e09bf3c9d..ef81b052a 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/WarpsJson.java
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/WarpsJson.java
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.utils.jsonobjects;
+package at.hannibal2.skyhanni.data.jsonobjects.repo;
import com.google.gson.annotations.Expose;
@@ -7,4 +7,4 @@ import java.util.List;
public class WarpsJson {
@Expose
public List<String> warpCommands;
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/events/DamageIndicatorDeathEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/DamageIndicatorDeathEvent.kt
new file mode 100644
index 000000000..141f293a3
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/events/DamageIndicatorDeathEvent.kt
@@ -0,0 +1,6 @@
+package at.hannibal2.skyhanni.events
+
+import at.hannibal2.skyhanni.features.combat.damageindicator.EntityData
+import net.minecraft.entity.EntityLivingBase
+
+class DamageIndicatorDeathEvent(val entity: EntityLivingBase, val data: EntityData) : LorenzEvent()
diff --git a/src/main/java/at/hannibal2/skyhanni/events/DataWatcherUpdatedEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/DataWatcherUpdatedEvent.kt
new file mode 100644
index 000000000..05389c2d7
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/events/DataWatcherUpdatedEvent.kt
@@ -0,0 +1,9 @@
+package at.hannibal2.skyhanni.events
+
+import net.minecraft.entity.DataWatcher
+import net.minecraft.entity.Entity
+
+data class DataWatcherUpdatedEvent(
+ val entity: Entity,
+ val updatedEntries: List<DataWatcher.WatchableObject>,
+) : LorenzEvent()
diff --git a/src/main/java/at/hannibal2/skyhanni/events/EntityCustomNameUpdateEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/EntityCustomNameUpdateEvent.kt
new file mode 100644
index 000000000..4b4b075e3
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/events/EntityCustomNameUpdateEvent.kt
@@ -0,0 +1,8 @@
+package at.hannibal2.skyhanni.events
+
+import net.minecraft.entity.Entity
+
+data class EntityCustomNameUpdateEvent(
+ val newName: String?,
+ val entity: Entity,
+) : LorenzEvent()
diff --git a/src/main/java/at/hannibal2/skyhanni/events/InventoryCloseEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/InventoryCloseEvent.kt
index bf43a57f9..72630756a 100644
--- a/src/main/java/at/hannibal2/skyhanni/events/InventoryCloseEvent.kt
+++ b/src/main/java/at/hannibal2/skyhanni/events/InventoryCloseEvent.kt
@@ -3,9 +3,9 @@ package at.hannibal2.skyhanni.events
import at.hannibal2.skyhanni.data.OtherInventoryData
import net.minecraft.item.ItemStack
-class InventoryCloseEvent(val inventory: OtherInventoryData.Inventory) : LorenzEvent() {
+class InventoryCloseEvent(val inventory: OtherInventoryData.Inventory, val reopenSameName: Boolean) : LorenzEvent() {
val inventoryId: Int by lazy { inventory.windowId }
val inventoryName: String by lazy { inventory.title }
val inventorySize: Int by lazy { inventory.slotCount }
val inventoryItems: Map<Int, ItemStack> by lazy { inventory.items }
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/events/ItemAddEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/ItemAddEvent.kt
new file mode 100644
index 000000000..ad0c6355d
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/events/ItemAddEvent.kt
@@ -0,0 +1,7 @@
+package at.hannibal2.skyhanni.events
+
+import at.hannibal2.skyhanni.data.ItemAddManager
+import at.hannibal2.skyhanni.utils.NEUInternalName
+
+class ItemAddEvent(val internalName: NEUInternalName, val amount: Int, val source: ItemAddManager.Source) :
+ LorenzEvent()
diff --git a/src/main/java/at/hannibal2/skyhanni/events/ItemInHandChangeEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/ItemInHandChangeEvent.kt
index 3f5b94b3c..4ef39df43 100644
--- a/src/main/java/at/hannibal2/skyhanni/events/ItemInHandChangeEvent.kt
+++ b/src/main/java/at/hannibal2/skyhanni/events/ItemInHandChangeEvent.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.events
import at.hannibal2.skyhanni.utils.NEUInternalName
-import net.minecraft.item.ItemStack
-class ItemInHandChangeEvent(val internalName: NEUInternalName, val stack: ItemStack?) : LorenzEvent() \ No newline at end of file
+class ItemInHandChangeEvent(val newItem: NEUInternalName, val oldItem: NEUInternalName) : LorenzEvent()
diff --git a/src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt
index 21f9d07e8..766da4c14 100644
--- a/src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt
+++ b/src/main/java/at/hannibal2/skyhanni/events/LorenzEvent.kt
@@ -1,5 +1,6 @@
package at.hannibal2.skyhanni.events
+import at.hannibal2.skyhanni.data.EventCounter
import at.hannibal2.skyhanni.mixins.transformers.AccessorEventBus
import at.hannibal2.skyhanni.test.command.ErrorManager
import at.hannibal2.skyhanni.utils.LorenzUtils
@@ -10,7 +11,7 @@ import net.minecraftforge.fml.common.eventhandler.IEventListener
abstract class LorenzEvent : Event() {
private val eventName by lazy {
- this::class.simpleName
+ this::class.simpleName!!
}
fun postAndCatch() = postAndCatchAndBlock {}
@@ -21,6 +22,7 @@ abstract class LorenzEvent : Event() {
ignoreErrorCache: Boolean = false,
onError: (Throwable) -> Unit,
): Boolean {
+ EventCounter.count(eventName)
val visibleErrors = 3
var errors = 0
for (listener in getListeners()) {
diff --git a/src/main/java/at/hannibal2/skyhanni/events/MessageSendToServerEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/MessageSendToServerEvent.kt
new file mode 100644
index 000000000..b6dff658e
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/events/MessageSendToServerEvent.kt
@@ -0,0 +1,6 @@
+package at.hannibal2.skyhanni.events
+
+import net.minecraftforge.fml.common.eventhandler.Cancelable
+
+@Cancelable
+class MessageSendToServerEvent(val message: String) : LorenzEvent()
diff --git a/src/main/java/at/hannibal2/skyhanni/events/MinionOpenEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/MinionOpenEvent.kt
index 5d577b6ee..bfe8649ba 100644
--- a/src/main/java/at/hannibal2/skyhanni/events/MinionOpenEvent.kt
+++ b/src/main/java/at/hannibal2/skyhanni/events/MinionOpenEvent.kt
@@ -1,5 +1,8 @@
package at.hannibal2.skyhanni.events
+import at.hannibal2.skyhanni.utils.LorenzVec
import net.minecraft.item.ItemStack
-class MinionOpenEvent(val inventoryName: String, val inventoryItems: Map<Int, ItemStack>) : LorenzEvent() \ No newline at end of file
+class MinionOpenEvent(val inventoryName: String, val inventoryItems: Map<Int, ItemStack>) : LorenzEvent()
+class MinionCloseEvent : LorenzEvent()
+class MinionStorageOpenEvent(val position: LorenzVec?, val inventoryItems: Map<Int, ItemStack>) : LorenzEvent()
diff --git a/src/main/java/at/hannibal2/skyhanni/events/OwnInventoryItemUpdateEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/OwnInventoryItemUpdateEvent.kt
index a7a5ba491..32e19e751 100644
--- a/src/main/java/at/hannibal2/skyhanni/events/OwnInventoryItemUpdateEvent.kt
+++ b/src/main/java/at/hannibal2/skyhanni/events/OwnInventoryItemUpdateEvent.kt
@@ -2,7 +2,4 @@ package at.hannibal2.skyhanni.events
import net.minecraft.item.ItemStack
-/**
- * Note: This event is async and may not be executed on the main minecraft thread.
- */
-data class OwnInventoryItemUpdateEvent(val itemStack: ItemStack) : LorenzEvent() \ No newline at end of file
+data class OwnInventoryItemUpdateEvent(val itemStack: ItemStack) : LorenzEvent()
diff --git a/src/main/java/at/hannibal2/skyhanni/events/SkillExpGainEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/SkillExpGainEvent.kt
new file mode 100644
index 000000000..c6c7be5cc
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/events/SkillExpGainEvent.kt
@@ -0,0 +1,4 @@
+package at.hannibal2.skyhanni.events
+
+// does not know how much exp is there, also gets called multiple times
+class SkillExpGainEvent(val skill: String) : LorenzEvent()
diff --git a/src/main/java/at/hannibal2/skyhanni/events/bingo/BingoCardUpdateEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/bingo/BingoCardUpdateEvent.kt
new file mode 100644
index 000000000..f7406498b
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/events/bingo/BingoCardUpdateEvent.kt
@@ -0,0 +1,5 @@
+package at.hannibal2.skyhanni.events.bingo
+
+import at.hannibal2.skyhanni.events.LorenzEvent
+
+class BingoCardUpdateEvent : LorenzEvent()
diff --git a/src/main/java/at/hannibal2/skyhanni/events/bingo/BingoGoalReachedEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/bingo/BingoGoalReachedEvent.kt
new file mode 100644
index 000000000..b091c24f3
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/events/bingo/BingoGoalReachedEvent.kt
@@ -0,0 +1,6 @@
+package at.hannibal2.skyhanni.events.bingo
+
+import at.hannibal2.skyhanni.events.LorenzEvent
+import at.hannibal2.skyhanni.features.bingo.card.goals.BingoGoal
+
+class BingoGoalReachedEvent(val goal: BingoGoal) : LorenzEvent()
diff --git a/src/main/java/at/hannibal2/skyhanni/events/garden/pests/PestSpawnEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/garden/pests/PestSpawnEvent.kt
new file mode 100644
index 000000000..20b80ff4a
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/events/garden/pests/PestSpawnEvent.kt
@@ -0,0 +1,5 @@
+package at.hannibal2.skyhanni.events.garden.pests
+
+import at.hannibal2.skyhanni.events.LorenzEvent
+
+class PestSpawnEvent(val amountPests: Int, val plotName: String) : LorenzEvent()
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarApi.kt b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarApi.kt
index 57e674976..0f14c98c3 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarApi.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarApi.kt
@@ -16,6 +16,7 @@ import at.hannibal2.skyhanni.utils.NEUInternalName
import at.hannibal2.skyhanni.utils.NEUItems
import at.hannibal2.skyhanni.utils.OSUtils
import at.hannibal2.skyhanni.utils.RenderUtils.highlight
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import net.minecraft.client.gui.inventory.GuiChest
import net.minecraft.inventory.ContainerChest
@@ -109,11 +110,12 @@ class BazaarApi {
@SubscribeEvent
fun onChat(event: LorenzChatEvent) {
- if ("\\[Bazaar] (Buy Order Setup!|Bought).*$currentSearchedItem.*".toRegex()
- .matches(event.message.removeColor())
- ) {
- currentSearchedItem = ""
- }
+ if (!LorenzUtils.inSkyBlock) return
+ if (!inBazaarInventory) return
+ // TODO USE SH-REPO
+ // TODO remove dynamic pattern
+ "\\[Bazaar] (Buy Order Setup!|Bought).*$currentSearchedItem.*".toPattern()
+ .matchMatcher(event.message.removeColor()) { currentSearchedItem = "" }
}
private fun checkIfInBazaar(event: InventoryFullyOpenedEvent): Boolean {
@@ -146,4 +148,4 @@ class BazaarApi {
inBazaarInventory = false
currentlyOpenedProduct = null
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoAPI.kt
new file mode 100644
index 000000000..cc5dec6ff
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoAPI.kt
@@ -0,0 +1,40 @@
+package at.hannibal2.skyhanni.features.bingo
+
+import at.hannibal2.skyhanni.data.jsonobjects.repo.BingoJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.BingoRanksJson
+import at.hannibal2.skyhanni.events.RepositoryReloadEvent
+import at.hannibal2.skyhanni.features.bingo.card.goals.BingoGoal
+import at.hannibal2.skyhanni.features.bingo.card.goals.GoalType
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+object BingoAPI {
+ private var ranks = mapOf<String, Int>()
+ var tips: Map<String, BingoJson.BingoTip> = emptyMap()
+ // TODO save into storage
+ val bingoGoals = mutableListOf<BingoGoal>()
+ val personalGoals get() = bingoGoals.filter { it.type == GoalType.PERSONAL }
+ val communityGoals get() = bingoGoals.filter { it.type == GoalType.COMMUNITY }
+ var lastBingoCardOpenTime = SimpleTimeMark.farPast()
+
+ @SubscribeEvent
+ fun onRepoReload(event: RepositoryReloadEvent) {
+ ranks = event.getConstant<BingoRanksJson>("BingoRanks").ranks
+ tips = event.getConstant<BingoJson>("Bingo").bingo_tips
+ }
+
+ fun getRank(text: String) = ranks.entries.find { text.contains(it.key) }?.value
+
+ fun getIcon(searchRank: Int) = ranks.entries.find { it.value == searchRank }?.key
+
+ // We added the suffix (Community Goal) so that older skyhanni versions don't crash with the new repo data.
+ fun getTip(itemName: String) =
+ tips.filter { itemName.startsWith(it.key.split(" (Community Goal)")[0]) }.values.firstOrNull()
+
+ fun BingoGoal.getTip(): BingoJson.BingoTip? = if (type == at.hannibal2.skyhanni.features.bingo.card.goals.GoalType.COMMUNITY) {
+ getTip(displayName)
+ } else {
+ tips[displayName]
+ }
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardDisplay.kt
deleted file mode 100644
index ee1fc5874..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardDisplay.kt
+++ /dev/null
@@ -1,193 +0,0 @@
-package at.hannibal2.skyhanni.features.bingo
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-import at.hannibal2.skyhanni.events.ConfigLoadEvent
-import at.hannibal2.skyhanni.events.GuiRenderEvent
-import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
-import at.hannibal2.skyhanni.events.LorenzChatEvent
-import at.hannibal2.skyhanni.features.bingo.card.CommunityGoal
-import at.hannibal2.skyhanni.features.bingo.card.PersonalGoal
-import at.hannibal2.skyhanni.utils.InventoryUtils
-import at.hannibal2.skyhanni.utils.ItemUtils
-import at.hannibal2.skyhanni.utils.ItemUtils.getLore
-import at.hannibal2.skyhanni.utils.ItemUtils.name
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.LorenzUtils.onToggle
-import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings
-import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
-import at.hannibal2.skyhanni.utils.StringUtils.removeColor
-import net.minecraft.client.Minecraft
-import net.minecraft.client.gui.GuiChat
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-
-class BingoCardDisplay {
-
- private var display = emptyList<String>()
-
- // TODO USE SH-REPO
- private val goalCompletePattern = "§6§lBINGO GOAL COMPLETE! §r§e(?<name>.*)".toPattern()
-
- init {
- update()
- }
-
- companion object {
- private const val MAX_PERSONAL_GOALS = 20
- private const val MAX_COMMUNITY_GOALS = 5
-
- private val config get() = SkyHanniMod.feature.event.bingo.bingoCard
- private var displayMode = 0
- val personalGoals = mutableListOf<PersonalGoal>()
- private val communityGoals = mutableListOf<CommunityGoal>()
-
- fun command() {
- reload()
- }
-
- private fun reload() {
- personalGoals.clear()
- communityGoals.clear()
- }
-
- fun toggleCommand() {
- if (!LorenzUtils.isBingoProfile) {
- LorenzUtils.userError("This command only works on a bingo profile!")
- return
- }
- if (!config.enabled) {
- LorenzUtils.userError("Bingo Card is disabled in the config!")
- return
- }
- toggleMode()
- }
-
- private fun toggleMode() {
- displayMode++
- if (displayMode == 3) {
- displayMode = 0
- }
- }
- }
-
- @SubscribeEvent
- fun onInventoryOpen(event: InventoryFullyOpenedEvent) {
- if (!LorenzUtils.isBingoProfile) return
- if (!config.enabled) return
- if (event.inventoryName != "Bingo Card") return
-
- personalGoals.clear()
- communityGoals.clear()
- for (stack in event.inventoryItems.values) {
- val personalGoal = stack.getLore().any { it.endsWith("Personal Goal") }
- val communityGoal = stack.getLore().any { it.endsWith("Community Goal") }
- if (!personalGoal && !communityGoal) continue
- val name = stack.name?.removeColor() ?: continue
- val lore = stack.getLore()
- var index = 0
- val builder = StringBuilder()
- for (s in lore) {
- if (index > 1) {
- if (s == "") break
- builder.append(s)
- builder.append(" ")
- }
- index++
- }
- var description = builder.toString()
- if (description.endsWith(" ")) {
- description = description.substring(0, description.length - 1)
- }
- if (description.startsWith("§7§7")) {
- description = description.substring(2)
- }
-
- val done = stack.getLore().any { it.contains("GOAL REACHED") }
- if (personalGoal) {
- personalGoals.add(PersonalGoal(name, description, done))
- } else {
- communityGoals.add(CommunityGoal(name, description, done))
- }
- }
-
- update()
- }
-
- private fun update() {
- display = drawDisplay()
- }
-
- private fun drawDisplay(): MutableList<String> {
- val newList = mutableListOf<String>()
-
- if (communityGoals.isEmpty()) {
- newList.add("§6Bingo Goals:")
- newList.add("§cOpen the §e/bingo §ccard.")
- } else {
- if (!config.hideCommunityGoals.get()) {
- newList.add("§6Community Goals:")
- communityGoals.mapTo(newList) { " " + it.description + if (it.done) " §aDONE" else "" }
- newList.add(" ")
- }
-
- val todo = personalGoals.filter { !it.done }
- val done = MAX_PERSONAL_GOALS - todo.size
- newList.add("§6Personal Goals: ($done/$MAX_PERSONAL_GOALS done)")
- todo.mapTo(newList) { " " + it.description }
- }
- return newList
- }
-
- private var lastSneak = false
-
- @SubscribeEvent
- fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
- if (!LorenzUtils.isBingoProfile) return
- if (!config.enabled) return
-
- if (config.quickToggle && ItemUtils.isSkyBlockMenuItem(InventoryUtils.getItemInHand())) {
- val sneaking = Minecraft.getMinecraft().thePlayer.isSneaking
- if (lastSneak != sneaking) {
- lastSneak = sneaking
- if (sneaking) {
- toggleMode()
- }
- }
- }
- if (!config.stepHelper && displayMode == 1) {
- displayMode = 2
- }
- if (displayMode == 0) {
- if (Minecraft.getMinecraft().currentScreen !is GuiChat) {
- config.bingoCardPos.renderStrings(display, posLabel = "Bingo Card")
- }
- } else if (displayMode == 1) {
- config.bingoCardPos.renderStrings(BingoNextStepHelper.currentHelp, posLabel = "Bingo Card")
- }
- }
-
- @SubscribeEvent
- fun onChat(event: LorenzChatEvent) {
- if (!LorenzUtils.isBingoProfile) return
- if (!config.enabled) return
-
- goalCompletePattern.matchMatcher(event.message) {
- val name = group("name")
- personalGoals.filter { it.displayName == name }
- .forEach {
- it.done = true
- update()
- }
- }
- }
-
- @SubscribeEvent
- fun onConfigLoad(event: ConfigLoadEvent) {
- config.hideCommunityGoals.onToggle { update() }
- }
-
- @SubscribeEvent
- fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
- event.move(2, "bingo", "event.bingo")
- }
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardTips.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardTips.kt
deleted file mode 100644
index 318888fec..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardTips.kt
+++ /dev/null
@@ -1,77 +0,0 @@
-package at.hannibal2.skyhanni.features.bingo
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.events.GuiContainerEvent
-import at.hannibal2.skyhanni.events.RepositoryReloadEvent
-import at.hannibal2.skyhanni.utils.InventoryUtils
-import at.hannibal2.skyhanni.utils.ItemUtils.name
-import at.hannibal2.skyhanni.utils.LorenzColor
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.RenderUtils.highlight
-import at.hannibal2.skyhanni.utils.StringUtils.removeColor
-import at.hannibal2.skyhanni.utils.jsonobjects.BingoJson
-import at.hannibal2.skyhanni.utils.jsonobjects.BingoJson.BingoTip
-import net.minecraft.inventory.ContainerChest
-import net.minecraftforge.event.entity.player.ItemTooltipEvent
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-
-class BingoCardTips {
- private var tips: Map<String, BingoTip> = emptyMap()
-
- @SubscribeEvent
- fun onRepoReload(event: RepositoryReloadEvent) {
- tips = event.getConstant<BingoJson>("Bingo").bingo_tips
- }
-
- @SubscribeEvent
- fun onItemTooltipLow(event: ItemTooltipEvent) {
- if (!isEnabled()) return
- if (InventoryUtils.openInventoryName() != "Bingo Card") return
-
- val itemName = event.itemStack?.name ?: return
- tips[itemName.removeColor()]?.let {
- val difficulty = Difficulty.valueOf(it.difficulty.uppercase())
- event.toolTip[0] = event.toolTip[0] + " §7(" + difficulty.displayName + "§7)"
-
- var index = event.toolTip.indexOf("§5§o§7Reward") - 1
- event.toolTip.add(index++, "")
- event.toolTip.add(index++, "§eGuide:")
- for (line in it.note) {
- event.toolTip.add(index++, line)
- }
- }
- }
-
- @SubscribeEvent
- fun onBackgroundDrawn(event: GuiContainerEvent.BackgroundDrawnEvent) {
- if (!isEnabled()) return
- if (InventoryUtils.openInventoryName() != "Bingo Card") return
-
- val guiChest = event.gui
- val chest = guiChest.inventorySlots as ContainerChest
-
- for (slot in chest.inventorySlots) {
- if (slot == null) continue
- if (slot.slotNumber != slot.slotIndex) continue
- if (slot.stack == null) continue
-
- val itemName = slot.stack.name ?: continue
-
- tips[itemName.removeColor()]?.let {
- val difficulty = Difficulty.valueOf(it.difficulty.uppercase())
- slot highlight difficulty.color.addOpacity(120)
- }
- }
- }
-
- fun isEnabled() = LorenzUtils.inSkyBlock && SkyHanniMod.feature.event.bingo.bingoCard.bingoSplashGuide
-
- enum class Difficulty(rawName: String, val color: LorenzColor) {
- EASY("Easy", LorenzColor.GREEN),
- MEDIUM("Medium", LorenzColor.YELLOW),
- HARD("Hard", LorenzColor.RED),
- ;
-
- val displayName = color.getChatColor() + rawName
- }
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/CompactBingoChat.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/CompactBingoChat.kt
index e686191aa..91e7a1745 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/CompactBingoChat.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/CompactBingoChat.kt
@@ -15,8 +15,8 @@ class CompactBingoChat {
private var inCollectionLevelUp = false
private var collectionLevelUpLastLine: String? = null
private var newArea = 0//0 = nothing, 1 = after first message, 2 = after second message
- private val healthPattern = " §r§7§8\\+§a.* §c❤ Health".toPattern()
- private val strengthPattern = " §r§7§8\\+§a. §c❁ Strength".toPattern()
+ private val healthPattern = " {3}§r§7§8\\+§a.* §c❤ Health".toPattern()
+ private val strengthPattern = " {3}§r§7§8\\+§a. §c❁ Strength".toPattern()
// TODO USE SH-REPO
@SubscribeEvent
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/MinionCraftHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/MinionCraftHelper.kt
index 8657f76ee..4428fd072 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/MinionCraftHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/MinionCraftHelper.kt
@@ -7,10 +7,12 @@ import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
import at.hannibal2.skyhanni.events.ProfileJoinEvent
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName_old
+import at.hannibal2.skyhanni.utils.ItemUtils.hasEnchantments
import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.NEUItems
-import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded
+import at.hannibal2.skyhanni.utils.NEUItems.getCachedIngredients
+import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary
import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
@@ -76,7 +78,7 @@ class MinionCraftHelper {
for ((minionName, minionId) in minions) {
minionNamePattern.matchMatcher(minionName) {
val cleanName = group("name").removeColor()
- val number = group("number").romanToDecimalIfNeeded()
+ val number = group("number").romanToDecimalIfNecessary()
addMinion(cleanName, number, minionId, otherItems, newDisplay)
}
}
@@ -107,6 +109,7 @@ class MinionCraftHelper {
for (item in mainInventory) {
val name = item?.name?.removeColor() ?: continue
+ if (item.hasEnchantments()) continue
val rawId = item.getInternalName_old()
if (!isMinionName(name)) {
if (!allIngredients.contains(rawId)) continue
@@ -128,7 +131,7 @@ class MinionCraftHelper {
val recipes = NEUItems.getRecipes(minion)
for (recipe in recipes) {
- for (ingredient in recipe.ingredients) {
+ for (ingredient in recipe.getCachedIngredients()) {
val ingredientInternalName = ingredient.internalItemId
if (ingredientInternalName == internalName) return true
@@ -159,7 +162,7 @@ class MinionCraftHelper {
for (recipe in NEUItems.getRecipes(internalId)) {
if (recipe !is CraftingRecipe) continue
- for (ingredient in recipe.ingredients) {
+ for (ingredient in recipe.getCachedIngredients()) {
val id = ingredient.internalItemId
if (!id.contains("_GENERATOR_") && !allIngredients.contains(id)) {
allIngredients.add(id)
@@ -182,7 +185,7 @@ class MinionCraftHelper {
for (minionId in tierOneMinionsFiltered) {
for (recipe in NEUItems.getRecipes(minionId)) {
if (recipe !is CraftingRecipe) continue
- if (recipe.ingredients.any { help.contains(it.internalItemId) }) {
+ if (recipe.getCachedIngredients().any { help.contains(it.internalItemId) }) {
val name = recipe.output.itemStack.name!!.removeColor()
val abc = name.replace(" I", " 0")
minions[abc] = minionId.replace("_1", "_0")
@@ -223,11 +226,16 @@ class MinionCraftHelper {
val have = otherItems.getOrDefault(itemId, 0)
val percentage = have.toDouble() / needAmount
val itemName = NEUItems.getItemStack(rawId).name ?: "§cName??§f"
+ val isTool = itemId.startsWith("WOOD_")
if (percentage >= 1) {
- val color = if (itemId.startsWith("WOOD_")) "§7" else "§a"
+ val color = if (isTool) "§7" else "§a"
newDisplay.add(" $itemName§8: ${color}DONE")
otherItems[itemId] = have - needAmount
} else {
+ if (!config.minionCraftHelperProgressFirst && !isTool && minionId.endsWith("_0")) {
+ newDisplay.removeLast()
+ return
+ }
val format = LorenzUtils.formatPercentage(percentage)
val haveFormat = LorenzUtils.formatInteger(have)
val needFormat = LorenzUtils.formatInteger(needAmount)
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoCardDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoCardDisplay.kt
new file mode 100644
index 000000000..126212ba6
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoCardDisplay.kt
@@ -0,0 +1,272 @@
+package at.hannibal2.skyhanni.features.bingo.card
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
+import at.hannibal2.skyhanni.events.ConfigLoadEvent
+import at.hannibal2.skyhanni.events.GuiRenderEvent
+import at.hannibal2.skyhanni.events.LorenzTickEvent
+import at.hannibal2.skyhanni.events.bingo.BingoCardUpdateEvent
+import at.hannibal2.skyhanni.features.bingo.BingoAPI
+import at.hannibal2.skyhanni.features.bingo.card.goals.BingoGoal
+import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.BingoNextStepHelper
+import at.hannibal2.skyhanni.utils.InventoryUtils
+import at.hannibal2.skyhanni.utils.ItemUtils
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.LorenzUtils.onToggle
+import at.hannibal2.skyhanni.utils.RenderUtils.renderRenderables
+import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
+import at.hannibal2.skyhanni.utils.StringUtils
+import at.hannibal2.skyhanni.utils.StringUtils.removeColor
+import at.hannibal2.skyhanni.utils.TimeUtils.format
+import at.hannibal2.skyhanni.utils.renderables.Renderable
+import net.minecraft.client.Minecraft
+import net.minecraft.client.gui.GuiChat
+import net.minecraft.client.gui.inventory.GuiInventory
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import kotlin.time.Duration.Companion.days
+import kotlin.time.Duration.Companion.milliseconds
+
+class BingoCardDisplay {
+
+ private var display = emptyList<Renderable>()
+
+ private var hasHiddenPersonalGoals = false
+
+ init {
+ update()
+ }
+
+ companion object {
+ private const val MAX_PERSONAL_GOALS = 20
+ private const val MAX_COMMUNITY_GOALS = 5
+
+ private val config get() = SkyHanniMod.feature.event.bingo.bingoCard
+ private var displayMode = 0
+
+ fun command() {
+ reload()
+ }
+
+ private fun reload() {
+ BingoAPI.bingoGoals.clear()
+ }
+
+ fun toggleCommand() {
+ if (!LorenzUtils.isBingoProfile) {
+ LorenzUtils.userError("This command only works on a bingo profile!")
+ return
+ }
+ if (!config.enabled) {
+ LorenzUtils.userError("Bingo Card is disabled in the config!")
+ return
+ }
+ toggleMode()
+ }
+
+ private fun toggleMode() {
+ displayMode++
+ if (displayMode == 3) {
+ displayMode = 0
+ }
+ }
+ }
+
+ @SubscribeEvent
+ fun onTick(event: LorenzTickEvent) {
+ if (event.repeatSeconds(1)) {
+ if (hasHiddenPersonalGoals) {
+ update()
+ }
+ }
+ }
+
+ private fun update() {
+ display = drawDisplay()
+ }
+
+ private fun drawDisplay(): MutableList<Renderable> {
+ val newList = mutableListOf<Renderable>()
+
+ if (BingoAPI.bingoGoals.isEmpty()) {
+ newList.add(Renderable.string("§6Bingo Goals:"))
+ newList.add(Renderable.clickAndHover("§cOpen the §e/bingo §ccard.",
+ listOf("Click to run §e/bingo"),
+ onClick = {
+ LorenzUtils.sendCommandToServer("bingo")
+ }
+ ))
+ } else {
+ if (!config.hideCommunityGoals.get()) {
+ newList.addCommunityGoals()
+ }
+ newList.addPersonalGoals()
+ }
+ return newList
+ }
+
+ private var lastClick = SimpleTimeMark.farPast()
+
+ private fun MutableList<Renderable>.addCommunityGoals() {
+ add(Renderable.string("§6Community Goals:"))
+ val goals = BingoAPI.communityGoals.toMutableList()
+ var hiddenGoals = 0
+ for (goal in goals.toList()) {
+ if (goal.hiddenGoalData.unknownTip) {
+ hiddenGoals++
+ goals.remove(goal)
+ }
+ }
+
+ addGoals(goals) { it.description.removeColor() + if (it.done) " §aDONE" else " " }
+
+ if (hiddenGoals > 0) {
+ val name = StringUtils.canBePlural(hiddenGoals, "goal", "goals")
+ add(Renderable.string("§7+ $hiddenGoals more §cunknown §7community $name."))
+ }
+ add(Renderable.string(" "))
+ }
+
+ private fun MutableList<Renderable>.addPersonalGoals() {
+ val todo = BingoAPI.personalGoals.filter { !it.done }.toMutableList()
+ val done = MAX_PERSONAL_GOALS - todo.size
+ add(Renderable.string("§6Personal Goals: ($done/$MAX_PERSONAL_GOALS done)"))
+
+ var hiddenGoals = 0
+ var nextTip = 14.days
+ for (goal in todo.toList()) {
+ val hiddenGoalData = goal.hiddenGoalData
+ if (hiddenGoalData.unknownTip) {
+ hiddenGoals++
+ todo.remove(goal)
+ hiddenGoalData.nextHintTime?.let {
+ if (it < nextTip) {
+ nextTip = it
+ }
+ }
+ }
+ }
+
+ addGoals(todo) { it.description.removeColor() }
+
+ if (hiddenGoals > 0) {
+ val name = StringUtils.canBePlural(hiddenGoals, "goal", "goals")
+ add(Renderable.string("§7+ $hiddenGoals more §cunknown §7$name."))
+ }
+ hasHiddenPersonalGoals = config.nextTipDuration.get() && nextTip != 14.days
+ if (hasHiddenPersonalGoals) {
+ val nextTipTime = BingoAPI.lastBingoCardOpenTime + nextTip
+ if (nextTipTime.isInPast()) {
+ add(Renderable.string("§eThe next hint got unlocked already!"))
+ add(Renderable.string("§eOpen the bingo card to update!"))
+ } else {
+ val until = nextTipTime.timeUntil()
+ add(Renderable.string("§eThe next hint will unlock in §b${until.format(maxUnits = 2)}"))
+ }
+ }
+ }
+
+ private fun MutableList<Renderable>.addGoals(goals: MutableList<BingoGoal>, format: (BingoGoal) -> String) {
+ val editDisplay = canEditDisplay()
+ val showOnlyHighlighted = goals.count { it.highlight } > 0
+
+ val filter = showOnlyHighlighted && !editDisplay
+ val finalGoal = if (filter) {
+ goals.filter { it.highlight }
+ } else goals
+
+ finalGoal.mapTo(this) {
+ val currentlyHighlighted = it.highlight
+ val highlightColor = if (currentlyHighlighted && editDisplay) "§e" else "§7"
+ val display = " $highlightColor" + format(it)
+
+ if (editDisplay) {
+ val clickName = if (currentlyHighlighted) "remove" else "add"
+ Renderable.clickAndHover(
+ display,
+ listOf(
+ "§a" + it.displayName,
+ "",
+ "§eClick to $clickName this goal as highlight!",
+ ),
+ onClick = {
+ if (lastClick.passedSince() < 300.milliseconds) return@clickAndHover
+ lastClick = SimpleTimeMark.now()
+
+ it.highlight = !currentlyHighlighted
+ update()
+ }
+ )
+ } else {
+ Renderable.string(display)
+ }
+ }
+ if (filter) {
+ val missing = goals.size - finalGoal.size
+ add(Renderable.string(" §8+ $missing not highlighted goals."))
+ }
+ }
+
+ private var highlightedMaps = mutableMapOf<String, Boolean>()
+
+ var BingoGoal.highlight: Boolean
+ get() = highlightedMaps[displayName] ?: false
+ set(value) {
+ highlightedMaps[displayName] = value
+ }
+
+ private var lastSneak = false
+ private var inventoryOpen = false
+
+ @SubscribeEvent
+ fun onRenderOverlay(event: GuiRenderEvent) {
+ if (!LorenzUtils.isBingoProfile) return
+ if (!config.enabled) return
+
+ val currentlyOpen = canEditDisplay()
+ if (inventoryOpen != currentlyOpen) {
+ inventoryOpen = currentlyOpen
+ update()
+ }
+
+ if (config.quickToggle && ItemUtils.isSkyBlockMenuItem(InventoryUtils.getItemInHand())) {
+ val sneaking = Minecraft.getMinecraft().thePlayer.isSneaking
+ if (lastSneak != sneaking) {
+ lastSneak = sneaking
+ if (sneaking) {
+ toggleMode()
+ }
+ }
+ }
+ if (!config.stepHelper && displayMode == 1) {
+ displayMode = 2
+ }
+ if (displayMode == 0) {
+ if (Minecraft.getMinecraft().currentScreen !is GuiChat) {
+ config.bingoCardPos.renderRenderables(display, posLabel = "Bingo Card")
+ }
+ } else if (displayMode == 1) {
+ config.bingoCardPos.renderStrings(BingoNextStepHelper.currentHelp, posLabel = "Bingo Card")
+ }
+ }
+
+ private fun canEditDisplay() =
+ Minecraft.getMinecraft().currentScreen is GuiInventory || InventoryUtils.openInventoryName() == "Bingo Card"
+
+ @SubscribeEvent
+ fun onBingoCardUpdate(event: BingoCardUpdateEvent) {
+ if (!config.enabled) return
+ update()
+ }
+
+ @SubscribeEvent
+ fun onConfigLoad(event: ConfigLoadEvent) {
+ config.hideCommunityGoals.onToggle { update() }
+ config.nextTipDuration.onToggle { update() }
+ }
+
+ @SubscribeEvent
+ fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
+ event.move(2, "bingo", "event.bingo")
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoCardReader.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoCardReader.kt
new file mode 100644
index 000000000..151cb145e
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoCardReader.kt
@@ -0,0 +1,123 @@
+package at.hannibal2.skyhanni.features.bingo.card
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.jsonobjects.repo.BingoJson
+import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
+import at.hannibal2.skyhanni.events.LorenzChatEvent
+import at.hannibal2.skyhanni.events.bingo.BingoCardUpdateEvent
+import at.hannibal2.skyhanni.events.bingo.BingoGoalReachedEvent
+import at.hannibal2.skyhanni.features.bingo.BingoAPI
+import at.hannibal2.skyhanni.features.bingo.card.goals.BingoGoal
+import at.hannibal2.skyhanni.features.bingo.card.goals.GoalType
+import at.hannibal2.skyhanni.features.bingo.card.goals.HiddenGoalData
+import at.hannibal2.skyhanni.utils.ItemUtils.getLore
+import at.hannibal2.skyhanni.utils.ItemUtils.name
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
+import at.hannibal2.skyhanni.utils.StringUtils.removeColor
+import at.hannibal2.skyhanni.utils.TimeUtils
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import kotlin.time.Duration
+
+class BingoCardReader {
+ private val config get() = SkyHanniMod.feature.event.bingo.bingoCard
+
+ // TODO USE SH-REPO
+ private val goalCompletePattern = "§6§lBINGO GOAL COMPLETE! §r§e(?<name>.*)".toPattern()
+
+ private val personalHiddenGoalPattern = ".*§7§eThe next hint will unlock in (?<time>.*)".toPattern()
+
+ @SubscribeEvent
+ fun onInventoryOpen(event: InventoryFullyOpenedEvent) {
+ if (!LorenzUtils.isBingoProfile) return
+ if (!config.enabled) return
+ if (event.inventoryName != "Bingo Card") return
+
+ BingoAPI.bingoGoals.clear()
+ for ((slot, stack) in event.inventoryItems) {
+ val goalType = when {
+ stack.getLore().any { it.endsWith("Personal Goal") } -> GoalType.PERSONAL
+ stack.getLore().any { it.endsWith("Community Goal") } -> GoalType.COMMUNITY
+ else -> continue
+ }
+ val name = stack.name?.removeColor() ?: continue
+ val lore = stack.getLore()
+ var index = 0
+ val builder = StringBuilder()
+ for (s in lore) {
+ if (index > 1) {
+ if (s == "") break
+ builder.append(s)
+ builder.append(" ")
+ }
+ index++
+ }
+ var description = builder.toString()
+ if (description.endsWith(" ")) {
+ description = description.substring(0, description.length - 1)
+ }
+ if (description.startsWith("§7§7")) {
+ description = description.substring(2)
+ }
+
+ val done = stack.getLore().any { it.contains("GOAL REACHED") }
+
+ val hiddenGoalData = getHiddenGoalData(name, description, goalType)
+ val visualDescription = hiddenGoalData.tipNote
+
+ val bingoGoal = BingoGoal(name, visualDescription, goalType, slot, done, hiddenGoalData)
+ BingoAPI.bingoGoals.add(bingoGoal)
+ }
+ BingoAPI.lastBingoCardOpenTime = SimpleTimeMark.now()
+
+ BingoCardUpdateEvent().postAndCatch()
+ }
+
+ private fun getHiddenGoalData(
+ name: String,
+ originalDescription: String,
+ goalType: GoalType,
+ ): HiddenGoalData {
+ var unknownTip = false
+ val nextHintTime: Duration? = when (goalType) {
+ GoalType.PERSONAL -> {
+ personalHiddenGoalPattern.matchMatcher(originalDescription) {
+ unknownTip = true
+ TimeUtils.getDuration(group("time").removeColor())
+ }
+ }
+
+ GoalType.COMMUNITY -> {
+ if (originalDescription == "§7This goal will be revealed §7when it hits Tier IV.") {
+ unknownTip = true
+ }
+ null
+ }
+ }
+
+ val description = BingoAPI.getTip(name)?.getDescriptionLine()
+ val tipNote = description?.let {
+ unknownTip = false
+ it
+ } ?: originalDescription
+ return HiddenGoalData(unknownTip, nextHintTime, tipNote)
+ }
+
+ @SubscribeEvent
+ fun onChat(event: LorenzChatEvent) {
+ if (!LorenzUtils.isBingoProfile) return
+ if (!config.enabled) return
+
+ val name = goalCompletePattern.matchMatcher(event.message) {
+ group("name")
+ } ?: return
+
+ val goal = BingoAPI.personalGoals.firstOrNull { it.displayName == name } ?: return
+ goal.done = true
+ BingoGoalReachedEvent(goal).postAndCatch()
+ BingoCardUpdateEvent().postAndCatch()
+ }
+
+ private fun BingoJson.BingoTip.getDescriptionLine() = "§7" + note.joinToString(" ")
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoCardTips.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoCardTips.kt
new file mode 100644
index 000000000..a8d62579c
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoCardTips.kt
@@ -0,0 +1,84 @@
+package at.hannibal2.skyhanni.features.bingo.card
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.events.GuiContainerEvent
+import at.hannibal2.skyhanni.features.bingo.BingoAPI
+import at.hannibal2.skyhanni.features.bingo.BingoAPI.getTip
+import at.hannibal2.skyhanni.features.bingo.card.goals.GoalType
+import at.hannibal2.skyhanni.utils.InventoryUtils
+import at.hannibal2.skyhanni.utils.LorenzColor
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.RenderUtils.highlight
+import net.minecraft.client.Minecraft
+import net.minecraft.client.gui.inventory.GuiContainer
+import net.minecraft.inventory.ContainerChest
+import net.minecraftforge.event.entity.player.ItemTooltipEvent
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+class BingoCardTips {
+ private val config get() = SkyHanniMod.feature.event.bingo.bingoCard
+
+ @SubscribeEvent
+ fun onItemTooltipLow(event: ItemTooltipEvent) {
+ if (!isEnabled()) return
+ if (InventoryUtils.openInventoryName() != "Bingo Card") return
+
+ val gui = Minecraft.getMinecraft().currentScreen as? GuiContainer ?: return
+ val slot = gui.slotUnderMouse
+ val goal = BingoAPI.bingoGoals.firstOrNull { it.slot == slot.slotNumber } ?: return
+
+ val toolTip = event.toolTip ?: return
+ val bingoTip = goal.getTip() ?: return
+ val communityGoal = goal.type == GoalType.COMMUNITY
+
+ val difficulty = Difficulty.valueOf(bingoTip.difficulty.uppercase())
+ toolTip[0] = toolTip[0] + " §7(" + difficulty.displayName + "§7) ${goal.done}"
+
+ var index = if (!communityGoal) {
+ toolTip.indexOf("§5§o§7Reward")
+ } else {
+ toolTip.indexOfFirst { it.startsWith("§5§o§7Contribution Rewards") }
+ } - 1
+
+ toolTip.add(index++, "")
+ toolTip.add(index++, "§eGuide:")
+ for (line in bingoTip.note) {
+ toolTip.add(index++, " $line")
+ }
+ bingoTip.found?.let {
+ toolTip.add(index++, "§7Found by: §e$it")
+ }
+ }
+
+ @SubscribeEvent
+ fun onBackgroundDrawn(event: GuiContainerEvent.BackgroundDrawnEvent) {
+ if (!isEnabled()) return
+ if (InventoryUtils.openInventoryName() != "Bingo Card") return
+
+ val guiChest = event.gui
+ val chest = guiChest.inventorySlots as ContainerChest
+ for (slot in chest.inventorySlots) {
+ if (slot == null) continue
+
+ val goal = BingoAPI.bingoGoals.firstOrNull { it.slot == slot.slotNumber } ?: continue
+ if (config.hideDoneDifficulty && goal.done) continue
+
+ val color = goal.getTip()?.let {
+ val difficulty = Difficulty.valueOf(it.difficulty.uppercase())
+ difficulty.color
+ } ?: LorenzColor.GRAY
+ slot highlight color.addOpacity(120)
+ }
+ }
+
+ fun isEnabled() = LorenzUtils.inSkyBlock && config.bingoSplashGuide
+
+ enum class Difficulty(rawName: String, val color: LorenzColor) {
+ EASY("Easy", LorenzColor.GREEN),
+ MEDIUM("Medium", LorenzColor.YELLOW),
+ HARD("Hard", LorenzColor.RED),
+ ;
+
+ val displayName = color.getChatColor() + rawName
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoGoals.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoGoals.kt
deleted file mode 100644
index dbcb5bf35..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/BingoGoals.kt
+++ /dev/null
@@ -1,4 +0,0 @@
-package at.hannibal2.skyhanni.features.bingo.card
-
-
-abstract class BingoGoals(val displayName: String, val description: String, var done: Boolean) \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/CommunityGoal.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/CommunityGoal.kt
deleted file mode 100644
index 63e13eadc..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/CommunityGoal.kt
+++ /dev/null
@@ -1,4 +0,0 @@
-package at.hannibal2.skyhanni.features.bingo.card
-
-class CommunityGoal(displayName: String, description: String, done: Boolean) :
- BingoGoals(displayName, description, done) \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/PersonalGoal.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/PersonalGoal.kt
deleted file mode 100644
index 981bb1a20..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/PersonalGoal.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package at.hannibal2.skyhanni.features.bingo.card
-
-class PersonalGoal(displayName: String, description: String, done: Boolean) : BingoGoals(displayName, description, done) \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/goals/BingoGoal.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/goals/BingoGoal.kt
new file mode 100644
index 000000000..31f01b335
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/goals/BingoGoal.kt
@@ -0,0 +1,12 @@
+package at.hannibal2.skyhanni.features.bingo.card.goals
+
+class BingoGoal(
+ val displayName: String,
+ val description: String,
+ val type: GoalType,
+ val slot: Int,
+ var done: Boolean,
+ val hiddenGoalData: HiddenGoalData,
+) {
+ override fun toString(): String = displayName
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/goals/GoalType.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/goals/GoalType.kt
new file mode 100644
index 000000000..b2e4f6d8d
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/goals/GoalType.kt
@@ -0,0 +1,7 @@
+package at.hannibal2.skyhanni.features.bingo.card.goals
+
+enum class GoalType {
+ COMMUNITY,
+ PERSONAL,
+ ;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/goals/HiddenGoalData.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/goals/HiddenGoalData.kt
new file mode 100644
index 000000000..b2ea441d3
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/goals/HiddenGoalData.kt
@@ -0,0 +1,5 @@
+package at.hannibal2.skyhanni.features.bingo.card.goals
+
+import kotlin.time.Duration
+
+class HiddenGoalData(val unknownTip: Boolean, val nextHintTime: Duration?, val tipNote: String)
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoNextStepHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/BingoNextStepHelper.kt
index 2960b2d22..0cd5df65a 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoNextStepHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/BingoNextStepHelper.kt
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.features.bingo
+package at.hannibal2.skyhanni.features.bingo.card.nextstephelper
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.api.CollectionAPI
@@ -6,22 +6,22 @@ import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.data.SkillExperience
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
-import at.hannibal2.skyhanni.features.bingo.nextstep.ChatMessageStep
-import at.hannibal2.skyhanni.features.bingo.nextstep.CollectionStep
-import at.hannibal2.skyhanni.features.bingo.nextstep.CraftStep
-import at.hannibal2.skyhanni.features.bingo.nextstep.IslandVisitStep
-import at.hannibal2.skyhanni.features.bingo.nextstep.ItemsStep
-import at.hannibal2.skyhanni.features.bingo.nextstep.NextStep
-import at.hannibal2.skyhanni.features.bingo.nextstep.ObtainCrystalStep
-import at.hannibal2.skyhanni.features.bingo.nextstep.PartialProgressItemsStep
-import at.hannibal2.skyhanni.features.bingo.nextstep.ProgressionStep
-import at.hannibal2.skyhanni.features.bingo.nextstep.SkillLevelStep
+import at.hannibal2.skyhanni.features.bingo.BingoAPI
+import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps.ChatMessageStep
+import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps.CollectionStep
+import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps.CraftStep
+import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps.IslandVisitStep
+import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps.ItemsStep
+import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps.NextStep
+import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps.ObtainCrystalStep
+import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps.PartialProgressItemsStep
+import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps.ProgressionStep
+import at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps.SkillLevelStep
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
-import at.hannibal2.skyhanni.utils.StringUtils.matchRegex
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
@@ -37,6 +37,7 @@ class BingoNextStepHelper {
private val collectionPattern = "Reach (?<amount>[0-9]+(?:,\\d+)*) (?<name>.*) Collection\\.".toPattern()
private val crystalPattern = "Obtain a (?<name>\\w+) Crystal in the Crystal Hollows\\.".toPattern()
private val skillPattern = "Obtain level (?<level>.*) in the (?<skill>.*) Skill.".toPattern()
+ private val crystalFoundPattern = " *§r§5§l✦ CRYSTAL FOUND §r§7\\(.§r§7/5§r§7\\)".toPattern()
private val rhysTaskName = "30x Enchanted Minerals (Redstone, Lapis Lazuli, Coal) (for Rhys)"
companion object {
@@ -135,7 +136,7 @@ class BingoNextStepHelper {
for (currentStep in currentSteps) {
if (currentStep is ObtainCrystalStep) {
- if (event.message.matchRegex(" *§r§5§l✦ CRYSTAL FOUND §r§7\\(.§r§7/5§r§7\\)")) {
+ crystalFoundPattern.matchMatcher(event.message) {
nextMessageIsCrystal = true
return
}
@@ -215,7 +216,7 @@ class BingoNextStepHelper {
}
private fun update() {
- val personalGoals = BingoCardDisplay.personalGoals.filter { !it.done }
+ val personalGoals = BingoAPI.personalGoals.filter { !it.done }
if (personalGoals.isEmpty()) {
if (!dirty) {
reset()
@@ -228,9 +229,10 @@ class BingoNextStepHelper {
dirty = false
for (goal in personalGoals) {
- val bingoCardStep = readDescription(goal.description.removeColor())
+ val description = goal.description
+ val bingoCardStep = readDescription(description.removeColor())
if (bingoCardStep == null) {
- println("Warning: Could not find bingo steps for ${goal.description}")
+// println("Warning: Could not find bingo steps for $description")
} else {
finalSteps.add(bingoCardStep)
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/ChatMessageStep.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/ChatMessageStep.kt
index 021ef5f73..0da254a40 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/ChatMessageStep.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/ChatMessageStep.kt
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.features.bingo.nextstep
+package at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps
class ChatMessageStep(displayName: String) : NextStep(displayName)
class ObtainCrystalStep(val crystalName: String) : NextStep("Obtain a $crystalName Crystal")
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/CollectionStep.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/CollectionStep.kt
index 4e08b2ba4..e6bb7075b 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/CollectionStep.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/CollectionStep.kt
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.features.bingo.nextstep
+package at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps
import at.hannibal2.skyhanni.utils.NEUInternalName
import at.hannibal2.skyhanni.utils.NumberUtil
@@ -6,4 +6,4 @@ import at.hannibal2.skyhanni.utils.NumberUtil
class CollectionStep(collectionName: String, amountNeeded: Int) :
ProgressionStep(NumberUtil.format(amountNeeded) + " $collectionName Collection", amountNeeded.toLong()) {
val internalName by lazy { NEUInternalName.fromItemName(if (collectionName == "Mushroom") "Red Mushroom" else collectionName) }
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/CraftStep.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/CraftStep.kt
new file mode 100644
index 000000000..4ae9a08c0
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/CraftStep.kt
@@ -0,0 +1,3 @@
+package at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps
+
+class CraftStep(val itemName: String) : NextStep("Craft $itemName")
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/IslandVisitStep.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/IslandVisitStep.kt
index c25c440bc..f2ae9cf01 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/IslandVisitStep.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/IslandVisitStep.kt
@@ -1,5 +1,5 @@
-package at.hannibal2.skyhanni.features.bingo.nextstep
+package at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps
import at.hannibal2.skyhanni.data.IslandType
-class IslandVisitStep(val island: IslandType) : NextStep("Visit ${island.displayName}") \ No newline at end of file
+class IslandVisitStep(val island: IslandType) : NextStep("Visit ${island.displayName}")
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/ItemsStep.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/ItemsStep.kt
index c9e65b1b4..548318a20 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/ItemsStep.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/ItemsStep.kt
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.features.bingo.nextstep
+package at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps
open class ItemsStep(displayName: String, val itemName: String, amountNeeded: Long, val variants: Map<String, Int>) :
ProgressionStep(displayName, amountNeeded)
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/NextStep.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/NextStep.kt
index d5077478e..d0a73926a 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/NextStep.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/NextStep.kt
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.features.bingo.nextstep
+package at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps
abstract class NextStep(
val displayName: String,
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/ProgressionStep.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/ProgressionStep.kt
index 2d19438d5..26f7d6c4d 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/ProgressionStep.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/ProgressionStep.kt
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.features.bingo.nextstep
+package at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps
abstract class ProgressionStep(displayName: String, open val amountNeeded: Long, var amountHaving: Long = 0) :
- NextStep(displayName) \ No newline at end of file
+ NextStep(displayName)
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/SkillLevelStep.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/SkillLevelStep.kt
index 48767e8d9..e93aa24b0 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/SkillLevelStep.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/card/nextstephelper/steps/SkillLevelStep.kt
@@ -1,4 +1,4 @@
-package at.hannibal2.skyhanni.features.bingo.nextstep
+package at.hannibal2.skyhanni.features.bingo.card.nextstephelper.steps
import at.hannibal2.skyhanni.data.SkillExperience
@@ -7,4 +7,4 @@ class SkillLevelStep(
private val skillLevelNeeded: Int,
skillExpNeeded: Long = SkillExperience.getExpForLevel(skillLevelNeeded)
) :
- ProgressionStep("$skillName $skillLevelNeeded", skillExpNeeded) \ No newline at end of file
+ ProgressionStep("$skillName $skillLevelNeeded", skillExpNeeded)
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/CraftStep.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/CraftStep.kt
deleted file mode 100644
index 4c20494b0..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/nextstep/CraftStep.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package at.hannibal2.skyhanni.features.bingo.nextstep
-
-class CraftStep(val itemName: String) : NextStep("Craft $itemName") \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilter.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilter.kt
index 33509b606..3c6614e1f 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilter.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilter.kt
@@ -3,7 +3,7 @@ package at.hannibal2.skyhanni.features.chat
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.LorenzChatEvent
-import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
+import at.hannibal2.skyhanni.utils.StringUtils.matches
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import at.hannibal2.skyhanni.utils.StringUtils.trimWhiteSpaceAndResets
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
@@ -192,13 +192,13 @@ class ChatFilter {
// Party
private val partyMessages = listOf(
- "§9§m-----------------------------------------------------"
+ "§9§m-----------------------------------------------------",
)
// MONEY
// Auction House
private val auctionHouseMessages = listOf(
- "§b-----------------------------------------------------", "§eVisit the Auction House to collect your item!"
+ "§b-----------------------------------------------------", "§eVisit the Auction House to collect your item!",
)
// Bazaar
@@ -206,12 +206,12 @@ class ChatFilter {
"§eBuy Order Setup! §r§a(.*)§r§7x (.*) §r§7for §r§6(.*) coins§r§7.".toPattern(),
"§eSell Offer Setup! §r§a(.*)§r§7x (.*) §r§7for §r§6(.*) coins§r§7.".toPattern(),
"§cCancelled! §r§7Refunded §r§6(.*) coins §r§7from cancelling buy order!".toPattern(),
- "§cCancelled! §r§7Refunded §r§a(.*)§r§7x (.*) §r§7from cancelling sell offer!".toPattern()
+ "§cCancelled! §r§7Refunded §r§a(.*)§r§7x (.*) §r§7from cancelling sell offer!".toPattern(),
)
// Winter Island
private val winterIslandPatterns = listOf(
- "§r§f☃ §r§7§r(.*) §r§7mounted a §r§fSnow Cannon§r§7!".toPattern()
+ "§r§f☃ §r§7§r(.*) §r§7mounted a §r§fSnow Cannon§r§7!".toPattern(),
)
// Useless Warning
@@ -224,13 +224,13 @@ class ChatFilter {
"§cPlace a Dungeon weapon or armor piece above the anvil to salvage it!",
"§cWhoa! Slow down there!",
"§cWait a moment before confirming!",
- "§cYou cannot open the SkyBlock menu while in combat!"
+ "§cYou cannot open the SkyBlock menu while in combat!",
)
// Annoying Spam
private val annoyingSpamPatterns = listOf(
"§7Your Implosion hit (.*) for §r§c(.*) §r§7damage.".toPattern(),
- "§7Your Molten Wave hit (.*) for §r§c(.*) §r§7damage.".toPattern()
+ "§7Your Molten Wave hit (.*) for §r§c(.*) §r§7damage.".toPattern(),
)
private val annoyingSpamMessages = listOf(
"§cThere are blocks in the way!",
@@ -242,7 +242,7 @@ class ChatFilter {
"§6§lGOOD CATCH! §r§bYou found a §r§fDark Bait§r§b.",
"§6§lGOOD CATCH! §r§bYou found a §r§fLight Bait§r§b.",
"§6§lGOOD CATCH! §r§bYou found a §r§aHot Bait§r§b.",
- "§6§lGOOD CATCH! §r§bYou found a §r§fSpooky Bait§r§b."
+ "§6§lGOOD CATCH! §r§bYou found a §r§fSpooky Bait§r§b.",
)
// Winter Gift
@@ -275,7 +275,7 @@ class ChatFilter {
"§e§lSWEET! §r§5Snow Suit .* §r§egift with §r.*§r§e!".toPattern(),
// winter gifts not your gifts
- "§cThis gift is for §r.*§r§c, sorry!".toPattern()
+ "§cThis gift is for §r.*§r§c, sorry!".toPattern(),
)
// Powder Mining
@@ -289,7 +289,12 @@ class ChatFilter {
// Useful, maybe in another chat
"§aYou received §r§b\\+\\d{1,3} §r§a(Mithril|Gemstone) Powder.".toPattern(),
- "§aYou received §r(§6|§b)\\+[1-2] (Diamond|Gold) Essence".toPattern()
+ "§aYou received §r(§6|§b)\\+[1-2] (Diamond|Gold) Essence".toPattern(),
+ )
+ private val fireSalePatterns = listOf(
+ "§c♨ §eFire Sales for .* §eare starting soon!".toPattern(),
+ "§c {3}♨ .* Skin §e\\(.* §eleft\\)§c".toPattern(),
+ "§c♨ §eVisit the Community Shop in the next §c.* §eto grab yours! §a§l\\[WARP]".toPattern()
)
private val powderMiningMessages = listOf(
"§aYou uncovered a treasure chest!",
@@ -298,7 +303,11 @@ class ChatFilter {
// Jungle
"§aYou received §r§f1 §r§aOil Barrel§r§a.",
// Useful, maybe in another chat
- "§6You have successfully picked the lock on this chest!"
+ "§6You have successfully picked the lock on this chest!",
+ )
+ private val fireSaleMessages = listOf(
+ "§6§k§lA§r §c§lFIRE SALE §r§6§k§lA",
+ "§c♨ §eSelling multiple items for a limited time!",
)
private val patternsMap: Map<String, List<Pattern>> = mapOf(
@@ -314,7 +323,8 @@ class ChatFilter {
"winter_island" to winterIslandPatterns,
"annoying_spam" to annoyingSpamPatterns,
"winter_gift" to winterGiftPatterns,
- "powder_mining" to powderMiningPatterns
+ "powder_mining" to powderMiningPatterns,
+ "fire_sale" to fireSalePatterns,
)
private val messagesMap: Map<String, List<String>> = mapOf(
@@ -330,14 +340,15 @@ class ChatFilter {
"money" to auctionHouseMessages,
"useless_warning" to uselessWarningMessages,
"annoying_spam" to annoyingSpamMessages,
- "powder_mining" to powderMiningMessages
+ "powder_mining" to powderMiningMessages,
+ "fire_sale" to fireSaleMessages,
)
private val messagesContainsMap: Map<String, List<String>> = mapOf(
"lobby" to lobbyMessagesContains,
)
private val messagesStartsWithMap: Map<String, List<String>> = mapOf(
"slayer" to slayerMessageStartWith,
- "profile_join" to profileJoinMessageStartsWith
+ "profile_join" to profileJoinMessageStartsWith,
)
/// </editor-fold>
@@ -367,6 +378,8 @@ class ChatFilter {
config.winterGift && message.isPresent("winter_gift") -> "winter_gift"
config.powderMining && message.isPresent("powder_mining") -> "powder_mining"
+ config.fireSale && message.isPresent("fire_sale") -> "fire_sale"
+
else -> ""
}
@@ -417,7 +430,7 @@ class ChatFilter {
* @see messagesStartsWithMap
*/
private fun String.isPresent(key: String) = this in (messagesMap[key] ?: emptyList()) ||
- (patternsMap[key] ?: emptyList()).any { it.matchMatcher(this) { } != null } ||
+ (patternsMap[key] ?: emptyList()).any { it.matches(this) } ||
(messagesContainsMap[key] ?: emptyList()).any { this.contains(it) } ||
(messagesStartsWithMap[key] ?: emptyList()).any { this.startsWith(it) }
diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/CompactSplashPotionMessage.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/CompactSplashPotionMessage.kt
index c823d83f0..e624af88c 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/chat/CompactSplashPotionMessage.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/chat/CompactSplashPotionMessage.kt
@@ -3,49 +3,59 @@ package at.hannibal2.skyhanni.features.chat
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.LorenzUtils.groupOrNull
+import at.hannibal2.skyhanni.utils.StringUtils.cleanPlayerName
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
-import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class CompactSplashPotionMessage {
private val config get() = SkyHanniMod.feature.chat.compactPotionMessages
- private val potionEffectPattern =
- "§a§lBUFF! §fYou have gained §r(?<name>.*)§r§f! Press TAB or type /effects to view your active effects!".toPattern()
- private val potionSplashEffectOthersPattern =
- "§a§lBUFF! §fYou were splashed by (?<playerName>.*) §fwith §r(?<effectName>.*)§r§f! Press TAB or type /effects to view your active effects!".toPattern()
- private val potionSplashEffectPattern =
- "§a§lBUFF! §fYou splashed yourself with §r(?<name>.*)§r§f! Press TAB or type /effects to view your active effects!".toPattern()
+ private val potionEffectPatternList = listOf(
+ "§a§lBUFF! §fYou were splashed by (?<playerName>.*) §fwith §r(?<effectName>.*)§r§f! Press TAB or type /effects to view your active effects!".toPattern(),
+ "§a§lBUFF! §fYou have gained §r(?<effectName>.*)§r§f! Press TAB or type /effects to view your active effects!".toPattern(),
+ "§a§lBUFF! §fYou splashed yourself with §r(?<effectName>.*)§r§f! Press TAB or type /effects to view your active effects!".toPattern(),
+
+ // Fix for Hypixel having a different message for Poisoned Candy.
+ // Did not make the first pattern optional to prevent conflicts with Dungeon Buffs/other things
+ "§a§lBUFF! §fYou have gained §r(?<effectName>§2Poisoned Candy I)§r§f!§r".toPattern(),
+ "§a§lBUFF! §fYou splashed yourself with §r(?<effectName>§2Poisoned Candy I)§r§f!§r".toPattern(),
+ "§a§lBUFF! §fYou were splashed by (?<playerName>.*) §fwith §r(?<effectName>§2Poisoned Candy I)§r§f!§r".toPattern()
+ )
@SubscribeEvent
fun onChatMessage(event: LorenzChatEvent) {
- if (!LorenzUtils.inSkyBlock || !config.enabled) return
-
- potionEffectPattern.matchMatcher(event.message) {
- val name = group("name")
- sendMessage("§a§lPotion Effect! §r$name")
- event.blockedReason = "compact_potion_effect"
- }
-
- potionSplashEffectOthersPattern.matchMatcher(event.message) {
- val playerName = group("playerName").removeColor()
- val effectName = group("effectName")
- sendMessage("§a§lPotion Effect! §r$effectName by §b$playerName")
- event.blockedReason = "compact_potion_effect"
- }
-
- potionSplashEffectPattern.matchMatcher(event.message) {
- val name = group("name")
- sendMessage("§a§lPotion Effect! §r$name")
- event.blockedReason = "compact_potion_effect"
- }
+ if (!isEnabled()) return
+ if (!event.message.isPotionMessage()) return
+ event.blockedReason = "compact_potion_effect"
}
private fun sendMessage(message: String) {
if (config.clickableChatMessage) {
- LorenzUtils.hoverableChat(message, listOf("§eClick to view your potion effects."), "/effects")
+ LorenzUtils.hoverableChat(
+ message,
+ listOf("§eClick to view your potion effects."),
+ "/effects",
+ prefix = false
+ )
} else {
- LorenzUtils.chat(message)
+ LorenzUtils.chat(message, prefix = false)
}
}
+
+ private fun String.isPotionMessage(): Boolean {
+ return potionEffectPatternList.any {
+ it.matchMatcher(this) {
+ val effectName = group("effectName")
+ // If splashed by a player, append their name.
+ val byPlayer = groupOrNull("playerName")?.let { player ->
+ val displayName = player.cleanPlayerName(displayName = true)
+ " §aby $displayName"
+ } ?: ""
+ sendMessage("§a§lPotion Effect! §r$effectName$byPlayer")
+ } != null
+ }
+ }
+
+ private fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt
index 2cfdb5dc9..3cc67e617 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt
@@ -25,7 +25,7 @@ class Translator {
// Logic for listening for a user click on a chat message is from NotEnoughUpdates
@SubscribeEvent(priority = EventPriority.LOWEST)
- fun onGuiChat(event: LorenzChatEvent) {
+ fun onChat(event: LorenzChatEvent) {
if (!isEnabled()) return
val message = event.message
diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatFilter.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatFilter.kt
index ed1a256d5..4a80f8084 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatFilter.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatFilter.kt
@@ -2,7 +2,7 @@ package at.hannibal2.skyhanni.features.chat.playerchat
import at.hannibal2.skyhanni.events.RepositoryReloadEvent
import at.hannibal2.skyhanni.utils.MultiFilter
-import at.hannibal2.skyhanni.utils.jsonobjects.PlayerChatFilterJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.PlayerChatFilterJson
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class PlayerChatFilter {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaFontRenderer.kt b/src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaFontRenderer.kt
index 469fc2f3c..26dc45969 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaFontRenderer.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaFontRenderer.kt
@@ -31,9 +31,7 @@ class ChromaFontRenderer(private val baseColor: Int) {
}
fun restoreChromaEnv() {
- if (ShaderHelper.areShadersSupported()) {
- if (!chromaOn) ChromaShaderManager.end()
- }
+ if (ShaderHelper.areShadersSupported() && !chromaOn) ChromaShaderManager.end()
}
fun newChromaEnv(): ChromaFontRenderer {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaShader.kt b/src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaShader.kt
index e7bedbdcd..8afd758a7 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaShader.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/chroma/ChromaShader.kt
@@ -13,32 +13,32 @@ import net.minecraft.client.Minecraft
* Credit: [ChromaShader.java](https://github.com/BiscuitDevelopment/SkyblockAddons/blob/main/src/main/java/codes/biscuit/skyblockaddons/shader/chroma/ChromaShader.java)
*/
object ChromaShader : Shader("chroma", "chroma") {
-
+ val config get() = SkyHanniMod.feature.chroma
val INSTANCE: ChromaShader
get() = this
override fun registerUniforms() {
registerUniform(Uniform.UniformType.FLOAT, "chromaSize") {
- SkyHanniMod.feature.chroma.chromaSize * (Minecraft.getMinecraft().displayWidth / 100f)
+ config.chromaSize * (Minecraft.getMinecraft().displayWidth / 100f)
}
registerUniform(Uniform.UniformType.FLOAT, "timeOffset") {
var ticks =
(MinecraftData.totalTicks / 2) + (Minecraft.getMinecraft() as AccessorMinecraft).timer.renderPartialTicks
- ticks = when (SkyHanniMod.feature.chroma.chromaDirection) {
+ ticks = when (config.chromaDirection) {
0, 2 -> ticks
1, 3 -> -ticks
else -> ticks
}
- val chromaSpeed = SkyHanniMod.feature.chroma.chromaSpeed / 360f
+ val chromaSpeed = config.chromaSpeed / 360f
ticks * chromaSpeed
}
registerUniform(Uniform.UniformType.FLOAT, "saturation") {
- SkyHanniMod.feature.chroma.chromaSaturation
+ config.chromaSaturation
}
registerUniform(Uniform.UniformType.BOOL, "forwardDirection") {
- when (SkyHanniMod.feature.chroma.chromaDirection) {
+ when (config.chromaDirection) {
0, 1 -> true
2, 3 -> false
else -> true
diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/BestiaryData.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/BestiaryData.kt
index 5f0a4125e..daf5caddd 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/combat/BestiaryData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/combat/BestiaryData.kt
@@ -15,7 +15,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.addButton
import at.hannibal2.skyhanni.utils.NumberUtil
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber
-import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded
+import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary
import at.hannibal2.skyhanni.utils.NumberUtil.roundToPrecision
import at.hannibal2.skyhanni.utils.NumberUtil.toRoman
import at.hannibal2.skyhanni.utils.RenderUtils.highlight
@@ -245,7 +245,7 @@ object BestiaryData {
private fun getMobHover(mob: BestiaryMob) = listOf(
"§6Name: §b${mob.name}",
- "§6Level: §b${mob.level} ${if (!config.replaceRoman) "§7(${mob.level.romanToDecimalIfNeeded()})" else ""}",
+ "§6Level: §b${mob.level} ${if (!config.replaceRoman) "§7(${mob.level.romanToDecimalIfNecessary()})" else ""}",
"§6Total Kills: §b${mob.actualRealTotalKill.formatNumber()}",
"§6Kills needed to max: §b${mob.killNeededToMax().formatNumber()}",
"§6Kills needed to next lvl: §b${mob.killNeededToNextLevel().formatNumber()}",
@@ -459,7 +459,7 @@ object BestiaryData {
}
- private fun String.romanOrInt() = romanToDecimalIfNeeded().let {
+ private fun String.romanOrInt() = romanToDecimalIfNecessary().let {
if (config.replaceRoman || it == 0) it.toString() else it.toRoman()
}
@@ -473,7 +473,7 @@ object BestiaryData {
if (this == "0") {
"I".romanOrInt()
} else {
- val intValue = romanToDecimalIfNeeded()
+ val intValue = romanToDecimalIfNecessary()
(intValue + 1).toRoman().romanOrInt()
}
}
@@ -486,4 +486,4 @@ object BestiaryData {
private fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/BossType.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/BossType.kt
index 664aa63d4..045eaaa78 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/BossType.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/BossType.kt
@@ -1,94 +1,109 @@
package at.hannibal2.skyhanni.features.combat.damageindicator
+import at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry
+
+typealias Type = DamageIndicatorBossEntry
+
enum class BossType(
val fullName: String,
- val bossTypeToggle: Int,
+ val bossTypeToggle: Type,
val shortName: String = fullName,
val showDeathTime: Boolean = false
) {
- GENERIC_DUNGEON_BOSS("Generic Dungeon boss", 0),//TODO split into different bosses
+ GENERIC_DUNGEON_BOSS("Generic Dungeon boss", Type.DUNGEON_ALL),//TODO split into different bosses
//Nether Mini Bosses
- NETHER_BLADESOUL("§8Bladesoul", 1),
- NETHER_MAGMA_BOSS("§4Magma Boss", 1),
- NETHER_ASHFANG("§cAshfang", 1),
- NETHER_BARBARIAN_DUKE("§eBarbarian Duke", 1),
- NETHER_MAGE_OUTLAW("§5Mage Outlaw", 1),
-
- NETHER_VANQUISHER("§5Vanquisher", 2),
-
- END_ENDSTONE_PROTECTOR("§cEndstone Protector", 3),
- END_ENDER_DRAGON("Ender Dragon", 4),//TODO fix totally
-
- SLAYER_ZOMBIE_1("§aRevenant Horror 1", 5, "§aRev 1", showDeathTime = true),
- SLAYER_ZOMBIE_2("§eRevenant Horror 2", 5, "§eRev 2", showDeathTime = true),
- SLAYER_ZOMBIE_3("§cRevenant Horror 3", 5, "§cRev 3", showDeathTime = true),
- SLAYER_ZOMBIE_4("§4Revenant Horror 4", 5, "§4Rev 4", showDeathTime = true),
- SLAYER_ZOMBIE_5("§5Revenant Horror 5", 5, "§5Rev 5", showDeathTime = true),
-
- SLAYER_SPIDER_1("§aTarantula Broodfather 1", 6, "§aTara 1", showDeathTime = true),
- SLAYER_SPIDER_2("§eTarantula Broodfather 2", 6, "§eTara 2", showDeathTime = true),
- SLAYER_SPIDER_3("§cTarantula Broodfather 3", 6, "§cTara 3", showDeathTime = true),
- SLAYER_SPIDER_4("§4Tarantula Broodfather 4", 6, "§4Tara 4", showDeathTime = true),
-
- SLAYER_WOLF_1("§aSven Packmaster 1", 7, "§aSven 1", showDeathTime = true),
- SLAYER_WOLF_2("§eSven Packmaster 2", 7, "§eSven 2", showDeathTime = true),
- SLAYER_WOLF_3("§cSven Packmaster 3", 7, "§cSven 3", showDeathTime = true),
- SLAYER_WOLF_4("§4Sven Packmaster 4", 7, "§4Sven 4", showDeathTime = true),
-
- SLAYER_ENDERMAN_1("§aVoidgloom Seraph 1", 8, "§aVoid 1", showDeathTime = true),
- SLAYER_ENDERMAN_2("§eVoidgloom Seraph 2", 8, "§eVoid 2", showDeathTime = true),
- SLAYER_ENDERMAN_3("§cVoidgloom Seraph 3", 8, "§cVoid 3", showDeathTime = true),
- SLAYER_ENDERMAN_4("§4Voidgloom Seraph 4", 8, "§4Void 4", showDeathTime = true),
-
- SLAYER_BLAZE_1("§aInferno Demonlord 1", 9, "§aInferno 1", showDeathTime = true),
- SLAYER_BLAZE_2("§aInferno Demonlord 2", 9, "§aInferno 2", showDeathTime = true),
- SLAYER_BLAZE_3("§aInferno Demonlord 3", 9, "§aInferno 3", showDeathTime = true),
- SLAYER_BLAZE_4("§aInferno Demonlord 4", 9, "§aInferno 4", showDeathTime = true),
-
- SLAYER_BLAZE_TYPHOEUS_1("§aInferno Typhoeus 1", 9, "§aTyphoeus 1"),
- SLAYER_BLAZE_TYPHOEUS_2("§eInferno Typhoeus 2", 9, "§eTyphoeus 2"),
- SLAYER_BLAZE_TYPHOEUS_3("§cInferno Typhoeus 3", 9, "§cTyphoeus 3"),
- SLAYER_BLAZE_TYPHOEUS_4("§cInferno Typhoeus 4", 9, "§cTyphoeus 4"),
-
- SLAYER_BLAZE_QUAZII_1("§aInferno Quazii 1", 9, "§aQuazii 1"),
- SLAYER_BLAZE_QUAZII_2("§eInferno Quazii 2", 9, "§eQuazii 2"),
- SLAYER_BLAZE_QUAZII_3("§cInferno Quazii 3", 9, "§cQuazii 3"),
- SLAYER_BLAZE_QUAZII_4("§cInferno Quazii 4", 9, "§cQuazii 4"),
-
- SLAYER_BLOODFIEND_1("§aRiftstalker Bloodfiend 1", 23, "§aBlood 1", showDeathTime = true),
- SLAYER_BLOODFIEND_2("§6Riftstalker Bloodfiend 2", 23, "§6Blood 2", showDeathTime = true),
- SLAYER_BLOODFIEND_3("§cRiftstalker Bloodfiend 3", 23, "§cBlood 3", showDeathTime = true),
- SLAYER_BLOODFIEND_4("§4Riftstalker Bloodfiend 4", 23, "§4Blood 4", showDeathTime = true),
- SLAYER_BLOODFIEND_5("§5Riftstalker Bloodfiend 5", 23, "§5Blood 5", showDeathTime = true),
-
- HUB_HEADLESS_HORSEMAN("§6Headless Horseman", 10),
-
- DUNGEON_F1("", 11),
- DUNGEON_F2("", 12),
- DUNGEON_F3("", 13),
- DUNGEON_F4_THORN("§cThorn", 14),
- DUNGEON_F5("§dLivid", 15),
- DUNGEON_F("", 16),
- DUNGEON_75("", 17),
-
- MINOS_INQUISITOR("§5Minos Inquisitor", 18),
- MINOS_CHAMPION("§2Minos Champion", 18),
- GAIA_CONSTURUCT("§2Gaia Construct", 18),
- MINOTAUR("§2Minotaur", 18),
-
- THUNDER("§cThunder", 19),
- LORD_JAWBUS("§cLord Jawbus", 19),
-
- DUMMY("Dummy", 20),
- ARACHNE_SMALL("§cSmall Arachne", 21),
- ARACHNE_BIG("§4Big Arachne", 21),
+ NETHER_BLADESOUL("§8Bladesoul", Type.NETHER_MINI_BOSSES),
+ NETHER_MAGMA_BOSS("§4Magma Boss", Type.NETHER_MINI_BOSSES),
+ NETHER_ASHFANG("§cAshfang", Type.NETHER_MINI_BOSSES),
+ NETHER_BARBARIAN_DUKE("§eBarbarian Duke", Type.NETHER_MINI_BOSSES),
+ NETHER_MAGE_OUTLAW("§5Mage Outlaw", Type.NETHER_MINI_BOSSES),
+
+ NETHER_VANQUISHER("§5Vanquisher", Type.VANQUISHER),
+
+ END_ENDSTONE_PROTECTOR("§cEndstone Protector", Type.ENDERSTONE_PROTECTOR),
+ END_ENDER_DRAGON("Ender Dragon", Type.ENDER_DRAGON),//TODO fix totally
+
+ SLAYER_ZOMBIE_1("§aRevenant Horror 1", Type.REVENANT_HORROR, "§aRev 1", showDeathTime = true),
+ SLAYER_ZOMBIE_2("§eRevenant Horror 2", Type.REVENANT_HORROR, "§eRev 2", showDeathTime = true),
+ SLAYER_ZOMBIE_3("§cRevenant Horror 3", Type.REVENANT_HORROR, "§cRev 3", showDeathTime = true),
+ SLAYER_ZOMBIE_4("§4Revenant Horror 4", Type.REVENANT_HORROR, "§4Rev 4", showDeathTime = true),
+ SLAYER_ZOMBIE_5("§5Revenant Horror 5", Type.REVENANT_HORROR, "§5Rev 5", showDeathTime = true),
+
+ SLAYER_SPIDER_1("§aTarantula Broodfather 1", Type.TARANTULA_BROODFATHER, "§aTara 1", showDeathTime = true),
+ SLAYER_SPIDER_2("§eTarantula Broodfather 2", Type.TARANTULA_BROODFATHER, "§eTara 2", showDeathTime = true),
+ SLAYER_SPIDER_3("§cTarantula Broodfather 3", Type.TARANTULA_BROODFATHER, "§cTara 3", showDeathTime = true),
+ SLAYER_SPIDER_4("§4Tarantula Broodfather 4", Type.TARANTULA_BROODFATHER, "§4Tara 4", showDeathTime = true),
+
+ SLAYER_WOLF_1("§aSven Packmaster 1", Type.SVEN_PACKMASTER, "§aSven 1", showDeathTime = true),
+ SLAYER_WOLF_2("§eSven Packmaster 2", Type.SVEN_PACKMASTER, "§eSven 2", showDeathTime = true),
+ SLAYER_WOLF_3("§cSven Packmaster 3", Type.SVEN_PACKMASTER, "§cSven 3", showDeathTime = true),
+ SLAYER_WOLF_4("§4Sven Packmaster 4", Type.SVEN_PACKMASTER, "§4Sven 4", showDeathTime = true),
+
+ SLAYER_ENDERMAN_1("§aVoidgloom Seraph 1", Type.VOIDGLOOM_SERAPH, "§aVoid 1", showDeathTime = true),
+ SLAYER_ENDERMAN_2("§eVoidgloom Seraph 2", Type.VOIDGLOOM_SERAPH, "§eVoid 2", showDeathTime = true),
+ SLAYER_ENDERMAN_3("§cVoidgloom Seraph 3", Type.VOIDGLOOM_SERAPH, "§cVoid 3", showDeathTime = true),
+ SLAYER_ENDERMAN_4("§4Voidgloom Seraph 4", Type.VOIDGLOOM_SERAPH, "§4Void 4", showDeathTime = true),
+
+ SLAYER_BLAZE_1("§aInferno Demonlord 1", Type.INFERNO_DEMONLORD, "§aInferno 1", showDeathTime = true),
+ SLAYER_BLAZE_2("§aInferno Demonlord 2", Type.INFERNO_DEMONLORD, "§aInferno 2", showDeathTime = true),
+ SLAYER_BLAZE_3("§aInferno Demonlord 3", Type.INFERNO_DEMONLORD, "§aInferno 3", showDeathTime = true),
+ SLAYER_BLAZE_4("§aInferno Demonlord 4", Type.INFERNO_DEMONLORD, "§aInferno 4", showDeathTime = true),
+
+ SLAYER_BLAZE_TYPHOEUS_1("§aInferno Typhoeus 1", Type.INFERNO_DEMONLORD, "§aTyphoeus 1"),
+ SLAYER_BLAZE_TYPHOEUS_2("§eInferno Typhoeus 2", Type.INFERNO_DEMONLORD, "§eTyphoeus 2"),
+ SLAYER_BLAZE_TYPHOEUS_3("§cInferno Typhoeus 3", Type.INFERNO_DEMONLORD, "§cTyphoeus 3"),
+ SLAYER_BLAZE_TYPHOEUS_4("§cInferno Typhoeus 4", Type.INFERNO_DEMONLORD, "§cTyphoeus 4"),
+
+ SLAYER_BLAZE_QUAZII_1("§aInferno Quazii 1", Type.INFERNO_DEMONLORD, "§aQuazii 1"),
+ SLAYER_BLAZE_QUAZII_2("§eInferno Quazii 2", Type.INFERNO_DEMONLORD, "§eQuazii 2"),
+ SLAYER_BLAZE_QUAZII_3("§cInferno Quazii 3", Type.INFERNO_DEMONLORD, "§cQuazii 3"),
+ SLAYER_BLAZE_QUAZII_4("§cInferno Quazii 4", Type.INFERNO_DEMONLORD, "§cQuazii 4"),
+
+ SLAYER_BLOODFIEND_1("§aRiftstalker Bloodfiend 1", Type.RIFTSTALKER_BLOODFIEND, "§aBlood 1", showDeathTime = true),
+ SLAYER_BLOODFIEND_2("§6Riftstalker Bloodfiend 2", Type.RIFTSTALKER_BLOODFIEND, "§6Blood 2", showDeathTime = true),
+ SLAYER_BLOODFIEND_3("§cRiftstalker Bloodfiend 3", Type.RIFTSTALKER_BLOODFIEND, "§cBlood 3", showDeathTime = true),
+ SLAYER_BLOODFIEND_4("§4Riftstalker Bloodfiend 4", Type.RIFTSTALKER_BLOODFIEND, "§4Blood 4", showDeathTime = true),
+ SLAYER_BLOODFIEND_5("§5Riftstalker Bloodfiend 5", Type.RIFTSTALKER_BLOODFIEND, "§5Blood 5", showDeathTime = true),
+
+ HUB_HEADLESS_HORSEMAN("§6Headless Horseman", Type.HEADLESS_HORSEMAN),
+
+ DUNGEON_F1("", Type.DUNGEON_FLOOR_1),
+ DUNGEON_F2("", Type.DUNGEON_FLOOR_2),
+ DUNGEON_F3("", Type.DUNGEON_FLOOR_3),
+ DUNGEON_F4_THORN("§cThorn", Type.DUNGEON_FLOOR_4),
+ DUNGEON_F5("§dLivid", Type.DUNGEON_FLOOR_5),
+ DUNGEON_F("", Type.DUNGEON_FLOOR_6),
+ DUNGEON_75("", Type.DUNGEON_FLOOR_7),
+
+ MINOS_INQUISITOR("§5Minos Inquisitor", Type.DIANA_MOBS),
+ MINOS_CHAMPION("§2Minos Champion", Type.DIANA_MOBS),
+ GAIA_CONSTURUCT("§2Gaia Construct", Type.DIANA_MOBS),
+ MINOTAUR("§2Minotaur", Type.DIANA_MOBS),
+
+ THUNDER("§cThunder", Type.SEA_CREATURES),
+ LORD_JAWBUS("§cLord Jawbus", Type.SEA_CREATURES),
+
+ DUMMY("Dummy", Type.DUMMY),
+ ARACHNE_SMALL("§cSmall Arachne", Type.ARACHNE),
+ ARACHNE_BIG("§4Big Arachne", Type.ARACHNE),
// The Rift
- LEECH_SUPREME("§cLeech Supreme", 22),
- BACTE("§aBacte", 22),
-
- WINTER_REINDRAKE("Reindrake", 24),//TODO fix totally
+ LEECH_SUPREME("§cLeech Supreme", Type.THE_RIFT_BOSSES),
+ BACTE("§aBacte", Type.THE_RIFT_BOSSES),
+
+ WINTER_REINDRAKE("Reindrake", Type.REINDRAKE),//TODO fix totally
+
+ GARDEN_PEST_BEETLE("§cBeetle", Type.GARDEN_PESTS),
+ GARDEN_PEST_CRICKET("§cCricket", Type.GARDEN_PESTS),
+ GARDEN_PEST_FLY("§cFly", Type.GARDEN_PESTS),
+ GARDEN_PEST_LOCUST("§cLocust", Type.GARDEN_PESTS),
+ GARDEN_PEST_MITE("§cMite", Type.GARDEN_PESTS),
+ GARDEN_PEST_MOSQUITO("§cMosquito", Type.GARDEN_PESTS),
+ GARDEN_PEST_MOTH("§cMoth", Type.GARDEN_PESTS),
+ GARDEN_PEST_RAT("§cRat", Type.GARDEN_PESTS),
+ GARDEN_PEST_SLUG("§cSlug", Type.GARDEN_PESTS),
+ GARDEN_PEST_EARTHWORM("§cEarthworm", Type.GARDEN_PESTS),
//TODO arachne
@@ -108,4 +123,4 @@ enum class BossType(
*/
//TODO diana mythological creatures
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/DamageIndicatorManager.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/DamageIndicatorManager.kt
index ebe6e9397..b12f48cba 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/DamageIndicatorManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/DamageIndicatorManager.kt
@@ -2,10 +2,13 @@ package at.hannibal2.skyhanni.features.combat.damageindicator
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
+import at.hannibal2.skyhanni.config.features.combat.damageindicator.DamageIndicatorConfig.DamageIndicatorBossEntry
import at.hannibal2.skyhanni.data.ScoreboardData
import at.hannibal2.skyhanni.events.BossHealthChangeEvent
+import at.hannibal2.skyhanni.events.DamageIndicatorDeathEvent
import at.hannibal2.skyhanni.events.DamageIndicatorDetectedEvent
import at.hannibal2.skyhanni.events.DamageIndicatorFinalBossEvent
+import at.hannibal2.skyhanni.events.EntityHealthUpdateEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
@@ -14,7 +17,9 @@ import at.hannibal2.skyhanni.features.dungeon.DungeonAPI
import at.hannibal2.skyhanni.features.slayer.blaze.HellionShield
import at.hannibal2.skyhanni.features.slayer.blaze.setHellionShield
import at.hannibal2.skyhanni.test.command.ErrorManager
+import at.hannibal2.skyhanni.utils.ConfigUtils
import at.hannibal2.skyhanni.utils.EntityUtils
+import at.hannibal2.skyhanni.utils.EntityUtils.canBeSeen
import at.hannibal2.skyhanni.utils.EntityUtils.getNameTagWith
import at.hannibal2.skyhanni.utils.EntityUtils.hasNameTagWith
import at.hannibal2.skyhanni.utils.LocationUtils
@@ -157,7 +162,7 @@ class DamageIndicatorManager {
// data.ignoreBlocks =
// data.bossType == BossType.END_ENDSTONE_PROTECTOR && Minecraft.getMinecraft().thePlayer.isSneaking
- if (!data.ignoreBlocks && !player.canEntityBeSeen(data.entity)) continue
+ if (!data.ignoreBlocks && !data.entity.canBeSeen(70.0)) continue
if (!data.isConfigEnabled()) continue
val entity = data.entity
@@ -852,10 +857,24 @@ class DamageIndicatorManager {
}
@SubscribeEvent
+ fun onEntityHealthUpdate(event: EntityHealthUpdateEvent) {
+ val data = data[event.entity.uniqueID] ?: return
+ if (event.health <= 1) {
+ if (!data.firstDeath) {
+ data.firstDeath = true
+ DamageIndicatorDeathEvent(event.entity, data).postAndCatch()
+ }
+ }
+ }
+
+ @SubscribeEvent
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
event.move(2, "damageIndicator", "combat.damageIndicator")
event.move(3, "slayer.endermanPhaseDisplay", "slayer.endermen.phaseDisplay")
event.move(3, "slayer.blazePhaseDisplay", "slayer.blazes.phaseDisplay")
+ event.move(11, "combat.damageIndicator.bossesToShow", "combat.damageIndicator.bossesToShow") { element ->
+ ConfigUtils.migrateIntArrayListToEnumArrayList(element, DamageIndicatorBossEntry::class.java)
+ }
}
fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled
diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/EntityData.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/EntityData.kt
index 970bdd0dd..50e5b4547 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/EntityData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/EntityData.kt
@@ -21,10 +21,11 @@ class EntityData(
var nameSuffix: String = "",
var nameAbove: String = "",
var dead: Boolean = false,
+ var firstDeath: Boolean = false, // TODO this defines if hp is very low, replace dead with this later
var deathLocation: LorenzVec? = null,
) {
val timeToKill by lazy {
val duration = System.currentTimeMillis() - foundTime
"§e" + TimeUtils.formatDuration(duration, TimeUnit.SECOND, showMilliSeconds = true)
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/MobFinder.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/MobFinder.kt
index 6cc9b4b85..0d39c0233 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/MobFinder.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/MobFinder.kt
@@ -3,6 +3,8 @@ package at.hannibal2.skyhanni.features.combat.damageindicator
import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.features.dungeon.DungeonAPI
import at.hannibal2.skyhanni.features.dungeon.DungeonLividFinder
+import at.hannibal2.skyhanni.features.garden.GardenAPI
+import at.hannibal2.skyhanni.features.garden.pests.PestType
import at.hannibal2.skyhanni.features.rift.RiftAPI
import at.hannibal2.skyhanni.utils.EntityUtils
import at.hannibal2.skyhanni.utils.EntityUtils.hasBossHealth
@@ -14,7 +16,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.baseMaxHealth
import at.hannibal2.skyhanni.utils.LorenzUtils.derpy
import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland
import at.hannibal2.skyhanni.utils.LorenzVec
-import at.hannibal2.skyhanni.utils.StringUtils.matchRegex
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.getLorenzVec
import net.minecraft.client.entity.EntityOtherPlayerMP
import net.minecraft.entity.Entity
@@ -30,10 +32,12 @@ import net.minecraft.entity.monster.EntityGuardian
import net.minecraft.entity.monster.EntityIronGolem
import net.minecraft.entity.monster.EntityMagmaCube
import net.minecraft.entity.monster.EntityPigZombie
+import net.minecraft.entity.monster.EntitySilverfish
import net.minecraft.entity.monster.EntitySkeleton
import net.minecraft.entity.monster.EntitySlime
import net.minecraft.entity.monster.EntitySpider
import net.minecraft.entity.monster.EntityZombie
+import net.minecraft.entity.passive.EntityBat
import net.minecraft.entity.passive.EntityHorse
import net.minecraft.entity.passive.EntityWolf
import java.util.UUID
@@ -67,6 +71,8 @@ class MobFinder {
//F5
private var floor5lividEntity: EntityOtherPlayerMP? = null
private var floor5lividEntitySpawnTime = 0L
+ private val correctLividPattern =
+ "§c\\[BOSS] (.*) Livid§r§f: Impossible! How did you figure out which one I was\\?!".toPattern()
//F6
private var floor6Giants = false
@@ -78,6 +84,7 @@ class MobFinder {
internal fun tryAdd(entity: EntityLivingBase) = when {
LorenzUtils.inDungeons -> tryAddDungeon(entity)
RiftAPI.inRift() -> tryAddRift(entity)
+ GardenAPI.inGarden() -> tryAddGarden(entity)
else -> {
when (entity) {
/*
@@ -106,6 +113,22 @@ class MobFinder {
}
}
+ private fun tryAddGarden(entity: EntityLivingBase): EntityResult? {
+ if (entity is EntitySilverfish || entity is EntityBat) {
+ return tryAddGardenPest(entity)
+ }
+
+ return null
+ }
+
+ private fun tryAddGardenPest(entity: EntityLivingBase): EntityResult? {
+ if (!GardenAPI.inGarden()) return null
+
+ return PestType.entries
+ .firstOrNull { entity.hasNameTagWith(3, it.displayName) }
+ ?.let { EntityResult(bossType = it.damageIndicatorBoss) }
+ }
+
private fun tryAddDungeon(entity: EntityLivingBase) = when {
DungeonAPI.isOneOf("F1", "M1") -> tryAddDungeonF1(entity)
DungeonAPI.isOneOf("F2", "M2") -> tryAddDungeonF2(entity)
@@ -566,7 +589,7 @@ class MobFinder {
}
}
- if (message.matchRegex("§c\\[BOSS] (.*) Livid§r§f: Impossible! How did you figure out which one I was\\?!")) {
+ correctLividPattern.matchMatcher(message) {
floor5lividEntity = null
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/endernodetracker/EnderNodeTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/endernodetracker/EnderNodeTracker.kt
index b65021067..51f9a7e8b 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/combat/endernodetracker/EnderNodeTracker.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/combat/endernodetracker/EnderNodeTracker.kt
@@ -2,6 +2,7 @@ package at.hannibal2.skyhanni.features.combat.endernodetracker
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
+import at.hannibal2.skyhanni.config.features.combat.EnderNodeConfig.EnderNodeDisplayEntry
import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.data.ProfileStorageData
import at.hannibal2.skyhanni.events.ConfigLoadEvent
@@ -10,6 +11,7 @@ import at.hannibal2.skyhanni.events.IslandChangeEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.OwnInventoryItemUpdateEvent
import at.hannibal2.skyhanni.events.SackChangeEvent
+import at.hannibal2.skyhanni.utils.ConfigUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalNameOrNull
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
@@ -22,7 +24,6 @@ import at.hannibal2.skyhanni.utils.NumberUtil.format
import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker
import at.hannibal2.skyhanni.utils.tracker.TrackerData
import com.google.gson.annotations.Expose
-import io.github.moulberry.notenoughupdates.util.MinecraftExecutor
import net.minecraft.client.Minecraft
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
@@ -128,18 +129,16 @@ object EnderNodeTracker {
if (!isInTheEnd()) return
if (!ProfileStorageData.loaded) return
- MinecraftExecutor.OnThread.execute {
- val newMiteGelInInventory = Minecraft.getMinecraft().thePlayer.inventory.mainInventory
- .filter { it?.getInternalNameOrNull() == EnderNode.MITE_GEL.internalName }
- .sumOf { it.stackSize }
- val change = newMiteGelInInventory - miteGelInInventory
- if (change > 0) {
- tracker.modify { storage ->
- storage.lootCount.addOrPut(EnderNode.MITE_GEL, change)
- }
+ val newMiteGelInInventory = Minecraft.getMinecraft().thePlayer.inventory.mainInventory
+ .filter { it?.getInternalNameOrNull() == EnderNode.MITE_GEL.internalName }
+ .sumOf { it.stackSize }
+ val change = newMiteGelInInventory - miteGelInInventory
+ if (change > 0) {
+ tracker.modify { storage ->
+ storage.lootCount.addOrPut(EnderNode.MITE_GEL, change)
}
- miteGelInInventory = newMiteGelInInventory
}
+ miteGelInInventory = newMiteGelInInventory
}
@SubscribeEvent
@@ -161,6 +160,9 @@ object EnderNodeTracker {
@SubscribeEvent
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
event.move(2, "misc.enderNodeTracker", "combat.enderNodeTracker")
+ event.move(11, "combat.enderNodeTracker.textFormat", "combat.enderNodeTracker.textFormat") { element ->
+ ConfigUtils.migrateIntArrayListToEnumArrayList(element, EnderNodeDisplayEntry::class.java)
+ }
}
private fun calculateProfit(storage: Data): Map<EnderNode, Double> {
@@ -245,7 +247,8 @@ object EnderNodeTracker {
val newList = mutableListOf<List<Any>>()
for (index in config.textFormat.get()) {
- newList.add(map[index])
+ // TODO, change functionality to use enum rather than ordinals
+ newList.add(map[index.ordinal])
}
return newList
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostCounter.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostCounter.kt
index 56e70437c..eb9b68643 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostCounter.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostCounter.kt
@@ -2,6 +2,7 @@ package at.hannibal2.skyhanni.features.combat.ghostcounter
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
+import at.hannibal2.skyhanni.config.features.combat.ghostcounter.GhostCounterConfig.GhostDisplayEntry
import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.data.ProfileStorageData
import at.hannibal2.skyhanni.data.SkillExperience
@@ -34,6 +35,7 @@ import at.hannibal2.skyhanni.utils.CombatUtils.lastKillUpdate
import at.hannibal2.skyhanni.utils.CombatUtils.lastUpdate
import at.hannibal2.skyhanni.utils.CombatUtils.xpGainHour
import at.hannibal2.skyhanni.utils.CombatUtils.xpGainHourLast
+import at.hannibal2.skyhanni.utils.ConfigUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
@@ -111,7 +113,8 @@ object GhostCounter {
private fun formatDisplay(map: List<List<Any>>): List<List<Any>> {
val newList = mutableListOf<List<Any>>()
for (index in config.ghostDisplayText) {
- newList.add(map[index])
+ // TODO, change functionality to use enum rather than ordinals
+ newList.add(map[index.ordinal])
}
return newList
}
@@ -488,6 +491,9 @@ object GhostCounter {
@SubscribeEvent
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
event.move(2, "ghostCounter", "combat.ghostCounter")
+ event.move(11, "combat.ghostCounter.ghostDisplayText", "combat.ghostCounter.ghostDisplayText") { element ->
+ ConfigUtils.migrateIntArrayListToEnumArrayList(element, GhostDisplayEntry::class.java)
+ }
}
fun isEnabled() = config.enabled && IslandType.DWARVEN_MINES.isInIsland()
diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostFormatting.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostFormatting.kt
index 70f64de29..183753e51 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostFormatting.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/combat/ghostcounter/GhostFormatting.kt
@@ -138,7 +138,7 @@ object GhostFormatting {
fun reset() {
with(GhostCounter.config.textFormatting) {
titleFormat = "&6Ghost Counter"
- ghostKilledFormat = " &6Ghost Killed: &b%value% &7(%session%)"
+ ghostKilledFormat = " &6Ghosts Killed: &b%value% &7(%session%)"
sorrowsFormat = " &6Sorrow: &b%value% &7(%session%)"
ghostSinceSorrowFormat = " &6Ghost since Sorrow: &b%value%"
ghostKillPerSorrowFormat = " &6Ghosts/Sorrow: &b%value%"
@@ -179,4 +179,4 @@ object GhostFormatting {
moneyMadeFormat = " &6Money made: &b%value%"
}
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/commands/SendCoordinatedCommand.kt b/src/main/java/at/hannibal2/skyhanni/features/commands/SendCoordinatedCommand.kt
index 8cc303fcf..a41547c68 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/commands/SendCoordinatedCommand.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/commands/SendCoordinatedCommand.kt
@@ -1,26 +1,22 @@
package at.hannibal2.skyhanni.features.commands
-import at.hannibal2.skyhanni.events.PacketEvent
+import at.hannibal2.skyhanni.events.MessageSendToServerEvent
import at.hannibal2.skyhanni.utils.LocationUtils
import at.hannibal2.skyhanni.utils.LorenzUtils
-import net.minecraft.network.play.client.C01PacketChatMessage
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class SendCoordinatedCommand {
@SubscribeEvent
- fun onSendPacket(event: PacketEvent.SendEvent) {
- val packet = event.packet
- if (packet is C01PacketChatMessage) {
- val message = packet.message.lowercase()
- if (message == "/sendcoords") {
- event.isCanceled = true
- LorenzUtils.sendMessageToServer(getCoordinates())
- } else if (message.startsWith("/sendcoords ")) {
- event.isCanceled = true
- val description = message.split(" ").drop(1).joinToString(" ")
- LorenzUtils.sendMessageToServer("${getCoordinates()} $description")
- }
+ fun onMessageSendToServer(event: MessageSendToServerEvent) {
+ val message = event.message
+ if (message == "/sendcoords") {
+ event.isCanceled = true
+ LorenzUtils.sendMessageToServer(getCoordinates())
+ } else if (message.startsWith("/sendcoords ")) {
+ event.isCanceled = true
+ val description = message.split(" ").drop(1).joinToString(" ")
+ LorenzUtils.sendMessageToServer("${getCoordinates()} $description")
}
}
@@ -32,5 +28,4 @@ class SendCoordinatedCommand {
return "x: $x, y: $y, z: $z"
}
-
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/commands/ViewRecipeCommand.kt b/src/main/java/at/hannibal2/skyhanni/features/commands/ViewRecipeCommand.kt
index 4464959e2..147775fed 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/commands/ViewRecipeCommand.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/commands/ViewRecipeCommand.kt
@@ -1,26 +1,22 @@
package at.hannibal2.skyhanni.features.commands
import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.events.PacketEvent
+import at.hannibal2.skyhanni.events.MessageSendToServerEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.NEUItems
-import net.minecraft.network.play.client.C01PacketChatMessage
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
object ViewRecipeCommand {
private val config get() = SkyHanniMod.feature.commands
@SubscribeEvent
- fun onSendPacket(event: PacketEvent.SendEvent) {
+ fun onMessageSendToServer(event: MessageSendToServerEvent) {
if (!config.viewRecipeLowerCase) return
- val packet = event.packet
- if (packet is C01PacketChatMessage) {
- val message = packet.message
- if (message == message.uppercase()) return
- if (message.startsWith("/viewrecipe ", ignoreCase = true)) {
- event.isCanceled = true
- LorenzUtils.sendMessageToServer(message.uppercase())
- }
+ val message = event.message
+ if (message == message.uppercase()) return
+ if (message.startsWith("/viewrecipe ", ignoreCase = true)) {
+ event.isCanceled = true
+ LorenzUtils.sendMessageToServer(message.uppercase())
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/commands/WarpIsCommand.kt b/src/main/java/at/hannibal2/skyhanni/features/commands/WarpIsCommand.kt
index eb9ea503e..4cb06b568 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/commands/WarpIsCommand.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/commands/WarpIsCommand.kt
@@ -1,22 +1,20 @@
package at.hannibal2.skyhanni.features.commands
import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.events.PacketEvent
+import at.hannibal2.skyhanni.events.MessageSendToServerEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
-import net.minecraft.network.play.client.C01PacketChatMessage
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class WarpIsCommand {
@SubscribeEvent
- fun onSendPacket(event: PacketEvent.SendEvent) {
+ fun onMessageSendToServer(event: MessageSendToServerEvent) {
if (!LorenzUtils.inSkyBlock) return
if (!SkyHanniMod.feature.commands.replaceWarpIs) return
- val packet = event.packet
- if (packet is C01PacketChatMessage && packet.message.lowercase() == "/warp is") {
+ if (event.message.lowercase() == "/warp is") {
event.isCanceled = true
LorenzUtils.sendMessageToServer("/is")
}
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/commands/WikiManager.kt b/src/main/java/at/hannibal2/skyhanni/features/commands/WikiManager.kt
index de7cc4408..b3bdbe42c 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/commands/WikiManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/commands/WikiManager.kt
@@ -2,7 +2,7 @@ package at.hannibal2.skyhanni.features.commands
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-import at.hannibal2.skyhanni.events.PacketEvent
+import at.hannibal2.skyhanni.events.MessageSendToServerEvent
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.ItemUtils.nameWithEnchantment
@@ -13,7 +13,6 @@ import at.hannibal2.skyhanni.utils.OSUtils
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import net.minecraft.client.gui.inventory.GuiContainer
import net.minecraft.item.ItemStack
-import net.minecraft.network.play.client.C01PacketChatMessage
import net.minecraftforge.client.event.GuiScreenEvent
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
@@ -32,29 +31,25 @@ class WikiManager {
}
@SubscribeEvent
- fun onSendPacket(event: PacketEvent.SendEvent) {
+ fun onMessageSendToServer(event: MessageSendToServerEvent) {
if (!LorenzUtils.inSkyBlock) return
if (!isEnabled()) return
- val packet = event.packet
-
- if (packet is C01PacketChatMessage) {
- val message = packet.message.lowercase()
- if (!(message.startsWith("/wiki"))) return
- event.isCanceled = true
- if (message == "/wiki") {
- LorenzUtils.chat("Opening the Fandom Wiki..")
- OSUtils.openBrowser("${urlPrefix}Hypixel_SkyBlock_Wiki")
- } else if (message.startsWith("/wiki ") || message == ("/wikithis")) { //conditional to see if we need Special:Search page
- if (message == ("/wikithis")) {
- val itemInHand = InventoryUtils.getItemInHand() ?: return
- wikiTheItem(itemInHand)
- } else {
- val search = packet.message.split("/wiki ").last()
- LorenzUtils.chat("Searching the Fandom Wiki for §a$search")
- val wikiUrlCustom = "$urlSearchPrefix$search&scope=internal"
- OSUtils.openBrowser(wikiUrlCustom.replace(' ', '+'))
- }
+ val message = event.message.lowercase()
+ if (!(message.startsWith("/wiki"))) return
+ event.isCanceled = true
+ if (message == "/wiki") {
+ LorenzUtils.chat("Opening the Fandom Wiki..")
+ OSUtils.openBrowser("${urlPrefix}Hypixel_SkyBlock_Wiki")
+ } else if (message.startsWith("/wiki ") || message == ("/wikithis")) { //conditional to see if we need Special:Search page
+ if (message == ("/wikithis")) {
+ val itemInHand = InventoryUtils.getItemInHand() ?: return
+ wikiTheItem(itemInHand)
+ } else {
+ val search = event.message.split("/wiki ").last()
+ LorenzUtils.chat("Searching the Fandom Wiki for §a$search")
+ val wikiUrlCustom = "$urlSearchPrefix$search&scope=internal"
+ OSUtils.openBrowser(wikiUrlCustom.replace(' ', '+'))
}
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/GetFromSacksTabComplete.kt b/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/GetFromSacksTabComplete.kt
index 97a110508..f3738c6b4 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/GetFromSacksTabComplete.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/GetFromSacksTabComplete.kt
@@ -1,11 +1,10 @@
package at.hannibal2.skyhanni.features.commands.tabcomplete
import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.events.PacketEvent
+import at.hannibal2.skyhanni.data.jsonobjects.repo.SacksJson
+import at.hannibal2.skyhanni.events.MessageSendToServerEvent
import at.hannibal2.skyhanni.events.RepositoryReloadEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.jsonobjects.SacksJson
-import net.minecraft.network.play.client.C01PacketChatMessage
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
object GetFromSacksTabComplete {
@@ -26,19 +25,18 @@ object GetFromSacksTabComplete {
}
@SubscribeEvent
- fun onSendPacket(event: PacketEvent.SendEvent) {
+ fun onMessageSendToServer(event: MessageSendToServerEvent) {
if (!isEnabled()) return
- val packet = event.packet as? C01PacketChatMessage ?: return
- val message = packet.message
- if (commands.any { message.startsWith("/$it ") }) {
- val rawName = message.split(" ")[1]
- val realName = rawName.replace("_", " ")
- if (realName == rawName) return
- if (realName !in sackList) return
- event.isCanceled = true
- LorenzUtils.sendMessageToServer(message.replace(rawName, realName))
- }
+ val message = event.message
+ if (!commands.any { message.startsWith("/$it ") }) return
+
+ val rawName = message.split(" ")[1]
+ val realName = rawName.replace("_", " ")
+ if (realName == rawName) return
+ if (realName !in sackList) return
+ event.isCanceled = true
+ LorenzUtils.sendMessageToServer(message.replace(rawName, realName))
}
fun isEnabled() = LorenzUtils.inSkyBlock && config.gfsSack
diff --git a/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/PlayerTabComplete.kt b/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/PlayerTabComplete.kt
index e6b2baaf8..9df128920 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/PlayerTabComplete.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/PlayerTabComplete.kt
@@ -6,7 +6,7 @@ import at.hannibal2.skyhanni.data.FriendAPI
import at.hannibal2.skyhanni.data.PartyAPI
import at.hannibal2.skyhanni.events.RepositoryReloadEvent
import at.hannibal2.skyhanni.utils.EntityUtils.isNPC
-import at.hannibal2.skyhanni.utils.jsonobjects.VipVisitsJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.VipVisitsJson
import net.minecraft.client.Minecraft
import net.minecraft.client.entity.EntityOtherPlayerMP
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
diff --git a/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/WarpTabComplete.kt b/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/WarpTabComplete.kt
index ea76e03ea..c5487fdb8 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/WarpTabComplete.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/WarpTabComplete.kt
@@ -3,7 +3,7 @@ package at.hannibal2.skyhanni.features.commands.tabcomplete
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.RepositoryReloadEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.jsonobjects.WarpsJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.WarpsJson
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
object WarpTabComplete {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/cosmetics/CosmeticFollowingLine.kt b/src/main/java/at/hannibal2/skyhanni/features/cosmetics/CosmeticFollowingLine.kt
index 662ad68a0..022ec07b9 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/cosmetics/CosmeticFollowingLine.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/cosmetics/CosmeticFollowingLine.kt
@@ -69,7 +69,7 @@ class CosmeticFollowingLine {
}
private fun updateClose(event: LorenzRenderWorldEvent) {
- val playerLocation = event.exactLocation(Minecraft.getMinecraft().thePlayer).add(0.0, 0.3, 0.0)
+ val playerLocation = event.exactLocation(Minecraft.getMinecraft().thePlayer).add(y = 0.3)
latestLocations = latestLocations.editCopy {
val locationSpot = LocationSpot(SimpleTimeMark.now(), Minecraft.getMinecraft().thePlayer.onGround)
@@ -110,7 +110,7 @@ class CosmeticFollowingLine {
}
if (event.isMod(2)) {
- val playerLocation = LocationUtils.playerLocation().add(0.0, 0.3, 0.0)
+ val playerLocation = LocationUtils.playerLocation().add(y = 0.3)
locations.keys.lastOrNull()?.let {
if (it.distance(playerLocation) < 0.1) return
diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonAPI.kt
index 8bbf2a015..2840565df 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonAPI.kt
@@ -16,7 +16,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.addOrPut
import at.hannibal2.skyhanni.utils.LorenzUtils.equalsOneOf
import at.hannibal2.skyhanni.utils.LorenzUtils.getOrNull
import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber
-import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded
+import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import at.hannibal2.skyhanni.utils.TabListData
@@ -115,7 +115,7 @@ class DungeonAPI {
DungeonClass.entries.forEach {
if (playerTeam.contains("(${it.scoreboardName} ")) {
- val level = playerTeam.split(" ").last().trimEnd(')').romanToDecimalIfNeeded()
+ val level = playerTeam.split(" ").last().trimEnd(')').romanToDecimalIfNecessary()
playerClass = it
playerClassLevel = level
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonBossMessages.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonBossMessages.kt
index b49839471..86d64b416 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonBossMessages.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonBossMessages.kt
@@ -3,11 +3,46 @@ package at.hannibal2.skyhanni.features.dungeon
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.StringUtils.matchRegex
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class DungeonBossMessages {
+ private val config get() = SkyHanniMod.feature.chat
+ private val bossPattern = "§([cd4])\\[BOSS] (.*)".toPattern()
+
+ private val excludedMessages = listOf(
+ "§c[BOSS] The Watcher§r§f: You have proven yourself. You may pass."
+ )
+
+ private val messageList = listOf(
+ //M7 – Dragons
+ "§cThe Crystal withers your soul as you hold it in your hands!",
+ "§cIt doesn't seem like that is supposed to go there."
+ )
+
+ private val messageContainsList = listOf(
+ " The Watcher§r§f: ",
+ " Bonzo§r§f: ",
+ " Scarf§r§f:",
+ "Professor§r§f",
+ " Livid§r§f: ",
+ " Enderman§r§f: ",
+ " Thorn§r§f: ",
+ " Sadan§r§f: ",
+ " Maxor§r§c: ",
+ " Storm§r§c: ",
+ " Goldor§r§c: ",
+ " Necron§r§c: ",
+ " §r§4§kWither King§r§c:"
+ )
+
+ private val messageEndsWithList = listOf(
+ " Necron§r§c: That is enough, fool!",
+ " Necron§r§c: Adventurers! Be careful of who you are messing with..",
+ " Necron§r§c: Before I have to deal with you myself."
+ )
+
@SubscribeEvent
fun onChatMessage(event: LorenzChatEvent) {
if (!LorenzUtils.inDungeons) return
@@ -15,40 +50,31 @@ class DungeonBossMessages {
DungeonAPI.handleBossMessage(event.message)
- if (SkyHanniMod.feature.chat.dungeonBossMessages) {
+ if (config.dungeonBossMessages) {
event.blockedReason = "dungeon_boss"
}
}
+ /**
+ * Checks if the message is a boss message
+ * @return true if the message is a boss message
+ * @param message The message to check
+ * @see excludedMessages
+ * @see messageList
+ * @see messageContainsList
+ * @see messageEndsWithList
+ */
private fun isBoss(message: String): Boolean {
- when {
- message.matchRegex("§([cd4])\\[BOSS] (.*)") -> {
- when {
- message.contains(" The Watcher§r§f: ") ->
- message != "§c[BOSS] The Watcher§r§f: You have proven yourself. You may pass."
-
- message.contains(" Bonzo§r§f: ") -> return true
- message.contains(" Scarf§r§f:") -> return true
- message.contains("Professor§r§f") -> return true
- message.contains(" Livid§r§f: ") || message.contains(" Enderman§r§f: ") -> return true
- message.contains(" Thorn§r§f: ") -> return true
- message.contains(" Sadan§r§f: ") -> return true
- message.contains(" Maxor§r§c: ") -> return true
- message.contains(" Storm§r§c: ") -> return true
- message.contains(" Goldor§r§c: ") -> return true
- message.contains(" Necron§r§c: ") -> return true
- message.contains(" §r§4§kWither King§r§c:") -> return true
-
- message.endsWith(" Necron§r§c: That is enough, fool!") -> return true
- message.endsWith(" Necron§r§c: Adventurers! Be careful of who you are messing with..") -> return true
- message.endsWith(" Necron§r§c: Before I have to deal with you myself.") -> return true
- }
- }
-
- //M7 – Dragons
- message == "§cThe Crystal withers your soul as you hold it in your hands!" -> return true
- message == "§cIt doesn't seem like that is supposed to go there." -> return true
+ // Cases that match below but should not be blocked
+ if (message in excludedMessages) return false
+
+ // Exact Matches
+ if (message in messageList) return true
+
+ // Matches Regex for Boss Prefix
+ bossPattern.matchMatcher(message) {
+ return messageContainsList.any { message.contains(it) } || messageEndsWithList.any { message.endsWith(it) }
}
return false
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonChatFilter.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonChatFilter.kt
index 5559ba14a..4bc4b3c46 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonChatFilter.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonChatFilter.kt
@@ -3,18 +3,198 @@ package at.hannibal2.skyhanni.features.dungeon
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.StringUtils.matchRegex
+import at.hannibal2.skyhanni.utils.StringUtils.matches
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import java.util.regex.Pattern
class DungeonChatFilter {
+ private val config get() = SkyHanniMod.feature.chat
+
+ /// <editor-fold desc="Patterns, Messages, and Maps">
+ // TODO USE SH-REPO
+ private val endPatterns = listOf(
+ "(.*) §r§eunlocked §r§d(.*) Essence §r§8x(.*)§r§e!".toPattern(),
+ " {4}§r§d(.*) Essence §r§8x(.*)".toPattern()
+ )
+ private val endMessagesEndWith = listOf(
+ " Experience §r§b(Team Bonus)"
+ )
+ private val abilityPatterns = listOf(
+ "§7Your Guided Sheep hit §r§c(.*) §r§7enemy for §r§c(.*) §r§7damage.".toPattern(),
+ "§a§lBUFF! §fYou were splashed by (.*) §fwith §r§cHealing VIII§r§f!".toPattern(),
+ "§aYou were healed for (.*) health by (.*)§a!".toPattern(),
+ "§aYou gained (.*) HP worth of absorption for 3s from §r(.*)§r§a!".toPattern(),
+ "§c(.*) §r§epicked up your (.*) Orb!".toPattern(),
+ "§cThis ability is on cooldown for (.*)s.".toPattern(),
+ "§a§l(.*) healed you for (.*) health!".toPattern(),
+ "§eYour bone plating reduced the damage you took by §r§c(.*)§r§e!".toPattern(),
+ "(.*) §r§eformed a tether with you!".toPattern(),
+ "§eYour tether with (.*) §r§ehealed you for §r§a(.*) §r§ehealth.".toPattern(),
+ "§7Your Implosion hit §r§c(.*) §r§7enemy for §r§c(.*) §r§7damage.".toPattern(),
+ "§eYour §r§6Spirit Pet §r§ehealed (.*) §r§efor §r§a(.*) §r§ehealth!".toPattern(),
+ "§eYour §r§6Spirit Pet §r§ehit (.*) enemy for §r§c(.*) §r§edamage.".toPattern(),
+ "§cYou need at least (.*) mana to activate this!".toPattern(),
+ "§eYou were healed for §r§a(.*)§r§e health by §r(.*)§r§e's §r§9Healing Bow§r§e and gained §r§c\\+(.*) Strength§r§e for 10 seconds.".toPattern(),
+ "(.*)§r§a granted you §r§c(.*) §r§astrength for §r§e20 §r§aseconds!".toPattern(),
+ "§eYour fairy healed §r§ayourself §r§efor §r§a(.*) §r§ehealth!".toPattern(),
+ "§eYour fairy healed §r(.*) §r§efor §r§a(.*) §r§ehealth!".toPattern(),
+ "(.*) fairy healed you for §r§a(.*) §r§ehealth!".toPattern()
+ )
+ private val abilityMessages = listOf(
+ "§a§r§6Guided Sheep §r§ais now available!",
+ "§dCreeper Veil §r§aActivated!",
+ "§dCreeper Veil §r§cDe-activated!",
+ "§6Rapid Fire§r§a is ready to use! Press §r§6§lDROP§r§a to activate it!",
+ "§6Castle of Stone§r§a is ready to use! Press §r§6§lDROP§r§a to activate it!",
+ "§6Ragnarok§r§a is ready to use! Press §r§6§lDROP§r§a to activate it!"
+ )
+ private val damagePatterns = listOf(
+ "(.*) §r§aused §r(.*) §r§aon you!".toPattern(),
+ "§cThe (.*)§r§c struck you for (.*) damage!".toPattern(),
+ "§cThe (.*) hit you for (.*) damage!".toPattern(),
+ "§7(.*) struck you for §r§c(.*)§r§7 damage.".toPattern(),
+ "(.*) hit you for §r§c(.*)§r§7 damage.".toPattern(),
+ "(.*) hit you for §r§c(.*)§r§7 true damage.".toPattern(),
+ "§7(.*) exploded, hitting you for §r§c(.*)§r§7 damage.".toPattern(),
+ "(.*)§r§c hit you with §r(.*) §r§cfor (.*) damage!".toPattern(),
+ "(.*)§r§a struck you for §r§c(.*)§r§a damage!".toPattern(),
+ "(.*)§r§c struck you for (.*)!".toPattern(),
+ "§7The Mage's Magma burnt you for §r§c(.*)§r§7 true damage.".toPattern(),
+ "§7Your (.*) hit §r§c(.*) §r§7(enemy|enemies) for §r§c(.*) §r§7damage.".toPattern(),
+ )
+ private val damageMessages = listOf(
+ "§cMute silenced you!"
+ )
+ private val notPossibleMessages = listOf(
+ "§cYou cannot hit the silverfish while it's moving!",
+ "§cYou cannot move the silverfish in that direction!",
+ "§cThere are blocks in the way!",
+ "§cThis chest has already been searched!",
+ "§cThis lever has already been used.",
+ "§cYou cannot do that in this room!",
+ "§cYou do not have the key for this door!",
+ "§cYou have already opened this dungeon chest!",
+ "§cYou cannot use abilities in this room!",
+ "§cA mystical force in this room prevents you from using that ability!"
+ )
+ private val buffPatterns = listOf(
+ "§6§lDUNGEON BUFF! (.*) §r§ffound a §r§dBlessing of (.*)§r§f!(.*)".toPattern(),
+ "§6§lDUNGEON BUFF! §r§fYou found a §r§dBlessing of (.*)§r§f!(.*)".toPattern(),
+ "§6§lDUNGEON BUFF! §r§fA §r§dBlessing of (.*)§r§f was found! (.*)".toPattern(),
+ "§eA §r§a§r§dBlessing of (.*)§r§e was picked up!".toPattern(),
+ "(.*) §r§ehas obtained §r§a§r§dBlessing of (.*)§r§e!".toPattern(),
+ " {5}§r§7Granted you §r§a§r§a(.*)§r§7 & §r§a(.*)x §r§c❁ Strength§r§7.".toPattern(),
+ " {5}§r§7Also granted you §r§a§r§a(.*)§r§7 & §r§a(.*)x §r§9☠ Crit Damage§r§7.".toPattern(),
+ " {5}§r§7(Grants|Granted) you §r§a(.*) Defense §r§7and §r§a+(.*) Damage§r§7.".toPattern(),
+ " {5}§r§7Granted you §r§a§r§a(.*)x HP §r§7and §r§a§r§a(.*)x §r§c❣ Health Regen§r§7.".toPattern(),
+ " {5}§r§7(Grants|Granted) you §r§a(.*) Intelligence §r§7and §r§a+(.*)? Speed§r§7.".toPattern(),
+ " {5}§r§7Granted you §r§a+(.*) HP§r§7, §r§a(.*) Defense§r§7, §r§a(.*) Intelligence§r§7, and §r§a(.*) Strength§r§7.".toPattern()
+ )
+ private val buffMessages = listOf(
+ "§a§lBUFF! §fYou have gained §r§cHealing V§r§f!"
+ )
+ private val puzzlePatterns = listOf(
+ "§a§lPUZZLE SOLVED! (.*) §r§ewasn't fooled by §r§c(.*)§r§e! §r§4G§r§co§r§6o§r§ed§r§a §r§2j§r§bo§r§3b§r§5!".toPattern(),
+ "§a§lPUZZLE SOLVED! (.*) §r§etied Tic Tac Toe! §r§4G§r§co§r§6o§r§ed§r§a §r§2j§r§bo§r§3b§r§5!".toPattern(),
+ "§4\\[STATUE] Oruo the Omniscient§r§f: §r(.*) §r§fthinks the answer is §r§6 . §r(.*)§r§f! §r§fLock in your party's answer in my Chamber!".toPattern(),
+ )
+ private val puzzleMessages = listOf(
+ "§4[STATUE] Oruo the Omniscient§r§f: §r§fThough I sit stationary in this prison that is §r§cThe Catacombs§r§f, my knowledge knows no bounds.",
+ "§4[STATUE] Oruo the Omniscient§r§f: §r§fProve your knowledge by answering 3 questions and I shall reward you in ways that transcend time!",
+ "§4[STATUE] Oruo the Omniscient§r§f: §r§fAnswer incorrectly, and your moment of ineptitude will live on for generations.",
+ "§4[STATUE] Oruo the Omniscient§r§f: §r§f2 questions left... Then you will have proven your worth to me!",
+ "§4[STATUE] Oruo the Omniscient§r§f: §r§fOne more question!",
+ "§4[STATUE] Oruo the Omniscient§r§f: §r§fI bestow upon you all the power of a hundred years!",
+ "§4[STATUE] Oruo the Omniscient§r§f: §r§fYou've already proven enough to me! No need to press more of my buttons!",
+ "§4[STATUE] Oruo the Omniscient§r§f: §r§fI've had enough of you and your party fiddling with my buttons. Scram!",
+ "§4[STATUE] Oruo the Omniscient§r§f: §r§fEnough! My buttons are not to be pressed with such lack of grace!"
+ )
+ private val unsortedBlockedPatterns = listOf( // TODO sort out and filter separately
+ "(.*) §r§ehas obtained §r§a§r§9Beating Heart§r§e!".toPattern()
+ )
+ private val unsortedBlockedMessages = listOf(
+ "§5A shiver runs down your spine..."
+ )
+ private val reminderMessages = listOf(
+ "§e§lRIGHT CLICK §r§7on §r§7a §r§8WITHER §r§7door§r§7 to open it. This key can only be used to open §r§a1§r§7 door!",
+ "§e§lRIGHT CLICK §r§7on §r§7the §r§cBLOOD DOOR§r§7 to open it. This key can only be used to open §r§a1§r§7 door!"
+ )
+ private val pickupPatterns = listOf(
+ "(.*) §r§ehas obtained §r§a§r§9Superboom TNT§r§e!".toPattern(),
+ "(.*) §r§ehas obtained §r§a§r§9Superboom TNT §r§8x2§r§e!".toPattern(),
+ "§6§lRARE DROP! §r§9Hunk of Blue Ice §r§b\\(+(.*)% Magic Find!\\)".toPattern(),
+ "(.*) §r§ehas obtained §r§a§r§6Revive Stone§r§e!".toPattern(),
+ "(.*) §r§ffound a §r§dWither Essence§r§f! Everyone gains an extra essence!".toPattern(),
+ "§d(.*) the Fairy§r§f: You killed me! Take this §r§6Revive Stone §r§fso that my death is not in vain!".toPattern(),
+ "§d(.*) the Fairy§r§f: You killed me! I'll revive you so that my death is not in vain!".toPattern(),
+ "§d(.*) the Fairy§r§f: You killed me! I'll revive your friend §r(.*) §r§fso that my death is not in vain!".toPattern(),
+ "§d(.*) the Fairy§r§f: Have a great life!".toPattern(),
+ "§c(.*) §r§eYou picked up a Ability Damage Orb from (.*) §r§ehealing you for §r§c(.*) §r§eand granting you +§r§c(.*)% §r§eAbility Damage for §r§b10 §r§eseconds.".toPattern(),
+ "§c(.*) §r§eYou picked up a Damage Orb from (.*) §r§ehealing you for §r§c(.*) §r§eand granting you +§r§c(.*)% §r§eDamage for §r§b10 §r§eseconds.".toPattern(),
+ "(.*) §r§ehas obtained §r§a§r§9Premium Flesh§r§e!".toPattern(),
+ "§6§lRARE DROP! §r§9Beating Heart §r§b(.*)".toPattern()
+ )
+ private val pickupMessages = listOf(
+ "§fYou found a §r§dWither Essence§r§f! Everyone gains an extra essence!"
+ )
+ private val startPatterns = listOf(
+ //§a[Berserk] §r§fMelee Damage §r§c48%§r§f -> §r§a88%
+ //§a[Berserk] §r§fWalk Speed §r§c38§r§f -> §r§a68
+ "§a(.*) §r§f(.*) §r§c(.*)§r§f -> §r§a(.*)".toPattern()
+ )
+ private val startMessages = listOf(
+ "§e[NPC] §bMort§f: §rHere, I found this map when I first entered the dungeon.",
+ "§e[NPC] §bMort§f: §rYou should find it useful if you get lost.",
+ "§e[NPC] §bMort§f: §rGood luck.",
+ "§e[NPC] §bMort§f: §rTalk to me to change your class and ready up."
+ )
+ private val preparePatterns = listOf(
+ "(.*) has started the dungeon countdown. The dungeon will begin in 1 minute.".toPattern(),
+ "§e[NPC] §bMort§f: §rTalk to me to change your class and ready up.".toPattern(),
+ "(.*)§a is now ready!".toPattern(),
+ "§aDungeon starts in (.*) seconds.".toPattern(),
+ )
+ private val prepareMessages = listOf(
+ "§aYour active Potion Effects have been paused and stored. They will be restored when you leave Dungeons! You are not allowed to use existing Potion Effects while in Dungeons.",
+ "§aDungeon starts in 1 second.",
+ "§aYou can no longer consume or splash any potions during the remainder of this Dungeon run!",
+ )
+
+ private val messagesMap: Map<String, List<String>> = mapOf(
+ "prepare" to prepareMessages,
+ "start" to startMessages,
+ "unsorted" to unsortedBlockedMessages,
+ "pickup" to pickupMessages,
+ "reminder" to reminderMessages,
+ "buff" to buffMessages,
+ "not_possible" to notPossibleMessages,
+ "damage" to damageMessages,
+ "ability" to abilityMessages,
+ "puzzle" to puzzleMessages,
+ )
+ private val patternsMap: Map<String, List<Pattern>> = mapOf(
+ "prepare" to preparePatterns,
+ "start" to startPatterns,
+ "unsorted" to unsortedBlockedPatterns,
+ "pickup" to pickupPatterns,
+ "buff" to buffPatterns,
+ "damage" to damagePatterns,
+ "ability" to abilityPatterns,
+ "puzzle" to puzzlePatterns,
+ "end" to endPatterns,
+ )
+ private val messagesEndsWithMap: Map<String, List<String>> = mapOf(
+ "end" to endMessagesEndWith,
+ )
+ /// </editor-fold>
+
@SubscribeEvent
fun onChatMessage(event: LorenzChatEvent) {
- if (!LorenzUtils.onHypixel) return
+ if (!LorenzUtils.onHypixel || !config.dungeonMessages) return
// Workaround since the potion message gets always sent at that moment when SkyBlock is set as false
if (!LorenzUtils.inSkyBlock && !event.message.startsWith("§aYour active Potion Effects")) return
- if (!SkyHanniMod.feature.chat.dungeonMessages) return
val blockReason = block(event.message)
if (blockReason != "") {
@@ -24,200 +204,39 @@ class DungeonChatFilter {
private fun block(message: String): String {
when {
- isPrepare(message) -> return "prepare"
- isStart(message) -> return "start"
+ message.isPresent("prepare") -> return "prepare"
+ message.isPresent("start") -> return "start"
}
if (!LorenzUtils.inDungeons) return ""
return when {
- isUnsortedBlockedMessage(message) -> "unsorted"
- isPickup(message) -> "pickup"
- isReminder(message) -> "reminder"
- isBuff(message) -> "buff"
- isNotPossible(message) -> "not_possible"
- isDamage(message) -> "damage"
- isAbility(message) -> "ability"
- isPuzzle(message) -> "puzzle"
- isEnd(message) -> "end"
-
+ message.isPresent("unsorted") -> "unsorted"
+ message.isPresent("pickup") -> "pickup"
+ message.isPresent("reminder") -> "reminder"
+ message.isPresent("buff") -> "buff"
+ message.isPresent("not_possible") -> "not_possible"
+ message.isPresent("damage") -> "damage"
+ message.isPresent("ability") -> "ability"
+ message.isPresent("puzzle") -> "puzzle"
+ message.isPresent("end") -> "end"
else -> ""
}
}
- private fun isEnd(message: String): Boolean = when {
- message.matchRegex("(.*) §r§eunlocked §r§d(.*) Essence §r§8x(.*)§r§e!") -> true
- message.matchRegex(" §r§d(.*) Essence §r§8x(.*)") -> true
- message.endsWith(" Experience §r§b(Team Bonus)") -> true
- else -> false
- }
-
- private fun isAbility(message: String): Boolean = when {
- message == "§a§r§6Guided Sheep §r§ais now available!" -> true
- message.matchRegex("§7Your Guided Sheep hit §r§c(.*) §r§7enemy for §r§c(.*) §r§7damage.") -> true
- message == "§6Rapid Fire§r§a is ready to use! Press §r§6§lDROP§r§a to activate it!" -> true
- message == "§6Castle of Stone§r§a is ready to use! Press §r§6§lDROP§r§a to activate it!" -> true
- message == "§6Ragnarok§r§a is ready to use! Press §r§6§lDROP§r§a to activate it!" -> true
-
-
- message.matchRegex("§a§lBUFF! §fYou were splashed by (.*) §fwith §r§cHealing VIII§r§f!") -> true
- message.matchRegex("§aYou were healed for (.*) health by (.*)§a!") -> true
- message.matchRegex("§aYou gained (.*) HP worth of absorption for 3s from §r(.*)§r§a!") -> true
- message.matchRegex("§c(.*) §r§epicked up your (.*) Orb!") -> true
- message.matchRegex("§cThis ability is on cooldown for (.*)s.") -> true
- message.matchRegex("§a§l(.*) healed you for (.*) health!") -> true
- message.matchRegex("§eYour bone plating reduced the damage you took by §r§c(.*)§r§e!") -> true
- message.matchRegex("(.*) §r§eformed a tether with you!") -> true
- message.matchRegex("§eYour tether with (.*) §r§ehealed you for §r§a(.*) §r§ehealth.") -> true
- message.matchRegex("§7Your Implosion hit §r§c(.*) §r§7enemy for §r§c(.*) §r§7damage.") -> true
-
- message.matchRegex("§eYour §r§6Spirit Pet §r§ehealed (.*) §r§efor §r§a(.*) §r§ehealth!") -> true
- message.matchRegex("§eYour §r§6Spirit Pet §r§ehit (.*) enemy for §r§c(.*) §r§edamage.") -> true
-
- message == "§dCreeper Veil §r§aActivated!" -> true
- message == "§dCreeper Veil §r§cDe-activated!" -> true
- message.matchRegex("§cYou need at least (.*) mana to activate this!") -> true
-
- message.matchRegex(
- "§eYou were healed for §r§a(.*)§r§e health by §r(.*)§r§e's §r§9Healing Bow§r§e and " + "gained §r§c\\+(.*) Strength§r§e for 10 seconds."
- ) -> true
-
- message.matchRegex("(.*)§r§a granted you §r§c(.*) §r§astrength for §r§e20 §r§aseconds!") -> true
-
- message.matchRegex("§eYour fairy healed §r§ayourself §r§efor §r§a(.*) §r§ehealth!") -> true
- message.matchRegex("§eYour fairy healed §r(.*) §r§efor §r§a(.*) §r§ehealth!") -> true
- message.matchRegex("(.*) fairy healed you for §r§a(.*) §r§ehealth!") -> true
-
- else -> false
- }
-
- private fun isDamage(message: String): Boolean = when {
- message == "§cMute silenced you!" -> true
- message.matchRegex("(.*) §r§aused §r(.*) §r§aon you!") -> true
- message.matchRegex("§cThe (.*)§r§c struck you for (.*) damage!") -> true
- message.matchRegex("§cThe (.*) hit you for (.*) damage!") -> true
- message.matchRegex("§7(.*) struck you for §r§c(.*)§r§7 damage.") -> true
- message.matchRegex("(.*) hit you for §r§c(.*)§r§7 damage.") -> true
- message.matchRegex("(.*) hit you for §r§c(.*)§r§7 true damage.") -> true
- message.matchRegex("§7(.*) exploded, hitting you for §r§c(.*)§r§7 damage.") -> true
- message.matchRegex("(.*)§r§c hit you with §r(.*) §r§cfor (.*) damage!") -> true
- message.matchRegex("(.*)§r§a struck you for §r§c(.*)§r§a damage!") -> true
- message.matchRegex("(.*)§r§c struck you for (.*)!") -> true
-
- message.matchRegex("§7The Mage's Magma burnt you for §r§c(.*)§r§7 true damage.") -> true
-
- message.matchRegex("§7Your (.*) hit §r§c(.*) §r§7(enemy|enemies) for §r§c(.*) §r§7damage.") -> true
- else -> false
- }
-
- private fun isNotPossible(message: String): Boolean = when (message) {
- "§cYou cannot hit the silverfish while it's moving!",
- "§cYou cannot move the silverfish in that direction!",
- "§cThere are blocks in the way!",
- "§cThis chest has already been searched!",
- "§cThis lever has already been used.",
- "§cYou cannot do that in this room!",
- "§cYou do not have the key for this door!",
- "§cYou have already opened this dungeon chest!",
- "§cYou cannot use abilities in this room!",
- "§cA mystical force in this room prevents you from using that ability!" -> true
-
- else -> false
- }
-
- private fun isBuff(message: String): Boolean = when {
- message.matchRegex("§6§lDUNGEON BUFF! (.*) §r§ffound a §r§dBlessing of (.*)§r§f!(.*)") -> true
- message.matchRegex("§6§lDUNGEON BUFF! §r§fYou found a §r§dBlessing of (.*)§r§f!(.*)") -> true
- message.matchRegex("§6§lDUNGEON BUFF! §r§fA §r§dBlessing of (.*)§r§f was found! (.*)") -> true
- message.matchRegex("§eA §r§a§r§dBlessing of (.*)§r§e was picked up!") -> true
- message.matchRegex("(.*) §r§ehas obtained §r§a§r§dBlessing of (.*)§r§e!") -> true
- message.matchRegex(" §r§7Granted you §r§a§r§a(.*)§r§7 & §r§a(.*)x §r§c❁ Strength§r§7.") -> true
- message.matchRegex(" §r§7Also granted you §r§a§r§a(.*)§r§7 & §r§a(.*)x §r§9☠ Crit Damage§r§7.") -> true
- message.matchRegex(" §r§7(Grants|Granted) you §r§a(.*) Defense §r§7and §r§a+(.*) Damage§r§7.") -> true
- message.matchRegex(" §r§7Granted you §r§a§r§a(.*)x HP §r§7and §r§a§r§a(.*)x §r§c❣ Health Regen§r§7.") -> true
- message.matchRegex(" §r§7(Grants|Granted) you §r§a(.*) Intelligence §r§7and §r§a+(.*)? Speed§r§7.") -> true
- message.matchRegex(" §r§7Granted you §r§a+(.*) HP§r§7, §r§a(.*) Defense§r§7, §r§a(.*) Intelligence§r§7, and §r§a(.*) Strength§r§7.") -> true
- message == "§a§lBUFF! §fYou have gained §r§cHealing V§r§f!" -> true
- else -> false
- }
-
- private fun isPuzzle(message: String): Boolean = when {
- message.matchRegex("§a§lPUZZLE SOLVED! (.*) §r§ewasn't fooled by §r§c(.*)§r§e! §r§4G§r§co§r§6o§r§ed§r§a §r§2j§r§bo§r§3b§r§5!") -> true
- message.matchRegex("§a§lPUZZLE SOLVED! (.*) §r§etied Tic Tac Toe! §r§4G§r§co§r§6o§r§ed§r§a §r§2j§r§bo§r§3b§r§5!") -> true
- message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fThough I sit stationary in this prison that is §r§cThe Catacombs§r§f, my knowledge knows no bounds." -> true
- message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fProve your knowledge by answering 3 questions and I shall reward you in ways that transcend time!" -> true
- message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fAnswer incorrectly, and your moment of ineptitude will live on for generations." -> true
-
- message == "§4[STATUE] Oruo the Omniscient§r§f: §r§f2 questions left... Then you will have proven your worth to me!" -> true
-
- message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fOne more question!" -> true
- message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fI bestow upon you all the power of a hundred years!" -> true
- message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fYou've already proven enough to me! No need to press more of my buttons!" -> true
- message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fI've had enough of you and your party fiddling with my buttons. Scram!" -> true
- message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fEnough! My buttons are not to be pressed with such lack of grace!" -> true
- message.matchRegex("§4\\[STATUE] Oruo the Omniscient§r§f: §r(.*) §r§fthinks the answer is §r§6 . §r(.*)§r§f! §r§fLock in your party's answer in my Chamber!") -> true
- else -> false
- }
-
- //TODO sort out and filter separately
- private fun isUnsortedBlockedMessage(message: String): Boolean = when {
- message.matchRegex("(.*) §r§ehas obtained §r§a§r§9Beating Heart§r§e!") -> true
- message == "§5A shiver runs down your spine..." -> true
-
- else -> false
- }
-
- private fun isReminder(message: String): Boolean = when (message) {
- "§e§lRIGHT CLICK §r§7on §r§7a §r§8WITHER §r§7door§r§7 to open it. This key can only be used to open §r§a1§r§7 door!",
- "§e§lRIGHT CLICK §r§7on §r§7the §r§cBLOOD DOOR§r§7 to open it. This key can only be used to open §r§a1§r§7 door!" -> true
-
- else -> false
- }
-
- private fun isPickup(message: String): Boolean = when {
- message.matchRegex("(.*) §r§ehas obtained §r§a§r§9Superboom TNT§r§e!") -> true
- message.matchRegex("(.*) §r§ehas obtained §r§a§r§9Superboom TNT §r§8x2§r§e!") -> true
- message.matchRegex("§6§lRARE DROP! §r§9Hunk of Blue Ice §r§b\\(+(.*)% Magic Find!\\)") -> true
- message.matchRegex("(.*) §r§ehas obtained §r§a§r§6Revive Stone§r§e!") -> true
- message.matchRegex("(.*) §r§ffound a §r§dWither Essence§r§f! Everyone gains an extra essence!") -> true
- message == "§fYou found a §r§dWither Essence§r§f! Everyone gains an extra essence!" -> true
- message.matchRegex("§d(.*) the Fairy§r§f: You killed me! Take this §r§6Revive Stone §r§fso that my death is not in vain!") -> true
- message.matchRegex("§d(.*) the Fairy§r§f: You killed me! I'll revive you so that my death is not in vain!") -> true
- message.matchRegex("§d(.*) the Fairy§r§f: You killed me! I'll revive your friend §r(.*) §r§fso that my death is not in vain!") -> true
- message.matchRegex("§d(.*) the Fairy§r§f: Have a great life!") -> true
- message.matchRegex(
- "§c(.*) §r§eYou picked up a Ability Damage Orb from (.*) §r§ehealing you for §r§c(.*) §r§eand granting you +§r§c(.*)% §r§eAbility Damage for §r§b10 §r§eseconds."
- ) -> true
-
- message.matchRegex(
- "§c(.*) §r§eYou picked up a Damage Orb from (.*) §r§ehealing you for §r§c(.*) §r§eand granting you +§r§c(.*)% §r§eDamage for §r§b10 §r§eseconds."
- ) -> true
-
- message.matchRegex("(.*) §r§ehas obtained §r§a§r§9Premium Flesh§r§e!") -> true
- message.matchRegex("§6§lRARE DROP! §r§9Beating Heart §r§b(.*)") -> true
- else -> false
- }
-
- private fun isStart(message: String): Boolean = when {
- message == "§e[NPC] §bMort§f: §rHere, I found this map when I first entered the dungeon." -> true
- message == "§e[NPC] §bMort§f: §rYou should find it useful if you get lost." -> true
- message == "§e[NPC] §bMort§f: §rGood luck." -> true
- message == "§e[NPC] §bMort§f: §rTalk to me to change your class and ready up." -> true
-
- //§a[Berserk] §r§fMelee Damage §r§c48%§r§f -> §r§a88%
- //§a[Berserk] §r§fWalk Speed §r§c38§r§f -> §r§a68
- message.matchRegex("§a(.*) §r§f(.*) §r§c(.*)§r§f -> §r§a(.*)") -> true
- else -> false
- }
-
- private fun isPrepare(message: String): Boolean = when {
- message == "§aYour active Potion Effects have been paused and stored. They will be restored when you leave Dungeons! You are not allowed to use existing Potion Effects while in Dungeons." -> true
- message.matchRegex("(.*) has started the dungeon countdown. The dungeon will begin in 1 minute.") -> true
- message.matchRegex("§e[NPC] §bMort§f: §rTalk to me to change your class and ready up.") -> true
- message.matchRegex("(.*)§a is now ready!") -> true
- message.matchRegex("§aDungeon starts in (.*) seconds.") -> true
- message == "§aDungeon starts in 1 second." -> true
- message == "§aYou can no longer consume or splash any potions during the remainder of this Dungeon run!" -> true
- else -> false
+ /**
+ * Checks if the message is present in the list of messages or patterns
+ * Checks against three maps that compare in different ways.
+ * @receiver The message to check
+ * @param key The key of the list to check
+ * @return True if the message is present in any of the maps
+ * @see messagesMap
+ * @see patternsMap
+ * @see messagesEndsWithMap
+ */
+ private fun String.isPresent(key: String): Boolean {
+ return this in (messagesMap[key] ?: emptyList()) ||
+ (patternsMap[key] ?: emptyList()).any { it.matches(this) } ||
+ (messagesEndsWithMap[key] ?: emptyList()).any { this.endsWith(it) }
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCleanEnd.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCleanEnd.kt
index 6e5fc27bd..8602b9282 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCleanEnd.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCleanEnd.kt
@@ -10,7 +10,7 @@ import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
import at.hannibal2.skyhanni.events.PlaySoundEvent
import at.hannibal2.skyhanni.events.ReceiveParticleEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.StringUtils.matchRegex
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import net.minecraft.client.Minecraft
import net.minecraft.client.entity.EntityOtherPlayerMP
import net.minecraft.entity.item.EntityArmorStand
@@ -20,6 +20,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class DungeonCleanEnd {
private val config get() = SkyHanniMod.feature.dungeon.cleanEnd
+ private val catacombsPattern = "([ ]*)§r§c(The|Master Mode) Catacombs §r§8- §r§eFloor (.*)".toPattern()
private var bossDone = false
private var chestsSpawned = false
@@ -32,7 +33,7 @@ class DungeonCleanEnd {
val message = event.message
- if (message.matchRegex("([ ]*)§r§c(The|Master Mode) Catacombs §r§8- §r§eFloor (.*)")) {
+ catacombsPattern.matchMatcher(message) {
chestsSpawned = true
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCopilot.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCopilot.kt
index 8119535fd..1dcc92dab 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCopilot.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCopilot.kt
@@ -11,12 +11,23 @@ import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.RenderUtils.renderString
-import at.hannibal2.skyhanni.utils.StringUtils.matchRegex
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import net.minecraft.entity.item.EntityArmorStand
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class DungeonCopilot {
+ private val config get() = SkyHanniMod.feature.dungeon.dungeonCopilot
+
+ private val countdownPattern =
+ "(.*) has started the dungeon countdown. The dungeon will begin in 1 minute.".toPattern()
+ private val keyPatternsList = listOf(
+ "§eA §r§a§r§[6c]§r§[8c](?<key>Wither|Blood) Key§r§e was picked up!".toPattern(),
+ "(.*) §r§ehas obtained §r§a§r§[6c]§r§[8c](?<key>Wither|Blood) Key§r§e!".toPattern()
+ )
+ private val witherDoorPattern = "(.*) opened a §r§8§lWITHER §r§adoor!".toPattern()
+ private val bloodDoorPattern = "§cThe §r§c§lBLOOD DOOR§r§c has been opened!".toPattern()
+
private var nextStep = ""
private var searchForKey = false
@@ -24,60 +35,50 @@ class DungeonCopilot {
fun onChatMessage(event: LorenzChatEvent) {
if (!isEnabled()) return
- val message = event.message
+ copilot(event.message)?.let {
+ event.blockedReason = it
+ }
+ }
- if (message.matchRegex("(.*) has started the dungeon countdown. The dungeon will begin in 1 minute.")) {
+ private fun copilot(message: String): String? {
+ countdownPattern.matchMatcher(message) {
changeNextStep("Ready up")
}
- if (message.endsWith("§a is now ready!")) {
- var name = LorenzUtils.getPlayerName()
- if (message.contains(name)) {
- changeNextStep("Wait for the dungeon to start!")
- }
+
+ if (message.endsWith("§a is now ready!") && message.contains(LorenzUtils.getPlayerName())) {
+ changeNextStep("Wait for the dungeon to start!")
}
+ // Key Pickup
var foundKeyOrDoor = false
-
- //key pickup
- if (message.matchRegex("(.*) §r§ehas obtained §r§a§r§6§r§8Wither Key§r§e!") ||
- message == "§eA §r§a§r§6§r§8Wither Key§r§e was picked up!"
- ) {
- changeNextStep("Open Wither Door")
- foundKeyOrDoor = true
-
- }
- if (message.matchRegex("(.*) §r§ehas obtained §r§a§r§c§r§cBlood Key§r§e!") ||
- message == "§eA §r§a§r§c§r§cBlood Key§r§e was picked up!"
- ) {
- changeNextStep("Open Blood Door")
- foundKeyOrDoor = true
+ keyPatternsList.any {
+ it.matchMatcher(message) {
+ val key = group("key")
+ changeNextStep("Open $key Door")
+ foundKeyOrDoor = true
+ } != null
}
-
- if (message.matchRegex("(.*) opened a §r§8§lWITHER §r§adoor!")) {
+ witherDoorPattern.matchMatcher(message) {
changeNextStep("Clear next room")
searchForKey = true
foundKeyOrDoor = true
}
- if (message == "§cThe §r§c§lBLOOD DOOR§r§c has been opened!") {
+ bloodDoorPattern.matchMatcher(message) {
changeNextStep("Wait for Blood Room to fully spawn")
foundKeyOrDoor = true
}
- if (foundKeyOrDoor && SkyHanniMod.feature.dungeon.messageFilter.keysAndDoors) {
- event.blockedReason = "dungeon_keys_and_doors"
- }
-
+ if (foundKeyOrDoor && SkyHanniMod.feature.dungeon.messageFilter.keysAndDoors) return "dungeon_keys_and_doors"
- if (message == "§c[BOSS] The Watcher§r§f: That will be enough for now.") {
- changeNextStep("Clear Blood Room")
- }
+ if (message == "§c[BOSS] The Watcher§r§f: That will be enough for now.") changeNextStep("Clear Blood Room")
if (message == "§c[BOSS] The Watcher§r§f: You have proven yourself. You may pass.") {
- event.blockedReason = "dungeon copilot"
changeNextStep("Enter Boss Room")
+ return "dungeon_copilot"
}
+ return null
}
private fun changeNextStep(step: String) {
@@ -126,14 +127,14 @@ class DungeonCopilot {
}
private fun isEnabled(): Boolean {
- return LorenzUtils.inDungeons && SkyHanniMod.feature.dungeon.dungeonCopilot.enabled
+ return LorenzUtils.inDungeons && config.enabled
}
@SubscribeEvent
fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
if (!isEnabled()) return
- SkyHanniMod.feature.dungeon.dungeonCopilot.pos.renderString(nextStep, posLabel = "Dungeon Copilot")
+ config.pos.renderString(nextStep, posLabel = "Dungeon Copilot")
}
@SubscribeEvent
diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonDeathCounter.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonDeathCounter.kt
index 36788e4b3..794736954 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonDeathCounter.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonDeathCounter.kt
@@ -7,7 +7,7 @@ import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.RenderUtils.renderString
-import at.hannibal2.skyhanni.utils.StringUtils.matchRegex
+import at.hannibal2.skyhanni.utils.StringUtils.matches
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class DungeonDeathCounter {
@@ -15,37 +15,39 @@ class DungeonDeathCounter {
private var display = ""
private var deaths = 0
- private fun isDeathMessage(message: String): Boolean = when {
- message.matchRegex("§c ☠ §r§7You were killed by (.*)§r§7 and became a ghost§r§7.") -> true
- message.matchRegex("§c ☠ §r§7(.*) was killed by (.*) and became a ghost§r§7.") -> true
+ private val deathPatternsList = listOf(
+ // TODO USE SH-REPO
+ "§c ☠ §r§7You were killed by (.*)§r§7 and became a ghost§r§7.".toPattern(),
+ "§c ☠ §r§7(.*) was killed by (.*) and became a ghost§r§7.".toPattern(),
- message.matchRegex("§c ☠ §r§7You were crushed and became a ghost§r§7.") -> true
- message.matchRegex("§c ☠ §r§7§r(.*)§r§7 was crushed and became a ghost§r§7.") -> true
+ "§c ☠ §r§7You were crushed and became a ghost§r§7.".toPattern(),
+ "§c ☠ §r§7§r(.*)§r§7 was crushed and became a ghost§r§7.".toPattern(),
- message.matchRegex("§c ☠ §r§7You died to a trap and became a ghost§r§7.") -> true
- message.matchRegex("§c ☠ §r(.*)§r§7 died to a trap and became a ghost§r§7.") -> true
+ "§c ☠ §r§7You died to a trap and became a ghost§r§7.".toPattern(),
+ "§c ☠ §r(.*)§r§7 died to a trap and became a ghost§r§7.".toPattern(),
- message.matchRegex("§c ☠ §r§7You burnt to death and became a ghost§r§7.") -> true
- message.matchRegex("§c ☠ §r(.*)§r§7 burnt to death and became a ghost§r§7.") -> true
+ "§c ☠ §r§7You burnt to death and became a ghost§r§7.".toPattern(),
+ "§c ☠ §r(.*)§r§7 burnt to death and became a ghost§r§7.".toPattern(),
- message.matchRegex("§c ☠ §r§7You died and became a ghost§r§7.") -> true
- message.matchRegex("§c ☠ §r(.*)§r§7 died and became a ghost§r§7.") -> true
+ "§c ☠ §r§7You died and became a ghost§r§7.".toPattern(),
+ "§c ☠ §r(.*)§r§7 died and became a ghost§r§7.".toPattern(),
- message.matchRegex("§c ☠ §r§7You suffocated and became a ghost§r§7.") -> true
- message.matchRegex("§c ☠ §r§7§r(.*)§r§7 suffocated and became a ghost§r§7.") -> true
+ "§c ☠ §r§7You suffocated and became a ghost§r§7.".toPattern(),
+ "§c ☠ §r§7§r(.*)§r§7 suffocated and became a ghost§r§7.".toPattern(),
- message.matchRegex("§c ☠ §r§7You died to a mob and became a ghost§r§7.") -> true
- message.matchRegex("§c ☠ §r(.*)§7 died to a mob and became a ghost§r§7.") -> true
+ "§c ☠ §r§7You died to a mob and became a ghost§r§7.".toPattern(),
+ "§c ☠ §r(.*)§7 died to a mob and became a ghost§r§7.".toPattern(),
- message.matchRegex("§c ☠ §r§7You fell into a deep hole and became a ghost§r§7.") -> true
- message.matchRegex("§c ☠ §r(.*)§r§7 fell into a deep hole and became a ghost§r§7.") -> true
+ "§c ☠ §r§7You fell into a deep hole and became a ghost§r§7.".toPattern(),
+ "§c ☠ §r(.*)§r§7 fell into a deep hole and became a ghost§r§7.".toPattern(),
- message.matchRegex("§c ☠ §r§(.*)§r§7 disconnected from the Dungeon and became a ghost§r§7.") -> true
+ "§c ☠ §r§(.*)§r§7 disconnected from the Dungeon and became a ghost§r§7.".toPattern(),
- message.matchRegex("§c ☠ §r§7(.*)§r§7 fell to their death with help from §r(.*)§r§7 and became a ghost§r§7.") -> true
+ "§c ☠ §r§7(.*)§r§7 fell to their death with help from §r(.*)§r§7 and became a ghost§r§7.".toPattern()
+ )
- else -> false
- }
+ private fun isDeathMessage(message: String): Boolean =
+ deathPatternsList.any { it.matches(message) }
@SubscribeEvent(receiveCanceled = true)
fun onChatPacket(event: LorenzChatEvent) {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonFinderFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonFinderFeatures.kt
index b824bc6a5..f21274a02 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonFinderFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonFinderFeatures.kt
@@ -11,7 +11,7 @@ import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzColor
import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded
+import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary
import at.hannibal2.skyhanni.utils.RenderUtils.highlight
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
@@ -47,11 +47,11 @@ class DungeonFinderFeatures {
} else if (itemName == "Entrance") {
event.stackTip = "E"
} else if (itemName.startsWith("Floor ")) {
- event.stackTip = itemName.split(' ').last().romanToDecimalIfNeeded().toString()
+ event.stackTip = itemName.split(' ').last().romanToDecimalIfNecessary().toString()
}
} else if (itemName.startsWith("The Catacombs - ") || itemName.startsWith("MM Catacombs -")) {
val floor = itemName.split(" - ").last().removeColor()
- val floorNum = floor.split(' ').last().romanToDecimalIfNeeded().toString()
+ val floorNum = floor.split(' ').last().romanToDecimalIfNecessary().toString()
val isMasterMode = itemName.contains("MM ")
event.stackTip = if (floor.contains("Entrance")) {
@@ -64,7 +64,7 @@ class DungeonFinderFeatures {
} else if (itemName.endsWith("'s Party")) {
val floor = event.stack.getLore().find { it.startsWith("§7Floor: ") } ?: return
val dungeon = event.stack.getLore().find { it.startsWith("§7Dungeon: ") } ?: return
- val floorNum = floor.split(' ').last().romanToDecimalIfNeeded().toString()
+ val floorNum = floor.split(' ').last().romanToDecimalIfNecessary().toString()
val isMasterMode = dungeon.contains("Master Mode")
event.stackTip = if (floor.contains("Entrance")) {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonMilestonesDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonMilestonesDisplay.kt
index b3a6a1f59..fc5462901 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonMilestonesDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonMilestonesDisplay.kt
@@ -7,7 +7,7 @@ import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.RenderUtils.renderString
-import at.hannibal2.skyhanni.utils.StringUtils.matchRegex
+import at.hannibal2.skyhanni.utils.StringUtils.matches
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.concurrent.fixedRateTimer
@@ -15,25 +15,28 @@ class DungeonMilestonesDisplay {
private val config get() = SkyHanniMod.feature.dungeon
companion object {
+
+ // TODO USE SH-REPO
+ private val milestonePatternList = listOf(
+ "§e§l(.*) Milestone §r§e.§r§7: You have dealt §r§c(.*)§r§7 Total Damage so far! §r§a(.*)".toPattern(),
+ "§e§lArcher Milestone §r§e.§r§7: You have dealt §r§c(.*)§r§7 Ranged Damage so far! §r§a(.*)".toPattern(),
+ "§e§lHealer Milestone §r§e.§r§7: You have healed §r§a(.*)§r§7 Damage so far! §r§a(.*)".toPattern(),
+ "§e§lTank Milestone §r§e.§r§7: You have tanked and dealt §r§c(.*)§r§7 Total Damage so far! §r§a(.*)s".toPattern()
+ )
+
private var display = ""
var color = ""
var currentMilestone = 0
var timeReached = 0L
- fun isMilestoneMessage(message: String): Boolean = when {
- message.matchRegex("§e§l(.*) Milestone §r§e.§r§7: You have dealt §r§c(.*)§r§7 Total Damage so far! §r§a(.*)") -> true
- message.matchRegex("§e§lArcher Milestone §r§e.§r§7: You have dealt §r§c(.*)§r§7 Ranged Damage so far! §r§a(.*)") -> true
- message.matchRegex("§e§lHealer Milestone §r§e.§r§7: You have healed §r§a(.*)§r§7 Damage so far! §r§a(.*)") -> true
- message.matchRegex("§e§lTank Milestone §r§e.§r§7: You have tanked and dealt §r§c(.*)§r§7 Total Damage so far! §r§a(.*)s") -> true
-
- else -> false
- }
+ fun isMilestoneMessage(message: String): Boolean = milestonePatternList.any { it.matches(message) }
}
init {
fixedRateTimer(name = "skyhanni-dungeon-milestone-display", period = 200) {
- if (!isEnabled()) return@fixedRateTimer
- checkVisibility()
+ if (isEnabled()) {
+ checkVisibility()
+ }
}
}
@@ -84,7 +87,10 @@ class DungeonMilestonesDisplay {
fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
if (!isEnabled()) return
- config.showMileStonesDisplayPos.renderString(color + display, posLabel = "Dungeon Milestone")
+ config.showMileStonesDisplayPos.renderString(
+ color + display,
+ posLabel = "Dungeon Milestone"
+ )
}
private fun isEnabled() = LorenzUtils.inDungeons && config.showMilestonesDisplay
diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonRankTabListColor.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonRankTabListColor.kt
index 9a28dcc06..46e2e0514 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonRankTabListColor.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonRankTabListColor.kt
@@ -20,13 +20,13 @@ class DungeonRankTabListColor {
val playerName = group("playerName")
val split = playerName.split(" ")
val sbLevel = split[0]
- val cleanName = split[1].cleanPlayerName()
+ val cleanName = split[1].cleanPlayerName(displayName = true)
val className = group("className")
val level = group("classLevel").romanToDecimal()
val color = getColor(level)
- event.text = "$sbLevel §b$cleanName §7(§e$className $color$level§7)"
+ event.text = "$sbLevel $cleanName §7(§e$className $color$level§7)"
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/UniqueGiftingOpportunitiesFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/event/UniqueGiftingOpportunitiesFeatures.kt
new file mode 100644
index 000000000..d3b75780c
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/event/UniqueGiftingOpportunitiesFeatures.kt
@@ -0,0 +1,90 @@
+package at.hannibal2.skyhanni.features.event
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.HypixelData
+import at.hannibal2.skyhanni.data.ProfileStorageData
+import at.hannibal2.skyhanni.events.EntityCustomNameUpdateEvent
+import at.hannibal2.skyhanni.events.LorenzChatEvent
+import at.hannibal2.skyhanni.events.RenderMobColoredEvent
+import at.hannibal2.skyhanni.events.withAlpha
+import at.hannibal2.skyhanni.features.event.winter.UniqueGiftCounter
+import at.hannibal2.skyhanni.utils.EntityUtils
+import at.hannibal2.skyhanni.utils.EntityUtils.isNPC
+import at.hannibal2.skyhanni.utils.InventoryUtils
+import at.hannibal2.skyhanni.utils.LorenzColor
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
+import at.hannibal2.skyhanni.utils.getLorenzVec
+import net.minecraft.client.entity.EntityPlayerSP
+import net.minecraft.entity.EntityLivingBase
+import net.minecraft.entity.item.EntityArmorStand
+import net.minecraft.entity.player.EntityPlayer
+import net.minecraftforge.event.entity.EntityJoinWorldEvent
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+object UniqueGiftingOpportunitiesFeatures {
+ private val playerList: MutableSet<String>?
+ get() = ProfileStorageData.playerSpecific?.winter?.playersThatHaveBeenGifted
+
+ private val pattern = "§6\\+1 Unique Gift given! To ([^§]+)§r§6!".toPattern()
+
+ private fun hasGiftedPlayer(player: EntityPlayer) = playerList?.contains(player.name) == true
+
+ private fun addGiftedPlayer(playerName: String) {
+ playerList?.add(playerName)
+ }
+
+ private val config get() = SkyHanniMod.feature.event.winter.giftingOpportunities
+
+ private fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled &&
+ (InventoryUtils.itemInHandId.endsWith("_GIFT")
+ || !config.highlighWithGiftOnly)
+
+ private val hasNotGiftedNametag = "§a§lꤥ"
+ private val hasGiftedNametag = "§c§lꤥ"
+
+ private fun analyzeArmorStand(entity: EntityArmorStand) {
+ if (!config.useArmorStandDetection) return
+ if (entity.name != hasGiftedNametag) return
+
+ val matchedPlayer = EntityUtils.getEntitiesNearby<EntityPlayer>(entity.getLorenzVec(), 2.0)
+ .singleOrNull { !it.isNPC() } ?: return
+ addGiftedPlayer(matchedPlayer.name)
+
+ }
+
+ @SubscribeEvent
+ fun onEntityChangeName(event: EntityCustomNameUpdateEvent) {
+ val entity = event.entity as? EntityArmorStand ?: return
+ analyzeArmorStand(entity)
+ }
+
+ @SubscribeEvent
+ fun onEntityJoinWorldEvent(event: EntityJoinWorldEvent) {
+ val entity = event.entity as? EntityArmorStand ?: return
+ analyzeArmorStand(entity)
+ }
+
+ @SubscribeEvent
+ fun onRenderMobColored(event: RenderMobColoredEvent) {
+ if (!isEnabled()) return
+ val entity = event.entity
+ if (entity is EntityPlayerSP) return
+ if (entity is EntityPlayer && !entity.isNPC() && !isIronman(entity) && !isBingo(entity) && !hasGiftedPlayer(entity))
+ event.color = LorenzColor.DARK_GREEN.toColor().withAlpha(127)
+ }
+
+ private fun isBingo(entity: EntityLivingBase) =
+ !HypixelData.bingo && entity.displayName.formattedText.endsWith("Ⓑ§r")
+
+ private fun isIronman(entity: EntityLivingBase) =
+ !LorenzUtils.noTradeMode && entity.displayName.formattedText.endsWith("♲§r")
+
+ @SubscribeEvent
+ fun onChat(event: LorenzChatEvent) {
+ pattern.matchMatcher(event.message) {
+ addGiftedPlayer(group(1))
+ UniqueGiftCounter.addUniqueGift()
+ }
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/diana/GriffinBurrowHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/event/diana/GriffinBurrowHelper.kt
index df89ccd7f..14422e6b4 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/event/diana/GriffinBurrowHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/event/diana/GriffinBurrowHelper.kt
@@ -152,25 +152,24 @@ object GriffinBurrowHelper {
val playerLocation = LocationUtils.playerLocation()
if (config.inquisitorSharing.enabled) {
for (inquis in InquisitorWaypointShare.waypoints.values) {
- val playerName = inquis.fromPlayer
val location = inquis.location
event.drawColor(location, LorenzColor.LIGHT_PURPLE)
val distance = location.distance(playerLocation)
if (distance > 10) {
val formattedDistance = LorenzUtils.formatInteger(distance.toInt())
- event.drawDynamicText(location.add(0, 1, 0), "§d§lInquisitor §e${formattedDistance}m", 1.7)
+ event.drawDynamicText(location.add(y = 1), "§d§lInquisitor §e${formattedDistance}m", 1.7)
} else {
- event.drawDynamicText(location.add(0, 1, 0), "§d§lInquisitor", 1.7)
+ event.drawDynamicText(location.add(y = 1), "§d§lInquisitor", 1.7)
}
if (distance < 5) {
- InquisitorWaypointShare.maybeRemove(playerName)
+ InquisitorWaypointShare.maybeRemove(inquis)
}
- event.drawDynamicText(location.add(0, 1, 0), "§eFrom §b$playerName", 1.6, yOff = 9f)
+ event.drawDynamicText(location.add(y = 1), "§eFrom §b${inquis.displayName}", 1.6, yOff = 9f)
if (config.inquisitorSharing.showDespawnTime) {
val spawnTime = inquis.spawnTime
val format = TimeUtils.formatDuration(75.seconds - spawnTime.passedSince())
- event.drawDynamicText(location.add(0, 1, 0), "§eDespawns in §b$format", 1.6, yOff = 18f)
+ event.drawDynamicText(location.add(y = 1), "§eDespawns in §b$format", 1.6, yOff = 18f)
}
}
}
@@ -185,7 +184,7 @@ object GriffinBurrowHelper {
val distance = location.distance(playerLocation)
val burrowType = burrow.value
event.drawColor(location, burrowType.color, distance > 10)
- event.drawDynamicText(location.add(0, 1, 0), burrowType.text, 1.5)
+ event.drawDynamicText(location.add(y = 1), burrowType.text, 1.5)
}
}
@@ -194,10 +193,10 @@ object GriffinBurrowHelper {
val guessLocation = findBlock(it)
val distance = guessLocation.distance(playerLocation)
event.drawColor(guessLocation, LorenzColor.WHITE, distance > 10)
- event.drawDynamicText(guessLocation.add(0, 1, 0), "Guess", 1.5)
+ event.drawDynamicText(guessLocation.add(y = 1), "Guess", 1.5)
if (distance > 5) {
val formattedDistance = LorenzUtils.formatInteger(distance.toInt())
- event.drawDynamicText(guessLocation.add(0, 1, 0), "§e${formattedDistance}m", 1.7, yOff = 10f)
+ event.drawDynamicText(guessLocation.add(y = 1), "§e${formattedDistance}m", 1.7, yOff = 10f)
}
}
}
@@ -224,7 +223,7 @@ object GriffinBurrowHelper {
if (config.burrowNearestWarp) {
BurrowWarpHelper.currentWarp?.let { warp ->
animationLocation?.let {
- event.drawColor(it.add(0.0, 1.0, 0.0), LorenzColor.AQUA)
+ event.drawColor(it.add(y = 1), LorenzColor.AQUA)
if (it.distanceToPlayer() < 10) {
event.drawString(it.add(0.5, 1.5, 0.5), "§bWarp to " + warp.displayName, true)
if (config.keyBindWarp != Keyboard.KEY_NONE) {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/diana/InquisitorWaypointShare.kt b/src/main/java/at/hannibal2/skyhanni/features/event/diana/InquisitorWaypointShare.kt
index c4f12a993..5532d70e9 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/event/diana/InquisitorWaypointShare.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/event/diana/InquisitorWaypointShare.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.event.diana
-
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.EntityHealthUpdateEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
@@ -47,7 +46,12 @@ object InquisitorWaypointShare {
var waypoints = mapOf<String, SharedInquisitor>()
- class SharedInquisitor(val fromPlayer: String, val location: LorenzVec, val spawnTime: SimpleTimeMark)
+ class SharedInquisitor(
+ val fromPlayer: String,
+ val displayName: String,
+ val location: LorenzVec,
+ val spawnTime: SimpleTimeMark
+ )
private var test = false
@@ -221,42 +225,45 @@ object InquisitorWaypointShare {
if (packet.type.toInt() != 0) return
partyPattern.matchMatcher(message) {
- val playerName = group("playerName")
+ val rawName = group("playerName")
val x = group("x").trim().toInt()
val y = group("y").trim().toInt()
val z = group("z").trim().toInt()
val location = LorenzVec(x, y, z)
- val cleanName = playerName.cleanPlayerName()
- if (!waypoints.containsKey(cleanName)) {
- LorenzUtils.chat("$playerName §l§efound an inquisitor at §l§c$x $y $z!")
- if (cleanName != LorenzUtils.getPlayerName()) {
- LorenzUtils.sendTitle("§dINQUISITOR §efrom §b$cleanName", 5.seconds)
+ val name = rawName.cleanPlayerName()
+ val displayName = rawName.cleanPlayerName(displayName = true)
+ if (!waypoints.containsKey(name)) {
+ LorenzUtils.chat("$displayName §l§efound an inquisitor at §l§c$x $y $z!")
+ if (name != LorenzUtils.getPlayerName()) {
+ LorenzUtils.sendTitle("§dINQUISITOR §efrom §b$displayName", 5.seconds)
SoundUtils.playBeepSound()
}
}
- val inquis = SharedInquisitor(cleanName, location, SimpleTimeMark.now())
- waypoints = waypoints.editCopy { this[cleanName] = inquis }
+ val inquis = SharedInquisitor(name, displayName, location, SimpleTimeMark.now())
+ waypoints = waypoints.editCopy { this[name] = inquis }
if (config.focusInquisitor) {
- GriffinBurrowHelper.setTargetLocation(location.add(0, 1, 0))
+ GriffinBurrowHelper.setTargetLocation(location.add(y = 1))
GriffinBurrowHelper.animationLocation = LocationUtils.playerLocation()
}
event.isCanceled = true
}
diedPattern.matchMatcher(message) {
- val playerName = group("playerName").cleanPlayerName()
- waypoints = waypoints.editCopy { remove(playerName) }
- logger.log("Inquisitor died from '$playerName'")
+ val rawName = group("playerName")
+ val name = rawName.cleanPlayerName()
+ val displayName = rawName.cleanPlayerName(displayName = true)
+ waypoints = waypoints.editCopy { remove(name) }
+ logger.log("Inquisitor died from '$displayName'")
}
}
fun isEnabled() = DianaAPI.featuresEnabled() && config.enabled
- fun maybeRemove(playerName: String) {
+ fun maybeRemove(inquis: SharedInquisitor) {
if (inquisitorsNearby.isEmpty()) {
- waypoints = waypoints.editCopy { remove(playerName) }
- LorenzUtils.chat("Inquisitor from $playerName not found, deleting.")
+ waypoints = waypoints.editCopy { remove(inquis.fromPlayer) }
+ LorenzUtils.chat("Inquisitor from ${inquis.displayName} not found, deleting.")
}
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/jerry/frozentreasure/FrozenTreasureTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/event/jerry/frozentreasure/FrozenTreasureTracker.kt
index bfae2a7d8..63ec4fbf2 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/event/jerry/frozentreasure/FrozenTreasureTracker.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/event/jerry/frozentreasure/FrozenTreasureTracker.kt
@@ -2,12 +2,14 @@ package at.hannibal2.skyhanni.features.event.jerry.frozentreasure
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
+import at.hannibal2.skyhanni.config.features.event.winter.FrozenTreasureConfig.FrozenTreasureDisplayEntry
import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.data.ProfileStorageData
import at.hannibal2.skyhanni.data.ScoreboardData
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
+import at.hannibal2.skyhanni.utils.ConfigUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
import at.hannibal2.skyhanni.utils.LorenzUtils.addOrPut
import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland
@@ -96,7 +98,8 @@ object FrozenTreasureTracker {
private fun formatDisplay(map: List<List<Any>>): List<List<Any>> {
val newList = mutableListOf<List<Any>>()
for (index in config.textFormat) {
- newList.add(map[index])
+ // TODO, change functionality to use enum rather than ordinals
+ newList.add(map[index.ordinal])
}
return newList
}
@@ -168,6 +171,13 @@ object FrozenTreasureTracker {
@SubscribeEvent
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
event.move(2, "misc.frozenTreasureTracker", "event.winter.frozenTreasureTracker")
+ event.move(
+ 11,
+ "event.winter.frozenTreasureTracker.textFormat",
+ "event.winter.frozenTreasureTracker.textFormat"
+ ) { element ->
+ ConfigUtils.migrateIntArrayListToEnumArrayList(element, FrozenTreasureDisplayEntry::class.java)
+ }
}
private fun onJerryWorkshop() = IslandType.WINTER.isInIsland()
diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/winter/UniqueGiftCounter.kt b/src/main/java/at/hannibal2/skyhanni/features/event/winter/UniqueGiftCounter.kt
new file mode 100644
index 000000000..10b52745a
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/event/winter/UniqueGiftCounter.kt
@@ -0,0 +1,74 @@
+package at.hannibal2.skyhanni.features.event.winter
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.ProfileStorageData
+import at.hannibal2.skyhanni.events.GuiRenderEvent
+import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
+import at.hannibal2.skyhanni.events.IslandChangeEvent
+import at.hannibal2.skyhanni.utils.InventoryUtils
+import at.hannibal2.skyhanni.utils.ItemUtils.getLore
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber
+import at.hannibal2.skyhanni.utils.RenderUtils.renderString
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+object UniqueGiftCounter {
+
+ private val config get() = SkyHanniMod.feature.event.winter.uniqueGiftCounter
+ private val storage get() = ProfileStorageData.playerSpecific?.winter
+
+ private val pattern = "§7Unique Players Gifted: §a(?<amount>.*)".toPattern()
+
+ private var display = ""
+
+ @SubscribeEvent
+ fun onInventoryOpen(event: InventoryFullyOpenedEvent) {
+ if (event.inventoryName != "Generow") return
+ val item = event.inventoryItems[40] ?: return
+
+ val storage = storage ?: return
+
+ for (line in item.getLore()) {
+ pattern.matchMatcher(line) {
+ val amount = group("amount").formatNumber().toInt()
+ storage.amountGifted = amount
+ update()
+ return
+ }
+ }
+ }
+
+ @SubscribeEvent
+ fun onIslandChange(event: IslandChangeEvent) {
+ update()
+ }
+
+ fun addUniqueGift() {
+ val storage = storage ?: return
+ storage.amountGifted++
+ update()
+ }
+
+ private fun update() {
+ val storage = storage ?: return
+
+ val amountGifted = storage.amountGifted
+ val max = 600
+ val hasMax = amountGifted >= max
+ val color = if (hasMax) "§a" else "§e"
+ display = "§7Unique Players Gifted: $color$amountGifted/$max"
+ }
+
+ @SubscribeEvent
+ fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
+ if (!isEnabled()) return
+
+ config.position.renderString(
+ display,
+ posLabel = "Unique Gift Counter"
+ )
+ }
+
+ private fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled && InventoryUtils.itemInHandId.endsWith("_GIFT")
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingAPI.kt
index 550388893..027a4b6d0 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingAPI.kt
@@ -1,10 +1,18 @@
package at.hannibal2.skyhanni.features.fishing
import at.hannibal2.skyhanni.events.FishingBobberCastEvent
+import at.hannibal2.skyhanni.events.ItemInHandChangeEvent
+import at.hannibal2.skyhanni.events.SkillExpGainEvent
+import at.hannibal2.skyhanni.features.fishing.tracker.FishingProfitTracker
+import at.hannibal2.skyhanni.features.fishing.trophy.TrophyFishManager
+import at.hannibal2.skyhanni.features.fishing.trophy.TrophyFishManager.getFilletValue
+import at.hannibal2.skyhanni.features.fishing.trophy.TrophyRarity
+import at.hannibal2.skyhanni.utils.DelayedRun
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.NEUInternalName
import at.hannibal2.skyhanni.utils.SimpleTimeMark
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import net.minecraft.client.Minecraft
@@ -13,12 +21,14 @@ import net.minecraft.init.Blocks
import net.minecraft.item.ItemStack
import net.minecraftforge.event.entity.EntityJoinWorldEvent
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import kotlin.time.Duration.Companion.seconds
object FishingAPI {
private val lavaBlocks = listOf(Blocks.lava, Blocks.flowing_lava)
private val waterBlocks = listOf(Blocks.water, Blocks.flowing_water)
var lastCastTime = SimpleTimeMark.farPast()
+ var lastActiveFishingTime = SimpleTimeMark.farPast()
@SubscribeEvent
fun onJoinWorld(event: EntityJoinWorldEvent) {
@@ -31,7 +41,31 @@ object FishingAPI {
FishingBobberCastEvent(entity).postAndCatch()
}
- fun hasFishingRodInHand() = InventoryUtils.itemInHandId.asString().contains("ROD")
+ @SubscribeEvent
+ fun onItemInHandChange(event: ItemInHandChangeEvent) {
+ if (event.oldItem.isFishingRod()) {
+ lastActiveFishingTime = SimpleTimeMark.now()
+ }
+ if (event.newItem.isFishingRod()) {
+ DelayedRun.runDelayed(1.seconds) {
+ lastActiveFishingTime = SimpleTimeMark.now()
+ }
+ }
+ }
+
+ @SubscribeEvent
+ fun onSkillExpGain(event: SkillExpGainEvent) {
+ val skill = event.skill
+ if (FishingProfitTracker.isEnabled()) {
+ if (skill != "fishing") {
+ lastActiveFishingTime = SimpleTimeMark.farPast()
+ }
+ }
+ }
+
+ fun hasFishingRodInHand() = InventoryUtils.itemInHandId.isFishingRod()
+
+ fun NEUInternalName.isFishingRod() = contains("ROD")
fun ItemStack.isBait(): Boolean {
val name = name ?: return false
@@ -42,4 +76,14 @@ object FishingAPI {
fun getAllowedBlocks() = if (isLavaRod()) lavaBlocks else waterBlocks
+ fun getFilletPerTrophy(internalName: NEUInternalName): Int {
+ val internal = internalName.asString()
+ val trophyFishName = internal.substringBeforeLast("_")
+ .replace("_", "").lowercase()
+ val trophyRarityName = internal.substringAfterLast("_")
+ val info = TrophyFishManager.getInfo(trophyFishName)
+ val rarity = TrophyRarity.getByName(trophyRarityName) ?: TrophyRarity.BRONZE
+ return info?.getFilletValue(rarity) ?: 0
+ }
+
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingTimer.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingTimer.kt
index fa2b9b824..501b217f4 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingTimer.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingTimer.kt
@@ -92,6 +92,10 @@ class FishingTimer {
return true
}
+ if (config.crimsonIsle && IslandType.CRIMSON_ISLE.isInIsland()) return true
+
+ if (config.winterIsland && IslandType.WINTER.isInIsland()) return true
+
if (!IslandType.THE_FARMING_ISLANDS.isInIsland()) {
return LocationUtils.playerLocation().distance(barnLocation) < 50
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureManager.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureManager.kt
index f0a3c54b1..b3e0670fe 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureManager.kt
@@ -5,7 +5,7 @@ import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.RepositoryReloadEvent
import at.hannibal2.skyhanni.events.SeaCreatureFishEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.jsonobjects.SeaCreatureJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.SeaCreatureJson
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class SeaCreatureManager {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/ShowFishingItemName.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/ShowFishingItemName.kt
index a64d3da77..4a41b332c 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/fishing/ShowFishingItemName.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/ShowFishingItemName.kt
@@ -47,7 +47,7 @@ class ShowFishingItemName {
if (!isEnabled()) return
if (hasRodInHand) {
for (entityItem in EntityUtils.getEntities<EntityItem>()) {
- val location = event.exactLocation(entityItem).add(0.0, 0.8, 0.0)
+ val location = event.exactLocation(entityItem).add(y = 0.8)
if (location.distance(LocationUtils.playerLocation()) > 15) continue
val itemStack = entityItem.entityItem
var name = itemStack.name ?: continue
diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/ThunderSparksHighlight.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/ThunderSparksHighlight.kt
index bab0d5ae1..e49e8e3f8 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/fishing/ThunderSparksHighlight.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/ThunderSparksHighlight.kt
@@ -55,7 +55,7 @@ class ThunderSparksHighlight {
sparkLocation.add(-0.5, 0.0, -0.5), color, extraSize = -0.25, seeThroughBlocks = seeThroughBlocks
)
if (sparkLocation.distance(playerLocation) < 10) {
- event.drawString(sparkLocation.add(0.0, 1.5, 0.0), "Thunder Spark", seeThroughBlocks = seeThroughBlocks)
+ event.drawString(sparkLocation.add(y = 1.5), "Thunder Spark", seeThroughBlocks = seeThroughBlocks)
}
}
}
@@ -74,4 +74,4 @@ class ThunderSparksHighlight {
event.move(3, "fishing.thunderSparkHighlight", "fishing.thunderSpark.highlight")
event.move(3, "fishing.thunderSparkColor", "fishing.thunderSpark.color")
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingProfitPlayerMoving.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingProfitPlayerMoving.kt
new file mode 100644
index 000000000..ee19bab84
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingProfitPlayerMoving.kt
@@ -0,0 +1,43 @@
+package at.hannibal2.skyhanni.features.fishing.tracker
+
+import at.hannibal2.skyhanni.events.EntityMoveEvent
+import at.hannibal2.skyhanni.events.FishingBobberCastEvent
+import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
+import net.minecraft.client.Minecraft
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+object FishingProfitPlayerMoving {
+
+ private val lastSteps = mutableListOf<Double>()
+ var isMoving = true
+
+ @SubscribeEvent
+ fun onEntityMove(event: EntityMoveEvent) {
+ if (!FishingProfitTracker.isEnabled() || !FishingProfitTracker.config.hideMoving) return
+ if (event.entity != Minecraft.getMinecraft().thePlayer) return
+
+ val distance = event.newLocation.distanceIgnoreY(event.oldLocation)
+ if (distance < 0.1) {
+ lastSteps.clear()
+ return
+ }
+ lastSteps.add(distance)
+ if (lastSteps.size > 20) {
+ lastSteps.removeAt(0)
+ }
+ val total = lastSteps.sum()
+ if (total > 3) {
+ isMoving = true
+ }
+ }
+
+ @SubscribeEvent
+ fun onBobberThrow(event: FishingBobberCastEvent) {
+ isMoving = false
+ }
+
+ @SubscribeEvent
+ fun onWorldChange(event: LorenzWorldChangeEvent) {
+ isMoving = true
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingProfitTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingProfitTracker.kt
new file mode 100644
index 000000000..8d3da8564
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingProfitTracker.kt
@@ -0,0 +1,224 @@
+package at.hannibal2.skyhanni.features.fishing.tracker
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.events.FishingBobberCastEvent
+import at.hannibal2.skyhanni.events.GuiRenderEvent
+import at.hannibal2.skyhanni.events.ItemAddEvent
+import at.hannibal2.skyhanni.events.LorenzChatEvent
+import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
+import at.hannibal2.skyhanni.features.fishing.FishingAPI
+import at.hannibal2.skyhanni.utils.DelayedRun
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
+import at.hannibal2.skyhanni.utils.LorenzUtils.addButton
+import at.hannibal2.skyhanni.utils.NEUInternalName
+import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
+import at.hannibal2.skyhanni.utils.NumberUtil
+import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
+import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
+import at.hannibal2.skyhanni.utils.renderables.Renderable
+import at.hannibal2.skyhanni.utils.tracker.ItemTrackerData
+import at.hannibal2.skyhanni.utils.tracker.SkyHanniItemTracker
+import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker
+import com.google.gson.annotations.Expose
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import kotlin.time.Duration.Companion.milliseconds
+import kotlin.time.Duration.Companion.minutes
+import kotlin.time.Duration.Companion.seconds
+
+typealias CategoryName = String
+
+object FishingProfitTracker {
+ val config get() = SkyHanniMod.feature.fishing.fishingProfitTracker
+
+ private val coinsChatPattern = ".* CATCH! §r§bYou found §r§6(?<coins>.*) Coins§r§b\\.".toPattern()
+
+ private var lastCatchTime = SimpleTimeMark.farPast()
+ private val tracker = SkyHanniItemTracker(
+ "Fishing Profit Tracker",
+ { Data() },
+ { it.fishing.fishingProfitTracker }) { drawDisplay(it) }
+
+ class Data : ItemTrackerData() {
+ override fun resetItems() {
+ totalCatchAmount = 0
+ }
+
+ override fun getDescription(timesCaught: Long): List<String> {
+ val percentage = timesCaught.toDouble() / totalCatchAmount
+ val catchRate = LorenzUtils.formatPercentage(percentage.coerceAtMost(1.0))
+
+ return listOf(
+ "§7Caught §e${timesCaught.addSeparators()} §7times.",
+ "§7Your catch rate: §c$catchRate"
+ )
+ }
+
+ override fun getCoinName(item: TrackedItem) = "§6Fished Coins"
+
+ override fun getCoinDescription(item: TrackedItem): List<String> {
+ val mobKillCoinsFormat = NumberUtil.format(item.totalAmount)
+ return listOf(
+ "§7You fished up §6$mobKillCoinsFormat coins §7already."
+ )
+ }
+
+ override fun getCustomPricePer(internalName: NEUInternalName): Double {
+ // TODO find better way to tell if the item is a trophy
+ val neuInternalNames = itemCategories["Trophy Fish"]!!
+
+ return if (internalName in neuInternalNames) {
+ SkyHanniTracker.getPricePer(MAGMA_FISH) * FishingAPI.getFilletPerTrophy(internalName)
+ } else super.getCustomPricePer(internalName)
+ }
+
+ @Expose
+ var totalCatchAmount = 0L
+ }
+
+ private val ItemTrackerData.TrackedItem.timesCaught get() = timesGained
+
+ private val MAGMA_FISH by lazy { "MAGMA_FISH".asInternalName() }
+
+ private val nameAll: CategoryName = "All"
+ private var currentCategory: CategoryName = nameAll
+
+ private fun getCurrentCategories(data: Data): Map<CategoryName, Int> {
+ val map = mutableMapOf<CategoryName, Int>()
+ map[nameAll] = data.items.size
+ for ((name, items) in itemCategories) {
+ val amount = items.count { it in data.items }
+ if (amount > 0) {
+ map[name] = amount
+ }
+ }
+
+ return map
+ }
+
+ private fun drawDisplay(data: Data): List<List<Any>> = buildList {
+ addAsSingletonList("§e§lFishing Profit Tracker")
+ val filter: (NEUInternalName) -> Boolean = addCategories(data)
+
+ val profit = tracker.drawItems(data, filter, this)
+
+ val fishedCount = data.totalCatchAmount
+ addAsSingletonList(
+ Renderable.hoverTips(
+ "§7Times fished: §e${fishedCount.addSeparators()}",
+ listOf("§7You catched §e${fishedCount.addSeparators()} §7times something.")
+ )
+ )
+
+ val profitFormat = NumberUtil.format(profit)
+ val profitPrefix = if (profit < 0) "§c" else "§6"
+
+ val profitPerCatch = profit / data.totalCatchAmount
+ val profitPerCatchFormat = NumberUtil.format(profitPerCatch)
+
+ val text = "§eTotal Profit: $profitPrefix$profitFormat coins"
+ addAsSingletonList(Renderable.hoverTips(text, listOf("§7Profit per catch: $profitPrefix$profitPerCatchFormat")))
+
+ tracker.addPriceFromButton(this)
+ }
+
+ private fun MutableList<List<Any>>.addCategories(data: Data): (NEUInternalName) -> Boolean {
+ val amounts = getCurrentCategories(data)
+ val list = amounts.keys.toList()
+ if (currentCategory !in list) {
+ currentCategory = nameAll
+ }
+
+ if (tracker.isInventoryOpen()) {
+ addButton(
+ prefix = "§7Category: ",
+ getName = currentCategory + " §7(" + amounts[currentCategory] + ")",
+ onChange = {
+ val id = list.indexOf(currentCategory)
+ currentCategory = list[(id + 1) % list.size]
+ tracker.update()
+ }
+ )
+ }
+
+ val filter: (NEUInternalName) -> Boolean = if (currentCategory == nameAll) {
+ { true }
+ } else {
+ val items = itemCategories[currentCategory]!!
+ { it in items }
+ }
+ return filter
+ }
+
+ @SubscribeEvent
+ fun onItemAdd(event: ItemAddEvent) {
+ if (!isEnabled()) return
+ DelayedRun.runDelayed(500.milliseconds) {
+ maybeAddItem(event.internalName, event.amount)
+ }
+ }
+
+ @SubscribeEvent
+ fun onChat(event: LorenzChatEvent) {
+ coinsChatPattern.matchMatcher(event.message) {
+ val coins = group("coins").formatNumber()
+ tracker.addCoins(coins.toInt())
+ addCatch()
+ }
+ }
+
+ private fun addCatch() {
+ tracker.modify {
+ it.totalCatchAmount++
+ }
+ lastCatchTime = SimpleTimeMark.now()
+ }
+
+ @SubscribeEvent
+ fun onRenderOverlay(event: GuiRenderEvent) {
+ if (!isEnabled()) return
+
+ val recentPickup = config.showWhenPickup && lastCatchTime.passedSince() < 3.seconds
+ if (!recentPickup) {
+ if (!FishingAPI.hasFishingRodInHand()) return
+ // TODO remove hide moving chech, replace with last cast location + radius
+ if (FishingProfitPlayerMoving.isMoving && config.hideMoving) return
+ }
+
+ tracker.renderDisplay(config.position)
+ }
+
+ @SubscribeEvent
+ fun onWorldChange(event: LorenzWorldChangeEvent) {
+ lastCatchTime = SimpleTimeMark.farPast()
+ }
+
+ private fun maybeAddItem(internalName: NEUInternalName, amount: Int) {
+ if (FishingAPI.lastActiveFishingTime.passedSince() > 10.minutes) return
+
+ if (!isAllowedItem(internalName)) {
+ LorenzUtils.debug("Ignored non-fishing item pickup: $internalName'")
+ return
+ }
+
+ tracker.addItem(internalName, amount)
+ addCatch()
+ }
+
+ private val itemCategories get() = FishingTrackerCategoryManager.itemCategories
+
+ private fun isAllowedItem(internalName: NEUInternalName) = itemCategories.any { internalName in it.value }
+
+ @SubscribeEvent
+ fun onBobberThrow(event: FishingBobberCastEvent) {
+ tracker.firstUpdate()
+ }
+
+ fun resetCommand(args: Array<String>) {
+ tracker.resetCommand(args, "shresetfishingtracker")
+ }
+
+ fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingTrackerCategoryManager.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingTrackerCategoryManager.kt
new file mode 100644
index 000000000..2006975ad
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingTrackerCategoryManager.kt
@@ -0,0 +1,72 @@
+package at.hannibal2.skyhanni.features.fishing.tracker
+
+import at.hannibal2.skyhanni.data.jsonobjects.repo.FishingProfitItemsJson
+import at.hannibal2.skyhanni.events.RepositoryReloadEvent
+import at.hannibal2.skyhanni.utils.NEUInternalName
+import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+object FishingTrackerCategoryManager {
+
+ var itemCategories = mapOf<String, List<NEUInternalName>>()
+
+ private var shItemCategories = mapOf<String, List<NEUInternalName>>()
+ private var neuItemCategories = mapOf<String, List<NEUInternalName>>()
+
+ @SubscribeEvent
+ fun onRepoReload(event: RepositoryReloadEvent) {
+ shItemCategories = event.getConstant<FishingProfitItemsJson>("FishingProfitItems").categories
+ updateItemCategories()
+ }
+
+ private fun updateItemCategories() {
+ itemCategories = shItemCategories + neuItemCategories
+ }
+
+ @SubscribeEvent
+ fun onNeuRepoReload(event: io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent) {
+ val totalDrops = mutableListOf<String>()
+ val dropCategories = mutableMapOf<String, MutableList<NEUInternalName>>()
+ for ((seaCreature, data) in NotEnoughUpdates.INSTANCE.manager.itemInformation.filter { it.key.endsWith("_SC") }) {
+ val asJsonObject = data.getAsJsonArray("recipes")[0].asJsonObject
+ val drops = asJsonObject.getAsJsonArray("drops")
+ .map { it.asJsonObject.get("id").asString }.map { it.split(":").first() }
+ val asJsonArray = asJsonObject.get("extra")
+ val extra = asJsonArray?.let {
+ asJsonArray.asJsonArray.toList()
+ .map { it.toString() }
+ .filter { !it.contains("Fishing Skill") && !it.contains("Requirements:") && !it.contains("Fished from water") }
+ .joinToString(" + ")
+ } ?: "null"
+ val category = if (extra.contains("Fishing Festival")) {
+ "Fishing Festival"
+ } else if (extra.contains("Spooky Festival")) {
+ "Spooky Festival"
+ } else if (extra.contains("Jerry's Workshop")) {
+ "Jerry's Workshop"
+ } else if (extra.contains("Oasis")) {
+ "Oasis"
+ } else if (extra.contains("Magma Fields") || extra.contains("Precursor Remnants") ||
+ extra.contains("Goblin Holdout")
+ ) {
+ "Crystal Hollows"
+ } else if (extra.contains("Crimson Isle Lava")) {
+ "Crimson Isle Lava"
+ } else {
+ if (extra.isNotEmpty()) {
+ println("unknown extra: $extra = $seaCreature ($drops)")
+ }
+ "Water"
+ } + " Sea Creatures"
+ for (drop in drops) {
+ if (drop !in totalDrops) {
+ totalDrops.add(drop)
+ dropCategories.getOrPut(category) { mutableListOf() }.add(drop.asInternalName())
+ }
+ }
+ }
+ neuItemCategories = dropCategories
+ updateItemCategories()
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/TrophyFishManager.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/TrophyFishManager.kt
index 5f576ae46..6be896fb3 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/TrophyFishManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/trophy/TrophyFishManager.kt
@@ -5,8 +5,8 @@ import at.hannibal2.skyhanni.events.RepositoryReloadEvent
import at.hannibal2.skyhanni.test.command.ErrorManager
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.StringUtils.splitLines
-import at.hannibal2.skyhanni.utils.jsonobjects.TrophyFishJson
-import at.hannibal2.skyhanni.utils.jsonobjects.TrophyFishJson.TrophyFishInfo
+import at.hannibal2.skyhanni.data.jsonobjects.repo.TrophyFishJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.TrophyFishJson.TrophyFishInfo
import net.minecraft.event.HoverEvent
import net.minecraft.util.ChatComponentText
import net.minecraft.util.ChatStyle
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt
index 7d5c04d5f..e92fda526 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.InventoryCloseEvent
@@ -24,7 +23,7 @@ import net.minecraft.item.ItemStack
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class AnitaMedalProfit {
- private val config get() = SkyHanniMod.feature.garden.anitaShop
+ private val config get() = GardenAPI.config.anitaShop
private var display = emptyList<List<Any>>()
companion object {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt
index 423bdaed1..41ef944ea 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt
@@ -59,8 +59,7 @@ enum class CropType(
Blocks.melon_block -> MELON
Blocks.cactus -> CACTUS
Blocks.cocoa -> COCOA_BEANS
- Blocks.red_mushroom -> MUSHROOM
- Blocks.brown_mushroom -> MUSHROOM
+ Blocks.red_mushroom, Blocks.brown_mushroom -> MUSHROOM
Blocks.nether_wart -> NETHER_WART
else -> null
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt
index 3e57bb199..9fa7d7257 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt
@@ -148,7 +148,7 @@ class FarmingFortuneDisplay {
private fun isEnabled(): Boolean = GardenAPI.inGarden() && config.display
companion object {
- private val config get() = SkyHanniMod.feature.garden.farmingFortunes
+ private val config get() = GardenAPI.config.farmingFortunes
private val latestFF: MutableMap<CropType, Double>? get() = GardenAPI.storage?.latestTrueFarmingFortune
private var currentCrop: CropType? = null
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt
index 8998903d5..6ef4800dc 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt
@@ -4,6 +4,7 @@ import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.data.PetAPI
import at.hannibal2.skyhanni.data.ProfileStorageData
+import at.hannibal2.skyhanni.data.jsonobjects.repo.GardenJson
import at.hannibal2.skyhanni.events.BlockClickEvent
import at.hannibal2.skyhanni.events.ConfigLoadEvent
import at.hannibal2.skyhanni.events.CropClickEvent
@@ -22,21 +23,18 @@ import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI
import at.hannibal2.skyhanni.features.garden.inventory.SkyMartCopperPrice
import at.hannibal2.skyhanni.features.garden.visitor.VisitorAPI
import at.hannibal2.skyhanni.utils.BlockUtils.isBabyCrop
+import at.hannibal2.skyhanni.utils.DelayedRun
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.LocationUtils.isPlayerInside
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland
import at.hannibal2.skyhanni.utils.LorenzVec
-import at.hannibal2.skyhanni.utils.MinecraftDispatcher
import at.hannibal2.skyhanni.utils.NEUInternalName
import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getCultivatingCounter
import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getHoeCounter
-import at.hannibal2.skyhanni.utils.jsonobjects.GardenJson
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
import net.minecraft.client.Minecraft
+import net.minecraft.enchantment.Enchantment
import net.minecraft.item.ItemStack
import net.minecraft.network.play.client.C09PacketHeldItemChange
import net.minecraft.util.AxisAlignedBB
@@ -51,6 +49,7 @@ object GardenAPI {
private var inBarn = false
val onBarnPlot get() = inBarn && inGarden()
val storage get() = ProfileStorageData.profileSpecific?.garden
+ val config get() = SkyHanniMod.feature.garden
var totalAmountVisitorsExisting = 0
var gardenExp: Long?
get() = storage?.experience
@@ -62,6 +61,17 @@ object GardenAPI {
private val barnArea = AxisAlignedBB(35.5, 70.0, -4.5, -32.5, 100.0, -46.5)
+ // TODO USE SH-REPO
+ private val otherToolsList = listOf(
+ "DAEDALUS_AXE",
+ "BASIC_GARDENING_HOE",
+ "ADVANCED_GARDENING_AXE",
+ "BASIC_GARDENING_AXE",
+ "ADVANCED_GARDENING_HOE",
+ "ROOKIE_HOE",
+ "BINGHOE"
+ )
+
@SubscribeEvent
fun onSendPacket(event: PacketEvent.SendEvent) {
if (!inGarden()) return
@@ -87,14 +97,12 @@ object GardenAPI {
}
}
+ // TODO use IslandChangeEvent
@SubscribeEvent
fun onWorldChange(event: LorenzWorldChangeEvent) {
- SkyHanniMod.coroutineScope.launch {
- delay(2.seconds)
- withContext(MinecraftDispatcher) {
- if (inGarden()) {
- checkItemInHand()
- }
+ DelayedRun.runDelayed(2.seconds) {
+ if (inGarden()) {
+ checkItemInHand()
}
}
}
@@ -123,19 +131,7 @@ object GardenAPI {
}
private fun isOtherTool(internalName: NEUInternalName): Boolean {
- if (internalName.startsWith("DAEDALUS_AXE")) return true
-
- if (internalName.startsWith("BASIC_GARDENING_HOE")) return true
- if (internalName.startsWith("ADVANCED_GARDENING_AXE")) return true
-
- if (internalName.startsWith("BASIC_GARDENING_AXE")) return true
- if (internalName.startsWith("ADVANCED_GARDENING_HOE")) return true
-
- if (internalName.startsWith("ROOKIE_HOE")) return true
-
- if (internalName.startsWith("BINGHOE")) return true
-
- return false
+ return internalName.asString() in otherToolsList
}
fun inGarden() = IslandType.GARDEN.isInIsland()
@@ -147,9 +143,14 @@ object GardenAPI {
fun readCounter(itemStack: ItemStack): Long = itemStack.getHoeCounter() ?: itemStack.getCultivatingCounter() ?: -1L
- fun MutableList<Any>.addCropIcon(crop: CropType) {
+ fun MutableList<Any>.addCropIcon(crop: CropType, highlight: Boolean = false) {
try {
- add(crop.icon)
+ var icon = crop.icon.copy()
+ if (highlight) {
+ // Hack to add enchant glint, like Hypixel does it
+ icon.addEnchantment(Enchantment.protection, 0)
+ }
+ add(icon)
} catch (e: NullPointerException) {
e.printStackTrace()
}
@@ -185,7 +186,6 @@ object GardenAPI {
val cropBroken = blockState.getCropType() ?: return
if (cropBroken.multiplier == 1 && blockState.isBabyCrop()) return
-
val position = event.position
if (lastLocation == position) {
return
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneFix.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneFix.kt
index f6c235cc1..fa273ebb3 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneFix.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneFix.kt
@@ -9,14 +9,14 @@ import at.hannibal2.skyhanni.events.TabListUpdateEvent
import at.hannibal2.skyhanni.features.garden.farming.GardenCropMilestoneDisplay
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
-import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded
+import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import java.util.regex.Pattern
class GardenCropMilestoneFix {
private val tabListPattern = " Milestone: §r§a(?<crop>.*) (?<tier>.*): §r§3(?<percentage>.*)%".toPattern()
- private val levelUpPattern = Pattern.compile(" §r§b§lGARDEN MILESTONE §3(?<crop>.*) §8(?:.*)➜§3(?<tier>.*)")
+ private val levelUpPattern = Pattern.compile(" {2}§r§b§lGARDEN MILESTONE §3(?<crop>.*) §8(?:.*)➜§3(?<tier>.*)")
private val tabListCropProgress = mutableMapOf<CropType, Long>()
@@ -26,7 +26,7 @@ class GardenCropMilestoneFix {
val cropName = group("crop")
val crop = CropType.getByNameOrNull(cropName) ?: return
- val tier = group("tier").romanToDecimalIfNeeded()
+ val tier = group("tier").romanToDecimalIfNecessary()
val crops = GardenCropMilestones.getCropsForTier(tier, crop)
changedValue(crop, crops, "level up chat message", 0)
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropTimeCommand.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropTimeCommand.kt
index 92a01c7fb..bc1993c96 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropTimeCommand.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropTimeCommand.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.features.garden.farming.CropMoneyDisplay
import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed.getSpeed
import at.hannibal2.skyhanni.utils.ItemUtils.getItemName
@@ -12,7 +11,7 @@ import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import at.hannibal2.skyhanni.utils.TimeUtils
object GardenCropTimeCommand {
- private val config get() = SkyHanniMod.feature.garden.moneyPerHours
+ private val config get() = GardenAPI.config.moneyPerHours
fun onCommand(args: Array<String>) {
if (!config.display) {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenLevelDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenLevelDisplay.kt
index 50cf6b758..fe4df931b 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenLevelDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenLevelDisplay.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
@@ -9,7 +8,7 @@ import at.hannibal2.skyhanni.events.ProfileJoinEvent
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded
+import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary
import at.hannibal2.skyhanni.utils.RenderUtils.renderString
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
@@ -18,7 +17,7 @@ import kotlin.math.roundToLong
import kotlin.time.Duration.Companion.milliseconds
class GardenLevelDisplay {
- private val config get() = SkyHanniMod.feature.garden.gardenLevels
+ private val config get() = GardenAPI.config.gardenLevels
private val expToNextLevelPattern = ".* §e(?<nextLevelExp>.*)§6/.*".toPattern()
private val overflowPattern = ".*§r §6(?<overflow>.*) XP".toPattern()
private val namePattern = "Garden Level (?<currentLevel>.*)".toPattern()
@@ -64,7 +63,7 @@ class GardenLevelDisplay {
val item = event.inventoryItems[4]!!
namePattern.matchMatcher(item.name!!.removeColor()) {
- val currentLevel = group("currentLevel").romanToDecimalIfNeeded()
+ val currentLevel = group("currentLevel").romanToDecimalIfNecessary()
var nextLevelExp = 0L
for (line in item.getLore()) {
expToNextLevelPattern.matchMatcher(line) {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt
index c058e9fe6..2baa27ffa 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt
@@ -16,9 +16,12 @@ import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.RenderUtils.renderSingleLineWithItems
import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
+import at.hannibal2.skyhanni.utils.SimpleTimeMark.Companion.asTimeMark
import at.hannibal2.skyhanni.utils.SoundUtils
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
+import at.hannibal2.skyhanni.utils.TabListData
import at.hannibal2.skyhanni.utils.TimeUtils
import com.google.gson.Gson
import io.github.moulberry.notenoughupdates.util.SkyBlockTime
@@ -30,25 +33,30 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import org.lwjgl.opengl.Display
import java.awt.event.MouseAdapter
import java.awt.event.MouseEvent
-import java.time.Instant
import javax.swing.JButton
import javax.swing.JFrame
import javax.swing.JOptionPane
import javax.swing.UIManager
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.days
+import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds
object GardenNextJacobContest {
private var dispatcher = Dispatchers.IO
private var display = emptyList<Any>()
private var simpleDisplay = emptyList<String>()
- private var contests = mutableMapOf<Long, FarmingContest>()
+ private var contests = mutableMapOf<SimpleTimeMark, FarmingContest>()
private var inCalendar = false
+
private val patternDay = "§aDay (?<day>.*)".toPattern()
private val patternMonth = "(?<month>.*), Year (?<year>.*)".toPattern()
private val patternCrop = "§(e○|6☘) §7(?<crop>.*)".toPattern()
+ private val closeToNewYear = "§7Close to new SB year!"
private const val maxContestsPerYear = 124
- private const val contestDuration = 1_000 * 60 * 20
+ private val contestDuration = 20.minutes
+
private var lastWarningTime = 0L
private var loadedContestsYear = -1
private var nextContestsAvailableAt = -1L
@@ -76,12 +84,27 @@ object GardenNextJacobContest {
if (counter == 4) break
}
}
- newList.add("§cOpen calendar for")
- newList.add("§cmore exact data!")
+
+ if (isCloseToNewYear()) {
+ newList.add(closeToNewYear)
+ } else {
+ newList.add("§cOpen calendar for")
+ newList.add("§cmore exact data!")
+ }
simpleDisplay = newList
}
+ private fun isCloseToNewYear(): Boolean {
+ val now = SkyBlockTime.now()
+ val newYear = SkyBlockTime(year = now.year)
+ val nextYear = SkyBlockTime(year = now.year + 1)
+ val diffA = now.asTimeMark() - newYear.asTimeMark()
+ val diffB = nextYear.asTimeMark() - now.asTimeMark()
+
+ return diffA < 30.minutes || diffB < 30.minutes
+ }
+
@SubscribeEvent
fun onTick(event: LorenzTickEvent) {
if (!isEnabled()) return
@@ -123,7 +146,7 @@ object GardenNextJacobContest {
private fun readCalendar(items: Collection<ItemStack>, year: Int, month: Int) {
if (contests.isNotEmpty() && loadedContestsYear != year) {
val endTime = contests.values.first().endTime
- val lastYear = SkyBlockTime.fromInstant(Instant.ofEpochMilli(endTime)).year
+ val lastYear = endTime.toSkyBlockTime().year
if (year != lastYear) {
contests.clear()
}
@@ -149,7 +172,7 @@ object GardenNextJacobContest {
val name = item.name ?: continue
val day = patternDay.matchMatcher(name) { group("day").toInt() } ?: continue
- val startTime = SkyBlockTime(year, month, day).toMillis()
+ val startTime = SkyBlockTime(year, month, day).asTimeMark()
val crops = mutableListOf<CropType>()
for (line in lore) {
@@ -184,7 +207,7 @@ object GardenNextJacobContest {
val currentYear = SkyBlockTime.now().year
for (contest in contests.values) {
- val contestYear = (SkyBlockTime.fromInstant(Instant.ofEpochMilli(contest.endTime))).year
+ val contestYear = (contest.endTime.toSkyBlockTime()).year
// Ensure all stored contests are really from the current year
if (contestYear != currentYear) continue
@@ -199,7 +222,7 @@ object GardenNextJacobContest {
val year = savedContests.firstNotNullOfOrNull {
val endTime = it.key
- SkyBlockTime.fromInstant(Instant.ofEpochMilli(endTime)).year
+ endTime.toSkyBlockTime().year
}
// Clear contests if from previous year
@@ -232,7 +255,7 @@ object GardenNextJacobContest {
}
}
- class FarmingContest(val endTime: Long, val crops: List<CropType>)
+ class FarmingContest(val endTime: SimpleTimeMark, val crops: List<CropType>)
private fun update() {
nextContestCrops.clear()
@@ -265,18 +288,22 @@ object GardenNextJacobContest {
}
if (contests.isEmpty()) {
- list.add("§cOpen calendar to read jacob contest times!")
+ if (isCloseToNewYear()) {
+ list.add(closeToNewYear)
+ } else {
+ list.add("§cOpen calendar to read jacob contest times!")
+ }
return list
}
val nextContest =
- contests.filter { it.value.endTime > System.currentTimeMillis() }.toSortedMap()
+ contests.filter { !it.value.endTime.isInPast() }.toSortedMap()
.firstNotNullOfOrNull { it.value }
// Show next contest
if (nextContest != null) return drawNextContest(nextContest, list)
- if (contests.size == maxContestsPerYear) {
- list.add("§cNew SkyBlock Year! Open calendar again!")
+ if (isCloseToNewYear()) {
+ list.add(closeToNewYear)
} else {
list.add("§cOpen calendar to read jacob contest times!")
}
@@ -291,17 +318,24 @@ object GardenNextJacobContest {
nextContest: FarmingContest,
list: MutableList<Any>,
): MutableList<Any> {
- var duration = nextContest.endTime - System.currentTimeMillis()
+ var duration = nextContest.endTime.timeUntil()
+ if (duration > 4.days) {
+ list.add(closeToNewYear)
+ return list
+ }
+
+ val boostedCrop = calculateBoostedCrop(nextContest)
+
if (duration < contestDuration) {
list.add("§aActive: ")
} else {
list.add("§eNext: ")
duration -= contestDuration
- warn(duration, nextContest.crops)
+ warn(duration, nextContest.crops, boostedCrop)
}
for (crop in nextContest.crops) {
list.add(" ")
- list.addCropIcon(crop)
+ list.addCropIcon(crop, highlight = (crop == boostedCrop))
nextContestCrops.add(crop)
}
val format = TimeUtils.formatDuration(duration)
@@ -310,23 +344,39 @@ object GardenNextJacobContest {
return list
}
- private fun warn(timeInMillis: Long, crops: List<CropType>) {
+ private fun calculateBoostedCrop(nextContest: FarmingContest): CropType? {
+ for (line in TabListData.getTabList()) {
+ val lineStripped = line.removeColor().trim()
+ if (!lineStripped.startsWith("☘ ")) continue
+ for (crop in nextContest.crops) {
+ if (line.removeColor().trim() == "☘ ${crop.cropName}") {
+ return crop
+ }
+ }
+ }
+
+ return null
+ }
+
+ private fun warn(duration: Duration, crops: List<CropType>, boostedCrop: CropType?) {
if (!config.warn) return
- if (config.warnTime <= timeInMillis / 1000) return
+ if (config.warnTime.seconds <= duration) return
if (System.currentTimeMillis() < lastWarningTime) return
lastWarningTime = System.currentTimeMillis() + 60_000 * 40
- val cropText = crops.joinToString("§7, ") { "§a${it.cropName}" }
+ val cropText = crops.joinToString("§7, ") { (if (it == boostedCrop) "§6" else "§a") + it.cropName }
LorenzUtils.chat("Next farming contest: $cropText")
LorenzUtils.sendTitle("§eFarming Contest!", 5.seconds)
SoundUtils.playBeepSound()
+ val cropTextNoColor =
+ crops.joinToString(", ") { if (it == boostedCrop) "<b>${it.cropName}</b>" else it.cropName }
if (config.warnPopup && !Display.isActive()) {
SkyHanniMod.coroutineScope.launch {
openPopupWindow(
- "Farming Contest soon!\n" +
- "Crops: ${cropText.removeColor()}"
+ "<html>Farming Contest soon!<br />" +
+ "Crops: ${cropTextNoColor}</html>"
)
}
}
@@ -422,12 +472,13 @@ object GardenNextJacobContest {
val url = "https://api.elitebot.dev/contests/at/now"
val result = withContext(dispatcher) { APIUtil.getJSONResponse(url) }.asJsonObject
- val newContests = mutableMapOf<Long, FarmingContest>()
+ val newContests = mutableMapOf<SimpleTimeMark, FarmingContest>()
val complete = result["complete"].asBoolean
if (complete) {
for (entry in result["contests"].asJsonObject.entrySet()) {
var timestamp = entry.key.toLongOrNull() ?: continue
+ val timeMark = (timestamp * 1000).asTimeMark()
timestamp *= 1_000 // Seconds to milliseconds
val crops = entry.value.asJsonArray.map {
@@ -436,7 +487,7 @@ object GardenNextJacobContest {
if (crops.size != 3) continue
- newContests[timestamp + contestDuration] = FarmingContest(timestamp + contestDuration, crops)
+ newContests[timeMark + contestDuration] = FarmingContest(timeMark + contestDuration, crops)
}
} else {
LorenzUtils.chat("This years contests aren't available to fetch automatically yet, please load them from your calender or wait 10 minutes!")
@@ -459,7 +510,7 @@ object GardenNextJacobContest {
}
private fun sendContests() {
- if (isSendingContests || contests.size != maxContestsPerYear) return
+ if (isSendingContests || contests.size != maxContestsPerYear || isCloseToNewYear()) return
isSendingContests = true
@@ -473,7 +524,7 @@ object GardenNextJacobContest {
val formatted = mutableMapOf<Long, List<String>>()
for ((endTime, contest) in contests) {
- formatted[endTime / 1000] = contest.crops.map {
+ formatted[endTime.toMillis() / 1000] = contest.crops.map {
it.cropName
}
}
@@ -494,7 +545,7 @@ object GardenNextJacobContest {
null
}
- private val config get() = SkyHanniMod.feature.garden.nextJacobContests
+ private val config get() = GardenAPI.config.nextJacobContests
private val nextContestCrops = mutableListOf<CropType>()
fun isNextCrop(cropName: CropType) = nextContestCrops.contains(cropName) && config.otherGuis
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt
index 967368915..201b1bc7e 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.GardenToolChangeEvent
import at.hannibal2.skyhanni.events.GuiRenderEvent
@@ -19,7 +18,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.time.Duration.Companion.seconds
class GardenOptimalSpeed {
- private val config get() = SkyHanniMod.feature.garden.optimalSpeeds
+ private val config get() = GardenAPI.config.optimalSpeeds
private val configCustomSpeed get() = config.customSpeed
private var currentSpeed = 100
private var optimalSpeed = -1
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenPlotAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenPlotAPI.kt
new file mode 100644
index 000000000..64308abf1
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenPlotAPI.kt
@@ -0,0 +1,185 @@
+package at.hannibal2.skyhanni.features.garden
+
+import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
+import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
+import at.hannibal2.skyhanni.features.misc.LockMouseLook
+import at.hannibal2.skyhanni.utils.ItemUtils.name
+import at.hannibal2.skyhanni.utils.LocationUtils.isPlayerInside
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.LorenzVec
+import at.hannibal2.skyhanni.utils.RenderUtils.draw3DLine
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
+import com.google.gson.annotations.Expose
+import net.minecraft.util.AxisAlignedBB
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import java.awt.Color
+import kotlin.math.floor
+
+object GardenPlotAPI {
+
+ private val pestNamePattern = "§aPlot §7- §b(?<name>.*)".toPattern()
+
+ var plots = listOf<Plot>()
+
+ fun getCurrentPlot(): Plot? {
+ return plots.firstOrNull { it.isPlayerInside() }
+ }
+
+ class Plot(val id: Int, var inventorySlot: Int, val box: AxisAlignedBB, val middle: LorenzVec)
+
+ class PlotData(
+ @Expose
+ val id: Int,
+
+ @Expose
+ var name: String,
+
+ @Expose
+ var pests: Int
+ )
+
+ private fun Plot.getData() = GardenAPI.storage?.plotData?.getOrPut(id) { PlotData(id, "$id", 0) }
+
+ var Plot.name: String
+ get() = getData()?.name ?: "$id"
+ set(value) {
+ getData()?.name = value
+ }
+
+ var Plot.pests: Int
+ get() = getData()?.pests ?: 0
+ set(value) {
+ getData()?.pests = value
+ }
+
+ fun Plot.isBarn() = id == -1
+
+ fun Plot.isPlayerInside() = box.isPlayerInside()
+
+ fun Plot.sendTeleportTo() {
+ LorenzUtils.sendCommandToServer("tptoplot $name")
+ LockMouseLook.autoDisable()
+ }
+
+ init {
+ val plotMap = listOf(
+ listOf(21, 13, 9, 14, 22),
+ listOf(15, 5, 1, 6, 16),
+ listOf(10, 2, -1, 3, 11),
+ listOf(17, 7, 4, 8, 18),
+ listOf(23, 19, 12, 20, 24),
+ )
+ val list = mutableListOf<Plot>()
+ var slot = 2
+ for ((y, rows) in plotMap.withIndex()) {
+ for ((x, id) in rows.withIndex()) {
+ val minX = ((x - 2) * 96 - 48).toDouble()
+ val minY = ((y - 2) * 96 - 48).toDouble()
+ val maxX = ((x - 2) * 96 + 48).toDouble()
+ val maxY = ((y - 2) * 96 + 48).toDouble()
+ val a = LorenzVec(minX, 0.0, minY)
+ val b = LorenzVec(maxX, 256.0, maxY)
+ val middle = a.interpolate(b, 0.5).copy(y = 10.0)
+ val box = a.axisAlignedTo(b).expand(0.0001, 0.0, 0.0001)
+ list.add(Plot(id, slot, box, middle))
+ slot++
+ }
+ slot += 4
+ }
+ plots = list
+ }
+
+ @SubscribeEvent
+ fun onInventoryOpen(event: InventoryFullyOpenedEvent) {
+ if (!GardenAPI.inGarden()) return
+ if (event.inventoryName != "Configure Plots") return
+
+ for (plot in plots) {
+ val itemName = event.inventoryItems[plot.inventorySlot]?.name ?: continue
+ pestNamePattern.matchMatcher(itemName) {
+ plot.name = group("name")
+ }
+ }
+ }
+
+ fun getPlotByName(plotName: String) = plots.firstOrNull { it.name == plotName }
+
+ fun LorenzRenderWorldEvent.renderPlot(plot: GardenPlotAPI.Plot, lineColor: Color, cornerColor: Color) {
+
+ // These don't refer to Minecraft chunks but rather garden plots, but I use
+ // the word chunk as the logic closely represents how chunk borders are rendered in latter mc versions
+ val plotSize = 96
+ val chunkX = floor((plot.middle.x + 48) / plotSize).toInt()
+ val chunkZ = floor((plot.middle.z + 48) / plotSize).toInt()
+ val chunkMinX = (chunkX * plotSize) - 48
+ val chunkMinZ = (chunkZ * plotSize) - 48
+
+ // Lowest point in the garden
+ val minHeight = 66
+ val maxHeight = 256
+
+ // Render 4 vertical corners
+ for (i in 0..plotSize step plotSize) {
+ for (j in 0..plotSize step plotSize) {
+ val start = LorenzVec(chunkMinX + i, minHeight, chunkMinZ + j)
+ val end = LorenzVec(chunkMinX + i, maxHeight, chunkMinZ + j)
+ tryDraw3DLine(start, end, cornerColor, 2, true)
+ }
+ }
+
+ // Render vertical on X-Axis
+ for (x in 4..<plotSize step 4) {
+ val start = LorenzVec(chunkMinX + x, minHeight, chunkMinZ)
+ val end = LorenzVec(chunkMinX + x, maxHeight, chunkMinZ)
+ // Front lines
+ tryDraw3DLine(start, end, lineColor, 1, true)
+ // Back lines
+ tryDraw3DLine(start.add(z = plotSize), end.add(z = plotSize), lineColor, 1, true)
+ }
+
+ // Render vertical on Z-Axis
+ for (z in 4..<plotSize step 4) {
+ val start = LorenzVec(chunkMinX, minHeight, chunkMinZ + z)
+ val end = LorenzVec(chunkMinX, maxHeight, chunkMinZ + z)
+ // Left lines
+ tryDraw3DLine(start, end, lineColor, 1, true)
+ // Right lines
+ tryDraw3DLine(start.add(x = plotSize), end.add(x = plotSize), lineColor, 1, true)
+ }
+
+ // Render horizontal
+ for (y in minHeight..maxHeight step 4) {
+ val start = LorenzVec(chunkMinX, y, chunkMinZ)
+ // (minX, minZ) -> (minX, minZ + 96)
+ tryDraw3DLine(start, start.add(z = plotSize), lineColor, 1, true)
+ // (minX, minZ + 96) -> (minX + 96, minZ + 96)
+ tryDraw3DLine(start.add(z = plotSize), start.add(x = plotSize, z = plotSize), lineColor, 1, true)
+ // (minX + 96, minZ + 96) -> (minX + 96, minZ)
+ tryDraw3DLine(start.add(x = plotSize, z = plotSize), start.add(x = plotSize), lineColor, 1, true)
+ // (minX + 96, minZ) -> (minX, minZ)
+ tryDraw3DLine(start.add(x = plotSize), start, lineColor, 1, true)
+ }
+ }
+
+ private fun LorenzRenderWorldEvent.tryDraw3DLine(
+ p1: LorenzVec,
+ p2: LorenzVec,
+ color: Color,
+ lineWidth: Int,
+ depth: Boolean
+ ) {
+ if (isOutOfBorders(p1)) return
+ if (isOutOfBorders(p2)) return
+ draw3DLine(p1, p2, color, lineWidth, depth)
+ }
+
+ private fun isOutOfBorders(location: LorenzVec) = when {
+ location.x > 240 -> true
+ location.x < -240 -> true
+ location.z > 240 -> true
+ location.z < -240 -> true
+
+ else -> false
+ }
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenPlotBorders.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenPlotBorders.kt
index d5d00d509..893e31cbf 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenPlotBorders.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenPlotBorders.kt
@@ -1,29 +1,19 @@
package at.hannibal2.skyhanni.features.garden
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.LorenzKeyPressEvent
import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
+import at.hannibal2.skyhanni.features.garden.GardenPlotAPI.renderPlot
import at.hannibal2.skyhanni.utils.LorenzColor
-import at.hannibal2.skyhanni.utils.LorenzVec
-import at.hannibal2.skyhanni.utils.RenderUtils.draw3DLine
import at.hannibal2.skyhanni.utils.SimpleTimeMark
-import net.minecraft.client.Minecraft
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import org.lwjgl.input.Keyboard
-import java.awt.Color
-import kotlin.math.floor
import kotlin.time.Duration.Companion.milliseconds
-class GardenPlotBorders {
+object GardenPlotBorders {
- private val config get() = SkyHanniMod.feature.garden.plotBorders
+ private val config get() = GardenAPI.config.plotBorders
private var timeLastSaved = SimpleTimeMark.farPast()
private var showBorders = false
- private val LINE_COLOR = LorenzColor.YELLOW.toColor()
-
- private fun LorenzVec.addX(x: Int) = add(x, 0, 0)
- private fun LorenzVec.addZ(z: Int) = add(0, 0, z)
- private fun LorenzVec.addXZ(x: Int, z: Int) = add(x, 0, z)
@SubscribeEvent
fun onKeyClick(event: LorenzKeyPressEvent) {
@@ -44,84 +34,10 @@ class GardenPlotBorders {
fun render(event: LorenzRenderWorldEvent) {
if (!isEnabled()) return
if (!showBorders) return
-
- val entity = Minecraft.getMinecraft().renderViewEntity
-
- // Lowest point in garden
- val minHeight = 66
- val maxHeight = 256
-
- // These don't refer to Minecraft chunks but rather garden plots, but I use
- // the word chunk as the logic closely represents how chunk borders are rendered in latter mc versions
- val chunkX = floor((entity.posX + 48) / 96).toInt()
- val chunkZ = floor((entity.posZ + 48) / 96).toInt()
- val chunkMinX = (chunkX * 96) - 48
- val chunkMinZ = (chunkZ * 96) - 48
-
- // Render 4 vertical corners
- for (i in 0..96 step 96) {
- for (j in 0..96 step 96) {
- val start = LorenzVec(chunkMinX + i, minHeight, chunkMinZ + j)
- val end = LorenzVec(chunkMinX + i, maxHeight, chunkMinZ + j)
- event.tryDraw3DLine(start, end, LorenzColor.DARK_BLUE.toColor(), 2, true)
- }
- }
-
- // Render vertical on X-Axis
- for (x in 4..<96 step 4) {
- val start = LorenzVec(chunkMinX + x, minHeight, chunkMinZ)
- val end = LorenzVec(chunkMinX + x, maxHeight, chunkMinZ)
- // Front lines
- event.tryDraw3DLine(start, end, LINE_COLOR, 1, true)
- // Back lines
- event.tryDraw3DLine(start.addZ(96), end.addZ(96), LINE_COLOR, 1, true)
- }
-
- // Render vertical on Z-Axis
- for (z in 4..<96 step 4) {
- val start = LorenzVec(chunkMinX, minHeight, chunkMinZ + z)
- val end = LorenzVec(chunkMinX, maxHeight, chunkMinZ + z)
- // Left lines
- event.tryDraw3DLine(start, end, LINE_COLOR, 1, true)
- // Right lines
- event.tryDraw3DLine(start.addX(96), end.addX(96), LINE_COLOR, 1, true)
- }
-
- // Render horizontal
- for (y in minHeight..maxHeight step 4) {
- val start = LorenzVec(chunkMinX, y, chunkMinZ)
- // (minX, minZ) -> (minX, minZ + 96)
- event.tryDraw3DLine(start, start.addZ(96), LINE_COLOR, 1, true)
- // (minX, minZ + 96) -> (minX + 96, minZ + 96)
- event.tryDraw3DLine(start.addZ(96), start.addXZ(96, 96), LINE_COLOR, 1, true)
- // (minX + 96, minZ + 96) -> (minX + 96, minZ)
- event.tryDraw3DLine(start.addXZ(96, 96), start.addX(96), LINE_COLOR, 1, true)
- // (minX + 96, minZ) -> (minX, minZ)
- event.tryDraw3DLine(start.addX(96), start, LINE_COLOR, 1, true)
- }
- }
-
- private fun LorenzRenderWorldEvent.tryDraw3DLine(
- p1: LorenzVec,
- p2: LorenzVec,
- color: Color,
- lineWidth: Int,
- depth: Boolean
- ) {
- if (isOutOfBorders(p1)) return
- if (isOutOfBorders(p2)) return
- draw3DLine(p1, p2, color, lineWidth, depth)
+ val plot = GardenPlotAPI.getCurrentPlot() ?: return
+ event.renderPlot(plot, LorenzColor.YELLOW.toColor(), LorenzColor.DARK_BLUE.toColor())
}
- private fun isOutOfBorders(location: LorenzVec) = when {
- location.x > 240 -> true
- location.x < -240 -> true
- location.z > 240 -> true
- location.z < -240 -> true
-
- else -> false
- }
-
fun isEnabled() = GardenAPI.inGarden() && config
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenWarpCommands.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenWarpCommands.kt
new file mode 100644
index 000000000..a25949350
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenWarpCommands.kt
@@ -0,0 +1,63 @@
+package at.hannibal2.skyhanni.features.garden
+
+import at.hannibal2.skyhanni.events.LorenzKeyPressEvent
+import at.hannibal2.skyhanni.events.MessageSendToServerEvent
+import at.hannibal2.skyhanni.features.misc.LockMouseLook
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.NEUItems
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
+import net.minecraft.client.Minecraft
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+class GardenWarpCommands {
+ private val config get() = GardenAPI.config.gardenCommands
+
+ // TODO repo
+ private val tpPlotPattern = "/tp (?<plot>.*)".toPattern()
+
+ @SubscribeEvent
+ fun onMessageSendToServer(event: MessageSendToServerEvent) {
+ if (!config.warpCommands) return
+ if (!GardenAPI.inGarden()) return
+
+ val message = event.message.lowercase()
+
+ if (message == "/home") {
+ event.isCanceled = true
+ LorenzUtils.sendCommandToServer("warp garden")
+ LorenzUtils.chat("§aTeleported you to the spawn location!", prefix = false)
+ }
+
+ if (message == "/barn") {
+ event.isCanceled = true
+ LorenzUtils.sendCommandToServer("tptoplot barn")
+ LockMouseLook.autoDisable()
+ }
+
+ tpPlotPattern.matchMatcher(event.message) {
+ event.isCanceled = true
+ val plotName = group("plot")
+ LorenzUtils.sendCommandToServer("tptoplot $plotName")
+ LockMouseLook.autoDisable()
+ }
+ }
+
+ @SubscribeEvent
+ fun onKeyClick(event: LorenzKeyPressEvent) {
+ if (!GardenAPI.inGarden()) return
+ if (Minecraft.getMinecraft().currentScreen != null) return
+ if (NEUItems.neuHasFocus()) return
+
+ val command = when (event.keyCode) {
+ config.homeHotkey -> "warp garden"
+ config.sethomeHotkey -> "sethome"
+ config.barnHotkey -> "tptoplot barn"
+
+ else -> return
+ }
+ if (command == "tptoplot barn") {
+ LockMouseLook.autoDisable()
+ }
+ LorenzUtils.sendCommandToServer(command)
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenYawAndPitch.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenYawAndPitch.kt
index 2a09754cd..d053a4ede 100755
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenYawAndPitch.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenYawAndPitch.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.GardenToolChangeEvent
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
@@ -12,7 +11,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.time.Duration.Companion.seconds
class GardenYawAndPitch {
- private val config get() = SkyHanniMod.feature.garden.yawPitchDisplay
+ private val config get() = GardenAPI.config.yawPitchDisplay
private var lastChange = SimpleTimeMark.farPast()
private var lastYaw = 0f
private var lastPitch = 0f
@@ -57,4 +56,4 @@ class GardenYawAndPitch {
fun onGardenToolChange(event: GardenToolChangeEvent) {
lastChange = SimpleTimeMark.farPast()
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/ToolTooltipTweaks.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/ToolTooltipTweaks.kt
index 58371a771..bebeb71f8 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/ToolTooltipTweaks.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/ToolTooltipTweaks.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.LorenzToolTipEvent
import at.hannibal2.skyhanni.features.garden.FarmingFortuneDisplay.Companion.getAbilityFortune
@@ -19,7 +18,7 @@ import java.text.DecimalFormat
import kotlin.math.roundToInt
class ToolTooltipTweaks {
- private val config get() = SkyHanniMod.feature.garden.tooltipTweak
+ private val config get() = GardenAPI.config.tooltipTweak
private val tooltipFortunePattern =
"^§5§o§7Farming Fortune: §a\\+([\\d.]+)(?: §2\\(\\+\\d\\))?(?: §9\\(\\+(\\d+)\\))?$".toRegex()
private val counterStartLine = setOf("§5§o§6Logarithmic Counter", "§5§o§6Collection Analysis")
@@ -160,4 +159,4 @@ class ToolTooltipTweaks {
event.move(3, "garden.fortuneTooltipKeybind", "garden.tooltipTweak.fortuneTooltipKeybind")
event.move(3, "garden.cropTooltipFortune", "garden.tooltipTweak.cropTooltipFortune")
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterDisplay.kt
index 2e089364c..cf06da7f6 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterDisplay.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden.composter
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.TabListUpdateEvent
@@ -19,7 +18,7 @@ import kotlin.time.Duration.Companion.seconds
import kotlin.time.DurationUnit
class ComposterDisplay {
- private val config get() = SkyHanniMod.feature.garden.composters
+ private val config get() = GardenAPI.config.composters
private val storage get() = GardenAPI.storage
private var display = emptyList<List<Any>>()
private var composterEmptyTime: Duration? = null
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterInventoryNumbers.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterInventoryNumbers.kt
index e344699c7..2bbfc27a6 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterInventoryNumbers.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterInventoryNumbers.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden.composter
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.RenderInventoryItemTipEvent
import at.hannibal2.skyhanni.features.garden.GardenAPI
@@ -18,7 +17,7 @@ class ComposterInventoryNumbers {
@SubscribeEvent
fun onRenderItemTip(event: RenderInventoryItemTipEvent) {
if (!GardenAPI.inGarden()) return
- if (!SkyHanniMod.feature.garden.composters.inventoryNumbers) return
+ if (!GardenAPI.config.composters.inventoryNumbers) return
if (event.inventoryName != "Composter") return
@@ -72,4 +71,4 @@ class ComposterInventoryNumbers {
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
event.move(3, "garden.composterInventoryNumbers", "garden.composters.inventoryNumbers")
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterOverlay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterOverlay.kt
index b99f059da..f65e02107 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterOverlay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterOverlay.kt
@@ -1,9 +1,9 @@
package at.hannibal2.skyhanni.features.garden.composter
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.data.SackAPI
import at.hannibal2.skyhanni.data.SackStatus
+import at.hannibal2.skyhanni.data.jsonobjects.repo.GardenJson
import at.hannibal2.skyhanni.data.model.ComposterUpgrade
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.InventoryCloseEvent
@@ -14,6 +14,7 @@ import at.hannibal2.skyhanni.events.TabListUpdateEvent
import at.hannibal2.skyhanni.features.bazaar.BazaarApi
import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.features.garden.composter.ComposterAPI.getLevel
+import at.hannibal2.skyhanni.features.misc.items.EstimatedItemValue
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName_old
import at.hannibal2.skyhanni.utils.ItemUtils.name
@@ -27,14 +28,13 @@ import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
import at.hannibal2.skyhanni.utils.NEUItems
import at.hannibal2.skyhanni.utils.NumberUtil
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
-import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded
+import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary
import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
import at.hannibal2.skyhanni.utils.SimpleTimeMark
import at.hannibal2.skyhanni.utils.SoundUtils
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import at.hannibal2.skyhanni.utils.TimeUtils
-import at.hannibal2.skyhanni.utils.jsonobjects.GardenJson
import at.hannibal2.skyhanni.utils.renderables.Renderable
import io.github.moulberry.notenoughupdates.NotEnoughUpdates
import net.minecraftforge.event.entity.player.ItemTooltipEvent
@@ -52,7 +52,7 @@ object ComposterOverlay {
private var fuelFactors: Map<String, Double> = emptyMap()
private var organicMatter: Map<String, Double> = emptyMap()
- private val config get() = SkyHanniMod.feature.garden.composters
+ private val config get() = GardenAPI.config.composters
private var organicMatterDisplay = emptyList<List<Any>>()
private var fuelExtraDisplay = emptyList<List<Any>>()
@@ -135,7 +135,7 @@ object ComposterOverlay {
event.itemStack?.name?.let {
if (it.contains(upgrade.displayName)) {
maxLevel = ComposterUpgrade.regex.matchMatcher(it) {
- group("level")?.romanToDecimalIfNeeded() ?: 0
+ group("level")?.romanToDecimalIfNecessary() ?: 0
} == 25
extraComposterUpgrade = upgrade
update()
@@ -550,6 +550,8 @@ object ComposterOverlay {
@SubscribeEvent
fun onBackgroundDraw(event: GuiRenderEvent.ChestGuiOverlayRenderEvent) {
+ if (EstimatedItemValue.isCurrentlyShowing()) return
+
if (inInventory) {
config.overlayOrganicMatterPos.renderStringsAndItems(
organicMatterDisplay,
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/GardenComposterInventoryFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/GardenComposterInventoryFeatures.kt
index 397231258..3a1f9cf5e 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/GardenComposterInventoryFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/GardenComposterInventoryFeatures.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden.composter
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.GuiContainerEvent
import at.hannibal2.skyhanni.features.garden.GardenAPI
@@ -19,7 +18,7 @@ import net.minecraftforge.event.entity.player.ItemTooltipEvent
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class GardenComposterInventoryFeatures {
- private val config get() = SkyHanniMod.feature.garden.composters
+ private val config get() = GardenAPI.config.composters
@SubscribeEvent
fun onTooltip(event: ItemTooltipEvent) {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestFFNeededDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestFFNeededDisplay.kt
index 3f03cbe4b..e52a1b343 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestFFNeededDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestFFNeededDisplay.kt
@@ -1,11 +1,11 @@
package at.hannibal2.skyhanni.features.garden.contest
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.InventoryCloseEvent
import at.hannibal2.skyhanni.events.RenderItemTooltipEvent
import at.hannibal2.skyhanni.features.garden.CropType
import at.hannibal2.skyhanni.features.garden.FarmingFortuneDisplay.Companion.getLatestTrueFarmingFortune
+import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed.getLatestBlocksPerSecond
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.name
@@ -19,7 +19,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.math.ceil
class JacobContestFFNeededDisplay {
- private val config get() = SkyHanniMod.feature.garden
+ private val config get() = GardenAPI.config
private var display = emptyList<List<Any>>()
private var lastToolTipTime = 0L
private val cache = mutableMapOf<ItemStack, List<List<Any>>>()
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestStatsSummary.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestStatsSummary.kt
index faa2ed534..72dc37621 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestStatsSummary.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestStatsSummary.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden.contest
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.data.ClickType
import at.hannibal2.skyhanni.events.CropClickEvent
import at.hannibal2.skyhanni.events.FarmingContestEvent
@@ -12,7 +11,7 @@ import at.hannibal2.skyhanni.utils.TimeUtils
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class JacobContestStatsSummary {
- private val config get() = SkyHanniMod.feature.garden
+ private val config get() = GardenAPI.config
private var blocksBroken = 0
private var startTime = 0L
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestTimeNeeded.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestTimeNeeded.kt
index 4d9e035cd..3ce6178ad 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestTimeNeeded.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/JacobContestTimeNeeded.kt
@@ -1,10 +1,10 @@
package at.hannibal2.skyhanni.features.garden.contest
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.InventoryUpdatedEvent
import at.hannibal2.skyhanni.features.garden.CropType
import at.hannibal2.skyhanni.features.garden.FarmingFortuneDisplay.Companion.getLatestTrueFarmingFortune
+import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed.getLatestBlocksPerSecond
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
@@ -19,7 +19,7 @@ import net.minecraftforge.fml.common.eventhandler.EventPriority
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class JacobContestTimeNeeded {
- private val config get() = SkyHanniMod.feature.garden
+ private val config get() = GardenAPI.config
private var display = emptyList<List<Any>>()
private var currentBracket = ContestBracket.GOLD
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/ArmorDropTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/ArmorDropTracker.kt
index 21c271e49..f3fac8d2d 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/ArmorDropTracker.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/ArmorDropTracker.kt
@@ -1,7 +1,8 @@
package at.hannibal2.skyhanni.features.garden.farming
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
+import at.hannibal2.skyhanni.data.jsonobjects.repo.ArmorDropsJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.ArmorDropsJson.DropInfo
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
@@ -16,8 +17,6 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.addOrPut
import at.hannibal2.skyhanni.utils.LorenzUtils.sortedDesc
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.SimpleTimeMark
-import at.hannibal2.skyhanni.utils.jsonobjects.ArmorDropsJson
-import at.hannibal2.skyhanni.utils.jsonobjects.ArmorDropsJson.DropInfo
import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker
import at.hannibal2.skyhanni.utils.tracker.TrackerData
import com.google.gson.JsonObject
@@ -29,7 +28,7 @@ object ArmorDropTracker {
private var hasArmor = false
private val armorPattern = "(FERMENTO|CROPIE|SQUASH|MELON)_(LEGGINGS|CHESTPLATE|BOOTS|HELMET)".toPattern()
- private val config get() = SkyHanniMod.feature.garden.farmingArmorDrop
+ private val config get() = GardenAPI.config.farmingArmorDrop
private val tracker = SkyHanniTracker("Armor Drop Tracker", { Data() }, { it.garden.armorDropTracker })
{ drawDisplay(it) }
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropMoneyDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropMoneyDisplay.kt
index b780bbc0e..937a94a45 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropMoneyDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropMoneyDisplay.kt
@@ -2,6 +2,7 @@ package at.hannibal2.skyhanni.features.garden.farming
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
+import at.hannibal2.skyhanni.config.features.garden.MoneyPerHourConfig.CustomFormatEntry
import at.hannibal2.skyhanni.events.GardenToolChangeEvent
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
@@ -16,6 +17,7 @@ import at.hannibal2.skyhanni.features.garden.GardenNextJacobContest
import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed.getSpeed
import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed.isSpeedDataEmpty
import at.hannibal2.skyhanni.test.command.ErrorManager
+import at.hannibal2.skyhanni.utils.ConfigUtils
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.ItemUtils.getItemNameOrNull
@@ -50,7 +52,7 @@ object CropMoneyDisplay {
}
private var display = emptyList<List<Any>>()
- private val config get() = SkyHanniMod.feature.garden.moneyPerHours
+ private val config get() = GardenAPI.config.moneyPerHours
private var loaded = false
private var ready = false
private val cropNames = mutableMapOf<NEUInternalName, CropType>()
@@ -110,7 +112,7 @@ object CropMoneyDisplay {
newDisplay.addAsSingletonList(fullTitle(title))
- if (!SkyHanniMod.feature.garden.cropMilestones.progress) {
+ if (!GardenAPI.config.cropMilestones.progress) {
newDisplay.addAsSingletonList("§cCrop Milestone Progress Display is disabled!")
return newDisplay
}
@@ -235,6 +237,7 @@ object CropMoneyDisplay {
return if (config.hideTitle) newDisplay.drop(1) else newDisplay
}
+ // TODO : Rewrite to not be index-reliant
private fun fullTitle(title: String): String {
val titleText: String
val nameList = mutableListOf<String>()
@@ -246,7 +249,8 @@ object CropMoneyDisplay {
)
val list = mutableListOf<String>()
for (index in config.customFormat) {
- map[index]?.let {
+ // TODO, change functionality to use enum rather than ordinals
+ map[index.ordinal]?.let {
list.add(it)
}
}
@@ -276,8 +280,7 @@ object CropMoneyDisplay {
val onlyNpcPrice =
(!config.useCustomFormat && LorenzUtils.noTradeMode) ||
- (config.useCustomFormat && config.customFormat.size == 1 &&
- config.customFormat[0] == 2)
+ (config.useCustomFormat && config.customFormat.singleOrNull() == CustomFormatEntry.NPC_PRICE)
for ((internalName, amount) in multipliers.moveEntryToTop { isSeeds(it.key) }) {
val crop = cropNames[internalName]!!
@@ -364,6 +367,7 @@ object CropMoneyDisplay {
private fun isSeeds(internalName: NEUInternalName) =
internalName.equals("ENCHANTED_SEEDS") || internalName.equals("SEEDS")
+ // TODO : Rewrite to not be index-reliant
private fun formatNumbers(sellOffer: Double, instantSell: Double, npcPrice: Double): Array<Double> {
return if (config.useCustomFormat) {
val map = mapOf(
@@ -373,7 +377,8 @@ object CropMoneyDisplay {
)
val newList = mutableListOf<Double>()
for (index in config.customFormat) {
- map[index]?.let {
+ // TODO, change functionality to use enum rather than ordinals
+ map[index.ordinal]?.let {
newList.add(it)
}
}
@@ -436,5 +441,8 @@ object CropMoneyDisplay {
event.move(3, "garden.moneyPerHourDicer", "garden.moneyPerHours.dicer")
event.move(3, "garden.moneyPerHourHideTitle", "garden.moneyPerHours.hideTitle")
event.move(3, "garden.moneyPerHourPos", "garden.moneyPerHours.pos")
+ event.move(11, "garden.moneyPerHours.customFormat") { element ->
+ ConfigUtils.migrateIntArrayListToEnumArrayList(element, CustomFormatEntry::class.java)
+ }
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropSpeedMeter.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropSpeedMeter.kt
index fd337a361..2d1580974 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropSpeedMeter.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropSpeedMeter.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden.farming
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.data.GardenCropMilestones.getCounter
import at.hannibal2.skyhanni.events.CropClickEvent
import at.hannibal2.skyhanni.events.CropMilestoneUpdateEvent
@@ -128,7 +127,7 @@ class CropSpeedMeter {
fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
if (!isEnabled()) return
- SkyHanniMod.feature.garden.cropSpeedMeterPos.renderStrings(display, posLabel = "Crop Speed Meter")
+ GardenAPI.config.cropSpeedMeterPos.renderStrings(display, posLabel = "Crop Speed Meter")
}
fun isEnabled() = enabled && GardenAPI.inGarden()
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/DicerDropTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/DicerDropTracker.kt
index 24f55672b..b347d6dfe 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/DicerDropTracker.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/DicerDropTracker.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden.farming
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigManager
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.GardenToolChangeEvent
@@ -13,14 +12,16 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
import at.hannibal2.skyhanni.utils.LorenzUtils.addOrPut
import at.hannibal2.skyhanni.utils.LorenzUtils.sortedDesc
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker
import at.hannibal2.skyhanni.utils.tracker.TrackerData
import com.google.gson.annotations.Expose
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import java.util.regex.Pattern
object DicerDropTracker {
private val itemDrops = mutableListOf<ItemDrop>()
- private val config get() = SkyHanniMod.feature.garden.dicerCounters
+ private val config get() = GardenAPI.config.dicerCounters
private val tracker = SkyHanniTracker("Dicer Drop Tracker", { Data() }, { it.garden.dicerDropTracker })
{ drawDisplay(it) }
@@ -33,16 +34,35 @@ object DicerDropTracker {
var drops: MutableMap<CropType, MutableMap<DropRarity, Int>> = mutableMapOf()
}
+ // TODO USE SH-REPO
+ private val melonUncommonDropPattern =
+ "§a§lUNCOMMON DROP! §r§eDicer dropped §r§a(\\d+)x §r§aEnchanted Melon§r§e!".toPattern()
+ private val melonRareDropPattern =
+ "§9§lRARE DROP! §r§eDicer dropped §r§a(\\d+)x §r§aEnchanted Melon§r§e!".toPattern()
+ private val melonCrazyRareDropPattern =
+ "§d§lCRAZY RARE DROP! §r§eDicer dropped §r§[a|9](\\d+)x §r§[a|9]Enchanted Melon(?: Block)?§r§e!".toPattern()
+ private val melonRngesusDropPattern =
+ "§5§lPRAY TO RNGESUS DROP! §r§eDicer dropped §r§9(\\d+)x §r§9Enchanted Melon Block§r§e!".toPattern()
+
+ private val pumpkinUncommonDropPattern =
+ "§a§lUNCOMMON DROP! §r§eDicer dropped §r§a(\\d+)x §r§aEnchanted Pumpkin§r§e!".toPattern()
+ private val pumpkinRareDropPattern =
+ "§9§lRARE DROP! §r§eDicer dropped §r§a(\\d+)x §r§aEnchanted Pumpkin§r§e!".toPattern()
+ private val pumpkinCrazyRareDropPattern =
+ "§d§lCRAZY RARE DROP! §r§eDicer dropped §r§a(\\d+)x §r§aEnchanted Pumpkin§r§e!".toPattern()
+ private val pumpkinRngesusDropPattern =
+ "§5§lPRAY TO RNGESUS DROP! §r§eDicer dropped §r§[a|9](\\d+)x §r§(aEnchanted|9Polished) Pumpkin§r§e!".toPattern()
+
init {
- itemDrops.add(ItemDrop(CropType.MELON, DropRarity.UNCOMMON, "§a§lUNCOMMON DROP! §r§eDicer dropped §r§a(\\d+)x §r§aEnchanted Melon§r§e!".toRegex()))
- itemDrops.add(ItemDrop(CropType.MELON, DropRarity.RARE, "§9§lRARE DROP! §r§eDicer dropped §r§a(\\d+)x §r§aEnchanted Melon§r§e!".toRegex()))
- itemDrops.add(ItemDrop(CropType.MELON, DropRarity.CRAZY_RARE, "§d§lCRAZY RARE DROP! §r§eDicer dropped §r§[a|9](\\d+)x §r§[a|9]Enchanted Melon(?: Block)?§r§e!".toRegex()))
- itemDrops.add(ItemDrop(CropType.MELON, DropRarity.PRAY_TO_RNGESUS, "§5§lPRAY TO RNGESUS DROP! §r§eDicer dropped §r§9(\\d+)x §r§9Enchanted Melon Block§r§e!".toRegex()))
-
- itemDrops.add(ItemDrop(CropType.PUMPKIN, DropRarity.UNCOMMON, "§a§lUNCOMMON DROP! §r§eDicer dropped §r§a(\\d+)x §r§aEnchanted Pumpkin§r§e!".toRegex()))
- itemDrops.add(ItemDrop(CropType.PUMPKIN, DropRarity.RARE, "§9§lRARE DROP! §r§eDicer dropped §r§a(\\d+)x §r§aEnchanted Pumpkin§r§e!".toRegex()))
- itemDrops.add(ItemDrop(CropType.PUMPKIN, DropRarity.CRAZY_RARE, "§d§lCRAZY RARE DROP! §r§eDicer dropped §r§a(\\d+)x §r§aEnchanted Pumpkin§r§e!".toRegex()))
- itemDrops.add(ItemDrop(CropType.PUMPKIN, DropRarity.PRAY_TO_RNGESUS, "§5§lPRAY TO RNGESUS DROP! §r§eDicer dropped §r§[a|9](\\d+)x §r§(aEnchanted|9Polished) Pumpkin§r§e!".toRegex()))
+ itemDrops.add(ItemDrop(CropType.MELON, DropRarity.UNCOMMON, melonUncommonDropPattern))
+ itemDrops.add(ItemDrop(CropType.MELON, DropRarity.RARE, melonRareDropPattern))
+ itemDrops.add(ItemDrop(CropType.MELON, DropRarity.CRAZY_RARE, melonCrazyRareDropPattern))
+ itemDrops.add(ItemDrop(CropType.MELON, DropRarity.PRAY_TO_RNGESUS, melonRngesusDropPattern))
+
+ itemDrops.add(ItemDrop(CropType.PUMPKIN, DropRarity.UNCOMMON, pumpkinUncommonDropPattern))
+ itemDrops.add(ItemDrop(CropType.PUMPKIN, DropRarity.RARE, pumpkinRareDropPattern))
+ itemDrops.add(ItemDrop(CropType.PUMPKIN, DropRarity.CRAZY_RARE, pumpkinCrazyRareDropPattern))
+ itemDrops.add(ItemDrop(CropType.PUMPKIN, DropRarity.PRAY_TO_RNGESUS, pumpkinRngesusDropPattern))
}
enum class DropRarity(val displayName: String) {
@@ -59,7 +79,7 @@ object DicerDropTracker {
val message = event.message
for (drop in itemDrops) {
- if (drop.pattern.matches(message)) {
+ drop.pattern.matchMatcher(message) {
addDrop(drop.crop, drop.rarity)
if (config.hideChat) {
event.blockedReason = "dicer_drop_tracker"
@@ -107,7 +127,7 @@ object DicerDropTracker {
tracker.renderDisplay(config.pos)
}
- class ItemDrop(val crop: CropType, val rarity: DropRarity, val pattern: Regex)
+ class ItemDrop(val crop: CropType, val rarity: DropRarity, val pattern: Pattern)
fun isEnabled() = GardenAPI.inGarden() && config.display
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt
index fb9bdfaac..4b478c28f 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt
@@ -90,7 +90,7 @@ class FarmingWeightDisplay {
}
companion object {
- private val config get() = SkyHanniMod.feature.garden.eliteFarmingWeights
+ private val config get() = GardenAPI.config.eliteFarmingWeights
private val localCounter = mutableMapOf<CropType, Long>()
private var dispatcher = Dispatchers.IO
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBestCropTime.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBestCropTime.kt
index 0ef03d090..6190bc27b 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBestCropTime.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBestCropTime.kt
@@ -1,11 +1,11 @@
package at.hannibal2.skyhanni.features.garden.farming
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.data.GardenCropMilestones
import at.hannibal2.skyhanni.data.GardenCropMilestones.getCounter
import at.hannibal2.skyhanni.data.GardenCropMilestones.isMaxed
import at.hannibal2.skyhanni.features.garden.CropType
+import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.features.garden.GardenAPI.addCropIcon
import at.hannibal2.skyhanni.features.garden.GardenNextJacobContest
import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed.getSpeed
@@ -19,7 +19,7 @@ class GardenBestCropTime {
var display = emptyList<List<Any>>()
companion object {
- private val config get() = SkyHanniMod.feature.garden.cropMilestones
+ private val config get() = GardenAPI.config.cropMilestones
val timeTillNextCrop = mutableMapOf<CropType, Long>()
fun reset() {
@@ -95,7 +95,8 @@ class GardenBestCropTime {
for (crop in sorted.keys) {
if (crop.isMaxed()) continue
val millis = timeTillNextCrop[crop]!!
- val biggestUnit = TimeUnit.entries[config.highestTimeFormat.get()]
+ // TODO, change functionality to use enum rather than ordinals
+ val biggestUnit = TimeUnit.entries[config.highestTimeFormat.get().ordinal]
val duration = TimeUtils.formatDuration(millis, biggestUnit, maxUnits = 2)
val isCurrent = crop == currentCrop
number++
@@ -136,4 +137,4 @@ class GardenBestCropTime {
event.move(3, "garden.cropMilestoneBestCompact", "garden.cropMilestones.next.bestCompact")
event.move(3, "garden.cropMilestoneBestHideTitle", "garden.cropMilestones.next.bestHideTitle")
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBurrowingSporesNotifier.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBurrowingSporesNotifier.kt
index 93387ac32..33036b52a 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBurrowingSporesNotifier.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBurrowingSporesNotifier.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden.farming
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.utils.LorenzUtils
@@ -12,7 +11,7 @@ class GardenBurrowingSporesNotifier {
@SubscribeEvent
fun onChat(event: LorenzChatEvent) {
if (!GardenAPI.inGarden()) return
- if (!SkyHanniMod.feature.garden.burrowingSporesNotification) return
+ if (!GardenAPI.config.burrowingSporesNotification) return
if (event.message.endsWith("§6§lVERY RARE CROP! §r§f§r§9Burrowing Spores")) {
LorenzUtils.sendTitle("§9Burrowing Spores!", 5.seconds)
@@ -20,4 +19,4 @@ class GardenBurrowingSporesNotifier {
// ItemBlink.setBlink(NEUItems.getItemStackOrNull("BURROWING_SPORES"), 5_000)
}
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropMilestoneDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropMilestoneDisplay.kt
index 76647517d..adfe0518d 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropMilestoneDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropMilestoneDisplay.kt
@@ -1,7 +1,9 @@
package at.hannibal2.skyhanni.features.garden.farming
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
+import at.hannibal2.skyhanni.config.features.garden.cropmilestones.CropMilestonesConfig.MilestoneTextEntry
+import at.hannibal2.skyhanni.config.features.garden.cropmilestones.CropMilestonesConfig.TimeFormatEntry
+import at.hannibal2.skyhanni.config.features.garden.cropmilestones.MushroomPetPerkConfig.MushroomTextEntry
import at.hannibal2.skyhanni.data.GardenCropMilestones
import at.hannibal2.skyhanni.data.GardenCropMilestones.getCounter
import at.hannibal2.skyhanni.data.GardenCropMilestones.isMaxed
@@ -18,6 +20,7 @@ import at.hannibal2.skyhanni.features.garden.GardenAPI.addCropIcon
import at.hannibal2.skyhanni.features.garden.GardenAPI.getCropType
import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed.setSpeed
import at.hannibal2.skyhanni.test.command.ErrorManager
+import at.hannibal2.skyhanni.utils.ConfigUtils
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
import at.hannibal2.skyhanni.utils.LorenzUtils.round
@@ -34,7 +37,7 @@ object GardenCropMilestoneDisplay {
private var progressDisplay = emptyList<List<Any>>()
private var mushroomCowPerkDisplay = emptyList<List<Any>>()
private val cultivatingData = mutableMapOf<CropType, Long>()
- private val config get() = SkyHanniMod.feature.garden.cropMilestones
+ private val config get() = GardenAPI.config.cropMilestones
private val bestCropTime = GardenBestCropTime()
private var lastPlaySoundTime = 0L
@@ -176,7 +179,8 @@ object GardenCropMilestoneDisplay {
val missingTimeSeconds = missing / farmingFortuneSpeed
val millis = missingTimeSeconds * 1000
GardenBestCropTime.timeTillNextCrop[crop] = millis
- val biggestUnit = TimeUnit.entries[config.highestTimeFormat.get()]
+ // TODO, change functionality to use enum rather than ordinals
+ val biggestUnit = TimeUnit.entries[config.highestTimeFormat.get().ordinal]
val duration = TimeUtils.formatDuration(millis, biggestUnit)
tryWarn(millis, "§b${crop.cropName} $nextTier in $duration")
val speedText = "§7In §b$duration"
@@ -225,7 +229,8 @@ object GardenCropMilestoneDisplay {
private fun formatDisplay(lineMap: HashMap<Int, List<Any>>): MutableList<List<Any>> {
val newList = mutableListOf<List<Any>>()
for (index in config.text) {
- lineMap[index]?.let {
+ // TODO, change functionality to use enum rather than ordinals
+ lineMap[index.ordinal]?.let {
newList.add(it)
}
}
@@ -238,14 +243,23 @@ object GardenCropMilestoneDisplay {
}
private fun addMushroomCowData() {
+ val mushroom = CropType.MUSHROOM
+ if (mushroom.isMaxed()) {
+ mushroomCowPerkDisplay = listOf(
+ listOf("§6Mooshroom Cow Perk"),
+ listOf("§eMushroom crop is maxed!"),
+ )
+ return
+ }
+
val lineMap = HashMap<Int, List<Any>>()
- val counter = CropType.MUSHROOM.getCounter()
+ val counter = mushroom.getCounter()
- val currentTier = GardenCropMilestones.getTierForCropCount(counter, CropType.MUSHROOM)
+ val currentTier = GardenCropMilestones.getTierForCropCount(counter, mushroom)
val nextTier = currentTier + 1
- val cropsForCurrentTier = GardenCropMilestones.getCropsForTier(currentTier, CropType.MUSHROOM)
- val cropsForNextTier = GardenCropMilestones.getCropsForTier(nextTier, CropType.MUSHROOM)
+ val cropsForCurrentTier = GardenCropMilestones.getCropsForTier(currentTier, mushroom)
+ val cropsForNextTier = GardenCropMilestones.getCropsForTier(nextTier, mushroom)
val have = counter - cropsForCurrentTier
val need = cropsForNextTier - cropsForCurrentTier
@@ -258,7 +272,7 @@ object GardenCropMilestoneDisplay {
lineMap[0] = Collections.singletonList("§6Mooshroom Cow Perk")
val list = mutableListOf<Any>()
- list.addCropIcon(CropType.MUSHROOM)
+ list.addCropIcon(mushroom)
list.add("§7Mushroom Tier $nextTier")
lineMap[1] = list
@@ -270,7 +284,8 @@ object GardenCropMilestoneDisplay {
val missingTimeSeconds = missing / blocksPerSecond
val millis = missingTimeSeconds * 1000
- val biggestUnit = TimeUnit.entries[config.highestTimeFormat.get()]
+ // TODO, change functionality to use enum rather than ordinals
+ val biggestUnit = TimeUnit.entries[config.highestTimeFormat.get().ordinal]
val duration = TimeUtils.formatDuration(millis.toLong(), biggestUnit)
lineMap[3] = Collections.singletonList("§7In §b$duration")
}
@@ -280,7 +295,8 @@ object GardenCropMilestoneDisplay {
val newList = mutableListOf<List<Any>>()
for (index in config.mushroomPetPerk.text) {
- lineMap[index]?.let {
+ // TODO, change functionality to use enum rather than ordinals
+ lineMap[index.ordinal]?.let {
newList.add(it)
}
}
@@ -304,5 +320,26 @@ object GardenCropMilestoneDisplay {
event.move(3, "garden.cropMilestoneMushroomPetPerkEnabled", "garden.cropMilestones.mushroomPetPerk.enabled")
event.move(3, "garden.cropMilestoneMushroomPetPerkText", "garden.cropMilestones.mushroomPetPerk.text")
event.move(3, "garden.cropMilestoneMushroomPetPerkPos", "garden.cropMilestones.mushroomPetPerk.pos")
+ event.move(
+ 11,
+ "garden.cropMilestones.highestTimeFormat",
+ "garden.cropMilestones.highestTimeFormat"
+ ) { element ->
+ ConfigUtils.migrateIntToEnum(element, TimeFormatEntry::class.java)
+ }
+ event.move(
+ 11,
+ "garden.cropMilestones.text",
+ "garden.cropMilestones.text"
+ ) { element ->
+ ConfigUtils.migrateIntArrayListToEnumArrayList(element, MilestoneTextEntry::class.java)
+ }
+ event.move(
+ 11,
+ "garden.cropMilestones.mushroomPetPerk.text",
+ "garden.cropMilestones.mushroomPetPerk.text"
+ ) { element ->
+ ConfigUtils.migrateIntArrayListToEnumArrayList(element, MushroomTextEntry::class.java)
+ }
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropSpeed.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropSpeed.kt
index 0f10ed883..a21f57698 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropSpeed.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropSpeed.kt
@@ -1,11 +1,12 @@
package at.hannibal2.skyhanni.features.garden.farming
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.data.ClickType
import at.hannibal2.skyhanni.data.GardenCropMilestones.getCounter
import at.hannibal2.skyhanni.data.GardenCropMilestones.setCounter
import at.hannibal2.skyhanni.data.MayorElection
+import at.hannibal2.skyhanni.data.jsonobjects.repo.DicerDropsJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.DicerDropsJson.DicerType
import at.hannibal2.skyhanni.events.CropClickEvent
import at.hannibal2.skyhanni.events.GardenToolChangeEvent
import at.hannibal2.skyhanni.events.PreProfileSwitchEvent
@@ -15,13 +16,11 @@ import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy
-import at.hannibal2.skyhanni.utils.jsonobjects.DicerDropsJson
-import at.hannibal2.skyhanni.utils.jsonobjects.DicerDropsJson.DicerType
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.concurrent.fixedRateTimer
object GardenCropSpeed {
- private val config get() = SkyHanniMod.feature.garden
+ private val config get() = GardenAPI.config
private val cropsPerSecond: MutableMap<CropType, Int>? get() = GardenAPI.storage?.cropsPerSecond
private val latestBlocksPerSecond: MutableMap<CropType, Double>? get() = GardenAPI.storage?.latestBlocksPerSecond
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCustomKeybinds.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCustomKeybinds.kt
index 6b30cf3af..6bbde660f 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCustomKeybinds.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCustomKeybinds.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden.farming
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.mixins.transformers.AccessorKeyBinding
@@ -14,24 +13,24 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable
import java.util.IdentityHashMap
object GardenCustomKeybinds {
- private val shConfig get() = SkyHanniMod.feature.garden.keyBind
+ private val config get() = GardenAPI.config.keyBind
private val mcSettings get() = Minecraft.getMinecraft().gameSettings
private val map: MutableMap<KeyBinding, () -> Int> = IdentityHashMap()
private var lastWindowOpenTime = 0L
init {
- map[mcSettings.keyBindAttack] = { shConfig.attack }
- map[mcSettings.keyBindUseItem] = { shConfig.useItem }
- map[mcSettings.keyBindLeft] = { shConfig.left }
- map[mcSettings.keyBindRight] = { shConfig.right }
- map[mcSettings.keyBindForward] = { shConfig.forward }
- map[mcSettings.keyBindBack] = { shConfig.back }
- map[mcSettings.keyBindJump] = { shConfig.jump }
- map[mcSettings.keyBindSneak] = { shConfig.sneak }
+ map[mcSettings.keyBindAttack] = { config.attack }
+ map[mcSettings.keyBindUseItem] = { config.useItem }
+ map[mcSettings.keyBindLeft] = { config.left }
+ map[mcSettings.keyBindRight] = { config.right }
+ map[mcSettings.keyBindForward] = { config.forward }
+ map[mcSettings.keyBindBack] = { config.back }
+ map[mcSettings.keyBindJump] = { config.jump }
+ map[mcSettings.keyBindSneak] = { config.sneak }
}
- private fun isEnabled() = GardenAPI.inGarden() && shConfig.enabled
+ private fun isEnabled() = GardenAPI.inGarden() && config.enabled
private fun isActive(): Boolean {
if (!isEnabled()) return false
@@ -80,4 +79,4 @@ object GardenCustomKeybinds {
event.move(3, "garden.keyBindJump", "garden.keyBind.jump")
event.move(3, "garden.keyBindSneak", "garden.keyBind.sneak")
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenStartLocation.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenStartLocation.kt
index 3384af51e..f1fdd112a 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenStartLocation.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenStartLocation.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden.farming
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.CropClickEvent
import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
import at.hannibal2.skyhanni.features.garden.GardenAPI
@@ -12,13 +11,14 @@ import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
object GardenStartLocation {
+ private val config get() = GardenAPI.config.cropStartLocation
fun setLocationCommand() {
if (!GardenAPI.inGarden()) {
LorenzUtils.userError("This Command only works in the garden!")
return
}
- if (!SkyHanniMod.feature.garden.cropStartLocation.enabled) {
+ if (!config.enabled) {
LorenzUtils.clickableChat(
"This feature is disabled. Enable it in the config: §e/sh crop start location",
"sh crop start location",
@@ -67,5 +67,5 @@ object GardenStartLocation {
event.drawDynamicText(location, crop.cropName, 1.5)
}
- fun isEnabled() = GardenAPI.inGarden() && SkyHanniMod.feature.garden.cropStartLocation.enabled
+ fun isEnabled() = GardenAPI.inGarden() && config.enabled
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/WildStrawberryDyeNotification.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/WildStrawberryDyeNotification.kt
index d923efb6d..aaa1a734c 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/WildStrawberryDyeNotification.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/WildStrawberryDyeNotification.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden.farming
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.GuiContainerEvent
import at.hannibal2.skyhanni.events.OwnInventoryItemUpdateEvent
import at.hannibal2.skyhanni.features.garden.GardenAPI
@@ -10,7 +9,6 @@ import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
import at.hannibal2.skyhanni.utils.SoundUtils
-import io.github.moulberry.notenoughupdates.util.MinecraftExecutor
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.time.Duration.Companion.seconds
@@ -27,23 +25,21 @@ class WildStrawberryDyeNotification {
@SubscribeEvent
fun onOwnInventoryItemUpdate(event: OwnInventoryItemUpdateEvent) {
if (!GardenAPI.inGarden()) return
- if (!SkyHanniMod.feature.garden.wildStrawberryDyeNotification) return
+ if (!GardenAPI.config.wildStrawberryDyeNotification) return
val itemStack = event.itemStack
- MinecraftExecutor.OnThread.execute {
-
- // Prevent false positives when buying the item in ah or moving it from a storage
- val diff = System.currentTimeMillis() - lastCloseTime
- if (diff < 1_000) return@execute
-
- val internalName = itemStack.getInternalName()
- if (internalName == item) {
- val name = itemStack.name!!
- LorenzUtils.sendTitle(name, 5.seconds)
- LorenzUtils.chat("You found a $name§e!")
- SoundUtils.playBeepSound()
- ItemBlink.setBlink(itemStack, 5_000)
- }
+
+ // Prevent false positives when buying the item in ah or moving it from a storage
+ val diff = System.currentTimeMillis() - lastCloseTime
+ if (diff < 1_000) return
+
+ val internalName = itemStack.getInternalName()
+ if (internalName == item) {
+ val name = itemStack.name!!
+ LorenzUtils.sendTitle(name, 5.seconds)
+ LorenzUtils.chat("You found a $name§e!")
+ SoundUtils.playBeepSound()
+ ItemBlink.setBlink(itemStack, 5_000)
}
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/WrongFungiCutterWarning.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/WrongFungiCutterWarning.kt
index e7bdce1db..dc31789a9 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/WrongFungiCutterWarning.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/WrongFungiCutterWarning.kt
@@ -1,11 +1,11 @@
package at.hannibal2.skyhanni.features.garden.farming
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.data.ClickType
import at.hannibal2.skyhanni.events.CropClickEvent
import at.hannibal2.skyhanni.events.GardenToolChangeEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.features.garden.CropType
+import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getFungiCutterMode
@@ -44,7 +44,7 @@ class WrongFungiCutterWarning {
}
private fun notifyWrong() {
- if (!SkyHanniMod.feature.garden.fungiCutterWarn) return
+ if (!GardenAPI.config.fungiCutterWarn) return
LorenzUtils.sendTitle("§cWrong Fungi Cutter Mode!", 2.seconds)
if (System.currentTimeMillis() > lastPlaySoundTime + 3_00) {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CaptureFarmingGear.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CaptureFarmingGear.kt
index 483cce5a5..04fc38a6e 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CaptureFarmingGear.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CaptureFarmingGear.kt
@@ -13,7 +13,7 @@ import at.hannibal2.skyhanni.utils.ItemUtils.getItemRarityOrNull
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimal
-import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded
+import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary
import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getEnchantments
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
@@ -170,7 +170,7 @@ class CaptureFarmingGear {
if (event.inventoryName.contains("Your Skills")) {
for ((_, item) in event.inventoryItems) {
if (item.displayName.contains("Farming ")) {
- storage.farmingLevel = item.displayName.split(" ").last().romanToDecimalIfNeeded()
+ storage.farmingLevel = item.displayName.split(" ").last().romanToDecimalIfNecessary()
}
}
}
@@ -226,7 +226,7 @@ class CaptureFarmingGear {
ProfileStorageData.playerSpecific?.gardenCommunityUpgrade = group("level").romanToDecimal()
}
farmingLevelUpPattern.matchMatcher(msg) {
- storage.farmingLevel = group("level").romanToDecimalIfNeeded()
+ storage.farmingLevel = group("level").romanToDecimalIfNecessary()
}
anitaBuffPattern.matchMatcher(msg) {
storage.anitaUpgrade = group("level").toInt() / 4
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/OverviewPage.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/OverviewPage.kt
index 2fe623c74..670756832 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/OverviewPage.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/OverviewPage.kt
@@ -210,11 +210,19 @@ class OverviewPage : FFGuideGUI.FFGuidePage() {
else -> FFStats.equipmentTotalFF
}
+ val maxEquipmentBaseFortune = 5.0
+ val maxEquipmentAbilityFortune = 15.0
+ val maxEquipmentReforgeFortune = 15.0
+ val maxGreenThumbFortune = GardenAPI.totalAmountVisitorsExisting.toDouble() / 4
+
+ val maxFortunePerPiece = maxEquipmentBaseFortune + maxEquipmentAbilityFortune + maxEquipmentReforgeFortune + maxGreenThumbFortune
+
line = if (currentEquipment == 0) "§7§2Total fortune from all your equipment\n§2Select a piece for more info"
else "§7§2Total fortune from your\n${equipmentItem.getItem().displayName}"
GuiRenderUtils.drawFarmingBar(
"§2Total $word Fortune", line, equipmentFF[FFTypes.TOTAL] ?: 0,
- if (currentEquipment == 0) 218 else 54.5,
+ if (currentEquipment == 0) maxFortunePerPiece * 4 else maxFortunePerPiece,
+
FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 30, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
)
@@ -222,7 +230,7 @@ class OverviewPage : FFGuideGUI.FFGuidePage() {
else "§7§2Total base fortune from your\n${equipmentItem.getItem().displayName}"
GuiRenderUtils.drawFarmingBar(
"§2$word Base Fortune", line, equipmentFF[FFTypes.BASE] ?: 0,
- if (currentEquipment == 0) 20 else 5,
+ if (currentEquipment == 0) maxEquipmentBaseFortune * 4 else maxEquipmentBaseFortune,
FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 55, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
)
@@ -231,7 +239,7 @@ class OverviewPage : FFGuideGUI.FFGuidePage() {
else "§7§2Total ability fortune from your\n${equipmentItem.getItem().displayName}"
GuiRenderUtils.drawFarmingBar(
"§2$word Ability", line, equipmentFF[FFTypes.ABILITY] ?: 0,
- if (currentEquipment == 0) 60 else 15,
+ if (currentEquipment == 0) maxEquipmentAbilityFortune * 4 else maxEquipmentAbilityFortune,
FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 80, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
)
@@ -240,11 +248,10 @@ class OverviewPage : FFGuideGUI.FFGuidePage() {
else "§7§2Total reforge fortune from your\n${equipmentItem.getItem().displayName}"
GuiRenderUtils.drawFarmingBar(
"§2$word Reforge", line, equipmentFF[FFTypes.REFORGE] ?: 0,
- if (currentEquipment == 0) 60 else 15,
+ if (currentEquipment == 0) maxEquipmentReforgeFortune * 4 else maxEquipmentReforgeFortune,
FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 105, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
)
- val maxGreenThumbFortune = GardenAPI.totalAmountVisitorsExisting.toDouble() / 4
line =
if (currentEquipment == 0) "§7§2The fortune from all of your equipment's enchantments\n§2Select a piece for more info"
else "§7§2Total enchantment fortune from your\n${equipmentItem.getItem().displayName}"
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/AnitaExtraFarmingFortune.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/AnitaExtraFarmingFortune.kt
index 2af928a30..683834419 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/AnitaExtraFarmingFortune.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/AnitaExtraFarmingFortune.kt
@@ -1,7 +1,8 @@
package at.hannibal2.skyhanni.features.garden.inventory
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
+import at.hannibal2.skyhanni.data.jsonobjects.repo.AnitaUpgradeCostsJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.AnitaUpgradeCostsJson.Price
import at.hannibal2.skyhanni.events.RepositoryReloadEvent
import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.utils.InventoryUtils
@@ -12,13 +13,11 @@ import at.hannibal2.skyhanni.utils.NumberUtil
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
-import at.hannibal2.skyhanni.utils.jsonobjects.AnitaUpgradeCostsJson
-import at.hannibal2.skyhanni.utils.jsonobjects.AnitaUpgradeCostsJson.Price
import net.minecraftforge.event.entity.player.ItemTooltipEvent
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class AnitaExtraFarmingFortune {
- private val config get() = SkyHanniMod.feature.garden.anitaShop
+ private val config get() = GardenAPI.config.anitaShop
private var levelPrice = mapOf<Int, Price>()
@SubscribeEvent
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenCropMilestoneInventory.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenCropMilestoneInventory.kt
index cb236050b..6a37862a9 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenCropMilestoneInventory.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenCropMilestoneInventory.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden.inventory
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.data.GardenCropMilestones
import at.hannibal2.skyhanni.data.GardenCropMilestones.getCounter
@@ -8,6 +7,7 @@ import at.hannibal2.skyhanni.events.CropMilestoneUpdateEvent
import at.hannibal2.skyhanni.events.InventoryCloseEvent
import at.hannibal2.skyhanni.events.RenderInventoryItemTipEvent
import at.hannibal2.skyhanni.features.garden.CropType
+import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.indexOfFirst
import at.hannibal2.skyhanni.utils.LorenzUtils.round
@@ -19,7 +19,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class GardenCropMilestoneInventory {
private var average = -1.0
- private val config get() = SkyHanniMod.feature.garden
+ private val config get() = GardenAPI.config
@SubscribeEvent
fun onCropMilestoneUpdate(event: CropMilestoneUpdateEvent) {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenDeskInSBMenu.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenDeskInSBMenu.kt
index a3f72ac4c..bc20b44a3 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenDeskInSBMenu.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenDeskInSBMenu.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden.inventory
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.InventoryCloseEvent
import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
import at.hannibal2.skyhanni.features.garden.GardenAPI
@@ -15,7 +14,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class GardenDeskInSBMenu {
- private val config get() = SkyHanniMod.feature.garden
+ private val config get() = GardenAPI.config
private var showItem = false
private val item by lazy {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenInventoryNumbers.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenInventoryNumbers.kt
index fe3d690a3..7ace9f0db 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenInventoryNumbers.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenInventoryNumbers.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden.inventory
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.data.GardenCropMilestones
import at.hannibal2.skyhanni.data.GardenCropMilestones.getCounter
@@ -10,12 +9,12 @@ import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.ItemUtils.name
-import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded
+import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class GardenInventoryNumbers {
- private val config get() = SkyHanniMod.feature.garden.number
+ private val config get() = GardenAPI.config.number
private var patternUpgradeTier = "§7Current Tier: §[ea](?<tier>.*)§7/§a.*".toPattern()
@@ -47,7 +46,7 @@ class GardenInventoryNumbers {
event.stack.name?.let {
ComposterUpgrade.regex.matchMatcher(it) {
- val level = group("level")?.romanToDecimalIfNeeded() ?: 0
+ val level = group("level")?.romanToDecimalIfNecessary() ?: 0
event.stackTip = "$level"
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenNextPlotPrice.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenNextPlotPrice.kt
index 64d176bcd..bd2a3b5a3 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenNextPlotPrice.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenNextPlotPrice.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden.inventory
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils
@@ -16,7 +15,7 @@ class GardenNextPlotPrice {
@SubscribeEvent
fun onTooltip(event: ItemTooltipEvent) {
if (!GardenAPI.inGarden()) return
- if (!SkyHanniMod.feature.garden.plotPrice) return
+ if (!GardenAPI.config.plotPrice) return
if (InventoryUtils.openInventoryName() != "Configure Plots") return
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenPlotIcon.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenPlotIcon.kt
index cdd5d4358..c7ff13dc6 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenPlotIcon.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/GardenPlotIcon.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden.inventory
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.InventoryCloseEvent
import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
import at.hannibal2.skyhanni.events.LorenzToolTipEvent
@@ -20,7 +19,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
object GardenPlotIcon {
- private val config get() = SkyHanniMod.feature.garden.plotIcon
+ private val config get() = GardenAPI.config.plotIcon
private val plotList get() = GardenAPI.storage?.plotIcon?.plotList
private var inInventory = false
private var copyStack: ItemStack? = null
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/SkyMartCopperPrice.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/SkyMartCopperPrice.kt
index a70ca7f96..e2b15c49c 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/SkyMartCopperPrice.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/inventory/SkyMartCopperPrice.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden.inventory
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.InventoryCloseEvent
@@ -21,7 +20,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class SkyMartCopperPrice {
private val pattern = "§c(?<amount>.*) Copper".toPattern()
private var display = emptyList<List<Any>>()
- private val config get() = SkyHanniMod.feature.garden.skyMart
+ private val config get() = GardenAPI.config.skyMart
companion object {
var inInventory = false
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestAPI.kt
new file mode 100644
index 000000000..5609b61b8
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestAPI.kt
@@ -0,0 +1,21 @@
+package at.hannibal2.skyhanni.features.garden.pests
+
+import at.hannibal2.skyhanni.features.garden.GardenAPI
+import at.hannibal2.skyhanni.utils.InventoryUtils
+import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
+
+object PestAPI {
+ val config get() = GardenAPI.config.pests
+
+ val vacuumVariants = listOf(
+ "SKYMART_VACUUM".asInternalName(),
+ "SKYMART_TURBO_VACUUM".asInternalName(),
+ "SKYMART_HYPER_VACUUM".asInternalName(),
+ "INFINI_VACUUM".asInternalName(),
+ "INFINI_VACUUM_HOOVERIUS".asInternalName(),
+ )
+
+ fun hasVacuumInHand() = InventoryUtils.itemInHandId in vacuumVariants
+
+ fun SprayType.getPests() = PestType.entries.filter { it.spray == this }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestFinder.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestFinder.kt
new file mode 100644
index 000000000..dfe34c56c
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestFinder.kt
@@ -0,0 +1,226 @@
+package at.hannibal2.skyhanni.features.garden.pests
+
+import at.hannibal2.skyhanni.events.GuiRenderEvent
+import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
+import at.hannibal2.skyhanni.events.IslandChangeEvent
+import at.hannibal2.skyhanni.events.LorenzChatEvent
+import at.hannibal2.skyhanni.events.LorenzKeyPressEvent
+import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
+import at.hannibal2.skyhanni.events.ScoreboardChangeEvent
+import at.hannibal2.skyhanni.events.garden.pests.PestSpawnEvent
+import at.hannibal2.skyhanni.features.garden.GardenAPI
+import at.hannibal2.skyhanni.features.garden.GardenPlotAPI
+import at.hannibal2.skyhanni.features.garden.GardenPlotAPI.isPlayerInside
+import at.hannibal2.skyhanni.features.garden.GardenPlotAPI.name
+import at.hannibal2.skyhanni.features.garden.GardenPlotAPI.pests
+import at.hannibal2.skyhanni.features.garden.GardenPlotAPI.renderPlot
+import at.hannibal2.skyhanni.features.garden.GardenPlotAPI.sendTeleportTo
+import at.hannibal2.skyhanni.test.GriffinUtils.drawWaypointFilled
+import at.hannibal2.skyhanni.utils.ItemUtils.getLore
+import at.hannibal2.skyhanni.utils.LocationUtils.distanceSqToPlayer
+import at.hannibal2.skyhanni.utils.LorenzColor
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.NEUItems
+import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber
+import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText
+import at.hannibal2.skyhanni.utils.RenderUtils.exactPlayerEyeLocation
+import at.hannibal2.skyhanni.utils.RenderUtils.renderRenderables
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
+import at.hannibal2.skyhanni.utils.StringUtils
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
+import at.hannibal2.skyhanni.utils.renderables.Renderable
+import net.minecraft.client.Minecraft
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import kotlin.time.Duration.Companion.seconds
+
+class PestFinder {
+
+ private val config get() = PestAPI.config.pestFinder
+
+ private val pestsInScoreboardPattern = " §7⏣ §[ac]The Garden §4§lൠ§7 x(?<pests>.*)".toPattern()
+
+ private var display = emptyList<Renderable>()
+ private var scoreboardPests = 0
+
+ @SubscribeEvent
+ fun onPestSpawn(event: PestSpawnEvent) {
+ if (!isEnabled()) return
+ PestSpawnTimer.lastSpawnTime = SimpleTimeMark.now()
+ val plot = GardenPlotAPI.getPlotByName(event.plotName)
+ if (plot == null) {
+ LorenzUtils.userError("Open Desk to load plot names and pest locations!")
+ return
+ }
+ plot.pests += event.amountPests
+ update()
+ }
+
+ @SubscribeEvent
+ fun onInventoryOpen(event: InventoryFullyOpenedEvent) {
+ if (!isEnabled()) return
+ if (event.inventoryName != "Configure Plots") return
+
+ val pestInventoryPattern = "§4§lൠ §cThis plot has §6(?<amount>\\d) Pests?§c!".toPattern()
+
+ for (plot in GardenPlotAPI.plots) {
+ plot.pests = 0
+ val item = event.inventoryItems[plot.inventorySlot] ?: continue
+ for (line in item.getLore()) {
+ pestInventoryPattern.matchMatcher(line) {
+ plot.pests = group("amount").formatNumber().toInt()
+ }
+ }
+ }
+ update()
+
+ }
+
+ private fun update() {
+ display = drawDisplay()
+ }
+
+ private fun drawDisplay() = buildList {
+ val totalAmount = getPlotsWithPests().sumOf { it.pests }
+ if (totalAmount != scoreboardPests) {
+ add(Renderable.string("§cIncorrect pest amount!"))
+ add(Renderable.string("§eOpen Configure Plots Menu!"))
+ return@buildList
+ }
+
+ add(Renderable.string("§eTotal pests in garden: §c${totalAmount}§7/§c8"))
+
+ for (plot in getPlotsWithPests()) {
+ val pests = plot.pests
+ val plotName = plot.name
+ val pestsName = StringUtils.optionalPlural(pests, "pest", "pests")
+ val renderable = Renderable.clickAndHover(
+ "§c$pestsName §7in §b$plotName",
+ listOf(
+ "§7Pests Found: §e$pests",
+ "§7In plot §b$plotName",
+ "",
+ "§eClick here to warp!"
+ ),
+ onClick = {
+ plot.sendTeleportTo()
+ }
+ )
+ add(renderable)
+ }
+ }
+
+ @SubscribeEvent
+ fun onIslandChange(event: IslandChangeEvent) {
+ update()
+ }
+
+ @SubscribeEvent
+ fun onChat(event: LorenzChatEvent) {
+ if (!isEnabled()) return
+ if (event.message == "§cThere are no pests in your Garden right now! Keep farming!") {
+ GardenPlotAPI.plots.forEach {
+ it.pests = 0
+ }
+ update()
+ }
+ }
+
+ @SubscribeEvent
+ fun onScoreboardChange(event: ScoreboardChangeEvent) {
+ if (!isEnabled()) return
+
+ var newPests = 0
+ for (line in event.newList) {
+ pestsInScoreboardPattern.matchMatcher(line) {
+ newPests = group("pests").formatNumber().toInt()
+ }
+ }
+
+ if (newPests == scoreboardPests) return
+
+ removePests(scoreboardPests - newPests)
+ scoreboardPests = newPests
+ update()
+ }
+
+ private fun removePests(removedPests: Int) {
+ if (removedPests < 1) return
+ repeat(removedPests) {
+ removeNearestPest()
+ }
+ }
+
+ private fun getNearestInfectedPest() = getPlotsWithPests().minByOrNull { it.middle.distanceSqToPlayer() }
+
+ private fun removeNearestPest() {
+ val plot = getNearestInfectedPest() ?: run {
+ LorenzUtils.error("Can not remove nearest pest: No infected plots detected.")
+ return
+ }
+ plot.pests--
+ }
+
+ @SubscribeEvent
+ fun onRenderOverlay(event: GuiRenderEvent) {
+ if (!isEnabled()) return
+ if (!config.showDisplay) return
+ if (config.onlyWithVacuum && !PestAPI.hasVacuumInHand()) return
+
+ if (GardenAPI.inGarden() && config.showDisplay) {
+ config.position.renderRenderables(display, posLabel = "Pest Finder")
+ }
+ }
+
+ private fun getPlotsWithPests() = GardenPlotAPI.plots.filter { it.pests > 0 }
+
+ @SubscribeEvent
+ fun onRenderWorld(event: LorenzRenderWorldEvent) {
+ if (!isEnabled()) return
+ if (!config.showPlotInWorld) return
+ if (config.onlyWithVacuum && !PestAPI.hasVacuumInHand()) return
+
+ val playerLocation = event.exactPlayerEyeLocation()
+ for (plot in getPlotsWithPests()) {
+ if (plot.isPlayerInside()) {
+ event.renderPlot(plot, LorenzColor.RED.toColor(), LorenzColor.DARK_RED.toColor())
+ continue
+ }
+ event.renderPlot(plot, LorenzColor.GOLD.toColor(), LorenzColor.RED.toColor())
+
+ val pestsName = StringUtils.optionalPlural(plot.pests, "pest", "pests")
+ val plotName = plot.name
+ val middle = plot.middle
+ val location = playerLocation.copy(x = middle.x, z = middle.z)
+ event.drawWaypointFilled(location, LorenzColor.RED.toColor())
+ event.drawDynamicText(location, "§c$pestsName §7in §b$plotName", 1.5)
+
+ }
+ }
+
+ private var lastKeyPress = SimpleTimeMark.farPast()
+
+ @SubscribeEvent
+ fun onKeyClick(event: LorenzKeyPressEvent) {
+ if (!GardenAPI.inGarden()) return
+ if (Minecraft.getMinecraft().currentScreen != null) return
+ if (NEUItems.neuHasFocus()) return
+
+ if (event.keyCode != config.teleportHotkey) return
+ if (lastKeyPress.passedSince() < 2.seconds) return
+ lastKeyPress = SimpleTimeMark.now()
+
+ val plot = getNearestInfectedPest() ?: run {
+ LorenzUtils.userError("No infected plots detected to warp to!")
+ return
+ }
+
+ if (plot.isPlayerInside()) {
+ LorenzUtils.userError("You stand already on the infected plot!")
+ return
+ }
+
+ plot.sendTeleportTo()
+ }
+
+ fun isEnabled() = GardenAPI.inGarden() && (config.showDisplay || config.showPlotInWorld)
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestSpawn.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestSpawn.kt
new file mode 100644
index 000000000..934a73ef2
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestSpawn.kt
@@ -0,0 +1,57 @@
+package at.hannibal2.skyhanni.features.garden.pests
+
+import at.hannibal2.skyhanni.events.LorenzChatEvent
+import at.hannibal2.skyhanni.events.garden.pests.PestSpawnEvent
+import at.hannibal2.skyhanni.features.garden.GardenAPI
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import kotlin.time.Duration.Companion.seconds
+
+class PestSpawn {
+ private val config get() = PestAPI.config.pestSpawn
+
+ private val patternOnePest = "§6§l.*! §7A §6Pest §7has appeared in §aPlot §7- §b(?<plot>.*)§7!".toPattern()
+ private val patternMultiplePests =
+ "§6§l.*! §6(?<amount>\\d) Pests §7have spawned in §aPlot §7- §b(?<plot>.*)§7!".toPattern()
+
+ @SubscribeEvent
+ fun onChat(event: LorenzChatEvent) {
+ if (!GardenAPI.inGarden()) return
+
+ var blocked = false
+
+ patternOnePest.matchMatcher(event.message) {
+ pestSpawn(1, group("plot"))
+ blocked = true
+ }
+ patternMultiplePests.matchMatcher(event.message) {
+ pestSpawn(group("amount").toInt(), group("plot"))
+ blocked = true
+ }
+ if (event.message == " §r§e§lCLICK HERE §eto teleport to the plot!") {
+ if (PestSpawnTimer.lastSpawnTime.passedSince() < 1.seconds) {
+ blocked = true
+ }
+ }
+
+ if (blocked && config.chatMessageFormat != 0) {
+ event.blockedReason = "pests_spawn"
+ }
+ }
+
+ private fun pestSpawn(amount: Int, plotName: String) {
+ PestSpawnEvent(amount, plotName).postAndCatch()
+
+ if (config.showTitle) {
+ LorenzUtils.sendTitle("§aPest Spawn! §e$amount §ain §b$plotName§a!", 7.seconds)
+ }
+
+ if (config.chatMessageFormat == 1) {
+ LorenzUtils.clickableChat(
+ "§aPest Spawn! §e$amount §ain §b$plotName§a!",
+ "tptoplot $plotName"
+ )
+ }
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestSpawnTimer.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestSpawnTimer.kt
new file mode 100644
index 000000000..726032591
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestSpawnTimer.kt
@@ -0,0 +1,37 @@
+package at.hannibal2.skyhanni.features.garden.pests
+
+import at.hannibal2.skyhanni.events.GuiRenderEvent
+import at.hannibal2.skyhanni.events.garden.pests.PestSpawnEvent
+import at.hannibal2.skyhanni.features.garden.GardenAPI
+import at.hannibal2.skyhanni.utils.RenderUtils.renderString
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
+import at.hannibal2.skyhanni.utils.TimeUtils.format
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+object PestSpawnTimer {
+ private val config get() = PestAPI.config.pestTimer
+
+ var lastSpawnTime = SimpleTimeMark.farPast()
+
+ @SubscribeEvent
+ fun onPestSpawn(event: PestSpawnEvent) {
+ lastSpawnTime = SimpleTimeMark.now()
+ }
+
+ @SubscribeEvent
+ fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
+ if (!isEnabled()) return
+ if (config.onlyWithVacuum && !PestAPI.hasVacuumInHand()) return
+
+ val display = if (lastSpawnTime.isFarPast()) {
+ "§cNo pest spawned since joining."
+ } else {
+ val timeSinceLastPest = lastSpawnTime.passedSince().format()
+ "§eLast pest spawned §b$timeSinceLastPest ago"
+ }
+
+ config.position.renderString(display, posLabel = "Pest Spawn Timer")
+ }
+
+ fun isEnabled() = GardenAPI.inGarden() && config.enabled
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestType.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestType.kt
new file mode 100644
index 000000000..946a37c4a
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/PestType.kt
@@ -0,0 +1,16 @@
+package at.hannibal2.skyhanni.features.garden.pests
+
+import at.hannibal2.skyhanni.features.combat.damageindicator.BossType
+
+enum class PestType(val displayName: String, val damageIndicatorBoss: BossType, val spray: SprayType) {
+ BEETLE("Beetle", BossType.GARDEN_PEST_BEETLE, SprayType.DUNG),
+ CRICKET("Cricket", BossType.GARDEN_PEST_CRICKET, SprayType.HONEY_JAR),
+ EARTHWORM("Earthworm", BossType.GARDEN_PEST_EARTHWORM, SprayType.COMPOST),
+ FLY("Fly", BossType.GARDEN_PEST_FLY, SprayType.DUNG),
+ LOCUST("Locust", BossType.GARDEN_PEST_LOCUST, SprayType.PLANT_MATTER),
+ MITE("Mite", BossType.GARDEN_PEST_MITE, SprayType.TASTY_CHEESE),
+ MOSQUITO("Mosquito", BossType.GARDEN_PEST_MOSQUITO, SprayType.COMPOST),
+ MOTH("Moth", BossType.GARDEN_PEST_MOTH, SprayType.HONEY_JAR),
+ RAT("Rat", BossType.GARDEN_PEST_RAT, SprayType.TASTY_CHEESE),
+ SLUG("Slug", BossType.GARDEN_PEST_SLUG, SprayType.PLANT_MATTER),
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/pests/SprayFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/SprayFeatures.kt
new file mode 100644
index 000000000..04501d1f4
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/SprayFeatures.kt
@@ -0,0 +1,76 @@
+package at.hannibal2.skyhanni.features.garden.pests
+
+import at.hannibal2.skyhanni.events.GuiRenderEvent
+import at.hannibal2.skyhanni.events.LorenzChatEvent
+import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
+import at.hannibal2.skyhanni.features.garden.GardenPlotAPI
+import at.hannibal2.skyhanni.features.garden.GardenPlotAPI.renderPlot
+import at.hannibal2.skyhanni.features.garden.pests.PestAPI.getPests
+import at.hannibal2.skyhanni.test.command.ErrorManager
+import at.hannibal2.skyhanni.utils.InventoryUtils
+import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
+import at.hannibal2.skyhanni.utils.LorenzColor
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
+import at.hannibal2.skyhanni.utils.RenderUtils.renderString
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import kotlin.time.Duration.Companion.seconds
+
+class SprayFeatures {
+ private val config get() = PestAPI.config.spray
+
+ private var display: String? = null
+ private var lastChangeTime = SimpleTimeMark.farPast()
+
+ // TODO repo
+ private val pattern = "§a§lSPRAYONATOR! §r§7Your selected material is now §r§a(?<spray>.*)§r§7!".toPattern()
+
+ @SubscribeEvent
+ fun onChat(event: LorenzChatEvent) {
+ if (!config.pestWhenSelector) return
+
+ val type = pattern.matchMatcher(event.message) {
+ val sprayName = group("spray")
+ SprayType.getByName(sprayName) ?: run {
+ ErrorManager.logErrorStateWithData(
+ "Error reading spray material", "SprayType is null",
+ "sprayName" to sprayName,
+ "event.message" to event.message,
+ )
+ return
+ }
+ } ?: return
+
+ val pests = type.getPests().joinToString("§7, §6") { it.displayName }
+ display = "§a${type.displayName} §7(§6$pests§7)"
+
+ lastChangeTime = SimpleTimeMark.now()
+
+ }
+
+ @SubscribeEvent
+ fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
+ if (!isEnabled()) return
+
+ val display = display ?: return
+
+ if (lastChangeTime.passedSince() > 5.seconds) {
+ this.display = null
+ return
+ }
+
+ config.position.renderString(display, posLabel = "Pest Spray Selector")
+ }
+
+ @SubscribeEvent
+ fun onWorldRender(event: LorenzRenderWorldEvent) {
+ if (!config.drawPlotsBorderWhenInHands) return
+ if (!InventoryUtils.itemInHandId.equals("SPRAYONATOR")) return
+ val plot = GardenPlotAPI.getCurrentPlot() ?: return
+ event.renderPlot(plot, LorenzColor.YELLOW.toColor(), LorenzColor.DARK_BLUE.toColor())
+ }
+
+ fun isEnabled() = LorenzUtils.inSkyBlock && config.pestWhenSelector
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/pests/SprayType.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/SprayType.kt
new file mode 100644
index 000000000..eec073cf3
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/pests/SprayType.kt
@@ -0,0 +1,14 @@
+package at.hannibal2.skyhanni.features.garden.pests
+
+enum class SprayType(val displayName: String) {
+ COMPOST("Compost"),
+ PLANT_MATTER("Plant Matter"),
+ DUNG("Dung"),
+ HONEY_JAR("Honey Jar"),
+ TASTY_CHEESE("Tasty Cheese"),
+ ;
+
+ companion object {
+ fun getByName(name: String) = entries.firstOrNull {it.displayName == name}
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorColorNames.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorColorNames.kt
index 9fa465a47..c35b2d78a 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorColorNames.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorColorNames.kt
@@ -1,9 +1,9 @@
package at.hannibal2.skyhanni.features.garden.visitor
-import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.jsonobjects.repo.GardenJson
import at.hannibal2.skyhanni.events.RepositoryReloadEvent
+import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
-import at.hannibal2.skyhanni.utils.jsonobjects.GardenJson
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
object GardenVisitorColorNames {
@@ -23,7 +23,7 @@ object GardenVisitorColorNames {
}
fun getColoredName(name: String): String {
- if (!SkyHanniMod.feature.garden.visitors.coloredName) return name
+ if (!GardenAPI.config.visitors.coloredName) return name
val cleanName = name.removeColor()
val color = visitorColours[cleanName] ?: return name
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorDropStatistics.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorDropStatistics.kt
index 6ddabd2f5..59db979be 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorDropStatistics.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorDropStatistics.kt
@@ -1,8 +1,8 @@
package at.hannibal2.skyhanni.features.garden.visitor
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.config.Storage
+import at.hannibal2.skyhanni.config.features.garden.visitor.DropsStatisticsConfig.DropsStatisticsTextEntry
import at.hannibal2.skyhanni.data.ProfileStorageData
import at.hannibal2.skyhanni.events.ConfigLoadEvent
import at.hannibal2.skyhanni.events.GuiRenderEvent
@@ -11,6 +11,7 @@ import at.hannibal2.skyhanni.events.PreProfileSwitchEvent
import at.hannibal2.skyhanni.events.garden.visitor.VisitorAcceptEvent
import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.test.command.ErrorManager
+import at.hannibal2.skyhanni.utils.ConfigUtils
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
import at.hannibal2.skyhanni.utils.LorenzUtils.addOrPut
@@ -24,7 +25,7 @@ import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
object GardenVisitorDropStatistics {
- private val config get() = SkyHanniMod.feature.garden.visitors.dropsStatistics
+ private val config get() = GardenAPI.config.visitors.dropsStatistics
private var display = emptyList<List<Any>>()
private var acceptedVisitors = 0
@@ -46,7 +47,8 @@ object GardenVisitorDropStatistics {
private fun formatDisplay(map: List<List<Any>>): List<List<Any>> {
val newList = mutableListOf<List<Any>>()
for (index in config.textFormat) {
- newList.add(map[index])
+ // We need to use the ordinal here, can't change this.
+ newList.add(map[index.ordinal])
}
return newList
}
@@ -119,17 +121,18 @@ object GardenVisitorDropStatistics {
val currentRarity = LorenzUtils.enumValueOf<VisitorRarity>(rarity)
val visitorRarities = GardenAPI.storage?.visitorDrops?.visitorRarities ?: return
fixRaritiesSize(visitorRarities)
+ // TODO, change functionality to use enum rather than ordinals
val temp = visitorRarities[currentRarity.ordinal] + 1
visitorRarities[currentRarity.ordinal] = temp
saveAndUpdate()
}
+ /**
+ * Do not change the order of the elements getting added to the list. See DropsStatisticsTextEntry for the order.
+ */
private fun drawDisplay(storage: Storage.ProfileSpecific.GardenStorage.VisitorDrops) = buildList<List<Any>> {
- //0
addAsSingletonList("§e§lVisitor Statistics")
- //1
addAsSingletonList(format(totalVisitors, "Total", "§e", ""))
- //2
val visitorRarities = storage.visitorRarities
fixRaritiesSize(visitorRarities)
if (visitorRarities.isNotEmpty()) {
@@ -147,20 +150,19 @@ object GardenVisitorDropStatistics {
"Error rendering visitor drop statistics"
)
}
- //3
addAsSingletonList(format(acceptedVisitors, "Accepted", "§2", ""))
- //4
addAsSingletonList(format(deniedVisitors, "Denied", "§c", ""))
- //5
addAsSingletonList("")
- //6
addAsSingletonList(format(storage.copper, "Copper", "§c", ""))
- //7
addAsSingletonList(format(storage.farmingExp, "Farming EXP", "§3", "§7"))
- //8
addAsSingletonList(format(coinsSpent, "Coins Spent", "§6", ""))
- //9 – 16
+ addAsSingletonList("")
+ addAsSingletonList(format(storage.gardenExp, "Garden EXP", "§2", "§7"))
+ addAsSingletonList(format(storage.bits, "Bits", "§b", "§b"))
+ addAsSingletonList(format(storage.mithrilPowder, "Mithril Powder", "§2", "§2"))
+ addAsSingletonList(format(storage.gemstonePowder, "Gemstone Powder", "§d", "§d"))
+
for (reward in VisitorReward.entries) {
val count = rewardsCount[reward] ?: 0
if (config.displayIcons) {// Icons
@@ -172,16 +174,6 @@ object GardenVisitorDropStatistics {
addAsSingletonList(format(count, reward.displayName, "§b"))
}
}
- //17
- addAsSingletonList("")
- //18
- addAsSingletonList(format(storage.gardenExp, "Garden EXP", "§2", "§7"))
- //19
- addAsSingletonList(format(storage.bits, "Bits", "§b", "§b"))
- //20
- addAsSingletonList(format(storage.mithrilPowder, "Mithril Powder", "§2", "§2"))
- //21
- addAsSingletonList(format(storage.gemstonePowder, "Gemstone Powder", "§d", "§d"))
}
// Adding the mythic rarity between legendary and special, if missing
@@ -254,6 +246,10 @@ object GardenVisitorDropStatistics {
event.move(3, "${originalPrefix}displayIcons", "${newPrefix}displayIcons")
event.move(3, "${originalPrefix}onlyOnBarn", "${newPrefix}onlyOnBarn")
event.move(3, "${originalPrefix}visitorDropPos", "${newPrefix}pos")
+
+ event.move(11, "${newPrefix}textFormat", "${newPrefix}textFormat") { element ->
+ ConfigUtils.migrateIntArrayListToEnumArrayList(element, DropsStatisticsTextEntry::class.java)
+ }
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorFeatures.kt
index 4995decc8..22a53c388 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorFeatures.kt
@@ -20,6 +20,7 @@ import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed.getSpeed
import at.hannibal2.skyhanni.mixins.hooks.RenderLivingEntityHelper
import at.hannibal2.skyhanni.test.command.ErrorManager
+import at.hannibal2.skyhanni.utils.ConfigUtils
import at.hannibal2.skyhanni.utils.EntityUtils
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemBlink
@@ -46,7 +47,8 @@ import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import at.hannibal2.skyhanni.utils.TimeUtils
import at.hannibal2.skyhanni.utils.getLorenzVec
import at.hannibal2.skyhanni.utils.renderables.Renderable
-import io.github.moulberry.notenoughupdates.util.MinecraftExecutor
+import com.google.gson.JsonArray
+import com.google.gson.JsonPrimitive
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.inventory.GuiEditSign
import net.minecraft.entity.EntityLivingBase
@@ -232,9 +234,7 @@ class GardenVisitorFeatures {
@SubscribeEvent
fun onOwnInventoryItemUpdate(event: OwnInventoryItemUpdateEvent) {
if (GardenAPI.onBarnPlot) {
- MinecraftExecutor.OnThread.execute {
- update()
- }
+ update()
}
}
@@ -258,12 +258,12 @@ class GardenVisitorFeatures {
val visitor = event.visitor
val text = visitor.status.displayName
val location = event.location
- event.parent.drawString(location.add(0.0, 2.23, 0.0), text)
+ event.parent.drawString(location.add(y = 2.23), text)
if (config.rewardWarning.showOverName) {
visitor.hasReward()?.let { reward ->
val name = reward.displayName
- event.parent.drawString(location.add(0.0, 2.73, 0.0), "§c!$name§c!")
+ event.parent.drawString(location.add(y = 2.73), "§c!$name§c!")
}
}
}
@@ -436,6 +436,7 @@ class GardenVisitorFeatures {
private fun hideVisitorMessage(message: String) = visitorChatMessagePattern.matchMatcher(message) {
val name = group("name")
+ if (name == "Jacob") return false
if (name == "Spaceman") return false
if (name == "Beth") return false
@@ -606,6 +607,23 @@ class GardenVisitorFeatures {
event.move(3, "garden.visitorColoredName", "garden.visitors.coloredName")
event.move(3, "garden.visitorHypixelArrivedMessage", "garden.visitors.hypixelArrivedMessage")
event.move(3, "garden.visitorHideChat", "garden.visitors.hideChat")
+ event.move(11, "garden.visitors.rewardWarning.drops", "garden.visitors.rewardWarning.drops") { element ->
+ ConfigUtils.migrateIntArrayListToEnumArrayList(element, VisitorReward::class.java)
+ }
+ event.move(12, "garden.visitors.rewardWarning.drops", "garden.visitors.rewardWarning.drops") { element ->
+ val drops = JsonArray()
+ for (jsonElement in element.asJsonArray) {
+ val old = jsonElement.asString
+ val new = VisitorReward.entries.firstOrNull { old.startsWith(it.name) }
+ if (new == null) {
+ println("error with migrating old VisitorReward entity: '$old'")
+ continue
+ }
+ drops.add(JsonPrimitive(new.name))
+ }
+
+ drops
+ }
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorTimer.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorTimer.kt
index 1bd9290e2..f7bed5ef6 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorTimer.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorTimer.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.features.garden.visitor
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.CropClickEvent
import at.hannibal2.skyhanni.events.GuiRenderEvent
@@ -23,14 +22,15 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.concurrent.fixedRateTimer
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
+import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds
import kotlin.time.DurationUnit
import kotlin.time.toDuration
class GardenVisitorTimer {
- private val config get() = SkyHanniMod.feature.garden.visitors.timer
+ private val config get() = GardenAPI.config.visitors.timer
private val pattern = "§b§lVisitors: §r§f\\((?<time>.*)\\)".toPattern()
- private var render = ""
+ private var display = ""
private var lastMillis = 0.seconds
private var sixthVisitorArrivalTime = SimpleTimeMark.farPast()
private var visitorJustArrived = false
@@ -73,7 +73,7 @@ class GardenVisitorTimer {
@SubscribeEvent
fun onPreProfileSwitch(event: PreProfileSwitchEvent) {
- render = ""
+ display = ""
lastMillis = 0.seconds
sixthVisitorArrivalTime = SimpleTimeMark.farPast()
visitorJustArrived = false
@@ -93,7 +93,7 @@ class GardenVisitorTimer {
continue
}
if (line == "§b§lVisitors: §r§f(§r§cNot Unlocked!§r§f)") {
- render = ""
+ display = ""
return
}
@@ -173,14 +173,14 @@ class GardenVisitorTimer {
"Next in §$formatColor$formatDuration$extraSpeed"
}
val visitorLabel = if (visitorsAmount == 1) "visitor" else "visitors"
- render = "§b$visitorsAmount $visitorLabel §7($next§7)"
+ display = "§b$visitorsAmount $visitorLabel §7($next§7)"
}
@SubscribeEvent
fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
if (!isEnabled()) return
- config.pos.renderString(render, posLabel = "Garden Visitor Timer")
+ config.pos.renderString(display, posLabel = "Garden Visitor Timer")
}
@SubscribeEvent
@@ -200,7 +200,11 @@ class GardenVisitorTimer {
fun onBlockBreak(event: CropClickEvent) {
if (!isEnabled()) return
sixthVisitorArrivalTime -= 100.milliseconds
- lastTimerUpdate -= 100.milliseconds
+
+ // We only need manually retracting the time when hypixel shows 6 minutes or above
+ if (lastMillis > 5.minutes) {
+ lastTimerUpdate -= 100.milliseconds
+ }
}
private fun updateSixthVisitorArrivalTime() {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/HighlightVisitorsOutsideOfGarden.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/HighlightVisitorsOutsideOfGarden.kt
index a4d370e62..bd0fe5704 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/HighlightVisitorsOutsideOfGarden.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/HighlightVisitorsOutsideOfGarden.kt
@@ -1,11 +1,12 @@
package at.hannibal2.skyhanni.features.garden.visitor
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.features.garden.visitor.VisitorConfig.VisitorBlockBehaviour
+import at.hannibal2.skyhanni.data.jsonobjects.repo.GardenJson
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.PacketEvent
import at.hannibal2.skyhanni.events.RepositoryReloadEvent
import at.hannibal2.skyhanni.events.withAlpha
+import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.mixins.hooks.RenderLivingEntityHelper
import at.hannibal2.skyhanni.utils.EntityUtils
import at.hannibal2.skyhanni.utils.EntityUtils.getSkinTexture
@@ -13,7 +14,6 @@ import at.hannibal2.skyhanni.utils.LorenzColor
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzVec
import at.hannibal2.skyhanni.utils.getLorenzVec
-import at.hannibal2.skyhanni.utils.jsonobjects.GardenJson
import at.hannibal2.skyhanni.utils.toLorenzVec
import io.github.moulberry.notenoughupdates.util.SBInfo
import net.minecraft.client.Minecraft
@@ -27,7 +27,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class HighlightVisitorsOutsideOfGarden {
private var visitorJson = mapOf<String?, List<GardenJson.GardenVisitor>>()
- private val config get() = SkyHanniMod.feature.garden.visitors
+ private val config get() = GardenAPI.config.visitors
@SubscribeEvent
fun onRepoReload(event: RepositoryReloadEvent) {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorAPI.kt
index f71ab6883..a74793fbe 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorAPI.kt
@@ -1,11 +1,11 @@
package at.hannibal2.skyhanni.features.garden.visitor
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.garden.visitor.VisitorAcceptedEvent
import at.hannibal2.skyhanni.events.garden.visitor.VisitorArrivalEvent
import at.hannibal2.skyhanni.events.garden.visitor.VisitorLeftEvent
import at.hannibal2.skyhanni.events.garden.visitor.VisitorRefusedEvent
import at.hannibal2.skyhanni.events.withAlpha
+import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.test.command.ErrorManager
import at.hannibal2.skyhanni.utils.EntityUtils
import at.hannibal2.skyhanni.utils.LorenzColor
@@ -18,7 +18,7 @@ import net.minecraft.item.ItemStack
object VisitorAPI {
private var visitors = mapOf<String, Visitor>()
var inInventory = false
- val config get() = SkyHanniMod.feature.garden.visitors
+ val config get() = GardenAPI.config.visitors
private val logger = LorenzLogger("garden/visitors/api")
fun getVisitorsMap() = visitors
@@ -121,8 +121,7 @@ object VisitorAPI {
fun hasReward(): VisitorReward? {
for (internalName in allRewards) {
val reward = VisitorReward.getByInternalName(internalName) ?: continue
-
- if (config.rewardWarning.drops.contains(reward.ordinal)) {
+ if (reward in config.rewardWarning.drops) {
return reward
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorReward.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorReward.kt
index d6aabd3b5..3f5f5eb17 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorReward.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorReward.kt
@@ -1,26 +1,36 @@
package at.hannibal2.skyhanni.features.garden.visitor
-import at.hannibal2.skyhanni.utils.ItemUtils.nameWithEnchantment
+import at.hannibal2.skyhanni.config.HasLegacyId
import at.hannibal2.skyhanni.utils.NEUInternalName
import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
import at.hannibal2.skyhanni.utils.NEUItems.getItemStack
-enum class VisitorReward(private val rawInternalName: String) {
- FLOWERING_BOUQUET("FLOWERING_BOUQUET"),
- OVERGROWN_GRASS("OVERGROWN_GRASS"),
- GREEN_BANDANA("GREEN_BANDANA"),
- DEDICATION("DEDICATION;4"),
- MUSIC_RUNE("MUSIC_RUNE;1"),
- SPACE_HELMET("DCTR_SPACE_HELM"),
- CULTIVATING("CULTIVATING;1"),
- REPLENISH("REPLENISH;1"),
+enum class VisitorReward(private val rawInternalName: String, val displayName: String, private val legacyId: Int = -1) : HasLegacyId {
+ FLOWERING_BOUQUET("FLOWERING_BOUQUET", "§9Flowering Bouquet", legacyId = 0),
+ OVERGROWN_GRASS("OVERGROWN_GRASS", "§9Overgrown Grass", legacyId = 1),
+ GREEN_BANDANA("GREEN_BANDANA", "§9Green Bandana", legacyId = 2),
+ DEDICATION("DEDICATION;4", "§9Dedication IV", legacyId = 3),
+ MUSIC_RUNE("MUSIC_RUNE;1", "§9Music Rune", legacyId = 4),
+ SPACE_HELMET("DCTR_SPACE_HELM", "§cSpace Helmet", legacyId = 5),
+ CULTIVATING("CULTIVATING;1", "§9Cultivating I", legacyId = 6),
+ REPLENISH("REPLENISH;1", "§9Replenish I", legacyId = 7),
+ DELICATE("DELICATE;5", "§9Delicate V"),
;
private val internalName by lazy { rawInternalName.asInternalName() }
val itemStack by lazy { internalName.getItemStack() }
- val displayName by lazy { itemStack.nameWithEnchantment ?: internalName.asString() }
+ // TODO use this instead of hard coded item names once moulconfig no longer calls toString before the neu repo gets loaded
+// val displayName by lazy { itemStack.nameWithEnchantment ?: internalName.asString() }
companion object {
fun getByInternalName(internalName: NEUInternalName) = entries.firstOrNull { it.internalName == internalName }
}
+
+ override fun getLegacyId(): Int {
+ return legacyId
+ }
+
+ override fun toString(): String {
+ return displayName
+ }
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/ChestValue.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/ChestValue.kt
index 42b22741b..f8817b43b 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/inventory/ChestValue.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/ChestValue.kt
@@ -45,7 +45,7 @@ class ChestValue {
if (InventoryUtils.openInventoryName() == "") return
if (!config.showDuringEstimatedItemValue) {
- if (EstimatedItemValue.currentlyShowing) return
+ if (EstimatedItemValue.isCurrentlyShowing()) return
}
if (inInventory) {
@@ -126,11 +126,11 @@ class ChestValue {
val textAmount = " §7x$amount:"
val width = Minecraft.getMinecraft().fontRendererObj.getStringWidth(textAmount)
val name = "${stack.displayName.reduceStringLength((config.nameLength - width), ' ')} $textAmount"
- val price = "§b${(total).formatPrice()}"
+ val price = "§6${(total).formatPrice()}"
val text = if (config.alignedDisplay)
"$name $price"
else
- "${stack.displayName} §7x$amount: §b${total.formatPrice()}"
+ "${stack.displayName} §7x$amount: §6${total.formatPrice()}"
newDisplay.add(buildList {
val renderable = Renderable.hoverTips(
text,
@@ -144,7 +144,7 @@ class ChestValue {
})
rendered++
}
- newDisplay.addAsSingletonList("§6Total value : §b${totalPrice.formatPrice()}")
+ newDisplay.addAsSingletonList("§aTotal value: §6${totalPrice.formatPrice()} coins")
}
private fun sortedList() = when (config.sortingType) {
@@ -197,7 +197,7 @@ class ChestValue {
val key = "$internalName+$total"
if (stack.item == Items.enchanted_book)
total /= 2
- list.add("§aTotal: §6§l${total.formatPrice()}")
+ list.add("§aTotal: §6§l${total.formatPrice()} coins")
if (total == 0.0) continue
val item = chestItems.getOrPut(key) {
Item(mutableListOf(), 0, stack, 0.0, list)
diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/HideNotClickableItems.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/HideNotClickableItems.kt
index a8880aefd..d0c6d91f8 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/inventory/HideNotClickableItems.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/HideNotClickableItems.kt
@@ -27,9 +27,9 @@ import at.hannibal2.skyhanni.utils.MultiFilter
import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.isRiftExportable
import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.isRiftTransferable
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
-import at.hannibal2.skyhanni.utils.jsonobjects.HideNotClickableItemsJson
-import at.hannibal2.skyhanni.utils.jsonobjects.HideNotClickableItemsJson.SalvageFilter
-import at.hannibal2.skyhanni.utils.jsonobjects.MultiFilterJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.HideNotClickableItemsJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.HideNotClickableItemsJson.SalvageFilter
+import at.hannibal2.skyhanni.data.jsonobjects.repo.MultiFilterJson
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.inventory.GuiChest
import net.minecraft.inventory.ContainerChest
diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemDisplayOverlayFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemDisplayOverlayFeatures.kt
index aa3a46ed2..db4443677 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemDisplayOverlayFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemDisplayOverlayFeatures.kt
@@ -2,24 +2,60 @@ package at.hannibal2.skyhanni.features.inventory
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.api.CollectionAPI
+import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
+import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry
+import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.BINGO_GOAL_RANK
+import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.BOTTLE_OF_JYRRE
+import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.COLLECTION_LEVEL
+import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.DUNGEON_HEAD_FLOOR_NUMBER
+import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.DUNGEON_POTION_LEVEL
+import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.EDITION_NUMBER
+import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.KUUDRA_KEY
+import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.LARVA_HOOK
+import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.MASTER_SKULL_TIER
+import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.MASTER_STAR_TIER
+import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.MINION_TIER
+import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.NEW_YEAR_CAKE
+import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.PET_LEVEL
+import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.RANCHERS_BOOTS_SPEED
+import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.SKILL_LEVEL
+import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.VACUUM_GARDEN
import at.hannibal2.skyhanni.events.RenderItemTipEvent
+import at.hannibal2.skyhanni.features.garden.pests.PestAPI
+import at.hannibal2.skyhanni.utils.ConfigUtils
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils
import at.hannibal2.skyhanni.utils.ItemUtils.cleanName
+import at.hannibal2.skyhanni.utils.ItemUtils.getInternalNameOrNull
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzUtils.between
+import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
+import at.hannibal2.skyhanni.utils.NumberUtil
+import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber
import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimal
-import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded
+import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getBottleOfJyrreSeconds
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getEdition
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
-import at.hannibal2.skyhanni.utils.StringUtils.matchRegex
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import net.minecraft.item.ItemStack
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-class ItemDisplayOverlayFeatures {
+object ItemDisplayOverlayFeatures {
+ // TODO USE SH-REPO
+ private val config get() = SkyHanniMod.feature.inventory
+
+ // TODO repo
private val rancherBootsSpeedCapPattern = "§7Current Speed Cap: §a(?<cap>.*)".toPattern()
private val petLevelPattern = "\\[Lvl (?<level>.*)] .*".toPattern()
+ private val masterSkullPattern = "(.*)Master Skull - Tier .".toPattern()
+ private val gardenVacuumPatterm = "§7Vacuum Bag: §6(?<amount>\\d*) Pests?".toPattern()
+ private val harvestPattern = "§7§7You may harvest §6(?<amount>.).*".toPattern()
+ private val dungeonPotionPattern = "Dungeon (?<level>.*) Potion".toPattern()
+ private val bingoGoalRankPattern = "(§.)*You were the (§.)*(?<rank>[\\w]+)(?<ordinal>(st|nd|rd|th)) (§.)*to".toPattern()
+
+ private val bottleOfJyrre = "NEW_BOTTLE_OF_JYRRE".asInternalName()
@SubscribeEvent
fun onRenderItemTip(event: RenderItemTipEvent) {
@@ -28,8 +64,9 @@ class ItemDisplayOverlayFeatures {
private fun getStackTip(item: ItemStack): String {
val itemName = item.cleanName()
+ val chestName = InventoryUtils.openInventoryName()
- if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(0)) {
+ if (MASTER_STAR_TIER.isSelected()) {
when (itemName) {
"First Master Star" -> return "1"
"Second Master Star" -> return "2"
@@ -39,11 +76,13 @@ class ItemDisplayOverlayFeatures {
}
}
- if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(1) && itemName.matchRegex("(.*)Master Skull - Tier .")) {
- return itemName.substring(itemName.length - 1)
+ if (MASTER_SKULL_TIER.isSelected()) {
+ masterSkullPattern.matchMatcher(itemName) {
+ return itemName.substring(itemName.length - 1)
+ }
}
- if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(2) && (itemName.contains("Golden ") || itemName.contains("Diamond "))) {
+ if (DUNGEON_HEAD_FLOOR_NUMBER.isSelected() && (itemName.contains("Golden ") || itemName.contains("Diamond "))) {
when {
itemName.contains("Bonzo") -> return "1"
itemName.contains("Scarf") -> return "2"
@@ -55,11 +94,11 @@ class ItemDisplayOverlayFeatures {
}
}
- if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(3) && itemName.startsWith("New Year Cake (")) {
+ if (NEW_YEAR_CAKE.isSelected() && itemName.startsWith("New Year Cake (")) {
return "§b" + itemName.between("(Year ", ")")
}
- if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(4)) {
+ if (PET_LEVEL.isSelected()) {
val chestName = InventoryUtils.openInventoryName()
if (!chestName.endsWith("Sea Creature Guide") && ItemUtils.isPet(itemName)) {
petLevelPattern.matchMatcher(itemName) {
@@ -73,7 +112,7 @@ class ItemDisplayOverlayFeatures {
}
}
- if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(5) && itemName.contains(" Minion ") &&
+ if (MINION_TIER.isSelected() && itemName.contains(" Minion ") &&
!itemName.contains("Recipe") && item.getLore().any { it.contains("Place this minion") }
) {
val array = itemName.split(" ")
@@ -81,12 +120,12 @@ class ItemDisplayOverlayFeatures {
return last.romanToDecimal().toString()
}
- if (SkyHanniMod.feature.inventory.displaySackName && ItemUtils.isSack(item)) {
+ if (config.displaySackName && ItemUtils.isSack(item)) {
val sackName = grabSackName(itemName)
return (if (itemName.contains("Enchanted")) "§5" else "") + sackName.substring(0, 2)
}
- if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(8) && itemName.contains("Kuudra Key")) {
+ if (KUUDRA_KEY.isSelected() && itemName.contains("Kuudra Key")) {
return when (itemName) {
"Kuudra Key" -> "§a1"
"Hot Kuudra Key" -> "§22"
@@ -97,32 +136,33 @@ class ItemDisplayOverlayFeatures {
}
}
- if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(9) &&
+ if (SKILL_LEVEL.isSelected() &&
InventoryUtils.openInventoryName() == "Your Skills" &&
- item.getLore().any { it.contains("Click to view!") }) {
+ item.getLore().any { it.contains("Click to view!") }
+ ) {
if (CollectionAPI.isCollectionTier0(item.getLore())) return "0"
val split = itemName.split(" ")
if (!itemName.contains("Dungeon")) {
val text = split.last()
if (split.size < 2) return "0"
- return "" + text.romanToDecimalIfNeeded()
+ return "" + text.romanToDecimalIfNecessary()
}
}
- if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(10) && InventoryUtils.openInventoryName().endsWith(" Collections")) {
+ if (COLLECTION_LEVEL.isSelected() && InventoryUtils.openInventoryName().endsWith(" Collections")) {
val lore = item.getLore()
if (lore.any { it.contains("Click to view!") }) {
if (CollectionAPI.isCollectionTier0(lore)) return "0"
item.name?.let {
if (it.startsWith("§e")) {
val text = it.split(" ").last()
- return "" + text.romanToDecimalIfNeeded()
+ return "" + text.romanToDecimalIfNecessary()
}
}
}
}
- if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(11) && itemName.contains("Rancher's Boots")) {
+ if (RANCHERS_BOOTS_SPEED.isSelected() && itemName.contains("Rancher's Boots")) {
for (line in item.getLore()) {
rancherBootsSpeedCapPattern.matchMatcher(line) {
return group("cap")
@@ -130,9 +170,9 @@ class ItemDisplayOverlayFeatures {
}
}
- if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(12) && itemName.contains("Larva Hook")) {
+ if (LARVA_HOOK.isSelected() && itemName.contains("Larva Hook")) {
for (line in item.getLore()) {
- "§7§7You may harvest §6(?<amount>.).*".toPattern().matchMatcher(line) {
+ harvestPattern.matchMatcher(line) {
val amount = group("amount").toInt()
return when {
amount > 4 -> "§a$amount"
@@ -143,9 +183,9 @@ class ItemDisplayOverlayFeatures {
}
}
- if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(13) && itemName.startsWith("Dungeon ") && itemName.contains(" Potion")) {
+ if (DUNGEON_POTION_LEVEL.isSelected() && itemName.startsWith("Dungeon ") && itemName.contains(" Potion")) {
item.name?.let {
- "Dungeon (?<level>.*) Potion".toPattern().matchMatcher(it.removeColor()) {
+ dungeonPotionPattern.matchMatcher(it.removeColor()) {
return when (val level = group("level").romanToDecimal()) {
in 1..2 -> "§f$level"
in 3..4 -> "§a$level"
@@ -156,6 +196,46 @@ class ItemDisplayOverlayFeatures {
}
}
+ if (VACUUM_GARDEN.isSelected() && item.getInternalNameOrNull() in PestAPI.vacuumVariants) {
+ for (line in item.getLore()) {
+ gardenVacuumPatterm.matchMatcher(line) {
+ val pests = group("amount").formatNumber()
+ return if (config.vacuumBagCap) {
+ if (pests > 39) "§640" else "$pests"
+ } else {
+ when {
+ pests < 40 -> "$pests"
+ pests < 1_000 -> "§6$pests"
+ pests < 100_000 -> "§c${pests / 1000}k"
+ else -> "§c${pests / 100_000 / 10.0}m"
+ }
+ }
+ }
+ }
+ }
+
+ if (BOTTLE_OF_JYRRE.isSelected() && item.getInternalNameOrNull() == bottleOfJyrre) {
+ val seconds = item.getBottleOfJyrreSeconds() ?: 0
+ return "§a${(seconds / 3600)}"
+ }
+
+ if (EDITION_NUMBER.isSelected()) {
+ item.getEdition()?.let { edition ->
+ if (edition < 1_000) {
+ return "§6$edition"
+ }
+ }
+ }
+
+ if (BINGO_GOAL_RANK.isSelected() && chestName == "Bingo Card" && item.getLore().lastOrNull() == "§aGOAL REACHED") {
+ for (line in item.getLore()) {
+ bingoGoalRankPattern.matchMatcher(line) {
+ val rank = group("rank").formatNumber()
+ if (rank < 10000) return "§6${NumberUtil.format(rank)}"
+ }
+ }
+ }
+
return ""
}
@@ -169,4 +249,13 @@ class ItemDisplayOverlayFeatures {
}
return text
}
+
+ @SubscribeEvent
+ fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
+ event.move(11, "inventory.itemNumberAsStackSize", "inventory.itemNumberAsStackSize") { element ->
+ ConfigUtils.migrateIntArrayListToEnumArrayList(element, ItemNumberEntry::class.java)
+ }
+ }
+
+ fun ItemNumberEntry.isSelected() = config.itemNumberAsStackSize.contains(this)
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemStars.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemStars.kt
index f8dd111b2..bbd302009 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemStars.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemStars.kt
@@ -1,36 +1,40 @@
package at.hannibal2.skyhanni.features.inventory
import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.config.features.inventory.InventoryConfig.ItemNumberEntry.CRIMSON_ARMOR
+import at.hannibal2.skyhanni.data.jsonobjects.repo.ItemsJson
import at.hannibal2.skyhanni.events.RenderItemTipEvent
import at.hannibal2.skyhanni.events.RepositoryReloadEvent
+import at.hannibal2.skyhanni.features.inventory.ItemDisplayOverlayFeatures.isSelected
import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.jsonobjects.ItemsJson
+import at.hannibal2.skyhanni.utils.StringUtils.matches
import net.minecraftforge.event.entity.player.ItemTooltipEvent
import net.minecraftforge.fml.common.eventhandler.EventPriority
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class ItemStars {
+ private val config get() = SkyHanniMod.feature.inventory
+
private val armorNames = mutableListOf<String>()
private val tiers = mutableMapOf<String, Int>()
- private val STAR_FIND_PATCHER = "(.*)§.✪(.*)".toPattern()
+ private val starFindPattern = "(.*)§.✪(.*)".toPattern()
private val armorParts = listOf("Helmet", "Chestplate", "Leggings", "Boots")
@SubscribeEvent(priority = EventPriority.LOW)
fun onTooltip(event: ItemTooltipEvent) {
- if (!LorenzUtils.inSkyBlock) return
-
+ if (!isEnabled()) return
val stack = event.itemStack ?: return
if (stack.stackSize != 1) return
- if (!SkyHanniMod.feature.inventory.itemStars) return
+
val itemName = stack.name ?: return
val stars = getStars(itemName)
if (stars > 0) {
var name = itemName
- while (STAR_FIND_PATCHER.matcher(name).matches()) {
+ while (starFindPattern.matches(name)) {
name = name.replaceFirst("§.✪".toRegex(), "")
}
name = name.trim()
@@ -51,7 +55,7 @@ class ItemStars {
@SubscribeEvent
fun onRenderItemTip(event: RenderItemTipEvent) {
- if (!SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(6)) return
+ if (!CRIMSON_ARMOR.isSelected()) return
val stack = event.stack
val number = getCrimsonStars(stack.name ?: return)
if (number != -1) {
@@ -120,4 +124,6 @@ class ItemStars {
return -1
}
+
+ private fun isEnabled() = LorenzUtils.inSkyBlock && config.itemStars
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/mining/KingTalismanHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/mining/KingTalismanHelper.kt
index 501ae420e..93e12cc6f 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/mining/KingTalismanHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/mining/KingTalismanHelper.kt
@@ -83,7 +83,7 @@ class KingTalismanHelper {
private fun checkOffset() {
val king = EntityUtils.getEntitiesNearby<EntityArmorStand>(LorenzVec(129.6, 196.0, 196.7), 2.0)
- .filter { it.name.startsWith("§6§lKing ") }.first()
+ .filter { it.name.startsWith("§6§lKing ") }.firstOrNull() ?: return
val foundKing = "§6§lKing (?<name>.*)".toPattern().matchMatcher(king.name) {
group("name")
} ?: return
diff --git a/src/main/java/at/hannibal2/skyhanni/features/mining/powdertracker/PowderTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/mining/powdertracker/PowderTracker.kt
index fd4ad8962..63ae5763e 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/mining/powdertracker/PowderTracker.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/mining/powdertracker/PowderTracker.kt
@@ -2,12 +2,14 @@ package at.hannibal2.skyhanni.features.mining.powdertracker
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
+import at.hannibal2.skyhanni.config.features.mining.PowderTrackerConfig.PowderDisplayEntry
import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.events.ConfigLoadEvent
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
+import at.hannibal2.skyhanni.utils.ConfigUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
import at.hannibal2.skyhanni.utils.LorenzUtils.afterChange
import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland
@@ -176,12 +178,16 @@ object PowderTracker {
event.move(8, "#profile.powderTracker", "#profile.powderTracker") { old ->
old.asJsonObject.get("0")
}
+ event.move(11, "mining.powderTracker.textFormat", "mining.powderTracker.textFormat") { element ->
+ ConfigUtils.migrateIntArrayListToEnumArrayList(element, PowderDisplayEntry::class.java)
+ }
}
private fun formatDisplay(map: List<List<Any>>) = buildList {
if (map.isEmpty()) return@buildList
for (index in config.textFormat.get()) {
- add(map[index])
+ // TODO, change functionality to use enum rather than ordinals
+ add(map[index.ordinal])
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt
index 9eab0fdde..881c5c215 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt
@@ -7,11 +7,14 @@ import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.data.ProfileStorageData
import at.hannibal2.skyhanni.events.InventoryCloseEvent
import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
+import at.hannibal2.skyhanni.events.InventoryUpdatedEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
+import at.hannibal2.skyhanni.events.MinionCloseEvent
import at.hannibal2.skyhanni.events.MinionOpenEvent
+import at.hannibal2.skyhanni.events.MinionStorageOpenEvent
import at.hannibal2.skyhanni.test.GriffinUtils.drawWaypointFilled
import at.hannibal2.skyhanni.utils.BlockUtils.getBlockStateAt
import at.hannibal2.skyhanni.utils.InventoryUtils
@@ -25,12 +28,12 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy
import at.hannibal2.skyhanni.utils.LorenzUtils.formatInteger
import at.hannibal2.skyhanni.utils.LorenzVec
import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimal
-import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded
+import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary
import at.hannibal2.skyhanni.utils.RenderUtils.drawString
import at.hannibal2.skyhanni.utils.RenderUtils.renderString
import at.hannibal2.skyhanni.utils.SpecialColour
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
-import at.hannibal2.skyhanni.utils.StringUtils.matchRegex
+import at.hannibal2.skyhanni.utils.StringUtils.matches
import at.hannibal2.skyhanni.utils.TimeUtils
import at.hannibal2.skyhanni.utils.getLorenzVec
import at.hannibal2.skyhanni.utils.toLorenzVec
@@ -51,15 +54,14 @@ import java.awt.Color
class MinionFeatures {
private val config get() = SkyHanniMod.feature.minions
private var lastClickedEntity: LorenzVec? = null
- private var lastMinion: LorenzVec? = null
private var newMinion: LorenzVec? = null
private var newMinionName: String? = null
private var lastMinionOpened = 0L
- private var minionInventoryOpen = false
private var lastInventoryClosed = 0L
private var coinsPerDay = ""
private val minionUpgradePattern = "§aYou have upgraded your Minion to Tier (?<tier>.*)".toPattern()
+ private val minionCoinPattern = "§aYou received §r§6(.*) coins§r§a!".toPattern()
@SubscribeEvent
fun onPlayerInteract(event: PlayerInteractEvent) {
@@ -91,6 +93,10 @@ class MinionFeatures {
val entity = minecraft.pointedEntity
if (entity != null) {
lastClickedEntity = entity.getLorenzVec()
+ return
+ }
+ minecraft.thePlayer.rayTrace(16.0, 1.0f)?.let {
+ lastStorage = it.blockPos.toLorenzVec()
}
}
@@ -123,13 +129,24 @@ class MinionFeatures {
fun onInventoryOpen(event: InventoryFullyOpenedEvent) {
if (!LorenzUtils.inSkyBlock) return
if (LorenzUtils.skyBlockIsland != IslandType.PRIVATE_ISLAND) return
- if (!event.inventoryName.contains(" Minion ")) return
+ if (!event.inventoryName.contains("Minion ")) return
event.inventoryItems[48]?.let {
if ("§aCollect All" == it.name) {
MinionOpenEvent(event.inventoryName, event.inventoryItems).postAndCatch()
+ return
}
}
+
+ MinionStorageOpenEvent(lastStorage, event.inventoryItems).postAndCatch()
+ minionStorageInventoryOpen = true
+ }
+
+ @SubscribeEvent
+ fun onInventoryUpdated(event: InventoryUpdatedEvent) {
+ if (minionInventoryOpen) {
+ MinionOpenEvent(event.inventoryName, event.inventoryItems).postAndCatch()
+ }
}
@SubscribeEvent
@@ -159,6 +176,9 @@ class MinionFeatures {
@SubscribeEvent
fun onInventoryClose(event: InventoryCloseEvent) {
+ if (event.reopenSameName) return
+
+ minionStorageInventoryOpen = false
if (!minionInventoryOpen) return
val minions = minions ?: return
@@ -172,6 +192,7 @@ class MinionFeatures {
if (location !in minions) {
minions[location]!!.lastClicked = 0
}
+ MinionCloseEvent().postAndCatch()
}
@SubscribeEvent
@@ -224,6 +245,7 @@ class MinionFeatures {
lastMinion = null
lastMinionOpened = 0L
minionInventoryOpen = false
+ minionStorageInventoryOpen = false
}
@SubscribeEvent
@@ -232,11 +254,10 @@ class MinionFeatures {
if (LorenzUtils.skyBlockIsland != IslandType.PRIVATE_ISLAND) return
val message = event.message
- if (message.matchRegex("§aYou received §r§6(.*) coins§r§a!") && System.currentTimeMillis() - lastInventoryClosed < 2_000) {
+ if (minionCoinPattern.matches(message) && System.currentTimeMillis() - lastInventoryClosed < 2_000) {
minions?.get(lastMinion)?.let {
it.lastClicked = System.currentTimeMillis()
}
-
}
if (message.startsWith("§aYou picked up a minion!") && lastMinion != null) {
minions = minions?.editCopy { remove(lastMinion) }
@@ -256,7 +277,7 @@ class MinionFeatures {
}
minionUpgradePattern.matchMatcher(message) {
- val newTier = group("tier").romanToDecimalIfNeeded()
+ val newTier = group("tier").romanToDecimalIfNecessary()
minions?.get(lastMinion)?.let {
val minionName = getMinionName(it.displayName, newTier)
it.displayName = minionName
@@ -272,7 +293,7 @@ class MinionFeatures {
val playerLocation = LocationUtils.playerLocation()
val minions = minions ?: return
for (minion in minions) {
- val location = minion.key.add(0.0, 1.0, 0.0)
+ val location = minion.key.add(y = 1.0)
if (!location.canBeSeen()) continue
val lastEmptied = minion.value.lastClicked
@@ -283,14 +304,14 @@ class MinionFeatures {
val name = "§6" + if (config.nameOnlyTier) {
displayName.split(" ").last()
} else displayName
- event.drawString(location.add(0.0, 0.65, 0.0), name, true)
+ event.drawString(location.add(y = 0.65), name, true)
}
if (config.emptiedTime.display && lastEmptied != 0L) {
val duration = System.currentTimeMillis() - lastEmptied
val format = TimeUtils.formatDuration(duration, longName = true) + " ago"
val text = "§eHopper Emptied: $format"
- event.drawString(location.add(0.0, 1.15, 0.0), text, true)
+ event.drawString(location.add(y = 1.15), text, true)
}
}
}
@@ -326,6 +347,12 @@ class MinionFeatures {
}
companion object {
+
+ var lastMinion: LorenzVec? = null
+ var lastStorage: LorenzVec? = null
+ var minionInventoryOpen = false
+ var minionStorageInventoryOpen = false
+
private var minions: Map<LorenzVec, Storage.ProfileSpecific.MinionConfig>?
get() {
return ProfileStorageData.profileSpecific?.minions
diff --git a/src/main/java/at/hannibal2/skyhanni/features/minion/MinionXp.kt b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionXp.kt
new file mode 100644
index 000000000..787cbe059
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionXp.kt
@@ -0,0 +1,195 @@
+package at.hannibal2.skyhanni.features.minion
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.jsonobjects.repo.MinionXPJson
+import at.hannibal2.skyhanni.events.IslandChangeEvent
+import at.hannibal2.skyhanni.events.MinionCloseEvent
+import at.hannibal2.skyhanni.events.MinionOpenEvent
+import at.hannibal2.skyhanni.events.MinionStorageOpenEvent
+import at.hannibal2.skyhanni.events.RepositoryReloadEvent
+import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
+import at.hannibal2.skyhanni.utils.ItemUtils.getLore
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.LorenzVec
+import at.hannibal2.skyhanni.utils.NEUInternalName
+import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
+import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
+import net.minecraft.block.BlockChest
+import net.minecraft.client.Minecraft
+import net.minecraft.item.Item
+import net.minecraft.item.ItemStack
+import net.minecraftforge.event.entity.player.ItemTooltipEvent
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import java.util.EnumMap
+
+class MinionXp {
+
+ private val config get() = SkyHanniMod.feature.minions
+
+ private val xpItemMap: MutableMap<PrimitiveItemStack, String> = mutableMapOf()
+ private val collectItemXpList: MutableList<String> = mutableListOf()
+
+ private var collectItem: Item? = null
+
+ private val minionStorages = mutableListOf<MinionStorage>()
+
+ private var xpInfoMap: Map<NEUInternalName, XpInfo> = hashMapOf()
+
+ data class XpInfo(val type: XpType, val amount: Double)
+
+ private data class MinionStorage(val position: LorenzVec, val xpList: EnumMap<XpType, Double>) {
+ val timestamp: SimpleTimeMark = SimpleTimeMark.now()
+ }
+
+ // TODO move to some other spot. This can be used at other features as well
+ private data class PrimitiveItemStack(val name: NEUInternalName, val stackSize: Int)
+
+ private fun toPrimitiveItemStack(itemStack: ItemStack) =
+ PrimitiveItemStack(itemStack.getInternalName(), itemStack.stackSize)
+
+ // TODO use upper case names, created a function to get type by lowercase name
+ // TODO maybe: rename to SkillType, move somewhere else
+ enum class XpType {
+ Farming,
+ Mining,
+ Combat,
+ Foraging,
+ Fishing,
+ Alchemy
+ }
+
+ @SubscribeEvent
+ fun onMinionOpen(event: MinionOpenEvent) {
+ if (!config.xpDisplay) return
+
+ collectItem = event.inventoryItems[48]?.item
+ collectItemXpList.clear()
+
+ val xpTotal = handleItems(event.inventoryItems, true)
+
+ val missesStorage = MinionFeatures.lastMinion?.let { minionPosition ->
+ getStorageXpAndUpdateTotal(minionPosition, xpTotal)
+ } ?: false
+
+ collectItemXpList.addAll(xpTotal.map { (type, amount) -> collectMessage(type, amount) })
+ if (missesStorage) {
+ collectItemXpList.add("")
+ collectItemXpList.add("§cError: No Minion Storage Data")
+ collectItemXpList.add("§eOpen Storage to get Correct Value")
+ }
+ collectItemXpList.add("")
+ }
+
+ private fun getStorageXpAndUpdateTotal(
+ minionPosition: LorenzVec,
+ xpTotal: EnumMap<XpType, Double>,
+ ): Boolean {
+ if (!getHasStorage(minionPosition)) return false
+ val storage = minionStorages.firstOrNull {
+ it.position.distanceSq(minionPosition) <= 2.5 && it.timestamp.passedSince().inWholeMinutes < 20
+ }
+
+ return if (storage != null) {
+ storage.xpList.forEach { (type, amount) ->
+ xpTotal.compute(type) { _, currentAmount -> (currentAmount ?: 0.0) + amount }
+ }
+ false
+ } else {
+ true
+ }
+
+ }
+
+ private fun handleItems(inventoryItems: Map<Int, ItemStack>, isMinion: Boolean): EnumMap<XpType, Double> {
+ val xpTotal = EnumMap<XpType, Double>(XpType::class.java)
+ inventoryItems.filter {
+ it.value.getLore().isNotEmpty() && (!isMinion || it.key in listOf(21..26, 30..35, 39..44).flatten())
+ }.forEach { (_, itemStack) ->
+ val item = toPrimitiveItemStack(itemStack)
+ val name = item.name
+ val xp = xpInfoMap[name] ?: return@forEach
+
+ // TODO add wisdom and Derpy to calculation and random extra Exp Events
+ val xpAmount = xp.amount * item.stackSize
+
+ xpItemMap[item] = collectMessage(xp.type, xpAmount)
+ xpTotal.compute(xp.type) { _, currentAmount -> (currentAmount ?: 0.0) + xpAmount }
+ }
+ return xpTotal
+ }
+
+ @SubscribeEvent
+ fun onMinionStorageOpen(event: MinionStorageOpenEvent) {
+ if (!config.xpDisplay) return
+
+ val xpTotal = handleItems(event.inventoryItems, false)
+
+ if (event.position == null) return
+ minionStorages.removeIf { it.position == event.position }
+ minionStorages.add(MinionStorage(event.position, xpTotal))
+ }
+
+ private fun collectMessage(type: XpType, amount: Double) =
+ "§7Collect to get: §b${amount.addSeparators()} §e${type.name} XP"
+
+ private fun getHasStorage(minionPosition: LorenzVec): Boolean {
+ val positionsToCheck = listOf(
+ LorenzVec(1, 0, 0), LorenzVec(0, 0, 1),
+ LorenzVec(-1, 0, 0), LorenzVec(0, 0, -1)
+ )
+
+ return positionsToCheck.any { position ->
+ val pos = minionPosition.add(position).toBlocPos()
+ val block = Minecraft.getMinecraft().theWorld.getBlockState(pos).block
+ block is BlockChest
+ }
+ }
+
+ @SubscribeEvent
+ fun onItemTooltipEvent(event: ItemTooltipEvent) {
+ if (!LorenzUtils.inSkyBlock) return
+ if (!config.xpDisplay) return
+ when {
+ MinionFeatures.minionInventoryOpen -> {
+ addXpInfoToTooltip(event)
+ if (collectItem == event.itemStack.item) {
+ collectItemXpList.forEachIndexed { i, it ->
+ event.toolTip.add(i + 1, it)
+ }
+ }
+ }
+
+ MinionFeatures.minionStorageInventoryOpen -> {
+ addXpInfoToTooltip(event)
+ }
+ }
+ }
+
+ private fun addXpInfoToTooltip(event: ItemTooltipEvent) {
+ xpItemMap[toPrimitiveItemStack(event.itemStack)]?.let {
+ event.toolTip.add("")
+ event.toolTip.add(it)
+ }
+ }
+
+ @SubscribeEvent
+ fun onIslandChangeEvent(event: IslandChangeEvent) {
+ minionStorages.clear()
+ xpItemMap.clear()
+ collectItemXpList.clear()
+ }
+
+ @SubscribeEvent
+ fun onMinionClose(event: MinionCloseEvent) {
+ xpItemMap.clear()
+ collectItemXpList.clear()
+ }
+
+ @SubscribeEvent
+ fun onRepoReload(event: RepositoryReloadEvent) {
+ xpInfoMap = event.getConstant<MinionXPJson>("MinionXP").minion_xp.mapNotNull { xpType ->
+ xpType.value.mapNotNull { it.key.asInternalName() to XpInfo(XpType.valueOf(xpType.key), it.value) }
+ }.flatten().toMap()
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/FixNEUHeavyPearls.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/FixNEUHeavyPearls.kt
index 8f3920844..b5ce08ba7 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/FixNEUHeavyPearls.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/FixNEUHeavyPearls.kt
@@ -1,7 +1,7 @@
package at.hannibal2.skyhanni.features.misc
import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.events.SackChangeEvent
+import at.hannibal2.skyhanni.events.ItemAddEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
import io.github.moulberry.notenoughupdates.NotEnoughUpdates
@@ -13,16 +13,14 @@ class FixNEUHeavyPearls {
private val heavyPearl = "HEAVY_PEARL".asInternalName()
@SubscribeEvent
- fun onSackChange(event: SackChangeEvent) {
+ fun onSackChange(event: ItemAddEvent) {
if (!isEnabled()) return
- for (change in event.sackChanges) {
- if (change.internalName == heavyPearl && change.delta == 3) {
- val specific = NotEnoughUpdates.INSTANCE.config.getProfileSpecific()
- if (System.currentTimeMillis() > specific.dailyHeavyPearlCompleted + 1.hours.inWholeMilliseconds) {
- LorenzUtils.chat("Mark NEU Heavy Pearls as done.")
- specific.dailyHeavyPearlCompleted = System.currentTimeMillis()
- }
+ if (event.internalName == heavyPearl && event.amount == 3) {
+ val specific = NotEnoughUpdates.INSTANCE.config.getProfileSpecific()
+ if (System.currentTimeMillis() > specific.dailyHeavyPearlCompleted + 1.hours.inWholeMilliseconds) {
+ LorenzUtils.chat("Mark NEU Heavy Pearls as done.")
+ specific.dailyHeavyPearlCompleted = System.currentTimeMillis()
}
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/InGameDateDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/InGameDateDisplay.kt
index 5bacfd047..0d87bb767 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/InGameDateDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/InGameDateDisplay.kt
@@ -10,7 +10,7 @@ import at.hannibal2.skyhanni.utils.RenderUtils.renderString
import at.hannibal2.skyhanni.utils.StringUtils.matches
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import at.hannibal2.skyhanni.utils.TimeUtils.formatted
-import at.hannibal2.skyhanni.utils.jsonobjects.TabListJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.TabListJson
import io.github.moulberry.notenoughupdates.util.SkyBlockTime
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/LockMouseLook.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/LockMouseLook.kt
index 14b430d19..4025c32e2 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/LockMouseLook.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/LockMouseLook.kt
@@ -46,4 +46,10 @@ object LockMouseLook {
if (!lockedMouse) return
config.lockedMouseDisplay.renderString("§eMouse Locked", posLabel = "Mouse Locked")
}
+
+ fun autoDisable() {
+ if (lockedMouse) {
+ toggleLock()
+ }
+ }
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/MarkedPlayerManager.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/MarkedPlayerManager.kt
index 66e379747..5409d956a 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/MarkedPlayerManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/MarkedPlayerManager.kt
@@ -16,6 +16,8 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class MarkedPlayerManager {
+ private val config get() = SkyHanniMod.feature.markedPlayers
+
companion object {
val playerNamesToMark = mutableListOf<String>()
private val markedPlayers = mutableMapOf<String, EntityOtherPlayerMP>()
@@ -64,7 +66,7 @@ class MarkedPlayerManager {
@SubscribeEvent
fun onConfigLoad(event: ConfigLoadEvent) {
- SkyHanniMod.feature.markedPlayers.markOwnName.whenChanged { _, new ->
+ config.markOwnName.whenChanged { _, new ->
val name = LorenzUtils.getPlayerName()
if (new) {
if (!playerNamesToMark.contains(name)) {
@@ -87,8 +89,7 @@ class MarkedPlayerManager {
@SubscribeEvent
fun onRenderMobColored(event: RenderMobColoredEvent) {
- if (!LorenzUtils.inSkyBlock) return
- if (!SkyHanniMod.feature.markedPlayers.highlightInWorld) return
+ if (!isEnabled()) return
val entity = event.entity
if (entity in markedPlayers.values) {
@@ -98,8 +99,7 @@ class MarkedPlayerManager {
@SubscribeEvent
fun onResetEntityHurtTime(event: ResetEntityHurtEvent) {
- if (!LorenzUtils.inSkyBlock) return
- if (!SkyHanniMod.feature.markedPlayers.highlightInWorld) return
+ if (!isEnabled()) return
val entity = event.entity
if (entity in markedPlayers.values) {
@@ -112,11 +112,13 @@ class MarkedPlayerManager {
if (Minecraft.getMinecraft().thePlayer == null) return
markedPlayers.clear()
- if (SkyHanniMod.feature.markedPlayers.markOwnName.get()) {
+ if (config.markOwnName.get()) {
val name = LorenzUtils.getPlayerName()
if (!playerNamesToMark.contains(name)) {
playerNamesToMark.add(name)
}
}
}
+
+ private fun isEnabled() = LorenzUtils.inSkyBlock && config.highlightInWorld
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/NonGodPotEffectDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/NonGodPotEffectDisplay.kt
index 80c3b870d..d08dd888a 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/NonGodPotEffectDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/NonGodPotEffectDisplay.kt
@@ -63,6 +63,7 @@ class NonGodPotEffectDisplay {
private var patternEffectsCount = "§7You have §e(?<name>\\d+) §7non-god effects\\.".toPattern()
private var totalEffectsCount = 0
+ // todo : cleanup and add support for poison candy I, and add support for splash / other formats
@SubscribeEvent
fun onChatMessage(event: LorenzChatEvent) {
if (event.message == "§aYou cleared all of your active effects!") {
@@ -95,6 +96,7 @@ class NonGodPotEffectDisplay {
effectDuration[NonGodPotEffect.GOBLIN] = Timer(20.minutes)
update()
}
+
if (event.message == "§cThe Goblin King's §r§afoul stench §r§chas dissipated!") {
effectDuration.remove(NonGodPotEffect.GOBLIN)
update()
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/QuickModMenuSwitch.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/QuickModMenuSwitch.kt
index 9b6987fad..fceb8563e 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/QuickModMenuSwitch.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/QuickModMenuSwitch.kt
@@ -8,7 +8,7 @@ import at.hannibal2.skyhanni.test.command.ErrorManager
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.makeAccessible
import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
-import at.hannibal2.skyhanni.utils.jsonobjects.ModGuiSwitcherJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.ModGuiSwitcherJson
import at.hannibal2.skyhanni.utils.renderables.Renderable
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.GlStateManager
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/AdvancedPlayerList.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/AdvancedPlayerList.kt
index 7c96f4efa..2eac62d1f 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/AdvancedPlayerList.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/AdvancedPlayerList.kt
@@ -1,12 +1,13 @@
package at.hannibal2.skyhanni.features.misc.compacttablist
import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.data.BingoAPI
import at.hannibal2.skyhanni.data.FriendAPI
import at.hannibal2.skyhanni.data.GuildAPI
import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.data.PartyAPI
+import at.hannibal2.skyhanni.data.jsonobjects.repo.ContributorListJson
import at.hannibal2.skyhanni.events.RepositoryReloadEvent
+import at.hannibal2.skyhanni.features.bingo.BingoAPI
import at.hannibal2.skyhanni.features.misc.MarkedPlayerManager
import at.hannibal2.skyhanni.test.SkyHanniDebugsAndTests
import at.hannibal2.skyhanni.utils.KeyboardManager
@@ -14,7 +15,6 @@ import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
-import at.hannibal2.skyhanni.utils.jsonobjects.ContributorListJson
import com.google.common.cache.CacheBuilder
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import java.util.concurrent.TimeUnit
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordRPCManager.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordRPCManager.kt
index e358b3f28..96123826e 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordRPCManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordRPCManager.kt
@@ -5,11 +5,15 @@ package at.hannibal2.skyhanni.features.misc.discordrpc
import at.hannibal2.skyhanni.SkyHanniMod.Companion.consoleLog
import at.hannibal2.skyhanni.SkyHanniMod.Companion.coroutineScope
import at.hannibal2.skyhanni.SkyHanniMod.Companion.feature
+import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
+import at.hannibal2.skyhanni.config.features.misc.DiscordRPCConfig.LineEntry
+import at.hannibal2.skyhanni.config.features.misc.DiscordRPCConfig.PriorityEntry
import at.hannibal2.skyhanni.events.ConfigLoadEvent
import at.hannibal2.skyhanni.events.LorenzKeyPressEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
import at.hannibal2.skyhanni.test.command.ErrorManager
+import at.hannibal2.skyhanni.utils.ConfigUtils
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.onToggle
import at.hannibal2.skyhanni.utils.SimpleTimeMark
@@ -50,9 +54,9 @@ object DiscordRPCManager : IPCListener {
return@launch
}
consoleLog("Starting Discord RPC...")
-
- firstLine = getStatusByConfigId(config.firstLine.get())
- secondLine = getStatusByConfigId(config.secondLine.get())
+ // TODO, change functionality to use enum rather than ordinals
+ firstLine = getStatusByConfigId(config.firstLine.get().ordinal)
+ secondLine = getStatusByConfigId(config.secondLine.get().ordinal)
startTimestamp = System.currentTimeMillis()
client = IPCClient(applicationID)
client?.setListener(this@DiscordRPCManager)
@@ -106,9 +110,9 @@ object DiscordRPCManager : IPCListener {
fun updatePresence() {
val location = DiscordStatus.LOCATION.getDisplayString()
val discordIconKey = DiscordLocationKey.getDiscordIconKey(location)
-
- secondLine = getStatusByConfigId(config.secondLine.get())
- firstLine = getStatusByConfigId(config.firstLine.get())
+ // TODO, change functionality to use enum rather than ordinals
+ secondLine = getStatusByConfigId(config.secondLine.get().ordinal)
+ firstLine = getStatusByConfigId(config.firstLine.get().ordinal)
val presence: RichPresence = RichPresence.Builder()
.setDetails(firstLine.getDisplayString())
.setState(secondLine.getDisplayString())
@@ -207,7 +211,25 @@ object DiscordRPCManager : IPCListener {
// Events that change things in DiscordStatus
@SubscribeEvent
fun onKeybind(event: LorenzKeyPressEvent) {
- if (!isEnabled() || !feature.misc.discordRPC.autoPriority.contains(4)) return // autoPriority 4 is dynamic afk
+ if (!isEnabled() || !PriorityEntry.AFK.isSelected()) return // autoPriority 4 is dynamic afk
beenAfkFor = SimpleTimeMark.now()
}
+
+ @SubscribeEvent
+ fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
+ event.move(11, "misc.discordRPC.firstLine", "misc.discordRPC.firstLine") { element ->
+ ConfigUtils.migrateIntToEnum(element, LineEntry::class.java)
+ }
+ event.move(11, "misc.discordRPC.secondLine", "misc.discordRPC.secondLine") { element ->
+ ConfigUtils.migrateIntToEnum(element, LineEntry::class.java)
+ }
+ event.move(11, "misc.discordRPC.auto", "misc.discordRPC.auto") { element ->
+ ConfigUtils.migrateIntToEnum(element, LineEntry::class.java)
+ }
+ event.move(11, "misc.discordRPC.autoPriority", "misc.discordRPC.autoPriority") { element ->
+ ConfigUtils.migrateIntArrayListToEnumArrayList(element, PriorityEntry::class.java)
+ }
+ }
+
+ private fun PriorityEntry.isSelected() = config.autoPriority.contains(this)
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordStatus.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordStatus.kt
index 141870585..cc2a09b9d 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordStatus.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordStatus.kt
@@ -258,7 +258,8 @@ enum class DiscordStatus(private val displayMessageSupplier: Supplier<String>?)
AUTO({
var autoReturn = ""
for (statusID in SkyHanniMod.feature.misc.discordRPC.autoPriority) { // for every dynamic that the user wants to see...
- val autoStatus = AutoStatus.entries[statusID]
+ // TODO, change functionality to use enum rather than ordinals
+ val autoStatus = AutoStatus.entries[statusID.ordinal]
val result =
autoStatus.correspondingDiscordStatus.getDisplayString() // get what would happen if we were to display it
if (result != autoStatus.placeholderText) { // if that value is useful, display it
@@ -269,7 +270,7 @@ enum class DiscordStatus(private val displayMessageSupplier: Supplier<String>?)
if (autoReturn == "") { // if we didn't find any useful information, display the fallback
val statusNoAuto = DiscordStatus.entries.toMutableList()
statusNoAuto.remove(AUTO)
- autoReturn = statusNoAuto[SkyHanniMod.feature.misc.discordRPC.auto.get()].getDisplayString()
+ autoReturn = statusNoAuto[SkyHanniMod.feature.misc.discordRPC.auto.get().ordinal].getDisplayString()
}
autoReturn
}),
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValue.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValue.kt
index a4fe36fdc..cefac74a8 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValue.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValue.kt
@@ -38,7 +38,9 @@ object EstimatedItemValue {
private val cache = mutableMapOf<ItemStack, List<List<Any>>>()
private var lastToolTipTime = 0L
var gemstoneUnlockCosts = HashMap<NEUInternalName, HashMap<String, List<String>>>()
- var currentlyShowing = false
+ private var currentlyShowing = false
+
+ fun isCurrentlyShowing() = currentlyShowing && Minecraft.getMinecraft().currentScreen != null
@SubscribeEvent
fun onRepoReload(event: RepositoryReloadEvent) {
@@ -139,11 +141,6 @@ object EstimatedItemValue {
}
}
- // Stats Breakdown
- val name = item.name ?: return
- if (name == "§6☘ Category: Item Ability (Passive)") return
- if (name.contains("Salesperson")) return
-
val newDisplay = try {
draw(item)
} catch (e: Exception) {
@@ -160,6 +157,16 @@ object EstimatedItemValue {
private fun draw(stack: ItemStack): List<List<Any>> {
val internalName = stack.getInternalNameOrNull() ?: return listOf()
+ // Stats Breakdown
+ val name = stack.name ?: return listOf()
+ if (name == "§6☘ Category: Item Ability (Passive)") return listOf()
+ if (name.contains("Salesperson")) return listOf()
+
+ // Autopet rule > Create Rule
+ if (!InventoryUtils.isSlotInPlayerInventory(stack)) {
+ if (InventoryUtils.openInventoryName() == "Choose a wardrobe slot") return listOf()
+ }
+
// FIX neu item list
if (internalName.startsWith("ULTIMATE_ULTIMATE_")) return listOf()
// We don't need this feature to work on books at all
@@ -190,7 +197,7 @@ object EstimatedItemValue {
} else {
NumberUtil.format(totalPrice)
}
- list.add("§aTotal: §6§l$numberFormat")
+ list.add("§aTotal: §6§l$numberFormat coins")
val newDisplay = mutableListOf<List<Any>>()
for (line in list) {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValueCalculator.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValueCalculator.kt
index f3e27957d..5f726f544 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValueCalculator.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValueCalculator.kt
@@ -527,6 +527,7 @@ object EstimatedItemValueCalculator {
return price
}
+ // TODO repo
private val hasAlwaysScavenger = listOf(
"CRYPT_DREADLORD_SWORD".asInternalName(),
"ZOMBIE_SOLDIER_CUTLASS".asInternalName(),
@@ -535,6 +536,12 @@ object EstimatedItemValueCalculator {
"ZOMBIE_KNIGHT_SWORD".asInternalName(),
"SILENT_DEATH".asInternalName(),
"ZOMBIE_COMMANDER_WHIP".asInternalName(),
+ "ICE_SPRAY_WAND".asInternalName(),
+ )
+
+ private val hasAlwaysReplenish = listOf(
+ "ADVANCED_GARDENING_HOE".asInternalName(),
+ "ADVANCED_GARDENING_AXE".asInternalName(),
)
private fun addEnchantments(stack: ItemStack, list: MutableList<String>): Double {
@@ -554,6 +561,10 @@ object EstimatedItemValueCalculator {
continue
}
+ if (rawName == "replenish" && rawLevel == 1 && internalName in hasAlwaysReplenish) {
+ continue
+ }
+
var level = rawLevel
var multiplier = 1
if (rawName == "ultimate_chimera" || rawName == "ultimate_fatal_tempo" || rawName == "smoldering") {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedWardrobePrice.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedWardrobePrice.kt
index 6655d71cd..3969372ff 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedWardrobePrice.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedWardrobePrice.kt
@@ -42,7 +42,7 @@ class EstimatedWardrobePrice {
toolTip.add(index++, " §7- $name: §6${NumberUtil.format(price)}")
}
- toolTip.add(index, " §aTotal Value: §6§l${NumberUtil.format(totalPrice)}")
+ toolTip.add(index, " §aTotal Value: §6§l${NumberUtil.format(totalPrice)} coins")
}
@SubscribeEvent
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorFeatures.kt
index 318d4c1f0..b07c4dab6 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorFeatures.kt
@@ -1,6 +1,8 @@
package at.hannibal2.skyhanni.features.misc.trevor
import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
+import at.hannibal2.skyhanni.config.features.misc.TrevorTheTrapperConfig.TrackerEntry
import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.data.ScoreboardData
import at.hannibal2.skyhanni.events.CheckRenderEntityEvent
@@ -14,6 +16,7 @@ import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed
import at.hannibal2.skyhanni.mixins.hooks.RenderLivingEntityHelper
import at.hannibal2.skyhanni.test.GriffinUtils.drawWaypointFilled
import at.hannibal2.skyhanni.test.command.ErrorManager
+import at.hannibal2.skyhanni.utils.ConfigUtils
import at.hannibal2.skyhanni.utils.EntityUtils
import at.hannibal2.skyhanni.utils.LocationUtils.distanceToPlayer
import at.hannibal2.skyhanni.utils.LorenzColor
@@ -67,16 +70,16 @@ object TrevorFeatures {
init {
fixedRateTimer(name = "skyhanni-update-trapper", period = 1000L) {
- Minecraft.getMinecraft().addScheduledTask {
- try {
- if (config.trapperSolver && onFarmingIsland()) {
+ if (onFarmingIsland() && config.trapperSolver) {
+ Minecraft.getMinecraft().addScheduledTask {
+ try {
updateTrapper()
- TrevorTracker.saveAndUpdate()
+ TrevorTracker.update()
TrevorTracker.calculatePeltsPerHour()
if (questActive) TrevorSolver.findMob()
+ } catch (error: Throwable) {
+ ErrorManager.logError(error, "Encountered an error when updating the trapper solver")
}
- } catch (error: Throwable) {
- ErrorManager.logError(error, "Encountered an error when updating the trapper solver")
}
}
}
@@ -158,7 +161,6 @@ object TrevorFeatures {
)
}
-
private fun updateTrapper() {
timeUntilNextReady -= 1
if (trapperReady && timeUntilNextReady > 0) {
@@ -220,7 +222,7 @@ object TrevorFeatures {
{ config.trapperTalkCooldown }
entityTrapper.getLorenzVec().let {
if (it.distanceToPlayer() < 15) {
- event.drawString(it.add(0.0, 2.23, 0.0), currentLabel)
+ event.drawString(it.add(y = 2.23), currentLabel)
}
}
}
@@ -236,11 +238,11 @@ object TrevorFeatures {
TrevorSolver.currentMob!!.mobName
}
location = TrevorSolver.mobCoordinates
- event.drawWaypointFilled(location.add(0, -2, 0), LorenzColor.GREEN.toColor(), true, true)
- event.drawDynamicText(location.add(0, 1, 0), displayName, 1.5)
+ event.drawWaypointFilled(location.add(y = -2), LorenzColor.GREEN.toColor(), true, true)
+ event.drawDynamicText(location.add(y = 1), displayName, 1.5)
} else {
event.drawWaypointFilled(location, LorenzColor.GOLD.toColor(), true, true)
- event.drawDynamicText(location.add(0, 1, 0), TrevorSolver.mobLocation.location, 1.5)
+ event.drawDynamicText(location.add(y = 1), TrevorSolver.mobLocation.location, 1.5)
}
}
}
@@ -302,4 +304,11 @@ object TrevorFeatures {
fun onFarmingIsland() = IslandType.THE_FARMING_ISLANDS.isInIsland()
fun inTrapperDen() = ScoreboardData.sidebarLinesFormatted.contains(" §7⏣ §bTrapper's Den")
+
+ @SubscribeEvent
+ fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
+ event.move(11, "misc.trevorTheTrapper.textFormat", "misc.trevorTheTrapper.textFormat") { element ->
+ ConfigUtils.migrateIntArrayListToEnumArrayList(element, TrackerEntry::class.java)
+ }
+ }
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorTracker.kt
index 59d44b1b7..175d21903 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorTracker.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorTracker.kt
@@ -59,13 +59,13 @@ object TrevorTracker {
peltsPerSecond.clear()
peltsPerHour = 0
stoppedChecks = 0
- saveAndUpdate()
}
private fun formatDisplay(map: List<List<Any>>): List<List<Any>> {
val newList = mutableListOf<List<Any>>()
for (index in config.textFormat) {
- newList.add(map[index])
+ // TODO, change functionality to use enum rather than ordinals
+ newList.add(map[index.ordinal])
}
return newList
}
@@ -80,14 +80,14 @@ object TrevorTracker {
val pelts = matcher.group("pelts").toInt()
storage.peltsGained += pelts
storage.selfKillingAnimals += 1
- saveAndUpdate()
+ update()
}
matcher = killMobPattern.matcher(event.message)
if (matcher.matches()) {
val pelts = matcher.group("pelts").toInt()
storage.peltsGained += pelts
storage.killedAnimals += 1
- saveAndUpdate()
+ update()
}
}
@@ -98,10 +98,10 @@ object TrevorTracker {
val foundRarity = TrapperMobRarity.entries.firstOrNull { it.formattedName == rarity } ?: return
val old = storage.animalRarities[foundRarity] ?: 0
storage.animalRarities = storage.animalRarities.editCopy { this[foundRarity] = old + 1 }
- saveAndUpdate()
+ update()
}
- fun saveAndUpdate() {
+ fun update() {
val storage = ProfileStorageData.profileSpecific?.trapperData ?: return
display = formatDisplay(drawTrapperDisplay(storage))
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazingSouls.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazingSouls.kt
index 8d7507e12..03175e255 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazingSouls.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazingSouls.kt
@@ -48,7 +48,7 @@ class AshfangBlazingSouls {
event.drawWaypointFilled(orbLocation.add(-0.5, 1.25, -0.5), color, extraSize = -0.15)
if (orbLocation.distance(playerLocation) < 10) {
//TODO find way to dynamically change color
- event.drawString(orbLocation.add(0.0, 2.5, 0.0), "§bBlazing Soul")
+ event.drawString(orbLocation.add(y = 2.5), "§bBlazing Soul")
}
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangFreezeCooldown.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangFreezeCooldown.kt
index 5fd7a3b77..447884c05 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangFreezeCooldown.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangFreezeCooldown.kt
@@ -8,13 +8,16 @@ import at.hannibal2.skyhanni.features.combat.damageindicator.BossType
import at.hannibal2.skyhanni.features.combat.damageindicator.DamageIndicatorManager
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.RenderUtils.renderString
-import at.hannibal2.skyhanni.utils.StringUtils.matchRegex
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.TimeUtils
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class AshfangFreezeCooldown {
private val config get() = SkyHanniMod.feature.crimsonIsle.ashfang
+ // TODO USE SH-REPO
+ private val cryogenicBlastPattern = "§cAshfang Follower's Cryogenic Blast hit you for (.*) damage!".toPattern()
+
private var lastHit = 0L
@SubscribeEvent
@@ -22,7 +25,7 @@ class AshfangFreezeCooldown {
if (!isEnabled()) return
val message = event.message
- if (message.matchRegex("§cAshfang Follower's Cryogenic Blast hit you for (.*) damage!")) {
+ cryogenicBlastPattern.matchMatcher(message) {
lastHit = System.currentTimeMillis()
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangGravityOrbs.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangGravityOrbs.kt
index 5b3fc60de..bf9899e0c 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangGravityOrbs.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangGravityOrbs.kt
@@ -49,7 +49,7 @@ class AshfangGravityOrbs {
if (orbLocation.distance(playerLocation) < 15) {
//TODO find way to dynamically change color
- event.drawString(orbLocation.add(0.0, 2.5, 0.0), "§cGravity Orb")
+ event.drawString(orbLocation.add(y = 2.5), "§cGravity Orb")
}
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/CrimsonIsleReputationHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/CrimsonIsleReputationHelper.kt
index ec03ad514..d6f8d8e05 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/CrimsonIsleReputationHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/CrimsonIsleReputationHelper.kt
@@ -19,7 +19,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland
import at.hannibal2.skyhanni.utils.LorenzVec
import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
import at.hannibal2.skyhanni.utils.TabListData
-import at.hannibal2.skyhanni.utils.jsonobjects.CrimsonIsleReputationJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.CrimsonIsleReputationJson
import net.minecraftforge.fml.common.eventhandler.EventPriority
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailykuudra/DailyKuudraBossHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailykuudra/DailyKuudraBossHelper.kt
index a14da5859..bf88fb865 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailykuudra/DailyKuudraBossHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailykuudra/DailyKuudraBossHelper.kt
@@ -13,7 +13,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
import at.hannibal2.skyhanni.utils.LorenzVec
import at.hannibal2.skyhanni.utils.NEUItems
import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText
-import at.hannibal2.skyhanni.utils.jsonobjects.CrimsonIsleReputationJson.ReputationQuest
+import at.hannibal2.skyhanni.data.jsonobjects.repo.CrimsonIsleReputationJson.ReputationQuest
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class DailyKuudraBossHelper(private val reputationHelper: CrimsonIsleReputationHelper) {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/QuestLoader.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/QuestLoader.kt
index 6184fd51e..47a8716fd 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/QuestLoader.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/QuestLoader.kt
@@ -15,7 +15,7 @@ import at.hannibal2.skyhanni.features.nether.reputationhelper.dailyquest.quest.U
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.TabListData
-import at.hannibal2.skyhanni.utils.jsonobjects.CrimsonIsleReputationJson.ReputationQuest
+import at.hannibal2.skyhanni.data.jsonobjects.repo.CrimsonIsleReputationJson.ReputationQuest
class QuestLoader(private val dailyQuestHelper: DailyQuestHelper) {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/DailyMiniBossHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/DailyMiniBossHelper.kt
index 52f5c23f4..87ab3ae5f 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/DailyMiniBossHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/DailyMiniBossHelper.kt
@@ -16,7 +16,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
import at.hannibal2.skyhanni.utils.NEUItems.getItemStack
import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
-import at.hannibal2.skyhanni.utils.jsonobjects.CrimsonIsleReputationJson.ReputationQuest
+import at.hannibal2.skyhanni.data.jsonobjects.repo.CrimsonIsleReputationJson.ReputationQuest
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class DailyMiniBossHelper(private val reputationHelper: CrimsonIsleReputationHelper) {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/RiftAgaricusCap.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/RiftAgaricusCap.kt
index 5ef56976f..c1790a6cc 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/RiftAgaricusCap.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/RiftAgaricusCap.kt
@@ -59,7 +59,7 @@ class RiftAgaricusCap {
fun onRenderWorld(event: LorenzRenderWorldEvent) {
if (!isEnabled()) return
- val location = location?.add(0.0, 0.6, 0.0) ?: return
+ val location = location?.add(y = 0.6) ?: return
if (startTime == -1L) {
event.drawDynamicText(location, "§cClick!", 1.5)
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/RiftWiltedBerberisHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/RiftWiltedBerberisHelper.kt
index e17bd32ed..aa1dafd55 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/RiftWiltedBerberisHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/RiftWiltedBerberisHelper.kt
@@ -43,7 +43,7 @@ class RiftWiltedBerberisHelper {
hasFarmingToolInHand = InventoryUtils.getItemInHand()?.getInternalName() == RiftAPI.farmingTool
if (Minecraft.getMinecraft().thePlayer.onGround) {
- val block = LocationUtils.playerLocation().add(0, -1, 0).getBlockAt().toString()
+ val block = LocationUtils.playerLocation().add(y = -1).getBlockAt().toString()
val currentY = LocationUtils.playerLocation().y
isOnFarmland = block == "Block{minecraft:farmland}" && (currentY % 1 == 0.0)
}
@@ -115,7 +115,7 @@ class RiftWiltedBerberisHelper {
val location = currentParticles.fixLocation(berberis)
if (!moving) {
event.drawFilledBoundingBox_nea(axisAlignedBB(location), Color.YELLOW, 0.7f)
- event.drawDynamicText(location.add(0, 1, 0), "§eWilted Berberis", 1.5, ignoreBlocks = false)
+ event.drawDynamicText(location.add(y = 1), "§eWilted Berberis", 1.5, ignoreBlocks = false)
} else {
event.drawFilledBoundingBox_nea(axisAlignedBB(location), Color.WHITE, 0.5f)
previous?.fixLocation(berberis)?.let {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/VoltHighlighter.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/VoltHighlighter.kt
index 6cf37e285..41d42f77b 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/VoltHighlighter.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/dreadfarm/VoltHighlighter.kt
@@ -75,7 +75,7 @@ class VoltHighlighter {
val dischargeTimeLeft = CHARGE_TIME - dischargingSince.passedSince()
if (dischargeTimeLeft > Duration.ZERO) {
event.drawDynamicText(
- event.exactLocation(entity).add(0.0, 2.5, 0.0),
+ event.exactLocation(entity).add(y = 2.5),
"§eLightning: ${dischargeTimeLeft.format(showMilliSeconds = true)}",
2.5
)
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/livingcave/LivingCaveDefenseBlocks.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/livingcave/LivingCaveDefenseBlocks.kt
index 88b2939c8..071ec6e94 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/livingcave/LivingCaveDefenseBlocks.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/livingcave/LivingCaveDefenseBlocks.kt
@@ -147,7 +147,7 @@ class LivingCaveDefenseBlocks {
val location = block.location
event.drawWaypointFilled(location, color)
event.draw3DLine(
- block.entity.getLorenzVec().add(0.0, 0.5, 0.0),
+ block.entity.getLorenzVec().add(y = 0.5),
location.add(0.5, 0.5, 0.5),
color,
1,
@@ -161,7 +161,7 @@ class LivingCaveDefenseBlocks {
event.drawWaypointFilled(location, color)
event.draw3DLine(
- block.entity.getLorenzVec().add(0.0, 0.5, 0.0),
+ block.entity.getLorenzVec().add(y = 0.5),
location.add(0.5, 0.5, 0.5),
color,
3,
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/DanceRoomHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/DanceRoomHelper.kt
index 524e1b354..a2b337668 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/DanceRoomHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/DanceRoomHelper.kt
@@ -12,7 +12,7 @@ import at.hannibal2.skyhanni.features.rift.RiftAPI
import at.hannibal2.skyhanni.utils.LocationUtils.isPlayerInside
import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings
import at.hannibal2.skyhanni.utils.StringUtils.firstLetterUppercase
-import at.hannibal2.skyhanni.utils.jsonobjects.DanceRoomInstructionsJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.DanceRoomInstructionsJson
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/RiftLavaMazeParkour.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/RiftLavaMazeParkour.kt
index efaf77163..2ffcb7928 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/RiftLavaMazeParkour.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/RiftLavaMazeParkour.kt
@@ -9,7 +9,7 @@ import at.hannibal2.skyhanni.features.rift.RiftAPI
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.toChromaColor
import at.hannibal2.skyhanni.utils.ParkourHelper
-import at.hannibal2.skyhanni.utils.jsonobjects.ParkourJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.ParkourJson
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class RiftLavaMazeParkour {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/RiftUpsideDownParkour.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/RiftUpsideDownParkour.kt
index 18a09709d..1826a5e38 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/RiftUpsideDownParkour.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/RiftUpsideDownParkour.kt
@@ -9,7 +9,7 @@ import at.hannibal2.skyhanni.features.rift.RiftAPI
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.toChromaColor
import at.hannibal2.skyhanni.utils.ParkourHelper
-import at.hannibal2.skyhanni.utils.jsonobjects.ParkourJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.ParkourJson
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class RiftUpsideDownParkour {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/TubulatorParkour.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/TubulatorParkour.kt
index 567f2bf2e..281643bfc 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/TubulatorParkour.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/mirrorverse/TubulatorParkour.kt
@@ -9,7 +9,7 @@ import at.hannibal2.skyhanni.utils.LocationUtils.isPlayerInside
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.toChromaColor
import at.hannibal2.skyhanni.utils.ParkourHelper
-import at.hannibal2.skyhanni.utils.jsonobjects.ParkourJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.ParkourJson
import net.minecraft.util.AxisAlignedBB
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/stillgorechateau/RiftBloodEffigies.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/stillgorechateau/RiftBloodEffigies.kt
index d10aac4ca..9fc00b99a 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/area/stillgorechateau/RiftBloodEffigies.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/stillgorechateau/RiftBloodEffigies.kt
@@ -19,7 +19,7 @@ import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.TimeUtils
import at.hannibal2.skyhanni.utils.getLorenzVec
-import at.hannibal2.skyhanni.utils.jsonobjects.RiftEffigiesJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.RiftEffigiesJson
import net.minecraft.entity.item.EntityArmorStand
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/EnigmaSoulWaypoints.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/EnigmaSoulWaypoints.kt
index 983df0d88..f8ceaa833 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/EnigmaSoulWaypoints.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/EnigmaSoulWaypoints.kt
@@ -1,5 +1,6 @@
package at.hannibal2.skyhanni.features.rift.everywhere
+import at.hannibal2.skyhanni.data.jsonobjects.repo.EnigmaSoulsJson
import at.hannibal2.skyhanni.events.GuiContainerEvent
import at.hannibal2.skyhanni.events.InventoryCloseEvent
import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
@@ -17,7 +18,6 @@ import at.hannibal2.skyhanni.utils.NEUItems
import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText
import at.hannibal2.skyhanni.utils.RenderUtils.highlight
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
-import at.hannibal2.skyhanni.utils.jsonobjects.EnigmaSoulsJson
import io.github.moulberry.notenoughupdates.events.ReplaceItemEvent
import io.github.moulberry.notenoughupdates.events.SlotClickEvent
import io.github.moulberry.notenoughupdates.util.Utils
@@ -137,7 +137,7 @@ object EnigmaSoulWaypoints {
for (soul in trackedSouls) {
soulLocations[soul]?.let {
event.drawWaypointFilled(it, LorenzColor.DARK_PURPLE.toColor(), seeThroughBlocks = true, beacon = true)
- event.drawDynamicText(it.add(0, 1, 0), "§5$soul Soul", 1.5)
+ event.drawDynamicText(it.add(y = 1), "§5$soul Soul", 1.5)
}
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/motes/ShowMotesNpcSellPrice.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/motes/ShowMotesNpcSellPrice.kt
index 53b7b56f9..47c002c92 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/motes/ShowMotesNpcSellPrice.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/motes/ShowMotesNpcSellPrice.kt
@@ -156,7 +156,7 @@ class ShowMotesNpcSellPrice {
add("§6Value per: §d$valuePer Motes")
add("§6Total in chest: §d${(value / valuePer).toInt()}")
add("")
- add("§6Total value: §d$price")
+ add("§6Total value: §d$price coins")
}
add(Renderable.hoverTips("§6${stack.displayName}: §b$price", tips, indexes = index, stack = stack))
})
diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/HideMobNames.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/HideMobNames.kt
index 34a98bb43..eee256884 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/slayer/HideMobNames.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/HideMobNames.kt
@@ -17,7 +17,7 @@ class HideMobNames {
private val patterns = mutableListOf<Pattern>()
init {
- addMobToHide("Zombie")
+ // TODO USE SH-REPO
addMobToHide("Zombie")
addMobToHide("Zombie Villager")
addMobToHide("Crypt Ghoul")
@@ -84,4 +84,4 @@ class HideMobNames {
return false
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerBossSpawnSoon.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerBossSpawnSoon.kt
index 2bfdf640f..c5fd182db 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerBossSpawnSoon.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerBossSpawnSoon.kt
@@ -14,7 +14,7 @@ import kotlin.time.Duration.Companion.seconds
class SlayerBossSpawnSoon {
private val config get() = SkyHanniMod.feature.slayer.slayerBossWarning
- private val pattern = " \\(?(?<progress>[0-9.,k]+)\\/(?<total>[0-9.,k]+)\\)?.*".toPattern()
+ private val pattern = " \\(?(?<progress>[0-9.,k]+)/(?<total>[0-9.,k]+)\\)?.*".toPattern()
private var lastCompletion = 0f
private var warned = false
diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemsOnGround.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemsOnGround.kt
index 0cb129c7d..f0f80ace4 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemsOnGround.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemsOnGround.kt
@@ -32,7 +32,7 @@ class SlayerItemsOnGround {
if (!SlayerAPI.hasActiveSlayerQuest()) return
for (entityItem in EntityUtils.getEntities<EntityItem>()) {
- val location = event.exactLocation(entityItem).add(0.0, 0.8, 0.0)
+ val location = event.exactLocation(entityItem).add(y = 0.8)
if (location.distance(LocationUtils.playerLocation()) > 15) continue
val itemStack = entityItem.entityItem
diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerMiniBossFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerMiniBossFeatures.kt
index f45d352b5..e384b5de8 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerMiniBossFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerMiniBossFeatures.kt
@@ -60,7 +60,7 @@ class SlayerMiniBossFeatures {
event.draw3DLine(
event.exactPlayerEyeLocation(),
- mob.getLorenzVec().add(0, 1, 0),
+ mob.getLorenzVec().add(y = 1),
LorenzColor.AQUA.toColor(),
3,
true
diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt
index c05839ba6..52e27d305 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt
@@ -1,108 +1,76 @@
package at.hannibal2.skyhanni.features.slayer
import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.config.Storage
import at.hannibal2.skyhanni.data.SlayerAPI
import at.hannibal2.skyhanni.events.GuiRenderEvent
-import at.hannibal2.skyhanni.events.LorenzChatEvent
+import at.hannibal2.skyhanni.events.ItemAddEvent
import at.hannibal2.skyhanni.events.PurseChangeCause
import at.hannibal2.skyhanni.events.PurseChangeEvent
import at.hannibal2.skyhanni.events.RepositoryReloadEvent
-import at.hannibal2.skyhanni.events.SackChangeEvent
import at.hannibal2.skyhanni.events.SlayerChangeEvent
import at.hannibal2.skyhanni.events.SlayerQuestCompleteEvent
-import at.hannibal2.skyhanni.events.entity.ItemAddInInventoryEvent
-import at.hannibal2.skyhanni.features.bazaar.BazaarApi.Companion.getBazaarData
-import at.hannibal2.skyhanni.test.PriceSource
-import at.hannibal2.skyhanni.utils.KeyboardManager
import at.hannibal2.skyhanni.utils.LorenzLogger
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
-import at.hannibal2.skyhanni.utils.LorenzUtils.addSelector
-import at.hannibal2.skyhanni.utils.LorenzUtils.sortedDesc
import at.hannibal2.skyhanni.utils.NEUInternalName
-import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
-import at.hannibal2.skyhanni.utils.NEUItems.getNpcPriceOrNull
-import at.hannibal2.skyhanni.utils.NEUItems.getPriceOrNull
import at.hannibal2.skyhanni.utils.NumberUtil
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
-import at.hannibal2.skyhanni.utils.SimpleTimeMark
-import at.hannibal2.skyhanni.utils.StringUtils
-import at.hannibal2.skyhanni.utils.StringUtils.matches
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
-import at.hannibal2.skyhanni.utils.jsonobjects.SlayerProfitTrackerItemsJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.SlayerProfitTrackerItemsJson
import at.hannibal2.skyhanni.utils.renderables.Renderable
-import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker
-import at.hannibal2.skyhanni.utils.tracker.TrackerData
+import at.hannibal2.skyhanni.utils.tracker.ItemTrackerData
+import at.hannibal2.skyhanni.utils.tracker.SkyHanniItemTracker
+import com.google.gson.JsonObject
+import com.google.gson.JsonPrimitive
import com.google.gson.annotations.Expose
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds
object SlayerProfitTracker {
private val config get() = SkyHanniMod.feature.slayer.itemProfitTracker
- private val diceRollChatPattern =
- "§eYour §r§(5|6High Class )Archfiend Dice §r§erolled a §r§.(?<number>.)§r§e! Bonus: §r§.(?<hearts>.*)❤".toPattern()
-
- private val ARCHFIEND_DICE = "ARCHFIEND_DICE".asInternalName()
- private val HIGH_CLASS_ARCHFIEND_DICE = "HIGH_CLASS_ARCHFIEND_DICE".asInternalName()
-
private var itemLogCategory = ""
private var baseSlayerType = ""
private val logger = LorenzLogger("slayer/profit_tracker")
- private var lastClickDelay = 0L
- private val trackers = mutableMapOf<String, SkyHanniTracker<Data>>()
+ private val trackers = mutableMapOf<String, SkyHanniItemTracker<Data>>()
- class Data : TrackerData() {
- override fun reset() {
- items.clear()
- mobKillCoins = 0
+ class Data : ItemTrackerData() {
+ override fun resetItems() {
slayerSpawnCost = 0
slayerCompletedCount = 0
}
@Expose
- var items: MutableMap<NEUInternalName, SlayerItem> = HashMap()
-
- @Expose
- var mobKillCoins: Long = 0
-
- @Expose
var slayerSpawnCost: Long = 0
@Expose
var slayerCompletedCount = 0
- class SlayerItem {
- @Expose
- var internalName: NEUInternalName? = null
-
- @Expose
- var timesDropped: Long = 0
+ override fun getDescription(timesDropped: Long): List<String> {
+ val percentage = timesDropped.toDouble() / slayerCompletedCount
+ val perBoss = LorenzUtils.formatPercentage(percentage.coerceAtMost(1.0))
- @Expose
- var totalAmount: Long = 0
+ return listOf(
+ "§7Dropped §e${timesDropped.addSeparators()} §7times.",
+ "§7Your drop rate: §c$perBoss",
+ )
+ }
- @Expose
- var hidden = false
+ override fun getCoinName(item: TrackedItem) = "§6Mob Kill Coins"
- override fun toString() = "SlayerItem{" +
- "internalName='" + internalName + '\'' +
- ", timesDropped=" + timesDropped +
- ", totalAmount=" + totalAmount +
- ", hidden=" + hidden +
- '}'
+ override fun getCoinDescription(item: TrackedItem): List<String> {
+ val mobKillCoinsFormat = NumberUtil.format(item.totalAmount)
+ return listOf(
+ "§7Killing mobs gives you coins (more with scavenger).",
+ "§7You got §6$mobKillCoinsFormat coins §7way."
+ )
}
-
- override fun toString() = "SlayerProfitTracker.Data{" +
- "items=" + items +
- ", mobKillCoins=" + mobKillCoins +
- ", slayerSpawnCost=" + slayerSpawnCost +
- ", slayerCompletedCount=" + slayerCompletedCount +
- '}'
}
+ private val ItemTrackerData.TrackedItem.timesDropped get() = timesGained
+
private fun addSlayerCosts(price: Int) {
getTracker()?.modify {
it.slayerSpawnCost += price
@@ -139,21 +107,14 @@ object SlayerProfitTracker {
}
private fun addMobKillCoins(coins: Int) {
- getTracker()?.modify {
- it.mobKillCoins += coins
- }
+ getTracker()?.addCoins(coins)
}
private fun addItemPickup(internalName: NEUInternalName, stackSize: Int) {
- getTracker()?.modify {
- val slayerItem = it.items.getOrPut(internalName) { Data.SlayerItem() }
-
- slayerItem.timesDropped++
- slayerItem.totalAmount += stackSize
- }
+ getTracker()?.addItem(internalName, stackSize)
}
- private fun getTracker(): SkyHanniTracker<Data>? {
+ private fun getTracker(): SkyHanniItemTracker<Data>? {
if (itemLogCategory == "") return null
return trackers.getOrPut(itemLogCategory) {
@@ -162,7 +123,7 @@ object SlayerProfitTracker {
itemLogCategory
) { Data() }
}
- SkyHanniTracker("$itemLogCategory Profit Tracker", { Data() }, getStorage) { drawDisplay(it) }
+ SkyHanniItemTracker("$itemLogCategory Profit Tracker", { Data() }, getStorage) { drawDisplay(it) }
}
}
@@ -174,46 +135,14 @@ object SlayerProfitTracker {
}
@SubscribeEvent
- fun onSackChange(event: SackChangeEvent) {
- if (!isEnabled()) return
- if (!SlayerAPI.isInCorrectArea) return
- if (!SlayerAPI.hasActiveSlayerQuest()) return
-
- for (sackChange in event.sackChanges) {
- val change = sackChange.delta
- if (change > 0) {
- val internalName = sackChange.internalName
- addItem(internalName, change)
- }
- }
- }
-
- @SubscribeEvent
- fun onItemAdd(event: ItemAddInInventoryEvent) {
+ fun onItemAdd(event: ItemAddEvent) {
if (!isEnabled()) return
if (!SlayerAPI.isInCorrectArea) return
if (!SlayerAPI.hasActiveSlayerQuest()) return
val internalName = event.internalName
- if (internalName == ARCHFIEND_DICE || internalName == HIGH_CLASS_ARCHFIEND_DICE) {
- if (lastDiceRoll.passedSince() < 500.milliseconds) {
- return
- }
- }
-
- addItem(internalName, event.amount)
- }
-
- private var lastDiceRoll = SimpleTimeMark.farPast()
-
- @SubscribeEvent
- fun onChat(event: LorenzChatEvent) {
- if (diceRollChatPattern.matches(event.message)) {
- lastDiceRoll = SimpleTimeMark.now()
- }
- }
+ val amount = event.amount
- private fun addItem(internalName: NEUInternalName, amount: Int) {
if (!isAllowedItem(internalName)) {
LorenzUtils.debug("Ignored non-slayer item pickup: '$internalName' '$itemLogCategory'")
return
@@ -239,82 +168,19 @@ object SlayerProfitTracker {
val tracker = getTracker() ?: return@buildList
addAsSingletonList("§e§l$itemLogCategory Profit Tracker")
- var profit = 0.0
- val map = mutableMapOf<Renderable, Long>()
- for ((internalName, itemProfit) in itemLog.items) {
- val amount = itemProfit.totalAmount
-
- val price = (getPrice(internalName) * amount).toLong()
-
- val cleanName = SlayerAPI.getNameWithEnchantmentFor(internalName)
- var name = cleanName
- val priceFormat = NumberUtil.format(price)
- val hidden = itemProfit.hidden
- if (hidden) {
- while (name.startsWith("§f")) {
- name = name.substring(2)
- }
- name = StringUtils.addFormat(name, "§m")
- }
- val text = " §7${amount.addSeparators()}x $name§7: §6$priceFormat"
-
- val timesDropped = itemProfit.timesDropped
- val percentage = timesDropped.toDouble() / itemLog.slayerCompletedCount
- val perBoss = LorenzUtils.formatPercentage(percentage.coerceAtMost(1.0))
-
- val renderable = if (tracker.isInventoryOpen()) Renderable.clickAndHover(
- text, listOf(
- "§7Dropped §e${timesDropped.addSeparators()} §7times.",
- "§7Your drop rate: §c$perBoss",
- "",
- "§eClick to " + (if (hidden) "show" else "hide") + "!",
- "§eControl + Click to remove this item!",
- )
- ) {
- if (System.currentTimeMillis() > lastClickDelay + 150) {
-
- if (KeyboardManager.isControlKeyDown()) {
- itemLog.items.remove(internalName)
- LorenzUtils.chat("Removed $cleanName §efrom slayer profit display.")
- lastClickDelay = System.currentTimeMillis() + 500
- } else {
- itemProfit.hidden = !hidden
- lastClickDelay = System.currentTimeMillis()
- }
- tracker.update()
- }
- } else Renderable.string(text)
- if (tracker.isInventoryOpen() || !hidden) {
- map[renderable] = price
- }
- profit += price
- }
- val mobKillCoins = itemLog.mobKillCoins
- if (mobKillCoins != 0L) {
- val mobKillCoinsFormat = NumberUtil.format(mobKillCoins)
- map[Renderable.hoverTips(
- " §7Mob kill coins: §6$mobKillCoinsFormat",
- listOf(
- "§7Killing mobs gives you coins (more with scavenger)",
- "§7You got §e$mobKillCoinsFormat §7coins in total this way"
- )
- )] = mobKillCoins
- profit += mobKillCoins
- }
+ var profit = tracker.drawItems(itemLog, { true }, this)
val slayerSpawnCost = itemLog.slayerSpawnCost
if (slayerSpawnCost != 0L) {
val mobKillCoinsFormat = NumberUtil.format(slayerSpawnCost)
- map[Renderable.hoverTips(
- " §7Slayer Spawn Costs: §c$mobKillCoinsFormat",
- listOf("§7You paid §c$mobKillCoinsFormat §7in total", "§7for starting the slayer quests.")
- )] = slayerSpawnCost
+ addAsSingletonList(
+ Renderable.hoverTips(
+ " §7Slayer Spawn Costs: §c$mobKillCoinsFormat",
+ listOf("§7You paid §c$mobKillCoinsFormat §7in total", "§7for starting the slayer quests.")
+ )
+ )
profit += slayerSpawnCost
}
- for (text in map.sortedDesc().keys) {
- addAsSingletonList(text)
- }
-
val slayerCompletedCount = itemLog.slayerCompletedCount
addAsSingletonList(
Renderable.hoverTips(
@@ -329,27 +195,21 @@ object SlayerProfitTracker {
val profitPerBoss = profit / itemLog.slayerCompletedCount
val profitPerBossFormat = NumberUtil.format(profitPerBoss)
- val text = "§eTotal Profit: $profitPrefix$profitFormat"
+ val text = "§eTotal Profit: $profitPrefix$profitFormat coins"
addAsSingletonList(Renderable.hoverTips(text, listOf("§7Profit per boss: $profitPrefix$profitPerBossFormat")))
- if (tracker.isInventoryOpen()) {
- addSelector<PriceSource>(
- "",
- getName = { type -> type.displayName },
- isCurrent = { it.ordinal == config.priceFrom },
- onChange = {
- config.priceFrom = it.ordinal
- tracker.update()
- }
- )
- }
+ tracker.addPriceFromButton(this)
}
- private fun getPrice(internalName: NEUInternalName) = when (config.priceFrom) {
- 0 -> internalName.getBazaarData()?.sellPrice ?: internalName.getPriceOrNull() ?: 0.0
- 1 -> internalName.getBazaarData()?.buyPrice ?: internalName.getPriceOrNull() ?: 0.0
+ val coinFormat: (ItemTrackerData.TrackedItem) -> Pair<String, List<String>> = { item ->
+ val mobKillCoinsFormat = NumberUtil.format(item.totalAmount)
+ val text = " §6Mob kill coins§7: §6$mobKillCoinsFormat"
+ val lore = listOf(
+ "§7Killing mobs gives you coins (more with scavenger)",
+ "§7You got §e$mobKillCoinsFormat §7coins in total this way"
+ )
- else -> internalName.getNpcPriceOrNull() ?: 0.0
+ text to lore
}
@SubscribeEvent
@@ -360,6 +220,29 @@ object SlayerProfitTracker {
getTracker()?.renderDisplay(config.pos)
}
+ @SubscribeEvent
+ fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
+ event.move(10, "#profile.slayerProfitData", "#profile.slayerProfitData") { old ->
+ for (data in old.asJsonObject.entrySet().map { it.value.asJsonObject }) {
+ val items = data.get("items").asJsonObject
+ for (item in items.entrySet().map { it.value.asJsonObject }) {
+ val oldValue = item.get("timesDropped")
+ item.add("timesGained", oldValue)
+ }
+
+ val coinAmount = data.get("mobKillCoins")
+ val coins = JsonObject()
+ coins.add("internalName", JsonPrimitive("SKYBLOCK_COIN"))
+ coins.add("timesDropped", JsonPrimitive(1))
+ coins.add("totalAmount", coinAmount)
+ items.add("SKYBLOCK_COIN", coins)
+ }
+
+ old
+ }
+
+ }
+
fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled
fun clearProfitCommand(args: Array<String>) {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerQuestWarning.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerQuestWarning.kt
index 728896e22..52eb9f806 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerQuestWarning.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerQuestWarning.kt
@@ -9,7 +9,7 @@ import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
import at.hannibal2.skyhanni.utils.LocationUtils.distanceToPlayer
import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.StringUtils.matchRegex
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import at.hannibal2.skyhanni.utils.getLorenzVec
import net.minecraft.entity.EntityLivingBase
@@ -18,6 +18,7 @@ import kotlin.time.Duration.Companion.seconds
class SlayerQuestWarning {
private val config get() = SkyHanniMod.feature.slayer
+ private val talkToMaddoxPattern = " {3}§r§5§l» §r§7Talk to Maddox to claim your (.+) Slayer XP!".toPattern()
private var needSlayerQuest = false
private var lastWarning = 0L
private var currentReason = ""
@@ -43,7 +44,7 @@ class SlayerQuestWarning {
}
//no auto slayer
- if (message.matchRegex(" §r§5§l» §r§7Talk to Maddox to claim your (.+) Slayer XP!")) {
+ talkToMaddoxPattern.matchMatcher(message) {
needNewQuest("You have no Auto-Slayer active!")
}
if (message == " §r§a§lSLAYER QUEST COMPLETE!") {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerRngMeterDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerRngMeterDisplay.kt
index b26fd4c09..239935368 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerRngMeterDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerRngMeterDisplay.kt
@@ -28,7 +28,7 @@ class SlayerRngMeterDisplay {
private val config get() = SkyHanniMod.feature.slayer.rngMeterDisplay
private var display = ""
private val inventoryNamePattern = "(?<name>.*) RNG Meter".toPattern()
- private val updatePattern = " §dRNG Meter §f- §d(?<exp>.*) Stored XP".toPattern()
+ private val updatePattern = " {3}§dRNG Meter §f- §d(?<exp>.*) Stored XP".toPattern()
private val changedItemPattern = "§aYou set your §r.* RNG Meter §r§ato drop §r.*§a!".toPattern()
private var lastItemDroppedTime = 0L
diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/VampireSlayerFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/VampireSlayerFeatures.kt
index 59ca5b075..e1f837a7b 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/slayer/VampireSlayerFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/VampireSlayerFeatures.kt
@@ -12,6 +12,7 @@ import at.hannibal2.skyhanni.events.withAlpha
import at.hannibal2.skyhanni.features.rift.RiftAPI
import at.hannibal2.skyhanni.mixins.hooks.RenderLivingEntityHelper
import at.hannibal2.skyhanni.test.GriffinUtils.drawWaypointFilled
+import at.hannibal2.skyhanni.utils.DelayedRun
import at.hannibal2.skyhanni.utils.EntityUtils
import at.hannibal2.skyhanni.utils.EntityUtils.canBeSeen
import at.hannibal2.skyhanni.utils.EntityUtils.getAllNameTagsInRadiusWith
@@ -23,7 +24,6 @@ import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.baseMaxHealth
import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy
import at.hannibal2.skyhanni.utils.LorenzUtils.toChromaColor
-import at.hannibal2.skyhanni.utils.MinecraftDispatcher
import at.hannibal2.skyhanni.utils.RenderUtils.draw3DLine
import at.hannibal2.skyhanni.utils.RenderUtils.drawColor
import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText
@@ -36,7 +36,6 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
import net.minecraft.client.Minecraft
import net.minecraft.client.entity.EntityOtherPlayerMP
import net.minecraft.client.renderer.GlStateManager
@@ -136,21 +135,18 @@ object VampireSlayerFeatures {
else taggedEntityList.contains(this.entityId) && configOtherBoss.twinClawsSound
if (shouldSendTitle || shouldSendSound) {
- SkyHanniMod.coroutineScope.launch {
- delay(config.twinclawsDelay.milliseconds)
- withContext(MinecraftDispatcher) {
- if (nextClawSend < System.currentTimeMillis()) {
- if (shouldSendSound)
- playTwinclawsSound()
- if (shouldSendTitle) {
- LorenzUtils.sendTitle(
- "§6§lTWINCLAWS",
- (1750 - config.twinclawsDelay).milliseconds,
- 2.6
- )
- }
- nextClawSend = System.currentTimeMillis() + 5_000
+ DelayedRun.runDelayed(config.twinclawsDelay.milliseconds) {
+ if (nextClawSend < System.currentTimeMillis()) {
+ if (shouldSendSound)
+ playTwinclawsSound()
+ if (shouldSendTitle) {
+ LorenzUtils.sendTitle(
+ "§6§lTWINCLAWS",
+ (1750 - config.twinclawsDelay).milliseconds,
+ 2.6
+ )
}
+ nextClawSend = System.currentTimeMillis() + 5_000
}
}
}
@@ -295,7 +291,7 @@ object VampireSlayerFeatures {
if (distance <= 15) {
event.draw3DLine(
event.exactPlayerEyeLocation(),
- vec.add(0.0, 1.54, 0.0),
+ vec.add(y = 1.54),
config.lineColor.toChromaColor(),
config.lineWidth,
true
@@ -323,7 +319,7 @@ object VampireSlayerFeatures {
(if (isIchor) configBloodIcor.linesColor else configKillerSpring.linesColor).toChromaColor()
val text = if (isIchor) "§4Ichor" else "§4Spring"
event.drawColor(
- stand.position.toLorenzVec().add(0.0, 2.0, 0.0),
+ stand.position.toLorenzVec().add(y = 2.0),
LorenzColor.DARK_RED,
alpha = 1f
)
@@ -336,8 +332,8 @@ object VampireSlayerFeatures {
for ((player, stand2) in standList) {
if ((configBloodIcor.showLines && isIchor) || (configKillerSpring.showLines && isSpring))
event.draw3DLine(
- event.exactLocation(player).add(0.0, 1.5, 0.0),
- event.exactLocation(stand2).add(0.0, 1.5, 0.0),
+ event.exactLocation(player).add(y = 1.5),
+ event.exactLocation(stand2).add(y = 1.5),
// stand2.position.toLorenzVec().add(0.0, 1.5, 0.0),
linesColorStart,
3,
@@ -347,7 +343,7 @@ object VampireSlayerFeatures {
}
if (configBloodIcor.renderBeam && isIchor && stand.isEntityAlive) {
event.drawWaypointFilled(
- event.exactLocation(stand).add(0, -2, 0),
+ event.exactLocation(stand).add(0, y = -2, 0),
configBloodIcor.color.toChromaColor(),
beacon = true
)
diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/blaze/BlazeSlayerDaggerHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/blaze/BlazeSlayerDaggerHelper.kt
index 0e9b9f8ae..260d7d4d6 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/slayer/blaze/BlazeSlayerDaggerHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/blaze/BlazeSlayerDaggerHelper.kt
@@ -14,7 +14,7 @@ import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LocationUtils
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.RenderUtils.renderString
-import at.hannibal2.skyhanni.utils.StringUtils.matchRegex
+import at.hannibal2.skyhanni.utils.StringUtils.matches
import at.hannibal2.skyhanni.utils.getLorenzVec
import net.minecraft.client.Minecraft
import net.minecraft.item.ItemStack
@@ -22,6 +22,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class BlazeSlayerDaggerHelper {
private val config get() = SkyHanniMod.feature.slayer.blazes.hellion
+ private val attunementPattern = "§cStrike using the §r(.+) §r§cattunement on your dagger!".toPattern()
private var clientSideClicked = false
private var textTop = ""
@@ -34,12 +35,10 @@ class BlazeSlayerDaggerHelper {
@SubscribeEvent
fun onChatMessage(event: LorenzChatEvent) {
if (!LorenzUtils.inSkyBlock) return
- if (!SkyHanniMod.feature.slayer.blazes.hellion.hideDaggerWarning) return
+ if (!config.hideDaggerWarning) return
val message = event.message
- if (message.matchRegex("§cStrike using the §r(.+) §r§cattunement on your dagger!") ||
- message == "§cYour hit was reduced by Hellion Shield!"
- ) {
+ if (attunementPattern.matches(message) || message == "§cYour hit was reduced by Hellion Shield!") {
event.blockedReason = "blaze_slayer_dagger"
}
}
@@ -63,7 +62,7 @@ class BlazeSlayerDaggerHelper {
checkActiveDagger()
lastNearest = findNearest()
- val first = Dagger.entries[SkyHanniMod.feature.slayer.blazes.hellion.firstDagger]
+ val first = Dagger.entries[config.firstDagger]
val second = first.other()
textTop = format(holding, true, first) + " " + format(holding, true, second)
@@ -71,7 +70,7 @@ class BlazeSlayerDaggerHelper {
}
private fun findNearest(): HellionShield? {
- if (!SkyHanniMod.feature.slayer.blazes.hellion.markRightHellionShield) return null
+ if (!config.markRightHellionShield) return null
if (lastNearestCheck + 100 > System.currentTimeMillis()) return lastNearest
lastNearestCheck = System.currentTimeMillis()
diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/enderman/EndermanSlayerFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/enderman/EndermanSlayerFeatures.kt
index 42c50f00a..cd0de443e 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/slayer/enderman/EndermanSlayerFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/enderman/EndermanSlayerFeatures.kt
@@ -129,14 +129,14 @@ class EndermanSlayerFeatures {
val durationFormat = duration.format(showMilliSeconds = true)
event.drawColor(location, beaconConfig.beaconColor.toChromaColor(), alpha = 1f)
event.drawWaypointFilled(location, beaconConfig.beaconColor.toChromaColor(), true, true)
- event.drawDynamicText(location.add(0, 1, 0), "§4Beacon §b$durationFormat", 1.8)
+ event.drawDynamicText(location.add(y = 1), "§4Beacon §b$durationFormat", 1.8)
}
}
for (beacon in flyingBeacons) {
if (beacon.isDead) continue
if (beaconConfig.highlightBeacon) {
val beaconLocation = event.exactLocation(beacon)
- event.drawDynamicText(beaconLocation.add(0, 1, 0), "§4Beacon", 1.8)
+ event.drawDynamicText(beaconLocation.add(y = 1), "§4Beacon", 1.8)
}
if (beaconConfig.showLine) {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningMobManager.kt b/src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningMobManager.kt
index 6b4757e21..e1755f988 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningMobManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningMobManager.kt
@@ -35,9 +35,10 @@ class SummoningMobManager {
private var searchArmorStands = false
private var searchMobs = false
+ // TODO repo
//§aYou have spawned your Tank Zombie §r§asoul! §r§d(249 Mana)
- private val spawnPatter = "§aYou have spawned your (.+) §r§asoul! §r§d\\((\\d+) Mana\\)".toPattern()
- private val despawnPatter = "§cYou have despawned your (monster|monsters)!".toPattern()
+ private val spawnPattern = "§aYou have spawned your (.+) §r§asoul! §r§d\\((\\d+) Mana\\)".toPattern()
+ private val despawnPattern = "§cYou have despawned your (monster|monsters)!".toPattern()
//§a§ohannibal2's Tank Zombie§r §a160k§c❤
private val healthPattern = "§a§o(.+)'s (.+)§r §[ae]([\\dkm]+)§c❤".toPattern()
@@ -50,7 +51,7 @@ class SummoningMobManager {
if (!LorenzUtils.inSkyBlock) return
val message = event.message
- spawnPatter.matchMatcher(message) {
+ spawnPattern.matchMatcher(message) {
if (config.summoningMobDisplay) {
event.blockedReason = "summoning_soul"
}
@@ -59,7 +60,7 @@ class SummoningMobManager {
searchMobs = true
}
- if (despawnPatter.matcher(message).matches() || message.startsWith("§c ☠ §r§7You ")) {
+ if (despawnPattern.matcher(message).matches() || message.startsWith("§c ☠ §r§7You ")) {
despawned()
if (config.summoningMobDisplay && !message.contains("☠")) {
event.blockedReason = "summoning_soul"
diff --git a/src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningSoulsName.kt b/src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningSoulsName.kt
index 6d206bf17..98752b04a 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningSoulsName.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/summonings/SummoningSoulsName.kt
@@ -78,7 +78,7 @@ class SummoningSoulsName {
for ((entity, name) in souls) {
val vec = entity.getLorenzVec()
- event.drawString(vec.add(0.0, 2.5, 0.0), name)
+ event.drawString(vec.add(y = 2.5), name)
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/hooks/GuiIngameHook.kt b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/GuiIngameHook.kt
index 7fb80d4e0..896313d12 100644
--- a/src/main/java/at/hannibal2/skyhanni/mixins/hooks/GuiIngameHook.kt
+++ b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/GuiIngameHook.kt
@@ -1,6 +1,10 @@
package at.hannibal2.skyhanni.mixins.hooks
import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.features.garden.GardenAPI
+import at.hannibal2.skyhanni.features.garden.GardenPlotAPI
+import at.hannibal2.skyhanni.features.garden.GardenPlotAPI.isBarn
+import at.hannibal2.skyhanni.features.garden.GardenPlotAPI.name
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import net.minecraft.client.gui.FontRenderer
@@ -13,16 +17,39 @@ fun drawString(
x: Int,
y: Int,
color: Int,
-): Int {
+) = replaceString(text)?.let {
+ instance.drawString(it, x, y, color)
+} ?: 0
+
+private fun replaceString(text: String): String? {
if (SkyHanniMod.feature.misc.hideScoreboardNumbers && text.startsWith("§c") && text.length <= 4) {
- return 0
+ return null
}
if (SkyHanniMod.feature.misc.hidePiggyScoreboard) {
piggyPattern.matchMatcher(text) {
val coins = group("coins")
- return instance.drawString("Purse: $coins", x, y, color)
+ return "Purse: $coins"
+ }
+ }
+
+ if (SkyHanniMod.feature.garden.plotNameInScoreboard && GardenAPI.inGarden()) {
+ if (text.contains("⏣")) {
+ val plot = GardenPlotAPI.getCurrentPlot()
+ val hasPests = text.contains("ൠ")
+ val pestSuffix = if (hasPests) {
+ val pests = text.last().digitToInt()
+ val color = if (pests >= 4) "§c" else "§6"
+ " §7(${color}${pests}ൠ§7)"
+ } else ""
+ val name = plot?.let {
+ if (it.isBarn()) "§aThe Barn" else {
+ val namePrefix = if (hasPests) "" else "§aPlot §7- "
+ "$namePrefix§b" + it.name
+ }
+ } ?: "§aGarden §coutside"
+ return " §7⏣ $name$pestSuffix"
}
}
- return instance.drawString(text, x, y, color)
+ return text
}
diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/hooks/NetworkManagerHook.kt b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/NetworkManagerHook.kt
index ca4c2e42b..71f6aaba9 100644
--- a/src/main/java/at/hannibal2/skyhanni/mixins/hooks/NetworkManagerHook.kt
+++ b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/NetworkManagerHook.kt
@@ -5,5 +5,5 @@ import net.minecraft.network.Packet
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo
fun onReceivePacket(packet: Packet<*>, ci: CallbackInfo) {
- if (packet != null && PacketEvent.ReceiveEvent(packet).postAndCatch()) ci.cancel()
-} \ No newline at end of file
+ if (PacketEvent.ReceiveEvent(packet).postAndCatch()) ci.cancel()
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/UpdateDataWatcherEventPatch.java b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/UpdateDataWatcherEventPatch.java
new file mode 100644
index 000000000..bcc30f42d
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/UpdateDataWatcherEventPatch.java
@@ -0,0 +1,25 @@
+package at.hannibal2.skyhanni.mixins.transformers;
+
+import at.hannibal2.skyhanni.events.DataWatcherUpdatedEvent;
+import net.minecraft.entity.DataWatcher;
+import net.minecraft.entity.Entity;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import java.util.List;
+
+@Mixin(DataWatcher.class)
+public class UpdateDataWatcherEventPatch {
+ @Shadow
+ @Final
+ private Entity owner;
+
+ @Inject(method = "updateWatchedObjectsFromList", at = @At("TAIL"))
+ public void onWhatever(List<DataWatcher.WatchableObject> list, CallbackInfo ci) {
+ new DataWatcherUpdatedEvent(owner, list).postAndCatch();
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/test/HighlightMissingRepoItems.kt b/src/main/java/at/hannibal2/skyhanni/test/HighlightMissingRepoItems.kt
index 28e657c1e..2419d6161 100644
--- a/src/main/java/at/hannibal2/skyhanni/test/HighlightMissingRepoItems.kt
+++ b/src/main/java/at/hannibal2/skyhanni/test/HighlightMissingRepoItems.kt
@@ -10,7 +10,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.MultiFilter
import at.hannibal2.skyhanni.utils.NEUItems
import at.hannibal2.skyhanni.utils.RenderUtils.highlight
-import at.hannibal2.skyhanni.utils.jsonobjects.MultiFilterJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.MultiFilterJson
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.inventory.GuiChest
import net.minecraft.client.gui.inventory.GuiInventory
diff --git a/src/main/java/at/hannibal2/skyhanni/test/PacketTest.kt b/src/main/java/at/hannibal2/skyhanni/test/PacketTest.kt
index 454ce6afa..8ae9f0c5e 100644
--- a/src/main/java/at/hannibal2/skyhanni/test/PacketTest.kt
+++ b/src/main/java/at/hannibal2/skyhanni/test/PacketTest.kt
@@ -64,10 +64,10 @@ class PacketTest {
@SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true)
fun onChatPacket(event: PacketEvent.ReceiveEvent) {
+ if (!enabled) return
val packet = event.packet
val packetName = packet.javaClass.simpleName
- if (!enabled) return
// Keep alive
if (packetName == "S00PacketKeepAlive") return
diff --git a/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt b/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt
index 635ea3351..1a53e8283 100644
--- a/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt
+++ b/src/main/java/at/hannibal2/skyhanni/test/SkyHanniDebugsAndTests.kt
@@ -250,6 +250,14 @@ class SkyHanniDebugsAndTests {
LorenzUtils.chat("stopped ${modules.size} listener classes.")
}
+ fun whereami() {
+ if (LorenzUtils.inSkyBlock) {
+ LorenzUtils.chat("§eYou are currently in ${LorenzUtils.skyBlockIsland}.")
+ return
+ }
+ LorenzUtils.chat("§eYou are not in Skyblock.")
+ }
+
fun copyLocation(args: Array<String>) {
val location = LocationUtils.playerLocation()
val x = LorenzUtils.formatDouble(location.x + 0.001).replace(",", ".")
@@ -336,13 +344,13 @@ class SkyHanniDebugsAndTests {
fun copyItemInternalName() {
val hand = InventoryUtils.getItemInHand()
if (hand == null) {
- LorenzUtils.chat("§cNo item in hand!")
+ LorenzUtils.userError("No item in hand!")
return
}
val internalName = hand.getInternalNameOrNull()
if (internalName == null) {
- LorenzUtils.chat("§cInternal name is null for item ${hand.name}")
+ LorenzUtils.error("§cInternal name is null for item ${hand.name}")
return
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/BlockUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/BlockUtils.kt
index 9bc353820..5b8c8a0c0 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/BlockUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/BlockUtils.kt
@@ -48,9 +48,9 @@ object BlockUtils {
return result?.blockPos?.toLorenzVec()
}
- fun getBlockLookingAt(duration: Double = 10.0) = rayTrace(
+ fun getBlockLookingAt(distance: Double = 10.0) = rayTrace(
LocationUtils.playerEyeLocation(),
Minecraft.getMinecraft().thePlayer.lookVec.toLorenzVec(),
- duration
+ distance
)
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ConfigUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ConfigUtils.kt
new file mode 100644
index 000000000..99ed4b231
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/ConfigUtils.kt
@@ -0,0 +1,63 @@
+package at.hannibal2.skyhanni.utils
+
+import at.hannibal2.skyhanni.config.HasLegacyId
+import com.google.gson.JsonArray
+import com.google.gson.JsonElement
+import com.google.gson.JsonPrimitive
+
+object ConfigUtils {
+
+ /**
+ * Migrates an Int ArrayList to an Enum ArrayList.
+ * The new enum class should implement HasLegacyId and have a getter for LegacyId
+ *
+ * @param element The JsonElement to migrate
+ * @param enumClass The enum class to migrate to
+ * @return The migrated JsonElement
+ */
+ fun <T> migrateIntArrayListToEnumArrayList(element: JsonElement, enumClass: Class<T>): JsonElement
+ where T : Enum<T>, T : HasLegacyId {
+ require(element is JsonArray) { "Expected a JsonArray but got ${element.javaClass.simpleName}" }
+
+ // An array of enum constants that are to be migrated
+ val migratedArray = element.mapNotNull { jsonElement ->
+ val index = jsonElement.asInt
+ getEnumConstantFromLegacyId(index, enumClass)?.name
+ }.map { JsonPrimitive(it) }
+
+ // Return a JsonArray of the migrated enum constants
+ return JsonArray().apply {
+ migratedArray.forEach { add(it) }
+ }
+ }
+
+ /**
+ * Gets an enum constant from a legacy id
+ * @param legacyId The legacy id to get the enum constant from
+ * @param enumClass The enum class to get the enum constant from
+ * @return The enum constant, or null if not found
+ */
+ private fun <T> getEnumConstantFromLegacyId(
+ legacyId: Int,
+ enumClass: Class<T>
+ ): T? where T : Enum<T>, T : HasLegacyId {
+ for (enumConstant in enumClass.getEnumConstants()) {
+ if (enumConstant.legacyId == legacyId) return enumConstant
+ }
+ return null
+ }
+
+ /**
+ * Migrates an Int to an Enum Constant.
+ * The new enum class should implement HasLegacyId and have a getter for LegacyId
+ *
+ * @param element The JsonElement to migrate
+ * @param enumClass The enum class to migrate to
+ * @return The migrated JsonElement
+ */
+ fun <T> migrateIntToEnum(element: JsonElement, enumClass: Class<T>): JsonElement
+ where T : Enum<T>, T : HasLegacyId {
+ require(element is JsonPrimitive) { "Expected a JsonPrimitive but got ${element.javaClass.simpleName}" }
+ return JsonPrimitive(getEnumConstantFromLegacyId(element.asInt, enumClass)?.name)
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/DelayedRun.kt b/src/main/java/at/hannibal2/skyhanni/utils/DelayedRun.kt
new file mode 100644
index 000000000..f90237588
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/DelayedRun.kt
@@ -0,0 +1,34 @@
+package at.hannibal2.skyhanni.utils
+
+import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy
+import kotlin.time.Duration
+
+// TODO find better sync bug fix than creating a new map for each use
+object DelayedRun {
+ var map = mapOf<() -> Any, SimpleTimeMark>()
+
+ fun runDelayed(duration: Duration, run: () -> Unit) {
+ map = map.editCopy {
+ this[run] = SimpleTimeMark.now() + duration
+ }
+ }
+
+ fun runNextTick(run: () -> Unit) {
+ map = map.editCopy {
+ this[run] = SimpleTimeMark.now()
+ }
+ }
+
+ fun checkRuns() {
+ if (map.isEmpty()) return
+ map = map.editCopy {
+ entries.removeIf { (runnable, time) ->
+ val inPast = time.isInPast()
+ if (inPast) {
+ runnable()
+ }
+ inPast
+ }
+ }
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt b/src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt
index 28fc08807..ca4827291 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/EntityOutlineRenderer.kt
@@ -77,9 +77,7 @@ object EntityOutlineRenderer {
*
* @param camera the current camera
* @param partialTicks the progress to the next tick
- * @param x the camera x position
- * @param y the camera y position
- * @param z the camera z position
+ * @param vector the camera position as Vector
*/
@JvmStatic
fun renderEntityOutlines(camera: ICamera, partialTicks: Float, vector: LorenzVec): Boolean {
@@ -284,9 +282,7 @@ object EntityOutlineRenderer {
*
* @param camera the current camera
* @param entity the entity to render
- * @param x the camera x position
- * @param y the camera y position
- * @param z the camera z position
+ * @param vector the camera position as Vector
* @return whether the entity should be rendered
*/
private fun shouldRender(camera: ICamera, entity: Entity, vector: LorenzVec): Boolean =
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt
index 7fe6e8efb..427d5e48b 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt
@@ -34,7 +34,7 @@ object EntityUtils {
inaccuracy: Double = 1.6,
debugWrongEntity: Boolean = false,
): List<EntityArmorStand> {
- val center = getLorenzVec().add(0, y, 0)
+ val center = getLorenzVec().add(y = y)
val a = center.add(-inaccuracy, -inaccuracy - 3, -inaccuracy).toBlocPos()
val b = center.add(inaccuracy, inaccuracy + 3, inaccuracy).toBlocPos()
val alignedBB = AxisAlignedBB(a, b)
@@ -58,7 +58,7 @@ object EntityUtils {
contains: String,
radius: Double = 3.0,
): List<EntityArmorStand> {
- val center = getLorenzVec().add(0, 3, 0)
+ val center = getLorenzVec().add(y = 3)
val a = center.add(-radius, -radius - 3, -radius).toBlocPos()
val b = center.add(radius, radius + 3, radius).toBlocPos()
val alignedBB = AxisAlignedBB(a, b)
@@ -77,7 +77,7 @@ object EntityUtils {
inaccuracy: Double = 1.6,
debugWrongEntity: Boolean = false,
): EntityArmorStand? {
- val center = getLorenzVec().add(0, y, 0)
+ val center = getLorenzVec().add(y = y)
val a = center.add(-inaccuracy, -inaccuracy - 3, -inaccuracy).toBlocPos()
val b = center.add(inaccuracy, inaccuracy + 3, inaccuracy).toBlocPos()
val alignedBB = AxisAlignedBB(a, b)
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt
index be29569a5..9ce83c23a 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt
@@ -4,6 +4,8 @@ import at.hannibal2.skyhanni.test.command.ErrorManager
import io.github.moulberry.notenoughupdates.NotEnoughUpdates
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.inventory.GuiChest
+import net.minecraft.client.gui.inventory.GuiContainer
+import net.minecraft.entity.player.InventoryPlayer
import net.minecraft.inventory.ContainerChest
import net.minecraft.inventory.Slot
import net.minecraft.item.ItemStack
@@ -45,7 +47,7 @@ object InventoryUtils {
fun inStorage() = openInventoryName().let {
(it.contains("Storage") && !it.contains("Rift Storage"))
- || it.contains("Ender Chest") || it.contains("Backpack")
+ || it.contains("Ender Chest") || it.contains("Backpack")
}
fun getItemInHand(): ItemStack? = Minecraft.getMinecraft().thePlayer.heldItem
@@ -66,4 +68,9 @@ object InventoryUtils {
false
}
}
+
+ fun isSlotInPlayerInventory(itemStack: ItemStack): Boolean {
+ val screen = Minecraft.getMinecraft().currentScreen as? GuiContainer ?: return false
+ return screen.slotUnderMouse.inventory is InventoryPlayer && screen.slotUnderMouse.stack == itemStack
+ }
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt
index a1b7ed09f..420f3decb 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt
@@ -6,8 +6,9 @@ import at.hannibal2.skyhanni.utils.NEUItems.getItemStack
import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber
import at.hannibal2.skyhanni.utils.SimpleTimeMark.Companion.asTimeMark
import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.cachedData
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getEnchantments
import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.isRecombobulated
-import at.hannibal2.skyhanni.utils.StringUtils.matchRegex
+import at.hannibal2.skyhanni.utils.StringUtils.matches
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import com.google.gson.GsonBuilder
import com.google.gson.JsonObject
@@ -24,6 +25,20 @@ import kotlin.time.Duration.Companion.seconds
object ItemUtils {
+ // TODO USE SH-REPO
+ private val patternInFront = "(?: *§8(\\+§\\w)?(?<amount>[\\d.km,]+)(x )?)?(?<name>.*)".toPattern()
+ private val patternBehind = "(?<name>(?:['\\w-]+ ?)+)(?:§8x(?<amount>[\\d,]+))?".toPattern()
+ private val petLevelPattern = "\\[Lvl (.*)] (.*)".toPattern()
+
+ private val ignoredPetStrings = listOf(
+ "Archer",
+ "Berserk",
+ "Mage",
+ "Tank",
+ "Healer",
+ "➡",
+ )
+
fun ItemStack.cleanName() = this.displayName.removeColor()
fun isSack(stack: ItemStack) = stack.getInternalName().endsWith("_SACK") && stack.cleanName().endsWith(" Sack")
@@ -50,14 +65,7 @@ object ItemUtils {
fun isRecombobulated(stack: ItemStack) = stack.isRecombobulated()
- fun isPet(name: String): Boolean = name.matchRegex("\\[Lvl (.*)] (.*)") && !listOf(
- "Archer",
- "Berserk",
- "Mage",
- "Tank",
- "Healer",
- "➡",
- ).any { name.contains(it) }
+ fun isPet(name: String): Boolean = petLevelPattern.matches(name) && !ignoredPetStrings.any { name.contains(it) }
fun maxPetLevel(name: String) = if (name.contains("Golden Dragon")) 200 else 100
@@ -133,8 +141,12 @@ object ItemUtils {
fun ItemStack.isVanilla() = NEUItems.isVanillaItem(this)
+ // Checks for the enchantment glint as part of the minecraft enchantments
fun ItemStack.isEnchanted() = isItemEnchanted
+ // Checks for hypixel enchantments in the attributes
+ fun ItemStack.hasEnchantments() = getEnchantments()?.isNotEmpty() ?: false
+
fun ItemStack.getSkullTexture(): String? {
if (item != Items.skull) return null
if (tagCompound == null) return null
@@ -248,10 +260,6 @@ object ItemUtils {
fun isSkyBlockMenuItem(stack: ItemStack?): Boolean = stack?.getInternalName()?.equals("SKYBLOCK_MENU") ?: false
- // TODO USE SH-REPO
- private val patternInFront = "(?: *§8(\\+§[\\d\\w])?(?<amount>[\\d\\.km,]+)(x )?)?(?<name>.*)".toPattern()
- private val patternBehind = "(?<name>(?:['\\w-]+ ?)+)(?:§8x(?<amount>[\\d,]+))?".toPattern()
-
private val itemAmountCache = mutableMapOf<String, Pair<String, Int>>()
fun readItemAmount(originalInput: String): Pair<String, Int>? {
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LocationUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/LocationUtils.kt
index e6929d737..654974d5c 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/LocationUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/LocationUtils.kt
@@ -24,12 +24,12 @@ object LocationUtils {
fun playerEyeLocation(): LorenzVec {
val player = Minecraft.getMinecraft().thePlayer
val vec = player.getLorenzVec()
- return vec.add(0.0, 0.0 + player.getEyeHeight(), 0.0)
+ return vec.add(y = player.getEyeHeight().toDouble())
}
- fun AxisAlignedBB.isVecInside(vec: LorenzVec) = isVecInside(vec.toVec3())
+ fun AxisAlignedBB.isInside(vec: LorenzVec) = isVecInside(vec.toVec3())
- fun AxisAlignedBB.isPlayerInside() = isVecInside(playerLocation())
+ fun AxisAlignedBB.isPlayerInside() = isInside(playerLocation())
fun LorenzVec.canBeSeen(radius: Double = 150.0): Boolean {
val a = playerEyeLocation()
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt
index 90970a315..b468bc33d 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt
@@ -23,7 +23,9 @@ import net.minecraft.entity.EntityLivingBase
import net.minecraft.entity.SharedMonsterAttributes
import net.minecraft.event.ClickEvent
import net.minecraft.event.HoverEvent
+import net.minecraft.launchwrapper.Launch
import net.minecraft.util.ChatComponentText
+import net.minecraftforge.fml.common.FMLCommonHandler
import java.awt.Color
import java.lang.reflect.Field
import java.lang.reflect.Modifier
@@ -33,6 +35,7 @@ import java.text.SimpleDateFormat
import java.util.Collections
import java.util.Timer
import java.util.TimerTask
+import java.util.regex.Matcher
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KMutableProperty1
import kotlin.reflect.KProperty
@@ -359,7 +362,7 @@ object LorenzUtils {
}
fun sendMessageToServer(message: String) {
- if (System.currentTimeMillis() > lastMessageSent + 2_000) {
+ if (System.currentTimeMillis() > lastMessageSent + 1_000) {
lastMessageSent = System.currentTimeMillis()
val thePlayer = Minecraft.getMinecraft().thePlayer
thePlayer.sendChatMessage(message)
@@ -489,7 +492,7 @@ object LorenzUtils {
}
}
- fun List<String>.nextAfter(after: String, skip: Int = 1) = nextAfter({ it == after}, skip)
+ fun List<String>.nextAfter(after: String, skip: Int = 1) = nextAfter({ it == after }, skip)
fun List<String>.nextAfter(after: (String) -> Boolean, skip: Int = 1): String? {
var missing = -1
@@ -625,4 +628,22 @@ object LorenzUtils {
inline fun <reified T : Enum<T>> enumValueOf(name: String) =
enumValueOfOrNull<T>(name)
?: kotlin.error("Unknown enum constant for ${enumValues<T>().first().name.javaClass.simpleName}: '$name'")
+
+ fun isInDevEnviromen() = Launch.blackboard.get("fml.deobfuscatedEnvironment") as Boolean
+
+ fun shutdownMinecraft(reason: String? = null) {
+ System.err.println("SkyHanni-${SkyHanniMod.version} forced the game to shutdown.")
+ reason?.let {
+ System.err.println("Reason: $it")
+ }
+ FMLCommonHandler.instance().handleExit(-1)
+ }
+
+ /**
+ * Get the group, otherwise, return null
+ * @param groupName The group name in the pattern
+ */
+ fun Matcher.groupOrNull(groupName: String): String? {
+ return runCatching { this.group(groupName) }.getOrNull()
+ }
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt
index fd38fd441..b3cd44032 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt
@@ -50,7 +50,7 @@ data class LorenzVec(
fun add(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0): LorenzVec = LorenzVec(this.x + x, this.y + y, this.z + z)
- fun add(x: Int, y: Int, z: Int): LorenzVec = LorenzVec(this.x + x, this.y + y, this.z + z)
+ fun add(x: Int = 0, y: Int = 0, z: Int = 0): LorenzVec = LorenzVec(this.x + x, this.y + y, this.z + z)
override fun toString() = "LorenzVec{x=$x, y=$y, z=$z}"
@@ -132,6 +132,16 @@ data class LorenzVec(
fun axisAlignedTo(other: LorenzVec) = AxisAlignedBB(x, y, z, other.x, other.y, other.z)
+ fun interpolate(other: LorenzVec, factor: Double): LorenzVec {
+ require(factor in 0.0..1.0) { "Percentage must be between 0 and 1: $factor" }
+
+ val x = (1 - factor) * this.x + factor * other.x
+ val y = (1 - factor) * this.y + factor * other.y
+ val z = (1 - factor) * this.z + factor * other.z
+
+ return LorenzVec(x, y, z)
+ }
+
companion object {
fun getFromYawPitch(yaw: Double, pitch: Double): LorenzVec {
val yaw: Double = (yaw + 90) * Math.PI / 180
@@ -149,7 +159,7 @@ data class LorenzVec(
return LorenzVec(x, y, z)
}
- fun getBlockBelowPlayer() = LocationUtils.playerLocation().roundLocationToBlock().add(0.0, -1.0, 0.0)
+ fun getBlockBelowPlayer() = LocationUtils.playerLocation().roundLocationToBlock().add(y = -1.0)
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/MultiFilter.kt b/src/main/java/at/hannibal2/skyhanni/utils/MultiFilter.kt
index ab9817ef4..bc3b1789e 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/MultiFilter.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/MultiFilter.kt
@@ -1,7 +1,7 @@
package at.hannibal2.skyhanni.utils
import at.hannibal2.skyhanni.utils.StringUtils.trimWhiteSpace
-import at.hannibal2.skyhanni.utils.jsonobjects.MultiFilterJson
+import at.hannibal2.skyhanni.data.jsonobjects.repo.MultiFilterJson
class MultiFilter {
@@ -56,4 +56,4 @@ class MultiFilter {
fun count(): Int {
return equals.size + startsWith.size + endsWith.size + contains.size + containsWord.size
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
index 007d9f1d5..7965a2ded 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
@@ -17,6 +17,7 @@ import io.github.moulberry.notenoughupdates.NotEnoughUpdates
import io.github.moulberry.notenoughupdates.overlays.AuctionSearchOverlay
import io.github.moulberry.notenoughupdates.overlays.BazaarSearchOverlay
import io.github.moulberry.notenoughupdates.recipes.CraftingRecipe
+import io.github.moulberry.notenoughupdates.recipes.Ingredient
import io.github.moulberry.notenoughupdates.recipes.NeuRecipe
import io.github.moulberry.notenoughupdates.util.ItemResolutionQuery
import io.github.moulberry.notenoughupdates.util.Utils
@@ -34,6 +35,7 @@ object NEUItems {
private val itemNameCache = mutableMapOf<String, NEUInternalName>() // item name -> internal name
private val multiplierCache = mutableMapOf<String, Pair<String, Int>>()
private val recipesCache = mutableMapOf<String, Set<NeuRecipe>>()
+ private val ingredientsCache = mutableMapOf<NeuRecipe, Set<Ingredient>>()
private val enchantmentNamePattern = Pattern.compile("^(?<format>(?:§.)+)(?<name>[^§]+) (?<level>[IVXL]+)$")
var allItemsCache = mapOf<String, NEUInternalName>() // item name -> internal name
var allInternalNames = mutableListOf<NEUInternalName>()
@@ -244,7 +246,7 @@ object NEUItems {
if (recipe !is CraftingRecipe) continue
val map = mutableMapOf<String, Int>()
- for (ingredient in recipe.ingredients) {
+ for (ingredient in recipe.getCachedIngredients()) {
val count = ingredient.count.toInt()
var internalItemId = ingredient.internalItemId
// ignore cactus green
@@ -297,6 +299,8 @@ object NEUItems {
return recipes
}
+ fun NeuRecipe.getCachedIngredients() = ingredientsCache.getOrPut(this) { ingredients }
+
fun neuHasFocus(): Boolean {
if (AuctionSearchOverlay.shouldReplace()) return true
if (BazaarSearchOverlay.shouldReplace()) return true
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt b/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt
index 41e5f4923..31062b559 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt
@@ -104,7 +104,7 @@ object NumberUtil {
fun Number.addSeparators() = NumberFormat.getNumberInstance().format(this)
- fun String.romanToDecimalIfNeeded() = toIntOrNull() ?: romanToDecimal()
+ fun String.romanToDecimalIfNecessary() = toIntOrNull() ?: romanToDecimal()
/**
* This code was converted to Kotlin and taken under CC BY-SA 3.0 license
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ParkourHelper.kt b/src/main/java/at/hannibal2/skyhanni/utils/ParkourHelper.kt
index 68f7a0d49..e80aa7f62 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/ParkourHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/ParkourHelper.kt
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.utils
import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.jsonobjects.repo.ParkourJson.ShortCut
import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
import at.hannibal2.skyhanni.test.command.ErrorManager
import at.hannibal2.skyhanni.utils.LocationUtils.distanceToPlayer
@@ -11,7 +12,6 @@ import at.hannibal2.skyhanni.utils.RenderUtils.drawFilledBoundingBox_nea
import at.hannibal2.skyhanni.utils.RenderUtils.drawString
import at.hannibal2.skyhanni.utils.RenderUtils.expandBlock
import at.hannibal2.skyhanni.utils.RenderUtils.outlineTopFace
-import at.hannibal2.skyhanni.utils.jsonobjects.ParkourJson.ShortCut
import net.minecraft.client.Minecraft
import java.awt.Color
import kotlin.time.Duration.Companion.seconds
@@ -116,7 +116,7 @@ class ParkourHelper(
if (outline) event.outlineTopFace(aabb, 2, Color.BLACK, true)
}
if (SkyHanniMod.feature.dev.waypoint.showPlatformNumber && !isMovingPlatform) {
- event.drawString(location.offsetCenter().add(0, 1, 0), "§a§l$index", seeThroughBlocks = true)
+ event.drawString(location.offsetCenter().add(y = 1), "§a§l$index", seeThroughBlocks = true)
}
}
} catch (e: Throwable) {
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt b/src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt
index 3e30f300c..66629d11d 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt
@@ -6,7 +6,7 @@ import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
@JvmInline
-value class SimpleTimeMark(private val millis: Long) {
+value class SimpleTimeMark(private val millis: Long) : Comparable<SimpleTimeMark> {
operator fun minus(other: SimpleTimeMark) =
(millis - other.millis).milliseconds
@@ -24,6 +24,8 @@ value class SimpleTimeMark(private val millis: Long) {
fun isFarPast() = millis == 0L
+ override fun compareTo(other: SimpleTimeMark): Int = millis.compareTo(other.millis)
+
override fun toString(): String {
if (millis == 0L) return "The Far Past"
return Instant.ofEpochMilli(millis).toString()
@@ -31,6 +33,8 @@ value class SimpleTimeMark(private val millis: Long) {
fun toMillis() = millis
+ fun toSkyBlockTime() = SkyBlockTime.fromInstant(Instant.ofEpochMilli(millis))
+
companion object {
fun now() = SimpleTimeMark(System.currentTimeMillis())
fun farPast() = SimpleTimeMark(0)
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt
index 9f65a71f1..9db592047 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt
@@ -179,6 +179,10 @@ object SkyBlockItemModifierUtils {
fun ItemStack.getLivingMetalProgress() = getAttributeInt("lm_evo")
+ fun ItemStack.getBottleOfJyrreSeconds() = getAttributeInt("bottle_of_jyrre_seconds")
+
+ fun ItemStack.getEdition() = getAttributeInt("edition")
+
fun ItemStack.getEnchantments() = getExtraAttributes()?.takeIf { it.hasKey("enchantments") }?.run {
val enchantments = this.getCompoundTag("enchantments")
enchantments.keySet.associateWith { enchantments.getInteger(it) }
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt
index dd114d8fd..cb7a0fa23 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt
@@ -1,5 +1,6 @@
package at.hannibal2.skyhanni.utils
+import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.mixins.transformers.AccessorChatComponentText
import at.hannibal2.skyhanni.utils.GuiRenderUtils.darkenColor
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
@@ -7,7 +8,6 @@ import net.minecraft.client.Minecraft
import net.minecraft.client.gui.GuiUtilRenderComponents
import net.minecraft.util.ChatComponentText
import net.minecraft.util.IChatComponent
-import org.intellij.lang.annotations.Language
import java.util.Base64
import java.util.NavigableMap
import java.util.UUID
@@ -36,14 +36,18 @@ object StringUtils {
return first + lowercase.substring(1)
}
- fun String.removeColor(): String {
+ private val formattingChars by lazy { "kmolnr".toCharArray() + "kmolnr".uppercase().toCharArray() }
+
+ fun String.removeColor(keepFormatting: Boolean = false): String {
val builder = StringBuilder(this.length)
var counter = 0
while (counter < this.length) {
if (this[counter] == '§') {
- counter += 2
- continue
+ if (!keepFormatting || this[counter + 1] !in formattingChars) {
+ counter += 2
+ continue
+ }
}
builder.append(this[counter])
counter++
@@ -73,17 +77,11 @@ object StringUtils {
return toString().replace("-", "")
}
- @Deprecated("Do not create a regex pattern each time.", ReplaceWith("toPattern()"))
- fun String.matchRegex(@Language("RegExp") regex: String): Boolean = regex.toRegex().matches(this)
-
- private fun String.removeAtBeginning(text: String): String =
- if (this.startsWith(text)) substring(text.length) else this
-
// TODO find better name for this method
inline fun <T> Pattern.matchMatcher(text: String, consumer: Matcher.() -> T) =
matcher(text).let { if (it.matches()) consumer(it) else null }
- fun String.cleanPlayerName(): String {
+ private fun String.internalCleanPlayerName(): String {
val split = trim().split(" ")
return if (split.size > 1) {
split[1].removeColor()
@@ -92,6 +90,16 @@ object StringUtils {
}
}
+ fun String.cleanPlayerName(displayName: Boolean = false): String {
+ return if (displayName) {
+ if (SkyHanniMod.feature.chat.playerMessage.playerRankHider) {
+ "§b" + internalCleanPlayerName()
+ } else this
+ } else {
+ internalCleanPlayerName()
+ }
+ }
+
inline fun <T> List<Pattern>.matchMatchers(text: String, consumer: Matcher.() -> T): T? {
for (pattern in iterator()) {
pattern.matchMatcher<T>(text) {
@@ -132,7 +140,6 @@ object StringUtils {
}
}
-
fun String.removeWordsAtEnd(i: Int) = split(" ").dropLast(i).joinToString(" ")
fun String.splitLines(width: Int): String {
@@ -150,7 +157,10 @@ object StringUtils {
}
fun optionalPlural(number: Int, singular: String, plural: String) =
- "${number.addSeparators()} " + if (number == 1) singular else plural
+ "${number.addSeparators()} " + canBePlural(number, singular, plural)
+
+ fun canBePlural(number: Int, singular: String, plural: String) =
+ if (number == 1) singular else plural
fun progressBar(percentage: Double, steps: Int = 24): Any {
//'§5§o§2§l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §f§l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §l§m §r §e348,144.3§6/§e936k'
@@ -233,6 +243,10 @@ object StringUtils {
}
if (username == "") return null
+ if (username.contains("[NPC]")) {
+ return null
+ }
+
if (username.contains(">")) {
username = username.substring(username.indexOf('>') + 1).trim()
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/tracker/ItemTrackerData.kt b/src/main/java/at/hannibal2/skyhanni/utils/tracker/ItemTrackerData.kt
new file mode 100644
index 000000000..7aa2cf4f9
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/tracker/ItemTrackerData.kt
@@ -0,0 +1,53 @@
+package at.hannibal2.skyhanni.utils.tracker
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.utils.NEUInternalName
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
+import com.google.gson.annotations.Expose
+
+abstract class ItemTrackerData : TrackerData() {
+
+ private val config get() = SkyHanniMod.feature.misc.tracker
+
+ abstract fun resetItems()
+
+ abstract fun getDescription(timesGained: Long): List<String>
+
+ abstract fun getCoinName(item: TrackedItem): String
+
+ abstract fun getCoinDescription(item: TrackedItem): List<String>
+
+ open fun getCustomPricePer(internalName: NEUInternalName) = SkyHanniTracker.getPricePer(internalName)
+
+ override fun reset() {
+ items.clear()
+ resetItems()
+ }
+
+ fun additem(internalName: NEUInternalName, stackSize: Int) {
+ val item = items.getOrPut(internalName) { TrackedItem() }
+
+ item.timesGained++
+ item.totalAmount += stackSize
+ item.lastTimeUpdated = SimpleTimeMark.now()
+ }
+
+ @Expose
+ var items: MutableMap<NEUInternalName, TrackedItem> = HashMap()
+
+ class TrackedItem {
+ @Expose
+ var internalName: NEUInternalName? = null
+
+ @Expose
+ var timesGained: Long = 0
+
+ @Expose
+ var totalAmount: Long = 0
+
+ @Expose
+ var hidden = false
+
+ var lastTimeUpdated = SimpleTimeMark.farPast()
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniItemTracker.kt b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniItemTracker.kt
new file mode 100644
index 000000000..7ea533166
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniItemTracker.kt
@@ -0,0 +1,151 @@
+package at.hannibal2.skyhanni.utils.tracker
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.config.Storage
+import at.hannibal2.skyhanni.test.PriceSource
+import at.hannibal2.skyhanni.utils.ItemUtils.nameWithEnchantment
+import at.hannibal2.skyhanni.utils.KeyboardManager
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
+import at.hannibal2.skyhanni.utils.LorenzUtils.addSelector
+import at.hannibal2.skyhanni.utils.LorenzUtils.sortedDesc
+import at.hannibal2.skyhanni.utils.NEUInternalName
+import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
+import at.hannibal2.skyhanni.utils.NEUItems.getItemStack
+import at.hannibal2.skyhanni.utils.NumberUtil
+import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
+import at.hannibal2.skyhanni.utils.StringUtils.removeColor
+import at.hannibal2.skyhanni.utils.renderables.Renderable
+import kotlin.time.Duration.Companion.seconds
+
+class SkyHanniItemTracker<Data : ItemTrackerData>(
+ name: String,
+ createNewSession: () -> Data,
+ getStorage: (Storage.ProfileSpecific) -> Data,
+ drawDisplay: (Data) -> List<List<Any>>,
+) : SkyHanniTracker<Data>(name, createNewSession, getStorage, drawDisplay) {
+
+ companion object {
+ val SKYBLOCK_COIN by lazy { "SKYBLOCK_COIN".asInternalName() }
+ }
+
+ private var lastClickDelay = 0L
+
+ fun addCoins(coins: Int) {
+ addItem(SKYBLOCK_COIN, coins)
+ }
+
+ fun addItem(internalName: NEUInternalName, stackSize: Int) {
+ modify {
+ it.additem(internalName, stackSize)
+ }
+ getSharedTracker()?.let {
+ val hidden = it.get(DisplayMode.TOTAL).items[internalName]!!.hidden
+ it.get(DisplayMode.SESSION).items[internalName]!!.hidden = hidden
+ }
+
+ }
+
+ fun addPriceFromButton(lists: MutableList<List<Any>>) {
+ if (isInventoryOpen()) {
+ lists.addSelector<PriceSource>(
+ "",
+ getName = { type -> type.displayName },
+ isCurrent = { it.ordinal == config.priceFrom },
+ onChange = {
+ config.priceFrom = it.ordinal
+ update()
+ }
+ )
+ }
+ }
+
+ fun drawItems(
+ data: Data,
+ filter: (NEUInternalName) -> Boolean,
+ lists: MutableList<List<Any>>
+ ): Double {
+ var profit = 0.0
+ val items = mutableMapOf<Renderable, Long>()
+ for ((internalName, itemProfit) in data.items) {
+ if (!filter(internalName)) continue
+
+ val amount = itemProfit.totalAmount
+ val pricePer =
+ if (internalName == SKYBLOCK_COIN) 1.0 else data.getCustomPricePer(internalName)
+ val price = (pricePer * amount).toLong()
+ val displayAmount = if (internalName == SKYBLOCK_COIN) itemProfit.timesGained else amount
+
+ val cleanName = if (internalName == SKYBLOCK_COIN) {
+ data.getCoinName(itemProfit)
+ } else {
+ internalName.getItemStack().nameWithEnchantment ?: error("no name for $internalName")
+ }
+
+ val priceFormat = NumberUtil.format(price)
+ val hidden = itemProfit.hidden
+ val newDrop = itemProfit.lastTimeUpdated.passedSince() < 10.seconds && config.showRecentDrops
+ val numberColor = if (newDrop) "§a§l" else "§7"
+
+ var displayName = if (hidden) {
+ "§8§m" + cleanName.removeColor(keepFormatting = true).replace("§r", "")
+ } else cleanName
+ displayName = " $numberColor${displayAmount.addSeparators()}x $displayName§7: §6$priceFormat"
+
+ val lore = buildLore(data, itemProfit, hidden, newDrop, internalName)
+
+ val renderable = if (isInventoryOpen()) Renderable.clickAndHover(displayName, lore) {
+ if (System.currentTimeMillis() > lastClickDelay + 150) {
+ if (KeyboardManager.isControlKeyDown()) {
+ data.items.remove(internalName)
+ LorenzUtils.chat("Removed $cleanName §efrom Fishing Frofit Tracker.")
+ lastClickDelay = System.currentTimeMillis() + 500
+ } else {
+ modify {
+ it.items[internalName]?.hidden = !hidden
+ }
+ lastClickDelay = System.currentTimeMillis()
+ }
+ update()
+ }
+ } else Renderable.string(displayName)
+ if (isInventoryOpen() || !hidden) {
+ items[renderable] = price
+ }
+ if (!hidden || !config.excludeHiddenItemsInPrice) {
+ profit += price
+ }
+ }
+
+ for (text in items.sortedDesc().keys) {
+ lists.addAsSingletonList(text)
+ }
+ return profit
+ }
+
+ private fun buildLore(
+ data: Data,
+ item: ItemTrackerData.TrackedItem,
+ hidden: Boolean,
+ newDrop: Boolean,
+ internalName: NEUInternalName
+ ) = buildList {
+ if (internalName == SKYBLOCK_COIN) {
+ addAll(data.getCoinDescription(item))
+ } else {
+ addAll(data.getDescription(item.timesGained))
+ }
+ add("")
+ if (newDrop) {
+ add("§aYou caught this item recently.")
+ add("")
+ }
+ add("§eClick to " + (if (hidden) "show" else "hide") + "!")
+ add("§eControl + Click to remove this item!")
+ if (SkyHanniMod.feature.dev.debug.enabled) {
+ add("")
+ add("§7${internalName}")
+ }
+ }
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt
index f882a268e..bc2db88e1 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt
@@ -1,10 +1,16 @@
package at.hannibal2.skyhanni.utils.tracker
+import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.Storage
import at.hannibal2.skyhanni.config.core.config.Position
import at.hannibal2.skyhanni.data.ProfileStorageData
+import at.hannibal2.skyhanni.features.bazaar.BazaarApi.Companion.getBazaarData
+import at.hannibal2.skyhanni.features.misc.items.EstimatedItemValue
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
+import at.hannibal2.skyhanni.utils.NEUInternalName
+import at.hannibal2.skyhanni.utils.NEUItems.getNpcPriceOrNull
+import at.hannibal2.skyhanni.utils.NEUItems.getPriceOrNull
import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
import at.hannibal2.skyhanni.utils.SimpleTimeMark
import at.hannibal2.skyhanni.utils.renderables.Renderable
@@ -12,19 +18,31 @@ import net.minecraft.client.Minecraft
import net.minecraft.client.gui.inventory.GuiInventory
import kotlin.time.Duration.Companion.seconds
-class SkyHanniTracker<Data : TrackerData>(
+open class SkyHanniTracker<Data : TrackerData>(
private val name: String,
private val createNewSession: () -> Data,
private val getStorage: (Storage.ProfileSpecific) -> Data,
private val drawDisplay: (Data) -> List<List<Any>>,
) {
private var inventoryOpen = false
- private var displayMode = DisplayMode.TOTAL
+ private var displayMode: DisplayMode? = null
private val currentSessions = mutableMapOf<Storage.ProfileSpecific, Data>()
private var display = emptyList<List<Any>>()
private var sessionResetTime = SimpleTimeMark.farPast()
private var dirty = false
+ companion object {
+ val config get() = SkyHanniMod.feature.misc.tracker
+ private val storedTrackers get() = SkyHanniMod.feature.storage.trackerDisplayModes
+
+ fun getPricePer(name: NEUInternalName) = when (config.priceFrom) {
+ 0 -> name.getBazaarData()?.sellPrice ?: name.getPriceOrNull() ?: 0.0
+ 1 -> name.getBazaarData()?.buyPrice ?: name.getPriceOrNull() ?: 0.0
+
+ else -> name.getNpcPriceOrNull() ?: 0.0
+ }
+ }
+
fun isInventoryOpen() = inventoryOpen
fun resetCommand(args: Array<String>, command: String) {
@@ -47,6 +65,8 @@ class SkyHanniTracker<Data : TrackerData>(
}
fun renderDisplay(position: Position) {
+ if (config.hideInEstimatedItemValue && EstimatedItemValue.isCurrentlyShowing()) return
+
val currentlyOpen = Minecraft.getMinecraft().currentScreen is GuiInventory
if (inventoryOpen != currentlyOpen) {
inventoryOpen = currentlyOpen
@@ -55,7 +75,7 @@ class SkyHanniTracker<Data : TrackerData>(
if (dirty) {
display = getSharedTracker()?.let {
- buildFinalDisplay(drawDisplay(it.get(displayMode)))
+ buildFinalDisplay(drawDisplay(it.get(getDisplayMode())))
} ?: emptyList()
dirty = false
}
@@ -72,7 +92,7 @@ class SkyHanniTracker<Data : TrackerData>(
if (inventoryOpen) {
it.add(1, buildDisplayModeView())
}
- if (inventoryOpen && displayMode == DisplayMode.SESSION) {
+ if (inventoryOpen && getDisplayMode() == DisplayMode.SESSION) {
it.addAsSingletonList(buildSessionResetButton())
}
}
@@ -94,14 +114,15 @@ class SkyHanniTracker<Data : TrackerData>(
private fun buildDisplayModeView() = LorenzUtils.buildSelector<DisplayMode>(
"§7Display Mode: ",
getName = { type -> type.displayName },
- isCurrent = { it == displayMode },
+ isCurrent = { it == getDisplayMode() },
onChange = {
displayMode = it
+ storedTrackers[name] = it
update()
}
)
- private fun getSharedTracker() = ProfileStorageData.profileSpecific?.let {
+ protected fun getSharedTracker() = ProfileStorageData.profileSpecific?.let {
SharedTracker(getStorage(it), currentSessions.getOrPut(it) { createNewSession() })
}
@@ -113,6 +134,18 @@ class SkyHanniTracker<Data : TrackerData>(
}
}
+ private fun getDisplayMode() = displayMode ?: run {
+ val newValue = config.defaultDisplayMode.get().mode ?: storedTrackers[name] ?: DisplayMode.TOTAL
+ displayMode = newValue
+ newValue
+ }
+
+ fun firstUpdate() {
+ if (display.isEmpty()) {
+ update()
+ }
+ }
+
class SharedTracker<Data : TrackerData>(private val total: Data, private val currentSession: Data) {
fun modify(modifyFunction: (Data) -> Unit) {
modifyFunction(total)
@@ -130,4 +163,13 @@ class SkyHanniTracker<Data : TrackerData>(
SESSION("This Session"),
;
}
+
+ enum class DefaultDisplayMode(val display: String, val mode: DisplayMode?) {
+ TOTAL("Total", DisplayMode.TOTAL),
+ SESSION("This Session", DisplayMode.SESSION),
+ REMEMBER_LAST("Remember Last", null),
+ ;
+
+ override fun toString() = display
+ }
}