aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/features/fishing
diff options
context:
space:
mode:
authorJ10a1n15 <45315647+j10a1n15@users.noreply.github.com>2024-03-23 19:14:25 +0100
committerGitHub <noreply@github.com>2024-03-23 19:14:25 +0100
commit44014aa68a8c672c779f38202a215ab1e8dcd8c5 (patch)
tree08296df55bca53055497bb26253f24b1d7423c18 /src/main/java/at/hannibal2/skyhanni/features/fishing
parent54aba6cbdd46da9f4c9d064382c0f487d06e3c0b (diff)
downloadskyhanni-44014aa68a8c672c779f38202a215ab1e8dcd8c5.tar.gz
skyhanni-44014aa68a8c672c779f38202a215ab1e8dcd8c5.tar.bz2
skyhanni-44014aa68a8c672c779f38202a215ab1e8dcd8c5.zip
Feature: Totem Of Corruption Overlay & Effective Area (#1139)
Co-authored-by: hannibal2 <24389977+hannibal002@users.noreply.github.com>
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/features/fishing')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/fishing/TotemOfCorruption.kt143
1 files changed, 143 insertions, 0 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/TotemOfCorruption.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/TotemOfCorruption.kt
new file mode 100644
index 000000000..2deb676af
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/TotemOfCorruption.kt
@@ -0,0 +1,143 @@
+package at.hannibal2.skyhanni.features.fishing
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.events.GuiRenderEvent
+import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
+import at.hannibal2.skyhanni.events.LorenzTickEvent
+import at.hannibal2.skyhanni.events.ReceiveParticleEvent
+import at.hannibal2.skyhanni.utils.ColorUtils.toChromaColor
+import at.hannibal2.skyhanni.utils.EntityUtils
+import at.hannibal2.skyhanni.utils.LocationUtils.distanceToPlayer
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.LorenzUtils.sendTitle
+import at.hannibal2.skyhanni.utils.LorenzVec
+import at.hannibal2.skyhanni.utils.RenderUtils.drawSphereInWorld
+import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings
+import at.hannibal2.skyhanni.utils.SoundUtils.playPlingSound
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
+import at.hannibal2.skyhanni.utils.StringUtils.matches
+import at.hannibal2.skyhanni.utils.TimeUnit
+import at.hannibal2.skyhanni.utils.TimeUtils.format
+import at.hannibal2.skyhanni.utils.getLorenzVec
+import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern
+import net.minecraft.entity.item.EntityArmorStand
+import net.minecraft.util.EnumParticleTypes
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.seconds
+
+class TotemOfCorruption {
+
+ private val config get() = SkyHanniMod.feature.fishing.totemOfCorruption
+
+ private var display = emptyList<String>()
+ private var totems: List<Totem> = emptyList()
+
+ private val group = RepoPattern.group("fishing.totemofcorruption")
+ private val totemNamePattern by group.pattern(
+ "totemname",
+ "§5§lTotem of Corruption"
+ )
+ private val timeRemainingPattern by group.pattern(
+ "timeremaining",
+ "§7Remaining: §e(?:(?<min>\\d+)m )?(?<sec>\\d+)s"
+ )
+ private val ownerPattern by group.pattern(
+ "owner",
+ "§7Owner: §e(?<owner>.+)"
+ )
+
+ @SubscribeEvent
+ fun onRender(event: GuiRenderEvent.GuiOverlayRenderEvent) {
+ if (!isOverlayEnabled() || display.isEmpty()) return
+ config.position.renderStrings(display, posLabel = "Totem of Corruption")
+ }
+
+ @SubscribeEvent
+ fun onTick(event: LorenzTickEvent) {
+ if (!event.repeatSeconds(2)) return
+ if (!isOverlayEnabled()) return
+
+ totems = getTotems()
+ display = createDisplay()
+ }
+
+ @SubscribeEvent
+ fun onChatPacket(event: ReceiveParticleEvent) {
+ if (!isHideParticlesEnabled()) return
+
+ for (totem in totems) {
+ if (event.type == EnumParticleTypes.SPELL_WITCH && event.speed == 0.0f) {
+ if (totem.location.distance(event.location) < 4.0) {
+ event.isCanceled = true
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ fun onRenderWorld(event: LorenzRenderWorldEvent) {
+ if (!isEffectiveAreaEnabled()) return
+
+ val color = config.color.toChromaColor()
+ for (totem in totems) {
+ // The center of the totem is the upper part
+ event.drawSphereInWorld(color, totem.location.add(y = 1), 16f)
+ }
+ }
+
+ private fun getTimeRemaining(totem: EntityArmorStand): Duration? =
+ EntityUtils.getEntitiesNearby<EntityArmorStand>(totem.getLorenzVec(), 2.0)
+ .firstNotNullOfOrNull { entity ->
+ timeRemainingPattern.matchMatcher(entity.name) {
+ val minutes = group("min")?.toIntOrNull() ?: 0
+ val seconds = group("sec")?.toInt() ?: 0
+ (minutes * 60 + seconds).seconds
+ }
+ }
+
+ private fun getOwner(totem: EntityArmorStand): String? =
+ EntityUtils.getEntitiesNearby<EntityArmorStand>(totem.getLorenzVec(), 2.0)
+ .firstNotNullOfOrNull { entity ->
+ ownerPattern.matchMatcher(entity.name) {
+ group("owner")
+ }
+ }
+
+
+ private fun createDisplay() = buildList {
+ val totem = getTotemToShow() ?: return@buildList
+ add("§5§lTotem of Corruption")
+ add("§7Remaining: §e${totem.timeRemaining.format(TimeUnit.MINUTE)}")
+ add("§7Owner: §e${totem.ownerName}")
+ }
+
+ private fun getTotemToShow(): Totem? = totems
+ .filter { it.distance < config.distanceThreshold }
+ .maxByOrNull { it.timeRemaining }
+
+ private fun getTotems(): List<Totem> = EntityUtils.getEntitiesNextToPlayer<EntityArmorStand>(100.0)
+ .filter { totemNamePattern.matches(it.name) }.toList()
+ .mapNotNull { totem ->
+ val timeRemaining = getTimeRemaining(totem) ?: return@mapNotNull null
+ val owner = getOwner(totem) ?: return@mapNotNull null
+
+ val timeToWarn = config.warnWhenAboutToExpire.seconds
+ if (timeToWarn > 0.seconds && timeRemaining == timeToWarn) {
+ playPlingSound()
+ sendTitle("§c§lTotem of Corruption §eabout to expire!", 5.seconds)
+ }
+ Totem(totem.getLorenzVec(), timeRemaining, owner)
+ }
+
+ private fun isOverlayEnabled() = LorenzUtils.inSkyBlock && config.showOverlay
+ private fun isHideParticlesEnabled() = LorenzUtils.inSkyBlock && config.hideParticles
+ private fun isEffectiveAreaEnabled() = LorenzUtils.inSkyBlock && config.showEffectiveArea
+}
+
+class Totem(
+ val location: LorenzVec,
+ val timeRemaining: Duration,
+ val ownerName: String,
+ val distance: Double = location.distanceToPlayer()
+)