From 3acf36fbd07686431b8fbb5484f1f70b52651dc5 Mon Sep 17 00:00:00 2001 From: Linnea Gräf Date: Sat, 7 Dec 2024 23:10:13 +0100 Subject: Add kuudra chest detection --- .../moe/nea/ledger/modules/ChestDetection.kt | 48 +++++++++++++++++ .../nea/ledger/modules/DungeonChestDetection.kt | 63 +--------------------- .../moe/nea/ledger/modules/KuudraChestDetection.kt | 45 ++++++++++++++++ 3 files changed, 95 insertions(+), 61 deletions(-) create mode 100644 src/main/kotlin/moe/nea/ledger/modules/ChestDetection.kt create mode 100644 src/main/kotlin/moe/nea/ledger/modules/KuudraChestDetection.kt (limited to 'src/main/kotlin/moe/nea/ledger/modules') diff --git a/src/main/kotlin/moe/nea/ledger/modules/ChestDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/ChestDetection.kt new file mode 100644 index 0000000..48c040a --- /dev/null +++ b/src/main/kotlin/moe/nea/ledger/modules/ChestDetection.kt @@ -0,0 +1,48 @@ +package moe.nea.ledger.modules + +import moe.nea.ledger.ItemChange +import moe.nea.ledger.ItemId +import moe.nea.ledger.ItemIdProvider +import moe.nea.ledger.getDisplayNameU +import moe.nea.ledger.getInternalId +import moe.nea.ledger.getLore +import moe.nea.ledger.unformattedString +import moe.nea.ledger.utils.Inject +import net.minecraft.init.Blocks +import net.minecraft.inventory.Slot +import net.minecraft.item.Item +import java.time.Instant + +abstract class ChestDetection { + data class ChestCost( + val diff: List, + val timestamp: Instant, + ) + + @Inject + lateinit var itemIdProvider: ItemIdProvider + fun scrapeChestReward(rewardSlot: Slot): ChestCost? { + val inventory = rewardSlot.inventory + if (!inventory.displayName.unformattedText.unformattedString() + .endsWith(" Chest") + ) return null + val rewardStack = rewardSlot.stack ?: return null + val name = rewardStack.getDisplayNameU() + if (name != "§aOpen Reward Chest") return null + val lore = rewardStack.getLore() + val cost = itemIdProvider.findCostItemsFromSpan(lore) + val gain = (9..18) + .mapNotNull { inventory.getStackInSlot(it) } + .filter { it.item != Item.getItemFromBlock(Blocks.stained_glass_pane) } + .map { + it.getInternalId()?.withStackSize(it.stackSize) + ?: itemIdProvider.findStackableItemByName(it.displayName) + ?: ItemId.NIL.withStackSize(it.stackSize) + } + return ChestCost( + cost.map { ItemChange.lose(it.first, it.second) } + gain.map { ItemChange.gain(it.first, it.second) }, + Instant.now() + ) + } + +} \ No newline at end of file diff --git a/src/main/kotlin/moe/nea/ledger/modules/DungeonChestDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/DungeonChestDetection.kt index c50e9eb..4be5228 100644 --- a/src/main/kotlin/moe/nea/ledger/modules/DungeonChestDetection.kt +++ b/src/main/kotlin/moe/nea/ledger/modules/DungeonChestDetection.kt @@ -3,7 +3,6 @@ package moe.nea.ledger.modules import moe.nea.ledger.ExpiringValue import moe.nea.ledger.ItemChange import moe.nea.ledger.ItemId -import moe.nea.ledger.ItemIdProvider import moe.nea.ledger.LedgerEntry import moe.nea.ledger.LedgerLogger import moe.nea.ledger.TransactionType @@ -11,49 +10,14 @@ import moe.nea.ledger.events.ChatReceived import moe.nea.ledger.events.ExtraSupplyIdEvent import moe.nea.ledger.events.GuiClickEvent import moe.nea.ledger.getDisplayNameU -import moe.nea.ledger.getInternalId -import moe.nea.ledger.getLore import moe.nea.ledger.unformattedString import moe.nea.ledger.useMatcher import moe.nea.ledger.utils.Inject -import net.minecraft.init.Blocks -import net.minecraft.item.Item import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import java.time.Instant import kotlin.time.Duration.Companion.seconds -class DungeonChestDetection @Inject constructor(val logger: LedgerLogger) { - - /*{ - id: "minecraft:chest", - Count: 1b, - tag: { - display: { - Lore: ["§7Purchase this chest to receive the", "§7rewards above. You can only open", "§7one chest per Dungeons run -", "§7choose wisely!", "", "§7Cost", "§625,000 Coins", "§9Dungeon Chest Key", "", "§7§cNOTE: Coins are withdrawn from your", "§cbank if you don't have enough in", "§cyour purse."], - Name: "§aOpen Reward Chest" - } - }, - Damage: 0s - } - - { - id: "minecraft:feather", - Count: 1b, - tag: { - overrideMeta: 1b, - ench: [], - HideFlags: 254, - display: { - Lore: ["§7Consume a §9Kismet Feather §7to reroll", "§7the loot within this chest.", "", "§7You may only use a feather once", "§7per dungeon run.", "", "§eClick to reroll this chest!"], - Name: "§aReroll Chest" - }, - AttributeModifiers: [] - }, - Damage: 0s -} - */ - @Inject - lateinit var itemIdProvider: ItemIdProvider +class DungeonChestDetection @Inject constructor(val logger: LedgerLogger) : ChestDetection() { @SubscribeEvent fun onKismetClick(event: GuiClickEvent) { @@ -73,10 +37,6 @@ class DungeonChestDetection @Inject constructor(val logger: LedgerLogger) { } } - data class ChestCost( - val diff: List, - val timestamp: Instant, - ) var lastOpenedChest = ExpiringValue.empty() @@ -88,26 +48,7 @@ class DungeonChestDetection @Inject constructor(val logger: LedgerLogger) { @SubscribeEvent fun onRewardChestClick(event: GuiClickEvent) { - val slot = event.slotIn ?: return - if (!slot.inventory.displayName.unformattedText.unformattedString().endsWith(" Chest")) return - val stack = slot.stack ?: return - val name = stack.getDisplayNameU() - if (name != "§aOpen Reward Chest") return - val lore = stack.getLore() - val cost = itemIdProvider.findCostItemsFromSpan(lore) - val gain = (9..18) - .mapNotNull { slot.inventory.getStackInSlot(it) } - .filter { it.item != Item.getItemFromBlock(Blocks.stained_glass_pane) } - .map { - it.getInternalId()?.singleItem() - ?: itemIdProvider.findStackableItemByName(it.displayName) - ?: Pair(ItemId.NIL, it.stackSize.toDouble()) - } - lastOpenedChest = ExpiringValue(ChestCost( - cost.map { ItemChange.lose(it.first, it.second) } - + gain.map { ItemChange.gain(it.first, it.second) }, - Instant.now() - )) + lastOpenedChest = ExpiringValue(scrapeChestReward(event.slotIn ?: return) ?: return) } val rewardMessage = " .* CHEST REWARDS".toPattern() diff --git a/src/main/kotlin/moe/nea/ledger/modules/KuudraChestDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/KuudraChestDetection.kt new file mode 100644 index 0000000..bc072ba --- /dev/null +++ b/src/main/kotlin/moe/nea/ledger/modules/KuudraChestDetection.kt @@ -0,0 +1,45 @@ +package moe.nea.ledger.modules + +import moe.nea.ledger.ItemChange +import moe.nea.ledger.ItemId +import moe.nea.ledger.LedgerEntry +import moe.nea.ledger.LedgerLogger +import moe.nea.ledger.TransactionType +import moe.nea.ledger.events.GuiClickEvent +import moe.nea.ledger.getInternalId +import moe.nea.ledger.utils.Inject +import net.minecraft.client.Minecraft +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class KuudraChestDetection : ChestDetection() { + // TODO: extra essence for kuudra pet (how?), item SALVAGE detection + // TODO: save uuid along side item id + + val kuudraKeyPattern = "KUUDRA_.*_TIER_KEY".toPattern() + + @Inject + lateinit var log: LedgerLogger + + @Inject + lateinit var minecraft: Minecraft + fun hasKey(keyItem: ItemId): Boolean { + val p = minecraft.thePlayer ?: return false + return p.inventory.mainInventory.any { it.getInternalId() == keyItem } + } + + @SubscribeEvent + fun onRewardChestClick(event: GuiClickEvent) { + val diffs = scrapeChestReward(event.slotIn ?: return) ?: return + val requiredKey = diffs.diff.find { + it.direction == ItemChange.ChangeDirection.LOST && kuudraKeyPattern.asPredicate().test(it.itemId.string) + }?.itemId + if (requiredKey != null && !hasKey(requiredKey)) { + return + } + log.logEntry(LedgerEntry( + TransactionType.KUUDRA_CHEST_OPEN, + diffs.timestamp, + diffs.diff, + )) + } +} \ No newline at end of file -- cgit