Skip to content

Commit

Permalink
Feature: Profit per corpse loot (#1734)
Browse files Browse the repository at this point in the history
Co-authored-by: CalMWolfs <94038482+CalMWolfs@users.noreply.github.com>
Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com>
  • Loading branch information
3 people authored May 8, 2024
1 parent 64ffd48 commit 2d98444
Show file tree
Hide file tree
Showing 11 changed files with 211 additions and 15 deletions.
4 changes: 4 additions & 0 deletions src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,8 @@ import at.hannibal2.skyhanni.features.mining.fossilexcavator.FossilExcavatorAPI
import at.hannibal2.skyhanni.features.mining.fossilexcavator.GlacitePowderFeatures
import at.hannibal2.skyhanni.features.mining.fossilexcavator.ProfitPerExcavation
import at.hannibal2.skyhanni.features.mining.fossilexcavator.solver.FossilSolverDisplay
import at.hannibal2.skyhanni.features.mining.mineshaft.CorpseAPI
import at.hannibal2.skyhanni.features.mining.mineshaft.MineshaftCorpseProfitPer
import at.hannibal2.skyhanni.features.mining.powdertracker.PowderTracker
import at.hannibal2.skyhanni.features.minion.InfernoMinionFeatures
import at.hannibal2.skyhanni.features.minion.MinionCollectLogic
Expand Down Expand Up @@ -746,6 +748,8 @@ class SkyHanniMod {
loadModule(ExcavatorProfitTracker())
loadModule(ProfitPerExcavation())
loadModule(GlacitePowderFeatures())
loadModule(MineshaftCorpseProfitPer())
loadModule(CorpseAPI())
loadModule(GardenOptimalSpeed())
loadModule(GardenLevelDisplay())
loadModule(FarmingWeightDisplay())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ public class FossilExcavatorConfig {

@Expose
@ConfigOption(
name = "Profit Per",
desc = "Show profit/loss in chat after each excavation. Also include breakdown information on hover."
name = "Profit Per Excavation",
desc = "Show profit/loss in chat after each excavation. Also includes breakdown information on hover."
)
@ConfigEditorBoolean
@FeatureToggle
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package at.hannibal2.skyhanni.config.features.mining;

import at.hannibal2.skyhanni.config.FeatureToggle;
import com.google.gson.annotations.Expose;
import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorBoolean;
import io.github.notenoughupdates.moulconfig.annotations.ConfigOption;

public class MineshaftConfig {

@Expose
@ConfigOption(
name = "Profit Per Corpse",
desc = "Show profit/loss in chat after each looted corpse in the Mineshaft. Also includes breakdown information on hover."
)
@ConfigEditorBoolean
@FeatureToggle
public boolean profitPerCorpseLoot = true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ public class MiningConfig {
@Accordion
public CommissionsBlocksColorConfig commissionsBlocksColor = new CommissionsBlocksColorConfig();

@Expose
@ConfigOption(name = "Mineshaft", desc = "")
@Accordion
public MineshaftConfig mineshaft = new MineshaftConfig();

@Expose
@ConfigOption(name = "Highlight Commission Mobs", desc = "Highlight Mobs that are part of active commissions.")
@ConfigEditorBoolean
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package at.hannibal2.skyhanni.events.mining

import at.hannibal2.skyhanni.events.LorenzEvent
import at.hannibal2.skyhanni.features.mining.mineshaft.CorpeType

class CorpseLootedEvent(val corpseType: CorpeType, val loot: List<Pair<String, Int>>) : LorenzEvent()
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ object FossilExcavatorAPI {
} ?: return
// Workaround: If it is a enchanted book, we assume it is a paleontologist I book
if (pair.first.let { it == "§fEnchanted" || it == "§fEnchanted Book" }) {
pair = "Paleontologist I" to pair.second
pair = "§9Paleontologist I" to pair.second
}
loot.add(pair)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class ProfitPerExcavation {
val pricePer = it.getPrice()
if (pricePer == -1.0) continue
val profit = amount * pricePer
val text = "Found $name §8${amount.addSeparators()}x §7(§6${NumberUtil.format(profit)}§7)"
val text = "§eFound $name §8${amount.addSeparators()}x §7(§6${NumberUtil.format(profit)}§7)"
map[text] = profit
totalProfit += profit
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package at.hannibal2.skyhanni.features.mining.mineshaft

import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName

enum class CorpeType(val displayName: String, private val keyName: String? = null) {
LAPIS("§9Lapis"),
TUNGSTEN("§7Tungsten", "TUNGSTEN_KEY"),
UMBER("§6Umber", "UMBER_KEY"),
VANGUARD("§fVanguard", "SKELETON_KEY"),
;

val key by lazy { keyName?.asInternalName() }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package at.hannibal2.skyhanni.features.mining.mineshaft

import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.mining.CorpseLootedEvent
import at.hannibal2.skyhanni.utils.ItemUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.StringUtils.matches
import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent

class CorpseAPI {

private val patternGroup = RepoPattern.group("mining.mineshaft")
private val chatPatternGroup = patternGroup.group("chat")

/**
* REGEX-TEST: §r§b§l§r§9§lLAPIS §r§b§lCORPSE LOOT!
* REGEX-TEST: §r§b§l§r§7§lTUNGSTEN §r§b§lCORPSE LOOT!
* REGEX-TEST: §r§b§l§r§6§lUMBER §r§b§lCORPSE LOOT!
* REGEX-TEST: §r§b§l§r§f§lVANGUARD §r§b§lCORPSE LOOT!
*/
private val startPattern by chatPatternGroup.pattern(
"start",
" {2}§r§b§l§r§(?<color>.)§l(?<name>.*) §r§b§lCORPSE LOOT! ?"
)

/**
* REGEX-TEST: §a§l▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
*/
private val endPattern by chatPatternGroup.pattern("end", "§a§l▬{64}")

/**
* REGEX-TEST: §r§9☠ Fine Onyx Gemstone §r§8x2
*/
private val itemPattern by chatPatternGroup.pattern("item", " {4}§r(?<item>.+)")

private var inLoot = false
private val loot = mutableListOf<Pair<String, Int>>()

private var corpeType: CorpeType? = null

@SubscribeEvent
fun onChat(event: LorenzChatEvent) {
if (!IslandType.MINESHAFT.isInIsland()) return

val message = event.message

startPattern.matchMatcher(message) {
inLoot = true
val name = group("name")
corpeType = CorpeType.valueOf(name)
return
}

if (!inLoot) return

if (endPattern.matches(message)) {
corpeType?.let {
CorpseLootedEvent(it, loot.toList()).postAndCatch()
}
corpeType = null
loot.clear()
inLoot = false
return
}
var pair = itemPattern.matchMatcher(message) {
/**
* TODO fix the bug that readItemAmount produces two different outputs:
* §r§fEnchanted Book -> §fEnchanted
* §fEnchanted Book §r§8x -> §fEnchanted Book
*
* also maybe this is no bug, as enchanted book is no real item?
*/
ItemUtils.readItemAmount(group("item"))
} ?: return
// Workaround: If it is a enchanted book, we assume it is a paleontologist I book
if (pair.first.let { it == "§fEnchanted" || it == "§fEnchanted Book" }) {
// pair = "Paleontologist I" to pair.second
pair = "§9Ice Cold I" to pair.second
}
loot.add(pair)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package at.hannibal2.skyhanni.features.mining.mineshaft

import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.mining.CorpseLootedEvent
import at.hannibal2.skyhanni.utils.ChatUtils
import at.hannibal2.skyhanni.utils.CollectionUtils.sortedDesc
import at.hannibal2.skyhanni.utils.ItemUtils.itemName
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 net.minecraftforge.fml.common.eventhandler.SubscribeEvent

class MineshaftCorpseProfitPer {
private val config get() = SkyHanniMod.feature.mining.mineshaft

@SubscribeEvent
fun onFossilExcavation(event: CorpseLootedEvent) {
if (!config.profitPerCorpseLoot) return
val loot = event.loot

var totalProfit = 0.0
val map = mutableMapOf<String, Double>()
for ((name, amount) in loot) {
if (name == "§bGlacite Powder") continue
NEUInternalName.fromItemNameOrNull(name)?.let {
val pricePer = it.getPrice()
if (pricePer == -1.0) continue
val profit = amount * pricePer
val text = "§eFound $name §8${amount.addSeparators()}x §7(§6${NumberUtil.format(profit)}§7)"
map[text] = profit
totalProfit += profit
}
}

val corpseType = event.corpseType
val name = corpseType.displayName

corpseType.key?.let {
val keyName = it.itemName
val price = it.getPrice()

map["$keyName: §c-${NumberUtil.format(price)}"] = -price
totalProfit -= price
}

val hover = map.sortedDesc().keys.toMutableList()
val profitPrefix = if (totalProfit < 0) "§c" else "§6"
val totalMessage = "Profit for $name Corpse§e: $profitPrefix${NumberUtil.format(totalProfit)}"
hover.add("")
hover.add("§e$totalMessage")
ChatUtils.hoverableChat(totalMessage, hover)
}
}
33 changes: 22 additions & 11 deletions src/main/java/at/hannibal2/skyhanni/test/command/TestChatCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,35 @@ object TestChatCommand {
val isComplex = mutArgs.remove("-complex")
val isClipboard = mutArgs.remove("-clipboard")
val isHidden = mutArgs.remove("-s")
val multiLines = mutArgs.remove("-lines")
val text = if (isClipboard) {
OSUtils.readFromClipboard()
?: return@launchCoroutine ChatUtils.userError("Clipboard does not contain a string!")
} else mutArgs.joinToString(" ")
val component =
if (isComplex)
try {
IChatComponent.Serializer.jsonToComponent(text)
} catch (ex: Exception) {
ChatUtils.userError("Please provide a valid JSON chat component (either in the command or via -clipboard)")
return@launchCoroutine
}
else ChatComponentText(text.replace("&", "§"))
if (!isHidden) ChatUtils.chat("Testing message: §7${component.formattedText}", prefixColor = "§a")
test(component)
if (multiLines) {
for (line in text.split("\n")) {
extracted(isComplex, line, isHidden)
}
} else {
extracted(isComplex, text, isHidden)
}
}
}

private fun extracted(isComplex: Boolean, text: String, isHidden: Boolean) {
val component =
if (isComplex)
try {
IChatComponent.Serializer.jsonToComponent(text)
} catch (ex: Exception) {
ChatUtils.userError("Please provide a valid JSON chat component (either in the command or via -clipboard)")
return
}
else ChatComponentText(text.replace("&", "§"))
if (!isHidden) ChatUtils.chat("Testing message: §7${component.formattedText}", prefixColor = "§a")
test(component)
}

private fun test(componentText: IChatComponent) {
val message = componentText.formattedText.stripHypixelMessage()
val event = LorenzChatEvent(message, componentText)
Expand Down

0 comments on commit 2d98444

Please sign in to comment.