diff options
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni')
16 files changed, 494 insertions, 23 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt index f974d3d1d..569e22167 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt @@ -112,6 +112,7 @@ import at.hannibal2.skyhanni.features.fishing.ChumBucketHider import at.hannibal2.skyhanni.features.fishing.FishingAPI import at.hannibal2.skyhanni.features.fishing.FishingBaitWarnings import at.hannibal2.skyhanni.features.fishing.FishingHookDisplay +import at.hannibal2.skyhanni.features.fishing.FishingProfitTracker import at.hannibal2.skyhanni.features.fishing.FishingTimer import at.hannibal2.skyhanni.features.fishing.SeaCreatureFeatures import at.hannibal2.skyhanni.features.fishing.SeaCreatureManager @@ -564,6 +565,7 @@ class SkyHanniMod { loadModule(PlayerTabComplete) loadModule(GetFromSacksTabComplete) loadModule(SlayerProfitTracker) + loadModule(FishingProfitTracker) loadModule(SlayerItemsOnGround()) loadModule(RestorePieceOfWizardPortalLore()) loadModule(QuickModMenuSwitch) diff --git a/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt b/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt index ddd51b18f..5893fbf06 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt @@ -13,6 +13,7 @@ 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.tracker.SkyHanniTracker import com.google.gson.GsonBuilder import com.google.gson.JsonObject import com.google.gson.TypeAdapter @@ -37,6 +38,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 +111,15 @@ 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()) .enableComplexMapKeySerialization() .create() diff --git a/src/main/java/at/hannibal2/skyhanni/config/Storage.java b/src/main/java/at/hannibal2/skyhanni/config/Storage.java index b21361b6f..162f804e4 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/Storage.java +++ b/src/main/java/at/hannibal2/skyhanni/config/Storage.java @@ -5,6 +5,7 @@ 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.FishingProfitTracker; import at.hannibal2.skyhanni.features.fishing.trophy.TrophyRarity; import at.hannibal2.skyhanni.features.garden.CropAccessory; import at.hannibal2.skyhanni.features.garden.CropType; @@ -19,6 +20,7 @@ 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; @@ -50,6 +52,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 { @@ -389,5 +394,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 d14628560..8bf1be499 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt +++ b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt @@ -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.FishingProfitTracker import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.features.garden.GardenCropTimeCommand import at.hannibal2.skyhanni.features.garden.GardenNextJacobContest @@ -174,6 +175,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", 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..af8d9d3de --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingProfitTrackerConfig.java @@ -0,0 +1,35 @@ +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.ConfigEditorDropdown; +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 = "Show Price From", desc = "Show price from Bazaar or NPC.") + @ConfigEditorDropdown(values = {"Instant Sell", "Sell Offer", "NPC"}) + public int priceFrom = 1; + + @Expose + @ConfigOption(name = "Recent Drops", desc = "Highlight the amount in green on recently caught items.") + @ConfigEditorBoolean + public boolean showRecentDropss = true; + + @Expose + @ConfigOption(name = "Hide Moving", desc = "Hide the Fishing Profit Tracker while moving.") + @ConfigEditorBoolean + public boolean hideMoving = true; +} 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..a2f7da58d --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/TrackerConfig.java @@ -0,0 +1,21 @@ +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 = "Default Display Mode", desc = "Change the display mode that gets shown when starting.") + @ConfigEditorDropdown + public Property<SkyHanniTracker.DefaultDisplayMode> defaultDisplayMode = Property.of(SkyHanniTracker.DefaultDisplayMode.TOTAL); +} 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/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/features/fishing/FishingAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingAPI.kt index 550388893..035525c01 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,14 @@ package at.hannibal2.skyhanni.features.fishing import at.hannibal2.skyhanni.events.FishingBobberCastEvent +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.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 @@ -42,4 +46,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/FishingProfitTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingProfitTracker.kt new file mode 100644 index 000000000..50a9e6e1f --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/FishingProfitTracker.kt @@ -0,0 +1,322 @@ +package at.hannibal2.skyhanni.features.fishing + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.EntityMoveEvent +import at.hannibal2.skyhanni.events.FishingBobberCastEvent +import at.hannibal2.skyhanni.events.GuiRenderEvent +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent +import at.hannibal2.skyhanni.events.RepositoryReloadEvent +import at.hannibal2.skyhanni.events.SackChangeEvent +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.ItemUtils.getItemName +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.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.NumberUtil.formatNumber +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.jsonobjects.FishingProfitItemsJson +import at.hannibal2.skyhanni.utils.renderables.Renderable +import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker +import at.hannibal2.skyhanni.utils.tracker.TrackerData +import com.google.gson.annotations.Expose +import net.minecraft.client.Minecraft +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.time.Duration.Companion.seconds + +object FishingProfitTracker { + private val config get() = SkyHanniMod.feature.fishing.fishingProfitTracker + + private val coinsChatPattern = ".* CATCH! §r§bYou found §r§6(?<coins>.*) Coins§r§b\\.".toPattern() + private var lastClickDelay = 0L + + private val tracker = + SkyHanniTracker("Fishing Profit Tracker", { Data() }, { it.fishing.fishingProfitTracker }) { drawDisplay(it) } + + class Data : TrackerData() { + override fun reset() { + items.clear() + totalCatchAmount = 0 + } + + @Expose + var items = mutableMapOf<NEUInternalName, FishingItem>() + + @Expose + var totalCatchAmount = 0L + + class FishingItem { + @Expose + var internalName: NEUInternalName? = null + + @Expose + var timesCaught: Long = 0 + + @Expose + var totalAmount: Long = 0 + + @Expose + var hidden = false + + override fun toString() = "FishingItem{" + + "internalName='" + internalName + '\'' + + ", timesDropped=" + timesCaught + + ", totalAmount=" + totalAmount + + ", hidden=" + hidden + + '}' + + var lastTimeUpdated = SimpleTimeMark.farPast() + } + } + + private val SKYBLOCK_COIN by lazy { "SKYBLOCK_COIN".asInternalName() } + private val MAGMA_FISH by lazy { "MAGMA_FISH".asInternalName() } + + private fun drawDisplay(data: Data): List<List<Any>> = buildList { + addAsSingletonList("§e§lFishing Profit Tracker") + + var profit = 0.0 + val map = mutableMapOf<Renderable, Long>() + for ((internalName, itemProfit) in data.items) { + val amount = itemProfit.totalAmount + + var pricePer = if (internalName == SKYBLOCK_COIN) 1.0 else getPrice(internalName) + if (pricePer == 0.0) { + pricePer = getPrice(MAGMA_FISH) * FishingAPI.getFilletPerTrophy(internalName) + } + + val price = (pricePer * amount).toLong() + val displayAmount = if (internalName == SKYBLOCK_COIN) { + itemProfit.timesCaught + } else amount + + val cleanName = if (internalName == SKYBLOCK_COIN) "§6Coins" else internalName.getItemName() + var name = cleanName + val priceFormat = NumberUtil.format(price) + val hidden = itemProfit.hidden + + val newDrop = itemProfit.lastTimeUpdated.passedSince() < 10.seconds && config.showRecentDropss + val numberColor = if (newDrop) "§a§l" else "§7" + + if (hidden) { + name = "§8§m" + name.removeColor(keepFormatting = true).replace("§r", "") + } + + val text = " $numberColor${displayAmount.addSeparators()}x $name§7: §6$priceFormat" + + val timesCaught = itemProfit.timesCaught + val percentage = timesCaught.toDouble() / data.totalCatchAmount + val catchRate = LorenzUtils.formatPercentage(percentage.coerceAtMost(1.0)) + + val renderable = if (tracker.isInventoryOpen()) Renderable.clickAndHover( + text, + buildLore(timesCaught, catchRate, hidden, newDrop) + ) { + if (System.currentTimeMillis() > lastClickDelay + 150) { + + if (KeyboardManager.isControlKeyDown()) { + data.items.remove(internalName) + LorenzUtils.chat("§e[SkyHanni] Removed $cleanName §efrom Fishing Frofit Tracker.") + 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 + } + + for (text in map.sortedDesc().keys) { + addAsSingletonList(text) + } + + 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" + addAsSingletonList(Renderable.hoverTips(text, listOf("§7Profit per catch: $profitPrefix$profitPerCatchFormat"))) + + if (tracker.isInventoryOpen()) { + addSelector<PriceSource>( + "", + getName = { type -> type.displayName }, + isCurrent = { it.ordinal == config.priceFrom }, + onChange = { + config.priceFrom = it.ordinal + tracker.update() + } + ) + } + } + + private fun buildLore( + timesCaught: Long, + catchRate: String, + hidden: Boolean, + newDrop: Boolean + ) = buildList { + add("§7Caught §e${timesCaught.addSeparators()} §7times.") + add("§7Your catch rate: §c$catchRate") + 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!") + } + + @SubscribeEvent + fun onSackChange(event: SackChangeEvent) { + if (!isEnabled()) return + + for (sackChange in event.sackChanges) { + val change = sackChange.delta + if (change > 0) { + val internalName = sackChange.internalName + maybeAddItem(internalName, change) + } + } + } + + @SubscribeEvent + fun onItemAdd(event: ItemAddInInventoryEvent) { + if (!isEnabled()) return + + maybeAddItem(event.internalName, event.amount) + } + + @SubscribeEvent + fun onChat(event: LorenzChatEvent) { + coinsChatPattern.matchMatcher(event.message) { + val coins = group("coins").formatNumber() + addItem(SKYBLOCK_COIN, coins.toInt()) + } + } + + private fun addItem(internalName: NEUInternalName, stackSize: Int) { + tracker.modify { + it.totalCatchAmount++ + + val fishingItem = it.items.getOrPut(internalName) { Data.FishingItem() } + + fishingItem.timesCaught++ + fishingItem.totalAmount += stackSize + fishingItem.lastTimeUpdated = SimpleTimeMark.now() + } + } + + @SubscribeEvent + fun onRenderOverlay(event: GuiRenderEvent) { + if (!isEnabled()) return + if (!FishingAPI.hasFishingRodInHand()) return + if (isMoving && config.hideMoving) return + + tracker.renderDisplay(config.position) + } + + private fun maybeAddItem(internalName: NEUInternalName, amount: Int) { + if (!isAllowedItem(internalName)) { + LorenzUtils.debug("Ignored non-fishing item pickup: $internalName'") + return + } + + addItem(internalName, amount) + } + + private var itemCategories = mutableMapOf<String, List<NEUInternalName>>() + + @SubscribeEvent + fun onRepoReload(event: RepositoryReloadEvent) { + itemCategories = event.getConstant<FishingProfitItemsJson>("FishingProfitItems").categories + } + + private fun isAllowedItem(internalName: NEUInternalName): Boolean { + for ((name, items) in itemCategories) { + if (internalName in items) { + return true + } + } + + return false + } + + private fun getPrice(internalName: NEUInternalName) = when (config.priceFrom) { + 0 -> internalName.getBazaarData()?.sellPrice ?: internalName.getPriceOrNull() ?: 0.0 + 1 -> internalName.getBazaarData()?.buyPrice ?: internalName.getPriceOrNull() ?: 0.0 + + else -> internalName.getNpcPriceOrNull() ?: 0.0 + } + + /// <editor-fold desc="isMoving"> + + private val lastSteps = mutableListOf<Double>() + private var isMoving = true + + @SubscribeEvent + fun onEntityMove(event: EntityMoveEvent) { + if (!isEnabled() || !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) { + if (!isEnabled() || !config.hideMoving) return + isMoving = false + tracker.firstUpdate() + } + + @SubscribeEvent + fun onWorldChange(event: LorenzWorldChangeEvent) { + isMoving = true + } + /// </editor-fold> + + 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/slayer/SlayerProfitTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt index c05839ba6..6ea38924b 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt @@ -251,10 +251,7 @@ object SlayerProfitTracker { val priceFormat = NumberUtil.format(price) val hidden = itemProfit.hidden if (hidden) { - while (name.startsWith("§f")) { - name = name.substring(2) - } - name = StringUtils.addFormat(name, "§m") + name = "§8§m" + name.removeColor(keepFormatting = true).replace("§r", "") } val text = " §7${amount.addSeparators()}x $name§7: §6$priceFormat" diff --git a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt index dd114d8fd..d5365703a 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt @@ -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++ @@ -132,7 +136,6 @@ object StringUtils { } } - fun String.removeWordsAtEnd(i: Int) = split(" ").dropLast(i).joinToString(" ") fun String.splitLines(width: Int): String { diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/FishingProfitItemsJson.java b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/FishingProfitItemsJson.java new file mode 100644 index 000000000..d17fd7d30 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/FishingProfitItemsJson.java @@ -0,0 +1,12 @@ +package at.hannibal2.skyhanni.utils.jsonobjects; + +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/tracker/SkyHanniTracker.kt b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt index f882a268e..29b61faee 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt @@ -1,8 +1,10 @@ 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.misc.items.EstimatedItemValue import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems @@ -19,12 +21,17 @@ class SkyHanniTracker<Data : TrackerData>( 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 { + private val config get() = SkyHanniMod.feature.misc.tracker + private val storedTrackers get() = SkyHanniMod.feature.storage.trackerDisplayModes + } + fun isInventoryOpen() = inventoryOpen fun resetCommand(args: Array<String>, command: String) { @@ -47,6 +54,8 @@ class SkyHanniTracker<Data : TrackerData>( } fun renderDisplay(position: Position) { + if (config.hideInEstimatedItemValue && EstimatedItemValue.currentlyShowing) return + val currentlyOpen = Minecraft.getMinecraft().currentScreen is GuiInventory if (inventoryOpen != currentlyOpen) { inventoryOpen = currentlyOpen @@ -55,7 +64,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 +81,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,9 +103,10 @@ 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() } ) @@ -113,6 +123,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 +152,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 + } } |