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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
package at.hannibal2.skyhanni.features.garden
import at.hannibal2.skyhanni.data.GardenCropMilestones
import at.hannibal2.skyhanni.data.GardenCropMilestones.getCounter
import at.hannibal2.skyhanni.data.GardenCropMilestones.setCounter
import at.hannibal2.skyhanni.data.ProfileStorageData
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.TabListUpdateEvent
import at.hannibal2.skyhanni.features.garden.farming.GardenCropMilestoneDisplay
import at.hannibal2.skyhanni.features.garden.pests.PestAPI
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
import at.hannibal2.skyhanni.utils.ChatUtils
import at.hannibal2.skyhanni.utils.ItemUtils.itemNameWithoutColor
import at.hannibal2.skyhanni.utils.NEUInternalName
import at.hannibal2.skyhanni.utils.NEUItems
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary
import at.hannibal2.skyhanni.utils.RegexUtils.matchFirst
import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher
import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
@SkyHanniModule
object GardenCropMilestoneFix {
private val patternGroup = RepoPattern.group("garden.cropmilestone.fix")
/**
* REGEX-TEST: Cocoa Beans 31: §r§a68%
* REGEX-TEST: Potato 32: §r§a97.7%
*/
private val tabListPattern by patternGroup.pattern(
"tablist",
" (?<crop>Wheat|Carrot|Potato|Pumpkin|Sugar Cane|Melon|Cactus|Cocoa Beans|Mushroom|Nether Wart) (?<tier>\\d+): §r§a(?<percentage>.*)%"
)
private val levelUpPattern by patternGroup.pattern(
"levelup",
" {2}§r§b§lGARDEN MILESTONE §3(?<crop>.*) §8.*➜§3(?<tier>.*)"
)
/**
* REGEX-TEST: §6§lRARE DROP! §9Mutant Nether Wart §6(§6+1,344☘)
*/
private val pestRareDropPattern by patternGroup.pattern(
"pests.raredrop",
"§6§lRARE DROP! (?:§.)*(?<item>.+) §6\\(§6\\+.*☘\\)"
)
private val tabListCropProgress = mutableMapOf<CropType, Long>()
@SubscribeEvent
fun onChat(event: LorenzChatEvent) {
levelUpPattern.matchMatcher(event.message) {
val cropName = group("crop")
val crop = CropType.getByNameOrNull(cropName) ?: return
val tier = group("tier").romanToDecimalIfNecessary()
val crops = GardenCropMilestones.getCropsForTier(tier, crop)
changedValue(crop, crops, "level up chat message", 0)
}
PestAPI.pestDeathChatPattern.matchMatcher(event.message) {
val amount = group("amount").toInt()
val item = NEUInternalName.fromItemNameOrNull(group("item")) ?: return
val primitiveStack = NEUItems.getPrimitiveMultiplier(item)
val rawName = primitiveStack.internalName.itemNameWithoutColor
val cropType = CropType.getByNameOrNull(rawName) ?: return
cropType.setCounter(
cropType.getCounter() + (amount * primitiveStack.amount)
)
GardenCropMilestoneDisplay.update()
}
pestRareDropPattern.matchMatcher(event.message) {
val item = NEUInternalName.fromItemNameOrNull(group("item")) ?: return
val primitiveStack = NEUItems.getPrimitiveMultiplier(item)
val rawName = primitiveStack.internalName.itemNameWithoutColor
val cropType = CropType.getByNameOrNull(rawName) ?: return
cropType.setCounter(
cropType.getCounter() + primitiveStack.amount
)
GardenCropMilestoneDisplay.update()
}
}
@SubscribeEvent
fun onTabListUpdate(event: TabListUpdateEvent) {
event.tabList.matchFirst(tabListPattern) {
val tier = group("tier").toInt()
val percentage = group("percentage").toDouble()
val cropName = group("crop")
check(cropName, tier, percentage)
}
}
private fun check(cropName: String, tier: Int, percentage: Double) {
if (!ProfileStorageData.loaded) return
val crop = CropType.getByNameOrNull(cropName)
if (crop == null) {
ChatUtils.debug("GardenCropMilestoneFix: crop is null: '$cropName'")
return
}
val baseCrops = GardenCropMilestones.getCropsForTier(tier, crop)
val next = GardenCropMilestones.getCropsForTier(tier + 1, crop)
val progressCrops = next - baseCrops
val progress = progressCrops * (percentage / 100)
val smallestPercentage = progressCrops * 0.0005
val tabListValue = baseCrops + progress - smallestPercentage
val newValue = tabListValue.toLong()
if (tabListCropProgress[crop] != newValue && tabListCropProgress.containsKey(crop)) {
changedValue(crop, newValue, "tab list", smallestPercentage.toInt())
}
tabListCropProgress[crop] = newValue
}
private val loadedCrops = mutableListOf<CropType>()
private fun changedValue(crop: CropType, tabListValue: Long, source: String, minDiff: Int) {
val calculated = crop.getCounter()
val diff = calculated - tabListValue
if (diff <= -minDiff) {
crop.setCounter(tabListValue)
GardenCropMilestoneDisplay.update()
if (!loadedCrops.contains(crop)) {
ChatUtils.chat("Loaded ${crop.cropName} milestone data from $source!")
loadedCrops.add(crop)
}
} else if (diff >= minDiff) {
ChatUtils.debug("Fixed wrong ${crop.cropName} milestone data from $source: ${diff.addSeparators()}")
crop.setCounter(tabListValue)
GardenCropMilestoneDisplay.update()
}
}
}
|