Package games.stendhal.server.entity.mapstuff.portal

Source Code of games.stendhal.server.entity.mapstuff.portal.Portal

/* $Id: Portal.java,v 1.22 2010/12/29 18:35:33 kiheru Exp $ */
/***************************************************************************
*                      (C) Copyright 2003 - Marauroa                      *
***************************************************************************
***************************************************************************
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
***************************************************************************/
package games.stendhal.server.entity.mapstuff.portal;

import games.stendhal.server.core.engine.SingletonRepository;
import games.stendhal.server.core.engine.StendhalRPZone;
import games.stendhal.server.core.events.UseListener;
import games.stendhal.server.core.pathfinder.FixedPath;
import games.stendhal.server.core.pathfinder.Node;
import games.stendhal.server.core.pathfinder.Path;
import games.stendhal.server.entity.Entity;
import games.stendhal.server.entity.RPEntity;
import games.stendhal.server.entity.player.Player;

import java.util.List;

import marauroa.common.game.RPClass;
import marauroa.common.game.RPObject;
import marauroa.common.game.SyntaxException;
import marauroa.common.game.Definition.Type;

import org.apache.log4j.Logger;

/**
* A portal which teleports the player to another portal if used.
*/
public class Portal extends Entity implements UseListener {
  private static final String RPCLASS_NAME = "portal";

  /**
   * The hidden flags attribute name.
   */
  protected static final String ATTR_HIDDEN = "hidden";
  protected static final String ATTR_USE = "use";

  /** the logger instance. */
  private static final Logger logger = Logger.getLogger(Portal.class);

  private boolean isDestinationSet;

  private Object identifier;

  private String destinationZone;

  private Object destinationReference;

  public static void generateRPClass() {
    try {
        if (!RPClass.hasRPClass(RPCLASS_NAME)){
          final RPClass portal = new RPClass(RPCLASS_NAME);
          portal.isA("entity");
          portal.addAttribute(ATTR_USE, Type.FLAG);
          portal.addAttribute(ATTR_HIDDEN, Type.FLAG);
        }
    } catch (final SyntaxException e) {
      logger.error("cannot generate RPClass", e);
    }
  }

  /**
   * Creates a new portal.
   */
  public Portal() {
    setRPClass(RPCLASS_NAME);
    put("type", RPCLASS_NAME);

    isDestinationSet = false;
  }
 
  public Portal(final RPObject object) {
    super(object);
    setRPClass(RPCLASS_NAME);
    put("type", RPCLASS_NAME);
    isDestinationSet = false;
  }

  /**
   * Set the portal reference to identify this specific portal with-in a zone.
   * This value is opaque and requires a working equals(), but typically uses
   * a String or Integer.
   *
   * @param reference
   *            A reference tag.
   */
  public void setIdentifier(final Object reference) {
    this.identifier = reference;
  }

  /**
   * gets the identifier of this portal.
   *
   * @return identifier
   */
  public Object getIdentifier() {
    return identifier;
  }

  /**
   * Set the destination portal zone and reference. The reference should match
   * the same type/value as that passed to setReference() in the corresponding
   * portal.
   *
   * @param zone
   *            The target zone.
   * @param reference
   *            A reference tag.
   */
  public void setDestination(final String zone, final Object reference) {
    this.destinationReference = reference;
    this.destinationZone = zone;
    this.isDestinationSet = true;
  }

  public Object getDestinationReference() {
    return destinationReference;
  }

  public String getDestinationZone() {
    return destinationZone;
  }

  /**
   * Determine if this portal is hidden from players.
   *
   * @return <code>true</code> if hidden.
   */
  @Override
  public boolean isHidden() {
    return has(ATTR_HIDDEN);
  }

  public boolean loaded() {
    return isDestinationSet;
  }

  @Override
  public String toString() {
    final StringBuilder sbuf = new StringBuilder();
    sbuf.append("Portal");

    final StendhalRPZone zone = getZone();

    if (zone != null) {
      sbuf.append(" at ");
      sbuf.append(zone.getName());
    }

    sbuf.append('[');
    sbuf.append(getX());
    sbuf.append(',');
    sbuf.append(getY());
    sbuf.append(']');

    if (isHidden()) {
      sbuf.append(", hidden");
    }

    return sbuf.toString();
  }

  /**
   * Use the portal.
   *
   * @param player
   *            the Player who wants to use this portal
   * @return <code>true</code> if the portal worked, <code>false</code>
   *         otherwise.
   */
  protected boolean usePortal(final Player player) {
    if (!player.isZoneChangeAllowed()) {
      player.sendPrivateText("For some reason you cannot get through right now.");
      return false;
    }

    if (!nextTo(player) && has("use")) {
      player.sendPrivateText("You must come closer before you can use this orb.");
      return false;
    }
   
    if (!nextTo(player)) {
      // Too far to use the portal from here, but walk to it
      // The pathfinder will do the rest of the work and make the player pass through the portal
      // Check that mouse movement is allowed first
      if (!player.getZone().isMoveToAllowed()) {
        player.sendPrivateText("Mouse movement is not possible here. Use your keyboard.");
      } else if (player.isPoisoned()) {
        player.sendPrivateText("Poison has disoriented you and you cannot move normally. You only seem able to walk backwards and cannot plan out any route in advance.");
      } else {
        final List<Node> path = Path.searchPath(player, this.getX(), this.getY());
        player.setPath(new FixedPath(path, false));
      }
      return false;
    }

    if (getDestinationZone() == null) {
      // This portal is incomplete
      logger.error(this + " has no destination.");
      return false;
    }

    final StendhalRPZone destZone = SingletonRepository.getRPWorld().getZone(
        getDestinationZone());

    if (destZone == null) {
      logger.error(this + " has invalid destination zone: "
          + getDestinationZone());
      return false;
    }

    final Portal dest = destZone.getPortal(getDestinationReference());

    if (dest == null) {
      // This portal is incomplete
      logger.error(this + " has invalid destination identitifer: "
          + getDestinationReference());
      return false;
    }

    if (player.teleport(destZone, dest.getX(), dest.getY(), null, null)) {
      player.stop();
      dest.onUsedBackwards(player);
    }
    return true;
  }

  public boolean onUsed(final RPEntity user) {
    if (user instanceof Player) {
      return usePortal((Player) user);
    } else {
      logger.error("user is no instance of Player but: " + user, new Throwable());
      return false;
    }
  }

  /**
   * if this portal is the destination of another portal used.
   *
   * @param user
   *            the player who used the other portal teleporting to us
   */
  public void onUsedBackwards(final RPEntity user) {
    // do nothing
  }
}
TOP

Related Classes of games.stendhal.server.entity.mapstuff.portal.Portal

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.