aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2024-12-19 22:13:32 +0100
committerLinnea Gräf <nea@nea.moe>2024-12-19 22:13:32 +0100
commit175379be77dd530bc019e34d3937950df22e4f8a (patch)
tree26667fda120efefa857655583f622f170856bd38
parent7c4b2e089fa23622799bc06a08f6932197365368 (diff)
downloadLocalTransactionLedger-175379be77dd530bc019e34d3937950df22e4f8a.tar.gz
LocalTransactionLedger-175379be77dd530bc019e34d3937950df22e4f8a.tar.bz2
LocalTransactionLedger-175379be77dd530bc019e34d3937950df22e4f8a.zip
feat: Items bought for other items at NPCs
-rw-r--r--src/main/kotlin/moe/nea/ledger/ItemChange.kt1
-rw-r--r--src/main/kotlin/moe/nea/ledger/ItemIdProvider.kt16
-rw-r--r--src/main/kotlin/moe/nea/ledger/ItemUtil.kt22
-rw-r--r--src/main/kotlin/moe/nea/ledger/modules/NpcDetection.kt46
4 files changed, 79 insertions, 6 deletions
diff --git a/src/main/kotlin/moe/nea/ledger/ItemChange.kt b/src/main/kotlin/moe/nea/ledger/ItemChange.kt
index 186a4e3..fda709c 100644
--- a/src/main/kotlin/moe/nea/ledger/ItemChange.kt
+++ b/src/main/kotlin/moe/nea/ledger/ItemChange.kt
@@ -59,6 +59,7 @@ data class ItemChange(
}
fun unpairGain(pair: Pair<ItemId, Double>) = unpair(ChangeDirection.GAINED, pair)
+ fun unpairLose(pair: Pair<ItemId, Double>) = unpair(ChangeDirection.LOST, pair)
fun gain(itemId: ItemId, amount: Number): ItemChange {
return ItemChange(itemId, amount.toDouble(), ChangeDirection.GAINED)
diff --git a/src/main/kotlin/moe/nea/ledger/ItemIdProvider.kt b/src/main/kotlin/moe/nea/ledger/ItemIdProvider.kt
index 30610e9..72f1d09 100644
--- a/src/main/kotlin/moe/nea/ledger/ItemIdProvider.kt
+++ b/src/main/kotlin/moe/nea/ledger/ItemIdProvider.kt
@@ -29,16 +29,24 @@ class ItemIdProvider {
private val knownNames = mutableMapOf<String, ItemId>()
+ fun createLookupTagFromDisplayName(itemName: String): String {
+ return itemName.unformattedString().trim().lowercase()
+ }
+
+ fun saveKnownItem(itemName: String, itemId: ItemId) {
+ knownNames[createLookupTagFromDisplayName(itemName)] = itemId
+ }
+
@SubscribeEvent
fun onDataLoaded(event: ExternalDataProvider.DataLoaded) {
event.provider.itemNames.forEach { (itemId, itemName) ->
- knownNames[itemName.unformattedString().trim()] = ItemId(itemId)
+ saveKnownItem(itemName, ItemId(itemId))
}
}
@SubscribeEvent
fun onRegistrationFinished(event: RegistrationFinishedEvent) {
- MinecraftForge.EVENT_BUS.post(ExtraSupplyIdEvent(knownNames::put))
+ MinecraftForge.EVENT_BUS.post(ExtraSupplyIdEvent(::saveKnownItem))
}
@SubscribeEvent(priority = EventPriority.HIGH)
@@ -63,7 +71,7 @@ class ItemIdProvider {
name = name.trim()
val id = stack.getInternalId()
if (id != null && name.isNotBlank()) {
- knownNames[name] = id
+ saveKnownItem(name, id)
}
}
@@ -84,7 +92,7 @@ class ItemIdProvider {
// TODO: make use of colour
fun findForName(name: String, fallbackToGenerated: Boolean = true): ItemId? {
- var id = knownNames[name]
+ var id = knownNames[createLookupTagFromDisplayName(name)]
if (id == null && fallbackToGenerated) {
id = generateName(name)
}
diff --git a/src/main/kotlin/moe/nea/ledger/ItemUtil.kt b/src/main/kotlin/moe/nea/ledger/ItemUtil.kt
index 949f58a..a3d8162 100644
--- a/src/main/kotlin/moe/nea/ledger/ItemUtil.kt
+++ b/src/main/kotlin/moe/nea/ledger/ItemUtil.kt
@@ -1,5 +1,6 @@
package moe.nea.ledger
+import net.minecraft.inventory.IInventory
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
@@ -37,7 +38,10 @@ class PetInfo {
fun ItemStack.getPetId(): String? {
val petInfoStr = getExtraAttributes().getString("petInfo")
- val petInfo = runCatching { Ledger.gson.fromJson(petInfoStr, PetInfo::class.java) }.getOrNull() // TODO: error reporting to sentry
+ val petInfo = runCatching {
+ Ledger.gson.fromJson(petInfoStr,
+ PetInfo::class.java)
+ }.getOrNull() // TODO: error reporting to sentry
if (petInfo?.type == null || petInfo.tier == null) return null
return petInfo.type + ";" + rarityToIndex(petInfo.tier ?: "")
}
@@ -62,6 +66,22 @@ fun ItemStack.getLore(): List<String> {
}
+fun IInventory.asIterable(): Iterable<ItemStack?> = object : Iterable<ItemStack?> {
+ override fun iterator(): Iterator<ItemStack?> {
+ return object : Iterator<ItemStack?> {
+ var i = 0
+ override fun hasNext(): Boolean {
+ return i < this@asIterable.sizeInventory
+ }
+
+ override fun next(): ItemStack? {
+ if (!hasNext()) throw NoSuchElementException("$i is out of range for inventory ${this@asIterable}")
+ return this@asIterable.getStackInSlot(i++)
+ }
+ }
+ }
+}
+
fun ItemStack.getDisplayNameU(): String {
val nbt = this.tagCompound ?: NBTTagCompound()
val extraAttributes = nbt.getCompoundTag("display")
diff --git a/src/main/kotlin/moe/nea/ledger/modules/NpcDetection.kt b/src/main/kotlin/moe/nea/ledger/modules/NpcDetection.kt
index 5906562..c17cdc8 100644
--- a/src/main/kotlin/moe/nea/ledger/modules/NpcDetection.kt
+++ b/src/main/kotlin/moe/nea/ledger/modules/NpcDetection.kt
@@ -7,9 +7,16 @@ import moe.nea.ledger.LedgerEntry
import moe.nea.ledger.LedgerLogger
import moe.nea.ledger.SHORT_NUMBER_PATTERN
import moe.nea.ledger.TransactionType
+import moe.nea.ledger.asIterable
+import moe.nea.ledger.events.BeforeGuiAction
import moe.nea.ledger.events.ChatReceived
+import moe.nea.ledger.getDisplayNameU
+import moe.nea.ledger.getInternalId
+import moe.nea.ledger.getLore
import moe.nea.ledger.parseShortNumber
+import moe.nea.ledger.unformattedString
import moe.nea.ledger.useMatcher
+import moe.nea.ledger.utils.ErrorUtil
import moe.nea.ledger.utils.di.Inject
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import java.util.regex.Pattern
@@ -21,7 +28,44 @@ class NpcDetection @Inject constructor(val ledger: LedgerLogger, val ids: ItemId
val npcSellPattern =
Pattern.compile("You sold (?<what>.*) (x(?<count>$SHORT_NUMBER_PATTERN) )?for (?<coins>$SHORT_NUMBER_PATTERN) Coins?!")
- // TODO: IMPROVE BUYING FROM NPC TO INCLUDE ITEMS OTHER THAN COINS (KUUDRA KEYS ARE CHEAP)
+ // You bought InfiniDirt™ Wand!
+ // You bought Prismapump x4!
+ val npcBuyWithItemPattern =
+ "You bought (?<what>.*?)!".toPattern()
+ var storedPurchases = mutableMapOf<String, List<ItemChange>>()
+
+ @SubscribeEvent
+ fun onClick(event: BeforeGuiAction) {
+ (event.chestSlots?.lowerChestInventory?.asIterable() ?: listOf())
+ .filterNotNull().forEach {
+ val name = it.getDisplayNameU().unformattedString()
+ val id = it.getInternalId() ?: return@forEach
+ val count = it.stackSize
+ val cost = ids.findCostItemsFromSpan(it.getLore())
+ storedPurchases[name] = listOf(ItemChange.gain(id, count)) + cost.map { ItemChange.unpairLose(it) }
+ }
+ }
+
+ @Inject
+ lateinit var errorUtil: ErrorUtil
+
+ @SubscribeEvent
+ fun onBarteredItemBought(event: ChatReceived) {
+ npcBuyWithItemPattern.useMatcher(event.message) {
+ val changes = storedPurchases[group("what")]
+ if (changes == null) {
+ errorUtil.reportAdHoc("Item bought for items without associated cost")
+ }
+ storedPurchases.clear()
+ ledger.logEntry(
+ LedgerEntry(
+ TransactionType.NPC_BUY,
+ event.timestamp,
+ changes ?: listOf()
+ )
+ )
+ }
+ }
@SubscribeEvent
fun onNpcBuy(event: ChatReceived) {