Search in sources :

Example 1 with EngineChunk

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);
}
Also used : EngineChunk(thpmc.vanilla_source.api.world.cache.EngineChunk) BlockPosition(thpmc.vanilla_source.api.entity.ai.pathfinding.BlockPosition) EngineBlock(thpmc.vanilla_source.api.world.block.EngineBlock) EngineWorld(thpmc.vanilla_source.api.world.cache.EngineWorld) INMSHandler(thpmc.vanilla_source.api.nms.INMSHandler) Vector(org.bukkit.util.Vector) Location(org.bukkit.Location)

Example 2 with EngineChunk

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);
    }
}
Also used : EngineChunk(thpmc.vanilla_source.api.world.cache.EngineChunk) EngineBlock(thpmc.vanilla_source.api.world.block.EngineBlock) INMSHandler(thpmc.vanilla_source.api.nms.INMSHandler)

Example 3 with EngineChunk

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);
}
Also used : EngineChunk(thpmc.vanilla_source.api.world.cache.EngineChunk) EngineBlock(thpmc.vanilla_source.api.world.block.EngineBlock) INMSHandler(thpmc.vanilla_source.api.nms.INMSHandler)

Example 4 with EngineChunk

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);
}
Also used : ArrayList(java.util.ArrayList) INMSHandler(thpmc.vanilla_source.api.nms.INMSHandler) EngineChunk(thpmc.vanilla_source.api.world.cache.EngineChunk) EngineBlock(thpmc.vanilla_source.api.world.block.EngineBlock) Vector(org.bukkit.util.Vector) HashSet(java.util.HashSet) NotNull(org.jetbrains.annotations.NotNull)

Example 5 with EngineChunk

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);
}
Also used : EngineChunk(thpmc.vanilla_source.api.world.cache.EngineChunk)

Aggregations

EngineChunk (thpmc.vanilla_source.api.world.cache.EngineChunk)6 INMSHandler (thpmc.vanilla_source.api.nms.INMSHandler)4 EngineBlock (thpmc.vanilla_source.api.world.block.EngineBlock)4 Vector (org.bukkit.util.Vector)2 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 Location (org.bukkit.Location)1 NotNull (org.jetbrains.annotations.NotNull)1 BlockPosition (thpmc.vanilla_source.api.entity.ai.pathfinding.BlockPosition)1 AsyncEngineChunk (thpmc.vanilla_source.api.world.cache.AsyncEngineChunk)1 EngineWorld (thpmc.vanilla_source.api.world.cache.EngineWorld)1