From ad9aea3e82ff91e949e6068c540a3c6c0b69a53a Mon Sep 17 00:00:00 2001 From: Lorenz Date: Sat, 6 Aug 2022 22:59:00 +0200 Subject: adding damage indicator for nether bosses --- .../dungeon/damageindicator/BossDamageIndicator.kt | 77 +++++++++++++++------- .../skyhanni/dungeon/damageindicator/BossFinder.kt | 57 ++++++++++++---- .../skyhanni/dungeon/damageindicator/BossType.kt | 17 +++++ .../skyhanni/dungeon/damageindicator/EntityData.kt | 13 +++- .../dungeon/damageindicator/EntityResult.kt | 7 +- 5 files changed, 134 insertions(+), 37 deletions(-) create mode 100644 src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossType.kt (limited to 'src') diff --git a/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossDamageIndicator.kt b/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossDamageIndicator.kt index 3e09fa816..002bd6e2d 100644 --- a/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossDamageIndicator.kt +++ b/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossDamageIndicator.kt @@ -24,7 +24,7 @@ import kotlin.math.max class BossDamageIndicator { - var data = mutableMapOf() + var data = mutableMapOf() private var bossFinder: BossFinder? = null private val decimalFormat = DecimalFormat("0.0") private val maxHealth = mutableMapOf() @@ -32,6 +32,7 @@ class BossDamageIndicator { @SubscribeEvent fun onDungeonStart(event: WorldEvent.Load) { bossFinder = BossFinder() + data.clear() } @SubscribeEvent(receiveCanceled = true) @@ -49,7 +50,7 @@ class BossDamageIndicator { val player = Minecraft.getMinecraft().thePlayer for (data in data.values) { - if (System.currentTimeMillis() > data.time + 100) continue//TODO use removeIf + if (System.currentTimeMillis() > data.timeLastTick + 100) continue//TODO use removeIf if (!data.ignoreBlocks) { if (!player.canEntityBeSeen(data.entity)) continue } @@ -98,15 +99,12 @@ class BossDamageIndicator { fun onRenderLivingPost(event: RenderLivingEvent.Post<*>) { try { val entity = event.entity - val result = bossFinder?.shouldShow(entity) ?: return + val entityData = grabData(entity) ?: return if (LorenzUtils.inDungeons) { - checkLastBossDead(result.finalBoss, entity.entityId) + checkFinalBoss(entityData.finalDungeonBoss, entity.entityId) } - val ignoreBlocks = result.ignoreBlocks - val delayedStart = result.delayedStart - - var health = event.entity.health.toInt() + var health = entity.health.toInt() val maxHealth: Int if (DungeonData.isOneOf("F4")) { val hitPoints = when (health) { @@ -158,31 +156,64 @@ class BossDamageIndicator { else -> LorenzColor.RED } - if (data.containsKey(entity)){ - val lastHealth = data[entity]!!.lastHealth - val diff = lastHealth - health + if (data.containsKey(entity.uniqueID)) { + val lastHealth = data[entity.uniqueID]!!.lastHealth + val diff = lastHealth - health if (diff != 0) { - LorenzUtils.chat("diff: $diff") + val bossType = entityData.bossType + if (bossType == BossType.NETHER_ASHFANG) { + if (diff < 0) { + val oldHealth = lastHealth / 1_000_000 + val newHealth = health / 1_000_000 + LorenzUtils.chat("§e§lAshfang healing: ${oldHealth}M -> ${newHealth}M") + } + } else if (bossType == BossType.NETHER_BLADESOUL) { + if (diff < 0) { + val oldHealth = lastHealth / 1_000_000 + val newHealth = health / 1_000_000 + val oldFormat = NumberUtil.format(oldHealth) + val newFormat = NumberUtil.format(newHealth) + LorenzUtils.chat("§e§lBladesoul healing: §a+12.5m §e(${oldFormat}M -> ${newFormat}M)") + } + } else if (bossType == BossType.NETHER_BARBARIAN_DUKE) { + if (diff < 0) { + val oldHealth = lastHealth / 1_000_000 + val newHealth = health / 1_000_000 + val oldFormat = NumberUtil.format(oldHealth) + val newFormat = NumberUtil.format(newHealth) + LorenzUtils.chat("§e§lBarbarian Duke healing: §a+12.5m §e(${oldFormat}M -> ${newFormat}M)") + } + } else { + LorenzUtils.chat("$bossType diff: $diff") + } } - } - data[entity] = EntityData( - entity, - health, - NumberUtil.format(health), - color, - System.currentTimeMillis(), - ignoreBlocks, - delayedStart - ) + entityData.lastHealth = health + entityData.text = NumberUtil.format(health) + entityData.color = color + entityData.timeLastTick = System.currentTimeMillis() + data[entity.uniqueID] = entityData } catch (e: Throwable) { e.printStackTrace() } } - private fun checkLastBossDead(finalBoss: Boolean, id: Int) { + private fun grabData(entity: EntityLivingBase): EntityData? { + if (data.contains(entity.uniqueID)) return data[entity.uniqueID] + + val entityResult = bossFinder?.tryAdd(entity) ?: return null + return EntityData( + entity, + entityResult.ignoreBlocks, + entityResult.delayedStart, + entityResult.finalDungeonBoss, + entityResult.bossType + ) + } + + private fun checkFinalBoss(finalBoss: Boolean, id: Int) { if (finalBoss) { DamageIndicatorFinalBossEvent(id).postAndCatch() } diff --git a/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossFinder.kt b/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossFinder.kt index 0806716cf..f192f41ff 100644 --- a/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossFinder.kt +++ b/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossFinder.kt @@ -11,10 +11,9 @@ import net.minecraft.client.Minecraft import net.minecraft.client.entity.EntityOtherPlayerMP import net.minecraft.entity.Entity import net.minecraft.entity.EntityLivingBase -import net.minecraft.entity.monster.EntityBlaze -import net.minecraft.entity.monster.EntityGhast -import net.minecraft.entity.monster.EntityGiantZombie -import net.minecraft.entity.monster.EntityGuardian +import net.minecraft.entity.item.EntityArmorStand +import net.minecraft.entity.monster.* +import net.minecraft.util.AxisAlignedBB import java.util.* class BossFinder { @@ -54,7 +53,7 @@ class BossFinder { private var floor6Sadan = false private var floor6SadanSpawnTime = 0L - internal fun shouldShow(entity: EntityLivingBase): EntityResult? { + internal fun tryAdd(entity: EntityLivingBase): EntityResult? { if (LorenzUtils.inDungeons) { if (DungeonData.isOneOf("F1", "M1")) { if (floor1bonzo1) { @@ -67,7 +66,7 @@ class BossFinder { if (floor1bonzo2) { if (entity is EntityOtherPlayerMP) { if (entity.name == "Bonzo ") { - return EntityResult(floor1bonzo2SpawnTime, finalBoss = true) + return EntityResult(floor1bonzo2SpawnTime, finalDungeonBoss = true) } } } @@ -96,7 +95,7 @@ class BossFinder { //TODO only show scarf after (all/at least x) summons are dead? val result = entity.name == "Scarf " if (result) { - return EntityResult(floor2secondPhaseSpawnTime, finalBoss = true) + return EntityResult(floor2secondPhaseSpawnTime, finalDungeonBoss = true) } } } @@ -144,7 +143,7 @@ class BossFinder { if (entity is EntityGuardian) { if (floor3ProfessorGuardian) { if (entity == floor3ProfessorGuardianEntity) { - return EntityResult(finalBoss = true) + return EntityResult(finalDungeonBoss = true) } } } @@ -156,7 +155,7 @@ class BossFinder { //TODO add m4 support LorenzTest.enabled = true LorenzTest.text = "thorn has $health hp!" - return EntityResult(ignoreBlocks = true, finalBoss = true) + return EntityResult(ignoreBlocks = true, finalDungeonBoss = true) } } @@ -164,7 +163,7 @@ class BossFinder { if (DungeonData.isOneOf("F5", "M5")) { if (entity is EntityOtherPlayerMP) { if (entity == floor5lividEntity) { - return EntityResult(floor5lividEntitySpawnTime, true, finalBoss = true) + return EntityResult(floor5lividEntitySpawnTime, true, finalDungeonBoss = true) } } } @@ -180,10 +179,35 @@ class BossFinder { } if (floor6Sadan) { - return EntityResult(floor6SadanSpawnTime, finalBoss = true) + return EntityResult(floor6SadanSpawnTime, finalDungeonBoss = true) } } } + } else { + + if (entity is EntityBlaze) { + if (entity.name != "Dinnerbone") { + if (entity.hasNameTagWith(0, 2, 0, "§e﴾ §8[§7Lv200§8] §l§8§lAshfang§r ")) { + if (entity.baseMaxHealth == 50_000_000.0) { + return EntityResult(bossType = BossType.NETHER_ASHFANG) + } + } + } + } + if (entity is EntitySkeleton) { + if (entity.hasNameTagWith(0, 5, 0, "§e﴾ §8[§7Lv200§8] §l§8§lBladesoul§r ")) { + return EntityResult(bossType = BossType.NETHER_BLADESOUL) + } + } + if (entity is EntityOtherPlayerMP) { + if (entity.name == "Mage Outlaw") { + return EntityResult(bossType = BossType.NETHER_MAGE_OUTLAW) + } + if (entity.name == "DukeBarb ") { + return EntityResult(bossType = BossType.NETHER_BARBARIAN_DUKE) + } + } + } return null @@ -384,4 +408,13 @@ class BossFinder { return null } -} \ No newline at end of file +} + +private fun EntityMob.hasNameTagWith(x: Int, y: Int, z: Int, startName: String): Boolean { + val center = getLorenzVec().add(x, y, z) + val a = center.add(-1.6, -1.6, -1.6).toBlocPos() + val b = center.add(1.6, 1.6, 1.6).toBlocPos() + val alignedBB = AxisAlignedBB(a, b) + val clazz = EntityArmorStand::class.java + return worldObj.getEntitiesWithinAABB(clazz, alignedBB).any { it.name.startsWith(startName) } +} diff --git a/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossType.kt b/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossType.kt new file mode 100644 index 000000000..5ed9bf38f --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossType.kt @@ -0,0 +1,17 @@ +package at.hannibal2.skyhanni.dungeon.damageindicator + +enum class BossType { + DUNGEON, + +// CRIMSON_AILE_BLADESOUL, + NETHER_BLADESOUL, + NETHER_MAGMA_BOSS, + NETHER_ASHFANG, + NETHER_BARBARIAN_DUKE, + NETHER_MAGE_OUTLAW,//TODO add real name + + END_ENDER_DRAGON, + END_OBSIDIAN_DEFENDER, + END_VOIDGLOOM_SLAYER_4 + +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/EntityData.kt b/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/EntityData.kt index 321addb8d..4c66d77a7 100644 --- a/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/EntityData.kt +++ b/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/EntityData.kt @@ -3,4 +3,15 @@ package at.hannibal2.skyhanni.dungeon.damageindicator import at.hannibal2.skyhanni.utils.LorenzColor import net.minecraft.entity.EntityLivingBase -class EntityData(val entity: EntityLivingBase, val text: String, val color: LorenzColor, val time: Long, val ignoreBlocks: Boolean, val delayedStart: Long) \ No newline at end of file +class EntityData( + val entity: EntityLivingBase, + val ignoreBlocks: Boolean, + val delayedStart: Long, + val finalDungeonBoss: Boolean, + val bossType: BossType = BossType.DUNGEON, + + var lastHealth: Int = 0, + var text: String = "", + var color: LorenzColor = LorenzColor.DARK_GREEN, + var timeLastTick: Long = 0, +) \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/EntityResult.kt b/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/EntityResult.kt index 1831ebe70..521e923b1 100644 --- a/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/EntityResult.kt +++ b/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/EntityResult.kt @@ -1,3 +1,8 @@ package at.hannibal2.skyhanni.dungeon.damageindicator -class EntityResult(val delayedStart: Long = -1L, val ignoreBlocks: Boolean = false, val finalBoss: Boolean = false) \ No newline at end of file +class EntityResult( + val delayedStart: Long = -1L, + val ignoreBlocks: Boolean = false, + val finalDungeonBoss: Boolean = false, + val bossType: BossType = BossType.DUNGEON, +) \ No newline at end of file -- cgit