aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCalMWolfs <94038482+CalMWolfs@users.noreply.github.com>2023-05-12 23:39:34 +1000
committerGitHub <noreply@github.com>2023-05-12 15:39:34 +0200
commit07064c0b8dcce1a9ca48077f9f7b87c21e1466be (patch)
tree6a9ac4b084c3fcec904b52fc219bab4c68b2593c
parent233b5d9b79afce09b830df22b89bc99180b5b991 (diff)
downloadskyhanni-07064c0b8dcce1a9ca48077f9f7b87c21e1466be.tar.gz
skyhanni-07064c0b8dcce1a9ca48077f9f7b87c21e1466be.tar.bz2
skyhanni-07064c0b8dcce1a9ca48077f9f7b87c21e1466be.zip
Visitor drop counter (#103)
-rw-r--r--src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/Garden.java67
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/Hidden.java28
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorDropStatistics.kt177
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorFeatures.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorTimer.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorReward.kt13
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt8
9 files changed, 305 insertions, 5 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt
index 6a0deeb26..e43cf16ec 100644
--- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt
+++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt
@@ -32,6 +32,7 @@ import at.hannibal2.skyhanni.features.garden.contest.JacobFarmingContestsInvento
import at.hannibal2.skyhanni.features.garden.farming.*
import at.hannibal2.skyhanni.features.garden.inventory.*
import at.hannibal2.skyhanni.features.garden.visitor.GardenVisitorColorNames
+import at.hannibal2.skyhanni.features.garden.visitor.GardenVisitorDropStatistics
import at.hannibal2.skyhanni.features.garden.visitor.GardenVisitorFeatures
import at.hannibal2.skyhanni.features.garden.visitor.GardenVisitorTimer
import at.hannibal2.skyhanni.features.inventory.*
@@ -268,6 +269,7 @@ class SkyHanniMod {
loadModule(TrevorFeatures())
loadModule(TrevorSolver)
loadModule(BingoCardTips())
+ loadModule(GardenVisitorDropStatistics)
init()
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java b/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java
index 304ba66d9..2746cc991 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java
@@ -174,6 +174,71 @@ public class Garden {
@ConfigAccordionId(id = 1)
public boolean visitorHideChat = true;
+
+ @Expose
+ @ConfigOption(name = "Visitor Drops Statistics", desc = "")
+ @Accordion
+ public VisitorDrops visitorDropsStatistics = new VisitorDrops();
+
+ public static class VisitorDrops {
+
+ @Expose
+ @ConfigOption(
+ name = "Enabled",
+ desc = "Tallies up statistic about visitors and the rewards you have received from them.\n" +
+ "§eThis feature is in beta please report issues on the discord!"
+ )
+ @ConfigEditorBoolean
+ public boolean enabled = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Text Format",
+ desc = "Drag text to change the appearance of the overlay."
+ )
+ @ConfigEditorDraggableList(
+ exampleText = {
+ "§e§lVisitor Statistics",
+ "§e1,636 Total",
+ "§a1,172§f-§9382§f-§681§f-§c1",
+ "§21,382 Accepted",
+ "§c254 Denied",
+ " ",
+ "§c62,072 Copper",
+ "§23.2m Farming EXP",
+ "§647.2m Coins Spent",
+ "§b23 §9Flowering Bouquet",
+ "§b4 §9Overgrown Grass",
+ "§b2 §9Green Bandana",
+ "§b1 §9Dedication IV",
+ "§b6 §9Music Rune",
+ "§b1 §cSpace Helmet",
+ " ", // If they want another empty row
+ }
+ )
+ public List<Integer> textFormat = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12));
+
+ @Expose
+ @ConfigOption(name = "Display Numbers First", desc = "Determines whether the number or drop name displays first. " +
+ "§eNote: Will not update the preview above!")
+ @ConfigEditorBoolean
+ public boolean displayNumbersFirst = true;
+
+ @Expose
+ @ConfigOption(name = "Display Icons", desc = "Replaces the drop names with icons. " +
+ "§eNote: Will not update the preview above!")
+ @ConfigEditorBoolean
+ public boolean displayIcons = false;
+
+ @Expose
+ @ConfigOption(name = "Only On Barn Plot", desc = "Only shows the overlay while on the barn plot.")
+ @ConfigEditorBoolean
+ public boolean onlyOnBarn = true;
+
+ @Expose
+ public Position visitorDropPos = new Position(10, 80, false, true);
+ }
+
@Expose
@ConfigOption(name = "Numbers", desc = "")
@ConfigEditorAccordion(id = 5)
@@ -1013,7 +1078,7 @@ public class Garden {
)
@ConfigEditorBoolean
@ConfigAccordionId(id = 22)
- public boolean farmingFortuneDropMultiplier = false;
+ public boolean farmingFortuneDropMultiplier = true;
@Expose
public Position farmingFortunePos = new Position(-375, -200, false, true);
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Hidden.java b/src/main/java/at/hannibal2/skyhanni/config/features/Hidden.java
index a310ab367..bb5349168 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/Hidden.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/Hidden.java
@@ -3,6 +3,7 @@ package at.hannibal2.skyhanni.config.features;
import at.hannibal2.skyhanni.data.model.ComposterUpgrade;
import at.hannibal2.skyhanni.features.garden.CropAccessory;
import at.hannibal2.skyhanni.features.garden.CropType;
+import at.hannibal2.skyhanni.features.garden.visitor.VisitorReward;
import com.google.gson.annotations.Expose;
import java.util.ArrayList;
@@ -89,4 +90,31 @@ public class Hidden {
@Expose
public String gardenComposterCurrentFuelItem = "";
+
+
+ @Expose
+ public VisitorDrops visitorDrops = new VisitorDrops();
+
+ public static class VisitorDrops {
+ @Expose
+ public int acceptedVisitors = 0;
+
+ @Expose
+ public int deniedVisitors = 0;
+
+ @Expose
+ public List<Long> visitorRarities = new ArrayList<>();
+
+ @Expose
+ public int copper = 0;
+
+ @Expose
+ public long farmingExp = 0;
+
+ @Expose
+ public long coinsSpent = 0;
+
+ @Expose
+ public Map<VisitorReward, Integer> rewardsCount = new HashMap<>();
+ }
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt
index 4c19346b0..2eb6e4fee 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt
@@ -34,7 +34,8 @@ object GardenAPI {
var itemInHand: ItemStack? = null
var cropInHand: CropType? = null
var mushroomCowPet = false
- var onBarnPlot = false
+ var inBarn = false
+ val onBarnPlot get() = inBarn && inGarden()
var tick = 0
@@ -57,7 +58,7 @@ object GardenAPI {
if (!inGarden()) return
tick++
if (tick % 10 == 0) {
- onBarnPlot = ScoreboardData.sidebarLinesFormatted.contains(" §7⏣ §aThe Garden")
+ inBarn = ScoreboardData.sidebarLinesFormatted.contains(" §7⏣ §aThe Garden")
// We ignore random hypixel moments
Minecraft.getMinecraft().currentScreen ?: return
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorDropStatistics.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorDropStatistics.kt
new file mode 100644
index 000000000..9e8621beb
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorDropStatistics.kt
@@ -0,0 +1,177 @@
+package at.hannibal2.skyhanni.features.garden.visitor
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.events.GuiRenderEvent
+import at.hannibal2.skyhanni.events.LorenzChatEvent
+import at.hannibal2.skyhanni.features.garden.GardenAPI
+import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
+import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy
+import at.hannibal2.skyhanni.utils.NEUItems
+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.RenderUtils.renderStringsAndItems
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
+import at.hannibal2.skyhanni.utils.StringUtils.removeColor
+import net.minecraftforge.event.world.WorldEvent
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+object GardenVisitorDropStatistics {
+ private val config get() = SkyHanniMod.feature.garden.visitorDropsStatistics
+ private val hidden get() = SkyHanniMod.feature.hidden.visitorDrops
+ private var display = listOf<List<Any>>()
+
+ private var acceptedVisitors = 0
+ var deniedVisitors = 0
+ private var totalVisitors = 0
+ private var visitorRarities = mutableListOf<Long>()
+ private var copper = 0
+ private var farmingExp = 0L
+ var coinsSpent = 0L
+
+ private val acceptPattern = "OFFER ACCEPTED with (?<visitor>.*) [(](?<rarity>.*)[)]".toPattern()
+ private val copperPattern = "[+](?<amount>.*) Copper".toPattern()
+ private val farmingExpPattern = "[+](?<amount>.*) Farming XP".toPattern()
+ private var rewardsCount = mapOf<VisitorReward, Int>()
+
+ private fun formatDisplay(map: List<List<Any>>): MutableList<List<Any>> {
+ val newList = mutableListOf<List<Any>>()
+ for (index in config.textFormat) {
+ newList.add(map[index])
+ }
+ return newList
+ }
+
+ @SubscribeEvent
+ fun onChat(event: LorenzChatEvent) {
+ if (!GardenAPI.onBarnPlot) return
+ val message = event.message.removeColor().trim()
+
+ copperPattern.matchMatcher(message) {
+ val amount = group("amount").formatNumber().toInt()
+ copper += amount
+ saveAndUpdate()
+ }
+ farmingExpPattern.matchMatcher(message) {
+ val amount = group("amount").formatNumber()
+ farmingExp += amount
+ saveAndUpdate()
+ }
+ acceptPattern.matchMatcher(message) {
+ setRarities(group("rarity"))
+ saveAndUpdate()
+ }
+
+ for (reward in VisitorReward.values()) {
+ reward.pattern.matchMatcher(message) {
+ val old = rewardsCount[reward] ?: 0
+ rewardsCount = rewardsCount.editCopy { this[reward] = old + 1 }
+ saveAndUpdate()
+ }
+ }
+ }
+
+ private fun setRarities(rarity: String) {
+ acceptedVisitors += 1
+ val currentRarity = VisitorRarity.valueOf(rarity)
+ val temp = visitorRarities[currentRarity.ordinal] + 1
+ visitorRarities[currentRarity.ordinal] = temp
+ saveAndUpdate()
+ }
+
+ private fun drawVisitorStatsDisplay() = buildList<List<Any>> {
+ //0
+ addAsSingletonList("§e§lVisitor Statistics")
+ //1
+ addAsSingletonList(format(totalVisitors, "Total", "§e", ""))
+ //2
+ addAsSingletonList(
+ "§a${visitorRarities[0].addSeparators()}§f-" +
+ "§9${visitorRarities[1].addSeparators()}§f-" +
+ "§6${visitorRarities[2].addSeparators()}§f-" +
+ "§c${visitorRarities[3].addSeparators()}"
+ )
+ //3
+ addAsSingletonList(format(acceptedVisitors, "Accepted", "§2", ""))
+ //4
+ addAsSingletonList(format(deniedVisitors, "Denied", "§c", ""))
+ //5
+ addAsSingletonList("")
+ //6
+ addAsSingletonList(format(copper, "Copper", "§c", ""))
+ //7
+ addAsSingletonList(format(farmingExp, "Farming EXP", "§3", "§7"))
+ //8
+ addAsSingletonList(format(coinsSpent, "Coins Spent", "§6", ""))
+
+ //9 - 14
+ for (reward in VisitorReward.values()) {
+ val count = rewardsCount[reward] ?: 0
+ if (config.displayIcons) {// Icons
+ val stack = NEUItems.getItemStack(reward.internalName)
+ if (config.displayNumbersFirst)
+ add(listOf("§b${count.addSeparators()} ", stack))
+ else add(listOf(stack, " §b${count.addSeparators()}"))
+ } else { // No Icons
+ addAsSingletonList(format(count, reward.displayName, "§b"))
+ }
+ }
+ }
+
+ fun format(amount: Number, name: String, color: String, amountColor: String = color) =
+ if (config.displayNumbersFirst)
+ "$color${format(amount)} $name"
+ else
+ "$color$name: $amountColor${format(amount)}"
+
+ fun format(amount: Number): String {
+ if (amount is Int) return amount.addSeparators()
+ if (amount is Long) return NumberUtil.format(amount)
+ return "$amount"
+ }
+
+ fun saveAndUpdate() {
+ if (!GardenAPI.inGarden()) return
+ hidden.acceptedVisitors = acceptedVisitors
+ hidden.deniedVisitors = deniedVisitors
+ totalVisitors = acceptedVisitors + deniedVisitors
+ hidden.visitorRarities = visitorRarities
+ hidden.copper = copper
+ hidden.farmingExp = farmingExp
+ hidden.coinsSpent = coinsSpent
+ hidden.rewardsCount = rewardsCount
+ display = formatDisplay(drawVisitorStatsDisplay())
+ }
+
+ @SubscribeEvent
+ fun onWorldLoad(event: WorldEvent.Load) {
+ if (hidden.visitorRarities.size == 0) {
+ hidden.visitorRarities.add(0)
+ hidden.visitorRarities.add(0)
+ hidden.visitorRarities.add(0)
+ hidden.visitorRarities.add(0)
+ }
+ acceptedVisitors = hidden.acceptedVisitors
+ deniedVisitors = hidden.deniedVisitors
+ totalVisitors = acceptedVisitors + deniedVisitors
+ visitorRarities = hidden.visitorRarities
+ copper = hidden.copper
+ farmingExp = hidden.farmingExp
+ coinsSpent = hidden.coinsSpent
+ rewardsCount = hidden.rewardsCount
+ saveAndUpdate()
+ }
+
+ @SubscribeEvent
+ fun onRenderOverlay(event: GuiRenderEvent.GameOverlayRenderEvent) {
+ if (!config.enabled) return
+ if (!GardenAPI.inGarden()) return
+ if (GardenAPI.hideExtraGuis()) return
+ if (config.onlyOnBarn && !GardenAPI.onBarnPlot) return
+ config.visitorDropPos.renderStringsAndItems(display, posLabel = "Visitor Stats")
+ }
+}
+
+enum class VisitorRarity {
+ UNCOMMON, RARE, LEGENDARY, SPECIAL,
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorFeatures.kt
index 057b5f670..14d0920c4 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorFeatures.kt
@@ -35,6 +35,7 @@ import net.minecraftforge.event.entity.player.ItemTooltipEvent
import net.minecraftforge.fml.common.eventhandler.EventPriority
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import net.minecraftforge.fml.common.gameevent.TickEvent
+import kotlin.math.round
class GardenVisitorFeatures {
private val visitors = mutableMapOf<String, Visitor>()
@@ -47,6 +48,7 @@ class GardenVisitorFeatures {
private val visitorChatMessagePattern = "§e\\[NPC] (§.)?(?<name>.*)§f: §r.*".toPattern()
private val config get() = SkyHanniMod.feature.garden
private val logger = LorenzLogger("garden/visitors")
+ private var price = 0.0
companion object {
var inVisitorInventory = false
@@ -221,12 +223,15 @@ class GardenVisitorFeatures {
if (event.slot.stack?.name != "§cRefuse Offer") return
changeStatus(visitor, VisitorStatus.REFUSED, "refused")
update()
+ GardenVisitorDropStatistics.deniedVisitors += 1
+ GardenVisitorDropStatistics.saveAndUpdate()
return
}
if (event.slotId == 29) {
if (event.slot.stack?.getLore()?.any { it == "§eClick to give!" } == true) {
changeStatus(visitor, VisitorStatus.ACCEPTED, "accepted")
update()
+ GardenVisitorDropStatistics.coinsSpent += round(price).toLong()
return
}
}
@@ -303,7 +308,7 @@ class GardenVisitorFeatures {
LorenzUtils.error(message)
return
}
- val price = NEUItems.getPrice(internalName) * amount
+ price = NEUItems.getPrice(internalName) * amount
totalPrice += price
if (config.visitorShowPrice) {
val format = NumberUtil.format(price)
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorTimer.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorTimer.kt
index 6c43f92f1..e7b55bf14 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorTimer.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorTimer.kt
@@ -48,6 +48,9 @@ class GardenVisitorTimer {
CopyErrorCommand.errorStackTrace = error.stackTrace.asList()
LorenzUtils.chat("§c[SkyHanni] encountered an error when updating visitor display, please run /shcopyerror")
}
+ try {
+ GardenVisitorDropStatistics.saveAndUpdate()
+ } catch (_: Throwable) {} // no config yet
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorReward.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorReward.kt
new file mode 100644
index 000000000..7651a1d3e
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/visitor/VisitorReward.kt
@@ -0,0 +1,13 @@
+package at.hannibal2.skyhanni.features.garden.visitor
+
+import java.util.regex.Pattern
+
+enum class VisitorReward(val displayName: String, val internalName: String, val pattern: Pattern) {
+ GREEN_BANDANA("§9Green Bandana", "GREEN_BANDANA", "[+]1x Green Bandana".toPattern()),
+ OVERGROWN_GRASS("§9Overgrown Grass", "OVERGROWN_GRASS", "[+]1x Overgrown Grass".toPattern()),
+ FLOWERING_BOUQUET("§9Flowering Bouquet", "FLOWERING_BOUQUET", "[+]1x Flowering Bouquet".toPattern()),
+ DEDICATION("§9Dedication IV", "DEDICATION;4", "Dedication (IV|4) Book".toPattern()),
+ SPACE_HELMET("§cSpace Helmet", "DCTR_SPACE_HELM", "[+]Space Helmet".toPattern()),
+ // Pretty sure that the symbol is ◆ but not 100%
+ MUSIC_RUNE("§9Music Rune", "MUSIC_RUNE;1", "[+]1x ◆ Music Rune [1I]".toPattern()),
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt b/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt
index b776cb1dc..cae0a5896 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt
@@ -178,7 +178,12 @@ object NumberUtil {
}
fun String.formatNumber(): Long {
+ var hasDecimal = false
var text = replace(",", "")
+ if (text.contains(".")) {
+ text = replace(".", "")
+ hasDecimal = true
+ }
val multiplier = if (text.endsWith("k")) {
text = text.substring(0, text.length - 1)
1_000
@@ -186,7 +191,8 @@ object NumberUtil {
text = text.substring(0, text.length - 1)
1_000_000
} else 1
- val d = text.toDouble()
+ var d = text.toDouble()
+ if (hasDecimal) d /= 10
return (d * multiplier).toLong()
}
} \ No newline at end of file