use of thpmc.engine.api.nms.INMSHandler in project THP-Engine 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 = THPEngineAPI.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.engine.api.nms.INMSHandler in project THP-Engine 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 = THPEngineAPI.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.engine.api.nms.INMSHandler in project THP-Engine 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 (nmsEntity == 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 = THPEngineAPI.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) {
nmsEntity.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.engine.api.nms.INMSHandler in project THP-Engine by TheHollowPlanetMC.
the class EnginePlayerEntity method show.
@Override
public void show(EnginePlayer player) {
INMSHandler nmsHandler = THPEngineAPI.getInstance().getNMSHandler();
Player bukkitPlayer = player.getBukkitPlayer();
nmsHandler.sendPacket(bukkitPlayer, nmsHandler.createPlayerInfoPacket(nmsEntity, WrappedPlayerInfoAction.ADD_PLAYER));
nmsHandler.sendPacket(bukkitPlayer, nmsHandler.createSpawnNamedEntityPacket(nmsEntity));
nmsHandler.sendPacket(bukkitPlayer, nmsHandler.createTeleportPacket(nmsEntity));
}
use of thpmc.engine.api.nms.INMSHandler in project THP-Engine by TheHollowPlanetMC.
the class TestListener method onChat.
@EventHandler
public void onChat(AsyncPlayerChatEvent event) {
Player player = event.getPlayer();
if (!event.getMessage().equals("spawn"))
return;
TaskHandler.runSync(() -> {
Location location = player.getLocation();
INMSHandler nmsHandler = THPEngineAPI.getInstance().getNMSHandler();
GameProfile gameProfile = new GameProfile(UUID.randomUUID(), "NPC");
NMSEntity entityPlayer = nmsHandler.createNMSEntity(location.getWorld(), location.getX(), location.getY(), location.getZ(), EntityType.PLAYER, gameProfile);
entityPlayer.setPositionRaw(location.getX(), location.getY(), location.getZ());
CollideOption collideOption = new CollideOption(FluidCollisionMode.ALWAYS, false);
collideOption.setCollideBlockFunction(engineBlock -> {
return engineBlock.getMaterial() != Material.GLASS;
});
THPEngineAPI.getInstance().getTickRunnerPool().spawn(tickRunner -> {
EnginePlayerEntity npc = new EnginePlayerEntity(tickRunner.getThreadLocalCache().getWorld(location.getWorld().getName()), (NMSEntityPlayer) entityPlayer, tickRunner, true);
npc.getGoalSelector().registerGoal(0, new EntityFollowGoal(player));
npc.setMovementCollideOption(collideOption);
tickRunner.addEntity(npc);
});
});
}
Aggregations