/** * Return the blocks that will be moved with this elevator * * @return The blocks that this lift will move */ public LiftContents getContents() { Set<Vector3i> blocks = new HashSet<Vector3i>(); Set<Vector3i> edgeBlocks = new HashSet<Vector3i>(); Vector3i location = position.add(0, -1, 0); travelBlocks(location, location, blocks, new HashSet<Vector3i>(), edgeBlocks); return new LiftContents(this, edgeBlocks, blocks); }
/** * Go through the blocks, checking for valid ones The way this works is: * * <ul> * <li>Adds the current location to the list of valid locations * <li>Checks if the current block is within {@link LiftPlatesConfig#maxLiftSize} * <li>Makes sure the current block is of the same type and data as the central block * <li>If large lifts are not enabled in the configuration, also checks that the block above is * a pressureplate (If any of the previous conditions are not met, the method does not * continue) * <li>Adds the current location to the list of valid locations * <li>Runs the method on {@link LiftUtil#NSEW_FACES}, excluding locations that have already * been visited, with the same sets of valid and visited locations * </ul> * * @param start The origin block * @param current The current block * @param validLocations The list of already travelled and valid locations * @param visited The list of already travelled (not necessarily valid) locations */ private void travelBlocks( Vector3i start, Vector3i current, Set<Vector3i> validLocations, Set<Vector3i> visited, Set<Vector3i> edgeBlocks) { visited.add(current); LiftPlatesConfig config = manager.getPlugin().getConfiguration(); final int maxDist = config.maxLiftSize * config.maxLiftSize; if (start.distanceSquared(current) > maxDist) { // Too far away edgeBlocks.add(current); return; } final World world = manager.getWorld(); if (!world.getBlock(start).equals(world.getBlock(current))) { // Different block type edgeBlocks.add(current); return; } if (!config.recursiveLifts && !LiftUtil.isPressurePlate( world.getBlockType(current.add(0, 1, 0)))) { // Not a pressure plate edgeBlocks.add(current); return; } validLocations.add(current); for (int i = 1; i < config.liftHeight; ++i) { validLocations.add(current.add(0, i, 0)); } for (Direction face : LiftUtil.NSEW_FACES) { Vector3i newLoc = current.add(face.toVector3d().toInt()); if (visited.contains(newLoc)) { continue; } travelBlocks(start, newLoc, validLocations, visited, edgeBlocks); } }