aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2
diff options
context:
space:
mode:
authorEmpa <42304516+ItsEmpa@users.noreply.github.com>2024-10-13 12:08:11 +0200
committerGitHub <noreply@github.com>2024-10-13 12:08:11 +0200
commit486231d369a8e2e8cf54f079d6105dac99dec6aa (patch)
tree04ab0da51d3dc3090a6fc57262548a42fcf71211 /src/main/java/at/hannibal2
parent37a06d12289f76ee01903454bf47d4a2b9538934 (diff)
downloadskyhanni-486231d369a8e2e8cf54f079d6105dac99dec6aa.tar.gz
skyhanni-486231d369a8e2e8cf54f079d6105dac99dec6aa.tar.bz2
skyhanni-486231d369a8e2e8cf54f079d6105dac99dec6aa.zip
Improvement + Fix: Ashfang Features with Mob Detection (#2112)
Co-authored-by: Thunderblade73 <85900443+Thunderblade73@users.noreply.github.com> Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com> Co-authored-by: ItsEmpa <itsempa@users.noreply.github.com>
Diffstat (limited to 'src/main/java/at/hannibal2')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/EntityData.kt56
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/mob/Mob.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/mob/MobData.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/mob/MobDetection.kt16
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/MobEvent.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/entity/EntityLeaveWorldEvent.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazes.kt124
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazingSouls.kt71
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangFreezeCooldown.kt45
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangGravityOrbs.kt75
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHideDamageIndicator.kt34
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHideParticles.kt60
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHider.kt46
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHighlights.kt106
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangManager.kt93
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangNextResetCooldown.kt53
-rw-r--r--src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinWorld.java25
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/ColorUtils.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/ExtendedChatColor.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt9
20 files changed, 355 insertions, 484 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/data/EntityData.kt b/src/main/java/at/hannibal2/skyhanni/data/EntityData.kt
index d2f81a6d8..04147ce77 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/EntityData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/EntityData.kt
@@ -5,9 +5,9 @@ import at.hannibal2.skyhanni.events.EntityHealthUpdateEvent
import at.hannibal2.skyhanni.events.EntityMaxHealthUpdateEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
-import at.hannibal2.skyhanni.events.SecondPassedEvent
import at.hannibal2.skyhanni.events.entity.EntityDisplayNameEvent
import at.hannibal2.skyhanni.events.entity.EntityHealthDisplayEvent
+import at.hannibal2.skyhanni.events.entity.EntityLeaveWorldEvent
import at.hannibal2.skyhanni.events.minecraft.packet.PacketReceivedEvent
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
import at.hannibal2.skyhanni.utils.EntityUtils
@@ -31,27 +31,35 @@ import kotlin.time.Duration.Companion.milliseconds
@SkyHanniModule
object EntityData {
- private val maxHealthMap = mutableMapOf<EntityLivingBase, Int>()
+ private val maxHealthMap = mutableMapOf<Int, Int>()
private val nametagCache = TimeLimitedCache<Entity, ChatComponentText>(50.milliseconds)
private val healthDisplayCache = TimeLimitedCache<String, String>(50.milliseconds)
+ private val ignoredEntities = setOf(
+ EntityArmorStand::class.java,
+ EntityXPOrb::class.java,
+ EntityItem::class.java,
+ EntityItemFrame::class.java,
+ EntityOtherPlayerMP::class.java,
+ EntityPlayerSP::class.java,
+ )
+
@SubscribeEvent
fun onTick(event: LorenzTickEvent) {
- for (entity in EntityUtils.getEntities<EntityLivingBase>()) {
+ for (entity in EntityUtils.getEntities<EntityLivingBase>()) { // this completely ignores the ignored entities list?
val maxHealth = entity.baseMaxHealth
- val oldMaxHealth = maxHealthMap.getOrDefault(entity, -1)
+ val id = entity.entityId
+ val oldMaxHealth = maxHealthMap.getOrDefault(id, -1)
if (oldMaxHealth != maxHealth) {
- maxHealthMap[entity] = maxHealth
+ maxHealthMap[id] = maxHealth
EntityMaxHealthUpdateEvent(entity, maxHealth.derpy()).postAndCatch()
}
}
}
- @SubscribeEvent
- fun onSecondPassed(event: SecondPassedEvent) {
- if (event.repeatSeconds(30)) {
- maxHealthMap.keys.removeIf { it.isDead }
- }
+ @HandleEvent
+ fun onEntityLeaveWorld(event: EntityLeaveWorldEvent<EntityLivingBase>) {
+ maxHealthMap -= event.entity.entityId
}
@SubscribeEvent
@@ -69,26 +77,11 @@ object EntityData {
val entityId = packet.entityId
val entity = EntityUtils.getEntityByID(entityId) ?: return
- if (entity is EntityArmorStand) return
- if (entity is EntityXPOrb) return
- if (entity is EntityItem) return
- if (entity is EntityItemFrame) return
-
- if (entity is EntityOtherPlayerMP) return
- if (entity is EntityPlayerSP) return
-
- for (watchableObject in watchableObjects) {
-
- val dataValueId = watchableObject.dataValueId
- val any = watchableObject.`object`
- if (dataValueId != 6) continue
-
- val health = (any as Float).toInt()
-
- if (entity is EntityWither && health == 300 && entityId < 0) {
- return
- }
+ if (entity.javaClass in ignoredEntities) return
+ watchableObjects.find { it.dataValueId == 6 }?.let {
+ val health = (it.`object` as Float).toInt()
+ if (entity is EntityWither && health == 300 && entityId < 0) return
if (entity is EntityLivingBase) {
EntityHealthUpdateEvent(entity, health.derpy()).postAndCatch()
}
@@ -100,6 +93,11 @@ object EntityData {
return postRenderNametag(entity, oldValue)
}
+ @JvmStatic
+ fun despawnEntity(entity: Entity) {
+ EntityLeaveWorldEvent(entity).post()
+ }
+
private fun postRenderNametag(entity: Entity, chatComponent: ChatComponentText) = nametagCache.getOrPut(entity) {
val event = EntityDisplayNameEvent(entity, chatComponent)
event.postAndCatch()
diff --git a/src/main/java/at/hannibal2/skyhanni/data/mob/Mob.kt b/src/main/java/at/hannibal2/skyhanni/data/mob/Mob.kt
index e9eb6729d..062acc4b3 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/mob/Mob.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/mob/Mob.kt
@@ -8,6 +8,7 @@ import at.hannibal2.skyhanni.utils.CollectionUtils.toSingletonListOrEmpty
import at.hannibal2.skyhanni.utils.ColorUtils.addAlpha
import at.hannibal2.skyhanni.utils.EntityUtils.canBeSeen
import at.hannibal2.skyhanni.utils.EntityUtils.cleanName
+import at.hannibal2.skyhanni.utils.EntityUtils.getArmorInventory
import at.hannibal2.skyhanni.utils.EntityUtils.isCorrupted
import at.hannibal2.skyhanni.utils.EntityUtils.isRunic
import at.hannibal2.skyhanni.utils.LocationUtils.distanceToPlayer
@@ -17,6 +18,7 @@ import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher
import net.minecraft.entity.EntityLivingBase
import net.minecraft.entity.item.EntityArmorStand
import net.minecraft.entity.monster.EntityZombie
+import net.minecraft.entity.player.EntityPlayer
import net.minecraft.util.AxisAlignedBB
import java.awt.Color
import java.util.UUID
@@ -111,7 +113,7 @@ class Mob(
fun canBeSeen() = baseEntity.canBeSeen()
- fun isInvisible() = if (baseEntity !is EntityZombie) baseEntity.isInvisible else false
+ fun isInvisible() = baseEntity !is EntityZombie && baseEntity.isInvisible && baseEntity.inventory.isNullOrEmpty()
private var highlightColor: Color? = null
diff --git a/src/main/java/at/hannibal2/skyhanni/data/mob/MobData.kt b/src/main/java/at/hannibal2/skyhanni/data/mob/MobData.kt
index f955384c5..2363945d2 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/mob/MobData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/mob/MobData.kt
@@ -104,11 +104,6 @@ object MobData {
}
@SubscribeEvent
- fun onMobFirstSeen(event: MobEvent.FirstSeen) {
- notSeenMobs.remove(event.mob)
- }
-
- @SubscribeEvent
fun onSkyblockMobSpawnEvent(event: MobEvent.Spawn.SkyblockMob) {
skyblockMobs.add(event.mob)
}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/mob/MobDetection.kt b/src/main/java/at/hannibal2/skyhanni/data/mob/MobDetection.kt
index 014e0a846..b075ab312 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/mob/MobDetection.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/mob/MobDetection.kt
@@ -159,13 +159,15 @@ object MobDetection {
private fun canBeSeen(mob: Mob): Boolean {
val isVisible = !mob.isInvisible() && mob.canBeSeen()
- if (isVisible) when (mob.mobType) {
- Mob.Type.PLAYER -> MobEvent.FirstSeen.Player(mob)
- Mob.Type.SUMMON -> MobEvent.FirstSeen.Summon(mob)
- Mob.Type.SPECIAL -> MobEvent.FirstSeen.Special(mob)
- Mob.Type.PROJECTILE -> MobEvent.FirstSeen.Projectile(mob)
- Mob.Type.DISPLAY_NPC -> MobEvent.FirstSeen.DisplayNPC(mob)
- Mob.Type.BASIC, Mob.Type.DUNGEON, Mob.Type.BOSS, Mob.Type.SLAYER -> MobEvent.FirstSeen.SkyblockMob(mob)
+ if (isVisible) {
+ when (mob.mobType) {
+ Mob.Type.PLAYER -> MobEvent.FirstSeen.Player(mob)
+ Mob.Type.SUMMON -> MobEvent.FirstSeen.Summon(mob)
+ Mob.Type.SPECIAL -> MobEvent.FirstSeen.Special(mob)
+ Mob.Type.PROJECTILE -> MobEvent.FirstSeen.Projectile(mob)
+ Mob.Type.DISPLAY_NPC -> MobEvent.FirstSeen.DisplayNPC(mob)
+ Mob.Type.BASIC, Mob.Type.DUNGEON, Mob.Type.BOSS, Mob.Type.SLAYER -> MobEvent.FirstSeen.SkyblockMob(mob)
+ }.postAndCatch()
}
return isVisible
}
diff --git a/src/main/java/at/hannibal2/skyhanni/events/MobEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/MobEvent.kt
index 10172cb5f..07990ff22 100644
--- a/src/main/java/at/hannibal2/skyhanni/events/MobEvent.kt
+++ b/src/main/java/at/hannibal2/skyhanni/events/MobEvent.kt
@@ -21,8 +21,6 @@ open class MobEvent(val mob: Mob) : LorenzEvent() {
class Projectile(mob: Mob) : DeSpawn(mob)
}
- // TODO replace with "isFirstTime" parameter in the Spawn event. Also create an actual "player sees the mob for the first time" event
- @Deprecated("Old. Will get replaced soon.")
open class FirstSeen(mob: Mob) : MobEvent(mob) {
class SkyblockMob(mob: Mob) : FirstSeen(mob)
class Summon(mob: Mob) : FirstSeen(mob)
diff --git a/src/main/java/at/hannibal2/skyhanni/events/entity/EntityLeaveWorldEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/entity/EntityLeaveWorldEvent.kt
new file mode 100644
index 000000000..74d885e11
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/events/entity/EntityLeaveWorldEvent.kt
@@ -0,0 +1,6 @@
+package at.hannibal2.skyhanni.events.entity
+
+import at.hannibal2.skyhanni.api.event.GenericSkyHanniEvent
+import net.minecraft.entity.Entity
+
+class EntityLeaveWorldEvent<T : Entity>(val entity: T) : GenericSkyHanniEvent<T>(entity.javaClass)
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazes.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazes.kt
deleted file mode 100644
index 9c152e143..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazes.kt
+++ /dev/null
@@ -1,124 +0,0 @@
-package at.hannibal2.skyhanni.features.nether.ashfang
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-import at.hannibal2.skyhanni.data.IslandType
-import at.hannibal2.skyhanni.events.EntityHealthUpdateEvent
-import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
-import at.hannibal2.skyhanni.events.SecondPassedEvent
-import at.hannibal2.skyhanni.events.SkyHanniRenderEntityEvent
-import at.hannibal2.skyhanni.features.combat.damageindicator.BossType
-import at.hannibal2.skyhanni.features.combat.damageindicator.DamageIndicatorManager
-import at.hannibal2.skyhanni.mixins.hooks.RenderLivingEntityHelper
-import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
-import at.hannibal2.skyhanni.utils.CollectionUtils.editCopy
-import at.hannibal2.skyhanni.utils.ColorUtils.withAlpha
-import at.hannibal2.skyhanni.utils.EntityUtils
-import at.hannibal2.skyhanni.utils.EntityUtils.getAllNameTagsWith
-import at.hannibal2.skyhanni.utils.LorenzColor
-import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland
-import net.minecraft.entity.EntityLivingBase
-import net.minecraft.entity.item.EntityArmorStand
-import net.minecraft.entity.monster.EntityBlaze
-import net.minecraftforge.fml.common.eventhandler.EventPriority
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-
-@SkyHanniModule
-object AshfangBlazes {
-
- private val config get() = SkyHanniMod.feature.crimsonIsle.ashfang
-
- private val blazeColor = mutableMapOf<EntityBlaze, LorenzColor>()
- private var blazeArmorStand = mapOf<EntityBlaze, EntityArmorStand>()
-
- private var nearAshfang = false
-
- @SubscribeEvent
- fun onSecondPassed(event: SecondPassedEvent) {
- if (!isEnabled()) return
-
- checkNearAshfang()
-
- if (nearAshfang) {
- for (entity in EntityUtils.getEntities<EntityBlaze>()
- .filter { it !in blazeColor.keys }) {
- val list = entity.getAllNameTagsWith(2, "Ashfang")
- if (list.size == 1) {
- val armorStand = list[0]
- val color = when {
- armorStand.name.contains("Ashfang Follower") -> LorenzColor.DARK_GRAY
- armorStand.name.contains("Ashfang Underling") -> LorenzColor.RED
- armorStand.name.contains("Ashfang Acolyte") -> LorenzColor.BLUE
- else -> {
- blazeArmorStand = blazeArmorStand.editCopy {
- remove(entity)
- }
- continue
- }
- }
- blazeArmorStand = blazeArmorStand.editCopy {
- this[entity] = armorStand
- }
- entity setBlazeColor color
- }
- }
- }
- }
-
- @SubscribeEvent
- fun onEntityHealthUpdate(event: EntityHealthUpdateEvent) {
- if (!isEnabled()) return
-
- val entityId = event.entity.entityId
- if (entityId !in blazeArmorStand.keys.map { it.entityId }) return
-
- if (event.health % 10_000_000 != 0) {
- blazeArmorStand = blazeArmorStand.editCopy {
- keys.removeIf { it.entityId == entityId }
- }
- }
- }
-
- private fun checkNearAshfang() {
- nearAshfang = EntityUtils.getEntities<EntityArmorStand>().any { it.name.contains("Ashfang") }
- }
-
- @SubscribeEvent(priority = EventPriority.HIGH)
- fun onRenderLiving(event: SkyHanniRenderEntityEvent.Specials.Pre<EntityLivingBase>) {
- if (!isEnabled()) return
- if (!config.hide.fullNames) return
-
- val entity = event.entity
- if (entity !is EntityArmorStand) return
- if (!entity.hasCustomName()) return
- if (entity.isDead) return
- if (entity in blazeArmorStand.values) {
- event.cancel()
- }
- }
-
- @SubscribeEvent
- fun onWorldChange(event: LorenzWorldChangeEvent) {
- blazeColor.clear()
- blazeArmorStand = emptyMap()
- }
-
- @SubscribeEvent
- fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
- event.move(2, "ashfang.nextResetCooldown", "crimsonIsle.ashfang.nextResetCooldown")
- event.move(2, "ashfang.highlightBlazes", "crimsonIsle.ashfang.highlightBlazes")
- event.move(2, "ashfang.hideNames", "crimsonIsle.ashfang.hide.fullNames")
- }
-
- private fun isEnabled(): Boolean {
- return IslandType.CRIMSON_ISLE.isInIsland() && DamageIndicatorManager.isBossSpawned(BossType.NETHER_ASHFANG)
- }
-
- private infix fun EntityBlaze.setBlazeColor(color: LorenzColor) {
- blazeColor[this] = color
- RenderLivingEntityHelper.setEntityColorWithNoHurtTime(
- this,
- color.toColor().withAlpha(40),
- ) { isEnabled() && config.highlightBlazes }
- }
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazingSouls.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazingSouls.kt
deleted file mode 100644
index de4db8f83..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazingSouls.kt
+++ /dev/null
@@ -1,71 +0,0 @@
-package at.hannibal2.skyhanni.features.nether.ashfang
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
-import at.hannibal2.skyhanni.events.LorenzTickEvent
-import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
-import at.hannibal2.skyhanni.features.combat.damageindicator.BossType
-import at.hannibal2.skyhanni.features.combat.damageindicator.DamageIndicatorManager
-import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
-import at.hannibal2.skyhanni.utils.ColorUtils.toChromaColor
-import at.hannibal2.skyhanni.utils.EntityUtils
-import at.hannibal2.skyhanni.utils.EntityUtils.hasSkullTexture
-import at.hannibal2.skyhanni.utils.LocationUtils
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.RenderUtils.drawString
-import at.hannibal2.skyhanni.utils.RenderUtils.drawWaypointFilled
-import at.hannibal2.skyhanni.utils.getLorenzVec
-import net.minecraft.entity.item.EntityArmorStand
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-
-@SkyHanniModule
-object AshfangBlazingSouls {
-
- private val config get() = SkyHanniMod.feature.crimsonIsle.ashfang.blazingSouls
-
- private const val TEXTURE =
- "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODI4N2IzOTdkYWY5NTE2YTBiZDc2ZjVmMWI3YmY5Nzk1MTVkZjNkNWQ4MzNlMDYzNWZhNjhiMzdlZTA4MjIxMiJ9fX0="
- private val souls = mutableListOf<EntityArmorStand>()
-
- @SubscribeEvent
- fun onTick(event: LorenzTickEvent) {
- if (!isEnabled()) return
-
- EntityUtils.getEntities<EntityArmorStand>()
- .filter { it !in souls && it.hasSkullTexture(TEXTURE) }
- .forEach { souls.add(it) }
- }
-
- @SubscribeEvent
- fun onRenderWorld(event: LorenzRenderWorldEvent) {
- if (!isEnabled()) return
-
- val color = config.color.toChromaColor()
-
- val playerLocation = LocationUtils.playerLocation()
- for (orb in souls) {
- if (orb.isDead) continue
- val orbLocation = orb.getLorenzVec()
- event.drawWaypointFilled(orbLocation.add(-0.5, 1.25, -0.5), color, extraSize = -0.15)
- if (orbLocation.distance(playerLocation) < 10) {
- // TODO find way to dynamically change color
- event.drawString(orbLocation.up(2.5), "§bBlazing Soul")
- }
- }
- }
-
- @SubscribeEvent
- fun onWorldChange(event: LorenzWorldChangeEvent) {
- souls.clear()
- }
-
- @SubscribeEvent
- fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
- event.move(2, "ashfang.blazingSouls", "crimsonIsle.ashfang.blazingSouls.enabled")
- event.move(2, "ashfang.blazingSoulsColor", "crimsonIsle.ashfang.blazingSouls.color")
- }
-
- private fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled &&
- DamageIndicatorManager.isBossSpawned(BossType.NETHER_ASHFANG)
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangFreezeCooldown.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangFreezeCooldown.kt
index 68684ef49..07cf723fa 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangFreezeCooldown.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangFreezeCooldown.kt
@@ -1,14 +1,10 @@
package at.hannibal2.skyhanni.features.nether.ashfang
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
-import at.hannibal2.skyhanni.features.combat.damageindicator.BossType
-import at.hannibal2.skyhanni.features.combat.damageindicator.DamageIndicatorManager
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher
+import at.hannibal2.skyhanni.utils.RegexUtils.matches
import at.hannibal2.skyhanni.utils.RenderUtils.renderString
import at.hannibal2.skyhanni.utils.SimpleTimeMark
import at.hannibal2.skyhanni.utils.TimeUtils.format
@@ -19,47 +15,35 @@ import kotlin.time.Duration.Companion.seconds
@SkyHanniModule
object AshfangFreezeCooldown {
- private val config get() = SkyHanniMod.feature.crimsonIsle.ashfang
+ private val config get() = AshfangManager.config
private val cryogenicBlastPattern by RepoPattern.pattern(
"ashfang.freeze.cryogenic",
- "§cAshfang Follower's Cryogenic Blast hit you for .* damage!"
+ "§cAshfang Follower's Cryogenic Blast hit you for .* damage!",
)
- private var lastHit = SimpleTimeMark.farPast()
+ private var unfrozenTime = SimpleTimeMark.farPast()
+ private val duration = 3.seconds
@SubscribeEvent
fun onChat(event: LorenzChatEvent) {
if (!isEnabled()) return
-
- val message = event.message
- cryogenicBlastPattern.matchMatcher(message) {
- lastHit = SimpleTimeMark.now()
- }
+ if (cryogenicBlastPattern.matches(event.message)) unfrozenTime = SimpleTimeMark.now() + duration
}
@SubscribeEvent
fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
if (!isEnabled()) return
+ if (!isCurrentlyFrozen()) return
- val passedSince = lastHit.passedSince()
- val maxDuration = 3.seconds
- val duration = maxDuration - passedSince
- if (duration > 0.seconds) {
- val format = duration.format(showMilliSeconds = true)
- config.freezeCooldownPos.renderString(
- "§cAshfang Freeze: §a$format",
- posLabel = "Ashfang Freeze Cooldown"
- )
- }
+ val format = unfrozenTime.timeUntil().format(showMilliSeconds = true)
+ config.freezeCooldownPos.renderString(
+ "§cAshfang Freeze: §a$format",
+ posLabel = "Ashfang Freeze Cooldown",
+ )
}
- fun isCurrentlyFrozen(): Boolean {
- val passedSince = lastHit.passedSince()
- val maxDuration = 3.seconds
- val duration = maxDuration - passedSince
- return duration > 0.seconds
- }
+ fun isCurrentlyFrozen() = unfrozenTime.isInFuture()
@SubscribeEvent
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
@@ -67,6 +51,5 @@ object AshfangFreezeCooldown {
event.move(2, "ashfang.freezeCooldownPos", "crimsonIsle.ashfang.freezeCooldownPos")
}
- private fun isEnabled() = LorenzUtils.inSkyBlock && config.freezeCooldown &&
- DamageIndicatorManager.isBossSpawned(BossType.NETHER_ASHFANG)
+ private fun isEnabled() = AshfangManager.active && config.freezeCooldown
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangGravityOrbs.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangGravityOrbs.kt
deleted file mode 100644
index 1eaa1dd5e..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangGravityOrbs.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-package at.hannibal2.skyhanni.features.nether.ashfang
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
-import at.hannibal2.skyhanni.events.LorenzTickEvent
-import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
-import at.hannibal2.skyhanni.features.combat.damageindicator.BossType
-import at.hannibal2.skyhanni.features.combat.damageindicator.DamageIndicatorManager
-import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
-import at.hannibal2.skyhanni.utils.EntityUtils
-import at.hannibal2.skyhanni.utils.EntityUtils.hasSkullTexture
-import at.hannibal2.skyhanni.utils.LocationUtils
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.RenderUtils
-import at.hannibal2.skyhanni.utils.RenderUtils.drawString
-import at.hannibal2.skyhanni.utils.SpecialColor
-import at.hannibal2.skyhanni.utils.getLorenzVec
-import net.minecraft.entity.item.EntityArmorStand
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-import java.awt.Color
-
-@SkyHanniModule
-object AshfangGravityOrbs {
-
- private val config get() = SkyHanniMod.feature.crimsonIsle.ashfang.gravityOrbs
-
- private const val TEXTURE = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV" +
- "0L3RleHR1cmUvMWE2OWNjZjdhZDkwNGM5YTg1MmVhMmZmM2Y1YjRlMjNhZGViZjcyZWQxMmQ1ZjI0Yjc4Y2UyZDQ0YjRhMiJ9fX0="
- private val orbs = mutableListOf<EntityArmorStand>()
-
- @SubscribeEvent
- fun onTick(event: LorenzTickEvent) {
- if (!isEnabled()) return
-
- EntityUtils.getEntities<EntityArmorStand>()
- .filter { it !in orbs && it.hasSkullTexture(TEXTURE) }
- .forEach { orbs.add(it) }
- }
-
- @SubscribeEvent
- fun onRenderWorld(event: LorenzRenderWorldEvent) {
- if (!isEnabled()) return
-
- val color = Color(SpecialColor.specialToChromaRGB(config.color), true)
- val playerLocation = LocationUtils.playerLocation()
- for (orb in orbs) {
- if (orb.isDead) continue
- val orbLocation = orb.getLorenzVec()
- val center = orbLocation.add(-0.5, -2.0, -0.5)
- RenderUtils.drawCylinderInWorld(color, center.x, center.y, center.z, 3.5f, 4.5f, event.partialTicks)
-
- if (orbLocation.distance(playerLocation) < 15) {
- // TODO find way to dynamically change color
- event.drawString(orbLocation.up(2.5), "§cGravity Orb")
- }
- }
- }
-
- @SubscribeEvent
- fun onWorldChange(event: LorenzWorldChangeEvent) {
- orbs.clear()
- }
-
- @SubscribeEvent
- fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
- event.move(1, "ashfang.gravityOrbs", "ashfang.gravityOrbs.enabled")
- event.move(1, "ashfang.gravityOrbsColor", "ashfang.gravityOrbs.color")
-
- event.move(2, "ashfang.gravityOrbs", "crimsonIsle.ashfang.gravityOrbs")
- }
-
- private fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled &&
- DamageIndicatorManager.isBossSpawned(BossType.NETHER_ASHFANG)
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHideDamageIndicator.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHideDamageIndicator.kt
deleted file mode 100644
index 606f7d17f..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHideDamageIndicator.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package at.hannibal2.skyhanni.features.nether.ashfang
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-import at.hannibal2.skyhanni.events.SkyHanniRenderEntityEvent
-import at.hannibal2.skyhanni.features.combat.damageindicator.BossType
-import at.hannibal2.skyhanni.features.combat.damageindicator.DamageIndicatorManager
-import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import net.minecraft.entity.EntityLivingBase
-import net.minecraftforge.fml.common.eventhandler.EventPriority
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-
-@SkyHanniModule
-object AshfangHideDamageIndicator {
-
- @SubscribeEvent(priority = EventPriority.HIGH)
- fun onRenderLiving(event: SkyHanniRenderEntityEvent.Specials.Pre<EntityLivingBase>) {
- if (!isEnabled()) return
-
- if (DamageIndicatorManager.isDamageSplash(event.entity)) {
- event.cancel()
- }
- }
-
- @SubscribeEvent
- fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
- event.move(2, "ashfang.hideDamageSplash", "crimsonIsle.ashfang.hide.damageSplash")
- }
-
- private fun isEnabled() =
- LorenzUtils.inSkyBlock && SkyHanniMod.feature.crimsonIsle.ashfang.hide.damageSplash &&
- DamageIndicatorManager.isBossSpawned(BossType.NETHER_ASHFANG)
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHideParticles.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHideParticles.kt
deleted file mode 100644
index 4c228a436..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHideParticles.kt
+++ /dev/null
@@ -1,60 +0,0 @@
-package at.hannibal2.skyhanni.features.nether.ashfang
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-import at.hannibal2.skyhanni.events.CheckRenderEntityEvent
-import at.hannibal2.skyhanni.events.ReceiveParticleEvent
-import at.hannibal2.skyhanni.events.SecondPassedEvent
-import at.hannibal2.skyhanni.features.combat.damageindicator.BossType
-import at.hannibal2.skyhanni.features.combat.damageindicator.DamageIndicatorManager
-import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
-import at.hannibal2.skyhanni.utils.ItemUtils.name
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import net.minecraft.entity.item.EntityArmorStand
-import net.minecraftforge.fml.common.eventhandler.EventPriority
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-
-@SkyHanniModule
-object AshfangHideParticles {
-
- private var nearAshfang = false
-
- @SubscribeEvent
- fun onSecondPassed(event: SecondPassedEvent) {
- if (!LorenzUtils.inSkyBlock) return
-
- nearAshfang = DamageIndicatorManager.getDistanceTo(BossType.NETHER_ASHFANG) < 40
- }
-
- @SubscribeEvent
- fun onReceiveParticle(event: ReceiveParticleEvent) {
- if (isEnabled()) {
- event.cancel()
- }
- }
-
- @SubscribeEvent(priority = EventPriority.HIGH)
- fun onCheckRender(event: CheckRenderEntityEvent<*>) {
- if (!isEnabled()) return
-
- val entity = event.entity
- if (entity is EntityArmorStand) {
- for (stack in entity.inventory) {
- if (stack == null) continue
- val name = stack.name
- if (name == "§aFairy Souls") continue
- if (name == "Glowstone") {
- event.cancel()
- }
- }
- }
- }
-
- @SubscribeEvent
- fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
- event.move(2, "ashfang.hideParticles", "crimsonIsle.ashfang.hide.particles")
- }
-
- private fun isEnabled() =
- LorenzUtils.inSkyBlock && SkyHanniMod.feature.crimsonIsle.ashfang.hide.particles && nearAshfang
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHider.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHider.kt
new file mode 100644
index 000000000..4e40ed77c
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHider.kt
@@ -0,0 +1,46 @@
+package at.hannibal2.skyhanni.features.nether.ashfang
+
+import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
+import at.hannibal2.skyhanni.events.CheckRenderEntityEvent
+import at.hannibal2.skyhanni.events.ReceiveParticleEvent
+import at.hannibal2.skyhanni.events.SkyHanniRenderEntityEvent
+import at.hannibal2.skyhanni.features.combat.damageindicator.DamageIndicatorManager
+import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
+import at.hannibal2.skyhanni.utils.ItemUtils.name
+import net.minecraft.entity.item.EntityArmorStand
+import net.minecraftforge.fml.common.eventhandler.EventPriority
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+@SkyHanniModule
+object AshfangHider {
+
+ private val config get() = AshfangManager.config.hide
+
+ @SubscribeEvent(priority = EventPriority.HIGH)
+ fun onRenderLiving(event: SkyHanniRenderEntityEvent.Specials.Pre<EntityArmorStand>) {
+ if (!AshfangManager.active || !config.damageSplash) return
+
+ if (DamageIndicatorManager.isDamageSplash(event.entity)) {
+ event.cancel()
+ }
+ }
+
+ @SubscribeEvent
+ fun onReceiveParticle(event: ReceiveParticleEvent) {
+ if (!AshfangManager.active || !config.particles) return
+ event.cancel()
+ }
+
+ @SubscribeEvent(priority = EventPriority.HIGH)
+ fun onCheckRender(event: CheckRenderEntityEvent<*>) {
+ if (!AshfangManager.active || !config.particles) return
+ val entity = event.entity as? EntityArmorStand ?: return
+ if (entity.inventory.any { it?.name == "Glowstone" }) event.cancel()
+ }
+
+ @SubscribeEvent
+ fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
+ event.move(2, "ashfang.hideDamageSplash", "crimsonIsle.ashfang.hide.damageSplash")
+ event.move(2, "ashfang.hideParticles", "crimsonIsle.ashfang.hide.particles")
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHighlights.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHighlights.kt
new file mode 100644
index 000000000..312cfc469
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHighlights.kt
@@ -0,0 +1,106 @@
+package at.hannibal2.skyhanni.features.nether.ashfang
+
+import at.hannibal2.skyhanni.api.event.HandleEvent
+import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
+import at.hannibal2.skyhanni.data.IslandType
+import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
+import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
+import at.hannibal2.skyhanni.events.entity.EntityEnterWorldEvent
+import at.hannibal2.skyhanni.events.entity.EntityLeaveWorldEvent
+import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
+import at.hannibal2.skyhanni.utils.ColorUtils
+import at.hannibal2.skyhanni.utils.ColorUtils.getExtendedColorCode
+import at.hannibal2.skyhanni.utils.ColorUtils.toChromaColor
+import at.hannibal2.skyhanni.utils.DelayedRun
+import at.hannibal2.skyhanni.utils.EntityUtils.hasSkullTexture
+import at.hannibal2.skyhanni.utils.LocationUtils.distanceToPlayer
+import at.hannibal2.skyhanni.utils.LorenzColor
+import at.hannibal2.skyhanni.utils.LorenzVec
+import at.hannibal2.skyhanni.utils.RenderUtils.drawCylinderInWorld
+import at.hannibal2.skyhanni.utils.RenderUtils.drawString
+import at.hannibal2.skyhanni.utils.RenderUtils.drawWaypointFilled
+import at.hannibal2.skyhanni.utils.RenderUtils.exactLocation
+import net.minecraft.entity.item.EntityArmorStand
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+@SkyHanniModule
+object AshfangHighlights {
+
+ private val config get() = AshfangManager.config
+
+ private const val BLAZING_SOUL =
+ "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODI4N2IzOTdkYWY5NTE2YTBiZDc2ZjVmMWI3YmY5Nzk1MTVkZjNkNWQ4MzNlMDYzNWZhNjhiMzdlZTA4MjIxMiJ9fX0="
+ private const val GRAVITY_ORB =
+ "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMWE2OWNjZjdhZDkwNGM5YTg1MmVhMmZmM2Y1YjRlMjNhZGViZjcyZWQxMmQ1ZjI0Yjc4Y2UyZDQ0YjRhMiJ9fX0="
+ private val blazingSouls = mutableSetOf<EntityArmorStand>()
+ private val gravityOrbs = mutableSetOf<EntityArmorStand>()
+ private const val MAX_DISTANCE = 15.0
+
+ @HandleEvent(onlyOnSkyblock = true, onlyOnIsland = IslandType.CRIMSON_ISLE)
+ fun onEntityJoin(event: EntityEnterWorldEvent<EntityArmorStand>) {
+ if (!AshfangManager.active) return
+ val entity = event.entity
+ DelayedRun.runNextTick {
+ when {
+ entity.hasSkullTexture(BLAZING_SOUL) -> blazingSouls += entity
+ entity.hasSkullTexture(GRAVITY_ORB) -> gravityOrbs += entity
+ }
+ }
+ }
+
+ @HandleEvent(onlyOnSkyblock = true, onlyOnIsland = IslandType.CRIMSON_ISLE)
+ fun onEntityLeave(event: EntityLeaveWorldEvent<EntityArmorStand>) {
+ blazingSouls -= event.entity
+ gravityOrbs -= event.entity
+ }
+
+ @SubscribeEvent
+ fun onRenderWorld(event: LorenzRenderWorldEvent) {
+ if (!AshfangManager.active) return
+
+ if (config.blazingSouls.enabled) {
+ val color = config.blazingSouls.color.toChromaColor()
+ blazingSouls.forEach {
+ val location = event.exactLocation(it)
+ event.drawWaypointFilled(location.add(-0.5, 1.25, -0.5), color, extraSize = -0.15)
+ event.drawBlendedColorString(location, "Blazing Soul")
+ }
+ }
+
+ if (config.gravityOrbs.enabled) {
+ val color = config.gravityOrbs.color.toChromaColor()
+ gravityOrbs.forEach {
+ val location = event.exactLocation(it)
+ event.drawCylinderInWorld(color, location.add(-0.5, -2.0, -0.5), 3.5f, 4.5f)
+ event.drawBlendedColorString(location, "Gravity Orb")
+ }
+ }
+ }
+
+ @SubscribeEvent
+ fun onWorldChange(event: LorenzWorldChangeEvent) {
+ blazingSouls.clear()
+ gravityOrbs.clear()
+ }
+
+ private fun LorenzRenderWorldEvent.drawBlendedColorString(location: LorenzVec, text: String) {
+ val distance = location.distanceToPlayer()
+ if (distance < MAX_DISTANCE) {
+ val colorCode = getColorCode(distance)
+ drawString(location.add(y = 2.5), colorCode + text)
+ }
+ }
+
+ private fun getColorCode(distance: Double): String =
+ ColorUtils.blendRGB(LorenzColor.GREEN.toColor(), LorenzColor.RED.toColor(), distance / MAX_DISTANCE).getExtendedColorCode()
+
+ @SubscribeEvent
+ fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
+ event.move(2, "ashfang.blazingSouls", "crimsonIsle.ashfang.blazingSouls.enabled")
+ event.move(2, "ashfang.blazingSoulsColor", "crimsonIsle.ashfang.blazingSouls.color")
+
+ event.move(1, "ashfang.gravityOrbs", "ashfang.gravityOrbs.enabled")
+ event.move(1, "ashfang.gravityOrbsColor", "ashfang.gravityOrbs.color")
+ event.move(2, "ashfang.gravityOrbs", "crimsonIsle.ashfang.gravityOrbs")
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangManager.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangManager.kt
new file mode 100644
index 000000000..edf7dbd64
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangManager.kt
@@ -0,0 +1,93 @@
+package at.hannibal2.skyhanni.features.nether.ashfang
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
+import at.hannibal2.skyhanni.config.features.crimsonisle.ashfang.AshfangConfig
+import at.hannibal2.skyhanni.data.IslandType
+import at.hannibal2.skyhanni.data.mob.Mob
+import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
+import at.hannibal2.skyhanni.events.MobEvent
+import at.hannibal2.skyhanni.events.SkyHanniRenderEntityEvent
+import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
+import at.hannibal2.skyhanni.utils.ChatUtils
+import at.hannibal2.skyhanni.utils.ColorUtils.addAlpha
+import at.hannibal2.skyhanni.utils.EntityUtils.isAtFullHealth
+import at.hannibal2.skyhanni.utils.LorenzColor
+import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland
+import at.hannibal2.skyhanni.utils.MobUtils.mob
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
+import net.minecraft.entity.item.EntityArmorStand
+import net.minecraftforge.fml.common.eventhandler.EventPriority
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import kotlin.time.Duration.Companion.seconds
+
+@SkyHanniModule
+object AshfangManager {
+
+ val config: AshfangConfig get() = SkyHanniMod.feature.crimsonIsle.ashfang
+
+ private val ashfangMobs = mutableSetOf<Mob>()
+ var ashfang: Mob? = null
+ private set
+ var lastSpawnTime = SimpleTimeMark.farPast()
+ private set
+
+ val active get() = ashfang != null
+
+ @SubscribeEvent
+ fun onMobSpawn(event: MobEvent.Spawn.SkyblockMob) {
+ if (!IslandType.CRIMSON_ISLE.isInIsland()) return
+ val mob = event.mob
+ val color = when (mob.name) {
+ "Ashfang Follower" -> LorenzColor.DARK_GRAY
+ "Ashfang Underling" -> LorenzColor.RED
+ "Ashfang Acolyte" -> LorenzColor.BLUE
+ "Ashfang" -> {
+ ashfang = mob
+ return
+ }
+
+ else -> return
+ }
+ ashfangMobs += mob
+ if (config.highlightBlazes) mob.highlight(color.toColor().addAlpha(40))
+ }
+
+ @SubscribeEvent
+ fun onMobFirstSeen(event: MobEvent.FirstSeen.SkyblockMob) {
+ if (!IslandType.CRIMSON_ISLE.isInIsland()) return
+ if (!event.mob.name.contains("Ashfang ")) return
+ if (lastSpawnTime.passedSince() < 10.seconds) return
+ lastSpawnTime = SimpleTimeMark.now()
+ }
+
+ @SubscribeEvent
+ fun onMobDeSpawn(event: MobEvent.DeSpawn.SkyblockMob) {
+ val mob = event.mob
+ ashfangMobs -= mob
+ if (ashfang == mob) {
+ ashfang = null
+ if (mob.isInRender()) lastSpawnTime = SimpleTimeMark.farPast()
+ }
+ }
+
+ @SubscribeEvent(priority = EventPriority.HIGH)
+ fun onRenderLiving(event: SkyHanniRenderEntityEvent.Specials.Pre<EntityArmorStand>) {
+ if (!active || !config.hide.fullNames) return
+ val mob = event.entity.mob ?: return
+ if (mob !in ashfangMobs) return
+ if (mob.baseEntity.isAtFullHealth()) event.cancel()
+ }
+
+ @SubscribeEvent
+ fun onWorldChange(event: LorenzWorldChangeEvent) {
+ lastSpawnTime = SimpleTimeMark.farPast()
+ }
+
+ @SubscribeEvent
+ fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
+ event.move(2, "ashfang.nextResetCooldown", "crimsonIsle.ashfang.nextResetCooldown")
+ event.move(2, "ashfang.highlightBlazes", "crimsonIsle.ashfang.highlightBlazes")
+ event.move(2, "ashfang.hideNames", "crimsonIsle.ashfang.hide.fullNames")
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangNextResetCooldown.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangNextResetCooldown.kt
index c555ec6d2..b77301edc 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangNextResetCooldown.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangNextResetCooldown.kt
@@ -1,61 +1,33 @@
package at.hannibal2.skyhanni.features.nether.ashfang
-import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.GuiRenderEvent
-import at.hannibal2.skyhanni.events.LorenzTickEvent
-import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
-import at.hannibal2.skyhanni.features.combat.damageindicator.BossType
-import at.hannibal2.skyhanni.features.combat.damageindicator.DamageIndicatorManager
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
-import at.hannibal2.skyhanni.utils.EntityUtils
-import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.RenderUtils.renderString
-import at.hannibal2.skyhanni.utils.SimpleTimeMark
import at.hannibal2.skyhanni.utils.TimeUnit
import at.hannibal2.skyhanni.utils.TimeUtils.format
-import net.minecraft.entity.item.EntityArmorStand
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.time.Duration.Companion.seconds
@SkyHanniModule
object AshfangNextResetCooldown {
- private val config get() = SkyHanniMod.feature.crimsonIsle.ashfang
- private var spawnTime = SimpleTimeMark.farPast()
-
- @SubscribeEvent
- fun onTick(event: LorenzTickEvent) {
- if (!isEnabled()) return
-
- if (EntityUtils.getEntities<EntityArmorStand>().any {
- it.posY > 145 && (it.name.contains("§c§9Ashfang Acolyte§r") || it.name.contains("§c§cAshfang Underling§r"))
- }
- ) {
- spawnTime = SimpleTimeMark.now()
- }
- }
+ private val config get() = AshfangManager.config
+ private val ashfangResetTime = 46.1.seconds
@SubscribeEvent
fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
if (!isEnabled()) return
- if (spawnTime.isFarPast()) return
+ if (AshfangManager.lastSpawnTime.isFarPast()) return
+ val nextSpawn = AshfangManager.lastSpawnTime + ashfangResetTime
- val passedSince = spawnTime.passedSince()
- if (passedSince < 46.1.seconds) {
- val format = passedSince.format(TimeUnit.SECOND, showMilliSeconds = true)
- config.nextResetCooldownPos.renderString(
- "§cAshfang next reset in: §a$format",
- posLabel = "Ashfang Reset Cooldown"
- )
- } else {
- spawnTime = SimpleTimeMark.farPast()
- }
- }
+ val format = if (nextSpawn.isInPast()) "§aNow!"
+ else "§b${nextSpawn.timeUntil().format(TimeUnit.SECOND, showMilliSeconds = true)}"
- @SubscribeEvent
- fun onWorldChange(event: LorenzWorldChangeEvent) {
- spawnTime = SimpleTimeMark.farPast()
+ config.nextResetCooldownPos.renderString(
+ "§cAshfang next reset in: $format",
+ posLabel = "Ashfang Reset Cooldown",
+ )
}
@SubscribeEvent
@@ -64,8 +36,5 @@ object AshfangNextResetCooldown {
event.move(2, "ashfang.nextResetCooldownPos", "crimsonIsle.ashfang.nextResetCooldownPos")
}
- private fun isEnabled(): Boolean {
- return LorenzUtils.inSkyBlock && config.nextResetCooldown &&
- DamageIndicatorManager.isBossSpawned(BossType.NETHER_ASHFANG)
- }
+ private fun isEnabled() = AshfangManager.active && config.nextResetCooldown
}
diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinWorld.java b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinWorld.java
new file mode 100644
index 000000000..1569416d4
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinWorld.java
@@ -0,0 +1,25 @@
+package at.hannibal2.skyhanni.mixins.transformers;
+
+import at.hannibal2.skyhanni.data.EntityData;
+import net.minecraft.entity.Entity;
+import net.minecraft.world.World;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import java.util.Collection;
+
+@Mixin(World.class)
+public class MixinWorld {
+
+ @Inject(method = "unloadEntities", at = @At("HEAD"))
+ private void unloadEntities(Collection<Entity> entityCollection, CallbackInfo ci) {
+ for (Entity entity : entityCollection) EntityData.despawnEntity(entity);
+ }
+
+ @Inject(method = "onEntityRemoved", at = @At("HEAD"))
+ private void onEntityRemoved(Entity entityIn, CallbackInfo ci) {
+ EntityData.despawnEntity(entityIn);
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ColorUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ColorUtils.kt
index 7b941aebe..52b1eb68d 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/ColorUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/ColorUtils.kt
@@ -8,7 +8,7 @@ object ColorUtils {
fun String.toChromaColor() = Color(toChromaColorInt(), true)
fun String.toChromaColorInt() = SpecialColor.specialToChromaRGB(this)
- fun String.getFirstColorCode() = this.takeIf { it.firstOrNull() == '§' }?.getOrNull(1)
+ fun String.getFirstColorCode() = takeIf { it.firstOrNull() == '§' }?.getOrNull(1)
fun getRed(color: Int) = color shr 16 and 0xFF
@@ -24,6 +24,8 @@ object ColorUtils {
(start.blue * (1 - percent) + end.blue * percent).toInt(),
)
+ fun Color.getExtendedColorCode(hasAlpha: Boolean = false): String = ExtendedChatColor(rgb, hasAlpha).toString()
+
/** Darkens a color by a [factor]. The lower the [factor], the darker the color. */
fun Color.darker(factor: Double = 0.7) = Color(
(red * factor).toInt().coerceIn(0, 255),
@@ -34,7 +36,8 @@ object ColorUtils {
val TRANSPARENT_COLOR = Color(0, 0, 0, 0)
- fun Color.withAlpha(alpha: Int): Int = (alpha.coerceIn(0, 255) shl 24) or (this.rgb and 0x00ffffff)
+ @Deprecated("Don't use int colors", ReplaceWith("this.addAlpha()"))
+ fun Color.withAlpha(alpha: Int): Int = (alpha.coerceIn(0, 255) shl 24) or (rgb and 0x00ffffff)
fun Color.addAlpha(alpha: Int): Color = Color(red, green, blue, alpha)
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ExtendedChatColor.kt b/src/main/java/at/hannibal2/skyhanni/utils/ExtendedChatColor.kt
index f4a64017d..e4cb2f448 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/ExtendedChatColor.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/ExtendedChatColor.kt
@@ -4,7 +4,7 @@ import java.awt.Color
class ExtendedChatColor(
val rgb: Int,
- val hasAlpha: Boolean,
+ val hasAlpha: Boolean = false,
) {
override fun toString(): String {
val stringBuilder = StringBuilder()
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt
index 14241f314..47bdb3976 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt
@@ -768,6 +768,15 @@ object RenderUtils {
GlStateManager.popMatrix()
}
+ fun LorenzRenderWorldEvent.drawCylinderInWorld(
+ color: Color,
+ location: LorenzVec,
+ radius: Float,
+ height: Float,
+ ) {
+ drawCylinderInWorld(color, location.x, location.y, location.z, radius, height, partialTicks)
+ }
+
fun drawCylinderInWorld(
color: Color,
x: Double,