Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvement: Profit per Anita Medal #3122

Merged
merged 4 commits into from
Dec 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
import at.hannibal2.skyhanni.features.garden.visitor.VisitorAPI
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
import at.hannibal2.skyhanni.test.command.ErrorManager
import at.hannibal2.skyhanni.utils.CollectionUtils.add
import at.hannibal2.skyhanni.utils.DisplayTableEntry
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemCategory
Expand All @@ -20,7 +21,6 @@ import at.hannibal2.skyhanni.utils.ItemUtils.itemName
import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.NEUInternalName
import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.toInternalName
import at.hannibal2.skyhanni.utils.NumberUtil.shortFormat
import at.hannibal2.skyhanni.utils.RenderUtils.renderRenderables
import at.hannibal2.skyhanni.utils.renderables.Renderable
Expand Down Expand Up @@ -71,20 +71,21 @@ object AnitaMedalProfit {
}

val newList = mutableListOf<Renderable>()
newList.add(Renderable.string("§eMedal Profit"))
newList.add(Renderable.string("§eProfit per Bronze Medal"))
newList.add(LorenzUtils.fillTable(table, padding = 5, itemScale = 0.7))
display = newList
}

private fun readItem(slot: Int, item: ItemStack, table: MutableList<DisplayTableEntry>) {
val itemName = getItemName(item)
if (itemName == " ") return
if (itemName == "§cClose") return
if (itemName == "§eUnique Gold Medals") return
if (itemName == "§aMedal Trades") return
if (isInvalidItemName(itemName)) return

val fullCost = getFullCost(getRequiredItems(item))
if (fullCost < 0) return
val requiredItems = getRequiredItems(item)
val additionalMaterials = getAdditionalMaterials(requiredItems)
val additionalCost = getAdditionalCost(additionalMaterials)

// Ignore items without medal cost, e.g. InfiniDirt Wand
val bronzeCost = getBronzeCost(requiredItems) ?: return

val (name, amount) = ItemUtils.readItemAmount(itemName) ?: return

Expand All @@ -96,30 +97,58 @@ object AnitaMedalProfit {
val itemPrice = internalName.getPrice() * amount
if (itemPrice < 0) return

val profit = itemPrice - fullCost
val profitFormat = profit.shortFormat()
val color = if (profit > 0) "§6" else "§c"
val profitPerSell = itemPrice - additionalCost

// profit per bronze
val profitPerBronze = profitPerSell / bronzeCost

val profitPerSellFormat = profitPerSell.shortFormat()
val profitPerBronzeFormat = profitPerBronze.shortFormat()
val color = if (profitPerBronze > 0) "§6" else "§c"

val hover = buildList {
add(itemName)
add("")
add("§7Sell price: §6${itemPrice.shortFormat()}")

val hover = listOf(
itemName,
"",
"§7Item price: §6${itemPrice.shortFormat()} ",
// TODO add more exact material cost breakdown
"§7Material cost: §6${fullCost.shortFormat()} ",
"§7Final profit: §6$profitFormat ",
)
add("§7Additional cost: §6${additionalCost.shortFormat()}")
addAdditionalMaterials(additionalMaterials)

add("§7Profit per sell: §6$profitPerSellFormat")
add("")
add("§7Bronze medals required: §c$bronzeCost")
add("§7Profit per bronze medal: §6$profitPerBronzeFormat")
}
table.add(
DisplayTableEntry(
itemName,
"$color$profitFormat",
profit,
"$color$profitPerBronzeFormat",
profitPerBronze,
internalName,
hover,
highlightsOnHoverSlots = listOf(slot),
),
)
}

private fun MutableList<String>.addAdditionalMaterials(additionalMaterials: Map<NEUInternalName, Int>) {
for ((internalName, amount) in additionalMaterials) {
val pricePer = internalName.getPrice() * amount
add(" " + internalName.itemName + " §8${amount}x §7(§6${pricePer.shortFormat()}§7)")
}
}

private fun isInvalidItemName(itemName: String): Boolean = when (itemName) {
" ",
"§cClose",
"§eUnique Gold Medals",
"§aMedal Trades",
-> true

else -> false
}

private fun getItemName(item: ItemStack): String {
val name = item.name
val isEnchantedBook = item.getItemCategoryOrNull() == ItemCategory.ENCHANTED_BOOK
Expand All @@ -128,35 +157,39 @@ object AnitaMedalProfit {
} else name
}

private fun getFullCost(requiredItems: MutableList<String>): Double {
val jacobTicketPrice = "JACOBS_TICKET".toInternalName().getPrice()
var otherItemsPrice = 0.0
for (rawItemName in requiredItems) {
val pair = ItemUtils.readItemAmount(rawItemName)
if (pair == null) {
ErrorManager.logErrorStateWithData(
"Error in Anita Medal Contest", "Could not read item amount",
"rawItemName" to rawItemName,
)
continue
}

val (name, amount) = pair
private fun getAdditionalMaterials(requiredItems: Map<String, Int>): Map<NEUInternalName, Int> {
val additionalMaterials = mutableMapOf<NEUInternalName, Int>()
for ((name, amount) in requiredItems) {
val medal = getMedal(name)
otherItemsPrice += if (medal != null) {
val bronze = medal.factorBronze * amount
bronze * jacobTicketPrice
} else {
NEUInternalName.fromItemName(name).getPrice() * amount
if (medal == null) {
additionalMaterials[NEUInternalName.fromItemName(name)] = amount
}
}
return additionalMaterials
}

private fun getAdditionalCost(requiredItems: Map<NEUInternalName, Int>): Double {
var otherItemsPrice = 0.0
for ((name, amount) in requiredItems) {
otherItemsPrice += name.getPrice() * amount
}
return otherItemsPrice
}

private fun getRequiredItems(item: ItemStack): MutableList<String> {
val items = mutableListOf<String>()
private fun getBronzeCost(requiredItems: Map<String, Int>): Int? {
for ((name, amount) in requiredItems) {
getMedal(name)?.let {
return it.factorBronze * amount
}
}
return null
}

private fun getRequiredItems(item: ItemStack): MutableMap<String, Int> {
val items = mutableMapOf<String, Int>()
var next = false
for (line in item.getLore()) {
val lore = item.getLore()
for (line in lore) {
if (line == "§7Cost") {
next = true
continue
Expand All @@ -167,7 +200,19 @@ object AnitaMedalProfit {
continue
}

items.add(line.replace("§8 ", " §8"))
val rawItemName = line.replace("§8 ", " §8")

val pair = ItemUtils.readItemAmount(rawItemName)
if (pair == null) {
ErrorManager.logErrorStateWithData(
"Error in Anita Medal Contest", "Could not read item amount",
"rawItemName" to rawItemName,
"name" to item.name,
"lore" to lore,
)
continue
}
items.add(pair)
}
}
return items
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -489,4 +489,8 @@ object CollectionUtils {
fun <E> MutableList<E>.addOrInsert(index: Int, element: E) {
if (index < size) add(index, element) else add(element)
}

fun <K, V> MutableMap<K, V>.add(pair: Pair<K, V>) {
this[pair.first] = pair.second
}
}
Loading