diff options
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/features')
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/PunchcardHighlight.kt | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/PunchcardHighlight.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/PunchcardHighlight.kt new file mode 100644 index 000000000..10be4a54a --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/PunchcardHighlight.kt @@ -0,0 +1,253 @@ +package at.hannibal2.skyhanni.features.rift.everywhere + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.data.HypixelData +import at.hannibal2.skyhanni.data.IslandType +import at.hannibal2.skyhanni.data.mob.MobData +import at.hannibal2.skyhanni.events.ConfigLoadEvent +import at.hannibal2.skyhanni.events.EntityClickEvent +import at.hannibal2.skyhanni.events.GuiRenderEvent +import at.hannibal2.skyhanni.events.IslandChangeEvent +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.MobEvent +import at.hannibal2.skyhanni.features.rift.RiftAPI +import at.hannibal2.skyhanni.mixins.hooks.RenderLivingEntityHelper +import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule +import at.hannibal2.skyhanni.test.command.ErrorManager +import at.hannibal2.skyhanni.utils.ChatUtils +import at.hannibal2.skyhanni.utils.ColorUtils.toChromaColor +import at.hannibal2.skyhanni.utils.ColorUtils.withAlpha +import at.hannibal2.skyhanni.utils.ConditionalUtils +import at.hannibal2.skyhanni.utils.DelayedRun +import at.hannibal2.skyhanni.utils.EntityUtils.isNPC +import at.hannibal2.skyhanni.utils.InventoryUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland +import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName +import at.hannibal2.skyhanni.utils.NEUItems.getItemStack +import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher +import at.hannibal2.skyhanni.utils.RegexUtils.matches +import at.hannibal2.skyhanni.utils.RenderUtils.renderRenderable +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import at.hannibal2.skyhanni.utils.renderables.Renderable +import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern +import net.minecraft.client.entity.AbstractClientPlayer +import net.minecraft.entity.EntityLivingBase +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.seconds + +@SkyHanniModule +object PunchcardHighlight { + private val config get() = SkyHanniMod.feature.rift.punchcard + private var lastRiftServer: String = "" + + private var listening = false + + private val patternGroup = RepoPattern.group("rift.punchcard") + + /** + * REGEX-TEST: §5§lPUNCHCARD! §r§eYou punched §r§b[MVP§r§c+§r§b] ThorQOM§r§f §r§eand both regained §r§a+25ф Rift Time§r§e! + * REGEX-TEST: §5§lPUNCHCARD! §r§eYou punched §r§7Metafighter§r§7 §r§eand both regained §r§a+25ф Rift Time§r§e! + * REGEX-TEST: §5§lPUNCHCARD! §r§eYou punched §r§a[VIP] RickyLafleur22§r§f §r§eand both regained §r§a+25ф Rift Time§r§e! + */ + private val punchedPattern by patternGroup.pattern( + "new", + "§5§lPUNCHCARD! §r§eYou punched §r§.(?:.*?)?(?<name>\\w+)§r§. §r§eand both regained §r§a\\+25ф Rift Time§r§e!", + ) + + /** + * REGEX-TEST: §c§lAWKWARD! §r§cThis player has already been punched by you... somehow! + */ + private val repeatPattern by patternGroup.pattern( + "repeat", + "§c§lAWKWARD! §r§cThis player has already been punched by you\\.\\.\\. somehow!", + ) + + /** + * REGEX-TEST: §c§lUH OH! §r§cYou reached the limit of 20 players you can punch in one session! + */ + private val limitPattern by patternGroup.pattern( + "limit", + "§c§lUH OH! §r§cYou reached the limit of 20 players you can punch in one session!", + ) + + private val playerList: MutableSet<String> = mutableSetOf() + private var playerQueue = mutableListOf<String>() + + private val displayIcon by lazy { "PUNCHCARD_ARTIFACT".asInternalName().getItemStack() } + private var display: Renderable = Renderable.string("hello") + + @SubscribeEvent + fun onPlayerSpawn(event: MobEvent.Spawn.Player) { + if (!config.highlight.get()) return + if (!IslandType.THE_RIFT.isInIsland()) return + if (config.reverse.get()) return + val size = playerList.size + if (size >= 20) return + val entity = event.mob + if (!playerList.contains(entity.name)) { + colorPlayer(entity.baseEntity) + } + } + + @SubscribeEvent + fun onToggle(event: ConfigLoadEvent) { + ConditionalUtils.onToggle( + config.highlight, + config.color, + config.reverse, + ) { + reloadColors() + } + ConditionalUtils.onToggle( + config.gui, + config.compact, + config.reverseGUI, + ) { + display = drawDisplay() + } + ConditionalUtils.onToggle( + config.highlight, + config.color, + ) { + checkPunchcard() + } + } + + private var warningCooldown = SimpleTimeMark.farPast() + + private fun checkPunchcard() { + if (!RiftAPI.inRift()) return + + val hasPunchcard = InventoryUtils.isItemInInventory("PUNCHCARD_ARTIFACT".asInternalName()) + if (!hasPunchcard && warningCooldown.passedSince() > 30.seconds) { + warningCooldown = SimpleTimeMark.now() + ChatUtils.chat("You don't seem to own a Punchcard Artifact, this feature will not work without one.") + } + } + + @SubscribeEvent + fun onWorldSwitch(event: IslandChangeEvent) { + DelayedRun.runDelayed(1500.milliseconds) { + if (playerList.isEmpty()) return@runDelayed + if (event.newIsland != IslandType.THE_RIFT) return@runDelayed + + if (HypixelData.server.isNotEmpty() && lastRiftServer != HypixelData.server) { + reloadColors() + lastRiftServer = HypixelData.server + playerList.clear() + } + display = drawDisplay() + } + } + + private fun colorPlayer(entity: EntityLivingBase) { + val color = config.color.get().toChromaColor() + val alpha = when (color.alpha) { + 0 -> 0 + 255 -> 1 + else -> 255 - color.alpha + } + RenderLivingEntityHelper.setEntityColor(entity, color.withAlpha(alpha)) { IslandType.THE_RIFT.isInIsland() } + } + + private fun removePlayerColor(entity: EntityLivingBase) { + RenderLivingEntityHelper.removeEntityColor(entity) + } + + fun clearList() { + playerList.clear() + playerQueue.clear() + if (config.reverse.get()) { + MobData.players.forEach { + colorPlayer(it.baseEntity) + } + } else { + MobData.players.forEach { + removePlayerColor(it.baseEntity) + } + } + } + + @SubscribeEvent + fun onPunch(event: EntityClickEvent) { + if (!RiftAPI.inRift()) return + val entity = event.clickedEntity + if (entity !is AbstractClientPlayer) return + if (entity.isNPC()) return + val name = entity.name + if (name in playerList || name in playerQueue) return + playerQueue.add(name) + listening = true + DelayedRun.runDelayed(1.seconds) { + if (name in playerQueue) playerQueue.remove(name) + listening = false + } + } + + @SubscribeEvent + fun onChat(event: LorenzChatEvent) { + if (!IslandType.THE_RIFT.isInIsland()) return + if (!listening) return + if (playerQueue.isEmpty()) return + val message = event.message + val queuedName = playerQueue[0] + punchedPattern.matchMatcher(message) { + val name = group("name") + if (queuedName == name) { + addPunch(name) + } else ErrorManager.logErrorStateWithData( + "Error finding punched player", "queuedName and capturedName were different", + "queuedName" to queuedName, + "capturedName" to name, + noStackTrace = true, + betaOnly = true, + ) + return + } + if (limitPattern.matches(message) || repeatPattern.matches(message)) addPunch(queuedName) + } + + private fun addPunch(playerName: String) { + playerList.add(playerName) + playerQueue.remove(playerName) + val player = MobData.players.firstOrNull { it.name == playerName } ?: return + if (!config.reverse.get()) removePlayerColor(player.baseEntity) + else colorPlayer(player.baseEntity) + display = drawDisplay() + } + + @SubscribeEvent + fun onRenderUI(event: GuiRenderEvent.GuiOverlayRenderEvent) { + if (!config.gui.get()) return + if (!RiftAPI.inRift()) return + + config.position.renderRenderable(display, "Punchcard Overlay") + } + + private fun drawDisplay(): Renderable { + var string = "" + if (!config.compact.get()) string += "Punchcard Artifact: " + string += "§d" + if (!config.reverseGUI.get()) playerList.size + else 20 - playerList.size + + return Renderable.horizontalContainer( + listOf( + Renderable.itemStack(displayIcon), + Renderable.string(string), + ), + spacing = 1, + ) + } + + private fun reloadColors() { + MobData.players.forEach { + removePlayerColor(it.baseEntity) + } + if (!config.highlight.get()) return + val reverse = config.reverse.get() + for (player in MobData.players.filter { (reverse && it.name in playerList) || (!reverse && it.name !in playerList) }) { + colorPlayer(player.baseEntity) + } + } +} |