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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
|
package at.hannibal2.skyhanni.features.event.carnival
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.data.Perk
import at.hannibal2.skyhanni.data.ProfileStorageData
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.ProfileJoinEvent
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.RegexUtils.matches
import at.hannibal2.skyhanni.utils.RenderUtils.renderRenderables
import at.hannibal2.skyhanni.utils.SkyBlockTime
import at.hannibal2.skyhanni.utils.renderables.Renderable
import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern
import net.minecraft.init.Blocks
import net.minecraft.init.Items
import net.minecraft.item.Item
import net.minecraft.item.ItemStack
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import org.intellij.lang.annotations.Language
private val repoGroup = RepoPattern.group("carnvial.goals")
enum class CarnivalGoal(
private val type: GoalType,
@Language("RegEXP") loreLine: String,
@Language("RegEXP") chatLine: String,
val display: String,
) {
FRUIT_DIGGING_PLAY(
GoalType.FRUIT_DIGGING,
"§7Play §a3 games §7of §6Fruit Digging§7.",
"(§8 - §r)?§7Play §r§a3 games §r§7of §r§6Fruit Digging§r§7.",
"Play §a3 games",
),
FRUIT_DIGGING_SCORE(
GoalType.FRUIT_DIGGING,
"§7Reach §a3,000 score §7in a single game",
"(§8 - §r)?§7Reach §r§a3,000 score §r§7in a single game of §r§6Fruit Digging§r§7.",
"Reach §a3,000 score",
),
DIG_APPLE(
GoalType.FRUIT_DIGGING,
"§7Dig up §a3 Apples §7in a single game of",
"(§8 - §r)?§7Dig up §r§a3 Apples §r§7in a single game of §r§6Fruit Digging§r§7.",
"Dig up §a3 Apples",
),
UNIQUE_FRUIT(
GoalType.FRUIT_DIGGING,
"§7Dig up §a5 unique Fruits §7in a single",
"(§8 - §r)?§7Dig up §r§a5 unique Fruits §r§7in a single game of §r§6Fruit Digging§r§7.",
"Dig up §a5 unique Fruits",
),
DRAGONFRUIT(
GoalType.FRUIT_DIGGING,
"§7Dig up a §dDragonfruit§7.",
"(§8 - §r)?§7Dig up a §r§dDragonfruit§r§7.",
"Dig up a §dDragonfruit",
),
CATCH_A_FISH_PLAY(
GoalType.CATCH_A_FISH,
"§7Play §a3 games §7of §3Catch a Fish§7.",
"(§8 - §r)?§7Play §r§a3 games §r§7of §r§3Catch a Fish§r§7.",
"Play §a3 games",
),
CATCH_A_FISH_SCORE(
GoalType.CATCH_A_FISH,
"§7Reach §a3,000 score §7in a single game",
"(§8 - §r)?§7Reach §r§a3,000 score §r§7in a single game of §r§3Catch a Fish§r§7.",
"Reach §a3,000 score",
),
CATCH_FISH(
GoalType.CATCH_A_FISH,
"§7Catch §a30 Fish §7in a single game of",
"(§8 - §r)?§7Catch §r§a30 Fish §r§7in a single game of §r§3Catch a Fish§r§7.",
"Catch §a30 Fish",
),
CATCH_YELLOW_FISH(
GoalType.CATCH_A_FISH,
"§7Catch §a5 Yellow Fish §7in a single game",
"(§8 - §r)?§7Catch §r§a5 Yellow Fish §r§7in a single game of §r§3Catch a Fish§r§7.",
"Catch §a5 Yellow Fish",
),
CATCH_STREAK(
GoalType.CATCH_A_FISH,
"§7Reach a §a5 Catch Streak §7in a single",
"(§8 - §r)?§7Reach a §r§a5 Catch Streak §r§7in a single game of §r§3Catch a Fish§r§7.",
"Reach a §a5 Catch Streak",
),
ZOMBIE_SHOOTOUT_PLAY(
GoalType.ZOMBIE_SHOOTOUT,
"§7Play §a3 games §7of §cZombie Shootout§7.",
"(§8 - §r)?§7Play §r§a3 games §r§7of §r§cZombie Shootout§r§7.",
"Play §a3 games",
),
ZOMBIE_SHOOTOUT_SCORE(
GoalType.ZOMBIE_SHOOTOUT,
"§7Reach §a3,000 score §7in a single game",
"(§8 - §r)?§7Reach §r§a3,000 score §r§7in a single game of §r§cZombie Shootout§r§7.",
"Reach §a3,000 score",
),
SHOOT_ZOMBIE(
GoalType.ZOMBIE_SHOOTOUT,
"§7Shoot §a60 Zombies §7in a single game of",
"(§8 - §r)?§7Shoot §r§a60 Zombies §r§7in a single game of §r§cZombie Shootout§r§7.",
"Shoot §a60 Zombies",
),
SHOOT_DIAMOND_ZOMBIE(
GoalType.ZOMBIE_SHOOTOUT,
"§7Shoot §a5 Diamond Zombies §7in a single",
"(§8 - §r)?§7Shoot §r§a5 Diamond Zombies §r§7in a single game of §r§cZombie Shootout§r§7.",
"Shoot §a5 Diamond Zombies",
),
SHOOT_LAMPS(
GoalType.ZOMBIE_SHOOTOUT,
"§7Shoot §a5 Redstone Lamps §7in a single",
"(§8 - §r)?§7Shoot §r§a5 Redstone Lamps §r§7in a single game of §r§cZombie Shootout§r§7.",
"Shoot §a5 Redstone Lamps",
),
;
private val patternKeyName = name.lowercase().replace("_", ".")
private val lorePattern by repoGroup.pattern("lore.$patternKeyName", loreLine)
private val chatPattern by repoGroup.pattern("chat.$patternKeyName", chatLine)
private var isReached: Boolean
get() {
val year = SkyBlockTime.now().year
if (year != storage?.carnivalYear) {
storage?.goals?.clear()
storage?.carnivalYear = year
}
return storage?.goals?.get(this) ?: false
}
set(value) {
val year = SkyBlockTime.now().year
if (year != storage?.carnivalYear) {
storage?.goals?.clear()
storage?.carnivalYear = year
}
storage?.goals?.set(this, value)
dirty = true
}
@SkyHanniModule
companion object {
init {
entries.forEach {
it.chatPattern
it.lorePattern
}
}
private val config get() = SkyHanniMod.feature.event.carnival
private val storage get() = ProfileStorageData.profileSpecific?.carnival
private val inventoryPattern by repoGroup.pattern("inventory", "Carnival Goals")
private val completePattern by repoGroup.pattern("complete", "§a§lCOMPLETE")
private var dirty = true
private fun getEntry(item: Item, lore: List<String>): CarnivalGoal? =
entries.filter { it.type.item == item }.firstOrNull { it.lorePattern.matches(lore.firstOrNull()) }
@SubscribeEvent
fun onProfileJoin(event: ProfileJoinEvent) {
dirty = true
}
@SubscribeEvent
fun onInventoryFullyOpened(event: InventoryFullyOpenedEvent) {
if (!isEnabled()) return
if (!inventoryPattern.matches(event.inventoryName)) return
for (stack in event.inventoryItems.values) {
val lore = stack.getLore()
val goal = getEntry(stack.item, lore) ?: continue
val lastLine = lore.last()
goal.isReached = completePattern.matches(lastLine)
}
}
@SubscribeEvent
fun onLorenzChat(event: LorenzChatEvent) {
if (!isEnabled()) return
entries.firstOrNull { it.chatPattern.matches(event.message) }?.isReached = true
}
private var display = emptyList<Renderable>()
@SubscribeEvent
fun onGuiRenderGuiOverlayRender(event: GuiRenderEvent.GuiOverlayRenderEvent) {
if (!isEnabled()) return
if (dirty) {
display = buildList {
GoalType.entries.map { it.fullDisplay }.forEach { list -> addAll(list) }
}
dirty = false
}
config.goalsPosition.renderRenderables(display, posLabel = "Carnival Goals")
}
fun isEnabled() =
LorenzUtils.inSkyBlock && config.showGoals && Perk.CHIVALROUS_CARNIVAL.isActive && LorenzUtils.skyBlockArea == "Carnival"
private enum class GoalType(val item: Item, display: String) {
FRUIT_DIGGING(Item.getItemFromBlock(Blocks.sand), "§6Fruit Digging"),
CATCH_A_FISH(Items.fish, "§3Catch a Fish"),
ZOMBIE_SHOOTOUT(Items.arrow, "§cZombie Shootout");
val singleDisplay by lazy {
Renderable.horizontalContainer(
listOf(
Renderable.itemStack(ItemStack(item)),
Renderable.string(display),
),
)
}
val fullDisplay: List<Renderable>
get() {
val goals = getGoals.filterNot { it.isReached }
if (goals.isEmpty()) return emptyList()
return listOf(singleDisplay) + goals.map { Renderable.string(" " + it.display) }
}
val getGoals get() = CarnivalGoal.entries.filter { it.type == this }
}
}
}
|