Utils.java 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. package me.km.utils;
  2. import java.util.List;
  3. import net.minecraft.entity.Entity;
  4. import net.minecraft.entity.LivingEntity;
  5. import net.minecraft.entity.player.PlayerEntity;
  6. import net.minecraft.entity.player.ServerPlayerEntity;
  7. import net.minecraft.entity.projectile.ArrowEntity;
  8. import net.minecraft.entity.projectile.DamagingProjectileEntity;
  9. import net.minecraft.entity.projectile.ThrowableEntity;
  10. import net.minecraft.server.MinecraftServer;
  11. import net.minecraft.util.math.AxisAlignedBB;
  12. import net.minecraft.util.math.Vec3d;
  13. import net.minecraft.world.IWorld;
  14. import net.minecraft.util.DamageSource;
  15. import net.minecraft.util.math.RayTraceContext;
  16. import net.minecraft.util.math.RayTraceResult;
  17. import net.minecraft.world.World;
  18. public class Utils {
  19. public static Entity getEntityFromProjectile(Entity ent) {
  20. if(ent instanceof ArrowEntity) {
  21. return ((ArrowEntity) ent).getShooter();
  22. } else if(ent instanceof ThrowableEntity) {
  23. return ((ThrowableEntity) ent).getThrower();
  24. } else if(ent instanceof DamagingProjectileEntity) {
  25. return ( (DamagingProjectileEntity) ent).shootingEntity;
  26. }
  27. return null;
  28. }
  29. public static PlayerEntity getDamager(DamageSource ds) {
  30. Entity ent = ds.getTrueSource();
  31. if(ent == null) {
  32. return null;
  33. }
  34. if(ent instanceof PlayerEntity) {
  35. return (PlayerEntity) ent;
  36. }
  37. return null;
  38. }
  39. private static AxisAlignedBB buildBoxAround(double x, double y, double z, double radius) {
  40. return new AxisAlignedBB(x - radius, y - radius, z - radius, x + radius, y + radius, z + radius);
  41. }
  42. @SuppressWarnings("unchecked")
  43. public static <T extends Entity> List<T> getEntities(IWorld w, double x, double y, double z, double radius, Class<T> type) {
  44. double sqareRadius = radius * radius;
  45. return w.getWorld().getEntitiesWithinAABB(type, buildBoxAround(x, y, z, radius), ent -> ent.getDistanceSq(x, y, z) <= sqareRadius);
  46. }
  47. public static List<Entity> getEntities(Entity ent, double radius) {
  48. double sqareRadius = radius * radius;
  49. double x = ent.getPosX();
  50. double y = ent.getPosY();
  51. double z = ent.getPosZ();
  52. return ent.world.getEntitiesInAABBexcluding(ent, buildBoxAround(x, y, z, radius), e -> e.getDistanceSq(x, y, z) <= sqareRadius);
  53. }
  54. public static List<Entity> getEntities(Location loc, double radius) {
  55. double sqareRadius = radius * radius;
  56. double x = loc.getX();
  57. double y = loc.getY();
  58. double z = loc.getZ();
  59. return loc.getWorld().getEntitiesInAABBexcluding(null, buildBoxAround(x, y, z, radius), ent -> ent.getDistanceSq(x, y, z) <= sqareRadius);
  60. }
  61. public static List<PlayerEntity> getPlayers(IWorld w, double x, double y, double z, double radius) {
  62. double sqareRadius = radius * radius;
  63. return w.getEntitiesWithinAABB(PlayerEntity.class, buildBoxAround(x, y, z, radius), p -> p.getDistanceSq(x, y, z) <= sqareRadius);
  64. }
  65. public static List<PlayerEntity> getPlayers(Entity not, double radius) {
  66. double sqareRadius = radius * radius;
  67. return not.world.getEntitiesWithinAABB(PlayerEntity.class, buildBoxAround(not.getPosX(), not.getPosY(), not.getPosZ(), radius),
  68. p -> p != not && p.getDistanceSq(not) <= sqareRadius);
  69. }
  70. public static List<LivingEntity> getLiving(Entity not, double radius) {
  71. double sqareRadius = radius * radius;
  72. return not.world.getEntitiesWithinAABB(LivingEntity.class, buildBoxAround(not.getPosX(), not.getPosY(), not.getPosZ(), radius),
  73. p -> p != not && p.getDistanceSq(not) <= sqareRadius);
  74. }
  75. public static List<LivingEntity> getLiving(Location loc, double radius) {
  76. double sqareRadius = radius * radius;
  77. double x = loc.getX();
  78. double y = loc.getY();
  79. double z = loc.getZ();
  80. return loc.getWorld().getEntitiesWithinAABB(LivingEntity.class, buildBoxAround(x, y, z, radius),
  81. p -> p.getDistanceSq(x, y, z) <= sqareRadius);
  82. }
  83. public static <T extends Entity> T getEntity(IWorld w, double x, double y, double z, double radius, Class<T> type) {
  84. return getEntities(w, x, y, z, radius, type).stream()
  85. .min((e1, e2) -> Double.compare(e1.getDistanceSq(x, y, z), e2.getDistanceSq(x, y, z)))
  86. .orElse(null);
  87. }
  88. private static boolean doesIntersect(AxisAlignedBB bound, Vec3d start, Vec3d unit) {
  89. double lowerX = Double.NEGATIVE_INFINITY;
  90. double upperX = Double.POSITIVE_INFINITY;
  91. if(unit.x != 0) {
  92. if(unit.x > 0) {
  93. lowerX = (bound.minX - start.x) / unit.x;
  94. upperX = (bound.maxX - start.x) / unit.x;
  95. } else {
  96. lowerX = (bound.maxX - start.x) / unit.x;
  97. upperX = (bound.minX - start.x) / unit.x;
  98. }
  99. }
  100. double lowerY = Double.NEGATIVE_INFINITY;
  101. double upperY = Double.POSITIVE_INFINITY;
  102. if(unit.y != 0) {
  103. if(unit.y > 0) {
  104. lowerY = (bound.minY - start.y) / unit.y;
  105. upperY = (bound.maxY - start.y) / unit.y;
  106. } else {
  107. lowerY = (bound.maxY - start.y) / unit.y;
  108. upperY = (bound.minY - start.y) / unit.y;
  109. }
  110. }
  111. double lowerZ = Double.NEGATIVE_INFINITY;
  112. double upperZ = Double.POSITIVE_INFINITY;
  113. if(unit.z != 0) {
  114. if(unit.z > 0) {
  115. lowerZ = (bound.minZ - start.z) / unit.z;
  116. upperZ = (bound.maxZ - start.z) / unit.z;
  117. } else {
  118. lowerZ = (bound.maxZ - start.z) / unit.z;
  119. upperZ = (bound.minZ - start.z) / unit.z;
  120. }
  121. }
  122. return Math.max(Math.max(lowerX, lowerY), lowerZ) < Math.min(Math.min(upperX, upperY), upperZ);
  123. }
  124. private static Vec3d getTargetVector(Entity ent, double range) {
  125. if(range > 128) {
  126. range = 128;
  127. }
  128. World w = ent.getEntityWorld().getWorld();
  129. Vec3d start = ent.getEyePosition(1.0f);
  130. Vec3d look = ent.getLookVec();
  131. Vec3d end = start.add(look.x * range, look.y * range, look.z * range);
  132. RayTraceResult ray = w.rayTraceBlocks(new RayTraceContext(start, end, RayTraceContext.BlockMode.COLLIDER, RayTraceContext.FluidMode.NONE, ent));
  133. if(ray == null || ray.getHitVec() == null) {
  134. return end;
  135. }
  136. return ray.getHitVec();
  137. }
  138. @SuppressWarnings("unchecked")
  139. public static <T extends Entity> T getTargetedEntity(PlayerEntity p, double radius, Class<T> type) {
  140. World w = p.getEntityWorld().getWorld();
  141. Vec3d l = getTargetVector(p, radius);
  142. Vec3d eye = p.getEyePosition(1.0f);
  143. Vec3d unit = new Vec3d(l.x - eye.x, l.y - eye.y, l.z - eye.z);
  144. List<Entity> col = w.getEntitiesWithinAABBExcludingEntity(p, new AxisAlignedBB(eye.x, eye.y, eye.z, l.x, l.y, l.z));
  145. col.removeIf(ent -> !type.isAssignableFrom(ent.getClass()));
  146. // removes entities, which do not intersect with the sight vector
  147. col.removeIf(ent -> !doesIntersect(ent.getBoundingBox().grow(0.1), eye, unit));
  148. return (T) col.stream().sorted((Entity e1, Entity e2) -> {
  149. return Double.compare(e1.getDistanceSq(eye.x, eye.y, eye.z), e2.getDistanceSq(eye.x, eye.y, eye.z));
  150. }).findFirst().orElse(null);
  151. }
  152. // -------------------------------------------------------------------------
  153. // Player-Tools
  154. // -------------------------------------------------------------------------
  155. public static ServerPlayerEntity getPlayerByName(MinecraftServer server, String name) {
  156. String nameLower = name.toLowerCase();
  157. return server.getPlayerList().getPlayers().stream()
  158. .filter(pl -> pl.getName().getUnformattedComponentText().toLowerCase().contains(nameLower))
  159. .findFirst().orElse(null);
  160. }
  161. }