aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/utils/ItemPriceUtils.kt
blob: b12f3640e07f6e550c3fc3c66bc57510d78a2f43 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package at.hannibal2.skyhanni.utils

import at.hannibal2.skyhanni.features.inventory.bazaar.BazaarApi.getBazaarData
import at.hannibal2.skyhanni.features.inventory.bazaar.BazaarDataHolder
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.ItemUtils.getRecipePrice
import at.hannibal2.skyhanni.utils.ItemUtils.itemName
import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
import at.hannibal2.skyhanni.utils.NEUItems.getItemStackOrNull
import at.hannibal2.skyhanni.utils.NEUItems.getRecipes
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import io.github.moulberry.notenoughupdates.recipes.NeuRecipe

object ItemPriceUtils {

    fun NEUInternalName.getPrice(
        priceSource: ItemPriceSource = ItemPriceSource.BAZAAR_INSTANT_BUY,
        pastRecipes: List<NeuRecipe> = emptyList(),
    ) = getPriceOrNull(priceSource, pastRecipes) ?: 0.0

    fun NEUInternalName.getPriceOrNull(
        priceSource: ItemPriceSource = ItemPriceSource.BAZAAR_INSTANT_BUY,
        pastRecipes: List<NeuRecipe> = emptyList(),
    ): Double? {
        when (this) {
            NEUInternalName.JASPER_CRYSTAL -> return 0.0
            NEUInternalName.RUBY_CRYSTAL -> return 0.0
            NEUInternalName.SKYBLOCK_COIN -> return 1.0
            NEUInternalName.WISP_POTION -> return 20_000.0
        }

        if (priceSource != ItemPriceSource.NPC_SELL) {
            getBazaarData()?.let {
                return if (priceSource == ItemPriceSource.BAZAAR_INSTANT_BUY) it.sellOfferPrice else it.instantBuyPrice
            }

            getLowestBinOrNull()?.let {
                return it
            }

            if (equals("JACK_O_LANTERN")) {
                return "PUMPKIN".asInternalName().getPrice(priceSource) + 1
            }
        }
        if (equals("GOLDEN_CARROT")) {
            // 6.8 for some players
            return 7.0 // NPC price
        }

        return getNpcPriceOrNull() ?: getRawCraftCostOrNull(priceSource, pastRecipes)
    }

    private fun NEUInternalName.getLowestBinOrNull(): Double? {
        val result = NEUItems.manager.auctionManager.getLowestBin(asString())
        if (result == -1L) return null
        return result.toDouble()
    }

    // We can not use NEU craft cost, since we want to respect the price source choice
    // NEUItems.manager.auctionManager.getCraftCost(asString())?.craftCost
    fun NEUInternalName.getRawCraftCostOrNull(
        priceSource: ItemPriceSource = ItemPriceSource.BAZAAR_INSTANT_BUY,
        pastRecipes: List<NeuRecipe> = emptyList(),
    ): Double? = getRecipes(this).filter { it !in pastRecipes }
        .map { it.getRecipePrice(priceSource, pastRecipes + it) }
        .filter { it >= 0 }
        .minOrNull()

    fun NEUInternalName.getNpcPrice(): Double = getNpcPriceOrNull() ?: 0.0

    fun NEUInternalName.getNpcPriceOrNull(): Double? {
        if (this == NEUInternalName.WISP_POTION) {
            return 20_000.0
        }
        return BazaarDataHolder.getNpcPrice(this)
    }

    fun debugItemPrice(args: Array<String>) {
        val internalName = getItemOrFromHand(args)
        if (internalName == null) {
            ChatUtils.userError("Hold an item in hand or do /shdebugprice <item name/id>")
            return
        }


        val defaultPrice = internalName.getPrice().addSeparators()
        ChatUtils.chat("${internalName.itemName}§f: §6$defaultPrice")

        println("")
        println(" Debug Item Price for $internalName ")
        println("defaultPrice: $defaultPrice")

        println(" #")
        for (source in ItemPriceSource.values()) {
            val price = internalName.getPrice(source)
            println("${source.displayName} price: ${price.addSeparators()}")
        }
        println(" #")

        println(" ")
        println("getLowestBinOrNull: ${internalName.getLowestBinOrNull()?.addSeparators()}")

        internalName.getBazaarData().let {
            println("getBazaarData sellOfferPrice: ${it?.sellOfferPrice?.addSeparators()}")
            println("getBazaarData instantBuyPrice: ${it?.instantBuyPrice?.addSeparators()}")
        }

        println("getNpcPriceOrNull: ${internalName.getNpcPriceOrNull()?.addSeparators()}")
        println("getRawCraftCostOrNull: ${internalName.getRawCraftCostOrNull()?.addSeparators()}")
        println(" ")
    }

    // TODO move either into inventory utils or new command utils
    fun getItemOrFromHand(args: Array<String>): NEUInternalName? {
        val name = args.joinToString(" ")
        return if (name.isEmpty()) {
            InventoryUtils.getItemInHand()?.getInternalName()
        } else {
            val internalName = name.asInternalName()
            if (internalName.getItemStackOrNull() != null) {
                internalName
            } else {
                NEUInternalName.fromItemNameOrNull(name)
            }

        }
    }
}