Beispiel #1
0
  /**
   * 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);
    }
  }
Beispiel #2
0
  /**
   * @param sign treated as sign post if it is such, or else assumed to be a wall sign (i.e., if you
   *     ask about a stone block, it's considered a wall sign).
   * @return the blank side of the sign opposite the text. In the case of a wall sign, the block in
   *     this direction is the block to which the sign is attached. This is also the direction a
   *     player would be facing when reading the sign; see {@link #getFront(Location)}.
   */
  public static Direction getBack(Location sign) {
    Direction front = getFront(sign);
    if (front == null) return Direction.NONE;

    return front.getOpposite();
  }
Beispiel #3
0
  @Override
  public boolean triggerMechanic(Location block, Sign sign, Human human, Boolean forceState) {

    if (!SignUtil.getTextRaw(sign, 1).equals("[Door]")) {

      Direction back =
          SignUtil.getTextRaw(sign, 1).equals("[Door Up]") ? Direction.UP : Direction.DOWN;

      Location baseBlock = block.getRelative(back);

      Location otherSide = getOtherEnd(block, back, maximumLength);
      if (otherSide == null) {
        if (human instanceof CommandSource)
          ((CommandSource) human).sendMessage(Texts.builder("Missing other end!").build());
        return true;
      }

      Location otherBase = otherSide.getRelative(back.getOpposite());

      if (!baseBlock.getBlock().equals(otherBase.getBlock())) {
        if (human instanceof CommandSource)
          ((CommandSource) human)
              .sendMessage(Texts.builder("Both ends must be the same material!").build());
        return true;
      }

      int leftBlocks = 0, rightBlocks = 0; // Default to 0. Single width bridge is the default.

      Location left = baseBlock.getRelative(SignUtil.getLeft(block));
      Location right = baseBlock.getRelative(SignUtil.getRight(block));

      // Calculate left distance
      Location otherLeft = otherBase.getRelative(SignUtil.getLeft(block));

      while (true) {
        if (leftBlocks >= maximumWidth) break;
        if (left.getBlock().equals(baseBlock.getBlock())
            && otherLeft.getBlock().equals(baseBlock.getBlock())) {
          leftBlocks++;
          left = left.getRelative(SignUtil.getLeft(block));
          otherLeft = otherLeft.getRelative(SignUtil.getLeft(block));
        } else {
          break;
        }
      }

      // Calculate right distance
      Location otherRight = otherBase.getRelative(SignUtil.getRight(block));

      while (true) {
        if (rightBlocks >= maximumWidth) break;
        if (right.getBlock().equals(baseBlock.getBlock())
            && otherRight.getBlock().equals(baseBlock.getBlock())) {
          rightBlocks++;
          right = right.getRelative(SignUtil.getRight(block));
          otherRight = otherRight.getRelative(SignUtil.getRight(block));
        } else {
          break;
        }
      }

      baseBlock = baseBlock.getRelative(back);

      BlockState type = block.getRelative(back).getBlock();
      if (baseBlock.getBlock().equals(type) && (forceState == null || !forceState))
        type = BlockTypes.AIR.getDefaultState();

      while (baseBlock.getBlockY() != otherSide.getBlockY() + (back == Direction.UP ? -1 : 1)) {

        baseBlock.setBlock(type);

        left = baseBlock.getRelative(SignUtil.getLeft(block));

        for (int i = 0; i < leftBlocks; i++) {
          left.setBlock(type);
          left = left.getRelative(SignUtil.getLeft(block));
        }

        right = baseBlock.getRelative(SignUtil.getRight(block));

        for (int i = 0; i < rightBlocks; i++) {
          right.setBlock(type);
          right = right.getRelative(SignUtil.getRight(block));
        }

        baseBlock = baseBlock.getRelative(back);
      }
    } else {
      if (human instanceof CommandSource)
        ((CommandSource) human)
            .sendMessage(Texts.builder("Door not activatable from here!").build());
      return false;
    }

    return true;
  }