mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-24 05:47:59 +01:00
Ssome more cleanup
This commit is contained in:
parent
312afe3d46
commit
5c2e156392
4 changed files with 174 additions and 178 deletions
|
@ -16,125 +16,138 @@ import net.minecraft.world.World;
|
||||||
|
|
||||||
public class TreeTraverser {
|
public class TreeTraverser {
|
||||||
|
|
||||||
public static void removeTree(World w, BlockPos pos) {
|
public static class Remover {
|
||||||
BlockState log = w.getBlockState(pos);
|
/**
|
||||||
|
* Removes the tree located at the given position.
|
||||||
|
*/
|
||||||
|
public static void removeTree(World w, BlockPos pos) {
|
||||||
|
BlockState log = w.getBlockState(pos);
|
||||||
|
|
||||||
int size = measureTree(w, log, pos);
|
if (Measurer.measureTree(w, log, pos) > 0) {
|
||||||
|
removeTreePart(w, log, Ascender.ascendTrunk(new HashSet<BlockPos>(), w, pos, log, 0).get(), 0);
|
||||||
if (size > 0) {
|
|
||||||
removeTreePart(w, log, ascendTrunk(new HashSet<BlockPos>(), w, pos, log, 0).get(), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void removeTreePart(World w, BlockState log, BlockPos pos, int level) {
|
|
||||||
if (level < 10 && isWoodOrLeaf(w, log, pos)) {
|
|
||||||
if (level < 5) {
|
|
||||||
w.breakBlock(pos, true);
|
|
||||||
} else {
|
|
||||||
Block.dropStacks(w.getBlockState(pos), w, pos);
|
|
||||||
w.setBlockState(pos, Blocks.AIR.getDefaultState(), 3);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PosHelper.all(pos, p -> {
|
private static void removeTreePart(World w, BlockState log, BlockPos pos, int level) {
|
||||||
removeTreePart(w, log, p, level + 1);
|
if (level < 10 && isWoodOrLeaf(w, log, pos)) {
|
||||||
}, Direction.UP, Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST);
|
breakBlock(w, pos, level < 5);
|
||||||
|
|
||||||
|
PosHelper.all(pos, p -> {
|
||||||
|
removeTreePart(w, log, p, level + 1);
|
||||||
|
}, Direction.UP, Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Optional<BlockPos> ascendTrunk(Set<BlockPos> done, World w, BlockPos pos, BlockState log, int level) {
|
public static class Ascender {
|
||||||
if (level < 3 && !done.contains(pos)) {
|
/**
|
||||||
done.add(pos);
|
* Locates the top of the tree's trunk. Usually the point where wood meets leaves.
|
||||||
|
*/
|
||||||
BlockPos.Mutable result = new BlockPos.Mutable();
|
public static BlockPos ascendTree(World w, BlockState log, BlockPos pos, boolean remove) {
|
||||||
result.set(ascendTree(w, log, pos, true));
|
int breaks = 0;
|
||||||
|
while (variantAndBlockEquals(w.getBlockState(pos.up()), log)) {
|
||||||
PosHelper.all(pos, p -> {
|
if (PosHelper.any(pos, p -> isLeaves(w.getBlockState(p), log), Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST)) {
|
||||||
if (variantAndBlockEquals(w.getBlockState(pos.east()), log)) {
|
break;
|
||||||
ascendTrunk(done, w, pos.east(), log, level + 1).filter(a -> a.getY() > result.getY()).ifPresent(result::set);
|
|
||||||
}
|
}
|
||||||
}, Direction.EAST, Direction.WEST, Direction.NORTH, Direction.SOUTH);
|
|
||||||
|
|
||||||
done.add(result.toImmutable());
|
if (remove) {
|
||||||
return Optional.of(result.toImmutable());
|
breakBlock(w, pos, breaks++ < 10);
|
||||||
}
|
|
||||||
return Optional.of(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BlockPos ascendTree(World w, BlockState log, BlockPos pos, boolean remove) {
|
|
||||||
int breaks = 0;
|
|
||||||
BlockState state;
|
|
||||||
while (variantAndBlockEquals(w.getBlockState(pos.up()), log)) {
|
|
||||||
if (PosHelper.some(pos, p -> isLeaves(w.getBlockState(p), log), Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (remove) {
|
|
||||||
if (breaks < 10) {
|
|
||||||
w.breakBlock(pos, true);
|
|
||||||
} else {
|
|
||||||
state = w.getBlockState(pos);
|
|
||||||
Block.dropStacks(state, w, pos);
|
|
||||||
w.setBlockState(pos, Blocks.AIR.getDefaultState(), 3);
|
|
||||||
}
|
}
|
||||||
breaks++;
|
pos = pos.up();
|
||||||
}
|
}
|
||||||
pos = pos.up();
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Optional<BlockPos> ascendTrunk(Set<BlockPos> done, World w, BlockPos pos, BlockState log, int level) {
|
||||||
|
if (level < 3 && !done.contains(pos)) {
|
||||||
|
done.add(pos);
|
||||||
|
|
||||||
|
BlockPos.Mutable result = new BlockPos.Mutable();
|
||||||
|
result.set(ascendTree(w, log, pos, true));
|
||||||
|
|
||||||
|
PosHelper.all(pos, p -> {
|
||||||
|
if (variantAndBlockEquals(w.getBlockState(pos.east()), log)) {
|
||||||
|
ascendTrunk(done, w, pos.east(), log, level + 1).filter(a -> a.getY() > result.getY()).ifPresent(result::set);
|
||||||
|
}
|
||||||
|
}, Direction.EAST, Direction.WEST, Direction.NORTH, Direction.SOUTH);
|
||||||
|
|
||||||
|
done.add(result.toImmutable());
|
||||||
|
return Optional.of(result.toImmutable());
|
||||||
|
}
|
||||||
|
return Optional.of(pos);
|
||||||
}
|
}
|
||||||
return pos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Optional<BlockPos> descendTree(World w, BlockState log, BlockPos pos) {
|
public static class Descender {
|
||||||
return descendTreePart(new HashSet<BlockPos>(), w, log, new BlockPos.Mutable(pos.getX(), pos.getY(), pos.getZ()));
|
/**
|
||||||
|
* Recursively locates the base of the tree.
|
||||||
|
*/
|
||||||
|
public static Optional<BlockPos> descendTree(World w, BlockState log, BlockPos pos) {
|
||||||
|
return descendTreePart(new HashSet<BlockPos>(), w, log, new BlockPos.Mutable(pos.getX(), pos.getY(), pos.getZ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Optional<BlockPos> descendTreePart(Set<BlockPos> done, World w, BlockState log, BlockPos.Mutable pos) {
|
||||||
|
if (done.contains(pos) || !variantAndBlockEquals(w.getBlockState(pos), log)) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
done.add(pos.toImmutable());
|
||||||
|
while (variantAndBlockEquals(w.getBlockState(pos.down()), log)) {
|
||||||
|
done.add(pos.move(Direction.DOWN).toImmutable());
|
||||||
|
}
|
||||||
|
|
||||||
|
PosHelper.all(pos.toImmutable(), p -> {
|
||||||
|
descendTreePart(done, w, log, new BlockPos.Mutable(p.getX(), p.getY(), p.getZ())).filter(a -> a.getY() < pos.getY()).ifPresent(pos::set);
|
||||||
|
}, Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST);
|
||||||
|
|
||||||
|
done.add(pos.toImmutable());
|
||||||
|
return Optional.of(pos.toImmutable());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Optional<BlockPos> descendTreePart(Set<BlockPos> done, World w, BlockState log, BlockPos.Mutable pos) {
|
public static class Measurer {
|
||||||
if (done.contains(pos) || !variantAndBlockEquals(w.getBlockState(pos), log)) {
|
/**
|
||||||
return Optional.empty();
|
* Counts the number of logs and leaves present in the targeted tree.
|
||||||
|
*/
|
||||||
|
public static int measureTree(World w, BlockState log, BlockPos pos) {
|
||||||
|
Set<BlockPos> logs = new HashSet<>();
|
||||||
|
Set<BlockPos> leaves = new HashSet<>();
|
||||||
|
|
||||||
|
countParts(logs, leaves, w, log, pos);
|
||||||
|
|
||||||
|
return logs.size() <= (leaves.size() / 2) ? logs.size() + leaves.size() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
done.add(pos.toImmutable());
|
private static void countParts(Set<BlockPos> logs, Set<BlockPos> leaves, World w, BlockState log, BlockPos pos) {
|
||||||
while (variantAndBlockEquals(w.getBlockState(pos.down()), log)) {
|
if (logs.contains(pos) || leaves.contains(pos)) {
|
||||||
done.add(pos.move(Direction.DOWN).toImmutable());
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockState state = w.getBlockState(pos);
|
||||||
|
boolean yay = false;
|
||||||
|
|
||||||
|
if (isLeaves(state, log) && !state.get(LeavesBlock.PERSISTENT)) {
|
||||||
|
leaves.add(pos);
|
||||||
|
yay = true;
|
||||||
|
} else if (variantAndBlockEquals(state, log)) {
|
||||||
|
logs.add(pos);
|
||||||
|
yay = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yay) {
|
||||||
|
PosHelper.all(pos, p -> {
|
||||||
|
countParts(logs, leaves, w, log, p);
|
||||||
|
}, Direction.UP, Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PosHelper.all(pos.toImmutable(), p -> {
|
|
||||||
descendTreePart(done, w, log, new BlockPos.Mutable(p.getX(), p.getY(), p.getZ())).filter(a -> a.getY() < pos.getY()).ifPresent(pos::set);
|
|
||||||
}, Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST);
|
|
||||||
|
|
||||||
done.add(pos.toImmutable());
|
|
||||||
return Optional.of(pos.toImmutable());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int measureTree(World w, BlockState log, BlockPos pos) {
|
private static void breakBlock(World w, BlockPos pos, boolean destroy) {
|
||||||
Set<BlockPos> logs = new HashSet<>();
|
if (destroy) {
|
||||||
Set<BlockPos> leaves = new HashSet<>();
|
w.breakBlock(pos, true);
|
||||||
|
} else {
|
||||||
countParts(logs, leaves, w, log, pos);
|
Block.dropStacks(w.getBlockState(pos), w, pos);
|
||||||
|
w.setBlockState(pos, Blocks.AIR.getDefaultState(), 3);
|
||||||
return logs.size() <= (leaves.size() / 2) ? logs.size() + leaves.size() : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void countParts(Set<BlockPos> logs, Set<BlockPos> leaves, World w, BlockState log, BlockPos pos) {
|
|
||||||
if (logs.contains(pos) || leaves.contains(pos)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockState state = w.getBlockState(pos);
|
|
||||||
boolean yay = false;
|
|
||||||
|
|
||||||
if (isLeaves(state, log) && !state.get(LeavesBlock.PERSISTENT)) {
|
|
||||||
leaves.add(pos);
|
|
||||||
yay = true;
|
|
||||||
} else if (variantAndBlockEquals(state, log)) {
|
|
||||||
logs.add(pos);
|
|
||||||
yay = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (yay) {
|
|
||||||
PosHelper.all(pos, p -> {
|
|
||||||
countParts(logs, leaves, w, log, p);
|
|
||||||
}, Direction.UP, Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,8 +81,8 @@ public class EarthPonyStompAbility implements Ability<Multi> {
|
||||||
BlockState state = player.getWorld().getBlockState(pos);
|
BlockState state = player.getWorld().getBlockState(pos);
|
||||||
|
|
||||||
if (state.getBlock().isIn(BlockTags.LOGS)) {
|
if (state.getBlock().isIn(BlockTags.LOGS)) {
|
||||||
pos = TreeTraverser.descendTree(player.getWorld(), state, pos).get();
|
pos = TreeTraverser.Descender.descendTree(player.getWorld(), state, pos).get();
|
||||||
if (TreeTraverser.measureTree(player.getWorld(), state, pos) > 0) {
|
if (TreeTraverser.Measurer.measureTree(player.getWorld(), state, pos) > 0) {
|
||||||
return new Multi(pos, 1);
|
return new Multi(pos, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,7 +164,7 @@ public class EarthPonyStompAbility implements Ability<Multi> {
|
||||||
if (harmed || player.world.random.nextInt(5) == 0) {
|
if (harmed || player.world.random.nextInt(5) == 0) {
|
||||||
|
|
||||||
if (!harmed || player.world.random.nextInt(30) == 0) {
|
if (!harmed || player.world.random.nextInt(30) == 0) {
|
||||||
TreeTraverser.removeTree(player.world, data.pos());
|
TreeTraverser.Remover.removeTree(player.world, data.pos());
|
||||||
}
|
}
|
||||||
|
|
||||||
iplayer.subtractEnergyCost(3);
|
iplayer.subtractEnergyCost(3);
|
||||||
|
@ -223,7 +223,7 @@ public class EarthPonyStompAbility implements Ability<Multi> {
|
||||||
|
|
||||||
private int dropApples(World w, BlockPos pos) {
|
private int dropApples(World w, BlockPos pos) {
|
||||||
BlockState log = w.getBlockState(pos);
|
BlockState log = w.getBlockState(pos);
|
||||||
int size = TreeTraverser.measureTree(w, log, pos);
|
int size = TreeTraverser.Measurer.measureTree(w, log, pos);
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
|
|
||||||
List<ItemEntity> capturedDrops = Lists.newArrayList();
|
List<ItemEntity> capturedDrops = Lists.newArrayList();
|
||||||
|
@ -244,7 +244,7 @@ public class EarthPonyStompAbility implements Ability<Multi> {
|
||||||
private static void dropApplesPart(List<ItemEntity> drops, List<BlockPos> done, World w, BlockState log, BlockPos pos, int level) {
|
private static void dropApplesPart(List<ItemEntity> drops, List<BlockPos> done, World w, BlockState log, BlockPos pos, int level) {
|
||||||
if (!done.contains(pos)) {
|
if (!done.contains(pos)) {
|
||||||
done.add(pos);
|
done.add(pos);
|
||||||
pos = TreeTraverser.ascendTree(w, log, pos, false);
|
pos = TreeTraverser.Ascender.ascendTree(w, log, pos, false);
|
||||||
if (level < 10 && TreeTraverser.isWoodOrLeaf(w, log, pos)) {
|
if (level < 10 && TreeTraverser.isWoodOrLeaf(w, log, pos)) {
|
||||||
BlockState state = w.getBlockState(pos);
|
BlockState state = w.getBlockState(pos);
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.minelittlepony.unicopia.util;
|
package com.minelittlepony.unicopia.util;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Spliterator;
|
import java.util.Spliterator;
|
||||||
import java.util.Spliterators.AbstractSpliterator;
|
import java.util.Spliterators.AbstractSpliterator;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
@ -39,7 +38,7 @@ public interface PosHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean some(BlockPos origin, Predicate<BlockPos> consumer, Direction... directions) {
|
static boolean any(BlockPos origin, Predicate<BlockPos> consumer, Direction... directions) {
|
||||||
for (Direction facing : directions) {
|
for (Direction facing : directions) {
|
||||||
if (consumer.test(origin.offset(facing))) {
|
if (consumer.test(origin.offset(facing))) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -49,17 +48,15 @@ public interface PosHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
static Stream<BlockPos> adjacentNeighbours(BlockPos origin) {
|
static Stream<BlockPos> adjacentNeighbours(BlockPos origin) {
|
||||||
BlockPos.Mutable pos = new BlockPos.Mutable(origin.getX(), origin.getY(), origin.getZ());
|
return StreamSupport.stream(new AbstractSpliterator<BlockPos>(Direction.values().length, Spliterator.SIZED) {
|
||||||
List<Direction> directions = Lists.newArrayList(Direction.values());
|
private final BlockPos.Mutable pos = new BlockPos.Mutable();
|
||||||
Iterator<Direction> iter = directions.iterator();
|
private final Iterator<Direction> iter = Lists.newArrayList(Direction.values()).iterator();
|
||||||
return StreamSupport.stream(new AbstractSpliterator<BlockPos>(directions.size(), Spliterator.SIZED) {
|
|
||||||
@Override
|
@Override
|
||||||
public boolean tryAdvance(Consumer<? super BlockPos> consumer) {
|
public boolean tryAdvance(Consumer<? super BlockPos> consumer) {
|
||||||
if (iter.hasNext()) {
|
if (iter.hasNext()) {
|
||||||
Direction next = iter.next();
|
Direction next = iter.next();
|
||||||
|
consumer.accept(pos.set(origin.getX() + next.getOffsetX(), origin.getY() + next.getOffsetY(), origin.getZ() + next.getOffsetZ()));
|
||||||
pos.set(origin.getX() + next.getOffsetX(), origin.getY() + next.getOffsetY(), origin.getZ() + next.getOffsetZ());
|
|
||||||
consumer.accept(pos);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.minelittlepony.unicopia.util;
|
package com.minelittlepony.unicopia.util;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
@ -15,82 +14,83 @@ import net.minecraft.util.hit.HitResult;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Box;
|
import net.minecraft.util.math.Box;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.RayTraceContext;
|
|
||||||
|
|
||||||
public class RayTraceHelper {
|
public class RayTraceHelper {
|
||||||
public static <T extends Entity> Optional<T> findEntity(Entity e, double distance) {
|
public static <T extends Entity> Optional<T> findEntity(Entity e, double distance, float tickDelta, Predicate<Entity> predicate) {
|
||||||
return doTrace(e, distance, 1).getEntity();
|
return doTrace(e, distance, tickDelta, EntityPredicates.EXCEPT_SPECTATOR.and(predicate)).getEntity();
|
||||||
}
|
|
||||||
|
|
||||||
public static <T extends Entity> Optional<T> findEntity(Entity e, double distance, float partialTick, Predicate<Entity> predicate) {
|
|
||||||
return doTrace(e, distance, partialTick, EntityPredicates.EXCEPT_SPECTATOR.and(predicate)).getEntity();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Trace doTrace(Entity e, double distance, float partialTick) {
|
|
||||||
return doTrace(e, distance, partialTick, EntityPredicates.EXCEPT_SPECTATOR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs a ray trace from the given entity and returns a result for the first Entity that passing the given predicate or block that the ray intercepts.
|
* Performs a ray trace from the given entity and returns
|
||||||
* <p>
|
* a result for the first Entity or block that the ray intercepts.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @param e Entity to start from
|
* @param e Entity to start from
|
||||||
* @param distance Maximum distance
|
* @param distance Maximum distance
|
||||||
* @param partialTick Client partial ticks
|
* @param tickDelta Client partial ticks
|
||||||
* @param predicate Predicate test to filter entities
|
|
||||||
*
|
*
|
||||||
* @return A OptionalHit describing what was found.
|
* @return A Trace describing what was found.
|
||||||
*/
|
*/
|
||||||
public static Trace doTrace(Entity e, double distance, float partialTick, Predicate<Entity> predicate) {
|
public static Trace doTrace(Entity e, double distance, float tickDelta) {
|
||||||
HitResult tracedBlock = traceBlocks(e, distance, partialTick, false);
|
return doTrace(e, distance, tickDelta, EntityPredicates.EXCEPT_SPECTATOR);
|
||||||
|
}
|
||||||
|
|
||||||
double totalTraceDistance = distance;
|
/**
|
||||||
|
* Performs a ray trace from the given entity and returns
|
||||||
|
* a result for the first Entity that passes the given predicate
|
||||||
|
* or block that the ray intercepts.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param e Entity to start from
|
||||||
|
* @param distance Maximum distance
|
||||||
|
* @param tickDelta Client partial ticks
|
||||||
|
* @param predicate Predicate test to filter entities
|
||||||
|
*
|
||||||
|
* @return A Trace describing what was found.
|
||||||
|
*/
|
||||||
|
public static Trace doTrace(Entity e, double distance, float tickDelta, Predicate<Entity> predicate) {
|
||||||
|
HitResult tracedBlock = e.rayTrace(distance, tickDelta, false);
|
||||||
|
|
||||||
Vec3d pos = e.getCameraPosVec(partialTick);
|
final Vec3d start = e.getCameraPosVec(tickDelta);
|
||||||
|
|
||||||
if (tracedBlock != null) {
|
final double totalTraceDistance = tracedBlock == null ? distance : tracedBlock.getPos().distanceTo(start);
|
||||||
totalTraceDistance = tracedBlock.getPos().distanceTo(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3d look = e.getRotationVec(partialTick);
|
final Vec3d ray = e.getRotationVec(tickDelta).multiply(distance);
|
||||||
Vec3d ray = pos.add(look.multiply(distance));
|
final Vec3d end = start.add(ray);
|
||||||
|
|
||||||
Vec3d hit = null;
|
Vec3d hit = null;
|
||||||
Entity pointedEntity = null;
|
Entity pointedEntity = null;
|
||||||
List<Entity> entitiesWithinRange = e.world.getOtherEntities(e, e.getBoundingBox()
|
|
||||||
.expand(look.x * distance, look.y * distance, look.z * distance)
|
|
||||||
.expand(1, 1, 1), predicate);
|
|
||||||
|
|
||||||
double traceDistance = totalTraceDistance;
|
double traceDistance = totalTraceDistance;
|
||||||
|
|
||||||
for (Entity entity : entitiesWithinRange) {
|
for (Entity entity : e.world.getOtherEntities(e,
|
||||||
if (entity.collides()) {
|
e.getBoundingBox().expand(ray.x + 1, ray.y + 1, ray.z + 1),
|
||||||
Box entityAABB = entity.getBoundingBox().expand(entity.getTargetingMargin());
|
predicate.and(Entity::collides)
|
||||||
|
)) {
|
||||||
|
Box entityAABB = entity.getBoundingBox().expand(entity.getTargetingMargin());
|
||||||
|
|
||||||
Optional<Vec3d> intercept = entityAABB.rayTrace(pos, ray);
|
Optional<Vec3d> intercept = entityAABB.rayTrace(start, end);
|
||||||
|
|
||||||
if (entityAABB.contains(pos)) {
|
if (entityAABB.contains(start)) {
|
||||||
if (traceDistance <= 0) {
|
if (traceDistance <= 0) {
|
||||||
pointedEntity = entity;
|
pointedEntity = entity;
|
||||||
hit = intercept.orElse(null);
|
hit = intercept.orElse(null);
|
||||||
traceDistance = 0;
|
traceDistance = 0;
|
||||||
}
|
}
|
||||||
} else if (intercept.isPresent()) {
|
} else if (intercept.isPresent()) {
|
||||||
Vec3d inter = intercept.get();
|
Vec3d inter = intercept.get();
|
||||||
double distanceToHit = pos.distanceTo(inter);
|
double distanceToHit = start.distanceTo(inter);
|
||||||
|
|
||||||
if (distanceToHit < traceDistance || traceDistance == 0) {
|
if (distanceToHit < traceDistance || traceDistance == 0) {
|
||||||
if (entity.getRootVehicle() == e.getRootVehicle()) {
|
if (entity.getRootVehicle() == e.getRootVehicle()) {
|
||||||
if (traceDistance == 0) {
|
if (traceDistance == 0) {
|
||||||
pointedEntity = entity;
|
|
||||||
hit = inter;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pointedEntity = entity;
|
pointedEntity = entity;
|
||||||
hit = inter;
|
hit = inter;
|
||||||
traceDistance = distanceToHit;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
pointedEntity = entity;
|
||||||
|
hit = inter;
|
||||||
|
traceDistance = distanceToHit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,20 +103,6 @@ public class RayTraceHelper {
|
||||||
return new Trace(tracedBlock);
|
return new Trace(tracedBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Server-available version of Entity.rayTrace
|
|
||||||
*/
|
|
||||||
public static HitResult traceBlocks(Entity e, double maxDistance, float tickDelta, boolean includeFluids) {
|
|
||||||
Vec3d start = e.getCameraPosVec(tickDelta);
|
|
||||||
Vec3d end = e.getRotationVec(tickDelta).multiply(maxDistance).add(start);
|
|
||||||
|
|
||||||
return e.world.rayTrace(new RayTraceContext(start, end,
|
|
||||||
RayTraceContext.ShapeType.OUTLINE,
|
|
||||||
includeFluids ? RayTraceContext.FluidHandling.ANY : RayTraceContext.FluidHandling.NONE,
|
|
||||||
e)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Trace {
|
public static class Trace {
|
||||||
@Nullable
|
@Nullable
|
||||||
private final HitResult result;
|
private final HitResult result;
|
||||||
|
|
Loading…
Reference in a new issue