diff options
author | HiZe_ <superhize@hotmail.com> | 2023-09-02 11:40:38 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-02 11:40:38 +0200 |
commit | aa14f20e2e07bccd26e2e162648f97b4281e3f25 (patch) | |
tree | 2d50cb5cafbf40a9af2adbef5e1f852d50a80566 /src/main/java/at/hannibal2/skyhanni | |
parent | 653c95679ba5dd59cfc5c1129c124f99aa8ed47b (diff) | |
download | skyhanni-aa14f20e2e07bccd26e2e162648f97b4281e3f25.tar.gz skyhanni-aa14f20e2e07bccd26e2e162648f97b4281e3f25.tar.bz2 skyhanni-aa14f20e2e07bccd26e2e162648f97b4281e3f25.zip |
Powder Grinding Tracker (#409)
powder tracker overlay #409
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni')
5 files changed, 499 insertions, 0 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt index 7628a2bfb..5fbbb8e1a 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt @@ -58,6 +58,7 @@ import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostCounter import at.hannibal2.skyhanni.features.misc.items.EstimatedItemValue import at.hannibal2.skyhanni.features.misc.items.EstimatedWardrobePrice import at.hannibal2.skyhanni.features.misc.massconfiguration.DefaultConfigFeatures +import at.hannibal2.skyhanni.features.misc.powdertracker.PowderTracker import at.hannibal2.skyhanni.features.misc.tabcomplete.PlayerTabComplete import at.hannibal2.skyhanni.features.misc.tabcomplete.WarpTabComplete import at.hannibal2.skyhanni.features.misc.teleportpad.TeleportPadCompactName @@ -389,6 +390,7 @@ class SkyHanniMod { loadModule(GardenPlotBorders()) loadModule(CosmeticFollowingLine()) loadModule(SuperpairsClicksAlert()) + loadModule(PowderTracker()) init() diff --git a/src/main/java/at/hannibal2/skyhanni/config/Storage.java b/src/main/java/at/hannibal2/skyhanni/config/Storage.java index 2b9755926..9ec45a70c 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/Storage.java +++ b/src/main/java/at/hannibal2/skyhanni/config/Storage.java @@ -10,6 +10,7 @@ import at.hannibal2.skyhanni.features.garden.visitor.VisitorReward; import at.hannibal2.skyhanni.features.misc.EnderNode; import at.hannibal2.skyhanni.features.misc.FrozenTreasure; import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostData; +import at.hannibal2.skyhanni.features.misc.powdertracker.PowderChestReward; import at.hannibal2.skyhanni.features.rift.area.westvillage.KloonTerminal; import at.hannibal2.skyhanni.utils.LorenzVec; import at.hannibal2.skyhanni.utils.NEUInternalName; @@ -273,6 +274,17 @@ public class Storage { } @Expose + public Map<Integer, PowderTracker> powderTracker = new HashMap<>(); + + public static class PowderTracker { + @Expose + public int totalChestPicked = 0; + + @Expose + public Map<PowderChestReward, Long> rewards = new HashMap<>(); + } + + @Expose public FrozenTreasureTracker frozenTreasureTracker = new FrozenTreasureTracker(); public static class FrozenTreasureTracker { diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/MiscConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/MiscConfig.java index 6a8bc4576..84a5977a8 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/MiscConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/MiscConfig.java @@ -808,6 +808,77 @@ public class MiscConfig { } @Expose + @ConfigOption(name = "Powder Tracker", desc = "") + @Accordion + public PowderTrackerConfig powderTrackerConfig = new PowderTrackerConfig(); + + public static class PowderTrackerConfig { + + @Expose + @ConfigOption(name = "Enabled", desc = "Enable the Powder Tracker overlay.") + @ConfigEditorBoolean + public boolean enabled = false; + + @Expose + @ConfigOption(name = "Only when Grinding", desc = "Only show the overlay when powder grinding.") + @ConfigEditorBoolean + public boolean onlyWhenPowderGrinding = false; + + @Expose + @ConfigOption(name = "Great Explorer", desc = "Enable this if your Great Explorer perk is maxed.") + @ConfigEditorBoolean + public boolean greatExplorerMaxed = false; + + @Expose + @ConfigOption( + name = "Text Format", + desc = "Drag text to change the appearance of the overlay." + ) + @ConfigEditorDraggableList( + exampleText = { + "§b§lPowder Tracker", + "§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)", + "", + "§50§7-§90§7-§a0§f-0 §cRuby Gemstone", + "§50§7-§90§7-§a0§f-0 §bSapphire Gemstone", + "§50§7-§90§7-§a0§f-0 §6Amber Gemstone", + "§50§7-§90§7-§a0§f-0 §5Amethyst Gemstone", + "§50§7-§90§7-§a0§f-0 §aJade Gemstone", + "§50§7-§90§7-§a0§f-0 §eTopaz Gemstone", + + "§b14 §9FTX 3070", + "§b14 §9Electron Transmitter", + "§b14 §9Robotron Reflector", + "§b14 §9Superlite Motor", + "§b14 §9Control Switch", + "§b14 §9Synthetic Heart", + "§b14 §9Total Robot Parts", + + "§90§7-§a0§7-§c0§f-§e0§f-§30 §fGoblin Egg", + + "§b12 §aWishing Compass", + + "§b320 §aSludge Juice", + "§b2 §9Ascension Rope", + "§b6 §5Treasurite", + "§b4 §6Jungle Heart", + "§b1 §5Pickonimbus 2000", + "§b14 §aYoggie", + "§b9 §fPrehistoric Egg", + "§b25 §aOil Barrel" + } + ) + public Property<List<Integer>> textFormat = Property.of(new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18))); + + @Expose + public Position position = new Position(-274, 0, false, true); + + } + + @Expose @ConfigOption(name = "Cosmetic", desc = "") @Accordion public CosmeticConfig cosmeticConfig = new CosmeticConfig(); diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/powdertracker/PowderChestReward.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/powdertracker/PowderChestReward.kt new file mode 100644 index 000000000..8a6fce7d5 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/powdertracker/PowderChestReward.kt @@ -0,0 +1,64 @@ +package at.hannibal2.skyhanni.features.misc.powdertracker + +import java.util.regex.Pattern + +enum class PowderChestReward(val displayName: String, val pattern: Pattern) { + + + MITHRIL_POWDER("§aMithril Powder", "§aYou received §r§b[+](?<amount>.*) §r§aMithril Powder.".toPattern()), + GEMSTONE_POWDER("§dGemstone Powder", "§aYou received §r§b[+](?<amount>.*) §r§aGemstone Powder.".toPattern()), + + ROUGH_RUBY_GEMSTONE("§fRough Ruby Gemstone", "§aYou received §r§f(?<amount>.*) §r§f❤ §r§fRough Ruby Gemstone§r§a.".toPattern()), + FLAWED_RUBY_GEMSTONE("§aFlawed Sapphire Gemstone", "§aYou received §r§f(?<amount>.*) §r§a❤ §r§aFlawed RubyGemstone§r§a.".toPattern()), + FINE_RUBY_GEMSTONE("§9Fine Ruby Gemstone", "§aYou received §r§f(?<amount>.*) §r§9❤ §r§9Fine Ruby Gemstone§r§a.".toPattern()), + FLAWLESS_RUBY_GEMSTONE("§5Flawless Ruby Gemstone", "§aYou received §r§f(?<amount>.*) §r§9❤ §r§5Flawless Ruby Gemstone§r§a.".toPattern()), + + ROUGH_SAPPHIRE_GEMSTONE("§fRough Sapphire Gemstone", "§aYou received §r§f(?<amount>.*) §r§f✎ §r§fRough Sapphire Gemstone§r§a.".toPattern()), + FLAWED_SAPPHIRE_GEMSTONE("§aFlawed Sapphire Gemstone", "§aYou received §r§f(?<amount>.*) §r§a✎ §r§aFlawed Sapphire Gemstone§r§a.".toPattern()), + FINE_SAPPHIRE_GEMSTONE("§9Fine Sapphire Gemstone", "§aYou received §r§f(?<amount>.*) §r§9✎ §r§9Fine Sapphire Gemstone§r§a.".toPattern()), + FLAWLESS_SAPPHIRE_GEMSTONE("§5Flawless Sapphire Gemstone", "§aYou received §r§f(?<amount>.*) §r§9✎ §r§5Flawless Sapphire Gemstone§r§a.".toPattern()), + + ROUGH_AMBER_GEMSTONE("§fRough Amber Gemstone", "§aYou received §r§f(?<amount>.*) §r§f⸕ §r§fRough Amber Gemstone§r§a.".toPattern()), + FLAWED_AMBER_GEMSTONE("§aFlawed Amber Gemstone", "§aYou received §r§f(?<amount>.*) §r§a⸕ §r§aFlawed Amber Gemstone§r§a.".toPattern()), + FINE_AMBER_GEMSTONE("§9Fine Amber Gemstone", "§aYou received §r§f(?<amount>.*) §r§9⸕ §r§9Fine Amber Gemstone§r§a.".toPattern()), + FLAWLESS_AMBER_GEMSTONE("§5Flawless Amber Gemstone", "§aYou received §r§f(?<amount>.*) §r§9⸕ §r§5Flawless Amber Gemstone§r§a.".toPattern()), + + ROUGH_AMETHYST_GEMSTONE("§fRough Amethyst Gemstone", "§aYou received §r§f(?<amount>.*) §r§f❈ §r§fRough Amethyst Gemstone§r§a.".toPattern()), + FLAWED_AMETHYST_GEMSTONE("§aFlawed Amethyst Gemstone", "§aYou received §r§f(?<amount>.*) §r§a❈ §r§aFlawed Amethyst Gemstone§r§a.".toPattern()), + FINE_AMETHYST_GEMSTONE("§9Fine Amethyst Gemstone", "§aYou received §r§f(?<amount>.*) §r§9❈ §r§9Fine Amethyst Gemstone§r§a.".toPattern()), + FLAWLESS_AMETHYST_GEMSTONE("§5Flawless Amethyst Gemstone", "§aYou received §r§f(?<amount>.*) §r§9❈ §r§5Flawless Amethyst Gemstone§r§a.".toPattern()), + + ROUGH_JADE_GEMSTONE("§fRough Jade Gemstone", "§aYou received §r§f(?<amount>.*) §r§f☘ §r§fRough Jade Gemstone§r§a.".toPattern()), + FLAWED_JADE_GEMSTONE("§aFlawed Jade Gemstone", "§aYou received §r§f(?<amount>.*) §r§a☘ §r§aFlawed Jade Gemstone§r§a.".toPattern()), + FINE_JADE_GEMSTONE("§9Fine Jade Gemstone", "§aYou received §r§f(?<amount>.*) §r§9☘ §r§9Fine Jade Gemstone§r§a.".toPattern()), + FLAWLESS_JADE_GEMSTONE("§5Flawless Jade Gemstone", "§aYou received §r§f(?<amount>.*) §r§9☘ §r§5Flawless Jade Gemstone§r§a.".toPattern()), + + ROUGH_TOPAZ_GEMSTONE("§fRough Topaz Gemstone", "§aYou received §r§f(?<amount>.*) §r§f✧ §r§fRough Topaz Gemstone§r§a.".toPattern()), + FLAWED_TOPAZ_GEMSTONE("§aFlawed Topaz Gemstone", "§aYou received §r§f(?<amount>.*) §r§a✧ §r§aFlawed Topaz Gemstone§r§a.".toPattern()), + FINE_TOPAZ_GEMSTONE("§9Fine Topaz Gemstone", "§aYou received §r§f(?<amount>.*) §r§9✧ §r§9Fine Topaz Gemstone§r§a.".toPattern()), + FLAWLESS_TOPAZ_GEMSTONE("§5Flawless Topaz Gemstone", "§aYou received §r§f(?<amount>.*) §r§9✧ §r§5Flawless Topaz Gemstone§r§a.".toPattern()), + + FTX_3070("§9FTX 3070", "§aYou received §r§f(?<amount>.*) §r§9FTX 3070§r§a.".toPattern()), + ELECTRON_TRANSIMTTER("§9Electron Transmitter", "§aYou received §r§f(?<amount>.*) §r§9Electron Transmitter§r§a.".toPattern()), + ROBOTRON_REFLECTOR("§9Robotron Reflector", "§aYou received §r§f(?<amount>.*) §r§9Robotron Reflector§r§a.".toPattern()), + SUPERLITE_MOTOR("§9Superlite Motor", "§aYou received §r§f(?<amount>.*) §r§9Superlite Motor§r§a.".toPattern()), + CONTROL_SWITCH("§9Control Switch", "§aYou received §r§f(?<amount>.*) §r§9Control Switch§r§a.".toPattern()), + SYNTHETIC_HEART("§9Synthetic Heart", "§aYou received §r§f(?<amount>.*) §r§9Synthetic Heart§r§a.".toPattern()), + + GOBLIN_EGG("§9Goblin Egg", "§aYou received §r§f(?<amount>.*) §r§9Goblin Egg§r§a.".toPattern()), + GREEN_GOBLIN_EGG("§aGreen Goblin Egg", "§aYou received §r§f(?<amount>.*) §r§a§r§aGreen Goblin Egg§r§a.".toPattern()), + RED_GOBLIN_EGG("§cRed Goblin Egg", "§aYou received §r§f(?<amount>.*) §r§9§r§cRed Goblin Egg§r§a.".toPattern()), + YELLOW_GOBLIN_EGG("§eYellow Goblin Egg", "§aYou received §r§f(?<amount>.*) §r§9§r§eYellow Goblin Egg§r§a.".toPattern()), + BLUE_GOBLIN_EGG("§3Blue Goblin Egg", "§aYou received §r§f(?<amount>.*) §r§9§r§3Blue Goblin Egg§r§a.".toPattern()), + + WISHING_COMPASS("§aWishing Compass", "§aYou received §r§f(?<amount>.*) §r§aWishing Compass§r§a.".toPattern()), + + SLUDGE_JUICE("§aSludge Juice", "§aYou received §r§f(?<amount>.*) §r§aSludge Juice§r§a.".toPattern()), + ASCENSION_ROPE("§9Ascension Rope", "§aYou received §r§f(?<amount>.*) §r§9Ascension Rope§r§a.".toPattern()), + TREASURITE("§5Treasurite", "§aYou received §r§f(?<amount>.*) §r§5Treasurite§r§a.".toPattern()), + JUNGLE_HEART("§6Jungle Heart", "§aYou received §r§f(?<amount>.*) §r§6Jungle Heart§r§a.".toPattern()), + PICKONIMBUS_2000("§5Pickonimbus 2000", "§aYou received §r§f(?<amount>.*) §r§5Pickonimbus 2000§r§a.".toPattern()), + YOGGIE("§aYoggie", "§aYou received §r§f(?<amount>.*) §r§aYoggie§r§a.".toPattern()), + PREHISTORIC_EGG("§fPrehistoric Egg", "§aYou received §r§f(?<amount>.*) §r§fPrehistoric Egg§r§a.".toPattern()), + OIL_BARREL("§aOil Barrel", "§aYou received §r§f(?<amount>.*) §r§aOil Barrel§r§a.".toPattern()), +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/powdertracker/PowderTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/powdertracker/PowderTracker.kt new file mode 100644 index 000000000..3dfb082ad --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/powdertracker/PowderTracker.kt @@ -0,0 +1,350 @@ +package at.hannibal2.skyhanni.features.misc.powdertracker + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.config.Storage +import at.hannibal2.skyhanni.data.IslandType +import at.hannibal2.skyhanni.data.ProfileStorageData +import at.hannibal2.skyhanni.events.* +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList +import at.hannibal2.skyhanni.utils.LorenzUtils.addSelector +import at.hannibal2.skyhanni.utils.LorenzUtils.afterChange +import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators +import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber +import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher +import net.minecraft.client.Minecraft +import net.minecraft.client.gui.inventory.GuiInventory +import net.minecraft.entity.boss.BossStatus +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.concurrent.fixedRateTimer + +class PowderTracker { + + private val config get() = SkyHanniMod.feature.misc.powderTrackerConfig + private var display = emptyList<List<Any>>() + private val picked = "§6You have successfully picked the lock on this chest!".toPattern() + private val uncovered = "§aYou uncovered a treasure chest!".toPattern() + private val powderEvent = ".*§r§b§l2X POWDER STARTED!.*".toPattern() + private val powderEnded = ".*§r§b§l2X POWDER ENDED!.*".toPattern() + private val powderBossBar = "§e§lPASSIVE EVENT §b§l2X POWDER §e§lRUNNING FOR §a§l(?<time>.*)§r".toPattern() + private var lastChestPicked = 0L + private var isGrinding = false + private val gemstoneInfo = ResourceInfo(0L, 0L, 0, 0.0, mutableListOf()) + private val mithrilInfo = ResourceInfo(0L, 0L, 0, 0.0, mutableListOf()) + private val chestInfo = ResourceInfo(0L, 0L, 0, 0.0, mutableListOf()) + private var doublePowder = false + private var powderTimer = "" + private var currentDisplayMode = DisplayMode.TOTAL + private var inventoryOpen = false + private var currentSessionData = mutableMapOf<Int, Storage.ProfileSpecific.PowderTracker>() + private val gemstones = listOf( + "Ruby" to "§c", + "Sapphire" to "§b", + "Amber" to "§6", + "Amethyst" to "§5", + "Jade" to "§a", + "Topaz" to "§e" + ) + + init { + fixedRateTimer(name = "skyhanni-powder-tracker", period = 1000) { + if (!isEnabled()) return@fixedRateTimer + calculateResourceHour(gemstoneInfo) + calculateResourceHour(mithrilInfo) + calculateResourceHour(chestInfo) + } + } + + @SubscribeEvent + fun onRenderOverlay(event: GuiRenderEvent) { + if (!isEnabled()) return + + val currentlyOpen = Minecraft.getMinecraft().currentScreen is GuiInventory + if (inventoryOpen != currentlyOpen) { + inventoryOpen = currentlyOpen + saveAndUpdate() + } + + if (config.onlyWhenPowderGrinding && !isGrinding) return + + config.position.renderStringsAndItems( + display, + posLabel = "Powder Chest Tracker" + ) + } + + @SubscribeEvent + fun onChat(event: LorenzChatEvent) { + if (!isEnabled()) return + val msg = event.message + val both = currentLog() ?: return + + if (config.greatExplorerMaxed) { + uncovered.matchMatcher(msg) { + both.modify { + it.totalChestPicked += 1 + } + isGrinding = true + lastChestPicked = System.currentTimeMillis() + } + } + + picked.matchMatcher(msg) { + both.modify { + it.totalChestPicked += 1 + } + isGrinding = true + lastChestPicked = System.currentTimeMillis() + } + + powderEvent.matchMatcher(msg) { doublePowder = true } + powderEnded.matchMatcher(msg) { doublePowder = false } + + for (reward in PowderChestReward.entries) { + reward.pattern.matchMatcher(msg) { + both.modify { + val count = it.rewards[reward] ?: 0 + var amount = group("amount").formatNumber() + if ((reward == PowderChestReward.MITHRIL_POWDER || reward == PowderChestReward.GEMSTONE_POWDER) && doublePowder) + amount *= 2 + it.rewards[reward] = count + amount + } + } + } + saveAndUpdate() + } + + @SubscribeEvent + fun onTick(event: LorenzTickEvent) { + if (!isEnabled()) return + if (event.repeatSeconds(1)) { + doublePowder = powderBossBar.matcher(BossStatus.bossName).find() + powderBossBar.matchMatcher(BossStatus.bossName) { + powderTimer = group("time") + doublePowder = powderTimer != "00:00" + + saveAndUpdate() + } + } + if (System.currentTimeMillis() - lastChestPicked > 60_000) { + isGrinding = false + } + } + + @SubscribeEvent + fun onConfigLoad(event: ConfigLoadEvent) { + config.textFormat.afterChange { saveAndUpdate() } + } + + @SubscribeEvent + fun onWorldChange(event: LorenzWorldChangeEvent) { + if (!isEnabled()) return + gemstoneInfo.perHour = 0.0 + gemstoneInfo.stoppedChecks = 0 + gemstoneInfo.perMin.clear() + mithrilInfo.perHour = 0.0 + mithrilInfo.stoppedChecks = 0 + mithrilInfo.perMin.clear() + chestInfo.perHour = 0.0 + chestInfo.stoppedChecks = 0 + chestInfo.perMin.clear() + doublePowder = false + saveAndUpdate() + } + + private fun saveAndUpdate() { + calculateGemstone() + calculateMithril() + calculateChest() + display = formatDisplay(drawDisplay()) + } + + private fun formatDisplay(map: List<List<Any>>) = buildList { + if (map.isEmpty()) return@buildList + for (index in config.textFormat.get()) { + add(map[index]) + } + } + + private fun drawDisplay() = buildList<List<Any>> { + addAsSingletonList("§b§lPowder Tracker") + if (inventoryOpen) { + addSelector<DisplayMode>( + "§7Display Mode: ", + getName = { type -> type.displayName }, + isCurrent = { it == currentDisplayMode }, + onChange = { + currentDisplayMode = it + saveAndUpdate() + } + ) + } + val both = currentLog() ?: return@buildList + val display = both.get(currentDisplayMode) + val rewards = display.rewards + + val chestPerHour = if (chestInfo.perHour < 0) 0 else chestInfo.perHour.toInt().addSeparators() + addAsSingletonList("§d${display.totalChestPicked.addSeparators()} Total Chests Picked §7($chestPerHour/h)") + addAsSingletonList("§bDouble Powder: ${if (doublePowder) "§aActive! §7($powderTimer)" else "§cInactive!"}") + + val mithril = PowderChestReward.entries[0] + val mithrilCount = rewards.getOrDefault(mithril, 0).addSeparators() + val mithrilPerHour = if (mithrilInfo.perHour < 0) 0 else mithrilInfo.perHour.toInt().addSeparators() + addAsSingletonList("§b$mithrilCount ${mithril.displayName} §7($mithrilPerHour/h)") + + val gemstone = PowderChestReward.entries[1] + val gemstoneCount = rewards.getOrDefault(gemstone, 0).addSeparators() + val gemstonePerHour = if (gemstoneInfo.perHour < 0) 0 else gemstoneInfo.perHour.toInt().addSeparators() + addAsSingletonList("§b$gemstoneCount ${gemstone.displayName} §7($gemstonePerHour/h)") + + addAsSingletonList("") + + for ((gem, color) in gemstones) { + var totalGemstone = 0L + + for (quality in arrayOf("ROUGH", "FLAWED", "FINE", "FLAWLESS")) { + val gemstoneType = PowderChestReward.valueOf("${quality}_${gem.uppercase()}_GEMSTONE") + val count = rewards.getOrDefault(gemstoneType, 0) + val multiplier = when (quality) { + "FLAWED" -> 80 + "FINE" -> 6400 + "FLAWLESS" -> 512000 + else -> 1 + } + totalGemstone += count * multiplier + } + + val (flawless, fine, flawed, rough) = convert(totalGemstone) + addAsSingletonList("§5${flawless}§7-§9${fine}§7-§a${flawed}§f-${rough} $color$gem Gemstone") + } + + var totalParts = 0L + for (reward in PowderChestReward.entries.subList(26, 32)) { // robots part + val count = rewards.getOrDefault(reward, 0) + totalParts += count + addAsSingletonList("§b${count.addSeparators()} ${reward.displayName}") + } + addAsSingletonList("§b${totalParts.addSeparators()} §9Total Robot Parts") + + val goblinEgg = rewards.getOrDefault(PowderChestReward.GOBLIN_EGG, 0) + val greenEgg = rewards.getOrDefault(PowderChestReward.GREEN_GOBLIN_EGG, 0) + val redEgg = rewards.getOrDefault(PowderChestReward.RED_GOBLIN_EGG, 0) + val yellowEgg = rewards.getOrDefault(PowderChestReward.YELLOW_GOBLIN_EGG, 0) + val blueEgg = rewards.getOrDefault(PowderChestReward.BLUE_GOBLIN_EGG, 0) + addAsSingletonList("§9$goblinEgg§7-§a$greenEgg§7-§c$redEgg§f-§e$yellowEgg§f-§3$blueEgg §fGoblin Egg") + + for (reward in PowderChestReward.entries.subList(37, 46)) { + val count = rewards.getOrDefault(reward, 0).addSeparators() + addAsSingletonList("§b$count ${reward.displayName}") + } + } + + private fun calculateResourceHour(resourceInfo: ResourceInfo) { + val difference = resourceInfo.estimated - resourceInfo.lastEstimated + resourceInfo.lastEstimated = resourceInfo.estimated + + if (difference == resourceInfo.estimated) { + return + } + + resourceInfo.perHour = resourceInfo.perMin.average() * 3600 + resourceInfo.perMin.add(difference) + + if (difference == 0L) { + resourceInfo.stoppedChecks += 1 + + if (resourceInfo.stoppedChecks == 60) { + resourceInfo.stoppedChecks = 0 + resourceInfo.perMin.clear() + resourceInfo.perHour = 0.0 + } + return + } + resourceInfo.stoppedChecks = 0 + } + + private fun calculateGemstone() { + val both = currentLog() ?: return + val display = both.get(currentDisplayMode) + val rewards = display.rewards + gemstoneInfo.estimated = 0 + gemstoneInfo.estimated += rewards.getOrDefault(PowderChestReward.GEMSTONE_POWDER, 0) + } + + private fun calculateMithril() { + val both = currentLog() ?: return + val display = both.get(currentDisplayMode) + val rewards = display.rewards + mithrilInfo.estimated = 0 + mithrilInfo.estimated += rewards.getOrDefault(PowderChestReward.MITHRIL_POWDER, 0) + } + + private fun calculateChest() { + val both = currentLog() ?: return + val display = both.get(currentDisplayMode) + chestInfo.estimated = 0 + chestInfo.estimated += display.totalChestPicked + } + + private fun convert(roughCount: Long): Gem { + val flawlessRatio = 512000 + val fineRatio = 6400 + val flawedRatio = 80 + + val flawlessCount = roughCount / flawlessRatio + val remainingAfterFlawless = roughCount % flawlessRatio + + val fineCount = remainingAfterFlawless / fineRatio + val remainingAfterFine = remainingAfterFlawless % fineRatio + + val flawedCount = remainingAfterFine / flawedRatio + val remainingRoughCount = remainingAfterFine % flawedRatio + + return Gem(flawlessCount, fineCount, flawedCount, remainingRoughCount) + } + + data class Gem(val flawless: Long, val fine: Long, val flawed: Long, val rough: Long) + private data class ResourceInfo( + var estimated: Long, + var lastEstimated: Long, + var stoppedChecks: Int, + var perHour: Double, + val perMin: MutableList<Long> + ) + + enum class DisplayMode(val displayName: String) { + TOTAL("Total"), + CURRENT("This Session"), + ; + } + + + private fun currentLog(): AbstractPowderTracker? { + val profileSpecific = ProfileStorageData.profileSpecific ?: return null + + return AbstractPowderTracker( + profileSpecific.powderTracker.getOrPut(0) { Storage.ProfileSpecific.PowderTracker() }, + currentSessionData.getOrPut(0) { Storage.ProfileSpecific.PowderTracker() } + ) + } + + class AbstractPowderTracker( + private val total: Storage.ProfileSpecific.PowderTracker, + private val currentSession: Storage.ProfileSpecific.PowderTracker, + ) { + + fun modify(modifyFunction: (Storage.ProfileSpecific.PowderTracker) -> Unit) { + modifyFunction(total) + modifyFunction(currentSession) + } + + fun get(displayMode: DisplayMode) = when (displayMode) { + DisplayMode.TOTAL -> total + DisplayMode.CURRENT -> currentSession + } + } + + private fun isEnabled() = + LorenzUtils.inSkyBlock && LorenzUtils.skyBlockIsland == IslandType.CRYSTAL_HOLLOWS && config.enabled +}
\ No newline at end of file |