diff options
Diffstat (limited to 'src')
322 files changed, 6001 insertions, 2290 deletions
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 + } } |