aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md3
-rw-r--r--FEATURES.md3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/Garden.java19
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/Hidden.java6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/model/ComposterUpgrade.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarDataHolder.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterAPI.kt29
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterDisplay.kt14
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterOverlay.kt438
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropMoneyDisplay.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropMilestoneDisplay.kt1
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/visitor/GardenVisitorFeatures.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/inventory/JacobFarmingContestsInventory.kt1
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt2
16 files changed, 519 insertions, 25 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 545c0a0cf..01dc0c675 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -68,6 +68,9 @@
+ Added **Compost Low Notification** - Shows a notification as title when organic matter/fuel is low.
+ Added **Jacob's Contest Warning** - Show a warning shortly before a new jacob contest starts.
+ Added **Inventory Numbers** - Show the number of the teleport pads inside the 'Change Destination' inventory as stack size.
++ Added **Composter Overlay** - Show the cheapest items for organic matter and fuel, show profit per compost/hour/day and time per compost
++ Added **Composter Upgrades Overlay** - Show an overview of all composter stats, including time till organic matter and fuel is empty when fully filled and show a preview how these stats change when hovering over an upgrade
++ Hide crop money display, crop milestone display and garden visitor list while inside anita show, SkyMart or the composter inventory
### Features from other Mods
> *The following features are only there because I want them when testing SkyHanni features without other mods present.*
diff --git a/FEATURES.md b/FEATURES.md
index fd032788e..30392f0f8 100644
--- a/FEATURES.md
+++ b/FEATURES.md
@@ -213,6 +213,9 @@
+ **Compost Low Notification** - Shows a notification as title when organic matter/fuel is low.
+ **Jacob's Contest Warning** - Show a warning shortly before a new jacob contest starts.
+ **Inventory Numbers** - Show the number of the teleport pads inside the 'Change Destination' inventory as stack size.
++ **Composter Overlay** - Show the cheapest items for organic matter and fuel, show profit per compost/hour/day and time per compost
++ **Composter Upgrades Overlay** - Show an overview of all composter stats, including time till organic matter and fuel is empty when fully filled and show a preview how these stats change when hovering over an upgrade
++ Hide crop money display, crop milestone display and garden visitor list while inside anita show, SkyMart or the composter inventory
## Commands
+ **/wiki <search term>** - using hypixel-skyblock.fandom.com instead of Hypixel wiki.
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java
index b645d6e69..734e4921a 100644
--- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java
+++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java
@@ -30,6 +30,7 @@ import at.hannibal2.skyhanni.features.fishing.*;
import at.hannibal2.skyhanni.features.garden.*;
import at.hannibal2.skyhanni.features.garden.composter.ComposterDisplay;
import at.hannibal2.skyhanni.features.garden.composter.ComposterInventoryNumbers;
+import at.hannibal2.skyhanni.features.garden.composter.ComposterOverlay;
import at.hannibal2.skyhanni.features.garden.composter.GardenComposterInventoryFeatures;
import at.hannibal2.skyhanni.features.garden.farming.*;
import at.hannibal2.skyhanni.features.garden.inventory.*;
@@ -269,6 +270,7 @@ public class SkyHanniMod {
loadModule(new CropSpeedMeter());
loadModule(new AshfangMinisNametagHider());
loadModule(new GardenTeleportPadInventoryNumber());
+ loadModule(new ComposterOverlay());
Commands.INSTANCE.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 79657ae5b..1f5b2a90b 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java
@@ -756,8 +756,23 @@ public class Garden {
@Expose
@ConfigOption(
- name = "Compact Display",
- desc = "Displays the compost data from the tab list in a compact form as gui element."
+ name = "Composter Overlay",
+ desc = "Show organic matter, fuel, and profit prices while inside the Composter Inventory."
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 17)
+ public boolean composterOverlay = true;
+
+ @Expose
+ public Position composterOverlayOrganicMatterPos = new Position(140, 152, false, true);
+
+ @Expose
+ public Position composterOverlayFuelExtrasPos = new Position(-320, 152, false, true);
+
+ @Expose
+ @ConfigOption(
+ name = "Display Element",
+ desc = "Displays the compost data from the tab list as gui element."
)
@ConfigEditorBoolean
@ConfigAccordionId(id = 17)
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 209ac61f3..f212b50a1 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/Hidden.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/Hidden.java
@@ -71,4 +71,10 @@ public class Hidden {
@Expose
public Map<CropType, Boolean> gardenToolHasBountiful = new HashMap<>();
+
+ @Expose
+ public String gardenComposterCurrentOrganicMatterItem = "";
+
+ @Expose
+ public String gardenComposterCurrentFuelItem = "";
}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/model/ComposterUpgrade.kt b/src/main/java/at/hannibal2/skyhanni/data/model/ComposterUpgrade.kt
index 83a106ca8..cc0a82a2d 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/model/ComposterUpgrade.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/model/ComposterUpgrade.kt
@@ -1,11 +1,11 @@
package at.hannibal2.skyhanni.data.model
-enum class ComposterUpgrade(val displayName: String) {
- COMPOSTER_SPEED("Composter Speed"),
- ORGANIC_MATTER_CAP("Organic Matter Cap"),
- MULTI_DROP("Multi Drop"),
- COST_REDUCTION("Cost Reduction"),
- FUEL_CAP("Fuel Cap"),
+enum class ComposterUpgrade(val displayName: String, val slotNumber: Int) {
+ COMPOSTER_SPEED("Composter Speed", 20),
+ MULTI_DROP("Multi Drop", 21),
+ FUEL_CAP("Fuel Cap", 22),
+ ORGANIC_MATTER_CAP("Organic Matter Cap", 23),
+ COST_REDUCTION("Cost Reduction", 24),
;
companion object {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarDataHolder.kt b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarDataHolder.kt
index da06c15f1..a149b09c1 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarDataHolder.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarDataHolder.kt
@@ -17,7 +17,6 @@ class BazaarDataHolder {
}
private fun loadNpcPrices(): MutableMap<String, Double> {
- println("loadNpcPrices")
val list = mutableMapOf<String, Double>()
try {
val itemsData = APIUtil.getJSONResponse("https://api.hypixel.net/resources/skyblock/items")
@@ -71,6 +70,7 @@ class BazaarDataHolder {
if (internalName.startsWith("TURBO_")) return true
if (internalName == "PURPLE_CANDY") return true
if (internalName == "JACOBS_TICKET") return true
+ if (internalName == "RAW_SOULFLOW") return true
return false
}
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 192746e0a..d6ffa41ab 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt
@@ -4,6 +4,8 @@ import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.data.ScoreboardData
import at.hannibal2.skyhanni.events.*
+import at.hannibal2.skyhanni.features.garden.composter.ComposterOverlay
+import at.hannibal2.skyhanni.features.garden.inventory.SkyMartCopperPrice
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getCultivatingCounter
@@ -133,4 +135,6 @@ object GardenAPI {
}
fun isSpeedDataEmpty() = cropsPerSecond.values.sum() < 0
+
+ fun hideExtraGuis() = ComposterOverlay.inInventory || AnitaMedalProfit.inInventory || SkyMartCopperPrice.inInventory
} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterAPI.kt
index 35d144a12..fb45d179c 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterAPI.kt
@@ -4,14 +4,41 @@ import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.data.model.ComposterUpgrade
import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.minutes
object ComposterAPI {
var tabListData = mapOf<ComposterDisplay.DataType, String>()
val composterUpgrades: MutableMap<ComposterUpgrade, Int> get() = SkyHanniMod.feature.hidden.gardenComposterUpgrades
- fun ComposterUpgrade.getLevel() = composterUpgrades[this] ?: 0
+ fun ComposterUpgrade.getLevel(addOne: ComposterUpgrade?) = (composterUpgrades[this] ?: 0) + if (addOne == this) 1 else 0
fun getFuel() = tabListData[ComposterDisplay.DataType.FUEL]?.removeColor()?.formatNumber() ?: 0
fun getOrganicMatter() = tabListData[ComposterDisplay.DataType.ORGANIC_MATTER]?.removeColor()?.formatNumber() ?: 0
+
+ fun maxOrganicMatter(addOne: ComposterUpgrade?) = 40_000 + ComposterUpgrade.ORGANIC_MATTER_CAP.getLevel(addOne) * 20_000
+
+ fun multiDropChance(addOne: ComposterUpgrade?) = ComposterUpgrade.MULTI_DROP.getLevel(addOne) * 0.03
+
+ fun maxFuel(addOne: ComposterUpgrade?) = 100_000 + ComposterUpgrade.FUEL_CAP.getLevel(addOne) * 30_000
+
+ fun timePerCompost(addOne: ComposterUpgrade?): Duration {
+ val speedUpgrade = ComposterUpgrade.COMPOSTER_SPEED.getLevel(addOne)
+ val speedFactor = 1 + speedUpgrade * 0.2
+ val baseDuration = 10.minutes
+ return baseDuration / speedFactor
+ }
+
+ fun organicMatterRequiredPer(addOne: ComposterUpgrade?): Double {
+ val costReduction = ComposterUpgrade.COST_REDUCTION.getLevel(addOne)
+ val costFactor = 1.0 - costReduction.toDouble() / 100
+ return 4_000.0 * costFactor
+ }
+
+ fun fuelRequiredPer(addOne: ComposterUpgrade?): Double {
+ val costReduction = ComposterUpgrade.COST_REDUCTION.getLevel(addOne)
+ val costFactor = 1.0 - costReduction.toDouble() / 100
+ return 2_000.0 * costFactor
+ }
} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterDisplay.kt
index 846ab4bf1..9914f756f 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterDisplay.kt
@@ -2,11 +2,9 @@ package at.hannibal2.skyhanni.features.garden.composter
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.data.TitleUtils
-import at.hannibal2.skyhanni.data.model.ComposterUpgrade
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.TabListUpdateEvent
import at.hannibal2.skyhanni.features.garden.GardenAPI
-import at.hannibal2.skyhanni.features.garden.composter.ComposterAPI.getLevel
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
import at.hannibal2.skyhanni.utils.NEUItems
@@ -15,7 +13,6 @@ import at.hannibal2.skyhanni.utils.TimeUtils
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import java.util.regex.Pattern
import kotlin.time.Duration
-import kotlin.time.Duration.Companion.minutes
import kotlin.time.DurationUnit
class ComposterDisplay {
@@ -63,15 +60,10 @@ class ComposterDisplay {
return
}
- val speedUpgrade = ComposterUpgrade.COMPOSTER_SPEED.getLevel()
- val speedFactor = 1 + speedUpgrade * 0.2
- val baseDuration = 10.minutes
- val timePerCompost = baseDuration / speedFactor
+ val timePerCompost = ComposterAPI.timePerCompost(null)
- val costReduction = ComposterUpgrade.COST_REDUCTION.getLevel()
- val costFactor = 1.0 - costReduction.toDouble() / 100
- val organicMatterRequired = 4_000.0 * costFactor
- val fuelRequired = 2_000.0 * costFactor
+ val organicMatterRequired = ComposterAPI.organicMatterRequiredPer(null)
+ val fuelRequired = ComposterAPI.fuelRequiredPer(null)
val organicMatterRemaining = organicMatter / organicMatterRequired
val fuelRemaining = fuel / fuelRequired
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterOverlay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterOverlay.kt
new file mode 100644
index 000000000..fbca4aad9
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterOverlay.kt
@@ -0,0 +1,438 @@
+package at.hannibal2.skyhanni.features.garden.composter
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.model.ComposterUpgrade
+import at.hannibal2.skyhanni.events.*
+import at.hannibal2.skyhanni.features.garden.GardenAPI
+import at.hannibal2.skyhanni.features.garden.composter.ComposterAPI.getLevel
+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.LorenzUtils.round
+import at.hannibal2.skyhanni.utils.LorenzUtils.sortedDesc
+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.romanToDecimalIfNeeded
+import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
+import at.hannibal2.skyhanni.utils.StringUtils.removeColor
+import at.hannibal2.skyhanni.utils.TimeUtils
+import at.hannibal2.skyhanni.utils.renderables.Renderable
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates
+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.ceil
+import kotlin.time.Duration
+import kotlin.time.DurationUnit
+
+class ComposterOverlay {
+ private var organicMatterFactors: Map<String, Double> = emptyMap()
+ private var fuelFactors: Map<String, Double> = emptyMap()
+
+ private val config get() = SkyHanniMod.feature.garden
+ private val hidden get() = SkyHanniMod.feature.hidden
+ private var organicMatterDisplay = listOf<List<Any>>()
+ private var fuelExtraDisplay = listOf<List<Any>>()
+
+ private var currentOrganicMatterItem: String
+ get() = hidden.gardenComposterCurrentOrganicMatterItem
+ set(value) {
+ hidden.gardenComposterCurrentOrganicMatterItem = value
+ }
+
+ private var currentFuelItem: String
+ get() = hidden.gardenComposterCurrentFuelItem
+ set(value) {
+ hidden.gardenComposterCurrentFuelItem = value
+ }
+
+ private var currentTimeType = TimeType.HOUR
+ private var inComposter = false
+ private var inComposterUpgrades = false
+ private var extraComposterUpgrade: ComposterUpgrade? = null
+ set(value) {
+ field = value
+ lastHovered = System.currentTimeMillis()
+ }
+
+ private var maxLevel = false
+ private var lastHovered = 0L
+
+ companion object {
+ var inInventory = false
+ }
+
+ @SubscribeEvent
+ fun onInventoryClose(event: GuiContainerEvent.CloseWindowEvent) {
+ inInventory = false
+ }
+
+ @SubscribeEvent(priority = EventPriority.LOW)
+ fun onTabListUpdate(event: TabListUpdateEvent) {
+ if (!inInventory) return
+
+ update()
+ }
+
+ @SubscribeEvent
+ fun onTick(event: TickEvent.ClientTickEvent) {
+ if (!GardenAPI.inGarden()) return
+ if (inComposterUpgrades) {
+ if (extraComposterUpgrade != null) {
+// if (System.currentTimeMillis() > lastHovered + 30) {
+ if (System.currentTimeMillis() > lastHovered + 200) {
+ extraComposterUpgrade = null
+ update()
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ fun onInventoryOpen(event: InventoryOpenEvent) {
+ if (!GardenAPI.inGarden()) return
+ if (!config.composterOverlay) return
+ inComposter = event.inventoryName == "Composter"
+ inComposterUpgrades = event.inventoryName == "Composter Upgrades"
+ if (!inComposter && !inComposterUpgrades) return
+
+ inInventory = true
+ update()
+ }
+
+ @SubscribeEvent
+ fun onTooltip(event: ItemTooltipEvent) {
+ if (inComposterUpgrades) {
+ update()
+ for (upgrade in ComposterUpgrade.values()) {
+ event.itemStack?.name?.let {
+ if (it.contains(upgrade.displayName)) {
+ val matcher = ComposterUpgrade.regex.matcher(it)
+ matcher.matches()
+ val level = matcher.group("level")?.romanToDecimalIfNeeded() ?: 0
+ maxLevel = level == 25
+ extraComposterUpgrade = upgrade
+ update()
+ return
+ }
+ }
+ }
+ if (extraComposterUpgrade != null) {
+ extraComposterUpgrade = null
+ maxLevel = false
+ update()
+ }
+ }
+ }
+
+ private fun update() {
+ if (inComposter) {
+ organicMatterDisplay = drawOrganicMatterDisplay()
+ fuelExtraDisplay = drawFuelExtraDisplay()
+ } else if (inComposterUpgrades) {
+ organicMatterDisplay = drawUpgradeStats()
+ fuelExtraDisplay = emptyList()
+ }
+ }
+
+ private fun drawUpgradeStats(): List<List<Any>> {
+ val newList = mutableListOf<List<Any>>()
+
+ var upgrade = extraComposterUpgrade
+ if (upgrade == null) {
+ newList.addAsSingletonList("§7Preview: Nothing")
+ } else {
+ val level = upgrade.getLevel(null)
+ val nextLevel = if (maxLevel) "§6§lMAX" else "§c➜ §a" + (level + 1)
+ val displayName = upgrade.displayName
+ newList.addAsSingletonList("§7Preview §a$displayName§7: §a$level $nextLevel")
+ }
+ newList.addAsSingletonList("")
+ if (maxLevel) {
+ upgrade = null
+ }
+
+ addExtraData(newList)
+
+ val maxOrganicMatter = ComposterAPI.maxOrganicMatter(null)
+ val maxOrganicMatterPreview = ComposterAPI.maxOrganicMatter(upgrade)
+
+ val matterPer = ComposterAPI.organicMatterRequiredPer(null)
+ val matterPerPreview = ComposterAPI.organicMatterRequiredPer(upgrade)
+
+ val matterMaxDuration = ComposterAPI.timePerCompost(null) * (maxOrganicMatter / matterPer)
+ val matterMaxDurationPreview =
+ ComposterAPI.timePerCompost(upgrade) * (maxOrganicMatterPreview / matterPerPreview)
+
+ var format = formatTime(matterMaxDuration)
+ var formatPreview =
+ if (matterMaxDuration != matterMaxDurationPreview) " §c➜ §b" + formatTime(matterMaxDurationPreview) else ""
+
+ newList.addAsSingletonList("§7Full §eOrganic Matter §7empty time: §b$format$formatPreview")
+
+ val maxFuel = ComposterAPI.maxFuel(null)
+ val maxFuelPreview = ComposterAPI.maxFuel(upgrade)
+
+ val fuelRequiredPer = ComposterAPI.fuelRequiredPer(null)
+ val fuelRequiredPerPreview = ComposterAPI.fuelRequiredPer(upgrade)
+
+ val fuelMaxDuration = ComposterAPI.timePerCompost(null) * (maxFuel / fuelRequiredPer)
+ val fuelMaxDurationPreview =
+ ComposterAPI.timePerCompost(upgrade) * (maxFuelPreview / fuelRequiredPerPreview)
+
+ format = formatTime(fuelMaxDuration)
+ formatPreview =
+ if (fuelMaxDuration != fuelMaxDurationPreview) " §c➜ §b" + formatTime(fuelMaxDurationPreview) else ""
+ newList.addAsSingletonList("§7Full §2Fuel §7empty time: §b$format$formatPreview")
+
+ return newList
+ }
+
+ private fun formatTime(timePerCompost1: Duration) =
+ TimeUtils.formatDuration(timePerCompost1.toLong(DurationUnit.MILLISECONDS), maxUnits = 2)
+
+ private fun drawOrganicMatterDisplay(): MutableList<List<Any>> {
+ val maxOrganicMatter = ComposterAPI.maxOrganicMatter(if (maxLevel) null else extraComposterUpgrade)
+ val currentOrganicMatter = ComposterAPI.getOrganicMatter()
+ val missingOrganicMatter = (maxOrganicMatter - currentOrganicMatter).toDouble()
+
+ val newList = mutableListOf<List<Any>>()
+ newList.addAsSingletonList("§7Items needed to fill §eOrganic Matter")
+ val fillList = fillList(newList, organicMatterFactors, missingOrganicMatter) {
+ currentOrganicMatterItem = it
+ update()
+ }
+ if (currentOrganicMatterItem == "") {
+ currentOrganicMatterItem = fillList
+ update()
+ }
+ return newList
+ }
+
+ private fun drawFuelExtraDisplay(): List<List<Any>> {
+ val newList = mutableListOf<List<Any>>()
+
+ addExtraData(newList)
+
+ if (inComposter) {
+ newList.addAsSingletonList("§7Items needed to fill §2Fuel")
+ val maxFuel = ComposterAPI.maxFuel(null)
+ val currentFuel = ComposterAPI.getFuel()
+ val missingFuel = (maxFuel - currentFuel).toDouble()
+ val fillList = fillList(newList, fuelFactors, missingFuel) {
+ currentFuelItem = it
+ update()
+ }
+ if (currentFuelItem == "") {
+ currentFuelItem = fillList
+ update()
+ }
+ }
+ return newList
+ }
+
+ private fun addExtraData(newList: MutableList<List<Any>>) {
+ val organicMatterItem = currentOrganicMatterItem
+ val fuelItem = currentFuelItem
+ if (organicMatterItem == "" || fuelItem == "") return
+
+ val clickableList = mutableListOf<Any>()
+ clickableList.add("§7Per ")
+ for (type in TimeType.values()) {
+ val display = type.display
+ if (type == currentTimeType) {
+ clickableList.add("§a[$display]")
+ } else {
+ clickableList.add("§e[")
+ clickableList.add(Renderable.link("§e$display") {
+ currentTimeType = type
+ update()
+ })
+ clickableList.add("§e]")
+ }
+ clickableList.add(" ")
+ }
+ newList.add(clickableList)
+
+
+ val list = mutableListOf<Any>()
+ list.add("§7Using: ")
+ list.add(NEUItems.getItemStack(organicMatterItem))
+ list.add("§7and ")
+ list.add(NEUItems.getItemStack(fuelItem))
+ newList.add(list)
+
+ val timePerCompost = ComposterAPI.timePerCompost(null).toLong(DurationUnit.MILLISECONDS)
+ val upgrade = if (maxLevel) null else extraComposterUpgrade
+ val timePerCompostPreview = ComposterAPI.timePerCompost(upgrade).toLong(DurationUnit.MILLISECONDS)
+ val format = TimeUtils.formatDuration(timePerCompost)
+ val formatPreview =
+ if (timePerCompostPreview != timePerCompost) " §c➜ §b" + TimeUtils.formatDuration(timePerCompostPreview) else ""
+ newList.addAsSingletonList(" §7Time per Compost: §b$format$formatPreview")
+
+ val timeText = currentTimeType.display.lowercase()
+ val timeMultiplier = if (currentTimeType != TimeType.COMPOST) {
+ (currentTimeType.multiplier * 1000 / (timePerCompost.toDouble()))
+ } else 1.0
+ val timeMultiplierPreview = if (currentTimeType != TimeType.COMPOST) {
+ (currentTimeType.multiplier * 1000 / (timePerCompostPreview.toDouble()))
+ } else 1.0
+
+ val multiDropFactor = ComposterAPI.multiDropChance(null) + 1
+ val multiDropFactorPreview = ComposterAPI.multiDropChance(upgrade) + 1
+ val multiplier = multiDropFactor * timeMultiplier
+ val multiplierPreview = multiDropFactorPreview * timeMultiplierPreview
+ val compostPerTitlePreview =
+ if (multiplier != multiplierPreview) " §c➜ §e" + multiplierPreview.round(2) else ""
+ val compostPerTitle =
+ if (currentTimeType == TimeType.COMPOST) "Compost multiplier" else "Composts per $timeText"
+ newList.addAsSingletonList(" §7$compostPerTitle: §e${multiplier.round(2)}$compostPerTitlePreview")
+
+
+ val organicMatterPrice = NEUItems.getPrice(organicMatterItem)
+ val organicMatterFactor = organicMatterFactors[organicMatterItem]!!
+
+ val organicMatterRequired = ComposterAPI.organicMatterRequiredPer(null)
+ val organicMatterRequiredPreview = ComposterAPI.organicMatterRequiredPer(upgrade)
+
+ val organicMatterPricePer = organicMatterPrice * (organicMatterRequired / organicMatterFactor)
+ val organicMatterPricePerPreview = organicMatterPrice * (organicMatterRequiredPreview / organicMatterFactor)
+
+ val fuelPrice = NEUItems.getPrice(fuelItem)
+ val fuelFactor = fuelFactors[fuelItem]!!
+
+ val fuelRequired = ComposterAPI.fuelRequiredPer(null)
+ val fuelRequiredPreview = ComposterAPI.fuelRequiredPer(upgrade)
+
+ val fuelPricePer = fuelPrice * (fuelRequired / fuelFactor)
+ val fuelPricePerPreview = fuelPrice * (fuelRequiredPreview / fuelFactor)
+
+ val totalCost = (fuelPricePer + organicMatterPricePer) * multiplier
+ val totalCostPreview = (fuelPricePerPreview + organicMatterPricePerPreview) * multiplierPreview
+
+ val materialCostFormatPreview =
+ if (totalCost != totalCostPreview) " §c➜ §6" + NumberUtil.format(totalCostPreview) else ""
+ val materialCostFormat =
+ " §7Material costs per $timeText: §6${NumberUtil.format(totalCost)}$materialCostFormatPreview"
+ newList.addAsSingletonList(materialCostFormat)
+
+
+ val priceCompost = NEUItems.getPrice("COMPOST")
+ val profit = (priceCompost - (fuelPricePer + organicMatterPricePer)) * multiplier
+ val profitPreview = (priceCompost - (fuelPricePerPreview + organicMatterPricePerPreview)) * multiplierPreview
+
+ val profitFormatPreview = if (profit != profitPreview) " §c➜ §6" + NumberUtil.format(profitPreview) else ""
+ val profitFormat = " §7Profit per $timeText: §6${NumberUtil.format(profit)}$profitFormatPreview"
+ newList.addAsSingletonList(profitFormat)
+
+ newList.addAsSingletonList("")
+ }
+
+ private fun fillList(
+ bigList: MutableList<List<Any>>,
+ factors: Map<String, Double>,
+ missing: Double,
+ onClick: (String) -> Unit,
+ ): String {
+ val map = mutableMapOf<String, Double>()
+ for ((internalName, factor) in factors) {
+ map[internalName] = factor / NEUItems.getPrice(internalName)
+ }
+
+ var i = 0
+ var first: String? = null
+ for (internalName in map.sortedDesc().keys) {
+ if (first == null) first = internalName
+ val factor = factors[internalName]!!
+
+ val item = NEUItems.getItemStack(internalName)
+ val itemName = item.name!!
+ val price = NEUItems.getPrice(internalName)
+ val itemsNeeded = ceil(missing / factor)
+ val totalPrice = itemsNeeded * price
+
+ val list = mutableListOf<Any>()
+ list.add(item)
+ val format = NumberUtil.format(totalPrice)
+ val selected =
+ if (internalName == currentOrganicMatterItem || internalName == currentFuelItem) "§n" else ""
+ val name = itemName.substring(0, 2) + selected + itemName.removeColor()
+ list.add(Renderable.link("$name§r §8x${itemsNeeded.addSeparators()} §7(§6$format§7)") {
+ onClick(internalName)
+ })
+ bigList.add(list)
+
+
+ i++
+ if (i == 10) break
+ }
+
+ return first!!
+ }
+
+ @SubscribeEvent
+ fun onRepoReload(event: RepositoryReloadEvent) {
+ try {
+ val garden = event.getConstant("Garden")!!
+
+ val baseValues = mutableMapOf<String, Double>()
+ for ((name, value) in garden["organic_matter"].asJsonObject.entrySet()) {
+ baseValues[name] = value.asDouble
+ }
+ organicMatterFactors = updateOrganicMatterFactors(baseValues)
+
+ val fuelMap = mutableMapOf<String, Double>()
+ for ((name, value) in garden["fuel"].asJsonObject.entrySet()) {
+ fuelMap[name] = value.asDouble
+ }
+ fuelFactors = fuelMap
+ } catch (e: Exception) {
+ e.printStackTrace()
+ LorenzUtils.error("error in RepositoryReloadEvent")
+ }
+ }
+
+ private fun updateOrganicMatterFactors(baseValues: MutableMap<String, Double>): Map<String, Double> {
+ val map = mutableMapOf<String, Double>()
+ for ((internalName, _) in NotEnoughUpdates.INSTANCE.manager.itemInformation) {
+ if (internalName.endsWith("_BOOTS")) continue
+ if (internalName.endsWith("_HELMET")) continue
+ if (internalName.endsWith("_CHESTPLATE")) continue
+ if (internalName.endsWith("_LEGGINGS")) continue
+ val (newId, amount) = NEUItems.getMultiplier(internalName)
+ val finalAmount =
+ if (internalName == "ENCHANTED_HUGE_MUSHROOM_1" || internalName == "ENCHANTED_HUGE_MUSHROOM_2") {
+ // 160 * 8 * 4 is 5120 and not 5184, but hypixel made an error, so we have to copy the error
+ 5184
+ } else amount
+
+ baseValues[newId]?.let {
+ val d = it * finalAmount
+ map[internalName] = d
+ }
+ }
+ return map
+ }
+
+ @SubscribeEvent
+ fun onBackgroundDraw(event: GuiRenderEvent.ChestBackgroundRenderEvent) {
+ if (inInventory) {
+ config.composterOverlayOrganicMatterPos.renderStringsAndItems(
+ organicMatterDisplay,
+ posLabel = "Composter Overlay Organic Matter"
+ )
+ config.composterOverlayFuelExtrasPos.renderStringsAndItems(
+ fuelExtraDisplay,
+ posLabel = "Composter Overlay Fuel Extras"
+ )
+ }
+ }
+
+ enum class TimeType(val display: String, val multiplier: Int) {
+ COMPOST("Compost", 1),
+ HOUR("Hour", 60 * 60),
+ DAY("Day", 60 * 60 * 24),
+ }
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropMoneyDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropMoneyDisplay.kt
index 979f7d6b8..d219aefce 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropMoneyDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/CropMoneyDisplay.kt
@@ -40,7 +40,9 @@ class CropMoneyDisplay {
fun onRenderOverlay(event: GuiRenderEvent.GameOverlayRenderEvent) {
if (!isEnabled()) return
- config.moneyPerHourPos.renderStringsAndItems(display, posLabel = "Garden Crop Money Per Hour")
+ if (!GardenAPI.hideExtraGuis()) {
+ config.moneyPerHourPos.renderStringsAndItems(display, posLabel = "Garden Crop Money Per Hour")
+ }
}
@SubscribeEvent
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropMilestoneDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropMilestoneDisplay.kt
index d40c7e21c..0442e4ffe 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropMilestoneDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropMilestoneDisplay.kt
@@ -77,6 +77,7 @@ class GardenCropMilestoneDisplay {
@SubscribeEvent
fun onRenderOverlay(event: GuiRenderEvent.GameOverlayRenderEvent) {
if (!isEnabled()) return
+ if (GardenAPI.hideExtraGuis()) return
config.cropMilestoneProgressDisplayPos.renderStringsAndItems(
progressDisplay,
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 17823d52a..aa6aaba5c 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
@@ -544,7 +544,9 @@ class GardenVisitorFeatures {
if (config.visitorNeedsOnlyWhenClose && !GardenAPI.onBarnPlot) return
- config.visitorNeedsPos.renderStringsAndItems(display, posLabel = "Visitor Items Needed")
+ if (!GardenAPI.hideExtraGuis()) {
+ config.visitorNeedsPos.renderStringsAndItems(display, posLabel = "Visitor Items Needed")
+ }
}
@SubscribeEvent(priority = EventPriority.HIGH)
diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/JacobFarmingContestsInventory.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/JacobFarmingContestsInventory.kt
index 0ce9023a0..f21bbbbb8 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/inventory/JacobFarmingContestsInventory.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/JacobFarmingContestsInventory.kt
@@ -135,7 +135,6 @@ class JacobFarmingContestsInventory {
if (!InventoryUtils.openInventoryName().contains("Your Contests")) return
val slot = event.slot.slotNumber
-
if (config.jacobFarmingContestHideDuplicates) {
if (duplicateSlots.contains(slot)) {
event.toolTip.clear()
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt
index 253be7938..4adec2c34 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt
@@ -52,7 +52,7 @@ object TimeUtils {
}
}
}
- return builder.toString()
+ return builder.toString().trim()
}
// TODO: use kotlin Duration