aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/moe/nea/ledger/modules/DungeonChestDetection.kt
blob: 559817404c2da3fe84fc7606f5a4f7bcb418c401 (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
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.SHORT_NUMBER_PATTERN
import moe.nea.ledger.TransactionType
import moe.nea.ledger.events.ChatReceived
import moe.nea.ledger.events.GuiClickEvent
import moe.nea.ledger.getDisplayNameU
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.Inject
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import net.minecraftforge.fml.common.gameevent.TickEvent
import java.time.Instant
import java.util.regex.Pattern

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
}
	*/
	val costPattern = Pattern.compile("(?<cost>$SHORT_NUMBER_PATTERN) Coins")


	data class ChestCost(
		val cost: Double,
		val openTimestamp: Long,
		val hasKey: Boolean,
	)

	var lastOpenedChest: ChestCost? = null

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

	@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 costIndex = lore.indexOf("§7Cost")
		if (costIndex < 0 || costIndex + 1 !in lore.indices) return
		val cost = costPattern.useMatcher(lore[costIndex + 1].unformattedString()) {
			parseShortNumber(group("cost"))
		} ?: 0.0 // Free chest!
		val hasKey = lore.contains("§9Dungeon Chest Key")
		lastOpenedChest?.let(::completeTransaction)
		lastOpenedChest = ChestCost(cost, System.currentTimeMillis(), hasKey)
	}

	@SubscribeEvent
	fun onChatMessage(event: ChatReceived) {
		if (event.message == "You don't have that many coins in the bank!")
			lastOpenedChest = null
	}

	fun completeTransaction(toOpen: ChestCost) {
		lastOpenedChest = null
		logger.logEntry(
			LedgerEntry(
				TransactionType.DUNGEON_CHEST_OPEN,
				Instant.ofEpochMilli(toOpen.openTimestamp),
				listOfNotNull(
					if (toOpen.hasKey) ItemChange.lose(ItemId.DUNGEON_CHEST_KEY, 1) else null,
					ItemChange.loseCoins(toOpen.cost)
				),
			)
		)
	}

	@SubscribeEvent
	fun onTick(event: TickEvent) {
		val toOpen = lastOpenedChest
		if (toOpen != null && toOpen.openTimestamp + 1000L < System.currentTimeMillis()) {
			completeTransaction(toOpen)
		}
	}
}