aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/Storage.java15
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingConfig.java5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingProfitTrackerConfig.java35
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/MiscConfig.java5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/TrackerConfig.java21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/EntityMovementData.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt13
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/FishingAPI.kt14
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/FishingProfitTracker.kt322
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/FishingProfitItemsJson.java12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt39
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
+ }
}