aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/moe/nea/ledger/modules/DungeonChestDetection.kt
blob: c50e9eb5be002e086098716218af02531a337f76 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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
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

	@SubscribeEvent
	fun onKismetClick(event: GuiClickEvent) {
		val slot = event.slotIn ?: return
		if (!slot.inventory.displayName.unformattedText.unformattedString().endsWith(" Chest")) return
		val stack = slot.stack ?: return
		if (stack.getDisplayNameU() == "§aReroll Chest") {
			logger.logEntry(
				LedgerEntry(
					TransactionType.KISMET_REROLL,
					Instant.now(),
					listOf(
						ItemChange.lose(ItemId.KISMET_FEATHER, 1)
					)
				)
			)
		}
	}

	data class ChestCost(
		val diff: List<ItemChange>,
		val timestamp: Instant,
	)

	var lastOpenedChest = ExpiringValue.empty<ChestCost>()

	@SubscribeEvent
	fun supplyExtraIds(event: ExtraSupplyIdEvent) {
		event.store("Dungeon Chest Key", ItemId("DUNGEON_CHEST_KEY"))
		event.store("Kismet Feather", ItemId("KISMET_FEATHER"))
	}

	@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()
		))
	}

	val rewardMessage = " .* CHEST REWARDS".toPattern()

	@SubscribeEvent
	fun onChatMessage(event: ChatReceived) {
		if (event.message == "You don't have that many coins in the bank!") {
			lastOpenedChest.take()
		}
		rewardMessage.useMatcher(event.message) {
			val chest = lastOpenedChest.consume(3.seconds) ?: return
			logger.logEntry(LedgerEntry(
				TransactionType.DUNGEON_CHEST_OPEN,
				chest.timestamp,
				chest.diff,
			))
		}
	}
}