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 --- .../java/at/hannibal2/skyhanni/SkyHanniMod.java | 2 +- .../skyhanni/config/features/Dungeon.java | 5 - .../hannibal2/skyhanni/config/features/Misc.java | 5 + .../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 + .../dungeon/damageindicator/BossDamageIndicator.kt | 349 ---------------- .../skyhanni/dungeon/damageindicator/BossFinder.kt | 455 --------------------- .../skyhanni/dungeon/damageindicator/BossType.kt | 21 - .../skyhanni/dungeon/damageindicator/EntityData.kt | 18 - .../dungeon/damageindicator/EntityResult.kt | 8 - 13 files changed, 857 insertions(+), 857 deletions(-) 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 delete mode 100644 src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossDamageIndicator.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossFinder.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossType.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/EntityData.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/EntityResult.kt (limited to 'src/main/java/at') diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java index 2a8a76631..d9724877c 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java @@ -10,7 +10,7 @@ import at.hannibal2.skyhanni.chat.PlayerChatFilter; import at.hannibal2.skyhanni.config.Features; import at.hannibal2.skyhanni.config.gui.commands.Commands; import at.hannibal2.skyhanni.dungeon.*; -import at.hannibal2.skyhanni.dungeon.damageindicator.BossDamageIndicator; +import at.hannibal2.skyhanni.damageindicator.BossDamageIndicator; import at.hannibal2.skyhanni.features.abilities.AshfangFreezeCooldown; import at.hannibal2.skyhanni.fishing.SeaCreatureManager; import at.hannibal2.skyhanni.fishing.SeaCreatureMessageShortener; diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Dungeon.java b/src/main/java/at/hannibal2/skyhanni/config/features/Dungeon.java index 8217c71a9..7be3f6902 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/Dungeon.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/Dungeon.java @@ -13,11 +13,6 @@ public class Dungeon { @ConfigEditorBoolean public boolean highlightClickedBlocks = false; - @Expose - @ConfigOption(name = "Boss Damage Indicator", desc = "Show the missing health of a boss in the dungeon and the cooldown time until the boss becomes attackable.") - @ConfigEditorBoolean - public boolean bossDamageIndicator = false; - @Expose @ConfigOption(name = "Milestone Display", desc = "Show the current milestone inside Dungeons.") @ConfigEditorBoolean diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java b/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java index 82268e2aa..dcaf6a259 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java @@ -8,6 +8,11 @@ import com.google.gson.annotations.Expose; public class Misc { + @Expose + @ConfigOption(name = "Boss Damage Indicator", desc = "Show the missing health of a boss in the dungeon, of slayer bosses and other bosses and the cooldown time until the boss becomes attackable.") + @ConfigEditorBoolean + public boolean bossDamageIndicator = false; + @Expose @ConfigOption(name = "Pet Display", desc = "Show the currently active pet.") @ConfigEditorBoolean 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 diff --git a/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossDamageIndicator.kt b/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossDamageIndicator.kt deleted file mode 100644 index 4978bd6d2..000000000 --- a/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossDamageIndicator.kt +++ /dev/null @@ -1,349 +0,0 @@ -package at.hannibal2.skyhanni.dungeon.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 onDungeonStart(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.dungeon.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/dungeon/damageindicator/BossFinder.kt b/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossFinder.kt deleted file mode 100644 index c0173d2a5..000000000 --- a/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossFinder.kt +++ /dev/null @@ -1,455 +0,0 @@ -package at.hannibal2.skyhanni.dungeon.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/dungeon/damageindicator/BossType.kt b/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossType.kt deleted file mode 100644 index 52f24fd52..000000000 --- a/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/BossType.kt +++ /dev/null @@ -1,21 +0,0 @@ -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, - - 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/dungeon/damageindicator/EntityData.kt b/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/EntityData.kt deleted file mode 100644 index f073045b8..000000000 --- a/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/EntityData.kt +++ /dev/null @@ -1,18 +0,0 @@ -package at.hannibal2.skyhanni.dungeon.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/dungeon/damageindicator/EntityResult.kt b/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/EntityResult.kt deleted file mode 100644 index 521e923b1..000000000 --- a/src/main/java/at/hannibal2/skyhanni/dungeon/damageindicator/EntityResult.kt +++ /dev/null @@ -1,8 +0,0 @@ -package at.hannibal2.skyhanni.dungeon.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