From 336266ad88396d8df795f7a429174c5a010c1658 Mon Sep 17 00:00:00 2001 From: Lorenz Date: Sun, 7 Aug 2022 03:35:42 +0200 Subject: moved damage indicator classes outside of dungeon --- .../damageindicator/BossDamageIndicator.kt | 349 ++++++++++++++++ .../skyhanni/damageindicator/BossFinder.kt | 455 +++++++++++++++++++++ .../hannibal2/skyhanni/damageindicator/BossType.kt | 21 + .../skyhanni/damageindicator/EntityData.kt | 18 + .../skyhanni/damageindicator/EntityResult.kt | 8 + 5 files changed, 851 insertions(+) create mode 100644 src/main/java/at/hannibal2/skyhanni/damageindicator/BossDamageIndicator.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/damageindicator/BossFinder.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/damageindicator/BossType.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/damageindicator/EntityData.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/damageindicator/EntityResult.kt (limited to 'src/main/java/at/hannibal2/skyhanni/damageindicator') diff --git a/src/main/java/at/hannibal2/skyhanni/damageindicator/BossDamageIndicator.kt b/src/main/java/at/hannibal2/skyhanni/damageindicator/BossDamageIndicator.kt new file mode 100644 index 000000000..09032b6c3 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/damageindicator/BossDamageIndicator.kt @@ -0,0 +1,349 @@ +package at.hannibal2.skyhanni.damageindicator + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.dungeon.DungeonData +import at.hannibal2.skyhanni.events.DamageIndicatorFinalBossEvent +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.utils.* +import at.hannibal2.skyhanni.utils.LorenzUtils.baseMaxHealth +import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.GlStateManager +import net.minecraft.entity.EntityLivingBase +import net.minecraft.entity.monster.EntityEnderman +import net.minecraft.util.Vec3 +import net.minecraftforge.client.event.RenderWorldLastEvent +import net.minecraftforge.event.entity.EntityJoinWorldEvent +import net.minecraftforge.event.world.WorldEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent +import java.text.DecimalFormat +import java.util.* +import kotlin.math.max + +class BossDamageIndicator { + + var data = mutableMapOf() + private var bossFinder: BossFinder? = null + private val decimalFormat = DecimalFormat("0.0") + private val maxHealth = mutableMapOf() + + @SubscribeEvent + fun onWorldLoad(event: WorldEvent.Load) { + bossFinder = BossFinder() + data.clear() + } + + @SubscribeEvent(receiveCanceled = true) + fun onChatMessage(event: LorenzChatEvent) { + bossFinder?.handleChat(event.message) + } + + @SubscribeEvent + fun onWorldRender(event: RenderWorldLastEvent) { + if (!SkyHanniMod.feature.misc.bossDamageIndicator) return + + GlStateManager.disableDepth() + GlStateManager.disableCull() + + val player = Minecraft.getMinecraft().thePlayer + + for (uuid in data.filter { System.currentTimeMillis() > it.value.timeLastTick + 100 }.map { it.key }) { + data.remove(uuid) + } + + for (data in data.values) { + if (!data.ignoreBlocks) { + if (!player.canEntityBeSeen(data.entity)) continue + } + if (data.hidden) continue + + val entity = data.entity + + var color = data.color + var text = data.text + val delayedStart = data.delayedStart + if (delayedStart != -1L) { + if (delayedStart > System.currentTimeMillis()) { + val delay = delayedStart - System.currentTimeMillis() + color = colorForTime(delay) + var d = delay * 1.0 + d /= 1000 + text = decimalFormat.format(d) + } + } + + val partialTicks = event.partialTicks + RenderUtils.drawLabel( + Vec3( + RenderUtils.interpolate(entity.posX, entity.lastTickPosX, partialTicks), + RenderUtils.interpolate(entity.posY, entity.lastTickPosY, partialTicks) + 0.5f, + RenderUtils.interpolate(entity.posZ, entity.lastTickPosZ, partialTicks) + ), + text, + color.toColor(), + partialTicks, + true, + 6f + ) + } + GlStateManager.enableDepth() + GlStateManager.enableCull() + } + + private fun colorForTime(delayedStart: Long): LorenzColor = when { + delayedStart < 1_000 -> LorenzColor.DARK_PURPLE + delayedStart < 3_000 -> LorenzColor.LIGHT_PURPLE + + else -> LorenzColor.WHITE + } + + @SubscribeEvent + fun onTickEvent(event: TickEvent.ClientTickEvent) { + if (!LorenzUtils.inSkyblock) return + for (entity in Minecraft.getMinecraft().theWorld.loadedEntityList) { + if (entity is EntityLivingBase) { + checkEntity(entity) + } + } + } + + private fun checkEntity(entity: EntityLivingBase) { + try { + val entityData = grabData(entity) ?: return + if (LorenzUtils.inDungeons) { + checkFinalBoss(entityData.finalDungeonBoss, entity.entityId) + } + + val biggestHealth = getMaxHealthFor(entity) + + val health = entity.health.toInt() + val maxHealth: Int + + if (biggestHealth == 0) { + val currentMaxHealth = entity.baseMaxHealth.toInt() + maxHealth = max(currentMaxHealth, health) + setMaxHealth(entity, maxHealth) + } else { + maxHealth = biggestHealth + } + + var calcHealth = health + var calcMaxHealth = maxHealth + var extraPrefix = "" + + if (DungeonData.isOneOf("F4")) { + calcHealth = when (health) { + 300_000 -> 4 + 222_000 -> 3 + 144_000 -> 2 + 66_000 -> 1 + else -> { + LorenzUtils.error("Unexpected health of thorn in F4! ($health)") + return + } + } + calcMaxHealth = 4 + //TODO add m4 support +// } else if (DungeonData.isOneOf("M4")) { +// calcHealth = when (health) { +// 300_000 -> 4 +// 222_000 -> 3 +// 144_000 -> 2 +// 66_000 -> 1 +// else -> { +// LorenzUtils.error("Unexpected health of thorn in F4! ($health)") +// return +// } +// } +// calcMaxHealth = 4 + } + + + if (entityData.bossType == BossType.END_ENDERMAN_SLAYER) { + //custom prefix and health for the four different ender slayers + when (maxHealth) { + 300_000 -> { + calcMaxHealth = 100_000 + if (health > 200_000) { + calcHealth -= 200_000 + extraPrefix = "1/3" + } else if (health > 100_000) { + calcHealth -= 100_000 + extraPrefix = "2/3" + } else { + calcHealth = health + extraPrefix = "3/3" + } + } + 15_000_000 -> { + calcMaxHealth = 5_000_000 + if (health > 10_000_000) { + extraPrefix = "1/3" + calcHealth -= 10_000_000 + } else if (health > 5_000_000) { + calcHealth -= 5_000_000 + extraPrefix = "2/3" + } else { + calcHealth = health + extraPrefix = "3/3" + } + } + 66_666_666 -> { + calcMaxHealth = 22_222_222 + if (health > 44_444_444) { + calcHealth -= 44_444_444 + extraPrefix = "1/3" + } else if (health > 22_222_222) { + calcHealth -= 22_222_222 + extraPrefix = "2/3" + } else { + calcHealth = health + extraPrefix = "3/3" + } + + } + 300_000_000 -> { + calcMaxHealth = 50_000_000 + if (health > 250_000_000) { + calcHealth -= 250_000_000 + extraPrefix = "1/6" + } else if (health > 200_000_000) { + calcHealth -= 200_000_000 + extraPrefix = "2/6" + } else if (health > 150_000_000) { + calcHealth -= 150_000_000 + extraPrefix = "3/6" + } else if (health > 100_000_000) { + calcHealth -= 100_000_000 + extraPrefix = "4/6" + } else if (health > 50_000_000) { + calcHealth -= 50_000_000 + extraPrefix = "5/6" + } else { + calcHealth = health + extraPrefix = "6/6" + } + } + else -> { + //TODO this is a workaround, find a sweet solution pls? + if (!entityData.hidden) { + LorenzUtils.warning("§c[SkyHanni] Unknown max enderman health: $maxHealth") + entityData.hidden = true + } + + } + } + + //Hides the damage indicator when in hit phase or in laser phase + if (entity is EntityEnderman) { + var hidden = false + if (entity.hasNameTagWith(0, 3, 0, " Hit")) { + hidden = true + } + if (entity.ridingEntity != null) { + hidden = true + } + entityData.hidden = hidden + } + } + + //See through blocks when the barbarian duke stands on the platform and the player is below + if (entityData.bossType == BossType.NETHER_BARBARIAN_DUKE) { + val location = entity.getLorenzVec() + val y = location.y + var ignoreBlocks = false + val distance = Minecraft.getMinecraft().thePlayer.getLorenzVec().distance(location) + if (distance < 10) { + if (y == 117.0) { + ignoreBlocks = true + } + } + entityData.ignoreBlocks = ignoreBlocks + } + + val percentage = calcHealth.toDouble() / calcMaxHealth.toDouble() + val color = when { + percentage > 0.9 -> LorenzColor.DARK_GREEN + percentage > 0.75 -> LorenzColor.GREEN + percentage > 0.5 -> LorenzColor.YELLOW + percentage > 0.25 -> LorenzColor.GOLD + else -> LorenzColor.RED + } + + if (data.containsKey(entity.uniqueID)) { + val lastHealth = data[entity.uniqueID]!!.lastHealth + val diff = lastHealth - health + if (diff != 0) { + 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)") + } + //TODO check for revive buffs +// } else { +// LorenzUtils.chat("$bossType diff: $diff") + } + } + } + + entityData.lastHealth = health + entityData.text = extraPrefix + " " + NumberUtil.format(calcHealth) + entityData.color = color + entityData.timeLastTick = System.currentTimeMillis() + data[entity.uniqueID] = entityData + + } catch (e: Throwable) { + e.printStackTrace() + } + } + + 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() + } + } + + private fun setMaxHealth(entity: EntityLivingBase, currentMaxHealth: Int) { + maxHealth[entity.uniqueID!!] = currentMaxHealth + } + + private fun getMaxHealthFor(entity: EntityLivingBase): Int { + return maxHealth.getOrDefault(entity.uniqueID!!, 0) + } + + @SubscribeEvent + fun onWorldRender(event: EntityJoinWorldEvent) { + bossFinder?.handleNewEntity(event.entity) + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/damageindicator/BossFinder.kt b/src/main/java/at/hannibal2/skyhanni/damageindicator/BossFinder.kt new file mode 100644 index 000000000..4576afb73 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/damageindicator/BossFinder.kt @@ -0,0 +1,455 @@ +package at.hannibal2.skyhanni.damageindicator + +import at.hannibal2.skyhanni.dungeon.DungeonData +import at.hannibal2.skyhanni.test.LorenzTest +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.baseMaxHealth +import at.hannibal2.skyhanni.utils.LorenzUtils.matchRegex +import at.hannibal2.skyhanni.utils.LorenzVec +import at.hannibal2.skyhanni.utils.getLorenzVec +import net.minecraft.client.Minecraft +import net.minecraft.client.entity.EntityOtherPlayerMP +import net.minecraft.entity.Entity +import net.minecraft.entity.EntityLiving +import net.minecraft.entity.EntityLivingBase +import net.minecraft.entity.boss.EntityDragon +import net.minecraft.entity.boss.EntityWither +import net.minecraft.entity.item.EntityArmorStand +import net.minecraft.entity.monster.* +import net.minecraft.util.AxisAlignedBB +import java.util.* + +class BossFinder { + + //F1 + private var floor1bonzo1 = false + private var floor1bonzo1SpawnTime = 0L + private var floor1bonzo2 = false + private var floor1bonzo2SpawnTime = 0L + + //F2 + private var floor2summons1 = false + private var floor2summons1SpawnTime = 0L + private var floor2summonsDiedOnce = mutableListOf() + private var floor2secondPhase = false + private var floor2secondPhaseSpawnTime = 0L + + //F3 + private var floor3GuardianShield = false + private var floor3GuardianShieldSpawnTime = 0L + private var guardians = mutableListOf() + private var floor3Professor = false + private var floor3ProfessorSpawnTime = 0L + private var floor3ProfessorGuardianPrepare = false + private var floor3ProfessorGuardianPrepareSpawnTime = 0L + private var floor3ProfessorGuardian = false + private var floor3ProfessorGuardianEntity: EntityGuardian? = null + + //F5 + private var floor5lividEntity: EntityOtherPlayerMP? = null + private var floor5lividEntitySpawnTime = 0L + + //F6 + private var floor6Giants = false + private var floor6GiantsSpawnTime = 0L + private var floor6GiantsSeparateDelay = mutableMapOf() + private var floor6Sadan = false + private var floor6SadanSpawnTime = 0L + + internal fun tryAdd(entity: EntityLivingBase): EntityResult? { + if (LorenzUtils.inDungeons) { + if (DungeonData.isOneOf("F1", "M1")) { + if (floor1bonzo1) { + if (entity is EntityOtherPlayerMP) { + if (entity.name == "Bonzo ") { + return EntityResult(floor1bonzo1SpawnTime) + } + } + } + if (floor1bonzo2) { + if (entity is EntityOtherPlayerMP) { + if (entity.name == "Bonzo ") { + return EntityResult(floor1bonzo2SpawnTime, finalDungeonBoss = true) + } + } + } + } + + if (DungeonData.isOneOf("F2", "M2")) { + if (entity.name == "Summon ") { + if (entity is EntityOtherPlayerMP) { + if (floor2summons1) { + if (!floor2summonsDiedOnce.contains(entity)) { + if (entity.health.toInt() != 0) { + return EntityResult(floor2summons1SpawnTime) + } else { + floor2summonsDiedOnce.add(entity) + } + } + } + if (floor2secondPhase) { + return EntityResult(floor2secondPhaseSpawnTime) + } + } + } + + if (floor2secondPhase) { + if (entity is EntityOtherPlayerMP) { + //TODO only show scarf after (all/at least x) summons are dead? + val result = entity.name == "Scarf " + if (result) { + return EntityResult(floor2secondPhaseSpawnTime, finalDungeonBoss = true) + } + } + } + } + + if (DungeonData.isOneOf("F3", "M3")) { + if (entity is EntityGuardian) { + if (floor3GuardianShield) { + if (guardians.size == 4) { + var totalHealth = 0 + for (guardian in guardians) { + totalHealth += guardian.health.toInt() + } + if (totalHealth == 0) { + floor3GuardianShield = false + guardians.clear() + } + } else { + findGuardians() + } + if (guardians.contains(entity)) { + return EntityResult(floor3GuardianShieldSpawnTime, true) + } + } + } + + if (floor3Professor) { + if (entity is EntityOtherPlayerMP) { + if (entity.name == "The Professor") { + return EntityResult( + floor3ProfessorSpawnTime, + floor3ProfessorSpawnTime + 1_000 > System.currentTimeMillis() + ) + } + } + } + if (floor3ProfessorGuardianPrepare) { + if (entity is EntityOtherPlayerMP) { + if (entity.name == "The Professor") { + return EntityResult(floor3ProfessorGuardianPrepareSpawnTime, true) + } + } + } + + if (entity is EntityGuardian) { + if (floor3ProfessorGuardian) { + if (entity == floor3ProfessorGuardianEntity) { + return EntityResult(finalDungeonBoss = true) + } + } + } + } + + if (DungeonData.isOneOf("F4", "M4")) { + if (entity is EntityGhast) { + val health = LorenzUtils.formatDouble(entity.health.toDouble()) + //TODO add m4 support + LorenzTest.enabled = true + LorenzTest.text = "thorn has $health hp!" + return EntityResult(ignoreBlocks = true, finalDungeonBoss = true) + } + + } + + if (DungeonData.isOneOf("F5", "M5")) { + if (entity is EntityOtherPlayerMP) { + if (entity == floor5lividEntity) { + return EntityResult(floor5lividEntitySpawnTime, true, finalDungeonBoss = true) + } + } + } + + if (DungeonData.isOneOf("F6", "M6")) { + if (entity is EntityGiantZombie && !entity.isInvisible) { + if (floor6Giants && entity.posY > 68) { + val extraDelay = checkExtraF6GiantsDelay(entity) + return EntityResult( + floor6GiantsSpawnTime + extraDelay, + floor6GiantsSpawnTime + extraDelay + 1_000 > System.currentTimeMillis() + ) + } + + if (floor6Sadan) { + 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) + } + } + + //TODO testing and make right and so + if (entity is EntityWither) { + if (entity.hasNameTagWith(0, 4, 0, "§8[§7Lv100§8] §c§5Vanquisher§r ")) { + return EntityResult(bossType = BossType.NETHER_VANQUISHER) + } + } + + if (entity is EntityEnderman) { + if (entity.hasNameTagWith(0, 3, 0, "§c☠ §bVoidgloom Seraph ")) { + return EntityResult(bossType = BossType.END_ENDERMAN_SLAYER) + } + } + + if (entity is EntityDragon) { + //TODO testing and make right and so + return EntityResult(bossType = BossType.END_ENDER_DRAGON) + } + + if (entity is EntityIronGolem) { + //TODO testing + if (entity.hasNameTagWith(0, 3, 0, "§e﴾ §8[§7Lv100§8] §lEndstone Protector§r ")) { + return EntityResult(bossType = BossType.END_ENDSTONE_PROTECTOR, ignoreBlocks = true) + } + } + + if (entity is EntityZombie) { + if (entity.hasNameTagWith(0, 2, 0, "§c☠ §fAtoned Horror ")) { + if (entity.baseMaxHealth == 10_000_000.0) { + return EntityResult(bossType = BossType.HUB_REVENANT_HORROR) + } + } + } + } + + return null + } + + private fun checkExtraF6GiantsDelay(entity: EntityGiantZombie): Long { + val uuid = entity.uniqueID + + if (floor6GiantsSeparateDelay.contains(uuid)) { + return floor6GiantsSeparateDelay[uuid]!! + } + + val middle = LorenzVec(-8, 0, 56) + + val loc = entity.getLorenzVec() + + var pos = 0 + + //first + if (loc.x > middle.x && loc.z > middle.z) { + pos = 2 + } + + //second + if (loc.x > middle.x && loc.z < middle.z) { + pos = 3 + } + + //third + if (loc.x < middle.x && loc.z < middle.z) { + pos = 0 + } + + //fourth + if (loc.x < middle.x && loc.z > middle.z) { + pos = 1 + } + + val extraDelay = 900L * pos + floor6GiantsSeparateDelay[uuid] = extraDelay + + return extraDelay + } + + fun handleChat(message: String) { + if (LorenzUtils.inDungeons) { + when (message) { + //F1 + "§c[BOSS] Bonzo§r§f: Gratz for making it this far, but I’m basically unbeatable." -> { + floor1bonzo1 = true + floor1bonzo1SpawnTime = System.currentTimeMillis() + 11_250 + } + + "§c[BOSS] Bonzo§r§f: Oh noes, you got me.. what ever will I do?!" -> { + floor1bonzo1 = false + } + + "§c[BOSS] Bonzo§r§f: Oh I'm dead!" -> { + floor1bonzo2 = true + floor1bonzo2SpawnTime = System.currentTimeMillis() + 4_200 + } + + "§c[BOSS] Bonzo§r§f: Alright, maybe I'm just weak after all.." -> { + floor1bonzo2 = false + } + + //F2 + "§c[BOSS] Scarf§r§f: ARISE, MY CREATIONS!" -> { + floor2summons1 = true + floor2summons1SpawnTime = System.currentTimeMillis() + 3_500 + } + + "§c[BOSS] Scarf§r§f: Those toys are not strong enough I see." -> { + floor2summons1 = false + } + + "§c[BOSS] Scarf§r§f: Don't get too excited though." -> { + floor2secondPhase = true + floor2secondPhaseSpawnTime = System.currentTimeMillis() + 6_300 + } + + "§c[BOSS] Scarf§r§f: Whatever..." -> { + floor2secondPhase = false + } + + //F3 + "§c[BOSS] The Professor§r§f: I was burdened with terrible news recently..." -> { + floor3GuardianShield = true + floor3GuardianShieldSpawnTime = System.currentTimeMillis() + 16_400 + } + + "§c[BOSS] The Professor§r§f: Even if you took my barrier down, I can still fight." -> { + floor3GuardianShield = false + } + + "§c[BOSS] The Professor§r§f: Oh? You found my Guardians one weakness?" -> { + floor3Professor = true + floor3ProfessorSpawnTime = System.currentTimeMillis() + 10_300 + } + + "§c[BOSS] The Professor§r§f: I see. You have forced me to use my ultimate technique." -> { + floor3Professor = false + + floor3ProfessorGuardianPrepare = true + floor3ProfessorGuardianPrepareSpawnTime = System.currentTimeMillis() + 10_500 + } + + "§c[BOSS] The Professor§r§f: The process is irreversible, but I'll be stronger than a Wither now!" -> { + floor3ProfessorGuardian = true + } + + "§c[BOSS] The Professor§r§f: What?! My Guardian power is unbeatable!" -> { + floor3ProfessorGuardian = false + } + + + //F5 + "§c[BOSS] Livid§r§f: This Orb you see, is Thorn, or what is left of him." -> { + floor5lividEntity = findLivid() + floor5lividEntitySpawnTime = System.currentTimeMillis() + 13_000 + } + + //F6 + "§c[BOSS] Sadan§r§f: ENOUGH!" -> { + floor6Giants = true + floor6GiantsSpawnTime = System.currentTimeMillis() + 7_400 + } + + "§c[BOSS] Sadan§r§f: You did it. I understand now, you have earned my respect." -> { + floor6Giants = false + floor6Sadan = true + floor6SadanSpawnTime = System.currentTimeMillis() + 32_500 + } + + "§c[BOSS] Sadan§r§f: NOOOOOOOOO!!! THIS IS IMPOSSIBLE!!" -> { + floor6Sadan = false + } + } + + if (message.matchRegex("§c\\[BOSS] (.*) Livid§r§f: Impossible! How did you figure out which one I was\\?!")) { + floor5lividEntity = null + } + } + } + + fun handleNewEntity(entity: Entity) { + if (LorenzUtils.inDungeons) { + if (floor3ProfessorGuardian) { + if (entity is EntityGuardian) { + if (floor3ProfessorGuardianEntity == null) { + floor3ProfessorGuardianEntity = entity + floor3ProfessorGuardianPrepare = false + } + } + } + } + } + + private fun findGuardians() { + guardians.clear() + + for (entity in Minecraft.getMinecraft().theWorld.loadedEntityList) { + if (entity is EntityGuardian) { + + val maxHealth = entity.baseMaxHealth.toInt() + + //F3 + if (maxHealth == 1_000_000 || maxHealth == 1_200_000) { + guardians.add(entity) + } + + //F3 Derpy + if (maxHealth == 2_000_000 || maxHealth == 2_400_000) { + guardians.add(entity) + } + + //M3 + if (maxHealth == 240_000_000 || maxHealth == 280_000_000) { + guardians.add(entity) + } + + //M3 Derpy + if (maxHealth == 120_000_000 || maxHealth == 140_000_000) { + guardians.add(entity) + } + } + } + } + + private fun findLivid(): EntityOtherPlayerMP? { + for (entity in Minecraft.getMinecraft().theWorld.loadedEntityList) { + if (entity is EntityOtherPlayerMP) { + if (entity.name == "Livid ") { + return entity + } + } + } + + return null + } +} + +fun EntityLiving.hasNameTagWith(x: Int, y: Int, z: Int, contains: 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.contains(contains) } +} diff --git a/src/main/java/at/hannibal2/skyhanni/damageindicator/BossType.kt b/src/main/java/at/hannibal2/skyhanni/damageindicator/BossType.kt new file mode 100644 index 000000000..889b0d674 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/damageindicator/BossType.kt @@ -0,0 +1,21 @@ +package at.hannibal2.skyhanni.damageindicator + +enum class BossType { + DUNGEON, + +// CRIMSON_AILE_BLADESOUL, + NETHER_BLADESOUL, + NETHER_MAGMA_BOSS, + NETHER_ASHFANG, + NETHER_BARBARIAN_DUKE, + NETHER_MAGE_OUTLAW, + + NETHER_VANQUISHER, + + END_ENDSTONE_PROTECTOR, + END_ENDERMAN_SLAYER, + END_ENDER_DRAGON, + + HUB_REVENANT_HORROR + +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/damageindicator/EntityData.kt b/src/main/java/at/hannibal2/skyhanni/damageindicator/EntityData.kt new file mode 100644 index 000000000..ffbe00a87 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/damageindicator/EntityData.kt @@ -0,0 +1,18 @@ +package at.hannibal2.skyhanni.damageindicator + +import at.hannibal2.skyhanni.utils.LorenzColor +import net.minecraft.entity.EntityLivingBase + +class EntityData( + val entity: EntityLivingBase, + var 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, + var hidden: Boolean = false +) \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/damageindicator/EntityResult.kt b/src/main/java/at/hannibal2/skyhanni/damageindicator/EntityResult.kt new file mode 100644 index 000000000..e2f8e9e69 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/damageindicator/EntityResult.kt @@ -0,0 +1,8 @@ +package at.hannibal2.skyhanni.damageindicator + +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