aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorappable <enzospiacitelli@gmail.com>2023-04-12 06:09:48 -0700
committerGitHub <noreply@github.com>2023-04-12 15:09:48 +0200
commit6a4663673cb244fb265bb08f96165d4929e72f0c (patch)
tree9840d09dd34f4df40382574868d568373e3ee84d /src/main/java
parentd5dbe653bb865e85d0f433313ab11e21efdaed39 (diff)
downloadskyhanni-6a4663673cb244fb265bb08f96165d4929e72f0c.tar.gz
skyhanni-6a4663673cb244fb265bb08f96165d4929e72f0c.tar.bz2
skyhanni-6a4663673cb244fb265bb08f96165d4929e72f0c.zip
Farming fortune accessory support (#37)
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java1
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/Bazaar.java2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/Garden.java10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/Hidden.java4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/Misc.java3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/CropAccessoryData.kt124
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/CropAccessory.kt21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt63
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt5
10 files changed, 220 insertions, 15 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java
index 48d49ec87..055c645f7 100644
--- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java
+++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java
@@ -133,6 +133,7 @@ public class SkyHanniMod {
loadModule(new ToolTipData());
loadModule(new GuiEditManager());
loadModule(UpdateManager.INSTANCE);
+ loadModule(new CropAccessoryData());
// APIs
loadModule(new BazaarApi());
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Bazaar.java b/src/main/java/at/hannibal2/skyhanni/config/features/Bazaar.java
index 48d32fc15..e988c7b67 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/Bazaar.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/Bazaar.java
@@ -18,7 +18,7 @@ public class Bazaar {
public boolean bestSellMethod = false;
@Expose
- public Position bestSellMethodPos = new Position(10, 10, false, true);
+ public Position bestSellMethodPos = new Position(394, 142, false, true);
@Expose
@ConfigOption(name = "Cancelled Buy Order Clipboard", desc = "Saves missing items from cancelled buy orders to clipboard for faster re-entry.")
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 45189cec8..4a2ac82a2 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java
@@ -772,6 +772,16 @@ public class Garden {
public boolean farmingFortuneDisplay = true;
@Expose
+ @ConfigOption(
+ name = "Show As Drop Multiplier",
+ desc = "Adds 100 to the displayed farming fortune so that it represents a drop multiplier rather than" +
+ " the chance for bonus drops. "
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 18)
+ public boolean farmingFortuneDropMultiplier = false;
+
+ @Expose
public Position farmingFortunePos = new Position(-375, -200, false, true);
@Expose
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 1aa26dd72..59133d122 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/Hidden.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/Hidden.java
@@ -1,5 +1,6 @@
package at.hannibal2.skyhanni.config.features;
+import at.hannibal2.skyhanni.features.garden.CropAccessory;
import at.hannibal2.skyhanni.features.garden.CropType;
import com.google.gson.annotations.Expose;
@@ -47,6 +48,9 @@ public class Hidden {
public int gardenExp = -1;
@Expose
+ public CropAccessory savedCropAccessory = null;
+
+ @Expose
public Map<String, Integer> gardenDicerRngDrops = new HashMap<>();
@Expose
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java b/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java
index 8b9ea625a..7808e0df7 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java
@@ -276,4 +276,7 @@ public class Misc {
@ConfigOption(name = "Config Button", desc = "Add a button to the pause menu to configure SkyHanni.")
@ConfigEditorBoolean
public boolean configButtonOnPause = true;
+
+ @Expose
+ public Position inventoryLoadPos = new Position(394, 124, false, true);
}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/CropAccessoryData.kt b/src/main/java/at/hannibal2/skyhanni/data/CropAccessoryData.kt
new file mode 100644
index 000000000..ea50257c3
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/data/CropAccessoryData.kt
@@ -0,0 +1,124 @@
+package at.hannibal2.skyhanni.data
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.events.GuiContainerEvent
+import at.hannibal2.skyhanni.events.InventoryOpenEvent
+import at.hannibal2.skyhanni.events.ProfileApiDataLoadedEvent
+import at.hannibal2.skyhanni.events.ProfileJoinEvent
+import at.hannibal2.skyhanni.features.garden.CropAccessory
+import at.hannibal2.skyhanni.utils.InventoryUtils
+import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.NEUItems
+import com.google.gson.JsonElement
+import net.minecraft.item.ItemStack
+import net.minecraft.nbt.CompressedStreamTools
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import net.minecraftforge.fml.common.gameevent.TickEvent
+import java.io.ByteArrayInputStream
+import java.util.*
+
+class CropAccessoryData {
+ private val accessoryBagNamePattern = "Accessory Bag \\((\\d)/(\\d)\\)".toRegex()
+ private var loadedAccessoryThisProfile = false
+ private var ticks = 0
+ private var accessoryInBag: CropAccessory? = null
+ private var accessoryInInventory = CropAccessory.NONE
+
+ private var accessoryBagPageNumber = 0
+
+ // Handle API detection
+ @SubscribeEvent
+ fun onProfileJoin(event: ProfileJoinEvent) {
+ loadedAccessoryThisProfile = false
+ }
+
+ @SubscribeEvent
+ fun onProfileDataLoad(event: ProfileApiDataLoadedEvent) {
+ if (loadedAccessoryThisProfile) return
+ val inventoryData = event.profileData["inv_contents"] ?: return
+ val accessories = getCropAccessories(event.profileData["talisman_bag"]).also {
+ it.addAll(getCropAccessories(inventoryData))
+ }
+ cropAccessory = accessories.maxOrNull() ?: CropAccessory.NONE
+ loadedAccessoryThisProfile = true
+ }
+
+ // Handle accessory bag detection
+ @SubscribeEvent
+ fun onGuiDraw(event: InventoryOpenEvent) {
+ val groups = accessoryBagNamePattern.matchEntire(event.inventoryName)?.groups ?: return
+ accessoryBagPageCount = groups[2]!!.value.toInt()
+ accessoryBagPageNumber = groups[1]!!.value.toInt()
+ isLoadingAccessories = true
+
+ val bestCropAccessoryPage = bestCropAccessory(event.inventoryItems.values)
+ accessoryPage[accessoryBagPageNumber] = bestCropAccessoryPage
+ if (accessoryBagPageCount == accessoryPage.size) {
+ accessoryInBag = accessoryPage.values.max().also {
+ cropAccessory = maxOf(it, accessoryInInventory)
+ }
+ loadedAccessoryThisProfile = true
+ }
+ }
+
+ @SubscribeEvent
+ fun onCloseWindow(event: GuiContainerEvent.CloseWindowEvent) {
+ isLoadingAccessories = false
+ }
+
+ // Handle inventory detection
+ @SubscribeEvent
+ fun onTick(event: TickEvent.ClientTickEvent) {
+ if (event.phase != TickEvent.Phase.START || ticks++ % 20 != 0) return
+ if (!LorenzUtils.inSkyBlock) return
+ accessoryInInventory = bestCropAccessory(InventoryUtils.getItemsInOwnInventory())
+ if (accessoryInInventory == CropAccessory.NONE) return
+ if (accessoryInInventory > (accessoryInBag ?: CropAccessory.NONE)) {
+ cropAccessory = accessoryInInventory
+ }
+ }
+
+
+ private fun bestCropAccessory(items: Iterable<ItemStack>): CropAccessory {
+ return items.mapNotNull { item -> CropAccessory.getByName(item.getInternalName()) }
+ .maxOrNull() ?: CropAccessory.NONE
+ }
+
+ companion object {
+ var accessoryBagPageCount = 0
+ private set
+
+ private var accessoryPage = mutableMapOf<Int, CropAccessory>()
+
+ var isLoadingAccessories = false
+ private set
+
+ val pagesLoaded get() = accessoryPage.size
+
+ var cropAccessory: CropAccessory?
+ get() = SkyHanniMod.feature.hidden.savedCropAccessory
+ private set(accessory) {
+ SkyHanniMod.feature.hidden.savedCropAccessory = accessory
+ }
+
+ // Derived partially from NotEnoughUpdates/NotEnoughUpdates, ProfileViewer.Profile#getInventoryInfo
+ private fun getCropAccessories(inventory: JsonElement?): MutableList<CropAccessory> {
+ if (inventory == null) return mutableListOf()
+ val cropAccessories = mutableListOf<CropAccessory>()
+ val data = inventory.asJsonObject["data"]?.asString
+ val accessoryBagItems = CompressedStreamTools.readCompressed(
+ ByteArrayInputStream(Base64.getDecoder().decode(data))
+ ).getTagList("i", 10)
+ for (j in 0 until accessoryBagItems.tagCount()) {
+ val itemStackTag = accessoryBagItems.getCompoundTagAt(j)
+ if (!itemStackTag.hasKey("tag")) continue
+ val itemTag = itemStackTag.getCompoundTag("tag")
+ val itemName = NEUItems.getInternalNameOrNull(itemTag) ?: continue
+ val itemAsCropAccessory = CropAccessory.getByName(itemName) ?: continue
+ cropAccessories.add(itemAsCropAccessory)
+ }
+ return cropAccessories
+ }
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/CropAccessory.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/CropAccessory.kt
new file mode 100644
index 000000000..441453ded
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/CropAccessory.kt
@@ -0,0 +1,21 @@
+package at.hannibal2.skyhanni.features.garden
+
+enum class CropAccessory(val internalName: String, private val affectedCrops: Set<CropType>, private val fortune: Double) {
+ NONE("NONE", emptySet(), 0.0),
+ CROPIE("CROPIE_TALISMAN", setOf(CropType.WHEAT, CropType.POTATO, CropType.CARROT), 10.0),
+ SQUASH(
+ "SQUASH_RING",
+ setOf(CropType.WHEAT, CropType.POTATO, CropType.CARROT, CropType.COCOA_BEANS, CropType.MELON, CropType.PUMPKIN),
+ 20.0
+ ),
+ FERMENTO("FERMENTO_ARTIFACT", CropType.values().toSet(), 30.0),
+ ;
+
+ fun getFortune(cropType: CropType): Double {
+ return if (this.affectedCrops.contains(cropType)) this.fortune else 0.0
+ }
+
+ companion object {
+ fun getByName(internalName: String) = values().firstOrNull { it.internalName == internalName }
+ }
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt
index a838eecc5..60d70e691 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt
@@ -1,6 +1,7 @@
package at.hannibal2.skyhanni.features.garden
import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.CropAccessoryData
import at.hannibal2.skyhanni.data.GardenCropMilestones
import at.hannibal2.skyhanni.data.GardenCropMilestones.Companion.getCounter
import at.hannibal2.skyhanni.data.GardenCropUpgrades.Companion.getUpgradeLevel
@@ -12,7 +13,9 @@ import at.hannibal2.skyhanni.features.garden.GardenAPI.Companion.getCropType
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.RenderUtils.renderSingleLineWithItems
+import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
+import at.hannibal2.skyhanni.utils.RenderUtils.renderString
+import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getEnchantments
import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getHoeCounter
import net.minecraft.item.ItemStack
@@ -27,12 +30,18 @@ class FarmingFortuneDisplay {
private val tabFortunePattern = " Farming Fortune: §r§6☘(\\d+)".toRegex()
- private var display = listOf<Any>()
+ private var display = listOf<List<Any>>()
+ private var accessoryProgressDisplay = ""
private var currentCrop: CropType? = null
private var tabFortune: Double = 0.0
private var toolFortune: Double = 0.0
+ private val baseFortune: Double get() = if (config.farmingFortuneDropMultiplier) 100.0 else 0.0
private val upgradeFortune: Double? get() = currentCrop?.getUpgradeLevel()?.let { it * 5.0 }
+ private val accessoryFortune: Double?
+ get() = currentCrop?.let {
+ CropAccessoryData.cropAccessory?.getFortune(it)
+ }
private var lastToolSwitch: Long = 0
private var ticks: Int = 0
@@ -73,23 +82,47 @@ class FarmingFortuneDisplay {
@SubscribeEvent
fun onRenderOverlay(event: GuiRenderEvent.GameOverlayRenderEvent) {
if (!isEnabled()) return
- config.farmingFortunePos.renderSingleLineWithItems(display, posLabel = "True Farming Fortune")
+ config.farmingFortunePos.renderStringsAndItems(display, posLabel = "True Farming Fortune")
+ }
+
+ @SubscribeEvent
+ fun onRenderOverlay(event: GuiRenderEvent.ChestBackgroundRenderEvent) {
+ if (!isEnabled()) return
+ if (!CropAccessoryData.isLoadingAccessories) return
+ SkyHanniMod.feature.misc.inventoryLoadPos.renderString(accessoryProgressDisplay, posLabel = "Load Accessory Bags")
}
@SubscribeEvent
fun onTick(event: TickEvent.ClientTickEvent) {
if (event.phase != TickEvent.Phase.START || ticks++ % 5 != 0) return
val displayCrop = currentCrop ?: return
- val updatedDisplay = mutableListOf<Any>()
- updatedDisplay.addCropIcon(displayCrop)
- val recentlySwitchedTool = System.currentTimeMillis() < lastToolSwitch + 1000
- val displayString = upgradeFortune?.let {
- "§6Farming Fortune§7: §e" + if (!recentlySwitchedTool) {
- val totalFortune = it + tabFortune + toolFortune
- LorenzUtils.formatDouble(totalFortune, 0)
- } else "?"
- } ?: "§cOpen §e/cropupgrades§c to use!"
- updatedDisplay.add(displayString)
+
+ val updatedDisplay = mutableListOf<List<Any>>()
+ updatedDisplay.add(mutableListOf<Any>().also {
+ it.addCropIcon(displayCrop)
+ val recentlySwitchedTool = System.currentTimeMillis() < lastToolSwitch + 1000
+ it.add(
+ "§6Farming Fortune§7: §e" + if (!recentlySwitchedTool) {
+ val upgradeFortune = upgradeFortune ?: 0.0
+ val accessoryFortune = accessoryFortune ?: 0.0
+ val totalFortune = baseFortune + upgradeFortune + tabFortune + toolFortune + accessoryFortune
+ LorenzUtils.formatDouble(totalFortune, 0)
+ } else "?")
+ })
+
+ if (this.upgradeFortune == null) {
+ updatedDisplay.addAsSingletonList("§cOpen §e/cropupgrades§c for more exact data!")
+ }
+ if (accessoryFortune == null) {
+ updatedDisplay.addAsSingletonList("§cOpen Accessory Bag for more exact data!")
+ if (CropAccessoryData.isLoadingAccessories) {
+ accessoryProgressDisplay =
+ "§e${CropAccessoryData.pagesLoaded}/${CropAccessoryData.accessoryBagPageCount} pages viewed"
+ }
+ } else {
+ accessoryProgressDisplay = ""
+ }
+
display = updatedDisplay
}
@@ -104,9 +137,11 @@ class FarmingFortuneDisplay {
private fun isEnabled(): Boolean = GardenAPI.inGarden() && config.farmingFortuneDisplay
+
companion object {
private val collectionPattern = "§7You have §6\\+([\\d]{1,3})☘ Farming Fortune".toRegex()
+
fun getToolFortune(tool: ItemStack?): Double {
val internalName = tool?.getInternalName() ?: return 0.0
return if (internalName.startsWith("THEORETICAL_HOE")) {
@@ -148,5 +183,7 @@ class FarmingFortuneDisplay {
)
return dedicationMultiplier * cropMilestone
}
+
+
}
} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt
index 398b6818f..e056ba510 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt
@@ -218,7 +218,7 @@ class GardenNextJacobContest {
if (!inCalendar) return
if (display.isNotEmpty()) {
- config.nextJacobContestPos.renderSingleLineWithItems(display, posLabel = "Garden Next Jacob Contest")
+ SkyHanniMod.feature.misc.inventoryLoadPos.renderSingleLineWithItems(display, posLabel = "Load SkyBlock Calendar")
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
index 25d67bb07..2549c215b 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
@@ -12,6 +12,7 @@ import net.minecraft.client.renderer.GlStateManager
import net.minecraft.client.renderer.RenderHelper
import net.minecraft.init.Items
import net.minecraft.item.ItemStack
+import net.minecraft.nbt.NBTTagCompound
object NEUItems {
private val manager: NEUManager get() = NotEnoughUpdates.INSTANCE.manager
@@ -47,6 +48,10 @@ object NEUItems {
.resolveInternalName() ?: ""
}
+ fun getInternalNameOrNull(nbt: NBTTagCompound): String? {
+ return ItemResolutionQuery(manager).withItemNBT(nbt).resolveInternalName()
+ }
+
fun getPriceOrNull(internalName: String, useSellingPrice: Boolean = false): Double? {
val price = getPrice(internalName, useSellingPrice)
if (price == -1.0) {