use of thpmc.vanilla_source.api.world.cache.EngineChunk in project VanillaSource by TheHollowPlanetMC.
the class EntityFollowGoal method run.
@Override
public void run(GoalSelector goalSelector, Navigator navigator) {
tick++;
if (tick % TRACK_INTERVAL != 0) {
goalSelector.setFinished(true);
return;
}
INMSHandler nmsHandler = VanillaSourceAPI.getInstance().getNMSHandler();
EngineWorld world = navigator.getEntity().getWorld();
if (!world.getName().equals(target.getWorld().getName()))
return;
Location location = target.getLocation();
EngineChunk chunk = world.getChunkAt(location.getBlockX() >> 4, location.getBlockZ() >> 4);
if (chunk == null)
return;
for (int dy = 0; dy < 5; dy++) {
Location l = location.clone().add(new Vector(0, -dy, 0));
Object nmsBlockData = world.getNMSBlockData(l.getBlockX(), l.getBlockY(), l.getBlockZ());
if (nmsBlockData == null)
continue;
if (nmsHandler.hasCollision(new EngineBlock(world, chunk, l.getBlockX(), l.getBlockY(), l.getBlockZ(), nmsBlockData), navigator.getEntity().getMovementCollideOption())) {
// Goal set
navigator.setNavigationGoal(new BlockPosition(l.getBlockX(), l.getBlockY() + 1, l.getBlockZ()));
break;
}
}
goalSelector.setFinished(true);
}
use of thpmc.vanilla_source.api.world.cache.EngineChunk in project VanillaSource by TheHollowPlanetMC.
the class NodeData method isTraversable.
public static boolean isTraversable(EngineWorld world, int blockX, int blockY, int blockZ, CollideOption collideOption) {
EngineChunk chunk = world.getChunkAt(blockX >> 4, blockZ >> 4);
if (chunk == null)
return false;
INMSHandler nmsHandler = VanillaSourceAPI.getInstance().getNMSHandler();
Object nmsBlockData1 = chunk.getNMSBlockData(blockX, blockY, blockZ);
Object nmsBlockData2 = chunk.getNMSBlockData(blockX, blockY + 1, blockZ);
Function<EngineBlock, Boolean> collideBlockFunction = collideOption.getCollideBlockFunction();
if (collideBlockFunction != null) {
if (nmsBlockData1 != null) {
if (!collideBlockFunction.apply(new EngineBlock(world, chunk, blockX, blockY, blockZ, nmsBlockData1))) {
nmsBlockData1 = null;
}
}
if (nmsBlockData2 != null) {
if (!collideBlockFunction.apply(new EngineBlock(world, chunk, blockX, blockY + 1, blockZ, nmsBlockData2))) {
nmsBlockData2 = null;
}
}
}
if (nmsBlockData1 == null && nmsBlockData2 == null) {
return true;
} else if (nmsBlockData1 == null) {
return !nmsHandler.hasCollision(new EngineBlock(world, chunk, blockX, blockY + 1, blockZ, nmsBlockData2), collideOption);
} else if (nmsBlockData2 == null) {
return !nmsHandler.hasCollision(new EngineBlock(world, chunk, blockX, blockY, blockZ, nmsBlockData1), collideOption);
} else {
return !nmsHandler.hasCollision(new EngineBlock(world, chunk, blockX, blockY, blockZ, nmsBlockData1), collideOption) && !nmsHandler.hasCollision(new EngineBlock(world, chunk, blockX, blockY + 1, blockZ, nmsBlockData2), collideOption);
}
}
use of thpmc.vanilla_source.api.world.cache.EngineChunk in project VanillaSource by TheHollowPlanetMC.
the class NodeData method canStand.
public static boolean canStand(EngineWorld world, int blockX, int blockY, int blockZ, CollideOption collideOption) {
EngineChunk chunk = world.getChunkAt(blockX >> 4, blockZ >> 4);
if (chunk == null)
return false;
Object nmsBlockData1 = chunk.getNMSBlockData(blockX, blockY, blockZ);
Object nmsBlockData2 = chunk.getNMSBlockData(blockX, blockY + 1, blockZ);
Object nmsBlockData3 = chunk.getNMSBlockData(blockX, blockY - 1, blockZ);
Function<EngineBlock, Boolean> collideBlockFunction = collideOption.getCollideBlockFunction();
if (collideBlockFunction != null) {
if (nmsBlockData1 != null) {
if (!collideBlockFunction.apply(new EngineBlock(world, chunk, blockX, blockY, blockZ, nmsBlockData1))) {
nmsBlockData1 = null;
}
}
if (nmsBlockData2 != null) {
if (!collideBlockFunction.apply(new EngineBlock(world, chunk, blockX, blockY + 1, blockZ, nmsBlockData2))) {
nmsBlockData2 = null;
}
}
if (nmsBlockData3 != null) {
if (!collideBlockFunction.apply(new EngineBlock(world, chunk, blockX, blockY - 1, blockZ, nmsBlockData3))) {
nmsBlockData3 = null;
}
}
}
INMSHandler nmsHandler = VanillaSourceAPI.getInstance().getNMSHandler();
boolean traversable;
if (nmsBlockData1 == null && nmsBlockData2 == null) {
traversable = true;
} else if (nmsBlockData1 == null) {
traversable = !nmsHandler.hasCollision(new EngineBlock(world, chunk, blockX, blockY + 1, blockZ, nmsBlockData2), collideOption);
} else if (nmsBlockData2 == null) {
traversable = !nmsHandler.hasCollision(new EngineBlock(world, chunk, blockX, blockY, blockZ, nmsBlockData1), collideOption);
} else {
traversable = !nmsHandler.hasCollision(new EngineBlock(world, chunk, blockX, blockY, blockZ, nmsBlockData1), collideOption) && !nmsHandler.hasCollision(new EngineBlock(world, chunk, blockX, blockY + 1, blockZ, nmsBlockData2), collideOption);
}
if (!traversable)
return false;
if (nmsBlockData3 == null)
return false;
return nmsHandler.hasCollision(new EngineBlock(world, chunk, blockX, blockY - 1, blockZ, nmsBlockData3), collideOption);
}
use of thpmc.vanilla_source.api.world.cache.EngineChunk in project VanillaSource by TheHollowPlanetMC.
the class EngineEntity method move.
/**
* Moves this entity by the specified amount.
* @param movement Vector to move an entity
* @return {@link MovementResult}
*/
@NotNull
public MovementResult move(Vector movement) {
if (!hasBoundingBox())
return MovementResult.EMPTY_MOVEMENT_RESULT;
if (entityController == null)
return MovementResult.EMPTY_MOVEMENT_RESULT;
EngineBoundingBox originalBoundingBox = getBoundingBox();
if (originalBoundingBox == null)
return MovementResult.EMPTY_MOVEMENT_RESULT;
if (movement.equals(new Vector(0.0, 0.0, 0.0)))
return MovementResult.EMPTY_MOVEMENT_RESULT;
EngineBoundingBox entityBox = originalBoundingBox.clone().expandForMovement(movement);
entityBox.expand(movementCollideOption.getBoundingBoxGrow());
entityBox.expand(1.5);
// collect collisions
Set<EngineBoundingBox> boxList = new HashSet<>();
// get block collisions
int startX = NumberConversions.floor(entityBox.getMinX());
int startY = NumberConversions.floor(entityBox.getMinY());
int startZ = NumberConversions.floor(entityBox.getMinZ());
int endX = NumberConversions.floor(entityBox.getMaxX());
int endY = NumberConversions.floor(entityBox.getMaxY());
int endZ = NumberConversions.floor(entityBox.getMaxZ());
INMSHandler nmsHandler = VanillaSourceAPI.getInstance().getNMSHandler();
EngineChunk chunk = null;
for (int x = startX; x < endX; x++) {
for (int y = startY; y < endY; y++) {
for (int z = startZ; z < endZ; z++) {
int chunkX = x >> 4;
int chunkZ = z >> 4;
// get chunk cache
if (chunk == null) {
chunk = world.getChunkAt(chunkX, chunkZ);
} else if (chunk.getChunkX() != chunkX || chunk.getChunkZ() != chunkZ) {
chunk = world.getChunkAt(chunkX, chunkZ);
}
if (chunk == null) {
boxList.add(EngineBoundingBox.getBoundingBoxForUnloadChunk(chunkX, chunkZ));
continue;
}
// get nms block from cache
Object iBlockData = chunk.getNMSBlockData(x, y, z);
if (iBlockData == null) {
continue;
}
EngineBlock engineBlock = new EngineBlock(world, chunk, x, y, z, iBlockData);
// collect block collisions
nmsHandler.collectBlockCollisions(engineBlock, boxList, movementCollideOption);
}
}
}
entityBox = originalBoundingBox;
// apply collision option
boxList.removeIf(boundingBox -> {
if (movementCollideOption.getCollideBoundingBoxFunction() != null) {
if (!movementCollideOption.getCollideBoundingBoxFunction().apply(boundingBox)) {
return true;
}
}
if (movementCollideOption.getCollideBlockFunction() != null) {
if (boundingBox instanceof EngineBlockBoundingBox) {
if (!movementCollideOption.getCollideBlockFunction().apply(((EngineBlockBoundingBox) boundingBox).getBlock())) {
return true;
}
}
}
if (movementCollideOption.getCollideEntityFunction() != null) {
if (boundingBox instanceof EngineEntityBoundingBox) {
return !movementCollideOption.getCollideEntityFunction().apply(((EngineEntityBoundingBox) boundingBox).getEntity());
}
}
return false;
});
// perform movement
PerformCollisionResult result = entityBox.performCollisions(movement, boxList);
// get hit collisions for movement result
List<EngineBoundingBox> hitCollisions = new ArrayList<>(result.getHitCollisions());
Vector limitedMovement = result.getLimitedMovement();
// perform auto climb
if (this.autoClimbHeight > 0.0F && (this.onGround || (limitedMovement.getY() != movement.getY() && movement.getY() < 0.0)) && (limitedMovement.getX() != movement.getX() || limitedMovement.getZ() != movement.getZ())) {
PerformCollisionResult autoClimbResult = entityBox.performCollisions(new Vector(movement.getX(), this.autoClimbHeight, movement.getZ()), boxList);
PerformCollisionResult autoClimbUpToResult = ((EngineBoundingBox) entityBox.clone().expand(movement.getX(), 0.0, movement.getZ())).clone().performCollisions(new Vector(0.0, this.autoClimbHeight, 0.0), boxList);
hitCollisions.addAll(autoClimbResult.getHitCollisions());
hitCollisions.addAll(autoClimbUpToResult.getHitCollisions());
Vector autoClimbMovement = autoClimbResult.getLimitedMovement();
Vector autoClimbUpToMovement = autoClimbUpToResult.getLimitedMovement();
if (autoClimbUpToMovement.getY() < this.autoClimbHeight) {
PerformCollisionResult afterClimbResult = ((EngineBoundingBox) entityBox.clone().shift(autoClimbUpToMovement)).performCollisions(new Vector(movement.getX(), 0.0D, movement.getZ()), boxList);
hitCollisions.addAll(afterClimbResult.getHitCollisions());
Vector afterClimbMovement = afterClimbResult.getLimitedMovement();
if (afterClimbMovement.clone().setY(0).lengthSquared() > autoClimbMovement.clone().setY(0).lengthSquared()) {
autoClimbMovement = afterClimbMovement;
}
}
if (autoClimbMovement.clone().setY(0).lengthSquared() > limitedMovement.clone().setY(0).lengthSquared()) {
PerformCollisionResult climbCheckResult = ((EngineBoundingBox) entityBox.clone().shift(autoClimbMovement)).performCollisions(new Vector(0.0D, -autoClimbMovement.getY() + movement.getY(), 0.0D), boxList);
hitCollisions.addAll(climbCheckResult.getHitCollisions());
limitedMovement = autoClimbMovement.add(climbCheckResult.getLimitedMovement());
}
}
// reset position by using bounding box
if (limitedMovement.lengthSquared() > 1.0E-7D) {
entityController.resetBoundingBoxForMovement((EngineBoundingBox) this.getBoundingBox().shift(limitedMovement));
EngineBoundingBox boundingBox = getBoundingBox();
setPosition((boundingBox.getMinX() + boundingBox.getMaxX()) / 2.0D, boundingBox.getMinY(), (boundingBox.getMinZ() + boundingBox.getMaxZ()) / 2.0D);
}
if (movement.getY() > 0.0) {
this.onGround = false;
} else {
this.onGround = movement.getY() != limitedMovement.getY();
}
return new MovementResult(hitCollisions);
}
use of thpmc.vanilla_source.api.world.cache.EngineChunk in project VanillaSource by TheHollowPlanetMC.
the class EngineEntity method setPosition.
public void setPosition(double x, double y, double z) {
int previousBlockX = NumberConversions.floor(this.x);
int previousBlockY = NumberConversions.floor(this.y);
int previousBlockZ = NumberConversions.floor(this.z);
int nextBlockX = NumberConversions.floor(x);
int nextBlockY = NumberConversions.floor(y);
int nextBlockZ = NumberConversions.floor(z);
int previousChunkX = previousBlockX >> 4;
int previousChunkZ = previousBlockZ >> 4;
int nextChunkX = nextBlockX >> 4;
int nextChunkZ = nextBlockZ >> 4;
int previousSectionIndex = ChunkUtil.getSectionIndex(previousBlockY);
int nextSectionIndex = ChunkUtil.getSectionIndex(nextBlockY);
// Moving between chunks
if (!(previousChunkX == nextChunkX && previousChunkZ == nextChunkZ) || previousSectionIndex != nextSectionIndex) {
if (chunk == null) {
chunk = world.getChunkAt(previousChunkX, previousChunkZ);
// unload chunk teleport cancel
if (chunk == null)
return;
}
Set<EngineEntity> previousEntityList = chunk.getEntitiesInSection(previousSectionIndex);
EngineChunk nextChunk;
if (previousChunkX != nextChunkX || previousChunkZ != nextChunkZ) {
nextChunk = world.getChunkAt(nextBlockX >> 4, nextBlockZ >> 4);
} else {
nextChunk = chunk;
}
// unload chunk teleport cancel
if (nextChunk == null)
return;
Set<EngineEntity> nextEntityList = nextChunk.getEntitiesInSection(nextSectionIndex);
nextEntityList.add(this);
previousEntityList.remove(this);
}
this.x = x;
this.y = y;
this.z = z;
entityController.setPositionRaw(x, y, z);
}
Aggregations