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

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

/* $Id: HousePortal.java,v 1.14 2010/09/19 02:24:39 nhnb Exp $ */
/***************************************************************************
*                   (C) Copyright 2003-2010 - Stendhal                    *
***************************************************************************
***************************************************************************
*                                                                         *
*   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 marauroa.common.game.RPClass;
import marauroa.common.game.RPObject;
import marauroa.common.game.RPSlot;
import marauroa.common.game.Definition.Type;

import games.stendhal.common.Constants;
import games.stendhal.common.MathHelper;
import games.stendhal.server.core.engine.SingletonRepository;
import games.stendhal.server.core.engine.StendhalRPZone;
import games.stendhal.server.core.events.TurnListener;
import games.stendhal.server.entity.RPEntity;
import games.stendhal.server.entity.item.HouseKey;

/**
* A portal that can be used with a matching <code>HouseKey</code>.
* The requirements are saved with the portal.
*/
public class HousePortal extends AccessCheckingPortal {
  private static final String RPCLASS_NAME = "house_portal";
 
  /** attribute name for the door identifier string. */
  private static final String DOOR_ID = "door_id";
  /** attribute name for the door owner string. */
  private static final String OWNER = "owner";
  /** attribute name for the lock number. */
  private static final String LOCK_NUMBER = "lock_number";
  /** attribute name for the time when the house would be confiscated. */
  private static final String EXPIRES = "expires";
 
  // these 3 are needed to save the data for linking the portals to each other
  /** attribute name for storing the destination zone name .*/
  private static final String DESTINATION_ZONE = "destination_zone";
  /** attribute name for storing the referance name of the destination portal. */
  private static final String DESTINATION_ID = "destination_id";
  /** the attribute name for the map reference id of this portal. */
  private static final String PORTAL_REFERENCE = "reference";
 
  private boolean needsSaving = false;
 
  public static void generateRPClass() {
    if (!RPClass.hasRPClass(RPCLASS_NAME)) {
      final RPClass entity = new RPClass(RPCLASS_NAME);
      entity.isA("portal");
      entity.addAttribute(DOOR_ID, Type.STRING);
      entity.addAttribute(OWNER, Type.STRING);
      entity.addAttribute(LOCK_NUMBER, Type.INT);
      entity.addAttribute(EXPIRES, Type.STRING);
      entity.addAttribute(DESTINATION_ZONE, Type.STRING);
      entity.addAttribute(DESTINATION_ID, Type.STRING);
      entity.addAttribute(PORTAL_REFERENCE, Type.STRING);
    }
  }
 
  /**
   * Create a HousePortal.
   *
   * @param doorId the door identifier
   */
  public HousePortal(final String doorId) {
    super("The door is locked.");
    setRPClass(RPCLASS_NAME);
    put("type", "house_portal");
    put(DOOR_ID, doorId);
    put(OWNER, "");
    put(LOCK_NUMBER, 0);
    store();
  }
 
  /**
   * Create a HousePortal from an <code>RPObject</code>. Used when restoring from the database.
   *
   * @param object the corresponding <code>RPObject</code>
   */
  public HousePortal(final RPObject object) {
    super(object);
    setRPClass(RPCLASS_NAME);
    put("type", "house_portal");
    super.setDestination(get(DESTINATION_ZONE), idToObject(DESTINATION_ID));
    super.setIdentifier(idToObject(PORTAL_REFERENCE));
    setRejectedMessage("The door is locked.");
   
       store();
  }
 
  /**
   * Sets the owner of this portal.
   *
   * @param owner name of the owner.
   */
  public void setOwner(final String owner) {
    put(OWNER, owner);
    requestSave();
  }
 
  // treating the portal references the same way as PortalSetupXMLReader
  /**
   * Get the door reference as an <code>Object</code>.
   *
   * @param attribute name of the attribute to fetch the reference from
   *
   * @return portal reference in the form that <code>Portal</code> accepts it
   */
  private Object idToObject(final String attribute) {
    final String idString = get(attribute);
    Object id;
    try {
      id = Integer.valueOf(idString);
    } catch (final NumberFormatException ex) {
      id = idString;
    }
   
    return id;
  }
 
  @Override
  public void setDestination(final String zone, final Object id) {
    super.setDestination(zone, id);
    // Save zone and id information. They are needed when restoring from db
    put(DESTINATION_ZONE, zone);
    put(DESTINATION_ID, id.toString());
  }
 
  @Override
  public void setIdentifier(final Object id) {
    super.setIdentifier(id);
    // Save the reference name of this portal. Needed when restoring from the db.
    put(PORTAL_REFERENCE, id.toString());
  }
 
  @Override
  public String describe() {
    final String owner = getOwner();
    final String description;
    if (owner.length() > 0) {
      description = "Here lives " + owner + ".";
    } else {
      description = "For sale!";
    }
   
    return description;
  }
 
  @Override
  protected boolean isAllowed(final RPEntity user) {
    // check if the player is carrying a matching HouseKey
    for (final String slotName : Constants.CARRYING_SLOTS) {
      final RPSlot slot = user.getSlot(slotName);

      for (final RPObject object : slot) {
        if (!(object instanceof HouseKey)) {
          continue;
        }

        final HouseKey key = (HouseKey) object;
        if (key.matches(getDoorId(), getLockNumber())) {
          // TODO: Remove the key naming support, and just return. 
          // The renaming code does not need to be here forever, just some
          // months, so that most of the player's keys get tagged with
          // an owner. Comment added 2009-03-13
          key.setup(getDoorId(), getLockNumber(), getOwner());
         
          return true;
        }
      }
    }

    return false;
  }
 
  /**
   * Get the identification string of this portal.
   *
   * @return the identification string
   */
  public String getDoorId() {
    return get(DOOR_ID);
  }

 
  /**
   * Get the house number of this portal.
   *
   * @return the house number, or 0 if house number not found
   */
  public int getPortalNumber() {
    final String doorId = getDoorId();
    final String[] parts = doorId.split(" ");
    int id = 0;
    if (parts.length > 2) {
      id = MathHelper.parseIntDefault(parts[2], 0);
    }
    return id;
  }
 
  /**
   * Get the name of the owner.
   *
   * @return owner
   */
  public String getOwner() {
    return get(OWNER);
  }
 
  /**
   * Get the number of the lock.
   *
   * @return number of the lock
   */
  public int getLockNumber() {
    return this.getInt(LOCK_NUMBER);
  }
 
  /**
   * Increase the lock number by one.
   */
  public void changeLock() {
    put(LOCK_NUMBER, getInt(LOCK_NUMBER) + 1);
   
    requestSave();
  }
 
  /**
   * Get the expiration time of the portal.
   *
   * @return time in milliseconds
   */
  public long getExpireTime() {
    return Long.parseLong(get(EXPIRES));
  }
 
  /**
   * Set the expiration time of the portal.
   *
   * @param time time in milliseconds
   */
  public void setExpireTime(final long time) {
    put(EXPIRES, Long.toString(time));
   
    requestSave();
  }
 
  /**
   * Request saving the zone where the portal is located.
   * Multiple requests within a turn get merged to one.
   */
  private void requestSave() {
    /*
     * Avoid saving the zone three times when a new house is bought
     */
    needsSaving = true;
    SingletonRepository.getTurnNotifier().notifyInTurns(1, new TurnListener() {
      public void onTurnReached(int turn) {
        if (needsSaving) {
          needsSaving = false;
          saveToDatabase();
        }
      }
    });
  }
 
  /**
   * Save the zone (and the portal along it)
   */
  private void saveToDatabase() {
    StendhalRPZone zone = this.getZone();
    if (zone != null) {
      zone.storeToDatabase();
    }
  }
}
TOP

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

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.