summaryrefslogtreecommitdiff
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.java7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/Garden.java57
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt45
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/ItemClickEvent.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarData.kt10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarDataGrabber.kt33
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatModifier.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt141
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/ComposterDisplay.kt80
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/CropMoneyDisplay.kt80
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/EliteFarmingWeight.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt15
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenBestCropTime.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneDisplay.kt113
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt41
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextPlotPrice.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenTeleportPadCompactName.kt32
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt48
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorTimer.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/SkyMartCopperPrice.kt (renamed from src/main/java/at/hannibal2/skyhanni/features/garden/SkyMartBestProfit.kt)66
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/inventory/HighlightBonzoMasks.kt57
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/itemabilities/abilitycooldown/ItemAbility.kt44
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/itemabilities/abilitycooldown/ItemAbilityCooldown.kt89
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/CrimsonIsleReputationHelper.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailykuudra/DailyKuudraBossHelper.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/DailyQuestHelper.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/DailyMiniBossHelper.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/LorenzTest.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt24
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/SoundUtils.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/TabListData.kt2
34 files changed, 831 insertions, 254 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java
index 782ae6d4a..073c4e514 100644
--- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java
+++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java
@@ -75,7 +75,7 @@ import java.util.List;
public class SkyHanniMod {
public static final String MODID = "skyhanni";
- public static final String VERSION = "0.17.Beta.24";
+ public static final String VERSION = "0.17.Beta.25";
public static final String DEPENDENCIES = "after:notenoughupdates@[2.1.1,);";
@@ -215,7 +215,7 @@ public class SkyHanniMod {
loadModule(new TpsCounter());
loadModule(new ParticleHider());
loadModule(new MiscFeatures());
- loadModule(new SkyMartBestProfit());
+ loadModule(new SkyMartCopperPrice());
loadModule(new GardenVisitorFeatures());
loadModule(new GardenInventoryNumbers());
loadModule(new GardenVisitorTimer());
@@ -235,6 +235,9 @@ public class SkyHanniMod {
loadModule(new FarmingArmorDrops());
loadModule(new JoinCrystalHollows());
loadModule(new GardenVisitorColorNames());
+ loadModule(new GardenTeleportPadCompactName());
+ loadModule(new AnitaMedalProfit());
+ loadModule(new ComposterDisplay());
Commands.INSTANCE.init();
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 2ef9f169b..638ec334f 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt
+++ b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt
@@ -5,6 +5,7 @@ import at.hannibal2.skyhanni.config.ConfigGuiManager
import at.hannibal2.skyhanni.config.commands.SimpleCommand.ProcessCommandRunnable
import at.hannibal2.skyhanni.data.ApiDataLoader
import at.hannibal2.skyhanni.data.GuiEditManager
+import at.hannibal2.skyhanni.features.bazaar.BazaarDataGrabber
import at.hannibal2.skyhanni.features.bingo.BingoCardDisplay
import at.hannibal2.skyhanni.features.bingo.BingoNextStepHelper
import at.hannibal2.skyhanni.features.event.diana.BurrowWarpHelper
@@ -51,6 +52,7 @@ object Commands {
registerCommand("shprintbingohelper") { BingoNextStepHelper.command() }
registerCommand("shsetapikey") { ApiDataLoader.command(it) }
registerCommand("shtestgardenvisitors") { LorenzTest.testGardenVisitors() }
+ registerCommand("shresetitemnames") { BazaarDataGrabber.resetItemNames() }
}
private fun registerCommand(name: String, function: (Array<String>) -> Unit) {
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 26734ef00..67f0decca 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java
@@ -33,7 +33,7 @@ public class Garden {
// @ConfigOption(name = "Copper Price Position", desc = "")
// @ConfigEditorButton(runnableId = "skyMartCopperPrice", buttonText = "Edit")
// @ConfigAccordionId(id = 0)
- public Position skyMartCopperPricePos = new Position(188, -105, false, true);
+ public Position skyMartCopperPricePos = new Position(211, 132, false, true);
@Expose
@ConfigOption(name = "Visitor", desc = "")
@@ -530,6 +530,13 @@ public class Garden {
@ConfigEditorBoolean
@ConfigAccordionId(id = 13)
public boolean moneyPerHourCompactPrice = false;
+ @Expose
+ @ConfigOption(
+ name = "Advanced stats",
+ desc = "Show not only Sell Offer price but also Instant Sell price and NPC Sell price.")
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 13)
+ public boolean moneyPerHourAdvancedStats = false;
@Expose
// @ConfigOption(name = "Money per hour Position", desc = "")
@@ -564,7 +571,7 @@ public class Garden {
// @ConfigOption(name = "Jacob Contest Position", desc = "")
// @ConfigEditorButton(runnableId = "nextJacobContest", buttonText = "Edit")
// @ConfigAccordionId(id = 14)
- public Position nextJacobContestPos = new Position(-113, -240, false, true);
+ public Position nextJacobContestPos = new Position(-278, 11, false, true);
@Expose
@ConfigOption(name = "Farming Armor Drops", desc = "")
@@ -587,6 +594,52 @@ public class Garden {
public Position farmingArmorDropsPos = new Position(16, -232, false, true);
@Expose
+ @ConfigOption(name = "Teleport Pads", desc = "")
+ @ConfigEditorAccordion(id = 12)
+ public boolean teleportPads = false;
+
+ @Expose
+ @ConfigOption(name = "Compact Name", desc = "Hide the 'Warp to' and 'No Destination' texts over teleport pads.")
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 12)
+ public boolean teleportPadsCompactName = false;
+
+ @Expose
+ @ConfigOption(name = "Anita Medal Profit", desc = "")
+ @ConfigEditorAccordion(id = 16)
+ public boolean anitaMedalProfit = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Show Prices",
+ desc = "Helps to identify profitable items to buy at the Anita item shop " +
+ "and potential profit from selling the item at the auction house."
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 16)
+ public boolean anitaMedalProfitEnabled = true;
+
+ @Expose
+ public Position anitaMedalProfitPos = new Position(206, 158, false, true);
+
+ @Expose
+ @ConfigOption(name = "Composter", desc = "")
+ @ConfigEditorAccordion(id = 16)
+ public boolean composter = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Compact Display",
+ desc = "Displays the compost data from the tab list in a compact form as gui element."
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 16)
+ public boolean composterDisplayEnabled = true;
+
+ @Expose
+ public Position composterDisplayPos = new Position(-363, 13, false, true);
+
+ @Expose
@ConfigOption(name = "Plot Price", desc = "Show the price of the plot in coins when inside the Configure Plots inventory.")
@ConfigEditorBoolean
public boolean plotPrice = true;
diff --git a/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt b/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt
index 0e2ed1fef..5294d79a1 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt
@@ -6,15 +6,12 @@ import at.hannibal2.skyhanni.events.InventoryOpenEvent
import at.hannibal2.skyhanni.events.ProfileJoinEvent
import at.hannibal2.skyhanni.features.garden.CropType
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
-import at.hannibal2.skyhanni.utils.ItemUtils.name
-import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded
-import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import java.util.regex.Pattern
class GardenCropMilestones {
- private val overflowPattern = Pattern.compile("(?:.*) §e(.*)§6\\/(?:.*)")
- private val nextTierPattern = Pattern.compile("§7Progress to Tier (.*): §e(?:.*)")
+ private val cropPattern = Pattern.compile("§7Harvest §f(.*) §7on .*")
+ private val totalPattern = Pattern.compile("§7Total: §a(.*)")
// Add when api support is there
// @SubscribeEvent
@@ -43,31 +40,17 @@ class GardenCropMilestones {
if (event.inventoryName != "Crop Milestones") return
for ((_, stack) in event.inventoryItems) {
- val cropName = stack.name?.removeColor() ?: continue
- val crop = CropType.getByName(cropName) ?: continue
-
- val lore = stack.getLore()
- var cropForTier = 0L
- var next = false
- for (line in lore) {
- if (line.contains("Progress to Tier")) {
- val matcher = nextTierPattern.matcher(line)
- if (matcher.matches()) {
- val nextTier = matcher.group(1).romanToDecimalIfNeeded()
- val currentTier = nextTier - 1
- cropForTier = getCropsForTier(currentTier)
- }
- next = true
- continue
+ var crop: CropType? = null
+ for (line in stack.getLore()) {
+ var matcher = cropPattern.matcher(line)
+ if (matcher.matches()) {
+ val name = matcher.group(1)
+ crop = CropType.getByName(name) ?: continue
}
- if (next) {
- val matcher = overflowPattern.matcher(line)
- if (matcher.matches()) {
- val rawNumber = matcher.group(1)
- val overflow = rawNumber.formatNumber()
- crop.setCounter(cropForTier + overflow)
- }
- next = false
+ matcher = totalPattern.matcher(line)
+ if (matcher.matches()) {
+ val amount = matcher.group(1).replace(",", "").toLong()
+ crop?.setCounter(amount)
}
}
}
@@ -80,7 +63,9 @@ class GardenCropMilestones {
fun CropType.getCounter() = cropCounter[this]!!
- fun CropType.setCounter(counter: Long) { cropCounter[this] = counter }
+ fun CropType.setCounter(counter: Long) {
+ cropCounter[this] = counter
+ }
fun getTierForCrops(crops: Long): Int {
var tier = 0
diff --git a/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt b/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt
index a2a22a865..fc68e1a52 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt
@@ -2,12 +2,14 @@ package at.hannibal2.skyhanni.data
import at.hannibal2.skyhanni.events.BlockClickEvent
import at.hannibal2.skyhanni.events.EntityClickEvent
+import at.hannibal2.skyhanni.events.ItemClickEvent
import at.hannibal2.skyhanni.events.PacketEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.toLorenzVec
import net.minecraft.client.Minecraft
import net.minecraft.network.play.client.C07PacketPlayerDigging
import net.minecraft.network.play.client.C08PacketPlayerBlockPlacement
+import net.minecraft.network.play.client.C0APacketAnimation
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import net.minecraftforge.fml.common.gameevent.InputEvent
import org.lwjgl.input.Mouse
@@ -21,11 +23,14 @@ class ItemClickData {
val position = packet.position.toLorenzVec()
BlockClickEvent(ClickType.RIGHT_CLICK, position, packet.stack).postAndCatch()
}
+ val itemInHand = Minecraft.getMinecraft().thePlayer.heldItem
if (packet is C07PacketPlayerDigging && packet.status == C07PacketPlayerDigging.Action.START_DESTROY_BLOCK) {
val position = packet.position.toLorenzVec()
- val itemInHand = Minecraft.getMinecraft().thePlayer.heldItem
BlockClickEvent(ClickType.LEFT_CLICK, position, itemInHand).postAndCatch()
}
+ if (packet is C0APacketAnimation) {
+ ItemClickEvent(itemInHand).postAndCatch()
+ }
}
@SubscribeEvent
diff --git a/src/main/java/at/hannibal2/skyhanni/events/ItemClickEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/ItemClickEvent.kt
new file mode 100644
index 000000000..7b12f60cb
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/events/ItemClickEvent.kt
@@ -0,0 +1,8 @@
+package at.hannibal2.skyhanni.events
+
+import at.hannibal2.skyhanni.data.ClickType
+import at.hannibal2.skyhanni.utils.BlockUtils.getBlockStateAt
+import at.hannibal2.skyhanni.utils.LorenzVec
+import net.minecraft.item.ItemStack
+
+class ItemClickEvent(val itemInHand: ItemStack?) : LorenzEvent() \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarData.kt b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarData.kt
index b4f00f248..eb76ac18f 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarData.kt
@@ -1,3 +1,11 @@
package at.hannibal2.skyhanni.features.bazaar
-data class BazaarData(val apiName: String, val itemName: String, val sellPrice: Double, val buyPrice: Double, val buyMovingWeek: Int, val sellMovingWeek: Int) \ No newline at end of file
+data class BazaarData(
+ val apiName: String,
+ val itemName: String,
+ val sellPrice: Double,
+ val buyPrice: Double,
+ val npcPrice: Double,
+ val buyMovingWeek: Int,
+ val sellMovingWeek: Int,
+) \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarDataGrabber.kt b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarDataGrabber.kt
index 609801cd5..0bcaded93 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarDataGrabber.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarDataGrabber.kt
@@ -14,9 +14,15 @@ internal class BazaarDataGrabber(private var bazaarMap: MutableMap<String, Bazaa
companion object {
private val itemNames = mutableMapOf<String, String>()
+ private val npcPrices = mutableMapOf<String, Double>()
var lastTime = 0L
var currentlyUpdating = false
+
+ fun resetItemNames() {
+ LorenzUtils.chat("§e[SkyHanni] Reloading the hypixel item api..")
+ itemNames.clear()
+ }
}
private fun loadItemNames(): Boolean {
@@ -28,6 +34,17 @@ internal class BazaarDataGrabber(private var bazaarMap: MutableMap<String, Bazaa
val name = jsonObject["name"].asString
val id = jsonObject["id"].asString
itemNames[id] = name.removeColor()
+// if (id.lowercase().contains("redstone")) {
+ if (jsonObject.has("npc_sell_price")) {
+// println(" ")
+// println("name: $name")
+// println("id: $id")
+ val npcPrice = jsonObject["npc_sell_price"].asDouble
+// println("npcPrice: $npcPrice")
+ npcPrices[id] = npcPrice
+ }
+// println("jsonObject: $jsonObject")
+// }
}
currentlyUpdating = false
return true
@@ -94,7 +111,8 @@ internal class BazaarDataGrabber(private var bazaarMap: MutableMap<String, Bazaa
val itemName = getItemName(apiName)
if (itemName == null) {
- LorenzUtils.warning("§c[SkyHanni] bazaar item '$apiName' not found! Try restarting your minecraft to fix this.")
+ LorenzUtils.warning("§c[SkyHanni] bazaar item '$apiName' not found!")
+ resetItemNames()
continue
}
@@ -109,7 +127,18 @@ internal class BazaarDataGrabber(private var bazaarMap: MutableMap<String, Bazaa
apiName = text
}
- val data = BazaarData(apiName, itemName, sellPrice, buyPrice, buyMovingWeek, sellMovingWeek)
+ val npcPrice = npcPrices[apiName] ?: -1.0
+// if (npcPrice == -1.0) {
+// if (apiName.lowercase().contains("carrot")) {
+// println(" ")
+// println("BazaarData")
+// println("itemName: '$itemName'")
+// println("apiName: '$apiName'")
+// println("npc price: $npcPrice")
+// }
+// }
+
+ val data = BazaarData(apiName, itemName, sellPrice, buyPrice, npcPrice, buyMovingWeek, sellMovingWeek)
bazaarMap[itemName] = data
}
BazaarUpdateEvent(bazaarMap).postAndCatch()
diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatModifier.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatModifier.kt
index ba144e9db..15eff6a85 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatModifier.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/chat/playerchat/PlayerChatModifier.kt
@@ -14,8 +14,8 @@ class PlayerChatModifier {
init {
patterns.add("§(?:a|b|6)\\[(?:VIP|MVP)(?:(?:§.|\\+)*)](?: {1,2})(?:§[7ab6])?(\\w{2,16})".toRegex()) // ranked player everywhere
- patterns.add("§(?:7|a|b|6)((?:\\w+){2,16})§r(?!§7x)".toRegex()) // nons in notification message
- patterns.add("(?:§7 )?§7((?:\\w+){2,16})§7§r".toRegex()) // nons user chat
+ patterns.add("§(?:7|a|b|6)((?:\\w){2,16})§r(?!§7x)".toRegex()) // nons in notification message
+ patterns.add("(?:§7 )?§7((?:\\w){2,16})§7§r".toRegex()) // nons user chat
}
@SubscribeEvent
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt
new file mode 100644
index 000000000..fa6500bcb
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt
@@ -0,0 +1,141 @@
+package at.hannibal2.skyhanni.features.garden
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.events.GuiRenderEvent
+import at.hannibal2.skyhanni.events.InventoryCloseEvent
+import at.hannibal2.skyhanni.events.InventoryOpenEvent
+import at.hannibal2.skyhanni.utils.ItemUtils
+import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
+import at.hannibal2.skyhanni.utils.ItemUtils.getLore
+import at.hannibal2.skyhanni.utils.ItemUtils.name
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
+import at.hannibal2.skyhanni.utils.NEUItems
+import at.hannibal2.skyhanni.utils.NumberUtil
+import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
+import net.minecraft.item.ItemStack
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+class AnitaMedalProfit {
+ private val config get() = SkyHanniMod.feature.garden
+ private var display = listOf<List<Any>>()
+
+ companion object {
+ var inInventory = false
+ }
+
+ enum class MedalType(val displayName: String, val factorBronze: Int) {
+ GOLD("§6Gold medal", 8),
+ SILVER("§fSilver medal", 2),
+ BRONZE("§cBronze medal", 1),
+ ;
+ }
+
+ private fun getMedal(name: String) = MedalType.values().firstOrNull { it.displayName == name }
+
+ @SubscribeEvent
+ fun onInventoryClose(event: InventoryCloseEvent) {
+ inInventory = false
+ }
+
+ @SubscribeEvent
+ fun onInventoryOpen(event: InventoryOpenEvent) {
+ if (!config.anitaMedalProfitEnabled) return
+ if (event.inventoryName != "Anita") return
+
+ inInventory = true
+
+ val table = mutableMapOf<Pair<String, String>, Pair<Double, String>>()
+ for ((_, item) in event.inventoryItems) {
+ readItem(item, table)
+ }
+
+ val newList = mutableListOf<List<Any>>()
+ newList.addAsSingletonList("§eMedal Profit")
+ LorenzUtils.fillTable(newList, table)
+ display = newList
+ }
+
+ private fun readItem(item: ItemStack, table: MutableMap<Pair<String, String>, Pair<Double, String>>) {
+ var itemName = item.name ?: return
+ if (itemName == " ") return
+ if (itemName.endsWith("Enchanted Book")) {
+ itemName = item.getLore()[0]
+ }
+
+ val fullCost = getFullCost(getRequiredItems(item))
+ if (fullCost < 0) return
+
+ val (name, amount) = ItemUtils.readItemAmount(itemName)
+ if (name == null) return
+
+ val internalName = try {
+ NEUItems.getInternalName(name)
+ } catch (e: Exception) {
+ // TODO make a better alternative
+ item.getInternalName()
+ }
+
+ val itemPrice = NEUItems.getPrice(internalName) * amount
+ if (itemPrice < 0) return
+
+ val profit = itemPrice - fullCost
+ val format = NumberUtil.format(profit)
+ val color = if (profit > 0) "§6" else "§c"
+ table[Pair(itemName, "$color$format")] = Pair(profit, internalName)
+ }
+
+ private fun getFullCost(requiredItems: MutableList<String>): Double {
+ val jacobTicketPrice = NEUItems.getPrice("JACOBS_TICKET")
+ var otherItemsPrice = 0.0
+ for (rawItemName in requiredItems) {
+ val (name, amount) = ItemUtils.readItemAmount(rawItemName)
+ if (name == null) {
+ LorenzUtils.error("§c[SkyHanni] Could not read item '$rawItemName'")
+ continue
+ }
+
+ val medal = getMedal(name)
+ otherItemsPrice += if (medal != null) {
+ val bronze = medal.factorBronze * amount
+ bronze * jacobTicketPrice
+ } else {
+ val internalName = NEUItems.getInternalName(name)
+ NEUItems.getPrice(internalName) * amount
+ }
+ }
+ return otherItemsPrice
+ }
+
+ private fun getRequiredItems(item: ItemStack): MutableList<String> {
+ val items = mutableListOf<String>()
+ var next = false
+ for (line in item.getLore()) {
+ if (line == "§7Cost") {
+ next = true
+ continue
+ }
+ if (next) {
+ if (line == "") {
+ next = false
+ continue
+ }
+
+ items.add(line.replace("§8 ", " §8"))
+ }
+ }
+ return items
+ }
+
+ @SubscribeEvent
+ fun onBackgroundDraw(event: GuiRenderEvent.ChestBackgroundRenderEvent) {
+ if (inInventory) {
+ config.anitaMedalProfitPos.renderStringsAndItems(
+ display,
+ extraSpace = 5,
+ itemScale = 1.7,
+ posLabel = "Anita Medal Profit"
+ )
+ }
+ }
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/ComposterDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/ComposterDisplay.kt
new file mode 100644
index 000000000..57cf15aa9
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/ComposterDisplay.kt
@@ -0,0 +1,80 @@
+package at.hannibal2.skyhanni.features.garden
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.events.GuiRenderEvent
+import at.hannibal2.skyhanni.events.TabListUpdateEvent
+import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
+import at.hannibal2.skyhanni.utils.NEUItems
+import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import java.util.regex.Pattern
+
+class ComposterDisplay {
+ private val config get() = SkyHanniMod.feature.garden
+ private var display = listOf<List<Any>>()
+
+ enum class DataType(val pattern: String, val icon: String) {
+ ORGANIC_MATTER(" Organic Matter: §r(.*)", "WHEAT"),
+ FUEL(" Fuel: §r(.*)", "OIL_BARREL"),
+ TIME_LEFT(" Time Left: §r(.*)", "WATCH"),
+ STORED_COMPOST(" Stored Compost: §r(.*)", "COMPOST"),
+ ;
+
+ val displayItem by lazy {
+ NEUItems.getItemStack(icon)
+ }
+
+ fun addToList(map: Map<DataType, String>): List<Any> {
+ return listOf(displayItem, map[this]!!)
+ }
+ }
+
+ @SubscribeEvent
+ fun onTabListUpdate(event: TabListUpdateEvent) {
+ if (!isEnabled()) return
+
+ var next = false
+ val data = mutableMapOf<DataType, String>()
+
+ for (line in event.tabList) {
+ if (line == "§b§lComposter:") {
+ next = true
+ continue
+ }
+ if (next) {
+ if (line == "") break
+ for (type in DataType.values()) {
+ val pattern = Pattern.compile(type.pattern)
+ val matcher = pattern.matcher(line)
+ if (matcher.matches()) {
+ data[type] = matcher.group(1)
+ }
+ }
+ }
+ }
+
+ val newList = mutableListOf<List<Any>>()
+ newList.addAsSingletonList("§bComposter")
+
+ newList.add(DataType.TIME_LEFT.addToList(data))
+
+ val list = mutableListOf<Any>()
+ list.addAll(DataType.ORGANIC_MATTER.addToList(data))
+ list.add(" ")