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/Storage.java20
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/Slayer.java27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/SlayerAPI.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemProfitTracker.kt1
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerRngMeterDisplay.kt189
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt2
7 files changed, 245 insertions, 4 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt
index f36cc9d63..0021299fa 100644
--- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt
+++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt
@@ -42,7 +42,6 @@ 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
import at.hannibal2.skyhanni.features.misc.items.EstimatedItemValue
import at.hannibal2.skyhanni.features.misc.items.EstimatedWardrobePrice
import at.hannibal2.skyhanni.features.misc.tabcomplete.PlayerTabComplete
@@ -297,6 +296,7 @@ class SkyHanniMod {
loadModule(RestorePieceOfWizardPortalLore())
loadModule(QuickModMenuSwitch)
loadModule(ShowItemUuid())
+ loadModule(SlayerRngMeterDisplay())
loadModule(GhostCounter)
init()
diff --git a/src/main/java/at/hannibal2/skyhanni/config/Storage.java b/src/main/java/at/hannibal2/skyhanni/config/Storage.java
index 0a63e5928..ffac3b8ec 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/Storage.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/Storage.java
@@ -5,7 +5,7 @@ import at.hannibal2.skyhanni.features.garden.CropAccessory;
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.GhostCounter.Option;
+import at.hannibal2.skyhanni.features.misc.GhostCounter.Option;
import at.hannibal2.skyhanni.utils.LorenzVec;
import com.google.gson.annotations.Expose;
import net.minecraft.item.ItemStack;
@@ -259,5 +259,23 @@ public class Storage {
public boolean hidden;
}
}
+
+ @Expose
+ public Map<String, SlayerRngMeterStorage> slayerRngMeter = new HashMap<>();
+
+ public static class SlayerRngMeterStorage {
+
+ @Expose
+ public long currentMeter = -1;
+
+ @Expose
+ public long gainPerBoss = -1;
+
+ @Expose
+ public long goalNeeded = -1;
+
+ @Expose
+ public String itemGoal = "?";
+ }
}
} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Slayer.java b/src/main/java/at/hannibal2/skyhanni/config/features/Slayer.java
index 00392bcc4..852b54970 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/Slayer.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/Slayer.java
@@ -144,6 +144,33 @@ public class Slayer {
}
@Expose
+ @ConfigOption(name = "RNG Meter Display", desc = "")
+ @Accordion
+ public RngMeterDisplay rngMeterDisplay = new RngMeterDisplay();
+
+ public static class RngMeterDisplay {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Display amount of bosses needed until next rng meter drop.")
+ @ConfigEditorBoolean
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Warn Empty", desc = "Warn when no item is set in the rng meter.")
+ @ConfigEditorBoolean
+ public boolean warnEmpty = false;
+
+ @Expose
+ @ConfigOption(name = "Hide Chat", desc = "Hide the rng meter message from chat if current item is selected.")
+ @ConfigEditorBoolean
+ public boolean hideChat = true;
+
+ @Expose
+ public Position pos = new Position(410, 110, false, true);
+
+ }
+
+ @Expose
@ConfigOption(name = "Broken Wither Impact",
desc = "Warns when right-clicking with a Wither Impact weapon (e.g. Hyperion) no longer gains combat exp. " +
"Kill a mob with melee-hits to fix this hypixel bug. §cOnly works while doing slayers!"
diff --git a/src/main/java/at/hannibal2/skyhanni/data/SlayerAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/SlayerAPI.kt
index 1c5c76d92..7e44bd5cf 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/SlayerAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/SlayerAPI.kt
@@ -27,7 +27,7 @@ object SlayerAPI {
var questStartTime = 0L
var isInSlayerArea = false
- private var latestSlayerCategory = ""
+ var latestSlayerCategory = ""
private var latestProgressChangeTime = 0L
var latestWrongAreaWarning = 0L
private var latestSlayerProgress = ""
@@ -106,10 +106,14 @@ object SlayerAPI {
if (event.phase != TickEvent.Phase.START) return
if (!LorenzUtils.inSkyBlock) return
+ // wait with sending SlayerChangeEvent until profile is detected
+ if (ProfileStorageData.profileSpecific == null) return
+
val slayerQuest = ScoreboardData.sidebarLinesFormatted.nextAfter("Slayer Quest") ?: ""
if (slayerQuest != latestSlayerCategory) {
- SlayerChangeEvent(latestSlayerCategory, slayerQuest).postAndCatch()
+ val old = latestSlayerCategory
latestSlayerCategory = slayerQuest
+ SlayerChangeEvent(old, latestSlayerCategory).postAndCatch()
}
val slayerProgress = ScoreboardData.sidebarLinesFormatted.nextAfter("Slayer Quest", 2) ?: ""
diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemProfitTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemProfitTracker.kt
index f4e380fc4..c04d662e2 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemProfitTracker.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemProfitTracker.kt
@@ -211,6 +211,7 @@ object SlayerItemProfitTracker {
lastClickDelay = System.currentTimeMillis() + 500
} else {
itemProfit.hidden = !hidden
+ lastClickDelay = System.currentTimeMillis()
}
update()
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerRngMeterDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerRngMeterDisplay.kt
new file mode 100644
index 000000000..1d41aaeeb
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerRngMeterDisplay.kt
@@ -0,0 +1,189 @@
+package at.hannibal2.skyhanni.features.slayer
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.config.Storage
+import at.hannibal2.skyhanni.data.ProfileStorageData
+import at.hannibal2.skyhanni.data.SlayerAPI
+import at.hannibal2.skyhanni.data.TitleUtils
+import at.hannibal2.skyhanni.events.GuiRenderEvent
+import at.hannibal2.skyhanni.events.InventoryOpenEvent
+import at.hannibal2.skyhanni.events.LorenzChatEvent
+import at.hannibal2.skyhanni.events.SlayerChangeEvent
+import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
+import at.hannibal2.skyhanni.utils.ItemUtils.getLore
+import at.hannibal2.skyhanni.utils.ItemUtils.nameWithEnchantment
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
+import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber
+import at.hannibal2.skyhanni.utils.RenderUtils.renderString
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
+import at.hannibal2.skyhanni.utils.StringUtils.removeColor
+import at.hannibal2.skyhanni.utils.StringUtils.removeWordsAtEnd
+import io.github.moulberry.notenoughupdates.util.Constants
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import net.minecraftforge.fml.common.gameevent.TickEvent
+import kotlin.math.ceil
+
+class SlayerRngMeterDisplay {
+ private val config get() = SkyHanniMod.feature.slayer.rngMeterDisplay
+ private var display = ""
+ private val inventoryNamePattern = "(?<name>.*) RNG Meter".toPattern()
+ private val updatePattern = " §dRNG Meter §f- §d(?<exp>.*) Stored XP".toPattern()
+ private val changedItemPattern = "§aYou set your §r.* RNG Meter §r§ato drop §r.*§a!".toPattern()
+ private var lastItemDroppedTime = 0L
+
+ private var tick = 0
+
+ @SubscribeEvent
+ fun onTick(event: TickEvent.ClientTickEvent) {
+ if (event.phase != TickEvent.Phase.START) return
+
+ if (!isEnabled()) return
+ tick++
+
+ if (tick % 20 == 0) {
+ if (lastItemDroppedTime != 0L) {
+ if (System.currentTimeMillis() > lastItemDroppedTime + 4_000) {
+ lastItemDroppedTime = 0L
+ update()
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ fun onSlayerChange(event: SlayerChangeEvent) {
+ update()
+ }
+
+ @SubscribeEvent
+ fun onChat(event: LorenzChatEvent) {
+
+ if (!isEnabled()) return
+
+ if (config.hideChat) {
+ if (SlayerAPI.isInSlayerArea) {
+ changedItemPattern.matchMatcher(event.message) {
+ event.blockedReason = "slayer_rng_meter"
+ }
+ }
+ }
+
+ val currentMeter = updatePattern.matchMatcher(event.message) {
+ group("exp").formatNumber()
+ } ?: return
+
+ val storage = getStorage() ?: return
+ val old = storage.currentMeter
+ storage.currentMeter = currentMeter
+
+ if (old != -1L) {
+ val item = storage.itemGoal
+ val hasItemSelected = item != "" && item != "?"
+ if (!hasItemSelected) {
+ if (config.warnEmpty) {
+ LorenzUtils.warning("§c[Skyhanni] No Slayer RNG Meter Item selected!")
+ TitleUtils.sendTitle("§cNo RNG Meter Item!", 3_000)
+ }
+ }
+ var blockChat = config.hideChat && hasItemSelected
+ val diff = currentMeter - old
+ if (diff > 0) {
+ storage.gainPerBoss = diff
+ } else {
+ storage.itemGoal = ""
+ blockChat = false
+ val from = old.addSeparators()
+ val to = storage.goalNeeded.addSeparators()
+
+ var rawPercentage = old.toDouble() / storage.goalNeeded
+ if (rawPercentage > 1) rawPercentage = 1.0
+ val percentage = LorenzUtils.formatPercentage(rawPercentage)
+ LorenzUtils.chat("§e[SkyHanni] §dRNG Meter §7dropped at §e$percentage §7XP ($from/${to}§7)")
+ lastItemDroppedTime = System.currentTimeMillis()
+ }
+ if (blockChat) {
+ event.blockedReason = "slayer_rng_meter"
+ }
+ }
+ update()
+ }
+
+ private fun getStorage(): Storage.ProfileSpecific.SlayerRngMeterStorage? {
+ return ProfileStorageData.profileSpecific?.slayerRngMeter?.getOrPut(getCurrentSlayer()) {
+ Storage.ProfileSpecific.SlayerRngMeterStorage()
+ }
+ }
+
+ private fun getCurrentSlayer() = SlayerAPI.latestSlayerCategory.removeWordsAtEnd(1).removeColor()
+
+ @SubscribeEvent
+ fun onInventoryOpen(event: InventoryOpenEvent) {
+ if (!isEnabled()) return
+
+ val name = inventoryNamePattern.matchMatcher(event.inventoryName) {
+ group("name")
+ } ?: return
+
+ if (name != getCurrentSlayer()) return
+
+ val storage = getStorage() ?: return
+
+ val selectedItem = event.inventoryItems.values.find { item -> item.getLore().any { it.contains("§aSELECTED") } }
+ if (selectedItem == null) {
+ storage.itemGoal = ""
+ storage.goalNeeded = -1
+ } else {
+ storage.itemGoal = selectedItem.nameWithEnchantment
+ val jsonObject = Constants.RNGSCORE["slayer"].asJsonObject.get(getCurrentSlayer()).asJsonObject
+ storage.goalNeeded = jsonObject.get(selectedItem.getInternalName()).asLong
+ }
+ update()
+ }
+
+ private fun update() {
+ display = drawDisplay()
+ }
+
+ private fun drawDisplay(): String {
+ val storage = getStorage() ?: return ""
+
+ if (SlayerAPI.latestSlayerCategory.let {
+ it.endsWith(" I") || it.endsWith(" II")
+ }) {
+ return ""
+ }
+ val latestSlayerCategory = SlayerAPI.latestSlayerCategory
+ latestSlayerCategory.endsWith(" I")
+
+ with(storage) {
+ if (itemGoal == "?") return "§cOpen RNG Meter Inventory!"
+ if (itemGoal == "") {
+ return if (lastItemDroppedTime != 0L) {
+ "§a§lRNG Item dropped!"
+ } else {
+ "§eNo RNG Item selected!"
+ }
+ }
+ if (currentMeter == -1L || gainPerBoss == -1L) return "§cKill the slayer boss 2 times!"
+
+ val missing = goalNeeded - currentMeter + gainPerBoss
+ var timesMissing = missing.toDouble() / gainPerBoss
+ if (timesMissing < 1) timesMissing = 1.0
+ timesMissing = ceil(timesMissing)
+
+ return "$itemGoal §7in §e${timesMissing.toInt().addSeparators()} §7bosses!"
+ }
+ }
+
+ @SubscribeEvent
+ fun onRenderOverlay(event: GuiRenderEvent.GameOverlayRenderEvent) {
+ if (!isEnabled()) return
+ if (!SlayerAPI.isInSlayerArea) return
+ if (!SlayerAPI.hasActiveSlayerQuest()) return
+
+ config.pos.renderString(display, posLabel = "Rng Meter Display")
+ }
+
+ fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt
index 90dcddf9b..917ec5c88 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt
@@ -105,4 +105,6 @@ object StringUtils {
"$format$text"
}
}
+
+ fun String.removeWordsAtEnd(i: Int) = split(" ").dropLast(i).joinToString(" ")
} \ No newline at end of file