diff options
Diffstat (limited to 'src/main/java/at/hannibal2')
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) } } } |