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

Feature: Excavation Profit Tracker #1432

Merged
merged 24 commits into from
Apr 13, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
8 changes: 6 additions & 2 deletions src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,9 @@ import at.hannibal2.skyhanni.features.mining.crystalhollows.CrystalHollowsNamesI
import at.hannibal2.skyhanni.features.mining.crystalhollows.CrystalHollowsWalls
import at.hannibal2.skyhanni.features.mining.eventtracker.MiningEventDisplay
import at.hannibal2.skyhanni.features.mining.eventtracker.MiningEventTracker
import at.hannibal2.skyhanni.features.mining.fossilexcavator.FossilExcavator
import at.hannibal2.skyhanni.features.mining.fossilexcavator.ExcavatorProfitTracker
import at.hannibal2.skyhanni.features.mining.fossilexcavator.FossilExcavatorAPI
import at.hannibal2.skyhanni.features.mining.fossilexcavator.solver.FossilSolverDisplay
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 @@ -536,6 +538,7 @@ class SkyHanniMod {
loadModule(LorenzUtils)
loadModule(NEUItems)
loadModule(PestAPI)
loadModule(FossilExcavatorAPI)

// features
loadModule(BazaarOrderHelper())
Expand Down Expand Up @@ -659,7 +662,8 @@ class SkyHanniMod {
loadModule(GardenCropMilestoneDisplay)
loadModule(GardenCustomKeybinds)
loadModule(ChickenHeadTimer())
loadModule(FossilExcavator)
loadModule(FossilSolverDisplay)
loadModule(ExcavatorProfitTracker())
loadModule(GardenOptimalSpeed())
loadModule(GardenLevelDisplay())
loadModule(FarmingWeightDisplay())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package at.hannibal2.skyhanni.config.features.mining;

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

public class ExcavatorProfitTrackerConfig {

@Expose
@ConfigOption(
name = "Enabled",
desc = "Count all drops you gain while excavating fossils in the Glacial Cave."
hannibal002 marked this conversation as resolved.
Show resolved Hide resolved
)
@ConfigEditorBoolean
@FeatureToggle
public boolean enabled = true;

@Expose
@ConfigOption(
name = "Show nearby",
desc = "Show the profit tracker while close to the excavation point."
)
@ConfigEditorBoolean
public boolean showNearvy = true;

@Expose
@ConfigLink(owner = ExcavatorProfitTrackerConfig.class, field = "enabled")
public Position position = new Position(20, 20, false, true);
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,19 @@
package at.hannibal2.skyhanni.config.features.mining;

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

public class FossilExcavatorConfig {

@Expose
@ConfigOption(name = "Fossil Excavator Helper", desc = "Helps you find fossils in the fossil excavator. " +
"§eWill always solve if you have at least 18 clicks. Solves everything except Spine, Ugly and Helix in 16 clicks.")
@ConfigEditorBoolean
@FeatureToggle
public boolean enabled = true;
@ConfigOption(name = "Fossil Excavator Solver", desc = "")
@Accordion
public FossilExcavatorSolverConfig solver = new FossilExcavatorSolverConfig();

@Expose
@ConfigOption(name = "Show Percentage", desc = "Shows percentage chance that next click will be a fossil. " +
"§eThis assumes there is a fossil hidden in the dirt.")
@ConfigEditorBoolean
public boolean showPercentage = true;

@Expose
@ConfigLink(owner = FossilExcavatorConfig.class, field = "enabled")
public Position position = new Position(183, 212, false, true);
@ConfigOption(name = "Excavator Profit Tracker", desc = "")
@Accordion
public ExcavatorProfitTrackerConfig profitTracker = new ExcavatorProfitTrackerConfig();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package at.hannibal2.skyhanni.config.features.mining;

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

public class FossilExcavatorSolverConfig {

@Expose
@ConfigOption(name = "Fossil Excavator Helper", desc = "Helps you find fossils in the fossil excavator. " +
"§eWill always solve if you have at least 18 clicks. Solves everything except Spine, Ugly and Helix in 16 clicks.")
@ConfigEditorBoolean
@FeatureToggle
public boolean enabled = true;

@Expose
@ConfigOption(name = "Show Percentage", desc = "Shows percentage chance that next click will be a fossil. " +
"§eThis assumes there is a fossil hidden in the dirt.")
@ConfigEditorBoolean
public boolean showPercentage = true;

@Expose
@ConfigLink(owner = FossilExcavatorSolverConfig.class, field = "enabled")
public Position position = new Position(-380, 150, false, true);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@
import at.hannibal2.skyhanni.features.garden.farming.DicerRngDropTracker;
import at.hannibal2.skyhanni.features.garden.farming.lane.FarmingLane;
import at.hannibal2.skyhanni.features.garden.fortuneguide.FarmingItems;
import at.hannibal2.skyhanni.features.garden.pests.VinylType;
import at.hannibal2.skyhanni.features.garden.pests.PestProfitTracker;
import at.hannibal2.skyhanni.features.garden.pests.VinylType;
import at.hannibal2.skyhanni.features.garden.visitor.VisitorReward;
import at.hannibal2.skyhanni.features.mining.fossilexcavator.ExcavatorProfitTracker;
import at.hannibal2.skyhanni.features.mining.powdertracker.PowderTracker;
import at.hannibal2.skyhanni.features.misc.trevor.TrevorTracker;
import at.hannibal2.skyhanni.features.rift.area.westvillage.VerminTracker;
Expand Down Expand Up @@ -384,6 +385,9 @@ public static class MiningConfig {

@Expose
public List<String> kingsTalkedTo = new ArrayList<>();

@Expose
public ExcavatorProfitTracker.Data fossilExcavatorProfitTracker = new ExcavatorProfitTracker.Data();
}

@Expose
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package at.hannibal2.skyhanni.events.mining

import at.hannibal2.skyhanni.events.LorenzEvent

class FossilExcavationEvent(val loot: List<Pair<String, Int>>): LorenzEvent()
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package at.hannibal2.skyhanni.features.mining.fossilexcavator

import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.IslandChangeEvent
import at.hannibal2.skyhanni.events.mining.FossilExcavationEvent
import at.hannibal2.skyhanni.utils.CollectionUtils.addAsSingletonList
import at.hannibal2.skyhanni.utils.ItemUtils.itemName
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland
import at.hannibal2.skyhanni.utils.NEUInternalName
import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
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.Companion.makePrimitiveStack
import at.hannibal2.skyhanni.utils.renderables.Renderable
import at.hannibal2.skyhanni.utils.tracker.ItemTrackerData
import at.hannibal2.skyhanni.utils.tracker.SkyHanniItemTracker
import com.google.gson.annotations.Expose
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent

class ExcavatorProfitTracker {

private val config get() = SkyHanniMod.feature.mining.fossilExcavator.profitTracker

private val tracker = SkyHanniItemTracker(
"Fossil Excavation Profit Tracker",
{ Data() },
{ it.mining.fossilExcavatorProfitTracker }) { drawDisplay(it) }

class Data : ItemTrackerData() {
override fun resetItems() {
timesExcavated = 0
}

override fun getDescription(timesGained: Long): List<String> {
val percentage = timesGained.toDouble() / timesExcavated
val dropRate = LorenzUtils.formatPercentage(percentage.coerceAtMost(1.0))
return listOf(
"§7Dropped §e${timesGained.addSeparators()} §7times.",
"§7Your drop rate: §c$dropRate."
)
}

override fun getCoinName(item: TrackedItem) = "<no coins>"

override fun getCoinDescription(item: TrackedItem): List<String> {
return listOf(
"<no coins>"
)
}

@Expose
var timesExcavated = 0L
}

private val scrapItem = "SUSPICIOUS_SCRAP".asInternalName()

private fun drawDisplay(data: Data): List<List<Any>> = buildList {
addAsSingletonList("§e§lFossil Excavation Profit Tracker")
var profit = tracker.drawItems(data, { true }, this)

val timesExcavated = data.timesExcavated
addAsSingletonList(
Renderable.hoverTips(
"§7Times excavated: §e${timesExcavated.addSeparators()}",
listOf("§7You excavated §e${timesExcavated.addSeparators()} §7times.")
)
)

// TODO use same price source as profit tracker
val scrapPrice = timesExcavated * scrapItem.getPrice()
profit -= scrapPrice
addAsSingletonList(
Renderable.hoverTips(
"${scrapItem.itemName}§7: §c${NumberUtil.format(scrapPrice)}",
hannibal002 marked this conversation as resolved.
Show resolved Hide resolved
listOf(
"§7You paid ${NumberUtil.format(scrapPrice)} coins",
"§7in total for all §e$timesExcavated §7${scrapItem.itemName}",
"§7you have used."
)
)
)

addAsSingletonList(tracker.addTotalProfit(profit, data.timesExcavated, "excarvation"))

tracker.addPriceFromButton(this)
}

@SubscribeEvent
fun onFossilExcavation(event: FossilExcavationEvent) {
if (!isEnabled()) return
for ((name, amount) in event.loot) {
println("")
println("name: '$name'")
println("amount: $amount")
val internalName = NEUInternalName.fromItemNameOrNull(name) ?: continue
val itemStack = internalName.makePrimitiveStack(amount)
println("itemStack: '$itemStack'")
tracker.addItem(internalName, amount)
}
tracker.modify {
it.timesExcavated++
}
}

@SubscribeEvent
fun onRenderOverlay(event: GuiRenderEvent) {
if (!isEnabled()) return
if (LorenzUtils.skyBlockArea != "Fossil Research Center") return
// hide during an active excavation
if (FossilExcavatorAPI.inInventory && !FossilExcavatorAPI.inExcavatorMenu) {
return
}

tracker.renderDisplay(config.position)
}

@SubscribeEvent
fun onIslandChange(event: IslandChangeEvent) {
if (event.newIsland == IslandType.DWARVEN_MINES) {
tracker.firstUpdate()
}
}

fun isEnabled() = IslandType.DWARVEN_MINES.isInIsland() && config.enabled
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package at.hannibal2.skyhanni.features.mining.fossilexcavator

import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.events.InventoryCloseEvent
import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
import at.hannibal2.skyhanni.events.InventoryUpdatedEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
import at.hannibal2.skyhanni.events.mining.FossilExcavationEvent
import at.hannibal2.skyhanni.utils.InventoryUtils
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.StringUtils.removeColor
import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent

object FossilExcavatorAPI {

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

/**
* REGEX-TEST: §r§6§lEXCAVATION COMPLETE
*/
private val startPattern by chatPatternGroup.pattern("start", " {2}§r§6§lEXCAVATION COMPLETE ")

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

/**
* REGEX-TEST: §r§6Tusk Fossil
*/
private val itemPattern by chatPatternGroup.pattern("item", " {4}§r(?<item>.+)")

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

var inInventory = false
var inExcavatorMenu = false

@SubscribeEvent
fun onInventoryOpen(event: InventoryFullyOpenedEvent) {
if (!IslandType.DWARVEN_MINES.isInIsland()) return
if (event.inventoryName != "Fossil Excavator") return
inInventory = true
}

@SubscribeEvent
fun onInventoryUpdated(event: InventoryUpdatedEvent) {
if (!inInventory) return
val slots = InventoryUtils.getItemsInOpenChest()
val itemNames = slots.map { it.stack.displayName.removeColor() }
inExcavatorMenu = itemNames.any { it == "Start Excavator" }
}

@SubscribeEvent
fun onWorldChange(event: LorenzWorldChangeEvent) {
inInventory = false
inExcavatorMenu = false
}

@SubscribeEvent
fun onInventoryClose(event: InventoryCloseEvent) {
inInventory = false
inExcavatorMenu = false
}

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

val message = event.message

if (startPattern.matches(message)) {
inLoot = true
return
}

if (!inLoot) return

if (endPattern.matches(message)) {
FossilExcavationEvent(loot.toList()).postAndCatch()
loot.clear()
inLoot = false
return
}

val pair = itemPattern.matchMatcher(message) {
val itemLine = group("item")
// TODO fix readItemAmount bug
if (itemLine.contains("§bGlacite Powder")) return
ItemUtils.readItemAmount(itemLine) ?: return
} ?: return
loot.add(pair)
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package at.hannibal2.skyhanni.features.mining.fossilexcavator
package at.hannibal2.skyhanni.features.mining.fossilexcavator.solver

enum class FossilMutation(val modification: (FossilShape) -> FossilShape) {
ROTATE_0({ positions -> positions.rotate(0) }),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package at.hannibal2.skyhanni.features.mining.fossilexcavator
package at.hannibal2.skyhanni.features.mining.fossilexcavator.solver

data class FossilShape(val tiles: List<FossilTile>) {
fun width() = tiles.maxOf { it.x } - tiles.minOf { it.x }
Expand Down
Loading
Loading