@Override public List<Message> getSpawnMessages(Entity entity, RepositionManager rm) { FallingBlock block = entity.get(FallingBlock.class); if (block != null) { VanillaBlockMaterial material = block.getMaterial(); int messageData = material.getMinecraftId() | (material.getMinecraftData(material.getData()) >> 16); List<Message> messages = new ArrayList<Message>(); final double p = 32d; Point pos = entity.getScene().getPosition(); int x = (int) Math.floor(pos.getX() * p); int y = (int) Math.floor(pos.getY() * p); int z = (int) Math.floor(pos.getZ() * p); byte yaw = (byte) ChannelBufferUtils.protocolifyYaw(entity.getScene().getRotation().getYaw()); byte pitch = (byte) ChannelBufferUtils.protocolifyPitch(entity.getScene().getRotation().getPitch()); short fallSpeed = (short) (block.getFallingSpeed() * 8000d); messages.add( new EntityObjectMessage( entity.getId(), (byte) typeId, x, y, z, messageData, (short) 0, fallSpeed, (short) 0, yaw, pitch, rm)); messages.add(new EntityMetadataMessage(entity.getId(), getSpawnParameters(entity))); return messages; } else { return Collections.emptyList(); } }
@Override public Entity getNearestEntity(Point position, Entity ignore, int range) { Entity best = null; double bestDistance = range * range; for (Entity entity : getEntitiesNearRegion(position, range)) { if (entity != null && entity != ignore) { double distance = position.distanceSquared(entity.getScene().getPosition()); if (distance < bestDistance) { bestDistance = distance; best = entity; } } } return best; }
@Override public List<Entity> getNearbyEntities(Point position, Entity ignore, int range) { ArrayList<Entity> foundEntities = new ArrayList<Entity>(); final int RANGE_SQUARED = range * range; for (Entity entity : getEntitiesNearRegion(position, range)) { if (entity != null && entity != ignore) { double distance = position.distanceSquared(entity.getScene().getPosition()); if (distance < RANGE_SQUARED) { foundEntities.add(entity); } } } return Collections.unmodifiableList(foundEntities); }
/** * Gets the absolute closest player from the specified point within a specified range. * * @param position to search from * @param ignore to ignore while searching * @param range to search * @return nearest player */ @Override @LiveRead @Threadsafe public Player getNearestPlayer(Point position, Player ignore, int range) { Entity best = null; double bestDistance = range * range; for (Entity entity : getEntitiesNearRegion(position, range)) { if (entity != null && entity instanceof Player && entity != ignore) { double distance = position.distanceSquared(entity.getScene().getPosition()); if (distance < bestDistance) { bestDistance = distance; best = entity; } } } return (Player) best; }
/** Spawns an entity into the world. Fires off a cancellable EntitySpawnEvent */ public void spawnEntity(Entity e, int entityID) { if (e.isSpawned()) { throw new IllegalArgumentException("Cannot spawn an entity that is already spawned!"); } SpoutRegion region = (SpoutRegion) e.getRegion(); if (region == null) { throw new IllegalStateException("Cannot spawn an entity that has a null region!"); } if (region.getEntityManager().isSpawnable((SpoutEntity) e)) { if (entityID > -1) { if (getEngine().getPlatform() == Platform.CLIENT) { ((SpoutEntity) e).setId(entityID); } else { throw new IllegalArgumentException("Can not set entity id's manually"); } } EntitySpawnEvent event = getEngine() .getEventManager() .callEvent(new EntitySpawnEvent(e, e.getScene().getPosition())); if (event.isCancelled()) { return; } region.getEntityManager().addEntity((SpoutEntity) e); // Alert world components that an entity entered for (Component component : values()) { if (component instanceof WorldComponent) { ((WorldComponent) component).onSpawn(event); } } // Alert entity components that their owner spawned for (Component component : e.values()) { if (component instanceof EntityComponent) { ((EntityComponent) component).onSpawned(event); } } } else { throw new IllegalStateException("Cannot spawn an entity that already has an id!"); } }
@Override public List<Message> getUpdateMessages( Entity entity, Transform liveTransform, RepositionManager rm, boolean force) { // Movement final Transform prevTransform = rm.convert(entity.getScene().getTransform()); final Transform newTransform = rm.convert(liveTransform); final boolean looked = entity.getScene().isRotationDirty(); final int lastX = protocolifyPosition(prevTransform.getPosition().getX()); final int lastY = protocolifyPosition(prevTransform.getPosition().getY()); final int lastZ = protocolifyPosition(prevTransform.getPosition().getZ()); final int lastYaw = protocolifyYaw(prevTransform.getRotation().getYaw()); final int lastPitch = protocolifyPitch(prevTransform.getRotation().getPitch()); final int newX = protocolifyPosition(newTransform.getPosition().getX()); final int newY = protocolifyPosition(newTransform.getPosition().getY()); final int newZ = protocolifyPosition(newTransform.getPosition().getZ()); final int newYaw = protocolifyYaw(newTransform.getRotation().getYaw()); final int newPitch = protocolifyPitch(newTransform.getRotation().getPitch()); final int deltaX = newX - lastX; final int deltaY = newY - lastY; final int deltaZ = newZ - lastZ; final int deltaYaw = newYaw - lastYaw; final int deltaPitch = newPitch - lastPitch; final List<Message> messages = new ArrayList<Message>(); /* * Two scenarios: * - The entity moves more than 4 blocks and maybe changes rotation. * - The entity moves less than 4 blocks and maybe changes rotation. */ if (force || deltaX > 128 || deltaX < -128 || deltaY > 128 || deltaY < -128 || deltaZ > 128 || deltaZ < -128) { messages.add(new EntityTeleportMessage(entity.getId(), newX, newY, newZ, newYaw, newPitch)); if (force || looked) { messages.add(new EntityYawMessage(entity.getId(), newYaw, newPitch)); } } else if (deltaX != 0 || deltaY != 0 || deltaZ != 0 || deltaYaw != 0 || deltaPitch != 0) { if (looked) { messages.add( new EntityRelativePositionYawMessage( entity.getId(), deltaX, deltaY, deltaZ, newYaw, newPitch)); } else if (!prevTransform.getPosition().equals(newTransform.getPosition())) { messages.add(new EntityRelativePositionMessage(entity.getId(), deltaX, deltaY, deltaZ)); } } // Head movement HeadComponent head = entity.get(HeadComponent.class); if (head != null && head.isDirty()) { final int headYawProt = ChannelBufferUtils.protocolifyYaw(head.getRotation().getYaw()); messages.add(new EntityHeadYawMessage(entity.getId(), headYawProt)); } // Physics // TODO: Actually not used? /*if (physics != null && physics.isLinearVelocityDirty()) { messages.add(new EntityVelocityMessage(entity.getId(), new Vector3(0, 0, 0))); }*/ // Extra metadata List<Parameter<?>> params = getUpdateParameters(entity); if (lastMeta == null || !lastMeta.equals(params)) { messages.add(new EntityMetadataMessage(entity.getId(), params)); lastMeta = params; } return messages; }
/** * Gets the absolute closest player from the specified point within a specified range. * * @param entity to search from * @param range to search * @return nearest player */ @Override @LiveRead @Threadsafe public Player getNearestPlayer(Entity entity, int range) { return getNearestPlayer(entity.getScene().getPosition(), range); }
/** * Gets a set of nearby players to the entity, inside of the range * * @param entity marking the center and which is ignored * @param range to look for * @return A set of nearby Players */ @Override @LiveRead @Threadsafe public List<Player> getNearbyPlayers(Entity entity, int range) { return getNearbyPlayers(entity.getScene().getPosition(), range); }
@Override public Entity getNearestEntity(Entity entity, int range) { return getNearestEntity(entity.getScene().getPosition(), range); }
@Override public List<Entity> getNearbyEntities(Entity entity, int range) { return getNearbyEntities(entity.getScene().getPosition(), range); }