mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-02 14:38:26 +01:00
Code review
This commit is contained in:
parent
f2f592209a
commit
66e8ac2dc3
@ -138,6 +138,8 @@ public class BoundingBox {
|
|||||||
* @return true if the bounding box intersects with the line segment, false otherwise.
|
* @return true if the bounding box intersects with the line segment, false otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean intersect(double x1, double y1, double z1, double x2, double y2, double z2) {
|
public boolean intersect(double x1, double y1, double z1, double x2, double y2, double z2) {
|
||||||
|
// originally from http://www.3dkingdoms.com/weekly/weekly.php?a=3
|
||||||
|
|
||||||
double x3 = getMinX();
|
double x3 = getMinX();
|
||||||
double x4 = getMaxX();
|
double x4 = getMaxX();
|
||||||
double y3 = getMinY();
|
double y3 = getMinY();
|
||||||
@ -152,12 +154,12 @@ public class BoundingBox {
|
|||||||
z1 < z3 && z2 < z3 || z1 > z4 && z2 > z4) {
|
z1 < z3 && z2 < z3 || z1 > z4 && z2 > z4) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return isInsideBoxWithAxis(1, getSegmentIntersection(x1 - x3, x2 - x3, x1, y1, z1, x2, y2, z2)) ||
|
return isInsideBoxWithAxis(Axis.X, getSegmentIntersection(x1 - x3, x2 - x3, x1, y1, z1, x2, y2, z2)) ||
|
||||||
isInsideBoxWithAxis(1, getSegmentIntersection(x1 - x4, x2 - x4, x1, y1, z1, x2, y2, z2)) ||
|
isInsideBoxWithAxis(Axis.X, getSegmentIntersection(x1 - x4, x2 - x4, x1, y1, z1, x2, y2, z2)) ||
|
||||||
isInsideBoxWithAxis(2, getSegmentIntersection(y1 - y3, y2 - y3, x1, y1, z1, x2, y2, z2)) ||
|
isInsideBoxWithAxis(Axis.Y, getSegmentIntersection(y1 - y3, y2 - y3, x1, y1, z1, x2, y2, z2)) ||
|
||||||
isInsideBoxWithAxis(2, getSegmentIntersection(y1 - y4, y2 - y4, x1, y1, z1, x2, y2, z2)) ||
|
isInsideBoxWithAxis(Axis.Y, getSegmentIntersection(y1 - y4, y2 - y4, x1, y1, z1, x2, y2, z2)) ||
|
||||||
isInsideBoxWithAxis(3, getSegmentIntersection(z1 - z3, z2 - z3, x1, y1, z1, x2, y2, z2)) ||
|
isInsideBoxWithAxis(Axis.Z, getSegmentIntersection(z1 - z3, z2 - z3, x1, y1, z1, x2, y2, z2)) ||
|
||||||
isInsideBoxWithAxis(3, getSegmentIntersection(z1 - z4, z2 - z4, x1, y1, z1, x2, y2, z2));
|
isInsideBoxWithAxis(Axis.Z, getSegmentIntersection(z1 - z4, z2 - z4, x1, y1, z1, x2, y2, z2));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -190,7 +192,7 @@ public class BoundingBox {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isInsideBoxWithAxis(int axis, @Nullable Vec intersection) {
|
private boolean isInsideBoxWithAxis(Axis axis, @Nullable Vec intersection) {
|
||||||
if (intersection == null) {
|
if (intersection == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -200,9 +202,9 @@ public class BoundingBox {
|
|||||||
double y2 = getMaxY();
|
double y2 = getMaxY();
|
||||||
double z1 = getMinZ();
|
double z1 = getMinZ();
|
||||||
double z2 = getMaxZ();
|
double z2 = getMaxZ();
|
||||||
return axis == 1 && intersection.z() > z1 && intersection.z() < z2 && intersection.y() > y1 && intersection.y() < y2 ||
|
return axis == Axis.X && intersection.z() > z1 && intersection.z() < z2 && intersection.y() > y1 && intersection.y() < y2 ||
|
||||||
axis == 2 && intersection.z() > z1 && intersection.z() < z2 && intersection.x() > x1 && intersection.x() < x2 ||
|
axis == Axis.Y && intersection.z() > z1 && intersection.z() < z2 && intersection.x() > x1 && intersection.x() < x2 ||
|
||||||
axis == 3 && intersection.x() > x1 && intersection.x() < x2 && intersection.y() > y1 && intersection.y() < y2;
|
axis == Axis.Z && intersection.x() > x1 && intersection.x() < x2 && intersection.y() > y1 && intersection.y() < y2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -417,4 +419,9 @@ public class BoundingBox {
|
|||||||
this.lastPosition = entityPos;
|
this.lastPosition = entityPos;
|
||||||
return vecSupplier.get();
|
return vecSupplier.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum Axis {
|
||||||
|
X, Y, Z
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1455,26 +1455,7 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<Entity> getNearbyEntities(double range) {
|
|
||||||
Instance instance = getInstance();
|
|
||||||
if (instance == null) {
|
|
||||||
return Collections.emptySet();
|
|
||||||
}
|
|
||||||
int minX = ChunkUtils.getChunkCoordinate(position.x() - range);
|
|
||||||
int maxX = ChunkUtils.getChunkCoordinate(position.x() + range);
|
|
||||||
int minZ = ChunkUtils.getChunkCoordinate(position.z() - range);
|
|
||||||
int maxZ = ChunkUtils.getChunkCoordinate(position.z() + range);
|
|
||||||
List<Entity> result = new ArrayList<>();
|
|
||||||
for (int x = minX; x <= maxX; ++x) {
|
|
||||||
for (int z = minZ; z <= maxZ; ++z) {
|
|
||||||
Chunk chunk = instance.getChunk(x, z);
|
|
||||||
if (chunk != null) {
|
|
||||||
result.addAll(instance.getChunkEntities(chunk));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the line of sight of the entity.
|
* Gets the line of sight of the entity.
|
||||||
@ -1483,11 +1464,16 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler
|
|||||||
* @return A list of {@link Point poiints} in this entities line of sight
|
* @return A list of {@link Point poiints} in this entities line of sight
|
||||||
*/
|
*/
|
||||||
public List<Point> getLineOfSight(int maxDistance) {
|
public List<Point> getLineOfSight(int maxDistance) {
|
||||||
|
Instance instance = getInstance();
|
||||||
|
if (instance == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
List<Point> blocks = new ArrayList<>();
|
List<Point> blocks = new ArrayList<>();
|
||||||
Iterator<Point> it = new BlockIterator(this, maxDistance);
|
var it = new BlockIterator(this, maxDistance);
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
final Point position = it.next();
|
final Point position = it.next();
|
||||||
if (!getInstance().getBlock(position).isAir()) blocks.add(position);
|
if (!instance.getBlock(position).isAir()) blocks.add(position);
|
||||||
}
|
}
|
||||||
return blocks;
|
return blocks;
|
||||||
}
|
}
|
||||||
@ -1501,14 +1487,19 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler
|
|||||||
* @return if the current entity has line of sight to the given one.
|
* @return if the current entity has line of sight to the given one.
|
||||||
*/
|
*/
|
||||||
public boolean hasLineOfSight(Entity entity) {
|
public boolean hasLineOfSight(Entity entity) {
|
||||||
final var start = getPosition().asVec().add(0D, getEyeHeight(), 0D);
|
Instance instance = getInstance();
|
||||||
final var end = entity.getPosition().asVec().add(0D, getEyeHeight(), 0D);
|
if (instance == null) {
|
||||||
final var direction = end.sub(start);
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Vec start = getPosition().asVec().add(0D, getEyeHeight(), 0D);
|
||||||
|
final Vec end = entity.getPosition().asVec().add(0D, getEyeHeight(), 0D);
|
||||||
|
final Vec direction = end.sub(start);
|
||||||
final int maxDistance = (int) Math.ceil(direction.length());
|
final int maxDistance = (int) Math.ceil(direction.length());
|
||||||
|
|
||||||
Iterator<Point> it = new BlockIterator(start, direction.normalize(), 0D, maxDistance);
|
var it = new BlockIterator(start, direction.normalize(), 0D, maxDistance);
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
Block block = getInstance().getBlock(it.next());
|
Block block = instance.getBlock(it.next());
|
||||||
if (!block.isAir() && !block.isLiquid()) {
|
if (!block.isAir() && !block.isLiquid()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1520,34 +1511,32 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler
|
|||||||
* Gets first entity on the line of sight of the current one that matches the given predicate.
|
* Gets first entity on the line of sight of the current one that matches the given predicate.
|
||||||
*
|
*
|
||||||
* @param range max length of the line of sight of the current entity to be checked.
|
* @param range max length of the line of sight of the current entity to be checked.
|
||||||
* @param predicate optional predicate, defaults to "accept any".
|
* @param predicate optional predicate
|
||||||
* @return resulting entity whether there're any, null otherwise.
|
* @return resulting entity whether there're any, null otherwise.
|
||||||
*/
|
*/
|
||||||
public @Nullable Entity getLineOfSightEntity(double range, @Nullable Predicate<Entity> predicate) {
|
public @Nullable Entity getLineOfSightEntity(double range, Predicate<Entity> predicate) {
|
||||||
var instance = getInstance();
|
Instance instance = getInstance();
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var start = new Vec(position.x(), position.y() + getEyeHeight(), position.z());
|
Vec start = new Vec(position.x(), position.y() + getEyeHeight(), position.z());
|
||||||
var end = start.add(position.direction().mul(range));
|
Vec end = start.add(position.direction().mul(range));
|
||||||
|
|
||||||
var finalPredicate = Objects.requireNonNullElseGet(predicate, () -> e -> true);
|
List<Entity> nearby = instance.getNearbyEntities(position, range).stream()
|
||||||
|
.filter(e -> e != this && e.boundingBox.intersect(start, end) && predicate.test(e))
|
||||||
var nearby = getNearbyEntities(range).stream()
|
|
||||||
.filter(e -> e != this && e.boundingBox.intersect(start, end) && finalPredicate.test(e))
|
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
if (nearby.isEmpty()) {
|
if (nearby.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var direction = end.sub(start);
|
Vec direction = end.sub(start);
|
||||||
int maxDistance = (int) Math.ceil(direction.length());
|
int maxDistance = (int) Math.ceil(direction.length());
|
||||||
double maxVisibleDistanceSquared = direction.lengthSquared();
|
double maxVisibleDistanceSquared = direction.lengthSquared();
|
||||||
|
|
||||||
Iterator<Point> iterator = new BlockIterator(start, direction.normalize(), 0D, maxDistance);
|
var iterator = new BlockIterator(start, direction.normalize(), 0D, maxDistance);
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
var blockPos = iterator.next();
|
Point blockPos = iterator.next();
|
||||||
Block block = instance.getBlock(blockPos);
|
Block block = instance.getBlock(blockPos);
|
||||||
if (!block.isAir() && !block.isLiquid()) {
|
if (!block.isAir() && !block.isLiquid()) {
|
||||||
maxVisibleDistanceSquared = blockPos.distanceSquared(position);
|
maxVisibleDistanceSquared = blockPos.distanceSquared(position);
|
||||||
@ -1557,7 +1546,7 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler
|
|||||||
|
|
||||||
Entity result = null;
|
Entity result = null;
|
||||||
double minDistanceSquared = 0D;
|
double minDistanceSquared = 0D;
|
||||||
for (var entity : nearby) {
|
for (Entity entity : nearby) {
|
||||||
double distanceSquared = entity.getDistanceSquared(this);
|
double distanceSquared = entity.getDistanceSquared(this);
|
||||||
if (result == null || minDistanceSquared > distanceSquared) {
|
if (result == null || minDistanceSquared > distanceSquared) {
|
||||||
result = entity;
|
result = entity;
|
||||||
|
@ -489,6 +489,32 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta
|
|||||||
return Collections.unmodifiableSet(entities);
|
return Collections.unmodifiableSet(entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets nearby entities to the given position.
|
||||||
|
*
|
||||||
|
* @param point position to look at
|
||||||
|
* @param range max range from the given point to collect entities at
|
||||||
|
* @return entities that are not further than the specified distance from the transmitted position.
|
||||||
|
*/
|
||||||
|
public @NotNull Collection<Entity> getNearbyEntities(@NotNull Point point, double range) {
|
||||||
|
int minX = ChunkUtils.getChunkCoordinate(point.x() - range);
|
||||||
|
int maxX = ChunkUtils.getChunkCoordinate(point.x() + range);
|
||||||
|
int minZ = ChunkUtils.getChunkCoordinate(point.z() - range);
|
||||||
|
int maxZ = ChunkUtils.getChunkCoordinate(point.z() + range);
|
||||||
|
List<Entity> result = new ArrayList<>();
|
||||||
|
synchronized (entitiesLock) {
|
||||||
|
for (int x = minX; x <= maxX; ++x) {
|
||||||
|
for (int z = minZ; z <= maxZ; ++z) {
|
||||||
|
Chunk chunk = getChunk(x, z);
|
||||||
|
if (chunk != null) {
|
||||||
|
result.addAll(getChunkEntities(chunk));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable Block getBlock(int x, int y, int z, @NotNull Condition condition) {
|
public @Nullable Block getBlock(int x, int y, int z, @NotNull Condition condition) {
|
||||||
final Chunk chunk = getChunkAt(x, z);
|
final Chunk chunk = getChunkAt(x, z);
|
||||||
|
Loading…
Reference in New Issue
Block a user