From 486231d369a8e2e8cf54f079d6105dac99dec6aa Mon Sep 17 00:00:00 2001 From: Empa <42304516+ItsEmpa@users.noreply.github.com> Date: Sun, 13 Oct 2024 12:08:11 +0200 Subject: 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 --- .../java/at/hannibal2/skyhanni/data/EntityData.kt | 56 +++++----- .../java/at/hannibal2/skyhanni/data/mob/Mob.kt | 4 +- .../java/at/hannibal2/skyhanni/data/mob/MobData.kt | 5 - .../at/hannibal2/skyhanni/data/mob/MobDetection.kt | 16 +-- .../java/at/hannibal2/skyhanni/events/MobEvent.kt | 2 - .../events/entity/EntityLeaveWorldEvent.kt | 6 + .../features/nether/ashfang/AshfangBlazes.kt | 124 --------------------- .../features/nether/ashfang/AshfangBlazingSouls.kt | 71 ------------ .../nether/ashfang/AshfangFreezeCooldown.kt | 45 +++----- .../features/nether/ashfang/AshfangGravityOrbs.kt | 75 ------------- .../nether/ashfang/AshfangHideDamageIndicator.kt | 34 ------ .../nether/ashfang/AshfangHideParticles.kt | 60 ---------- .../features/nether/ashfang/AshfangHider.kt | 46 ++++++++ .../features/nether/ashfang/AshfangHighlights.kt | 106 ++++++++++++++++++ .../features/nether/ashfang/AshfangManager.kt | 93 ++++++++++++++++ .../nether/ashfang/AshfangNextResetCooldown.kt | 53 ++------- .../skyhanni/mixins/transformers/MixinWorld.java | 25 +++++ .../java/at/hannibal2/skyhanni/utils/ColorUtils.kt | 7 +- .../hannibal2/skyhanni/utils/ExtendedChatColor.kt | 2 +- .../at/hannibal2/skyhanni/utils/RenderUtils.kt | 9 ++ 20 files changed, 355 insertions(+), 484 deletions(-) create mode 100644 src/main/java/at/hannibal2/skyhanni/events/entity/EntityLeaveWorldEvent.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazes.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangBlazingSouls.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangGravityOrbs.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHideDamageIndicator.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHideParticles.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHider.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangHighlights.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangManager.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinWorld.java (limited to 'src/main') 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() + private val maxHealthMap = mutableMapOf() private val nametagCache = TimeLimitedCache(50.milliseconds) private val healthDisplayCache = TimeLimitedCache(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()) { + for (entity in EntityUtils.getEntities()) { // 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) { + 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 @@ -103,11 +103,6 @@ object MobData { notSeenMobs.remove(event.mob) } - @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(val entity: T) : GenericSkyHanniEvent(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() - private var blazeArmorStand = mapOf() - - private var nearAshfang = false - - @SubscribeEvent - fun onSecondPassed(event: SecondPassedEvent) { - if (!isEnabled()) return - - checkNearAshfang() - - if (nearAshfang) { - for (entity in EntityUtils.getEntities() - .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().any { it.name.contains("Ashfang") } - } - - @SubscribeEvent(priority = EventPriority.HIGH) - fun onRenderLiving(event: SkyHanniRenderEntityEvent.Specials.Pre) { - 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() - - @SubscribeEvent - fun onTick(event: LorenzTickEvent) { - if (!isEnabled()) return - - EntityUtils.getEntities() - .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() - - @SubscribeEvent - fun onTick(event: LorenzTickEvent) { - if (!isEnabled()) return - - EntityUtils.getEntities() - .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) { - 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) { + 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() + private val gravityOrbs = mutableSetOf() + private const val MAX_DISTANCE = 15.0 + + @HandleEvent(onlyOnSkyblock = true, onlyOnIsland = IslandType.CRIMSON_ISLE) + fun onEntityJoin(event: EntityEnterWorldEvent) { + 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) { + 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() + 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) { + 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().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 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, -- cgit