diff options
| author | Lorenz <lo.scherf@gmail.com> | 2022-08-17 03:05:34 +0200 |
|---|---|---|
| committer | Lorenz <lo.scherf@gmail.com> | 2022-08-17 03:05:34 +0200 |
| commit | efbf06263d6fbf5de5a815fe5583ddd02710470f (patch) | |
| tree | cb56d5969f8bebf586298475a61c521229663fda /src/main/java/at/hannibal2/skyhanni/features/damageindicator | |
| parent | 9b8ff26e84dda348685fe1306abed7457b63f7e3 (diff) | |
| download | SkyHanni-efbf06263d6fbf5de5a815fe5583ddd02710470f.tar.gz SkyHanni-efbf06263d6fbf5de5a815fe5583ddd02710470f.tar.bz2 SkyHanni-efbf06263d6fbf5de5a815fe5583ddd02710470f.zip | |
moving packets around
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/features/damageindicator')
7 files changed, 1227 insertions, 0 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/features/damageindicator/BossFinder.kt b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/BossFinder.kt new file mode 100644 index 000000000..a0895c753 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/BossFinder.kt @@ -0,0 +1,569 @@ +package at.hannibal2.skyhanni.features.damageindicator + +import at.hannibal2.skyhanni.features.dungeon.DungeonData +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.entity.passive.EntityHorse +import net.minecraft.entity.passive.EntityWolf +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<EntityOtherPlayerMP>() + private var floor2secondPhase = false + private var floor2secondPhaseSpawnTime = 0L + + //F3 + private var floor3GuardianShield = false + private var floor3GuardianShieldSpawnTime = 0L + private var guardians = mutableListOf<EntityGuardian>() + 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<UUID, Long>() + 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) { + return EntityResult(bossType = BossType.DUNGEON_F4_THORN, + 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 { + + val maxHealth = entity.baseMaxHealth.toInt() + if (entity is EntityBlaze) { + if (entity.name != "Dinnerbone") { + if (entity.hasNameTagWith(2, "§e﴾ §8[§7Lv200§8] §l§8§lAshfang§r ")) { + if (maxHealth == 50_000_000) { + return EntityResult(bossType = BossType.NETHER_ASHFANG) + } + //Derpy + if (maxHealth == 100_000_000) { + return EntityResult(bossType = BossType.NETHER_ASHFANG) + } + } + } + } + if (entity is EntitySkeleton) { + if (entity.hasNameTagWith(5, "§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) + } + } + if (entity is EntityWither) { + if (entity.hasNameTagWith(4, "§8[§7Lv100§8] §c§5Vanquisher§r ")) { + return EntityResult(bossType = BossType.NETHER_VANQUISHER) + } + } + if (entity is EntityEnderman) { + if (entity.hasNameTagWith(3, "§c☠ §bVoidgloom Seraph ")) { + when (maxHealth) { + 300_000, 600_000 -> { + return EntityResult(bossType = BossType.SLAYER_ENDERMAN_1) + } + 15_000_000, 30_000_000 -> { + return EntityResult(bossType = BossType.SLAYER_ENDERMAN_2) + } + 66_666_666, 66_666_666 * 2 -> { + return EntityResult(bossType = BossType.SLAYER_ENDERMAN_3) + } + 300_000_000, 600_000_000 -> { + return EntityResult(bossType = BossType.SLAYER_ENDERMAN_4) + } + } + } + } + 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(3, "§e﴾ §8[§7Lv100§8] §lEndstone Protector§r ")) { + return EntityResult(bossType = BossType.END_ENDSTONE_PROTECTOR, ignoreBlocks = true) + } + } + if (entity is EntityZombie) { + if (entity.hasNameTagWith(2, "§c☠ §bRevenant Horror")) { + when (maxHealth) { + 500, 1_000 -> { + return EntityResult(bossType = BossType.SLAYER_ZOMBIE_1) + } + 20_000, 40_000 -> { + return EntityResult(bossType = BossType.SLAYER_ZOMBIE_2) + } + 400_000, 800_000 -> { + return EntityResult(bossType = BossType.SLAYER_ZOMBIE_3) + } + 1_500_000, 3_000_000 -> { + return EntityResult(bossType = BossType.SLAYER_ZOMBIE_4) + } + } + } + if (entity.hasNameTagWith(2, "§c☠ §fAtoned Horror ")) { + if (maxHealth == 10_000_000 || maxHealth == 20_000_000) { + return EntityResult(bossType = BossType.SLAYER_ZOMBIE_5) + } + } + } + if (entity is EntityMagmaCube) { + if (entity.hasNameTagWith(15, "§e﴾ §8[§7Lv500§8] §l§4§lMagma Boss§r ")) { + if (maxHealth == 200_000_000) { + return EntityResult(bossType = BossType.NETHER_MAGMA_BOSS, ignoreBlocks = true) + } + //Derpy + if (maxHealth == 400_000_000) { + return EntityResult(bossType = BossType.NETHER_MAGMA_BOSS, ignoreBlocks = true) + } + } + } + if (entity is EntityHorse) { + if (entity.hasNameTagWith(15, "§8[§7Lv100§8] §c§6Headless Horseman§r ")) { + if (maxHealth == 3_000_000) { + return EntityResult(bossType = BossType.HUB_HEADLESS_HORSEMAN) + } + //Derpy + if (maxHealth == 6_000_000) { + return EntityResult(bossType = BossType.HUB_HEADLESS_HORSEMAN) + } + } + } + if (entity is EntityBlaze) { + if (entity.hasNameTagWith(2, "§c☠ §bInferno Demonlord ")) { + when (maxHealth) { + 2_500_000, 5_000_000 -> { + return EntityResult(bossType = BossType.SLAYER_BLAZE_1) + } + } + } + } + if (entity is EntitySpider) { + if (entity.hasNameTagWith(1, "§5☠ §4Tarantula Broodfather ")) { + when (maxHealth) { + 740, 1_500 -> { + return EntityResult(bossType = BossType.SLAYER_SPIDER_1) + } + 30_000, 60_000 -> { + return EntityResult(bossType = BossType.SLAYER_SPIDER_2) + } + 900_000, 1_800_000 -> { + return EntityResult(bossType = BossType.SLAYER_SPIDER_3) + } + 2_400_000, 4_800_000 -> { + return EntityResult(bossType = BossType.SLAYER_SPIDER_4) + } + } + } + } + if (entity is EntityWolf) { + if (entity.hasNameTagWith(1, "§c☠ §fSven Packmaster ")) { + when (maxHealth) { + 2_000, 4_000 -> { + return EntityResult(bossType = BossType.SLAYER_WOLF_1) + } + 40_000, 80_000 -> { + return EntityResult(bossType = BossType.SLAYER_WOLF_2) + } + 750_000, 1_500_000 -> { + return EntityResult(bossType = BossType.SLAYER_WOLF_3) + } + 2_000_000, 4_000_000 -> { + return EntityResult(bossType = BossType.SLAYER_WOLF_4) + } + } + } + } + } + + 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( + y: Int, + contains: String, + debugRightEntity: Boolean = false, + consumer: (EntityArmorStand) -> Unit = {}, + inaccuracy: Double = 1.6, + debugWrongEntity: Boolean = false, +): Boolean { + val center = getLorenzVec().add(0, y, 0) + val a = center.add(-inaccuracy, -inaccuracy - 3, -inaccuracy).toBlocPos() + val b = center.add(inaccuracy, inaccuracy + 3, inaccuracy).toBlocPos() + val alignedBB = AxisAlignedBB(a, b) + val clazz = EntityArmorStand::class.java + val found = worldObj.getEntitiesWithinAABB(clazz, alignedBB) + return found.any { + val result = it.name.contains(contains) + if (debugWrongEntity && !result) { + println("wrong entity in aabb: '" + it.name + "'") + } + if (debugRightEntity && result) { + println("mob: " + center.printWithAccuracy(2)) + println("nametag: " + it.getLorenzVec().printWithAccuracy(2)) + println("accuracy: " + it.getLorenzVec().subtract(center).printWithAccuracy(3)) + } + if (result) consumer(it) + result + } +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/damageindicator/BossType.kt b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/BossType.kt new file mode 100644 index 000000000..0bae4bbbd --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/BossType.kt @@ -0,0 +1,70 @@ +package at.hannibal2.skyhanni.features.damageindicator + +enum class BossType(val fullName: String, val bossTypeToggle: Int, val shortName: String = fullName) { + GENERIC_DUNGEON_BOSS("Generic Dungeon boss", 0),//TODO split into different bosses + + //Nether Mini Bosses + NETHER_BLADESOUL("§8Bladesoul", 1), + NETHER_MAGMA_BOSS("§4Magma Boss", 1), + NETHER_ASHFANG("§cAshfang", 1), + NETHER_BARBARIAN_DUKE("§eBarbarian Duke", 1), + NETHER_MAGE_OUTLAW("§5Mage Outlaw", 1), + + NETHER_VANQUISHER("§5Vanquisher", 2), + + END_ENDSTONE_PROTECTOR("§cEndstone Protector", 3), + END_ENDER_DRAGON("Ender Dragon", 4),//TODO fix totally + + SLAYER_ZOMBIE_1("§aRevenant Horror 1", 5, "§aRev 1"), + SLAYER_ZOMBIE_2("§eRevenant Horror 2", 5, "§eRev 2"), + SLAYER_ZOMBIE_3("§cRevenant Horror 3", 5, "§cRev 3"), + SLAYER_ZOMBIE_4("§4Revenant Horror 4", 5, "§4Rev 4"), + SLAYER_ZOMBIE_5("§5Revenant Horror 5", 5, "§5Rev 5"), + + SLAYER_SPIDER_1("§aTarantula Broodfather 1", 6, "§aTara 1"), + SLAYER_SPIDER_2("§eTarantula Broodfather 2", 6, "§eTara 2"), + SLAYER_SPIDER_3("§cTarantula Broodfather 3", 6, "§cTara 3"), + SLAYER_SPIDER_4("§4Tarantula Broodfather 4", 6, "§4Tara 4"), + + SLAYER_WOLF_1("§aSven Packmaster 1", 7, "§aSven 1"), + SLAYER_WOLF_2("§eSven Packmaster 2", 7, "§eSven 2"), + SLAYER_WOLF_3("§cSven Packmaster 3", 7, "§cSven 3"), + SLAYER_WOLF_4("§4Sven Packmaster 4", 7, "§4Sven 4"), + + SLAYER_ENDERMAN_1("§aVoidgloom Seraph 1", 8, "§aVoid 1"), + SLAYER_ENDERMAN_2("§eVoidgloom Seraph 2", 8, "§eVoid 2"), + SLAYER_ENDERMAN_3("§cVoidgloom Seraph 3", 8, "§cVoid 3"), + SLAYER_ENDERMAN_4("§4Voidgloom Seraph 4", 8, "§4Void 4"), + + SLAYER_BLAZE_1("§aInferno Demonlord 1", 9, "§aInferno 1"), + + HUB_HEADLESS_HORSEMAN("§6Headless Horseman", 10), + + DUNGEON_F1("", 11), + DUNGEON_F2("", 12), + DUNGEON_F3("", 13), + DUNGEON_F4_THORN("§cThorn", 14), + DUNGEON_F5("", 15), + DUNGEON_F("", 16), + DUNGEON_75("", 17), + + //TODO arachne + + //TODO corelone + //TODO bal + + + /** + * TODO dungeon mini bosses + * shadow assassin + * lost adventurer + * frozen adventurer + * king midas + * silverfish 2b one tap - deathmite outside trap + * in blood room: bonzo, scarf, ?? + * f7 blood room giants + * + */ + + //TODO diana mythological creatures +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/damageindicator/DamageCounter.kt b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/DamageCounter.kt new file mode 100644 index 000000000..84bc7d50a --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/DamageCounter.kt @@ -0,0 +1,10 @@ +package at.hannibal2.skyhanni.features.damageindicator + +class DamageCounter { + + var currentDamage = 0L + var currentHealing = 0L + var oldDamages = mutableListOf<OldDamage>() + var firstTick = 0L + +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/damageindicator/DamageIndicatorManager.kt b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/DamageIndicatorManager.kt new file mode 100644 index 000000000..ddfaed4cf --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/DamageIndicatorManager.kt @@ -0,0 +1,544 @@ +package at.hannibal2.skyhanni.features.damageindicator + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.data.ScoreboardData +import at.hannibal2.skyhanni.events.DamageIndicatorFinalBossEvent +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.features.dungeon.DungeonData +import at.hannibal2.skyhanni.test.LorenzTest +import at.hannibal2.skyhanni.utils.* +import at.hannibal2.skyhanni.utils.LorenzUtils.baseMaxHealth +import at.hannibal2.skyhanni.utils.LorenzUtils.between +import at.hannibal2.skyhanni.utils.LorenzUtils.removeColor +import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.GlStateManager +import net.minecraft.entity.EntityLivingBase +import net.minecraft.entity.item.EntityArmorStand +import net.minecraft.entity.monster.EntityEnderman +import net.minecraft.entity.monster.EntityMagmaCube +import net.minecraft.entity.monster.EntityZombie +import net.minecraft.entity.passive.EntityWolf +import net.minecraftforge.client.event.RenderLivingEvent +import net.minecraftforge.client.event.RenderWorldLastEvent +import net.minecraftforge.event.entity.EntityJoinWorldEvent +import net.minecraftforge.event.world.WorldEvent +import net.minecraftforge.fml.common.eventhandler.EventPriority +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent +import java.text.DecimalFormat +import java.util.* +import java.util.regex.Pattern +import kotlin.math.max + +class DamageIndicatorManager { + + var data = mutableMapOf<UUID, EntityData>() + private var bossFinder: BossFinder? = null + private val decimalFormat = DecimalFormat("0.0") + private val maxHealth = mutableMapOf<UUID, Int>() + private val damagePattern = Pattern.compile("✧?(\\d+[⚔+✧❤♞☄✷ﬗ]*)") + + @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.damageIndicator.enabled) return + + GlStateManager.disableDepth() + GlStateManager.disableCull() + + val player = Minecraft.getMinecraft().thePlayer + + //TODO config to define between 100ms and 5 sec + for (uuid in data.filter { System.currentTimeMillis() > it.value.timeLastTick + if (it.value.dead) 3_000 else 100 } + .map { it.key }) { + data.remove(uuid) + } + + for (data in data.values) { + tickDamage(data.damageCounter) + if (!data.ignoreBlocks) { + if (!player.canEntityBeSeen(data.entity)) continue + } + if (data.bossType.bossTypeToggle !in SkyHanniMod.feature.damageIndicator.bossesToShow) continue + + val entity = data.entity + + var healthText = data.healthText + val delayedStart = data.delayedStart + if (delayedStart != -1L) { + if (delayedStart > System.currentTimeMillis()) { + val delay = delayedStart - System.currentTimeMillis() + healthText = formatDelay(delay) + } + } + + val partialTicks = event.partialTicks + + val location = if (data.dead && data.deathLocation != null) { + data.deathLocation!! + } else { + val loc = LorenzVec( + RenderUtils.interpolate(entity.posX, entity.lastTickPosX, partialTicks), + RenderUtils.interpolate(entity.posY, entity.lastTickPosY, partialTicks) + 0.5f, + RenderUtils.interpolate(entity.posZ, entity.lastTickPosZ, partialTicks) + ) + if (data.dead) data.deathLocation = loc + loc + } + + if (!data.healthLineHidden) { + RenderUtils.drawLabel(location, healthText, partialTicks, true, 6f) + } + + var bossName = when (SkyHanniMod.feature.damageIndicator.bossName) { + 0 -> "" + 1 -> data.bossType.fullName + 2 -> data.bossType.shortName + else -> data.bossType.fullName + } + + if (data.namePrefix.isNotEmpty()) { + bossName = data.namePrefix + bossName + } + if (data.nameSuffix.isNotEmpty()) { + bossName += data.nameSuffix + } + + RenderUtils.drawLabel(location, bossName, partialTicks, true, 3.9f, -9.0f) + + if (SkyHanniMod.feature.damageIndicator.showDamageOverTime) { + var diff = 13f + val currentDamage = data.damageCounter.currentDamage + val currentHealing = data.damageCounter.currentHealing + if (currentDamage != 0L || currentHealing != 0L) { + val formatDamage = "§c" + NumberUtil.format(currentDamage) + val formatHealing = "§a+" + NumberUtil.format(currentHealing) + val finalResult = if (currentHealing == 0L) { + formatDamage + } else if (currentDamage == 0L) { + formatHealing + } else { + "$formatDamage §7/ $formatHealing" + } + RenderUtils.drawLabel(location, finalResult, partialTicks, true, 3.9f, diff) + diff += 9f + } + for (damage in data.damageCounter.oldDamages) { + val formatDamage = "§c" + NumberUtil.format(damage.damage) + "/s" + val formatHealing = "§a+" + NumberUtil.format(damage.healing) + "/s" + val finalResult = if (damage.healing == 0L) { + formatDamage + } else if (damage.damage == 0L) { + formatHealing + } else { + "$formatDamage §7/ $formatHealing" + } + RenderUtils.drawLabel(loc |
