diff options
5 files changed, 230 insertions, 50 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt index 60254162c..3985c00a1 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt @@ -349,7 +349,7 @@ class SkyHanniMod { loadModule(HighlightMiningCommissionMobs()) loadModule(ShowMotesNpcSellPrice()) loadModule(LivingMetalSuitProgress()) - loadModule(VampireSlayerFeatures()) + loadModule(VampireSlayerFeatures) loadModule(BlobbercystsHighlight()) loadModule(LivingCaveDefenseBlocks()) loadModule(LivingCaveLivingMetalHelper()) diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/SlayerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/SlayerConfig.java index e5aba386f..4efa9feb4 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/SlayerConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/SlayerConfig.java @@ -130,9 +130,14 @@ public class SlayerConfig { public boolean steakAlert = true; @Expose - @ConfigOption(name = "Twinclaws warning", desc = "Send a title when Twinclaws is about to happen.\nWork on others highlighted people boss.") + @ConfigOption(name = "Twinclaws title", desc = "Send a title when Twinclaws is about to happen.\nWork on others highlighted people boss.") @ConfigEditorBoolean public boolean twinClawsTitle = true; + + @Expose + @ConfigOption(name = "Twinclaws sound", desc = "Play a sound when Twinclaws is about to happen.") + @ConfigEditorBoolean + public boolean twinClawsSound = true; } @Expose @@ -158,15 +163,20 @@ public class SlayerConfig { public boolean steakAlert = true; @Expose - @ConfigOption(name = "Twinclaws warning", desc = "Send a title when Twinclaws is about to happen.") + @ConfigOption(name = "Twinclaws title", desc = "Send a title when Twinclaws is about to happen.") @ConfigEditorBoolean public boolean twinClawsTitle = true; + + @Expose + @ConfigOption(name = "Twinclaws sound", desc = "Play a sound when Twinclaws is about to happen.") + @ConfigEditorBoolean + public boolean twinClawsSound = true; } @Expose @ConfigOption(name = "Co-op Boss", desc = "") @Accordion - public CoopBossHighlight coopsBossHighlight = new CoopBossHighlight(); + public CoopBossHighlight coopBoss = new CoopBossHighlight(); public static class CoopBossHighlight { @Expose @@ -190,9 +200,14 @@ public class SlayerConfig { public boolean steakAlert = true; @Expose - @ConfigOption(name = "Twinclaws warning", desc = "Send a title when Twinclaws is about to happen.") + @ConfigOption(name = "Twinclaws title", desc = "Send a title when Twinclaws is about to happen.") @ConfigEditorBoolean public boolean twinClawsTitle = true; + + @Expose + @ConfigOption(name = "Twinclaws sound", desc = "Play a sound when Twinclaws is about to happen.") + @ConfigEditorBoolean + public boolean twinClawsSound = true; } @Expose @@ -215,6 +230,28 @@ public class SlayerConfig { @ConfigEditorColour public String steakColor = "0:255:255:0:88"; + @Expose + @ConfigOption(name = "Twinclaws", desc = "Delay the sound and title of twinclaws alert for a given amount in milliseconds.") + @ConfigEditorSlider(minStep = 1, minValue = 0, maxValue = 1000) + public int twinclawsDelay = 0; + + @Expose + @ConfigOption(name = "Draw line", desc = "Draw a line starting at your crosshair to the boss head") + @ConfigEditorBoolean + public boolean drawLine = false; + + @Expose + @ConfigOption(name = "Line color", desc = "Color of the line") + @ConfigEditorColour + public String lineColor = "0:255:255:0:88"; + + @Expose + @ConfigOption(name = "Line Width", desc = "Width of the line") + @ConfigEditorSlider(minStep = 1, minValue = 1, maxValue = 10) + public int lineWidth = 1; + + + @Expose @ConfigOption(name = "Blood Ichor", desc = "") @@ -236,6 +273,17 @@ public class SlayerConfig { @ConfigOption(name = "Color", desc = "Highlight color.") @ConfigEditorColour public String color = "0:199:100:0:88"; + + @Expose + @ConfigOption(name = "Show lines", desc = "Draw lines that start from the head of the boss and end on the Blood Ichor.") + @ConfigEditorBoolean + public boolean showLines = false; + + @Expose + @ConfigOption(name = "Lines start color", desc = "Starting color of the lines.") + @ConfigEditorColour + public String linesColor = "0:255:255:13:0"; + } @Expose @@ -253,6 +301,16 @@ public class SlayerConfig { @ConfigOption(name = "Color", desc = "Highlight color.") @ConfigEditorColour public String color = "0:199:100:0:88"; + + @Expose + @ConfigOption(name = "Show lines", desc = "Draw lines that start from the head of the boss and end on the Killer Spring tower.") + @ConfigEditorBoolean + public boolean showLines = false; + + @Expose + @ConfigOption(name = "Lines start color", desc = "Starting color of the lines.") + @ConfigEditorColour + public String linesColor = "0:255:255:13:0"; } } @@ -347,7 +405,7 @@ public class SlayerConfig { @Expose @ConfigOption(name = "Broken Wither Impact", desc = "Warns when right-clicking with a Wither Impact weapon (e.g. Hyperion) no longer gains combat exp. " + - "Kill a mob with melee-hits to fix this hypixel bug. §cOnly works while doing slayers!" + "Kill a mob with melee-hits to fix this hypixel bug. §cOnly works while doing slayers!" ) @ConfigEditorBoolean public boolean brokenHyperion = true; diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/VampireSlayerFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/VampireSlayerFeatures.kt index 9a771a36c..6818eb4b0 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/rift/VampireSlayerFeatures.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/rift/VampireSlayerFeatures.kt @@ -5,6 +5,7 @@ import at.hannibal2.skyhanni.data.ClickType import at.hannibal2.skyhanni.data.TitleUtils import at.hannibal2.skyhanni.events.EntityClickEvent import at.hannibal2.skyhanni.events.LorenzTickEvent +import at.hannibal2.skyhanni.events.ReceiveParticleEvent import at.hannibal2.skyhanni.events.withAlpha import at.hannibal2.skyhanni.features.rift.everywhere.RiftAPI import at.hannibal2.skyhanni.mixins.hooks.RenderLivingEntityHelper @@ -14,34 +15,52 @@ import at.hannibal2.skyhanni.utils.EntityUtils.getAllNameTagsInRadiusWith import at.hannibal2.skyhanni.utils.EntityUtils.hasSkullTexture import at.hannibal2.skyhanni.utils.EntityUtils.isNPC import at.hannibal2.skyhanni.utils.LorenzUtils.baseMaxHealth +import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy import at.hannibal2.skyhanni.utils.LorenzUtils.toChromaColor +import at.hannibal2.skyhanni.utils.RenderUtils.draw3DLine +import at.hannibal2.skyhanni.utils.RenderUtils.drawColor +import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText +import at.hannibal2.skyhanni.utils.RenderUtils.exactLocation +import at.hannibal2.skyhanni.utils.SoundUtils.playSound +import kotlinx.coroutines.* +import net.minecraft.client.Minecraft import net.minecraft.client.entity.EntityOtherPlayerMP import net.minecraft.client.renderer.GlStateManager import net.minecraft.entity.EntityLivingBase import net.minecraft.entity.item.EntityArmorStand +import net.minecraft.util.EnumParticleTypes import net.minecraftforge.client.event.RenderLivingEvent import net.minecraftforge.client.event.RenderWorldLastEvent import net.minecraftforge.event.entity.living.LivingDeathEvent import net.minecraftforge.event.world.WorldEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.time.Duration.Companion.milliseconds -class VampireSlayerFeatures { +object VampireSlayerFeatures { private val config get() = SkyHanniMod.feature.slayer.vampireSlayerConfig + private val configOwnBoss get() = config.ownBoss + private val configOtherBoss get() = config.othersBoss + private val configCoopBoss get() = config.coopBoss + private val configBloodIcor get() = config.bloodIchor + private val configKillerSpring get() = config.killerSpring + private val entityList = mutableListOf<EntityLivingBase>() private val taggedEntityList = mutableListOf<Int>() + private val standList = mutableMapOf<EntityArmorStand, EntityOtherPlayerMP>() private val username get() = LorenzUtils.getPlayerName() private val bloodIchorTexture = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzAzNDA5MjNhNmRlNDgyNWExNzY4MTNkMTMzNTAzZWZmMTg2ZGIwODk2ZTMyYjY3MDQ5MjhjMmEyYmY2ODQyMiJ9fX0=" private val killerSpringTexture = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzdmN2E3YmM4YWM4NmYyM2NhN2JmOThhZmViNzY5NjAyMjdlMTgzMmZlMjA5YTMwMjZmNmNlYjhiZGU3NGY1NCJ9fX0=" + private var nextClawSend = 0L @SubscribeEvent fun onTick(event: LorenzTickEvent) { if (!isEnabled()) return if (!event.isMod(5)) return val start = LocationUtils.playerLocation() - if (config.ownBoss.highlight || config.othersBoss.highlight || config.coopsBossHighlight.highlight) { + if (configOwnBoss.highlight || configOtherBoss.highlight || configCoopBoss.highlight) { EntityUtils.getEntities<EntityOtherPlayerMP>().forEach { val vec = it.position.toLorenzVec() val distance = start.distance(vec) @@ -49,13 +68,13 @@ class VampireSlayerFeatures { it.process() } } - if (config.bloodIchor.highlight || config.killerSpring.highlight) { + if (configBloodIcor.highlight || configKillerSpring.highlight) { EntityUtils.getEntities<EntityArmorStand>().forEach { stand -> val vec = stand.position.toLorenzVec() val distance = start.distance(vec) val isIchor = stand.hasSkullTexture(bloodIchorTexture) if (isIchor || stand.hasSkullTexture(killerSpringTexture)) { - val color = (if (isIchor) config.bloodIchor.color else config.killerSpring.color) + val color = (if (isIchor) configBloodIcor.color else configKillerSpring.color) .toChromaColor().withAlpha(config.withAlpha) if (distance <= 15) { RenderLivingEntityHelper.setEntityColor( @@ -68,19 +87,23 @@ class VampireSlayerFeatures { } } } + if (event.isMod(20)) { + entityList.editCopy { removeIf { it.isDead } } + } } private fun EntityOtherPlayerMP.process() { if (name != "Bloodfiend ") return - if (config.ownBoss.twinClawsTitle || config.othersBoss.twinClawsTitle || config.coopsBossHighlight.twinClawsTitle) { + + if (configOwnBoss.twinClawsTitle || configOtherBoss.twinClawsTitle || configCoopBoss.twinClawsTitle) { getAllNameTagsInRadiusWith("TWINCLAWS").forEach { stand -> if (".*(?:§(?:\\d|\\w))+TWINCLAWS (?:§(?:\\w|\\d))+[0-9.,]+s.*".toRegex().matches(stand.name)) { - val coopList = config.coopsBossHighlight.coopMembers.split(",").toList() + val coopList = configCoopBoss.coopMembers.split(",").toList() val containUser = getAllNameTagsInRadiusWith("Spawned by").any { it.name.contains(username) } val containCoop = getAllNameTagsInRadiusWith("Spawned by").any { - coopList.isNotEmpty() && config.coopsBossHighlight.highlight && coopList.any { it2 -> + coopList.isNotEmpty() && configCoopBoss.highlight && coopList.any { it2 -> var contain = false if (".*§(?:\\d|\\w)+Spawned by: §(?:\\d|\\w)(\\w*).*".toRegex().matches(it.name)) { val name = ".*§(?:\\d|\\w)+Spawned by: §(?:\\d|\\w)(\\w*)".toRegex() @@ -91,18 +114,34 @@ class VampireSlayerFeatures { } } val shouldSendTitle = - if (containUser && config.ownBoss.twinClawsTitle) true - else if (containCoop && config.coopsBossHighlight.twinClawsTitle) true - else taggedEntityList.contains(this.entityId) && config.othersBoss.twinClawsTitle + if (containUser && configOwnBoss.twinClawsTitle) true + else if (containCoop && configCoopBoss.twinClawsTitle) true + else taggedEntityList.contains(this.entityId) && configOtherBoss.twinClawsTitle + + val shouldSendSound = + if (containUser && configOwnBoss.twinClawsSound) true + else if (containCoop && configCoopBoss.twinClawsSound) true + else taggedEntityList.contains(this.entityId) && configOtherBoss.twinClawsSound - if (shouldSendTitle) { - TitleUtils.sendTitle("§6§lTWINCLAWS", 300, 2.6) + if (shouldSendTitle || shouldSendSound) { + SkyHanniMod.coroutineScope.launch { + delay(config.twinclawsDelay.milliseconds) + withContext(MinecraftDispatcher) { + if (nextClawSend < System.currentTimeMillis()) { + if (shouldSendSound) + playTwinclawsSound() + if (shouldSendTitle) + TitleUtils.sendTitle("§6§lTWINCLAWS", (1750 - config.twinclawsDelay), 2.6) + nextClawSend = System.currentTimeMillis() + 5000 + } + } + } } } } } getAllNameTagsInRadiusWith("Spawned by").forEach { - val coopList = config.coopsBossHighlight.coopMembers.split(",").toList() + val coopList = configCoopBoss.coopMembers.split(",").toList() val containUser = it.name.contains(username) val containCoop = coopList.isNotEmpty() && coopList.any { it2 -> var contain = false @@ -124,28 +163,27 @@ class VampireSlayerFeatures { taggedEntityList.remove(this.entityId) } val canUseSteak = health <= neededHealth - val ownBoss = config.ownBoss.highlight && containUser && isNPC() - val otherBoss = config.othersBoss.highlight && taggedEntityList.contains(this.entityId) && isNPC() - val coopBoss = config.coopsBossHighlight.highlight && containCoop && isNPC() + val ownBoss = configOwnBoss.highlight && containUser && isNPC() + val otherBoss = configOtherBoss.highlight && taggedEntityList.contains(this.entityId) && isNPC() + val coopBoss = configCoopBoss.highlight && containCoop && isNPC() val shouldRender = if (ownBoss) true else if (otherBoss) true else coopBoss val color = if (canUseSteak && config.changeColorWhenCanSteak) config.steakColor.color() - else if (ownBoss) config.ownBoss.highlightColor.color() - else if (otherBoss) config.othersBoss.highlightColor.color() - else if (coopBoss) config.coopsBossHighlight.highlightColor.color() + else if (ownBoss) configOwnBoss.highlightColor.color() + else if (otherBoss) configOtherBoss.highlightColor.color() + else if (coopBoss) configCoopBoss.highlightColor.color() else 0 val shouldSendSteakTitle = - if (canUseSteak && config.ownBoss.steakAlert && containUser) true - else if (canUseSteak && config.othersBoss.steakAlert && taggedEntityList.contains(this.entityId)) true - else canUseSteak && config.coopsBossHighlight.steakAlert && containCoop + if (canUseSteak && configOwnBoss.steakAlert && containUser) true + else if (canUseSteak && configOtherBoss.steakAlert && taggedEntityList.contains(this.entityId)) true + else canUseSteak && configCoopBoss.steakAlert && containCoop if (shouldSendSteakTitle) TitleUtils.sendTitle("§c§lSTEAK!", 300, 2.6) - if (shouldRender) { RenderLivingEntityHelper.setEntityColor(this, color) { isEnabled() } RenderLivingEntityHelper.setNoHurtTime(this) { isEnabled() } @@ -154,6 +192,19 @@ class VampireSlayerFeatures { } } + private fun playTwinclawsSound() { + CoroutineScope(Dispatchers.Default).launch { + repeat(15) { + delay(50) + SoundUtils.createSound("random.orb", 0.5f).playSound() + } + } + } + + private fun EntityOtherPlayerMP.isHighlighted(): Boolean { + return entityList.contains(this) || taggedEntityList.contains(this.entityId) + } + private fun String.color(): Int { return toChromaColor().withAlpha(config.withAlpha) } @@ -164,7 +215,7 @@ class VampireSlayerFeatures { if (event.clickType != ClickType.LEFT_CLICK) return if (event.clickedEntity !is EntityOtherPlayerMP) return if (!event.clickedEntity.isNPC()) return - val coopList = config.coopsBossHighlight.coopMembers.split(",").toList() + val coopList = configCoopBoss.coopMembers.split(",").toList() event.clickedEntity.getAllNameTagsInRadiusWith("Spawned by").forEach { val containCoop = coopList.isNotEmpty() && coopList.any { it2 -> var contain = false @@ -223,22 +274,94 @@ class VampireSlayerFeatures { @SubscribeEvent fun onWorldRender(event: RenderWorldLastEvent) { if (!isEnabled()) return - if (config.bloodIchor.renderBeam) + val start = LocationUtils.playerLocation() + + if (config.drawLine) { + Minecraft.getMinecraft().theWorld.loadedEntityList.filterIsInstance<EntityOtherPlayerMP>().forEach { + if (it.isHighlighted()) { + val vec = event.exactLocation(it) + val distance = start.distance(vec) + if (distance <= 15) { + val p = Minecraft.getMinecraft().thePlayer + val add = if (p.isSneaking) LorenzVec(0.0, 1.54, 0.0) else LorenzVec(0.0, 1.62, 0.0) + event.draw3DLine(event.exactLocation(p).add(add), vec.add(0.0, 1.54, 0.0), config.lineColor.toChromaColor(), config.lineWidth, true) + } + } + } + } + + if (configBloodIcor.renderBeam) { entityList.filterIsInstance<EntityArmorStand>().forEach { - if (it.isEntityAlive) { - event.drawWaypointFilled( - it.position.toLorenzVec().add(0, -2, 0), config.bloodIchor.color.toChromaColor(), - beacon = true - ) + if (it.hasSkullTexture(bloodIchorTexture)) { + if (it.isEntityAlive) { + event.drawWaypointFilled( + it.position.toLorenzVec().add(0, -2, 0), configBloodIcor.color.toChromaColor(), + beacon = true + ) + } } } + } + if (configBloodIcor.highlight || configKillerSpring.highlight) { + Minecraft.getMinecraft().theWorld.loadedEntityList.filterIsInstance<EntityArmorStand>().forEach { stand -> + val vec = stand.position.toLorenzVec() + val distance = start.distance(vec) + val isIchor = stand.hasSkullTexture(bloodIchorTexture) + val isSpring = stand.hasSkullTexture(killerSpringTexture) + if (isIchor || isSpring) { + val color = (if (isIchor) configBloodIcor.color else configKillerSpring.color) + .toChromaColor().withAlpha(config.withAlpha) + if (distance <= 15) { + RenderLivingEntityHelper.setEntityColor( + stand, + color + ) { isEnabled() } + + val linesColorStart = (if (isIchor) configBloodIcor.linesColor else configKillerSpring.linesColor).toChromaColor() + val text = if (isIchor) "§4Ichor" else "§4Spring" + event.drawColor(stand.position.toLorenzVec().add(0.0, 2.0, 0.0), LorenzColor.DARK_RED, alpha = 1f) + event.drawDynamicText(stand.position.toLorenzVec().add(0.5, 2.5, 0.5), text, 1.5, ignoreBlocks = false) + for ((player, stand2) in standList) { + if (configBloodIcor.showLines || configKillerSpring.showLines) + event.draw3DLine( + event.exactLocation(player).add(0.0, 1.5, 0.0), + event.exactLocation(stand2).add(0.0, 1.5, 0.0), + // stand2.position.toLorenzVec().add(0.0, 1.5, 0.0), + linesColorStart, + 3, + true) + } + } + } + } + } } + @SubscribeEvent fun onWorldChange(event: WorldEvent.Load) { entityList.clear() taggedEntityList.clear() + standList.clear() + } + + + @SubscribeEvent + fun onParticle(event: ReceiveParticleEvent) { + if (!isEnabled()) return + val loc = event.location + EntityUtils.getEntitiesNearby<EntityOtherPlayerMP>(loc, 3.0).forEach { + if (it.isHighlighted()) { + if (event.type == EnumParticleTypes.ENCHANTMENT_TABLE) { + EntityUtils.getEntitiesNearby<EntityArmorStand>(event.location, 3.0).forEach { stand -> + if (stand.hasSkullTexture(killerSpringTexture) || stand.hasSkullTexture(bloodIchorTexture)) { + standList[stand] = it + } + } + } + } + } } - fun isEnabled() = RiftAPI.inRift() + fun isEnabled() = RiftAPI.inRift() && RiftAPI.inStillgoreChateau() }
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/RiftAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/RiftAPI.kt index 4609b3057..d3be9a77e 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/RiftAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/RiftAPI.kt @@ -24,4 +24,5 @@ object RiftAPI { fun inLivingCave() = LorenzUtils.skyBlockArea == "Living Cave" fun inLivingStillness() = LorenzUtils.skyBlockArea == "Living Stillness" + fun inStillgoreChateau() = LorenzUtils.skyBlockArea == "Stillgore Château" || LorenzUtils.skyBlockArea == "Oubliette" }
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt index 30a8025cf..9bfb9e1bb 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt @@ -5,11 +5,9 @@ import at.hannibal2.skyhanni.utils.LocationUtils.distanceTo import at.hannibal2.skyhanni.utils.LorenzUtils.baseMaxHealth import net.minecraft.block.state.IBlockState import net.minecraft.client.Minecraft -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.monster.EntityEnderman import net.minecraft.entity.player.EntityPlayer import net.minecraft.item.ItemStack @@ -129,20 +127,20 @@ object EntityUtils { } inline fun <reified T : Entity> getEntitiesNextToPlayer(radius: Double): List<T> = - getEntitiesNearby(LocationUtils.playerLocation(), radius) + getEntitiesNearby<T>(LocationUtils.playerLocation(), radius) inline fun <reified T : Entity> getEntitiesNearby(location: LorenzVec, radius: Double): List<T> = - getAllEntities().filterIsInstance<T>().filter { it.distanceTo(location) < radius } + getEntities<T>().filter { it.distanceTo(location) < radius } fun EntityLivingBase.isAtFullHealth() = baseMaxHealth == health.toInt() - fun WorldClient.getEntitiesNearby( - clazz: Class<EntityBlaze>, - location: LorenzVec, - radius: Double - ): MutableList<EntityBlaze> = getEntities(clazz) { entity -> - entity?.getLorenzVec()?.let { it.distance(location) < radius } ?: false - } +// fun WorldClient.getEntitiesNearby( +// clazz: Class<EntityBlaze>, +// location: LorenzVec, +// radius: Double +// ): MutableList<EntityBlaze> = getEntities(clazz) { entity -> +// entity?.getLorenzVec()?.let { it.distance(location) < radius } ?: false +// } fun EntityArmorStand.hasSkullTexture(skin: String): Boolean { if (inventory == null) return false @@ -158,9 +156,9 @@ object EntityUtils { fun EntityEnderman.getBlockInHand(): IBlockState? = heldBlockState - inline fun <reified R: Entity> getEntities(): List<R> = getAllEntities().filterIsInstance<R>() + inline fun <reified R : Entity> getEntities(): List<R> = getAllEntities().filterIsInstance<R>() - inline fun <reified R: Entity> getEntitiesOrNull(): List<R>? = getAllEntitiesOrNull()?.filterIsInstance<R>() + inline fun <reified R : Entity> getEntitiesOrNull(): List<R>? = getAllEntitiesOrNull()?.filterIsInstance<R>() fun getAllEntities(): List<Entity> = getAllEntitiesOrNull() ?: error("minecraft.world.loadedEntityList is null.") |