/** * Creates a temple piece. * * @param random the PRNG that will choose the orientation * @param location the root location * @param size the size as a width-height-depth vector */ public GlowTemplePiece(Random random, Location location, Vector size) { super(random, location, size); width = size.getBlockX(); height = size.getBlockY(); depth = size.getBlockZ(); }
/** * Checks whether the given point is inside a block that intersects this box. * * @param vec the point to check * @return true if this box intersects the block containing {@code vec} */ public boolean isVectorInside(Vector vec) { return vec.getBlockX() >= min.getBlockX() && vec.getBlockX() <= max.getBlockX() && vec.getBlockY() >= min.getBlockY() && vec.getBlockY() <= max.getBlockY() && vec.getBlockZ() >= min.getBlockZ() && vec.getBlockZ() <= max.getBlockZ(); }
/** * Changes this bounding box to the bounding box of the union of itself and another bounding * box. * * @param boundingBox the other bounding box to contain */ public void expandTo(StructureBoundingBox boundingBox) { min = new Vector(Math.min(min.getBlockX(), boundingBox.getMin().getBlockX()), Math.min(min.getBlockY(), boundingBox.getMin().getBlockY()), Math.min(min.getBlockZ(), boundingBox.getMin().getBlockZ())); max = new Vector(Math.max(max.getBlockX(), boundingBox.getMax().getBlockX()), Math.max(max.getBlockY(), boundingBox.getMax().getBlockY()), Math.max(max.getBlockZ(), boundingBox.getMax().getBlockZ())); }
private int countAvailableBlocks(Vector from, Vector to, World world) { int n = 0; Vector target = to.subtract(from); int maxDistance = Math.max(Math.abs(target.getBlockY()), Math.max(Math.abs(target.getBlockX()), Math.abs(target.getBlockZ()))); float dx = (float) target.getX() / maxDistance; float dy = (float) target.getY() / maxDistance; float dz = (float) target.getZ() / maxDistance; for (int i = 0; i <= maxDistance; i++, n++) { target = from.clone() .add(new Vector((double) (0.5F + i * dx), 0.5F + i * dy, 0.5F + i * dz)); if (target.getBlockY() < 0 || target.getBlockY() > 255 || !overridables.contains(blockTypeAt( target.getBlockX(), target.getBlockY(), target.getBlockZ(), world))) { return n; } } return -1; }
/** * Write an encoded block vector (position) to the buffer. * * @param buf The buffer. * @param vector The vector to write. */ public static void writeBlockPosition(ByteBuf buf, Vector vector) { writeBlockPosition(buf, vector.getBlockX(), vector.getBlockY(), vector.getBlockZ()); }
/** * Used to get the locations that neighbor a vector's faces. * @param vector The vector we're grabbing the face neighbors of. * * @return A set of vector's that neighbor the specified vector's faces. */ default Set<Vector> getFaceNeighbors(final Vector vector) { Vector[] faces = new Vector[] { new Vector(vector.getBlockX() + 1, vector.getBlockY(), vector.getBlockZ()), new Vector(vector.getBlockX() - 1, vector.getBlockY(), vector.getBlockZ()), new Vector(vector.getBlockX(), vector.getBlockY() + 1, vector.getBlockZ()), new Vector(vector.getBlockX(), vector.getBlockY() - 1, vector.getBlockZ()), new Vector(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ() + 1), new Vector(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ() - 1) }; return Sets.newHashSet(faces); }
/** * Used to get the locations that neighbor a vector's corners. * @param vector The vector we're grabbing the corner neighbors of. * * @return A set of vector's that neighbor the specified vector's corners. */ default Set<Vector> getCornerNeighbors(final Vector vector) { Vector[] faces = new Vector[] { new Vector(vector.getBlockX() + 1, vector.getBlockY() - 1, vector.getBlockZ() + 1), new Vector(vector.getBlockX() + 1, vector.getBlockY() - 1, vector.getBlockZ() - 1), new Vector(vector.getBlockX() + 1, vector.getBlockY() + 1, vector.getBlockZ() + 1), new Vector(vector.getBlockX() + 1, vector.getBlockY() + 1, vector.getBlockZ() - 1), new Vector(vector.getBlockX() - 1, vector.getBlockY() + 1, vector.getBlockZ() + 1), new Vector(vector.getBlockX() - 1, vector.getBlockY() + 1, vector.getBlockZ() - 1), new Vector(vector.getBlockX() - 1, vector.getBlockY() - 1, vector.getBlockZ() + 1), new Vector(vector.getBlockX() - 1, vector.getBlockY() - 1, vector.getBlockZ() - 1) }; return Sets.newHashSet(faces); } }
/** * Whether this box intersects the given box. * * @param boundingBox the box to check intersection with * @return true if the given box intersects this box; false otherwise */ public boolean intersectsWith(StructureBoundingBox boundingBox) { return boundingBox.getMin().getBlockX() <= max.getBlockX() && boundingBox.getMax().getBlockX() >= min.getBlockX() && boundingBox.getMin().getBlockY() <= max.getBlockY() && boundingBox.getMax().getBlockY() >= min.getBlockY() && boundingBox.getMin().getBlockZ() <= max.getBlockZ() && boundingBox.getMax().getBlockZ() >= min.getBlockZ(); }
public BlockState getBlockState(Vector pos) { Vector vec = translate(pos); return delegate.getBlockState(world, vec.getBlockX(), vec.getBlockY(), vec.getBlockZ()); }
/** * Creates a structure piece. * * @param random the PRNG that will choose the orientation * @param location the root location * @param size the size as a width-height-depth vector */ public GlowStructurePiece(Random random, Location location, Vector size) { orientation = getOrientationFromOrdinal(random.nextInt(4)); switch (orientation) { case EAST: case WEST: size = new Vector(size.getBlockZ(), size.getBlockY(), size.getBlockX()); break; default: break; } createNewBoundingBox(location, size); }
/** * Sets the block at a given point, if it is inside this structure's bounding box. * * @param pos a point relative to this structure's root point * @param type the new block type * @param data the new block data */ public void setBlock(Vector pos, Material type, MaterialData data) { Vector vec = translate(pos); if (boundingBox.isVectorInside(vec)) { delegate.setTypeAndData(world, vec.getBlockX(), vec.getBlockY(), vec.getBlockZ(), type, data); } }
private Vector translate(Vector pos) { StructureBoundingBox boundingBox = structure.getBoundingBox(); switch (structure.getOrientation()) { case EAST: return new Vector(boundingBox.getMax().getBlockX() - pos.getBlockZ(), boundingBox.getMin().getBlockY() + pos.getBlockY(), boundingBox.getMin().getBlockZ() + pos.getBlockX()); case SOUTH: return new Vector(boundingBox.getMin().getBlockX() + pos.getBlockX(), boundingBox.getMin().getBlockY() + pos.getBlockY(), boundingBox.getMax().getBlockZ() - pos.getBlockZ()); case WEST: return new Vector(boundingBox.getMin().getBlockX() + pos.getBlockZ(), boundingBox.getMin().getBlockY() + pos.getBlockY(), boundingBox.getMin().getBlockZ() + pos.getBlockX()); default: // NORTH return new Vector(boundingBox.getMin().getBlockX() + pos.getBlockX(), boundingBox.getMin().getBlockY() + pos.getBlockY(), boundingBox.getMin().getBlockZ() + pos.getBlockZ()); } }
/** * Sets a box of blocks to have random types, chosen independently. * * @param min the minimum coordinates, relative to this structure's root point * @param max the maximum coordinates, relative to this structure's root point * @param random the PRNG to use * @param materials a map of possible blocks to integer weights */ public void fillWithRandomMaterial(Vector min, Vector max, Random random, Map<StructureMaterial, Integer> materials) { for (int y = min.getBlockY(); y <= max.getBlockY(); y++) { for (int x = min.getBlockX(); x <= max.getBlockX(); x++) { for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { StructureMaterial material = getRandomMaterial(random, materials); setBlock(new Vector(x, y, z), material.getType(), material.getData()); } } } }
/** * Sets the block at a given point, if it is inside this builder's bounding box. * * @param pos a point relative to this structure's root point * @param type the new block type * @param data the new block data */ public void setBlock(Vector pos, Material type, int data) { Vector vec = translate(pos); if (boundingBox.isVectorInside(vec)) { delegate .setTypeAndRawData(world, vec.getBlockX(), vec.getBlockY(), vec .getBlockZ(), type, data); } }
/** * Spawns an entity if the given position is within this structure's bounding box. * * @param pos a point relative to this structure's root point * @param entityType the type of entity to spawn * @return true if the entity was spawned; false if {@code pos} is outside the builder's * bounding box or {@link World#spawnEntity(Location, EntityType)} fails */ public boolean spawnMob(Vector pos, EntityType entityType) { Vector vec = translate(pos); return boundingBox.isVectorInside(vec) && world .spawnEntity(new Location(world, vec.getBlockX(), vec.getBlockY(), vec.getBlockZ()), entityType) != null; }
/** * Sets the given block to a spawner for the given entity type. * * @param pos a point relative to this structure's root point * @param entityType the type of entity the spawner will spawn */ public void createMobSpawner(Vector pos, EntityType entityType) { Vector vec = translate(pos); if (boundingBox.isVectorInside(vec)) { BlockState state = world.getBlockAt(vec.getBlockX(), vec.getBlockY(), vec.getBlockZ()) .getState(); delegate.backupBlockState(state.getBlock()); state.setType(Material.MOB_SPAWNER); state.update(true); state = world.getBlockAt(vec.getBlockX(), vec.getBlockY(), vec.getBlockZ()).getState(); if (state instanceof CreatureSpawner) { ((CreatureSpawner) state).setSpawnedType(entityType); } } }
/** * Save information about this structure piece to the given tag. * * @param structurePiece The structure piece to save. * @param compound The target tag. */ public void save(T structurePiece, CompoundTag compound) { compound.putInt("GD", structurePiece.getUnknownGd()); compound.putInt("O", structurePiece.getNumericOrientation()); StructureBoundingBox boundingBox = structurePiece.getBoundingBox(); int[] bb = new int[6]; bb[0] = boundingBox.getMin().getBlockX(); bb[1] = boundingBox.getMin().getBlockY(); bb[2] = boundingBox.getMin().getBlockZ(); bb[3] = boundingBox.getMax().getBlockX(); bb[4] = boundingBox.getMax().getBlockY(); bb[5] = boundingBox.getMax().getBlockZ(); compound.putIntArray("BB", bb); } }
/** * Builds a 1x1 column out of the given block, replacing non-solid blocks starting at a given * location and proceeding downward until a solid block is reached. * * @param pos the highest point to possibly replace, relative to this structure's root * point * @param type the block type to fill * @param data the block data */ public void setBlockDownward(Vector pos, Material type, MaterialData data) { Vector vec = translate(pos); if (boundingBox.isVectorInside(vec)) { int x = vec.getBlockX(); int y = vec.getBlockY(); int z = vec.getBlockZ(); while (!world.getBlockAt(x, y, z).getType().isSolid() && y > 1) { delegate.setTypeAndData(world, x, y, z, type, data); y--; } } }
private void createNewBoundingBox(Location location, Vector size) { Vector min = new Vector(location.getBlockX(), location.getBlockY(), location.getBlockZ()); Vector max = new Vector(location.getBlockX() + size.getBlockX() - 1, location.getBlockY() + size.getBlockY() - 1, location.getBlockZ() + size.getBlockZ() - 1); boundingBox = new StructureBoundingBox(min, max); }
/** * Builds a 1x1 column out of the given block, replacing non-solid blocks starting at a given * location and proceeding downward until a solid block is reached. * * @param pos the highest point to possibly replace, relative to this structure's root * point * @param type the block type to fill * @param data the block data */ public void setBlockDownward(Vector pos, Material type, int data) { Vector vec = translate(pos); if (boundingBox.isVectorInside(vec)) { int y = vec.getBlockY(); while (!world.getBlockAt(vec.getBlockX(), y, vec.getBlockZ()).getType().isSolid() && y > 1) { delegate.setTypeAndRawData(world, vec.getBlockX(), y, vec.getBlockZ(), type, data); y--; } } }