aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt1
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/Storage.java6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/GhostCounter.java21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostCounter.kt (renamed from src/main/java/at/hannibal2/skyhanni/features/misc/GhostCounter.kt)442
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostData.kt86
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostFormatting.kt182
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostUtil.kt107
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/CombatUtils.kt20
9 files changed, 480 insertions, 391 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt
index f538d1ed9..a8224e317 100644
--- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt
+++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt
@@ -44,6 +44,7 @@ import at.hannibal2.skyhanni.features.minion.MinionCollectLogic
import at.hannibal2.skyhanni.features.minion.MinionFeatures
import at.hannibal2.skyhanni.features.misc.*
import at.hannibal2.skyhanni.features.misc.discordrpc.DiscordRPCManager
+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.tabcomplete.PlayerTabComplete
diff --git a/src/main/java/at/hannibal2/skyhanni/config/Storage.java b/src/main/java/at/hannibal2/skyhanni/config/Storage.java
index 21979ffef..a53cb13bc 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/Storage.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/Storage.java
@@ -7,12 +7,12 @@ import at.hannibal2.skyhanni.features.garden.CropType;
import at.hannibal2.skyhanni.features.garden.fortuneguide.FarmingItems;
import at.hannibal2.skyhanni.features.garden.visitor.VisitorReward;
import at.hannibal2.skyhanni.features.misc.FrozenTreasure;
-import at.hannibal2.skyhanni.features.misc.GhostCounter.Option;
+import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostCounter;
+import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostData;
import at.hannibal2.skyhanni.features.rift.area.westvillage.KloonTerminal;
import at.hannibal2.skyhanni.utils.LorenzVec;
import com.google.gson.annotations.Expose;
import net.minecraft.item.ItemStack;
-
import java.util.*;
public class Storage {
@@ -219,7 +219,7 @@ public class Storage {
public static class GhostCounter {
@Expose
- public Map<Option, Double> data = new HashMap<>();
+ public Map<GhostData.Option, Double> data = new HashMap<>();
@Expose
public boolean ctDataImported = false;
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 237b0afe3..e5c46cb00 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt
+++ b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt
@@ -20,9 +20,9 @@ import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI
import at.hannibal2.skyhanni.features.minion.MinionFeatures
import at.hannibal2.skyhanni.features.misc.CityProjectFeatures
import at.hannibal2.skyhanni.features.misc.CollectionCounter
-import at.hannibal2.skyhanni.features.misc.GhostCounter
import at.hannibal2.skyhanni.features.misc.MarkedPlayerManager
import at.hannibal2.skyhanni.features.misc.discordrpc.DiscordRPCManager
+import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostUtil
import at.hannibal2.skyhanni.features.slayer.SlayerItemProfitTracker
import at.hannibal2.skyhanni.test.PacketTest
import at.hannibal2.skyhanni.test.SkyHanniTestCommand
@@ -126,12 +126,12 @@ object Commands {
registerCommand(
"shimportghostcounterdata",
"Manually importing the ghost counter data from GhostCounterV3"
- ) { GhostCounter.importCTGhostCounterData() }
+ ) { GhostUtil.importCTGhostCounterData() }
registerCommand(
"shclearfarmingitems",
"Clear farming items saved for the Farming Fortune Guide"
) { clearFarmingItems() }
- registerCommand("shresetghostcounter", "Resets the ghost counter stats") { GhostCounter.reset() }
+ registerCommand("shresetghostcounter", "Resets the ghost counter stats") { GhostUtil.reset() }
}
private fun usersBugFix() {
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/GhostCounter.java b/src/main/java/at/hannibal2/skyhanni/config/features/GhostCounter.java
index 84b6e99d3..5b2a91f7b 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/GhostCounter.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/GhostCounter.java
@@ -1,6 +1,8 @@
package at.hannibal2.skyhanni.config.features;
import at.hannibal2.skyhanni.config.core.config.Position;
+import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostFormatting;
+import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostUtil;
import com.google.gson.annotations.Expose;
import io.github.moulberry.moulconfig.annotations.*;
@@ -40,7 +42,8 @@ public class GhostCounter {
" §bXP/h: 810,410",
" §bKills/h: 420",
" §bETA: 14d",
- " §bMoney/h: 13,420,069"
+ " §bMoney/h: 13,420,069",
+ " §bMoney made: 14B"
}
)
public List<Integer> ghostDisplayText = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 9, 10, 11, 12));
@@ -61,15 +64,15 @@ public class GhostCounter {
@ConfigOption(name = "Reset Formatting", desc = "Reset formatting to default text.")
@ConfigEditorButton(buttonText = "Reset")
- public Runnable resetFormatting = at.hannibal2.skyhanni.features.misc.GhostCounter.INSTANCE::resetFormatting;
+ public Runnable resetFormatting = GhostFormatting.INSTANCE::reset;
@ConfigOption(name = "Export Formatting", desc = "Export current formatting to clipboard.")
@ConfigEditorButton(buttonText = "Export")
- public Runnable exportFormatting = at.hannibal2.skyhanni.features.misc.GhostCounter.INSTANCE::exportFormatting;
+ public Runnable exportFormatting = GhostFormatting.INSTANCE::export;
@ConfigOption(name = "Import Formatting", desc = "Import formatting from clipboard.")
@ConfigEditorButton(buttonText = "Import")
- public Runnable importFormatting = at.hannibal2.skyhanni.features.misc.GhostCounter.INSTANCE::importFormatting;
+ public Runnable importFormatting = GhostFormatting.INSTANCE::importFormat;
@Expose
@ConfigOption(name = "Title", desc = "Title Line.")
@@ -294,6 +297,13 @@ public class GhostCounter {
"Calculated with your kill per hour and your average magic find.")
@ConfigEditorText
public String moneyHourFormat = " &6$/h: &b%value%";
+
+ @Expose
+ @ConfigOption(name = "Money made", desc = "Calculate the money you made.\nInclude §eSorrow§7, §ePlasma§7, §eVolta§7, §e1M coins drop\n" +
+ "§eGhostly Boots§7, §eScavenger coins.\n" +
+ "§cUsing current Sell Offer value.")
+ @ConfigEditorText
+ public String moneyMadeFormat = " &6Money made: &b%value%";
}
@Expose
@@ -325,9 +335,8 @@ public class GhostCounter {
@ConfigOption(name = "Reset", desc = "Reset the counter.")
@ConfigEditorButton(buttonText = "Reset")
- public Runnable resetCounter = at.hannibal2.skyhanni.features.misc.GhostCounter.INSTANCE::reset;
+ public Runnable resetCounter = GhostUtil.INSTANCE::reset;
@Expose
public Position position = new Position(50, 50, false, true);
-
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/GhostCounter.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostCounter.kt
index 490ec110b..d23f8afc5 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/GhostCounter.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostCounter.kt
@@ -1,13 +1,17 @@
-package at.hannibal2.skyhanni.features.misc
+package at.hannibal2.skyhanni.features.misc.ghostcounter
import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.config.ConfigManager
import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.data.ProfileStorageData
import at.hannibal2.skyhanni.data.SkillExperience
import at.hannibal2.skyhanni.events.*
import at.hannibal2.skyhanni.features.bazaar.BazaarApi
-import at.hannibal2.skyhanni.features.misc.GhostCounter.Option.*
+import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostData.Option.*
+import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostData.bestiaryData
+import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostUtil.formatBestiary
+import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostUtil.formatText
+import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostUtil.isUsingCTGhostCounter
+import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostUtil.prettyTime
import at.hannibal2.skyhanni.utils.CombatUtils._isKilling
import at.hannibal2.skyhanni.utils.CombatUtils.calculateETA
import at.hannibal2.skyhanni.utils.CombatUtils.calculateXP
@@ -22,30 +26,23 @@ import at.hannibal2.skyhanni.utils.CombatUtils.xpGainHourLast
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
-import at.hannibal2.skyhanni.utils.LorenzUtils.chat
import at.hannibal2.skyhanni.utils.LorenzUtils.clickableChat
-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.roundToPrecision
+import at.hannibal2.skyhanni.utils.OSUtils
import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
-import com.google.gson.JsonArray
-import com.google.gson.JsonParser
-import com.google.gson.JsonPrimitive
+import at.hannibal2.skyhanni.utils.TabListData
+import at.hannibal2.skyhanni.utils.renderables.Renderable
import io.github.moulberry.notenoughupdates.util.Utils
import io.github.moulberry.notenoughupdates.util.XPInformation
+import net.minecraft.client.Minecraft
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-import java.awt.Toolkit
-import java.awt.datatransfer.DataFlavor
-import java.awt.datatransfer.StringSelection
import java.io.File
-import java.io.FileReader
-import java.nio.charset.StandardCharsets
import java.text.NumberFormat
import java.util.*
-import java.util.regex.Pattern
import kotlin.math.roundToInt
import kotlin.math.roundToLong
@@ -54,12 +51,13 @@ object GhostCounter {
val config get() = SkyHanniMod.feature.ghostCounter
val hidden get() = ProfileStorageData.profileSpecific?.ghostCounter
private var display = emptyList<List<Any>>()
- private var ghostCounterV3File = File("." + File.separator + "config" + File.separator + "ChatTriggers" + File.separator + "modules" + File.separator + "GhostCounterV3" + File.separator + ".persistantData.json")
+ var ghostCounterV3File = File("." + File.separator + "config" + File.separator + "ChatTriggers" + File.separator + "modules" + File.separator + "GhostCounterV3" + File.separator + ".persistantData.json")
private val skillXPPattern = "[+](?<gained>[0-9,.]+) \\((?<current>[0-9,.]+)(?:\\/(?<total>[0-9,.]+))?\\)".toPattern()
private val combatSectionPattern = ".*[+](?<gained>[0-9,.]+) (?<skillName>[A-Za-z]+) \\((?<progress>(?:(?:(?:(?<current>[0-9.,]+)\\/(?<total>[0-9.,]+))|(?:(?<percent>[0-9.]+)%))))\\).*".toPattern()
private val killComboExpiredPattern = "§cYour Kill Combo has expired! You reached a (?<combo>.*) Kill Combo!".toPattern()
private val ghostXPPattern = "(?<current>\\d+(?:\\.\\d+)?(?:,\\d+)?[kK]?)\\/(?<total>\\d+(?:\\.\\d+)?(?:,\\d+)?[kKmM]?)".toPattern()
- private val bestiaryPattern = "BESTIARY Ghost .*➜(?<newLevel>.*)".toPattern()
+ private val bestiaryPattern = ".*(?:§\\d|§\\w)+BESTIARY (?:§\\d|§\\w)+Ghost (?:§\\d|§\\w)(?<previousLevel>\\d)➜(?:§\\d|§\\w)(?<nextLevel>\\d+).*".toPattern() // &r&3&lBESTIARY &b&lGhost &89➜&b10&r
+ private val skillLevelPattern = ".*§e§lSkills: §r§a(?<skillName>.*) (?<skillLevel>\\d+).*".toPattern()
private val format = NumberFormat.getInstance()
private var percent: Float = 0.0f
private var totalSkillXp = 0
@@ -67,7 +65,6 @@ object GhostCounter {
private var skillText = ""
private var lastParsedSkillSection = ""
private var lastSkillProgressString: String? = null
- private const val exportPrefix = "gc/"
private var lastXp: String = "0"
private var gain: Int = 0
private var num: Double = 0.0
@@ -75,46 +72,16 @@ object GhostCounter {
private var notifyCTModule = true
var bestiaryCurrentKill = 0
private var killETA = ""
- private var session = mutableMapOf(
- KILLS to 0.0,
- SORROWCOUNT to 0.0,
- VOLTACOUNT to 0.0,
- PLASMACOUNT to 0.0,
- GHOSTLYBOOTS to 0.0,
- BAGOFCASH to 0.0,
- TOTALDROPS to 0.0,
- SCAVENGERCOINS to 0.0,
- MAXKILLCOMBO to 0.0,
- SKILLXPGAINED to 0.0
- )
- val bestiaryData = mutableMapOf<Int, Int>().apply {
- val commonValue = 100_000
- for (i in 1..46) {
- this[i] = when (i) {
- 1 -> 10
- 2 -> 15
- 3 -> 75
- 4 -> 150
- 5 -> 250
- 6 -> 500
- 7 -> 1_500
- 8 -> 2_500
- 9 -> 5_000
- 10 -> 15_000
- 11 -> 25_000
- 12 -> 50_000
- else -> commonValue
- }
- }
- }
+ private var currentSkill = ""
+ private var currentSkillLevel = -1
@SubscribeEvent
fun onRenderOverlay(event: GuiRenderEvent.GameOverlayRenderEvent) {
if (!isEnabled()) return
if (config.onlyOnMist && !inMist) return
config.position.renderStringsAndItems(display,
- extraSpace = config.extraSpace,
- posLabel = "Ghost Counter")
+ extraSpace = config.extraSpace,
+ posLabel = "Ghost Counter")
}
private fun formatDisplay(map: List<List<Any>>): List<List<Any>> {
@@ -129,38 +96,12 @@ object GhostCounter {
display = formatDisplay(drawDisplay())
}
- private fun prettyTime(millis: Long): Map<String, String> {
- val seconds = millis / 1000 % 60
- val minutes = millis / 1000 / 60 % 60
- val hours = millis / 1000 / 60 / 60 % 24
- val days = millis / 1000 / 60 / 60 / 24
- return buildMap {
- if (millis < 0) {
- clear()
- } else if (minutes == 0L && hours == 0L && days == 0L) {
- put("seconds", seconds.toString())
- } else if (hours == 0L && days == 0L) {
- put("seconds", seconds.toString())
- put("minutes", minutes.toString())
- } else if (days == 0L) {
- put("seconds", seconds.toString())
- put("minutes", minutes.toString())
- put("hours", hours.toString())
- } else {
- put("seconds", seconds.toString())
- put("minutes", minutes.toString())
- put("hours", hours.toString())
- put("days", days.toString())
- }
- }
- }
-
private fun drawDisplay() = buildList<List<Any>> {
- val value: Int = when (SORROWCOUNT.get()) {
+ val ghostKillPerSorrow: Int = when (SORROWCOUNT.get()) {
0.0 -> 0
else -> "${((((KILLS.get() / SORROWCOUNT.get()) + Math.ulp(1.0)) * 100) / 100).roundToInt()}".toInt()
}
- val mgc = when (TOTALDROPS.get()) {
+ val avgMagicFind = when (TOTALDROPS.get()) {
0.0 -> "0"
else -> "${((((hidden?.totalMF!! / TOTALDROPS.get()) + Math.ulp(1.0)) * 100) / 100).roundToPrecision(2)}"
}
@@ -226,10 +167,10 @@ object GhostCounter {
val time = buildString {
if (timeMap.isNotEmpty()) {
val formatMap = mapOf(
- "%days%" to "days",
- "%hours%" to "hours",
- "%minutes%" to "minutes",
- "%seconds%" to "seconds"
+ "%days%" to "days",
+ "%hours%" to "hours",
+ "%minutes%" to "minutes",
+ "%seconds%" to "seconds"
)
for ((format, key) in formatMap) {
if (etaFormatting.time.contains(format)) {
@@ -251,12 +192,12 @@ object GhostCounter {
addAsSingletonList(config.textFormatting.ghostKilledFormat.formatText(KILLS.getInt(), KILLS.getInt(true)))
addAsSingletonList(config.textFormatting.sorrowsFormat.formatText(SORROWCOUNT.getInt(), SORROWCOUNT.getInt(true)))
addAsSingletonList(config.textFormatting.ghostSinceSorrowFormat.formatText(GHOSTSINCESORROW.getInt()))
- addAsSingletonList(config.textFormatting.ghostKillPerSorrowFormat.formatText(value))
+ addAsSingletonList(config.textFormatting.ghostKillPerSorrowFormat.formatText(ghostKillPerSorrow))
addAsSingletonList(config.textFormatting.voltasFormat.formatText(VOLTACOUNT.getInt(), VOLTACOUNT.getInt(true)))
addAsSingletonList(config.textFormatting.plasmasFormat.formatText(PLASMACOUNT.getInt(), PLASMACOUNT.getInt(true)))
addAsSingletonList(config.textFormatting.ghostlyBootsFormat.formatText(GHOSTLYBOOTS.getInt(), GHOSTLYBOOTS.getInt(true)))
addAsSingletonList(config.textFormatting.bagOfCashFormat.formatText(BAGOFCASH.getInt(), BAGOFCASH.getInt(true)))
- addAsSingletonList(config.textFormatting.avgMagicFindFormat.formatText(mgc))
+ addAsSingletonList(config.textFormatting.avgMagicFindFormat.formatText(avgMagicFind))
addAsSingletonList(config.textFormatting.scavengerCoinsFormat.formatText(SCAVENGERCOINS.getInt(), SCAVENGERCOINS.getInt(true)))
addAsSingletonList(config.textFormatting.killComboFormat.formatText(KILLCOMBO.getInt(), MAXKILLCOMBO.getInt(true)))
addAsSingletonList(config.textFormatting.highestKillComboFormat.formatText(MAXKILLCOMBO.getInt(), MAXKILLCOMBO.getInt(true)))
@@ -266,10 +207,34 @@ object GhostCounter {
addAsSingletonList(killHourFormatting.base.formatText(killHour))
addAsSingletonList(etaFormatting.base.formatText(eta).formatText(killETA))
- val rate = 0.12 * (1 + (mgc.toDouble() / 100))
- val price = (BazaarApi.getBazaarDataByInternalName("SORROW")?.sellPrice ?: 0).toLong()
- val final: String = (killInterp * price * (rate / 100)).toLong().addSeparators()
+ val rate = 0.12 * (1 + (avgMagicFind.toDouble() / 100))
+ val sorrowValue = (BazaarApi.getBazaarDataByInternalName("SORROW")?.buyPrice ?: 0).toLong()
+ val final: String = (killInterp * sorrowValue * (rate / 100)).toLong().addSeparators()
+ val plasmaValue = (BazaarApi.getBazaarDataByInternalName("PLASMA")?.buyPrice ?: 0).toLong()
+ val voltaValue = (BazaarApi.getBazaarDataByInternalName("VOLTA")?.buyPrice ?: 0).toLong()
+ var moneyMade: Long = 0
+ val priceMap = listOf(
+ Triple("Sorrow", SORROWCOUNT.getInt(), sorrowValue),
+ Triple("Plasma", PLASMACOUNT.getInt(), plasmaValue),
+ Triple("Volta", VOLTACOUNT.getInt(), voltaValue),
+ Triple("Bag Of Cash", BAGOFCASH.getInt(), 1_000_000),
+ Triple("Scavenger Coins", SCAVENGERCOINS.getInt(), 1),
+ Triple("Ghostly Boots", GHOSTLYBOOTS.getInt(), 77_777)
+ )
+ val moneyMadeTips = buildList {
+ for ((name, count, value) in priceMap) {
+ moneyMade += (count.toLong() * value.toLong())
+ add("$name: §b${value.addSeparators()} §fx §b${count.addSeparators()} §f= §6${(value.toLong() * count.toLong()).addSeparators()}")
+ }
+ add("§bTotal: §6${moneyMade.addSeparators()}")
+ add("§eClick to copy to clipboard!")
+ }
+ val moneyMadeWithClickableTips = Renderable.clickAndHover(
+ config.textFormatting.moneyMadeFormat.formatText(moneyMade.addSeparators()),
+ moneyMadeTips
+ ) { OSUtils.copyToClipboard(moneyMadeTips.joinToString("\n").removeColor()) }
addAsSingletonList(config.textFormatting.moneyHourFormat.formatText(final))
+ addAsSingletonList(moneyMadeWithClickableTips)
}
@SubscribeEvent
@@ -281,7 +246,8 @@ object GhostCounter {
val current = group("current")
if (current != lastXp) {
val res = if (current.contains(".")) {
- "(?:[0-9,]+){3,}".toRegex().find(current)?.groupValues?.get(1) ?: "0"
+ // current.split(".")[0] ?: "0"
+ "([0-9,]+).*".toRegex().find(current)?.groupValues?.get(1) ?: "0"
} else {
current.replace("\\D".toRegex(), "")
}
@@ -309,7 +275,7 @@ object GhostCounter {
clickableChat("§6[SkyHanni] GhostCounterV3 ChatTriggers module has been detected, do you want to import saved data ? Click here to import data", "shimportghostcounterdata")
}
}
- inMist = LorenzUtils.skyBlockArea == "The Mist"
+ inMist = Minecraft.getMinecraft().thePlayer.posY <= 110 // some area don't show as 'The Mist' in the scoreboard
update()
}
if (event.isMod(40)) {
@@ -321,6 +287,7 @@ object GhostCounter {
@SubscribeEvent
fun onActionBar(event: LorenzActionBarEvent) {
if (!isEnabled()) return
+ if (!inMist) return
combatSectionPattern.matchMatcher(event.message) {
if (group("skillName").lowercase() != "combat") return
parseCombatSection(event.message)
@@ -341,7 +308,7 @@ object GhostCounter {
var parse = true
if (skillPercent) {
percent = nf.parse(group("percent")).toFloat()
- val level = XPInformation.getInstance().getSkillInfo(skillName).level
+ val level = if (currentSkill == "Combat" && currentSkillLevel != -1) currentSkillLevel else XPInformation.getInstance().getSkillInfo(skillName)?.level ?: 0
if (level > 0) {
totalSkillXp = SkillExperience.getExpForNextLevel(level)
currentSkillXp = totalSkillXp * percent / 100
@@ -373,10 +340,20 @@ object GhostCounter {
}
@SubscribeEvent
+ fun onTabUpdate(event: TabListUpdateEvent){
+ if (!isEnabled()) return
+ for (line in event.tabList){
+ skillLevelPattern.matchMatcher(line){
+ currentSkill = group("skillName")
+ currentSkillLevel = group("skillLevel").toInt()
+ }
+ }
+ }
+ @SubscribeEvent
fun onChat(event: LorenzChatEvent) {
if (!isEnabled()) return
if (LorenzUtils.skyBlockIsland != IslandType.DWARVEN_MINES) return
- for (opt in Option.values()) {
+ for (opt in GhostData.Option.values()) {
val pattern = opt.pattern ?: continue
pattern.matchMatcher(event.message) {
when (opt) {
@@ -384,7 +361,7 @@ object GhostCounter {
opt.add(1.0)
opt.add(1.0, true)
hidden?.totalMF = hidden?.totalMF?.plus(group("mf").substring(4).toDouble())
- ?: group("mf").substring(4).toDouble()
+ ?: group("mf").substring(4).toDouble()
TOTALDROPS.add(1.0)
if (opt == SORROWCOUNT)
GHOSTSINCESORROW.set(0.0)
@@ -408,10 +385,10 @@ object GhostCounter {
}
killComboExpiredPattern.matchMatcher(event.message) {
if (KILLCOMBO.getInt() > MAXKILLCOMBO.getInt()) {
- MAXKILLCOMBO.set(group("combo").toDouble())
+ MAXKILLCOMBO.set(group("combo").formatNumber().toDouble())
}
if (KILLCOMBO.getInt() > MAXKILLCOMBO.getInt(true)) {
- MAXKILLCOMBO.set(group("combo").toDouble(), true)
+ MAXKILLCOMBO.set(group("combo").formatNumber().toDouble(), true)
}
KILLCOMBOCOINS.set(0.0)
KILLCOMBO.set(0.0)
@@ -469,279 +446,4 @@ object GhostCounter {
fun isEnabled(): Boolean {
return LorenzUtils.inSkyBlock && config.enabled && LorenzUtils.skyBlockIsland == IslandType.DWARVEN_MINES
}
-
- private fun percent(number: Double): String {
- return "${((number / 3_000_000) * 100).roundToPrecision(4)}"
- }
-
- fun reset() {
- for (opt in Option.values()) {
- opt.set(0.0)
- opt.set(0.0, true)
- }
- hidden?.totalMF = 0.0
- update()
- }
-
- private fun isUsingCTGhostCounter(): Boolean {
- return ghostCounterV3File.exists() && ghostCounterV3File.isFile
- }
-
- fun importCTGhostCounterData() {
- val c = ProfileStorageData.profileSpecific?.ghostCounter ?: return
- if (isUsingCTGhostCounter()) {
- if (c.ctDataImported) {
- chat("§e[SkyHanni] §cYou already imported GhostCounterV3 data!")
- return
- }
- val json = ConfigManager.gson.fromJson(FileReader(ghostCounterV3File), com.google.gson.JsonObject::class.java)
- GHOSTSINCESORROW.add(json["ghostsSinceSorrow"].asDouble)
- SORROWCOUNT.add(json["sorrowCount"].asDouble)
- BAGOFCASH.add(json["BagOfCashCount"].asDouble)
- PLASMACOUNT.add(json["PlasmaCount"].asDouble)
- VOLTACOUNT.add(json["VoltaCount"].asDouble)
- GHOSTLYBOOTS.add(json["GhostlyBootsCount"].asDouble)
- KILLS.add(json["ghostsKilled"].asDouble)
- hidden?.totalMF = hidden?.totalMF?.plus(json["TotalMF"].asDouble) ?: json["TotalMF"].asDouble
- TOTALDROPS.add(json["TotalDrops"].asDouble)
- c.ctDataImported = true
- chat("§e[SkyHanni] §aImported data successfully!")
- } else
- chat("§e[SkyHanni] §cGhostCounterV3 ChatTriggers module not found!")
- }
-
- private fun String.formatText(value: Int, session: Int = -1): String {
- return Utils.chromaStringByColourCode(this.replace("%value%", value.addSeparators())
- .replace("%session%", session.addSeparators())
- .replace("&", "§"))
- }
-
- private fun String.formatText(t: String): String {
- return Utils.chromaStringByColourCode(this.replace("%value%", t)
- .replace("&", "§"))
- }
-
- private fun String.formatText(value: Double, session: Double): String {
- return Utils.chromaStringByColourCode(this.replace("%value%", value.roundToPrecision(2).addSeparators())
- .replace("%session%", session.roundToPrecision(2).addSeparators())
- .replace("&", "§"))
- }
-
- private fun String.formatBestiary(currentKill: Int, killNeeded: Int): String {
- return Utils.chromaStringByColourCode(
- this.replace("%currentKill%", if (config.showMax) bestiaryCurrentKill.addSeparators() else currentKill.addSeparators())
- .replace("%percentNumber%", percent(bestiaryCurrentKill.toDouble()))
- .replace("%killNeeded%", NumberUtil.format(killNeeded))
- .replace("%currentLevel%", if (hidden?.bestiaryNextLevel?.toInt()!! < 0) "46" else "${hidden?.bestiaryNextLevel?.toInt()!! - 1}")
- .replace("%nextLevel%", if (config.showMax) "46" else "${hidden?.bestiaryNextLevel?.toInt()!!}")
- .replace("&", "§"))
- }
-
- enum class Option(val pattern: Pattern? = null) {
- KILLS,
- SORROWCOUNT("§6§lRARE DROP! §r§9Sorrow §r§b\\([+](?<mf>.*)% §r§b✯ Magic Find§r§b\\)".toPattern()),
- VOLTACOUNT("§6§lRARE DROP! §r§9Volta §r§b\\([+](?<mf>.*)% §r§b✯ Magic Find§r§b\\)".toPattern()),
- PLASMACOUNT("§6§lRARE DROP! §r§9Plasma §r§b\\([+](?<mf>.*)% §r§b✯ Magic Find§r§b\\)".toPattern()),
- GHOSTLYBOOTS("§6§lRARE DROP! §r§9Ghostly Boots §r§b\\([+](?<mf>.*)% §r§b✯ Magic Find§r§b\\)".toPattern()),
- BAGOFCASH("§eThe ghost's death materialized §r§61,000,000 coins §r§efrom the mists!".toPattern()),
- KILLCOMBOCOINS("[+]\\d+ Kill Combo [+](?<coin>.*) coins per kill".toPattern()),
- TOTALDROPS,
- GHOSTSINCESORROW,
- SCAVENGERCOINS,
- MAXKILLCOMBO,
- KILLCOMBO("[+]\\d+ Kill Combo [+](?<coin>.*) coins per kill".toPattern()),
- SKILLXPGAINED;
-
- fun add(i: Double, s: Boolean = false) {
- if (s)
- session[this] = session[this]?.plus(i) ?: i
- else
- hidden?.data?.set(this, hidden?.data?.get(this)?.plus(i) ?: i)
- }
-
- fun set(i: Double, s: Boolean = false) {
- if (s)
- session[this] = i
- else
- hidden?.data?.set(this, i)
- }
-
- fun getInt(s: Boolean = false): Int {
- return if (s)
- session[this]?.roundToInt() ?: 0
- else
- hidden?.data?.get(this)?.roundToInt() ?: 0
- }
-
- fun get(s: Boolean = false): Double {
- return if (s)
- session[this] ?: 0.0
- else
- hidden?.data?.get(this) ?: 0.0
- }
- }
-
- fun importFormatting() {
- val base64: String = try {
- Toolkit.getDefaultToolkit().systemClipboard.getData(DataFlavor.stringFlavor) as String
- } catch (e: Exception) {
- return
- }
-
- if (base64.length <= exportPrefix.length) return
- val jsonString = try {
- val t = String(Base64.getDecoder().decode(base64.trim()))
- if (!t.startsWith(exportPrefix)) return
- t.substring(exportPrefix.length)
- } catch (e: IllegalArgumentException) {
- return
- }
-
- val list = try {
- JsonParser().parse(jsonString).asJsonArray
- .filter { it.isJsonPrimitive }
- .map { it.asString }
- } catch (e: Exception) {
- return
- }
-
- if (list.isNotEmpty()) {
- with(config.textFormatting) {
- titleFormat = list[0]
- ghostKilledFormat = list[1]
- sorrowsFormat = list[2]
- ghostSinceSorrowFormat = list[3]
- ghostKillPerSorrowFormat = list[4]
- voltasFormat = list[5]
- plasmasFormat = list[6]
- ghostlyBootsFormat = list[7]
- bagOfCashFormat = list[8]
- avgMagicFindFormat = list[9]
- scavengerCoinsFormat = list[10]
- killComboFormat = list[11]
- highestKillComboFormat = list[12]
- skillXPGainFormat = list[13]
- with(xpHourFormatting) {
- base = list[14]
- noData = list[15]
- paused = list[16]
- }
- with(bestiaryFormatting) {
- base = list[17]
- openMenu = list[18]
- maxed = list[19]
- showMax_progress = list[20]
- progress = list[21]
- }
- with(killHourFormatting) {
- base = list[22]
- noData = list[23]
- paused = list[24]
- }
- with(etaFormatting) {
- base = list[25]
- maxed = list[26]
- noData = list[27]
- progress = list[28]
- time = list[29]
- }
- moneyHourFormat = list[30]
- }
- }
- }
-
- fun exportFormatting() {
- val list = mutableListOf<String>()
- with(config.textFormatting) {
- list.add(titleFormat)
- list.add(ghostKilledFormat)
- list.add(sorrowsFormat)
- list.add(ghostSinceSorrowFormat)
- list.add(ghostKillPerSorrowFormat)
- list.add(voltasFormat)
- list.add(plasmasFormat)
- list.add(ghostlyBootsFormat)
- list.add(bagOfCashFormat)
- list.add(avgMagicFindFormat)
- list.add(scavengerCoinsFormat)
- list.add(killComboFormat)
- list.add(highestKillComboFormat)
- list.add(skillXPGainFormat)
- with(xpHourFormatting) {
- list.add(base)
- list.add(noData)
- list.add(paused)
- }
- with(bestiaryFormatting) {
- list.add(base)
- list.add(openMenu)
- list.add(maxed)
- list.add(showMax_progress)
- list.add(progress)
- }
- with(killHourFormatting) {
- list.add(base)
- list.add(noData)
- list.add(paused)
- }
- with(etaFormatting) {
- list.add(base)
- list.add(maxed)
- list.add(noData)
- list.add(progress)
- list.add(time)
- }
- list.add(moneyHourFormat)
- }
- val jsonArray = JsonArray()
- for (l in list) {
- jsonArray.add(JsonPrimitive(l))
- }
- val base64 = Base64.getEncoder().encodeToString((exportPrefix + jsonArray).toByteArray(StandardCharsets.UTF_8))
- Toolkit.getDefaultToolkit().systemClipboard.setContents(StringSelection(base64), null)
- }
-
- fun resetFormatting() {
- with(config.textFormatting) {
- titleFormat = "&6Ghost Counter"
- ghostKilledFormat = " &6Ghost Killed: &b%value% &7(%session%)"
- sorrowsFormat = " &6Sorrow: &b%value% &7(%session%)"
- ghostSinceSorrowFormat = " &6Ghost since Sorrow: &b%value%"
- ghostKillPerSorrowFormat = " &6Ghosts/Sorrow: &b%value%"
- voltasFormat = " &6Volta: &b%value% &7(%session%)"
- plasmasFormat = " &6Plasmas: &b%value% &7(%session%)"
- ghostlyBootsFormat = " &6Ghostly Boots: &b%value% &7(%session%)"
- bagOfCashFormat = " &6Bag Of Cash: &b%value% &7(%session%)"
- avgMagicFindFormat = " &6Avg Magic Find: &b%value%"
- scavengerCoinsFormat = " &6Scavenger Coins: &b%value% &7(%session%)"
- killComboFormat = " &6Kill Combo: &b%value%"
- highestKillComboFormat = " &6Highest Kill Combo: &b%value% &7(%session%)"
- skillXPGainFormat = " &6Skill XP Gained: &b%value% &7(%session%)"
- with(xpHourFormatting) {
- base = " &6XP/h: &b%value%"
- noData = "&bN/A"
- paused = "&c(PAUSED)"
- }
- with(bestiaryFormatting) {
- base = " &6Bestiary %currentLevel%->%nextLevel%: &b%value%"
- openMenu = "§cOpen Bestiary Menu !"
- maxed = "%currentKill% (&c&lMaxed!)"
- showMax_progress = "%currentKill%/3M (%percentNumber%%)"
- progress = "%currentKill%/%killNeeded%"
- }
- with(killHourFormatting) {
- base = " &6Kill/h: &b%value%"
- noData = "§bN/A"
- paused = "&c(PAUSED)"
- }
- with(etaFormatting) {
- base = " &6ETA: &b%value%"
- maxed = "§c§lMAXED!"
- noData = "§bN/A"
- progress = "§b%value%"
- time = "&6%days%%hours%%minutes%%seconds%"
- }
- moneyHourFormat = " &6$/h: &b%value%"
- }
- }
} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostData.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostData.kt
new file mode 100644
index 000000000..de5696ee8
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostData.kt
@@ -0,0 +1,86 @@
+package at.hannibal2.skyhanni.features.misc.ghostcounter
+
+import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostData.Option.*
+import java.util.regex.Pattern
+import kotlin.math.roundToInt
+
+object GhostData {
+
+ private var session = mutableMapOf(
+ KILLS to 0.0,
+ SORROWCOUNT to 0.0,
+ VOLTACOUNT to 0.0,
+ PLASMACOUNT to 0.0,
+ GHOSTLYBOOTS to 0.0,
+ BAGOFCASH to 0.0,
+ TOTALDROPS to 0.0,
+ SCAVENGERCOINS to 0.0,
+ MAXKILLCOMBO to 0.0,
+ SKILLXPGAINED to 0.0
+ )
+
+ val bestiaryData = mutableMapOf<Int, Int>().apply {
+ val commonValue = 100_000
+ for (i in 1..46) {
+ this[i] = when (i) {
+ 1 -> 10
+ 2 -> 15
+ 3 -> 75
+ 4 -> 150
+ 5 -> 250
+ 6 -> 500
+ 7 -> 1_500
+ 8 -> 2_500
+ 9 -> 5_000
+ 10 -> 15_000
+ 11 -> 25_000
+ 12 -> 50_000
+ else -> commonValue
+ }
+ }
+ }
+
+ enum class Option(val pattern: Pattern? = null) {
+ KILLS,
+ SORROWCOUNT("§6§lRARE DROP! §r§9Sorrow §r§b\\([+](?<mf>.*)% §r§b✯ Magic Find§r§b\\)".toPattern()),
+ VOLTACOUNT("§6§lRARE DROP! §r§9Volta §r§b\\([+](?<mf>.*)% §r§b✯ Magic Find§r§b\\)".toPattern()),
+ PLASMACOUNT("§6§lRARE DROP! §r§9Plasma §r§b\\([+](?<mf>.*)% §r§b✯ Magic Find§r§b\\)".toPattern()),
+ GHOSTLYBOOTS("§6§lRARE DROP! §r§9Ghostly Boots §r§b\\([+](?<mf>.*)% §r§b✯ Magic Find§r§b\\)".toPattern()),
+ BAGOFCASH("§eThe ghost's death materialized §r§61,000,000 coins §r§efrom the mists!".toPattern()),
+ KILLCOMBOCOINS("[+]\\d+ Kill Combo [+](?<coin>.*) coins per kill".toPattern()),
+ TOTALDROPS,
+ GHOSTSINCESORROW,
+ SCAVENGERCOINS,
+ MAXKILLCOMBO,
+ KILLCOMBO("[+]\\d+ Kill Combo [+](?<coin>.*) coins per kill".toPattern()),
+ SKILLXPGAINED;
+
+ fun add(i: Double, s: Boolean = false) {
+ if (s)
+ session[this] = session[this]?.plus(i) ?: i
+ else
+ GhostCounter.hidden?.data?.set(this, GhostCounter.hidden?.data?.get(this)?.plus(i) ?: i)
+ }
+
+ fun set(i: Double, s: Boolean = false) {
+ if (s)
+ session[this] = i
+ else
+ GhostCounter.hidden?.data?.set(this, i)
+ }
+
+ fun getInt(s: Boolean = false): Int {
+ return if (s)
+ session[this]?.roundToInt() ?: 0
+ else
+ GhostCounter.hidden?.data?.get(this)?.roundToInt() ?: 0
+ }
+
+ fun get(s: Boolean = false): Double {
+ return if (s)
+ session[this] ?: 0.0
+ else
+ GhostCounter.hidden?.data?.get(this) ?: 0.0
+ }
+ }
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostFormatting.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostFormatting.kt
new file mode 100644
index 000000000..304be561d
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostFormatting.kt
@@ -0,0 +1,182 @@
+package at.hannibal2.skyhanni.features.misc.ghostcounter
+
+import com.google.gson.JsonArray
+import com.google.gson.JsonParser
+import com.google.gson.JsonPrimitive
+import java.awt.Toolkit
+import java.awt.datatransfer.DataFlavor
+import java.awt.datatransfer.StringSelection
+import java.nio.charset.StandardCharsets
+import java.util.*
+
+object GhostFormatting {
+
+ private const val exportPrefix = "gc/"
+
+ fun importFormat() {
+ val base64: String = try {
+ Toolkit.getDefaultToolkit().systemClipboard.getData(DataFlavor.stringFlavor) as String
+ } catch (e: Exception) {
+ return
+ }
+
+ if (base64.length <= exportPrefix.length) return
+ val jsonString = try {
+ val t = String(Base64.getDecoder().decode(base64.trim()))
+ if (!t.startsWith(exportPrefix)) return
+ t.substring(exportPrefix.length)
+ } catch (e: IllegalArgumentException) {
+ return
+ }
+
+ val list = try {
+ JsonParser().parse(jsonString).asJsonArray
+ .filter { it.isJsonPrimitive }
+ .map { it.asString }
+ } catch (e: Exception) {
+ return
+ }
+
+ if (list.isNotEmpty()) {
+ with(GhostCounter.config.textFormatting) {
+ titleFormat = list[0]
+ ghostKilledFormat = list[1]
+ sorrowsFormat = list[2]
+ ghostSinceSorrowFormat = list[3]
+ ghostKillPerSorrowFormat = list[4]
+ voltasFormat = list[5]
+ plasmasFormat = list[6]
+ ghostlyBootsFormat = list[7]
+ bagOfCashFormat = list[8]
+ avgMagicFindFormat = list[9]
+ scavengerCoinsFormat = list[10]
+ killComboFormat = list[11]
+ highestKillComboFormat = list[12]
+ skillXPGainFormat = list[13]
+ with(xpHourFormatting) {
+ base = list[14]
+ noData = list[15]
+ paused = list[16]
+ }
+ with(bestiaryFormatting) {
+ base = list[17]
+ openMenu = list[18]
+ maxed = list[19]
+ showMax_progress = list[20]
+ progress = list[21]
+ }
+ with(killHourFormatting) {
+ base = list[22]
+ noData = list[23]
+ paused = list[24]
+ }
+ with(etaFormatting) {
+ base = list[25]
+ maxed = list[26]
+ noData = list[27]
+ progress = list[28]
+ time = list[29]
+ }
+ moneyHourFormat = list[30]
+ moneyMadeFormat = list[31]
+ }
+ }
+ }
+
+ fun export() {
+ val list = mutableListOf<String>()
+ with(GhostCounter.config.textFormatting) {
+ list.add(titleFormat)
+ list.add(ghostKilledFormat)
+ list.add(sorrowsFormat)
+ list.add(ghostSinceSorrowFormat)
+ list.add(ghostKillPerSorrowFormat)
+ list.add(voltasFormat)
+ list.add(plasmasFormat)
+ list.add(ghostlyBootsFormat)
+ list.add(bagOfCashFormat)
+ list.add(avgMagicFindFormat)
+ list.add(scavengerCoinsFormat)
+ list.add(killComboFormat)
+ list.add(highestKillComboFormat)
+ list.add(skillXPGainFormat)
+ with(xpHourFormatting) {
+ list.add(base)
+ list.add(noData)
+ list.add(paused)
+ }
+ with(bestiaryFormatting) {
+ list.add(base)
+ list.add(openMenu)
+ list.add(maxed)
+ list.add(showMax_progress)
+ list.add(progress)
+ }
+ with(killHourFormatting) {
+ list.add(base)
+ list.add(noData)
+ list.add(paused)
+ }
+ with(etaFormatting) {
+ list.add(base)
+ list.add(maxed)
+ list.add(noData)
+ list.add(progress)
+ list.add(time)
+ }
+ list.add(moneyHourFormat)
+ list.add(moneyMadeFormat)
+ }
+ val jsonArray = JsonArray()
+ for (l in list) {
+ jsonArray.add(JsonPrimitive(l))
+ }
+ val base64 = Base64.getEncoder().encodeToString((exportPrefix + jsonArray).toByteArray(StandardCharsets.UTF_8))
+ Toolkit.getDefaultToolkit().systemClipboard.setContents(StringSelection(base64), null)
+ }
+
+ fun reset() {
+ with(GhostCounter.config.textFormatting) {
+ titleFormat = "&6Ghost Counter"
+ ghostKilledFormat = " &6Ghost Killed: &b%value% &7(%session%)"
+ sorrowsFormat = " &6Sorrow: &b%value% &7(%session%)"
+ ghostSinceSorrowFormat = " &6Ghost since Sorrow: &b%value%"
+ ghostKillPerSorrowFormat = " &6Ghosts/Sorrow: &b%value%"
+ voltasFormat = " &6Volta: &b%value% &7(%session%)"
+ plasmasFormat = " &6Plasmas: &b%value% &7(%session%)"
+ ghostlyBootsFormat = " &6Ghostly Boots: &b%value% &7(%session%)"
+ bagOfCashFormat = " &6Bag Of Cash: &b%value% &7(%session%)"
+ avgMagicFindFormat = " &6Avg Magic Find: &b%value%"
+ scavengerCoinsFormat = " &6Scavenger Coins: &b%value% &7(%session%)"
+ killComboFormat = " &6Kill Combo: &b%value%"
+ highestKillComboFormat = " &6Highest Kill Combo: &b%value% &7(%session%)"
+ skillXPGainFormat = " &6Skill XP Gained: &b%value% &7(%session%)"
+ with(xpHourFormatting) {
+ base = " &6XP/h: &b%value%"
+ noData = "&bN/A"
+ paused = "&c(PAUSED)"
+ }
+ with(bestiaryFormatting) {
+ base = " &6Bestiary %currentLevel%->%nextLevel%: &b%value%"
+ openMenu = "§cOpen Bestiary Menu !"
+ maxed = "%currentKill% (&c&lMaxed!)"
+ showMax_progress = "%currentKill%/3M (%percentNumber%%)"
+ progress = "%currentKill%/%killNeeded%"
+ }
+ with(killHourFormatting) {
+ base = " &6Kill/h: &b%value%"
+ noData = "§bN/A"
+ paused = "&c(PAUSED)"
+ }
+ with(etaFormatting) {
+ base = " &6ETA: &b%value%"
+ maxed = "§c§lMAXED!"
+ noData = "§bN/A"
+ progress = "§b%value%"
+ time = "&6%days%%hours%%minutes%%seconds%"
+ }
+ moneyHourFormat = " &6$/h: &b%value%"
+ moneyMadeFormat = " &6Money made: &b%value%"
+ }
+ }
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostUtil.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostUtil.kt
new file mode 100644
index 000000000..95432ef82
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostUtil.kt
@@ -0,0 +1,107 @@
+package at.hannibal2.skyhanni.features.misc.ghostcounter
+
+import at.hannibal2.skyhanni.config.ConfigManager
+import at.hannibal2.skyhanni.data.ProfileStorageData
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.NumberUtil
+import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
+import at.hannibal2.skyhanni.utils.NumberUtil.roundToPrecision
+import io.github.moulberry.notenoughupdates.util.Utils
+import java.io.FileReader
+
+object GhostUtil {
+
+ fun reset() {
+ for (opt in GhostData.Option.values()) {
+ opt.set(0.0)
+ opt.set(0.0, true)
+ }
+ GhostCounter.hidden?.totalMF = 0.0
+ GhostCounter.update()
+ }
+
+ fun isUsingCTGhostCounter(): Boolean {
+ return GhostCounter.ghostCounterV3File.exists() && GhostCounter.ghostCounterV3File.isFile
+ }
+
+ fun prettyTime(millis: Long): Map<String, String> {
+ val seconds = millis / 1000 % 60
+ val minutes = millis / 1000 / 60 % 60
+ val hours = millis / 1000 / 60 / 60 % 24
+ val days = millis / 1000 / 60 / 60 / 24
+ return buildMap {
+ if (millis < 0) {
+ clear()
+ } else if (minutes == 0L && hours == 0L && days == 0L) {
+ put("seconds", seconds.toString())
+ } else if (hours == 0L && days == 0L) {
+ put("seconds", seconds.toString())
+ put("minutes", minutes.toString())
+ } else if (days == 0L) {
+ put("seconds", seconds.toString())
+ put("minutes", minutes.toString())
+ put("hours", hours.toString())
+ } else {
+ put("seconds", seconds.toString())
+ put("minutes", minutes.toString())
+ put("hours", hours.toString())
+ put("days", days.toString())
+ }
+ }
+ }
+
+ fun importCTGhostCounterData() {
+ val c = ProfileStorageData.profileSpecific?.ghostCounter ?: return
+ if (isUsingCTGhostCounter()) {
+ if (c.ctDataImported) {
+ LorenzUtils.chat("§e[SkyHanni] §cYou already imported GhostCounterV3 data!")
+ return
+ }
+ val json = ConfigManager.gson.fromJson(FileReader(GhostCounter.ghostCounterV3File), com.google.gson.JsonObject::class.java)
+ GhostData.Option.GHOSTSINCESORROW.add(json["ghostsSinceSorrow"].asDouble)
+ GhostData.Option.SORROWCOUNT.add(json["sorrowCount"].asDouble)
+ GhostData.Option.BAGOFCASH.add(json["BagOfCashCount"].asDouble)
+ GhostData.Option.PLASMACOUNT.add(json["PlasmaCount"].asDouble)
+ GhostData.Option.VOLTACOUNT.add(json["VoltaCount"].asDouble)
+ GhostData.Option.GHOSTLYBOOTS.add(json["GhostlyBootsCount"].asDouble)
+ GhostData.Option.KILLS.add(json["ghostsKilled"].asDouble)
+ GhostCounter.hidden?.totalMF = GhostCounter.hidden?.totalMF?.plus(json["TotalMF"].asDouble)
+ ?: json["TotalMF"].asDouble
+ GhostData.Option.TOTALDROPS.add(json["TotalDrops"].asDouble)
+ c.ctDataImported = true
+ LorenzUtils.chat("§e[SkyHanni] §aImported data successfully!")
+ } else
+ LorenzUtils.chat("§e[SkyHanni] §cGhostCounterV3 ChatTriggers module not found!")
+ }
+
+ fun String.formatText(value: Int, session: Int = -1): String {
+ return Utils.chromaStringByColourCode(this.replace("%value%", value.addSeparators())
+ .replace("%session%", session.addSeparators())
+ .replace("&", "§"))
+ }
+
+ fun String.formatText(t: String): String {
+ return Utils.chromaStringByColourCode(this.replace("%value%", t)
+ .replace("&", "§"))
+ }
+
+ fun String.formatText(value: Double, session: Double): String {
+ return Utils.chromaStringByColourCode(this.replace("%value%", value.roundToPrecision(2).addSeparators())
+ .replace("%session%", session.roundToPrecision(2).addSeparators())
+ .replace("&", "§"))
+ }
+
+ fun String.formatBestiary(currentKill: Int, killNeeded: Int): String {
+ return Utils.chromaStringByColourCode(
+ this.replace("%currentKill%", if (GhostCounter.config.showMax) GhostCounter.bestiaryCurrentKill.addSeparators() else currentKill.addSeparators())
+ .replace("%percentNumber%", percent(GhostCounter.bestiaryCurrentKill.toDouble()))
+ .replace("%killNeeded%", NumberUtil.format(killNeeded))
+ .replace("%currentLevel%", if (GhostCounter.hidden?.bestiaryNextLevel?.toInt()!! < 0) "46" else "${GhostCounter.hidden?.bestiaryNextLevel?.toInt()!! - 1}")
+ .replace("%nextLevel%", if (GhostCounter.config.showMax) "46" else "${GhostCounter.hidden?.bestiaryNextLevel?.toInt()!!}")
+ .replace("&", "§"))
+ }
+
+ private fun percent(number: Double): String {
+ return "${((number / 3_000_000) * 100).roundToPrecision(4)}"
+ }
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/CombatUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/CombatUtils.kt
index 83430cecb..5fdc63f46 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/CombatUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/CombatUtils.kt
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.utils
-import at.hannibal2.skyhanni.features.misc.GhostCounter
+import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostCounter
+import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostData
import io.github.moulberry.notenoughupdates.core.util.lerp.LerpUtils
import io.github.moulberry.notenoughupdates.util.XPInformation
@@ -67,42 +68,43 @@ object CombatUtils {
/*
Must be a better way to do this than repeating the calculateXP function
*/
- fun calculateETA(){
+ fun calculateETA() {
lastKillUpdate = System.currentTimeMillis()
killGainHourLast = killGainHour
val nextLevel = GhostCounter.hidden?.bestiaryNextLevel?.toInt() ?: return
val kill = GhostCounter.hidden?.bestiaryCurrentKill?.toInt() ?: return
- val sum = GhostCounter.bestiaryData.filterKeys { it <= nextLevel - 1 }.values.sum()
+ val sum = GhostData.bestiaryData.filterKeys { it <= nextLevel - 1 }.values.sum()
val cKill = sum + kill
val totalKill = if (GhostCounter.config.showMax) GhostCounter.bestiaryCurrentKill else cKill
- if (lastTotalKill > 0){
+ if (lastTotalKill > 0) {
val delta: Int = totalKill - lastTotalKill
- if (delta in 1..19){
+ if (delta in 1..19) {
gainTimer = GhostCounter.config.pauseTimer
killGainQueue.add(0, delta)
- while (killGainQueue.size > 30){
+ while (killGainQueue.size > 30) {
killGainQueue.removeLast()
}
var totalGain = 0
for (f in killGainQueue) totalGain += f
killGainHour = totalGain * (60 * 60) / killGainQueue.size
_isKilling = true
- }else if(gainTimer > 0){
+ } else if (gainTimer > 0) {
gainTimer--
killGainQueue.add(0, 0)
- while (killGainQueue.size > 30){
+ while (killGainQueue.size > 30) {
killGainQueue.removeLast()
}
var totalGain = 0
for (f in killGainQueue) totalGain += f
killGainHour = totalGain * (60 * 60) / killGainQueue.size
_isKilling = true
- }else if (delta <= 0){
+ } else if (delta <= 0) {
_isKilling = false
}
}
lastTotalKill = totalKill
}
+
/**
* Taken from NotEnoughUpdates
*/