/** * Returns the {@link BlockState} of a block at the given location. * * @param loc the location which contains the block * @return The {@link BlockState} state. */ public BlockState getBlockState(Location loc) { if (blockStateMap.containsKey(loc)) { return blockStateMap.get(loc); } else { return loc.getBlock().getState(); } } }
/** * Returns the {@link BlockState} of a block at the given coordinates. * * @param world the world which contains the block * @param x the x-coordinate * @param y the y-coordinate * @param z the z-coordinate * @return The {@link BlockState} state. */ public BlockState getBlockState(World world, int x, int y, int z) { Location loc = world.getBlockAt(x, y, z).getLocation(); if (blockStateMap.containsKey(loc)) { return blockStateMap.get(loc); } else { return loc.getBlock().getState(); } }
/** * Sets a block type and add it to the BlockState list. * * @param world the world which contains the block * @param x the x-coordinate of this block * @param y the y-coordinate of this block * @param z the z-coordinate of this block * @param type the new type of this block */ public void setType(World world, int x, int y, int z, Material type) { GlowBlockState state = (GlowBlockState) world.getBlockAt(x, y, z).getState(); state.setType(type); blockStateMap.put(world.getBlockAt(x, y, z).getLocation(), state); }
@Override public void decorate(World world, Random random, Chunk source) { int sourceX = (source.getX() << 4) + random.nextInt(16); int sourceZ = (source.getZ() << 4) + random.nextInt(16); int sourceY = random.nextInt(128); for (int i = 0; i < 64; i++) { int x = sourceX + random.nextInt(8) - random.nextInt(8); int z = sourceZ + random.nextInt(8) - random.nextInt(8); int y = sourceY + random.nextInt(4) - random.nextInt(4); Block block = world.getBlockAt(x, y, z); Block blockBelow = world.getBlockAt(x, y - 1, z); if (y < 128 && block.getType() == Material.AIR && Arrays.asList(MATERIALS) .contains(blockBelow.getType())) { BlockState state = block.getState(); state.setType(type); state.setData(new MaterialData(type)); state.update(true); } } } }
@Override public void decorate(World world, Random random, Chunk source) { int amount = 1 + random.nextInt(1 + random.nextInt(10)); for (int j = 0; j < amount; j++) { int sourceX = (source.getX() << 4) + random.nextInt(16); int sourceZ = (source.getZ() << 4) + random.nextInt(16); int sourceY = 4 + random.nextInt(120); for (int i = 0; i < 64; i++) { int x = sourceX + random.nextInt(8) - random.nextInt(8); int z = sourceZ + random.nextInt(8) - random.nextInt(8); int y = sourceY + random.nextInt(4) - random.nextInt(4); Block block = world.getBlockAt(x, y, z); Block blockBelow = world.getBlockAt(x, y - 1, z); if (y < 128 && block.getType() == Material.AIR && blockBelow.getType() == Material.NETHERRACK) { BlockState state = block.getState(); state.setType(Material.FIRE); state.setData(new MaterialData(Material.FIRE)); state.update(true); } } } } }
@Override public void populate(World world, Random random, Chunk source) { if (random.nextInt(32) == 0) { int sourceX = (source.getX() << 4) + random.nextInt(16); int sourceZ = (source.getZ() << 4) + random.nextInt(16); int sourceY = random.nextInt(world.getHighestBlockYAt(sourceX, sourceZ) << 1); for (int i = 0; i < 64; i++) { int x = sourceX + random.nextInt(8) - random.nextInt(8); int z = sourceZ + random.nextInt(8) - random.nextInt(8); int y = sourceY + random.nextInt(4) - random.nextInt(4); if (world.getBlockAt(x, y, z).getType() == Material.AIR && world.getBlockAt(x, y - 1, z).getType() == Material.GRASS) { BlockState state = world.getBlockAt(x, y, z).getState(); state.setType(Material.PUMPKIN); // random facing state.setData(new Pumpkin(FACES[random.nextInt(FACES.length)])); state.update(true); } } } } }
@Override public void populate(World world, Random random, Chunk source) { int sourceX = (source.getX() << 4) + random.nextInt(16); int sourceZ = (source.getZ() << 4) + random.nextInt(16); int sourceY = random.nextInt(world.getSeaLevel() << 1); for (int i = 0; i < 64; i++) { int x = sourceX + random.nextInt(8) - random.nextInt(8); int z = sourceZ + random.nextInt(8) - random.nextInt(8); int y = sourceY + random.nextInt(4) - random.nextInt(4); if (world.getBlockAt(x, y, z).getType() == Material.AIR && world.getBlockAt(x, y - 1, z).getType() == Material.GRASS) { BlockState state = world.getBlockAt(x, y, z).getState(); state.setType(Material.MELON_BLOCK); state.setData(new MaterialData(Material.MELON_BLOCK)); state.update(true); } } } }
private boolean isPistonExtended(Block block) { // TODO: check direction of piston_extension to make sure that the extension is attached to // piston Block pistonHead = block .getRelative(((PistonBaseMaterial) block.getState().getData()).getFacing()); return pistonHead.getType() == Material.PISTON_EXTENSION; }
/** * Sets a block type, data and add it to the BlockState list. * * @param world the world which contains the block * @param x the x-coordinate of this block * @param y the y-coordinate of this block * @param z the z-coordinate of this block * @param type the new type of this block * @param data the new data value of this block */ public void setTypeAndRawData(World world, int x, int y, int z, Material type, int data) { GlowBlockState state = (GlowBlockState) world.getBlockAt(x, y, z).getState(); state.setType(type); state.setRawData((byte) data); blockStateMap.put(world.getBlockAt(x, y, z).getLocation(), state); }
/** * Sets a block type and MaterialData, and add it to the BlockState list. * * @param world the world which contains the block * @param x the x-coordinate of this block * @param y the y-coordinate of this block * @param z the z-coordinate of this block * @param type the new type of this block * @param data the new MaterialData of this block */ public void setTypeAndData(World world, int x, int y, int z, Material type, MaterialData data) { GlowBlockState state = (GlowBlockState) world.getBlockAt(x, y, z).getState(); state.setType(type); state.setData(data); blockStateMap.put(world.getBlockAt(x, y, z).getLocation(), state); }
@Override public void decorate(World world, Random random, Chunk source) { int sourceX = (source.getX() << 4) + random.nextInt(16); int sourceZ = (source.getZ() << 4) + random.nextInt(16); int sourceY = random.nextInt(world.getHighestBlockYAt(sourceX, sourceZ) << 1); while (world.getBlockAt(sourceX, sourceY - 1, sourceZ).getType() == Material.AIR && sourceY > 0) { sourceY--; } for (int j = 0; j < 10; j++) { int x = sourceX + random.nextInt(8) - random.nextInt(8); int z = sourceZ + random.nextInt(8) - random.nextInt(8); int y = sourceY + random.nextInt(4) - random.nextInt(4); if (y >= 0 && y <= 255 && world.getBlockAt(x, y, z).getType() == Material.AIR && world.getBlockAt(x, y - 1, z).getType() == Material.STATIONARY_WATER) { BlockState state = world.getBlockAt(x, y, z).getState(); state.setType(Material.WATER_LILY); state.setData(new MaterialData(Material.WATER_LILY)); state.update(true); } } } }
/** * Returns whether any of {@link #canHeightFit(int)}, {@link #canPlace(int, int, int, World)} or * {@link #canPlaceOn(BlockState)} prevent this tree from generating. * * @param baseX the X coordinate of the base of the trunk * @param baseY the Y coordinate of the base of the trunk * @param baseZ the Z coordinate of the base of the trunk * @param world the world to grow in * @return true if any of the checks prevent us from generating, false otherwise */ protected boolean cannotGenerateAt(int baseX, int baseY, int baseZ, World world) { return !canHeightFit(baseY) || !canPlaceOn(world.getBlockAt(baseX, baseY - 1, baseZ).getState()) || !canPlace(baseX, baseY, baseZ, world); }
@Override public void onBlockChanged(GlowBlock block, Material oldType, byte oldData, Material newType, byte newData) { if (newType != Material.AIR) { return; } if (oldType.getData() == Door.class) { Door door = new Door(oldType); door.setData(oldData); if (door.isTopHalf()) { Block b = block.getRelative(BlockFace.DOWN); if (b.getState().getData() instanceof Door) { b.setType(Material.AIR); } } else { Block b = block.getRelative(BlockFace.UP); if (b.getState().getData() instanceof Door) { b.setType(Material.AIR); } } } }
/** * Removes the grass, shrub, flower or mushroom directly above the given block, if present. Does * not drop an item. * * @param block the block to update * @return true if a plant was removed; false if none was present */ static boolean killPlantAbove(Block block) { Block blockAbove = block.getRelative(BlockFace.UP); Material mat = blockAbove.getType(); if (PLANT_TYPES.contains(mat)) { if (mat == Material.DOUBLE_PLANT) { MaterialData dataAbove = blockAbove.getState().getData(); if (dataAbove instanceof DoublePlant && ((DoublePlant) dataAbove).getSpecies() == DoublePlantSpecies.PLANT_APEX) { blockAbove.getRelative(BlockFace.UP) .setType(Material.AIR); } } blockAbove.setType(Material.AIR); return true; } return false; }
@Override public boolean clearContainerBlockContents(BlockVector3 pt) { Block block = getWorld().getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()); if (block == null) { return false; } BlockState state = block.getState(); if (!(state instanceof org.bukkit.inventory.InventoryHolder)) { return false; } org.bukkit.inventory.InventoryHolder chest = (org.bukkit.inventory.InventoryHolder) state; Inventory inven = chest.getInventory(); if (chest instanceof Chest) { inven = getBlockInventory((Chest) chest); } inven.clear(); return true; }
/** * 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); } } }
@Override public Inventory getInventory() { GlowBlock me = getBlock(); BlockChest blockChest = (BlockChest) ItemTable.instance().getBlock(me.getType()); BlockFace attachedChest = blockChest.getAttachedChest(me); if (attachedChest != null) { Block nearbyBlock = me.getRelative(attachedChest); GlowChest nearbyChest = (GlowChest) nearbyBlock.getState(); switch (attachedChest) { case SOUTH: case EAST: return new GlowDoubleChestInventory(this, nearbyChest); case WEST: case NORTH: return new GlowDoubleChestInventory(nearbyChest, this); default: GlowServer.logger.warning( "GlowChest#getInventory() can only handle N/O/S/W BlockFaces, got " + attachedChest); return getBlockInventory(); } } return getBlockInventory(); }
/** * Generates or extends a cactus, if there is space. */ @Override public boolean generate(World world, Random random, int x, int y, int z) { if (world.getBlockAt(x, y, z).isEmpty()) { int height = random.nextInt(random.nextInt(3) + 1) + 1; for (int n = y; n < y + height; n++) { Block block = world.getBlockAt(x, n, z); Material typeBelow = block.getRelative(BlockFace.DOWN).getType(); if ((typeBelow == Material.SAND || typeBelow == Material.CACTUS) && block.getRelative(BlockFace.UP).isEmpty()) { for (BlockFace face : FACES) { if (block.getRelative(face).getType().isSolid()) { return n > y; } } BlockState state = block.getState(); state.setType(Material.CACTUS); state.setData(new MaterialData(Material.CACTUS)); state.update(true); } } } return true; } }
/** * Sets the given block to a container and fills it with random items. * * @param pos a point relative to this structure's root point * @param random the PRNG to use * @param content the distribution to draw items from * @param container the container to place * @param maxStacks the maximum number of slots to fill * @return true if the container was placed and filled; false if {@code pos} is outside the * builder's bounding box or {@link RandomItemsContent#fillContainer(Random, BlockState, * int)} fails */ public boolean createRandomItemsContainer(Vector pos, Random random, RandomItemsContent content, DirectionalContainer container, int maxStacks) { 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(container.getItemType()); state.setData(container); state.update(true); return content.fillContainer(random, state, maxStacks); } return false; }
private void flow(GlowBlock source, BlockFace direction) { // if we're not going down BlockFromToEvent fromToEvent = new BlockFromToEvent(source, direction); if (fromToEvent.isCancelled()) { return; } byte strength = fromToEvent.getBlock().getState().getRawData(); if (DOWN != fromToEvent.getFace()) { if (strength < (isWater(fromToEvent.getBlock().getType()) || fromToEvent.getBlock().getBiome() == Biome.HELL ? STRENGTH_MIN_WATER : STRENGTH_MIN_LAVA)) { // decrease the strength strength += 1; } else { // no strength, can't flow return; } } else { // reset the strength if we're going down strength = STRENGTH_MAX; } // flow to the target GlowBlock toBlock = (GlowBlock) fromToEvent.getToBlock(); toBlock.setType(fromToEvent.getBlock().getType(), strength, false); toBlock.getWorld().requestPulse(toBlock); }