package me.km.utils; import java.util.List; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.entity.projectile.ProjectileEntity; import net.minecraft.server.MinecraftServer; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.world.IWorld; import net.minecraft.util.DamageSource; import net.minecraft.util.RegistryKey; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.RayTraceContext; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.vector.Vector3d; import net.minecraft.util.registry.Registry; import net.minecraft.world.World; public class Utils { public static Entity getEntityFromProjectile(Entity ent) { if(ent instanceof ProjectileEntity) { return ((ProjectileEntity) ent).func_234616_v_(); } return null; } public static PlayerEntity getDamager(DamageSource ds) { Entity ent = ds.getTrueSource(); if(ent == null) { return null; } if(ent instanceof PlayerEntity) { return (PlayerEntity) ent; } return null; } private static AxisAlignedBB buildBoxAround(double x, double y, double z, double radius) { return new AxisAlignedBB(x - radius, y - radius, z - radius, x + radius, y + radius, z + radius); } @SuppressWarnings("unchecked") public static List getEntities(IWorld w, double x, double y, double z, double radius, Class type) { double sqareRadius = radius * radius; return w.getEntitiesWithinAABB(type, buildBoxAround(x, y, z, radius), ent -> ent.getDistanceSq(x, y, z) <= sqareRadius); } public static List getEntities(Entity ent, double radius) { double sqareRadius = radius * radius; double x = ent.getPosX(); double y = ent.getPosY(); double z = ent.getPosZ(); return ent.world.getEntitiesInAABBexcluding(ent, buildBoxAround(x, y, z, radius), e -> e.getDistanceSq(x, y, z) <= sqareRadius); } public static List getEntities(Location loc, double radius) { double sqareRadius = radius * radius; double x = loc.getX(); double y = loc.getY(); double z = loc.getZ(); return loc.getWorld().getEntitiesInAABBexcluding(null, buildBoxAround(x, y, z, radius), ent -> ent.getDistanceSq(x, y, z) <= sqareRadius); } public static List getPlayers(IWorld w, double x, double y, double z, double radius) { double sqareRadius = radius * radius; return w.getEntitiesWithinAABB(PlayerEntity.class, buildBoxAround(x, y, z, radius), p -> p.getDistanceSq(x, y, z) <= sqareRadius); } public static List getPlayers(Entity not, double radius) { double sqareRadius = radius * radius; return not.world.getEntitiesWithinAABB(PlayerEntity.class, buildBoxAround(not.getPosX(), not.getPosY(), not.getPosZ(), radius), p -> p != not && p.getDistanceSq(not) <= sqareRadius); } public static List getLiving(Entity not, double radius) { double sqareRadius = radius * radius; return not.world.getEntitiesWithinAABB(LivingEntity.class, buildBoxAround(not.getPosX(), not.getPosY(), not.getPosZ(), radius), p -> p != not && p.getDistanceSq(not) <= sqareRadius); } public static List getLiving(Location loc, double radius) { double sqareRadius = radius * radius; double x = loc.getX(); double y = loc.getY(); double z = loc.getZ(); return loc.getWorld().getEntitiesWithinAABB(LivingEntity.class, buildBoxAround(x, y, z, radius), p -> p.getDistanceSq(x, y, z) <= sqareRadius); } public static T getEntity(IWorld w, double x, double y, double z, double radius, Class type) { return getEntities(w, x, y, z, radius, type).stream() .min((e1, e2) -> Double.compare(e1.getDistanceSq(x, y, z), e2.getDistanceSq(x, y, z))) .orElse(null); } private static boolean doesIntersect(AxisAlignedBB bound, Vector3d start, Vector3d unit) { double lowerX = Double.NEGATIVE_INFINITY; double upperX = Double.POSITIVE_INFINITY; if(unit.x != 0) { if(unit.x > 0) { lowerX = (bound.minX - start.x) / unit.x; upperX = (bound.maxX - start.x) / unit.x; } else { lowerX = (bound.maxX - start.x) / unit.x; upperX = (bound.minX - start.x) / unit.x; } } double lowerY = Double.NEGATIVE_INFINITY; double upperY = Double.POSITIVE_INFINITY; if(unit.y != 0) { if(unit.y > 0) { lowerY = (bound.minY - start.y) / unit.y; upperY = (bound.maxY - start.y) / unit.y; } else { lowerY = (bound.maxY - start.y) / unit.y; upperY = (bound.minY - start.y) / unit.y; } } double lowerZ = Double.NEGATIVE_INFINITY; double upperZ = Double.POSITIVE_INFINITY; if(unit.z != 0) { if(unit.z > 0) { lowerZ = (bound.minZ - start.z) / unit.z; upperZ = (bound.maxZ - start.z) / unit.z; } else { lowerZ = (bound.maxZ - start.z) / unit.z; upperZ = (bound.minZ - start.z) / unit.z; } } return Math.max(Math.max(lowerX, lowerY), lowerZ) < Math.min(Math.min(upperX, upperY), upperZ); } private static Vector3d getTargetVector(Entity ent, double range) { if(range > 128) { range = 128; } World w = ent.getEntityWorld(); Vector3d start = ent.getEyePosition(1.0f); Vector3d look = ent.getLookVec(); Vector3d end = start.add(look.x * range, look.y * range, look.z * range); RayTraceResult ray = w.rayTraceBlocks(new RayTraceContext(start, end, RayTraceContext.BlockMode.COLLIDER, RayTraceContext.FluidMode.NONE, ent)); if(ray == null || ray.getHitVec() == null) { return end; } return ray.getHitVec(); } @SuppressWarnings("unchecked") public static T getTargetedEntity(PlayerEntity p, double radius, Class type) { World w = p.getEntityWorld(); Vector3d l = getTargetVector(p, radius); Vector3d eye = p.getEyePosition(1.0f); Vector3d unit = new Vector3d(l.x - eye.x, l.y - eye.y, l.z - eye.z); List col = w.getEntitiesWithinAABBExcludingEntity(p, new AxisAlignedBB(eye.x, eye.y, eye.z, l.x, l.y, l.z)); col.removeIf(ent -> !type.isAssignableFrom(ent.getClass())); // removes entities, which do not intersect with the sight vector col.removeIf(ent -> !doesIntersect(ent.getBoundingBox().grow(0.1), eye, unit)); return (T) col.stream().sorted((Entity e1, Entity e2) -> { return Double.compare(e1.getDistanceSq(eye.x, eye.y, eye.z), e2.getDistanceSq(eye.x, eye.y, eye.z)); }).findFirst().orElse(null); } // ------------------------------------------------------------------------- // Player-Tools // ------------------------------------------------------------------------- public static ServerPlayerEntity getPlayerByName(MinecraftServer server, String name) { String nameLower = name.toLowerCase(); return server.getPlayerList().getPlayers().stream() .filter(pl -> pl.getName().getUnformattedComponentText().toLowerCase().contains(nameLower)) .findFirst().orElse(null); } public static String getWorldName(World w) { return w.getDimensionKey().getLocation().getPath(); } public static World getWorldFromName(MinecraftServer server, String name) { return server.getWorld(RegistryKey.getOrCreateKey(Registry.WORLD_KEY, new ResourceLocation(name))); } }