aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/inventory/BazaarConfig.java9
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/InventoryFullyOpenedEvent.kt11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/inventory/bazaar/CraftMaterialsFromBazaar.kt164
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/PrimitiveItemStack.kt3
5 files changed, 189 insertions, 0 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt
index b1dbd73e0..4d0765de0 100644
--- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt
+++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt
@@ -237,6 +237,7 @@ import at.hannibal2.skyhanni.features.inventory.bazaar.BazaarBestSellMethod
import at.hannibal2.skyhanni.features.inventory.bazaar.BazaarCancelledBuyOrderClipboard
import at.hannibal2.skyhanni.features.inventory.bazaar.BazaarOpenPriceWebsite
import at.hannibal2.skyhanni.features.inventory.bazaar.BazaarOrderHelper
+import at.hannibal2.skyhanni.features.inventory.bazaar.CraftMaterialsFromBazaar
import at.hannibal2.skyhanni.features.inventory.tiarelay.TiaRelayHelper
import at.hannibal2.skyhanni.features.inventory.tiarelay.TiaRelayWaypoints
import at.hannibal2.skyhanni.features.itemabilities.ChickenHeadTimer
@@ -787,6 +788,7 @@ class SkyHanniMod {
loadModule(InfernoMinionFeatures())
loadModule(LimboPlaytime())
loadModule(RareDropMessages())
+ loadModule(CraftMaterialsFromBazaar())
init()
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/BazaarConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/BazaarConfig.java
index 418d629dc..7d0ca7e81 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/BazaarConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/BazaarConfig.java
@@ -49,4 +49,13 @@ public class BazaarConfig {
@Expose
public Position maxPurseItemsPosition = new Position(346, 90, true, false);
+
+ @Expose
+ @ConfigOption(name = "Craft Materials Bazaar", desc = "In the crafting view, offer a shopping list of required materials for the craft along with a convenient shortcut for purchasing them from the Bazaar.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean craftMaterialsFromBazaar = false;
+
+ @Expose
+ public Position craftMaterialsFromBazaarPosition = new Position(50, 50, true, false);
}
diff --git a/src/main/java/at/hannibal2/skyhanni/events/InventoryFullyOpenedEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/InventoryFullyOpenedEvent.kt
index f8d6c4ab4..d786445fb 100644
--- a/src/main/java/at/hannibal2/skyhanni/events/InventoryFullyOpenedEvent.kt
+++ b/src/main/java/at/hannibal2/skyhanni/events/InventoryFullyOpenedEvent.kt
@@ -1,6 +1,8 @@
package at.hannibal2.skyhanni.events
import at.hannibal2.skyhanni.data.OtherInventoryData
+import at.hannibal2.skyhanni.utils.PrimitiveItemStack
+import at.hannibal2.skyhanni.utils.PrimitiveItemStack.Companion.toPrimitiveStackOrNull
import net.minecraft.item.ItemStack
open class InventoryOpenEvent(private val inventory: OtherInventoryData.Inventory) : LorenzEvent() {
@@ -12,6 +14,15 @@ open class InventoryOpenEvent(private val inventory: OtherInventoryData.Inventor
val inventoryItemsWithNull: Map<Int, ItemStack?> by lazy {
(0 until inventorySize).associateWith { inventoryItems[it] }
}
+ val inventoryItemsPrimitive: Map<Int, PrimitiveItemStack> by lazy {
+ val map = mutableMapOf<Int, PrimitiveItemStack>()
+ for ((slot, item) in inventoryItems) {
+ item.toPrimitiveStackOrNull()?.let {
+ map[slot] = it
+ }
+ }
+ map
+ }
val fullyOpenedOnce: Boolean get() = inventory.fullyOpenedOnce
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/bazaar/CraftMaterialsFromBazaar.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/bazaar/CraftMaterialsFromBazaar.kt
new file mode 100644
index 000000000..c17308bb9
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/bazaar/CraftMaterialsFromBazaar.kt
@@ -0,0 +1,164 @@
+package at.hannibal2.skyhanni.features.inventory.bazaar
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.events.GuiRenderEvent
+import at.hannibal2.skyhanni.events.InventoryCloseEvent
+import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
+import at.hannibal2.skyhanni.features.inventory.bazaar.BazaarApi.Companion.isBazaarItem
+import at.hannibal2.skyhanni.utils.CollectionUtils.addOrPut
+import at.hannibal2.skyhanni.utils.ItemUtils.itemName
+import at.hannibal2.skyhanni.utils.ItemUtils.itemNameWithoutColor
+import at.hannibal2.skyhanni.utils.ItemUtils.name
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.NEUInternalName
+import at.hannibal2.skyhanni.utils.NEUItems.getPrice
+import at.hannibal2.skyhanni.utils.NumberUtil
+import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
+import at.hannibal2.skyhanni.utils.PrimitiveItemStack
+import at.hannibal2.skyhanni.utils.PrimitiveItemStack.Companion.makePrimitiveStack
+import at.hannibal2.skyhanni.utils.RenderUtils.renderRenderables
+import at.hannibal2.skyhanni.utils.StringUtils.matches
+import at.hannibal2.skyhanni.utils.renderables.Renderable
+import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+class CraftMaterialsFromBazaar {
+
+ private val config get() = SkyHanniMod.feature.inventory.bazaar
+
+ private val materialSlots = listOf(10, 11, 12, 19, 20, 21, 28, 29, 30)
+ private val inventoryPattern by RepoPattern.pattern(
+ "inventory.recipe.title",
+ ".* Recipe"
+ )
+
+ private var inRecipeInventory = false
+ private var purchasing = false
+ private var display = listOf<Renderable>()
+ private var neededMaterials = listOf<PrimitiveItemStack>()
+ private var multiplier = 1
+
+ @SubscribeEvent
+ fun onInventoryOpen(event: InventoryFullyOpenedEvent) {
+ if (!isEnabled()) return
+ val correctInventoryName = inventoryPattern.matches(event.inventoryName)
+ val items = event.inventoryItems
+ val correctItem = items[23]?.name == "§aCrafting Table"
+
+ inRecipeInventory = correctInventoryName && correctItem && !purchasing
+ if (!inRecipeInventory) return
+
+ val recipeName = items[25]?.itemName ?: return
+ showRecipe(calculateMaterialsNeeded(event.inventoryItemsPrimitive), recipeName)
+ }
+
+ private fun showRecipe(
+ recipeMaterials: List<PrimitiveItemStack>,
+ recipeName: String,
+ ) {
+ val neededMaterials = mutableListOf<PrimitiveItemStack>()
+ display = buildList {
+ val totalPrice = calculateTotalPrice(recipeMaterials, 1)
+ add(Renderable.string("§7Craft $recipeName §7(§6${NumberUtil.format(totalPrice)}§7)"))
+ for (item in recipeMaterials) {
+ val material = item.internalName
+ val amount = item.amount
+ var text = "§8${amount.addSeparators()}x " + material.itemName
+ if (material.isBazaarItem()) {
+ neededMaterials.add(item)
+ text += " §6${NumberUtil.format(material.getPrice() * amount)}"
+ }
+ add(Renderable.string(text))
+ }
+ if (neededMaterials.isNotEmpty()) {
+ add(
+ Renderable.clickAndHover(
+ "§eGet from bazaar!",
+ listOf("§eClick here to buy the items from bazaar!"),
+ onClick = {
+ getFromBazaar(neededMaterials)
+ })
+ )
+ }
+ }
+ }
+
+ private fun calculateMaterialsNeeded(items: Map<Int, PrimitiveItemStack>): List<PrimitiveItemStack> {
+ val recipeMaterials = mutableMapOf<NEUInternalName, Int>()
+ for (slot in materialSlots) {
+ val item = items[slot] ?: continue
+ val internalName = item.internalName
+ recipeMaterials.addOrPut(internalName, item.amount)
+ }
+ return recipeMaterials.map { it.key.makePrimitiveStack(it.value) }
+ }
+
+ private fun getFromBazaar(neededMaterials: MutableList<PrimitiveItemStack>) {
+ this.neededMaterials = neededMaterials
+ this.multiplier = 1
+ purchasing = true
+ updateBazaarDisplay()
+ }
+
+ private fun updateBazaarDisplay() {
+ display = buildList {
+ add(Renderable.string("§7Buy items from Bazaar:"))
+ for ((material, amount) in neededMaterials) {
+ val priceMultiplier = amount * multiplier
+ val text = "§8${priceMultiplier.addSeparators()}x " + material.itemName +
+ " §6${NumberUtil.format(material.getPrice() * priceMultiplier)}"
+ add(Renderable.optionalLink(text, onClick = {
+ BazaarApi.searchForBazaarItem(material.itemNameWithoutColor, priceMultiplier)
+ }))
+ }
+ add(
+ Renderable.clickAndHover(
+ "§eStop!",
+ listOf("§eClick here to stop this view!"),
+ onClick = {
+ purchasing = false
+ display = emptyList()
+ })
+ )
+ addMultipliers()
+ }
+ }
+
+ private fun MutableList<Renderable>.addMultipliers() {
+ for (m in listOf(1, 5, 16, 32, 64, 512)) {
+ val nameColor = if (m == multiplier) "§amount" else "§e"
+ val priceColor = if (m == multiplier) "§6" else "§7"
+ val price = priceColor + NumberUtil.format(calculateTotalPrice(neededMaterials, m))
+ add(
+ Renderable.clickAndHover(
+ "${nameColor}Mulitply x$m $price",
+ listOf("§eClick here to multiply the items needed times $m!"),
+ onClick = {
+ multiplier = m
+ updateBazaarDisplay()
+ })
+ )
+ }
+ }
+
+ private fun calculateTotalPrice(neededMaterials: List<PrimitiveItemStack>, multiplier: Int): Double =
+ neededMaterials
+ .filter { it.internalName.isBazaarItem() }
+ .sumOf { it.internalName.getPrice() * it.amount * multiplier }
+
+ @SubscribeEvent
+ fun onInventoryClose(event: InventoryCloseEvent) {
+ inRecipeInventory = false
+ }
+
+ @SubscribeEvent
+ fun onRenderOverlay(event: GuiRenderEvent.ChestGuiOverlayRenderEvent) {
+ if (!isEnabled()) return
+ if (!inRecipeInventory && !purchasing) return
+
+ config.craftMaterialsFromBazaarPosition.renderRenderables(display, posLabel = "Craft Materials From Bazaar")
+ }
+
+ fun isEnabled() = LorenzUtils.inSkyBlock && config.craftMaterialsFromBazaar
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/PrimitiveItemStack.kt b/src/main/java/at/hannibal2/skyhanni/utils/PrimitiveItemStack.kt
index fd684950f..26338c839 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/PrimitiveItemStack.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/PrimitiveItemStack.kt
@@ -1,7 +1,9 @@
package at.hannibal2.skyhanni.utils
+import at.hannibal2.skyhanni.utils.ItemUtils.getInternalNameOrNull
import at.hannibal2.skyhanni.utils.ItemUtils.itemName
import at.hannibal2.skyhanni.utils.NEUItems.getItemStack
+import net.minecraft.item.ItemStack
data class PrimitiveItemStack(val internalName: NEUInternalName, val amount: Int) {
@@ -12,5 +14,6 @@ data class PrimitiveItemStack(val internalName: NEUInternalName, val amount: Int
companion object {
fun NEUInternalName.makePrimitiveStack(amount: Int) = PrimitiveItemStack(this, amount)
+ fun ItemStack.toPrimitiveStackOrNull() = getInternalNameOrNull()?.let { PrimitiveItemStack(it, stackSize) }
}
}