package at.hannibal2.skyhanni.utils import at.hannibal2.skyhanni.utils.ItemUtils.getSkullTexture import at.hannibal2.skyhanni.utils.LocationUtils.distanceTo import at.hannibal2.skyhanni.utils.LorenzUtils.baseMaxHealth import net.minecraft.client.multiplayer.WorldClient import net.minecraft.entity.Entity import net.minecraft.entity.EntityLivingBase import net.minecraft.entity.item.EntityArmorStand import net.minecraft.entity.monster.EntityBlaze import net.minecraft.entity.player.EntityPlayer import net.minecraft.item.ItemStack import net.minecraft.potion.Potion import net.minecraft.util.AxisAlignedBB object EntityUtils { fun EntityLivingBase.hasNameTagWith( y: Int, contains: String, debugRightEntity: Boolean = false, inaccuracy: Double = 1.6, debugWrongEntity: Boolean = false, ): Boolean { return getNameTagWith(y, contains, debugRightEntity, inaccuracy, debugWrongEntity) != null } fun EntityLivingBase.getAllNameTagsWith( y: Int, contains: String, debugRightEntity: Boolean = false, inaccuracy: Double = 1.6, debugWrongEntity: Boolean = false, ): List { 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.filter { val result = it.name.contains(contains) if (debugWrongEntity && !result) { LorenzUtils.consoleLog("wrong entity in aabb: '" + it.name + "'") } if (debugRightEntity && result) { LorenzUtils.consoleLog("mob: " + center.printWithAccuracy(2)) LorenzUtils.consoleLog("nametag: " + it.getLorenzVec().printWithAccuracy(2)) LorenzUtils.consoleLog("accuracy: " + it.getLorenzVec().subtract(center).printWithAccuracy(3)) } result } } fun EntityLivingBase.getAllNameTagsInRadiusWith( contains: String, radius: Double = 3.0, ): List { val center = getLorenzVec().add(0, 3, 0) val a = center.add(-radius, -radius - 3, -radius).toBlocPos() val b = center.add(radius, radius + 3, radius).toBlocPos() val alignedBB = AxisAlignedBB(a, b) val clazz = EntityArmorStand::class.java val found = worldObj.getEntitiesWithinAABB(clazz, alignedBB) return found.filter { val result = it.name.contains(contains) result } } fun EntityLivingBase.getNameTagWith( y: Int, contains: String, debugRightEntity: Boolean = false, inaccuracy: Double = 1.6, debugWrongEntity: Boolean = false, ): EntityArmorStand? { 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.find { val result = it.name.contains(contains) if (debugWrongEntity && !result) { LorenzUtils.consoleLog("wrong entity in aabb: '" + it.name + "'") } if (debugRightEntity && result) { LorenzUtils.consoleLog("mob: " + center.printWithAccuracy(2)) LorenzUtils.consoleLog("nametag: " + it.getLorenzVec().printWithAccuracy(2)) LorenzUtils.consoleLog("accuracy: " + it.getLorenzVec().subtract(center).printWithAccuracy(3)) } result } } fun EntityLivingBase.hasBossHealth(health: Int): Boolean = this.hasMaxHealth(health, true) //TODO remove baseMaxHealth fun EntityLivingBase.hasMaxHealth(health: Int, boss: Boolean = false, maxHealth: Int = baseMaxHealth): Boolean { if (maxHealth == health) return true //Derpy if (maxHealth == health * 2) return true if (!boss) { //Corrupted if (maxHealth == health * 3) return true //Derpy + Corrupted if (maxHealth == health * 2 * 3) return true } return false } fun EntityPlayer.getSkinTexture(): String? { val gameProfile = gameProfile ?: return null return gameProfile.properties.entries() .filter { it.key == "textures" } .map { it.value } .firstOrNull { it.name == "textures" } ?.value } inline fun WorldClient.getEntitiesNextToPlayer(radius: Double): List = getEntitiesNearby(LocationUtils.playerLocation(), radius) inline fun WorldClient.getEntitiesNearby(location: LorenzVec, radius: Double): List = getLoadedEntityList().filterIsInstance().filter { it.distanceTo(location) < radius } fun EntityLivingBase.isAtFullHealth() = baseMaxHealth == health.toInt() fun WorldClient.getEntitiesNearby( clazz: Class, location: LorenzVec, radius: Double ): MutableList = getEntities(clazz) { entity -> entity?.getLorenzVec()?.let { it.distance(location) < radius } ?: false } fun EntityArmorStand.hasSkullTexture(skin: String): Boolean { if (inventory == null) return false return inventory.any { it != null && it.getSkullTexture() == skin } } fun EntityPlayer.isNPC() = uniqueID == null || uniqueID.version() != 4 fun EntityLivingBase.hasPotionEffect(potion: Potion) = getActivePotionEffect(potion) != null fun EntityLivingBase.getArmorInventory(): Array? = if (this is EntityPlayer) inventory.armorInventory else null }