Utils.java 8.0 KB

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