예제 #1
0
  public void teleport(final Vehicle vehicle) {
    Location traveller =
        new Location(
            this.world,
            vehicle.getLocation().getX(),
            vehicle.getLocation().getY(),
            vehicle.getLocation().getZ());
    Location exit = getExit(traveller);

    double velocity = vehicle.getVelocity().length();

    // Stop and teleport
    vehicle.setVelocity(new Vector());

    // Get new velocity
    final Vector newVelocity = new Vector();
    switch ((int) id.getBlock().getData()) {
      case 2:
        newVelocity.setZ(-1);
        break;
      case 3:
        newVelocity.setZ(1);
        break;
      case 4:
        newVelocity.setX(-1);
        break;
      case 5:
        newVelocity.setX(1);
        break;
    }
    newVelocity.multiply(velocity);

    final Entity passenger = vehicle.getPassenger();
    if (passenger != null) {
      final Vehicle v = exit.getWorld().spawn(exit, vehicle.getClass());
      vehicle.eject();
      vehicle.remove();
      passenger.teleport(exit);
      Stargate.server
          .getScheduler()
          .scheduleSyncDelayedTask(
              Stargate.stargate,
              new Runnable() {
                public void run() {
                  v.setPassenger(passenger);
                  v.setVelocity(newVelocity);
                }
              },
              1);
    } else {
      Vehicle mc = exit.getWorld().spawn(exit, vehicle.getClass());
      if (mc instanceof StorageMinecart) {
        StorageMinecart smc = (StorageMinecart) mc;
        smc.getInventory().setContents(((StorageMinecart) vehicle).getInventory().getContents());
      }
      mc.setVelocity(newVelocity);
      vehicle.remove();
    }
  }
예제 #2
0
  /**
   * Teleports the passed in Entity through the portal.
   *
   * <p>Given an Entity object, attempts to teleport them through the portal. This involves many
   * steps. 1) Verify the portal on the other end still exists. If it doesn't, mark this as such. 2)
   * If there is no counterpart, figure out where it would be, and get it. This may involve
   * generating and placing a portal into the world. 3) Assuming we now have a counterpart, figure
   * out where to teleport the entity to. 3a) Figure out the entity's position relative to the entry
   * portal. 3b) Translate this to a position relative to the exit portal. 3c) Preserve the entity's
   * camera's orientation relative to the portal. 4) Teleport the entity. 4a) If the entity is a
   * Player in a vehicle, we do a dance. - Raise the destination by 1 (vehicles have to 'fall' into
   * the portal to avoid losing momentum, so they should be one higher). - Make the player leave the
   * vehicle. - Spawn a new minecart at the destination. - Teleport the player to the destination. -
   * Make the player a passenger of the minecart. - Give the new minecart the (properly translated)
   * velocity of the old vehicle. - Remove the old vehicle.
   *
   * @param e The entity to teleport.
   * @return The location the entity was teleported to, or null if the entity was not teleported.
   */
  public Location teleport(Entity e, Location interaction) {
    if (this.counterpart != null) {
      if (!this.counterpart.isValid()) {
        PortalUtil.removePortal(this.counterpart);
        this.counterpart = null;
        PortalUtil.getCounterpartPortalFor(this);
      } else {
        BlockData bd = this.getWorldBlockType();
        if (bd != null
            && !bd.m.equals(Material.AIR)
            && !bd.m.equals(Material.OBSIDIAN)
            && !this.counterpart
                .getKeyBlock()
                .getWorld()
                .equals(PortalUtil.getDestWorldFor(this))) {

          // Did my keyblock change, and if so, change my destination.
          this.counterpart = null;
          PortalUtil.getCounterpartPortalFor(this);
        }
      }
    } else {
      PortalUtil.getCounterpartPortalFor(this);
    }

    if (this.counterpart == null) {
      // Could not establish a link, for whatever reason.
      return null;
    }

    double destX, destY, destZ;
    float destPitch, destYaw;
    int rotateVehicleVelocity = 0;

    Vector offset = interaction.toVector().subtract(this.keyBlock.getLocation().toVector());

    Vector finalOffset;

    if (this.facingNorth) {
      if (offset.getX() < .5) {
        // Player moving south.
        offset.setX(offset.getX() + OFFSET);
      } else {
        // Player moving north.
        offset.setX(offset.getX() - OFFSET);
      }

      if (this.counterpart.isFacingNorth()) {
        destYaw = e.getLocation().getYaw();
        finalOffset = offset;
      } else {
        destYaw = e.getLocation().getYaw() - 90;
        finalOffset = new Vector(offset.getZ(), offset.getY(), -offset.getX() + OFFSET);
        rotateVehicleVelocity = 1;
      }
    } else {
      if (offset.getZ() < .5) {
        // Player moving west
        offset.setZ(offset.getZ() + OFFSET);
      } else {
        // Player moving east.
        offset.setZ(offset.getZ() - OFFSET);
      }
      if (this.counterpart.isFacingNorth()) {
        destYaw = e.getLocation().getYaw() + 90;
        finalOffset = new Vector(-offset.getZ() + OFFSET, offset.getY(), offset.getX());
        rotateVehicleVelocity = 2;
      } else {
        destYaw = e.getLocation().getYaw();
        finalOffset = offset;
      }
    }

    World destWorld = this.counterpart.getKeyBlock().getWorld();
    String permission = "nethrar.block." + destWorld.getName();

    if ((Nethrar.getPlugin().shouldUsePermissions())
        && ((e instanceof Player))
        && (((Player) e).hasPermission(permission))
        && !((Player) e).isOp()) {
      return null;
    }

    destX = this.counterpart.getKeyBlock().getX() + finalOffset.getX();
    destY = this.counterpart.getKeyBlock().getY() + finalOffset.getY();
    destZ = this.counterpart.getKeyBlock().getZ() + finalOffset.getZ();

    destPitch = e.getLocation().getPitch();

    // Jitter the location just a bit so the resulting minecart doesn't
    // end up underground, if there is a minecart being teleported.
    if ((e instanceof Player && ((Player) e).isInsideVehicle())
        || (e instanceof Vehicle && !(e instanceof Pig))) {
      // +.11 is necessary to get a minecart to spawn on top of, instead
      // of inside, rails on the same level on the other side. However,
      // if there are *not* rails on the other side, then the minecart
      // will fall into the block underneath, unless a +1 is added.
      destY += 1.0;
    }

    Location dest;
    dest = new Location(destWorld, destX, destY, destZ, destYaw, destPitch);

    // Bug: Player camera orientation not preserved when teleporting
    // in a vehicle. Probably because vehicle takes over player
    // camera.
    Vehicle oldV = null, newV = null;
    if (e instanceof Player) {
      if (((Player) e).isInsideVehicle()) {
        oldV = (Vehicle) ((Player) e).getVehicle();
        ((Player) e).leaveVehicle();
      }
    } else if (e instanceof StorageMinecart || e instanceof Minecart || e instanceof Boat) {

      oldV = ((Vehicle) e);
    }

    if (oldV != null) {
      if (oldV instanceof StorageMinecart) {
        newV = destWorld.spawn(dest, StorageMinecart.class);
        ((StorageMinecart) newV)
            .getInventory()
            .setContents(((StorageMinecart) oldV).getInventory().getContents());
      } else if (oldV instanceof Minecart) {
        newV = destWorld.spawn(dest, Minecart.class);
      } else if (oldV instanceof Boat) {
        newV = destWorld.spawn(dest, Boat.class);
      } else {
        log.warning("[NETHRAR] Unsupported vehicle hit a portal.");
      }

      Vector oldVelocity = oldV.getVelocity();
      Vector newVelocity;
      switch (rotateVehicleVelocity) {
          // Left-handed system - clockwise is positive.
        case 1:
          // In a north-facing portal, out a west-facing portal.
          // Rotate 90 degrees counterclockwise.
          newVelocity = new Vector(oldVelocity.getZ(), oldVelocity.getY(), oldVelocity.getX() * -1);
          break;
        case 2:
          // In a west-facing portal, out a north-facing portal.
          // Rotate 90 degrees clockwise.
          newVelocity = new Vector(oldVelocity.getZ() * -1, oldVelocity.getY(), oldVelocity.getX());
          break;
        default:
          newVelocity = oldVelocity;
          break;
      }

      PortalUtil.markTeleported(e);
      Bukkit.getServer()
          .getScheduler()
          .scheduleSyncDelayedTask(
              PortalUtil.getPlugin(), new NethrarTeleporter(e, dest, newV, newVelocity, oldV));
    } else {
      PortalUtil.markTeleported(e);
      // Regular player teleportation doesn't need to be delayed.
      NethrarTeleporter tp = new NethrarTeleporter(e, dest);
      tp.run();
    }
    return null;
  }